Пример #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);
}
Пример #2
0
    static struct access *sitelock_alloc(const char *host, dbref who,
                                         uint32_t can, uint32_t cant,
                                         const char *comment,
                                         const char **errptr)
{
  struct access *tmp;
  tmp = mush_malloc(sizeof(struct access), "sitelock.rule");
  if (!tmp) {
    static const char *memerr = "unable to allocate memory";
    if (errptr)
      *errptr = memerr;
    return NULL;
  }
  tmp->who = who;
  tmp->can = can;
  tmp->cant = cant;
  tmp->host = mush_strdup(host, "sitelock.rule.pattern");
  if (comment && *comment)
    tmp->comment = mush_strdup(comment, "sitelock.rule.comment");
  else
    tmp->comment = NULL;
  tmp->next = NULL;

  if (can & ACS_REGEXP) {
    int erroffset = 0;
    tmp->re = pcre_compile(host, 0, errptr, &erroffset, tables);
    if (!tmp->re) {
      sitelock_free(tmp);
      return NULL;
    }
  } else
    tmp->re = NULL;

  return tmp;
}
Пример #3
0
void addNewNebula(dbref executor, int index, const char* name, double radius, double x, double y, double z, char *buff, char **bp)
{
	aspace_borders* newNebula;
	newNebula = im_find(nebula_map, index);
	
	if (newNebula != NULL) {
		safe_str("#-1 NEBULA # ALREADY IN USE", buff, bp);
		return;
	}
		
	newNebula = mush_malloc(sizeof(aspace_borders), "nebula_info");
	
	newNebula->name = mush_strdup(name, "spacenebula_name");
	newNebula->empire_id = 0;
	newNebula->radius = radius;
	newNebula->x = x;
	newNebula->y = y;
	newNebula->z = z;
	
	if( im_insert(nebula_map, index, newNebula )) {
		safe_str("New nebula Created.", buff, bp);
		write_spacelog(executor, executor, tprintf("Nebula Created: %s", newNebula->name));
	} else
		safe_str("#-1 NEBULA NOT CREATED.", buff, bp);
}
Пример #4
0
/** Add an entry to a hash table.
 * \param htab pointer to hash table.
 * \param key key string to store data under.
 * \param hashdata void pointer to data to be stored.
 * \retval false failure.
 * \retval true success.
 */
bool
hash_add(HASHTAB *htab, const char *key, void *hashdata)
{
    char *keycopy;
    int keylen;

    if (hash_find(htab, key) != NULL)
        return false;

    keycopy = mush_strdup(key, "hash.key");
    keylen = strlen(keycopy);

    if (htab->entries == htab->hashsize)
        real_hash_resize(htab, next_prime_after(floor(htab->hashsize * 1.15)),
                         htab->hashfunc_offset);

    htab->entries += 1;
    if (!hash_insert(htab, keycopy, keylen, hashdata)) {
        first_offset = -1;
        resize_calls = 0;
        real_hash_resize(htab, htab->hashsize,
                         (htab->hashfunc_offset + 1) % NHASH_MOD);
    }
    return true;
}
Пример #5
0
static void
genrecord(s_rec *sp, dbref player, ListTypeInfo * lti)
{
  lti->make_record(sp, player, lti->attrname);
  if (lti->flags & IS_CASE_INSENS && sp->memo.str.s) {
    if (sp->memo.str.freestr == 0) {
      sp->memo.str.s = mush_strdup(sp->memo.str.s, "genrecord");
      sp->memo.str.freestr = 1;
    }
    upcasestr(sp->memo.str.s);
  }
}
Пример #6
0
/** Add a new lock to the table.
 * \param name The name of the lock
 * \param flags The default flags.
 */
void
define_lock(lock_type name, privbits flags)
{
  lock_list *newlock;

  newlock = mush_malloc(sizeof *newlock, "lock");
  newlock->type = mush_strdup(strupper(name), "lock.name");
  newlock->flags = flags;
  newlock->creator = GOD;
  newlock->key = TRUE_BOOLEXP;
  newlock->next = NULL;
  hashadd((char *) newlock->type, newlock, &htab_locks);
}
Пример #7
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);
}
Пример #8
0
/* Ads a module entry and returns */
struct module_entry_t *module_entry_add(char *name) {
  struct module_entry_t *entry;

  entry = (struct module_entry_t *) mush_malloc(sizeof(struct module_entry_t), "MODULE_ENTRY");

  if(!entry) {
    return NULL; /* Should really panic here.. */
  }

  entry->name = mush_strdup(name, "MODULE_ENTRY.NAME");
  entry->info = NULL;
  entry->load = NULL;
  entry->unload = NULL;
  entry->next = module_list;
  module_list = entry;

