share.c 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206
  1. /*
  2. * share.c -- part of share.mod
  3. *
  4. */
  5. #define MODULE_NAME "share"
  6. #define MAKING_SHARE
  7. #include "src/mod/module.h"
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <sys/stat.h>
  11. #include "src/chan.h"
  12. #include "src/users.h"
  13. #include "transfer.mod/transfer.h"
  14. #include "channels.mod/channels.h"
  15. #ifdef LEAF
  16. # include "irc.mod/irc.h"
  17. #endif /* LEAF */
  18. /* Minimum version I will share with. */
  19. static const int min_share = 1000000;
  20. /* Earliest version that supports exempts and invites. */
  21. static const int min_exemptinvite = 1000000;
  22. /* Minimum version that supports userfile features. */
  23. static const int min_uffeature = 1000000;
  24. static Function *global = NULL, *transfer_funcs = NULL, *channels_funcs = NULL;
  25. #ifdef LEAF
  26. static Function *irc_funcs = NULL;
  27. #endif /* LEAF */
  28. static int private_global = 0;
  29. static int private_user = 0;
  30. static char private_globals[50];
  31. static int allow_resync = 0;
  32. static struct flag_record fr = {0, 0, 0, 0, 0, 0};
  33. static int resync_time = 900;
  34. static int overr_local_bots = 1; /* Override local bots? */
  35. struct delay_mode {
  36. struct delay_mode *next;
  37. struct chanset_t *chan;
  38. int plsmns;
  39. int mode;
  40. char *mask;
  41. int seconds;
  42. };
  43. static struct delay_mode *start_delay = NULL;
  44. /* Store info for sharebots */
  45. struct share_msgq {
  46. struct chanset_t *chan;
  47. char *msg;
  48. struct share_msgq *next;
  49. };
  50. typedef struct tandbuf_t {
  51. char bot[HANDLEN + 1];
  52. time_t timer;
  53. struct share_msgq *q;
  54. struct tandbuf_t *next;
  55. } tandbuf;
  56. tandbuf *tbuf;
  57. /* Prototypes */
  58. static void start_sending_users(int);
  59. static void shareout_but EGG_VARARGS(struct chanset_t *, arg1);
  60. static int flush_tbuf(char *);
  61. static int can_resync(char *);
  62. static void dump_resync(int);
  63. static void q_resync(char *, struct chanset_t *);
  64. static void cancel_user_xfer(int, void *);
  65. static int private_globals_bitmask();
  66. #include "share.h"
  67. #include "uf_features.c"
  68. /*
  69. * Sup's delay code
  70. */
  71. static void add_delay(struct chanset_t *chan, int plsmns, int mode, char *mask)
  72. {
  73. struct delay_mode *d = NULL;
  74. d = (struct delay_mode *) nmalloc(sizeof(struct delay_mode));
  75. if (!d)
  76. return;
  77. d->chan = chan;
  78. d->plsmns = plsmns;
  79. d->mode = mode;
  80. d->mask = (char *) nmalloc(strlen(mask) + 1);
  81. if (!d->mask) {
  82. nfree(d);
  83. return;
  84. }
  85. strncpyz(d->mask, mask, strlen(mask) + 1);
  86. d->seconds = (int) (now + (random() % 20));
  87. d->next = start_delay;
  88. start_delay = d;
  89. }
  90. static void del_delay(struct delay_mode *delay)
  91. {
  92. struct delay_mode *d = NULL, *old = NULL;
  93. for (d = start_delay; d; old = d, d = d->next) {
  94. if (d == delay) {
  95. if (old)
  96. old->next = d->next;
  97. else
  98. start_delay = d->next;
  99. if (d->mask)
  100. nfree(d->mask);
  101. nfree(d);
  102. break;
  103. }
  104. }
  105. }
  106. static void check_delay()
  107. {
  108. struct delay_mode *d = NULL, *dnext = NULL;
  109. for (d = start_delay; d; d = dnext) {
  110. dnext = d->next;
  111. if (d->seconds <= now) {
  112. add_mode(d->chan, d->plsmns, d->mode, d->mask);
  113. del_delay(d);
  114. }
  115. }
  116. }
  117. static int delay_expmem()
  118. {
  119. int size = 0;
  120. struct delay_mode *d = NULL;
  121. for (d = start_delay; d; d = d->next) {
  122. if (d->mask)
  123. size += strlen(d->mask) + 1;
  124. size += sizeof(struct delay_mode);
  125. }
  126. return size;
  127. }
  128. /*
  129. * Botnet commands
  130. */
  131. static void share_stick_ban(int idx, char *par)
  132. {
  133. char *host, *val;
  134. int yn;
  135. if (dcc[idx].status & STAT_SHARE) {
  136. host = newsplit(&par);
  137. val = newsplit(&par);
  138. yn = atoi(val);
  139. noshare = 1;
  140. if (!par[0]) { /* Global ban */
  141. #ifdef LEAF
  142. struct chanset_t *chan;
  143. #endif /* LEAF */
  144. if (u_setsticky_ban(NULL, host, yn) > 0) {
  145. putlog(LOG_CMDS, "@", "%s: %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host);
  146. shareout_but(NULL, idx, "s %s %d\n", host, yn);
  147. }
  148. #ifdef LEAF
  149. for (chan = chanset; chan != NULL; chan = chan->next)
  150. check_this_ban(chan, host, yn);
  151. #endif /* LEAF */
  152. } else {
  153. struct chanset_t *chan = findchan_by_dname(par);
  154. struct chanuserrec *cr;
  155. if ((chan !=NULL) && ((channel_shared(chan) &&
  156. ((cr = get_chanrec(dcc[idx].user, par)) &&
  157. (bot_aggressive_to(dcc[idx].user)))) ||
  158. (1)))
  159. if (u_setsticky_ban(chan, host, yn) > 0) {
  160. putlog(LOG_CMDS, "@", "%s: %s %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host, par);
  161. shareout_but(chan, idx, "s %s %d %s\n", host, yn, chan->dname);
  162. noshare = 0;
  163. return;
  164. }
  165. #ifdef LEAF
  166. if (chan)
  167. check_this_ban(chan, host, yn);
  168. #endif /* LEAF */
  169. putlog(LOG_CMDS, "@", "Rejecting invalid sticky exempt: %s on %s%s", host, par, yn ? "" : " (unstick)");
  170. }
  171. noshare = 0;
  172. }
  173. }
  174. /* Same as share_stick_ban, only for exempts.
  175. */
  176. static void share_stick_exempt(int idx, char *par)
  177. {
  178. char *host, *val;
  179. int yn;
  180. if (dcc[idx].status & STAT_SHARE) {
  181. host = newsplit(&par);
  182. val = newsplit(&par);
  183. yn = atoi(val);
  184. noshare = 1;
  185. if (!par[0]) { /* Global exempt */
  186. if (u_setsticky_exempt(NULL, host, yn) > 0) {
  187. putlog(LOG_CMDS, "@", "%s: %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host);
  188. shareout_but(NULL, idx, "se %s %d\n", host, yn);
  189. }
  190. } else {
  191. struct chanset_t *chan = findchan_by_dname(par);
  192. struct chanuserrec * cr;
  193. if ((chan != NULL) && ((channel_shared(chan) &&
  194. ((cr = get_chanrec(dcc[idx].user, par)) &&
  195. (bot_aggressive_to(dcc[idx].user)))) ||
  196. (1)))
  197. if (u_setsticky_exempt(chan, host, yn) > 0) {
  198. putlog(LOG_CMDS, "@", "%s: stick %s %c %s", dcc[idx].nick, host, yn ? 'y' : 'n', par);
  199. shareout_but(chan, idx, "se %s %d %s\n", host, yn, chan->dname);
  200. noshare = 0;
  201. return;
  202. }
  203. putlog(LOG_CMDS, "@", "Rejecting invalid sticky exempt: %s on %s, %c", host, par, yn ? 'y' : 'n');
  204. }
  205. noshare = 0;
  206. }
  207. }
  208. /* Same as share_stick_ban, only for invites.
  209. */
  210. static void share_stick_invite (int idx, char * par) {
  211. char *host, *val;
  212. int yn;
  213. if (dcc[idx].status & STAT_SHARE) {
  214. host = newsplit(&par);
  215. val = newsplit(&par);
  216. yn = atoi(val);
  217. noshare = 1;
  218. if (!par[0]) { /* Global invite */
  219. if (u_setsticky_invite(NULL, host, yn) > 0) {
  220. putlog(LOG_CMDS, "@", "%s: %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host);
  221. shareout_but(NULL, idx, "sInv %s %d\n", host, yn);
  222. }
  223. } else {
  224. struct chanset_t *chan = findchan_by_dname(par);
  225. struct chanuserrec * cr;
  226. if ((chan != NULL) && ((channel_shared(chan) &&
  227. ((cr = get_chanrec(dcc[idx].user, par)) &&
  228. (bot_aggressive_to(dcc[idx].user)))) ||
  229. (1)))
  230. if (u_setsticky_invite(chan, host, yn) > 0) {
  231. putlog(LOG_CMDS, "@", "%s: %s %s %s", dcc[idx].nick, (yn) ? "stick" : "unstick", host, par);
  232. shareout_but(chan, idx, "sInv %s %d %s\n", host, yn, chan->dname);
  233. noshare = 0;
  234. return;
  235. }
  236. putlog(LOG_CMDS, "@", "Rejecting invalid sticky invite: %s on %s%s", host, par, yn ? "" : " (unstick)");
  237. }
  238. noshare = 0;
  239. }
  240. }
  241. static void share_chhand(int idx, char *par)
  242. {
  243. char *hand;
  244. struct userrec *u;
  245. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  246. hand = newsplit(&par);
  247. u = get_user_by_handle(userlist, hand);
  248. if (u && !(u->flags & USER_UNSHARED)) {
  249. shareout_but(NULL, idx, "h %s %s\n", hand, par);
  250. noshare = 1;
  251. if (change_handle(u, par))
  252. putlog(LOG_CMDS, "@", "%s: handle %s->%s", dcc[idx].nick, hand, par);
  253. noshare = 0;
  254. }
  255. }
  256. }
  257. static void share_chattr(int idx, char *par)
  258. {
  259. char *hand, *atr, s[100];
  260. struct chanset_t *cst;
  261. struct userrec *u;
  262. struct flag_record fr2;
  263. int bfl, ofl;
  264. module_entry *me;
  265. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  266. hand = newsplit(&par);
  267. u = get_user_by_handle(userlist, hand);
  268. if (u && !(u->flags & USER_UNSHARED)) {
  269. atr = newsplit(&par);
  270. cst = findchan_by_dname(par);
  271. if (!par[0] || (cst && channel_shared(cst))) {
  272. if (!(dcc[idx].status & STAT_GETTING) && (cst || !private_global))
  273. shareout_but(cst, idx, "a %s %s %s\n", hand, atr, par);
  274. noshare = 1;
  275. if (par[0] && cst) {
  276. fr.match = (FR_CHAN | FR_BOT);
  277. get_user_flagrec(dcc[idx].user, &fr, par);
  278. if (bot_chan(fr) || bot_global(fr)) {
  279. fr.match = FR_CHAN;
  280. fr2.match = FR_CHAN;
  281. break_down_flags(atr, &fr, 0);
  282. get_user_flagrec(u, &fr2, par);
  283. fr.chan = (fr2.chan & BOT_AGGRESSIVE) |
  284. (fr.chan & ~BOT_AGGRESSIVE);
  285. set_user_flagrec(u, &fr, par);
  286. check_dcc_chanattrs(u, par, fr.chan, fr2.chan);
  287. noshare = 0;
  288. build_flags(s, &fr, 0);
  289. if (!(dcc[idx].status & STAT_GETTING))
  290. putlog(LOG_CMDS, "@", "%s: chattr %s %s %s",
  291. dcc[idx].nick, hand, s, par);
  292. if ((me = module_find("irc", 0, 0))) {
  293. Function *func = me->funcs;
  294. (func[IRC_RECHECK_CHANNEL]) (cst, 0);
  295. }
  296. } else
  297. putlog(LOG_CMDS, "*",
  298. "Rejected flags for unshared channel %s from %s",
  299. par, dcc[idx].nick);
  300. } else if (!private_global) {
  301. int pgbm = private_globals_bitmask();
  302. fr.match = FR_GLOBAL;
  303. get_user_flagrec(dcc[idx].user, &fr, 0);
  304. /* Don't let bot flags be altered */
  305. ofl = fr.global;
  306. break_down_flags(atr, &fr, 0);
  307. bfl = u->flags & USER_BOT;
  308. fr.global = (fr.global &~pgbm)
  309. |(u->flags & pgbm);
  310. fr.global = sanity_check(fr.global |bfl);
  311. set_user_flagrec(u, &fr, 0);
  312. check_dcc_attrs(u, ofl);
  313. noshare = 0;
  314. build_flags(s, &fr, 0);
  315. fr.match = FR_CHAN;
  316. #ifndef LEAF
  317. if (!(dcc[idx].status & STAT_GETTING))
  318. putlog(LOG_CMDS, "@", "%s: chattr %s %s", dcc[idx].nick, hand, s);
  319. #endif /* LEAF */
  320. if ((me = module_find("irc", 0, 0))) {
  321. Function *func = me->funcs;
  322. for (cst = chanset; cst; cst = cst->next)
  323. (func[IRC_RECHECK_CHANNEL]) (cst, 0);
  324. }
  325. } else
  326. putlog(LOG_CMDS, "@", "Rejected global flags for %s from %s",
  327. hand, dcc[idx].nick);
  328. noshare = 0;
  329. }
  330. }
  331. }
  332. }
  333. static void share_pls_chrec(int idx, char *par)
  334. {
  335. char *user;
  336. struct chanset_t *chan;
  337. struct userrec *u;
  338. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  339. user = newsplit(&par);
  340. if ((u = get_user_by_handle(userlist, user))) {
  341. chan = findchan_by_dname(par);
  342. fr.match = (FR_CHAN | FR_BOT);
  343. get_user_flagrec(dcc[idx].user, &fr, par);
  344. if (!chan || !channel_shared(chan) ||
  345. !(bot_chan(fr) || bot_global(fr)))
  346. putlog(LOG_CMDS, "*",
  347. "Rejected info for unshared channel %s from %s",
  348. par, dcc[idx].nick);
  349. else {
  350. noshare = 1;
  351. shareout_but(chan, idx, "+cr %s %s\n", user, par);
  352. if (!get_chanrec(u, par)) {
  353. add_chanrec(u, par);
  354. putlog(LOG_CMDS, "@", "%s: +chrec %s %s", dcc[idx].nick, user, par);
  355. }
  356. noshare = 0;
  357. }
  358. }
  359. }
  360. }
  361. static void share_mns_chrec(int idx, char *par)
  362. {
  363. char *user;
  364. struct chanset_t *chan;
  365. struct userrec *u;
  366. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  367. user = newsplit(&par);
  368. if ((u = get_user_by_handle(userlist, user))) {
  369. chan = findchan_by_dname(par);
  370. fr.match = (FR_CHAN | FR_BOT);
  371. get_user_flagrec(dcc[idx].user, &fr, par);
  372. if (!chan || !channel_shared(chan) ||
  373. !(bot_chan(fr) || bot_global(fr)))
  374. putlog(LOG_CMDS, "*",
  375. "Rejected info for unshared channel %s from %s",
  376. par, dcc[idx].nick);
  377. else {
  378. noshare = 1;
  379. del_chanrec(u, par);
  380. shareout_but(chan, idx, "-cr %s %s\n", user, par);
  381. noshare = 0;
  382. putlog(LOG_CMDS, "@", "%s: -chrec %s %s", dcc[idx].nick, user, par);
  383. }
  384. }
  385. }
  386. }
  387. static void share_newuser(int idx, char *par)
  388. {
  389. char *nick, *host, *pass, s[100];
  390. struct userrec *u;
  391. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  392. nick = newsplit(&par);
  393. host = newsplit(&par);
  394. pass = newsplit(&par);
  395. if (!(u = get_user_by_handle(userlist, nick)) ||
  396. !(u->flags & USER_UNSHARED)) {
  397. fr.global = 0;
  398. fr.match = FR_GLOBAL;
  399. break_down_flags(par, &fr, NULL);
  400. /* If user already exists, ignore command */
  401. shareout_but(NULL, idx, "n %s %s %s %s\n", nick, host, pass,
  402. private_global ? (fr.global & USER_BOT ? "b" : "-") : par);
  403. if (!u) {
  404. noshare = 1;
  405. if (strlen(nick) > HANDLEN)
  406. nick[HANDLEN] = 0;
  407. if (private_global)
  408. fr.global &= USER_BOT;
  409. else {
  410. /* It shouldn't be done before sending to other bots? */
  411. int pgbm = private_globals_bitmask();
  412. fr.match = FR_GLOBAL;
  413. fr.global &=~pgbm;
  414. }
  415. build_flags(s, &fr, 0);
  416. userlist = adduser(userlist, nick, host, pass, 0);
  417. /* Support for userdefinedflag share - drummer */
  418. u = get_user_by_handle(userlist, nick);
  419. set_user_flagrec(u, &fr, 0);
  420. fr.match = FR_CHAN; /* why?? */
  421. noshare = 0;
  422. #ifndef LEAF
  423. putlog(LOG_CMDS, "@", "%s: newuser %s %s", dcc[idx].nick, nick, s);
  424. #endif /* LEAF */
  425. }
  426. }
  427. }
  428. }
  429. static void share_killuser(int idx, char *par)
  430. {
  431. struct userrec *u;
  432. /* If user is a share bot, ignore command */
  433. if ((dcc[idx].status & STAT_SHARE) && !private_user &&
  434. (u = get_user_by_handle(userlist, par)) &&
  435. !(u->flags & USER_UNSHARED) &&
  436. !((u->flags & USER_BOT) && (bot_flags(u) & BOT_SHARE))) {
  437. noshare = 1;
  438. if (deluser(par)) {
  439. shareout_but(NULL, idx, "k %s\n", par);
  440. #ifndef LEAF
  441. putlog(LOG_CMDS, "@", "%s: killuser %s", dcc[idx].nick, par);
  442. #endif /* LEAF */
  443. }
  444. noshare = 0;
  445. }
  446. }
  447. static void share_pls_host(int idx, char *par)
  448. {
  449. char *hand;
  450. struct userrec *u;
  451. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  452. hand = newsplit(&par);
  453. if ((u = get_user_by_handle(userlist, hand)) &&
  454. !(u->flags & USER_UNSHARED)) {
  455. shareout_but(NULL, idx, "+h %s %s\n", hand, par);
  456. set_user(&USERENTRY_HOSTS, u, par);
  457. #ifdef LEAF
  458. check_this_user(u->handle, 0, NULL);
  459. #else /* !LEAF */
  460. putlog(LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand, par);
  461. #endif /* LEAF */
  462. }
  463. }
  464. }
  465. static void share_pls_bothost(int idx, char *par)
  466. {
  467. char *hand, p[32];
  468. struct userrec *u;
  469. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  470. hand = newsplit(&par);
  471. if (!(u = get_user_by_handle(userlist, hand)) ||
  472. !(u->flags & USER_UNSHARED)) {
  473. if (!(dcc[idx].status & STAT_GETTING))
  474. shareout_but(NULL, idx, "+bh %s %s\n", hand, par);
  475. /* Add bot to userlist if not there */
  476. if (u) {
  477. if (!(u->flags & USER_BOT))
  478. return; /* ignore */
  479. set_user(&USERENTRY_HOSTS, u, par);
  480. } else {
  481. makepass(p);
  482. userlist = adduser(userlist, hand, par, p, USER_BOT);
  483. }
  484. #ifndef LEAF
  485. if (!(dcc[idx].status & STAT_GETTING))
  486. putlog(LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand, par);
  487. #endif /* LEAF */
  488. }
  489. }
  490. }
  491. static void share_mns_host(int idx, char *par)
  492. {
  493. char *hand;
  494. struct userrec *u;
  495. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  496. hand = newsplit(&par);
  497. if ((u = get_user_by_handle(userlist, hand)) &&
  498. !(u->flags & USER_UNSHARED)) {
  499. shareout_but(NULL, idx, "-h %s %s\n", hand, par);
  500. noshare = 1;
  501. delhost_by_handle(hand, par);
  502. noshare = 0;
  503. #ifdef LEAF
  504. check_this_user(hand, 2, par);
  505. #else /* !LEAF */
  506. putlog(LOG_CMDS, "@", "%s: -host %s %s", dcc[idx].nick, hand, par);
  507. #endif /* LEAF */
  508. }
  509. }
  510. }
  511. static void share_change(int idx, char *par)
  512. {
  513. char *key, *hand;
  514. struct userrec *u;
  515. struct user_entry_type *uet;
  516. struct user_entry *e;
  517. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  518. key = newsplit(&par);
  519. hand = newsplit(&par);
  520. if (!(u = get_user_by_handle(userlist, hand)) ||
  521. !(u->flags & USER_UNSHARED)) {
  522. if (!(uet = find_entry_type(key)))
  523. /* If it's not a supported type, forget it */
  524. debug2("Ignore ch %s from %s (unknown type)", key, dcc[idx].nick);
  525. else {
  526. if (!(dcc[idx].status & STAT_GETTING))
  527. shareout_but(NULL, idx, "c %s %s %s\n", key, hand, par);
  528. noshare = 1;
  529. if (!u && (uet == &USERENTRY_BOTADDR)) {
  530. char pass[30];
  531. makepass(pass);
  532. userlist = adduser(userlist, hand, "none", pass, USER_BOT);
  533. u = get_user_by_handle(userlist, hand);
  534. } else if (!u)
  535. return;
  536. if (uet->got_share) {
  537. if (!(e = find_user_entry(uet, u))) {
  538. e = user_malloc(sizeof(struct user_entry));
  539. e->type = uet;
  540. e->name = NULL;
  541. e->u.list = NULL;
  542. list_insert((&(u->entries)), e);
  543. }
  544. uet->got_share(u, e, par, idx);
  545. if (!e->u.list) {
  546. list_delete((struct list_type **) &(u->entries),
  547. (struct list_type *) e);
  548. nfree(e);
  549. }
  550. }
  551. noshare = 0;
  552. }
  553. }
  554. }
  555. }
  556. static void share_chchinfo(int idx, char *par)
  557. {
  558. char *hand, *chan;
  559. struct chanset_t *cst;
  560. struct userrec *u;
  561. if ((dcc[idx].status & STAT_SHARE) && !private_user) {
  562. hand = newsplit(&par);
  563. if ((u = get_user_by_handle(userlist, hand)) &&
  564. !(u->flags & USER_UNSHARED)) {
  565. chan = newsplit(&par);
  566. cst = findchan_by_dname(chan);
  567. fr.match = (FR_CHAN | FR_BOT);
  568. get_user_flagrec(dcc[idx].user, &fr, chan);
  569. if (!cst || !channel_shared(cst) || !(bot_chan(fr) || bot_global(fr)))
  570. putlog(LOG_CMDS, "*",
  571. "Info line change from %s denied. Channel %s not shared.",
  572. dcc[idx].nick, chan);
  573. else {
  574. shareout_but(cst, idx, "chchinfo %s %s %s\n", hand, chan, par);
  575. noshare = 1;
  576. set_handle_chaninfo(userlist, hand, chan, par);
  577. noshare = 0;
  578. putlog(LOG_CMDS, "@", "%s: change info %s %s", dcc[idx].nick,
  579. chan, hand);
  580. }
  581. }
  582. }
  583. }
  584. static void share_mns_ban(int idx, char *par)
  585. {
  586. struct chanset_t *chan = NULL;
  587. if (dcc[idx].status & STAT_SHARE) {
  588. shareout_but(NULL, idx, "-b %s\n", par);
  589. putlog(LOG_CMDS, "@", "%s: cancel ban %s", dcc[idx].nick, par);
  590. str_unescape(par, '\\');
  591. noshare = 1;
  592. if (u_delban(NULL, par, 1) > 0) {
  593. for (chan = chanset; chan; chan = chan->next)
  594. add_delay(chan, '-', 'b', par);
  595. }
  596. noshare = 0;
  597. }
  598. }
  599. static void share_mns_exempt(int idx, char *par)
  600. {
  601. struct chanset_t *chan = NULL;
  602. if (dcc[idx].status & STAT_SHARE) {
  603. shareout_but(NULL, idx, "-e %s\n", par);
  604. putlog(LOG_CMDS, "@", "%s: cancel exempt %s", dcc[idx].nick, par);
  605. str_unescape(par, '\\');
  606. noshare = 1;
  607. if (u_delexempt(NULL, par, 1) > 0) {
  608. for (chan = chanset; chan; chan = chan->next)
  609. add_delay(chan, '-', 'e', par);
  610. }
  611. noshare = 0;
  612. }
  613. }
  614. static void share_mns_invite(int idx, char *par)
  615. {
  616. struct chanset_t *chan = NULL;
  617. if (dcc[idx].status & STAT_SHARE) {
  618. shareout_but(NULL, idx, "-inv %s\n", par);
  619. putlog(LOG_CMDS, "@", "%s: cancel invite %s", dcc[idx].nick, par);
  620. str_unescape(par, '\\');
  621. noshare = 1;
  622. if (u_delinvite(NULL, par, 1) > 0) {
  623. for (chan = chanset; chan; chan = chan->next)
  624. add_delay(chan, '-', 'I', par);
  625. }
  626. noshare = 0;
  627. }
  628. }
  629. static void share_mns_banchan(int idx, char *par)
  630. {
  631. char *chname;
  632. struct chanset_t *chan;
  633. if (dcc[idx].status & STAT_SHARE) {
  634. chname = newsplit(&par);
  635. chan = findchan_by_dname(chname);
  636. fr.match = (FR_CHAN | FR_BOT);
  637. get_user_flagrec(dcc[idx].user, &fr, chname);
  638. if (!chan || !channel_shared(chan) ||
  639. !(bot_chan(fr) || bot_global(fr)))
  640. putlog(LOG_CMDS, "*",
  641. "Cancel channel ban %s on %s rejected - channel not shared.",
  642. par, chname);
  643. else {
  644. shareout_but(chan, idx, "-bc %s %s\n", chname, par);
  645. putlog(LOG_CMDS, "@", "%s: cancel ban %s on %s", dcc[idx].nick,
  646. par, chname);
  647. str_unescape(par, '\\');
  648. noshare = 1;
  649. if (u_delban(chan, par, 1) > 0)
  650. add_delay(chan, '-', 'b', par);
  651. noshare = 0;
  652. }
  653. }
  654. }
  655. static void share_mns_exemptchan(int idx, char *par)
  656. {
  657. char *chname;
  658. struct chanset_t *chan;
  659. if (dcc[idx].status & STAT_SHARE) {
  660. chname = newsplit(&par);
  661. chan = findchan_by_dname(chname);
  662. fr.match = (FR_CHAN | FR_BOT);
  663. get_user_flagrec(dcc[idx].user,&fr,chname);
  664. if (!chan || !channel_shared(chan) ||
  665. !(bot_chan(fr) || bot_global(fr)))
  666. putlog(LOG_CMDS, "*",
  667. "Cancel channel exempt %s on %s rejected - channel not shared.",
  668. par, chname);
  669. else {
  670. shareout_but(chan,idx, "-ec %s %s\n", chname, par);
  671. putlog(LOG_CMDS, "@", "%s: cancel exempt %s on %s", dcc[idx].nick,
  672. par, chname);
  673. str_unescape(par, '\\');
  674. noshare = 1;
  675. if (u_delexempt(chan, par, 1) > 0)
  676. add_delay(chan, '-', 'e', par);
  677. noshare = 0;
  678. }
  679. }
  680. }
  681. static void share_mns_invitechan (int idx, char *par)
  682. {
  683. char *chname;
  684. struct chanset_t *chan;
  685. if (dcc[idx].status & STAT_SHARE) {
  686. chname = newsplit(&par);
  687. chan = findchan_by_dname(chname);
  688. fr.match = (FR_CHAN | FR_BOT);
  689. get_user_flagrec(dcc[idx].user,&fr,chname);
  690. if (!chan || !channel_shared(chan) ||
  691. !(bot_chan(fr) || bot_global(fr)))
  692. putlog(LOG_CMDS, "*",
  693. "Cancel channel invite %s on %s rejected - channel not shared.",
  694. par, chname);
  695. else {
  696. shareout_but(chan,idx, "-invc %s %s\n", chname, par);
  697. putlog(LOG_CMDS, "@", "%s: cancel invite %s on %s", dcc[idx].nick,
  698. par, chname);
  699. str_unescape(par, '\\');
  700. noshare = 1;
  701. if (u_delinvite(chan, par, 1) > 0)
  702. add_delay(chan, '-', 'I', par);
  703. noshare = 0;
  704. }
  705. }
  706. }
  707. static void share_mns_ignore(int idx, char *par)
  708. {
  709. if (dcc[idx].status & STAT_SHARE) {
  710. shareout_but(NULL, idx, "-i %s\n", par);
  711. putlog(LOG_CMDS, "@", "%s: cancel ignore %s", dcc[idx].nick, par);
  712. str_unescape(par, '\\');
  713. noshare = 1;
  714. delignore(par);
  715. noshare = 0;
  716. }
  717. }
  718. static void share_pls_ban(int idx, char *par)
  719. {
  720. #ifdef LEAF
  721. struct chanset_t *chan;
  722. #endif /* LEAF */
  723. time_t expire_time;
  724. char *ban, *tm, *from;
  725. int flags = 0;
  726. if (dcc[idx].status & STAT_SHARE) {
  727. shareout_but(NULL, idx, "+b %s\n", par);
  728. noshare = 1;
  729. ban = newsplit(&par);
  730. str_unescape(ban, '\\');
  731. tm = newsplit(&par);
  732. from = newsplit(&par);
  733. if (strchr(from, 's'))
  734. flags |= MASKREC_STICKY;
  735. if (strchr(from, 'p'))
  736. flags |= MASKREC_PERM;
  737. from = newsplit(&par);
  738. expire_time = (time_t) atoi(tm);
  739. if (expire_time != 0L)
  740. expire_time += now;
  741. u_addban(NULL, ban, from, par, expire_time, flags);
  742. putlog(LOG_CMDS, "@", "%s: global ban %s (%s:%s)", dcc[idx].nick, ban,
  743. from, par);
  744. noshare = 0;
  745. #ifdef LEAF
  746. for (chan = chanset; chan != NULL; chan = chan->next)
  747. check_this_ban(chan, ban, 0);
  748. #endif /* LEAF */
  749. }
  750. }
  751. static void share_pls_banchan(int idx, char *par)
  752. {
  753. time_t expire_time;
  754. int flags = 0;
  755. struct chanset_t *chan;
  756. char *ban, *tm, *chname, *from;
  757. if (dcc[idx].status & STAT_SHARE) {
  758. ban = newsplit(&par);
  759. tm = newsplit(&par);
  760. chname = newsplit(&par);
  761. chan = findchan_by_dname(chname);
  762. fr.match = (FR_CHAN | FR_BOT);
  763. get_user_flagrec(dcc[idx].user, &fr, chname);
  764. if (!chan || !channel_shared(chan) ||
  765. !(bot_chan(fr) || bot_global(fr)))
  766. putlog(LOG_CMDS, "*",
  767. "Channel ban %s on %s rejected - channel not shared.",
  768. ban, chname);
  769. else {
  770. shareout_but(chan, idx, "+bc %s %s %s %s\n", ban, tm, chname, par);
  771. str_unescape(ban, '\\');
  772. from = newsplit(&par);
  773. if (strchr(from, 's'))
  774. flags |= MASKREC_STICKY;
  775. if (strchr(from, 'p'))
  776. flags |= MASKREC_PERM;
  777. from = newsplit(&par);
  778. putlog(LOG_CMDS, "@", "%s: ban %s on %s (%s:%s)", dcc[idx].nick,
  779. ban, chname, from, par);
  780. noshare = 1;
  781. expire_time = (time_t) atoi(tm);
  782. if (expire_time != 0L)
  783. expire_time += now;
  784. u_addban(chan, ban, from, par, expire_time, flags);
  785. noshare = 0;
  786. #ifdef LEAF
  787. check_this_ban(chan, ban, 0);
  788. #endif /* LEAF */
  789. }
  790. }
  791. }
  792. /* Same as share_pls_ban, only for exempts.
  793. */
  794. static void share_pls_exempt(int idx, char *par)
  795. {
  796. time_t expire_time;
  797. char *exempt, *tm, *from;
  798. int flags = 0;
  799. if (dcc[idx].status & STAT_SHARE) {
  800. shareout_but(NULL,idx, "+e %s\n", par);
  801. noshare = 1;
  802. exempt = newsplit(&par);
  803. str_unescape(exempt, '\\');
  804. tm = newsplit(&par);
  805. from = newsplit(&par);
  806. if (strchr(from,'s'))
  807. flags |= MASKREC_STICKY;
  808. if (strchr(from,'p'))
  809. flags |= MASKREC_PERM;
  810. from = newsplit(&par);
  811. expire_time = (time_t) atoi(tm);
  812. if (expire_time != 0L)
  813. expire_time += now;
  814. u_addexempt(NULL,exempt, from, par, expire_time,flags);
  815. putlog(LOG_CMDS, "@", "%s: global exempt %s (%s:%s)", dcc[idx].nick, exempt,
  816. from, par);
  817. noshare = 0;
  818. }
  819. }
  820. /* Same as share_pls_banchan, only for exempts.
  821. */
  822. static void share_pls_exemptchan(int idx, char *par)
  823. {
  824. time_t expire_time;
  825. int flags = 0;
  826. struct chanset_t *chan;
  827. char *exempt, *tm, *chname, *from;
  828. if (dcc[idx].status & STAT_SHARE) {
  829. exempt = newsplit(&par);
  830. tm = newsplit(&par);
  831. chname = newsplit(&par);
  832. chan = findchan_by_dname(chname);
  833. fr.match = (FR_CHAN | FR_BOT);
  834. get_user_flagrec(dcc[idx].user,&fr,chname);
  835. if (!chan || !channel_shared(chan) ||
  836. !(bot_chan(fr) || bot_global(fr)))
  837. putlog(LOG_CMDS, "*",
  838. "Channel exempt %s on %s rejected - channel not shared.",
  839. exempt, chname);
  840. else {
  841. shareout_but(chan,idx, "+ec %s %s %s %s\n", exempt, tm, chname, par);
  842. str_unescape(exempt, '\\');
  843. from = newsplit(&par);
  844. if (strchr(from,'s'))
  845. flags |= MASKREC_STICKY;
  846. if (strchr(from,'p'))
  847. flags |= MASKREC_PERM;
  848. from = newsplit(&par);
  849. putlog(LOG_CMDS, "@", "%s: exempt %s on %s (%s:%s)", dcc[idx].nick,
  850. exempt, chname, from, par);
  851. noshare = 1;
  852. expire_time = (time_t) atoi(tm);
  853. if (expire_time != 0L)
  854. expire_time += now;
  855. u_addexempt(chan, exempt, from, par, expire_time,flags);
  856. noshare = 0;
  857. }
  858. }
  859. }
  860. /* Same as share_pls_ban, only for invites.
  861. */
  862. static void share_pls_invite(int idx, char *par)
  863. {
  864. time_t expire_time;
  865. char *invite, *tm, *from;
  866. int flags = 0;
  867. if (dcc[idx].status & STAT_SHARE) {
  868. shareout_but(NULL,idx, "+inv %s\n", par);
  869. noshare = 1;
  870. invite = newsplit(&par);
  871. str_unescape(invite, '\\');
  872. tm = newsplit(&par);
  873. from = newsplit(&par);
  874. if (strchr(from,'s'))
  875. flags |= MASKREC_STICKY;
  876. if (strchr(from,'p'))
  877. flags |= MASKREC_PERM;
  878. from = newsplit(&par);
  879. expire_time = (time_t) atoi(tm);
  880. if (expire_time != 0L)
  881. expire_time += now;
  882. u_addinvite(NULL,invite, from, par, expire_time,flags);
  883. putlog(LOG_CMDS, "@", "%s: global invite %s (%s:%s)", dcc[idx].nick,
  884. invite, from, par);
  885. noshare = 0;
  886. }
  887. }
  888. /* Same as share_pls_banchan, only for invites.
  889. */
  890. static void share_pls_invitechan(int idx, char *par)
  891. {
  892. time_t expire_time;
  893. int flags = 0;
  894. struct chanset_t *chan;
  895. char *invite, *tm, *chname, *from;
  896. if (dcc[idx].status & STAT_SHARE) {
  897. invite = newsplit(&par);
  898. tm = newsplit(&par);
  899. chname = newsplit(&par);
  900. chan = findchan_by_dname(chname);
  901. fr.match = (FR_CHAN | FR_BOT);
  902. get_user_flagrec(dcc[idx].user,&fr,chname);
  903. if (!chan || !channel_shared(chan) ||
  904. !(bot_chan(fr) || bot_global(fr)))
  905. putlog(LOG_CMDS, "*",
  906. "Channel invite %s on %s rejected - channel not shared.",
  907. invite, chname);
  908. else {
  909. shareout_but(chan,idx, "+invc %s %s %s %s\n", invite, tm, chname, par);
  910. str_unescape(invite, '\\');
  911. from = newsplit(&par);
  912. if (strchr(from,'s'))
  913. flags |= MASKREC_STICKY;
  914. if (strchr(from,'p'))
  915. flags |= MASKREC_PERM;
  916. from = newsplit(&par);
  917. putlog(LOG_CMDS, "@", "%s: invite %s on %s (%s:%s)", dcc[idx].nick,
  918. invite, chname, from, par);
  919. noshare = 1;
  920. expire_time = (time_t) atoi(tm);
  921. if (expire_time != 0L)
  922. expire_time += now;
  923. u_addinvite(chan, invite, from, par, expire_time,flags);
  924. noshare = 0;
  925. }
  926. }
  927. }
  928. /* +i <host> +<seconds-left> <from> <note>
  929. */
  930. static void share_pls_ignore(int idx, char *par)
  931. {
  932. time_t expire_time;
  933. char *ign, *from, *ts;
  934. if (dcc[idx].status & STAT_SHARE) {
  935. shareout_but(NULL, idx, "+i %s\n", par);
  936. noshare = 1;
  937. ign = newsplit(&par);
  938. str_unescape(ign, '\\');
  939. ts = newsplit(&par);
  940. if (!atoi(ts))
  941. expire_time = 0L;
  942. else
  943. expire_time = now + atoi(ts);
  944. from = newsplit(&par);
  945. if (strchr(from, 'p'))
  946. expire_time = 0;
  947. from = newsplit(&par);
  948. if (strlen(from) > HANDLEN + 1)
  949. from[HANDLEN + 1] = 0;
  950. par[65] = 0;
  951. putlog(LOG_CMDS, "@", "%s: ignore %s (%s: %s)",
  952. dcc[idx].nick, ign, from, par);
  953. addignore(ign, from, par, expire_time);
  954. noshare = 0;
  955. }
  956. }
  957. static void share_ufno(int idx, char *par)
  958. {
  959. putlog(LOG_BOTS, "@", "User file rejected by %s: %s",
  960. dcc[idx].nick, par);
  961. dcc[idx].status &= ~STAT_OFFERED;
  962. if (!(dcc[idx].status & STAT_GETTING))
  963. dcc[idx].status &= ~(STAT_SHARE | STAT_AGGRESSIVE);
  964. }
  965. static void share_ufyes(int idx, char *par)
  966. {
  967. if (dcc[idx].status & STAT_OFFERED) {
  968. dcc[idx].status &= ~STAT_OFFERED;
  969. dcc[idx].status |= STAT_SHARE;
  970. dcc[idx].status |= STAT_SENDING;
  971. uf_features_parse(idx, par);
  972. lower_bot_linked(idx);
  973. start_sending_users(idx);
  974. putlog(LOG_BOTS, "@", "Sending user file send request to %s",
  975. dcc[idx].nick);
  976. }
  977. }
  978. static void share_userfileq(int idx, char *par)
  979. {
  980. int ok = 1, i;
  981. flush_tbuf(dcc[idx].nick);
  982. if (bot_aggressive_to(dcc[idx].user)) {
  983. putlog(LOG_ERRORS, "*", STR("%s offered user transfer - I'm supposed to be aggressive to it"), dcc[idx].nick);
  984. dprintf(idx, STR("s un I have you marked for Agressive sharing.\n"));
  985. botunlink(-2, dcc[idx].nick, STR("I'm aggressive to you"));
  986. }
  987. else {
  988. for (i = 0; i < dcc_total; i++)
  989. if (dcc[i].type->flags & DCT_BOT) {
  990. if ((dcc[i].status & STAT_SHARE) &&
  991. (dcc[i].status & STAT_AGGRESSIVE) && (i != idx)) {
  992. ok = 0;
  993. break;
  994. }
  995. }
  996. if (!ok)
  997. dprintf(idx, "s un Already sharing.\n");
  998. else {
  999. if (dcc[idx].u.bot->numver >= min_uffeature)
  1000. dprintf(idx, "s uy %s\n", uf_features_dump(idx));
  1001. else
  1002. dprintf(idx, "s uy\n");
  1003. /* Set stat-getting to astatic void race condition (robey 23jun1996) */
  1004. dcc[idx].status |= STAT_SHARE | STAT_GETTING | STAT_AGGRESSIVE;
  1005. #ifdef HUB
  1006. putlog(LOG_BOTS, "@", "Downloading user file from %s", dcc[idx].nick);
  1007. #else /* !HUB */
  1008. putlog(LOG_BOTS, "@", "Downloading user file via uplink.");
  1009. #endif /* HUB */
  1010. }
  1011. }
  1012. }
  1013. /* us <ip> <port> <length>
  1014. */
  1015. static void share_ufsend(int idx, char *par)
  1016. {
  1017. char *ip=NULL, *port;
  1018. char s[1024];
  1019. int i, sock;
  1020. FILE *f;
  1021. egg_snprintf(s, sizeof s, "%s.share.%s.%lu.users", tempdir, botnetnick, now);
  1022. if (!(b_status(idx) & STAT_SHARE)) {
  1023. dprintf(idx, "s e You didn't ask; you just started sending.\n");
  1024. dprintf(idx, "s e Ask before sending the userfile.\n");
  1025. zapfbot(idx);
  1026. } else if (dcc_total == max_dcc) {
  1027. putlog(LOG_MISC, "@", "NO MORE DCC CONNECTIONS -- can't grab userfile");
  1028. dprintf(idx, "s e I can't open a DCC to you; I'm full.\n");
  1029. zapfbot(idx);
  1030. } else if (!(f = fopen(s, "wb"))) {
  1031. putlog(LOG_MISC, "@", "CAN'T WRITE USERFILE DOWNLOAD FILE!");
  1032. zapfbot(idx);
  1033. } else {
  1034. ip = newsplit(&par);
  1035. port = newsplit(&par);
  1036. #ifdef USE_IPV6
  1037. sock = getsock(SOCK_BINARY, hostprotocol(ip)); /* Don't buffer this -> mark binary. */
  1038. #else
  1039. sock = getsock(SOCK_BINARY); /* Don't buffer this -> mark binary. */
  1040. #endif /* USE_IPV6 */
  1041. if (sock < 0 || open_telnet_dcc(sock, ip, port) < 0) {
  1042. killsock(sock);
  1043. putlog(LOG_BOTS, "@", "Asynchronous connection failed!");
  1044. dprintf(idx, "s e Can't connect to you!\n");
  1045. zapfbot(idx);
  1046. } else {
  1047. putlog(LOG_DEBUG, "@", "Connecting to %s:%s for userfile.", ip, port);
  1048. i = new_dcc(&DCC_FORK_SEND, sizeof(struct xfer_info));
  1049. dcc[i].addr = my_atoul(ip);
  1050. dcc[i].port = atoi(port);
  1051. strcpy(dcc[i].nick, "*users");
  1052. dcc[i].u.xfer->filename = nmalloc(strlen(s) + 1);
  1053. strcpy(dcc[i].u.xfer->filename, s);
  1054. dcc[i].u.xfer->origname = dcc[i].u.xfer->filename;
  1055. dcc[i].u.xfer->length = atoi(par);
  1056. dcc[i].u.xfer->f = f;
  1057. dcc[i].sock = sock;
  1058. strcpy(dcc[i].host, dcc[idx].nick);
  1059. dcc[idx].status |= STAT_GETTING;
  1060. }
  1061. }
  1062. }
  1063. static void share_resyncq(int idx, char *par)
  1064. {
  1065. if (!allow_resync)
  1066. dprintf(idx, "s rn Not permitting resync.\n");
  1067. else {
  1068. if (can_resync(dcc[idx].nick)) {
  1069. dprintf(idx, STR("s r!\n"));
  1070. dump_resync(idx);
  1071. dcc[idx].status &= ~STAT_OFFERED;
  1072. dcc[idx].status |= STAT_SHARE;
  1073. putlog(LOG_BOTS, "*", STR("Resync'd user file with %s"), dcc[idx].nick);
  1074. updatebot(-1, dcc[idx].nick, '+', 0);
  1075. } else if (!bot_aggressive_to(dcc[idx].user)) {
  1076. dprintf(idx, STR("s r!\n"));
  1077. dcc[idx].status &= ~STAT_OFFERED;
  1078. dcc[idx].status |= STAT_SHARE;
  1079. updatebot(-1, dcc[idx].nick, '+', 0);
  1080. putlog(LOG_BOTS, "@", STR("Resyncing user file from %s"), dcc[idx].nick);
  1081. } else
  1082. dprintf(idx, STR("s rn No resync buffer.\n"));
  1083. }
  1084. }
  1085. static void share_resync(int idx, char *par)
  1086. {
  1087. if ((dcc[idx].status & STAT_OFFERED) && can_resync(dcc[idx].nick)) {
  1088. dump_resync(idx);
  1089. dcc[idx].status &= ~STAT_OFFERED;
  1090. dcc[idx].status |= STAT_SHARE;
  1091. updatebot(-1, dcc[idx].nick, '+', 0);
  1092. putlog(LOG_BOTS, "@", "Resync'd user file with %s", dcc[idx].nick);
  1093. }
  1094. }
  1095. static void share_resync_no(int idx, char *par)
  1096. {
  1097. putlog(LOG_BOTS, "@", "Resync refused by %s: %s", dcc[idx].nick, par);
  1098. flush_tbuf(dcc[idx].nick);
  1099. dprintf(idx, "s u?\n");
  1100. }
  1101. static void share_version(int idx, char *par)
  1102. {
  1103. /* Cleanup any share flags */
  1104. dcc[idx].status &= ~(STAT_SHARE | STAT_GETTING | STAT_SENDING |
  1105. STAT_OFFERED | STAT_AGGRESSIVE);
  1106. dcc[idx].u.bot->uff_flags = 0;
  1107. if (1 && //only share with same VER bots.
  1108. (bot_aggressive_to(dcc[idx].user))) {
  1109. if (can_resync(dcc[idx].nick))
  1110. dprintf(idx, "s r?\n");
  1111. else
  1112. dprintf(idx, "s u?\n");
  1113. dcc[idx].status |= STAT_OFFERED;
  1114. } else
  1115. higher_bot_linked(idx);
  1116. }
  1117. static void hook_read_userfile()
  1118. {
  1119. int i;
  1120. if (!noshare) {
  1121. for (i = 0; i < dcc_total; i++)
  1122. if ((dcc[i].type->flags & DCT_BOT) && (dcc[i].status & STAT_SHARE) &&
  1123. !(dcc[i].status & STAT_AGGRESSIVE) &&
  1124. (1)) {
  1125. /* Cancel any existing transfers */
  1126. if (dcc[i].status & STAT_SENDING)
  1127. cancel_user_xfer(-i, 0);
  1128. dprintf(i, "s u?\n");
  1129. dcc[i].status |= STAT_OFFERED;
  1130. }
  1131. }
  1132. }
  1133. static void share_endstartup(int idx, char *par)
  1134. {
  1135. dcc[idx].status &= ~STAT_GETTING;
  1136. /* Send to any other sharebots */
  1137. hook_read_userfile();
  1138. }
  1139. static void share_end(int idx, char *par)
  1140. {
  1141. putlog(LOG_BOTS, "@", "Ending sharing with %s (%s).", dcc[idx].nick, par);
  1142. cancel_user_xfer(-idx, 0);
  1143. dcc[idx].status &= ~(STAT_SHARE | STAT_GETTING | STAT_SENDING |
  1144. STAT_OFFERED | STAT_AGGRESSIVE);
  1145. dcc[idx].u.bot->uff_flags = 0;
  1146. }
  1147. static void share_feats(int idx, char *par)
  1148. {
  1149. (int) uf_features_check(idx, par);
  1150. }
  1151. /* Note: these MUST be sorted. */
  1152. static botcmd_t C_share[] =
  1153. {
  1154. {"!", (Function) share_endstartup},
  1155. {"+b", (Function) share_pls_ban},
  1156. {"+bc", (Function) share_pls_banchan},
  1157. {"+bh", (Function) share_pls_bothost},
  1158. {"+cr", (Function) share_pls_chrec},
  1159. {"+e", (Function) share_pls_exempt},
  1160. {"+ec", (Function) share_pls_exemptchan},
  1161. {"+h", (Function) share_pls_host},
  1162. {"+i", (Function) share_pls_ignore},
  1163. {"+inv", (Function) share_pls_invite},
  1164. {"+invc", (Function) share_pls_invitechan},
  1165. {"-b", (Function) share_mns_ban},
  1166. {"-bc", (Function) share_mns_banchan},
  1167. {"-cr", (Function) share_mns_chrec},
  1168. {"-e", (Function) share_mns_exempt},
  1169. {"-ec", (Function) share_mns_exemptchan},
  1170. {"-h", (Function) share_mns_host},
  1171. {"-i", (Function) share_mns_ignore},
  1172. {"-inv", (Function) share_mns_invite},
  1173. {"-invc", (Function) share_mns_invitechan},
  1174. {"a", (Function) share_chattr},
  1175. {"c", (Function) share_change},
  1176. {"chchinfo", (Function) share_chchinfo},
  1177. {"e", (Function) share_end},
  1178. {"feats", (Function) share_feats},
  1179. {"h", (Function) share_chhand},
  1180. {"k", (Function) share_killuser},
  1181. {"n", (Function) share_newuser},
  1182. {"r!", (Function) share_resync},
  1183. {"r?", (Function) share_resyncq},
  1184. {"rn", (Function) share_resync_no},
  1185. {"s", (Function) share_stick_ban},
  1186. {"se", (Function) share_stick_exempt},
  1187. {"sInv", (Function) share_stick_invite},
  1188. {"u?", (Function) share_userfileq},
  1189. {"un", (Function) share_ufno},
  1190. {"us", (Function) share_ufsend},
  1191. {"uy", (Function) share_ufyes},
  1192. {"v", (Function) share_version},
  1193. {NULL, NULL}
  1194. };
  1195. static void sharein_mod(int idx, char *msg)
  1196. {
  1197. char *code;
  1198. int f, i;
  1199. code = newsplit(&msg);
  1200. for (f = 0, i = 0; C_share[i].name && !f; i++) {
  1201. int y = egg_strcasecmp(code, C_share[i].name);
  1202. if (!y)
  1203. /* Found a match */
  1204. (C_share[i].func)(idx, msg);
  1205. if (y < 0)
  1206. f = 1;
  1207. }
  1208. }
  1209. static void shareout_mod EGG_VARARGS_DEF(struct chanset_t *, arg1)
  1210. {
  1211. int i, l;
  1212. char *format;
  1213. char s[601];
  1214. struct chanset_t *chan;
  1215. va_list va;
  1216. chan = EGG_VARARGS_START(struct chanset_t *, arg1, va);
  1217. if (!chan || channel_shared(chan)) {
  1218. format = va_arg(va, char *);
  1219. strcpy(s, "s ");
  1220. if ((l = egg_vsnprintf(s + 2, 509, format, va)) < 0)
  1221. s[2 + (l = 509)] = 0;
  1222. for (i = 0; i < dcc_total; i++)
  1223. if ((dcc[i].type->flags & DCT_BOT) &&
  1224. (dcc[i].status & STAT_SHARE) &&
  1225. !(dcc[i].status & (STAT_GETTING | STAT_SENDING))) {
  1226. if (chan) {
  1227. fr.match = (FR_CHAN | FR_BOT);
  1228. get_user_flagrec(dcc[i].user, &fr, chan->dname);
  1229. }
  1230. if (!chan || bot_chan(fr) || bot_global(fr))
  1231. tputs(dcc[i].sock, s, l + 2);
  1232. }
  1233. q_resync(s, chan);
  1234. }
  1235. va_end(va);
  1236. }
  1237. static void shareout_but EGG_VARARGS_DEF(struct chanset_t *, arg1)
  1238. {
  1239. int i, x, l;
  1240. char *format;
  1241. char s[601];
  1242. struct chanset_t *chan;
  1243. va_list va;
  1244. chan = EGG_VARARGS_START(struct chanset_t *, arg1, va);
  1245. x = va_arg(va, int);
  1246. format = va_arg(va, char *);
  1247. strcpy(s, "s ");
  1248. if ((l = egg_vsnprintf(s + 2, 509, format, va)) < 0)
  1249. s[2 + (l = 509)] = 0;
  1250. for (i = 0; i < dcc_total; i++)
  1251. if ((dcc[i].type->flags & DCT_BOT) && (i != x) &&
  1252. (dcc[i].status & STAT_SHARE) &&
  1253. (!(dcc[i].status & STAT_GETTING)) &&
  1254. (!(dcc[i].status & STAT_SENDING))) {
  1255. if (chan) {
  1256. fr.match = (FR_CHAN | FR_BOT);
  1257. get_user_flagrec(dcc[i].user, &fr, chan->dname);
  1258. }
  1259. if (!chan || bot_chan(fr) || bot_global(fr))
  1260. tputs(dcc[i].sock, s, l + 2);
  1261. }
  1262. q_resync(s, chan);
  1263. va_end(va);
  1264. }
  1265. /*
  1266. * Resync buffers
  1267. */
  1268. /* Create a tandem buffer for 'bot'.
  1269. */
  1270. static void new_tbuf(char *bot)
  1271. {
  1272. tandbuf **old = &tbuf, *new;
  1273. new = nmalloc(sizeof(tandbuf));
  1274. strcpy(new->bot, bot);
  1275. new->q = NULL;
  1276. new->timer = now;
  1277. new->next = *old;
  1278. *old = new;
  1279. putlog(LOG_BOTS, "@", "Creating resync buffer for %s", bot);
  1280. }
  1281. static void del_tbuf(tandbuf *goner)
  1282. {
  1283. struct share_msgq *q, *r;
  1284. tandbuf *t = NULL, *old = NULL;
  1285. for (t = tbuf; t; old = t, t = t->next) {
  1286. if (t == goner) {
  1287. if (old)
  1288. old->next = t->next;
  1289. else
  1290. tbuf = t->next;
  1291. for (q = t->q; q && q->msg[0]; q = r) {
  1292. r = q->next;
  1293. nfree(q->msg);
  1294. nfree(q);
  1295. }
  1296. nfree(t);
  1297. break;
  1298. }
  1299. }
  1300. }
  1301. /* Flush a certain bot's tbuf.
  1302. */
  1303. static int flush_tbuf(char *bot)
  1304. {
  1305. tandbuf *t, *tnext = NULL;
  1306. for (t = tbuf; t; t = tnext) {
  1307. tnext = t->next;
  1308. if (!egg_strcasecmp(t->bot, bot)) {
  1309. del_tbuf(t);
  1310. return 1;
  1311. }
  1312. }
  1313. return 0;
  1314. }
  1315. /* Flush all tbufs older than 15 minutes.
  1316. */
  1317. static void check_expired_tbufs()
  1318. {
  1319. int i;
  1320. tandbuf *t, *tnext = NULL;
  1321. for (t = tbuf; t; t = tnext) {
  1322. tnext = t->next;
  1323. if ((now - t->timer) > resync_time) {
  1324. putlog(LOG_BOTS, "@", "Flushing resync buffer for clonebot %s.",
  1325. t->bot);
  1326. del_tbuf(t);
  1327. }
  1328. }
  1329. /* Resend userfile requests */
  1330. for (i = 0; i < dcc_total; i++)
  1331. if (dcc[i].type->flags & DCT_BOT) {
  1332. if (dcc[i].status & STAT_OFFERED) {
  1333. if (now - dcc[i].timeval > 120) {
  1334. if (dcc[i].user && bot_aggressive_to(dcc[i].user))
  1335. dprintf(i, "s u?\n");
  1336. /* ^ send it again in case they missed it */
  1337. }
  1338. /* If it's a share bot that hasnt been sharing, ask again */
  1339. } else if (!(dcc[i].status & STAT_SHARE)) {
  1340. if (dcc[i].user && bot_aggressive_to(dcc[i].user)) {
  1341. dprintf(i, "s u?\n");
  1342. dcc[i].status |= STAT_OFFERED;
  1343. }
  1344. }
  1345. }
  1346. }
  1347. static struct share_msgq *q_addmsg(struct share_msgq *qq,
  1348. struct chanset_t *chan, char *s)
  1349. {
  1350. struct share_msgq *q;
  1351. int cnt;
  1352. if (!qq) {
  1353. q = (struct share_msgq *) nmalloc(sizeof(struct share_msgq));
  1354. q->chan = chan;
  1355. q->next = NULL;
  1356. q->msg = (char *) nmalloc(strlen(s) + 1);
  1357. strcpy(q->msg, s);
  1358. return q;
  1359. }
  1360. cnt = 0;
  1361. for (q = qq; q->next; q = q->next)
  1362. cnt++;
  1363. if (cnt > 1000)
  1364. return NULL; /* Return null: did not alter queue */
  1365. q->next = (struct share_msgq *) nmalloc(sizeof(struct share_msgq));
  1366. q = q->next;
  1367. q->chan = chan;
  1368. q->next = NULL;
  1369. q->msg = (char *) nmalloc(strlen(s) + 1);
  1370. strcpy(q->msg, s);
  1371. return qq;
  1372. }
  1373. /* Add stuff to a specific bot's tbuf.
  1374. */
  1375. static void q_tbuf(char *bot, char *s, struct chanset_t *chan)
  1376. {
  1377. struct share_msgq *q;
  1378. tandbuf *t;
  1379. for (t = tbuf; t && t->bot[0]; t = t->next)
  1380. if (!egg_strcasecmp(t->bot, bot)) {
  1381. if (chan) {
  1382. fr.match = (FR_CHAN | FR_BOT);
  1383. get_user_flagrec(get_user_by_handle(userlist, bot), &fr, chan->dname);
  1384. }
  1385. if ((!chan || bot_chan(fr) || bot_global(fr))
  1386. && (q = q_addmsg(t->q, chan, s)))
  1387. t->q = q;
  1388. break;
  1389. }
  1390. }
  1391. /* Add stuff to the resync buffers.
  1392. */
  1393. static void q_resync(char *s, struct chanset_t *chan)
  1394. {
  1395. struct share_msgq *q;
  1396. tandbuf *t;
  1397. for (t = tbuf; t && t->bot[0]; t = t->next) {
  1398. if (chan) {
  1399. fr.match = (FR_CHAN | FR_BOT);
  1400. get_user_flagrec(get_user_by_handle(userlist, t->bot), &fr,
  1401. chan->dname);
  1402. }
  1403. if ((!chan || bot_chan(fr) || bot_global(fr))
  1404. && (q = q_addmsg(t->q, chan, s)))
  1405. t->q = q;
  1406. }
  1407. }
  1408. /* Is bot in resync list?
  1409. */
  1410. static int can_resync(char *bot)
  1411. {
  1412. tandbuf *t;
  1413. for (t = tbuf; t && t->bot[0]; t = t->next)
  1414. if (!egg_strcasecmp(bot, t->bot))
  1415. return 1;
  1416. return 0;
  1417. }
  1418. /* Dump the resync buffer for a bot.
  1419. */
  1420. static void dump_resync(int idx)
  1421. {
  1422. struct share_msgq *q;
  1423. tandbuf *t;
  1424. for (t = tbuf; t && t->bot[0]; t = t->next)
  1425. if (!egg_strcasecmp(dcc[idx].nick, t->bot)) {
  1426. for (q = t->q; q && q->msg[0]; q = q->next) {
  1427. dprintf(idx, "%s", q->msg);
  1428. }
  1429. flush_tbuf(dcc[idx].nick);
  1430. break;
  1431. }
  1432. }
  1433. /* Give status report on tbufs.
  1434. */
  1435. static void status_tbufs(int idx)
  1436. {
  1437. int count, off = 0;
  1438. struct share_msgq *q;
  1439. char s[121];
  1440. tandbuf *t;
  1441. off = 0;
  1442. for (t = tbuf; t && t->bot[0]; t = t->next)
  1443. if (off < (110 - HANDLEN)) {
  1444. off += my_strcpy(s + off, t->bot);
  1445. count = 0;
  1446. for (q = t->q; q; q = q->next)
  1447. count++;
  1448. off += simple_sprintf(s + off, " (%d), ", count);
  1449. }
  1450. if (off) {
  1451. s[off - 2] = 0;
  1452. dprintf(idx, "Pending sharebot buffers: %s\n", s);
  1453. }
  1454. }
  1455. static int write_tmp_userfile(char *fn, struct userrec *bu, int idx)
  1456. {
  1457. FILE *f;
  1458. struct userrec *u;
  1459. int ok = 0;
  1460. if ((f = fopen(fn, "wb"))) {
  1461. chmod(fn, 0600); /* make it -rw------- */
  1462. lfprintf(f, "#4v: %s -- %s -- transmit\n", ver, botnetnick);
  1463. ok = 1;
  1464. if (!write_chans(f, idx))
  1465. ok = 0;
  1466. if (!write_bans(f, idx))
  1467. ok = 0;
  1468. if (!write_config(f, idx))
  1469. ok = 0;
  1470. /* Only share with bots which support exempts and invites.
  1471. *
  1472. * If UFF is supported, we also check the UFF flags before sharing. If
  1473. * UFF isn't supported, but +I/+e is supported, we just share.
  1474. */
  1475. if (dcc[idx].u.bot->numver >= min_exemptinvite) {
  1476. if ((dcc[idx].u.bot->uff_flags & UFF_EXEMPT) ||
  1477. (dcc[idx].u.bot->numver < min_uffeature))
  1478. if (!write_exempts(f, idx))
  1479. ok = 0;
  1480. if ((dcc[idx].u.bot->uff_flags & UFF_INVITE) ||
  1481. (dcc[idx].u.bot->numver < min_uffeature))
  1482. if (!write_invites(f,idx))
  1483. ok = 0;
  1484. } else
  1485. putlog(LOG_BOTS, "@", "%s is too old: not sharing exempts and invites.",
  1486. dcc[idx].nick);
  1487. for (u = bu; u && ok; u = u->next)
  1488. if (!write_user(u, f, idx))
  1489. ok = 0;
  1490. fclose(f);
  1491. }
  1492. if (!ok)
  1493. putlog(LOG_MISC, "@", USERF_ERRWRITE2);
  1494. return ok;
  1495. }
  1496. /* Create a copy of the entire userlist (for sending user lists to clone
  1497. * bots) -- userlist is reversed in the process, which is OK because the
  1498. * receiving bot reverses the list AGAIN when saving.
  1499. *
  1500. * t = 0: copy everything BUT tandem-bots
  1501. * t = 1: copy only tandem-bots
  1502. * t = 2; copy all entries
  1503. */
  1504. static struct userrec *dup_userlist(int t)
  1505. {
  1506. struct userrec *u, *u1, *retu, *nu;
  1507. struct chanuserrec *ch;
  1508. struct user_entry *ue;
  1509. char *p;
  1510. nu = retu = NULL;
  1511. noshare = 1;
  1512. for (u = userlist; u; u = u->next)
  1513. /* Only copying non-bot entries? */
  1514. if (((t == 0) && !(u->flags & (USER_BOT | USER_UNSHARED))) ||
  1515. /* ... or only copying bot entries? */
  1516. ((t == 1) && (u->flags & (USER_BOT | USER_UNSHARED))) ||
  1517. /* ... or copying everything? */
  1518. (t == 2)) {
  1519. p = get_user(&USERENTRY_PASS, u);
  1520. u1 = adduser(NULL, u->handle, 0, p, u->flags);
  1521. u1->flags_udef = u->flags_udef;
  1522. if (!nu)
  1523. nu = retu = u1;
  1524. else {
  1525. nu->next = u1;
  1526. nu = nu->next;
  1527. }
  1528. for (ch = u->chanrec; ch; ch = ch->next) {
  1529. struct chanuserrec *z = add_chanrec(nu, ch->channel);
  1530. if (z) {
  1531. z->flags = ch->flags;
  1532. z->flags_udef = ch->flags_udef;
  1533. z->laston = ch->laston;
  1534. set_handle_chaninfo(nu, nu->handle, ch->channel, ch->info);
  1535. }
  1536. }
  1537. for (ue = u->entries; ue; ue = ue->next) {
  1538. if (ue->name) {
  1539. struct list_type *lt;
  1540. struct user_entry *nue;
  1541. nue = user_malloc(sizeof(struct user_entry));
  1542. nue->name = user_malloc(strlen(ue->name) + 1);
  1543. nue->type = NULL;
  1544. nue->u.list = NULL;
  1545. strcpy(nue->name, ue->name);
  1546. list_insert((&nu->entries), nue);
  1547. for (lt = ue->u.list; lt; lt = lt->next) {
  1548. struct list_type *list;
  1549. list = user_malloc(sizeof(struct list_type));
  1550. list->next = NULL;
  1551. list->extra = user_malloc(strlen(lt->extra) + 1);
  1552. strcpy(list->extra, lt->extra);
  1553. list_append((&nue->u.list), list);
  1554. }
  1555. } else {
  1556. if (ue->type->dup_user && (t || ue->type->got_share))
  1557. ue->type->dup_user(nu, u, ue);
  1558. }
  1559. }
  1560. }
  1561. noshare = 0;
  1562. return retu;
  1563. }
  1564. /* Erase old user list, switch to new one.
  1565. */
  1566. static void finish_share(int idx)
  1567. {
  1568. struct userrec *u = NULL, *ou = NULL;
  1569. struct chanset_t *chan;
  1570. int i, j = -1;
  1571. for (i = 0; i < dcc_total; i++)
  1572. if (!egg_strcasecmp(dcc[i].nick, dcc[idx].host) &&
  1573. (dcc[i].type->flags & DCT_BOT))
  1574. j = i;
  1575. if (j == -1)
  1576. return;
  1577. if (!uff_call_receiving(j, dcc[idx].u.xfer->filename)) {
  1578. putlog(LOG_BOTS, "@", "A uff parsing function failed for the userfile!");
  1579. unlink(dcc[idx].u.xfer->filename);
  1580. return;
  1581. }
  1582. if (dcc[j].u.bot->uff_flags & UFF_OVERRIDE)
  1583. debug1("NOTE: Sharing passively with %s, overriding local bots.",
  1584. dcc[j].nick);
  1585. else
  1586. /* Copy the bots over. The entries will be used in the new user list. */
  1587. u = dup_userlist(1);
  1588. /*
  1589. * This is where we remove all global and channel bans/exempts/invites and
  1590. * ignores since they will be replaced by what our hub gives us.
  1591. */
  1592. noshare = 1;
  1593. fr.match = (FR_CHAN | FR_BOT);
  1594. while (global_bans)
  1595. u_delban(NULL, global_bans->mask, 1);
  1596. while (global_ign)
  1597. delignore(global_ign->igmask);
  1598. while (global_invites)
  1599. u_delinvite(NULL, global_invites->mask, 1);
  1600. while (global_exempts)
  1601. u_delexempt(NULL, global_exempts->mask, 1);
  1602. for (chan = chanset; chan; chan = chan->next)
  1603. if (channel_shared(chan)) {
  1604. get_user_flagrec(dcc[j].user, &fr, chan->dname);
  1605. if (bot_chan(fr) || bot_global(fr)) {
  1606. while (chan->bans)
  1607. u_delban(chan, chan->bans->mask, 1);
  1608. while (chan->exempts)
  1609. u_delexempt(chan, chan->exempts->mask, 1);
  1610. while (chan->invites)
  1611. u_delinvite(chan, chan->invites->mask, 1);
  1612. }
  1613. }
  1614. noshare = 0;
  1615. ou = userlist; /* Save old user list */
  1616. userlist = (void *) -1; /* Do this to prevent .user messups */
  1617. /* Bot user pointers are updated to point to the new list, all others
  1618. * are set to NULL. If our userfile will be overriden, just set _all_
  1619. * to NULL directly.
  1620. */
  1621. if (u == NULL)
  1622. for (i = 0; i < dcc_total; i++)
  1623. dcc[i].user = NULL;
  1624. else
  1625. for (i = 0; i < dcc_total; i++)
  1626. dcc[i].user = get_user_by_handle(u, dcc[i].nick);
  1627. /* Read the transferred userfile. Add entries to u, which already holds
  1628. * the bot entries in non-override mode.
  1629. */
  1630. loading = 1;
  1631. checkchans(0); /* flag all the channels.. */
  1632. Context;
  1633. if (!readuserfile(dcc[idx].u.xfer->filename, &u)) {
  1634. char xx[1024];
  1635. Context;
  1636. unlink(dcc[idx].u.xfer->filename); //why the fuck was this not here, stupid eggdev team.
  1637. loading = 0;
  1638. putlog(LOG_MISC, "*", "%s", USERF_CANTREAD);
  1639. clear_userlist(u); /* Clear new, obsolete, user list. */
  1640. clear_chanlist(); /* Remove all user references from the
  1641. channel lists. */
  1642. for (i = 0; i < dcc_total; i++)
  1643. dcc[i].user = get_user_by_handle(ou, dcc[i].nick);
  1644. userlist = ou; /* Revert to old user list. */
  1645. lastuser = NULL; /* Reset last accessed user ptr. */
  1646. checkchans(2); /* un-flag the channels, we are keeping them.. */
  1647. dprintf(idx, "bye\n");
  1648. egg_snprintf(xx, sizeof xx, "Disconnected %s (can't read userfile)", dcc[idx].nick);
  1649. botnet_send_unlinked(idx, dcc[idx].nick, xx);
  1650. chatout("*** %s\n", xx);
  1651. killsock(dcc[idx].sock);
  1652. lostdcc(idx);
  1653. return;
  1654. }
  1655. unlink(dcc[idx].u.xfer->filename); //I mean really, shit fills up the quota fast.
  1656. loading = 0;
  1657. putlog(LOG_BOTS, "@", "%s.", USERF_XFERDONE);
  1658. clear_chanlist(); /* Remove all user references from the
  1659. channel lists. */
  1660. userlist = u; /* Set new user list. */
  1661. lastuser = NULL; /* Reset last accessed user ptr. */
  1662. /*
  1663. * Migrate:
  1664. * - old channel flags over (unshared channels see)
  1665. * - unshared (got_share == 0) user entries
  1666. * - old bot flags and passwords
  1667. */
  1668. fr.match = (FR_CHAN | FR_BOT);
  1669. for (u = userlist; u; u = u->next) {
  1670. struct userrec *u2 = get_user_by_handle(ou, u->handle);
  1671. if ((dcc[j].u.bot->uff_flags & UFF_OVERRIDE) &&
  1672. u2 && (u2->flags & USER_BOT)) {
  1673. /* We knew this bot before, copy flags and the password back over. */
  1674. set_user(&USERENTRY_BOTFL, u, get_user(&USERENTRY_BOTFL, u2));
  1675. set_user(&USERENTRY_PASS, u, get_user(&USERENTRY_PASS, u2));
  1676. } else if ((dcc[j].u.bot->uff_flags & UFF_OVERRIDE) &&
  1677. (u->flags & USER_BOT)) {
  1678. /* This bot was unknown to us, reset it's flags and password. */
  1679. set_user(&USERENTRY_BOTFL, u, NULL);
  1680. set_user(&USERENTRY_PASS, u, NULL);
  1681. } else if (u2 && !(u2->flags & (USER_BOT | USER_UNSHARED))) {
  1682. struct chanuserrec *cr, *cr_next, *cr_old = NULL;
  1683. struct user_entry *ue;
  1684. if (private_global) {
  1685. u->flags = u2->flags;
  1686. u->flags_udef = u2->flags_udef;
  1687. } else {
  1688. int pgbm = private_globals_bitmask();
  1689. u->flags = (u2->flags & pgbm) | (u->flags & ~pgbm);
  1690. }
  1691. noshare = 1;
  1692. for (cr = u2->chanrec; cr; cr = cr_next) {
  1693. struct chanset_t *chan = findchan_by_dname(cr->channel);
  1694. cr_next = cr->next;
  1695. if (chan) {
  1696. int not_shared = 0;
  1697. if (!channel_shared(chan))
  1698. not_shared = 1;
  1699. else {
  1700. get_user_flagrec(dcc[j].user, &fr, chan->dname);
  1701. if (!bot_chan(fr) && !bot_global(fr))
  1702. not_shared = 1;
  1703. }
  1704. if (not_shared) {
  1705. del_chanrec(u, cr->channel);
  1706. if (cr_old)
  1707. cr_old->next = cr_next;
  1708. else
  1709. u2->chanrec = cr_next;
  1710. cr->next = u->chanrec;
  1711. u->chanrec = cr;
  1712. } else {
  1713. /* Shared channel, still keep old laston time */
  1714. for (cr_old = u->chanrec; cr_old; cr_old = cr_old->next)
  1715. if (!rfc_casecmp(cr_old->channel, cr->channel)) {
  1716. cr_old->laston = cr->laston;
  1717. break;
  1718. }
  1719. cr_old = cr;
  1720. }
  1721. }
  1722. }
  1723. noshare = 0;
  1724. /* Any unshared user entries need copying over */
  1725. for (ue = u2->entries; ue; ue = ue->next)
  1726. if (ue->type && !ue->type->got_share && ue->type->dup_user)
  1727. ue->type->dup_user(u, u2, ue);
  1728. } else if (!u2 && private_global) {
  1729. u->flags = 0;
  1730. u->flags_udef = 0;
  1731. } else
  1732. u->flags = (u->flags & ~private_globals_bitmask());
  1733. }
  1734. clear_userlist(ou);
  1735. unlink(dcc[idx].u.xfer->filename); /* Done with you! */
  1736. checkchans(1); /* remove marked channels */
  1737. trigger_cfg_changed();
  1738. reaffirm_owners(); /* Make sure my owners are +a */
  1739. updatebot(-1, dcc[j].nick, '+', 0);
  1740. }
  1741. /* Begin the user transfer process.
  1742. */
  1743. static void start_sending_users(int idx)
  1744. {
  1745. struct userrec *u;
  1746. char share_file[1024], s1[64];
  1747. int i = 1;
  1748. struct chanuserrec *ch;
  1749. struct chanset_t *cst;
  1750. egg_snprintf(share_file, sizeof share_file, ".share.%s.%lu", dcc[idx].nick,
  1751. now);
  1752. if (dcc[idx].u.bot->uff_flags & UFF_OVERRIDE) {
  1753. debug1("NOTE: Sharing aggressively with %s, overriding its local bots.",
  1754. dcc[idx].nick);
  1755. u = dup_userlist(2); /* All entries */
  1756. } else
  1757. u = dup_userlist(0); /* Only non-bots */
  1758. write_tmp_userfile(share_file, u, idx);
  1759. clear_userlist(u);
  1760. if (!uff_call_sending(idx, share_file)) {
  1761. unlink(share_file);
  1762. dprintf(idx, "s e %s\n", "uff parsing failed");
  1763. putlog(LOG_BOTS, "@", "uff parsing failed");
  1764. dcc[idx].status &= ~(STAT_SHARE | STAT_SENDING | STAT_AGGRESSIVE);
  1765. return;
  1766. }
  1767. if ((i = raw_dcc_send(share_file, "*users", "(users)", share_file)) > 0) {
  1768. unlink(share_file);
  1769. dprintf(idx, "s e %s\n", USERF_CANTSEND);
  1770. putlog(LOG_BOTS, "@", "%s -- can't send userfile",
  1771. i == DCCSEND_FULL ? "NO MORE DCC CONNECTIONS" :
  1772. i == DCCSEND_NOSOCK ? "CAN'T OPEN A LISTENING SOCKET" :
  1773. i == DCCSEND_BADFN ? "BAD FILE" :
  1774. i == DCCSEND_FEMPTY ? "EMPTY FILE" : "UNKNOWN REASON!");
  1775. dcc[idx].status &= ~(STAT_SHARE | STAT_SENDING | STAT_AGGRESSIVE);
  1776. } else {
  1777. updatebot(-1, dcc[idx].nick, '+', 0);
  1778. dcc[idx].status |= STAT_SENDING;
  1779. i = dcc_total - 1;
  1780. strcpy(dcc[i].host, dcc[idx].nick); /* Store bot's nick */
  1781. dprintf(idx, "s us %lu %d %lu\n",
  1782. iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip()),
  1783. dcc[i].port, dcc[i].u.xfer->length);
  1784. /* Start up a tbuf to queue outgoing changes for this bot until the
  1785. * userlist is done transferring.
  1786. */
  1787. new_tbuf(dcc[idx].nick);
  1788. /* Immediately, queue bot hostmasks & addresses (jump-start) - if we
  1789. * don't override the leaf's local bots.
  1790. */
  1791. if (!(dcc[idx].u.bot->uff_flags & UFF_OVERRIDE)) {
  1792. for (u = userlist; u; u = u->next) {
  1793. if ((u->flags & USER_BOT) && !(u->flags & USER_UNSHARED)) {
  1794. struct bot_addr *bi = get_user(&USERENTRY_BOTADDR, u);
  1795. struct list_type *t;
  1796. char s2[1024];
  1797. /* Send hostmasks */
  1798. for (t = get_user(&USERENTRY_HOSTS, u); t; t = t->next) {
  1799. egg_snprintf(s2, sizeof s2, "s +bh %s %s\n", u->handle, t->extra);
  1800. q_tbuf(dcc[idx].nick, s2, NULL);
  1801. }
  1802. /* Send address */
  1803. if (bi)
  1804. egg_snprintf(s2, sizeof s2, "s c BOTADDR %s %s %d %d\n", u->handle,
  1805. bi->address, bi->telnet_port, bi->relay_port);
  1806. q_tbuf(dcc[idx].nick, s2, NULL);
  1807. fr.match = FR_GLOBAL;
  1808. fr.global = u->flags;
  1809. fr.udef_global = u->flags_udef;
  1810. build_flags(s1, &fr, NULL);
  1811. egg_snprintf(s2, sizeof s2, "s a %s %s\n", u->handle, s1);
  1812. q_tbuf(dcc[idx].nick, s2, NULL);
  1813. for (ch = u->chanrec; ch; ch = ch->next) {
  1814. if ((ch->flags & ~BOT_SHARE) &&
  1815. ((cst = findchan_by_dname(ch->channel)) &&
  1816. channel_shared(cst))) {
  1817. fr.match = (FR_CHAN | FR_BOT);
  1818. get_user_flagrec(dcc[idx].user, &fr, ch->channel);
  1819. if (bot_chan(fr) || bot_global(fr)) {
  1820. fr.match = FR_CHAN;
  1821. fr.chan = ch->flags & ~BOT_SHARE;
  1822. fr.udef_chan = ch->flags_udef;
  1823. build_flags(s1, &fr, NULL);
  1824. egg_snprintf(s2, sizeof s2, "s a %s %s %s\n", u->handle, s1,
  1825. ch->channel);
  1826. q_tbuf(dcc[idx].nick, s2, cst);
  1827. }
  1828. }
  1829. }
  1830. }
  1831. }
  1832. }
  1833. q_tbuf(dcc[idx].nick, "s !\n", NULL);
  1834. /* Unlink the file. We don't really care whether this causes problems
  1835. * for NFS setups. It's not worth the trouble.
  1836. */
  1837. unlink(share_file);
  1838. }
  1839. }
  1840. static void (*def_dcc_bot_kill) (int, void *) = 0;
  1841. static void cancel_user_xfer(int idx, void *x)
  1842. {
  1843. int i, j, k = 0;
  1844. if (idx < 0) {
  1845. idx = -idx;
  1846. k = 1;
  1847. updatebot(-1, dcc[idx].nick, '-', 0);
  1848. }
  1849. flush_tbuf(dcc[idx].nick);
  1850. if (dcc[idx].status & STAT_SHARE) {
  1851. if (dcc[idx].status & STAT_GETTING) {
  1852. j = 0;
  1853. for (i = 0; i < dcc_total; i++)
  1854. if (!egg_strcasecmp(dcc[i].host, dcc[idx].nick) &&
  1855. ((dcc[i].type->flags & (DCT_FILETRAN | DCT_FILESEND)) ==
  1856. (DCT_FILETRAN | DCT_FILESEND)))
  1857. j = i;
  1858. if (j != 0) {
  1859. killsock(dcc[j].sock);
  1860. unlink(dcc[j].u.xfer->filename);
  1861. lostdcc(j);
  1862. }
  1863. putlog(LOG_BOTS, "@", "(Userlist download aborted.)");
  1864. }
  1865. if (dcc[idx].status & STAT_SENDING) {
  1866. j = 0;
  1867. for (i = 0; i < dcc_total; i++)
  1868. if ((!egg_strcasecmp(dcc[i].host, dcc[idx].nick)) &&
  1869. ((dcc[i].type->flags & (DCT_FILETRAN | DCT_FILESEND))
  1870. == DCT_FILETRAN))
  1871. j = i;
  1872. if (j != 0) {
  1873. killsock(dcc[j].sock);
  1874. unlink(dcc[j].u.xfer->filename);
  1875. lostdcc(j);
  1876. }
  1877. putlog(LOG_BOTS, "@", "(Userlist transmit aborted.)");
  1878. }
  1879. if (allow_resync && (!(dcc[idx].status & STAT_GETTING)) &&
  1880. (!(dcc[idx].status & STAT_SENDING)))
  1881. new_tbuf(dcc[idx].nick);
  1882. }
  1883. if (!k)
  1884. def_dcc_bot_kill(idx, x);
  1885. }
  1886. static int share_expmem()
  1887. {
  1888. int tot = 0;
  1889. struct share_msgq *q;
  1890. tandbuf *t;
  1891. for (t = tbuf; t && t->bot[0]; t = t->next) {
  1892. tot += sizeof(tandbuf);
  1893. for (q = t->q; q; q = q->next) {
  1894. tot += sizeof(struct share_msgq);
  1895. tot += strlen(q->msg) + 1;
  1896. }
  1897. }
  1898. tot += uff_expmem();
  1899. tot += delay_expmem();
  1900. return tot;
  1901. }
  1902. static void share_report(int idx, int details)
  1903. {
  1904. int i, j;
  1905. if (details) {
  1906. dprintf(idx, " Share module, using %d bytes.\n", share_expmem());
  1907. dprintf(idx, " Private owners: %3s Allow resync: %3s\n",
  1908. (private_global || (private_globals_bitmask() & USER_OWNER)) ?
  1909. "yes" : "no", allow_resync ? "yes" : "no");
  1910. for (i = 0; i < dcc_total; i++)
  1911. if (dcc[i].type == &DCC_BOT) {
  1912. if (dcc[i].status & STAT_GETTING) {
  1913. int ok = 0;
  1914. for (j = 0; j < dcc_total; j++)
  1915. if (((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND))
  1916. == (DCT_FILETRAN | DCT_FILESEND)) &&
  1917. !egg_strcasecmp(dcc[j].host, dcc[i].nick)) {
  1918. dprintf(idx, "Downloading userlist from %s (%d%% done)\n",
  1919. dcc[i].nick,
  1920. (int) (100.0 * ((float) dcc[j].status) /
  1921. ((float) dcc[j].u.xfer->length)));
  1922. ok = 1;
  1923. break;
  1924. }
  1925. if (!ok)
  1926. dprintf(idx, "Download userlist from %s (negotiating "
  1927. "botentries)\n", dcc[i].nick);
  1928. } else if (dcc[i].status & STAT_SENDING) {
  1929. for (j = 0; j < dcc_total; j++) {
  1930. if (((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND))
  1931. == DCT_FILETRAN)
  1932. && !egg_strcasecmp(dcc[j].host, dcc[i].nick)) {
  1933. if (dcc[j].type == &DCC_GET)
  1934. dprintf(idx, "Sending userlist to %s (%d%% done)\n",
  1935. dcc[i].nick,
  1936. (int) (100.0 * ((float) dcc[j].status) /
  1937. ((float) dcc[j].u.xfer->length)));
  1938. else
  1939. dprintf(idx,
  1940. "Sending userlist to %s (waiting for connect)\n",
  1941. dcc[i].nick);
  1942. }
  1943. }
  1944. } else if (dcc[i].status & STAT_AGGRESSIVE) {
  1945. dprintf(idx, " Passively sharing with %s.\n", dcc[i].nick);
  1946. } else if (dcc[i].status & STAT_SHARE) {
  1947. dprintf(idx, " Aggressively sharing with %s.\n", dcc[i].nick);
  1948. }
  1949. }
  1950. status_tbufs(idx);
  1951. }
  1952. }
  1953. EXPORT_SCOPE char *share_start();
  1954. static Function share_table[] =
  1955. {
  1956. /* 0 - 3 */
  1957. (Function) share_start,
  1958. (Function) NULL,
  1959. (Function) share_expmem,
  1960. (Function) share_report,
  1961. /* 4 - 7 */
  1962. (Function) finish_share,
  1963. (Function) dump_resync,
  1964. (Function) uff_addtable,
  1965. (Function) uff_deltable
  1966. /* 8 - 11 */
  1967. };
  1968. char *share_start(Function *global_funcs)
  1969. {
  1970. global = global_funcs;
  1971. module_register(MODULE_NAME, share_table, 2, 3);
  1972. if (!(transfer_funcs = module_depend(MODULE_NAME, "transfer", 0, 0))) {
  1973. module_undepend(MODULE_NAME);
  1974. return "This module requires transfer module 2.0 or later.";
  1975. }
  1976. if (!(channels_funcs = module_depend(MODULE_NAME, "channels", 0, 0))) {
  1977. module_undepend(MODULE_NAME);
  1978. return "This module requires channels module 1.0 or later.";
  1979. }
  1980. #ifdef LEAF
  1981. if (!(irc_funcs = module_depend(MODULE_NAME, "irc", 0, 0))) {
  1982. module_undepend(MODULE_NAME);
  1983. return "This module requires channels module 1.0 or later.";
  1984. }
  1985. #endif /* LEAF */
  1986. add_hook(HOOK_SHAREOUT, (Function) shareout_mod);
  1987. add_hook(HOOK_SHAREIN, (Function) sharein_mod);
  1988. add_hook(HOOK_MINUTELY, (Function) check_expired_tbufs);
  1989. add_hook(HOOK_READ_USERFILE, (Function) hook_read_userfile);
  1990. add_hook(HOOK_SECONDLY, (Function) check_delay);
  1991. def_dcc_bot_kill = DCC_BOT.kill;
  1992. DCC_BOT.kill = cancel_user_xfer;
  1993. uff_init();
  1994. uff_addtable(internal_uff_table);
  1995. return NULL;
  1996. }
  1997. int private_globals_bitmask()
  1998. {
  1999. struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
  2000. break_down_flags(private_globals, &fr, 0);
  2001. return fr.global;
  2002. }