SortType autodetect_list(char *ptrs[], int nptrs) { int i; ltype lt; SortType sort_type = NUMERIC_LIST; lt = L_NUMERIC; for (i = 0; i < nptrs; i++) { /* Just one big chain of fall-throughs =). */ switch (lt) { case L_NUMERIC: if (is_strict_integer(ptrs[i])) { break; } case L_FLOAT: if (is_strict_number(ptrs[i])) { lt = L_FLOAT; sort_type = FLOAT_LIST; break; } case L_DBREF: if (is_objid(ptrs[i]) && (i == 0 || lt == L_DBREF)) { lt = L_DBREF; sort_type = DBREF_LIST; break; } case L_ALPHANUM: return MAGIC_LIST; } } return sort_type; }
/** Remove an access rule from the linked list. * \param pattern access rule host pattern to match. * \return number of rule removed. * This function removes an access rule from the list. * Only rules that appear after the "@sitelock" rule can be * removed with this function. */ int remove_access_sitelock(const char *pattern) { struct access *ap, *next, *prev = NULL; int n = 0; int rulenum = 0, deletethis = -1; if (is_strict_integer(pattern)) deletethis = parse_integer(pattern); /* We only want to be able to delete entries added with @sitelock */ for (ap = access_top; ap; ap = ap->next) { rulenum++; if (strcmp(ap->host, "@sitelock") == 0) { prev = ap; ap = ap->next; break; } } while (ap) { rulenum++; next = ap->next; if (deletethis == -1 ? (strcasecmp(pattern, ap->host) == 0) : deletethis == rulenum) { n++; sitelock_free(ap); if (prev) prev->next = next; else access_top = next; if (deletethis >= 0) break; } else { prev = ap; } ap = next; } return n; }
/** 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; }
/** Parse access options into fields. * \param opts access options to read from. * \param who pointer to player to whom rule applies, or AMBIGUOUS. * \param can pointer to flags of allowed actions. * \param cant pointer to flags of disallowed actions. * \param player enactor. * \return number of options successfully parsed. * Parse options and return the appropriate can and cant bits. * Return the number of options successfully parsed. * This makes a copy of the options string, so it's not modified. */ int parse_access_options(const char *opts, dbref *who, uint32_t *can, uint32_t *cant, dbref player) { char myopts[BUFFER_LEN]; char *p; char *w; acsflag *c; int found, totalfound, first; if (!opts || !*opts) return 0; strcpy(myopts, opts); totalfound = 0; first = 1; if (who) *who = AMBIGUOUS; p = trim_space_sep(myopts, ' '); while ((w = split_token(&p, ' '))) { found = 0; if (first && who) { /* Check for a character */ first = 0; if (is_strict_integer(w)) { /* We have a dbref */ *who = parse_integer(w); if (*who != AMBIGUOUS && !GoodObject(*who)) *who = AMBIGUOUS; continue; } } if (*w == '!') { /* Found a negated warning */ w++; for (c = acslist; c->name; c++) { if (c->toggle && !strncasecmp(w, c->name, strlen(c->name))) { *cant |= c->flag; found++; } } } else { /* None is special */ if (!strncasecmp(w, "NONE", 4)) { *cant = ACS_DEFAULT; found++; } else { for (c = acslist; c->name; c++) { if (!strncasecmp(w, c->name, strlen(c->name))) { *can |= c->flag; found++; } } } } /* At this point, we haven't matched any warnings. */ if (!found) { if (GoodObject(player)) notify_format(player, T("Unknown access option: %s"), w); else do_log(LT_ERR, GOD, GOD, "Unknown access flag: %s", w); } else { totalfound += found; } } return totalfound; }