  return entry;
}
Пример #9
0
/**
 * Given a string description of a sort type, generate and return a
 * ListTypeInfo that can be passed to slist_* functions.
 * \param sort_type A string describing a sort type.
 * \retval ListTypeInfo containing all generating and comparison information
 *         needed.
 */
ListTypeInfo *
get_list_type_info(SortType sort_type)
{
  int i, len;
  char *ptr = NULL;
  ListTypeInfo *lti;

  /* i is either the right one or the default, so we return it anyway. */
  lti = mush_calloc(1, sizeof(ListTypeInfo), "list_type_info");

  lti->sort_order = ASCENDING;

  if (*sort_type == '-') {
    lti->sort_order = DESCENDING;
    sort_type++;
  }
  if (!sort_type) {
    /* Advance i to the default */
    for (i = 0; ltypelist[i].name; i++) ;
  } else if ((ptr = strchr(sort_type, ':'))) {
    len = ptr - sort_type;
    ptr += 1;
    if (!*ptr)
      ptr = NULL;
    for (i = 0;
         ltypelist[i].name && strncasecmp(ltypelist[i].name, sort_type, len);
         i++) ;
  } else {
    for (i = 0; ltypelist[i].name && strcasecmp(ltypelist[i].name, sort_type);
         i++) ;
  }

  lti->name = ltypelist[i].name;
  if (ptr) {
    lti->attrname = mush_strdup(ptr, "list_type_info_attrname");
  } else {
    lti->attrname = NULL;
  }
  lti->make_record = ltypelist[i].make_record;
  lti->sorter = ltypelist[i].sorter;
  lti->flags = ltypelist[i].flags;
  return lti;
}
Пример #10
0
/** Save the current timezone (The TZ environment variable) and set a new one.
 * \param newzone The new timezone.
 */
void
save_and_set_tz(const char *newzone)
{
  const char *tz;

  if (!newzone)
    newzone = "";

  tz = getenv("TZ");
  if (tz)
    saved_tz = mush_strdup(tz, "timezone");
  else
    saved_tz = NULL;

#ifdef WIN32
  _putenv_s("TZ", newzone);
#else
  setenv("TZ", newzone, 1);
#endif

  tzset();
}
Пример #11
0
char *
sound_hash(const char *str, int len, enum sound_hash_type type)
{
  sqlite3 *sqldb = get_shared_db();
  sqlite3_stmt *hasher;
  char *utf8, *result = NULL;
  int ulen;
  int status;

  switch (type) {
  case HASH_SOUNDEX:
    /* Classic Penn soundex turns a leading ph into f. This makes
       sense but isn't typical. */
    hasher = prepare_statement(sqldb,
                               "VALUES (soundex(CASE WHEN ?1 LIKE 'ph%' THEN "
                               "printf('f%s', substr(?1, 3)) ELSE ?1 END))",
                               "hash.soundex");
    break;
  case HASH_PHONE:
    hasher =
      prepare_statement(sqldb, "VALUES (spellfix1_phonehash(?))", "hash.phone");
    break;
  default:
    return NULL;
  }

  utf8 = latin1_to_utf8(str, len, &ulen, "string");
  sqlite3_bind_text(hasher, 1, utf8, ulen, free_string);
  status = sqlite3_step(hasher);
  if (status == SQLITE_ROW) {
    result =
      mush_strdup((const char *) sqlite3_column_text(hasher, 0), "string");
  }
  sqlite3_reset(hasher);
  return result;
}
Пример #12
0
void edit_border(dbref executor, int border_id, const char* setting, const char* new_value, char *buff, char **bp)
{
	aspace_borders *si = NULL;

	si = im_find(border_map, border_id);
	
	if (si != NULL)
	{
		switch (setting[0]) {
			case 'n': /* Name */
				si->name = mush_strdup(new_value, "spaceborder_name");
				safe_format(buff, bp, "Border Name changed for border %u to %s", border_id, si->name);
				break;
			case 'r': /* Radius */
				si->radius = parse_number(new_value);
				safe_format(buff, bp, "Border Radius changed for border %u to %f", border_id, si->radius);
				break;
			case 'x': /* X Coordinate of Centre */
				si->x = parse_number(new_value);
				safe_format(buff, bp, "Border CoordX changed for border %u to %f", border_id, si->x);
				break;
			case 'y': /* Y Coordinate of Centre */
				si->y = parse_number(new_value);
				safe_format(buff, bp, "Border CoordY changed for border %u to %f", border_id, si->y);
				break;
			case 'z': /* Z Coordinate of Centre */
				si->z = parse_number(new_value);
				safe_format(buff, bp, "Border CoordZ changed for border %u to %f", border_id, si->z);
				break;
			default: safe_str("#-1 BORDER SETTING NOT FOUND.", buff, bp);
				break;
		}
	} else {
		safe_str("#-1 BORDER NOT FOUND.", buff, bp);
	}
}
Пример #13
0
void addNewBorder(dbref executor, int border_number, const char* name, double radius, double x, double y, double z, char *buff, char **bp)
{
	aspace_borders* newBorder;
	newBorder = im_find(border_map, border_number);
	if (newBorder != NULL) {
		safe_str("#-1 BORDER ALREADY EXISTS", buff, bp);
		return;
	}
		
	newBorder = mush_malloc(sizeof(aspace_borders), "border_info");
	
	newBorder->name = mush_strdup(name, "spaceborder_name");
	newBorder->empire_id = 0;
	newBorder->radius = radius;
	newBorder->x = x;
	newBorder->y = y;
	newBorder->z = z;
	
	if( im_insert(border_map, border_number, newBorder )) {
		safe_str("New Border Created.", buff, bp);
		write_spacelog(executor, executor, tprintf("Border Created: %s", newBorder->name));
	} else
		safe_str("#-1 BORDER NOT CREATED.", buff, bp);
}
Пример #14
0
/** Rename something.
 * \verbatim
 * This implements @name.
 * \endverbatim
 * \param player the enactor.
 * \param name current name of object to rename.
 * \param newname_ new name for object.
 */
