play.c needs <string.h> since commit f1fc0df. My version of
<readline/readline.h> pulls it in, but at least Apple's (derived from
NetBSD's) doesn't, and we get warnings then. Add the missing
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Set the application name to "Empire" to support Empire-specific
customization of readline. Use in .inputrc looks like this:
$if Empire
set bell-style audible
set history-size 500
else
set bell-style visible
$endif
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Readline is for interactive use. For non-interactive use, it merely
complicates things. Case in point: it slows down "make check" by almost
10% for me.
Interactive use should always involve a TTY, so use readline only when
standard input is a TTY. This supresses readline in "make check".
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
AX_LIB_READLINE tries to cope with systems where readline lacks
history support, or lacks headers, or needs headers included in
unorthodox ways. It puts six HAVE_ macros into config.h, and its
usage example takes 24 lines of code just to include two headers.
Way too complicated for my taste. Replace with new MY_LIB_READLINE,
which succeeds only when you have a sane readline, and then defines
*one* macro: HAVE_LIBREADLINE.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
If recv_input() can't stuff the whole line into @inbuf, it leaves its
tail in @input_from_rl. If send_input() then empties @inbuf, the next
iteration will select @input_fd for reading instead of @sock for
writing, because @inbuf is empty. Since @has_rl_input is still set,
recv_input() will do nothing, and the client hangs.
Fix as follows. Factor ring_from_rl() out of recv_input(). Also call
it in send_input() to refill @inbuf from @input_from_rl.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Document readline in more detail in man/empire.6.
Make @history_file local to main().
main() silently truncates the home directory name to 1000 characters
when constructing the history file name; mark FIXME.
Set @rl_already_prompted just once.
Write history file on unsuccessful exit, too.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Readline provides fancy command line editing such as <Arrow Up> for
previous commands and CTRL+A to jump to the beginning of the line.
This patch does not add any completion on <tab> key, a TODO, if you
will.
A new command line flag, -H, turns on saving the history to disk.
This may have security implications on shared computers, as all
commands are saved as-is. Thus "change re 1234" would be logged
directly to the file.
Signed-off-by: Martin Haukeli <martin.haukeli@gmail.com>
Rebase on top of preparatory work, fix a few bugs, and tidy up:
* Update the standalone client build, too.
* Fix the Windows build.
* Keep command line options sorted case-insensitively.
* Error out when $HOME is unset and getpwuid() fails, just like we do
for $LOGNAME.
* Give @input_from_rl, @has_rl_input static linkage.
* @has_rl_input is a flag, not a counter, set and test it accordingly.
* Save all input in history, not just commands. Martin's attempt to
recognize commands works only as long as the server sends prompts
faster than the user sends input. Drop that part, and update commit
message accordingly.
* Fix recv_input() not to truncate value of strlen() to int, and to
use memmove() for updating @input_from_rl in place.
* Clean up whitespace in a few places.
* Tweak commit message.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
We need to copy input to @auxfp to implement command line option -2,
and pass it to save_input() to enable protection against a rogue
server exploiting redirection and execute. We currently do this right
when input enters the ring buffer, in recv_input().
Calling save_input() before sending input to the server is sloppy: it
can make the client accept "future" redirections and executes.
Delay save_input() until after input is sent. For simplicity, delay
copying to @auxfp as well.
This is actually pretty close to how things worked before commit
8b7d0b9 (v4.3.11).
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
On successful execute, servercmd() sets @input_fd to the batch file
descriptor. Return the file descriptor instead, and let its caller
recv_output() set @input_fd. This permits giving @input_fd static
linkage.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
recv_input(input_fd, &inbuf) returns zero when @inbuf is full or
@input_fd is at EOF. We avoid the former by putting @input_fd in
@rdfd only when @inbuf has space, so we can detect EOF easily. But we
missed the case where adding a cookie fills up @inbuf. We
misinterpret "can't read into full buffer" as "EOF on input" then.
Fix by checking for space again.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The client can send an interrupt cookie after the EOF cookie.
Harmless, as the server throws away input after the EOF cookie. Clean
it up anyway.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
We increment @send_eof only when read() returns zero, and we read()
only when it's zero. Therefore, we never increment it beyond one.
Change it from counter to flag.
This effectively reverts commit 51846ec (v4.3.11). Possible only
because the previous commit got rid of the @send_eof increment on
failed execute.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The server doesn't currently care for the difference, but interrupt is
more accurate than EOF. The change also enables the next commit.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
recv_input() passes full lines to save_input(). Pass characters
instead. Simpler, and doesn't truncate long lines.
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>
Commit 3cceb59b (v4.3.26) fixed the client to abort commands reliably
on ^C, even when it arrives at the beginning of an input line. Except
it didn't work at the beginning of the first input line, because
input_eol was initialized to zero.
Easily fixed, but "end of line" isn't quite right there. Revert sense
and rename to partial_line_sent.
They can still get split by output arriving between two reads from
input, but that's unavoidable, because the client is designed to read
and write big chunks, not lines.
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.
The server aborts the current command when it receives a special line
of input for a prompt. To make the client send it, you type the INTR
character (normally ^C). This sends the client the SIGINT signal.
Unfortunately, it never quite worked.
Because we use a special line of input to signal interrupt, the client
can do that only after a complete line of input.
What if SIGINT arrives in the middle of a line? We split the line in
two then and there, by inserting a newline. Nasty, but it's simple,
and happens rarely.
However, we inserted the newline always, even after a complete line.
In that case, we inserted an empty line of input before the interrupt.
If you hit INTR at a server prompt, the server received an empty line
of input for that prompt, and the interrupt only for the *next*
prompt. Which may well be too late to abort the command you wanted to
abort.
Fix by inserting the newline only when needed.
Move client's w32_connect() to w32sockets.c.
Replace w32_recv() and w32_send() by read() and write().
Replace w32_close() by w32_close_function.
Replace call of WSAStartup() in w32_sysdep_init() by
w32_socket_init().
Remove the identical copies of fd_is_socket(),
w32_set_winsock_errno(), w32_socket().
Unlike POSIX sockets, Windows sockets are not file descriptors, but
"OS handles", with a completely separate set of functions.
However, Windows can create a file descriptor for a socket, and return
a file descriptor's underlying handle. Use that instead of our gross
hacks to keep up the illusion that sockets are file descriptors.
Slightly dirty: we put file descriptors into fd_set. Works because
both boil down to int. Change w32_select(), w32_socket(),
w32_connect(), w32_recv(), w32_writev_socket(), w32_send() to take and
return only file descriptors, and map to sockets internally. Replace
w32_close_socket() by w32_close(), and drop the close() macro hackery
that made tcp_connect(), host_connect() use w32_close_socket(). New
fd_is_socket().
Windows provides select()-like functions only for handles. Because of
that, the client used a handle for reading script files, and stored it
in file descriptor input_fd. Drop this dirty hack, use a file
descriptor instead. Works because we can get its underlying handle.
Remove the dirty macro hackery that made play(), ring_from_file() and
doexecute() unwittingly work with a handle. Remove w32_openhandle()
and w32_close_handle(). Replace w32_readv_handle() by w32_readv_fd().
Update w32_select().
Remove w32_openfd(), it's not really needed.
The old code stuffed WSA error codes into errno, which doesn't work.
Use new w32_set_winsock_errno() to convert & stuff.
Fix signed vs. unsigned warnings in Windows client.
Move the struct sigaction replacement next to the sigaction()
replacement.
Rename sysdep_init() to w32_sysdep_init() for consistency.
When select() gets interrupted by SIGINT while a handler is active
without SA_RESTART, it returns immediately with EINTR. w32_select()
did that only while it waited for standard input to become ready for
reading. This isn't the case when:
* The client has already received EOF on standard input. But then the
action is SIG_DFL, so there was no problem.
* Reading standard input is suspended until the server drains the
input buffer. Then reaction to Ctrl-C got delayed until the socket
got ready, and w32_select() returned normally. Harmless, because
the reaction merely appends to the input buffer.
Change w32_select() to match select()'s behavior anyway.
We use the C run-time, so we better use its _beginthread(), too.
CreateThread() can lead to deadlocks, at least with some versions of
the C run-time. Broken in commit f082ef9f, v4.3.11.
stdin_read_thread() zeroed bounce_status on failure, effectifely
treating it like EOF. Fix by setting to -1.
It treated main thread termination like failure, and set bounce_error
to a bogus value. Can't happen, because the program terminates when
the main thread terminates, and the only user of bounce_error is the
main thread anyway. Regardless, handle the case by terminating,
because that's more obviously correct.
Broken in commit f082ef9f, v4.3.11.
Should be more portable to modern systems and could be less portable
to obsolete systems than the traditional sys/time.h sys/types.h
unistd.h incantation.
Player input may overtake batch file contents (well-known protocol
flaw, see doc/clients-howto for details). This includes EOF. When
that happens, the client closes standard input, sends an EOF cookie,
and continues reading output until the server closes the connection.
When it gets C_EXECUTE, it redirects input to the batch file. But it
then failed to read the batch file. The server waited forever for the
execute's EOF cookie, the client waited forever for the server closing
the connection.
Fix by stopping only reading from standard input. Broken in 8b7d0b91,
v4.3.11.
Note that the EOF cookie still overtakes the batch file contents,
which makes the server interpret the input between the execute command
and the EOF as batch file, and the batch file contents as ordinary
input.