/* 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 #endif #include #include #include #include #include #include #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), "" "PureAdmin v" VERSION ""); 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 $BROWSER 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" "%s"), 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+ 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 (); }