static gboolean receive_args_until_done(GIOChannel *chan, GHashTable *return_table, GError **err) { GIOStatus iostat; GError *tmp_error = NULL; guint numargs = 0; while (1) { gchar *line; gsize term_pos; /* if we are getting too many args, connection could be malicious */ if (numargs >= 20) { g_set_error(err, g_quark_from_static_string("malicious connection"), 0, "malicious connection"); return FALSE; } /* get the string */ iostat = g_io_channel_read_line(chan, &line, NULL, &term_pos, &tmp_error); if (iostat == G_IO_STATUS_ERROR || tmp_error != NULL) { g_free(line); if (tmp_error != NULL) { g_propagate_error(err, tmp_error); } return FALSE; } else if (iostat == G_IO_STATUS_EOF) { g_free(line); g_set_error(err, g_quark_from_static_string("connection closed"), 0, "connection closed"); return FALSE; } *(line+term_pos) = '\0'; if (strcmp("done", line) == 0) { g_free(line); break; } else { gboolean parse_result; parse_result = dropbox_client_util_command_parse_arg(line, return_table); g_free(line); if (FALSE == parse_result) { g_set_error(err, g_quark_from_static_string("parse error"), 0, "parse error"); return FALSE; } } numargs += 1; } return TRUE; }
static gboolean handle_hook_server_input(GIOChannel *chan, GIOCondition cond, NautilusDropboxHookserv *hookserv) { /*debug_enter(); */ /* we have some sweet macros defined that allow us to write this async event handler like a microthread yeahh, watch out for context */ CRBEGIN(hookserv->hhsi.line); while (1) { hookserv->hhsi.command_args = g_hash_table_new_full((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_strfreev); hookserv->hhsi.numargs = 0; /* read the command name */ { gchar *line; CRREADLINE(hookserv->hhsi.line, chan, line); hookserv->hhsi.command_name = dropbox_client_util_desanitize(line); g_free(line); } /*debug("got a hook name: %s", hookserv->hhsi.command_name); */ /* now read each arg line (until a certain limit) until we receive "done" */ while (1) { gchar *line; /* if too many arguments, this connection seems malicious */ if (hookserv->hhsi.numargs >= 20) { CRHALT; } CRREADLINE(hookserv->hhsi.line, chan, line); if (strcmp("done", line) == 0) { g_free(line); break; } else { gboolean parse_result; parse_result = dropbox_client_util_command_parse_arg(line, hookserv->hhsi.command_args); g_free(line); if (FALSE == parse_result) { debug("bad parse"); CRHALT; } } hookserv->hhsi.numargs += 1; } { HookData *hd; hd = (HookData *) g_hash_table_lookup(hookserv->dispatch_table, hookserv->hhsi.command_name); if (hd != NULL) { (hd->hook)(hookserv->hhsi.command_args, hd->ud); } } g_free(hookserv->hhsi.command_name); g_hash_table_unref(hookserv->hhsi.command_args); hookserv->hhsi.command_name = NULL; hookserv->hhsi.command_args = NULL; } CREND; }