QuietUnrar/libunrar/list.cpp

397 lines
11 KiB
C++

#include "rar.hpp"
static void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare);
static void ListSymLink(Archive &Arc);
static void ListFileAttr(uint A,int HostOS);
static void ListOldSubHeader(Archive &Arc);
static void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical);
void ListArchive(CommandData *Cmd)
{
int64 SumPackSize=0,SumUnpSize=0;
uint ArcCount=0,SumFileCount=0;
bool Technical=(Cmd->Command[1]=='T');
bool Bare=(Cmd->Command[1]=='B');
bool Verbose=(*Cmd->Command=='V');
char ArcName[NM];
wchar ArcNameW[NM];
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
{
Archive Arc(Cmd);
#ifdef _WIN_32
Arc.RemoveSequentialFlag();
#endif
if (!Arc.WOpen(ArcName,ArcNameW))
continue;
bool FileMatched=true;
while (1)
{
int64 TotalPackSize=0,TotalUnpSize=0;
uint FileCount=0;
if (Arc.IsArchive(true))
{
if (!Arc.IsOpened())
break;
bool TitleShown=false;
if (!Bare)
{
Arc.ViewComment();
// RAR can close a corrupt encrypted archive
if (!Arc.IsOpened())
break;
mprintf("\n");
if (Arc.Solid)
mprintf(St(MListSolid));
if (Arc.SFXSize>0)
mprintf(St(MListSFX));
if (Arc.Volume)
if (Arc.Solid)
mprintf(St(MListVol1));
else
mprintf(St(MListVol2));
else
if (Arc.Solid)
mprintf(St(MListArc1));
else
mprintf(St(MListArc2));
mprintf(" %s\n",Arc.FileName);
if (Technical)
{
if (Arc.Protected)
mprintf(St(MListRecRec));
if (Arc.Locked)
mprintf(St(MListLock));
}
}
while(Arc.ReadHeader()>0)
{
int HeaderType=Arc.GetHeaderType();
if (HeaderType==ENDARC_HEAD)
break;
switch(HeaderType)
{
case FILE_HEAD:
IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
FileMatched=Cmd->IsProcessFile(Arc.NewLhd)!=0;
if (FileMatched)
{
ListFileHeader(Arc.NewLhd,Verbose,Technical,TitleShown,Bare);
if (!(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
{
TotalUnpSize+=Arc.NewLhd.FullUnpSize;
FileCount++;
}
TotalPackSize+=Arc.NewLhd.FullPackSize;
if (Technical)
ListSymLink(Arc);
#ifndef SFX_MODULE
if (Verbose)
Arc.ViewFileComment();
#endif
}
break;
#ifndef SFX_MODULE
case SUB_HEAD:
if (Technical && FileMatched && !Bare)
ListOldSubHeader(Arc);
break;
#endif
case NEWSUB_HEAD:
if (FileMatched && !Bare)
{
if (Technical)
ListFileHeader(Arc.SubHead,Verbose,true,TitleShown,false);
ListNewSubHeader(Cmd,Arc,Technical);
}
break;
}
Arc.SeekToNext();
}
if (!Bare)
if (TitleShown)
{
mprintf("\n");
for (int I=0;I<79;I++)
mprintf("-");
char UnpSizeText[20];
itoa(TotalUnpSize,UnpSizeText);
char PackSizeText[20];
itoa(TotalPackSize,PackSizeText);
mprintf("\n%5lu %16s %8s %3d%%",FileCount,UnpSizeText,
PackSizeText,ToPercentUnlim(TotalPackSize,TotalUnpSize));
SumFileCount+=FileCount;
SumUnpSize+=TotalUnpSize;
SumPackSize+=TotalPackSize;
#ifndef SFX_MODULE
if (Arc.EndArcHead.Flags & EARC_VOLNUMBER)
{
mprintf(" ");
mprintf(St(MVolumeNumber),Arc.EndArcHead.VolNumber+1);
}
#endif
mprintf("\n");
}
else
mprintf(St(MListNoFiles));
ArcCount++;
#ifndef NOVOLUME
if (Cmd->VolSize!=0 && ((Arc.NewLhd.Flags & LHD_SPLIT_AFTER) ||
Arc.GetHeaderType()==ENDARC_HEAD &&
(Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)!=0) &&
MergeArchive(Arc,NULL,false,*Cmd->Command))
{
Arc.Seek(0,SEEK_SET);
}
else
#endif
break;
}
else
{
if (Cmd->ArcNames->ItemsCount()<2 && !Bare)
mprintf(St(MNotRAR),Arc.FileName);
break;
}
}
}
if (ArcCount>1 && !Bare)
{
char UnpSizeText[20],PackSizeText[20];
itoa(SumUnpSize,UnpSizeText);
itoa(SumPackSize,PackSizeText);
mprintf("\n%5lu %16s %8s %3d%%\n",SumFileCount,UnpSizeText,
PackSizeText,ToPercentUnlim(SumPackSize,SumUnpSize));
}
}
void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare)
{
if (!Bare)
{
if (!TitleShown)
{
if (Verbose)
mprintf(St(MListPathComm));
else
mprintf(St(MListName));
mprintf(St(MListTitle));
if (Technical)
mprintf(St(MListTechTitle));
for (int I=0;I<79;I++)
mprintf("-");
TitleShown=true;
}
if (hd.HeadType==NEWSUB_HEAD)
mprintf(St(MSubHeadType),hd.FileName);
mprintf("\n%c",(hd.Flags & LHD_PASSWORD) ? '*' : ' ');
}
char *Name=hd.FileName;
#ifdef UNICODE_SUPPORTED
char ConvertedName[NM];
if ((hd.Flags & LHD_UNICODE)!=0 && *hd.FileNameW!=0 && UnicodeEnabled())
{
if (WideToChar(hd.FileNameW,ConvertedName) && *ConvertedName!=0)
Name=ConvertedName;
}
#endif
if (Bare)
{
mprintf("%s\n",Verbose ? Name:PointToName(Name));
return;
}
if (Verbose)
mprintf("%s\n%12s ",Name,"");
else
mprintf("%-12s",PointToName(Name));
char UnpSizeText[20],PackSizeText[20];
if (hd.FullUnpSize==INT64NDF)
strcpy(UnpSizeText,"?");
else
itoa(hd.FullUnpSize,UnpSizeText);
itoa(hd.FullPackSize,PackSizeText);
mprintf(" %8s %8s ",UnpSizeText,PackSizeText);
if ((hd.Flags & LHD_SPLIT_BEFORE) && (hd.Flags & LHD_SPLIT_AFTER))
mprintf(" <->");
else
if (hd.Flags & LHD_SPLIT_BEFORE)
mprintf(" <--");
else
if (hd.Flags & LHD_SPLIT_AFTER)
mprintf(" -->");
else
mprintf("%3d%%",ToPercentUnlim(hd.FullPackSize,hd.FullUnpSize));
char DateStr[50];
hd.mtime.GetText(DateStr,false);
mprintf(" %s ",DateStr);
if (hd.HeadType==NEWSUB_HEAD)
mprintf(" %c....B ",(hd.SubFlags & SUBHEAD_FLAGS_INHERITED) ? 'I' : '.');
else
ListFileAttr(hd.FileAttr,hd.HostOS);
mprintf(" %8.8X",hd.FileCRC);
mprintf(" m%d",hd.Method-0x30);
if ((hd.Flags & LHD_WINDOWMASK)<=6*32)
mprintf("%c",((hd.Flags&LHD_WINDOWMASK)>>5)+'a');
else
mprintf(" ");
mprintf(" %d.%d",hd.UnpVer/10,hd.UnpVer%10);
static const char *RarOS[]={
"DOS","OS/2","Win95/NT","Unix","MacOS","BeOS","WinCE","","",""
};
if (Technical)
mprintf("\n%22s %8s %4s",
(hd.HostOS<sizeof(RarOS)/sizeof(RarOS[0]) ? RarOS[hd.HostOS]:""),
(hd.Flags & LHD_SOLID) ? St(MYes):St(MNo),
(hd.Flags & LHD_VERSION) ? St(MYes):St(MNo));
}
void ListSymLink(Archive &Arc)
{
if (Arc.NewLhd.HostOS==HOST_UNIX && (Arc.NewLhd.FileAttr & 0xF000)==0xA000)
if ((Arc.NewLhd.Flags & LHD_PASSWORD)==0)
{
char FileName[NM];
int DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
Arc.Read(FileName,DataSize);
FileName[DataSize]=0;
mprintf("\n%22s %s","-->",FileName);
}
else
{
// Link data are encrypted. We would need to ask for password
// and initialize decryption routine to display the link target.
mprintf("\n%22s %s","-->","*<-?->");
}
}
void ListFileAttr(uint A,int HostOS)
{
switch(HostOS)
{
case HOST_MSDOS:
case HOST_OS2:
case HOST_WIN32:
case HOST_MACOS:
mprintf(" %c%c%c%c%c%c%c ",
(A & 0x08) ? 'V' : '.',
(A & 0x10) ? 'D' : '.',
(A & 0x01) ? 'R' : '.',
(A & 0x02) ? 'H' : '.',
(A & 0x04) ? 'S' : '.',
(A & 0x20) ? 'A' : '.',
(A & 0x800) ? 'C' : '.');
break;
case HOST_UNIX:
case HOST_BEOS:
switch (A & 0xF000)
{
case 0x4000:
mprintf("d");
break;
case 0xA000:
mprintf("l");
break;
default:
mprintf("-");
break;
}
mprintf("%c%c%c%c%c%c%c%c%c",
(A & 0x0100) ? 'r' : '-',
(A & 0x0080) ? 'w' : '-',
(A & 0x0040) ? ((A & 0x0800) ? 's':'x'):((A & 0x0800) ? 'S':'-'),
(A & 0x0020) ? 'r' : '-',
(A & 0x0010) ? 'w' : '-',
(A & 0x0008) ? ((A & 0x0400) ? 's':'x'):((A & 0x0400) ? 'S':'-'),
(A & 0x0004) ? 'r' : '-',
(A & 0x0002) ? 'w' : '-',
(A & 0x0001) ? 'x' : '-');
break;
}
}
#ifndef SFX_MODULE
void ListOldSubHeader(Archive &Arc)
{
switch(Arc.SubBlockHead.SubType)
{
case EA_HEAD:
mprintf(St(MListEAHead));
break;
case UO_HEAD:
mprintf(St(MListUOHead),Arc.UOHead.OwnerName,Arc.UOHead.GroupName);
break;
case MAC_HEAD:
mprintf(St(MListMACHead1),Arc.MACHead.fileType>>24,Arc.MACHead.fileType>>16,Arc.MACHead.fileType>>8,Arc.MACHead.fileType);
mprintf(St(MListMACHead2),Arc.MACHead.fileCreator>>24,Arc.MACHead.fileCreator>>16,Arc.MACHead.fileCreator>>8,Arc.MACHead.fileCreator);
break;
case BEEA_HEAD:
mprintf(St(MListBeEAHead));
break;
case NTACL_HEAD:
mprintf(St(MListNTACLHead));
break;
case STREAM_HEAD:
mprintf(St(MListStrmHead),Arc.StreamHead.StreamName);
break;
default:
mprintf(St(MListUnkHead),Arc.SubBlockHead.SubType);
break;
}
}
#endif
void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical)
{
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_CMT) &&
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0 && !Cmd->DisableComment)
{
Array<byte> CmtData;
size_t ReadSize=Arc.ReadCommentData(&CmtData,NULL);
if (ReadSize!=0)
{
mprintf(St(MFileComment));
OutComment((char *)&CmtData[0],ReadSize);
}
}
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM) &&
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0)
{
size_t DestSize=Arc.SubHead.SubData.Size()/2;
wchar DestNameW[NM];
char DestName[NM];
if (DestSize<sizeof(DestName))
{
RawToWide(&Arc.SubHead.SubData[0],DestNameW,DestSize);
DestNameW[DestSize]=0;
WideToChar(DestNameW,DestName);
mprintf("\n %s",DestName);
}
}
}