1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1998, 2013 Oracle and/or its affiliates.  All rights reserved.
5  *
6  * $Id$
7  */
8 
9 #include "db_config.h"
10 
11 #include "db_int.h"
12 
13 #ifdef HAVE_SYSTEM_INCLUDE_FILES
14 #ifdef macintosh
15 #include <TFileSpec.h>
16 #endif
17 #endif
18 
19 /*
20  * __os_tmpdir --
21  *	Set the temporary directory path.
22  *
23  * The order of items in the list structure and the order of checks in
24  * the environment are documented.
25  *
26  * PUBLIC: int __os_tmpdir __P((ENV *, u_int32_t));
27  */
28 int
__os_tmpdir(env,flags)29 __os_tmpdir(env, flags)
30 	ENV *env;
31 	u_int32_t flags;
32 {
33 	DB_ENV *dbenv;
34 	int isdir, ret;
35 	char *tdir, tdir_buf[DB_MAXPATHLEN];
36 
37 	dbenv = env->dbenv;
38 
39 	/* Use the environment if it's permitted and initialized. */
40 	if (LF_ISSET(DB_USE_ENVIRON) ||
41 	    (LF_ISSET(DB_USE_ENVIRON_ROOT) && __os_isroot())) {
42 		/* POSIX: TMPDIR */
43 		tdir = tdir_buf;
44 		if ((ret = __os_getenv(
45 		    env, "TMPDIR", &tdir, sizeof(tdir_buf))) != 0)
46 			return (ret);
47 		if (tdir != NULL && tdir[0] != '\0')
48 			goto found;
49 
50 		/*
51 		 * Windows: TEMP, TMP
52 		 */
53 		tdir = tdir_buf;
54 		if ((ret = __os_getenv(
55 		    env, "TEMP", &tdir, sizeof(tdir_buf))) != 0)
56 			return (ret);
57 		if (tdir != NULL && tdir[0] != '\0')
58 			goto found;
59 
60 		tdir = tdir_buf;
61 		if ((ret = __os_getenv(
62 		    env, "TMP", &tdir, sizeof(tdir_buf))) != 0)
63 			return (ret);
64 		if (tdir != NULL && tdir[0] != '\0')
65 			goto found;
66 
67 		/* Macintosh */
68 		tdir = tdir_buf;
69 		if ((ret = __os_getenv(
70 		    env, "TempFolder", &tdir, sizeof(tdir_buf))) != 0)
71 			return (ret);
72 
73 		if (tdir != NULL && tdir[0] != '\0')
74 found:			return (__os_strdup(env, tdir, &dbenv->db_tmp_dir));
75 	}
76 
77 #ifdef macintosh
78 	/* Get the path to the temporary folder. */
79 	{FSSpec spec;
80 
81 		if (!Special2FSSpec(kTemporaryFolderType,
82 		    kOnSystemDisk, 0, &spec))
83 			return (__os_strdup(env,
84 			    FSp2FullPath(&spec), &dbenv->db_tmp_dir));
85 	}
86 #endif
87 #ifdef DB_WIN32
88 	/* Get the path to the temporary directory. */
89 	{
90 		_TCHAR tpath[DB_MAXPATHLEN + 1];
91 		char *path, *eos;
92 
93 		if (GetTempPath(DB_MAXPATHLEN, tpath) > 2) {
94 			FROM_TSTRING(env, tpath, path, ret);
95 			if (ret != 0)
96 				return (ret);
97 
98 			eos = path + strlen(path) - 1;
99 			if (*eos == '\\' || *eos == '/')
100 				*eos = '\0';
101 			if (__os_exists(env, path, &isdir) == 0 && isdir) {
102 				ret = __os_strdup(env,
103 				    path, &dbenv->db_tmp_dir);
104 				FREE_STRING(env, path);
105 				return (ret);
106 			}
107 			FREE_STRING(env, path);
108 		}
109 	}
110 #endif
111 
112 	/*
113 	 * Step through the static list looking for a possibility.
114 	 *
115 	 * We don't use the obvious data structure because some C compilers
116 	 * (and I use the phrase loosely) don't like static data arrays.
117 	 */
118 #define	DB_TEMP_DIRECTORY(n) {						\
119 	char *__p = n;							\
120 	if (__os_exists(env, __p, &isdir) == 0 && isdir != 0)		\
121 		return (__os_strdup(env, __p, &dbenv->db_tmp_dir));	\
122 	}
123 #ifdef DB_WIN32
124 	DB_TEMP_DIRECTORY("/temp");
125 	DB_TEMP_DIRECTORY("C:/temp");
126 	DB_TEMP_DIRECTORY("C:/tmp");
127 #else
128 	DB_TEMP_DIRECTORY("/var/tmp");
129 	DB_TEMP_DIRECTORY("/usr/tmp");
130 	DB_TEMP_DIRECTORY("/tmp");
131 #if defined(ANDROID) || defined(DB_ANDROID)
132 	DB_TEMP_DIRECTORY("/cache");
133 #endif
134 #endif
135 
136 	/*
137 	 * If we don't have any other place to store temporary files, store
138 	 * them in the current directory.
139 	 */
140 	return (__os_strdup(env, "", &dbenv->db_tmp_dir));
141 }
142