diff options
-rw-r--r-- | usr.bin/rcs/ci.c | 26 | ||||
-rw-r--r-- | usr.bin/rcs/co.c | 61 | ||||
-rw-r--r-- | usr.bin/rcs/rcs.c | 42 | ||||
-rw-r--r-- | usr.bin/rcs/rcs.h | 10 | ||||
-rw-r--r-- | usr.bin/rcs/rcsclean.c | 13 | ||||
-rw-r--r-- | usr.bin/rcs/rcsdiff.c | 21 | ||||
-rw-r--r-- | usr.bin/rcs/rcsmerge.c | 9 | ||||
-rw-r--r-- | usr.bin/rcs/rcsprog.c | 28 | ||||
-rw-r--r-- | usr.bin/rcs/rcsutil.c | 103 | ||||
-rw-r--r-- | usr.bin/rcs/rcsutil.h | 8 | ||||
-rw-r--r-- | usr.bin/rcs/rlog.c | 10 |
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))) { |