PurpleBOSHConnection* jabber_bosh_connection_init(JabberStream *js, const char *url) { PurpleBOSHConnection *conn; char *host, *path, *user, *passwd; int port; if (!purple_url_parse(url, &host, &port, &path, &user, &passwd)) { purple_debug_info("jabber", "Unable to parse given URL.\n"); return NULL; } conn = g_new0(PurpleBOSHConnection, 1); conn->host = host; conn->port = port; conn->path = g_strdup_printf("/%s", path); g_free(path); conn->pipelining = TRUE; if (purple_ip_address_is_valid(host)) js->serverFQDN = g_strdup(js->user->domain); else js->serverFQDN = g_strdup(host); if ((user && user[0] != '\0') || (passwd && passwd[0] != '\0')) { purple_debug_info("jabber", "Ignoring unexpected username and password " "in BOSH URL.\n"); } g_free(user); g_free(passwd); conn->js = js; /* * Random 64-bit integer masked off by 2^52 - 1. * * This should produce a random integer in the range [0, 2^52). It's * unlikely we'll send enough packets in one session to overflow the rid. */ conn->rid = ((guint64)g_random_int() << 32) | g_random_int(); conn->rid &= 0xFFFFFFFFFFFFFLL; conn->pending = purple_circ_buffer_new(0 /* default grow size */); conn->state = BOSH_CONN_OFFLINE; if (purple_strcasestr(url, "https://") != NULL) conn->ssl = TRUE; else conn->ssl = FALSE; conn->connections[0] = jabber_bosh_http_connection_init(conn); return conn; }
void BuddyListNode::updateFilterVisibility(const char *name) { if (!isVisible()) return; const char *filter = BUDDYLIST->getFilterString(); if (!filter[0]) return; // filtering is active setVisibility(purple_strcasestr(name, filter)); }
static void search_cb(GtkWidget *button, PidginLogViewer *lv) { const char *search_term = gtk_entry_get_text(GTK_ENTRY(lv->entry)); GList *logs; if (!(*search_term)) { /* reset the tree */ gtk_tree_store_clear(lv->treestore); populate_log_tree(lv); g_free(lv->search); lv->search = NULL; gtk_imhtml_search_clear(GTK_IMHTML(lv->imhtml)); select_first_log(lv); return; } if (lv->search != NULL && !strcmp(lv->search, search_term)) { /* Searching for the same term acts as "Find Next" */ gtk_imhtml_search_find(GTK_IMHTML(lv->imhtml), lv->search); return; } pidgin_set_cursor(lv->window, GDK_WATCH); g_free(lv->search); lv->search = g_strdup(search_term); gtk_tree_store_clear(lv->treestore); gtk_imhtml_clear(GTK_IMHTML(lv->imhtml)); for (logs = lv->logs; logs != NULL; logs = logs->next) { char *read = purple_log_read((PurpleLog*)logs->data, NULL); if (read && *read && purple_strcasestr(read, search_term)) { GtkTreeIter iter; PurpleLog *log = logs->data; gtk_tree_store_append (lv->treestore, &iter, NULL); gtk_tree_store_set(lv->treestore, &iter, 0, log_get_date(log), 1, log, -1); } g_free(read); } select_first_log(lv); pidgin_clear_cursor(lv->window); }
static void jabber_bosh_http_connection_process(PurpleHTTPConnection *conn) { const char *cursor; cursor = conn->read_buf->str + conn->handled_len; if (purple_debug_is_verbose()) purple_debug_misc("jabber", "BOSH server sent: %s\n", cursor); /* TODO: Chunked encoding and check response version :/ */ if (!conn->headers_done) { const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length:"); const char *connection = purple_strcasestr(cursor, "\r\nConnection:"); const char *end_of_headers = strstr(cursor, "\r\n\r\n"); /* Make sure Content-Length is in headers, not body */ if (content_length && (!end_of_headers || content_length < end_of_headers)) { int len; if (strstr(content_length, "\r\n") == NULL) /* * The packet ends in the middle of the Content-Length line. * We'll try again later when we have more. */ return; len = atoi(content_length + strlen("\r\nContent-Length:")); if (len == 0) purple_debug_warning("jabber", "Found mangled Content-Length header, or server returned 0-length response.\n"); conn->body_len = len; } if (connection && (!end_of_headers || content_length < end_of_headers)) { const char *tmp; if (strstr(connection, "\r\n") == NULL) return; tmp = connection + strlen("\r\nConnection:"); while (*tmp && (*tmp == ' ' || *tmp == '\t')) ++tmp; if (!g_ascii_strncasecmp(tmp, "close", strlen("close"))) { conn->close = TRUE; jabber_bosh_disable_pipelining(conn->bosh); } } if (end_of_headers) { conn->headers_done = TRUE; conn->handled_len = end_of_headers - conn->read_buf->str + 4; } else { conn->handled_len = conn->read_buf->len; return; } } /* Have we handled everything in the buffer? */ if (conn->handled_len >= conn->read_buf->len) return; /* Have we read all that the Content-Length promised us? */ if (conn->read_buf->len - conn->handled_len < conn->body_len) return; --conn->requests; --conn->bosh->requests; http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len, conn->bosh); /* Connection: Close? */ if (conn->close && conn->state == HTTP_CONN_CONNECTED) { if (purple_debug_is_verbose()) purple_debug_misc("jabber", "bosh (%p), server sent Connection: " "close\n", conn); http_connection_disconnected(conn); } if (conn->bosh->state == BOSH_CONN_ONLINE && (conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) { purple_debug_misc("jabber", "BOSH: Sending an empty request\n"); jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); } g_string_free(conn->read_buf, TRUE); conn->read_buf = NULL; conn->headers_done = FALSE; conn->handled_len = conn->body_len = 0; }
static gboolean msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, size_t size, char **ret_buf, size_t *ret_size, gboolean *error) { const char *s, *c; char *header, *body; const char *body_start; char *tmp; size_t body_len = 0; g_return_val_if_fail(httpconn != NULL, FALSE); g_return_val_if_fail(buf != NULL, FALSE); g_return_val_if_fail(size > 0, FALSE); g_return_val_if_fail(ret_buf != NULL, FALSE); g_return_val_if_fail(ret_size != NULL, FALSE); g_return_val_if_fail(error != NULL, FALSE); #if 0 purple_debug_info("msn", "HTTP: parsing data {%s}\n", buf); #endif /* Healthy defaults. */ body = NULL; *ret_buf = NULL; *ret_size = 0; *error = FALSE; /* First, some tests to see if we have a full block of stuff. */ if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) { *error = TRUE; return FALSE; } if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) { if ((s = strstr(buf, "\r\n\r\n")) == NULL) return FALSE; s += 4; if (*s == '\0') { *ret_buf = g_strdup(""); *ret_size = 0; msn_httpconn_process_queue(httpconn); return TRUE; } buf = s; size -= (s - buf); } if ((s = strstr(buf, "\r\n\r\n")) == NULL) /* Need to wait for the full HTTP header to arrive */ return FALSE; s += 4; /* Skip \r\n\r\n */ header = g_strndup(buf, s - buf); body_start = s; body_len = size - (body_start - buf); if ((s = purple_strcasestr(header, "Content-Length: ")) != NULL) { int tmp_len; s += strlen("Content-Length: "); if ((c = strchr(s, '\r')) == NULL) { g_free(header); return FALSE; } tmp = g_strndup(s, c - s); tmp_len = atoi(tmp); g_free(tmp); if (body_len != tmp_len) { /* Need to wait for the full packet to arrive */ g_free(header); #if 0 purple_debug_warning("msn", "body length (%d) != content length (%d)\n", body_len, tmp_len); #endif return FALSE; } } body = g_malloc(body_len + 1); memcpy(body, body_start, body_len); body[body_len] = '\0'; #ifdef MSN_DEBUG_HTTP purple_debug_misc("msn", "Incoming HTTP buffer (header): {%s}\n", header); #endif /* Now we should be able to process the data. */ if ((s = purple_strcasestr(header, "X-MSN-Messenger: ")) != NULL) { gchar *full_session_id = NULL, *gw_ip = NULL, *session_action = NULL; char *t, *session_id; char **elems, **cur, **tokens; full_session_id = gw_ip = session_action = NULL; s += strlen("X-MSN-Messenger: "); if ((c = strchr(s, '\r')) == NULL) { msn_session_set_error(httpconn->session, MSN_ERROR_HTTP_MALFORMED, NULL); purple_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}\n", buf); g_free(header); g_free(body); return FALSE; } tmp = g_strndup(s, c - s); elems = g_strsplit(tmp, "; ", 0); for (cur = elems; *cur != NULL; cur++) { tokens = g_strsplit(*cur, "=", 2); if (strcmp(tokens[0], "SessionID") == 0) { g_free(full_session_id); full_session_id = tokens[1]; } else if (strcmp(tokens[0], "GW-IP") == 0) { g_free(gw_ip); gw_ip = tokens[1]; } else if (strcmp(tokens[0], "Session") == 0) { g_free(session_action); session_action = tokens[1]; } else g_free(tokens[1]); g_free(tokens[0]); /* Don't free each of the tokens, only the array. */ g_free(tokens); } g_strfreev(elems); g_free(tmp); t = strchr(full_session_id, '.'); if (t != NULL) session_id = g_strndup(full_session_id, t - full_session_id); else { purple_debug_error("msn", "Malformed full_session_id[%s]\n", full_session_id ? full_session_id : NULL); session_id = g_strdup(full_session_id); } if (session_action == NULL || strcmp(session_action, "close") != 0) { g_free(httpconn->full_session_id); httpconn->full_session_id = full_session_id; g_free(httpconn->session_id); httpconn->session_id = session_id; g_free(httpconn->host); httpconn->host = gw_ip; } else { MsnServConn *servconn; /* It's going to die. */ /* poor thing */ servconn = httpconn->servconn; /* I'll be honest, I don't fully understand all this, but this * causes crashes, Stu. */ /* if (servconn != NULL) servconn->wasted = TRUE; */ g_free(full_session_id); g_free(session_id); g_free(gw_ip); } g_free(session_action); } g_free(header); *ret_buf = body; *ret_size = body_len; msn_httpconn_process_queue(httpconn); return TRUE; }
/*------------------------------------------------------------------------ * Callback when data is received from the HTTP server. * * @param user_data The MXit session object * @param source The file-descriptor on which data was received * @param cond Condition which caused the callback (PURPLE_INPUT_READ) */ static void mxit_cb_http_read( gpointer user_data, gint source, PurpleInputCondition cond ) { struct MXitSession* session = (struct MXitSession*) user_data; char buf[256]; int buflen; char* body; int bodylen; char* ch; int len; char* tmp; int res; char* next; purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_http_read\n" ); if ( session->rx_state == RX_STATE_RLEN ) { /* we are reading in the HTTP headers */ /* copy partial headers if we have any part saved */ memcpy( buf, session->rx_dbuf, session->rx_i ); buflen = session->rx_i; /* read bytes from the socket */ len = read( session->fd, buf + buflen, sizeof( buf ) - ( buflen + 1 ) ); if ( len <= 0 ) { /* connection has been terminated, or error occurred */ goto done; } buf[buflen+len] = '\0'; //nextpacket: #ifdef DEBUG_HTTP purple_debug_info( MXIT_PLUGIN_ID, "HTTP POST READ 1: (%i)\n", len ); dump_bytes( session, buf + buflen, len ); #endif /* see if we have all the HTTP headers yet */ ch = strstr( buf, HTTP_11_SEPERATOR ); if ( !ch ) { /* we need to wait for more input, so save what we have */ session->rx_i = buflen + len; memcpy( session->rx_dbuf, buf, session->rx_i ); return; } buflen += len; /* we have the header's end now skip over the http separator to get the body offset */ ch += strlen( HTTP_11_SEPERATOR ); *(ch - 1) = '\0'; body = ch; res = buflen - ( ch - buf ); if ( res > 0 ) { /* we read more bytes than just the header so copy it over */ memcpy( session->rx_dbuf, ch, res ); session->rx_i = res; } else { session->rx_i = 0; } /* test for a good response */ if ( ( strncmp( buf, HTTP_11_200_OK, strlen( HTTP_11_200_OK ) ) != 0 ) && ( strncmp( buf, HTTP_11_100_CONT, strlen( HTTP_11_100_CONT ) ) != 0 ) ) { /* bad result */ purple_debug_error( MXIT_PLUGIN_ID, "HTTP error: %s\n", ch ); goto done; } /* find the content-length */ ch = (char*) purple_strcasestr( buf, HTTP_CONTENT_LEN ); if ( !ch ) { /* bad request. it does not contain a content-length header */ purple_debug_error( MXIT_PLUGIN_ID, "HTTP reply received without content-length header (ignoring packet)\n" ); goto done; } /* parse the content-length */ ch += strlen( HTTP_CONTENT_LEN ); tmp = strchr( ch, '\r' ); if ( !tmp ) { purple_debug_error( MXIT_PLUGIN_ID, "Received bad HTTP reply packet (ignoring packet)\n" ); goto done; } tmp = g_strndup( ch, tmp - ch ); bodylen = atoi( tmp ); g_free( tmp ); tmp = NULL; if ( buflen + bodylen >= CP_MAX_PACKET ) { /* this packet is way to big */ goto done; } else if ( buflen > ( ( body - buf ) + bodylen ) ) { /* we have a second packet here */ next = body + bodylen; session->rx_res = 0; } else { session->rx_res = bodylen - session->rx_i; } if ( session->rx_res == 0 ) { /* we have read all the data */ session->rx_i = bodylen; session->rx_state = RX_STATE_PROC; } else { /* there is still some data outstanding */ session->rx_state = RX_STATE_DATA; } } else if ( session->rx_state == RX_STATE_DATA ) { /* we are reading the HTTP content (body) */ /* read bytes from the socket */ len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res ); if ( len <= 0 ) { /* connection has been terminated, or error occurred */ goto done; } #ifdef DEBUG_HTTP purple_debug_info( MXIT_PLUGIN_ID, "HTTP POST READ 2: (%i)\n", len ); dump_bytes( session, &session->rx_dbuf[session->rx_i], len ); #endif session->rx_i += len; session->rx_res -= len; if ( session->rx_res == 0 ) { /* ok, so now we have read in the whole packet */ session->rx_state = RX_STATE_PROC; } } if ( session->rx_state == RX_STATE_PROC ) { mxit_parse_packet( session ); #if 0 if ( next ) { /* there is another packet of which we read some data */ /* reset input */ session->rx_state = RX_STATE_RLEN; session->rx_lbuf[0] = '\0'; session->rx_i = 0; session->rx_res = 0; /* move read data */ len = next - buf; buflen = len; memcpy( buf, next, len ); goto nextpacket; } #endif /* we are done */ goto done; } return; done: close( session->fd ); purple_input_remove( session->http_handler ); session->http_handler = 0; }
/*--------------------------------------------------------------------------* * PUBLIC FUNCTIONS * *--------------------------------------------------------------------------*/ void ap_gtk_add_message (APUpdateType update_type, APMessageType type, const gchar *text) { GtkTreeIter iter; struct tm *cur_time; char *time_string, *simple_text, *s; time_t *general_time; gchar *type_string; // Create the time string general_time = (time_t *) malloc (sizeof(time_t)); time (general_time); cur_time = ap_localtime (general_time); free (general_time); time_string = (char *) malloc (sizeof(char[32])); *time_string = '\0'; strftime (time_string, 31, "<b>%I:%M %p</b>", cur_time); free (cur_time); // Create the type string type_string = strdup("<b>Status</b>"); switch (type) { case AP_MESSAGE_TYPE_PROFILE: type_string = strdup (_("<b>User profile</b>")); break; case AP_MESSAGE_TYPE_AWAY: type_string = strdup (_("<b>Away message</b>")); break; case AP_MESSAGE_TYPE_AVAILABLE: type_string = strdup (_("<b>Available message</b>")); break; case AP_MESSAGE_TYPE_STATUS: type_string = strdup (_("<b>Status message</b>")); break; default: type_string = strdup (_("<b>Other</b>")); break; } // Simplify the text if (text != NULL) { simple_text = strdup (text); // Only show the first line s = (gchar *) purple_strcasestr (simple_text, "<br>"); if (s != NULL) { *s++ = '.'; *s++ = '.'; *s++ = '.'; *s = '\0'; } // Strip HTML s = simple_text; simple_text = purple_markup_strip_html (simple_text); free (s); } else { simple_text = NULL; } // Add it gtk_list_store_prepend (message_list, &iter); gtk_list_store_set (message_list, &iter, 0, time_string, 1, type_string, 2, simple_text, 3, text, -1); free (type_string); free (time_string); if (simple_text) free (simple_text); // Delete if too many if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(message_list), &iter, NULL, AP_GTK_MAX_MESSAGES)) { gtk_list_store_remove (message_list, &iter); } // Move the timeout bar ap_gtk_timeout_start (update_type); // Check if it needs to be visible or not if (type != AP_MESSAGE_TYPE_PROFILE && ap_is_currently_away () != ap_previously_away) { update_summary_visibility (); } }
static void jabber_bosh_http_connection_process(PurpleHTTPConnection *conn) { const char *cursor; cursor = conn->read_buf->str + conn->handled_len; if (!conn->headers_done) { const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length"); const char *end_of_headers = strstr(cursor, "\r\n\r\n"); /* Make sure Content-Length is in headers, not body */ if (content_length && (!end_of_headers || content_length < end_of_headers)) { const char *sep; const char *eol; int len; if ((sep = strstr(content_length, ": ")) == NULL || (eol = strstr(sep, "\r\n")) == NULL) /* * The packet ends in the middle of the Content-Length line. * We'll try again later when we have more. */ return; len = atoi(sep + 2); if (len == 0) purple_debug_warning("jabber", "Found mangled Content-Length header.\n"); conn->body_len = len; } if (end_of_headers) { conn->headers_done = TRUE; conn->handled_len = end_of_headers - conn->read_buf->str + 4; cursor = end_of_headers + 4; } else { conn->handled_len = conn->read_buf->len; return; } } /* Have we handled everything in the buffer? */ if (conn->handled_len >= conn->read_buf->len) return; /* Have we read all that the Content-Length promised us? */ if (conn->read_buf->len - conn->handled_len < conn->body_len) return; --conn->requests; --conn->bosh->requests; http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len, conn->bosh); if (conn->bosh->state == BOSH_CONN_ONLINE && (conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) { purple_debug_misc("jabber", "BOSH: Sending an empty request\n"); jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); } g_string_free(conn->read_buf, TRUE); conn->read_buf = NULL; conn->headers_done = FALSE; conn->handled_len = conn->body_len = 0; }