/[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.57 - (show annotations) (download) (as text)
Fri Feb 14 20:55:02 2003 UTC (16 years, 5 months ago) by stdarg
Branch: MAIN
Changes since 1.56: +2 -9 lines
File MIME type: text/x-chdr
* Added autoload section to xml config file and got rid of the -p option (preload).
* To load your old config file, rename it to blah.tcl and put <script>blah.tcl</script> in the autoload section.
* Added sample config.xml and config.tcl files.
* Moved some more script functions to the script module.

1 /* * chanprog.c --
2 *
3 * telling the current programmed settings
4 * initializing a lot of stuff and loading the tcl scripts
5 */
6 /*
7 * Copyright (C) 1997 Robey Pointer
8 * Copyright (C) 1999, 2000, 2001, 2002, 2003 Eggheads Development Team
9 *
10 * 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 *
15 * 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 *
20 * 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 */
24
25 #ifndef lint
26 static const char rcsid[] = "$Id: chanprog.c,v 1.56 2003/02/11 02:32:05 stdarg Exp $";
27 #endif
28
29 #include "main.h"
30 #include "core_config.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[], 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: "), core_config.botname, 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"), core_config.botname);
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 call_hook(HOOK_REHASH);
328 if (!core_config.botname)
329 fatal("Please set the myname setting.\n", 0);
330 if (!userfile[0])
331 fatal(_("STARTING BOT IN USERFILE CREATION MODE.\n\
332 Telnet to the bot and enter 'NEW' as your nickname."), 0);
333 if (!readuserfile(userfile, &userlist)) {
334 if (!make_userfile) {
335 char tmp[178];
336
337 snprintf(tmp, sizeof tmp, _("USER FILE NOT FOUND! (try ./eggdrop -m %s to make one)\n"), configfile);
338 fatal(tmp, 0);
339 }
340 printf(_("\n\nSTARTING BOT IN USERFILE CREATION MODE.\n\
341 Telnet to the bot and enter 'NEW' as your nickname.\n"));
342 if (module_find("server", 0, 0))
343 printf(_("OR go to IRC and type: /msg %s hello\n"), core_config.botname);
344 printf(_("This will make the bot recognize you as the master.\n\n"));
345 } else if (make_userfile) {
346 make_userfile = 0;
347 printf(_("USERFILE ALREADY EXISTS (drop the -m)\n"));
348 }
349 if (helpdir[0])
350 if (helpdir[strlen(helpdir) - 1] != '/')
351 strcat(helpdir, "/");
352 if (tempdir[0])
353 if (tempdir[strlen(tempdir) - 1] != '/')
354 strcat(tempdir, "/");
355 /* Test tempdir: it's vital */
356 {
357 FILE *f;
358 char s[161], rands[8];
359
360 /* Possible file race condition solved by using a random string
361 * and the process id in the filename.
362 * FIXME: This race is only partitially fixed. We could still be
363 * overwriting an existing file / following a malicious
364 * link.
365 */
366 make_rand_str(rands, 7); /* create random string */
367 sprintf(s, "%s.test-%u-%s", tempdir, getpid(), rands);
368 f = fopen(s, "w");
369 if (f == NULL)
370 fatal(_("CANT WRITE TO TEMP DIR"), 0);
371 fclose(f);
372 unlink(s);
373 }
374 reaffirm_owners();
375 }
376
377 /* Reload the user file from disk
378 */
379 void reload()
380 {
381 if (!file_readable(userfile)) {
382 putlog(LOG_MISC, "*", _("Cant reload user file!"));
383 return;
384 }
385
386 noshare = 1;
387 clear_userlist(userlist);
388 noshare = 0;
389 userlist = NULL;
390 if (!readuserfile(userfile, &userlist))
391 fatal(_("User file is missing!"), 0);
392 reaffirm_owners();
393 call_hook(HOOK_READ_USERFILE);
394 }
395
396 void rehash()
397 {
398 call_hook(HOOK_PRE_REHASH);
399 noshare = 1;
400 clear_userlist(userlist);
401 noshare = 0;
402 userlist = NULL;
403 chanprog();
404 }
405
406 /* Oddly enough, written by proton (Emech's coder)
407 */
408 int isowner(char *name)
409 {
410 char *pa, *pb;
411 char nl, pl;
412
413 if (!owner || !*owner)
414 return (0);
415 if (!name || !*name)
416 return (0);
417 nl = strlen(name);
418 pa = owner;
419 pb = owner;
420 while (1) {
421 while (1) {
422 if ((*pb == 0) || (*pb == ',') || (*pb == ' '))
423 break;
424 pb++;
425 }
426 pl = (unsigned int) pb - (unsigned int) pa;
427 if (pl == nl && !strncasecmp(pa, name, nl))
428 return (1);
429 while (1) {
430 if ((*pb == 0) || ((*pb != ',') && (*pb != ' ')))
431 break;
432 pb++;
433 }
434 if (*pb == 0)
435 return (0);
436 pa = pb;
437 }
438 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23