Since commit 1ec9b94, we derive the version number from git tags with
build-aux/git-version-gen. When a shallow clone doesn't include a
suitable tag, this fails, and make refuses to build anything. Since
Travis uses git-clone --depth=50, it'll break as soon as we've got
more than 50 commits since the last release.
Support arbitrarily shallow clones for limited purposes like testing
by falling back from a proper V.N-H version number to UNKNOWN-H.
To guard against use of such builds for other purposes, log a warning
on server startup, and print one on player login.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Several headers define macros that use ef_ptr() without including
"file.h". Fix that. Drop redundant inclusions elsewhere.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
... when referring to a function's parameter or a struct/union's
member.
The idea of using FOO comes from the GNU coding standards:
The comment on a function is much clearer if you use the argument
names to speak about the argument values. The variable name
itself should be lower case, but write it in upper case when you
are speaking about the value rather than the variable itself.
Thus, "the inode number NODE_NUM" rather than "an inode".
Upcasing names is problematic for a case-sensitive language like C,
because it can create ambiguity. Moreover, it's too much shouting for
my taste.
GTK-Doc's convention to prefix the identifier with @ makes references
to variables stand out nicely. The rest of the GTK-Doc conventions
make no sense for us, however.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
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>
For now, it just logs "Configured for testing" on startup, and prints
a scary warning on player login.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The journal logs a thread name for each event. The player thread name
changes on entry to the playing phase. Connecting old and new name
isn't as easy as it should be:
Sun Apr 29 12:13:39 2012 Conn29 input coun POGO
Sun Apr 29 12:13:39 2012 Conn29 input pass peter
Sun Apr 29 12:13:39 2012 Conn29 input play
Sun Apr 29 12:13:39 2012 Play#0 login 0 127.0.0.1 armbru
Sun Apr 29 12:15:39 2012 Play#0 logout 0
To connect Conn29 with Play#0, you have to know that country#0 is
named POGO.
Fix that by logging login before the thread name change:
Sun Apr 29 12:17:41 2012 Conn29 input coun POGO
Sun Apr 29 12:17:41 2012 Conn29 input pass peter
Sun Apr 29 12:17:41 2012 Conn29 input play
Sun Apr 29 12:17:41 2012 Conn29 login 0 127.0.0.1 armbru
Sun Apr 29 12:19:41 2012 Play#0 logout 0
Now "Conn29 login 0" makes the connection obvious.
This involves moving journal_login() from player_main() before
empth_set_name() in its caller play_cmd(). Move journal_logout() as
well, for symmetry.
If player_main() fails, we now log login/logout instead of nothing in
the journal. That's okay. Note that before commit c9f21c0e (v4.3.8),
we logged just login then.
If execute's argument was read interactively, it prints the argument
instead of the command. Else, it prints uninitialized garbage. The
latter can theoretically crash the server, or leak information.
Broken in commit 3de1e8be, v4.3.28
Simply set the player connection's EOF indicator. Cleaner than
setting player->state to PS_SHUTDOWN from random places.
Move the assignment of PS_PLAYING from player_main() to its caller
play_cmd(), so that player->state is exclusively controlled in
login.c.
Timeout during execute gets handled just like an EOF cookie: end the
batch file, resume reading normal commands. That's wrong, we need to
close the connection.
A real EOF is recorded in the player's connection's EOF indicator.
Let's use that for all "connection needs to be closed" conditions, so
they all work the same. Create io_set_eof() to provide access.
Make recvclient() set the player connection's EOF indicator on
timeout. This makes the timeout "stick". Record receipt of an EOF
cookie in new struct player member got_ctld. Also abort the command,
as before. This leaves further interpretation of the EOF cookie to
the command loops.
Make player_main() set the player connection's EOF indicator on
got_ctld. Player connection gets closed on on EOF cookie, as before.
Change execute() to break the batch command loop when got_ctld is set,
then reset it. Ends the batch file on EOF cookie, as before.
Change status() back to checking EOF and error indicators (partial
revert of commit 9c5854c8, v4.3.16), and drop struct player member
eof.
A player sending execute script contents quickly could theoretically
get an unfair share of the server. Missed in commit db6fd8da
(v4.2.22), which made only the normal command loop yield.
status() informs the player of non-trivial command costs and earnings,
and when he goes broke or becomes solvent. However, this is skipped
when the command gets aborted by the player signalling EOF, or by
server shutdown, and after a quit command.
Fix by moving the check for EOF or shutdown down to the may_play_now()
check.
This looks a bit like it would also fix charging of play time. But
that's not broken, because player_main() charges, too.
Commit e3cf1e32 (v4.3.27) created make_stale_if_command_arg() to
permit catching more potential yields on input. Unfortunately, the
implementation of navigate and march sub-commands 'r', 'l' and 's'
breaks it.
do_unit_move() reads units into a unit list at the beginning and at
each stop. It writes them back when they move or sweep. If a unit
changed in the file in between, the changes would get wiped out.
Therefore, do_unit_move() must not yield between stops.
do_unit_move() parses sub-commands into player->argp[], then supplies
defaults for missing arguments, so that code using them (radar(),
do_look(), sona(), mine(), landmine()) won't prompt for missing
arguments. Unclean and brittle. See also commit 28cc236e and commit
45106ab9.
Unfortunately, make_stale_if_command_arg() doesn't recognize the
difference between these defaulted arguments and parsed arguments, so
it makes objects stale, even though the defaulted arguments can't be
missing. If a move or sweep follows, it triggers a false positive
generation oops.
To fix, test "points into argument buffer" (only true for parsed
arguments) instead of "is in player->argp[]". Requires making the
argument buffer accessible: new struct player member argbuf[]. Use it
for parsing commands, in command(), execute(), do_unit_move(). Don't
use it in emp_config(), player_login(), move_ground(), because these
parse something else.
The argument is UTF-8. If it's missing, execute() gets it with
getstring(), which mangles non-ASCII characters. Clients reject
mangled file names for security reasons.
Fix by switching to ugetstring(). Missed in commit 69832255, v4.3.11.
Non-ASCII characters are still mangled in ASCII sessions, but that's
not expected to work.
When we added input filtering in v4.2.21, we missed the execute
command. Because of that, funny characters can be treated differently
in batch files.
The main command loop uses getcommand(), which filters input.
execute() uses recvclient() directly, and doesn't filter input. Both
feed the command to parse(), which drops unwanted control and
non-ASCII characters.
Input filtering drops unwanted control characters and, for ASCII
sessions, replaces non-ASCII characters by '?'.
Because of that, execute in ASCII sessions drops non-ASCII command
characters in batch files rather than replacing them.
Except where parts of the command are used raw: execute's command
echo, flash and wall message argument. There, unwanted control
characters aren't dropped in UTF-8 sessions, and non-ASCII characters
are interpreted as UTF-8 in ASCII sessions. Output filtering replaces
any resulting non-ASCII characters.
players column "last command" also uses the command raw, but commands
executed from batch files are not visible there, so it isn't affected.
To get rid of the differences, move the prompting from getcommand() to
command(), then switch execute() over to getcommand().
Side effect: the batch file's commands are now recorded in
player_commands[]. That's desirable.
getstarg(), snxtitem() and snxtsct() can yield the processor, because
they call getstring(). But only for null or empty arguments. For
other arguments, we should call ef_make_stale(), to catch errors.
Problem: if a caller never passes null or empty arguments, it may rely
on these functions not yielding. We'd get false positives. In
general, we can't know whether that's the case. But we do know in the
common special case of player arguments. Call ef_make_stale() for
those.
Why upgrade? I'm not a lawyer, but here's my take on the differences
to version 2:
* Software patents: better protection against abuse of patents to
prevent users from exercising the rights under the GPL. I doubt
we'll get hit with a patent suit, but it's a good move just on
general principles.
* License compatibility: compatible with more free licenses, i.e. can
"steal" more free software for use in Empire. I don't expect to steal
much, but it's nice to have the option.
* Definition of "source code": modernization of some details for today's
networked world, to make it easier to distribute the software. Not
really relevant to us now, as we normally distribute full source code.
* Tivoization: this is about putting GPL-licensed software in hardware,
then make the hardware refuse to run modified software. "Neat" trick
to effectively deny its users their rights under the GPL. Abuse was
"pioneered" by TiVo (popular digital video recorders). GPLv3 forbids
it. Unlikely to become a problem for us.
* Internationalization: more careful wording, to harden the license
outside the US. The lawyers tell us it better be done that way.
* License violations: friendlier way to deal with license violations.
This has come out of past experience enforcing the GPL.
* Additional permissions: Probably not relevant to us.
Also include myself in the list of principal authors.
may_play_now() tells deities about hours restriction and game down
status. It runs at login and before and after each command. Getting
notified that often is annoying.
Avoid repetition by remembering notification in new player flags
PF_HOURS and PF_DOWN. Add a notification when hours restriction has
been lifted. Ensure the notification is printed before the prompt,
not before the command, by calling may_play_now() from command() only
for mortals. Safe, because may_play_now() always returns true for
deities anyway.
New tel_read_header(), tel_read_body(). Use them in rea(),
show_first_tel(), copy_and_expire().
rea() now stops when it encounters a corrupt telegram, and logs the
problem. Before, error detection was incomplete, and errors were not
logged. Corrupt mailboxes could make it crash.
show_first_tel() and copy_and_expire() can now cope with telegrams of
arbitrary length, like rea(), and sanity-check the header fields they
don't actually use.
Move the gamedown() check from status to may_play_now() so it is
checked upon login, before a command is executed and after command
completion. This fixes the situation where a player to could execute
one more command after the game was down.
Report to the deities that the game is down.
Remove to duplicate gamedown message.
Commit 3da4030 already changed player_main() to log out the player
when m_m_p_d was exceeded in command(). This crept in accidentally.
Complete the job by changing status() to log out the player instead of
downgrading him to visitor status.
Also, change player_main(), command() and status() to apply the time
limit to countries in sanctuary in addition to active countries.
Leave visitors alone, because those are shared logins. Make the
disconnect message to a player consistent for all situations.
Note that commit 875a80d1 already changed player_main() to apply the
time limit only to active countries instead of all, just like status()
does, but neglected to document that.
Replace daychange() and gettimeleft() by update_timeused_login(),
update_timeused() and enforce_minimum_session_time(). The new
code doesn't assume the day is always 24 hours long which can
occur when transitioning into or out of DST and such. Logging
in after more a multiple of 128 days now resets nat_timeused
properly.
Fix nat_timeused calculation on midnight rollover to include
the time since midnight.
struct natstr member nat_dayno and struct player member timeleft
are now unused, remove them.
This simplifies things. In particular, it gets rid of random rounding
in getcommand(), which created a variation in the nightly build
depending on whether the update starts before or after the deity logs
out.
Replace struct natstr member nat_minused by nat_timeused, and update
cou_ca[] accordingly (this affects xdump nat). Replace player member
minleft by timeleft, and getminleft() by gettimeleft(). Update
getcommand(), daychange(), player_main(), status() accordingly, taking
care not to change player output. Change edit country key 'u' to work
in seconds.