ctcp.c 26 KB

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