/*-------------------------------------------------------------------------*\ List the files in a RAR file rarfile - Name of the RAR file to uncompress list - Output. A list of file data of the files in the archive. The list should be freed with urarlib_freelist(). libpassword - Password (for encrypted archives) \*-------------------------------------------------------------------------*/ int urarlib_list(char *rarfile, ArchiveList_struct **ppList, char *libpassword, bool stopattwo) { if (!ppList) return 0; uint FileCount = 0; InitCRC(); // Set the arguments for the extract command auto_ptr<CommandData> pCmd( new CommandData ); { strcpy(pCmd->Command, "L"); pCmd->AddArcName(rarfile, NULL); pCmd->FileArgs->AddString(MASKALL); pCmd->ParseArg((char*)"-va",NULL); // Set password for encrypted archives if (libpassword) { strncpy(pCmd->Password, libpassword, sizeof(pCmd->Password) - 1); pCmd->Password[sizeof(pCmd->Password) - 1] = '\0'; } // Opent the archive auto_ptr<Archive> pArc( new Archive(pCmd.get()) ); if ( pArc.get() ) { if (!pArc->WOpen(rarfile,NULL)) return 0; FileCount=0; *ppList = NULL; ArchiveList_struct *pPrev = NULL; int iArchive=0; while (1) { if (pArc->IsOpened() && pArc->IsArchive(true)) { int64_t iOffset = pArc->NextBlockPos; while(pArc->ReadHeader()>0) { if (pArc->GetHeaderType() == FILE_HEAD) { if (pPrev) if (strcasecmp(pArc->NewLhd.FileName,pPrev->item.Name)==0) { iOffset = pArc->NextBlockPos; pArc->SeekToNext(); continue; } IntToExt(pArc->NewLhd.FileName,pArc->NewLhd.FileName); ArchiveList_struct *pCurr = (ArchiveList_struct *)malloc(sizeof(ArchiveList_struct)); if (!pCurr) break; if (pPrev) pPrev->next = pCurr; if (!*ppList) *ppList = pCurr; pCurr->item.NameSize = strlen(pArc->NewLhd.FileName); // sanity check - if it fails the archive is likely corrupt if (pCurr->item.NameSize > NM) { File::RemoveCreated(); return 0; } pCurr->item.Name = (char *)malloc(pCurr->item.NameSize + 1); strcpy(pCurr->item.Name, pArc->NewLhd.FileName); pCurr->item.NameW = (wchar *)malloc((pCurr->item.NameSize + 1)*sizeof(wchar)); wcscpy(pCurr->item.NameW, pArc->NewLhd.FileNameW); pCurr->item.PackSize = pArc->NewLhd.PackSize; pCurr->item.UnpSize = int32to64(pArc->NewLhd.HighUnpSize,pArc->NewLhd.UnpSize); pCurr->item.HostOS = pArc->NewLhd.HostOS; pCurr->item.FileCRC = pArc->NewLhd.FileCRC; pCurr->item.FileTime = pArc->NewLhd.FileTime; pCurr->item.UnpVer = pArc->NewLhd.UnpVer; pCurr->item.Method = pArc->NewLhd.Method; pCurr->item.FileAttr = pArc->NewLhd.FileAttr; pCurr->item.iOffset = iOffset; pCurr->next = NULL; pPrev = pCurr; FileCount++; if (stopattwo && FileCount > 1) break; } iOffset = pArc->NextBlockPos; if (iOffset > pArc->FileLength()) { File::RemoveCreated(); return 0; } pArc->SeekToNext(); } if (pCmd->VolSize!=0 && ((pArc->NewLhd.Flags & LHD_SPLIT_AFTER) || (pArc->GetHeaderType()==ENDARC_HEAD && (pArc->EndArcHead.Flags & EARC_NEXT_VOLUME)!=0))) { if (FileCount == 1 && iArchive==0) { char NextName[NM]; char LastName[NM]; strcpy(NextName,pArc->FileName); while (XBMC->FileExists(NextName, true)) { strcpy(LastName,NextName); NextVolumeName(NextName,(pArc->NewMhd.Flags & MHD_NEWNUMBERING)==0 || pArc->OldFormat); } Archive arc; if (arc.WOpen(LastName,NULL)) { bool bBreak=false; while(arc.ReadHeader()>0) { if (arc.GetHeaderType() == FILE_HEAD) if (strcasecmp(arc.NewLhd.FileName,pPrev->item.Name)==0) { bBreak=true; break; } // iOffset = pArc->Tell(); arc.SeekToNext(); } if (bBreak) { break; } } } if (MergeArchive(*pArc,NULL,false,*pCmd->Command)) { iArchive++; pArc->Seek(0,SEEK_SET); } else break; } else break; } else break; } } } File::RemoveCreated(); return FileCount; }