Added ios home and temp dir support.
This commit is contained in:
parent
dd9354d55f
commit
081b57905f
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
winpr_module_add(path.c shell.c)
|
winpr_module_add(path.c shell.c)
|
||||||
|
|
||||||
|
if (IOS)
|
||||||
|
winpr_module_add(shell_ios.m)
|
||||||
|
endif (IOS)
|
||||||
|
|
||||||
if(BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
endif()
|
endif()
|
||||||
|
@ -34,6 +34,10 @@
|
|||||||
|
|
||||||
#include <winpr/path.h>
|
#include <winpr/path.h>
|
||||||
|
|
||||||
|
#if defined(__IOS__)
|
||||||
|
#include "shell_ios.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
#include <Shlobj.h>
|
#include <Shlobj.h>
|
||||||
#else
|
#else
|
||||||
@ -57,14 +61,15 @@ static char* GetEnvAlloc(LPCSTR lpName)
|
|||||||
{
|
{
|
||||||
DWORD length;
|
DWORD length;
|
||||||
char* env = NULL;
|
char* env = NULL;
|
||||||
|
|
||||||
length = GetEnvironmentVariableA(lpName, NULL, 0);
|
length = GetEnvironmentVariableA(lpName, NULL, 0);
|
||||||
|
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
env = malloc(length + 1);
|
env = malloc(length + 1);
|
||||||
|
|
||||||
if (!env)
|
if (!env)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
GetEnvironmentVariableA(lpName, env, length + 1);
|
GetEnvironmentVariableA(lpName, env, length + 1);
|
||||||
env[length] = '\0';
|
env[length] = '\0';
|
||||||
}
|
}
|
||||||
@ -75,36 +80,36 @@ static char* GetEnvAlloc(LPCSTR lpName)
|
|||||||
static char* GetPath_HOME(void)
|
static char* GetPath_HOME(void)
|
||||||
{
|
{
|
||||||
char* path = NULL;
|
char* path = NULL;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
path = GetEnvAlloc("UserProfile");
|
path = GetEnvAlloc("UserProfile");
|
||||||
|
#elif defined(__IOS__)
|
||||||
|
path = ios_get_home();
|
||||||
#else
|
#else
|
||||||
path = GetEnvAlloc("HOME");
|
path = GetEnvAlloc("HOME");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* GetPath_TEMP(void)
|
static char* GetPath_TEMP(void)
|
||||||
{
|
{
|
||||||
char* path = NULL;
|
char* path = NULL;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
path = GetEnvAlloc("TEMP");
|
path = GetEnvAlloc("TEMP");
|
||||||
|
#elif defined(__IOS__)
|
||||||
|
path = ios_get_temp();
|
||||||
#else
|
#else
|
||||||
path = GetEnvAlloc("TMPDIR");
|
path = GetEnvAlloc("TMPDIR");
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
path = _strdup("/tmp");
|
path = _strdup("/tmp");
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* GetPath_XDG_DATA_HOME(void)
|
static char* GetPath_XDG_DATA_HOME(void)
|
||||||
{
|
{
|
||||||
char* path = NULL;
|
char* path = NULL;
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
path = GetPath_XDG_CONFIG_HOME();
|
path = GetPath_XDG_CONFIG_HOME();
|
||||||
#else
|
#else
|
||||||
@ -116,36 +121,36 @@ static char* GetPath_XDG_DATA_HOME(void)
|
|||||||
* $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored.
|
* $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored.
|
||||||
* If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
|
* If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
path = GetEnvAlloc("XDG_DATA_HOME");
|
path = GetEnvAlloc("XDG_DATA_HOME");
|
||||||
|
|
||||||
if (path)
|
if (path)
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
home = GetPath_HOME();
|
home = GetPath_HOME();
|
||||||
|
|
||||||
if (!home)
|
if (!home)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
path = (char*) malloc(strlen(home) + strlen("/.local/share") + 1);
|
path = (char*) malloc(strlen(home) + strlen("/.local/share") + 1);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
{
|
{
|
||||||
free(home);
|
free(home);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sprintf(path, "%s%s", home, "/.local/share");
|
|
||||||
|
|
||||||
|
sprintf(path, "%s%s", home, "/.local/share");
|
||||||
free(home);
|
free(home);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* GetPath_XDG_CONFIG_HOME(void)
|
static char* GetPath_XDG_CONFIG_HOME(void)
|
||||||
{
|
{
|
||||||
char* path = NULL;
|
char* path = NULL;
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(_UWP)
|
#if defined(WIN32) && !defined(_UWP)
|
||||||
path = calloc(MAX_PATH, sizeof(char));
|
path = calloc(MAX_PATH, sizeof(char));
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -154,6 +159,9 @@ static char* GetPath_XDG_CONFIG_HOME(void)
|
|||||||
free(path);
|
free(path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(__IOS__)
|
||||||
|
path = GetCombinedPath(GetPath_HOME(), ".freerdp");
|
||||||
#else
|
#else
|
||||||
char* home = NULL;
|
char* home = NULL;
|
||||||
/**
|
/**
|
||||||
@ -163,7 +171,6 @@ static char* GetPath_XDG_CONFIG_HOME(void)
|
|||||||
* $XDG_CONFIG_HOME defines the base directory relative to which user specific configuration files should be stored.
|
* $XDG_CONFIG_HOME defines the base directory relative to which user specific configuration files should be stored.
|
||||||
* If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used.
|
* If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
path = GetEnvAlloc("XDG_CONFIG_HOME");
|
path = GetEnvAlloc("XDG_CONFIG_HOME");
|
||||||
|
|
||||||
if (path)
|
if (path)
|
||||||
@ -178,16 +185,16 @@ static char* GetPath_XDG_CONFIG_HOME(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
path = (char*) malloc(strlen(home) + strlen("/.config") + 1);
|
path = (char*) malloc(strlen(home) + strlen("/.config") + 1);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
{
|
{
|
||||||
free(home);
|
free(home);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sprintf(path, "%s%s", home, "/.config");
|
|
||||||
|
|
||||||
|
sprintf(path, "%s%s", home, "/.config");
|
||||||
free(home);
|
free(home);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,16 +202,18 @@ static char* GetPath_XDG_CACHE_HOME(void)
|
|||||||
{
|
{
|
||||||
char* path = NULL;
|
char* path = NULL;
|
||||||
char* home = NULL;
|
char* home = NULL;
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
home = GetPath_XDG_RUNTIME_DIR();
|
home = GetPath_XDG_RUNTIME_DIR();
|
||||||
|
|
||||||
if (home)
|
if (home)
|
||||||
{
|
{
|
||||||
path = GetCombinedPath(home, "cache");
|
path = GetCombinedPath(home, "cache");
|
||||||
|
|
||||||
if (!PathFileExistsA(path))
|
if (!PathFileExistsA(path))
|
||||||
if (!CreateDirectoryA(path, NULL))
|
if (!CreateDirectoryA(path, NULL))
|
||||||
path = NULL;
|
path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(home);
|
free(home);
|
||||||
#else
|
#else
|
||||||
/**
|
/**
|
||||||
@ -214,44 +223,46 @@ static char* GetPath_XDG_CACHE_HOME(void)
|
|||||||
* $XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data files should be stored.
|
* $XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data files should be stored.
|
||||||
* If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache should be used.
|
* If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache should be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
path = GetEnvAlloc("XDG_CACHE_HOME");
|
path = GetEnvAlloc("XDG_CACHE_HOME");
|
||||||
|
|
||||||
if (path)
|
if (path)
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
home = GetPath_HOME();
|
home = GetPath_HOME();
|
||||||
|
|
||||||
if (!home)
|
if (!home)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
path = (char*) malloc(strlen(home) + strlen("/.cache") + 1);
|
path = (char*) malloc(strlen(home) + strlen("/.cache") + 1);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
{
|
{
|
||||||
free(home);
|
free(home);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sprintf(path, "%s%s", home, "/.cache");
|
|
||||||
|
|
||||||
|
sprintf(path, "%s%s", home, "/.cache");
|
||||||
free(home);
|
free(home);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* GetPath_XDG_RUNTIME_DIR(void)
|
char* GetPath_XDG_RUNTIME_DIR(void)
|
||||||
{
|
{
|
||||||
char* path = NULL;
|
char* path = NULL;
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(_UWP)
|
#if defined(WIN32) && !defined(_UWP)
|
||||||
path = calloc(MAX_PATH, sizeof(char));
|
path = calloc(MAX_PATH, sizeof(char));
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (FAILED(SHGetFolderPathA(0, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)))
|
if (FAILED(SHGetFolderPathA(0, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
|
||||||
|
path)))
|
||||||
{
|
{
|
||||||
free(path);
|
free(path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/**
|
/**
|
||||||
* There is a single base directory relative to which user-specific runtime files and other file objects should be placed.
|
* There is a single base directory relative to which user-specific runtime files and other file objects should be placed.
|
||||||
@ -279,7 +290,6 @@ char* GetPath_XDG_RUNTIME_DIR(void)
|
|||||||
* print a warning message. Applications should use this directory for communication and synchronization purposes and
|
* print a warning message. Applications should use this directory for communication and synchronization purposes and
|
||||||
* should not place larger files in it, since it might reside in runtime memory and cannot necessarily be swapped out to disk.
|
* should not place larger files in it, since it might reside in runtime memory and cannot necessarily be swapped out to disk.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
path = GetEnvAlloc("XDG_RUNTIME_DIR");
|
path = GetEnvAlloc("XDG_RUNTIME_DIR");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -287,7 +297,6 @@ char* GetPath_XDG_RUNTIME_DIR(void)
|
|||||||
return path;
|
return path;
|
||||||
|
|
||||||
path = GetPath_TEMP();
|
path = GetPath_TEMP();
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +312,6 @@ char* GetKnownPath(int id)
|
|||||||
|
|
||||||
case KNOWN_PATH_TEMP:
|
case KNOWN_PATH_TEMP:
|
||||||
path = GetPath_TEMP();
|
path = GetPath_TEMP();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KNOWN_PATH_XDG_DATA_HOME:
|
case KNOWN_PATH_XDG_DATA_HOME:
|
||||||
@ -334,14 +342,13 @@ char* GetKnownSubPath(int id, const char* path)
|
|||||||
{
|
{
|
||||||
char* subPath;
|
char* subPath;
|
||||||
char* knownPath;
|
char* knownPath;
|
||||||
|
|
||||||
knownPath = GetKnownPath(id);
|
knownPath = GetKnownPath(id);
|
||||||
|
|
||||||
if (!knownPath)
|
if (!knownPath)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
subPath = GetCombinedPath(knownPath, path);
|
subPath = GetCombinedPath(knownPath, path);
|
||||||
|
|
||||||
free(knownPath);
|
free(knownPath);
|
||||||
|
|
||||||
return subPath;
|
return subPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,14 +356,15 @@ char* GetEnvironmentPath(char* name)
|
|||||||
{
|
{
|
||||||
char* env = NULL;
|
char* env = NULL;
|
||||||
DWORD nSize;
|
DWORD nSize;
|
||||||
|
|
||||||
nSize = GetEnvironmentVariableA(name, NULL, 0);
|
nSize = GetEnvironmentVariableA(name, NULL, 0);
|
||||||
|
|
||||||
if (nSize)
|
if (nSize)
|
||||||
{
|
{
|
||||||
env = (LPSTR) malloc(nSize);
|
env = (LPSTR) malloc(nSize);
|
||||||
|
|
||||||
if (!env)
|
if (!env)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
nSize = GetEnvironmentVariableA(name, env, nSize);
|
nSize = GetEnvironmentVariableA(name, env, nSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,16 +375,13 @@ char* GetEnvironmentSubPath(char* name, const char* path)
|
|||||||
{
|
{
|
||||||
char* env;
|
char* env;
|
||||||
char* subpath;
|
char* subpath;
|
||||||
|
|
||||||
env = GetEnvironmentPath(name);
|
env = GetEnvironmentPath(name);
|
||||||
|
|
||||||
if (!env)
|
if (!env)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
subpath = GetCombinedPath(env, path);
|
subpath = GetCombinedPath(env, path);
|
||||||
|
|
||||||
free(env);
|
free(env);
|
||||||
|
|
||||||
return subpath;
|
return subpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,16 +396,19 @@ char* GetCombinedPath(const char* basePath, const char* subPath)
|
|||||||
|
|
||||||
if (basePath)
|
if (basePath)
|
||||||
basePathLength = (int) strlen(basePath);
|
basePathLength = (int) strlen(basePath);
|
||||||
|
|
||||||
if (subPath)
|
if (subPath)
|
||||||
subPathLength = (int) strlen(subPath);
|
subPathLength = (int) strlen(subPath);
|
||||||
|
|
||||||
length = basePathLength + subPathLength + 1;
|
length = basePathLength + subPathLength + 1;
|
||||||
path = (char*) malloc(length + 1);
|
path = (char*) malloc(length + 1);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (basePath)
|
if (basePath)
|
||||||
CopyMemory(path, basePath, basePathLength);
|
CopyMemory(path, basePath, basePathLength);
|
||||||
|
|
||||||
path[basePathLength] = '\0';
|
path[basePathLength] = '\0';
|
||||||
|
|
||||||
if (FAILED(PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE)))
|
if (FAILED(PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE)))
|
||||||
@ -413,11 +421,13 @@ char* GetCombinedPath(const char* basePath, const char* subPath)
|
|||||||
return path;
|
return path;
|
||||||
|
|
||||||
subPathCpy = _strdup(subPath);
|
subPathCpy = _strdup(subPath);
|
||||||
|
|
||||||
if (!subPathCpy)
|
if (!subPathCpy)
|
||||||
{
|
{
|
||||||
free(path);
|
free(path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE)))
|
if (FAILED(PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE)))
|
||||||
{
|
{
|
||||||
free(path);
|
free(path);
|
||||||
@ -426,7 +436,6 @@ char* GetCombinedPath(const char* basePath, const char* subPath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = NativePathCchAppendA(path, length + 1, subPathCpy);
|
status = NativePathCchAppendA(path, length + 1, subPathCpy);
|
||||||
|
|
||||||
free(subPathCpy);
|
free(subPathCpy);
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
@ -457,11 +466,12 @@ BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
|
|||||||
for (p = dup; p;)
|
for (p = dup; p;)
|
||||||
{
|
{
|
||||||
if ((p = strchr(p + 1, delim)))
|
if ((p = strchr(p + 1, delim)))
|
||||||
*p = '\0';
|
* p = '\0';
|
||||||
|
|
||||||
if (mkdir(dup, 0777) != 0)
|
if (mkdir(dup, 0777) != 0)
|
||||||
if (errno != EEXIST)
|
if (errno != EEXIST)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
*p = delim;
|
*p = delim;
|
||||||
}
|
}
|
||||||
|
8
winpr/libwinpr/path/shell_ios.h
Normal file
8
winpr/libwinpr/path/shell_ios.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef SHELL_IOS_H_
|
||||||
|
#define SHELL_IOS_H_
|
||||||
|
|
||||||
|
char* ios_get_home(void);
|
||||||
|
char* ios_get_temp(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
40
winpr/libwinpr/path/shell_ios.m
Normal file
40
winpr/libwinpr/path/shell_ios.m
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* WinPR: Windows Portable Runtime
|
||||||
|
* Path Functions
|
||||||
|
*
|
||||||
|
* Copyright 2016 Armin Novak <armin.novak@thincast.om>
|
||||||
|
* Copyright 2016 Thincast Technologies GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "shell_ios.h"
|
||||||
|
|
||||||
|
char* ios_get_home(void)
|
||||||
|
{
|
||||||
|
NSString* home_path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
|
||||||
|
NSUserDomainMask, YES) lastObject];
|
||||||
|
return strdup([home_path UTF8String]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ios_get_temp(void)
|
||||||
|
{
|
||||||
|
NSString* tmp_path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"freerdp"];
|
||||||
|
return strdup([tmp_path UTF8String]);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user