Mercurial > pidgin
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 |