Added ios home and temp dir support.

This commit is contained in:
Armin Novak 2016-08-05 12:05:08 +02:00 committed by Armin Novak
parent dd9354d55f
commit 081b57905f
4 changed files with 93 additions and 31 deletions

View File

@ -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()

View File

@ -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;
} }

View File

@ -0,0 +1,8 @@
#ifndef SHELL_IOS_H_
#define SHELL_IOS_H_
char* ios_get_home(void);
char* ios_get_temp(void);
#endif

View 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]);
}