tool_homedir.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. ***************************************************************************/
  22. #include "tool_setup.h"
  23. #ifdef HAVE_PWD_H
  24. # undef __NO_NET_API /* required for building for AmigaOS */
  25. # include <pwd.h>
  26. #endif
  27. #ifdef HAVE_SYS_STAT_H
  28. #include <sys/stat.h>
  29. #endif
  30. #ifdef HAVE_FCNTL_H
  31. #include <fcntl.h>
  32. #endif
  33. #include <curl/mprintf.h>
  34. #include "tool_homedir.h"
  35. #include "memdebug.h" /* keep this as LAST include */
  36. static char *GetEnv(const char *variable)
  37. {
  38. char *dupe, *env;
  39. env = curl_getenv(variable);
  40. if(!env)
  41. return NULL;
  42. dupe = strdup(env);
  43. curl_free(env);
  44. return dupe;
  45. }
  46. /* return the home directory of the current user as an allocated string */
  47. /*
  48. * The original logic found a home dir to use (by checking a range of
  49. * environment variables and last using getpwuid) and returned that for the
  50. * parent to use.
  51. *
  52. * With the XDG_CONFIG_HOME support (added much later than the other), this
  53. * variable is treated differently in order to not ruin existing installations
  54. * even if this environment variable is set. If this variable is set, and a
  55. * file name is set to check, then only if that file name exists in that
  56. * directory will it be returned as a "home directory".
  57. *
  58. * 1. use CURL_HOME if set
  59. * 2. use XDG_CONFIG_HOME if set and fname is present
  60. * 3. use HOME if set
  61. * 4. Non-windows: use getpwuid
  62. * 5. Windows: use APPDATA if set
  63. * 6. Windows: use "USERPROFILE\Application Data" is set
  64. */
  65. char *homedir(const char *fname)
  66. {
  67. char *home;
  68. home = GetEnv("CURL_HOME");
  69. if(home)
  70. return home;
  71. if(fname) {
  72. home = GetEnv("XDG_CONFIG_HOME");
  73. if(home) {
  74. char *c = curl_maprintf("%s" DIR_CHAR "%s", home, fname);
  75. if(c) {
  76. int fd = open(c, O_RDONLY);
  77. curl_free(c);
  78. if(fd >= 0) {
  79. close(fd);
  80. return home;
  81. }
  82. }
  83. free(home);
  84. }
  85. }
  86. home = GetEnv("HOME");
  87. if(home)
  88. return home;
  89. #if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
  90. {
  91. struct passwd *pw = getpwuid(geteuid());
  92. if(pw) {
  93. home = pw->pw_dir;
  94. if(home && home[0])
  95. home = strdup(home);
  96. else
  97. home = NULL;
  98. }
  99. }
  100. #endif /* PWD-stuff */
  101. #ifdef WIN32
  102. home = GetEnv("APPDATA");
  103. if(!home) {
  104. char *env = GetEnv("USERPROFILE");
  105. if(env) {
  106. char *path = curl_maprintf("%s\\Application Data", env);
  107. if(path) {
  108. home = strdup(path);
  109. curl_free(path);
  110. }
  111. free(env);
  112. }
  113. }
  114. #endif /* WIN32 */
  115. return home;
  116. }