Example #1
0
/** Helper function for calling \@functioned funs.
 * \param buff string to store result of evaluation.
 * \param bp pointer into end of buff.
 * \param obj object on which the ufun is stored.
 * \param attrib pointer to attribute on which the ufun is stored.
 * \param nargs number of arguments passed to the ufun.
 * \param args array of arguments passed to the ufun.
 * \param executor executor.
 * \param caller caller (unused).
 * \param enactor enactor.
 * \param pe_info pointer to structure for process_expression data.
 * \param extra_flags extra PE_ flags to pass in (PE_USERFN or 0).
 */
void
do_userfn(char *buff, char **bp, dbref obj, ATTR *attrib, int nargs,
          char **args, dbref executor, dbref caller
          __attribute__ ((__unused__)), dbref enactor, NEW_PE_INFO *pe_info,
          int extra_flags)
{
  int j;
  int made_pe_info = 0;
  char *tbuf;
  char const *tp;
  int pe_flags = PE_DEFAULT | extra_flags;
  PE_REGS *pe_regs;

  if (nargs > 10)
    nargs = 10;                 /* maximum ten args */

  /* save our stack */
  if (!pe_info) {
    made_pe_info = 1;
    pe_info = make_pe_info("pe_info-do_userfn");
  }

  /* copy the appropriate args into pe_regs */
  pe_regs = pe_regs_localize(pe_info, PE_REGS_ARG, "do_userfn");
  for (j = 0; j < nargs; j++) {
    pe_regs_setenv_nocopy(pe_regs, j, args[j]);
  }

  tp = tbuf = safe_atr_value(attrib);
  if (AF_NoDebug(attrib))
    pe_flags |= PE_NODEBUG;     /* no_debug overrides debug */
  else if (AF_Debug(attrib))
    pe_flags |= PE_DEBUG;

  process_expression(buff, bp, &tp, obj, executor, enactor, pe_flags,
                     PT_DEFAULT, pe_info);

  free(tbuf);

  pe_regs_restore(pe_info, pe_regs);
  pe_regs_free(pe_regs);

  if (made_pe_info) {
    free_pe_info(pe_info);
  }
}
Example #2
0
/** Evaluate a lock, saving/clearing the env (%0-%9) and qreg (%q*) first,
 ** and restoring them after.
 */
int
eval_lock_clear(dbref player, dbref thing, lock_type ltype,
                NEW_PE_INFO *pe_info)
{
  if (!pe_info)
    return eval_lock_with(player, thing, ltype, NULL);
  else {
    PE_REGS *pe_regs;
    int result;

    pe_regs = pe_regs_localize(pe_info, PE_REGS_ISOLATE, "eval_lock_clear");

    /* Run the lock */
    result = eval_lock_with(player, thing, ltype, pe_info);

    /* Restore q-regs */
    pe_regs_restore(pe_info, pe_regs);
    pe_regs_free(pe_regs);
    return result;
  }
}
Example #3
0
/** Given a ufun, executor, enactor, PE_Info, and arguments for %0-%9,
 *  call the ufun with appropriate permissions on values given for
 *  wenv_args. The value returned is stored in the buffer pointed to
 *  by ret, if given.
 * \param ufun The ufun_attrib that was initialized by fetch_ufun_attrib
 * \param ret If desired, a pointer to a buffer in which the results
 *            of the process_expression are stored in.
 * \param caller The caller (%@).
 * \param enactor The enactor. (%#)
 * \param pe_info The pe_info passed to the FUNCTION
 * \param user_regs Other arguments that may want to be added. This nests BELOW
 *                the pe_regs created by call_ufun. (It is checked first)
 * \param data a void pointer to extra data. Currently only used to pass the
 *             name to use, when UFUN_NAME is given.
 * \retval 0 success
 * \retval 1 process_expression failed. (CPU time limit)
 */
bool
call_ufun_int(ufun_attrib * ufun, char *ret, dbref caller, dbref enactor,
              NEW_PE_INFO *pe_info, PE_REGS *user_regs, void *data)
{
  char rbuff[BUFFER_LEN];
  char *rp, *np = NULL;
  int pe_ret;
  char const *ap;
  char old_attr[BUFFER_LEN];
  int made_pe_info = 0;
  PE_REGS *pe_regs;
  PE_REGS *pe_regs_old;
  int pe_reg_flags = 0;

  /* Make sure we have a ufun first */
  if (!ufun)
    return 1;
  if (!pe_info) {
    pe_info = make_pe_info("pe_info.call_ufun");
    made_pe_info = 1;
  } else {
    strcpy(old_attr, pe_info->attrname);
  }

  pe_regs_old = pe_info->regvals;

  if (ufun->ufun_flags & UFUN_LOCALIZE)
    pe_reg_flags |= PE_REGS_Q;
  else {
    pe_reg_flags |= PE_REGS_NEWATTR;
    if (ufun->ufun_flags & UFUN_SHARE_STACK)
      pe_reg_flags |= PE_REGS_ARGPASS;
  }

  pe_regs = pe_regs_localize(pe_info, pe_reg_flags, "call_ufun");

  rp = pe_info->attrname;
  if (*ufun->attrname == '\0') {
    safe_str("#LAMBDA", pe_info->attrname, &rp);
    safe_chr('/', pe_info->attrname, &rp);
    safe_str(ufun->contents, pe_info->attrname, &rp);
  } else {
    safe_dbref(ufun->thing, pe_info->attrname, &rp);
    safe_chr('/', pe_info->attrname, &rp);
    safe_str(ufun->attrname, pe_info->attrname, &rp);
  }
  *rp = '\0';

  /* If the user doesn't care about the return of the expression,
   * then use our own rbuff.  */
  if (!ret)
    ret = rbuff;
  rp = ret;

  /* Anything the caller wants available goes on the bottom of the stack */
  if (user_regs) {
    user_regs->prev = pe_info->regvals;
    pe_info->regvals = user_regs;
  }

  if (ufun->ufun_flags & UFUN_NAME) {
    char *name = (char *) data;
    if (!name || !*name)
      name = (char *) Name(enactor);
    safe_str(name, ret, &rp);
    if (!(ufun->ufun_flags & UFUN_NAME_NOSPACE))
      safe_chr(' ', ret, &rp);
    np = rp;
  }


  /* And now, make the call! =) */
  ap = ufun->contents;
  pe_ret = process_expression(ret, &rp, &ap, ufun->thing, caller,
                              enactor, ufun->pe_flags, PT_DEFAULT, pe_info);
  *rp = '\0';

  if ((ufun->ufun_flags & UFUN_NAME) && np == rp) {
    /* Attr was empty, so we take off the name again */
    *ret = '\0';
  }

  /* Restore call_ufun's pe_regs */
  if (user_regs) {
    pe_info->regvals = user_regs->prev;
  }

  /* Restore the pe_regs stack. */
  pe_regs_restore(pe_info, pe_regs);
  pe_regs_free(pe_regs);

  pe_info->regvals = pe_regs_old;

  if (!made_pe_info) {
    /* Restore the old attrname. */
    strcpy(pe_info->attrname, old_attr);
  } else {
    free_pe_info(pe_info);
  }

  return pe_ret;
}