#include "setup.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef VMS
#include <unixlib.h>
#endif
#include <curl/curl.h>
#include "strequal.h"
#include "strtok.h"
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
enum {
NOTHING,
HOSTFOUND,
HOSTCOMPLETE,
HOSTVALID,
HOSTEND
};
#define LOGINSIZE 64
#define PASSWORDSIZE 64
int Curl_parsenetrc(char *host,
char *login,
char *password)
{
FILE *file;
char netrcbuffer[256];
int retcode=1;
int specific_login = (login[0] != 0);
char *home = NULL;
int state=NOTHING;
char state_login=0;
char state_password=0;
char state_our_login=0;
#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");
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 MALLOCDEBUG
{
char *override = curl_getenv("CURL_DEBUG_NETRC");
if (override != NULL) {
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);
}
}
#endif
file = fopen(netrcbuffer, "r");
if(file) {
char *tok;
char *tok_buf;
while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) {
tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
while(tok) {
if (login[0] && password[0])
goto done;
switch(state) {
case NOTHING:
if(strequal("machine", tok)) {
state=HOSTFOUND;
}
break;
case HOSTFOUND:
if(strequal(host, tok)) {
state=HOSTVALID;
#ifdef _NETRC_DEBUG
printf("HOST: %s\n", tok);
#endif
retcode=0;
}
else
state=NOTHING;
break;
case HOSTVALID:
if(state_login) {
if (specific_login) {
state_our_login = strequal(login, tok);
}else{
strncpy(login, tok, LOGINSIZE-1);
#ifdef _NETRC_DEBUG
printf("LOGIN: %s\n", login);
#endif
}
state_login=0;
}
else if(state_password) {
if (state_our_login || !specific_login) {
strncpy(password, tok, PASSWORDSIZE-1);
#ifdef _NETRC_DEBUG
printf("PASSWORD: %s\n", password);
#endif
}
state_password=0;
}
else if(strequal("login", tok))
state_login=1;
else if(strequal("password", tok))
state_password=1;
else if(strequal("machine", tok)) {
state = HOSTFOUND;
state_our_login = 0;
}
break;
}
tok = strtok_r(NULL, " \t\n", &tok_buf);
}
}
done:
fclose(file);
}
if(NULL==pw)
free(home);
return retcode;
}
#ifdef _NETRC_DEBUG
int main(int argc, char **argv)
{
char login[64]="";
char password[64]="";
if(argc<2)
return -1;
if(0 == ParseNetrc(argv[1], login, password)) {
printf("HOST: %s LOGIN: %s PASSWORD: %s\n",
argv[1], login, password);
}
}
#endif