Esempio n. 1
0
// Gets an attribute from an object and stores the value
// in the buffer.  It returns false if the attribute was
// not found.  Otherwise, true.
HS_BOOL8 CHSInterface::AtrGet(int obj, const char *atrname)
{
#ifdef PENNMUSH
    ATTR *a;

    a = atr_get(obj, atrname);
    if (!a)
    {
        return false;
    }

    strcpy_s(m_buffer, atr_value(a));
    return true;
#endif

#if defined(TM3) || defined(MUX)
    char *a;
    a = my_atr_get(obj, atrname);
    if (a && *a)
    {
        strcpy(m_buffer, a);
        return true;
    }
    else
        return false;
#endif
}
Esempio n. 2
0
HS_DBREF CHSInterface::GetLock(int objnum, HS_LOCKTYPE lock)
{
#ifdef PENNMUSH                 // No change in code between versions
    boolexp boolExp = getlock(objnum, Use_Lock);

    if (boolExp == TRUE_BOOLEXP)
    {
        return NOTHING;
    }
    else
    {
        return strtodbref(unparse_boolexp(objnum, boolExp, UB_DBREF));
    }
#endif

#if defined(TM3) || defined(MUX)
    char *value;
    BOOLEXP *key;
    int aowner, aflags;
    dbref lockobj;

#ifdef TM3
    int alen;
    value = atr_get((dbref) objnum, A_LUSE, &aowner, &aflags, &alen);
#else
    value = atr_get((dbref) objnum, A_LUSE, &aowner, &aflags);
#endif
    key = parse_boolexp((dbref) objnum, value, 1);
    free_lbuf(value);
    if (key == TRUE_BOOLEXP)
    {
        free_boolexp(key);
        return NOTHING;
    }
    else
    {
        lockobj = key->thing;
        free_boolexp(key);
        return lockobj;
    }
#endif
}
Esempio n. 3
0
void do_report(dbref executor, dbref caller, dbref enactor, int extra)
{
    UNUSED_PARAMETER(caller);
    UNUSED_PARAMETER(enactor);
    UNUSED_PARAMETER(extra);

    char *buff = alloc_mbuf("do_report");
    int nBin[NPERIODS];
    int i;

    for (i = 0; i < NPERIODS; i++)
    {
        nBin[i] = 0;
    }

    CLinearTimeAbsolute ltaNow, ltaPlayer;
    ltaNow.GetLocal();

    const int PeriodInSeconds = 28800;

    int iPlayer;
    DO_WHOLE_DB(iPlayer)
    {
        if (isPlayer(iPlayer))
        {
            int aowner, aflags;
            char *player_last = atr_get(iPlayer, A_LAST, &aowner, &aflags);

            if (ltaPlayer.SetString(player_last))
            {
                CLinearTimeDelta ltd(ltaPlayer, ltaNow);
                int ltdSeconds = ltd.ReturnSeconds();
                int iBin = ltdSeconds / PeriodInSeconds;
                if (0 <= iBin && iBin < NPERIODS)
                {
                    nBin[iBin]++;
                }
            }
            free_lbuf(player_last);
        }
    }

    int iHour, nSum = 0;
    notify(executor, "Day   Hours     Players  Total");
    for (i = 0, iHour = 0; i < NPERIODS; i++, iHour += 8)
    {
        nSum += nBin[i];
        mux_sprintf(buff, MBUF_SIZE, "%3d %03d - %03d: %6d %6d",
            iHour/24 + 1, iHour, iHour+8, nBin[i], nSum);
        notify(executor, buff);
    }
    free_mbuf(buff);
}
Esempio n. 4
0
char *unparse_class (int x)
{
	ATTR *a;
	static char buffer[20];

	a = atr_get(sdb[x].object, CLASS_ATTR_NAME);
	if (a == NULL)
		return (char *) "#-1 BAD CLASS";

	strncpy(buffer, atr_value(a), sizeof(buffer) - 1);

	return (buffer);
}
Esempio n. 5
0
/* board a ship through the ship object */
void board_ship(dbref player, char *which, char *code)
{
  ATTR *a;
  char *bcode;
  dbref obj, nav, bay;
  int security;
  
  /* find the shipobj */
  obj = match_result(player, which, TYPE_THING, MAT_NEAR_THINGS);
  if (!IsShipObj(obj))
  {
    notify(player, "Can't find that ship.");
    return;
  }
  
  /* see if it's got an HSNAV */
  nav = atr_parse_dbref(obj, "HSNAV");
  if (!IsShip(nav))
  {
    notify(player, "That is not a valid ship object.");
    return;
  }
  
  /* check the boarding code, if necessary */
  security = atr_parse_integer(nav, "SECURITY", 0);
  if (security)
  {
    a = atr_get(nav, "BOARDING_CODE");
    if (a)
    {
      bcode = atr_value(a);
      if (strcmp(bcode, code))
      {
        notify(player, "Invalid boarding code.");
        return;
      }
    }
  }
  
  /* check for a BAY on the nav, otherwise go to the nav's location */
  bay = atr_parse_dbref(nav, "BAY");
  if (!RealGoodObject(bay))
  {
    bay = Location(nav);
  }
  
  atr_add(player, "HSPACE", unparse_dbref(nav), hs_options.space_wiz, 0);
  notify_except(obj, Location(player), player, tprintf("%s boards the %s.", Name(player), Name(obj)), 0);
  notify_except(obj, bay, player, tprintf("%s boards through the main hatch.", Name(player)), 0);
  moveto(player, bay, hs_options.space_wiz, NULL);
}
Esempio n. 6
0
/** Parse object/attribute strings into components.
 * This function takes a string which is of the format obj/attr or attr,
 * and returns the dbref of the object, and a pointer to the attribute.
 * If no object is specified, then the dbref returned is the player's.
 * str is destructively modified. This function is probably underused.
 * \param player the default object.
 * \param str the string to parse.
 * \param thing pointer to dbref of object parsed out of string.
 * \param attrib pointer to pointer to attribute structure retrieved.
 */
