diff options
author | Anil Madhavapeddy <avsm@cvs.openbsd.org> | 2005-05-24 20:13:29 +0000 |
---|---|---|
committer | Anil Madhavapeddy <avsm@cvs.openbsd.org> | 2005-05-24 20:13:29 +0000 |
commit | bf70235783a080c2b1da5823628d3a3c8ee141bf (patch) | |
tree | f7337fa8cf6a703274faa808b732a849af826420 | |
parent | 50168be1381281d3882d0cacf8df97174ebe1864 (diff) |
Switch atomicio to a simpler interface which returns size_t and uses
0 to signal errors. should be no functional change in nc apart from
different error messages.
"groovy", said deraadt@
-rw-r--r-- | usr.bin/nc/atomicio.c | 29 | ||||
-rw-r--r-- | usr.bin/nc/atomicio.h | 33 | ||||
-rw-r--r-- | usr.bin/nc/netcat.c | 17 | ||||
-rw-r--r-- | usr.bin/nc/socks.c | 54 |
4 files changed, 78 insertions, 55 deletions
diff --git a/usr.bin/nc/atomicio.c b/usr.bin/nc/atomicio.c index 151dde0cf66..545bbeee949 100644 --- a/usr.bin/nc/atomicio.c +++ b/usr.bin/nc/atomicio.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2005 Anil Madhavapeddy. All rights served. * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. * All rights reserved. * @@ -21,36 +22,42 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * $OpenBSD: atomicio.c,v 1.6 2005/05/24 20:13:28 avsm Exp $ */ #include <sys/types.h> #include <sys/uio.h> - #include <errno.h> #include <unistd.h> - -ssize_t atomicio(ssize_t (*f)(int, void *, size_t), int fd, void *_s, size_t n); +#include "atomicio.h" /* - * ensure all of data on socket comes through. f==read || f==write + * ensure all of data on socket comes through. f==read || f==vwrite */ -ssize_t -atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) +size_t +atomicio(f, fd, _s, n) + ssize_t (*f) (int, void *, size_t); + int fd; + void *_s; + size_t n; { char *s = _s; - ssize_t res, pos = 0; + size_t pos = 0; + ssize_t res; - while (n > (size_t)pos) { + while (n > pos) { res = (f) (fd, s + pos, n - pos); switch (res) { case -1: if (errno == EINTR || errno == EAGAIN) continue; + return 0; case 0: - return (res); + errno = EPIPE; + return pos; default: - pos += res; + pos += (u_int)res; } } - return (pos); + return pos; } diff --git a/usr.bin/nc/atomicio.h b/usr.bin/nc/atomicio.h new file mode 100644 index 00000000000..551a0565da8 --- /dev/null +++ b/usr.bin/nc/atomicio.h @@ -0,0 +1,33 @@ +/* $OpenBSD: atomicio.h,v 1.1 2005/05/24 20:13:28 avsm Exp $ */ + +/* + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); + +#define vwrite (ssize_t (*)(int, void *, size_t))write diff --git a/usr.bin/nc/netcat.c b/usr.bin/nc/netcat.c index 88dde5290b1..36d133a2bb4 100644 --- a/usr.bin/nc/netcat.c +++ b/usr.bin/nc/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.78 2005/04/10 19:43:34 otto Exp $ */ +/* $OpenBSD: netcat.c,v 1.79 2005/05/24 20:13:28 avsm Exp $ */ /* * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> * @@ -50,6 +50,7 @@ #include <string.h> #include <unistd.h> #include <fcntl.h> +#include "atomicio.h" #ifndef SUN_LEN #define SUN_LEN(su) \ @@ -80,7 +81,6 @@ int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; -ssize_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); void help(void); @@ -590,7 +590,7 @@ readwrite(int nfd) { struct pollfd pfd[2]; unsigned char buf[BUFSIZ]; - int wfd = fileno(stdin), n; + int n, wfd = fileno(stdin); int lfd = fileno(stdout); /* Setup Network FD */ @@ -623,8 +623,7 @@ readwrite(int nfd) } else { if (tflag) atelnet(nfd, buf, n); - if (atomicio((ssize_t (*)(int, void *, size_t))write, - lfd, buf, n) != n) + if (atomicio(vwrite, lfd, buf, n) != n) return; } } @@ -637,8 +636,7 @@ readwrite(int nfd) pfd[1].fd = -1; pfd[1].events = 0; } else { - if (atomicio((ssize_t (*)(int, void *, size_t))write, - nfd, buf, n) != n) + if (atomicio(vwrite, nfd, buf, n) != n) return; } } @@ -669,9 +667,8 @@ atelnet(int nfd, unsigned char *buf, unsigned int size) p++; obuf[2] = *p; obuf[3] = '\0'; - if (atomicio((ssize_t (*)(int, void *, size_t))write, - nfd, obuf, 3) != 3) - warnx("Write Error!"); + if (atomicio(vwrite, nfd, obuf, 3) != 3) + warn("Write Error!"); obuf[0] = '\0'; } } diff --git a/usr.bin/nc/socks.c b/usr.bin/nc/socks.c index 7380b7999d4..de61439400d 100644 --- a/usr.bin/nc/socks.c +++ b/usr.bin/nc/socks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: socks.c,v 1.14 2005/05/20 22:46:08 djm Exp $ */ +/* $OpenBSD: socks.c,v 1.15 2005/05/24 20:13:28 avsm Exp $ */ /* * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. @@ -37,6 +37,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include "atomicio.h" #define SOCKS_PORT "1080" #define HTTP_PROXY_PORT "3128" @@ -50,7 +51,6 @@ #define SOCKS_DOMAIN 3 #define SOCKS_IPV6 4 -ssize_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); int remote_connect(const char *, const char *, struct addrinfo); int socks_connect(const char *host, const char *port, struct addrinfo hints, const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, @@ -86,18 +86,15 @@ decode_addrport(const char *h, const char *p, struct sockaddr *addr, } static int -proxy_read_line(int fd, char *buf, int bufsz) +proxy_read_line(int fd, char *buf, size_t bufsz) { - int r, off; + size_t off; for(off = 0;;) { if (off >= bufsz) errx(1, "proxy read too long"); - if ((r = read(fd, buf + off, 1)) <= 0) { - if (r == -1 && errno == EINTR) - continue; + if (atomicio(read, fd, buf + off, 1) != 1) err(1, "proxy read"); - } /* Skip CR */ if (buf[off] == '\r') continue; @@ -119,7 +116,7 @@ socks_connect(const char *host, const char *port, int proxyfd, r; size_t hlen, wlen; unsigned char buf[1024]; - ssize_t cnt; + size_t cnt; struct sockaddr_storage addr; struct sockaddr_in *in4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr; @@ -148,13 +145,14 @@ socks_connect(const char *host, const char *port, buf[0] = SOCKS_V5; buf[1] = 1; buf[2] = SOCKS_NOAUTH; - cnt = write(proxyfd, buf, 3); - if (cnt == -1) - err(1, "write failed"); + cnt = atomicio(vwrite, proxyfd, buf, 3); if (cnt != 3) - errx(1, "short write, %d (expected 3)", cnt); + err(1, "write failed (%d/3)", cnt); + + cnt = atomicio(read, proxyfd, buf, 2); + if (cnt != 2) + err(1, "read failed (%d/3)", cnt); - read(proxyfd, buf, 2); if (buf[1] == SOCKS_NOMETHOD) errx(1, "authentication method negotiation failed"); @@ -200,18 +198,13 @@ socks_connect(const char *host, const char *port, errx(1, "internal error: silly AF"); } - cnt = atomicio((ssize_t (*)(int, void *, size_t))write, - proxyfd, buf, wlen); - if (cnt == -1) - err(1, "write failed"); + cnt = atomicio(vwrite, proxyfd, buf, wlen); if (cnt != wlen) - errx(1, "short write, %d (expected %d)", cnt, wlen); + err(1, "write failed (%d/%d)", cnt, wlen); cnt = atomicio(read, proxyfd, buf, 10); - if (cnt == -1) - err(1, "read failed"); if (cnt != 10) - errx(1, "unexpected reply size %d (expected 10)", cnt); + err(1, "read failed (%d/10)", cnt); if (buf[1] != 0) errx(1, "connection failed, SOCKS error %d", buf[1]); } else if (socksv == 4) { @@ -227,17 +220,13 @@ socks_connect(const char *host, const char *port, buf[8] = 0; /* empty username */ wlen = 9; - cnt = write(proxyfd, buf, wlen); - if (cnt == -1) - err(1, "write failed"); + cnt = atomicio(vwrite, proxyfd, buf, wlen); if (cnt != wlen) - errx(1, "short write, %d (expected %d)", cnt, wlen); + err(1, "write failed (%d/%d)", cnt, wlen); cnt = atomicio(read, proxyfd, buf, 8); - if (cnt == -1) - err(1, "read failed"); if (cnt != 8) - errx(1, "unexpected reply size %d (expected 8)", cnt); + err(1, "read failed (%d/8)", cnt); if (buf[1] != 90) errx(1, "connection failed, SOCKS error %d", buf[1]); } else if (socksv == -1) { @@ -261,12 +250,9 @@ socks_connect(const char *host, const char *port, errx(1, "hostname too long"); r = strlen(buf); - cnt = atomicio((ssize_t (*)(int, void *, size_t))write, - proxyfd, buf, r); - if (cnt == -1) - err(1, "write failed"); + cnt = atomicio(vwrite, proxyfd, buf, r); if (cnt != r) - errx(1, "short write, %d (expected %d)", cnt, r); + err(1, "write failed (%d/%d)", cnt, r); /* Read reply */ for (r = 0; r < HTTP_MAXHDRS; r++) { |