static void pending_read(struct bufferevent *bev, void *pending_ptr) { struct evwspendingconn* pending = (struct evwspendingconn *)pending_ptr; struct evbuffer* input = bufferevent_get_input(pending->bev); struct evbuffer_ptr end = evbuffer_search(input, "\r\n\r\n", 4, NULL); size_t len = evbuffer_get_length(input); if (end.pos == -1) { if (len > MAX_HTTP_HEADER_SIZE) { remove_pending(pending); free_pending(pending); } return; // full request not yet found } unsigned char* data = evbuffer_pullup(input, len); char accept_key[29]; struct evwsconnlistener* levws = pending->levws; const char* subprotocol = NULL; if (evaluate_websocket_handshake((char*)data, len, levws->supported_subprotocols, accept_key, &subprotocol)) { remove_pending(pending); free_pending(pending); return; } evbuffer_drain(input, len); bufferevent_setcb(pending->bev, NULL, NULL, NULL, pending); struct evbuffer* output = bufferevent_get_output(pending->bev); evbuffer_add_printf(output, "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: %s\r\n", accept_key); if (subprotocol != NULL) { evbuffer_add_printf(output, "Sec-WebSocket-Protocol: %s\r\n\r\n", subprotocol); } else { evbuffer_add_printf(output, "\r\n"); } remove_pending(pending); struct evwsconn *wsconn = evwsconn_new(pending->bev, subprotocol); pending->bev = NULL; levws->cb(levws, wsconn, pending->address, pending->socklen, levws->user_data); free_pending(pending); }
static void pending_event(struct bufferevent *bev, short events, void *pending_ptr) { struct evwspendingconn* pending = (struct evwspendingconn *)pending_ptr; if (events & BEV_EVENT_EOF) { fprintf(stderr, "Connection closed\n"); } else if (events & BEV_EVENT_ERROR) { fprintf(stderr, "Connection error\n"); if (errno != 0) { fprintf(stderr, "Got an error on the connection: %s\n", strerror(errno)); } unsigned long ssl_error = ERR_get_error(); if (ssl_error != 0) { fprintf(stderr, "SSL error: %s\n", ERR_error_string(ssl_error, NULL)); } ssl_error = bufferevent_get_openssl_error(bev); if (ssl_error != 0) { fprintf(stderr, "Got an SSL error on the connection: %s\n", ERR_error_string(ssl_error, NULL)); } } else if (events & BEV_EVENT_CONNECTED) { return; // SSL connected } else { fprintf(stderr, "Unknown event: %x\n", (int)events); } remove_pending(pending); free_pending(pending); }
static gboolean session_request_proceed(gpointer data) { struct pending_data *pending = data; struct transfer_data *transfer = pending->transfer; pending->cb(transfer->session, NULL, transfer); free_pending(pending); return FALSE; }
static gboolean plugin_unload(GaimPlugin * plugin) { gaim_signals_disconnect_by_handle(plugin); GSList *search = NULL; for (search = pending_list; search; search = search->next) { free_pending(search, TRUE); } return TRUE; }
void evwsconnlistener_free(struct evwsconnlistener *levws) { if (levws == NULL) { return; } struct evwspendingconn* curr = levws->head; while (curr) { struct evwspendingconn* temp = curr; curr = curr->next; free_pending(temp); } evconnlistener_free(levws->lev); free(levws); }
/** * Purge pending_list of entries older than BOT_MAX_MINUTES minutes */ void expire_pending_list() { const glong max_sec = 60 * BOT_MAX_MINUTES; GTimeVal *now = NULL; now = g_new0(GTimeVal, 1); g_get_current_time(now); GSList *search = NULL; for (search = pending_list; search; search = search->next) { PendingMessage *pending = search->data; if (pending->tv_sec < (now->tv_sec - max_sec)) { free_pending(search, TRUE); } } g_free(now); }
static void session_request_reply(DBusPendingCall *call, gpointer user_data) { struct session_data *session = user_data; struct agent_data *agent = session->agent; struct pending_data *pending = agent->pending; DBusMessage *reply = dbus_pending_call_steal_reply(call); const char *name; DBusError derr; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { GError *gerr = NULL; error("Replied with an error: %s, %s", derr.name, derr.message); dbus_error_free(&derr); dbus_message_unref(reply); g_set_error(&gerr, OBEX_IO_ERROR, -ECANCELED, "%s", derr.message); session_terminate_transfer(session, pending->transfer, gerr); g_clear_error(&gerr); return; } dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); DBG("Agent.Request() reply: %s", name); if (strlen(name)) { g_free(pending->transfer->name); pending->transfer->name = g_strdup(name); } agent->pending = NULL; pending->cb(session, NULL, pending->transfer); dbus_message_unref(reply); free_pending(pending); return; }
static void agent_free(struct session_data *session) { struct agent_data *agent = session->agent; if (agent->watch) g_dbus_remove_watch(session->conn, agent->watch); if (agent->pending) { dbus_pending_call_cancel(agent->pending->call); free_pending(agent->pending); } session->agent = NULL; g_free(agent->name); g_free(agent->path); g_free(agent); }
/** * This is our callback for the receiving-im-msg signal. * * We return TRUE to block the IM, FALSE to accept the IM */ static gboolean receiving_im_msg_cb(GaimAccount * account, char **sender, char **buffer, int *flags, void *data) { gboolean retval = FALSE; /* assume the sender is allowed */ gboolean found = FALSE; gint pos = -1; char *botmsg = NULL; PendingMessage *pending = NULL; GSList *slist = NULL; GSList *search = NULL; GaimConnection *connection = NULL; /* expire any old entries in pending */ expire_pending_list(); connection = gaim_account_get_connection(account); /* not good, but don't do anything */ if (!connection || !sender) { return retval; } /* if there is already an open conversation, allowed it */ if (gaim_find_conversation_with_account(*sender, account)) { return retval; } /* don't make buddies use the challenge/response system */ if (gaim_find_buddy(account, *sender)) { return retval; } /* don't make permit list members use the challenge/response system */ for (slist = account->permit; slist != NULL; slist = slist->next) { if (!gaim_utf8_strcasecmp (*sender, gaim_normalize(account, (char *) slist->data))) { return retval; } } /* if there is no question or no answer, allow the sender */ const char *question = gaim_prefs_get_string("/plugins/core/bot/challenger/question"); const char *answer = gaim_prefs_get_string("/plugins/core/bot/challenger/answer"); if (!question || !answer) { return retval; } /* blank / null message ... can this even happen? */ if (!*buffer) { return retval; } /* search if this sender is already in pending */ for (search = pending_list; search; search = search->next) { pending = search->data; pos = g_slist_position(pending_list, search); if (protocmp(account, pending) && usercmp(account, pending) && sendercmp(*sender, pending)) { found = TRUE; break; } } if (!found) { /** * its the first time through, save the nick/msg to the * queue and ask the question */ GTimeVal *now = NULL; now = g_new0(GTimeVal, 1); g_get_current_time(now); PendingMessage *newpend = NULL; newpend = g_new0(PendingMessage, 1); newpend->tv_sec = now->tv_sec; newpend->protocol = g_strdup(account->protocol_id); newpend->username = g_strdup(account->username); newpend->sender = g_strdup(*sender); newpend->message = g_strdup(*buffer); pending_list = g_slist_append(pending_list, newpend); botmsg = g_strdup_printf(_ ("Bot Challenger engaged: you are now being ignored! Your message will be delivered if you can correctly answer the following question within %i minutes: %s"), BOT_MAX_MINUTES, question); send_auto_reply(account, *sender, botmsg); g_free(now); g_free(botmsg); retval = TRUE; } else { if (gaim_utf8_strcasecmp(*buffer, answer)) { /** * Sorry, thanks for playing, please try again */ retval = TRUE; } else { botmsg = _ ("Bot Challenger accepted your answer and delivered your original message. You may now speak freely."); send_auto_reply(account, *sender, botmsg); if (gaim_prefs_get_bool ("/plugins/core/bot/challenger/auto_add_permit")) { if (!gaim_privacy_permit_add(account, *sender, FALSE)) { gaim_debug_info("bot-challenger", "Unable to add %s/%s/%s to permit list\n", *sender, pending->username, pending->protocol); } } /** * Free what is currently in the buffer (the correct answer) * and replace it with the user's first message that was * queued, pending the correct answer. I think some other * process is supposed to free the buffer after its sent. */ g_free(*buffer); *buffer = pending->message; /* Clean up everything else except pending->message */ free_pending(search, FALSE); retval = FALSE; /* Don't block this message */ } } debug_pending_list(); return retval; /* returning TRUE will block the IM */ }