/[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.7 - (show annotations) (download) (as text)
Wed Oct 27 20:17:42 1999 UTC (20 years, 1 month ago) by guppy
Branch: MAIN
Changes since 1.6: +1 -1 lines
File MIME type: text/x-chdr
patches and patches

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23