summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorJoris Vink <joris@cvs.openbsd.org>2005-09-06 15:29:34 +0000
committerJoris Vink <joris@cvs.openbsd.org>2005-09-06 15:29:34 +0000
commit71442aed77bb01f56d28f6cbc9fdeb82acfe9212 (patch)
tree35b9ff888169a577e220f0a931adb7cf93123088 /usr.bin
parent68ccf787a8ec4f3499e320c5c4fdb8b8bb01406e (diff)
Make sure entries do not go away when we run through them in the file code.
Fixes corrupt Entry files. Problem found by Mike Pechkin, thanks.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/cvs/cvs.h9
-rw-r--r--usr.bin/cvs/entries.c3
-rw-r--r--usr.bin/cvs/file.c36
3 files changed, 27 insertions, 21 deletions
diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h
index ec2491d05a3..9498cfb1503 100644
--- a/usr.bin/cvs/cvs.h
+++ b/usr.bin/cvs/cvs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cvs.h,v 1.81 2005/09/05 19:29:42 xsa Exp $ */
+/* $OpenBSD: cvs.h,v 1.82 2005/09/06 15:29:33 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -260,6 +260,13 @@ struct cvs_ent {
time_t ce_mtime;
char *ce_opts;
char *ce_tag;
+
+ /*
+ * This variable is set to 1 if we have already processed this entry
+ * in the cvs_file_getdir() function. This is to avoid files being
+ * passed twice to the callbacks.
+ */
+ int processed;
TAILQ_ENTRY(cvs_ent) ce_list;
};
diff --git a/usr.bin/cvs/entries.c b/usr.bin/cvs/entries.c
index cc9de477513..97d4dc66215 100644
--- a/usr.bin/cvs/entries.c
+++ b/usr.bin/cvs/entries.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: entries.c,v 1.47 2005/08/22 08:53:12 joris Exp $ */
+/* $OpenBSD: entries.c,v 1.48 2005/09/06 15:29:33 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -371,6 +371,7 @@ cvs_ent_parse(const char *entry)
ent->ce_status = CVS_ENT_REG;
ent->ce_name = fields[1];
+ ent->processed = 0;
if (ent->ce_type == CVS_ENT_FILE) {
if (*fields[2] == '-') {
diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c
index bacda35e99c..c11ccc21e28 100644
--- a/usr.bin/cvs/file.c
+++ b/usr.bin/cvs/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.116 2005/08/19 13:36:50 joris Exp $ */
+/* $OpenBSD: file.c,v 1.117 2005/09/06 15:29:33 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -837,6 +837,15 @@ cvs_file_getdir(CVSFILE *cf, int flags, int (*cb)(CVSFILE *, void *),
!strcmp(de->d_name, ".."))
continue;
+ len = cvs_path_cat(fpath, de->d_name, pbuf, sizeof(pbuf));
+ if (len >= sizeof(pbuf))
+ goto done;
+
+ if (entf != NULL)
+ ent = cvs_ent_get(entf, de->d_name);
+ else
+ ent = NULL;
+
/*
* Do some filtering on the current directory item.
*/
@@ -844,26 +853,14 @@ cvs_file_getdir(CVSFILE *cf, int flags, int (*cb)(CVSFILE *, void *),
continue;
if (!(flags & CF_RECURSE) && (de->d_type == DT_DIR)) {
- if (entf != NULL)
- (void)cvs_ent_remove(entf, de->d_name);
+ if (ent != NULL)
+ ent->processed = 1;
continue;
}
if ((de->d_type != DT_DIR) && (flags & CF_NOFILES))
continue;
- /*
- * Obtain info about the item.
- */
- len = cvs_path_cat(fpath, de->d_name, pbuf, sizeof(pbuf));
- if (len >= sizeof(pbuf))
- goto done;
-
- if (entf != NULL)
- ent = cvs_ent_get(entf, de->d_name);
- else
- ent = NULL;
-
cfp = cvs_file_lget(pbuf, flags, cf, entf, ent);
if (cfp == NULL) {
cvs_log(LP_ERR, "failed to get '%s'", pbuf);
@@ -892,11 +889,10 @@ cvs_file_getdir(CVSFILE *cf, int flags, int (*cb)(CVSFILE *, void *),
}
/*
- * Remove it from the Entries list to make sure it won't
- * be picked up again when we look at the Entries.
+ * Mark the entry as processed.
*/
- if (entf != NULL)
- (void)cvs_ent_remove(entf, de->d_name);
+ if (ent != NULL)
+ ent->processed = 1;
/*
* If we don't want to keep it, free it
@@ -915,6 +911,8 @@ cvs_file_getdir(CVSFILE *cf, int flags, int (*cb)(CVSFILE *, void *),
* (Follows the same procedure as above ... can we merge them?)
*/
while ((entf != NULL) && ((ent = cvs_ent_next(entf)) != NULL)) {
+ if (ent->processed == 1)
+ continue;
if (!(flags & CF_RECURSE) && (ent->ce_type == CVS_ENT_DIR))
continue;
if ((flags & CF_NOFILES) && (ent->ce_type != CVS_ENT_DIR))