123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876 |
- #include "precompile.h"
- #include <wchar.h>
- #include <errno.h>
- #include <assert.h>
- #ifdef _WIN32
- #include <mbstring.h>
- #include <limits.h>
- #include <ShellAPI.h>
- #else
- #include <winpr/wtypes.h>
- #include <winpr/error.h>
- #include <winpr/file.h>
- #include <libgen.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #endif
- #include "array.h"
- #include "fileutil.h"
- #include "strutil.h"
- #include "memutil.h"
- #include "dbgutil.h"
- #include <winpr/wlog.h>
- #define TAG TOOLKIT_TAG("fileutil")
- TOOLKIT_API BOOL ExistsDirA(LPCSTR lpDirPath)
- {
- DWORD dwRet = GetFileAttributesA(lpDirPath);
- return (dwRet != INVALID_FILE_ATTRIBUTES) && (dwRet & FILE_ATTRIBUTE_DIRECTORY);
- }
- TOOLKIT_API BOOL ExistsDirW(LPCWSTR lpDirPath)
- {
- DWORD dwRet = GetFileAttributesW(lpDirPath);
- return (dwRet != INVALID_FILE_ATTRIBUTES) && (dwRet & FILE_ATTRIBUTE_DIRECTORY);
- }
- TOOLKIT_API BOOL ExistsFileA(LPCSTR lpFilePath)
- {
- DWORD dwRet = GetFileAttributesA(lpFilePath);
- return (dwRet != INVALID_FILE_ATTRIBUTES) && !(dwRet & FILE_ATTRIBUTE_DIRECTORY);
- }
- TOOLKIT_API BOOL ExistsFileW(LPCWSTR lpFilePath)
- {
- DWORD dwRet = GetFileAttributesW(lpFilePath);
- return (dwRet != INVALID_FILE_ATTRIBUTES) && !(dwRet & FILE_ATTRIBUTE_DIRECTORY);
- }
- TOOLKIT_API BOOL CreateDirA(LPCSTR lpDirPath, BOOL bRecursive)
- {
- char* slashPos = NULL;
- char* backSlashPos = NULL;
- size_t len = strlen(lpDirPath);
- if (len <= 2 || len >= MAX_PATH-2) {
- return FALSE;
- } else {
- if (!bRecursive) {
- if (ExistsDirA(lpDirPath))
- return TRUE;
- return CreateDirectoryA(lpDirPath, NULL);
- }
- else {
- CHAR tmp[MAX_PATH], * p;
- CHAR* q = NULL;
- q = p = &tmp[0];
- strncpy(tmp, lpDirPath, MAX_PATH);
- tmp[MAX_PATH - 1] = 0;
- if (tmp[len - 1] != BACK_SLASH && tmp[len - 1] != SLASH) {
- tmp[len++] = SPLIT_SLASH;
- tmp[len] = 0;
- }
- #ifdef _WIN32
- do {
- slashPos = strchr(p, SLASH);
- backSlashPos = strchr(p, BACK_SLASH);
- if (slashPos != NULL && backSlashPos != NULL) {
- p = slashPos < backSlashPos ? slashPos : backSlashPos;
- }
- else if (slashPos != NULL) {
- p = slashPos;
- }
- else {
- p = backSlashPos;
- }
- if (!p) {
- break;
- }
- *p = 0;
- if (!ExistsDirA(tmp)) {
- if (!CreateDirectoryA(tmp, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
- return FALSE;
- }
- *p = SPLIT_SLASH;
- p++;
- }
- while (1);
- #else
- while ((p = strchr(p, SPLIT_SLASH)) != NULL) {
- if(p != q) {//linux compatibility.
- *p = 0;
- if (!ExistsDirA(tmp)) {
- if (!CreateDirectoryA(tmp, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
- return FALSE;
- }
- *p = SPLIT_SLASH;
- }
- p++;
- q = p;
- }
- #endif
- }
- }
- return TRUE;
- }
- TOOLKIT_API BOOL CreateDirW(LPCWSTR lpDirPath, BOOL bRecursive)
- {
- WCHAR* slashPos = NULL;
- WCHAR* backSlashPos = NULL;
- size_t len = wcslen(lpDirPath);
- if (len <= 2 || len >= MAX_PATH-2) {
- return FALSE;
- } else {
- if (!bRecursive) {
- return CreateDirectoryW(lpDirPath, NULL) || (GetLastError() == ERROR_ALREADY_EXISTS);
- } else {
- WCHAR tmp[MAX_PATH], *p;
- WCHAR* q = NULL;
- q = p = &tmp[0];
- wcsncpy(tmp, lpDirPath, MAX_PATH);
- tmp[MAX_PATH-1] = 0;
- if (tmp[len-1] != '\\' && tmp[len-1] != '/') {
- tmp[len++] = SPLIT_SLASH;
- tmp[len] = 0;
- }
- #ifdef _WIN32
- do {
- slashPos = wcschr(p, SLASH);
- backSlashPos = wcschr(p, BACK_SLASH);
- if (slashPos != NULL && backSlashPos != NULL) {
- p = slashPos < backSlashPos ? slashPos : backSlashPos;
- }
- else if (slashPos != NULL) {
- p = slashPos;
- }
- else {
- p = backSlashPos;
- }
- if (!p) {
- break;
- }
- *p = 0;
- if (!ExistsDirW(tmp)) {
- if (!CreateDirectoryW(tmp, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
- return FALSE;
- }
- *p = SPLIT_SLASH;
- p++;
- } while (1);
- #else
- while ((p = wcschr(p, SPLIT_SLASH)) != NULL) {
- if (p != q) {//linux compatibility.
- *p = 0;
- if (!ExistsDirW(tmp)) {
- if (!CreateDirectoryW(tmp, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
- return FALSE;
- }
- *p = SPLIT_SLASH;
- }
- p++;
- q = p;
- }
- #endif
- }
- }
- return TRUE;
- }
- TOOLKIT_API BOOL CreateDirRecursiveA(LPCSTR lpDirPath) { return CreateDirA(lpDirPath, TRUE); }
- TOOLKIT_API BOOL CreateDirRecursiveW(LPCWSTR lpDirPath) { return CreateDirW(lpDirPath, TRUE); }
- TOOLKIT_API BOOL CreateParentDirA(LPCSTR lpPath, BOOL bRecursive)
- {
- CHAR pdir[MAX_PATH];
- const CHAR *p;
- p = strrchr(lpPath, '\\');
- if (!p) {
- p = strrchr(lpPath, '/');
- }
- if (!p) {
- return FALSE;
- }
- strncpy(pdir, lpPath, p-lpPath);
- pdir[p-lpPath] = 0;
- return CreateDirA(pdir, bRecursive);
- }
- TOOLKIT_API BOOL CreateParentDirW(LPCWSTR lpPath, BOOL bRecursive)
- {
- WCHAR pdir[MAX_PATH];
- const WCHAR *p;
- p = wcsrchr(lpPath, '\\');
- if (!p) {
- p = wcsrchr(lpPath, '/');
- }
- if (!p) {
- return FALSE;
- }
- wcsncpy(pdir, lpPath, p-lpPath);
- pdir[p-lpPath] = 0;
- return CreateDirW(pdir, bRecursive);
- }
- TOOLKIT_API BOOL ClearDirRecursiveA(LPCSTR lpDirPath)
- {
- array_header_t *arr;
- BOOL bRet = TRUE;
- TOOLKIT_ASSERT(lpDirPath);
- arr = fileutil_get_sub_files_a(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- char *tmp = ARRAY_IDX(arr, i, char*);
- bRet &= DeleteFileA(tmp);
- }
- toolkit_array_free2(arr);
- }
- arr = fileutil_get_sub_dirs_a(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- char *tmp = ARRAY_IDX(arr, i, char*);
- bRet &= ClearDirRecursiveA(tmp);
- }
- toolkit_array_free2(arr);
- }
- return bRet;
- }
- TOOLKIT_API BOOL ClearDirRecursiveW(LPCWSTR lpDirPath)
- {
- array_header_t *arr;
- BOOL bRet = TRUE;
- TOOLKIT_ASSERT(lpDirPath);
- arr = fileutil_get_sub_files_w(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- wchar_t *tmp = ARRAY_IDX(arr, i, wchar_t*);
- bRet &= DeleteFileW(tmp);
- }
- toolkit_array_free2(arr);
- }
- arr = fileutil_get_sub_dirs_w(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- wchar_t *tmp = ARRAY_IDX(arr, i, wchar_t*);
- bRet &= ClearDirRecursiveW(tmp);
- }
- toolkit_array_free2(arr);
- }
- return bRet;
- }
- TOOLKIT_API BOOL RemoveFileA(LPCSTR pszFile)
- {
- if(ExistsFileA(pszFile))
- {
- // remove readonly attribute
- DWORD dwRet = GetFileAttributesA(pszFile);
- if (dwRet & FILE_ATTRIBUTE_READONLY)
- {
- dwRet &= (~FILE_ATTRIBUTE_READONLY);
- SetFileAttributesA(pszFile, dwRet);
- }
- // delete it
- return DeleteFileA(pszFile);
- }
- return FALSE;
- }
- // 移除文件只读属性
- TOOLKIT_API BOOL RemoveFileReadOnlyAttributeA(LPCSTR pszFile)
- {
- if(ExistsFileA(pszFile))
- {
- // remove readonly attribute
- DWORD dwRet = GetFileAttributesA(pszFile);
- if (dwRet & FILE_ATTRIBUTE_READONLY)
- {
- dwRet &= (~FILE_ATTRIBUTE_READONLY);
- SetFileAttributesA(pszFile, dwRet);
- }
- return TRUE;
- }
- return FALSE;
- }
- // 递归拷贝所有文件及子文件夹
- TOOLKIT_API BOOL CopyDirA(LPCSTR pszSourceDir, LPCSTR pszDestDir)
- {
- array_header_t *arr;
- BOOL bRet = TRUE;
- if (!ExistsDirA(pszSourceDir))
- return FALSE;
- if (!ExistsDirA(pszDestDir))
- {
- if (!CreateDirRecursiveA(pszDestDir))
- return FALSE;
- }
- arr = fileutil_get_sub_files_a(pszSourceDir);
- if (arr)
- {
- int i;
- for (i = 0; i < arr->nelts; ++i)
- {
- char szDestFile[256] = {0};
- char *file = ARRAY_IDX(arr, i, char*);
- strcpy(szDestFile, pszDestDir);
- if (szDestFile[strlen(szDestFile)-1] != '\\' && szDestFile[strlen(szDestFile) - 1] != '/')
- strcat(szDestFile, MB_SPLIT_SLASH_STR);
- strcat(szDestFile, strrchr(file, SPLIT_SLASH)+1);
-
- bRet &= CopyFileA(file, szDestFile, FALSE);
- }
- toolkit_array_free2(arr);
- }
- arr = fileutil_get_sub_dirs_a(pszSourceDir);
- if (arr)
- {
- int i;
- for (i = 0; i < arr->nelts; ++i)
- {
- char szDestSubDir[256] = {0};
- char *dir = ARRAY_IDX(arr, i, char*);
- strcpy(szDestSubDir, pszDestDir);
- if (szDestSubDir[strlen(szDestSubDir)-1] != '\\' && szDestSubDir[strlen(szDestSubDir) - 1] != '/')
- strcat(szDestSubDir, MB_SPLIT_SLASH_STR);
- strcat(szDestSubDir, strrchr(dir, SPLIT_SLASH)+1);
-
- bRet &= CopyDirA(dir, szDestSubDir);
- }
- toolkit_array_free2(arr);
- }
- return bRet;
- }
- TOOLKIT_API BOOL RemoveDirRecursiveA(LPCSTR lpDirPath)
- {
- #ifdef _WIN32
- int nRet = 0;
- char szDir[256] = {0};
- SHFILEOPSTRUCT fo;
- memset(&fo, 0, sizeof(fo));
- memcpy(szDir, lpDirPath, strlen(lpDirPath));
- fo.wFunc = FO_DELETE;
- fo.pFrom = szDir;
- fo.fFlags = FOF_NO_UI;
- nRet = SHFileOperationA(&fo);
- return nRet ==0 ? TRUE: FALSE;
- #else
- array_header_t* arr;
- BOOL bRet = TRUE;
- TOOLKIT_ASSERT(lpDirPath);
- arr = fileutil_get_sub_files_a(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- char* tmp = ARRAY_IDX(arr, i, char*);
- bRet &= DeleteFileA(tmp);
- }
- toolkit_array_free2(arr);
- }
- arr = fileutil_get_sub_dirs_a(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- char* tmp = ARRAY_IDX(arr, i, char*);
- bRet &= RemoveDirRecursiveA(tmp);
- }
- toolkit_array_free2(arr);
- }
- if (bRet) {
- bRet = RemoveDirectoryA(lpDirPath);
- }
- return bRet;
- #endif
- }
- TOOLKIT_API BOOL RemoveDirRecursiveW(LPCWSTR lpDirPath)
- {
- array_header_t *arr;
- BOOL bRet = TRUE;
- TOOLKIT_ASSERT(lpDirPath);
- arr = fileutil_get_sub_files_w(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- wchar_t *tmp = ARRAY_IDX(arr, i, wchar_t*);
- bRet &= DeleteFileW(tmp);
- }
- toolkit_array_free2(arr);
- }
- arr = fileutil_get_sub_dirs_w(lpDirPath);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- wchar_t *tmp = ARRAY_IDX(arr, i, wchar_t*);
- bRet &= RemoveDirRecursiveW(tmp);
- }
- toolkit_array_free2(arr);
- }
- if (bRet) {
- bRet = RemoveDirectoryW(lpDirPath);
- }
- return bRet;
- }
- TOOLKIT_API HANDLE ExtCreateFileW(LPCWSTR lpFileName,
- DWORD dwDesiredAccess,
- DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- DWORD dwCreationDisposition,
- DWORD dwFlagsAndAttributes,
- HANDLE hTemplateFile)
- {
- if (!lpFileName)
- return INVALID_HANDLE_VALUE;
- if (lpFileName[0] != '\\')
- CreateParentDirW(lpFileName, TRUE);
- return CreateFileW(lpFileName,
- dwDesiredAccess,
- dwShareMode,
- lpSecurityAttributes,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- hTemplateFile);
- }
- TOOLKIT_API HANDLE ExtCreateFileA(LPCSTR lpFileName,
- DWORD dwDesiredAccess,
- DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- DWORD dwCreationDisposition,
- DWORD dwFlagsAndAttributes,
- HANDLE hTemplateFile)
- {
- if (!lpFileName)
- return INVALID_HANDLE_VALUE;
- if (lpFileName[0] != '\\')
- CreateParentDirA(lpFileName, TRUE);
- return CreateFileA(lpFileName,
- dwDesiredAccess,
- dwShareMode,
- lpSecurityAttributes,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- hTemplateFile);
- }
- TOOLKIT_API int fileutil_copy_file(const char* dest_file_path, const char* src_file_path)
- {
- if (CopyFileA(src_file_path, dest_file_path, FALSE)) {
- return 0;
- }
- return -1;
- }
- TOOLKIT_API void fileutil_delete_file(const char* filename)
- {
- #ifdef _WIN32
- DeleteFileA(filename);
- #else
- unlink(filename);
- #endif //_WIN32
- }
- /*
- * isfile: only fetch file type elem or not.
- * limitation: max elem count to satsfy.
- */
- static array_header_t *fileutil_get_sub_a(const char *path, int isfile, int limitation)
- {
- #if 1
- array_header_t* arr = NULL;
- char tmp[MAX_PATH];
- int npath;
- if (!path)
- return NULL;
- npath = strlen(path);
- if (npath < 2)
- return NULL;
- strcpy(tmp, path);
- if (tmp[npath - 1] != '\\' && tmp[npath - 1] != '/') {
- tmp[npath++] = SPLIT_SLASH;
- tmp[npath] = 0;
- }
- tmp[npath++] = '*';
- tmp[npath] = 0;
- arr = array_make(3, sizeof(char*));
- {
- WIN32_FIND_DATAA fd;
- HANDLE hFind = FindFirstFileA(tmp, &fd);
- if (hFind != INVALID_HANDLE_VALUE) {
- tmp[--npath] = 0;
- do {
- int isdir = !!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
- if (isdir) {
- if (strcmp(fd.cFileName, ".") == 0 || strcmp(fd.cFileName, "..") == 0) {
- continue;
- }
- }
- /*[if require file while is not dir] or [not require file but is dir]*/
- if (isfile ^ isdir) {
- char* v = malloc(sizeof(char) * (npath + strlen(fd.cFileName) + 1));
- strcpy(v, tmp);
- strcat(v, fd.cFileName);
- ARRAY_PUSH(arr, char*) = v;
- }
- } while (FindNextFileA(hFind, &fd) && arr->nelts < limitation);
- FindClose(hFind);
- }
- }
- #else
- array_header_t* arr = NULL;
- char tmp[MAX_PATH];
- char tmp2[MAX_PATH];
- DIR* d = NULL;
- struct dirent* dp = NULL;
- struct stat st;
- int npath;
- if (!path)
- return NULL;
- npath = strlen(path);
- if (npath < 1)
- return NULL;
- strcpy(tmp, path);
- if (tmp[npath - 1] == '/') {
- tmp[npath - 1] = '\0';
- }
- if (stat(tmp, &st) < 0 || !S_ISDIR(st.st_mode)) {
- return NULL;
- }
- if (!(d = opendir(tmp))) {
- return NULL;
- }
- if (tmp[npath - 1] != '/') {
- tmp[npath++] = '/';
- tmp[npath] = 0;
- }
- arr = array_make(3, sizeof(char*));
- while ((dp = readdir(d)) != NULL && arr->nelts < limitation)
- {
- if((!strncmp(dp->d_name, ".", 1)) || (!strncmp(dp->d_name, "..", 2))) {
- continue;
- }
- snprintf(tmp2, sizeof(tmp2) - 1, "%s%s", tmp, dp->d_name);
- stat(tmp2, &st);
- int isdir = !!(S_ISDIR(st.st_mode));
- if (isfile ^ isdir) {
- char* v = malloc(sizeof(char) * (npath + strlen(dp->d_name) + 1));
- strcpy(v, tmp);
- strcat(v, dp->d_name);
- ARRAY_PUSH(arr, char*) = v;
- }
- }
- closedir(d);
- #endif //1
- return arr;
- }
- static array_header_t *fileutil_get_sub_w(const wchar_t *path, int isfile, int limitation)
- {
- array_header_t *arr = NULL;
- WCHAR tmp[MAX_PATH];
- int npath;
- if (!path)
- return NULL;
- npath = wcslen(path);
- if (npath < 2)
- return NULL;
- wcscpy(tmp, path);
- if (tmp[npath - 1] != '\\' && tmp[npath - 1] != '/') {
- tmp[npath++] = SPLIT_SLASH;
- tmp[npath] = 0;
- }
- tmp[npath++] = '*';
- tmp[npath] = 0;
- arr = array_make(3, sizeof(wchar_t*));
- {
- WIN32_FIND_DATAW fd;
- HANDLE hFind = FindFirstFileW(tmp, &fd);
- if (hFind != INVALID_HANDLE_VALUE) {
- tmp[--npath] = 0;
- do {
- int isdir = !!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
- if (isfile ^ isdir) {
- wchar_t* v = malloc(sizeof(wchar_t) * (npath + wcslen(fd.cFileName) + 1));
- wcscpy(v, tmp);
- wcscat(v, fd.cFileName);
- ARRAY_PUSH(arr, wchar_t*) = v;
- }
- } while (FindNextFileW(hFind, &fd) && arr->nelts < limitation);
- FindClose(hFind);
- }
- }
- return arr;
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_files_a(const char *path)
- {
- return fileutil_get_sub_a(path, 1, INT_MAX);
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_dirs_a(const char *path)
- {
- return fileutil_get_sub_a(path, 0, INT_MAX);
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_files_w(const wchar_t *path)
- {
- return fileutil_get_sub_w(path, 1, INT_MAX);
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_dirs_w(const wchar_t *path)
- {
- return fileutil_get_sub_w(path, 0, INT_MAX);
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_files2_a(const char *path, int limitation)
- {
- return fileutil_get_sub_a(path, 1, limitation);
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_dirs2_a(const char *path, int limitation)
- {
- return fileutil_get_sub_a(path, 0, limitation);
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_files2_w(const wchar_t *path, int limitation)
- {
- return fileutil_get_sub_w(path, 1, limitation);
- }
- TOOLKIT_API array_header_t *fileutil_get_sub_dirs2_w(const wchar_t *path, int limitation)
- {
- return fileutil_get_sub_w(path, 0, limitation);
- }
- TOOLKIT_API FILE *fileutil_transaction_fopen(const char *filename, const char *mode)
- {
- DWORD dwAttr;
- char t[MAX_PATH];
- int write_flag;
- if (!filename || !mode) {
- errno = EINVAL;
- return NULL;
- }
- write_flag = (int)strchr(mode, 'w');
- strcpy(t, filename);
- strcat(t, ".bak");
- dwAttr = GetFileAttributesA(filename);
- if (dwAttr != INVALID_FILE_ATTRIBUTES && dwAttr & FILE_ATTRIBUTE_DIRECTORY) {
- errno = EIO;
- return NULL;
- }
- if (dwAttr != INVALID_FILE_ATTRIBUTES) {
- if (!(dwAttr & FILE_ATTRIBUTE_READONLY)) {
- BOOL bRet = DeleteFileA(filename);
- if (bRet) {
- if (!write_flag) {
- if (ExistsFileA(t)) {
- bRet = CopyFileA(t, filename, FALSE);
- if (bRet)
- bRet = SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL);
- }
- }
- }
- if (!bRet) {
- errno = EIO;
- return NULL;
- }
- } else {
- if (write_flag) {
- BOOL bRet = TRUE;
- if (ExistsFileA(t)) {
- bRet = SetFileAttributesA(t, dwAttr & ~FILE_ATTRIBUTE_READONLY);
- }
- if (bRet) {
- bRet = CopyFileA(filename, t, FALSE);
- }
- if (!bRet) {
- errno = EIO;
- return NULL;
- }
- }
- }
- } else {
- if (!write_flag) {
- BOOL bRet = TRUE;
- if (ExistsFileA(t)) {
- bRet = CopyFileA(t, filename, FALSE);
- } else {
- bRet = FALSE;
- }
- if (!bRet) {
- errno = EIO;
- return NULL;
- }
- }
- }
- return fopen(filename, mode);
- }
- TOOLKIT_API int fileutil_transaction_fclose(const char *filename, FILE *fp)
- {
- int rc = fclose(fp);
- if (!rc && filename) {
- DWORD dwAttr = GetFileAttributesA(filename);
- if (dwAttr != INVALID_FILE_ATTRIBUTES) {
- if (!(dwAttr & FILE_ATTRIBUTE_READONLY))
- SetFileAttributesA(filename, dwAttr | FILE_ATTRIBUTE_READONLY);
- }
- }
- return rc;
- }
- #ifndef _WIN32
- void _splitpath(const char* path, char* drive, char* dir, char* fname, char* ext)
- {
- char resolved_path[4096];
- char* p;
- char* q;
- char* last_slash = NULL;
- char* dot = NULL;
- size_t len, sub_len;
- if (drive) {
- *drive = '\0';
- }
- if (path == NULL) {
- if (dir) { *dir = '\0'; }
- if (fname) { *fname = '\0'; }
- if (ext) { *ext = '\0'; }
- return;
- }
-
- if (realpath(path, resolved_path) == NULL) {
- WLog_ERR(TAG, "realpath failed: %s", strerror(errno));
- strcpy(resolved_path, path);
- }
- else {
- //WLog_DBG(TAG, "resolved_path: %s", resolved_path);
- }
- len = strlen(resolved_path);
- if (resolved_path[0] == '/') {
- p = strchr(resolved_path + 1, '/');
- if (p != NULL) {
- *p = '\0';
- }
- if (drive) {
- strcpy(drive, resolved_path);
- }
- if (p != NULL) {
- *p = '/';
- }
- else {
- p = resolved_path + len;
- }
- } else {
- p = resolved_path;
- }
- q = p;
- for (last_slash = NULL; p && *p != '\0'; ++p) {
- if (*p == '/') {
- last_slash = p + 1;
- if (dot) {
- dot = NULL;
- }
- }
- else if(*p == '.') {
- dot = p;
- }
- }
- if (last_slash) {
- if (dir) {
- sub_len = last_slash - q;
- strncpy(dir, q, sub_len);
- *(dir + sub_len) = '\0';
- }
- q = last_slash;
- }
- else if(dir){
- *dir = '\0';
- }
- if (dot) {
- if (fname) {
- sub_len = dot - q;
- strncpy(fname, q, sub_len);
- *(fname + sub_len) = '\0';
- }
- if (ext) {
- sub_len = p - dot;
- strncpy(ext, dot, sub_len);
- *(ext + sub_len) = '\0';
- }
- }
- else {
- if (fname) {
- sub_len = p - q;
- strncpy(fname, q, sub_len);
- *(fname + sub_len) = '\0';
- }
- if (ext) {
- *ext = '\0';
- }
- }
- }
- #endif //NOT _WIN32
|