/[cvs]/eggdrop1.4/src/tcluser.c
ViewVC logotype

Contents of /eggdrop1.4/src/tcluser.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.10 - (show annotations) (download) (as text)
Wed Dec 15 02:32:58 1999 UTC (19 years, 8 months ago) by guppy
Branch: MAIN
Changes since 1.9: +21 -8 lines
File MIME type: text/x-chdr
id-header patch, finally, we have id tags for each file

1 /*
2 * tcluser.c -- handles:
3 * Tcl stubs for the user-record-oriented commands
4 *
5 * dprintf'ized, 1aug1996
6 *
7 * $Id$
8 */
9 /*
10 * Copyright (C) 1997 Robey Pointer
11 * Copyright (C) 1999 Eggheads
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 #include "main.h"
29 #include "users.h"
30 #include "chan.h"
31 #include "tandem.h"
32
33 /* eggdrop always uses the same interpreter */
34 extern Tcl_Interp *interp;
35 extern struct userrec *userlist;
36 extern int default_flags;
37 extern struct dcc_t *dcc;
38 extern int dcc_total;
39 extern char origbotname[];
40 extern char botnetnick[];
41 extern int ignore_time;
42 extern time_t now;
43
44 /***********************************************************************/
45
46 static int tcl_countusers STDVAR {
47 Context;
48 BADARGS(1, 1, "");
49 Tcl_AppendResult(irp, int_to_base10(count_users(userlist)), NULL);
50 return TCL_OK;
51 }
52
53 static int tcl_validuser STDVAR {
54 Context;
55 BADARGS(2, 2, " handle");
56 Tcl_AppendResult(irp, get_user_by_handle(userlist, argv[1]) ? "1" : "0",
57 NULL);
58 return TCL_OK;
59 }
60 static int tcl_finduser STDVAR {
61 struct userrec *u;
62
63 Context;
64 BADARGS(2, 2, " nick!user@host");
65 u = get_user_by_host(argv[1]);
66 Tcl_AppendResult(irp, u ? u->handle : "*", NULL);
67 return TCL_OK;
68 }
69
70 static int tcl_passwdOk STDVAR {
71 struct userrec *u;
72
73 Context;
74 BADARGS(3, 3, " handle passwd");
75 Tcl_AppendResult(irp, ((u = get_user_by_handle(userlist, argv[1])) &&
76 u_pass_match(u, argv[2])) ? "1" : "0", NULL);
77 return TCL_OK;
78 }
79
80 static int tcl_chattr STDVAR {
81 char *chan, *chg, work[100];
82 struct flag_record pls, mns, user;
83 struct userrec *u;
84
85 Context;
86 BADARGS(2, 4, " handle ?changes? ?channel?");
87 if ((argv[1][0] == '*') || !(u = get_user_by_handle(userlist, argv[1]))) {
88 Tcl_AppendResult(irp, "*", NULL);
89 return TCL_OK;
90 }
91 if (argc == 4) {
92 user.match = FR_GLOBAL | FR_CHAN;
93 chan = argv[3];
94 chg = argv[2];
95 } else if ((argc == 3)
96 && (argv[2][0] && (strchr(CHANMETA, argv[2][0]) != NULL))) {
97 /* We need todo extra checking here to stop us mixing up +channel's
98 * with flags. <cybah> */
99 if (!findchan(argv[2]) && argv[2][0] != '+') {
100 /* Channel doesnt exist, and it cant possibly be flags as there
101 * is no + at the start of the string. */
102 Tcl_AppendResult(irp, "no such channel", NULL);
103 return TCL_ERROR;
104 } else if(findchan(argv[2])) {
105 /* Channel exists */
106 user.match = FR_GLOBAL | FR_CHAN;
107 chan = argv[2];
108 chg = NULL;
109 } else {
110 /* 3rd possibility... channel doesnt exist, does start with a +.
111 * In this case we assume the string is flags. */
112 user.match = FR_GLOBAL;
113 chan = NULL;
114 chg = argv[2];
115 }
116 } else {
117 user.match = FR_GLOBAL;
118 chan = NULL;
119 chg = argv[2];
120 }
121 if (chan && !findchan(chan)) {
122 Tcl_AppendResult(irp, "no such channel", NULL);
123 return TCL_ERROR;
124 }
125 get_user_flagrec(u, &user, chan);
126 /* make changes */
127 if (chg) {
128 pls.match = user.match;
129 break_down_flags(chg, &pls, &mns);
130 /* no-one can change these flags on-the-fly */
131 pls.global &=~(USER_BOT);
132 mns.global &=~(USER_BOT);
133 if (chan) {
134 pls.chan &= ~(BOT_SHARE);
135 mns.chan &= ~(BOT_SHARE);
136 }
137 user.global = sanity_check((user.global |pls.global) &~mns.global);
138 user.udef_global = (user.udef_global | pls.udef_global)
139 & ~mns.udef_global;
140 if (chan) {
141 user.chan = chan_sanity_check((user.chan | pls.chan) & ~mns.chan,
142 user.global);
143 user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
144 }
145 set_user_flagrec(u, &user, chan);
146 }
147 /* retrieve current flags and return them */
148 build_flags(work, &user, NULL);
149 Tcl_AppendResult(irp, work, NULL);
150 return TCL_OK;
151 }
152
153 static int tcl_botattr STDVAR {
154 char *chan, *chg, work[100];
155 struct flag_record pls, mns, user;
156 struct userrec *u;
157
158 Context;
159 BADARGS(2, 4, " bot-handle ?changes? ?channel?");
160 u = get_user_by_handle(userlist, argv[1]);
161 if ((argv[1][0] == '*') || !u || !(u->flags & USER_BOT)) {
162 Tcl_AppendResult(irp, "*", NULL);
163 return TCL_OK;
164 }
165 if (argc == 4) {
166 user.match = FR_BOT | FR_CHAN;
167 chan = argv[3];
168 chg = argv[2];
169 } else if ((argc == 3)
170 && (argv[2][0] && (strchr(CHANMETA, argv[2][0]) != NULL))) {
171 /* We need todo extra checking here to stop us mixing up +channel's
172 * with flags. <cybah> */
173 if (!findchan(argv[2]) && argv[2][0] != '+') {
174 /* Channel doesnt exist, and it cant possibly be flags as there
175 * is no + at the start of the string. */
176 Tcl_AppendResult(irp, "no such channel", NULL);
177 return TCL_ERROR;
178 } else if(findchan(argv[2])) {
179 /* Channel exists */
180 user.match = FR_BOT | FR_CHAN;
181 chan = argv[2];
182 chg = NULL;
183 } else {
184 /* 3rd possibility... channel doesnt exist, does start with a +.
185 * In this case we assume the string is flags. */
186 user.match = FR_BOT;
187 chan = NULL;
188 chg = argv[2];
189 }
190 } else {
191 user.match = FR_BOT;
192 chan = NULL;
193 chg = argv[2];
194 }
195 if (chan && !findchan(chan)) {
196 Tcl_AppendResult(irp, "no such channel", NULL);
197 return TCL_ERROR;
198 }
199 get_user_flagrec(u, &user, chan);
200 /* make changes */
201 if (chg) {
202 pls.match = user.match;
203 break_down_flags(chg, &pls, &mns);
204 /* no-one can change these flags on-the-fly */
205 if (chan) {
206 pls.chan &= BOT_SHARE;
207 mns.chan &= BOT_SHARE;
208 }
209 user.bot = sanity_check((user.bot | pls.bot) & ~mns.bot);
210 if (chan) {
211 user.chan = chan_sanity_check((user.chan | pls.chan) & ~mns.chan,
212 user.global);
213 user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
214 }
215 set_user_flagrec(u, &user, chan);
216 }
217 /* retrieve current flags and return them */
218 build_flags(work, &user, NULL);
219 Tcl_AppendResult(irp, work, NULL);
220 return TCL_OK;
221 }
222
223 static int tcl_matchattr STDVAR {
224 struct userrec *u;
225 struct flag_record plus, minus, user;
226 int ok = 0, f;
227
228 Context;
229 BADARGS(3, 4, " handle flags ?channel?");
230 Context; /* a2 - Last context: tcluser.c/184 */
231 if ((u = get_user_by_handle(userlist, argv[1])) &&
232 ((argc == 3) || findchan(argv[3]))) {
233 Context; /* a2 - Last context: tcluser.c/184 */
234 user.match = FR_GLOBAL | (argc == 4 ? FR_CHAN : 0) | FR_BOT;
235 get_user_flagrec(u, &user, argv[3]);
236 plus.match = user.match;
237 break_down_flags(argv[2], &plus, &minus);
238 f = (minus.global || minus.udef_global || minus.chan ||
239 minus.udef_chan || minus.bot);
240 if (flagrec_eq(&plus, &user)) {
241 Context; /* a2 - Last context: tcluser.c/184 */
242 if (!f)
243 ok = 1;
244 else {
245 minus.match = plus.match ^ (FR_AND | FR_OR);
246 if (!flagrec_eq(&minus, &user))
247 ok = 1;
248 }
249 }
250 }
251 Context; /* a2 - Last context: tcluser.c/184 */
252 Tcl_AppendResult(irp, ok ? "1" : "0", NULL);
253 return TCL_OK;
254 }
255
256 static int tcl_adduser STDVAR {
257 Context;
258 BADARGS(2, 3, " handle ?hostmask?");
259 if (strlen(argv[1]) > HANDLEN)
260 argv[1][HANDLEN] = 0;
261 if ((argv[1][0] == '*') || get_user_by_handle(userlist, argv[1]))
262 Tcl_AppendResult(irp, "0", NULL);
263 else {
264 userlist = adduser(userlist, argv[1], argv[2], "-", default_flags);
265 Tcl_AppendResult(irp, "1", NULL);
266 }
267 return TCL_OK;
268 }
269
270 static int tcl_addbot STDVAR {
271 struct bot_addr *bi;
272 char *p, *q;
273
274 Context;
275 BADARGS(3, 3, " handle address");
276 if (strlen(argv[1]) > HANDLEN)
277 argv[1][HANDLEN] = 0;
278 if (get_user_by_handle(userlist, argv[1]))
279 Tcl_AppendResult(irp, "0", NULL);
280 else if (argv[1][0] == '*')
281 Tcl_AppendResult(irp, "0", NULL);
282 else {
283 userlist = adduser(userlist, argv[1], "none", "-", USER_BOT);
284 bi = user_malloc(sizeof(struct bot_addr));
285 q = strchr(argv[2], ':');
286 if (!q) {
287 bi->address = user_malloc(strlen(argv[2]) + 1);
288 strcpy(bi->address, argv[2]);
289 bi->telnet_port = 3333;
290 bi->relay_port = 3333;
291 } else {
292 bi->address = user_malloc(q - argv[2] + 1);
293 strncpy(bi->address, argv[2], q - argv[2]);
294 bi->address[q - argv[2]] = 0;
295 p = q + 1;
296 bi->telnet_port = atoi(p);
297 q = strchr(p, '/');
298 if (!q)
299 bi->relay_port = bi->telnet_port;
300 else
301 bi->relay_port = atoi(q + 1);
302 }
303 set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, argv[1]), bi);
304 Tcl_AppendResult(irp, "1", NULL);
305 }
306 return TCL_OK;
307 }
308
309 static int tcl_deluser STDVAR {
310 Context;
311 BADARGS(2, 2, " handle");
312 Tcl_AppendResult(irp, (argv[1][0] == '*') ? "0" :
313 int_to_base10(deluser(argv[1])), NULL);
314 return TCL_OK;
315 }
316
317 static int tcl_delhost STDVAR {
318 Context;
319 BADARGS(3, 3, " handle hostmask");
320 if ((!get_user_by_handle(userlist, argv[1])) || (argv[1][0] == '*')) {
321 Tcl_AppendResult(irp, "non-existent user", NULL);
322 return TCL_ERROR;
323 }
324 Tcl_AppendResult(irp, delhost_by_handle(argv[1], argv[2]) ? "1" : "0",
325 NULL);
326 return TCL_OK;
327 }
328
329 static int tcl_userlist STDVAR {
330 struct userrec *u = userlist;
331 struct flag_record user, plus, minus;
332 int ok = 1, f = 0;
333
334 Context;
335 BADARGS(1, 3, " ?flags ?channel??");
336 if ((argc == 3) && !findchan(argv[2])) {
337 Tcl_AppendResult(irp, "Invalid channel: ", argv[2], NULL);
338 return TCL_ERROR;
339 }
340 if (argc >= 2) {
341 plus.match = FR_GLOBAL | FR_CHAN | FR_BOT;
342 break_down_flags(argv[1], &plus, &minus);
343 f = (minus.global || minus.udef_global || minus.chan ||
344 minus.udef_chan || minus.bot);
345 }
346 minus.match = plus.match ^ (FR_AND | FR_OR);
347 while (u) {
348 if (argc >= 2) {
349 user.match = FR_GLOBAL | FR_CHAN | FR_BOT | (argc == 3 ? 0 : FR_ANYWH);
350 get_user_flagrec(u, &user, argv[2]); /* argv[2] == NULL for argc = 2 ;) */
351 if (flagrec_eq(&plus, &user) && !(f && flagrec_eq(&minus, &user)))
352 ok = 1;
353 else
354 ok = 0;
355 }
356 if (ok)
357 Tcl_AppendElement(interp, u->handle);
358 u = u->next;
359 }
360 return TCL_OK;
361 }
362
363 static int tcl_save STDVAR {
364 Context;
365 write_userfile(-1);
366 return TCL_OK;
367 }
368
369 static int tcl_reload STDVAR {
370 Context;
371 reload();
372 return TCL_OK;
373 }
374
375 static int tcl_chnick STDVAR {
376 struct userrec *u;
377 char newhand[HANDLEN + 1];
378 int x = 1, i;
379
380 Context;
381 BADARGS(3, 3, " oldnick newnick");
382 u = get_user_by_handle(userlist, argv[1]);
383 if (!u)
384 x = 0;
385 else {
386 strncpy(newhand, argv[2], HANDLEN);
387 newhand[HANDLEN] = 0;
388 for (i = 0; i < strlen(newhand); i++)
389 if ((newhand[i] <= 32) || (newhand[i] >= 127) || (newhand[i] == '@'))
390 newhand[i] = '?';
391 if (strchr(BADHANDCHARS, newhand[0]) != NULL)
392 x = 0;
393 else if (strlen(newhand) < 1)
394 x = 0;
395 else if (get_user_by_handle(userlist, newhand))
396 x = 0;
397 else if (!strcasecmp(botnetnick, newhand) &&
398 (!(u->flags & USER_BOT) || nextbot (argv [1]) != -1))
399 x = 0;
400 else if (newhand[0] == '*')
401 x = 0;
402 }
403 if (x)
404 x = change_handle(u, newhand);
405
406 Tcl_AppendResult(irp, x ? "1" : "0", NULL);
407 return TCL_OK;
408 }
409
410 static int tcl_getting_users STDVAR {
411 int i;
412
413 Context;
414 BADARGS(1, 1, "");
415 for (i = 0; i < dcc_total; i++) {
416 if ((dcc[i].type == &DCC_BOT) &&
417 (dcc[i].status & STAT_GETTING)) {
418 Tcl_AppendResult(irp, "1", NULL);
419 return TCL_OK;
420 }
421 }
422 Tcl_AppendResult(irp, "0", NULL);
423 return TCL_OK;
424 }
425
426 static int tcl_isignore STDVAR {
427 Context;
428 BADARGS(2, 2, " nick!user@host");
429 Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
430 return TCL_OK;
431 }
432
433 static int tcl_newignore STDVAR {
434 time_t expire_time;
435 char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
436
437 Context;
438 BADARGS(4, 5, " hostmask creator comment ?lifetime?");
439 strncpy(ign, argv[1], UHOSTMAX);
440 ign[UHOSTMAX] = 0;
441 strncpy(from, argv[2], HANDLEN);
442 from[HANDLEN] = 0;
443 strncpy(cmt, argv[3], 65);
444 cmt[65] = 0;
445 if (argc == 4)
446 expire_time = now + (60 * ignore_time);
447 else {
448 if (atol(argv[4]) == 0)
449 expire_time = 0L;
450 else
451 expire_time = now + (60 * atol(argv[4]));
452 }
453 addignore(ign, from, cmt, expire_time);
454
455 return TCL_OK;
456 }
457
458 static int tcl_killignore STDVAR {
459 Context;
460 BADARGS(2, 2, " hostmask");
461 Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
462 return TCL_OK;
463 }
464
465 /* { hostmask note expire-time create-time creator } */
466 static int tcl_ignorelist STDVAR {
467 struct igrec *i;
468 char ts[21], ts1[21], *list[5], *p;
469
470 Context;
471 BADARGS(1, 1, "");
472 for (i = global_ign; i; i = i->next) {
473 list[0] = i->igmask;
474 list[1] = i->msg;
475 sprintf(ts, "%lu", i->expire);
476 list[2] = ts;
477 sprintf(ts1, "%lu", i->added);
478 list[3] = ts1;
479 list[4] = i->user;
480 p = Tcl_Merge(5, list);
481 Tcl_AppendElement(irp, p);
482 Tcl_Free((char *) p);
483 }
484 return TCL_OK;
485 }
486
487 static int tcl_getuser STDVAR {
488 struct user_entry_type *et;
489 struct userrec *u;
490 struct user_entry *e;
491
492 Context;
493 BADARGS(3, 999, " handle type");
494 if (!(et = find_entry_type(argv[2]))) {
495 Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
496 return TCL_ERROR;
497 }
498 if (!(u = get_user_by_handle(userlist, argv[1]))) {
499 if (argv[1][0] != '*') {
500 Tcl_AppendResult(irp, "No such user.", NULL);
501 return TCL_ERROR;
502 } else
503 return TCL_OK; /* silently ignore user * */
504 }
505 e = find_user_entry(et, u);
506
507 if (e)
508 return et->tcl_get(irp, u, e, argc, argv);
509 return TCL_OK;
510 }
511
512 static int tcl_setuser STDVAR {
513 struct user_entry_type *et;
514 struct userrec *u;
515 struct user_entry *e;
516 int r;
517
518 Context;
519 BADARGS(3, 999, " handle type ?setting....?");
520 if (!(et = find_entry_type(argv[2]))) {
521 Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
522 return TCL_ERROR;
523 }
524 if (!(u = get_user_by_handle(userlist, argv[1]))) {
525 if (argv[1][0] != '*') {
526 Tcl_AppendResult(irp, "No such user.", NULL);
527 return TCL_ERROR;
528 } else
529 return TCL_OK; /* silently ignore user * */
530 }
531 if (!(e = find_user_entry(et, u))) {
532 e = user_malloc(sizeof(struct user_entry));
533
534 e->type = et;
535 e->name = NULL;
536 e->u.list = NULL;
537 list_insert((&(u->entries)), e);
538 }
539 r = et->tcl_set(irp, u, e, argc, argv);
540 /* yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
541 if (!e->u.list) {
542 if (list_delete((struct list_type **) &(u->entries),
543 (struct list_type *) e))
544 nfree(e);
545 /* else maybe already freed... (entry_type==HOSTS) <drummer> */
546 }
547 return r;
548 }
549
550 tcl_cmds tcluser_cmds[] =
551 {
552 {"countusers", tcl_countusers},
553 {"validuser", tcl_validuser},
554 {"finduser", tcl_finduser},
555 {"passwdok", tcl_passwdOk},
556 {"chattr", tcl_chattr},
557 {"botattr", tcl_botattr},
558 {"matchattr", tcl_matchattr},
559 {"matchchanattr", tcl_matchattr},
560 {"adduser", tcl_adduser},
561 {"addbot", tcl_addbot},
562 {"deluser", tcl_deluser},
563 {"delhost", tcl_delhost},
564 {"userlist", tcl_userlist},
565 {"save", tcl_save},
566 {"reload", tcl_reload},
567 {"chnick", tcl_chnick},
568 {"getting-users", tcl_getting_users},
569 {"isignore", tcl_isignore},
570 {"newignore", tcl_newignore},
571 {"killignore", tcl_killignore},
572 {"ignorelist", tcl_ignorelist},
573 {"getuser", tcl_getuser},
574 {"setuser", tcl_setuser},
575 {0, 0}
576 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23