share.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. /*
  2. * share.c -- part of share.mod
  3. *
  4. */
  5. #include "src/common.h"
  6. #include "src/main.h"
  7. #include "src/rfc1459.h"
  8. #include "src/botmsg.h"
  9. #include "src/misc.h"
  10. #include "src/misc_file.h"
  11. #include "src/cmds.h"
  12. #include "src/chanprog.h"
  13. #include "src/users.h"
  14. #include "src/userrec.h"
  15. #include "src/botnet.h"
  16. #include "src/auth.h"
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <sys/stat.h>
  20. #include <stdarg.h>
  21. #include "src/chan.h"
  22. #include "src/net.h"
  23. #include "src/users.h"
  24. #include "src/egg_timer.h"
  25. #include "src/mod/transfer.mod/transfer.h"
  26. #include "src/mod/channels.mod/channels.h"
  27. #include "src/mod/irc.mod/irc.h"
  28. static struct flag_record fr = { 0, 0, 0, 0 };
  29. struct delay_mode {
  30. struct delay_mode *next;
  31. struct chanset_t *chan;
  32. int plsmns;
  33. int mode;
  34. int seconds;
  35. char *mask;
  36. };
  37. static struct delay_mode *start_delay = NULL;
  38. /* Prototypes */
  39. static void start_sending_users(int);
  40. static void shareout_but(int, const char *, ...) __attribute__ ((format(printf, 2, 3)));
  41. static void cancel_user_xfer(int, void *);
  42. #include "share.h"
  43. /*
  44. * Resync buffers
  45. */
  46. /* Store info for sharebots */
  47. struct share_msgq {
  48. struct share_msgq *next;
  49. char *msg;
  50. };
  51. typedef struct tandbuf_t {
  52. struct tandbuf_t *next;
  53. struct share_msgq *q;
  54. time_t timer;
  55. char bot[HANDLEN + 1];
  56. } tandbuf;
  57. tandbuf *tbuf = NULL;
  58. /* Create a tandem buffer for 'bot'.
  59. */
  60. static void new_tbuf(char *bot)
  61. {
  62. tandbuf **old = &tbuf, *newbuf = NULL;
  63. newbuf = (tandbuf *) my_calloc(1, sizeof(tandbuf));
  64. strcpy(newbuf->bot, bot);
  65. newbuf->q = NULL;
  66. newbuf->timer = now;
  67. newbuf->next = *old;
  68. *old = newbuf;
  69. putlog(LOG_BOTS, "*", "Creating resync buffer for %s", bot);
  70. }
  71. static void del_tbuf(tandbuf *goner)
  72. {
  73. struct share_msgq *q = NULL, *r = NULL;
  74. tandbuf *t = NULL, *old = NULL;
  75. for (t = tbuf; t; old = t, t = t->next) {
  76. if (t == goner) {
  77. if (old)
  78. old->next = t->next;
  79. else
  80. tbuf = t->next;
  81. for (q = t->q; q && q->msg[0]; q = r) {
  82. r = q->next;
  83. free(q->msg);
  84. free(q);
  85. }
  86. free(t);
  87. break;
  88. }
  89. }
  90. }
  91. /* Flush a certain bot's tbuf.
  92. */
  93. static bool flush_tbuf(char *bot)
  94. {
  95. tandbuf *t = NULL, *tnext = NULL;
  96. for (t = tbuf; t; t = tnext) {
  97. tnext = t->next;
  98. if (!egg_strcasecmp(t->bot, bot)) {
  99. del_tbuf(t);
  100. return 1;
  101. }
  102. }
  103. return 0;
  104. }
  105. static struct share_msgq *q_addmsg(struct share_msgq *qq, char *s)
  106. {
  107. struct share_msgq *q = NULL;
  108. int cnt;
  109. if (!qq) {
  110. q = (share_msgq *) my_calloc(1, sizeof *q);
  111. q->next = NULL;
  112. q->msg = (char *) my_calloc(1, strlen(s) + 1);
  113. strcpy(q->msg, s);
  114. return q;
  115. }
  116. cnt = 0;
  117. for (q = qq; q->next; q = q->next)
  118. cnt++;
  119. if (cnt > 1000)
  120. return NULL; /* Return null: did not alter queue */
  121. q->next = (share_msgq *) my_calloc(1, sizeof *q->next);
  122. q = q->next;
  123. q->next = NULL;
  124. q->msg = (char *) my_calloc(1, strlen(s) + 1);
  125. strcpy(q->msg, s);
  126. return qq;
  127. }
  128. /* Add stuff to a specific bot's tbuf.
  129. */
  130. static void q_tbuf(char *bot, char *s)
  131. {
  132. struct share_msgq *q = NULL;
  133. tandbuf *t = NULL;
  134. for (t = tbuf; t && t->bot[0]; t = t->next)
  135. if (!egg_strcasecmp(t->bot, bot)) {
  136. if ((q = q_addmsg(t->q, s)))
  137. t->q = q;
  138. break;
  139. }
  140. }
  141. /* Add stuff to the resync buffers.
  142. */
  143. static void q_resync(char *s)
  144. {
  145. struct share_msgq *q = NULL;
  146. tandbuf *t = NULL;
  147. for (t = tbuf; t && t->bot[0]; t = t->next) {
  148. if ((q = q_addmsg(t->q, s)))
  149. t->q = q;
  150. }
  151. }
  152. /* Dump the resync buffer for a bot.
  153. */
  154. void dump_resync(int idx)
  155. {
  156. struct share_msgq *q = NULL;
  157. tandbuf *t = NULL;
  158. for (t = tbuf; t && t->bot[0]; t = t->next)
  159. if (!egg_strcasecmp(dcc[idx].nick, t->bot)) {
  160. for (q = t->q; q && q->msg[0]; q = q->next) {
  161. dprintf(idx, "%s", q->msg);
  162. }
  163. flush_tbuf(dcc[idx].nick);
  164. break;
  165. }
  166. }
  167. /*
  168. * Sup's delay code
  169. */
  170. static void
  171. add_delay(struct chanset_t *chan, int plsmns, int mode, char *mask)
  172. {
  173. struct delay_mode *d = (struct delay_mode *) my_calloc(1, sizeof(struct delay_mode));
  174. d->chan = chan;
  175. d->plsmns = plsmns;
  176. d->mode = mode;
  177. d->mask = (char *) my_calloc(1, strlen(mask) + 1);
  178. strncpy(d->mask, mask, strlen(mask) + 1);
  179. d->seconds = (int) (now + randint(20));
  180. d->next = start_delay;
  181. start_delay = d;
  182. }
  183. static void
  184. del_delay(struct delay_mode *delay)
  185. {
  186. struct delay_mode *old = NULL;
  187. for (struct delay_mode *d = start_delay; d; old = d, d = d->next) {
  188. if (d == delay) {
  189. if (old)
  190. old->next = d->next;
  191. else
  192. start_delay = d->next;
  193. if (d->mask)
  194. free(d->mask);
  195. free(d);
  196. break;
  197. }
  198. }
  199. }
  200. static void
  201. check_delay()
  202. {
  203. struct delay_mode *dnext = NULL;
  204. for (struct delay_mode *d = start_delay; d; d = dnext) {
  205. dnext = d->next;
  206. if (d->seconds <= now) {
  207. add_mode(d->chan, d->plsmns, d->mode, d->mask);
  208. del_delay(d);
  209. }
  210. }
  211. }
  212. /*
  213. * Botnet commands
  214. */
  215. static void
  216. share_stick_ban(int idx, char *par)
  217. {
  218. if (dcc[idx].status & STAT_SHARE) {
  219. char *host = NULL, *val = NULL;
  220. bool yn;
  221. host = newsplit(&par);
  222. val = newsplit(&par);
  223. yn = atoi(val);
  224. noshare = 1;
  225. if (!par[0]) { /* Global ban */
  226. struct chanset_t *chan = NULL;
  227. if (u_setsticky_ban(NULL, host, yn) > 0) {
  228. if (conf.bot->hub)
  229. putlog(LOG_CMDS, "@", "%s: %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host);
  230. shareout_but(idx, "s %s %d\n", host, yn);
  231. }
  232. if (!conf.bot->hub)
  233. for (chan = chanset; chan != NULL; chan = chan->next)
  234. check_this_ban(chan, host, yn);
  235. } else {
  236. struct chanset_t *chan = findchan_by_dname(par);
  237. struct chanuserrec *cr;
  238. if ((chan != NULL) && (cr = get_chanrec(dcc[idx].user, par)))
  239. if (u_setsticky_ban(chan, host, yn) > 0) {
  240. if (conf.bot->hub)
  241. putlog(LOG_CMDS, "@", "%s: %s %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host, par);
  242. shareout_but(idx, "s %s %d %s\n", host, yn, chan->dname);
  243. noshare = 0;
  244. return;
  245. }
  246. if (chan && !conf.bot->hub)
  247. check_this_ban(chan, host, yn);
  248. putlog(LOG_CMDS, "@", "Rejecting invalid sticky ban: %s on %s%s", host, par, yn ? "" : " (unstick)");
  249. }
  250. noshare = 0;
  251. }
  252. }
  253. /* Same as share_stick_ban, only for exempts.
  254. */
  255. static void
  256. share_stick_exempt(int idx, char *par)
  257. {
  258. if (dcc[idx].status & STAT_SHARE) {
  259. char *host = NULL, *val = NULL;
  260. bool yn;
  261. host = newsplit(&par);
  262. val = newsplit(&par);
  263. yn = atoi(val);
  264. noshare = 1;
  265. if (!par[0]) { /* Global exempt */
  266. if (u_setsticky_exempt(NULL, host, yn) > 0) {
  267. if (conf.bot->hub)
  268. putlog(LOG_CMDS, "@", "%s: %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host);
  269. shareout_but(idx, "se %s %d\n", host, yn);
  270. }
  271. } else {
  272. struct chanset_t *chan = findchan_by_dname(par);
  273. struct chanuserrec *cr = NULL;
  274. if ((chan != NULL) && (cr = get_chanrec(dcc[idx].user, par)))
  275. if (u_setsticky_exempt(chan, host, yn) > 0) {
  276. if (conf.bot->hub)
  277. putlog(LOG_CMDS, "@", "%s: stick %s %c %s", dcc[idx].nick, host, yn ? 'y' : 'n', par);
  278. shareout_but(idx, "se %s %d %s\n", host, yn, chan->dname);
  279. noshare = 0;
  280. return;
  281. }
  282. putlog(LOG_CMDS, "@", "Rejecting invalid sticky exempt: %s on %s, %c", host, par, yn ? 'y' : 'n');
  283. }
  284. noshare = 0;
  285. }
  286. }
  287. /* Same as share_stick_ban, only for invites.
  288. */
  289. static void
  290. share_stick_invite(int idx, char *par)
  291. {
  292. if (dcc[idx].status & STAT_SHARE) {
  293. char *host = NULL, *val = NULL;
  294. bool yn;
  295. host = newsplit(&par);
  296. val = newsplit(&par);
  297. yn = atoi(val);
  298. noshare = 1;
  299. if (!par[0]) { /* Global invite */
  300. if (u_setsticky_invite(NULL, host, yn) > 0) {
  301. if (conf.bot->hub)
  302. putlog(LOG_CMDS, "@", "%s: %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host);
  303. shareout_but(idx, "sInv %s %d\n", host, yn);
  304. }
  305. } else {
  306. struct chanset_t *chan = findchan_by_dname(par);
  307. struct chanuserrec *cr = NULL;
  308. if ((chan != NULL) && (cr = get_chanrec(dcc[idx].user, par)))
  309. if (u_setsticky_invite(chan, host, yn) > 0) {
  310. if (conf.bot->hub)
  311. putlog(LOG_CMDS, "@", "%s: %s %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host, par);
  312. shareout_but(idx, "sInv %s %d %s\n", host, yn, chan->dname);
  313. noshare = 0;
  314. return;
  315. }
  316. putlog(LOG_CMDS, "@", "Rejecting invalid sticky invite: %s on %s%s", host, par, yn ? "" : " (unstick)");
  317. }
  318. noshare = 0;
  319. }
  320. }
  321. static void
  322. share_chhand(int idx, char *par)
  323. {
  324. if (dcc[idx].status & STAT_SHARE) {
  325. char *hand = NULL;
  326. struct userrec *u = NULL;
  327. hand = newsplit(&par);
  328. u = get_user_by_handle(userlist, hand);
  329. if (u) {
  330. int value = 0;
  331. shareout_but(idx, "h %s %s\n", hand, par);
  332. noshare = 1;
  333. value = change_handle(u, par);
  334. if (value && conf.bot->hub)
  335. putlog(LOG_CMDS, "@", "%s: handle %s->%s", dcc[idx].nick, hand, par);
  336. noshare = 0;
  337. }
  338. }
  339. }
  340. static void
  341. share_chattr(int idx, char *par)
  342. {
  343. if (dcc[idx].status & STAT_SHARE) {
  344. char *hand = NULL, *atr = NULL, s[100] = "";
  345. struct chanset_t *cst = NULL;
  346. struct userrec *u = NULL;
  347. struct flag_record fr2;
  348. flag_t ofl;
  349. hand = newsplit(&par);
  350. u = get_user_by_handle(userlist, hand);
  351. if (u) {
  352. atr = newsplit(&par);
  353. cst = findchan_by_dname(par);
  354. if (!par[0] || cst) {
  355. if (!(dcc[idx].status & STAT_GETTING))
  356. shareout_but(idx, "a %s %s %s\n", hand, atr, par);
  357. noshare = 1;
  358. if (par[0] && cst) {
  359. fr.match = FR_CHAN;
  360. fr2.match = FR_CHAN;
  361. break_down_flags(atr, &fr, 0);
  362. get_user_flagrec(u, &fr2, par);
  363. set_user_flagrec(u, &fr, par);
  364. check_dcc_chanattrs(u, par, fr.chan, fr2.chan);
  365. noshare = 0;
  366. build_flags(s, &fr, 0);
  367. if (conf.bot->hub) {
  368. if (!(dcc[idx].status & STAT_GETTING))
  369. putlog(LOG_CMDS, "@", "%s: chattr %s %s %s", dcc[idx].nick, hand, s, par);
  370. } else
  371. recheck_channel(cst, 0);
  372. } else {
  373. fr.match = FR_GLOBAL;
  374. get_user_flagrec(dcc[idx].user, &fr, 0);
  375. /* Don't let bot flags be altered */
  376. ofl = fr.global;
  377. break_down_flags(atr, &fr, 0);
  378. fr.global = sanity_check(fr.global, u->bot);
  379. set_user_flagrec(u, &fr, 0);
  380. check_dcc_attrs(u, ofl);
  381. noshare = 0;
  382. build_flags(s, &fr, 0);
  383. fr.match = FR_CHAN;
  384. if (conf.bot->hub) {
  385. if (!(dcc[idx].status & STAT_GETTING))
  386. putlog(LOG_CMDS, "@", "%s: chattr %s %s", dcc[idx].nick, hand, s);
  387. } else {
  388. for (cst = chanset; cst; cst = cst->next)
  389. recheck_channel(cst, 0);
  390. }
  391. }
  392. noshare = 0;
  393. }
  394. if (conf.bot->hub)
  395. write_userfile(-1);
  396. }
  397. }
  398. }
  399. static void
  400. share_pls_chrec(int idx, char *par)
  401. {
  402. if (dcc[idx].status & STAT_SHARE) {
  403. char *user = NULL;
  404. struct chanset_t *chan = NULL;
  405. struct userrec *u = NULL;
  406. user = newsplit(&par);
  407. if ((u = get_user_by_handle(userlist, user))) {
  408. chan = findchan_by_dname(par);
  409. noshare = 1;
  410. shareout_but(idx, "+cr %s %s\n", user, par);
  411. if (!get_chanrec(u, par)) {
  412. add_chanrec(u, par);
  413. if (conf.bot->hub)
  414. putlog(LOG_CMDS, "@", "%s: +chrec %s %s", dcc[idx].nick, user, par);
  415. }
  416. noshare = 0;
  417. }
  418. }
  419. }
  420. static void
  421. share_mns_chrec(int idx, char *par)
  422. {
  423. if (dcc[idx].status & STAT_SHARE) {
  424. char *user = NULL;
  425. struct chanset_t *chan = NULL;
  426. struct userrec *u = NULL;
  427. user = newsplit(&par);
  428. if ((u = get_user_by_handle(userlist, user))) {
  429. chan = findchan_by_dname(par);
  430. noshare = 1;
  431. del_chanrec(u, par);
  432. shareout_but(idx, "-cr %s %s\n", user, par);
  433. noshare = 0;
  434. if (conf.bot->hub)
  435. putlog(LOG_CMDS, "@", "%s: -chrec %s %s", dcc[idx].nick, user, par);
  436. else
  437. recheck_channel(chan, 0);
  438. }
  439. }
  440. }
  441. static void
  442. share_newuser(int idx, char *par)
  443. {
  444. if (dcc[idx].status & STAT_SHARE) {
  445. char *nick = NULL, *host = NULL, *pass = NULL;
  446. bool isbot = 0;
  447. struct userrec *u = NULL;
  448. nick = newsplit(&par);
  449. host = newsplit(&par);
  450. pass = newsplit(&par);
  451. if (nick[0] == '-') {
  452. isbot = 1;
  453. nick++;
  454. }
  455. if (!(u = get_user_by_handle(userlist, nick))) {
  456. char s[100] = "";
  457. fr.global = 0;
  458. fr.match = FR_GLOBAL;
  459. break_down_flags(par, &fr, NULL);
  460. /* If user already exists, ignore command */
  461. shareout_but(idx, "n %s%s %s %s %s\n", isbot ? "-" : "", nick, host, pass, par);
  462. noshare = 1;
  463. if (strlen(nick) > HANDLEN)
  464. nick[HANDLEN] = 0;
  465. fr.match = FR_GLOBAL;
  466. build_flags(s, &fr, 0);
  467. userlist = adduser(userlist, nick, host, pass, 0, isbot);
  468. /* Support for userdefinedflag share - drummer */
  469. u = get_user_by_handle(userlist, nick);
  470. set_user_flagrec(u, &fr, 0);
  471. fr.match = FR_CHAN; /* why?? */
  472. noshare = 0;
  473. if (conf.bot->hub)
  474. putlog(LOG_CMDS, "@", "%s: newuser %s %s", dcc[idx].nick, nick, s);
  475. }
  476. }
  477. }
  478. static void
  479. share_killuser(int idx, char *par)
  480. {
  481. struct userrec *u = NULL;
  482. /* If user is a share bot, ignore command */
  483. if ((dcc[idx].status & STAT_SHARE) && (u = get_user_by_handle(userlist, par))) {
  484. noshare = 1;
  485. if (deluser(par)) {
  486. shareout_but(idx, "k %s\n", par);
  487. if (conf.bot->hub)
  488. putlog(LOG_CMDS, "@", "%s: killuser %s", dcc[idx].nick, par);
  489. }
  490. noshare = 0;
  491. }
  492. }
  493. static void
  494. share_pls_host(int idx, char *par)
  495. {
  496. if (dcc[idx].status & STAT_SHARE) {
  497. char *hand = NULL;
  498. struct userrec *u = NULL;
  499. hand = newsplit(&par);
  500. if ((u = get_user_by_handle(userlist, hand))) {
  501. shareout_but(idx, "+h %s %s\n", hand, par);
  502. set_user(&USERENTRY_HOSTS, u, par);
  503. if (conf.bot->hub)
  504. putlog(LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand, par);
  505. else
  506. check_this_user(u->handle, 0, NULL);
  507. }
  508. }
  509. }
  510. static void
  511. share_pls_bothost(int idx, char *par)
  512. {
  513. if (dcc[idx].status & STAT_SHARE) {
  514. char *hand = NULL;
  515. struct userrec *u = NULL;
  516. hand = newsplit(&par);
  517. u = get_user_by_handle(userlist, hand);
  518. if (!(dcc[idx].status & STAT_GETTING))
  519. shareout_but(idx, "+bh %s %s\n", hand, par);
  520. /* Add bot to userlist if not there */
  521. if (u) {
  522. if (!u->bot)
  523. return; /* ignore */
  524. set_user(&USERENTRY_HOSTS, u, par);
  525. } else {
  526. userlist = adduser(userlist, hand, par, "-", 0, 1);
  527. }
  528. if (conf.bot->hub && !(dcc[idx].status & STAT_GETTING))
  529. putlog(LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand, par);
  530. }
  531. }
  532. static void
  533. share_mns_host(int idx, char *par)
  534. {
  535. if (dcc[idx].status & STAT_SHARE) {
  536. char *hand = NULL;
  537. struct userrec *u = NULL;
  538. hand = newsplit(&par);
  539. if ((u = get_user_by_handle(userlist, hand))) {
  540. shareout_but(idx, "-h %s %s\n", hand, par);
  541. noshare = 1;
  542. delhost_by_handle(hand, par);
  543. noshare = 0;
  544. if (conf.bot->hub)
  545. putlog(LOG_CMDS, "@", "%s: -host %s %s", dcc[idx].nick, hand, par);
  546. else
  547. check_this_user(hand, 2, par);
  548. }
  549. }
  550. }
  551. static void
  552. share_change(int idx, char *par)
  553. {
  554. if (dcc[idx].status & STAT_SHARE) {
  555. char *key = NULL, *hand = NULL;
  556. struct userrec *u = NULL;
  557. struct user_entry_type *uet = NULL;
  558. struct user_entry *e = NULL;
  559. key = newsplit(&par);
  560. hand = newsplit(&par);
  561. u = get_user_by_handle(userlist, hand);
  562. if (!(uet = find_entry_type(key)))
  563. /* If it's not a supported type, forget it */
  564. putlog(LOG_ERROR, "*", "Ignore ch %s from %s (unknown type)", key, dcc[idx].nick);
  565. else {
  566. if (!(dcc[idx].status & STAT_GETTING))
  567. shareout_but(idx, "c %s %s %s\n", key, hand, par);
  568. noshare = 1;
  569. if (!u && (uet == &USERENTRY_BOTADDR)) {
  570. char pass[30] = "";
  571. makepass(pass);
  572. userlist = adduser(userlist, hand, "none", pass, 0, 1);
  573. u = get_user_by_handle(userlist, hand);
  574. } else if (!u)
  575. return;
  576. if (uet->got_share) {
  577. if (!(e = find_user_entry(uet, u))) {
  578. e = (struct user_entry *) my_calloc(1, sizeof(struct user_entry));
  579. e->type = uet;
  580. e->name = NULL;
  581. e->u.list = NULL;
  582. list_insert((&(u->entries)), e);
  583. }
  584. uet->got_share(u, e, par, idx);
  585. if (!e->u.list) {
  586. list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
  587. free(e);
  588. }
  589. }
  590. noshare = 0;
  591. }
  592. }
  593. }
  594. static void
  595. share_chchinfo(int idx, char *par)
  596. {
  597. if (dcc[idx].status & STAT_SHARE) {
  598. char *hand = NULL, *chan = NULL;
  599. struct chanset_t *cst = NULL;
  600. struct userrec *u = NULL;
  601. hand = newsplit(&par);
  602. if ((u = get_user_by_handle(userlist, hand))) {
  603. chan = newsplit(&par);
  604. cst = findchan_by_dname(chan);
  605. shareout_but(idx, "chchinfo %s %s %s\n", hand, chan, par);
  606. noshare = 1;
  607. set_handle_chaninfo(userlist, hand, chan, par);
  608. noshare = 0;
  609. if (conf.bot->hub)
  610. putlog(LOG_CMDS, "@", "%s: change info %s %s", dcc[idx].nick, chan, hand);
  611. }
  612. }
  613. }
  614. static void share_mns_mask(int idx, char *par)
  615. {
  616. if (dcc[idx].status & STAT_SHARE) {
  617. char *types = newsplit(&par);
  618. const char type = types[0];
  619. shareout_but(idx, "-m %c %s\n", type, par);
  620. if (conf.bot->hub)
  621. putlog(LOG_CMDS, "@", "%s: cancel %s %s", dcc[idx].nick, type == 'b' ? "ban" : type == 'e' ? "exempt" : "invite", par);
  622. str_unescape(par, '\\');
  623. noshare = 1;
  624. if (u_delmask(type, NULL, par, 1) > 0) {
  625. if (!conf.bot->hub) {
  626. struct chanset_t *chan = NULL;
  627. masklist *channel_list = NULL;
  628. for (chan = chanset; chan; chan = chan->next) {
  629. channel_list = (type == 'b' ? chan->channel.ban : type == 'e' ?
  630. chan->channel.exempt : chan->channel.invite);
  631. if (channel_list && !ismasked(channel_list, par))
  632. add_delay(chan, '-', type, par);
  633. }
  634. }
  635. }
  636. noshare = 0;
  637. }
  638. }
  639. static void share_mns_maskchan(int idx, char *par)
  640. {
  641. if (dcc[idx].status & STAT_SHARE) {
  642. char *types = newsplit(&par);
  643. const char type = types[0];
  644. char *chname = NULL;
  645. struct chanset_t *chan = NULL;
  646. int value = 0;
  647. chname = newsplit(&par);
  648. chan = findchan_by_dname(chname);
  649. shareout_but(idx, "-mc %c %s %s\n", type, chname, par);
  650. if (conf.bot->hub)
  651. putlog(LOG_CMDS, "@", "%s: cancel %s %s on %s", dcc[idx].nick,
  652. type == 'b' ? "ban" : type == 'e' ? "exempt" : "invite", par, chname);
  653. str_unescape(par, '\\');
  654. noshare = 1;
  655. value = u_delmask(type, chan, par, 1);
  656. if (!conf.bot->hub && value > 0)
  657. add_delay(chan, '-', type, par);
  658. noshare = 0;
  659. }
  660. }
  661. static void share_pls_mask(int idx, char *par)
  662. {
  663. if (dcc[idx].status & STAT_SHARE) {
  664. char *types = newsplit(&par);
  665. const char type = types[0];
  666. const char *str_type = (type == 'b' ? "ban" : type == 'e' ? "exempt" : "invite");
  667. time_t expire_time;
  668. char *mask = NULL, *tm = NULL, *from = NULL;
  669. int flags = 0;
  670. bool stick = 0;
  671. shareout_but(idx, "+m %c %s\n", type, par);
  672. noshare = 1;
  673. mask = newsplit(&par);
  674. str_unescape(mask, '\\');
  675. tm = newsplit(&par);
  676. from = newsplit(&par);
  677. if (strchr(from, 's')) {
  678. flags |= MASKREC_STICKY;
  679. stick = 1;
  680. }
  681. if (strchr(from, 'p'))
  682. flags |= MASKREC_PERM;
  683. from = newsplit(&par);
  684. expire_time = (time_t) atoi(tm);
  685. if (expire_time != 0L)
  686. expire_time += now;
  687. u_addmask(type, NULL, mask, from, par, expire_time, flags);
  688. noshare = 0;
  689. if (conf.bot->hub)
  690. putlog(LOG_CMDS, "@", "%s: global %s %s (%s:%s)", dcc[idx].nick, str_type, mask, from, par);
  691. else {
  692. void (*check_this_mask) (struct chanset_t *, char *, bool) = NULL;
  693. check_this_mask = (type == 'b' ? check_this_ban : type == 'e' ? check_this_exempt : check_this_invite);
  694. for (struct chanset_t *chan = chanset; chan != NULL; chan = chan->next)
  695. check_this_mask(chan, mask, stick);
  696. }
  697. }
  698. }
  699. static void share_pls_maskchan(int idx, char *par)
  700. {
  701. if (dcc[idx].status & STAT_SHARE) {
  702. char *types = newsplit(&par);
  703. const char type = types[0];
  704. const char *str_type = (type == 'b' ? "ban" : type == 'e' ? "exempt" : "invite");
  705. time_t expire_time;
  706. int flags = 0;
  707. char *mask = NULL, *tm = NULL, *chname = NULL, *from = NULL;
  708. bool stick = 0;
  709. struct chanset_t *chan = NULL;
  710. mask = newsplit(&par);
  711. tm = newsplit(&par);
  712. chname = newsplit(&par);
  713. chan = findchan_by_dname(chname);
  714. shareout_but(idx, "+mc %c %s %s %s %s\n", type, mask, tm, chname, par);
  715. str_unescape(mask, '\\');
  716. from = newsplit(&par);
  717. if (strchr(from, 's')) {
  718. flags |= MASKREC_STICKY;
  719. stick = 1;
  720. }
  721. if (strchr(from, 'p'))
  722. flags |= MASKREC_PERM;
  723. from = newsplit(&par);
  724. if (conf.bot->hub)
  725. putlog(LOG_CMDS, "@", "%s: %s %s on %s (%s:%s)", dcc[idx].nick, str_type, mask, chname, from, par);
  726. noshare = 1;
  727. expire_time = (time_t) atoi(tm);
  728. if (expire_time != 0L)
  729. expire_time += now;
  730. u_addmask(type, chan, mask, from, par, expire_time, flags);
  731. noshare = 0;
  732. if (!conf.bot->hub) {
  733. void (*check_this_mask) (struct chanset_t *, char *, bool) = NULL;
  734. check_this_mask = (type == 'b' ? check_this_ban : type == 'e' ? check_this_exempt : check_this_invite);
  735. check_this_mask(chan, mask, stick);
  736. }
  737. }
  738. }
  739. static void
  740. share_mns_ignore(int idx, char *par)
  741. {
  742. if (dcc[idx].status & STAT_SHARE) {
  743. shareout_but(idx, "-i %s\n", par);
  744. if (conf.bot->hub)
  745. putlog(LOG_CMDS, "@", "%s: cancel ignore %s", dcc[idx].nick, par);
  746. str_unescape(par, '\\');
  747. noshare = 1;
  748. delignore(par);
  749. noshare = 0;
  750. }
  751. }
  752. /* +i <host> +<seconds-left> <from> <note>
  753. */
  754. static void
  755. share_pls_ignore(int idx, char *par)
  756. {
  757. if (dcc[idx].status & STAT_SHARE) {
  758. time_t expire_time;
  759. char *ign = NULL, *from = NULL, *ts = NULL;
  760. shareout_but(idx, "+i %s\n", par);
  761. noshare = 1;
  762. ign = newsplit(&par);
  763. str_unescape(ign, '\\');
  764. ts = newsplit(&par);
  765. if (!atoi(ts))
  766. expire_time = 0L;
  767. else
  768. expire_time = now + atoi(ts);
  769. from = newsplit(&par);
  770. if (strchr(from, 'p'))
  771. expire_time = 0;
  772. from = newsplit(&par);
  773. if (strlen(from) > HANDLEN + 1)
  774. from[HANDLEN + 1] = 0;
  775. par[65] = 0;
  776. if (conf.bot->hub)
  777. putlog(LOG_CMDS, "@", "%s: ignore %s (%s: %s)", dcc[idx].nick, ign, from, par);
  778. addignore(ign, from, (const char *) par, expire_time);
  779. noshare = 0;
  780. }
  781. }
  782. static void
  783. share_ufno(int idx, char *par)
  784. {
  785. putlog(LOG_BOTS, "@", "User file rejected by %s: %s", dcc[idx].nick, par);
  786. dcc[idx].status &= ~STAT_OFFERED;
  787. if (!(dcc[idx].status & STAT_GETTING))
  788. dcc[idx].status &= ~(STAT_SHARE | STAT_AGGRESSIVE);
  789. }
  790. static void
  791. share_ufyes(int idx, char *par)
  792. {
  793. if (dcc[idx].status & STAT_OFFERED) {
  794. dcc[idx].status &= ~STAT_OFFERED;
  795. dcc[idx].status |= STAT_SHARE;
  796. dcc[idx].status |= STAT_SENDING;
  797. dcc[idx].u.bot->uff_flags |= (UFF_OVERRIDE | UFF_INVITE | UFF_EXEMPT);
  798. dprintf(idx, "s feats overbots invites exempts\n");
  799. lower_bot_linked(idx);
  800. start_sending_users(idx);
  801. putlog(LOG_BOTS, "@", "Sending user file send request to %s", dcc[idx].nick);
  802. }
  803. }
  804. static void
  805. share_userfileq(int idx, char *par)
  806. {
  807. flush_tbuf(dcc[idx].nick);
  808. if (bot_aggressive_to(dcc[idx].user)) {
  809. putlog(LOG_ERRORS, "*", "%s offered user transfer - I'm supposed to be aggressive to it", dcc[idx].nick);
  810. dprintf(idx, "s un I have you marked for Agressive sharing.\n");
  811. botunlink(-2, dcc[idx].nick, "I'm aggressive to you");
  812. } else {
  813. bool ok = 1;
  814. for (int i = 0; i < dcc_total; i++)
  815. if (dcc[i].type && dcc[i].type->flags & DCT_BOT) {
  816. if ((dcc[i].status & STAT_SHARE) && (dcc[i].status & STAT_AGGRESSIVE) && (i != idx)) {
  817. ok = 0;
  818. break;
  819. }
  820. }
  821. if (!ok)
  822. dprintf(idx, "s un Already sharing.\n");
  823. else {
  824. dcc[idx].u.bot->uff_flags |= (UFF_OVERRIDE | UFF_INVITE | UFF_EXEMPT);
  825. dprintf(idx, "s uy overbots invites exempts\n");
  826. /* Set stat-getting to astatic void race condition (robey 23jun1996) */
  827. dcc[idx].status |= STAT_SHARE | STAT_GETTING | STAT_AGGRESSIVE;
  828. if (conf.bot->hub)
  829. putlog(LOG_BOTS, "*", "Downloading user file from %s", dcc[idx].nick);
  830. else
  831. putlog(LOG_BOTS, "*", "Downloading user file via uplink.");
  832. }
  833. }
  834. }
  835. /* us <ip> <port> <length>
  836. */
  837. static void
  838. share_ufsend(int idx, char *par)
  839. {
  840. char *port = NULL, *ip = NULL;
  841. char s[1024] = "";
  842. int i, sock;
  843. FILE *f = NULL;
  844. egg_snprintf(s, sizeof s, "%s.share.%s.%li.users", tempdir, conf.bot->nick, now);
  845. if (!(b_status(idx) & STAT_SHARE)) {
  846. dprintf(idx, "s e You didn't ask; you just started sending.\n");
  847. dprintf(idx, "s e Ask before sending the userfile.\n");
  848. zapfbot(idx);
  849. } else if (dcc_total == max_dcc) {
  850. putlog(LOG_MISC, "@", "NO MORE DCC CONNECTIONS -- can't grab userfile");
  851. dprintf(idx, "s e I can't open a DCC to you; I'm full.\n");
  852. zapfbot(idx);
  853. } else if (!(f = fopen(s, "wb"))) {
  854. putlog(LOG_MISC, "@", "CAN'T WRITE USERFILE DOWNLOAD FILE!");
  855. zapfbot(idx);
  856. } else {
  857. ip = newsplit(&par);
  858. port = newsplit(&par);
  859. #ifdef USE_IPV6
  860. // sock = getsock(SOCK_BINARY, hostprotocol(ip)); /* Don't buffer this -> mark binary. */
  861. sock = getsock(SOCK_BINARY, AF_INET);
  862. #else
  863. sock = getsock(SOCK_BINARY); /* Don't buffer this -> mark binary. */
  864. #endif /* USE_IPV6 */
  865. if (sock < 0 || open_telnet_dcc(sock, ip, port) < 0) {
  866. fclose(f);
  867. killsock(sock);
  868. putlog(LOG_BOTS, "@", "Asynchronous connection failed!");
  869. dprintf(idx, "s e Can't connect to you!\n");
  870. zapfbot(idx);
  871. } else {
  872. putlog(LOG_DEBUG, "@", "Connecting to %s:%s for userfile.", ip, port);
  873. i = new_dcc(&DCC_FORK_SEND, sizeof(struct xfer_info));
  874. dcc[i].addr = my_atoul(ip);
  875. dcc[i].port = atoi(port);
  876. strcpy(dcc[i].nick, "*users");
  877. dcc[i].u.xfer->filename = strdup(s);
  878. dcc[i].u.xfer->origname = dcc[i].u.xfer->filename;
  879. dcc[i].u.xfer->length = atoi(par);
  880. dcc[i].u.xfer->f = f;
  881. dcc[i].sock = sock;
  882. strcpy(dcc[i].host, dcc[idx].nick);
  883. dcc[idx].status |= STAT_GETTING;
  884. }
  885. }
  886. }
  887. static void
  888. share_version(int idx, char *par)
  889. {
  890. /* Cleanup any share flags */
  891. dcc[idx].status &= ~(STAT_SHARE | STAT_GETTING | STAT_SENDING | STAT_OFFERED | STAT_AGGRESSIVE);
  892. dcc[idx].u.bot->uff_flags |= (UFF_OVERRIDE | UFF_INVITE | UFF_EXEMPT);
  893. if (bot_aggressive_to(dcc[idx].user)) {
  894. dprintf(idx, "s u?\n");
  895. dcc[idx].status |= STAT_OFFERED;
  896. }
  897. // else higher_bot_linked(idx);
  898. }
  899. void
  900. hook_read_userfile()
  901. {
  902. if (!noshare) {
  903. for (int i = 0; i < dcc_total; i++) {
  904. if (dcc[i].type && (dcc[i].type->flags & DCT_BOT) && (dcc[i].status & STAT_SHARE) && !(dcc[i].status & STAT_AGGRESSIVE)
  905. && (1)) {
  906. /* Cancel any existing transfers */
  907. if (dcc[i].status & STAT_SENDING)
  908. cancel_user_xfer(-i, 0);
  909. dprintf(i, "s u?\n");
  910. dcc[i].status |= STAT_OFFERED;
  911. }
  912. }
  913. }
  914. }
  915. static void
  916. share_endstartup(int idx, char *par)
  917. {
  918. dcc[idx].status &= ~STAT_GETTING;
  919. /* Send to any other sharebots */
  920. if (conf.bot->hub)
  921. hook_read_userfile();
  922. }
  923. static void
  924. share_end(int idx, char *par)
  925. {
  926. putlog(LOG_BOTS, "*", "Ending sharing with %s (%s).", dcc[idx].nick, par);
  927. cancel_user_xfer(-idx, 0);
  928. dcc[idx].status &= ~(STAT_SHARE | STAT_GETTING | STAT_SENDING | STAT_OFFERED | STAT_AGGRESSIVE);
  929. dcc[idx].u.bot->uff_flags = 0;
  930. }
  931. /* Note: these MUST be sorted. */
  932. static botcmd_t C_share[] = {
  933. {"!", share_endstartup, 0},
  934. {"+bh", share_pls_bothost, 0},
  935. {"+cr", share_pls_chrec, 0},
  936. {"+h", share_pls_host, 0},
  937. {"+i", share_pls_ignore, 0},
  938. {"+m", share_pls_mask, 0},
  939. {"+mc", share_pls_maskchan, 0},
  940. {"-cr", share_mns_chrec, 0},
  941. {"-h", share_mns_host, 0},
  942. {"-i", share_mns_ignore, 0},
  943. {"-m", share_mns_mask, 0},
  944. {"-mc", share_mns_maskchan, 0},
  945. {"a", share_chattr, 0},
  946. {"c", share_change, 0},
  947. {"chchinfo", share_chchinfo, 0},
  948. {"e", share_end, 0},
  949. {"h", share_chhand, 0},
  950. {"k", share_killuser, 0},
  951. {"n", share_newuser, 0},
  952. {"s", share_stick_ban, 0},
  953. {"se", share_stick_exempt, 0},
  954. {"sInv", share_stick_invite, 0},
  955. {"u?", share_userfileq, 0},
  956. {"un", share_ufno, HUB},
  957. {"us", share_ufsend, 0},
  958. {"uy", share_ufyes, HUB},
  959. {"v", share_version, 0},
  960. {NULL, NULL, 0}
  961. };
  962. void
  963. sharein(int idx, char *msg)
  964. {
  965. char *code = newsplit(&msg);
  966. int y, f = 0, i = 0;
  967. for (f = 0, i = 0; C_share[i].name && !f; i++) {
  968. y = egg_strcasecmp(code, C_share[i].name);
  969. if (!y)
  970. /* Found a match */
  971. (C_share[i].func) (idx, msg);
  972. if (y < 0)
  973. f = 1;
  974. }
  975. }
  976. void
  977. shareout(const char *format, ...)
  978. {
  979. char s[601] = "";
  980. int l;
  981. va_list va;
  982. va_start(va, format);
  983. strcpy(s, "s ");
  984. if ((l = egg_vsnprintf(s + 2, 509, format, va)) < 0)
  985. s[2 + (l = 509)] = 0;
  986. va_end(va);
  987. for (int i = 0; i < dcc_total; i++) {
  988. if (dcc[i].type && (dcc[i].type->flags & DCT_BOT) &&
  989. (dcc[i].status & STAT_SHARE) && !(dcc[i].status & (STAT_GETTING | STAT_SENDING))) {
  990. tputs(dcc[i].sock, s, l + 2);
  991. }
  992. }
  993. q_resync(s);
  994. }
  995. static void
  996. shareout_but(int x, const char *format, ...)
  997. {
  998. int l;
  999. char s[601] = "";
  1000. va_list va;
  1001. va_start(va, format);
  1002. strcpy(s, "s ");
  1003. if ((l = egg_vsnprintf(s + 2, 509, format, va)) < 0)
  1004. s[2 + (l = 509)] = 0;
  1005. va_end(va);
  1006. for (int i = 0; i < dcc_total; i++) {
  1007. if (dcc[i].type && (dcc[i].type->flags & DCT_BOT) && (i != x) &&
  1008. (dcc[i].status & STAT_SHARE) && (!(dcc[i].status & STAT_GETTING)) &&
  1009. (!(dcc[i].status & STAT_SENDING))) {
  1010. tputs(dcc[i].sock, s, l + 2);
  1011. }
  1012. }
  1013. q_resync(s);
  1014. }
  1015. /* Flush all tbufs older than 15 minutes.
  1016. */
  1017. static void
  1018. check_expired_tbufs()
  1019. {
  1020. tandbuf *t = NULL, *tnext = NULL;
  1021. for (t = tbuf; t; t = tnext) {
  1022. tnext = t->next;
  1023. if ((now - t->timer) > 300) {
  1024. putlog(LOG_BOTS, "*", "Flushing resync buffer for clonebot %s.", t->bot);
  1025. del_tbuf(t);
  1026. }
  1027. }
  1028. /* Resend userfile requests */
  1029. for (int i = 0; i < dcc_total; i++) {
  1030. if (dcc[i].type && dcc[i].type->flags & DCT_BOT) {
  1031. if (dcc[i].status & STAT_OFFERED) {
  1032. if (now - dcc[i].timeval > 120) {
  1033. if (dcc[i].user && bot_aggressive_to(dcc[i].user))
  1034. dprintf(i, "s u?\n");
  1035. /* ^ send it again in case they missed it */
  1036. }
  1037. /* If it's a share bot that hasnt been sharing, ask again */
  1038. } else if (!(dcc[i].status & STAT_SHARE)) {
  1039. if (dcc[i].user && bot_aggressive_to(dcc[i].user)) {
  1040. dprintf(i, "s u?\n");
  1041. dcc[i].status |= STAT_OFFERED;
  1042. }
  1043. }
  1044. }
  1045. }
  1046. }
  1047. static bool
  1048. write_tmp_userfile(char *fn, const struct userrec *bu, int idx)
  1049. {
  1050. FILE *f = NULL;
  1051. int ok = 0;
  1052. if ((f = fopen(fn, "wb"))) {
  1053. time_t tt = now;
  1054. char s1[81] = "";
  1055. fixmod(fn);
  1056. strcpy(s1, ctime(&tt));
  1057. lfprintf(f, "#4v: %s -- %s -- written %s", ver, conf.bot->nick, s1);
  1058. ok += write_chans(f, idx);
  1059. ok += write_config(f, idx);
  1060. ok += write_bans(f, idx);
  1061. ok += write_exempts(f, idx);
  1062. ok += write_invites(f, idx);
  1063. if (ok != 5)
  1064. ok = 0;
  1065. for (struct userrec *u = (struct userrec *) bu; u && ok; u = u->next) {
  1066. if (!write_user(u, f, idx))
  1067. ok = 0;
  1068. }
  1069. fclose(f);
  1070. }
  1071. if (!ok)
  1072. putlog(LOG_MISC, "*", USERF_ERRWRITE2);
  1073. return ok;
  1074. }
  1075. /* Erase old user list, switch to new one.
  1076. */
  1077. void
  1078. finish_share(int idx)
  1079. {
  1080. struct userrec *u = NULL, *ou = NULL;
  1081. struct chanset_t *chan = NULL;
  1082. int i, j = -1;
  1083. for (i = 0; i < dcc_total; i++)
  1084. if (dcc[i].type && !egg_strcasecmp(dcc[i].nick, dcc[idx].host) && (dcc[i].type->flags & DCT_BOT)) {
  1085. j = i;
  1086. break;
  1087. }
  1088. if (j == -1)
  1089. return;
  1090. /* compress.mod
  1091. if (!uncompressfile(dcc[idx].u.xfer->filename)) {
  1092. char xx[1024] = "";
  1093. putlog(LOG_BOTS, "*", "A uff parsing function failed for the userfile!");
  1094. unlink(dcc[idx].u.xfer->filename);
  1095. dprintf(j, "bye\n");
  1096. simple_snprintf(xx, sizeof xx, "Disconnected %s (uff error)", dcc[j].nick);
  1097. botnet_send_unlinked(j, dcc[j].nick, xx);
  1098. chatout("*** %s\n", xx);
  1099. killsock(dcc[j].sock);
  1100. lostdcc(j);
  1101. return;
  1102. }
  1103. */
  1104. /*
  1105. * This is where we remove all global and channel bans/exempts/invites and
  1106. * ignores since they will be replaced by what our hub gives us.
  1107. */
  1108. noshare = 1;
  1109. while (global_bans)
  1110. u_delmask('b', NULL, global_bans->mask, 1);
  1111. while (global_ign)
  1112. delignore(global_ign->igmask);
  1113. while (global_invites)
  1114. u_delmask('I', NULL, global_invites->mask, 1);
  1115. while (global_exempts)
  1116. u_delmask('e', NULL, global_exempts->mask, 1);
  1117. for (chan = chanset; chan; chan = chan->next) {
  1118. while (chan->bans)
  1119. u_delmask('b', chan, chan->bans->mask, 1);
  1120. while (chan->exempts)
  1121. u_delmask('e', chan, chan->exempts->mask, 1);
  1122. while (chan->invites)
  1123. u_delmask('I', chan, chan->invites->mask, 1);
  1124. }
  1125. noshare = 0;
  1126. ou = userlist; /* Save old user list */
  1127. userlist = (struct userrec *) -1; /* Do this to prevent .user messups */
  1128. /* Bot user pointers are updated to point to the new list, all others
  1129. * are set to NULL. If our userfile will be overriden, just set _all_
  1130. * to NULL directly.
  1131. */
  1132. for (i = 0; i < dcc_total; i++)
  1133. if (dcc[i].type)
  1134. dcc[i].user = NULL;
  1135. Auth::NullUsers();
  1136. if (conf.bot->u)
  1137. conf.bot->u = NULL;
  1138. /* Read the transferred userfile. Add entries to u, which already holds
  1139. * the bot entries in non-override mode.
  1140. */
  1141. loading = 1;
  1142. checkchans(0); /* flag all the channels.. */
  1143. Context;
  1144. if (!readuserfile(dcc[idx].u.xfer->filename, &u)) { /* read the userfile into 'u' */
  1145. /* FAILURE */
  1146. char xx[1024] = "";
  1147. Context;
  1148. unlink(dcc[idx].u.xfer->filename);
  1149. clear_userlist(u); /* Clear new, obsolete, user list. */
  1150. clear_chanlist(); /* Remove all user references from the
  1151. * channel lists. */
  1152. for (i = 0; i < dcc_total; i++)
  1153. if (dcc[i].type)
  1154. dcc[i].user = get_user_by_handle(ou, dcc[i].nick);
  1155. conf.bot->u = get_user_by_handle(ou, conf.bot->nick);
  1156. userlist = ou; /* Revert to old user list. */
  1157. lastuser = NULL; /* Reset last accessed user ptr. */
  1158. Auth::FillUsers();
  1159. checkchans(2); /* un-flag the channels, we are keeping them.. */
  1160. /* old userlist is now being used, safe to do this stuff... */
  1161. loading = 0;
  1162. putlog(LOG_MISC, "*", "%s", USERF_CANTREAD);
  1163. dprintf(idx, "bye\n");
  1164. simple_snprintf(xx, sizeof xx, "Disconnected %s (can't read userfile)", dcc[j].nick);
  1165. botnet_send_unlinked(j, dcc[j].nick, xx);
  1166. chatout("*** %s\n", xx);
  1167. killsock(dcc[j].sock);
  1168. lostdcc(j);
  1169. return;
  1170. }
  1171. /* SUCCESS! */
  1172. unlink(dcc[idx].u.xfer->filename);
  1173. loading = 0;
  1174. clear_chanlist(); /* Remove all user references from the
  1175. * channel lists. */
  1176. userlist = u; /* Set new user list. */
  1177. lastuser = NULL; /* Reset last accessed user ptr. */
  1178. putlog(LOG_BOTS, "*", "%s.", USERF_XFERDONE);
  1179. /*
  1180. * Migrate:
  1181. * - unshared (got_share == 0) user entries
  1182. */
  1183. clear_userlist(ou);
  1184. /* copy over any auth users */
  1185. Auth::FillUsers();
  1186. checkchans(1); /* remove marked channels */
  1187. trigger_cfg_changed();
  1188. reaffirm_owners(); /* Make sure my owners are +a */
  1189. updatebot(-1, dcc[j].nick, '+', 0, 0, NULL);
  1190. }
  1191. /* Begin the user transfer process.
  1192. */
  1193. static void
  1194. start_sending_users(int idx)
  1195. {
  1196. char share_file[1024] = "";
  1197. int i = 1, j = -1;
  1198. egg_snprintf(share_file, sizeof share_file, "%s.share.%s.%li", tempdir, dcc[idx].nick, now);
  1199. write_tmp_userfile(share_file, userlist, idx);
  1200. /* compress.mod
  1201. if (!compress_file(share_file, compress_level)) {
  1202. unlink(share_file);
  1203. dprintf(idx, "s e %s\n", "uff parsing failed");
  1204. putlog(LOG_BOTS, "*", "uff parsing failed");
  1205. dcc[idx].status &= ~(STAT_SHARE | STAT_SENDING | STAT_AGGRESSIVE);
  1206. return;
  1207. }
  1208. */
  1209. if ((i = raw_dcc_send(share_file, "*users", "(users)", share_file, &j)) > 0) {
  1210. unlink(share_file);
  1211. dprintf(idx, "s e %s\n", USERF_CANTSEND);
  1212. putlog(LOG_BOTS, "@", "%s -- can't send userfile",
  1213. i == DCCSEND_FULL ? "NO MORE DCC CONNECTIONS" :
  1214. i == DCCSEND_NOSOCK ? "CAN'T OPEN A LISTENING SOCKET" :
  1215. i == DCCSEND_BADFN ? "BAD FILE" : i == DCCSEND_FEMPTY ? "EMPTY FILE" : "UNKNOWN REASON!");
  1216. dcc[idx].status &= ~(STAT_SHARE | STAT_SENDING | STAT_AGGRESSIVE);
  1217. } else {
  1218. updatebot(-1, dcc[idx].nick, '+', 0, 0, NULL);
  1219. dcc[idx].status |= STAT_SENDING;
  1220. strcpy(dcc[j].host, dcc[idx].nick); /* Store bot's nick */
  1221. dprintf(idx, "s us %lu %d %lu\n", iptolong(getmyip()), dcc[j].port, dcc[j].u.xfer->length);
  1222. /* Start up a tbuf to queue outgoing changes for this bot until the
  1223. * userlist is done transferring.
  1224. */
  1225. new_tbuf(dcc[idx].nick);
  1226. /* override shit removed here */
  1227. q_tbuf(dcc[idx].nick, "s !\n");
  1228. /* Unlink the file. We don't really care whether this causes problems
  1229. * for NFS setups. It's not worth the trouble.
  1230. */
  1231. unlink(share_file);
  1232. }
  1233. }
  1234. static void (*def_dcc_bot_kill) (int, void *) = 0;
  1235. static void
  1236. cancel_user_xfer(int idx, void *x)
  1237. {
  1238. int i, j = -1, k = 0;
  1239. if (idx < 0) {
  1240. idx = -idx;
  1241. k = 1;
  1242. updatebot(-1, dcc[idx].nick, '-', 0, 0, NULL);
  1243. }
  1244. flush_tbuf(dcc[idx].nick);
  1245. if (dcc[idx].status & STAT_SHARE) {
  1246. if (dcc[idx].status & STAT_GETTING) {
  1247. for (i = 0; i < dcc_total; i++)
  1248. if (dcc[i].type && !egg_strcasecmp(dcc[i].host, dcc[idx].nick) &&
  1249. ((dcc[i].type->flags & (DCT_FILETRAN | DCT_FILESEND)) == (DCT_FILETRAN | DCT_FILESEND))) {
  1250. j = i;
  1251. break;
  1252. }
  1253. if (j >= 0) {
  1254. killsock(dcc[j].sock);
  1255. unlink(dcc[j].u.xfer->filename);
  1256. lostdcc(j);
  1257. }
  1258. putlog(LOG_BOTS, "*", "(Userlist download aborted.)");
  1259. }
  1260. if (dcc[idx].status & STAT_SENDING) {
  1261. for (i = 0; i < dcc_total; i++)
  1262. if (dcc[i].type && (!egg_strcasecmp(dcc[i].host, dcc[idx].nick)) &&
  1263. ((dcc[i].type->flags & (DCT_FILETRAN | DCT_FILESEND))
  1264. == DCT_FILETRAN)) {
  1265. j = i;
  1266. break;
  1267. }
  1268. if (j >= 0) {
  1269. killsock(dcc[j].sock);
  1270. unlink(dcc[j].u.xfer->filename);
  1271. lostdcc(j);
  1272. }
  1273. putlog(LOG_BOTS, "*", "(Userlist transmit aborted.)");
  1274. }
  1275. }
  1276. if (!k)
  1277. def_dcc_bot_kill(idx, x);
  1278. }
  1279. void
  1280. share_report(int idx, int details)
  1281. {
  1282. int i, j;
  1283. if (details) {
  1284. for (i = 0; i < dcc_total; i++)
  1285. if (dcc[i].type && dcc[i].type == &DCC_BOT) {
  1286. if (dcc[i].status & STAT_GETTING) {
  1287. int ok = 0;
  1288. for (j = 0; j < dcc_total; j++)
  1289. if (dcc[j].type && ((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND))
  1290. == (DCT_FILETRAN | DCT_FILESEND)) && !egg_strcasecmp(dcc[j].host, dcc[i].nick)) {
  1291. dprintf(idx, "Downloading userlist from %s (%d%% done)\n",
  1292. dcc[i].nick, (int) (100.0 * ((float) dcc[j].status) / ((float) dcc[j].u.xfer->length)));
  1293. ok = 1;
  1294. break;
  1295. }
  1296. if (!ok)
  1297. dprintf(idx, "Download userlist from %s (negotiating " "botentries)\n", dcc[i].nick);
  1298. } else if (dcc[i].status & STAT_SENDING) {
  1299. for (j = 0; j < dcc_total; j++) {
  1300. if (dcc[j].type && ((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND))
  1301. == DCT_FILETRAN)
  1302. && !egg_strcasecmp(dcc[j].host, dcc[i].nick)) {
  1303. if (dcc[j].type == &DCC_GET)
  1304. dprintf(idx, "Sending userlist to %s (%d%% done)\n",
  1305. dcc[i].nick,
  1306. (int) (100.0 * ((float) dcc[j].status) / ((float) dcc[j].u.xfer->length)));
  1307. else
  1308. dprintf(idx, "Sending userlist to %s (waiting for connect)\n", dcc[i].nick);
  1309. }
  1310. }
  1311. } else if (dcc[i].status & STAT_AGGRESSIVE) {
  1312. dprintf(idx, " Passively sharing with %s.\n", dcc[i].nick);
  1313. } else if (dcc[i].status & STAT_SHARE) {
  1314. dprintf(idx, " Aggressively sharing with %s.\n", dcc[i].nick);
  1315. }
  1316. }
  1317. }
  1318. }
  1319. void
  1320. share_init()
  1321. {
  1322. if (conf.bot->hub)
  1323. timer_create_secs(60, "check_expired_tbufs", (Function) check_expired_tbufs);
  1324. else
  1325. timer_create_secs(1, "check_delay", (Function) check_delay);
  1326. def_dcc_bot_kill = DCC_BOT.kill;
  1327. DCC_BOT.kill = cancel_user_xfer;
  1328. }