home *** CD-ROM | disk | FTP | other *** search
/ EigenPC: Software Surprise / image.IMA / STREE.ZIP / STREE.C next >
Encoding:
C/C++ Source or Header  |  1992-07-02  |  7.4 KB  |  261 lines

  1. /* ******************************************** */
  2. /* TREE.COM substitute (c) UK 1992 Rob Staveley */
  3. /*          Public Domain property              */
  4. /*                                              */
  5. /*       Compiled with Borland C++ 3.0          */
  6. /*          BCC -mt -tDc STREE.C                */
  7. /*                                              */
  8. /*     To say hello, mail : rstaveley@cix       */
  9. /* ******************************************** */
  10.  
  11. #ifndef __TINY__
  12.    #error Use TINY model and link as COM file
  13. #endif
  14.  
  15. #include <dir.h>
  16. #include <dos.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. struct fileSize {
  22.    long bytesActual,            /* Files are sized by disk space occupation */
  23.         bytesOccupation;        /* as well as actual size (1 cluster = min) */
  24. };
  25.  
  26. static int dircount = 0,        /* tally of files and directories           */
  27.            filecount = 0,
  28.            a = 0,               /* ASCII only                               */
  29.            f = 0;               /* display files                            */
  30. static long bpc;
  31.  
  32. static char *strut[] = {        /* graphic characters with ASCII alternvs   */
  33.    "  \xb3",
  34.    "  |"
  35. };
  36.  
  37. static char *elbow[] = {
  38.    "  \xc3\xc4",
  39.    "  +-"
  40. };
  41.  
  42. static char *elbeq[] = {
  43.    " \xd4\xcd\xcd",
  44.    " +=="
  45. };
  46.  
  47. static char here[] = ".";       /* current directory                        */
  48.  
  49. static const char usagestr[] =
  50.         "Designed as a replacement for DOS 5.0's TREE command, which"
  51.         "\ngraphically displays the directory structure of a drive or path."
  52.         "\n\nSTREE [drive:][path] [/F] [/A]"
  53.         "\n\n\t/F   Displays the names of the files in each directory."
  54.         "\n\n\t/A   Uses ASCII instead of extended IBM characters.";
  55.  
  56. static struct fileSize sizedir(
  57.    const char *pathname,
  58.    const char *prefix,
  59.    int nesting
  60. );
  61.  
  62. int main(
  63.    int argc,
  64.    char *argv[]
  65. ) {
  66.  
  67.   char olddir[ MAXPATH ],
  68.        prefix[ MAXPATH ],
  69.        argv1[ MAXPATH ];
  70.  
  71.   int rtnval,
  72.       thendrive,
  73.       nowdrive;
  74.  
  75.   struct dfree free;
  76.   struct fileSize byteCount = { 0, 0 };
  77.  
  78.   fprintf( stderr, "\nSubstitute TREE (c) UK 1992 Rob Staveley\n\n" );
  79.  
  80.   strcpy( argv1, here );
  81.   thendrive = getdisk();
  82.   thendrive++;
  83.   if ( argc > 1 )  {
  84.      int i = 0, j = 1;
  85.      while ( j < argc ) {
  86.          if (
  87.             strlen( argv[ j ] ) > 1 && (
  88.                ( argv[ j ][ 0 ] == '-' )
  89.                  ||
  90.                ( argv[ j ][ 0 ] == '/' )
  91.             )
  92.          )
  93.          {
  94.             switch ( argv[ j ][ 1 ] ) {
  95.                 case 'a':; case 'A':
  96.                    a = 1; break;
  97.                 case 'f':; case 'F':
  98.                    f = 1; break;
  99.                 case '?':; case 'H':; case 'h':
  100.                    fprintf( stderr, usagestr );
  101.                    exit( 100 );
  102.                 default:
  103.                    i = j;
  104.             }
  105.          }
  106.          else
  107.             i = j;
  108.          j++;
  109.      }
  110.      if ( i ) {
  111.         strncpy( argv1, argv[ i ], MAXPATH - 1 );
  112.         strupr( argv1 );
  113.         if ( argv1[ 1 ] == ':' ) {
  114.            if ( _chdrive( argv1[ 0 ] - 'A' + 1 ) ) {
  115.               fprintf( stderr, "Unable to access drive %c\n", argv1[ 0 ] );
  116.               exit( 98 );
  117.            }
  118.            if ( strlen( argv[ i ] ) > 2 )
  119.               strncpy( argv1, &argv[ i ][ 2 ], MAXPATH - 1 );
  120.            else
  121.               strcpy( argv1, here );
  122.            strupr( argv1 );
  123.         }
  124.         else
  125.            thendrive = 0;
  126.      }
  127.   }
  128.  
  129.   if ( strlen( argv1 ) > 1 && argv1[ strlen( argv1 ) - 1 ] == '\\' )
  130.      argv1[ strlen( argv1 ) - 1 ] = 0;
  131.  
  132.   setcbrk( 1 );
  133.   getcwd( olddir, MAXPATH );
  134.  
  135.   if ( chdir( argv1 ) ) {
  136.     fprintf( stderr, "Access to [%s] denied\n", argv1 );
  137.     if ( thendrive )
  138.        _chdrive( thendrive );
  139.     exit( errno );
  140.   }
  141.  
  142.  
  143.   fprintf( stderr, "Current dir [%s]\n", olddir);
  144.   fprintf( stderr, "Inspecting  [%s]\n\n", argv1 );
  145.  
  146.   strcpy( prefix, olddir );
  147.   if (
  148.      strlen( olddir ) != 3
  149.      && argv1[ 0 ] != '\\'
  150.   )
  151.      strcat( prefix, "\\" );
  152.   strcat( prefix, argv1 );
  153.   if ( strstr( argv1, ".." ) != NULL )
  154.     strcpy( prefix, argv1 );
  155.   if ( prefix[ strlen( prefix ) - 1 ] != '\\' )
  156.     strcat( prefix, "\\" );
  157.  
  158.   nowdrive = getdisk();
  159.   getdfree( nowdrive + 1, &free );
  160.   if ( free.df_sclus == 0xFFFF ) {
  161.      fprintf( stderr, "\nEstimating 512 bytes per cluster\n" );
  162.      bpc = 512;
  163.   }
  164.   else
  165.      bpc = free.df_bsec * free.df_sclus;
  166.  
  167.   byteCount = sizedir( "", strupr( prefix ), 0 );
  168.   fprintf( stderr,
  169.      "\nProfile:\n\tFiles :\t%d\n\tDirs  :\t%d\n"
  170.      "\tBytes :\t%ld (%ld)\n\tFree  :\t%ld\n",
  171.      filecount, dircount,
  172.      byteCount.bytesActual, byteCount.bytesOccupation,
  173.      bpc * free.df_avail
  174.   );
  175.   chdir( olddir );
  176.   if ( thendrive )
  177.      _chdrive( thendrive );
  178.   return 0;
  179. }
  180.  
  181. static long diskOcc( long actualBytes ) {
  182.    return bpc * ( actualBytes / bpc + ( ( actualBytes % bpc ) != 0 ) );
  183. }
  184.  
  185. static struct fileSize sizedir(
  186.    const char *pathname, const char *prefix, int nesting
  187. ) {
  188.   int done,
  189.       lfilecount = 0,           /* local tallies                        */
  190.       localdirs = 0;
  191.   static int hello = 0;         /* static marker                        */
  192.   struct fileSize rtnval = { 0, 0 },
  193.                   localbytes = { 0, 0 };
  194.   struct ffblk ffblk;
  195.   char pathspec[ MAXPATH ];
  196.   if ( hello++ ) {
  197.      for ( done = 0; done < nesting - 1; done++ )
  198.         printf( strut[ a ] );
  199.      printf( elbow[ a ] );
  200.   }
  201.   getcwd( pathspec, MAXPATH );
  202.   if ( pathspec[ strlen( pathspec ) - 1 ] == '\\' )
  203.      pathspec[ strlen( pathspec ) - 1 ] = 0;
  204.   printf( "%s", pathspec );
  205.   strcpy( pathspec, pathname );
  206.   printf( "\\%s\n", pathspec );
  207.   strcat( pathspec, "*.*" );
  208.   done = findfirst( pathspec, &ffblk, 0x10 );
  209.   while ( !done ) {
  210.     if ( ffblk.ff_attrib == 0x10 ) {
  211.       if ( ffblk.ff_name[0] != '.' ) {
  212.         char *dirpath;
  213.         struct fileSize ds;
  214.         dirpath = malloc( strlen( pathname ) + strlen( ffblk.ff_name ) + 2 );
  215.         strcpy( dirpath, pathname );
  216.         strcat( dirpath, ffblk.ff_name );
  217.         strcat( dirpath, "\\" );
  218.         ds = sizedir( dirpath, prefix, nesting + 1 );
  219.         rtnval.bytesOccupation += ds.bytesOccupation;
  220.         rtnval.bytesActual += ds.bytesActual;
  221.         dirpath[ strlen( dirpath ) - 1 ] = 0;
  222.         dircount++; localdirs++;
  223.         free( dirpath );
  224.       }
  225.     }
  226.     else {
  227.       if ( f ) {
  228.          int done2;
  229.          for ( done2 = -1; done2 < nesting; done2++ )
  230.             printf( strut[ a ] );
  231.          printf( " %s\n", ffblk.ff_name );
  232.       }
  233.       localbytes.bytesActual += ffblk.ff_fsize;
  234.       localbytes.bytesOccupation += diskOcc( ffblk.ff_fsize );
  235.       lfilecount++;
  236.     }
  237.     done=findnext( &ffblk );
  238.   }
  239.   for ( done = -1; done < nesting - 1; done++ )
  240.      printf( strut[ a ] );
  241.   filecount += lfilecount;
  242.   rtnval.bytesActual += localbytes.bytesActual;
  243.   rtnval.bytesOccupation += localbytes.bytesOccupation;
  244.   printf(
  245.      " %s %ld (%ld) bytes in %d files\n", elbeq[ a ],
  246.      localbytes.bytesActual, localbytes.bytesOccupation, lfilecount
  247.   );
  248.   if ( localdirs ) {
  249.      for ( done = -1; done < nesting - 1; done++ )
  250.         printf( strut[ a ] );
  251.      printf(
  252.         "      %ld (%ld) bytes including %d dirs\n",
  253.         rtnval.bytesActual, rtnval.bytesOccupation, localdirs
  254.      );
  255.   }
  256.   return rtnval;
  257. }
  258.  
  259.  
  260.  
  261.