home *** CD-ROM | disk | FTP | other *** search
/ The UNIX CD Bookshelf / OREILLY_TUCB_UNIX_CD.iso / upt / examples / SOURCES / DELETE / PART02.Z / PART02 / lsdel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-24  |  7.3 KB  |  354 lines

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