src/protocols/yahoo/yahoo_packet.c

changeset 13201
8c224ef70efa
parent 11644
939411169d01
child 13276
121eb8698b39
equal deleted inserted replaced
13200:3769f413f073 13201:8c224ef70efa
240 240
241 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); 241 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n");
242 #endif 242 #endif
243 } 243 }
244 244
245 int yahoo_packet_send(struct yahoo_packet *pkt, struct yahoo_data *yd) 245 static void
246 yahoo_packet_send_can_write(gpointer data, gint source, GaimInputCondition cond)
247 {
248 struct yahoo_data *yd = data;
249 int ret, writelen;
250
251 writelen = gaim_circ_buffer_get_max_read(yd->txbuf);
252
253 if (writelen == 0) {
254 gaim_input_remove(yd->txhandler);
255 yd->txhandler = -1;
256 return;
257 }
258
259 ret = write(yd->fd, yd->txbuf->outptr, writelen);
260
261 if (ret < 0 && errno == EAGAIN)
262 return;
263 else if (ret < 0) {
264 /* TODO: what to do here - do we really have to disconnect? */
265 gaim_connection_error(yd->gc, _("Write Error"));
266 return;
267 }
268
269 gaim_circ_buffer_mark_read(yd->txbuf, ret);
270 }
271
272
273 gsize yahoo_packet_build(struct yahoo_packet *pkt, int pad, gboolean wm,
274 guchar **buf)
246 { 275 {
247 int pktlen = yahoo_packet_length(pkt); 276 int pktlen = yahoo_packet_length(pkt);
248 int len = YAHOO_PACKET_HDRLEN + pktlen; 277 int len = YAHOO_PACKET_HDRLEN + pktlen;
249 int ret;
250
251 guchar *data; 278 guchar *data;
252 int pos = 0; 279 int pos = 0;
253 280
254 if (yd->fd < 0)
255 return -1;
256
257 data = g_malloc0(len + 1); 281 data = g_malloc0(len + 1);
258 282
259 memcpy(data + pos, "YMSG", 4); pos += 4; 283 memcpy(data + pos, "YMSG", 4); pos += 4;
260 284
261 if (yd->wm) 285 if (wm)
262 pos += yahoo_put16(data + pos, YAHOO_WEBMESSENGER_PROTO_VER); 286 pos += yahoo_put16(data + pos, YAHOO_WEBMESSENGER_PROTO_VER);
263 else 287 else
264 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); 288 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER);
265
266 pos += yahoo_put16(data + pos, 0x0000);
267 pos += yahoo_put16(data + pos, pktlen);
268 pos += yahoo_put16(data + pos, pkt->service);
269 pos += yahoo_put32(data + pos, pkt->status);
270 pos += yahoo_put32(data + pos, pkt->id);
271
272 yahoo_packet_write(pkt, data + pos);
273
274 yahoo_packet_dump(data, len);
275 ret = write(yd->fd, data, len);
276 if (ret != len)
277 gaim_debug_warning("yahoo", "Only wrote %d of %d bytes!", ret, len);
278 g_free(data);
279
280 return ret;
281 }
282
283 int yahoo_packet_send_and_free(struct yahoo_packet *pkt, struct yahoo_data *yd)
284 {
285 int ret;
286
287 ret = yahoo_packet_send(pkt, yd);
288 yahoo_packet_free(pkt);
289 return ret;
290 }
291
292 int yahoo_packet_send_special(struct yahoo_packet *pkt, int fd, int pad)
293 {
294 int pktlen = yahoo_packet_length(pkt);
295 int len = YAHOO_PACKET_HDRLEN + pktlen;
296 int ret;
297
298 guchar *data;
299 int pos = 0;
300
301 if (fd < 0)
302 return -1;
303
304 data = g_malloc0(len + 1);
305
306 memcpy(data + pos, "YMSG", 4); pos += 4;
307
308 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER);
309 pos += yahoo_put16(data + pos, 0x0000); 289 pos += yahoo_put16(data + pos, 0x0000);
310 pos += yahoo_put16(data + pos, pktlen + pad); 290 pos += yahoo_put16(data + pos, pktlen + pad);
311 pos += yahoo_put16(data + pos, pkt->service); 291 pos += yahoo_put16(data + pos, pkt->service);
312 pos += yahoo_put32(data + pos, pkt->status); 292 pos += yahoo_put32(data + pos, pkt->status);
313 pos += yahoo_put32(data + pos, pkt->id); 293 pos += yahoo_put32(data + pos, pkt->id);
314 294
315 yahoo_packet_write(pkt, data + pos); 295 yahoo_packet_write(pkt, data + pos);
316 296
317 ret = write(fd, data, len); 297 *buf = data;
298
299 return len;
300 }
301
302 int yahoo_packet_send(struct yahoo_packet *pkt, struct yahoo_data *yd)
303 {
304 gsize len;
305 int ret;
306 guchar *data;
307
308 if (yd->fd < 0)
309 return -1;
310
311 len = yahoo_packet_build(pkt, 0, yd->wm, &data);
312
313 yahoo_packet_dump(data, len);
314 if (yd->txhandler == -1)
315 ret = write(yd->fd, data, len);
316 else {
317 ret = -1;
318 errno = EAGAIN;
319 }
320
321 if (ret < 0 && errno == EAGAIN)
322 ret = 0;
323 else if (ret <= 0) {
324 gaim_debug_warning("yahoo", "Only wrote %d of %d bytes!", ret, len);
325 g_free(data);
326 return ret;
327 }
328
329 if (ret < len) {
330 if (yd->txhandler == -1)
331 yd->txhandler = gaim_input_add(yd->fd, GAIM_INPUT_WRITE,
332 yahoo_packet_send_can_write, yd);
333 gaim_circ_buffer_append(yd->txbuf, data + ret, len - ret);
334 }
335
318 g_free(data); 336 g_free(data);
319 337
338 return ret;
339 }
340
341 int yahoo_packet_send_and_free(struct yahoo_packet *pkt, struct yahoo_data *yd)
342 {
343 int ret;
344
345 ret = yahoo_packet_send(pkt, yd);
346 yahoo_packet_free(pkt);
320 return ret; 347 return ret;
321 } 348 }
322 349
323 void yahoo_packet_free(struct yahoo_packet *pkt) 350 void yahoo_packet_free(struct yahoo_packet *pkt)
324 { 351 {

mercurial