/[cvs]/eggdrop1.9/src/chanprog.c
ViewVC logotype

Contents of /eggdrop1.9/src/chanprog.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.52 - (show annotations) (download) (as text)
Thu Oct 10 05:50:12 2002 UTC (16 years, 9 months ago) by wcc
Branch: MAIN
Changes since 1.51: +5 -4 lines
File MIME type: text/x-chdr
* Synch'd 1.6 with 1.7 as of September 1st.
  * Did not synch +C or +r chanmode additions or halfop code, as our mode
    handling really needs to be redone in 1.7.
  * Did not synch any of the handlen-friendly patches.
  * Did not synch Tcl 8.4 fixes (not a proper fix yet).
  * My banligic patch doesn't seem relevent currently.
  * Did not synch sockfix, as network code has changed drasticly.

Synch will be continued tomorrow.

1 /*
2 * chanprog.c --
3 *
4 * telling the current programmed settings
5 * initializing a lot of stuff and loading the tcl scripts
6 */
7 /*
8 * Copyright (C) 1997 Robey Pointer
9 * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25
26 #ifndef lint
27 static const char rcsid[] = "$Id: chanprog.c,v 1.51 2002/08/10 09:31:19 poptix Exp $";
28 #endif
29
30 #include "main.h"
31 #if HAVE_GETRUSAGE
32 #include <sys/resource.h>
33 #if HAVE_SYS_RUSAGE_H
34 #include <sys/rusage.h>
35 #endif
36 #endif
37 #ifdef HAVE_UNAME
38 #include <sys/utsname.h>
39 #endif
40 #include "modules.h"
41 #include "logfile.h"
42 #include "misc.h"
43 #include "users.h" /* get_user_by_handle, readuserfile */
44 #include "dccutil.h" /* dprintf_eggdrop */
45 #include "tcl.h" /* readtclprog */
46 #include "userrec.h" /* count_users, clear_userlist */
47 #include "irccmp.h" /* irccmp */
48
49 extern struct userrec *userlist;
50 extern char ver[], botnetnick[], firewall[],
51 motdfile[], userfile[], helpdir[], tempdir[],
52 moddir[], notify_new[], owner[], configfile[];
53 extern time_t now, online_since;
54 extern int backgrd, term_z, con_chan, cache_hit, cache_miss,
55 firewallport, default_flags, conmask,
56 protect_readonly, make_userfile, noshare,
57 ignore_time;
58
59 struct chanset_t *chanset = NULL; /* Channel list */
60 char admin[121] = ""; /* Admin info */
61 char origbotname[NICKLEN + 1];
62 char *botname; /* Primary botname */
63
64
65 /* Returns memberfields if the nick is in the member list.
66 */
67 memberlist *ismember(struct chanset_t *chan, char *nick)
68 {
69 register memberlist *x;
70
71 for (x = chan->channel.member; x && x->nick[0]; x = x->next)
72 if (!irccmp(x->nick, nick))
73 return x;
74 return NULL;
75 }
76
77 /* Find a chanset by channel name as the server knows it (ie !ABCDEchannel)
78 */
79 struct chanset_t *findchan(const char *name)
80 {
81 register struct chanset_t *chan;
82
83 for (chan = chanset; chan; chan = chan->next)
84 if (!irccmp(chan->name, name))
85 return chan;
86 return NULL;
87 }
88
89 /* Find a chanset by display name (ie !channel)
90 */
91 struct chanset_t *findchan_by_dname(const char *name)
92 {
93 register struct chanset_t *chan;
94
95 for (chan = chanset; chan; chan = chan->next)
96 if (!irccmp(chan->dname, name))
97 return chan;
98 return NULL;
99 }
100
101 /*
102 * "caching" functions
103 */
104
105 /* Shortcut for get_user_by_host -- might have user record in one
106 * of the channel caches.
107 */
108 struct userrec *check_chanlist(const char *host)
109 {
110 char *nick, *uhost, buf[UHOSTLEN];
111 register memberlist *m;
112 register struct chanset_t *chan;
113
114 strlcpy(buf, host, sizeof buf);
115 nick = strtok(buf, "!");
116 uhost = strtok(NULL, "!");
117 for (chan = chanset; chan; chan = chan->next)
118 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
119 if (!irccmp(nick, m->nick) && !strcasecmp(uhost, m->userhost))
120 return m->user;
121 return NULL;
122 }
123
124 /* Shortcut for get_user_by_handle -- might have user record in channels
125 */
126 struct userrec *check_chanlist_hand(const char *hand)
127 {
128 register struct chanset_t *chan;
129 register memberlist *m;
130
131 for (chan = chanset; chan; chan = chan->next)
132 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
133 if (m->user && !strcasecmp(m->user->handle, hand))
134 return m->user;
135 return NULL;
136 }
137
138 /* Clear the user pointers in the chanlists.
139 *
140 * Necessary when a hostmask is added/removed, a user is added or a new
141 * userfile is loaded.
142 */
143 void clear_chanlist(void)
144 {
145 register memberlist *m;
146 register struct chanset_t *chan;
147
148 for (chan = chanset; chan; chan = chan->next)
149 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
150 m->user = NULL;
151 }
152
153 /* Clear the user pointer of a specific nick in the chanlists.
154 *
155 * Necessary when a hostmask is added/removed, a nick changes, etc.
156 * Does not completely invalidate the channel cache like clear_chanlist().
157 */
158 void clear_chanlist_member(const char *nick)
159 {
160 register memberlist *m;
161 register struct chanset_t *chan;
162
163 for (chan = chanset; chan; chan = chan->next)
164 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
165 if (!irccmp(m->nick, nick)) {
166 m->user = NULL;
167 break;
168 }
169 }
170
171 /* If this user@host is in a channel, set it (it was null)
172 */
173 void set_chanlist(const char *host, struct userrec *rec)
174 {
175 char *nick, *uhost, buf[UHOSTLEN];
176 register memberlist *m;
177 register struct chanset_t *chan;
178
179 strlcpy(buf, host, sizeof buf);
180 nick = strtok(buf, "!");
181 uhost = strtok(NULL, "!");
182 for (chan = chanset; chan; chan = chan->next)
183 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
184 if (!irccmp(nick, m->nick) && !strcasecmp(uhost, m->userhost))
185 m->user = rec;
186 }
187
188 /* Dump status info out to dcc
189 */
190 void tell_verbose_status(int idx)
191 {
192 char s[256], s1[121], s2[81];
193 char *vers_t, *uni_t;
194 int i;
195 time_t now2, hr, min;
196 #if HAVE_GETRUSAGE
197 struct rusage ru;
198 #else
199 # if HAVE_CLOCK
200 clock_t cl;
201 # endif
202 #endif
203 #ifdef HAVE_UNAME
204 struct utsname un;
205
206 if (!uname(&un) < 0) {
207 #endif
208 vers_t = " ";
209 uni_t = _("*unknown*");
210 #ifdef HAVE_UNAME
211 } else {
212 vers_t = un.release;
213 uni_t = un.sysname;
214 }
215 #endif
216
217 i = count_users(userlist);
218 dprintf(idx, _("I am %1$s, running %2$s: "), botnetnick, ver);
219 dprintf(idx, P_("%d user\n", "%d users\n", i), i);
220 now2 = now - online_since;
221 s[0] = 0;
222
223 if (now2 > 86400) {
224 int days = (int) (now2 / 86400);
225
226 snprintf(s, sizeof(s), P_("%d day", "%d days", days), days);
227 strcat(s, ", ");
228 now2 -= days * 86400;
229 }
230 hr = (time_t) ((int) now2 / 3600);
231 now2 -= (hr * 3600);
232 min = (time_t) ((int) now2 / 60);
233 snprintf(&s[strlen(s)], sizeof(s) - strlen(s), "%02d:%02d", (int) hr,
234 (int) min);
235 s1[0] = 0;
236 if (backgrd)
237 strcpy(s1, _("background"));
238 else {
239 if (term_z)
240 strcpy(s1, _("terminal mode"));
241 else if (con_chan)
242 strcpy(s1, _("status mode"));
243 else
244 strcpy(s1, _("log dump mode"));
245 }
246 #if HAVE_GETRUSAGE
247 getrusage(RUSAGE_SELF, &ru);
248 hr = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) / 60);
249 min = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) - (hr * 60));
250 sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min); /* Actally min/sec */
251 #else
252 # if HAVE_CLOCK
253 cl = (clock() / CLOCKS_PER_SEC);
254 hr = (int) (cl / 60);
255 min = (int) (cl - (hr * 60));
256 sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min); /* Actually min/sec */
257 # else
258 sprintf(s2, "CPU ???");
259 # endif
260 #endif
261 dprintf(idx, "%s %s (%s) %s %s %4.1f%%\n", _("Online for"),
262 s, s1, s2, _("cache hit"),
263 100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));
264 if (admin[0])
265 dprintf(idx, _("Admin: %s\n"), admin);
266 dprintf(idx, _("Config file: %s\n"), configfile);
267 dprintf(idx, _("OS: %1$s %2$s\n"), uni_t, vers_t);
268 }
269
270 /* Show all internal state variables
271 */
272 void tell_settings(int idx)
273 {
274 char s[1024];
275 struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
276
277 dprintf(idx, _("Botnet Nickname: %s\n"), botnetnick);
278 if (firewall[0])
279 dprintf(idx, _("Firewall: %1$s, port %2$d\n"), firewall, firewallport);
280 dprintf(idx, _("Userfile: %1$s Motd: %2$s\n"), userfile, motdfile);
281 dprintf(idx, _("Directories:\n"));
282 dprintf(idx, _(" Help : %s\n"), helpdir);
283 dprintf(idx, _(" Temp : %s\n"), tempdir);
284 dprintf(idx, _(" Modules : %s\n"), moddir);
285 fr.global = default_flags;
286
287 build_flags(s, &fr, NULL);
288 dprintf(idx, "%s [%s], %s: %s\n", _("New users get flags"), s,
289 _("notify"), notify_new);
290 /* FIXME PLURAL: handle it properly */
291 if (owner[0])
292 dprintf(idx, _("Permanent owner(s): %s\n"), owner);
293 dprintf(idx, _("Ignores last %d mins\n"), ignore_time);
294 }
295
296 void reaffirm_owners()
297 {
298 char *p, *q, s[121];
299 struct userrec *u;
300
301 /* Make sure default owners are +n */
302 if (owner[0]) {
303 q = owner;
304 p = strchr(q, ',');
305 while (p) {
306 strlcpy(s, q, (p - q) + 1);
307 rmspace(s);
308 u = get_user_by_handle(userlist, s);
309 if (u)
310 u->flags = sanity_check(u->flags | USER_OWNER);
311 q = p + 1;
312 p = strchr(q, ',');
313 }
314 strcpy(s, q);
315 rmspace(s);
316 u = get_user_by_handle(userlist, s);
317 if (u)
318 u->flags = sanity_check(u->flags | USER_OWNER);
319 }
320 }
321
322 void chanprog()
323 {
324 admin[0] = 0;
325 helpdir[0] = 0;
326 tempdir[0] = 0;
327 conmask = 0;
328 /* Turn off read-only variables (make them write-able) for rehash */
329 protect_readonly = 0;
330 /* Now read it */
331 if (!readtclprog(configfile))
332 fatal(_("CONFIG FILE NOT LOADED (NOT FOUND, OR ERROR)"), 0);
333 /* We should be safe now */
334 call_hook(HOOK_REHASH);
335 protect_readonly = 1;
336 if (!botnetnick[0]) {
337 strlcpy(botnetnick, origbotname, HANDLEN + 1);
338 }
339 if (!botnetnick[0])
340 fatal("I don't have a botnet nick!!\n", 0);
341 if (!userfile[0])
342 fatal(_("STARTING BOT IN USERFILE CREATION MODE.\n\
343 Telnet to the bot and enter 'NEW' as your nickname."), 0);
344 if (!readuserfile(userfile, &userlist)) {
345 if (!make_userfile) {
346 char tmp[178];
347
348 snprintf(tmp, sizeof tmp, _("USER FILE NOT FOUND! (try ./eggdrop -m %s to make one)\n"), configfile);
349 fatal(tmp, 0);
350 }
351 printf(_("\n\nSTARTING BOT IN USERFILE CREATION MODE.\n\
352 Telnet to the bot and enter 'NEW' as your nickname.\n"));
353 if (module_find("server", 0, 0))
354 printf(_("OR go to IRC and type: /msg %s hello\n"), origbotname);
355 printf(_("This will make the bot recognize you as the master.\n\n"));
356 } else if (make_userfile) {
357 make_userfile = 0;
358 printf(_("USERFILE ALREADY EXISTS (drop the -m)\n"));
359 }
360 if (helpdir[0])
361 if (helpdir[strlen(helpdir) - 1] != '/')
362 strcat(helpdir, "/");
363 if (tempdir[0])
364 if (tempdir[strlen(tempdir) - 1] != '/')
365 strcat(tempdir, "/");
366 /* Test tempdir: it's vital */
367 {
368 FILE *f;
369 char s[161], rands[8];
370
371 /* Possible file race condition solved by using a random string
372 * and the process id in the filename.
373 * FIXME: This race is only partitially fixed. We could still be
374 * overwriting an existing file / following a malicious
375 * link.
376 */
377 make_rand_str(rands, 7); /* create random string */
378 sprintf(s, "%s.test-%u-%s", tempdir, getpid(), rands);
379 f = fopen(s, "w");
380 if (f == NULL)
381 fatal(_("CANT WRITE TO TEMP DIR"), 0);
382 fclose(f);
383 unlink(s);
384 }
385 reaffirm_owners();
386 }
387
388 /* Reload the user file from disk
389 */
390 void reload()
391 {
392 FILE *f;
393
394 f = fopen(userfile, "r");
395 if (f == NULL) {
396 putlog(LOG_MISC, "*", _("Cant reload user file!"));
397 return;
398 }
399 fclose(f);
400 noshare = 1;
401 clear_userlist(userlist);
402 noshare = 0;
403 userlist = NULL;
404 if (!readuserfile(userfile, &userlist))
405 fatal(_("User file is missing!"), 0);
406 reaffirm_owners();
407 call_hook(HOOK_READ_USERFILE);
408 }
409
410 void rehash()
411 {
412 call_hook(HOOK_PRE_REHASH);
413 noshare = 1;
414 clear_userlist(userlist);
415 noshare = 0;
416 userlist = NULL;
417 chanprog();
418 }
419
420 /* Oddly enough, written by proton (Emech's coder)
421 */
422 int isowner(char *name)
423 {
424 char *pa, *pb;
425 char nl, pl;
426
427 if (!owner || !*owner)
428 return (0);
429 if (!name || !*name)
430 return (0);
431 nl = strlen(name);
432 pa = owner;
433 pb = owner;
434 while (1) {
435 while (1) {
436 if ((*pb == 0) || (*pb == ',') || (*pb == ' '))
437 break;
438 pb++;
439 }
440 pl = (unsigned int) pb - (unsigned int) pa;
441 if (pl == nl && !strncasecmp(pa, name, nl))
442 return (1);
443 while (1) {
444 if ((*pb == 0) || ((*pb != ',') && (*pb != ' ')))
445 break;
446 pb++;
447 }
448 if (*pb == 0)
449 return (0);
450 pa = pb;
451 }
452 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23