| 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 { |