/[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.40 - (show annotations) (download) (as text)
Sat Jan 19 20:08:58 2002 UTC (17 years, 6 months ago) by ite
Branch: MAIN
Changes since 1.39: +3 -1 lines
File MIME type: text/x-chdr
* varoius header inclusion cleanups
* moved FILEDB* defines from src/egg.h to a more suitable place in modules/filesys/filesys.h
* moved NORMAL and QUICK defines from src/egg.h to a more suitable place in modules/irc/irc.h
* fixed a warning in modules/perlscript/perlscript.c
* created src/misc.h and src/logfile.h. Moved in them the respective prototypes from src/proto.h, and the respective defines from src/egg.h
* moved private structures from src/dns.h to src/dns.c
* moved src/dns.c's related prototypes from src/egg.h to src/dns.h
* moved RES_* defines from src/egg.h to dns.h
* removed some unneeded defines here and there
* moved LOG_* defines from src/egg.h to src/logfile.h
* dns_events wasn't static

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23