diff --git a/CHANGES b/CHANGES index b798b81a7..d88359886 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,24 @@ Changelog +Daniel (11 November) +- Added CURLOPT_NETRC_FILE. Use this to tell libcurl which file to use instead + of trying to find a .netrc in the current user's home directory. The + existing .netrc file finder is somewhat naive and is far from perfect on + several platforms that aren't unix-style. If this option isn't set when + CURLOPT_NETRC is set, the previous approach will still be used. + + The current .netrc check code now also support longer than 256 bytes path + names. + +Daniel (10 November) +- Kang-Jin Lee pointed out that the generated ca-bundle.h file shouldn't be + written in the source dir if a different build dir is used. + +- After Sébastien Willemijns' bug report, we now check the separators properly + in the 229-reply servers respond on a EPSV command and bail out better if + the reply string is not RFC2428-compliant. + Daniel (7 November) - Based on Gisle Vanem's patch, I made curl try harder to get the home directory of the current user, in order to find the default .curlrc file. diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index ab104cda3..9096fdf30 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -1,7 +1,7 @@ .\" nroff -man [file] .\" $Id$ .\" -.TH curl_easy_setopt 3 "7 Nov 2003" "libcurl 7.10.8" "libcurl Manual" +.TH curl_easy_setopt 3 "11 Nov 2003" "libcurl 7.10.9" "libcurl Manual" .SH NAME curl_easy_setopt - set options for a curl easy handle .SH SYNOPSIS @@ -274,6 +274,11 @@ Only machine name, user name and password are taken into account \fBNote:\fP libcurl does not verify that the file has the correct properties set (as the standard Unix ftp client does). It should only be readable by user. +.IP CURLOPT_NETRC_FILE +Pass a char * as parameter, pointing to a zero terminated string containing +the full path name to the file you want libcurl to use as .netrc file. If this +option is omitted, and CURLOPT_NETRC is set, libcurl will attempt to find the +a .netrc file in the current user's home directory. .IP CURLOPT_USERPWD Pass a char * as parameter, which should be [user name]:[password] to use for the connection. Use \fICURLOPT_HTTPAUTH\fP to decide authentication method. diff --git a/include/curl/curl.h b/include/curl/curl.h index 5884c292e..c3c41b4d2 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -693,6 +693,12 @@ typedef enum { an HTTP or FTP server. */ CINIT(MAXFILESIZE, LONG, 114), + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, OBJECTPOINT, 115), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; diff --git a/lib/netrc.c b/lib/netrc.c index ed5d70252..c6443608e 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -45,6 +45,9 @@ #include "strequal.h" #include "strtok.h" +#define _MPRINTF_REPLACE /* use our functions only */ +#include + /* The last #include file should be: */ #ifdef CURLDEBUG #include "memdebug.h" @@ -71,54 +74,24 @@ enum { #define LOGINSIZE 64 #define PASSWORDSIZE 64 +/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */ int Curl_parsenetrc(char *host, char *login, - char *password) + char *password, + char *netrcfile) { FILE *file; - char netrcbuffer[256]; int retcode=1; - int specific_login = (login[0] != 0); - char *home = NULL; + bool home_alloc = FALSE; + bool netrc_alloc = FALSE; int state=NOTHING; char state_login=0; /* Found a login keyword */ char state_password=0; /* Found a password keyword */ char state_our_login=0; /* With specific_login, found *our* login name */ -#define NETRC DOT_CHAR "netrc" - -#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - struct passwd *pw; - pw= getpwuid(geteuid()); - if (pw) { -#ifdef VMS - home = decc$translate_vms(pw->pw_dir); -#else - home = pw->pw_dir; -#endif - } -#else - void *pw=NULL; -#endif - - if(NULL == pw) { - home = curl_getenv("HOME"); /* portable environment reader */ - if(!home) { - return -1; - } - } - - if(strlen(home)>(sizeof(netrcbuffer)-strlen(NETRC))) { - if(NULL==pw) - free(home); - return -1; - } - - sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC); - #ifdef CURLDEBUG { /* This is a hack to allow testing. @@ -127,27 +100,49 @@ int Curl_parsenetrc(char *host, char *override = curl_getenv("CURL_DEBUG_NETRC"); - if (override != NULL) { + if (override) { printf("NETRC: overridden .netrc file: %s\n", home); - - if (strlen(override)+1 > sizeof(netrcbuffer)) { - free(override); - if(NULL==pw) - free(home); - - return -1; - } - strcpy(netrcbuffer, override); - free(override); + netrcfile = override; + netrc_alloc = TRUE; } } #endif /* CURLDEBUG */ + if(!netrcfile) { +#define NETRC DOT_CHAR "netrc" +#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) + struct passwd *pw; + pw= getpwuid(geteuid()); + if (pw) { +#ifdef VMS + home = decc$translate_vms(pw->pw_dir); +#else + home = pw->pw_dir; +#endif + } +#endif + + if(NULL == pw) { + home = curl_getenv("HOME"); /* portable environment reader */ + if(!home) + return -1; + home_alloc = TRUE; + } - file = fopen(netrcbuffer, "r"); + netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC); + if(!netrcfile) { + if(home_alloc) + free(home); + return -1; + } + netrc_alloc = TRUE; + } + + file = fopen(netrcfile, "r"); if(file) { char *tok; char *tok_buf; bool done=FALSE; + char netrcbuffer[256]; while(!done && fgets(netrcbuffer, sizeof(netrcbuffer), file)) { tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); @@ -223,8 +218,10 @@ int Curl_parsenetrc(char *host, fclose(file); } - if(NULL==pw) + if(home_alloc) free(home); + if(netrc_alloc) + free(netrcfile); return retcode; } diff --git a/lib/netrc.h b/lib/netrc.h index 8b5bdc1a5..ef066b4c3 100644 --- a/lib/netrc.h +++ b/lib/netrc.h @@ -24,7 +24,8 @@ ***************************************************************************/ int Curl_parsenetrc(char *host, char *login, - char *password); + char *password, + char *filename); /* Assume: password[0]=0, host[0] != 0. * If login[0] = 0, search for login and password within a machine section * in the netrc. diff --git a/lib/url.c b/lib/url.c index 5da898c59..6b0d19170 100644 --- a/lib/url.c +++ b/lib/url.c @@ -507,6 +507,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.use_netrc = va_arg(param, long); break; + case CURLOPT_NETRC_FILE: + /* + * Use this file instead of the $HOME/.netrc file + */ + data->set.netrc_file = va_arg(param, char *); + break; case CURLOPT_FOLLOWLOCATION: /* * Follow Location: header hints on a HTTP-server. @@ -2758,7 +2764,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (data->set.use_netrc != CURL_NETRC_IGNORED) { if(Curl_parsenetrc(conn->hostname, - user, passwd)) { + user, passwd, + data->set.netrc_file)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } diff --git a/lib/urldata.h b/lib/urldata.h index d26cab6d9..aab332e80 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -854,6 +854,8 @@ struct UserDefined { bool upload; enum CURL_NETRC_OPTION use_netrc; /* defined in include/curl.h */ + char *netrc_file; /* if not NULL, use this instead of trying to find + $HOME/.netrc */ bool verbose; bool krb4; /* kerberos4 connection requested */ bool reuse_forbid; /* forbidden to be reused, close after use */