]> git.pond.sub.org Git - empserver/log
empserver
9 years agoUpdate copyright notice
Markus Armbruster [Fri, 2 Jan 2015 08:14:50 +0000 (09:14 +0100)]
Update copyright notice

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoUpdate known contributors comments
Markus Armbruster [Wed, 31 Dec 2014 09:42:30 +0000 (10:42 +0100)]
Update known contributors comments

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoempmod: Fix usage string of retreat and lretreat
Markus Armbruster [Wed, 31 Dec 2014 09:26:05 +0000 (10:26 +0100)]
empmod: Fix usage string of retreat and lretreat

Has been wrong since the commands were added in Chainsaw.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoinfo/retreat info/lretreat: Fix and clean up
Markus Armbruster [Wed, 31 Dec 2014 09:02:23 +0000 (10:02 +0100)]
info/retreat info/lretreat: Fix and clean up

.SY claims all arguments are individually optional.  Fix that, and
clarify that omitting the optional arguments shows current orders.

Don't complicate syntax with <SECTS>, <SHIP/FLEET> covers sectors.

The two pages are identical apart from header and footer.  They
mention land units briefly, then explain ship retreat.  Lazy.  Drop
the land unit mention from "info retreat", and rewrite "info lretreat"
for land units.

Update example output for current code.

Don't shout retreat conditions.  We've always accepted both lower and
upper case conditions.  Help has been advertising lower case since
commit bb5dfd8, v4.3.16.

While there, fix a few misspellings and such.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoinfo/lretreat: Resync with retreat.t
Markus Armbruster [Wed, 31 Dec 2014 08:55:08 +0000 (09:55 +0100)]
info/lretreat: Resync with retreat.t

Commit 18ee9a2f (v4.2.21) and commit 18ee9a2f (v4.3.16) updated only
info/retreat.t, and missed info/lretreat.t.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoinfo/retreat: De-document retreat condition help
Markus Armbruster [Wed, 31 Dec 2014 08:54:08 +0000 (09:54 +0100)]
info/retreat: De-document retreat condition help

Documented in commit dc41544, v4.3.16.  It actually worked only at the
condition prompt then.  No longer recognized elsewhere since commit
c699949.  The documentation is now misleading.  Simply drop it; the
prompt points out how to get help,

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Report where exactly ships and land units sweep mines
Markus Armbruster [Mon, 29 Dec 2014 21:45:20 +0000 (22:45 +0100)]
subs: Report where exactly ships and land units sweep mines

shp_sweep() and lnd_sweep() print only a couple of "Sweep...".
Sometimes, the sector isn't obvious, e.g. when you march multiple
sectors in one go, sweeping along the way.

Print "Approaching minefield at X,Y..." right before the first sweep
in a sector.

Note that retreat.c duplicates the sweeping code.  Retreating ships
report sweeping with coordinates since commit dcd0794, v4.2.21.
Retreating land units still sweep silently.  Left for another day.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Drop contains_engineer(), lnd_find_capable() can do
Markus Armbruster [Mon, 29 Dec 2014 19:13:21 +0000 (20:13 +0100)]
subs: Drop contains_engineer(), lnd_find_capable() can do

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonavigate march: Nicer error messages for sub-command 'm'
Markus Armbruster [Mon, 29 Dec 2014 18:49:39 +0000 (19:49 +0100)]
navigate march: Nicer error messages for sub-command 'm'

Don't report every incapable ship or land unit.  Complain only when
there are no capable ships or land units available.

The ships are all in the same sector, so complain about the sector
type just once instead of once per capable ship or land unit.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agomarch attack assault: Hit mines like ships do
Markus Armbruster [Mon, 29 Dec 2014 17:05:30 +0000 (18:05 +0100)]
march attack assault: Hit mines like ships do

When ships enter a sector with sea mines, any minesweepers sweep, then
hit mines, and finally all ships (including the minesweepers) hit
mines.  Sweeping in a sector (navigate sub-command 'm') works the same
without the final step.

When land units enter a sector with land mines, any engineers sweep,
and then all land units (including the engineers) hit mines.  Sweeping
in a sector (march sub-command 'm') works the same, which means
non-engineers can hit mines then.  Broken in Empire 2.

Actually broken for ships too then.  4.0.17 fixed ships, but neglected
to fix land units.

Change the land unit code to work like the ship code.  Fixes march
sub-command 'm' not to expose non-engineers to mines.  Changes march,
attack and assault with option INTERDICT_ATT enabled to expose
engineers twice.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Factor lnd_check_one_mines() out of lnd_check_mines()
Markus Armbruster [Mon, 29 Dec 2014 16:55:56 +0000 (17:55 +0100)]
subs: Factor lnd_check_one_mines() out of lnd_check_mines()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agomarch: Fix 'm' not to leave engineer without mobility behind
Markus Armbruster [Mon, 29 Dec 2014 16:36:36 +0000 (17:36 +0100)]
march: Fix 'm' not to leave engineer without mobility behind

When lnd_sweep() rejects an engineer for want of mobility, it removes
it from the list of units.

Can happen only when sweeping for march sub-command 'm'.  Any engineer
without mobility is dropped from the march immediately.  Broken in
Empire 2.

