/[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.60 - (hide annotations) (download) (as text)
Mon Feb 17 10:22:30 2003 UTC (16 years, 6 months ago) by stdarg
Branch: MAIN
Changes since 1.59: +1 -2 lines
File MIME type: text/x-chdr
* Moved irccmp to libeggdrop
* Initial support for 005 numeric

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23