Hello,
I have added a new feature to telnetd that might
be of use to others. What I wanted was to use
telnetd in standalone mode but to only service
one connection and to exit if the connection is
not established within a specified timeout. So I
added a "-t <timeout>" argument to telnetd as a
sub-feature of the standalone feature. Changes
are wrapped within the ONESHOT feature.
See patch below.
Please consider for inclusion.
Thank you,
Steve Bradshaw
=============
diff -ru busybox-1.8.2.orig/networking/Config.in
busybox-1.8.2.new/networking/Config.in
--- busybox-1.8.2.orig/networking/Config.in 2007-11-09 17:40:47.000000000
-0800
+++ busybox-1.8.2.new/networking/Config.in 2008-02-22 18:06:45.000000000
-0800
@@ -693,6 +693,14 @@
help
Selecting this will make telnetd able to run standalone.
+config FEATURE_TELNETD_ONESHOT
+ bool "Support one session per telnetd with connect timeout"
+ default n
+ depends on FEATURE_TELNETD_STANDALONE
+ help
+ Allow only one session per telnetd instance and exit if no connection
+ within the timeout.
+
config TFTP
bool "tftp"
default n
diff -ru busybox-1.8.2.orig/networking/telnetd.c
busybox-1.8.2.new/networking/telnetd.c
--- busybox-1.8.2.orig/networking/telnetd.c 2007-11-09 17:54:22.000000000
-0800
+++ busybox-1.8.2.new/networking/telnetd.c 2008-02-27 09:41:24.000000000
-0800
@@ -328,6 +328,7 @@
OPT_INETD = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
OPT_PORT = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
+ OPT_TIMEOUT = (1 << 7) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -t */
};
#if ENABLE_FEATURE_TELNETD_STANDALONE
@@ -337,8 +338,10 @@
{
struct tsession *t = sessions;
- if (option_mask32 & OPT_INETD)
+ if (option_mask32 & (OPT_INETD
+ USE_FEATURE_TELNETD_ONESHOT(| OPT_TIMEOUT))) {
exit(0);
+ }
/* Unlink this telnet session from the session list */
if (t == ts)
@@ -421,6 +424,10 @@
unsigned portnbr = 23;
char *opt_bindaddr = NULL;
char *opt_portnbr;
+#if ENABLE_FEATURE_TELNETD_ONESHOT
+ char *opt_timeout;
+ int timeout = -1;
+#endif
#else
enum {
IS_INETD = 1,
@@ -430,9 +437,12 @@
#endif
/* 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" USE_FEATURE_TELNETD_STANDALONE("p:b:F"),
+ opt = getopt32(argv, "f:l:Ki"
+ USE_FEATURE_TELNETD_STANDALONE("p:b:F"
+ USE_FEATURE_TELNETD_ONESHOT("t:")),
&issuefile, &loginpath
- USE_FEATURE_TELNETD_STANDALONE(, &opt_portnbr,
&opt_bindaddr));
+ USE_FEATURE_TELNETD_STANDALONE(, &opt_portnbr,
&opt_bindaddr
+ USE_FEATURE_TELNETD_ONESHOT(, &opt_timeout)));
if (!IS_INETD /*&& !re_execed*/) {
/* inform that we start in standalone mode?
* May be useful when people forget to give -i */
@@ -451,6 +461,10 @@
USE_FEATURE_TELNETD_STANDALONE(
if (opt & OPT_PORT)
portnbr = xatou16(opt_portnbr);
+ USE_FEATURE_TELNETD_ONESHOT(
+ if (opt & OPT_TIMEOUT)
+ timeout = xatou_range(opt_timeout, 0, INT_MAX);
+ )
);
/* Used to check access(loginpath, X_OK) here. Pointless.
@@ -461,9 +475,19 @@
sessions = make_new_session(0);
if (!sessions) /* pty opening or vfork problem, exit */
return 1; /* make_new_session prints error message */
+#if ENABLE_FEATURE_TELNETD_ONESHOT
+ timeout = -1; /* disable if in inetd mode */
+#endif
} else {
master_fd = create_and_bind_stream_or_die(opt_bindaddr,
portnbr);
xlisten(master_fd, 1);
+#if ENABLE_FEATURE_TELNETD_ONESHOT
+ if (timeout >= 0) {
+ /* wakeup accept() in "timeout" seconds */
+ signal(SIGALRM, exit); /* Bypass "Alarm clock" message
*/
+ alarm(timeout);
+ }
+#endif
}
#else
sessions = make_new_session();
@@ -523,7 +547,7 @@
}
ts = next;
}
- if (!IS_INETD) {
+ if (!IS_INETD && USE_FEATURE_TELNETD_ONESHOT(master_fd >= 0)) {
FD_SET(master_fd, &rdfdset);
/* This is needed because free_session() does not
* take master_fd into account when it finds new
@@ -538,13 +562,19 @@
#if ENABLE_FEATURE_TELNETD_STANDALONE
/* First check for and accept new sessions. */
- if (!IS_INETD && FD_ISSET(master_fd, &rdfdset)) {
+ if ( !IS_INETD USE_FEATURE_TELNETD_ONESHOT(&& master_fd >= 0)
+ && FD_ISSET(master_fd, &rdfdset)) {
int fd;
struct tsession *new_ts;
fd = accept(master_fd, NULL, NULL);
if (fd < 0)
goto again;
+#if ENABLE_FEATURE_TELNETD_ONESHOT
+ /* Cancel SIGALRM if it was setup */
+ if (timeout >= 0)
+ alarm(0);
+#endif
/* Create a new session and link it into our active list */
new_ts = make_new_session(fd);
if (new_ts) {
@@ -553,6 +583,13 @@
} else {
close(fd);
}
+#if ENABLE_FEATURE_TELNETD_ONESHOT
+ /* Accept only one session per telnetd */
+ if (timeout >= 0) {
+ close(master_fd);
+ master_fd = -1;
+ }
+#endif
}
#endif
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox