static void connect_cb(gpointer data, gint source, const gchar *error_message) { MsnServConn *servconn; servconn = data; servconn->connect_data = NULL; servconn->processing = FALSE; if (servconn->wasted) { if (source >= 0) close(source); msn_servconn_destroy(servconn); return; } servconn->fd = source; if (source >= 0) { servconn->connected = TRUE; /* Someone wants to know we connected. */ servconn->connect_cb(servconn); servconn->inpa = gaim_input_add(servconn->fd, GAIM_INPUT_READ, read_cb, data); } else { msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT); } }
static void servconn_write_cb(gpointer data, gint source, GaimInputCondition cond) { MsnServConn *servconn = data; int ret, writelen; writelen = gaim_circ_buffer_get_max_read(servconn->tx_buf); if (writelen == 0) { gaim_input_remove(servconn->tx_handler); servconn->tx_handler = -1; return; } ret = write(servconn->fd, servconn->tx_buf->outptr, writelen); if (ret < 0 && errno == EAGAIN) return; else if (ret <= 0) { msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE); return; } gaim_circ_buffer_mark_read(servconn->tx_buf, ret); }
static void connect_cb(gpointer data, gint source, const char *error_message) { MsnServConn *servconn; servconn = data; servconn->connect_data = NULL; servconn->fd = source; if (source >= 0) { servconn->connected = TRUE; /* Someone wants to know we connected. */ servconn->connect_cb(servconn); servconn->inpa = purple_input_add(servconn->fd, PURPLE_INPUT_READ, read_cb, data); servconn_timeout_renew(servconn); } else { purple_debug_error("msn", "Connection error: %s\n", error_message); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT, error_message); } }
static void read_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnServConn *servconn; char buf[MSN_BUF_LEN]; gssize len; servconn = data; if (servconn->type == MSN_SERVCONN_NS) servconn->session->account->gc->last_received = time(NULL); len = read(servconn->fd, buf, sizeof(buf) - 1); if (len < 0 && errno == EAGAIN) return; if (len <= 0) { purple_debug_error("msn", "servconn %03d read error, " "len: %" G_GSSIZE_FORMAT ", errno: %d, error: %s\n", servconn->num, len, errno, g_strerror(errno)); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ, NULL); return; } buf[len] = '\0'; servconn->rx_buf = g_realloc(servconn->rx_buf, len + servconn->rx_len + 1); memcpy(servconn->rx_buf + servconn->rx_len, buf, len + 1); servconn->rx_len += len; servconn = msn_servconn_process_data(servconn); if (servconn) servconn_timeout_renew(servconn); }
static void servconn_write_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnServConn *servconn = data; gssize ret; int writelen; writelen = purple_circ_buffer_get_max_read(servconn->tx_buf); if (writelen == 0) { purple_input_remove(servconn->tx_handler); servconn->tx_handler = 0; return; } ret = write(servconn->fd, servconn->tx_buf->outptr, writelen); if (ret < 0 && errno == EAGAIN) return; else if (ret <= 0) { msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE, NULL); return; } purple_circ_buffer_mark_read(servconn->tx_buf, ret); servconn_timeout_renew(servconn); }
static void connect_cb(gpointer data, gint source, const gchar *error_message) { MsnHttpConn *httpconn; httpconn = data; httpconn->connect_data = NULL; httpconn->fd = source; if (source >= 0) { httpconn->inpa = purple_input_add(httpconn->fd, PURPLE_INPUT_READ, read_cb, data); httpconn->timer = purple_timeout_add_seconds(2, msn_httpconn_poll, httpconn); msn_httpconn_process_queue(httpconn); } else { purple_debug_error("msn", "HTTP: Connection error: %s\n", error_message ? error_message : "(null)"); msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); } }
static gboolean write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) { gssize res; /* result of the write operation */ if (httpconn->tx_handler == 0) res = write(httpconn->fd, data, data_len); else { res = -1; errno = EAGAIN; } if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK))) { msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); return FALSE; } if (res < 0 || res < data_len) { if (res < 0) res = 0; if (httpconn->tx_handler == 0 && httpconn->fd) httpconn->tx_handler = purple_input_add(httpconn->fd, PURPLE_INPUT_WRITE, httpconn_write_cb, httpconn); purple_circ_buffer_append(httpconn->tx_buf, data + res, data_len - res); } return TRUE; }
static void httpconn_write_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnHttpConn *httpconn; gssize ret; int writelen; httpconn = data; writelen = purple_circ_buffer_get_max_read(httpconn->tx_buf); if (writelen == 0) { purple_input_remove(httpconn->tx_handler); httpconn->tx_handler = 0; return; } ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); if (ret <= 0) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) /* No worries */ return; /* Error! */ msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); return; } purple_circ_buffer_mark_read(httpconn->tx_buf, ret); /* TODO: I don't think these 2 lines are needed. Remove them? */ if (ret == writelen) httpconn_write_cb(data, source, cond); }
gssize msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len) { gssize ret = 0; g_return_val_if_fail(servconn != NULL, 0); if (!servconn->session->http_method) { if (servconn->tx_handler == 0) { switch (servconn->type) { case MSN_SERVCONN_NS: case MSN_SERVCONN_SB: ret = write(servconn->fd, buf, len); break; #if 0 case MSN_SERVCONN_DC: ret = write(servconn->fd, &buf, sizeof(len)); ret = write(servconn->fd, buf, len); break; #endif default: ret = write(servconn->fd, buf, len); break; } } else { ret = -1; errno = EAGAIN; } if (ret < 0 && errno == EAGAIN) ret = 0; if (ret >= 0 && ret < len) { if (servconn->tx_handler == 0) servconn->tx_handler = purple_input_add( servconn->fd, PURPLE_INPUT_WRITE, servconn_write_cb, servconn); purple_circ_buffer_append(servconn->tx_buf, buf + ret, len - ret); } } else { ret = msn_httpconn_write(servconn->httpconn, buf, len); } if (ret == -1) { msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE, NULL); } servconn_timeout_renew(servconn); return ret; }
static void read_cb(gpointer data, gint source, GaimInputCondition cond) { MsnServConn *servconn; MsnSession *session; char buf[MSN_BUF_LEN]; char *cur, *end, *old_rx_buf; int len, cur_len; servconn = data; session = servconn->session; len = read(servconn->fd, buf, sizeof(buf) - 1); if (len < 0 && errno == EAGAIN) return; else if (len <= 0) { gaim_debug_error("msn", "servconn read error, len: %d error: %s\n", len, strerror(errno)); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ); return; } buf[len] = '\0'; servconn->rx_buf = g_realloc(servconn->rx_buf, len + servconn->rx_len + 1); memcpy(servconn->rx_buf + servconn->rx_len, buf, len + 1); servconn->rx_len += len; end = old_rx_buf = servconn->rx_buf; servconn->processing = TRUE; do { cur = end; if (servconn->payload_len) { if (servconn->payload_len > servconn->rx_len) /* The payload is still not complete. */ break; cur_len = servconn->payload_len; end += cur_len; } else { end = strstr(cur, "\r\n"); if (end == NULL) /* The command is still not complete. */ break; *end = '\0'; end += 2; cur_len = end - cur; } servconn->rx_len -= cur_len; if (servconn->payload_len) { msn_cmdproc_process_payload(servconn->cmdproc, cur, cur_len); servconn->payload_len = 0; } else { msn_cmdproc_process_cmd_text(servconn->cmdproc, cur); } } while (servconn->connected && !servconn->wasted && servconn->rx_len > 0); if (servconn->connected && !servconn->wasted) { if (servconn->rx_len > 0) servconn->rx_buf = g_memdup(cur, servconn->rx_len); else servconn->rx_buf = NULL; } servconn->processing = FALSE; if (servconn->wasted) msn_servconn_destroy(servconn); g_free(old_rx_buf); }
static void read_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnHttpConn *httpconn; MsnServConn *servconn; char buf[MSN_BUF_LEN]; gssize len; char *result_msg = NULL; size_t result_len = 0; gboolean error = FALSE; httpconn = data; servconn = httpconn->servconn; if (servconn->type == MSN_SERVCONN_NS) servconn->session->account->gc->last_received = time(NULL); len = read(httpconn->fd, buf, sizeof(buf) - 1); if (len < 0 && errno == EAGAIN) return; if (len <= 0) { purple_debug_error("msn", "HTTP: servconn %03d read error, " "len: %" G_GSSIZE_FORMAT ", errno: %d, error: %s\n", servconn->num, len, error, g_strerror(errno)); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ); return; } buf[len] = '\0'; httpconn->rx_buf = g_realloc(httpconn->rx_buf, len + httpconn->rx_len + 1); memcpy(httpconn->rx_buf + httpconn->rx_len, buf, len + 1); httpconn->rx_len += len; if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len, &result_msg, &result_len, &error)) { /* Either we must wait for more input, or something went wrong */ if (error) msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ); return; } if (error) { purple_debug_error("msn", "HTTP: Special error\n"); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ); return; } g_free(httpconn->rx_buf); httpconn->rx_buf = NULL; httpconn->rx_len = 0; if (result_len == 0) { /* Nothing to do here */ #if 0 purple_debug_info("msn", "HTTP: nothing to do here\n"); #endif g_free(result_msg); return; } g_free(servconn->rx_buf); servconn->rx_buf = result_msg; servconn->rx_len = result_len; msn_servconn_process_data(servconn); }
static void read_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnHttpConn *httpconn; MsnServConn *servconn; MsnSession *session; char buf[MSN_BUF_LEN]; char *cur, *end, *old_rx_buf; int len, cur_len; char *result_msg = NULL; size_t result_len = 0; gboolean error = FALSE; httpconn = data; servconn = NULL; session = httpconn->session; len = read(httpconn->fd, buf, sizeof(buf) - 1); if (len < 0 && errno == EAGAIN) return; else if (len <= 0) { purple_debug_error("msn", "HTTP: Read error\n"); msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); return; } buf[len] = '\0'; httpconn->rx_buf = g_realloc(httpconn->rx_buf, len + httpconn->rx_len + 1); memcpy(httpconn->rx_buf + httpconn->rx_len, buf, len + 1); httpconn->rx_len += len; if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len, &result_msg, &result_len, &error)) { /* Either we must wait for more input, or something went wrong */ if (error) msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); return; } httpconn->servconn->processing = FALSE; servconn = httpconn->servconn; if (error) { purple_debug_error("msn", "HTTP: Special error\n"); msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); return; } g_free(httpconn->rx_buf); httpconn->rx_buf = NULL; httpconn->rx_len = 0; if (result_len == 0) { /* Nothing to do here */ #if 0 purple_debug_info("msn", "HTTP: nothing to do here\n"); #endif g_free(result_msg); return; } g_free(servconn->rx_buf); servconn->rx_buf = result_msg; servconn->rx_len = result_len; end = old_rx_buf = servconn->rx_buf; servconn->processing = TRUE; do { cur = end; if (servconn->payload_len) { if (servconn->payload_len > servconn->rx_len) /* The payload is still not complete. */ break; cur_len = servconn->payload_len; end += cur_len; } else { end = strstr(cur, "\r\n"); if (end == NULL) /* The command is still not complete. */ break; *end = '\0'; end += 2; cur_len = end - cur; } servconn->rx_len -= cur_len; if (servconn->payload_len) { msn_cmdproc_process_payload(servconn->cmdproc, cur, cur_len); servconn->payload_len = 0; } else { msn_cmdproc_process_cmd_text(servconn->cmdproc, cur); } } while (servconn->connected && servconn->rx_len > 0); if (servconn->connected) { if (servconn->rx_len > 0) servconn->rx_buf = g_memdup(cur, servconn->rx_len); else servconn->rx_buf = NULL; } servconn->processing = FALSE; if (servconn->wasted) msn_servconn_destroy(servconn); g_free(old_rx_buf); }