Changeset 862371b for libfaim/ft.c
- Timestamp:
- Jun 29, 2003, 1:47:04 PM (21 years ago)
- Branches:
- master, barnowl_perlaim, debian, owl, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- e016fc2
- Parents:
- 03ad7b2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfaim/ft.c
r5e53c4a r862371b 10 10 #endif 11 11 #include <aim.h> 12 13 12 14 13 #ifndef _WIN32 … … 17 16 #include <netinet/in.h> 18 17 #include <sys/utsname.h> /* for aim_directim_initiate */ 19 20 18 #include <arpa/inet.h> /* for inet_ntoa */ 21 19 #define G_DIR_SEPARATOR '/' 22 20 #endif 23 21 24 /* TODO: 25 o look for memory leaks.. there's going to be shitloads, i'm sure. 26 */ 22 #ifdef _WIN32 23 #include "win32dep.h" 24 #endif 25 26 #define AIM_OFT_PROTO_OFFER 0x0101 27 #define AIM_OFT_PROTO_ACCEPT 0x0202 28 #define AIM_OFT_PROTO_RESUME 0x0205 29 #define AIM_OFT_PROTO_RESUMEACCEPT 0x0207 30 #define AIM_OFT_PROTO_ACK 0x0204 31 32 struct aim_filetransfer_priv { 33 char sn[MAXSNLEN+1]; 34 char cookie[8]; 35 char ip[30]; 36 int state; 37 struct aim_fileheader_t fh; 38 }; 27 39 28 40 struct aim_directim_intdata { … … 33 45 34 46 static int listenestablish(fu16_t portnum); 47 static struct aim_fileheader_t *aim_oft_getfh(aim_bstream_t *bs); 48 static void oft_dirconvert(char *name); 49 static int aim_oft_buildheader(aim_bstream_t *bs, struct aim_fileheader_t *fh); 35 50 36 51 /** … … 90 105 aim_rxcallback_t userfunc; 91 106 92 93 107 newconn->priv = cur->priv; 94 108 cur->priv = NULL; … … 100 114 ret = userfunc(sess, NULL, newconn, cur); 101 115 #endif 116 } else if (newconn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) { 117 struct aim_filetransfer_priv *ft; 118 aim_rxcallback_t userfunc; 119 120 /* The new conn automatically inherits the internal value 121 * of cur. */ 122 cur->internal = NULL; 123 ft = (struct aim_filetransfer_priv *)newconn->internal; 124 125 snprintf(ft->ip, sizeof(ft->ip), "%s:%u", inet_ntoa(((struct sockaddr_in *)&cliaddr)->sin_addr), ntohs(((struct sockaddr_in *)&cliaddr)->sin_port)); 126 127 if ((userfunc = aim_callhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_SENDFILEINITIATE))) 128 ret = userfunc(sess, NULL, newconn, cur); 102 129 } else { 103 130 faimdprintf(sess, 1,"Got a Connection on a listener that's not Rendezvous Closing conn.\n"); … … 110 137 111 138 /** 139 * aim_send_typing - send client-to-client typing notification over established connection 140 * @sess: session to conn 141 * @conn: directim connection 142 * @typing: If true, notify user has started typing; if false, notify user has stopped. 143 * 144 * The connection must have been previously established. 145 */ 146 faim_export int aim_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing) 147 { 148 struct aim_directim_intdata *intdata = (struct aim_directim_intdata *)conn->internal; 149 aim_frame_t *fr; 150 aim_bstream_t *hdrbs; 151 fu8_t *hdr; 152 int hdrlen = 0x44; 153 154 if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS)) 155 return -EINVAL; 156 157 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x01, 0))) 158 return -ENOMEM; 159 memcpy(fr->hdr.rend.magic, "ODC2", 4); 160 fr->hdr.rend.hdrlen = hdrlen; 161 162 if (!(hdr = calloc(1, hdrlen))) { 163 aim_frame_destroy(fr); 164 return -ENOMEM; 165 } 166 167 hdrbs = &(fr->data); 168 aim_bstream_init(hdrbs, hdr, hdrlen); 169 170 aimbs_put16(hdrbs, 0x0006); 171 aimbs_put16(hdrbs, 0x0000); 172 aimbs_putraw(hdrbs, intdata->cookie, 8); 173 aimbs_put16(hdrbs, 0x0000); 174 aimbs_put16(hdrbs, 0x0000); 175 aimbs_put16(hdrbs, 0x0000); 176 aimbs_put16(hdrbs, 0x0000); 177 aimbs_put32(hdrbs, 0x00000000); 178 aimbs_put16(hdrbs, 0x0000); 179 aimbs_put16(hdrbs, 0x0000); 180 aimbs_put16(hdrbs, 0x0000); 181 182 /* flags -- 0x000e for "started typing", 0x0002 for "stopped typing */ 183 aimbs_put16(hdrbs, ( typing ? 0x000e : 0x0002)); 184 185 aimbs_put16(hdrbs, 0x0000); 186 aimbs_put16(hdrbs, 0x0000); 187 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); 188 189 aim_bstream_setpos(hdrbs, 52); /* bleeehh */ 190 191 aimbs_put8(hdrbs, 0x00); 192 aimbs_put16(hdrbs, 0x0000); 193 aimbs_put16(hdrbs, 0x0000); 194 aimbs_put16(hdrbs, 0x0000); 195 aimbs_put16(hdrbs, 0x0000); 196 aimbs_put16(hdrbs, 0x0000); 197 aimbs_put16(hdrbs, 0x0000); 198 aimbs_put16(hdrbs, 0x0000); 199 aimbs_put8(hdrbs, 0x00); 200 201 /* end of hdr */ 202 203 aim_tx_enqueue(sess, fr); 204 205 return 0; 206 } 207 208 /** 112 209 * aim_send_im_direct - send IM client-to-client over established connection 113 210 * @sess: session to conn 114 211 * @conn: directim connection 115 * @msg: null-terminated string to send; if this is NULL, it will send a "typing" notice. 116 * 212 * @msg: null-terminated string to send. 213 * @len: The length of the message to send, including binary data. 214 * @encoding: 0 for ascii, 2 for Unicode, 3 for ISO 8859-1 215 * 117 216 * Call this just like you would aim_send_im, to send a directim. You 118 217 * _must_ have previously established the directim connection. 119 218 */ 120 faim_export int aim_send_im_direct(aim_session_t *sess, aim_conn_t *conn, const char *msg )219 faim_export int aim_send_im_direct(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding) 121 220 { 122 221 struct aim_directim_intdata *intdata = (struct aim_directim_intdata *)conn->internal; 123 222 aim_frame_t *fr; 124 aim_bstream_t hdrbs; /* XXX this should be within aim_frame_t */ 125 126 if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS)) 223 aim_bstream_t *hdrbs; 224 int hdrlen = 0x44; 225 fu8_t *hdr; 226 227 if (!sess || !conn || !msg || (conn->type != AIM_CONN_TYPE_RENDEZVOUS)) 127 228 return -EINVAL; 128 229 129 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x01, strlen(msg)))) 130 return -ENOMEM; 131 132 memcpy(fr->hdr.oft.magic, "ODC2", 4); 230 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x01, len))) 231 return -ENOMEM; 232 233 memcpy(fr->hdr.rend.magic, "ODC2", 4); 234 fr->hdr.rend.hdrlen = hdrlen; 133 235 134 fr->hdr.oft.hdr2len = 0x44; 135 136 if (!(fr->hdr.oft.hdr2 = calloc(1, fr->hdr.oft.hdr2len))) { 236 if (!(hdr = calloc(1, hdrlen + len))) { 137 237 aim_frame_destroy(fr); 138 238 return -ENOMEM; 139 239 } 240 241 hdrbs = &(fr->data); 242 aim_bstream_init(hdrbs, hdr, hdrlen + len); 243 244 aimbs_put16(hdrbs, 0x0006); 245 aimbs_put16(hdrbs, 0x0000); 246 aimbs_putraw(hdrbs, intdata->cookie, 8); 247 aimbs_put16(hdrbs, 0x0000); 248 aimbs_put16(hdrbs, 0x0000); 249 aimbs_put16(hdrbs, 0x0000); 250 aimbs_put16(hdrbs, 0x0000); 251 aimbs_put32(hdrbs, len); 252 aimbs_put16(hdrbs, encoding); 253 aimbs_put16(hdrbs, 0x0000); 254 aimbs_put16(hdrbs, 0x0000); 140 255 141 aim_bstream_init(&hdrbs, fr->hdr.oft.hdr2, fr->hdr.oft.hdr2len); 142 143 aimbs_put16(&hdrbs, 0x0006); 144 aimbs_put16(&hdrbs, 0x0000); 145 aimbs_putraw(&hdrbs, intdata->cookie, 8); 146 aimbs_put16(&hdrbs, 0x0000); 147 aimbs_put16(&hdrbs, 0x0000); 148 aimbs_put16(&hdrbs, 0x0000); 149 aimbs_put16(&hdrbs, 0x0000); 150 aimbs_put32(&hdrbs, strlen(msg)); 151 aimbs_put16(&hdrbs, 0x0000); 152 aimbs_put16(&hdrbs, 0x0000); 153 aimbs_put16(&hdrbs, 0x0000); 154 155 /* flags -- 0x000e for "typing", 0x0000 for message */ 156 aimbs_put16(&hdrbs, msg ? 0x0000 : 0x000e); 157 158 aimbs_put16(&hdrbs, 0x0000); 159 aimbs_put16(&hdrbs, 0x0000); 160 aimbs_putraw(&hdrbs, sess->sn, strlen(sess->sn)); 161 162 aim_bstream_setpos(&hdrbs, 52); /* bleeehh */ 163 164 aimbs_put8(&hdrbs, 0x00); 165 aimbs_put16(&hdrbs, 0x0000); 166 aimbs_put16(&hdrbs, 0x0000); 167 aimbs_put16(&hdrbs, 0x0000); 168 aimbs_put16(&hdrbs, 0x0000); 169 aimbs_put16(&hdrbs, 0x0000); 170 aimbs_put16(&hdrbs, 0x0000); 171 aimbs_put16(&hdrbs, 0x0000); 172 256 /* flags -- 0x000e for "started typing", 0x0002 for "stopped typing, 0x0000 for message */ 257 aimbs_put16(hdrbs, 0x0000); 258 259 aimbs_put16(hdrbs, 0x0000); 260 aimbs_put16(hdrbs, 0x0000); 261 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); 262 263 aim_bstream_setpos(hdrbs, 52); /* bleeehh */ 264 265 aimbs_put8(hdrbs, 0x00); 266 aimbs_put16(hdrbs, 0x0000); 267 aimbs_put16(hdrbs, 0x0000); 268 aimbs_put16(hdrbs, 0x0000); 269 aimbs_put16(hdrbs, 0x0000); 270 aimbs_put16(hdrbs, 0x0000); 271 aimbs_put16(hdrbs, 0x0000); 272 aimbs_put16(hdrbs, 0x0000); 273 aimbs_put8(hdrbs, 0x00); 274 173 275 /* end of hdr2 */ 174 175 if (msg) { 276 176 277 #if 0 /* XXX this is how you send buddy icon info... */ 177 178 179 180 181 182 183 184 278 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0008); 279 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x000c); 280 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); 281 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x1466); 282 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0001); 283 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x2e0f); 284 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x393e); 285 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0xcac8); 185 286 #endif 186 aimbs_putraw(&fr->data, msg, strlen(msg)); 187 } 188 287 aimbs_putraw(hdrbs, msg, len); 288 189 289 aim_tx_enqueue(sess, fr); 190 290 191 291 return 0; 192 292 } … … 279 379 * 280 380 */ 281 faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *sess, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize )381 faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *sess, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize, char *cookret) 282 382 { 283 383 aim_conn_t *newconn; 284 384 aim_msgcookie_t *cookie; 285 struct aim_ directim_intdata *priv;385 struct aim_filetransfer_priv *ft; 286 386 int listenfd; 387 388 /* XXX allow different ports */ 287 389 fu16_t port = 4443; 288 390 fu8_t localip[4]; … … 299 401 cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t)); 300 402 memcpy(cookie->cookie, ck, 8); 301 cookie->type = AIM_COOKIETYPE_OFTIM; 403 cookie->type = AIM_COOKIETYPE_OFTSEND; 404 memcpy(cookret, ck, 8); 302 405 303 406 /* this one is for the cookie */ 304 priv = (struct aim_directim_intdata *)calloc(1, sizeof(struct aim_directim_intdata));305 306 memcpy( priv->cookie, ck, 8);307 strncpy( priv->sn, destsn, sizeof(priv->sn));308 cookie->data = priv;407 ft = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); 408 409 memcpy(ft->cookie, ck, 8); 410 strncpy(ft->sn, destsn, sizeof(ft->sn)); 411 cookie->data = ft; 309 412 aim_cachecookie(sess, cookie); 310 413 311 /* XXX switch to aim_cloneconn()? */312 414 if (!(newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL))) { 313 415 close(listenfd); … … 316 418 317 419 /* this one is for the conn */ 318 priv = (struct aim_directim_intdata *)calloc(1, sizeof(struct aim_directim_intdata));319 320 memcpy( priv->cookie, ck, 8);321 strncpy( priv->sn, destsn, sizeof(priv->sn));420 ft = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); 421 422 memcpy(ft->cookie, ck, 8); 423 strncpy(ft->sn, destsn, sizeof(ft->sn)); 322 424 323 425 newconn->fd = listenfd; 324 426 newconn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE; 325 newconn->internal = priv;427 newconn->internal = ft; 326 428 newconn->lastactivity = time(NULL); 327 429 … … 335 437 * unsigned int aim_oft_listener_clean - close up old listeners 336 438 * @sess: session to clean up in 337 * @age: maximum age in seconds 439 * @age: maximum age in seconds 338 440 * 339 441 * returns number closed, -1 on error. 340 442 */ 341 faim_export unsigned int aim_oft_listener_clean(struct aim_session_t *sess, time_t age) 342 { 343 struct aim_conn_t *cur; 344 time_t now; 345 unsigned int hit = 0; 346 347 if (!sess) 348 return -1; 349 now = time(NULL); 350 faim_mutex_lock(&sess->connlistlock); 351 for(cur = sess->connlist;cur; cur = cur->next) 352 if (cur->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) { 353 faim_mutex_lock(&cur->active); 354 if (cur->lastactivity < (now - age) ) { 355 faim_mutex_unlock(&cur->active); 356 aim_conn_close(cur); 357 hit++; 358 } else 359 faim_mutex_unlock(&cur->active); 360 } 361 faim_mutex_unlock(&sess->connlistlock); 362 return hit; 363 } 364 #endif 443 faim_export unsigned int aim_oft_listener_clean(aim_session_t *sess, time_t age) 444 { 445 aim_conn_t *cur; 446 time_t now; 447 unsigned int hit = 0; 448 449 if (!sess) 450 return -1; 451 now = time(NULL); 452 453 for(cur = sess->connlist;cur; cur = cur->next) 454 if (cur->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) { 455 if (cur->lastactivity < (now - age) ) { 456 aim_conn_close(cur); 457 hit++; 458 } 459 } 460 return hit; 461 } 462 #endif 365 463 366 464 faim_export const char *aim_directim_getsn(aim_conn_t *conn) … … 369 467 370 468 if (!conn) 371 469 return NULL; 372 470 373 471 if ((conn->type != AIM_CONN_TYPE_RENDEZVOUS) || 374 472 (conn->subtype != AIM_CONN_SUBTYPE_OFT_DIRECTIM)) 375 473 return NULL; 376 474 377 475 if (!conn->internal) … … 432 530 * aim_directim_getconn - find a directim conn for buddy name 433 531 * @sess: your session, 434 * @name: the name to get, 532 * @name: the name to get, 435 533 * 436 534 * returns conn for directim with name, %NULL if none found. … … 466 564 * @cookie: the cookie used 467 565 * @ip: the ip to connect to 566 * @port: the port to use 567 * @rendid: capability type (%AIM_CAPS_GETFILE or %AIM_CAPS_SENDFILE) 568 * 468 569 * @listingfiles: number of files to share 469 570 * @listingtotsize: total size of shared files 470 571 * @listingsize: length of the listing file(buffer) 471 572 * @listingchecksum: checksum of the listing 472 * @rendid: capability type (%AIM_CAPS_GETFILE or %AIM_CAPS_SENDFILE)473 573 * 474 574 * Returns new connection or %NULL on error. … … 476 576 * XXX this should take a struct. 477 577 */ 478 faim_export aim_conn_t *aim_accepttransfer(aim_session_t *sess, 479 aim_conn_t *conn, 480 const char *sn, const fu8_t *cookie, 481 const fu8_t *ip, 482 fu16_t listingfiles, 483 fu16_t listingtotsize, 484 fu16_t listingsize, 485 fu32_t listingchecksum, 486 fu16_t rendid) 487 { 488 return NULL; 578 faim_export aim_conn_t *aim_accepttransfer(aim_session_t *sess, aim_conn_t *conn, const char *sn, 579 const fu8_t *cookie, const fu8_t *ip, 580 fu16_t port, fu16_t rendid, ...) 581 { 582 aim_frame_t *newpacket; 583 aim_conn_t *newconn; 584 struct aim_filetransfer_priv *priv; 585 int i; 586 char addr[21]; 587 588 if (!sess || !conn || !sn || !cookie || !ip) { 589 return NULL; 590 } 591 592 /* OSCAR CAP accept packet */ 593 594 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x0002, 10+8+2+1+strlen(sn)+4+2+8+16))) { 595 return NULL; 596 } 597 598 aim_putsnac(&newpacket->data, 0x0004, 0x0006, 0x0000, sess->snacid_next); 599 600 for (i = 0; i < 8; i++) 601 aimbs_put8(&newpacket->data, cookie[i]); 602 603 aimbs_put16(&newpacket->data, 0x0002); 604 aimbs_put8(&newpacket->data, strlen(sn)); 605 aimbs_putraw(&newpacket->data, sn, strlen(sn)); 606 aimbs_put16(&newpacket->data, 0x0005); 607 aimbs_put16(&newpacket->data, 0x001a); 608 aimbs_put16(&newpacket->data, AIM_RENDEZVOUS_ACCEPT); 609 610 for (i = 0; i < 8; i++) /* yes, again... */ 611 aimbs_put8(&newpacket->data, cookie[i]); 612 613 aim_putcap(&newpacket->data, rendid); 614 aim_tx_enqueue(sess, newpacket); 615 616 snprintf(addr, sizeof(addr), "%s:%d", ip, port); 617 newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS, addr); 618 619 if (newconn->status & AIM_CONN_STATUS_CONNERR) { 620 return NULL; 621 } 622 623 if (!newconn || (newconn->fd == -1)) { 624 perror("aim_newconn"); 625 faimdprintf(sess, 2, "could not connect to %s (fd: %i)\n", ip, newconn?newconn->fd:0); 626 return newconn; 627 } 628 629 priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); 630 631 memcpy(priv->cookie, cookie, 8); 632 priv->state = 0; 633 strncpy(priv->sn, sn, MAXSNLEN); 634 strncpy(priv->ip, ip, sizeof(priv->ip)); 635 newconn->internal = (void *)priv; 636 637 faimdprintf(sess, 2, "faim: connected to peer (fd = %d)\n", newconn->fd); 638 639 if (rendid == AIM_CAPS_GETFILE) { 640 return NULL; /* This should never happen for now. -- wtm */ 641 489 642 #if 0 490 struct command_tx_struct *newpacket, *newoft; 491 struct aim_conn_t *newconn; 492 struct aim_fileheader_t *fh; 493 struct aim_filetransfer_priv *priv; 494 struct aim_msgcookie_t *cachedcook; 495 int curbyte, i; 496 497 if (!sess || !conn || !sn || !cookie || !ip) { 498 return NULL; 499 } 500 501 newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS, ip); 502 503 if (!newconn || (newconn->fd == -1)) { 504 perror("aim_newconn"); 505 faimdprintf(sess, 2, "could not connect to %s (fd: %i)\n", ip, newconn?newconn->fd:0); 506 return newconn; 507 } else { 508 priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); 509 510 memcpy(priv->cookie, cookie, 8); 511 priv->state = 0; 512 strncpy(priv->sn, sn, MAXSNLEN); 513 strncpy(priv->ip, ip, sizeof(priv->ip)); 514 newconn->priv = (void *)priv; 515 516 faimdprintf(sess, 2, "faim: connected to peer (fd = %d)\n", newconn->fd); 517 } 518 519 if (rendid == AIM_CAPS_GETFILE) { 520 newconn->subtype = AIM_CONN_SUBTYPE_OFT_GETFILE; 521 522 faimdprintf(sess, 2, "faim: getfile request accept\n"); 523 524 if (!(newoft = aim_tx_new(sess, newconn, AIM_FRAMETYPE_OFT, 0x1108, 0))) { 525 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 526 /* XXX: conn leak here */ 527 return NULL; 528 } 529 530 newoft->lock = 1; 531 memcpy(newoft->hdr.oft.magic, "OFT2", 4); 532 newoft->hdr.oft.hdr2len = 0x100 - 8; 533 534 if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t)))) { 535 /* XXX: conn leak here */ 536 perror("calloc"); 537 return NULL; 538 } 539 540 fh->encrypt = 0x0000; 541 fh->compress = 0x0000; 542 fh->totfiles = listingfiles; 543 fh->filesleft = listingfiles; /* is this right -- total parts and parts left?*/ 544 fh->totparts = 0x0001; 545 fh->partsleft = 0x0001; 546 fh->totsize = listingtotsize; 547 fh->size = listingsize; /* ls -l listing.txt */ 548 fh->modtime = (int)time(NULL); /* we'll go with current time for now */ 549 fh->checksum = listingchecksum; 550 fh->rfcsum = 0x00000000; 551 fh->rfsize = 0x00000000; 552 fh->cretime = 0x00000000; 553 fh->rfcsum = 0x00000000; 554 fh->nrecvd = 0x00000000; 555 fh->recvcsum = 0x00000000; 556 memset(fh->idstring, 0, sizeof(fh->idstring)); 557 memcpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring)); 558 fh->flags = 0x02; 559 fh->lnameoffset = 0x1a; 560 fh->lsizeoffset = 0x10; 561 memset(fh->dummy, 0, sizeof(fh->dummy)); 562 memset(fh->macfileinfo, 0, sizeof(fh->macfileinfo)); 563 564 /* we need to figure out these encodings for filenames */ 565 fh->nencode = 0x0000; 566 fh->nlanguage = 0x0000; 567 memset(fh->name, 0, sizeof(fh->name)); 568 memcpy(fh->name, "listing.txt", sizeof(fh->name)); 569 570 if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { 571 newoft->lock = 0; 572 aim_frame_destroy(newoft); 573 /* XXX: conn leak */ 574 perror("calloc (1)"); 575 return NULL; 576 } 577 578 memcpy(fh->bcookie, cookie, 8); 579 580 if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, fh))) 581 faimdprintf(sess, 1, "eek, bh fail!\n"); 582 583 newoft->lock = 0; 584 aim_tx_enqueue(sess, newoft); 585 586 if (!(cachedcook = (struct aim_msgcookie_t *)calloc(1, sizeof(struct aim_msgcookie_t)))) { 587 faimdprintf(sess, 1, "faim: accepttransfer: couldn't calloc cachedcook. yeep!\n"); 588 /* XXX: more cleanup, conn leak */ 589 perror("calloc (2)"); 590 return NULL; 591 } 592 593 memcpy(&(priv->fh), fh, sizeof(struct aim_fileheader_t)); 594 memcpy(cachedcook->cookie, cookie, 8); 595 596 cachedcook->type = AIM_COOKIETYPE_OFTGET; 597 cachedcook->data = (void *)priv; 598 599 if (aim_cachecookie(sess, cachedcook) == -1) 600 faimdprintf(sess, 1, "faim: ERROR caching message cookie\n"); 601 602 free(fh); 603 604 /* OSCAR CAP accept packet */ 605 606 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+8+2+1+strlen(sn)+4+2+8+16))) { 607 return NULL; 608 } 609 } else { 610 return NULL; 611 } 612 613 newpacket->lock = 1; 614 curbyte = aim_putsnac(newpacket->data, 0x0004, 0x0006, 0x0000, sess->snac_nextid); 615 616 for (i = 0; i < 8; i++) 617 curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]); 618 619 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); 620 curbyte += aimutil_put8(newpacket->data+curbyte, strlen(sn)); 621 curbyte += aimutil_putstr(newpacket->data+curbyte, sn, strlen(sn)); 622 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); 623 curbyte += aimutil_put16(newpacket->data+curbyte, 0x001a); 624 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002 /* accept*/); 625 626 for (i = 0;i < 8; i++) 627 curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]); 628 629 curbyte += aim_putcap(newpacket->data+curbyte, 0x10, rendid); 630 newpacket->lock = 0; 631 aim_tx_enqueue(sess, newpacket); 632 633 return newconn; 643 struct aim_fileheader_t *fh; 644 aim_frame_t *newoft; 645 aim_msgcookie_t *cachedcook; 646 /* XXX take the following parameters fu16_t listingfiles, 647 fu16_t listingtotsize, 648 fu16_t listingsize, 649 fu32_t listingchecksum, */ 650 651 newconn->subtype = AIM_CONN_SUBTYPE_OFT_GETFILE; 652 653 faimdprintf(sess, 2, "faim: getfile request accept\n"); 654 655 if (!(newoft = aim_tx_new(sess, newconn, AIM_FRAMETYPE_OFT, 0x1108, 0))) { 656 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 657 /* XXX: conn leak here */ 658 return NULL; 659 } 660 661 memcpy(newoft->hdr.oft.magic, "OFT2", 4); 662 newoft->hdr.oft.hdr2len = 0x100 - 8; 663 664 if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t)))) { 665 /* XXX: conn leak here */ 666 perror("calloc"); 667 return NULL; 668 } 669 670 fh->encrypt = 0x0000; 671 fh->compress = 0x0000; 672 fh->totfiles = listingfiles; 673 fh->filesleft = listingfiles; /* is this right -- total parts and parts left?*/ 674 fh->totparts = 0x0001; 675 fh->partsleft = 0x0001; 676 fh->totsize = listingtotsize; 677 fh->size = listingsize; /* ls -l listing.txt */ 678 fh->modtime = (int)time(NULL); /* we'll go with current time for now */ 679 fh->checksum = listingchecksum; 680 fh->rfcsum = 0x00000000; 681 fh->rfsize = 0x00000000; 682 fh->cretime = 0x00000000; 683 fh->rfcsum = 0x00000000; 684 fh->nrecvd = 0x00000000; 685 fh->recvcsum = 0x00000000; 686 memset(fh->idstring, 0, sizeof(fh->idstring)); 687 strncpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring)); 688 fh->flags = 0x02; 689 fh->lnameoffset = 0x1a; 690 fh->lsizeoffset = 0x10; 691 memset(fh->dummy, 0, sizeof(fh->dummy)); 692 memset(fh->macfileinfo, 0, sizeof(fh->macfileinfo)); 693 694 /* we need to figure out these encodings for filenames */ 695 fh->nencode = 0x0000; 696 fh->nlanguage = 0x0000; 697 memset(fh->name, 0, sizeof(fh->name)); 698 strncpy(fh->name, "listing.txt", sizeof(fh->name)); 699 700 if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { 701 aim_frame_destroy(newoft); 702 /* XXX: conn leak */ 703 perror("calloc (1)"); 704 return NULL; 705 } 706 707 memcpy(fh->bcookie, cookie, 8); 708 709 if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, fh))) 710 faimdprintf(sess, 1, "eek, bh fail!\n"); 711 712 aim_tx_enqueue(sess, newoft); 713 714 if (!(cachedcook = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t)))) { 715 faimdprintf(sess, 1, "faim: accepttransfer: couldn't calloc cachedcook. yeep!\n"); 716 /* XXX: more cleanup, conn leak */ 717 perror("calloc (2)"); 718 return NULL; 719 } 720 721 memcpy(&(priv->fh), fh, sizeof(struct aim_fileheader_t)); 722 memcpy(cachedcook->cookie, cookie, 8); 723 724 cachedcook->type = AIM_COOKIETYPE_OFTGET; 725 /* XXX doesn't priv need to be copied so we don't 726 * double free? -- wtm 727 */ 728 cachedcook->data = (void *)priv; 729 730 if (aim_cachecookie(sess, cachedcook) == -1) 731 faimdprintf(sess, 1, "faim: ERROR caching message cookie\n"); 732 733 free(fh); 634 734 #endif 735 736 } else if (rendid == AIM_CAPS_SENDFILE) { 737 newconn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE; 738 priv->fh.recvcsum = 0xffff0000; 739 } else { 740 return NULL; 741 } 742 743 return newconn; 744 } 745 746 /* conn is a BOS connection over which to send the cancel msg */ 747 faim_export int aim_canceltransfer(aim_session_t *sess, aim_conn_t *conn, 748 const char *cookie, const char *sn, int rendid) 749 { 750 aim_frame_t *newpacket; 751 int i; 752 753 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x0002, 10+8+2+1+strlen(sn)+4+2+8+16))) { 754 return 1; 755 } 756 757 aim_putsnac(&newpacket->data, 0x0004, 0x0006, 0x0000, sess->snacid_next); 758 759 for (i = 0; i < 8; i++) 760 aimbs_put8(&newpacket->data, cookie[i]); 761 762 aimbs_put16(&newpacket->data, 0x0002); 763 aimbs_put8(&newpacket->data, strlen(sn)); 764 aimbs_putraw(&newpacket->data, sn, strlen(sn)); 765 aimbs_put16(&newpacket->data, 0x0005); 766 aimbs_put16(&newpacket->data, 0x001a); 767 aimbs_put16(&newpacket->data, AIM_RENDEZVOUS_CANCEL); 768 769 for (i = 0; i < 8; i++) 770 aimbs_put8(&newpacket->data, cookie[i]); 771 772 aim_putcap(&newpacket->data, rendid); 773 aim_tx_enqueue(sess, newpacket); 774 775 return 0; 635 776 } 636 777 637 778 /** 638 779 * aim_getlisting(FILE *file) -- get an aim_fileheader_t for a given FILE* 639 * 780 * @file is an opened listing file 640 781 * 641 782 * returns a pointer to the filled-in fileheader_t … … 649 790 return NULL; 650 791 #if 0 651 652 653 654 655 656 int linelength = 1024; 657 658 /* XXX: if we have a line longer than 1024chars, God help us. */ 659 if ( (linebuf = (char *)calloc(1, linelength)) == NULL ) { 660 faimdprintf(sess, 2, "linebuf calloc failed\n");661 return NULL; 662 } 663 664 if (fseek(file, 0, SEEK_END) == -1) { /* use this for sanity check */ 665 perror("getlisting END1 fseek:");666 faimdprintf(sess, 2, "getlising fseek END1 error\n"); 667 } 668 669 if ((size = ftell(file)) == -1) { 670 perror("getlisting END1 getpos:");671 faimdprintf(sess, 2, "getlising getpos END1 error\n"); 672 } 673 674 if (fseek(file, 0, SEEK_SET) != 0) { 675 perror("getlesting fseek(SET):");676 faimdprintf(sess, 2, "faim: getlisting: couldn't seek to beginning of listing file\n"); 677 } 678 679 memset(linebuf, 0, linelength); 680 681 size = 0; 682 683 while(fgets(linebuf, linelength, file)) { 684 totfiles++;685 memset(sizebuf, 0, 9); 686 687 size += strlen(linebuf); 688 689 if (strlen(linebuf) < 23) { 690 faimdprintf(sess, 2, "line \"%s\" too short. skipping\n", linebuf);691 continue; 692 } 693 694 695 696 697 698 699 700 701 } 702 703 704 705 706 } 707 708 709 710 711 712 * done at register time and cached, but, eh. */ 713 714 715 716 717 fh->encrypt= 0x0000;718 fh->compress = 0x0000; 719 fh->totfiles= totfiles;720 fh->filesleft = totfiles; /* is this right ?*/721 fh->totparts= 0x0001;722 fh->partsleft= 0x0001;723 fh->totsize= totsize;724 fh->size= size; /* ls -l listing.txt */725 fh->modtime= (int)time(NULL); /* we'll go with current time for now */726 fh->checksum= checksum; /* XXX: checksum ! */727 fh->rfcsum= 0x00000000;728 fh->rfsize= 0x00000000;729 fh->cretime= 0x00000000;730 fh->rfcsum= 0x00000000;731 fh->nrecvd= 0x00000000;732 fh->recvcsum= 0x00000000;733 734 /*memset(fh->idstring, 0, sizeof(fh->idstring)); */735 736 737 738 fh->flags= 0x02;739 740 741 742 /*memset(fh->dummy, 0, sizeof(fh->dummy)); */743 744 745 fh->nencode= 0x0000; /* we need to figure out these encodings for filenames */746 fh->nlanguage= 0x0000;747 748 /*memset(fh->name, 0, sizeof(fh->name)); */749 memcpy(fh->name, "listing.txt", sizeof(fh->name));750 751 752 753 792 struct aim_fileheader_t *fh; 793 u_long totsize = 0, size = 0, checksum = 0xffff0000; 794 short totfiles = 0; 795 char *linebuf, sizebuf[9]; 796 int linelength = 1024; 797 798 /* XXX: if we have a line longer than 1024chars, God help us. */ 799 if ((linebuf = (char *)calloc(1, linelength)) == NULL ) { 800 faimdprintf(sess, 2, "linebuf calloc failed\n"); 801 return NULL; 802 } 803 804 if (fseek(file, 0, SEEK_END) == -1) { /* use this for sanity check */ 805 perror("getlisting END1 fseek:"); 806 faimdprintf(sess, 2, "getlising fseek END1 error\n"); 807 } 808 809 if ((size = ftell(file)) == -1) { 810 perror("getlisting END1 getpos:"); 811 faimdprintf(sess, 2, "getlising getpos END1 error\n"); 812 } 813 814 if (fseek(file, 0, SEEK_SET) != 0) { 815 perror("getlesting fseek(SET):"); 816 faimdprintf(sess, 2, "faim: getlisting: couldn't seek to beginning of listing file\n"); 817 } 818 819 memset(linebuf, 0, linelength); 820 821 size = 0; 822 823 while(fgets(linebuf, linelength, file)) { 824 totfiles++; 825 memset(sizebuf, 0, 9); 826 827 size += strlen(linebuf); 828 829 if (strlen(linebuf) < 23) { 830 faimdprintf(sess, 2, "line \"%s\" too short. skipping\n", linebuf); 831 continue; 832 } 833 834 if (linebuf[strlen(linebuf)-1] != '\n') { 835 faimdprintf(sess, 2, "faim: OFT: getlisting -- hit EOF or line too long!\n"); 836 } 837 838 memcpy(sizebuf, linebuf+17, 8); 839 840 totsize += strtol(sizebuf, NULL, 10); 841 memset(linebuf, 0, linelength); 842 } 843 844 if (fseek(file, 0, SEEK_SET) == -1) { 845 perror("getlisting END2 fseek:"); 846 faimdprintf(sess, 2, "getlising fseek END2 error\n"); 847 } 848 849 free(linebuf); 850 851 /* we're going to ignore checksumming the data for now -- that 852 * requires walking the whole listing.txt. it should probably be 853 * done at register time and cached, but, eh. */ 854 855 if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t)))) 856 return NULL; 857 858 fh->encrypt = 0x0000; 859 fh->compress = 0x0000; 860 fh->totfiles = totfiles; 861 fh->filesleft = totfiles; /* is this right? */ 862 fh->totparts = 0x0001; 863 fh->partsleft = 0x0001; 864 fh->totsize = totsize; 865 fh->size = size; /* ls -l listing.txt */ 866 fh->modtime = (int)time(NULL); /* we'll go with current time for now */ 867 fh->checksum = checksum; /* XXX: checksum ! */ 868 fh->rfcsum = 0x00000000; 869 fh->rfsize = 0x00000000; 870 fh->cretime = 0x00000000; 871 fh->rfcsum = 0x00000000; 872 fh->nrecvd = 0x00000000; 873 fh->recvcsum = 0x00000000; 874 875 /* memset(fh->idstring, 0, sizeof(fh->idstring)); */ 876 memcpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring)); 877 memset(fh->idstring+strlen(fh->idstring), 0, sizeof(fh->idstring)-strlen(fh->idstring)); 878 879 fh->flags = 0x02; 880 fh->lnameoffset = 0x1a; 881 fh->lsizeoffset = 0x10; 882 883 /* memset(fh->dummy, 0, sizeof(fh->dummy)); */ 884 memset(fh->macfileinfo, 0, sizeof(fh->macfileinfo)); 885 886 fh->nencode = 0x0000; /* we need to figure out these encodings for filenames */ 887 fh->nlanguage = 0x0000; 888 889 /* memset(fh->name, 0, sizeof(fh->name)); */ 890 strncpy(fh->name, "listing.txt", sizeof(fh->name)); 891 memset(fh->name+strlen(fh->name), 0, 64-strlen(fh->name)); 892 893 faimdprintf(sess, 2, "faim: OFT: listing fh name %s / %s\n", fh->name, (fh->name+(strlen(fh->name)))); 894 return fh; 754 895 #endif 755 896 } … … 757 898 /** 758 899 * aim_listenestablish - create a listening socket on a port. 759 * @portnum: the port number to bind to. 900 * @portnum: the port number to bind to. 760 901 * 761 902 * you need to call accept() when it's connected. returns your fd … … 784 925 ressave = res; 785 926 do { 786 listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 927 listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 787 928 if (listenfd < 0) 788 929 continue; … … 802 943 } 803 944 945 fcntl(listenfd, F_SETFL, O_NONBLOCK); 946 804 947 freeaddrinfo(ressave); 805 948 return listenfd; … … 834 977 return -1; 835 978 } 979 fcntl(listenfd, F_SETFL, O_NONBLOCK); 836 980 return listenfd; 837 981 #endif … … 849 993 int ret = 0; 850 994 char *listing; 851 struct command_tx_struct *newoft;995 aim_frame_t *newoft; 852 996 853 997 if (!(listing = malloc(ft->fh.size))) … … 860 1004 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x120b, 0))) { 861 1005 faimdprintf(sess, 2, "faim: aim_get_command_rendezvous: getfile listing: tx_new OFT failed\n"); 862 faim_mutex_unlock(&conn->active);863 1006 free(listing); 864 1007 aim_conn_close(conn); … … 896 1039 /* waiting on file data */ 897 1040 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILERECEIVE)) ) 898 return userfunc(sess, NULL, conn, ft); 1041 return userfunc(sess, NULL, conn, ft->fh.name, 1042 ft->fh.size); 899 1043 return 0; 900 1044 } … … 916 1060 { 917 1061 aim_msgcookie_t *cook; 918 struct aim_filetransfer_priv *priv = (struct aim_filetransfer_priv *)conn-> priv;1062 struct aim_filetransfer_priv *priv = (struct aim_filetransfer_priv *)conn->internal; 919 1063 920 1064 cook = aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTSEND); … … 926 1070 static void connkill_sendfile(aim_session_t *sess, aim_conn_t *conn) 927 1071 { 928 929 1072 free(conn->internal); 930 1073 … … 934 1077 static void connclose_getfile(aim_session_t *sess, aim_conn_t *conn) 935 1078 { 1079 #if 0 936 1080 aim_msgcookie_t *cook; 937 1081 struct aim_filetransfer_priv *priv = (struct aim_filetransfer_priv *)conn->priv; … … 939 1083 cook = aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTGET); 940 1084 aim_cookie_free(sess, cook); 941 1085 #endif 942 1086 return; 943 1087 } … … 1002 1146 } 1003 1147 1004 static int handlehdr_directim(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr)1148 static int handlehdr_directim(aim_session_t *sess, aim_conn_t *conn, aim_bstream_t *bs) 1005 1149 { 1006 1150 aim_frame_t fr; 1007 1151 aim_rxcallback_t userfunc; 1008 1152 fu32_t payloadlength; 1009 fu16_t flags ;1153 fu16_t flags, encoding; 1010 1154 char *snptr = NULL; 1011 1155 1012 1156 fr.conn = conn; 1013 1157 1014 payloadlength = aimutil_get32(hdr+22); 1015 flags = aimutil_get16(hdr+32); 1016 snptr = (char *)hdr+38; 1158 /* XXX ugly */ 1159 aim_bstream_setpos(bs, 20); 1160 payloadlength = aimbs_get32(bs); 1161 1162 aim_bstream_setpos(bs, 24); 1163 encoding = aimbs_get16(bs); 1164 1165 aim_bstream_setpos(bs, 30); 1166 flags = aimbs_get16(bs); 1167 1168 aim_bstream_setpos(bs, 36); 1169 /* XXX -create an aimbs_getnullstr function? */ 1170 snptr = aimbs_getstr(bs, MAXSNLEN); 1017 1171 1018 1172 faimdprintf(sess, 2, "faim: OFT frame: handlehdr_directim: %04x / %04x / %s\n", payloadlength, flags, snptr); 1019 1173 1020 if (flags == 0x000e) {1174 if (flags & 0x0002) { 1021 1175 int ret = 0; 1022 1176 1177 if (flags == 0x000c) { 1178 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) 1179 ret = userfunc(sess, &fr, snptr, 1); 1180 return ret; 1181 } 1182 1023 1183 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) 1024 ret = userfunc(sess, &fr, snptr );1184 ret = userfunc(sess, &fr, snptr, 0); 1025 1185 1026 1186 return ret; 1027 1187 1028 } else if (( flags == 0x0000) && payloadlength) {1029 char *msg ;1188 } else if (((flags & 0x000f) == 0x0000) && payloadlength) { 1189 char *msg, *msg2; 1030 1190 int ret = 0; 1191 int recvd = 0; 1192 int i; 1031 1193 1032 1194 if (!(msg = calloc(1, payloadlength+1))) 1033 1195 return -1; 1034 1035 if (aim_recv(conn->fd, msg, payloadlength) < payloadlength) { 1036 free(msg); 1037 return -1; 1196 msg2 = msg; 1197 1198 while (payloadlength - recvd) { 1199 if (payloadlength - recvd >= 1024) 1200 i = aim_recv(conn->fd, msg2, 1024); 1201 else 1202 i = aim_recv(conn->fd, msg2, payloadlength - recvd); 1203 if (i <= 0) { 1204 free(msg); 1205 return -1; 1206 } 1207 recvd = recvd + i; 1208 msg2 = msg2 + i; 1209 if ((userfunc=aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER))) 1210 userfunc(sess, &fr, snptr, (double)recvd / payloadlength); 1038 1211 } 1039 1040 msg[payloadlength] = '\0'; 1041 1212 1042 1213 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)) ) 1043 ret = userfunc(sess, &fr, snptr, msg );1214 ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding); 1044 1215 1045 1216 free(msg); … … 1057 1228 struct aim_fileheader_t *fh; 1058 1229 struct aim_msgcookie_t *cook; 1059 struct command_tx_struct *newoft;1230 aim_frame_t *newoft; 1060 1231 aim_rxcallback_t userfunc; 1061 1232 … … 1081 1252 faimdprintf(sess, 1, "error caching cookie\n"); 1082 1253 return -1; 1083 } 1254 } 1084 1255 1085 1256 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x1209, 0))) { … … 1121 1292 1122 1293 if (!(cook = aim_checkcookie(sess, fh->bcookie, AIM_COOKIETYPE_OFTGET))) 1123 faimdprintf(sess, 2, "shit, no cookie in 0x1209. (%i/%s)going to crash..\n", 1294 faimdprintf(sess, 2, "shit, no cookie in 0x1209. (%i/%s)going to crash..\n", AIM_COOKIETYPE_OFTGET, fh->bcookie); 1124 1295 1125 1296 ft = cook->data; … … 1173 1344 #if 0 1174 1345 struct aim_filetransfer_priv *ft; 1175 structaim_msgcookie_t *cook;1346 aim_msgcookie_t *cook; 1176 1347 struct aim_fileheader_t *fh; 1177 struct command_tx_struct *newoft;1348 aim_frame_t *newoft; 1178 1349 int i = 0; 1179 1350 aim_rxcallback_t userfunc; … … 1205 1376 } 1206 1377 1207 newoft->lock = 1;1208 1378 memcpy(newoft->hdr.oft.magic, "OFT2", 4); 1209 1379 newoft->hdr.oft.hdr2len = 0x100 - 8; … … 1221 1391 aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)); 1222 1392 1223 newoft->lock = 0;1224 1393 aim_tx_enqueue(sess, newoft); 1225 1394 … … 1288 1457 } 1289 1458 1459 /* We are receiving a file, and the buddy sent us this header describing 1460 * it. We send back a similar header to confirm, then we're ready to 1461 * start reading the raw data. 1462 */ 1463 static int handlehdr_sendfile_sending(aim_session_t *sess, aim_conn_t *conn, aim_bstream_t *bs) 1464 { 1465 struct aim_filetransfer_priv *ft; 1466 struct aim_fileheader_t *fh; 1467 aim_frame_t *newoft; 1468 aim_rxcallback_t userfunc; 1469 1470 fh = aim_oft_getfh(bs); 1471 1472 /* We receive a null cookie for the first file; we must fill 1473 * it in to authenticate ourselves. -- wtm 1474 */ 1475 ft = conn->internal; 1476 memcpy(&(fh->bcookie), ft->cookie, 8); 1477 1478 memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t)); 1479 free(fh); 1480 1481 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, AIM_OFT_PROTO_ACCEPT, 0))) { 1482 faimdprintf(sess, 2, "faim: send_final_transfer: tx_new OFT failed\n"); 1483 return -1; 1484 } 1485 1486 if (aim_oft_buildheader(&(newoft->data), &(ft->fh)) == -1) { 1487 return -1; 1488 } 1489 memcpy(newoft->hdr.rend.magic, "OFT2", 4); 1490 newoft->hdr.rend.hdrlen = aim_bstream_curpos(&newoft->data); 1491 1492 aim_tx_enqueue(sess, newoft); 1493 1494 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_SENDFILEFILEREQ)) == NULL) 1495 return 1; 1496 1497 { 1498 char *cur; 1499 /* Convert the directory separator: it is sent 1500 * as ^A (0x01). 1501 */ 1502 while ((cur = strchr(ft->fh.name, 0x01))) { 1503 *cur = G_DIR_SEPARATOR; 1504 } 1505 } 1506 return userfunc(sess, NULL, conn, &(ft->fh)); 1507 } 1508 1509 1510 /* 1511 * These were originally described by Josh Myer: 1512 * http://www.geocrawler.com/archives/3/896/2000/9/0/4291064/ 1513 * XXX this doesn't actually work yet 1514 * -- wtm 1515 */ 1516 static int handlehdr_sendfile_resume(aim_session_t *sess, aim_conn_t *conn, aim_bstream_t *bs) { 1517 aim_frame_t *newoft; 1518 aim_msgcookie_t *cook; 1519 struct aim_fileheader_t *fh; 1520 struct aim_filetransfer_priv *ft; 1521 1522 fh = aim_oft_getfh(bs); 1523 if (!(cook = aim_checkcookie(sess, fh->bcookie, AIM_COOKIETYPE_OFTSEND))) { 1524 free(fh); 1525 return -1; 1526 } 1527 ft = (struct aim_filetransfer_priv *)cook->data; 1528 1529 ft->fh.nrecvd = fh->nrecvd; 1530 ft->fh.recvcsum = fh->recvcsum; 1531 strncpy(ft->fh.name, fh->name, sizeof(ft->fh.name)); 1532 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0106, 0))) { 1533 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 1534 free(fh); 1535 return -1; 1536 } 1537 1538 if (aim_oft_buildheader(&(newoft->data), &(ft->fh)) == -1) { 1539 aim_frame_destroy(newoft); 1540 free(fh); 1541 return -1; 1542 } 1543 memcpy(newoft->hdr.rend.magic, "OFT2", 4); 1544 newoft->hdr.rend.hdrlen = aim_bstream_curpos(&newoft->data); 1545 1546 aim_tx_enqueue(sess, newoft); 1547 free(fh); 1548 1549 return 0; 1550 } 1551 1552 /* We are sending a file, and the buddy sent us this header indicating 1553 * that he or she is ready for the raw data. 1554 */ 1555 static int handlehdr_sendfile_recv(aim_session_t *sess, aim_conn_t *conn, aim_bstream_t *bs) { 1556 struct aim_fileheader_t *fh; 1557 aim_msgcookie_t *cook; 1558 int ret = 1; 1559 struct aim_filetransfer_priv *ft; 1560 aim_rxcallback_t userfunc; 1561 1562 fh = aim_oft_getfh(bs); 1563 if (!(cook = aim_checkcookie(sess, fh->bcookie, AIM_COOKIETYPE_OFTSEND))) { 1564 free(fh); 1565 return -1; 1566 } 1567 ft = (struct aim_filetransfer_priv *)cook->data; 1568 1569 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_SENDFILEFILESEND)) ) 1570 ret = userfunc(sess, NULL, conn, &(ft->fh)); 1571 1572 free(fh); 1573 1574 return ret; 1575 } 1576 1290 1577 static int handlehdr_getfile_recv(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) 1291 1578 { 1292 1579 #if 0 1293 1580 struct aim_fileheader_t *fh; 1294 struct aim_filetransfer_priv *ft;1295 1581 struct aim_msgcookie_t *cook; 1296 1582 int ret = 1; 1297 1583 aim_rxcallback_t userfunc; 1584 struct aim_filetransfer_priv *ft; 1298 1585 1299 1586 fh = aim_oft_getfh(hdr); … … 1319 1606 } 1320 1607 1608 /* We just sent the raw data of a file, and the buddy sent us back this 1609 * header indicating that the transfer is complete. 1610 */ 1611 static int handlehdr_sendfile_finish(aim_session_t *sess, aim_conn_t *conn, aim_bstream_t *bs) 1612 { 1613 struct aim_fileheader_t *fh; 1614 aim_msgcookie_t *cook; 1615 aim_rxcallback_t userfunc; 1616 1617 fh = aim_oft_getfh(bs); 1618 1619 if (!(cook = aim_checkcookie(sess, fh->bcookie, AIM_COOKIETYPE_OFTSEND))) { 1620 free(fh); 1621 return -1; 1622 } 1623 1624 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_SENDFILECOMPLETE)) ) 1625 userfunc(sess, NULL, conn, fh->bcookie); 1626 1627 free(fh); 1628 return 0; 1629 } 1630 1321 1631 static int handlehdr_getfile_finish(aim_session_t *sess, aim_conn_t *conn, fu8_t *hdr) 1322 1632 { … … 1338 1648 } 1339 1649 1340 /** 1341 * aim_get_command_rendezvous - OFT equivalent of aim_get_command 1342 * @sess: session to work on 1343 * @conn: conn to pull data from 1344 * 1345 * this reads and handles data from conn->fd. currently a little rough 1346 * around the edges 1347 */ 1348 faim_internal int aim_get_command_rendezvous(aim_session_t *sess, aim_conn_t *conn) 1349 { 1350 fu8_t hdrbuf1[6]; 1351 fu8_t *hdr = NULL; 1352 int hdrlen, hdrtype; 1650 faim_internal int aim_rxdispatch_rendezvous(aim_session_t *sess, aim_frame_t *fr) 1651 { 1652 aim_conn_t *conn = fr->conn; 1653 aim_bstream_t *bs = &fr->data; 1353 1654 int ret = -1; 1354 1655 1355 if (!sess || !conn) 1356 return -1; 1357 1358 memset(hdrbuf1, 0, sizeof(hdrbuf1)); 1359 1360 /* I guess? I didn't understand any of that mess... */ 1361 if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) 1656 if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) { 1657 /* This should never happen. -- wtm */ 1362 1658 return getcommand_getfile(sess, conn); 1363 1659 1364 /* XXX fix all the error cases here */ 1365 if (aim_recv(conn->fd, hdrbuf1, 6) < 6) { 1366 1367 faimdprintf(sess, 2, "faim: rend: read error (fd: %i)\n", conn->fd); 1368 1369 aim_conn_close(conn); 1370 1371 return -1; 1372 } 1373 1374 hdrlen = aimutil_get16(hdrbuf1+4); 1375 hdrlen -= 6; 1376 1377 hdr = malloc(hdrlen); 1378 1379 if (aim_recv(conn->fd, hdr, hdrlen) < hdrlen) { 1380 faimdprintf(sess, 2, "faim: rend: read2 error on %d (%d)\n", conn->fd, hdrlen); 1381 free(hdr); 1382 aim_conn_close(conn); 1383 return -1; 1384 } 1385 1386 hdrtype = aimutil_get16(hdr); 1387 1388 if (hdrtype == 0x0001) 1389 ret = handlehdr_directim(sess, conn, hdr); 1390 else if (hdrtype == 0x1108) /* getfile listing.txt incoming tx->rx */ 1391 ret = handlehdr_getfile_listing(sess, conn, hdr); 1392 else if (hdrtype == 0x1209) /* get file listing ack rx->tx */ 1393 ret = handlehdr_getfile_listing2(sess, conn, hdr); 1394 else if (hdrtype == 0x120b) /* get file listing rx confirm */ 1395 ret = handlehdr_getfile_listing3(sess, conn, hdr); 1396 else if (hdrtype == 0x120c) /* getfile request */ 1397 ret = handlehdr_getfile_request(sess, conn, hdr); 1398 else if (hdrtype == 0x0101) /* getfile sending data */ 1399 ret = handlehdr_getfile_sending(sess, conn, hdr); 1400 else if (hdrtype == 0x0202) /* getfile recv data */ 1401 ret = handlehdr_getfile_recv(sess, conn, hdr); 1402 else if (hdrtype == 0x0204) /* getfile finished */ 1403 ret = handlehdr_getfile_finish(sess, conn, hdr); 1404 else { 1405 faimdprintf(sess, 2,"faim: OFT frame: uknown type %04x\n", hdrtype); 1406 ret = -1; 1660 } else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) { 1661 switch(fr->hdr.rend.type) { 1662 case AIM_OFT_PROTO_OFFER: 1663 ret = handlehdr_sendfile_sending(sess, conn, bs); 1664 break; 1665 case AIM_OFT_PROTO_RESUME: 1666 ret = handlehdr_sendfile_resume(sess, conn, bs); 1667 break; 1668 case AIM_OFT_PROTO_RESUMEACCEPT: /* like _ACCEPT */; 1669 case AIM_OFT_PROTO_ACCEPT: 1670 ret = handlehdr_sendfile_recv(sess, conn, bs); 1671 break; 1672 case AIM_OFT_PROTO_ACK: 1673 ret = handlehdr_sendfile_finish(sess, conn, bs); 1674 break; 1675 default: 1676 faimdprintf(sess, 2, "faim: OFT frame: uknown type %04x\n", fr->hdr.rend.type); 1677 ret = -1; 1678 break; 1679 } 1680 1681 } else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) { 1682 if (fr->hdr.rend.type == 0x0001) 1683 ret = handlehdr_directim(sess, conn, bs); 1684 else 1685 faimdprintf(sess, 0, "faim: DIM frame: unknown type %04x\n", fr->hdr.rend.type); 1686 1687 } else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) { 1688 /* This _really_ shouldn't happen. :) -- wtm */ 1689 char *hdr = NULL; 1690 int hdrtype = fr->hdr.rend.type; 1691 if (hdrtype == 0x1108) /* getfile listing.txt incoming tx->rx */ 1692 ret = handlehdr_getfile_listing(sess, conn, hdr); 1693 else if (hdrtype == 0x1209) /* get file listing ack rx->tx */ 1694 ret = handlehdr_getfile_listing2(sess, conn, hdr); 1695 else if (hdrtype == 0x120b) /* get file listing rx confirm */ 1696 ret = handlehdr_getfile_listing3(sess, conn, hdr); 1697 else if (hdrtype == 0x120c) /* getfile request */ 1698 ret = handlehdr_getfile_request(sess, conn, hdr); 1699 else if (hdrtype == 0x0101) /* getfile sending data */ 1700 ret = handlehdr_getfile_sending(sess, conn, hdr); 1701 else if (hdrtype == 0x0202) /* getfile recv data */ 1702 ret = handlehdr_getfile_recv(sess, conn, hdr); 1703 else if (hdrtype == 0x0204) /* getfile finished */ 1704 ret = handlehdr_getfile_finish(sess, conn, hdr); 1705 else { 1706 faimdprintf(sess, 2,"faim: OFT frame: uknown type %04x\n", hdrtype); 1707 ret = -1; 1708 } 1407 1709 } 1408 1710 1409 free(hdr);1410 1411 1711 if (ret == -1) 1412 1712 aim_conn_close(conn); … … 1415 1715 } 1416 1716 1417 #if 01418 1717 /** 1419 1718 * aim_oft_getfh - extracts an &aim_fileheader_t from buffer hdr. 1420 * @hdr: buffer to extract header from 1421 * 1422 * returns pointer to new struct on success; %NULL on error. 1423 * 1424 */ 1425 static struct aim_fileheader_t *aim_oft_getfh(unsigned char *hdr) 1426 { 1427 struct aim_fileheader_t *fh; 1428 int i, j; 1429 if (!(fh = calloc(1, sizeof(struct aim_fileheader_t)))) 1430 return NULL; 1431 1432 /* [0] and [1] are the type. we can ignore those here. */ 1433 i = 2; 1434 for(j = 0; j < 8; j++, i++) 1435 fh->bcookie[j] = hdr[i]; 1436 fh->encrypt = aimutil_get16(hdr+i); 1437 i += 2; 1438 fh->compress = aimutil_get16(hdr+i); 1439 i += 2; 1440 fh->totfiles = aimutil_get16(hdr+i); 1441 i += 2; 1442 fh->filesleft = aimutil_get16(hdr+i); 1443 i += 2; 1444 fh->totparts = aimutil_get16(hdr+i); 1445 i += 2; 1446 fh->partsleft = aimutil_get16(hdr+i); 1447 i += 2; 1448 fh->totsize = aimutil_get32(hdr+i); 1449 i += 4; 1450 fh->size = aimutil_get32(hdr+i); 1451 i += 4; 1452 fh->modtime = aimutil_get32(hdr+i); 1453 i += 4; 1454 fh->checksum = aimutil_get32(hdr+i); 1455 i += 4; 1456 fh->rfrcsum = aimutil_get32(hdr+i); 1457 i += 4; 1458 fh->rfsize = aimutil_get32(hdr+i); 1459 i += 4; 1460 fh->cretime = aimutil_get32(hdr+i); 1461 i += 4; 1462 fh->rfcsum = aimutil_get32(hdr+i); 1463 i += 4; 1464 fh->nrecvd = aimutil_get32(hdr+i); 1465 i += 4; 1466 fh->recvcsum = aimutil_get32(hdr+i); 1467 i += 4; 1468 memcpy(fh->idstring, hdr+i, 32); 1469 i += 32; 1470 fh->flags = aimutil_get8(hdr+i); 1471 i += 1; 1472 fh->lnameoffset = aimutil_get8(hdr+i); 1473 i += 1; 1474 fh->lsizeoffset = aimutil_get8(hdr+i); 1475 i += 1; 1476 memcpy(fh->dummy, hdr+i, 69); 1477 i += 69; 1478 memcpy(fh->macfileinfo, hdr+i, 16); 1479 i += 16; 1480 fh->nencode = aimutil_get16(hdr+i); 1481 i += 2; 1482 fh->nlanguage = aimutil_get16(hdr+i); 1483 i += 2; 1484 memcpy(fh->name, hdr+i, 64); 1485 i += 64; 1486 return fh; 1719 * @bs: bstream to extract header from 1720 * 1721 * returns pointer to new struct on success; %NULL on error. 1722 * 1723 */ 1724 static struct aim_fileheader_t *aim_oft_getfh(aim_bstream_t *bs) 1725 { 1726 struct aim_fileheader_t *fh; 1727 1728 if (!(fh = calloc(1, sizeof(struct aim_fileheader_t)))) 1729 return NULL; 1730 1731 /* The bstream should be positioned after the hdrtype. */ 1732 aimbs_getrawbuf(bs, fh->bcookie, 8); 1733 fh->encrypt = aimbs_get16(bs); 1734 fh->compress = aimbs_get16(bs); 1735 fh->totfiles = aimbs_get16(bs); 1736 fh->filesleft = aimbs_get16(bs); 1737 fh->totparts = aimbs_get16(bs); 1738 fh->partsleft = aimbs_get16(bs); 1739 fh->totsize = aimbs_get32(bs); 1740 fh->size = aimbs_get32(bs); 1741 fh->modtime = aimbs_get32(bs); 1742 fh->checksum = aimbs_get32(bs); 1743 fh->rfrcsum = aimbs_get32(bs); 1744 fh->rfsize = aimbs_get32(bs); 1745 fh->cretime = aimbs_get32(bs); 1746 fh->rfcsum = aimbs_get32(bs); 1747 fh->nrecvd = aimbs_get32(bs); 1748 fh->recvcsum = aimbs_get32(bs); 1749 aimbs_getrawbuf(bs, fh->idstring, 32); 1750 fh->flags = aimbs_get8(bs); 1751 fh->lnameoffset = aimbs_get8(bs); 1752 fh->lsizeoffset = aimbs_get8(bs); 1753 aimbs_getrawbuf(bs, fh->dummy, 69); 1754 aimbs_getrawbuf(bs, fh->macfileinfo, 16); 1755 fh->nencode = aimbs_get16(bs); 1756 fh->nlanguage = aimbs_get16(bs); 1757 aimbs_getrawbuf(bs, fh->name, 64); /* XXX */ 1758 1759 return fh; 1487 1760 } 1488 #endif1489 1761 1490 1762 /** … … 1492 1764 * @buffer: buffer of data to checksum 1493 1765 * @bufsize: size of buffer 1494 * @checksum: pointer to integer to place result in (pointer!) 1495 * 1496 * 1497 * Note that checksum is a pointer. Checksum should be filled with 1498 * 0xFFFF0000 for each new file; you can have this checksum chunks of 1499 * files in series if you just call it repeatedly in a for(; ; ) loop 1500 * and don't reset the checksum between each call. And you thought we 1501 * didn't care about you and your pathetic client's meomry footprint 1502 * ;^) 1503 * 1504 * 1505 * Also, it's been said that this is incorrect as currently 1506 * written. You were warned. 1507 */ 1508 faim_export fu32_t aim_oft_checksum(aim_session_t *sess, const char *buffer, int bufsize, fu32_t *checksum) 1509 { 1510 return 0xdeadbeef; 1511 #if 0 1512 fu16_t check0, check1; 1513 int i; 1514 1515 check0 = ((*checksum & 0xFF000000) >> 16); 1516 check1 = ((*checksum & 0x00ff0000) >> 16); 1517 for(i = 0; i < bufsize; i++) { 1518 if (i % 2) { /* use check1 -- second byte */ 1519 if ( (short)buffer[i] > check1 ) { /* wrapping */ 1520 check1 += 0x100; /* this is a cheap way to wrap */ 1521 1522 /* if we're wrapping, decrement the other one */ 1523 /* XXX: check this corner case */ 1524 if (check0 == 0) 1525 check0 = 0x00ff; 1526 else 1527 check0--; 1528 } 1529 check1 -= buffer[i]; 1530 } else { /* use check0 -- first byte */ 1531 if ( (short)buffer[i] > check0 ) { /* wrapping */ 1532 check0 += 0x100; /* this is a cheap way to wrap */ 1533 1534 /* if we're wrapping, decrement the other one */ 1535 /* XXX: check this corner case */ 1536 if (check1 == 0) 1537 check1 = 0x00ff; 1538 else 1539 check1--; 1540 } 1541 check0 -= buffer[i]; 1542 } 1543 } 1544 1545 if (check0 > 0xff || check1 > 0xff) { 1546 /* they shouldn't be able to do this. error! */ 1547 faimdprintf(sess, 2, "check0 or check1 is too high: 0x%04x, 0x%04x\n", check0, check1); 1548 return -1; 1549 } 1550 1551 /* grab just the lowest byte; this should be clean, but just in 1552 case */ 1553 check0 &= 0xff; 1554 check1 &= 0xff; 1555 1556 *checksum = ((check0 * 0x1000000) + (check1 * 0x10000)); 1557 return *checksum; 1558 #endif 1559 } 1560 1561 #if 0 1766 * @prevcheck: previous checksum 1767 * 1768 * Prevcheck should be 0xFFFF0000 for each new file; you can have this 1769 * checksum chunks of files in series if you just call it repeatedly in a 1770 * for(; ; ) loop and don't reset the checksum between each call. And you 1771 * thought we didn't care about you and your pathetic client's meomry 1772 * footprint ;^) 1773 * 1774 * Thanks to Graham Booker for providing this improved checksum 1775 * routine, which is simpler and should be more accurate than Josh 1776 * Myer's original code. -- wtm 1777 * 1778 * This algorithim works every time I have tried it. The other fails 1779 * sometimes. So, AOL who thought this up? It has got to be the weirdest 1780 * checksum I have ever seen. 1781 */ 1782 faim_export fu32_t aim_oft_checksum(const unsigned char *buffer, int bufferlen, int prevcheck) { 1783 fu32_t check = (prevcheck >> 16) & 0xffff, oldcheck; 1784 int i; 1785 unsigned short val; 1786 1787 for (i=0; i<bufferlen; i++) { 1788 oldcheck = check; 1789 if (i&1) { 1790 val = buffer[i]; 1791 } else { 1792 val = buffer[i] << 8; 1793 } 1794 check -= val; 1795 /* The follownig appears to be necessary.... It happens every once in a while and the checksum doesn't fail. */ 1796 if (check > oldcheck) { 1797 check--; 1798 } 1799 } 1800 check = ((check & 0x0000ffff) + (check >> 16)); 1801 check = ((check & 0x0000ffff) + (check >> 16)); 1802 return check << 16; 1803 } 1804 1805 faim_export fu32_t aim_update_checksum(aim_session_t *sess, aim_conn_t *conn, 1806 const unsigned char *buffer, int len) { 1807 struct aim_filetransfer_priv *ft = conn->internal; 1808 1809 ft->fh.nrecvd += len; 1810 ft->fh.recvcsum = aim_oft_checksum(buffer, len, ft->fh.recvcsum); 1811 1812 return 0; 1813 } 1814 1562 1815 /** 1563 1816 * aim_oft_buildheader - fills a buffer with network-order fh data 1564 * @dest: buffer to fill -- pre-alloced 1565 * @fh: fh to get data from 1566 * 1567 * returns length written; -1 on error. 1568 * DOES NOT DO BOUNDS CHECKING! 1569 * 1570 */ 1571 static int oft_buildheader(unsigned char *dest, struct aim_fileheader_t *fh) 1817 * @bs: bstream to fill -- automatically initialized 1818 * @fh: fh to get data from 1819 * 1820 * returns -1 on error. 1821 * 1822 */ 1823 static int aim_oft_buildheader(aim_bstream_t *bs, struct aim_fileheader_t *fh) 1572 1824 { 1573 int i, curbyte; 1574 if (!dest || !fh) 1575 return -1; 1576 curbyte = 0; 1577 for(i = 0; i < 8; i++) 1578 curbyte += aimutil_put8(dest+curbyte, fh->bcookie[i]); 1579 curbyte += aimutil_put16(dest+curbyte, fh->encrypt); 1580 curbyte += aimutil_put16(dest+curbyte, fh->compress); 1581 curbyte += aimutil_put16(dest+curbyte, fh->totfiles); 1582 curbyte += aimutil_put16(dest+curbyte, fh->filesleft); 1583 curbyte += aimutil_put16(dest+curbyte, fh->totparts); 1584 curbyte += aimutil_put16(dest+curbyte, fh->partsleft); 1585 curbyte += aimutil_put32(dest+curbyte, fh->totsize); 1586 curbyte += aimutil_put32(dest+curbyte, fh->size); 1587 curbyte += aimutil_put32(dest+curbyte, fh->modtime); 1588 curbyte += aimutil_put32(dest+curbyte, fh->checksum); 1589 curbyte += aimutil_put32(dest+curbyte, fh->rfrcsum); 1590 curbyte += aimutil_put32(dest+curbyte, fh->rfsize); 1591 curbyte += aimutil_put32(dest+curbyte, fh->cretime); 1592 curbyte += aimutil_put32(dest+curbyte, fh->rfcsum); 1593 curbyte += aimutil_put32(dest+curbyte, fh->nrecvd); 1594 curbyte += aimutil_put32(dest+curbyte, fh->recvcsum); 1595 memcpy(dest+curbyte, fh->idstring, 32); 1596 curbyte += 32; 1597 curbyte += aimutil_put8(dest+curbyte, fh->flags); 1598 curbyte += aimutil_put8(dest+curbyte, fh->lnameoffset); 1599 curbyte += aimutil_put8(dest+curbyte, fh->lsizeoffset); 1600 memcpy(dest+curbyte, fh->dummy, 69); 1601 curbyte += 69; 1602 memcpy(dest+curbyte, fh->macfileinfo, 16); 1603 curbyte += 16; 1604 curbyte += aimutil_put16(dest+curbyte, fh->nencode); 1605 curbyte += aimutil_put16(dest+curbyte, fh->nlanguage); 1606 memset(dest+curbyte, 0x00, 64); 1607 memcpy(dest+curbyte, fh->name, 64); 1608 1609 /* XXX: Filenames longer than 64B */ 1610 curbyte += 64; 1611 return curbyte; 1612 } 1613 #endif 1825 fu8_t *hdr; 1826 1827 if (!bs || !fh) 1828 return -1; 1829 1830 1831 1832 1833 if (!(hdr = (unsigned char *)calloc(1, 0x100 - 8))) { 1834 return -1; 1835 } 1836 aim_bstream_init(bs, hdr, 0x100 - 8); 1837 1838 aimbs_putraw(bs, fh->bcookie, 8); 1839 aimbs_put16(bs, fh->encrypt); 1840 aimbs_put16(bs, fh->compress); 1841 aimbs_put16(bs, fh->totfiles); 1842 aimbs_put16(bs, fh->filesleft); 1843 aimbs_put16(bs, fh->totparts); 1844 aimbs_put16(bs, fh->partsleft); 1845 aimbs_put32(bs, fh->totsize); 1846 aimbs_put32(bs, fh->size); 1847 aimbs_put32(bs, fh->modtime); 1848 aimbs_put32(bs, fh->checksum); 1849 aimbs_put32(bs, fh->rfrcsum); 1850 aimbs_put32(bs, fh->rfsize); 1851 aimbs_put32(bs, fh->cretime); 1852 aimbs_put32(bs, fh->rfcsum); 1853 aimbs_put32(bs, fh->nrecvd); 1854 aimbs_put32(bs, fh->recvcsum); 1855 aimbs_putraw(bs, fh->idstring, 32); 1856 aimbs_put8(bs, fh->flags); 1857 aimbs_put8(bs, fh->lnameoffset); 1858 aimbs_put8(bs, fh->lsizeoffset); 1859 aimbs_putraw(bs, fh->dummy, 69); 1860 aimbs_putraw(bs, fh->macfileinfo, 16); 1861 aimbs_put16(bs, fh->nencode); 1862 aimbs_put16(bs, fh->nlanguage); 1863 aimbs_putraw(bs, fh->name, 64); 1864 1865 /* XXX: Filenames longer than 64B */ 1866 return 0; 1867 } 1614 1868 1615 1869 /** … … 1625 1879 return NULL; 1626 1880 #if 0 1627 struct command_tx_struct *newpacket; 1628 struct aim_conn_t *newconn; 1629 struct aim_filetransfer_priv *priv; 1630 struct aim_msgcookie_t *cookie; 1631 int curbyte, i, listenfd; 1632 short port = 4443; 1633 struct hostent *hptr; 1634 struct utsname myname; 1635 char cap[16]; 1636 char d[4]; 1881 struct command_tx_struct *newpacket; 1882 struct aim_conn_t *newconn; 1883 struct aim_filetransfer_priv *priv; 1884 struct aim_msgcookie_t *cookie; 1885 int curbyte, i, listenfd; 1886 short port = 4443; 1887 struct hostent *hptr; 1888 struct utsname myname; 1889 char cap[16]; 1890 char d[4]; 1891 1892 /* Open our socket */ 1893 1894 if ( (listenfd = aim_listenestablish(port)) == -1) 1895 return NULL; 1896 1897 /* get our local IP */ 1898 1899 if (uname(&myname) < 0) 1900 return NULL; 1901 if ( (hptr = gethostbyname(myname.nodename)) == NULL) 1902 return NULL; 1903 memcpy(&d, hptr->h_addr_list[0], 4); 1904 1905 aim_putcap(cap, 16, AIM_CAPS_GETFILE); 1906 1907 /* create the OSCAR packet */ 1908 1909 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+8+2+1+strlen(destsn)+4+4+0x42))) 1910 return NULL; 1911 newpacket->lock = 1; 1912 1913 /* lock struct */ 1914 curbyte = 0; 1915 curbyte += aim_putsnac(newpacket->data+curbyte, 0x0004, 0x0006, 0x0000, sess->snac_nextid); 1916 1917 /* XXX: check the cookie before commiting to using it */ 1918 1919 /* Generate a random message cookie 1920 * This cookie needs to be alphanumeric and NULL-terminated to be TOC-compatible. */ 1921 for (i=0; i<7; i++) 1922 curbyte += aimutil_put8(newpacket->data+curbyte, 0x30 + ((u_char) random() % 10)); 1923 1924 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1925 1926 /* grab all the data for cookie caching. */ 1637 1927 1638 /* Open our socket */ 1639 1640 if ( (listenfd = aim_listenestablish(port)) == -1) 1641 return NULL; 1642 1643 /* get our local IP */ 1644 1645 if (uname(&myname) < 0) 1646 return NULL; 1647 if ( (hptr = gethostbyname(myname.nodename)) == NULL) 1648 return NULL; 1649 memcpy(&d, hptr->h_addr_list[0], 4); 1650 1651 aim_putcap(cap, 16, AIM_CAPS_GETFILE); 1652 1653 /* create the OSCAR packet */ 1654 1655 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+8+2+1+strlen(destsn)+4+4+0x42))) 1656 return NULL; 1657 newpacket->lock = 1; 1658 1659 /* lock struct */ 1660 curbyte = 0; 1661 curbyte += aim_putsnac(newpacket->data+curbyte, 0x0004, 0x0006, 0x0000, sess->snac_nextid); 1662 1663 /* XXX: check the cookie before commiting to using it */ 1664 1665 /* Generate a random message cookie 1666 * This cookie needs to be alphanumeric and NULL-terminated to be TOC-compatible. */ 1667 for (i=0; i<7; i++) 1668 curbyte += aimutil_put8(newpacket->data+curbyte, 0x30 + ((u_char) random() % 10)); 1669 1670 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1671 1672 /* grab all the data for cookie caching. */ 1928 if (!(cookie = (struct aim_msgcookie_t *)calloc(1, sizeof(struct aim_msgcookie_t)))) 1929 return NULL; 1930 memcpy(cookie->cookie, newpacket->data+curbyte-8, 8); 1931 cookie->type = AIM_COOKIETYPE_OFTGET; 1932 1933 if (!(priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)))) 1934 return NULL; 1935 memcpy(priv->cookie, cookie, 8); 1936 memcpy(priv->sn, destsn, sizeof(priv->sn)); 1937 memcpy(priv->fh.name, "listing.txt", strlen("listing.txt")); 1938 priv->state = 1; 1939 1940 cookie->data = priv; 1941 1942 aim_cachecookie(sess, cookie); 1943 1944 /* Channel ID */ 1945 curbyte += aimutil_put16(newpacket->data+curbyte,0x0002); 1946 1947 /* Destination SN (prepended with byte length) */ 1948 curbyte += aimutil_put8(newpacket->data+curbyte,strlen(destsn)); 1949 curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn)); 1950 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); 1951 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); 1952 1953 /* enTLV start */ 1954 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); 1955 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0042); 1956 1957 /* Flag data / ICBM Parameters? */ 1958 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1959 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1960 1961 /* Cookie */ 1962 curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cookie, 8); 1963 1964 /* Capability String */ 1965 curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cap, 0x10); 1966 1967 /* 000a/0002 : 0001 */ 1968 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000a); 1969 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); 1970 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001); 1971 1972 /* 0003/0004: IP address */ 1973 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); 1974 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0004); 1975 for (i = 0; i < 4; i++) 1976 curbyte += aimutil_put8(newpacket->data+curbyte, d[i]); 1977 1978 /* already in network byte order */ 1673 1979 1674 if (!(cookie = (struct aim_msgcookie_t *)calloc(1, sizeof(struct aim_msgcookie_t)))) 1675 return NULL; 1676 memcpy(cookie->cookie, newpacket->data+curbyte-8, 8); 1677 cookie->type = AIM_COOKIETYPE_OFTGET; 1678 1679 if (!(priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)))) 1680 return NULL; 1681 memcpy(priv->cookie, cookie, 8); 1682 memcpy(priv->sn, destsn, sizeof(priv->sn)); 1683 memcpy(priv->fh.name, "listing.txt", strlen("listing.txt")); 1684 priv->state = 1; 1685 1686 cookie->data = priv; 1687 1688 aim_cachecookie(sess, cookie); 1689 1690 /* Channel ID */ 1691 curbyte += aimutil_put16(newpacket->data+curbyte,0x0002); 1692 1693 /* Destination SN (prepended with byte length) */ 1694 curbyte += aimutil_put8(newpacket->data+curbyte,strlen(destsn)); 1695 curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn)); 1696 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); 1697 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); 1698 1699 /* enTLV start */ 1700 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); 1701 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0042); 1702 1703 /* Flag data / ICBM Parameters? */ 1704 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1705 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1706 1707 /* Cookie */ 1708 curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cookie, 8); 1709 1710 /* Capability String */ 1711 curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cap, 0x10); 1712 1713 /* 000a/0002 : 0001 */ 1714 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000a); 1715 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); 1716 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001); 1717 1718 /* 0003/0004: IP address */ 1719 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); 1720 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0004); 1721 for(i = 0; i < 4; i++) 1722 curbyte += aimutil_put8(newpacket->data+curbyte, d[i]); 1723 1724 /* already in network byte order */ 1725 1726 /* 0005/0002: Port */ 1727 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); 1728 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); 1729 curbyte += aimutil_put16(newpacket->data+curbyte, port); 1730 1731 /* 000f/0000: ?? */ 1732 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f); 1733 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); 1734 1735 /* 2711/000c: ?? */ 1736 curbyte += aimutil_put16(newpacket->data+curbyte, 0x2711); 1737 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000c); 1738 curbyte += aimutil_put32(newpacket->data+curbyte, 0x00120001); 1739 1740 for(i = 0; i < 0x000c - 4; i++) 1741 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1742 1743 newpacket->commandlen = curbyte; 1744 newpacket->lock = 0; 1745 aim_tx_enqueue(sess, newpacket); 1746 1747 /* allocate and set up our connection */ 1748 1749 i = fcntl(listenfd, F_GETFL, 0); 1750 fcntl(listenfd, F_SETFL, i | O_NONBLOCK); 1751 newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL); 1752 1753 if (!newconn){ 1754 perror("aim_newconn"); 1755 return NULL; 1756 } 1757 1758 newconn->fd = listenfd; 1759 newconn->subtype = AIM_CONN_SUBTYPE_OFT_GETFILE; 1760 newconn->priv = priv; 1761 faimdprintf(sess, 2,"faim: listening (fd = %d, unconnected)\n", newconn->fd); 1762 1763 return newconn; 1980 /* 0005/0002: Port */ 1981 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); 1982 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); 1983 curbyte += aimutil_put16(newpacket->data+curbyte, port); 1984 1985 /* 000f/0000: ?? */ 1986 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f); 1987 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); 1988 1989 /* 2711/000c: ?? */ 1990 curbyte += aimutil_put16(newpacket->data+curbyte, 0x2711); 1991 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000c); 1992 curbyte += aimutil_put32(newpacket->data+curbyte, 0x00120001); 1993 1994 for (i = 0; i < 0x000c - 4; i++) 1995 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); 1996 1997 newpacket->commandlen = curbyte; 1998 newpacket->lock = 0; 1999 aim_tx_enqueue(sess, newpacket); 2000 2001 /* allocate and set up our connection */ 2002 2003 i = fcntl(listenfd, F_GETFL, 0); 2004 fcntl(listenfd, F_SETFL, i | O_NONBLOCK); 2005 newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL); 2006 2007 if (!newconn){ 2008 perror("aim_newconn"); 2009 return NULL; 2010 } 2011 2012 newconn->fd = listenfd; 2013 newconn->subtype = AIM_CONN_SUBTYPE_OFT_GETFILE; 2014 newconn->internal = priv; 2015 faimdprintf(sess, 2,"faim: listening (fd = %d, unconnected)\n", newconn->fd); 2016 2017 return newconn; 1764 2018 #endif 1765 2019 } … … 1775 2029 * returns -1 on error, 0 on successful enqueuing 1776 2030 */ 2031 #if 0 1777 2032 faim_export int aim_oft_getfile_request(aim_session_t *sess, aim_conn_t *conn, const char *name, int size) 1778 2033 { 1779 return -EINVAL; 1780 #if 0 1781 struct command_tx_struct *newoft; 1782 struct aim_filetransfer_priv *ft; 1783 if (!sess || !conn || !conn->priv || !name) 1784 return -1; 1785 1786 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x120c, 0))) { 1787 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 1788 return -1; 1789 } 1790 1791 newoft->lock = 1; 1792 1793 memcpy(newoft->hdr.oft.magic, "OFT2", 4); 1794 newoft->hdr.oft.hdr2len = 0x100 - 8; 1795 1796 ft = (struct aim_filetransfer_priv *)conn->priv; 1797 ft->fh.filesleft = 1; 1798 ft->fh.totfiles = 1; 1799 ft->fh.totparts = 1; 1800 ft->fh.partsleft = 1; 1801 ft->fh.totsize = size; 1802 ft->fh.size = size; 1803 ft->fh.checksum = 0; 1804 memcpy(ft->fh.name, name, strlen(name)); 1805 memset(ft->fh.name+strlen(name), 0, 1); 1806 1807 if (!(newoft->hdr.oft.hdr2 = (unsigned char *)calloc(1,newoft->hdr.oft.hdr2len))) { 1808 newoft->lock = 0; 1809 aim_frame_destroy(newoft); 1810 return -1; 1811 } 1812 1813 if (!(aim_oft_buildheader(newoft->hdr.oft.hdr2, &(ft->fh)))) { 1814 newoft->lock = 0; 1815 aim_frame_destroy(newoft); 1816 return -1; 1817 } 1818 1819 newoft->lock = 0; 1820 1821 aim_tx_enqueue(sess, newoft); 1822 return 0; 2034 aim_frame_t *newoft; 2035 struct aim_filetransfer_priv *ft; 2036 if (!sess || !conn || !conn->priv || !name) 2037 return -1; 2038 2039 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x120c, 0))) { 2040 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 2041 return -1; 2042 } 2043 memcpy(newoft->hdr.oft.magic, "OFT2", 4); 2044 newoft->hdr.oft.hdr2len = 0x100 - 8; 2045 2046 ft = (struct aim_filetransfer_priv *)conn->priv; 2047 ft->fh.filesleft = 1; 2048 ft->fh.totfiles = 1; 2049 ft->fh.totparts = 1; 2050 ft->fh.partsleft = 1; 2051 ft->fh.totsize = size; 2052 ft->fh.size = size; 2053 ft->fh.checksum = 0; 2054 memcpy(ft->fh.name, name, strlen(name)); 2055 memset(ft->fh.name+strlen(name), 0, 1); 2056 2057 if (!(newoft->hdr.oft.hdr2 = (unsigned char *)calloc(1,newoft->hdr.oft.hdr2len))) { 2058 aim_frame_destroy(newoft); 2059 return -1; 2060 } 2061 2062 if (!(aim_oft_buildheader(newoft->hdr.oft.hdr2, &(ft->fh)))) { 2063 aim_frame_destroy(newoft); 2064 return -1; 2065 } 2066 2067 aim_tx_enqueue(sess, newoft); 2068 return 0; 2069 } 1823 2070 #endif 2071 2072 /* Identify a file that we are about to send by transmitting the 2073 * appropriate header. 2074 */ 2075 faim_export int aim_oft_sendfile_request(aim_session_t *sess, aim_conn_t *conn, const char *filename, int filesdone, int numfiles, int size, int totsize) 2076 { 2077 aim_frame_t *newoft; 2078 aim_msgcookie_t *cook; 2079 struct aim_filetransfer_priv *ft = (struct aim_filetransfer_priv *)conn->internal; 2080 struct aim_fileheader_t *fh; 2081 2082 if (!sess || !conn || !filename) 2083 return -1; 2084 2085 if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t)))) 2086 return -1; 2087 2088 #ifdef DUMB_OFT_CHECKSUM 2089 /* Yes, we are supposed to checksum the whole file before sending, and 2090 * yes, it's dumb. This is the only way to get some clients (such as 2091 * Mac AIM v4.5.163) to successfully complete the transfer. With 2092 * the WinAIM clients, we seem to be able to get away with just 2093 * setting the checksum to zero. 2094 * -- wtm 2095 */ 2096 { 2097 int fd = open(filename, O_RDONLY); 2098 if (fd >= 0) { 2099 int bytes; 2100 char buf[1024]; 2101 fh->checksum = 0xffff0000; 2102 while ((bytes = aim_recv(fd, buf, 1024)) > 0) { 2103 fh->checksum = aim_oft_checksum(buf, bytes, fh->checksum); 2104 } 2105 } 2106 close(fd); 2107 } 2108 #else 2109 fh->checksum = 0x00000000; 2110 #endif 2111 fh->encrypt = 0x0000; 2112 fh->compress = 0x0000; 2113 fh->totfiles = numfiles; 2114 fh->filesleft = numfiles - filesdone; 2115 fh->totparts = 0x0001; /* set to 0x0002 sending Mac resource forks */ 2116 fh->partsleft = 0x0001; 2117 fh->totsize = totsize; 2118 fh->size = size; 2119 fh->modtime = (int)time(NULL); /* we'll go with current time for now */ 2120 /* fh->checksum set above */ 2121 fh->rfcsum = 0x00000000; 2122 fh->rfsize = 0x00000000; 2123 fh->cretime = 0x00000000; 2124 fh->rfcsum = 0x00000000; 2125 fh->nrecvd = 0x00000000; /* always zero initially */ 2126 fh->recvcsum= 0x00000000; /* ditto */ 2127 2128 strncpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring)); 2129 fh->flags = 0x02; 2130 fh->lnameoffset = 0x1a; 2131 fh->lsizeoffset = 0x10; 2132 memset(fh->dummy, 0, sizeof(fh->dummy)); 2133 memset(fh->macfileinfo, 0, sizeof(fh->macfileinfo)); 2134 2135 /* apparently 0 is ASCII, 2 is UCS-2 */ 2136 /* it is likely that 3 is ISO 8859-1 */ 2137 fh->nencode = 0x0000; 2138 fh->nlanguage = 0x0000; 2139 2140 /* Convert the directory separator to ^A for portability. */ 2141 strncpy(fh->name, filename, sizeof(fh->name)); 2142 oft_dirconvert(fh->name); 2143 2144 /* XXX we should normally send a null cookie here, and make 2145 * the receiver fill it in for authentication -- wtm 2146 */ 2147 memcpy(fh->bcookie, ft->cookie, 8); 2148 2149 if (!(cook = aim_checkcookie(sess, ft->cookie, AIM_COOKIETYPE_OFTSEND))) { 2150 return -1; 2151 } 2152 2153 /* Update both headers to be safe. */ 2154 memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t)); 2155 memcpy(&(((struct aim_filetransfer_priv *)cook->data)->fh), fh, sizeof(struct aim_fileheader_t)); 2156 2157 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, AIM_OFT_PROTO_OFFER, 0))) { 2158 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 2159 free(fh); 2160 return -1; 2161 } 2162 2163 if (aim_oft_buildheader(&newoft->data, fh) == -1) { 2164 aim_frame_destroy(newoft); 2165 free(fh); 2166 return -1; 2167 } 2168 2169 memcpy(newoft->hdr.rend.magic, "OFT2", 4); 2170 newoft->hdr.rend.hdrlen = aim_bstream_curpos(&newoft->data); 2171 2172 aim_tx_enqueue(sess, newoft); 2173 free(fh); 2174 return 0; 1824 2175 } 1825 2176 … … 1837 2188 return -EINVAL; 1838 2189 #if 0 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 2190 struct command_tx_struct *newoft; 2191 struct aim_filetransfer_priv *ft; 2192 2193 if (!sess || !conn || !conn->priv) 2194 return -1; 2195 2196 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0202, 0))) { 2197 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 2198 return -1; 2199 } 2200 2201 newoft->lock = 1; 2202 2203 memcpy(newoft->hdr.oft.magic, "OFT2", 4); 2204 newoft->hdr.oft.hdr2len = 0x100-8; 2205 2206 if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { 2207 newoft->lock = 0; 2208 aim_frame_destroy(newoft); 2209 return -1; 2210 } 2211 2212 ft = (struct aim_filetransfer_priv *)conn->priv; 2213 2214 if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)))) { 2215 newoft->lock = 0; 2216 aim_frame_destroy(newoft); 2217 return -1; 2218 } 2219 2220 newoft->lock = 0; 2221 aim_tx_enqueue(sess, newoft); 2222 return 0; 1872 2223 #endif 1873 2224 } 1874 2225 1875 2226 /** 1876 * aim_oft_ getfile_end - end a getfile.2227 * aim_oft_end - end a getfile/sendfile. 1877 2228 * @sess: your session 1878 2229 * @conn: the getfile connection … … 1881 2232 * receiving/requesting end. 1882 2233 */ 1883 faim_export int aim_oft_getfile_end(aim_session_t *sess, aim_conn_t *conn) 1884 { 1885 return -EINVAL; 1886 #if 0 1887 struct command_tx_struct *newoft; 1888 struct aim_filetransfer_priv *ft; 1889 1890 if (!sess || !conn || !conn->priv) 1891 return -1; 1892 1893 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0204, 0))) { 1894 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 1895 return -1; 1896 } 1897 1898 newoft->lock = 1; 1899 1900 memcpy(newoft->hdr.oft.magic, "OFT2", 4); 1901 newoft->hdr.oft.hdr2len = 0x100 - 8; 1902 1903 if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { 1904 newoft->lock = 0; 1905 aim_frame_destroy(newoft); 1906 return -1; 1907 } 1908 1909 ft = (struct aim_filetransfer_priv *)conn->priv; 1910 ft->state = 4; /* no longer wanting data */ 1911 ft->fh.nrecvd = ft->fh.size; 1912 ft->fh.recvcsum = ft->fh.checksum; 1913 ft->fh.flags = 0x21; 1914 1915 if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)))) { 1916 newoft->lock = 0; 1917 aim_frame_destroy(newoft); 1918 return -1; 1919 } 1920 1921 newoft->lock = 0; 1922 aim_tx_enqueue(sess, newoft); 1923 1924 return 0; 1925 #endif /* 0 */ 1926 } 1927 2234 faim_export int aim_oft_end(aim_session_t *sess, aim_conn_t *conn) 2235 { 2236 aim_frame_t *newoft; 2237 struct aim_filetransfer_priv *ft; 2238 2239 if (!sess || !conn || !conn->internal) 2240 return -1; 2241 2242 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, AIM_OFT_PROTO_ACK, 0))) { 2243 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); 2244 return -1; 2245 } 2246 2247 ft = (struct aim_filetransfer_priv *)conn->internal; 2248 ft->state = 4; /* no longer wanting data */ 2249 ft->fh.flags = 0x21; 2250 2251 if (aim_oft_buildheader(&(newoft->data), &(ft->fh)) == -1) { 2252 aim_frame_destroy(newoft); 2253 return -1; 2254 } 2255 memcpy(newoft->hdr.rend.magic, "OFT2", 4); 2256 newoft->hdr.rend.hdrlen = aim_bstream_curpos(&newoft->data); 2257 2258 aim_tx_enqueue(sess, newoft); 2259 2260 return 0; 2261 } 2262 2263 /* 2264 * Convert the directory separator to ^A, which seems to be AOL's attempt at portability. 2265 */ 2266 static void oft_dirconvert(char *name) { 2267 char *c = name; 2268 while ((c = strchr(c, G_DIR_SEPARATOR))) 2269 *c = 0x01; 2270 }
Note: See TracChangeset
for help on using the changeset viewer.