diff options
author | Joris Vink <joris@cvs.openbsd.org> | 2005-09-06 15:29:34 +0000 |
---|---|---|
committer | Joris Vink <joris@cvs.openbsd.org> | 2005-09-06 15:29:34 +0000 |
commit | 71442aed77bb01f56d28f6cbc9fdeb82acfe9212 (patch) | |
tree | 35b9ff888169a577e220f0a931adb7cf93123088 /usr.bin | |
parent | 68ccf787a8ec4f3499e320c5c4fdb8b8bb01406e (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.h | 9 | ||||
-rw-r--r-- | usr.bin/cvs/entries.c | 3 | ||||
-rw-r--r-- | usr.bin/cvs/file.c | 36 |
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)) |