summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/unix/CPP/Windows/FileDir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/unix/CPP/Windows/FileDir.cpp')
-rw-r--r--src/libs/7zip/unix/CPP/Windows/FileDir.cpp898
1 files changed, 431 insertions, 467 deletions
diff --git a/src/libs/7zip/unix/CPP/Windows/FileDir.cpp b/src/libs/7zip/unix/CPP/Windows/FileDir.cpp
index 838f92d5b..9915bd8b8 100644
--- a/src/libs/7zip/unix/CPP/Windows/FileDir.cpp
+++ b/src/libs/7zip/unix/CPP/Windows/FileDir.cpp
@@ -2,10 +2,14 @@
#include "StdAfx.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
#include "FileDir.h"
-#include "FileName.h"
#include "FileFind.h"
-#include "Defs.h"
+#include "FileName.h"
+
#include "../Common/StringConvert.h"
#include "../Common/IntToString.h"
@@ -25,6 +29,10 @@
// #define TRACEN(u) u;
#define TRACEN(u) /* */
+int g_filedir = 1;
+
+static NWindows::NSynchronization::CCriticalSection g_CountCriticalSection;
+
class Umask
{
public:
@@ -34,10 +42,12 @@ class Umask
current_umask = umask (0); /* get and set the umask */
umask(current_umask); /* restore the umask */
mask = 0777 & (~current_umask);
- }
+ }
};
static Umask gbl_umask;
+extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds );
+
#ifdef _UNICODE
AString nameWindowToUnix2(LPCWSTR name) // FIXME : optimization ?
@@ -47,10 +57,7 @@ AString nameWindowToUnix2(LPCWSTR name) // FIXME : optimization ?
}
#endif
-extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds );
-
-#ifdef _UNICODE
-DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *lastpart ) { // FIXME
+DWORD WINAPI GetFullPathNameW( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *lastpart ) { // FIXME
if (name == 0) return 0;
DWORD name_len = lstrlen(name);
@@ -71,7 +78,7 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
*lastpart=ptr+1;
ptr++;
}
- TRACEN((printf("GetFullPathNameA(%s,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
return ret;
}
if (isascii(name[0]) && (name[1] == ':')) { // FIXME isascii
@@ -89,14 +96,14 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
*lastpart=ptr+1;
ptr++;
}
- TRACEN((printf("GetFullPathNameA(%sl,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
return ret;
}
// name is a relative pathname.
//
if (len < 2) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 2)\n",name, (int)len)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 2)\n",name, (int)len)))
return 0;
}
@@ -110,13 +117,13 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
if (cret) {
begin_len = strlen(begin);
}
-
+
if (begin_len >= 1) {
// strlen(begin) + strlen("/") + strlen(name)
ret = begin_len + 1 + name_len;
if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 4)\n",name, (int)len)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 4)\n",name, (int)len)))
return 0;
}
UString wbegin = GetUnicodeString(begin);
@@ -131,136 +138,14 @@ DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *la
*lastpart=ptr+1;
ptr++;
}
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
} else {
ret = 0;
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 5)\n",name, (int)len)))
+ TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 5)\n",name, (int)len)))
}
return ret;
}
-#endif
-
-#if 0
-DWORD WINAPI GetFullPathName( LPCSTR name, DWORD len, LPSTR buffer, LPSTR *lastpart ) {
- if (name == 0) return 0;
-
- DWORD name_len = strlen(name);
-
- if (name[0] == '/') {
- DWORD ret = name_len+2;
- if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 0)\n",name, (int)len)))
- return 0;
- }
- strcpy(buffer,"c:");
- strcat(buffer,name);
-
- *lastpart=buffer;
- char *ptr=buffer;
- while (*ptr) {
- if (*ptr == '/')
- *lastpart=ptr+1;
- ptr++;
- }
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
- return ret;
- }
- if (isascii(name[0]) && (name[1] == ':')) {
- DWORD ret = name_len;
- if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 1)\n",name, (int)len)))
- return 0;
- }
- strcpy(buffer,name);
-
- *lastpart=buffer;
- char *ptr=buffer;
- while (*ptr) {
- if (*ptr == '/')
- *lastpart=ptr+1;
- ptr++;
- }
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
- return ret;
- }
-
- // name is a relative pathname.
- //
- if (len < 2) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 2)\n",name, (int)len)))
- return 0;
- }
-
- DWORD ret = 0;
- char begin[MAX_PATHNAME_LEN];
- /* DWORD begin_len = GetCurrentDirectoryA(MAX_PATHNAME_LEN,begin); */
- DWORD begin_len = 0;
- begin[0]='c';
- begin[1]=':';
- char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3);
- if (cret) {
- begin_len = strlen(begin);
- }
-
- if (begin_len >= 1) {
- // strlen(begin) + strlen("/") + strlen(name)
- ret = begin_len + 1 + name_len;
-
- if (ret >= len) {
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 4)\n",name, (int)len)))
- return 0;
- }
- strcpy(buffer,begin);
- strcat(buffer,"/");
- strcat(buffer,name);
-
- *lastpart=buffer + begin_len + 1;
- char *ptr=buffer;
- while (*ptr) {
- if (*ptr == '/')
- *lastpart=ptr+1;
- ptr++;
- }
- TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret)))
- } else {
- ret = 0;
- TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 5)\n",name, (int)len)))
- }
- return ret;
-}
-
-static BOOL WINAPI RemoveDirectory(LPCSTR path) {
- if (!path || !*path) {
- SetLastError(ERROR_PATH_NOT_FOUND);
- return FALSE;
- }
- const char * name = nameWindowToUnix(path);
- TRACEN((printf("RemoveDirectoryA(%s)\n",name)))
-
- if (rmdir( name ) != 0) {
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
-#ifdef _UNICODE
-static BOOL WINAPI RemoveDirectory(LPCWSTR path) {
- if (!path || !*path) {
- SetLastError(ERROR_PATH_NOT_FOUND);
- return FALSE;
- }
- AString name = nameWindowToUnix2(path);
- TRACEN((printf("RemoveDirectoryA(%s)\n",(const char *)name)))
-
- if (rmdir( (const char *)name ) != 0) {
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
static int copy_fd(int fin,int fout)
{
char buffer[16384];
@@ -297,6 +182,7 @@ static BOOL CopyFile(const char *src,const char *dst)
flags |= O_LARGEFILE;
#endif
+ // printf("##DBG CopyFile(%s,%s)\n",src,dst);
int fout = open(dst,O_CREAT | O_WRONLY | O_EXCL | flags, 0600);
if (fout != -1)
{
@@ -314,102 +200,76 @@ static BOOL CopyFile(const char *src,const char *dst)
return FALSE;
}
-/*****************************************************************************************/
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
namespace NWindows {
namespace NFile {
-namespace NDirectory {
+// SetCurrentDirectory doesn't support \\?\ prefix
-bool MySetCurrentDirectory(LPCWSTR wpath)
-{
- AString path = UnicodeStringToMultiByte(wpath);
+#ifdef WIN_LONG_PATH
+bool GetLongPathBase(CFSTR fileName, UString &res);
+bool GetLongPath(CFSTR fileName, UString &res);
+#endif
- return chdir((const char*)path) == 0;
-}
+namespace NDir {
-#ifdef _UNICODE
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
-}
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Left(index);
- return true;
-}
-#endif
+#ifdef _WIN32
+#ifndef UNDER_CE
-bool MyGetCurrentDirectory(CSysString &resultPath)
+bool MyGetWindowsDirectory(FString &path)
{
- char begin[MAX_PATHNAME_LEN];
- begin[0]='c';
- begin[1]=':';
- char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3);
- if (cret)
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
-#ifdef _UNICODE
- resultPath = GetUnicodeString(begin);
-#else
- resultPath = begin;
-#endif
- return true;
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
}
- return false;
-}
-
-bool MyMoveFile( LPCTSTR fn1, LPCTSTR fn2 ) {
-#ifdef _UNICODE
- AString src = nameWindowToUnix2(fn1);
- AString dst = nameWindowToUnix2(fn2);
-#else
- const char * src = nameWindowToUnix(fn1);
- const char * dst = nameWindowToUnix(fn2);
-#endif
-
- TRACEN((printf("MoveFileW(%s,%s)\n",src,dst)))
-
- int ret = rename(src,dst);
- if (ret != 0)
+ else
+ #endif
{
- if (errno == EXDEV) // FIXED : bug #1112167 (Temporary directory must be on same partition as target)
- {
- BOOL bret = CopyFile(src,dst);
- if (bret == FALSE) return false;
-
- struct stat info_file;
- ret = stat(src,&info_file);
- if (ret == 0) {
- TRACEN((printf("##DBG chmod-1(%s,%o)\n",dst,(unsigned)info_file.st_mode & gbl_umask.mask)))
- ret = chmod(dst,info_file.st_mode & gbl_umask.mask);
- }
- if (ret == 0) {
- ret = unlink(src);
- }
- if (ret == 0) return true;
- }
- return false;
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
}
- return true;
+ return (needLength > 0 && needLength <= MAX_PATH);
}
-bool MyRemoveDirectory(LPCTSTR pathName)
+
+bool MyGetSystemDirectory(FString &path)
{
- return BOOLToBool(::RemoveDirectory(pathName));
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
+ }
+ return (needLength > 0 && needLength <= MAX_PATH);
}
+#endif
+#endif // _WIN32
-bool SetDirTime(LPCWSTR fileName, const FILETIME * /* creationTime */ ,
- const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime)
+bool SetDirTime(CFSTR fileName, const FILETIME * /* cTime */ , const FILETIME *aTime, const FILETIME *mTime)
{
AString cfilename = UnicodeStringToMultiByte(fileName);
const char * unix_filename = nameWindowToUnix((const char *)cfilename);
@@ -427,22 +287,22 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME * /* creationTime */ ,
buf.modtime = current_time;
}
- if (lpLastAccessTime)
+ if (aTime)
{
LARGE_INTEGER ltime;
DWORD dw;
- ltime.QuadPart = lpLastAccessTime->dwHighDateTime;
- ltime.QuadPart = (ltime.QuadPart << 32) | lpLastAccessTime->dwLowDateTime;
+ ltime.QuadPart = aTime->dwHighDateTime;
+ ltime.QuadPart = (ltime.QuadPart << 32) | aTime->dwLowDateTime;
RtlTimeToSecondsSince1970( &ltime, &dw );
buf.actime = dw;
}
- if (lpLastWriteTime)
+ if (mTime)
{
LARGE_INTEGER ltime;
DWORD dw;
- ltime.QuadPart = lpLastWriteTime->dwHighDateTime;
- ltime.QuadPart = (ltime.QuadPart << 32) | lpLastWriteTime->dwLowDateTime;
+ ltime.QuadPart = mTime->dwHighDateTime;
+ ltime.QuadPart = (ltime.QuadPart << 32) | mTime->dwLowDateTime;
RtlTimeToSecondsSince1970( &ltime, &dw );
buf.modtime = dw;
}
@@ -452,25 +312,20 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME * /* creationTime */ ,
return true;
}
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
-{
- return MySetFileAttributes(UnicodeStringToMultiByte(fileName, CP_ACP), fileAttributes);
-}
-
-bool MyRemoveDirectory(LPCWSTR pathName)
-{
- return MyRemoveDirectory(UnicodeStringToMultiByte(pathName, CP_ACP));
-}
-
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
-{
- UINT codePage = CP_ACP;
- return MyMoveFile(UnicodeStringToMultiByte(existFileName, codePage), UnicodeStringToMultiByte(newFileName, codePage));
+#ifdef WIN_LONG_PATH
+bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2)
+{
+ if (!GetLongPathBase(s1, d1) ||
+ !GetLongPathBase(s2, d2))
+ return false;
+ if (d1.IsEmpty() && d2.IsEmpty())
+ return false;
+ if (d1.IsEmpty()) d1 = fs2us(s1);
+ if (d2.IsEmpty()) d2 = fs2us(s2);
+ return true;
}
#endif
-
static int convert_to_symlink(const char * name) {
FILE *file = fopen(name,"rb");
if (file) {
@@ -482,17 +337,17 @@ static int convert_to_symlink(const char * name) {
if (ir == 0) {
ir = symlink(buf,name);
}
- return ir;
+ return ir;
}
}
return -1;
}
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
+bool SetFileAttrib(CFSTR fileName, DWORD fileAttributes)
{
if (!fileName) {
SetLastError(ERROR_PATH_NOT_FOUND);
- TRACEN((printf("MySetFileAttributes(NULL,%d) : false-1\n",fileAttributes)))
+ TRACEN((printf("SetFileAttrib(NULL,%d) : false-1\n",fileAttributes)))
return false;
}
#ifdef _UNICODE
@@ -504,14 +359,14 @@ bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
#ifdef ENV_HAVE_LSTAT
if (global_use_lstat) {
if(lstat(name,&stat_info)!=0) {
- TRACEN((printf("MySetFileAttributes(%s,%d) : false-2-1\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : false-2-1\n",(const char *)name,fileAttributes)))
return false;
}
} else
#endif
{
if(stat(name,&stat_info)!=0) {
- TRACEN((printf("MySetFileAttributes(%s,%d) : false-2-2\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : false-2-2\n",(const char *)name,fileAttributes)))
return false;
}
}
@@ -521,18 +376,18 @@ bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
#ifdef ENV_HAVE_LSTAT
if (S_ISLNK(stat_info.st_mode)) {
if ( convert_to_symlink(name) != 0) {
- TRACEN((printf("MySetFileAttributes(%s,%d) : false-3\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : false-3\n",(const char *)name,fileAttributes)))
return false;
}
} else
#endif
if (S_ISREG(stat_info.st_mode)) {
- TRACEN((printf("##DBG chmod-2(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-2(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
} else if (S_ISDIR(stat_info.st_mode)) {
// user/7za must be able to create files in this directory
stat_info.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR);
- TRACEN((printf("##DBG chmod-3(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-3(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
}
#ifdef ENV_HAVE_LSTAT
@@ -545,121 +400,123 @@ bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
/* Only Windows Attributes */
if( S_ISDIR(stat_info.st_mode)) {
/* Remark : FILE_ATTRIBUTE_READONLY ignored for directory. */
- TRACEN((printf("##DBG chmod-4(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-4(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
} else {
if (fileAttributes & FILE_ATTRIBUTE_READONLY) stat_info.st_mode &= ~0222; /* octal!, clear write permission bits */
- TRACEN((printf("##DBG chmod-5(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
+ TRACEN((printf("##DBG chmod-5(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask)))
chmod(name,stat_info.st_mode & gbl_umask.mask);
}
}
- TRACEN((printf("MySetFileAttributes(%s,%d) : true\n",name,fileAttributes)))
+ TRACEN((printf("SetFileAttrib(%s,%d) : true\n",(const char *)name,fileAttributes)))
return true;
}
-bool MyCreateDirectory(LPCTSTR pathName)
-{
- if (!pathName || !*pathName) {
+bool RemoveDir(CFSTR path)
+{
+ if (!path || !*path) {
SetLastError(ERROR_PATH_NOT_FOUND);
- return false;
+ return FALSE;
}
+ AString name = nameWindowToUnix2(path);
+ TRACEN((printf("RemoveDirectoryA(%s)\n",(const char *)name)))
+
+ if (rmdir( (const char *)name ) != 0) {
+ return FALSE;
+ }
+ return TRUE;
+}
+bool MyMoveFile(CFSTR existFileName, CFSTR newFileName)
+{
#ifdef _UNICODE
- AString name = nameWindowToUnix2(pathName);
+ AString src = nameWindowToUnix2(existFileName);
+ AString dst = nameWindowToUnix2(newFileName);
#else
- const char * name = nameWindowToUnix(pathName);
+ const char * src = nameWindowToUnix(existFileName);
+ const char * dst = nameWindowToUnix(newFileName);
#endif
- bool bret = false;
- if (mkdir( name, 0700 ) == 0) bret = true;
-
- TRACEN((printf("MyCreateDirectory(%s)=%d\n",name,(int)bret)))
- return bret;
-}
-#ifndef _UNICODE
-bool MyCreateDirectory(LPCWSTR pathName)
-{
- return MyCreateDirectory(UnicodeStringToMultiByte(pathName, CP_ACP));
-}
-#endif
+ TRACEN((printf("MyMoveFile(%s,%s)\n",(const char *)src,(const char *)dst)))
-bool CreateComplexDirectory(LPCTSTR _aPathName)
-{
- CSysString pathName = _aPathName;
- int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos > 0 && pos == pathName.Length() - 1)
- {
- if (pathName.Length() == 3 && pathName[1] == ':')
- return true; // Disk folder;
- pathName.Delete(pos);
- }
- CSysString pathName2 = pathName;
- pos = pathName.Length();
- while(true)
+ int ret = rename(src,dst);
+ if (ret != 0)
{
- if(MyCreateDirectory(pathName))
- break;
- if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ if (errno == EXDEV) // FIXED : bug #1112167 (Temporary directory must be on same partition as target)
{
-#ifdef _WIN32 // FIXED for supporting symbolic link instead of a directory
- NFind::CFileInfo fileInfo;
- if (!NFind::FindFile(pathName, fileInfo)) // For network folders
- return true;
- if (!fileInfo.IsDir())
- return false;
-#endif
- break;
+ BOOL bret = CopyFile(src,dst);
+ if (bret == FALSE) return false;
+
+ struct stat info_file;
+ ret = stat(src,&info_file);
+ if (ret == 0) {
+ TRACEN((printf("##DBG chmod-1(%s,%o)\n",(const char *)dst,(unsigned)info_file.st_mode & gbl_umask.mask)))
+ ret = chmod(dst,info_file.st_mode & gbl_umask.mask);
+ }
+ if (ret == 0) {
+ ret = unlink(src);
+ }
+ if (ret == 0) return true;
}
- pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos < 0 || pos == 0)
- return false;
- if (pathName[pos - 1] == ':')
- return false;
- pathName = pathName.Left(pos);
- }
- pathName = pathName2;
- while(pos < pathName.Length())
- {
- pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
- if (pos < 0)
- pos = pathName.Length();
- if(!MyCreateDirectory(pathName.Left(pos)))
- return false;
+ return false;
}
return true;
}
-#ifndef _UNICODE
+bool CreateDir(CFSTR path)
+{
+ if (!path || !*path) {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ return false;
+ }
-bool CreateComplexDirectory(LPCWSTR _aPathName)
+#ifdef _UNICODE
+ AString name = nameWindowToUnix2(path);
+#else
+ const char * name = nameWindowToUnix(path);
+#endif
+ bool bret = false;
+ if (mkdir( name, 0700 ) == 0) bret = true;
+
+ TRACEN((printf("CreateDir(%s)=%d\n",(const char *)name,(int)bret)))
+ return bret;
+}
+
+bool CreateComplexDir(CFSTR _aPathName)
{
- UString pathName = _aPathName;
- int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos > 0 && pos == pathName.Length() - 1)
+ AString name = nameWindowToUnix2(_aPathName);
+ TRACEN((printf("CreateComplexDir(%s)\n",(const char *)name)))
+
+
+ FString pathName = _aPathName;
+ int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos > 0 && pos == pathName.Len() - 1)
{
- if (pathName.Length() == 3 && pathName[1] == L':')
+ if (pathName.Len() == 3 && pathName[1] == L':')
return true; // Disk folder;
pathName.Delete(pos);
}
- UString pathName2 = pathName;
- pos = pathName.Length();
- while(true)
+ FString pathName2 = pathName;
+ pos = pathName.Len();
+ TRACEN((printf("CreateComplexDir(%s) pathName2=%ls\n",(const char *)name,(CFSTR)pathName2)))
+ for (;;)
{
- if(MyCreateDirectory(pathName))
+ if (CreateDir(pathName))
break;
- if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ TRACEN((printf("CreateComplexDir(%s) GetLastError=%d (ERROR_ALREADY_EXISTS=%d)\n",(const char *)name,::GetLastError(), ERROR_ALREADY_EXISTS)))
+ if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
#ifdef _WIN32 // FIXED for supporting symbolic link instead of a directory
- NFind::CFileInfoW fileInfo;
- if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(pathName)) // For network folders
return true;
if (!fileInfo.IsDir())
return false;
#endif
break;
}
- pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos < 0 || pos == 0)
return false;
if (pathName[pos - 1] == L':')
@@ -667,20 +524,18 @@ bool CreateComplexDirectory(LPCWSTR _aPathName)
pathName = pathName.Left(pos);
}
pathName = pathName2;
- while(pos < pathName.Length())
+ while (pos < pathName.Len())
{
- pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ pos = pathName.Find(FCHAR_PATH_SEPARATOR, pos + 1);
if (pos < 0)
- pos = pathName.Length();
- if(!MyCreateDirectory(pathName.Left(pos)))
+ pos = pathName.Len();
+ if (!CreateDir(pathName.Left(pos)))
return false;
}
return true;
}
-#endif
-
-bool DeleteFileAlways(LPCTSTR name)
+bool DeleteFileAlways(CFSTR name)
{
if (!name || !*name) {
SetLastError(ERROR_PATH_NOT_FOUND);
@@ -693,235 +548,344 @@ bool DeleteFileAlways(LPCTSTR name)
#endif
bool bret = false;
if (remove(unixname) == 0) bret = true;
- TRACEN((printf("DeleteFileAlways(%s)=%d\n",unixname,(int)bret)))
+ TRACEN((printf("DeleteFileAlways(%s)=%d\n",(const char *)unixname,(int)bret)))
return bret;
}
-#ifndef _UNICODE
-bool DeleteFileAlways(LPCWSTR name)
-{
- return DeleteFileAlways(UnicodeStringToMultiByte(name, CP_ACP));
+bool RemoveDirWithSubItems(const FString &path)
+{
+ bool needRemoveSubItems = true;
+ {
+ NFind::CFileInfo fi;
+ if (!fi.Find(path))
+ return false;
+ if (!fi.IsDir())
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ if (fi.HasReparsePoint())
+ needRemoveSubItems = false;
+ }
+
+ if (needRemoveSubItems)
+ {
+ FString s = path;
+ s += FCHAR_PATH_SEPARATOR;
+ unsigned prefixSize = s.Len();
+ s += FCHAR_ANY_MASK;
+ NFind::CEnumerator enumerator(s);
+ NFind::CFileInfo fi;
+ while (enumerator.Next(fi))
+ {
+ s.DeleteFrom(prefixSize);
+ s += fi.Name;
+ if (fi.IsDir())
+ {
+ if (!RemoveDirWithSubItems(s))
+ return false;
+ }
+ else if (!DeleteFileAlways(s))
+ return false;
+ }
+ }
+
+ if (!SetFileAttrib(path, 0))
+ return false;
+ return RemoveDir(path);
}
-#endif
-static bool RemoveDirectorySubItems2(const UString &pathPrefix, const NFind::CFileInfoW &fileInfo)
+bool RemoveDirectoryWithSubItems(const FString &path); // FIXME
+static bool RemoveDirectorySubItems2(const FString pathPrefix, const NFind::CFileInfo &fileInfo)
{
if (fileInfo.IsDir())
return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
return DeleteFileAlways(pathPrefix + fileInfo.Name);
}
-
-bool RemoveDirectoryWithSubItems(const UString &path)
+bool RemoveDirectoryWithSubItems(const FString &path)
{
- NFind::CFileInfoW fileInfo;
- UString pathPrefix = path + NName::kDirDelimiter;
+ NFind::CFileInfo fileInfo;
+ FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
{
- NFind::CEnumeratorW enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
+ NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
while (enumerator.Next(fileInfo))
if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
return false;
}
- if (!MySetFileAttributes(path, 0))
+ if (!SetFileAttrib(path, 0))
return false;
- return MyRemoveDirectory(path);
+ return RemoveDir(path);
}
-#ifndef _WIN32_WCE
+#ifdef UNDER_CE
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
- int &fileNamePartStartIndex)
+bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
{
- LPTSTR fileNamePointer = 0;
- LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1,
- buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength == 0 || needLength >= MAX_PATH)
- return false;
- if (fileNamePointer == 0)
- fileNamePartStartIndex = lstrlen(fileName);
- else
- fileNamePartStartIndex = fileNamePointer - buffer;
+ resFullPath = fileName;
return true;
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
- int &fileNamePartStartIndex)
-{
- const UINT currentPage = CP_ACP;
- CSysString sysPath;
- if (!MyGetFullPathName(UnicodeStringToMultiByte(fileName,
- currentPage), sysPath, fileNamePartStartIndex))
- return false;
- UString resultPath1 = MultiByteToUnicodeString(
- sysPath.Left(fileNamePartStartIndex), currentPage);
- UString resultPath2 = MultiByteToUnicodeString(
- sysPath.Mid(fileNamePartStartIndex), currentPage);
- fileNamePartStartIndex = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
- return true;
-}
-#endif
+#else
+#ifdef WIN_LONG_PATH
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+static FString GetLastPart(CFSTR path)
{
- int index;
- return MyGetFullPathName(fileName, path, index);
+ int i = MyStringLen(path);
+ for (; i > 0; i--)
+ {
+ FChar c = path[i - 1];
+ if (c == FCHAR_PATH_SEPARATOR || c == '/')
+ break;
+ }
+ return path + i;
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &path)
+static void AddTrailingDots(CFSTR oldPath, FString &newPath)
{
- int index;
- return MyGetFullPathName(fileName, path, index);
+ int len = MyStringLen(oldPath);
+ int i;
+ for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
+ if (i == 0 || i == len)
+ return;
+ FString oldName = GetLastPart(oldPath);
+ FString newName = GetLastPart(newPath);
+ int nonDotsLen = oldName.Len() - (len - i);
+ if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
+ return;
+ for (; i != len; i++)
+ newPath += '.';
}
-#endif
#endif
-/* needed to find .DLL/.so and SFX */
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath)
+
+bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
{
- if (path != 0) {
- printf("NOT EXPECTED : MySearchPath : path != NULL\n");
- exit(EXIT_FAILURE);
+ resFullPath.Empty();
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ LPTSTR fileNamePointer = 0;
+ DWORD needLength = ::GetFullPathName(fs2fas(fileName), MAX_PATH + 1, s, &fileNamePointer);
+ if (needLength == 0 || needLength > MAX_PATH)
+ return false;
+ resFullPath = fas2fs(s);
+ return true;
}
-
- if (extension != 0) {
- printf("NOT EXPECTED : MySearchPath : extension != NULL\n");
- exit(EXIT_FAILURE);
+ else
+ #endif
+ {
+ LPWSTR fileNamePointer = 0;
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD needLength = ::GetFullPathNameW(fs2us(fileName), MAX_PATH + 1, s, &fileNamePointer);
+ if (needLength == 0)
+ return false;
+ if (needLength <= MAX_PATH)
+ {
+ resFullPath = us2fs(s);
+ return true;
+ }
+ #ifdef WIN_LONG_PATH
+ needLength++;
+ UString temp;
+ LPWSTR buffer = temp.GetBuffer(needLength + 1);
+ buffer[0] = 0;
+ DWORD needLength2 = ::GetFullPathNameW(fs2us(fileName), needLength, buffer, &fileNamePointer);
+ temp.ReleaseBuffer();
+ if (needLength2 > 0 && needLength2 <= needLength)
+ {
+ resFullPath = us2fs(temp);
+ AddTrailingDots(fileName, resFullPath);
+ return true;
+ }
+ #endif
+ return false;
}
+}
- if (fileName == 0) {
- printf("NOT EXPECTED : MySearchPath : fileName == NULL\n");
- exit(EXIT_FAILURE);
- }
+bool SetCurrentDir(CFSTR path)
+{
+ AString apath = UnicodeStringToMultiByte(path);
- const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR");
- if (p7zip_home_dir) {
- AString file_path = p7zip_home_dir;
- file_path += UnicodeStringToMultiByte(fileName, CP_ACP);
+ return chdir((const char*)apath) == 0;
+}
- TRACEN((printf("MySearchPath() fopen(%s)\n",(const char *)file_path)))
- FILE *file = fopen((const char *)file_path,"r");
- if (file) {
- // file is found
- fclose(file);
- resultPath = MultiByteToUnicodeString(file_path, CP_ACP);
- return true;
- }
+bool GetCurrentDir(FString &path)
+{
+ char begin[MAX_PATHNAME_LEN];
+ begin[0]='c';
+ begin[1]=':';
+ char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3);
+ if (cret)
+ {
+#ifdef _UNICODE
+ path = GetUnicodeString(begin);
+#else
+ path = begin;
+#endif
+ return true;
}
return false;
}
-#ifndef _UNICODE
-bool MyGetTempPath(CSysString &path)
-{
- path = "c:/tmp/"; // final '/' is needed
- return true;
-}
#endif
-bool MyGetTempPath(UString &path)
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
{
- path = L"c:/tmp/"; // final '/' is needed
- return true;
+ bool res = MyGetFullPathName(path, resDirPrefix);
+ if (!res)
+ resDirPrefix = path;
+ int pos = resDirPrefix.ReverseFind(FCHAR_PATH_SEPARATOR);
+ resFileName = resDirPrefix.Ptr(pos + 1);
+ resDirPrefix.DeleteFrom(pos + 1);
+ return res;
}
-static NSynchronization::CCriticalSection g_CountCriticalSection;
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix)
+{
+ FString resFileName;
+ return GetFullPathAndSplit(path, resDirPrefix, resFileName);
+}
-static CSysString CSysConvertUInt32ToString(UInt32 value)
+bool MyGetTempPath(FString &path)
{
- TCHAR buffer[32];
- ConvertUInt32ToString(value, buffer);
- return buffer;
+ path = L"c:/tmp/"; // final '/' is needed
+ return true;
}
-UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile)
{
+#ifdef _WIN32
+ UInt32 d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
+#else
static UInt32 memo_count = 0;
UInt32 count;
g_CountCriticalSection.Enter();
count = memo_count++;
g_CountCriticalSection.Leave();
-
- Remove();
-/* UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH)); */
UINT number = (UINT)getpid();
- resultPath = dirPath;
- resultPath += prefix;
- resultPath += TEXT('#');
- resultPath += CSysConvertUInt32ToString(number);
- resultPath += TEXT('@');
- resultPath += CSysConvertUInt32ToString(count);
- resultPath += TEXT(".tmp");
-
- _fileName = resultPath;
+ UInt32 d = (GetTickCount() << 12) ^ (count << 14) ^ number;
+#endif
+ for (unsigned i = 0; i < 100; i++)
+ {
+ path = prefix;
+ if (addRandom)
+ {
+ FChar s[16];
+ UInt32 value = d;
+ unsigned k;
+ for (k = 0; k < 8; k++)
+ {
+ unsigned t = value & 0xF;
+ value >>= 4;
+ s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ s[k] = '\0';
+ if (outFile)
+ path += FChar('.');
+ path += s;
+ UInt32 step = GetTickCount() + 2;
+ if (step == 0)
+ step = 1;
+ d += step;
+ }
+ addRandom = true;
+ if (outFile)
+ path += FTEXT(".tmp");
+ if (NFind::DoesFileOrDirExist(path))
+ {
+ SetLastError(ERROR_ALREADY_EXISTS);
+ continue;
+ }
+ if (outFile)
+ {
+ if (outFile->Create(path, false))
+ return true;
+ }
+ else
+ {
+ if (CreateDir(path))
+ return true;
+ }
+ DWORD error = GetLastError();
+ if (error != ERROR_FILE_EXISTS &&
+ error != ERROR_ALREADY_EXISTS)
+ break;
+ }
+ path.Empty();
+ return false;
+}
+
+bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile)
+{
+ if (!Remove())
+ return false;
+ if (!CreateTempFile(prefix, false, _path, outFile))
+ return false;
_mustBeDeleted = true;
-
- return number;
+ return true;
}
-bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile)
{
- CSysString tempPath;
+ if (!Remove())
+ return false;
+ FString tempPath;
if (!MyGetTempPath(tempPath))
return false;
- if (Create(tempPath, prefix, resultPath) != 0)
- return true;
- return false;
+ if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile))
+ return false;
+ _mustBeDeleted = true;
+ return true;
}
-
bool CTempFile::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !DeleteFileAlways(_path);
return !_mustBeDeleted;
}
-bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
+bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore)
{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFileW tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
+ if (deleteDestBefore)
+ if (NFind::DoesFileExist(name))
+ if (!DeleteFileAlways(name))
return false;
- }
- /*
- UINT32 randomNumber = random.Generate();
- TCHAR randomNumberString[32];
- _stprintf(randomNumberString, _T("%04X"), randomNumber);
- dirName = prefix + randomNumberString;
- */
- if (NFind::DoesFileOrDirExist(dirName))
- continue;
- if (MyCreateDirectory(dirName))
- return true;
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
+ DisableDeleting();
+ return MyMoveFile(_path, name);
}
-bool CTempDirectory::Create(LPCTSTR prefix)
+bool CTempDir::Create(CFSTR prefix)
{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+ if (!Remove())
+ return false;
+ FString tempPath;
+ if (!MyGetTempPath(tempPath))
+ return false;
+ if (!CreateTempFile(tempPath + prefix, true, _path, NULL))
+ return false;
+ _mustBeDeleted = true;
+ return true;
}
+bool CTempDir::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_path);
+ return !_mustBeDeleted;
+}
}}}
+
+
+