#include "copyrite.h"
#include "config.h"
#include "conf.h"
#include "externs.h"
#include "intrface.h"
#include "match.h"
#include "parse.h"
#include "mymalloc.h"
#include "confmagic.h"
void do_userfn _((char *buff, char **bp, dbref obj, ATTR *attrib, int nargs, char **args, dbref executor, dbref caller, dbref enactor, PE_Info * pe_info));
/* ARGSUSED */
FUNCTION(fun_s)
{
char const *p;
p = args[0];
process_expression(buff, bp, &p, executor, caller, enactor,
PE_DEFAULT, PT_DEFAULT, pe_info);
return;
}
/* ARGSUSED */
FUNCTION(fun_objeval)
{
char name[BUFFER_LEN];
char *s;
char const *p;
dbref obj;
/* First, we evaluate our first argument so people can use
* functions on it.
*/
s = name;
p = args[0];
process_expression(name, &s, &p, executor, caller, enactor,
PE_DEFAULT, PT_DEFAULT, pe_info);
*s = '\0';
#ifdef FUNCTION_SIDE_EFFECTS
/* The security hole created by function side effects is too great
* to allow a see_all player to evaluate functions from someone else's
* standpoint. We require control.
*/
if (((obj = match_thing(executor, name)) == NOTHING) ||
!controls(executor, obj))
obj = executor;
#else
/* In order to evaluate from something else's viewpoint, you
* must own it, or be able to see_all.
*/
if (((obj = match_thing(executor, name)) == NOTHING) ||
(!Owns(executor, obj) && !See_All(executor)))
obj = executor;
#endif
p = args[1];
process_expression(buff, bp, &p, obj, executor, enactor,
PE_DEFAULT, PT_DEFAULT, pe_info);
}
void
do_userfn(buff, bp, obj, attrib, nargs, args,
executor, caller, enactor, pe_info)
char *buff, **bp;
dbref obj;
ATTR *attrib;
int nargs;
char **args;
dbref executor, caller, enactor;
PE_Info *pe_info;
{
int j;
char *tptr[10];
char *tbuf;
char const *tp;
/* save our stack */
for (j = 0; j < 10; j++)
tptr[j] = wenv[j];
/* copy the appropriate args into the stack */
if (nargs > 10)
nargs = 10; /* maximum ten args */
for (j = 0; j < nargs; j++)
wenv[j] = args[j];
for (; j < 10; j++)
wenv[j] = NULL;
tp = tbuf = safe_uncompress(attrib->value);
process_expression(buff, bp, &tp, obj, executor, enactor,
PE_DEFAULT, PT_DEFAULT, pe_info);
free(tbuf);
/* restore the stack */
for (j = 0; j < 10; j++)
wenv[j] = tptr[j];
}
/* ARGSUSED */
FUNCTION(fun_ufun)
{
ATTR *attrib;
dbref obj;
/* find the user function attribute */
parse_attrib(executor, args[0], &obj, &attrib);
if (attrib && Can_Read_Attr(executor, obj, attrib)) {
if (SAFER_UFUN)
if ((!Wizard(executor) && Wizard(obj)) ||
(!God(executor) && God(obj)) ||
(!Hasprivs(executor) && Hasprivs(obj))) {
safe_str("#-1 PERMISSION DENIED", buff, bp);
return;
}
do_userfn(buff, bp, obj, attrib, nargs - 1, args + 1,
executor, caller, enactor, pe_info);
return;
} else if (attrib || !Can_Examine(executor, obj)) {
safe_str("#-1 NO PERMISSION TO GET ATTRIBUTE", buff, bp);
return;
}
return;
}
/* ARGSUSED */
FUNCTION(fun_ulocal)
{
/* Like fun_ufun, but saves the state of the q0-q9 registers
* when called
*/
ATTR *attrib;
dbref obj;
char *preserve[10];
/* find the user function attribute */
parse_attrib(executor, args[0], &obj, &attrib);
if (attrib && Can_Read_Attr(executor, obj, attrib)) {
if (SAFER_UFUN)
if ((!Wizard(executor) && Wizard(obj)) ||
(!God(executor) && God(obj)) ||
(!Hasprivs(executor) && Hasprivs(obj))) {
safe_str("#-1 PERMISSION DENIED", buff, bp);
return;
}
save_global_regs("ulocal.save", preserve);
do_userfn(buff, bp, obj, attrib, nargs - 1, args + 1,
executor, caller, enactor, pe_info);
restore_global_regs("ulocal.save", preserve);
return;
} else if (attrib || !Can_Examine(executor, obj)) {
safe_str("#-1 NO PERMISSION TO GET ATTRIBUTE", buff, bp);
return;
}
return;
}
/* Like fun_ufun, but takes as second argument a default message
* to use if the attribute isn't there
*/
/* ARGSUSED */
FUNCTION(fun_udefault)
{
dbref thing;
ATTR *attrib;
char *dp;
char const *sp;
char mstr[BUFFER_LEN];
char **xargs;
int i;
/* find our object and attribute */
dp = mstr;
sp = args[0];
process_expression(mstr, &dp, &sp, executor, caller, enactor,
PE_DEFAULT, PT_DEFAULT, pe_info);
*dp = '\0';
parse_attrib(executor, mstr, &thing, &attrib);
if (GoodObject(thing) && attrib &&
(!SAFER_UFUN ||
(!(!Wizard(executor) && Wizard(thing)) &&
!(!God(executor) && God(thing)) &&
!(!Hasprivs(executor) && Hasprivs(thing)))) &&
Can_Read_Attr(executor, thing, attrib)) {
/* Ok, we've got it */
/* We must now evaluate all the arguments from args[2] on and
* pass them to the function */
xargs = NULL;
if (nargs > 2) {
xargs = (char **) mush_malloc((nargs - 2) * sizeof(char *), "udefault.xargs");
for (i = 0; i < nargs - 2; i++) {
xargs[i] = (char *) mush_malloc(BUFFER_LEN, "udefault");
dp = xargs[i];
sp = args[i + 2];
process_expression(xargs[i], &dp, &sp, executor, caller, enactor,
PE_DEFAULT, PT_DEFAULT, pe_info);
*dp = '\0';
}
}
do_userfn(buff, bp, thing, attrib, nargs - 2, xargs,
executor, caller, enactor, pe_info);
/* Free the xargs */
if (nargs > 2) {
for (i = 0; i < nargs - 2; i++)
mush_free(xargs[i], "udefault");
mush_free(xargs, "udefault.xargs");
}
return;
}
/* We couldn't get it. Evaluate args[1] and return it */
sp = args[1];
process_expression(buff, bp, &sp, executor, caller, enactor,
PE_DEFAULT, PT_DEFAULT, pe_info);
return;
}
/* ARGSUSED */
FUNCTION(fun_zfun)
{
ATTR *attrib;
dbref zone;
zone = Zone(executor);
if (zone == NOTHING) {
safe_str("#-1 INVALID ZONE", buff, bp);
return;
}
/* find the user function attribute */
attrib = atr_get(zone, upcasestr(args[0]));
if (attrib && Can_Read_Attr(executor, zone, attrib)) {
if (SAFER_UFUN)
if ((!Wizard(executor) && Wizard(zone)) ||
(!God(executor) && God(zone)) ||
(!Hasprivs(executor) && Hasprivs(zone))) {
safe_str("#-1 NO PERMISSION TO RUN ATTRIBUTE", buff, bp);
return;
}
do_userfn(buff, bp, zone, attrib, nargs - 1, args + 1,
executor, caller, enactor, pe_info);
} else if (attrib || !Can_Examine(executor, zone)) {
safe_str("#-1 NO PERMISSION TO GET ATTRIBUTE", buff, bp);
return;
}
safe_str("#-1 NO SUCH USER FUNCTION", buff, bp);
return;
}