/** Add a player's alias list to the player list htab. * \param player dbref of player to add. * \param alias list of names ot use as hash table keys for player, * semicolon-separated. */ void add_player_alias(dbref player, const char *alias) { char tbuf1[BUFFER_LEN], *s, *sp; if (!hft_initialized) init_hft(); if (!alias) { add_player(player); return; } mush_strncpy(tbuf1, alias, BUFFER_LEN); s = trim_space_sep(tbuf1, ALIAS_DELIMITER); while (s) { sp = split_token(&s, ALIAS_DELIMITER); while (sp && *sp && *sp == ' ') sp++; if (sp && *sp) { dbref *p; p = slab_malloc(player_dbref_slab, NULL); if (!p) mush_panic("Unable to allocate memory in plyrlist!"); *p = player; hashadd(strupper(sp), p, &htab_player_list); } } }
/** Reset all of a player's player list entries (names/aliases). * This is called when a player changes name or alias. * We remove all their old entries, and add back their new ones. * \param player dbref of player * \param oldname player's former name (NULL if not changing) * \param oldalias player's former aliases (NULL if not changing) * \param name player's new name * \param alias player's new aliases */ void reset_player_list(dbref player, const char *oldname, const char *oldalias, const char *name, const char *alias) { char tbuf1[BUFFER_LEN]; char tbuf2[BUFFER_LEN]; if (!oldname) name = Name(player); if (oldalias) { mush_strncpy(tbuf1, oldalias, BUFFER_LEN); if (alias) { strncpy(tbuf2, alias, BUFFER_LEN - 1); tbuf2[BUFFER_LEN - 1] = '\0'; } else { tbuf2[0] = '\0'; } } else { /* We are not changing aliases, just name, but we need to get the * aliases anyway, since we may change name to something that's * in the alias, and thus must not be deleted. */ ATTR *a = atr_get_noparent(player, "ALIAS"); if (a) { mush_strncpy(tbuf1, atr_value(a), BUFFER_LEN); } else { tbuf1[0] = '\0'; } strcpy(tbuf2, tbuf1); } /* Delete all the old stuff */ delete_player(player, tbuf1); delete_player(player, NULL); /* Add in the new stuff */ add_player_alias(player, name); add_player_alias(player, tbuf2); }
static const char * normalize_entry(help_file *help_dat, const char *arg1) { static char the_topic[LINE_SIZE + 2]; if (*arg1 == '\0') arg1 = (char *) "help"; else if (*arg1 == '&') return T("#-1 INVALID ENTRY"); if (help_dat->admin) snprintf(the_topic, LINE_SIZE, "&%s", arg1); else mush_strncpy(the_topic, arg1, LINE_SIZE); return the_topic; }
/* Allocate a new reference count struct. Consider moving away from slabs; the struct size is pretty big with the skip list fields added. But see comment for memcheck_slab's declaration. */ static MEM * alloc_memcheck_node(const char *ref) { MEM *newcheck; if (!memcheck_slab) memcheck_slab = slab_create("mem check references", sizeof(MEM)); newcheck = slab_malloc(memcheck_slab, NULL); memset(newcheck, 0, sizeof *newcheck); mush_strncpy(newcheck->ref_name, ref, REF_NAME_LEN); newcheck->link_count = pick_link_count(MAX_LINKS); newcheck->ref_count = 1; return newcheck; }
char * crypt_code(char *code, char *text, int type) { static char textbuff[BUFFER_LEN]; char codebuff[BUFFER_LEN]; int start = 32; int end = 126; int mod = end - start + 1; char *p, *q, *r; if (!(text && *text)) return (char *) ""; if (!code || !*code) return text; mush_strncpy(codebuff, crunch_code(code), BUFFER_LEN); if (!*codebuff) return text; textbuff[0] = '\0'; p = text; q = codebuff; r = textbuff; /* Encryption: Simply go through each character of the text, get its ascii * value, subtract start, add the ascii value (less start) of the * code, mod the result, add start. Continue */ while (*p) { if ((*p < start) || (*p > end)) { p++; continue; } if (type) *r++ = (((*p++ - start) + (*q++ - start)) % mod) + start; else *r++ = (((*p++ - *q++) + 2 * mod) % mod) + start; if (!*q) q = codebuff; } *r = '\0'; return textbuff; }
/** Check to see that the lock type is a valid type. * If it's not in our lock table, it's not valid, * unless it begins with 'user:'******'t allow '|' in lock names because it * will confuse our db-reading routines. * * * \param player the enactor, for notification. * \param thing object on which to check the lock. * \param name name of lock type. * \return lock type, or NULL. */ static lock_type check_lock_type(dbref player, dbref thing, lock_type name) { lock_type ll; char user_name[BUFFER_LEN]; char *colon; /* Special-case for basic locks. */ if (!name || !*name) return Basic_Lock; /* Normal locks. */ ll = match_lock(name); if (ll != NULL) return ll; /* If the lock is set, it's allowed, whether it exists normally or not. */ if (getlock(thing, name) != TRUE_BOOLEXP) return name; /* Check to see if it's a well-formed user-defined lock. */ if (!string_prefix(name, "User:"******"Unknown lock type.")); return NULL; } if (strchr(name, '|')) { notify(player, T("The character \'|\' may not be used in lock names.")); return NULL; } colon = strchr(name, ':') + 1; mush_strncpy(user_name, colon, BUFFER_LEN); if (!good_atr_name(user_name)) { notify(player, T("That is not a valid lock name.")); return NULL; } return colon; }
/** Remove a player from the player list htab. * \param player dbref of player to remove. * \param alias key to remove if given. */ void delete_player(dbref player, const char *alias) { if (!hft_initialized) { init_hft(); return; } if (alias) { /* This could be a compound alias, in which case we need to delete * them all, but we shouldn't delete the player's own name! */ char tbuf1[BUFFER_LEN], *s, *sp; mush_strncpy(tbuf1, alias, BUFFER_LEN); s = trim_space_sep(tbuf1, ALIAS_DELIMITER); while (s) { sp = split_token(&s, ALIAS_DELIMITER); while (sp && *sp && *sp == ' ') sp++; if (sp && *sp && strcasecmp(sp, Name(player))) hashdelete(strupper(sp), &htab_player_list); } } else hashdelete(strupper(Name(player)), &htab_player_list); }
/** 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; }
/** 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"); }