Exemple #1
0
/** Add new help command. This function is
 * the basis for the help_command directive in mush.cnf. It creates
 * a new help entry for the hash table, builds a help index,
 * and adds the new command to the command table.
 * \param command_name name of help command to add.
 * \param filename name of the help file to use for this command.
 * \param admin if 1, this command reads admin topics, rather than standard.
 */
void
add_help_file(const char *command_name, const char *filename, int admin)
{
  help_file *h;

  if (help_init == 0)
    init_help_files();

  if (!command_name || !filename || !*command_name || !*filename)
    return;

  /* If there's already an entry for it, complain */
  h = hashfind(strupper(command_name), &help_files);
  if (h) {
    do_rawlog(LT_ERR, "Duplicate help_command %s ignored.", command_name);
    return;
  }

  h = mush_malloc(sizeof *h, "help_file.entry");
  h->command = mush_strdup(strupper(command_name), "help_file.command");
  h->file = mush_strdup(filename, "help_file.filename");
  h->entries = 0;
  h->indx = NULL;
  h->admin = admin;
  help_build_index(h, h->admin);
  if (!h->indx) {
    mush_free(h->command, "help_file.command");
    mush_free(h->file, "help_file.filename");
    mush_free(h, "help_file.entry");
    return;
  }
  (void) command_add(h->command, CMD_T_ANY | CMD_T_NOPARSE, NULL, 0, NULL,
                     cmd_helpcmd);
  hashadd(h->command, h, &help_files);
}
Exemple #2
0
static void
end_log(struct log_stream *log, bool keep_buffer)
{
  FILE *fp;

  if (!log->filename || !*log->filename || !log->fp)
    return;
  if ((fp = hashfind(strupper(log->filename), &htab_logfiles))) {
    int n;

    lock_file(fp);
    fputs("END OF LOG.\n", fp);
    fflush(fp);
    for (n = 0; n < NLOGS; n++) {
      if (logs[n].fp == fp)
        logs[n].fp = NULL;
    }
    fclose(fp);                 /* Implicit lock removal */
    if (!keep_buffer) {
      free_bufferq(log->buffer);
      log->buffer = NULL;
    }
    hashdelete(strupper(log->filename), &htab_logfiles);
  }
}
Exemple #3
0
static void
start_log(struct log_stream *log)
{
  static int ht_initialized = 0;
  FILE *f;

  if (!log->filename || !*log->filename) {
    log->fp = stderr;
  } else {
    if (!ht_initialized) {
      hashinit(&htab_logfiles, 8);
      ht_initialized = 1;
    }
    if ((f = hashfind(strupper(log->filename), &htab_logfiles))) {
      /* We've already opened this file for another log, so just use that pointer */
      log->fp = f;
    } else {
      log->fp = fopen(log->filename, "a+");
      if (log->fp == NULL) {
        fprintf(stderr, "WARNING: cannot open log %s: %s\n", log->filename,
                strerror(errno));
        log->fp = stderr;
      } else {
        hashadd(strupper(log->filename), log->fp, &htab_logfiles);
        fputs("START OF LOG.\n", log->fp);
        fflush(log->fp);
      }
    }
  }
  if (!log->buffer)
    log->buffer = allocate_bufferq(LOG_BUFFER_SIZE);
}
Exemple #4
0
int HandledCommand_sub(dbref player, dbref location, char *command)
{
	XCODE *xcode_obj = NULL;

	struct SpecialObjectStruct *typeOfObject;
	int type;
	CommandsStruct *cmd;
	HASHTAB *damnedhash;
	char *tmpc, *tmpchar;
	int ishelp;

	type = WhichSpecial(location);
	if (type < 0 || (SpecialObjects[type].datasize > 0
	    && !(xcode_obj = rb_find(xcode_tree, (void *)location)))) {
		if(type >= 0 || !Hardcode(location) || Zombie(location))
			return 0;
		if((type = WhichSpecialS(location)) >= 0) {
			if(SpecialObjects[type].datasize > 0)
				return 0;
		} else
			return 0;
	}
#ifdef FAST_WHICHSPECIAL
	if(type > NUM_SPECIAL_OBJECTS)
		return 0;
#endif
	typeOfObject = &SpecialObjects[type];
	damnedhash = &SpecialCommandHash[type];
	tmpc = strstr(command, " ");
	if(tmpc)
		*tmpc = 0;
	ishelp = !strcmp(command, "HELP");
	for(tmpchar = command; *tmpchar; tmpchar++)
		*tmpchar = ToLower(*tmpchar);
	cmd = (CommandsStruct *) hashfind(command, &SpecialCommandHash[type]);
	if(tmpc)
		*tmpc = ' ';
	if(cmd && (type != GTYPE_MECH || (type == GTYPE_MECH &&
									  Can_Use_Command(((MECH *)
													   xcode_obj),
													  cmd->flag)))) {
#define SKIPSTUFF(a) while (*a && *a != ' ') a++;while (*a == ' ') a++
		if(cmd->helpmsg[0] != '@' ||
		   Have_MechPower(Owner(player), typeOfObject->power_needed)) {
			SKIPSTUFF(command);
			cmd->func(player, xcode_obj, command);
		} else
			notify(player, "Sorry, that command is restricted!");
		return 1;
	} else if(ishelp) {
		SKIPSTUFF(command);
		DoSpecialObjectHelp(player, typeOfObject->type, type, location,
							typeOfObject->power_needed, location, command);
		return 1;
	}
	return 0;
}
Exemple #5
0
/** Determine if a lock type is one of the standard types or not.
 * \param type type of lock to check.
 * \return canonical lock type or NULL
 */
