source: trunk/athena/bin/delete/lsdel.c @ 2177

Revision 2177, 8.4 KB checked in by jik, 35 years ago (diff)
Not quite sure what all the changes are, but most of them are to fit in with the new error-handling and to fix some lint errors.
Line 
1/*
2 * $Source: /afs/dev.mit.edu/source/repository/athena/bin/delete/lsdel.c,v $
3 * $Author: jik $
4 *
5 * This program is a replacement for rm.  Instead of actually deleting
6 * files, it marks them for deletion by prefixing them with a ".#"
7 * prefix.
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_lsdel_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/delete/lsdel.c,v 1.7 1989-10-23 13:35:27 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 <sys/stat.h>
22#include <strings.h>
23#include <errno.h>
24#include <com_err.h>
25#include "col.h"
26#include "util.h"
27#include "directories.h"
28#include "pattern.h"
29#include "lsdel.h"
30#include "shell_regexp.h"
31#include "mit-copyright.h"
32#include "delete_errs.h"
33#include "errors.h"
34
35char *malloc(), *realloc();
36extern int current_time;
37extern int errno;
38
39int block_total = 0;
40int dirsonly, recursive, timev, yield;
41
42main(argc, argv)
43int argc;
44char *argv[];
45{
46     extern char *optarg;
47     extern int optind;
48     int arg;
49     
50     whoami = lastpart(argv[0]);
51
52     dirsonly = recursive = timev = yield = 0;
53     while ((arg = getopt(argc, argv, "drt:y")) != -1) {
54          switch (arg) {
55          case 'd':
56               dirsonly++;
57               break;
58          case 'r':
59               recursive++;
60               break;
61          case 't':
62               timev = atoi(optarg);
63               break;
64          case 'y':
65               yield++;
66               break;
67          default:
68               usage();
69               exit(1);
70          }
71     }
72     if (optind == argc) {
73          char *cwd;
74
75          cwd = ".";
76
77          if (ls(&cwd, 1))
78               error("ls of .");
79     }
80     if (ls(&argv[optind], argc - optind))
81          error ("ls");
82
83     exit (error_occurred ? 1 : 0);
84}
85
86
87
88
89
90
91usage()
92{
93     printf("Usage: %s [ options ] [ filename [ ...]]\n", whoami);
94     printf("Options are:\n");
95     printf("     -d     list directory names, not contents\n");
96     printf("     -r     recursive\n");
97     printf("     -t n   list n-day-or-older files only\n");
98     printf("     -y     report total space taken up by files\n");
99}
100
101
102
103
104ls(args, num)
105char **args;
106int num;
107{
108     char *start_dir;
109     char **found_files;
110     int num_found, total = 0;
111     char *file_re;
112     int status = 0;
113     int retval;
114
115     initialize_del_error_table();
116     
117     if (retval = initialize_tree()) {
118          error("initialize_tree");
119          return retval;
120     }
121     
122     for ( ; num; num--) {
123          if (*args[num - 1] == '/') {
124               start_dir = "/";
125               file_re = args[num - 1] + 1;
126          }
127          else {
128               start_dir = "";
129               file_re = args[num - 1];
130          }
131
132          if (retval = get_the_files(start_dir, file_re, &num_found,
133                                     &found_files)) {
134               error(args[num - 1]);
135               status = retval;
136               continue;
137          }
138
139          if (num_found) {
140               num_found = process_files(found_files, num_found);
141               if (num_found < 0) {
142                    error("process_files");
143                    status = error_code;
144                    continue;
145               }
146               total += num_found;
147          }
148          else {
149               /* What we do at this point depends on exactly what the
150                * file_re is.  There are several possible conditions:
151                * 1. file_re has no wildcards in it, which means that
152                *    if we couldn't find it, that means it doesn't
153                *    exist.  Print a not found error.
154                * 2. file_re is an existing directory, with no deleted
155                *    files in it.  Print nothing.
156                * 3. file_re doesn't exist, and there are wildcards in
157                *    it.  Print "no match".
158                * None of these are considered error conditions, so we
159                * don't set the error flag.
160                */
161               if (no_wildcards(file_re)) {
162                    if (! directory_exists(args[num - 1])) {
163                         set_error(ENOENT);
164                         error(args[num - 1]);
165                         status = error_code;
166                         continue;
167                    }
168               }
169               else {
170                    set_error(ENOMATCH);
171                    error(args[num - 1]);
172                    status = error_code;
173                    continue;
174               }
175          }
176     }
177     if (total) {
178          if (list_files()) {
179               error("list_files");
180               return error_code;
181          }
182     }
183     if (yield)
184          printf("\nTotal space taken up by file%s: %dk\n",
185                 (total == 1 ? "" : "s"), blk_to_k(block_total));
186
187     return status;
188}
189
190
191
192
193int get_the_files(start_dir, file_re, number_found, found)
194char *start_dir, *file_re;
195int *number_found;
196char ***found;
197{
198     char **matches;
199     int num_matches;
200     int num;
201     int i;
202     int retval;
203     int status = 0;
204     
205     *found = (char **) malloc(0);
206     num = 0;
207
208     if (retval = find_matches(start_dir, file_re, &num_matches, &matches)) {
209          error("find_matches");
210          return retval;
211     }
212     
213     if (recursive) {
214          char **recurs_found;
215          int recurs_num;
216
217          for (i = 0; i < num_matches; free(matches[i]), i++) {
218               if (is_deleted(lastpart(matches[i]))) {
219                    if (retval = add_str(found, num, matches[i])) {
220                         error("add_str");
221                         return retval;
222                    }
223                    num++;
224               }
225               if (retval = find_deleted_recurses(matches[i], &recurs_num,
226                                                  &recurs_found)) {
227                    error("find_deleted_recurses");
228                    return retval;
229               }
230               if (retval = add_arrays(found, &num, &recurs_found,
231                                       &recurs_num)) {
232                    error("add_arrays");
233                    return retval;
234               }
235          }
236     }
237     else {
238          struct stat stat_buf;
239          char **contents_found;
240          int num_contents;
241         
242          for (i = 0; i < num_matches; free(matches[i]), i++) {
243               if (is_deleted(lastpart(matches[i]))) {
244                    if (retval = add_str(found, num, matches[i])) {
245                         error("add_str");
246                         return retval;
247                    }
248                    num++;
249               }
250               if (dirsonly)
251                    continue;
252               if (lstat(matches[i], &stat_buf)) {
253                    set_error(errno);
254                    error(matches[i]);
255                    status = error_code;
256                    continue;
257               }
258               if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
259                    if (retval = find_deleted_contents_recurs(matches[i],
260                                      &num_contents, &contents_found)) {
261                         error("find_deleted_contents_recurs");
262                         return retval;
263                    }
264                    if (retval = add_arrays(found, &num, &contents_found,
265                                            &num_contents)) {
266                         error("add_arrays");
267                         return retval;
268                    }
269               }
270          }
271     }
272     free(matches);
273     *number_found = num;
274     return status;
275}
276
277
278
279
280
281
282process_files(files, num)
283char **files;
284int num;
285{
286     int i;
287     filerec *leaf;
288     
289     for (i = 0; i < num; i++) {
290          if (add_path_to_tree(files[i], &leaf)) {
291               error("add_path_to_tree");
292               return -1;
293          }
294          free(files[i]);
295          if (! timed_out(leaf, current_time, timev)) {
296               free_leaf(leaf);
297               num--;
298               continue;
299          }
300          block_total += leaf->specs.st_blocks;
301     }
302     free(files);
303     return(num);
304}
305
306
307
308
309
310list_files()
311{
312     filerec *current;
313     char **strings;
314     int num;
315     int retval;
316     
317     strings = (char **) malloc(sizeof(char *));
318     num = 0;
319     if (! strings) {
320          set_error(errno);
321          error("malloc");
322          return error_code;
323     }
324     current = get_root_tree();
325     if (retval = accumulate_names(current, &strings, &num)) {
326          error("accumulate_names");
327          return retval;
328     }
329     current = get_cwd_tree();
330     if (retval = accumulate_names(current, &strings, &num)) {
331          error("accumulate_names");
332          return retval;
333     }
334
335     if (retval = sort_files(strings, num)) {
336          error("sort_files");
337          return retval;
338     }
339     
340     if (retval = unique(&strings, &num)) {
341          error("unique");
342          return retval;
343     }
344     
345     if (retval = column_array(strings, num, DEF_SCR_WIDTH, 0, 0, 2, 1, 0,
346                               1, stdout)) {
347          error("column_array");
348          return retval;
349     }
350     
351     for ( ; num; num--)
352          free(strings[num - 1]);
353     free(strings);
354     return 0;
355}
356
357
358int sort_files(data, num_data)
359char **data;
360int num_data;
361{
362     qsort((char *) data, num_data, sizeof(char *), strcmp);
363
364     return 0;
365}
366
367
368int unique(the_files, number)
369char ***the_files;
370int *number;
371{
372     int i, last;
373     int offset;
374     char **files;
375
376     files = *the_files;
377     for (last = 0, i = 1; i < *number; i++) {
378          if (! strcmp(files[last], files[i])) {
379               free (files[i]);
380               free (files[i]);
381               files[i] = (char *) NULL;
382          }
383          else
384               last = i;
385     }
386     
387     for (offset = 0, i = 0; i + offset < *number; i++) {
388          if (! files[i])
389               offset++;
390          if (i + offset < *number)
391               files[i] = files[i + offset];
392     }
393     *number -= offset;
394     files = (char **) realloc((char *) files,
395                               (unsigned) (sizeof(char *) * *number));
396     if (! files) {
397          set_error(errno);
398          error("realloc");
399          return errno;
400     }
401
402     *the_files = files;
403     return 0;
404}
Note: See TracBrowser for help on using the repository browser.