void
parse_attrib(dbref player, char *str, dbref *thing, ATTR **attrib)
{
  char *name;

  /* find the object */

  if ((name = strchr(str, '/')) != NULL) {
    *name++ = '\0';
    *thing = noisy_match_result(player, str, NOTYPE, MAT_EVERYTHING);
  } else {
    name = str;
    *thing = player;
  }

  /* find the attribute */
  *attrib = (ATTR *) atr_get(*thing, upcasestr(name));
}
Esempio n. 7
0
int nfy_que(dbref sem, int attr, int key, int count)
{
    int cSemaphore = 1;
    if (attr)
    {
        int   aflags;
        dbref aowner;
        char *str = atr_get(sem, attr, &aowner, &aflags);
        cSemaphore = mux_atol(str);
        free_lbuf(str);
    }

    Notify_Num_Done = 0;
    if (cSemaphore > 0)
    {
        Notify_Key     = key;
        Notify_Sem     = sem;
        Notify_Attr    = attr;
        Notify_Num_Max = count;
        if (  key == NFY_NFY
           || key == NFY_QUIET)
        {
            scheduler.TraverseOrdered(CallBack_NotifySemaphoreFirstOrQuiet);
        }
        else
        {
            scheduler.TraverseUnordered(CallBack_NotifySemaphoreDrainOrAll);
        }
    }

    // Update the sem waiters count.
    //
    if (  NFY_NFY == key
       || NFY_QUIET == key)
    {
        add_to(sem, -count, attr);
    }
    else
    {
        atr_clr(sem, attr);
    }

    return Notify_Num_Done;
}
Esempio n. 8
0
// ---------------------------------------------------------------------------
// add_to: Adjust an object's queue or semaphore count.
//
static int add_to(dbref executor, int am, int attrnum)
{
    int aflags;
    dbref aowner;

    char *atr_gotten = atr_get(executor, attrnum, &aowner, &aflags);
    int num = mux_atol(atr_gotten);
    free_lbuf(atr_gotten);
    num += am;

    char buff[20];
    size_t nlen = 0;
    *buff = '\0';
    if (num)
    {
        nlen = mux_ltoa(num, buff);
    }
    atr_add_raw_LEN(executor, attrnum, buff, nlen);
    return num;
}
Esempio n. 9
0
static void
ct_thing(dbref player, dbref i, warn_type flags)
{
    int lt;

    /* Ignore carried objects */
    if (Location(i) == player)
        return;
    if ((flags & W_THING_DESC) && !atr_get(i, "DESCRIBE"))
        complain(player, i, "thing-desc", T("thing is missing description"));

    if (flags & W_THING_MSGS) {
        lt = warning_lock_type(getlock(i, Basic_Lock));
        if ((lt & W_UNLOCKED) &&
                (!atr_get(i, "OSUCCESS") || !atr_get(i, "ODROP") ||
                 !atr_get(i, "SUCCESS") || !atr_get(i, "DROP")))
            complain(player, i, "thing-msgs",
                     T("possibly unlocked thing missing succ/osucc/drop/odrop"));
        if ((lt & W_LOCKED) && !atr_get(i, "FAILURE"))
            complain(player, i, "thing-msgs",
                     T("possibly locked thing missing fail"));
    }
}
Esempio n. 10
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;
}
Esempio n. 11
0
static void
ct_player(dbref player, dbref i, warn_type flags)
{
    if ((flags & W_PLAYER_DESC) && !atr_get(i, "DESCRIBE"))
        complain(player, i, "my-desc", T("player is missing description"));
}
Esempio n. 12
0
static void
ct_exit(dbref player, dbref i, warn_type flags)
{
    dbref j, src, dst;
    int count = 0;
    int lt;

    /* i must be an exit, must be in a valid room, and must lead to a
     * different room
     * Remember, for exit i, Exits(i) = source room
     * and Location(i) = destination room
     */

    dst = Destination(i);
    if ((flags & W_EXIT_UNLINKED) && (dst == NOTHING))
        complain(player, i, "exit-unlinked",
                 T("exit is unlinked; anyone can steal it"));

    if ((flags & W_EXIT_UNLINKED) && dst == AMBIGUOUS) {
        ATTR *a;
        const char *var = "DESTINATION";
        a = atr_get(i, "DESTINATION");
        if (!a)
            a = atr_get(i, "EXITTO");
        if (a)
            var = "EXITTO";
        if (!a)
            complain(player, i, "exit-unlinked",
                     T("Variable exit has no %s attribute"), var);
        else {
            const char *x = atr_value(a);
            if (!x || !*x)
                complain(player, i, "exit-unlinked",
                         T("Variable exit has empty %s attribute"), var);
        }
    }

    if (!Dark(i)) {
        if (flags & W_EXIT_MSGS) {
            lt = warning_lock_type(getlock(i, Basic_Lock));
            if ((lt & W_UNLOCKED) &&
                    (!atr_get(i, "OSUCCESS") || !atr_get(i, "ODROP") ||
                     !atr_get(i, "SUCCESS")))
                complain(player, i, "exit-msgs",
                         T("possibly unlocked exit missing succ/osucc/odrop"));
            if ((lt & W_LOCKED) && !atr_get(i, "FAILURE"))
                complain(player, i, "exit-msgs",
                         T("possibly locked exit missing fail"));
        }
        if (flags & W_EXIT_DESC) {
            if (!atr_get(i, "DESCRIBE"))
                complain(player, i, "exit-desc", T("exit is missing description"));
        }
    }
    src = Source(i);
    if (!GoodObject(src) || !IsRoom(src))
        return;
    if (src == dst)
        return;
    /* Don't complain about exits linked to HOME or variable exits. */
    if (!GoodObject(dst))
        return;

    for (j = Exits(dst); GoodObject(j); j = Next(j))
        if (Location(j) == src) {
            if (!(flags & W_EXIT_MULTIPLE))
                return;
            else
                count++;
        }
    if ((count == 0) && (flags & W_EXIT_ONEWAY))
        complain(player, i, "exit-oneway", T("exit has no return exit"));
    else if ((count > 1) && (flags & W_EXIT_MULTIPLE))
        complain(player, i, "exit-multiple",
                 T("exit has multiple (%d) return exits"), count);
}
Esempio n. 13
0
static void
ct_room(dbref player, dbref i, warn_type flags)
{
    if ((flags & W_ROOM_DESC) && !atr_get(i, "DESCRIBE"))
        complain(player, i, "room-desc", T("room has no description"));
}
Esempio n. 14
0
File: db_rw.c Progetto: chazu/btmux
static int db_write_object(FILE * f, dbref i, int db_format, int flags)
{
	ATTR *a;
	char *got, *as;
	dbref aowner;
	int ca, aflags, save, j;
	BOOLEXP *tempbool;

	if(!(flags & V_ATRNAME))
		putstring(f, Name(i));
	putref(f, Location(i));
	if(flags & V_ZONE)
		putref(f, Zone(i));
	putref(f, Contents(i));
	putref(f, Exits(i));
	if(flags & V_LINK)
		putref(f, Link(i));
	putref(f, Next(i));
	if(!(flags & V_ATRKEY)) {
		got = atr_get(i, A_LOCK, &aowner, &aflags);
		tempbool = parse_boolexp(GOD, got, 1);
		free_lbuf(got);
		putboolexp(f, tempbool);
		if(tempbool)
			free_bool(tempbool);
	}
	putref(f, Owner(i));
	if(flags & V_PARENT)
		putref(f, Parent(i));
	if(!(flags & V_ATRMONEY))
		putref(f, Pennies(i));
	putref(f, Flags(i));
	if(flags & V_XFLAGS)
		putref(f, Flags2(i));
	if(flags & V_3FLAGS)
		putref(f, Flags3(i));
	if(flags & V_POWERS) {
		putref(f, Powers(i));
		putref(f, Powers2(i));
	}
	/*
	 * write the attribute list 
	 */

	if((!(flags & V_GDBM)) || (mudstate.panicking == 1)) {
		for(ca = atr_head(i, &as); ca; ca = atr_next(&as)) {
			save = 0;
			a = atr_num(ca);
			if(a)
				j = a->number;
			else
				j = -1;

			if(j > 0) {
				switch (j) {
				case A_NAME:
					if(flags & V_ATRNAME)
						save = 1;
					break;
				case A_LOCK:
					if(flags & V_ATRKEY)
						save = 1;
					break;
				case A_LIST:
				case A_MONEY:
					break;
				default:
					save = 1;
				}
			}
			if(save) {
				got = atr_get_raw(i, j);
				fprintf(f, ">%d\n", j);
				putstring(f, got);
			}
		}
		fprintf(f, "<\n");
	}
	return 0;
}
Esempio n. 15
0
static void give_money (dbref giver, dbref recipient, int key, int amount)
{
dbref	aowner;
int	cost, pcost, rcost, aflags, dpamount;
char	*str;

	/* do amount consistency check */

	if (amount < 0 && ((!Builder(giver) && !HasPriv(giver,recipient,POWER_STEAL,POWER3,NOTHING)) ||
				DePriv(giver,recipient,DP_STEAL,POWER6,NOTHING))) {
		notify(giver,
			unsafe_tprintf("You look through your pockets. Nope, no negative %s.",
				mudconf.many_coins));
		return;
	}

	if (!amount) {
		notify(giver,
			unsafe_tprintf("You must specify a positive number of %s.",
							mudconf.many_coins));
		return;
	}

	dpamount = 0;
	if (amount < 0) 
	  dpamount = DePriv(giver,NOTHING,DP_NOSTEAL,POWER7,POWER_LEVEL_NA);
	else
	  dpamount = DePriv(giver,NOTHING,DP_NOGOLD,POWER7,POWER_LEVEL_NA);
	if (dpamount) {
	  if (DPShift(giver))
	    dpamount--;
	  dpamount = mudconf.money_limit[dpamount];
	}
	else
	  dpamount = -1;
	if (!Admin(Owner(giver))) {
		if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount > mudconf.paylimit)) {
			notify(giver,
				unsafe_tprintf("That player doesn't need that many %s!",
					mudconf.many_coins));
			return;
		}
		if ((Typeof(recipient) != TYPE_PLAYER) && (!could_doit(giver, recipient, A_LUSE,1))) {
			notify(giver,
				unsafe_tprintf("%s won't take your money.",
					Name(recipient)));
			return;
		}
	}

	str = atr_get(Owner(giver), A_PAYLIM, &aowner, &aflags);
	pcost = atoi(str);
	free_lbuf(str);
	if (!Immortal(Owner(giver)) && pcost) {
		if ((Typeof(recipient) == TYPE_PLAYER) && (amount > 0) &&
			 (Pennies(recipient) + amount > pcost)) {
			notify(giver,
				unsafe_tprintf("That player doesn't need that many %s!",
					mudconf.many_coins));
			return;
		}
		else if (Pennies(recipient) + amount < (-pcost)) {
			notify(giver,"That player doesn't need that much debt!");
			return;
		}
	}
        str = atr_get(Owner(recipient), A_RECEIVELIM, &aowner, &aflags);
        rcost = atoi(str);
        free_lbuf(str);
	if (!Immortal(Owner(giver)) && rcost) {
		if ((Typeof(recipient) == TYPE_PLAYER) && (amount > 0) &&
			 (Pennies(recipient) + amount > rcost)) {
			notify(giver,
				unsafe_tprintf("That player doesn't need that many %s!",
					mudconf.many_coins));
			return;
		}
		else if (Pennies(recipient) + amount < (-rcost)) {
			notify(giver,"That player doesn't need that much debt!");
			return;
		}
	}

	if (!Immortal(Owner(giver))) {
	  if (dpamount >= 0) {
	    if (amount > 0) {
	      if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount > dpamount)) {
		notify(giver,
			unsafe_tprintf("That player doesn't need that many %s!",
				mudconf.many_coins));
		return;
	      }
	      else if (amount > dpamount) {
		notify(giver, "Permission denied.");
		return;
	      }
	    }
	    else {
	      if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount < (-dpamount))) {
		notify(giver,
			unsafe_tprintf("That player doesn't need that many %s!",
				mudconf.many_coins));
		return;
	      }
	      else if (amount < (-dpamount)) {
		notify(giver, "Permission denied.");
		return;
	      }
	    }
	  }
	}

	/* try to do the give */

	if (!payfor_give(giver, amount)) {
		notify(giver,
			unsafe_tprintf("You don't have that many %s to give!",
				mudconf.many_coins));
		return;
	}

	/* Find out cost if an object */

	if (Typeof(recipient) == TYPE_THING) {
		str = atr_pget(recipient, A_COST, &aowner, &aflags);
		cost = atoi(str);
		free_lbuf(str);

		/* Can't afford it? */

		if (amount < cost) {
			notify(giver, "Feeling poor today?");
			giveto(giver, amount, NOTHING);
			return;
		}

		/* Negative cost */

		if (cost < 0) {
			return;
		}
	} else {
		cost = amount;
	}

	if (!(key & GIVE_QUIET)) {
		if (amount == 1) {
			notify(giver,
				unsafe_tprintf("You give a %s to %s.",
					mudconf.one_coin, Name(recipient)));
			notify_with_cause(recipient, giver,
				unsafe_tprintf("%s gives you a %s.", Name(giver),
					mudconf.one_coin));
		} else {
			notify(giver,
				unsafe_tprintf("You give %d %s to %s.", amount,
					mudconf.many_coins, Name(recipient)));
			notify_with_cause(recipient, giver,
				unsafe_tprintf("%s gives you %d %s.", Name(giver),
				amount, mudconf.many_coins));
		}
	}
	else {
		if (amount == 1) {
			notify(giver,
				unsafe_tprintf("You give a %s to %s. (quiet)",
					mudconf.one_coin, Name(recipient)));
		}
		else {
			notify(giver,
				unsafe_tprintf("You give %d %s to %s. (quiet)",
					amount, mudconf.many_coins,
					Name(recipient)));
		}
	}

	/* Report change given */

	if((amount - cost) == 1) {
        	notify(giver,
			unsafe_tprintf("You get 1 %s in change.", mudconf.one_coin));
		giveto(giver, 1, NOTHING);
	} else if (amount != cost) {
		notify(giver,
			unsafe_tprintf("You get %d %s in change.",
				(amount - cost), mudconf.many_coins));
		giveto(giver, (amount - cost), NOTHING);
	}
	if (pcost && (Pennies(Owner(recipient)) + cost > pcost)) {
	  pcost = pcost - Pennies(Owner(recipient));
	  if (pcost < 0)
	    pcost = 0;
	}
	else
	  pcost = cost;
	if (!giveto(recipient, pcost, giver))
		giveto(giver, cost, NOTHING);

	/* Transfer the money and run PAY attributes */
        /* Rooms should not kick off the PAY attribute */

        if ( !isRoom(giver) )
	   did_it(giver, recipient, A_PAY, NULL, A_OPAY, NULL, A_APAY,
	   	  (char **)NULL, 0);
	return;
}
Esempio n. 16
0
/* leave a flying ship through the escape pod */
void emergency_eject(dbref player)
{
  dbref nav, pad;
  hship *ship;
  hcelestial *cel, *min_cel;
  ATTR *a;
  char *r, *s;
  char buff[512];
  double dist, min_dist;
  dbref min_pad;
  hship *sptr, *min_ship;
  
  /* check for a BAY */
  a = atr_get(Location(player), "BAY");
  if (!a)
  {
    /* no BAY, see if we're next to the nav console */
    ship = find_ship(player);
    if (ship)
    {
      if (Location(ship->objnum) != Location(player))
      {
        notify(player, "You can't eject from here.");
        return;
      }
    }
  }
  else
  {
    /* there's a BAY, see if the ship is valid */
    nav = parse_dbref(atr_value(a));
    if (!IsShip(nav))
    {
      notify(player, "You can't eject from here.");
      return;
    }

    ship = find_ship_by_nav(nav);
  }
  
  if (!ship)
  {
    notify(player, "You can't eject from here.");
    return;
  }

  /* only eject when flying, not when landing or docking */
  if (!ship->uid || ship->landed || ship->docked)
  {
    notify(player, "You may only eject while flying.");
    return;
  }
  
  /* find a planet with a drop pad */
  min_pad = NOTHING;
  min_dist = 1000000.0;
  min_cel = NULL;
  for (cel = ship->uid->head_celestial; cel; cel = cel->next)
  {
    if (!HasFlag(cel->type, HS_PLANET))
      continue;
    
    pad = atr_parse_dbref(cel->objnum, "DROPPADS");
    if (!RealGoodObject(pad))
      continue;

    dist = ship_celestial_distance(ship, cel);

    if (dist < min_dist)
    {
      min_dist = dist;
      min_pad = pad;
      min_cel = cel;
    }
  }
  
  min_ship = NULL;
  for (sptr = ship->uid->head_ship; sptr; sptr = sptr->next)
  {
    if (min_cel)
      break;
    
    if (!HasFlag(sptr->type, HS_STATION | HS_CAPITAL))
      continue;
    
    pad = atr_parse_dbref(sptr->objnum, "BAY");
    if (!RealGoodObject(pad))
      continue;
    
    dist = ship_distance(ship, sptr);

    if (dist < min_dist)
    {
      min_cel = NULL;
      min_ship = sptr;
      min_dist = dist;
      min_pad = pad;
    }
  }
  
  if (!RealGoodObject(min_pad))
  {
    notify(player, "There is nowhere to eject to!");
    return;
  }

  /* finish up by setting HSPACE and notifying everybody of the move */
  if (min_ship)
  {
    atr_add(player, "HSPACE", unparse_dbref(min_ship->objnum), hs_options.space_wiz, 0);
  }
  else if (min_cel)
  {
    atr_add(player, "HSPACE", unparse_dbref(min_cel->objnum), hs_options.space_wiz, 0);
  }
  else
  {
    SPACEWALL("Weird problem in eject.");
    notify(player, "Bad space object. Contact an administrator.");
    return;
  }

  notify_except(Location(player), Location(player), player, tprintf("%s ejects in an emergency escape pod!", Name(player)), 0);
  notify_except(min_pad, min_pad, player, tprintf("%s crash lands in an emergency escape pod!", Name(player)), 0);
  if (min_ship)
  {
    notify_consoles(min_ship, tprintf("%s%s-%s Emergency ejection pod automatically tractored into the docking back.",
          ANSI_HILITE, ANSI_GREEN, ANSI_NORMAL));
  }
  moveto(player, min_pad, hs_options.space_wiz, NULL);
}
Esempio n. 17
0
File: eval.c Progetto: gtaylor/btmux
void exec(char *buff, char **bufc, int tflags, dbref player, dbref cause,
		  int eval, char **dstr, char *cargs[], int ncargs)
{
#define	NFARGS	30
	char *fargs[NFARGS];
	char *preserve[MAX_GLOBAL_REGS];
	char *tstr, *tbuf, *tbufc, *savepos, *atr_gotten, *start, *oldp, *savestr;
	char savec, ch, *str;
	char *realbuff = NULL, *realbp = NULL;
	dbref aowner;
	int at_space, nfargs, gender, i, j, alldone, feval; long aflags;
	int is_trace, is_top, save_count;
	int ansi;
	FUN *fp;
	UFUN *ufp;

	static const char *subj[5] = { "", "it", "she", "he", "they" };
	static const char *poss[5] = { "", "its", "her", "his", "their" };
	static const char *obj[5] = { "", "it", "her", "him", "them" };
	static const char *absp[5] = { "", "its", "hers", "his", "theirs" };

	if(*dstr == NULL)
		return;

	// dprintk("%d/%s", player, *dstr);

	at_space = 1;
	gender = -1;
	alldone = 0;
	ansi = 0;

	is_trace = Trace(player) && !(eval & EV_NOTRACE);
	is_top = 0;

	/* Extend the buffer if we need to. */

	if(((*bufc) - buff) > (LBUF_SIZE - SBUF_SIZE)) {
		realbuff = buff;
		realbp = *bufc;
		buff = (char *) malloc(LBUF_SIZE);
		*bufc = buff;
	}

	oldp = start = *bufc;

	/*
	 * If we are tracing, save a copy of the starting buffer 
	 */

	savestr = NULL;
	if(is_trace) {
		is_top = tcache_empty();
		savestr = alloc_lbuf("exec.save");
		StringCopy(savestr, *dstr);
	}
	while (**dstr && !alldone) {
		switch (**dstr) {
		case ' ':
			/*
			 * A space.  Add a space if not compressing or if * * 
			 * 
			 * *  * * previous char was not a space 
			 */

			if(!(mudconf.space_compress && at_space) ||
			   (eval & EV_NO_COMPRESS)) {
				safe_chr(' ', buff, bufc);
				at_space = 1;
			}
			break;
		case '\\':
			/*
			 * General escape.  Add the following char without *
			 * * * * special processing 
			 */

			at_space = 0;
			(*dstr)++;
			if(**dstr)
				safe_chr(**dstr, buff, bufc);
			else
				(*dstr)--;
			break;
		case '[':
			/*
			 * Function start.  Evaluate the contents of the * *
			 * * * square brackets as a function.  If no closing
			 * * * * * bracket, insert the [ and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			if(eval & EV_NOFCHECK) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
				break;
			}
			tbuf = parse_to(dstr, ']', 0);
			if(*dstr == NULL) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
			} else {
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval | EV_FCHECK | EV_FMAND), &str, cargs, ncargs);
				(*dstr)--;
			}
			break;
		case '{':
			/*
			 * Literal start.  Insert everything up to the * * *
			 * * terminating } without parsing.  If no closing *
			 * * * * brace, insert the { and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			tbuf = parse_to(dstr, '}', 0);
			if(*dstr == NULL) {
				safe_chr('{', buff, bufc);
				*dstr = tstr;
			} else {
				if(!(eval & EV_STRIP)) {
					safe_chr('{', buff, bufc);
				}
				/*
				 * Preserve leading spaces (Felan) 
				 */

				if(*tbuf == ' ') {
					safe_chr(' ', buff, bufc);
					tbuf++;
				}
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval & ~(EV_STRIP | EV_FCHECK)), &str, cargs, ncargs);
				if(!(eval & EV_STRIP)) {
					safe_chr('}', buff, bufc);
				}
				(*dstr)--;
			}
			break;
		case '%':
			/*
			 * Percent-replace start.  Evaluate the chars * * *
			 * following * and perform the appropriate * * *
			 * substitution. 
			 */

			at_space = 0;
			(*dstr)++;
			savec = **dstr;
			savepos = *bufc;
			switch (savec) {
			case '\0':			/*
								 * Null - all done 
								 */
				(*dstr)--;
				break;
			case '|':			/* piped command output */
				safe_str(mudstate.pout, buff, bufc);
				break;
			case '%':			/*
								 * Percent - a literal % 
								 */
				safe_chr('%', buff, bufc);
				break;
			case 'c':
			case 'C':
				(*dstr)++;
				if(!**dstr)
					(*dstr)--;
				ansi = 1;
				switch (**dstr) {
				case 'h':		/*
								 * hilite 
								 */
					safe_str(ANSI_HILITE, buff, bufc);
					break;
				case 'i':		/*
								 * inverse 
								 */
					safe_str(ANSI_INVERSE, buff, bufc);
					break;
				case 'f':		/*
								 * flash 
								 */
					safe_str(ANSI_BLINK, buff, bufc);
					break;
				case 'u':		/* underline */
					safe_str(ANSI_UNDER, buff, bufc);
					break;
				case 'n':		/*
								 * normal 
								 */
					safe_str(ANSI_NORMAL, buff, bufc);
					ansi = 0;
					break;
				case 'x':		/*
								 * black fg 
								 */
					safe_str(ANSI_BLACK, buff, bufc);
					break;
				case 'r':		/*
								 * red fg 
								 */
					safe_str(ANSI_RED, buff, bufc);
					break;
				case 'g':		/*
								 * green fg 
								 */
					safe_str(ANSI_GREEN, buff, bufc);
					break;
				case 'y':		/*
								 * yellow fg 
								 */
					safe_str(ANSI_YELLOW, buff, bufc);
					break;
				case 'b':		/*
								 * blue fg 
								 */
					safe_str(ANSI_BLUE, buff, bufc);
					break;
				case 'm':		/*
								 * magenta fg 
								 */
					safe_str(ANSI_MAGENTA, buff, bufc);
					break;
				case 'c':		/*
								 * cyan fg 
								 */
					safe_str(ANSI_CYAN, buff, bufc);
					break;
				case 'w':		/*
								 * white fg 
								 */
					safe_str(ANSI_WHITE, buff, bufc);
					break;
				case 'X':		/*
								 * black bg 
								 */
					safe_str(ANSI_BBLACK, buff, bufc);
					break;
				case 'R':		/*
								 * red bg 
								 */
					safe_str(ANSI_BRED, buff, bufc);
					break;
				case 'G':		/*
								 * green bg 
								 */
					safe_str(ANSI_BGREEN, buff, bufc);
					break;
				case 'Y':		/*
								 * yellow bg 
								 */
					safe_str(ANSI_BYELLOW, buff, bufc);
					break;
				case 'B':		/*
								 * blue bg 
								 */
					safe_str(ANSI_BBLUE, buff, bufc);
					break;
				case 'M':		/*
								 * magenta bg 
								 */
					safe_str(ANSI_BMAGENTA, buff, bufc);
					break;
				case 'C':		/*
								 * cyan bg 
								 */
					safe_str(ANSI_BCYAN, buff, bufc);
					break;
				case 'W':		/*
								 * white bg 
								 */
					safe_str(ANSI_BWHITE, buff, bufc);
					break;
				default:
					safe_chr(**dstr, buff, bufc);
				}
				break;
			case 'r':			/*
								 * Carriage return 
								 */
			case 'R':
				safe_str((char *) "\r\n", buff, bufc);
				break;
			case 't':			/*
								 * Tab 
								 */
			case 'T':
				safe_chr('\t', buff, bufc);
				break;
			case 'B':			/*
								 * Blank 
								 */
			case 'b':
				safe_chr(' ', buff, bufc);
				break;
			case '0':			/*
								 * Command argument number N 
								 */
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				i = (**dstr - '0');
				if((i < ncargs) && (cargs[i] != NULL))
					safe_str(cargs[i], buff, bufc);
				break;
			case 'V':			/*
								 * Variable attribute 
								 */
			case 'v':
				(*dstr)++;
				ch = ToUpper(**dstr);
				if(!**dstr)
					(*dstr)--;
				if((ch < 'A') || (ch > 'Z'))
					break;
				i = 100 + ch - 'A';
				atr_gotten = atr_pget(player, i, &aowner, &aflags);
				safe_str(atr_gotten, buff, bufc);
				free_lbuf(atr_gotten);
				break;
			case 'Q':
			case 'q':
				(*dstr)++;
				i = (**dstr - '0');
				if((i >= 0) && (i <= 9) && mudstate.global_regs[i]) {
					safe_str(mudstate.global_regs[i], buff, bufc);
				}
				if(!**dstr)
					(*dstr)--;
				break;
			case 'O':			/*
								 * Objective pronoun 
								 */
			case 'o':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) obj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'P':			/*
								 * Personal pronoun 
								 */
			case 'p':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) poss[gender], buff, bufc);
				}
				break;
			case 'S':			/*
								 * Subjective pronoun 
								 */
			case 's':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) subj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'A':			/*
								 * Absolute posessive 
								 */
			case 'a':			/*
								 * idea from Empedocles 
								 */
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) absp[gender], buff, bufc);
				}
				break;
			case '#':			/*
								 * Invoker DB number 
								 */
				tbuf = alloc_sbuf("exec.invoker");
				sprintf(tbuf, "#%ld", cause);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case '!':			/*
								 * Executor DB number 
								 */
				tbuf = alloc_sbuf("exec.executor");
				sprintf(tbuf, "#%ld", player);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case 'N':			/*
								 * Invoker name 
								 */
			case 'n':
				safe_str(Name(cause), buff, bufc);
				break;
			case 'L':			/*
								 * Invoker location db# 
								 */
			case 'l':
				if(!(eval & EV_NO_LOCATION)) {
					tbuf = alloc_sbuf("exec.exloc");
					sprintf(tbuf, "#%ld", where_is(cause));
					safe_str(tbuf, buff, bufc);
					free_sbuf(tbuf);
				}

				break;
			default:			/*
								 * Just copy 
								 */
				safe_chr(**dstr, buff, bufc);
			}
			if(isupper(savec))
				*savepos = ToUpper(*savepos);
			break;
		case '(':
			/*
			 * Arglist start.  See if what precedes is a function. If so,
			 * execute it if we should.
			 */

			at_space = 0;
			if(!(eval & EV_FCHECK)) {
				safe_chr('(', buff, bufc);
				break;
			}
			/*
			 * Load an sbuf with an uppercase version of the func name, and
			 * see if the func exists.  Trim trailing spaces from the name
			 * if configured.
			 */

			**bufc = '\0';
			tbufc = tbuf = alloc_sbuf("exec.tbuf");
			safe_sb_str(oldp, tbuf, &tbufc);
			*tbufc = '\0';
			if(mudconf.space_compress) {
				while ((--tbufc >= tbuf) && isspace(*tbufc));
				tbufc++;
				*tbufc = '\0';
			}
			for(tbufc = tbuf; *tbufc; tbufc++)
				*tbufc = ToLower(*tbufc);
			fp = (FUN *) hashfind(tbuf, &mudstate.func_htab);

			/*
			 * If not a builtin func, check for global func 
			 */

			ufp = NULL;
			if(fp == NULL) {
				ufp = (UFUN *) hashfind(tbuf, &mudstate.ufunc_htab);
			}
			/*
			 * Do the right thing if it doesn't exist 
			 */

			if(!fp && !ufp) {
				if(eval & EV_FMAND) {
					*bufc = oldp;
					safe_str((char *) "#-1 FUNCTION (", buff, bufc);
					safe_str(tbuf, buff, bufc);
					safe_str((char *) ") NOT FOUND", buff, bufc);
					alldone = 1;
				} else {
					safe_chr('(', buff, bufc);
				}
				free_sbuf(tbuf);
				eval &= ~EV_FCHECK;
				break;
			}
			free_sbuf(tbuf);

			/*
			 * Get the arglist and count the number of args * Neg 
			 * 
			 * *  * *  * * # of args means catenate subsequent
			 * args 
			 */

			if(ufp)
				nfargs = NFARGS;
			else if(fp->nargs < 0)
				nfargs = -fp->nargs;
			else
				nfargs = NFARGS;
			tstr = *dstr;
			if(fp && (fp->flags & FN_NO_EVAL))
				feval = (eval & ~EV_EVAL) | EV_STRIP_ESC;
			else
				feval = eval;
			*dstr =
				parse_arglist(player, cause, *dstr + 1, ')', feval, fargs,
							  nfargs, cargs, ncargs);

			/*
			 * If no closing delim, just insert the '(' and * * * 
			 * 
			 * * continue normally 
			 */

			if(!*dstr) {
				*dstr = tstr;
				safe_chr(**dstr, buff, bufc);
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * Count number of args returned 
			 */

			(*dstr)--;
			j = 0;
			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					j = i + 1;
			nfargs = j;

			/*
			 * If it's a user-defined function, perform it now. 
			 */

			if(ufp) {
				mudstate.func_nest_lev++;
				if(!check_access(player, ufp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else {
					tstr = atr_get(ufp->obj, ufp->atr, &aowner, &aflags);
					if(ufp->flags & FN_PRIV)
						i = ufp->obj;
					else
						i = player;
					str = tstr;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(!mudstate.global_regs[j])
								preserve[j] = NULL;
							else {
								preserve[j] = alloc_lbuf("eval_regs");
								StringCopy(preserve[j],
										   mudstate.global_regs[j]);
							}
						}
					}

					exec(buff, &oldp, 0, i, cause, feval, &str, fargs,
						 nfargs);
					*bufc = oldp;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(preserve[j]) {
								if(!mudstate.global_regs[j])
									mudstate.global_regs[j] =
										alloc_lbuf("eval_regs");
								StringCopy(mudstate.global_regs[j],
										   preserve[j]);
								free_lbuf(preserve[j]);
							} else {
								if(mudstate.global_regs[j])
									*(mudstate.global_regs[i]) = '\0';
							}
						}
					}

					free_lbuf(tstr);
				}

				/*
				 * Return the space allocated for the args 
				 */

				mudstate.func_nest_lev--;
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * If the number of args is right, perform the func.
			 * Otherwise return an error message.  Note
			 * that parse_arglist returns zero args as one
			 * null arg, so we have to handle that case
			 * specially. 
			 */

			if((fp->nargs == 0) && (nfargs == 1)) {
				if(!*fargs[0]) {
					free_lbuf(fargs[0]);
					fargs[0] = NULL;
					nfargs = 0;
				}
			}
			if((nfargs == fp->nargs) || (nfargs == -fp->nargs) ||
			   (fp->flags & FN_VARARGS)) {

				/*
				 * Check recursion limit 
				 */

				mudstate.func_nest_lev++;
				mudstate.func_invk_ctr++;
				if(mudstate.func_nest_lev >= mudconf.func_nest_lim) {
					safe_str("#-1 FUNCTION RECURSION LIMIT EXCEEDED", buff,
							 bufc);
				} else if(mudstate.func_invk_ctr == mudconf.func_invk_lim) {
					safe_str("#-1 FUNCTION INVOCATION LIMIT EXCEEDED",
							 buff, bufc);
				} else if(!check_access(player, fp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else if(mudstate.func_invk_ctr < mudconf.func_invk_lim) {
					fp->fun(buff, &oldp, player, cause, fargs, nfargs,
							cargs, ncargs);
					*bufc = oldp;
				} else {
					**bufc = '\0';
				}
				mudstate.func_nest_lev--;
			} else {
				*bufc = oldp;
				tstr = alloc_sbuf("exec.funcargs");
				sprintf(tstr, "%d", fp->nargs);
				safe_str((char *) "#-1 FUNCTION (", buff, bufc);
				safe_str((char *) fp->name, buff, bufc);
				safe_str((char *) ") EXPECTS ", buff, bufc);
				safe_str(tstr, buff, bufc);
				safe_str((char *) " ARGUMENTS", buff, bufc);
				free_sbuf(tstr);
			}

			/*
			 * Return the space allocated for the arguments 
			 */

			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					free_lbuf(fargs[i]);
			eval &= ~EV_FCHECK;
			break;
		default:
			/*
			 * A mundane character.  Just copy it 
			 */

			at_space = 0;
			safe_chr(**dstr, buff, bufc);
		}
		(*dstr)++;
	}

	/*
	 * If we're eating spaces, and the last thing was a space, eat it
	 * up. Complicated by the fact that at_space is initially
	 * true. So check to see if we actually put something in the
	 * buffer, too. 
	 */

	if(mudconf.space_compress && at_space && !(eval & EV_NO_COMPRESS)
	   && (start != *bufc))
		(*bufc)--;

	/*
	 * The ansi() function knows how to take care of itself. However, 
	 * if the player used a %c sub in the string, and hasn't yet
	 * terminated the color with a %cn yet, we'll have to do it for 
	 * them. 
	 */

	if(ansi == 1)
		safe_str(ANSI_NORMAL, buff, bufc);

	**bufc = '\0';

	/*
	 * Report trace information 
	 */

	if(realbuff) {
		**bufc = '\0';
		*bufc = realbp;
		safe_str(buff, realbuff, bufc);
		free(buff);
		buff = realbuff;
	}

	if(is_trace) {
		tcache_add(savestr, start);
		save_count = tcache_count - mudconf.trace_limit;;
		if(is_top || !mudconf.trace_topdown)
			tcache_finish(player);
		if(is_top && (save_count > 0)) {
			tbuf = alloc_mbuf("exec.trace_diag");
			sprintf(tbuf, "%d lines of trace output discarded.", save_count);
			notify(player, tbuf);
			free_mbuf(tbuf);
		}
	}
}
Esempio n. 18
0
/** Attempt to register a new player at the connect screen.
 * If registration is allowed, a new player object is created with
 * a random password which is emailed to the registering player.
 * \param name name of player to register.
 * \param email email address to send registration details.
 * \param host host from which registration is being attempted.
 * \param ip ip address from which registration is being attempted.
 * \return dbref of created player or NOTHING if creation failed.
 */
