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

Revision 2175, 13.8 KB checked in by jik, 35 years ago (diff)
changes to fit new error-handling and regular expression handling
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.11 1989-10-23 13:33:06 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 <errno.h>
24#include <com_err.h>
25#include "directories.h"
26#include "pattern.h"
27#include "util.h"
28#include "undelete.h"
29#include "shell_regexp.h"
30#include "mit-copyright.h"
31#include "delete_errs.h"
32#include "errors.h"
33
34extern char *malloc(), *realloc();
35extern int errno;
36
37extern char *whoami;
38
39
40
41/*
42 * add_arrays() takes pointers to two arrays of char **'s and their
43 * lengths, merges the two into the first by realloc'ing the first and
44 * then free's the second's memory usage.
45 */ 
46int add_arrays(array1, num1, array2, num2)
47char ***array1, ***array2;
48int *num1, *num2;
49{
50     int counter;
51     
52     *array1 = (char **) realloc((char *) *array1, (unsigned)
53                                 (sizeof(char *) * (*num1 + *num2)));
54     if (! *array1) {
55          set_error(errno);
56          error("realloc");
57          return error_code;
58     }
59     for (counter = *num1; counter < *num1 + *num2; counter++)
60          *(*array1 + counter) = *(*array2 + counter - *num1);
61     free ((char *) *array2);
62     *num1 += *num2;
63     return 0;
64}
65
66
67
68
69
70
71/*
72 * Add a string to a list of strings.
73 */
74int add_str(strs, num, str)
75char ***strs;
76int num;
77char *str;
78{
79     char **ary;
80
81     ary = *strs = (char **) realloc((char *) *strs, (unsigned)
82                                     (sizeof(char *) * (num + 1)));
83     if (! strs) {
84          set_error(errno);
85          error("realloc");
86          return error_code;
87     }
88     ary[num] = malloc((unsigned) (strlen(str) + 1));
89     if (! ary[num]) {
90          set_error(errno);
91          error("malloc");
92          return error_code;
93     }
94     (void) strcpy(ary[num], str);
95     return 0;
96}
97
98
99
100
101
102
103int find_deleted_matches(base, expression, num_found, found)
104char *base, *expression;
105int *num_found;
106char ***found;
107{
108     struct direct *dp;
109     DIR *dirp;
110     int num;
111     char **next;
112     int num_next;
113     char first[MAXNAMLEN], rest[MAXPATHLEN];
114     char new[MAXPATHLEN];
115     int retval;
116     
117#ifdef DEBUG
118     printf("Looking for %s in %s\n", expression, base);
119#endif
120     *found = (char **) malloc(0);
121     if (! *found) {
122          set_error(errno);
123          error("malloc");
124          return error_code;
125     }
126     num = 0;
127
128     dirp = opendir(base);
129     if (! dirp) {
130          set_error(errno);
131          error(base);
132          return error_code;
133     }
134
135     (void) strcpy(first, firstpart(expression, rest));
136     
137     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
138          if ((retval = reg_cmp(first, dp->d_name)) < 0) {
139               error("reg_cmp");
140               return error_code;
141          }
142          if ((retval == REGEXP_MATCH) && *rest) {
143               (void) strcpy(new, append(base, dp->d_name));
144               if (retval = find_deleted_matches(new, rest, &num_next,
145                                                 &next)) {
146                    error("find_deleted_matches");
147                    closedir(dirp);
148                    return retval;
149               }
150               if (retval = add_arrays(found, &num, &next, &num_next)) {
151                    error("add_arrays");
152                    closedir(dirp);
153                    return retval;
154               }
155          }
156          else if (is_deleted(dp->d_name)) {
157               if ((retval = reg_cmp(first, &dp->d_name[2])) < 0) {
158                    error("reg_cmp");
159                    closedir(dirp);
160                    return retval;
161               }
162               if (retval == REGEXP_MATCH) {
163                    if (*rest) {
164                         (void) strcpy(new, append(base, dp->d_name));
165                         if (retval = find_deleted_matches(new, rest,
166                                                           &num_next, &next)) {
167                              error("find_deleted_matches");
168                              closedir(dirp);
169                              return retval;
170                         }
171                         if (retval = add_arrays(found, &num, &next,
172                                                 &num_next)) {
173                              error("add_arrays");
174                              closedir(dirp);
175                              return retval;
176                         }
177                    }
178                    else {
179                         char *tmp;
180
181                         tmp = append(base, dp->d_name);
182                         if (! *tmp) {
183                              error("append");
184                              return error_code;
185                         }
186                         if (retval = add_str(found, num, tmp)) {
187                              error("add_str");
188                              closedir(dirp);
189                              return retval;
190                         }
191                         num++;
192                    }
193               }
194          }
195     }
196     closedir(dirp);
197     *num_found = num;
198     return 0;
199}
200
201
202
203
204
205int find_matches(base, expression, num_found, found)
206char *base, *expression;
207int *num_found;
208char ***found;
209{
210     struct direct *dp;
211     DIR *dirp;
212     int num;
213     char **next;
214     int num_next;
215     char first[MAXNAMLEN], rest[MAXPATHLEN];
216     char new[MAXPATHLEN];
217     int retval;
218     
219#ifdef DEBUG
220     printf("Looking for %s in %s\n", expression, base);
221#endif
222     *found = (char **) malloc(0);
223     num = 0;
224
225     dirp = opendir(base);
226     if (! dirp) {
227          set_error(errno);
228          error(base);
229          return error_code;
230     }
231
232     (void) strcpy(first, firstpart(expression, rest));
233     
234     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
235          retval = reg_cmp(first, dp->d_name);
236          if (retval < 0) {
237               error("reg_cmp");
238               closedir(dirp);
239               return retval;
240          }
241          if (retval == REGEXP_MATCH) {
242               if (*rest) {
243                    char *tmp;
244
245                    tmp = append(base, dp->d_name);
246                    if (! *tmp) {
247                         error("append");
248                         return error_code;
249                    }
250                    (void) strcpy(new, tmp);
251                    if (retval = find_matches(new, rest, &num_next, &next)) {
252                         error("find_matches");
253                         closedir(dirp);
254                         return retval;
255                    }
256                    if (retval = add_arrays(found, &num, &next, &num_next)) {
257                         error("add_arrays");
258                         closedir(dirp);
259                         return retval;
260                    }
261               }
262               else {
263                    char *tmp;
264
265                    tmp = append(base, dp->d_name);
266                    if (! *tmp) {
267                         error("append");
268                         return error_code;
269                    }
270                   
271                    if (retval = add_str(found, num, tmp)) {
272                         error("add_str");
273                         closedir(dirp);
274                         return retval;
275                    }
276                    num++;
277               }
278          }
279          else if (is_deleted(dp->d_name)) {
280               if ((retval = reg_cmp(first, &dp->d_name[2])) < 0) {
281                    error("reg_cmp");
282                    closedir(dirp);
283                    return retval;
284               }
285               if (retval == REGEXP_MATCH) {
286                    if (*rest) {
287                         (void) strcpy(new, append(base, dp->d_name));
288                         if (! *new) {
289                              error("append");
290                              return error_code;
291                         }
292                         if (retval = find_matches(new, rest, &num_next,
293                                                   &next)) {
294                              error("find_matches");
295                              closedir(dirp);
296                              return retval;
297                         }
298                         if (retval = add_arrays(found, &num, &next,
299                                                 &num_next)) {
300                              error("add_arrays");
301                              closedir(dirp);
302                              return retval;
303                         }
304                    }
305                    else {
306                         char *tmp;
307
308                         tmp = append(base, dp->d_name);
309                         if (! *tmp) {
310                              error("append");
311                              return error_code;
312                         }
313                         if (retval = add_str(found, num, tmp)) {
314                              error("add_str");
315                              closedir(dirp);
316                              return 0;
317                         }
318                         num++;
319                    }
320               }
321          }
322     }
323     closedir(dirp);
324     *num_found = num;
325
326     return 0;
327}
328
329
330
331
332
333
334
335int find_recurses(base, num_found, found)
336char *base;
337int *num_found;
338char ***found;
339{
340     DIR *dirp;
341     struct direct *dp;
342     char newname[MAXPATHLEN];
343     char **new_found;
344     int found_num, new_found_num;
345     struct stat stat_buf;
346     int retval;
347     
348#ifdef DEBUG
349     printf("Looking for subs of %s\n", base);
350#endif
351     *found = (char **) malloc(0);
352     *num_found = found_num = 0;
353     
354     dirp = opendir(base);
355     if (! dirp) {
356          set_error(errno);
357          error(base);
358          return error_code;
359     }
360
361     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
362          if (is_dotfile(dp->d_name))
363               continue;
364          (void) strcpy(newname, append(base, dp->d_name));
365          if (! *newname) {
366               error("append");
367               return error_code;
368          }
369          if (retval = add_str(found, found_num, newname)) {
370               error("add_str");
371               closedir(dirp);
372               return retval;
373          }
374          found_num++;
375          if (lstat(newname, &stat_buf)) {
376               set_error(errno);
377               error(newname);
378               continue;
379          }
380          if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
381               if (retval = find_recurses(newname, &new_found_num,
382                                          &new_found)) {
383                    error(newname);
384                    closedir(dirp);
385                    return retval;
386               }
387               if (retval = add_arrays(found, &found_num, &new_found,
388                                       &new_found_num)) {
389                    error("add_arrays");
390                    closedir(dirp);
391                    return retval;
392               }
393          }
394     }
395     closedir(dirp);
396     *num_found = found_num;
397     return 0;
398}
399
400
401
402
403
404
405int find_deleted_recurses(base, num_found, found)
406char *base;
407int *num_found;
408char ***found;
409{
410     DIR *dirp;
411     struct direct *dp;
412     char newname[MAXPATHLEN];
413     char **new_found;
414     int found_num, new_found_num;
415     struct stat stat_buf;
416     int retval;
417     
418#ifdef DEBUG
419     printf("Looking for deleted recurses of %s\n", base);
420#endif
421     *found = (char **) malloc(0);
422     *num_found = found_num = 0;
423     
424     dirp = opendir(base);
425     if (! dirp) {
426          set_error(errno);
427          error(base);
428          return error_code;
429     }
430
431     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
432          if (is_dotfile(dp->d_name))
433               continue;
434
435          (void) strcpy(newname, append(base, dp->d_name));
436
437          if (! *newname) {
438               error("append");
439               return error_code;
440          }
441         
442          if (is_deleted(dp->d_name)) {
443               if (retval = add_str(found, found_num, newname)) {
444                    error("add_str");
445                    closedir(dirp);
446                    return retval;
447               }
448               found_num++;
449          }
450          if (lstat(newname, &stat_buf)) {
451               set_error(errno);
452               error(newname);
453               continue;
454          }
455          if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
456               if (retval = find_deleted_recurses(newname, &new_found_num,
457                                                  &new_found)) {
458                    error(newname);
459                    closedir(dirp);
460                    return retval;
461               }
462               if (retval = add_arrays(found, &found_num, &new_found,
463                                       &new_found_num)) {
464                    error("add_arrays");
465                    closedir(dirp);
466                    return retval;
467               }
468          }
469     }
470     closedir(dirp);
471     *num_found = found_num;
472     return 0;
473}
474
475
476
477
478
479
480int find_contents(base, num_found, found)
481char *base;
482int *num_found;
483char ***found;
484{
485     DIR *dirp;
486     struct direct *dp;
487     int num;
488     int retval;
489     char *tmp;
490     
491#ifdef DEBUG
492     printf("Looking for contents of %s\n", base);
493#endif
494     *found = (char **) malloc(0);
495     *num_found = num = 0;
496   
497     dirp = opendir(base);
498     if (! dirp) {
499          set_error(errno);
500          error(base);
501          return error_code;
502     }
503     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
504          if (is_dotfile(dp->d_name))
505               continue;
506
507          tmp = append(base, dp->d_name);
508          if (! *tmp) {
509               error("append");
510               return error_code;
511          }
512          if (retval = add_str(found, num, tmp)) {
513               error("add_str");
514               closedir(dirp);
515               return retval;
516          }
517          num += 1;
518     }
519     closedir(dirp);
520     *num_found = num;
521     return 0;
522}
523
524
525     
526int find_deleted_contents(base, num_found, found)
527char *base;
528int *num_found;
529char ***found;
530{
531     DIR *dirp;
532     struct direct *dp;
533     int num;
534     int retval;
535     
536#ifdef DEBUG
537     printf("Looking for deleted contents of %s\n", base);
538#endif
539     *found = (char **) malloc(0);
540     *num_found = num = 0;
541   
542     dirp = opendir(base);
543     if (! dirp) {
544          set_error(errno);
545          error(base);
546          return error_code;
547     }
548
549     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
550          if (is_dotfile(dp->d_name))
551               continue;
552          if (is_deleted(dp->d_name)) {
553               char *tmp;
554
555               tmp = append(base, dp->d_name);
556               if (! *tmp) {
557                    error("append");
558                    return error_code;
559               }
560               if (retval = add_str(found, num, tmp)) {
561                    error("add_str");
562                    closedir(dirp);
563                    return retval;
564               }
565               num += 1;
566          }
567     }
568     closedir(dirp);
569     *num_found = num;
570     return 0;
571}
572
573
574
575
576int find_deleted_contents_recurs(base, num_found, found)
577char *base;
578int *num_found;
579char ***found;
580{
581     DIR *dirp;
582     struct direct *dp;
583     int num;
584     struct stat stat_buf;
585     char newname[MAXPATHLEN];
586     char **new_found;
587     int new_found_num;
588     int retval;
589     
590#ifdef DEBUG
591     printf("Looking for recursive deleted contents of %s\n", base);
592#endif
593     *found = (char **) malloc(0);
594     *num_found = num = 0;
595   
596     dirp = opendir(base);
597     if (! dirp) {
598          set_error(errno);
599          error(base);
600          return error_code;
601     }
602     
603     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
604          if (is_dotfile(dp->d_name))
605               continue;
606          if (is_deleted(dp->d_name)) {
607               (void) strcpy(newname, append(base, dp->d_name));
608               if (! *newname) {
609                    error("append");
610                    return error_code;
611               }
612               if (retval = add_str(found, num, newname)) {
613                    error("add_str");
614                    closedir(dirp);
615                    return retval;
616               }
617               num += 1;
618               if (lstat(newname, &stat_buf)) {
619                    set_error(errno);
620                    error(newname);
621                    continue;
622               }
623               if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
624                    if (retval = find_recurses(newname, &new_found_num,
625                                               &new_found)) {
626                         error(newname);
627                         closedir(dirp);
628                         return retval;
629                    }
630                    if (retval = add_arrays(found, &num, &new_found,
631                                            &new_found_num)) {
632                         error("add_arrays");
633                         closedir(dirp);
634                         return retval;
635                    }
636               }
637          }
638     }
639     closedir(dirp);
640     *num_found = num;
641     return 0;
642}
643     
644
645
646/*
647 * returns true if the filename has no globbing wildcards in it.  That
648 * means no non-quoted question marks, asterisks, or open square
649 * braces.  Assumes a null-terminated string, and a valid globbing
650 * expression.
651 */
652int no_wildcards(name)
653char *name;
654{
655     do {
656          switch (*name) {
657          case '\\':
658               name++;
659               break;
660          case '?':
661               return(0);
662          case '*':
663               return(0);
664          case '[':
665               return(0);
666          }
667     } while (*++name);
668     return(1);
669}
Note: See TracBrowser for help on using the repository browser.