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

Revision 1705, 10.9 KB checked in by jik, 35 years ago (diff)
frep
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.4 1989-01-27 02:58:15 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
28static char *add_char();
29
30extern char *malloc(), *realloc();
31
32extern char *whoami, *error_buf;
33
34/*
35 * parse_pattern returns an area of memory allocated by malloc when it
36 * is successful.  Therefore, other procedures calling parse_pattern
37 * should use free() to free the region of memory when they are done
38 * with it.
39 */
40char *parse_pattern(file_pattern)
41char *file_pattern;
42{
43     char *re_pattern, *cur_ptr, *re_ptr;
44     int guess_length;
45     
46     guess_length = strlen(file_pattern) + 5;
47     re_ptr = re_pattern = malloc(guess_length);
48     if (! re_ptr) {
49          perror(sprintf(error_buf, "%s: parse_pattern", whoami));
50          exit(1);
51     }
52     
53     for (cur_ptr = file_pattern, re_ptr = re_pattern; *cur_ptr != NULL;
54          cur_ptr++) {
55          if (*cur_ptr == '\\') {
56               if (! cur_ptr[1]) {
57                    fprintf(stderr,
58                            "%s: parse_pattern: incomplete expression\n",
59                            whoami);
60                    return((char *) NULL);
61               }
62               if (! add_char(&re_pattern, &re_ptr, &guess_length, '\\'))
63                    return ((char *) NULL);
64               cur_ptr++;
65               if (! add_char(&re_pattern, &re_ptr, &guess_length, *cur_ptr))
66                    return ((char *) NULL);
67               continue;
68          }
69          else if (*cur_ptr == '*') {
70               if (! add_char(&re_pattern, &re_ptr, &guess_length, '.'))
71                    return ((char *) NULL);
72               if (! add_char(&re_pattern, &re_ptr, &guess_length, '*'))
73                    return ((char *) NULL);
74               continue;
75          }
76          else if (*cur_ptr == '?') {
77               if (! add_char(&re_pattern, &re_ptr, &guess_length, '.'))
78                    return ((char *) NULL);
79               continue;
80          }
81          else {
82               if (! add_char(&re_pattern, &re_ptr, &guess_length, *cur_ptr))
83                    return ((char *) NULL);
84          }
85     }
86     if (! add_char(&re_pattern, &re_ptr, &guess_length, '\0'))
87          return ((char *) NULL);
88     return (re_pattern);
89}
90
91
92
93
94
95
96/*
97 * add_char() takes two char **, a length which is the current amount
98 * of space implemented for the string pointed to by the first *(char **),
99 * and a character to add to the string.  It reallocs extra space if
100 * necessary, adds the character, and messes with the pointers if necessary.
101 */
102static char *add_char(start, finish, length, chr)
103char **start, **finish;
104int *length;
105char chr;
106{
107     if (*finish - *start == *length) {
108          *start = realloc(*start, *length + 5);
109          if (! *start) {
110               perror(sprintf(error_buf, "%s: add_char", whoami));
111               exit(1);
112          }
113          *finish = *start + *length - 1;
114          *length += 5;
115     }
116     **finish = chr;
117     (*finish)++;
118     return(*start);
119}
120
121         
122
123
124
125
126/*
127 * add_arrays() takes pointers to two arrays of char **'s and their
128 * lengths, merges the two into the first by realloc'ing the first and
129 * then free's the second's memory usage.
130 */ 
131add_arrays(array1, num1, array2, num2)
132char ***array1, ***array2;
133int *num1, *num2;
134{
135     int counter;
136     
137     *array1 = (char **) realloc(*array1, sizeof(char *) * (*num1 + *num2));
138     if (! *array1) {
139          perror(sprintf(error_buf, "%s: add_arrays", whoami));
140          exit(1);
141     }
142     for (counter = *num1; counter < *num1 + *num2; counter++)
143          *(*array1 + counter) = *(*array2 + counter - *num1);
144     free (*array2);
145     *num1 += *num2;
146     return(0);
147}
148
149
150
151
152
153
154
155char **add_str(strs, num, str)
156char **strs;
157int num;
158char *str;
159{
160     strs = (char **) realloc(strs, sizeof(char *) * (num + 1));
161     if (! strs) {
162          perror(sprintf(error_buf, "%s: add_str", whoami));
163          exit(1);
164     }
165     strs[num] = malloc(strlen(str) + 1);
166     if (! strs[num]) {
167          perror(sprintf(error_buf, "%s: add_str", whoami));
168          exit(1);
169     }
170     strcpy(strs[num], str);
171     return(strs);
172}
173
174
175
176
177
178
179
180char **find_deleted_matches(base, expression, num_found)
181char *base, *expression;
182int *num_found;
183{
184     struct direct *dp;
185     DIR *dirp;
186     char **found;
187     int num;
188     char **next;
189     int num_next;
190     char first[MAXNAMLEN], rest[MAXPATHLEN];
191     char new[MAXPATHLEN];
192     
193     found = (char **) malloc(0);
194     *num_found = num = 0;
195
196     dirp = opendir(base);
197     if (! dirp)
198          return(found);
199
200     readdir(dirp); readdir(dirp); /* get rid of . and .. */
201     
202     strcpy(first, reg_firstpart(expression, rest));
203     re_comp(first);
204
205     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
206          if (re_exec(dp->d_name) && *rest) {
207               strcpy(new, append(base, dp->d_name));
208               next = find_deleted_matches(new, rest, &num_next);
209               add_arrays(&found, &num, &next, &num_next);
210          }
211          else if (is_deleted(dp->d_name)) if (re_exec(&dp->d_name[2])) {
212               if (*rest) {
213                    strcpy(new, append(base, dp->d_name));
214                    next = find_deleted_matches(new, rest, &num_next);
215                    add_arrays(&found, &num, &next, &num_next);
216               }
217               else {
218                    found = add_str(found, num, append(base, dp->d_name));
219                    num++;
220               }
221          }
222     }
223     closedir(dirp);
224     *num_found = num;
225     return(found);
226}
227
228
229
230
231
232char **find_matches(base, expression, num_found)
233char *base, *expression;
234int *num_found;
235{
236     struct direct *dp;
237     DIR *dirp;
238     char **found;
239     int num;
240     char **next;
241     int num_next;
242     char first[MAXNAMLEN], rest[MAXPATHLEN];
243     char new[MAXPATHLEN];
244     
245     found = (char **) malloc(0);
246     *num_found = num = 0;
247
248     dirp = opendir(base);
249     if (! dirp)
250          return(found);
251
252     readdir(dirp); readdir(dirp); /* get rid of . and .. */
253     
254     strcpy(first, reg_firstpart(expression, rest));
255
256     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
257          re_comp(first);
258          if (re_exec(dp->d_name)) {
259               if (*rest) {
260                    strcpy(new, append(base, dp->d_name));
261                    next = find_matches(new, rest, &num_next);
262                    add_arrays(&found, &num, &next, &num_next);
263               }
264               else {
265                    found = add_str(found, num, append(base, dp->d_name));
266                    num++;
267               }
268          }
269          else if (is_deleted(dp->d_name)) if (re_exec(&dp->d_name[2])) {
270               if (*rest) {
271                    strcpy(new, append(base, dp->d_name));
272                    next = find_matches(new, rest, &num_next);
273                    add_arrays(&found, &num, &next, &num_next);
274               }
275               else {
276                    found = add_str(found, num, append(base, dp->d_name));
277                    num++;
278               }
279          }
280     }
281     closedir(dirp);
282     *num_found = num;
283     return(found);
284}
285
286
287
288
289
290
291
292char **find_recurses(base, num_found)
293char *base;
294int *num_found;
295{
296     DIR *dirp;
297     struct direct *dp;
298     char newname[MAXPATHLEN];
299     char **found, **new_found;
300     int found_num, new_found_num;
301     struct stat stat_buf;
302     
303     found = (char **) malloc(0);
304     *num_found = found_num = 0;
305     
306     dirp = opendir(base);
307     if (! dirp)
308          return(found);
309
310     readdir(dirp); readdir(dirp); /* get rid of . and .. */
311
312     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
313          strcpy(newname, append(base, dp->d_name));
314          found = add_str(found, found_num, newname);
315          found_num++;
316          if (lstat(newname, &stat_buf))
317               continue;
318          if (stat_buf.st_mode & S_IFDIR) {
319               new_found = find_recurses(newname, &new_found_num);
320               add_arrays(&found, &found_num, &new_found, &new_found_num);
321          }
322     }
323     closedir(dirp);
324     *num_found = found_num;
325     return(found);
326}
327
328
329
330
331
332
333char **find_deleted_recurses(base, num_found)
334char *base;
335int *num_found;
336{
337     DIR *dirp;
338     struct direct *dp;
339     char newname[MAXPATHLEN];
340     char **found, **new_found;
341     int found_num, new_found_num;
342     struct stat stat_buf;
343     
344     found = (char **) malloc(0);
345     *num_found = found_num = 0;
346     
347     dirp = opendir(base);
348     if (! dirp)
349          return(found);
350
351     readdir(dirp); readdir(dirp); /* get rid of . and .. */
352
353     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
354          strcpy(newname, append(base, dp->d_name));
355         
356          if (is_deleted(dp->d_name)) {
357               found = add_str(found, found_num, newname);
358               found_num++;
359          }
360          if (lstat(newname, &stat_buf)) {
361               perror("foobar");
362               continue;
363          }
364          if (stat_buf.st_mode & S_IFDIR) {
365               new_found = find_deleted_recurses(newname, &new_found_num);
366               add_arrays(&found, &found_num, &new_found, &new_found_num);
367          }
368     }
369     closedir(dirp);
370     *num_found = found_num;
371     return(found);
372}
373
374
375
376
377
378
379char **find_contents(base, num_found)
380char *base;
381int *num_found;
382{
383     DIR *dirp;
384     struct direct *dp;
385     char **found;
386     int num;
387
388     found = (char **) malloc(0);
389     *num_found = num = 0;
390   
391     dirp = opendir(base);
392     if (! dirp)
393          return(found);
394
395     readdir(dirp); readdir(dirp); /* get rid of . and .. */
396
397     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
398          found = add_str(found, num, append(base, dp->d_name));
399          num += 1;
400     }
401     closedir(dirp);
402     *num_found = num;
403     return(found);
404}
405
406
407     
408char **find_deleted_contents(base, num_found)
409char *base;
410int *num_found;
411{
412     DIR *dirp;
413     struct direct *dp;
414     char **found;
415     int num;
416
417     found = (char **) malloc(0);
418     *num_found = num = 0;
419   
420     dirp = opendir(base);
421     if (! dirp)
422          return(found);
423
424     readdir(dirp); readdir(dirp); /* get rid of . and .. */
425
426     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
427          if (is_deleted(dp->d_name)) {
428               found = add_str(found, num, append(base, dp->d_name));
429               num += 1;
430          }
431     }
432     closedir(dirp);
433     *num_found = num;
434     return(found);
435}
436
437
438
439
440char **find_deleted_contents_recurs(base, num_found)
441char *base;
442int *num_found;
443{
444     DIR *dirp;
445     struct direct *dp;
446     char **found;
447     int num;
448     struct stat stat_buf;
449     char newname[MAXPATHLEN];
450     char **new_found;
451     int new_found_num;
452     
453     found = (char **) malloc(0);
454     *num_found = num = 0;
455   
456     dirp = opendir(base);
457     if (! dirp)
458          return(found);
459
460     readdir(dirp); readdir(dirp); /* get rid of . and .. */
461
462     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
463          if (is_deleted(dp->d_name)) {
464               strcpy(newname, append(base, dp->d_name));
465               found = add_str(found, num, newname);
466               num += 1;
467               if (lstat(newname, &stat_buf))
468                    continue;
469               if (stat_buf.st_mode & S_IFDIR) {
470                    new_found = find_recurses(newname, &new_found_num);
471                    add_arrays(&found, &num, &new_found, &new_found_num);
472               }
473          }
474     }
475     closedir(dirp);
476     *num_found = num;
477     return(found);
478}
479     
Note: See TracBrowser for help on using the repository browser.