diff options
Diffstat (limited to 'common/userpref.c')
| -rw-r--r-- | common/userpref.c | 105 |
1 files changed, 76 insertions, 29 deletions
diff --git a/common/userpref.c b/common/userpref.c index d363b0e..ab3a3cf 100644 --- a/common/userpref.c +++ b/common/userpref.c | |||
| @@ -26,6 +26,9 @@ | |||
| 26 | #include <stdint.h> | 26 | #include <stdint.h> |
| 27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
| 28 | #include <string.h> | 28 | #include <string.h> |
| 29 | #include <sys/types.h> | ||
| 30 | #include <pwd.h> | ||
| 31 | #include <unistd.h> | ||
| 29 | #ifdef HAVE_OPENSSL | 32 | #ifdef HAVE_OPENSSL |
| 30 | #include <openssl/pem.h> | 33 | #include <openssl/pem.h> |
| 31 | #include <openssl/rsa.h> | 34 | #include <openssl/rsa.h> |
| @@ -48,6 +51,7 @@ | |||
| 48 | 51 | ||
| 49 | #include "userpref.h" | 52 | #include "userpref.h" |
| 50 | #include "debug.h" | 53 | #include "debug.h" |
| 54 | #include "utils.h" | ||
| 51 | 55 | ||
| 52 | #define LIBIMOBILEDEVICE_CONF_DIR "libimobiledevice" | 56 | #define LIBIMOBILEDEVICE_CONF_DIR "libimobiledevice" |
| 53 | #define LIBIMOBILEDEVICE_CONF_FILE "libimobiledevicerc" | 57 | #define LIBIMOBILEDEVICE_CONF_FILE "libimobiledevicerc" |
| @@ -65,7 +69,7 @@ | |||
| 65 | #define DIR_SEP_S "/" | 69 | #define DIR_SEP_S "/" |
| 66 | #endif | 70 | #endif |
| 67 | 71 | ||
| 68 | static char __config_dir[512] = {0, }; | 72 | static char *__config_dir = NULL; |
| 69 | 73 | ||
| 70 | #ifdef WIN32 | 74 | #ifdef WIN32 |
| 71 | static char *userpref_utf16_to_utf8(wchar_t *unistr, long len, long *items_read, long *items_written) | 75 | static char *userpref_utf16_to_utf8(wchar_t *unistr, long len, long *items_read, long *items_written) |
| @@ -103,24 +107,60 @@ static char *userpref_utf16_to_utf8(wchar_t *unistr, long len, long *items_read, | |||
| 103 | #endif | 107 | #endif |
| 104 | 108 | ||
| 105 | #ifndef WIN32 | 109 | #ifndef WIN32 |
| 106 | static const char *userpref_get_tmp_dir() | 110 | static char *get_home_dir_from_system(void) |
| 107 | { | 111 | { |
| 108 | const char *cdir = getenv("TMPDIR"); | 112 | long bufsize; |
| 109 | if (cdir && cdir[0]) | 113 | char *buf; |
| 110 | return cdir; | 114 | int error; |
| 111 | cdir = getenv("TMP"); | 115 | struct passwd pwd; |
| 112 | if (cdir && cdir[0]) | 116 | struct passwd *ppwd; |
| 113 | return cdir; | 117 | char *result = NULL; |
| 114 | cdir = getenv("TEMP"); | 118 | |
| 115 | if (cdir && cdir[0]) | 119 | bufsize = sysconf (_SC_GETPW_R_SIZE_MAX); |
| 116 | return cdir; | 120 | |
| 117 | return "/tmp"; | 121 | if (bufsize < 0) |
| 122 | bufsize = 1024; | ||
| 123 | |||
| 124 | buf = NULL; | ||
| 125 | |||
| 126 | do { | ||
| 127 | free (buf); | ||
| 128 | buf = malloc (bufsize); | ||
| 129 | if (!buf) | ||
| 130 | return NULL; | ||
| 131 | |||
| 132 | errno = 0; | ||
| 133 | error = getpwuid_r (getuid (), &pwd, buf, bufsize, &ppwd); | ||
| 134 | |||
| 135 | error = (error < 0) ? errno : error; | ||
| 136 | |||
| 137 | if (!ppwd) { | ||
| 138 | if (error == 0 || error == ENOENT) | ||
| 139 | break; | ||
| 140 | else if (bufsize > 32 * 1024) | ||
| 141 | break; /* Unreasonable size; let's bail out */ | ||
| 142 | |||
| 143 | bufsize *= 2; | ||
| 144 | } | ||
| 145 | } while (!ppwd); | ||
| 146 | |||
| 147 | if (ppwd && ppwd->pw_dir) | ||
| 148 | result = strdup (ppwd->pw_dir); | ||
| 149 | |||
| 150 | free (buf); | ||
| 151 | |||
| 152 | return result; | ||
| 118 | } | 153 | } |
| 119 | #endif | 154 | #endif |
| 120 | 155 | ||
| 121 | static const char *userpref_get_config_dir() | 156 | static const char *userpref_get_config_dir() |
| 122 | { | 157 | { |
| 123 | if (__config_dir[0]) return __config_dir; | 158 | char *base_config_dir; |
| 159 | int use_dot_config; | ||
| 160 | |||
| 161 | if (__config_dir) | ||
| 162 | return __config_dir; | ||
| 163 | |||
| 124 | #ifdef WIN32 | 164 | #ifdef WIN32 |
| 125 | wchar_t path[MAX_PATH+1]; | 165 | wchar_t path[MAX_PATH+1]; |
| 126 | HRESULT hr; | 166 | HRESULT hr; |
| @@ -131,38 +171,45 @@ static const char *userpref_get_config_dir() | |||
| 131 | if (hr == S_OK) { | 171 | if (hr == S_OK) { |
| 132 | b = SHGetPathFromIDListW (pidl, path); | 172 | b = SHGetPathFromIDListW (pidl, path); |
| 133 | if (b) { | 173 | if (b) { |
| 134 | char *cdir = userpref_utf16_to_utf8 (path, wcslen(path), NULL, NULL); | 174 | base_config_dir = userpref_utf16_to_utf8 (path, wcslen(path), NULL, NULL); |
| 135 | strcpy(__config_dir, cdir); | ||
| 136 | free(cdir); | ||
| 137 | CoTaskMemFree (pidl); | 175 | CoTaskMemFree (pidl); |
| 138 | } | 176 | } |
| 139 | } | 177 | } |
| 178 | |||
| 179 | use_dot_config = 0; | ||
| 140 | #else | 180 | #else |
| 141 | const char *cdir = getenv("XDG_CONFIG_HOME"); | 181 | const char *cdir = getenv("XDG_CONFIG_HOME"); |
| 142 | if (!cdir) { | 182 | if (!cdir) { |
| 143 | cdir = getenv("HOME"); | 183 | cdir = getenv("HOME"); |
| 144 | if (!cdir || !cdir[0]) { | 184 | if (!cdir || !cdir[0]) { |
| 145 | const char *tdir = userpref_get_tmp_dir(); | 185 | base_config_dir = get_home_dir_from_system(); |
| 146 | strcpy(__config_dir, tdir); | 186 | if (!base_config_dir) |
| 147 | strcat(__config_dir, DIR_SEP_S); | 187 | return NULL; |
| 148 | strcat(__config_dir, "root"); | ||
| 149 | } else { | 188 | } else { |
| 150 | strcpy(__config_dir, cdir); | 189 | base_config_dir = strdup(cdir); |
| 151 | } | 190 | } |
| 152 | strcat(__config_dir, DIR_SEP_S); | 191 | |
| 153 | strcat(__config_dir, ".config"); | 192 | use_dot_config = 1; |
| 154 | } else { | 193 | } else { |
| 155 | strcpy(__config_dir, cdir); | 194 | base_config_dir = strdup(cdir); |
| 195 | use_dot_config = 0; | ||
| 156 | } | 196 | } |
| 157 | #endif | 197 | #endif |
| 158 | strcat(__config_dir, DIR_SEP_S); | ||
| 159 | strcat(__config_dir, LIBIMOBILEDEVICE_CONF_DIR); | ||
| 160 | 198 | ||
| 161 | int i = strlen(__config_dir)-1; | 199 | if (use_dot_config) |
| 162 | while ((i > 0) && (__config_dir[i] == DIR_SEP)) { | 200 | __config_dir = string_concat(base_config_dir, DIR_SEP_S, ".config", DIR_SEP_S, LIBIMOBILEDEVICE_CONF_DIR); |
| 163 | __config_dir[i--] = '\0'; | 201 | else |
| 202 | __config_dir = string_concat(base_config_dir, DIR_SEP_S, LIBIMOBILEDEVICE_CONF_DIR); | ||
| 203 | |||
| 204 | if (__config_dir) { | ||
| 205 | int i = strlen(__config_dir)-1; | ||
| 206 | while ((i > 0) && (__config_dir[i] == DIR_SEP)) { | ||
| 207 | __config_dir[i--] = '\0'; | ||
| 208 | } | ||
| 164 | } | 209 | } |
| 165 | 210 | ||
| 211 | free(base_config_dir); | ||
| 212 | |||
| 166 | return __config_dir; | 213 | return __config_dir; |
| 167 | } | 214 | } |
| 168 | 215 | ||
