Ejemplo n.º 1
0
/** A generic comparer routine to compare two values of any sort type.
 * \param player Player doing the comparison
 * \param a Key 1 to compare
 * \param b Key 2 to compare
 * \param sort_type SortType describing what kind of comparison to make.
 */
int
gencomp(dbref player, char *a, char *b, SortType sort_type)
{
  char *ptr;
  int i, len;
  int result;
  s_rec s1, s2;
  ListTypeInfo *lti;
  ptr = NULL;
  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 = get_list_type_info(sort_type);

  if (ltypelist[i].flags & IS_DB) {
    s1.db = parse_objid(a);
    s2.db = parse_objid(b);
    if (!RealGoodObject(s1.db))
      s1.db = NOTHING;
    if (!RealGoodObject(s2.db))
      s2.db = NOTHING;
  } else {
    s1.db = s2.db = 0;
  }

  s1.val = a;
  s2.val = b;
  genrecord(&s1, player, lti);
  genrecord(&s2, player, lti);
  result = lti->sorter((const void *) &s1, (const void *) &s2);
  if (lti->flags & IS_STRING) {
    if (s1.memo.str.freestr)
      mush_free(s1.memo.str.s, "genrecord");
    if (s2.memo.str.freestr)
      mush_free(s2.memo.str.s, "genrecord");
  }
  free_list_type_info(lti);
  return result;
}
Ejemplo n.º 2
0
/* utility for open and link */
static dbref
parse_linkable_room(dbref player, const char *room_name)
{
  dbref room;

  /* parse room */
  if (!strcasecmp(room_name, "here")) {
    room = IsExit(player) ? Source(player) : Location(player);
  } else if (!strcasecmp(room_name, "home")) {
    return HOME;                /* HOME is always linkable */
  } else {
    room = parse_objid(room_name);
  }

  /* check room */
  if (!GoodObject(room)) {
    notify(player, T("That is not a valid object."));
    return NOTHING;
  } else if (Going(room)) {
    notify(player, T("That room is being destroyed. Sorry."));
    return NOTHING;
  } else if (!can_link_to(player, room)) {
    notify(player, T("You can't link to that."));
    return NOTHING;
  } else {
    return room;
  }
}
Ejemplo n.º 3
0
/**
 * Given a player dbref (For use with viewing permissions for attrs, etc),
 * list of keys, list of strings it maps to (sortkey()-style),
 * # of keys+strings and a list type info, build an array of
 * s_rec structures representing each item.
 * \param player the player executing the sort.
 * \param keys the array of items to sort.
 * \param strs If non-NULL, these are what to sort <keys> using.
 * \param n Number of items in <keys> and <strs>
 * \param lti List Type Info describing how it's sorted and built.
 * \retval A pointer to the first s_rec of an <n> s_rec array.
 */
s_rec *
slist_build(dbref player, char *keys[], char *strs[], int n, ListTypeInfo * lti)
{
  int i;
  s_rec *sp;

  sort_order = lti->sort_order;

  sp = mush_calloc(n, sizeof(s_rec), "do_gensort");

  for (i = 0; i < n; i++) {
    /* Elements are 0 by default thanks to calloc. Only need to touch
       those that need other values. */
    sp[i].val = keys[i];
    if (strs)
      sp[i].ptr = strs[i];
    if (lti->flags & IS_DB) {
      sp[i].db = parse_objid(keys[i]);
      if (!RealGoodObject(sp[i].db))
        sp[i].db = NOTHING;
    }
    genrecord(&sp[i], player, lti);
  }
  return sp;
}
Ejemplo n.º 4
0
/** Look up a player in the player list htab (or by dbref).
 * \param name name of player to find.
 * \return dbref of player, or NOTHING.
 */
dbref
lookup_player(const char *name)
{
  dbref d;

  if (!name || !*name)
    return NOTHING;
  if (*name == NUMBER_TOKEN) {
    d = parse_objid(name);
    if (GoodObject(d) && IsPlayer(d))
      return d;
    else
      return NOTHING;
  }
  if (*name == LOOKUP_TOKEN)
    name++;
  return lookup_player_name(name);
}
Ejemplo n.º 5
0
/** Parse a softcode timezone request.
 *
 * \verbatim
 *
 * If arg is a objid, look up that object's @TZ attribute and parse
 * that. Otherwise, parse arg.
 *
 * If an object doesn't have a @TZ set, offset is set to 0 and tznotset to 1, to be able to tell
 * that case apart from a UTC timezone.
 *
 * If a timezone database is present, try to read the given zone from
 * it. Integers are treated as 'Etc/GMT[+-]N' first.
 *
 * If no tzinfo database, or reading the given zone from one fails,
 * and the arg is an integer, treat it as the number of hours
 * difference from GMT.  Otherwise fail.
 *
 * \endverbatim
 *
 * \param arg The string to parse for a dbref, number or symbolic tz name
 * \param when When to calculate the offset for.
 * \param res Structure to store the parsed results in.
 * \return 1 for success, 0 for failure in parsing the time zone.
 */
bool
parse_timezone_arg(const char *arg, time_t when, struct tz_result *res)
{
  if (!res)
    return 0;

  memset(res, 0, sizeof *res);
  res->tz_when = when;

  if (strcasecmp(arg, "UTC") == 0) {
    res->tz_utc = 1;
    return 1;
  } else if (is_objid(arg)) {
    ATTR *a;
    dbref thing = parse_objid(arg);

    if (!RealGoodObject(thing))
      return 0;

    a = atr_get(thing, "TZ");
    if (!a) {
      /* No timezone attribute isn't an error. Just use the server's
         zone. */
      res->tz_attr_missing = 1;
      return 1;
    }

    arg = atr_value(a);
  }
#ifdef HAVE_ZONEINFO
  {
    struct tzinfo *tz = NULL;
    static char tz_path[BUFFER_LEN];

    if (is_valid_tzname(arg)) {
      tz = read_tzfile(arg);
      snprintf(tz_path, sizeof tz_path, ":%s", arg);
    } else if (is_strict_integer(arg)) {
      int offset;
      char tzname[100];

      offset = parse_integer(arg);

      /* GMT-8 is 8 hours ahead, GMT+8 is 8 hours behind, which makes
         no sense to me. */
      offset = -offset;

      snprintf(tzname, sizeof tzname, "Etc/GMT%+d", offset);
      tz = read_tzfile(tzname);
      snprintf(tz_path, sizeof tz_path, ":%s", tzname);
    }

    if (tz) {
      res->tz_offset = offset_for_tzinfo(tz, when);
      free_tzinfo(tz);
      res->tz_name = tz_path;
      res->tz_has_file = 1;
      return 1;
    }
    /* Fall through to gross numeric offset on failure */
  }
#endif

  if (is_strict_number(arg)) {
    double n = parse_number(arg);

    if (fabs(n) >= 24.0)
      return 0;

    res->tz_offset = floor(n * 3600.0);
    return 1;
  }

  return 0;
}