home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume18 / undel / part03 / lsdel.c < prev   
Encoding:
C/C++ Source or Header  |  1989-05-06  |  5.9 KB  |  274 lines

  1. /*
  2.  * $Source: /mit/jik/src/delete/RCS/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: lsdel.c,v 1.4 89/03/27 12:07:13 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.  
  30. char *malloc(), *realloc();
  31. extern int current_time;
  32.  
  33. int block_total = 0;
  34. int dirsonly, recursive, timev, yield;
  35. char *whoami, *error_buf;
  36.  
  37. main(argc, argv)
  38. int argc;
  39. char *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.  
  85. usage()
  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.  
  98. ls(args, num)
  99. char **args;
  100. int 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.       free(file_re);
  125.       total += num_found;
  126.       if (num_found)
  127.            num_found = process_files(found_files, num_found);
  128.       else {
  129.            /* What we do at this point depends on exactly what the
  130.             * file_re is.  There are three possible conditions:
  131.         * 1. It's an existing directory.  Print nothing.
  132.         * 2. It doesn't exist in deleted form, and there are
  133.         *    no wildcards in it.  Then we print "not found."
  134.         * 3. It does't exist, but there are wildcards in it.
  135.         *    Then we print "no match."
  136.         * None of these are considered error conditions, so we
  137.         * don't set the error flag.
  138.         */
  139.            if (no_wildcards(file_re)) {
  140.             if (! directory_exists(args[num - 1])) {
  141.              fprintf(stderr, "%s: %s: not found\n",
  142.                  whoami, args[num - 1]);
  143.             }
  144.            }
  145.            else {
  146.             fprintf(stderr, "%s: %s: no match\n",
  147.                 whoami, args[num-1]);
  148.            }
  149.       }
  150.      }
  151.      if (total) {
  152.       list_files();
  153.      }
  154.      if (yield)
  155.       printf("\nTotal space taken up by file%s: %dk\n",
  156.          (total == 1 ? "" : "s"), blk_to_k(block_total));
  157.      return(status);
  158. }
  159.  
  160.  
  161.  
  162.  
  163. char **get_the_files(start_dir, file_re, number_found)
  164. char *start_dir, *file_re;
  165. int *number_found;
  166. {
  167.      char **matches;
  168.      int num_matches;
  169.      char **found;
  170.      int num;
  171.      int i;
  172.  
  173.      found = (char **) malloc(0);
  174.      num = 0;
  175.  
  176.      matches = find_matches(start_dir, file_re, &num_matches);
  177.      if (recursive) {
  178.       char **recurs_found;
  179.       int recurs_num;
  180.  
  181.       for (i = 0; i < num_matches; free(matches[i]), i++) {
  182.            if (is_deleted(lastpart(matches[i]))) {
  183.             found = add_str(found, num, matches[i]);
  184.             num++;
  185.            }
  186.            recurs_found = find_deleted_recurses(matches[i], &recurs_num);
  187.            add_arrays(&found, &num, &recurs_found, &recurs_num);
  188.       }
  189.      }
  190.      else {
  191.       struct stat stat_buf;
  192.       char **contents_found;
  193.       int num_contents;
  194.       
  195.       for (i = 0; i < num_matches; free(matches[i]), i++) {
  196.            if (is_deleted(lastpart(matches[i]))) {
  197.             found = add_str(found, num, matches[i]);
  198.             num++;
  199.            }
  200.            if (dirsonly)
  201.             continue;
  202.            if (lstat(matches[i], &stat_buf))
  203.             continue;
  204.            if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
  205.             contents_found = find_deleted_contents_recurs(matches[i],
  206.                               &num_contents);
  207.             add_arrays(&found, &num, &contents_found, &num_contents);
  208.             
  209.            }
  210.       }
  211.      }
  212.      free(matches);
  213.      *number_found = num;
  214.      return(found);
  215. }
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222. process_files(files, num)
  223. char **files;
  224. int num;
  225. {
  226.      int i;
  227.      filerec *leaf;
  228.      
  229.      for (i = 0; i < num; i++) {
  230.       if (! (leaf = add_path_to_tree(files[i]))) {
  231.            fprintf(stderr, "%s: error adding path to filename tree\n",
  232.                whoami);
  233.            exit(1);
  234.       }
  235.  
  236.       free(files[i]);
  237.       if (! timed_out(leaf, current_time, timev)) {
  238.            free_leaf(leaf);
  239.            num--;
  240.            continue;
  241.       }
  242.       block_total += leaf->specs.st_blocks;
  243.      }
  244.      free(files);
  245.      return(num);
  246. }
  247.  
  248.  
  249.  
  250.  
  251.  
  252. list_files()
  253. {
  254.      filerec *current;
  255.      char **strings;
  256.      int num;
  257.  
  258.      strings = (char **) malloc(sizeof(char *));
  259.      num = 0;
  260.      if (! strings) {
  261.       perror(sprintf(error_buf, "%s: list_files", whoami));
  262.       exit(1);
  263.      }
  264.      current = get_root_tree();
  265.      strings = accumulate_names(current, strings, &num);
  266.      current = get_cwd_tree();
  267.      strings = accumulate_names(current, strings, &num);
  268.      column_array(strings, num, DEF_SCR_WIDTH, 0, 0, 2, 1, 0, 1, stdout);
  269.      for ( ; num; num--)
  270.       free(strings[num - 1]);
  271.      free(strings);
  272.      return(0);
  273. }
  274.