Commit graph

4521 commits

Author SHA1 Message Date
b6775d1c9b nsc: Turn common patterns into CA_IS_ARRAY() and CA_ARRAY_LEN()
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-02-01 16:52:59 +01:00
143a4e4e6f 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>
2015-02-01 16:52:59 +01:00
9a6998882a 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>
2015-02-01 16:52:59 +01:00
9ef4f1bf50 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>
2015-02-01 16:52:59 +01:00
199388b084 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>
2015-02-01 16:52:58 +01:00
a06cea24c1 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>
2015-02-01 16:52:58 +01:00
55857c7b20 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>
2015-02-01 16:52:58 +01:00
002a3a3f1e 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>
2015-02-01 16:52:58 +01:00
47ccc40e38 subs: Factor out lnd_mar_put_one()
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-02-01 16:52:28 +01:00
268b05225f subs: Factor out shp_nav_put_one()
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-02-01 16:51:39 +01:00
86c7249ca9 subs: Use lnd_put_one() in lnd_put(), lnd_mar_put()
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-01-17 15:25:24 +01:00
56cadfe157 subs: Rename lnd_delete() to lnd_put_one()
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-01-17 15:25:24 +01:00
7548337e73 subs: Rename shp_put() to shp_nav_put()
For consistency with lnd_mar_put().

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-01-17 15:25:24 +01:00
18bf9e0b34 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>
2015-01-17 15:25:23 +01:00
b5ffc1ca49 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>
2015-01-17 15:25:16 +01:00
62b9399cdf 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>
2015-01-14 19:08:47 +01:00
e62af86066 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>
2015-01-14 19:08:46 +01:00
fe42e6e8dd subs: Factor shp_insque() out of shp_sel(), shp_missdef(), ...
... nav_ship(), fltp_to_list().

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-01-14 19:08:46 +01:00
47af370eaa 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>
2014-02-16 13:19:27 +01:00
76ca2011c3 trade: Clean up type of trdswitchown()'s second parameter
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:27 +01:00
c274d0820c 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>
2014-02-16 13:19:27 +01:00
52a40481cb 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>
2014-02-16 13:19:26 +01:00
4d899f6e6d pathfind: Fix up comment for commit 92e64d7
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
5cbcdc0497 Clean up superfluous includes
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
8f5c600f71 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>
2014-02-16 13:19:26 +01:00
ff826d2582 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>
2014-02-16 13:19:26 +01:00
40ec33b099 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>
2014-02-16 13:19:26 +01:00
1e3b7773d4 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>
2014-02-16 13:19:26 +01:00
c699949326 retreat: Fix infinite loop when third argument contains '?'
Broken in commit bb5dfd8, v4.3.16.  Fix by recognizing '?' only when
getting the argument interactively.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
b3453efdfc retreat: Don't charge mobility for retreating in direction 'h'
Obscure feature: 'h' in a retreat path stops the current retreat.  The
code treats that as entering the current sector again, thus charges
mobility for staying put.  It also reports "could not retreat to" for
a ship or land unit that can retreat out of, but could not retreat
into its current sector, e.g. a ship in an unfriendly harbor.

Fix by cleaning up the tortuous control flow.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
98cb83302c retreat: Drop useless write back on failed retreat
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
d1c3529009 retreat: Don't retreat the current player's ships or land units
The retreat code happily retreats anything, without considering who
owns it.  It reports retreat to the owner by bulletin, even when the
owner is the current player.

Commands shouldn't report to the current player by bulletin, they
should print directly.  Fixable.  However, your ships and land units
retreating from your own actions makes little sense.  Suppress it.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
df8a1ffc1b retreat: Don't report a destroyed ship/land unit couldn't retreat
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
c3a839934f retreat: Oops on retreating ghosts
Code never actually retreated them, but it could zap their mission and
retreat flags.  Harmless, but avoid it anyway.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:26 +01:00
c03db4c5ef shpsub: Make shp_check_nav() return more useful information
Some callers have to second-guess shp_check_nav() to figure out
whether CN_LANDLOCKED means "too big to fit into the canal" or "can't
go there at all".

