home *** CD-ROM | disk | FTP | other *** search
/ TopWare Tools / TOOLS.iso / tools / top1288 / arjwalk.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-12  |  14.4 KB  |  354 lines

  1. /*
  2.  
  3.     ARJWALK - a program that looks for things to compress.
  4.     ------------------------------------------------------
  5.  
  6.     I wrote this program for myself because, from time to time,
  7.     I need to free up disk space without deleting anything.
  8.  
  9.     This program goes from directory to directory looking for
  10.     things to "ARJ" ("ARJ" is a great utility written by Robert
  11.     Jung, and the word "ARJ" belongs to him).
  12.  
  13.     To use the program, go to the disk you want to work with
  14.     and type ARJWALK.  When you use it the first time, answer
  15.     NO to all the questions just to get a feel for what's happening.
  16.  
  17.     Other suggestions are:
  18.  
  19.         1.  Don't ARJ directories in your PATH unless
  20.             you really know what you are doing.
  21.         2.  Don't use this program when other programs
  22.             are running because they may be using
  23.             some files you want to ARJ and they
  24.             may get confused if the files are gone.
  25.  
  26.     Needless to say, you need to have ARJ installed on your
  27.     machine.
  28.  
  29.     This program is provided as is without liability of
  30.     any sort.  It may or may not perform as described
  31.     on your machine due to any number of factors.  There
  32.     are no guarantees that you received an unmodified
  33.     version of this software, an unmodified version of
  34.     ARJ, or that your machine is free from virus.
  35.  
  36.     The "C" language source code for this program is
  37.     given below.  If you modify it, please rename the
  38.     product and remove my comments.
  39. */
  40. /***************************************************************/
  41. /*                                                             */
  42. /*                                                             */
  43. /*                                                             */
  44. /*                                                             */
  45. /***************************************************************/
  46. #include  <stdio.h>  // some basic rtl includes
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include  <ctype.h>
  50. #include  <conio.h>
  51. #include    <dir.h>
  52. #include    <dos.h>
  53. /***************************************************************/
  54. /*                                                             */
  55. /*                                                             */
  56. /*                                                             */
  57. /*                                                             */
  58. /***************************************************************/
  59. #define TYPE_FILE 0
  60. #define TYPE_DIR  1
  61. /***************************************************************/
  62. /*                                                             */
  63. /*                                                             */
  64. /*                                                             */
  65. /*                                                             */
  66. /***************************************************************/
  67. typedef struct sFI {
  68.         struct find_t blk;
  69.         char dirof[ 128 ];
  70.         int count;
  71.         int what;  // FILE OR DIR
  72.         struct sFI *files;
  73.         struct sFI *next;
  74.         }sfxxx;
  75. /***************************************************************/
  76. /*                                                             */
  77. /*                                                             */
  78. /*                                                             */
  79. /*                                                             */
  80. /***************************************************************/
  81. typedef struct sCMD {
  82.         char *cmdstring;
  83.         struct sCMD *next;
  84.         }scmdxxx;
  85. /***************************************************************/
  86. /*                                                             */
  87. /*                                                             */
  88. /*                                                             */
  89. /*                                                             */
  90. /***************************************************************/
  91. struct sCMD *Cmdroot = NULL;
  92. struct sFI *Rootdirs = NULL;   // some global variables
  93. char Cmd[ 200 ];
  94. char Basecwd[ 128 ];
  95. char Spec[ 128 ];
  96. char Temp[ 128 ];
  97. /***************************************************************/
  98. /*                                                             */
  99. /*                                                             */
  100. /*                                                             */
  101. /*                                                             */
  102. /***************************************************************/
  103. int removedoubles( char *s )  // the lazy programmer's method
  104. {                             // for getting path names correct
  105.     if( !strlen( s ) ) return( 0 );
  106.     char *p = strstr( s, "\\\\" );
  107.     while( p ) {
  108.            strcpy( p, p + 1 );
  109.            removedoubles( s );
  110.            p = strstr( s, "\\\\" );
  111.     }
  112.     return( 1 );
  113. }
  114. /***************************************************************/
  115. /*                                                             */
  116. /*                                                             */
  117. /*                                                             */
  118. /*                                                             */
  119. /***************************************************************/
  120. int quit( void ) // hmmmm...  I can't remember what this does...
  121. {
  122.     chdir( Basecwd );
  123.     printf( "You are now in %s\n", Basecwd );
  124.     exit( 0 );
  125.     return( 1 );
  126. }
  127. /***************************************************************/
  128. /*                                                             */
  129. /*                                                             */
  130. /*                                                             */
  131. /*                                                             */
  132. /***************************************************************/
  133. int drainget( void )
  134. {
  135.     while( kbhit() );
  136.     while( 1 ) {
  137.            int c = toupper( getch() );
  138.            switch( c ) {
  139.                    case 'Y':
  140.                    case 'J':
  141.                    case 'N':
  142.                         printf( "\n" );
  143.                         return( c );
  144.            }
  145.     }
  146.     return( 0 );
  147. }
  148. /***************************************************************/
  149. /*                                                             */
  150. /*                                                             */
  151. /*                                                             */
  152. /*                                                             */
  153. /***************************************************************/
  154. int insertcmd( char *c )
  155. {
  156. struct sCMD *n = (struct sCMD *) malloc( sizeof( struct sCMD ) );
  157.     if( n ) {
  158.         n -> cmdstring = strdup( c );
  159.         n -> next = NULL;
  160.         if( !Cmdroot ) {
  161.             Cmdroot = n;
  162.         } else {
  163.             for( struct sCMD *i = Cmdroot; i; i = i -> next ) {
  164.                  if( !i -> next ) {
  165.                      i -> next = n;
  166.                      return( 1 );
  167.                  }
  168.             }
  169.         }
  170.     } else {
  171.         printf( "Cannot get enough memory!\n" );
  172.         return( quit() );
  173.     }
  174.     return( 1 );
  175. }
  176. /***************************************************************/
  177. /*                                                             */
  178. /*                                                             */
  179. /*                                                             */
  180. /*                                                             */
  181. /***************************************************************/
  182. int walkcmdlist( void )
  183. {
  184.     for( struct sCMD *i = Cmdroot; i; i = i -> next ) {
  185.          printf( "%s\n", i -> cmdstring );
  186.          system( i -> cmdstring );
  187.     }
  188.     return( 1 );
  189. }
  190.  
  191. /***************************************************************/
  192. /*                                                             */
  193. /*                                                             */
  194. /*                                                             */
  195. /*                                                             */
  196. /***************************************************************/
  197. int walkdirlist( struct sFI *n )
  198. {
  199.     if( !n ) {
  200.         return( 0 );
  201.     }
  202.     for( struct sFI *i = n; i; i = i -> next ) {
  203.          switch( i -> what ) {
  204.                  case TYPE_DIR:
  205.                       if( i -> count > 1 ) {
  206.                           if( !strlen( i -> blk.name ) ) {
  207.                               printf( "\tRoot skipped\n" );
  208.                           } else {
  209.                               printf( "\t%s\\%s contains %d files.  ARJ them?", i -> dirof, i -> blk.name, i -> count );
  210.                               switch( drainget() ) {
  211.                                       case 'Y':
  212.                                       case 'J':
  213.                                            sprintf( Cmd, "CD  %s\\%s", i -> dirof, i -> blk.name );
  214.                                            removedoubles( Cmd );
  215.                                            insertcmd( Cmd );
  216.                                            sprintf( Cmd, "ARJ m  %s *.*", i -> blk.name );
  217.                                            removedoubles( Cmd );
  218.                                            insertcmd( Cmd );
  219.                               }
  220.                           }
  221.                       } else if( i -> count == 0 && !i -> files ) {
  222.                           printf( "\t%s\\%s is empty.  Remove it? (Y/N) ", i -> dirof, i -> blk.name );
  223.                           switch( drainget() ) {
  224.                                   case 'Y':
  225.                                   case 'J':
  226.                                        sprintf( Cmd, "RD %s\\%s", i -> dirof, i -> blk.name );
  227.                                        removedoubles( Cmd );
  228.                                        insertcmd( Cmd );
  229.                           }
  230.                       }
  231.                       walkdirlist( i -> files );
  232.                       break;
  233.                  case TYPE_FILE:
  234.                       break;
  235.                  default:
  236.                       break;
  237.          }
  238.     }
  239.     return( 1 );
  240. }
  241. /***************************************************************/
  242. /*                                                             */
  243. /*                                                             */
  244. /*                                                             */
  245. /*                                                             */
  246. /***************************************************************/
  247. struct sFI *insertlist( struct sFI *node, struct find_t *b, int wh )
  248. {
  249.     struct sFI *n;
  250.     n = (struct sFI *)malloc( sizeof( struct sFI ) );
  251.     if( n ) {
  252.         memmove( &n -> blk, b, sizeof( struct find_t ) );
  253.         sprintf( n -> dirof, "%s\\%s", node -> dirof, node -> blk.name );
  254.         removedoubles( n -> dirof );
  255.         n -> count = 0;
  256.         n -> what = wh;
  257.         n -> files = NULL;
  258.         n -> next = NULL;
  259.         switch( wh ) {
  260.                 case TYPE_FILE:
  261.                      ++node -> count;
  262.                      break;
  263.         }
  264.         if( !node -> files ) {
  265.             node -> files = n;
  266.         } else {
  267.             for( struct sFI *i = node -> files; i; i = i -> next ) {
  268.                  if( !i -> next ) {
  269.                      i -> next = n;
  270.                      return( n );
  271.                  }
  272.             }
  273.         }
  274.         return( n );
  275.     }
  276.     printf( "Memory fault!  Cannot load the directory tree.\n" );
  277.     return( (sFI *)quit() );
  278. }
  279. /***************************************************************/
  280. /*                                                             */
  281. /*                                                             */
  282. /*                                                             */
  283. /*                                                             */
  284. /***************************************************************/
  285. int builddirlist( struct sFI *node )
  286. {
  287.     char temp[ 128 ];
  288.     struct sFI *x;
  289.     struct find_t blk;
  290.     int done;
  291.     strcpy( temp, node -> blk.name );
  292.     sprintf( Spec, "%s\\%s\\%s", node -> dirof, node -> blk.name, "*.*" );
  293.     removedoubles( Spec );
  294.     done = _dos_findfirst( Spec , 0xFF, &blk );
  295.     while( !done ) {
  296.            switch( blk.attrib ) {
  297.                    case FA_LABEL:
  298.                    case FA_DIREC:
  299.                         if( blk.name[ 0 ] != '.' ) {
  300.                             x = insertlist( node, &blk, TYPE_DIR );
  301.                             builddirlist( x );
  302.                         }
  303.                         break;
  304.                    case 0x28:
  305.                    case FA_ARCH:
  306.                    case FA_RDONLY:
  307.                    case FA_HIDDEN:
  308.                    case FA_SYSTEM:
  309.                    default:
  310.                         x = insertlist( node, &blk, TYPE_FILE );
  311.                         break;
  312.            }
  313.            done = _dos_findnext( &blk );
  314.     }
  315.     return( 0 );
  316. }
  317. /***************************************************************/
  318. /*                                                             */
  319. /*                                                             */
  320. /*                                                             */
  321. /*                                                             */
  322. /***************************************************************/
  323. int main( int argc, char *argv[] )
  324. {
  325.     getcwd( Basecwd, 128 );
  326.     system( "CHKDSK /F" );
  327.     struct find_t blk;
  328.     int done = _dos_findfirst( Basecwd, 0xFF, &blk );
  329.     if( !done ) {
  330.         memset( &blk, 0, sizeof( struct find_t ) );
  331.     }
  332.     Rootdirs = (struct sFI *)malloc( sizeof( struct sFI ) );
  333.     if( Rootdirs ) {
  334.         memmove( &Rootdirs -> blk, &blk, sizeof( struct find_t ) );
  335.         sprintf( Temp, "%c:\\", 'A' + getdisk() );
  336.         removedoubles( Temp );
  337.         strcpy( Rootdirs -> dirof, Temp );
  338.         Rootdirs -> count = 0;
  339.         Rootdirs -> files = NULL;
  340.         Rootdirs -> next = NULL;
  341.         Rootdirs -> what = TYPE_DIR;
  342.         builddirlist( Rootdirs );
  343.         walkdirlist( Rootdirs );
  344.         walkcmdlist();
  345.     }
  346.     return( quit() );
  347. }
  348. /***************************************************************/
  349. /*                                                             */
  350. /*                                                             */
  351. /*                                                             */
  352. /*                                                             */
  353. /***************************************************************/
  354.