comparison src/protocols/oscar/ft.c @ 3752:b32474e522fa

[gaim-migrate @ 3890] From: "William T. Mahan" <wtm2@duke.edu> This patch, against CVS HEAD, fixes three bugs in Oscar File Transfer support. I can split it up further if desired. * Send a null checksum when initiating a file transfer, which fixes "files don't match" warnings produced by some versions of WinAIM; add a compile-time option to actually compute the checksum, which is slow but necessary when sending to some Mac clients. * Don't allow sending files to oneself, because it causes all kinds of subtle problems and it's not useful. * Don't crash when there is an error writing to the output file when receiving. From: "William T. Mahan" <wtm2@duke.edu> This patch 2 of 3, which applies on top of the first, adds support for reverse connections for Oscar File Transfer, the lack of which has been the biggest complaint so far. Reverse connections are used by newer AIM clients when there is difficulty verifying the IP of the sender. From: "William T. Mahan" <wtm2@duke.edu> This patch 3 of 3, which applies on top of the first 2, removes the alarm() and sigaction() calls that were added by my original FT patch to detect transfer timeouts. Besides apparently not working on Windows, they involved a lot of ugly code to handle a special case. My new approach is to add destructors that can called when SNACs are freed; a timeout is detected when a request SNAC is cleaned up before the transfer is accepted. Although this touches several files, it is more generic than the old method. I tried to implement this in an unintrusive manner, so that there is little preformance penalty for SNACs that do not use destructors. My first two patches should work fine without this. If there are any objections to the third patch, I ask that the first two patches be applied, in which case I will set up a SourceForge page for this one. committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Sat, 19 Oct 2002 05:22:30 +0000
parents 988485669631
children 765769211688
comparison
equal deleted inserted replaced
3751:e25577506dec 3752:b32474e522fa
1620 return -1; 1620 return -1;
1621 } 1621 }
1622 1622
1623 faimdprintf(sess, 2, "faim: get_rend: looks like we're done with a transfer (oft 0x0204)\n"); 1623 faimdprintf(sess, 2, "faim: get_rend: looks like we're done with a transfer (oft 0x0204)\n");
1624 1624
1625 debug_printf("wtm: they sent csum %x\n", fh->recvcsum); 1625 debug_printf("sendfile: receiver sent checksum %x\n", fh->recvcsum);
1626 1626
1627 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE)) ) 1627 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE)) )
1628 userfunc(sess, NULL, conn, fh->bcookie); 1628 userfunc(sess, NULL, conn, fh->bcookie);
1629 1629
1630 free(fh); 1630 free(fh);
2149 struct aim_fileheader_t *fh; 2149 struct aim_fileheader_t *fh;
2150 2150
2151 if (!sess || !conn || !name) 2151 if (!sess || !conn || !name)
2152 return -1; 2152 return -1;
2153 2153
2154 /* Authenticate whomever connected to our listener by checking
2155 * that the correct cookie was proivided. */
2156 if (!(cook = aim_checkcookie(sess, ft->cookie,
2157 AIM_COOKIETYPE_OFTSEND))) {
2158 return -1;
2159 }
2160
2161 if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t)))) 2154 if (!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t))))
2162 return -1; 2155 return -1;
2156
2157 #ifdef DUMB_OFT_CHECKSUM
2158 /* Yes, we are supposed to checksum the whole file before sending, and
2159 * yes, it's dumb. This is the only way to get some clients (such as
2160 * Mac AIM v4.5.163) to successfully complete the transfer. With
2161 * the WinAIM clients, we seem to be able to get away with just
2162 * setting the checksum to zero.
2163 * -- wtm
2164 */
2165 {
2166 int fd = open(name, O_RDONLY);
2167 if (fd >= 0) {
2168 int bytes;
2169 char buf[1024];
2170 fh->checksum = 0xffff0000;
2171 while ((bytes = read(fd, buf, 1024)) > 0) {
2172 fh->checksum = aim_oft_checksum(buf, bytes, fh->checksum);
2173 }
2174 }
2175 close(fd);
2176 }
2177 #else
2178 fh->checksum = 0x00000000;
2179 #endif
2163 2180
2164 fh->encrypt = 0x0000; 2181 fh->encrypt = 0x0000;
2165 fh->compress = 0x0000; 2182 fh->compress = 0x0000;
2166 fh->totfiles = numfiles; 2183 fh->totfiles = numfiles;
2167 fh->filesleft = numfiles - filesdone; 2184 fh->filesleft = numfiles - filesdone;
2168 fh->totparts = 0x0001; 2185 fh->totparts = 0x0001;
2169 fh->partsleft = 0x0001; 2186 fh->partsleft = 0x0001;
2170 fh->totsize = totsize; 2187 fh->totsize = totsize;
2171 fh->size = size; 2188 fh->size = size;
2172 fh->modtime = (int)time(NULL); /* we'll go with current time for now */ 2189 fh->modtime = (int)time(NULL); /* we'll go with current time for now */
2173 fh->checksum = 0xffffffff; /* XXX: checksum ! */ 2190 /* fh->checksum set above */
2174 fh->rfcsum = 0x00000000; 2191 fh->rfcsum = 0x00000000;
2175 fh->rfsize = 0x00000000; 2192 fh->rfsize = 0x00000000;
2176 fh->cretime = 0x00000000; 2193 fh->cretime = 0x00000000;
2177 fh->rfcsum = 0x00000000; 2194 fh->rfcsum = 0x00000000;
2178 fh->nrecvd = 0x00000000; /* always zero initially */ 2195 fh->nrecvd = 0x00000000; /* always zero initially */
2196 char *basename = g_path_get_basename(name); 2213 char *basename = g_path_get_basename(name);
2197 strncpy(fh->name, basename, sizeof(fh->name)); 2214 strncpy(fh->name, basename, sizeof(fh->name));
2198 g_free(basename); 2215 g_free(basename);
2199 } 2216 }
2200 2217
2201 memcpy(fh->bcookie, cook->cookie, 8); 2218 /* XXX we should normally send a null cookie here, and make
2219 * the receiver fill it in for authentication -- wtm
2220 */
2221 memcpy(fh->bcookie, ft->cookie, 8);
2222
2223 if (!(cook = aim_checkcookie(sess, ft->cookie, AIM_COOKIETYPE_OFTSEND))) {
2224 return -1;
2225 }
2226
2202 /* Update both headers to be safe. */ 2227 /* Update both headers to be safe. */
2203 memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t)); 2228 memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t));
2204 memcpy(&(((struct aim_filetransfer_priv *)cook->data)->fh), fh, 2229 memcpy(&(((struct aim_filetransfer_priv *)cook->data)->fh), fh,
2205 sizeof(struct aim_fileheader_t)); 2230 sizeof(struct aim_fileheader_t));
2206 2231