ctcp.c 26 KB

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