From 05624c18147b87ed4d808da3cdad04f74740a703 Mon Sep 17 00:00:00 2001 From: djm Date: Thu, 26 May 2005 02:23:44 +0000 Subject: [PATCH] - avsm@cvs.openbsd.org 2005/05/24 17:32:44 [atomicio.c atomicio.h authfd.c monitor_wrap.c msg.c scp.c sftp-client.c] [ssh-keyscan.c sshconnect.c] Switch atomicio to use a simpler interface; it now returns a size_t (containing number of bytes read/written), and indicates error by returning 0. EOF is signalled by errno==EPIPE. Typical use now becomes: if (atomicio(read, ..., len) != len) err(1,"read"); ok deraadt@, cloder@, djm@ --- ChangeLog | 12 ++++++++++++ atomicio.c | 14 +++++++++----- atomicio.h | 4 ++-- authfd.c | 5 ++--- monitor_wrap.c | 19 ++++++++----------- msg.c | 15 ++++++--------- scp.c | 26 ++++++++++++++------------ sftp-client.c | 29 +++++++++++++++-------------- ssh-keyscan.c | 27 +++++++++++++++------------ sshconnect.c | 13 +++++++------ 10 files changed, 90 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index 115014bf..5c316d83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -83,6 +83,18 @@ - avsm@cvs.openbsd.org 2005/05/24 02:05:09 [ssh-keygen.c] some style nits from dmiller@, and use a fatal() instead of a printf()/exit + - avsm@cvs.openbsd.org 2005/05/24 17:32:44 + [atomicio.c atomicio.h authfd.c monitor_wrap.c msg.c scp.c sftp-client.c] + [ssh-keyscan.c sshconnect.c] + Switch atomicio to use a simpler interface; it now returns a size_t + (containing number of bytes read/written), and indicates error by + returning 0. EOF is signalled by errno==EPIPE. + Typical use now becomes: + + if (atomicio(read, ..., len) != len) + err(1,"read"); + + ok deraadt@, cloder@, djm@ 20050524 - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] diff --git a/atomicio.c b/atomicio.c index 7637e167..12abbda1 100644 --- a/atomicio.c +++ b/atomicio.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. * All rights reserved. * @@ -24,14 +25,14 @@ */ #include "includes.h" -RCSID("$OpenBSD: atomicio.c,v 1.12 2003/07/31 15:50:16 avsm Exp $"); +RCSID("$OpenBSD: atomicio.c,v 1.13 2005/05/24 17:32:43 avsm Exp $"); #include "atomicio.h" /* * ensure all of data on socket comes through. f==read || f==vwrite */ -ssize_t +size_t atomicio(f, fd, _s, n) ssize_t (*f) (int, void *, size_t); int fd; @@ -39,7 +40,8 @@ atomicio(f, fd, _s, n) size_t n; { char *s = _s; - ssize_t res, pos = 0; + size_t pos = 0; + ssize_t res; while (n > pos) { res = (f) (fd, s + pos, n - pos); @@ -51,10 +53,12 @@ atomicio(f, fd, _s, n) if (errno == EINTR || errno == EAGAIN) #endif continue; + return 0; case 0: - return (res); + errno = EPIPE; + return pos; default: - pos += res; + pos += (u_int)res; } } return (pos); diff --git a/atomicio.h b/atomicio.h index 5c0f392e..7eccf206 100644 --- a/atomicio.h +++ b/atomicio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.h,v 1.5 2003/06/28 16:23:06 deraadt Exp $ */ +/* $OpenBSD: atomicio.h,v 1.6 2005/05/24 17:32:43 avsm Exp $ */ /* * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. @@ -28,6 +28,6 @@ /* * Ensure all of data on socket comes through. f==read || f==vwrite */ -ssize_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); +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/authfd.c b/authfd.c index 662350ce..9ce5b5ea 100644 --- a/authfd.c +++ b/authfd.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.64 2004/08/11 21:44:31 avsm Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.65 2005/05/24 17:32:43 avsm Exp $"); #include @@ -149,8 +149,7 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply l = len; if (l > sizeof(buf)) l = sizeof(buf); - l = atomicio(read, auth->fd, buf, l); - if (l <= 0) { + if (atomicio(read, auth->fd, buf, l) != l) { error("Error reading response from authentication socket."); return 0; } diff --git a/monitor_wrap.c b/monitor_wrap.c index e1b6512b..afa612f4 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.39 2004/07/17 05:31:41 dtucker Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.40 2005/05/24 17:32:43 avsm Exp $"); #include #include @@ -95,9 +95,9 @@ mm_request_send(int sock, enum monitor_reqtype type, Buffer *m) PUT_32BIT(buf, mlen + 1); buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) - fatal("%s: write", __func__); + fatal("%s: write: %s", __func__, strerror(errno)); if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) - fatal("%s: write", __func__); + fatal("%s: write: %s", __func__, strerror(errno)); } void @@ -105,24 +105,21 @@ mm_request_receive(int sock, Buffer *m) { u_char buf[4]; u_int msg_len; - ssize_t res; debug3("%s entering", __func__); - res = atomicio(read, sock, buf, sizeof(buf)); - if (res != sizeof(buf)) { - if (res == 0) + if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { + if (errno == EPIPE) cleanup_exit(255); - fatal("%s: read: %ld", __func__, (long)res); + fatal("%s: read: %s", __func__, strerror(errno)); } msg_len = GET_32BIT(buf); if (msg_len > 256 * 1024) fatal("%s: read: bad msg_len %d", __func__, msg_len); buffer_clear(m); buffer_append_space(m, msg_len); - res = atomicio(read, sock, buffer_ptr(m), msg_len); - if (res != msg_len) - fatal("%s: read: %ld != msg_len", __func__, (long)res); + if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) + fatal("%s: read: %s", __func__, strerror(errno)); } void diff --git a/msg.c b/msg.c index 30bc3f10..3e4c2882 100644 --- a/msg.c +++ b/msg.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: msg.c,v 1.7 2003/11/17 09:45:39 djm Exp $"); +RCSID("$OpenBSD: msg.c,v 1.8 2005/05/24 17:32:43 avsm Exp $"); #include "buffer.h" #include "getput.h" @@ -55,15 +55,13 @@ int ssh_msg_recv(int fd, Buffer *m) { u_char buf[4]; - ssize_t res; u_int msg_len; debug3("ssh_msg_recv entering"); - res = atomicio(read, fd, buf, sizeof(buf)); - if (res != sizeof(buf)) { - if (res != 0) - error("ssh_msg_recv: read: header %ld", (long)res); + if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) { + if (errno != EPIPE) + error("ssh_msg_recv: read: header"); return (-1); } msg_len = GET_32BIT(buf); @@ -73,9 +71,8 @@ ssh_msg_recv(int fd, Buffer *m) } buffer_clear(m); buffer_append_space(m, msg_len); - res = atomicio(read, fd, buffer_ptr(m), msg_len); - if (res != msg_len) { - error("ssh_msg_recv: read: %ld != msg_len", (long)res); + if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) { + error("ssh_msg_recv: read: %s", strerror(errno)); return (-1); } return (0); diff --git a/scp.c b/scp.c index 1d34cc63..1455c18f 100644 --- a/scp.c +++ b/scp.c @@ -71,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.121 2005/04/02 12:41:16 djm Exp $"); +RCSID("$OpenBSD: scp.c,v 1.122 2005/05/24 17:32:43 avsm Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -502,7 +502,8 @@ source(int argc, char **argv) struct stat stb; static BUF buffer; BUF *bp; - off_t i, amt, result, statbytes; + off_t i, amt, statbytes; + size_t result; int fd, haderr, indx; char *last, *name, buf[2048]; int len; @@ -578,14 +579,14 @@ next: (void) close(fd); if (!haderr) { result = atomicio(read, fd, bp->buf, amt); if (result != amt) - haderr = result >= 0 ? EIO : errno; + haderr = errno; } if (haderr) (void) atomicio(vwrite, remout, bp->buf, amt); else { result = atomicio(vwrite, remout, bp->buf, amt); if (result != amt) - haderr = result >= 0 ? EIO : errno; + haderr = errno; statbytes += result; } if (limit_rate) @@ -720,7 +721,8 @@ sink(int argc, char **argv) YES, NO, DISPLAYED } wrerr; BUF *bp; - off_t i, j; + off_t i; + size_t j; int amt, count, exists, first, mask, mode, ofd, omode; off_t size, statbytes; int setimes, targisdir, wrerrno = 0; @@ -748,7 +750,7 @@ sink(int argc, char **argv) targisdir = 1; for (first = 1;; first = 0) { cp = buf; - if (atomicio(read, remin, cp, 1) <= 0) + if (atomicio(read, remin, cp, 1) != 1) return; if (*cp++ == '\n') SCREWUP("unexpected "); @@ -902,7 +904,7 @@ bad: run_err("%s: %s", np, strerror(errno)); count += amt; do { j = atomicio(read, remin, cp, amt); - if (j <= 0) { + if (j == 0) { run_err("%s", j ? strerror(errno) : "dropped connection"); exit(1); @@ -918,10 +920,10 @@ bad: run_err("%s: %s", np, strerror(errno)); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { - j = atomicio(vwrite, ofd, bp->buf, count); - if (j != count) { + if (atomicio(vwrite, ofd, bp->buf, + count) != count) { wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; + wrerrno = errno; } } count = 0; @@ -931,9 +933,9 @@ bad: run_err("%s: %s", np, strerror(errno)); if (showprogress) stop_progress_meter(); if (count != 0 && wrerr == NO && - (j = atomicio(vwrite, ofd, bp->buf, count)) != count) { + atomicio(vwrite, ofd, bp->buf, count) != count) { wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; + wrerrno = errno; } if (wrerr == NO && ftruncate(ofd, size) != 0) { run_err("%s: truncate: %s", np, strerror(errno)); diff --git a/sftp-client.c b/sftp-client.c index 92df4275..47297898 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -20,7 +20,7 @@ /* XXX: copy between two remote sites */ #include "includes.h" -RCSID("$OpenBSD: sftp-client.c,v 1.53 2005/03/10 22:01:05 deraadt Exp $"); +RCSID("$OpenBSD: sftp-client.c,v 1.54 2005/05/24 17:32:44 avsm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -64,10 +64,10 @@ send_msg(int fd, Buffer *m) /* Send length first */ PUT_32BIT(mlen, buffer_len(m)); - if (atomicio(vwrite, fd, mlen, sizeof(mlen)) <= 0) + if (atomicio(vwrite, fd, mlen, sizeof(mlen)) != sizeof(mlen)) fatal("Couldn't send packet: %s", strerror(errno)); - if (atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) <= 0) + if (atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) != buffer_len(m)) fatal("Couldn't send packet: %s", strerror(errno)); buffer_clear(m); @@ -76,26 +76,27 @@ send_msg(int fd, Buffer *m) static void get_msg(int fd, Buffer *m) { - ssize_t len; u_int msg_len; buffer_append_space(m, 4); - len = atomicio(read, fd, buffer_ptr(m), 4); - if (len == 0) - fatal("Connection closed"); - else if (len == -1) - fatal("Couldn't read packet: %s", strerror(errno)); + if (atomicio(read, fd, buffer_ptr(m), 4) != 4) { + if (errno == EPIPE) + fatal("Connection closed"); + else + fatal("Couldn't read packet: %s", strerror(errno)); + } msg_len = buffer_get_int(m); if (msg_len > MAX_MSG_LENGTH) fatal("Received message too long %u", msg_len); buffer_append_space(m, msg_len); - len = atomicio(read, fd, buffer_ptr(m), msg_len); - if (len == 0) - fatal("Connection closed"); - else if (len == -1) - fatal("Read packet: %s", strerror(errno)); + if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) { + if (errno == EPIPE) + fatal("Connection closed"); + else + fatal("Read packet: %s", strerror(errno)); + } } static void diff --git a/ssh-keyscan.c b/ssh-keyscan.c index fdcfc5b3..7dffb851 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.53 2005/04/28 10:17:56 moritz Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.54 2005/05/24 17:32:44 avsm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -493,10 +493,10 @@ conrecycle(int s) static void congreet(int s) { - int remote_major = 0, remote_minor = 0, n = 0; + int remote_major = 0, remote_minor = 0; char buf[256], *cp; char remote_version[sizeof buf]; - size_t bufsiz; + size_t bufsiz, n = 0; con *c = &fdcon[s]; bufsiz = sizeof(buf); @@ -506,14 +506,17 @@ congreet(int s) *cp = '\n'; cp++; } - if (n < 0) { - if (errno != ECONNREFUSED) - error("read (%s): %s", c->c_name, strerror(errno)); - conrecycle(s); - return; - } if (n == 0) { - error("%s: Connection closed by remote host", c->c_name); + switch (errno) { + case EPIPE: + error("%s: Connection closed by remote host", c->c_name); + break; + case ECONNREFUSED: + break; + default: + error("read (%s): %s", c->c_name, strerror(errno)); + break; + } conrecycle(s); return; } @@ -566,14 +569,14 @@ static void conread(int s) { con *c = &fdcon[s]; - int n; + size_t n; if (c->c_status == CS_CON) { congreet(s); return; } n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off); - if (n < 0) { + if (n == 0) { error("read (%s): %s", c->c_name, strerror(errno)); confree(s); return; diff --git a/sshconnect.c b/sshconnect.c index 07703cf7..b79cead5 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.162 2005/03/10 22:01:06 deraadt Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.163 2005/05/24 17:32:44 avsm Exp $"); #include @@ -426,14 +426,15 @@ ssh_exchange_identification(void) int connection_out = packet_get_connection_out(); int minor1 = PROTOCOL_MINOR_1; - /* Read other side\'s version identification. */ + /* Read other side's version identification. */ for (;;) { for (i = 0; i < sizeof(buf) - 1; i++) { - int len = atomicio(read, connection_in, &buf[i], 1); - if (len < 0) - fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); - if (len != 1) + size_t len = atomicio(read, connection_in, &buf[i], 1); + + if (len != 1 && errno == EPIPE) fatal("ssh_exchange_identification: Connection closed by remote host"); + else if (len != 1) + fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); if (buf[i] == '\r') { buf[i] = '\n'; buf[i + 1] = 0; -- 2.45.2