home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / SNIP9404.ZIP / RM_ALL.C < prev    next >
C/C++ Source or Header  |  1994-04-03  |  6KB  |  223 lines

  1. /*
  2. **  Remove all files and (optionally) subdirectories
  3. **
  4. **  public domain demo by Bob Stout
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <io.h>
  11. #include <dos.h>
  12. #include <ctype.h>
  13.  
  14. #define LAST_CHAR(str) (str[strlen(str) - 1])
  15. #define MAX_PATH 80
  16.  
  17. #ifdef __TURBOC__
  18.  #include <dir.h>
  19.  #include <io.h>
  20.  #define FAR far
  21.  #define find_1st(n,a,b) (findfirst((n),(b),(a)))
  22.  #define find_nxt(b) (findnext(b))
  23.  #define find_t ffblk
  24.  #define name ff_name
  25.  #define attrib ff_attrib
  26.  #define _A_SUBDIR FA_DIREC
  27. #else
  28.  #include <direct.h>
  29.  #include <stdarg.h>
  30.  #define FAR _far
  31.  #define find_1st(n,a,b) (_dos_findfirst((n),(a),(b)))
  32.  #define find_nxt(b) (_dos_findnext(b))
  33.  
  34.  #ifndef FA_RDONLY
  35.   #define FA_RDONLY _A_RDONLY
  36.  #endif
  37.  
  38.  #ifndef FA_HIDDEN
  39.   #define FA_HIDDEN _A_HIDDEN
  40.  #endif
  41.  
  42.  #ifndef FA_SYSTEM
  43.   #define FA_SYSTEM _A_SYSTEM
  44.  #endif
  45.  
  46.  #if (defined(_MSC_VER) && (_MSC_VER >= 700)) || (defined(__SC__))
  47.   // Make FP_xxx macros lvalues as in older versions
  48.   #undef FP_SEG
  49.   #undef FP_OFF
  50.   #define FP_SEG(fp)    ((unsigned)((unsigned long)(fp) >> 16))
  51.   #define FP_OFF(fp)    ((unsigned)(fp && 0xffff))
  52.  #endif
  53.  
  54. #endif
  55.  
  56. /* Select one of the following - remove() is ANSI       */
  57.  
  58. #define rmfunc remove
  59. /* #define rmfunc unlink */
  60.  
  61. #define show(s) fputs((s), stderr)
  62.  
  63. typedef enum {ERROR = -1, SUCCESS, FALSE = 0, TRUE} LOGICAL;
  64. LOGICAL recurse = FALSE, gobble = FALSE, ignore = FALSE;
  65.  
  66. char *mask = "*.*";
  67.  
  68. /*
  69. **  Clean all files from a directory
  70. */
  71.  
  72. void clean_dir(char *path)
  73. {
  74.       char rmpath[MAX_PATH], *rmfile;
  75.       struct find_t fbuf;
  76.       unsigned attrib = (ignore) ? 0xff : 0;
  77.  
  78.       strcpy(rmpath, path);
  79.       if ('\\' != LAST_CHAR(rmpath))
  80.             strcat(rmpath, "\\");
  81.       rmfile = &rmpath[strlen(rmpath)];
  82.       strcpy(rmfile, mask);
  83.       if (0 == find_1st(rmpath, attrib, &fbuf)) do
  84.       {
  85.             strcpy(rmfile, fbuf.name);
  86.             if (ignore)
  87.             {
  88.                   union REGS regs;
  89.                   struct SREGS sregs;
  90.  
  91.                   regs.x.ax = 0x4300;
  92.                   regs.x.dx = FP_OFF((char FAR *)rmpath);
  93.                   segread(&sregs);
  94.                   sregs.ds  = FP_SEG((char FAR *)rmpath);
  95.                   intdosx(®s, ®s, &sregs);
  96.                   if (!regs.x.cflag)
  97.                   {
  98.                         regs.x.ax  = 0x4301;
  99.                         regs.x.cx &= ~(FA_RDONLY | FA_HIDDEN | FA_SYSTEM);
  100.                         intdosx(®s, ®s, &sregs);
  101.                         if (regs.x.cflag)
  102.                               printf("unable to delete %s\n", rmpath);
  103.                   }
  104.             }
  105.             rmfunc(rmpath);
  106.             printf("deleting %s\n", rmpath);
  107.       } while (0 == find_nxt(&fbuf));
  108. }
  109.  
  110. /*
  111. **  Process directories
  112. */
  113.  
  114. void do_dir(char *path)
  115. {
  116.       char search[MAX_PATH], new[MAX_PATH];
  117.       struct find_t ff;
  118.  
  119.       strcpy(search, path);
  120.       if ('\\' != LAST_CHAR(search))
  121.             strcat(search, "\\");
  122.       strcat(search, "*.*");
  123.       if (SUCCESS == find_1st(search, 0xff, &ff)) do
  124.       {
  125.             if (ff.attrib & _A_SUBDIR && '.' != *ff.name)
  126.             {
  127.                   strcpy(new, path);
  128.                   if ('\\' != LAST_CHAR(new))
  129.                         strcat(new, "\\");
  130.                   strcat(new, ff.name);
  131.                   do_dir(new);
  132.             }
  133.       } while (SUCCESS == find_nxt(&ff));
  134.       clean_dir(path);
  135.       if (gobble)
  136.             rmdir(path);
  137. }
  138.  
  139. /*
  140. **  Tell 'em they messed up
  141. */
  142.  
  143. void usage(LOGICAL errstat)
  144. {
  145.       if (errstat)
  146.             fputc('\a', stderr);
  147.       show("Usage: RM_ALL directory [...directory] [-eFNAME.EXT] [-rgi?]\n");
  148.       show("switches: -eFNAME.EXT  Remove only files matching mask "
  149.             "(default is \"-e*.*\")\n");
  150.       show("          -r           Recurse subdirectories\n");
  151.       show("          -g           Gobble (delete) empty subdirectories\n");
  152.       show("          -i           Ignore special file attributes "
  153.             "(CAUTION!)\n");
  154.       show("          -?           Display help (this message)\n");
  155.       exit(errstat);
  156. }
  157.  
  158. /*
  159. **  RM_ALL - Deletes all files and (optionally) subdirectories
  160. */
  161.  
  162. int main(int argc, char *argv[])
  163. {
  164.       int i, j;
  165.       LOGICAL found_dir = FALSE;
  166.       void (*clean_func)(char *) = clean_dir;
  167.  
  168.       for (i = 1; i < argc; ++i)          /* Check for switches         */
  169.       {
  170.             if (NULL == strchr("-/", *argv[i]))
  171.                   continue;               /* Assume it's a filename     */
  172.             for (j = 1; argv[i][j] ; ++j) /* Traverse nested switches   */
  173.             {
  174.                   switch (toupper(argv[i][j]))
  175.                   {
  176.                   case 'R':
  177.                         clean_func = do_dir;
  178.                         break;
  179.  
  180.                   case 'G':
  181.                         gobble = TRUE;
  182.                         break;
  183.  
  184.                   case 'I':
  185.                         ignore = TRUE;
  186.                         break;
  187.  
  188.                   case '?':
  189.                         puts("***help***");
  190.                         usage(FALSE);
  191.                         break;
  192.  
  193.                   case 'E':
  194.                         if (0 == strlen(&argv[i][++j]))
  195.                         {
  196.                               puts("***no file***");
  197.                               usage(ERROR);                 /* Oops     */
  198.                         }
  199.                         mask = strupr(&argv[i][j]);
  200.                         j += strlen(&argv[i][j]) - 1; /* End of switch  */
  201.                         break;
  202.  
  203.                   default:
  204.                         puts("***default***");
  205.                         usage(ERROR);
  206.                   }
  207.             }
  208.       }
  209.       for (i = 1; i < argc; ++i)          /* Scan filenames             */
  210.       {
  211.             if (strchr("/-", *argv[i]))
  212.                   continue;
  213.             found_dir = TRUE;
  214.             clean_func(argv[i]);
  215.       }
  216.       if (!found_dir)
  217.       {
  218.             puts("***not found***");
  219.             usage(TRUE);
  220.       }
  221.       else  return 0;
  222. }
  223.