lock_type
match_lock(lock_type type)
{
  lock_list *ll;
  ll = hashfind(strupper(type), &htab_locks);
  if (ll)
    return ll->type;
  else
    return NULL;
}
Exemple #6
0
FLAGENT *find_flag( dbref thing, char *flagname ) {
    char *cp;

    /*
     * Make sure the flag name is valid
     */

    for( cp = flagname; *cp; cp++ ) {
        *cp = toupper( *cp );
    }
    return ( FLAGENT * ) hashfind( flagname, &mudstate.flags_htab );
}
Exemple #7
0
/** Look up a player in the player list htab only.
 * \param name name of player to find.
 * \return dbref of player, or NOTHING.
 */
dbref
lookup_player_name(const char *name)
{
  dbref *p;
  if (hft_initialized) {
    p = hashfind(strupper(name), &htab_player_list);
    if (!p)
      return NOTHING;
    return *p;
  }
  return NOTHING;
}
Exemple #8
0
POWERENT *find_power(dbref thing, char *powername)
{
    char *cp;

    /*
     * Make sure the power name is valid
     */

    for (cp = powername; *cp; cp++) {
	*cp = tolower(*cp);
    }

    return (POWERENT *) hashfind(powername, &mudstate.powers_htab);
}
Exemple #9
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;
}
Exemple #10
0
int decode_power(dbref player, char *powername, POWERSET * pset)
{
    POWERENT *pent;
    pset->word1 = 0;
    pset->word2 = 0;
    pent = (POWERENT *) hashfind(powername, &mudstate.powers_htab);

    if (!pent) {
	notify_check(player, player, MSG_PUP_ALWAYS | MSG_ME_ALL | MSG_F_DOWN, "%s: Power not found.", powername);
	return 0;
    }

    if (pent->powerpower & POWER_EXT) {
	pset->word2 = pent->powervalue;
    } else {
	pset->word1 = pent->powervalue;
    }

    return 1;
}
Exemple #11
0
/** Add new help command. This function is
 * the basis for the help_command directive in mush.cnf. It creates
 * a new help entry for the hash table, builds a help index,
 * and adds the new command to the command table.
 * \param command_name name of help command to add.
 * \param filename name of the help file to use for this command.
 * \param admin if 1, this command reads admin topics, rather than standard.
 */
