ctcp.c 25 KB

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