void netinfo_text_buffer_insert (Netinfo * netinfo) { gchar *dir = g_get_current_dir (); gint child_pid, pout; GIOChannel *channel; const gchar *charset; GIOStatus status; GError *err = NULL; g_return_if_fail (netinfo != NULL); g_return_if_fail (netinfo->command_line != NULL); if (g_spawn_async_with_pipes (dir, netinfo->command_line, NULL, G_SPAWN_FILE_AND_ARGV_ZERO | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &child_pid, NULL, &pout, NULL, &err)) { netinfo->child_pid = child_pid; netinfo->pipe_out = pout; fcntl (pout, F_SETFL, O_NONBLOCK); fcntl (pout, F_SETFL, O_NONBLOCK); netinfo->command_output = NULL; g_child_watch_add (child_pid, netinfo_reap_child, netinfo); g_get_charset(&charset); channel = g_io_channel_unix_new (pout); status = g_io_channel_set_encoding(channel, charset, &err); if (G_IO_STATUS_NORMAL == status) { g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, netinfo_io_text_buffer_dialog, netinfo); g_io_channel_unref (channel); } else { g_warning ("Error: %s\n", err->message); g_error_free (err); } } else { gint len = strlen (err->message); if (netinfo->process_line != NULL) { (netinfo->process_line) ((gpointer) netinfo, err->message, len, NULL); } netinfo_toggle_state (netinfo, ACTIVE, NULL); g_warning ("Error: %s\n", err->message); g_error_free (err); } g_free (dir); }
void netinfo_process_command (Netinfo * netinfo) { g_return_if_fail (netinfo != NULL); netinfo_toggle_state (netinfo, INACTIVE, NULL); netinfo_text_buffer_insert (netinfo); }
gboolean netinfo_io_text_buffer_dialog (GIOChannel * channel, GIOCondition condition, gpointer data) { gchar *text = NULL; gsize len; Netinfo *netinfo = (Netinfo *) data; GError *err = NULL; const gchar *encoding; g_return_val_if_fail (channel != NULL, FALSE); g_return_val_if_fail (netinfo != NULL, FALSE); g_return_val_if_fail (netinfo->output != NULL, FALSE); #ifdef DEBUG switch (condition) { case G_IO_IN: g_print ("G_IO_IN\n"); break; case G_IO_HUP: g_print ("G_IO_HUP\n"); break; case G_IO_ERR: g_print ("G_IO_ERR\n"); break; case G_IO_NVAL: g_print ("G_IO_NVAL\n"); break; default: g_print ("Nothing\n"); break; } #endif /* DEBUG */ if (condition & G_IO_IN) { GIOStatus status; status = g_io_channel_read_line (channel, &text, &len, NULL, &err); if (status == G_IO_STATUS_NORMAL) { if (netinfo->command_output) { g_string_append (netinfo->command_output, text); g_free (text); text = g_string_free (netinfo->command_output, FALSE); netinfo->command_output = NULL; } if (netinfo->process_line != NULL) { (netinfo->process_line) ((gpointer) netinfo, text, len, NULL); } } else if (status == G_IO_STATUS_AGAIN) { char buf[1]; /* A non-terminated line was read, read the data into the buffer. */ status = g_io_channel_read_chars (channel, buf, 1, NULL, NULL); if (status == G_IO_STATUS_NORMAL) { if (netinfo->command_output == NULL) { netinfo->command_output = g_string_new (NULL); } g_string_append_c (netinfo->command_output, buf[0]); } } else if (status == G_IO_STATUS_EOF) { } else if (status == G_IO_STATUS_ERROR) { encoding = g_io_channel_get_encoding (channel); if (err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) { g_warning ("Warning: change of encoding: %s. The encoding " "was changed from %s to ISO-8859-1 only " "for this string\n", err->message, encoding); g_io_channel_set_encoding (channel, "ISO-8859-1", NULL); g_io_channel_read_line (channel, &text, &len, NULL, NULL); } else { g_warning ("Error: %s\n", err->message); g_free (text); g_free (err); } } g_free (text); return TRUE; } /* The condition is not G_IO_HUP | G_IO_ERR | G_IO_NVAL, so we are ready to receive a new request from the user */ close (netinfo->pipe_out); /*close (netinfo->pipe_err); */ if (condition & G_IO_HUP) { if (netinfo->child_pid > 0) waitpid (netinfo->child_pid, NULL, WNOHANG); netinfo_toggle_state (netinfo, ACTIVE, NULL); } if (condition & G_IO_NVAL) { gchar *msg_nval = _("Information not available"); int len_nval; len_nval = strlen (msg_nval); (netinfo->process_line) ((gpointer) netinfo, msg_nval, len_nval, NULL); } return FALSE; }
void scan_do (Netinfo * netinfo) { const gchar *host = NULL; GtkTreeModel *model; struct sockaddr_in addr; struct sockaddr_in6 addr6; struct hostent *hp = NULL; struct servent *service = NULL; gint i, sock, start_port = 1, end_port = 65535; GIOChannel *channel; GIOChannel *channel2; gint pfd[2]; gint pid; gchar buf[SIZE]; gchar *service_name = NULL; gint ip_version, pf; struct sockaddr *addr_ptr; gint size; g_return_if_fail (netinfo != NULL); /* Because of the delay, we can't check twice for a hostname/IP. * It was made before this function was called. Anyway, we * check at least if we have a text as hostname */ if (netinfo_validate_domain (netinfo) == FALSE) { netinfo_stop_process_command (netinfo); return; } /* signal handling */ signal (SIGCHLD, wait_for_child); host = netinfo_get_host (netinfo); if (netinfo->stbar_text) g_free (netinfo->stbar_text); netinfo->stbar_text = g_strdup_printf (_("Scanning %s for open ports"), host); /* Clear the current output */ model = gtk_tree_view_get_model (GTK_TREE_VIEW (netinfo->output)); if (GTK_IS_LIST_STORE (model)) { gtk_list_store_clear (GTK_LIST_STORE (model)); } switch (ip_version = netinfo_get_ip_version (netinfo)) { case IPV4: pf = PF_INET; break; case IPV6: pf = PF_INET6; break; case -1: default: #ifdef DEBUG g_print ("Error: Host unkown\n"); #endif /* DEBUG */ return; /*g_return_if_fail (hp != NULL);*/ break; } hp = gethostbyname2 (host, pf); if (pipe (pfd) == -1) { perror ("pipe failed"); return; } netinfo_toggle_state (netinfo, INACTIVE, NULL); if ((pid = fork ()) < 0) { perror ("fork failed"); return; } if (pid == 0) { /* child */ close (pfd[0]); for (i = start_port; i <= end_port; i++) { if ((sock = socket (pf, SOCK_STREAM, 0)) == -1) { #ifdef DEBUG g_print ("Unable to create socket\n"); #endif /* DEBUG */ continue; } channel = g_io_channel_unix_new (sock); if (ip_version == IPV4) { addr.sin_family = PF_INET; bcopy (hp->h_addr, &addr.sin_addr, hp->h_length); addr.sin_port = htons (i); addr_ptr = (struct sockaddr *) &addr; size = sizeof (addr); } else { addr6.sin6_family = PF_INET6; addr6.sin6_flowinfo = 0; bcopy (hp->h_addr, &addr6.sin6_addr, hp->h_length); addr6.sin6_port = htons (i); addr_ptr = (struct sockaddr *) &addr6; size = sizeof (addr6); } if (connect (sock, addr_ptr, size) == 0) { service = getservbyport (htons (i), "tcp"); if (service != NULL) { service_name = g_strdup (service->s_name); } else { service_name = g_strdup (_("unknown")); } /* Translators: "open" is a network status and should be one word. */ g_sprintf (buf, "%d %s %s\n", i, _("open"), service_name); g_free (service_name); write (pfd[1], buf, strlen (buf)); } /* close (sock); */ g_io_channel_shutdown (channel, FALSE, NULL); } close (pfd[1]); exit (0); } else { /* parent */ close (pfd[1]); netinfo->child_pid = pid; netinfo->pipe_out = pfd[0]; channel2 = g_io_channel_unix_new (pfd[0]); g_io_add_watch (channel2, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, netinfo_io_text_buffer_dialog, netinfo); g_io_channel_unref (channel2); } }