#include #include #include #include #include #include #include "util.h" #include "defines.h" gchar * conv_from_utf8 (gchar * msg) { return g_locale_from_utf8 (msg, -1, NULL, NULL, NULL); } gchar * conv_to_utf8 (gchar * msg) { return g_locale_to_utf8 (msg, -1, NULL, NULL, NULL); } /* * handles the error code returned by pppd */ gint gkdial_handle_return_code (GkDial * gkdial) { gboolean retry_connection = FALSE; #ifdef DEBUG printf ("(gkdial_handle_return_code)ret: %d - gkdial->state: %d\n", gkdial->return_code, gkdial->state); fflush (stdout); #endif if (gkdial->state == DISCONNECTED || !gkdial->was_gkdial) { g_free (gkdial->command); gkdial->command = NULL; gkdial->return_code = -1; return 0; } /* * tries to reconnect if the connection fails */ if (gkdial_conf_get_bool (gkdial, "preferences/retry_when_dialing") && gkdial->return_code != 0 && gkdial->state == CONNECTING) { #ifdef DEBUG fprintf (stderr, "num_retries: %d\nmax_retries: %d\n", gkdial->num_retries, (gint) gkdial->max_retries); #endif if (!gkdial->max_retries) retry_connection = TRUE; else if (gkdial->num_retries < (gint) gkdial->max_retries) retry_connection = TRUE; gkdial->num_retries++; } /* * tries to reconnect if the connection is lost */ if (gkdial_conf_get_bool (gkdial, "preferences/reconn_if_lost") && gkdial->return_code != 0 && gkdial->state == CONNECTED) retry_connection = TRUE; gtk_statusbar_pop (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id); switch (gkdial->return_code) { case 0: gk_dialog (GTK_MESSAGE_INFO, _("Connection timed out.\nIs your modem connected?")); break; case 1: gk_dialog (GTK_MESSAGE_ERROR, _("Fatal error when running:\n%s."), gkdial->command); retry_connection = FALSE; /* it will not work, anyway */ break; case 2: gk_dialog (GTK_MESSAGE_ERROR, _("No modem or bad options.")); retry_connection = FALSE; break; case 3: gk_dialog (GTK_MESSAGE_INFO, _("You are not allowed to run:\n%s."), gkdial->command); retry_connection = FALSE; break; case 4: gk_dialog (GTK_MESSAGE_ERROR, _("Fatal error:\n" "Your kernel is missing PPP support.")); retry_connection = FALSE; break; case 5: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Connection terminated by signal...")); else gk_dialog (GTK_MESSAGE_INFO, _("The connection was terminated prematurely " "by a signal it received.")); break; case 6: gk_dialog (GTK_MESSAGE_INFO, _("The serial port could not be locked.")); retry_connection = FALSE; break; case 7: gk_dialog (GTK_MESSAGE_INFO, _("The serial port could not be opened.")); retry_connection = FALSE; break; case 8: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Connection failed...")); else gk_dialog (GTK_MESSAGE_INFO, _("A connection was being tried but could not\n" "be completed. Check the /var/log/syslog file\n" "for details.")); break; case 9: gk_dialog (GTK_MESSAGE_INFO, _("The command specified as argumento to the\n" "pty option could not be run.")); retry_connection = FALSE; break; case 10: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("PPP negotiation failed.")); else gk_dialog (GTK_MESSAGE_INFO, _("PPP negotiation failed.")); break; case 11: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Peer did not authenticate itself.")); else gk_dialog (GTK_MESSAGE_INFO, _("Peer did not authenticate itself.")); break; case 12: gk_dialog (GTK_MESSAGE_INFO, _("Connection terminated because it was idle.")); retry_connection = FALSE; break; case 13: gk_dialog (GTK_MESSAGE_INFO, _("Connection terminated because it reached\n" "the time limit.")); retry_connection = FALSE; break; case 14: gk_dialog (GTK_MESSAGE_INFO, _("Callback negotiated, incoming call should\n" "arrive shortly.")); retry_connection = FALSE; break; case 15: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Peer is not responding.")); else gk_dialog (GTK_MESSAGE_ERROR, _("Peer is not responding.")); break; case 16: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Modem hang up.")); else gk_dialog (GTK_MESSAGE_ERROR, _("Modem hang up.")); break; case 17: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Loopback detected.")); else gk_dialog (GTK_MESSAGE_ERROR, _("Negotiation failed: loopback detected.")); break; case 18: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Connection script failed.")); else gk_dialog (GTK_MESSAGE_ERROR, _("Connection script failed.")); break; case 19: if (retry_connection) gtk_statusbar_push (GTK_STATUSBAR (gkdial->details_statusbar), gkdial->status_state_id, _("Failed to authenticate...")); else gk_dialog (GTK_MESSAGE_ERROR, _("Failed to authenticate: check your\n" "username and password and try again.")); break; } /* * reset values */ g_free (gkdial->command); gkdial->command = NULL; gkdial->return_code = -1; if (retry_connection) { gint i; /* * wait a bit, so that the user is able to read the status message */ for (i = 0; i < 70; i++) { while (gtk_events_pending ()) gtk_main_iteration_do (FALSE); usleep (1000); } gk_connect (NULL, gkdial); return 1; } return 0; } /* * executes a command */ void gkdial_exec (GkDial * gkdial, const gchar * command, gint what) { gchar **gk_args; gchar tmp[FILENAME_MAX], *c; int i, status, return_code; pid_t pid; #ifdef DEBUG printf ("(gkdial_exec)gkdial->state: %d\n", gkdial->state); #endif /* * we'll allocate memory as needed, here we get the first bytes we * need */ gk_args = g_malloc (sizeof (gchar *) * 2); /* * we'll not use 'command' for strtok as we don't want it to be * modified */ strncpy (tmp, command, FILENAME_MAX); c = strtok (tmp, " "); gk_args[0] = g_strdup (c); gk_args[1] = NULL; #ifdef DEBUG fprintf (stderr, _("Calling: %s "), gk_args[0]); #endif for (i = 1; (c = strtok (NULL, " ")) != NULL; i++) { /* * let's fill the arguments, we'll add one last NULL because * execv() needs it */ gk_args = g_realloc (gk_args, sizeof (gchar *) * (i + 2)); gk_args[i] = g_strdup (c); gk_args[i + 1] = NULL; #ifdef DEBUG fprintf (stderr, "%s ", gk_args[i]); #endif } fprintf (stderr, "\n"); pid = fork (); if (!pid) { if (execvp (gk_args[0], gk_args) == -1) { printf ("%s\n", gk_args[0]); gk_dialog (GTK_MESSAGE_ERROR, _("Error! Could not execute %s."), gk_args[0]); } } else if (pid == -1) gk_dialog (GTK_MESSAGE_ERROR, _("Error, could not fork().")); else { if (what == CONNECTING) { waitpid (pid, &status, 0); /* * unlock state */ gkdial->state_locked = FALSE; if (WIFEXITED (status)) { gkdial->return_code = WEXITSTATUS (status); g_free (gkdial->command); gkdial->command = g_strdup (command); } } else { waitpid (pid, &status, 0); if (WIFEXITED (status) && WEXITSTATUS (status)) { gk_dialog (GTK_MESSAGE_ERROR, _("An error ocurred when trying to disconnect." "\n\n" "You may not have the needed permissions or " "there was no connection to be finished " "(stale lock file?).")); } } } for (i = 0; gk_args[i] != NULL; i++) g_free (gk_args[i]); g_free (gk_args); } void gkdial_fork_new (GkDial * gkdial, gchar * msg, gchar * cmd) { gint a; pid_t pid; gchar **command; gchar *fcmd = g_strdup_printf("%s > /dev/null 2>&1",cmd); command = g_malloc (sizeof (gchar *) * 4); command[0] = g_strdup (PREFIX "/bin/gpe-su"); command[1] = g_strdup ("-c"); command[2] = fcmd; command[3] = NULL; pid = fork (); if (pid == 0) { execv (command[0], command); } else if (pid == -1) { gk_dialog (GTK_MESSAGE_ERROR, _("Error, could not fork().")); return; } else { while (!waitpid (pid, NULL, WNOHANG)) { usleep (1); while (gtk_events_pending ()) gtk_main_iteration_do (FALSE); } /* * after the command is finished the buttons can go back to be * sensitive */ gkdial_prefs_buttons_set_sensitive (gkdial, TRUE); peers_list_fill (gkdial, FALSE); } for (a = 0; command[a] != NULL; a++) g_free (command[a]); g_free (command); } /* * adds a label and a stock image to a GtkButton */ void gkdial_add_label_and_stock_image (GtkWidget * w, gchar * label_str, gchar * stock_id) { GtkWidget *align; GtkWidget *hbox; GtkWidget *label; GtkWidget *image; align = gtk_alignment_new (0.5, 0.5, 0, 0); gtk_widget_show (align); hbox = gtk_hbox_new (FALSE, 1); gtk_container_add (GTK_CONTAINER (align), hbox); gtk_widget_show (hbox); image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 1); gtk_widget_show (image); label = gtk_label_new_with_mnemonic (label_str); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 1); gtk_widget_show (label); gtk_container_add (GTK_CONTAINER (w), align); } /* * Shows 'msg' in a dialog box with an OK button This function is to be a * helper for functions needing to display some information to the user */ void gk_dialog (GtkMessageType type, gchar * format, ...) { GtkWidget *diag_win; va_list ap; gchar *msg; va_start (ap, format); msg = g_strdup_vprintf (format, ap); va_end (ap); diag_win = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, type, GTK_BUTTONS_CLOSE, msg); gtk_label_set_use_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (diag_win)->label), TRUE); /* * gtk_signal_connect_object (GTK_OBJECT(diag_win), "delete_event", * GTK_SIGNAL_FUNC(gtk_main_quit), NULL); */ gtk_window_set_position (GTK_WINDOW (diag_win), GTK_WIN_POS_CENTER); gtk_window_set_resizable (GTK_WINDOW (diag_win), FALSE); gtk_widget_show_all (diag_win); gtk_dialog_run (GTK_DIALOG (diag_win)); g_free (msg); gtk_widget_destroy (diag_win); }