mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-02-05 16:20:10 +08:00
3db4f013bf
Specific changes: 1. Add dap4 code: libdap4 and dap4_test. Note that until the d4ts server problem is solved, dap4 is turned off. 2. Modify various files to support dap4 flags: configure.ac, Makefile.am, CMakeLists.txt, etc. 3. Add nc_test/test_common.sh. This centralizes the handling of the locations of various things in the build tree: e.g. where is ncgen.exe located. See nc_test/test_common.sh for details. 4. Modify .sh files to use test_common.sh 5. Obsolete separate oc2 by moving it to be part of netcdf-c. This means replacing code with netcdf-c equivalents. 5. Add --with-testserver to configure.ac to allow override of the servers to be used for --enable-dap-remote-tests. 6. There were multiple versions of nctypealignment code. Try to centralize in libdispatch/doffset.c and include/ncoffsets.h 7. Add a unit test for the ncuri code because of its complexity. 8. Move the findserver code out of libdispatch and into a separate, self contained program in ncdap_test and dap4_test. 9. Move the dispatch header files (nc{3,4}dispatch.h) to .../include because they are now shared by modules. 10. Revamp the handling of TOPSRCDIR and TOPBUILDDIR for shell scripts. 11. Make use of MREMAP if available 12. Misc. minor changes e.g. - #include <config.h> -> #include "config.h" - Add some no-install headers to /include - extern -> EXTERNL and vice versa as needed - misc header cleanup - clean up checking for misc. unix vs microsoft functions 13. Change copyright decls in some files to point to LICENSE file. 14. Add notes to RELEASENOTES.md
622 lines
17 KiB
C
622 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 void storedump(char* msg, NClist* triples);
|
|
static int rcsetinfocurlflag(NCD4INFO*, const char* flag, const char* value);
|
|
|
|
/* 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);
|
|
}
|
|
}
|
|
}
|
|
storedump("reorder:",rc);
|
|
}
|
|
|
|
|
|
/* 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);
|
|
}
|
|
|
|
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",
|
|
(strlen(t->host)==0?"--":t->host),t->key,t->value);
|
|
}
|
|
fflush(stderr);
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|