mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
b7f6941da8
v4.5-release-candidate branch and master branch ASAP. The bug occurs in d4rc.c where strcmp is being applied to NULL. Also, the code in which it occurs is debugging code, so it needs to be #ifdef'd. This fix may cause minor conflicts with other outstanding pull requests that fix the same bug. But the conflicts should be minor and easy to resolve.
628 lines
17 KiB
C
628 lines
17 KiB
C
/*********************************************************************
|
|
* Copyright 2016, UCAR/Unidata
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*********************************************************************/
|
|
|
|
#include "d4includes.h"
|
|
|
|
#define D4RCFILEENV "DAPRCFILE"
|
|
|
|
#define RTAG ']'
|
|
#define LTAG '['
|
|
|
|
#define TRIMCHARS " \t\r\n"
|
|
|
|
#undef MEMCHECK
|
|
#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
|
|
|
|
/* Forward */
|
|
static char* extract_credentials(NCURI*);
|
|
static int rccompile(const char* path);
|
|
static struct NCD4triple* rclocate(char* key, char* hostport);
|
|
static void rcorder(NClist* rc);
|
|
static char* rcreadline(char**);
|
|
static int rcsearch(const char* prefix, const char* rcname, char** pathp);
|
|
static void rctrim(char* text);
|
|
static int rcsetinfocurlflag(NCD4INFO*, const char* flag, const char* value);
|
|
#ifdef D4DEBUG
|
|
static void storedump(char* msg, NClist* triples);
|
|
#endif
|
|
|
|
/* Define default rc files and aliases, also defines search order*/
|
|
static char* rcfilenames[] = {".daprc",".dodsrc",NULL};
|
|
|
|
/* Define the curl flag defaults in envv style */
|
|
static const char* RCDEFAULTFLAGS[] = {
|
|
"HTTP.TIMEOUT","10", /*seconds */
|
|
NULL
|
|
};
|
|
|
|
static char*
|
|
rcreadline(char** nextlinep)
|
|
{
|
|
char* line;
|
|
char* p;
|
|
|
|
line = (p = *nextlinep);
|
|
if(*p == '\0') return NULL; /*signal done*/
|
|
for(;*p;p++) {
|
|
if(*p == '\r' && p[1] == '\n') *p = '\0';
|
|
else if(*p == '\n') break;
|
|
}
|
|
*p++ = '\0'; /* null terminate line; overwrite newline */
|
|
*nextlinep = p;
|
|
return line;
|
|
}
|
|
|
|
/* Trim TRIMCHARS from both ends of text; */
|
|
static void
|
|
rctrim(char* text)
|
|
{
|
|
char* p = text;
|
|
size_t len;
|
|
int i;
|
|
|
|
len = strlen(text);
|
|
/* locate first non-trimchar */
|
|
for(;*p;p++) {
|
|
if(strchr(TRIMCHARS,*p) == NULL) break; /* hit non-trim char */
|
|
}
|
|
d4memmove(text,p,strlen(p)+1);
|
|
len = strlen(text);
|
|
/* locate last non-trimchar */
|
|
if(len > 0) {
|
|
for(i=(len-1);i>=0;i--) {
|
|
if(strchr(TRIMCHARS,text[i]) == NULL) {
|
|
text[i+1] = '\0'; /* elide trailing trimchars */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Order the triples: put all those with urls first */
|
|
static void
|
|
rcorder(NClist* rc)
|
|
{
|
|
int i,j;
|
|
int len = nclistlength(rc);
|
|
if(rc == NULL || len == 0) return;
|
|
for(i=0;i<len;i++) {
|
|
NCD4triple* ti = nclistget(rc,i);
|
|
if(ti->host != NULL) continue;
|
|
for(j=i;j<len;j++) {
|
|
NCD4triple* tj = nclistget(rc,j);
|
|
if(tj->host != NULL) {/*swap*/
|
|
NCD4triple* t = ti;
|
|
nclistset(rc,i,tj);
|
|
nclistset(rc,j,t);
|
|
}
|
|
}
|
|
}
|
|
#ifdef D4DEBUG
|
|
storedump("reorder:",rc);
|
|
#endif
|
|
}
|
|
|
|
|
|
/* Create a triple store from a file */
|
|
static int
|
|
rccompile(const char* path)
|
|
{
|
|
int ret = NC_NOERR;
|
|
NClist* rc = NCD4_globalstate->rc.rc;
|
|
char* contents = NULL;
|
|
NCbytes* tmp = ncbytesnew();
|
|
NCURI* uri = NULL;
|
|
char* nextline = NULL;
|
|
|
|
if((ret=NCD4_readfile(path,tmp))) {
|
|
nclog(NCLOGERR, "Could not open configuration file: %s",path);
|
|
goto done;
|
|
}
|
|
contents = ncbytesextract(tmp);
|
|
if(contents == NULL) contents = strdup("");
|
|
NCD4_rcfree(rc); /* clear out any old data */
|
|
rc = nclistnew();
|
|
nextline = contents;
|
|
for(;;) {
|
|
char* line;
|
|
char* key;
|
|
char* value;
|
|
size_t llen;
|
|
NCD4triple* triple;
|
|
|
|
line = rcreadline(&nextline);
|
|
if(line == NULL) break; /* done */
|
|
rctrim(line); /* trim leading and trailing blanks */
|
|
if(line[0] == '#') continue; /* comment */
|
|
if((llen=strlen(line)) == 0) continue; /* empty line */
|
|
triple = (NCD4triple*)calloc(1,sizeof(NCD4triple));
|
|
if(triple == NULL) {ret = NC_ENOMEM; goto done;}
|
|
if(line[0] == LTAG) {
|
|
char* url = ++line;
|
|
char* rtag = strchr(line,RTAG);
|
|
if(rtag == NULL) {
|
|
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
|
|
continue;
|
|
}
|
|
line = rtag + 1;
|
|
*rtag = '\0';
|
|
/* compile the url and pull out the host */
|
|
if(uri) ncurifree(uri);
|
|
if(ncuriparse(url,&uri) != NCU_OK) {
|
|
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
|
|
continue;
|
|
}
|
|
ncbytesclear(tmp);
|
|
ncbytescat(tmp,uri->host);
|
|
if(uri->port != NULL) {
|
|
ncbytesappend(tmp,':');
|
|
ncbytescat(tmp,uri->port);
|
|
}
|
|
ncbytesnull(tmp);
|
|
triple->host = ncbytesextract(tmp);
|
|
}
|
|
/* split off key and value */
|
|
key=line;
|
|
value = strchr(line, '=');
|
|
if(value == NULL)
|
|
value = line + strlen(line);
|
|
else {
|
|
*value = '\0';
|
|
value++;
|
|
}
|
|
triple->key = strdup(key);
|
|
triple->value = strdup(value);
|
|
rctrim(triple->key);
|
|
rctrim(triple->value);
|
|
#ifdef D4DEBUG
|
|
fprintf(stderr,"rc: host=%s key=%s value=%s\n",
|
|
triple->host,triple->key,triple->valu);
|
|
#endif
|
|
nclistpush(rc,triple);
|
|
triple = NULL;
|
|
}
|
|
rcorder(rc);
|
|
|
|
done:
|
|
ncurifree(uri);
|
|
ncbytesfree(tmp);
|
|
return THROW(ret);
|
|
}
|
|
|
|
/* locate, read and compile the rc file, if any */
|
|
int
|
|
NCD4_rcload(void)
|
|
{
|
|
int ret = NC_NOERR;
|
|
char* path = NULL;
|
|
|
|
if(NCD4_globalstate->rc.ignore) {
|
|
nclog(NCLOGDBG,"No runtime configuration file specified; continuing");
|
|
return THROW(NC_NOERR);
|
|
}
|
|
if(NCD4_globalstate->rc.loaded) return THROW(NC_NOERR);
|
|
|
|
/* locate the configuration files in the following order:
|
|
1. specified by NCD4_set_rcfile
|
|
2. set by DAPRCFILE env variable
|
|
3. '.'
|
|
4. $HOME
|
|
*/
|
|
if(NCD4_globalstate->rc.rcfile != NULL) { /* always use this */
|
|
path = strdup(NCD4_globalstate->rc.rcfile);
|
|
} else if(getenv(RCFILEENV) != NULL && strlen(getenv(RCFILEENV)) > 0) {
|
|
path = strdup(getenv(RCFILEENV));
|
|
} else {
|
|
char** rcname;
|
|
int found = 0;
|
|
for(rcname=rcfilenames;!found && *rcname;rcname++) {
|
|
ret = rcsearch(".",*rcname,&path);
|
|
if(ret == NC_NOERR && path == NULL) /* try $HOME */
|
|
ret = rcsearch(NCD4_globalstate->home,*rcname,&path);
|
|
if(ret != NC_NOERR)
|
|
goto done;
|
|
if(path != NULL)
|
|
found = 1;
|
|
}
|
|
}
|
|
if(path == NULL) {
|
|
nclog(NCLOGDBG,"Cannot find runtime configuration file; continuing");
|
|
} else {
|
|
#ifdef D4DEBUG
|
|
fprintf(stderr, "RC file: %s\n", path);
|
|
#endif
|
|
if((ret=rccompile(path))) {
|
|
nclog(NCLOGERR, "Error parsing %s\n",path);
|
|
goto done;
|
|
}
|
|
}
|
|
done:
|
|
NCD4_globalstate->rc.loaded = 1; /* even if not exists */
|
|
nullfree(path);
|
|
return THROW(ret);
|
|
}
|
|
|
|
static int
|
|
rcsetinfocurlflag(NCD4INFO* info, const char* flag, const char* value)
|
|
{
|
|
int ret = NC_NOERR;
|
|
if(value == NULL) goto done;
|
|
if(strcmp(flag,"HTTP.DEFLATE")==0) {
|
|
if(atoi(value)) info->curl->curlflags.compress = 1;
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.DEFLATE: %ld", info->curlflags.compress);
|
|
#endif
|
|
}
|
|
if(strcmp(flag,"HTTP.VERBOSE")==0) {
|
|
if(atoi(value)) info->curl->curlflags.verbose = 1;
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.VERBOSE: %ld", info->curl->curlflags.verbose);
|
|
#endif
|
|
}
|
|
if(strcmp(flag,"HTTP.TIMEOUT")==0) {
|
|
if(atoi(value)) info->curl->curlflags.timeout = atoi(value);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.TIMEOUT: %ld", info->curl->curlflags.timeout);
|
|
#endif
|
|
}
|
|
if(strcmp(flag,"HTTP.USERAGENT")==0) {
|
|
if(atoi(value)) info->curl->curlflags.useragent = strdup(value);
|
|
MEMCHECK(info->curl->curlflags.useragent);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.USERAGENT: %s", info->curl->curlflags.useragent);
|
|
#endif
|
|
}
|
|
if(
|
|
strcmp(flag,"HTTP.COOKIEFILE")==0
|
|
|| strcmp(flag,"HTTP.COOKIE_FILE")==0
|
|
|| strcmp(flag,"HTTP.COOKIEJAR")==0
|
|
|| strcmp(flag,"HTTP.COOKIE_JAR")==0
|
|
) {
|
|
nullfree(info->curl->curlflags.cookiejar);
|
|
info->curl->curlflags.cookiejar = strdup(value);
|
|
MEMCHECK(info->curl->curlflags.cookiejar);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.COOKIEJAR: %s", info->curl->curlflags.cookiejar);
|
|
#endif
|
|
}
|
|
if(strcmp(flag,"HTTP.PROXY_SERVER")==0) {
|
|
ret = NCD4_parseproxy(info,value);
|
|
if(ret != NC_NOERR) goto done;
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.PROXY_SERVER: %s", value);
|
|
#endif
|
|
}
|
|
if(strcmp(flag,"HTTP.SSL.VALIDATE")==0) {
|
|
if(atoi(value)) {
|
|
info->curl->ssl.verifypeer = 1;
|
|
info->curl->ssl.verifyhost = 1;
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.SSL.VALIDATE: %ld", 1);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.SSL.CERTIFICATE")==0) {
|
|
nullfree(info->curl->ssl.certificate);
|
|
info->curl->ssl.certificate = strdup(value);
|
|
MEMCHECK(info->curl->ssl.certificate);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.SSL.CERTIFICATE: %s", info->curl->ssl.certificate);
|
|
#endif
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.SSL.KEY")==0) {
|
|
nullfree(info->curl->ssl.key);
|
|
info->curl->ssl.key = strdup(value);
|
|
MEMCHECK(info->curl->ssl.key);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.SSL.KEY: %s", info->curl->ssl.key);
|
|
#endif
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.SSL.KEYPASSWORD")==0) {
|
|
nullfree(info->curl->ssl.keypasswd) ;
|
|
info->curl->ssl.keypasswd = strdup(value);
|
|
MEMCHECK(info->curl->ssl.keypasswd);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.SSL.KEYPASSWORD: %s", info->curl->ssl.keypasswd);
|
|
#endif
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.SSL.CAINFO")==0) {
|
|
nullfree(info->curl->ssl.cainfo) ;
|
|
info->curl->ssl.cainfo = strdup(value);
|
|
MEMCHECK(info->curl->ssl.cainfo);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.SSL.CAINFO: %s", info->curl->ssl.cainfo);
|
|
#endif
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.SSL.CAPATH")==0) {
|
|
nullfree(info->curl->ssl.capath) ;
|
|
info->curl->ssl.capath = strdup(value);
|
|
MEMCHECK(info->curl->ssl.capath);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.SSL.CAPATH: %s", info->curl->ssl.capath);
|
|
#endif
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.SSL.VERIFYPEER")==0) {
|
|
const char* s = value;
|
|
int tf = 0;
|
|
if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0)
|
|
tf = 0;
|
|
else if(strcmp(s,"1")==0 || strcasecmp(s,"true")==0)
|
|
tf = 1;
|
|
else
|
|
tf = 1; /* default if not null */
|
|
info->curl->ssl.verifypeer = tf;
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.SSL.VERIFYPEER: %d", info->curl->ssl.verifypeer);
|
|
#endif
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.NETRC")==0) {
|
|
nullfree(info->curl->curlflags.netrc);
|
|
info->curl->curlflags.netrc = strdup(value);
|
|
MEMCHECK(info->curl->curlflags.netrc);
|
|
#ifdef D4DEBUG
|
|
nclog(NCLOGNOTE,"HTTP.NETRC: %s", info->curl->curlflags.netrc);
|
|
#endif
|
|
}
|
|
|
|
if(strcmp(flag,"HTTP.CREDENTIALS.USERPASSWORD")==0) {
|
|
nullfree(info->curl->creds.userpwd);
|
|
info->curl->creds.userpwd = strdup(value);
|
|
MEMCHECK(info->curl->creds.userpwd);
|
|
}
|
|
|
|
done:
|
|
return THROW(ret);
|
|
|
|
nomem:
|
|
return THROW(NC_ENOMEM);
|
|
}
|
|
|
|
int
|
|
NCD4_rcprocess(NCD4INFO* info)
|
|
{
|
|
int ret = NC_NOERR;
|
|
char userpwd[NC_MAX_PATH];
|
|
char hostport[NC_MAX_PATH];
|
|
char* url_userpwd = userpwd; /* WATCH OUT: points to previous variable */
|
|
char* url_hostport = hostport; /* WATCH OUT: points to previous variable */
|
|
NCURI* uri = info->uri;
|
|
|
|
assert (NCD4_globalstate != NULL);
|
|
|
|
if(!NCD4_globalstate->rc.loaded)
|
|
NCD4_rcload();
|
|
|
|
/* Note, we still must do this function even if
|
|
NCD4_globalstate->rc.ignore is set in order
|
|
to getinfo e.g. user:pwd from url
|
|
*/
|
|
|
|
if(uri != NULL) {
|
|
NCD4_userpwd(uri,url_userpwd,sizeof(userpwd));
|
|
NCD4_hostport(uri,url_hostport,sizeof(hostport));
|
|
} else {
|
|
url_hostport = NULL;
|
|
url_userpwd = NULL;
|
|
}
|
|
|
|
rcsetinfocurlflag(info,"HTTP.DEFLATE",
|
|
NCD4_rclookup("HTTP.DEFLATE",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.VERBOSE",
|
|
NCD4_rclookup("HTTP.VERBOSE",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.TIMEOUT",
|
|
NCD4_rclookup("HTTP.TIMEOUT",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.USERAGENT",
|
|
NCD4_rclookup("HTTP.USERAGENT",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.COOKIEFILE",
|
|
NCD4_rclookup("HTTP.COOKIEFILE",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.COOKIE_FILE",
|
|
NCD4_rclookup("HTTP.COOKIE_FILE",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.COOKIEJAR",
|
|
NCD4_rclookup("HTTP.COOKIEJAR",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.COOKIE_JAR",
|
|
NCD4_rclookup("HTTP.COOKIE_JAR",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.PROXY_SERVER",
|
|
NCD4_rclookup("HTTP.PROXY_SERVER",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.SSL.VALIDATE",
|
|
NCD4_rclookup("HTTP.SSL.VALIDATE",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.SSL.CERTIFICATE",
|
|
NCD4_rclookup("HTTP.SSL.CERTIFICATE",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.SSL.KEY",
|
|
NCD4_rclookup("HTTP.SSL.KEY",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.SSL.KEYPASSWORD",
|
|
NCD4_rclookup("HTTP.SSL.KEYPASSWORD",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.SSL.CAINFO",
|
|
NCD4_rclookup("HTTP.SSL.CAINFO",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.SSL.CAPATH",
|
|
NCD4_rclookup("HTTP.SSL.CAPATH",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.SSL.VERIFYPEER",
|
|
NCD4_rclookup("HTTP.SSL.VERIFYPEER",url_hostport));
|
|
rcsetinfocurlflag(info,"HTTP.NETRC",
|
|
NCD4_rclookup("HTTP.NETRC",url_hostport));
|
|
{ /* Handle various cases for user + password */
|
|
/* First, see if the user+pwd was in the original url */
|
|
char* userpwd = NULL;
|
|
char* user = NULL;
|
|
char* pwd = NULL;
|
|
if(url_userpwd != NULL)
|
|
userpwd = url_userpwd;
|
|
else {
|
|
user = NCD4_rclookup("HTTP.CREDENTIALS.USER",url_hostport);
|
|
pwd = NCD4_rclookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
|
|
userpwd = NCD4_rclookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
|
|
}
|
|
if(userpwd == NULL && user != NULL && pwd != NULL) {
|
|
char creds[NC_MAX_PATH];
|
|
strncpy(creds,user,sizeof(creds));
|
|
strncat(creds,":",sizeof(creds));
|
|
strncat(creds,pwd,sizeof(creds));
|
|
rcsetinfocurlflag(info,"HTTP.USERPASSWORD",creds);
|
|
} else if(userpwd != NULL)
|
|
rcsetinfocurlflag(info,"HTTP.USERPASSWORD",userpwd);
|
|
}
|
|
|
|
return THROW(ret);
|
|
}
|
|
|
|
static struct NCD4triple*
|
|
rclocate(char* key, char* hostport)
|
|
{
|
|
int i,found;
|
|
NClist* rc = NCD4_globalstate->rc.rc;
|
|
NCD4triple* triple = NULL;
|
|
|
|
if(NCD4_globalstate->rc.ignore)
|
|
return NULL;
|
|
if(!NCD4_globalstate->rc.loaded)
|
|
NCD4_rcload();
|
|
|
|
if(key == NULL || rc == NULL) return NULL;
|
|
if(hostport == NULL) hostport = "";
|
|
|
|
for(found=0,i=0;i<nclistlength(rc);i++) {
|
|
triple = (NCD4triple*)nclistget(rc,i);
|
|
size_t hplen = strlen(triple->host);
|
|
int t;
|
|
if(strcmp(key,triple->key) != 0) continue; /* keys do not match */
|
|
/* If the triple entry has no url, then use it
|
|
(because we have checked all other cases)*/
|
|
if(hplen == 0) {found=1;break;}
|
|
/* do hostport match */
|
|
t = strcmp(hostport,triple->host);
|
|
if(t == 0) {found=1; break;}
|
|
}
|
|
return (found?triple:NULL);
|
|
}
|
|
|
|
char*
|
|
NCD4_rclookup(char* key, char* hostport)
|
|
{
|
|
struct NCD4triple* triple = rclocate(key,hostport);
|
|
return (triple == NULL ? NULL : triple->value);
|
|
}
|
|
|
|
#ifdef D4DEBUG
|
|
static void
|
|
storedump(char* msg, NClist* triples)
|
|
{
|
|
int i;
|
|
|
|
if(msg != NULL) fprintf(stderr,"%s\n",msg);
|
|
if(triples == NULL || nclistlength(triples)==0) {
|
|
fprintf(stderr,"<EMPTY>\n");
|
|
return;
|
|
}
|
|
for(i=0;i<nclistlength(triples);i++) {
|
|
NCD4triple* t = (NCD4triple*)nclistget(triples,i);
|
|
fprintf(stderr,"\t%s\t%s\t%s\n",
|
|
(t->host == NULL || strlen(t->host)==0?"--":t->host),t->key,t->value);
|
|
}
|
|
fflush(stderr);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Prefix must end in '/'
|
|
*/
|
|
static
|
|
int
|
|
rcsearch(const char* prefix, const char* rcname, char** pathp)
|
|
{
|
|
char* path = NULL;
|
|
FILE* f = NULL;
|
|
int plen = strlen(prefix);
|
|
int rclen = strlen(rcname);
|
|
int ret = NC_NOERR;
|
|
|
|
size_t pathlen = plen+rclen+1; /*+1 for '/' */
|
|
path = (char*)malloc(pathlen+1); /* +1 for nul*/
|
|
if(path == NULL) {ret = NC_ENOMEM; goto done;}
|
|
strncpy(path,prefix,pathlen);
|
|
strncat(path,"/",pathlen);
|
|
strncat(path,rcname,pathlen);
|
|
/* see if file is readable */
|
|
f = fopen(path,"r");
|
|
if(f != NULL)
|
|
nclog(NCLOGDBG, "Found rc file=%s",path);
|
|
done:
|
|
if(f == NULL || ret != NC_NOERR) {
|
|
nullfree(path);
|
|
path = NULL;
|
|
}
|
|
if(f != NULL)
|
|
fclose(f);
|
|
if(pathp != NULL)
|
|
*pathp = path;
|
|
else {
|
|
nullfree(path);
|
|
path = NULL;
|
|
}
|
|
return THROW(ret);
|
|
}
|
|
|
|
void
|
|
NCD4_rcfree(NClist* rc)
|
|
{
|
|
int i;
|
|
for(i=0;i<nclistlength(rc);i++) {
|
|
NCD4triple* t = (NCD4triple*)nclistget(rc,i);
|
|
nullfree(t->host);
|
|
nullfree(t->key);
|
|
nullfree(t->value);
|
|
free(t);
|
|
}
|
|
nclistfree(rc);
|
|
}
|
|
|
|
int
|
|
NCD4_parseproxy(NCD4INFO* info, const char* surl)
|
|
{
|
|
int ret = NC_NOERR;
|
|
NCURI* uri = NULL;
|
|
if(surl == NULL || strlen(surl) == 0)
|
|
return THROW(NC_NOERR); /* nothing there*/
|
|
if(ncuriparse(surl,&uri) != NCU_OK)
|
|
return THROW(NC_EURL);
|
|
info->curl->proxy.userpwd = extract_credentials(uri);
|
|
info->curl->proxy.host = strdup(uri->host);
|
|
if(uri->port != NULL)
|
|
info->curl->proxy.port = atoi(uri->port);
|
|
else
|
|
info->curl->proxy.port = 80;
|
|
return THROW(ret);
|
|
}
|
|
|
|
/* Caller must free result_url */
|
|
static char*
|
|
extract_credentials(NCURI* url)
|
|
{
|
|
char tmp[NC_MAX_PATH];
|
|
if(url->user == NULL || url->password == NULL)
|
|
return NULL;
|
|
NCD4_userpwd(url,tmp,sizeof(tmp));
|
|
return strdup(tmp);
|
|
}
|
|
|
|
int
|
|
NCD4_rcdefault(NCD4INFO* info)
|
|
{
|
|
int ret = NC_NOERR;
|
|
const char** p;
|
|
for(p=RCDEFAULTFLAGS;*p;p+=2) {
|
|
ret = rcsetinfocurlflag(info,p[0],p[1]);
|
|
if(ret) {
|
|
nclog(NCLOGERR, "RC file defaulting failed for: %s=%s",p[0],p[1]);
|
|
}
|
|
}
|
|
return THROW(ret);
|
|
}
|