| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 |
- /*
- * tcluser.c -- handles:
- * Tcl stubs for the user-record-oriented commands
- *
- */
- #include "main.h"
- #include "users.h"
- #include "chan.h"
- #include "tandem.h"
- #include "modules.h"
- extern Tcl_Interp *interp;
- extern struct userrec *userlist;
- extern int default_flags, dcc_total, ignore_time;
- extern struct dcc_t *dcc;
- extern char origbotname[], botnetnick[];
- extern time_t now;
- static int tcl_countusers STDVAR
- {
- BADARGS(1, 1, "");
- Tcl_AppendResult(irp, int_to_base10(count_users(userlist)), NULL);
- return TCL_OK;
- }
- static int tcl_validuser STDVAR
- {
- BADARGS(2, 2, " handle");
- Tcl_AppendResult(irp, get_user_by_handle(userlist, argv[1]) ? "1" : "0",
- NULL);
- return TCL_OK;
- }
- static int tcl_finduser STDVAR
- {
- struct userrec *u;
- BADARGS(2, 2, " nick!user@host");
- u = get_user_by_host(argv[1]);
- Tcl_AppendResult(irp, u ? u->handle : "*", NULL);
- return TCL_OK;
- }
- static int tcl_passwdOk STDVAR
- {
- struct userrec *u;
- BADARGS(3, 3, " handle passwd");
- Tcl_AppendResult(irp, ((u = get_user_by_handle(userlist, argv[1])) &&
- u_pass_match(u, argv[2])) ? "1" : "0", NULL);
- return TCL_OK;
- }
- static int tcl_chattr STDVAR
- {
- char *chan, *chg, work[100];
- struct flag_record pls, mns, user;
- struct userrec *u;
- BADARGS(2, 4, " handle ?changes? ?channel?");
- if ((argv[1][0] == '*') || !(u = get_user_by_handle(userlist, argv[1]))) {
- Tcl_AppendResult(irp, "*", NULL);
- return TCL_OK;
- }
- if (argc == 4) {
- user.match = FR_GLOBAL | FR_CHAN;
- chan = argv[3];
- chg = argv[2];
- } else if (argc == 3 && argv[2][0]) {
- int ischan = (findchan_by_dname(argv[2]) != NULL);
- if (strchr(CHANMETA, argv[2][0]) && !ischan && argv[2][0] != '+' && argv[2][0] != '-') {
- Tcl_AppendResult(irp, "no such channel", NULL);
- return TCL_ERROR;
- } else if (ischan) {
- /* Channel exists */
- user.match = FR_GLOBAL | FR_CHAN;
- chan = argv[2];
- chg = NULL;
- } else {
- /* 3rd possibility... channel doesnt exist, does start with a +.
- * In this case we assume the string is flags.
- */
- user.match = FR_GLOBAL;
- chan = NULL;
- chg = argv[2];
- }
- } else {
- user.match = FR_GLOBAL;
- chan = NULL;
- chg = NULL;
- }
- if (chan && !findchan_by_dname(chan)) {
- Tcl_AppendResult(irp, "no such channel", NULL);
- return TCL_ERROR;
- }
- get_user_flagrec(u, &user, chan);
- /* Make changes */
- if (chg) {
- pls.match = user.match;
- break_down_flags(chg, &pls, &mns);
- /* No-one can change these flags on-the-fly */
- pls.global &=~(USER_BOT);
- mns.global &=~(USER_BOT);
- if (chan) {
- pls.chan &= ~(BOT_SHARE);
- mns.chan &= ~(BOT_SHARE);
- }
- user.global = sanity_check((user.global |pls.global) &~mns.global);
- user.udef_global = (user.udef_global | pls.udef_global)
- & ~mns.udef_global;
- if (chan) {
- user.chan = chan_sanity_check((user.chan | pls.chan) & ~mns.chan,
- user.global);
- user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
- }
- set_user_flagrec(u, &user, chan);
- }
- /* Retrieve current flags and return them */
- build_flags(work, &user, NULL);
- Tcl_AppendResult(irp, work, NULL);
- return TCL_OK;
- }
- static int tcl_botattr STDVAR
- {
- char *chan, *chg, work[100];
- struct flag_record pls, mns, user;
- struct userrec *u;
- BADARGS(2, 4, " bot-handle ?changes? ?channel?");
- u = get_user_by_handle(userlist, argv[1]);
- if ((argv[1][0] == '*') || !u || !(u->flags & USER_BOT)) {
- Tcl_AppendResult(irp, "*", NULL);
- return TCL_OK;
- }
- if (argc == 4) {
- user.match = FR_BOT | FR_CHAN;
- chan = argv[3];
- chg = argv[2];
- } else if (argc == 3 && argv[2][0] &&
- strchr(CHANMETA, argv[2][0]) != NULL) {
- /* We need todo extra checking here to stop us mixing up +channel's
- * with flags. <cybah>
- */
- if (!findchan_by_dname(argv[2]) && argv[2][0] != '+') {
- /* Channel doesnt exist, and it cant possibly be flags as there
- * is no + at the start of the string.
- */
- Tcl_AppendResult(irp, "no such channel", NULL);
- return TCL_ERROR;
- } else if(findchan_by_dname(argv[2])) {
- /* Channel exists */
- user.match = FR_BOT | FR_CHAN;
- chan = argv[2];
- chg = NULL;
- } else {
- /* 3rd possibility... channel doesnt exist, does start with a +.
- * In this case we assume the string is flags.
- */
- user.match = FR_BOT;
- chan = NULL;
- chg = argv[2];
- }
- } else {
- user.match = FR_BOT;
- chan = NULL;
- if (argc < 3)
- chg = NULL;
- else
- chg = argv[2];
- }
- if (chan && !findchan_by_dname(chan)) {
- Tcl_AppendResult(irp, "no such channel", NULL);
- return TCL_ERROR;
- }
- get_user_flagrec(u, &user, chan);
- /* Make changes */
- if (chg) {
- pls.match = user.match;
- break_down_flags(chg, &pls, &mns);
- /* No-one can change these flags on-the-fly */
- if (chan) {
- pls.chan &= BOT_SHARE;
- mns.chan &= BOT_SHARE;
- }
- user.bot = sanity_check((user.bot | pls.bot) & ~mns.bot);
- if (chan) {
- user.chan = (user.chan | pls.chan) & ~mns.chan;
- user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
- }
- set_user_flagrec(u, &user, chan);
- }
- /* Retrieve current flags and return them */
- build_flags(work, &user, NULL);
- Tcl_AppendResult(irp, work, NULL);
- return TCL_OK;
- }
- static int tcl_matchattr STDVAR
- {
- struct userrec *u;
- struct flag_record plus, minus, user;
- int ok = 0, f;
- BADARGS(3, 4, " handle flags ?channel?");
- if ((u = get_user_by_handle(userlist, argv[1]))) {
- user.match = FR_GLOBAL | (argc == 4 ? FR_CHAN : 0) | FR_BOT;
- get_user_flagrec(u, &user, argv[3]);
- plus.match = user.match;
- break_down_flags(argv[2], &plus, &minus);
- f = (minus.global || minus.udef_global || minus.chan ||
- minus.udef_chan || minus.bot);
- if (flagrec_eq(&plus, &user)) {
- if (!f)
- ok = 1;
- else {
- minus.match = plus.match ^ (FR_AND | FR_OR);
- if (!flagrec_eq(&minus, &user))
- ok = 1;
- }
- }
- }
- Tcl_AppendResult(irp, ok ? "1" : "0", NULL);
- return TCL_OK;
- }
- static int tcl_adduser STDVAR
- {
- BADARGS(2, 3, " handle ?hostmask?");
- if (strlen(argv[1]) > HANDLEN)
- argv[1][HANDLEN] = 0;
- if ((argv[1][0] == '*') || get_user_by_handle(userlist, argv[1]))
- Tcl_AppendResult(irp, "0", NULL);
- else {
- userlist = adduser(userlist, argv[1], argv[2], "-", default_flags);
- Tcl_AppendResult(irp, "1", NULL);
- }
- return TCL_OK;
- }
- static int tcl_addbot STDVAR
- {
- struct bot_addr *bi;
- char *p, *q;
- BADARGS(3, 3, " handle address");
- if (strlen(argv[1]) > HANDLEN)
- argv[1][HANDLEN] = 0;
- if (get_user_by_handle(userlist, argv[1]))
- Tcl_AppendResult(irp, "0", NULL);
- else if (argv[1][0] == '*')
- Tcl_AppendResult(irp, "0", NULL);
- else {
- userlist = adduser(userlist, argv[1], "none", "-", USER_BOT);
- bi = user_malloc(sizeof(struct bot_addr));
- q = strchr(argv[2], ':');
- if (!q) {
- bi->address = user_malloc(strlen(argv[2]) + 1);
- strcpy(bi->address, argv[2]);
- bi->telnet_port = 3333;
- bi->relay_port = 3333;
- } else {
- bi->address = user_malloc(q - argv[2] + 1);
- strncpy(bi->address, argv[2], q - argv[2]);
- bi->address[q - argv[2]] = 0;
- p = q + 1;
- bi->telnet_port = atoi(p);
- q = strchr(p, '/');
- if (!q)
- bi->relay_port = bi->telnet_port;
- else
- bi->relay_port = atoi(q + 1);
- }
- set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, argv[1]), bi);
- Tcl_AppendResult(irp, "1", NULL);
- }
- return TCL_OK;
- }
- static int tcl_deluser STDVAR
- {
- BADARGS(2, 2, " handle");
- Tcl_AppendResult(irp, (argv[1][0] == '*') ? "0" :
- int_to_base10(deluser(argv[1])), NULL);
- return TCL_OK;
- }
- static int tcl_delhost STDVAR
- {
- BADARGS(3, 3, " handle hostmask");
- if ((!get_user_by_handle(userlist, argv[1])) || (argv[1][0] == '*')) {
- Tcl_AppendResult(irp, "non-existent user", NULL);
- return TCL_ERROR;
- }
- Tcl_AppendResult(irp, delhost_by_handle(argv[1], argv[2]) ? "1" : "0",
- NULL);
- return TCL_OK;
- }
- static int tcl_userlist STDVAR
- {
- struct userrec *u;
- struct flag_record user, plus, minus;
- int ok = 1, f = 0;
- BADARGS(1, 3, " ?flags ?channel??");
- if (argc == 3 && !findchan_by_dname(argv[2])) {
- Tcl_AppendResult(irp, "Invalid channel: ", argv[2], NULL);
- return TCL_ERROR;
- }
- if (argc >= 2) {
- plus.match = FR_GLOBAL | FR_CHAN | FR_BOT;
- break_down_flags(argv[1], &plus, &minus);
- f = (minus.global || minus.udef_global || minus.chan ||
- minus.udef_chan || minus.bot);
- }
- minus.match = plus.match ^ (FR_AND | FR_OR);
- for (u = userlist; u; u = u->next) {
- if (argc >= 2) {
- user.match = FR_GLOBAL | FR_CHAN | FR_BOT | (argc == 3 ? 0 : FR_ANYWH);
- if (argc == 3)
- get_user_flagrec(u, &user, argv[2]);
- else
- get_user_flagrec(u, &user, NULL);
- if (flagrec_eq(&plus, &user) && !(f && flagrec_eq(&minus, &user)))
- ok = 1;
- else
- ok = 0;
- }
- if (ok)
- Tcl_AppendElement(interp, u->handle);
- }
- return TCL_OK;
- }
- #ifdef HUB
- static int tcl_save STDVAR
- {
- write_userfile(-1);
- return TCL_OK;
- }
- static int tcl_reload STDVAR
- {
- reload();
- return TCL_OK;
- }
- #endif
- static int tcl_chhandle STDVAR
- {
- struct userrec *u;
- char newhand[HANDLEN + 1];
- int x = 1, i;
- BADARGS(3, 3, " oldnick newnick");
- u = get_user_by_handle(userlist, argv[1]);
- if (!u)
- x = 0;
- else {
- strncpyz(newhand, argv[2], sizeof newhand);
- for (i = 0; i < strlen(newhand); i++)
- if ((newhand[i] <= 32) || (newhand[i] >= 127) || (newhand[i] == '@'))
- newhand[i] = '?';
- if (strchr(BADHANDCHARS, newhand[0]) != NULL)
- x = 0;
- else if (strlen(newhand) < 1)
- x = 0;
- else if (get_user_by_handle(userlist, newhand))
- x = 0;
- else if (!egg_strcasecmp(botnetnick, newhand) &&
- (!(u->flags & USER_BOT) || nextbot (argv [1]) != -1))
- x = 0;
- else if (newhand[0] == '*')
- x = 0;
- }
- if (x)
- x = change_handle(u, newhand);
- Tcl_AppendResult(irp, x ? "1" : "0", NULL);
- return TCL_OK;
- }
- static int tcl_getting_users STDVAR
- {
- int i;
- BADARGS(1, 1, "");
- for (i = 0; i < dcc_total; i++) {
- if (dcc[i].type == &DCC_BOT && dcc[i].status & STAT_GETTING) {
- Tcl_AppendResult(irp, "1", NULL);
- return TCL_OK;
- }
- }
- Tcl_AppendResult(irp, "0", NULL);
- return TCL_OK;
- }
- static int tcl_isignore STDVAR
- {
- BADARGS(2, 2, " nick!user@host");
- Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
- return TCL_OK;
- }
- static int tcl_newignore STDVAR
- {
- time_t expire_time;
- char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
- BADARGS(4, 5, " hostmask creator comment ?lifetime?");
- strncpyz(ign, argv[1], sizeof ign);
- strncpyz(from, argv[2], sizeof from);
- strncpyz(cmt, argv[3], sizeof cmt);
- if (argc == 4)
- expire_time = now + (60 * ignore_time);
- else {
- if (argc == 5 && atol(argv[4]) == 0)
- expire_time = 0L;
- else
- expire_time = now + (60 * atol(argv[4])); /* This is a potential crash. FIXME -poptix */
- }
- addignore(ign, from, cmt, expire_time);
- return TCL_OK;
- }
- static int tcl_killignore STDVAR
- {
- BADARGS(2, 2, " hostmask");
- Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
- return TCL_OK;
- }
- /* { hostmask note expire-time create-time creator }
- */
- static int tcl_ignorelist STDVAR
- {
- struct igrec *i;
- char expire[11], added[11], *p;
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- CONST char *list[5];
- #else
- char *list[5];
- #endif
- BADARGS(1, 1, "");
- for (i = global_ign; i; i = i->next) {
- list[0] = i->igmask;
- list[1] = i->msg;
- egg_snprintf(expire, sizeof expire, "%lu", i->expire);
- list[2] = expire;
- egg_snprintf(added, sizeof added, "%lu", i->added);
- list[3] = added;
- list[4] = i->user;
- p = Tcl_Merge(5, list);
- Tcl_AppendElement(irp, p);
- Tcl_Free((char *) p);
- }
- return TCL_OK;
- }
- static int tcl_getuser STDVAR
- {
- struct user_entry_type *et;
- struct userrec *u;
- struct user_entry *e;
- BADARGS(3, 999, " handle type");
- if (!(et = find_entry_type(argv[2])) && egg_strcasecmp(argv[2], "HANDLE")) {
- Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
- return TCL_ERROR;
- }
- if (!(u = get_user_by_handle(userlist, argv[1]))) {
- if (argv[1][0] != '*') {
- Tcl_AppendResult(irp, "No such user.", NULL);
- return TCL_ERROR;
- } else
- return TCL_OK; /* silently ignore user * */
- }
- if (!egg_strcasecmp(argv[2], "HANDLE")) {
- Tcl_AppendResult(irp,u->handle, NULL);
- } else {
- e = find_user_entry(et, u);
- if (e)
- return et->tcl_get(irp, u, e, argc, argv);
- }
- return TCL_OK;
- }
- static int tcl_setuser STDVAR
- {
- struct user_entry_type *et;
- struct userrec *u;
- struct user_entry *e;
- int r;
- module_entry *me;
- BADARGS(3, 999, " handle type ?setting....?");
- if (!(et = find_entry_type(argv[2]))) {
- Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
- return TCL_ERROR;
- }
- if (!(u = get_user_by_handle(userlist, argv[1]))) {
- if (argv[1][0] != '*') {
- Tcl_AppendResult(irp, "No such user.", NULL);
- return TCL_ERROR;
- } else
- return TCL_OK; /* Silently ignore user * */
- }
- me = module_find("irc", 0, 0);
- if (me && !strcmp(argv[2], "hosts") && argc == 3) {
- Function *func = me->funcs;
- (func[IRC_CHECK_THIS_USER]) (argv[1], 1, NULL);
- }
- if (!(e = find_user_entry(et, u))) {
- e = user_malloc(sizeof(struct user_entry));
- e->type = et;
- e->name = NULL;
- e->u.list = NULL;
- list_insert((&(u->entries)), e);
- }
- r = et->tcl_set(irp, u, e, argc, argv);
- /* Yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
- if (!e->u.list) {
- if (list_delete((struct list_type **) &(u->entries),
- (struct list_type *) e))
- nfree(e);
- /* else maybe already freed... (entry_type==HOSTS) <drummer> */
- }
- if (me && !strcmp(argv[2], "hosts") && argc == 4) {
- Function *func = me->funcs;
- (func[IRC_CHECK_THIS_USER]) (argv[1], 0, NULL);
- }
- return r;
- }
- tcl_cmds tcluser_cmds[] =
- {
- {"countusers", tcl_countusers},
- {"validuser", tcl_validuser},
- {"finduser", tcl_finduser},
- {"passwdok", tcl_passwdOk},
- {"chattr", tcl_chattr},
- {"botattr", tcl_botattr},
- {"matchattr", tcl_matchattr},
- {"matchchanattr", tcl_matchattr},
- {"adduser", tcl_adduser},
- {"addbot", tcl_addbot},
- {"deluser", tcl_deluser},
- {"delhost", tcl_delhost},
- {"userlist", tcl_userlist},
- #ifdef HUB
- {"save", tcl_save},
- {"reload", tcl_reload},
- #endif
- {"chhandle", tcl_chhandle},
- {"chnick", tcl_chhandle},
- {"getting-users", tcl_getting_users},
- {"isignore", tcl_isignore},
- {"newignore", tcl_newignore},
- {"killignore", tcl_killignore},
- {"ignorelist", tcl_ignorelist},
- {"getuser", tcl_getuser},
- {"setuser", tcl_setuser},
- {NULL, NULL}
- };
|