Fix lnd_sweep() to handle this case just like the others, and like
shp_sweep(): report and continue with the next list member.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agomarch attack assault: Don't sweep with zero mobility
Markus Armbruster [Mon, 29 Dec 2014 16:32:40 +0000 (17:32 +0100)]
march attack assault: Don't sweep with zero mobility

Require positive mobility for sweeping mines, just like ships do.
Screwed up when land units were added in Chainsaw 3.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agounit: Drop ulist member chrp
Markus Armbruster [Mon, 29 Dec 2014 07:41:23 +0000 (08:41 +0100)]
unit: Drop ulist member chrp

Commit cd8d742 mechanically combined struct mlist's mcp and struct
llist's llp into struct ulist's chrp, adding type casts to every use.
Not necessary, simply use mchr[] and lchr[] directly.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoinfo/mission: Correct land unit missile interdiction limit
Markus Armbruster [Mon, 29 Dec 2014 06:10:31 +0000 (07:10 +0100)]
info/mission: Correct land unit missile interdiction limit

It's not 100 flat, it's 20 per interdicted land unit.  It's been that
way since Empire 2 at least.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoinfo/navigate: Correct and clarify
Markus Armbruster [Mon, 29 Dec 2014 06:09:35 +0000 (07:09 +0100)]
info/navigate: Correct and clarify

Don't claim the lowest-numbered land unit is always the leader.

Reword the explanation of the prompt.

Update example output for current code.

Clarify that a destination sector is also accepted interactively, not
just on the command line.

Missiles interdict just the valuable ships, unlike other interdiction.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoinfo/march: Correct and clarify
Markus Armbruster [Mon, 29 Dec 2014 06:02:05 +0000 (07:02 +0100)]
info/march: Correct and clarify

Don't claim the army stops when the leader stops.

Don't claim the lowest-numbered land unit is always the leader.

The prompt shows minimum mobility, not leader mobility.

Clarify that a destination sector is also accepted interactively, not
just on the command line.  Fix the example output, and update for
current code.

Replace incorrect landmine hit chance formula by a reference to "info
Hitchance".

Drop incorrect damage limit for missile interdiction, rely on the
reference to "info mission" instead.

The hit chance of missiles and pin-bombers interdicting land units is
not 100%, but depends on the marching land unit that is easiest to hit.

Clarify that interdiction damage is spread evenly among the marching
land units.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Clean up convoluted logic in lnd_mar_one_sector()
Markus Armbruster [Sun, 28 Dec 2014 21:51:56 +0000 (22:51 +0100)]
subs: Clean up convoluted logic in lnd_mar_one_sector()

Handle "no movement" before the movement loop instead of relying on
the first iteration of the loop.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Clean up convoluted logic in shp_nav_one_sector()
Markus Armbruster [Sun, 28 Dec 2014 21:50:17 +0000 (22:50 +0100)]
subs: Clean up convoluted logic in shp_nav_one_sector()

Handle "no movement" before the movement loop instead of relying on
the first iteration of the loop.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonavigate: Don't disclose whether unfriendly canal is navigable
Markus Armbruster [Sun, 28 Dec 2014 21:43:47 +0000 (22:43 +0100)]
navigate: Don't disclose whether unfriendly canal is navigable

When you try to navigate a ship without canal capability into an
unfriendly canal, you get "can't go" when it's below 2%, else "too
large to fit".  Always report "can't go" for unfriendly sectors.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Drop unit_path() parameter together
Markus Armbruster [Sun, 28 Dec 2014 21:36:25 +0000 (22:36 +0100)]
subs: Drop unit_path() parameter together

It's always non-zero now.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonavigate march: Drop do_unit_move() parameter together
Markus Armbruster [Sun, 28 Dec 2014 21:32:23 +0000 (22:32 +0100)]
navigate march: Drop do_unit_move() parameter together

It's always non-zero now.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonavigate: Require all ships to start in the same sector
Markus Armbruster [Sun, 28 Dec 2014 21:27:37 +0000 (22:27 +0100)]
navigate: Require all ships to start in the same sector

The capability to navigate ships spread over several sectors is
obscure and rarely useful.  Accidental use is probably more frequent
than intentional use.  Issues:

* Interactive prompts show only the flagship's position, and give no
  clue that some ships are actually elsewhere.

* Path finding is supported only when all navigating ships are in
  the same sector.

* Interdiction becomes rather complex.  For each movement, every
  sector entered is interdicted independently.  This means the same
  fort, ship, land unit or plane can interdict multiple times.
  Interdiction order depends on the order the code examines
  ships. which the player can control.  This is all pretty much
  undocumented.

* Complicates the code and its maintenance.  Multiplies the number of
  test cases needed to cover navigate.

I feel we're better off without this feature.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agomarch: Require all land units to start in the same sector
Markus Armbruster [Sun, 28 Dec 2014 21:24:17 +0000 (22:24 +0100)]
march: Require all land units to start in the same sector

The capability to march land units spread over several sectors is
obscure and rarely useful.  Accidental use is probably more frequent
than intentional use.  Issues:

* Interactive prompts show only the leader's position, and give no
  clue that some land units are actually elsewhere.

* Path finding is supported only when all marching land units are in
  the same sector.

* In each step, the bmap is updated for the leader's radar.  The bmap
  is not updated around other marching land units.  Already odd when
  all units are in the leader's sector, and odder still when some are
  elsewhere.

