#include "ubermud.h" #include "syssym.h" #include "externs.h" /* Copyright(C) 1990, Marcus J. Ranum, All Rights Reserved. This software may be freely used, modified, and redistributed, as long as this copyright message is left intact, and this software is not used to develop any commercial product, or used in any product that is provided on a pay-for-use basis. */ /* routines for managing local function symbol tables. */ /* #define FREEZEDEBUG #define THAWDEBUG #define SYMDEBUG */ /* free entries are stacked, not freed */ static Sym *freel = (Sym *)0; /* system symbol table */ static SysSym *systable[SYSSYMWIDTH]; static SysSym *syssymfree = (SysSym *)0; Sym * symnew(name,typ,op) char *name; int typ; Oper op; { Sym *ret; if(freel != (Sym *)0) { ret = freel; freel = freel->next; #ifdef SYMDEBUG printf("symnew return Sym holder %d\n",ret); #endif } else { if((ret = (Sym *)malloc(sizeof(Sym))) == 0) return(0); #ifdef SYMDEBUG printf("symnew malloc Sym holder %d\n",ret); #endif } ret->data = op; ret->typ = typ; ret->name = name; return(ret); } Sym * symadd(sym,table) Sym *sym; Sym *table; { sym->next = table; return(sym); } Sym * symlook(str,table) char *str; Sym *table; { Sym *ret; for(ret = table; ret != (Sym *)0; ret = ret->next) if(str != 0 && !strcmp(str,ret->name)) return(ret); return(0); } void symfreelist(l) Sym *l; { Sym *p; p = l; while(l != 0) { l = l->next; #ifdef SYMDEBUG printf("symfree stack Sym holder %d\n",p); #endif p->next = freel; freel = p; p = l; } } int cornedbeefhash(s,siz) char *s; int siz; { register unsigned int c = 0; register unsigned int g; while(*s) { c = (c << 1) + *s++; if(g = c & 0xF00000000) { c = c ^ (g >> 24); c = c ^ g; } } c = c % 211; return(c % siz); } syssyminit() { int x; for(x = 0; x < SYSSYMWIDTH; x++) systable[x] = (SysSym *)0; return(0); } /* chill a system variable. */ sys_freeze(ele,typ,data,uid,euid) char *ele; int typ; Oper data; long uid; long euid; { register SysSym *sp; int hv; #ifdef FREEZEDEBUG printf("freeze:elem %d.%s\n",ELENUM(ele),ELENAM(ele)); #endif if(*ELENAM(ele) == '_' && uid != (long)0 && euid != (long)0) return(ERR_PERM); sp = systable[(hv = cornedbeefhash(ELENAM(ele),SYSSYMWIDTH))]; while(sp != (SysSym *)0) { if(!strcmp(ELENAM(ele),sp->nam)) break; sp = sp->next; } /* if the variable is not defined, simply create it otherwise we need to clean up the old version and adjust it. */ if(sp == (SysSym *)0 && typ != TYP_NULL) { /* only uid#0 can create in system table */ if(uid != (long)0 && euid != (long)0) return(ERR_NOTOWN); if(syssymfree != (SysSym *)0) { sp = syssymfree; syssymfree = sp->next; sp->next = (SysSym *)0; } else { sp = (SysSym *)malloc(sizeof(SysSym)); if(sp == (SysSym *)0) return(ERR_OOM); } if((sp->nam = copystr(ELENAM(ele))) == 0) return(ERR_OOM); sp->next = systable[hv]; systable[hv] = sp; #ifdef FREEZEDEBUG printf("freeze:added elem to system sym table\n"); #endif sp->ino.mode = PERM_DEFAULT; sp->ino.owner = (long)0; } else { if(sp == (SysSym *)0 && typ == TYP_NULL) return(0); /* free any existing stuff. none of this may be allocated with tmpstr,etc. an implicit cast between char *, Prog *, and Objlist * is made here. SO SUE ME! */ if(!permitted(PERM_WRITE,sp->ino.owner,sp->ino.mode,uid,euid)) return(ERR_PERM); /* free data if there is any. - a deferred free() */ if(sp->ino.dsiz > 0) tmpputonfree(sp->ino.op.c); /* de-assign the sucker. */ if(typ == TYP_NULL) { SysSym *jp; free(sp->nam); jp = systable[hv]; if(jp == sp) { systable[hv] = sp->next; } else { while(jp != (SysSym *)0 && jp->next != sp) jp = jp->next; if(jp != (SysSym *)0) jp->next = sp->next; sp->next = syssymfree; syssymfree = sp; } return(0); } } if(opercopy(data,typ,&(sp->ino.op),&(sp->ino.typ),&(sp->ino.dsiz))) return(1); /* back-patch functions */ if(typ == TYP_FUNC) { sp->ino.op.p->p_uid = sp->ino.owner; sp->ino.op.p->p_mode = sp->ino.mode; } #ifdef FREEZEDEBUG printf("installed sys \"%s\", size=%d\n",sp->nam,sp->ino.dsiz); #endif return(0); } sys_thaw(ele,typ,data,uid,euid) char *ele; int *typ; Oper *data; long uid; long euid; { register SysSym *sp; #ifdef THAWDEBUG printf("thaw:elem %d.%s\n",ELENUM(ele),ELENAM(ele)); #endif sp = systable[cornedbeefhash(ELENAM(ele),SYSSYMWIDTH)]; while(sp != (SysSym *)0) { if(!strcmp(ELENAM(ele),sp->nam)) break; sp = sp->next; } if(sp == (SysSym *)0) return(ERR_NOTHERE); if(!permitted(PERM_READ,sp->ino.owner,sp->ino.mode,uid,euid)) return(ERR_PERM); *typ = sp->ino.typ; *data = sp->ino.op; return(0); } /* used by blt_chmod and blt_chown in store.c */ SysSym * sys_getsym(ele) char *ele; { register SysSym *sp; #ifdef THAWDEBUG printf("sys_getsym:elem %d.%s\n",ELENUM(ele),ELENAM(ele)); #endif sp = systable[cornedbeefhash(ELENAM(ele),SYSSYMWIDTH)]; while(sp != (SysSym *)0) { if(!strcmp(ELENAM(ele),sp->nam)) break; sp = sp->next; } return(sp); }