| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bke | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Access to application level directories. | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | #include "BLI_fileops.h"
 | 
					
						
							| 
									
										
										
										
											2018-08-28 15:12:14 +02:00
										 |  |  | #include "BLI_fileops_types.h"
 | 
					
						
							|  |  |  | #include "BLI_listbase.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #include "BLI_path_util.h"
 | 
					
						
							| 
									
										
										
										
											2018-08-28 15:12:14 +02:00
										 |  |  | #include "BLI_string.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | #include "BKE_blender_version.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #include "BKE_appdir.h"  /* own include */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "GHOST_Path-api.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | #include "CLG_log.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  | #  include "utf_winfunc.h"
 | 
					
						
							|  |  |  | #  include "utfconv.h"
 | 
					
						
							|  |  |  | #  include <io.h>
 | 
					
						
							|  |  |  | #  ifdef _WIN32_IE
 | 
					
						
							|  |  |  | #    undef _WIN32_IE
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | #  define _WIN32_IE 0x0501
 | 
					
						
							|  |  |  | #  include <windows.h>
 | 
					
						
							|  |  |  | #  include <shlobj.h>
 | 
					
						
							|  |  |  | #  include "BLI_winstuff.h"
 | 
					
						
							|  |  |  | #else /* non windows */
 | 
					
						
							|  |  |  | #  ifdef WITH_BINRELOC
 | 
					
						
							|  |  |  | #    include "binreloc.h"
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | #  include <unistd.h>  /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
 | 
					
						
							|  |  |  | #endif /* WIN32 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* local */ | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | static CLG_LogRef LOG = {"bke.appdir"}; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | static char bprogname[FILE_MAX];    /* full path to program executable */ | 
					
						
							|  |  |  | static char bprogdir[FILE_MAX];     /* full path to directory in which executable is located */ | 
					
						
							|  |  |  | static char btempdir_base[FILE_MAX];          /* persistent temporary directory */ | 
					
						
							|  |  |  | static char btempdir_session[FILE_MAX] = "";  /* volatile temporary directory */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This is now only used to really get the user's default document folder */ | 
					
						
							|  |  |  | /* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used
 | 
					
						
							|  |  |  |  * as default location to save documents */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | const char *BKE_appdir_folder_default(void) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #ifndef WIN32
 | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 	const char * const xdg_documents_dir = BLI_getenv("XDG_DOCUMENTS_DIR"); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (xdg_documents_dir) | 
					
						
							|  |  |  | 		return xdg_documents_dir; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 	return BLI_getenv("HOME"); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #else /* Windows */
 | 
					
						
							|  |  |  | 	static char documentfolder[MAXPATHLEN]; | 
					
						
							|  |  |  | 	HRESULT hResult; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Check for %HOME% env var */ | 
					
						
							|  |  |  | 	if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) { | 
					
						
							|  |  |  | 		if (BLI_is_dir(documentfolder)) return documentfolder; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	/* add user profile support for WIN 2K / NT.
 | 
					
						
							|  |  |  | 	 * This is %APPDATA%, which translates to either | 
					
						
							|  |  |  | 	 * %USERPROFILE%\Application Data or since Vista | 
					
						
							|  |  |  | 	 * to %USERPROFILE%\AppData\Roaming | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (hResult == S_OK) { | 
					
						
							|  |  |  | 		if (BLI_is_dir(documentfolder)) return documentfolder; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	return NULL; | 
					
						
							|  |  |  | #endif /* WIN32 */
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // #define PATH_DEBUG
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* returns a formatted representation of the specified version number. Non-reentrant! */ | 
					
						
							|  |  |  | static char *blender_version_decimal(const int ver) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static char version_str[5]; | 
					
						
							| 
									
										
										
										
											2017-08-11 08:56:57 +10:00
										 |  |  | 	BLI_assert(ver < 1000); | 
					
						
							| 
									
										
										
										
											2017-08-12 13:37:34 +10:00
										 |  |  | 	BLI_snprintf(version_str, sizeof(version_str), "%d.%02d", ver / 100, ver % 100); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	return version_str; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath, | 
					
						
							|  |  |  |  * returning true if result points to a directory. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | static bool test_path( | 
					
						
							|  |  |  |         char *targetpath, size_t targetpath_len, | 
					
						
							|  |  |  |         const char *path_base, const char *path_sep, const char *folder_name) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	char tmppath[FILE_MAX]; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 	if (path_sep) { | 
					
						
							|  |  |  | 		BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		BLI_strncpy(tmppath, path_base, sizeof(tmppath)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-15 14:10:42 +11:00
										 |  |  | 	/* rare cases folder_name is omitted (when looking for ~/.config/blender/2.xx dir only) */ | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 	if (folder_name) { | 
					
						
							|  |  |  | 		BLI_join_dirfile(targetpath, targetpath_len, tmppath, folder_name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		BLI_strncpy(targetpath, tmppath, targetpath_len); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	/* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
 | 
					
						
							|  |  |  | 	 * if folder_name is specified but not otherwise? */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (BLI_is_dir(targetpath)) { | 
					
						
							|  |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | 		printf("\t%s found: %s\n", __func__, targetpath); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | 		printf("\t%s missing: %s\n", __func__, targetpath); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		//targetpath[0] = '\0';
 | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Puts the value of the specified environment variable into *path if it exists | 
					
						
							|  |  |  |  * and points at a directory. Returns true if this was done. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static bool test_env_path(char *path, const char *envvar) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 	const char *env = envvar ? BLI_getenv(envvar) : NULL; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (!env) return false; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (BLI_is_dir(env)) { | 
					
						
							|  |  |  | 		BLI_strncpy(path, env, FILE_MAX); | 
					
						
							|  |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | 		printf("\t%s env %s found: %s\n", __func__, envvar, env); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		path[0] = '\0'; | 
					
						
							|  |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | 		printf("\t%s env %s missing: %s\n", __func__, envvar, env); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Constructs in \a targetpath the name of a directory relative to a version-specific | 
					
						
							|  |  |  |  * subdirectory in the parent directory of the Blender executable. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param targetpath: String to return path | 
					
						
							|  |  |  |  * \param folder_name: Optional folder name within version-specific directory | 
					
						
							|  |  |  |  * \param subfolder_name: Optional subfolder name within folder_name | 
					
						
							|  |  |  |  * \param ver: To construct name of version-specific directory within bprogdir | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  * \return true if such a directory exists. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | static bool get_path_local( | 
					
						
							|  |  |  |         char *targetpath, size_t targetpath_len, | 
					
						
							|  |  |  |         const char *folder_name, const char *subfolder_name, const int ver) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	char relfolder[FILE_MAX]; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | 	printf("%s...\n", __func__); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (folder_name) { | 
					
						
							|  |  |  | 		if (subfolder_name) { | 
					
						
							|  |  |  | 			BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		relfolder[0] = '\0'; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ | 
					
						
							|  |  |  | #ifdef __APPLE__
 | 
					
						
							| 
									
										
										
										
											2017-03-24 10:11:01 +11:00
										 |  |  | 	/* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */ | 
					
						
							| 
									
										
										
										
											2017-08-11 08:48:15 +10:00
										 |  |  | 	char osx_resourses[FILE_MAX]; | 
					
						
							|  |  |  | 	BLI_snprintf(osx_resourses, sizeof(osx_resourses), "%s../Resources", bprogdir); | 
					
						
							| 
									
										
										
										
											2017-08-11 08:42:27 +10:00
										 |  |  | 	/* Remove the '/../' added above. */ | 
					
						
							|  |  |  | 	BLI_cleanup_path(NULL, osx_resourses); | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 	return test_path(targetpath, targetpath_len, osx_resourses, blender_version_decimal(ver), relfolder); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 	return test_path(targetpath, targetpath_len, bprogdir, blender_version_decimal(ver), relfolder); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Is this an install with user files kept together with the Blender executable and its | 
					
						
							|  |  |  |  * installation files. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 20:55:36 +01:00
										 |  |  | bool BKE_appdir_app_is_portable_install(void) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* detect portable install by the existence of config folder */ | 
					
						
							|  |  |  | 	const int ver = BLENDER_VERSION; | 
					
						
							|  |  |  | 	char path[FILE_MAX]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 	return get_path_local(path, sizeof(path), "config", NULL, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the path of a folder from environment variables | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \param targetpath: String to return path. | 
					
						
							|  |  |  |  * \param subfolder_name: optional name of subfolder within folder. | 
					
						
							|  |  |  |  * \param envvar: name of environment variable to check folder_name. | 
					
						
							| 
									
										
										
										
											2019-03-20 15:17:32 +11:00
										 |  |  |  * \return true if it was able to construct such a path and the path exists. | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  |  */ | 
					
						
							|  |  |  | static bool get_path_environment( | 
					
						
							|  |  |  |         char *targetpath, | 
					
						
							|  |  |  |         size_t targetpath_len, | 
					
						
							|  |  |  |         const char *subfolder_name, | 
					
						
							|  |  |  |         const char *envvar) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char user_path[FILE_MAX]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (test_env_path(user_path, envvar)) { | 
					
						
							|  |  |  | 		if (subfolder_name) { | 
					
						
							|  |  |  | 			return test_path( | 
					
						
							|  |  |  | 			        targetpath, | 
					
						
							|  |  |  | 			        targetpath_len, | 
					
						
							|  |  |  | 			        user_path, | 
					
						
							|  |  |  | 			        NULL, | 
					
						
							|  |  |  | 			        subfolder_name); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BLI_strncpy(targetpath, user_path, FILE_MAX); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-20 15:17:32 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the path of a folder from environment variables | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \param targetpath: String to return path. | 
					
						
							|  |  |  |  * \param subfolder_name: optional name of subfolder within folder. | 
					
						
							|  |  |  |  * \param envvar: name of environment variable to check folder_name. | 
					
						
							|  |  |  |  * \return true if it was able to construct such a path. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static bool get_path_environment_notest( | 
					
						
							|  |  |  |         char *targetpath, | 
					
						
							|  |  |  |         size_t targetpath_len, | 
					
						
							|  |  |  |         const char *subfolder_name, | 
					
						
							|  |  |  |         const char *envvar) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char user_path[FILE_MAX]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (test_env_path(user_path, envvar)) { | 
					
						
							|  |  |  | 		if (subfolder_name) { | 
					
						
							|  |  |  | 			BLI_join_dirfile(targetpath, targetpath_len, user_path, subfolder_name); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BLI_strncpy(targetpath, user_path, FILE_MAX); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the path of a folder within the user-files area. | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param targetpath: String to return path | 
					
						
							|  |  |  |  * \param folder_name: default name of folder within user area | 
					
						
							|  |  |  |  * \param subfolder_name: optional name of subfolder within folder | 
					
						
							| 
									
										
										
										
											2019-03-19 15:17:46 +11:00
										 |  |  |  * \param ver: Blender version, used to construct a subdirectory name | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  * \return true if it was able to construct such a path. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-03-24 10:11:01 +11:00
										 |  |  | static bool get_path_user( | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  |         char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name, | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  |         const int ver) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	char user_path[FILE_MAX]; | 
					
						
							|  |  |  | 	const char *user_base_path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* for portable install, user path is always local */ | 
					
						
							| 
									
										
										
										
											2018-12-03 20:55:36 +01:00
										 |  |  | 	if (BKE_appdir_app_is_portable_install()) { | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 		return get_path_local(targetpath, targetpath_len, folder_name, subfolder_name, ver); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	user_path[0] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver)); | 
					
						
							|  |  |  | 	if (user_base_path) | 
					
						
							|  |  |  | 		BLI_strncpy(user_path, user_base_path, FILE_MAX); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!user_path[0]) | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | 	printf("%s: %s\n", __func__, user_path); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (subfolder_name) { | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 		return test_path(targetpath, targetpath_len, user_path, folder_name, subfolder_name); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 		return test_path(targetpath, targetpath_len, user_path, NULL, folder_name); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the path of a folder within the Blender installation directory. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param targetpath: String to return path | 
					
						
							|  |  |  |  * \param folder_name: default name of folder within installation area | 
					
						
							|  |  |  |  * \param subfolder_name: optional name of subfolder within folder | 
					
						
							|  |  |  |  * \param ver: Blender version, used to construct a subdirectory name | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  * \return  true if it was able to construct such a path. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-03-24 10:11:01 +11:00
										 |  |  | static bool get_path_system( | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  |         char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name, | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  |         const int ver) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	char system_path[FILE_MAX]; | 
					
						
							|  |  |  | 	const char *system_base_path; | 
					
						
							|  |  |  | 	char relfolder[FILE_MAX]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (folder_name) { | 
					
						
							|  |  |  | 		if (subfolder_name) { | 
					
						
							|  |  |  | 			BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		relfolder[0] = '\0'; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	system_path[0] = '\0'; | 
					
						
							| 
									
										
										
										
											2018-04-25 12:48:51 +02:00
										 |  |  | 	system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver)); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (system_base_path) | 
					
						
							|  |  |  | 		BLI_strncpy(system_path, system_base_path, FILE_MAX); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (!system_path[0]) | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | 	printf("%s: %s\n", __func__, system_path); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (subfolder_name) { | 
					
						
							|  |  |  | 		/* try $BLENDERPATH/folder_name/subfolder_name */ | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 		return test_path(targetpath, targetpath_len, system_path, folder_name, subfolder_name); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* try $BLENDERPATH/folder_name */ | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 		return test_path(targetpath, targetpath_len, system_path, NULL, folder_name); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Get a folder out of the 'folder_id' presets for paths. | 
					
						
							|  |  |  |  * returns the path if found, NULL string if not | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \param subfolder: The name of a directory to check for, | 
					
						
							|  |  |  |  * this may contain path separators but must resolve to a directory, checked with #BLI_is_dir. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const char *BKE_appdir_folder_id_ex( | 
					
						
							|  |  |  |         const int folder_id, const char *subfolder, | 
					
						
							|  |  |  |         char *path, size_t path_len) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	const int ver = BLENDER_VERSION; | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	switch (folder_id) { | 
					
						
							|  |  |  | 		case BLENDER_DATAFILES:     /* general case */ | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_USER_DATAFILES")) break; | 
					
						
							|  |  |  | 			if (get_path_user(path, path_len, "datafiles", subfolder, ver)) break; | 
					
						
							|  |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_SYSTEM_DATAFILES")) break; | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 			if (get_path_local(path, path_len, "datafiles", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_system(path, path_len, "datafiles", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		case BLENDER_USER_DATAFILES: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_USER_DATAFILES")) break; | 
					
						
							|  |  |  | 			if (get_path_user(path, path_len, "datafiles", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		case BLENDER_SYSTEM_DATAFILES: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_SYSTEM_DATAFILES")) break; | 
					
						
							|  |  |  | 			if (get_path_system(path, path_len, "datafiles", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 			if (get_path_local(path, path_len, "datafiles", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		case BLENDER_USER_AUTOSAVE: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_USER_DATAFILES")) break; | 
					
						
							|  |  |  | 			if (get_path_user(path, path_len, "autosave", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case BLENDER_USER_CONFIG: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_USER_CONFIG")) break; | 
					
						
							|  |  |  | 			if (get_path_user(path, path_len, "config", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		case BLENDER_USER_SCRIPTS: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_USER_SCRIPTS")) break; | 
					
						
							|  |  |  | 			if (get_path_user(path, path_len, "scripts", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		case BLENDER_SYSTEM_SCRIPTS: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_SYSTEM_SCRIPTS")) break; | 
					
						
							|  |  |  | 			if (get_path_system(path, path_len, "scripts", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 			if (get_path_local(path, path_len, "scripts", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		case BLENDER_SYSTEM_PYTHON: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			if (get_path_environment(path, path_len, subfolder, "BLENDER_SYSTEM_PYTHON")) break; | 
					
						
							|  |  |  | 			if (get_path_system(path, path_len, "python", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 			if (get_path_local(path, path_len, "python", subfolder, ver)) break; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			BLI_assert(0); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	return path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | const char *BKE_appdir_folder_id( | 
					
						
							|  |  |  |         const int folder_id, const char *subfolder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static char path[FILE_MAX] = ""; | 
					
						
							|  |  |  | 	return BKE_appdir_folder_id_ex(folder_id, subfolder, path, sizeof(path)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the path to a folder in the user area without checking that it actually exists first. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	const int ver = BLENDER_VERSION; | 
					
						
							|  |  |  | 	static char path[FILE_MAX] = ""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (folder_id) { | 
					
						
							|  |  |  | 		case BLENDER_USER_DATAFILES: | 
					
						
							| 
									
										
										
										
											2019-03-20 15:17:32 +11:00
										 |  |  | 			if (get_path_environment_notest(path, sizeof(path), subfolder, "BLENDER_USER_DATAFILES")) break; | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			get_path_user(path, sizeof(path), "datafiles", subfolder, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case BLENDER_USER_CONFIG: | 
					
						
							| 
									
										
										
										
											2019-03-20 15:17:32 +11:00
										 |  |  | 			if (get_path_environment_notest(path, sizeof(path), subfolder, "BLENDER_USER_CONFIG")) break; | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			get_path_user(path, sizeof(path), "config", subfolder, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case BLENDER_USER_AUTOSAVE: | 
					
						
							| 
									
										
										
										
											2019-03-20 15:17:32 +11:00
										 |  |  | 			if (get_path_environment_notest(path, sizeof(path), subfolder, "BLENDER_USER_AUTOSAVE")) break; | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			get_path_user(path, sizeof(path), "autosave", subfolder, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case BLENDER_USER_SCRIPTS: | 
					
						
							| 
									
										
										
										
											2019-03-20 15:17:32 +11:00
										 |  |  | 			if (get_path_environment_notest(path, sizeof(path), subfolder, "BLENDER_USER_SCRIPTS")) break; | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			get_path_user(path, sizeof(path), "scripts", subfolder, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			BLI_assert(0); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ('\0' == path[0]) { | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the path to a folder in the user area, creating it if it doesn't exist. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-01-06 18:21:46 +11:00
										 |  |  | const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfolder) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	const char *path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* only for user folders */ | 
					
						
							|  |  |  | 	if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | 	path = BKE_appdir_folder_id(folder_id, subfolder); | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (!path) { | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | 		path = BKE_appdir_folder_id_user_notest(folder_id, subfolder); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		if (path) BLI_dir_create_recursive(path); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	return path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the path of the top-level version-specific local, user or system directory. | 
					
						
							|  |  |  |  * If do_check, then the result will be NULL if the directory doesn't exist. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, const bool do_check) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	static char path[FILE_MAX] = ""; | 
					
						
							|  |  |  | 	bool ok; | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | 	switch (folder_id) { | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		case BLENDER_RESOURCE_PATH_USER: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			ok = get_path_user(path, sizeof(path), NULL, NULL, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case BLENDER_RESOURCE_PATH_LOCAL: | 
					
						
							| 
									
										
										
										
											2017-03-24 10:35:58 +11:00
										 |  |  | 			ok = get_path_local(path, sizeof(path), NULL, NULL, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case BLENDER_RESOURCE_PATH_SYSTEM: | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 			ok = get_path_system(path, sizeof(path), NULL, NULL, ver); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			path[0] = '\0'; /* in case do_check is false */ | 
					
						
							|  |  |  | 			ok = false; | 
					
						
							|  |  |  | 			BLI_assert(!"incorrect ID"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!ok && do_check) { | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef PATH_DEBUG
 | 
					
						
							|  |  |  | #  undef PATH_DEBUG
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /* Preset paths */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Checks if name is a fully qualified filename to an executable. | 
					
						
							|  |  |  |  * If not it searches $PATH for the file. On Windows it also | 
					
						
							|  |  |  |  * adds the correct extension (.com .exe etc) from | 
					
						
							|  |  |  |  * $PATHEXT if necessary. Also on Windows it translates | 
					
						
							|  |  |  |  * the name to its 8.3 version to prevent problems with | 
					
						
							|  |  |  |  * spaces and stuff. Final result is returned in fullname. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param fullname: The full path and full name of the executable | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  * (must be FILE_MAX minimum) | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param name: The name of the executable (usually argv[0]) to be checked | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-06-28 19:09:20 +10:00
										 |  |  | static void where_am_i(char *fullname, const size_t maxlen, const char *name) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | #ifdef WITH_BINRELOC
 | 
					
						
							|  |  |  | 	/* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */ | 
					
						
							| 
									
										
										
										
											2015-05-13 12:49:33 +10:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		const char *path = NULL; | 
					
						
							|  |  |  | 		path = br_find_exe(NULL); | 
					
						
							|  |  |  | 		if (path) { | 
					
						
							|  |  |  | 			BLI_strncpy(fullname, path, maxlen); | 
					
						
							|  |  |  | 			free((void *)path); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2015-05-13 12:49:33 +10:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath"); | 
					
						
							|  |  |  | 		if (GetModuleFileNameW(0, fullname_16, maxlen)) { | 
					
						
							|  |  |  | 			conv_utf_16_to_8(fullname_16, fullname, maxlen); | 
					
						
							|  |  |  | 			if (!BLI_exists(fullname)) { | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 				CLOG_ERROR(&LOG, "path can't be found: \"%.*s\"", (int)maxlen, fullname); | 
					
						
							| 
									
										
										
										
											2015-05-13 12:49:33 +10:00
										 |  |  | 				MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			MEM_freeN(fullname_16); | 
					
						
							|  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-13 12:49:33 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		MEM_freeN(fullname_16); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* unix and non linux */ | 
					
						
							|  |  |  | 	if (name && name[0]) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BLI_strncpy(fullname, name, maxlen); | 
					
						
							|  |  |  | 		if (name[0] == '.') { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:05:58 +11:00
										 |  |  | 			BLI_path_cwd(fullname, maxlen); | 
					
						
							| 
									
										
										
										
											2015-05-06 06:05:31 +10:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2015-05-06 06:34:19 +10:00
										 |  |  | 			BLI_path_program_extensions_add_win32(fullname, maxlen); | 
					
						
							| 
									
										
										
										
											2015-05-06 06:05:31 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (BLI_last_slash(name)) { | 
					
						
							|  |  |  | 			// full path
 | 
					
						
							|  |  |  | 			BLI_strncpy(fullname, name, maxlen); | 
					
						
							| 
									
										
										
										
											2015-05-06 06:05:31 +10:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2015-05-06 06:34:19 +10:00
										 |  |  | 			BLI_path_program_extensions_add_win32(fullname, maxlen); | 
					
						
							| 
									
										
										
										
											2015-05-06 06:05:31 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2015-05-06 06:34:19 +10:00
										 |  |  | 			BLI_path_program_search(fullname, maxlen, name); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-11 08:42:27 +10:00
										 |  |  | 		/* Remove "/./" and "/../" so string comparisons can be used on the path. */ | 
					
						
							|  |  |  | 		BLI_cleanup_path(NULL, fullname); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #if defined(DEBUG)
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 		if (!STREQ(name, fullname)) { | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 			CLOG_INFO(&LOG, 2, "guessing '%s' == '%s'", name, fullname); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | void BKE_appdir_program_path_init(const char *argv0) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-28 19:09:20 +10:00
										 |  |  | 	where_am_i(bprogname, sizeof(bprogname), argv0); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Path to executable | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | const char *BKE_appdir_program_path(void) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	return bprogname; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Path to directory of executable | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | const char *BKE_appdir_program_dir(void) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	return bprogdir; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | bool BKE_appdir_program_python_search( | 
					
						
							|  |  |  |         char *fullpath, const size_t fullpath_len, | 
					
						
							|  |  |  |         const int version_major, const int version_minor) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-02-15 19:01:28 +11:00
										 |  |  | #ifdef PYTHON_EXECUTABLE_NAME
 | 
					
						
							|  |  |  | 	/* passed in from the build-systems 'PYTHON_EXECUTABLE' */ | 
					
						
							|  |  |  | 	const char *python_build_def = STRINGIFY(PYTHON_EXECUTABLE_NAME); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | 	const char *basename = "python"; | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 	char python_ver[16]; | 
					
						
							|  |  |  | 	/* check both possible names */ | 
					
						
							| 
									
										
										
										
											2016-02-15 19:01:28 +11:00
										 |  |  | 	const char *python_names[] = { | 
					
						
							|  |  |  | #ifdef PYTHON_EXECUTABLE_NAME
 | 
					
						
							|  |  |  | 		python_build_def, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		python_ver, | 
					
						
							|  |  |  | 		basename, | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | 	bool is_found = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 	BLI_snprintf(python_ver, sizeof(python_ver), "%s%d.%d", basename, version_major, version_minor); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		const char *python_bin_dir = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, "bin"); | 
					
						
							|  |  |  | 		if (python_bin_dir) { | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0; i < ARRAY_SIZE(python_names); i++) { | 
					
						
							|  |  |  | 				BLI_join_dirfile(fullpath, fullpath_len, python_bin_dir, python_names[i]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ( | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 				    BLI_path_program_extensions_add_win32(fullpath, fullpath_len) | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 				    BLI_exists(fullpath) | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 				    ) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					is_found = true; | 
					
						
							| 
									
										
										
										
											2015-06-02 15:42:03 +10:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (is_found == false) { | 
					
						
							| 
									
										
										
										
											2015-05-19 15:55:31 +10:00
										 |  |  | 		for (i = 0; i < ARRAY_SIZE(python_names); i++) { | 
					
						
							|  |  |  | 			if (BLI_path_program_search(fullpath, fullpath_len, python_names[i])) { | 
					
						
							|  |  |  | 				is_found = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-05-06 11:07:15 +10:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (is_found == false) { | 
					
						
							|  |  |  | 		*fullpath = '\0'; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return is_found; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-15 05:46:43 +10:00
										 |  |  | /** Keep in sync with `bpy.utils.app_template_paths()` */ | 
					
						
							| 
									
										
										
										
											2017-03-25 09:29:51 +11:00
										 |  |  | static const char *app_template_directory_search[2] = { | 
					
						
							|  |  |  | 	"startup" SEP_STR "bl_app_templates_user", | 
					
						
							|  |  |  | 	"startup" SEP_STR "bl_app_templates_system", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const int app_template_directory_id[2] = { | 
					
						
							| 
									
										
										
										
											2017-09-15 05:46:43 +10:00
										 |  |  | 	/* Only 'USER' */ | 
					
						
							| 
									
										
										
										
											2017-03-25 09:29:51 +11:00
										 |  |  | 	BLENDER_USER_SCRIPTS, | 
					
						
							| 
									
										
										
										
											2017-09-15 05:46:43 +10:00
										 |  |  | 	/* Covers 'LOCAL' & 'SYSTEM'. */ | 
					
						
							| 
									
										
										
										
											2017-03-25 09:29:51 +11:00
										 |  |  | 	BLENDER_SYSTEM_SCRIPTS, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Return true if templates exist | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | bool BKE_appdir_app_template_any(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char temp_dir[FILE_MAX]; | 
					
						
							|  |  |  | 	for (int i = 0; i < 2; i++) { | 
					
						
							|  |  |  | 		if (BKE_appdir_folder_id_ex( | 
					
						
							|  |  |  | 		        app_template_directory_id[i], app_template_directory_search[i], | 
					
						
							|  |  |  | 		        temp_dir, sizeof(temp_dir))) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (int i = 0; i < 2; i++) { | 
					
						
							|  |  |  | 		char subdir[FILE_MAX]; | 
					
						
							|  |  |  | 		BLI_join_dirfile(subdir, sizeof(subdir), app_template_directory_search[i], app_template); | 
					
						
							|  |  |  | 		if (BKE_appdir_folder_id_ex( | 
					
						
							|  |  |  | 		        app_template_directory_id[i], subdir, | 
					
						
							|  |  |  | 		        path, path_len)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 15:12:14 +02:00
										 |  |  | void BKE_appdir_app_templates(ListBase *templates) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BLI_listbase_clear(templates); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < 2; i++) { | 
					
						
							|  |  |  | 		char subdir[FILE_MAX]; | 
					
						
							|  |  |  | 		if (!BKE_appdir_folder_id_ex( | 
					
						
							|  |  |  | 		        app_template_directory_id[i], app_template_directory_search[i], | 
					
						
							|  |  |  | 		        subdir, sizeof(subdir))) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		struct direntry *dir; | 
					
						
							|  |  |  | 		uint totfile = BLI_filelist_dir_contents(subdir, &dir); | 
					
						
							|  |  |  | 		for (int f = 0; f < totfile; f++) { | 
					
						
							|  |  |  | 			if (!FILENAME_IS_CURRPAR(dir[f].relname) && S_ISDIR(dir[f].type)) { | 
					
						
							|  |  |  | 				char *template = BLI_strdup(dir[f].relname); | 
					
						
							|  |  |  | 				BLI_addtail(templates, BLI_genericNodeN(template)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BLI_filelist_free(dir, totfile); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Gets the temp directory when blender first runs. | 
					
						
							|  |  |  |  * If the default path is not found, use try $TEMP | 
					
						
							| 
									
										
										
										
											2018-06-01 18:19:39 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  * Also make sure the temp dir has a trailing slash | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param fullname: The full path to the temporary temp directory | 
					
						
							|  |  |  |  * \param basename: The full path to the persistent temp directory (may be NULL) | 
					
						
							|  |  |  |  * \param maxlen: The size of the fullname buffer | 
					
						
							|  |  |  |  * \param userdir: Directory specified in user preferences | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-06-28 19:09:20 +10:00
										 |  |  | static void where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* Clear existing temp dir, if needed. */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | 	BKE_tempdir_session_purge(); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	fullname[0] = '\0'; | 
					
						
							|  |  |  | 	if (basename) { | 
					
						
							|  |  |  | 		basename[0] = '\0'; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (userdir && BLI_is_dir(userdir)) { | 
					
						
							|  |  |  | 		BLI_strncpy(fullname, userdir, maxlen); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  | 	if (fullname[0] == '\0') { | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 		const char *tmp = BLI_getenv("TEMP"); /* Windows */ | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		if (tmp && BLI_is_dir(tmp)) { | 
					
						
							|  |  |  | 			BLI_strncpy(fullname, tmp, maxlen); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* Other OS's - Try TMP and TMPDIR */ | 
					
						
							|  |  |  | 	if (fullname[0] == '\0') { | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 		const char *tmp = BLI_getenv("TMP"); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		if (tmp && BLI_is_dir(tmp)) { | 
					
						
							|  |  |  | 			BLI_strncpy(fullname, tmp, maxlen); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (fullname[0] == '\0') { | 
					
						
							| 
									
										
										
										
											2018-09-05 14:31:10 +10:00
										 |  |  | 		const char *tmp = BLI_getenv("TMPDIR"); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		if (tmp && BLI_is_dir(tmp)) { | 
					
						
							|  |  |  | 			BLI_strncpy(fullname, tmp, maxlen); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-06-17 17:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 	if (fullname[0] == '\0') { | 
					
						
							|  |  |  | 		BLI_strncpy(fullname, "/tmp/", maxlen); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* add a trailing slash if needed */ | 
					
						
							|  |  |  | 		BLI_add_slash(fullname); | 
					
						
							|  |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  | 		if (userdir && userdir != fullname) { | 
					
						
							| 
									
										
										
										
											2017-03-24 10:11:01 +11:00
										 |  |  | 			/* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */ | 
					
						
							|  |  |  | 			BLI_strncpy(userdir, fullname, maxlen); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Now that we have a valid temp dir, add system-generated unique sub-dir. */ | 
					
						
							|  |  |  | 	if (basename) { | 
					
						
							|  |  |  | 		/* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ | 
					
						
							|  |  |  | 		char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); | 
					
						
							|  |  |  | 		const size_t ln = strlen(tmp_name) + 1; | 
					
						
							|  |  |  | 		if (ln <= maxlen) { | 
					
						
							|  |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  | 			if (_mktemp_s(tmp_name, ln) == 0) { | 
					
						
							|  |  |  | 				BLI_dir_create_recursive(tmp_name); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-05-13 14:10:05 +02:00
										 |  |  | 			if (mkdtemp(tmp_name) == NULL) { | 
					
						
							|  |  |  | 				BLI_dir_create_recursive(tmp_name); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (BLI_is_dir(tmp_name)) { | 
					
						
							|  |  |  | 			BLI_strncpy(basename, fullname, maxlen); | 
					
						
							|  |  |  | 			BLI_strncpy(fullname, tmp_name, maxlen); | 
					
						
							|  |  |  | 			BLI_add_slash(fullname); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2019-02-01 12:44:19 +11:00
										 |  |  | 			CLOG_WARN(&LOG, "Could not generate a temp file name for '%s', falling back to '%s'", tmp_name, fullname); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		MEM_freeN(tmp_name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Sets btempdir_base to userdir if specified and is a valid directory, otherwise | 
					
						
							|  |  |  |  * chooses a suitable OS-specific temporary directory. | 
					
						
							|  |  |  |  * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base. | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * \note On Window userdir will be set to the temporary directory! | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | void BKE_tempdir_init(char *userdir) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-28 19:09:20 +10:00
										 |  |  | 	where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Path to temporary directory (with trailing slash) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | const char *BKE_tempdir_session(void) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | 	return btempdir_session[0] ? btempdir_session : BKE_tempdir_base(); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Path to persistent temporary directory (with trailing slash) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | const char *BKE_tempdir_base(void) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	return btempdir_base; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Path to the system temporary directory (with trailing slash) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | void BKE_tempdir_system_init(char *dir) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-28 19:09:20 +10:00
										 |  |  | 	where_is_temp(dir, NULL, FILE_MAX, NULL); | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Delete content of this instance's temp dir. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-23 15:54:29 +01:00
										 |  |  | void BKE_tempdir_session_purge(void) | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (btempdir_session[0] && BLI_is_dir(btempdir_session)) { | 
					
						
							|  |  |  | 		BLI_delete(btempdir_session, true, true); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |