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

Revision 12350, 7.8 KB checked in by ghudson, 26 years ago (diff)
Some RCS ID cleanup: delete $Log$ and replace other RCS keywords with $Id$.
Line 
1/*
2 * $Id: lsdel.c,v 1.24 1999-01-22 23:09:01 ghudson Exp $
3 *
4 * This program is a replacement for rm.  Instead of actually deleting
5 * files, it marks them for deletion by prefixing them with a ".#"
6 * prefix.
7 *
8 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, see the file "mit-copying.h."
10 */
11
12#if (!defined(lint) && !defined(SABER))
13     static char rcsid_lsdel_c[] = "$Id: lsdel.c,v 1.24 1999-01-22 23:09:01 ghudson Exp $";
14#endif
15
16#include <stdio.h>
17#include <sys/types.h>
18#include <dirent.h>
19#include <sys/param.h>
20#include <string.h>
21#include <errno.h>
22#include <com_err.h>
23#include "col.h"
24#include "util.h"
25#include "directories.h"
26#include "pattern.h"
27#include "lsdel.h"
28#include "shell_regexp.h"
29#include "mit-copying.h"
30#include "delete_errs.h"
31#include "errors.h"
32
33extern time_t current_time;
34
35int space_total = 0;
36int dirsonly, recursive, yield, f_links, f_mounts, singlecolumn;
37time_t timev;
38
39main(argc, argv)
40int argc;
41char *argv[];
42{
43     extern char *optarg;
44     extern int optind;
45     int arg;
46     
47     whoami = lastpart(argv[0]);
48
49     dirsonly = recursive = timev = yield = f_links = f_mounts = 0;
50     singlecolumn = -1;
51     while ((arg = getopt(argc, argv, "1Cdrt:ysm")) != -1) {
52          switch (arg) {
53          case '1':
54               if ((singlecolumn != -1) && (! singlecolumn)) {
55                    fprintf(stderr,
56                            "%s: -1 and -C options are mutually exclusive\n",
57                            whoami);
58                    usage();
59                    exit(1);
60               }
61               singlecolumn = 1;
62               break;
63          case 'C':
64               if ((singlecolumn != -1) && singlecolumn) {
65                    fprintf(stderr,
66                            "%s: -1 and -C options are mutually exclusive\n",
67                            whoami);
68                    usage();
69                    exit(1);
70               }
71               singlecolumn = 0;
72               break;
73          case 'd':
74               dirsonly++;
75               break;
76          case 'r':
77               recursive++;
78               break;
79          case 't':
80               timev = atoi(optarg);
81               break;
82          case 'y':
83               yield++;
84               break;
85          case 's':
86               f_links++;
87               break;
88          case 'm':
89               f_mounts++;
90               break;
91          default:
92               usage();
93               exit(1);
94          }
95     }
96     if (singlecolumn == -1)
97          singlecolumn = ! isatty(1);
98
99     if (optind == argc) {
100          char *cwd;
101
102          cwd = ".";
103
104          if (ls(&cwd, 1))
105               error("ls of .");
106     }
107     else if (ls(&argv[optind], argc - optind))
108          error ("ls");
109
110     exit (error_occurred ? 1 : 0);
111}
112
113
114
115
116
117
118usage()
119{
120     fprintf(stderr, "Usage: %s [ options ] [ filename [ ...]]\n", whoami);
121     fprintf(stderr, "Options are:\n");
122     fprintf(stderr, "     -d     list directory names, not contents\n");
123     fprintf(stderr, "     -r     recursive\n");
124     fprintf(stderr, "     -t n   list n-day-or-older files only\n");
125     fprintf(stderr, "     -y     report total space taken up by files\n");
126     fprintf(stderr, "     -s     follow symbolic links to directories\n");
127     fprintf(stderr, "     -m     follow mount points\n");
128     fprintf(stderr, "     -1     force single-column output\n");
129     fprintf(stderr, "     -C     force multi-column output (default when output is to a terminal)\n");
130     fprintf(stderr, "-1 and -C are mutually exclusive\n");
131}
132
133
134
135
136ls(args, num)
137char **args;
138int num;
139{
140     char **found_files;
141     int num_found = 0, total = 0;
142     int status = 0;
143     int retval;
144
145     initialize_del_error_table();
146     
147     if (retval = initialize_tree()) {
148          error("initialize_tree");
149          return retval;
150     }
151     
152     for ( ; num; num--) {
153          if (retval = get_the_files(args[num - 1], &num_found,
154                                     &found_files)) {
155               error(args[num - 1]);
156               status = retval;
157               continue;
158          }
159
160          if (num_found) {
161               num_found = process_files(found_files, num_found);
162               if (num_found < 0) {
163                    error("process_files");
164                    status = error_code;
165                    continue;
166               }
167               total += num_found;
168          }
169          else {
170               /* What we do at this point depends on exactly what the
171                * filename is.  There are several possible conditions:
172                * 1. The filename has no wildcards in it, which means that
173                *    if we couldn't find it, that means it doesn't
174                *    exist.  Print a not found error.
175                * 2. Filename is an existing directory, with no deleted
176                *    files in it.  Print nothing.
177                * 3. Filename doesn't exist, and there are wildcards in
178                *    it.  Print "no match".
179                * None of these are considered error conditions, so we
180                * don't set the error flag.
181                */
182               if (no_wildcards(args[num - 1])) {
183                    if (! directory_exists(args[num - 1])) {
184                         set_error(ENOENT);
185                         error(args[num - 1]);
186                         status = error_code;
187                         continue;
188                    }
189               }
190               else {
191                    set_error(ENOMATCH);
192                    error(args[num - 1]);
193                    status = error_code;
194                    continue;
195               }
196          }
197     }
198     if (total) {
199          if (list_files()) {
200               error("list_files");
201               return error_code;
202          }
203     }
204     if (yield)
205          printf("\nTotal space taken up by file%s: %dk\n",
206                 (total == 1 ? "" : "s"), space_to_k(space_total));
207
208     return status;
209}
210
211
212
213
214int get_the_files(name, number_found, found)
215char *name;
216int *number_found;
217char ***found;
218{
219     int retval;
220     int options;
221     
222     options = FIND_DELETED | FIND_CONTENTS;
223     if (recursive)
224          options |= RECURS_FIND_DELETED;
225     if (! dirsonly)
226          options |= RECURS_DELETED;
227     if (f_mounts)
228          options |= FOLLW_MOUNTPOINTS;
229     if (f_links)
230          options |= FOLLW_LINKS;
231     
232     retval = find_matches(name, number_found, found, options);
233     if (retval) {
234          error("find_matches");
235          return retval;
236     }
237
238     return 0;
239}
240
241
242
243
244
245
246process_files(files, num)
247char **files;
248int num;
249{
250     int i, skipped = 0;
251     filerec *leaf;
252     
253     for (i = 0; i < num; i++) {
254          if (add_path_to_tree(files[i], &leaf)) {
255               error("add_path_to_tree");
256               return -1;
257          }
258          free(files[i]);
259          if (! timed_out(leaf, current_time, timev)) {
260               free_leaf(leaf);
261               skipped++;
262               continue;
263          }
264          space_total += specs_to_space(leaf->specs);
265     }
266     free((char *) files);
267     return(num-skipped);
268}
269
270
271
272
273static int alphacmp(arg1, arg2)
274const void *arg1, *arg2;
275{
276     return(strcmp(*(char **) arg1, *(char **) arg2));
277}
278
279list_files()
280{
281     filerec *current;
282     char **strings;
283     int num;
284     int retval;
285     
286     strings = (char **) Malloc((unsigned) sizeof(char *));
287     num = 0;
288     if (! strings) {
289          set_error(errno);
290          error("Malloc");
291          return error_code;
292     }
293     current = get_root_tree();
294     if (retval = accumulate_names(current, &strings, &num)) {
295          error("accumulate_names");
296          return retval;
297     }
298     current = get_cwd_tree();
299     if (retval = accumulate_names(current, &strings, &num)) {
300          error("accumulate_names");
301          return retval;
302     }
303
304     qsort(strings, num, sizeof(char *), alphacmp);
305
306     if (retval = unique(&strings, &num)) {
307          error("unique");
308          return retval;
309     }
310
311     if (retval = column_array(strings, num, DEF_SCR_WIDTH, 0, singlecolumn,
312                               2, 1, 0, 1, stdout)) {
313          error("column_array");
314          return retval;
315     }
316     
317     for ( ; num; num--)
318          free(strings[num - 1]);
319     free((char *) strings);
320     return 0;
321}
322
323
324int unique(the_files, number)
325char ***the_files;
326int *number;
327{
328     int i, last;
329     int offset;
330     char **files;
331
332     files = *the_files;
333     for (last = 0, i = 1; i < *number; i++) {
334          if (! strcmp(files[last], files[i])) {
335               free (files[i]);
336               free (files[i]);
337               files[i] = (char *) NULL;
338          }
339          else
340               last = i;
341     }
342     
343     for (offset = 0, i = 0; i + offset < *number; i++) {
344          if (! files[i])
345               offset++;
346          if (i + offset < *number)
347               files[i] = files[i + offset];
348     }
349     *number -= offset;
350     files = (char **) realloc((char *) files,
351                               (unsigned) (sizeof(char *) * *number));
352     if ((! files) && *number)
353     {
354          set_error(errno);
355          error("realloc");
356          return errno;
357     }
358
359     *the_files = files;
360     return 0;
361}
Note: See TracBrowser for help on using the repository browser.