diff options
-rw-r--r-- | src/Makefile.inc | 4 | ||||
-rw-r--r-- | src/tool_findfile.c | 134 | ||||
-rw-r--r-- | src/tool_findfile.h (renamed from src/tool_homedir.h) | 4 | ||||
-rw-r--r-- | src/tool_homedir.c | 132 | ||||
-rw-r--r-- | src/tool_operate.c | 24 | ||||
-rw-r--r-- | src/tool_paramhlp.c | 1 | ||||
-rw-r--r-- | src/tool_parsecfg.c | 78 |
7 files changed, 180 insertions, 197 deletions
diff --git a/src/Makefile.inc b/src/Makefile.inc index 9fb9946d6..44cfe0f81 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -65,12 +65,12 @@ CURL_CFILES = \ tool_doswin.c \ tool_easysrc.c \ tool_filetime.c \ + tool_findfile.c \ tool_formparse.c \ tool_getparam.c \ tool_getpass.c \ tool_help.c \ tool_helpers.c \ - tool_homedir.c \ tool_hugehelp.c \ tool_libinfo.c \ tool_listhelp.c \ @@ -108,12 +108,12 @@ CURL_HFILES = \ tool_doswin.h \ tool_easysrc.h \ tool_filetime.h \ + tool_findfile.h \ tool_formparse.h \ tool_getparam.h \ tool_getpass.h \ tool_help.h \ tool_helpers.h \ - tool_homedir.h \ tool_hugehelp.h \ tool_libinfo.h \ tool_main.h \ diff --git a/src/tool_findfile.c b/src/tool_findfile.c new file mode 100644 index 000000000..cda8c8ed8 --- /dev/null +++ b/src/tool_findfile.c @@ -0,0 +1,134 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "tool_setup.h" + +#ifdef HAVE_PWD_H +# undef __NO_NET_API /* required for building for AmigaOS */ +# include <pwd.h> +#endif + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include <curl/mprintf.h> + +#include "tool_findfile.h" + +#include "memdebug.h" /* keep this as LAST include */ + +struct finder { + const char *env; + const char *append; +}; + +static const struct finder list[] = { + { "CURL_HOME", NULL }, + { "XDG_CONFIG_HOME", NULL }, + { "HOME", NULL }, +#ifdef WIN32 + { "USERPROFILE", NULL }, + { "APPDATA", NULL }, + { "USERPROFILE", "\\Application Data"}, +#endif + { NULL, NULL } +}; + +static char *checkhome(const char *home, const char *fname, bool dotscore) +{ + const char pref[2] = { '.', '_' }; + int i; + for(i = 0; i < (dotscore ? 2 : 1); i++) { + char *c; + if(dotscore) + c = curl_maprintf("%s" DIR_CHAR "%c%s", home, pref[i], &fname[1]); + else + c = curl_maprintf("%s" DIR_CHAR "%s", home, fname); + if(c) { + int fd = open(c, O_RDONLY); + if(fd >= 0) { + char *path = strdup(c); + close(fd); + curl_free(c); + return path; + } + curl_free(c); + } + } + return NULL; +} + +/* + * findfile() - return the full path name of the file. + * + * If 'dotscore' is TRUE, then check for the file first with a leading dot + * and then with a leading underscore. + * + * 1. Iterate over the environment variables in order, and if set, check for + * the given file to be accessed there, then it is a match. + * 2. Non-windows: try getpwuid + */ +char *findfile(const char *fname, bool dotscore) +{ + int i; + DEBUGASSERT(fname && fname[0]); + DEBUGASSERT(!dotscore || (fname[0] == '.')); + + if(!fname[0]) + return NULL; + + for(i = 0; list[i].env; i++) { + char *home = curl_getenv(list[i].env); + if(home) { + char *path; + if(!home[0]) { + curl_free(home); + continue; + } + if(list[i].append) { + char *c = curl_maprintf("%s%s", home, list[i].append); + curl_free(home); + if(!c) + return NULL; + home = c; + } + path = checkhome(home, fname, dotscore); + curl_free(home); + if(path) + return path; + } + } +#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) + { + struct passwd *pw = getpwuid(geteuid()); + if(pw) { + char *home = pw->pw_dir; + if(home && home[0]) + return checkhome(home, fname, FALSE); + } + } +#endif /* PWD-stuff */ + return NULL; +} diff --git a/src/tool_homedir.h b/src/tool_findfile.h index 31e38e96a..0f6a8eb55 100644 --- a/src/tool_homedir.h +++ b/src/tool_findfile.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,6 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -char *homedir(const char *fname); +char *findfile(const char *fname, bool dotscore); #endif /* HEADER_CURL_TOOL_HOMEDIR_H */ diff --git a/src/tool_homedir.c b/src/tool_homedir.c deleted file mode 100644 index 632bdcc4f..000000000 --- a/src/tool_homedir.c +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "tool_setup.h" - -#ifdef HAVE_PWD_H -# undef __NO_NET_API /* required for building for AmigaOS */ -# include <pwd.h> -#endif - -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#include <curl/mprintf.h> - -#include "tool_homedir.h" - -#include "memdebug.h" /* keep this as LAST include */ - -static char *GetEnv(const char *variable) -{ - char *dupe, *env; - - env = curl_getenv(variable); - if(!env) - return NULL; - - dupe = strdup(env); - curl_free(env); - return dupe; -} - -/* return the home directory of the current user as an allocated string */ - -/* - * The original logic found a home dir to use (by checking a range of - * environment variables and last using getpwuid) and returned that for the - * parent to use. - * - * With the XDG_CONFIG_HOME support (added much later than the other), this - * variable is treated differently in order to not ruin existing installations - * even if this environment variable is set. If this variable is set, and a - * file name is set to check, then only if that file name exists in that - * directory will it be returned as a "home directory". - * - * 1. use CURL_HOME if set - * 2. use XDG_CONFIG_HOME if set and fname is present - * 3. use HOME if set - * 4. Non-windows: use getpwuid - * 5. Windows: use APPDATA if set - * 6. Windows: use "USERPROFILE\Application Data" is set - */ - -char *homedir(const char *fname) -{ - char *home; - - home = GetEnv("CURL_HOME"); - if(home) - return home; - - if(fname) { - home = GetEnv("XDG_CONFIG_HOME"); - if(home) { - char *c = curl_maprintf("%s" DIR_CHAR "%s", home, fname); - if(c) { - int fd = open(c, O_RDONLY); - curl_free(c); - if(fd >= 0) { - close(fd); - return home; - } - } - free(home); - } - } - - home = GetEnv("HOME"); - if(home) - return home; - -#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - { - struct passwd *pw = getpwuid(geteuid()); - - if(pw) { - home = pw->pw_dir; - if(home && home[0]) - home = strdup(home); - else - home = NULL; - } - } -#endif /* PWD-stuff */ -#ifdef WIN32 - home = GetEnv("APPDATA"); - if(!home) { - char *env = GetEnv("USERPROFILE"); - if(env) { - char *path = curl_maprintf("%s\\Application Data", env); - if(path) { - home = strdup(path); - curl_free(path); - } - free(env); - } - } -#endif /* WIN32 */ - return home; -} diff --git a/src/tool_operate.c b/src/tool_operate.c index b9183c22a..d648dc054 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -63,7 +63,7 @@ #include "tool_filetime.h" #include "tool_getparam.h" #include "tool_helpers.h" -#include "tool_homedir.h" +#include "tool_findfile.h" #include "tool_libinfo.h" #include "tool_main.h" #include "tool_msgs.h" @@ -1716,23 +1716,19 @@ static CURLcode single_transfer(struct GlobalConfig *global, if((use_proto & (CURLPROTO_SCP|CURLPROTO_SFTP)) && !config->insecure_ok) { - char *home = homedir(NULL); - if(home) { - char *file = aprintf("%s/.ssh/known_hosts", home); - if(file) { - /* new in curl 7.19.6 */ - result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, file); - curl_free(file); - if(result == CURLE_UNKNOWN_OPTION) - /* libssh2 version older than 1.1.1 */ - result = CURLE_OK; - } - Curl_safefree(home); + char *known = findfile(".ssh/known_hosts", FALSE); + if(known) { + /* new in curl 7.19.6 */ + result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known); + curl_free(known); + if(result == CURLE_UNKNOWN_OPTION) + /* libssh2 version older than 1.1.1 */ + result = CURLE_OK; if(result) break; } else - warnf(global, "No home dir, couldn't find known_hosts file!"); + warnf(global, "Couldn't find a known_hosts file!"); } if(config->no_body || config->remote_time) { diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c index 28a8754f1..8ac6cf53e 100644 --- a/src/tool_paramhlp.c +++ b/src/tool_paramhlp.c @@ -30,7 +30,6 @@ #include "tool_cfgable.h" #include "tool_getparam.h" #include "tool_getpass.h" -#include "tool_homedir.h" #include "tool_msgs.h" #include "tool_paramhlp.h" #include "tool_version.h" diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c index d26774faf..ba8ac60e2 100644 --- a/src/tool_parsecfg.c +++ b/src/tool_parsecfg.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -28,7 +28,7 @@ #include "tool_cfgable.h" #include "tool_getparam.h" #include "tool_helpers.h" -#include "tool_homedir.h" +#include "tool_findfile.h" #include "tool_msgs.h" #include "tool_parsecfg.h" #include "dynbuf.h" @@ -45,9 +45,9 @@ static const char *unslashquote(const char *line, char *param); static bool my_get_line(FILE *fp, struct curlx_dynbuf *, bool *error); #ifdef WIN32 -static FILE *execpath(const char *filename) +static FILE *execpath(const char *filename, char **pathp) { - char filebuffer[512]; + static char filebuffer[512]; /* Get the filename of our executable. GetModuleFileName is already declared * via inclusions done in setup header file. We assume that we are using * the ASCII version here. @@ -62,8 +62,11 @@ static FILE *execpath(const char *filename) /* If we have enough space, build the RC filename */ remaining = sizeof(filebuffer) - strlen(filebuffer); if(strlen(filename) < remaining - 1) { + FILE *f; msnprintf(lastdirchar, remaining, "%s%s", DIR_CHAR, filename); - return fopen(filebuffer, FOPEN_READTEXT); + *pathp = filebuffer; + f = fopen(filebuffer, FOPEN_READTEXT); + return f; } } } @@ -81,55 +84,37 @@ int parseconfig(const char *filename, struct GlobalConfig *global) int rc = 0; struct OperationConfig *operation = global->last; char *pathalloc = NULL; +#ifdef WIN32 +#define DOTSCORE TRUE /* look for underscore-prefixed name too */ +#else +#define DOTSCORE FALSE +#endif - if(!filename || !*filename) { - /* NULL or no file name attempts to load .curlrc from the homedir! */ - - char *home = homedir(".curlrc"); -#ifndef WIN32 - if(home) { - pathalloc = curl_maprintf("%s%s.curlrc", home, DIR_CHAR); - if(!pathalloc) { - free(home); - return 1; /* out of memory */ + if(!filename) { + /* NULL means load .curlrc from homedir! */ + char *curlrc = findfile(".curlrc", DOTSCORE); + if(curlrc) { + file = fopen(curlrc, FOPEN_READTEXT); + if(!file) { + curl_free(curlrc); + return 1; } - filename = pathalloc; - } -#else /* Windows */ - if(home) { - int i = 0; - char prefix = '.'; - do { - /* if it was allocated in a previous attempt */ - curl_free(pathalloc); - /* check for .curlrc then _curlrc in the home dir */ - pathalloc = curl_maprintf("%s%s%ccurlrc", home, DIR_CHAR, prefix); - if(!pathalloc) { - free(home); - return 1; /* out of memory */ - } - - /* Check if the file exists - if not, try _curlrc */ - file = fopen(pathalloc, FOPEN_READTEXT); - if(file) { - filename = pathalloc; - break; - } - prefix = '_'; - } while(++i < 2); + filename = pathalloc = curlrc; } - if(!filename) { +#ifdef WIN32 /* Windows */ + else { + char *fullp; /* check for .curlrc then _curlrc in the dir of the executable */ - file = execpath(".curlrc"); + file = execpath(".curlrc", &fullp); if(!file) - file = execpath("_curlrc"); + file = execpath("_curlrc", &fullp); + if(file) + /* this is the filename we read from */ + filename = fullp; } #endif - - Curl_safefree(home); /* we've used it, now free it */ } - - if(!file && filename) { /* no need to fopen() again */ + else { if(strcmp(filename, "-")) file = fopen(filename, FOPEN_READTEXT); else @@ -145,6 +130,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) struct curlx_dynbuf buf; bool fileerror; curlx_dyn_init(&buf, MAX_CONFIG_LINE_LENGTH); + DEBUGASSERT(filename); while(my_get_line(file, &buf, &fileerror)) { int res; |