* Interdiction becomes rather complex.  For each movement, every
  sector entered is interdicted independently.  This means the same
  ship, land unit or plane can interdict multiple times.  Interdiction
  order depends on the order the code examines land units. which the
  player can control.  This is all pretty much undocumented.

* Complicates the code and its maintenance.  Multiplies the number of
  test cases needed to cover march.

I feel we're better off without this feature.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Drop has_units() parameter lp, it's always null now
Markus Armbruster [Sun, 28 Dec 2014 20:59:05 +0000 (21:59 +0100)]
subs: Drop has_units() parameter lp, it's always null now

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agomarch: Check for sector abandonment before anyone marches
Markus Armbruster [Sun, 28 Dec 2014 20:55:44 +0000 (21:55 +0100)]
march: Check for sector abandonment before anyone marches

Unlike the move command, march checks sector abandonment before every
step.

If the player declines, the last land unit stays put and is removed
from the march.

Except when sectors or land units change while we're waiting for the
player's reply.  Then the last unit is not removed from the march.
This can scatter land units.  Screwed up when checking for abandoning
the sector was added in 4.2.2.

Change march to work like move, and to avoid scattering land units: if
the player declines to abandon the sector, the command simply fails.

Put the check into new lnd_abandon_askyn().

Extend would_abandon() and want_to_abandon() from a single land unit
to many.  Rename the latter to abandon_askyn() for consistency.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Move sector abandonment functions to control.c
Markus Armbruster [Sun, 28 Dec 2014 20:42:02 +0000 (21:42 +0100)]
subs: Move sector abandonment functions to control.c

Move them out of commands/move.c, because they're the only thing
involving land units there.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agogen: New emp_quelen(), replacing open-coded counting loops
Markus Armbruster [Sun, 28 Dec 2014 20:38:13 +0000 (21:38 +0100)]
gen: New emp_quelen(), replacing open-coded counting loops

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Add unitsatxy() parameter only_count
Markus Armbruster [Sun, 28 Dec 2014 20:34:18 +0000 (21:34 +0100)]
subs: Add unitsatxy() parameter only_count

Like shipsatxy().  To be used shortly.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agomarch: Don't scatter land units on crossing border
Markus Armbruster [Sun, 28 Dec 2014 19:32:16 +0000 (20:32 +0100)]
march: Don't scatter land units on crossing border

When attempting to enter a sector with a land unit that can't go there
while the marching land units are all in the same sector, march stops
and prompts without removing the incapable land unit from the group.
If another land unit has already entered the sector, the group becomes
scattered.

This can happen when marching a mixed group of spies and non-spies
into a non-allied sector.  Same for marching a mixed group of trains
and non-trains into a sector without rail, except such groups have
been disallowed since commit 36e41e5 (v4.3.7).  Both screwed up when
spies and trains were added in 4.0.0

Remove the incapable land unit from the group when another land unit
can enter the sector.  This avoids scattering land units.

Don't remove incapable land units when no land unit can enter the
sector.  Without this, march would remove everyone and end then.

It can also happen when sectors or land units change while we're
sitting at the "Do you really want to abandon X,Y" prompt.  I'm going
to fix that differently.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Make shp_check_nav() more like lnd_check_mar()
Markus Armbruster [Sun, 28 Dec 2014 19:12:01 +0000 (20:12 +0100)]
subs: Make shp_check_nav() more like lnd_check_mar()

No functional change.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agomarch: Don't permit trains to march out of sectors without rail
Markus Armbruster [Sun, 28 Dec 2014 18:58:52 +0000 (19:58 +0100)]
march: Don't permit trains to march out of sectors without rail

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Factor lnd_check_mar() out of lnd_mar_one_sector()
Markus Armbruster [Sun, 28 Dec 2014 18:47:45 +0000 (19:47 +0100)]
subs: Factor lnd_check_mar() out of lnd_mar_one_sector()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Don't hardcode impassable sector types
Markus Armbruster [Sun, 28 Dec 2014 18:06:16 +0000 (19:06 +0100)]
subs: Don't hardcode impassable sector types

Check for d_mob0 < 0 instead, like we do elsewhere.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonavigate: Don't scatter ships on canal entry
Markus Armbruster [Sun, 28 Dec 2014 16:42:44 +0000 (17:42 +0100)]
navigate: Don't scatter ships on canal entry

When attempting to enter a sector with a ship that can't go there
while the navigating ships are all in the same sector, navigate stops
and prompts without removing the incapable ship from the group.  If
another ship has already entered the sector, the group becomes
scattered.

This can happen only when navigating a mixed group of ships with and
without canal capability into a canal.  Broken in commit 74e4e281,
v4.3.0.

Remove the incapable ship from the group when another ship can enter
the sector.  This avoids scattering ships.

Don't remove incapable ships when no ship can enter the sector.
Without this, navigate would remove everyone and end then.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Give shp_nav_put(), lnd_mar_put() internal linkage
Markus Armbruster [Fri, 26 Dec 2014 08:53:55 +0000 (09:53 +0100)]
subs: Give shp_nav_put(), lnd_mar_put() internal linkage

With autonav and SAIL gone, shp_nav_put() isn't used externally
anymore.  lnd_mar_put() never was; it got external linkage just for
symmetry.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosail: Remove option SAIL
Markus Armbruster [Wed, 24 Dec 2014 20:42:51 +0000 (21:42 +0100)]
sail: Remove option SAIL

