📄 zipv.c
字号:
return 0;
}
/* It is probably not possible for the FileName to have a length
of 0 but who knows. */
if(CentralDirRecord.FileNameLength > 0) {
/* The file name can be long so allocate space for the name as
needed rather that write to a statically allocated array */
if((FileName = malloc(CentralDirRecord.FileNameLength + 1)) == NULL) {
printf("Out of memory\n\n");
exit(1);
}
/* Read the file name. */
BytesRead = read(ZipFileHandle,FileName,CentralDirRecord.FileNameLength);
if(BytesRead != CentralDirRecord.FileNameLength) {
printf("Invalid ZIP file format\n\n");
close(ZipFileHandle);
return 0;
}
/* Add the trailing \0 byte. */
FileName[CentralDirRecord.FileNameLength] = '\0';
/* Display the record. */
DisplayHeaderRecord(CentralDirRecord,FileName);
/* The file name is not needed any more. */
free(FileName);
}
/* Skip over the extra field and the comment field */
FileOffset = CentralDirRecord.ExtraFieldLength +
CentralDirRecord.CommentFieldLength;
if(FileOffset > 0L) {
if(lseek(ZipFileHandle,FileOffset,SEEK_CUR) == -1) {
printf("Invalid ZIP file format\n\n");
close(ZipFileHandle);
return 0;
}
}
/* Read the signature from the next record. */
BytesRead = read(ZipFileHandle,(char *)&CentralDirRecord,sizeof(long));
if(BytesRead != sizeof(long)) {
printf("Invalid ZIP file format\n\n");
close(ZipFileHandle);
return 0;
}
/* If we get a match then we found the "End of central dir record"
and we are done. */
if(CentralDirRecord.Signature == 0x06054b50) {
break;
}
}
close(ZipFileHandle);
DisplayTotals();
return 0;
}
DisplayHeaderRecord(struct CENTRAL_RECORD CentralDirRecord, char *FileName)
{
int Month,
Day,
Year,
Hour,
Minutes,
StowageFactor;
char *NamePtr;
long SizeReduction;
if(CentralDirRecord.UnCompressedSize == 0) {
StowageFactor = 0;
}
else {
if(CentralDirRecord.CompressedSize <= CentralDirRecord.UnCompressedSize) {
SizeReduction = CentralDirRecord.UnCompressedSize - CentralDirRecord.CompressedSize;
if(SizeReduction == 0L) {
StowageFactor = 0;
}
else {
SizeReduction = SizeReduction * 100L + 50;
StowageFactor = (int)(SizeReduction/CentralDirRecord.UnCompressedSize);
}
}
else {
SizeReduction = CentralDirRecord.CompressedSize - CentralDirRecord.UnCompressedSize;
SizeReduction = SizeReduction * 100L + 50;
StowageFactor = (int)(SizeReduction/CentralDirRecord.UnCompressedSize);
StowageFactor *= -1;
}
}
if(StowageFactor >= 100) {
StowageFactor = 0;
}
/* Convert the DOS internal date and time format to something we can
use for output. */
Month = (CentralDirRecord.FileDate >> 5) & 0x0f;
Day = CentralDirRecord.FileDate & 0x1f;
Year = ((CentralDirRecord.FileDate >> 9) & 0x7f) + 80;
if(CentralDirRecord.FileTime > 0) {
Hour = (CentralDirRecord.FileTime >> 11) & 0x1f;
Minutes = (CentralDirRecord.FileTime >> 5) & 0x3f;
}
else {
Hour = 0;
Minutes = 0;
}
/* The ZIP documentation says that path names are stored with '/'s
rather than '\'s. Look for a '/' and if so point to the file
name rather than the whole path name. */
if((NamePtr = strrchr(FileName,'/')) == NULL) {
NamePtr = FileName;
}
printf("%-14s%8ld %s %2d%% %8ld %02d %s %2d %02d:%02d %08lX\n",
NamePtr,
CentralDirRecord.UnCompressedSize,
DisplayCompressionType(CentralDirRecord.CompressionMethod),
StowageFactor,
CentralDirRecord.CompressedSize,
Day,
DisplayMonthName(Month),
Year,
Hour,
Minutes,
CentralDirRecord.CRC32);
TotalFiles += 1;
TotalBytes += CentralDirRecord.CompressedSize;
TotalUnCompressedBytes += CentralDirRecord.UnCompressedSize;
return 0;
}
DisplayTotals()
{
int StowageFactor;
long SizeReduction;
printf("============ ======== ======== ==== ======== ========= ====== ========\n");
if(TotalUnCompressedBytes == 0) {
StowageFactor = 0;
}
else {
if(TotalBytes <= TotalUnCompressedBytes) {
SizeReduction = TotalUnCompressedBytes - TotalBytes;
if(SizeReduction == 0L) {
StowageFactor = 0;
}
else {
SizeReduction = SizeReduction * 100L + 50;
StowageFactor = (int)(SizeReduction/TotalUnCompressedBytes);
}
}
else {
SizeReduction = TotalBytes - TotalUnCompressedBytes;
SizeReduction = SizeReduction * 100L + 50;
StowageFactor = (int)(SizeReduction/TotalUnCompressedBytes);
StowageFactor *= -1;
}
}
if(StowageFactor >= 100) {
StowageFactor = 0;
}
printf("*total%6d %8ld %2d%% %8ld\n\n",
TotalFiles,
TotalUnCompressedBytes,
StowageFactor,
TotalBytes);
return 0;
}
char *DisplayCompressionType(int Compression)
{
switch (Compression) {
case 0:
return " Stored ";
break;
case 1:
return " Shrunk ";
break;
case 2:
return "Reduced1";
break;
case 3:
return "Reduced2";
break;
case 4:
return "Reduced3";
break;
case 5:
return "Reduced4";
break;
default:
return "Unknown ";
break;
}
}
char *DisplayMonthName(int Month)
{
switch (Month) {
case 1:
return "Jan";
break;
case 2:
return "Feb";
break;
case 3:
return "Mar";
break;
case 4:
return "Apr";
break;
case 5:
return "May";
break;
case 6:
return "Jun";
break;
case 7:
return "Jul";
break;
case 8:
return "Aug";
break;
case 9:
return "Sep";
break;
case 10:
return "Oct";
break;
case 11:
return "Nov";
break;
case 12:
return "Dec";
break;
}
}
/*
* BuildFileList() uses the _dos_findfirst() and _dos_findnext() routines
* to build a linked list of all files which match FileMask.
*
* _dos_findfirst() is from the Microsoft C library. There is a Turbo C
* equivalent but I don't know the name.
*
*/
BuildFileList(char *FileMask)
{
char FileDirectory[83],
*StrPtr;
struct find_t FileInfo;
struct stat StatBuffer;
strcpy(FileDirectory,FileMask);
if((StrPtr = strrchr(FileDirectory,'\\')) != NULL) {
StrPtr++;
*StrPtr = '\0';
}
else {
if((StrPtr = strrchr(FileDirectory,':')) != NULL) {
StrPtr++;
*StrPtr = '\0';
}
else {
FileDirectory[0] = '\0';
}
}
if(_dos_findfirst(FileMask,_A_NORMAL|_A_RDONLY,&FileInfo) == 0) {
do {
if(FileList == NULL) {
FileList = calloc(sizeof(struct FILELIST),1);
/* This is not likely to happen but you never know. */
if(FileList == NULL) {
printf("Out of memory\n\n");
exit(1);
}
FilePtr = FileList;
}
else {
FilePtr->NextFile = calloc(sizeof(struct FILELIST),1);
if(FilePtr->NextFile == NULL) {
printf("Out of memory\n\n");
exit(1);
}
FilePtr = FilePtr->NextFile;
}
/* Make a copy of the file name from the find_t structure. */
strcpy(FilePtr->FileName,FileDirectory);
strcat(FilePtr->FileName,FileInfo.name);
} while (_dos_findnext(&FileInfo) == 0);
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -