[c5c522c] | 1 | From: Aron Xu <aron@debian.org> |
---|
| 2 | Date: Mon, 13 Feb 2012 15:16:04 +0800 |
---|
| 3 | Subject: quit timer |
---|
| 4 | |
---|
| 5 | --- |
---|
| 6 | nc.1 | 5 +++++ |
---|
| 7 | netcat.c | 38 +++++++++++++++++++++++++++++++++----- |
---|
| 8 | 2 files changed, 38 insertions(+), 5 deletions(-) |
---|
| 9 | |
---|
| 10 | diff --git a/nc.1 b/nc.1 |
---|
| 11 | index af44976..0d92b74 100644 |
---|
| 12 | --- a/nc.1 |
---|
| 13 | +++ b/nc.1 |
---|
| 14 | @@ -40,6 +40,7 @@ |
---|
| 15 | .Op Fl O Ar length |
---|
| 16 | .Op Fl P Ar proxy_username |
---|
| 17 | .Op Fl p Ar source_port |
---|
| 18 | +.Op Fl q Ar seconds |
---|
| 19 | .Op Fl s Ar source |
---|
| 20 | .Op Fl T Ar toskeyword |
---|
| 21 | .Op Fl V Ar rtable |
---|
| 22 | @@ -148,6 +149,10 @@ Proxy authentication is only supported for HTTP CONNECT proxies at present. |
---|
| 23 | Specifies the source port |
---|
| 24 | .Nm |
---|
| 25 | should use, subject to privilege restrictions and availability. |
---|
| 26 | +.It Fl q Ar seconds |
---|
| 27 | +after EOF on stdin, wait the specified number of seconds and then quit. If |
---|
| 28 | +.Ar seconds |
---|
| 29 | +is negative, wait forever. |
---|
| 30 | .It Fl r |
---|
| 31 | Specifies that source and/or destination ports should be chosen randomly |
---|
| 32 | instead of sequentially within a range or in the order that the system |
---|
| 33 | diff --git a/netcat.c b/netcat.c |
---|
| 34 | index 4f4d2bf..29ecf1a 100644 |
---|
| 35 | --- a/netcat.c |
---|
| 36 | +++ b/netcat.c |
---|
| 37 | @@ -86,6 +86,7 @@ |
---|
| 38 | #include <errno.h> |
---|
| 39 | #include <netdb.h> |
---|
| 40 | #include <poll.h> |
---|
| 41 | +#include <signal.h> |
---|
| 42 | #include <stdarg.h> |
---|
| 43 | #include <stdio.h> |
---|
| 44 | #include <stdlib.h> |
---|
| 45 | @@ -120,6 +121,7 @@ int lflag; /* Bind to local port */ |
---|
| 46 | int nflag; /* Don't do name look up */ |
---|
| 47 | char *Pflag; /* Proxy username */ |
---|
| 48 | char *pflag; /* Localport flag */ |
---|
| 49 | +int qflag = 0; /* Quit after some secs */ |
---|
| 50 | int rflag; /* Random ports flag */ |
---|
| 51 | char *sflag; /* Source Address */ |
---|
| 52 | int tflag; /* Telnet Emulation */ |
---|
| 53 | @@ -158,6 +160,7 @@ void usage(int); |
---|
| 54 | |
---|
| 55 | static int connect_with_timeout(int fd, const struct sockaddr *sa, |
---|
| 56 | socklen_t salen, int ctimeout); |
---|
| 57 | +static void quit(); |
---|
| 58 | |
---|
| 59 | int |
---|
| 60 | main(int argc, char *argv[]) |
---|
| 61 | @@ -181,7 +184,7 @@ main(int argc, char *argv[]) |
---|
| 62 | sv = NULL; |
---|
| 63 | |
---|
| 64 | while ((ch = getopt(argc, argv, |
---|
| 65 | - "46CDdhI:i:jklnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { |
---|
| 66 | + "46CDdhI:i:jklnO:P:p:q:rSs:tT:UuV:vw:X:x:z")) != -1) { |
---|
| 67 | switch (ch) { |
---|
| 68 | case '4': |
---|
| 69 | family = AF_INET; |
---|
| 70 | @@ -235,6 +238,11 @@ main(int argc, char *argv[]) |
---|
| 71 | case 'p': |
---|
| 72 | pflag = optarg; |
---|
| 73 | break; |
---|
| 74 | + case 'q': |
---|
| 75 | + qflag = strtonum(optarg, INT_MIN, INT_MAX, &errstr); |
---|
| 76 | + if (errstr) |
---|
| 77 | + errx(1, "quit timer %s: %s", errstr, optarg); |
---|
| 78 | + break; |
---|
| 79 | case 'r': |
---|
| 80 | rflag = 1; |
---|
| 81 | break; |
---|
| 82 | @@ -924,9 +932,18 @@ readwrite(int nfd) |
---|
| 83 | } |
---|
| 84 | else if (pfd[1].revents & POLLHUP) { |
---|
| 85 | shutdown_wr: |
---|
| 86 | + /* if the user asked to exit on EOF, do it */ |
---|
| 87 | + if (qflag == 0) { |
---|
| 88 | shutdown(nfd, SHUT_WR); |
---|
| 89 | - pfd[1].fd = -1; |
---|
| 90 | - pfd[1].events = 0; |
---|
| 91 | + close(wfd); |
---|
| 92 | + } |
---|
| 93 | + /* if user asked to die after a while, arrange for it */ |
---|
| 94 | + if (qflag > 0) { |
---|
| 95 | + signal(SIGALRM, quit); |
---|
| 96 | + alarm(qflag); |
---|
| 97 | + } |
---|
| 98 | + pfd[1].fd = -1; |
---|
| 99 | + pfd[1].events = 0; |
---|
| 100 | } |
---|
| 101 | } |
---|
| 102 | } |
---|
| 103 | @@ -1164,6 +1181,7 @@ help(void) |
---|
| 104 | \t-O length TCP send buffer length\n\ |
---|
| 105 | \t-P proxyuser\tUsername for proxy authentication\n\ |
---|
| 106 | \t-p port\t Specify local port for remote connects\n\ |
---|
| 107 | + \t-q secs\t quit after EOF on stdin and delay of secs\n\ |
---|
| 108 | \t-r Randomize remote ports\n\ |
---|
| 109 | \t-S Enable the TCP MD5 signature option\n\ |
---|
| 110 | \t-s addr\t Local source address\n\ |
---|
| 111 | @@ -1186,9 +1204,19 @@ usage(int ret) |
---|
| 112 | { |
---|
| 113 | fprintf(stderr, |
---|
| 114 | "usage: nc [-46CDdhjklnrStUuvz] [-I length] [-i interval] [-O length]\n" |
---|
| 115 | - "\t [-P proxy_username] [-p source_port] [-s source] [-T toskeyword]\n" |
---|
| 116 | - "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" |
---|
| 117 | + "\t [-P proxy_username] [-p source_port] [-q seconds] [-s source]\n" |
---|
| 118 | + "\t [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]\n" |
---|
| 119 | "\t [-x proxy_address[:port]] [destination] [port]\n"); |
---|
| 120 | if (ret) |
---|
| 121 | exit(1); |
---|
| 122 | } |
---|
| 123 | + |
---|
| 124 | +/* |
---|
| 125 | + * quit() |
---|
| 126 | + * handler for a "-q" timeout (exit 0 instead of 1) |
---|
| 127 | + */ |
---|
| 128 | +static void quit() |
---|
| 129 | +{ |
---|
| 130 | + /* XXX: should explicitly close fds here */ |
---|
| 131 | + exit(0); |
---|
| 132 | +} |
---|
| 133 | -- |
---|