/[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.12 - (show annotations) (download) (as text)
Mon Jan 17 16:14:45 2000 UTC (19 years, 7 months ago) by per
Branch: MAIN
CVS Tags: eggdrop10402RC1, eggdrop10402
Changes since 1.11: +3 -6 lines
File MIME type: text/x-chdr
relayfix, extern_cleanup

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23