From a6bcdcc2b6019204155b0392148681ff641fafe2 Mon Sep 17 00:00:00 2001 From: lulf Date: Wed, 25 Mar 2009 20:15:48 +0000 Subject: [PATCH] - Add proper error checking and printing to the CVSMode code when reading and writing from/to streams, as leaving them out stops csup from cleaning up on SIGINT and friends properly. MFC after: 1 week --- contrib/csup/rcsfile.c | 157 ++++++++++++++++++++++++++-------------- contrib/csup/rcsfile.h | 4 +- contrib/csup/rcsparse.c | 2 +- contrib/csup/updater.c | 56 ++++++++++---- 4 files changed, 145 insertions(+), 74 deletions(-) diff --git a/contrib/csup/rcsfile.c b/contrib/csup/rcsfile.c index 0d823e8a45e5..2e86a8885fe0 100644 --- a/contrib/csup/rcsfile.c +++ b/contrib/csup/rcsfile.c @@ -140,7 +140,7 @@ static void rcsfile_insertsorteddelta(struct rcsfile *, struct delta *); static struct stream *rcsfile_getdeltatext(struct rcsfile *, struct delta *, struct buf **); -static void rcsdelta_writestring(char *, size_t, struct stream *); +static int rcsdelta_writestring(char *, size_t, struct stream *); static void rcsdelta_insertbranch(struct delta *, struct branch *); /* Space formatting of RCS file. */ @@ -308,14 +308,19 @@ rcsfile_write(struct rcsfile *rf, struct stream *dest) /* First write head. */ d = LIST_FIRST(&rf->trunk->deltalist); - stream_printf(dest, "head%s%s;\n", head_space, d->revnum); + if (stream_printf(dest, "head%s%s;\n", head_space, d->revnum) < 0) + return (-1); /* Write branch, if we have. */ - if (rf->branch != NULL) - stream_printf(dest, "branch%s%s;\n", branch_space, rf->branch); + if (rf->branch != NULL) { + if (stream_printf(dest, "branch%s%s;\n", branch_space, + rf->branch) < 0) + return (-1); + } /* Write access. */ - stream_printf(dest, "access"); + if (stream_printf(dest, "access") < 0) + return (-1); #if 0 if (!STAILQ_EMPTY(&rf->accesslist)) { /* @@ -324,32 +329,44 @@ rcsfile_write(struct rcsfile *rf, struct stream *dest) */ } #endif - stream_printf(dest, ";\n"); + if (stream_printf(dest, ";\n") < 0) + return (-1); /* Write out taglist. */ - stream_printf(dest, "symbols"); + if (stream_printf(dest, "symbols") < 0) + return (-1); if (!STAILQ_EMPTY(&rf->taglist)) { STAILQ_FOREACH(t, &rf->taglist, tag_next) { - stream_printf(dest, "\n%s%s:%s", tag_space, t->tag, - t->revnum); + if (stream_printf(dest, "\n%s%s:%s", tag_space, t->tag, + t->revnum) < 0) + return (-1); } } - stream_printf(dest, ";\n"); /* Write out locks and strict. */ - stream_printf(dest, "locks;"); - if (rf->strictlock) - stream_printf(dest, " strict;"); - stream_printf(dest, "\n"); + if (stream_printf(dest, ";\nlocks;") < 0) + return (-1); + if (rf->strictlock) { + if (stream_printf(dest, " strict;") < 0) + return (-1); + } + if (stream_printf(dest, "\n") < 0) + return (-1); /* Write out the comment. */ - if (rf->comment != NULL) - stream_printf(dest, "comment%s%s;\n", comment_space, rf->comment); - if (rf->expand != EXPAND_DEFAULT) - stream_printf(dest, "expand%s@%s@;\n", expand_space, - keyword_encode_expand(rf->expand)); + if (rf->comment != NULL) { + if (stream_printf(dest, "comment%s%s;\n", comment_space, + rf->comment) < 0) + return (-1); + } + if (rf->expand != EXPAND_DEFAULT) { + if (stream_printf(dest, "expand%s@%s@;\n", expand_space, + keyword_encode_expand(rf->expand)) < 0) + return (-1); + } - stream_printf(dest, "\n\n"); + if (stream_printf(dest, "\n\n") < 0) + return (-1); /* * Write out deltas. We use a stack where we push the appropriate deltas @@ -364,14 +381,18 @@ rcsfile_write(struct rcsfile *rf, struct stream *dest) /* Do not write out placeholders just to be safe. */ if (d->placeholder) continue; - stream_printf(dest, "%s\n", d->revnum); - stream_printf(dest, "date%s%s;%sauthor %s;%sstate", + if (stream_printf(dest, "%s\n", d->revnum) < 0) + return (-1); + if (stream_printf(dest, "date%s%s;%sauthor %s;%sstate", date_space, d->revdate, auth_space, d->author, - state_space); - if (d->state != NULL) - stream_printf(dest, " %s", d->state); - stream_printf(dest, ";\n"); - stream_printf(dest, "branches"); + state_space) < 0) + return (-1); + if (d->state != NULL) { + if (stream_printf(dest, " %s", d->state) < 0) + return (-1); + } + if (stream_printf(dest, ";\nbranches") < 0) + return (-1); /* * Write out our branches. Add them to a reversed list for use * later when we write out the text. @@ -385,30 +406,36 @@ rcsfile_write(struct rcsfile *rf, struct stream *dest) /* Push branch heads on stack. */ STAILQ_FOREACH(d_tmp, &deltalist_inverted, delta_prev) { - if (d_tmp == NULL) - err(1, "empty branch!"); - stream_printf(dest, "\n%s%s", branches_space, - d_tmp->revnum); + if (d_tmp == NULL) { + lprintf(2, "Empty branch!\n"); + return (-1); + } + if (stream_printf(dest, "\n%s%s", branches_space, + d_tmp->revnum) < 0) + return (-1); } - stream_printf(dest, ";\n"); - stream_printf(dest, "next%s", next_space); + if (stream_printf(dest, ";\nnext%s", next_space) < 0) + return (-1); /* Push next delta on stack. */ d_next = LIST_NEXT(d, delta_next); if (d_next != NULL) { - stream_printf(dest, "%s", d_next->revnum); + if (stream_printf(dest, "%s", d_next->revnum) < 0) + return (-1); STAILQ_INSERT_HEAD(&deltastack, d_next, stack_next); } - stream_printf(dest, ";\n\n"); + if (stream_printf(dest, ";\n\n") < 0) + return (-1); } - stream_printf(dest, "\n"); /* Write out desc. */ - stream_printf(dest, "desc\n@@"); + if (stream_printf(dest, "\ndesc\n@@") < 0) + return (-1); d = LIST_FIRST(&rf->trunk->deltalist); /* Write out deltatexts. */ error = rcsfile_write_deltatext(rf, dest); - stream_printf(dest, "\n"); + if (stream_printf(dest, "\n") < 0) + return (-1); return (error); } @@ -438,21 +465,25 @@ rcsfile_write_deltatext(struct rcsfile *rf, struct stream *dest) /* Do not write out placeholders just to be safe. */ if (d->placeholder) return (0); - stream_printf(dest, "\n\n\n%s\n", d->revnum); - stream_printf(dest, "log\n@"); + if (stream_printf(dest, "\n\n\n%s\n", d->revnum) < 0) + return (-1); + if (stream_printf(dest, "log\n@") < 0) + return (-1); in = stream_open_buf(d->log); line = stream_getln(in, &size); while (line != NULL) { - stream_write(dest, line, size); + if (stream_write(dest, line, size) == -1) + return (-1); line = stream_getln(in, &size); } stream_close(in); - stream_printf(dest, "@\n"); - stream_printf(dest, "text\n@"); + if (stream_printf(dest, "@\ntext\n@") < 0) + return (-1); error = rcsfile_puttext(rf, dest, d, d->prev); if (error) return (error); - stream_printf(dest, "@"); + if (stream_printf(dest, "@") < 0) + return (-1); LIST_INIT(&branchlist_datesorted); d_next = LIST_NEXT(d, delta_next); @@ -535,7 +566,10 @@ rcsfile_puttext(struct rcsfile *rf, struct stream *dest, struct delta *d, in = stream_open_buf(d->text); line = stream_getln(in, &size); while (line != NULL) { - stream_write(dest, line, size); + if (stream_write(dest, line, size) == -1) { + error = -1; + goto cleanup; + } line = stream_getln(in, &size); } stream_close(in); @@ -549,7 +583,10 @@ rcsfile_puttext(struct rcsfile *rf, struct stream *dest, struct delta *d, } line = stream_getln(orig, &size); while (line != NULL) { - stream_write(dest, line, size); + if (stream_write(dest, line, size) == -1) { + error = -1; + goto cleanup; + } line = stream_getln(orig, &size); } stream_close(orig); @@ -1261,6 +1298,7 @@ int rcsdelta_addlog(struct delta *d, char *log, int len) { struct stream *dest; + int nbytes; assert(d != NULL); /* Strip away '@' at beginning and end. */ @@ -1268,9 +1306,9 @@ rcsdelta_addlog(struct delta *d, char *log, int len) len--; log[len - 1] = '\0'; dest = stream_open_buf(d->log); - stream_write(dest, log, len - 1); + nbytes = stream_write(dest, log, len - 1); stream_close(dest); - return (0); + return ((nbytes == -1) ? -1 : 0); } /* Add deltatext to a delta. Assume the delta already exists. */ @@ -1278,6 +1316,7 @@ int rcsdelta_addtext(struct delta *d, char *text, int len) { struct stream *dest; + int nbytes; assert(d != NULL); /* Strip away '@' at beginning and end. */ @@ -1286,36 +1325,40 @@ rcsdelta_addtext(struct delta *d, char *text, int len) text[len - 1] = '\0'; dest = stream_open_buf(d->text); - stream_write(dest, text, len - 1); + nbytes = stream_write(dest, text, len - 1); stream_close(dest); - return (0); + return ((nbytes == -1) ? -1 : 0); } /* Add a deltatext logline to a delta. */ -void +int rcsdelta_appendlog(struct delta *d, char *logline, size_t size) { struct stream *dest; + int error; assert(d != NULL); dest = stream_open_buf(d->log); - rcsdelta_writestring(logline, size, dest); + error = rcsdelta_writestring(logline, size, dest); stream_close(dest); + return (error); } /* Add a deltatext textline to a delta. */ -void +int rcsdelta_appendtext(struct delta *d, char *textline, size_t size) { struct stream *dest; + int error; assert(d != NULL); dest = stream_open_buf(d->text); - rcsdelta_writestring(textline, size, dest); + error = rcsdelta_writestring(textline, size, dest); stream_close(dest); + return (error); } -static void +static int rcsdelta_writestring(char *textline, size_t size, struct stream *dest) { char buf[3]; @@ -1332,8 +1375,10 @@ rcsdelta_writestring(char *textline, size_t size, struct stream *dest) buf[2] = '\0'; count = 2; } - stream_write(dest, buf, count); + if (stream_write(dest, buf, count) == -1) + return (-1); } + return (0); } /* Set delta state. */ diff --git a/contrib/csup/rcsfile.h b/contrib/csup/rcsfile.h index 7eb38bec4171..5fa9f31cb1a5 100644 --- a/contrib/csup/rcsfile.h +++ b/contrib/csup/rcsfile.h @@ -65,8 +65,8 @@ void rcsfile_importdelta(struct rcsfile *, char *, char *, char *, int rcsdelta_addlog(struct delta *, char *, int); int rcsdelta_addtext(struct delta *, char *, int); -void rcsdelta_appendlog(struct delta *, char *, size_t); -void rcsdelta_appendtext(struct delta *, char *, size_t); +int rcsdelta_appendlog(struct delta *, char *, size_t); +int rcsdelta_appendtext(struct delta *, char *, size_t); void rcsdelta_setstate(struct delta *, char *); void rcsdelta_truncatetext(struct delta *, off_t); void rcsdelta_truncatelog(struct delta *, off_t); diff --git a/contrib/csup/rcsparse.c b/contrib/csup/rcsparse.c index 682f113935b8..5ea690ccde36 100644 --- a/contrib/csup/rcsparse.c +++ b/contrib/csup/rcsparse.c @@ -309,7 +309,7 @@ parse_deltatexts(struct rcsfile *rf, yyscan_t *sp, int token) error = 0; /* In case we don't have deltatexts. */ if (token != NUM) - return (token); + return (-1); do { /* num */ assert(token == NUM); diff --git a/contrib/csup/updater.c b/contrib/csup/updater.c index 7d351c1d17db..ad9fbcfb92e7 100644 --- a/contrib/csup/updater.c +++ b/contrib/csup/updater.c @@ -1385,8 +1385,11 @@ updater_addfile(struct updater *up, struct file_update *fup, char *attr, do { nread = stream_read(up->rd, buf, (BUFSIZE > remains ? remains : BUFSIZE)); + if (nread == -1) + return (UPDATER_ERR_PROTO); remains -= nread; - stream_write(to, buf, nread); + if (stream_write(to, buf, nread) == -1) + goto bad; } while (remains > 0); stream_close(to); line = stream_getln(up->rd, NULL); @@ -1411,9 +1414,11 @@ updater_addfile(struct updater *up, struct file_update *fup, char *attr, FA_MODTIME | FA_MASK); error = updater_updatefile(up, fup, md5, isfixup); fup->wantmd5 = NULL; /* So that it doesn't get freed. */ - if (error) - return (error); - return (0); + return (error); +bad: + xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath, + strerror(errno)); + return (UPDATER_ERR_MSG); } static int @@ -1469,7 +1474,9 @@ updater_checkout(struct updater *up, struct file_update *fup, int isfixup) if (nbytes == -1) goto bad; } - stream_write(to, line, size); + nbytes = stream_write(to, line, size); + if (nbytes == -1) + goto bad; line = stream_getln(up->rd, &size); first = 0; } @@ -1682,8 +1689,11 @@ updater_rcsedit(struct updater *up, struct file_update *fup, char *name, error = rcsfile_write(rf, dest); stream_close(dest); rcsfile_free(rf); - if (error) - lprintf(-1, "Error writing %s\n", name); + if (error) { + xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath, + strerror(errno)); + return (UPDATER_ERR_MSG); + } finish: sr->sr_clientattr = fattr_frompath(path, FATTR_NOFOLLOW); @@ -1768,7 +1778,9 @@ updater_addelta(struct rcsfile *rf, struct stream *rd, char *cmdline) size--; logline++; } - rcsdelta_appendlog(d, logline, size); + if (rcsdelta_appendlog(d, logline, size) + < 0) + return (-1); logline = stream_getln(rd, &size); } break; @@ -1799,7 +1811,9 @@ updater_addelta(struct rcsfile *rf, struct stream *rd, char *cmdline) size--; textline++; } - rcsdelta_appendtext(d, textline, size); + if (rcsdelta_appendtext(d, textline, + size) < 0) + return (-1); textline = stream_getln(rd, &size); } break; @@ -1839,8 +1853,15 @@ updater_append_file(struct updater *up, struct file_update *fup, off_t pos) stream_filter_start(to, STREAM_FILTER_MD5, md5); /* First write the existing content. */ - while ((nread = read(fd, buf, BUFSIZE)) > 0) - stream_write(to, buf, nread); + while ((nread = read(fd, buf, BUFSIZE)) > 0) { + if (stream_write(to, buf, nread) == -1) + goto bad; + } + if (nread == -1) { + xasprintf(&up->errmsg, "%s: Error reading: %s", + strerror(errno)); + return (UPDATER_ERR_MSG); + } close(fd); bytes = fattr_filesize(fa) - pos; @@ -1848,8 +1869,11 @@ updater_append_file(struct updater *up, struct file_update *fup, off_t pos) do { nread = stream_read(up->rd, buf, (BUFSIZE > bytes) ? bytes : BUFSIZE); + if (nread == -1) + return (UPDATER_ERR_PROTO); bytes -= nread; - stream_write(to, buf, nread); + if (stream_write(to, buf, nread) == -1) + goto bad; } while (bytes > 0); stream_close(to); @@ -1875,9 +1899,11 @@ updater_append_file(struct updater *up, struct file_update *fup, off_t pos) FA_MODTIME | FA_MASK); error = updater_updatefile(up, fup, md5, 0); fup->wantmd5 = NULL; /* So that it doesn't get freed. */ - if (error) - return (error); - return (0); + return (error); +bad: + xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath, + strerror(errno)); + return (UPDATER_ERR_MSG); } /*