home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / directry / mv / rm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  8.1 KB  |  302 lines

  1. /*
  2.    8-Sep-86 16:13:37-PDT,7276;000000000000
  3.    Return-Path: <pwu@unix.macc.wisc.edu>
  4.    Received: FROM UNIX.MACC.WISC.EDU BY B.ISI.EDU WITH TCP ; 8 Sep 86 16:10:31 PDT
  5.    Received: by unix.macc.wisc.edu;
  6.              id AA05007; 4.12/5; Mon, 8 Sep 86 17:32:42 cdt
  7.    Date: Mon, 8 Sep 86 17:32:42 cdt
  8.    From: Peter Wu <pwu@unix.macc.wisc.edu>
  9.    Message-Id: <8609082232.AA05007@unix.macc.wisc.edu>
  10.    To: info-ibmpc-request@mosis
  11.    Subject: rm.c
  12. */
  13.  
  14. /* rm - removes everything you got
  15. ** Written by Peter Wu @ Faculty Support Center, MACC
  16. ** University of Wisconsin - Madison. August 1986.
  17. */
  18. #include "dta.h"
  19. #include <conio.h>
  20. #include <ctype.h>
  21. #include "date.h"
  22.  
  23. char getkey();
  24.  
  25. main(argc, argv)
  26. int argc;
  27. char *argv[];
  28. {
  29.   int brgc, optc, i, status, mask;
  30.   char *brgv[40], opt[26], *t, path[200], c;
  31.  
  32.   optc = 0;
  33.   brgc = 0;  /* my argc */
  34.  
  35.   for (i=0; i < 26; i++) {  /* clear options flags */
  36.     opt[i] = 0;
  37.   };
  38.  
  39.   for (i=1; i < argc; i++) {  /* separate options and arguments */
  40.     if ((*argv[i] == '/') || (*argv[i] == '-')) {
  41.       t = argv[i] + 1;
  42.       while ((c = *t++) != '\0') {
  43.         if (isalpha(c)) {
  44.           opt[tolower(c) - 'a'] = 1;
  45.         };
  46.       };
  47.     } else {
  48.       brgv[brgc++] = argv[i];
  49.     };
  50.   };
  51.  
  52.   if (brgc == 0) {
  53.     putn("Usage: RM <filespec>\15\n",
  54.          "<filespec> can have wild cards and attributes /f /d /h; E.g:\15\n",
  55.          "  *.* or *.*/f  selects all visible file\15\n",
  56.          "  *.*/h or *.*/hf  selects all visible and invisible files\15\n",
  57.          "  *.*/d  selects all sub-directories\15\n\n",
  58.          "For each file/sub-directory found, you will be prompted for\15\n",
  59.          "one of the following actions:\15\n",
  60.          "   y - yes, delete this file\15\n",
  61.          "   Y - Yes, delete this sub-directory\15\n",
  62.          "   n - no, leave this file/sub-directory alone\15\n",
  63.          "   l - list all the rest of the files/sub-directories\15\n",
  64.          "   Z - delete ALL the rest of the files/sub-directories\15\n",
  65.          "   e - enter this sub-directory\15\n",
  66.          "   x - exit current sub-directory\15\n",
  67.          "   q - quit now\15\n\n",
  68.          "Version 2.00 made ", date, ".\15\n",
  69.          "Please report problems to Peter Wu.\15\n",
  70.          0);
  71.     exit(0);
  72.   }
  73.  
  74.   /* process parameters */
  75.   for (i=0; i < brgc; i++) {
  76.     strcpy(path, brgv[i]);
  77.     mask = extype(path);
  78.     mask |= normal(path);
  79.     if ((mask & (A_FIL | A_DIR)) == 0) {
  80.       mask |= A_FIL;  /* default is remove files only */
  81.     }
  82.     rm(1, 1, mask, path);
  83.   }
  84. }
  85.  
  86. rm(confirm, echo, mask, path)  /* use normalized path only */
  87. int confirm, mask;
  88. char *path;
  89. {
  90.   char headp[200], fullp[200], c;
  91.   int status;
  92.   union dtbuf mydta;
  93.  
  94.   strcpy(headp,path);
  95.   chopath(headp);  /* cut off the tail (might be wild-cards) */
  96.  
  97.   status = ffmf(path, mask, &mydta);
  98.   if (status) {  /* not found; probably empty directory */
  99.     return 1;  /* let the caller print out the error message */
  100.   }
  101.  
  102.   do {  /* for all matching files */
  103.  
  104.     strcpy(fullp, headp);
  105.     catpath(fullp, mydta.dos.fn);  /* now fullp has the expanded name */
  106.  
  107.     do {
  108.  
  109.       if (confirm | echo) {  /* echo files to be deleted */
  110.         cputs(fullp);
  111.         if (mydta.dos.attr & A_DIR) {
  112.           cputs(" <DIR>");
  113.         }
  114.         if (mydta.dos.attr & (A_HID | A_SYS)) {
  115.           cputs(" (hidden)");
  116.         }
  117.       }
  118.  
  119.       if (confirm) {  /* ask for confirmation */
  120.  
  121.         status = 0;
  122.         if (mydta.dos.attr & A_DIR) {  /* sub-dir */
  123.           cputs(" (Y/n/e/x/l/Z/q; ? for help): ");
  124.           c = getkey("YynlxqeZ?");
  125.         } else {  /* file */
  126.           cputs(" (y/n/x/l/Z/q; ? for help): ");
  127.           c = getkey("YynlxqZx?");
  128.         }
  129.  
  130.         switch (c) {
  131.  
  132.           case '?':
  133.             putn("\15\n",
  134.                  "Y - Yes, delete this sub-directory and its content\15\n",
  135.                  "y - yes, delete this file\15\n",
  136.                  "n - no, skip this file/sub-directory\15\n",
  137.                  "e - enter this sub-directory\15\n",
  138.                  "x - exit current sub-directory\15\n",
  139.                  "l - list all the rest of the files/sub-directories\15\n",
  140.                  "Z - delete ALL the rest without further prompts\15\n",
  141.                  "q - quit to DOS now\15\n",
  142.                  0);
  143.                  cputs("\n");
  144.             break;
  145.  
  146.           case 'Z':
  147.             putn("\15\n",
  148.                "Really delete ALL the remaning files/sub-directories (Y/N)? ",
  149.                0);
  150.             c = getkey("YNn");
  151.             if (c == 'Y') {
  152.               confirm = 0;  /* no more confirmation request */
  153.               status = 1;  /* exit loop */
  154.             }
  155.             cputs("\15\n");
  156.             break;
  157.  
  158.           case 'q':
  159.             cputs("\15\nquiting to DOS\15\n");
  160.             exit(0);
  161.  
  162.           case 'x':
  163.             cputs("\15\n");
  164.             return 2;  /* exit current directory */
  165.  
  166.           case 'y':
  167.             if (mydta.dos.attr & A_DIR) { /* can't delete sub-dir with 'y' */
  168.               cputs(" use Y to delete sub-directory\15\n");
  169.             } else {  /* delete this file */
  170.               putch(' ');  /* move the cursor */
  171.               status = 1;  /* delete */
  172.             }
  173.             break;
  174.  
  175.           case 'Y':
  176.             if (mydta.dos.attr & A_DIR) {
  177.               putch(' ');  /* move the cursor */
  178.               status = 1;  /* delete */
  179.             } else {  /* can't delete file with 'Y' */
  180.               cputs(" use y to delete file\15\n");
  181.             }
  182.             break;
  183.  
  184.           case 'n':
  185.             status = 2;
  186.             break;
  187.  
  188.           case 'l':
  189.             cputs("\15\n");
  190.             ls(mydta);
  191.             break;
  192.  
  193.           case 'e':
  194.             cputs(" entering sub-directory\15\n\n");
  195.             catpath(fullp,"*.*");
  196.             if (rm(1,1,A_MASK,fullp) == 1) {  /* empty */
  197.               cputs("This sub-directory is empty. ");
  198.             }
  199.             chopath(fullp);
  200.             cputs("Returning to previous directory.\15\n\n");
  201.             break;
  202.  
  203.           default:  /* what did I miss? */
  204.             cputs("invalid key\15\n");
  205.         }
  206.  
  207.       } else {  /* confirm == 0 */
  208.         status = 1;
  209.       }
  210.  
  211.     } while (!status);
  212.  
  213.     /* status == 1 delete; status == 2 don't delete */
  214.  
  215.     if (status == 1) {  /* delete */
  216.       if (mydta.dos.attr & A_DIR) {  /* delete sub-directory */
  217.         /* check if fullp is parent of current path */
  218.  
  219.         /* call rm recursively to remove stuff */
  220.         catpath(fullp,"*.*");
  221.         rm(0,0,A_MASK,fullp);  /* no confirmation for this */
  222.         chopath(fullp);  /* cut off the "*.*" */
  223.         status = rmdir(fullp);
  224.         if (echo || confirm) {
  225.           if (status) {
  226.             cputs(" can't delete\15\n");
  227.           } else {
  228.             cputs(" Deleted\15\n");
  229.           }
  230.         }
  231.  
  232.       } else {  /* delete files */
  233.  
  234.         status = unlink(fullp);
  235.         if (echo || confirm) {
  236.           if (status) {
  237.             cputs(" can't delete\15\n");
  238.           } else {
  239.             cputs(" deleted\15\n");
  240.           }
  241.         }
  242.       }
  243.  
  244.     } else {
  245.       cputs(" not deleted\15\n");
  246.     }
  247.  
  248.     status = fnmf(&mydta);
  249.   } while (status == 0);
  250.  
  251.   return 0;
  252. }
  253.  
  254. ls(cdta)  /* list the rest of the files */
  255. union dtbuf cdta;
  256. {
  257.   int i, status, col, slen;  /* column */
  258.  
  259.   col = 0;
  260.   do {  /* list the current one also */
  261.     col++;
  262.     slen = strlen(cdta.dos.fn);
  263.     cputs(cdta.dos.fn);
  264.     if (cdta.dos.attr & A_DIR) {
  265.       putch('\\');
  266.       slen++;
  267.     };
  268.  
  269.     if (col < 5) {
  270.       for (i=slen; i < 16; i++) {
  271.         putch(' ');
  272.       }
  273.     } else {
  274.       cputs("\15\n");
  275.       col = 0;
  276.     }
  277.     status = fnmf(&cdta);
  278.   } while (!status);
  279.  
  280.   if (col) {  /* complete last line */
  281.     cputs("\15\n");
  282.   }
  283. }
  284.  
  285. char getkey(valid)  /* wait for valid key and echo it */
  286. char *valid;
  287. {
  288.   char c;
  289.   int i;
  290.  
  291.   do {
  292.     c = getch();
  293.     i = index(valid,c);
  294.     if (i > -1) {
  295.       putch(c);  /* echo valid key */
  296.       return c;
  297.     } else {  /* beep at invalid key */
  298.       putch(7);
  299.     }
  300.   } while (1);
  301. }
  302.