4
0

dcccmds.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*
  2. * Copyright (C) 2000,2001 Florian Sander
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. static int cmd_savestats(struct userrec *u, int idx, char *par)
  19. {
  20. write_stats();
  21. putlog(LOG_CMDS, "*", "#%s# savestats", dcc[idx].nick);
  22. return 0;
  23. }
  24. static int cmd_loadstats(struct userrec *u, int idx, char *par)
  25. {
  26. read_stats();
  27. putlog(LOG_CMDS, "*", "#%s# loadstats", dcc[idx].nick);
  28. return 0;
  29. }
  30. static int cmd_purgestats(struct userrec *u, int idx, char *par)
  31. {
  32. Context;
  33. deloldstatusers();
  34. Context;
  35. purgestats();
  36. Context;
  37. update_schannel_members();
  38. Context;
  39. putlog(LOG_CMDS, "*", "#%s# purgestats", dcc[idx].nick);
  40. Context;
  41. return 0;
  42. }
  43. static int cmd_sumuser(struct userrec *user, int idx, char *par)
  44. {
  45. struct stats_userlist *uu1, *uu2;
  46. char *user1, *user2;
  47. Context;
  48. user1 = newsplit(&par);
  49. user2 = par;
  50. uu1 = findsuser_by_name(user1);
  51. uu2 = findsuser_by_name(user2);
  52. if (!user1[0] || !user2[0]) {
  53. dprintf(idx, "Usage: .sumuser <user1> <user2>\n");
  54. return 0;
  55. }
  56. if (!uu1) {
  57. dprintf(idx, "%s isn't a valid user!\n", user1);
  58. return 0;
  59. }
  60. if (!uu2) {
  61. dprintf(idx, "%s isn't a valid user!\n", user2);
  62. return 0;
  63. }
  64. user_merge(user1, user2);
  65. dprintf(idx, "Transferred stats from %s to %s and deleted %s\n", user2,
  66. user1, user2);
  67. putlog(LOG_CMDS, "*", "#%s# sumuser %s %s", dcc[idx].nick, user1, user2);
  68. update_schannel_members();
  69. Context;
  70. return 0;
  71. }
  72. static int cmd_resetuser(struct userrec *u, int idx, char *par)
  73. {
  74. char *user, *chan;
  75. locstats *ls;
  76. Context;
  77. user = newsplit(&par);
  78. chan = newsplit(&par);
  79. ls = findlocstats(chan, user);
  80. if (!ls) {
  81. dprintf(idx, "Couldn't find stats for %s in %s.\n", user, chan);
  82. return 0;
  83. }
  84. resetlocstats(ls);
  85. dprintf(idx, "%s's stats set to 0 on %s.\n", ls->user, chan);
  86. putlog(LOG_CMDS, "*", "#%s# resetuser %s %s", dcc[idx].nick, user, chan);
  87. Context;
  88. return 0;
  89. }
  90. static int cmd_schannel(struct userrec *u, int idx, char *par)
  91. {
  92. char *chname, spaces[50], *user, ubuf[2];
  93. struct stats_chan *chan;
  94. struct stats_member *m;
  95. int len = 0;
  96. Context;
  97. ubuf[0] = '*';
  98. ubuf[1] = 0;
  99. #if EGG_IS_MIN_VER(10500)
  100. len = nick_len;
  101. #else
  102. len = NICKLEN;
  103. #endif
  104. chname = newsplit(&par);
  105. putlog(LOG_CMDS, "*", "#%s# (%s) schannel %s", dcc[idx].nick,
  106. dcc[idx].u.chat->con_chan, chname);
  107. if (!chname[0])
  108. chname = dcc[idx].u.chat->con_chan;
  109. chan = schan_find(chname);
  110. if (!chan) {
  111. if (!findchan_by_dname(chname))
  112. dprintf(idx, "Invalid channel: %s\n", chname);
  113. else
  114. dprintf(idx, "Channel %s is inactive\n", chname);
  115. return 0;
  116. }
  117. dprintf(idx, "%d users on channel:\n", schan_members_count(&chan->members));
  118. sprintf(spaces, " ");
  119. spaces[len - 4] = 0;
  120. dprintf(idx, "NICK%s", spaces);
  121. spaces[len - 4] = ' ';
  122. spaces[HANDLEN - 4] = 0;
  123. dprintf(idx, " USER%s", spaces);
  124. dprintf(idx, " UHOST\n");
  125. spaces[HANDLEN - 4] = ' ';
  126. for (m = schan_members_getfirst(&chan->members); m; m = schan_members_getnext(&chan->members)) {
  127. if (m->user)
  128. user = m->user->user;
  129. else
  130. user = ubuf;
  131. spaces[len - strlen(m->nick)] = 0;
  132. dprintf(idx, "%s%s", m->nick, spaces);
  133. spaces[len - strlen(m->nick)] = ' ';
  134. spaces[HANDLEN - strlen(user)] = 0;
  135. dprintf(idx, " %s%s", user, spaces);
  136. spaces[HANDLEN - strlen(user)] = ' ';
  137. dprintf(idx, " %s\n", m->uhost);
  138. }
  139. Context;
  140. return 0;
  141. }
  142. static int cmd_swhois(struct userrec *user, int idx, char *par)
  143. {
  144. struct stats_userlist *u;
  145. Context;
  146. glob_slang = slang_find(coreslangs, default_slang);
  147. if (!par[0]) {
  148. dprintf(idx, "Usage: .swhois <stats-user>\n");
  149. return 0;
  150. }
  151. putlog(LOG_CMDS, "*", "#%s# swhois %s", dcc[idx].nick, par);
  152. u = findsuser_by_name(par);
  153. if (!u) {
  154. dprintf(idx, "No such user %s.\n", par);
  155. return 0;
  156. }
  157. dump_suser(idx, u);
  158. return 0;
  159. }
  160. static void dump_suser(int idx, struct stats_userlist *u)
  161. {
  162. struct stats_hostlist *h;
  163. struct userrec *uu;
  164. dprintf(idx, "------ %s ------\n", u->user);
  165. dprintf(idx, "flags: %clist %caddhosts %cnostats\n",
  166. suser_list(u) ? '+' : '-',
  167. suser_addhosts(u) ? '+' : '-',
  168. suser_nostats(u) ? '+' : '-');
  169. dprintf(idx, "Age: %s\n", stats_duration((now - u->created), 3));
  170. dprintf(idx, "Allowed inactivity: %s\n", stats_duration(TIMETOLIVE(u), 3));
  171. if (u->hosts) {
  172. dprintf(idx, "Hosts: %s\n", u->hosts->mask);
  173. for (h = u->hosts->next; h; h = h->next)
  174. dprintf(idx, " %s\n", h->mask);
  175. }
  176. uu = get_user_by_handle(userlist, u->user);
  177. if (uu)
  178. dprintf(idx, "This user also exists in the eggdrop-userfile. There might be additional hosts.\n");
  179. }
  180. static int cmd_pls_shost(struct userrec *user, int idx, char *par)
  181. {
  182. char *suser, *host;
  183. struct stats_userlist *u;
  184. Context;
  185. suser = newsplit(&par);
  186. host = newsplit(&par);
  187. if (!suser[0] || !host[0]) {
  188. dprintf(idx, "Usage: .+shost <statuser> <host>\n");
  189. return 0;
  190. }
  191. putlog(LOG_CMDS, "*", "#%s# +shost %s %s", dcc[idx].nick, suser, host);
  192. u = findsuser_by_name(suser);
  193. if (!u) {
  194. dprintf(idx, "No such user: %s\n", suser);
  195. return 0;
  196. }
  197. saddhost(u, host, now, now);
  198. dprintf(idx, "Added hostmask %s to %s.\n", host, u->user);
  199. update_schannel_members();
  200. return 0;
  201. }
  202. static int cmd_mns_shost(struct userrec *user, int idx, char *par)
  203. {
  204. char *suser, *host;
  205. struct stats_userlist *u;
  206. Context;
  207. suser = newsplit(&par);
  208. host = newsplit(&par);
  209. if (!suser[0] || !host[0]) {
  210. dprintf(idx, "Usage: .-shost <statuser> <host>\n");
  211. return 0;
  212. }
  213. putlog(LOG_CMDS, "*", "#%s# -shost %s %s", dcc[idx].nick, suser, host);
  214. u = findsuser_by_name(suser);
  215. if (!u) {
  216. dprintf(idx, "No such user: %s\n", suser);
  217. return 0;
  218. }
  219. if (sdelhost(u, host)) {
  220. dprintf(idx, "Removed hostmask %s from %s.\n", host, u->user);
  221. update_schannel_members();
  222. } else
  223. dprintf(idx, "Couldn't remove hostmask %s from %s: no such mask!\n", host, u->user);
  224. update_schannel_members();
  225. return 0;
  226. }
  227. static int cmd_pls_suser(struct userrec *user, int idx, char *par)
  228. {
  229. struct stats_userlist *u;
  230. char *suser, *host;
  231. Context;
  232. suser = newsplit(&par);
  233. host = newsplit(&par);
  234. if (!suser[0]) {
  235. dprintf(idx, "Usage: .+suser <statuser> [host]\n");
  236. return 0;
  237. }
  238. putlog(LOG_CMDS, "*", "#%s# +suser %s %s", dcc[idx].nick, suser, host);
  239. u = findsuser_by_name(suser);
  240. if (u) {
  241. dprintf(idx, "That statuser already exists!\n");
  242. return 0;
  243. }
  244. u = addsuser(suser, now, now);
  245. if (host[0]) {
  246. saddhost(u, host, now, now);
  247. putlog(LOG_MISC, "Added stats user %s with hostmask %s.", u->user, host);
  248. } else
  249. putlog(LOG_MISC, "Added stats user %s without a hostmask.", u->user);
  250. update_schannel_members();
  251. return 0;
  252. }
  253. static int cmd_mns_suser(struct userrec *user, int idx, char *par)
  254. {
  255. struct stats_userlist *u;
  256. char *suser;
  257. Context;
  258. suser = newsplit(&par);
  259. if (!suser[0]) {
  260. dprintf(idx, "Usage: .-suser <statuser>\n");
  261. return 0;
  262. }
  263. putlog(LOG_CMDS, "*", "#%s# -suser %s", dcc[idx].nick, suser);
  264. u = findsuser_by_name(suser);
  265. if (!u) {
  266. dprintf(idx, "No such user.\n");
  267. return 0;
  268. }
  269. putlog(LOG_MISC, "Deleted stats user %s.", u->user);
  270. delsuser(suser);
  271. update_schannel_members();
  272. return 0;
  273. }
  274. static int cmd_schattr(struct userrec *user, int idx, char *par)
  275. {
  276. struct stats_userlist *u;
  277. char *suser, *mode;
  278. Context;
  279. suser = newsplit(&par);
  280. if (!suser[0] || !par[0]) {
  281. dprintf(idx, "Usage: .schattr <statuser> <+/-list +/-addhosts +/-nostats>\n");
  282. return 0;
  283. }
  284. putlog(LOG_CMDS, "*", "#%s# schattr %s %s", dcc[idx].nick, suser, par);
  285. u = findsuser_by_name(suser);
  286. if (!u) {
  287. dprintf(idx, "No such user.\n");
  288. return 0;
  289. }
  290. while (par[0]) {
  291. mode = newsplit(&par);
  292. if (!user_changeflag(u, mode))
  293. dprintf(idx, "Unknown mode \"%s\" ignored.\n", mode);
  294. }
  295. dprintf(idx, "New settings for %s: %clist %caddhosts %cnostats\n", u->user,
  296. suser_list(u) ? '+' : '-', suser_addhosts(u) ? '+' : '-',
  297. suser_nostats(u) ? '+' : '-');
  298. return 0;
  299. }
  300. static int cmd_updateschans(struct userrec *user, int idx, char *par)
  301. {
  302. Context;
  303. putlog(LOG_CMDS, "*", "#%s# updateschans", dcc[idx].nick);
  304. update_schannel_members();
  305. return 0;
  306. }
  307. static int cmd_smatch(struct userrec *user, int idx, char *par)
  308. {
  309. char *tmp, *mask;
  310. int list, addhosts, nostats, match, matches, deb;
  311. struct stats_userlist *u;
  312. struct stats_hostlist *h;
  313. Context;
  314. mask = NULL;
  315. list = addhosts = nostats = -1;
  316. putlog(LOG_CMDS, "*", "#%s# smatch %s", dcc[idx].nick, par);
  317. while (par[0]) {
  318. tmp = newsplit(&par);
  319. if ((tmp[0] == '+') || (tmp[0] == '-')) {
  320. if (!strcasecmp(tmp + 1, "addhosts"))
  321. addhosts = (tmp[0] == '+');
  322. else if (!strcasecmp(tmp + 1, "list"))
  323. list = (tmp[0] == '+');
  324. else if (!strcasecmp(tmp + 1, "nostats"))
  325. nostats = (tmp[0] == '+');
  326. else {
  327. dprintf(idx, "Unknown stats-user flag: %s\n", tmp);
  328. return 0;
  329. }
  330. } else {
  331. if (mask) {
  332. dprintf(idx, "Usage: .smatch [hostmask|nickmask] [+|-addhosts] [+|-list]\n");
  333. return 0;
  334. }
  335. mask = tmp;
  336. }
  337. }
  338. if (!mask && (list == -1) && (addhosts == -1) && (nostats == -1)) {
  339. dprintf(idx, "Usage: .smatch [hostmask|nickmask] [+|-addhosts] [+|-list]\n");
  340. return 0;
  341. }
  342. debug3("mask: %s, list: %d, addhosts: %d", mask, list, addhosts);
  343. matches = deb = 0;
  344. for (u = suserlist; u; u = u->next) {
  345. deb++;
  346. match = 0;
  347. if (list && (list != -1) && !suser_list(u))
  348. continue;
  349. if (!list && suser_list(u))
  350. continue;
  351. if (addhosts && (addhosts != -1) && !suser_addhosts(u))
  352. continue;
  353. if (!addhosts && suser_addhosts(u))
  354. continue;
  355. if (nostats && (nostats != -1) && !suser_nostats(u))
  356. continue;
  357. if (!nostats && suser_nostats(u))
  358. continue;
  359. if (mask) {
  360. if (wild_match(mask, u->user)) {
  361. match = 1;
  362. } else {
  363. for (h = u->hosts; h && !match; h = h->next) {
  364. if (wild_match(mask, h->mask)) {
  365. match = 1;
  366. }
  367. }
  368. }
  369. } else
  370. match = 1;
  371. if (match) {
  372. matches++;
  373. if (matches > 20) {
  374. dprintf(idx, "More than 20 matches. Truncated.\n");
  375. break;
  376. } else
  377. dump_suser(idx, u);
  378. }
  379. }
  380. if (!matches)
  381. dprintf(idx, "No matches!\n");
  382. else if (matches <= 20)
  383. dprintf(idx, "===\n%d matches found.\n", matches);
  384. debug2("%d matches, %d cycles", matches, deb);
  385. return 0;
  386. }
  387. static int cmd_chsusername(struct userrec *user, int idx, char *par)
  388. {
  389. char *oldnick, *newnick;
  390. struct stats_userlist *u;
  391. Context;
  392. putlog(LOG_CMDS, "*", "#%s# chsusername %s", dcc[idx].nick, par);
  393. oldnick = newsplit(&par);
  394. newnick = newsplit(&par);
  395. if (!newnick[0] || par[0]) {
  396. dprintf(idx, "Usage: .chsusername old_user_name new_user_name\n");
  397. return 0;
  398. }
  399. u = findsuser_by_name(oldnick);
  400. if (!u) {
  401. dprintf(idx, "No such user: %s\n", oldnick);
  402. return 0;
  403. }
  404. u = findsuser_by_name(newnick);
  405. if (u && strcasecmp(oldnick, newnick)) {
  406. dprintf(idx, "User %s already exists!\n", newnick);
  407. return 0;
  408. }
  409. if (get_user_by_handle(userlist, oldnick)) {
  410. dprintf(idx, "%s exists in the eggdrop userfile. Please use .chnick or "
  411. ".chhand instead to keep the stats synched.\n");
  412. return 0;
  413. }
  414. track_stat_user(oldnick, newnick);
  415. update_schannel_members();
  416. return 0;
  417. }
  418. static cmd_t mydcc[] =
  419. {
  420. {"savestats", "m", cmd_savestats, NULL},
  421. {"loadstats", "m", cmd_loadstats, NULL},
  422. {"purgestats", "m|-", cmd_purgestats, NULL},
  423. {"sumuser", "n|-", cmd_sumuser, NULL},
  424. {"resetuser", "m|-", cmd_resetuser, NULL},
  425. {"schannel", "o|o", cmd_schannel, NULL},
  426. {"swhois", "o|o", cmd_swhois, NULL},
  427. {"+shost", "m|-", cmd_pls_shost, NULL},
  428. {"-shost", "m|-", cmd_mns_shost, NULL},
  429. {"+suser", "m|-", cmd_pls_suser, NULL},
  430. {"-suser", "m|-", cmd_mns_suser, NULL},
  431. {"schattr", "m|-", cmd_schattr, NULL},
  432. {"updateschans", "-|-", cmd_updateschans, NULL},
  433. {"smatch", "m", cmd_smatch, NULL},
  434. {"chsusername", "m", cmd_chsusername, NULL},
  435. {0, 0, 0, 0}
  436. };