HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r) { // try // { r->OpenResult=0; DataSet *Data=new DataSet; Data->Cmd.DllError=0; Data->OpenMode=r->OpenMode; Data->Cmd.FileArgs->AddString("*"); char an[NM]; if (r->ArcName==NULL && r->ArcNameW!=NULL) { WideToChar(r->ArcNameW,an,NM); r->ArcName=an; } Data->Cmd.AddArcName(r->ArcName,r->ArcNameW); Data->Cmd.Overwrite=OVERWRITE_ALL; Data->Cmd.VersionControl=1; if (!Data->Arc.Open(r->ArcName,r->ArcNameW)) { r->OpenResult=ERAR_EOPEN; delete Data; return(NULL); } if (!Data->Arc.IsArchive(false)) { r->OpenResult=Data->Cmd.DllError!=0 ? Data->Cmd.DllError:ERAR_BAD_ARCHIVE; delete Data; return(NULL); } r->Flags=Data->Arc.NewMhd.Flags; Array<byte> CmtData; if (r->CmtBufSize!=0 && Data->Arc.GetComment(&CmtData,NULL)) { r->Flags|=2; size_t Size=CmtData.Size()+1; r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1; r->CmtSize=(uint)Min(Size,r->CmtBufSize); memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1); if (Size<=r->CmtBufSize) r->CmtBuf[r->CmtSize-1]=0; } else r->CmtState=r->CmtSize=0; if (Data->Arc.Signed) r->Flags|=0x20; Data->Extract.ExtractArchiveInit(&Data->Cmd,Data->Arc); return((HANDLE)Data); // } // catch (int ErrCode) // { // r->OpenResult=RarErrorToDll(ErrCode); // return(NULL); // } }
bool WideToChar(const wchar *Src,char *Dest,size_t DestSize) { bool RetCode=true; *Dest=0; // Set 'Dest' to zero just in case the conversion will fail. #ifdef _WIN_ALL if (WideCharToMultiByte(CP_ACP,0,Src,-1,Dest,(int)DestSize,NULL,NULL)==0) RetCode=false; #elif defined(_APPLE) WideToUtf(Src,Dest,DestSize); #elif defined(MBFUNCTIONS) size_t ResultingSize=wcstombs(Dest,Src,DestSize); if (ResultingSize==(size_t)-1) RetCode=false; if (ResultingSize==0 && *Src!=0) RetCode=false; if ((!RetCode || *Dest==0 && *Src!=0) && DestSize>NM && wcslen(Src)<NM) { /* Workaround for strange Linux Unicode functions bug. Some of wcstombs and mbstowcs implementations in some situations (we are yet to find out what it depends on) can return an empty string and success code if buffer size value is too large. */ return(WideToChar(Src,Dest,NM)); } #else if (UnicodeEnabled()) { #if defined(_EMX) && !defined(_DJGPP) int len=Min(wcslen(Src)+1,DestSize-1); if (uni_fromucs((UniChar*)Src,len,Dest,(size_t*)&DestSize)==-1 || DestSize>len*2) RetCode=false; Dest[DestSize]=0; #endif } else for (int I=0;I<DestSize;I++) { Dest[I]=(char)Src[I]; if (Src[I]==0) break; } #endif // We tried to return the zero terminated string if conversion is failed, // but it does not work well. WideCharToMultiByte returns 'failed' code // even if we wanted to convert only a part of string and passed DestSize // smaller than required for fully converted string. Such call is the valid // behavior in RAR code and we do not expect the empty string in this case. return(RetCode); }
void FindFile::SetMaskW(const wchar *FindMaskW) { if (FindMaskW==NULL) return; strcpyw(FindFile::FindMaskW,FindMaskW); if (*FindMask==0) WideToChar(FindMaskW,FindMask); FirstCall=TRUE; }
void CHomonym::Print(TOutputStream& stream, const Stroka& strKwType, ECharset encoding) const { Stroka s; if (strKwType.size()) s = Substitute(" (<b>$0</b>) ", strKwType); stream << " " << WideToChar(GetShortLemma(), encoding) << " "; PrintFormGrammems(stream, encoding); stream << s << GetLabelsString(encoding) << Endl; }
bool RenameFile(const wchar *SrcName,const wchar *DestName) { #ifdef _WIN_ALL bool Success=MoveFile(SrcName,DestName)!=0; if (!Success) { wchar LongName1[NM],LongName2[NM]; if (GetWinLongPath(SrcName,LongName1,ASIZE(LongName1)) && GetWinLongPath(DestName,LongName2,ASIZE(LongName2))) Success=MoveFile(LongName1,LongName2)!=0; } return Success; #else char SrcNameA[NM],DestNameA[NM]; WideToChar(SrcName,SrcNameA,ASIZE(SrcNameA)); WideToChar(DestName,DestNameA,ASIZE(DestNameA)); return rename(SrcNameA,DestNameA)==0; #endif }
void ErrorHandler::SysErrMsg() { #if !defined(SFX_MODULE) && !defined(SILENT) #ifdef _WIN_ALL wchar *lpMsgBuf=NULL; int ErrType=GetLastError(); if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf,0,NULL)) { wchar *CurMsg=lpMsgBuf; while (CurMsg!=NULL) { while (*CurMsg=='\r' || *CurMsg=='\n') CurMsg++; if (*CurMsg==0) break; wchar *EndMsg=wcschr(CurMsg,'\r'); if (EndMsg==NULL) EndMsg=wcschr(CurMsg,'\n'); if (EndMsg!=NULL) { *EndMsg=0; EndMsg++; } // We use ASCII for output in Windows console, so let's convert Unicode // message to single byte. size_t Length=wcslen(CurMsg)*2; // Must be enough for DBCS characters. char *MsgA=(char *)malloc(Length+2); if (MsgA!=NULL) { WideToChar(CurMsg,MsgA,Length+1); MsgA[Length]=0; Log(NULL,"\n%s",MsgA); free(MsgA); } CurMsg=EndMsg; } } LocalFree( lpMsgBuf ); #endif #if defined(_UNIX) || defined(_EMX) if (errno!=0) { char *err=strerror(errno); if (err!=NULL) Log(NULL,"\n%s",err); } #endif #endif }
void ExtractStreamsNew(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; wchar NameW[NM]; if (FileNameW!=NULL && *FileNameW!=0) strcpyw(NameW,FileNameW); else CharToWide(FileName,NameW); wchar StreamNameW[NM+2]; if (NameW[0]!=0 && NameW[1]==0) { strcpyw(StreamNameW,L".\\"); strcpyw(StreamNameW+2,NameW); } else strcpyw(StreamNameW,NameW); wchar *DestName=StreamNameW+strlenw(StreamNameW); byte *SrcName=&Arc.SubHead.SubData[0]; int DestSize=Arc.SubHead.SubData.Size()/2; if (strlenw(StreamNameW)+DestSize>=sizeof(StreamNameW)/sizeof(StreamNameW[0])) { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName,St(MStreamBroken),FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } RawToWide(SrcName,DestName,DestSize); DestName[DestSize]=0; FindData fd; bool Found=FindFile::FastFind(FileName,FileNameW,&fd); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY); char StreamName[NM]; WideToChar(StreamNameW,StreamName); File CurFile; if (CurFile.WCreate(StreamName,StreamNameW) && Arc.ReadSubData(NULL,&CurFile)) CurFile.Close(); File HostFile; if (Found && HostFile.Open(FileName,FileNameW,true,true)) SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime, &fd.ftLastWriteTime); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr); }
void CHomonym::Print(TOutputStream& stream, ECharset encoding) const { Stroka s; s = GetStrKWType(encoding); if (s.size()) s = Substitute(" (<b>$0</b>) ", s); if (IsDeleted()) s += "[deleted]"; stream << WideToChar(GetShortLemma(), encoding) << " "; PrintGrammems(Grammems.All(), stream, encoding); stream << s << GetLabelsString(encoding); }
bool FileExist(const wchar *Name) { #ifdef _WIN_ALL return GetFileAttr(Name)!=0xffffffff; #elif defined(ENABLE_ACCESS) char NameA[NM]; WideToChar(Name,NameA,ASIZE(NameA)); return access(NameA,0)==0; #else FindData FD; return FindFile::FastFind(Name,&FD); #endif }
bool WideToChar(const wchar *Src,char *Dest,size_t DestSize) { bool RetCode=true; #ifdef _WIN_32 if (WideCharToMultiByte(CP_ACP,0,Src,-1,Dest,(int)DestSize,NULL,NULL)==0) RetCode=false; #else #ifdef _APPLE WideToUtf(Src,Dest,DestSize); #else #ifdef MBFUNCTIONS size_t ResultingSize=wcstombs(Dest,Src,DestSize); if (ResultingSize==(size_t)-1) RetCode=false; if (ResultingSize==0 && *Src!=0) RetCode=false; if ((!RetCode || *Dest==0 && *Src!=0) && DestSize>NM && strlenw(Src)<NM) { /* Workaround for strange Linux Unicode functions bug. Some of wcstombs and mbstowcs implementations in some situations (we are yet to find out what it depends on) can return an empty string and success code if buffer size value is too large. */ return(WideToChar(Src,Dest,NM)); } #else if (UnicodeEnabled()) { #if defined(_EMX) && !defined(_DJGPP) int len=Min(strlenw(Src)+1,DestSize-1); if (uni_fromucs((UniChar*)Src,len,Dest,(size_t*)&DestSize)==-1 || DestSize>len*2) RetCode=false; Dest[DestSize]=0; #endif } else for (int I=0;I<DestSize;I++) { Dest[I]=(char)Src[I]; if (Src[I]==0) break; } #endif #endif #endif return(RetCode); }
void ConvertNameToFull(const wchar *Src,wchar *Dest) { if (Src==NULL || *Src==0) { *Dest=0; return; } #ifdef _WIN_32 #ifndef _WIN_CE if (WinNT()) #endif { //#ifndef _WIN_CE #if !defined(_WIN_CE) && !defined(_LINUX) wchar FullName[NM],*NamePtr; if (GetFullPathNameW(Src,sizeof(FullName)/sizeof(FullName[0]),FullName,&NamePtr)) strcpyw(Dest,FullName); else #endif if (Src!=Dest) strcpyw(Dest,Src); } #ifndef _WIN_CE else { char AnsiName[NM]; WideToChar(Src,AnsiName); ConvertNameToFull(AnsiName,AnsiName); CharToWide(AnsiName,Dest); } #endif #else char AnsiName[NM]; WideToChar(Src,AnsiName); ConvertNameToFull(AnsiName,AnsiName); CharToWide(AnsiName,Dest); #endif }
void IntToExt(const char *Src,char *Dest,size_t DestSize) { #ifdef _WIN_ALL OemToCharBuffA(Src,Dest,(DWORD)DestSize); Dest[DestSize-1]=0; #elif defined(_ANDROID) wchar DestW[NM]; JniCharToWide(Src,DestW,ASIZE(DestW),true); WideToChar(DestW,Dest,DestSize); #else if (Dest!=Src) strncpyz(Dest,Src,DestSize); #endif }
bool ExtractUnixLink50(const wchar *Name,FileHeader *hd) { char Target[NM]; WideToChar(hd->RedirName,Target,ASIZE(Target)); if (hd->RedirType==FSREDIR_WINSYMLINK || hd->RedirType==FSREDIR_JUNCTION) { // Cannot create Windows absolute path symlinks in Unix. Only relative path // Windows symlinks can be created here. if (strncmp(Target,"\\??\\",4)==0) return false; DosSlashToUnix(Target,Target,ASIZE(Target)); } return UnixSymlink(Target,Name); }
Stroka CHomonym::GetLabelsString(ECharset encoding) const { Stroka s; if (m_Labels.size() == 0) return s; else s = " labels = ("; yset<Wtroka>::const_iterator it = m_Labels.begin(); for (; it != m_Labels.end(); ++it) s += WideToChar(*it, encoding); s += ")"; return s; }
void PrepareToDelete(const wchar *Name) { #if defined(_WIN_ALL) || defined(_EMX) SetFileAttr(Name,0); #endif #ifdef _UNIX if (Name!=NULL) { char NameA[NM]; WideToChar(Name,NameA,ASIZE(NameA)); chmod(NameA,S_IRUSR|S_IWUSR|S_IXUSR); } #endif }
void SetUnixOwner(Archive &Arc,const wchar *FileName) { char NameA[NM]; WideToChar(FileName,NameA,ASIZE(NameA)); // First, we try to resolve symbolic names. If they are missing or cannot // be resolved, we try to use numeric values if any. If numeric values // are missing too, function fails. FileHeader &hd=Arc.FileHead; if (*hd.UnixOwnerName!=0) { struct passwd *pw; if ((pw=getpwnam(hd.UnixOwnerName))==NULL) { if (!hd.UnixOwnerNumeric) { uiMsg(UIERROR_UOWNERGETOWNERID,Arc.FileName,GetWide(hd.UnixOwnerName)); ErrHandler.SetErrorCode(RARX_WARNING); return; } } else hd.UnixOwnerID=pw->pw_uid; } if (*hd.UnixGroupName!=0) { struct group *gr; if ((gr=getgrnam(hd.UnixGroupName))==NULL) { if (!hd.UnixGroupNumeric) { uiMsg(UIERROR_UOWNERGETGROUPID,Arc.FileName,GetWide(hd.UnixGroupName)); ErrHandler.SetErrorCode(RARX_WARNING); return; } } else hd.UnixGroupID=gr->gr_gid; } #if defined(SAVE_LINKS) && !defined(_APPLE) if (lchown(NameA,hd.UnixOwnerID,hd.UnixGroupID)!=0) #else if (chown(NameA,hd.UnixOwnerID,hd.UnixGroupID)!=0) #endif { uiMsg(UIERROR_UOWNERSET,Arc.FileName,FileName); ErrHandler.SetErrorCode(RARX_CREATE); } }
bool RenameFile(const wchar *SrcName,const wchar *DestName) { #ifdef _WIN_ALL bool Success=MoveFile(SrcName,DestName)!=0; if (!Success) { wchar LongName1[NM],LongName2[NM]; if (GetWinLongPath(SrcName,LongName1,ASIZE(LongName1)) && GetWinLongPath(DestName,LongName2,ASIZE(LongName2))) Success=MoveFile(LongName1,LongName2)!=0; } return Success; #else char SrcNameA[NM],DestNameA[NM]; WideToChar(SrcName,SrcNameA,ASIZE(SrcNameA)); WideToChar(DestName,DestNameA,ASIZE(DestNameA)); bool Success=rename(SrcNameA,DestNameA)==0; #ifdef _ANDROID if (!Success) Success=JniRename(SrcName,DestName); // If external card is read-only for usual file API. #endif return Success; #endif }
TGramBitSet HumanGrammemsToGramBitSet(const TWtringBuf& strGrammems) { Stroka str = WideToChar(~strGrammems, +strGrammems, CODES_WIN); VectorStrok gramTokens = splitStrokuBySet(str.c_str(), ","); TGramBitSet grammars; for (size_t j = 0; j < gramTokens.size(); j++) { if (gramTokens[j].empty()) continue; TGrammar gr = TGrammarIndex::GetCode(gramTokens[j]); if (gr != gInvalid) grammars.Set(gr); } return grammars; }
bool FindFile::FastFind(const wchar *FindMask,FindData *fd,bool GetSymLink) { fd->Error=false; #ifndef _UNIX if (IsWildcard(FindMask)) return false; #endif #ifdef _WIN_ALL HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,fd); if (hFind==INVALID_HANDLE_VALUE) return false; FindClose(hFind); #else char FindMaskA[NM]; WideToChar(FindMask,FindMaskA,ASIZE(FindMaskA)); struct stat st; if (GetSymLink) { #ifdef SAVE_LINKS if (lstat(FindMaskA,&st)!=0) #else if (stat(FindMaskA,&st)!=0) #endif { fd->Error=(errno!=ENOENT); return false; } } else if (stat(FindMaskA,&st)!=0) { fd->Error=(errno!=ENOENT); return false; } fd->FileAttr=st.st_mode; fd->Size=st.st_size; fd->mtime=st.st_mtime; fd->atime=st.st_atime; fd->ctime=st.st_ctime; wcsncpyz(fd->Name,FindMask,ASIZE(fd->Name)); #endif fd->Flags=0; fd->IsDir=IsDir(fd->FileAttr); fd->IsLink=IsLink(fd->FileAttr); return true; }
bool File::Create(const char *Name,const wchar *NameW) { // Below commented code was left behind on spiffs request for possible later usage /*#ifdef _WIN_32 #ifndef _XBOX if (WinNT() && NameW!=NULL && *NameW!=0) hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL, CREATE_ALWAYS,0,NULL); else #endif hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL, CREATE_ALWAYS,0,NULL); #else hFile=fopen(Name,CREATEBINARY); #endif*/ char name[NM]; if (NameW) WideToUtf(NameW, name, NM); else strcpy(name, Name); char* lastslash = strrchr(name, '\\'); char tmp; if (!lastslash) lastslash = strrchr(name, '/'); if (lastslash) { tmp = *lastslash; *lastslash = '\0'; } XBMC->CreateDirectory(name); *lastslash = tmp; m_File = XBMC->OpenFileForWrite(name, true); NewFile=true; HandleType=FILE_HANDLENORMAL; SkipClose=false; if (NameW!=NULL) strcpyw(FileNameW,NameW); else *FileNameW=0; if (Name!=NULL) strcpy(FileName,Name); else WideToChar(NameW,FileName); //AddFileToList(hFile); AddFileToList(); //return(hFile!=BAD_HANDLE); return true; }
void ExtractUnixOwner20(Archive &Arc,const wchar *FileName) { char NameA[NM]; WideToChar(FileName,NameA,ASIZE(NameA)); if (Arc.BrokenHeader) { Log(Arc.FileName,St(MOwnersBroken),FileName); ErrHandler.SetErrorCode(RARX_CRC); return; } struct passwd *pw; errno=0; // Required by getpwnam specification if we need to check errno. if ((pw=getpwnam(Arc.UOHead.OwnerName))==NULL) { Log(Arc.FileName,St(MErrGetOwnerID),GetWide(Arc.UOHead.OwnerName)); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(RARX_WARNING); return; } uid_t OwnerID=pw->pw_uid; struct group *gr; errno=0; // Required by getgrnam specification if we need to check errno. if ((gr=getgrnam(Arc.UOHead.GroupName))==NULL) { Log(Arc.FileName,St(MErrGetGroupID),GetWide(Arc.UOHead.GroupName)); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(RARX_CRC); return; } gid_t GroupID=gr->gr_gid; #if defined(SAVE_LINKS) && !defined(_APPLE) if (lchown(NameA,OwnerID,GroupID)!=0) #else if (chown(NameA,OwnerID,GroupID)!=0) #endif { Log(Arc.FileName,St(MSetOwnersError),FileName); ErrHandler.SetErrorCode(RARX_CREATE); } #ifndef NOFILECREATE uint Attr=GetFileAttr(FileName); SetFileAttr(FileName,Attr); #endif }
HANDLE PASCAL RAROpenArchiveEx(vector<string> *pvRarFiles, string sParfileName, struct RAROpenArchiveDataEx *r) { try { r->OpenResult=0; DataSet *Data=new DataSet(pvRarFiles, sParfileName); Data->OpenMode=r->OpenMode; Data->Cmd.FileArgs->AddString("*"); char an[NM]; if (r->ArcName==NULL && r->ArcNameW!=NULL) { WideToChar(r->ArcNameW,an,NM); r->ArcName=an; } Data->Cmd.AddArcName(r->ArcName,r->ArcNameW); Data->Cmd.Overwrite=OVERWRITE_ALL; Data->Cmd.VersionControl=1; if (!Data->Arc.Open(r->ArcName,r->ArcNameW)) { delete Data; r->OpenResult=ERAR_EOPEN; return(NULL); } if (!Data->Arc.IsArchive(false)) { delete Data; r->OpenResult=ERAR_BAD_ARCHIVE; return(NULL); } r->Flags=Data->Arc.NewMhd.Flags; Array<byte> CmtData(sParfileName); //gmilow - ignore comments r->CmtState=r->CmtSize=0; if (Data->Arc.Signed) r->Flags|=0x20; Data->Extract.ExtractArchiveInit(&Data->Cmd,Data->Arc); return((HANDLE)Data); } catch (int ErrCode) { r->OpenResult=RarErrorToDll(ErrCode); return(NULL); } }
bool DelFile(const wchar *Name) { #ifdef _WIN_ALL bool Success=DeleteFile(Name)!=0; if (!Success) { wchar LongName[NM]; if (GetWinLongPath(Name,LongName,ASIZE(LongName))) Success=DeleteFile(LongName)!=0; } return Success; #else char NameA[NM]; WideToChar(Name,NameA,ASIZE(NameA)); return remove(NameA)==0; #endif }
bool File::Create(const wchar *Name,uint Mode) { // OpenIndiana based NAS and CIFS shares fail to set the file time if file // was created in read+write mode and some data was written and not flushed // before SetFileTime call. So we should use the write only mode if we plan // SetFileTime call and do not need to read from file. bool WriteMode=(Mode & FMF_WRITE)!=0; char NameA[NM]; WideToChar(Name,NameA,ASIZE(NameA)); // hFile=fopen(NameA,WriteMode ? WRITEBINARY:CREATEBINARY); hFile=jsCreate(Name); NewFile=true; HandleType=FILE_HANDLENORMAL; SkipClose=false; wcsncpyz(FileName,Name,ASIZE(FileName)); return hFile!=FILE_BAD_HANDLE; }
bool CreatePath(const wchar *Path,bool SkipLastName) { if (Path==NULL || *Path==0) return(false); #if defined(_WIN_ALL) || defined(_EMX) uint DirAttr=0; #else uint DirAttr=0777; #endif bool Success=true; for (const wchar *s=Path;*s!=0;s++) { if (s-Path>=NM) break; if (*s==CPATHDIVIDER) { wchar DirName[NM]; wcsncpy(DirName,Path,s-Path); DirName[s-Path]=0; if (MakeDir(NULL,DirName,true,DirAttr)==MKDIR_SUCCESS) { #ifndef GUI char DirNameA[NM]; WideToChar(DirName,DirNameA,ASIZE(DirNameA)); DirNameA[ASIZE(DirNameA)-1]=0; mprintf(St(MCreatDir),DirNameA); mprintf(" %s",St(MOk)); #endif } else Success=false; } } if (!SkipLastName) if (!IsPathDiv(*PointToLastChar(Path))) if (MakeDir(NULL,Path,true,DirAttr)!=MKDIR_SUCCESS) Success=false; return(Success); }
bool SetFileAttr(const wchar *Name,uint Attr) { #ifdef _WIN_ALL bool Success=SetFileAttributes(Name,Attr)!=0; if (!Success) { wchar LongName[NM]; if (GetWinLongPath(Name,LongName,ASIZE(LongName))) Success=SetFileAttributes(LongName,Attr)!=0; } return Success; #elif defined(_UNIX) char NameA[NM]; WideToChar(Name,NameA,ASIZE(NameA)); return chmod(NameA,(mode_t)Attr)==0; #else return false; #endif }
int Archive::ReadCommentData(Array<byte> &CmtData) { bool Unicode=SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE; if (!ReadSubData(&CmtData,NULL)) return(0); int CmtSize=CmtData.Size(); if (Unicode) { CmtSize/=2; Array<wchar> CmtDataW(CmtSize+1); RawToWide(&CmtData[0],&CmtDataW[0],CmtSize); CmtDataW[CmtSize]=0; CmtData.Alloc(CmtSize*2); WideToChar(&CmtDataW[0],(char *)&CmtData[0]); CmtSize=strlen((char *)&CmtData[0]); CmtData.Alloc(CmtSize); } return(CmtSize); }
void ExtractUnixOwner30(Archive &Arc,const wchar *FileName) { char NameA[NM]; WideToChar(FileName,NameA,ASIZE(NameA)); char *OwnerName=(char *)&Arc.SubHead.SubData[0]; int OwnerSize=strlen(OwnerName)+1; int GroupSize=Arc.SubHead.SubData.Size()-OwnerSize; char GroupName[NM]; strncpy(GroupName,(char *)&Arc.SubHead.SubData[OwnerSize],GroupSize); GroupName[GroupSize]=0; struct passwd *pw; if ((pw=getpwnam(OwnerName))==NULL) { Log(Arc.FileName,St(MErrGetOwnerID),GetWide(OwnerName)); ErrHandler.SetErrorCode(RARX_WARNING); return; } uid_t OwnerID=pw->pw_uid; struct group *gr; if ((gr=getgrnam(GroupName))==NULL) { Log(Arc.FileName,St(MErrGetGroupID),GetWide(GroupName)); ErrHandler.SetErrorCode(RARX_WARNING); return; } gid_t GroupID=gr->gr_gid; #if defined(SAVE_LINKS) && !defined(_APPLE) if (lchown(NameA,OwnerID,GroupID)!=0) #else if (chown(NameA,OwnerID,GroupID)!=0) #endif { Log(Arc.FileName,St(MSetOwnersError),FileName); ErrHandler.SetErrorCode(RARX_CREATE); } #ifndef NOFILECREATE uint Attr=GetFileAttr(FileName); SetFileAttr(FileName,Attr); #endif }
MKDIR_CODE MakeDir(const wchar *Name,bool SetAttr,uint Attr) { #ifdef _WIN_ALL // Windows automatically removes dots and spaces in the end of directory // name. So we detect such names and process them with \\?\ prefix. wchar *LastChar=PointToLastChar(Name); bool Special=*LastChar=='.' || *LastChar==' '; BOOL RetCode=Special ? FALSE : CreateDirectory(Name,NULL); if (RetCode==0 && !FileExist(Name)) { wchar LongName[NM]; if (GetWinLongPath(Name,LongName,ASIZE(LongName))) RetCode=CreateDirectory(LongName,NULL); } if (RetCode!=0) // Non-zero return code means success for CreateDirectory. { if (SetAttr) SetFileAttr(Name,Attr); return MKDIR_SUCCESS; } int ErrCode=GetLastError(); if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND) return MKDIR_BADPATH; return MKDIR_ERROR; #elif defined(_UNIX) char NameA[NM]; WideToChar(Name,NameA,ASIZE(NameA)); mode_t uattr=SetAttr ? (mode_t)Attr:0777; int ErrCode=mkdir(NameA,uattr); #ifdef _ANDROID if (ErrCode==-1 && errno!=ENOENT) ErrCode=JniMkdir(Name) ? 0 : -1; // If external card is read-only for usual file API. if (ErrCode!=-1) JniFileNotify(Name,false); #endif if (ErrCode==-1) return errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR; return MKDIR_SUCCESS; #else return MKDIR_ERROR; #endif }
uint GetFileAttr(const wchar *Name) { #ifdef _WIN_ALL DWORD Attr=GetFileAttributes(Name); if (Attr==0xffffffff) { wchar LongName[NM]; if (GetWinLongPath(Name,LongName,ASIZE(LongName))) Attr=GetFileAttributes(LongName); } return Attr; #else char NameA[NM]; WideToChar(Name,NameA,ASIZE(NameA)); struct stat st; if (stat(NameA,&st)!=0) return 0; return st.st_mode; #endif }