ctcp.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. /*
  2. * ctcp.c -- part of ctcp.mod
  3. * all the ctcp handling (except DCC, it's special ;)
  4. *
  5. */
  6. #define MODULE_NAME "ctcp"
  7. #define MAKING_CTCP
  8. #include "ctcp.h"
  9. #include "src/mod/module.h"
  10. #ifdef LEAF
  11. #include "server.mod/server.h"
  12. #include <netinet/in.h>
  13. #include <arpa/inet.h>
  14. #include <sys/utsname.h>
  15. #include <pwd.h>
  16. #include <ctype.h>
  17. static Function *global = NULL, *server_funcs = NULL;
  18. #else /* !LEAF */
  19. static Function *global = NULL;
  20. #endif /* LEAF */
  21. #define CLOAK_COUNT 10 /* The number of scripts currently existing */
  22. #define CLOAK_PLAIN 1 /* This is your plain bitchx client behaviour */
  23. #define CLOAK_CRACKROCK 2
  24. #define CLOAK_NEONAPPLE 3
  25. #define CLOAK_TUNNELVISION 4
  26. #define CLOAK_ARGON 5
  27. #define CLOAK_EVOLVER 6
  28. #define CLOAK_PREVAIL 7
  29. #define CLOAK_CYPRESS 8 /* Now with full theme and customization support */
  30. #define CLOAK_MIRC 9
  31. int cloak_script = CLOAK_PLAIN;
  32. #ifdef LEAF
  33. #ifdef S_AUTOAWAY
  34. #define AVGAWAYTIME 60
  35. #define AVGHERETIME 5
  36. #endif /* S_AUTOAWAY */
  37. int cloak_awaytime = 0;
  38. int cloak_heretime = 0;
  39. int listen_time = 0;
  40. char cloak_bxver[10];
  41. char cloak_os[20];
  42. char cloak_osver[100];
  43. char cloak_host[161];
  44. char ctcpversion[400];
  45. char ctcpuserinfo[400];
  46. char autoaway[100];
  47. char *strtolower(char *s)
  48. {
  49. char *p,
  50. *p2 = nmalloc(strlen(s) + 1);
  51. strcpy(p2, s);
  52. p = p2;
  53. while (*p) {
  54. *p = tolower(*p);
  55. p++;
  56. }
  57. return p2;
  58. }
  59. void scriptchanged()
  60. {
  61. char tmp[200],
  62. *p;
  63. switch (cloak_script) {
  64. case CLOAK_PLAIN:
  65. sprintf(ctcpversion, STR("\002BitchX-%s\002 by panasync - %s %s : \002Keep it to yourself!\002"), cloak_bxver, cloak_os, cloak_osver);
  66. strcpy(ctcpuserinfo, "");
  67. strcpy(autoaway, STR("Auto-Away after 10 mins"));
  68. strcpy(kickprefix, "");
  69. strcpy(bankickprefix, "");
  70. break;
  71. case CLOAK_CRACKROCK:
  72. sprintf(ctcpversion, STR("BitchX-%s\002/\002%s %s:(\002c\002)\037rackrock\037/\002b\002X \037[\0373.0.1á9\037]\037 :\002 Keep it to yourself!\002"), cloak_bxver, cloak_os, cloak_osver);
  73. strcpy(ctcpuserinfo, STR("crack addict, help me."));
  74. strcpy(autoaway, STR("automatically dead"));
  75. strcpy(kickprefix, STR("\002c\002/\037k\037: "));
  76. strcpy(bankickprefix, STR("\002c\002/\037kb\037: "));
  77. break;
  78. case CLOAK_NEONAPPLE:
  79. sprintf(tmp, STR("%s %s"), cloak_os, cloak_osver);
  80. p = strtolower(tmp);
  81. sprintf(ctcpversion, STR("bitchx-%s\037(\037%s\037):\037 \002n\002eon\037a\037ppl\002e\002\037/\037\002v\0020\037.\03714i : \002d\002ont you wish you had it\037?\037"), cloak_bxver, p);
  82. nfree(p);
  83. strcpy(ctcpuserinfo, STR("neon apple"));
  84. strcpy(autoaway, STR("automatically away after 10 mins \037(\037\002n\002/\037a)\037"));
  85. strcpy(kickprefix, STR("\037[na\002(\037k\037)\002]\037 "));
  86. strcpy(bankickprefix, "");
  87. break;
  88. case CLOAK_TUNNELVISION:
  89. strcpy(tmp, cloak_bxver);
  90. p = tmp;
  91. p += strlen(tmp) - 1;
  92. p[1] = p[0];
  93. p[0] = '\037';
  94. p[2] = '\037';
  95. p[3] = 0;
  96. sprintf(ctcpversion, STR("\002b\002itchx-%s :tunnel\002vision\002/\0371.2\037"), tmp);
  97. strcpy(ctcpuserinfo, "");
  98. strcpy(autoaway, STR("auto-gone"));
  99. strcpy(kickprefix, "");
  100. strcpy(bankickprefix, "");
  101. break;
  102. case CLOAK_ARGON:
  103. sprintf(ctcpversion, STR(".\037.(\037argon\002/\0021g\037)\037 \002:\002bitchx-%s"), cloak_bxver);
  104. strcpy(ctcpuserinfo, "");
  105. strcpy(autoaway, STR("\037(\037ar\037)\037 auto-away \037(\03710m\037)\037"));
  106. strcpy(kickprefix, STR("\037(\037ar\037)\037 "));
  107. strcpy(bankickprefix, STR("\037(\037ar\037)\037 "));
  108. break;
  109. case CLOAK_EVOLVER:
  110. sprintf(ctcpversion, STR("\037evolver\037(\00202x9\002)\037: bitchx\037(\002%s\002) \037í\037 %s\002/\002%s : eye yam pheerable now!"), cloak_bxver, cloak_os, cloak_osver);
  111. strcpy(ctcpuserinfo, "");
  112. strcpy(autoaway, STR("[\037\002i\002dle for \037[\03710 minutes\037]]"));
  113. strcpy(kickprefix, STR("\037ev\002!\002k\037 "));
  114. strcpy(bankickprefix, STR("\037ev\002!\002bk\037 "));
  115. break;
  116. case CLOAK_PREVAIL:
  117. sprintf(ctcpversion, STR("%s\037!\037%s bitchx-%s \002-\002 prevail\037[\0370123\037]\037 :down with people"), cloak_os, cloak_osver, cloak_bxver);
  118. strcpy(ctcpuserinfo, botrealname);
  119. strcpy(autoaway, STR("idle 10 minutes \037-\037 gone\037!\037"));
  120. strcpy(kickprefix, STR("\037[\037pv\037!\037k\037]\037 "));
  121. strcpy(bankickprefix, STR("\037[\037pv\037!\037bk\037]\037 "));
  122. break;
  123. case CLOAK_MIRC:
  124. {
  125. char mircver[4];
  126. switch (random() % 7) {
  127. case 0:
  128. strcpy(mircver, "6.01");
  129. break;
  130. case 1:
  131. strcpy(mircver, "6.02");
  132. break;
  133. case 2:
  134. strcpy(mircver, "6.03");
  135. break;
  136. case 3:
  137. strcpy(mircver, "6.1");
  138. break;
  139. case 4:
  140. strcpy(mircver, "5.91");
  141. break;
  142. case 5:
  143. strcpy(mircver, "6.11");
  144. break;
  145. case 6:
  146. strcpy(mircver, "6.12");
  147. break;
  148. case 7:
  149. strcpy(mircver, "6.14");
  150. break;
  151. default:
  152. strcpy(mircver, "");
  153. }
  154. sprintf(ctcpversion, STR("mIRC v%s Khaled Mardam-Bey"), mircver);
  155. strcpy(ctcpuserinfo, botrealname);
  156. strcpy(autoaway, STR("auto-away after 10 minutes"));
  157. strcpy(kickprefix, "");
  158. strcpy(bankickprefix, "");
  159. break;
  160. }
  161. case CLOAK_CYPRESS:
  162. {
  163. char theme[30];
  164. switch (random() % 25) { /* 0-19 = script, 20-24 = plain */
  165. case 0:
  166. strcpy(theme, STR(" \037.\037.\002BX\002"));
  167. break;
  168. case 1:
  169. strcpy(theme, STR(" \037.\037.chl\037o\037rine"));
  170. break;
  171. case 2:
  172. strcpy(theme, STR(" \037.\037.\037<\037c\002x\002\037>\037"));
  173. break;
  174. case 3:
  175. strcpy(theme, STR(" \037.\037.supercyan"));
  176. break;
  177. case 4:
  178. strcpy(theme, STR(" \037.\037.\037c\037yan\002i\002\002\037z\037\002\037e\037d"));
  179. break;
  180. case 5:
  181. strcpy(theme, STR(" \037.\037.delusion"));
  182. break;
  183. case 6:
  184. strcpy(theme, STR(" \037.\037.\002e\002mbryonic"));
  185. break;
  186. case 7:
  187. strcpy(theme, STR(" \037.\037.e\002x\002tra\037.\037terrestr\037i\037al"));
  188. break;
  189. case 8:
  190. strcpy(theme, STR(" \037.\037.\002f\002ad\037e\037d"));
  191. break;
  192. case 9:
  193. strcpy(theme, STR(" \037.\037.fo\037c\037us"));
  194. break;
  195. case 10:
  196. strcpy(theme, STR(" \037.\037.\002h\002ade\037s\037"));
  197. break;
  198. case 11:
  199. strcpy(theme, STR(" \037.\037.hellbent\037.\037"));
  200. break;
  201. case 12:
  202. strcpy(theme, STR(" \037.\037.illusi\037o\037n"));
  203. break;
  204. case 13:
  205. strcpy(theme, STR(" \037.\037.\037j\037ungl\037e\037"));
  206. break;
  207. case 14:
  208. strcpy(theme, STR(" \037.\037.\002l\002abry\037i\037nth"));
  209. break;
  210. case 15:
  211. strcpy(theme, STR(" \037.\037.nightblue"));
  212. break;
  213. case 16:
  214. strcpy(theme, STR(" \037.\037.\037o\037bli\037v\037io\037n\037"));
  215. break;
  216. case 17:
  217. strcpy(theme, STR(" \037.\037.ph\002a\002ze"));
  218. break;
  219. case 18:
  220. strcpy(theme, STR(" \037.\037.sphere"));
  221. break;
  222. case 19:
  223. strcpy(theme, STR(" \037.\037.zip"));
  224. break;
  225. default:
  226. strcpy(theme, STR(""));
  227. break;
  228. }
  229. switch (random() % 16) {
  230. case 0:
  231. sprintf(ctcpversion, STR("bitchx\037-\037%s \037/\037 cypress\037.\03701i%s"), cloak_bxver, theme);
  232. break;
  233. case 1:
  234. sprintf(ctcpversion, STR("cypress\037.\03701i%s \037/\037 bitchx\037-\037%s"), theme, cloak_bxver);
  235. break;
  236. case 2:
  237. sprintf(tmp, STR("%s %s"), cloak_os, cloak_osver);
  238. p = strtolower(tmp);
  239. sprintf(ctcpversion, STR("cypress\037.\03701i%s %s\037(\037%s\037)\037 bitchx\037-\037%s)"), theme, p, cloak_host, cloak_bxver);
  240. nfree(p);
  241. break;
  242. case 3:
  243. sprintf(tmp, STR("%s %s"), cloak_os, cloak_osver);
  244. p = strtolower(tmp);
  245. sprintf(ctcpversion, STR("bitchx\037-\037%s %s\037(\037%s\037)\037 cypress\037.\03701i%s"), cloak_bxver, p, cloak_host, theme);
  246. nfree(p);
  247. break;
  248. case 4:
  249. sprintf(ctcpversion, STR("%s\002/\002%s: BitchX-%s \002[\002cypress\002]\002 v01i%s"), cloak_os, cloak_osver, cloak_bxver, theme);
  250. break;
  251. case 5:
  252. p = replace(cloak_osver, ".", "\037.\037");
  253. sprintf(tmp, STR("%s %s"), cloak_os, p);
  254. p = strtolower(tmp);
  255. sprintf(ctcpversion, STR("\037.\037.cypress\037.\03701i%s %s\037(\037%s\037)\037 bitchx\037/\037%s"),theme, p, cloak_host, cloak_bxver);
  256. nfree(p);
  257. break;
  258. case 6:
  259. p = replace(cloak_osver, ".", "\037.\037");
  260. sprintf(tmp, STR("%s %s"), cloak_os, p);
  261. p = strtolower(tmp);
  262. sprintf(ctcpversion, STR("cypress\002.\00201i%s\037(\037bitchx\002.\002%s\037)\037\002.\002. %s\037(\037%s\037)\037"),theme, cloak_bxver, p, cloak_host);
  263. nfree(p);
  264. break;
  265. case 7:
  266. p = replace(cloak_osver, ".", "\037.\037");
  267. sprintf(tmp, STR("%s %s"), cloak_os, p);
  268. p = strtolower(tmp);
  269. sprintf(ctcpversion, STR("\037.\037.cypress\037.\03701i%s - bitchx\037.\037%s\002/\002%s"), theme, cloak_bxver, p);
  270. nfree(p);
  271. break;
  272. case 8:
  273. sprintf(ctcpversion, STR("\002BitchX-%s\002 by panasync \002-\002 %s %s"), cloak_bxver, cloak_os, cloak_osver);
  274. break;
  275. case 9:
  276. sprintf(ctcpversion, STR("\037[\037cypress\002/\00201i\037]\037 - %s \037[\037bx\002/\002%s\037]\037"), theme, cloak_bxver);
  277. break;
  278. case 10:
  279. sprintf(ctcpversion, STR("\037[\037\002b\002itchx\002.\002%s\037]\037 \002+\002 \037[\037cypress\002.\00201i\037]\037 %s"),cloak_bxver, theme);
  280. break;
  281. case 11:
  282. sprintf(ctcpversion, STR("\037[\037BitchX\002/\002%s\037(\037cypress\002/\00201i\037)]\037 %s"), cloak_bxver, theme);
  283. break;
  284. case 12:
  285. p = strtolower(cloak_os);
  286. sprintf(ctcpversion, STR("bitchx\037/\037%s %s %s \037(\037cypress\037/\03701i\037)\037 %s"), cloak_bxver, p, cloak_osver, theme);
  287. nfree(p);
  288. break;
  289. case 13:
  290. sprintf(ctcpversion, STR("\037.\037.cypress\037/\03701i\037!\037bitchx\037/\037%s\037.\037.%s"), cloak_bxver, theme);
  291. break;
  292. case 14:
  293. p = strtolower(cloak_bxver);
  294. sprintf(ctcpversion, STR("cypress\002\037.\037\002\037.\03701i\002/\002bitchx\037.\037\002\037.\037\002%s%s"), p, theme);
  295. nfree(p);
  296. break;
  297. case 15:
  298. p = strtolower(cloak_bxver);
  299. sprintf(ctcpversion, STR("cypress\037.\03701i\037/\037bx%s \037(\037%s\037)\037"), p, theme);
  300. nfree(p);
  301. break;
  302. }
  303. strcpy(ctcpuserinfo, STR(""));
  304. strcpy(autoaway, STR("autoaway after 40 min"));
  305. strcpy(kickprefix, STR("\002.\002.\037(\037\002c\002yp\002/\002k\037)\037 "));
  306. strcpy(bankickprefix, STR("\002.\002.\037(\037\002c\002yp\002/\002bk\037)\037 "));
  307. break;
  308. }
  309. }
  310. }
  311. #ifdef S_AUTOAWAY
  312. void sendaway()
  313. {
  314. char awtime[20];
  315. int hrs,
  316. min,
  317. sec,
  318. gt;
  319. gt = time(NULL) - cloak_awaytime;
  320. hrs = gt / 3600;
  321. min = (gt % 3600) / 60;
  322. sec = gt % 60;
  323. switch (cloak_script) {
  324. case CLOAK_PLAIN:
  325. dprintf(DP_HELP, STR("AWAY :is away: (%s) [\002BX\002-MsgLog Off]\n"), autoaway);
  326. break;
  327. case CLOAK_MIRC:
  328. dprintf(DP_HELP, STR("AWAY :is away: (%s)\n"), autoaway);
  329. break;
  330. case CLOAK_CRACKROCK:
  331. if (hrs)
  332. sprintf(awtime, STR("%dh %dm %ds"), hrs, min, sec);
  333. else if (min)
  334. sprintf(awtime, STR("%dm %ds"), min, sec);
  335. else
  336. sprintf(awtime, STR("%ds"), sec);
  337. dprintf(DP_HELP, STR("AWAY :%s\002\037[\002%s\002]\037\002\n"), autoaway, awtime);
  338. break;
  339. case CLOAK_TUNNELVISION:
  340. if (hrs)
  341. sprintf(awtime, STR("%dh%dm%ds"), hrs, min, sec);
  342. else if (min)
  343. sprintf(awtime, STR("%dm%ds"), min, sec);
  344. else
  345. sprintf(awtime, STR("%ds"), sec);
  346. dprintf(DP_HELP, STR("AWAY :%s \037(\037%s\037)\037\n"), autoaway, awtime);
  347. break;
  348. case CLOAK_ARGON:
  349. if (hrs)
  350. sprintf(awtime, STR("%dh%dm%ds"), hrs, min, sec);
  351. else if (min)
  352. sprintf(awtime, STR("%dm%ds"), min, sec);
  353. else
  354. sprintf(awtime, STR("%ds"), sec);
  355. dprintf(DP_HELP, STR("AWAY :%s .\002.\002\037(\037%s\037)\037\n"), autoaway, awtime);
  356. break;
  357. case CLOAK_EVOLVER:
  358. if (hrs)
  359. sprintf(awtime, STR("%dh %dm %ds"), hrs, min, sec);
  360. else if (min)
  361. sprintf(awtime, STR("%dm %ds"), min, sec);
  362. else
  363. sprintf(awtime, STR("%ds"), sec);
  364. dprintf(DP_HELP, STR("AWAY :away\037: %s (\037l\002:\002off\037,\037 p\002:\002off\037)\037 \037[\037gone\002:\002%s\037]\037\n"), autoaway, awtime);
  365. break;
  366. case CLOAK_PREVAIL:
  367. if (hrs)
  368. sprintf(awtime, STR("%dh%dm%ds"), hrs, min, sec);
  369. else if (min)
  370. sprintf(awtime, STR("%dm%ds"), min, sec);
  371. else
  372. sprintf(awtime, STR("%ds"), sec);
  373. dprintf(DP_HELP, STR("AWAY :%s %s\n"), autoaway, awtime);
  374. break;
  375. case CLOAK_CYPRESS:
  376. dprintf(DP_HELP, STR("AWAY :is gone\037.\037. %s \037.\037.\037[\037\002c\002yp\037(\037l\002/\002off\002.\002p\002/\002off)]\n"), autoaway);
  377. break;
  378. }
  379. }
  380. #endif /* S_AUTOAWAY */
  381. static void ctcp_minutely()
  382. {
  383. int i;
  384. #ifdef S_AUTOAWAY
  385. int n;
  386. if ((cloak_awaytime == 0) && (cloak_heretime == 0)) {
  387. cloak_heretime = time(NULL);
  388. dprintf(DP_HELP, STR("AWAY :\n"));
  389. return;
  390. }
  391. n = random();
  392. if (cloak_awaytime == 0) {
  393. if (!(n % AVGHERETIME)) {
  394. cloak_heretime = 0;
  395. cloak_awaytime = time(NULL) - 600 - random() % 60;
  396. sendaway();
  397. }
  398. } else {
  399. if (!(n % AVGAWAYTIME)) {
  400. cloak_awaytime = 0;
  401. cloak_heretime = time(NULL);
  402. dprintf(DP_HELP, STR("AWAY :\n"));
  403. } else
  404. sendaway();
  405. }
  406. #endif /* S_AUTOAWAY */
  407. if (listen_time <= 0) {
  408. for (i = 0; i < dcc_total; i++) {
  409. if ((dcc[i].type->flags & DCT_LISTEN) && (!strcmp(dcc[i].nick, "(telnet)") || !strcmp(dcc[i].nick, "(telnet6)"))) {
  410. putlog(LOG_DEBUG, "*", "Closing listening port %d %s", dcc[i].port, dcc[i].nick);
  411. killsock(dcc[i].sock);
  412. lostdcc(i);
  413. break;
  414. }
  415. }
  416. } else
  417. listen_time--;
  418. }
  419. static int ctcp_FINGER(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  420. {
  421. char *p;
  422. int idletime;
  423. struct passwd *pwd;
  424. if (cloak_awaytime)
  425. idletime = now - cloak_awaytime;
  426. else if (cloak_heretime)
  427. idletime = now - cloak_heretime;
  428. else
  429. idletime = 0;
  430. if (!(pwd = getpwuid(geteuid())))
  431. return 0;
  432. #ifndef GECOS_DELIMITER
  433. #define GECOS_DELIMITER ','
  434. #endif
  435. if ((p = strchr(pwd->pw_gecos, GECOS_DELIMITER)) != NULL)
  436. *p = 0;
  437. dprintf(DP_HELP, STR("NOTICE %s :\001%s %s (%s@%s) Idle %ld second%s\001\n"), nick, keyword, pwd->pw_gecos, pwd->pw_name, (char *) (strchr(botuserhost, '@') + 1), idletime, (idletime == 1) ? "" : "s");
  438. return 1;
  439. }
  440. static int ctcp_ECHO(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  441. {
  442. char reply[60];
  443. strncpyz(reply, text, sizeof(reply));
  444. dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, reply);
  445. return 1;
  446. }
  447. static int ctcp_PING(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  448. {
  449. if (strlen(text) <= 80) /* bitchx ignores > 80 */
  450. dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, text);
  451. return 1;
  452. }
  453. static int ctcp_VERSION(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  454. {
  455. char s[50] = "";
  456. if (cloak_script == CLOAK_CYPRESS) {
  457. switch (random() % 8) {
  458. case 0:
  459. strcpy(s, STR(" :should of put the glock down."));
  460. break;
  461. case 1:
  462. strcpy(s, STR(" :hot damn, I didn't want to kill a man."));
  463. break;
  464. case 2:
  465. strcpy(s, STR(" :check me and I'll check ya back."));
  466. break;
  467. case 3:
  468. strcpy(s, STR(" :put the blunt down just for a minute."));
  469. break;
  470. case 4:
  471. strcpy(s, STR(" :tried to jack me, my homie got shot."));
  472. break;
  473. case 5:
  474. strcpy(s, STR(" :insane in the membrane"));
  475. break;
  476. case 6:
  477. strcpy(s, STR(" :slow hits from the bong"));
  478. break;
  479. case 7:
  480. strcpy(s, STR(" :k\002-\002leet"));
  481. break;
  482. }
  483. }
  484. dprintf(DP_HELP, STR("NOTICE %s :\001%s %s%s\001\n"), nick, keyword, ctcpversion, s);
  485. //if mirc send second reply here..
  486. return 1;
  487. }
  488. static int ctcp_WHOAMI(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  489. {
  490. dprintf(DP_HELP, STR("NOTICE %s :\002BitchX\002: Access Denied\n"), nick);
  491. return 1;
  492. }
  493. static int ctcp_OP(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  494. {
  495. char chan[256],
  496. *p;
  497. if (text[0]) {
  498. strncpyz(chan, text, sizeof(chan));
  499. p = strchr(chan, ' ');
  500. if (p)
  501. *p = 0;
  502. dprintf(DP_HELP, STR("NOTICE %s :\002BitchX\002: I'm not on %s or I'm not opped\n"), nick, chan);
  503. }
  504. return 1;
  505. }
  506. static int ctcp_INVITE_UNBAN(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  507. {
  508. struct chanset_t *chan = chanset;
  509. char chname[256],
  510. *p;
  511. if (text[0] == '#') {
  512. strncpyz(chname, text, sizeof(chname));
  513. p = strchr(chname, ' ');
  514. if (p)
  515. *p = 0;
  516. while (chan) {
  517. if (chan->status & CHAN_ACTIVE) {
  518. if (!egg_strcasecmp(chan->name, chname)) {
  519. dprintf(DP_HELP, STR("NOTICE %s :\002BitchX\002: Access Denied\n"), nick);
  520. return 0;
  521. }
  522. }
  523. chan = chan->next;
  524. }
  525. dprintf(DP_HELP, STR("NOTICE %s :\002BitchX\002: I'm not on that channel\n"), nick);
  526. }
  527. return 1;
  528. }
  529. static int ctcp_USERINFO(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  530. {
  531. if (cloak_script == CLOAK_TUNNELVISION)
  532. strcpy(ctcpuserinfo, botname);
  533. else if (cloak_script == CLOAK_PREVAIL) {
  534. strcpy(ctcpuserinfo, botname);
  535. strcat(ctcpuserinfo, " ?");
  536. }
  537. dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, ctcpuserinfo);
  538. return 1;
  539. }
  540. static int ctcp_CLIENTINFO(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  541. {
  542. char buf[256];
  543. if (!text[0]) {
  544. strcpy(buf, STR("SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK UPTIME :Use CLIENTINFO <COMMAND> to get more specific information"));
  545. } else if (!egg_strcasecmp(text, STR("UNBAN")))
  546. strcpy(buf, STR("UNBAN unbans the person from channel"));
  547. else if (!egg_strcasecmp(text, STR("OPS")))
  548. strcpy(buf, STR("OPS ops the person if on userlist"));
  549. else if (!egg_strcasecmp(text, STR("ECHO")))
  550. strcpy(buf, STR("ECHO returns the arguments it receives"));
  551. else if (!egg_strcasecmp(text, STR("WHOAMI")))
  552. strcpy(buf, STR("WHOAMI user list information"));
  553. else if (!egg_strcasecmp(text, STR("INVITE")))
  554. strcpy(buf, STR("INVITE invite to channel specified"));
  555. else if (!egg_strcasecmp(text, STR("PING")))
  556. strcpy(buf, STR("PING returns the arguments it receives"));
  557. else if (!egg_strcasecmp(text, STR("UTC")))
  558. strcpy(buf, STR("UTC substitutes the local timezone"));
  559. else if (!egg_strcasecmp(text, STR("XDCC")))
  560. strcpy(buf, STR("XDCC checks cdcc info for you"));
  561. else if (!egg_strcasecmp(text, STR("BDCC")))
  562. strcpy(buf, STR("BDCC checks cdcc info for you"));
  563. else if (!egg_strcasecmp(text, STR("CDCC")))
  564. strcpy(buf, STR("CDCC checks cdcc info for you"));
  565. else if (!egg_strcasecmp(text, STR("DCC")))
  566. strcpy(buf, STR("DCC requests a direct_client_connection"));
  567. else if (!egg_strcasecmp(text, STR("ACTION")))
  568. strcpy(buf, STR("ACTION contains action descriptions for atmosphere"));
  569. else if (!egg_strcasecmp(text, STR("FINGER")))
  570. strcpy(buf, STR("FINGER shows real name, login name and idle time of user"));
  571. else if (!egg_strcasecmp(text, STR("ERRMSG")))
  572. strcpy(buf, STR("ERRMSG returns error messages"));
  573. else if (!egg_strcasecmp(text, STR("USERINFO")))
  574. strcpy(buf, STR("USERINFO returns user settable information"));
  575. else if (!egg_strcasecmp(text, STR("CLIENTINFO")))
  576. strcpy(buf, STR("CLIENTINFO gives information about available CTCP commands"));
  577. else if (!egg_strcasecmp(text, STR("SED")))
  578. strcpy(buf, STR("SED contains simple_encrypted_data"));
  579. else if (!egg_strcasecmp(text, "OP"))
  580. strcpy(buf, STR("OP ops the person if on userlist"));
  581. else if (!egg_strcasecmp(text, STR("VERSION")))
  582. strcpy(buf, STR("VERSION shows client type, version and environment"));
  583. else if (!egg_strcasecmp(text, STR("XLINK")))
  584. strcpy(buf, STR("XLINK x-filez rule"));
  585. else if (!egg_strcasecmp(text, STR("IDENT")))
  586. strcpy(buf, STR("IDENT change userhost of userlist"));
  587. else if (!egg_strcasecmp(text, STR("TIME")))
  588. strcpy(buf, STR("TIME tells you the time on the user's host"));
  589. else if (!egg_strcasecmp(text, STR("UPTIME")))
  590. strcpy(buf, STR("UPTIME my uptime"));
  591. else {
  592. dprintf(DP_HELP, STR("NOTICE %s :\001ERRMSG %s is not a valid function\001\n"), nick, text);
  593. return 0;
  594. }
  595. dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, buf);
  596. return 1;
  597. }
  598. static int ctcp_TIME(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  599. {
  600. char tms[81];
  601. strncpyz(tms, ctime(&now), sizeof(tms));
  602. dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, tms);
  603. return 1;
  604. }
  605. static int ctcp_CHAT(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
  606. {
  607. int i, ix = (-1);
  608. if (!ischanhub())
  609. return 0;
  610. if (u_pass_match(u, "-")) {
  611. simple_sprintf(ctcp_reply, "%s\001ERROR no password set\001", ctcp_reply);
  612. return 1;
  613. }
  614. for (i = 0; i < dcc_total; i++) {
  615. if ((dcc[i].type->flags & DCT_LISTEN) && (!strcmp(dcc[i].nick, "(telnet)")))
  616. ix = i;
  617. }
  618. if (dcc_total == max_dcc || (ix < 0 && (ix = listen_all(0, 0)) < 0))
  619. simple_sprintf(ctcp_reply, "%s\001ERROR no telnet port\001", ctcp_reply);
  620. else {
  621. if (listen_time <= 2)
  622. listen_time++;
  623. /* do me a favour and don't change this back to a CTCP reply,
  624. * CTCP replies are NOTICE's this has to be a PRIVMSG
  625. * -poptix 5/1/1997 */
  626. dprintf(DP_HELP, "PRIVMSG %s :\001DCC CHAT chat %lu %u\001\n", nick, iptolong(getmyip()), dcc[ix].port);
  627. }
  628. return 1;
  629. }
  630. static cmd_t myctcp[] =
  631. {
  632. {"CLIENTINFO", "", ctcp_CLIENTINFO, NULL},
  633. {"FINGER", "", ctcp_FINGER, NULL},
  634. {"WHOAMI", "", ctcp_WHOAMI, NULL},
  635. {"OP", "", ctcp_OP, NULL},
  636. {"OPS", "", ctcp_OP, NULL},
  637. {"INVITE", "", ctcp_INVITE_UNBAN, NULL},
  638. {"UNBAN", "", ctcp_INVITE_UNBAN, NULL},
  639. {"ERRMSG", "", ctcp_ECHO, NULL},
  640. {"USERINFO", "", ctcp_USERINFO, NULL},
  641. {"ECHO", "", ctcp_ECHO, NULL},
  642. {"VERSION", "", ctcp_VERSION, NULL},
  643. {"PING", "", ctcp_PING, NULL},
  644. {"TIME", "", ctcp_TIME, NULL},
  645. {"CHAT", "", ctcp_CHAT, NULL},
  646. {NULL, NULL, NULL, NULL}
  647. };
  648. #endif /* LEAF */
  649. void cloak_describe(struct cfg_entry *cfgent, int idx)
  650. {
  651. dprintf(idx, STR("cloak-script decides which BitchX script the bot cloaks. If set to 0, a random script will be cloaked.\n"));
  652. dprintf(idx, STR("Available: 1=plain bitchx, 2=crackrock, 3=neonapple, 4=tunnelvision, 5=argon, 6=evolver, 7=prevail 8=cypress 9=mIRC\n"));
  653. }
  654. void cloak_changed(struct cfg_entry *cfgent, char *oldval, int *valid)
  655. {
  656. char *p;
  657. int i;
  658. if (!(p = cfgent->ldata ? cfgent->ldata : cfgent->gdata))
  659. return;
  660. i = atoi(p);
  661. #ifdef LEAF
  662. if (i == 0)
  663. i = (random() % CLOAK_COUNT) + 1;
  664. #endif /* LEAF */
  665. if ((*valid = ((i >= 0) && (i <= CLOAK_COUNT))))
  666. cloak_script = i;
  667. #ifdef LEAF
  668. scriptchanged();
  669. #endif /* LEAF */
  670. }
  671. struct cfg_entry CFG_CLOAK_SCRIPT = {
  672. "cloak-script", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  673. cloak_changed, cloak_changed, cloak_describe
  674. };
  675. EXPORT_SCOPE char *ctcp_start();
  676. static Function ctcp_table[] =
  677. {
  678. (Function) ctcp_start,
  679. (Function) NULL,
  680. (Function) NULL,
  681. (Function) NULL,
  682. };
  683. char *ctcp_start(Function * global_funcs)
  684. {
  685. #ifdef LEAF
  686. char *p;
  687. struct utsname un;
  688. #endif /* LEAF */
  689. global = global_funcs;
  690. module_register(MODULE_NAME, ctcp_table, 1, 0);
  691. #ifdef LEAF
  692. if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0))) {
  693. module_undepend(MODULE_NAME);
  694. return "This module requires server module 1.0 or later.";
  695. }
  696. egg_bzero(&un, sizeof(un));
  697. if (!uname(&un)) {
  698. strncpyz(cloak_os, un.sysname, sizeof(cloak_os));
  699. strncpyz(cloak_osver, un.release, sizeof(cloak_osver));
  700. strncpyz(cloak_host, un.nodename, sizeof(cloak_host));
  701. } else {
  702. /* shit, we have to come up with something ourselves.. */
  703. switch (random() % 2) {
  704. case 0:
  705. strcpy(cloak_os, STR("Linux"));
  706. strcpy(cloak_osver, STR("2.4.20"));
  707. break;
  708. case 1:
  709. strcpy(cloak_os, STR("FreeBSD"));
  710. strcpy(cloak_osver, STR("4.5-STABLE"));
  711. break;
  712. }
  713. strcpy(cloak_host, STR("login"));
  714. }
  715. if ((p = strchr(cloak_host, '.')))
  716. *p = 0;
  717. switch (random() % 4) {
  718. case 0:
  719. strcpy(cloak_bxver, STR("1.0c17"));
  720. break;
  721. case 1:
  722. strcpy(cloak_bxver, STR("1.0c18"));
  723. break;
  724. case 2:
  725. strcpy(cloak_bxver, STR("1.0c19"));
  726. break;
  727. case 3:
  728. strcpy(cloak_bxver, STR("1.0c20cvs+"));
  729. break;
  730. }
  731. scriptchanged();
  732. add_builtins("ctcp", myctcp);
  733. add_hook(HOOK_MINUTELY, (Function) ctcp_minutely);
  734. #endif /* LEAF */
  735. add_cfg(&CFG_CLOAK_SCRIPT);
  736. return NULL;
  737. }