Back to index

lightning-sunbird  0.9+nobinonly
ds32.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Sean Su <ssu@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include <windows.h>
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <ctype.h>
00044 #include <math.h>
00045 #include <io.h>
00046 
00047 #define MAXLEVEL 30000
00048 #define MAX_BUF  4096
00049 
00050 /* PP: Parse Path */
00051 #define PP_FILENAME_ONLY                1
00052 #define PP_PATH_ONLY                    2
00053 #define PP_ROOT_ONLY                    3
00054 
00055 void GetDirSize(         char *InputName,
00056                 unsigned int   Level,
00057                 ULONGLONG      Sector,
00058                          int   AddDirectorySize,
00059                          int   AutoInfoFormat,
00060                 unsigned int   CurrentLevel,
00061                 ULONGLONG     *TotalDirSize,
00062                 ULONGLONG     *TotalDirCount,
00063                 ULONGLONG     *TotalFileSize,
00064                 ULONGLONG     *TotalAllocSize);
00065 
00066 char DirDepth[MAX_BUF];
00067 
00068 struct Params
00069 {
00070     unsigned long ArgNum;
00071     unsigned int  Level;
00072     ULONGLONG     Sector;
00073              int  SuppressHeader;
00074              int  AutoInfoFormat;
00075              int  AddDirectorySize;
00076     char         *DirName;
00077 };
00078 
00079 void RemoveBackSlash(LPSTR szInput)
00080 {
00081   int   iCounter;
00082   DWORD dwInputLen;
00083 
00084   if(szInput != NULL)
00085   {
00086     dwInputLen = lstrlen(szInput);
00087 
00088     for(iCounter = dwInputLen -1; iCounter >= 0 ; iCounter--)
00089     {
00090       if(szInput[iCounter] == '\\')
00091         szInput[iCounter] = '\0';
00092       else
00093         break;
00094     }
00095   }
00096 }
00097 
00098 void AppendBackSlash(LPSTR szInput, DWORD dwInputSize)
00099 {
00100   if(szInput != NULL)
00101   {
00102     if(*szInput == '\0')
00103     {
00104       if(((DWORD)lstrlen(szInput) + 1) < dwInputSize)
00105       {
00106         lstrcat(szInput, "\\");
00107       }
00108     }
00109     else if(szInput[strlen(szInput) - 1] != '\\')
00110     {
00111       if(((DWORD)lstrlen(szInput) + 1) < dwInputSize)
00112       {
00113         lstrcat(szInput, "\\");
00114       }
00115     }
00116   }
00117 }
00118 
00119 void ParsePath(LPSTR szInput, LPSTR szOutput, DWORD dwOutputSize, DWORD dwType)
00120 {
00121   int   iCounter;
00122   DWORD dwCounter;
00123   DWORD dwInputLen;
00124   BOOL  bFound;
00125 
00126   if((szInput != NULL) && (szOutput != NULL))
00127   {
00128     bFound        = TRUE;
00129     dwInputLen    = lstrlen(szInput);
00130     ZeroMemory(szOutput, dwOutputSize);
00131 
00132     if(dwInputLen < dwOutputSize)
00133     {
00134       switch(dwType)
00135       {
00136         case PP_FILENAME_ONLY:
00137           for(iCounter = dwInputLen - 1; iCounter >= 0; iCounter--)
00138           {
00139             if(szInput[iCounter] == '\\')
00140             {
00141               lstrcpy(szOutput, &szInput[iCounter + 1]);
00142               bFound = TRUE;
00143               break;
00144             }
00145           }
00146           if(bFound == FALSE)
00147             lstrcpy(szOutput, szInput);
00148 
00149           break;
00150 
00151         case PP_PATH_ONLY:
00152           for(iCounter = dwInputLen - 1; iCounter >= 0; iCounter--)
00153           {
00154             if(szInput[iCounter] == '\\')
00155             {
00156               lstrcpy(szOutput, szInput);
00157               szOutput[iCounter + 1] = '\0';
00158               bFound = TRUE;
00159               break;
00160             }
00161           }
00162           if(bFound == FALSE)
00163             lstrcpy(szOutput, szInput);
00164 
00165           break;
00166 
00167         case PP_ROOT_ONLY:
00168           if(szInput[1] == ':')
00169           {
00170             szOutput[0] = szInput[0];
00171             szOutput[1] = szInput[1];
00172             AppendBackSlash(szOutput, dwOutputSize);
00173           }
00174           else if(szInput[1] == '\\')
00175           {
00176             int iFoundBackSlash = 0;
00177             for(dwCounter = 0; dwCounter < dwInputLen; dwCounter++)
00178             {
00179               if(szInput[dwCounter] == '\\')
00180               {
00181                 szOutput[dwCounter] = szInput[dwCounter];
00182                 ++iFoundBackSlash;
00183               }
00184 
00185               if(iFoundBackSlash == 3)
00186                 break;
00187             }
00188 
00189             if(iFoundBackSlash != 0)
00190               AppendBackSlash(szOutput, dwOutputSize);
00191           }
00192           break;
00193       }
00194     }
00195   }
00196 }
00197 
00198 // returns size of a directory
00199 void GetDirSize(         char *InputName,
00200                 unsigned int   Level,
00201                 ULONGLONG      Sector,
00202                          int   AddDirectorySize,
00203                          int   AutoInfoFormat,
00204                 unsigned int   CurrentLevel,
00205                 ULONGLONG     *TotalDirSize,
00206                 ULONGLONG     *TotalDirCount,
00207                 ULONGLONG     *TotalFileSize,
00208                 ULONGLONG     *TotalAllocSize)
00209 {
00210     HANDLE          hDir;
00211     WIN32_FIND_DATA wfdFindFileData;
00212     ULONGLONG       llFileSize;
00213     ULONGLONG       TmpTotalFileSize;
00214     ULONGLONG       TmpTotalAllocSize;
00215     int             InputNameLen = strlen(InputName);
00216     int             DirNameLen   = InputNameLen;
00217     char            DirName[MAX_BUF];
00218     char            szBuf[MAX_BUF];
00219 
00220     memset(DirName, '\0', sizeof(DirName));
00221     memcpy(DirName, InputName, InputNameLen);
00222 
00223     *TotalFileSize  = 0;
00224     *TotalAllocSize = 0;
00225 
00226     AppendBackSlash(DirName, sizeof(DirName));
00227     lstrcat(DirName, "*.*");
00228     if((hDir = FindFirstFile(DirName, &wfdFindFileData)) != INVALID_HANDLE_VALUE)
00229     {
00230         do
00231         {
00232             if((wfdFindFileData.dwFileAttributes & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
00233               continue;
00234 
00235             if(wfdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00236             {
00237                 if((lstrcmpi(wfdFindFileData.cFileName, ".") != 0) && (lstrcmpi(wfdFindFileData.cFileName, "..") != 0))
00238                 {
00239                     ParsePath(DirName, szBuf, sizeof(szBuf), PP_PATH_ONLY);
00240                     AppendBackSlash(szBuf, sizeof(szBuf));
00241                     strcat(szBuf, wfdFindFileData.cFileName);
00242 
00243                     TmpTotalFileSize  = *TotalFileSize;
00244                     TmpTotalAllocSize = *TotalAllocSize;
00245                     GetDirSize(szBuf,
00246                                Level,
00247                                Sector,
00248                                AddDirectorySize,
00249                                AutoInfoFormat,
00250                                CurrentLevel + 1,
00251                                TotalDirSize,
00252                                TotalDirCount,
00253                                TotalFileSize,
00254                                TotalAllocSize);
00255                     TmpTotalFileSize  += *TotalFileSize;
00256                     TmpTotalAllocSize += *TotalAllocSize;
00257 
00258                     *TotalFileSize  = TmpTotalFileSize;
00259                     *TotalAllocSize = TmpTotalAllocSize;
00260                 }
00261             }
00262             else
00263             {
00264                 llFileSize      = (wfdFindFileData.nFileSizeHigh * MAXDWORD) + wfdFindFileData.nFileSizeLow;
00265                 *TotalFileSize += llFileSize;
00266 
00267                 if(llFileSize <= Sector)
00268                     *TotalAllocSize += Sector;
00269                 else
00270                 {
00271                     // get the ceiling of llFileSize/Sector
00272                     if((llFileSize % Sector) == 0)
00273                         *TotalAllocSize += Sector * ((llFileSize / Sector));
00274                     else
00275                         *TotalAllocSize += Sector * ((llFileSize / Sector) + 1);
00276                 }
00277             }
00278         } while(FindNextFile(hDir, &wfdFindFileData));
00279 
00280         FindClose(hDir);
00281     }
00282 
00283     *TotalDirSize   += Sector;
00284     *TotalDirCount  += 1;
00285     if(AddDirectorySize == 1)
00286         *TotalAllocSize += Sector;
00287 
00288     if(CurrentLevel <= Level)
00289     {
00290         if(*TotalFileSize == 0)
00291         {
00292             if(AutoInfoFormat == 0)
00293             {
00294                 printf("                   0 -                    0 - %s\n", InputName);
00295             }
00296             else
00297             {
00298                 if(Level == 0)
00299                 {
00300                     printf("0\n");
00301                 }
00302                 else
00303                 {
00304                     printf("                   0\n");
00305                 }
00306             }
00307         }
00308         else
00309         {
00310             if(AutoInfoFormat == 0)
00311             {
00312                 printf("%20.0I64u - %20.0I64u - %s\n", *TotalFileSize, *TotalAllocSize, InputName);
00313             }
00314             else
00315             {
00316                 if(Level == 0)
00317                 {
00318                     printf("%I64u\n", *TotalAllocSize);
00319                 }
00320                 else
00321                 {
00322                     printf("%20.0I64u\n", *TotalAllocSize);
00323                 }
00324             }
00325         }
00326     }
00327 }
00328 
00329 void PrintUsage()
00330 {
00331     printf("Usage: ds32.exe [/? /h /L <number> /C <number> /S /A directory]\n\n");
00332     printf("       /?          : this usage\n");
00333     printf("       /h          : this usage\n");
00334     printf("       /L <number> : the depth of directory to display info for\n");
00335     printf("       /C <number> : calculate allocation space using this number\n");
00336     printf("       /S          : Suppress header information\n");
00337     printf("       /A          : Allocation information only (bare format)\n");
00338     printf("       /D          : Add size of directories to calculation (1 directory takes up a cluster size of space)\n");
00339     printf("       directory   : the directory to calcualte\n");
00340 }
00341 
00342 void PrintBadArg(char *String)
00343 {
00344     printf("Error: bad argument %s\n", String);
00345     PrintUsage();
00346     exit(1);
00347 }
00348 
00349 void PrintBadDir(char *String)
00350 {
00351     printf("Error: bad directory %s\n", String);
00352     PrintUsage();
00353     exit(1);
00354 }
00355 
00356 char *ParseForUNCSourceDrivePath(char *DirName, char *NewDirName)
00357 {
00358     int QuitCountingFlag;
00359     int NameAndVolume;
00360     int BackSlashCntr;
00361     int charposition;
00362     int count;
00363     int numchars;
00364 
00365     // Test for UNC path
00366     if((DirName[0] == '\\') && (DirName[1] == '\\'))
00367     {
00368         QuitCountingFlag = 1;               // Stop incrementing NameAndVolume
00369         NameAndVolume    = 0;               // Initialize string length
00370         BackSlashCntr    = 2;               // Backslash count is two
00371         charposition     = 1;               // Initialize position in string to the second position
00372         numchars         = strlen(DirName); //Get the total length of UNC Path
00373 
00374         // Count the character position and the number of backslashes
00375         for(count = 2; count < numchars; count++)
00376         {
00377             ++charposition;
00378             if(DirName[charposition] == '\\')
00379                 ++BackSlashCntr;
00380 
00381             // Save the number of chars equal to the Computer name and volume
00382             if((BackSlashCntr == 4) && QuitCountingFlag)
00383             {
00384                 NameAndVolume    = charposition;
00385                 QuitCountingFlag = 0;
00386             }
00387         }
00388         if(NameAndVolume == 0)
00389             NameAndVolume = numchars;
00390 
00391         // Save the UNC path
00392         memcpy(NewDirName, DirName, NameAndVolume);
00393     }
00394     else
00395         memcpy(NewDirName, DirName, 2);
00396 
00397     return(NewDirName);
00398 }
00399 
00400 
00401 int ParseArgumentList(struct Params *ArgList, int argc, char *argv[])
00402 {
00403     int i;
00404 
00405     ArgList->ArgNum         = argc;
00406     ArgList->Level          = -1;
00407     ArgList->Sector         = -1;
00408     ArgList->SuppressHeader = 0;
00409     ArgList->AutoInfoFormat = 0;
00410     ArgList->DirName        = (char *)calloc(MAX_BUF, 1);
00411 
00412     for(i = 1; i < argc; i++)
00413     {
00414         // Check for /L parameter
00415         if((argv[i][0] == '/') || (argv[i][0] == '-'))
00416         {
00417             switch(tolower(argv[i][1]))
00418             {
00419                 case 'l':
00420                     if(argv[i][2] != '\0')
00421                     {
00422                         if(ArgList->Level == -1)
00423                             if((ArgList->Level = atol(&(argv[i][2]))) == 0)
00424                                 if(isdigit(argv[i][2]) == 0)
00425                                     PrintBadArg(argv[i]);
00426                     }
00427                     else
00428                     {
00429                         ++i;
00430                         if(ArgList->Level == -1)
00431                             if((ArgList->Level = atol(argv[i])) == 0)
00432                                 if(isdigit(argv[i][0]) == 0)
00433                                     PrintBadArg(argv[--i]);
00434                     }
00435                     continue;
00436 
00437                 case 'c':
00438                     if(argv[i][2] != '\0')
00439                     {
00440                         if(ArgList->Sector == -1)
00441                             if((ArgList->Sector = atol(&(argv[i][2]))) == 0)
00442                                 PrintBadArg(argv[i]);
00443                     }
00444                     else
00445                     {
00446                         ++i;
00447                         if(ArgList->Sector == -1)
00448                             if((ArgList->Sector = atol(argv[i])) == 0)
00449                                 PrintBadArg(argv[--i]);
00450                     }
00451                     continue;
00452 
00453                 case 's':
00454                     if(argv[i][2] == '\0')
00455                     {
00456                         if(ArgList->SuppressHeader == 0)
00457                             ArgList->SuppressHeader = 1;
00458                     }
00459                     else
00460                     {
00461                         PrintBadArg(argv[i]);
00462                     }
00463                     continue;
00464 
00465                 case 'd':
00466                     if(argv[i][2] == '\0')
00467                     {
00468                         ArgList->AddDirectorySize = 1;
00469                     }
00470                     else
00471                     {
00472                         PrintBadArg(argv[i]);
00473                     }
00474                     continue;
00475 
00476                 case 'a':
00477                     if(argv[i][2] == '\0')
00478                     {
00479                         if(ArgList->AutoInfoFormat == 0)
00480                             ArgList->AutoInfoFormat = 1;
00481                     }
00482                     else
00483                     {
00484                         PrintBadArg(argv[i]);
00485                     }
00486                     continue;
00487 
00488                 case 'h':
00489                 case '?':
00490                     PrintUsage();
00491                     exit(0);
00492             }
00493         }
00494 
00495         // Check for existance of directory or file
00496         if(access(argv[i], 0) == 0)
00497         {
00498             if(ArgList->DirName[0] == '\0')
00499                 memcpy(ArgList->DirName, argv[i], strlen(argv[i]));
00500         }
00501         else
00502             PrintBadDir(argv[i]);
00503     }
00504     return(0);
00505 }
00506 
00507 int main(int argc, char *argv[])
00508 {
00509     ULONGLONG     SectorsPerCluster = 0;
00510     ULONGLONG     FreeClusters      = 0;
00511     ULONGLONG     Clusters          = 0;
00512     ULONGLONG     BytesPerSector    = 0;
00513     unsigned int  CurrentLevel      = 0;
00514     ULONGLONG     TotalDirSize      = 0;
00515     ULONGLONG     TotalDirCount     = 0;
00516     ULONGLONG     TotalFileSize     = 0;
00517     ULONGLONG     TotalAllocSize    = 0;
00518     char          UNCPath[MAX_BUF];
00519     char          szBuf[MAX_BUF];
00520     struct Params ArgList;
00521 
00522     memset(UNCPath, 0, sizeof(UNCPath));
00523 
00524     if(ParseArgumentList(&ArgList, argc, argv))
00525         return(1);
00526     else
00527     {
00528         if(ArgList.DirName[strlen(ArgList.DirName) - 1] == '\\')
00529             ArgList.DirName[strlen(ArgList.DirName) - 1] = '\0';
00530 
00531         if(ArgList.DirName[0] == '\0')
00532         {
00533             if(GetCurrentDirectory(MAX_BUF, ArgList.DirName) == NULL)
00534             {
00535                 perror("GetCurrentDirectory()");
00536                 printf("Error: could not get current working directory\n");
00537                 exit(1);
00538             }
00539         }
00540 
00541         if((ArgList.DirName[1] == ':') || ((ArgList.DirName[0] == '\\') && (ArgList.DirName[1] == '\\')))
00542             ParseForUNCSourceDrivePath(ArgList.DirName, UNCPath);
00543 
00544         if((ArgList.DirName[1] != ':') && (ArgList.DirName[0] != '\\'))
00545         {
00546             if(GetCurrentDirectory(sizeof(szBuf), szBuf) == NULL)
00547             {
00548                 perror("GetCurrentDirectory()");
00549                 printf("Error: could not get current working directory\n");
00550                 exit(1);
00551             }
00552             ParsePath(szBuf, UNCPath, sizeof(UNCPath), PP_ROOT_ONLY);
00553         }
00554 
00555         AppendBackSlash(UNCPath, sizeof(UNCPath));
00556 
00557         if(ArgList.Sector == -1)
00558         {
00559             GetDiskFreeSpace(UNCPath, (PDWORD)&SectorsPerCluster, (PDWORD)&BytesPerSector, (PDWORD)&FreeClusters, (PDWORD)&Clusters);
00560             ArgList.Sector = SectorsPerCluster * BytesPerSector;
00561         }
00562 
00563         if(ArgList.SuppressHeader == 0)
00564         {
00565             printf("  Root Path Name           : %s\n",   UNCPath);
00566             printf("  Sectors Per Cluster      : %I64u\n",   SectorsPerCluster);
00567             printf("  Bytes Per Sectors        : %I64u\n",   BytesPerSector);
00568             printf("  Bytes Per Cluster       *: %I64u\n",   ArgList.Sector);
00569             printf("  Free Clusters            : %I64u\n",   FreeClusters);
00570             printf("  Total Number Of Clusters : %I64u\n\n", Clusters);
00571         }
00572 
00573         GetDirSize(ArgList.DirName,
00574                    ArgList.Level,
00575                    ArgList.Sector,
00576                    ArgList.AddDirectorySize,
00577                    ArgList.AutoInfoFormat,
00578                    CurrentLevel,
00579                    &TotalDirSize,
00580                    &TotalDirCount,
00581                    &TotalFileSize,
00582                    &TotalAllocSize);
00583 
00584         if(ArgList.AutoInfoFormat == 0)
00585         {
00586             if(ArgList.AddDirectorySize == 1)
00587             {
00588                 printf("                       %20.0I64u - total size of directories\n", TotalDirSize);
00589                 printf("                       %20.0I64u - number of directories\n",    TotalDirCount);
00590             }
00591 
00592             printf("--------------------   --------------------\n");
00593             printf("         total files             allocation\n");
00594         }
00595     }
00596     free(ArgList.DirName);
00597     return(0);
00598 }