telnetd: add -w ("inetd wait") option. Can be configured off.
gcc fils to fully optimize it out when it's off: function old new delta telnetd_main 1527 1548 +21 packed_usage 26596 26587 -9 but nevertheless it's a useful (and so far single) example how to write "inetd wait" tcp service. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
cfc216345e
commit
ed1667e8ee
@ -1468,11 +1468,11 @@
|
||||
"\n -m Get baud rate from modem's CONNECT status message" \
|
||||
"\n -w Wait for a CR or LF before sending /etc/issue" \
|
||||
"\n -n Do not prompt the user for a login name" \
|
||||
"\n -f issue_file Display issue_file instead of /etc/issue" \
|
||||
"\n -l login_app Invoke login_app instead of /bin/login" \
|
||||
"\n -t timeout Terminate after timeout if no username is read" \
|
||||
"\n -I initstring Init string to send before anything else" \
|
||||
"\n -H login_host Log login_host into the utmp file as the hostname" \
|
||||
"\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue" \
|
||||
"\n -l LOGIN Invoke LOGIN instead of /bin/login" \
|
||||
"\n -t SEC Terminate after SEC if no username is read" \
|
||||
"\n -I INITSTR Send INITSTR before anything else" \
|
||||
"\n -H HOST Log HOST into the utmp file as the hostname" \
|
||||
|
||||
#define grep_trivial_usage \
|
||||
"[-HhrilLnqvso" \
|
||||
@ -4415,14 +4415,18 @@
|
||||
IF_NOT_FEATURE_TELNETD_STANDALONE(" via inetd") "\n" \
|
||||
"\nOptions:" \
|
||||
"\n -l LOGIN Exec LOGIN on connect" \
|
||||
"\n -f issue_file Display issue_file instead of /etc/issue" \
|
||||
"\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue" \
|
||||
"\n -K Close connection as soon as login exits" \
|
||||
"\n (normally wait until all programs close slave pty)" \
|
||||
IF_FEATURE_TELNETD_STANDALONE( \
|
||||
"\n -p PORT Port to listen on" \
|
||||
"\n -b ADDR Address to bind to" \
|
||||
"\n -b ADDR[:PORT] Address to bind to" \
|
||||
"\n -F Run in foreground" \
|
||||
"\n -i Run as inetd subservice" \
|
||||
"\n -i Run as inetd service" \
|
||||
IF_FEATURE_TELNETD_INETD_WAIT( \
|
||||
"\n -w SEC Run as inetd service in wait mode, linger time SEC" \
|
||||
"\n -S Log to syslog (implied by -i or without -F and -w)" \
|
||||
) \
|
||||
)
|
||||
|
||||
/* "test --help" does not print help (POSIX compat), only "[ --help" does.
|
||||
|
@ -788,6 +788,27 @@ config FEATURE_TELNETD_STANDALONE
|
||||
help
|
||||
Selecting this will make telnetd able to run standalone.
|
||||
|
||||
config FEATURE_TELNETD_INETD_WAIT
|
||||
bool "Support -w SEC option (inetd wait mode)"
|
||||
default n
|
||||
depends on FEATURE_TELNETD_STANDALONE
|
||||
help
|
||||
This option allows you to run telnetd in "inet wait" mode.
|
||||
Example inetd.conf line (note "wait", not usual "nowait"):
|
||||
|
||||
telnet stream tcp wait root /bin/telnetd telnetd -w10
|
||||
|
||||
In this example, inetd passes _listening_ socket_ as fd 0
|
||||
to telnetd when connection appears.
|
||||
telnetd will wait for connections until all existing
|
||||
connections are closed, and no new connections
|
||||
appear during 10 seconds. Then it exits, and inetd continues
|
||||
to listen for new connections.
|
||||
|
||||
This option is rarely used. "tcp nowait" is much more usual
|
||||
way of running tcp services, including telnetd.
|
||||
You most probably want to say N here.
|
||||
|
||||
config TFTP
|
||||
bool "tftp"
|
||||
default n
|
||||
|
@ -211,8 +211,10 @@ static size_t iac_safe_write(int fd, const char *buf, size_t count)
|
||||
enum {
|
||||
OPT_WATCHCHILD = (1 << 2), /* -K */
|
||||
OPT_INETD = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
|
||||
OPT_PORT = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
|
||||
OPT_PORT = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p PORT */
|
||||
OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
|
||||
OPT_SYSLOG = (1 << 7) * ENABLE_FEATURE_TELNETD_INETD_WAIT, /* -S */
|
||||
OPT_WAIT = (1 << 8) * ENABLE_FEATURE_TELNETD_INETD_WAIT, /* -w SEC */
|
||||
};
|
||||
|
||||
static struct tsession *
|
||||
@ -438,24 +440,29 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv)
|
||||
struct tsession *ts;
|
||||
#if ENABLE_FEATURE_TELNETD_STANDALONE
|
||||
#define IS_INETD (opt & OPT_INETD)
|
||||
int master_fd = master_fd; /* be happy, gcc */
|
||||
unsigned portnbr = 23;
|
||||
int master_fd = master_fd; /* for compiler */
|
||||
int sec_linger = sec_linger;
|
||||
char *opt_bindaddr = NULL;
|
||||
char *opt_portnbr;
|
||||
#else
|
||||
enum {
|
||||
IS_INETD = 1,
|
||||
master_fd = -1,
|
||||
portnbr = 23,
|
||||
};
|
||||
#endif
|
||||
INIT_G();
|
||||
|
||||
/* -w NUM, and implies -F. -w and -i don't mix */
|
||||
IF_FEATURE_TELNETD_INETD_WAIT(opt_complementary = "wF:w+:i--w:w--i";)
|
||||
/* Even if !STANDALONE, we accept (and ignore) -i, thus people
|
||||
* don't need to guess whether it's ok to pass -i to us */
|
||||
opt = getopt32(argv, "f:l:Ki" IF_FEATURE_TELNETD_STANDALONE("p:b:F"),
|
||||
opt = getopt32(argv, "f:l:Ki"
|
||||
IF_FEATURE_TELNETD_STANDALONE("p:b:F")
|
||||
IF_FEATURE_TELNETD_INETD_WAIT("Sw:"),
|
||||
&G.issuefile, &G.loginpath
|
||||
IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr));
|
||||
IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr)
|
||||
IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger)
|
||||
);
|
||||
if (!IS_INETD /*&& !re_execed*/) {
|
||||
/* inform that we start in standalone mode?
|
||||
* May be useful when people forget to give -i */
|
||||
@ -467,32 +474,30 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv)
|
||||
}
|
||||
}
|
||||
/* Redirect log to syslog early, if needed */
|
||||
if (IS_INETD || !(opt & OPT_FOREGROUND)) {
|
||||
if (IS_INETD || (opt & OPT_SYSLOG) || !(opt & OPT_FOREGROUND)) {
|
||||
openlog(applet_name, LOG_PID, LOG_DAEMON);
|
||||
logmode = LOGMODE_SYSLOG;
|
||||
}
|
||||
IF_FEATURE_TELNETD_STANDALONE(
|
||||
if (opt & OPT_PORT)
|
||||
portnbr = xatou16(opt_portnbr);
|
||||
);
|
||||
|
||||
/* Used to check access(G.loginpath, X_OK) here. Pointless.
|
||||
* exec will do this for us for free later. */
|
||||
|
||||
#if ENABLE_FEATURE_TELNETD_STANDALONE
|
||||
if (IS_INETD) {
|
||||
G.sessions = make_new_session(0);
|
||||
if (!G.sessions) /* pty opening or vfork problem, exit */
|
||||
return 1; /* make_new_session prints error message */
|
||||
return 1; /* make_new_session printed error message */
|
||||
} else {
|
||||
master_fd = create_and_bind_stream_or_die(opt_bindaddr, portnbr);
|
||||
xlisten(master_fd, 1);
|
||||
master_fd = 0;
|
||||
if (!(opt & OPT_WAIT)) {
|
||||
unsigned portnbr = 23;
|
||||
if (opt & OPT_PORT)
|
||||
portnbr = xatou16(opt_portnbr);
|
||||
master_fd = create_and_bind_stream_or_die(opt_bindaddr, portnbr);
|
||||
xlisten(master_fd, 1);
|
||||
}
|
||||
close_on_exec_on(master_fd);
|
||||
}
|
||||
#else
|
||||
G.sessions = make_new_session();
|
||||
if (!G.sessions) /* pty opening or vfork problem, exit */
|
||||
return 1; /* make_new_session prints error message */
|
||||
return 1; /* make_new_session printed error message */
|
||||
#endif
|
||||
|
||||
/* We don't want to die if just one session is broken */
|
||||
@ -556,7 +561,18 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv)
|
||||
G.maxfd = master_fd;
|
||||
}
|
||||
|
||||
count = select(G.maxfd + 1, &rdfdset, &wrfdset, NULL, NULL);
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timeval *tv_ptr = NULL;
|
||||
if ((opt & OPT_WAIT) && !G.sessions) {
|
||||
tv.tv_sec = sec_linger;
|
||||
tv.tv_usec = 0;
|
||||
tv_ptr = &tv;
|
||||
}
|
||||
count = select(G.maxfd + 1, &rdfdset, &wrfdset, NULL, tv_ptr);
|
||||
}
|
||||
if (count == 0) /* "telnetd -w SEC" timed out */
|
||||
return 0;
|
||||
if (count < 0)
|
||||
goto again; /* EINTR or ENOMEM */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user