| 228 } |
228 } |
| 229 |
229 |
| 230 static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count) |
230 static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count) |
| 231 { |
231 { |
| 232 int wrote = 0; |
232 int wrote = 0; |
| 233 |
|
| 234 if (!bs || !conn || (count < 0)) |
233 if (!bs || !conn || (count < 0)) |
| 235 return -EINVAL; |
234 return -EINVAL; |
| 236 |
235 |
| 237 if (count > aim_bstream_empty(bs)) |
236 if (count > aim_bstream_empty(bs)) |
| 238 count = aim_bstream_empty(bs); /* truncate to remaining space */ |
237 count = aim_bstream_empty(bs); /* truncate to remaining space */ |
| 239 |
238 |
| 240 if (count) |
239 if (count) { |
| 241 wrote = aim_send(conn->fd, bs->data + bs->offset, count); |
240 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && |
| |
241 (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) { |
| |
242 /* I strongly suspect that this is a horrible thing to do |
| |
243 * and I feel really guilty doing it. */ |
| |
244 char *sn = aim_directim_getsn(conn); |
| |
245 aim_rxcallback_t userfunc; |
| |
246 while (count - wrote > 1024) { |
| |
247 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, 1024); |
| |
248 if ((userfunc=aim_callhandler(conn->sessv, conn, |
| |
249 AIM_CB_FAM_SPECIAL, |
| |
250 AIM_CB_SPECIAL_IMAGETRANSFER))) |
| |
251 userfunc(conn->sessv, NULL, sn, |
| |
252 count-wrote>1024 ? ((double)wrote / count) : 1); |
| |
253 } |
| |
254 } |
| |
255 if (count - wrote) { |
| |
256 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote); |
| |
257 } |
| |
258 |
| |
259 } |
| |
260 |
| 242 |
261 |
| 243 if (((aim_session_t *)conn->sessv)->debug >= 2) { |
262 if (((aim_session_t *)conn->sessv)->debug >= 2) { |
| 244 int i; |
263 int i; |
| 245 aim_session_t *sess = (aim_session_t *)conn->sessv; |
264 aim_session_t *sess = (aim_session_t *)conn->sessv; |
| 246 |
265 |
| 282 aim_bstream_rewind(&fr->data); |
301 aim_bstream_rewind(&fr->data); |
| 283 aimbs_putbs(&obs, &fr->data, payloadlen); |
302 aimbs_putbs(&obs, &fr->data, payloadlen); |
| 284 |
303 |
| 285 obslen = aim_bstream_curpos(&obs); |
304 obslen = aim_bstream_curpos(&obs); |
| 286 aim_bstream_rewind(&obs); |
305 aim_bstream_rewind(&obs); |
| 287 |
|
| 288 if (aim_bstream_send(&obs, fr->conn, obslen) != obslen) |
306 if (aim_bstream_send(&obs, fr->conn, obslen) != obslen) |
| 289 err = -errno; |
307 err = -errno; |
| 290 |
308 |
| 291 free(obs_raw); /* XXX aim_bstream_free */ |
309 free(obs_raw); /* XXX aim_bstream_free */ |
| 292 |
310 |
| 314 aimbs_put16(&hbs, fr->hdr.oft.hdr2len + 8); |
331 aimbs_put16(&hbs, fr->hdr.oft.hdr2len + 8); |
| 315 aimbs_put16(&hbs, fr->hdr.oft.type); |
332 aimbs_put16(&hbs, fr->hdr.oft.type); |
| 316 aimbs_putraw(&hbs, fr->hdr.oft.hdr2, fr->hdr.oft.hdr2len); |
333 aimbs_putraw(&hbs, fr->hdr.oft.hdr2, fr->hdr.oft.hdr2len); |
| 317 |
334 |
| 318 aim_bstream_rewind(&hbs); |
335 aim_bstream_rewind(&hbs); |
| |
336 |
| 319 |
337 |
| 320 if (aim_bstream_send(&hbs, fr->conn, hbslen) != hbslen) { |
338 if (aim_bstream_send(&hbs, fr->conn, hbslen) != hbslen) { |
| 321 |
339 |
| 322 err = -errno; |
340 err = -errno; |
| 323 |
341 |