1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251875Speter * contributor license agreements. See the NOTICE file distributed with 3251875Speter * this work for additional information regarding copyright ownership. 4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251875Speter * (the "License"); you may not use this file except in compliance with 6251875Speter * the License. You may obtain a copy of the License at 7251875Speter * 8251875Speter * http://www.apache.org/licenses/LICENSE-2.0 9251875Speter * 10251875Speter * Unless required by applicable law or agreed to in writing, software 11251875Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251875Speter * See the License for the specific language governing permissions and 14251875Speter * limitations under the License. 15251875Speter */ 16251875Speter#include "apr_private.h" 17251875Speter#include "apr_file_io.h" 18251875Speter#include "apr_strings.h" 19251875Speter#include "apr_env.h" 20251875Speter 21251875Speter 22251875Speter/* Try to open a temporary file in the temporary dir, write to it, 23251875Speter and then close it. */ 24251875Speterstatic int test_tempdir(const char *temp_dir, apr_pool_t *p) 25251875Speter{ 26251875Speter apr_file_t *dummy_file; 27251875Speter char *path = apr_pstrcat(p, temp_dir, "/apr-tmp.XXXXXX", NULL); 28251875Speter 29251875Speter if (apr_file_mktemp(&dummy_file, path, 0, p) == APR_SUCCESS) { 30251875Speter if (apr_file_putc('!', dummy_file) == APR_SUCCESS) { 31251875Speter if (apr_file_close(dummy_file) == APR_SUCCESS) { 32251875Speter return 1; 33251875Speter } 34251875Speter } 35251875Speter } 36251875Speter return 0; 37251875Speter} 38251875Speter 39251875Speter 40251875SpeterAPR_DECLARE(apr_status_t) apr_temp_dir_get(const char **temp_dir, 41251875Speter apr_pool_t *p) 42251875Speter{ 43251875Speter apr_status_t apr_err; 44251875Speter const char *try_dirs[] = { "/tmp", "/usr/tmp", "/var/tmp" }; 45251875Speter const char *try_envs[] = { "TMPDIR", "TMP", "TEMP"}; 46251875Speter const char *dir; 47251875Speter char *cwd; 48251875Speter int i; 49251875Speter 50251875Speter /* Our goal is to find a temporary directory suitable for writing 51251875Speter into. 52251875Speter Here's the order in which we'll try various paths: 53251875Speter 54251875Speter $TMPDIR 55251875Speter $TMP 56251875Speter $TEMP 57251875Speter "C:\TEMP" (windows only) 58251875Speter "SYS:\TMP" (netware only) 59251875Speter "/tmp" 60251875Speter "/var/tmp" 61251875Speter "/usr/tmp" 62251875Speter P_tmpdir (POSIX define) 63251875Speter `pwd` 64251875Speter 65251875Speter NOTE: This algorithm is basically the same one used by Python 66251875Speter 2.2's tempfile.py module. */ 67251875Speter 68251875Speter /* Try the environment first. */ 69251875Speter for (i = 0; i < (sizeof(try_envs) / sizeof(const char *)); i++) { 70251875Speter char *value; 71251875Speter apr_err = apr_env_get(&value, try_envs[i], p); 72251875Speter if ((apr_err == APR_SUCCESS) && value) { 73251875Speter apr_size_t len = strlen(value); 74251875Speter if (len && (len < APR_PATH_MAX) && test_tempdir(value, p)) { 75251875Speter dir = value; 76251875Speter goto end; 77251875Speter } 78251875Speter } 79251875Speter } 80251875Speter 81251875Speter#ifdef WIN32 82251875Speter /* Next, on Win32, try the C:\TEMP directory. */ 83251875Speter if (test_tempdir("C:\\TEMP", p)) { 84251875Speter dir = "C:\\TEMP"; 85251875Speter goto end; 86251875Speter } 87251875Speter#endif 88251875Speter#ifdef NETWARE 89251875Speter /* Next, on NetWare, try the SYS:/TMP directory. */ 90251875Speter if (test_tempdir("SYS:/TMP", p)) { 91251875Speter dir = "SYS:/TMP"; 92251875Speter goto end; 93251875Speter } 94251875Speter#endif 95251875Speter 96251875Speter /* Next, try a set of hard-coded paths. */ 97251875Speter for (i = 0; i < (sizeof(try_dirs) / sizeof(const char *)); i++) { 98251875Speter if (test_tempdir(try_dirs[i], p)) { 99251875Speter dir = try_dirs[i]; 100251875Speter goto end; 101251875Speter } 102251875Speter } 103251875Speter 104251875Speter#ifdef P_tmpdir 105251875Speter /* 106251875Speter * If we have it, use the POSIX definition of where 107251875Speter * the tmpdir should be 108251875Speter */ 109251875Speter if (test_tempdir(P_tmpdir, p)) { 110251875Speter dir = P_tmpdir; 111251875Speter goto end; 112251875Speter } 113251875Speter#endif 114251875Speter 115251875Speter /* Finally, try the current working directory. */ 116251875Speter if (APR_SUCCESS == apr_filepath_get(&cwd, APR_FILEPATH_NATIVE, p)) { 117251875Speter if (test_tempdir(cwd, p)) { 118251875Speter dir = cwd; 119251875Speter goto end; 120251875Speter } 121251875Speter } 122251875Speter 123251875Speter /* We didn't find a suitable temp dir anywhere */ 124251875Speter return APR_EGENERAL; 125251875Speter 126251875Speterend: 127251875Speter *temp_dir = apr_pstrdup(p, dir); 128251875Speter return APR_SUCCESS; 129251875Speter} 130