summaryrefslogtreecommitdiff
path: root/usr.bin/cvs
diff options
context:
space:
mode:
authorJoris Vink <joris@cvs.openbsd.org>2008-02-27 22:34:05 +0000
committerJoris Vink <joris@cvs.openbsd.org>2008-02-27 22:34:05 +0000
commitc8955619dd8db636823797d2bd41b68bc78af8c1 (patch)
tree0f1a922b9d1b4bb083ea6b7477f91aaa7333681d /usr.bin/cvs
parent3d3b75f61b57504b71451e352de59d6ff8ffd6a4 (diff)
prevent file races
ok tobias@
Diffstat (limited to 'usr.bin/cvs')
-rw-r--r--usr.bin/cvs/buf.c11
-rw-r--r--usr.bin/cvs/buf.h4
-rw-r--r--usr.bin/cvs/checkout.c10
-rw-r--r--usr.bin/cvs/client.c4
-rw-r--r--usr.bin/cvs/commit.c18
-rw-r--r--usr.bin/cvs/diff.c31
-rw-r--r--usr.bin/cvs/diff.h4
-rw-r--r--usr.bin/cvs/diff3.c68
-rw-r--r--usr.bin/cvs/diff_internals.c30
-rw-r--r--usr.bin/cvs/import.c12
-rw-r--r--usr.bin/cvs/rcs.c20
-rw-r--r--usr.bin/cvs/rcs.h4
-rw-r--r--usr.bin/cvs/remote.c16
-rw-r--r--usr.bin/cvs/remote.h4
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;