home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume22 / undel2 / part02 / lsdel.c < prev    next >
C/C++ Source or Header  |  1990-06-07  |  7KB  |  346 lines

  1. /*
  2.  * $Source: /afs/athena.mit.edu/user/j/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: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/lsdel.c,v 1.9 89/11/22 21:31:08 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.  
  35. char *realloc();
  36. extern time_t current_time;
  37. extern int errno;
  38.  
  39. int block_total = 0;
  40. int dirsonly, recursive, yield, f_links, f_mounts;
  41. time_t timev;
  42.  
  43. main(argc, argv)
  44. int argc;
  45. char *argv[];
  46. {
  47.      extern char *optarg;
  48.      extern int optind;
  49.      int arg;
  50.      
  51.      whoami = lastpart(argv[0]);
  52.  
  53.      dirsonly = recursive = timev = yield = f_links = f_mounts = 0;
  54.      while ((arg = getopt(argc, argv, "drt:ysm")) != -1) {
  55.       switch (arg) {
  56.       case 'd':
  57.            dirsonly++;
  58.            break;
  59.       case 'r':
  60.            recursive++;
  61.            break;
  62.       case 't':
  63.            timev = atoi(optarg);
  64.            break;
  65.       case 'y':
  66.            yield++;
  67.            break;
  68.       case 's':
  69.            f_links++;
  70.            break;
  71.       case 'm':
  72.            f_mounts++;
  73.            break;
  74.       default:
  75.            usage();
  76.            exit(1);
  77.       }
  78.      }
  79.      if (optind == argc) {
  80.       char *cwd;
  81.  
  82.       cwd = ".";
  83.  
  84.       if (ls(&cwd, 1))
  85.            error("ls of .");
  86.      }
  87.      else if (ls(&argv[optind], argc - optind))
  88.       error ("ls");
  89.  
  90.      exit (error_occurred ? 1 : 0);
  91. }
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98. usage()
  99. {
  100.      fprintf(stderr, "Usage: %s [ options ] [ filename [ ...]]\n", whoami);
  101.      fprintf(stderr, "Options are:\n");
  102.      fprintf(stderr, "     -d     list directory names, not contents\n");
  103.      fprintf(stderr, "     -r     recursive\n");
  104.      fprintf(stderr, "     -t n   list n-day-or-older files only\n");
  105.      fprintf(stderr, "     -y     report total space taken up by files\n");
  106.      fprintf(stderr, "     -s     follow symbolic links to directories\n");
  107.      fprintf(stderr, "     -m     follow mount points\n");
  108. }
  109.  
  110.  
  111.  
  112.  
  113. ls(args, num)
  114. char **args;
  115. int num;
  116. {
  117.      char **found_files;
  118.      int num_found = 0, total = 0;
  119.      int status = 0;
  120.      int retval;
  121.  
  122.      initialize_del_error_table();
  123.      
  124.      if (retval = initialize_tree()) {
  125.       error("initialize_tree");
  126.       return retval;
  127.      }
  128.      
  129.      for ( ; num; num--) {
  130.       if (retval = get_the_files(args[num - 1], &num_found,
  131.                      &found_files)) {
  132.            error(args[num - 1]);
  133.            status = retval;
  134.            continue;
  135.       }
  136.  
  137.       if (num_found) {
  138.            num_found = process_files(found_files, num_found);
  139.            if (num_found < 0) {
  140.             error("process_files");
  141.             status = error_code;
  142.             continue;
  143.            }
  144.            total += num_found;
  145.       }
  146.       else {
  147.            /* What we do at this point depends on exactly what the
  148.             * filename is.  There are several possible conditions:
  149.         * 1. The filename has no wildcards in it, which means that
  150.         *    if we couldn't find it, that means it doesn't
  151.         *    exist.  Print a not found error.
  152.         * 2. Filename is an existing directory, with no deleted
  153.         *    files in it.  Print nothing.
  154.         * 3. Filename doesn't exist, and there are wildcards in
  155.         *    it.  Print "no match".
  156.         * None of these are considered error conditions, so we
  157.         * don't set the error flag.
  158.         */
  159.            if (no_wildcards(args[num - 1])) {
  160.             if (! directory_exists(args[num - 1])) {
  161.              set_error(ENOENT);
  162.              error(args[num - 1]);
  163.              status = error_code;
  164.              continue;
  165.             }
  166.            }
  167.            else {
  168.             set_error(ENOMATCH);
  169.             error(args[num - 1]);
  170.             status = error_code;
  171.             continue;
  172.            }
  173.       }
  174.      }
  175.      if (total) {
  176.       if (list_files()) {
  177.            error("list_files");
  178.            return error_code;
  179.       }
  180.      }
  181.      if (yield)
  182.       printf("\nTotal space taken up by file%s: %dk\n",
  183.          (total == 1 ? "" : "s"), blk_to_k(block_total));
  184.  
  185.      return status;
  186. }
  187.  
  188.  
  189.  
  190.  
  191. int get_the_files(name, number_found, found)
  192. char *name;
  193. int *number_found;
  194. char ***found;
  195. {
  196.      int retval;
  197.      int options;
  198.      
  199.      options = FIND_DELETED | FIND_CONTENTS;
  200.      if (recursive)
  201.       options |= RECURS_FIND_DELETED;
  202.      if (! dirsonly)
  203.       options |= RECURS_DELETED;
  204.      if (f_mounts)
  205.       options |= FOLLW_MOUNTPOINTS;
  206.      if (f_links)
  207.       options |= FOLLW_LINKS;
  208.      
  209.      retval = find_matches(name, number_found, found, options);
  210.      if (retval) {
  211.       error("find_matches");
  212.       return retval;
  213.      }
  214.  
  215.      return 0;
  216. }
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223. process_files(files, num)
  224. char **files;
  225. int num;
  226. {
  227.      int i;
  228.      filerec *leaf;
  229.      
  230.      for (i = 0; i < num; i++) {
  231.       if (add_path_to_tree(files[i], &leaf)) {
  232.            error("add_path_to_tree");
  233.            return -1;
  234.       }
  235.       free(files[i]);
  236.       if (! timed_out(leaf, current_time, timev)) {
  237.            free_leaf(leaf);
  238.            num--;
  239.            continue;
  240.       }
  241.       block_total += leaf->specs.st_blocks;
  242.      }
  243.      free((char *) files);
  244.      return(num);
  245. }
  246.  
  247.  
  248.  
  249.  
  250.  
  251. list_files()
  252. {
  253.      filerec *current;
  254.      char **strings;
  255.      int num;
  256.      int retval;
  257.      
  258.      strings = (char **) Malloc((unsigned) sizeof(char *));
  259.      num = 0;
  260.      if (! strings) {
  261.       set_error(errno);
  262.       error("Malloc");
  263.       return error_code;
  264.      }
  265.      current = get_root_tree();
  266.      if (retval = accumulate_names(current, &strings, &num)) {
  267.       error("accumulate_names");
  268.       return retval;
  269.      }
  270.      current = get_cwd_tree();
  271.      if (retval = accumulate_names(current, &strings, &num)) {
  272.       error("accumulate_names");
  273.       return retval;
  274.      }
  275.  
  276.      if (retval = sort_files(strings, num)) {
  277.       error("sort_files");
  278.       return retval;
  279.      }
  280.      
  281.      if (retval = unique(&strings, &num)) {
  282.       error("unique");
  283.       return retval;
  284.      }
  285.      
  286.      if (retval = column_array(strings, num, DEF_SCR_WIDTH, 0, 0, 2, 1, 0,
  287.                    1, stdout)) {
  288.       error("column_array");
  289.       return retval;
  290.      }
  291.      
  292.      for ( ; num; num--)
  293.       free(strings[num - 1]);
  294.      free((char *) strings);
  295.      return 0;
  296. }
  297.  
  298.  
  299. int sort_files(data, num_data)
  300. char **data;
  301. int num_data;
  302. {
  303.      qsort((char *) data, num_data, sizeof(char *), strcmp);
  304.  
  305.      return 0;
  306. }
  307.  
  308.  
  309. int unique(the_files, number)
  310. char ***the_files;
  311. int *number;
  312. {
  313.      int i, last;
  314.      int offset;
  315.      char **files;
  316.  
  317.      files = *the_files;
  318.      for (last = 0, i = 1; i < *number; i++) {
  319.       if (! strcmp(files[last], files[i])) {
  320.            free (files[i]);
  321.            free (files[i]);
  322.            files[i] = (char *) NULL;
  323.       }
  324.       else
  325.            last = i;
  326.      }
  327.      
  328.      for (offset = 0, i = 0; i + offset < *number; i++) {
  329.       if (! files[i])
  330.            offset++;
  331.       if (i + offset < *number)
  332.            files[i] = files[i + offset];
  333.      }
  334.      *number -= offset;
  335.      files = (char **) realloc((char *) files,
  336.                    (unsigned) (sizeof(char *) * *number));
  337.      if (! files) {
  338.       set_error(errno);
  339.       error("realloc");
  340.       return errno;
  341.      }
  342.  
  343.      *the_files = files;
  344.      return 0;
  345. }
  346.