home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / batch / cutils10.arj / RMPATH.C < prev    next >
C/C++ Source or Header  |  1991-10-17  |  14KB  |  451 lines

  1. /*+M, RmPath.c */
  2. /************************************************************************/
  3. /************************************************************************/
  4. /*                                    */
  5. /*    COPYRIGHT (C) G. KLYNE, 1991.    All rights reserved.        */
  6. /*                                    */
  7. /*    Permission to freely distribute this software, or use it    */
  8. /*    for any purpose, is granted provided that no charge is        */
  9. /*    levied for its distribution and this notice is retained        */
  10. /*    in all copies of the source code.                */
  11. /*                                    */
  12. /************************************************************************/
  13. /************************************************************************/
  14. /*                                    */
  15. /*                                    */
  16. /*    Module name        : RmPath                */
  17. /*    File name        : RmPath.c                */
  18. /*                                    */
  19. /*                                    */
  20. /*  AMENDMENT RECORD                            */
  21. /*  ================                            */
  22. /*                                    */
  23. /*  1.    V01.0A    19-Feb-1991    Graham Klyne                */
  24. /*    Program initially created.                    */
  25. /*                                    */
  26. /*                                    */
  27. /*  PROGRAM FUNCTION                            */
  28. /*  ================                            */
  29. /*                                    */
  30. /*    This program is a simple DOS utility which removes all files    */
  31. /*    in a directory, and attempts to remove all directories on the    */
  32. /*    path to that directory.                        */
  33. /*                                    */
  34. /*    The exit code is:                        */
  35. /*      0    No directory and/or file specified.            */
  36. /*      1    Files deleted but no directory specified.        */
  37. /*      2    Files deleted but no directories could be deleted.    */
  38. /*      3    Files and at least one directory removed.        */
  39. /*      4    Could not delete all files in directory.        */
  40. /*      6    Error in supplied path name.                */
  41. /*                                    */
  42. /*    This program assumes that the current default directory does    */
  43. /*    exist, and no attempt will be made to delete it.        */
  44. /*                                    */
  45. /*    Any filename and extension (as opposed to directory name) on    */
  46. /*    the command line is ignored:  all files in the indicated    */
  47. /*    directory are deleted (if possible).                */
  48. /*                                    */
  49. /*                                    */
  50. /************************************************************************/
  51. /************************************************************************/
  52. /*-M*/
  53.  
  54.  
  55. /************************************************************************/
  56. /*    External declarations used                    */
  57. /************************************************************************/
  58.  
  59. #define    LINT_ARGS
  60.  
  61. #include <ctype.h>
  62. #include <string.h>
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <direct.h>
  66. #include <io.h>
  67. #include <dos.h>
  68.  
  69. /************************************************************************/
  70. /*    External entry points declared in this module            */
  71. /************************************************************************/
  72.  
  73.     /*    No external entry points  */
  74.  
  75.  
  76. /************************************************************************/
  77. /*    Local definitions                        */
  78. /************************************************************************/
  79.  
  80. #define FALSE 0
  81. #define TRUE  1
  82.  
  83. /************************************************************************/
  84. /*    Local type declarations                        */
  85. /************************************************************************/
  86.  
  87. typedef struct FileDetail_str
  88.     {
  89.     char Context[21] ;    /* Search context for "FindNextFile"    */
  90.     char Attributes ;    /* File attributes            */
  91.     short int Time ;    /* Time file written HHHHHMMMMMMSSSSS    */
  92.     short int Date ;    /* Date file written YYYYYYYMMMMDDDDD    */
  93.     long int Size ;        /* File size in bytes            */
  94.     char Name[13] ;        /* File name and extension        */
  95.     }
  96.     FileDetail, *FileDetail_ptr ;
  97.  
  98. /************************************************************************/
  99. /*    Local variable declarations                    */
  100. /************************************************************************/
  101.  
  102.     /*    No local variables  */
  103.  
  104.  
  105. /*+F*/
  106. /************************************************************************/
  107. /*    *-FindFirstFile,    Find first file matching given specification    */
  108. /************************************************************************/
  109. /*
  110. /*    This function finds the first file matching a given specification.
  111. /*
  112. /*  PARAMETERS
  113. /*  ----------
  114. /*    ReqPath        points to a string containing the ambiguous file
  115. /*            name (including drive and path) to be matched.
  116. /*    ReqAttr        indicates the types of files to be located:
  117. /*              0x01    Include read-only files.
  118. /*              0x02    Include hidden files.
  119. /*              0x04    Include system files.
  120. /*              0x08    Include volume identifier file.
  121. /*              0x10    Include directory files.
  122. /*            Any combination of the above options may be
  123. /*            specified.
  124. /*    FilAttr        points to a "FileDetail" structure which receives
  125. /*            additional information about the file, and other data
  126. /*            required by subsequent calls of "FindNextFile".
  127. /*    FilSize        is the size of the supplied "FilBuff" buffer.
  128. /*    FilBuff        points to a buffer which receives the filename
  129. /*            (including drive and path) as a NULL-terminated
  130. /*            string.
  131. /*
  132. /*  RESULT
  133. /*  ------
  134. /*    The result returned is FALSE if no file is found, otherwise TRUE.
  135. /*
  136. /*  NOTES
  137. /*  -----
  138. /*    This routine assumes that the current DTA and the supplied file
  139. /*    details structure both lie in the default data segment.
  140. /*
  141. /*    If the serach is to include directories, the special files "."
  142. /*    and ".." may be returned.
  143. /*
  144. /*-F*/
  145.  
  146. int FindFirstFile
  147.       ( const char *ReqPath, int ReqAttr,
  148.     FileDetail *FilAttr,
  149.     int FilSize, char *FilBuff )
  150.     {
  151.     union REGS InpRegs, OutRegs ;
  152.     int SaveDTA ;
  153.     int Status ;
  154.     int Length ;
  155.     int i ;
  156.  
  157.     /*--------------------------------------------------------------*/
  158.     /*    Copy file path to result buffer                */
  159.     /*--------------------------------------------------------------*/
  160.  
  161.     Status = FALSE ;
  162.     Length = strlen( ReqPath ) ;
  163.     while ( ( Length > 0 ) &&
  164.         ( ReqPath[Length-1] != '\\' ) &&
  165.         ( ReqPath[Length-1] != '/'  ) ) Length-- ;
  166.     if ( Length+13 > FilSize )
  167.         {
  168.         printf( "RmPath: supplied path '%s' is too long\n", ReqPath ) ;
  169.         exit( 6 ) ;
  170.         }
  171.     strncpy( FilBuff, ReqPath, FilSize ) ;
  172.     FilBuff[Length] = '\0' ;
  173.  
  174.     /*--------------------------------------------------------------*/
  175.     /*    Save current DTA, and set new value            */
  176.     /*--------------------------------------------------------------*/
  177.  
  178.     InpRegs.x.ax = 0x2F00 ;
  179.     intdos( &InpRegs, &OutRegs ) ;
  180.     SaveDTA = OutRegs.x.bx ;
  181.  
  182.     InpRegs.x.ax = 0x1A00 ;
  183.     InpRegs.x.dx = FP_OFF( FilAttr ) ;
  184.     intdos( &InpRegs, &OutRegs ) ;
  185.  
  186.     /*--------------------------------------------------------------*/
  187.     /*    Find file                        */
  188.     /*--------------------------------------------------------------*/
  189.  
  190.     InpRegs.x.ax = 0x4E00 ;
  191.     InpRegs.x.cx = ReqAttr ;
  192.     InpRegs.x.dx = FP_OFF( ReqPath ) ;
  193.     intdos( &InpRegs, &OutRegs ) ;
  194.     if ( OutRegs.x.cflag == 0 ) Status = TRUE ;
  195.  
  196.     /*--------------------------------------------------------------*/
  197.     /*    Restore original DTA                    */
  198.     /*--------------------------------------------------------------*/
  199.  
  200.     InpRegs.x.ax = 0x1A00 ;
  201.     InpRegs.x.dx = SaveDTA ;
  202.     intdos( &InpRegs, &OutRegs ) ;
  203.  
  204.     /*--------------------------------------------------------------*/
  205.     /*    Sort out result                        */
  206.     /*--------------------------------------------------------------*/
  207.  
  208.     if ( Status )
  209.         {
  210.         i = 0 ;
  211.         while ( ( FilAttr->Name[i] != '\0' ) && ( i < 12 ) )
  212.         {
  213.         FilBuff[Length++] = FilAttr->Name[i++] ;
  214.         }
  215.         FilBuff[Length] = '\0' ;
  216.         }
  217.  
  218.     return Status ;
  219.     } ;    // End of function FindFirstFile
  220.  
  221.  
  222. /*+F*/
  223. /************************************************************************/
  224. /*    *-FindNextFile,    Find next file matching given specification    */
  225. /************************************************************************/
  226. /*
  227. /*    This function finds the next file matching a given specification,
  228. /*    following a previous call of "FindFirstFile" and possible calls
  229. /*    of this function.
  230. /*
  231. /*    Attributes for the required files are carried over from the
  232. /*    original call of "FindFirstFile".
  233. /*
  234. /*  PARAMETERS
  235. /*  ----------
  236. /*    ReqPath        points to a string containing the ambiguous file
  237. /*            name (including drive and path) to be matched.
  238. /*    FilAttr        points to a "FileDetail" structure which receives
  239. /*            additional information about the file, and other data
  240. /*            required by subsequent calls of "FindNextFile".
  241. /*    FilSize        is the size of the supplied "FilBuff" buffer.
  242. /*    FilBuff        points to a buffer which receives the filename
  243. /*            (including drive and path) as a NULL-terminated
  244. /*            string.
  245. /*
  246. /*  RESULT
  247. /*  ------
  248. /*    The result returned is FALSE if no file is found, otherwise TRUE.
  249. /*
  250. /*  NOTE
  251. /*  ----
  252. /*    This routine assumes that the current DTA and the supplied file
  253. /*    details structure both lie in the default data segment.
  254. /*
  255. /*-F*/
  256.  
  257. int FindNextFile
  258.       ( const char *ReqPath,
  259.     FileDetail *FilAttr,
  260.     int FilSize, char *FilBuff )
  261.     {
  262.     union REGS InpRegs, OutRegs ;
  263.     int SaveDTA ;
  264.     int Status ;
  265.     int Length ;
  266.     int i ;
  267.  
  268.     /*--------------------------------------------------------------*/
  269.     /*    Copy file path to result buffer                */
  270.     /*--------------------------------------------------------------*/
  271.  
  272.     Status = FALSE ;
  273.     Length = strlen( ReqPath ) ;
  274.     while ( ( Length > 0 ) &&
  275.         ( ReqPath[Length-1] != '\\' ) &&
  276.         ( ReqPath[Length-1] != '/'  ) ) Length-- ;
  277.     if ( Length+13 > FilSize )
  278.         {
  279.         printf( "RmPath: supplied path '%s' is too long\n", ReqPath ) ;
  280.         exit( 6 ) ;
  281.         }
  282.     strncpy( FilBuff, ReqPath, FilSize ) ;
  283.     FilBuff[Length] = '\0' ;
  284.  
  285.     /*--------------------------------------------------------------*/
  286.     /*    Save current DTA, and set new value            */
  287.     /*--------------------------------------------------------------*/
  288.  
  289.     InpRegs.x.ax = 0x2F00 ;
  290.     intdos( &InpRegs, &OutRegs ) ;
  291.     SaveDTA = OutRegs.x.bx ;
  292.  
  293.     InpRegs.x.ax = 0x1A00 ;
  294.     InpRegs.x.dx = FP_OFF( FilAttr ) ;
  295.     intdos( &InpRegs, &OutRegs ) ;
  296.  
  297.     /*--------------------------------------------------------------*/
  298.     /*    Find file                        */
  299.     /*--------------------------------------------------------------*/
  300.  
  301.     InpRegs.x.ax = 0x4F00 ;
  302.     intdos( &InpRegs, &OutRegs ) ;
  303.     if ( OutRegs.x.cflag == 0 ) Status = TRUE ;
  304.  
  305.     /*--------------------------------------------------------------*/
  306.     /*    Restore original DTA                    */
  307.     /*--------------------------------------------------------------*/
  308.  
  309.     InpRegs.x.ax = 0x1A00 ;
  310.     InpRegs.x.dx = SaveDTA ;
  311.     intdos( &InpRegs, &OutRegs ) ;
  312.  
  313.     /*--------------------------------------------------------------*/
  314.     /*    Sort out result                        */
  315.     /*--------------------------------------------------------------*/
  316.  
  317.     if ( Status )
  318.         {
  319.         i = 0 ;
  320.         while ( ( FilAttr->Name[i] != '\0' ) && ( i < 12 ) )
  321.         {
  322.         FilBuff[Length++] = FilAttr->Name[i++] ;
  323.         }
  324.         FilBuff[Length] = '\0' ;
  325.         }
  326.  
  327.     return Status ;
  328.     } ;    // End of function FindNextFile
  329.  
  330.  
  331. /*+T*/
  332. /************************************************************************/
  333. /*    *-main,            Main Program                */
  334. /************************************************************************/
  335. /*
  336. /*    This program reads commands from standard input and submits
  337. /*    them for execution, each in its own command shell.
  338. /*
  339. /*-T*/
  340.  
  341. void main( int argc, char *(argv[]), char *(envp[]) )
  342.     {
  343.     int Status ;
  344.     char DirPath[132] ;
  345.     char FilPath[144] ;
  346.     FileDetail FilAttr ;
  347.     int l ;
  348.     int r ;
  349.  
  350.     /*--------------------------------------------------------------*/
  351.     /*    Entry point here                    */
  352.     /*--------------------------------------------------------------*/
  353.  
  354.     Status = 0 ;
  355.  
  356.     if ( argc < 2 )
  357.         {
  358.         printf( "Usage:  RmPath path\n"
  359.         "               Remove all files in the indicated directory,\n"
  360.         "               and remove all directories on the path.\n\n"
  361.         "    Note:      Any filename specified in 'path' is ignored:\n"
  362.         "               removes ALL files in the given directory.\n" ) ;
  363.         printf( "\n"
  364.         "Exit status:   0: no file or directory specified.\n"
  365.         "               1: files deleted but no directory specified.\n"
  366.         "               2: files deleted but no directories removed.\n"
  367.         "               3: files and at least one directory removed.\n"
  368.         "               4: failed to delete all files in directory.\n"
  369.         "               6: error in supplied path.\n" ) ;
  370.         printf( "\n"
  371.         "Copyright (C) 1991 Graham Klyne.  All rights reserved.\n" ) ;
  372.         exit( 0 ) ;
  373.         }
  374.  
  375.     /*--------------------------------------------------------------*/
  376.     /*    Copy path to local buffer and force '*.*' filename    */
  377.     /*--------------------------------------------------------------*/
  378.  
  379.     l = strlen( argv[1] ) ;
  380.     if ( l >= 128 )
  381.         {
  382.         printf( "RmPath: supplied path '%s' is too long\n", argv[1] ) ;
  383.         exit( 6 ) ;
  384.         }
  385.     strcpy( DirPath, argv[1] ) ;
  386.  
  387.     while ( ( l > 0 ) &&
  388.         ( DirPath[l-1] != '\\' ) &&
  389.         ( DirPath[l-1] != '/' ) ) l-- ;
  390.  
  391.     DirPath[l++] = '*' ;
  392.     DirPath[l++] = '.' ;
  393.     DirPath[l++] = '*' ;
  394.     DirPath[l++] = '\0' ;
  395.  
  396.     /*--------------------------------------------------------------*/
  397.     /*    Delete files in specified directory            */
  398.     /*--------------------------------------------------------------*/
  399.  
  400.     Status = FindFirstFile( DirPath, 0, &FilAttr, 144, FilPath ) ;
  401.     while ( Status )
  402.         {
  403.         r = remove( FilPath ) ;
  404.         if ( r != 0 )
  405.         {
  406.         printf( "Failed to delete file '%s'\n", FilPath ) ;
  407.         exit( 4 ) ;
  408.         }
  409.         Status = FindNextFile( DirPath, &FilAttr, 144, FilPath ) ;
  410.         }
  411.  
  412.     /*--------------------------------------------------------------*/
  413.     /*    Remove directories on path                */
  414.     /*--------------------------------------------------------------*/
  415.  
  416.     Status = 1 ;        // No directory
  417.  
  418.     while ( l > 0 )
  419.         {
  420.         while ( ( l > 0 ) &&
  421.             ( DirPath[l] != '\\' ) &&
  422.             ( DirPath[l] != '/' ) ) l-- ;
  423.         if ( l > 0 )
  424.         {
  425.         DirPath[l] = '\0' ;
  426.         r = rmdir( DirPath ) ;
  427.         if ( r != 0 )
  428.             {
  429.             if ( Status == 1 )
  430.             {
  431.             printf( "Failed to remove directory '%s'\n", DirPath ) ;
  432.             Status = 2 ;
  433.             }
  434.             break ;
  435.             }
  436.         Status = 3 ;
  437.         }
  438.         }
  439.  
  440.     /*--------------------------------------------------------------*/
  441.     /*    Exit                            */
  442.     /*--------------------------------------------------------------*/
  443.  
  444.     exit( Status ) ;
  445.  
  446.     } ;    /* End of procedure main */
  447.  
  448. /************************************************************************/
  449. /*    End of module RmPath                        */
  450. /************************************************************************/
  451.