123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113 |
- #include "rar.hpp"
- #include "cmdfilter.cpp"
- #include "cmdmix.cpp"
- CommandData::CommandData()
- {
- Init();
- }
- void CommandData::Init()
- {
- RAROptions::Init();
- *Command=0;
- *ArcName=0;
- FileLists=false;
- NoMoreSwitches=false;
- ListMode=RCLM_AUTO;
- BareOutput=false;
- FileArgs.Reset();
- ExclArgs.Reset();
- InclArgs.Reset();
- StoreArgs.Reset();
- ArcNames.Reset();
- NextVolSizes.Reset();
- }
- // Return the pointer to next position in the string and store dynamically
- // allocated command line parameter in Par.
- static const wchar *AllocCmdParam(const wchar *CmdLine,wchar **Par)
- {
- const wchar *NextCmd=GetCmdParam(CmdLine,NULL,0);
- if (NextCmd==NULL)
- return NULL;
- size_t ParSize=NextCmd-CmdLine+2; // Parameter size including the trailing zero.
- *Par=(wchar *)malloc(ParSize*sizeof(wchar));
- if (*Par==NULL)
- return NULL;
- return GetCmdParam(CmdLine,*Par,ParSize);
- }
- #if !defined(SFX_MODULE)
- void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[])
- {
- *Command=0;
- NoMoreSwitches=false;
- #ifdef CUSTOM_CMDLINE_PARSER
- // In Windows we may prefer to implement our own command line parser
- // to avoid replacing \" by " in standard parser. Such replacing corrupts
- // destination paths like "dest path\" in extraction commands.
- const wchar *CmdLine=GetCommandLine();
- wchar *Par;
- for (bool FirstParam=true;;FirstParam=false)
- {
- if ((CmdLine=AllocCmdParam(CmdLine,&Par))==NULL)
- break;
- if (!FirstParam) // First parameter is the executable name.
- if (Preprocess)
- PreprocessArg(Par);
- else
- ParseArg(Par);
- free(Par);
- }
- #else
- Array<wchar> Arg;
- for (int I=1;I<argc;I++)
- {
- Arg.Alloc(strlen(argv[I])+1);
- CharToWide(argv[I],&Arg[0],Arg.Size());
- if (Preprocess)
- PreprocessArg(&Arg[0]);
- else
- ParseArg(&Arg[0]);
- }
- #endif
- if (!Preprocess)
- ParseDone();
- }
- #endif
- #if !defined(SFX_MODULE)
- void CommandData::ParseArg(wchar *Arg)
- {
- if (IsSwitch(*Arg) && !NoMoreSwitches)
- if (Arg[1]=='-' && Arg[2]==0)
- NoMoreSwitches=true;
- else
- ProcessSwitch(Arg+1);
- else
- if (*Command==0)
- {
- wcsncpyz(Command,Arg,ASIZE(Command));
- *Command=toupperw(*Command);
- // 'I' and 'S' commands can contain case sensitive strings after
- // the first character, so we must not modify their case.
- // 'S' can contain SFX name, which case is important in Unix.
- if (*Command!='I' && *Command!='S')
- wcsupper(Command);
- if (*Command=='P') // Enforce -idq for print command.
- {
- MsgStream=MSG_ERRONLY;
- SetConsoleMsgStream(MSG_ERRONLY);
- }
- }
- else
- if (*ArcName==0)
- wcsncpyz(ArcName,Arg,ASIZE(ArcName));
- else
- {
- // Check if last character is the path separator.
- size_t Length=wcslen(Arg);
- wchar EndChar=Length==0 ? 0:Arg[Length-1];
- bool EndSeparator=IsDriveDiv(EndChar) || IsPathDiv(EndChar);
- wchar CmdChar=toupperw(*Command);
- bool Add=wcschr(L"AFUM",CmdChar)!=NULL;
- bool Extract=CmdChar=='X' || CmdChar=='E';
- bool Repair=CmdChar=='R' && Command[1]==0;
- if (EndSeparator && !Add)
- wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
- else
- if ((Add || CmdChar=='T') && (*Arg!='@' || ListMode==RCLM_REJECT_LISTS))
- FileArgs.AddString(Arg);
- else
- {
- FindData FileData;
- bool Found=FindFile::FastFind(Arg,&FileData);
- if ((!Found || ListMode==RCLM_ACCEPT_LISTS) &&
- ListMode!=RCLM_REJECT_LISTS && *Arg=='@' && !IsWildcard(Arg+1))
- {
- FileLists=true;
- ReadTextFile(Arg+1,&FileArgs,false,true,FilelistCharset,true,true,true);
- }
- else // We use 'destpath\' when extracting and reparing.
- if (Found && FileData.IsDir && (Extract || Repair) && *ExtrPath==0)
- {
- wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
- AddEndSlash(ExtrPath,ASIZE(ExtrPath));
- }
- else
- FileArgs.AddString(Arg);
- }
- }
- }
- #endif
- void CommandData::ParseDone()
- {
- if (FileArgs.ItemsCount()==0 && !FileLists)
- FileArgs.AddString(MASKALL);
- wchar CmdChar=toupperw(Command[0]);
- bool Extract=CmdChar=='X' || CmdChar=='E' || CmdChar=='P';
- if (Test && Extract)
- Test=false; // Switch '-t' is senseless for 'X', 'E', 'P' commands.
- // Suppress the copyright message and final end of line for 'lb' and 'vb'.
- if ((CmdChar=='L' || CmdChar=='V') && Command[1]=='B')
- BareOutput=true;
- }
- #if !defined(SFX_MODULE)
- void CommandData::ParseEnvVar()
- {
- char *EnvStr=getenv("RAR");
- if (EnvStr!=NULL)
- {
- Array<wchar> EnvStrW(strlen(EnvStr)+1);
- CharToWide(EnvStr,&EnvStrW[0],EnvStrW.Size());
- ProcessSwitchesString(&EnvStrW[0]);
- }
- }
- #endif
- #if !defined(SFX_MODULE)
- // Preprocess those parameters, which must be processed before the rest of
- // command line. Return 'false' to stop further processing.
- void CommandData::PreprocessArg(const wchar *Arg)
- {
- if (IsSwitch(Arg[0]) && !NoMoreSwitches)
- {
- Arg++;
- if (Arg[0]=='-' && Arg[1]==0) // Switch "--".
- NoMoreSwitches=true;
- if (wcsicomp(Arg,L"cfg-")==0)
- ConfigDisabled=true;
- if (wcsnicomp(Arg,L"ilog",4)==0)
- {
- // Ensure that correct log file name is already set
- // if we need to report an error when processing the command line.
- ProcessSwitch(Arg);
- InitLogOptions(LogName,ErrlogCharset);
- }
- if (wcsnicomp(Arg,L"sc",2)==0)
- {
- // Process -sc before reading any file lists.
- ProcessSwitch(Arg);
- if (*LogName!=0)
- InitLogOptions(LogName,ErrlogCharset);
- }
- }
- else
- if (*Command==0)
- wcsncpy(Command,Arg,ASIZE(Command)); // Need for rar.ini.
- }
- #endif
- #if !defined(SFX_MODULE)
- void CommandData::ReadConfig()
- {
- StringList List;
- if (ReadTextFile(DefConfigName,&List,true))
- {
- wchar *Str;
- while ((Str=List.GetString())!=NULL)
- {
- while (IsSpace(*Str))
- Str++;
- if (wcsnicomp(Str,L"switches=",9)==0)
- ProcessSwitchesString(Str+9);
- if (*Command!=0)
- {
- wchar Cmd[16];
- wcsncpyz(Cmd,Command,ASIZE(Cmd));
- wchar C0=toupperw(Cmd[0]);
- wchar C1=toupperw(Cmd[1]);
- if (C0=='I' || C0=='L' || C0=='M' || C0=='S' || C0=='V')
- Cmd[1]=0;
- if (C0=='R' && (C1=='R' || C1=='V'))
- Cmd[2]=0;
- wchar SwName[16+ASIZE(Cmd)];
- swprintf(SwName,ASIZE(SwName),L"switches_%ls=",Cmd);
- size_t Length=wcslen(SwName);
- if (wcsnicomp(Str,SwName,Length)==0)
- ProcessSwitchesString(Str+Length);
- }
- }
- }
- }
- #endif
- #if !defined(SFX_MODULE)
- void CommandData::ProcessSwitchesString(const wchar *Str)
- {
- wchar *Par;
- while ((Str=AllocCmdParam(Str,&Par))!=NULL)
- {
- if (IsSwitch(*Par))
- ProcessSwitch(Par+1);
- free(Par);
- }
- }
- #endif
- #if !defined(SFX_MODULE)
- void CommandData::ProcessSwitch(const wchar *Switch)
- {
- switch(toupperw(Switch[0]))
- {
- case '@':
- ListMode=Switch[1]=='+' ? RCLM_ACCEPT_LISTS:RCLM_REJECT_LISTS;
- break;
- case 'A':
- switch(toupperw(Switch[1]))
- {
- case 'C':
- ClearArc=true;
- break;
- case 'D':
- if (Switch[2]==0)
- AppendArcNameToPath=APPENDARCNAME_DESTPATH;
- else
- if (Switch[2]=='1')
- AppendArcNameToPath=APPENDARCNAME_OWNSUBDIR;
- else
- if (Switch[2]=='2')
- AppendArcNameToPath=APPENDARCNAME_OWNDIR;
- break;
- #ifndef SFX_MODULE
- case 'G':
- if (Switch[2]=='-' && Switch[3]==0)
- GenerateArcName=0;
- else
- if (toupperw(Switch[2])=='F')
- wcsncpyz(DefGenerateMask,Switch+3,ASIZE(DefGenerateMask));
- else
- {
- GenerateArcName=true;
- wcsncpyz(GenerateMask,Switch+2,ASIZE(GenerateMask));
- }
- break;
- #endif
- case 'I':
- IgnoreGeneralAttr=true;
- break;
- case 'N': // Reserved for archive name.
- break;
- case 'O':
- AddArcOnly=true;
- break;
- case 'P':
- wcsncpyz(ArcPath,Switch+2,ASIZE(ArcPath));
- break;
- case 'S':
- SyncFiles=true;
- break;
- default:
- BadSwitch(Switch);
- break;
- }
- break;
- case 'C':
- if (Switch[2]==0)
- switch(toupperw(Switch[1]))
- {
- case '-':
- DisableComment=true;
- break;
- case 'U':
- ConvertNames=NAMES_UPPERCASE;
- break;
- case 'L':
- ConvertNames=NAMES_LOWERCASE;
- break;
- }
- break;
- case 'D':
- if (Switch[2]==0)
- switch(toupperw(Switch[1]))
- {
- case 'S':
- DisableSortSolid=true;
- break;
- case 'H':
- OpenShared=true;
- break;
- case 'F':
- DeleteFiles=true;
- break;
- }
- break;
- case 'E':
- switch(toupperw(Switch[1]))
- {
- case 'P':
- switch(Switch[2])
- {
- case 0:
- ExclPath=EXCL_SKIPWHOLEPATH;
- break;
- case '1':
- ExclPath=EXCL_BASEPATH;
- break;
- case '2':
- ExclPath=EXCL_SAVEFULLPATH;
- break;
- case '3':
- ExclPath=EXCL_ABSPATH;
- break;
- case '4':
- wcsncpyz(ExclArcPath,Switch+3,ASIZE(ExclArcPath));
- break;
- }
- break;
- default:
- if (Switch[1]=='+')
- {
- InclFileAttr|=GetExclAttr(Switch+2,InclDir);
- InclAttrSet=true;
- }
- else
- ExclFileAttr|=GetExclAttr(Switch+1,ExclDir);
- break;
- }
- break;
- case 'F':
- if (Switch[1]==0)
- FreshFiles=true;
- else
- BadSwitch(Switch);
- break;
- case 'H':
- switch (toupperw(Switch[1]))
- {
- case 'P':
- EncryptHeaders=true;
- if (Switch[2]!=0)
- {
- if (wcslen(Switch+2)>=MAXPASSWORD)
- uiMsg(UIERROR_TRUNCPSW,MAXPASSWORD-1);
- Password.Set(Switch+2);
- cleandata((void *)Switch,wcslen(Switch)*sizeof(Switch[0]));
- }
- else
- if (!Password.IsSet())
- {
- uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password);
- eprintf(L"\n");
- }
- break;
- default :
- BadSwitch(Switch);
- break;
- }
- break;
- case 'I':
- if (wcsnicomp(Switch+1,L"LOG",3)==0)
- {
- wcsncpyz(LogName,Switch[4]!=0 ? Switch+4:DefLogName,ASIZE(LogName));
- break;
- }
- if (wcsnicomp(Switch+1,L"SND",3)==0)
- {
- Sound=Switch[4]=='-' ? SOUND_NOTIFY_OFF : SOUND_NOTIFY_ON;
- break;
- }
- if (wcsicomp(Switch+1,L"ERR")==0)
- {
- MsgStream=MSG_STDERR;
- // Set it immediately when parsing the command line, so it also
- // affects messages issued while parsing the command line.
- SetConsoleMsgStream(MSG_STDERR);
- break;
- }
- if (wcsnicomp(Switch+1,L"EML",3)==0)
- {
- wcsncpyz(EmailTo,Switch[4]!=0 ? Switch+4:L"@",ASIZE(EmailTo));
- break;
- }
- if (wcsicomp(Switch+1,L"M")==0) // For compatibility with pre-WinRAR 6.0 -im syntax. Replaced with -idv.
- {
- VerboseOutput=true;
- break;
- }
- if (wcsicomp(Switch+1,L"NUL")==0)
- {
- MsgStream=MSG_NULL;
- SetConsoleMsgStream(MSG_NULL);
- break;
- }
- if (toupperw(Switch[1])=='D')
- {
- for (uint I=2;Switch[I]!=0;I++)
- switch(toupperw(Switch[I]))
- {
- case 'Q':
- MsgStream=MSG_ERRONLY;
- SetConsoleMsgStream(MSG_ERRONLY);
- break;
- case 'C':
- DisableCopyright=true;
- break;
- case 'D':
- DisableDone=true;
- break;
- case 'P':
- DisablePercentage=true;
- break;
- case 'N':
- DisableNames=true;
- break;
- case 'V':
- VerboseOutput=true;
- break;
- }
- break;
- }
- if (wcsnicomp(Switch+1,L"OFF",3)==0)
- {
- switch(Switch[4])
- {
- case 0:
- case '1':
- Shutdown=POWERMODE_OFF;
- break;
- case '2':
- Shutdown=POWERMODE_HIBERNATE;
- break;
- case '3':
- Shutdown=POWERMODE_SLEEP;
- break;
- case '4':
- Shutdown=POWERMODE_RESTART;
- break;
- }
- break;
- }
- if (wcsicomp(Switch+1,L"VER")==0)
- {
- PrintVersion=true;
- break;
- }
- break;
- case 'K':
- switch(toupperw(Switch[1]))
- {
- case 'B':
- KeepBroken=true;
- break;
- case 0:
- Lock=true;
- break;
- }
- break;
- case 'M':
- switch(toupperw(Switch[1]))
- {
- case 'C':
- {
- const wchar *Str=Switch+2;
- if (*Str=='-')
- for (uint I=0;I<ASIZE(FilterModes);I++)
- FilterModes[I].State=FILTER_DISABLE;
- else
- while (*Str!=0)
- {
- int Param1=0,Param2=0;
- FilterState State=FILTER_AUTO;
- FilterType Type=FILTER_NONE;
- if (IsDigit(*Str))
- {
- Param1=atoiw(Str);
- while (IsDigit(*Str))
- Str++;
- }
- if (*Str==':' && IsDigit(Str[1]))
- {
- Param2=atoiw(++Str);
- while (IsDigit(*Str))
- Str++;
- }
- switch(toupperw(*(Str++)))
- {
- case 'T': Type=FILTER_PPM; break;
- case 'E': Type=FILTER_E8; break;
- case 'D': Type=FILTER_DELTA; break;
- case 'A': Type=FILTER_AUDIO; break;
- case 'C': Type=FILTER_RGB; break;
- case 'R': Type=FILTER_ARM; break;
- }
- if (*Str=='+' || *Str=='-')
- State=*(Str++)=='+' ? FILTER_FORCE:FILTER_DISABLE;
- FilterModes[Type].State=State;
- FilterModes[Type].Param1=Param1;
- FilterModes[Type].Param2=Param2;
- }
- }
- break;
- case 'M':
- break;
- case 'D':
- break;
- case 'E':
- if (toupperw(Switch[2])=='S' && Switch[3]==0)
- SkipEncrypted=true;
- break;
- case 'S':
- {
- wchar StoreNames[1024];
- wcsncpyz(StoreNames,(Switch[2]==0 ? DefaultStoreList:Switch+2),ASIZE(StoreNames));
- wchar *Names=StoreNames;
- while (*Names!=0)
- {
- wchar *End=wcschr(Names,';');
- if (End!=NULL)
- *End=0;
- if (*Names=='.')
- Names++;
- wchar Mask[NM];
- if (wcspbrk(Names,L"*?.")==NULL)
- swprintf(Mask,ASIZE(Mask),L"*.%ls",Names);
- else
- wcsncpyz(Mask,Names,ASIZE(Mask));
- StoreArgs.AddString(Mask);
- if (End==NULL)
- break;
- Names=End+1;
- }
- }
- break;
- #ifdef RAR_SMP
- case 'T':
- Threads=atoiw(Switch+2);
- if (Threads>MaxPoolThreads || Threads<1)
- BadSwitch(Switch);
- else
- {
- }
- break;
- #endif
- default:
- Method=Switch[1]-'0';
- if (Method>5 || Method<0)
- BadSwitch(Switch);
- break;
- }
- break;
- case 'N':
- case 'X':
- if (Switch[1]!=0)
- {
- StringList *Args=toupperw(Switch[0])=='N' ? &InclArgs:&ExclArgs;
- if (Switch[1]=='@' && !IsWildcard(Switch))
- ReadTextFile(Switch+2,Args,false,true,FilelistCharset,true,true,true);
- else
- Args->AddString(Switch+1);
- }
- break;
- case 'O':
- switch(toupperw(Switch[1]))
- {
- case '+':
- Overwrite=OVERWRITE_ALL;
- break;
- case '-':
- Overwrite=OVERWRITE_NONE;
- break;
- case 0:
- Overwrite=OVERWRITE_FORCE_ASK;
- break;
- #ifdef _WIN_ALL
- case 'C':
- SetCompressedAttr=true;
- break;
- #endif
- case 'H':
- SaveHardLinks=true;
- break;
- #ifdef SAVE_LINKS
- case 'L':
- SaveSymLinks=true;
- if (toupperw(Switch[2])=='A')
- AbsoluteLinks=true;
- break;
- #endif
- #ifdef _WIN_ALL
- case 'N':
- if (toupperw(Switch[2])=='I')
- AllowIncompatNames=true;
- break;
- #endif
- case 'P':
- wcsncpyz(ExtrPath,Switch+2,ASIZE(ExtrPath));
- AddEndSlash(ExtrPath,ASIZE(ExtrPath));
- break;
- case 'R':
- Overwrite=OVERWRITE_AUTORENAME;
- break;
- #ifdef _WIN_ALL
- case 'S':
- SaveStreams=true;
- break;
- #endif
- case 'W':
- ProcessOwners=true;
- break;
- default :
- BadSwitch(Switch);
- break;
- }
- break;
- case 'P':
- if (Switch[1]==0)
- {
- uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password);
- eprintf(L"\n");
- }
- else
- {
- if (wcslen(Switch+1)>=MAXPASSWORD)
- uiMsg(UIERROR_TRUNCPSW,MAXPASSWORD-1);
- Password.Set(Switch+1);
- cleandata((void *)Switch,wcslen(Switch)*sizeof(Switch[0]));
- }
- break;
- #ifndef SFX_MODULE
- case 'Q':
- if (toupperw(Switch[1])=='O')
- switch(toupperw(Switch[2]))
- {
- case 0:
- QOpenMode=QOPEN_AUTO;
- break;
- case '-':
- QOpenMode=QOPEN_NONE;
- break;
- case '+':
- QOpenMode=QOPEN_ALWAYS;
- break;
- default:
- BadSwitch(Switch);
- break;
- }
- else
- BadSwitch(Switch);
- break;
- #endif
- case 'R':
- switch(toupperw(Switch[1]))
- {
- case 0:
- Recurse=RECURSE_ALWAYS;
- break;
- case '-':
- Recurse=RECURSE_DISABLE;
- break;
- case '0':
- Recurse=RECURSE_WILDCARDS;
- break;
- case 'I':
- {
- Priority=atoiw(Switch+2);
- if (Priority<0 || Priority>15)
- BadSwitch(Switch);
- const wchar *ChPtr=wcschr(Switch+2,':');
- if (ChPtr!=NULL)
- {
- SleepTime=atoiw(ChPtr+1);
- if (SleepTime>1000)
- BadSwitch(Switch);
- InitSystemOptions(SleepTime);
- }
- SetPriority(Priority);
- }
- break;
- }
- break;
- case 'S':
- if (IsDigit(Switch[1]))
- {
- Solid|=SOLID_COUNT;
- SolidCount=atoiw(&Switch[1]);
- }
- else
- switch(toupperw(Switch[1]))
- {
- case 0:
- Solid|=SOLID_NORMAL;
- break;
- case '-':
- Solid=SOLID_NONE;
- break;
- case 'E':
- Solid|=SOLID_FILEEXT;
- break;
- case 'V':
- Solid|=Switch[2]=='-' ? SOLID_VOLUME_DEPENDENT:SOLID_VOLUME_INDEPENDENT;
- break;
- case 'D':
- Solid|=SOLID_VOLUME_DEPENDENT;
- break;
- case 'I':
- ProhibitConsoleInput();
- wcsncpyz(UseStdin,Switch[2] ? Switch+2:L"stdin",ASIZE(UseStdin));
- break;
- case 'L':
- if (IsDigit(Switch[2]))
- FileSizeLess=atoilw(Switch+2);
- break;
- case 'M':
- if (IsDigit(Switch[2]))
- FileSizeMore=atoilw(Switch+2);
- break;
- case 'C':
- {
- bool AlreadyBad=false; // Avoid reporting "bad switch" several times.
- RAR_CHARSET rch=RCH_DEFAULT;
- switch(toupperw(Switch[2]))
- {
- case 'A':
- rch=RCH_ANSI;
- break;
- case 'O':
- rch=RCH_OEM;
- break;
- case 'U':
- rch=RCH_UNICODE;
- break;
- case 'F':
- rch=RCH_UTF8;
- break;
- default :
- BadSwitch(Switch);
- AlreadyBad=true;
- break;
- };
- if (!AlreadyBad)
- if (Switch[3]==0)
- CommentCharset=FilelistCharset=ErrlogCharset=RedirectCharset=rch;
- else
- for (uint I=3;Switch[I]!=0 && !AlreadyBad;I++)
- switch(toupperw(Switch[I]))
- {
- case 'C':
- CommentCharset=rch;
- break;
- case 'L':
- FilelistCharset=rch;
- break;
- case 'R':
- RedirectCharset=rch;
- break;
- default:
- BadSwitch(Switch);
- AlreadyBad=true;
- break;
- }
- // Set it immediately when parsing the command line, so it also
- // affects messages issued while parsing the command line.
- SetConsoleRedirectCharset(RedirectCharset);
- }
- break;
- }
- break;
- case 'T':
- switch(toupperw(Switch[1]))
- {
- case 'K':
- ArcTime=ARCTIME_KEEP;
- break;
- case 'L':
- ArcTime=ARCTIME_LATEST;
- break;
- case 'O':
- SetTimeFilters(Switch+2,true,true);
- break;
- case 'N':
- SetTimeFilters(Switch+2,false,true);
- break;
- case 'B':
- SetTimeFilters(Switch+2,true,false);
- break;
- case 'A':
- SetTimeFilters(Switch+2,false,false);
- break;
- case 'S':
- SetStoreTimeMode(Switch+2);
- break;
- case '-':
- Test=false;
- break;
- case 0:
- Test=true;
- break;
- default:
- BadSwitch(Switch);
- break;
- }
- break;
- case 'U':
- if (Switch[1]==0)
- UpdateFiles=true;
- else
- BadSwitch(Switch);
- break;
- case 'V':
- switch(toupperw(Switch[1]))
- {
- case 'P':
- VolumePause=true;
- break;
- case 'E':
- if (toupperw(Switch[2])=='R')
- VersionControl=atoiw(Switch+3)+1;
- break;
- case '-':
- VolSize=0;
- break;
- default:
- VolSize=VOLSIZE_AUTO; // UnRAR -v switch for list command.
- break;
- }
- break;
- case 'W':
- wcsncpyz(TempPath,Switch+1,ASIZE(TempPath));
- AddEndSlash(TempPath,ASIZE(TempPath));
- break;
- case 'Y':
- AllYes=true;
- break;
- case 'Z':
- if (Switch[1]==0)
- {
- // If comment file is not specified, we read data from stdin.
- wcsncpyz(CommentFile,L"stdin",ASIZE(CommentFile));
- }
- else
- wcsncpyz(CommentFile,Switch+1,ASIZE(CommentFile));
- break;
- case '?' :
- OutHelp(RARX_SUCCESS);
- break;
- default :
- BadSwitch(Switch);
- break;
- }
- }
- #endif
- #if !defined(SFX_MODULE)
- void CommandData::BadSwitch(const wchar *Switch)
- {
- mprintf(St(MUnknownOption),Switch);
- ErrHandler.Exit(RARX_USERERROR);
- }
- #endif
- void CommandData::ProcessCommand()
- {
- #ifndef SFX_MODULE
- const wchar *SingleCharCommands=L"FUADPXETK";
- if (Command[0]!=0 && Command[1]!=0 && wcschr(SingleCharCommands,Command[0])!=NULL || *ArcName==0)
- OutHelp(*Command==0 ? RARX_SUCCESS:RARX_USERERROR); // Return 'success' for 'rar' without parameters.
- const wchar *ArcExt=GetExt(ArcName);
- #ifdef _UNIX
- if (ArcExt==NULL && (!FileExist(ArcName) || IsDir(GetFileAttr(ArcName))))
- wcsncatz(ArcName,L".rar",ASIZE(ArcName));
- #else
- if (ArcExt==NULL)
- wcsncatz(ArcName,L".rar",ASIZE(ArcName));
- #endif
- // Treat arcname.part1 as arcname.part1.rar.
- if (ArcExt!=NULL && wcsnicomp(ArcExt,L".part",5)==0 && IsDigit(ArcExt[5]) &&
- !FileExist(ArcName))
- {
- wchar Name[NM];
- wcsncpyz(Name,ArcName,ASIZE(Name));
- wcsncatz(Name,L".rar",ASIZE(Name));
- if (FileExist(Name))
- wcsncpyz(ArcName,Name,ASIZE(ArcName));
- }
- if (wcschr(L"AFUMD",*Command)==NULL && *UseStdin==0)
- {
- if (GenerateArcName)
- {
- const wchar *Mask=*GenerateMask!=0 ? GenerateMask:DefGenerateMask;
- GenerateArchiveName(ArcName,ASIZE(ArcName),Mask,false);
- }
- StringList ArcMasks;
- ArcMasks.AddString(ArcName);
- ScanTree Scan(&ArcMasks,Recurse,SaveSymLinks,SCAN_SKIPDIRS);
- FindData FindData;
- while (Scan.GetNext(&FindData)==SCAN_SUCCESS)
- AddArcName(FindData.Name);
- }
- else
- AddArcName(ArcName);
- #endif
- switch(Command[0])
- {
- case 'P':
- case 'X':
- case 'E':
- case 'T':
- {
- CmdExtract Extract(this);
- Extract.DoExtract();
- }
- break;
- #ifndef SILENT
- case 'V':
- case 'L':
- ListArchive(this);
- break;
- default:
- OutHelp(RARX_USERERROR);
- #endif
- }
- if (!BareOutput)
- mprintf(L"\n");
- }
- void CommandData::AddArcName(const wchar *Name)
- {
- ArcNames.AddString(Name);
- }
- bool CommandData::GetArcName(wchar *Name,int MaxSize)
- {
- return ArcNames.GetString(Name,MaxSize);
- }
- bool CommandData::IsSwitch(int Ch)
- {
- #if defined(_WIN_ALL) || defined(_EMX)
- return Ch=='-' || Ch=='/';
- #else
- return Ch=='-';
- #endif
- }
- #ifndef SFX_MODULE
- uint CommandData::GetExclAttr(const wchar *Str,bool &Dir)
- {
- if (IsDigit(*Str))
- return wcstol(Str,NULL,0);
- uint Attr=0;
- while (*Str!=0)
- {
- switch(toupperw(*Str))
- {
- case 'D':
- Dir=true;
- break;
- #ifdef _UNIX
- case 'V':
- Attr|=S_IFCHR;
- break;
- #elif defined(_WIN_ALL) || defined(_EMX)
- case 'R':
- Attr|=0x1;
- break;
- case 'H':
- Attr|=0x2;
- break;
- case 'S':
- Attr|=0x4;
- break;
- case 'A':
- Attr|=0x20;
- break;
- #endif
- }
- Str++;
- }
- return Attr;
- }
- #endif
- #ifndef SFX_MODULE
- bool CommandData::CheckWinSize()
- {
- // Define 0x100000000 as macro to avoid troubles with older compilers.
- const uint64 MaxDictSize=INT32TO64(1,0);
- // Limit the dictionary size to 4 GB.
- for (uint64 I=0x10000;I<=MaxDictSize;I*=2)
- if (WinSize==I)
- return true;
- WinSize=0x400000;
- return false;
- }
- #endif
- #ifndef SFX_MODULE
- void CommandData::ReportWrongSwitches(RARFORMAT Format)
- {
- if (Format==RARFMT15)
- {
- if (HashType!=HASH_CRC32)
- uiMsg(UIERROR_INCOMPATSWITCH,L"-ht",4);
- #ifdef _WIN_ALL
- if (SaveSymLinks)
- uiMsg(UIERROR_INCOMPATSWITCH,L"-ol",4);
- #endif
- if (SaveHardLinks)
- uiMsg(UIERROR_INCOMPATSWITCH,L"-oh",4);
- #ifdef _WIN_ALL
- // Do not report a wrong dictionary size here, because we are not sure
- // yet about archive format. We can switch to RAR5 mode later
- // if we update RAR5 archive.
- #endif
- if (QOpenMode!=QOPEN_AUTO)
- uiMsg(UIERROR_INCOMPATSWITCH,L"-qo",4);
- }
- if (Format==RARFMT50)
- {
- }
- }
- #endif
|