diff options
author | peter <peter@FreeBSD.org> | 1996-08-20 23:46:10 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-08-20 23:46:10 +0000 |
commit | 8982e501c77217c860f79bba431f46a62b607a21 (patch) | |
tree | 70187fdf5be4cbefd0baf46bddac7e5e32c13c24 /contrib/cvs/src/find_names.c | |
parent | 01ee40fd6a76f6ff7ef247fc1b2cf6e337f216c5 (diff) | |
download | FreeBSD-src-8982e501c77217c860f79bba431f46a62b607a21.zip FreeBSD-src-8982e501c77217c860f79bba431f46a62b607a21.tar.gz |
Import of slightly trimmed cvs-1.8 distribution. Generated files
and non-unix code has been left out.
Diffstat (limited to 'contrib/cvs/src/find_names.c')
-rw-r--r-- | contrib/cvs/src/find_names.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/contrib/cvs/src/find_names.c b/contrib/cvs/src/find_names.c new file mode 100644 index 0000000..4885437 --- /dev/null +++ b/contrib/cvs/src/find_names.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 1992, Brian Berliner and Jeff Polk + * Copyright (c) 1989-1992, Brian Berliner + * + * You may distribute under the terms of the GNU General Public License as + * specified in the README file that comes with the CVS 1.4 kit. + * + * Find Names + * + * Finds all the pertinent file names, both from the administration and from the + * repository + * + * Find Dirs + * + * Finds all pertinent sub-directories of the checked out instantiation and the + * repository (and optionally the attic) + */ + +#include "cvs.h" + +static int find_dirs PROTO((char *dir, List * list, int checkadm)); +static int find_rcs PROTO((char *dir, List * list)); + +static List *filelist; + +/* + * add the key from entry on entries list to the files list + */ +static int add_entries_proc PROTO((Node *, void *)); +static int +add_entries_proc (node, closure) + Node *node; + void *closure; +{ + Node *fnode; + + fnode = getnode (); + fnode->type = FILES; + fnode->key = xstrdup (node->key); + if (addnode (filelist, fnode) != 0) + freenode (fnode); + return (0); +} + +/* + * compare two files list node (for sort) + */ +static int fsortcmp PROTO ((const Node *, const Node *)); +static int +fsortcmp (p, q) + const Node *p; + const Node *q; +{ + return (strcmp (p->key, q->key)); +} + +List * +Find_Names (repository, which, aflag, optentries) + char *repository; + int which; + int aflag; + List **optentries; +{ + List *entries; + List *files; + char dir[PATH_MAX]; + + /* make a list for the files */ + files = filelist = getlist (); + + /* look at entries (if necessary) */ + if (which & W_LOCAL) + { + /* parse the entries file (if it exists) */ + entries = Entries_Open (aflag); + if (entries != NULL) + { + /* walk the entries file adding elements to the files list */ + (void) walklist (entries, add_entries_proc, NULL); + + /* if our caller wanted the entries list, return it; else free it */ + if (optentries != NULL) + *optentries = entries; + else + Entries_Close (entries); + } + } + + if ((which & W_REPOS) && repository && !isreadable (CVSADM_ENTSTAT)) + { + /* search the repository */ + if (find_rcs (repository, files) != 0) + error (1, errno, "cannot open directory %s", repository); + + /* search the attic too */ + if (which & W_ATTIC) + { + (void) sprintf (dir, "%s/%s", repository, CVSATTIC); + (void) find_rcs (dir, files); + } + } + + /* sort the list into alphabetical order and return it */ + sortlist (files, fsortcmp); + return (files); +} + +/* + * create a list of directories to traverse from the current directory + */ +List * +Find_Directories (repository, which) + char *repository; + int which; +{ + List *dirlist; + + /* make a list for the directories */ + dirlist = getlist (); + + /* find the local ones */ + if (which & W_LOCAL) + { + /* look only for CVS controlled sub-directories */ + if (find_dirs (".", dirlist, 1) != 0) + error (1, errno, "cannot open current directory"); + } + + /* look for sub-dirs in the repository */ + if ((which & W_REPOS) && repository) + { + /* search the repository */ + if (find_dirs (repository, dirlist, 0) != 0) + error (1, errno, "cannot open directory %s", repository); + +#ifdef ATTIC_DIR_SUPPORT /* XXX - FIXME */ + /* search the attic too */ + if (which & W_ATTIC) + { + char dir[PATH_MAX]; + + (void) sprintf (dir, "%s/%s", repository, CVSATTIC); + (void) find_dirs (dir, dirlist, 0); + } +#endif + } + + /* sort the list into alphabetical order and return it */ + sortlist (dirlist, fsortcmp); + return (dirlist); +} + +/* + * Finds all the ,v files in the argument directory, and adds them to the + * files list. Returns 0 for success and non-zero if the argument directory + * cannot be opened. + */ +static int +find_rcs (dir, list) + char *dir; + List *list; +{ + Node *p; + struct dirent *dp; + DIR *dirp; + + /* set up to read the dir */ + if ((dirp = opendir (dir)) == NULL) + return (1); + + /* read the dir, grabbing the ,v files */ + while ((dp = readdir (dirp)) != NULL) + { + if (fnmatch (RCSPAT, dp->d_name, 0) == 0) + { + char *comma; + + comma = strrchr (dp->d_name, ','); /* strip the ,v */ + *comma = '\0'; + p = getnode (); + p->type = FILES; + p->key = xstrdup (dp->d_name); + if (addnode (list, p) != 0) + freenode (p); + } + } + (void) closedir (dirp); + return (0); +} + +/* + * Finds all the subdirectories of the argument dir and adds them to the + * specified list. Sub-directories without a CVS administration directory + * are optionally ignored Returns 0 for success or 1 on error. + */ +static int +find_dirs (dir, list, checkadm) + char *dir; + List *list; + int checkadm; +{ + Node *p; + char tmp[PATH_MAX]; + struct dirent *dp; + DIR *dirp; + + /* set up to read the dir */ + if ((dirp = opendir (dir)) == NULL) + return (1); + + /* read the dir, grabbing sub-dirs */ + while ((dp = readdir (dirp)) != NULL) + { + if (strcmp (dp->d_name, ".") == 0 || + strcmp (dp->d_name, "..") == 0 || + strcmp (dp->d_name, CVSATTIC) == 0 || + strcmp (dp->d_name, CVSLCK) == 0 || + strcmp (dp->d_name, CVSREP) == 0) + continue; + +#ifdef DT_DIR + if (dp->d_type != DT_DIR) + { + if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK) + continue; +#endif + /* don't bother stating ,v files */ + if (fnmatch (RCSPAT, dp->d_name, 0) == 0) + continue; + + sprintf (tmp, "%s/%s", dir, dp->d_name); + if (!isdir (tmp)) + continue; + +#ifdef DT_DIR + } +#endif + + /* check for administration directories (if needed) */ + if (checkadm) + { + /* blow off symbolic links to dirs in local dir */ +#ifdef DT_DIR + if (dp->d_type != DT_DIR) + { + /* we're either unknown or a symlink at this point */ + if (dp->d_type == DT_LNK) + continue; +#endif + if (islink (tmp)) + continue; +#ifdef DT_DIR + } +#endif + + /* check for new style */ + (void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM); + if (!isdir (tmp)) + continue; + } + + /* put it in the list */ + p = getnode (); + p->type = DIRS; + p->key = xstrdup (dp->d_name); + if (addnode (list, p) != 0) + freenode (p); + } + (void) closedir (dirp); + return (0); +} |