#define FOUND_LOGIN 1
#define FOUND_PASSWORD 2
-#define NETRC_FILE_MISSING 1
-#define NETRC_FAILED -1
-#define NETRC_SUCCESS 0
-
#define MAX_NETRC_LINE 16384
#define MAX_NETRC_FILE (128*1024)
#define MAX_NETRC_TOKEN 4096
-static CURLcode file2memory(const char *filename, struct dynbuf *filebuf)
+/* convert a dynbuf call CURLcode error to a NETRCcode error */
+#define curl2netrc(result) \
+ (((result) == CURLE_OUT_OF_MEMORY) ? \
+ NETRC_OUT_OF_MEMORY : NETRC_SYNTAX_ERROR)
+
+static NETRCcode file2memory(const char *filename, struct dynbuf *filebuf)
{
- CURLcode result = CURLE_OK;
+ NETRCcode ret = NETRC_FILE_MISSING; /* if it cannot open the file */
FILE *file = fopen(filename, FOPEN_READTEXT);
struct dynbuf linebuf;
Curl_dyn_init(&linebuf, MAX_NETRC_LINE);
if(file) {
+ ret = NETRC_OK;
while(Curl_get_line(&linebuf, file)) {
+ CURLcode result;
const char *line = Curl_dyn_ptr(&linebuf);
/* skip comments on load */
while(ISBLANK(*line))
if(*line == '#')
continue;
result = Curl_dyn_add(filebuf, line);
- if(result)
+ if(result) {
+ ret = curl2netrc(result);
goto done;
+ }
}
}
done:
Curl_dyn_free(&linebuf);
if(file)
fclose(file);
- return result;
+ return ret;
}
/*
* Returns zero on success.
*/
-static int parsenetrc(struct store_netrc *store,
- const char *host,
- char **loginp, /* might point to a username */
- char **passwordp,
- const char *netrcfile)
+static NETRCcode parsenetrc(struct store_netrc *store,
+ const char *host,
+ char **loginp, /* might point to a username */
+ char **passwordp,
+ const char *netrcfile)
{
- int retcode = NETRC_FILE_MISSING;
+ NETRCcode retcode = NETRC_NO_MATCH;
char *login = *loginp;
char *password = NULL;
bool specific_login = !!login; /* points to something */
Curl_dyn_init(&token, MAX_NETRC_TOKEN);
if(!store->loaded) {
- if(file2memory(netrcfile, filebuf))
- return NETRC_FAILED;
+ NETRCcode ret = file2memory(netrcfile, filebuf);
+ if(ret)
+ return ret;
store->loaded = TRUE;
}
tok_end = tok;
if(!quoted) {
size_t len = 0;
+ CURLcode result;
while(!ISSPACE(*tok_end)) {
tok_end++;
len++;
}
- if(!len || Curl_dyn_addn(&token, tok, len)) {
- retcode = NETRC_FAILED;
+ if(!len) {
+ retcode = NETRC_SYNTAX_ERROR;
+ goto out;
+ }
+ result = Curl_dyn_addn(&token, tok, len);
+ if(result) {
+ retcode = curl2netrc(result);
goto out;
}
}
bool endquote = FALSE;
tok_end++; /* pass the leading quote */
while(*tok_end) {
+ CURLcode result;
char s = *tok_end;
if(escape) {
escape = FALSE;
endquote = TRUE;
break;
}
- if(Curl_dyn_addn(&token, &s, 1)) {
- retcode = NETRC_FAILED;
+ result = Curl_dyn_addn(&token, &s, 1);
+ if(result) {
+ retcode = curl2netrc(result);
goto out;
}
tok_end++;
}
if(escape || !endquote) {
/* bad syntax, get out */
- retcode = NETRC_FAILED;
+ retcode = NETRC_SYNTAX_ERROR;
goto out;
}
}
}
else if(strcasecompare("default", tok)) {
state = HOSTVALID;
- retcode = NETRC_SUCCESS; /* we did find our host */
+ retcode = NETRC_OK; /* we did find our host */
}
break;
case MACDEF:
if(strcasecompare(host, tok)) {
/* and yes, this is our host! */
state = HOSTVALID;
- retcode = NETRC_SUCCESS; /* we did find our host */
+ retcode = NETRC_OK; /* we did find our host */
}
else
/* not our host */
free(login);
login = strdup(tok);
if(!login) {
- retcode = NETRC_FAILED; /* allocation failed */
+ retcode = NETRC_OUT_OF_MEMORY; /* allocation failed */
goto out;
}
}
free(password);
password = strdup(tok);
if(!password) {
- retcode = NETRC_FAILED; /* allocation failed */
+ retcode = NETRC_OUT_OF_MEMORY; /* allocation failed */
goto out;
}
if(!specific_login || our_login)
}
else if(strcasecompare("default", tok)) {
state = HOSTVALID;
- retcode = NETRC_SUCCESS; /* we did find our host */
+ retcode = NETRC_OK; /* we did find our host */
Curl_safefree(password);
if(!specific_login)
Curl_safefree(login);
/* success without a password, set a blank one */
password = strdup("");
if(!password)
- retcode = 1; /* out of memory */
+ retcode = NETRC_OUT_OF_MEMORY; /* out of memory */
}
else if(!login && !password)
/* a default with no credentials */
- retcode = NETRC_FILE_MISSING;
+ retcode = NETRC_NO_MATCH;
}
if(!retcode) {
/* success */
return retcode;
}
+const char *Curl_netrc_strerror(NETRCcode ret)
+{
+ switch(ret) {
+ default:
+ return ""; /* not a legit error */
+ case NETRC_FILE_MISSING:
+ return "no such file";
+ case NETRC_NO_MATCH:
+ return "no matching entry";
+ case NETRC_OUT_OF_MEMORY:
+ return "out of memory";
+ case NETRC_SYNTAX_ERROR:
+ return "syntax error";
+ }
+ /* never reached */
+}
+
/*
* @unittest: 1304
*
* *loginp and *passwordp MUST be allocated if they are not NULL when passed
* in.
*/
-int Curl_parsenetrc(struct store_netrc *store, const char *host,
- char **loginp, char **passwordp,
- char *netrcfile)
+NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
+ char **loginp, char **passwordp,
+ char *netrcfile)
{
- int retcode = 1;
+ NETRCcode retcode = NETRC_OK;
char *filealloc = NULL;
if(!netrcfile) {
}
if(!home)
- return retcode; /* no home directory found (or possibly out of
- memory) */
+ return NETRC_FILE_MISSING; /* no home directory found (or possibly out
+ of memory) */
filealloc = aprintf("%s%s.netrc", home, DIR_CHAR);
if(!filealloc) {
free(homea);
- return -1;
+ return NETRC_OUT_OF_MEMORY;
}
retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
free(filealloc);
#ifdef _WIN32
- if((retcode == NETRC_FILE_MISSING) || (retcode == NETRC_FAILED)) {
+ if(retcode == NETRC_FILE_MISSING) {
/* fallback to the old-style "_netrc" file */
filealloc = aprintf("%s%s_netrc", home, DIR_CHAR);
if(!filealloc) {
free(homea);
- return -1;
+ return NETRC_OUT_OF_MEMORY;
}
retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
free(filealloc);
BIT(loaded);
};
+typedef enum {
+ NETRC_OK,
+ NETRC_NO_MATCH, /* no matching entry in the file */
+ NETRC_SYNTAX_ERROR, /* in the netrc file */
+ NETRC_FILE_MISSING, /* the netrc file does not exist */
+ NETRC_OUT_OF_MEMORY, /* while parsing netrc */
+ NETRC_LAST /* never used */
+} NETRCcode;
+
+const char *Curl_netrc_strerror(NETRCcode ret);
void Curl_netrc_init(struct store_netrc *s);
void Curl_netrc_cleanup(struct store_netrc *s);
-/* returns -1 on failure, 0 if the host is found, 1 is the host is not found */
-int Curl_parsenetrc(struct store_netrc *s, const char *host, char **loginp,
- char **passwordp, char *filename);
+NETRCcode Curl_parsenetrc(struct store_netrc *s, const char *host,
+ char **loginp, char **passwordp, char *filename);
/* Assume: (*passwordp)[0]=0, host[0] != 0.
* If (*loginp)[0] = 0, search for login and password within a machine
* section in the netrc.