Fix that by returning d_navigation.  CN_LANDLOCKED becomes either
NAV_CANAL or NAV_NONE, CN_CONSTRUCTION becomes either NAV_02 or
NAV_60, and CN_NAVIGABLE becomes NAVOK.

The CN_NAVIGABLE, ... codes are now unused.  Drop them.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:25 +01:00
1fee5028a2 Delete trivial instances of /*NOTREACHED*/
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:25 +01:00
b860123590 retreat: Retreat groups in a more sensible order
A group retreat is executed in increasing UID order.  The resulting
bulletin can be confusing.

Instead, retreat the ship that had its retreat conditions satisfied
first, and only then its group, if any.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:25 +01:00
e7949e20f3 retreat: Clear mission only when ship or land unit moves
The mission gets cleared whenever a retreat is triggered, even for
ships and land units that are unable to retreat.

Clear it only when the ship or land unit actually retreats.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:25 +01:00
2cc0664e3e retreat: Fix stack smash in land unit group retreat
retreat_land() reads ships instead of land units, overrunning local
variable land.  On lucky systems such as mine, this clobbers ni, and
triggers an oops.  On unlucky systems, it crashes.  On really unlucky
systems, it corrupts the land units file.

Broken since land unit retreat was added in Chainsaw 3.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:25 +01:00
c7af9bd955 edit: Keep missions centered on unit centered when teleporting
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:25 +01:00
ae595ec430 edit: Fix edit s key 'U' to preserve "does not follow"
Copying the ship copies the ship to follow.  When the source ship
doesn't follow a ship, the target ship is made to follow the source.
Screwed up since Chainsaw added the means to copy a ship.  Fix it.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:24 +01:00
e604c6e737 edit: Make edit l key 'L' preserve "no dist center"
Copying the sector copies its distribution center.  When the source
sector has none, the target sector is made to distribute to the
source.  Unexpected.  Zap the distribution center then.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:24 +01:00
3c7d9da3ab edit: Fix edit l key 'L' not to mess up coastal flag
Screwed up since Chainsaw added the means to copy a sector.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 13:19:24 +01:00
15e3309297 build: Reword bridge next to land messages to mention the sector
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 12:00:31 +01:00
05f1844ca1 build: Deities build ex nihilo
Let deities build in any sector.  If the deity's tech level is too
low, use the required tech level instead.  Don't require or use
materials, work or money.  Bridge spans still require support.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 12:00:19 +01:00
636752a234 bridgefall: Factor bridge_support_at() out of bridgefall()
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 12:00:18 +01:00
4824648978 bridgefall: Fix loss of bridge support with EASY_BRIDGES off
With EASY_BRIDGES off, bridge spans need to be next to a bridge tower
or a bridge head that is at least 20% efficient to remain standing.

When a bridge tower or head gets damaged below 20%, adjacent spans may
lose support.  Bug: they don't fall when they're next to another
bridge head below 20%.

Has always been broken.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 12:00:18 +01:00
292bfac797 bridgefall: Fix support loss with EASY_BRIDGES and BRIDGETOWERS on
With EASY_BRIDGES on, bridge spans need to be next to land or a bridge
tower to remain standing.

Land can't go away, but a bridge tower can fall.  Bridge spans next to
it may lose support then.  Bug: they don't fall when they lose support
that way.  Fix that.

Broken in commit 40eb78e, v4.3.12.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 12:00:18 +01:00
d80ecb97f5 Revert "Remove dead EASY_BRIDGES code from bridgefall()"
This reverts commit df62b8604d.

The next commit will revive that code.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 12:00:18 +01:00
f5244d4702 bridgefall: Fix harmless coordinate normalization bug
bridgefall() wants to do this:

    for all possible pairs of directions (i, j)
        if i and j cancel out
	    continue
	do stuff

It does it by adding direction offsets to start coordinates, and
comparing the resulting coordinates to the start coordinates.  Fine,
except it neglects to normalize the resulting coordinates.

Harmless in practice, because you can get an incorrect result only
when the path goes around the world, which it can do only in a 4x2
world.

Fix it anyway, by testing "directions cancel out" directly.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 12:00:18 +01:00