Exemple #1
0
/** Add a lock to an object (primitive).
 * Set the lock type on thing to boolexp.
 * This is a primitive routine, to be called by other routines.
 * It will go somewhat wonky if given a NULL boolexp.
 * It will allocate memory if called with a string that is not already
 * in the lock table.
 * \param player the enactor, for permission checking.
 * \param thing object on which to set the lock.
 * \param type type of lock to set.
 * \param key lock boolexp pointer (should not be NULL!).
 * \param flags lock flags.
 * \retval 0 failure.
 * \retval 1 success.
 */
int
add_lock(dbref player, dbref thing, lock_type type, boolexp key, privbits flags)
{
  lock_list *ll, **t;

  if (!GoodObject(thing)) {
    return 0;
  }

  ll = getlockstruct_noparent(thing, type);

  if (ll) {
    if (!can_write_lock(player, thing, ll)) {
      free_boolexp(key);
      return 0;
    }
    /* We're replacing an existing lock. */
    free_boolexp(ll->key);
    ll->key = key;
    ll->creator = player;
    if (flags != LF_DEFAULT)
      ll->flags = flags;
  } else {
    ll = next_free_lock(Locks(thing));
    if (!ll) {
      /* Oh, this sucks */
      do_log(LT_ERR, 0, 0, "Unable to malloc memory for lock_list!");
    } else {
      lock_type real_type = st_insert(type, &lock_names);
      ll->type = real_type;
      ll->key = key;
      ll->creator = player;
      if (flags == LF_DEFAULT) {
        const lock_list *l2 = get_lockproto(real_type);
        if (l2)
          ll->flags = l2->flags;
        else
          ll->flags = 0;
      } else {
        ll->flags = flags;
      }
      if (!can_write_lock(player, thing, ll)) {
        st_delete(real_type, &lock_names);
        free_boolexp(key);
        return 0;
      }
      t = &Locks(thing);
      while (*t && strcasecmp(L_TYPE(*t), L_TYPE(ll)) < 0)
        t = &L_NEXT(*t);
      L_NEXT(ll) = *t;
      *t = ll;
    }
  }
  return 1;
}
Exemple #2
0
static lock_list *
getlockstruct(dbref thing, lock_type type)
{
  lock_list *ll;
  dbref p = thing, ancestor = NOTHING;
  int cmp, count = 0, ancestor_in_chain = 0;

  if (GoodObject(thing))
    ancestor = Ancestor_Parent(thing);
  do {
    for (; GoodObject(p); p = Parent(p)) {
      if (count++ > 100)
        return NULL;
      if (p == ancestor)
        ancestor_in_chain = 1;
      ll = Locks(p);
      while (ll && L_TYPE(ll)) {
        cmp = strcasecmp(L_TYPE(ll), type);
        if (cmp == 0)
          return (p != thing && (ll->flags & LF_PRIVATE)) ? NULL : ll;
        else if (cmp > 0)
          break;
        ll = ll->next;
      }
    }
    p = ancestor;
  } while (!ancestor_in_chain && !Orphan(thing) && GoodObject(ancestor));
  return NULL;
}
Exemple #3
0
/** Copy the locks from one object to another.
 * \param player the enactor.
 * \param orig the source object.
 * \param clone the destination object.
 */
