386BSD 0.1 development
[unix-history] / usr / othersrc / public / cvs-1.3 / src / find_names.c
CommitLineData
0758ccff
WJ
1/*
2 * Copyright (c) 1992, Brian Berliner and Jeff Polk
3 * Copyright (c) 1989-1992, Brian Berliner
4 *
5 * You may distribute under the terms of the GNU General Public License as
6 * specified in the README file that comes with the CVS 1.3 kit.
7 *
8 * Find Names
9 *
10 * Finds all the pertinent file names, both from the administration and from the
11 * repository
12 *
13 * Find Dirs
14 *
15 * Finds all pertinent sub-directories of the checked out instantiation and the
16 * repository (and optionally the attic)
17 */
18
19#include "cvs.h"
20
21#ifndef lint
22static char rcsid[] = "@(#)find_names.c 1.38 92/04/10";
23#endif
24
25#if __STDC__
26static int find_dirs (char *dir, List * list, int checkadm);
27static int find_rcs (char *dir, List * list);
28#else
29static int find_rcs ();
30static int find_dirs ();
31#endif /* __STDC__ */
32
33static List *filelist;
34
35/*
36 * add the key from entry on entries list to the files list
37 */
38static int
39add_entries_proc (node)
40 Node *node;
41{
42 Node *fnode;
43
44 fnode = getnode ();
45 fnode->type = FILES;
46 fnode->key = xstrdup (node->key);
47 if (addnode (filelist, fnode) != 0)
48 freenode (fnode);
49 return (0);
50}
51
52/*
53 * compare two files list node (for sort)
54 */
55static int
56fsortcmp (p, q)
57 Node *p, *q;
58{
59 return (strcmp (p->key, q->key));
60}
61
62List *
63Find_Names (repository, which, aflag, optentries)
64 char *repository;
65 int which;
66 int aflag;
67 List **optentries;
68{
69 List *entries;
70 List *files;
71 char dir[PATH_MAX];
72
73 /* make a list for the files */
74 files = filelist = getlist ();
75
76 /* look at entries (if necessary) */
77 if (which & W_LOCAL)
78 {
79 /* parse the entries file (if it exists) */
80 entries = ParseEntries (aflag);
81
82 if (entries != NULL)
83 {
84 /* walk the entries file adding elements to the files list */
85 (void) walklist (entries, add_entries_proc);
86
87 /* if our caller wanted the entries list, return it; else free it */
88 if (optentries != NULL)
89 *optentries = entries;
90 else
91 dellist (&entries);
92 }
93 }
94
95 if ((which & W_REPOS) && repository && !isreadable (CVSADM_ENTSTAT))
96 {
97 /* search the repository */
98 if (find_rcs (repository, files) != 0)
99 error (1, errno, "cannot open directory %s", repository);
100
101 /* search the attic too */
102 if (which & W_ATTIC)
103 {
104 (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
105 (void) find_rcs (dir, files);
106 }
107 }
108
109 /* sort the list into alphabetical order and return it */
110 sortlist (files, fsortcmp);
111 return (files);
112}
113
114/*
115 * create a list of directories to traverse from the current directory
116 */
117List *
118Find_Dirs (repository, which)
119 char *repository;
120 int which;
121{
122 List *dirlist;
123
124 /* make a list for the directories */
125 dirlist = getlist ();
126
127 /* find the local ones */
128 if (which & W_LOCAL)
129 {
130 /* look only for CVS controlled sub-directories */
131 if (find_dirs (".", dirlist, 1) != 0)
132 error (1, errno, "cannot open current directory");
133 }
134
135 /* look for sub-dirs in the repository */
136 if ((which & W_REPOS) && repository)
137 {
138 /* search the repository */
139 if (find_dirs (repository, dirlist, 0) != 0)
140 error (1, errno, "cannot open directory %s", repository);
141
142#ifdef ATTIC_DIR_SUPPORT /* XXX - FIXME */
143 /* search the attic too */
144 if (which & W_ATTIC)
145 {
146 char dir[PATH_MAX];
147
148 (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
149 (void) find_dirs (dir, dirlist, 0);
150 }
151#endif
152 }
153
154 /* sort the list into alphabetical order and return it */
155 sortlist (dirlist, fsortcmp);
156 return (dirlist);
157}
158
159/*
160 * Finds all the ,v files in the argument directory, and adds them to the
161 * files list. Returns 0 for success and non-zero if the argument directory
162 * cannot be opened.
163 */
164static int
165find_rcs (dir, list)
166 char *dir;
167 List *list;
168{
169 Node *p;
170 CONST char *regex_err;
171 char line[50];
172 struct direct *dp;
173 DIR *dirp;
174
175 /* set up to read the dir */
176 if ((dirp = opendir (dir)) == NULL)
177 return (1);
178
179 /* set up a regular expression to find the ,v files */
180 (void) sprintf (line, ".*%s$", RCSEXT);
181 if ((regex_err = re_comp (line)) != NULL)
182 error (1, 0, "%s", regex_err);
183
184 /* read the dir, grabbing the ,v files */
185 while ((dp = readdir (dirp)) != NULL)
186 {
187 if (re_exec (dp->d_name))
188 {
189 char *comma;
190
191 comma = rindex (dp->d_name, ','); /* strip the ,v */
192 *comma = '\0';
193 p = getnode ();
194 p->type = FILES;
195 p->key = xstrdup (dp->d_name);
196 if (addnode (list, p) != 0)
197 freenode (p);
198 }
199 }
200 (void) closedir (dirp);
201 return (0);
202}
203
204/*
205 * Finds all the subdirectories of the argument dir and adds them to the
206 * specified list. Sub-directories without a CVS administration directory
207 * are optionally ignored Returns 0 for success or 1 on error.
208 */
209static int
210find_dirs (dir, list, checkadm)
211 char *dir;
212 List *list;
213 int checkadm;
214{
215 Node *p;
216 CONST char *regex_err;
217 char tmp[PATH_MAX];
218 char admdir[PATH_MAX];
219 struct direct *dp;
220 DIR *dirp;
221
222 /* build a regex to blow off ,v files */
223 (void) sprintf (tmp, ".*%s$", RCSEXT);
224 if ((regex_err = re_comp (tmp)) != NULL)
225 error (1, 0, "%s", regex_err);
226
227 /* set up to read the dir */
228 if ((dirp = opendir (dir)) == NULL)
229 return (1);
230
231 /* read the dir, grabbing sub-dirs */
232 while ((dp = readdir (dirp)) != NULL)
233 {
234 if (strcmp (dp->d_name, ".") == 0 ||
235 strcmp (dp->d_name, "..") == 0 ||
236 strcmp (dp->d_name, CVSATTIC) == 0 ||
237 strcmp (dp->d_name, CVSLCK) == 0 ||
238 re_exec (dp->d_name)) /* don't bother stating ,v files */
239 continue;
240
241 (void) sprintf (tmp, "%s/%s", dir, dp->d_name);
242 if (isdir (tmp))
243 {
244 /* check for administration directories (if needed) */
245 if (checkadm)
246 {
247 /* blow off symbolic links to dirs in local dir */
248 if (islink (tmp))
249 continue;
250
251 /* check for new style */
252 (void) sprintf (admdir, "%s/%s", tmp, CVSADM);
253 if (!isdir (admdir))
254 {
255 /* and old style */
256 (void) sprintf (admdir, "%s/%s", tmp, OCVSADM);
257 if (!isdir (admdir))
258 continue;
259 }
260 }
261
262 /* put it in the list */
263 p = getnode ();
264 p->type = DIRS;
265 p->key = xstrdup (dp->d_name);
266 if (addnode (list, p) != 0)
267 freenode (p);
268 }
269 }
270 (void) closedir (dirp);
271 return (0);
272}