/[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.59 - (show annotations) (download) (as text)
Sun Feb 16 11:15:06 2003 UTC (16 years, 9 months ago) by stdarg
Branch: MAIN
Changes since 1.58: +4 -6 lines
File MIME type: text/x-chdr
* Variables can be linked to config now (auto-update).
* config_str bind for changes to config strings

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23