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

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

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


Revision 1.44 - (hide annotations) (download) (as text)
Wed Feb 13 16:44:58 2002 UTC (17 years, 10 months ago) by ite
Branch: MAIN
Changes since 1.43: +11 -12 lines
File MIME type: text/x-chdr
gettext plurals are now supported with the P_() macro

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23