summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnil Madhavapeddy <avsm@cvs.openbsd.org>2005-05-24 20:13:29 +0000
committerAnil Madhavapeddy <avsm@cvs.openbsd.org>2005-05-24 20:13:29 +0000
commitbf70235783a080c2b1da5823628d3a3c8ee141bf (patch)
treef7337fa8cf6a703274faa808b732a849af826420
parent50168be1381281d3882d0cacf8df97174ebe1864 (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.c29
-rw-r--r--usr.bin/nc/atomicio.h33
-rw-r--r--usr.bin/nc/netcat.c17
-rw-r--r--usr.bin/nc/socks.c54
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++) {