SAIL has issues:

* Sail orders are executed at the update.  Crafty players can use them
  to get around the update window.

* The route is fixed at command time.  You can't let the update find
  the best route, like it does for distribution.

* The info pages documenting it amount to almost 100 non-blank lines
  formatted.  They claim you can follow friendly ships.  This is
  wrong.  They also show incorrect follow syntax.  Unlikely to be the
  only errors.

* Few players use it.  Makes it a nice hidey-hole for bugs.  Here are
  two nice ones:

  - If follow's second argument is negative, the code attempts to
    follow an uninitialized ship.  Could well be a remote hole.

  - If ship #1 follows #2 follows #3 follows #2, the update goes into
    an infinite loop.

* It's more than 500 lines of rather crufty code nobody wants to
  touch.  Thanks to a big effort in Empire 2, it shares some code with
  the navigation command.  It still duplicates other navigation code.
  The sharing complicates fixing the bugs demonstrated by
  navi-march-test.

Reviewing, fixing and testing this mess isn't worth the opportunity
cost.  Remove it instead.  Drop commands follow, mquota, sail and
unsail.  Drop ship selectors mquota, path, follow.

struct shpstr shrinks some more, on my system from 160 to 120 bytes.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoautonav: Remove the feature
Markus Armbruster [Wed, 24 Dec 2014 15:33:51 +0000 (16:33 +0100)]
autonav: Remove the feature

The autonavigation feature has issues:

* Autonavigation orders are executed at the update.  Crafty players
  can use them to get around the update window.

* Usability is poor:

  - The order command is overly complex, not least because it can do
    five different things: clear, suspend, resume, declare route, set
    cargo levels.

  - Unlike every other command involving movement, order does not let
    you specify routes, only destination sectors.

  - Setting cargo levels can silently swap start and end point of a
    circular route, because "this keeps the load_it() procedure
    happy".  Maybe it does, but it surely keeps players confused.

  - Setting "start" cargo levels actually sets the "end" levels, and
    vice versa.  Has always been broken that way.

  - Predicting what exactly autonavigation will do at the update isn't
    easy.

* The info pages documenting it amount to almost 400 non-blank lines
  formatted.  They claim only merchant ships can be given orders.
  This is wrong.  Unlikely to be the only error.

* Few players use it, and its workings at the update a fairly opaque.
  Makes it a nice hidey-hole for bugs.  Here are two:

  - Unlike the scuttle command, autonavigation happily scuttles trade
    ships while they're on the trading block.

  - Unlike the load command, autonavigation can load in friendly and
    allied sectors.

* It's more than 700 lines of rather crufty code nobody wants to
  touch.  Thanks to a big effort in Empire 2, it shares code with the
  navigation command.  It still duplicates load code.  The sharing
  complicates fixing the bugs demonstrated by navi-march-test.

Reviewing, fixing and testing this mess isn't worth the opportunity
cost.  Remove it instead.  Drop commands order, qorder and sorder.
Drop ship selectors xstart, xend, ystart, yend, cargostart, cargoend,
amtstart, amtend, autonav.

xdump ship sheds almost half its columns.  struct shpstr shrinks, on
my system from 200 to 160 bytes.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonavigate: Fix buffer overrun for impossibly long paths taken
Markus Armbruster [Mon, 22 Dec 2014 14:29:17 +0000 (15:29 +0100)]
navigate: Fix buffer overrun for impossibly long paths taken

When a player moves more than 1023 sectors in a single navigate
command, we overrun the buffer holding the path taken.  Remote hole,
but it requires a ship that can go that far, and even a ship with
speed 1000 would need a tech level well in excess of 1000 for that.
Thus, the hole is purely theoretical for even remotely sane game
configurations.

First known version with the flaw is 4.0.0.

