botmsg.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. /*
  2. * botmsg.c -- handles:
  3. * formatting of messages to be sent on the botnet
  4. * sending differnet messages to different versioned bots
  5. *
  6. * by Darrin Smith (beldin@light.iinet.net.au)
  7. *
  8. * $Id: botmsg.c,v 1.25 2002/01/02 03:46:35 guppy Exp $
  9. */
  10. /*
  11. * Copyright (C) 1997 Robey Pointer
  12. * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  27. */
  28. #include "main.h"
  29. #include "tandem.h"
  30. extern struct dcc_t *dcc;
  31. extern int dcc_total, tands;
  32. extern char botnetnick[];
  33. extern party_t *party;
  34. extern Tcl_Interp *interp;
  35. extern struct userrec *userlist;
  36. static char OBUF[1024];
  37. #ifndef NO_OLD_BOTNET
  38. /* Ditto for tandem bots
  39. */
  40. void tandout_but EGG_VARARGS_DEF(int, arg1)
  41. {
  42. int i, x, len;
  43. char *format;
  44. char s[601];
  45. va_list va;
  46. x = EGG_VARARGS_START(int, arg1, va);
  47. format = va_arg(va, char *);
  48. egg_vsnprintf(s, 511, format, va);
  49. va_end(va);
  50. s[sizeof(s)-1] = 0;
  51. len = strlen(s);
  52. for (i = 0; i < dcc_total; i++)
  53. if ((dcc[i].type == &DCC_BOT) && (i != x) &&
  54. (b_numver(i) < NEAT_BOTNET))
  55. tputs(dcc[i].sock, s, len);
  56. }
  57. #endif
  58. /* Thank you ircu :) */
  59. static char tobase64array[64] =
  60. {
  61. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  62. 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  63. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  64. 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  65. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  66. '[', ']'
  67. };
  68. char *int_to_base64(unsigned int val)
  69. {
  70. static char buf_base64[12];
  71. int i = 11;
  72. buf_base64[11] = 0;
  73. if (!val) {
  74. buf_base64[10] = 'A';
  75. return buf_base64 + 10;
  76. }
  77. while (val) {
  78. i--;
  79. buf_base64[i] = tobase64array[val & 0x3f];
  80. val = val >> 6;
  81. }
  82. return buf_base64 + i;
  83. }
  84. char *int_to_base10(int val)
  85. {
  86. static char buf_base10[17];
  87. int p = 0;
  88. int i = 16;
  89. buf_base10[16] = 0;
  90. if (!val) {
  91. buf_base10[15] = '0';
  92. return buf_base10 + 15;
  93. }
  94. if (val < 0) {
  95. p = 1;
  96. val *= -1;
  97. }
  98. while (val) {
  99. i--;
  100. buf_base10[i] = '0' + (val % 10);
  101. val /= 10;
  102. }
  103. if (p) {
  104. i--;
  105. buf_base10[i] = '-';
  106. }
  107. return buf_base10 + i;
  108. }
  109. char *unsigned_int_to_base10(unsigned int val)
  110. {
  111. static char buf_base10[16];
  112. int i = 15;
  113. buf_base10[15] = 0;
  114. if (!val) {
  115. buf_base10[14] = '0';
  116. return buf_base10 + 14;
  117. }
  118. while (val) {
  119. i--;
  120. buf_base10[i] = '0' + (val % 10);
  121. val /= 10;
  122. }
  123. return buf_base10 + i;
  124. }
  125. int simple_sprintf EGG_VARARGS_DEF(char *,arg1)
  126. {
  127. char *buf, *format, *s;
  128. int c = 0, i;
  129. va_list va;
  130. buf = EGG_VARARGS_START(char *, arg1, va);
  131. format = va_arg(va, char *);
  132. while (*format && c < 1023) {
  133. if (*format == '%') {
  134. format++;
  135. switch (*format) {
  136. case 's':
  137. s = va_arg(va, char *);
  138. break;
  139. case 'd':
  140. case 'i':
  141. i = va_arg(va, int);
  142. s = int_to_base10(i);
  143. break;
  144. case 'D':
  145. i = va_arg(va, int);
  146. s = int_to_base64((unsigned int) i);
  147. break;
  148. case 'u':
  149. i = va_arg(va, unsigned int);
  150. s = unsigned_int_to_base10(i);
  151. break;
  152. case '%':
  153. buf[c++] = *format++;
  154. continue;
  155. case 'c':
  156. buf[c++] = (char) va_arg(va, int);
  157. format++;
  158. continue;
  159. default:
  160. continue;
  161. }
  162. if (s)
  163. while (*s && c < 1023)
  164. buf[c++] = *s++;
  165. format++;
  166. } else
  167. buf[c++] = *format++;
  168. }
  169. va_end(va);
  170. buf[c] = 0;
  171. return c;
  172. }
  173. /* Ditto for tandem bots
  174. */
  175. void send_tand_but(int x, char *buf, int len)
  176. {
  177. int i, iso = 0;
  178. if (len < 0) {
  179. len = -len;
  180. iso = 1;
  181. }
  182. for (i = 0; i < dcc_total; i++)
  183. if ((dcc[i].type == &DCC_BOT) && (i != x) &&
  184. (b_numver(i) >= NEAT_BOTNET) &&
  185. (!iso || !(bot_flags(dcc[i].user) & BOT_ISOLATE)))
  186. tputs(dcc[i].sock, buf, len);
  187. }
  188. void botnet_send_bye()
  189. {
  190. if (tands > 0) {
  191. send_tand_but(-1, "bye\n", 4);
  192. #ifndef NO_OLD_BOTNET
  193. tandout_but(-1, "bye\n");
  194. #endif
  195. }
  196. }
  197. void botnet_send_chan(int idx, char *botnick, char *user,
  198. int chan, char *data)
  199. {
  200. int i;
  201. if ((tands > 0) && (chan < GLOBAL_CHANS)) {
  202. if (user) {
  203. i = simple_sprintf(OBUF, "c %s@%s %D %s\n", user, botnick, chan, data);
  204. } else {
  205. i = simple_sprintf(OBUF, "c %s %D %s\n", botnick, chan, data);
  206. }
  207. send_tand_but(idx, OBUF, -i);
  208. #ifndef NO_OLD_BOTNET
  209. tandout_but(idx, "chan %s%s%s %d %s\n", user ? user : "",
  210. user ? "@" : "", botnick, chan, data);
  211. #endif
  212. }
  213. }
  214. void botnet_send_act(int idx, char *botnick, char *user,
  215. int chan, char *data)
  216. {
  217. int i;
  218. if ((tands > 0) && (chan < GLOBAL_CHANS)) {
  219. if (user) {
  220. i = simple_sprintf(OBUF, "a %s@%s %D %s\n", user, botnick, chan, data);
  221. } else {
  222. i = simple_sprintf(OBUF, "a %s %D %s\n", botnick, chan, data);
  223. }
  224. send_tand_but(idx, OBUF, -i);
  225. #ifndef NO_OLD_BOTNET
  226. tandout_but(idx, "actchan %s%s%s %d %s\n", user ? user : "",
  227. user ? "@" : "", botnick, chan, data);
  228. #endif
  229. }
  230. }
  231. void botnet_send_chat(int idx, char *botnick, char *data)
  232. {
  233. int i;
  234. if (tands > 0) {
  235. i = simple_sprintf(OBUF, "ct %s %s\n", botnick, data);
  236. send_tand_but(idx, OBUF, -i);
  237. #ifndef NO_OLD_BOTNET
  238. tandout_but(idx, "chat %s %s\n", botnick, data);
  239. #endif
  240. }
  241. }
  242. void botnet_send_ping(int idx)
  243. {
  244. #ifndef NO_OLD_BOTNET
  245. if (b_numver(idx) < NEAT_BOTNET)
  246. tputs(dcc[idx].sock, "ping\n", 5);
  247. else
  248. #endif
  249. tputs(dcc[idx].sock, "pi\n", 3);
  250. }
  251. void botnet_send_pong(int idx)
  252. {
  253. #ifndef NO_OLD_BOTNET
  254. if (b_numver(idx) < NEAT_BOTNET)
  255. tputs(dcc[idx].sock, "pong\n", 5);
  256. else
  257. #endif
  258. tputs(dcc[idx].sock, "po\n", 3);
  259. }
  260. void botnet_send_priv EGG_VARARGS_DEF(int, arg1)
  261. {
  262. int idx, l;
  263. char *from, *to, *tobot, *format;
  264. char tbuf[1024];
  265. va_list va;
  266. idx = EGG_VARARGS_START(int, arg1, va);
  267. from = va_arg(va, char *);
  268. to = va_arg(va, char *);
  269. tobot = va_arg(va, char *);
  270. format = va_arg(va, char *);
  271. egg_vsnprintf(tbuf, 450, format, va);
  272. va_end(va);
  273. tbuf[sizeof(tbuf)-1] = 0;
  274. if (tobot) {
  275. #ifndef NO_OLD_BOTNET
  276. if (b_numver(idx) < NEAT_BOTNET)
  277. l = simple_sprintf(OBUF, "priv %s %s@%s %s\n", from, to, tobot, tbuf);
  278. else
  279. #endif
  280. l = simple_sprintf(OBUF, "p %s %s@%s %s\n", from, to, tobot, tbuf);
  281. } else {
  282. #ifndef NO_OLD_BOTNET
  283. if (b_numver(idx) < NEAT_BOTNET)
  284. l = simple_sprintf(OBUF, "priv %s %s %s\n", from, to, tbuf);
  285. else
  286. #endif
  287. l = simple_sprintf(OBUF, "p %s %s %s\n", from, to, tbuf);
  288. }
  289. tputs(dcc[idx].sock, OBUF, l);
  290. }
  291. void botnet_send_who(int idx, char *from, char *to, int chan)
  292. {
  293. int l;
  294. #ifndef NO_OLD_BOTNET
  295. if (b_numver(idx) < NEAT_BOTNET)
  296. l = simple_sprintf(OBUF, "who %s %s %d\n", from, to, chan);
  297. else
  298. #endif
  299. l = simple_sprintf(OBUF, "w %s %s %D\n", from, to, chan);
  300. tputs(dcc[idx].sock, OBUF, l);
  301. }
  302. void botnet_send_infoq(int idx, char *par)
  303. {
  304. int i = simple_sprintf(OBUF, "i? %s\n", par);
  305. send_tand_but(idx, OBUF, i);
  306. #ifndef NO_OLD_BOTNET
  307. tandout_but(idx, "info? %s\n", par);
  308. #endif
  309. }
  310. void botnet_send_unlink(int idx, char *who, char *via,
  311. char *bot, char *reason)
  312. {
  313. int l;
  314. #ifndef NO_OLD_BOTNET
  315. if (b_numver(idx) < NEAT_BOTNET)
  316. l = simple_sprintf(OBUF, "unlink %s %s %s %s\n", who, via, bot, reason);
  317. else
  318. #endif
  319. l = simple_sprintf(OBUF, "ul %s %s %s %s\n", who, via, bot, reason);
  320. tputs(dcc[idx].sock, OBUF, l);
  321. }
  322. void botnet_send_link(int idx, char *who, char *via, char *bot)
  323. {
  324. int l;
  325. #ifndef NO_OLD_BOTNET
  326. if (b_numver(idx) < NEAT_BOTNET)
  327. l = simple_sprintf(OBUF, "link %s %s %s\n", who, via, bot);
  328. else
  329. #endif
  330. l = simple_sprintf(OBUF, "l %s %s %s\n", who, via, bot);
  331. tputs(dcc[idx].sock, OBUF, l);
  332. }
  333. void botnet_send_unlinked(int idx, char *bot, char *args)
  334. {
  335. int l;
  336. if (tands > 0) {
  337. l = simple_sprintf(OBUF, "un %s %s\n", bot, args ? args : "");
  338. send_tand_but(idx, OBUF, l);
  339. #ifndef NO_OLD_BOTNET
  340. if ((idx >= 0) && (b_numver(idx) >= NEAT_BOTNET) && args && args[0])
  341. tandout_but(idx, "chat %s %s\n", lastbot(bot), args);
  342. tandout_but(idx, "unlinked %s\n", bot);
  343. #endif
  344. }
  345. }
  346. void botnet_send_nlinked(int idx, char *bot, char *next, char flag,
  347. int vernum)
  348. {
  349. int l;
  350. if (tands > 0) {
  351. l = simple_sprintf(OBUF, "n %s %s %c%D\n", bot, next, flag, vernum);
  352. send_tand_but(idx, OBUF, l);
  353. #ifndef NO_OLD_BOTNET
  354. if (flag == '!') {
  355. flag = '-';
  356. tandout_but(idx, "chat %s %s %s\n", next, NET_LINKEDTO, bot);
  357. }
  358. tandout_but(idx, "nlinked %s %s %c%d\n", bot, next, flag, vernum);
  359. #endif
  360. }
  361. }
  362. void botnet_send_traced(int idx, char *bot, char *buf)
  363. {
  364. int l;
  365. #ifndef NO_OLD_BOTNET
  366. if (b_numver(idx) < NEAT_BOTNET)
  367. l = simple_sprintf(OBUF, "traced %s %s\n", bot, buf);
  368. else
  369. #endif
  370. l = simple_sprintf(OBUF, "td %s %s\n", bot, buf);
  371. tputs(dcc[idx].sock, OBUF, l);
  372. }
  373. void botnet_send_trace(int idx, char *to, char *from, char *buf)
  374. {
  375. int l;
  376. #ifndef NO_OLD_BOTNET
  377. if (b_numver(idx) < NEAT_BOTNET)
  378. l = simple_sprintf(OBUF, "trace %s %s %s:%s\n", to, from, buf, botnetnick);
  379. else
  380. #endif
  381. l = simple_sprintf(OBUF, "t %s %s %s:%s\n", to, from, buf, botnetnick);
  382. tputs(dcc[idx].sock, OBUF, l);
  383. }
  384. void botnet_send_update(int idx, tand_t * ptr)
  385. {
  386. int l;
  387. if (tands > 0) {
  388. l = simple_sprintf(OBUF, "u %s %c%D\n", ptr->bot, ptr->share, ptr->ver);
  389. send_tand_but(idx, OBUF, l);
  390. #ifndef NO_OLD_BOTNET
  391. tandout_but(idx, "update %s %c%d\n", ptr->bot, ptr->share, ptr->ver);
  392. #endif
  393. }
  394. }
  395. void botnet_send_reject(int idx, char *fromp, char *frombot, char *top,
  396. char *tobot, char *reason)
  397. {
  398. int l;
  399. char to[NOTENAMELEN + 1], from[NOTENAMELEN + 1];
  400. if (!(bot_flags(dcc[idx].user) & BOT_ISOLATE)) {
  401. if (tobot) {
  402. simple_sprintf(to, "%s@%s", top, tobot);
  403. top = to;
  404. }
  405. if (frombot) {
  406. simple_sprintf(from, "%s@%s", fromp, frombot);
  407. fromp = from;
  408. }
  409. if (!reason)
  410. reason = "";
  411. #ifndef NO_OLD_BOTNET
  412. if (b_numver(idx) < NEAT_BOTNET)
  413. l = simple_sprintf(OBUF, "reject %s %s %s\n", fromp, top, reason);
  414. else
  415. #endif
  416. l = simple_sprintf(OBUF, "r %s %s %s\n", fromp, top, reason);
  417. tputs(dcc[idx].sock, OBUF, l);
  418. }
  419. }
  420. void botnet_send_zapf(int idx, char *a, char *b, char *c)
  421. {
  422. int l;
  423. #ifndef NO_OLD_BOTNET
  424. if (b_numver(idx) < NEAT_BOTNET)
  425. l = simple_sprintf(OBUF, "zapf %s %s %s\n", a, b, c);
  426. else
  427. #endif
  428. l = simple_sprintf(OBUF, "z %s %s %s\n", a, b, c);
  429. tputs(dcc[idx].sock, OBUF, l);
  430. }
  431. void botnet_send_zapf_broad(int idx, char *a, char *b, char *c)
  432. {
  433. int l;
  434. if (tands > 0) {
  435. l = simple_sprintf(OBUF, "zb %s %s%s%s\n", a, b ? b : "", b ? " " : "", c);
  436. send_tand_but(idx, OBUF, l);
  437. #ifndef NO_OLD_BOTNET
  438. tandout_but(idx, "zapf-broad %s\n", OBUF + 3);
  439. #endif
  440. }
  441. }
  442. void botnet_send_motd(int idx, char *from, char *to)
  443. {
  444. int l;
  445. #ifndef NO_OLD_BOTNET
  446. if (b_numver(idx) < NEAT_BOTNET)
  447. l = simple_sprintf(OBUF, "motd %s %s\n", from, to);
  448. else
  449. #endif
  450. l = simple_sprintf(OBUF, "m %s %s\n", from, to);
  451. tputs(dcc[idx].sock, OBUF, l);
  452. }
  453. void botnet_send_filereject(int idx, char *path, char *from, char *reason)
  454. {
  455. int l;
  456. #ifndef NO_OLD_BOTNET
  457. if (b_numver(idx) < NEAT_BOTNET)
  458. l = simple_sprintf(OBUF, "filereject %s %s %s\n", path, from, reason);
  459. else
  460. #endif
  461. l = simple_sprintf(OBUF, "f! %s %s %s\n", path, from, reason);
  462. tputs(dcc[idx].sock, OBUF, l);
  463. }
  464. void botnet_send_filesend(int idx, char *path, char *from, char *data)
  465. {
  466. int l;
  467. #ifndef NO_OLD_BOTNET
  468. if (b_numver(idx) < NEAT_BOTNET)
  469. l = simple_sprintf(OBUF, "filesend %s %s %s\n", path, from, data);
  470. else
  471. #endif
  472. l = simple_sprintf(OBUF, "fs %s %s %s\n", path, from, data);
  473. tputs(dcc[idx].sock, OBUF, l);
  474. }
  475. void botnet_send_filereq(int idx, char *from, char *bot, char *path)
  476. {
  477. int l;
  478. #ifndef NO_OLD_BOTNET
  479. if (b_numver(idx) < NEAT_BOTNET)
  480. l = simple_sprintf(OBUF, "filereq %s %s:%s\n", from, bot, path);
  481. else
  482. #endif
  483. l = simple_sprintf(OBUF, "fr %s %s:%s\n", from, bot, path);
  484. tputs(dcc[idx].sock, OBUF, l);
  485. }
  486. void botnet_send_idle(int idx, char *bot, int sock, int idle, char *away)
  487. {
  488. int l;
  489. if (tands > 0) {
  490. l = simple_sprintf(OBUF, "i %s %D %D %s\n", bot, sock, idle,
  491. away ? away : "");
  492. send_tand_but(idx, OBUF, -l);
  493. #ifndef NO_OLD_BOTNET
  494. if (away && away[0])
  495. tandout_but(idx, "away %s %d %s\n", bot, sock, away);
  496. tandout_but(idx, "idle %s %d %d\n", bot, sock, idle);
  497. #endif
  498. }
  499. }
  500. void botnet_send_away(int idx, char *bot, int sock,
  501. char *msg, int linking)
  502. {
  503. int l;
  504. if (tands > 0) {
  505. l = simple_sprintf(OBUF, "aw %s%s %D %s\n",
  506. ((idx >= 0) && linking) ? "!" : "",
  507. bot, sock, msg ? msg : "");
  508. send_tand_but(idx, OBUF, -l);
  509. #ifndef NO_OLD_BOTNET
  510. if (msg) {
  511. if (idx < 0) {
  512. tandout_but(idx, "chan %s %d %s is now away: %s.\n", bot,
  513. dcc[linking].u.chat->channel, dcc[linking].nick,
  514. msg);
  515. } else if ((b_numver(idx) >= NEAT_BOTNET)) {
  516. int partyidx = getparty(bot, sock);
  517. if (partyidx >= 0)
  518. tandout_but(idx, "chan %s %d %s %s: %s.\n", bot,
  519. party[partyidx].chan, party[partyidx].nick,
  520. NET_AWAY, msg);
  521. }
  522. tandout_but(idx, "away %s %d %s\n", bot, sock, msg);
  523. } else {
  524. if (idx < 0) {
  525. tandout_but(idx, "chan %s %d %s %s.\n", bot,
  526. dcc[linking].u.chat->channel, dcc[linking].nick,
  527. NET_UNAWAY);
  528. } else if (b_numver(idx) >= NEAT_BOTNET) {
  529. int partyidx = getparty(bot, sock);
  530. if (partyidx >= 0)
  531. tandout_but(idx, "chan %s %d %s %s.\n", bot,
  532. party[partyidx].chan, party[partyidx].nick,
  533. NET_UNAWAY);
  534. }
  535. tandout_but(idx, "unaway %s %d\n", bot, sock);
  536. }
  537. #endif
  538. }
  539. }
  540. void botnet_send_join_idx(int useridx, int oldchan)
  541. {
  542. int l;
  543. if (tands > 0) {
  544. l = simple_sprintf(OBUF, "j %s %s %D %c%D %s\n",
  545. botnetnick, dcc[useridx].nick,
  546. dcc[useridx].u.chat->channel, geticon(useridx),
  547. dcc[useridx].sock, dcc[useridx].host);
  548. send_tand_but(-1, OBUF, -l);
  549. #ifndef NO_OLD_BOTNET
  550. tandout_but(-1, "join %s %s %d %c%d %s\n", botnetnick,
  551. dcc[useridx].nick, dcc[useridx].u.chat->channel,
  552. geticon(useridx), dcc[useridx].sock, dcc[useridx].host);
  553. tandout_but(-1, "chan %s %d %s %s %s.\n",
  554. botnetnick, dcc[useridx].u.chat->channel,
  555. dcc[useridx].nick, NET_JOINEDTHE,
  556. dcc[useridx].u.chat->channel ? "channel" : "party line");
  557. if ((oldchan >= 0) && (oldchan < GLOBAL_CHANS)) {
  558. tandout_but(-1, "chan %s %d %s %s %s.\n",
  559. botnetnick, oldchan,
  560. dcc[useridx].nick, NET_LEFTTHE,
  561. oldchan ? "channel" : "party line");
  562. }
  563. #endif
  564. }
  565. }
  566. void botnet_send_join_party(int idx, int linking, int useridx, int oldchan)
  567. {
  568. int l;
  569. if (tands > 0) {
  570. l = simple_sprintf(OBUF, "j %s%s %s %D %c%D %s\n", linking ? "!" : "",
  571. party[useridx].bot, party[useridx].nick,
  572. party[useridx].chan, party[useridx].flag,
  573. party[useridx].sock,
  574. party[useridx].from ? party[useridx].from : "");
  575. send_tand_but(idx, OBUF, -l);
  576. #ifndef NO_OLD_BOTNET
  577. tandout_but(idx, "join %s %s %d %c%d %s\n", party[useridx].bot,
  578. party[useridx].nick, party[useridx].chan,
  579. party[useridx].flag, party[useridx].sock,
  580. party[useridx].from ? party[useridx].from : "");
  581. if ((idx < 0) || (!linking && (b_numver(idx) >= NEAT_BOTNET))) {
  582. tandout_but(idx, "chan %s %d %s %s %s.\n",
  583. party[useridx].bot, party[useridx].chan,
  584. party[useridx].nick, NET_JOINEDTHE,
  585. party[useridx].chan ? "channel" : "party line");
  586. }
  587. if ((oldchan >= 0) && (oldchan < GLOBAL_CHANS) &&
  588. ((idx < 0) || (b_numver(idx) >= NEAT_BOTNET))) {
  589. tandout_but(idx, "chan %s %d %s %s %s.\n",
  590. party[useridx].bot, oldchan, party[useridx].nick,
  591. NET_LEFTTHE,
  592. party[useridx].chan ? "channel" : "party line");
  593. }
  594. #endif
  595. }
  596. }
  597. void botnet_send_part_idx(int useridx, char *reason)
  598. {
  599. int l = simple_sprintf(OBUF, "pt %s %s %D %s\n", botnetnick,
  600. dcc[useridx].nick, dcc[useridx].sock,
  601. reason ? reason : "");
  602. if (tands > 0) {
  603. send_tand_but(-1, OBUF, -l);
  604. #ifndef NO_OLD_BOTNET
  605. tandout_but(-1, "part %s %s %d\n", botnetnick,
  606. dcc[useridx].nick, dcc[useridx].sock);
  607. tandout_but(-1, "chan %s %d %s has left the %s%s%s.\n",
  608. botnetnick, dcc[useridx].u.chat->channel,
  609. dcc[useridx].nick,
  610. dcc[useridx].u.chat->channel ? "channel" : "party line",
  611. reason ? ": " : "", reason ? reason : "");
  612. #endif
  613. }
  614. }
  615. void botnet_send_part_party(int idx, int partyidx, char *reason,
  616. int silent)
  617. {
  618. int l;
  619. if (tands > 0) {
  620. l = simple_sprintf(OBUF, "pt %s%s %s %D %s\n",
  621. silent ? "!" : "", party[partyidx].bot,
  622. party[partyidx].nick, party[partyidx].sock,
  623. reason ? reason : "");
  624. send_tand_but(idx, OBUF, -l);
  625. #ifndef NO_OLD_BOTNET
  626. tandout_but(idx, "part %s %s %d\n", party[partyidx].bot,
  627. party[partyidx].nick, party[partyidx].sock);
  628. if (((idx < 0) || (b_numver(idx) >= NEAT_BOTNET)) && !silent) {
  629. tandout_but(idx, "chan %s %d %s has left the %s%s%s.\n",
  630. party[partyidx].bot, party[partyidx].chan,
  631. party[partyidx].nick,
  632. party[partyidx].chan ? "channel" : "party line",
  633. reason ? ": " : "", reason ? reason : "");
  634. }
  635. #endif
  636. }
  637. }
  638. void botnet_send_nkch(int useridx, char *oldnick)
  639. {
  640. int l;
  641. if (tands > 0) {
  642. l = simple_sprintf(OBUF, "nc %s %D %s\n", botnetnick,
  643. dcc[useridx].sock, dcc[useridx].nick);
  644. send_tand_but(-1, OBUF, -l);
  645. #ifndef NO_OLD_BOTNET
  646. tandout_but(-1, "part %s %s %d\n", botnetnick,
  647. dcc[useridx].nick, dcc[useridx].sock);
  648. tandout_but(-1, "join %s %s %d %c%d %s\n", botnetnick,
  649. dcc[useridx].nick, dcc[useridx].u.chat->channel,
  650. geticon(useridx), dcc[useridx].sock, dcc[useridx].host);
  651. tandout_but(-1, "chan %s %d %s: %s -> %s.\n",
  652. botnetnick, dcc[useridx].u.chat->channel,
  653. oldnick, NET_NICKCHANGE, dcc[useridx].nick);
  654. #endif
  655. }
  656. }
  657. void botnet_send_nkch_part(int butidx, int useridx, char *oldnick)
  658. {
  659. int l;
  660. if (tands > 0) {
  661. l = simple_sprintf(OBUF, "nc %s %D %s\n", party[useridx].bot,
  662. party[useridx].sock, party[useridx].nick);
  663. send_tand_but(butidx, OBUF, -l);
  664. #ifndef NO_OLD_BOTNET
  665. tandout_but(butidx, "part %s %s %d\n", party[useridx].bot,
  666. party[useridx].nick, party[useridx].sock);
  667. tandout_but(butidx, "join %s %s %d %c%d %s\n", party[useridx].bot,
  668. party[useridx].nick, party[useridx].chan,
  669. party[useridx].flag, party[useridx].sock,
  670. party[useridx].from ? party[useridx].from : "");
  671. tandout_but(butidx, "chan %s %d %s : %s -> %s.\n",
  672. party[useridx].bot, party[useridx].chan,
  673. NET_NICKCHANGE,
  674. oldnick, party[useridx].nick);
  675. #endif
  676. }
  677. }
  678. /* This part of add_note is more relevant to the botnet than
  679. * to the notes file
  680. */
  681. int add_note(char *to, char *from, char *msg, int idx, int echo)
  682. {
  683. int status, i, iaway, sock;
  684. char *p, botf[81], ss[81], ssf[81];
  685. struct userrec *u;
  686. if (strlen(msg) > 450)
  687. msg[450] = 0; /* Notes have a limit */
  688. /* note length + PRIVMSG header + nickname + date must be <512 */
  689. p = strchr(to, '@');
  690. if (p != NULL) { /* Cross-bot note */
  691. char x[21];
  692. *p = 0;
  693. strncpy(x, to, 20);
  694. x[20] = 0;
  695. *p = '@';
  696. p++;
  697. if (!egg_strcasecmp(p, botnetnick)) /* To me?? */
  698. return add_note(x, from, msg, idx, echo); /* Start over, dimwit. */
  699. if (egg_strcasecmp(from, botnetnick)) {
  700. if (strlen(from) > 40)
  701. from[40] = 0;
  702. if (strchr(from, '@')) {
  703. strcpy(botf, from);
  704. } else
  705. sprintf(botf, "%s@%s", from, botnetnick);
  706. } else
  707. strcpy(botf, botnetnick);
  708. i = nextbot(p);
  709. if (i < 0) {
  710. if (idx >= 0)
  711. dprintf(idx, BOT_NOTHERE);
  712. return NOTE_ERROR;
  713. }
  714. if ((idx >= 0) && (echo))
  715. dprintf(idx, "-> %s@%s: %s\n", x, p, msg);
  716. if (idx >= 0) {
  717. sprintf(ssf, "%lu:%s", dcc[idx].sock, botf);
  718. botnet_send_priv(i, ssf, x, p, "%s", msg);
  719. } else
  720. botnet_send_priv(i, botf, x, p, "%s", msg);
  721. return NOTE_OK; /* Forwarded to the right bot */
  722. }
  723. /* Might be form "sock:nick" */
  724. splitc(ssf, from, ':');
  725. rmspace(ssf);
  726. splitc(ss, to, ':');
  727. rmspace(ss);
  728. if (!ss[0])
  729. sock = (-1);
  730. else
  731. sock = atoi(ss);
  732. /* Don't process if there's a note binding for it */
  733. if (idx != (-2)) { /* Notes from bots don't trigger it */
  734. if (check_tcl_note(from, to, msg)) {
  735. if ((idx >= 0) && (echo))
  736. dprintf(idx, "-> %s: %s\n", to, msg);
  737. return NOTE_TCL;
  738. }
  739. }
  740. if (!(u = get_user_by_handle(userlist, to))) {
  741. if (idx >= 0)
  742. dprintf(idx, USERF_UNKNOWN);
  743. return NOTE_ERROR;
  744. }
  745. if (is_bot(u)) {
  746. if (idx >= 0)
  747. dprintf(idx, BOT_NONOTES);
  748. return NOTE_ERROR;
  749. }
  750. if (match_noterej(u, from)) {
  751. if (idx >= 0)
  752. dprintf(idx, "%s %s\n", u->handle, "rejected your note.");
  753. return NOTE_REJECT;
  754. }
  755. status = NOTE_STORED;
  756. iaway = 0;
  757. /* Online right now? */
  758. for (i = 0; i < dcc_total; i++) {
  759. if ((dcc[i].type->flags & DCT_GETNOTES) &&
  760. ((sock == (-1)) || (sock == dcc[i].sock)) &&
  761. (!egg_strcasecmp(dcc[i].nick, to))) {
  762. int aok = 1;
  763. if (dcc[i].type == &DCC_CHAT)
  764. if ((dcc[i].u.chat->away != NULL) &&
  765. (idx != (-2))) {
  766. /* Only check away if it's not from a bot */
  767. aok = 0;
  768. if (idx >= 0)
  769. dprintf(idx, "%s %s: %s\n", dcc[i].nick, BOT_USERAWAY,
  770. dcc[i].u.chat->away);
  771. if (!iaway)
  772. iaway = i;
  773. status = NOTE_AWAY;
  774. }
  775. if (aok) {
  776. char *p, *fr = from;
  777. int l = 0;
  778. char work[1024];
  779. while ((*msg == '<') || (*msg == '>')) {
  780. p = newsplit(&msg);
  781. if (*p == '<')
  782. l += simple_sprintf(work + l, "via %s, ", p + 1);
  783. else if (*from == '@')
  784. fr = p + 1;
  785. }
  786. if (idx == -2 || (!egg_strcasecmp(from, botnetnick)))
  787. dprintf(i, "*** [%s] %s%s\n", fr, l ? work : "", msg);
  788. else
  789. dprintf(i, "%cNote [%s]: %s%s\n", 7, fr, l ? work : "", msg);
  790. if ((idx >= 0) && (echo))
  791. dprintf(idx, "-> %s: %s\n", to, msg);
  792. return NOTE_OK;
  793. }
  794. }
  795. }
  796. if (idx == (-2))
  797. return NOTE_OK; /* Error msg from a tandembot: don't store */
  798. /* Call store note here */
  799. Tcl_SetVar(interp, "_from", from, 0);
  800. Tcl_SetVar(interp, "_to", to, 0);
  801. Tcl_SetVar(interp, "_data", msg, 0);
  802. simple_sprintf(ss, "%d", dcc[idx].sock);
  803. Tcl_SetVar(interp, "_idx", ss, 0);
  804. if (Tcl_VarEval(interp, "storenote", " $_from $_to $_data $_idx", NULL) == TCL_OK) {
  805. if (interp->result && interp->result[0])
  806. status = NOTE_FWD;
  807. if (status == NOTE_AWAY) {
  808. /* User is away in all sessions -- just notify the user that a
  809. * message arrived and was stored. (only oldest session is notified.)
  810. */
  811. dprintf(iaway, "*** %s.\n", BOT_NOTEARRIVED);
  812. }
  813. return status;
  814. }
  815. return NOTE_ERROR;
  816. }