/[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.4 - (show annotations) (download) (as text)
Fri Sep 3 17:21:17 1999 UTC (19 years, 11 months ago) by arthur2
Branch: MAIN
Changes since 1.3: +3 -2 lines
File MIME type: text/x-chdr
setuserfix.patch

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 hand[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(hand, argv[2], HANDLEN);
374 hand[HANDLEN] = 0;
375 for (i = 0; i < strlen(hand); i++)
376 if ((hand[i] <= 32) || (hand[i] >= 127) || (hand[i] == '@'))
377 hand[i] = '?';
378 if (strchr("-,+*=:!.@#;$", hand[0]) != NULL)
379 x = 0;
380 else if (strlen(hand) < 1)
381 x = 0;
382 else if (get_user_by_handle(userlist, hand))
383 x = 0;
384 else if (!strcasecmp(origbotname, hand) || !rfc_casecmp(botnetnick, hand))
385 x = 0;
386 else if (hand[0] == '*')
387 x = 0;
388 }
389 if (x)
390 x = change_handle(u, hand);
391
392 Tcl_AppendResult(irp, x ? "1" : "0", NULL);
393 return TCL_OK;
394 }
395
396 static int tcl_getting_users STDVAR {
397 int i;
398
399 context;
400 BADARGS(1, 1, "");
401 for (i = 0; i < dcc_total; i++) {
402 if ((dcc[i].type == &DCC_BOT) &&
403 (dcc[i].status & STAT_GETTING)) {
404 Tcl_AppendResult(irp, "1", NULL);
405 return TCL_OK;
406 }
407 }
408 Tcl_AppendResult(irp, "0", NULL);
409 return TCL_OK;
410 }
411
412 static int tcl_isignore STDVAR {
413 context;
414 BADARGS(2, 2, " nick!user@host");
415 Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
416 return TCL_OK;
417 }
418
419 static int tcl_newignore STDVAR {
420 time_t expire_time;
421 char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
422
423 context;
424 BADARGS(4, 5, " hostmask creator comment ?lifetime?");
425 strncpy(ign, argv[1], UHOSTLEN - 1);
426 ign[UHOSTLEN - 1] = 0;
427 strncpy(from, argv[2], HANDLEN);
428 from[HANDLEN] = 0;
429 strncpy(cmt, argv[3], 65);
430 cmt[65] = 0;
431 if (argc == 4)
432 expire_time = now + (60 * ignore_time);
433 else {
434 if (atol(argv[4]) == 0)
435 expire_time = 0L;
436 else
437 expire_time = now + (60 * atol(argv[4]));
438 }
439 addignore(ign, from, cmt, expire_time);
440
441 return TCL_OK;
442 }
443
444 static int tcl_killignore STDVAR {
445 context;
446 BADARGS(2, 2, " hostmask");
447 Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
448 return TCL_OK;
449 }
450
451 /* { hostmask note expire-time create-time creator } */
452 static int tcl_ignorelist STDVAR {
453 struct igrec *i;
454 char ts[21], ts1[21], *list[5], *p;
455
456 context;
457 BADARGS(1, 1, "");
458 for (i = global_ign; i; i = i->next) {
459 list[0] = i->igmask;
460 list[1] = i->msg;
461 sprintf(ts, "%lu", i->expire);
462 list[2] = ts;
463 sprintf(ts1, "%lu", i->added);
464 list[3] = ts1;
465 list[4] = i->user;
466 p = Tcl_Merge(5, list);
467 Tcl_AppendElement(irp, p);
468 n_free(p, "", 0);
469 }
470 return TCL_OK;
471 }
472
473 static int tcl_getuser STDVAR {
474 struct user_entry_type *et;
475 struct userrec *u;
476 struct user_entry *e;
477
478 context;
479 BADARGS(3, 999, " handle type");
480 if (!(et = find_entry_type(argv[2]))) {
481 Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
482 return TCL_ERROR;
483 }
484 if (!(u = get_user_by_handle(userlist, argv[1]))) {
485 if (argv[1][0] != '*') {
486 Tcl_AppendResult(irp, "No such user.", NULL);
487 return TCL_ERROR;
488 } else
489 return TCL_OK; /* silently ignore user * */
490 }
491 e = find_user_entry(et, u);
492
493 if (e)
494 return et->tcl_get(irp, u, e, argc, argv);
495 return TCL_OK;
496 }
497
498 static int tcl_setuser STDVAR {
499 struct user_entry_type *et;
500 struct userrec *u;
501 struct user_entry *e;
502 int r;
503
504 context;
505 BADARGS(3, 999, " handle type ?setting....?");
506 if (!(et = find_entry_type(argv[2]))) {
507 Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
508 return TCL_ERROR;
509 }
510 if (!(u = get_user_by_handle(userlist, argv[1]))) {
511 if (argv[1][0] != '*') {
512 Tcl_AppendResult(irp, "No such user.", NULL);
513 return TCL_ERROR;
514 } else
515 return TCL_OK; /* silently ignore user * */
516 }
517 if (!(e = find_user_entry(et, u))) {
518 e = user_malloc(sizeof(struct user_entry));
519
520 e->type = et;
521 e->name = NULL;
522 e->u.list = NULL;
523 list_insert((&(u->entries)), e);
524 }
525 r = et->tcl_set(irp, u, e, argc, argv);
526 /* yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
527 if (!e->u.list) {
528 if (list_delete((struct list_type **) &(u->entries),
529 (struct list_type *) e))
530 nfree(e);
531 /* else maybe already freed... (entry_type==HOSTS) <drummer> */
532 }
533 return r;
534 }
535
536 tcl_cmds tcluser_cmds[] =
537 {
538 {"countusers", tcl_countusers},
539 {"validuser", tcl_validuser},
540 {"finduser", tcl_finduser},
541 {"passwdok", tcl_passwdOk},
542 {"chattr", tcl_chattr},
543 {"botattr", tcl_botattr},
544 {"matchattr", tcl_matchattr},
545 {"matchchanattr", tcl_matchattr},
546 {"adduser", tcl_adduser},
547 {"addbot", tcl_addbot},
548 {"deluser", tcl_deluser},
549 {"delhost", tcl_delhost},
550 {"userlist", tcl_userlist},
551 {"save", tcl_save},
552 {"reload", tcl_reload},
553 {"chnick", tcl_chnick},
554 {"getting-users", tcl_getting_users},
555 {"isignore", tcl_isignore},
556 {"newignore", tcl_newignore},
557 {"killignore", tcl_killignore},
558 {"ignorelist", tcl_ignorelist},
559 {"getuser", tcl_getuser},
560 {"setuser", tcl_setuser},
561 {0, 0}
562 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23