share.c 59 KB

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