summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-07-30 11:50:34 +0000
committerJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-07-30 11:50:34 +0000
commit4ba93e9679394e7f05be4cc7cfa500e8ab941e75 (patch)
tree6df5f12782a17cfbe2675f529636c5903b7d94e7
parent4f267f6f8412ab27d13cd27ffa73e64c22be2c9c (diff)
Add cvs_file_find() to find a particular file from its path within a
hierarchy
-rw-r--r--usr.bin/cvs/file.c65
-rw-r--r--usr.bin/cvs/file.h11
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 */