/[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.55 - (show annotations) (download) (as text)
Mon Feb 10 00:09:08 2003 UTC (16 years, 5 months ago) by wcc
Branch: MAIN
Changes since 1.54: +3 -6 lines
File MIME type: text/x-chdr
* Synch 1.6: transfer-cleanups, filesys-move, delbancrash, plsbot_cosmetic,
             stricthostfix, opreverselogic, dontdelfile

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23