123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- #include "rar.hpp"
- static void ListFileHeader(Archive &Arc,FileHeader &hd,bool &TitleShown,bool Verbose,bool Technical,bool Bare,bool DisableNames);
- static void ListSymLink(Archive &Arc);
- static void ListFileAttr(uint A,HOST_SYSTEM_TYPE HostType,wchar *AttrStr,size_t AttrSize);
- static void ListOldSubHeader(Archive &Arc);
- static void ListNewSubHeader(CommandData *Cmd,Archive &Arc);
- void ListArchive(CommandData *Cmd)
- {
- int64 SumPackSize=0,SumUnpSize=0;
- uint ArcCount=0,SumFileCount=0;
- bool Technical=(Cmd->Command[1]=='T');
- bool ShowService=Technical && Cmd->Command[2]=='A';
- bool Bare=(Cmd->Command[1]=='B');
- bool Verbose=(Cmd->Command[0]=='V');
- wchar ArcName[NM];
- while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
- {
- if (Cmd->ManualPassword)
- Cmd->Password.Clean(); // Clean user entered password before processing next archive.
- Archive Arc(Cmd);
- if (!Arc.WOpen(ArcName))
- continue;
- bool FileMatched=true;
- while (true)
- {
- int64 TotalPackSize=0,TotalUnpSize=0;
- uint FileCount=0;
- if (Arc.IsArchive(true))
- {
- bool TitleShown=false;
- if (!Bare)
- {
- Arc.ViewComment();
- mprintf(L"\n%s: %s",St(MListArchive),Arc.FileName);
- mprintf(L"\n%s: ",St(MListDetails));
- uint SetCount=0;
- const wchar *Fmt=Arc.Format==RARFMT14 ? L"RAR 1.4":(Arc.Format==RARFMT15 ? L"RAR 4":L"RAR 5");
- mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", Fmt);
- if (Arc.Solid)
- mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListSolid));
- if (Arc.SFXSize>0)
- mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListSFX));
- if (Arc.Volume)
- if (Arc.Format==RARFMT50)
- {
- // RAR 5.0 archives store the volume number in main header,
- // so it is already available now.
- if (SetCount++ > 0)
- mprintf(L", ");
- mprintf(St(MVolumeNumber),Arc.VolNumber+1);
- }
- else
- mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListVolume));
- if (Arc.Protected)
- mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListRR));
- if (Arc.Locked)
- mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListLock));
- if (Arc.Encrypted)
- mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListEncHead));
- mprintf(L"\n");
- }
- wchar VolNumText[50];
- *VolNumText=0;
- while (Arc.ReadHeader()>0)
- {
- Wait(); // Allow quit listing with Ctrl+C.
- HEADER_TYPE HeaderType=Arc.GetHeaderType();
- if (HeaderType==HEAD_ENDARC)
- {
- #ifndef SFX_MODULE
- // Only RAR 1.5 archives store the volume number in end record.
- if (Arc.EndArcHead.StoreVolNumber && Arc.Format==RARFMT15)
- swprintf(VolNumText,ASIZE(VolNumText),L"%.10ls %u",St(MListVolume),Arc.VolNumber+1);
- #endif
- if (Technical && ShowService)
- {
- mprintf(L"\n%12ls: %ls",St(MListService),L"EOF");
- if (*VolNumText!=0)
- mprintf(L"\n%12ls: %ls",St(MListFlags),VolNumText);
- mprintf(L"\n");
- }
- break;
- }
- switch(HeaderType)
- {
- case HEAD_FILE:
- FileMatched=Cmd->IsProcessFile(Arc.FileHead,NULL,MATCH_WILDSUBPATH,0,NULL,0)!=0;
- if (FileMatched)
- {
- ListFileHeader(Arc,Arc.FileHead,TitleShown,Verbose,Technical,Bare,Cmd->DisableNames);
- if (!Arc.FileHead.SplitBefore)
- {
- TotalUnpSize+=Arc.FileHead.UnpSize;
- FileCount++;
- }
- TotalPackSize+=Arc.FileHead.PackSize;
- }
- break;
- case HEAD_SERVICE:
- if (FileMatched && !Bare)
- {
- if (Technical && ShowService)
- ListFileHeader(Arc,Arc.SubHead,TitleShown,Verbose,true,false,Cmd->DisableNames);
- }
- break;
- }
- Arc.SeekToNext();
- }
- if (!Bare && !Technical)
- if (TitleShown)
- {
- wchar UnpSizeText[20];
- itoa(TotalUnpSize,UnpSizeText,ASIZE(UnpSizeText));
-
- wchar PackSizeText[20];
- itoa(TotalPackSize,PackSizeText,ASIZE(PackSizeText));
-
- if (Verbose)
- {
- mprintf(L"\n----------- --------- -------- ----- ---------- ----- -------- ----");
- mprintf(L"\n%21ls %9ls %3d%% %-27ls %u",UnpSizeText,
- PackSizeText,ToPercentUnlim(TotalPackSize,TotalUnpSize),
- VolNumText,FileCount);
- }
- else
- {
- mprintf(L"\n----------- --------- ---------- ----- ----");
- mprintf(L"\n%21ls %-16ls %u",UnpSizeText,VolNumText,FileCount);
- }
- SumFileCount+=FileCount;
- SumUnpSize+=TotalUnpSize;
- SumPackSize+=TotalPackSize;
- mprintf(L"\n");
- }
- else
- mprintf(St(MListNoFiles));
- ArcCount++;
- #ifndef NOVOLUME
- if (Cmd->VolSize!=0 && (Arc.FileHead.SplitAfter ||
- Arc.GetHeaderType()==HEAD_ENDARC && Arc.EndArcHead.NextVolume) &&
- MergeArchive(Arc,NULL,false,Cmd->Command[0]))
- Arc.Seek(0,SEEK_SET);
- else
- #endif
- break;
- }
- else
- {
- if (Cmd->ArcNames.ItemsCount()<2 && !Bare)
- mprintf(St(MNotRAR),Arc.FileName);
- break;
- }
- }
- }
- // Clean user entered password. Not really required, just for extra safety.
- if (Cmd->ManualPassword)
- Cmd->Password.Clean();
- if (ArcCount>1 && !Bare && !Technical)
- {
- wchar UnpSizeText[20],PackSizeText[20];
- itoa(SumUnpSize,UnpSizeText,ASIZE(UnpSizeText));
- itoa(SumPackSize,PackSizeText,ASIZE(PackSizeText));
- if (Verbose)
- mprintf(L"%21ls %9ls %3d%% %28ls %u",UnpSizeText,PackSizeText,
- ToPercentUnlim(SumPackSize,SumUnpSize),L"",SumFileCount);
- else
- mprintf(L"%21ls %18s %lu",UnpSizeText,L"",SumFileCount);
- }
- }
- enum LISTCOL_TYPE {
- LCOL_NAME,LCOL_ATTR,LCOL_SIZE,LCOL_PACKED,LCOL_RATIO,LCOL_CSUM,LCOL_ENCR
- };
- void ListFileHeader(Archive &Arc,FileHeader &hd,bool &TitleShown,bool Verbose,bool Technical,bool Bare,bool DisableNames)
- {
- if (!TitleShown && !Technical && !Bare)
- {
- if (Verbose)
- {
- mprintf(L"\n%ls",St(MListTitleV));
- if (!DisableNames)
- mprintf(L"\n----------- --------- -------- ----- ---------- ----- -------- ----");
- }
- else
- {
- mprintf(L"\n%ls",St(MListTitleL));
- if (!DisableNames)
- mprintf(L"\n----------- --------- ---------- ----- ----");
- }
- // Must be set even in DisableNames mode to suppress "0 files" output
- // unless no files are matched.
- TitleShown=true;
- }
- if (DisableNames)
- return;
- wchar *Name=hd.FileName;
- RARFORMAT Format=Arc.Format;
- if (Bare)
- {
- mprintf(L"%s\n",Name);
- return;
- }
- wchar UnpSizeText[30],PackSizeText[30];
- if (hd.UnpSize==INT64NDF)
- wcsncpyz(UnpSizeText,L"?",ASIZE(UnpSizeText));
- else
- itoa(hd.UnpSize,UnpSizeText,ASIZE(UnpSizeText));
- itoa(hd.PackSize,PackSizeText,ASIZE(PackSizeText));
- wchar AttrStr[30];
- if (hd.HeaderType==HEAD_SERVICE)
- swprintf(AttrStr,ASIZE(AttrStr),L"%cB",hd.Inherited ? 'I' : '.');
- else
- ListFileAttr(hd.FileAttr,hd.HSType,AttrStr,ASIZE(AttrStr));
- wchar RatioStr[10];
- if (hd.SplitBefore && hd.SplitAfter)
- wcsncpyz(RatioStr,L"<->",ASIZE(RatioStr));
- else
- if (hd.SplitBefore)
- wcsncpyz(RatioStr,L"<--",ASIZE(RatioStr));
- else
- if (hd.SplitAfter)
- wcsncpyz(RatioStr,L"-->",ASIZE(RatioStr));
- else
- swprintf(RatioStr,ASIZE(RatioStr),L"%d%%",ToPercentUnlim(hd.PackSize,hd.UnpSize));
- wchar DateStr[50];
- hd.mtime.GetText(DateStr,ASIZE(DateStr),Technical);
- if (Technical)
- {
- mprintf(L"\n%12s: %s",St(MListName),Name);
- bool FileBlock=hd.HeaderType==HEAD_FILE;
- if (!FileBlock && Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM))
- {
- mprintf(L"\n%12ls: %ls",St(MListType),St(MListStream));
- wchar StreamName[NM];
- GetStreamNameNTFS(Arc,StreamName,ASIZE(StreamName));
- mprintf(L"\n%12ls: %ls",St(MListTarget),StreamName);
- }
- else
- {
- const wchar *Type=St(FileBlock ? (hd.Dir ? MListDir:MListFile):MListService);
-
- if (hd.RedirType!=FSREDIR_NONE)
- switch(hd.RedirType)
- {
- case FSREDIR_UNIXSYMLINK:
- Type=St(MListUSymlink); break;
- case FSREDIR_WINSYMLINK:
- Type=St(MListWSymlink); break;
- case FSREDIR_JUNCTION:
- Type=St(MListJunction); break;
- case FSREDIR_HARDLINK:
- Type=St(MListHardlink); break;
- case FSREDIR_FILECOPY:
- Type=St(MListCopy); break;
- }
- mprintf(L"\n%12ls: %ls",St(MListType),Type);
- if (hd.RedirType!=FSREDIR_NONE)
- if (Format==RARFMT15)
- {
- char LinkTargetA[NM];
- if (Arc.FileHead.Encrypted)
- {
- // Link data are encrypted. We would need to ask for password
- // and initialize decryption routine to display the link target.
- strncpyz(LinkTargetA,"*<-?->",ASIZE(LinkTargetA));
- }
- else
- {
- int DataSize=(int)Min(hd.PackSize,ASIZE(LinkTargetA)-1);
- Arc.Read(LinkTargetA,DataSize);
- LinkTargetA[DataSize > 0 ? DataSize : 0] = 0;
- }
- wchar LinkTarget[NM];
- CharToWide(LinkTargetA,LinkTarget,ASIZE(LinkTarget));
- mprintf(L"\n%12ls: %ls",St(MListTarget),LinkTarget);
- }
- else
- mprintf(L"\n%12ls: %ls",St(MListTarget),hd.RedirName);
- }
- if (!hd.Dir)
- {
- mprintf(L"\n%12ls: %ls",St(MListSize),UnpSizeText);
- mprintf(L"\n%12ls: %ls",St(MListPacked),PackSizeText);
- mprintf(L"\n%12ls: %ls",St(MListRatio),RatioStr);
- }
- bool WinTitles=false;
- #ifdef _WIN_ALL
- WinTitles=true;
- #endif
- if (hd.mtime.IsSet())
- mprintf(L"\n%12ls: %ls",St(WinTitles ? MListModified:MListMtime),DateStr);
- if (hd.ctime.IsSet())
- {
- hd.ctime.GetText(DateStr,ASIZE(DateStr),true);
- mprintf(L"\n%12ls: %ls",St(WinTitles ? MListCreated:MListCtime),DateStr);
- }
- if (hd.atime.IsSet())
- {
- hd.atime.GetText(DateStr,ASIZE(DateStr),true);
- mprintf(L"\n%12ls: %ls",St(WinTitles ? MListAccessed:MListAtime),DateStr);
- }
- mprintf(L"\n%12ls: %ls",St(MListAttr),AttrStr);
- if (hd.FileHash.Type==HASH_CRC32)
- mprintf(L"\n%12ls: %8.8X",
- hd.UseHashKey ? L"CRC32 MAC":hd.SplitAfter ? L"Pack-CRC32":L"CRC32",
- hd.FileHash.CRC32);
- if (hd.FileHash.Type==HASH_BLAKE2)
- {
- wchar BlakeStr[BLAKE2_DIGEST_SIZE*2+1];
- BinToHex(hd.FileHash.Digest,BLAKE2_DIGEST_SIZE,NULL,BlakeStr,ASIZE(BlakeStr));
- mprintf(L"\n%12ls: %ls",
- hd.UseHashKey ? L"BLAKE2 MAC":hd.SplitAfter ? L"Pack-BLAKE2":L"BLAKE2",
- BlakeStr);
- }
- const wchar *HostOS=L"";
- if (Format==RARFMT50 && hd.HSType!=HSYS_UNKNOWN)
- HostOS=hd.HSType==HSYS_WINDOWS ? L"Windows":L"Unix";
- if (Format==RARFMT15)
- {
- static const wchar *RarOS[]={
- L"DOS",L"OS/2",L"Windows",L"Unix",L"Mac OS",L"BeOS",L"WinCE",L"",L"",L""
- };
- if (hd.HostOS<ASIZE(RarOS))
- HostOS=RarOS[hd.HostOS];
- }
- if (*HostOS!=0)
- mprintf(L"\n%12ls: %ls",St(MListHostOS),HostOS);
- mprintf(L"\n%12ls: RAR %ls(v%d) -m%d -md=%d%s",St(MListCompInfo),
- Format==RARFMT15 ? L"1.5":L"5.0",
- hd.UnpVer==VER_UNKNOWN ? 0 : hd.UnpVer,hd.Method,
- hd.WinSize>=0x100000 ? hd.WinSize/0x100000:hd.WinSize/0x400,
- hd.WinSize>=0x100000 ? L"M":L"K");
- if (hd.Solid || hd.Encrypted)
- {
- mprintf(L"\n%12ls: ",St(MListFlags));
- if (hd.Solid)
- mprintf(L"%ls ",St(MListSolid));
- if (hd.Encrypted)
- mprintf(L"%ls ",St(MListEnc));
- }
- if (hd.Version)
- {
- uint Version=ParseVersionFileName(Name,false);
- if (Version!=0)
- mprintf(L"\n%12ls: %u",St(MListFileVer),Version);
- }
- if (hd.UnixOwnerSet)
- {
- mprintf(L"\n%12ls: ",L"Unix owner");
- if (*hd.UnixOwnerName!=0)
- mprintf(L"%ls",GetWide(hd.UnixOwnerName));
- else
- if (hd.UnixOwnerNumeric)
- mprintf(L"#%d",hd.UnixOwnerID);
- mprintf(L":");
- if (*hd.UnixGroupName!=0)
- mprintf(L"%ls",GetWide(hd.UnixGroupName));
- else
- if (hd.UnixGroupNumeric)
- mprintf(L"#%d",hd.UnixGroupID);
- }
- mprintf(L"\n");
- return;
- }
- mprintf(L"\n%c%10ls %9ls ",hd.Encrypted ? '*' : ' ',AttrStr,UnpSizeText);
- if (Verbose)
- mprintf(L"%9ls %4ls ",PackSizeText,RatioStr);
- mprintf(L" %ls ",DateStr);
- if (Verbose)
- {
- if (hd.FileHash.Type==HASH_CRC32)
- mprintf(L"%8.8X ",hd.FileHash.CRC32);
- else
- if (hd.FileHash.Type==HASH_BLAKE2)
- {
- byte *S=hd.FileHash.Digest;
- mprintf(L"%02x%02x..%02x ",S[0],S[1],S[31]);
- }
- else
- mprintf(L"???????? ");
- }
- mprintf(L"%ls",Name);
- }
- /*
- void ListSymLink(Archive &Arc)
- {
- if (Arc.FileHead.HSType==HSYS_UNIX && (Arc.FileHead.FileAttr & 0xF000)==0xA000)
- if (Arc.FileHead.Encrypted)
- {
- // Link data are encrypted. We would need to ask for password
- // and initialize decryption routine to display the link target.
- mprintf(L"\n%22ls %ls",L"-->",L"*<-?->");
- }
- else
- {
- char FileName[NM];
- uint DataSize=(uint)Min(Arc.FileHead.PackSize,sizeof(FileName)-1);
- Arc.Read(FileName,DataSize);
- FileName[DataSize]=0;
- mprintf(L"\n%22ls %ls",L"-->",GetWide(FileName));
- }
- }
- */
- void ListFileAttr(uint A,HOST_SYSTEM_TYPE HostType,wchar *AttrStr,size_t AttrSize)
- {
- switch(HostType)
- {
- case HSYS_WINDOWS:
- swprintf(AttrStr,AttrSize,L"%c%c%c%c%c%c%c",
- (A & 0x2000)!=0 ? 'I' : '.', // Not content indexed.
- (A & 0x0800)!=0 ? 'C' : '.', // Compressed.
- (A & 0x0020)!=0 ? 'A' : '.', // Archive.
- (A & 0x0010)!=0 ? 'D' : '.', // Directory.
- (A & 0x0004)!=0 ? 'S' : '.', // System.
- (A & 0x0002)!=0 ? 'H' : '.', // Hidden.
- (A & 0x0001)!=0 ? 'R' : '.'); // Read-only.
- break;
- case HSYS_UNIX:
- switch (A & 0xF000)
- {
- case 0x4000:
- AttrStr[0]='d';
- break;
- case 0xA000:
- AttrStr[0]='l';
- break;
- default:
- AttrStr[0]='-';
- break;
- }
- swprintf(AttrStr+1,AttrSize-1,L"%c%c%c%c%c%c%c%c%c",
- (A & 0x0100) ? 'r' : '-',
- (A & 0x0080) ? 'w' : '-',
- (A & 0x0040) ? ((A & 0x0800)!=0 ? 's':'x'):((A & 0x0800)!=0 ? 'S':'-'),
- (A & 0x0020) ? 'r' : '-',
- (A & 0x0010) ? 'w' : '-',
- (A & 0x0008) ? ((A & 0x0400)!=0 ? 's':'x'):((A & 0x0400)!=0 ? 'S':'-'),
- (A & 0x0004) ? 'r' : '-',
- (A & 0x0002) ? 'w' : '-',
- (A & 0x0001) ? ((A & 0x200)!=0 ? 't' : 'x') : '-');
- break;
- case HSYS_UNKNOWN:
- wcsncpyz(AttrStr,L"?",AttrSize);
- break;
- }
- }
|