/* PureAdmin
* Copyright (C) 2003 Isak Savo
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* Callback-functions for the main window GUI.
*
* Copyright (C) 2003- Isak Savo
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "globals.h"
#include "gui_helper.h"
#include "mainwin.h"
#include "prereq_usrmanager.h"
#include "usr_manager.h"
#include "helper.h"
#include "prefwin.h"
#include "cfg.h"
#include "logfile.h"
#include "helpview.h"
popup_src_t popup_source;
gboolean usermanager_initialized = FALSE;
static void update_adv_info (void)
{
static GtkWidget *tree_activities = NULL;
static GtkTreeModel *model = NULL;
static GtkWidget *adv_info = NULL;
static GtkTreeSelection *sel;
GtkTreeIter iter;
gboolean visible = TRUE, selected;
gint id;
PActivity *act;
if (G_UNLIKELY (!tree_activities))
{
tree_activities = MW("tree_activity");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_activities));
adv_info = MW("tbl_advanced_info");
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_activities));
}
g_object_get (adv_info,
"visible", &visible,
NULL);
selected = gtk_tree_selection_get_selected (sel, &model, &iter);
if (visible)
{
if (selected)
{
gtk_tree_model_get (model, &iter,
COL_ACT_ID, &id,
-1);
act = srv_get_activity_with_id (id);
gui_update_info_frame (act);
pactivity_free (act);
}
else
gui_update_info_frame (NULL); /* Clear advanced info labels */
}
}
/* Gets the ID of the selected activity and stores it in the location pointed to by output_id.
* Returns true if the id was found, otherwise false*/
static gboolean gui_tree_act_get_selected_id (guint *output_id)
{
static GtkWidget *tree_activities = NULL;
static GtkTreeModel *model = NULL;
static GtkTreeSelection *sel;
GtkTreeIter iter;
gboolean selected;
gint id;
if (G_UNLIKELY (!tree_activities))
{
tree_activities = MW("tree_activity");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_activities));
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_activities));
}
selected = gtk_tree_selection_get_selected (sel, &model, &iter);
if (!selected) /* Nothing is selected! */
return FALSE;
gtk_tree_model_get (model, &iter,
COL_ACT_ID, &id,
-1);
*output_id = id;
return TRUE;
}
static gboolean gui_tree_usr_get_selected_user (gchar **user, gchar **host)
{
static GtkWidget *tree_users = NULL;
static GtkTreeModel *model = NULL;
static GtkTreeSelection *sel;
GtkTreeIter iter;
gboolean selected;
if (G_UNLIKELY (!tree_users))
{
tree_users = MW("tree_users");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_users));
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_users));
}
selected = gtk_tree_selection_get_selected (sel, &model, &iter);
if (!selected) /* Nothing is selected! */
return FALSE;
gtk_tree_model_get (model, &iter,
COL_USR_USER, user,
COL_USR_HOST, host,
-1);
if (host && user)
return TRUE;
else
return FALSE;
}
gboolean
trayicon_activate (EggStatusIcon *icon, gpointer user_data)
{
gtk_window_present (GTK_WINDOW(MW("main_window")));
g_object_unref (status_icon);
status_icon = NULL;
return FALSE;
}
gboolean
on_main_window_delete_event (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
exit_program ();
return FALSE;
}
void
on_main_window_destroy (GtkObject *object,
gpointer user_data)
{
gtk_main_quit();
}
gboolean on_mainwin_focus_in_event (GtkWidget *widget,
GdkEventFocus *event,
gpointer user_data)
{
hide_status_icon();
return FALSE;
}
void
show_hide_advanced_info_cb (GtkToggleButton *togglebutton, gpointer user_data)
{
GtkWidget *adv_info = MW("tbl_advanced_info");
cfg.show_advinfo = gtk_toggle_button_get_active (togglebutton);
if (cfg.show_advinfo)
{
gtk_widget_show (adv_info);
update_adv_info();
}
else
gtk_widget_hide (adv_info);
}
void
on_tree_activity_cursor_changed (GtkTreeView *treeview,
gpointer user_data)
{
guint id;
update_adv_info ();
if (gui_tree_act_get_selected_id(&id))
{
PActivity *act = srv_get_activity_with_id (id);
g_return_if_fail (act != NULL);
user_list_select_user(act->username, act->remote_addr);
pactivity_free (act);
}
}
void
on_btn_user_manager_clicked (GtkButton *button,
gpointer user_data)
{
GtkWidget *dlg_usrman;
GtkWidget *mainwin = MW("main_window");
if (prereq_are_all_requirements_met() == FALSE)
{
gboolean success = prereq_show_dialog(GTK_WINDOW(mainwin));
if (!success)
return;
}
dlg_usrman = usr_init_usermanager_window (mainwin);
gtk_window_present (GTK_WINDOW (dlg_usrman));
}
void
menu_quit_cb (GtkMenuItem *menuitem,
gpointer user_data)
{
exit_program ();
gtk_main_quit ();
}
void
menu_preferences_cb (GtkMenuItem *menuitem, gpointer user_data)
{
GtkWidget *prefwin = pref_init_prefwindow (MW("main_window"));
gtk_window_present (GTK_WINDOW(prefwin));
}
void
menu_srv_startstop_cb (GtkMenuItem *menuitem, gpointer user_data)
{
GError *err = NULL;
int ret;
gchar *msg, *title;
gboolean running = ftp_runmode == RUNMODE_STANDALONE ? TRUE : FALSE;
if (G_UNLIKELY (ftp_runmode == RUNMODE_INETD))
/* This won't happen, but I'm paranoid! */
return;
if (!cfg.cmd_startstop)
{
gui_display_msgdialog (_("Startupscript Not Found"),
_("PureAdmin could not locate the script used to start and stop the server.\n"
"This file should be located in /etc/rc.d/init.d/ on RedHat (and similar) and "
"/etc/rc.d/ on Slackware (and similar)\n"
"Starting and stopping is disabled."),
MSGDLG_TYPE_ERROR, MW("main_window"));
return;
}
if (running)
ret = misc_stop_server (&err);
else
ret = misc_start_server (&err);
if (G_UNLIKELY (ret == FALSE))
{
if (running)
{
title = g_strdup (_("Failure to start server"));
msg = g_strdup_printf (_("PureAdmin was unable to start the server because the execution of \"%s\" failed.\n"
"Error reported was: %s"), cfg.cmd_startstop, err->message);
}
else
{
title = g_strdup (_("Failure to stop server"));
msg = g_strdup_printf (_("PureAdmin was unable to stop the server because the execution of \"%s\" failed.\n"
"Error reported was: %s"), cfg.cmd_startstop, err->message);
}
gui_display_msgdialog (title, msg,
MSGDLG_TYPE_ERROR, MW("main_window"));
g_free (title);
g_free (msg);
g_error_free (err);
return;
}
if (running)
ftp_runmode = RUNMODE_STOPPED;
else
ftp_runmode = RUNMODE_STANDALONE;
gui_update_server_status ();
}
void
menu_user_manager_cb (GtkMenuItem *menuitem, gpointer user_data)
{
GtkWidget *dlg_usrman;
if (!prereq_are_all_requirements_met())
if (!prereq_show_dialog(GTK_WINDOW(MW("main_window"))))
return;
dlg_usrman = usr_init_usermanager_window (MW("main_window"));
gtk_window_present (GTK_WINDOW (dlg_usrman));
}
void
menu_connections_cb (GtkMenuItem *menuitem, gpointer user_data)
{
GtkTreeView *act_tree = GTK_TREE_VIEW (MW("tree_activity"));
GtkTreeSelection *sel = gtk_tree_view_get_selection (act_tree);
GtkTreeIter iter;
GtkTreeModel *model = NULL;
gtk_widget_set_sensitive (MW("mi_close_all"), srv_has_activities ());
gboolean selected = gtk_tree_selection_get_selected (sel, NULL, NULL);
gtk_widget_set_sensitive (MW("mi_close_tx"), selected);
gtk_widget_set_sensitive (MW("mi_notify"), selected);
gchar *text;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (MW("tree_users")));
selected = gtk_tree_selection_get_selected (sel, &model, &iter);
gtk_widget_set_sensitive (MW("mi_disconnect"), selected);
if (selected)
{
gchar *username = NULL;
gtk_tree_model_get (model, &iter,
COL_USR_USER, &username,
-1);
text = g_strconcat (_("Disconnect user"), " ", username, NULL);
}
else
text = g_strdup (_("Disconnect user"));
GtkWidget *label = gtk_bin_get_child (GTK_BIN(MW("mi_disconnect")));
gtk_label_set_text (GTK_LABEL(label), text);
g_free (text);
}
void
menu_close_tx_cb (GtkMenuItem *menuitem, gpointer user_data)
{
show_not_yet_implemented (GTK_WINDOW(MW("main_window")));
}
void
menu_disconnect_user_cb (GtkMenuItem *menuitem, gpointer user_data)
{
show_not_yet_implemented (GTK_WINDOW(MW("main_window")));
}
void
menu_close_connections_cb (GtkMenuItem *menuitem, gpointer user_data)
{
GList *act_list, *head;
PActivity *activity;
gint ret;
head = act_list = srv_get_activities ();
while (act_list)
{
activity = (PActivity *) act_list->data;
g_print ("Closing connection with pid: %d...", activity->pid);
ret = misc_close_connection (activity->pid);
if (ret)
g_print ("success\n");
else
g_print ("failure\n");
act_list = act_list->next;
}
free_activity_list (head);
}
void
menu_notify_cb (GtkMenuItem *menuitem, gpointer user_data)
{
show_not_yet_implemented (GTK_WINDOW(MW("main_window")));
}
void
menu_about_cb (GtkMenuItem *menuitem, gpointer user_data)
{
GtkWidget *about, *title;
about = DW("dlg_about");
title = DW("lbl_title");
/* Make the About-text reflect the actual version */
gtk_label_set_text (GTK_LABEL (title),
"<span weight=\"bold\" size=\"x-large\">"
"PureAdmin v" VERSION
"</span>");
gtk_label_set_use_markup (GTK_LABEL (title), TRUE);
gtk_dialog_run (GTK_DIALOG (about));
gtk_widget_hide (about);
}
void
menu_help_cb (GtkMenuItem *menuitem, gpointer user_data)
{
hlp_show_help (HLP_ITEM_INDEX);
}
static void open_in_browser (const gchar *url)
{
gchar *browser = misc_find_webbrowser();
GError *err = NULL;
if (!browser) {
gchar *msg = g_strdup_printf (_("The default browser could not be located. You can solve this "
"by either:\n"
" \342\200\242 Setting the environment variable <i>$BROWSER</i> to the name of your web browser.\n"
" \342\200\242 Open \"Preferred Applications\" in the GNOME control panel and set "
"the browser there.\n\n"
"The requested page is:\n"
"<u>%s</u>"), url);
gui_display_msgdialog (_("Couldn't launch browser"), msg, MSGDLG_TYPE_WARNING, MW("main_window"));
g_free (msg);
return;
}
gchar *quoted_url = g_shell_quote (url);
gchar *cmd = g_strdup_printf (browser, quoted_url);
pur_log_dbg ("Running: %s", cmd);
gboolean success;
success = g_spawn_command_line_async (cmd, &err);
//success = FALSE;
g_free (quoted_url);
g_free (cmd);
if (!success) {
gchar *msg = g_strdup_printf (_("The web browser could not be started because of a system error. Try again and "
"if the error remains, report this bug in the support forums.\n\n"
"The reported error was: %s"), err->message);
gui_display_msgdialog (_("Couldn't launch browser"), msg, MSGDLG_TYPE_ERROR, MW("main_window"));
g_free (msg);
}
}
void menu_online_support_cb (GtkMenuItem *menuitem, gpointer user_data)
{
const char *url = "http://purify.sourceforge.net/forums/";
open_in_browser (url);
}
void menu_online_documentation_cb (GtkMenuItem *menuitem, gpointer user_data)
{
const char *url = "http://purify.sourceforge.net/index.php?page=documentation";
open_in_browser (url);
}
gboolean
on_tree_activity_popup_menu (GtkWidget *widget,
gpointer user_data)
{
popup_source = POPUP_FROM_ACTTREE;
gui_display_activity_popup (popup_source);
return TRUE;
}
gboolean
on_tree_activity_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
GdkEventButton *event_button;
if (event->type == GDK_BUTTON_PRESS)
{
event_button = (GdkEventButton *) event;
if (event_button->button == 3)
{
popup_source = POPUP_FROM_ACTTREE;
gui_display_activity_popup (popup_source);
return TRUE;
}
}
return FALSE;
}
gboolean
on_tree_users_popup_menu (GtkWidget *widget,
gpointer user_data)
{
popup_source = POPUP_FROM_USRTREE;
gui_display_activity_popup (popup_source);
return FALSE;
}
gboolean
on_tree_users_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
GdkEventButton *event_button;
if (event->type == GDK_BUTTON_PRESS)
{
event_button = (GdkEventButton *) event;
if (event_button->button == 3)
{
popup_source = POPUP_FROM_USRTREE;
gui_display_activity_popup (popup_source);
return TRUE;
}
}
return FALSE;
}
void
on_popup_close_tx (GtkMenuItem *menuitem,
gpointer user_data)
{
guint id;
PActivity *act;
if (popup_source == POPUP_FROM_ACTTREE)
{
if (!gui_tree_act_get_selected_id (&id))
{
pur_log_wrn ("Unable to fetch information about selected activity");
return;
}
act = srv_get_activity_with_id (id);
pur_log_dbg ("Closing connection for user %s (pid: %d)", act->username, act->pid);
misc_close_connection (act->pid);
pactivity_free (act);
}
else
{
/* This should _never_ happen! */
pur_log_err ("Close transfer for user NOT possible!");
}
}
void
on_popup_close_all_conns (GtkMenuItem *menuitem,
gpointer user_data)
{
gchar *user, *host;
guint id;
gboolean success;
PActivity *act;
GList *conns, *head;
if (popup_source == POPUP_FROM_ACTTREE)
{
if (!gui_tree_act_get_selected_id (&id))
{
pur_log_wrn ("Unable to fetch information about selected activity\n");
return;
}
act = srv_get_activity_with_id (id);
pur_log_dbg ("Closing all connection for user %s (pid: %d)\n", act->username, act->pid);
conns = srv_get_pids_for_user_host (act->username, act->remote_addr);
while (conns)
{
pur_log_dbg ("Killing process %d\n", GPOINTER_TO_INT (conns->data));
success = misc_close_connection (GPOINTER_TO_INT (conns->data));
if (!success)
pur_log_err ("Failed to kill process %d\n", GPOINTER_TO_INT (conns->data));
conns = g_list_next (conns);
}
pactivity_free (act);
g_list_free (conns);
}
else
{
if (!gui_tree_usr_get_selected_user (&user, &host))
{
pur_log_wrn ("Unable to fetch information about selected user");
return;
}
pur_log_dbg ("Closing all connection for user %s (host: %s)\n", user, host);
head = conns = srv_get_pids_for_user_host (user, host);
while (conns)
{
pur_log_dbg ("Killing process %d\n", GPOINTER_TO_INT (conns->data));
success = misc_close_connection (GPOINTER_TO_INT (conns->data));
if (!success)
pur_log_wrn ("Failed to kill process %d\n", GPOINTER_TO_INT (conns->data));
conns = g_list_next (conns);
}
g_list_free (head);
}
}
void on_popup_show_userinfo (GtkMenuItem *menuitem, gpointer user_data)
{
guint id;
gchar *user, *host;
PActivity *act;
GtkWidget *dlg_usrman;
if (popup_source == POPUP_FROM_ACTTREE)
{
if (!gui_tree_act_get_selected_id (&id))
{
pur_log_wrn ("Unable to fetch information about selected activity\n");
return;
}
act = srv_get_activity_with_id (id);
user = act->username;
pactivity_free (act);
}
else
{
if (!gui_tree_usr_get_selected_user (&user, &host))
{
pur_log_wrn ("Unable to fetch information about selected user\n");
return;
}
}
pur_log_dbg ("Showing userinfo for %s\n", user);
if (!prereq_are_all_requirements_met())
if(!prereq_show_dialog(GTK_WINDOW(MW("main_window"))))
return;
dlg_usrman = usr_init_usermanager_window (MW("main_window"));
gtk_window_set_transient_for (GTK_WINDOW(dlg_usrman), GTK_WINDOW (MW("main_window")));
usr_select_user (user);
gtk_widget_show (dlg_usrman);
gtk_window_present (GTK_WINDOW (dlg_usrman));
}
void
menu_debug_console_cb (GtkMenuItem *menuitem, gpointer user_data)
{
gtk_window_present (GTK_WINDOW (MW("dlg_debug")));
}
/* Handles keyboard press events for the main window. Used to grab
* hard-coded global keyboard shortcuts */
gboolean
mainwin_keypress (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data)
{
guint modifier = event->state;
static GtkWidget *notebook = NULL;
#define PUR_CTRL_OR_SHIFT (modifier & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))
if (G_UNLIKELY(!notebook))
notebook = MW("notebook1");
/* Alt+<key> shortcuts (ugly way, only check for ctrl/shift)*/
if (modifier & GDK_MOD1_MASK && !(PUR_CTRL_OR_SHIFT))
{
switch (event->keyval){
case GDK_1:
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0);
break;
case GDK_2:
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1);
break;
}
}
return FALSE;
}
void
on_btn_logview_clear_clicked (GtkButton *button,
gpointer user_data)
{
log_clear_logview ();
}
void
on_btn_logview_reread_clicked (GtkButton *button,
gpointer user_data)
{
close_logfile ();
init_logfile ();
}
syntax highlighted by Code2HTML, v. 0.9.1