aheinecke@404: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik aheinecke@404: * Software engineering by Intevation GmbH aheinecke@404: * aheinecke@404: * This file is Free Software under the GNU GPL (v>=2) aheinecke@404: * and comes with ABSOLUTELY NO WARRANTY! aheinecke@404: * See LICENSE.txt for details. aheinecke@404: */ wilde@146: #include "portpath.h" andre@984: #include "strhelp.h" andre@984: #include "util.h" andre@1070: #include "logging.h" wilde@146: wilde@146: #include wilde@146: #include wilde@146: #include wilde@146: #include wilde@168: #include wilde@168: #include wilde@168: #include andre@986: #include wilde@146: andre@1157: #ifdef WIN32 andre@1157: #include andre@1157: #endif andre@1157: wilde@146: char * wilde@146: port_dirname(char *path) wilde@146: { wilde@146: #ifndef _WIN32 wilde@146: return dirname(path); wilde@146: #else wilde@164: char drive[_MAX_DRIVE]; wilde@164: char dir[_MAX_DIR]; wilde@164: _splitpath(path, drive, dir, NULL, NULL); wilde@170: size_t dlen = strlen(dir); wilde@170: if ((dlen > 0) && wilde@170: ((dir[dlen-1] == '/') || (dir[dlen-1] == '\\'))) wilde@170: dir[dlen-1] = '\0'; wilde@164: /* We assume: drive + dir is shorter than wilde@164: * drive + dir + fname + ext */ wilde@164: sprintf(path, "%s%s", drive, dir); wilde@164: return path; wilde@146: #endif wilde@146: } wilde@146: andre@975: bool andre@1070: port_mkdir(const char *path, bool propagate_acl) andre@975: { andre@975: #ifndef _WIN32 andre@1070: if (propagate_acl) andre@1070: { andre@1070: DEBUGPRINTF("WARNING: ACL propagation only has an effect on Windows.\n"); andre@1070: } andre@975: return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; andre@975: #else andre@984: wchar_t *wchar_path = utf8_to_wchar(path, strlen(path)); andre@984: bool ret; andre@984: andre@984: if (!wchar_path) andre@984: { andre@984: return false; andre@984: } andre@1208: ret = create_restricted_directory (wchar_path, propagate_acl, NULL); andre@984: xfree (wchar_path); andre@984: return ret; andre@975: #endif andre@975: } andre@975: wilde@146: char * andre@975: port_realpath(const char *path) wilde@146: { wilde@146: #ifndef _WIN32 wilde@146: return realpath(path, NULL); wilde@146: #else wilde@169: char *fp = _fullpath(NULL, path, 0); wilde@169: if (port_fileexits(fp)) wilde@169: return fp; wilde@169: else wilde@169: return NULL; wilde@146: #endif wilde@146: } wilde@168: wilde@168: bool wilde@168: port_fileexits(char *path) wilde@168: { wilde@168: int ret; wilde@168: #ifndef _WIN32 wilde@168: struct stat sb; wilde@168: ret = stat(path, &sb); wilde@168: #else wilde@168: struct _stat sb; wilde@168: ret = _stat(path, &sb); wilde@168: #endif wilde@168: wilde@168: if (ret == 0) wilde@168: return true; wilde@168: else wilde@168: return false; wilde@168: } wilde@176: wilde@176: bool andre@1070: port_mkdir_p(const char *path, bool propagate_acl) andre@984: { andre@984: char *parent_path, andre@984: *p; andre@984: if (!path) { andre@984: return false; andre@984: } andre@984: if (port_isdir(path)) { andre@984: return true; andre@984: } andre@984: parent_path = xstrndup (path, strlen(path)); andre@984: p = strrchr(parent_path, '/'); andre@984: if (!p) andre@984: { andre@984: p = strrchr(parent_path, '\\'); andre@984: } andre@984: if (!p) andre@984: { andre@984: return false; andre@984: } andre@984: *p = '\0'; andre@984: if (!port_isdir(parent_path)) andre@984: { andre@1070: port_mkdir_p(parent_path, false); andre@984: } andre@1070: return port_mkdir(path, propagate_acl); andre@984: } andre@984: andre@984: bool andre@984: port_isdir(const char *path) wilde@176: { wilde@176: int ret; wilde@176: #ifndef _WIN32 wilde@176: struct stat sb; wilde@176: ret = stat(path, &sb); wilde@176: #else wilde@176: struct _stat sb; wilde@176: ret = _stat(path, &sb); wilde@176: #endif wilde@176: wilde@176: if ((ret == 0) && S_ISDIR(sb.st_mode)) wilde@176: return true; wilde@176: else wilde@176: return false; wilde@176: } andre@1157: andre@1157: FILE* andre@1157: port_fopen_rb(const char *path, bool exclusive) andre@1157: { andre@1157: FILE *f = NULL; andre@1157: if (!path) andre@1157: { andre@1157: return NULL; andre@1157: } andre@1157: #ifdef WIN32 andre@1157: { andre@1157: wchar_t *wFilename = utf8_to_wchar(path, strlen(path)); andre@1157: if (!wFilename) andre@1157: { andre@1157: ERRORPRINTF ("Invalid encoding\n"); andre@1157: return NULL; andre@1157: } andre@1157: /* We open and write protect the file here so that andre@1157: as long as the file is open we can be sure that andre@1157: it was not modified and can use it in subsequent andre@1157: calls based on the filename. */ andre@1157: if (exclusive) andre@1157: { andre@1157: f = _wfsopen(wFilename, L"rb", _SH_DENYWR); andre@1157: } andre@1157: else andre@1157: { andre@1157: f = _wfopen(wFilename, L"rb"); andre@1157: } andre@1157: xfree(wFilename); andre@1157: if (f == NULL) andre@1157: { andre@1157: /* Fall back to local8 bit encoding */ andre@1157: if (exclusive) andre@1157: { andre@1157: f = _fsopen(path, "rb", _SH_DENYWR); andre@1157: } andre@1157: else andre@1157: { andre@1157: f = fopen(path, "rb"); andre@1157: } andre@1157: } andre@1157: } andre@1157: #else andre@1157: (void)(exclusive); andre@1157: f = fopen(path, "rb"); andre@1157: #endif andre@1157: return f; andre@1157: }