static void ycht_packet_send(YchtConn *ycht, YchtPkt *pkt) { int len, pos, written; char *buf; GList *l; g_return_if_fail(ycht != NULL); g_return_if_fail(pkt != NULL); g_return_if_fail(ycht->fd != -1); pos = 0; len = ycht_packet_length(pkt); buf = g_malloc(len); memcpy(buf + pos, "YCHT", 4); pos += 4; pos += yahoo_put32(buf + pos, pkt->version); pos += yahoo_put32(buf + pos, pkt->service); pos += yahoo_put16(buf + pos, pkt->status); pos += yahoo_put16(buf + pos, len - YCHT_HEADER_LEN); for (l = pkt->data; l; l = l->next) { int slen = strlen(l->data); memcpy(buf + pos, l->data, slen); pos += slen; if (l->next) { memcpy(buf + pos, YCHT_SEP, strlen(YCHT_SEP)); pos += strlen(YCHT_SEP); } } if (!ycht->tx_handler) written = write(ycht->fd, buf, len); else { written = -1; errno = EAGAIN; } if (written < 0 && errno == EAGAIN) written = 0; else if (written <= 0) { /* TODO: Error handling (was none before NBIO changes) */ written = 0; } if (written < len) { if (!ycht->tx_handler) ycht->tx_handler = purple_input_add(ycht->fd, PURPLE_INPUT_WRITE, ycht_packet_send_write_cb, ycht); purple_circular_buffer_append(ycht->txbuf, buf + written, len - written); } g_free(buf); }
size_t yahoo_packet_build(struct yahoo_packet *pkt, int pad, gboolean wm, gboolean jp, guchar **buf) { size_t pktlen = yahoo_packet_length(pkt); size_t len = YAHOO_PACKET_HDRLEN + pktlen; guchar *data; int pos = 0; data = g_malloc0(len + 1); memcpy(data + pos, "YMSG", 4); pos += 4; if (wm) pos += yahoo_put16(data + pos, YAHOO_WEBMESSENGER_PROTO_VER); else if (jp) pos += yahoo_put16(data + pos, YAHOO_PROTO_VER_JAPAN); else pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); pos += yahoo_put16(data + pos, 0x0000); pos += yahoo_put16(data + pos, pktlen + pad); pos += yahoo_put16(data + pos, pkt->service); pos += yahoo_put32(data + pos, pkt->status); pos += yahoo_put32(data + pos, pkt->id); yahoo_packet_write(pkt, data + pos); *buf = data; return len; }