void
clone_locks(dbref player, dbref orig, dbref clone)
{
  lock_list *ll;
  for (ll = Locks(orig); ll; ll = ll->next) {
    if (!(L_FLAGS(ll) & LF_NOCLONE))
      add_lock(player, clone, L_TYPE(ll), dup_bool(L_KEY(ll)), L_FLAGS(ll));
  }
}
Exemple #4
0
static void
ct_generic(dbref player, dbref i, warn_type flags)
{
    if ((flags & W_LOCK_PROBS)) {
        lock_list *ll;
        for (ll = Locks(i); ll; ll = L_NEXT(ll)) {
            check_lock(player, i, L_TYPE(ll), L_KEY(ll));
        }
    }
}
Exemple #5
0
void
purge_locks(void)
{
  dbref thing;

  for (thing = 0; thing < db_top; thing++) {
    lock_list *ll;
    for (ll = Locks(thing); ll; ll = L_NEXT(ll))
      L_KEY(ll) = cleanup_boolexp(L_KEY(ll));
  }
}
Exemple #6
0
/* 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;

}
Exemple #7
0
/** Add a lock to an object on db load.
 * Set the lock type on thing to boolexp.
 * Used only on db load, when we can't safely test the player's
 * permissions because they're not loaded yet.
 * This is a primitive routine, to be called by other routines.
 * It will go somewhat wonky if given a NULL boolexp.
 * It will allocate memory if called with a string that is not already
 * in the lock table.
 * \param player lock creator.
 * \param thing object on which to set the lock.
 * \param type type of lock to set.
 * \param key lock boolexp pointer (should not be NULL!).
 * \param flags lock flags.
 * \retval 0 failure.
 */
int
add_lock_raw(dbref player, dbref thing, lock_type type, boolexp key,
             privbits flags)
{
  lock_list *ll, **t;
  lock_type real_type = type;

  if (!GoodObject(thing)) {
    return 0;
  }

  ll = next_free_lock(Locks(thing));
  if (!ll) {
    /* Oh, this sucks */
    do_log(LT_ERR, 0, 0, "Unable to malloc memory for lock_list!");
  } else {
    real_type = st_insert(type, &lock_names);
    ll->type = real_type;
    ll->key = key;
    ll->creator = player;
    if (flags == LF_DEFAULT) {
      const lock_list *l2 = get_lockproto(real_type);
      if (l2)
        ll->flags = l2->flags;
      else
        ll->flags = 0;
    } else {
      ll->flags = flags;
    }
    t = &Locks(thing);
    while (*t && strcasecmp(L_TYPE(*t), L_TYPE(ll)) < 0)
      t = &L_NEXT(*t);
    L_NEXT(ll) = *t;
    *t = ll;
  }
  return 1;
}
Exemple #8
0
static lock_list *
getlockstruct_noparent(dbref thing, lock_type type)
{
  lock_list *ll = Locks(thing);
  int cmp;

  while (ll && L_TYPE(ll)) {
    cmp = strcasecmp(L_TYPE(ll), type);
    if (cmp == 0)
      return ll;
    else if (cmp > 0)
      break;
    ll = ll->next;
  }
  return NULL;
}
Exemple #9
0
/** Delete a lock from an object (primitive).
 * Another primitive routine.
 * \param player the enactor, for permission checking.
 * \param thing object on which to remove the lock.
 * \param type type of lock to remove.
 */
int
delete_lock(dbref player, dbref thing, lock_type type)
{
  lock_list *ll, **llp;
  if (!GoodObject(thing)) {
    return 0;
  }
  llp = &(Locks(thing));
  while (*llp && strcasecmp((*llp)->type, type) != 0) {
    llp = &((*llp)->next);
  }
  if (*llp != NULL) {
    if (can_write_lock(player, thing, *llp)) {
      ll = *llp;
      *llp = ll->next;
      free_one_lock_list(ll);
      return 1;
    } else
      return 0;
  } else
    return 1;
}
Exemple #10
0
/** Migrate some number of chunks.
 * The requested amount is only a guideline; the actual amount
 * migrated will be more or less due to always migrating all the
 * attributes, locks, and mail on any given object together.
 * \param amount the suggested number of attributes to migrate.
 */
