📄 ft.c
字号:
fh->totsize = aimutil_get32(hdr+i); i += 4; fh->size = aimutil_get32(hdr+i); i += 4; fh->modtime = aimutil_get32(hdr+i); i += 4; fh->checksum = aimutil_get32(hdr+i); i += 4; fh->rfrcsum = aimutil_get32(hdr+i); i += 4; fh->rfsize = aimutil_get32(hdr+i); i += 4; fh->cretime = aimutil_get32(hdr+i); i += 4; fh->rfcsum = aimutil_get32(hdr+i); i += 4; fh->nrecvd = aimutil_get32(hdr+i); i += 4; fh->recvcsum = aimutil_get32(hdr+i); i += 4; memcpy(fh->idstring, hdr+i, 32); i += 32; fh->flags = aimutil_get8(hdr+i); i += 1; fh->lnameoffset = aimutil_get8(hdr+i); i += 1; fh->lsizeoffset = aimutil_get8(hdr+i); i += 1; memcpy(fh->dummy, hdr+i, 69); i += 69; memcpy(fh->macfileinfo, hdr+i, 16); i += 16; fh->nencode = aimutil_get16(hdr+i); i += 2; fh->nlanguage = aimutil_get16(hdr+i); i += 2; memcpy(fh->name, hdr+i, 64); i += 64; return fh;} #endif/** * aim_oft_checksum - calculate oft checksum of buffer * @buffer: buffer of data to checksum * @bufsize: size of buffer * @checksum: pointer to integer to place result in (pointer!) * * * Note that checksum is a pointer. Checksum should be filled with * 0xFFFF0000 for each new file; you can have this checksum chunks of * files in series if you just call it repeatedly in a for(; ; ) loop * and don't reset the checksum between each call. And you thought we * didn't care about you and your pathetic client's meomry footprint * ;^) * * * Also, it's been said that this is incorrect as currently * written. You were warned. */faim_export fu32_t aim_oft_checksum(aim_session_t *sess, const char *buffer, int bufsize, fu32_t *checksum){ return 0xdeadbeef;#if 0 fu16_t check0, check1; int i; check0 = ((*checksum & 0xFF000000) >> 16); check1 = ((*checksum & 0x00ff0000) >> 16); for(i = 0; i < bufsize; i++) { if (i % 2) { /* use check1 -- second byte */ if ( (short)buffer[i] > check1 ) { /* wrapping */ check1 += 0x100; /* this is a cheap way to wrap */ /* if we're wrapping, decrement the other one */ /* XXX: check this corner case */ if (check0 == 0) check0 = 0x00ff; else check0--; } check1 -= buffer[i]; } else { /* use check0 -- first byte */ if ( (short)buffer[i] > check0 ) { /* wrapping */ check0 += 0x100; /* this is a cheap way to wrap */ /* if we're wrapping, decrement the other one */ /* XXX: check this corner case */ if (check1 == 0) check1 = 0x00ff; else check1--; } check0 -= buffer[i]; } } if (check0 > 0xff || check1 > 0xff) { /* they shouldn't be able to do this. error! */ faimdprintf(sess, 2, "check0 or check1 is too high: 0x%04x, 0x%04x\n", check0, check1); return -1; } /* grab just the lowest byte; this should be clean, but just in case */ check0 &= 0xff; check1 &= 0xff; *checksum = ((check0 * 0x1000000) + (check1 * 0x10000)); return *checksum;#endif} #if 0/** * aim_oft_buildheader - fills a buffer with network-order fh data * @dest: buffer to fill -- pre-alloced * @fh: fh to get data from * * returns length written; -1 on error. * DOES NOT DO BOUNDS CHECKING! * */static int oft_buildheader(unsigned char *dest, struct aim_fileheader_t *fh) { int i, curbyte; if (!dest || !fh) return -1; curbyte = 0; for(i = 0; i < 8; i++) curbyte += aimutil_put8(dest+curbyte, fh->bcookie[i]); curbyte += aimutil_put16(dest+curbyte, fh->encrypt); curbyte += aimutil_put16(dest+curbyte, fh->compress); curbyte += aimutil_put16(dest+curbyte, fh->totfiles); curbyte += aimutil_put16(dest+curbyte, fh->filesleft); curbyte += aimutil_put16(dest+curbyte, fh->totparts); curbyte += aimutil_put16(dest+curbyte, fh->partsleft); curbyte += aimutil_put32(dest+curbyte, fh->totsize); curbyte += aimutil_put32(dest+curbyte, fh->size); curbyte += aimutil_put32(dest+curbyte, fh->modtime); curbyte += aimutil_put32(dest+curbyte, fh->checksum); curbyte += aimutil_put32(dest+curbyte, fh->rfrcsum); curbyte += aimutil_put32(dest+curbyte, fh->rfsize); curbyte += aimutil_put32(dest+curbyte, fh->cretime); curbyte += aimutil_put32(dest+curbyte, fh->rfcsum); curbyte += aimutil_put32(dest+curbyte, fh->nrecvd); curbyte += aimutil_put32(dest+curbyte, fh->recvcsum); memcpy(dest+curbyte, fh->idstring, 32); curbyte += 32; curbyte += aimutil_put8(dest+curbyte, fh->flags); curbyte += aimutil_put8(dest+curbyte, fh->lnameoffset); curbyte += aimutil_put8(dest+curbyte, fh->lsizeoffset); memcpy(dest+curbyte, fh->dummy, 69); curbyte += 69; memcpy(dest+curbyte, fh->macfileinfo, 16); curbyte += 16; curbyte += aimutil_put16(dest+curbyte, fh->nencode); curbyte += aimutil_put16(dest+curbyte, fh->nlanguage); memset(dest+curbyte, 0x00, 64); memcpy(dest+curbyte, fh->name, 64); /* XXX: Filenames longer than 64B */ curbyte += 64; return curbyte;}#endif/** * aim_getfile_intitiate - Request an OFT getfile session * @sess: your session, * @conn: the BOS conn, * @destsn is the SN to connect to. * * returns a new &aim_conn_t on success, %NULL on error */faim_export aim_conn_t *aim_getfile_initiate(aim_session_t *sess, aim_conn_t *conn, const char *destsn){ return NULL;#if 0 struct command_tx_struct *newpacket; struct aim_conn_t *newconn; struct aim_filetransfer_priv *priv; struct aim_msgcookie_t *cookie; int curbyte, i, listenfd; short port = 4443; struct hostent *hptr; struct utsname myname; char cap[16]; char d[4]; /* Open our socket */ if ( (listenfd = aim_listenestablish(port)) == -1) return NULL; /* get our local IP */ if (uname(&myname) < 0) return NULL; if ( (hptr = gethostbyname(myname.nodename)) == NULL) return NULL; memcpy(&d, hptr->h_addr_list[0], 4); aim_putcap(cap, 16, AIM_CAPS_GETFILE); /* create the OSCAR packet */ if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+8+2+1+strlen(destsn)+4+4+0x42))) return NULL; newpacket->lock = 1; /* lock struct */ curbyte = 0; curbyte += aim_putsnac(newpacket->data+curbyte, 0x0004, 0x0006, 0x0000, sess->snac_nextid); /* XXX: check the cookie before commiting to using it */ /* Generate a random message cookie * This cookie needs to be alphanumeric and NULL-terminated to be TOC-compatible. */ for (i=0; i<7; i++) curbyte += aimutil_put8(newpacket->data+curbyte, 0x30 + ((u_char) random() % 10)); curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); /* grab all the data for cookie caching. */ if (!(cookie = (struct aim_msgcookie_t *)calloc(1, sizeof(struct aim_msgcookie_t)))) return NULL; memcpy(cookie->cookie, newpacket->data+curbyte-8, 8); cookie->type = AIM_COOKIETYPE_OFTGET; if (!(priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)))) return NULL; memcpy(priv->cookie, cookie, 8); memcpy(priv->sn, destsn, sizeof(priv->sn)); memcpy(priv->fh.name, "listing.txt", strlen("listing.txt")); priv->state = 1; cookie->data = priv; aim_cachecookie(sess, cookie); /* Channel ID */ curbyte += aimutil_put16(newpacket->data+curbyte,0x0002); /* Destination SN (prepended with byte length) */ curbyte += aimutil_put8(newpacket->data+curbyte,strlen(destsn)); curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn)); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); /* enTLV start */ curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0042); /* Flag data / ICBM Parameters? */ curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); /* Cookie */ curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cookie, 8); /* Capability String */ curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cap, 0x10); /* 000a/0002 : 0001 */ curbyte += aimutil_put16(newpacket->data+curbyte, 0x000a); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001); /* 0003/0004: IP address */ curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0004); for(i = 0; i < 4; i++) curbyte += aimutil_put8(newpacket->data+curbyte, d[i]); /* already in network byte order */ /* 0005/0002: Port */ curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); curbyte += aimutil_put16(newpacket->data+curbyte, port); /* 000f/0000: ?? */ curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); /* 2711/000c: ?? */ curbyte += aimutil_put16(newpacket->data+curbyte, 0x2711); curbyte += aimutil_put16(newpacket->data+curbyte, 0x000c); curbyte += aimutil_put32(newpacket->data+curbyte, 0x00120001); for(i = 0; i < 0x000c - 4; i++) curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); newpacket->commandlen = curbyte; newpacket->lock = 0; aim_tx_enqueue(sess, newpacket); /* allocate and set up our connection */ i = fcntl(listenfd, F_GETFL, 0); fcntl(listenfd, F_SETFL, i | O_NONBLOCK); newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL); if (!newconn){ perror("aim_newconn"); return NULL; } newconn->fd = listenfd; newconn->subtype = AIM_CONN_SUBTYPE_OFT_GETFILE; newconn->priv = priv; faimdprintf(sess, 2,"faim: listening (fd = %d, unconnected)\n", newconn->fd); return newconn;#endif} /** * aim_oft_getfile_request - request a particular file over an established getfile connection * @sess: your session * @conn: the established OFT getfile connection * @name: filename to request * @size: size of the file * * * returns -1 on error, 0 on successful enqueuing */faim_export int aim_oft_getfile_request(aim_session_t *sess, aim_conn_t *conn, const char *name, int size){ return -EINVAL;#if 0 struct command_tx_struct *newoft; struct aim_filetransfer_priv *ft; if (!sess || !conn || !conn->priv || !name) return -1; if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x120c, 0))) { faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); return -1; } newoft->lock = 1; memcpy(newoft->hdr.oft.magic, "OFT2", 4); newoft->hdr.oft.hdr2len = 0x100 - 8; ft = (struct aim_filetransfer_priv *)conn->priv; ft->fh.filesleft = 1; ft->fh.totfiles = 1; ft->fh.totparts = 1; ft->fh.partsleft = 1; ft->fh.totsize = size; ft->fh.size = size; ft->fh.checksum = 0; memcpy(ft->fh.name, name, strlen(name)); memset(ft->fh.name+strlen(name), 0, 1); if (!(newoft->hdr.oft.hdr2 = (unsigned char *)calloc(1,newoft->hdr.oft.hdr2len))) { newoft->lock = 0; aim_frame_destroy(newoft); return -1; } if (!(aim_oft_buildheader(newoft->hdr.oft.hdr2, &(ft->fh)))) { newoft->lock = 0; aim_frame_destroy(newoft); return -1; } newoft->lock = 0; aim_tx_enqueue(sess, newoft); return 0;#endif} /** * aim_oft_getfile_ack - acknowledge a getfile download as complete * @sess: your session * @conn: the getfile conn to send the ack over * * Call this function after you have read all the data in a particular * filetransfer. Returns -1 on error, 0 on apparent success * */faim_export int aim_oft_getfile_ack(aim_session_t *sess, aim_conn_t *conn) { return -EINVAL;#if 0 struct command_tx_struct *newoft; struct aim_filetransfer_priv *ft; if (!sess || !conn || !conn->priv) return -1; if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0202, 0))) { faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); return -1; } newoft->lock = 1; memcpy(newoft->hdr.oft.magic, "OFT2", 4); newoft->hdr.oft.hdr2len = 0x100-8; if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { newoft->lock = 0; aim_frame_destroy(newoft); return -1; } ft = (struct aim_filetransfer_priv *)conn->priv; if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)))) { newoft->lock = 0; aim_frame_destroy(newoft); return -1; } newoft->lock = 0; aim_tx_enqueue(sess, newoft); return 0;#endif} /** * aim_oft_getfile_end - end a getfile. * @sess: your session * @conn: the getfile connection * * call this before you close the getfile connection if you're on the * receiving/requesting end. */faim_export int aim_oft_getfile_end(aim_session_t *sess, aim_conn_t *conn){ return -EINVAL;#if 0 struct command_tx_struct *newoft; struct aim_filetransfer_priv *ft; if (!sess || !conn || !conn->priv) return -1; if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0204, 0))) { faimdprintf(sess, 2, "faim: aim_accepttransfer: tx_new OFT failed\n"); return -1; } newoft->lock = 1; memcpy(newoft->hdr.oft.magic, "OFT2", 4); newoft->hdr.oft.hdr2len = 0x100 - 8; if (!(newoft->hdr.oft.hdr2 = (char *)calloc(1,newoft->hdr.oft.hdr2len))) { newoft->lock = 0; aim_frame_destroy(newoft); return -1; } ft = (struct aim_filetransfer_priv *)conn->priv; ft->state = 4; /* no longer wanting data */ ft->fh.nrecvd = ft->fh.size; ft->fh.recvcsum = ft->fh.checksum; ft->fh.flags = 0x21; if (!(aim_oft_buildheader((unsigned char *)newoft->hdr.oft.hdr2, &(ft->fh)))) { newoft->lock = 0; aim_frame_destroy(newoft); return -1; } newoft->lock = 0; aim_tx_enqueue(sess, newoft); return 0;#endif /* 0 */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -