2
0

tempdir.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 "fspr_private.h"
  17. #include "fspr_file_io.h"
  18. #include "fspr_strings.h"
  19. #include "fspr_env.h"
  20. /* Try to open a temporary file in the temporary dir, write to it,
  21. and then close it. */
  22. static int test_tempdir(const char *temp_dir, fspr_pool_t *p)
  23. {
  24. fspr_file_t *dummy_file;
  25. char *path = fspr_pstrcat(p, temp_dir, "/apr-tmp.XXXXXX", NULL);
  26. if (fspr_file_mktemp(&dummy_file, path, 0, p) == APR_SUCCESS) {
  27. if (fspr_file_putc('!', dummy_file) == APR_SUCCESS) {
  28. if (fspr_file_close(dummy_file) == APR_SUCCESS) {
  29. return 1;
  30. }
  31. }
  32. }
  33. return 0;
  34. }
  35. APR_DECLARE(fspr_status_t) fspr_temp_dir_get(const char **temp_dir,
  36. fspr_pool_t *p)
  37. {
  38. fspr_status_t fspr_err;
  39. const char *try_dirs[] = { "/tmp", "/usr/tmp", "/var/tmp" };
  40. const char *try_envs[] = { "TMP", "TEMP", "TMPDIR" };
  41. const char *dir;
  42. char *cwd;
  43. int i;
  44. /* Our goal is to find a temporary directory suitable for writing
  45. into. We'll only pay the price once if we're successful -- we
  46. cache our successful find. Here's the order in which we'll try
  47. various paths:
  48. $TMP
  49. $TEMP
  50. $TMPDIR
  51. "C:\TEMP" (windows only)
  52. "SYS:\TMP" (netware only)
  53. "/tmp"
  54. "/var/tmp"
  55. "/usr/tmp"
  56. P_tmpdir (POSIX define)
  57. `pwd`
  58. NOTE: This algorithm is basically the same one used by Python
  59. 2.2's tempfile.py module. */
  60. /* Try the environment first. */
  61. for (i = 0; i < (sizeof(try_envs) / sizeof(const char *)); i++) {
  62. char *value;
  63. fspr_err = fspr_env_get(&value, try_envs[i], p);
  64. if ((fspr_err == APR_SUCCESS) && value) {
  65. fspr_size_t len = strlen(value);
  66. if (len && (len < APR_PATH_MAX) && test_tempdir(value, p)) {
  67. dir = value;
  68. goto end;
  69. }
  70. }
  71. }
  72. #ifdef WIN32
  73. /* Next, on Win32, try the C:\TEMP directory. */
  74. if (test_tempdir("C:\\TEMP", p)) {
  75. dir = "C:\\TEMP";
  76. goto end;
  77. }
  78. #endif
  79. #ifdef NETWARE
  80. /* Next, on NetWare, try the SYS:/TMP directory. */
  81. if (test_tempdir("SYS:/TMP", p)) {
  82. dir = "SYS:/TMP";
  83. goto end;
  84. }
  85. #endif
  86. /* Next, try a set of hard-coded paths. */
  87. for (i = 0; i < (sizeof(try_dirs) / sizeof(const char *)); i++) {
  88. if (test_tempdir(try_dirs[i], p)) {
  89. dir = try_dirs[i];
  90. goto end;
  91. }
  92. }
  93. #ifdef P_tmpdir
  94. /*
  95. * If we have it, use the POSIX definition of where
  96. * the tmpdir should be
  97. */
  98. if (test_tempdir(P_tmpdir, p)) {
  99. dir = P_tmpdir;
  100. goto end;
  101. }
  102. #endif
  103. /* Finally, try the current working directory. */
  104. if (APR_SUCCESS == fspr_filepath_get(&cwd, APR_FILEPATH_NATIVE, p)) {
  105. if (test_tempdir(cwd, p)) {
  106. dir = cwd;
  107. goto end;
  108. }
  109. }
  110. /* We didn't find a suitable temp dir anywhere */
  111. return APR_EGENERAL;
  112. end:
  113. *temp_dir = fspr_pstrdup(p, dir);
  114. return APR_SUCCESS;
  115. }