mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-09 08:11:38 +08:00
715a6fe5eb
were added to provide a path name converter from e.g. cygwin paths to e.g. windows paths. This is necessary because the shell scripts may produce cygwin paths, but the code may have been compiled with Visual Studio. Similar issues arise with Mingw. At appropriate places, and if using Visual Studio or Mingw, I added calls to the path conversion code. Apparently I forgot to find all the places where this conversion was needed. So this pr does the following: 1. Push the calls to the converter to the various libXXX directories and out of libdispatch/dfile.c. 2. Add conversion calls to other parts of the code like oc2. I also turns out that conversion code in dapcvt.c had a bug when handling DAP Byte type under visual studio. Notes: 1. there may still be places I missed that need to do path conversion. 2. need to make sure that calls to e.g. H5open also use converted path.
758 lines
22 KiB
C
758 lines
22 KiB
C
/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
|
|
See the COPYRIGHT file for more information. */
|
|
|
|
#include "config.h"
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "netcdf.h"
|
|
#include "ocinternal.h"
|
|
#include "ocdebug.h"
|
|
#include "nclog.h"
|
|
#include "ncwinpath.h"
|
|
|
|
#define OCRCFILEENV "DAPRCFILE"
|
|
|
|
#define RTAG ']'
|
|
#define LTAG '['
|
|
|
|
#define TRIMCHARS " \t\r\n"
|
|
|
|
static OCerror rc_search(const char* prefix, const char* rcfile, char** pathp);
|
|
|
|
static int rcreadline(FILE* f, char* more, int morelen);
|
|
static void rctrim(char* text);
|
|
static char* combinecredentials(const char* user, const char* pwd);
|
|
|
|
static void storedump(char* msg, struct OCTriple*, int ntriples);
|
|
|
|
/* Define default rc files and aliases, also defines search order*/
|
|
static char* rcfilenames[] = {".daprc",".dodsrc",NULL};
|
|
|
|
/* The Username and password are in the URL if the URL is of the form:
|
|
* http://<name>:<passwd>@<host>/....
|
|
*/
|
|
static int
|
|
occredentials_in_url(const char *url)
|
|
{
|
|
char *pos = strstr(url, "http://");
|
|
if (!pos)
|
|
return 0;
|
|
pos += 7;
|
|
if (strchr(pos, '@') && strchr(pos, ':'))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
static OCerror
|
|
ocextract_credentials(const char *url, char **userpwd, char **result_url)
|
|
{
|
|
NCURI* parsed = NULL;
|
|
if(ncuriparse(url,&parsed) != NCU_OK)
|
|
return OCTHROW(OC_EBADURL);
|
|
if(parsed->user != NULL || parsed->password == NULL) {
|
|
ncurifree(parsed);
|
|
return OCTHROW(OC_EBADURL);
|
|
}
|
|
if(userpwd) *userpwd = combinecredentials(parsed->user,parsed->password);
|
|
ncurifree(parsed);
|
|
return OC_NOERR;
|
|
}
|
|
|
|
char*
|
|
occombinehostport(const NCURI* uri)
|
|
{
|
|
char* hp;
|
|
int len = 0;
|
|
|
|
if(uri->host == NULL)
|
|
return NULL;
|
|
else
|
|
len += strlen(uri->host);
|
|
if(uri->port != NULL)
|
|
len += strlen(uri->port);
|
|
hp = (char*)malloc(len+1);
|
|
if(hp == NULL)
|
|
return NULL;
|
|
if(uri->port == NULL)
|
|
occopycat(hp,len+1,1,uri->host);
|
|
else
|
|
occopycat(hp,len+1,3,uri->host,":",uri->port);
|
|
return hp;
|
|
}
|
|
|
|
static char*
|
|
combinecredentials(const char* user, const char* pwd)
|
|
{
|
|
int userPassSize;
|
|
char *userPassword;
|
|
|
|
if(user == NULL) user = "";
|
|
if(pwd == NULL) pwd = "";
|
|
|
|
userPassSize = strlen(user) + strlen(pwd) + 2;
|
|
userPassword = malloc(sizeof(char) * userPassSize);
|
|
if (!userPassword) {
|
|
nclog(NCLOGERR,"Out of Memory\n");
|
|
return NULL;
|
|
}
|
|
occopycat(userPassword,userPassSize-1,3,user,":",pwd);
|
|
return userPassword;
|
|
}
|
|
|
|
static int
|
|
rcreadline(FILE* f, char* more, int morelen)
|
|
{
|
|
int i = 0;
|
|
int c = getc(f);
|
|
if(c < 0) return 0;
|
|
for(;;) {
|
|
if(i < morelen) /* ignore excess characters */
|
|
more[i++]=c;
|
|
c = getc(f);
|
|
if(c < 0) break; /* eof */
|
|
if(c == '\n') break; /* eol */
|
|
}
|
|
/* null terminate more */
|
|
more[i] = '\0';
|
|
return 1;
|
|
}
|
|
|
|
/* 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 */
|
|
}
|
|
memmove(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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
ocparseproxy(OCstate* state, char* v)
|
|
{
|
|
/* Do not free these; they are pointers into v; free v instead */
|
|
char *host_pos = NULL;
|
|
char *port_pos = NULL;
|
|
if(v == NULL || strlen(v) == 0)
|
|
return OC_NOERR; /* nothing there*/
|
|
if (occredentials_in_url(v)) {
|
|
char *result_url = NULL;
|
|
ocextract_credentials(v, &state->proxy.userpwd, &result_url);
|
|
v = result_url;
|
|
}
|
|
/* allocating a bit more than likely needed ... */
|
|
host_pos = strstr(v, "http://");
|
|
if (host_pos)
|
|
host_pos += strlen("http://");
|
|
else
|
|
host_pos = v;
|
|
port_pos = strchr(host_pos, ':');
|
|
if (port_pos) {
|
|
size_t host_len;
|
|
char *port_sep = port_pos;
|
|
port_pos++;
|
|
*port_sep = '\0';
|
|
host_len = strlen(host_pos);
|
|
state->proxy.host = malloc(sizeof(char) * host_len + 1);
|
|
if (state->proxy.host == NULL)
|
|
return OCTHROW(OC_ENOMEM);
|
|
strncpy(state->proxy.host, host_pos, host_len);
|
|
state->proxy.host[host_len] = '\0';
|
|
state->proxy.port = atoi(port_pos);
|
|
} else {
|
|
size_t host_len = strlen(host_pos);
|
|
state->proxy.host = malloc(sizeof(char) * host_len + 1);
|
|
if (state->proxy.host == NULL)
|
|
return OCTHROW(OC_ENOMEM);
|
|
strncpy(state->proxy.host, host_pos, host_len);
|
|
state->proxy.host[host_len] = '\0';
|
|
state->proxy.port = 80;
|
|
}
|
|
#if 0
|
|
state->proxy.host[v_len] = '\0';
|
|
state->proxy.port = atoi(v);
|
|
s_len = strlen(v);
|
|
state->proxy.user = malloc(sizeof(char) * s_len + 1);
|
|
if (state->proxy.user == NULL)
|
|
return OC_ENOMEM;
|
|
strncpy(state->proxy.user, v, s_len);
|
|
state->proxy.user[s_len] = '\0';
|
|
p_len = strlen(v);
|
|
state->proxy.password = malloc(sizeof(char) * p_len + 1);
|
|
if (state->proxy.password == NULL)
|
|
return OCTHROW(OC_ENOMEM);
|
|
strncpy(state->proxy.password, v, p_len);
|
|
state->proxy.password[p_len] = '\0';
|
|
#endif /*0*/
|
|
if (ocdebug > 1) {
|
|
nclog(NCLOGNOTE,"host name: %s", state->proxy.host);
|
|
#ifdef INSECURE
|
|
nclog(NCLOGNOTE,"user+pwd: %s", state->proxy.userpwd);
|
|
#endif
|
|
nclog(NCLOGNOTE,"port number: %d", state->proxy.port);
|
|
}
|
|
if(v) free(v);
|
|
return OC_NOERR;
|
|
}
|
|
|
|
/* insertion sort the triplestore based on url */
|
|
static void
|
|
sorttriplestore(struct OCTriplestore* store)
|
|
{
|
|
int i, nsorted;
|
|
struct OCTriple* sorted = NULL;
|
|
|
|
if(store == NULL) return; /* nothing to sort */
|
|
if(store->ntriples <= 1) return; /* nothing to sort */
|
|
if(ocdebug > 2)
|
|
storedump("initial:",store->triples,store->ntriples);
|
|
|
|
sorted = (struct OCTriple*)malloc(sizeof(struct OCTriple)*store->ntriples);
|
|
if(sorted == NULL) {
|
|
nclog(NCLOGERR,"sorttriplestore: out of memory");
|
|
return;
|
|
}
|
|
|
|
nsorted = 0;
|
|
while(nsorted < store->ntriples) {
|
|
int largest;
|
|
/* locate first non killed entry */
|
|
for(largest=0;largest<store->ntriples;largest++) {
|
|
if(store->triples[largest].key[0] != '\0') break;
|
|
}
|
|
OCASSERT(store->triples[largest].key[0] != '\0');
|
|
for(i=0;i<store->ntriples;i++) {
|
|
if(store->triples[i].key[0] != '\0') { /* avoid empty slots */
|
|
int lexorder = strcmp(store->triples[i].host,store->triples[largest].host);
|
|
int leni = strlen(store->triples[i].host);
|
|
int lenlarge = strlen(store->triples[largest].host);
|
|
/* this defines the ordering */
|
|
if(leni == 0 && lenlarge == 0) continue; /* if no urls, then leave in order */
|
|
if(leni != 0 && lenlarge == 0) largest = i;
|
|
else if(lexorder > 0) largest = i;
|
|
}
|
|
}
|
|
/* Move the largest entry */
|
|
OCASSERT(store->triples[largest].key[0] != 0);
|
|
sorted[nsorted] = store->triples[largest];
|
|
store->triples[largest].key[0] = '\0'; /* kill entry */
|
|
nsorted++;
|
|
if(ocdebug > 2)
|
|
storedump("pass:",sorted,nsorted);
|
|
}
|
|
|
|
memcpy((void*)store->triples,(void*)sorted,sizeof(struct OCTriple)*nsorted);
|
|
free(sorted);
|
|
|
|
if(ocdebug > 1)
|
|
storedump("final .rc order:",store->triples,store->ntriples);
|
|
}
|
|
|
|
/* Create a triple store from a file */
|
|
static int
|
|
ocrc_compile(const char* path)
|
|
{
|
|
char line0[MAXRCLINESIZE+1];
|
|
FILE *in_file = NULL;
|
|
int linecount = 0;
|
|
struct OCTriplestore* ocrc = &ocglobalstate.rc.daprc;
|
|
|
|
ocrc->ntriples = 0; /* reset; nothing to free */
|
|
|
|
in_file = NCfopen(path, "r"); /* Open the file to read it */
|
|
if (in_file == NULL) {
|
|
nclog(NCLOGERR, "Could not open configuration file: %s",path);
|
|
return OC_EPERM;
|
|
}
|
|
|
|
for(;;) {
|
|
char *line,*key,*value;
|
|
int c;
|
|
if(!rcreadline(in_file,line0,sizeof(line0))) break;
|
|
linecount++;
|
|
if(linecount >= MAXRCLINES) {
|
|
nclog(NCLOGERR, ".rc has too many lines");
|
|
return 0;
|
|
}
|
|
line = line0;
|
|
/* check for comment */
|
|
c = line[0];
|
|
if (c == '#') continue;
|
|
rctrim(line); /* trim leading and trailing blanks */
|
|
if(strlen(line) == 0) continue;
|
|
if(strlen(line) >= MAXRCLINESIZE) {
|
|
nclog(NCLOGERR, "%s line too long: %s",path,line0);
|
|
continue; /* ignore it */
|
|
}
|
|
/* setup */
|
|
ocrc->triples[ocrc->ntriples].host[0] = '\0';
|
|
ocrc->triples[ocrc->ntriples].key[0] = '\0';
|
|
ocrc->triples[ocrc->ntriples].value[0] = '\0';
|
|
if(line[0] == LTAG) {
|
|
NCURI* uri;
|
|
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(ncuriparse(url,&uri) != NCU_OK) {
|
|
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
|
|
continue;
|
|
}
|
|
strncpy(ocrc->triples[ocrc->ntriples].host,uri->host,MAXRCLINESIZE-1);
|
|
if(uri->port != NULL) {
|
|
strncat(ocrc->triples[ocrc->ntriples].host,":",MAXRCLINESIZE-1);
|
|
strncat(ocrc->triples[ocrc->ntriples].host,uri->port,MAXRCLINESIZE-1);
|
|
}
|
|
ncurifree(uri);
|
|
}
|
|
/* split off key and value */
|
|
key=line;
|
|
value = strchr(line, '=');
|
|
if(value == NULL)
|
|
value = line + strlen(line);
|
|
else {
|
|
*value = '\0';
|
|
value++;
|
|
}
|
|
strncpy(ocrc->triples[ocrc->ntriples].key,key,MAXRCLINESIZE-1);
|
|
if(*value == '\0')
|
|
strcpy(ocrc->triples[ocrc->ntriples].value,"1");/*dfalt*/
|
|
else
|
|
strncpy(ocrc->triples[ocrc->ntriples].value,value,(MAXRCLINESIZE-1));
|
|
rctrim( ocrc->triples[ocrc->ntriples].key);
|
|
rctrim( ocrc->triples[ocrc->ntriples].value);
|
|
OCDBG2("rc: key=%s value=%s",
|
|
ocrc->triples[ocrc->ntriples].key,
|
|
ocrc->triples[ocrc->ntriples].value);
|
|
ocrc->ntriples++;
|
|
}
|
|
fclose(in_file);
|
|
sorttriplestore(&ocglobalstate.rc.daprc);
|
|
return 1;
|
|
}
|
|
|
|
/* read and compile the rc file, if any */
|
|
OCerror
|
|
ocrc_load(void)
|
|
{
|
|
OCerror stat = OC_NOERR;
|
|
char* path = NULL;
|
|
|
|
if(ocglobalstate.rc.ignore) {
|
|
nclog(NCLOGDBG,"No runtime configuration file specified; continuing");
|
|
return OC_NOERR;
|
|
}
|
|
if(ocglobalstate.rc.loaded) return OC_NOERR;
|
|
|
|
/* locate the configuration files in the following order:
|
|
1. specified by set_rcfile
|
|
2. set by DAPRCFILE env variable
|
|
3. '.'
|
|
4. $HOME
|
|
*/
|
|
if(ocglobalstate.rc.rcfile != NULL) { /* always use this */
|
|
path = strdup(ocglobalstate.rc.rcfile);
|
|
} else if(getenv(OCRCFILEENV) != NULL && strlen(getenv(OCRCFILEENV)) > 0) {
|
|
path = strdup(getenv(OCRCFILEENV));
|
|
} else {
|
|
char** rcname;
|
|
int found = 0;
|
|
for(rcname=rcfilenames;!found && *rcname;rcname++) {
|
|
stat = rc_search(".",*rcname,&path);
|
|
if(stat == OC_NOERR && path == NULL) /* try $HOME */
|
|
stat = rc_search(ocglobalstate.home,*rcname,&path);
|
|
if(stat != OC_NOERR)
|
|
goto done;
|
|
if(path != NULL)
|
|
found = 1;
|
|
}
|
|
}
|
|
if(path == NULL) {
|
|
nclog(NCLOGDBG,"Cannot find runtime configuration file; continuing");
|
|
} else {
|
|
if(ocdebug > 0)
|
|
fprintf(stderr, "RC file: %s\n", path);
|
|
if(ocrc_compile(path) == 0) {
|
|
nclog(NCLOGERR, "Error parsing %s\n",path);
|
|
stat = OC_ERCFILE;
|
|
}
|
|
}
|
|
done:
|
|
ocglobalstate.rc.loaded = 1; /* even if not exists */
|
|
if(path != NULL)
|
|
free(path);
|
|
return stat;
|
|
}
|
|
|
|
OCerror
|
|
ocrc_process(OCstate* state)
|
|
{
|
|
OCerror stat = OC_NOERR;
|
|
char* value = NULL;
|
|
NCURI* uri = state->uri;
|
|
char* url_userpwd = NULL;
|
|
char* url_hostport = NULL;
|
|
|
|
if(!ocglobalstate.initialized)
|
|
ocinternalinitialize();
|
|
if(!ocglobalstate.rc.loaded)
|
|
ocrc_load();
|
|
/* Note, we still must do this function even if
|
|
ocglobalstate.rc.ignore is set in order
|
|
to getinfo e.g. user:pwd from url
|
|
*/
|
|
|
|
url_userpwd = combinecredentials(uri->user,uri->password);
|
|
url_hostport = occombinehostport(uri);
|
|
if(url_hostport == NULL)
|
|
return OC_ENOMEM;
|
|
|
|
value = ocrc_lookup("HTTP.DEFLATE",url_hostport);
|
|
if(value != NULL) {
|
|
if(atoi(value)) state->curlflags.compress = 1;
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.DEFLATE: %ld", state->curlflags.compress);
|
|
}
|
|
if((value = ocrc_lookup("HTTP.VERBOSE",url_hostport)) != NULL) {
|
|
if(atoi(value)) state->curlflags.verbose = 1;
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.VERBOSE: %ld", state->curlflags.verbose);
|
|
}
|
|
if((value = ocrc_lookup("HTTP.TIMEOUT",url_hostport)) != NULL) {
|
|
if(atoi(value)) state->curlflags.timeout = atoi(value);
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.TIMEOUT: %ld", state->curlflags.timeout);
|
|
}
|
|
if((value = ocrc_lookup("HTTP.USERAGENT",url_hostport)) != NULL) {
|
|
if(atoi(value)) state->curlflags.useragent = strdup(value);
|
|
if(state->curlflags.useragent == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.USERAGENT: %s", state->curlflags.useragent);
|
|
}
|
|
|
|
if(
|
|
(value = ocrc_lookup("HTTP.COOKIEFILE",url_hostport))
|
|
|| (value = ocrc_lookup("HTTP.COOKIE_FILE",url_hostport))
|
|
|| (value = ocrc_lookup("HTTP.COOKIEJAR",url_hostport))
|
|
|| (value = ocrc_lookup("HTTP.COOKIE_JAR",url_hostport))
|
|
) {
|
|
state->curlflags.cookiejar = strdup(value);
|
|
if(state->curlflags.cookiejar == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.COOKIEJAR: %s", state->curlflags.cookiejar);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.PROXY_SERVER",url_hostport)) != NULL) {
|
|
stat = ocparseproxy(state,value);
|
|
if(stat != OC_NOERR) goto done;
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.PROXY_SERVER: %s", value);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.SSL.VALIDATE",url_hostport)) != NULL) {
|
|
if(atoi(value)) {
|
|
state->ssl.verifypeer = 1;
|
|
state->ssl.verifyhost = 1;
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.SSL.VALIDATE: %ld", 1);
|
|
}
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.SSL.CERTIFICATE",url_hostport)) != NULL) {
|
|
state->ssl.certificate = strdup(value);
|
|
if(state->ssl.certificate == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.SSL.CERTIFICATE: %s", state->ssl.certificate);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.SSL.KEY",url_hostport)) != NULL) {
|
|
state->ssl.key = strdup(value);
|
|
if(state->ssl.key == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.SSL.KEY: %s", state->ssl.key);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.SSL.KEYPASSWORD",url_hostport)) != NULL) {
|
|
state->ssl.keypasswd = strdup(value);
|
|
if(state->ssl.keypasswd == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.SSL.KEYPASSWORD: %s", state->ssl.keypasswd);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.SSL.CAINFO",url_hostport)) != NULL) {
|
|
state->ssl.cainfo = strdup(value);
|
|
if(state->ssl.cainfo == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.SSL.CAINFO: %s", state->ssl.cainfo);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.SSL.CAPATH",url_hostport)) != NULL) {
|
|
state->ssl.capath = strdup(value);
|
|
if(state->ssl.capath == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.SSL.CAPATH: %s", state->ssl.capath);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.SSL.VERIFYPEER",url_hostport)) != NULL) {
|
|
char* s = strdup(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 */
|
|
state->ssl.verifypeer = tf;
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.SSL.VERIFYPEER: %d", state->ssl.verifypeer);
|
|
free(s);
|
|
}
|
|
|
|
if((value = ocrc_lookup("HTTP.NETRC",url_hostport)) != NULL) {
|
|
if(state->curlflags.netrc != NULL)
|
|
free(state->curlflags.netrc);
|
|
state->curlflags.netrc = strdup(value);
|
|
if(state->curlflags.netrc == NULL) {stat = OC_ENOMEM; goto done;}
|
|
if(ocdebug > 0)
|
|
nclog(NCLOGNOTE,"HTTP.NETRC: %s", state->curlflags.netrc);
|
|
}
|
|
|
|
{ /* 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 = ocrc_lookup("HTTP.CREDENTIALS.USER",url_hostport);
|
|
pwd = ocrc_lookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
|
|
userpwd = ocrc_lookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
|
|
}
|
|
if(userpwd == NULL && user != NULL && pwd != NULL) {
|
|
userpwd = combinecredentials(user,pwd);
|
|
state->creds.userpwd = userpwd;
|
|
} else if(userpwd != NULL)
|
|
state->creds.userpwd = strdup(userpwd);
|
|
}
|
|
|
|
done:
|
|
if(url_hostport != NULL) free(url_hostport);
|
|
return stat;
|
|
}
|
|
|
|
static struct OCTriple*
|
|
ocrc_locate(char* key, char* hostport)
|
|
{
|
|
int i,found;
|
|
struct OCTriplestore* ocrc = &ocglobalstate.rc.daprc;
|
|
struct OCTriple* triple;
|
|
|
|
if(ocglobalstate.rc.ignore)
|
|
return NULL;
|
|
if(!ocglobalstate.rc.loaded)
|
|
ocrc_load();
|
|
|
|
triple = ocrc->triples;
|
|
|
|
if(key == NULL || ocrc == NULL) return NULL;
|
|
if(hostport == NULL) hostport = "";
|
|
/* Assume that the triple store has been properly sorted */
|
|
for(found=0,i=0;i<ocrc->ntriples;i++,triple++) {
|
|
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*
|
|
ocrc_lookup(char* key, char* hostport)
|
|
{
|
|
struct OCTriple* triple = ocrc_locate(key,hostport);
|
|
if(triple != NULL && ocdebug > 2) {
|
|
fprintf(stderr,"lookup %s: [%s]%s = %s\n",hostport,triple->host,triple->key,triple->value);
|
|
}
|
|
return (triple == NULL ? NULL : triple->value);
|
|
}
|
|
|
|
|
|
static void
|
|
storedump(char* msg, struct OCTriple* triples, int ntriples)
|
|
{
|
|
int i;
|
|
struct OCTriplestore* ocrc = &ocglobalstate.rc.daprc;
|
|
|
|
if(msg != NULL) fprintf(stderr,"%s\n",msg);
|
|
if(ocrc == NULL) {
|
|
fprintf(stderr,"<EMPTY>\n");
|
|
return;
|
|
}
|
|
if(triples == NULL) triples= ocrc->triples;
|
|
if(ntriples < 0 ) ntriples= ocrc->ntriples;
|
|
for(i=0;i<ntriples;i++) {
|
|
fprintf(stderr,"\t%s\t%s\t%s\n",
|
|
(strlen(triples[i].host)==0?"--":triples[i].host),
|
|
triples[i].key,
|
|
triples[i].value);
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
/*
|
|
Lookup against all prefixes
|
|
*/
|
|
|
|
static char*
|
|
ocrc_lookup(char* suffix, char* url)
|
|
{
|
|
char* value = NULL;
|
|
char key[MAXRCLINESIZE+1];
|
|
const char** p = prefixes;
|
|
for(;*p;p++) {
|
|
if(!occopycat(key,sizeof(key),2,*p,suffix))
|
|
return NULL;
|
|
value = ocrc_lookup(key,url);
|
|
if(value != NULL)
|
|
return value;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/* compile the rc file, if any */
|
|
static OCerror
|
|
ocreadrc(void)
|
|
{
|
|
OCerror stat = OC_NOERR;
|
|
char* path = NULL;
|
|
/* locate the configuration files: first if specified,
|
|
then '.', then $HOME */
|
|
if(ocglobalstate.rc.rcfile != NULL) { /* always use this */
|
|
path = ocglobalstate.rc.rcfile;
|
|
} else {
|
|
char** rcname;
|
|
int found = 0;
|
|
for(rcname=rcfilenames;!found && *rcname;rcname++) {
|
|
stat = rc_search(".",*rcname,&path);
|
|
if(stat == OC_NOERR && path == NULL) /* try $HOME */
|
|
stat = rc_search(ocglobalstate.home,*rcname,&path);
|
|
if(stat != OC_NOERR)
|
|
goto done;
|
|
if(path != NULL)
|
|
found = 1;
|
|
}
|
|
}
|
|
if(path == NULL) {
|
|
nclog(NCLOGDBG,"Cannot find runtime configuration file; continuing");
|
|
} else {
|
|
if(ocdebug > 0)
|
|
fprintf(stderr, "DODS RC file: %s\n", path);
|
|
if(ocdodsrc_read(path) == 0) {
|
|
nclog(NCLOGERR, "Error parsing %s\n",path);
|
|
stat = OC_ERCFILE;
|
|
}
|
|
}
|
|
done:
|
|
if(path != NULL)
|
|
free(path);
|
|
return stat;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Prefix must end in '/'
|
|
*/
|
|
static
|
|
OCerror
|
|
rc_search(const char* prefix, const char* rcname, char** pathp)
|
|
{
|
|
char* path = NULL;
|
|
FILE* f = NULL;
|
|
int plen = strlen(prefix);
|
|
int rclen = strlen(rcname);
|
|
OCerror stat = OC_NOERR;
|
|
|
|
size_t pathlen = plen+rclen+1+1; /*+1 for '/' +1 for nul*/
|
|
path = (char*)malloc(pathlen);
|
|
if(path == NULL) {
|
|
stat = OC_ENOMEM;
|
|
goto done;
|
|
}
|
|
if(!occopycat(path,pathlen,3,prefix,"/",rcname)) {
|
|
stat = OC_EOVERRUN;
|
|
goto done;
|
|
}
|
|
/* see if file is readable */
|
|
f = NCfopen(path,"r");
|
|
done:
|
|
if(f == NULL || stat != OC_NOERR) {
|
|
if(path != NULL)
|
|
free(path);
|
|
path = NULL;
|
|
}
|
|
|
|
if(f != NULL)
|
|
fclose(f);
|
|
if(pathp != NULL)
|
|
*pathp = path;
|
|
else {
|
|
free(path);
|
|
path = NULL;
|
|
}
|
|
|
|
return OCTHROW(stat);
|
|
}
|
|
|
|
struct OCTriple*
|
|
ocrc_triple_iterate(char* key, char* url, struct OCTriple* prev)
|
|
{
|
|
struct OCTriple* next;
|
|
if(prev == NULL)
|
|
next = ocrc_locate(key,url);
|
|
else
|
|
next = prev+1;
|
|
if(next == NULL)
|
|
return NULL;
|
|
for(; strlen(next->key) > 0; next++) {
|
|
/* See if key as prefix still matches */
|
|
int cmp = strcmp(key,next->key);
|
|
if(cmp != 0) {next = NULL; break;} /* key mismatch */
|
|
/* compare url */
|
|
cmp = ocstrncmp(url,next->host,strlen(next->host));
|
|
if(cmp == 0) break;
|
|
}
|
|
return next;
|
|
}
|