transfer.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819
  1. #define MODULE_NAME "transfer"
  2. #define MAKING_TRANSFER
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include "src/mod/module.h"
  6. #include "src/mod/update.mod/update.h"
  7. #include "src/tandem.h"
  8. #include "src/users.h"
  9. #include "transfer.h"
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. static Function *global = NULL, *update_funcs = NULL;
  13. static int copy_to_tmp = 1;
  14. static int wait_dcc_xfer = 40;
  15. static p_tcl_bind_list H_rcvd, H_sent, H_lost, H_tout;
  16. static int dcc_limit = 4;
  17. static int dcc_block = 0;
  18. static int quiet_reject = 1;
  19. static void stats_add_dnload (struct userrec *, unsigned long);
  20. static void stats_add_upload (struct userrec *, unsigned long);
  21. static void wipe_tmp_filename (char *, int);
  22. static int at_limit (char *);
  23. static void dcc_get_pending (int, char *, int);
  24. static struct dcc_table DCC_SEND;
  25. static struct dcc_table DCC_GET;
  26. static struct dcc_table DCC_GET_PENDING;
  27. static fileq_t *fileq = NULL;
  28. #undef MATCH
  29. #define MATCH (match+sofar)
  30. #define QUOTE '\\'
  31. #define WILDS '*'
  32. #define WILDQ '?'
  33. #define NOMATCH 0
  34. static int
  35. wild_match_file (register char *m, register char *n)
  36. {
  37. char *ma = m, *lsm = 0, *lsn = 0;
  38. int match = 1;
  39. register unsigned int sofar = 0;
  40. if ((m == 0) || (n == 0) || (!*n))
  41. return NOMATCH;
  42. while (*n)
  43. {
  44. switch (*m)
  45. {
  46. case 0:
  47. do
  48. m--;
  49. while ((m > ma) && (*m == '?'));
  50. if ((m > ma) ? ((*m == '*') && (m[-1] != QUOTE)) : (*m == '*'))
  51. return MATCH;
  52. break;
  53. case WILDS:
  54. do
  55. m++;
  56. while (*m == WILDS);
  57. lsm = m;
  58. lsn = n;
  59. match += sofar;
  60. sofar = 0;
  61. continue;
  62. case WILDQ:
  63. m++;
  64. n++;
  65. continue;
  66. case QUOTE:
  67. m++;
  68. }
  69. if (*m == *n)
  70. {
  71. m++;
  72. n++;
  73. sofar++;
  74. continue;
  75. }
  76. if (lsm)
  77. {
  78. n = ++lsn;
  79. m = lsm;
  80. sofar = 0;
  81. continue;
  82. }
  83. return NOMATCH;
  84. }
  85. while (*m == WILDS)
  86. m++;
  87. return (*m) ? NOMATCH : MATCH;
  88. }
  89. static void
  90. wipe_tmp_filename (char *fn, int idx)
  91. {
  92. int i, ok = 1;
  93. if (!copy_to_tmp)
  94. return;
  95. for (i = 0; i < dcc_total; i++)
  96. if (i != idx)
  97. if (dcc[i].type == &DCC_GET || dcc[i].type == &DCC_GET_PENDING)
  98. if (!strcmp (dcc[i].u.xfer->filename, fn))
  99. {
  100. ok = 0;
  101. break;
  102. }
  103. if (ok)
  104. unlink (fn);
  105. }
  106. static int
  107. at_limit (char *nick)
  108. {
  109. int i, x = 0;
  110. for (i = 0; i < dcc_total; i++)
  111. if (dcc[i].type == &DCC_GET || dcc[i].type == &DCC_GET_PENDING)
  112. if (!egg_strcasecmp (dcc[i].nick, nick))
  113. x++;
  114. return (x >= dcc_limit);
  115. }
  116. static char *
  117. replace_spaces (char *fn)
  118. {
  119. register char *ret, *p;
  120. p = ret = nmalloc (strlen (fn) + 1);
  121. strcpy (ret, fn);
  122. while ((p = strchr (p, ' ')) != NULL)
  123. *p = '_';
  124. return ret;
  125. }
  126. static int builtin_sentrcvd STDVAR
  127. {
  128. Function F = (Function) cd;
  129. BADARGS (4, 4, " hand nick path");
  130. CHECKVALIDITY (builtin_sentrcvd);
  131. F (argv[1], argv[2], argv[3]);
  132. return TCL_OK;
  133. }
  134. static int builtin_toutlost STDVAR
  135. {
  136. Function F = (Function) cd;
  137. BADARGS (6, 6, " hand nick path acked length");
  138. CHECKVALIDITY (builtin_toutlost);
  139. F (argv[1], argv[2], argv[3], argv[4], argv[5]);
  140. return TCL_OK;
  141. }
  142. static void
  143. check_tcl_sentrcvd (struct userrec *u, char *nick, char *path,
  144. p_tcl_bind_list h)
  145. {
  146. struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
  147. char *hand = u ? u->handle : "*";
  148. get_user_flagrec (u, &fr, NULL);
  149. Tcl_SetVar (interp, "_sr1", hand, 0);
  150. Tcl_SetVar (interp, "_sr2", nick, 0);
  151. Tcl_SetVar (interp, "_sr3", path, 0);
  152. check_tcl_bind (h, hand, &fr, " $_sr1 $_sr2 $_sr3",
  153. MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE);
  154. } static void
  155. check_tcl_toutlost (struct userrec *u, char *nick, char *path,
  156. unsigned long acked, unsigned long length,
  157. p_tcl_bind_list h)
  158. {
  159. struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
  160. char *hand = u ? u->handle : "*";
  161. char s[15];
  162. get_user_flagrec (u, &fr, NULL);
  163. Tcl_SetVar (interp, "_sr1", hand, 0);
  164. Tcl_SetVar (interp, "_sr2", nick, 0);
  165. Tcl_SetVar (interp, "_sr3", path, 0);
  166. egg_snprintf (s, sizeof s, "%lu", acked);
  167. Tcl_SetVar (interp, "_sr4", s, 0);
  168. egg_snprintf (s, sizeof s, "%lu", length);
  169. Tcl_SetVar (interp, "_sr5", s, 0);
  170. check_tcl_bind (h, hand, &fr, " $_sr1 $_sr2 $_sr3 $_sr4 $_sr5",
  171. MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE);
  172. }
  173. static int
  174. expmem_fileq ()
  175. {
  176. fileq_t *q;
  177. int tot = 0;
  178. for (q = fileq; q; q = q->next)
  179. tot += strlen (q->dir) + strlen (q->file) + 2 + sizeof (fileq_t);
  180. return tot;
  181. }
  182. static void
  183. queue_file (char *dir, char *file, char *from, char *to)
  184. {
  185. fileq_t *q = fileq;
  186. fileq = (fileq_t *) nmalloc (sizeof (fileq_t));
  187. fileq->next = q;
  188. fileq->dir = (char *) nmalloc (strlen (dir) + 1);
  189. fileq->file = (char *) nmalloc (strlen (file) + 1);
  190. strcpy (fileq->dir, dir);
  191. strcpy (fileq->file, file);
  192. strcpy (fileq->nick, from);
  193. strcpy (fileq->to, to);
  194. } static void
  195. deq_this (fileq_t * this)
  196. {
  197. fileq_t *q = fileq, *last = NULL;
  198. while (q && q != this)
  199. {
  200. last = q;
  201. q = q->next;
  202. }
  203. if (!q)
  204. return;
  205. if (last)
  206. last->next = q->next;
  207. else
  208. fileq = q->next;
  209. nfree (q->dir);
  210. nfree (q->file);
  211. nfree (q);
  212. }
  213. static void
  214. flush_fileq (char *to)
  215. {
  216. fileq_t *q = fileq;
  217. int fnd = 1;
  218. while (fnd)
  219. {
  220. q = fileq;
  221. fnd = 0;
  222. while (q != NULL)
  223. {
  224. if (!egg_strcasecmp (q->to, to))
  225. {
  226. deq_this (q);
  227. q = NULL;
  228. fnd = 1;
  229. }
  230. if (q != NULL)
  231. q = q->next;
  232. }
  233. }
  234. }
  235. static void
  236. send_next_file (char *to)
  237. {
  238. fileq_t *q, *this = NULL;
  239. char *s, *s1;
  240. int x;
  241. for (q = fileq; q; q = q->next)
  242. if (!egg_strcasecmp (q->to, to))
  243. this = q;
  244. if (this == NULL)
  245. return;
  246. if (this->dir[0] == '*')
  247. {
  248. s = nmalloc (strlen (&this->dir[1]) + strlen (this->file) + 2);
  249. sprintf (s, "%s/%s", &this->dir[1], this->file);
  250. }
  251. else
  252. {
  253. char *p = strchr (this->dir, '*');
  254. if (p == NULL)
  255. {
  256. send_next_file (to);
  257. return;
  258. }
  259. p++;
  260. s = nmalloc (strlen (p) + strlen (this->file) + 2);
  261. sprintf (s, "%s%s%s", p, p[0] ? "/" : "", this->file);
  262. strcpy (this->dir, &(p[atoi (this->dir)]));
  263. }
  264. if (copy_to_tmp)
  265. {
  266. s1 = nmalloc (strlen (tempdir) + strlen (this->file) + 1);
  267. sprintf (s1, "%s%s", tempdir, this->file);
  268. if (copyfile (s, s1) != 0)
  269. {
  270. putlog (LOG_FILES | LOG_MISC, "*", TRANSFER_COPY_FAILED, this->file,
  271. tempdir);
  272. dprintf (DP_HELP, TRANSFER_FILESYS_BROKEN, this->to);
  273. strcpy (s, this->to);
  274. flush_fileq (s);
  275. nfree (s1);
  276. nfree (s);
  277. return;
  278. }
  279. }
  280. else
  281. {
  282. s1 = nmalloc (strlen (s) + 1);
  283. strcpy (s1, s);
  284. }
  285. if (this->dir[0] == '*')
  286. {
  287. s = nrealloc (s, strlen (&this->dir[1]) + strlen (this->file) + 2);
  288. sprintf (s, "%s/%s", &this->dir[1], this->file);
  289. }
  290. else
  291. {
  292. s = nrealloc (s, strlen (this->dir) + strlen (this->file) + 2);
  293. sprintf (s, "%s%s%s", this->dir, this->dir[0] ? "/" : "", this->file);
  294. }
  295. x = raw_dcc_send (s1, this->to, this->nick, s);
  296. if (x == DCCSEND_OK)
  297. {
  298. if (egg_strcasecmp (this->to, this->nick))
  299. dprintf (DP_HELP, TRANSFER_FILE_ARRIVE, this->to, this->nick);
  300. deq_this (this);
  301. nfree (s);
  302. nfree (s1);
  303. return;
  304. }
  305. wipe_tmp_filename (s1, -1);
  306. if (x == DCCSEND_FULL)
  307. {
  308. putlog (LOG_FILES, "*", TRANSFER_LOG_CONFULL, s1, this->nick);
  309. dprintf (DP_HELP, TRANSFER_NOTICE_CONFULL, this->to);
  310. strcpy (s, this->to);
  311. flush_fileq (s);
  312. }
  313. else if (x == DCCSEND_NOSOCK)
  314. {
  315. putlog (LOG_FILES, "*", TRANSFER_LOG_SOCKERR, s1, this->nick);
  316. dprintf (DP_HELP, TRANSFER_NOTICE_SOCKERR, this->to);
  317. strcpy (s, this->to);
  318. flush_fileq (s);
  319. }
  320. else
  321. {
  322. if (x == DCCSEND_FEMPTY)
  323. {
  324. putlog (LOG_FILES, "*", TRANSFER_LOG_FILEEMPTY, this->file);
  325. dprintf (DP_HELP, TRANSFER_NOTICE_FILEEMPTY, this->to, this->file);
  326. }
  327. deq_this (this);
  328. }
  329. nfree (s);
  330. nfree (s1);
  331. return;
  332. }
  333. static void
  334. show_queued_files (int idx)
  335. {
  336. int i, cnt = 0, len;
  337. char spaces[] = " ";
  338. fileq_t *q;
  339. for (q = fileq; q; q = q->next)
  340. {
  341. if (!egg_strcasecmp (q->nick, dcc[idx].nick))
  342. {
  343. if (!cnt)
  344. {
  345. spaces[HANDLEN - 9] = 0;
  346. dprintf (idx, TRANSFER_SEND_TO, spaces);
  347. dprintf (idx, TRANSFER_LINES, spaces);
  348. spaces[HANDLEN - 9] = ' ';
  349. }
  350. cnt++;
  351. spaces[len = HANDLEN - strlen (q->to)] = 0;
  352. if (q->dir[0] == '*')
  353. dprintf (idx, " %s%s %s/%s\n", q->to, spaces, &q->dir[1],
  354. q->file);
  355. else
  356. dprintf (idx, " %s%s /%s%s%s\n", q->to, spaces, q->dir,
  357. q->dir[0] ? "/" : "", q->file);
  358. spaces[len] = ' ';
  359. }
  360. }
  361. for (i = 0; i < dcc_total; i++)
  362. {
  363. if ((dcc[i].type == &DCC_GET_PENDING || dcc[i].type == &DCC_GET)
  364. && (!egg_strcasecmp (dcc[i].nick, dcc[idx].nick)
  365. || !egg_strcasecmp (dcc[i].u.xfer->from, dcc[idx].nick)))
  366. {
  367. char *nfn;
  368. if (!cnt)
  369. {
  370. spaces[HANDLEN - 9] = 0;
  371. dprintf (idx, TRANSFER_SEND_TO, spaces);
  372. dprintf (idx, TRANSFER_LINES, spaces);
  373. spaces[HANDLEN - 9] = ' ';
  374. }
  375. nfn = strrchr (dcc[i].u.xfer->origname, '/');
  376. if (nfn == NULL)
  377. nfn = dcc[i].u.xfer->origname;
  378. else
  379. nfn++;
  380. cnt++;
  381. spaces[len = HANDLEN - strlen (dcc[i].nick)] = 0;
  382. if (dcc[i].type == &DCC_GET_PENDING)
  383. dprintf (idx, TRANSFER_WAITING, dcc[i].nick, spaces, nfn);
  384. else
  385. dprintf (idx, TRANSFER_DONE, dcc[i].nick, spaces, nfn,
  386. (100.0 *
  387. ((float) dcc[i].status /
  388. (float) dcc[i].u.xfer->length)));
  389. spaces[len] = ' ';
  390. }
  391. } if (!cnt)
  392. dprintf (idx, TRANSFER_QUEUED_UP);
  393. else
  394. dprintf (idx, TRANSFER_TOTAL, cnt);
  395. }
  396. static void
  397. fileq_cancel (int idx, char *par)
  398. {
  399. int fnd = 1, matches = 0, atot = 0, i;
  400. fileq_t *q;
  401. char *s = NULL;
  402. while (fnd)
  403. {
  404. q = fileq;
  405. fnd = 0;
  406. while (q != NULL)
  407. {
  408. if (!egg_strcasecmp (dcc[idx].nick, q->nick))
  409. {
  410. s = nrealloc (s, strlen (q->dir) + strlen (q->file) + 3);
  411. if (q->dir[0] == '*')
  412. sprintf (s, "%s/%s", &q->dir[1], q->file);
  413. else
  414. sprintf (s, "/%s%s%s", q->dir, q->dir[0] ? "/" : "", q->file);
  415. if (wild_match_file (par, s))
  416. {
  417. dprintf (idx, TRANSFER_CANCELLED, s, q->to);
  418. fnd = 1;
  419. deq_this (q);
  420. q = NULL;
  421. matches++;
  422. }
  423. if (!fnd && wild_match_file (par, q->file))
  424. {
  425. dprintf (idx, TRANSFER_CANCELLED, s, q->to);
  426. fnd = 1;
  427. deq_this (q);
  428. q = NULL;
  429. matches++;
  430. }
  431. }
  432. if (q != NULL)
  433. q = q->next;
  434. }
  435. }
  436. if (s)
  437. nfree (s);
  438. for (i = 0; i < dcc_total; i++)
  439. {
  440. if ((dcc[i].type == &DCC_GET_PENDING || dcc[i].type == &DCC_GET)
  441. && (!egg_strcasecmp (dcc[i].nick, dcc[idx].nick)
  442. || !egg_strcasecmp (dcc[i].u.xfer->from, dcc[idx].nick)))
  443. {
  444. char *nfn = strrchr (dcc[i].u.xfer->origname, '/');
  445. if (nfn == NULL)
  446. nfn = dcc[i].u.xfer->origname;
  447. else
  448. nfn++;
  449. if (wild_match_file (par, nfn))
  450. {
  451. dprintf (idx, TRANSFER_ABORT_DCCSEND, nfn);
  452. if (egg_strcasecmp (dcc[i].nick, dcc[idx].nick))
  453. dprintf (DP_HELP, TRANSFER_NOTICE_ABORT, dcc[i].nick, nfn,
  454. dcc[idx].nick);
  455. if (dcc[i].type == &DCC_GET)
  456. putlog (LOG_FILES, "*", TRANSFER_DCC_CANCEL, nfn, dcc[i].nick,
  457. dcc[i].status, dcc[i].u.xfer->length);
  458. wipe_tmp_filename (dcc[i].u.xfer->filename, i);
  459. atot++;
  460. matches++;
  461. killsock (dcc[i].sock);
  462. lostdcc (i);
  463. }
  464. }
  465. }
  466. if (!matches)
  467. dprintf (idx, TRANSFER_NO_MATCHES);
  468. else
  469. dprintf (idx, TRANSFER_CANCELLED_FILE, matches,
  470. (matches != 1) ? "s" : "");
  471. for (i = 0; i < atot; i++)
  472. if (!at_limit (dcc[idx].nick))
  473. send_next_file (dcc[idx].nick);
  474. }
  475. static int tcl_getfileq STDVAR
  476. {
  477. char *s = NULL;
  478. fileq_t *q;
  479. BADARGS (2, 2, " handle");
  480. for (q = fileq; q; q = q->next)
  481. {
  482. if (!egg_strcasecmp (q->nick, argv[1]))
  483. {
  484. s =
  485. nrealloc (s,
  486. strlen (q->to) + strlen (q->dir) + strlen (q->file) +
  487. 4);
  488. if (q->dir[0] == '*')
  489. sprintf (s, "%s %s/%s", q->to, &q->dir[1], q->file);
  490. else
  491. sprintf (s, "%s /%s%s%s", q->to, q->dir, q->dir[0] ? "/" : "",
  492. q->file);
  493. Tcl_AppendElement (irp, s);
  494. }
  495. }
  496. if (s)
  497. nfree (s);
  498. return TCL_OK;
  499. }
  500. static int tcl_dccsend STDVAR
  501. {
  502. char s[10], *sys, *nfn;
  503. int i;
  504. FILE *f;
  505. BADARGS (3, 3, " filename ircnick");
  506. f = fopen (argv[1], "r");
  507. if (f == NULL)
  508. {
  509. Tcl_AppendResult (irp, "3", NULL);
  510. return TCL_OK;
  511. }
  512. fclose (f);
  513. nfn = strrchr (argv[1], '/');
  514. if (nfn == NULL)
  515. nfn = argv[1];
  516. else
  517. nfn++;
  518. if (at_limit (argv[2]))
  519. {
  520. if (nfn == argv[1])
  521. queue_file ("*", nfn, "(script)", argv[2]);
  522. else
  523. {
  524. nfn--;
  525. *nfn = 0;
  526. nfn++;
  527. sys = nmalloc (strlen (argv[1]) + 2);
  528. sprintf (sys, "*%s", argv[1]);
  529. queue_file (sys, nfn, "(script)", argv[2]);
  530. nfree (sys);
  531. }
  532. Tcl_AppendResult (irp, "4", NULL);
  533. return TCL_OK;
  534. }
  535. if (copy_to_tmp)
  536. {
  537. sys = nmalloc (strlen (tempdir) + strlen (nfn) + 1);
  538. sprintf (sys, "%s%s", tempdir, nfn);
  539. f = fopen (sys, "r");
  540. if (f)
  541. {
  542. fclose (f);
  543. Tcl_AppendResult (irp, "5", NULL);
  544. return TCL_OK;
  545. }
  546. else
  547. copyfile (argv[1], sys);
  548. }
  549. else
  550. {
  551. sys = nmalloc (strlen (argv[1]) + 1);
  552. strcpy (sys, argv[1]);
  553. }
  554. i = raw_dcc_send (sys, argv[2], "*", argv[1]);
  555. if (i > 0)
  556. wipe_tmp_filename (sys, -1);
  557. egg_snprintf (s, sizeof s, "%d", i);
  558. Tcl_AppendResult (irp, s, NULL);
  559. nfree (sys);
  560. return TCL_OK;
  561. }
  562. static int tcl_getfilesendtime STDVAR
  563. {
  564. int sock, i;
  565. char s[15];
  566. BADARGS (2, 2, " idx");
  567. sock = atoi (argv[1]);
  568. for (i = 0; i < dcc_total; i++)
  569. if (dcc[i].sock == sock)
  570. {
  571. if (dcc[i].type == &DCC_SEND || dcc[i].type == &DCC_GET)
  572. {
  573. egg_snprintf (s, sizeof s, "%lu", dcc[i].u.xfer->start_time);
  574. Tcl_AppendResult (irp, s, NULL);
  575. }
  576. else
  577. Tcl_AppendResult (irp, "-2", NULL);
  578. return TCL_OK;
  579. }
  580. Tcl_AppendResult (irp, "-1", NULL);
  581. return TCL_OK;
  582. }
  583. static tcl_cmds mytcls[] =
  584. { {"dccsend", tcl_dccsend}, {"getfileq", tcl_getfileq}, {"getfilesendtime",
  585. tcl_getfilesendtime},
  586. {NULL, NULL} };
  587. #define PMAX_SIZE 4096
  588. static unsigned long
  589. pump_file_to_sock (FILE * file, long sock,
  590. register unsigned long pending_data)
  591. {
  592. const unsigned long buf_len =
  593. pending_data >= PMAX_SIZE ? PMAX_SIZE : pending_data;
  594. char *bf = nmalloc (buf_len);
  595. register unsigned long actual_size;
  596. if (bf)
  597. {
  598. do
  599. {
  600. actual_size = pending_data >= buf_len ? buf_len : pending_data;
  601. fread (bf, actual_size, 1, file);
  602. tputs (sock, bf, actual_size);
  603. pending_data -= actual_size;
  604. }
  605. while (!sock_has_data (SOCK_DATA_OUTGOING, sock) && pending_data != 0);
  606. nfree (bf);
  607. }
  608. return pending_data;
  609. }
  610. static void
  611. eof_dcc_fork_send (int idx)
  612. {
  613. char s1[121];
  614. char *s2;
  615. fclose (dcc[idx].u.xfer->f);
  616. if (!strcmp (dcc[idx].nick, "*users"))
  617. {
  618. int x, y = 0;
  619. for (x = 0; x < dcc_total; x++)
  620. if ((!egg_strcasecmp (dcc[x].nick, dcc[idx].host))
  621. && (dcc[x].type->flags & DCT_BOT))
  622. {
  623. y = x;
  624. break;
  625. }
  626. if (y != 0)
  627. {
  628. dcc[y].status &= ~STAT_GETTING;
  629. dcc[y].status &= ~STAT_SHARE;
  630. }
  631. putlog (LOG_BOTS, "*", USERF_FAILEDXFER);
  632. unlink (dcc[idx].u.xfer->filename);
  633. }
  634. else if (!strcmp (dcc[idx].nick, "*binary"))
  635. {
  636. int x, y = 0;
  637. for (x = 0; x < dcc_total; x++)
  638. if ((!egg_strcasecmp (dcc[x].nick, dcc[idx].host))
  639. && (dcc[x].type->flags & DCT_BOT))
  640. {
  641. y = x;
  642. break;
  643. }
  644. if (y != 0)
  645. {
  646. dcc[y].status &= ~STAT_GETTINGU;
  647. }
  648. putlog (LOG_BOTS, "*", "Failed binary transfer.");
  649. }
  650. else
  651. {
  652. neterror (s1);
  653. if (!quiet_reject)
  654. dprintf (DP_HELP, "NOTICE %s :%s (%s)\n", dcc[idx].nick,
  655. DCC_CONNECTFAILED1, s1);
  656. putlog (LOG_MISC, "*", "%s: SEND %s (%s!%s)", DCC_CONNECTFAILED2,
  657. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
  658. putlog (LOG_MISC, "*", " (%s)", s1);
  659. s2 =
  660. nmalloc (strlen (tempdir) + strlen (dcc[idx].u.xfer->filename) + 1);
  661. sprintf (s2, "%s%s", tempdir, dcc[idx].u.xfer->filename);
  662. unlink (s2);
  663. nfree (s2);
  664. }
  665. killsock (dcc[idx].sock);
  666. lostdcc (idx);
  667. }
  668. static void
  669. eof_dcc_send (int idx)
  670. {
  671. int ok, j;
  672. char *ofn, *nfn, s[1024], *hand;
  673. struct userrec *u;
  674. fclose (dcc[idx].u.xfer->f);
  675. if (dcc[idx].u.xfer->length == dcc[idx].status)
  676. {
  677. int l;
  678. ok = 0;
  679. if (!strcmp (dcc[idx].nick, "*users"))
  680. {
  681. module_entry *me = module_find ("share", 0, 0);
  682. if (me && me->funcs)
  683. {
  684. Function f = me->funcs[SHARE_FINISH];
  685. (f) (idx);
  686. }
  687. killsock (dcc[idx].sock);
  688. lostdcc (idx);
  689. return;
  690. }
  691. else if (!strcmp (dcc[idx].nick, "*binary"))
  692. {
  693. module_entry *me = module_find ("update", 0, 0);
  694. if (me && me->funcs)
  695. {
  696. Function f = me->funcs[UPDATE_FINISH];
  697. (f) (idx);
  698. }
  699. killsock (dcc[idx].sock);
  700. lostdcc (idx);
  701. return;
  702. }
  703. putlog (LOG_FILES, "*", TRANSFER_COMPLETED_DCC,
  704. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
  705. egg_snprintf (s, sizeof s, "%s!%s", dcc[idx].nick, dcc[idx].host);
  706. u = get_user_by_host (s);
  707. hand = u ? u->handle : "*";
  708. l = strlen (dcc[idx].u.xfer->filename);
  709. if (l > NAME_MAX)
  710. {
  711. putlog (LOG_FILES, "*", TRANSFER_FILENAME_TOOLONG, l);
  712. dprintf (DP_HELP, TRANSFER_NOTICE_FNTOOLONG, dcc[idx].nick, l);
  713. putlog (LOG_FILES, "*", TRANSFER_TOO_BAD);
  714. dprintf (DP_HELP, TRANSFER_NOTICE_TOOBAD, dcc[idx].nick);
  715. killsock (dcc[idx].sock);
  716. lostdcc (idx);
  717. return;
  718. }
  719. ofn =
  720. nmalloc (strlen (tempdir) + strlen (dcc[idx].u.xfer->filename) + 1);
  721. nfn =
  722. nmalloc (strlen (dcc[idx].u.xfer->dir) +
  723. strlen (dcc[idx].u.xfer->origname) + 1);
  724. sprintf (ofn, "%s%s", tempdir, dcc[idx].u.xfer->filename);
  725. sprintf (nfn, "%s%s", dcc[idx].u.xfer->dir, dcc[idx].u.xfer->origname);
  726. if (movefile (ofn, nfn))
  727. putlog (LOG_MISC | LOG_FILES, "*", TRANSFER_FAILED_MOVE, nfn, ofn);
  728. else
  729. {
  730. module_entry *fs = module_find ("filesys", 0, 0);
  731. if (fs != NULL)
  732. {
  733. Function f = fs->funcs[FILESYS_ADDFILE];
  734. f (dcc[idx].u.xfer->dir, dcc[idx].u.xfer->origname, hand);
  735. }
  736. stats_add_upload (u, dcc[idx].u.xfer->length);
  737. check_tcl_sentrcvd (u, dcc[idx].nick, nfn, H_rcvd);
  738. }
  739. nfree (ofn);
  740. nfree (nfn);
  741. for (j = 0; j < dcc_total; j++)
  742. if (!ok && (dcc[j].type->flags & (DCT_GETNOTES | DCT_FILES))
  743. && !egg_strcasecmp (dcc[j].nick, hand))
  744. {
  745. ok = 1;
  746. dprintf (j, TRANSFER_THANKS);
  747. }
  748. if (!ok)
  749. dprintf (DP_HELP, TRANSFER_NOTICE_THANKS, dcc[idx].nick);
  750. killsock (dcc[idx].sock);
  751. lostdcc (idx);
  752. return;
  753. }
  754. if (!strcmp (dcc[idx].nick, "*users"))
  755. {
  756. int x, y = 0;
  757. for (x = 0; x < dcc_total; x++)
  758. if ((!egg_strcasecmp (dcc[x].nick, dcc[idx].host))
  759. && (dcc[x].type->flags & DCT_BOT))
  760. y = x;
  761. if (y)
  762. {
  763. putlog (LOG_BOTS, "*", TRANSFER_USERFILE_LOST, dcc[y].nick);
  764. unlink (dcc[idx].u.xfer->filename);
  765. dprintf (y, "bye\n");
  766. egg_snprintf (s, sizeof s, TRANSFER_USERFILE_DISCON, dcc[y].nick);
  767. botnet_send_unlinked (y, dcc[y].nick, s);
  768. chatout ("*** %s\n", dcc[y].nick, s);
  769. if (y != idx)
  770. {
  771. killsock (dcc[y].sock);
  772. lostdcc (y);
  773. }
  774. killsock (dcc[idx].sock);
  775. lostdcc (idx);
  776. }
  777. }
  778. else if (!strcmp (dcc[idx].nick, "*binary"))
  779. {
  780. int x, y = 0;
  781. for (x = 0; x < dcc_total; x++)
  782. if ((!egg_strcasecmp (dcc[x].nick, dcc[idx].host))
  783. && (dcc[x].type->flags & DCT_BOT))
  784. y = x;
  785. if (y)
  786. {
  787. putlog (LOG_BOTS, "*", "Lost binary transfer from %s; aborting.",
  788. dcc[y].nick);
  789. unlink (dcc[idx].u.xfer->filename);
  790. killsock (dcc[idx].sock);
  791. lostdcc (idx);
  792. }
  793. }
  794. else
  795. {
  796. putlog (LOG_FILES, "*", TRANSFER_LOST_DCCSEND,
  797. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host,
  798. dcc[idx].status, dcc[idx].u.xfer->length);
  799. ofn =
  800. nmalloc (strlen (tempdir) + strlen (dcc[idx].u.xfer->filename) + 1);
  801. sprintf (ofn, "%s%s", tempdir, dcc[idx].u.xfer->filename);
  802. unlink (ofn);
  803. nfree (ofn);
  804. killsock (dcc[idx].sock);
  805. lostdcc (idx);
  806. }
  807. }
  808. static inline u_8bit_t
  809. byte_order_test (void)
  810. {
  811. u_16bit_t test = TRANSFER_REGET_PACKETID;
  812. if (*((u_8bit_t *) & test) == ((TRANSFER_REGET_PACKETID & 0xff00) >> 8))
  813. return 0;
  814. if (*((u_8bit_t *) & test) == (TRANSFER_REGET_PACKETID & 0x00ff))
  815. return 1;
  816. return 0;
  817. }
  818. inline static void
  819. handle_resend_packet (int idx, transfer_reget * reget_data)
  820. {
  821. if (byte_order_test () != reget_data->byte_order)
  822. {
  823. reget_data->packet_id =
  824. ((reget_data->packet_id & 0x00ff) << 8) | ((reget_data->
  825. packet_id & 0xff00) >> 8);
  826. reget_data->byte_offset =
  827. ((reget_data->byte_offset & 0xff000000) >> 24) | ((reget_data->
  828. byte_offset &
  829. 0x00ff0000) >> 8) |
  830. ((reget_data->byte_offset & 0x0000ff00) << 8) | ((reget_data->
  831. byte_offset &
  832. 0x000000ff) << 24);
  833. }
  834. if (reget_data->packet_id != TRANSFER_REGET_PACKETID)
  835. putlog (LOG_FILES, "*", TRANSFER_REGET_PACKET, dcc[idx].nick,
  836. dcc[idx].u.xfer->origname);
  837. else
  838. dcc[idx].u.xfer->offset = reget_data->byte_offset;
  839. dcc[idx].u.xfer->type = XFER_RESEND;
  840. }
  841. static void
  842. dcc_get (int idx, char *buf, int len)
  843. {
  844. char xnick[NICKLEN];
  845. unsigned char bbuf[4];
  846. unsigned long cmp, l;
  847. int w = len + dcc[idx].u.xfer->sofar, p = 0;
  848. dcc[idx].timeval = now;
  849. if (w < 4 || (w < 8 && dcc[idx].u.xfer->type == XFER_RESEND_PEND))
  850. {
  851. my_memcpy (&(dcc[idx].u.xfer->buf[dcc[idx].u.xfer->sofar]), buf, len);
  852. dcc[idx].u.xfer->sofar += len;
  853. return;
  854. }
  855. else if (dcc[idx].u.xfer->type == XFER_RESEND_PEND)
  856. {
  857. if (w == 8)
  858. {
  859. transfer_reget reget_data;
  860. my_memcpy (&reget_data, dcc[idx].u.xfer->buf,
  861. dcc[idx].u.xfer->sofar);
  862. my_memcpy (&reget_data + dcc[idx].u.xfer->sofar, buf, len);
  863. handle_resend_packet (idx, &reget_data);
  864. cmp = dcc[idx].u.xfer->offset;
  865. }
  866. else
  867. return;
  868. }
  869. else
  870. {
  871. if (w == 4)
  872. {
  873. my_memcpy (bbuf, dcc[idx].u.xfer->buf, dcc[idx].u.xfer->sofar);
  874. my_memcpy (&(bbuf[dcc[idx].u.xfer->sofar]), buf, len);
  875. }
  876. else
  877. {
  878. p = ((w - 1) & ~3) - dcc[idx].u.xfer->sofar;
  879. w = w - ((w - 1) & ~3);
  880. if (w < 4)
  881. {
  882. my_memcpy (dcc[idx].u.xfer->buf, &(buf[p]), w);
  883. return;
  884. }
  885. my_memcpy (bbuf, &(buf[p]), w);
  886. }
  887. cmp =
  888. ((unsigned int) (bbuf[0]) << 24) + ((unsigned int) (bbuf[1]) << 16) +
  889. ((unsigned int) (bbuf[2]) << 8) + bbuf[3];
  890. dcc[idx].u.xfer->acked = cmp;
  891. } dcc[idx].u.xfer->sofar = 0;
  892. if (cmp > dcc[idx].u.xfer->length && cmp > dcc[idx].status)
  893. {
  894. putlog (LOG_FILES, "*", TRANSFER_BEHIND_FILEEND,
  895. dcc[idx].u.xfer->origname, dcc[idx].nick);
  896. }
  897. else if (cmp > dcc[idx].status)
  898. {
  899. if (!strcmp (dcc[idx].nick, "*users"))
  900. {
  901. putlog (LOG_BOTS, "*", TRANSFER_TRY_SKIP_AHEAD);
  902. }
  903. else if (!strcmp (dcc[idx].nick, "*binary"))
  904. {
  905. putlog (LOG_BOTS, "*",
  906. "!!! Trying to skip ahead on binary transfer");
  907. }
  908. else
  909. {
  910. fseek (dcc[idx].u.xfer->f, cmp, SEEK_SET);
  911. dcc[idx].status = cmp;
  912. putlog (LOG_FILES, "*", TRANSFER_RESUME_FILE, (int) (cmp / 1024),
  913. dcc[idx].u.xfer->origname, dcc[idx].nick);
  914. }}
  915. else
  916. {
  917. if (dcc[idx].u.xfer->ack_type == XFER_ACK_UNKNOWN)
  918. {
  919. if (cmp < dcc[idx].u.xfer->offset)
  920. dcc[idx].u.xfer->ack_type = XFER_ACK_WITHOUT_OFFSET;
  921. else
  922. dcc[idx].u.xfer->ack_type = XFER_ACK_WITH_OFFSET;
  923. }
  924. if (dcc[idx].u.xfer->ack_type == XFER_ACK_WITHOUT_OFFSET)
  925. cmp += dcc[idx].u.xfer->offset;
  926. }
  927. if (cmp != dcc[idx].status)
  928. return;
  929. if (dcc[idx].status == dcc[idx].u.xfer->length)
  930. {
  931. killsock (dcc[idx].sock);
  932. fclose (dcc[idx].u.xfer->f);
  933. if (!strcmp (dcc[idx].nick, "*users"))
  934. {
  935. module_entry *me = module_find ("share", 0, 0);
  936. int x, y = 0;
  937. for (x = 0; x < dcc_total; x++)
  938. if (!egg_strcasecmp (dcc[x].nick, dcc[idx].host)
  939. && (dcc[x].type->flags & DCT_BOT))
  940. y = x;
  941. if (y != 0)
  942. dcc[y].status &= ~STAT_SENDING;
  943. putlog (LOG_BOTS, "*", TRANSFER_COMPLETED_USERFILE, dcc[y].nick);
  944. unlink (dcc[idx].u.xfer->filename);
  945. if (me && me->funcs[SHARE_DUMP_RESYNC])
  946. ((me->funcs)[SHARE_DUMP_RESYNC]) (y);
  947. xnick[0] = 0;
  948. }
  949. else if (!strcmp (dcc[idx].nick, "*binary"))
  950. {
  951. int x, y = 0;
  952. for (x = 0; x < dcc_total; x++)
  953. if (!egg_strcasecmp (dcc[x].nick, dcc[idx].host)
  954. && (dcc[x].type->flags & DCT_BOT))
  955. y = x;
  956. if (y != 0)
  957. {
  958. dcc[y].status &= ~STAT_SENDINGU;
  959. dcc[y].status |= STAT_UPDATED;
  960. }
  961. putlog (LOG_BOTS, "*", "Completed binary file send to %s",
  962. dcc[y].nick);
  963. xnick[0] = 0;
  964. #ifdef HUB
  965. bupdating = 0;
  966. #endif
  967. }
  968. else
  969. {
  970. module_entry *fs = module_find ("filesys", 0, 0);
  971. struct userrec *u =
  972. get_user_by_handle (userlist, dcc[idx].u.xfer->from);
  973. check_tcl_sentrcvd (u, dcc[idx].nick, dcc[idx].u.xfer->dir, H_sent);
  974. if (fs != NULL)
  975. {
  976. Function f = fs->funcs[FILESYS_INCRGOTS];
  977. f (dcc[idx].u.xfer->dir);
  978. }
  979. stats_add_dnload (u, dcc[idx].u.xfer->length);
  980. putlog (LOG_FILES, "*", TRANSFER_FINISHED_DCCSEND,
  981. dcc[idx].u.xfer->origname, dcc[idx].nick);
  982. wipe_tmp_filename (dcc[idx].u.xfer->filename, idx);
  983. strcpy ((char *) xnick, dcc[idx].nick);
  984. } lostdcc (idx);
  985. if (!at_limit (xnick))
  986. send_next_file (xnick);
  987. return;
  988. }
  989. l = dcc_block;
  990. if (l == 0 || dcc[idx].status + l > dcc[idx].u.xfer->length)
  991. l = dcc[idx].u.xfer->length - dcc[idx].status;
  992. dcc[idx].u.xfer->block_pending =
  993. pump_file_to_sock (dcc[idx].u.xfer->f, dcc[idx].sock, l);
  994. dcc[idx].status += l;
  995. }
  996. static void
  997. eof_dcc_get (int idx)
  998. {
  999. char xnick[NICKLEN], s[1024];
  1000. fclose (dcc[idx].u.xfer->f);
  1001. if (!strcmp (dcc[idx].nick, "*users"))
  1002. {
  1003. int x, y = 0;
  1004. for (x = 0; x < dcc_total; x++)
  1005. if (!egg_strcasecmp (dcc[x].nick, dcc[idx].host)
  1006. && (dcc[x].type->flags & DCT_BOT))
  1007. y = x;
  1008. putlog (LOG_BOTS, "*", TRANSFER_ABORT_USERFILE);
  1009. xnick[0] = 0;
  1010. dprintf (-dcc[y].sock, "bye\n");
  1011. egg_snprintf (s, sizeof s, TRANSFER_USERFILE_DISCON, dcc[y].nick);
  1012. botnet_send_unlinked (y, dcc[y].nick, s);
  1013. chatout ("*** %s\n", s);
  1014. if (y != idx)
  1015. {
  1016. killsock (dcc[y].sock);
  1017. lostdcc (y);
  1018. }
  1019. killsock (dcc[idx].sock);
  1020. lostdcc (idx);
  1021. return;
  1022. }
  1023. else if (!strcmp (dcc[idx].nick, "*binary"))
  1024. {
  1025. int x, y = 0;
  1026. for (x = 0; x < dcc_total; x++)
  1027. if (!egg_strcasecmp (dcc[x].nick, dcc[idx].host)
  1028. && (dcc[x].type->flags & DCT_BOT))
  1029. y = x;
  1030. putlog (LOG_BOTS, "*", "Lost binary transfer; aborting.");
  1031. xnick[0] = 0;
  1032. dcc[y].status &= ~STAT_SENDINGU;
  1033. #ifdef HUB
  1034. bupdating = 0;
  1035. #endif
  1036. killsock (dcc[idx].sock);
  1037. lostdcc (idx);
  1038. return;
  1039. }
  1040. else
  1041. {
  1042. struct userrec *u;
  1043. egg_snprintf (s, sizeof s, "%s!%s", dcc[idx].nick, dcc[idx].host);
  1044. u = get_user_by_host (s);
  1045. check_tcl_toutlost (u, dcc[idx].nick, dcc[idx].u.xfer->dir,
  1046. dcc[idx].u.xfer->acked, dcc[idx].u.xfer->length,
  1047. H_lost);
  1048. putlog (LOG_FILES, "*", TRANSFER_LOST_DCCGET, dcc[idx].u.xfer->origname,
  1049. dcc[idx].nick, dcc[idx].host);
  1050. wipe_tmp_filename (dcc[idx].u.xfer->filename, idx);
  1051. strcpy (xnick, dcc[idx].nick);
  1052. }
  1053. killsock (dcc[idx].sock);
  1054. lostdcc (idx);
  1055. if (!at_limit (xnick))
  1056. send_next_file (xnick);
  1057. }
  1058. static void
  1059. dcc_send (int idx, char *buf, int len)
  1060. {
  1061. char s[512], *b;
  1062. unsigned long sent;
  1063. fwrite (buf, len, 1, dcc[idx].u.xfer->f);
  1064. dcc[idx].status += len;
  1065. sent = dcc[idx].status;
  1066. s[0] = (sent / (1 << 24));
  1067. s[1] = (sent % (1 << 24)) / (1 << 16);
  1068. s[2] = (sent % (1 << 16)) / (1 << 8);
  1069. s[3] = (sent % (1 << 8));
  1070. tputs (dcc[idx].sock, s, 4);
  1071. dcc[idx].timeval = now;
  1072. if (dcc[idx].status > dcc[idx].u.xfer->length
  1073. && dcc[idx].u.xfer->length > 0)
  1074. {
  1075. dprintf (DP_HELP, TRANSFER_BOGUS_FILE_LENGTH, dcc[idx].nick);
  1076. putlog (LOG_FILES, "*", TRANSFER_FILE_TOO_LONG,
  1077. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
  1078. fclose (dcc[idx].u.xfer->f);
  1079. b = nmalloc (strlen (tempdir) + strlen (dcc[idx].u.xfer->filename) + 1);
  1080. sprintf (b, "%s%s", tempdir, dcc[idx].u.xfer->filename);
  1081. unlink (b);
  1082. nfree (b);
  1083. killsock (dcc[idx].sock);
  1084. lostdcc (idx);
  1085. }
  1086. }
  1087. static void
  1088. transfer_get_timeout (int i)
  1089. {
  1090. char xx[1024];
  1091. fclose (dcc[i].u.xfer->f);
  1092. if (strcmp (dcc[i].nick, "*users") == 0)
  1093. {
  1094. int x, y = 0;
  1095. for (x = 0; x < dcc_total; x++)
  1096. if ((!egg_strcasecmp (dcc[x].nick, dcc[i].host))
  1097. && (dcc[x].type->flags & DCT_BOT))
  1098. y = x;
  1099. if (y != 0)
  1100. {
  1101. dcc[y].status &= ~STAT_SENDING;
  1102. dcc[y].status &= ~STAT_SHARE;
  1103. }
  1104. unlink (dcc[i].u.xfer->filename);
  1105. putlog (LOG_BOTS, "*", TRANSFER_USERFILE_TIMEOUT);
  1106. dprintf (y, "bye\n");
  1107. egg_snprintf (xx, sizeof xx, TRANSFER_DICONNECT_TIMEOUT, dcc[y].nick);
  1108. botnet_send_unlinked (y, dcc[y].nick, xx);
  1109. chatout ("*** %s\n", xx);
  1110. if (y < i)
  1111. {
  1112. int t = y;
  1113. y = i;
  1114. i = t;
  1115. }
  1116. killsock (dcc[y].sock);
  1117. lostdcc (y);
  1118. xx[0] = 0;
  1119. }
  1120. else if (strcmp (dcc[i].nick, "*binary") == 0)
  1121. {
  1122. int x, y = 0;
  1123. for (x = 0; x < dcc_total; x++)
  1124. if ((!egg_strcasecmp (dcc[x].nick, dcc[i].host))
  1125. && (dcc[x].type->flags & DCT_BOT))
  1126. y = x;
  1127. if (y != 0)
  1128. {
  1129. dcc[y].status &= ~STAT_SENDINGU;
  1130. }
  1131. putlog (LOG_BOTS, "*", "Timeout on binary transfer.");
  1132. dprintf (y, "bye\n");
  1133. egg_snprintf (xx, sizeof xx,
  1134. "Disconnected %s (timed-out binary transfer)",
  1135. dcc[y].nick);
  1136. botnet_send_unlinked (y, dcc[y].nick, xx);
  1137. chatout ("*** %s\n", xx);
  1138. if (y < i)
  1139. {
  1140. int t = y;
  1141. y = i;
  1142. i = t;
  1143. }
  1144. killsock (dcc[y].sock);
  1145. lostdcc (y);
  1146. xx[0] = 0;
  1147. }
  1148. else
  1149. {
  1150. char *p;
  1151. struct userrec *u;
  1152. p = strrchr (dcc[i].u.xfer->origname, '/');
  1153. dprintf (DP_HELP, TRANSFER_NOTICE_TIMEOUT, dcc[i].nick,
  1154. p ? p + 1 : dcc[i].u.xfer->origname);
  1155. egg_snprintf (xx, sizeof xx, "%s!%s", dcc[i].nick, dcc[i].host);
  1156. u = get_user_by_host (xx);
  1157. check_tcl_toutlost (u, dcc[i].nick, dcc[i].u.xfer->dir,
  1158. dcc[i].u.xfer->acked, dcc[i].u.xfer->length,
  1159. H_tout);
  1160. putlog (LOG_FILES, "*", TRANSFER_DCC_GET_TIMEOUT,
  1161. p ? p + 1 : dcc[i].u.xfer->origname, dcc[i].nick, dcc[i].status,
  1162. dcc[i].u.xfer->length);
  1163. wipe_tmp_filename (dcc[i].u.xfer->filename, i);
  1164. strcpy (xx, dcc[i].nick);
  1165. }
  1166. killsock (dcc[i].sock);
  1167. lostdcc (i);
  1168. if (!at_limit (xx))
  1169. send_next_file (xx);
  1170. }
  1171. static void
  1172. tout_dcc_send (int idx)
  1173. {
  1174. if (!strcmp (dcc[idx].nick, "*users"))
  1175. {
  1176. int x, y = 0;
  1177. for (x = 0; x < dcc_total; x++)
  1178. if (!egg_strcasecmp (dcc[x].nick, dcc[idx].host)
  1179. && (dcc[x].type->flags & DCT_BOT))
  1180. y = x;
  1181. if (y != 0)
  1182. {
  1183. dcc[y].status &= ~STAT_GETTING;
  1184. dcc[y].status &= ~STAT_SHARE;
  1185. }
  1186. unlink (dcc[idx].u.xfer->filename);
  1187. putlog (LOG_BOTS, "*", TRANSFER_USERFILE_TIMEOUT);
  1188. }
  1189. else if (!strcmp (dcc[idx].nick, "*binary"))
  1190. {
  1191. int x, y = 0;
  1192. for (x = 0; x < dcc_total; x++)
  1193. if (!egg_strcasecmp (dcc[x].nick, dcc[idx].host)
  1194. && (dcc[x].type->flags & DCT_BOT))
  1195. y = x;
  1196. if (y != 0)
  1197. {
  1198. dcc[y].status &= ~STAT_GETTINGU;
  1199. }
  1200. putlog (LOG_BOTS, "*", "Timeout on binary transfer.");
  1201. }
  1202. else
  1203. {
  1204. char *buf;
  1205. dprintf (DP_HELP, TRANSFER_NOTICE_TIMEOUT, dcc[idx].nick,
  1206. dcc[idx].u.xfer->origname);
  1207. putlog (LOG_FILES, "*", TRANSFER_DCC_SEND_TIMEOUT,
  1208. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].status,
  1209. dcc[idx].u.xfer->length);
  1210. buf =
  1211. nmalloc (strlen (tempdir) + strlen (dcc[idx].u.xfer->filename) + 1);
  1212. sprintf (buf, "%s%s", tempdir, dcc[idx].u.xfer->filename);
  1213. unlink (buf);
  1214. nfree (buf);
  1215. } killsock (dcc[idx].sock);
  1216. lostdcc (idx);
  1217. } static void
  1218. display_dcc_get (int idx, char *buf)
  1219. {
  1220. if (dcc[idx].status == dcc[idx].u.xfer->length)
  1221. sprintf (buf, TRANSFER_SEND, dcc[idx].u.xfer->acked,
  1222. dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
  1223. else
  1224. sprintf (buf, TRANSFER_SEND, dcc[idx].status, dcc[idx].u.xfer->length,
  1225. dcc[idx].u.xfer->origname);
  1226. }
  1227. static void
  1228. display_dcc_get_p (int idx, char *buf)
  1229. {
  1230. sprintf (buf, TRANSFER_SEND_WAITED, now - dcc[idx].timeval,
  1231. dcc[idx].u.xfer->origname);
  1232. } static void
  1233. display_dcc_send (int idx, char *buf)
  1234. {
  1235. Context;
  1236. sprintf (buf, TRANSFER_SEND, dcc[idx].status, dcc[idx].u.xfer->length,
  1237. dcc[idx].u.xfer->origname);
  1238. } static void
  1239. display_dcc_fork_send (int idx, char *buf)
  1240. {
  1241. sprintf (buf, TRANSFER_CONN_SEND);
  1242. } static int
  1243. expmem_dcc_xfer (void *x)
  1244. {
  1245. register struct xfer_info *p = (struct xfer_info *) x;
  1246. int tot;
  1247. tot = sizeof (struct xfer_info);
  1248. if (p->filename)
  1249. tot += strlen (p->filename) + 1;
  1250. if (p->origname && p->filename != p->origname)
  1251. tot += strlen (p->origname) + 1;
  1252. return tot;
  1253. }
  1254. static void
  1255. kill_dcc_xfer (int idx, void *x)
  1256. {
  1257. register struct xfer_info *p = (struct xfer_info *) x;
  1258. if (p->filename)
  1259. nfree (p->filename);
  1260. if (p->origname && p->origname != p->filename)
  1261. nfree (p->origname);
  1262. nfree (x);
  1263. }
  1264. static void
  1265. out_dcc_xfer (int idx, char *buf, void *x)
  1266. {
  1267. } static void
  1268. outdone_dcc_xfer (int idx)
  1269. {
  1270. if (dcc[idx].u.xfer->block_pending)
  1271. dcc[idx].u.xfer->block_pending =
  1272. pump_file_to_sock (dcc[idx].u.xfer->f, dcc[idx].sock,
  1273. dcc[idx].u.xfer->block_pending);
  1274. }
  1275. static struct dcc_table DCC_SEND =
  1276. { "SEND", DCT_FILETRAN | DCT_FILESEND | DCT_VALIDIDX, eof_dcc_send,
  1277. dcc_send, &wait_dcc_xfer, tout_dcc_send, display_dcc_send, expmem_dcc_xfer, kill_dcc_xfer, out_dcc_xfer };
  1278. static void dcc_fork_send (int idx, char *x, int y);
  1279. static struct dcc_table DCC_FORK_SEND =
  1280. { "FORK_SEND", DCT_FILETRAN | DCT_FORKTYPE | DCT_FILESEND | DCT_VALIDIDX,
  1281. eof_dcc_fork_send, dcc_fork_send, &wait_dcc_xfer, eof_dcc_fork_send, display_dcc_fork_send, expmem_dcc_xfer,
  1282. kill_dcc_xfer, out_dcc_xfer };
  1283. static void
  1284. dcc_fork_send (int idx, char *x, int y)
  1285. {
  1286. char s1[121];
  1287. if (dcc[idx].type != &DCC_FORK_SEND)
  1288. return;
  1289. dcc[idx].type = &DCC_SEND;
  1290. dcc[idx].u.xfer->start_time = now;
  1291. egg_snprintf (s1, sizeof s1, "%s!%s", dcc[idx].nick, dcc[idx].host);
  1292. if (strcmp (dcc[idx].nick, "*users") && strcmp (dcc[idx].nick, "*binary"))
  1293. putlog (LOG_MISC, "*", TRANSFER_DCC_CONN, dcc[idx].u.xfer->origname, s1);
  1294. }
  1295. static struct dcc_table DCC_GET =
  1296. { "GET", DCT_FILETRAN | DCT_VALIDIDX, eof_dcc_get, dcc_get, &wait_dcc_xfer,
  1297. transfer_get_timeout, display_dcc_get, expmem_dcc_xfer, kill_dcc_xfer, out_dcc_xfer, outdone_dcc_xfer };
  1298. static struct dcc_table DCC_GET_PENDING =
  1299. { "GET_PENDING", DCT_FILETRAN | DCT_VALIDIDX, eof_dcc_get, dcc_get_pending,
  1300. &wait_dcc_xfer, transfer_get_timeout, display_dcc_get_p, expmem_dcc_xfer, kill_dcc_xfer, out_dcc_xfer };
  1301. static void
  1302. dcc_get_pending (int idx, char *buf, int len)
  1303. {
  1304. unsigned long ip;
  1305. unsigned short port;
  1306. int i;
  1307. char s[UHOSTLEN];
  1308. i = answer (dcc[idx].sock, s, &ip, &port, 1);
  1309. killsock (dcc[idx].sock);
  1310. dcc[idx].sock = i;
  1311. dcc[idx].addr = ip;
  1312. dcc[idx].port = (int) port;
  1313. if (dcc[idx].sock == -1)
  1314. {
  1315. neterror (s);
  1316. dprintf (DP_HELP, TRANSFER_NOTICE_BAD_CONN, dcc[idx].nick, s);
  1317. putlog (LOG_FILES, "*", TRANSFER_LOG_BAD_CONN,
  1318. dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
  1319. fclose (dcc[idx].u.xfer->f);
  1320. lostdcc (idx);
  1321. return;
  1322. }
  1323. dcc[idx].type = &DCC_GET;
  1324. dcc[idx].u.xfer->ack_type = XFER_ACK_UNKNOWN;
  1325. if (dcc[idx].u.xfer->type == XFER_RESUME_PEND)
  1326. {
  1327. int l;
  1328. if (dcc_block == 0 || dcc[idx].u.xfer->length < dcc_block)
  1329. {
  1330. l = dcc[idx].u.xfer->length - dcc[idx].u.xfer->offset;
  1331. dcc[idx].status = dcc[idx].u.xfer->length;
  1332. }
  1333. else
  1334. {
  1335. l = dcc_block;
  1336. dcc[idx].status = dcc[idx].u.xfer->offset + dcc_block;
  1337. }
  1338. fseek (dcc[idx].u.xfer->f, dcc[idx].u.xfer->offset, SEEK_SET);
  1339. dcc[idx].u.xfer->block_pending =
  1340. pump_file_to_sock (dcc[idx].u.xfer->f, dcc[idx].sock, l);
  1341. dcc[idx].u.xfer->type = XFER_RESUME;
  1342. }
  1343. else
  1344. {
  1345. dcc[idx].u.xfer->offset = 0;
  1346. if (dcc[idx].u.xfer->type != XFER_RESEND_PEND)
  1347. {
  1348. if (dcc_block == 0 || dcc[idx].u.xfer->length < dcc_block)
  1349. dcc[idx].status = dcc[idx].u.xfer->length;
  1350. else
  1351. dcc[idx].status = dcc_block;
  1352. dcc[idx].u.xfer->block_pending =
  1353. pump_file_to_sock (dcc[idx].u.xfer->f, dcc[idx].sock,
  1354. dcc[idx].status);
  1355. }
  1356. else
  1357. dcc[idx].status = 0;
  1358. }
  1359. dcc[idx].timeval = dcc[idx].u.xfer->start_time = now;
  1360. }
  1361. static int
  1362. raw_dcc_resend_send (char *filename, char *nick, char *from, char *dir,
  1363. int resend)
  1364. {
  1365. int zz, port, i;
  1366. char *nfn, *buf = NULL;
  1367. long dccfilesize;
  1368. FILE *f, *dccfile;
  1369. zz = (-1);
  1370. dccfile = fopen (filename, "r");
  1371. fseek (dccfile, 0, SEEK_END);
  1372. dccfilesize = ftell (dccfile);
  1373. fclose (dccfile);
  1374. if (dccfilesize == 0)
  1375. return DCCSEND_FEMPTY;
  1376. if (reserved_port_min > 0 && reserved_port_min < reserved_port_max)
  1377. {
  1378. for (port = reserved_port_min; port <= reserved_port_max; port++)
  1379. {
  1380. zz = open_listen (&port);
  1381. if (zz != (-1))
  1382. break;
  1383. }
  1384. }
  1385. else
  1386. {
  1387. port = reserved_port_min;
  1388. zz = open_listen (&port);
  1389. }
  1390. if (zz == (-1))
  1391. return DCCSEND_NOSOCK;
  1392. nfn = strrchr (dir, '/');
  1393. if (nfn == NULL)
  1394. nfn = dir;
  1395. else
  1396. nfn++;
  1397. f = fopen (filename, "r");
  1398. if (!f)
  1399. return DCCSEND_BADFN;
  1400. if ((i = new_dcc (&DCC_GET_PENDING, sizeof (struct xfer_info))) == -1)
  1401. return DCCSEND_FULL;
  1402. dcc[i].sock = zz;
  1403. dcc[i].addr = (IP) (-559026163);
  1404. dcc[i].port = port;
  1405. strcpy (dcc[i].nick, nick);
  1406. strcpy (dcc[i].host, "irc");
  1407. dcc[i].u.xfer->filename = get_data_ptr (strlen (filename) + 1);
  1408. strcpy (dcc[i].u.xfer->filename, filename);
  1409. if (strchr (nfn, ' '))
  1410. nfn = buf = replace_spaces (nfn);
  1411. dcc[i].u.xfer->origname = get_data_ptr (strlen (nfn) + 1);
  1412. strcpy (dcc[i].u.xfer->origname, nfn);
  1413. strncpyz (dcc[i].u.xfer->from, from, NICKLEN);
  1414. strncpyz (dcc[i].u.xfer->dir, dir, DIRLEN);
  1415. dcc[i].u.xfer->length = dccfilesize;
  1416. dcc[i].timeval = now;
  1417. dcc[i].u.xfer->f = f;
  1418. dcc[i].u.xfer->type = resend ? XFER_RESEND_PEND : XFER_SEND;
  1419. if (nick[0] != '*')
  1420. {
  1421. dprintf (DP_HELP, "PRIVMSG %s :\001DCC %sSEND %s %lu %d %lu\001\n",
  1422. nick, resend ? "RE" : "", nfn,
  1423. iptolong (natip[0] ? (IP) inet_addr (natip) : getmyip ()),
  1424. port, dccfilesize);
  1425. putlog (LOG_FILES, "*", TRANSFER_BEGIN_DCC, resend ? TRANSFER_RE : "",
  1426. nfn, nick);
  1427. }
  1428. if (buf)
  1429. nfree (buf);
  1430. return DCCSEND_OK;
  1431. }
  1432. static int
  1433. raw_dcc_resend (char *filename, char *nick, char *from, char *dir)
  1434. {
  1435. return raw_dcc_resend_send (filename, nick, from, dir, 1);
  1436. }
  1437. static int
  1438. raw_dcc_send (char *filename, char *nick, char *from, char *dir)
  1439. {
  1440. return raw_dcc_resend_send (filename, nick, from, dir, 0);
  1441. }
  1442. static tcl_ints myints[] =
  1443. { {"max-dloads", &dcc_limit}, {"dcc-block", &dcc_block}, {"copy-to-tmp",
  1444. &copy_to_tmp},
  1445. {"xfer-timeout", &wait_dcc_xfer}, {NULL, NULL} };
  1446. static int
  1447. fstat_unpack (struct userrec *u, struct user_entry *e)
  1448. {
  1449. char *par, *arg;
  1450. struct filesys_stats *fs;
  1451. fs = user_malloc (sizeof (struct filesys_stats));
  1452. egg_bzero (fs, sizeof (struct filesys_stats));
  1453. par = e->u.list->extra;
  1454. arg = newsplit (&par);
  1455. if (arg[0])
  1456. fs->uploads = atoi (arg);
  1457. arg = newsplit (&par);
  1458. if (arg[0])
  1459. fs->upload_ks = atoi (arg);
  1460. arg = newsplit (&par);
  1461. if (arg[0])
  1462. fs->dnloads = atoi (arg);
  1463. arg = newsplit (&par);
  1464. if (arg[0])
  1465. fs->dnload_ks = atoi (arg);
  1466. list_type_kill (e->u.list);
  1467. e->u.extra = fs;
  1468. return 1;
  1469. }
  1470. static int
  1471. fstat_pack (struct userrec *u, struct user_entry *e)
  1472. {
  1473. register struct filesys_stats *fs;
  1474. struct list_type *l = user_malloc (sizeof (struct list_type));
  1475. fs = e->u.extra;
  1476. l->extra = user_malloc (41);
  1477. egg_snprintf (l->extra, 41, "%09u %09u %09u %09u", fs->uploads,
  1478. fs->upload_ks, fs->dnloads, fs->dnload_ks);
  1479. l->next = NULL;
  1480. e->u.list = l;
  1481. nfree (fs);
  1482. return 1;
  1483. }
  1484. static int
  1485. fstat_write_userfile (FILE * f, struct userrec *u, struct user_entry *e)
  1486. {
  1487. register struct filesys_stats *fs;
  1488. fs = e->u.extra;
  1489. if (lfprintf
  1490. (f, "--FSTAT %09u %09u %09u %09u\n", fs->uploads, fs->upload_ks,
  1491. fs->dnloads, fs->dnload_ks) == EOF)
  1492. return 0;
  1493. return 1;
  1494. }
  1495. static int
  1496. fstat_set (struct userrec *u, struct user_entry *e, void *buf)
  1497. {
  1498. register struct filesys_stats *fs = buf;
  1499. if (e->u.extra != fs)
  1500. {
  1501. if (e->u.extra)
  1502. nfree (e->u.extra);
  1503. e->u.extra = fs;
  1504. }
  1505. else if (!fs)
  1506. return 1;
  1507. if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
  1508. {
  1509. if (fs)
  1510. shareout (NULL, "ch fstat %09u %09u %09u %09u\n", fs->uploads,
  1511. fs->upload_ks, fs->dnloads, fs->dnload_ks);
  1512. else
  1513. shareout (NULL, "ch fstat r\n");
  1514. }
  1515. return 1;
  1516. }
  1517. static int
  1518. fstat_tcl_get (Tcl_Interp * irp, struct userrec *u, struct user_entry *e,
  1519. int argc, char **argv)
  1520. {
  1521. register struct filesys_stats *fs;
  1522. char d[50];
  1523. BADARGS (3, 4, " handle FSTAT ?u/d?");
  1524. fs = e->u.extra;
  1525. if (argc == 3)
  1526. egg_snprintf (d, sizeof d, "%u %u %u %u", fs->uploads, fs->upload_ks,
  1527. fs->dnloads, fs->dnload_ks);
  1528. else
  1529. switch (argv[3][0])
  1530. {
  1531. case 'u':
  1532. egg_snprintf (d, sizeof d, "%u %u", fs->uploads, fs->upload_ks);
  1533. break;
  1534. case 'd':
  1535. egg_snprintf (d, sizeof d, "%u %u", fs->dnloads, fs->dnload_ks);
  1536. break;
  1537. }
  1538. Tcl_AppendResult (irp, d, NULL);
  1539. return TCL_OK;
  1540. }
  1541. static int
  1542. fstat_kill (struct user_entry *e)
  1543. {
  1544. if (e->u.extra)
  1545. nfree (e->u.extra);
  1546. nfree (e);
  1547. return 1;
  1548. }
  1549. static int
  1550. fstat_expmem (struct user_entry *e)
  1551. {
  1552. return sizeof (struct filesys_stats);
  1553. } static void
  1554. fstat_display (int idx, struct user_entry *e)
  1555. {
  1556. struct filesys_stats *fs;
  1557. fs = e->u.extra;
  1558. dprintf (idx, " FILES: %u download%s (%luk), %u upload%s (%luk)\n",
  1559. fs->dnloads, (fs->dnloads == 1) ? "" : "s", fs->dnload_ks,
  1560. fs->uploads, (fs->uploads == 1) ? "" : "s", fs->upload_ks);
  1561. } static int fstat_gotshare (struct userrec *u, struct user_entry *e,
  1562. char *par, int idx);
  1563. static int fstat_dupuser (struct userrec *u, struct userrec *o,
  1564. struct user_entry *e);
  1565. static void stats_add_dnload (struct userrec *u, unsigned long bytes);
  1566. static void stats_add_upload (struct userrec *u, unsigned long bytes);
  1567. static int fstat_tcl_set (Tcl_Interp * irp, struct userrec *u,
  1568. struct user_entry *e, int argc, char **argv);
  1569. static struct user_entry_type USERENTRY_FSTAT =
  1570. { NULL, fstat_gotshare, fstat_dupuser, fstat_unpack, fstat_pack,
  1571. fstat_write_userfile, fstat_kill, NULL, fstat_set, fstat_tcl_get, fstat_tcl_set, fstat_expmem, fstat_display, "FSTAT" };
  1572. static int
  1573. fstat_gotshare (struct userrec *u, struct user_entry *e, char *par, int idx)
  1574. {
  1575. char *p;
  1576. struct filesys_stats *fs;
  1577. noshare = 1;
  1578. switch (par[0])
  1579. {
  1580. case 'u':
  1581. case 'd':
  1582. break;
  1583. case 'r':
  1584. set_user (&USERENTRY_FSTAT, u, NULL);
  1585. break;
  1586. default:
  1587. if (!(fs = e->u.extra))
  1588. {
  1589. fs = user_malloc (sizeof (struct filesys_stats));
  1590. egg_bzero (fs, sizeof (struct filesys_stats));
  1591. }
  1592. p = newsplit (&par);
  1593. if (p[0])
  1594. fs->uploads = atoi (p);
  1595. p = newsplit (&par);
  1596. if (p[0])
  1597. fs->upload_ks = atoi (p);
  1598. p = newsplit (&par);
  1599. if (p[0])
  1600. fs->dnloads = atoi (p);
  1601. p = newsplit (&par);
  1602. if (p[0])
  1603. fs->dnload_ks = atoi (p);
  1604. set_user (&USERENTRY_FSTAT, u, fs);
  1605. break;
  1606. }
  1607. noshare = 0;
  1608. return 1;
  1609. }
  1610. static int
  1611. fstat_dupuser (struct userrec *u, struct userrec *o, struct user_entry *e)
  1612. {
  1613. struct filesys_stats *fs;
  1614. if (e->u.extra)
  1615. {
  1616. fs = user_malloc (sizeof (struct filesys_stats));
  1617. my_memcpy (fs, e->u.extra, sizeof (struct filesys_stats));
  1618. return set_user (&USERENTRY_FSTAT, u, fs);
  1619. }
  1620. return 0;
  1621. }
  1622. static void
  1623. stats_add_dnload (struct userrec *u, unsigned long bytes)
  1624. {
  1625. struct user_entry *ue;
  1626. register struct filesys_stats *fs;
  1627. if (u)
  1628. {
  1629. if (!(ue = find_user_entry (&USERENTRY_FSTAT, u))
  1630. || !(fs = ue->u.extra))
  1631. {
  1632. fs = user_malloc (sizeof (struct filesys_stats));
  1633. egg_bzero (fs, sizeof (struct filesys_stats));
  1634. }
  1635. fs->dnloads++;
  1636. fs->dnload_ks += ((bytes + 512) / 1024);
  1637. set_user (&USERENTRY_FSTAT, u, fs);
  1638. }
  1639. } static void
  1640. stats_add_upload (struct userrec *u, unsigned long bytes)
  1641. {
  1642. struct user_entry *ue;
  1643. register struct filesys_stats *fs;
  1644. if (u)
  1645. {
  1646. if (!(ue = find_user_entry (&USERENTRY_FSTAT, u))
  1647. || !(fs = ue->u.extra))
  1648. {
  1649. fs = user_malloc (sizeof (struct filesys_stats));
  1650. egg_bzero (fs, sizeof (struct filesys_stats));
  1651. }
  1652. fs->uploads++;
  1653. fs->upload_ks += ((bytes + 512) / 1024);
  1654. set_user (&USERENTRY_FSTAT, u, fs);
  1655. }
  1656. } static int
  1657. fstat_tcl_set (Tcl_Interp * irp, struct userrec *u, struct user_entry *e,
  1658. int argc, char **argv)
  1659. {
  1660. register struct filesys_stats *fs;
  1661. int f = 0, k = 0;
  1662. BADARGS (4, 6, " handle FSTAT u/d ?files ?ks??");
  1663. if (argc > 4)
  1664. f = atoi (argv[4]);
  1665. if (argc > 5)
  1666. k = atoi (argv[5]);
  1667. switch (argv[3][0])
  1668. {
  1669. case 'u':
  1670. case 'd':
  1671. if (!(fs = e->u.extra))
  1672. {
  1673. fs = user_malloc (sizeof (struct filesys_stats));
  1674. egg_bzero (fs, sizeof (struct filesys_stats));
  1675. }
  1676. switch (argv[3][0])
  1677. {
  1678. case 'u':
  1679. fs->uploads = f;
  1680. fs->upload_ks = k;
  1681. break;
  1682. case 'd':
  1683. fs->dnloads = f;
  1684. fs->dnload_ks = k;
  1685. break;
  1686. }
  1687. set_user (&USERENTRY_FSTAT, u, fs);
  1688. break;
  1689. case 'r':
  1690. set_user (&USERENTRY_FSTAT, u, NULL);
  1691. break;
  1692. }
  1693. return TCL_OK;
  1694. }
  1695. static int
  1696. ctcp_DCC_RESUME (char *nick, char *from, char *handle, char *object,
  1697. char *keyword, char *text)
  1698. {
  1699. char *action, *fn, buf[512], *msg = buf;
  1700. int i, port;
  1701. unsigned long offset;
  1702. strcpy (msg, text);
  1703. action = newsplit (&msg);
  1704. if (egg_strcasecmp (action, "RESUME"))
  1705. return 0;
  1706. fn = newsplit (&msg);
  1707. port = atoi (newsplit (&msg));
  1708. offset = my_atoul (newsplit (&msg));
  1709. for (i = 0; i < dcc_total; i++)
  1710. if ((dcc[i].type == &DCC_GET_PENDING)
  1711. && (!rfc_casecmp (dcc[i].nick, nick)) && (dcc[i].port == port))
  1712. break;
  1713. if (i == dcc_total)
  1714. return 0;
  1715. if (dcc[i].u.xfer->length <= offset)
  1716. {
  1717. char *p = strrchr (dcc[i].u.xfer->origname, '/');
  1718. dprintf (DP_HELP, TRANSFER_DCC_IGNORED, nick,
  1719. p ? p + 1 : dcc[i].u.xfer->origname);
  1720. return 0;
  1721. }
  1722. dcc[i].u.xfer->type = XFER_RESUME_PEND;
  1723. dcc[i].u.xfer->offset = offset;
  1724. dprintf (DP_HELP, "PRIVMSG %s :\001DCC ACCEPT %s %d %u\001\n", nick, fn,
  1725. port, offset);
  1726. return 1;
  1727. }
  1728. static cmd_t transfer_ctcps[] =
  1729. { {"DCC", "", ctcp_DCC_RESUME, "transfer:DCC"}, {NULL, NULL, NULL, NULL} };
  1730. static int
  1731. server_transfer_setup (char *mod)
  1732. {
  1733. p_tcl_bind_list H_ctcp;
  1734. if ((H_ctcp = find_bind_table ("ctcp")))
  1735. add_builtins (H_ctcp, transfer_ctcps);
  1736. return 1;
  1737. }
  1738. static cmd_t transfer_load[] =
  1739. { {"server", "", server_transfer_setup, NULL}, {NULL, "", NULL, NULL} };
  1740. static char *
  1741. transfer_close ()
  1742. {
  1743. int i;
  1744. p_tcl_bind_list H_ctcp;
  1745. Context;
  1746. putlog (LOG_MISC, "*", TRANSFER_UNLOADING);
  1747. for (i = dcc_total - 1; i >= 0; i--)
  1748. {
  1749. if (dcc[i].type == &DCC_GET || dcc[i].type == &DCC_GET_PENDING)
  1750. eof_dcc_get (i);
  1751. else if (dcc[i].type == &DCC_SEND)
  1752. eof_dcc_send (i);
  1753. else if (dcc[i].type == &DCC_FORK_SEND)
  1754. eof_dcc_fork_send (i);
  1755. }
  1756. while (fileq)
  1757. deq_this (fileq);
  1758. del_entry_type (&USERENTRY_FSTAT);
  1759. del_bind_table (H_rcvd);
  1760. del_bind_table (H_sent);
  1761. del_bind_table (H_lost);
  1762. del_bind_table (H_tout);
  1763. rem_builtins (H_load, transfer_load);
  1764. if ((H_ctcp = find_bind_table ("ctcp")))
  1765. rem_builtins (H_ctcp, transfer_ctcps);
  1766. rem_tcl_commands (mytcls);
  1767. rem_tcl_ints (myints);
  1768. del_lang_section ("transfer");
  1769. module_undepend (MODULE_NAME);
  1770. return NULL;
  1771. }
  1772. static int
  1773. transfer_expmem ()
  1774. {
  1775. return expmem_fileq ();
  1776. }
  1777. static void
  1778. transfer_report (int idx, int details)
  1779. {
  1780. if (details)
  1781. {
  1782. dprintf (idx, TRANSFER_STAT_BLOCK, dcc_block,
  1783. (dcc_block == 0) ? " (turbo dcc)" : "", dcc_limit);
  1784. dprintf (idx, TRANSFER_STAT_MEMORY, transfer_expmem ());
  1785. }
  1786. }
  1787. EXPORT_SCOPE char *transfer_start ();
  1788. static Function transfer_table[] =
  1789. { (Function) transfer_start, (Function) transfer_close,
  1790. (Function) transfer_expmem, (Function) transfer_report, (Function) & DCC_FORK_SEND, (Function) at_limit,
  1791. (Function) & copy_to_tmp, (Function) fileq_cancel, (Function) queue_file, (Function) raw_dcc_send,
  1792. (Function) show_queued_files, (Function) wild_match_file, (Function) wipe_tmp_filename,
  1793. (Function) & DCC_GET, (Function) & H_rcvd, (Function) & H_sent, (Function) & USERENTRY_FSTAT,
  1794. (Function) & quiet_reject, (Function) raw_dcc_resend, (Function) & H_lost, (Function) & H_tout, };
  1795. char *
  1796. transfer_start (Function * global_funcs)
  1797. {
  1798. global = global_funcs;
  1799. fileq = NULL;
  1800. module_register (MODULE_NAME, transfer_table, 2, 2);
  1801. if (!(update_funcs = module_depend (MODULE_NAME, "update", 0, 0)))
  1802. {
  1803. module_undepend (MODULE_NAME);
  1804. return "This module requires update module 0.0 or later.";
  1805. }
  1806. add_tcl_commands (mytcls);
  1807. add_tcl_ints (myints);
  1808. add_builtins (H_load, transfer_load);
  1809. server_transfer_setup (NULL);
  1810. H_rcvd = add_bind_table ("rcvd", HT_STACKABLE, builtin_sentrcvd);
  1811. H_sent = add_bind_table ("sent", HT_STACKABLE, builtin_sentrcvd);
  1812. H_lost = add_bind_table ("lost", HT_STACKABLE, builtin_toutlost);
  1813. H_tout = add_bind_table ("tout", HT_STACKABLE, builtin_toutlost);
  1814. USERENTRY_FSTAT.get = def_get;
  1815. add_entry_type (&USERENTRY_FSTAT);
  1816. add_lang_section ("transfer");
  1817. return NULL;
  1818. }