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

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

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


Revision 1.1.1.1 - (show annotations) (download) (as text) (vendor branch)
Wed Jun 23 19:51:32 1999 UTC (22 years, 4 months ago) by segfault
Branch: eggdev
CVS Tags: start
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Eggdrop 1.3.28 CVS Code

1 /*
2 * tclhash.c -- rewritten tclhash.c & hash.c, handles (from tclhash.c):
3 * bind and unbind
4 * checking and triggering the various in-bot bindings
5 * listing current bindings
6 * adding/removing new binding tables
7 *
8 * dprintf'ized, 4feb1996
9 * Now includes FREE OF CHARGE everything from hash.c, 'cause they
10 * were exporting functions to each other and only for each other.
11 *
12 * hash.c -- handles:
13 * (non-Tcl) procedure lookups for msg/dcc/file commands
14 * (Tcl) binding internal procedures to msg/dcc/file commands
15 *
16 * dprintf'ized, 15nov1995
17 */
18 /*
19 * This file is part of the eggdrop source code
20 * copyright (c) 1997 Robey Pointer
21 * and is distributed according to the GNU general public license.
22 * For full details, read the top of 'main.c' or the file called
23 * COPYING that was distributed with this code.
24 */
25
26 #include "main.h"
27 #include "chan.h"
28 #include "users.h"
29 #include "match.c"
30
31 extern Tcl_Interp *interp;
32 extern struct dcc_t *dcc;
33 extern struct userrec *userlist;
34 extern int debug_tcl;
35 extern int dcc_total;
36 extern time_t now;
37
38 static p_tcl_bind_list bind_table_list;
39 p_tcl_bind_list H_chat, H_act, H_bcst, H_chon, H_chof;
40 p_tcl_bind_list H_load, H_unld, H_link, H_disc, H_dcc, H_chjn, H_chpt;
41 p_tcl_bind_list H_bot, H_time, H_nkch, H_away, H_note, H_filt, H_event;
42
43 static int builtin_2char();
44 static int builtin_3char();
45 static int builtin_5int();
46 static int builtin_char();
47 static int builtin_chpt();
48 static int builtin_chjn();
49 static int builtin_idxchar();
50 static int builtin_charidx();
51 static int builtin_chat();
52 static int builtin_dcc();
53
54 int expmem_tclhash()
55 {
56 struct tcl_bind_list *p = bind_table_list;
57 struct tcl_bind_mask *q;
58 tcl_cmd_t *c;
59 int tot = 0;
60
61 while (p) {
62 tot += sizeof(struct tcl_bind_list);
63
64 for (q = p->first; q; q = q->next) {
65 tot += sizeof(struct tcl_bind_mask);
66
67 tot += strlen(q->mask) + 1;
68 for (c = q->first; c; c = c->next) {
69 tot += sizeof(tcl_cmd_t);
70 tot += strlen(c->func_name) + 1;
71 }
72 }
73 p = p->next;
74 }
75 return tot;
76 }
77
78 extern cmd_t C_dcc[], C_dcc_irc[], C_fil[]; /* wtf ??? */
79 static int tcl_bind();
80
81 void init_bind()
82 {
83 bind_table_list = NULL;
84 context;
85 Tcl_CreateCommand(interp, "bind", tcl_bind, (ClientData) 0, NULL);
86 Tcl_CreateCommand(interp, "unbind", tcl_bind, (ClientData) 1, NULL);
87 H_unld = add_bind_table("unld", HT_STACKABLE, builtin_char);
88 H_time = add_bind_table("time", HT_STACKABLE, builtin_5int);
89 H_note = add_bind_table("note", 0, builtin_3char);
90 H_nkch = add_bind_table("nkch", HT_STACKABLE, builtin_2char);
91 H_load = add_bind_table("load", HT_STACKABLE, builtin_char);
92 H_link = add_bind_table("link", HT_STACKABLE, builtin_2char);
93 H_filt = add_bind_table("filt", HT_STACKABLE, builtin_idxchar);
94 H_disc = add_bind_table("disc", HT_STACKABLE, builtin_char);
95 H_dcc = add_bind_table("dcc", 0, builtin_dcc);
96 H_chpt = add_bind_table("chpt", HT_STACKABLE, builtin_chpt);
97 H_chon = add_bind_table("chon", HT_STACKABLE, builtin_charidx);
98 H_chof = add_bind_table("chof", HT_STACKABLE, builtin_charidx);
99 H_chjn = add_bind_table("chjn", HT_STACKABLE, builtin_chjn);
100 H_chat = add_bind_table("chat", HT_STACKABLE, builtin_chat);
101 H_bot = add_bind_table("bot", 0, builtin_3char);
102 H_bcst = add_bind_table("bcst", HT_STACKABLE, builtin_chat);
103 H_away = add_bind_table("away", HT_STACKABLE, builtin_chat);
104 H_act = add_bind_table("act", HT_STACKABLE, builtin_chat);
105 context;
106 H_event = add_bind_table("evnt", HT_STACKABLE, builtin_char);
107 add_builtins(H_dcc, C_dcc, 65);
108 }
109
110 void kill_bind()
111 {
112 rem_builtins(H_dcc, C_dcc, 65);
113 while (bind_table_list) {
114 del_bind_table(bind_table_list);
115 }
116 }
117
118 p_tcl_bind_list add_bind_table(char *nme, int flg, Function f)
119 {
120 p_tcl_bind_list p = bind_table_list, o = NULL;
121
122 if (strlen(nme) > 4)
123 nme[4] = 0;
124 while (p) {
125 int v = strcasecmp(p->name, nme);
126
127 if (v == 0)
128 /* repeat, just return old value */
129 return p;
130 /* insert at start of list */
131 if (v > 0) {
132 break;
133 } else {
134 o = p;
135 p = p->next;
136 }
137 }
138 p = nmalloc(sizeof(struct tcl_bind_list));
139
140 p->first = NULL;
141 strcpy(p->name, nme);
142 p->flags = flg;
143 p->func = f;
144 if (o) {
145 p->next = o->next;
146 o->next = p;
147 } else {
148 p->next = bind_table_list;
149 bind_table_list = p;
150 }
151 putlog(LOG_DEBUG, "*", "Allocated bind table %s (flags %d)", nme, flg);
152 return p;
153 }
154
155 void del_bind_table(p_tcl_bind_list which)
156 {
157 p_tcl_bind_list p = bind_table_list, o = NULL;
158
159 while (p) {
160 if (p == which) {
161 tcl_cmd_t *tt, *tt1;
162 struct tcl_bind_mask *ht, *ht1;
163
164 if (o) {
165 o->next = p->next;
166 } else {
167 bind_table_list = p->next;
168 }
169 /* cleanup code goes here */
170 for (ht = p->first; ht; ht = ht1) {
171 ht1 = ht->next;
172 for (tt = ht->first; tt; tt = tt1) {
173 tt1 = tt->next;
174 nfree(tt->func_name);
175 nfree(tt);
176 }
177 nfree(ht->mask);
178 nfree(ht);
179 }
180 putlog(LOG_DEBUG, "*", "De-Allocated bind table %s", p->name);
181 nfree(p);
182 return;
183 }
184 o = p;
185 p = p->next;
186 }
187 putlog(LOG_DEBUG, "*", "??? Tried to delete no listed bind table ???");
188 }
189
190 p_tcl_bind_list find_bind_table(char *nme)
191 {
192 p_tcl_bind_list p = bind_table_list;
193
194 while (p) {
195 int v = strcasecmp(p->name, nme);
196
197 if (v == 0)
198 return p;
199 if (v > 0)
200 return NULL;
201 p = p->next;
202 }
203 return NULL;
204 }
205
206 static void dump_bind_tables(Tcl_Interp * irp)
207 {
208 p_tcl_bind_list p = bind_table_list;
209 int i = 0;
210
211 while (p) {
212 if (i)
213 Tcl_AppendResult(irp, ", ", NULL);
214 else
215 i++;
216 Tcl_AppendResult(irp, p->name, NULL);
217 p = p->next;
218 }
219 }
220
221 static int unbind_bind_entry(p_tcl_bind_list typ, char *flags, char *cmd,
222 char *proc)
223 {
224 tcl_cmd_t *tt, *last;
225 struct tcl_bind_mask *ma, *ma1 = NULL;
226
227 for (ma = typ->first; ma; ma = ma->next) {
228 int i = strcmp(cmd, ma->mask);
229
230 if (!i)
231 break; /* found it! fall out! */
232 ma1 = ma;
233 }
234 if (ma) {
235 last = NULL;
236 for (tt = ma->first; tt; tt = tt->next) {
237 /* if procs are same, erase regardless of flags */
238 if (!strcasecmp(tt->func_name, proc)) {
239 /* erase it */
240 if (last) {
241 last->next = tt->next;
242 } else if (tt->next) {
243 ma->first = tt->next;
244 } else {
245 if (ma1)
246 ma1->next = ma->next;
247 else
248 typ->first = ma->next;
249 nfree(ma->mask);
250 nfree(ma);
251 }
252 nfree(tt->func_name);
253 nfree(tt);
254 return 1;
255 }
256 last = tt;
257 }
258 }
259 return 0; /* no match */
260 }
261
262 /* add command (remove old one if necessary) */
263 static int bind_bind_entry(p_tcl_bind_list typ, char *flags, char *cmd,
264 char *proc)
265 {
266 tcl_cmd_t *tt;
267 struct tcl_bind_mask *ma, *ma1 = NULL;
268
269 if (proc[0] == '#') {
270 putlog(LOG_MISC, "*", "Note: binding to '#' is obsolete.");
271 return 0;
272 }
273 context;
274 for (ma = typ->first; ma; ma = ma->next) {
275 int i = strcmp(cmd, ma->mask);
276
277 if (!i)
278 break; /* found it! fall out! */
279 ma1 = ma;
280 }
281 context;
282 if (!ma) {
283 ma = nmalloc(sizeof(struct tcl_bind_mask));
284
285 ma->mask = nmalloc(strlen(cmd) + 1);
286 strcpy(ma->mask, cmd);
287 ma->first = NULL;
288 ma->next = typ->first;
289 typ->first = ma;
290 }
291 context;
292 for (tt = ma->first; tt; tt = tt->next) {
293 /* already defined? if so replace */
294 if (!strcasecmp(tt->func_name, proc)) {
295 tt->flags.match = FR_GLOBAL | FR_CHAN;
296 break_down_flags(flags, &(tt->flags), NULL);
297 return 1;
298 }
299 }
300 context;
301 if (!(typ->flags & HT_STACKABLE) && ma->first) {
302 nfree(ma->first->func_name);
303 nfree(ma->first);
304 ma->first = NULL;
305 }
306 context;
307 tt = nmalloc(sizeof(tcl_cmd_t));
308 tt->func_name = nmalloc(strlen(proc) + 1);
309 tt->next = NULL;
310 tt->hits = 0;
311 tt->flags.match = FR_GLOBAL | FR_CHAN;
312 break_down_flags(flags, &(tt->flags), NULL);
313 strcpy(tt->func_name, proc);
314 tt->next = ma->first;
315 ma->first = tt;
316 context;
317 return 1;
318 }
319
320 static int tcl_getbinds(p_tcl_bind_list kind, char *name)
321 {
322 tcl_cmd_t *tt;
323 struct tcl_bind_mask *be;
324
325 for (be = kind->first; be; be = be->next) {
326 if (!strcasecmp(be->mask, name)) {
327 for (tt = be->first; tt; tt = tt->next)
328 Tcl_AppendElement(interp, tt->func_name);
329 return TCL_OK;
330 }
331 }
332 return TCL_OK;
333 }
334
335 static int tcl_bind STDVAR
336 {
337 p_tcl_bind_list tp;
338
339 if ((long int) cd == 1) {
340 BADARGS(5, 5, " type flags cmd/mask procname")
341 } else {
342 BADARGS(4, 5, " type flags cmd/mask ?procname?")
343 }
344 tp = find_bind_table(argv[1]);
345 if (!tp) {
346 Tcl_AppendResult(irp, "bad type, should be one of: ", NULL);
347 dump_bind_tables(irp);
348 return TCL_ERROR;
349 }
350 if ((long int) cd == 1) {
351 if (!unbind_bind_entry(tp, argv[2], argv[3], argv[4])) {
352 /* don't error if trying to re-unbind a builtin */
353 if ((strcmp(argv[3], &argv[4][5]) != 0) || (argv[4][0] != '*') ||
354 (strncmp(argv[1], &argv[4][1], 3) != 0) ||
355 (argv[4][4] != ':')) {
356 Tcl_AppendResult(irp, "no such binding", NULL);
357 return TCL_ERROR;
358 }
359 }
360 } else {
361 if (argc == 4)
362 return tcl_getbinds(tp, argv[3]);
363 bind_bind_entry(tp, argv[2], argv[3], argv[4]);
364 }
365 Tcl_AppendResult(irp, argv[3], NULL);
366 return TCL_OK;
367 }
368
369 int check_validity(char *nme, Function f)
370 {
371 char *p;
372 p_tcl_bind_list t;
373
374 if (*nme != '*')
375 return 0;
376 if (!(p = strchr(nme + 1, ':')))
377 return 0;
378 *p = 0;
379 t = find_bind_table(nme + 1);
380 *p = ':';
381 if (!t)
382 return 0;
383 if (t->func != f)
384 return 0;
385 return 1;
386 }
387
388 static int builtin_3char STDVAR {
389 Function F = (Function) cd;
390
391 BADARGS(4, 4, " from to args");
392 CHECKVALIDITY(builtin_3char);
393 F(argv[1], argv[2], argv[3]);
394 return TCL_OK;
395 }
396
397 static int builtin_2char STDVAR {
398 Function F = (Function) cd;
399
400 BADARGS(3, 3, " nick msg");
401 CHECKVALIDITY(builtin_2char);
402 F(argv[1], argv[2]);
403 return TCL_OK;
404 }
405
406 static int builtin_5int STDVAR {
407 Function F = (Function) cd;
408
409 BADARGS(6, 6, " min hrs dom mon year");
410 CHECKVALIDITY(builtin_5int);
411 F(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
412 return TCL_OK;
413 }
414
415 static int builtin_char STDVAR {
416 Function F = (Function) cd;
417
418 BADARGS(2, 2, " handle");
419 CHECKVALIDITY(builtin_char);
420 F(argv[1]);
421 return TCL_OK;
422 }
423
424 static int builtin_chpt STDVAR {
425 Function F = (Function) cd;
426
427 BADARGS(3, 3, " bot nick sock");
428 CHECKVALIDITY(builtin_chpt);
429 F(argv[1], argv[2], atoi(argv[3]));
430 return TCL_OK;
431 }
432
433 static int builtin_chjn STDVAR {
434 Function F = (Function) cd;
435
436 BADARGS(6, 6, " bot nick chan# flag&sock host");
437 CHECKVALIDITY(builtin_chjn);
438 F(argv[1], argv[2], atoi(argv[3]), argv[4][0],
439 argv[4][0] ? atoi(argv[4] + 1) : 0, argv[5]);
440 return TCL_OK;
441 }
442
443 static int builtin_idxchar STDVAR {
444 Function F = (Function) cd;
445 int idx;
446 char *r;
447
448 BADARGS(3, 3, " idx args");
449 CHECKVALIDITY(builtin_idxchar);
450 idx = findidx(atoi(argv[1]));
451 if (idx < 0) {
452 Tcl_AppendResult(irp, "invalid idx", NULL);
453 return TCL_ERROR;
454 }
455 r = (((char *(*)()) F) (idx, argv[2]));
456
457 Tcl_ResetResult(irp);
458 Tcl_AppendResult(irp, r, NULL);
459 return TCL_OK;
460 }
461
462 int findanyidx(int z)
463 {
464 int j;
465
466 for (j = 0; j < dcc_total; j++)
467 if (dcc[j].sock == z)
468 return j;
469 return -1;
470 }
471
472 static int builtin_charidx STDVAR {
473 Function F = (Function) cd;
474 int idx;
475
476 BADARGS(3, 3, " handle idx");
477 CHECKVALIDITY(builtin_charidx);
478 idx = findanyidx(atoi(argv[2]));
479 if (idx < 0) {
480 Tcl_AppendResult(irp, "invalid idx", NULL);
481 return TCL_ERROR;
482 }
483 Tcl_AppendResult(irp, int_to_base10(F(argv[1], idx)), NULL);
484 return TCL_OK;
485 }
486
487 static int builtin_chat STDVAR {
488 Function F = (Function) cd;
489 int ch;
490
491 BADARGS(4, 4, " handle idx text");
492 CHECKVALIDITY(builtin_chat);
493 ch = atoi(argv[2]);
494 F(argv[1], ch, argv[3]);
495 return TCL_OK;
496 }
497
498 static int builtin_dcc STDVAR {
499 int idx;
500 Function F = (Function) cd;
501
502 context;
503 BADARGS(4, 4, " hand idx param");
504 idx = findidx(atoi(argv[2]));
505 if (idx < 0) {
506 Tcl_AppendResult(irp, "invalid idx", NULL);
507 return TCL_ERROR;
508 }
509 if (F == 0) {
510 Tcl_AppendResult(irp, "break", NULL);
511 return TCL_OK;
512 }
513 /* check if it's a password change, if so, don't show the password */
514 /* lets clean this up, it's debugging, we dont need pretty formats, just
515 * a cover up - and dont even bother with .tcl */
516 debug4("tcl: builtin dcc call: %s %s %s %s", argv[0], argv[1], argv[2],
517 (!strcmp(argv[0] + 5, "newpass") ||
518 !strcmp(argv[0] + 5, "chpass")) ? "[something]" : argv[3]);
519 context;
520 (F) (dcc[idx].user, idx, argv[3]);
521 context;
522 Tcl_ResetResult(irp);
523 Tcl_AppendResult(irp, "0", NULL);
524 context;
525 return TCL_OK;
526 }
527
528 /* trigger (execute) a proc */
529 static int trigger_bind(char *proc, char *param)
530 {
531 int x;
532 FILE *f = 0;
533
534 if (debug_tcl) {
535 f = fopen("DEBUG.TCL", "a");
536 if (f != NULL)
537 fprintf(f, "eval: %s%s\n", proc, param);
538 }
539 set_tcl_vars();
540 context;
541 x = Tcl_VarEval(interp, proc, param, NULL);
542 context;
543 if (x == TCL_ERROR) {
544 if (debug_tcl && (f != NULL)) {
545 fprintf(f, "done eval. error.\n");
546 fclose(f);
547 }
548 if (strlen(interp->result) > 400)
549 interp->result[400] = 0;
550 putlog(LOG_MISC, "*", "Tcl error [%s]: %s", proc, interp->result);
551 return BIND_EXECUTED;
552 } else {
553 if (debug_tcl && (f != NULL)) {
554 fprintf(f, "done eval. ok.\n");
555 fclose(f);
556 }
557 if (!strcmp(interp->result, "break"))
558 return BIND_EXEC_BRK;
559 return (atoi(interp->result) > 0) ? BIND_EXEC_LOG : BIND_EXECUTED;
560 }
561 }
562
563 int check_tcl_bind(p_tcl_bind_list bind, char *match,
564 struct flag_record *atr, char *param, int match_type)
565 {
566 struct tcl_bind_mask *hm, *ohm = NULL, *hmp = NULL;
567 int cnt = 0;
568 char *proc = NULL;
569 tcl_cmd_t *tt, *htt = NULL;
570 int f = 0, atrok, x;
571
572 context;
573 for (hm = bind->first; hm && !f; ohm = hm, hm = hm->next) {
574 int ok = 0;
575
576 switch (match_type & 0x03) {
577 case MATCH_PARTIAL:
578 ok = !strncasecmp(match, hm->mask, strlen(match));
579 break;
580 case MATCH_EXACT:
581 ok = !strcasecmp(match, hm->mask);
582 break;
583 case MATCH_CASE:
584 ok = !strcmp(match, hm->mask);
585 break;
586 case MATCH_MASK:
587 ok = wild_match_per((unsigned char *) hm->mask,
588 (unsigned char *) match);
589 break;
590 }
591 if (ok) {
592 tt = hm->first;
593 if (match_type & BIND_STACKABLE) {
594 /* could be multiple triggers */
595 while (tt) {
596 if (match_type & BIND_USE_ATTR) {
597 if (match_type & BIND_HAS_BUILTINS)
598 atrok = flagrec_ok(&tt->flags, atr);
599 else
600 atrok = flagrec_eq(&tt->flags, atr);
601 } else
602 atrok = 1;
603 if (atrok) {
604 cnt++;
605 tt->hits++;
606 hmp = ohm;
607 Tcl_SetVar(interp, "lastbind", match, TCL_GLOBAL_ONLY);
608 x = trigger_bind(tt->func_name, param);
609 if ((match_type & BIND_WANTRET) &&
610 !(match_type & BIND_ALTER_ARGS) && (x == BIND_EXEC_LOG))
611 return x;
612 if (match_type & BIND_ALTER_ARGS) {
613 if ((interp->result == NULL) || !(interp->result[0]))
614 return x;
615 /* this is such an amazingly ugly hack: */
616 Tcl_SetVar(interp, "_a", interp->result, 0);
617 }
618 }
619 tt = tt->next;
620 }
621 if ((match_type & 3) != MATCH_MASK)
622 f = 1; /* this will suffice until we have
623 * stackable partials */
624 } else {
625 if (match_type & BIND_USE_ATTR) {
626 if (match_type & BIND_HAS_BUILTINS)
627 atrok = flagrec_ok(&tt->flags, atr);
628 else
629 atrok = flagrec_eq(&tt->flags, atr);
630 } else
631 atrok = 1;
632 if (atrok) {
633 cnt++;
634 proc = tt->func_name;
635 htt = tt;
636 hmp = ohm;
637 if (((match_type & 3) != MATCH_PARTIAL) ||
638 !strcasecmp(match, hm->mask))
639 cnt = f = 1;
640 }
641 }
642 }
643 }
644 context;
645 if (cnt == 0)
646 return BIND_NOMATCH;
647 if (((match_type & 0x03) == MATCH_MASK) ||
648 ((match_type & 0x03) == MATCH_CASE))
649 return BIND_EXECUTED;
650 if ((match_type & 0x3) != MATCH_CASE) {
651 if (htt)
652 htt->hits++;
653 if (hmp) {
654 ohm = hmp->next;
655 hmp->next = ohm->next;
656 ohm->next = bind->first;
657 bind->first = ohm;
658 }
659 }
660 if (cnt > 1)
661 return BIND_AMBIGUOUS;
662 Tcl_SetVar(interp, "lastbind", match, TCL_GLOBAL_ONLY);
663 return trigger_bind(proc, param);
664 }
665
666 /* check for tcl-bound dcc command, return 1 if found */
667 /* dcc: proc-name <handle> <sock> <args...> */
668 int check_tcl_dcc(char *cmd, int idx, char *args)
669 {
670 struct flag_record fr =
671 {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
672 int x;
673 char s[5];
674
675 context;
676 get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan);
677 sprintf(s, "%ld", dcc[idx].sock);
678 Tcl_SetVar(interp, "_dcc1", dcc[idx].nick, 0);
679 Tcl_SetVar(interp, "_dcc2", s, 0);
680 Tcl_SetVar(interp, "_dcc3", args, 0);
681 context;
682 x = check_tcl_bind(H_dcc, cmd, &fr, " $_dcc1 $_dcc2 $_dcc3",
683 MATCH_PARTIAL | BIND_USE_ATTR | BIND_HAS_BUILTINS);
684 context;
685 if (x == BIND_AMBIGUOUS) {
686 dprintf(idx, MISC_AMBIGUOUS);
687 return 0;
688 }
689 if (x == BIND_NOMATCH) {
690 dprintf(idx, MISC_NOSUCHCMD);
691 return 0;
692 }
693 if (x == BIND_EXEC_BRK)
694 return 1; /* quit */
695 if (x == BIND_EXEC_LOG)
696 putlog(LOG_CMDS, "*", "#%s# %s %s", dcc[idx].nick, cmd, args);
697 return 0;
698 }
699
700 void check_tcl_bot(char *nick, char *code, char *param)
701 {
702 context;
703 Tcl_SetVar(interp, "_bot1", nick, 0);
704 Tcl_SetVar(interp, "_bot2", code, 0);
705 Tcl_SetVar(interp, "_bot3", param, 0);
706 check_tcl_bind(H_bot, code, 0, " $_bot1 $_bot2 $_bot3", MATCH_EXACT);
707 }
708
709 void check_tcl_chonof(char *hand, int sock, p_tcl_bind_list table)
710 {
711 struct flag_record fr =
712 {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
713 char s[20];
714 struct userrec *u = get_user_by_handle(userlist, hand);
715
716 context;
717 touch_laston(u, "partyline", now);
718 get_user_flagrec(u, &fr, NULL);
719 Tcl_SetVar(interp, "_chonof1", hand, 0);
720 simple_sprintf(s, "%d", sock);
721 Tcl_SetVar(interp, "_chonof2", s, 0);
722 context;
723 check_tcl_bind(table, hand, &fr, " $_chonof1 $_chonof2", MATCH_MASK |
724 BIND_USE_ATTR | BIND_STACKABLE | BIND_WANTRET);
725 context;
726 }
727
728 void check_tcl_chatactbcst(char *from, int chan, char *text,
729 p_tcl_bind_list ht)
730 {
731 char s[10];
732
733 context;
734 simple_sprintf(s, "%d", chan);
735 Tcl_SetVar(interp, "_cab1", from, 0);
736 Tcl_SetVar(interp, "_cab2", s, 0);
737 Tcl_SetVar(interp, "_cab3", text, 0);
738 check_tcl_bind(ht, text, 0, " $_cab1 $_cab2 $_cab3",
739 MATCH_MASK | BIND_STACKABLE);
740 context;
741 }
742
743 void check_tcl_nkch(char *ohand, char *nhand)
744 {
745 context;
746 Tcl_SetVar(interp, "_nkch1", ohand, 0);
747 Tcl_SetVar(interp, "_nkch2", nhand, 0);
748 check_tcl_bind(H_nkch, ohand, 0, " $_nkch1 $_nkch2",
749 MATCH_MASK | BIND_STACKABLE);
750 context;
751 }
752
753 void check_tcl_link(char *bot, char *via)
754 {
755 context;
756 Tcl_SetVar(interp, "_link1", bot, 0);
757 Tcl_SetVar(interp, "_link2", via, 0);
758 context;
759 check_tcl_bind(H_link, bot, 0, " $_link1 $_link2",
760 MATCH_MASK | BIND_STACKABLE);
761 context;
762 }
763
764 void check_tcl_disc(char *bot)
765 {
766 context;
767 Tcl_SetVar(interp, "_disc1", bot, 0);
768 context;
769 check_tcl_bind(H_disc, bot, 0, " $_disc1", MATCH_MASK | BIND_STACKABLE);
770 context;
771 }
772
773 void check_tcl_loadunld(char *mod, p_tcl_bind_list table)
774 {
775 context;
776 Tcl_SetVar(interp, "_lu1", mod, 0);
777 context;
778 check_tcl_bind(table, mod, 0, " $_lu1", MATCH_MASK | BIND_STACKABLE);
779 context;
780 }
781
782 char *check_tcl_filt(int idx, char *text)
783 {
784 char s[10];
785 int x;
786 struct flag_record fr =
787 {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
788
789 context;
790 sprintf(s, "%ld", dcc[idx].sock);
791 get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan);
792 Tcl_SetVar(interp, "_filt1", s, 0);
793 Tcl_SetVar(interp, "_filt2", text, 0);
794 context;
795 x = check_tcl_bind(H_filt, text, &fr, " $_filt1 $_filt2",
796 MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE |
797 BIND_WANTRET | BIND_ALTER_ARGS);
798 context;
799 if ((x == BIND_EXECUTED) || (x == BIND_EXEC_LOG)) {
800 if ((interp->result == NULL) || (!interp->result[0]))
801 return "";
802 else
803 return interp->result;
804 } else
805 return text;
806 }
807
808 int check_tcl_note(char *from, char *to, char *text)
809 {
810 int x;
811
812 context;
813 Tcl_SetVar(interp, "_note1", from, 0);
814 Tcl_SetVar(interp, "_note2", to, 0);
815 Tcl_SetVar(interp, "_note3", text, 0);
816 x = check_tcl_bind(H_note, to, 0, " $_note1 $_note2 $_note3", MATCH_EXACT);
817 return ((x == BIND_MATCHED) || (x == BIND_EXECUTED) ||
818 (x == BIND_EXEC_LOG));
819 }
820
821 void check_tcl_listen(char *cmd, int idx)
822 {
823 char s[10];
824 int x;
825
826 context;
827 simple_sprintf(s, "%d", idx);
828 Tcl_SetVar(interp, "_n", s, 0);
829 set_tcl_vars();
830 context;
831 x = Tcl_VarEval(interp, cmd, " $_n", NULL);
832 context;
833 if (x == TCL_ERROR)
834 putlog(LOG_MISC, "*", "error on listen: %s", interp->result);
835 }
836
837 void check_tcl_chjn(char *bot, char *nick, int chan, char type,
838 int sock, char *host)
839 {
840 struct flag_record fr =
841 {FR_GLOBAL, 0, 0, 0, 0, 0};
842 char s[20], t[2], u[20];
843
844 context;
845 t[0] = type;
846 t[1] = 0;
847 switch (type) {
848 case '*':
849 fr.global = USER_OWNER;
850
851 break;
852 case '+':
853 fr.global = USER_MASTER;
854
855 break;
856 case '@':
857 fr.global = USER_OP;
858
859 break;
860 case '%':
861 fr.global = USER_BOTMAST;
862 }
863 simple_sprintf(s, "%d", chan);
864 simple_sprintf(u, "%d", sock);
865 Tcl_SetVar(interp, "_chjn1", bot, 0);
866 Tcl_SetVar(interp, "_chjn2", nick, 0);
867 Tcl_SetVar(interp, "_chjn3", s, 0);
868 Tcl_SetVar(interp, "_chjn4", t, 0);
869 Tcl_SetVar(interp, "_chjn5", u, 0);
870 Tcl_SetVar(interp, "_chjn6", host, 0);
871 context;
872 check_tcl_bind(H_chjn, s, &fr,
873 " $_chjn1 $_chjn2 $_chjn3 $_chjn4 $_chjn5 $_chjn6",
874 MATCH_MASK | BIND_STACKABLE);
875 context;
876 }
877
878 void check_tcl_chpt(char *bot, char *hand, int sock, int chan)
879 {
880 char u[20], v[20];
881
882 context;
883 simple_sprintf(u, "%d", sock);
884 simple_sprintf(v, "%d", chan);
885 Tcl_SetVar(interp, "_chpt1", bot, 0);
886 Tcl_SetVar(interp, "_chpt2", hand, 0);
887 Tcl_SetVar(interp, "_chpt3", u, 0);
888 Tcl_SetVar(interp, "_chpt4", v, 0);
889 context;
890 check_tcl_bind(H_chpt, v, 0, " $_chpt1 $_chpt2 $_chpt3 $_chpt4",
891 MATCH_MASK | BIND_STACKABLE);
892 context;
893 }
894
895 void check_tcl_away(char *bot, int idx, char *msg)
896 {
897 char u[20];
898
899 context;
900 simple_sprintf(u, "%d", idx);
901 Tcl_SetVar(interp, "_away1", bot, 0);
902 Tcl_SetVar(interp, "_away2", u, 0);
903 Tcl_SetVar(interp, "_away3", msg ? msg : "", 0);
904 context;
905 check_tcl_bind(H_away, bot, 0, " $_away1 $_away2 $_away3",
906 MATCH_MASK | BIND_STACKABLE);
907 }
908
909 void check_tcl_time(struct tm *tm)
910 {
911 char y[100];
912
913 context;
914 sprintf(y, "%02d", tm->tm_min);
915 Tcl_SetVar(interp, "_time1", y, 0);
916 sprintf(y, "%02d", tm->tm_hour);
917 Tcl_SetVar(interp, "_time2", y, 0);
918 sprintf(y, "%02d", tm->tm_mday);
919 Tcl_SetVar(interp, "_time3", y, 0);
920 sprintf(y, "%02d", tm->tm_mon);
921 Tcl_SetVar(interp, "_time4", y, 0);
922 sprintf(y, "%04d", tm->tm_year + 1900);
923 Tcl_SetVar(interp, "_time5", y, 0);
924 sprintf(y, "%02d %02d %02d %02d %04d", tm->tm_min, tm->tm_hour, tm->tm_mday,
925 tm->tm_mon, tm->tm_year + 1900);
926 context;
927 check_tcl_bind(H_time, y, 0,
928 " $_time1 $_time2 $_time3 $_time4 $_time5",
929 MATCH_MASK | BIND_STACKABLE);
930 context;
931 }
932
933 void check_tcl_event(char *event)
934 {
935 context;
936 Tcl_SetVar(interp, "_event1", event, 0);
937 context;
938 check_tcl_bind(H_event, event, 0, " $_event1", MATCH_EXACT | BIND_STACKABLE);
939 context;
940 }
941
942 void tell_binds(int idx, char *name)
943 {
944 struct tcl_bind_mask *hm;
945 p_tcl_bind_list p, kind;
946 int fnd = 0;
947 tcl_cmd_t *tt;
948 char *s, *proc, flg[100];
949 int showall = 0;
950
951 context;
952 s = strchr(name, ' ');
953 if (s) {
954 *s = 0;
955 s++;
956 } else {
957 s = name;
958 }
959 kind = find_bind_table(name);
960 if (!strcasecmp(s, "all"))
961 showall = 1;
962 for (p = kind ? kind : bind_table_list; p; p = kind ? 0 : p->next) {
963 for (hm = p->first; hm; hm = hm->next) {
964 if (!fnd) {
965 dprintf(idx, MISC_CMDBINDS);
966 fnd = 1;
967 dprintf(idx, " TYPE FLGS COMMAND HITS BINDING (TCL)\n");
968 }
969 for (tt = hm->first; tt; tt = tt->next) {
970 proc = tt->func_name;
971 build_flags(flg, &(tt->flags), NULL);
972 context;
973 if ((showall) || (proc[0] != '*') || !strchr(proc, ':'))
974 dprintf(idx, " %-4s %-8s %-20s %4d %s\n", p->name, flg,
975 hm->mask, tt->hits, tt->func_name);
976 }
977 }
978 }
979 if (!fnd) {
980 if (!kind)
981 dprintf(idx, "No command bindings.\n");
982 else
983 dprintf(idx, "No bindings for %s.\n", name);
984 }
985 }
986
987 /* bring the default msg/dcc/fil commands into the Tcl interpreter */
988 void add_builtins(p_tcl_bind_list table, cmd_t * cc, int count)
989 {
990 int k;
991 char p[1024], *l;
992
993 context;
994 while (count) {
995 count--;
996 simple_sprintf(p, "*%s:%s", table->name,
997 cc[count].funcname ? cc[count].funcname : cc[count].name);
998 l = (char *) nmalloc(Tcl_ScanElement(p, &k));
999 Tcl_ConvertElement(p, l, k | TCL_DONT_USE_BRACES);
1000 Tcl_CreateCommand(interp, p, table->func,
1001 (ClientData) cc[count].func, NULL);
1002 bind_bind_entry(table, cc[count].flags, cc[count].name, l);
1003 nfree(l);
1004 /* create command entry in Tcl interpreter */
1005 }
1006 }
1007
1008 /* bring the default msg/dcc/fil commands into the Tcl interpreter */
1009 void rem_builtins(p_tcl_bind_list table, cmd_t * cc, int count)
1010 {
1011 int k;
1012 char p[1024], *l;
1013
1014 while (count) {
1015 count--;
1016 simple_sprintf(p, "*%s:%s", table->name,
1017 cc[count].funcname ? cc[count].funcname :
1018 cc[count].name);
1019 l = (char *) nmalloc(Tcl_ScanElement(p, &k));
1020 Tcl_ConvertElement(p, l, k | TCL_DONT_USE_BRACES);
1021 Tcl_DeleteCommand(interp, p);
1022 unbind_bind_entry(table, cc[count].flags, cc[count].name, l);
1023 nfree(l);
1024 }
1025 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23