/* returns the byte read or -1 if EOF, exits on failure */ static int read_byte (GIOChannel *io_channel) { /* expect binary mode */ g_assert (g_io_channel_get_encoding (io_channel) == NULL); GError *error = NULL; unsigned char c = 0; gsize bytes_read = -1; GIOStatus status = g_io_channel_read_chars (io_channel, (char *) &c, 1, &bytes_read, &error); g_assert (status != G_IO_STATUS_AGAIN); /* can't happen right? */ if (status == G_IO_STATUS_ERROR) { g_printerr ("bin-search: g_io_channel_read_chars: %s\n", error->message); exit (6); } else if (status == G_IO_STATUS_EOF) return -1; /* success. sanity check */ g_assert (status == G_IO_STATUS_NORMAL); g_assert (bytes_read == 1); return c; }
static gboolean on_startup ( G_GNUC_UNUSED gpointer data ) { g_message ("startup."); g_sessions = g_hash_table_new (g_str_hash, g_str_equal); /* add stdin to event manager */ #ifndef G_OS_WIN32 g_stdin_channel = g_io_channel_unix_new (fileno(stdin)); #else g_stdin_channel = g_io_channel_win32_new_fd (fileno(stdin)); #endif printf ("binding stdin with encoding %s.\n", g_io_channel_get_encoding(g_stdin_channel)); g_io_add_watch (g_stdin_channel, G_IO_IN | G_IO_PRI, on_stdin_data, NULL); /* period timer to indicate some form of life */ // TODO: Gnome 2.14: replace with g_timeout_add_seconds() g_timeout_add(10 * 1000, (GSourceFunc)on_mark, NULL); puts ("READY"); fflush (stdout); return FALSE; }
gboolean xml_parser_parse_io_channel (XMLParser *parser, GIOChannel *io, gboolean recode, GError **error) { GIOStatus status; guchar buffer[8196]; gsize len = 0; gsize bytes; g_return_val_if_fail (parser != NULL, FALSE); g_return_val_if_fail (io != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (recode) { const gchar *io_encoding = g_io_channel_get_encoding (io); gchar *encoding = NULL; if (io_encoding && strcmp (io_encoding, "UTF-8")) { g_warning ("xml_parser_parse_io_channel(): " "The encoding has already been set on this IOChannel!"); return FALSE; } /* try to determine the encoding */ while (len < sizeof (buffer) && !encoding) { status = g_io_channel_read_chars (io, buffer + len, 1, &bytes, error); len += bytes; if (status == G_IO_STATUS_ERROR) return FALSE; if (status == G_IO_STATUS_EOF) break; encoding = xml_parse_encoding (buffer, len); } if (encoding) { if (!g_io_channel_set_encoding (io, encoding, error)) return FALSE; g_free (encoding); } } while (TRUE) { if (!xml_parser_parse (parser, buffer, len, error)) return FALSE; status = g_io_channel_read_chars (io, buffer, sizeof(buffer), &len, error); switch (status) { case G_IO_STATUS_ERROR: return FALSE; case G_IO_STATUS_EOF: return xml_parser_end_parse (parser, error); case G_IO_STATUS_NORMAL: case G_IO_STATUS_AGAIN: break; } } }
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; }
static VALUE rg_encoding(VALUE self) { return CSTR2RVAL(g_io_channel_get_encoding(_SELF(self))); }
static gboolean on_startup ( G_GNUC_UNUSED gpointer data ) { int e; g_message ("startup."); /* find PGM protocol id */ // TODO: fix valgrind errors int ipproto_pgm = IPPROTO_PGM; struct protoent *proto = getprotobyname ("pgm"); if (proto != NULL) { if (proto->p_proto != ipproto_pgm) { g_message ("Setting PGM protocol number to %i from /etc/protocols.\n", proto ->p_proto); ipproto_pgm = proto->p_proto; } } /* open socket for snooping */ g_message ("opening raw socket."); int sock = socket (PF_INET, SOCK_RAW, ipproto_pgm); if (sock < 0) { perror("on_startup() failed"); #ifdef G_OS_UNIX if (EPERM == errno && 0 != getuid()) { g_message ("PGM protocol requires this program to run as superuser."); } #endif g_main_loop_quit (g_loop); return FALSE; } int _t = 1; e = setsockopt (sock, IPPROTO_IP, IP_HDRINCL, (const char*)&_t, sizeof(_t)); if (e < 0) { perror ("on_startup() failed"); close (sock); g_main_loop_quit (g_loop); return FALSE; } #ifdef G_OS_UNIX /* drop out of setuid 0 */ if (0 == getuid ()) { g_message ("dropping superuser privileges."); setgroups(0, NULL); setuid ((gid_t)65534); setgid ((uid_t)65534); } #endif /* buffers */ int buffer_size = 0; socklen_t len = 0; e = getsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char*)&buffer_size, &len); if (e == 0) { g_message ("receive buffer set at %i bytes.\n", buffer_size); } e = getsockopt (sock, SOL_SOCKET, SO_SNDBUF, (char*)&buffer_size, &len); if (e == 0) { g_message ("send buffer set at %i bytes.\n", buffer_size); } /* bind */ struct sockaddr_in addr; memset (&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); e = bind (sock, (struct sockaddr*)&addr, sizeof(addr)); if (e < 0) { perror ("on_startup() failed"); close (sock); g_main_loop_quit (g_loop); return FALSE; } /* multicast */ struct ip_mreq mreq; memset (&mreq, 0, sizeof(mreq)); mreq.imr_interface.s_addr = htonl (INADDR_ANY); g_message ("listening on interface %s.\n", inet_ntoa (mreq.imr_interface)); mreq.imr_multiaddr.s_addr = inet_addr (g_network); g_message ("subscription on multicast address %s.\n", inet_ntoa (mreq.imr_multiaddr)); e = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)); if (e < 0) { perror ("on_startup() failed"); close (sock); g_main_loop_quit (g_loop); return FALSE; } /* multicast loopback */ /* multicast ttl */ /* add socket to event manager */ g_io_channel = g_io_channel_unix_new (sock); g_message ("socket opened with encoding %s.\n", g_io_channel_get_encoding (g_io_channel)); /* guint event = */ g_io_add_watch (g_io_channel, G_IO_IN | G_IO_PRI, on_io_data, NULL); /* period timer to indicate some form of life */ // TODO: Gnome 2.14: replace with g_timeout_add_seconds() g_timeout_add (10 * 1000, (GSourceFunc)on_mark, NULL); g_message ("startup complete."); return FALSE; }