ctcp.c 23 KB

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