/* eval.c */ /* $Id: eval.c,v 1.16 1993/10/18 01:14:50 nils Exp $ */ /* Expression parsing module created by Lawrence Foard */ #include <sys/types.h> #include <time.h> #include <ctype.h> #include <math.h> #include "db.h" #include "interface.h" #include "config.h" #include "externs.h" #include "hash.h" #include "nalloc.h" #ifdef USE_SPACE /* Included by Michael Majere */ #include "space.h" #endif #ifdef DEBUGEVAL extern FILE *command_log; #endif /* functions for the string expressions */ extern NALLOC *glurp; dbref match_thing(player,name) dbref player; char *name; { init_match(player, name, NOTYPE); match_everything(); return(noisy_match_result()); } void fun_rand(buff,args) char *buff; char *args[10]; { int mod=atoi(args[0]); if (mod<1) mod=1; sprintf(buff,"%d",(rand() & 65535) % mod); } void fun_switch(buff,args, player, doer, nargs) char *buff; char *args[10]; dbref player; dbref doer; int nargs; { char thing[1024]; int i; char *ptrsrv[10]; if (nargs<2) { strcpy(buff,"WRONG NUMBER OF ARGS"); return; } for(i=0;i<10;i++) ptrsrv[i]=wptr[i]; strcpy(thing,args[0]); for (i=1; (i+1)<nargs; i+=2) { if (wild_match(args[i],thing)) { strcpy(buff, args[i+1]); for(i=0;i<10;i++) wptr[i]=ptrsrv[i]; return; } } if (i<nargs) strcpy (buff,args[i]); else *buff = '\0'; for(i=0;i<10;i++) wptr[i]=ptrsrv[i]; return; } void fun_attropts(buff, args, player, doer, nargs) char *buff; char *args[10]; dbref player; dbref doer; int nargs; { dbref thing; char buf[1024]; ATTR *attrib; if (nargs >2 || nargs < 1) { strcpy(buff,"WRONG NUMBER OF ARGS"); return; } if (nargs == 2) { char *k; static char *g[1]; k=tprintf("%s/%s",args[0],args[1]); args = g; g[0] = k; } if (!parse_attrib(player,args[0],&thing,&attrib,0)) { strcpy(buff,"NO MATCH"); return; } if (!can_see_atr(player, thing, attrib)) { strcpy(buff,"Permission denied."); return; } *buf = '\0'; buf[1] = '\0'; if (attrib->flags & AF_WIZARD) strcat(buf, " wizard"); if (attrib->flags & AF_UNIMP) strcat(buf, " unsaved"); if (attrib->flags & AF_OSEE) strcat(buf, " osee"); if (attrib->flags & AF_INHERIT) strcat(buf, " inherit"); if (attrib->flags & AF_DARK) strcat(buf, " dark"); if (attrib->flags & AF_DATE) strcat(buf, " date"); if (attrib->flags & AF_LOCK) strcat(buf, " lock"); if (attrib->flags & AF_FUNC) strcat(buf, " function"); strcpy (buff, buf+1); } void fun_foreach(buff,args,privs,doer) char *buff; char *args[10]; dbref privs; dbref doer; { char *k; char buff1[1024]; char *ptrsrv; int i=0,j=0; ptrsrv=wptr[0]; if(!args[0] || !strcmp(args[0],"")) { buff[0]=NULL; return; } while((k=parse_up(&args[0], ' ')) && i<1000) { wptr[0] = k; pronoun_substitute(buff1,doer,args[1],privs); for(j=strlen(db[doer].name)+1;buff1[j] && i<1000;i++,j++) buff[i]=buff1[j]; buff[i++]=' '; buff[i]='\0'; } if(i>0) buff[i-1]='\0'; wptr[0] = ptrsrv; } void fun_get(buff,args,player, doer, nargs) char *buff; char *args[10]; dbref player; dbref doer; int nargs; { dbref thing; ATTR *attrib; if (nargs >2 || nargs < 1) { strcpy(buff,"WRONG NUMBER OF ARGS"); return; } if (nargs == 2) { char *k; static char *g[1]; k=tprintf("%s/%s",args[0],args[1]); args = g; g[0] = k; } if (!parse_attrib(player,args[0],&thing,&attrib,0)) { strcpy(buff,"NO MATCH"); return; } if (can_see_atr (player, thing, attrib)) strcpy(buff,atr_get(thing,attrib)); else strcpy(buff,"Permission denied"); /* if (!controls(player,thing,POW_SEEATR) && !(attrib->flags&AF_OSEE)) { strcpy(buff,"Permission denied"); return; } if (attrib->flags&AF_DARK && !controls(player,attrib->obj,POW_SECURITY)) { strcpy(buff,"Permission denied"); return; } strcpy(buff,atr_get(thing,attrib)); */ } void fun_time(buff,args,privs,doer,nargs) char *buff; char *args[10]; dbref privs; dbref doer; int nargs; { time_t cl; /* use supplied x-value if one is given */ /* otherwise get the current x-value of time */ if ( nargs == 2 ) cl = atol(args[1]); else time(&cl); if ( nargs == 0 ) strcpy(buff, mktm(cl, "D", privs)); else strcpy(buff, mktm(cl, args[0], privs)); } void fun_xtime(buff,args,privs,doer,nargs) char *buff; char *args[]; dbref privs; dbref doer; int nargs; { time_t cl; if ( nargs == 0 ) time(&cl); else { cl = mkxtime(args[0], privs, (nargs > 1) ? args[1] : ""); if ( cl == -1L ) { strcpy(buff,"#-1"); return; } } sprintf(buff, "%ld", cl); } int mem_usage(thing) dbref thing; { int k; ALIST *m; ATRDEF *j; k = sizeof(struct object); k += strlen(db[thing].name)+1; for (m=db[thing].list; m; m=AL_NEXT(m)) if (AL_TYPE(m)) if (AL_TYPE(m) != A_DOOMSDAY) { k += sizeof(ALIST); if (AL_STR(m)) k += strlen(AL_STR(m)); } for (j=db[thing].atrdefs; j; j=j->next) { k += sizeof(ATRDEF); if (j->a.name) k += strlen(j->a.name); } return k; } void fun_objmem(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref thing; thing = match_thing (privs, args[0]); if (thing == NOTHING || !controls (privs, thing, POW_STATS)) { strcpy(buff,"#-1"); return; } sprintf(buff,"%d",mem_usage(thing)); } void fun_playmem (buff, args, privs) char *buff; char *args[10]; dbref privs; { int tot=0; dbref thing; dbref j; thing = match_thing (privs, args[0]); if (thing == NOTHING || !controls (privs, thing, POW_STATS) || !power (privs, POW_STATS)) { strcpy(buff,"#-1"); return; } for (j = 0; j<db_top; j++) if (db[j].owner == thing) tot += mem_usage (j); sprintf (buff,"%d",tot); } void fun_mid(buff,args) char *buff; char *args[10]; { int l=atoi(args[1]),len=atoi(args[2]); if ((l<0) || (len<0) || ((len+l)>1000)) { strcpy(buff,"OUT OF RANGE"); return; } if (l<strlen(args[0])) strcpy(buff,args[0]+l); else *buff=0; buff[len]=0; } void fun_add(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",atoi(args[0])+atoi(args[1])); } void fun_band(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",atoi(args[0]) & atoi(args[1])); } void fun_bor(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",atoi(args[0]) | atoi(args[1])); } void fun_bxor(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",atoi(args[0]) ^ atoi(args[1])); } void fun_bnot(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",~atoi(args[0])); } int istrue(str) char *str; { return (((strcmp(str,"#-1") == 0) || (strcmp(str,"") == 0) || ((atoi(str) == 0) && isdigit(str[0]))) ? 0 : 1); } void fun_land(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",istrue(args[0]) && istrue(args[1])); } void fun_lor(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",istrue(args[0]) || istrue(args[1])); } void fun_lxor(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",(istrue(args[0]) == 0 ? (istrue(args[1]) == 0 ? 0 : 1) : (istrue(args[1]) == 0 ? 1 : 0))); } void fun_lnot(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d", (istrue(args[0]) == 0 ? 1 : 0)); } void fun_truth(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d", (istrue(args[0]) ? 1 : 0)); } void fun_base(buff,args) char *buff; char *args[10]; { int i, digit, decimal, neg, oldbase, newbase; char tmpbuf[1000]; oldbase = atoi(args[1]); newbase = atoi(args[2]); if ((oldbase < 2) || (oldbase > 36) || (newbase < 2) || (newbase > 36)) { strcpy(buff, "BASES MUST BE BETWEEN 2 AND 36"); return; } neg = 0; if (args[0][0]=='-') { neg = 1; args[0][0] = '0'; } decimal = 0; for (i=0; args[0][i] != 0; i++) { decimal *= oldbase; if (('0' <= args[0][i]) && (args[0][i] <= '9')) digit = args[0][i] - '0'; else if (('a' <= args[0][i]) && (args[0][i] <= 'z')) digit = args[0][i] + 10 - 'a'; else if (('A' <= args[0][i]) && (args[0][i] <= 'Z')) digit = args[0][i] + 10 - 'A'; else { strcpy(buff, "ILLEGAL DIGIT"); return; } if (digit >= oldbase) { strcpy(buff, "DIGIT OUT OF RANGE"); return; } decimal += digit; } strcpy(buff,""); strcpy(tmpbuf,""); i = 0; while (decimal > 0) { strcpy(tmpbuf,buff); digit = (decimal % newbase); if (digit < 10) sprintf(buff,"%d%s", digit, tmpbuf); else sprintf(buff,"%c%s", digit+'a'-10, tmpbuf); decimal /= newbase; i++; } if (neg) { strcpy(tmpbuf,buff); sprintf(buff,"-%s",tmpbuf); } } void fun_sgn(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",atoi(args[0]) > 0 ? 1 : atoi(args[0]) < 0 ? -1 : 0); } void fun_sqrt(buff, args) char *buff; char *args[10]; { extern double sqrt P((double)); int k; k= atoi(args[0]); if (k<0) k= (-k); sprintf(buff,"%d",(int)sqrt((double)k)); } void fun_abs(buff,args) char *buff; char *args[10]; { extern int abs P((int)); sprintf(buff,"%d",abs(atoi(args[0]))); } void fun_mul(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",atoi(args[0])*atoi(args[1])); } void fun_div(buff,args) char *buff; char *args[10]; { int bot=atoi(args[1]); if (bot==0) bot=1; sprintf(buff,"%d",atoi(args[0])/bot); } void fun_mod(buff,args) char *buff; char *args[10]; { int bot=atoi(args[1]); if (bot==0) bot=1; sprintf(buff,"%d",atoi(args[0]) % bot); } /* read first word from a string */ void fun_first(buff,args) char *buff; char *args[10]; { char *s=args[0]; char *b; /* get rid of leading space */ while(*s && (*s==' ')) s++; b=s; while(*s && (*s!=' ')) s++; *s++=0; strcpy(buff,b); } void fun_rest(buff,args) char *buff; char *args[10]; { char *s=args[0]; /* skip leading space */ while(*s && (*s==' ')) s++; /* skip firsts word */ while(*s && (*s!=' ')) s++; /* skip leading space */ while(*s && (*s==' ')) s++; strcpy(buff,s); } void fun_flags(buff,args,privs,owner) char *buff; char *args[10]; dbref privs; dbref owner; { dbref thing; int oldflags; /* really kludgy. */ init_match(privs, args[0], NOTYPE); match_me(); match_here(); match_neighbor(); match_absolute(); match_possession(); match_player(); thing = match_result(); if ( thing == NOTHING || thing == AMBIGUOUS ) { *buff = '\0'; return; } /* if ( ! controls(owner, thing, POW_FUNCTIONS) ) { *buff = '\0'; return; } */ oldflags = db[thing].flags; /* grr, this is kludgy. */ if (!controls(privs,thing,POW_WHO) && !could_doit(privs, thing, A_LHIDE)) db[thing].flags &= ~(PLAYER_CONNECT); strcpy(buff, unparse_flags(thing)); db[thing].flags = oldflags; } void fun_mtime(buff, args, player) char *buff; char *args[10]; dbref player; { dbref thing; thing = match_thing(player,args[0]); if (thing == NOTHING) strcpy(buff,"#-1"); else sprintf(buff,"%d",db[thing].mod_time); } void fun_ctime(buff, args, player) char *buff; char *args[10]; dbref player; { dbref thing; thing = match_thing(player,args[0]); if (thing == NOTHING) strcpy(buff,"#-1"); else sprintf(buff,"%d",db[thing].create_time); } void fun_credits(buff,args,player) char *buff; char *args[10]; dbref player; { dbref who; init_match(player, args[0], TYPE_PLAYER); match_me(); match_player(); match_neighbor(); match_absolute(); if ( (who = match_result()) == NOTHING ) { strcpy(buff,"#-1"); return; } if (!power(player,POW_FUNCTIONS)&&!controls(player, who, POW_FUNCTIONS) ) { strcpy(buff,"#-1"); return; } sprintf(buff,"%d",Pennies(who)); } void fun_quota_left(buff,args,player) char *buff; char *args[10]; dbref player; { dbref who; init_match(player, args[0], TYPE_PLAYER); match_me(); match_player(); match_neighbor(); match_absolute(); if ( (who = match_result()) == NOTHING ) { strcpy(buff,"#-1"); return; } if ( ! controls(player, who,POW_FUNCTIONS) ) { strcpy(buff,"#-1"); return; } sprintf(buff,"%d", atoi(atr_get(who, A_RQUOTA))); } void fun_quota(buff,args,player) char *buff; char *args[10]; dbref player; { dbref who; init_match(player, args[0], TYPE_PLAYER); match_me(); match_player(); match_neighbor(); match_absolute(); if ( (who = match_result()) == NOTHING ) { strcpy(buff,"#-1"); return; } if ( ! controls(player, who,POW_FUNCTIONS) ) { strcpy(buff,"#-1"); return; } /* count up all owned objects */ /* owned = -1; * a player is never included in his own quota */ /* for ( thing = 0; thing < db_top; thing++ ) { if ( db[thing].owner == who ) if ((db[thing].flags & (TYPE_THING|GOING)) != (TYPE_THING|GOING)) ++owned; }*/ strcpy(buff,atr_get(who,A_QUOTA)); /* sprintf(buff,"%d", (owned + atoi(atr_get(who, A_RQUOTA))));*/ } void fun_stat(buff,args,player) char *buff; char *args[10]; dbref player; { int owned; dbref who, thing; init_match(player, args[0], TYPE_PLAYER); match_me(); match_player(); match_neighbor(); match_absolute(); if ( (who = match_result()) == NOTHING ) { strcpy(buff,"#-1"); return; } if ( ! controls(player, who,POW_FUNCTIONS) ) { strcpy(buff,"#-1"); return; } /* count up all owned objects */ owned = -1; /* a player is never included in his own quota */ for ( thing = 0; thing < db_top; thing++ ) { if ( db[thing].owner == who ) if ((db[thing].flags & (TYPE_THING|GOING)) != (TYPE_THING|GOING)) ++owned; } sprintf(buff,"%d", owned); } void fun_strlen(buff,args) char *buff; char *args[10]; { sprintf(buff,"%d",strlen(args[0])); } void fun_comp(buff, args) char *buff; char *args[10]; { int x; x = (atoi(args[0]) - atoi(args[1])); if ( x > 0 ) strcpy(buff, "1"); else if ( x < 0 ) strcpy(buff, "-1"); else strcpy(buff, "0"); } void fun_scomp(buff, args) char *buff; char *args[10]; { int x; x = strcmp(args[0], args[1]); if ( x > 0 ) strcpy(buff, "1"); else if ( x < 0 ) strcpy(buff, "-1"); else strcpy(buff, "0"); } /* handle 0-9,va-vz,n,# */ void fun_v(buff,args,privs,doer) char *buff; char *args[10]; dbref privs; dbref doer; { int c; if (args[0][0] && args[0][1]) { /* not a null or 1-character string. */ ATTR *attrib; if (!(attrib=atr_str(privs,privs,args[0]))) { *buff = '\0'; return; } strcpy(buff,atr_get(privs,attrib)); return; } switch(c=args[0][0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!wptr[c-'0']) { *buff=0; return; } strcpy(buff,wptr[c-'0']); break; case 'v': case 'V': { int a; a=to_upper(args[0][1]); if ((a<'A') || (a>'Z')) { *buff=0; return; } strcpy(buff,atr_get(privs,A_V[a-'A'])); } break; case 'n': case 'N': strcpy(buff,db[doer].name); break; case '#': sprintf(buff,"#%d",doer); break; /* info about location and stuff */ /* objects # */ case '!': sprintf(buff,"#%d",privs); break; default: *buff = '\0'; break; } } void fun_s(buff,args,privs,doer) char *buff; char *args[10]; dbref privs; dbref doer; { char buff1[1024]; pronoun_substitute(buff1,doer,args[0],privs); strcpy(buff,buff1+strlen(db[doer].name)+1); } void fun_s_with(buff,args,privs,doer,nargs) char *buff; char *args[10]; dbref privs; dbref doer; int nargs; { char buff1[1024]; char *tmp[10]; int a; if (nargs < 1) { strcpy(buff,"#-1"); return; } for (a=0; a<10; a++) tmp[a] = wptr[a]; wptr[9] = 0; for (a=1; a<10; a++) wptr[a-1] = args[a]; for (a=nargs; a<10; a++) wptr[a-1] = 0; pronoun_substitute(buff1,doer,args[0],privs); strcpy(buff,buff1+strlen(db[doer].name)+1); for (a=0; a<10; a++) wptr[a] = tmp[a]; } void fun_s_as(buff, args, privs, doer) char *buff; char *args[10]; dbref privs; dbref doer; { char buff1[1024]; dbref newprivs; dbref newdoer; newdoer = match_thing(privs, args[1]); newprivs = match_thing(privs, args[2]); if (!controls(privs, newdoer, POW_MODIFY)) { strcpy(buff,"Permission denid."); return; } pronoun_substitute(buff1,newdoer, args[0], newprivs); strcpy(buff,buff1+strlen(db[newdoer].name)+1); } void fun_s_as_with(buff,args,privs,doer,nargs) char *buff; char *args[10]; dbref privs; dbref doer; int nargs; { char buff1[1024]; char *tmp[10]; int a; dbref newprivs; dbref newdoer; if (nargs < 3) { strcpy(buff,"#-1"); return; } newdoer = match_thing(privs, args[1]); newprivs = match_thing(privs, args[2]); if (!controls(privs, newdoer, POW_MODIFY)) { strcpy(buff,"Permission denid."); return; } for (a=0; a<10; a++) tmp[a] = wptr[a]; wptr[9] = wptr[8] = wptr[7] = 0; for (a=3; a<10; a++) wptr[a-3] = args[a]; for (a=nargs; a<10; a++) wptr[a-3] = 0; pronoun_substitute(buff1,newdoer, args[0], newprivs); strcpy(buff,buff1+strlen(db[newdoer].name)+1); for (a=0; a<10; a++) wptr[a] = tmp[a]; } void fun_num(buff,args,privs) char *buff; char *args[]; dbref privs; { sprintf(buff,"#%d",match_thing(privs,args[0])); } void fun_con(buff,args,privs,doer) char *buff; char *args[]; dbref privs; dbref doer; { dbref it=match_thing(privs,args[0]); if ((it!=NOTHING) && (controls(privs,it,POW_FUNCTIONS) || (db[privs].location==it) || (it==doer))) { sprintf(buff,"#%d",db[it].contents); return; } strcpy(buff,"#-1"); return; } /* return next exit that is ok to see */ dbref next_exit(player,this) dbref player; dbref this; { while( (this!=NOTHING) && (db[this].flags & DARK) && !controls(player,this,POW_FUNCTIONS) ) this=db[this].next; return(this); } void fun_exit(buff,args,privs,doer) char *buff; char *args[]; dbref privs; dbref doer; { dbref it=match_thing(privs,args[0]); if ((it!=NOTHING) && (controls(privs,it,POW_FUNCTIONS) || (db[privs].location==it) || (it==doer))) { sprintf(buff,"#%d",next_exit(privs, db[it].exits)); return; } strcpy(buff,"#-1"); return; } void fun_next(buff,args,privs,doer) char *buff; char *args[]; dbref privs; dbref doer; { dbref it=match_thing(privs,args[0]); if (it!=NOTHING) { if (Typeof(it)!=TYPE_EXIT) { if ( controls(privs,db[it].location,POW_FUNCTIONS) || (db[it].location==doer) || (db[it].location==db[privs].location) ) { sprintf(buff,"#%d",db[it].next); return; } } else { sprintf(buff,"#%d",next_exit(privs,db[it].next)); return; } } strcpy(buff,"#-1"); return; } void fun_loc(buff,args,privs,doer) char *buff; char *args[]; dbref privs; dbref doer; { dbref it=match_thing(privs,args[0]); if ((it!=NOTHING) && (controls(privs,it,POW_FUNCTIONS) || controls(privs,db[it].location,POW_FUNCTIONS) || controls_a_zone(privs,it,POW_FUNCTIONS) || power(privs,POW_FUNCTIONS) || (it==doer) || (Typeof(it) == TYPE_PLAYER && !(db[it].flags&DARK)))) { sprintf(buff,"#%d",db[it].location); return; } strcpy(buff,"#-1"); return; } void fun_link(buff,args,privs,doer) char *buff; char *args[]; dbref privs; dbref doer; { dbref it=match_thing(privs,args[0]); if((it!=NOTHING) && (controls(privs,it,POW_FUNCTIONS) || controls(privs,db[it].location,POW_FUNCTIONS) || (it==doer))) { sprintf(buff,"#%d",db[it].link); return; } strcpy(buff,"#-1"); return; } void fun_linkup (buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref it=match_thing(privs, args[0]); dbref i; int len=0; if(!(controls(privs, it, POW_FUNCTIONS) || controls(privs, db[it].location,POW_FUNCTIONS) || (it==privs))) { strcpy(buff,"#-1"); return; } *buff = '\0'; for (i=0; i<db_top; i++) if (db[i].link == it) if(len) { static char smbuf[30]; sprintf(smbuf, " #%d", i); if((strlen(smbuf)+len)>990) { strcat(buff," #-1"); return; } strcat (buff, smbuf); len += strlen(smbuf); } else { sprintf(buff, "#%d", i); len = strlen(buff); } } void fun_class(buff,args,privs) char *buff; char *args[]; dbref privs; { dbref it=match_thing(privs,args[0]); if(it==NOTHING || !power(privs,POW_WHO)) *buff = '\0'; else strcpy(buff,get_class(it)); } void fun_is_a(buff,args,privs) char *buff; char *args[]; dbref privs; { dbref thing, parent; thing = match_thing(privs,args[0]); parent = match_thing(privs,args[1]); if (thing == NOTHING || parent == NOTHING) strcpy(buff,"#-1"); else strcpy(buff,is_a(thing,parent)?"1":"0"); } void fun_has(buff,args,privs) char *buff; char *args[]; dbref privs; { dbref user, obj; dbref i; user = match_thing(privs,args[0]); obj = match_thing(privs,args[1]); if (obj == NOTHING || user == NOTHING) strcpy(buff,"#-1"); else { strcpy(buff,"0"); for (i=db[user].contents; i!=NOTHING; i=db[i].next) if (i==obj) strcpy(buff,"1"); } } void fun_has_a(buff,args,privs) char *buff; char *args[]; dbref privs; { dbref user, parent; dbref i; user = match_thing(privs,args[0]); parent = match_thing(privs,args[1]); if (parent == NOTHING || user == NOTHING) strcpy(buff,"#-1"); else { strcpy(buff,"0"); for (i=db[user].contents; i!=NOTHING; i=db[i].next) if (is_a(i,parent)) strcpy(buff,"1"); } } void fun_owner(buff,args,privs) char *buff; char *args[]; dbref privs; { dbref it=match_thing(privs,args[0]); if (it!=NOTHING) it=db[it].owner; sprintf(buff,"#%d",it); } void fun_name(buff,args,privs) char *buff; char *args[]; dbref privs; { dbref it=match_thing(privs,args[0]); if (it==NOTHING) strcpy(buff,""); else if (Typeof(it)==TYPE_EXIT) strcpy(buff,main_exit_name(it)); else strcpy(buff,db[it].name); } void fun_pos(buff,args) char *buff; char *args[10]; { int i = 1; char *t, *u, *s = args[1]; while ( *s ) { u = s; t = args[0]; while ( *t && *t == *u ) ++t, ++u; if ( *t == '\0' ) { sprintf(buff, "%d", i); return; } ++i, ++s; } strcpy(buff, "0"); return; } void fun_delete(buff,args) char *buff; char *args[10]; { char *s = buff, *t = args[0]; int i, l = atoi(args[1]), len = atoi(args[2]); int a0len = strlen(args[0]); if ( (l < 0) || (len < 0) || (len+l >= 1000) ) { strcpy(buff,"OUT OF RANGE"); return; } for(i = 0; i < l && *s; i++) *s++ = *t++; if (len+l >= a0len) { *s = '\0'; return; } t += len; while((*s++ = *t++)); return; } void fun_remove(buff,args) char *buff; char *args[10]; { char *s = buff, *t = args[0]; int w = atoi(args[1]), num = atoi(args[2]), i; if (w < 1) { strcpy(buff,"OUT OF RANGE"); return; } for(i = 1; i < w; i++) { while(*t && *t != ' ') *s++ = *t++; while(*t && *t == ' ') *s++ = *t++; } if (!*t) return; for(i = 0; i < num; i++) { while(*t && *t != ' ') t++; while(*t && *t == ' ') t++; } if (!*t) { if (s != buff) s--; *s = '\0'; return; } while ((*s++ = *t++)); return; } void fun_match(buff,args) char *buff; char *args[10]; { int a; int wcount=1; char *s=args[0]; char *ptrsrv[10]; for( a = 0; a < 10; a++) ptrsrv[a] = wptr[a]; do { char *r; /* trim off leading space */ while ( *s && (*s == ' ') ) s++; r=s; /* scan to next space and truncate if necessary */ while ( *s && (*s != ' ') ) s++; if ( *s ) *s++ = 0; if ( wild_match(args[1],r) ) { sprintf(buff, "%d", wcount); for( a=0; a<10; a++ ) wptr[a] = ptrsrv[a]; return; } wcount++; } while(*s) ; strcpy(buff,"0"); for(a=0;a<10;a++) wptr[a]=ptrsrv[a]; } void fun_extract(buff,args) char *buff; char *args[10]; { int start=atoi(args[1]),len=atoi(args[2]); char *s=args[0],*r; if ((start<1) || (len<1)) { *buff=0; return; } start--; while(start && *s) { while(*s && (*s==' ')) s++; while(*s && (*s!=' ')) s++; start--; } while(*s && (*s==' ')) s++; r=s; while(len && *s) { while(*s && (*s==' ')) s++; while(*s && (*s!=' ')) s++; len--; } *s=0; strcpy(buff,r); } void fun_parents(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref it; int i; it = match_thing(privs, args[0]); if (it == NOTHING) { strcpy(buff, "#-1"); return; } *buff = '\0'; for (i=0; db[it].parents && db[it].parents[i]!=NOTHING; i++) if (controls (privs, it, POW_EXAMINE) || controls(privs, it, POW_FUNCTIONS) || controls (privs, db[it].parents[i], POW_EXAMINE) || controls(privs, db[it].parents[i], POW_FUNCTIONS)) if (*buff) sprintf(buff+strlen(buff)," #%d",db[it].parents[i]); else sprintf(buff,"#%d",db[it].parents[i]); } void fun_children(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref it; int i; it = match_thing(privs, args[0]); if (it == NOTHING) { strcpy(buff, "#-1"); return; } *buff = '\0'; for (i=0; db[it].children && db[it].children[i]!=NOTHING; i++) if (controls (privs, it, POW_EXAMINE) || controls(privs, it, POW_FUNCTIONS) || controls (privs, db[it].children[i], POW_EXAMINE) || controls(privs, db[it].children[i], POW_FUNCTIONS)) if (*buff) { sprintf(buff+strlen(buff)," #%d",db[it].children[i]); buff[990] = '\0'; } else sprintf(buff,"#%d",db[it].children[i]); } void fun_zone(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref thing; thing=match_thing (privs, args[0]); if (thing == NOTHING) { strcpy(buff, "#-1"); return; } sprintf(buff, "#%d", db[thing].zone); } void fun_getzone(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref thing; thing=match_thing (privs, args[0]); if (thing == NOTHING) { strcpy(buff, "#-1"); return; } sprintf(buff, "#%d", get_zone_first(thing)); } void fun_wmatch(buff, args) char *buff; char *args[10]; { char *string = args[0], *word = args[1], *s, *t; int count = 0, done = 0; for (s = string; *s && !done; s++) { count++; while (isspace(*s) && *s) s++; t = s; while (!isspace(*t) && *t) t++; done = (!*t) ? 1 : 0; *t = '\0'; if (!string_compare(s, word)) { sprintf(buff, "%d", count); return; } s = t; } sprintf(buff, "0"); return; } void fun_inzone (buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref it=match_thing(privs, args[0]); dbref i; int len=0; if(!controls(privs, it, POW_EXAMINE)) { strcpy(buff,"#-1"); return; } *buff = '\0'; for (i=0; i<db_top; i++) if (Typeof(i)==TYPE_ROOM) if (is_in_zone (i, it)) if(len) { static char smbuf[30]; /* eek, i hope it's not gunna be this long */ sprintf(smbuf, " #%d", i); if((strlen(smbuf)+len)>990) { strcat(buff," #-1"); return; } strcat (buff, smbuf); len += strlen(smbuf); } else { sprintf(buff, "#%d", i); len = strlen(buff); } } void fun_zwho (buff, args, who) char *buff; char *args[10]; dbref who; { dbref it=match_thing(who, args[0]); dbref i; int len=0; if(!controls(who, it, POW_FUNCTIONS)) { strcpy(buff,"#-1"); return; } *buff = '\0'; for (i=0; i<db_top; i++) if (Typeof(i)==TYPE_PLAYER) if (is_in_zone(i, it)) if(len) { static char smbuf[30]; /* eek, i hope it's not gunna be this long */ sprintf(smbuf, " #%d", i); if((strlen(smbuf)+len)>990) { strcat(buff," #-1"); return; } strcat (buff, smbuf); len += strlen(smbuf); } else { sprintf(buff, "#%d", i); len = strlen(buff); } } void fun_objlist(buff, args, privs, doer) char *buff; char *args[10]; dbref privs; dbref doer; { dbref it=match_thing(privs,args[0]); *buff = '\0'; if (it == NOTHING) return; if (Typeof(it)!=TYPE_EXIT) if (!(controls(privs, db[it].location, POW_FUNCTIONS) || (db[it].location == doer) || (db[it].location == db[privs].location) || (db[it].location == privs))) return; while (it != NOTHING) { if (*buff) strcpy(buff, tprintf("%s #%d",buff, it)); else sprintf(buff,"#%d", it); it = (Typeof(it)==TYPE_EXIT)?next_exit(privs, db[it].next):db[it].next; } } void fun_lzone(buff, args, privs, doer) char *buff; char *args[10]; dbref privs; dbref doer; { dbref it=match_thing(privs,args[0]); int depth=10; *buff = '\0'; if (it == NOTHING) return; it = get_zone_first(it); while (it != NOTHING) { if (*buff) strcpy(buff, tprintf("%s #%d", buff, it)); else sprintf(buff,"#%d", it); it = get_zone_next(it); depth--; if (depth <= 0) return; } } void fun_strcat(buff, args) char *buff; char *args[10]; { strcpy(buff,tprintf("%s%s", args[0], args[1])); } void fun_controls(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref player, object; ptype power; player = match_thing(privs, args[0]); object = match_thing(privs, args[1]); power = name_to_pow(args[2]); if (player == NOTHING || object == NOTHING || !power) { strcpy(buff,"#-1"); return; } sprintf(buff, "%d", controls(player, object, power)); } void fun_entrances(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref it=match_thing(privs,args[0]); dbref i; int control_here; *buff = '\0'; if (it == NOTHING) strcpy(buff, "#-1"); else { control_here = controls(privs, it, POW_EXAMINE); for (i=0; i<db_top; i++) if (Typeof(i)==TYPE_EXIT && db[i].link == it) if (controls(privs, i, POW_FUNCTIONS) || controls(privs,i, POW_EXAMINE) || control_here) if (*buff) strcpy(buff, tprintf("%s #%d", buff, i)); else sprintf(buff,"#%d", i); } } void fun_fadd (buff, args) char *buff; char *args[10]; { sprintf (buff, "%f", atof(args[0])+atof(args[1])); } void fun_fsub (buff, args) char *buff; char *args[10]; { sprintf (buff, "%f", atof(args[0])-atof(args[1])); } void fun_sub (buff, args) char *buff; char *args[10]; { sprintf (buff, "%d", atoi(args[0])-atoi(args[1])); } void fun_fmul (buff, args) char *buff; char *args[10]; { sprintf (buff, "%f", atof(args[0])*atof(args[1])); } void fun_fdiv (buff, args) char *buff; char *args[10]; { sprintf (buff, "%f", atof(args[0])/atof(args[1])); } void fun_fsgn (buff, args) char *buff; char *args[10]; { if (atof(args[0])<0) sprintf(buff,"-1"); else if(atof(args[0])>0) sprintf(buff,"1"); else strcpy(buff,"0"); } void fun_fsqrt (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",sqrt(atof(args[0]))); } void fun_fabs (buff, args) char *buff; char *args[10]; { if (atof(args[0])<0) sprintf(buff,"%f",-atof(args[0])); else strcpy(buff,args[0]); } void fun_fcomp (buff, args) char *buff; char *args[10]; { char buf[90]; char *k=buf; sprintf(buf,"%f",atof(args[0])-atof(args[1])); fun_fsgn(buff,&k); } void fun_exp (buff, args) char *buff; char *args[10]; { sprintf (buff,"%f", exp(atof(args[0]))); } void fun_pow (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",pow(atof(args[0]),atof(args[1]))); } void fun_log (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",log10(atof(args[0]))); } void fun_ln (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",log(atof(args[0]))); } void fun_arctan (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",atan(atof(args[0]))); } void fun_arccos (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",acos(atof(args[0]))); } void fun_arcsin (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",asin(atof(args[0]))); } void fun_tan (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",tan(atof(args[0]))); } void fun_cos (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",cos(atof(args[0]))); } void fun_sin (buff, args) char *buff; char *args[10]; { sprintf(buff,"%f",sin(atof(args[0]))); } void fun_if(buff, args) char *buff; char *args[10]; { if (istrue(args[0])) sprintf(buff,"%s",args[1]); else *buff = '\0'; return; } void fun_ifelse(buff, args) char *buff; char *args[10]; { if (istrue(args[0])) sprintf(buff,"%s",args[1]); else sprintf(buff,"%s",args[2]); return; } void fun_rmatch (buff, args, privs, doer) char *buff; char *args[10]; dbref privs; dbref doer; { dbref who; who = match_thing (privs, args[0]); if (!controls (privs, who, POW_EXAMINE) && who != doer) { strcpy (buff,"#-1"); notify (privs, "Permission denied."); return; } init_match (who, args[1], NOTYPE); match_everything(); sprintf (buff,"#%d", match_result()); } void fun_wcount(buff, args) char *buff; char *args[10]; { char *p = args[0]; int num = 0; while (*p) { while (*p && isspace(*p)) p++; if (*p) num++; while (*p && !isspace(*p)) p++; } sprintf(buff,"%d",num); return; } /* MERLMOD */ void fun_lwho (buff, privs, owner) char *buff; dbref privs; dbref owner; { char buf[1024]; struct descriptor_data *d; if( Typeof(owner) != TYPE_PLAYER && ! payfor(owner, 50) ) { notify(owner, "You don't have enough pennies."); return; } *buf = '\0'; for (d = descriptor_list; d; d = d->next) { if (d->state==CONNECTED && d->player>0) { if ((controls(owner, d->player, POW_WHO)) || could_doit(owner, d->player, A_LHIDE)) { if(*buf) strcpy(buf, tprintf("%s #%d",buf, d->player)); else sprintf(buf, "#%d", d->player); } }} strcpy(buff,buf); } void fun_spc(buff, args, dumm1, dumm2) char *buff; char *args[10]; dbref dumm1, dumm2; { char tbuf1[1024]; int i; int s = atoi(args[0]); if (s <= 0 ) { strcpy(buff, ""); return; } if (s > 950) s = 950; for (i = 0; i < s; i++) tbuf1[i] = ' '; tbuf1[i] = '\0'; strcpy(buff, tbuf1); } void do_flip(s, r) char *s; char *r; /* utility function to reverse a string */ { char *p; p = strlen(s) + r; for (*p-- = '\0'; *s; p--, s++) *p = *s; } void fun_flip(buff, args, dumm1, dumm2) char *buff; char *args[10]; dbref dumm1, dumm2; { do_flip(args[0], buff); } void fun_lnum(buff, args, dumm1, dumm2) char *buff; char *args[10]; dbref dumm1, dumm2; { int x, i; x = atoi(args[0]); if ((x > 250) || (x < 0)) { strcpy(buff, "#-1 Number Out Of Range"); return; } else { strcpy(buff,"0"); for (i = 1; i < x; i++) sprintf(buff, "%s %d", buff, i); } } void fun_string (buf, args, privs) char *buf; char *args[10]; dbref privs; { int num, i; char *letter; *buf = '\0'; num=atoi(args[1]); letter=args[0]; if (((num*strlen(letter)) <= 0) || ((num*strlen(letter)) > 950)) { strcpy(buf, "#-1 Out Of Range"); return; } *buf = '\0'; for (i = 0; i < num; i++) strcat(buf,letter); } void fun_ljust (buff, args, privs) char *buff; char *args[10]; dbref privs; { int number=atoi(args[1]); char *text; int leader; char tbuf1[1000]; char buf[1000]; int i; if (number <= 0 || number > 950) { sprintf(buff, "#-1 Number out of range."); return; } text=args[0]; leader=number-strlen(text); if (leader <= 0) { strcpy(buff, text); buff[number]=0; return; } if (leader > 950) leader = 950; for (i = 0; i < leader; i++) tbuf1[i] = ' '; tbuf1[i] = '\0'; sprintf(buf,"%s%s",text,tbuf1); strcpy(buff,buf); } void fun_rjust (buff, args, privs) char *buff; char *args[10]; dbref privs; { int number=atoi(args[1]); char *text; int leader; char tbuf1[1000]; char buf[1000]; int i; if (number <= 0 || number > 950) { sprintf(buff, "#-1 Number out of range."); return; } text=args[0]; leader=number-strlen(text); if (leader <= 0) { strcpy(buff, text); buff[number]=0; return; } if (leader > 950) leader = 950 - 1; for (i = 0; i < leader; i++) tbuf1[i] = ' '; tbuf1[i] = '\0'; sprintf(buf,"%s%s",tbuf1,text); strcpy(buff,buf); } void fun_lattrdef(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref it=match_thing(privs, args[0]); int len=0; ATRDEF *k; *buff = '\0'; if ((db[it].atrdefs) && (controls(privs,it,POW_EXAMINE) || (db[it].flags & SEE_OK))) { for (k=db[it].atrdefs; k; k=k->next) { if(len) { static char smbuf[100]; sprintf(smbuf, " %s", k->a.name); if((strlen(smbuf)+len)>990) { strcat(buff, " #-1"); return; } strcat(buff, smbuf); len += strlen(smbuf); } else { sprintf(buff, "%s", k->a.name); len=strlen(buff); } } } } void fun_lattr(buff, args, privs) char *buff; char *args[10]; dbref privs; { dbref it=match_thing(privs, args[0]); int len=0; ALIST *a; char temp[1024]; *buff = '\0'; if (db[it].list) { for (a=db[it].list; a; a=AL_NEXT(a)) { if (AL_TYPE(a) && can_see_atr(privs, it, AL_TYPE(a))) { sprintf(temp, (*buff)?" %s":"%s", unparse_attr(AL_TYPE(a),0)); if ((len+strlen(temp))>960) { strcat(buff," #-1"); return; } strcpy(buff+len,temp); len += strlen(temp); } } } } void fun_type(buff, args, privs, dumm1) char *buff; char *args[10]; dbref privs; dbref dumm1; { extern char *type_to_name(); dbref it = match_thing(privs, args[0]); if (it == NOTHING) { strcpy(buff, "#-1"); return; } strcpy(buff, type_to_name(Typeof(it))); } void fun_idle (buff, args, owner) char *buff; char *args[10]; dbref owner; { char buf[1024]; struct descriptor_data *d; dbref who=0; time_t now; time(&now); if (!string_compare(args[0], "me")) who=owner; else who=lookup_player(args[0]); if ( !who ) { sprintf(buff, "#-1"); return; } sprintf(buf,"#-1"); for (d = descriptor_list; d; d = d->next) { if (d->state==CONNECTED && d->player>0) { if ((controls(owner, d->player, POW_WHO)) || could_doit(owner, d->player, A_LHIDE)) { if ( d->player == who ) { sprintf(buf,"%d",(now - d->last_time)); break; } } }} if ( buf == NULL) sprintf(buf,"#-1"); strcpy(buff,buf); } void fun_onfor (buff, args, owner) char *buff; char *args[10]; dbref owner; { char buf[1024]; struct descriptor_data *d; dbref who=0; time_t now; time(&now); if ( !(string_compare(args[0], "me"))) who=owner; else who=lookup_player(args[0]); if (!who) { sprintf(buff, "#-1"); return; } sprintf(buf,"#-1"); for (d = descriptor_list; d; d = d->next) { if (d->state==CONNECTED && d->player>0) { if ((controls(owner, d->player, POW_WHO)) || could_doit(owner, d->player, A_LHIDE)) { if ( d->player == who ) { sprintf(buf,"%d",(now - d->connected_at)); break; } } }} if ( buf == NULL) sprintf(buf,"#-1"); strcpy(buff,buf); } void fun_host(buff, args, owner) char *buff; char *args[10]; dbref owner; { char buf[1024]; struct descriptor_data *d; dbref who=0; time_t now; time(&now); if ( !(string_compare(args[0], "me"))) who=owner; else who=lookup_player(args[0]); if ( (!who) || !(controls(owner, who, POW_HOST))) { strcpy(buff,"#-1"); return; } sprintf(buf,"#-1"); for (d = descriptor_list; d; d = d->next) { if (d->state==CONNECTED && d->player>0) { if ((controls(owner, d->player, POW_WHO)) || could_doit(owner, d->player, A_LHIDE)) { if ( d->player == who ) { sprintf(buf,"%s", d->addr); break; } } }} if ( buf == NULL) sprintf(buf,"#-1"); strcpy(buff,buf); } void fun_tms(buff,args) char *buff; char *args[10]; { int num=atoi(args[0]); if (num <0 ) { sprintf(buff,"#-1"); } else { sprintf(buff,"%s",time_format_2(num)); } } void fun_tml(buff,args) char *buff; char *args[10]; { int num=atoi(args[0]); if (num <0 ) { sprintf(buff,"#-1"); } else { sprintf(buff,"%s",time_format_1(num)); } } typedef struct fun FUN; struct fun { char *name; void (*fun)(); int nargs; }; FUN flist[]={ {"IS_A", fun_is_a, 2}, {"RAND", fun_rand, 1}, {"TIME", fun_time, -1}, {"XTIME", fun_xtime, -1}, {"CLASS", fun_class, 1}, {"FOREACH",fun_foreach,2}, {"GET", fun_get, -1}, {"HAS_A", fun_has_a, 2}, {"HAS", fun_has, 2}, {"ATTROPTS",fun_attropts, -1}, {"SWITCH", fun_switch,-1}, {"PLAYMEM",fun_playmem,1}, {"OBJMEM", fun_objmem, 1}, {"MID", fun_mid, 3}, {"DELETE", fun_delete, 3}, {"ADD", fun_add, 2}, {"MUL", fun_mul, 2}, {"DIV", fun_div, 2}, {"MOD", fun_mod, 2}, {"SUB", fun_sub, 2}, {"RMATCH", fun_rmatch, 2}, {"FADD", fun_fadd, 2}, {"FMUL", fun_fmul, 2}, {"FDIV", fun_fdiv, 2}, {"FSUB", fun_fsub, 2}, {"BAND", fun_band, 2}, {"BOR", fun_bor, 2}, {"BXOR", fun_bxor, 2}, {"BNOT", fun_bnot, 1}, {"LAND", fun_land, 2}, {"LOR", fun_lor, 2}, {"LXOR", fun_lxor, 2}, {"LNOT", fun_lnot, 1}, {"TRUTH", fun_truth, 1}, {"BASE", fun_base, 3}, {"PARENTS",fun_parents,1}, {"CHILDREN",fun_children,1}, {"SQRT", fun_sqrt, 1}, {"SGN", fun_sgn, 1}, {"ABS", fun_abs, 1}, {"FSQRT", fun_fsqrt, 1}, {"FSGN", fun_fsgn, 1}, {"FABS", fun_fabs, 1}, {"FIRST", fun_first, 1}, {"STRCAT", fun_strcat, 2}, {"REST", fun_rest, 1}, {"FLAGS", fun_flags, 1}, {"STRLEN", fun_strlen, 1}, {"COMP", fun_comp, 2}, {"FCOMP", fun_fcomp, 2}, {"SCOMP", fun_scomp, 2}, {"V", fun_v, 1}, {"S", fun_s, 1}, {"S_AS", fun_s_as, 3}, {"S_WITH", fun_s_with, -1}, {"S_AS_WITH",fun_s_as_with,-1}, {"QUOTA", fun_quota ,1}, {"ENTRANCES", fun_entrances, 1}, {"QUOTA_LEFT",fun_quota_left,1}, {"CREDITS",fun_credits,1}, {"CTIME", fun_ctime, 1}, {"MTIME", fun_mtime, 1}, {"POS", fun_pos, 2}, {"MATCH", fun_match, 2}, {"EXTRACT",fun_extract,3}, {"REMOVE", fun_remove, 3}, {"NUM", fun_num, 1}, {"CON", fun_con, 1}, {"NEXT", fun_next, 1}, {"OWNER", fun_owner, 1}, {"LOC", fun_loc, 1}, {"LINK", fun_link, 1}, {"LINKUP", fun_linkup, 1}, {"EXIT", fun_exit, 1}, {"NAME", fun_name, 1}, {"ZONE", fun_zone, 1}, {"GETZONE",fun_getzone,1}, {"LZONE", fun_lzone, 1}, {"WMATCH", fun_wmatch, 2}, {"INZONE", fun_inzone, 1}, {"ZWHO", fun_zwho, 1}, {"OBJLIST", fun_objlist, 1}, {"CONTROLS", fun_controls, 3}, {"SIN", fun_sin, 1}, {"COS", fun_cos, 1}, {"TAN", fun_tan, 1}, {"ARCSIN", fun_arcsin, 1}, {"ARCCOS", fun_arccos, 1}, {"ARCTAN", fun_arctan, 1}, {"LOG", fun_log, 1}, {"LN", fun_ln, 1}, {"EXP", fun_exp, 1}, {"POW", fun_pow, 2}, {"IF", fun_if, 2}, {"IFELSE", fun_ifelse, 3}, {"WCOUNT", fun_wcount, 1}, #ifdef USE_SPACE /* by Michael Majere */ {"DG2RD", fun_dg2rd, 1}, {"RD2DG", fun_rd2dg, 1}, {"KM2AU", fun_km2au, 1}, {"AU2KM", fun_au2km, 1}, {"KM2PS", fun_km2ps, 1}, {"PS2KM", fun_ps2km, 1}, {"KM2LY", fun_km2ly, 1}, {"LY2KM", fun_ly2km, 1}, {"KS2LS", fun_ks2ls, 1}, {"LS2KS", fun_ls2ks, 1}, {"DIST3D", fun_dist3d, 6}, {"HEAD3D", fun_head3d, 6}, {"RELHEAD",fun_relhead,4}, {"VELHDG", fun_velhdg, 3}, {"VELMAG", fun_velmag, 3}, {"RELPHI", fun_relphi, 6}, {"ORBIT", fun_orbit, 4}, {"SYNC", fun_sync, 1}, {"UPDATES", fun_updates,-1}, {"INRANGE", fun_inrange, 1}, {"INSIGHT", fun_insight, 2}, {"INSPACE", fun_inspace, 1}, {"INDIST", fun_indist, 2}, #endif {"LWHO", fun_lwho, 0}, {"SPC", fun_spc, 1}, {"FLIP", fun_flip, 1}, {"LNUM", fun_lnum, 1}, {"STRING", fun_string, 2}, {"LJUST", fun_ljust, 2}, {"RJUST", fun_rjust, 2}, {"LATTRDEF",fun_lattrdef,1}, {"LATTR", fun_lattr, 1}, {"TYPE", fun_type, 1}, {"IDLE", fun_idle, 1}, {"ONFOR", fun_onfor, 1}, {"HOST", fun_host, 1}, {"TMS", fun_tms, 1}, {"TML", fun_tml, 1}, {NULL, NULL, 0} }; void exec(); int udef_fun(str, buff, privs, doer) char **str; char *buff; dbref privs; dbref doer; { ATTR *attr; dbref tmp, defed_on = NOTHING; char obuff[1024], *args[10], *s; int a; /* check for explicit redirection */ if ((buff[0] == '#') && ((s = strchr(buff,':')) != NULL)) { *s = '\0'; tmp = (dbref) atoi(buff + 1); *s++ = ':'; if (((attr = atr_str(privs, tmp, s)) != NULL) && (attr->flags & AF_FUNC) && can_see_atr(privs, tmp, attr)) defed_on = tmp; } /* check the object doing it */ else if (((attr = atr_str(privs, tmp = privs, buff)) != NULL) && (attr->flags & AF_FUNC)) defed_on = tmp; /* check that object's zone */ else { DOZONE(tmp, privs) if (((attr = atr_str(privs, tmp, buff)) != NULL) && (attr->flags & AF_FUNC)) { defed_on = tmp; break; } } if (defed_on != NOTHING) { char result[1024], ftext[1024], *saveptr[10]; for (a = 0; a < 10; a++) args[a] = ""; for(a=0;(a<10) && **str && (**str!=')');a++) { if (**str==',') (*str)++; exec(str,obuff,privs,doer,1); strcpy(args[a]=na_alloc(glurp,strlen(obuff)+1),obuff); } for(a = 0; a < 10; a++) { saveptr[a] = wptr[a]; wptr[a] = args[a]; } if (**str) (*str)++; strcpy(ftext,atr_get(defed_on, attr)); pronoun_substitute(result,doer,ftext,privs); for(--a; a >= 0; a--) { /* na_unalloc(glurp,wptr[a]);. this is an example of something that seems to be done often. (i commented this out. it was wrong.). you do *not* unallocate things from glurp, especially static strings. glurp is freed at the beginning of each command anyways. at the for(a=0;a<10;a++) args[a]="";, it was assigning them all to "", then it was freeing them here. not good. -shkoo */ wptr[a] = saveptr[a]; } strcpy(buff, result + strlen(db[doer].name) + 1); return 1; } else return 0; } static char *disp_func (func) void *func; { return tprintf("args %d",((FUN *)func)->nargs); } void do_fun(str,buff,privs,doer) char **str; char *buff; dbref privs; dbref doer; { FUN *fp; char *args[10]; char obuff[1024]; int a; static struct hashtab *funchash=NULL; if (!funchash) funchash = make_hashtab (207, flist, sizeof(FUN), "funcs", disp_func); /* look for buff in flist */ strcpy(obuff,buff); fp = lookup_hash (funchash, hash_name (buff), buff); if (!fp) if (udef_fun(str, buff, privs, doer)) return; else { int deep=2; char *s=buff+strlen(obuff); strcpy(buff,obuff); *s++='('; while(**str && deep) switch(*s++= *(*str)++) { case '(': deep++; break; case ')': deep--; break; } if (**str) { (*str)--; s--; } *s=0; return; } /* now get the arguments to the function */ for(a=0;(a<10) && **str && (**str!=')');a++) { if (**str==',') (*str)++; #ifdef DEBUGEVAL #define DOLOG(str) do { if(command_log) { fprintf(command_log,str); fflush(command_log); } } while(0) #else #define DOLOG(str) do {} while(0) #endif exec(str,obuff,privs,doer,1); DOLOG("got back from exec\n"); strcpy(args[a]=(char *)na_alloc(glurp,strlen(obuff)+1),obuff); } if (**str) (*str)++; if ((fp->nargs!=-1) && (fp->nargs!=a)) strcpy(buff,tprintf("Function (%s) only expects %d arguments", fp->name,fp->nargs)); else { extern int floating_x; DOLOG("trying function "); DOLOG(fp->name); floating_x = 0; fp->fun(buff,args,privs,doer,a); if (floating_x) strcpy (buff,"Floating exception."); } } static int lev=0; /* the in depth level which we're at. */ void func_zerolev() {lev=0;} /* called from process_command just in case this goes bezerko */ /* execute a string expression, return result in buff */ void exec(str,buff,privs,doer,coma) char **str; char *buff; dbref privs; dbref doer; int coma; { char *s,*e=buff; #ifdef DEBUGEVAL extern FILE *command_log; #endif lev++; /* enter the func. */ if(lev>20) { strcpy(buff,"Too many levels of recursion."); lev--;return; } *buff=0; DOLOG("execing:"); DOLOG(*str); DOLOG("\n"); /* eat preceding space */ for(s= *str;*s && isspace(*s);s++); /* parse until (,],) or , */ for(;*s;s++) switch(*s) { case ',': /* comma in list of function arguments */ case ')': /* end of arguments */ if (!coma) goto cont; case ']': /* end of expression */ /* eat trailing space */ while((--e>=buff) && isspace(*e)); e[1]=0; *str=s; lev--;return; case '(': /* this is a function */ while((--e>=buff) && isspace(*e)); e[1]=0; *str=s+1; /* if just ()'s by them self then it is quoted */ if (*buff) do_fun(str,buff,privs,doer); lev--;return; case '{': if (e==buff) { int deep=1; e=buff; s++; while(deep && *s) switch(*e++= *s++) { case '{': deep++; break; case '}': deep--; break; } if ((e>buff) && (e[-1]=='}')) e--; while((--e>=buff) && isspace(*e)); e[1]=0; *str=s; lev--;return; } else { /* otherwise is a quote in middle, search for other end */ int deep=1; *e++= *s++; while(deep && *s) switch(*e++= *s++) { case '{': deep++; break; case '}': deep--; break; } s--; } break; default: cont: *e++= *s; break; } while((--e>=buff) && isspace(*e)); e[1]=0; *str=s; lev--;return; } /* function to split up a list given a seperator */ /* note str will get hacked up */ char *parse_up(str,delimit) char **str; int delimit; { int deep=0; char *s= *str,*os= *str; if (!*s) return(NULL); while(*s && (*s!=delimit)) if (*s++=='{') { deep=1; while(deep && *s) switch(*s++) { case '{': deep++; break; case '}': deep--; break; } } if (*s) *s++=0; *str=s; return(os); }