/[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.48 - (show annotations) (download) (as text)
Sun May 5 15:19:11 2002 UTC (17 years, 2 months ago) by wingman
Branch: MAIN
Changes since 1.47: +6 -1 lines
File MIME type: text/x-chdr
Changes:

 * removed patch.h
 * added proper <filename>.h to (nearly) all <filename.h>
 * moved fixcolon to server.mod and irc.mod
 * moved ip2long to net.h
 * removed some unused function (forgot the name :-P)

Todo:

 * move config.h #include's away from main.h to files which
   needs them
 * clean up lib/eggdrop/module.h
   (now not just main.h is included but nearly all .h files from
    the core, but i guess this fixes itself when the global func
    table is abandon - then the modules must be revised too and
    we can clean up module.h)

And i'll bet i forgot something... ;-)

1 /*
2 * chanprog.c -- handles:
3 * telling the current programmed settings
4 * initializing a lot of stuff and loading the tcl scripts
5 *
6 * $Id: chanprog.c,v 1.47 2002/04/01 13:33:33 ite Exp $
7 */
8 /*
9 * Copyright (C) 1997 Robey Pointer
10 * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
11 *
12 * 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 *
17 * 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 *
22 * 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 */
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 #include "logfile.h"
39 #include "misc.h"
40 #include "users.h" /* get_user_by_handle, readuserfile */
41 #include "dccutil.h" /* dprintf_eggdrop */
42 #include "tcl.h" /* readtclprog */
43 #include "userrec.h" /* count_users, clear_userlist */
44 #include "irccmp.h" /* irccmp */
45
46 extern struct userrec *userlist;
47 extern char ver[], botnetnick[], firewall[],
48 motdfile[], userfile[], helpdir[], tempdir[],
49 moddir[], notify_new[], owner[], configfile[];
50 extern time_t now, online_since;
51 extern int backgrd, term_z, con_chan, cache_hit, cache_miss,
52 firewallport, default_flags, conmask,
53 protect_readonly, make_userfile, noshare,
54 ignore_time;
55
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
62 /* Returns memberfields if the nick is in the member list.
63 */
64 memberlist *ismember(struct chanset_t *chan, char *nick)
65 {
66 register memberlist *x;
67
68 for (x = chan->channel.member; x && x->nick[0]; x = x->next)
69 if (!irccmp(x->nick, nick))
70 return x;
71 return NULL;
72 }
73
74 /* Find a chanset by channel name as the server knows it (ie !ABCDEchannel)
75 */
76 struct chanset_t *findchan(const char *name)
77 {
78 register struct chanset_t *chan;
79
80 for (chan = chanset; chan; chan = chan->next)
81 if (!irccmp(chan->name, name))
82 return chan;
83 return NULL;
84 }
85
86 /* Find a chanset by display name (ie !channel)
87 */
88 struct chanset_t *findchan_by_dname(const char *name)
89 {
90 register struct chanset_t *chan;
91
92 for (chan = chanset; chan; chan = chan->next)
93 if (!irccmp(chan->dname, name))
94 return chan;
95 return NULL;
96 }
97
98 /*
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 struct userrec *check_chanlist(const char *host)
106 {
107 char *nick, *uhost, buf[UHOSTLEN];
108 register memberlist *m;
109 register struct chanset_t *chan;
110
111 strlcpy(buf, host, sizeof buf);
112 nick = strtok(buf, "!");
113 uhost = strtok(NULL, "!");
114 for (chan = chanset; chan; chan = chan->next)
115 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
116 if (!irccmp(nick, m->nick) && !strcasecmp(uhost, m->userhost))
117 return m->user;
118 return NULL;
119 }
120
121 /* Shortcut for get_user_by_handle -- might have user record in channels
122 */
123 struct userrec *check_chanlist_hand(const char *hand)
124 {
125 register struct chanset_t *chan;
126 register memberlist *m;
127
128 for (chan = chanset; chan; chan = chan->next)
129 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
130 if (m->user && !strcasecmp(m->user->handle, hand))
131 return m->user;
132 return NULL;
133 }
134
135 /* 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 void clear_chanlist(void)
141 {
142 register memberlist *m;
143 register struct chanset_t *chan;
144
145 for (chan = chanset; chan; chan = chan->next)
146 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
147 m->user = NULL;
148 }
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 if (!irccmp(m->nick, nick)) {
163 m->user = NULL;
164 break;
165 }
166 }
167
168 /* If this user@host is in a channel, set it (it was null)
169 */
170 void set_chanlist(const char *host, struct userrec *rec)
171 {
172 char *nick, *uhost, buf[UHOSTLEN];
173 register memberlist *m;
174 register struct chanset_t *chan;
175
176 strlcpy(buf, host, sizeof buf);
177 nick = strtok(buf, "!");
178 uhost = strtok(NULL, "!");
179 for (chan = chanset; chan; chan = chan->next)
180 for (m = chan->channel.member; m && m->nick[0]; m = m->next)
181 if (!irccmp(nick, m->nick) && !strcasecmp(uhost, m->userhost))
182 m->user = rec;
183 }
184
185 /* Dump status info out to dcc
186 */
187 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 # if HAVE_CLOCK
197 clock_t cl;
198 # endif
199 #endif
200 #ifdef HAVE_UNAME
201 struct utsname un;
202
203 if (!uname(&un) < 0) {
204 #endif
205 vers_t = " ";
206 uni_t = _("*unknown*");
207 #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 dprintf(idx, _("I am %1$s, running %2$s: "), botnetnick, ver);
216 dprintf(idx, P_("%d user\n", "%d users\n", i), i);
217 dprintf(idx, _("Running on %1$s %2$s\n"), uni_t, vers_t);
218 if (admin[0])
219 dprintf(idx, _("Admin: %s\n"), admin);
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 }
265
266 /* Show all internal state variables
267 */
268 void tell_settings(int idx)
269 {
270 char s[1024];
271 struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
272
273 dprintf(idx, _("Botnet Nickname: %s\n"), botnetnick);
274 if (firewall[0])
275 dprintf(idx, _("Firewall: %1$s, port %2$d\n"), firewall, firewallport);
276 dprintf(idx, _("Userfile: %1$s Motd: %2$s\n"), userfile, motdfile);
277 dprintf(idx, _("Directories:\n"));
278 dprintf(idx, _(" Help : %s\n"), helpdir);
279 dprintf(idx, _(" Temp : %s\n"), tempdir);
280 dprintf(idx, _(" Modules : %s\n"), moddir);
281 fr.global = default_flags;
282
283 build_flags(s, &fr, NULL);
284 dprintf(idx, "%s [%s], %s: %s\n", _("New users get flags"), s,
285 _("notify"), notify_new);
286 /* FIXME PLURAL: handle it properly */
287 if (owner[0])
288 dprintf(idx, _("Permanent owner(s): %s\n"), owner);
289 dprintf(idx, _("Ignores last %d mins\n"), ignore_time);
290 }
291
292 void reaffirm_owners()
293 {
294 char *p, *q, s[121];
295 struct userrec *u;
296
297 /* Make sure default owners are +n */
298 if (owner[0]) {
299 q = owner;
300 p = strchr(q, ',');
301 while (p) {
302 strlcpy(s, q, p - q);
303 rmspace(s);
304 u = get_user_by_handle(userlist, s);
305 if (u)
306 u->flags = sanity_check(u->flags | USER_OWNER);
307 q = p + 1;
308 p = strchr(q, ',');
309 }
310 strcpy(s, q);
311 rmspace(s);
312 u = get_user_by_handle(userlist, s);
313 if (u)
314 u->flags = sanity_check(u->flags | USER_OWNER);
315 }
316 }
317
318 void chanprog()
319 {
320 admin[0] = 0;
321 helpdir[0] = 0;
322 tempdir[0] = 0;
323 conmask = 0;
324 /* Turn off read-only variables (make them write-able) for rehash */
325 protect_readonly = 0;
326 /* Now read it */
327 if (!readtclprog(configfile))
328 fatal(_("CONFIG FILE NOT LOADED (NOT FOUND, OR ERROR)"), 0);
329 /* We should be safe now */
330 call_hook(HOOK_REHASH);
331 protect_readonly = 1;
332 if (!botnetnick[0]) {
333 strlcpy(botnetnick, origbotname, HANDLEN + 1);
334 }
335 if (!botnetnick[0])
336 fatal("I don't have a botnet nick!!\n", 0);
337 if (!userfile[0])
338 fatal(_("STARTING BOT IN USERFILE CREATION MODE.\n\
339 Telnet to the bot and enter 'NEW' as your nickname."), 0);
340 if (!readuserfile(userfile, &userlist)) {
341 if (!make_userfile) {
342 char tmp[178];
343
344 snprintf(tmp, sizeof tmp, _("USER FILE NOT FOUND! (try ./eggdrop -m %s to make one)\n"), configfile);
345 fatal(tmp, 0);
346 }
347 printf(_("\n\nSTARTING BOT IN USERFILE CREATION MODE.\n\
348 Telnet to the bot and enter 'NEW' as your nickname.\n"));
349 if (module_find("server", 0, 0))
350 printf(_("OR go to IRC and type: /msg %s hello\n"), origbotname);
351 printf(_("This will make the bot recognize you as the master.\n\n"));
352 } else if (make_userfile) {
353 make_userfile = 0;
354 printf(_("USERFILE ALREADY EXISTS (drop the -m)\n"));
355 }
356 if (helpdir[0])
357 if (helpdir[strlen(helpdir) - 1] != '/')
358 strcat(helpdir, "/");
359 if (tempdir[0])
360 if (tempdir[strlen(tempdir) - 1] != '/')
361 strcat(tempdir, "/");
362 /* Test tempdir: it's vital */
363 {
364 FILE *f;
365 char s[161], rands[8];
366
367 /* Possible file race condition solved by using a random string
368 * and the process id in the filename.
369 * FIXME: This race is only partitially fixed. We could still be
370 * overwriting an existing file / following a malicious
371 * link.
372 */
373 make_rand_str(rands, 7); /* create random string */
374 sprintf(s, "%s.test-%u-%s", tempdir, getpid(), rands);
375 f = fopen(s, "w");
376 if (f == NULL)
377 fatal(_("CANT WRITE TO TEMP DIR"), 0);
378 fclose(f);
379 unlink(s);
380 }
381 reaffirm_owners();
382 }
383
384 /* Reload the user file from disk
385 */
386 void reload()
387 {
388 FILE *f;
389
390 f = fopen(userfile, "r");
391 if (f == NULL) {
392 putlog(LOG_MISC, "*", _("Cant reload user file!"));
393 return;
394 }
395 fclose(f);
396 noshare = 1;
397 clear_userlist(userlist);
398 noshare = 0;
399 userlist = NULL;
400 if (!readuserfile(userfile, &userlist))
401 fatal(_("User file is missing!"), 0);
402 reaffirm_owners();
403 call_hook(HOOK_READ_USERFILE);
404 }
405
406 void rehash()
407 {
408 call_hook(HOOK_PRE_REHASH);
409 noshare = 1;
410 clear_userlist(userlist);
411 noshare = 0;
412 userlist = NULL;
413 chanprog();
414 }
415
416 /* Oddly enough, written by proton (Emech's coder)
417 */
418 int isowner(char *name)
419 {
420 char *pa, *pb;
421 char nl, pl;
422
423 if (!owner || !*owner)
424 return (0);
425 if (!name || !*name)
426 return (0);
427 nl = strlen(name);
428 pa = owner;
429 pb = owner;
430 while (1) {
431 while (1) {
432 if ((*pb == 0) || (*pb == ',') || (*pb == ' '))
433 break;
434 pb++;
435 }
436 pl = (unsigned int) pb - (unsigned int) pa;
437 if (pl == nl && !strncasecmp(pa, name, nl))
438 return (1);
439 while (1) {
440 if ((*pb == 0) || ((*pb != ',') && (*pb != ' ')))
441 break;
442 pb++;
443 }
444 if (*pb == 0)
445 return (0);
446 pa = pb;
447 }
448 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23