chanprog.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. /*
  2. * chanprog.c -- handles:
  3. * rmspace()
  4. * maintaining the server list
  5. * revenge punishment
  6. * timers, utimers
  7. * telling the current programmed settings
  8. * initializing a lot of stuff and loading the tcl scripts
  9. *
  10. */
  11. #include "main.h"
  12. #if HAVE_GETRUSAGE
  13. #include <sys/resource.h>
  14. #if HAVE_SYS_RUSAGE_H
  15. #include <sys/rusage.h>
  16. #endif
  17. #endif
  18. #ifdef HAVE_UNAME
  19. #include <sys/utsname.h>
  20. #endif
  21. #include "modules.h"
  22. extern struct userrec *userlist;
  23. extern Tcl_Interp *interp;
  24. extern char ver[], botnetnick[], firewall[], myip[],
  25. motdfile[], userfile[], tempdir[],
  26. notify_new[], owner[],
  27. botuser[], *owners, *hubs;
  28. extern time_t now, online_since;
  29. extern int backgrd, term_z, con_chan, cache_hit, cache_miss,
  30. firewallport, default_flags, conmask,
  31. protect_readonly, noshare,
  32. #ifdef HUB
  33. my_port,
  34. #endif /* HUB */
  35. ignore_time, loading;
  36. tcl_timer_t *timer = NULL; /* Minutely timer */
  37. tcl_timer_t *utimer = NULL; /* Secondly timer */
  38. unsigned long timer_id = 1; /* Next timer of any sort will
  39. have this number */
  40. struct chanset_t *chanset = NULL; /* Channel list */
  41. char admin[121] = ""; /* Admin info */
  42. char origbotname[NICKLEN + 1];
  43. char botname[NICKLEN + 1]; /* Primary botname */
  44. /* Remove space characters from beginning and end of string
  45. * (more efficent by Fred1)
  46. */
  47. void rmspace(char *s)
  48. {
  49. #define whitespace(c) (((c) == 32) || ((c) == 9) || ((c) == 13) || ((c) == 10))
  50. char *p, *end;
  51. int len;
  52. if (!*s)
  53. return;
  54. /* Wipe end of string */
  55. end = s + strlen(s) - 1;
  56. for (p = end; ((whitespace(*p)) && (p >= s)); p--);
  57. if (p != end) *(p + 1) = 0;
  58. len = p+1 - s;
  59. for (p = s; ((whitespace(*p)) && (*p)); p++);
  60. len -= (p - s);
  61. if (p != s) {
  62. /* +1 to include the null in the copy */
  63. memmove(s, p, len + 1);
  64. }
  65. }
  66. /* Returns memberfields if the nick is in the member list.
  67. */
  68. memberlist *ismember(struct chanset_t *chan, char *nick)
  69. {
  70. register memberlist *x;
  71. for (x = chan->channel.member; x && x->nick[0]; x = x->next)
  72. if (!rfc_casecmp(x->nick, nick))
  73. return x;
  74. return NULL;
  75. }
  76. /* Find a chanset by channel name as the server knows it (ie !ABCDEchannel)
  77. */
  78. struct chanset_t *findchan(const char *name)
  79. {
  80. register struct chanset_t *chan;
  81. for (chan = chanset; chan; chan = chan->next)
  82. if (!rfc_casecmp(chan->name, name))
  83. return chan;
  84. return NULL;
  85. }
  86. /* Find a chanset by display name (ie !channel)
  87. */
  88. struct chanset_t *findchan_by_dname(const char *name)
  89. {
  90. register struct chanset_t *chan;
  91. for (chan = chanset; chan; chan = chan->next)
  92. if (!rfc_casecmp(chan->dname, name))
  93. return chan;
  94. return NULL;
  95. }
  96. /*
  97. * "caching" functions
  98. */
  99. /* Shortcut for get_user_by_host -- might have user record in one
  100. * of the channel caches.
  101. */
  102. struct userrec *check_chanlist(const char *host)
  103. {
  104. char *nick, *uhost, buf[UHOSTLEN];
  105. register memberlist *m;
  106. register struct chanset_t *chan;
  107. strncpyz(buf, host, sizeof buf);
  108. uhost = buf;
  109. nick = splitnick(&uhost);
  110. for (chan = chanset; chan; chan = chan->next)
  111. for (m = chan->channel.member; m && m->nick[0]; m = m->next)
  112. if (!rfc_casecmp(nick, m->nick) && !egg_strcasecmp(uhost, m->userhost))
  113. return m->user;
  114. return NULL;
  115. }
  116. /* Shortcut for get_user_by_handle -- might have user record in channels
  117. */
  118. struct userrec *check_chanlist_hand(const char *hand)
  119. {
  120. register struct chanset_t *chan;
  121. register memberlist *m;
  122. for (chan = chanset; chan; chan = chan->next)
  123. for (m = chan->channel.member; m && m->nick[0]; m = m->next)
  124. if (m->user && !egg_strcasecmp(m->user->handle, hand))
  125. return m->user;
  126. return NULL;
  127. }
  128. /* Clear the user pointers in the chanlists.
  129. *
  130. * Necessary when a hostmask is added/removed, a user is added or a new
  131. * userfile is loaded.
  132. */
  133. void clear_chanlist(void)
  134. {
  135. register memberlist *m;
  136. register struct chanset_t *chan;
  137. for (chan = chanset; chan; chan = chan->next)
  138. for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
  139. m->user = NULL;
  140. m->tried_getuser = 0;
  141. }
  142. }
  143. /* Clear the user pointer of a specific nick in the chanlists.
  144. *
  145. * Necessary when a hostmask is added/removed, a nick changes, etc.
  146. * Does not completely invalidate the channel cache like clear_chanlist().
  147. */
  148. void clear_chanlist_member(const char *nick)
  149. {
  150. register memberlist *m;
  151. register struct chanset_t *chan;
  152. for (chan = chanset; chan; chan = chan->next)
  153. for (m = chan->channel.member; m && m->nick[0]; m = m->next)
  154. if (!rfc_casecmp(m->nick, nick)) {
  155. m->user = NULL;
  156. m->tried_getuser = 0;
  157. break;
  158. }
  159. }
  160. /* If this user@host is in a channel, set it (it was null)
  161. */
  162. void set_chanlist(const char *host, struct userrec *rec)
  163. {
  164. char *nick, *uhost, buf[UHOSTLEN];
  165. register memberlist *m;
  166. register struct chanset_t *chan;
  167. strncpyz(buf, host, sizeof buf);
  168. uhost = buf;
  169. nick = splitnick(&uhost);
  170. for (chan = chanset; chan; chan = chan->next)
  171. for (m = chan->channel.member; m && m->nick[0]; m = m->next)
  172. if (!rfc_casecmp(nick, m->nick) && !egg_strcasecmp(uhost, m->userhost))
  173. m->user = rec;
  174. }
  175. /* Calculate the memory we should be using
  176. */
  177. int expmem_chanprog()
  178. {
  179. register int tot = 0;
  180. register tcl_timer_t *t;
  181. for (t = timer; t; t = t->next)
  182. tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
  183. for (t = utimer; t; t = t->next)
  184. tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
  185. return tot;
  186. }
  187. /* 0 marks all channels
  188. * 1 removes marked channels
  189. * 2 unmarks all channels
  190. */
  191. void checkchans(int which)
  192. {
  193. struct chanset_t *chan, *chan_next;
  194. sdprintf(STR("checkchans(%d)"), which);
  195. if (which == 0 || which == 2) {
  196. for (chan = chanset; chan; chan = chan->next) {
  197. if (which == 0) {
  198. chan->status |= CHAN_FLAGGED;
  199. } else if (which == 2) {
  200. chan->status &= ~CHAN_FLAGGED;
  201. }
  202. }
  203. } else if (which == 1) {
  204. module_entry *me;
  205. for (chan = chanset; chan; chan = chan_next) {
  206. chan_next = chan->next;
  207. if (chan->status & CHAN_FLAGGED) {
  208. putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname);
  209. /* remove_channel(chan); */
  210. if ((me = module_find("channels", 0, 0))) {
  211. Function *func = me->funcs;
  212. (func[CHANNEL_REMOVE]) (chan);
  213. }
  214. }
  215. }
  216. }
  217. }
  218. /* Dump uptime info out to dcc (guppy 9Jan99)
  219. */
  220. void tell_verbose_uptime(int idx)
  221. {
  222. char s[256], s1[121];
  223. time_t now2, hr, min;
  224. now2 = now - online_since;
  225. s[0] = 0;
  226. if (now2 > 86400) {
  227. /* days */
  228. sprintf(s, "%d day", (int) (now2 / 86400));
  229. if ((int) (now2 / 86400) >= 2)
  230. strcat(s, "s");
  231. strcat(s, ", ");
  232. now2 -= (((int) (now2 / 86400)) * 86400);
  233. }
  234. hr = (time_t) ((int) now2 / 3600);
  235. now2 -= (hr * 3600);
  236. min = (time_t) ((int) now2 / 60);
  237. sprintf(&s[strlen(s)], "%02d:%02d", (int) hr, (int) min);
  238. s1[0] = 0;
  239. if (backgrd)
  240. strcpy(s1, MISC_BACKGROUND);
  241. else {
  242. if (term_z)
  243. strcpy(s1, MISC_TERMMODE);
  244. else if (con_chan)
  245. strcpy(s1, MISC_STATMODE);
  246. else
  247. strcpy(s1, MISC_LOGMODE);
  248. }
  249. dprintf(idx, "%s %s (%s)\n", MISC_ONLINEFOR, s, s1);
  250. }
  251. /* Dump status info out to dcc
  252. */
  253. void tell_verbose_status(int idx)
  254. {
  255. char s[256], s1[121], s2[81];
  256. char *vers_t, *uni_t;
  257. #ifdef HUB
  258. int i;
  259. #endif /* HUB */
  260. time_t now2, hr, min;
  261. #if HAVE_GETRUSAGE
  262. struct rusage ru;
  263. #else
  264. # if HAVE_CLOCK
  265. clock_t cl;
  266. # endif
  267. #endif /* HAVE_GETRUSAGE */
  268. #ifdef HAVE_UNAME
  269. struct utsname un;
  270. if (!uname(&un) < 0) {
  271. #endif /* HAVE_UNAME */
  272. vers_t = " ";
  273. uni_t = "*unknown*";
  274. #ifdef HAVE_UNAME
  275. } else {
  276. vers_t = un.release;
  277. uni_t = un.sysname;
  278. }
  279. #endif /* HAVE_UNAME */
  280. #ifdef HUB
  281. i = count_users(userlist);
  282. dprintf(idx, "I am %s, running %s: %d user%s (mem: %uk)\n",
  283. botnetnick, ver, i, i == 1 ? "" : "s",
  284. (int) (expected_memory() / 1024));
  285. if (isupdatehub())
  286. dprintf(idx, "I am an update hub.\n");
  287. #endif /* HUB */
  288. now2 = now - online_since;
  289. s[0] = 0;
  290. if (now2 > 86400) {
  291. /* days */
  292. sprintf(s, "%d day", (int) (now2 / 86400));
  293. if ((int) (now2 / 86400) >= 2)
  294. strcat(s, "s");
  295. strcat(s, ", ");
  296. now2 -= (((int) (now2 / 86400)) * 86400);
  297. }
  298. hr = (time_t) ((int) now2 / 3600);
  299. now2 -= (hr * 3600);
  300. min = (time_t) ((int) now2 / 60);
  301. sprintf(&s[strlen(s)], "%02d:%02d", (int) hr, (int) min);
  302. s1[0] = 0;
  303. if (backgrd)
  304. strcpy(s1, MISC_BACKGROUND);
  305. else {
  306. if (term_z)
  307. strcpy(s1, MISC_TERMMODE);
  308. else if (con_chan)
  309. strcpy(s1, MISC_STATMODE);
  310. else
  311. strcpy(s1, MISC_LOGMODE);
  312. }
  313. #if HAVE_GETRUSAGE
  314. getrusage(RUSAGE_SELF, &ru);
  315. hr = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) / 60);
  316. min = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) - (hr * 60));
  317. sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min); /* Actally min/sec */
  318. #else
  319. # if HAVE_CLOCK
  320. cl = (clock() / CLOCKS_PER_SEC);
  321. hr = (int) (cl / 60);
  322. min = (int) (cl - (hr * 60));
  323. sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min); /* Actually min/sec */
  324. # else
  325. sprintf(s2, "CPU ???");
  326. # endif
  327. #endif /* HAVE_GETRUSAGE */
  328. dprintf(idx, "%s %s (%s) %s %s %4.1f%%\n", MISC_ONLINEFOR,
  329. s, s1, s2, MISC_CACHEHIT,
  330. 100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));
  331. if (admin[0])
  332. dprintf(idx, "Admin: %s\n", admin);
  333. dprintf(idx, "OS: %s %s\n", uni_t, vers_t);
  334. /* info library */
  335. dprintf(idx, "%s %s\n", MISC_TCLLIBRARY,
  336. ((interp) && (Tcl_Eval(interp, "info library") == TCL_OK)) ?
  337. interp->result : "*unknown*");
  338. /* info tclversion/patchlevel */
  339. dprintf(idx, "%s %s (%s %s)\n", MISC_TCLVERSION,
  340. ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ?
  341. interp->result : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ?
  342. interp->result : "*unknown*", MISC_TCLHVERSION,
  343. TCL_PATCH_LEVEL ? TCL_PATCH_LEVEL : "*unknown*");
  344. #if HAVE_TCL_THREADS
  345. dprintf(idx, "Tcl is threaded\n");
  346. #endif /* HAVE_TCL_THREADS */
  347. }
  348. /* Show all internal state variables
  349. */
  350. void tell_settings(int idx)
  351. {
  352. char s[1024];
  353. struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
  354. dprintf(idx, "Botnet Nickname: %s\n", botnetnick);
  355. if (firewall[0])
  356. dprintf(idx, "Firewall: %s, port %d\n", firewall, firewallport);
  357. #ifdef HUB
  358. dprintf(idx, "Userfile: %s \n", userfile);
  359. #endif /* HUB */
  360. dprintf(idx, "Directories:\n");
  361. dprintf(idx, " Temp : %s\n", tempdir);
  362. fr.global = default_flags;
  363. build_flags(s, &fr, NULL);
  364. dprintf(idx, "%s [%s], %s: %s\n", MISC_NEWUSERFLAGS, s, MISC_NOTIFY, notify_new);
  365. #ifdef HUB
  366. if (owner[0])
  367. dprintf(idx, "%s: %s\n", MISC_PERMOWNER, owner);
  368. #endif /* HUB */
  369. dprintf(idx, "Ignores last %d mins\n", ignore_time);
  370. }
  371. void reaffirm_owners()
  372. {
  373. char *p, *q, s[121];
  374. struct userrec *u;
  375. /* Make sure default owners are +a */
  376. if (owner[0]) {
  377. q = owner;
  378. p = strchr(q, ',');
  379. while (p) {
  380. strncpyz(s, q, (p - q) + 1);
  381. rmspace(s);
  382. u = get_user_by_handle(userlist, s);
  383. if (u)
  384. u->flags = sanity_check(u->flags | USER_ADMIN);
  385. q = p + 1;
  386. p = strchr(q, ',');
  387. }
  388. strcpy(s, q);
  389. rmspace(s);
  390. u = get_user_by_handle(userlist, s);
  391. if (u)
  392. u->flags = sanity_check(u->flags | USER_ADMIN);
  393. }
  394. }
  395. void load_internal_users()
  396. {
  397. char *p = NULL,
  398. *ln,
  399. *hand,
  400. *ip,
  401. *port,
  402. *pass,
  403. *hosts,
  404. host[250],
  405. buf[2048];
  406. char *attr;
  407. int i, hublevel = 0;
  408. struct bot_addr *bi;
  409. struct userrec *u;
  410. //struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
  411. /* hubs */
  412. sprintf(buf, "%s", hubs);
  413. p = buf;
  414. while (p) {
  415. ln = p;
  416. p = strchr(p, ',');
  417. if (p)
  418. *p++ = 0;
  419. hand = ln;
  420. ip = NULL;
  421. port = NULL;
  422. hosts = NULL;
  423. for (i = 0; ln; i++) {
  424. switch (i) {
  425. case 0:
  426. hand = ln;
  427. break;
  428. case 1:
  429. ip = ln;
  430. break;
  431. case 2:
  432. port = ln;
  433. break;
  434. case 3:
  435. hublevel++; /* We must increment this even if it is already added */
  436. if (!get_user_by_handle(userlist, hand)) {
  437. userlist = adduser(userlist, hand, "none", "-", USER_BOT | USER_OP);
  438. bi = user_malloc(sizeof(struct bot_addr));
  439. bi->address = user_malloc(strlen(ip) + 1);
  440. strcpy(bi->address, ip);
  441. bi->telnet_port = atoi(port) ? atoi(port) : 0;
  442. bi->relay_port = bi->telnet_port;
  443. bi->hublevel = hublevel;
  444. #ifdef HUB
  445. if ((!bi->hublevel) && (!strcmp(hand, botnetnick)))
  446. bi->hublevel = 99;
  447. #endif /* HUB */
  448. bi->uplink = user_malloc(1);
  449. bi->uplink[0] = 0;
  450. set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, hand), bi);
  451. /* set_user(&USERENTRY_PASS, get_user_by_handle(userlist, hand), SALT2); */
  452. }
  453. default:
  454. // ln = userids for hostlist, add them all
  455. hosts = ln;
  456. ln = strchr(ln, ' ');
  457. if (ln)
  458. *ln++ = 0;
  459. while (hosts) {
  460. sprintf(host, "*!%s@%s", hosts, ip);
  461. set_user(&USERENTRY_HOSTS, get_user_by_handle(userlist, hand), host);
  462. hosts = ln;
  463. if (ln)
  464. ln = strchr(ln, ' ');
  465. if (ln)
  466. *ln++ = 0;
  467. }
  468. break;
  469. }
  470. if (ln)
  471. ln = strchr(ln, ' ');
  472. if (ln) {
  473. *ln++ = 0;
  474. }
  475. }
  476. }
  477. /* perm owners */
  478. owner[0] = 0;
  479. sprintf(buf, "%s", owners);
  480. p = buf;
  481. while (p) {
  482. ln = p;
  483. p = strchr(p, ',');
  484. if (p)
  485. *p++ = 0;
  486. hand = ln;
  487. pass = NULL;
  488. attr = NULL;
  489. hosts = NULL;
  490. for (i = 0; ln; i++) {
  491. switch (i) {
  492. case 0:
  493. hand = ln;
  494. break;
  495. case 1:
  496. pass = ln;
  497. break;
  498. case 2:
  499. hosts = ln;
  500. if (owner[0])
  501. strncat(owner, ",", 120);
  502. strncat(owner, hand, 120);
  503. if (!get_user_by_handle(userlist, hand)) {
  504. userlist = adduser(userlist, hand, "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_OP | USER_PARTY | USER_HUBA | USER_CHUBA);
  505. u = get_user_by_handle(userlist, hand);
  506. set_user(&USERENTRY_PASS, u, pass);
  507. while (hosts) {
  508. ln = strchr(ln, ' ');
  509. if (ln)
  510. *ln++ = 0;
  511. set_user(&USERENTRY_HOSTS, u, hosts);
  512. hosts = ln;
  513. }
  514. }
  515. break;
  516. }
  517. if (ln)
  518. ln = strchr(ln, ' ');
  519. if (ln)
  520. *ln++ = 0;
  521. }
  522. }
  523. }
  524. void chanprog()
  525. {
  526. char buf[2048];
  527. struct bot_addr *bi;
  528. struct userrec *u;
  529. admin[0] = 0;
  530. /* cache our ip on load instead of every 30 seconds -zip */
  531. cache_my_ip();
  532. sdprintf("ip4: %s", myipstr(4));
  533. sdprintf("ip6: %s", myipstr(6));
  534. conmask = 0;
  535. /* Turn off read-only variables (make them write-able) for rehash */
  536. protect_readonly = 0;
  537. /* now this only checks server shit. (no channels) */
  538. call_hook(HOOK_REHASH);
  539. protect_readonly = 1;
  540. if (!botnetnick[0]) {
  541. strncpyz(botnetnick, origbotname, HANDLEN + 1);
  542. }
  543. strcpy(botuser, origbotname);
  544. if (!botnetnick[0])
  545. fatal("I don't have a botnet nick!!\n", 0);
  546. #ifdef HUB
  547. loading = 1;
  548. checkchans(0);
  549. readuserfile(userfile, &userlist);
  550. checkchans(1);
  551. loading = 0;
  552. #endif /* HUB */
  553. load_internal_users();
  554. if (!(u = get_user_by_handle(userlist, botnetnick))) {
  555. /* I need to be on the userlist... doh. */
  556. userlist = adduser(userlist, botnetnick, STR("none"), "-", USER_BOT | USER_OP );
  557. u = get_user_by_handle(userlist, botnetnick);
  558. bi = user_malloc(sizeof(struct bot_addr));
  559. bi->address = user_malloc(strlen(myip) + 1);
  560. strcpy(bi->address, myip);
  561. bi->telnet_port = atoi(buf) ? atoi(buf) : 3333;
  562. bi->relay_port = bi->telnet_port;
  563. #ifdef HUB
  564. bi->hublevel = 99;
  565. #else
  566. bi->hublevel = 0;
  567. #endif /* HUB */
  568. bi->uplink = user_malloc(1);
  569. bi->uplink[0] = 0;
  570. set_user(&USERENTRY_BOTADDR, u, bi);
  571. } else {
  572. bi = get_user(&USERENTRY_BOTADDR, u);
  573. }
  574. bi = get_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, botnetnick));
  575. if (!bi)
  576. fatal(STR("I'm added to userlist but without a bot record!"), 0);
  577. if (bi->telnet_port != 3333) {
  578. #ifdef HUB
  579. listen_all(bi->telnet_port, 0);
  580. my_port = bi->telnet_port;
  581. #endif /* HUB */
  582. }
  583. trigger_cfg_changed();
  584. /* We should be safe now */
  585. if (tempdir[0])
  586. if (tempdir[strlen(tempdir) - 1] != '/')
  587. strcat(tempdir, "/");
  588. /* test tempdir: it's vital */
  589. {
  590. FILE *f = NULL;
  591. char s[161];
  592. int fd;
  593. sprintf(s, STR("%s.test-XXXXXX"), tempdir);
  594. if ((fd = mkstemp(s)) == -1 || (f = fdopen(fd, "w")) == NULL) {
  595. if (fd != -1) {
  596. unlink(s);
  597. close(fd);
  598. }
  599. fatal(STR("Can't write to tempdir!"), 0);
  600. }
  601. unlink(s);
  602. fclose(f);
  603. }
  604. reaffirm_owners();
  605. }
  606. #ifdef HUB
  607. /* Reload the user file from disk
  608. */
  609. void reload()
  610. {
  611. FILE *f;
  612. f = fopen(userfile, "r");
  613. if (f == NULL) {
  614. putlog(LOG_MISC, "*", MISC_CANTRELOADUSER);
  615. return;
  616. }
  617. fclose(f);
  618. noshare = 1;
  619. clear_userlist(userlist);
  620. noshare = 0;
  621. userlist = NULL;
  622. loading = 1;
  623. checkchans(0);
  624. if (!readuserfile(userfile, &userlist))
  625. fatal(MISC_MISSINGUSERF, 0);
  626. checkchans(1);
  627. loading = 0;
  628. reaffirm_owners();
  629. call_hook(HOOK_READ_USERFILE);
  630. }
  631. #endif /* HUB */
  632. void rehash()
  633. {
  634. call_hook(HOOK_PRE_REHASH);
  635. noshare = 1;
  636. clear_userlist(userlist);
  637. noshare = 0;
  638. userlist = NULL;
  639. chanprog();
  640. }
  641. /*
  642. * Brief venture into timers
  643. */
  644. /* Add a timer
  645. */
  646. unsigned long add_timer(tcl_timer_t **stack, int elapse, char *cmd,
  647. unsigned long prev_id)
  648. {
  649. tcl_timer_t *old = (*stack);
  650. *stack = (tcl_timer_t *) nmalloc(sizeof(tcl_timer_t));
  651. (*stack)->next = old;
  652. (*stack)->mins = elapse;
  653. (*stack)->cmd = (char *) nmalloc(strlen(cmd) + 1);
  654. strcpy((*stack)->cmd, cmd);
  655. /* If it's just being added back and already had an id,
  656. * don't create a new one.
  657. */
  658. if (prev_id > 0)
  659. (*stack)->id = prev_id;
  660. else
  661. (*stack)->id = timer_id++;
  662. return (*stack)->id;
  663. }
  664. /* Remove a timer, by id
  665. */
  666. int remove_timer(tcl_timer_t **stack, unsigned long id)
  667. {
  668. tcl_timer_t *old;
  669. int ok = 0;
  670. while (*stack) {
  671. if ((*stack)->id == id) {
  672. ok++;
  673. old = *stack;
  674. *stack = ((*stack)->next);
  675. nfree(old->cmd);
  676. nfree(old);
  677. } else
  678. stack = &((*stack)->next);
  679. }
  680. return ok;
  681. }
  682. /* Check timers, execute the ones that have expired.
  683. */
  684. void do_check_timers(tcl_timer_t **stack)
  685. {
  686. tcl_timer_t *mark = *stack, *old = NULL;
  687. char x[16];
  688. /* New timers could be added by a Tcl script inside a current timer
  689. * so i'll just clear out the timer list completely, and add any
  690. * unexpired timers back on.
  691. */
  692. *stack = NULL;
  693. while (mark) {
  694. if (mark->mins > 0)
  695. mark->mins--;
  696. old = mark;
  697. mark = mark->next;
  698. if (!old->mins) {
  699. egg_snprintf(x, sizeof x, "timer%lu", old->id);
  700. do_tcl(x, old->cmd);
  701. nfree(old->cmd);
  702. nfree(old);
  703. } else {
  704. old->next = *stack;
  705. *stack = old;
  706. }
  707. }
  708. }
  709. /* Wipe all timers.
  710. */
  711. void wipe_timers(Tcl_Interp *irp, tcl_timer_t **stack)
  712. {
  713. tcl_timer_t *mark = *stack, *old;
  714. while (mark) {
  715. old = mark;
  716. mark = mark->next;
  717. nfree(old->cmd);
  718. nfree(old);
  719. }
  720. *stack = NULL;
  721. }
  722. /* Return list of timers
  723. */
  724. void list_timers(Tcl_Interp *irp, tcl_timer_t *stack)
  725. {
  726. tcl_timer_t *mark;
  727. char mins[10], id[16], *x;
  728. #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
  729. CONST char *argv[3];
  730. #else
  731. char *argv[3];
  732. #endif
  733. for (mark = stack; mark; mark = mark->next) {
  734. egg_snprintf(mins, sizeof mins, "%u", mark->mins);
  735. egg_snprintf(id, sizeof id, "timer%lu", mark->id);
  736. argv[0] = mins;
  737. argv[1] = mark->cmd;
  738. argv[2] = id;
  739. x = Tcl_Merge(3, argv);
  740. Tcl_AppendElement(irp, x);
  741. Tcl_Free((char *) x);
  742. }
  743. }
  744. /* Oddly enough, written by proton (Emech's coder)
  745. */
  746. int isowner(char *name)
  747. {
  748. char *pa, *pb;
  749. char nl, pl;
  750. if (!owner || !*owner)
  751. return (0);
  752. if (!name || !*name)
  753. return (0);
  754. nl = strlen(name);
  755. pa = owner;
  756. pb = owner;
  757. while (1) {
  758. while (1) {
  759. if ((*pb == 0) || (*pb == ',') || (*pb == ' '))
  760. break;
  761. pb++;
  762. }
  763. pl = (unsigned int) pb - (unsigned int) pa;
  764. if (pl == nl && !egg_strncasecmp(pa, name, nl))
  765. return (1);
  766. while (1) {
  767. if ((*pb == 0) || ((*pb != ',') && (*pb != ' ')))
  768. break;
  769. pb++;
  770. }
  771. if (*pb == 0)
  772. return (0);
  773. pa = pb;
  774. }
  775. }
  776. int shouldjoin(struct chanset_t *chan)
  777. {
  778. /* if (!strcmp(chan->dname, "#wtest2"))
  779. return 1;
  780. else
  781. return 0; */
  782. #ifdef G_BACKUP
  783. struct flag_record fr = { FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0, 0, 0 };
  784. get_user_flagrec(get_user_by_handle(userlist, botnetnick), &fr, chan->name);
  785. return (!channel_inactive(chan)
  786. && (channel_backup(chan) || !glob_backupbot(fr)));
  787. #else /* !G_BACKUP */
  788. return !channel_inactive(chan);
  789. #endif /* G_BACKUP */
  790. }
  791. /* do_chanset() set (options) on (chan)
  792. * local: 0 - send out over botnet only
  793. * local: 1 - ALSO set locally
  794. * local: 2 - ONLY set locally
  795. */
  796. void do_chanset(struct chanset_t *chan, char *options, int local)
  797. {
  798. char *buf;
  799. module_entry *me;
  800. Context;
  801. /* send out over botnet. */
  802. if (local != 2) {
  803. /* nmalloc(options,chan,'cset ',' ',+ 1) */
  804. if (chan)
  805. buf = nmalloc(strlen(options) + strlen(chan->dname) + 5 + 1 + 1);
  806. else
  807. buf = nmalloc(strlen(options) + 1 + 5 + 1 + 1);
  808. buf[0] = 0;
  809. strcat(buf, "cset ");
  810. if (chan)
  811. strcat(buf, chan->dname);
  812. else
  813. strcat(buf, "*");
  814. strcat(buf, " ");
  815. strcat(buf, options);
  816. buf[strlen(buf)] = 0;
  817. putlog(LOG_DEBUG, "*", "sending out cset: %s", buf);
  818. putallbots(buf);
  819. nfree(buf);
  820. }
  821. /* now set locally, hopefully it works */
  822. if (local && (me = module_find("channels", 0, 0))) {
  823. /* tcl_channel_modify(0, chan, 1, options) */
  824. Function *func = me->funcs;
  825. char *buf2, *bak;
  826. struct chanset_t *ch;
  827. int all = 0;
  828. if (!chan) {
  829. ch = chanset;
  830. all++;
  831. } else
  832. ch = chan;
  833. bak = options;
  834. buf2 = nmalloc(strlen(options) + 1);
  835. while (ch) {
  836. char *list[2];
  837. strcpy(buf2, bak);
  838. options = buf2;
  839. list[0] = newsplit(&options);
  840. while (list[0][0]) {
  841. if (list[0][0] == '+' || list[0][0] == '-' || (!strcmp(list[0], "dont-idle-kick"))) {
  842. (func[38]) (0, ch, 1, list); /* tcl_channel_modify() */
  843. list[0] = newsplit(&options);
  844. continue;
  845. }
  846. /* chanints */
  847. list[1] = options;
  848. (func[38]) (0, ch, 2, list); /* tcl_channel_modify() */
  849. break;
  850. }
  851. if (all)
  852. ch = ch->next;
  853. else
  854. ch = NULL;
  855. }
  856. nfree(buf2);
  857. }
  858. }