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

Revision 2084, 6.1 KB checked in by jik, 35 years ago (diff)
bug with "lsdel" with no arguments -- freeing to early, and treating lsdel . as a special case when it doesn't need to be.
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.6 1989-09-11 04:34: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 <sys/stat.h>
22#include <strings.h>
23#include "col.h"
24#include "util.h"
25#include "directories.h"
26#include "pattern.h"
27#include "lsdel.h"
28#include "mit-copyright.h"
29
30char *malloc(), *realloc();
31extern int current_time;
32
33int block_total = 0;
34int dirsonly, recursive, timev, yield;
35char *whoami, *error_buf;
36
37main(argc, argv)
38int argc;
39char *argv[];
40{
41     extern char *optarg;
42     extern int optind;
43     int arg;
44     
45     whoami = lastpart(argv[0]);
46     error_buf = malloc(strlen(whoami) + MAXPATHLEN + 3);
47     if (! error_buf) {
48          perror(whoami);
49          exit(1);
50     }
51     dirsonly = recursive = timev = yield = 0;
52     while ((arg = getopt(argc, argv, "drt:y")) != -1) {
53          switch (arg) {
54          case 'd':
55               dirsonly++;
56               break;
57          case 'r':
58               recursive++;
59               break;
60          case 't':
61               timev = atoi(optarg);
62               break;
63          case 'y':
64               yield++;
65               break;
66          default:
67               usage();
68               exit(1);
69          }
70     }
71     if (optind == argc) {
72          char *cwd;
73
74          cwd = ".";
75          exit(ls(&cwd, 1));
76     }
77     exit(ls(&argv[optind], argc - optind));
78}
79
80
81
82
83
84
85usage()
86{
87     printf("Usage: %s [ options ] [ filename [ ...]]\n", whoami);
88     printf("Options are:\n");
89     printf("     -d     list directory names, not contents\n");
90     printf("     -r     recursive\n");
91     printf("     -t n   list n-day-or-older files only\n");
92     printf("     -y     report total space taken up by files\n");
93}
94
95
96
97
98ls(args, num)
99char **args;
100int num;
101{
102     char *start_dir;
103     char **found_files;
104     int num_found, total = 0;
105     char *file_re;
106     int status = 0;
107
108     if (initialize_tree())
109          exit(1);
110     
111     for ( ; num; num--) {
112          if (*args[num - 1] == '/') {
113               start_dir = "/";
114               file_re = parse_pattern(args[num - 1] + 1);
115          }
116          else {
117               start_dir = "";
118               file_re = parse_pattern(args[num - 1]);
119          }
120          if (! file_re)
121               return(ERROR_MASK);
122
123          found_files = get_the_files(start_dir, file_re, &num_found);
124          total += num_found;
125          if (num_found)
126               num_found = process_files(found_files, num_found);
127          else {
128               /* What we do at this point depends on exactly what the
129                * file_re is.  There are several possible conditions:
130                * 1. file_re has no wildcards in it, which means that
131                *    if we couldn't find it, that means it doesn't
132                *    exist.  Print a not found error.
133                * 2. file_re is an existing directory, with no deleted
134                *    files in it.  Print nothing.
135                * 3. file_re doesn't exist, and there are wildcards in
136                *    it.  Print "no match".
137                * None of these are considered error conditions, so we
138                * don't set the error flag.
139                */
140               if (no_wildcards(file_re)) {
141                    if (! directory_exists(args[num - 1])) {
142                         fprintf(stderr, "%s: %s: not found\n",
143                                 whoami, args[num - 1]);
144                    }
145               }
146               else {
147                    fprintf(stderr, "%s: %s: no match\n",
148                            whoami, args[num-1]);
149               }
150          }
151          free(file_re);
152     }
153     if (total) {
154          list_files();
155     }
156     if (yield)
157          printf("\nTotal space taken up by file%s: %dk\n",
158                 (total == 1 ? "" : "s"), blk_to_k(block_total));
159     return(status);
160}
161
162
163
164
165char **get_the_files(start_dir, file_re, number_found)
166char *start_dir, *file_re;
167int *number_found;
168{
169     char **matches;
170     int num_matches;
171     char **found;
172     int num;
173     int i;
174
175     found = (char **) malloc(0);
176     num = 0;
177
178     matches = find_matches(start_dir, file_re, &num_matches);
179     if (recursive) {
180          char **recurs_found;
181          int recurs_num;
182
183          for (i = 0; i < num_matches; free(matches[i]), i++) {
184               if (is_deleted(lastpart(matches[i]))) {
185                    found = add_str(found, num, matches[i]);
186                    num++;
187               }
188               recurs_found = find_deleted_recurses(matches[i], &recurs_num);
189               add_arrays(&found, &num, &recurs_found, &recurs_num);
190          }
191     }
192     else {
193          struct stat stat_buf;
194          char **contents_found;
195          int num_contents;
196         
197          for (i = 0; i < num_matches; free(matches[i]), i++) {
198               if (is_deleted(lastpart(matches[i]))) {
199                    found = add_str(found, num, matches[i]);
200                    num++;
201               }
202               if (dirsonly)
203                    continue;
204               if (lstat(matches[i], &stat_buf))
205                    continue;
206               if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
207                    contents_found = find_deleted_contents_recurs(matches[i],
208                                                          &num_contents);
209                    add_arrays(&found, &num, &contents_found, &num_contents);
210                   
211               }
212          }
213     }
214     free(matches);
215     *number_found = num;
216     return(found);
217}
218
219
220
221
222
223
224process_files(files, num)
225char **files;
226int num;
227{
228     int i;
229     filerec *leaf;
230     
231     for (i = 0; i < num; i++) {
232          if (! (leaf = add_path_to_tree(files[i]))) {
233               fprintf(stderr, "%s: error adding path to filename tree\n",
234                       whoami);
235               exit(1);
236          }
237
238          free(files[i]);
239          if (! timed_out(leaf, current_time, timev)) {
240               free_leaf(leaf);
241               num--;
242               continue;
243          }
244          block_total += leaf->specs.st_blocks;
245     }
246     free(files);
247     return(num);
248}
249
250
251
252
253
254list_files()
255{
256     filerec *current;
257     char **strings;
258     int num;
259
260     strings = (char **) malloc(sizeof(char *));
261     num = 0;
262     if (! strings) {
263          perror(sprintf(error_buf, "%s: list_files", whoami));
264          exit(1);
265     }
266     current = get_root_tree();
267     strings = accumulate_names(current, strings, &num);
268     current = get_cwd_tree();
269     strings = accumulate_names(current, strings, &num);
270     column_array(strings, num, DEF_SCR_WIDTH, 0, 0, 2, 1, 0, 1, stdout);
271     for ( ; num; num--)
272          free(strings[num - 1]);
273     free(strings);
274     return(0);
275}
Note: See TracBrowser for help on using the repository browser.