diff options
author | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-07-30 11:50:34 +0000 |
---|---|---|
committer | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-07-30 11:50:34 +0000 |
commit | 4ba93e9679394e7f05be4cc7cfa500e8ab941e75 (patch) | |
tree | 6df5f12782a17cfbe2675f529636c5903b7d94e7 | |
parent | 4f267f6f8412ab27d13cd27ffa73e64c22be2c9c (diff) |
Add cvs_file_find() to find a particular file from its path within a
hierarchy
-rw-r--r-- | usr.bin/cvs/file.c | 65 | ||||
-rw-r--r-- | usr.bin/cvs/file.h | 11 |
2 files changed, 69 insertions, 7 deletions
diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c index 46229ca33a4..e9df757714a 100644 --- a/usr.bin/cvs/file.c +++ b/usr.bin/cvs/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.12 2004/07/29 17:51:06 jfb Exp $ */ +/* $OpenBSD: file.c,v 1.13 2004/07/30 11:50:33 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -400,6 +400,59 @@ cvs_file_getspec(char **fspec, int fsn, int flags) /* + * cvs_file_find() + * + * Find the pointer to a CVS file entry within the file hierarchy <hier>. + * The file's pathname <path> must be relative to the base of <hier>. + * Returns the entry on success, or NULL on failure. + */ + +CVSFILE* +cvs_file_find(CVSFILE *hier, const char *path) +{ + char *pp, *sp, pbuf[MAXPATHLEN]; + CVSFILE *sf, *cf; + + strlcpy(pbuf, path, sizeof(pbuf)); + + cf = hier; + pp = pbuf; + do { + sp = strchr(pp, '/'); + if (sp != NULL) + *sp = '\0'; + + /* special case */ + if (*pp == '.') { + if ((*(pp + 1) == '.') && (*(pp + 2) == '\0')) { + /* request to go back to parent */ + if (cf->cf_parent == NULL) { + cvs_log(LP_NOTICE, + "path %s goes back too far", path); + return (NULL); + } + cf = cf->cf_parent; + continue; + } + else if (*(pp + 1) == '\0') + continue; + } + + TAILQ_FOREACH(sf, &(cf->cf_ddat->cd_files), cf_list) + if (strcmp(pp, sf->cf_name) == 0) + break; + if (sf == NULL) + return (NULL); + + cf = sf; + pp = sp; + } while (sp != NULL); + + return (NULL); +} + + +/* * cvs_file_getdir() * * Get a cvs directory structure for the directory whose path is <dir>. @@ -408,9 +461,9 @@ cvs_file_getspec(char **fspec, int fsn, int flags) static int cvs_file_getdir(struct cvs_file *cf, int flags) { - int nf, ret, fd; + int ret, fd; long base; - void *dp, *ep, *tmp; + void *dp, *ep; char fbuf[2048], pbuf[MAXPATHLEN]; struct dirent *ent; struct cvs_file *cfp; @@ -525,11 +578,13 @@ cvs_file_examine(CVSFILE *cf, int (*exam)(CVSFILE *, void *), void *arg) TAILQ_FOREACH(fp, &(cf->cf_ddat->cd_files), cf_list) { ret = cvs_file_examine(fp, exam, arg); if (ret == -1) - return (-1); + break; } } else - return (*exam)(cf, arg); + ret = (*exam)(cf, arg); + + return (ret); } diff --git a/usr.bin/cvs/file.h b/usr.bin/cvs/file.h index aa587a1d06f..0dd8cc52144 100644 --- a/usr.bin/cvs/file.h +++ b/usr.bin/cvs/file.h @@ -1,4 +1,4 @@ -/* $OpenBSD: file.h,v 1.1 2004/07/30 01:49:23 jfb Exp $ */ +/* $OpenBSD: file.h,v 1.2 2004/07/30 11:50:33 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -193,14 +193,21 @@ struct cvs_dir { struct cvs_flist cd_files; }; + +#define CVS_DIR_ROOT(f) (((f)->cf_type == DTDIR) ? \ + (f)->cf_ddat->cd_root : (((f)->cf_parent == NULL) ? \ + NULL : (f)->cf_parent->cf_ddat->cd_root)) + + int cvs_file_init (void); int cvs_file_ignore (const char *); int cvs_file_chkign (const char *); CVSFILE* cvs_file_create (const char *, u_int, mode_t); CVSFILE* cvs_file_get (const char *, int); CVSFILE* cvs_file_getspec (char **, int, int); -void cvs_file_free (struct cvs_file *); +CVSFILE* cvs_file_find (CVSFILE *, const char *); int cvs_file_examine (CVSFILE *, int (*)(CVSFILE *, void *), void *); +void cvs_file_free (struct cvs_file *); #endif /* FILE_H */ |