home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / spacehog.zip / space.c < prev    next >
C/C++ Source or Header  |  2000-01-20  |  29KB  |  597 lines

  1. /*---------------------------------------------------------------------------*/
  2. /* File: SPACE.C                                          Date: 01/20/2000   */
  3. /*---------------------------------------------------------------------------*/
  4. /* Description: This PUBLIC DOMAIN program helps you maintain the amount     */
  5. /*              of free space in the specified drive to under 2G-512 bytes   */
  6. /*              Thus stopping programs using 32-bit signed integer math      */
  7. /*              from seeing space above 2Gb as negative.                     */
  8. /*                                                                           */
  9. /*              See Welcome() for details.                                   */
  10. /* Assumptions:                                                              */
  11. /*                                                                           */
  12. /* Programmers: Wing F Yuen, wfyuen@bestweb.net                              */
  13. /*                                                                           */
  14. /* Compiler   : IBM VisualAge C++ compiles with:                             */
  15. /*                icc space.c                                                */
  16. /*                                                                           */
  17. /*              Microsoft C6 compiles with:                                  */
  18. /*                cl /AS /Lp space.c os2.lib /link /pm:vio                   */
  19. /*                                                                           */
  20. /*              Watcom C/C++ v11.0 compiles with:                            */
  21. /*                wcl386 -3 space.c                                          */
  22. /*                wcl -i=\watcom\h\os21x -x -2 -lp -bt=os2 space.c           */
  23. /*                                                                           */
  24. /*              EMX/GCC v2.7.2.1 compiles (minimal testing) with:            */
  25. /*                gcc space.c                                                */
  26. /*                                                                           */
  27. /*              A batch file BUILD.CMD is provided for your convenience.     */
  28. /*                                                                           */
  29. /* Notes      : All local   variables begin with a Capital letter            */
  30. /*              All global  variables are prefixed with the letter 'g'       */
  31. /*              All pointer variables are prefixed with the letter 'p'       */
  32. /*              All user-supplied functions begin with a Capital letter;     */
  33. /*                the only exception is main()                               */
  34. /*---------------------------------------------------------------------------*/
  35. /* Change Log:                                                               */
  36. /* 1.00  - First release.                                                    */
  37. /* 1.01  - ArgV[0] doesn't include the path of the EXE except under 4OS2.    */
  38. /*       - Added support for Watcom C/C++ v11                                */
  39. /* 1.02  - Clean up conditional compile preprocessor directives.             */
  40. /*       - Watcom version not reading Drive Serial Number properly.          */
  41. /*       - Use double to track freespace and file sizes, D-U-H !!!           */
  42. /* 1.03  - Change Advantis email address                                     */
  43. /* 1.04  - Keep maximum free space to 2G-2 bytes. Seem to compile okay       */
  44. /*         with EMX/GCC v2.7.2.1 without any change!                         */
  45. /* 1.05  - Keep maximum free space to 2G-512 bytes.                          */
  46. /* 1.06  - Fixed space calculation for partitions above 4GB.                 */
  47. /* 1.06a - Changed email address to wfyuen@bestweb.net                       */
  48. /*---------------------------------------------------------------------------*/
  49. #define NDEBUG                                   /* define for production    */
  50.  
  51. #ifdef NDEBUG
  52.   #define MAX_BYTES_FREE (0x7FFFFE00*1.0)        /* 2G - 512                 */
  53.   #define MAX_FILE_SIZE  (0x7FFFFFFF*1.0)        /* 2G - 1                   */
  54. #else
  55.   #define MAX_BYTES_FREE (0x20000000*1.0)        /* 0.5G for testing         */
  56.   #define MAX_FILE_SIZE  (100.0*1024*1024)       /* 100 MB for testing       */
  57. #endif
  58.  
  59. #define INCL_DOSERRORS                           /* Error codes              */
  60. #define INCL_DOSFILEMGR                          /* File Manager values      */
  61. #include <os2.h>
  62. #include <stdio.h>                               /* fileno()                 */
  63. #include <ctype.h>                               /* toupper()                */
  64. #include <string.h>
  65. #include <io.h>                                  /* filelength()             */
  66. #include <errno.h>                               /* errno                    */
  67.  
  68. /*---------------------------------------------------------------------------*/
  69. /* Identify the compiler                                                     */
  70. /*                                                                           */
  71. /* Microsoft C                #ifdef  _MSC_VER                               */
  72. /* IBM Visuage C++            #ifdef  __IBMC__                               */
  73. /* Watcom C/C++               #ifdef  __WATCOMC__                            */
  74. /* Watcom C/C++ 32bit         #ifdef  __386__         in addition to above   */
  75. /*---------------------------------------------------------------------------*/
  76. #if defined(__WATCOMC__)
  77.   #if defined(__386__)
  78.     #define WC32_
  79.   #else
  80.     #define WC16_
  81.   #endif
  82. #endif
  83.  
  84. /*---------------------------------------------------------------------------*/
  85. /* Global variables are used extensively to reduce the stack size and make   */
  86. /* it cheaper to separate code blocks into functions. This is okay because   */
  87. /* this is not a multithreading program.                                     */
  88. /*---------------------------------------------------------------------------*/
  89. #if (defined(_MSC_VER) || defined(WC16_))
  90.  
  91. USHORT     gDriveNumber=0;                       /* Drive number             */
  92. USHORT     gFSInfoLevel;                         /* File system data required*/
  93. USHORT     gRcApi;
  94. #else
  95.  
  96. ULONG      gDriveNumber=0;                       /* Drive number             */
  97. ULONG      gFSInfoLevel;                         /* File system data required*/
  98. APIRET     gRcApi;                               /* Return code              */
  99. #endif
  100.  
  101. FSALLOCATE gFSInfoBuf;                           /* File system info buffer  */
  102. FSINFO     gFSVolBuf;
  103. ULONG      gCluster;
  104. FILE       *gHog;
  105. double     gTotal, gUsed, gFree;
  106. double     gOldHogSize, gNewHogSize;             /* old and new sizes        */
  107. USHORT     gOldHogCount;                         /* old hog file count       */
  108. char       gDriveVolume[12];
  109. char       gDriveSerial[10];
  110. char       gDriveFormat[8];                      /* FAT or HPFS              */
  111. char       gDriveLetter;
  112.  
  113. /*---------------------------------------------------------------------------*/
  114. /* I reserve 256 bytes here so that those without compilers can move the     */
  115. /* holding directory by patching here with a hex editor. It must *NOT*       */
  116. /* include a trailing backslash.                                             */
  117. /*---------------------------------------------------------------------------*/
  118. char       gHogFilePath[256] = {"?:\\spacehog"}; /* holding directory        */
  119.  
  120. /*---------------------------------------------------------------------------*/
  121. /* Local function prototypes                                                 */
  122. /*---------------------------------------------------------------------------*/
  123. int    CollectFileInfo  (void);
  124. void   CollectVolInfo   (void);
  125. long   FileSize         (const char *FileSpec);
  126. char   *Split000        (double Number, char Separator);
  127. double TotalHogSize     (void);
  128. void   Welcome          (char *MyName);
  129. int    WriteNewHogFiles (void);
  130.  
  131. /*---------------------------------------------------------------------------*/
  132. /* main()                                                                    */
  133. /*---------------------------------------------------------------------------*/
  134. int main (int ArgC, char *ArgV[])
  135. {
  136.   ULONG      DriveMap;
  137.   FILESTATUS PathBuf;
  138.  
  139.   if (ArgC < 2) {
  140.       #if (defined(_MSC_VER) || defined(WC16_))
  141.  
  142.       gRcApi = DosQCurDisk( &gDriveNumber, &DriveMap);
  143.       #else
  144.  
  145.       gRcApi = DosQueryCurrentDisk( &gDriveNumber, &DriveMap);
  146.       #endif
  147.       if (gRcApi)
  148.            gDriveLetter = '\0';
  149.       else gDriveLetter = 'A' + gDriveNumber - 1;
  150.       gDriveNumber = 0L;                         /* current partition        */
  151.   }
  152.   else if (!strcmp( "/?", ArgV[1])) {
  153.       Welcome( ArgV[0]);
  154.       return 0;
  155.   }                                              /* End if                   */
  156.   else {
  157.       /*---------------------------------------------------------------------*/
  158.       /* Assume the user entered a drive letter                              */
  159.       /*---------------------------------------------------------------------*/
  160.       gDriveLetter = toupper( *ArgV[1]);
  161.       if (NULL == strchr( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", gDriveLetter)) {
  162.           Welcome( ArgV[0]);
  163.           return 0;
  164.       }
  165.       gDriveNumber = (ULONG)(gDriveLetter - 'A' + 1);
  166.   }                                              /* End if                   */
  167.   if (CollectFileInfo()) {
  168.       return gRcApi;
  169.   }
  170.   gCluster = gFSInfoBuf.cSectorUnit * gFSInfoBuf.cbSector;
  171.   gFree    = (gFSInfoBuf.cUnitAvail  * 1.0) * gCluster;
  172.  
  173.   gHogFilePath[0] = gDriveLetter;
  174.   /*-------------------------------------------------------------------------*/
  175.   /* Did the user create the \SPACEHOG path?                                 */
  176.   /*-------------------------------------------------------------------------*/
  177.   #if (defined(_MSC_VER) || defined(WC16_))
  178.  
  179.   gRcApi = DosQPathInfo( gHogFilePath,
  180.                          FIL_STANDARD,
  181.                          (PBYTE)&PathBuf,
  182.                          sizeof PathBuf,
  183.                          0L);                    /* reserved                 */
  184.   #else
  185.  
  186.   gRcApi = DosQueryPathInfo( gHogFilePath,
  187.                              FIL_STANDARD,
  188.                              &PathBuf,
  189.                              sizeof PathBuf);
  190.   #endif
  191.  
  192.   if (NO_ERROR == gRcApi) {
  193.       gOldHogSize = TotalHogSize();
  194.       /*---------------------------------------------------------------------*/
  195.       /* The actual amount of free disk space is (gFree + gOldHogSize)       */
  196.       /*---------------------------------------------------------------------*/
  197.       gNewHogSize = (gOldHogSize + gFree) - MAX_BYTES_FREE;
  198.       if (gNewHogSize < 0.0) {
  199.           gNewHogSize = 0.0;
  200.       }
  201.       #ifndef NDEBUG
  202.  
  203.       printf( "OldHogSize     = %.0f\n", gOldHogSize);
  204.       printf( "NewHogSize     = %.0f\n", gNewHogSize);
  205.       printf( "Free           = %.0f\n", gFree      );
  206.       printf( "MAX_BYTES_FREE = %.0f\n", MAX_BYTES_FREE);
  207.       #endif
  208.  
  209.       if (gNewHogSize != gOldHogSize) {
  210.           /*-----------------------------------------------------------------*/
  211.           /* Resize HogFileName                                              */
  212.           /*-----------------------------------------------------------------*/
  213.           if (WriteNewHogFiles()) {
  214.               printf( __FILE__"/main(): Can't resize holding " \
  215.                       "files in %s\n", gHogFilePath);
  216.           }
  217.       }
  218.   }
  219.   /*-------------------------------------------------------------------------*/
  220.   /* Refresh the space usage                                                 */
  221.   /*-------------------------------------------------------------------------*/
  222.   if (CollectFileInfo()) {
  223.       return gRcApi;
  224.   }
  225.   gFree  = (gFSInfoBuf.cUnitAvail * 1.0) * gCluster;
  226.   gTotal = (gFSInfoBuf.cUnit      * 1.0) * gCluster;
  227.   gUsed  = gTotal - gFree;
  228.  
  229.   CollectVolInfo();
  230.  
  231.   printf( "\n SpaceHog v1.06a by Wing Yuen           compiled on %s", __DATE__);
  232.   printf( "\n Volume in drive %c is %-11s    Serial number is %s",
  233.           gDriveLetter, gDriveVolume, gDriveSerial);
  234.   printf( "\n --------------------------------------------------------------");
  235.   printf( "\n%16s bytes per sector",       Split000( gFSInfoBuf.cbSector, ','));
  236.   printf( "\n%16s bytes per cluster",      Split000( gCluster,            ','));
  237.   printf( "\n%16s bytes total disk space", Split000( gTotal,              ','));
  238.   printf( "\n%16s bytes used",             Split000( gUsed ,              ','));
  239.   if (0.0 != gNewHogSize) {
  240.       printf( "\n*%15s bytes reserved in %s directory",
  241.               Split000( gNewHogSize, ','), gHogFilePath);
  242.   }
  243.   printf( "\n%16s bytes free\n",           Split000( gFree ,              ','));
  244.  
  245.   return 0;
  246. }                                                /* main()                   */
  247.  
  248. /*---------------------------------------------------------------------------*/
  249. /* CollectFileInfo()                                      Date: 03/15/1999   */
  250. /*---------------------------------------------------------------------------*/
  251. /* Description: Collect file information of gDriveNumber                     */
  252. /* Returns    : Nothing                                                      */
  253. /* Assumptions: None                                                         */
  254. /* Programmers: Wing F Yuen                                                  */
  255. /*---------------------------------------------------------------------------*/
  256. int CollectFileInfo (void)
  257. {
  258.   gFSInfoLevel = FSIL_ALLOC;          /* requests file system allocation info*/
  259.   #if (defined(_MSC_VER) || defined(WC16_))
  260.  
  261.   gRcApi = DosQFSInfo( gDriveNumber,
  262.                        gFSInfoLevel,
  263.                        (PBYTE)&gFSInfoBuf,
  264.                        sizeof gFSInfoBuf);
  265.   if (gRcApi) {
  266.       printf( "DosQFSInfo error: Rc%ld", gRcApi);
  267.       return 2;
  268.   }
  269.   #else
  270.  
  271.   gRcApi = DosQueryFSInfo( gDriveNumber,
  272.                            gFSInfoLevel,
  273.                            &gFSInfoBuf,
  274.                            sizeof gFSInfoBuf);
  275.   if (gRcApi) {
  276.       printf( "DosQueryFSInfo error: Rc%ld", gRcApi);
  277.       return 2;
  278.   }
  279.   #endif
  280.  
  281.   /*-------------------------------------------------------------------------*/
  282.   /* On successful return, the data buffer gFSInfoBuf contains a set of      */
  283.   /* information about space allocation within the specified file system.    */
  284.   /*-------------------------------------------------------------------------*/
  285.   #if 0
  286.  
  287.   printf( "\nCollectFileInfo():\n");
  288.   printf( "  gFSInfoBuf.cSectorUnit = %lu\n", gFSInfoBuf.cSectorUnit);
  289.   printf( "  gFSInfoBuf.cUnit       = %lu\n", gFSInfoBuf.cUnit      );
  290.   printf( "  gFSInfoBuf.cUnitAvail  = %lu\n", gFSInfoBuf.cUnitAvail );
  291.   printf( "  gFSInfoBuf.cbSector    = %hu\n", gFSInfoBuf.cbSector   );
  292.   #endif
  293.   return 0;
  294. }                                                /* CollectFileInfo()        */
  295.  
  296. /*---------------------------------------------------------------------------*/
  297. /* CollectVolInfo()                                       Date: 04/16/1998   */
  298. /*---------------------------------------------------------------------------*/
  299. /* Description: Collect volume information of gDriveNumber                   */
  300. /* Returns    : Nothing                                                      */
  301. /* Assumptions: None                                                         */
  302. /* Programmers: Wing F Yuen                                                  */
  303. /*---------------------------------------------------------------------------*/
  304. void CollectVolInfo (void)
  305. {
  306.   #if (defined(_MSC_VER) || defined(WC16_))
  307.  
  308.   ULONG  VolSer;
  309.   #else
  310.  
  311.   UINT   VolSer;
  312.   #endif
  313.  
  314.   gFSInfoLevel = FSIL_VOLSER;           /* requests volume/serial number info*/
  315.   #if (defined(_MSC_VER) || defined(WC16_))
  316.  
  317.   gRcApi = DosQFSInfo( gDriveNumber,
  318.                        gFSInfoLevel,
  319.                        (PBYTE)&gFSVolBuf,
  320.                        sizeof gFSVolBuf);
  321.   if (gRcApi) {
  322.       printf( "DosQFSInfo error: Rc%ld", gRcApi);
  323.       strcpy( gDriveSerial, "unknown");
  324.       strcpy( gDriveVolume, "unknown");
  325.       return;
  326.   }
  327.  
  328.     #if defined(WC16_)                        /* see \watcom\h\os21x\bsedos.h*/
  329.  
  330.   VolSer = *((ULONG *)(&gFSVolBuf.fdateCreation));
  331.     #else
  332.  
  333.   VolSer = *((ULONG *)(&gFSVolBuf.ulVSN));       /* Microsoft C              */
  334.     #endif
  335.  
  336.   sprintf( gDriveSerial, "%04X:%04X",
  337.            (USHORT)(VolSer >>16),
  338.            (USHORT)(VolSer     ));
  339.   #else                                          /* 32 bit API               */
  340.  
  341.   gRcApi = DosQueryFSInfo( gDriveNumber,
  342.                            gFSInfoLevel,
  343.                            &gFSVolBuf,
  344.                            sizeof gFSVolBuf);
  345.  
  346.   if (gRcApi) {
  347.       printf( "DosQueryFSInfo error: Rc%ld", gRcApi);
  348.       strcpy( gDriveSerial, "unknown");
  349.       strcpy( gDriveVolume, "unknown");
  350.       return;
  351.   }
  352.   VolSer = *((UINT *)(&gFSVolBuf.fdateCreation));
  353.   sprintf( gDriveSerial, "%04X:%04X",
  354.            (USHORT)(VolSer >>16),
  355.            (USHORT)(VolSer     ));
  356.   #endif                             /* (defined(_MSC_VER) || defined(WC16_))*/
  357.  
  358.   /*-------------------------------------------------------------------------*/
  359.   /* On successful return, the data buffer gFSVolBuf contains a set of       */
  360.   /* information about the volume/serial number of the drive.                */
  361.   /*-------------------------------------------------------------------------*/
  362.   strcpy( gDriveVolume, gFSVolBuf.vol.szVolLabel);
  363.   if ('\0' == gDriveVolume[0]) {
  364.       strcpy( gDriveVolume, "unlabeled");
  365.   }
  366.   return;
  367. }                                                /* CollectVolInfo()         */
  368.  
  369. /*---------------------------------------------------------------------------*/
  370. /* FileSize()                                             Date: 04/15/1998   */
  371. /*---------------------------------------------------------------------------*/
  372. /* Description: Return the size of the specified file.                       */
  373. /* Returns    : Nothing                                                      */
  374. /* Assumptions: None                                                         */
  375. /* Programmers: Wing F Yuen                                                  */
  376. /*---------------------------------------------------------------------------*/
  377. long FileSize (const char *FileSpec)
  378. {
  379.   FILE *Tmp;
  380.   long FileLen;
  381.  
  382.   if (NULL == (Tmp = fopen( FileSpec, "rb"))) {
  383.       return -1L;
  384.   }
  385.   #if (defined(_MSC_VER) || defined (__WATCOMC__))
  386.  
  387.   FileLen = filelength( fileno( Tmp));
  388.   #else                                          /* VisualAge C++            */
  389.  
  390.   FileLen = _filelength( fileno( Tmp));          /* needs /Se                */
  391.  
  392.   #endif
  393.   fclose( Tmp);
  394.   return FileLen;
  395. }                                                /* FileSize()               */
  396.  
  397. /*---------------------------------------------------------------------------*/
  398. /* Split000()                                             Date: 04/17/1998   */
  399. /*---------------------------------------------------------------------------*/
  400. /* Description: Add commas as separators between the thousands, millions &   */
  401. /*              billions. This is accomplished by shifting trailing digits   */
  402. /*              three at a time, then inserting a comma before repeating.    */
  403. /* Returns    : Nothing                                                      */
  404. /* Assumptions: Partition size < 1,000,000,000,000 bytes                     */
  405. /* Programmers: Wing F Yuen                                                  */
  406. /*---------------------------------------------------------------------------*/
  407. char *Split000 (double Bytes, char Separator)
  408. {
  409.   int    CommaCnt, DigitCnt, i;
  410.   static
  411.   char   Buffer[16];                   /* HPFS 64GB limit needs only 14 bytes*/
  412.   char   *Src, *Dst;
  413.  
  414.   sprintf( Buffer, "%.0f", Bytes);
  415.   DigitCnt = strlen( Buffer);
  416.   CommaCnt = (DigitCnt-1) / 3;
  417.   Dst = Buffer + DigitCnt + CommaCnt;
  418.   Src = Buffer + DigitCnt;
  419.   *Dst = *Src;
  420.   for (i = 0; i < CommaCnt; i++) {
  421.       *--Dst = *--Src;
  422.       *--Dst = *--Src;
  423.       *--Dst = *--Src;
  424.       *--Dst = Separator;
  425.   }                                              /* End for                  */
  426.   return Buffer;
  427. }                                                /* Split000()               */
  428.  
  429. /*---------------------------------------------------------------------------*/
  430. /* TotalHogSize()                                         Date: 04/17/1998   */
  431. /*---------------------------------------------------------------------------*/
  432. /* Description: Count the number of Hog Files and add up their total.        */
  433. /* Returns    : Total size as a double, and updated gOldHogCount.            */
  434. /* Assumptions:                                                              */
  435. /* Programmers: Wing F Yuen                                                  */
  436. /*---------------------------------------------------------------------------*/
  437. double TotalHogSize (void)
  438. {
  439.   double Sum=0;
  440.   long   HogSize;
  441.   char   HogName[256];
  442.  
  443.   gOldHogCount = 0;
  444.   do {
  445.       sprintf( HogName, "%s\\%d", gHogFilePath, gOldHogCount);
  446.       HogSize = FileSize( HogName);
  447.       Sum += HogSize;
  448.       ++gOldHogCount;
  449.   } while (-1L != HogSize);                      /* End do                   */
  450.   --gOldHogCount;
  451.   return Sum + 1.0;                              /* undo final HogSize       */
  452. }                                                /* TotalHogSize()           */
  453.  
  454. /*---------------------------------------------------------------------------*/
  455. /* Welcome()                                                Date: 01/20/2000 */
  456. /*---------------------------------------------------------------------------*/
  457. /* Description: Show syntax and usage                                        */
  458. /* Returns    : Nothing                                                      */
  459. /* Assumptions: None                                                         */
  460. /* Programmers: Wing F Yuen                                                  */
  461. /*---------------------------------------------------------------------------*/
  462. void Welcome (char *MyName)
  463. {
  464.   printf( "\nSyntax: %s [DriveLetter[:]]\n"                                   \
  465.           "\nThe current drive will be used if no DriveLetter is given."      \
  466.           "\nThe trailing colon is also optional.\n"                          \
  467.           "\nThis PUBLIC DOMAIN program helps you maintain the amount"        \
  468.           "\nof free space in the specified drive to under 2G-512 Bytes."     \
  469.           "\n(Because HPFS allocates space in 512 byte units.)"               \
  470.           "\nThus stopping programs using 32-bit signed integer math"         \
  471.           "\nfrom seeing space above 2G-512 bytes as negative.\n"             \
  472.           "\nIf it can't find the \\SPACEHOG directory in the specified"      \
  473.           "\npartition, it behaves like a run-of-the-mill freespace"          \
  474.           "\nreporting utility, albeit it can handle disk partitions up"      \
  475.           "\nto 999,999,999,999 bytes in size. (see Split000())\n"            \
  476.           "\nIf it sees the \\SPACEHOG directory, which you have to"          \
  477.           "\ncreate explicitly, it will create dummy files there as"          \
  478.           "\nneeded to maintain the 2G-512 byte freespace ceiling for"        \
  479.           "\nthat disk partition (you may have to run this twice). The"       \
  480.           "\ndummy files are named with simple integers, from 0 thru"         \
  481.           "\n99999999...\n"                                                   \
  482.           "\nIf the amount of reserved space needed is less than 2G-512"      \
  483.           "\nbytes, it will shrink or expand the size of the \\SPACEHOG\\0"   \
  484.           "\nfile instead.\n"                                                 \
  485.           "\nWarning: You use this program and its source code at your"       \
  486.           "\n         own risk. I provide no warranty of any kind. But"       \
  487.           "\n         I *do* welcome bug FIXES/reports via email to:\n"       \
  488.           "\n         wfyuen@bestweb.net\n"                                   \
  489.           "\nPatches: If you don't have any of the four compilers I used,"    \
  490.           "\n         you can change the \\SPACEHOG directory to some place"  \
  491.           "\n         else by patching the 256 byte variable I reserved"      \
  492.           "\n         with a binary editor. Search for this string:\n"        \
  493.           "\n         \"?:\\spacehog\"\n"                                     \
  494.           "\n         The '?' will be replaced by the program with the"       \
  495.           "\n         drive letter passed from the command line. Therefore,"  \
  496.           "\n         you need not patch that. Please make sure you end the"  \
  497.           "\n         new directory name with a binary 0 byte. It must not"   \
  498.           "\n         end with a backslash ('\\')!!!\n"                       \
  499.           "\nWing Yuen                                      %s\n"
  500.           , MyName, __DATE__);
  501.   return;
  502. }                                                /* Welcome()                */
  503.  
  504. /*---------------------------------------------------------------------------*/
  505. /* WriteNewHogFiles()                                     Date: 06/25/1998   */
  506. /*---------------------------------------------------------------------------*/
  507. /* Description: Replace the Hog Files                                        */
  508. /* Returns    : Nothing                                                      */
  509. /* Assumptions: None                                                         */
  510. /* Programmers: Wing F Yuen                                                  */
  511. /*---------------------------------------------------------------------------*/
  512. int WriteNewHogFiles (void)
  513. {
  514.   #if (defined(_MSC_VER) || defined(WC16_))
  515.  
  516.   USHORT     ActionTaken;
  517.   #else                                          /* 32 bit API               */
  518.  
  519.   ULONG      ActionTaken;
  520.   #endif
  521.   HFILE      Hog;
  522.   int        i, HogCount, NewHogCount=1;
  523.   double     HogSize, Overhead;
  524.   char       HogName[256];
  525.  
  526.   HogSize = gNewHogSize;
  527.   #ifndef NDEBUG
  528.  
  529.   printf( "MaxFileSize = %.0f\n", MAX_FILE_SIZE);
  530.   printf( "gNewHogSize = %.0f\n", gNewHogSize);
  531.   #endif
  532.  
  533.   if (HogSize > MAX_FILE_SIZE) {
  534.       do {
  535.           HogSize = HogSize - MAX_FILE_SIZE;
  536.           ++NewHogCount;
  537.       } while (HogSize > MAX_FILE_SIZE);         /* End do                   */
  538.   }
  539.  
  540.   /*-------------------------------------------------------------------------*/
  541.   /* When gOldHogCount differs from NewHogCount, the first run of SpaceHog   */
  542.   /* will not maximize the free disk space. I haven't figure this puzzle     */
  543.   /* out yet. If you do, please email me.                                    */
  544.   /*-------------------------------------------------------------------------*/
  545.  
  546.   #ifndef NDEBUG
  547.  
  548.   printf( "gOldHogCount = %d\n",   gOldHogCount);
  549.   printf( "NewHogCount  = %d\n",   NewHogCount );
  550.   #endif
  551.  
  552.   for (i = 0; i < NewHogCount; i++) {
  553.       /*---------------------------------------------------------------------*/
  554.       /* Rewriting the entire file with DosOpen() is much faster than        */
  555.       /* adjusting its size with chsize().                                   */
  556.       /*---------------------------------------------------------------------*/
  557.       sprintf( HogName, "%s\\%d", gHogFilePath, i);
  558.       #ifndef NDEBUG
  559.  
  560.       printf( "\nRewriting %s\n",  HogName );
  561.       printf( "HogSize  = %.0f\n", HogSize );
  562.       #endif
  563.       gRcApi = DosOpen( HogName,
  564.                         &Hog,
  565.                         &ActionTaken,
  566.                         (ULONG)HogSize,
  567.                         FILE_NORMAL,
  568.                         OPEN_ACTION_CREATE_IF_NEW |
  569.                         OPEN_ACTION_REPLACE_IF_EXISTS,
  570.                         OPEN_SHARE_DENYREADWRITE |
  571.                         OPEN_ACCESS_WRITEONLY,
  572.                         0L);
  573.       if (gRcApi) {
  574.           printf( __FILE__"/WriteNewHogFiles(): DosOpen() returns %u\n",
  575.                   gRcApi);
  576.           return 1;
  577.       }
  578.  
  579.       gRcApi = DosClose( Hog);
  580.       if (gRcApi) {
  581.           printf( __FILE__"/WriteNewHogFiles(): DosClose() returns %u\n",
  582.                   gRcApi);
  583.           return 1;
  584.       }
  585.       HogSize = MAX_FILE_SIZE;
  586.   }                                              /* End for                  */
  587.   /*-------------------------------------------------------------------------*/
  588.   /* Delete any un-needed old hog files                                      */
  589.   /*-------------------------------------------------------------------------*/
  590.   for (i = NewHogCount; i < gOldHogCount; i++) {
  591.       sprintf( HogName, "%s\\%d", gHogFilePath, i);
  592.       remove( HogName);
  593.   }                                              /* End for                  */
  594.  
  595.   return 0;
  596. }                                                /* WriteNewHogFiles()       */
  597.