Beispiel #1
0
void display_flagtab(dbref player)
{
    UTF8 *buf, *bp;
    FLAGNAMEENT *fp;

    bp = buf = alloc_lbuf("display_flagtab");
    safe_str(T("Flags:"), buf, &bp);
    for (fp = gen_flag_names; fp->flagname; fp++)
    {
        FLAGBITENT *fbe = fp->fbe;
        if (  (  (fbe->listperm & CA_WIZARD)
              && !Wizard(player))
           || (  (fbe->listperm & CA_GOD)
              && !God(player)))
        {
            continue;
        }
        safe_chr(' ', buf, &bp);
        safe_str(fp->flagname, buf, &bp);
        if (fbe->flaglett != ' ')
        {
            safe_chr('(', buf, &bp);
            if (!fp->bPositive)
            {
                safe_chr('!', buf, &bp);
            }
            safe_chr(fbe->flaglett, buf, &bp);
            safe_chr(')', buf, &bp);
        }
    }
    *bp = '\0';
    notify(player, buf);
    free_lbuf(buf);
}
Beispiel #2
0
/** Return a list of all available locks
 * \param buff the buffer
 * \param bp a pointer to the current position in the buffer.
 * \param name if not NULL, only show locks with this prefix
 */
void
list_locks(char *buff, char **bp, const char *name)
{
  lock_list **locks, *lk;
  bool first = 1;
  int nlocks = 0, n;

  locks = mush_calloc(htab_locks.entries, sizeof(lock_list), "lock.list");

  for (lk = hash_firstentry(&htab_locks); lk; lk = hash_nextentry(&htab_locks)) {
    /* Skip those that don't match */
    if (name && !string_prefix(lk->type, name))
      continue;
    locks[nlocks++] = lk;
  }

  qsort(locks, nlocks, sizeof lk, lock_compare);

  for (n = 0; n < nlocks; n += 1) {
    if (first) {
      first = 0;
    } else {
      safe_chr(' ', buff, bp);
    }
    safe_str(strupper(locks[n]->type), buff, bp);
  }

  mush_free(locks, "lock.list");
}
Beispiel #3
0
/** Given a warning bitmask, return a string of warnings on it.
 * \param warns the warnings.
 * \return pointer to statically allocated string listing warnings.
 */
const char *
unparse_warnings(warn_type warns)
{
    static char tbuf1[BUFFER_LEN];
    char *tp;
    int listsize, indexx;

    tp = tbuf1;

    /* Get the # of elements in checklist */
    listsize = sizeof(checklist) / sizeof(tcheck);

    /* Point c at last non-null in checklist, and go backwards */
    for (indexx = listsize - 2; warns && (indexx >= 0); indexx--) {
        warn_type the_flag = checklist[indexx].flag;
        if (!(the_flag & ~warns)) {
            /* Which is to say:
             * if the bits set on the_flag is a subset of the bits set on warns
             */
            safe_str(checklist[indexx].name, tbuf1, &tp);
            safe_chr(' ', tbuf1, &tp);
            /* If we've got a flag which subsumes smaller ones, don't
             * list the smaller ones
             */
            warns &= ~the_flag;
        }
    }
    *tp = '\0';
    return tbuf1;
}
Beispiel #4
0
/** Return a list of standard attributes.
 * This functions returns the list of standard attributes, separated by
 * spaces, in a statically allocated buffer.
 */
char *
list_attribs(void)
{
  ATTR *ap;
  const char *ptrs[BUFFER_LEN / 2];
  static char buff[BUFFER_LEN];
  char *bp;
  const char *name;
  int nptrs = -1, i;

  for (ap = ptab_firstentry_new(&ptab_attrib, &name);
       ap; ap = ptab_nextentry_new(&ptab_attrib, &name)) {
    if (strcmp(name, AL_NAME(ap)))
      continue;
    ptrs[++nptrs] = AL_NAME(ap);
  }
  bp = buff;
  if (nptrs >= 0)
    safe_str(ptrs[0], buff, &bp);
  for (i = 1; i < nptrs; i++) {
    safe_chr(' ', buff, &bp);
    safe_str(ptrs[i], buff, &bp);
  }
  *bp = '\0';
  return buff;
}
Beispiel #5
0
dbref absolute_nref(char *str)
{
    char *p, *q, *buf, *bp;
    dbref *np, nref;
    /*
     * Global or local reference? Global references are automatically
     * * prepended with an additional underscore. i.e., #__foo_ is a global
     * * reference, and #_foo_ is a local reference.
     * * Our beginning and end underscores have already been stripped, so
     * * we would see only _foo or foo.
     * *
     * * We are not allowed to nibble our buffer, because we've got a
     * * pointer into the match string. Therefore we must copy it.
     * * If we're matching locally we copy the dbref of the owner first,
     * * which means that we then need to worry about buffer size.
     */
    buf = alloc_lbuf("absolute_nref");

    if (*str == '_') {
	for (p = buf, q = str; *q; p++, q++) {
	    *p = tolower(*q);
	}

	*p = '\0';
    } else {
	bp = buf;
	safe_ltos(buf, &bp, Owner(md.player), LBUF_SIZE);
	safe_chr('.', buf, &bp);

	for (q = str; *q; q++) {
	    safe_chr(tolower(*q), buf, &bp);
	}

	*bp = '\0';
    }

    np = (int *) hashfind(buf, &mudstate.nref_htab);

    if (np && Good_obj(*np)) {
	nref = *np;
    } else {
	nref = NOTHING;
    }

    free_lbuf(buf);
    return nref;
}
Beispiel #6
0
// Transform CRLF runs to a space.
//
UTF8 *ConvertCRLFtoSpace(const UTF8 *pString)
{
    static UTF8 buf[LBUF_SIZE];
    UTF8 *bp = buf;

    // Skip any leading CRLF as well as non-ASCII.
    //
    while (  '\r' == *pString
          || '\n' == *pString
          || (0x80 & *pString) == 0x80)
    {
        pString++;
    }

    bool bFirst = true;
    while (*pString)
    {
        if (!bFirst)
        {
            safe_chr(' ', buf, &bp);
        }
        else
        {
            bFirst = false;
        }

        while (  *pString
              && '\r' != *pString
              && '\n' != *pString
              && (0x80 & *pString) == 0x00)
        {
            safe_chr(*pString, buf, &bp);
            pString++;
        }

        // Skip any CRLF.
        //
        while (  '\r' == *pString
              || '\n' == *pString
              || 0x80 == (0x80 & *pString))
        {
            pString++;
        }
    }
    *bp = '\0';
    return buf;
}
Beispiel #7
0
/* Show the 'Obvious Exits' list for a room. Used in 'look' and 'examine'.
 * \param player The player looking
 * \param loc room whose exits we're showing
 * \param exit_name "Obvious Exits" string
 * \param pe_info the pe_info to use for evaluating EXITFORMAT and interact locks
 */
