summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoris <joris@openbsd.org>2006-05-27 05:20:25 +0000
committerjoris <joris@openbsd.org>2006-05-27 05:20:25 +0000
commit9f820608d8c6cdc27b1e73a107a9655033009cac (patch)
tree42ddcb9d4c940cc0084784232247f8db95cc976d
parentremove bogus non-style advice that just causes "discussions" (diff)
downloadwireguard-openbsd-9f820608d8c6cdc27b1e73a107a9655033009cac.tar.xz
wireguard-openbsd-9f820608d8c6cdc27b1e73a107a9655033009cac.zip
pruning (-P) support for both the update and checkout commands;
-rw-r--r--usr.bin/cvs/checkout.c9
-rw-r--r--usr.bin/cvs/cvs.h3
-rw-r--r--usr.bin/cvs/update.c88
3 files changed, 95 insertions, 5 deletions
diff --git a/usr.bin/cvs/checkout.c b/usr.bin/cvs/checkout.c
index 6eccb8c5927..bebfab3077b 100644
--- a/usr.bin/cvs/checkout.c
+++ b/usr.bin/cvs/checkout.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: checkout.c,v 1.53 2006/05/27 03:30:30 joris Exp $ */
+/* $OpenBSD: checkout.c,v 1.54 2006/05/27 05:20:25 joris Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -25,6 +25,8 @@
int cvs_checkout(int, char **);
static void checkout_repository(const char *, const char *);
+extern int prune_dirs;
+
struct cvs_cmd cvs_cmd_checkout = {
CVS_OP_CHECKOUT, CVS_REQ_CO, "checkout",
{ "co", "get" },
@@ -45,6 +47,9 @@ cvs_checkout(int argc, char **argv)
while ((ch = getopt(argc, argv, cvs_cmd_checkout.cmd_opts)) != -1) {
switch (ch) {
+ case 'P':
+ prune_dirs = 1;
+ break;
default:
fatal("%s", cvs_cmd_checkout.cmd_synopsis);
}
@@ -86,7 +91,7 @@ checkout_repository(const char *repobase, const char *wdbase)
TAILQ_INIT(&dl);
cr.enterdir = cvs_update_enterdir;
- cr.leavedir = NULL;
+ cr.leavedir = cvs_update_leavedir;
cr.local = cvs_update_local;
cr.remote = NULL;
diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h
index 290cc79b348..22e471ed8da 100644
--- a/usr.bin/cvs/cvs.h
+++ b/usr.bin/cvs/cvs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cvs.h,v 1.104 2006/05/27 03:30:30 joris Exp $ */
+/* $OpenBSD: cvs.h,v 1.105 2006/05/27 05:20:25 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -337,6 +337,7 @@ void cvsroot_remove(struct cvsroot *);
/* misc stuff */
void cvs_update_local(struct cvs_file *);
void cvs_update_enterdir(struct cvs_file *);
+void cvs_update_leavedir(struct cvs_file *);
int cvs_checkout_file(struct cvs_file *, RCSNUM *, int);
#endif
diff --git a/usr.bin/cvs/update.c b/usr.bin/cvs/update.c
index e6f5ebf52ad..72e3bad258c 100644
--- a/usr.bin/cvs/update.c
+++ b/usr.bin/cvs/update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: update.c,v 1.59 2006/05/27 03:30:31 joris Exp $ */
+/* $OpenBSD: update.c,v 1.60 2006/05/27 05:20:25 joris Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -23,6 +23,7 @@
#include "proto.h"
int cvs_update(int, char **);
+int prune_dirs = 0;
struct cvs_cmd cvs_cmd_update = {
CVS_OP_UPDATE, CVS_REQ_UPDATE, "update",
@@ -62,6 +63,7 @@ cvs_update(int argc, char **argv)
case 'l':
break;
case 'P':
+ prune_dirs = 1;
break;
case 'p':
break;
@@ -81,7 +83,7 @@ cvs_update(int argc, char **argv)
argv += optind;
cr.enterdir = cvs_update_enterdir;
- cr.leavedir = NULL;
+ cr.leavedir = cvs_update_leavedir;
cr.local = cvs_update_local;
cr.remote = NULL;
@@ -123,6 +125,88 @@ cvs_update_enterdir(struct cvs_file *cf)
}
void
+cvs_update_leavedir(struct cvs_file *cf)
+{
+ long base;
+ int nbytes;
+ int isempty;
+ size_t bufsize;
+ struct stat st;
+ struct dirent *dp;
+ char *buf, *ebuf, *cp;
+ struct cvs_ent *ent;
+ struct cvs_ent_line *line;
+ CVSENTRIES *entlist;
+
+ if (fstat(cf->fd, &st) == -1)
+ fatal("cvs_update_leavedir: %s", strerror(errno));
+
+ bufsize = st.st_size;
+ if (bufsize < st.st_blksize)
+ bufsize = st.st_blksize;
+
+ isempty = 1;
+ buf = xmalloc(bufsize);
+
+ if (lseek(cf->fd, SEEK_SET, 0) == -1)
+ fatal("cvs_update_leavedir: %s", strerror(errno));
+
+ while ((nbytes = getdirentries(cf->fd, buf, bufsize, &base)) > 0) {
+ ebuf = buf + nbytes;
+ cp = buf;
+
+ while (cp < ebuf) {
+ dp = (struct dirent *)cp;
+ if (!strcmp(dp->d_name, ".") ||
+ !strcmp(dp->d_name, "..") ||
+ dp->d_reclen == 0) {
+ cp += dp->d_reclen;
+ continue;
+ }
+
+ if (!strcmp(dp->d_name, CVS_PATH_CVSDIR)) {
+ entlist = cvs_ent_open(cf->file_path);
+ TAILQ_FOREACH(line, &(entlist->cef_ent),
+ entries_list) {
+ ent = cvs_ent_parse(line->buf);
+
+ if (ent->ce_status == CVS_ENT_REMOVED) {
+ isempty = 0;
+ cvs_ent_free(ent);
+ cvs_ent_close(entlist,
+ ENT_NOSYNC);
+ break;
+ }
+
+ cvs_ent_free(ent);
+ }
+ cvs_ent_close(entlist, ENT_NOSYNC);
+ } else {
+ isempty = 0;
+ }
+
+ if (isempty == 0)
+ break;
+
+ cp += dp->d_reclen;
+ }
+ }
+
+ if (nbytes == -1)
+ fatal("cvs_update_leavedir: %s", strerror(errno));
+
+ xfree(buf);
+
+ if (isempty == 1 && prune_dirs == 1) {
+ cvs_rmdir(cf->file_path);
+
+ entlist = cvs_ent_open(cf->file_wd);
+ cvs_ent_remove(entlist, cf->file_name);
+ cvs_ent_close(entlist, ENT_SYNC);
+ }
+}
+
+void
cvs_update_local(struct cvs_file *cf)
{
CVSENTRIES *entlist;