diff options
author | Joris Vink <joris@cvs.openbsd.org> | 2008-02-27 22:34:05 +0000 |
---|---|---|
committer | Joris Vink <joris@cvs.openbsd.org> | 2008-02-27 22:34:05 +0000 |
commit | c8955619dd8db636823797d2bd41b68bc78af8c1 (patch) | |
tree | 0f1a922b9d1b4bb083ea6b7477f91aaa7333681d /usr.bin/cvs | |
parent | 3d3b75f61b57504b71451e352de59d6ff8ffd6a4 (diff) |
prevent file races
ok tobias@
Diffstat (limited to 'usr.bin/cvs')
-rw-r--r-- | usr.bin/cvs/buf.c | 11 | ||||
-rw-r--r-- | usr.bin/cvs/buf.h | 4 | ||||
-rw-r--r-- | usr.bin/cvs/checkout.c | 10 | ||||
-rw-r--r-- | usr.bin/cvs/client.c | 4 | ||||
-rw-r--r-- | usr.bin/cvs/commit.c | 18 | ||||
-rw-r--r-- | usr.bin/cvs/diff.c | 31 | ||||
-rw-r--r-- | usr.bin/cvs/diff.h | 4 | ||||
-rw-r--r-- | usr.bin/cvs/diff3.c | 68 | ||||
-rw-r--r-- | usr.bin/cvs/diff_internals.c | 30 | ||||
-rw-r--r-- | usr.bin/cvs/import.c | 12 | ||||
-rw-r--r-- | usr.bin/cvs/rcs.c | 20 | ||||
-rw-r--r-- | usr.bin/cvs/rcs.h | 4 | ||||
-rw-r--r-- | usr.bin/cvs/remote.c | 16 | ||||
-rw-r--r-- | usr.bin/cvs/remote.h | 4 |
14 files changed, 159 insertions, 77 deletions
diff --git a/usr.bin/cvs/buf.c b/usr.bin/cvs/buf.c index 9a1865db156..266199d9ee7 100644 --- a/usr.bin/cvs/buf.c +++ b/usr.bin/cvs/buf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buf.c,v 1.68 2008/02/11 20:33:10 tobias Exp $ */ +/* $OpenBSD: buf.c,v 1.69 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2003 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -276,7 +276,7 @@ cvs_buf_write(BUF *b, const char *path, mode_t mode) * specified using <template> (see mkstemp.3). NB. This function will modify * <template>, as per mkstemp */ -void +int cvs_buf_write_stmp(BUF *b, char *template, struct timeval *tv) { int fd; @@ -294,9 +294,12 @@ cvs_buf_write_stmp(BUF *b, char *template, struct timeval *tv) fatal("cvs_buf_write_stmp: futimes failed"); } - (void)close(fd); - cvs_worklist_add(template, &temp_files); + + if (lseek(fd, SEEK_SET, 0) < 0) + fatal("cvs_buf_write_stmp: lseek: %s", strerror(errno)); + + return (fd); } /* diff --git a/usr.bin/cvs/buf.h b/usr.bin/cvs/buf.h index 8ed3c774025..0b283782c35 100644 --- a/usr.bin/cvs/buf.h +++ b/usr.bin/cvs/buf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buf.h,v 1.23 2008/02/11 20:33:11 tobias Exp $ */ +/* $OpenBSD: buf.h,v 1.24 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2003 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -47,7 +47,7 @@ size_t cvs_buf_len(BUF *); int cvs_buf_write_fd(BUF *, int); int cvs_buf_write(BUF *, const char *, mode_t); int cvs_buf_differ(const BUF *, const BUF *); -void cvs_buf_write_stmp(BUF *, char *, struct timeval *); +int cvs_buf_write_stmp(BUF *, char *, struct timeval *); ssize_t cvs_buf_copy(BUF *, size_t, void *, size_t); const u_char *cvs_buf_peek(BUF *, size_t); diff --git a/usr.bin/cvs/checkout.c b/usr.bin/cvs/checkout.c index a8d4f0e1450..3db000f713c 100644 --- a/usr.bin/cvs/checkout.c +++ b/usr.bin/cvs/checkout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: checkout.c,v 1.139 2008/02/24 20:04:05 tobias Exp $ */ +/* $OpenBSD: checkout.c,v 1.140 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -424,7 +424,7 @@ checkout_repository(const char *repobase, const char *wdbase) void cvs_checkout_file(struct cvs_file *cf, RCSNUM *rnum, char *tag, int co_flags) { - int cf_kflag, oflags, exists; + int cf_kflag, oflags, exists, fd; time_t rcstime; CVSENTRIES *ent; struct timeval tv[2]; @@ -540,6 +540,7 @@ cvs_checkout_file(struct cvs_file *cf, RCSNUM *rnum, char *tag, int co_flags) if (co_flags & CO_MERGE) { cvs_merge_file(cf, 1); tosend = cf->file_path; + fd = cf->fd; } if (co_flags & CO_COMMIT) @@ -561,14 +562,15 @@ cvs_checkout_file(struct cvs_file *cf, RCSNUM *rnum, char *tag, int co_flags) (void)xsnprintf(template, MAXPATHLEN, "%s/checkout.XXXXXXXXXX", cvs_tmpdir); - rcs_rev_write_stmp(cf->file_rcs, rnum, + fd = rcs_rev_write_stmp(cf->file_rcs, rnum, template, 0); tosend = template; } - cvs_remote_send_file(tosend); + cvs_remote_send_file(tosend, fd); if (!(co_flags & CO_MERGE)) { + close(fd); (void)unlink(template); cvs_worklist_run(&temp_files, cvs_worklist_unlink); diff --git a/usr.bin/cvs/client.c b/usr.bin/cvs/client.c index 5cee868bb23..0d0c0f5efa5 100644 --- a/usr.bin/cvs/client.c +++ b/usr.bin/cvs/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.105 2008/02/11 20:33:11 tobias Exp $ */ +/* $OpenBSD: client.c,v 1.106 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -525,7 +525,7 @@ cvs_client_sendfile(struct cvs_file *cf) case FILE_ADDED: case FILE_MODIFIED: cvs_client_send_request("Modified %s", cf->file_name); - cvs_remote_send_file(cf->file_path); + cvs_remote_send_file(cf->file_path, cf->fd); break; case FILE_UPTODATE: cvs_client_send_request("Unchanged %s", cf->file_name); diff --git a/usr.bin/cvs/commit.c b/usr.bin/cvs/commit.c index 9de98313e80..e7464cf5271 100644 --- a/usr.bin/cvs/commit.c +++ b/usr.bin/cvs/commit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: commit.c,v 1.130 2008/02/20 17:29:28 tobias Exp $ */ +/* $OpenBSD: commit.c,v 1.131 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org> @@ -547,6 +547,7 @@ cvs_commit_local(struct cvs_file *cf) static BUF * commit_diff(struct cvs_file *cf, RCSNUM *rev, int reverse) { + int fd1, fd2, f; char *p1, *p2, *p; BUF *b; @@ -555,14 +556,14 @@ commit_diff(struct cvs_file *cf, RCSNUM *rev, int reverse) if (cf->file_status == FILE_MODIFIED || cf->file_status == FILE_ADDED) { b = cvs_buf_load_fd(cf->fd); - cvs_buf_write_stmp(b, p1, NULL); + fd1 = cvs_buf_write_stmp(b, p1, NULL); cvs_buf_free(b); } else { - rcs_rev_write_stmp(cf->file_rcs, rev, p1, 0); + fd1 = rcs_rev_write_stmp(cf->file_rcs, rev, p1, 0); } (void)xasprintf(&p2, "%s/diff2.XXXXXXXXXX", cvs_tmpdir); - rcs_rev_write_stmp(cf->file_rcs, rev, p2, RCS_KWEXP_NONE); + fd2 = rcs_rev_write_stmp(cf->file_rcs, rev, p2, RCS_KWEXP_NONE); b = cvs_buf_alloc(128); @@ -572,11 +573,18 @@ commit_diff(struct cvs_file *cf, RCSNUM *rev, int reverse) p = p1; p1 = p2; p2 = p; + + f = fd1; + fd1 = fd2; + fd2 = f; } - if (cvs_diffreg(p1, p2, b) == D_ERROR) + if (cvs_diffreg(p1, p2, fd1, fd2, b) == D_ERROR) fatal("commit_diff: failed to get RCS patch"); + close(fd1); + close(fd2); + xfree(p1); xfree(p2); diff --git a/usr.bin/cvs/diff.c b/usr.bin/cvs/diff.c index 41129f63750..7e8b2b54846 100644 --- a/usr.bin/cvs/diff.c +++ b/usr.bin/cvs/diff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.c,v 1.130 2008/02/27 20:04:59 tobias Exp $ */ +/* $OpenBSD: diff.c,v 1.131 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -19,6 +19,7 @@ #include <sys/time.h> #include <errno.h> +#include <fcntl.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -220,6 +221,7 @@ cvs_diff_local(struct cvs_file *cf) { RCSNUM *r1; BUF *b1; + int fd1, fd2; struct stat st; struct timeval tv[2], tv2[2]; char rbuf[CVS_REV_BUFSZ], *p1, *p2; @@ -331,8 +333,8 @@ cvs_diff_local(struct cvs_file *cf) if (cvs_cmdop == CVS_OP_DIFF) cvs_printf("retrieving revision %s\n", rbuf); - rcs_rev_write_stmp(cf->file_rcs, r1, p1, 0); - if (utimes(p1, tv) == -1) + fd1 = rcs_rev_write_stmp(cf->file_rcs, r1, p1, 0); + if (futimes(fd1, tv) == -1) fatal("cvs_diff_local: utimes failed"); } } @@ -347,8 +349,8 @@ cvs_diff_local(struct cvs_file *cf) if (cvs_cmdop == CVS_OP_DIFF) cvs_printf("retrieving revision %s\n", rbuf); - rcs_rev_write_stmp(cf->file_rcs, diff_rev2, p2, 0); - if (utimes(p2, tv2) == -1) + fd2 = rcs_rev_write_stmp(cf->file_rcs, diff_rev2, p2, 0); + if (futimes(fd2, tv2) == -1) fatal("cvs_diff_local: utimes failed"); } else if (cf->file_status != FILE_REMOVED) { if (cvs_cmdop == CVS_OP_RDIFF || (cvs_server_active == 1 && @@ -359,9 +361,9 @@ cvs_diff_local(struct cvs_file *cf) tv2[0].tv_usec = 0; tv2[1] = tv2[0]; - rcs_rev_write_stmp(cf->file_rcs, + fd2 = rcs_rev_write_stmp(cf->file_rcs, cf->file_rcsrev, p2, 0); - if (utimes(p2, tv2) == -1) + if (futimes(fd2, tv2) == -1) fatal("cvs_diff_local: utimes failed"); } } else { @@ -373,7 +375,7 @@ cvs_diff_local(struct cvs_file *cf) tv2[0].tv_usec = 0; tv2[1] = tv2[0]; - cvs_buf_write_stmp(b1, p2, tv2); + fd2 = cvs_buf_write_stmp(b1, p2, tv2); cvs_buf_free(b1); } } @@ -429,16 +431,27 @@ cvs_diff_local(struct cvs_file *cf) if (cf->file_status == FILE_ADDED || (cvs_cmdop == CVS_OP_RDIFF && diff_rev1 == NULL)) { xfree(p1); + close(fd1); (void)xasprintf(&p1, "%s", CVS_PATH_DEVNULL); + if ((fd1 = open(p1, O_RDONLY)) == -1) + fatal("cvs_diff_local: cannot open %s", + CVS_PATH_DEVNULL); } else if (cf->file_status == FILE_REMOVED || (cvs_cmdop == CVS_OP_RDIFF && diff_rev2 == NULL)) { xfree(p2); + close(fd2); (void)xasprintf(&p2, "%s", CVS_PATH_DEVNULL); + if ((fd1 = open(p2, O_RDONLY)) == -1) + fatal("cvs_diff_local: cannot open %s", + CVS_PATH_DEVNULL); } - if (cvs_diffreg(p1, p2, NULL) == D_ERROR) + if (cvs_diffreg(p1, p2, fd1, fd2, NULL) == D_ERROR) fatal("cvs_diff_local: failed to get RCS patch"); + close(fd1); + close(fd2); + cvs_worklist_run(&temp_files, cvs_worklist_unlink); if (p1 != NULL) diff --git a/usr.bin/cvs/diff.h b/usr.bin/cvs/diff.h index 24d883e128b..2b488f20c48 100644 --- a/usr.bin/cvs/diff.h +++ b/usr.bin/cvs/diff.h @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.h,v 1.15 2008/02/03 18:18:44 tobias Exp $ */ +/* $OpenBSD: diff.h,v 1.16 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. * All rights reserved. @@ -93,7 +93,7 @@ void cvs_merge_file(struct cvs_file *, int); void diff_output(const char *, ...); -int cvs_diffreg(const char *, const char *, BUF *out); +int cvs_diffreg(const char *, const char *, int, int, BUF *); int ed_patch_lines(struct cvs_lines *, struct cvs_lines *); extern int diff_format; diff --git a/usr.bin/cvs/diff3.c b/usr.bin/cvs/diff3.c index 4bcfb654689..b551500fb41 100644 --- a/usr.bin/cvs/diff3.c +++ b/usr.bin/cvs/diff3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff3.c,v 1.41 2008/02/23 23:42:23 joris Exp $ */ +/* $OpenBSD: diff3.c,v 1.42 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -72,7 +72,7 @@ static const char copyright[] = #ifndef lint static const char rcsid[] = - "$OpenBSD: diff3.c,v 1.41 2008/02/23 23:42:23 joris Exp $"; + "$OpenBSD: diff3.c,v 1.42 2008/02/27 22:34:04 joris Exp $"; #endif /* not lint */ #include <ctype.h> @@ -146,7 +146,7 @@ static int edit(struct diff *, int, int); static char *getchange(FILE *); static char *getline(FILE *, size_t *); static int number(char **); -static size_t readin(char *, struct diff **); +static size_t readin(int, struct diff **); static int skip(int, int, char *); static int edscript(int); static int merge(size_t, size_t); @@ -160,10 +160,12 @@ static int diff3_internal(int, char **, const char *, const char *); int diff3_conflicts = 0; +static int fds[5]; + void cvs_merge_file(struct cvs_file *cf, int verbose) { - int argc; + int i, argc; char *data, *patch; char *argv[5], r1[CVS_REV_BUFSZ], r2[CVS_REV_BUFSZ]; char *dp13, *dp23, *path1, *path2, *path3; @@ -182,34 +184,28 @@ cvs_merge_file(struct cvs_file *cf, int verbose) d2 = cvs_buf_alloc(128); diffb = cvs_buf_alloc(128); - (void)close(cf->fd); - cf->fd = open(cf->file_path, O_WRONLY | O_TRUNC); - if (cf->fd == -1) { - fatal("cvs_merge_file: failed to reopen fd for writing: %s", - strerror(errno)); - } - (void)xasprintf(&path1, "%s/diff1.XXXXXXXXXX", cvs_tmpdir); (void)xasprintf(&path2, "%s/diff2.XXXXXXXXXX", cvs_tmpdir); (void)xasprintf(&path3, "%s/diff3.XXXXXXXXXX", cvs_tmpdir); - cvs_buf_write_stmp(b1, path1, NULL); + fds[2] = cvs_buf_write_stmp(b1, path1, NULL); if (verbose == 1) cvs_printf("Retrieving revision %s\n", r1); - rcs_rev_write_stmp(cf->file_rcs, cf->file_ent->ce_rev, path2, 0); + fds[3] = rcs_rev_write_stmp(cf->file_rcs, cf->file_ent->ce_rev, + path2, 0); if (verbose == 1) cvs_printf("Retrieving revision %s\n", r2); - rcs_rev_write_stmp(cf->file_rcs, cf->file_rcsrev, path3, 0); + fds[4] = rcs_rev_write_stmp(cf->file_rcs, cf->file_rcsrev, path3, 0); - cvs_diffreg(path1, path3, d1); - cvs_diffreg(path2, path3, d2); + cvs_diffreg(path1, path3, fds[2], fds[4], d1); + cvs_diffreg(path2, path3, fds[3], fds[4], d2); (void)xasprintf(&dp13, "%s/d13.XXXXXXXXXX", cvs_tmpdir); - cvs_buf_write_stmp(d1, dp13, NULL); + fds[0] = cvs_buf_write_stmp(d1, dp13, NULL); cvs_buf_free(d1); (void)xasprintf(&dp23, "%s/d23.XXXXXXXXXX", cvs_tmpdir); - cvs_buf_write_stmp(d2, dp23, NULL); + fds[1] = cvs_buf_write_stmp(d2, dp23, NULL); cvs_buf_free(d2); argc = 0; @@ -220,6 +216,13 @@ cvs_merge_file(struct cvs_file *cf, int verbose) argv[argc++] = path2; argv[argc++] = path3; + if (lseek(fds[2], SEEK_SET, 0) < 0) + fatal("cvs_merge_file: lseek fds[2]: %s", strerror(errno)); + if (lseek(fds[3], SEEK_SET, 0) < 0) + fatal("cvs_merge_file: lseek fds[3]: %s", strerror(errno)); + if (lseek(fds[4], SEEK_SET, 0) < 0) + fatal("cvs_merge_file: lseek fds[4]: %s", strerror(errno)); + diff3_conflicts = diff3_internal(argc, argv, cf->file_path, r2); if (diff3_conflicts < 0) fatal("cvs_merge_file: merging failed for an unknown reason"); @@ -243,6 +246,13 @@ cvs_merge_file(struct cvs_file *cf, int verbose) (diff3_conflicts > 1) ? "s" : ""); } + (void)close(cf->fd); + cf->fd = open(cf->file_path, O_WRONLY | O_TRUNC); + if (cf->fd == -1) { + fatal("cvs_merge_file: failed to reopen fd for writing: %s", + strerror(errno)); + } + TAILQ_FOREACH(lp, &(dlines->l_lines), l_list) { if (lp->l_line == NULL) continue; @@ -258,6 +268,9 @@ cvs_merge_file(struct cvs_file *cf, int verbose) xfree(data); xfree(patch); + for (i = 0; i < 3; i++) + fclose(fp[i]); + (void)unlink(path1); (void)unlink(path2); (void)unlink(path3); @@ -288,11 +301,16 @@ diff3_internal(int argc, char **argv, const char *fmark, const char *rmark) (void)xsnprintf(f3mark, sizeof(f3mark), ">>>>>>> %s", rmark); increase(); - m = readin(argv[0], &d13); - n = readin(argv[1], &d23); + + /* fds[0] and fds[1] are closed in readin() */ + cvs_printf("calling readin with fds[0] (%s)\n", argv[0]); + m = readin(fds[0], &d13); + cvs_printf("calling readin with fds[1] (%s)\n", argv[1]); + n = readin(fds[1], &d23); for (i = 0; i <= 2; i++) { - if ((fp[i] = fopen(argv[i + 2], "r")) == NULL) { + cvs_printf("opening fds[%d] (%s)\n", i + 2, argv[i + 2]); + if ((fp[i] = fdopen(fds[i + 2], "r")) == NULL) { cvs_log(LP_ERR, "%s", argv[i + 2]); return (-1); } @@ -415,13 +433,16 @@ ed_patch_lines(struct cvs_lines *dlines, struct cvs_lines *plines) * The vector could be optimized out of existence) */ static size_t -readin(char *name, struct diff **dd) +readin(int fd, struct diff **dd) { int a, b, c, d; char kind, *p; size_t i; - fp[0] = fopen(name, "r"); + fp[0] = fdopen(fd, "r"); + if (fp[0] == NULL) + fatal("readin: fdopen: %s", strerror(errno)); + for (i = 0; (p = getchange(fp[0])); i++) { if (i >= szchanges - 1) increase(); @@ -452,6 +473,7 @@ readin(char *name, struct diff **dd) (*dd)[i].old.from = (*dd)[i-1].old.to; (*dd)[i].new.from = (*dd)[i-1].new.to; } + (void)fclose(fp[0]); return (i); diff --git a/usr.bin/cvs/diff_internals.c b/usr.bin/cvs/diff_internals.c index 47e8ac05d52..16b4fd7f663 100644 --- a/usr.bin/cvs/diff_internals.c +++ b/usr.bin/cvs/diff_internals.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff_internals.c,v 1.18 2008/02/03 18:59:44 tobias Exp $ */ +/* $OpenBSD: diff_internals.c,v 1.19 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. * All rights reserved. @@ -295,10 +295,10 @@ u_char cup2low[256] = { }; int -cvs_diffreg(const char *file1, const char *file2, BUF *out) +cvs_diffreg(const char *file1, const char *file2, int _fd1, int _fd2, BUF *out) { FILE *f1, *f2; - int i, rval; + int i, rval, fd1, fd2; f1 = f2 = NULL; rval = D_SAME; @@ -310,23 +310,38 @@ cvs_diffreg(const char *file1, const char *file2, BUF *out) if (out != NULL) diffbuf = out; - f1 = fopen(file1, "r"); + fd1 = dup(_fd1); + if (fd1 == -1) + fatal("cvs_diffreg: dup: %s", strerror(errno)); + + fd2 = dup(_fd2); + if (fd2 == -1) + fatal("cvs_diffreg: dup: %s", strerror(errno)); + + if (lseek(fd1, SEEK_SET, 0) < 0) + fatal("cvs_diffreg: lseek: %s", strerror(errno)); + + f1 = fdopen(fd1, "r"); if (f1 == NULL) { cvs_log(LP_ERR, "%s", file1); goto closem; } - f2 = fopen(file2, "r"); + if (lseek(fd2, SEEK_SET, 0) < 0) + fatal("cvs_diffreg: lseek: %s", strerror(errno)); + + f2 = fdopen(fd2, "r"); if (f2 == NULL) { cvs_log(LP_ERR, "%s", file2); goto closem; } - if (fstat(fileno(f1), &stb1) < 0) { + if (fstat(fd1, &stb1) < 0) { cvs_log(LP_ERR, "%s", file1); goto closem; } - if (fstat(fileno(f2), &stb2) < 0) { + + if (fstat(fd2, &stb2) < 0) { cvs_log(LP_ERR, "%s", file2); goto closem; } @@ -386,6 +401,7 @@ closem: } if (f1 != NULL) fclose(f1); + if (f2 != NULL) fclose(f2); diff --git a/usr.bin/cvs/import.c b/usr.bin/cvs/import.c index 83047694576..7fe760ef03e 100644 --- a/usr.bin/cvs/import.c +++ b/usr.bin/cvs/import.c @@ -1,4 +1,4 @@ -/* $OpenBSD: import.c,v 1.84 2008/02/20 17:29:28 tobias Exp $ */ +/* $OpenBSD: import.c,v 1.85 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -359,6 +359,7 @@ import_get_rcsdiff(struct cvs_file *cf, RCSNUM *rev) { char *p1, *p2; BUF *b1, *b2; + int fd1, fd2; b2 = cvs_buf_alloc(128); @@ -366,16 +367,19 @@ import_get_rcsdiff(struct cvs_file *cf, RCSNUM *rev) b1 = cvs_buf_load_fd(cf->fd); (void)xasprintf(&p1, "%s/diff1.XXXXXXXXXX", cvs_tmpdir); - cvs_buf_write_stmp(b1, p1, NULL); + fd1 = cvs_buf_write_stmp(b1, p1, NULL); cvs_buf_free(b1); (void)xasprintf(&p2, "%s/diff2.XXXXXXXXXX", cvs_tmpdir); - rcs_rev_write_stmp(cf->file_rcs, rev, p2, RCS_KWEXP_NONE); + fd2 = rcs_rev_write_stmp(cf->file_rcs, rev, p2, RCS_KWEXP_NONE); diff_format = D_RCSDIFF; - if (cvs_diffreg(p2, p1, b2) == D_ERROR) + if (cvs_diffreg(p2, p1, fd2, fd1, b2) == D_ERROR) fatal("import_get_rcsdiff: failed to get RCS patch"); + close(fd1); + close(fd2); + (void)unlink(p1); (void)unlink(p2); diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c index 99dee560a96..8ed43db859b 100644 --- a/usr.bin/cvs/rcs.c +++ b/usr.bin/cvs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.250 2008/02/20 09:19:04 joris Exp $ */ +/* $OpenBSD: rcs.c,v 1.251 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -1292,6 +1292,7 @@ rcs_rev_add(RCSFILE *rf, RCSNUM *rev, const char *msg, time_t date, int rcs_rev_remove(RCSFILE *rf, RCSNUM *rev) { + int fd1, fd2; char *path_tmp1, *path_tmp2; struct rcs_delta *rdp, *prevrdp, *nextrdp; BUF *prevbuf, *newdiff, *newdeltatext; @@ -1323,15 +1324,19 @@ rcs_rev_remove(RCSFILE *rf, RCSNUM *rev) /* calculate new diff */ (void)xasprintf(&path_tmp1, "%s/diff1.XXXXXXXXXX", cvs_tmpdir); - rcs_rev_write_stmp(rf, nextrdp->rd_num, path_tmp1, 0); + fd1 = rcs_rev_write_stmp(rf, nextrdp->rd_num, path_tmp1, 0); (void)xasprintf(&path_tmp2, "%s/diff2.XXXXXXXXXX", cvs_tmpdir); - rcs_rev_write_stmp(rf, prevrdp->rd_num, path_tmp2, 0); + fd2 = rcs_rev_write_stmp(rf, prevrdp->rd_num, path_tmp2, 0); diff_format = D_RCSDIFF; - if (cvs_diffreg(path_tmp1, path_tmp2, newdiff) == D_ERROR) + if (cvs_diffreg(path_tmp1, path_tmp2, + fd1, fd2, newdiff) == D_ERROR) fatal("rcs_diffreg failed"); + close(fd1); + close(fd2); + newdeltatext = newdiff; } else if (nextrdp == NULL && prevrdp != NULL) { newdeltatext = prevbuf; @@ -3141,7 +3146,7 @@ rcs_rev_write_fd(RCSFILE *rfp, RCSNUM *rev, int fd, int mode) * specified using <template> (see mkstemp(3)). NB. This function will modify * <template>, as per mkstemp. */ -void +int rcs_rev_write_stmp(RCSFILE *rfp, RCSNUM *rev, char *template, int mode) { int fd; @@ -3152,7 +3157,10 @@ rcs_rev_write_stmp(RCSFILE *rfp, RCSNUM *rev, char *template, int mode) cvs_worklist_add(template, &temp_files); rcs_rev_write_fd(rfp, rev, fd, mode); - (void)close(fd); + if (lseek(fd, SEEK_SET, 0) < 0) + fatal("rcs_rev_write_stmp: lseek: %s", strerror(errno)); + + return (fd); } static void diff --git a/usr.bin/cvs/rcs.h b/usr.bin/cvs/rcs.h index 7b7b3c3999f..302d43d83f7 100644 --- a/usr.bin/cvs/rcs.h +++ b/usr.bin/cvs/rcs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.h,v 1.87 2008/02/09 14:03:20 joris Exp $ */ +/* $OpenBSD: rcs.h,v 1.88 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -258,7 +258,7 @@ int rcs_state_check(const char *); RCSNUM *rcs_tag_resolve(RCSFILE *, const char *); const char *rcs_errstr(int); void rcs_write(RCSFILE *); -void rcs_rev_write_stmp(RCSFILE *, RCSNUM *, char *, int); +int rcs_rev_write_stmp(RCSFILE *, RCSNUM *, char *, int); void rcs_rev_write_fd(RCSFILE *, RCSNUM *, int, int); struct cvs_lines *rcs_rev_getlines(RCSFILE *, RCSNUM *, struct cvs_line ***); diff --git a/usr.bin/cvs/remote.c b/usr.bin/cvs/remote.c index 0b325ca2e52..f707a1dc5f3 100644 --- a/usr.bin/cvs/remote.c +++ b/usr.bin/cvs/remote.c @@ -1,4 +1,4 @@ -/* $OpenBSD: remote.c,v 1.20 2008/02/10 14:15:36 joris Exp $ */ +/* $OpenBSD: remote.c,v 1.21 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -155,7 +155,7 @@ cvs_remote_receive_file(int fd, size_t len) } void -cvs_remote_send_file(const char *path) +cvs_remote_send_file(const char *path, int _fd) { int fd; FILE *out, *in; @@ -169,11 +169,17 @@ cvs_remote_send_file(const char *path) else out = current_cvsroot->cr_srvin; - if ((fd = open(path, O_RDONLY)) == -1) - fatal("cvs_remote_send_file: %s: %s", path, strerror(errno)); + fd = dup(_fd); + if (fd == -1) + fatal("cvs_remote_send_file: dup: %s", strerror(errno)); + + if (lseek(fd, SEEK_SET, 0) < 0) + fatal("cvs_remote_send_file: %s: lseek: %s", path, + strerror(errno)); if (fstat(fd, &st) == -1) - fatal("cvs_remote_send_file: %s: %s", path, strerror(errno)); + fatal("cvs_remote_send_file: %s: fstat: %s", path, + strerror(errno)); cvs_modetostr(st.st_mode, buf, sizeof(buf)); cvs_remote_output(buf); diff --git a/usr.bin/cvs/remote.h b/usr.bin/cvs/remote.h index a874816fa57..bb49701907f 100644 --- a/usr.bin/cvs/remote.h +++ b/usr.bin/cvs/remote.h @@ -1,4 +1,4 @@ -/* $OpenBSD: remote.h,v 1.31 2008/02/10 14:00:41 joris Exp $ */ +/* $OpenBSD: remote.h,v 1.32 2008/02/27 22:34:04 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -119,7 +119,7 @@ void cvs_remote_classify_file(struct cvs_file *); void cvs_remote_output(const char *); char *cvs_remote_input(void); void cvs_remote_receive_file(int, size_t); -void cvs_remote_send_file(const char *); +void cvs_remote_send_file(const char *, int); extern int cvs_client_inlog_fd; extern int cvs_client_outlog_fd; |