/* Clone an object. The new object is owned by the cloning player */ static dbref clone_object(dbref player, dbref thing, const char *newname, int preserve) { dbref clone; clone = new_object(); Owner(clone) = Owner(player); Name(clone) = NULL; if (newname && *newname) set_name(clone, newname); else set_name(clone, Name(thing)); s_Pennies(clone, Pennies(thing)); AttrCount(clone) = 0; List(clone) = NULL; Locks(clone) = NULL; clone_locks(player, thing, clone); Zone(clone) = Zone(thing); Parent(clone) = Parent(thing); Flags(clone) = clone_flag_bitmask("FLAG", Flags(thing)); if (!preserve) { clear_flag_internal(clone, "WIZARD"); clear_flag_internal(clone, "ROYALTY"); Warnings(clone) = 0; /* zap warnings */ Powers(clone) = new_flag_bitmask("POWER"); /* zap powers */ } else { Powers(clone) = clone_flag_bitmask("POWER", Powers(thing)); Warnings(clone) = Warnings(thing); if (Wizard(clone) || Royalty(clone) || Warnings(clone) || !null_flagmask("POWER", Powers(clone))) notify(player, T ("Warning: @CLONE/PRESERVE on an object with WIZ, ROY, @powers, or @warnings.")); } /* We give the clone the same modification time that its * other clone has, but update the creation time */ ModTime(clone) = ModTime(thing); CreTime(clone) = mudtime; Type(clone) = Type(thing); Contents(clone) = Location(clone) = Next(clone) = NOTHING; if (IsRoom(thing)) Exits(clone) = NOTHING; else Home(clone) = Home(thing); atr_cpy(clone, thing); queue_event(player, "OBJECT`CREATE", "%s,%s", unparse_objid(clone), unparse_objid(thing)); return clone; }
/* FileStatus - compare logical info about a file with file on disk * * Compare the last modified time with the last snapshot. If the filename * contains metachars, the file is not believed to have changed. Further, if * the file is a pseudo file, it cannot have changed. * * pFile file of interest (contains mod time) * pName name of file to examine (when writing to diff. name) * * returns FILECHANGED if timestamps differ * FILEDELETED if file on disk does not exist * FILESAME if timestamps are the same */ int FileStatus ( PFILE pFile, char *pName ){ long modtime; if (TESTFLAG(FLAGS(pFile),FAKE)) { return FILESAME; } if (pName == NULL) { pName = pFile->pName; } if (*strbscan (pName, "?*") != 0) { return FILESAME; } if ((modtime = ModTime (pName)) == 0L) { return FILEDELETED; } if (pFile->modify != modtime) { return FILECHANGED; } return FILESAME; }
static dbref make_player(const char *name, const char *password, const char *host, const char *ip) { dbref player; char temp[SBUF_LEN]; char *flaglist, *flagname; char flagbuff[BUFFER_LEN]; player = new_object(); /* initialize everything */ set_name(player, name); Location(player) = PLAYER_START; Home(player) = PLAYER_START; Owner(player) = player; Parent(player) = NOTHING; Type(player) = TYPE_PLAYER; Flags(player) = new_flag_bitmask("FLAG"); strcpy(flagbuff, options.player_flags); flaglist = trim_space_sep(flagbuff, ' '); if (*flaglist != '\0') { while (flaglist) { flagname = split_token(&flaglist, ' '); twiddle_flag_internal("FLAG", player, flagname, 0); } } if (Suspect_Site(host, player) || Suspect_Site(ip, player)) set_flag_internal(player, "SUSPECT"); set_initial_warnings(player); /* Modtime tracks login failures */ ModTime(player) = (time_t) 0; (void) atr_add(player, pword_attr, password_hash(password, NULL), GOD, 0); giveto(player, START_BONUS); /* starting bonus */ (void) atr_add(player, "LAST", show_time(mudtime, 0), GOD, 0); (void) atr_add(player, "LASTSITE", host, GOD, 0); (void) atr_add(player, "LASTIP", ip, GOD, 0); (void) atr_add(player, "LASTFAILED", " ", GOD, 0); snprintf(temp, sizeof temp, "%d", START_QUOTA); (void) atr_add(player, "RQUOTA", temp, GOD, 0); (void) atr_add(player, "MAILCURF", "0", GOD, AF_LOCKED | AF_NOPROG | AF_WIZARD); add_folder_name(player, 0, "inbox"); /* link him to PLAYER_START */ PUSH(player, Contents(PLAYER_START)); add_player(player); add_lock(GOD, player, Basic_Lock, parse_boolexp(player, "=me", Basic_Lock), LF_DEFAULT); add_lock(GOD, player, Enter_Lock, parse_boolexp(player, "=me", Basic_Lock), LF_DEFAULT); add_lock(GOD, player, Use_Lock, parse_boolexp(player, "=me", Basic_Lock), LF_DEFAULT); current_state.players++; local_data_create(player); return player; }
/** Unlock a lock (user interface). * \verbatim * This implements @unlock. * \endverbatim * \param player the enactor. * \param name name of object to unlock. * \param type type of lock to unlock. */ void do_unlock(dbref player, const char *name, lock_type type) { dbref thing; char *sp; lock_type real_type; /* check for '@unlock <object>/<atr>' */ sp = strchr(name, '/'); if (sp) { notify(player, "Use @atrlock."); return; } if ((thing = match_controlled(player, name)) != NOTHING) { if ((real_type = check_lock_type(player, thing, type)) != NULL) { if (getlock(thing, real_type) == TRUE_BOOLEXP) { if (!AreQuiet(player, thing)) notify_format(player, T("%s(%s) - %s (already) unlocked."), Name(thing), unparse_dbref(thing), real_type); } else if (delete_lock(player, thing, real_type)) { if (!AreQuiet(player, thing)) notify_format(player, T("%s(%s) - %s unlocked."), Name(thing), unparse_dbref(thing), real_type); if (!IsPlayer(thing)) { char lmbuf[1024]; ModTime(thing) = mudtime; snprintf(lmbuf, 1023, "%s lock[#%d]", real_type, player); lmbuf[strlen(lmbuf)+1] = '\0'; set_lmod(thing, lmbuf); } } else notify(player, T("Permission denied.")); } } }
/** Unlock a lock (user interface). * \verbatim * This implements @unlock. * \endverbatim * \param player the enactor. * \param name name of object to unlock. * \param type type of lock to unlock. */ void do_unlock(dbref player, const char *name, lock_type type) { dbref thing; lock_type real_type; /* check for '@unlock <object>/<atr>' */ if (strchr(name, '/')) { do_atrlock(player, name, "off"); return; } if ((thing = match_controlled(player, name)) != NOTHING) { if ((real_type = check_lock_type(player, thing, type)) != NULL) { if (getlock(thing, real_type) == TRUE_BOOLEXP) { if (!AreQuiet(player, thing)) notify_format(player, T("%s(%s) - %s (already) unlocked."), AName(thing, AN_SYS, NULL), unparse_dbref(thing), real_type); } else if (delete_lock(player, thing, real_type)) { if (!AreQuiet(player, thing)) notify_format(player, T("%s(%s) - %s unlocked."), AName(thing, AN_SYS, NULL), unparse_dbref(thing), real_type); if (!IsPlayer(thing)) ModTime(thing) = mudtime; } else notify(player, T("Permission denied.")); } } }
/** Set/lock a lock (user interface). * \verbatim * This implements @lock. * \endverbatim * \param player the enactor. * \param name name of object to lock. * \param keyname key to lock the lock to, as a string. * \param type type of lock to lock. */ void do_lock(dbref player, const char *name, const char *keyname, lock_type type) { lock_type real_type; dbref thing; boolexp key; /* check for '@lock <object>/<atr>' */ if (strchr(name, '/')) { do_atrlock(player, name, "on"); return; } if (!keyname || !*keyname) { do_unlock(player, name, type); return; } switch (thing = match_result(player, name, NOTYPE, MAT_EVERYTHING)) { case NOTHING: notify(player, T("I don't see what you want to lock!")); return; case AMBIGUOUS: notify(player, T("I don't know which one you want to lock!")); return; default: if (!controls(player, thing)) { notify(player, T("You can't lock that!")); return; } if (IsGarbage(thing)) { notify(player, T("Why would you want to lock garbage?")); return; } break; } key = parse_boolexp(player, keyname, type); /* do the lock */ if (key == TRUE_BOOLEXP) { notify(player, T("I don't understand that key.")); } else { if ((real_type = check_lock_type(player, thing, type)) != NULL) { /* everything ok, do it */ if (add_lock(player, thing, real_type, key, LF_DEFAULT)) { if (!AreQuiet(player, thing)) notify_format(player, T("%s(%s) - %s locked."), AName(thing, AN_SYS, NULL), unparse_dbref(thing), real_type); if (!IsPlayer(thing)) ModTime(thing) = mudtime; } else { notify(player, T("Permission denied.")); /* Done by a failed add_lock() // free_boolexp(key); */ } } else free_boolexp(key); } }
/** Set flags on a lock (user interface). * \verbatim * This implements @lset. * \endverbatim * \param player the enactor. * \param what string in the form obj/lock. * \param flags list of flags to set. */ void do_lset(dbref player, char *what, char *flags) { dbref thing; lock_list *l; char *lname; int flag; int unset = 0; if ((lname = strchr(what, '/')) == NULL) { notify(player, T("No lock name given.")); return; } *lname++ = '\0'; if ((thing = match_controlled(player, what)) == NOTHING) return; if (*flags == '!') { unset = 1; flags++; } if ((flag = string_to_lockflag(flags)) < 0) { notify(player, T("Unrecognized lock flag.")); return; } l = getlockstruct_noparent(thing, lname); if (!l || !Can_Read_Lock(player, thing, L_TYPE(l))) { notify(player, T("No such lock.")); return; } if (!can_write_lock(player, thing, l)) { notify(player, T("Permission denied.")); return; } if (unset) L_FLAGS(l) &= ~flag; else L_FLAGS(l) |= flag; if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player))) notify_format(player, "%s/%s - %s.", Name(thing), L_TYPE(l), unset ? T("lock flags unset") : T("lock flags set")); if (!IsPlayer(thing)) { char lmbuf[1024]; ModTime(thing) = mudtime; snprintf(lmbuf, 1023, "lflags - %s[#%d]", flags, player); lmbuf[strlen(lmbuf)+1] = '\0'; set_lmod(thing, lmbuf); } }
/** Set flags on a lock (user interface). * \verbatim * This implements @lset. * \endverbatim * \param player the enactor. * \param what string in the form obj/lock. * \param flags list of flags to set. */ void do_lset(dbref player, char *what, char *flags) { dbref thing; lock_list *l; char *lname; privbits flag; bool unset = 0; if ((lname = strchr(what, '/')) == NULL) { notify(player, T("No lock name given.")); return; } *lname++ = '\0'; if ((thing = match_controlled(player, what)) == NOTHING) return; if (*flags == '!') { unset = 1; flags++; } if (string_to_lockflag(player, flags, &flag) < 0) { notify(player, T("Unrecognized lock flag.")); return; } l = getlockstruct_noparent(thing, lname); if (!l || !Can_Read_Lock(player, thing, L_TYPE(l))) { notify(player, T("No such lock.")); return; } if (!can_write_lock(player, thing, l)) { notify(player, T("Permission denied.")); return; } if (unset) L_FLAGS(l) &= ~flag; else L_FLAGS(l) |= flag; if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player))) notify_format(player, "%s/%s - %s.", AName(thing, AN_SYS, NULL), L_TYPE(l), unset ? T("lock flags unset") : T("lock flags set")); if (!IsPlayer(thing)) ModTime(thing) = mudtime; }
/* SetModTime - Snapshot a file's last-modification time * * pFile file of interest */ void SetModTime ( PFILE pFile ) { pFile->modify = ModTime (pFile->pName); }
/** Check to see if someone can connect to a player. * \param d DESC the connect attempt is being made for * \param name name of player to connect to. * \param password password of player to connect to. * \param host host from which connection is being attempted. * \param ip ip address from which connection is being attempted. * \param errbuf buffer to return connection errors. * \return dbref of connected player object or NOTHING for failure * (with reason for failure returned in errbuf). */ dbref connect_player(DESC *d, const char *name, const char *password, const char *host, const char *ip, char *errbuf) { dbref player; int count; /* Default error */ strcpy(errbuf, T("Either that player does not exist, or has a different password.")); if (!name || !*name) return NOTHING; /* validate name */ if ((player = lookup_player(name)) == NOTHING) { /* Invalid player names are failures, too. */ count = mark_failed(ip); strcpy(errbuf, T("There is no player with that name.")); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d,%s", d->descriptor, ip, count, "invalid player", -1, name); return NOTHING; } /* See if player is allowed to connect like this */ if (Going(player) || Going_Twice(player)) { do_log(LT_CONN, 0, 0, "Connection to GOING player %s not allowed from %s (%s)", Name(player), host, ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count_failed(ip), "player is going", player); strcpy(errbuf, T("You cannot connect to that player at this time.")); return NOTHING; } /* Check sitelock patterns */ if (Guest(player) && (!Site_Can_Guest(host, player) || !Site_Can_Guest(ip, player))) { if (!Deny_Silent_Site(host, AMBIGUOUS) && !Deny_Silent_Site(ip, AMBIGUOUS)) { do_log(LT_CONN, 0, 0, "Connection to %s (GUEST) not allowed from %s (%s)", name, host, ip); strcpy(errbuf, T("Guest connections not allowed.")); count = mark_failed(ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count, "failed sitelock", player); } return NOTHING; } else if (!Guest(player) && (!Site_Can_Connect(host, player) || !Site_Can_Connect(ip, player))) { if (!Deny_Silent_Site(host, player) && !Deny_Silent_Site(ip, player)) { do_log(LT_CONN, 0, 0, "Connection to %s (Non-GUEST) not allowed from %s (%s)", name, host, ip); strcpy(errbuf, T("Player connections not allowed.")); count = mark_failed(ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count, "failed sitelock", player); } return NOTHING; } /* validate password */ if (!Guest(player)) if (!password_check(player, password)) { /* Increment count of login failures */ ModTime(player)++; check_lastfailed(player, host); count = mark_failed(ip); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count, "invalid password", player); strcpy(errbuf, T("That is not the correct password.")); return NOTHING; } /* If it's a Guest player, and already connected, search the * db for another Guest player to connect them to. */ if (Guest(player)) { /* Enforce guest limit */ player = guest_to_connect(player); if (!GoodObject(player)) { do_log(LT_CONN, 0, 0, "Can't connect to a guest (too many connected)"); strcpy(errbuf, T("Too many guests are connected now.")); queue_event(SYSEVENT, "SOCKET`LOGINFAIL", "%d,%s,%d,%s,#%d", d->descriptor, ip, count_failed(ip), "too many guests", player); return NOTHING; } } if (Suspect_Site(host, player) || Suspect_Site(ip, player)) { do_log(LT_CONN, 0, 0, "Connection from Suspect site. Setting %s(#%d) suspect.", Name(player), player); set_flag_internal(player, "SUSPECT"); } return player; }
/** Set/lock a lock (user interface). * \verbatim * This implements @lock. * \endverbatim * \param player the enactor. * \param name name of object to lock. * \param keyname key to lock the lock to, as a string. * \param type type of lock to lock. */ void do_lock(dbref player, const char *name, const char *keyname, lock_type type) { lock_type real_type; dbref thing; boolexp key; char *sp; /* check for '@lock <object>/<atr>' */ sp = strchr(name, '/'); if (sp) { do_atrlock(player, name, keyname, 0); return; } if (!keyname || !*keyname) { do_unlock(player, name, type); return; } switch (thing = match_result(player, name, NOTYPE, MAT_EVERYTHING)) { case NOTHING: notify(player, T("I don't see what you want to lock!")); return; case AMBIGUOUS: notify(player, T("I don't know which one you want to lock!")); return; default: if (!controls(player, thing)) { notify(player, T("You can't lock that!")); return; } if (IsGarbage(thing)) { notify(player, T("Why would you want to lock garbage?")); return; } break; } key = parse_boolexp(player, keyname, type); /* do the lock */ if (key == TRUE_BOOLEXP) { notify(player, T("I don't understand that key.")); } else { if ((real_type = check_lock_type(player, thing, type)) != NULL) { /* everything ok, do it */ if (add_lock(player, thing, real_type, key, -1)) { if (!AreQuiet(player, thing)) notify_format(player, T("%s(%s) - %s locked."), Name(thing), unparse_dbref(thing), real_type); if (!IsPlayer(thing)) { char lmbuf[1024]; ModTime(thing) = mudtime; snprintf(lmbuf, 1023, "%s lock[#%d]", real_type, player); lmbuf[strlen(lmbuf)+1] = '\0'; set_lmod(thing, lmbuf); } } else { notify(player, T("Permission denied.")); free_boolexp(key); } } else free_boolexp(key); } }