botcmd.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. #include "main.h"
  2. #include "tandem.h"
  3. #include "users.h"
  4. #include "chan.h"
  5. #include "modules.h"
  6. extern char botnetnick[], ver[], admin[], network[], motdfile[];
  7. extern int dcc_total, remote_boots, noshare, timesync;
  8. extern struct dcc_t *dcc;
  9. extern struct chanset_t *chanset;
  10. extern struct userrec *userlist;
  11. extern Tcl_Interp *interp;
  12. extern time_t now, online_since;
  13. extern party_t *party;
  14. extern module_entry *module_list;
  15. static char TBUF[1024];
  16. static char base64to[256] =
  17. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  18. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59,
  19. 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  20. 20, 21, 22, 23, 24, 25, 62, 0, 63, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  21. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  22. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  23. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  24. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  25. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  26. int
  27. base64_to_int (char *buf)
  28. {
  29. int i = 0;
  30. while (*buf)
  31. {
  32. i = i << 6;
  33. i += base64to[(int) *buf];
  34. buf++;
  35. } return i;
  36. }
  37. static int fakesock = 2300;
  38. static void
  39. fake_alert (int idx, char *item, char *extra)
  40. {
  41. static unsigned long lastfake;
  42. if (now - lastfake > 10)
  43. {
  44. dprintf (idx, "ct %s NOTICE: %s (%s != %s).\n", botnetnick,
  45. NET_FAKEREJECT, item, extra);
  46. putlog (LOG_BOTS, "*", "%s %s (%s != %s).", dcc[idx].nick,
  47. NET_FAKEREJECT, item, extra);
  48. lastfake = now;
  49. }
  50. }
  51. static void
  52. bot_chan2 (int idx, char *msg)
  53. {
  54. char *from, *p;
  55. int i, chan;
  56. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  57. return;
  58. from = newsplit (&msg);
  59. p = newsplit (&msg);
  60. chan = base64_to_int (p);
  61. for (p = from; *p;)
  62. {
  63. if ((*p < 32) || (*p == 127))
  64. strcpy (p, p + 1);
  65. else
  66. p++;
  67. }
  68. p = strchr (from, '@');
  69. if (p)
  70. {
  71. sprintf (TBUF, "<%s> %s", from, msg);
  72. *p = 0;
  73. if (!partyidle (p + 1, from))
  74. {
  75. *p = '@';
  76. fake_alert (idx, "user", from);
  77. return;
  78. }
  79. *p = '@';
  80. p++;
  81. }
  82. else
  83. {
  84. sprintf (TBUF, "*** (%s) %s", from, msg);
  85. p = from;
  86. }
  87. i = nextbot (p);
  88. if (i != idx)
  89. {
  90. fake_alert (idx, "direction", p);
  91. }
  92. else
  93. {
  94. chanout_but (-1, chan, "%s\n", TBUF);
  95. if (i >= 0)
  96. botnet_send_chan (idx, from, NULL, chan, msg);
  97. if (strchr (from, '@') != NULL)
  98. check_tcl_chat (from, chan, msg);
  99. else
  100. check_tcl_bcst (from, chan, msg);
  101. }
  102. }
  103. #ifdef S_DCCPASS
  104. void
  105. bot_cmdpass (int idx, char *par)
  106. {
  107. char *p;
  108. p = strchr (par, ' ');
  109. if (p)
  110. {
  111. *p++ = 0;
  112. botnet_send_cmdpass (idx, par, p);
  113. p--;
  114. *p = ' ';
  115. }
  116. else
  117. {
  118. botnet_send_cmdpass (idx, par, "");
  119. }
  120. set_cmd_pass (par, 0);
  121. }
  122. #endif
  123. void
  124. bot_config (int idx, char *par)
  125. {
  126. got_config_share (idx, par);
  127. } void
  128. bot_remotecmd (int idx, char *par)
  129. {
  130. char *tbot, *fbot, *fhnd, *fidx;
  131. tbot = newsplit (&par);
  132. fbot = newsplit (&par);
  133. fhnd = newsplit (&par);
  134. fidx = newsplit (&par);
  135. if (!strcmp (tbot, botnetnick))
  136. {
  137. gotremotecmd (tbot, fbot, fhnd, fidx, par);
  138. }
  139. else if (!strcmp (tbot, "*"))
  140. {
  141. botnet_send_cmd_broad (idx, fbot, fhnd, atoi (fidx), par);
  142. gotremotecmd (tbot, fbot, fhnd, fidx, par);
  143. }
  144. else
  145. {
  146. if (nextbot (tbot) != idx)
  147. botnet_send_cmd (fbot, tbot, fhnd, atoi (fidx), par);
  148. }
  149. }
  150. void
  151. bot_remotereply (int idx, char *par)
  152. {
  153. char *tbot, *fbot, *fhnd, *fidx;
  154. tbot = newsplit (&par);
  155. fbot = newsplit (&par);
  156. fhnd = newsplit (&par);
  157. fidx = newsplit (&par);
  158. if (!strcmp (tbot, botnetnick))
  159. {
  160. gotremotereply (fbot, fhnd, fidx, par);
  161. }
  162. else
  163. {
  164. if (nextbot (tbot) != idx)
  165. botnet_send_cmdreply (fbot, tbot, fhnd, fidx, par);
  166. }
  167. }
  168. static void
  169. bot_chat (int idx, char *par)
  170. {
  171. char *from;
  172. int i;
  173. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  174. return;
  175. from = newsplit (&par);
  176. if (strchr (from, '@') != NULL)
  177. {
  178. fake_alert (idx, "bot", from);
  179. return;
  180. }
  181. i = nextbot (from);
  182. if (i != idx)
  183. {
  184. fake_alert (idx, "direction", from);
  185. return;
  186. }
  187. chatout ("*** (%s) %s\n", from, par);
  188. botnet_send_chat (idx, from, par);
  189. }
  190. static void
  191. bot_actchan (int idx, char *par)
  192. {
  193. char *from, *p;
  194. int i, chan;
  195. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  196. return;
  197. from = newsplit (&par);
  198. p = strchr (from, '@');
  199. if (p == NULL)
  200. {
  201. fake_alert (idx, "user@bot", from);
  202. return;
  203. }
  204. *p = 0;
  205. if (!partyidle (p + 1, from))
  206. {
  207. *p = '@';
  208. fake_alert (idx, "user", from);
  209. return;
  210. }
  211. *p = '@';
  212. p++;
  213. i = nextbot (p);
  214. if (i != idx)
  215. {
  216. fake_alert (idx, "direction", p);
  217. return;
  218. }
  219. p = newsplit (&par);
  220. chan = base64_to_int (p);
  221. for (p = from; *p;)
  222. {
  223. if ((*p < 32) || (*p == 127))
  224. strcpy (p, p + 1);
  225. else
  226. p++;
  227. }
  228. chanout_but (-1, chan, "* %s %s\n", from, par);
  229. botnet_send_act (idx, from, NULL, chan, par);
  230. check_tcl_act (from, chan, par);
  231. }
  232. static void
  233. bot_priv (int idx, char *par)
  234. {
  235. char *from, *p, *to = TBUF, *tobot;
  236. int i;
  237. from = newsplit (&par);
  238. tobot = newsplit (&par);
  239. splitc (to, tobot, '@');
  240. p = strchr (from, '@');
  241. if (p != NULL)
  242. p++;
  243. else
  244. p = from;
  245. i = nextbot (p);
  246. if (i != idx)
  247. {
  248. fake_alert (idx, "direction", p);
  249. return;
  250. }
  251. if (!to[0])
  252. return;
  253. if (!egg_strcasecmp (tobot, botnetnick))
  254. {
  255. if (p == from)
  256. add_note (to, from, par, -2, 0);
  257. else
  258. {
  259. i = add_note (to, from, par, -1, 0);
  260. if (from[0] != '@')
  261. switch (i)
  262. {
  263. case NOTE_ERROR:
  264. botnet_send_priv (idx, botnetnick, from, NULL, "%s %s.",
  265. BOT_NOSUCHUSER, to);
  266. break;
  267. case NOTE_STORED:
  268. botnet_send_priv (idx, botnetnick, from, NULL, "%s",
  269. BOT_NOTESTORED2);
  270. break;
  271. case NOTE_FULL:
  272. botnet_send_priv (idx, botnetnick, from, NULL, "%s",
  273. BOT_NOTEBOXFULL);
  274. break;
  275. case NOTE_AWAY:
  276. botnet_send_priv (idx, botnetnick, from, NULL, "%s %s", to,
  277. BOT_NOTEISAWAY);
  278. break;
  279. case NOTE_FWD:
  280. botnet_send_priv (idx, botnetnick, from, NULL, "%s %s",
  281. "Not online; note forwarded to:", to);
  282. break;
  283. case NOTE_REJECT:
  284. botnet_send_priv (idx, botnetnick, from, NULL, "%s %s", to,
  285. "rejected your note.");
  286. break;
  287. case NOTE_TCL:
  288. break;
  289. case NOTE_OK:
  290. botnet_send_priv (idx, botnetnick, from, NULL, "%s %s.",
  291. BOT_NOTESENTTO, to);
  292. break;
  293. }
  294. }
  295. }
  296. else
  297. {
  298. i = nextbot (tobot);
  299. if (i >= 0)
  300. botnet_send_priv (i, from, to, tobot, "%s", par);
  301. }
  302. }
  303. static void
  304. bot_bye (int idx, char *par)
  305. {
  306. char s[1024];
  307. int users, bots;
  308. bots = bots_in_subtree (findbot (dcc[idx].nick));
  309. users = users_in_subtree (findbot (dcc[idx].nick));
  310. simple_sprintf (s, "%s %s. %s (lost %d bot%s and %d user%s)",
  311. BOT_DISCONNECTED, dcc[idx].nick, par[0] ? par : "No reason",
  312. bots, (bots != 1) ? "s" : "", users,
  313. (users != 1) ? "s" : "");
  314. putlog (LOG_BOTS, "*", "%s", s);
  315. chatout ("*** %s\n", s);
  316. botnet_send_unlinked (idx, dcc[idx].nick, s);
  317. dprintf (idx, "*bye\n");
  318. killsock (dcc[idx].sock);
  319. lostdcc (idx);
  320. } static void
  321. remote_tell_who (int idx, char *nick, int chan)
  322. {
  323. int i = 10, k, l, ok = 0;
  324. char s[1024], *realnick;
  325. struct chanset_t *c;
  326. realnick = strchr (nick, ':');
  327. if (realnick)
  328. realnick++;
  329. else
  330. realnick = nick;
  331. putlog (LOG_BOTS, "*", "#%s# who", realnick);
  332. strcpy (s, "Channels: ");
  333. for (c = chanset; c; c = c->next)
  334. if (!channel_secret (c) && !channel_inactive (c))
  335. {
  336. l = strlen (c->name);
  337. if (i + l < 1021)
  338. {
  339. if (i > 10)
  340. sprintf (s, "%s, %s", s, c->name);
  341. else
  342. {
  343. strcpy (s, c->name);
  344. i += (l + 2);
  345. }
  346. }
  347. }
  348. if (i > 10)
  349. {
  350. botnet_send_priv (idx, botnetnick, nick, NULL, "%s (%s)", s, ver);
  351. }
  352. else
  353. botnet_send_priv (idx, botnetnick, nick, NULL, "%s (%s)", BOT_NOCHANNELS,
  354. ver);
  355. if (admin[0])
  356. botnet_send_priv (idx, botnetnick, nick, NULL, "Admin: %s", admin);
  357. if (chan == 0)
  358. botnet_send_priv (idx, botnetnick, nick, NULL,
  359. "%s (* = %s, + = %s, @ = %s)", BOT_PARTYMEMBS,
  360. MISC_OWNER, MISC_MASTER, MISC_OP);
  361. else
  362. {
  363. simple_sprintf (s, "assoc %d", chan);
  364. if ((Tcl_Eval (interp, s) != TCL_OK) || !interp->result[0])
  365. botnet_send_priv (idx, botnetnick, nick, NULL,
  366. "%s %s%d: (* = %s, + = %s, @ = %s)\n",
  367. BOT_PEOPLEONCHAN, (chan < GLOBAL_CHANS) ? "" : "*",
  368. chan % GLOBAL_CHANS, MISC_OWNER, MISC_MASTER,
  369. MISC_OP);
  370. else
  371. botnet_send_priv (idx, botnetnick, nick, NULL,
  372. "%s '%s' (%s%d): (* = %s, + = %s, @ = %s)\n",
  373. BOT_PEOPLEONCHAN, interp->result,
  374. (chan < GLOBAL_CHANS) ? "" : "*",
  375. chan % GLOBAL_CHANS, MISC_OWNER, MISC_MASTER,
  376. MISC_OP);
  377. }
  378. for (i = 0; i < dcc_total; i++)
  379. if (dcc[i].type->flags & DCT_REMOTEWHO)
  380. if (dcc[i].u.chat->channel == chan)
  381. {
  382. k =
  383. sprintf (s, " %c%-15s %s",
  384. (geticon (i) == '-' ? ' ' : geticon (i)), dcc[i].nick,
  385. dcc[i].host);
  386. if (now - dcc[i].timeval > 300)
  387. {
  388. unsigned long days, hrs, mins;
  389. days = (now - dcc[i].timeval) / 86400;
  390. hrs = ((now - dcc[i].timeval) - (days * 86400)) / 3600;
  391. mins = ((now - dcc[i].timeval) - (hrs * 3600)) / 60;
  392. if (days > 0)
  393. sprintf (s + k, " (%s %lud%luh)", MISC_IDLE, days, hrs);
  394. else if (hrs > 0)
  395. sprintf (s + k, " (%s %luh%lum)", MISC_IDLE, hrs, mins);
  396. else
  397. sprintf (s + k, " (%s %lum)", MISC_IDLE, mins);
  398. }
  399. botnet_send_priv (idx, botnetnick, nick, NULL, "%s", s);
  400. if (dcc[i].u.chat->away != NULL)
  401. botnet_send_priv (idx, botnetnick, nick, NULL, " %s: %s",
  402. MISC_AWAY, dcc[i].u.chat->away);
  403. }
  404. for (i = 0; i < dcc_total; i++)
  405. if (dcc[i].type == &DCC_BOT)
  406. {
  407. if (!ok)
  408. {
  409. ok = 1;
  410. botnet_send_priv (idx, botnetnick, nick, NULL, "%s:",
  411. BOT_BOTSCONNECTED);
  412. }
  413. sprintf (s, " %s%c%-15s %s",
  414. dcc[i].status & STAT_CALLED ? "<-" : "->",
  415. dcc[i].status & STAT_SHARE ? '+' : ' ', dcc[i].nick,
  416. dcc[i].u.bot->version);
  417. botnet_send_priv (idx, botnetnick, nick, NULL, "%s", s);
  418. }
  419. ok = 0;
  420. for (i = 0; i < dcc_total; i++)
  421. if (dcc[i].type->flags & DCT_REMOTEWHO)
  422. if (dcc[i].u.chat->channel != chan)
  423. {
  424. if (!ok)
  425. {
  426. ok = 1;
  427. botnet_send_priv (idx, botnetnick, nick, NULL, "%s:",
  428. BOT_OTHERPEOPLE);
  429. }
  430. l =
  431. sprintf (s, " %c%-15s %s",
  432. (geticon (i) == '-' ? ' ' : geticon (i)), dcc[i].nick,
  433. dcc[i].host);
  434. if (now - dcc[i].timeval > 300)
  435. {
  436. k = (now - dcc[i].timeval) / 60;
  437. if (k < 60)
  438. sprintf (s + l, " (%s %dm)", MISC_IDLE, k);
  439. else
  440. sprintf (s + l, " (%s %dh%dm)", MISC_IDLE, k / 60, k % 60);
  441. }
  442. botnet_send_priv (idx, botnetnick, nick, NULL, "%s", s);
  443. if (dcc[i].u.chat->away != NULL)
  444. botnet_send_priv (idx, botnetnick, nick, NULL, " %s: %s",
  445. MISC_AWAY, dcc[i].u.chat->away);
  446. }
  447. }
  448. static void
  449. bot_sysname (int idx, char *par)
  450. {
  451. dcc[idx].u.bot->sysname[0] = 0;
  452. strcpy (dcc[idx].u.bot->sysname, par);
  453. } static void
  454. bot_who (int idx, char *par)
  455. {
  456. char *from, *to, *p;
  457. int i, chan;
  458. from = newsplit (&par);
  459. p = strchr (from, '@');
  460. if (!p)
  461. {
  462. sprintf (TBUF, "%s@%s", from, dcc[idx].nick);
  463. from = TBUF;
  464. }
  465. to = newsplit (&par);
  466. if (!egg_strcasecmp (to, botnetnick))
  467. to[0] = 0;
  468. chan = base64_to_int (par);
  469. if (to[0])
  470. {
  471. i = nextbot (to);
  472. if (i >= 0)
  473. botnet_send_who (i, from, to, chan);
  474. }
  475. else
  476. {
  477. remote_tell_who (idx, from, chan);
  478. }
  479. }
  480. static void
  481. bot_endlink (int idx, char *par)
  482. {
  483. dcc[idx].status &= ~STAT_LINKING;
  484. } static void
  485. bot_infoq (int idx, char *par)
  486. {
  487. char s[200], s2[32], *realnick;
  488. struct chanset_t *chan;
  489. time_t now2;
  490. int hr, min;
  491. realnick = strchr (par, ':');
  492. if (realnick)
  493. realnick++;
  494. else
  495. realnick = par;
  496. putlog (LOG_BOTS, "@", "#%s# botinfo", realnick);
  497. now2 = now - online_since;
  498. s2[0] = 0;
  499. if (now2 > 86400)
  500. {
  501. int days = now2 / 86400;
  502. sprintf (s2, "%d day", days);
  503. if (days >= 2)
  504. strcat (s2, "s");
  505. strcat (s2, ", ");
  506. now2 -= days * 86400;
  507. }
  508. hr = (time_t) ((int) now2 / 3600);
  509. now2 -= (hr * 3600);
  510. min = (time_t) ((int) now2 / 60);
  511. sprintf (&s2[strlen (s2)], "%02d:%02d", (int) hr, (int) min);
  512. if (module_find ("server", 0, 0))
  513. {
  514. s[0] = 0;
  515. for (chan = chanset; chan; chan = chan->next)
  516. {
  517. if (!channel_secret (chan))
  518. {
  519. if ((strlen (s) + strlen (chan->dname) + strlen (network) +
  520. strlen (botnetnick) + strlen (ver) + 1) >= 200)
  521. {
  522. strcat (s, "++ ");
  523. break;
  524. }
  525. strcat (s, chan->dname);
  526. strcat (s, ", ");
  527. }
  528. }
  529. if (s[0])
  530. {
  531. s[strlen (s) - 2] = 0;
  532. botnet_send_priv (idx, botnetnick, par, NULL,
  533. "%s <%s> (%s) [UP %s]", ver, network, s, s2);
  534. }
  535. else
  536. botnet_send_priv (idx, botnetnick, par, NULL, "%s <%s> (%s) [UP %s]",
  537. ver, network, BOT_NOCHANNELS, s2);
  538. }
  539. else
  540. botnet_send_priv (idx, botnetnick, par, NULL, "%s <NO_IRC> [UP %s]", ver,
  541. s2);
  542. botnet_send_infoq (idx, par);
  543. }
  544. static void
  545. bot_ping (int idx, char *par)
  546. {
  547. botnet_send_pong (idx);
  548. } static void
  549. bot_pong (int idx, char *par)
  550. {
  551. dcc[idx].status &= ~STAT_PINGED;
  552. if (dcc[idx].pingtime > (now - 120))
  553. dcc[idx].pingtime -= now;
  554. else
  555. dcc[idx].pingtime = 120;
  556. }
  557. static void
  558. bot_link (int idx, char *par)
  559. {
  560. char *from, *bot, *rfrom;
  561. int i;
  562. from = newsplit (&par);
  563. bot = newsplit (&par);
  564. if (!egg_strcasecmp (bot, botnetnick))
  565. {
  566. if ((rfrom = strchr (from, ':')))
  567. rfrom++;
  568. else
  569. rfrom = from;
  570. putlog (LOG_CMDS, "*", "#%s# link %s", rfrom, par);
  571. if (botlink (from, -1, par))
  572. botnet_send_priv (idx, botnetnick, from, NULL, "%s %s ...",
  573. BOT_LINKATTEMPT, par);
  574. else
  575. botnet_send_priv (idx, botnetnick, from, NULL, "%s.",
  576. BOT_CANTLINKTHERE);
  577. }
  578. else
  579. {
  580. i = nextbot (bot);
  581. if (i >= 0)
  582. botnet_send_link (i, from, bot, par);
  583. }
  584. }
  585. static void
  586. bot_unlink (int idx, char *par)
  587. {
  588. char *from, *bot, *rfrom, *p, *undes;
  589. int i;
  590. from = newsplit (&par);
  591. bot = newsplit (&par);
  592. undes = newsplit (&par);
  593. if (!egg_strcasecmp (bot, botnetnick))
  594. {
  595. if ((rfrom = strchr (from, ':')))
  596. rfrom++;
  597. else
  598. rfrom = from;
  599. putlog (LOG_CMDS, "*", "#%s# unlink %s (%s)", rfrom, undes,
  600. par[0] ? par : "No reason");
  601. i = botunlink (-3, undes, par[0] ? par : NULL);
  602. if (i == 1)
  603. {
  604. p = strchr (from, '@');
  605. if (p)
  606. {
  607. i = nextbot (p + 1);
  608. if (i >= 0)
  609. botnet_send_priv (i, botnetnick, from, NULL,
  610. "Unlinked from %s.", undes);
  611. }
  612. }
  613. else if (i == 0)
  614. {
  615. botnet_send_unlinked (-1, undes, "");
  616. p = strchr (from, '@');
  617. if (p)
  618. {
  619. i = nextbot (p + 1);
  620. if (i >= 0)
  621. botnet_send_priv (i, botnetnick, from, NULL, "%s %s.",
  622. BOT_CANTUNLINK, undes);
  623. }
  624. }
  625. else
  626. {
  627. p = strchr (from, '@');
  628. if (p)
  629. {
  630. i = nextbot (p + 1);
  631. if (i >= 0)
  632. botnet_send_priv (i, botnetnick, from, NULL,
  633. "Can't remotely unlink sharebots.");
  634. }
  635. }
  636. }
  637. else
  638. {
  639. i = nextbot (bot);
  640. if (i >= 0)
  641. botnet_send_unlink (i, from, bot, undes, par);
  642. }
  643. }
  644. static void
  645. bot_update (int idx, char *par)
  646. {
  647. char *bot, x;
  648. int vnum;
  649. bot = newsplit (&par);
  650. x = par[0];
  651. if (x)
  652. par++;
  653. vnum = base64_to_int (par);
  654. if (in_chain (bot))
  655. updatebot (idx, bot, x, vnum);
  656. }
  657. static void
  658. bot_mtcl (char *botnick, char *code, char *par)
  659. {
  660. int oidx = 0, tcode = 0;
  661. char ret[2000], buf[2000];
  662. if (!par[0])
  663. return;
  664. oidx = atoi (newsplit (&par));
  665. if (!par[0])
  666. return;
  667. sprintf (buf, "%s", par);
  668. tcode = Tcl_GlobalEval (interp, buf);
  669. if (tcode == TCL_OK)
  670. sprintf (ret, "r_mt %d Tcl: %s", oidx, interp->result);
  671. else
  672. sprintf (ret, "r_mt %d Tcl error: %s", oidx, interp->result);
  673. putbot (botnick, ret);
  674. }
  675. static void
  676. bot_rmtcl (char *botnick, char *code, char *par)
  677. {
  678. int oidx = 0;
  679. oidx = atoi (newsplit (&par));
  680. if (!par[0])
  681. return;
  682. dprintf (oidx, "(%s) %s\n", botnick, par);
  683. }
  684. static void
  685. bot_nlinked (int idx, char *par)
  686. {
  687. char *newbot, *next, *p, s[1024], x;
  688. int bogus = 0, i;
  689. struct userrec *u;
  690. newbot = newsplit (&par);
  691. next = newsplit (&par);
  692. s[0] = 0;
  693. if (!next[0])
  694. {
  695. putlog (LOG_BOTS, "*", "Invalid eggnet protocol from %s (zapfing)",
  696. dcc[idx].nick);
  697. simple_sprintf (s, "%s %s (%s)", MISC_DISCONNECTED, dcc[idx].nick,
  698. MISC_INVALIDBOT);
  699. dprintf (idx, "error invalid eggnet protocol for 'nlinked'\n");
  700. }
  701. else if ((in_chain (newbot)) || (!egg_strcasecmp (newbot, botnetnick)))
  702. {
  703. putlog (LOG_BOTS, "*", "%s %s (mutual: %s)", BOT_LOOPDETECT,
  704. dcc[idx].nick, newbot);
  705. simple_sprintf (s, "%s %s: disconnecting %s", MISC_LOOP, newbot,
  706. dcc[idx].nick);
  707. dprintf (idx, "error Loop (%s)\n", newbot);
  708. }
  709. if (!s[0])
  710. {
  711. for (p = newbot; *p; p++)
  712. if ((*p < 32) || (*p == 127) || ((p - newbot) >= HANDLEN))
  713. bogus = 1;
  714. i = nextbot (next);
  715. if (i != idx)
  716. bogus = 1;
  717. }
  718. if (bogus)
  719. {
  720. putlog (LOG_BOTS, "*", "%s %s! (%s -> %s)", BOT_BOGUSLINK,
  721. dcc[idx].nick, next, newbot);
  722. simple_sprintf (s, "%s: %s %s", BOT_BOGUSLINK, dcc[idx].nick,
  723. MISC_DISCONNECTED);
  724. dprintf (idx, "error %s (%s -> %s)\n", BOT_BOGUSLINK, next, newbot);
  725. }
  726. if (bot_flags (dcc[idx].user) & BOT_LEAF)
  727. {
  728. putlog (LOG_BOTS, "*", "%s %s (%s %s)", BOT_DISCONNLEAF, dcc[idx].nick,
  729. newbot, BOT_LINKEDTO);
  730. simple_sprintf (s, "%s %s (to %s): %s", BOT_ILLEGALLINK, dcc[idx].nick,
  731. newbot, MISC_DISCONNECTED);
  732. dprintf (idx, "error %s\n", BOT_YOUREALEAF);
  733. }
  734. if (s[0])
  735. {
  736. chatout ("*** %s\n", s);
  737. botnet_send_unlinked (idx, dcc[idx].nick, s);
  738. dprintf (idx, "bye %s\n", BOT_ILLEGALLINK);
  739. killsock (dcc[idx].sock);
  740. lostdcc (idx);
  741. return;
  742. }
  743. x = par[0];
  744. if (x)
  745. par++;
  746. else
  747. x = '-';
  748. i = base64_to_int (par);
  749. botnet_send_nlinked (idx, newbot, next, x, i);
  750. if (x == '!')
  751. {
  752. chatout ("*** (%s) %s %s.\n", next, NET_LINKEDTO, newbot);
  753. x = '-';
  754. }
  755. addbot (newbot, dcc[idx].nick, next, x, i);
  756. check_tcl_link (newbot, next);
  757. u = get_user_by_handle (userlist, newbot);
  758. if (bot_flags (u) & BOT_REJECT)
  759. {
  760. botnet_send_reject (idx, botnetnick, NULL, newbot, NULL, NULL);
  761. putlog (LOG_BOTS, "*", "%s %s %s %s", BOT_REJECTING, newbot, MISC_FROM,
  762. dcc[idx].nick);
  763. }
  764. }
  765. static void
  766. bot_unlinked (int idx, char *par)
  767. {
  768. int i;
  769. char *bot;
  770. bot = newsplit (&par);
  771. i = nextbot (bot);
  772. if ((i >= 0) && (i != idx))
  773. fake_alert (idx, "direction", bot);
  774. else if (i >= 0)
  775. {
  776. if (par[0])
  777. chatout ("*** (%s) %s\n", lastbot (bot), par);
  778. botnet_send_unlinked (idx, bot, par);
  779. unvia (idx, findbot (bot));
  780. rembot (bot);
  781. }
  782. }
  783. static void
  784. bot_trace (int idx, char *par)
  785. {
  786. char *from, *dest;
  787. int i;
  788. from = newsplit (&par);
  789. dest = newsplit (&par);
  790. simple_sprintf (TBUF, "%s:%s", par, botnetnick);
  791. botnet_send_traced (idx, from, TBUF);
  792. if (egg_strcasecmp (dest, botnetnick) && ((i = nextbot (dest)) > 0))
  793. botnet_send_trace (i, from, dest, par);
  794. }
  795. static void
  796. bot_traced (int idx, char *par)
  797. {
  798. char *to, *p;
  799. int i, sock;
  800. to = newsplit (&par);
  801. p = strchr (to, '@');
  802. if (p == NULL)
  803. p = to;
  804. else
  805. {
  806. *p = 0;
  807. p++;
  808. }
  809. if (!egg_strcasecmp (p, botnetnick))
  810. {
  811. time_t t = 0;
  812. char *p = par, *ss = TBUF;
  813. splitc (ss, to, ':');
  814. if (ss[0])
  815. sock = atoi (ss);
  816. else
  817. sock = (-1);
  818. if (par[0] == ':')
  819. {
  820. t = atoi (par + 1);
  821. p = strchr (par + 1, ':');
  822. if (p)
  823. p++;
  824. else
  825. p = par + 1;
  826. }
  827. for (i = 0; i < dcc_total; i++)
  828. if ((dcc[i].type->flags & DCT_CHAT)
  829. && (!egg_strcasecmp (dcc[i].nick, to)) && ((sock == (-1))
  830. || (sock ==
  831. dcc[i].sock)))
  832. {
  833. if (t)
  834. {
  835. int j = 0;
  836. {
  837. register char *c = p;
  838. for (; *c != '\0'; c++)
  839. if (*c == ':')
  840. j++;
  841. }
  842. dprintf (i, "%s -> %s (%lu secs, %d hop%s)\n",
  843. BOT_TRACERESULT, p, now - t, j, (j != 1) ? "s" : "");
  844. }
  845. else
  846. dprintf (i, "%s -> %s\n", BOT_TRACERESULT, p);
  847. }
  848. }
  849. else
  850. {
  851. i = nextbot (p);
  852. if (p != to)
  853. *--p = '@';
  854. if (i >= 0)
  855. botnet_send_traced (i, to, par);
  856. }
  857. }
  858. void
  859. bot_timesync (int idx, char *par)
  860. {
  861. putlog (LOG_DEBUG, "*", "Got timesync from %s: %s\n", dcc[idx].nick, par);
  862. timesync = atoi (par) - now;
  863. #ifdef HUB
  864. send_timesync (-1);
  865. #endif
  866. } static void
  867. bot_reject (int idx, char *par)
  868. {
  869. char *from, *who, *destbot, *frombot;
  870. struct userrec *u;
  871. int i;
  872. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  873. return;
  874. from = newsplit (&par);
  875. frombot = strchr (from, '@');
  876. if (frombot)
  877. frombot++;
  878. else
  879. frombot = from;
  880. i = nextbot (frombot);
  881. if (i != idx)
  882. {
  883. fake_alert (idx, "direction", frombot);
  884. return;
  885. }
  886. who = newsplit (&par);
  887. if (!(destbot = strchr (who, '@')))
  888. {
  889. i = nextbot (who);
  890. if (i < 0)
  891. {
  892. botnet_send_priv (idx, botnetnick, from, NULL, "%s %s (%s)",
  893. BOT_CANTUNLINK, who, BOT_DOESNTEXIST);
  894. }
  895. else if (!egg_strcasecmp (dcc[i].nick, who))
  896. {
  897. char s[1024];
  898. putlog (LOG_BOTS, "*", "%s %s %s", from, MISC_REJECTED,
  899. dcc[i].nick);
  900. dprintf (i, "bye %s\n", par[0] ? par : MISC_REJECTED);
  901. simple_sprintf (s, "%s %s (%s: %s)", MISC_DISCONNECTED, dcc[i].nick,
  902. from, par[0] ? par : MISC_REJECTED);
  903. chatout ("*** %s\n", s);
  904. botnet_send_unlinked (i, dcc[i].nick, s);
  905. killsock (dcc[i].sock);
  906. lostdcc (i);
  907. }
  908. else
  909. {
  910. if (i >= 0)
  911. botnet_send_reject (i, from, NULL, who, NULL, par);
  912. }
  913. }
  914. else
  915. {
  916. *destbot++ = 0;
  917. if (!egg_strcasecmp (destbot, botnetnick))
  918. {
  919. int ok = 0;
  920. if (remote_boots == 1)
  921. {
  922. frombot = strchr (from, '@');
  923. if (frombot == NULL)
  924. frombot = from;
  925. else
  926. frombot++;
  927. u = get_user_by_handle (userlist, frombot);
  928. if (!(bot_flags (u) & BOT_SHARE))
  929. {
  930. add_note (from, botnetnick, "No non sharebot boots.", -1,
  931. 0);
  932. ok = 1;
  933. }
  934. }
  935. else if (remote_boots == 0)
  936. {
  937. botnet_send_priv (idx, botnetnick, from, NULL, "%s",
  938. BOT_NOREMOTEBOOT);
  939. ok = 1;
  940. }
  941. for (i = 0; (i < dcc_total) && (!ok); i++)
  942. if ((!egg_strcasecmp (who, dcc[i].nick))
  943. && (dcc[i].type->flags & DCT_CHAT))
  944. {
  945. u = get_user_by_handle (userlist, dcc[i].nick);
  946. if (u
  947. && ((u->flags & USER_OWNER)
  948. && !(dcc[idx].user->flags & USER_ADMIN)))
  949. {
  950. add_note (from, botnetnick, BOT_NOOWNERBOOT, -1, 0);
  951. return;
  952. }
  953. do_boot (i, from, par);
  954. ok = 1;
  955. putlog (LOG_CMDS, "*", "#%s# boot %s (%s)", from, who,
  956. par[0] ? par : "No reason");
  957. }
  958. }
  959. else
  960. {
  961. i = nextbot (destbot);
  962. *--destbot = '@';
  963. if (i >= 0)
  964. botnet_send_reject (i, from, NULL, who, NULL, par);
  965. }
  966. }
  967. }
  968. static void
  969. bot_thisbot (int idx, char *par)
  970. {
  971. if (egg_strcasecmp (par, dcc[idx].nick))
  972. {
  973. char s[1024];
  974. putlog (LOG_BOTS, "*", NET_WRONGBOT, dcc[idx].nick, par);
  975. dprintf (idx, "bye %s\n", MISC_IMPOSTER);
  976. simple_sprintf (s, "%s %s (%s)", MISC_DISCONNECTED, dcc[idx].nick,
  977. MISC_IMPOSTER);
  978. chatout ("*** %s\n", s);
  979. botnet_send_unlinked (idx, dcc[idx].nick, s);
  980. unvia (idx, findbot (dcc[idx].nick));
  981. killsock (dcc[idx].sock);
  982. lostdcc (idx);
  983. return;
  984. }
  985. if (bot_flags (dcc[idx].user) & BOT_LEAF)
  986. dcc[idx].status |= STAT_LEAF;
  987. noshare = 1;
  988. change_handle (dcc[idx].user, par);
  989. noshare = 0;
  990. strcpy (dcc[idx].nick, par);
  991. }
  992. static void
  993. bot_hublog (char *botnick, char *code, char *par)
  994. {
  995. #ifdef HUB
  996. int type;
  997. type = atoi (newsplit (&par));
  998. putlog (type, "@", "(%s) %s", botnick, par);
  999. #endif
  1000. } static void
  1001. bot_handshake (int idx, char *par)
  1002. {
  1003. struct userrec *u = get_user_by_handle (userlist, dcc[idx].nick);
  1004. noshare = 1;
  1005. set_user (&USERENTRY_PASS, u, par);
  1006. noshare = 0;
  1007. } static void
  1008. bot_zapf (int idx, char *par)
  1009. {
  1010. char *from, *to;
  1011. int i;
  1012. from = newsplit (&par);
  1013. to = newsplit (&par);
  1014. i = nextbot (from);
  1015. if (i != idx)
  1016. {
  1017. fake_alert (idx, "direction", from);
  1018. return;
  1019. }
  1020. if (!egg_strcasecmp (to, botnetnick))
  1021. {
  1022. char *opcode;
  1023. opcode = newsplit (&par);
  1024. check_tcl_bot (from, opcode, par);
  1025. return;
  1026. }
  1027. i = nextbot (to);
  1028. if (i >= 0)
  1029. botnet_send_zapf (i, from, to, par);
  1030. }
  1031. static void
  1032. bot_zapfbroad (int idx, char *par)
  1033. {
  1034. char *from, *opcode;
  1035. int i;
  1036. from = newsplit (&par);
  1037. opcode = newsplit (&par);
  1038. i = nextbot (from);
  1039. if (i != idx)
  1040. {
  1041. fake_alert (idx, "direction", from);
  1042. return;
  1043. }
  1044. check_tcl_bot (from, opcode, par);
  1045. botnet_send_zapf_broad (idx, from, opcode, par);
  1046. }
  1047. static void
  1048. bot_filereject (int idx, char *par)
  1049. {
  1050. char *path, *to, *tobot, *p;
  1051. int i;
  1052. path = newsplit (&par);
  1053. to = newsplit (&par);
  1054. if ((tobot = strchr (to, '@')))
  1055. tobot++;
  1056. else
  1057. tobot = to;
  1058. if (egg_strcasecmp (tobot, botnetnick))
  1059. {
  1060. p = strchr (to, ':');
  1061. if (p != NULL)
  1062. {
  1063. *p = 0;
  1064. for (i = 0; i < dcc_total; i++)
  1065. {
  1066. if (dcc[i].sock == atoi (to))
  1067. dprintf (i, "%s (%s): %s\n", BOT_XFERREJECTED, path, par);
  1068. }
  1069. *p = ':';
  1070. }
  1071. putlog (LOG_FILES, "*", "%s %s: %s", path, MISC_REJECTED, par);
  1072. }
  1073. else
  1074. {
  1075. i = nextbot (tobot);
  1076. if (i >= 0)
  1077. botnet_send_filereject (i, path, to, par);
  1078. }
  1079. }
  1080. static void
  1081. bot_filereq (int idx, char *tobot)
  1082. {
  1083. char *from, *path;
  1084. int i;
  1085. from = newsplit (&tobot);
  1086. if ((path = strchr (tobot, ':')))
  1087. {
  1088. *path++ = 0;
  1089. if (!egg_strcasecmp (tobot, botnetnick))
  1090. {
  1091. module_entry *fs = module_find ("filesys", 0, 0);
  1092. if (fs == NULL)
  1093. botnet_send_priv (idx, botnetnick, from, NULL, MOD_NOFILESYSMOD);
  1094. else
  1095. {
  1096. Function f = fs->funcs[FILESYS_REMOTE_REQ];
  1097. f (idx, from, path);
  1098. }
  1099. }
  1100. else
  1101. {
  1102. i = nextbot (tobot);
  1103. if (i >= 0)
  1104. botnet_send_filereq (i, from, tobot, path);
  1105. }
  1106. }
  1107. }
  1108. static void
  1109. bot_filesend (int idx, char *par)
  1110. {
  1111. char *botpath, *to, *tobot, *nick;
  1112. int i;
  1113. char *nfn;
  1114. botpath = newsplit (&par);
  1115. to = newsplit (&par);
  1116. if ((tobot = strchr (to, '@')))
  1117. {
  1118. *tobot = 0;
  1119. tobot++;
  1120. }
  1121. else
  1122. {
  1123. tobot = to;
  1124. }
  1125. if (!egg_strcasecmp (tobot, botnetnick))
  1126. {
  1127. nfn = strrchr (botpath, '/');
  1128. if (nfn == NULL)
  1129. {
  1130. nfn = strrchr (botpath, ':');
  1131. if (nfn == NULL)
  1132. nfn = botpath;
  1133. else
  1134. nfn++;
  1135. }
  1136. else
  1137. nfn++;
  1138. if ((nick = strchr (to, ':')))
  1139. nick++;
  1140. else
  1141. nick = to;
  1142. dprintf (DP_SERVER, "PRIVMSG %s :\001DCC SEND %s %s\001\n", nick, nfn,
  1143. par);
  1144. }
  1145. else
  1146. {
  1147. i = nextbot (tobot);
  1148. if (i >= 0)
  1149. {
  1150. *--tobot = '@';
  1151. botnet_send_filesend (i, botpath, to, par);
  1152. }
  1153. }
  1154. }
  1155. static void
  1156. bot_error (int idx, char *par)
  1157. {
  1158. putlog (LOG_MISC | LOG_BOTS, "*", "%s: %s", dcc[idx].nick, par);
  1159. } static void
  1160. bot_nickchange (int idx, char *par)
  1161. {
  1162. char *bot, *ssock, *newnick;
  1163. int sock, i;
  1164. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  1165. return;
  1166. bot = newsplit (&par);
  1167. i = nextbot (bot);
  1168. if (i != idx)
  1169. {
  1170. fake_alert (idx, "direction", bot);
  1171. return;
  1172. }
  1173. ssock = newsplit (&par);
  1174. sock = base64_to_int (ssock);
  1175. newnick = newsplit (&par);
  1176. i = partynick (bot, sock, newnick);
  1177. if (i < 0)
  1178. {
  1179. fake_alert (idx, "sock#", ssock);
  1180. return;
  1181. }
  1182. chanout_but (-1, party[i].chan, "*** (%s) Nick change: %s -> %s\n", bot,
  1183. newnick, party[i].nick);
  1184. botnet_send_nkch_part (idx, i, newnick);
  1185. }
  1186. static void
  1187. bot_join (int idx, char *par)
  1188. {
  1189. char *bot, *nick, *x, *y;
  1190. struct userrec *u;
  1191. int i, sock, chan, i2, linking = 0;
  1192. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  1193. return;
  1194. bot = newsplit (&par);
  1195. if (bot[0] == '!')
  1196. {
  1197. linking = 1;
  1198. bot++;
  1199. }
  1200. if (b_status (idx) & STAT_LINKING)
  1201. {
  1202. linking = 1;
  1203. }
  1204. nick = newsplit (&par);
  1205. x = newsplit (&par);
  1206. chan = base64_to_int (x);
  1207. y = newsplit (&par);
  1208. if ((chan < 0) || !y[0])
  1209. return;
  1210. if (!y[0])
  1211. {
  1212. y[0] = '-';
  1213. sock = 0;
  1214. }
  1215. else
  1216. {
  1217. sock = base64_to_int (y + 1);
  1218. }
  1219. if (sock == 0)
  1220. sock = partysock (bot, nick);
  1221. if (sock == 0)
  1222. sock = fakesock++;
  1223. i = nextbot (bot);
  1224. if (i != idx)
  1225. {
  1226. fake_alert (idx, "direction", bot);
  1227. return;
  1228. }
  1229. u = get_user_by_handle (userlist, nick);
  1230. if (u)
  1231. {
  1232. sprintf (TBUF, "@%s", bot);
  1233. touch_laston (u, TBUF, now);
  1234. }
  1235. i = addparty (bot, nick, chan, y[0], sock, par, &i2);
  1236. botnet_send_join_party (idx, linking, i2, i);
  1237. if (i != chan)
  1238. {
  1239. if (i >= 0)
  1240. {
  1241. if (b_numver (idx) >= NEAT_BOTNET)
  1242. chanout_but (-1, i, "*** (%s) %s %s %s.\n", bot, nick,
  1243. NET_LEFTTHE, i ? "channel" : "party line");
  1244. check_tcl_chpt (bot, nick, sock, i);
  1245. }
  1246. if ((b_numver (idx) >= NEAT_BOTNET) && !linking)
  1247. chanout_but (-1, chan, "*** (%s) %s %s %s.\n", bot, nick,
  1248. NET_JOINEDTHE, chan ? "channel" : "party line");
  1249. check_tcl_chjn (bot, nick, chan, y[0], sock, par);
  1250. }
  1251. }
  1252. static void
  1253. bot_part (int idx, char *par)
  1254. {
  1255. char *bot, *nick, *etc;
  1256. struct userrec *u;
  1257. int sock, partyidx;
  1258. int silent = 0;
  1259. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  1260. return;
  1261. bot = newsplit (&par);
  1262. if (bot[0] == '!')
  1263. {
  1264. silent = 1;
  1265. bot++;
  1266. }
  1267. nick = newsplit (&par);
  1268. etc = newsplit (&par);
  1269. sock = base64_to_int (etc);
  1270. if (sock == 0)
  1271. sock = partysock (bot, nick);
  1272. u = get_user_by_handle (userlist, nick);
  1273. if (u)
  1274. {
  1275. sprintf (TBUF, "@%s", bot);
  1276. touch_laston (u, TBUF, now);
  1277. }
  1278. if ((partyidx = getparty (bot, sock)) != -1)
  1279. {
  1280. if (party[partyidx].chan >= 0)
  1281. check_tcl_chpt (bot, nick, sock, party[partyidx].chan);
  1282. if ((b_numver (idx) >= NEAT_BOTNET) && !silent)
  1283. {
  1284. register int chan = party[partyidx].chan;
  1285. if (par[0])
  1286. chanout_but (-1, chan, "*** (%s) %s %s %s (%s).\n", bot, nick,
  1287. NET_LEFTTHE, chan ? "channel" : "party line", par);
  1288. else
  1289. chanout_but (-1, chan, "*** (%s) %s %s %s.\n", bot, nick,
  1290. NET_LEFTTHE, chan ? "channel" : "party line");
  1291. }
  1292. botnet_send_part_party (idx, partyidx, par, silent);
  1293. remparty (bot, sock);
  1294. }
  1295. }
  1296. static void
  1297. bot_away (int idx, char *par)
  1298. {
  1299. char *bot, *etc;
  1300. int sock, partyidx, linking = 0;
  1301. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  1302. return;
  1303. bot = newsplit (&par);
  1304. if (bot[0] == '!')
  1305. {
  1306. linking = 1;
  1307. bot++;
  1308. }
  1309. if (b_status (idx) & STAT_LINKING)
  1310. {
  1311. linking = 1;
  1312. }
  1313. etc = newsplit (&par);
  1314. sock = base64_to_int (etc);
  1315. if (sock == 0)
  1316. sock = partysock (bot, etc);
  1317. check_tcl_away (bot, sock, par);
  1318. if (par[0])
  1319. {
  1320. partystat (bot, sock, PLSTAT_AWAY, 0);
  1321. partyaway (bot, sock, par);
  1322. }
  1323. else
  1324. {
  1325. partystat (bot, sock, 0, PLSTAT_AWAY);
  1326. }
  1327. partyidx = getparty (bot, sock);
  1328. if ((b_numver (idx) >= NEAT_BOTNET) && !linking)
  1329. {
  1330. if (par[0])
  1331. chanout_but (-1, party[partyidx].chan, "*** (%s) %s %s: %s.\n", bot,
  1332. party[partyidx].nick, NET_AWAY, par);
  1333. else
  1334. chanout_but (-1, party[partyidx].chan, "*** (%s) %s %s.\n", bot,
  1335. party[partyidx].nick, NET_UNAWAY);
  1336. }
  1337. botnet_send_away (idx, bot, sock, par, linking);
  1338. }
  1339. static void
  1340. bot_idle (int idx, char *par)
  1341. {
  1342. char *bot, *work;
  1343. int sock, idle;
  1344. if (bot_flags (dcc[idx].user) & BOT_ISOLATE)
  1345. return;
  1346. bot = newsplit (&par);
  1347. work = newsplit (&par);
  1348. sock = base64_to_int (work);
  1349. if (sock == 0)
  1350. sock = partysock (bot, work);
  1351. work = newsplit (&par);
  1352. idle = base64_to_int (work);
  1353. partysetidle (bot, sock, idle);
  1354. if (par[0])
  1355. {
  1356. partystat (bot, sock, PLSTAT_AWAY, 0);
  1357. partyaway (bot, sock, par);
  1358. }
  1359. botnet_send_idle (idx, bot, sock, idle, par);
  1360. }
  1361. void
  1362. bot_share (int idx, char *par)
  1363. {
  1364. sharein (idx, par);
  1365. } void
  1366. bot_shareupdate (int idx, char *par)
  1367. {
  1368. shareupdatein (idx, par);
  1369. } static void
  1370. bot_versions (int sock, char *par)
  1371. {
  1372. char *frombot = newsplit (&par), *tobot, *from;
  1373. module_entry *me;
  1374. if (nextbot (frombot) != sock)
  1375. fake_alert (sock, "versions-direction", frombot);
  1376. else if (egg_strcasecmp (tobot = newsplit (&par), botnetnick))
  1377. {
  1378. if ((sock = nextbot (tobot)) >= 0)
  1379. dprintf (sock, "v %s %s %s\n", frombot, tobot, par);
  1380. }
  1381. else
  1382. {
  1383. from = newsplit (&par);
  1384. botnet_send_priv (sock, botnetnick, from, frombot, "Modules loaded:\n");
  1385. for (me = module_list; me; me = me->next)
  1386. botnet_send_priv (sock, botnetnick, from, frombot,
  1387. " Module: %s (v%d.%d)\n", me->name, me->major,
  1388. me->minor);
  1389. botnet_send_priv (sock, botnetnick, from, frombot,
  1390. "End of module list.\n");
  1391. }
  1392. }
  1393. botcmd_t C_bot[] = { {"a", (Function) bot_actchan}
  1394. , {"aw", (Function) bot_away}
  1395. , {"away", (Function) bot_away}
  1396. , {"bye", (Function) bot_bye}
  1397. , {"c", (Function) bot_chan2}
  1398. , {"cg", (Function) bot_config}
  1399. ,
  1400. #ifdef S_DCCPASS
  1401. {"cp", (Function) bot_cmdpass}
  1402. ,
  1403. #endif
  1404. {"ct", (Function) bot_chat}
  1405. , {"e", (Function) bot_error}
  1406. , {"el", (Function) bot_endlink}
  1407. , {"f!", (Function) bot_filereject}
  1408. , {"fr", (Function) bot_filereq}
  1409. , {"fs", (Function) bot_filesend}
  1410. , {"hs", (Function) bot_handshake}
  1411. , {"i", (Function) bot_idle}
  1412. , {"i?", (Function) bot_infoq}
  1413. , {"j", (Function) bot_join}
  1414. , {"l", (Function) bot_link}
  1415. , {"n", (Function) bot_nlinked}
  1416. , {"nc", (Function) bot_nickchange}
  1417. , {"p", (Function) bot_priv}
  1418. , {"pi", (Function) bot_ping}
  1419. , {"po", (Function) bot_pong}
  1420. , {"pt", (Function) bot_part}
  1421. , {"r", (Function) bot_reject}
  1422. , {"rc", (Function) bot_remotecmd}
  1423. , {"rr", (Function) bot_remotereply}
  1424. , {"s", (Function) bot_share}
  1425. , {"sb", (Function) bot_shareupdate}
  1426. , {"t", (Function) bot_trace}
  1427. , {"tb", (Function) bot_thisbot}
  1428. , {"td", (Function) bot_traced}
  1429. , {"ts", (Function) bot_timesync}
  1430. , {"u", (Function) bot_update}
  1431. , {"ul", (Function) bot_unlink}
  1432. , {"un", (Function) bot_unlinked}
  1433. , {"v", (Function) bot_versions}
  1434. , {"vs", (Function) bot_sysname}
  1435. , {"w", (Function) bot_who}
  1436. , {"z", (Function) bot_zapf}
  1437. , {"zb", (Function) bot_zapfbroad}
  1438. , {NULL, NULL}
  1439. };
  1440. static cmd_t my_bot[] =
  1441. { {"hl", "", (Function) bot_hublog, NULL}, {"mt", "", (Function) bot_mtcl,
  1442. NULL}, {"r_mt", "",
  1443. (Function) bot_rmtcl,
  1444. NULL}, {NULL, NULL,
  1445. NULL, NULL} };
  1446. void
  1447. init_botcmd ()
  1448. {
  1449. add_builtins (H_bot, my_bot);
  1450. }