ok nicm, but you should save jmc the effort and trim the lines you left with trailing spaces in the man page ;-).
On Fri, Jan 07, 2011 at 12:13:43PM -0800, Jeremy Evans wrote: > On 01/07 07:31, Nicholas Marriott wrote: > > On Fri, Jan 07, 2011 at 10:52:18AM -0800, Jeremy Evans wrote: > > > On 01/07 06:21, Nicholas Marriott wrote: > > Two further minor comments: > > > > - Can the mktemp buffer be on the stack rather than malloc()d? > > Sure. > > > - I think the man page should mention it creates a file in /tmp (or > > mktemp). > > Makes sense. > > OK to commit this diff, which contains the above changes?: > > Index: atomicio.c > =================================================================== > RCS file: /cvs/src/usr.bin/nc/atomicio.c,v > retrieving revision 1.9 > diff -u -p -r1.9 atomicio.c > --- atomicio.c 7 Sep 2007 14:50:44 -0000 1.9 > +++ atomicio.c 6 Jan 2011 21:48:04 -0000 > @@ -53,7 +53,7 @@ atomicio(ssize_t (*f) (int, void *, size > case -1: > if (errno == EINTR) > continue; > - if (errno == EAGAIN) { > + if ((errno == EAGAIN) || (errno == ENOBUFS)) { > (void)poll(&pfd, 1, -1); > continue; > } > Index: nc.1 > =================================================================== > RCS file: /cvs/src/usr.bin/nc/nc.1,v > retrieving revision 1.55 > diff -u -p -r1.55 nc.1 > --- nc.1 25 Jul 2010 07:51:39 -0000 1.55 > +++ nc.1 7 Jan 2011 20:08:35 -0000 > @@ -155,6 +155,10 @@ assigns them. > Enables the RFC 2385 TCP MD5 signature option. > .It Fl s Ar source_ip_address > Specifies the IP of the interface which is used to send the packets. > +For > +.Ux Ns -domain > +datagram sockets, specifies the local temporary socket file > +to create and use so that datagrams can be received. > It is an error to use this option in conjunction with the > .Fl l > option. > @@ -179,6 +183,15 @@ Specifies to use > sockets. > .It Fl u > Use UDP instead of the default option of TCP. > +For > +.Ux Ns -domain > +sockets, use a datagram socket instead of a stream socket. > +If a > +.Ux Ns -domain > +socket is used, a temporary receiving socket is created in /tmp unless > +you specify one with the > +.Fl s > +flag. > .It Fl V Ar rtable > Set the routing table to be used. > The default is 0. > Index: netcat.c > =================================================================== > RCS file: /cvs/src/usr.bin/nc/netcat.c,v > retrieving revision 1.98 > diff -u -p -r1.98 netcat.c > --- netcat.c 3 Jul 2010 04:44:51 -0000 1.98 > +++ netcat.c 7 Jan 2011 20:03:37 -0000 > @@ -62,6 +62,7 @@ > > #define PORT_MAX 65535 > #define PORT_MAX_LEN 6 > +#define UNIX_DG_TMP_SOCKET_SIZE 19 > > /* Command Line Options */ > int dflag; /* detached, no stdin */ > @@ -89,6 +90,7 @@ u_int rtableid; > int timeout = -1; > int family = AF_UNSPEC; > char *portlist[PORT_MAX+1]; > +char *unix_dg_tmp_socket; > > void atelnet(int, unsigned char *, unsigned int); > void build_ports(char *); > @@ -99,6 +101,7 @@ int remote_connect(const char *, const c > int socks_connect(const char *, const char *, struct addrinfo, > const char *, const char *, struct addrinfo, int, const char *); > int udptest(int); > +int unix_bind(char *); > int unix_connect(char *); > int unix_listen(char *); > void set_common_sockopts(int); > @@ -117,6 +120,7 @@ main(int argc, char *argv[]) > char *proxy; > const char *errstr, *proxyhost = "", *proxyport = NULL; > struct addrinfo proxyhints; > + char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; > > ret = 1; > s = 0; > @@ -241,8 +245,6 @@ main(int argc, char *argv[]) > > /* Cruft to make sure options are clean, and used properly. */ > if (argv[0] && !argv[1] && family == AF_UNIX) { > - if (uflag) > - errx(1, "cannot use -u and -U"); > host = argv[0]; > uport = NULL; > } else if (argv[0] && !argv[1]) { > @@ -265,6 +267,19 @@ main(int argc, char *argv[]) > if (!lflag && kflag) > errx(1, "must use -l with -k"); > > + /* Get name of temporary socket for unix datagram client */ > + if ((family == AF_UNIX) && uflag && !lflag) { > + if (sflag) { > + unix_dg_tmp_socket = sflag; > + } else { > + strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", > + UNIX_DG_TMP_SOCKET_SIZE); > + if (mktemp(unix_dg_tmp_socket_buf) == NULL) > + err(1, "mktemp"); > + unix_dg_tmp_socket = unix_dg_tmp_socket_buf; > + } > + } > + > /* Initialize addrinfo structure. */ > if (family != AF_UNIX) { > memset(&hints, 0, sizeof(struct addrinfo)); > @@ -307,8 +322,12 @@ main(int argc, char *argv[]) > int connfd; > ret = 0; > > - if (family == AF_UNIX) > - s = unix_listen(host); > + if (family == AF_UNIX) { > + if (uflag) > + s = unix_bind(host); > + else > + s = unix_listen(host); > + } > > /* Allow only one connection at a time, but stay alive. */ > for (;;) { > @@ -337,17 +356,21 @@ main(int argc, char *argv[]) > if (rv < 0) > err(1, "connect"); > > - connfd = s; > + readwrite(s); > } else { > len = sizeof(cliaddr); > connfd = accept(s, (struct sockaddr *)&cliaddr, > &len); > + readwrite(connfd); > + close(connfd); > } > > - readwrite(connfd); > - close(connfd); > if (family != AF_UNIX) > close(s); > + else if (uflag) { > + if (connect(s, NULL, 0) < 0) > + err(1, "connect"); > + } > > if (!kflag) > break; > @@ -361,6 +384,8 @@ main(int argc, char *argv[]) > } else > ret = 1; > > + if (uflag) > + unlink(unix_dg_tmp_socket); > exit(ret); > > } else { > @@ -421,18 +446,19 @@ main(int argc, char *argv[]) > } > > /* > - * unix_connect() > - * Returns a socket connected to a local unix socket. Returns -1 on failure. > + * unix_bind() > + * Returns a unix socket bound to the given path > */ > int > -unix_connect(char *path) > +unix_bind(char *path) > { > struct sockaddr_un sun; > int s; > > - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) > + /* Create unix domain socket. */ > + if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, > + 0)) < 0) > return (-1); > - (void)fcntl(s, F_SETFD, 1); > > memset(&sun, 0, sizeof(struct sockaddr_un)); > sun.sun_family = AF_UNIX; > @@ -443,27 +469,32 @@ unix_connect(char *path) > errno = ENAMETOOLONG; > return (-1); > } > - if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { > + > + if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { > close(s); > return (-1); > } > return (s); > - > } > > /* > - * unix_listen() > - * Create a unix domain socket, and listen on it. > + * unix_connect() > + * Returns a socket connected to a local unix socket. Returns -1 on failure. > */ > int > -unix_listen(char *path) > +unix_connect(char *path) > { > struct sockaddr_un sun; > int s; > > - /* Create unix domain socket. */ > - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) > - return (-1); > + if (uflag) { > + if ((s = unix_bind(unix_dg_tmp_socket)) < 0) > + return (-1); > + } else { > + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) > + return (-1); > + } > + (void)fcntl(s, F_SETFD, 1); > > memset(&sun, 0, sizeof(struct sockaddr_un)); > sun.sun_family = AF_UNIX; > @@ -474,11 +505,24 @@ unix_listen(char *path) > errno = ENAMETOOLONG; > return (-1); > } > - > - if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { > + if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { > close(s); > return (-1); > } > + return (s); > + > +} > + > +/* > + * unix_listen() > + * Create a unix domain socket, and listen on it. > + */ > +int > +unix_listen(char *path) > +{ > + int s; > + if ((s = unix_bind(path)) < 0) > + return (-1); > > if (listen(s, 5) < 0) { > close(s);