示例#1
0
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);
}
示例#2
0
void
netinfo_process_command (Netinfo * netinfo)
{
	g_return_if_fail (netinfo != NULL);

	netinfo_toggle_state (netinfo, INACTIVE, NULL);

	netinfo_text_buffer_insert (netinfo);
}
示例#3
0
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;
}
示例#4
0
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);
	}
	
}