user.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 stats_checkhand (char *oldnick, char *newnick)
  19. {
  20. Context;
  21. if (track_stat_user(oldnick, newnick))
  22. putlog(LOG_MISC, "*", "Stats.mod: Transferred stats from %s to %s", oldnick, newnick);
  23. Context;
  24. return 1;
  25. }
  26. static cmd_t stats_nkch[] =
  27. {
  28. {"*", "", (Function) stats_checkhand, "stat:nkch"},
  29. {0, 0, 0, 0}
  30. };
  31. static void stats_autoadd(memberlist *m, char *chan)
  32. {
  33. struct userrec *u;
  34. char s[121], s2[121], host[121];
  35. struct xtra_key *xk;
  36. time_t tt;
  37. Context;
  38. if (!use_userfile)
  39. return;
  40. if (autoadd < 0)
  41. return;
  42. if (!m->nick[0])
  43. return;
  44. if ((now - m->joined) < (autoadd * 60))
  45. return;
  46. if (match_my_nick(m->nick))
  47. return;
  48. if ((strlen(m->nick) + strlen(m->userhost)) >= 120)
  49. return;
  50. sprintf(s, "%s!%s", m->nick, m->userhost);
  51. if (strchr(s, '*') || strchr(s, '?'))
  52. return; /* don't add users with wildcards in their hostmask */
  53. maskhost(s, host);
  54. u = get_user_by_host(s);
  55. if (u)
  56. return;
  57. u = get_user_by_handle(userlist, m->nick);
  58. if (u) {
  59. if (!matchattr(u, badflags, chan)) {
  60. addhost_by_handle(m->nick, host);
  61. putlog(LOG_MISC, "*", "Stats.mod: Added hostmask %s to %s.", host, m->nick);
  62. return;
  63. }
  64. } else {
  65. userlist = adduser(userlist, m->nick, host, "-", USER_DEFAULT);
  66. u = get_user_by_handle(userlist, m->nick);
  67. xk = user_malloc(sizeof(struct xtra_key));
  68. xk->key = user_malloc(7);
  69. strcpy(xk->key, "AADDED");
  70. xk->data = user_malloc(10);
  71. sprintf(xk->data, "%09lu", now);
  72. set_user(&USERENTRY_XTRA, u, xk);
  73. tt = now;
  74. strftime(s2, 120, "Added by Stats.mod on %d.%m.%Y %H:%M.", localtime(&tt));
  75. /* sprintf(s2, "Added by Stats.mod on %s", ctime(&tt)); */
  76. set_user(&USERENTRY_COMMENT, u, (void *) s2);
  77. set_handle_laston(chan, u, now);
  78. putlog(LOG_MISC, "*", "Stats.mod: Added %s to userlist.", m->nick);
  79. }
  80. Context;
  81. }
  82. static void deloldstatusers()
  83. {
  84. struct laston_info *li;
  85. struct xtra_key *xk;
  86. struct userrec *u, *lu;
  87. int changed, del;
  88. struct chanset_t *chan;
  89. struct stats_userlist *su, *lsu;
  90. struct stats_hostlist *h, *lh;
  91. if (stat_expire_user < 1)
  92. return;
  93. u = userlist;
  94. while (u) {
  95. changed = 0;
  96. del = 1;
  97. li = get_user(&USERENTRY_LASTON, u);
  98. if (li) {
  99. if ((now - li->laston) > (stat_expire_user * 86400)) {
  100. for (xk = get_user(&USERENTRY_XTRA, u); (xk && del); xk = xk->next) {
  101. if (!strcasecmp(xk->key, "AADDED")) {
  102. if(!get_user(&USERENTRY_PASS, u)) {
  103. for (chan = chanset; chan; chan = chan->next) {
  104. #if EGG_IS_MIN_VER(10500)
  105. if (matchattr(u, badflags, chan->dname)) {
  106. #else
  107. if (matchattr(u, badflags, chan->name)) {
  108. #endif
  109. del = 0;
  110. break;
  111. }
  112. }
  113. if (!del)
  114. break;
  115. putlog(LOG_MISC, "*", "Stats.mod: %s wasn't seen for over %d days. Deleted from the eggdrop userfile.", u->handle, stat_expire_user);
  116. lu = u->next;
  117. deluser(u->handle);
  118. u = lu;
  119. changed = 1;
  120. break;
  121. }
  122. }
  123. }
  124. }
  125. }
  126. if (!changed)
  127. u = u->next;
  128. }
  129. su = suserlist;
  130. lsu = NULL;
  131. while (su) {
  132. h = su->hosts;
  133. lh = NULL;
  134. while (h) {
  135. if ((now - h->lastused) > (stat_expire_user * 86400)) {
  136. putlog(LOG_MISC, "*", "Stats.Mod: %s didn't use the hostmask %s during the last %d days. Removing from hostlist...",
  137. su->user, h->mask, stat_expire_user);
  138. nfree(h->mask);
  139. if (lh)
  140. lh->next = h->next;
  141. else
  142. su->hosts = h->next;
  143. nfree(h);
  144. if (lh)
  145. h = lh->next;
  146. else
  147. h = su->hosts;
  148. } else {
  149. lh = h;
  150. h = h->next;
  151. }
  152. }
  153. if (!su->hosts) {
  154. u = get_user_by_handle(userlist, su->user);
  155. if (u) {
  156. lsu = su;
  157. su = su->next;
  158. continue;
  159. }
  160. putlog(LOG_MISC, "*", "Stats.Mod: All of %s's hosts expired. Deleting stat user...", su->user);
  161. nfree(su->user);
  162. if (lsu)
  163. lsu->next = su->next;
  164. else
  165. suserlist = su->next;
  166. weed_userlink_from_chanset(su);
  167. weed_userlink_from_locstats(su);
  168. nfree(su);
  169. if (lsu)
  170. su = lsu->next;
  171. else
  172. su = suserlist;
  173. } else {
  174. lsu = su;
  175. su = su->next;
  176. }
  177. }
  178. }
  179. static void purgestats()
  180. {
  181. globstats *gs, *gs2;
  182. locstats *ls, *ls2;
  183. locstats *sl, *sl2;
  184. int i, ii, kill;
  185. struct stats_userlist *u;
  186. struct userrec *u2;
  187. struct chanset_t *chan;
  188. Context;
  189. gs = sdata;
  190. gs2 = NULL;
  191. while (gs) {
  192. #ifndef OLDBOT
  193. chan = findchan_by_dname(gs->chan);
  194. #else
  195. chan = findchan(gs->chan);
  196. #endif
  197. if (chan && gs->local) {
  198. ls = gs->local;
  199. ls2 = NULL;
  200. while (ls) {
  201. kill = 1;
  202. u2 = get_user_by_handle(userlist, ls->user);
  203. u = findsuser_by_name(ls->user);
  204. if (u2 || u) {
  205. for (i = 0; i < TOTAL_TYPES; i++) {
  206. if (ls->values[S_TOTAL][i] != 0) {
  207. kill = 0;
  208. break;
  209. }
  210. }
  211. if (!kill) {
  212. if (use_userfile && u2) {
  213. if (strcmp(ls->user, u2->handle)) {
  214. debug2("Stats.mod: Transferred stats from %s to %s", ls->user, u2->handle);
  215. nfree(ls->user);
  216. ls->user = nmalloc(strlen(u2->handle) + 1);
  217. strcpy(ls->user, u2->handle);
  218. }
  219. } else if (!use_userfile && u) {
  220. if (strcmp(ls->user, u->user)) {
  221. debug2("Stats.mod: Transferred stats from %s to %s", ls->user, u->user);
  222. nfree(ls->user);
  223. ls->user = nmalloc(strlen(u->user) + 1);
  224. strcpy(ls->user, u->user);
  225. }
  226. }
  227. }
  228. }
  229. if (kill) {
  230. putlog(LOG_MISC, "*", "Stats.mod: Deleting stats for %s in %s(empty data or no such user)", ls->user, gs->chan);
  231. for (i = 0; i < 4; i++) {
  232. for (ii = 0; ii < (TOTAL_TYPES + TOTAL_SPECIAL_TYPES); ii++) {
  233. sl = gs->slocal[i][ii];
  234. sl2 = NULL;
  235. while (sl) {
  236. if (!rfc_casecmp(sl->user, ls->user))
  237. break;
  238. sl2 = sl;
  239. sl = sl->snext[i][ii];
  240. }
  241. if (sl) {
  242. if (sl2)
  243. sl2->snext[i][ii] = sl->snext[i][ii];
  244. else
  245. gs->slocal[i][ii] = sl->snext[i][ii];
  246. } else
  247. putlog(LOG_MISC, "*", "WARNING!!! %s not found in sorted list ([%d][%d])! Corrupted data?", ls->user, i, ii);
  248. }
  249. }
  250. if (ls2)
  251. ls2->next = ls->next;
  252. else
  253. gs->local = ls->next;
  254. nfree(ls->user);
  255. free_wordstats(ls->words);
  256. free_quotes(ls->quotes);
  257. weed_statlink_from_chanset(ls);
  258. nfree(ls);
  259. if (ls2)
  260. ls = ls2->next;
  261. else
  262. ls = gs->local;
  263. } else {
  264. ls2 = ls;
  265. ls = ls->next;
  266. }
  267. }
  268. gs2 = gs;
  269. gs = gs->next;
  270. } else {
  271. putlog(LOG_MISC, "*", "Stats.mod: Deleting stats for %s. (empty data or no such channel)", gs->chan);
  272. free_one_chan(gs->chan);
  273. if (gs2)
  274. gs2->next = gs->next;
  275. else
  276. sdata = gs->next;
  277. free_localstats(gs->local);
  278. free_wordstats(gs->words);
  279. free_topics(gs->topics);
  280. free_urls(gs->urls);
  281. free_quotes(gs->log);
  282. free_hosts(gs->hosts);
  283. free_kicks(gs->kicks);
  284. nfree(gs->chan);
  285. nfree(gs);
  286. if (gs2)
  287. gs = gs2->next;
  288. else
  289. gs = sdata;
  290. }
  291. }
  292. Context;
  293. }