/* 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);
}