static void
migrate_stuff(int amount)
{
  static int start_obj = 0;
  static chunk_reference_t **refs = NULL;
  static int refs_size = 0;
  int end_obj;
  int actual;
  ATTR *aptr;
  lock_list *lptr;
  MAIL *mp;

  if (db_top == 0)
    return;

  end_obj = start_obj;
  actual = 0;
  do {
    for (aptr = List(end_obj); aptr; aptr = AL_NEXT(aptr))
      if (aptr->data != NULL_CHUNK_REFERENCE)
        actual++;
    for (lptr = Locks(end_obj); lptr; lptr = L_NEXT(lptr))
      if (L_KEY(lptr) != NULL_CHUNK_REFERENCE)
        actual++;
    if (IsPlayer(end_obj)) {
      for (mp = find_exact_starting_point(end_obj); mp; mp = mp->next)
        if (mp->msgid != NULL_CHUNK_REFERENCE)
          actual++;
    }
    end_obj = (end_obj + 1) % db_top;
  } while (actual < amount && end_obj != start_obj);

  if (actual == 0)
    return;

  if (!refs || actual > refs_size) {
    if (refs)
      mush_free(refs, "migration reference array");
    refs =
      mush_calloc(actual, sizeof(chunk_reference_t *),
                  "migration reference array");
    refs_size = actual;
    if (!refs)
      mush_panic("Could not allocate migration reference array");
  }
#ifdef DEBUG_MIGRATE
  do_rawlog(LT_TRACE, "Migrate asked %d, actual objects #%d to #%d for %d",
            amount, start_obj, (end_obj + db_top - 1) % db_top, actual);
#endif

  actual = 0;
  do {
    for (aptr = List(start_obj); aptr; aptr = AL_NEXT(aptr))
      if (aptr->data != NULL_CHUNK_REFERENCE) {
        refs[actual] = &(aptr->data);
        actual++;
      }
    for (lptr = Locks(start_obj); lptr; lptr = L_NEXT(lptr))
      if (L_KEY(lptr) != NULL_CHUNK_REFERENCE) {
        refs[actual] = &(lptr->key);
        actual++;
      }
    if (IsPlayer(start_obj)) {
      for (mp = find_exact_starting_point(start_obj); mp; mp = mp->next)
        if (mp->msgid != NULL_CHUNK_REFERENCE) {
          refs[actual] = &(mp->msgid);
          actual++;
        }
    }
    start_obj = (start_obj + 1) % db_top;
  } while (start_obj != end_obj);

  chunk_migration(actual, refs);
}
Exemple #11
0
// Clones an object and returns the HS_DBREF of the new clone.
HS_DBREF CHSInterface::CloneThing(HS_DBREF model)
{
    HS_DBREF clone;

#ifdef PENNMUSH                 // No change in code between versions
    clone = new_object();

    // Copy the basic information from the model to the clone.
    memcpy(REFDB(clone), REFDB(model), sizeof(struct object));
    Owner(clone) = Owner(model);
    Name(clone) = NULL;

    // NULL-out some memory pointers we didn't really want copied.
    db[clone].list = NULL;

    // Now copy the pointer information.
    atr_cpy(clone, model);
    Locks(clone) = NULL;
    clone_locks(model, model, clone);
    Zone(clone) = Zone(model);
    Parent(clone) = Parent(model);
    Flags(clone) = clone_flag_bitmask("FLAG", Flags(model));
    set_name(clone, Name(model));
    s_Pennies(clone, Pennies(model));

#ifdef CREATION_TIMES
    /*
     * We give the clone the same modification time that its
     * other clone has, but update the creation time
     */
    db[clone].creation_time = time((time_t *) 0);
#endif

    db[clone].contents = db[clone].location = db[clone].next = NOTHING;
#endif

#if defined(TM3) || defined(MUX)
    clone = create_obj(Owner(model), Typeof(model),
                       Name(model), Pennies(model));

    //atr_free(clone);
    s_Name(clone, Name(model));
    s_Pennies(clone, Pennies(model));
    s_Parent(clone, Parent(model));
#ifdef TM3
    atr_cpy(Owner(clone), clone, model);
    s_Flags(clone, Flags(model));
    s_Flags2(clone, Flags2(model));
    s_Flags3(clone, Flags3(model));
#endif

#ifdef MUX
    atr_cpy(clone, model);
    s_Flags(clone, FLAG_WORD1, Flags(model));
    s_Flags(clone, FLAG_WORD2, Flags2(model));
    s_Flags(clone, FLAG_WORD3, Flags3(model));
    s_Home(clone, Home(model));
#endif
#endif

    return clone;
}