/[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.13 - (show annotations) (download) (as text)
Sun Jan 30 22:21:18 2000 UTC (19 years, 6 months ago) by per
Branch: MAIN
CVS Tags: eggdrop104030RC2, eggdrop10403RC1, eggdrop10404, eggdrop10403, HEAD
Changes since 1.12: +2 -3 lines
File MIME type: text/x-chdr
passwdok2(dw), botattr(dw) and kickmsg(eule)

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.12 2000/01/17 16:14:45 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 = (user.chan | pls.chan) & ~mns.chan;
209 user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
210 }
211 set_user_flagrec(u, &user, chan);
212 }
213 /* retrieve current flags and return them */
214 build_flags(work, &user, NULL);
215 Tcl_AppendResult(irp, work, NULL);
216 return TCL_OK;
217 }
218
219 static int tcl_matchattr STDVAR {
220 struct userrec *u;
221 struct flag_record plus, minus, user;
222 int ok = 0, f;
223
224 Context;
225 BADARGS(3, 4, " handle flags ?channel?");
226 Context; /* a2 - Last context: tcluser.c/184 */
227 if ((u = get_user_by_handle(userlist, argv[1])) &&
228 ((argc == 3) || findchan(argv[3]))) {
229 Context; /* a2 - Last context: tcluser.c/184 */
230 user.match = FR_GLOBAL | (argc == 4 ? FR_CHAN : 0) | FR_BOT;
231 get_user_flagrec(u, &user, argv[3]);
232 plus.match = user.match;
233 break_down_flags(argv[2], &plus, &minus);
234 f = (minus.global || minus.udef_global || minus.chan ||
235 minus.udef_chan || minus.bot);
236 if (flagrec_eq(&plus, &user)) {
237 Context; /* a2 - Last context: tcluser.c/184 */
238 if (!f)
239 ok = 1;
240 else {
241 minus.match = plus.match ^ (FR_AND | FR_OR);
242 if (!flagrec_eq(&minus, &user))
243 ok = 1;
244 }
245 }
246 }
247 Context; /* a2 - Last context: tcluser.c/184 */
248 Tcl_AppendResult(irp, ok ? "1" : "0", NULL);
249 return TCL_OK;
250 }
251
252 static int tcl_adduser STDVAR {
253 Context;
254 BADARGS(2, 3, " handle ?hostmask?");
255 if (strlen(argv[1]) > HANDLEN)
256 argv[1][HANDLEN] = 0;
257 if ((argv[1][0] == '*') || get_user_by_handle(userlist, argv[1]))
258 Tcl_AppendResult(irp, "0", NULL);
259 else {
260 userlist = adduser(userlist, argv[1], argv[2], "-", default_flags);
261 Tcl_AppendResult(irp, "1", NULL);
262 }
263 return TCL_OK;
264 }
265
266 static int tcl_addbot STDVAR {
267 struct bot_addr *bi;
268 char *p, *q;
269
270 Context;
271 BADARGS(3, 3, " handle address");
272 if (strlen(argv[1]) > HANDLEN)
273 argv[1][HANDLEN] = 0;
274 if (get_user_by_handle(userlist, argv[1]))
275 Tcl_AppendResult(irp, "0", NULL);
276 else if (argv[1][0] == '*')
277 Tcl_AppendResult(irp, "0", NULL);
278 else {
279 userlist = adduser(userlist, argv[1], "none", "-", USER_BOT);
280 bi = user_malloc(sizeof(struct bot_addr));
281 q = strchr(argv[2], ':');
282 if (!q) {
283 bi->address = user_malloc(strlen(argv[2]) + 1);
284 strcpy(bi->address, argv[2]);
285 bi->telnet_port = 3333;
286 bi->relay_port = 3333;
287 } else {
288 bi->address = user_malloc(q - argv[2] + 1);
289 strncpy(bi->address, argv[2], q - argv[2]);
290 bi->address[q - argv[2]] = 0;
291 p = q + 1;
292 bi->telnet_port = atoi(p);
293 q = strchr(p, '/');
294 if (!q)
295 bi->relay_port = bi->telnet_port;
296 else
297 bi->relay_port = atoi(q + 1);
298 }
299 set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, argv[1]), bi);
300 Tcl_AppendResult(irp, "1", NULL);
301 }
302 return TCL_OK;
303 }
304
305 static int tcl_deluser STDVAR {
306 Context;
307 BADARGS(2, 2, " handle");
308 Tcl_AppendResult(irp, (argv[1][0] == '*') ? "0" :
309 int_to_base10(deluser(argv[1])), NULL);
310 return TCL_OK;
311 }
312
313 static int tcl_delhost STDVAR {
314 Context;
315 BADARGS(3, 3, " handle hostmask");
316 if ((!get_user_by_handle(userlist, argv[1])) || (argv[1][0] == '*')) {
317 Tcl_AppendResult(irp, "non-existent user", NULL);
318 return TCL_ERROR;
319 }
320 Tcl_AppendResult(irp, delhost_by_handle(argv[1], argv[2]) ? "1" : "0",
321 NULL);
322 return TCL_OK;
323 }
324
325 static int tcl_userlist STDVAR {
326 struct userrec *u = userlist;
327 struct flag_record user, plus, minus;
328 int ok = 1, f = 0;
329
330 Context;
331 BADARGS(1, 3, " ?flags ?channel??");
332 if ((argc == 3) && !findchan(argv[2])) {
333 Tcl_AppendResult(irp, "Invalid channel: ", argv[2], NULL);
334 return TCL_ERROR;
335 }
336 if (argc >= 2) {
337 plus.match = FR_GLOBAL | FR_CHAN | FR_BOT;
338 break_down_flags(argv[1], &plus, &minus);
339 f = (minus.global || minus.udef_global || minus.chan ||
340 minus.udef_chan || minus.bot);
341 }
342 minus.match = plus.match ^ (FR_AND | FR_OR);
343 while (u) {
344 if (argc >= 2) {
345 user.match = FR_GLOBAL | FR_CHAN | FR_BOT | (argc == 3 ? 0 : FR_ANYWH);
346 get_user_flagrec(u, &user, argv[2]); /* argv[2] == NULL for argc = 2 ;) */
347 if (flagrec_eq(&plus, &user) && !(f && flagrec_eq(&minus, &user)))
348 ok = 1;
349 else
350 ok = 0;
351 }
352 if (ok)
353 Tcl_AppendElement(interp, u->handle);
354 u = u->next;
355 }
356 return TCL_OK;
357 }
358
359 static int tcl_save STDVAR {
360 Context;
361 write_userfile(-1);
362 return TCL_OK;
363 }
364
365 static int tcl_reload STDVAR {
366 Context;
367 reload();
368 return TCL_OK;
369 }
370
371 static int tcl_chnick STDVAR {
372 struct userrec *u;
373 char newhand[HANDLEN + 1];
374 int x = 1, i;
375
376 Context;
377 BADARGS(3, 3, " oldnick newnick");
378 u = get_user_by_handle(userlist, argv[1]);
379 if (!u)
380 x = 0;
381 else {
382 strncpy(newhand, argv[2], HANDLEN);
383 newhand[HANDLEN] = 0;
384 for (i = 0; i < strlen(newhand); i++)
385 if ((newhand[i] <= 32) || (newhand[i] >= 127) || (newhand[i] == '@'))
386 newhand[i] = '?';
387 if (strchr(BADHANDCHARS, newhand[0]) != NULL)
388 x = 0;
389 else if (strlen(newhand) < 1)
390 x = 0;
391 else if (get_user_by_handle(userlist, newhand))
392 x = 0;
393 else if (!strcasecmp(botnetnick, newhand) &&
394 (!(u->flags & USER_BOT) || nextbot (argv [1]) != -1))
395 x = 0;
396 else if (newhand[0] == '*')
397 x = 0;
398 }
399 if (x)
400 x = change_handle(u, newhand);
401
402 Tcl_AppendResult(irp, x ? "1" : "0", NULL);
403 return TCL_OK;
404 }
405
406 static int tcl_getting_users STDVAR {
407 int i;
408
409 Context;
410 BADARGS(1, 1, "");
411 for (i = 0; i < dcc_total; i++) {
412 if ((dcc[i].type == &DCC_BOT) &&
413 (dcc[i].status & STAT_GETTING)) {
414 Tcl_AppendResult(irp, "1", NULL);
415 return TCL_OK;
416 }
417 }
418 Tcl_AppendResult(irp, "0", NULL);
419 return TCL_OK;
420 }
421
422 static int tcl_isignore STDVAR {
423 Context;
424 BADARGS(2, 2, " nick!user@host");
425 Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
426 return TCL_OK;
427 }
428
429 static int tcl_newignore STDVAR {
430 time_t expire_time;
431 char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
432
433 Context;
434 BADARGS(4, 5, " hostmask creator comment ?lifetime?");
435 strncpy(ign, argv[1], UHOSTMAX);
436 ign[UHOSTMAX] = 0;
437 strncpy(from, argv[2], HANDLEN);
438 from[HANDLEN] = 0;
439 strncpy(cmt, argv[3], 65);
440 cmt[65] = 0;
441 if (argc == 4)
442 expire_time = now + (60 * ignore_time);
443 else {
444 if (atol(argv[4]) == 0)
445 expire_time = 0L;
446 else
447 expire_time = now + (60 * atol(argv[4]));
448 }
449 addignore(ign, from, cmt, expire_time);
450
451 return TCL_OK;
452 }
453
454 static int tcl_killignore STDVAR {
455 Context;
456 BADARGS(2, 2, " hostmask");
457 Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
458 return TCL_OK;
459 }
460
461 /* { hostmask note expire-time create-time creator } */
462 static int tcl_ignorelist STDVAR {
463 struct igrec *i;
464 char ts[21], ts1[21], *list[5], *p;
465
466 Context;
467 BADARGS(1, 1, "");
468 for (i = global_ign; i; i = i->next) {
469 list[0] = i->igmask;
470 list[1] = i->msg;
471 sprintf(ts, "%lu", i->expire);
472 list[2] = ts;
473 sprintf(ts1, "%lu", i->added);
474 list[3] = ts1;
475 list[4] = i->user;
476 p = Tcl_Merge(5, list);
477 Tcl_AppendElement(irp, p);
478 Tcl_Free((char *) p);
479 }
480 return TCL_OK;
481 }
482
483 static int tcl_getuser STDVAR {
484 struct user_entry_type *et;
485 struct userrec *u;
486 struct user_entry *e;
487
488 Context;
489 BADARGS(3, 999, " handle type");
490 if (!(et = find_entry_type(argv[2]))) {
491 Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
492 return TCL_ERROR;
493 }
494 if (!(u = get_user_by_handle(userlist, argv[1]))) {
495 if (argv[1][0] != '*') {
496 Tcl_AppendResult(irp, "No such user.", NULL);
497 return TCL_ERROR;
498 } else
499 return TCL_OK; /* silently ignore user * */
500 }
501 e = find_user_entry(et, u);
502
503 if (e)
504 return et->tcl_get(irp, u, e, argc, argv);
505 return TCL_OK;
506 }
507
508 static int tcl_setuser STDVAR {
509 struct user_entry_type *et;
510 struct userrec *u;
511 struct user_entry *e;
512 int r;
513
514 Context;
515 BADARGS(3, 999, " handle type ?setting....?");
516 if (!(et = find_entry_type(argv[2]))) {
517 Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
518 return TCL_ERROR;
519 }
520 if (!(u = get_user_by_handle(userlist, argv[1]))) {
521 if (argv[1][0] != '*') {
522 Tcl_AppendResult(irp, "No such user.", NULL);
523 return TCL_ERROR;
524 } else
525 return TCL_OK; /* silently ignore user * */
526 }
527 if (!(e = find_user_entry(et, u))) {
528 e = user_malloc(sizeof(struct user_entry));
529
530 e->type = et;
531 e->name = NULL;
532 e->u.list = NULL;
533 list_insert((&(u->entries)), e);
534 }
535 r = et->tcl_set(irp, u, e, argc, argv);
536 /* yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
537 if (!e->u.list) {
538 if (list_delete((struct list_type **) &(u->entries),
539 (struct list_type *) e))
540 nfree(e);
541 /* else maybe already freed... (entry_type==HOSTS) <drummer> */
542 }
543 return r;
544 }
545
546 tcl_cmds tcluser_cmds[] =
547 {
548 {"countusers", tcl_countusers},
549 {"validuser", tcl_validuser},
550 {"finduser", tcl_finduser},
551 {"passwdok", tcl_passwdOk},
552 {"chattr", tcl_chattr},
553 {"botattr", tcl_botattr},
554 {"matchattr", tcl_matchattr},
555 {"matchchanattr", tcl_matchattr},
556 {"adduser", tcl_adduser},
557 {"addbot", tcl_addbot},
558 {"deluser", tcl_deluser},
559 {"delhost", tcl_delhost},
560 {"userlist", tcl_userlist},
561 {"save", tcl_save},
562 {"reload", tcl_reload},
563 {"chnick", tcl_chnick},
564 {"getting-users", tcl_getting_users},
565 {"isignore", tcl_isignore},
566 {"newignore", tcl_newignore},
567 {"killignore", tcl_killignore},
568 {"ignorelist", tcl_ignorelist},
569 {"getuser", tcl_getuser},
570 {"setuser", tcl_setuser},
571 {0, 0}
572 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23