static void
look_exits(dbref player, dbref loc, const char *exit_name, NEW_PE_INFO *pe_info)
{
  dbref thing;
  char *tbuf1, *tbuf2, *nbuf;
  char *s1, *s2;
  char *p;
  int exit_count, this_exit, total_count;
  int texits;
  ufun_attrib ufun;
  PUEBLOBUFF;

  /* make sure location is a room */
  if (!IsRoom(loc))
    return;

  tbuf1 = (char *) mush_malloc(BUFFER_LEN, "string");
  tbuf2 = (char *) mush_malloc(BUFFER_LEN, "string");
  nbuf = (char *) mush_malloc(BUFFER_LEN, "string");
  if (!tbuf1 || !tbuf2 || !nbuf)
    mush_panic("Unable to allocate memory in look_exits");
  s1 = tbuf1;
  s2 = tbuf2;
  texits = exit_count = total_count = 0;
  this_exit = 1;

  if (fetch_ufun_attrib
      ("EXITFORMAT", loc, &ufun, UFUN_IGNORE_PERMS | UFUN_REQUIRE_ATTR)) {
    char *arg, *buff, *bp;
    PE_REGS *pe_regs = pe_regs_create(PE_REGS_ARG, "look_exits");

    arg = (char *) mush_malloc(BUFFER_LEN, "string");
    buff = (char *) mush_malloc(BUFFER_LEN, "string");
    if (!arg || !buff)
      mush_panic("Unable to allocate memory in look_exits");

    bp = arg;
    DOLIST(thing, Exits(loc)) {
      if (((Light(loc) || Light(thing)) || !(Dark(loc) || Dark(thing)))
          && can_interact(thing, player, INTERACT_SEE, pe_info)) {
        if (bp != arg)
          safe_chr(' ', arg, &bp);
        safe_dbref(thing, arg, &bp);
      }
    }
    *bp = '\0';
    pe_regs_setenv_nocopy(pe_regs, 0, arg);

    call_ufun(&ufun, buff, player, player, pe_info, pe_regs);

    pe_regs_free(pe_regs);
    notify_by(loc, player, buff);
    mush_free(tbuf1, "string");
    mush_free(tbuf2, "string");
    mush_free(nbuf, "string");
    mush_free(arg, "string");
    mush_free(buff, "string");
    return;
  }
Beispiel #8
0
void
list_lock_flags(char *buff, char **bp)
{
  int i;
  for (i = 0; lock_privs[i].name; i++) {
    if (lock_privs[i].letter)
      safe_chr(lock_privs[i].letter, buff, bp);
  }
}
Beispiel #9
0
static UTF8 *munge_space_for_match(const UTF8 *name, size_t n)
{
    static UTF8 buffer[LBUF_SIZE];

    size_t i = 0;
    UTF8 *q = buffer;

    if (NULL != name)
    {
        // Remove Initial spaces.
        //
        while (mux_isspace(name[i]))
        {
            i++;
        }

        while (i < n)
        {
            while (  i < n
                  && !mux_isspace(name[i]))
            {
                safe_chr(name[i], buffer, &q);
                i++;
            }

            while (mux_isspace(name[i]))
            {
                i++;
            }

            if (i < n)
            {
                safe_chr(' ', buffer, &q);
            }
        }
    }

    // Remove terminal spaces and terminate string.
    //
    *q = '\0';
    return buffer;
}
Beispiel #10
0
/** Display an access rule.
 * \param ap pointer to access rule.
 * \param rulenum access rule's number in the list.
 * \param who unused.
 * \param buff buffer to store output.
 * \param bp pointer into buff.
 * This function provides an appealing display of an access rule
 * in the list.
 */
void
format_access(struct access *ap, int rulenum,
              dbref who __attribute__ ((__unused__)), char *buff, char **bp)
{
  if (ap) {
    safe_format(buff, bp, T("Matched line %d: %s %s"), rulenum, ap->host,
                (ap->can & ACS_REGEXP) ? "(regexp)" : "");
    safe_chr('\n', buff, bp);
    safe_format(buff, bp, T("Comment: %s"), ap->comment);
    safe_chr('\n', buff, bp);
    safe_str(T("Connections allowed by: "), buff, bp);
    if (ap->cant & ACS_CONNECT)
      safe_str(T("No one"), buff, bp);
    else if (ap->cant & ACS_ADMIN)
      safe_str(T("All but admin"), buff, bp);
    else if (ap->cant & ACS_WIZARD)
      safe_str(T("All but wizards"), buff, bp);
    else if (ap->cant & ACS_GOD)
      safe_str(T("All but God"), buff, bp);
    else
      safe_str(T("All"), buff, bp);
    safe_chr('\n', buff, bp);
    if (ap->cant & ACS_GUEST)
      safe_str(T("Guest connections are NOT allowed"), buff, bp);
    else
      safe_str(T("Guest connections are allowed"), buff, bp);
    safe_chr('\n', buff, bp);
    if (ap->cant & ACS_CREATE)
      safe_str(T("Creation is NOT allowed"), buff, bp);
    else
      safe_str(T("Creation is allowed"), buff, bp);
    safe_chr('\n', buff, bp);
    if (ap->can & ACS_REGISTER)
      safe_str(T("Email registration is allowed"), buff, bp);
    if (ap->can & ACS_SUSPECT)
      safe_str(T("Players connecting are set SUSPECT"), buff, bp);
    if (ap->can & ACS_DENY_SILENT)
      safe_str(T("Denied connections are not logged"), buff, bp);
  } else {
    safe_str(T("No matching access rule"), buff, bp);
  }
}
Beispiel #11
0
/** Display the access list.
 * \param player enactor.
 * Sends the complete access list to the player.
 */
void
do_list_access(dbref player)
{
  struct access *ap;
  acsflag *c;
  char flaglist[BUFFER_LEN];
  int rulenum = 0;
  char *bp;

  for (ap = access_top; ap; ap = ap->next) {
    rulenum++;
    if (ap->can != ACS_SITELOCK) {
      bp = flaglist;
      for (c = acslist; c->name; c++) {
        if (c->flag == ACS_DEFAULT)
          continue;
        if (ap->can & c->flag) {
          safe_chr(' ', flaglist, &bp);
          safe_str(c->name, flaglist, &bp);
        }
        if (c->toggle && (ap->cant & c->flag)) {
          safe_chr(' ', flaglist, &bp);
          safe_chr('!', flaglist, &bp);
          safe_str(c->name, flaglist, &bp);
        }
      }
      *bp = '\0';
      notify_format(player,
                    T("%3d SITE: %-20s  DBREF: %-6s FLAGS:%s"), rulenum,
                    ap->host, unparse_dbref(ap->who), flaglist);
      notify_format(player, T(" COMMENT: %s"), ap->comment ? ap->comment : "");
    } else {
      notify(player,
             T
             ("---- @sitelock will add sites immediately below this line ----"));
    }

  }
  if (rulenum == 0) {
    notify(player, T("There are no access rules."));
  }
}
Beispiel #12
0
static void ShowPsLine(BQUE *tmp)
{
    char *bufp = unparse_object(Show_Player, tmp->executor, false);
    if (tmp->IsTimed && (Good_obj(tmp->sem)))
    {
        CLinearTimeDelta ltd = tmp->waittime - Show_lsaNow;
        notify(Show_Player, tprintf("[#%d/%d]%s:%s", tmp->sem, ltd.ReturnSeconds(), bufp, tmp->comm));
    }
    else if (tmp->IsTimed)
    {
        CLinearTimeDelta ltd = tmp->waittime - Show_lsaNow;
        notify(Show_Player, tprintf("[%d]%s:%s", ltd.ReturnSeconds(), bufp, tmp->comm));
    }
    else if (Good_obj(tmp->sem))
    {
        notify(Show_Player, tprintf("[#%d]%s:%s", tmp->sem, bufp, tmp->comm));
    }
    else
    {
        notify(Show_Player, tprintf("%s:%s", bufp, tmp->comm));
    }
    char *bp = bufp;
    if (Show_Key == PS_LONG)
    {
        for (int i = 0; i < tmp->nargs; i++)
        {
            if (tmp->env[i] != NULL)
            {
                safe_str("; Arg", bufp, &bp);
                safe_chr((char)(i + '0'), bufp, &bp);
                safe_str("='", bufp, &bp);
                safe_str(tmp->env[i], bufp, &bp);
                safe_chr('\'', bufp, &bp);
            }
        }
        *bp = '\0';
        bp = unparse_object(Show_Player, tmp->enactor, false);
        notify(Show_Player, tprintf("   Enactor: %s%s", bp, bufp));
        free_lbuf(bp);
    }
    free_lbuf(bufp);
}
Beispiel #13
0
void
list_lock_flags_long(char *buff, char **bp)
{
  int i;
  int first = 1;
  for (i = 0; lock_privs[i].name; i++) {
    if (!first)
      safe_chr(' ', buff, bp);
    first = 0;
    safe_str(lock_privs[i].name, buff, bp);
  }
}
Beispiel #14
0
static void ReportMatchedTopics(dbref executor, const UTF8 *topic, CHashTable *htab)
{
    bool matched = false;
    UTF8 *topic_list = NULL;
    UTF8 *buffp = NULL;
    struct help_entry *htab_entry;
    for (htab_entry = (struct help_entry *)hash_firstentry(htab);
         htab_entry != NULL;
         htab_entry = (struct help_entry *)hash_nextentry(htab))
    {
        mudstate.wild_invk_ctr = 0;
        if (  htab_entry->key
           && quick_wild(topic, htab_entry->key))
        {
            if (!matched)
            {
                matched = true;
                topic_list = alloc_lbuf("help_write");
                buffp = topic_list;
            }
            safe_str(htab_entry->key, topic_list, &buffp);
            safe_chr(' ', topic_list, &buffp);
            safe_chr(' ', topic_list, &buffp);
        }
    }

    if (!matched)
    {
        notify(executor, tprintf(T("No entry for \xE2\x80\x98%s\xE2\x80\x99."), topic));
    }
    else
    {
        notify(executor, tprintf(T("Here are the entries which match \xE2\x80\x98%s\xE2\x80\x99:"), topic));
        *buffp = '\0';
        notify(executor, topic_list);
        free_lbuf(topic_list);
    }
}
Beispiel #15
0
void display_flagtab( dbref player ) {
    char *buf, *bp;

    FLAGENT *fp;

    bp = buf = alloc_lbuf( "display_flagtab" );
    safe_str( ( char * ) "Flags:", buf, &bp );
    for( fp = gen_flags; fp->flagname; fp++ ) {
        if( ( fp->listperm & CA_WIZARD ) && !Wizard( player ) ) {
            continue;
        }
        if( ( fp->listperm & CA_GOD ) && !God( player ) ) {
            continue;
        }
        safe_chr( ' ', buf, &bp );
        safe_str( ( char * ) fp->flagname, buf, &bp );
        safe_chr( '(', buf, &bp );
        safe_chr( fp->flaglett, buf, &bp );
        safe_chr( ')', buf, &bp );
    }
    *bp = '\0';
    notify( player, buf );
    free_lbuf( buf );
}
Beispiel #16
0
static void
grep_add_attr(char *buff, char **bp, dbref player, int count, ATTR *attr,
              char *atrval)
{

  if (buff) {
    if (count)
      safe_chr(' ', buff, bp);
    safe_str(AL_NAME(attr), buff, bp);
  } else {
    notify_format(player, "%s%s [#%d%s]:%s %s",
                  ANSI_HILITE, AL_NAME(attr),
                  Owner(AL_CREATOR(attr)),
                  privs_to_letters(attr_privs_view, AL_FLAGS(attr)),
                  ANSI_END, atrval);
  }
}
Beispiel #17
0
/* Called when you issue localfunc() with the name of the function and args
 * 
 */
void local_function(char *funcname, char *buff, char **bufcx, dbref player, dbref cause,
                    char *fargs[], int nfargs, char *cargs[], int ncargs) {

   if ( !funcname || !*funcname ) {
      safe_str("#-1 NO FUNCTION", buff, bufcx);
      return;
   }
   if ( stricmp(funcname, "test") == 0 ) {
      safe_str("This was a test. Function: '", buff, bufcx);
      safe_str(funcname, buff, bufcx);
      safe_str("' First Arg: '", buff, bufcx);
      safe_str(fargs[0], buff, bufcx);
      safe_chr('\'', buff, bufcx);
   } else {
      safe_str("#-1 NO FUNCTION", buff, bufcx);
   }
}
Beispiel #18
0
static void
do_whichof(char *args[], int nargs, enum whichof_t flag,
           char *buff, char **bp, dbref executor,
           dbref caller, dbref enactor, PE_Info *pe_info, int isbool)
{
  int j;
  char tbuf[BUFFER_LEN], *tp;
  char const *sp;
  char sep = ' ';
  int first = 1;
  tbuf[0] = '\0';
  if (flag == DO_ALLOF) {
    /* The last arg is a delimiter. Parse it in place. */
    char insep[BUFFER_LEN];
    char *isep = insep;
    const char *arglast = args[nargs - 1];
    process_expression(insep, &isep, &arglast, executor,
                       caller, enactor, PE_DEFAULT, PT_DEFAULT, pe_info);
    *isep = '\0';
    strcpy(args[nargs - 1], insep);
    if (!delim_check(buff, bp, nargs, args, nargs, &sep))
      return;
    nargs--;
  }

  for (j = 0; j < nargs; j++) {
    tp = tbuf;
    sp = args[j];
    process_expression(tbuf, &tp, &sp, executor, caller,
                       enactor, PE_DEFAULT, PT_DEFAULT, pe_info);
    *tp = '\0';
    if ((isbool && parse_boolean(tbuf)) || (!isbool && strlen(tbuf))) {
      if (!first) {
        safe_chr(sep, buff, bp);
      } else
        first = 0;
      safe_str(tbuf, buff, bp);
      if (flag == DO_FIRSTOF)
        return;
    }
  }
  if (flag == DO_FIRSTOF)
    safe_str(tbuf, buff, bp);
}
Beispiel #19
0
/** Return a list of all available locks
 * \param buff the buffer
 * \param bp a pointer to the current position in the buffer
 */
void
list_locks(char *buff, char **bp, const char *name)
{
  char rbuff[BUFFER_LEN];
  char *rp;
  int first = 1;
  const lock_list *ptr;
  rp = rbuff;
  for (ptr = lock_types; ptr->type != NULL; ptr++) {
    /* Skip those that don't match */
    if (name && !string_prefix(ptr->type, name))
      continue;
    if (first) {
      first = 0;
    } else {
      safe_chr(' ', rbuff, &rp);
    }
    safe_str(ptr->type, rbuff, &rp);
  }
  *rp = '\0';
  /* We strupper it for consistency with the other
   * @list/foo and list(foo)s. */
  safe_str(strupper(rbuff), buff, bp);
}
Beispiel #20
0
/** Return a list of standard attributes.
 * This functions returns the list of standard attributes, separated by
 * spaces, in a statically allocated buffer.
 */
char *
list_attribs(void)
{
  ATTR *ap;
  const char *ptrs[BUFFER_LEN / 2];
  static char buff[BUFFER_LEN];
  char *bp;
  int nptrs = 0, i;

  ap = (ATTR *) ptab_firstentry(&ptab_attrib);
  ptrs[0] = "";
  while (ap) {
    ptrs[nptrs++] = AL_NAME(ap);
    ap = (ATTR *) ptab_nextentry(&ptab_attrib);
  }
  bp = buff;
  safe_str(ptrs[0], buff, &bp);
  for (i = 1; i < nptrs; i++) {
    safe_chr(' ', buff, &bp);
    safe_str(ptrs[i], buff, &bp);
  }
  *bp = '\0';
  return buff;
}
Beispiel #21
0
void display_powertab(dbref player)
{
    char *buf, *bp;
    POWERENT *fp;
    bp = buf = alloc_lbuf("display_powertab");
    safe_str((char *) "Powers:", buf, &bp);

    for (fp = gen_powers; fp->powername; fp++) {
	if ((fp->listperm & CA_WIZARD) && !Wizard(player)) {
	    continue;
	}

	if ((fp->listperm & CA_GOD) && !God(player)) {
	    continue;
	}

	safe_chr(' ', buf, &bp);
	safe_str((char *) fp->powername, buf, &bp);
    }

    *bp = '\0';
    notify(player, buf);
    free_lbuf(buf);
}
Beispiel #22
0
static void give_thing (dbref giver, dbref recipient, int key, char *what)
{
dbref	thing, loc;
char	*str, *sp;

	init_match(giver, what, TYPE_THING);
	match_possession();
	match_me();
	thing = match_result();

	switch (thing) {
	case NOTHING:
		notify(giver, "You don't have that!");
		return;
	case AMBIGUOUS:
		notify(giver, "I don't know which you mean!");
		return;
	}

	if (thing == giver) {
		notify(giver, "You can't give yourself away!");
		return;
	}

	if (((Typeof(thing) != TYPE_THING) &&
	     (Typeof(thing) != TYPE_PLAYER)) ||
	    !(Enter_ok(recipient) || controls(giver, recipient))) {
		notify(giver, "Permission denied.");
		return;
	}
	if ((Flags3(thing) & NOMOVE) && !Wizard(giver)) {
		notify(giver, "Permission denied.");
		return;
	}

	if (!could_doit(giver, thing, A_LGIVE,1)) {
		sp = str = alloc_lbuf("do_give.gfail");
		safe_str((char *)"You can't give ", str, &sp);
		safe_str(Name(thing), str, &sp);
		safe_str((char *)" away.", str, &sp);
		*sp = '\0';

		did_it(giver, thing, A_GFAIL, str, A_OGFAIL, NULL,
			A_AGFAIL, (char **)NULL, 0);
		free_lbuf(str);
		return;
	}
	if (!could_doit(thing, recipient, A_LRECEIVE,1)) {
		sp = str = alloc_lbuf("do_give.rfail");
		safe_str(Name(recipient), str, &sp);
		safe_str((char *)" doesn't want ", str, &sp);
		safe_str(Name(thing), str, &sp);
		safe_chr('.', str, &sp);
		*sp = '\0';

		did_it(giver, recipient, A_RFAIL, str, A_ORFAIL, NULL,
			A_ARFAIL, (char **)NULL, 0);
		free_lbuf(str);
		return;
	}
	loc = Location(giver);
	if ( !Good_obj(loc) || loc == NOTHING || loc == AMBIGUOUS || Recover(loc) || Going(loc) )
           loc = giver;
	if (!could_doit(giver, loc, A_LGIVETO, 1)) {
		sp = str = alloc_lbuf("do_giveto.rfail");
		safe_str((char *)"You can not give ", str, &sp);
		safe_str(Name(thing), str, &sp);
		safe_str((char *)" away at this location.", str, &sp);
		*sp = '\0';
		notify(giver, str);
		free_lbuf(str);
		return;
	}

	move_via_generic(thing, recipient, giver, 0);
	divest_object(thing);
	
	if (!(key & GIVE_QUIET)) {
		str = alloc_lbuf("do_give.thing.ok");
		strcpy(str, Name(giver));
		notify_with_cause(recipient, giver,
			unsafe_tprintf("%s gave you %s.", str, Name(thing)));
		notify(giver, "Given.");
		notify_with_cause(thing, giver,
			unsafe_tprintf("%s gave you to %s.", str, Name(recipient)));
		free_lbuf(str);
	}
	else {
		notify(giver, "Given. (quiet)");
	}
	did_it(giver, thing, A_DROP, NULL, A_ODROP, NULL, A_ADROP,
		(char **)NULL, 0);
	did_it(recipient, thing, A_SUCC, NULL, A_OSUCC, NULL, A_ASUCC,
		(char **)NULL, 0);
}
Beispiel #23
0
static void unparse_boolexp1( dbref player, BOOLEXP *b, char outer_type, int format ) {
    ATTR *ap;

    char sep_ch;

    char *buff;

    if( b == TRUE_BOOLEXP ) {
        if( format == F_EXAMINE ) {
            safe_str( ( char * ) "*UNLOCKED*", boolexp_buf, &buftop );
        }
        return;
    }
    switch( b->type ) {
    case BOOLEXP_AND:
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( AND_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_OR:
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( OR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_NOT:
        safe_chr( '!', boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_INDIR:
        safe_chr( INDIR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_IS:
        safe_chr( IS_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CARRY:
        safe_chr( CARRY_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_OWNER:
        safe_chr( OWNER_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CONST:
        if( !mudstate.standalone ) {
            switch( format ) {
            case F_QUIET:

                /*
                 * Quiet output - for dumps and internal use.
                 * Always #Num
                 */

                safe_str( ( char * ) unparse_object_quiet( player,
                          b->thing ), boolexp_buf, &buftop );
                break;
            case F_EXAMINE:

                /*
                 * Examine output - informative. *
                 * Name(#Num) or Name
                 */

                buff = unparse_object( player, b->thing, 0 );
                safe_str( buff, boolexp_buf, &buftop );
                free_lbuf( buff );
                break;
            case F_DECOMPILE:

                /*
                 * Decompile output - should be usable on
                 * other MUSHes. *Name if player, Name if
                 * thing, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                case TYPE_THING:
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
                break;
            case F_FUNCTION:

                /*
                 * Function output - must be usable by @lock
                 * cmd.  *Name if player, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
            }
        } else {
            safe_str( ( char * ) unparse_object_quiet( player,
                      b->thing ), boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_ATR:
    case BOOLEXP_EVAL:
        if( b->type == BOOLEXP_EVAL ) {
            sep_ch = '/';
        } else {
            sep_ch = ':';
        }
        ap = atr_num( b->thing );
        if( ap && ap->number ) {
            safe_str( ( char * ) ap->name, boolexp_buf, &buftop );
        } else {
            safe_ltos( boolexp_buf, &buftop, b->thing );
        }
        safe_chr( sep_ch, boolexp_buf, &buftop );
        safe_str( ( char * ) b->sub1, boolexp_buf, &buftop );
        break;
    default:
        log_write_raw( 1, "ABORT! unparse.c, bad boolexp type in unparse_boolexp1().\n" );
        abort();
        break;
    }
}
Beispiel #24
0
/** Populate a ufun_attrib struct from an obj/attr pair.
 * \verbatim Given an attribute [<object>/]<name> pair (which may include #lambda),
 * fetch its value, owner (thing), and pe_flags, and store in the struct
 * pointed to by ufun
 * \endverbatim
 * \param attrstring The obj/name of attribute.
 * \param executor Dbref of the executing object.
 * \param ufun Pointer to an allocated ufun_attrib struct to fill in.
 * \param flags A bitwise or of desired UFUN_* flags.
 * \return 0 on failure, true on success.
 */
bool
fetch_ufun_attrib(const char *attrstring, dbref executor, ufun_attrib * ufun,
                  int flags)
{
  char *thingname, *attrname;
  char astring[BUFFER_LEN];
  ATTR *attrib;

  if (!ufun)
    return 0;

  ufun->contents[0] = '\0';
  ufun->errmess = (char *) "";
  ufun->thing = executor;
  ufun->pe_flags = PE_UDEFAULT;
  ufun->ufun_flags = flags;

  ufun->thing = executor;
  thingname = NULL;

  if (!attrstring)
    return 0;
  strncpy(astring, attrstring, BUFFER_LEN);

  /* Split obj/attr */
  if ((flags & UFUN_OBJECT) && ((attrname = strchr(astring, '/')) != NULL)) {
    thingname = astring;
    *(attrname++) = '\0';
  } else {
    attrname = astring;
  }

  if (thingname && (flags & UFUN_LAMBDA)
      && (strcasecmp(thingname, "#lambda") == 0
          || strncasecmp(thingname, "#apply", 6) == 0)) {
    /* It's a lambda. */

    ufun->ufun_flags &= ~UFUN_NAME;
    ufun->thing = executor;
    if (strcasecmp(thingname, "#lambda") == 0)
      mush_strncpy(ufun->contents, attrname, BUFFER_LEN);
    else {                      /* #apply */
      char *ucb = ufun->contents;
      unsigned nargs = 1, n;

      thingname += 6;

      if (*thingname)
        nargs = parse_uinteger(thingname);

      /* Limit between 1 and 10 arguments (%0-%9) */
      if (nargs == 0)
        nargs = 1;
      if (nargs > 10)
        nargs = 10;

      safe_str(attrname, ufun->contents, &ucb);
      safe_chr('(', ufun->contents, &ucb);
      for (n = 0; n < nargs; n++) {
        if (n > 0)
          safe_chr(',', ufun->contents, &ucb);
        safe_format(ufun->contents, &ucb, "%%%u", n);
      }
      safe_chr(')', ufun->contents, &ucb);
      *ucb = '\0';
    }

    ufun->attrname[0] = '\0';
    return 1;
  }

  if (thingname) {
    /* Attribute is on something else. */
    ufun->thing =
      noisy_match_result(executor, thingname, NOTYPE, MAT_EVERYTHING);
    if (!GoodObject(ufun->thing)) {
      ufun->errmess = (char *) "#-1 INVALID OBJECT";
      return 0;
    }
  }

  attrib = (ATTR *) atr_get(ufun->thing, upcasestr(attrname));
  if (attrib && AF_Internal(attrib)) {
    /* Regardless of whether we're doing permission checks, we should
     * never be showing internal attributes here */
    attrib = NULL;
  }

  /* An empty attrib is the same as no attrib. */
  if (attrib == NULL) {
    if (flags & UFUN_REQUIRE_ATTR) {
      if (!(flags & UFUN_IGNORE_PERMS) && !Can_Examine(executor, ufun->thing))
        ufun->errmess = e_atrperm;
      return 0;
    } else {
      mush_strncpy(ufun->attrname, attrname, ATTRIBUTE_NAME_LIMIT + 1);
      return 1;
    }
  }
  if (!(flags & UFUN_IGNORE_PERMS)
      && !Can_Read_Attr(executor, ufun->thing, attrib)) {
    ufun->errmess = e_atrperm;
    return 0;
  }
  if (!(flags & UFUN_IGNORE_PERMS)
      && !CanEvalAttr(executor, ufun->thing, attrib)) {
    ufun->errmess = e_perm;
    return 0;
  }

  /* DEBUG attributes */
  if (AF_NoDebug(attrib))
    ufun->pe_flags |= PE_NODEBUG;       /* No_Debug overrides Debug */
  else if (AF_Debug(attrib))
    ufun->pe_flags |= PE_DEBUG;

  if (flags & UFUN_NAME) {
    if (attrib->flags & AF_NONAME)
      ufun->ufun_flags &= ~UFUN_NAME;
    else if (attrib->flags & AF_NOSPACE)
      ufun->ufun_flags |= UFUN_NAME_NOSPACE;
  }

  /* Populate the ufun object */
  mush_strncpy(ufun->contents, atr_value(attrib), BUFFER_LEN);
  mush_strncpy(ufun->attrname, AL_NAME(attrib), ATTRIBUTE_NAME_LIMIT + 1);

  /* We're good */
  return 1;
}
Beispiel #25
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;
}
Beispiel #26
0
/*
 * ---------------------------------------------------------------------------
 * * Return an lbuf pointing to the object name and possibly the db# and flags
 */
UTF8 *unparse_object(dbref player, dbref target, bool obey_myopic, bool bAddColor)
{
    UTF8 *buf = alloc_lbuf("unparse_object");
    if (NOPERM <= target && target < 0)
    {
        mux_strncpy(buf, aszSpecialDBRefNames[-target], LBUF_SIZE-1);
    }
    else if (!Good_obj(target))
    {
        mux_sprintf(buf, LBUF_SIZE, T("*ILLEGAL*(#%d)"), target);
    }
    else
    {
        bool exam;
        if (obey_myopic)
        {
            exam = MyopicExam(player, target);
        }
        else
        {
            exam = Examinable(player, target);
        }

        // Leave and extra 100 bytes for the dbref and flags at the end and
        // color at the beginning if necessary..
        //
        mux_field fldName = StripTabsAndTruncate( Moniker(target), buf,
                                                  LBUF_SIZE-100, LBUF_SIZE-100);
        UTF8 *bp = buf + fldName.m_byte;

#if defined(FIRANMUX)
        if (  fldName.m_column == fldName.m_byte
           && bAddColor)
        {
            // There is no color in the name, so look for @color, or highlight.
            //
            UTF8 *buf2 = alloc_lbuf("unparse_object.color");
            UTF8 *bp2  = buf2;

            UTF8 *pLetters = AcquireColorLetters(player, target);
            if (NULL != pLetters)
            {
                safe_str(LettersToBinary(pLetters), buf2, &bp2);
                free_lbuf(pLetters);
                pLetters = NULL;
            }
            else
            {
                safe_str((UTF8 *)COLOR_INTENSE, buf2, &bp2);
            }

            *bp = '\0';
            safe_str(buf, buf2, &bp2);
            safe_str((UTF8 *)COLOR_RESET, buf2, &bp2);

            // Swap buffers.
            //
            free_lbuf(buf);
            buf = buf2;
            bp  = bp2;
        }
#else
        UNUSED_PARAMETER(bAddColor);
#endif // FIRANMUX

        if (  exam
           || (Flags(target) & (CHOWN_OK | JUMP_OK | LINK_OK | DESTROY_OK))
           || (Flags2(target) & ABODE))
        {
            // Show everything.
            //
            UTF8 *fp = decode_flags(player, &(db[target].fs));

            safe_str(T("(#"), buf, &bp);
            safe_ltoa(target, buf, &bp);
            safe_str(fp, buf, &bp);
            safe_chr(')', buf, &bp);

            free_sbuf(fp);
        }
        *bp = '\0';
    }
    return buf;
}
Beispiel #27
0
void exec(char *buff, char **bufc, int tflags, dbref player, dbref cause,
		  int eval, char **dstr, char *cargs[], int ncargs)
{
#define	NFARGS	30
	char *fargs[NFARGS];
	char *preserve[MAX_GLOBAL_REGS];
	char *tstr, *tbuf, *tbufc, *savepos, *atr_gotten, *start, *oldp, *savestr;
	char savec, ch, *str;
	char *realbuff = NULL, *realbp = NULL;
	dbref aowner;
	int at_space, nfargs, gender, i, j, alldone, feval; long aflags;
	int is_trace, is_top, save_count;
	int ansi;
	FUN *fp;
	UFUN *ufp;

	static const char *subj[5] = { "", "it", "she", "he", "they" };
	static const char *poss[5] = { "", "its", "her", "his", "their" };
	static const char *obj[5] = { "", "it", "her", "him", "them" };
	static const char *absp[5] = { "", "its", "hers", "his", "theirs" };

	if(*dstr == NULL)
		return;

	// dprintk("%d/%s", player, *dstr);

	at_space = 1;
	gender = -1;
	alldone = 0;
	ansi = 0;

	is_trace = Trace(player) && !(eval & EV_NOTRACE);
	is_top = 0;

	/* Extend the buffer if we need to. */

	if(((*bufc) - buff) > (LBUF_SIZE - SBUF_SIZE)) {
		realbuff = buff;
		realbp = *bufc;
		buff = (char *) malloc(LBUF_SIZE);
		*bufc = buff;
	}

	oldp = start = *bufc;

	/*
	 * If we are tracing, save a copy of the starting buffer 
	 */

	savestr = NULL;
	if(is_trace) {
		is_top = tcache_empty();
		savestr = alloc_lbuf("exec.save");
		StringCopy(savestr, *dstr);
	}
	while (**dstr && !alldone) {
		switch (**dstr) {
		case ' ':
			/*
			 * A space.  Add a space if not compressing or if * * 
			 * 
			 * *  * * previous char was not a space 
			 */

			if(!(mudconf.space_compress && at_space) ||
			   (eval & EV_NO_COMPRESS)) {
				safe_chr(' ', buff, bufc);
				at_space = 1;
			}
			break;
		case '\\':
			/*
			 * General escape.  Add the following char without *
			 * * * * special processing 
			 */

			at_space = 0;
			(*dstr)++;
			if(**dstr)
				safe_chr(**dstr, buff, bufc);
			else
				(*dstr)--;
			break;
		case '[':
			/*
			 * Function start.  Evaluate the contents of the * *
			 * * * square brackets as a function.  If no closing
			 * * * * * bracket, insert the [ and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			if(eval & EV_NOFCHECK) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
				break;
			}
			tbuf = parse_to(dstr, ']', 0);
			if(*dstr == NULL) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
			} else {
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval | EV_FCHECK | EV_FMAND), &str, cargs, ncargs);
				(*dstr)--;
			}
			break;
		case '{':
			/*
			 * Literal start.  Insert everything up to the * * *
			 * * terminating } without parsing.  If no closing *
			 * * * * brace, insert the { and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			tbuf = parse_to(dstr, '}', 0);
			if(*dstr == NULL) {
				safe_chr('{', buff, bufc);
				*dstr = tstr;
			} else {
				if(!(eval & EV_STRIP)) {
					safe_chr('{', buff, bufc);
				}
				/*
				 * Preserve leading spaces (Felan) 
				 */

				if(*tbuf == ' ') {
					safe_chr(' ', buff, bufc);
					tbuf++;
				}
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval & ~(EV_STRIP | EV_FCHECK)), &str, cargs, ncargs);
				if(!(eval & EV_STRIP)) {
					safe_chr('}', buff, bufc);
				}
				(*dstr)--;
			}
			break;
		case '%':
			/*
			 * Percent-replace start.  Evaluate the chars * * *
			 * following * and perform the appropriate * * *
			 * substitution. 
			 */

			at_space = 0;
			(*dstr)++;
			savec = **dstr;
			savepos = *bufc;
			switch (savec) {
			case '\0':			/*
								 * Null - all done 
								 */
				(*dstr)--;
				break;
			case '|':			/* piped command output */
				safe_str(mudstate.pout, buff, bufc);
				break;
			case '%':			/*
								 * Percent - a literal % 
								 */
				safe_chr('%', buff, bufc);
				break;
			case 'c':
			case 'C':
				(*dstr)++;
				if(!**dstr)
					(*dstr)--;
				ansi = 1;
				switch (**dstr) {
				case 'h':		/*
								 * hilite 
								 */
					safe_str(ANSI_HILITE, buff, bufc);
					break;
				case 'i':		/*
								 * inverse 
								 */
					safe_str(ANSI_INVERSE, buff, bufc);
					break;
				case 'f':		/*
								 * flash 
								 */
					safe_str(ANSI_BLINK, buff, bufc);
					break;
				case 'u':		/* underline */
					safe_str(ANSI_UNDER, buff, bufc);
					break;
				case 'n':		/*
								 * normal 
								 */
					safe_str(ANSI_NORMAL, buff, bufc);
					ansi = 0;
					break;
				case 'x':		/*
								 * black fg 
								 */
					safe_str(ANSI_BLACK, buff, bufc);
					break;
				case 'r':		/*
								 * red fg 
								 */
					safe_str(ANSI_RED, buff, bufc);
					break;
				case 'g':		/*
								 * green fg 
								 */
					safe_str(ANSI_GREEN, buff, bufc);
					break;
				case 'y':		/*
								 * yellow fg 
								 */
					safe_str(ANSI_YELLOW, buff, bufc);
					break;
				case 'b':		/*
								 * blue fg 
								 */
					safe_str(ANSI_BLUE, buff, bufc);
					break;
				case 'm':		/*
								 * magenta fg 
								 */
					safe_str(ANSI_MAGENTA, buff, bufc);
					break;
				case 'c':		/*
								 * cyan fg 
								 */
					safe_str(ANSI_CYAN, buff, bufc);
					break;
				case 'w':		/*
								 * white fg 
								 */
					safe_str(ANSI_WHITE, buff, bufc);
					break;
				case 'X':		/*
								 * black bg 
								 */
					safe_str(ANSI_BBLACK, buff, bufc);
					break;
				case 'R':		/*
								 * red bg 
								 */
					safe_str(ANSI_BRED, buff, bufc);
					break;
				case 'G':		/*
								 * green bg 
								 */
					safe_str(ANSI_BGREEN, buff, bufc);
					break;
				case 'Y':		/*
								 * yellow bg 
								 */
					safe_str(ANSI_BYELLOW, buff, bufc);
					break;
				case 'B':		/*
								 * blue bg 
								 */
					safe_str(ANSI_BBLUE, buff, bufc);
					break;
				case 'M':		/*
								 * magenta bg 
								 */
					safe_str(ANSI_BMAGENTA, buff, bufc);
					break;
				case 'C':		/*
								 * cyan bg 
								 */
					safe_str(ANSI_BCYAN, buff, bufc);
					break;
				case 'W':		/*
								 * white bg 
								 */
					safe_str(ANSI_BWHITE, buff, bufc);
					break;
				default:
					safe_chr(**dstr, buff, bufc);
				}
				break;
			case 'r':			/*
								 * Carriage return 
								 */
			case 'R':
				safe_str((char *) "\r\n", buff, bufc);
				break;
			case 't':			/*
								 * Tab 
								 */
			case 'T':
				safe_chr('\t', buff, bufc);
				break;
			case 'B':			/*
								 * Blank 
								 */
			case 'b':
				safe_chr(' ', buff, bufc);
				break;
			case '0':			/*
								 * Command argument number N 
								 */
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				i = (**dstr - '0');
				if((i < ncargs) && (cargs[i] != NULL))
					safe_str(cargs[i], buff, bufc);
				break;
			case 'V':			/*
								 * Variable attribute 
								 */
			case 'v':
				(*dstr)++;
				ch = ToUpper(**dstr);
				if(!**dstr)
					(*dstr)--;
				if((ch < 'A') || (ch > 'Z'))
					break;
				i = 100 + ch - 'A';
				atr_gotten = atr_pget(player, i, &aowner, &aflags);
				safe_str(atr_gotten, buff, bufc);
				free_lbuf(atr_gotten);
				break;
			case 'Q':
			case 'q':
				(*dstr)++;
				i = (**dstr - '0');
				if((i >= 0) && (i <= 9) && mudstate.global_regs[i]) {
					safe_str(mudstate.global_regs[i], buff, bufc);
				}
				if(!**dstr)
					(*dstr)--;
				break;
			case 'O':			/*
								 * Objective pronoun 
								 */
			case 'o':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) obj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'P':			/*
								 * Personal pronoun 
								 */
			case 'p':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) poss[gender], buff, bufc);
				}
				break;
			case 'S':			/*
								 * Subjective pronoun 
								 */
			case 's':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) subj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'A':			/*
								 * Absolute posessive 
								 */
			case 'a':			/*
								 * idea from Empedocles 
								 */
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) absp[gender], buff, bufc);
				}
				break;
			case '#':			/*
								 * Invoker DB number 
								 */
				tbuf = alloc_sbuf("exec.invoker");
				sprintf(tbuf, "#%ld", cause);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case '!':			/*
								 * Executor DB number 
								 */
				tbuf = alloc_sbuf("exec.executor");
				sprintf(tbuf, "#%ld", player);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case 'N':			/*
								 * Invoker name 
								 */
			case 'n':
				safe_str(Name(cause), buff, bufc);
				break;
			case 'L':			/*
								 * Invoker location db# 
								 */
			case 'l':
				if(!(eval & EV_NO_LOCATION)) {
					tbuf = alloc_sbuf("exec.exloc");
					sprintf(tbuf, "#%ld", where_is(cause));
					safe_str(tbuf, buff, bufc);
					free_sbuf(tbuf);
				}

				break;
			default:			/*
								 * Just copy 
								 */
				safe_chr(**dstr, buff, bufc);
			}
			if(isupper(savec))
				*savepos = ToUpper(*savepos);
			break;
		case '(':
			/*
			 * Arglist start.  See if what precedes is a function. If so,
			 * execute it if we should.
			 */

			at_space = 0;
			if(!(eval & EV_FCHECK)) {
				safe_chr('(', buff, bufc);
				break;
			}
			/*
			 * Load an sbuf with an uppercase version of the func name, and
			 * see if the func exists.  Trim trailing spaces from the name
			 * if configured.
			 */

			**bufc = '\0';
			tbufc = tbuf = alloc_sbuf("exec.tbuf");
			safe_sb_str(oldp, tbuf, &tbufc);
			*tbufc = '\0';
			if(mudconf.space_compress) {
				while ((--tbufc >= tbuf) && isspace(*tbufc));
				tbufc++;
				*tbufc = '\0';
			}
			for(tbufc = tbuf; *tbufc; tbufc++)
				*tbufc = ToLower(*tbufc);
			fp = (FUN *) hashfind(tbuf, &mudstate.func_htab);

			/*
			 * If not a builtin func, check for global func 
			 */

			ufp = NULL;
			if(fp == NULL) {
				ufp = (UFUN *) hashfind(tbuf, &mudstate.ufunc_htab);
			}
			/*
			 * Do the right thing if it doesn't exist 
			 */

			if(!fp && !ufp) {
				if(eval & EV_FMAND) {
					*bufc = oldp;
					safe_str((char *) "#-1 FUNCTION (", buff, bufc);
					safe_str(tbuf, buff, bufc);
					safe_str((char *) ") NOT FOUND", buff, bufc);
					alldone = 1;
				} else {
					safe_chr('(', buff, bufc);
				}
				free_sbuf(tbuf);
				eval &= ~EV_FCHECK;
				break;
			}
			free_sbuf(tbuf);

			/*
			 * Get the arglist and count the number of args * Neg 
			 * 
			 * *  * *  * * # of args means catenate subsequent
			 * args 
			 */

			if(ufp)
				nfargs = NFARGS;
			else if(fp->nargs < 0)
				nfargs = -fp->nargs;
			else
				nfargs = NFARGS;
			tstr = *dstr;
			if(fp && (fp->flags & FN_NO_EVAL))
				feval = (eval & ~EV_EVAL) | EV_STRIP_ESC;
			else
				feval = eval;
			*dstr =
				parse_arglist(player, cause, *dstr + 1, ')', feval, fargs,
							  nfargs, cargs, ncargs);

			/*
			 * If no closing delim, just insert the '(' and * * * 
			 * 
			 * * continue normally 
			 */

			if(!*dstr) {
				*dstr = tstr;
				safe_chr(**dstr, buff, bufc);
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * Count number of args returned 
			 */

			(*dstr)--;
			j = 0;
			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					j = i + 1;
			nfargs = j;

			/*
			 * If it's a user-defined function, perform it now. 
			 */

			if(ufp) {
				mudstate.func_nest_lev++;
				if(!check_access(player, ufp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else {
					tstr = atr_get(ufp->obj, ufp->atr, &aowner, &aflags);
					if(ufp->flags & FN_PRIV)
						i = ufp->obj;
					else
						i = player;
					str = tstr;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(!mudstate.global_regs[j])
								preserve[j] = NULL;
							else {
								preserve[j] = alloc_lbuf("eval_regs");
								StringCopy(preserve[j],
										   mudstate.global_regs[j]);
							}
						}
					}

					exec(buff, &oldp, 0, i, cause, feval, &str, fargs,
						 nfargs);
					*bufc = oldp;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(preserve[j]) {
								if(!mudstate.global_regs[j])
									mudstate.global_regs[j] =
										alloc_lbuf("eval_regs");
								StringCopy(mudstate.global_regs[j],
										   preserve[j]);
								free_lbuf(preserve[j]);
							} else {
								if(mudstate.global_regs[j])
									*(mudstate.global_regs[i]) = '\0';
							}
						}
					}

					free_lbuf(tstr);
				}

				/*
				 * Return the space allocated for the args 
				 */

				mudstate.func_nest_lev--;
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * If the number of args is right, perform the func.
			 * Otherwise return an error message.  Note
			 * that parse_arglist returns zero args as one
			 * null arg, so we have to handle that case
			 * specially. 
			 */

			if((fp->nargs == 0) && (nfargs == 1)) {
				if(!*fargs[0]) {
					free_lbuf(fargs[0]);
					fargs[0] = NULL;
					nfargs = 0;
				}
			}
			if((nfargs == fp->nargs) || (nfargs == -fp->nargs) ||
			   (fp->flags & FN_VARARGS)) {

				/*
				 * Check recursion limit 
				 */

				mudstate.func_nest_lev++;
				mudstate.func_invk_ctr++;
				if(mudstate.func_nest_lev >= mudconf.func_nest_lim) {
					safe_str("#-1 FUNCTION RECURSION LIMIT EXCEEDED", buff,
							 bufc);
				} else if(mudstate.func_invk_ctr == mudconf.func_invk_lim) {
					safe_str("#-1 FUNCTION INVOCATION LIMIT EXCEEDED",
							 buff, bufc);
				} else if(!check_access(player, fp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else if(mudstate.func_invk_ctr < mudconf.func_invk_lim) {
					fp->fun(buff, &oldp, player, cause, fargs, nfargs,
							cargs, ncargs);
					*bufc = oldp;
				} else {
					**bufc = '\0';
				}
				mudstate.func_nest_lev--;
			} else {
				*bufc = oldp;
				tstr = alloc_sbuf("exec.funcargs");
				sprintf(tstr, "%d", fp->nargs);
				safe_str((char *) "#-1 FUNCTION (", buff, bufc);
				safe_str((char *) fp->name, buff, bufc);
				safe_str((char *) ") EXPECTS ", buff, bufc);
				safe_str(tstr, buff, bufc);
				safe_str((char *) " ARGUMENTS", buff, bufc);
				free_sbuf(tstr);
			}

			/*
			 * Return the space allocated for the arguments 
			 */

			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					free_lbuf(fargs[i]);
			eval &= ~EV_FCHECK;
			break;
		default:
			/*
			 * A mundane character.  Just copy it 
			 */

			at_space = 0;
			safe_chr(**dstr, buff, bufc);
		}
		(*dstr)++;
	}

	/*
	 * If we're eating spaces, and the last thing was a space, eat it
	 * up. Complicated by the fact that at_space is initially
	 * true. So check to see if we actually put something in the
	 * buffer, too. 
	 */

	if(mudconf.space_compress && at_space && !(eval & EV_NO_COMPRESS)
	   && (start != *bufc))
		(*bufc)--;

	/*
	 * The ansi() function knows how to take care of itself. However, 
	 * if the player used a %c sub in the string, and hasn't yet
	 * terminated the color with a %cn yet, we'll have to do it for 
	 * them. 
	 */

	if(ansi == 1)
		safe_str(ANSI_NORMAL, buff, bufc);

	**bufc = '\0';

	/*
	 * Report trace information 
	 */

	if(realbuff) {
		**bufc = '\0';
		*bufc = realbp;
		safe_str(buff, realbuff, bufc);
		free(buff);
		buff = realbuff;
	}

	if(is_trace) {
		tcache_add(savestr, start);
		save_count = tcache_count - mudconf.trace_limit;;
		if(is_top || !mudconf.trace_topdown)
			tcache_finish(player);
		if(is_top && (save_count > 0)) {
			tbuf = alloc_mbuf("exec.trace_diag");
			sprintf(tbuf, "%d lines of trace output discarded.", save_count);
			notify(player, tbuf);
			free_mbuf(tbuf);
		}
	}
}
Beispiel #28
0
/** The whisper command.
 * \param player the enactor.
 * \param arg1 name of the object to whisper to.
 * \param arg2 message to whisper.
 * \param noisy if 1, others overhear that a whisper has occurred.
 * \param pe_info the pe_info for evaluating interact locks
 */
void
do_whisper(dbref player, const char *arg1, const char *arg2, int noisy,
           NEW_PE_INFO *pe_info)
{
  dbref who;
  int key;
  const char *gap;
  char *tbuf, *tp;
  char *p;
  dbref good[100];
  int gcount = 0;
  const char *head;
  int overheard;
  char *current;
  const char **start;
  char sname[BUFFER_LEN];

  if (!arg1 || !*arg1) {
    notify(player, T("Whisper to whom?"));
    return;
  }
  if (!arg2 || !*arg2) {
    notify(player, T("Whisper what?"));
    return;
  }
  tp = tbuf = (char *) mush_malloc(BUFFER_LEN, "string");
  if (!tbuf)
    mush_panic("Unable to allocate memory in do_whisper");

  overheard = 0;
  head = arg1;
  start = &head;
  /* Figure out what kind of message */
  gap = " ";
  switch (*arg2) {
  case SEMI_POSE_TOKEN:
    gap = "";
  case POSE_TOKEN:
    key = 1;
    arg2++;
    break;
  default:
    key = 2;
    break;
  }

  *tp = '\0';
  /* Make up a list of good and bad names */
  while (head && *head) {
    current = next_in_list(start);
    who = match_result(player, current, TYPE_PLAYER, MAT_NEAR_THINGS |
                       MAT_CONTAINER);
    if (!GoodObject(who) || !can_interact(player, who, INTERACT_HEAR, pe_info)) {
      safe_chr(' ', tbuf, &tp);
      safe_str_space(current, tbuf, &tp);
      if (GoodObject(who))
        notify_format(player, T("%s can't hear you."),
                      AName(who, AN_SYS, NULL));
    } else {
      /* A good whisper */
      good[gcount++] = who;
      if (gcount >= 100) {
        notify(player, T("Too many people to whisper to."));
        break;
      }
    }
  }

  *tp = '\0';
  if (*tbuf)
    notify_format(player, T("Unable to whisper to:%s"), tbuf);

  if (!gcount) {
    mush_free(tbuf, "string");
    return;
  }

  /* Drunk wizards... */
  if (Dark(player))
    noisy = 0;

  /* Set up list of good names */
  tp = tbuf;
  safe_str(T(" to "), tbuf, &tp);
  for (who = 0; who < gcount; who++) {
    if (noisy && (get_random32(0, 100) < (uint32_t) WHISPER_LOUDNESS))
      overheard = 1;
    safe_itemizer(who + 1, (who == gcount - 1), ",", T("and"), " ", tbuf, &tp);
    safe_str(AName(good[who], AN_SAY, NULL), tbuf, &tp);
  }
  *tp = '\0';

  if (key == 1) {
    notify_format(player, (gcount > 1) ? T("%s sense: %s%s%s") :
                  T("%s senses: %s%s%s"), tbuf + 4, AName(player, AN_SAY, NULL),
                  gap, arg2);
    p = tprintf("You sense: %s%s%s", AName(player, AN_SAY, NULL), gap, arg2);
  } else {
    notify_format(player, T("You whisper, \"%s\"%s."), arg2, tbuf);
    p = tprintf(T("%s whispers%s: %s"), AName(player, AN_SAY, NULL),
                gcount > 1 ? tbuf : "", arg2);
  }

  strcpy(sname, AName(player, AN_SAY, NULL));
  for (who = 0; who < gcount; who++) {
    notify_must_puppet(good[who], p);
    if (Location(good[who]) != Location(player))
      overheard = 0;
  }
  if (overheard) {
    dbref first = Contents(Location(player));
    if (!GoodObject(first))
      return;
    p = tprintf(T("%s whispers%s."), sname, tbuf);
    DOLIST(first, first) {
      overheard = 1;
      for (who = 0; who < gcount; who++) {
        if ((first == player) || (first == good[who])) {
          overheard = 0;
          break;
        }
      }
      if (overheard)
        notify_noecho(first, p);
    }
  }
Beispiel #29
0
void
reap_info_slave(void)
{
  struct response_dgram resp;
  ssize_t len;
  char hostname[BUFFER_LEN], *hp;
  int n, count;

  if (info_slave_state != INFO_SLAVE_PENDING) {
    if (info_slave_state == INFO_SLAVE_DOWN)
      make_info_slave();
    return;
  }

  len = recv(info_slave, &resp, sizeof resp, 0);
  if (len < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
    return;
  else if (len < 0 || len != (int) sizeof resp) {
    penn_perror("reading info_slave response");
    return;
  }

  /* okay, now we have some info! */
  if (!FD_ISSET(resp.fd, &info_pending)) {
    /* Duplicate or spoof. Ignore. */
    return;
  }

  FD_CLR(resp.fd, &info_pending);

  /* See if we have any other pending queries and change state if not. */
  for (n = 0, count = 0; n < pending_max; n++)
    if (FD_ISSET(n, &info_pending))
      count++;

  if (count == 0) {
    info_slave_state = INFO_SLAVE_READY;
    pending_max = 0;
  }

  hp = hostname;
  if (resp.ident[0]) {
    safe_str(resp.ident, hostname, &hp);
    safe_chr('@', hostname, &hp);
  }
  if (resp.hostname[0])
    safe_str(resp.hostname, hostname, &hp);
  else
    safe_str(resp.ipaddr, hostname, &hp);
  *hp = '\0';

  if (Forbidden_Site(resp.ipaddr) || Forbidden_Site(hostname)) {
    if (!Deny_Silent_Site(resp.ipaddr, AMBIGUOUS)
        || !Deny_Silent_Site(hostname, AMBIGUOUS)) {
      do_log(LT_CONN, 0, 0, "[%d/%s/%s] Refused connection.", resp.fd,
             hostname, resp.ipaddr);
    }
    shutdown(resp.fd, 2);
    closesocket(resp.fd);
    return;
  }

  do_log(LT_CONN, 0, 0, "[%d/%s/%s] Connection opened.", resp.fd,
         hostname, resp.ipaddr);
  set_keepalive(resp.fd);
  initializesock(resp.fd, hostname, resp.ipaddr,
                 (resp.connected_to == SSLPORT));
}
Beispiel #30
0
/** Is name a valid new name for thing, when set by player?
 * \verbatim
 * Parses names and aliases for players/exits, validating each. If everything is valid,
 * the new name and alias are set into newname and newalias, with memory malloc'd as necessary.
 * For things/rooms, no parsing is done, and ok_name is called on the entire string to validate.
 * For players and exits, if name takes the format <name>; then newname is set to <name> and
 * newalias to ";", to signify that the existing alias should be cleared. If name contains a name and
 * valid aliases, newname and newalias are set accordingly.
 * \endverbatim
 * \param name the new name to set
 * \param player the player setting the name, for permission checks
 * \param thing object getting the name, or NOTHING for new objects
 * \param type type of object getting the name (necessary for new exits)
 * \param newname pointer to place the new name, once validated
 * \param newalias pointer to place the alias in, if any
 * \retval OPAE_SUCCESS name and any given aliases are valid
 * \retval OPAE_INVALID invalid name or aliases
 * \retval OPAE_TOOMANY too many aliases for player
 */
enum opa_error
ok_object_name(char *name, dbref player, dbref thing, int type, char **newname,
               char **newalias)
{
  char *bon, *eon;
  char nbuff[BUFFER_LEN], abuff[BUFFER_LEN];
  char *ap = abuff;
  int aliases = 0;
  int empty = 0;

  strncpy(nbuff, name, BUFFER_LEN - 1);
  nbuff[BUFFER_LEN - 1] = '\0';
  memset(abuff, 0, BUFFER_LEN);

  /* First, check for a quoted player name */
  if (type == TYPE_PLAYER && *name == '"') {
    /* Quoted player name, no aliases allowed */
    bon = nbuff;
    bon++;
    eon = bon;
    while (*eon && *eon != '"')
      eon++;
    if (*eon)
      *eon = '\0';
    if (!ok_player_name(bon, player, thing))
      return OPAE_INVALID;
    *newname = mush_strdup(bon, "name.newname");
    return OPAE_SUCCESS;
  }

  if (type & (TYPE_THING | TYPE_ROOM)) {
    /* No aliases in the name */
    if (!ok_name(nbuff, 0))
      return OPAE_INVALID;
    *newname = mush_strdup(nbuff, "name.newname");
    return OPAE_SUCCESS;
  }

  /* A player or exit name, with aliases allowed.
   * Possible things to parse:
   * <name>  - just a new name
   * <name>; - new name with trailing ; to clear alias
   * <name>;<alias1>[;<aliasN>] - name with one or more aliases, separated by ;
   */

  /* Validate name first */
  bon = nbuff;
  if ((eon = strchr(bon, ALIAS_DELIMITER))) {
    *eon++ = '\0';
    aliases++;
  }
  if (!
      (type ==
       TYPE_PLAYER ? ok_player_name(bon, player, thing) : ok_name(bon, 1)))
    return OPAE_INVALID;

  *newname = mush_strdup(bon, "name.newname");

  if (aliases) {
    /* We had aliases, so parse them */
    while (eon) {
      if (empty)
        return OPAE_NULL;       /* Null alias only valid as a single, final alias */
      bon = eon;
      if ((eon = strchr(bon, ALIAS_DELIMITER))) {
        *eon++ = '\0';
      }
      while (*bon && *bon == ' ')
        bon++;
      if (!*bon) {
        empty = 1;              /* empty alias, should only happen if we have no proper aliases */
        continue;
      }
      if (!
          (type ==
           TYPE_PLAYER ? ok_player_name(bon, player, thing) : ok_name(bon,
                                                                      1))) {
        *newalias = mush_strdup(bon, "name.newname");   /* So we can report the invalid alias */
        return OPAE_INVALID;
      }
      if (aliases > 1) {
        safe_chr(ALIAS_DELIMITER, abuff, &ap);
      }
      safe_str(bon, abuff, &ap);
      aliases++;
    }
  }
  *ap = '\0';

  if (aliases) {
    if (!Wizard(player) && type == TYPE_PLAYER && aliases > MAX_ALIASES)
      return OPAE_TOOMANY;
    if (*abuff) {
      /* We have actual aliases */
      *newalias = mush_strdup(abuff, "name.newname");
    } else {
      ap = abuff;
      safe_chr(ALIAS_DELIMITER, abuff, &ap);
      *ap = '\0';
      /* We just want to clear the existing alias */
      *newalias = mush_strdup(abuff, "name.newname");
    }
  }

  return OPAE_SUCCESS;
}