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

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