void
add_help_file(const char *command_name, const char *filename, int admin)
{
  help_file *h;
  char newfilename[256] = "\0";

  /* Must use a buffer for MacOS file path conversion */
  strncpy(newfilename, filename, 256);

  if (help_init == 0)
    init_help_files();

  if (!command_name || !filename || !*command_name || !*newfilename)
    return;

  /* If there's already an entry for it, complain */
  h = hashfind(strupper(command_name), &help_files);
  if (h) {
    do_rawlog(LT_ERR, T("Duplicate help_command %s ignored."), command_name);
    return;
  }

  h = mush_malloc(sizeof *h, "help_file.entry");
  h->command = mush_strdup(strupper(command_name), "help_file.command");
  h->file = mush_strdup(newfilename, "help_file.filename");
  h->entries = 0;
  h->indx = NULL;
  h->admin = admin;
  help_build_index(h, h->admin);
  if (!h->indx) {
    mush_free(h->command, "help_file.command");
    mush_free(h->file, "help_file.filename");
    mush_free(h, "help_file.entry");
    return;
  }
  (void) command_add(h->command, CMD_T_ANY | CMD_T_NOPARSE, NULL, cmd_helpcmd, NULL);
  hashadd(h->command, h, &help_files);
}
Exemple #12
0
void vattr_delete( char *name ) {
    VATTR *vp;

    int number;

    fixcase( name );
    if( !ok_attr_name( name ) ) {
        return;
    }

    number = 0;

    vp = ( VATTR * ) hashfind( name, &mudstate.vattr_name_htab );

    if( vp ) {
        number = vp->number;
        anum_set( number, NULL );
        hashdelete( name, &mudstate.vattr_name_htab );
        XFREE( vp, "vattr_delete" );
    }

    return;
}
Exemple #13
0
VATTR *vattr_rename( char *name, char *newname ) {
    VATTR *vp;

    fixcase( name );
    if( !ok_attr_name( name ) ) {
        return ( NULL );
    }

    /*
     * Be ruthless.
     */

    if( strlen( newname ) >= VNAME_SIZE ) {
        newname[VNAME_SIZE - 1] = '\0';
    }

    fixcase( newname );
    if( !ok_attr_name( newname ) ) {
        return ( NULL );
    }

    /*
     * We must explicitly delete and add the name to the hashtable,
     * * since we are changing the data.
     */

    vp = ( VATTR * ) hashfind( name, &mudstate.vattr_name_htab );

    if( vp ) {
        vp->name = store_string( newname );
        hashdelete( name, &mudstate.vattr_name_htab );
        hashadd( newname, ( int * ) vp, &mudstate.vattr_name_htab, 0 );
    }

    return ( vp );
}
Exemple #14
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);
		}
	}
}
Exemple #15
0
int cf_flag_name( int *vp, char *str, long extra, dbref player, char *cmd ) {
    char *numstr, *namestr, *tokst;

    FLAGENT *fp;

    int flagnum = -1;

    char *flagstr, *cp;

    numstr = strtok_r( str, " \t=,", &tokst );
    namestr = strtok_r( NULL, " \t=,", &tokst );

    if( numstr && ( strlen( numstr ) == 1 ) ) {
        flagnum = ( int ) strtol( numstr, ( char ** ) NULL, 10 );
    }
    if( ( flagnum < 0 ) || ( flagnum > 9 ) ) {
        cf_log_notfound( player, cmd, "Not a marker flag", numstr );
        return -1;
    }
    if( ( fp = letter_to_flag( *numstr ) ) == NULL ) {
        cf_log_notfound( player, cmd, "Marker flag", numstr );
        return -1;
    }
    /*
     * Our conditions: The flag name MUST start with an underscore. It
     * must not conflict with the name of any existing flag. There is a
     * KNOWN MEMORY LEAK here -- if you name the flag and rename it
     * later, the old bit of memory for the name won't get freed. This
     * should pretty much never happen, since you're not going to run
     * around arbitrarily giving your flags new names all the time.
     */

    flagstr = xstrprintf( "cf_flag_name", "_%s", namestr );
    if( strlen( flagstr ) > 31 ) {
        cf_log_syntax( player, cmd, "Marker flag name too long: %s",
                       namestr );
        XFREE( flagstr, "cf_flag_name" );
    }
    for( cp = flagstr; cp && *cp; cp++ ) {
        if( !isalnum( *cp ) && ( *cp != '_' ) ) {
            cf_log_syntax( player, cmd,
                           "Illegal marker flag name: %s", namestr );
            XFREE( flagstr, "cf_flag_name" );
            return -1;
        }
        *cp = tolower( *cp );
    }

    if( hashfind( flagstr, &mudstate.flags_htab ) ) {
        XFREE( flagstr, "cf_flag_name" );
        cf_log_syntax( player, cmd, "Marker flag name in use: %s",
                       namestr );
        return -1;
    }
    for( cp = flagstr; cp && *cp; cp++ ) {
        *cp = toupper( *cp );
    }

    fp->flagname = ( const char * ) flagstr;
    hashadd( ( char * ) fp->flagname, ( int * ) fp, &mudstate.flags_htab, 0 );

    return 0;
}
Exemple #16
0
VATTR *vattr_find( char *name ) {
    return ( VATTR * ) hashfind( name, &mudstate.vattr_name_htab );
}
Exemple #17
0
void process_data(Logfile *logfilep, Hashtable **hash,
		  Arraydata **arraydata, choice *count, choice *code2type,
		  choice datacols[ITEM_NUMBER][OUTCOME_NUMBER][DATACOLS_NUMBER][2],
		  choice data2cols[ITEM_NUMBER][DATA_NUMBER],
		  unsigned int *no_cols, Include **wanthead,
		  Include *ispagehead, Alias **aliashead, Include *argshead,
		  Include *refargshead, Dateman *dman, Tree **tree,
		  Derv **derv, choice *alltrees, choice *alldervs,
		  choice *lowmem, logical case_insensitive,
		  logical usercase_insensitive, unsigned char convfloor,
		  logical multibyte, char *dirsuffix,
		  unsigned int dirsufflength, unsigned int granularity) {
  extern unsigned int year, month, date, hour, minute, code;
  extern unsigned long unixtime, proctime;
  extern char am;
  extern double bytes;
  extern Memman mm[], mmq, mms, *amemman;
  extern choice *rep2type;
  extern Hashentry *unwanted_entry, *blank_entry;
  extern Hashindex *dummy_item;

  static Hashindex *gp[ITEM_NUMBER];
  unsigned long data[DATA2_NUMBER];
  Hashentry *item[ITEM_NUMBER];
  logical wanttree[ITEM_NUMBER];
  logical isitpage, last7;
  choice ispage = UNSET;
  choice wanted = TRUE, rc, outcome;
  timecode_t timecode = FIRST_TIME;
  char *name, *namestart, *nameend;
  size_t len;
  choice i, j, k;

  /*** check whether this line is wanted ***/

  if (count[INP_CODE] != 0) {
    if (code == IGNORE_CODE) {
      for (j = 0; j < ITEM_NUMBER; j++) {   /* reset strings */
	if (count[j] != 0)
	  mm[j].next_pos = mm[j].curr_pos;
      }
      mmq.next_pos = mmq.curr_pos;
      mms.next_pos = mms.curr_pos;
      logfilep->data[LOGDATA_UNKNOWN]++;
      return;
    }
    else if (code2type[code] == UNWANTED)
      wanted = FALSE;
  }
  if (wanted && count[INP_DATE] > 0) {
    if (count[INP_UNIXTIME])
      wanted = wantunixtime(&timecode, dman, unixtime, logfilep->tz);
    else {
      if (count[INP_AM]) {
	if (hour > 12) {
	  corrupt_line(logfilep, "Hour greater than 12", -1);
	  return;
	}
	else if (hour == 12)
	  hour = 0;
	if (am == 'p')
	  hour += 12;
      }
      wanted = wantdate(&timecode, dman, hour, minute, date, month, year,
			logfilep->tz);
    }
    if (wanted == ERR) { /* corrupt date */
      corrupt_line(logfilep, "Corrupt date or time", -1);
      return;
    }
  }  /* end count[INP_DATE] > 0 */
  for (i = 0; i < ITEM_NUMBER; i++) {
    wanttree[i] = FALSE;
    if (!wanted) {
      for (j = i; j < ITEM_NUMBER; j++) {  /* reset not-yet-hashed strings */
	if (count[j] != 0)                 /* NB i is now (unwanted i) + 1 */
	  mm[j].next_pos = mm[j].curr_pos;
      }
      mmq.next_pos = mmq.curr_pos;
      mms.next_pos = mms.curr_pos;
      logfilep->data[LOGDATA_UNWANTED]++;
      return;
    }
    if (i == ITEM_HOST)
      prealiasS(&(mm[ITEM_HOST]), &mms);
    name = (char *)(mm[i].curr_pos);
    if (count[i] == 0 || IS_EMPTY_STRING(name) ||
	(name[0] == '-' && name[1] == '\0')) {
      item[i] = blank_entry; /* or unwanted_; but we get wanted right anyway */
      wanted = (wanthead[i] == NULL || included("", FALSE, wanthead[i]));
      /* wanthead[i] == NULL is tested again in included() but it often saves
	 a call to that function, because blankness is common. */
    }
    else {
      if (i == ITEM_FILE || i == ITEM_REFERRER) {
	if ((j = prealias(&(mm[i]), &(mm[ITEM_VHOST]), item[ITEM_VHOST], &mmq,
			  (logical)((i == ITEM_FILE)?case_insensitive:FALSE),
			  (i == ITEM_FILE)?(logfilep->prefix):NULL,
			  logfilep->prefixlen, logfilep->pvpos,
			  (i == ITEM_FILE)?argshead:refargshead)) < 0) {
	  if (j == -1)
	    corrupt_line(logfilep,
			 "%v in file prefix but no VHOST in line", -1);
	  else
	    corrupt_line(logfilep, "Filename too long", -1);
	  return;
	}
      }
      if (lowmem[i] == 0) {
	if (gp[i] == NULL || !STREQ(name, gp[i]->name)) {
	  gp[i] = hashfind(&mm[i], &(hash[i]), no_cols[i], wanthead[i], UNSET,
			   ispagehead, aliashead[i], dirsuffix, dirsufflength,
			   usercase_insensitive, 0, FALSE, i, FALSE);
	}     /* if name the same as last time, don't need */
	else  /* to hashfind again, or save the name */
	  mm[i].next_pos = mm[i].curr_pos;
	item[i] = (Hashentry *)(gp[i]->other);	  
	wanted = (choice)(ENTRY_WANTED(item[i]));
      }

      else if (lowmem[i] == 1) {
	if ((rc = do_alias(name, amemman, aliashead[i], dirsuffix,
			   dirsufflength, usercase_insensitive, 0, FALSE, i))
	    == FALSE) {
	  item[i] = hashfind(&mm[i], &(hash[i]), no_cols[i], wanthead[i],
			     UNSET, ispagehead, NULL, dirsuffix, dirsufflength,
			     usercase_insensitive, 0, FALSE, i, TRUE)->own;
	}
	else if (rc == TRUE) {
	  mm[i].next_pos = mm[i].curr_pos;  /* don't save string */
	  item[i] = hashfind(amemman, &(hash[i]), no_cols[i], wanthead[i],
			     UNSET, ispagehead, NULL, dirsuffix, dirsufflength,
			     usercase_insensitive, 0, FALSE, i, TRUE)->own;
	}
	else { /* rc == ERR */
	  mm[i].next_pos = mm[i].curr_pos;
	  if (included("", FALSE, wanthead[i]))
	    item[i] = blank_entry;
	  else
	    item[i] = unwanted_entry;
	}
	wanted = (choice)(ENTRY_WANTED(item[i]));
      }

      else { /* lowmem[i] >= 2 */
	if ((rc = do_alias(name, amemman, aliashead[i], dirsuffix,
			   dirsufflength, usercase_insensitive, 0, FALSE, i))
	    == TRUE) {
	  mm[i].next_pos = mm[i].curr_pos;  /* don't save old string */
	  len = strlen((char *)(amemman->curr_pos));
	  memcpy(submalloc(&(mm[i]), len + 1), amemman->curr_pos, len + 1);
	  name = (char *)(mm[i].curr_pos); /* which might have changed */
	  amemman->next_pos = amemman->curr_pos;
	}
	if (rc == ERR) {
	  if (included("", FALSE, wanthead[i])) {
	    item[i] = blank_entry;
	    if (i == ITEM_FILE)
	      ispage = FALSE;
	  }
	  else
	    wanted = FALSE;
	  mm[i].next_pos = mm[i].curr_pos;
	}
	else {
	  isitpage = pageq(name, ispagehead, i);
	  if (i == ITEM_FILE)
	    ispage = (choice)isitpage;
	  if (included(name, isitpage, wanthead[i])) {
	    if (lowmem[i] == 2) {
	      item[i] = hashfind(&(mm[i]), &(hash[i]), no_cols[i], wanthead[i],
				 isitpage, ispagehead, NULL, dirsuffix,
				 dirsufflength, usercase_insensitive, 0, FALSE,
				 i, TRUE)->own;
	    }
	    else {
	      item[i] = blank_entry;
	      wanttree[i] = TRUE;
	      mm[i].next_pos = mm[i].curr_pos;
	    }
	  }
	  else {
	    wanted = FALSE;
	    mm[i].next_pos = mm[i].curr_pos;
	  }
	}
      }  /* end lowmem[i] >= 2 */
    }
  }      /* end for i */
  if (!wanted) {
    logfilep->data[LOGDATA_UNWANTED]++;
    return;
  }

  /*** now add it to the hash tables ***/

  /* add to logfile from and to if wanted, whatever status code */
  if (timecode != FIRST_TIME)
    logfilep->from = MIN(logfilep->from, timecode);
  logfilep->to = MAX(logfilep->to, timecode);
  last7 = (timecode > dman->last7from && timecode <= dman->last7to);
  if (ispage == UNSET)            /* NB blank_entry has ispage FALSE */
    ispage = (choice)(item[ITEM_FILE]->ispage);
  if (count[INP_BYTES] == 0)
    bytes = 0;
  if (count[INP_CODE] == 0) {
    outcome = SUCCESS;
    if (count[ITEM_FILE] == 2) {
      logfilep->data[LOGDATA_SUCC]++;
      logfilep->data[LOGDATA_SUCC7] += (unsigned long)last7;
      logfilep->data[LOGDATA_PAGES] += (unsigned long)ispage;
      logfilep->data[LOGDATA_PAGES7] +=
	(unsigned long)((logical)ispage && last7);
    }
    else {
      logfilep->data[LOGDATA_UNKNOWN]++;
      logfilep->data[LOGDATA_UNKNOWN7] += (unsigned long)last7;
    }
  }
  else if (code <= 199) {
    outcome = INFO;
    logfilep->data[LOGDATA_INFO]++;
    logfilep->data[LOGDATA_INFO7] += (unsigned long)last7;
  }
  else switch (outcome = code2type[code]) {
  case SUCCESS:
    logfilep->data[LOGDATA_SUCC]++;
    logfilep->data[LOGDATA_SUCC7] += (unsigned long)last7;
    logfilep->data[LOGDATA_PAGES] += (unsigned long)ispage;
    logfilep->data[LOGDATA_PAGES7] +=
      (unsigned long)((logical)ispage && last7);
    break;
  case FAILURE:
    logfilep->data[LOGDATA_FAIL]++;
    logfilep->data[LOGDATA_FAIL7] += (unsigned long)last7;
    break;
  case REDIRECT:
    logfilep->data[LOGDATA_REDIR]++;
    logfilep->data[LOGDATA_REDIR7] += (unsigned long)last7;
    break;
  case INFO:
    logfilep->data[LOGDATA_INFO]++;
    logfilep->data[LOGDATA_INFO7] += (unsigned long)last7;
    break;
  }

  /* NB any change in what to count when will require corresponding change to
     end of strtoinfmt() and to fmt munching in correct() */
  if (count[INP_CODE] == 2)
    arrayscore(arraydata[REP_CODE - FIRST_ARRAYREP], code, 1,
	       (unsigned long)last7, 0, 0, 0., 0., timecode);
  if (outcome != INFO) {
    if (outcome == SUCCESS) {
      if (count[INP_DATE] == 2)  /* only if file present: see strtoinfmt() */
	datehash(timecode, dman, 1, (unsigned long)ispage, bytes, granularity);
      if (count[INP_BYTES] == 2) {
	arrayscore(arraydata[REP_SIZE - FIRST_ARRAYREP], bytes, 1,
		   (unsigned long)last7, (unsigned long)ispage,
		   (unsigned long)((logical)ispage && last7), bytes,
		   last7?bytes:0., timecode);
	logfilep->bytes += bytes;
	if (last7)
	  logfilep->bytes7 += bytes;
      }
      if (count[INP_PROCTIME] == 2)
	arrayscore(arraydata[REP_PROCTIME - FIRST_ARRAYREP], proctime, 1,
		   (unsigned long)last7, (unsigned long)ispage,
		   (unsigned long)((logical)ispage && last7), bytes,
		   last7?bytes:0., timecode);

      if (alltrees[0] != REP_NUMBER || alldervs[0] != REP_NUMBER) {
	/* for LOWMEM 3, run through alltrees then alldervs */
	/* NB these (POSSTREE/POSSDERV in init.c) only count successes */
	for (k = 0; k <= 1; k++) {
	  for (i = 0; (k?(alldervs[i]):(alltrees[i])) != REP_NUMBER; i++) {
	    j = rep2type[k?(alldervs[i]):(alltrees[i])];
	    if (wanttree[j]) {
	      dummy_item->name = mm[j].curr_pos;
	      /* mm.curr_pos is marked for deletion, but still intact at
		 present */
	      dummy_item->own->data[data2cols[j][REQUESTS]] = 1;
	      if (data2cols[j][REQUESTS7] >= 0)  /* see comment in genrep() */
		dummy_item->own->data[data2cols[j][REQUESTS7]] =
		  (unsigned long)last7;
	      if (data2cols[j][PAGES] >= 0)
		dummy_item->own->data[data2cols[j][PAGES]] =
		  (unsigned long)ispage;
	      if (data2cols[j][PAGES7] >= 0)
		dummy_item->own->data[data2cols[j][PAGES7]] =
		  (unsigned long)((logical)ispage && last7);
	      if (data2cols[j][SUCCDATE] >= 0)
		dummy_item->own->data[data2cols[j][SUCCDATE]] = timecode;
	      if (data2cols[j][SUCCFIRSTD] >= 0)
		dummy_item->own->data[data2cols[j][SUCCFIRSTD]] = timecode;
	      dummy_item->own->bytes = bytes;
	      dummy_item->own->bytes7 = last7?bytes:0.;
	      if (k)
		makederived(derv[alldervs[i] - FIRST_DERVREP], dummy_item,
			    NULL, convfloor, multibyte, alldervs[i],
			    datacols[j], no_cols[j]);
	      else {
		namestart = NULL;
		tree[G(alltrees[i])]->cutfn(&namestart, &nameend,
					    dummy_item->name, FALSE);
		(void)treefind(namestart, nameend,
			       &(tree[G(alltrees[i])]->tree), dummy_item,
			       tree[G(alltrees[i])]->cutfn, FALSE, TRUE, FALSE,
			       tree[G(alltrees[i])]->space, datacols[j],
			       no_cols[j]);
	      }
	    }
	  }
	}
      }  /* there are trees or dervs */
    }    /* outcome == SUCCESS */
    data[REQUESTS2] = 1;
    data[REQUESTS72] = (unsigned long)last7;
    data[PAGES2] = (unsigned long)ispage;
    data[PAGES72] = (unsigned long)((logical)ispage && last7);
    data[DATE2] = timecode;
    data[FIRSTD2] = timecode;
    for (i = 0; i < ITEM_NUMBER; i++) {
      if (count[i] == 2 && !ENTRY_BLANK(item[i]))
	hashscore(item[i], data, datacols[i][outcome], outcome, bytes);
    }
  }      /* end if outcome != INFO */
}
Exemple #18
0
/** Return the proper entry from lock_types, or NULL.
 * \param type of lock to look up.
 * \return lock_types entry for lock.
 */
const lock_list *
get_lockproto(lock_type type)
{
  return hashfind(strupper(type), &htab_locks);
}