| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648 |
- /*
- * userent.c -- handles:
- * user-entry handling, new stylem more versatile.
- *
- */
- #include "main.h"
- #include "users.h"
- extern int noshare, cfg_noshare, cfg_count;
- extern struct cfg_entry **cfg;
- extern struct userrec *userlist;
- extern struct dcc_t *dcc;
- extern Tcl_Interp *interp;
- extern char whois_fields[], botnetnick[];
- extern time_t now;
- int share_greet = 0; /* Share greeting info */
- static struct user_entry_type *entry_type_list;
- void init_userent()
- {
- entry_type_list = 0;
- add_entry_type(&USERENTRY_COMMENT);
- add_entry_type(&USERENTRY_XTRA);
- add_entry_type(&USERENTRY_INFO);
- add_entry_type(&USERENTRY_LASTON);
- add_entry_type(&USERENTRY_BOTADDR);
- add_entry_type(&USERENTRY_PASS);
- add_entry_type(&USERENTRY_SECPASS);
- add_entry_type(&USERENTRY_HOSTS);
- add_entry_type(&USERENTRY_BOTFL);
- add_entry_type(&USERENTRY_STATS);
- add_entry_type(&USERENTRY_ADDED);
- add_entry_type(&USERENTRY_CONFIG);
- }
- void list_type_kill(struct list_type *t)
- {
- struct list_type *u;
- while (t) {
- u = t->next;
- if (t->extra)
- nfree(t->extra);
- nfree(t);
- t = u;
- }
- }
- int list_type_expmem(struct list_type *t)
- {
- int tot = 0;
- for (; t; t = t->next)
- tot += sizeof(struct list_type) + strlen(t->extra) + 1;
- return tot;
- }
- int def_unpack(struct userrec *u, struct user_entry *e)
- {
- char *tmp;
- tmp = e->u.list->extra;
- e->u.list->extra = NULL;
- list_type_kill(e->u.list);
- e->u.string = tmp;
- return 1;
- }
- int def_pack(struct userrec *u, struct user_entry *e)
- {
- char *tmp;
- tmp = e->u.string;
- e->u.list = user_malloc(sizeof(struct list_type));
- e->u.list->next = NULL;
- e->u.list->extra = tmp;
- return 1;
- }
- int def_kill(struct user_entry *e)
- {
- nfree(e->u.string);
- nfree(e);
- return 1;
- }
- int def_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
- {
- if (lfprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
- return 0;
- return 1;
- }
- void *def_get(struct userrec *u, struct user_entry *e)
- {
- return e->u.string;
- }
- int def_set(struct userrec *u, struct user_entry *e, void *buf)
- {
- char *string = (char *) buf;
- if (string && !string[0])
- string = NULL;
- if (!string && !e->u.string)
- return 1;
- if (string) {
- int l = strlen (string);
- char *i;
- if (l > 160)
- l = 160;
- e->u.string = user_realloc (e->u.string, l + 1);
- strncpyz (e->u.string, string, l + 1);
- for (i = e->u.string; *i; i++)
- /* Allow bold, inverse, underline, color text here...
- * But never add cr or lf!! --rtc
- */
- if ((unsigned int) *i < 32 && !strchr ("\002\003\026\037", *i))
- *i = '?';
- } else { /* string == NULL && e->u.string != NULL */
- nfree(e->u.string);
- e->u.string = NULL;
- }
- if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED))) {
- if (e->type != &USERENTRY_INFO || share_greet)
- shareout(NULL, "c %s %s %s\n", e->type->name, u->handle,
- e->u.string ? e->u.string : "");
- }
- return 1;
- }
- int def_gotshare(struct userrec *u, struct user_entry *e,
- char *data, int idx)
- {
- #ifdef HUB
- putlog(LOG_CMDS, "@", "%s: change %s %s", dcc[idx].nick, e->type->name,
- u->handle);
- #endif
- return e->type->set(u, e, data);
- }
- int def_tcl_get(Tcl_Interp * interp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- Tcl_AppendResult(interp, e->u.string, NULL);
- return TCL_OK;
- }
- int def_tcl_set(Tcl_Interp * irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- BADARGS(4, 4, " handle type setting");
- e->type->set(u, e, argv[3]);
- return TCL_OK;
- }
- int def_expmem(struct user_entry *e)
- {
- return strlen(e->u.string) + 1;
- }
- void def_display(int idx, struct user_entry *e, struct userrec *u)
- {
- dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
- }
- int def_dupuser(struct userrec *new, struct userrec *old,
- struct user_entry *e)
- {
- return set_user(e->type, new, e->u.string);
- }
- static void comment_display(int idx, struct user_entry *e, struct userrec *u)
- {
- if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
- dprintf(idx, " COMMENT: %s\n", e->u.string);
- }
- struct user_entry_type USERENTRY_COMMENT =
- {
- 0, /* always 0 ;) */
- def_gotshare,
- def_dupuser,
- def_unpack,
- def_pack,
- def_write_userfile,
- def_kill,
- def_get,
- def_set,
- def_tcl_get,
- def_tcl_set,
- def_expmem,
- comment_display,
- "COMMENT"
- };
- struct user_entry_type USERENTRY_INFO =
- {
- 0, /* always 0 ;) */
- def_gotshare,
- def_dupuser,
- def_unpack,
- def_pack,
- def_write_userfile,
- def_kill,
- def_get,
- def_set,
- def_tcl_get,
- def_tcl_set,
- def_expmem,
- def_display,
- "INFO"
- };
- void added_display(int idx, struct user_entry *e, struct userrec *u)
- {
- /* format: unixtime handle */
- if (dcc[idx].user && (dcc[idx].user->flags & USER_OWNER)) {
- char tmp[30],
- tmp2[70],
- *hnd;
- time_t tm;
- strncpy0(tmp, e->u.string, sizeof(tmp));
- hnd = strchr(tmp, ' ');
- if (hnd)
- *hnd++ = 0;
- tm = atoi(tmp);
- strftime(tmp2, sizeof(tmp2), STR("%a, %d %b %Y %H:%M:%S GMT"), gmtime(&tm));
- if (hnd)
- dprintf(idx, STR(" -- Added %s by %s\n"), tmp2, hnd);
- else
- dprintf(idx, STR(" -- Added %s\n"), tmp2);
- }
- }
- int added_gotshare(struct userrec *u, struct user_entry *e, char *data, int idx)
- {
- return e->type->set(u, e, data);
- }
- struct user_entry_type USERENTRY_ADDED = {
- 0, /* always 0 ;) */
- added_gotshare,
- def_dupuser,
- def_unpack,
- def_pack,
- def_write_userfile,
- def_kill,
- def_get,
- def_set,
- 0,
- 0,
- def_expmem,
- added_display,
- "ADDED"
- };
- int config_set(struct userrec *u, struct user_entry *e, void *buf)
- {
- struct xtra_key *curr,
- *old = NULL,
- *new = buf;
- for (curr = e->u.extra; curr; curr = curr->next) {
- if (curr->key && !egg_strcasecmp(curr->key, new->key)) {
- old = curr;
- break;
- }
- }
- if (!old && (!new->data || !new->data[0])) {
- /* delete non-existant entry -- doh ++rtc */
- nfree(new->key);
- if (new->data)
- nfree(new->data);
- nfree(new);
- return 1;
- }
- /* we will possibly free new below, so let's send the information
- * to the botnet now */
- if (!noshare && !cfg_noshare) {
- shareout(NULL, STR("c CONFIG %s %s %s\n"), u->handle, new->key, new->data ? new->data : "");
- }
- if ((old && old != new) || !new->data || !new->data[0]) {
- list_delete((struct list_type **) (&e->u.extra), (struct list_type *) old);
- nfree(old->key);
- nfree(old->data);
- nfree(old);
- }
- if (old != new && new->data) {
- if (new->data[0]) {
- list_insert((&e->u.extra), new);
- } else {
- nfree(new->data);
- nfree(new->key);
- nfree(new);
- }
- }
- return 1;
- }
- int config_unpack(struct userrec *u, struct user_entry *e)
- {
- struct list_type *curr,
- *head;
- struct xtra_key *t;
- char *key,
- *data;
- head = curr = e->u.list;
- e->u.extra = NULL;
- while (curr) {
- t = user_malloc(sizeof(struct xtra_key));
- data = curr->extra;
- key = newsplit(&data);
- if (data[0]) {
- t->key = user_malloc(strlen(key) + 1);
- strcpy(t->key, key);
- t->data = user_malloc(strlen(data) + 1);
- strcpy(t->data, data);
- list_insert((&e->u.extra), t);
- }
- curr = curr->next;
- }
- list_type_kill(head);
- return 1;
- }
- int config_pack(struct userrec *u, struct user_entry *e)
- {
- struct list_type *t;
- struct xtra_key *curr,
- *next;
- curr = e->u.extra;
- e->u.list = NULL;
- while (curr) {
- t = user_malloc(sizeof(struct list_type));
- t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
- sprintf(t->extra, STR("%s %s"), curr->key, curr->data);
- list_insert((&e->u.list), t);
- next = curr->next;
- nfree(curr->key);
- nfree(curr->data);
- nfree(curr);
- curr = next;
- }
- return 1;
- }
- void config_display(int idx, struct user_entry *e, struct userrec *u)
- {
- #ifdef HUB
- struct xtra_key *xk;
- struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
- get_user_flagrec(dcc[idx].user, &fr, NULL);
- /* scan thru xtra field, searching for matches */
- for (xk = e->u.extra; xk; xk = xk->next) {
- /* ok, it's a valid xtra field entry */
- if (glob_owner(fr))
- dprintf(idx, STR(" %s: %s\n"), xk->key, xk->data);
- }
- #endif
- }
- int config_gotshare(struct userrec *u, struct user_entry *e, char *buf, int idx)
- {
- char *arg;
- struct xtra_key *xk;
- int l;
- arg = newsplit(&buf);
- if (!arg[0])
- return 1;
- if (!strcmp(u->handle, botnetnick)) {
- struct cfg_entry *cfgent = NULL;
- int i;
- cfg_noshare++;
- for (i = 0; !cfgent && (i < cfg_count); i++)
- if (!strcmp(arg, cfg[i]->name) && (cfg[i]->flags & CFGF_LOCAL))
- cfgent = cfg[i];
- if (cfgent) {
- set_cfg_str(botnetnick, cfgent->name, buf[0] ? buf : NULL);
- }
- cfg_noshare--;
- return 1;
- }
- xk = user_malloc(sizeof(struct xtra_key));
- egg_bzero(xk, sizeof(struct xtra_key));
- l = strlen(arg);
- if (l > 1500)
- l = 1500;
- xk->key = user_malloc(l + 1);
- strncpy0(xk->key, arg, l + 1);
- if (buf[0]) {
- int k = strlen(buf);
- if (k > 1500 - l)
- k = 1500 - l;
- xk->data = user_malloc(k + 1);
- strncpy0(xk->data, buf, k + 1);
- }
- config_set(u, e, xk);
- return 1;
- }
- int config_dupuser(struct userrec *new, struct userrec *old, struct user_entry *e)
- {
- struct xtra_key *x1,
- *x2;
- for (x1 = e->u.extra; x1; x1 = x1->next) {
- x2 = user_malloc(sizeof(struct xtra_key));
- x2->key = user_malloc(strlen(x1->key) + 1);
- strcpy(x2->key, x1->key);
- x2->data = user_malloc(strlen(x1->data) + 1);
- strcpy(x2->data, x1->data);
- set_user(&USERENTRY_CONFIG, new, x2);
- }
- return 1;
- }
- int config_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
- {
- struct xtra_key *x;
- for (x = e->u.extra; x; x = x->next)
- lfprintf(f, STR("--CONFIG %s %s\n"), x->key, x->data);
- return 1;
- }
- int config_kill(struct user_entry *e)
- {
- struct xtra_key *x,
- *y;
- for (x = e->u.extra; x; x = y) {
- y = x->next;
- nfree(x->key);
- nfree(x->data);
- nfree(x);
- }
- nfree(e);
- return 1;
- }
- /* FIXME: possible expmem leak here */
- int config_expmem(struct user_entry *e)
- {
- struct xtra_key *x;
- int tot = 0;
- for (x = e->u.extra; x; x = x->next) {
- tot += sizeof(struct xtra_key);
- tot += strlen(x->key) + 1;
- tot += strlen(x->data) + 1;
- }
- return tot;
- }
- struct user_entry_type USERENTRY_CONFIG = {
- 0,
- config_gotshare,
- config_dupuser,
- config_unpack,
- config_pack,
- config_write_userfile,
- config_kill,
- def_get,
- config_set,
- 0,
- 0,
- config_expmem,
- config_display,
- "CONFIG"
- };
- void stats_add(struct userrec *u, int login, int op)
- {
- char *s,
- s2[50];
- int sl,
- so;
- if (!u)
- return;
- s = get_user(&USERENTRY_STATS, u);
- if (s) {
- strncpy0(s2, s, sizeof(s2));
- } else
- strcpy(s2, STR("0 0"));
- s = strchr(s2, ' ');
- if (s) {
- s++;
- so = atoi(s);
- } else
- so = 0;
- sl = atoi(s2);
- if (login)
- sl++;
- if (op)
- so++;
- sprintf(s2, STR("%i %i"), sl, so);
- set_user(&USERENTRY_STATS, u, s2);
- }
- void stats_display(int idx, struct user_entry *e, struct userrec *u)
- {
- /* format: logincount opcount */
- if (dcc[idx].user && (dcc[idx].user->flags & USER_OWNER)) {
- char *p;
- p = strchr(e->u.string, ' ');
- if (p)
- dprintf(idx, STR(" -- %i logins, %i ops\n"), atoi(e->u.string), atoi(p));
- }
- }
- int stats_gotshare(struct userrec *u, struct user_entry *e, char *data, int idx)
- {
- return e->type->set(u, e, data);
- }
- struct user_entry_type USERENTRY_STATS = {
- 0, /* always 0 ;) */
- stats_gotshare,
- def_dupuser,
- def_unpack,
- def_pack,
- def_write_userfile,
- def_kill,
- def_get,
- def_set,
- 0,
- 0,
- def_expmem,
- stats_display,
- "STATS"
- };
- int pass_set(struct userrec *u, struct user_entry *e, void *buf)
- {
- char new[32];
- register char *pass = buf;
- if (e->u.extra)
- nfree(e->u.extra);
- if (!pass || !pass[0] || (pass[0] == '-'))
- e->u.extra = NULL;
- else {
- unsigned char *p = (unsigned char *) pass;
- if (strlen(pass) > 15)
- pass[15] = 0;
- while (*p) {
- if ((*p <= 32) || (*p == 127))
- *p = '?';
- p++;
- }
- if ((u->flags & USER_BOT) || (pass[0] == '+'))
- strcpy(new, pass);
- else
- encrypt_pass(pass, new);
- e->u.extra = user_malloc(strlen(new) + 1);
- strcpy(e->u.extra, new);
- }
- if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
- shareout(NULL, "c PASS %s %s\n", u->handle, pass ? pass : "");
- return 1;
- }
- static int pass_tcl_set(Tcl_Interp * irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- BADARGS(3, 4, " handle PASS ?newpass?");
- pass_set(u, e, argc == 3 ? NULL : argv[3]);
- return TCL_OK;
- }
- struct user_entry_type USERENTRY_PASS =
- {
- 0,
- def_gotshare,
- 0,
- def_unpack,
- def_pack,
- def_write_userfile,
- def_kill,
- def_get,
- pass_set,
- def_tcl_get,
- pass_tcl_set,
- def_expmem,
- 0,
- "PASS"
- };
- void secpass_display(int idx, struct user_entry *e, struct userrec *u)
- {
- struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
- get_user_flagrec(dcc[idx].user, &fr, NULL);
- if (!strcmp(u->handle, dcc[idx].nick) || glob_admin(fr)) {
- #ifdef HUB
- dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
- #else
- dprintf(idx, " %s: Hidden on leaf bots.", e->type->name);
- if (dcc[idx].u.chat->su_nick)
- dprintf(idx, " Nice try, %s.", dcc[idx].u.chat->su_nick);
- dprintf(idx, "\n");
- #endif /* HUB */
- }
- }
- struct user_entry_type USERENTRY_SECPASS =
- {
- 0,
- def_gotshare,
- def_dupuser,
- def_unpack,
- def_pack,
- def_write_userfile,
- def_kill,
- def_get,
- def_set,
- 0,
- 0,
- def_expmem,
- secpass_display,
- "SECPASS"
- };
- static int laston_unpack(struct userrec *u, struct user_entry *e)
- {
- char *par, *arg;
- struct laston_info *li;
- par = e->u.list->extra;
- arg = newsplit (&par);
- if (!par[0])
- par = "???";
- li = user_malloc(sizeof(struct laston_info));
- li->lastonplace = user_malloc(strlen(par) + 1);
- li->laston = atoi(arg);
- strcpy(li->lastonplace, par);
- list_type_kill(e->u.list);
- e->u.extra = li;
- return 1;
- }
- static int laston_pack(struct userrec *u, struct user_entry *e)
- {
- char work[1024];
- struct laston_info *li;
- int l;
- li = (struct laston_info *) e->u.extra;
- l = sprintf(work, "%lu %s", li->laston, li->lastonplace);
- e->u.list = user_malloc(sizeof(struct list_type));
- e->u.list->next = NULL;
- e->u.list->extra = user_malloc(l + 1);
- strcpy(e->u.list->extra, work);
- nfree(li->lastonplace);
- nfree(li);
- return 1;
- }
- static int laston_write_userfile(FILE * f,
- struct userrec *u,
- struct user_entry *e)
- {
- struct laston_info *li = (struct laston_info *) e->u.extra;
- if (lfprintf(f, "--LASTON %lu %s\n", li->laston,
- li->lastonplace ? li->lastonplace : "") == EOF)
- return 0;
- return 1;
- }
- static int laston_kill(struct user_entry *e)
- {
- if (((struct laston_info *) (e->u.extra))->lastonplace)
- nfree(((struct laston_info *) (e->u.extra))->lastonplace);
- nfree(e->u.extra);
- nfree(e);
- return 1;
- }
- static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
- {
- struct laston_info *li = (struct laston_info *) e->u.extra;
- if (li != buf) {
- if (li) {
- nfree(li->lastonplace);
- nfree(li);
- }
- li = e->u.extra = buf;
- }
- /* donut share laston info */
- return 1;
- }
- static int laston_tcl_get(Tcl_Interp * irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- struct laston_info *li = (struct laston_info *) e->u.extra;
- char number[20];
- struct chanuserrec *cr;
- BADARGS(3, 4, " handle LASTON ?channel?");
- if (argc == 4) {
- for (cr = u->chanrec; cr; cr = cr->next)
- if (!rfc_casecmp(cr->channel, argv[3])) {
- Tcl_AppendResult(irp, int_to_base10(cr->laston), NULL);
- break;
- }
- if (!cr)
- Tcl_AppendResult(irp, "0", NULL);
- } else {
- sprintf(number, "%lu ", li->laston);
- Tcl_AppendResult(irp, number, li->lastonplace, NULL);
- }
- return TCL_OK;
- }
- static int laston_tcl_set(Tcl_Interp * irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- struct laston_info *li;
- struct chanuserrec *cr;
- BADARGS(4, 5, " handle LASTON time ?place?");
- if ((argc == 5) && argv[4][0] && strchr(CHANMETA, argv[4][0])) {
- /* Search for matching channel */
- for (cr = u->chanrec; cr; cr = cr->next)
- if (!rfc_casecmp(cr->channel, argv[4])) {
- cr->laston = atoi(argv[3]);
- break;
- }
- }
- /* Save globally */
- li = user_malloc(sizeof(struct laston_info));
- if (argc == 5) {
- li->lastonplace = user_malloc(strlen(argv[4]) + 1);
- strcpy(li->lastonplace, argv[4]);
- } else {
- li->lastonplace = user_malloc(1);
- li->lastonplace[0] = 0;
- }
- li->laston = atoi(argv[3]);
- set_user(&USERENTRY_LASTON, u, li);
- return TCL_OK;
- }
- /* FIXME: possible expmem leak here */
- static int laston_expmem(struct user_entry *e)
- {
- return sizeof(struct laston_info) +
- strlen(((struct laston_info *) (e->u.extra))->lastonplace) + 1;
- }
- static int laston_dupuser(struct userrec *new, struct userrec *old,
- struct user_entry *e)
- {
- struct laston_info *li = e->u.extra, *li2;
- if (li) {
- li2 = user_malloc(sizeof(struct laston_info));
- li2->laston = li->laston;
- li2->lastonplace = user_malloc(strlen(li->lastonplace) + 1);
- strcpy(li2->lastonplace, li->lastonplace);
- return set_user(&USERENTRY_LASTON, new, li2);
- }
- return 0;
- }
- struct user_entry_type USERENTRY_LASTON =
- {
- 0, /* always 0 ;) */
- 0,
- laston_dupuser,
- laston_unpack,
- laston_pack,
- laston_write_userfile,
- laston_kill,
- def_get,
- laston_set,
- laston_tcl_get,
- laston_tcl_set,
- laston_expmem,
- 0,
- "LASTON"
- };
- static int botaddr_unpack(struct userrec *u, struct user_entry *e)
- {
- char p[1024],
- *q1,
- *q2;
- struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
- bzero(bi, sizeof(struct bot_addr));
- /* address:port/port:hublevel:uplink */
- Context;
- Assert(e);
- Assert(e->name);
- bzero(bi, sizeof(struct bot_addr));
- strcpy(p, e->u.list->extra);
- q1 = strchr(p, ':');
- if (q1)
- *q1++ = 0;
- bi->address = user_malloc(strlen(p) + 1);
- strcpy(bi->address, p);
- if (q1) {
- q2 = strchr(q1, ':');
- if (q2)
- *q2++ = 0;
- bi->telnet_port = atoi(q1);
- q1 = strchr(q1, '/');
- if (q1) {
- q1++;
- bi->relay_port = atoi(q1);
- }
- if (q2) {
- q1 = strchr(q2, ':');
- if (q1) {
- *q1++ = 0;
- bi->uplink = user_malloc(strlen(q1) + 1);
- strcpy(bi->uplink, q1);
- }
- bi->hublevel = atoi(q2);
- }
- }
- if (!bi->telnet_port)
- bi->telnet_port = 3333;
- if (!bi->relay_port)
- bi->relay_port = bi->telnet_port;
- if (!bi->uplink) {
- bi->uplink = user_malloc(1);
- bi->uplink[0] = 0;
- }
- list_type_kill(e->u.list);
- e->u.extra = bi;
- return 1;
- }
- static int botaddr_pack(struct userrec *u, struct user_entry *e)
- {
- char work[1024];
- struct bot_addr *bi;
- int l;
- Assert(e);
- Assert(!e->name);
- bi = (struct bot_addr *) e->u.extra;
- l = simple_sprintf(work, STR("%s:%u/%u:%u:%s"), bi->address, bi->telnet_port, bi->relay_port, bi->hublevel, bi->uplink);
- e->u.list = user_malloc(sizeof(struct list_type));
- e->u.list->next = NULL;
- e->u.list->extra = user_malloc(l + 1);
- strcpy(e->u.list->extra, work);
- nfree(bi->address);
- nfree(bi->uplink);
- nfree(bi);
- return 1;
- }
- static int botaddr_kill(struct user_entry *e)
- {
- nfree(((struct bot_addr *) (e->u.extra))->address);
- nfree(((struct bot_addr *) (e->u.extra))->uplink);
- nfree(e->u.extra);
- nfree(e);
- return 1;
- }
- static int botaddr_write_userfile(FILE *f, struct userrec *u,
- struct user_entry *e)
- {
- register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
- if (lfprintf(f, "--%s %s:%u/%u:%u:%s\n", e->type->name, bi->address,
- bi->telnet_port, bi->relay_port, bi->hublevel, bi->uplink) == EOF)
- return 0;
- return 1;
- }
- static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
- {
- register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
- Context;
- if (!bi && !buf)
- return 1;
- if (bi != buf) {
- if (bi) {
- Assert(bi->address);
- nfree(bi->address);
- Assert(bi->uplink);
- nfree(bi->uplink);
- nfree(bi);
- }
- ContextNote("(sharebug) occurred in botaddr_set");
- bi = e->u.extra = buf;
- }
- Assert(u);
- if (bi && !noshare && !(u->flags & USER_UNSHARED)) {
- shareout(NULL, STR("c BOTADDR %s %s %d %d %d %s\n"),u->handle, (bi->address && bi->address[0]) ? bi->address : STR("127.0.0.1"), bi->telnet_port, bi->relay_port, bi->hublevel, bi->uplink);
- }
- return 1;
- }
- static int botaddr_tcl_get(Tcl_Interp *interp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
- char number[20];
- Context;
- sprintf(number, STR(" %d"), bi->telnet_port);
- Tcl_AppendResult(interp, bi->address, number, NULL);
- sprintf(number, STR(" %d"), bi->relay_port);
- Tcl_AppendResult(interp, number, NULL);
- sprintf(number, STR(" %d"), bi->hublevel);
- Tcl_AppendResult(interp, number, NULL);
- Tcl_AppendResult(interp, bi->uplink, NULL);
- return TCL_OK;
- }
- static int botaddr_tcl_set(Tcl_Interp *irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
- BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
- if (u->flags & USER_BOT) {
- /* Silently ignore for users */
- if (!bi) {
- bi = user_malloc(sizeof(struct bot_addr));
- egg_bzero(bi, sizeof (struct bot_addr));
- } else {
- nfree(bi->address);
- }
- bi->address = user_malloc(strlen(argv[3]) + 1);
- strcpy(bi->address, argv[3]);
- if (argc > 4)
- bi->telnet_port = atoi(argv[4]);
- if (argc > 5)
- bi->relay_port = atoi(argv[5]);
- if (!bi->telnet_port)
- bi->telnet_port = 3333;
- if (!bi->relay_port)
- bi->relay_port = bi->telnet_port;
- botaddr_set(u, e, bi);
- }
- return TCL_OK;
- }
- /* FIXME: possible expmem leak here */
- static int botaddr_expmem(struct user_entry *e)
- {
- register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
- Context;
- return strlen(bi->address) + 1 + strlen(bi->uplink) + 1 + sizeof(struct bot_addr);
- }
- static void botaddr_display(int idx, struct user_entry *e, struct userrec *u)
- {
- #ifdef HUB
- struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
- get_user_flagrec(dcc[idx].user, &fr, NULL);
- if (glob_admin(fr)) {
- register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
- dprintf(idx, STR(" ADDRESS: %.70s\n"), bi->address);
- dprintf(idx, STR(" telnet: %d, relay: %d\n"), bi->telnet_port, bi->relay_port);
- dprintf(idx, STR(" hublevel: %d, uplink: %s\n"), bi->hublevel, bi->uplink);
- }
- #endif
- }
- static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
- char *buf, int idx)
- {
- struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
- char *arg;
- bzero(bi, sizeof(struct bot_addr));
- arg = newsplit(&buf);
- bi->address = user_malloc(strlen(arg) + 1);
- strcpy(bi->address, arg);
- arg = newsplit(&buf);
- bi->telnet_port = atoi(arg);
- arg = newsplit(&buf);
- bi->relay_port = atoi(arg);
- arg = newsplit(&buf);
- bi->hublevel = atoi(arg);
- bi->uplink = user_malloc(strlen(buf) + 1);
- strcpy(bi->uplink, buf);
- if (!bi->telnet_port)
- bi->telnet_port = 3333;
- if (!bi->relay_port)
- bi->relay_port = bi->telnet_port;
- return botaddr_set(u, e, bi);
- }
- static int botaddr_dupuser(struct userrec *new, struct userrec *old,
- struct user_entry *e)
- {
- if (old->flags & USER_BOT) {
- struct bot_addr *bi = e->u.extra,
- *bi2;
- if (bi) {
- bi2 = user_malloc(sizeof(struct bot_addr));
- bi2->telnet_port = bi->telnet_port;
- bi2->relay_port = bi->relay_port;
- bi2->hublevel = bi->hublevel;
- bi2->address = user_malloc(strlen(bi->address) + 1);
- bi2->uplink = user_malloc(strlen(bi->uplink) + 1);
- strcpy(bi2->address, bi->address);
- strcpy(bi2->uplink, bi->uplink);
- return set_user(&USERENTRY_BOTADDR, new, bi2);
- }
- }
- return 0;
- }
- struct user_entry_type USERENTRY_BOTADDR =
- {
- 0, /* always 0 ;) */
- botaddr_gotshare,
- botaddr_dupuser,
- botaddr_unpack,
- botaddr_pack,
- botaddr_write_userfile,
- botaddr_kill,
- def_get,
- botaddr_set,
- botaddr_tcl_get,
- botaddr_tcl_set,
- botaddr_expmem,
- botaddr_display,
- "BOTADDR"
- };
- int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
- {
- struct xtra_key *curr, *old = NULL, *new = buf;
- for (curr = e->u.extra; curr; curr = curr->next) {
- if (curr->key && !egg_strcasecmp(curr->key, new->key)) {
- old = curr;
- break;
- }
- }
- if (!old && (!new->data || !new->data[0])) {
- /* Delete non-existant entry -- doh ++rtc */
- nfree(new->key);
- if (new->data)
- nfree(new->data);
- nfree(new);
- return TCL_OK;
- }
- /* We will possibly free new below, so let's send the information
- * to the botnet now
- */
- if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
- shareout(NULL, "c XTRA %s %s %s\n", u->handle, new->key,
- new->data ? new->data : "");
- if ((old && old != new) || !new->data || !new->data[0]) {
- list_delete((struct list_type **) (&e->u.extra),
- (struct list_type *) old);
- nfree(old->key);
- nfree(old->data);
- nfree(old);
- }
- if (old != new && new->data) {
- if (new->data[0])
- list_insert((&e->u.extra), new) /* do not add a ';' here */
- } else {
- if (new->data)
- nfree(new->data);
- nfree(new->key);
- nfree(new);
- }
- return TCL_OK;
- }
- static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- struct xtra_key *xk;
- int l;
- BADARGS(4, 5, " handle type key ?value?");
- xk = user_malloc(sizeof(struct xtra_key));
- l = strlen(argv[3]);
- egg_bzero(xk, sizeof (struct xtra_key));
- if (l > 500)
- l = 500;
- xk->key = user_malloc(l + 1);
- strncpyz(xk->key, argv[3], l + 1);
- if (argc == 5) {
- int k = strlen(argv[4]);
- if (k > 500 - l)
- k = 500 - l;
- xk->data = user_malloc(k + 1);
- strncpyz(xk->data, argv[4], k + 1);
- }
- xtra_set(u, e, xk);
- return TCL_OK;
- }
- int xtra_unpack(struct userrec *u, struct user_entry *e)
- {
- struct list_type *curr, *head;
- struct xtra_key *t;
- char *key, *data;
- Context;
- head = curr = e->u.list;
- e->u.extra = NULL;
- while (curr) {
- t = user_malloc(sizeof(struct xtra_key));
- data = curr->extra;
- key = newsplit(&data);
- if (data[0]) {
- t->key = user_malloc(strlen(key) + 1);
- strcpy(t->key, key);
- t->data = user_malloc(strlen(data) + 1);
- strcpy(t->data, data);
- list_insert((&e->u.extra), t);
- }
- curr = curr->next;
- }
- list_type_kill(head);
- return 1;
- }
- static int xtra_pack(struct userrec *u, struct user_entry *e)
- {
- struct list_type *t;
- struct xtra_key *curr, *next;
- curr = e->u.extra;
- e->u.list = NULL;
- while (curr) {
- t = user_malloc(sizeof(struct list_type));
- t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
- sprintf(t->extra, "%s %s", curr->key, curr->data);
- list_insert((&e->u.list), t);
- next = curr->next;
- nfree(curr->key);
- nfree(curr->data);
- nfree(curr);
- curr = next;
- }
- return 1;
- }
- static void xtra_display(int idx, struct user_entry *e, struct userrec *u)
- {
- int code, lc, j;
- struct xtra_key *xk;
- #if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
- CONST char **list;
- #else
- char **list;
- #endif
- code = Tcl_SplitList(interp, whois_fields, &lc, &list);
- if (code == TCL_ERROR)
- return;
- /* Scan thru xtra field, searching for matches */
- for (xk = e->u.extra; xk; xk = xk->next) {
- /* Ok, it's a valid xtra field entry */
- for (j = 0; j < lc; j++) {
- if (!egg_strcasecmp(list[j], xk->key))
- dprintf(idx, " %s: %s\n", xk->key, xk->data);
- }
- }
- Tcl_Free((char *) list);
- }
- static int xtra_gotshare(struct userrec *u, struct user_entry *e,
- char *buf, int idx)
- {
- char *arg;
- struct xtra_key *xk;
- int l;
- arg = newsplit (&buf);
- if (!arg[0])
- return 1;
- xk = user_malloc (sizeof(struct xtra_key));
- egg_bzero(xk, sizeof(struct xtra_key));
- l = strlen(arg);
- if (l > 500)
- l = 500;
- xk->key = user_malloc(l + 1);
- strncpyz(xk->key, arg, l + 1);
- if (buf[0]) {
- int k = strlen(buf);
- if (k > 500 - l)
- k = 500 - l;
- xk->data = user_malloc(k + 1);
- strncpyz(xk->data, buf, k + 1);
- }
- xtra_set(u, e, xk);
- return 1;
- }
- static int xtra_dupuser(struct userrec *new, struct userrec *old,
- struct user_entry *e)
- {
- struct xtra_key *x1, *x2;
- for (x1 = e->u.extra; x1; x1 = x1->next) {
- x2 = user_malloc(sizeof(struct xtra_key));
- x2->key = user_malloc(strlen(x1->key) + 1);
- strcpy(x2->key, x1->key);
- x2->data = user_malloc(strlen(x1->data) + 1);
- strcpy(x2->data, x1->data);
- set_user(&USERENTRY_XTRA, new, x2);
- }
- return 1;
- }
- static int xtra_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
- {
- struct xtra_key *x;
- for (x = e->u.extra; x; x = x->next)
- if (lfprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
- return 0;
- return 1;
- }
- int xtra_kill(struct user_entry *e)
- {
- struct xtra_key *x, *y;
- for (x = e->u.extra; x; x = y) {
- y = x->next;
- nfree(x->key);
- nfree(x->data);
- nfree(x);
- }
- nfree(e);
- return 1;
- }
- static int xtra_tcl_get(Tcl_Interp *irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- struct xtra_key *x;
- BADARGS(3, 4, " handle XTRA ?key?");
- if (argc == 4) {
- for (x = e->u.extra; x; x = x->next)
- if (!egg_strcasecmp(argv[3], x->key)) {
- Tcl_AppendResult(irp, x->data, NULL);
- return TCL_OK;
- }
- return TCL_OK;
- }
- for (x = e->u.extra; x; x = x->next) {
- char *p;
- #if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
- CONST char *list[2];
- #else
- char *list[2];
- #endif
- list[0] = x->key;
- list[1] = x->data;
- p = Tcl_Merge(2, list);
- Tcl_AppendElement(irp, p);
- Tcl_Free((char *) p);
- }
- return TCL_OK;
- }
- /* FIXME: possible expmem leak here
- * also, ghost does not have xtra_ it was changed to config
- */
- static int xtra_expmem(struct user_entry *e)
- {
- struct xtra_key *x;
- int tot = 0;
- for (x = e->u.extra; x; x = x->next) {
- tot += sizeof(struct xtra_key);
- tot += strlen(x->key) + 1;
- tot += strlen(x->data) + 1;
- }
- return tot;
- }
- struct user_entry_type USERENTRY_XTRA =
- {
- 0,
- xtra_gotshare,
- xtra_dupuser,
- xtra_unpack,
- xtra_pack,
- xtra_write_userfile,
- xtra_kill,
- def_get,
- xtra_set,
- xtra_tcl_get,
- xtra_tcl_set,
- xtra_expmem,
- xtra_display,
- "XTRA"
- };
- static int hosts_dupuser(struct userrec *new, struct userrec *old,
- struct user_entry *e)
- {
- struct list_type *h;
- for (h = e->u.extra; h; h = h->next)
- set_user(&USERENTRY_HOSTS, new, h->extra);
- return 1;
- }
- static int hosts_null(struct userrec *u, struct user_entry *e)
- {
- return 1;
- }
- static int hosts_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
- {
- struct list_type *h;
- for (h = e->u.extra; h; h = h->next)
- if (lfprintf(f, "--HOSTS %s\n", h->extra) == EOF)
- return 0;
- return 1;
- }
- static int hosts_kill(struct user_entry *e)
- {
- list_type_kill(e->u.list);
- nfree(e);
- return 1;
- }
- static int hosts_expmem(struct user_entry *e)
- {
- return list_type_expmem(e->u.list);
- }
- static void hosts_display(int idx, struct user_entry *e, struct userrec *u)
- {
- #ifdef LEAF
- /* if this is a su, dont show hosts
- * otherwise, let users see their own hosts */
- if (!strcmp(u->handle,dcc[idx].nick) && !dcc[idx].u.chat->su_nick) {
- #endif /* LEAF */
- char s[1024];
- struct list_type *q;
- s[0] = 0;
- strcpy(s, " HOSTS: ");
- for (q = e->u.list; q; q = q->next) {
- if (s[0] && !s[9])
- strcat(s, q->extra);
- else if (!s[0])
- sprintf(s, " %s", q->extra);
- else {
- if (strlen(s) + strlen(q->extra) + 2 > 65) {
- dprintf(idx, "%s\n", s);
- sprintf(s, " %s", q->extra);
- } else {
- strcat(s, ", ");
- strcat(s, q->extra);
- }
- }
- }
- if (s[0])
- dprintf(idx, "%s\n", s);
- #ifdef LEAF
- } else {
- dprintf(idx, " HOSTS: Hidden on leaf bots.");
- if (dcc[idx].u.chat->su_nick)
- dprintf(idx, " Nice try, %s.", dcc[idx].u.chat->su_nick);
- dprintf(idx, "\n");
- }
- #endif /* LEAF */
- }
- static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
- {
- if (!buf || !egg_strcasecmp(buf, "none")) {
- /* When the bot crashes, it's in this part, not in the 'else' part */
- list_type_kill(e->u.list);
- e->u.list = NULL;
- } else {
- char *host = buf, *p = strchr(host, ',');
- struct list_type **t;
- /* Can't have ,'s in hostmasks */
- while (p) {
- *p = '?';
- p = strchr(host, ',');
- }
- /* fred1: check for redundant hostmasks with
- * controversial "superpenis" algorithm ;) */
- /* I'm surprised Raistlin hasn't gotten involved in this controversy */
- t = &(e->u.list);
- while (*t) {
- if (wild_match(host, (*t)->extra)) {
- struct list_type *u;
- u = *t;
- *t = (*t)->next;
- if (u->extra)
- nfree(u->extra);
- nfree(u);
- } else
- t = &((*t)->next);
- }
- *t = user_malloc(sizeof(struct list_type));
- (*t)->next = NULL;
- (*t)->extra = user_malloc(strlen(host) + 1);
- strcpy((*t)->extra, host);
- }
- return 1;
- }
- static int hosts_tcl_get(Tcl_Interp *irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- struct list_type *x;
- BADARGS(3, 3, " handle HOSTS");
- for (x = e->u.list; x; x = x->next)
- Tcl_AppendElement(irp, x->extra);
- return TCL_OK;
- }
- static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
- struct user_entry *e, int argc, char **argv)
- {
- BADARGS(3, 4, " handle HOSTS ?host?");
- if (argc == 4)
- addhost_by_handle(u->handle, argv[3]);
- else
- addhost_by_handle(u->handle, "none"); /* drummer */
- return TCL_OK;
- }
- static int hosts_gotshare(struct userrec *u, struct user_entry *e,
- char *buf, int idx)
- {
- /* doh, try to be too clever and it bites your butt */
- return 0;
- }
- struct user_entry_type USERENTRY_HOSTS =
- {
- 0,
- hosts_gotshare,
- hosts_dupuser,
- hosts_null,
- hosts_null,
- hosts_write_userfile,
- hosts_kill,
- def_get,
- hosts_set,
- hosts_tcl_get,
- hosts_tcl_set,
- hosts_expmem,
- hosts_display,
- "HOSTS"
- };
- int list_append(struct list_type **h, struct list_type *i)
- {
- for (; *h; h = &((*h)->next));
- *h = i;
- return 1;
- }
- int list_delete(struct list_type **h, struct list_type *i)
- {
- for (; *h; h = &((*h)->next))
- if (*h == i) {
- *h = i->next;
- return 1;
- }
- return 0;
- }
- int list_contains(struct list_type *h, struct list_type *i)
- {
- for (; h; h = h->next)
- if (h == i) {
- return 1;
- }
- return 0;
- }
- int add_entry_type(struct user_entry_type *type)
- {
- struct userrec *u;
- list_insert(&entry_type_list, type);
- for (u = userlist; u; u = u->next) {
- struct user_entry *e = find_user_entry(type, u);
- if (e && e->name) {
- e->type = type;
- e->type->unpack(u, e);
- nfree(e->name);
- e->name = NULL;
- }
- }
- return 1;
- }
- int del_entry_type(struct user_entry_type *type)
- {
- struct userrec *u;
- for (u = userlist; u; u = u->next) {
- struct user_entry *e = find_user_entry(type, u);
- if (e && !e->name) {
- e->type->pack(u, e);
- e->name = user_malloc(strlen(e->type->name) + 1);
- strcpy(e->name, e->type->name);
- e->type = NULL;
- }
- }
- return list_delete((struct list_type **) &entry_type_list,
- (struct list_type *) type);
- }
- struct user_entry_type *find_entry_type(char *name)
- {
- struct user_entry_type *p;
- for (p = entry_type_list; p; p = p->next) {
- if (!egg_strcasecmp(name, p->name))
- return p;
- }
- return NULL;
- }
- struct user_entry *find_user_entry(struct user_entry_type *et,
- struct userrec *u)
- {
- struct user_entry **e, *t;
- for (e = &(u->entries); *e; e = &((*e)->next)) {
- if (((*e)->type == et) ||
- ((*e)->name && !egg_strcasecmp((*e)->name, et->name))) {
- t = *e;
- *e = t->next;
- t->next = u->entries;
- u->entries = t;
- return t;
- }
- }
- return NULL;
- }
- void *get_user(struct user_entry_type *et, struct userrec *u)
- {
- struct user_entry *e;
- if (u && (e = find_user_entry(et, u)))
- return et->get(u, e);
- return 0;
- }
- int set_user(struct user_entry_type *et, struct userrec *u, void *d)
- {
- struct user_entry *e;
- int r;
- if (!u || !et)
- return 0;
- 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->set(u, e, d);
- if (!e->u.list) {
- list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
- nfree(e);
- }
- return r;
- }
|