transfer.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  1. /*
  2. * Copyright (C) 1997 Robey Pointer
  3. * Copyright (C) 1999 - 2002 Eggheads Development Team
  4. * Copyright (C) 2002 - 2014 Bryan Drewery
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. /*
  21. * transfer.c -- part of transfer.mod
  22. *
  23. */
  24. /*
  25. * Small code snippets related to REGET/RESEND support were taken from
  26. * BitchX, copyright by panasync.
  27. */
  28. #include "src/common.h"
  29. #include "src/cmds.h"
  30. #include "src/misc_file.h"
  31. #include "src/misc.h"
  32. #include "src/main.h"
  33. #include "src/userrec.h"
  34. #include "src/userent.h"
  35. #include "src/tandem.h"
  36. #include "src/net.h"
  37. #include "src/users.h"
  38. #define MAKING_TRANSFER
  39. #include "transfer.h"
  40. #include "src/mod/share.mod/share.h"
  41. #include "src/mod/update.mod/update.h"
  42. #include "src/chanprog.h"
  43. #include <bdlib/src/String.h>
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #include <netinet/in.h>
  47. #include <arpa/inet.h>
  48. #include <errno.h>
  49. extern int bupdating;
  50. static interval_t wait_dcc_xfer = 40; /* Timeout time on DCC xfers */
  51. static int dcc_limit = 4; /* Maximum number of simultaneous file
  52. downloads allowed */
  53. static unsigned int dcc_block = 0; /* Size of one dcc block */
  54. /*
  55. * Prototypes
  56. */
  57. static void dcc_get_pending(int, char *, int);
  58. /*
  59. * Misc functions
  60. */
  61. /*
  62. * DCC routines
  63. */
  64. /* Instead of reading all data intended to go into the DCC block
  65. * in one go, we read it in PMAX_SIZE chunks, feed it to tputs and
  66. * continue until we get to know that the network buffer only
  67. * buffers the data instead of sending it.
  68. *
  69. * In that case, we delay further sending until we receive the
  70. * dcc outdone event.
  71. *
  72. * Note: To optimize buffer sizes, we default to PMAX_SIZE, but
  73. * allocate a smaller buffer for smaller pending_data sizes.
  74. */
  75. #define PMAX_SIZE 4096
  76. static unsigned long pump_file_to_sock(FILE *file, long sock,
  77. unsigned long pending_data)
  78. {
  79. const unsigned long buf_len = pending_data >= PMAX_SIZE ?
  80. PMAX_SIZE : pending_data;
  81. char *bf = (char *) calloc(1, buf_len);
  82. unsigned long actual_size;
  83. if (bf) {
  84. do {
  85. actual_size = pending_data >= buf_len ? buf_len : pending_data;
  86. if (fread(bf, actual_size, 1, file)) {
  87. tputs(sock, bf, actual_size);
  88. pending_data -= actual_size;
  89. }
  90. } while (!sock_has_data(SOCK_DATA_OUTGOING, sock) && pending_data != 0);
  91. free(bf);
  92. }
  93. return pending_data;
  94. }
  95. static void eof_dcc_fork_send(int idx)
  96. {
  97. fclose(dcc[idx].u.xfer->f);
  98. if (!strcmp(dcc[idx].nick, "*users")) {
  99. int x, y = -1;
  100. for (x = 0; x < dcc_total; x++)
  101. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  102. y = x;
  103. break;
  104. }
  105. if (y >= 0) {
  106. dcc[y].status &= ~STAT_GETTING;
  107. dcc[y].status &= ~STAT_SHARE;
  108. }
  109. putlog(LOG_BOTS, "*", "Failed connection; aborted userfile transfer.");
  110. unlink(dcc[idx].u.xfer->filename);
  111. } else if (!strcmp(dcc[idx].nick, "*binary")) {
  112. int x, y = -1;
  113. for (x = 0; x < dcc_total; x++)
  114. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  115. y = x;
  116. break;
  117. }
  118. if (y >= 0) {
  119. dcc[y].status &= ~STAT_GETTINGU;
  120. }
  121. putlog(LOG_BOTS, "*", "Failed binary transfer.");
  122. unlink(dcc[idx].u.xfer->filename);
  123. }
  124. killsock(dcc[idx].sock);
  125. lostdcc(idx);
  126. }
  127. static void eof_dcc_send(int idx)
  128. {
  129. char s[1024] = "";
  130. fflush(dcc[idx].u.xfer->f);
  131. fsync(fileno(dcc[idx].u.xfer->f));
  132. fclose(dcc[idx].u.xfer->f);
  133. if (dcc[idx].u.xfer->length == dcc[idx].status) {
  134. if (!strcmp(dcc[idx].nick, "*users")) {
  135. finish_share(idx);
  136. killsock(dcc[idx].sock);
  137. lostdcc(idx);
  138. return;
  139. } else if (!strcmp(dcc[idx].nick, "*binary")) {
  140. finish_update(idx);
  141. killsock(dcc[idx].sock);
  142. lostdcc(idx);
  143. return;
  144. }
  145. }
  146. /* Failure :( */
  147. if (!strcmp(dcc[idx].nick, "*users")) {
  148. int x, y = -1;
  149. for (x = 0; x < dcc_total; x++) {
  150. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  151. y = x;
  152. break;
  153. }
  154. }
  155. if (y >= 0) {
  156. putlog(LOG_BOTS, "*", "Lost userfile transfer from %s; aborting.", dcc[y].nick);
  157. unlink(dcc[idx].u.xfer->filename);
  158. /* Drop that bot */
  159. dprintf(y, "bye\n");
  160. simple_snprintf(s, sizeof s, "Disconnected %s (aborted userfile transfer)", dcc[y].nick);
  161. botnet_send_unlinked(y, dcc[y].nick, s);
  162. chatout("*** %s %s\n", dcc[y].nick, s);
  163. if (y < idx) {
  164. int t = y;
  165. y = idx;
  166. idx = t;
  167. }
  168. if (y != idx) {
  169. killsock(dcc[y].sock);
  170. lostdcc(y);
  171. }
  172. killsock(dcc[idx].sock);
  173. lostdcc(idx);
  174. }
  175. } else if (!strcmp(dcc[idx].nick, "*binary")) {
  176. int x, y = -1;
  177. for (x = 0; x < dcc_total; x++)
  178. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  179. y = x;
  180. break;
  181. }
  182. if (y >= 0) {
  183. putlog(LOG_BOTS, "*", "Lost binary transfer from %s; aborting.", dcc[y].nick);
  184. unlink(dcc[idx].u.xfer->filename);
  185. /* Drop that bot
  186. dprintf(y, "bye\n");
  187. simple_snprintf(s, sizeof s,"Disconnected %s (aborted binary transfer)", dcc[y].nick);
  188. botnet_send_unlinked(y, dcc[y].nick, s);
  189. chatout("*** %s\n", dcc[y].nick, s);
  190. if (y != idx) {
  191. killsock(dcc[y].sock);
  192. lostdcc(y);
  193. }
  194. */
  195. killsock(dcc[idx].sock);
  196. lostdcc(idx);
  197. }
  198. }
  199. }
  200. /* Determine byte order. Used for resend DCC startup packets.
  201. */
  202. static inline uint8_t byte_order_test(void)
  203. {
  204. uint16_t test = TRANSFER_REGET_PACKETID;
  205. if (*((uint8_t *)&test) == ((TRANSFER_REGET_PACKETID & 0xff00) >> 8))
  206. return 0;
  207. if (*((uint8_t *)&test) == (TRANSFER_REGET_PACKETID & 0x00ff))
  208. return 1;
  209. return 0;
  210. }
  211. /* Parse and handle resend DCC startup packets.
  212. */
  213. inline static void handle_resend_packet(int idx, transfer_reget *reget_data)
  214. {
  215. if (byte_order_test() != reget_data->byte_order) {
  216. /* The sender's byte order does not match our's so we need to switch the
  217. * bytes first, before we can make use of them.
  218. */
  219. reget_data->packet_id = ((reget_data->packet_id & 0x00ff) << 8) |
  220. ((reget_data->packet_id & 0xff00) >> 8);
  221. reget_data->byte_offset = ((reget_data->byte_offset & 0xff000000) >> 24) |
  222. ((reget_data->byte_offset & 0x00ff0000) >> 8) |
  223. ((reget_data->byte_offset & 0x0000ff00) << 8) |
  224. ((reget_data->byte_offset & 0x000000ff) << 24);
  225. }
  226. if (reget_data->packet_id != TRANSFER_REGET_PACKETID)
  227. putlog(LOG_FILES, "*", "(!) reget packet from %s for %s is invalid!",
  228. dcc[idx].nick, dcc[idx].u.xfer->origname);
  229. else
  230. dcc[idx].u.xfer->offset = reget_data->byte_offset;
  231. dcc[idx].u.xfer->type = XFER_RESEND;
  232. }
  233. /* Handles DCC packets the client sends us. As soon as the last sent dcc
  234. * block is fully acknowledged we send the next block.
  235. *
  236. * Note: The first received packet during reget is a special 8 bit packet
  237. * containing special information.
  238. */
  239. static void dcc_get(int idx, char *buf, int len)
  240. {
  241. unsigned char bbuf[4] = "";
  242. unsigned long cmp, l;
  243. int w = len + dcc[idx].u.xfer->sofar, p = 0;
  244. dcc[idx].timeval = now; /* Mark as active */
  245. /* Add bytes to our buffer if we don't have a complete response yet.
  246. * This is either a 4 bit ack or the 8 bit reget packet.
  247. */
  248. if (w < 4 ||
  249. (w < 8 && dcc[idx].u.xfer->type == XFER_RESEND_PEND)) {
  250. memcpy(&(dcc[idx].u.xfer->buf[dcc[idx].u.xfer->sofar]), buf, len);
  251. dcc[idx].u.xfer->sofar += len;
  252. return;
  253. /* Waiting for the 8 bit reget packet? */
  254. } else if (dcc[idx].u.xfer->type == XFER_RESEND_PEND) {
  255. /* The 8 bit packet is complete now. Parse it. */
  256. if (w == 8) {
  257. transfer_reget reget_data;
  258. memcpy(&reget_data, dcc[idx].u.xfer->buf, dcc[idx].u.xfer->sofar);
  259. memcpy(&reget_data + dcc[idx].u.xfer->sofar, buf, len);
  260. handle_resend_packet(idx, &reget_data);
  261. cmp = dcc[idx].u.xfer->offset;
  262. } else
  263. return;
  264. /* Fall through! */
  265. /* No, only want 4 bit ack responses. */
  266. } else {
  267. /* Complete packet? */
  268. if (w == 4) {
  269. memcpy(bbuf, dcc[idx].u.xfer->buf, dcc[idx].u.xfer->sofar);
  270. memcpy(&(bbuf[dcc[idx].u.xfer->sofar]), buf, len);
  271. } else {
  272. p = ((w - 1) & ~3) - dcc[idx].u.xfer->sofar;
  273. w = w - ((w - 1) & ~3);
  274. if (w < 4) {
  275. memcpy(dcc[idx].u.xfer->buf, &(buf[p]), w);
  276. return;
  277. }
  278. memcpy(bbuf, &(buf[p]), w);
  279. }
  280. /* This is more compatible than ntohl for machines where an int
  281. * is more than 4 bytes:
  282. */
  283. cmp = ((unsigned int) (bbuf[0]) << 24) +
  284. ((unsigned int) (bbuf[1]) << 16) +
  285. ((unsigned int) (bbuf[2]) << 8) + bbuf[3];
  286. dcc[idx].u.xfer->acked = cmp;
  287. }
  288. dcc[idx].u.xfer->sofar = 0;
  289. if (cmp > dcc[idx].u.xfer->length && cmp > dcc[idx].status) {
  290. /* Attempt to resume, but file is not as long as requested... */
  291. putlog(LOG_FILES, "*",
  292. "!! Resuming file transfer behind file end for %s to %s",
  293. dcc[idx].u.xfer->origname, dcc[idx].nick);
  294. } else if (cmp > dcc[idx].status) {
  295. /* Attempt to resume */
  296. if (!strcmp(dcc[idx].nick, "*users")) {
  297. putlog(LOG_BOTS, "*", "!!! Trying to skip ahead on userfile transfer");
  298. } else if (!strcmp(dcc[idx].nick, "*binary")) {
  299. putlog(LOG_BOTS, "*","!!! Trying to skip ahead on binary transfer");
  300. }
  301. } else {
  302. if (dcc[idx].u.xfer->ack_type == XFER_ACK_UNKNOWN) {
  303. if (cmp < dcc[idx].u.xfer->offset)
  304. /* If we don't start at the top of the file, some clients only tell
  305. * us the really received bytes (e.g. bitchx). This seems to be the
  306. * case here.
  307. */
  308. dcc[idx].u.xfer->ack_type = XFER_ACK_WITHOUT_OFFSET;
  309. else
  310. dcc[idx].u.xfer->ack_type = XFER_ACK_WITH_OFFSET;
  311. }
  312. if (dcc[idx].u.xfer->ack_type == XFER_ACK_WITHOUT_OFFSET)
  313. cmp += dcc[idx].u.xfer->offset;
  314. }
  315. if (cmp != dcc[idx].status)
  316. return;
  317. if (dcc[idx].status == dcc[idx].u.xfer->length) {
  318. /* Successful send, we are done */
  319. killsock(dcc[idx].sock);
  320. fclose(dcc[idx].u.xfer->f);
  321. if (!strcmp(dcc[idx].nick, "*users")) {
  322. int x, y = -1;
  323. for (x = 0; x < dcc_total; x++)
  324. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  325. y = x;
  326. break;
  327. }
  328. if (y >= 0)
  329. dcc[y].status &= ~STAT_SENDING;
  330. putlog(LOG_BOTS, "*", "Completed userfile transfer to %s.", dcc[y].nick);
  331. unlink(dcc[idx].u.xfer->filename);
  332. /* Any sharebot things that were queued: */
  333. dump_resync(y);
  334. } else if (!strcmp(dcc[idx].nick, "*binary")) {
  335. int x, y = -1;
  336. for (x = 0; x < dcc_total; x++)
  337. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  338. y = x;
  339. break;
  340. }
  341. if (y >= 0) {
  342. dcc[y].status &= ~STAT_SENDINGU;
  343. dcc[y].status |= STAT_UPDATED;
  344. }
  345. putlog(LOG_BOTS, "*", "Completed binary file send to %s", dcc[y].nick);
  346. bupdating = 0;
  347. }
  348. lostdcc(idx);
  349. return;
  350. }
  351. /* Note: No fseek() needed here, because the file position is kept from
  352. * the last run.
  353. */
  354. l = dcc_block;
  355. if (l == 0 || dcc[idx].status + l > dcc[idx].u.xfer->length)
  356. l = dcc[idx].u.xfer->length - dcc[idx].status;
  357. dcc[idx].u.xfer->block_pending = pump_file_to_sock(dcc[idx].u.xfer->f, dcc[idx].sock, l);
  358. dcc[idx].status += l;
  359. }
  360. static void eof_dcc_get(int idx)
  361. {
  362. char s[1024] = "";
  363. fclose(dcc[idx].u.xfer->f);
  364. if (!strcmp(dcc[idx].nick, "*users")) {
  365. int x, y = -1;
  366. for (x = 0; x < dcc_total; x++)
  367. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  368. y = x;
  369. break;
  370. }
  371. putlog(LOG_BOTS, "*", "Lost userfile transfer; aborting.");
  372. /* Note: no need to unlink the xfer file, as it's already unlinked. */
  373. /* Drop that bot */
  374. dprintf(-dcc[y].sock, "bye\n");
  375. simple_snprintf(s, sizeof s, "Disconnected %s (aborted userfile transfer)",
  376. dcc[y].nick);
  377. botnet_send_unlinked(y, dcc[y].nick, s);
  378. chatout("*** %s\n", s);
  379. if (y != idx) {
  380. killsock(dcc[y].sock);
  381. lostdcc(y);
  382. }
  383. if (dcc[idx].sock != -1)
  384. killsock(dcc[idx].sock);
  385. lostdcc(idx);
  386. return;
  387. } else if (!strcmp(dcc[idx].nick, "*binary")) {
  388. int x, y = -1;
  389. for (x = 0; x < dcc_total; x++)
  390. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  391. y = x;
  392. break;
  393. }
  394. putlog(LOG_BOTS, "*", "Lost binary transfer; aborting.");
  395. /* Note: no need to unlink the xfer file, as it's already unlinked. */
  396. /* Drop that bot */
  397. dcc[y].status &= ~STAT_SENDINGU;
  398. bupdating = 0;
  399. /*
  400. dprintf(-dcc[y].sock, "bye\n");
  401. simple_snprintf(s, sizeof s, "Disconnected %s (aborted binary transfer)",
  402. dcc[y].nick);
  403. botnet_send_unlinked(y, dcc[y].nick, s);
  404. chatout("*** %s\n", s);
  405. if (y != idx) {
  406. killsock(dcc[y].sock);
  407. lostdcc(y);
  408. }
  409. */
  410. killsock(dcc[idx].sock);
  411. lostdcc(idx);
  412. return;
  413. }
  414. killsock(dcc[idx].sock);
  415. lostdcc(idx);
  416. }
  417. static void dcc_send(int idx, char *buf, int len)
  418. {
  419. char s[SGRAB + 2] = "", *b = NULL;
  420. size_t siz = 0;
  421. unsigned long sent;
  422. if (!fwrite(buf, len, 1, dcc[idx].u.xfer->f)) {
  423. putlog(LOG_FILES, "*", "Problem writing file");
  424. fclose(dcc[idx].u.xfer->f);
  425. siz = strlen(tempdir) + strlen(dcc[idx].u.xfer->filename) + 1;
  426. b = (char *) calloc(1, siz);
  427. strlcpy(b, tempdir, siz);
  428. strlcat(b, dcc[idx].u.xfer->filename, siz);
  429. unlink(b);
  430. free(b);
  431. killsock(dcc[idx].sock);
  432. lostdcc(idx);
  433. return;
  434. }
  435. fflush(dcc[idx].u.xfer->f);
  436. fsync(fileno(dcc[idx].u.xfer->f));
  437. dcc[idx].status += len;
  438. /* Put in network byte order */
  439. sent = dcc[idx].status;
  440. s[0] = (sent / (1 << 24));
  441. s[1] = (sent % (1 << 24)) / (1 << 16);
  442. s[2] = (sent % (1 << 16)) / (1 << 8);
  443. s[3] = (sent % (1 << 8));
  444. tputs(dcc[idx].sock, s, 4);
  445. dcc[idx].timeval = now;
  446. if (dcc[idx].status > dcc[idx].u.xfer->length &&
  447. dcc[idx].u.xfer->length > 0) {
  448. notice(dcc[idx].nick, "Bogus file length.", DP_HELP);
  449. putlog(LOG_FILES, "*",
  450. "File too long: dropping dcc send %s from %s!%s",
  451. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
  452. fclose(dcc[idx].u.xfer->f);
  453. siz = strlen(tempdir) + strlen(dcc[idx].u.xfer->filename) + 1;
  454. b = (char *) calloc(1, siz);
  455. strlcpy(b, tempdir, siz);
  456. strlcat(b, dcc[idx].u.xfer->filename, siz);
  457. unlink(b);
  458. free(b);
  459. killsock(dcc[idx].sock);
  460. lostdcc(idx);
  461. }
  462. }
  463. static void transfer_get_timeout(int i)
  464. {
  465. char xx[1024] = "";
  466. fclose(dcc[i].u.xfer->f);
  467. if (strcmp(dcc[i].nick, "*users") == 0) {
  468. int x, y = -1;
  469. for (x = 0; x < dcc_total; x++)
  470. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[i].host))) {
  471. y = x;
  472. break;
  473. }
  474. if (y >= 0) {
  475. dcc[y].status &= ~STAT_SENDING;
  476. dcc[y].status &= ~STAT_SHARE;
  477. }
  478. unlink(dcc[i].u.xfer->filename);
  479. putlog(LOG_BOTS, "*","Timeout on userfile transfer.");
  480. //Bot may have already disconnected, hence y = -1
  481. if (y != -1) {
  482. dprintf(y, "bye\n");
  483. simple_snprintf(xx, sizeof xx,"Disconnected %s (timed-out userfile transfer)", dcc[y].nick);
  484. botnet_send_unlinked(y, dcc[y].nick, xx);
  485. chatout("*** %s\n", xx);
  486. }
  487. if (y < i) {
  488. int t = y;
  489. y = i;
  490. i = t;
  491. }
  492. killsock(dcc[y].sock);
  493. lostdcc(y);
  494. xx[0] = 0;
  495. } else if (strcmp(dcc[i].nick, "*binary") == 0) {
  496. int x, y = -1;
  497. for (x = 0; x < dcc_total; x++)
  498. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[i].host))) {
  499. y = x;
  500. break;
  501. }
  502. if (y >= 0) {
  503. dcc[y].status &= ~STAT_SENDINGU;
  504. }
  505. putlog(LOG_BOTS, "*","Timeout on binary transfer.");
  506. if (y != -1) {
  507. dprintf(y, "bye\n");
  508. simple_snprintf(xx, sizeof xx,"Disconnected %s (timed-out binary transfer)", dcc[y].nick);
  509. botnet_send_unlinked(y, dcc[y].nick, xx);
  510. chatout("*** %s\n", xx);
  511. }
  512. if (y < i) {
  513. int t = y;
  514. y = i;
  515. i = t;
  516. }
  517. killsock(dcc[y].sock);
  518. lostdcc(y);
  519. xx[0] = 0;
  520. }
  521. if (i != -1) {
  522. killsock(dcc[i].sock);
  523. lostdcc(i);
  524. }
  525. }
  526. static void tout_dcc_send(int idx)
  527. {
  528. fclose(dcc[idx].u.xfer->f);
  529. if (!strcmp(dcc[idx].nick, "*users")) {
  530. int x, y = -1;
  531. for (x = 0; x < dcc_total; x++)
  532. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  533. y = x;
  534. break;
  535. }
  536. if (y >= 0) {
  537. dcc[y].status &= ~STAT_GETTING;
  538. dcc[y].status &= ~STAT_SHARE;
  539. }
  540. unlink(dcc[idx].u.xfer->filename);
  541. putlog(LOG_BOTS, "*", "Timeout on userfile transfer.");
  542. } else if (!strcmp(dcc[idx].nick, "*binary")) {
  543. int x, y = -1;
  544. for (x = 0; x < dcc_total; x++)
  545. if (dcc[x].type && (dcc[x].type->flags & DCT_BOT) && (!strcasecmp(dcc[x].nick, dcc[idx].host))) {
  546. y = x;
  547. break;
  548. }
  549. if (y >= 0) {
  550. dcc[y].status &= ~STAT_GETTINGU;
  551. }
  552. putlog(LOG_BOTS, "*", "Timeout on binary transfer.");
  553. }
  554. killsock(dcc[idx].sock);
  555. lostdcc(idx);
  556. }
  557. static void display_dcc_get(int idx, char *buf, size_t bufsiz)
  558. {
  559. if (dcc[idx].status == dcc[idx].u.xfer->length)
  560. simple_snprintf(buf, bufsiz, "send (%lu)/%lu\n Filename: %s\n", dcc[idx].u.xfer->acked,
  561. dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
  562. else
  563. simple_snprintf(buf, bufsiz, "send (%lu)/%lu\n Filename: %s\n", dcc[idx].status,
  564. dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
  565. }
  566. static void display_dcc_get_p(int idx, char *buf, size_t bufsiz)
  567. {
  568. simple_snprintf(buf, bufsiz, "send waited %ds\n Filename: %s\n", (int) (now - dcc[idx].timeval), dcc[idx].u.xfer->origname);
  569. }
  570. static void display_dcc_send(int idx, char *buf, size_t bufsiz)
  571. {
  572. simple_snprintf(buf, bufsiz, "send (%lu)/%lu\n Filename: %s\n", dcc[idx].status, dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
  573. }
  574. static void display_dcc_fork_send(int idx, char *buf, size_t bufsiz)
  575. {
  576. simple_snprintf(buf, bufsiz, "conn send");
  577. }
  578. static void kill_dcc_xfer(int idx, void *x)
  579. {
  580. struct xfer_info *p = (struct xfer_info *) x;
  581. if (p->filename)
  582. free(p->filename);
  583. /* We need to check if origname points to filename before
  584. * attempting to free the memory.
  585. */
  586. if (p->origname && p->origname != p->filename)
  587. free(p->origname);
  588. free(x);
  589. }
  590. static void
  591. out_dcc_xfer(int idx, char *buf, void *x)
  592. {
  593. }
  594. static void outdone_dcc_xfer(int idx)
  595. {
  596. if (dcc[idx].u.xfer->block_pending)
  597. dcc[idx].u.xfer->block_pending =
  598. pump_file_to_sock(dcc[idx].u.xfer->f, dcc[idx].sock,
  599. dcc[idx].u.xfer->block_pending);
  600. }
  601. struct dcc_table DCC_SEND =
  602. {
  603. "SEND",
  604. DCT_FILETRAN | DCT_FILESEND | DCT_VALIDIDX,
  605. eof_dcc_send,
  606. dcc_send,
  607. &wait_dcc_xfer,
  608. tout_dcc_send,
  609. display_dcc_send,
  610. kill_dcc_xfer,
  611. out_dcc_xfer,
  612. NULL
  613. };
  614. static void dcc_fork_send(int idx, char *x, int y);
  615. struct dcc_table DCC_FORK_SEND =
  616. {
  617. "FORK_SEND",
  618. DCT_FILETRAN | DCT_FORKTYPE | DCT_FILESEND | DCT_VALIDIDX,
  619. eof_dcc_fork_send,
  620. dcc_fork_send,
  621. &wait_dcc_xfer,
  622. eof_dcc_fork_send,
  623. display_dcc_fork_send,
  624. kill_dcc_xfer,
  625. out_dcc_xfer,
  626. NULL
  627. };
  628. static void dcc_fork_send(int idx, char *x, int y)
  629. {
  630. if (dcc[idx].type != &DCC_FORK_SEND)
  631. return;
  632. char s1[121] = "";
  633. dcc[idx].type = &DCC_SEND;
  634. dcc[idx].status = 0;
  635. dcc[idx].u.xfer->start_time = now;
  636. simple_snprintf(s1, sizeof s1, "%s!%s", dcc[idx].nick, dcc[idx].host);
  637. if (strcmp(dcc[idx].nick, "*users") && strcmp(dcc[idx].nick, "*binary"))
  638. putlog(LOG_MISC, "*", "DCC connection: SEND %s (%s)", dcc[idx].u.xfer->origname, s1);
  639. }
  640. struct dcc_table DCC_GET =
  641. {
  642. "GET",
  643. DCT_FILETRAN | DCT_VALIDIDX,
  644. eof_dcc_get,
  645. dcc_get,
  646. &wait_dcc_xfer,
  647. transfer_get_timeout,
  648. display_dcc_get,
  649. kill_dcc_xfer,
  650. out_dcc_xfer,
  651. outdone_dcc_xfer,
  652. };
  653. struct dcc_table DCC_GET_PENDING =
  654. {
  655. "GET_PENDING",
  656. DCT_FILETRAN | DCT_VALIDIDX,
  657. eof_dcc_get,
  658. dcc_get_pending,
  659. &wait_dcc_xfer,
  660. transfer_get_timeout,
  661. display_dcc_get_p,
  662. kill_dcc_xfer,
  663. out_dcc_xfer,
  664. NULL
  665. };
  666. static void dcc_get_pending(int idx, char *buf, int len)
  667. {
  668. in_addr_t ip;
  669. in_port_t port;
  670. int i;
  671. char s[UHOSTLEN] = "";
  672. i = answer(dcc[idx].sock, s, &ip, &port, 1);
  673. killsock(dcc[idx].sock);
  674. dcc[idx].sock = i;
  675. dcc[idx].addr = ip;
  676. dcc[idx].port = (int) port;
  677. if (dcc[idx].sock == -1) {
  678. bd::String msg;
  679. msg = bd::String::printf("Bad connection (%s)", strerror(errno));
  680. notice(dcc[idx].nick, msg, DP_HELP);
  681. putlog(LOG_FILES, "*", "DCC bad connection: GET %s (%s!%s)",
  682. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
  683. fclose(dcc[idx].u.xfer->f);
  684. lostdcc(idx);
  685. return;
  686. }
  687. dcc[idx].type = &DCC_GET;
  688. dcc[idx].u.xfer->ack_type = XFER_ACK_UNKNOWN;
  689. /*
  690. * Note: The file was already opened and dcc[idx].u.xfer->f may be
  691. * used immediately. Leave it opened until the file transfer
  692. * is complete.
  693. */
  694. /* Are we resuming? */
  695. if (dcc[idx].u.xfer->type == XFER_RESUME_PEND) {
  696. long unsigned int l;
  697. if (dcc_block == 0 || dcc[idx].u.xfer->length < dcc_block) {
  698. l = dcc[idx].u.xfer->length - dcc[idx].u.xfer->offset;
  699. dcc[idx].status = dcc[idx].u.xfer->length;
  700. } else {
  701. l = dcc_block;
  702. dcc[idx].status = dcc[idx].u.xfer->offset + dcc_block;
  703. }
  704. /* Seek forward ... */
  705. fseek(dcc[idx].u.xfer->f, dcc[idx].u.xfer->offset, SEEK_SET);
  706. dcc[idx].u.xfer->block_pending = pump_file_to_sock(dcc[idx].u.xfer->f,
  707. dcc[idx].sock, l);
  708. dcc[idx].u.xfer->type = XFER_RESUME;
  709. } else {
  710. dcc[idx].u.xfer->offset = 0;
  711. /* If we're resending the data, wait for the client's response first,
  712. * before sending anything ourself.
  713. */
  714. if (dcc[idx].u.xfer->type != XFER_RESEND_PEND) {
  715. if (dcc_block == 0 || dcc[idx].u.xfer->length < dcc_block)
  716. dcc[idx].status = dcc[idx].u.xfer->length;
  717. else
  718. dcc[idx].status = dcc_block;
  719. dcc[idx].u.xfer->block_pending = pump_file_to_sock(dcc[idx].u.xfer->f,
  720. dcc[idx].sock,
  721. dcc[idx].status);
  722. } else
  723. dcc[idx].status = 0;
  724. }
  725. dcc[idx].timeval = dcc[idx].u.xfer->start_time = now;
  726. }
  727. /* Starts a new DCC SEND or DCC RESEND connection to `nick', transferring
  728. * `filename' from `dir'.
  729. *
  730. * Use raw_dcc_resend() and raw_dcc_send() instead of this function.
  731. */
  732. static int raw_dcc_resend_send(const char *filename, const char *nick,
  733. const char *from, int resend, int *idx)
  734. {
  735. int zz = -1;
  736. int i;
  737. in_port_t port;
  738. char *buf = NULL;
  739. long dccfilesize;
  740. FILE *f = NULL, *dccfile = NULL;
  741. sdprintf("raw_dcc_resend_send()");
  742. dccfile = fopen(filename, "rb");
  743. if (!dccfile) {
  744. putlog(LOG_MISC, "*", "Failed to open %s: %s", filename, strerror(errno));
  745. return DCCSEND_FEMPTY;
  746. }
  747. fseek(dccfile, 0, SEEK_END);
  748. dccfilesize = ftell(dccfile);
  749. fclose(dccfile);
  750. /* File empty?! */
  751. if (dccfilesize == 0)
  752. return DCCSEND_FEMPTY;
  753. if (conf.portmin > 0 && conf.portmin < conf.portmax) {
  754. for (port = conf.portmin; port <= conf.portmax; port++)
  755. #ifdef USE_IPV6
  756. if ((zz = open_listen_by_af(&port, AF_INET)) != -1) /* no idea how we want to handle this -poptix 02/03/03 */
  757. #else
  758. if ((zz = open_listen(&port)) != -1)
  759. #endif /* USE_IPV6 */
  760. break;
  761. } else {
  762. port = conf.portmin;
  763. #ifdef USE_IPV6
  764. zz = open_listen_by_af(&port, AF_INET);
  765. #else
  766. zz = open_listen(&port);
  767. #endif /* USE_IPV6 */
  768. }
  769. if (zz == (-1))
  770. return DCCSEND_NOSOCK;
  771. if ((i = new_dcc(&DCC_GET_PENDING, sizeof(struct xfer_info))) == -1)
  772. return DCCSEND_FULL;
  773. f = fopen(filename, "rb");
  774. if (!f)
  775. return DCCSEND_BADFN;
  776. dcc[i].sock = zz;
  777. dcc[i].addr = (in_addr_t) (-559026163);
  778. dcc[i].port = port;
  779. strlcpy(dcc[i].nick, nick, sizeof(dcc[i].nick));
  780. strlcpy(dcc[i].host, "irc", sizeof(dcc[i].host));
  781. dcc[i].u.xfer->filename = strdup(filename);
  782. dcc[i].u.xfer->origname = strdup(filename);
  783. strlcpy(dcc[i].u.xfer->from, from, NICKLEN);
  784. dcc[i].u.xfer->length = dccfilesize;
  785. dcc[i].timeval = now;
  786. dcc[i].u.xfer->f = f;
  787. dcc[i].u.xfer->type = resend ? XFER_RESEND_PEND : XFER_SEND;
  788. if (buf)
  789. free(buf);
  790. if (idx)
  791. *idx = i;
  792. return DCCSEND_OK;
  793. }
  794. /* Starts a DCC RESEND connection.
  795. */
  796. /*
  797. static int raw_dcc_resend(char *filename, char *nick, char *from, char *dir)
  798. {
  799. return raw_dcc_resend_send(filename, nick, from, dir, 1);
  800. }
  801. */
  802. /* Starts a DCC_SEND connection.
  803. */
  804. int raw_dcc_send(const char *filename, const char *nick, const char *from, int *idx)
  805. {
  806. return raw_dcc_resend_send(filename, nick, from, 0, idx);
  807. }
  808. /*
  809. * Module functions
  810. */
  811. void transfer_report(int idx, int details)
  812. {
  813. if (details) {
  814. dprintf(idx," DCC block is %d%s, max concurrent d/ls is %d\n",
  815. dcc_block, (dcc_block == 0) ? " (turbo dcc)" : "", dcc_limit);
  816. }
  817. }
  818. /* vim: set sts=2 sw=2 ts=8 et: */