Changeset 862371b for libfaim/ft.c
- Timestamp:
- Jun 29, 2003, 1:47:04 PM (23 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
-
libfaim/ft.c (modified) (42 diffs)
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 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0008);178 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x000c);179 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);180 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x1466);181 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0001);182 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x2e0f);183 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x393e);184 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0xcac8);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 return NULL;469 return NULL; 372 470 373 471 if ((conn->type != AIM_CONN_TYPE_RENDEZVOUS) || 374 472 (conn->subtype != AIM_CONN_SUBTYPE_OFT_DIRECTIM)) 375 return NULL;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 * @file is an opened listing file780 * @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 struct aim_fileheader_t *fh;652 u_long totsize = 0, size = 0, checksum = 0xffff0000;653 short totfiles = 0;654 char *linebuf, sizebuf[9];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 if (linebuf[strlen(linebuf)-1] != '\n') {694 faimdprintf(sess, 2, "faim: OFT: getlisting -- hit EOF or line too long!\n");695 }696 697 memcpy(sizebuf, linebuf+17, 8);698 699 totsize += strtol(sizebuf, NULL, 10);700 memset(linebuf, 0, linelength);701 } 702 703 if (fseek(file, 0, SEEK_SET) == -1) {704 perror("getlisting END2 fseek:");705 faimdprintf(sess, 2, "getlising fseek END2 error\n");706 } 707 708 free(linebuf);709 710 /* we're going to ignore checksumming the data for now -- that711 * requires walking the whole listing.txt. it should probably be712 * done at register time and cached, but, eh. */ 713 714 if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t))))715 return NULL;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 memcpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring));736 memset(fh->idstring+strlen(fh->idstring), 0, sizeof(fh->idstring)-strlen(fh->idstring));737 738 fh->flags= 0x02;739 fh->lnameoffset = 0x1a;740 fh->lsizeoffset = 0x10;741 742 /*memset(fh->dummy, 0, sizeof(fh->dummy)); */743 memset(fh->macfileinfo, 0, sizeof(fh->macfileinfo));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 memset(fh->name+strlen(fh->name), 0, 64-strlen(fh->name));751 752 faimdprintf(sess, 2, "faim: OFT: listing fh name %s / %s\n", fh->name, (fh->name+(strlen(fh->name))));753 return fh;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", AIM_COOKIETYPE_OFTGET, fh->bcookie);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 struct command_tx_struct *newoft;1840 struct aim_filetransfer_priv *ft;1841 1842 if (!sess || !conn || !conn->priv)1843 return -1;1844 1845 if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0202, 0))) {1846 faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n");1847 return -1;1848 }1849 1850 newoft->lock = 1;1851 1852 memcpy(newoft->hdr.oft.magic, "OFT2", 4);1853 newoft->hdr.oft.hdr2len = 0x100-8;1854 1855 if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) {1856 newoft->lock = 0;1857 aim_frame_destroy(newoft);1858 return -1;1859 }1860 1861 ft = (struct aim_filetransfer_priv *)conn->priv;1862 1863 if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)))) {1864 newoft->lock = 0;1865 aim_frame_destroy(newoft);1866 return -1;1867 }1868 1869 newoft->lock = 0;1870 aim_tx_enqueue(sess, newoft);1871 return 0;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.
