summaryrefslogtreecommitdiffstats
path: root/usr.bin/rcs/rcsprog.c
diff options
context:
space:
mode:
authorjoris <joris@openbsd.org>2006-04-13 19:55:41 +0000
committerjoris <joris@openbsd.org>2006-04-13 19:55:41 +0000
commitea1ee718da29f72e9a8b2866e6d79d4e92c116c6 (patch)
tree42ba9580a404174b4d8e1f8927bd6d4f4d8a8146 /usr.bin/rcs/rcsprog.c
parentfix -z option for openrcs, this was broken by xsa (diff)
downloadwireguard-openbsd-ea1ee718da29f72e9a8b2866e6d79d4e92c116c6.tar.xz
wireguard-openbsd-ea1ee718da29f72e9a8b2866e6d79d4e92c116c6.zip
add support for the openrcs -o'range' option.
-o allows users to delete revisions in the specified RCS files. example: rcs -o1.4:1.6 foo deletes revisions 1.4 - 1.6 rcs -o1.3 foo deletes revision 1.3 joint work with niallo@ okay niallo@
Diffstat (limited to 'usr.bin/rcs/rcsprog.c')
-rw-r--r--usr.bin/rcs/rcsprog.c110
1 files changed, 103 insertions, 7 deletions
diff --git a/usr.bin/rcs/rcsprog.c b/usr.bin/rcs/rcsprog.c
index 4dec4f791f6..37d4b05a9e7 100644
--- a/usr.bin/rcs/rcsprog.c
+++ b/usr.bin/rcs/rcsprog.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsprog.c,v 1.100 2006/04/13 16:10:29 joris Exp $ */
+/* $OpenBSD: rcsprog.c,v 1.101 2006/04/13 19:55:41 joris Exp $ */
/*
* Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -29,7 +29,7 @@
#include "rcsprog.h"
#define RCS_CMD_MAXARG 128
-#define RCSPROG_OPTSTRING "A:a:b::c:e::hik:Ll::m:Mn:N:qt::TUu::Vx::z::"
+#define RCSPROG_OPTSTRING "A:a:b::c:e::hik:Ll::m:Mn:N:o:qt::TUu::Vx::z::"
#define DESC_PROMPT "enter description, terminated with single '.' " \
"or end of file:\nNOTE: This is NOT the log message!" \
@@ -64,8 +64,9 @@ struct rcs_prog {
struct cvs_wklhead rcs_temp_files;
void sighdlr(int);
-static void rcs_set_description(RCSFILE *, const char *);
-static void rcs_attach_symbol(RCSFILE *, const char *);
+static void rcs_set_description(RCSFILE *, const char *);
+static void rcs_attach_symbol(RCSFILE *, const char *);
+static u_int rcs_rev_select(RCSFILE *, char *);
/* ARGSUSED */
void
@@ -466,7 +467,7 @@ rcs_usage(void)
fprintf(stderr,
"usage: rcs [-ehIiLMqTUV] [-Aoldfile] [-ausers] [-b[rev]]\n"
" [-cstring] [-e[users]] [-kmode] [-l[rev]] [-mrev:msg]\n"
- " [-orev] [-sstate[:rev]] [-tfile|str] [-u[rev]]\n"
+ " [-orange] [-sstate[:rev]] [-tfile|str] [-u[rev]]\n"
" [-xsuffixes] file ...\n");
}
@@ -482,7 +483,7 @@ rcs_main(int argc, char **argv)
int i, j, ch, kflag, lkmode;
char fpath[MAXPATHLEN], ofpath[MAXPATHLEN];
char *logstr, *logmsg, *nflag, *descfile;
- char *alist, *comment, *elist, *lrev, *urev;
+ char *alist, *comment, *elist, *lrev, *urev, *orange;
mode_t fmode;
RCSFILE *file, *oldfile;
RCSNUM *logrev;
@@ -494,7 +495,7 @@ rcs_main(int argc, char **argv)
fmode = S_IRUSR|S_IRGRP|S_IROTH;
flags = RCS_RDWR|RCS_PARSE_FULLY;
lrev = urev = descfile = nflag = NULL;
- logstr = alist = comment = elist = NULL;
+ logstr = alist = comment = elist = orange = NULL;
while ((ch = rcs_getopt(argc, argv, RCSPROG_OPTSTRING)) != -1) {
switch (ch) {
@@ -552,6 +553,9 @@ rcs_main(int argc, char **argv)
nflag = xstrdup(rcs_optarg);
rcsflags |= RCSPROG_NFLAG;
break;
+ case 'o':
+ orange = xstrdup(rcs_optarg);
+ break;
case 'q':
verbose = 0;
break;
@@ -754,6 +758,23 @@ rcs_main(int argc, char **argv)
rcsnum_free(rev);
}
+ if (orange != NULL) {
+ struct rcs_delta *rdp;
+ char b[16];
+
+ rcs_rev_select(file, orange);
+ TAILQ_FOREACH(rdp, &(file->rf_delta), rd_list) {
+ /*
+ * Delete selected revisions.
+ */
+ if (rdp->rd_flags & RCS_RD_SELECT) {
+ rcsnum_tostr(rdp->rd_num, b, sizeof(b));
+ printf("deleting revision %s\n", b);
+ (void)rcs_rev_remove(file, rdp->rd_num);
+ }
+ }
+ }
+
rcs_close(file);
if (rcsflags & PRESERVETIME)
@@ -873,3 +894,78 @@ rcs_set_description(RCSFILE *file, const char *in)
rcs_desc_set(file, content);
xfree(content);
}
+
+static u_int
+rcs_rev_select(RCSFILE *file, char *range)
+{
+ int i;
+ u_int nrev;
+ char *ep;
+ char *lstr, *rstr;
+ struct rcs_delta *rdp;
+ struct cvs_argvector *revargv, *revrange;
+ RCSNUM lnum, rnum;
+
+ nrev = 0;
+ (void)memset(&lnum, 0, sizeof(lnum));
+ (void)memset(&rnum, 0, sizeof(rnum));
+
+ if (range == NULL) {
+ TAILQ_FOREACH(rdp, &file->rf_delta, rd_list)
+ if (rcsnum_cmp(rdp->rd_num, file->rf_head, 0) == 0) {
+ rdp->rd_flags |= RCS_RD_SELECT;
+ return (1);
+ }
+ return (0);
+ }
+
+ revargv = cvs_strsplit(range, ",");
+ for (i = 0; revargv->argv[i] != NULL; i++) {
+ revrange = cvs_strsplit(revargv->argv[i], ":");
+ if (revrange->argv[0] == NULL)
+ /* should not happen */
+ fatal("invalid revision range: %s", revargv->argv[i]);
+ else if (revrange->argv[1] == NULL)
+ lstr = rstr = revrange->argv[0];
+ else {
+ if (revrange->argv[2] != NULL)
+ fatal("invalid revision range: %s",
+ revargv->argv[i]);
+ lstr = revrange->argv[0];
+ rstr = revrange->argv[1];
+ if (strcmp(lstr, "") == 0)
+ lstr = NULL;
+ if (strcmp(rstr, "") == 0)
+ rstr = NULL;
+ }
+
+ if (lstr == NULL)
+ lstr = RCS_HEAD_INIT;
+ if (rcsnum_aton(lstr, &ep, &lnum) == 0 || (*ep != '\0'))
+ fatal("invalid revision: %s", lstr);
+
+ if (rstr != NULL) {
+ if (rcsnum_aton(rstr, &ep, &rnum) == 0 || (*ep != '\0'))
+ fatal("invalid revision: %s", rstr);
+ } else
+ rcsnum_cpy(file->rf_head, &rnum, 0);
+
+ cvs_argv_destroy(revrange);
+
+ TAILQ_FOREACH(rdp, &file->rf_delta, rd_list)
+ if ((rcsnum_cmp(rdp->rd_num, &lnum, 0) <= 0) &&
+ (rcsnum_cmp(rdp->rd_num, &rnum, 0) >= 0) &&
+ !(rdp->rd_flags & RCS_RD_SELECT)) {
+ rdp->rd_flags |= RCS_RD_SELECT;
+ nrev++;
+ }
+ }
+ cvs_argv_destroy(revargv);
+
+ if (lnum.rn_id != NULL)
+ xfree(lnum.rn_id);
+ if (rnum.rn_id != NULL)
+ xfree(rnum.rn_id);
+
+ return (nrev);
+}