/[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.35 - (hide annotations) (download) (as text)
Fri Oct 19 01:55:04 2001 UTC (18 years, 1 month ago) by tothwolf
Branch: MAIN
Changes since 1.34: +6 -6 lines
File MIME type: text/x-chdr
* removed obsolete EGG_CHECK_FUNC_VSPRINTF autoconf macro
* removed obsolete EGG_HEADER_STDC autoconf macro
* added EGG_C_LONG_LONG autoconf macro
* added EGG_FUNC_C99_VSNPRINTF autoconf macro
* added EGG_REPLACE_SNPRINTF autoconf macro
* added EGG_TYPE_32BIT autoconf macro

* removed unused dlfcn.h header check from configure.ac
* removed AC_CHECK_SIZEOF long and int from configure.ac
* added many required autoconf macros to configure.ac
* added AC_REPLACE_FUNCS to configure.ac for compat functions
* many configure.ac cleanups

* updated compat/snprintf.c with latest version from Samba
* added code to link libm with compat library for snprintf.c
* added support for LIBOBJS to compat/Makefile.am
* added memset back to compat
* added memcpy back to compat
* many compat cleanups

* renamed egg_strcasecmp() to strcasecmp()
* renamed egg_strncasecmp() to strncasecmp()
* renamed egg_snprintf() to snprintf()
* renamed egg_vsnprintf() to vsnprintf()
* renamed egg_strftime() to strftime()
* renamed egg_inet_aton() to inet_aton()
* renamed egg_inet_ntop() to inet_ntop()
* renamed egg_inet_pton() to inet_pton()

* exported strftime() for modules
* exported inet_ntop() for modules
* exported inet_pton() for modules
* exported vasprintf() for modules
* exported asprintf() for modules

* renamed u_32bit_t typedef to u_32int_t
* extended stat.h to support standard bits and checks

* major function changes:
  + egg_strcasecmp -> strcasecmp
  + egg_strncasecmp -> strncasecmp
  + egg_snprintf -> snprintf
  + egg_vsnprintf -> vsnprintf
  + egg_strftime -> strftime
  + egg_inet_aton -> inet_aton
  + egg_inet_ntop -> inet_ntop
  + egg_inet_pton -> inet_pton

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23