void
do_name(dbref player, const char *name, char *newname_)
{
  dbref thing;
  char oldname[BUFFER_LEN];
  char *newname = NULL;
  char *alias = NULL;
  PE_REGS *pe_regs;

  if ((thing = match_controlled(player, name)) == NOTHING)
    return;

  /* check for bad name */
  if ((*newname_ == '\0') || strchr(newname_, '[')) {
    notify(player, T("Give it what new name?"));
    return;
  }
  switch (Typeof(thing)) {
  case TYPE_PLAYER:
    switch (ok_object_name
            (newname_, player, thing, TYPE_PLAYER, &newname, &alias)) {
    case OPAE_INVALID:
    case OPAE_NULL:
      notify(player, T("You can't give a player that name or alias."));
      if (newname)
        mush_free(newname, "name.newname");
      if (alias)
        mush_free(alias, "name.newname");
      return;
    case OPAE_TOOMANY:
      notify(player, T("Too many aliases."));
      mush_free(newname, "name.newname");
      return;
    case OPAE_SUCCESS:
      break;
    }
    break;
  case TYPE_EXIT:
    if (ok_object_name(newname_, player, thing, TYPE_EXIT, &newname, &alias) !=
        OPAE_SUCCESS) {
      notify(player, T("That is not a reasonable name."));
      if (newname)
        mush_free(newname, "name.newname");
      if (alias)
        mush_free(alias, "name.newname");
      return;
    }
    break;
  case TYPE_THING:
  case TYPE_ROOM:
    if (!ok_name(newname_, 0)) {
      notify(player, T("That is not a reasonable name."));
      return;
    }
    newname = mush_strdup(trim_space_sep(newname_, ' '), "name.newname");
    break;
  default:
    /* Should never occur */
    notify(player, T("I don't see that here."));
    return;
  }

  /* Actually change it */
  mush_strncpy(oldname, Name(thing), BUFFER_LEN);

  if (IsPlayer(thing)) {
    do_log(LT_CONN, 0, 0, "Name change by %s(#%d) to %s",
           Name(thing), thing, newname);
    if (Suspect(thing) && strcmp(Name(thing), newname) != 0)
      flag_broadcast("WIZARD", 0,
                     T("Broadcast: Suspect %s changed name to %s."),
                     Name(thing), newname);
    reset_player_list(thing, Name(thing), NULL, newname, NULL);
  }
  set_name(thing, newname);
  if (alias) {
    if (*alias == ALIAS_DELIMITER) {
      do_set_atr(thing, "ALIAS", NULL, player, 0);
    } else {
      /* New alias to set */
      do_set_atr(thing, "ALIAS", alias, player, 0);
    }
    mush_free(alias, "name.newname");
  }

  queue_event(player, "OBJECT`RENAME", "%s,%s,%s",
              unparse_objid(thing), newname, oldname);

  if (!AreQuiet(player, thing))
    notify(player, T("Name set."));
  pe_regs = pe_regs_create(PE_REGS_ARG, "do_name");
  pe_regs_setenv_nocopy(pe_regs, 0, oldname);
  pe_regs_setenv_nocopy(pe_regs, 1, newname);
  real_did_it(player, thing, NULL, NULL, "ONAME", NULL, "ANAME", NOTHING,
              pe_regs, NA_INTER_PRESENCE, AN_SYS);
  pe_regs_free(pe_regs);
  mush_free(newname, "name.newname");
}
Пример #15
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;
}