3 #include "guilib/GUIWindowManager.h"
4 #include "dialogs/GUIDialogProgress.h"
5 #include "filesystem/File.h"
12 extern "C" char **__crt0_glob_function (char *arg) { return 0; }
13 extern "C" void __crt0_load_environment_file (char *progname) { }
16 #if !defined(GUI) && !defined(RARDLL) && !defined(TARGET_POSIX) && !defined(_XBMC)
17 int main(int argc, char *argv[])
26 EnumConfigPaths(argv[0],-1);
30 ErrHandler.SetSignalHandlers(true);
37 GetModuleFileName(NULL,ModuleName,sizeof(ModuleName));
39 strcpy(ModuleName,argv[0]);
44 SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
49 #ifdef ALLOW_EXCEPTIONS
56 strcpy(Cmd.Command,"X");
59 char *CmdLine=GetCommandLine();
60 if (CmdLine!=NULL && *CmdLine=='\"')
61 CmdLine=strchr(CmdLine+1,'\"');
62 if (CmdLine!=NULL && (CmdLine=strpbrk(CmdLine," /"))!=NULL)
64 while (isspace(*CmdLine))
69 Switch=argc>1 ? argv[1]:NULL;
71 if (Switch!=NULL && Cmd.IsSwitch(Switch[0]))
73 int UpperCmd=toupper(Switch[1]);
78 Cmd.Command[0]=UpperCmd;
85 Cmd.AddArcName(ModuleName,NULL);
87 if (Cmd.IsConfigEnabled(argc,argv))
89 Cmd.ReadConfig(argc,argv);
92 for (int I=1;I<argc;I++)
93 Cmd.ParseArg(argv[I],NULL);
98 InitConsoleOptions(Cmd.MsgStream,Cmd.Sound);
99 InitSystemOptions(Cmd.SleepTime);
100 InitLogOptions(Cmd.LogName);
101 ErrHandler.SetSilent(Cmd.AllYes || Cmd.MsgStream==MSG_NULL);
102 ErrHandler.SetShutdown(Cmd.Shutdown);
105 Cmd.ProcessCommand();
107 #ifdef ALLOW_EXCEPTIONS
110 ErrHandler.SetErrorCode(ErrCode);
112 #ifdef ENABLE_BAD_ALLOC
115 ErrHandler.SetErrorCode(MEMORY_ERROR);
120 ErrHandler.SetErrorCode(FATAL_ERROR);
123 File::RemoveCreated();
124 #if defined(SFX_MODULE) && defined(_DJGPP)
125 _chmod(ModuleName,1,0x20);
127 return(ErrHandler.GetErrorCode());
132 #if defined(TARGET_POSIX) || defined(_XBMC)
133 /*-------------------------------------------------------------------------*\
135 \*-------------------------------------------------------------------------*/
137 /*-------------------------------------------------------------------------*\
139 rarfile - Name of the RAR file to uncompress
140 targetPath - The path to which we want to uncompress
141 fileToExtract - The file inside the archive we want to uncompress,
142 or NULL for all files.
143 libpassword - Password (for encrypted archives)
144 \*-------------------------------------------------------------------------*/
145 int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libpassword, int64_t* iOffset, bool bShowProgress)
150 // Set the arguments for the extract command
151 auto_ptr<CommandData> pCmd (new CommandData);
155 strcpy(pCmd->Command, "X");
156 pCmd->AddArcName(rarfile,NULL);
157 strncpy(pCmd->ExtrPath, targetPath, sizeof(pCmd->Command) - 2);
158 pCmd->ExtrPath[sizeof(pCmd->Command) - 2] = '\0';
159 AddEndSlash(pCmd->ExtrPath);
160 pCmd->ParseArg((char*)"-va",NULL);
165 pCmd->FileArgs->AddString(fileToExtract);
166 // Uncomment this if you want to extract a single file without the full path
167 strcpy(pCmd->Command, "E");
172 pCmd->FileArgs->AddString(MASKALL);
175 // Set password for encrypted archives
177 if (strlen(libpassword)!=0)
179 strncpy(pCmd->Password, libpassword, sizeof(pCmd->Password) - 1);
180 pCmd->Password[sizeof(pCmd->Password) - 1] = '\0';
184 auto_ptr<Archive> pArc( new Archive(pCmd.get()) );
188 if (!pArc->WOpen(rarfile,NULL))
191 if (pArc->IsOpened() && pArc->IsArchive(true))
193 auto_ptr<CmdExtract> pExtract( new CmdExtract );
197 pExtract->GetDataIO().SetCurrentCommand(*(pCmd->Command));
199 if (FindFile::FastFind(rarfile,NULL,&FD))
200 pExtract->GetDataIO().TotalArcSize+=FD.Size;
201 pExtract->ExtractArchiveInit(pCmd.get(),*pArc);
205 pExtract->GetDataIO().m_pDlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
206 if (pExtract->GetDataIO().m_pDlgProgress)
208 pExtract->GetDataIO().m_pDlgProgress->SetHeading(fileToExtract);
209 pExtract->GetDataIO().m_pDlgProgress->SetCanCancel(false);
210 pExtract->GetDataIO().m_pDlgProgress->StartModal();
215 bool bSeeked = false;
219 int Size=pArc->ReadHeader();
220 int Type=pArc->GetHeaderType();
222 if (Type == ENDARC_HEAD)
225 if (Type != FILE_HEAD)
232 if (!pExtract->ExtractCurrentFile(pCmd.get(),*pArc,Size,Repeat))
238 if (pExtract->GetDataIO().bQuit)
240 if (pExtract->GetDataIO().m_pDlgProgress)
241 pExtract->GetDataIO().m_pDlgProgress->Close();
250 bool EqualNames=false;
251 int MatchNumber=pCmd->IsProcessFile(pArc->NewLhd,&EqualNames);
252 bool ExactMatch=MatchNumber!=0;
261 if (iOffset && !bSeeked && !pArc->Solid)
266 pArc->Seek(*iOffset,SEEK_SET);
271 pExtract->GetDataIO().ProcessedArcSize+=FD.Size;
272 if (pExtract->GetDataIO().m_pDlgProgress)
273 pExtract->GetDataIO().m_pDlgProgress->ShowProgressBar(false);
276 if (pExtract->GetDataIO().m_pDlgProgress)
277 pExtract->GetDataIO().m_pDlgProgress->Close();
282 File::RemoveCreated();
286 /*-------------------------------------------------------------------------*\
287 List the files in a RAR file
288 rarfile - Name of the RAR file to uncompress
289 list - Output. A list of file data of the files in the archive.
290 The list should be freed with urarlib_freelist().
291 libpassword - Password (for encrypted archives)
292 \*-------------------------------------------------------------------------*/
293 int urarlib_list(char *rarfile, ArchiveList_struct **ppList, char *libpassword, bool stopattwo)
300 // Set the arguments for the extract command
301 auto_ptr<CommandData> pCmd( new CommandData );
304 strcpy(pCmd->Command, "L");
305 pCmd->AddArcName(rarfile, NULL);
306 pCmd->FileArgs->AddString(MASKALL);
307 pCmd->ParseArg((char*)"-va",NULL);
309 // Set password for encrypted archives
312 strncpy(pCmd->Password, libpassword, sizeof(pCmd->Password) - 1);
313 pCmd->Password[sizeof(pCmd->Password) - 1] = '\0';
317 auto_ptr<Archive> pArc( new Archive(pCmd.get()) );
320 if (!pArc->WOpen(rarfile,NULL))
325 ArchiveList_struct *pPrev = NULL;
329 if (pArc->IsOpened() && pArc->IsArchive(true))
331 int64_t iOffset = pArc->NextBlockPos;
332 while(pArc->ReadHeader()>0)
334 if (pArc->GetHeaderType() == FILE_HEAD)
337 if (stricmp(pArc->NewLhd.FileName,pPrev->item.Name)==0)
339 iOffset = pArc->NextBlockPos;
344 IntToExt(pArc->NewLhd.FileName,pArc->NewLhd.FileName);
345 ArchiveList_struct *pCurr = (ArchiveList_struct *)malloc(sizeof(ArchiveList_struct));
352 pCurr->item.NameSize = strlen(pArc->NewLhd.FileName);
353 // sanity check - if it fails the archive is likely corrupt
354 if (pCurr->item.NameSize > NM)
356 File::RemoveCreated();
360 pCurr->item.Name = (char *)malloc(pCurr->item.NameSize + 1);
361 strcpy(pCurr->item.Name, pArc->NewLhd.FileName);
362 pCurr->item.NameW = (wchar *)malloc((pCurr->item.NameSize + 1)*sizeof(wchar));
363 wcscpy(pCurr->item.NameW, pArc->NewLhd.FileNameW);
364 pCurr->item.PackSize = pArc->NewLhd.PackSize;
365 pCurr->item.UnpSize = int32to64(pArc->NewLhd.HighUnpSize,pArc->NewLhd.UnpSize);
366 pCurr->item.HostOS = pArc->NewLhd.HostOS;
367 pCurr->item.FileCRC = pArc->NewLhd.FileCRC;
368 pCurr->item.FileTime = pArc->NewLhd.FileTime;
369 pCurr->item.UnpVer = pArc->NewLhd.UnpVer;
370 pCurr->item.Method = pArc->NewLhd.Method;
371 pCurr->item.FileAttr = pArc->NewLhd.FileAttr;
372 pCurr->item.iOffset = iOffset;
376 if (stopattwo && FileCount > 1)
379 iOffset = pArc->NextBlockPos;
380 if (iOffset > pArc->FileLength())
382 File::RemoveCreated();
387 if (pCmd->VolSize!=0 && ((pArc->NewLhd.Flags & LHD_SPLIT_AFTER) || (pArc->GetHeaderType()==ENDARC_HEAD && (pArc->EndArcHead.Flags & EARC_NEXT_VOLUME)!=0)))
389 if (FileCount == 1 && iArchive==0)
393 strcpy(NextName,pArc->FileName);
394 while (XFILE::CFile::Exists(NextName))
396 strcpy(LastName,NextName);
397 NextVolumeName(NextName,(pArc->NewMhd.Flags & MHD_NEWNUMBERING)==0 || pArc->OldFormat);
400 if (arc.WOpen(LastName,NULL))
403 while(arc.ReadHeader()>0)
405 if (arc.GetHeaderType() == FILE_HEAD)
406 if (stricmp(arc.NewLhd.FileName,pPrev->item.Name)==0)
411 // iOffset = pArc->Tell();
420 if (MergeArchive(*pArc,NULL,false,*pCmd->Command))
423 pArc->Seek(0,SEEK_SET);
437 File::RemoveCreated();
441 /*-------------------------------------------------------------------------*\
442 Free the file list returned by urarlib_list()
443 list - The output from urarlib_list()
444 \*-------------------------------------------------------------------------*/
445 void urarlib_freelist(ArchiveList_struct *list)
447 ArchiveList_struct *p;
451 free(list->item.Name);
452 free(list->item.NameW);