/[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.46 - (show annotations) (download) (as text)
Mon Mar 4 03:55:28 2002 UTC (17 years, 8 months ago) by stdarg
Branch: MAIN
Changes since 1.45: +1 -19 lines
File MIME type: text/x-chdr
* Got rid of .set command
* Moved Tcl info from chanprog.c to tcl module

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23