home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR24 / DELTREE2.ZIP / DELTREE.C < prev    next >
Text File  |  1993-11-07  |  9KB  |  363 lines

  1. /************************************************************************
  2.    DELTREE2 1.0 1993 Russ Herman <rwh@gov.on.ca>
  3.  
  4.    This program is pretty much a clone of DOS6 DELTREE for MDOS and OS/2,
  5.    including HPFS filesystems. However, DELTREE2 may remove files
  6.    in different order and return different error codes for failure
  7.    than DELTREE does.
  8.  
  9.    Compile with BC++ 1.0 for OS/2 and BC++ 3.1 for DOS; run as DELTREE
  10.    under COMMAND.COM and DELTREE2 under CMD.EXE
  11.  
  12.    Added /f toggle for forcedelete in OS/2 version.
  13.  
  14.    It returns an error code (>0) if it fails, or 0 if everything goes
  15.    well.
  16. ************************************************************************/
  17.  
  18. #ifdef __OS2__
  19. #define INCL_DOSMISC
  20. #define INCL_DOSFILEMGR
  21. #include <os2.h>
  22. #define INCL_ERRORS
  23. #include <bseerr.h>
  24. int CHMOD_NORMAL(char *, int, int);
  25. #define FNAME find.achName[0]
  26. #define FATTR find.attrFile
  27. #define FILE_ABNORMAL (FILE_READONLY | FILE_SYSTEM | FILE_HIDDEN | FILE_ARCHIVED)
  28. #define CHDIR(a) DosSetCurrentDir(a)
  29. #define NOMOREFILES(x) (x == ERROR_NO_MORE_FILES)
  30. #else
  31. #include <dir.h>
  32. #define FALSE 0
  33. #define TRUE !FALSE
  34. #define HDIR unsigned long
  35. #define ULONG unsigned long
  36. #define FNAME find.ff_name[0]
  37. #define FATTR find.ff_attrib
  38. #define FILE_ABNORMAL (FA_RDONLY | FA_SYSTEM | FA_HIDDEN | FA_ARCH)
  39. #define CHDIR(a) chdir(a)
  40. #define MUST_HAVE_DIRECTORY FA_DIREC
  41. #define FILE_DIRECTORY FA_DIREC
  42. #define HDIR_CREATE 0x0FFFF
  43. #define DosFindFirst(a,b,c,d,e,f,g) findfirst(a, d, c)
  44. #define DosFindNext(a,b,c,d) findnext(b)
  45. #define DosFindClose(x) /* */
  46. #define DosDeleteDir(x) rmdir(x)
  47. #define DosDelete(x) unlink(x)
  48. #define NOMOREFILES(x) ((x != 0) && (_doserrno == ENMFILE))
  49. #define FILEFINDBUF3 struct ffblk
  50. #endif
  51. #include <dos.h>
  52. #include <io.h>
  53. #include <errno.h>
  54. #include <direct.h>
  55. #include <stdio.h>
  56. #include <conio.h>
  57. #include <process.h>
  58. #include <string.h>
  59. #include <ctype.h>
  60. #include <stdlib.h>
  61. #include <assert.h>
  62. #define DOSFINDBAD(x) assert((x == 0) || NOMOREFILES(x))
  63.  
  64. void main(int,char **);
  65. int nextdir(int);
  66. int getyn(void);
  67. #ifdef DBG
  68. int nextdirdepth = 0;
  69. char *dbgdel[]={"","force"};
  70. #endif
  71. int findret, forcedel = 0;
  72. #ifdef STKLEN
  73. extern unsigned _stklen=STKLEN;
  74. #endif
  75.  
  76. void main(int argc,char *argv[])
  77. {
  78.     char *basedir, *p;
  79.     FILEFINDBUF3 find; HDIR dirhandle; ULONG srch_cnt;
  80.     int newdrive, urdrive, rootdir, dotdir, dotdotdir;
  81.     int asking=TRUE, retcode=TRUE;
  82.  
  83.     while (--argc)  {
  84.     ++argv;
  85.     if ((argv[0][0] == '/') || (argv[0][0] == '-')) {
  86.         switch(toupper(argv[0][1])) {
  87.         case 'Y': asking = FALSE; break;
  88.  
  89. #ifdef __OS2__
  90.         case 'F': forcedel = 1; break;
  91. #endif
  92.         default : printf("Invalid switch - %c\n", argv[0][1]); abort();
  93.         }
  94.         }
  95.     else
  96.         break;
  97.     }
  98.     if (!argc) {
  99.     puts("DELTREE2 v1.0\nRequired parameter missing");
  100.     abort();
  101.     }
  102.     urdrive = getdisk();
  103. #ifdef __OS2__
  104.     DosError(FERR_DISABLEHARDERR);
  105. #endif
  106.  
  107.     /* Process each command line parameter */
  108.     while (argc--) {
  109.     basedir = *argv++;
  110.     if (asking) {
  111.         printf("Delete directory \"%s\" and all its subdirectories? [yn] ",
  112.            basedir);
  113.         if (!getyn())
  114.         continue;
  115.         }
  116.     setdisk(urdrive);
  117.     srch_cnt = 1; dirhandle = HDIR_CREATE;
  118.     findret = DosFindFirst(basedir, &dirhandle, MUST_HAVE_DIRECTORY,
  119.                    &find, sizeof(find), &srch_cnt,
  120.                    FIL_STANDARD);
  121.     if (findret == 0) {
  122. #ifndef __OS2__
  123.     dirhandle = 1;
  124. #endif
  125.         DosFindClose(dirhandle);
  126.         }
  127.     else
  128.         continue;  /* no such directory, goto next argument */
  129.     if (basedir[1] == ':') {
  130.         /* Need to change drives */
  131.         newdrive = toupper(basedir[0])-'A';
  132.         if (newdrive != urdrive) {
  133.         setdisk(newdrive);
  134.         if (newdrive != getdisk())
  135.             continue;  /* cannot switch drives, goto next argument */
  136.            }
  137.         basedir+=2;
  138.         }
  139.     assert (NULL != (p=getcwd(NULL, MAXPATH)));
  140.     dotdir = !strcmp(basedir, ".") ||
  141.          !strcmp(basedir, p+2);
  142.     free(p);
  143.     dotdotdir = !strcmp(basedir, "..");
  144.     rootdir = (!strcmp(basedir,"\\") ||
  145.            !strcmp(basedir,"/"));
  146.     printf("Deleting %s...\n", basedir);
  147.     if (rootdir) {
  148.         CHDIR("\\");
  149.         retcode &= nextdir(FALSE);
  150.         }
  151.     else if (dotdir) {
  152.         retcode &= nextdir(FALSE);
  153.         }
  154.     else if (dotdotdir) {
  155.         CHDIR("..");
  156.         retcode &= nextdir(FALSE);
  157.         }
  158.     else {
  159.         if (CHDIR(basedir))
  160.         continue /* cannot change directory - goto next argument */;
  161.         retcode &= nextdir(FALSE);
  162.         CHDIR("..");
  163. #ifndef DBG
  164.         retcode &= (0 == DosDeleteDir(basedir));
  165. #endif
  166.         }
  167.     /* goto next argument */
  168.     }
  169.     setdisk(urdrive);
  170.     exit(retcode ? 0 : 1);
  171.     }
  172.  
  173. int nextdir(int toplev)
  174. {
  175. #ifdef __OS2__
  176.     FILEFINDBUF3 find;
  177.     ULONG srch_cnt;
  178.     HDIR dirhandle;
  179.     APIRET findret;
  180. #else
  181.     struct ffblk find;
  182.     ULONG srch_cnt;
  183.     HDIR dirhandle;
  184.     int findret;
  185. #endif
  186.     int retcode=TRUE, c, rc, nomore;
  187.  
  188. #ifdef DBG
  189.     printf("entered nextdir %d\n", nextdirdepth++);
  190. #endif
  191.  
  192.     srch_cnt = 1; dirhandle = HDIR_CREATE;
  193.     findret =  DosFindFirst("*.*", &dirhandle, MUST_HAVE_DIRECTORY,
  194.                  &find, sizeof(find), &srch_cnt,
  195.                  FIL_STANDARD);
  196. #ifdef __OS2__
  197.     nomore = (findret == ERROR_NO_MORE_FILES);
  198. #else
  199.     nomore = ((findret == -1) && (_doserrno == ENMFILE));
  200.     if (!nomore)
  201.     dirhandle = 1;
  202. #endif
  203. #ifdef DBG
  204.     printf("DosFindFirstDir returned %d(%d)\n", (int) findret, nomore);
  205.     DOSFINDBAD(findret);
  206.     assert(dirhandle != HDIR_CREATE);
  207. #endif
  208.     if (nomore)
  209.     findret = 0;
  210.     while (!nomore) {
  211.     if ((findret == 0) && (FNAME != '.') && (FATTR & FILE_DIRECTORY)) {
  212.         /* descend next level */
  213.         if (toplev)
  214.         printf("Deleting %s...\n", &FNAME);
  215. #ifdef DBG
  216.         printf("descending to scan %s\n", &FNAME);
  217.         assert(0 == CHDIR(&FNAME));
  218.         retcode &= nextdir(FALSE);
  219.         /* ascend level and onto next directory */
  220.         assert(0 == CHDIR(".."));
  221.         printf("removing dir  %s\n", &FNAME);
  222. #else
  223.         /* descend level */
  224.         if (CHDIR(&FNAME)) {
  225.         /* descent impossible */
  226.         retcode = FALSE;
  227.         }
  228.         else {
  229.         /* process next directory */
  230.         retcode &= nextdir(FALSE);
  231.         /* ascend level */
  232.         if (CHDIR("..")) {
  233.             /* Something woefully wrong ... */
  234.             if (dirhandle != HDIR_CREATE) {
  235.             DosFindClose(dirhandle);
  236.             dirhandle = HDIR_CREATE;
  237.             }
  238.             return(FALSE);
  239.             }
  240.         else {
  241.             /* delete empty directory */
  242.             retcode &= (0 == DosDeleteDir(&FNAME));
  243.             }
  244.         }
  245. #endif
  246.         }
  247.     /* Position to next entry */
  248.     findret = DosFindNext(dirhandle, &find, sizeof(find), &srch_cnt);
  249. #ifdef __OS2__
  250.     nomore = (findret == ERROR_NO_MORE_FILES);
  251. #else
  252.     nomore = ((findret == -1) && (_doserrno == ENMFILE));
  253. #endif
  254. #ifdef DBG
  255.     printf("DosFindNextDir returned %d(%d)\n", (int) findret, nomore);
  256.     DOSFINDBAD(findret);
  257. #endif
  258.     if (nomore)
  259.         findret = 0;
  260.     /* Process next entry */
  261.     continue;
  262.     }
  263.     if (dirhandle != HDIR_CREATE) {
  264.     DosFindClose(dirhandle);
  265.     dirhandle = HDIR_CREATE;
  266.     }
  267.     srch_cnt = 1;
  268.  
  269. /* Now delete the files */
  270.     findret = DosFindFirst("*.*",&dirhandle, FILE_ABNORMAL, &find,
  271.                 sizeof(find), &srch_cnt, FIL_STANDARD);
  272. #ifdef __OS2__
  273.     nomore = (findret == ERROR_NO_MORE_FILES);
  274. #else
  275.     nomore = ((findret == -1) && (_doserrno == ENMFILE));
  276.     if (!nomore)
  277.     dirhandle = 1;
  278. #endif
  279. #ifdef DBG
  280.     printf("DosFindFirstFile returned %d(%d)\n", (int) findret, nomore);
  281.     DOSFINDBAD(findret);
  282. #endif
  283.     if (nomore)
  284.     findret = 0;
  285.  
  286.      while (!nomore) {
  287.      if (findret == 0) {
  288.         /* Process if file OK */
  289.         if (toplev)
  290.         printf("Deleting %s...\n", &FNAME);
  291. #ifdef DBG
  292.         if (!findret && (FATTR & FILE_ABNORMAL))
  293.         printf("making normal and %sdeleting %s\n",
  294.                dbgdel[forcedel], &FNAME);
  295.         else
  296.         printf("%sdeleting %s\n",
  297.                dbgdel[forcedel], &FNAME);
  298. #else
  299.         if (!findret && (FATTR & FILE_ABNORMAL))
  300.         rc = _chmod(&FNAME, 1, 0);
  301.         if (!rc) {
  302. #ifdef __OS2__
  303.         if (forcedel)
  304.             retcode &= (0 == DosForceDelete(&FNAME));
  305.         else
  306. #endif
  307.             retcode &= (0 == DosDelete(&FNAME));
  308.         }
  309.         else
  310.         retcode = FALSE;
  311. #endif
  312.         }
  313.     /* Advance to next file */
  314.     findret = DosFindNext(dirhandle, &find, sizeof(find), &srch_cnt);
  315. #ifdef __OS2__
  316.     nomore = (findret == ERROR_NO_MORE_FILES);
  317. #else
  318.     nomore = ((findret == -1) && (_doserrno == ENMFILE));
  319. #endif
  320. #ifdef DBG
  321.     printf("DosFindNextFile returned %d(%d)\n", (int) findret, nomore);
  322.     DOSFINDBAD(findret);
  323. #endif
  324.     if (nomore)
  325.         findret = 0;
  326.     /* Process next file */
  327.     continue;
  328.     }
  329.     if (dirhandle != HDIR_CREATE)
  330.     DosFindClose(dirhandle);
  331. #ifdef DBG
  332.     printf("leaving nextdir %d\n", --nextdirdepth);
  333. #endif
  334.     return(retcode);
  335.     }
  336.  
  337. int getyn()
  338. {
  339.     char response[2], c[2];
  340.  
  341.     /* Accept only y<ret>, Y<ret>, n<ret>, N<ret> */
  342.     while (!((response[1] == '\r') &&
  343.         ((response[0] == 'N') ||
  344.          (response[0] == 'Y')))) {
  345.     response[0] = response[1]; c[0] = c[1];
  346.     response[1] = toupper(c[1]=getch());
  347.     if (isprint(c[1])) {
  348.         putch(c[1]);
  349.         putch('\b');
  350.         }
  351.     }
  352.     putch('\r'); putch('\n');
  353.     return(response[0] == 'Y');
  354. }
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.