dbref
email_register_player(DESC *d, const char *name, const char *email,
                      const char *host, const char *ip)
{
  char *p;
  char passwd[20];
  static char elems[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  int i, len;
  bool resend = 0;
  dbref player = NOTHING;
  FILE *fp;
  size_t NELEMS = sizeof(elems) - 1;
  char sbuff[260];

  if (!check_fails(ip)) {
    return NOTHING;
  }

  if (strlen(options.sendmail_prog) == 0)
    return NOTHING;

  if (!ok_player_name(name, NOTHING, NOTHING)) {
    /* Check for re-registration request */
    player = lookup_player(name);
    if (GoodObject(player)) {
      ATTR *a;
      a = atr_get(player, "LASTLOGOUT");
      if (!a) {
        a = atr_get(player, "REGISTERED_EMAIL");
        if (a && !strcasecmp(atr_value(a), email))
          resend = 1;
      }
    }
    if (!resend) {
      do_log(LT_CONN, 0, 0, "Failed registration (bad name) from %s", host);
      queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s",
                  d->descriptor, ip, mark_failed(ip), "register: bad name",
                  name);
      return NOTHING;
    }
  }
  if (!resend) {
    /* Make sure that the email address is kind of valid. A valid
     * address must contain a @. Let the mailer sort it out beyond
     * that.  Also, to prevent someone from using the MUSH to mailbomb
     * another site, let's make sure that the site to which the user
     * wants the email sent is also allowed to use the register
     * command.  If there's an @, we check whatever's after the last @
     * (since @foo.bar:user@host is a valid email).
     */
    if ((p = strrchr(email, '@'))) {
      p++;
      if (!Site_Can_Register(p)) {
        if (!Deny_Silent_Site(p, AMBIGUOUS)) {
          do_log(LT_CONN, 0, 0,
                 "Failed registration (bad site in email: %s) from %s", email,
                 host);
          queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s",
                      d->descriptor, ip, mark_failed(ip),
                      "register: bad site in email", name);
        }
        return NOTHING;
      }
    } else {
      if (!Deny_Silent_Site(host, AMBIGUOUS)) {
        do_log(LT_CONN, 0, 0, "Failed registration (bad email: %s) from %s",
               email, host);
        queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s",
                    d->descriptor, ip, mark_failed(ip),
                    "register: sitelocked host", name);
      }
      return NOTHING;
    }

    if (DBTOP_MAX && (db_top >= DBTOP_MAX + 1) && (first_free == NOTHING)) {
      /* Oops, out of db space! */
      do_log(LT_CONN, 0, 0, "Failed registration (no db space) from %s", host);
      queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s",
                  d->descriptor, ip, count_failed(ip),
                  "register: no db space left to create!", name);
      return NOTHING;
    }
  }

  /* Come up with a random password of length 7-12 chars */
  len = get_random_u32(7, 12);
  for (i = 0; i < len; i++)
    passwd[i] = elems[get_random_u32(0, NELEMS - 1)];
  passwd[len] = '\0';

  /* If we've made it here, we can send the email and create the
   * character. Email first, since that's more likely to go bad.
   * Some security precautions we'll take:
   *  1) We'll use sendmail -t, so we don't pass user-given values to a shell.
   *  2) We'll cross our fingers and hope nobody uses this to spam.
   */

  release_fd();
  snprintf(sbuff, sizeof sbuff, "%s -t", options.sendmail_prog);
  if ((fp = popen(sbuff, "w")) == NULL) {
    do_log(LT_CONN, 0, 0,
           "Failed registration of %s by %s: unable to open sendmail", name,
           email);
    queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s,%d",
                d->descriptor, ip, count_failed(ip),
                "register: Unable to open sendmail!", name, 1);
    reserve_fd();
    return NOTHING;
  }
  fprintf(fp, "Subject: ");
  fprintf(fp, T("[%s] Registration of %s\n"), MUDNAME, name);
  fprintf(fp, "To: %s\n", email);
  fprintf(fp, "Precedence: junk\n");
  fprintf(fp, "\n");
  fprintf(fp, T("This is an automated message.\n"));
  fprintf(fp, "\n");
  fprintf(fp, T("Your requested player, %s, has been created.\n"), name);
  fprintf(fp, T("The password is %s\n"), passwd);
  fprintf(fp, "\n");
  fprintf(fp, T("To access this character, connect to %s and type:\n"),
          MUDNAME);
  fprintf(fp, "\tconnect \"%s\" %s\n", name, passwd);
  fprintf(fp, "\n");
  i = pclose(fp);
  reserve_fd();

  if (i != 0) {
    /* Mailer exited with an error code. Log it. */
    do_rawlog(
      LT_CONN,
      "When attempting to email a password to a newly registered player,\n"
      "\tthe mailer exited with error code %d.\n"
      "\t(Check /usr/include/sysexits.h if present for the meaning.)",
      i);
    queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s,%d",
                d->descriptor, ip, count_failed(ip),
                "register: Unable to send email", name, i);
    return NOTHING;
  } else if (resend) {
    /* Reset the password */
    (void) atr_add(player, pword_attr, password_hash(passwd, NULL), GOD, 0);
    return player;
  } else {
    /* Ok, all's well, make a player */
    player = make_player(name, passwd, host, ip);
    queue_event(SYSEVENT, "PLAYER`CREATE", "%s,%s,%s,%d,%s",
                unparse_objid(player), name, "register", d->descriptor, email);
    (void) atr_add(player, "REGISTERED_EMAIL", email, GOD, 0);
    return player;
  }
}
Esempio n. 19
0
/* send a standard radio communication */
void send_com(dbref from, char *arg_left, char *arg_right)
{
  dbref com, obj;
  hship *ship;
  hcelestial *cel;
  huniverse *uid;
  
  double xmit, rcv;
  char contact[32];
  char *r, *s;
  char buff[128];
  ATTR *a;
  double sx, sy, sz, tx, ty, tz, dist;
  char pre[128];
  char *mesg;
  int sent_to_from, send_to_com;
  
  if (!IsComm(from))
  {
    notify(from, "You do not have the HS_COMM flag.");
    return;
  }
  
  uid = NULL;
  obj = atr_parse_dbref(from, "HSPACE");
  if (!RealGoodObject(obj))
  {
    notify(from, "You do not have a valid space id. Board, disembark, eject, or man a console.");
    return;
  }
  
  if (IsShip(obj))
  {
    ship = find_ship_by_nav(obj);
    if (!ship)
    {
      notify(from, "Your space id is not a valid ship.");
      return;
    }
    
    if (ship->uid)
    {
      sx = ship->x;
      sy = ship->y;
      sz = ship->z;
      uid = ship->uid;
    }
    else if (ship->landed)
    {
      sx = ship->landed->x;
      sy = ship->landed->y;
      sz = ship->landed->z;
      uid = ship->landed->uid;
    }
    else if (ship->docked)
    {
      sx = ship->docked->x;
      sy = ship->docked->y;
      sz = ship->docked->z;
      uid = ship->docked->uid;
    }
    
    strncpy(contact, ship_name(ship), 10);
  }
  else if (IsCelestial(obj))
  {
    cel = find_celestial(obj);
    if (!cel)
    {
      notify(from, "Your space id is not a valid celestial.");
      return;
    }
    
    sx = cel->x;
    sy = cel->y;
    sz = cel->z;
    uid = cel->uid;

    strncpy(contact, celestial_name(cel), 10);
  }
  contact[10] = '\0';
  
  if (!uid)
  {
    notify(from, "Your space id does not have a valid uid.");
    return;
  }
  
  if (arg_left && arg_right && *arg_right)
  {
    xmit = strtod(arg_left, &s);
    
    if (s && *s)
    {
      return;
    }
    mesg = arg_right;
  } else {
    xmit = atr_parse_double(from, "TRANSMIT", 0.0);
    mesg = arg_left;
  }
  if (xmit < 100.0 || xmit > 999.9)
  {
    notify(from, "Transmission frequency must be between 100 and 999 MHz.");
    return;
  }
  
  a = atr_get(from, "CALLSIGN");
  if (!a)
  {
    snprintf(pre, 127,
         "%s%s[%s%5.1f MHz%s%s]-[%s%-10s%s]-[%s ",
         ANSI_HILITE, ANSI_BLUE, ANSI_NORMAL, xmit, ANSI_HILITE, ANSI_BLUE, ANSI_GREEN, contact,
         ANSI_BLUE, ANSI_NORMAL);
  }
  else
  {
    snprintf(pre, 127,
         "%s%s[%s%5.1f MHz%s%s]-[%s%-10s%s]-[%s %s<%s%s%s>%s ",
         ANSI_HILITE, ANSI_BLUE, ANSI_NORMAL, xmit, ANSI_HILITE, ANSI_BLUE, ANSI_GREEN, contact,
         ANSI_BLUE, ANSI_NORMAL, ANSI_CYAN, ANSI_NORMAL, atr_value(a), ANSI_CYAN, ANSI_NORMAL);
  }

  /* go through the comm list and check each one */
  sent_to_from = 0;
  for (com = 0; com < db_top; com++)
  {
    if (!IsComm(com))
      continue;
    
    /* check if the user is in the same uid */
    obj = atr_parse_dbref(com, "HSPACE");
    if (IsShip(obj))
    {
      ship = find_ship_by_nav(obj);
      if (!ship)
        continue;
      
      if (ship->uid && ship->uid != uid)
        continue;
      else if (ship->landed && ship->landed->uid != uid)
        continue;
      else if (ship->docked && ship->docked->uid != uid)
        continue;
      
      if (ship->uid)
      {
        tx = ship->x;
        ty = ship->y;
        tz = ship->z;
      }
      else if (ship->landed)
      {
        tx = ship->landed->x;
        ty = ship->landed->y;
        tz = ship->landed->z;
      }
      else if (ship->docked)
      {
        tx = ship->docked->x;
        ty = ship->docked->y;
        tz = ship->docked->z;
      }
    }
    else if (IsCelestial(obj))
    {
      cel = find_celestial(obj);
      if (!cel)
        continue;
      
      if (cel->uid != uid)
        continue;
      
      tx = cel->x;
      ty = cel->y;
      tz = cel->z;
    } else {
      continue;
    }
    
    dist = dist3d(sx, sy, sz, tx, ty, tz) / hs_options.max_comm_dist;
    if (dist > 1.0)
      continue;

    a = atr_get(com, "FREQUENCY");
    if (!a)
      continue;
    
    /* check all frequencies to see if we need to send to this com */
    send_to_com = 0;
    snprintf(buff, 127, atr_value(a));
    s = buff;
    while (s)
    {
      r = split_token(&s, ' ');
      rcv = parse_number(r);
      
      /* check to see if we're on the right frequency */
      if (fabs(rcv - xmit) < 0.1)
      {
        send_to_com = 1;
        break;
      }
    }
    
    if (send_to_com)
    {
      if (com == from)
        sent_to_from = 1;
      
      notify_format(com, "%s%s%s%s]%s", pre, decay_msg(mesg, dist), ANSI_HILITE, ANSI_BLUE, ANSI_NORMAL);
    }
  }
  
  if (!sent_to_from)
  {
    notify_format(from, "You send \"%s\" on frequency %5.1f.", mesg, xmit);
  }
}
Esempio n. 20
0
/** 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;
}
Esempio n. 21
0
/* leave a landed/docked ship through the hatch */
void disembark(dbref player)
{
  dbref nav, obj, newobj;
  hship *ship;
  ATTR *a;
  int security;
  
  /* check if we can disembark from here */
  a = atr_get(Location(player), "BAY");
  if (!a)
  {
    /* no BAY, check if we're near the nav console */
    ship = find_ship(player);
    if (ship)
    {
      if (Location(ship->objnum) != Location(player))
      {
        notify(player, "You can't disembark from here.");
        return;
      }
    }
  }
  else
  {
    /* there's a BAY here, make sure it's a good one */
    nav = parse_dbref(atr_value(a));
    if (!IsShip(nav))
    {
      notify(player, "You can't disembark from here.");
      return;
    }
  
    ship = find_ship_by_nav(nav);
  }
  
  if (!ship)
  {
    notify(player, "You can't disembark from here.");
    return;
  }
  
  /* no ditching in space, or early after launching, or prematurely when landing */
  if ((ship->uid || ship->landing || ship->launching) && !ship->linked)
  {
    notify(player, "You can't disembark while in space.");
    return;
  }
  
  obj = atr_parse_dbref(ship->objnum, "SHIPOBJ");
  if (!RealGoodObject(obj))
  {
    notify(player, "This ship can not be disembarked.");
    return;
  }
  
  /* check whether we're docking or landing, save the new space object */
  if (ship->landed)
  {
    newobj = ship->landed->objnum;
  }
  else if (ship->docked)
  {
    newobj = ship->docked->objnum;
  }
  else if (ship->linked)
  {
    newobj = ship->linked->objnum;
  } else {
    notify(player, "You can't disembark while in space.");
    return;
  }
  
  if (ship->linked)
  {
    /* check the boarding code, if necessary */
    security = atr_parse_integer(ship->linked->objnum, "SECURITY", 0);
    if (security)
    {
      notify(player, "Unable to use boarding link while the other ship has security enabled.");
      return;
    }
    
    security = atr_parse_integer(ship->objnum, "SECURITY", 0);
    if (security)
    {
      notify(player, "Unable to use boarding link while security is enabled.");
      return;
    }
    
    obj = atr_parse_dbref(ship->linked->objnum, "BAY");
    if (!RealGoodObject(obj))
      obj = Location(ship->linked->objnum);
      
    moveto(player, obj, hs_options.space_wiz, NULL);
  } else {
    moveto(player, Location(obj), hs_options.space_wiz, NULL);
  }
  
  /* finish up by setting HSPACE attribute and notifying everybody about the move */
  atr_add(player, "HSPACE", unparse_dbref(newobj), hs_options.space_wiz, 0);
  notify_except(obj, Location(player), player, tprintf("%s disembarks through the main hatch.", Name(player)), 0);
  notify_except(obj, Location(obj), player, tprintf("%s disembarks from the %s.", Name(player), Name(obj)), 0);
  
  return;
}
Esempio n. 22
0
static void mung_quotas(dbref player, int key, int value)
{
    dbref aowner;
    int aq, rq, xq, aflags;
    UTF8 *buff;

    if (key & QUOTA_FIX)
    {
        // Get value of stuff owned and good value, set other value from that.
        //
        xq = count_quota(player);
        if (key & QUOTA_TOT)
        {
            buff = atr_get("mung_quotas.79", player, A_RQUOTA, &aowner, &aflags);
            aq = mux_atol(buff) + xq;
            atr_add_raw(player, A_QUOTA, mux_ltoa_t(aq));
            free_lbuf(buff);
        }
        else
        {
            buff = atr_get("mung_quotas.86", player, A_QUOTA, &aowner, &aflags);
            rq = mux_atol(buff) - xq;
            atr_add_raw(player, A_RQUOTA, mux_ltoa_t(rq));
            free_lbuf(buff);
        }
    }
    else
    {
        // Obtain (or calculate) current relative and absolute quota.
        //
        buff = atr_get("mung_quotas.96", player, A_QUOTA, &aowner, &aflags);
        if (!*buff)
        {
            free_lbuf(buff);
            buff = atr_get("mung_quotas.100", player, A_RQUOTA, &aowner, &aflags);
            rq = mux_atol(buff);
            free_lbuf(buff);
            aq = rq + count_quota(player);
        }
        else
        {
            aq = mux_atol(buff);
            free_lbuf(buff);
            buff = atr_get("mung_quotas.109", player, A_RQUOTA, &aowner, &aflags);
            rq = mux_atol(buff);
            free_lbuf(buff);
        }

        // Adjust values.
        //
        if (key & QUOTA_REM)
        {
            aq += (value - rq);
            rq = value;
        }
        else
        {
            rq += (value - aq);
            aq = value;
        }

        // Set both abs and relative quota.
        //
        atr_add_raw(player, A_QUOTA, mux_ltoa_t(aq));
        atr_add_raw(player, A_RQUOTA, mux_ltoa_t(rq));
    }
}