Fix by going back the older behavior: don't print the total path
taken, but do print what the path finder does.  Context diff of an
example:

     [0:634] Command : nav 3 6,0
     Flagship is od   oil derrick (#3)
    +Using path 'n'
      h =
     k . .
      j d
     <67.2:67.2: 6,0> h
     od   oil derrick (#3) stopped at 6,0
    -Path taken: n

This is how march works.

Removes the only use of shp_nav_one_sector()'s unusual return value 2.
Return 1 instead.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests/navi-march: New; exercises navigate and march command
Markus Armbruster [Sun, 28 Dec 2014 07:03:28 +0000 (08:03 +0100)]
tests/navi-march: New; exercises navigate and march command

Does not cover scattered navigate and march, RAILWAYS 0, enemy action
while sitting at the prompt, and interdiction.

The test exposes bugs.  They're marked "BUG:" in the test input.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests: New helper customize
Markus Armbruster [Sun, 28 Dec 2014 07:01:35 +0000 (08:01 +0100)]
tests: New helper customize

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests/fire: Drop a stale comment
Markus Armbruster [Mon, 22 Dec 2014 09:06:24 +0000 (10:06 +0100)]
tests/fire: Drop a stale comment

Should have been dropped in commit b7bcf8f.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agodoc/econfig: Belatedly drop paragraph on holes in tables
Markus Armbruster [Mon, 22 Dec 2014 09:03:38 +0000 (10:03 +0100)]
doc/econfig: Belatedly drop paragraph on holes in tables

Holes work since commit 7457573, v4.3.28.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Polish error messages
Markus Armbruster [Tue, 18 Feb 2014 19:21:26 +0000 (20:21 +0100)]
xundump: Polish error messages

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoClean up extra semicolon after block
Markus Armbruster [Sun, 16 Feb 2014 08:10:42 +0000 (09:10 +0100)]
Clean up extra semicolon after block

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoempdump: Omit redundant data from export, new -c includes it
Markus Armbruster [Sun, 9 Feb 2014 16:48:36 +0000 (17:48 +0100)]
empdump: Omit redundant data from export, new -c includes it

Cuts size of export files in test suite by a factor of four.  Not a
big deal for disk usage, as export files compress very well, and disk
space is cheap anyway.  Export files are simply easier to work with
when they aren't full of redundant crap.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agofile: New ef_typedstr_eq(), factored out of obj_changed()
Markus Armbruster [Sun, 9 Feb 2014 16:26:44 +0000 (17:26 +0100)]
file: New ef_typedstr_eq(), factored out of obj_changed()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agofile: Rename struct emptypedstr to ef_typedstr
Markus Armbruster [Sun, 9 Feb 2014 16:24:10 +0000 (17:24 +0100)]
file: Rename struct emptypedstr to ef_typedstr

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Permit omitting non-trailing realms
Markus Armbruster [Sun, 9 Feb 2014 09:20:15 +0000 (10:20 +0100)]
xundump: Permit omitting non-trailing realms

This involves computing the realm ID from fields cnum, realm.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Permit omitting non-trailing sectors
Markus Armbruster [Sun, 9 Feb 2014 09:01:59 +0000 (10:01 +0100)]
xundump: Permit omitting non-trailing sectors

This involves computing the sector ID from fields xloc, yloc.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Eliminate global cur_obj
Markus Armbruster [Sat, 8 Feb 2014 18:28:30 +0000 (19:28 +0100)]
xundump: Eliminate global cur_obj

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Code motion to clean up after previous commit
Markus Armbruster [Sat, 8 Feb 2014 17:25:49 +0000 (18:25 +0100)]
xundump: Code motion to clean up after previous commit

The previous commit avoided code motion to ease review.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Don't require ID field to come first
Markus Armbruster [Sat, 8 Feb 2014 16:51:37 +0000 (17:51 +0100)]
xundump: Don't require ID field to come first

The code needs it first so it can store field values into the object
right away.  Save the values instead, and store them when the row is
complete.

The improvement is hardly worth the trouble by itself, but it'll
simplify supporting keys consisting of multiple fields, like sector
xloc, yloc or realm cnum, realm, so we can omit rows in those tables,
too.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Eliminate global may_trunc, may_omit_id
Markus Armbruster [Sat, 8 Feb 2014 15:52:14 +0000 (16:52 +0100)]
xundump: Eliminate global may_trunc, may_omit_id

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Permit omitting trailing sectors and realms
Markus Armbruster [Sat, 8 Feb 2014 14:11:51 +0000 (15:11 +0100)]
xundump: Permit omitting trailing sectors and realms

We currently require all rows to be present for tables item, sect-chr,
infrastructure, sect, realm.

The first three make sense: the code hard-codes indexes for them, and
malfunctions when entries are blank, so we want to make it hard to
leave any blank by accident.

The last two don't: blank sectors and realms work fine.  There, the
restriction is arbitrary.  Drop it.

Sectors and realms still can't be omitted "in the middle" (can do that
only with an ID selector), but that's coming soon.

See also commit 4a4ec91.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Support splitting any table
Markus Armbruster [Sat, 8 Feb 2014 11:16:34 +0000 (12:16 +0100)]
xundump: Support splitting any table

Each part of a split table needs to supply rows for the same objects.
We currently require each part to name its objects explicitly, with an
object ID field, and don't support splitting tables that don't have
such IDs.  These restrictions became arbitrary when commit 4e23c45
implemented checking each partial table supplies the same rows.  Relax
them.

Affects tables sect, news, lost, realm, game, infrastructure.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Report all missing fields, not just first one
Markus Armbruster [Sun, 2 Feb 2014 11:24:22 +0000 (12:24 +0100)]
xundump: Report all missing fields, not just first one

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonsc: Turn NSC_HIDDEN into a flag
Markus Armbruster [Sun, 2 Feb 2014 11:09:18 +0000 (12:09 +0100)]
nsc: Turn NSC_HIDDEN into a flag

More general, and fewer places need to know about it.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonsc: Reject array selectors in conditions
Markus Armbruster [Sun, 2 Feb 2014 09:29:18 +0000 (10:29 +0100)]
nsc: Reject array selectors in conditions

Array selectors were introduced for xdump (commit 612f2da, v4.2.18).
Since there is no syntax for subscripting arrays in conditions and
survey, we silently assume index zero.  Unclean.  Reject the selector
instead.

Affects ship selectors cargostart, cargoend, amtstart, amtend (since
commit 32011f1, v4.2.19), nat selectors relations (commit 0a44c48,
v4.3.0), contacts (commit c345ab8, v4.3.0), rejects (commit 6844c94,
v4.3.4).  The other array selectors aren't visible in conditions.  No
array selectors are visible in survey.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonsc: Turn common patterns into CA_IS_ARRAY() and CA_ARRAY_LEN()
Markus Armbruster [Sun, 2 Feb 2014 09:13:41 +0000 (10:13 +0100)]
nsc: Turn common patterns into CA_IS_ARRAY() and CA_ARRAY_LEN()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonsc: Rename nstr_exec_val() to nstr_eval() and tighten contract
Markus Armbruster [Sun, 2 Feb 2014 08:39:35 +0000 (09:39 +0100)]
nsc: Rename nstr_exec_val() to nstr_eval() and tighten contract

nstr_exec_val() can produce three different error values: NSC_NOTYPE
on invalid category, invalid type with zero val_as.lng on invalid type
(this is a bug), and the wanted type with zero val_s when it can't
coerce.  None of these should ever happen.

Fix it to always produce an NSC_NOTYPE error value.  Fix up callers to
check for it.

Specify the result's type is promoted on success.  Ensure it is even
when the argument is NSC_VAL with an unpromoted type, which is
invalid.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests/empdump: New; exercising the empdump utility
Markus Armbruster [Wed, 29 Jan 2014 19:24:26 +0000 (20:24 +0100)]
tests/empdump: New; exercising the empdump utility

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests: New helper cmp_out1
Markus Armbruster [Wed, 29 Jan 2014 20:09:04 +0000 (21:09 +0100)]
tests: New helper cmp_out1

Factor out of cmp_out, then make it optionally take an explicit
expected result.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests/files tests/fairland: Check stderr and exit status
Markus Armbruster [Wed, 29 Jan 2014 19:12:18 +0000 (20:12 +0100)]
tests/files tests/fairland: Check stderr and exit status

New helper run_and_cmp to automate the job: run a program capturing
its standard output, standard error and exit status, then compare the
actual with the expected results.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests: Fix missing local in feed_files and cmp_out
Markus Armbruster [Wed, 29 Jan 2014 19:11:25 +0000 (20:11 +0100)]
tests: Fix missing local in feed_files and cmp_out

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests: Simplify running cmp_out more than once
Markus Armbruster [Wed, 29 Jan 2014 18:56:38 +0000 (19:56 +0100)]
tests: Simplify running cmp_out more than once

When cmp_out detects a test failure, it returns non-zero status, which
terminates the test script unless caught.

Accumulate failures in a global variable checked at exit instead, so
running it multiple times in a test script just works.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests: Feed only logs and xdump to normalize.pl
Markus Armbruster [Tue, 28 Jan 2014 19:33:19 +0000 (20:33 +0100)]
tests: Feed only logs and xdump to normalize.pl

Feeding other test output files (right now tests/files/files.out
tests/fairland/fairland.out fairland/newcap_script) works, but it's
odd, and might not work as well for all future output files.  Only
strip trailing white space there.

There used to be other output files that required normalize.pl: client
output.  Gone since commit 9ca3fa9.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agotests: Define and use some abbreviations
Markus Armbruster [Tue, 28 Jan 2014 18:29:11 +0000 (19:29 +0100)]
tests: Define and use some abbreviations

No functional change.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agofile: Provide EF_WITH_CADEF_MAX_ENTRY_SIZE to clean up xditem()
Markus Armbruster [Mon, 27 Jan 2014 19:57:20 +0000 (20:57 +0100)]
file: Provide EF_WITH_CADEF_MAX_ENTRY_SIZE to clean up xditem()

xditem() needs a buffer that can hold entries of any xdumpable table.
It's been 2048 bytes and marked FIXME since day one.  Clean it up so
that if anyone ever goes crazy with entry sizes, we fail an assertion
during startup instead of overrunning the buffer during play.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoplayer: Drop long-disabled code to resolve IP addresses
Markus Armbruster [Mon, 27 Jan 2014 19:28:39 +0000 (20:28 +0100)]
player: Drop long-disabled code to resolve IP addresses

Disabled since commit 32fac04 (v4.2.13) because it could at the time
use more stack space than we provided.  Additional issues: code still
uses obsolete gethostbyaddr() rather than getnameinfo(), and we
provide only 512 bytes for host names instead of the customary
NI_MAXHOST (1025) bytes.

All three issues would be easy enough to fix.  What's not so easy is
to avoid blocking on the synchronous DNS lookup.  Without that,
connecting repeatedly from a range of addresses with slow reverse
lookup could conceivably be employed as a denial of service attack.

We've been living without reverse lookup for close to ten years.  Bury
the corpse, and move on.

Bonus: sizeof(struct natstr) is cut in half.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agonat: Deprecate selector hostname, fix value to ""
Markus Armbruster [Mon, 27 Jan 2014 19:03:29 +0000 (20:03 +0100)]
nat: Deprecate selector hostname, fix value to ""

Its value has always been "", unless the deity recompiled with
RESOLVE_IPADDRESS defined, or imported another value with empdump.

I'm going to drop the RESOLVE_IPADDRESS code, including struct natstr
member nat_hostname.  To prepare for that, fix the selector's value to
"", so it doesn't need nat_hostname, and deprecate it.

This changes its "len" in xdump meta nat from 512 to 0.  Unlikely to
upset clients.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Clean up lazy coding limiting string length to 65536
Markus Armbruster [Mon, 27 Jan 2014 18:44:44 +0000 (19:44 +0100)]
xundump: Clean up lazy coding limiting string length to 65536

Can't just replace the literal 65536 by INT_MAX, because my system's
vfprintf() rejects that with EOVERFLOW.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxdump: Avoid undefined pointer arithmetic
Markus Armbruster [Mon, 27 Jan 2014 17:56:05 +0000 (18:56 +0100)]
xdump: Avoid undefined pointer arithmetic

s + n is defined only as long as it points into or just beyond the
same array as s.  Thus, our use of INT_MAX for "unlimited" relies on
undefined behavior.  Works fine in practice, but avoiding undefined
pointer arithmetic isn't hard here, so let's do it.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoxundump: Refuse to undump strings too long for terminating null
Markus Armbruster [Mon, 27 Jan 2014 16:52:32 +0000 (17:52 +0100)]
xundump: Refuse to undump strings too long for terminating null

We're dealing with three kinds of string storage: char * pointing to a
null-terminated string, char[] holding a null-terminated string, and
char holding a string of length 0 or 1.

Unfortunately, xdump meta data doesn't distinguish the latter two:
both are NSC_STRINGY.  Because of that, xundump happily fills char[]
to the limit, producing strings that aren't null-terminated, resulting
in read beyond buffer and possibly worse.

Affects struct shpstr members shp_path, shp_name, shp_rpath, struct
lndstr member lnd_rpath, and struct natstr members nat_cnam, nat_pnam,
nat_hostaddr, nat_hostname, nat_userid.  Since these are all in game
state, only the empdump utility program is affected, not the
configuration table reader.

We clearly need to require null-termination for char[] values.  Since
using char[1] for null-terminated strings makes no sense, we can still
make NSC_STRINGY with length 1 serve char values as before, by
permitting non-null-terminated strings only when length is 1.  Ugly
wart, but it fixes the bug without a possibly awkward change xdump
meta-data.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Factor out lnd_mar_put_one()
Markus Armbruster [Sat, 25 Jan 2014 15:38:34 +0000 (16:38 +0100)]
subs: Factor out lnd_mar_put_one()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Factor out shp_nav_put_one()
Markus Armbruster [Sat, 25 Jan 2014 15:14:53 +0000 (16:14 +0100)]
subs: Factor out shp_nav_put_one()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Use lnd_put_one() in lnd_put(), lnd_mar_put()
Markus Armbruster [Sat, 25 Jan 2014 15:13:52 +0000 (16:13 +0100)]
subs: Use lnd_put_one() in lnd_put(), lnd_mar_put()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Rename lnd_delete() to lnd_put_one()
Markus Armbruster [Sat, 25 Jan 2014 15:11:53 +0000 (16:11 +0100)]
subs: Rename lnd_delete() to lnd_put_one()

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Rename shp_put() to shp_nav_put()
Markus Armbruster [Sat, 25 Jan 2014 15:05:07 +0000 (16:05 +0100)]
subs: Rename shp_put() to shp_nav_put()

For consistency with lnd_mar_put().

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Split lnd_mar_put() off lnd_put() and specialize
Markus Armbruster [Sat, 25 Jan 2014 14:57:12 +0000 (15:57 +0100)]
subs: Split lnd_mar_put() off lnd_put() and specialize

lnd_put() serves two masters: march, which wants it to report
"stopped" and write back struct ulist member mobility to
unit.land.lnd_mobil, and ground combat, which doesn't.

lnd_put() assumes march when actor is non-zero.  Correct (but see
commit 8c502d4).  Dates back to Empire 2.

Too ugly for my taste.  Specialize for each master instead:
lnd_mar_put() for march, and lnd_put() for ground combat.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Split unit_put() into shp_put() and lnd_put() again
Markus Armbruster [Sat, 25 Jan 2014 14:41:58 +0000 (15:41 +0100)]
subs: Split unit_put() into shp_put() and lnd_put() again

Commit d94d269 combined them into unit_put(), but that has turned out
not to be useful.  Split them again.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Factor lnd_insque() out of lnd_sel(), ask_olist(), ...
Markus Armbruster [Sat, 25 Jan 2014 09:44:50 +0000 (10:44 +0100)]
subs: Factor lnd_insque() out of lnd_sel(), ask_olist(), ...

... get_dlist(), att_reacting_units().

This loses malloc() error checking in ask_olist() and get_dlist().  No
great loss, because we don't check in so many other places, including
att_reacting_units().  We should use a wrapper that terminates on
error, though.  Left for another day.

ask_olist(), get_dlist() and att_reacting_units() zero the struct
ulist with memset().  lnd_insque() doesn't, so these functions need to
zero any members not otherwise initialized explicitly now.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Set struct ulist member supplied properly for attackers
Markus Armbruster [Sat, 25 Jan 2014 09:42:22 +0000 (10:42 +0100)]
subs: Set struct ulist member supplied properly for attackers

It's set to zero via memset().  Incorrect, but harmless, because it's
not actually used.  Correct it anyway.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agounit: Fix comments on struct ulist member use
Markus Armbruster [Sat, 25 Jan 2014 09:18:04 +0000 (10:18 +0100)]
unit: Fix comments on struct ulist member use

Members x, y, eff, supplied are not "LAND only", they're used only by
ground combat.  They're not used by march.

In ground combat, member mobil is not how much the land unit has left,
it's how much it still needs to be charged.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agosubs: Factor shp_insque() out of shp_sel(), shp_missdef(), ...
Markus Armbruster [Sat, 25 Jan 2014 07:49:02 +0000 (08:49 +0100)]
subs: Factor shp_insque() out of shp_sel(), shp_missdef(), ...

... nav_ship(), fltp_to_list().

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
9 years agoRemove superfluous override directive in make check
Gerd Flaig [Fri, 2 Jan 2015 18:29:41 +0000 (19:29 +0100)]
Remove superfluous override directive in make check

Travis CI and OS X system make on 10.9.x at least don't have GNU make
>=3.82 which contains a parser enhancement that allows multiple
directives.

Signed-off-by: Gerd Flaig <gefla@pond.sub.org>
Here's why removing override is a good idea.  The variable assignment
should already override anything Make may find in its environment.
All "override" does is protect against unwise make arguments.

"info make" says:

    The `override' directive was not invented for escalation in the war
    between makefiles and command arguments.  It was invented so you can
    alter and add to values that the user specifies with command
    arguments.

Thus, override is ill-advised here.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agotests/build: Clean up setup a bit
Markus Armbruster [Sun, 26 Jan 2014 09:47:53 +0000 (10:47 +0100)]
tests/build: Clean up setup a bit

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agotests/fire: Clean up setup a bit
Markus Armbruster [Sun, 26 Jan 2014 09:43:57 +0000 (10:43 +0100)]
tests/fire: Clean up setup a bit

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agotests/actofgod: Switch setup from deprecated setsect to edit
Markus Armbruster [Sun, 26 Jan 2014 09:23:00 +0000 (10:23 +0100)]
tests/actofgod: Switch setup from deprecated setsect to edit

Clean it up a bit while there.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoattsub: Clean up take_casualty() a bit
Markus Armbruster [Sat, 25 Jan 2014 10:40:04 +0000 (11:40 +0100)]
attsub: Clean up take_casualty() a bit

Giving biggest the appropriate type saves a type cast.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agotrade: Clean up type of trdswitchown()'s second parameter
Markus Armbruster [Sat, 25 Jan 2014 10:28:05 +0000 (11:28 +0100)]
trade: Clean up type of trdswitchown()'s second parameter

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoClean up casts from union empobj_storage * to struct empobj *
Markus Armbruster [Sat, 25 Jan 2014 10:25:43 +0000 (11:25 +0100)]
Clean up casts from union empobj_storage * to struct empobj *

Take the address of member gen instead.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoClean up casts from struct FOO * to struct emp_qelem *
Markus Armbruster [Sat, 25 Jan 2014 10:17:09 +0000 (11:17 +0100)]
Clean up casts from struct FOO * to struct emp_qelem *

Take the address of the queue member instead.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agopathfind: Fix up comment for commit 92e64d7
Markus Armbruster [Sat, 25 Jan 2014 10:08:43 +0000 (11:08 +0100)]
pathfind: Fix up comment for commit 92e64d7

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoClean up superfluous includes
Markus Armbruster [Wed, 22 Jan 2014 20:27:32 +0000 (21:27 +0100)]
Clean up superfluous includes

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoretreat: Move function declarations to retreat.h
Markus Armbruster [Wed, 22 Jan 2014 20:24:36 +0000 (21:24 +0100)]
retreat: Move function declarations to retreat.h

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoretreat: Clean up interface between retreat_FOO(), retreat_FOO1()
Markus Armbruster [Wed, 22 Jan 2014 19:56:53 +0000 (20:56 +0100)]
retreat: Clean up interface between retreat_FOO(), retreat_FOO1()

Move clearing of retreat flags from retreat_ship(), retreat_land() to
retreat_ship1(), retreat_land1(), so it's where the retreat path is
shortened.

Move putship(), putland() from retreat_ship1(), retreat_land1() to
retreat_ship(), retreat_land(), so it's where the nxtitem() is, and
doesn't need a "if (!orig)" guard.  Requires making retreat_ship1()
and retreat_land() return non-zero when they modified their argument.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoretreat: Don't consume a retreat direction that wasn't followed
Markus Armbruster [Wed, 22 Jan 2014 19:46:53 +0000 (20:46 +0100)]
retreat: Don't consume a retreat direction that wasn't followed

When a retreating ship or land unit runs into a sector it can't enter,
it stops.  The direction character that led it there is consumed, even
though it could not be followed.  The next retreat will then attempt
to follow the rest of the path.  Don't do that.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoretreat: Reject invalid retreat paths
Markus Armbruster [Wed, 22 Jan 2014 18:26:24 +0000 (19:26 +0100)]
retreat: Reject invalid retreat paths

Undocumented misfeature: retreat and lretreat accept anything as
retreat path.  The paths' actual consumers retreat_ship1() and
retread_land1() silently ignore invalid direction characters.

The retreat paths are in xdump, and invalid ones could conceivably
confuse smart clients.

Change the commands to reject invalid paths, and the consumers to oops
on invalid direction characters.

Note that invalid paths get rejected even when they're not actually
used because the conditions argument contains a "c" for "cancel".
Requiring the user give a new path so he can cancel the old one is
comically bad design.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
10 years agoretreat: Fail without charging BTUs when given no conditions
Markus Armbruster [Tue, 21 Jan 2014 21:07:12 +0000 (22:07 +0100)]
retreat: Fail without charging BTUs when given no conditions

Return RET_SYN instead of RET_FAIL then.  Also drop the error message;
the usage help printed for RET_SYN should do.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>