botmsg.c 23 KB

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