/src/httpd/srclib/apr/file_io/unix/tempdir.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Licensed to the Apache Software Foundation (ASF) under one or more |
2 | | * contributor license agreements. See the NOTICE file distributed with |
3 | | * this work for additional information regarding copyright ownership. |
4 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
5 | | * (the "License"); you may not use this file except in compliance with |
6 | | * the License. You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | #include "apr_private.h" |
17 | | #include "apr_file_io.h" |
18 | | #include "apr_strings.h" |
19 | | #include "apr_env.h" |
20 | | |
21 | | |
22 | | /* Try to open a temporary file in the temporary dir, write to it, |
23 | | and then close it. */ |
24 | | static int test_tempdir(const char *temp_dir, apr_pool_t *p) |
25 | 0 | { |
26 | 0 | apr_file_t *dummy_file; |
27 | 0 | char *path = apr_pstrcat(p, temp_dir, "/apr-tmp.XXXXXX", NULL); |
28 | |
|
29 | 0 | if (apr_file_mktemp(&dummy_file, path, 0, p) == APR_SUCCESS) { |
30 | 0 | if (apr_file_putc('!', dummy_file) == APR_SUCCESS) { |
31 | 0 | if (apr_file_close(dummy_file) == APR_SUCCESS) { |
32 | 0 | return 1; |
33 | 0 | } |
34 | 0 | } |
35 | 0 | } |
36 | 0 | return 0; |
37 | 0 | } |
38 | | |
39 | | |
40 | | APR_DECLARE(apr_status_t) apr_temp_dir_get(const char **temp_dir, |
41 | | apr_pool_t *p) |
42 | 0 | { |
43 | 0 | apr_status_t apr_err; |
44 | 0 | const char *try_dirs[] = { "/tmp", "/usr/tmp", "/var/tmp" }; |
45 | 0 | const char *try_envs[] = { "TMPDIR", "TMP", "TEMP"}; |
46 | 0 | const char *dir; |
47 | 0 | char *cwd; |
48 | 0 | int i; |
49 | | |
50 | | /* Our goal is to find a temporary directory suitable for writing |
51 | | into. |
52 | | Here's the order in which we'll try various paths: |
53 | | |
54 | | $TMPDIR |
55 | | $TMP |
56 | | $TEMP |
57 | | "C:\TEMP" (windows only) |
58 | | "SYS:\TMP" (netware only) |
59 | | "/tmp" |
60 | | "/var/tmp" |
61 | | "/usr/tmp" |
62 | | P_tmpdir (POSIX define) |
63 | | `pwd` |
64 | | |
65 | | NOTE: This algorithm is basically the same one used by Python |
66 | | 2.2's tempfile.py module. */ |
67 | | |
68 | | /* Try the environment first. */ |
69 | 0 | for (i = 0; i < (sizeof(try_envs) / sizeof(const char *)); i++) { |
70 | 0 | char *value; |
71 | 0 | apr_err = apr_env_get(&value, try_envs[i], p); |
72 | 0 | if ((apr_err == APR_SUCCESS) && value) { |
73 | 0 | apr_size_t len = strlen(value); |
74 | 0 | if (len && (len < APR_PATH_MAX) && test_tempdir(value, p)) { |
75 | 0 | dir = value; |
76 | 0 | goto end; |
77 | 0 | } |
78 | 0 | } |
79 | 0 | } |
80 | | |
81 | | #ifdef WIN32 |
82 | | /* Next, on Win32, try the C:\TEMP directory. */ |
83 | | if (test_tempdir("C:\\TEMP", p)) { |
84 | | dir = "C:\\TEMP"; |
85 | | goto end; |
86 | | } |
87 | | #endif |
88 | | #ifdef NETWARE |
89 | | /* Next, on NetWare, try the SYS:/TMP directory. */ |
90 | | if (test_tempdir("SYS:/TMP", p)) { |
91 | | dir = "SYS:/TMP"; |
92 | | goto end; |
93 | | } |
94 | | #endif |
95 | | |
96 | | /* Next, try a set of hard-coded paths. */ |
97 | 0 | for (i = 0; i < (sizeof(try_dirs) / sizeof(const char *)); i++) { |
98 | 0 | if (test_tempdir(try_dirs[i], p)) { |
99 | 0 | dir = try_dirs[i]; |
100 | 0 | goto end; |
101 | 0 | } |
102 | 0 | } |
103 | | |
104 | 0 | #ifdef P_tmpdir |
105 | | /* |
106 | | * If we have it, use the POSIX definition of where |
107 | | * the tmpdir should be |
108 | | */ |
109 | 0 | if (test_tempdir(P_tmpdir, p)) { |
110 | 0 | dir = P_tmpdir; |
111 | 0 | goto end; |
112 | 0 | } |
113 | 0 | #endif |
114 | | |
115 | | /* Finally, try the current working directory. */ |
116 | 0 | if (APR_SUCCESS == apr_filepath_get(&cwd, APR_FILEPATH_NATIVE, p)) { |
117 | 0 | if (test_tempdir(cwd, p)) { |
118 | 0 | dir = cwd; |
119 | 0 | goto end; |
120 | 0 | } |
121 | 0 | } |
122 | | |
123 | | /* We didn't find a suitable temp dir anywhere */ |
124 | 0 | return APR_EGENERAL; |
125 | | |
126 | 0 | end: |
127 | 0 | *temp_dir = apr_pstrdup(p, dir); |
128 | 0 | return APR_SUCCESS; |
129 | 0 | } |