📄 comptool.c
字号:
/* TS = none */
/*
** COMPTOOL.C -- Compression Tool for Setup Toolkits.
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef EAS
#include <malloc.h>
#endif /* EAS */
#include <io.h>
#include <string.h>
#include <fcntl.h>
#include <direct.h>
#include <ctype.h>
#include <sys\types.h>
#include <sys\stat.h>
#ifndef OS2_VER
#include <dos.h>
#endif /* !OS2_VER */
#include "..\sutkcomp.h"
#include "strings.h"
/* forward declarations */
int main(int argc, char ** argv);
void MakeDirs(SZ rgchDestArg);
void CopyAndFixSzDir(SZ rgchArg, SZ szArg);
BOOL FWildcardPath(SZ rgchSrcArg);
BOOL FDirectory(SZ rgchSrcArg);
void RecurseOnDir(SZ rgchSrcDir, SZ rgchDestDir);
void HandleDirFiles(SZ rgchSrcArg, SZ rgchDestDir);
void HandleOneFile(SZ rgchSrcFile, SZ rgchDestArg);
void Usage(SHORT wExitCode);
BOOL FEnsureSzBaseDoesNotExist(SZ szBaseFile);
BOOL FIncrementSzBase(SZ szBaseFile);
#ifdef EAS
#ifdef OS2_VER
BOOL QueryEAs(CHAR * pszPath, CHAR ** pEABuf);
#endif /* !OS2_VER */
#endif /* EAS */
extern void ExitErrorMsgRc(SHORT rc);
extern BOOL FUserConfirmsYN(void);
extern void DividePathIntoBaseExt(SZ szPath, SZ *pszBase, SZ *pszExt);
extern void MSCopyright(BOOL fCompress);
extern void GetDollarSzFromSzSrc(SZ szSrcFile, SZ szDstFile);
extern BOOL vfForceOverwrite;
BOOL fDollarSuffix = (BOOL)TRUE;
#ifdef JJJ1
#define wAlgTypeDefault 3
#else
#ifdef ZK1
#define wAlgTypeDefault 2
#else
#ifdef NC_XOR1
#define wAlgTypeDefault 1
#else
Force_a_compile_error__need_to_define_at_least_one_alg_type
#endif /* NC_XOR1 */
#endif /* ZK1 */
#endif /* JJJ1 */
struct _SDL
{
SZ szSubdir;
struct _SDL * psdlNext;
};
typedef struct _SDL SDL;
/* have our own globals because WReadHeaderInfo resets its globals */
USHORT wAlgType = wAlgTypeDefault;
BOOL fIncludeSrcLength = TRUE;
BOOL fIncludeChecksum = FALSE;
BOOL fIncludeBase = FALSE;
BOOL fIncludeExt = FALSE;
#ifdef EAS
BOOL fIncludeEAs = TRUE;
#endif /* EAS */
USHORT cbText = 0;
SZ szText = NULL;
BOOL fComputeOnly = FALSE;
BOOL fOnePieceOnly = FALSE;
LONG lcbSize = NIL;
int cFiles = 0;
LONG lcbSrcTotal = 0L;
LONG lcbDestTotal = 0L;
/*
** int main(int argc, char * argv[])
**
** Main compress routine.
*/
int main(int argc, char * argv[])
{
int iArg;
CHAR rgchSrcArg[_MAX_PATH + _MAX_FNAME + _MAX_EXT + 1];
CHAR rgchDestArg[_MAX_PATH + _MAX_FNAME + _MAX_EXT + 1];
MSCopyright((BOOL)TRUE);
vfForceOverwrite = FALSE;
if (argc < 2)
Usage(19);
/* Parse command line arguments */
for (iArg = 1; iArg < argc
&& (argv[iArg][0] == '-' || argv[iArg][0] == '/'); iArg++)
{
switch (argv[iArg][1])
{
default:
Usage(20);
case 'a':
case 'A':
wAlgType = atoi(&(argv[iArg][2]));
break;
case 'b':
case 'B':
fIncludeBase = (BOOL)TRUE;
break;
case 'c':
case 'C':
/* REVIEW */
#if 1
printf(szNoChecksum);
#else
fIncludeChecksum = (BOOL)TRUE;
#endif
break;
case 'e':
case 'E':
fIncludeExt = (BOOL)TRUE;
break;
case 'f':
case 'F':
vfForceOverwrite = (BOOL)TRUE;
break;
case '?':
case 'h':
case 'H':
Usage(0);
case 'l':
case 'L':
fIncludeSrcLength = (BOOL)FALSE;
break;
case 'q':
case 'Q':
fComputeOnly = (BOOL)TRUE;
break;
case 's':
case 'S':
lcbSize = atol(argv[iArg] + 2);
lcbSize *= (ULONG)512; /* user enters 512 bytes */
break;
case 't':
case 'T':
cbText = strlen(argv[iArg]) - 2; /* skip flag */
szText = argv[iArg] + 2;
break;
#ifdef EAS
case 'x':
case 'X':
fIncludeEAs = FALSE;
break;
#endif /* EAS */
case 'z':
case 'Z':
fOnePieceOnly = (BOOL)TRUE;
lcbSize = atol(argv[iArg] + 2);
lcbSize *= (ULONG)512; /* user enters 512 bytes */
break;
case '$':
fDollarSuffix = FALSE;
break;
}
}
if (lcbSize != NIL && fComputeOnly)
printf(szNoQWithS);
/* there needs to be at least one and at most two filenames after flags */
if (iArg != argc - 1 && iArg != argc - 2)
Usage(19);
CopyAndFixSzDir(rgchSrcArg, argv[iArg++]);
if (iArg < argc)
CopyAndFixSzDir(rgchDestArg, argv[iArg]);
else
rgchDestArg[0] = '\0';
/* info is passed as global vars */
if (FWildcardPath(rgchSrcArg))
{
if (!fComputeOnly)
MakeDirs(rgchDestArg);
if (fComputeOnly || FDirectory(rgchDestArg))
HandleDirFiles(rgchSrcArg, rgchDestArg);
else
printf(szDestDirWild);
}
else if (FDirectory(rgchSrcArg))
{
if (!fComputeOnly)
MakeDirs(rgchDestArg);
if (fComputeOnly || FDirectory(rgchDestArg))
RecurseOnDir(rgchSrcArg, rgchDestArg);
else
printf(szDestDirTree);
}
else
HandleOneFile(rgchSrcArg, rgchDestArg);
if (cFiles > 1)
{
printf(szTotals);
printf(szBytesCompressed, lcbSrcTotal, lcbDestTotal);
printf(szPercentSavings,
((200 * (lcbSrcTotal - lcbDestTotal) / lcbSrcTotal) + 1 ) / 2);
}
exit(0);
return(0);
}
void MakeDirs(SZ rgchDestArg)
{
int ichMac = strlen(rgchDestArg) - 1;
SZ pchSlash;
if (ichMac >= 0 && rgchDestArg[ichMac] != '\\'
&& rgchDestArg[ichMac] != ':')
strcat(rgchDestArg, "\\");
pchSlash = strchr(rgchDestArg + 1, '\\');
while (pchSlash != NULL)
{
*pchSlash = '\0';
if (!fComputeOnly)
mkdir(rgchDestArg);
*pchSlash = '\\';
pchSlash = strchr(pchSlash + 1, '\\');
}
}
void CopyAndFixSzDir(SZ rgchArg, SZ szArg)
{
if (szArg == NULL || *szArg == '\0')
rgchArg[0] = '\0';
else
{
int ichMac = strlen(szArg) - 1;
strcpy(rgchArg, szArg);
if (FDirectory(rgchArg) && rgchArg[ichMac] != '\\'
&& rgchArg[ichMac] != ':')
strcat(rgchArg, "\\");
}
}
BOOL FWildcardPath(SZ rgchSrcArg)
{
if (strcspn(rgchSrcArg, "?*") != strlen(rgchSrcArg))
return((BOOL)TRUE);
return(FALSE);
}
BOOL FDirectory(SZ rgchSrcArg)
{
int ichMac;
struct stat statBuf;
if (rgchSrcArg == NULL || *rgchSrcArg == '\0')
return((BOOL)TRUE);
ichMac = strlen(rgchSrcArg) - 1;
if (*(rgchSrcArg + ichMac) == '\\' || *(rgchSrcArg + ichMac) == ':')
return((BOOL)TRUE);
if (!stat(rgchSrcArg, &statBuf) && (statBuf.st_mode & S_IFDIR))
return((BOOL)TRUE);
return(FALSE);
}
#ifdef OS2_VER
#define ZZNAMEZZ achName
#else /* !OS2_VER */
#define ZZNAMEZZ name
#endif /* !OS2_VER */
void RecurseOnDir(SZ rgchSrcDir, SZ rgchDestDir)
{
int cchSrcSav = strlen(rgchSrcDir);
int cchDestSav = strlen(rgchDestDir);
BOOL fDirFound;
SDL * psdlHead = NULL;
#ifdef OS2_VER
HDIR hdir;
USHORT usSearchCount;
FILEFINDBUF ffindBuf;
#else /* !OS2_VER */
struct find_t ffindBuf;
#endif /* !OS2_VER */
strcat(rgchSrcDir, "*.*");
#ifdef OS2_VER
hdir = HDIR_CREATE;
usSearchCount = 1;
fDirFound = (BOOL)(!DosFindFirst(rgchSrcDir, &hdir,
FILE_NORMAL | FILE_DIRECTORY, &ffindBuf, sizeof(FILEFINDBUF),
&usSearchCount, 0L));
#else /* !OS2_VER */
fDirFound = (BOOL)(!_dos_findfirst(rgchSrcDir, _A_SUBDIR, &ffindBuf));
#endif /* !OS2_VER */
while (fDirFound)
{
if (strcmp(ffindBuf.ZZNAMEZZ, ".") && strcmp(ffindBuf.ZZNAMEZZ, ".."))
{
#ifdef OS2_VER
if (ffindBuf.attrFile & FILE_DIRECTORY)
#else /* !OS2_VER */
struct stat statBuf;
strcpy(rgchSrcDir + cchSrcSav, ffindBuf.ZZNAMEZZ);
if (!stat(rgchSrcDir, &statBuf) && (statBuf.st_mode & S_IFDIR))
#endif /* !OS2_VER */
{
SDL * psdl = (SDL *)malloc(sizeof(SDL));
psdl->szSubdir = strdup(ffindBuf.ZZNAMEZZ);
psdl->psdlNext = psdlHead;
psdlHead = psdl;
}
}
#ifdef OS2_VER
usSearchCount = 1;
fDirFound = (BOOL)(!DosFindNext(hdir, &ffindBuf, sizeof(FILEFINDBUF),
&usSearchCount));
#else /* !OS2_VER */
fDirFound = (BOOL)(!_dos_findnext(&ffindBuf));
#endif /* !OS2_VER */
}
#ifdef OS2_VER
DosFindClose(hdir);
#endif /* OS2_VER */
strcpy(rgchSrcDir + cchSrcSav, "*.*");
rgchDestDir[cchDestSav] = '\0';
HandleDirFiles(rgchSrcDir, rgchDestDir);
while (psdlHead != NULL)
{
SDL * psdlSav = psdlHead;
strcat(strcpy(rgchSrcDir + cchSrcSav, psdlHead->szSubdir), "\\");
strcpy(rgchDestDir + cchDestSav, psdlHead->szSubdir);
if (!fComputeOnly)
mkdir(rgchDestDir);
strcat(rgchDestDir, "\\");
RecurseOnDir(rgchSrcDir, rgchDestDir);
psdlHead = psdlHead->psdlNext;
free(psdlSav->szSubdir);
free(psdlSav);
}
}
void HandleDirFiles(SZ rgchSrcArg, SZ rgchDestDir)
{
int cchSrcSav = strlen(rgchSrcArg);
int cchDestSav = strlen(rgchDestDir);
BOOL fFileFound;
#ifdef OS2_VER
HDIR hdir;
USHORT usSearchCount;
FILEFINDBUF ffindBuf;
#else /* !OS2_VER */
struct find_t ffindBuf;
#endif /* !OS2_VER */
/* only count chars in SrcPath (includes backslash) */
while (cchSrcSav && *(rgchSrcArg + cchSrcSav - 1) != '\\'
&& *(rgchSrcArg + cchSrcSav - 1) != ':')
cchSrcSav--;
#ifdef OS2_VER
hdir = HDIR_CREATE;
usSearchCount = 1;
fFileFound = (BOOL)(!DosFindFirst(rgchSrcArg, &hdir,
FILE_NORMAL | FILE_READONLY, &ffindBuf, sizeof(FILEFINDBUF),
&usSearchCount, 0L));
#else /* !OS2_VER */
fFileFound = (BOOL)(!_dos_findfirst(rgchSrcArg, _A_NORMAL | _A_RDONLY,
&ffindBuf));
#endif /* !OS2_VER */
while (fFileFound)
{
strcpy(rgchSrcArg + cchSrcSav, ffindBuf.ZZNAMEZZ);
rgchDestDir[cchDestSav] = '\0';
HandleOneFile(rgchSrcArg, rgchDestDir);
#ifdef OS2_VER
usSearchCount = 1;
fFileFound = (BOOL)(!DosFindNext(hdir, &ffindBuf, sizeof(FILEFINDBUF),
&usSearchCount));
#else /* !OS2_VER */
fFileFound = (BOOL)(!_dos_findnext(&ffindBuf));
#endif /* !OS2_VER */
}
#ifdef OS2_VER
DosFindClose(hdir);
#endif /* OS2_VER */
}
void HandleOneFile(SZ rgchSrcFile, SZ rgchDestArg)
{
SZ szSrcBase;
SZ szSrcExt;
int fhSrc;
int fhDest;
LONG lcbSrc;
LONG lcbDest;
LONG lcbCompressed = 0L;
BOOL fDotRemoved = FALSE;
#ifdef OS2_VER
FILESTATUS fsSrc;
#else /* !OS2_VER */
USHORT usDate;
USHORT usTime;
#endif /* !OS2_VER */
printf("%s\n", rgchSrcFile);
if (FDirectory(rgchDestArg))
{
CHAR * szSrcFileName = strrchr(rgchSrcFile, '\\');
if (szSrcFileName == NULL)
szSrcFileName = strrchr(rgchSrcFile, ':');
if (szSrcFileName == NULL)
szSrcFileName = rgchSrcFile;
else
szSrcFileName++;
if (fDollarSuffix)
GetDollarSzFromSzSrc(szSrcFileName,
rgchDestArg + strlen(rgchDestArg));
else
strcat(rgchDestArg, szSrcFileName);
if (!stricmp(rgchDestArg, rgchSrcFile))
FIncrementSzBase(rgchDestArg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -