bool CommandData::IsConfigEnabled(int argc,char *argv[]) { bool ConfigEnabled=true; for (int I=1;I<argc;I++) if (IsSwitch(*argv[I])) { if (stricomp(&argv[I][1],"-")==0) break; if (stricomp(&argv[I][1],"cfg-")==0) ConfigEnabled=false; #ifndef GUI if (strnicomp(&argv[I][1],"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(&argv[I][1]); InitLogOptions(LogName); } #endif if (strnicomp(&argv[I][1],"sc",2)==0) { // Process -sc before reading any file lists. ProcessSwitch(&argv[I][1]); } } return(ConfigEnabled); }
// Preprocess those parameters, which must be processed before the rest of // command line. Return 'false' to stop further processing. bool CommandData::PreprocessSwitch(const char *Switch) { if (IsSwitch(Switch[0])) { Switch++; if (stricomp(Switch,"-")==0) // Switch "--". return false; if (stricomp(Switch,"cfg-")==0) ConfigDisabled=true; #ifndef GUI if (strnicomp(Switch,"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(Switch); InitLogOptions(LogName); } #endif if (strnicomp(Switch,"sc",2)==0) { // Process -sc before reading any file lists. ProcessSwitch(Switch); } } return true; }
int strnicompc(const char *Str1,const char *Str2,int N) { #if defined(_UNIX) return(strncmp(Str1,Str2,N)); #else return(strnicomp(Str1,Str2,N)); #endif }
int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase) { if (ForceCase) return(strncmp(Str1,Str2,N)); #if defined(_UNIX) return(strncmp(Str1,Str2,N)); #else return(strnicomp(Str1,Str2,N)); #endif }
void CommandData::ReadConfig(int argc,char *argv[]) { StringList List; if (ReadTextFile((char *) DefConfigName,&List,true)) { char *Str; while ((Str=List.GetString())!=NULL) if (strnicomp(Str,"switches=",9)==0) ProcessSwitchesString(Str+9); } }
void CommandData::ReadConfig() { StringList List; if (ReadTextFile(DefConfigName,NULL,&List,true)) { char *Str; while ((Str=List.GetString())!=NULL) { while (IsSpace(*Str)) Str++; if (strnicomp(Str,"switches=",9)==0) ProcessSwitchesString(Str+9); } } }
bool CommandData::IsConfigEnabled(int argc,char *argv[]) { bool ConfigEnabled=true; for (int I=1;I<argc;I++) if (IsSwitch(*argv[I])) { if (stricomp(&argv[I][1],"cfg-")==0) ConfigEnabled=false; if (strnicomp(&argv[I][1],"ilog",4)==0) { ProcessSwitch(&argv[I][1]); InitLogOptions(LogName); } } return(ConfigEnabled); }
void CommandData::ProcessSwitch(char *Switch) { switch(toupper(Switch[0])) { case 'I': if (strnicomp(&Switch[1],"LOG",3)==0) { strncpy(LogName,Switch[4] ? Switch+4:DefLogName,sizeof(LogName)); break; } if (stricomp(&Switch[1],"SND")==0) { Sound=true; break; } if (stricomp(&Switch[1],"ERR")==0) { MsgStream=MSG_STDERR; break; } if (strnicomp(&Switch[1],"EML",3)==0) { strncpy(EmailTo,Switch[4] ? Switch+4:"@",sizeof(EmailTo)); EmailTo[sizeof(EmailTo)-1]=0; break; } if (stricomp(&Switch[1],"NUL")==0) { MsgStream=MSG_NULL; break; } if (toupper(Switch[1])=='D') { for (int I=2;Switch[I]!=0;I++) switch(toupper(Switch[I])) { case 'Q': MsgStream=MSG_ERRONLY; break; case 'C': DisableCopyright=true; break; case 'D': DisableDone=true; break; case 'P': DisablePercentage=true; break; } break; } if (stricomp(&Switch[1],"OFF")==0) { Shutdown=true; break; } break; case 'T': switch(toupper(Switch[1])) { case 'K': ArcTime=ARCTIME_KEEP; break; case 'L': ArcTime=ARCTIME_LATEST; break; case 'O': FileTimeBefore.SetAgeText(Switch+2); break; case 'N': FileTimeAfter.SetAgeText(Switch+2); break; case 'B': FileTimeBefore.SetIsoText(Switch+2); break; case 'A': FileTimeAfter.SetIsoText(Switch+2); break; case 'S': { EXTTIME_MODE Mode=EXTTIME_HIGH3; bool CommonMode=Switch[2]>='0' && Switch[2]<='4'; if (CommonMode) Mode=(EXTTIME_MODE)(Switch[2]-'0'); if (Switch[2]=='-') Mode=EXTTIME_NONE; if (CommonMode || Switch[2]=='-' || Switch[2]=='+' || Switch[2]==0) xmtime=xctime=xatime=Mode; else { if (Switch[3]>='0' && Switch[3]<='4') Mode=(EXTTIME_MODE)(Switch[3]-'0'); if (Switch[3]=='-') Mode=EXTTIME_NONE; switch(toupper(Switch[2])) { case 'M': xmtime=Mode; break; case 'C': xctime=Mode; break; case 'A': xatime=Mode; break; case 'R': xarctime=Mode; break; } } } break; case '-': Test=false; break; case 0: Test=true; break; default: BadSwitch(Switch); break; } break; case 'A': switch(toupper(Switch[1])) { case 'C': ClearArc=true; break; case 'D': AppendArcNameToPath=true; break; case 'G': if (Switch[2]=='-' && Switch[3]==0) GenerateArcName=0; else { GenerateArcName=true; strncpy(GenerateMask,Switch+2,sizeof(GenerateMask)); } break; case 'N': //reserved for archive name break; case 'O': AddArcOnly=true; break; case 'P': strcpy(ArcPath,Switch+2); break; case 'S': SyncFiles=true; break; } break; case 'D': if (Switch[2]==0) switch(toupper(Switch[1])) { case 'S': DisableSortSolid=true; break; case 'H': OpenShared=true; break; case 'F': DeleteFiles=true; break; } break; case 'O': switch(toupper(Switch[1])) { case '+': Overwrite=OVERWRITE_ALL; break; case '-': Overwrite=OVERWRITE_NONE; break; case 'W': ProcessOwners=true; break; #ifdef SAVE_LINKS case 'L': SaveLinks=true; break; #endif #ifdef _WIN_32 case 'S': SaveStreams=true; break; case 'C': SetCompressedAttr=true; break; #endif default : BadSwitch(Switch); break; } break; case 'R': switch(toupper(Switch[1])) { case 0: Recurse=RECURSE_ALWAYS; break; case '-': Recurse=0; break; case '0': Recurse=RECURSE_WILDCARDS; break; case 'I': { Priority=atoi(Switch+2); char *ChPtr=strchr(Switch+2,':'); if (ChPtr!=NULL) { SleepTime=atoi(ChPtr+1); InitSystemOptions(SleepTime); } SetPriority(Priority); } break; } break; case 'Y': AllYes=true; break; case 'N': case 'X': if (Switch[1]!=0) { StringList *Args=toupper(Switch[0])=='N' ? InclArgs:ExclArgs; if (Switch[1]=='@' && !IsWildcard(Switch)) ReadTextFile(Switch+2,Args,false,true,true,true,true); else Args->AddString(Switch+1); } break; case 'E': switch(toupper(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; } break; case 'D': ExclEmptyDir=true; break; case 'E': ProcessEA=false; break; case 'N': NoEndBlock=true; break; default: if (Switch[1]=='+') { InclFileAttr=GetExclAttr(&Switch[2]); InclAttrSet=true; } else ExclFileAttr=GetExclAttr(&Switch[1]); break; } break; case 'P': if (Switch[1]==0) { GetPassword(PASSWORD_GLOBAL,NULL,Password,sizeof(Password)); eprintf("\n"); } else strncpy(Password,Switch+1,sizeof(Password)); break; case 'H': if (toupper(Switch[1])=='P') { EncryptHeaders=true; if (Switch[2]!=0) strncpy(Password,Switch+2,sizeof(Password)); else if (*Password==0) { GetPassword(PASSWORD_GLOBAL,NULL,Password,sizeof(Password)); eprintf("\n"); } } break; case 'Z': strncpy(CommentFile,Switch[1]!=0 ? Switch+1:"stdin",sizeof(CommentFile)); break; case 'M': switch(toupper(Switch[1])) { case 'C': { char *Str=Switch+2; if (*Str=='-') for (int I=0;I<sizeof(FilterModes)/sizeof(FilterModes[0]);I++) FilterModes[I].State=FILTER_DISABLE; else while (*Str) { int Param1=0,Param2=0; FilterState State=FILTER_AUTO; FilterType Type=FILTER_NONE; if (isdigit(*Str)) { Param1=atoi(Str); while (isdigit(*Str)) Str++; } if (*Str==':' && isdigit(Str[1])) { Param2=atoi(++Str); while (isdigit(*Str)) Str++; } switch(toupper(*(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 'I': Type=FILTER_ITANIUM; break; case 'L': Type=FILTER_UPCASETOLOW; 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': { if ((WinSize=atoi(&Switch[2]))==0) WinSize=0x10000<<(toupper(Switch[2])-'A'); else WinSize*=1024; if (!CheckWinSize()) BadSwitch(Switch); } break; case 'S': { char *Names=Switch+2,DefNames[512]; if (*Names==0) { strcpy(DefNames,DefaultStoreList); Names=DefNames; } while (*Names!=0) { char *End=strchr(Names,';'); if (End!=NULL) *End=0; if (*Names=='.') Names++; char Mask[NM]; if (strpbrk(Names,"*?.")==NULL) sprintf(Mask,"*.%s",Names); else strcpy(Mask,Names); StoreArgs->AddString(Mask); if (End==NULL) break; Names=End+1; } } break; default: Method=Switch[1]-'0'; if (Method>5 || Method<0) BadSwitch(Switch); break; } break; case 'V': switch(toupper(Switch[1])) { #ifdef _WIN_32 case 'D': EraseDisk=true; break; #endif case 'N': OldNumbering=true; break; case 'P': VolumePause=true; break; case 'E': if (toupper(Switch[2])=='R') VersionControl=atoi(Switch+3)+1; break; case '-': VolSize=0; break; default: { Int64 NewVolSize=atoil(&Switch[1]); if (NewVolSize==0) NewVolSize=INT64ERR; else switch (Switch[strlen(Switch)-1]) { case 'f': case 'F': switch(int64to32(NewVolSize)) { case 360: NewVolSize=362496; break; case 720: NewVolSize=730112; break; case 1200: NewVolSize=1213952; break; case 1440: NewVolSize=1457664; break; case 2880: NewVolSize=2915328; break; } break; case 'k': NewVolSize*=1024; break; case 'm': NewVolSize*=1024*1024; break; case 'M': NewVolSize*=1000*1000; break; case 'g': NewVolSize*=1024*1024; NewVolSize*=1024; break; case 'G': NewVolSize*=1000*1000; NewVolSize*=1000; break; case 'b': case 'B': break; default: NewVolSize*=1000; break; } if (VolSize==0) VolSize=NewVolSize; else NextVolSizes.Push(NewVolSize); } break; } break; case 'F': if (Switch[1]==0) FreshFiles=true; break; case 'U': if (Switch[1]==0) UpdateFiles=true; break; case 'W': strncpy(TempPath,&Switch[1],sizeof(TempPath)-1); AddEndSlash(TempPath); break; case 'S': if (strnicomp(Switch,"SFX",3)==0) { const char *SFXName=Switch[3] ? Switch+3:DefSFXName; if (PointToName(SFXName)!=SFXName || FileExist(SFXName)) strcpy(SFXModule,SFXName); else GetConfigName(SFXName,SFXModule,true); } if (isdigit(Switch[1])) { Solid|=SOLID_COUNT; SolidCount=atoi(&Switch[1]); } else switch(toupper(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; } break; case 'C': if (Switch[2]==0) switch(toupper(Switch[1])) { case '-': DisableComment=true; break; case 'U': ConvertNames=NAMES_UPPERCASE; break; case 'L': ConvertNames=NAMES_LOWERCASE; break; } break; case 'K': switch(toupper(Switch[1])) { case 'B': KeepBroken=true; break; case 0: Lock=true; break; } break; #ifndef GUI case '?' : OutHelp(); break; #endif default : BadSwitch(Switch); break; } }
void CommandData::ProcessSwitch(char *Switch,wchar *SwitchW) { bool WidePresent=SwitchW!=NULL && *SwitchW!=0; // If 'true', SwitchW is not empty. switch(etoupper(Switch[0])) { case 'I': if (strnicomp(&Switch[1],"LOG",3)==0) { strncpyz(LogName,Switch[4] ? Switch+4:DefLogName,ASIZE(LogName)); break; } if (stricomp(&Switch[1],"SND")==0) { Sound=true; break; } if (stricomp(&Switch[1],"ERR")==0) { MsgStream=MSG_STDERR; break; } if (strnicomp(&Switch[1],"EML",3)==0) { strncpyz(EmailTo,Switch[4] ? Switch+4:"@",ASIZE(EmailTo)); EmailTo[sizeof(EmailTo)-1]=0; break; } if (stricomp(&Switch[1],"NUL")==0) { MsgStream=MSG_NULL; break; } if (etoupper(Switch[1])=='D') { for (int I=2;Switch[I]!=0;I++) switch(etoupper(Switch[I])) { case 'Q': MsgStream=MSG_ERRONLY; break; case 'C': DisableCopyright=true; break; case 'D': DisableDone=true; break; case 'P': DisablePercentage=true; break; } break; } if (stricomp(&Switch[1],"OFF")==0) { Shutdown=true; break; } break; case 'T': switch(etoupper(Switch[1])) { case 'K': ArcTime=ARCTIME_KEEP; break; case 'L': ArcTime=ARCTIME_LATEST; break; case 'O': FileTimeBefore.SetAgeText(Switch+2); break; case 'N': FileTimeAfter.SetAgeText(Switch+2); break; case 'B': FileTimeBefore.SetIsoText(Switch+2); break; case 'A': FileTimeAfter.SetIsoText(Switch+2); break; case 'S': { EXTTIME_MODE Mode=EXTTIME_HIGH3; bool CommonMode=Switch[2]>='0' && Switch[2]<='4'; if (CommonMode) Mode=(EXTTIME_MODE)(Switch[2]-'0'); if (Switch[2]=='-') Mode=EXTTIME_NONE; if (CommonMode || Switch[2]=='-' || Switch[2]=='+' || Switch[2]==0) xmtime=xctime=xatime=Mode; else { if (Switch[3]>='0' && Switch[3]<='4') Mode=(EXTTIME_MODE)(Switch[3]-'0'); if (Switch[3]=='-') Mode=EXTTIME_NONE; switch(etoupper(Switch[2])) { case 'M': xmtime=Mode; break; case 'C': xctime=Mode; break; case 'A': xatime=Mode; break; case 'R': xarctime=Mode; break; } } } break; case '-': Test=false; break; case 0: Test=true; break; default: BadSwitch(Switch); break; } break; case 'A': switch(etoupper(Switch[1])) { case 'C': ClearArc=true; break; case 'D': AppendArcNameToPath=true; break; case 'I': IgnoreGeneralAttr=true; break; case 'N': //reserved for archive name break; case 'O': AddArcOnly=true; break; case 'P': strcpy(ArcPath,Switch+2); if (WidePresent) wcscpy(ArcPathW,SwitchW+2); break; case 'S': SyncFiles=true; break; default: BadSwitch(Switch); break; } break; case 'D': if (Switch[2]==0) switch(etoupper(Switch[1])) { case 'S': DisableSortSolid=true; break; case 'H': OpenShared=true; break; case 'F': DeleteFiles=true; break; } break; case 'O': switch(etoupper(Switch[1])) { case '+': Overwrite=OVERWRITE_ALL; break; case '-': Overwrite=OVERWRITE_NONE; break; case 0: Overwrite=OVERWRITE_FORCE_ASK; break; case 'R': Overwrite=OVERWRITE_AUTORENAME; break; case 'W': ProcessOwners=true; break; #ifdef SAVE_LINKS case 'L': SaveLinks=true; break; #endif #ifdef _WIN_ALL case 'S': SaveStreams=true; break; case 'C': SetCompressedAttr=true; break; #endif default : BadSwitch(Switch); break; } break; case 'R': switch(etoupper(Switch[1])) { case 0: Recurse=RECURSE_ALWAYS; break; case '-': Recurse=RECURSE_DISABLE; break; case '0': Recurse=RECURSE_WILDCARDS; break; #ifndef _WIN_CE case 'I': { Priority=atoi(Switch+2); char *ChPtr=strchr(Switch+2,':'); if (ChPtr!=NULL) { SleepTime=atoi(ChPtr+1); InitSystemOptions(SleepTime); } SetPriority(Priority); } break; #endif } break; case 'Y': AllYes=true; break; case 'N': case 'X': if (Switch[1]!=0) { StringList *Args=etoupper(Switch[0])=='N' ? InclArgs.get():ExclArgs.get(); if (Switch[1]=='@' && !IsWildcard(Switch)) { RAR_CHARSET Charset=FilelistCharset; #if defined(_WIN_ALL) && !defined(GUI) // for compatibility reasons we use OEM encoding // in Win32 console version by default if (Charset==RCH_DEFAULT) Charset=RCH_OEM; #endif ReadTextFile(Switch+2,NULL,Args,false,true,Charset,true,true,true); } else Args->AddString(Switch+1); } break; case 'E': switch(etoupper(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; } break; case 'E': ProcessEA=false; break; case 'N': NoEndBlock=true; break; default: if (Switch[1]=='+') { InclFileAttr=GetExclAttr(&Switch[2]); InclAttrSet=true; } else ExclFileAttr=GetExclAttr(&Switch[1]); break; } break; case 'P': if (Switch[1]==0) { GetPassword(PASSWORD_GLOBAL,NULL,NULL,Password,ASIZE(Password)); eprintf("\n"); } else { CharToWide(Switch+1,Password,ASIZE(Password)); Password[ASIZE(Password)-1]=0; } break; case 'H': if (etoupper(Switch[1])=='P') { EncryptHeaders=true; if (Switch[2]!=0) { CharToWide(Switch+2,Password,ASIZE(Password)); Password[ASIZE(Password)-1]=0; } else if (*Password==0) { GetPassword(PASSWORD_GLOBAL,NULL,NULL,Password,ASIZE(Password)); eprintf("\n"); } } break; case 'Z': if (Switch[1]==0 && (!WidePresent || SwitchW[1]==0)) { // If comment file is not specified, we read data from stdin. strcpy(CommentFile,"stdin"); } strncpyz(CommentFile,Switch+1,ASIZE(CommentFile)); if (WidePresent) wcsncpyz(CommentFileW,SwitchW+1,ASIZE(CommentFileW)); break; case 'M': switch(etoupper(Switch[1])) { case 'C': { char *Str=Switch+2; if (*Str=='-') for (int I=0;I<sizeof(FilterModes)/sizeof(FilterModes[0]);I++) FilterModes[I].State=FILTER_DISABLE; else while (*Str) { int Param1=0,Param2=0; FilterState State=FILTER_AUTO; FilterType Type=FILTER_NONE; if (IsDigit(*Str)) { Param1=atoi(Str); while (IsDigit(*Str)) Str++; } if (*Str==':' && IsDigit(Str[1])) { Param2=atoi(++Str); while (IsDigit(*Str)) Str++; } switch(etoupper(*(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 'I': Type=FILTER_ITANIUM; break; case 'L': Type=FILTER_UPCASETOLOW; 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': { if ((WinSize=atoi(&Switch[2]))==0) WinSize=0x10000<<(etoupper(Switch[2])-'A'); else WinSize*=1024; if (!CheckWinSize()) BadSwitch(Switch); } break; case 'S': { char *Names=Switch+2,DefNames[512]; if (*Names==0) { strcpy(DefNames,DefaultStoreList); Names=DefNames; } while (*Names!=0) { char *End=strchr(Names,';'); if (End!=NULL) *End=0; if (*Names=='.') Names++; char Mask[NM]; if (strpbrk(Names,"*?.")==NULL) sprintf(Mask,"*.%s",Names); else strcpy(Mask,Names); StoreArgs->AddString(Mask); if (End==NULL) break; Names=End+1; } } break; #ifdef PACK_SMP case 'T': Threads=atoi(Switch+2); if (Threads>16) BadSwitch(Switch); else { } break; #endif default: Method=Switch[1]-'0'; if (Method>5 || Method<0) BadSwitch(Switch); break; } break; case 'V': switch(etoupper(Switch[1])) { case 'N': OldNumbering=true; break; case 'P': VolumePause=true; break; case 'E': if (etoupper(Switch[2])=='R') VersionControl=atoi(Switch+3)+1; break; case '-': VolSize=0; break; default: { int64 NewVolSize=atoil(&Switch[1]); if (NewVolSize==0) NewVolSize=INT64NDF; // Autodetecting volume size. else switch (Switch[strlen(Switch)-1]) { case 'f': case 'F': switch(NewVolSize) { case 360: NewVolSize=362496; break; case 720: NewVolSize=730112; break; case 1200: NewVolSize=1213952; break; case 1440: NewVolSize=1457664; break; case 2880: NewVolSize=2915328; break; } break; case 'k': NewVolSize*=1024; break; case 'm': NewVolSize*=1024*1024; break; case 'M': NewVolSize*=1000*1000; break; case 'g': NewVolSize*=1024*1024; NewVolSize*=1024; break; case 'G': NewVolSize*=1000*1000; NewVolSize*=1000; break; case 'b': case 'B': break; default: NewVolSize*=1000; break; } if (VolSize==0) VolSize=NewVolSize; else NextVolSizes.Push(NewVolSize); } break; } break; case 'F': if (Switch[1]==0) FreshFiles=true; else BadSwitch(Switch); break; case 'U': if (Switch[1]==0) UpdateFiles=true; else BadSwitch(Switch); break; case 'W': strncpyz(TempPath,&Switch[1],ASIZE(TempPath)); AddEndSlash(TempPath); break; case 'S': if (IsDigit(Switch[1])) { Solid|=SOLID_COUNT; SolidCount=atoi(&Switch[1]); } else switch(etoupper(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 'L': if (IsDigit(Switch[2])) FileSizeLess=atoil(Switch+2); break; case 'M': if (IsDigit(Switch[2])) FileSizeMore=atoil(Switch+2); break; case 'C': { // Switch is already found bad, avoid reporting it several times. bool AlreadyBad=false; RAR_CHARSET rch=RCH_DEFAULT; switch(etoupper(Switch[2])) { case 'A': rch=RCH_ANSI; break; case 'O': rch=RCH_OEM; break; case 'U': rch=RCH_UNICODE; break; default : BadSwitch(Switch); AlreadyBad=true; break; }; if (!AlreadyBad) if (Switch[3]==0) CommentCharset=FilelistCharset=rch; else for (int I=3;Switch[I]!=0 && !AlreadyBad;I++) switch(etoupper(Switch[I])) { case 'C': CommentCharset=rch; break; case 'L': FilelistCharset=rch; break; default: BadSwitch(Switch); AlreadyBad=true; break; } } break; } break; case 'C': if (Switch[2]==0) switch(etoupper(Switch[1])) { case '-': DisableComment=true; break; case 'U': ConvertNames=NAMES_UPPERCASE; break; case 'L': ConvertNames=NAMES_LOWERCASE; break; } break; case 'K': switch(etoupper(Switch[1])) { case 'B': KeepBroken=true; break; case 0: Lock=true; break; } break; #ifndef GUI case '?' : OutHelp(); break; #endif default : BadSwitch(Switch); break; } }
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,bool &Repeat) { char Command=*Cmd->Command; if (HeaderSize==0) if (DataIO.UnpVolume) { #ifdef NOVOLUME return(false); #else if (!MergeArchive(Arc,&DataIO,false,Command)) { ErrHandler.SetErrorCode(WARNING); return(false); } SignatureFound=false; #endif } else return(false); int HeadType=Arc.GetHeaderType(); if (HeadType!=FILE_HEAD) { if (HeadType==AV_HEAD || HeadType==SIGN_HEAD) SignatureFound=true; #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (HeadType==SUB_HEAD && PrevExtracted) SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL); #endif if (HeadType==NEWSUB_HEAD) { if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV)) SignatureFound=true; #if !defined(NOSUBBLOCKS) && !defined(_WIN_CE) if (PrevExtracted) SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL); #endif } if (HeadType==ENDARC_HEAD) if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME) { #ifndef NOVOLUME if (!MergeArchive(Arc,&DataIO,false,Command)) { ErrHandler.SetErrorCode(WARNING); return(false); } SignatureFound=false; #endif Arc.Seek(Arc.CurBlockPos,SEEK_SET); return(true); } else return(false); Arc.SeekToNext(); return(true); } PrevExtracted=false; if (SignatureFound || !Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() && AllMatchesExact) return(false); char ArcFileName[NM]; IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName); strcpy(ArcFileName,Arc.NewLhd.FileName); wchar ArcFileNameW[NM]; *ArcFileNameW=0; int MatchType=MATCH_WILDSUBPATH; bool EqualNames=false; int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType); bool ExactMatch=MatchNumber!=0; #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (Cmd->ExclPath==EXCL_BASEPATH) { *Cmd->ArcPath=0; if (ExactMatch) { Cmd->FileArgs->Rewind(); if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1)) *PointToName(Cmd->ArcPath)=0; } } #endif if (ExactMatch && !EqualNames) AllMatchesExact=false; #ifdef UNICODE_SUPPORTED bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled(); #else bool WideName=false; #endif #ifdef _APPLE if (WideName) { WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,sizeof(ArcFileName)); WideName=false; } #endif wchar *DestNameW=WideName ? DestFileNameW:NULL; #ifdef UNICODE_SUPPORTED if (WideName) { ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW); char Name[NM]; if (WideToChar(ArcFileNameW,Name) && IsNameUsable(Name)) strcpy(ArcFileName,Name); } #endif ConvertPath(ArcFileName,ArcFileName); if (Arc.IsArcLabel()) return(true); if (Arc.NewLhd.Flags & LHD_VERSION) { if (Cmd->VersionControl!=1 && !EqualNames) { if (Cmd->VersionControl==0) ExactMatch=false; int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false); if (Cmd->VersionControl-1==Version) ParseVersionFileName(ArcFileName,ArcFileNameW,true); else ExactMatch=false; } } else if (!Arc.IsArcDir() && Cmd->VersionControl>1) ExactMatch=false; Arc.ConvertAttributes(); #ifndef SFX_MODULE if ((Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/)) && FirstFile) { char CurVolName[NM]; strcpy(CurVolName,ArcName); VolNameToFirstName(ArcName,ArcName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0); if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName)) { *ArcNameW=0; Repeat=true; return(false); } #if !defined(RARDLL) && !defined(_WIN_CE) if (!ReconstructDone) { ReconstructDone=true; RecVolumes RecVol; if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true)) { Repeat=true; return(false); } } #endif strcpy(ArcName,CurVolName); } #endif DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0; DataIO.NextVolumeMissing=false; Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); bool TestMode=false; bool ExtrFile=false; bool SkipSolid=false; #ifndef SFX_MODULE if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0) { if (ExactMatch) { Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName); #ifdef RARDLL Cmd->DllError=ERAR_BAD_DATA; #endif ErrHandler.SetErrorCode(OPEN_ERROR); } ExactMatch=false; } FirstFile=false; #endif if (ExactMatch || (SkipSolid=Arc.Solid)!=0) { if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0) #ifndef RARDLL if (*Password==0) #endif { #ifdef RARDLL if (*Cmd->Password==0) if (Cmd->Callback==NULL || Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)Cmd->Password,sizeof(Cmd->Password))==-1) return(false); strcpy(Password,Cmd->Password); #else if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password))) { PasswordCancelled=true; return(false); } #endif } #if !defined(GUI) && !defined(SILENT) else if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0)) { eprintf(St(MUseCurPsw),ArcFileName); switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll))) { case -1: ErrHandler.Exit(USER_BREAK); case 2: if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password))) { return(false); } break; case 3: PasswordAll=true; break; } } #endif #ifndef SFX_MODULE if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0) WideToChar(Cmd->ExtrPathW,DestFileName); else #endif strcpy(DestFileName,Cmd->ExtrPath); #ifndef SFX_MODULE if (Cmd->AppendArcNameToPath) { strcat(DestFileName,PointToName(Arc.FirstVolumeName)); SetExt(DestFileName,NULL); AddEndSlash(DestFileName); } #endif char *ExtrName=ArcFileName; bool EmptyName=false; #ifndef SFX_MODULE size_t Length=strlen(Cmd->ArcPath); if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) && strlen(ArcFileName)==Length-1) Length--; if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0) { ExtrName+=Length; while (*ExtrName==CPATHDIVIDER) ExtrName++; if (*ExtrName==0) EmptyName=true; } #endif bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':'); if (AbsPaths) *DestFileName=0; if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) strcat(DestFileName,PointToName(ExtrName)); else strcat(DestFileName,ExtrName); char DiskLetter=etoupper(DestFileName[0]); if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) && DiskLetter>='A' && DiskLetter<='Z') DestFileName[1]=':'; #ifndef SFX_MODULE if (!WideName && *Cmd->ExtrPathW!=0) { DestNameW=DestFileNameW; WideName=true; CharToWide(ArcFileName,ArcFileNameW); } #endif if (WideName) { if (*Cmd->ExtrPathW!=0) strcpyw(DestFileNameW,Cmd->ExtrPathW); else CharToWide(Cmd->ExtrPath,DestFileNameW); #ifndef SFX_MODULE if (Cmd->AppendArcNameToPath) { wchar FileNameW[NM]; if (*Arc.FirstVolumeNameW!=0) strcpyw(FileNameW,Arc.FirstVolumeNameW); else CharToWide(Arc.FirstVolumeName,FileNameW); strcatw(DestFileNameW,PointToName(FileNameW)); SetExt(DestFileNameW,NULL); AddEndSlash(DestFileNameW); } #endif wchar *ExtrNameW=ArcFileNameW; #ifndef SFX_MODULE if (Length>0) { wchar ArcPathW[NM]; GetWideName(Cmd->ArcPath,Cmd->ArcPathW,ArcPathW); Length=strlenw(ArcPathW); } ExtrNameW+=Length; while (*ExtrNameW==CPATHDIVIDER) ExtrNameW++; #endif if (AbsPaths) *DestFileNameW=0; if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) strcatw(DestFileNameW,PointToName(ExtrNameW)); else strcatw(DestFileNameW,ExtrNameW); if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2])) DestFileNameW[1]=':'; } else *DestFileNameW=0; ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0; if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X')) { struct FindData FD; if (FindFile::FastFind(DestFileName,DestNameW,&FD)) { if (FD.mtime >= Arc.NewLhd.mtime) { // If directory already exists and its modification time is newer // than start of extraction, it is likely it was created // when creating a path to one of already extracted items. // In such case we'll better update its time even if archived // directory is older. if (!FD.IsDir || FD.mtime<StartTime) ExtrFile=false; } } else if (Cmd->FreshFiles) ExtrFile=false; } // Skip encrypted file if no password is specified. if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && *Password==0) { ErrHandler.SetErrorCode(WARNING); #ifdef RARDLL Cmd->DllError=ERAR_MISSING_PASSWORD; #endif ExtrFile=false; } #ifdef RARDLL if (*Cmd->DllDestName) { strncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName)); *DestFileNameW=0; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } if (*Cmd->DllDestNameW) { strncpyzw(DestFileNameW,Cmd->DllDestNameW,ASIZE(DestFileNameW)); DestNameW=DestFileNameW; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } #endif #ifdef SFX_MODULE if ((Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.UnpVer!=29) && Arc.NewLhd.Method!=0x30) #else if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER) #endif { #ifndef SILENT Log(Arc.FileName,St(MUnknownMeth),ArcFileName); #ifndef SFX_MODULE Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10); #endif #endif ExtrFile=false; ErrHandler.SetErrorCode(WARNING); #ifdef RARDLL Cmd->DllError=ERAR_UNKNOWN_FORMAT; #endif } File CurFile; if (!IsLink(Arc.NewLhd.FileAttr)) if (Arc.IsArcDir()) { if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) return(true); if (SkipSolid) { #ifndef GUI mprintf(St(MExtrSkipFile),ArcFileName); #endif return(true); } TotalFileCount++; if (Cmd->Test) { #ifndef GUI mprintf(St(MExtrTestFile),ArcFileName); mprintf(" %s",St(MOk)); #endif return(true); } MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr); bool DirExist=false; if (MDCode!=MKDIR_SUCCESS) { DirExist=FileExist(DestFileName,DestNameW); if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW))) { bool UserReject; FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime); DirExist=false; } CreatePath(DestFileName,DestNameW,true); MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr); } if (MDCode==MKDIR_SUCCESS) { #ifndef GUI mprintf(St(MCreatDir),DestFileName); mprintf(" %s",St(MOk)); #endif PrevExtracted=true; } else if (DirExist) { if (!Cmd->IgnoreGeneralAttr) SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr); PrevExtracted=true; } else { Log(Arc.FileName,St(MExtrErrMkDir),DestFileName); ErrHandler.SysErrMsg(); #ifdef RARDLL Cmd->DllError=ERAR_ECREATE; #endif ErrHandler.SetErrorCode(CREATE_ERROR); } if (PrevExtracted) { #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) if (Cmd->SetCompressedAttr && (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) SetFileCompression(DestFileName,DestNameW,true); #endif SetDirTime(DestFileName,DestNameW, Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); } return(true); } else { if (Cmd->Test && ExtrFile) TestMode=true; #if !defined(GUI) && !defined(SFX_MODULE) if (Command=='P' && ExtrFile) CurFile.SetHandleType(FILE_HANDLESTD); #endif if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test) { bool UserReject; if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime)) { ExtrFile=false; if (!UserReject) { ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName); ErrHandler.SetErrorCode(CREATE_ERROR); #ifdef RARDLL Cmd->DllError=ERAR_ECREATE; #endif if (!IsNameUsable(DestFileName)) { Log(Arc.FileName,St(MCorrectingName)); char OrigName[sizeof(DestFileName)]; strncpyz(OrigName,DestFileName,ASIZE(OrigName)); MakeNameUsable(DestFileName,true); CreatePath(DestFileName,NULL,true); if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime)) { #ifndef SFX_MODULE Log(Arc.FileName,St(MRenaming),OrigName,DestFileName); #endif ExtrFile=true; } else ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName); } } } } } if (!ExtrFile && Arc.Solid) { SkipSolid=true; TestMode=true; ExtrFile=true; } if (ExtrFile) { if (!SkipSolid) { if (!TestMode && Command!='P' && CurFile.IsDevice()) { Log(Arc.FileName,St(MInvalidName),DestFileName); ErrHandler.WriteError(Arc.FileName,DestFileName); } TotalFileCount++; } FileCount++; #ifndef GUI if (Command!='I') if (SkipSolid) mprintf(St(MExtrSkipFile),ArcFileName); else switch(Cmd->Test ? 'T':Command) { case 'T': mprintf(St(MExtrTestFile),ArcFileName); break; #ifndef SFX_MODULE case 'P': mprintf(St(MExtrPrinting),ArcFileName); break; #endif case 'X': case 'E': mprintf(St(MExtrFile),DestFileName); break; } if (!Cmd->DisablePercentage) mprintf(" "); #endif DataIO.CurUnpRead=0; DataIO.CurUnpWrite=0; DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff; DataIO.PackedCRC=0xffffffff; DataIO.SetEncryption( (Arc.NewLhd.Flags & LHD_PASSWORD) ? Arc.NewLhd.UnpVer:0,Password, (Arc.NewLhd.Flags & LHD_SALT) ? Arc.NewLhd.Salt:NULL,false, Arc.NewLhd.UnpVer>=36); DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize); DataIO.SetFiles(&Arc,&CurFile); DataIO.SetTestMode(TestMode); DataIO.SetSkipUnpCRC(SkipSolid); #ifndef _WIN_CE if (!TestMode && !Arc.BrokenFileHeader && (Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize && (Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize)) CurFile.Prealloc(Arc.NewLhd.FullUnpSize); #endif CurFile.SetAllowDelete(!Cmd->KeepBroken); bool LinkCreateMode=!Cmd->Test && !SkipSolid; if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode)) PrevExtracted=LinkCreateMode; else if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0) if (Arc.NewLhd.Method==0x30) UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize); else { Unp->SetDestSize(Arc.NewLhd.FullUnpSize); #ifndef SFX_MODULE if (Arc.NewLhd.UnpVer<=15) Unp->DoUnpack(15,FileCount>1 && Arc.Solid); else #endif Unp->DoUnpack(Arc.NewLhd.UnpVer,(Arc.NewLhd.Flags & LHD_SOLID)!=0); } if (Arc.IsOpened()) Arc.SeekToNext(); bool BrokenFile=false; if (!SkipSolid) { if (Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC) || !Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC^0xffffffff)) { #ifndef GUI if (Command!='P' && Command!='I') mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk)); #endif } else { char *BadArcName=/*(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE) ? NULL:*/Arc.FileName; if (Arc.NewLhd.Flags & LHD_PASSWORD) { Log(BadArcName,St(MEncrBadCRC),ArcFileName); } else { Log(BadArcName,St(MCRCFailed),ArcFileName); } BrokenFile=true; ErrHandler.SetErrorCode(CRC_ERROR); #ifdef RARDLL Cmd->DllError=ERAR_BAD_DATA; #endif Alarm(); } } #ifndef GUI else mprintf("\b\b\b\b\b "); #endif if (!TestMode && (Command=='X' || Command=='E') && !IsLink(Arc.NewLhd.FileAttr)) { #if defined(_WIN_32) || defined(_EMX) if (Cmd->ClearArc) Arc.NewLhd.FileAttr&=~FA_ARCH; /* else Arc.NewLhd.FileAttr|=FA_ARCH; //set archive bit for unpacked files (file is not backed up) */ #endif if (!BrokenFile || Cmd->KeepBroken) { if (BrokenFile) CurFile.Truncate(); CurFile.SetOpenFileTime( Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); CurFile.Close(); #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) if (Cmd->SetCompressedAttr && (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) SetFileCompression(CurFile.FileName,CurFile.FileNameW,true); #endif CurFile.SetCloseFileTime( Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); if (!Cmd->IgnoreGeneralAttr) SetFileAttr(CurFile.FileName,CurFile.FileNameW,Arc.NewLhd.FileAttr); PrevExtracted=true; } } } } if (ExactMatch) MatchedArgs++; if (DataIO.NextVolumeMissing || !Arc.IsOpened()) return(false); if (!ExtrFile) if (!Arc.Solid) Arc.SeekToNext(); else if (!SkipSolid) return(false); return(true); }