source: trunk/athena/bin/delete/pattern.c @ 1852

Revision 1852, 11.9 KB checked in by jik, 35 years ago (diff)
Before, I was doing to readdir's at the beginning of every directory because I was assuming that dot files were always at the beginning. I'm not sure that's safe, so now I'm checking every file to make sure it's not a dot file.
Line 
1/*
2 * $Source: /afs/dev.mit.edu/source/repository/athena/bin/delete/pattern.c,v $
3 * $Author: jik $
4 *
5 * This program is part of a package including delete, undelete,
6 * lsdel, expunge and purge.  The software suite is meant as a
7 * replacement for rm which allows for file recovery.
8 *
9 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file "mit-copyright.h."
11 */
12
13#if (!defined(lint) && !defined(SABER))
14     static char rcsid_pattern_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/delete/pattern.c,v 1.9 1989-05-04 14:21:39 jik Exp $";
15#endif
16
17#include <stdio.h>
18#include <sys/types.h>
19#include <sys/dir.h>
20#include <sys/param.h>
21#include <strings.h>
22#include <sys/stat.h>
23#include "directories.h"
24#include "pattern.h"
25#include "util.h"
26#include "undelete.h"
27#include "mit-copyright.h"
28
29static char *add_char();
30
31extern char *malloc(), *realloc();
32
33extern char *whoami, *error_buf;
34
35/*
36 * parse_pattern returns an area of memory allocated by malloc when it
37 * is successful.  Therefore, other procedures calling parse_pattern
38 * should use free() to free the region of memory when they are done
39 * with it.
40 */
41char *parse_pattern(file_pattern)
42char *file_pattern;
43{
44     char *re_pattern, *cur_ptr, *re_ptr;
45     int guess_length;
46     
47     guess_length = strlen(file_pattern) + 5;
48     re_ptr = re_pattern = malloc(guess_length);
49     if (! re_ptr) {
50          perror(sprintf(error_buf, "%s: parse_pattern", whoami));
51          exit(1);
52     }
53     
54     for (cur_ptr = file_pattern, re_ptr = re_pattern; *cur_ptr != NULL;
55          cur_ptr++) {
56          if (*cur_ptr == '\\') {
57               if (! cur_ptr[1]) {
58                    fprintf(stderr,
59                            "%s: parse_pattern: incomplete expression\n",
60                            whoami);
61                    return((char *) NULL);
62               }
63               if (! add_char(&re_pattern, &re_ptr, &guess_length, '\\'))
64                    return ((char *) NULL);
65               cur_ptr++;
66               if (! add_char(&re_pattern, &re_ptr, &guess_length, *cur_ptr))
67                    return ((char *) NULL);
68               continue;
69          }
70          else if (*cur_ptr == '*') {
71               if (! add_char(&re_pattern, &re_ptr, &guess_length, '.'))
72                    return ((char *) NULL);
73               if (! add_char(&re_pattern, &re_ptr, &guess_length, '*'))
74                    return ((char *) NULL);
75               continue;
76          }
77          else if (*cur_ptr == '?') {
78               if (! add_char(&re_pattern, &re_ptr, &guess_length, '.'))
79                    return ((char *) NULL);
80               continue;
81          }
82          else if (*cur_ptr == '.') {
83               if (! add_char(&re_pattern, &re_ptr, &guess_length, '\\'))
84                    return ((char *) NULL);
85               if (! add_char(&re_pattern, &re_ptr, &guess_length, '.'))
86                    return ((char *) NULL);
87          }
88          else {
89               if (! add_char(&re_pattern, &re_ptr, &guess_length, *cur_ptr))
90                    return ((char *) NULL);
91          }
92     }
93     if (! add_char(&re_pattern, &re_ptr, &guess_length, '\0'))
94          return ((char *) NULL);
95     return (re_pattern);
96}
97
98
99
100
101
102
103/*
104 * add_char() takes two char **, a length which is the current amount
105 * of space implemented for the string pointed to by the first *(char **),
106 * and a character to add to the string.  It reallocs extra space if
107 * necessary, adds the character, and messes with the pointers if necessary.
108 */
109static char *add_char(start, finish, length, chr)
110char **start, **finish;
111int *length;
112char chr;
113{
114     if (*finish - *start == *length) {
115          *start = realloc(*start, *length + 5);
116          if (! *start) {
117               perror(sprintf(error_buf, "%s: add_char", whoami));
118               exit(1);
119          }
120          *finish = *start + *length - 1;
121          *length += 5;
122     }
123     **finish = chr;
124     (*finish)++;
125     return(*start);
126}
127
128         
129
130
131
132
133/*
134 * add_arrays() takes pointers to two arrays of char **'s and their
135 * lengths, merges the two into the first by realloc'ing the first and
136 * then free's the second's memory usage.
137 */ 
138add_arrays(array1, num1, array2, num2)
139char ***array1, ***array2;
140int *num1, *num2;
141{
142     int counter;
143     
144     *array1 = (char **) realloc(*array1, sizeof(char *) * (*num1 + *num2));
145     if (! *array1) {
146          perror(sprintf(error_buf, "%s: add_arrays", whoami));
147          exit(1);
148     }
149     for (counter = *num1; counter < *num1 + *num2; counter++)
150          *(*array1 + counter) = *(*array2 + counter - *num1);
151     free (*array2);
152     *num1 += *num2;
153     return(0);
154}
155
156
157
158
159
160
161
162char **add_str(strs, num, str)
163char **strs;
164int num;
165char *str;
166{
167     strs = (char **) realloc(strs, sizeof(char *) * (num + 1));
168     if (! strs) {
169          perror(sprintf(error_buf, "%s: add_str", whoami));
170          exit(1);
171     }
172     strs[num] = malloc(strlen(str) + 1);
173     if (! strs[num]) {
174          perror(sprintf(error_buf, "%s: add_str", whoami));
175          exit(1);
176     }
177     strcpy(strs[num], str);
178     return(strs);
179}
180
181
182
183
184
185
186
187char **find_deleted_matches(base, expression, num_found)
188char *base, *expression;
189int *num_found;
190{
191     struct direct *dp;
192     DIR *dirp;
193     char **found;
194     int num;
195     char **next;
196     int num_next;
197     char first[MAXNAMLEN], rest[MAXPATHLEN];
198     char new[MAXPATHLEN];
199
200#ifdef DEBUG
201     printf("Looking for %s in %s\n", expression, base);
202#endif
203     found = (char **) malloc(0);
204     *num_found = num = 0;
205
206     dirp = opendir(base);
207     if (! dirp)
208          return(found);
209
210     strcpy(first, reg_firstpart(expression, rest));
211     re_comp(first);
212
213     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
214          if (is_dotfile(dp->d_name)) /* skip dot files */
215               continue;
216          if (re_exec(dp->d_name) && *rest) {
217               strcpy(new, append(base, dp->d_name));
218               next = find_deleted_matches(new, rest, &num_next);
219               add_arrays(&found, &num, &next, &num_next);
220          }
221          else if (is_deleted(dp->d_name)) if (re_exec(&dp->d_name[2])) {
222               if (*rest) {
223                    strcpy(new, append(base, dp->d_name));
224                    next = find_deleted_matches(new, rest, &num_next);
225                    add_arrays(&found, &num, &next, &num_next);
226               }
227               else {
228                    found = add_str(found, num, append(base, dp->d_name));
229                    num++;
230               }
231          }
232     }
233     closedir(dirp);
234     *num_found = num;
235     return(found);
236}
237
238
239
240
241
242char **find_matches(base, expression, num_found)
243char *base, *expression;
244int *num_found;
245{
246     struct direct *dp;
247     DIR *dirp;
248     char **found;
249     int num;
250     char **next;
251     int num_next;
252     char first[MAXNAMLEN], rest[MAXPATHLEN];
253     char new[MAXPATHLEN];
254     
255#ifdef DEBUG
256     printf("Looking for %s in %s\n", expression, base);
257#endif
258     found = (char **) malloc(0);
259     *num_found = num = 0;
260
261     dirp = opendir(base);
262     if (! dirp)
263          return(found);
264
265     strcpy(first, reg_firstpart(expression, rest));
266
267     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
268          if (is_dotfile(dp->d_name))
269               continue;
270          re_comp(first);
271          if (re_exec(dp->d_name)) {
272               if (*rest) {
273                    strcpy(new, append(base, dp->d_name));
274                    next = find_matches(new, rest, &num_next);
275                    add_arrays(&found, &num, &next, &num_next);
276               }
277               else {
278                    found = add_str(found, num, append(base, dp->d_name));
279                    num++;
280               }
281          }
282          else if (is_deleted(dp->d_name)) if (re_exec(&dp->d_name[2])) {
283               if (*rest) {
284                    strcpy(new, append(base, dp->d_name));
285                    next = find_matches(new, rest, &num_next);
286                    add_arrays(&found, &num, &next, &num_next);
287               }
288               else {
289                    found = add_str(found, num, append(base, dp->d_name));
290                    num++;
291               }
292          }
293     }
294     closedir(dirp);
295     *num_found = num;
296     return(found);
297}
298
299
300
301
302
303
304
305char **find_recurses(base, num_found)
306char *base;
307int *num_found;
308{
309     DIR *dirp;
310     struct direct *dp;
311     char newname[MAXPATHLEN];
312     char **found, **new_found;
313     int found_num, new_found_num;
314     struct stat stat_buf;
315     
316#ifdef DEBUG
317     printf("Looking for subs of %s\n", base);
318#endif
319     found = (char **) malloc(0);
320     *num_found = found_num = 0;
321     
322     dirp = opendir(base);
323     if (! dirp)
324          return(found);
325
326     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
327          if (is_dotfile(dp->d_name))
328               continue;
329          strcpy(newname, append(base, dp->d_name));
330          found = add_str(found, found_num, newname);
331          found_num++;
332          if (lstat(newname, &stat_buf))
333               continue;
334          if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
335               new_found = find_recurses(newname, &new_found_num);
336               add_arrays(&found, &found_num, &new_found, &new_found_num);
337          }
338     }
339     closedir(dirp);
340     *num_found = found_num;
341     return(found);
342}
343
344
345
346
347
348
349char **find_deleted_recurses(base, num_found)
350char *base;
351int *num_found;
352{
353     DIR *dirp;
354     struct direct *dp;
355     char newname[MAXPATHLEN];
356     char **found, **new_found;
357     int found_num, new_found_num;
358     struct stat stat_buf;
359     
360     found = (char **) malloc(0);
361     *num_found = found_num = 0;
362     
363     dirp = opendir(base);
364     if (! dirp)
365          return(found);
366
367     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
368          if (is_dotfile(dp->d_name))
369               continue;
370
371          strcpy(newname, append(base, dp->d_name));
372         
373          if (is_deleted(dp->d_name)) {
374               found = add_str(found, found_num, newname);
375               found_num++;
376          }
377          if (lstat(newname, &stat_buf)) {
378               continue;
379          }
380          if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
381               new_found = find_deleted_recurses(newname, &new_found_num);
382               add_arrays(&found, &found_num, &new_found, &new_found_num);
383          }
384     }
385     closedir(dirp);
386     *num_found = found_num;
387     return(found);
388}
389
390
391
392
393
394
395char **find_contents(base, num_found)
396char *base;
397int *num_found;
398{
399     DIR *dirp;
400     struct direct *dp;
401     char **found;
402     int num;
403
404#ifdef DEBUG
405     printf("Looking for contents of %s\n", base);
406#endif
407     found = (char **) malloc(0);
408     *num_found = num = 0;
409   
410     dirp = opendir(base);
411     if (! dirp)
412          return(found);
413
414     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
415          if (is_dotfile(dp->d_name))
416               continue;
417          found = add_str(found, num, append(base, dp->d_name));
418          num += 1;
419     }
420     closedir(dirp);
421     *num_found = num;
422     return(found);
423}
424
425
426     
427char **find_deleted_contents(base, num_found)
428char *base;
429int *num_found;
430{
431     DIR *dirp;
432     struct direct *dp;
433     char **found;
434     int num;
435
436#ifdef DEBUG
437     printf("Looking for deleted contents of %s\n", base);
438#endif
439     found = (char **) malloc(0);
440     *num_found = num = 0;
441   
442     dirp = opendir(base);
443     if (! dirp)
444          return(found);
445
446     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
447          if (is_dotfile(dp->d_name))
448               continue;
449          if (is_deleted(dp->d_name)) {
450               found = add_str(found, num, append(base, dp->d_name));
451               num += 1;
452          }
453     }
454     closedir(dirp);
455     *num_found = num;
456     return(found);
457}
458
459
460
461
462char **find_deleted_contents_recurs(base, num_found)
463char *base;
464int *num_found;
465{
466     DIR *dirp;
467     struct direct *dp;
468     char **found;
469     int num;
470     struct stat stat_buf;
471     char newname[MAXPATHLEN];
472     char **new_found;
473     int new_found_num;
474     
475#ifdef DEBUG
476     printf("Looking for recursive deleted contents of %s\n", base);
477#endif
478     found = (char **) malloc(0);
479     *num_found = num = 0;
480   
481     dirp = opendir(base);
482     if (! dirp)
483          return(found);
484
485     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
486          if (is_dotfile(dp->d_name))
487               continue;
488          if (is_deleted(dp->d_name)) {
489               strcpy(newname, append(base, dp->d_name));
490               found = add_str(found, num, newname);
491               num += 1;
492               if (lstat(newname, &stat_buf))
493                    continue;
494               if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
495                    new_found = find_recurses(newname, &new_found_num);
496                    add_arrays(&found, &num, &new_found, &new_found_num);
497               }
498          }
499     }
500     closedir(dirp);
501     *num_found = num;
502     return(found);
503}
504     
505
506
507/*
508 * returns true if the filename has no regular expression wildcards in
509 * it.  That means no non-quoted dots or asterisks.  Assumes a
510 * null-terminated string, and a valid regular expression.
511 */
512int no_wildcards(name)
513char *name;
514{
515     do {
516          switch (*name) {
517          case '\\':
518               name++;
519               break;
520          case '.':
521               return(0);
522          case '*':
523               return(0);
524          }
525     } while (*++name);
526     return(1);
527}
Note: See TracBrowser for help on using the repository browser.