summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/rcs/ci.c26
-rw-r--r--usr.bin/rcs/co.c61
-rw-r--r--usr.bin/rcs/rcs.c42
-rw-r--r--usr.bin/rcs/rcs.h10
-rw-r--r--usr.bin/rcs/rcsclean.c13
-rw-r--r--usr.bin/rcs/rcsdiff.c21
-rw-r--r--usr.bin/rcs/rcsmerge.c9
-rw-r--r--usr.bin/rcs/rcsprog.c28
-rw-r--r--usr.bin/rcs/rcsutil.c103
-rw-r--r--usr.bin/rcs/rcsutil.h8
-rw-r--r--usr.bin/rcs/rlog.c10
11 files changed, 179 insertions, 152 deletions
diff --git a/usr.bin/rcs/ci.c b/usr.bin/rcs/ci.c
index b2d7c2d8869..088753a8698 100644
--- a/usr.bin/rcs/ci.c
+++ b/usr.bin/rcs/ci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ci.c,v 1.162 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: ci.c,v 1.163 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005, 2006 Niall O'Higgins <niallo@openbsd.org>
* All rights reserved.
@@ -100,6 +100,7 @@ checkin_usage(void)
int
checkin_main(int argc, char **argv)
{
+ int fd;
int i, ch, status;
char *rev_str;
struct checkin_params pb;
@@ -229,7 +230,6 @@ checkin_main(int argc, char **argv)
if ((pb.username = getlogin()) == NULL)
err(1, "getlogin");
-
for (i = 0; i < argc; i++) {
pb.filename = argv[i];
@@ -240,8 +240,10 @@ checkin_main(int argc, char **argv)
* Test for existence of ,v file. If we are expected to
* create one, set NEWFILE flag.
*/
- if (rcs_statfile(pb.filename, pb.fpath,
- sizeof(pb.fpath), pb.flags) < 0) {
+ fd = rcs_statfile(pb.filename, pb.fpath, sizeof(pb.fpath),
+ pb.flags);
+
+ if (fd < 0) {
if (pb.openflags & RCS_CREATE)
pb.flags |= NEWFILE;
else {
@@ -254,6 +256,7 @@ checkin_main(int argc, char **argv)
if (pb.flags & CI_INIT) {
warnx("%s already exists", pb.fpath);
status = 1;
+ (void)close(fd);
(void)close(workfile_fd);
continue;
}
@@ -264,18 +267,11 @@ checkin_main(int argc, char **argv)
* If we are to create a new ,v file, we must decide where it
* should go.
*/
- if (pb.flags & NEWFILE) {
- char *fpath = rcs_choosefile(pb.filename);
- if (fpath == NULL) {
- status = 1;
- (void)close(workfile_fd);
- continue;
- }
- strlcpy(pb.fpath, fpath, sizeof(pb.fpath));
- xfree(fpath);
- }
+ if (pb.flags & NEWFILE)
+ fd = rcs_choosefile(pb.filename,
+ pb.fpath, sizeof(pb.fpath));
- pb.file = rcs_open(pb.fpath, pb.openflags, pb.fmode);
+ pb.file = rcs_open(pb.fpath, fd, pb.openflags, pb.fmode);
if (pb.file == NULL)
errx(1, "failed to open rcsfile `%s'", pb.fpath);
diff --git a/usr.bin/rcs/co.c b/usr.bin/rcs/co.c
index 300076eb53d..80c68db241e 100644
--- a/usr.bin/rcs/co.c
+++ b/usr.bin/rcs/co.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: co.c,v 1.85 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: co.c,v 1.86 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005 Joris Vink <joris@openbsd.org>
* All rights reserved.
@@ -36,7 +36,7 @@ static void checkout_err_nobranch(RCSFILE *, const char *, const char *,
int
checkout_main(int argc, char **argv)
{
- int i, ch, flags, kflag, status, warg;
+ int fd, i, ch, flags, kflag, status, warg;
RCSNUM *rev;
RCSFILE *file;
char fpath[MAXPATHLEN];
@@ -152,7 +152,8 @@ checkout_main(int argc, char **argv)
err(1, "getlogin");
for (i = 0; i < argc; i++) {
- if (rcs_statfile(argv[i], fpath, sizeof(fpath), flags) < 0)
+ fd = rcs_statfile(argv[i], fpath, sizeof(fpath), flags);
+ if (fd < 0)
continue;
if (!(flags & QUIET))
@@ -161,14 +162,16 @@ checkout_main(int argc, char **argv)
if ((flags & CO_LOCK) && (kflag & RCS_KWEXP_VAL)) {
warnx("%s: cannot combine -kv and -l", fpath);
+ (void)close(fd);
continue;
}
- if ((file = rcs_open(fpath, RCS_RDWR|RCS_PARSE_FULLY)) == NULL)
+ if ((file = rcs_open(fpath, fd,
+ RCS_RDWR|RCS_PARSE_FULLY)) == NULL)
continue;
if (flags & PRESERVETIME)
- rcs_mtime = rcs_get_mtime(file->rf_path);
+ rcs_mtime = rcs_get_mtime(file);
rcs_kwexp_set(file, kflag);
@@ -197,11 +200,12 @@ checkout_main(int argc, char **argv)
if (!(flags & QUIET))
printf("done\n");
- rcs_close(file);
rcsnum_free(rev);
+ rcs_write(file);
if (flags & PRESERVETIME)
- rcs_set_mtime(fpath, rcs_mtime);
+ rcs_set_mtime(file, rcs_mtime);
+ rcs_close(file);
}
if (author != NULL && warg)
@@ -240,7 +244,7 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags,
{
BUF *bp;
u_int i;
- int lcount;
+ int fd, lcount;
char buf[16];
mode_t mode = 0444;
struct stat st;
@@ -364,10 +368,11 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags,
/*
* File inherits permissions from its ,v file
*/
- if (stat(file->rf_path, &st) == -1)
- err(1, "%s", file->rf_path);
-
- mode = st.st_mode;
+ if (file->fd != -1) {
+ if (fstat(file->fd, &st) == -1)
+ err(1, "%s", file->rf_path);
+ mode = st.st_mode;
+ }
if (flags & CO_LOCK) {
if (file->rf_ndelta != 0) {
@@ -379,8 +384,11 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags,
}
/* Strip all write bits from mode */
- mode = st.st_mode &
- (S_IXUSR|S_IXGRP|S_IXOTH|S_IRUSR|S_IRGRP|S_IROTH);
+ if (file->fd != -1) {
+ mode = st.st_mode &
+ (S_IXUSR|S_IXGRP|S_IXOTH|S_IRUSR|S_IRGRP|S_IROTH);
+ }
+
mode |= S_IWUSR;
if (file->rf_ndelta != 0) {
@@ -397,8 +405,10 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags,
}
/* Strip all write bits from mode */
- mode = st.st_mode &
- (S_IXUSR|S_IXGRP|S_IXOTH|S_IRUSR|S_IRGRP|S_IROTH);
+ if (file->fd != -1) {
+ mode = st.st_mode &
+ (S_IXUSR|S_IXGRP|S_IXOTH|S_IRUSR|S_IRGRP|S_IROTH);
+ }
if (file->rf_ndelta != 0) {
if (!(flags & QUIET) && !(flags & NEWFILE) &&
@@ -424,7 +434,7 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags,
file->rf_path, lcount);
}
- if (!(flags & PIPEOUT) && stat(dst, &st) == 0 && !(flags & FORCE)) {
+ if (!(flags & PIPEOUT) && stat(dst, &st) != -1 && !(flags & FORCE)) {
/*
* XXX - Not sure what is "right". If we go according
* to GNU's behavior, an existing file with no writable
@@ -460,20 +470,33 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags,
printf("%s", content);
xfree(content);
} else {
- if (rcs_buf_write(bp, dst, mode) < 0) {
+ (void)unlink(dst);
+
+ if ((fd = open(dst, O_WRONLY|O_CREAT|O_TRUNC, mode)) < 0)
+ err(1, "%s", dst);
+
+ if (rcs_buf_write_fd(bp, fd) < 0) {
warnx("failed to write revision to file");
rcs_buf_free(bp);
+ (void)close(fd);
return (-1);
}
+
+ if (fchmod(fd, mode) == -1)
+ warn("%s", dst);
+
rcs_buf_free(bp);
+
if (flags & CO_REVDATE) {
struct timeval tv[2];
memset(&tv, 0, sizeof(tv));
tv[0].tv_sec = (long)rcs_rev_getdate(file, rev);
tv[1].tv_sec = tv[0].tv_sec;
- if (utimes(dst, (const struct timeval *)&tv) < 0)
+ if (futimes(fd, (const struct timeval *)&tv) < 0)
warn("utimes");
}
+
+ (void)close(fd);
}
return (0);
diff --git a/usr.bin/rcs/rcs.c b/usr.bin/rcs/rcs.c
index 4f24efce48b..28c98d197ed 100644
--- a/usr.bin/rcs/rcs.c
+++ b/usr.bin/rcs/rcs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcs.c,v 1.2 2006/04/26 15:08:25 xsa Exp $ */
+/* $OpenBSD: rcs.c,v 1.3 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -236,25 +236,12 @@ static void rcs_strprint(const u_char *, size_t, FILE *);
static char* rcs_expand_keywords(char *, struct rcs_delta *, char *,
size_t, int);
-/*
- * rcs_open()
- *
- * Open a file containing RCS-formatted information. The file's path is
- * given in <path>, and the opening flags are given in <flags>, which is either
- * RCS_READ, RCS_WRITE, or RCS_RDWR. If the open requests write access and
- * the file does not exist, the RCS_CREATE flag must also be given, in which
- * case it will be created with the mode specified in a third argument of
- * type mode_t. If the file exists and RCS_CREATE is passed, the open will
- * fail.
- * Returns a handle to the opened file on success, or NULL on failure.
- */
RCSFILE *
-rcs_open(const char *path, int flags, ...)
+rcs_open(const char *path, int fd, int flags, ...)
{
- int ret, mode;
+ int mode;
mode_t fmode;
RCSFILE *rfp;
- struct stat st;
va_list vap;
struct rcs_delta *rdp;
struct rcs_lock *lkr;
@@ -262,19 +249,11 @@ rcs_open(const char *path, int flags, ...)
fmode = S_IRUSR|S_IRGRP|S_IROTH;
flags &= 0xffff; /* ditch any internal flags */
- if (((ret = stat(path, &st)) == -1) && errno == ENOENT) {
- if (flags & RCS_CREATE) {
- va_start(vap, flags);
- mode = va_arg(vap, int);
- va_end(vap);
- fmode = (mode_t)mode;
- } else {
- rcs_errno = RCS_ERR_NOENT;
- return (NULL);
- }
- } else if (ret == 0 && (flags & RCS_CREATE)) {
- warnx("RCS file `%s' exists", path);
- return (NULL);
+ if (flags & RCS_CREATE) {
+ va_start(vap, flags);
+ mode = va_arg(vap, int);
+ va_end(vap);
+ fmode = (mode_t)mode;
}
rfp = xcalloc(1, sizeof(*rfp));
@@ -282,6 +261,7 @@ rcs_open(const char *path, int flags, ...)
rfp->rf_path = xstrdup(path);
rfp->rf_flags = flags | RCS_SLOCK | RCS_SYNCED;
rfp->rf_mode = fmode;
+ rfp->fd = fd;
TAILQ_INIT(&(rfp->rf_delta));
TAILQ_INIT(&(rfp->rf_access));
@@ -1731,8 +1711,8 @@ rcs_parse_init(RCSFILE *rfp)
pdp->rp_lines = 0;
pdp->rp_pttype = RCS_TOK_ERR;
- if ((pdp->rp_file = fopen(rfp->rf_path, "r")) == NULL)
- err(1, "%s", rfp->rf_path);
+ if ((pdp->rp_file = fdopen(rfp->fd, "r")) == NULL)
+ err(1, "fopen: `%s'", rfp->rf_path);
pdp->rp_buf = xmalloc((size_t)RCS_BUFSIZE);
pdp->rp_blen = RCS_BUFSIZE;
diff --git a/usr.bin/rcs/rcs.h b/usr.bin/rcs/rcs.h
index 4ae27d19e0b..adf7677bdc6 100644
--- a/usr.bin/rcs/rcs.h
+++ b/usr.bin/rcs/rcs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcs.h,v 1.1 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: rcs.h,v 1.2 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -190,6 +190,7 @@ struct rcs_delta {
typedef struct rcs_file {
+ int fd;
char *rf_path;
mode_t rf_mode;
u_int rf_flags;
@@ -209,11 +210,9 @@ typedef struct rcs_file {
void *rf_pdata;
} RCSFILE;
-
extern int rcs_errno;
-
-RCSFILE *rcs_open(const char *, int, ...);
+RCSFILE *rcs_open(const char *, int, int, ...);
void rcs_close(RCSFILE *);
const RCSNUM *rcs_head_get(RCSFILE *);
int rcs_head_set(RCSFILE *, RCSNUM *);
@@ -253,7 +252,6 @@ RCSNUM *rcs_tag_resolve(RCSFILE *, const char *);
const char *rcs_errstr(int);
int rcs_write(RCSFILE *);
-
int rcs_kflag_get(const char *);
void rcs_kflag_usage(void);
int rcs_kw_expand(RCSFILE *, u_char *, size_t, size_t *);
@@ -272,9 +270,7 @@ int rcsnum_cmp(const RCSNUM *, const RCSNUM *, u_int);
/* rcstime.c */
void rcs_set_tz(char *, struct rcs_delta *, struct tm *);
-
extern char *timezone_flag;
-
extern int rcsnum_flags;
#endif /* RCS_H */
diff --git a/usr.bin/rcs/rcsclean.c b/usr.bin/rcs/rcsclean.c
index 9e20f1e55dc..6dc3b225110 100644
--- a/usr.bin/rcs/rcsclean.c
+++ b/usr.bin/rcs/rcsclean.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsclean.c,v 1.44 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: rcsclean.c,v 1.45 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005 Joris Vink <joris@openbsd.org>
* All rights reserved.
@@ -127,7 +127,7 @@ rcsclean_usage(void)
static void
rcsclean_file(char *fname, const char *rev_str)
{
- int match;
+ int fd, match;
RCSFILE *file;
char fpath[MAXPATHLEN], numb[64];
RCSNUM *rev;
@@ -138,14 +138,14 @@ rcsclean_file(char *fname, const char *rev_str)
file = NULL;
rev = NULL;
- if (rcs_statfile(fname, fpath, sizeof(fpath), flags) < 0)
+ if ((fd = rcs_statfile(fname, fpath, sizeof(fpath), flags)) < 0)
goto out;
- if ((file = rcs_open(fpath, RCS_RDWR)) == NULL)
+ if ((file = rcs_open(fpath, fd, RCS_RDWR)) == NULL)
goto out;
if (flags & PRESERVETIME)
- rcs_mtime = rcs_get_mtime(file->rf_path);
+ rcs_mtime = rcs_get_mtime(file);
rcs_kwexp_set(file, kflag);
@@ -200,8 +200,9 @@ rcsclean_file(char *fname, const char *rev_str)
}
}
+ rcs_write(file);
if (flags & PRESERVETIME)
- rcs_set_mtime(fpath, rcs_mtime);
+ rcs_set_mtime(file, rcs_mtime);
out:
if (b1 != NULL)
diff --git a/usr.bin/rcs/rcsdiff.c b/usr.bin/rcs/rcsdiff.c
index 034c4814848..a475d4a20cf 100644
--- a/usr.bin/rcs/rcsdiff.c
+++ b/usr.bin/rcs/rcsdiff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsdiff.c,v 1.57 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: rcsdiff.c,v 1.58 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005 Joris Vink <joris@openbsd.org>
* All rights reserved.
@@ -38,7 +38,7 @@ static int kflag = RCS_KWEXP_ERR;
int
rcsdiff_main(int argc, char **argv)
{
- int i, ch, status;
+ int fd, i, ch, status;
RCSNUM *rev1, *rev2;
RCSFILE *file;
char fpath[MAXPATHLEN], *rev_str1, *rev_str2;
@@ -109,10 +109,12 @@ rcsdiff_main(int argc, char **argv)
}
for (i = 0; i < argc; i++) {
- if (rcs_statfile(argv[i], fpath, sizeof(fpath), flags) < 0)
+ fd = rcs_statfile(argv[i], fpath, sizeof(fpath), flags);
+ if (fd < 0)
continue;
- if ((file = rcs_open(fpath, RCS_READ|RCS_PARSE_FULLY)) == NULL)
+ if ((file = rcs_open(fpath, fd,
+ RCS_READ|RCS_PARSE_FULLY)) == NULL)
continue;
rcs_kwexp_set(file, kflag);
@@ -173,13 +175,13 @@ rcsdiff_usage(void)
static int
rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename)
{
- int ret;
+ int ret, fd;
time_t t;
+ struct stat st;
char path1[MAXPATHLEN], path2[MAXPATHLEN];
BUF *b1, *b2;
char rbuf[64];
struct tm *tb;
- struct stat st;
struct timeval tv[2], tv2[2];
memset(&tv, 0, sizeof(tv));
@@ -191,7 +193,7 @@ rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename)
diff_rev1 = rev;
diff_rev2 = NULL;
- if (stat(filename, &st) == -1) {
+ if ((fd = open(filename, O_RDONLY)) == -1) {
warn("%s", filename);
goto out;
}
@@ -217,6 +219,9 @@ rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename)
}
/* XXX - GNU uses GMT */
+ if (fstat(fd, &st) == -1)
+ err(1, "%s", filename);
+
tb = gmtime(&st.st_mtime);
t = mktime(tb);
@@ -247,6 +252,8 @@ rcsdiff_file(RCSFILE *file, RCSNUM *rev, const char *filename)
ret = 0;
out:
+ if (fd != -1)
+ (void)close(fd);
if (b1 != NULL)
rcs_buf_free(b1);
if (b2 != NULL)
diff --git a/usr.bin/rcs/rcsmerge.c b/usr.bin/rcs/rcsmerge.c
index 9335838e503..e4eadf8167b 100644
--- a/usr.bin/rcs/rcsmerge.c
+++ b/usr.bin/rcs/rcsmerge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsmerge.c,v 1.36 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: rcsmerge.c,v 1.37 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005, 2006 Xavier Santolaria <xsa@openbsd.org>
* All rights reserved.
@@ -32,7 +32,7 @@
int
rcsmerge_main(int argc, char **argv)
{
- int i, ch, flags, kflag;
+ int fd, i, ch, flags, kflag;
char *fcont, fpath[MAXPATHLEN], r1[16], r2[16], *rev_str1, *rev_str2;
RCSFILE *file;
RCSNUM *rev1, *rev2;
@@ -105,10 +105,11 @@ rcsmerge_main(int argc, char **argv)
}
for (i = 0; i < argc; i++) {
- if (rcs_statfile(argv[i], fpath, sizeof(fpath), flags) < 0)
+ fd = rcs_statfile(argv[i], fpath, sizeof(fpath), flags);
+ if (fd < 0)
continue;
- if ((file = rcs_open(fpath, RCS_READ)) == NULL)
+ if ((file = rcs_open(fpath, fd, RCS_READ)) == NULL)
continue;
if (!(flags & QUIET))
diff --git a/usr.bin/rcs/rcsprog.c b/usr.bin/rcs/rcsprog.c
index 54592cfc129..e846f98d8d6 100644
--- a/usr.bin/rcs/rcsprog.c
+++ b/usr.bin/rcs/rcsprog.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsprog.c,v 1.117 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: rcsprog.c,v 1.118 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -174,6 +174,7 @@ rcs_usage(void)
int
rcs_main(int argc, char **argv)
{
+ int fd, ofd;
int i, j, ch, flags, kflag, lkmode;
char fpath[MAXPATHLEN], ofpath[MAXPATHLEN];
char *logstr, *logmsg, *nflag, *descfile;
@@ -196,11 +197,13 @@ rcs_main(int argc, char **argv)
warnx("warning: No options were given; "
"this usage is obsolescent.");
+ ofd = -1;
while ((ch = rcs_getopt(argc, argv, RCSPROG_OPTSTRING)) != -1) {
switch (ch) {
case 'A':
- if (rcs_statfile(rcs_optarg, ofpath,
- sizeof(ofpath), flags) < 0)
+ ofd = rcs_statfile(rcs_optarg, ofpath,
+ sizeof(ofpath), flags);
+ if (ofd < 0)
exit(1);
rcsflags |= CO_ACLAPPEND;
break;
@@ -300,13 +303,14 @@ rcs_main(int argc, char **argv)
}
for (i = 0; i < argc; i++) {
- if (rcs_statfile(argv[i], fpath, sizeof(fpath), flags) < 0)
+ fd = rcs_statfile(argv[i], fpath, sizeof(fpath), flags);
+ if (fd < 0 && !(flags & RCS_CREATE))
continue;
if (!(rcsflags & QUIET))
printf("RCS file: %s\n", fpath);
- if ((file = rcs_open(fpath, flags, fmode)) == NULL)
+ if ((file = rcs_open(fpath, fd, flags, fmode)) == NULL)
continue;
if (rcsflags & DESCRIPTION)
@@ -315,7 +319,7 @@ rcs_main(int argc, char **argv)
rcs_set_description(file, NULL);
if (rcsflags & PRESERVETIME)
- rcs_mtime = rcs_get_mtime(file->rf_path);
+ rcs_mtime = rcs_get_mtime(file);
if (nflag != NULL)
rcs_attach_symbol(file, nflag);
@@ -348,13 +352,14 @@ rcs_main(int argc, char **argv)
/* entries to add from <oldfile> */
if (rcsflags & CO_ACLAPPEND) {
/* XXX */
- if ((oldfile = rcs_open(ofpath, RCS_READ)) == NULL)
+ if ((oldfile = rcs_open(ofpath, ofd, RCS_READ)) == NULL)
exit(1);
TAILQ_FOREACH(acp, &(oldfile->rf_access), ra_list)
rcs_access_add(file, acp->ra_name);
rcs_close(oldfile);
+ ofd = -1;
}
/* entries to add to the access list */
@@ -467,10 +472,12 @@ rcs_main(int argc, char **argv)
}
}
- rcs_close(file);
+ rcs_write(file);
if (rcsflags & PRESERVETIME)
- rcs_set_mtime(fpath, rcs_mtime);
+ rcs_set_mtime(file, rcs_mtime);
+
+ rcs_close(file);
if (!(rcsflags & QUIET))
printf("done\n");
@@ -485,6 +492,9 @@ rcs_main(int argc, char **argv)
if (orange != NULL)
xfree(orange);
+ if (ofd != -1)
+ (void)close(ofd);
+
return (0);
}
diff --git a/usr.bin/rcs/rcsutil.c b/usr.bin/rcs/rcsutil.c
index cd6c9ff086a..8c732a0e944 100644
--- a/usr.bin/rcs/rcsutil.c
+++ b/usr.bin/rcs/rcsutil.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsutil.c,v 1.5 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: rcsutil.c,v 1.6 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005, 2006 Joris Vink <joris@openbsd.org>
* Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org>
@@ -38,15 +38,16 @@
* Returns last modified time on success, or -1 on failure.
*/
time_t
-rcs_get_mtime(const char *filename)
+rcs_get_mtime(RCSFILE *file)
{
struct stat st;
time_t mtime;
- if (stat(filename, &st) == -1) {
- warn("%s", filename);
+ if (fstat(file->fd, &st) == -1) {
+ warn("%s", file->rf_path);
return (-1);
}
+
mtime = (time_t)st.st_mtimespec.tv_sec;
return (mtime);
@@ -58,7 +59,7 @@ rcs_get_mtime(const char *filename)
* Set <filename> last modified time to <mtime> if it's not set to -1.
*/
void
-rcs_set_mtime(const char *filename, time_t mtime)
+rcs_set_mtime(RCSFILE *file, time_t mtime)
{
static struct timeval tv[2];
@@ -68,7 +69,7 @@ rcs_set_mtime(const char *filename, time_t mtime)
tv[0].tv_sec = mtime;
tv[1].tv_sec = tv[0].tv_sec;
- if (utimes(filename, tv) == -1)
+ if (futimes(file->fd, tv) == -1)
err(1, "utimes");
}
@@ -137,9 +138,10 @@ rcs_getopt(int argc, char **argv, const char *optstr)
*
* Returns pointer to a char array on success, NULL on failure.
*/
-char *
-rcs_choosefile(const char *filename)
+int
+rcs_choosefile(const char *filename, char *out, size_t len)
{
+ int fd;
struct stat sb;
char *p, *ext, name[MAXPATHLEN], *next, *ptr, rcsdir[MAXPATHLEN],
*ret, *suffixes, rcspath[MAXPATHLEN];
@@ -148,13 +150,16 @@ rcs_choosefile(const char *filename)
if (rcs_suffixes == NULL)
rcs_suffixes = RCS_DEFAULT_SUFFIX;
+ fd = -1;
+
/*
* If `filename' contains a directory, `rcspath' contains that
* directory, including a trailing slash. Otherwise `rcspath'
* contains an empty string.
*/
if (strlcpy(rcspath, filename, sizeof(rcspath)) >= sizeof(rcspath))
- return (NULL);
+ errx(1, "rcs_choosefile: truncation");
+
/* If `/' is found, end string after `/'. */
if ((ptr = strrchr(rcspath, '/')) != NULL)
*(++ptr) = '\0';
@@ -164,33 +169,36 @@ rcs_choosefile(const char *filename)
/* Append RCS/ to `rcspath' if it exists. */
if (strlcpy(rcsdir, rcspath, sizeof(rcsdir)) >= sizeof(rcsdir) ||
strlcat(rcsdir, RCSDIR, sizeof(rcsdir)) >= sizeof(rcsdir))
- return (NULL);
+ errx(1, "rcs_choosefile: truncation");
+
if (stat(rcsdir, &sb) == 0 && (sb.st_mode & S_IFDIR))
- if (strlcpy(rcspath, rcsdir, sizeof(rcspath)) >= sizeof(rcspath) ||
+ if (strlcpy(rcspath, rcsdir, sizeof(rcspath))
+ >= sizeof(rcspath) ||
strlcat(rcspath, "/", sizeof(rcspath)) >= sizeof(rcspath))
- return (NULL);
+ errx(1, "rcs_choosefile: truncation");
/* Name of file without path. */
if ((ptr = strrchr(filename, '/')) == NULL) {
if (strlcpy(name, filename, sizeof(name)) >= sizeof(name))
- return (NULL);
+ errx(1, "rcs_choosefile: truncation");
} else {
/* Skip `/'. */
if (strlcpy(name, ptr + 1, sizeof(name)) >= sizeof(name))
- return (NULL);
+ errx(1, "rcs_choosefile: truncation");
}
/* Name of RCS file without an extension. */
if (strlcat(rcspath, name, sizeof(rcspath)) >= sizeof(rcspath))
- return (NULL);
+ errx(1, "rcs_choosefile: truncation");
/*
* If only the empty suffix was given, use existing rcspath.
* This ensures that there is at least one suffix for strsep().
*/
if (strcmp(rcs_suffixes, "") == 0) {
- ret = xstrdup(rcspath);
- return (ret);
+ fd = open(rcspath, O_RDONLY);
+ strlcpy(out, rcspath, len);
+ return (fd);
}
/*
@@ -205,10 +213,16 @@ rcs_choosefile(const char *filename)
if ((p = strrchr(rcspath, ',')) != NULL) {
if (!strcmp(p, ext)) {
- if (stat(rcspath, &sb) == 0) {
- ret = xstrdup(rcspath);
- goto out;
- }
+ if ((fd = open(rcspath, O_RDONLY)) == -1)
+ continue;
+
+ if (fstat(fd, &sb) == -1)
+ err(1, "%s", rcspath);
+
+ if (strlcpy(out, rcspath, len) >= len)
+ errx(1, "rcs_choosefile; truncation");
+
+ return (fd);
}
continue;
@@ -217,16 +231,22 @@ rcs_choosefile(const char *filename)
/* Construct RCS file path. */
if (strlcpy(fpath, rcspath, sizeof(fpath)) >= sizeof(fpath) ||
strlcat(fpath, ext, sizeof(fpath)) >= sizeof(fpath))
- goto out;
+ errx(1, "rcs_choosefile: truncation");
/* Don't use `filename' as RCS file. */
if (strcmp(fpath, filename) == 0)
continue;
- if (stat(fpath, &sb) == 0) {
- ret = xstrdup(fpath);
- goto out;
- }
+ if ((fd = open(fpath, O_RDONLY)) == -1)
+ continue;
+
+ if (fstat(fd, &sb) == -1)
+ err(1, "%s", fpath);
+
+ if (strlcpy(out, fpath, len) >= len)
+ errx(1, "rcs_choosefile: truncation");
+
+ return (fd);
}
/*
@@ -238,13 +258,14 @@ rcs_choosefile(const char *filename)
*/
if (strlcat(rcspath, suffixes, sizeof(rcspath)) >=
sizeof(rcspath))
- goto out;
- ret = xstrdup(rcspath);
+ errx(1, "rcs_choosefile: truncation");
-out:
- /* `ret' may be NULL, which indicates an error. */
xfree(suffixes);
- return (ret);
+
+ fd = open(rcspath, O_RDONLY);
+ strlcpy(out, rcspath, len);
+
+ return (fd);
}
/*
@@ -255,27 +276,17 @@ out:
int
rcs_statfile(char *fname, char *out, size_t len, int flags)
{
- struct stat st;
- char *rcspath;
-
- if ((rcspath = rcs_choosefile(fname)) == NULL)
- errx(1, "rcs_statfile: path truncation");
+ int fd;
- /* Error out if file not found and we are not creating one. */
- if (stat(rcspath, &st) == -1 && !(flags & RCS_CREATE)) {
+ fd = rcs_choosefile(fname, out, len);
+ if (fd == -1 && !(flags & RCS_CREATE)) {
if (strcmp(__progname, "rcsclean") != 0 &&
strcmp(__progname, "ci") != 0)
- warn("%s", rcspath);
- xfree(rcspath);
+ warn("%s", out);
return (-1);
}
- if (strlcpy(out, rcspath, len) >= len)
- errx(1, "rcs_statfile: path truncation");
-
- xfree(rcspath);
-
- return (0);
+ return (fd);
}
/*
diff --git a/usr.bin/rcs/rcsutil.h b/usr.bin/rcs/rcsutil.h
index 69017e287b4..68dc5d655eb 100644
--- a/usr.bin/rcs/rcsutil.h
+++ b/usr.bin/rcs/rcsutil.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsutil.h,v 1.2 2006/04/24 04:51:57 ray Exp $ */
+/* $OpenBSD: rcsutil.h,v 1.3 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org>
* All rights reserved.
@@ -31,10 +31,10 @@
/* rcsutil.c */
int rcs_getopt(int, char **, const char *);
-void rcs_set_mtime(const char *, time_t);
-char *rcs_choosefile(const char *);
+void rcs_set_mtime(RCSFILE *, time_t);
+int rcs_choosefile(const char *, char *, size_t);
int rcs_statfile(char *, char *, size_t, int);
-time_t rcs_get_mtime(const char *);
+time_t rcs_get_mtime(RCSFILE *);
RCSNUM *rcs_getrevnum(const char *, RCSFILE *);
char *rcs_prompt(const char *);
u_int rcs_rev_select(RCSFILE *, char *);
diff --git a/usr.bin/rcs/rlog.c b/usr.bin/rcs/rlog.c
index 4fb1c917274..d19ccbd9cc7 100644
--- a/usr.bin/rcs/rlog.c
+++ b/usr.bin/rcs/rlog.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rlog.c,v 1.51 2006/04/26 02:55:13 joris Exp $ */
+/* $OpenBSD: rlog.c,v 1.52 2006/04/26 21:55:22 joris Exp $ */
/*
* Copyright (c) 2005 Joris Vink <joris@openbsd.org>
* Copyright (c) 2005, 2006 Xavier Santolaria <xsa@openbsd.org>
@@ -58,7 +58,7 @@ rlog_main(int argc, char **argv)
{
RCSFILE *file;
int Rflag;
- int i, ch;
+ int i, ch, fd;
char fpath[MAXPATHLEN];
rcsnum_flags |= RCSNUM_NO_MAGIC;
@@ -137,10 +137,12 @@ rlog_main(int argc, char **argv)
}
for (i = 0; i < argc; i++) {
- if (rcs_statfile(argv[i], fpath, sizeof(fpath), 0) < 0)
+ fd = rcs_statfile(argv[i], fpath, sizeof(fpath), 0);
+ if (fd < 0)
continue;
- if ((file = rcs_open(fpath, RCS_READ|RCS_PARSE_FULLY)) == NULL)
+ if ((file = rcs_open(fpath, fd,
+ RCS_READ|RCS_PARSE_FULLY)) == NULL)
continue;
if (Lflag == 1 && TAILQ_EMPTY(&(file->rf_locks))) {