From 7de1f7bef8693572d34276b164936bef411721d9 Mon Sep 17 00:00:00 2001 From: dmh Date: Sun, 30 Nov 2014 20:30:23 -0700 Subject: [PATCH] oc synch --- cf | 4 +- libdap2/env | 9 +- ncdap_test/Makefile.am | 3 +- ncdap_test/t_auth.c | 207 ++++++++++++++++++++-------- ncdap_test/test_nstride_cached.c | 7 +- ncdap_test/tst_ncdap.sh | 3 +- ncdap_test/tst_remote.sh | 5 +- oc2/Make0 | 5 +- oc2/oc.c | 66 ++++++++- oc2/oc.h | 8 ++ oc2/occurlfunctions.c | 12 +- oc2/ocinternal.c | 224 ++++++++++++++++++------------- oc2/ocinternal.h | 9 +- oc2/ocrc.c | 53 +++++++- oc2/ocrc.h | 3 +- 15 files changed, 433 insertions(+), 185 deletions(-) diff --git a/cf b/cf index 58b54a80c..2cd733a7c 100644 --- a/cf +++ b/cf @@ -1,7 +1,7 @@ #!/bin/bash #X="-x" #NB=1 -#DB=1 +DB=1 if test $# != 0 ; then cmds=$@ @@ -122,7 +122,7 @@ FLAGS="$FLAGS --disable-examples" #FLAGS="$FLAGS --enable-large-file-tests" #FLAGS="$FLAGS --disable-testsets" #FLAGS="$FLAGS --disable-dap-remote-tests" -#FLAGS="$FLAGS --enable-dap-auth-tests" +FLAGS="$FLAGS --enable-dap-auth-tests" #FLAGS="$FLAGS --enable-doxygen" #FLAGS="$FLAGS --enable-logging" #FLAGS="$FLAGS --disable-diskless" diff --git a/libdap2/env b/libdap2/env index 7a554f7b5..1a2ec0ac5 100644 --- a/libdap2/env +++ b/libdap2/env @@ -7,11 +7,14 @@ alias xx="cd ..;make; cd libdap2" PARMS=""; ARGS=""; CON="" ; CE=""; OCON="" ; VAR=""; SHARP='#' alias q0=;alias qq=;alias qv=;alias q=;alias qh=;alias qqh=;alias qall=;alias qv=;alias qo=; +F="http://remotetest.unidata.ucar.edu/thredds/dodsC/testdods/in.nc" +CON="var_nm.dot" -F="http://thredds.aodn.org.au/thredds/fileServer/IMOS/ANMN/NSW/PH100/Velocity/IMOS_ANMN-NSW_AETVZ_20131127T230000Z_PH100_FV01_PH100-1311-Workhorse-ADCP-109.5_END-20140306T010000Z_C-20140521T053527Z.nc" - -#PROG=./ncd +if test -f ./ncd ; then +PROG=./ncd +else PROG="$TOP/ncdump/ncdump" +fi P=`pwd` diff --git a/ncdap_test/Makefile.am b/ncdap_test/Makefile.am index 1eb76458e..4f2aa4074 100644 --- a/ncdap_test/Makefile.am +++ b/ncdap_test/Makefile.am @@ -42,6 +42,7 @@ endif test_partvar_SOURCES = test_partvar.c test_nstride_cached_SOURCE = test_nstride_cached.c t_auth_SOURCES = t_auth.c +t_auth1_SOURCES = t_auth1.c t_misc_SOURCES = t_misc.c test_varm3_SOURCES = test_varm3.c @@ -56,7 +57,7 @@ check_PROGRAMS += t_misc check_PROGRAMS += test_varm3 if ENABLE_DAP_AUTH_TESTS -check_PROGRAMS += t_auth +check_PROGRAMS += t_auth t_auth1 TESTS += t_auth endif diff --git a/ncdap_test/t_auth.c b/ncdap_test/t_auth.c index 62714bebe..62cb0b598 100644 --- a/ncdap_test/t_auth.c +++ b/ncdap_test/t_auth.c @@ -6,25 +6,40 @@ #include #endif +#define DEBUG + #include "netcdf.h" -#define USERPWD "tiggeUser:tigge" +#undef NOEMBED +#undef NOLOCAL +#undef NOHOME +#define NOREDIR -#define URL1 "https://tiggeUser:tigge@%s/thredds/dodsC/restrict/testData.nc" +#define KEEPRC + +#define RC ".ocrc" +#define SPECRC "./ocrc" + +#define DEFAULTTESTSERVER "remotetest.unidata.ucar.edu" +#define USERPWD "tiggeUser:tigge" +#define COOKIEFILE "./cookies" + +#define URL1 "https://%s@%s/thredds/dodsC/restrict/testData.nc" #define URL2 "https://%s/thredds/dodsC/restrict/testData.nc" +#define URL3 "https://%s@thredds-test.ucar.edu/thredds/dodsC/restrict/testData.nc" /* Embedded user:pwd */ static char url1[1024]; -/* user:pwd from .dodsrc*/ +/* user:pwd from RC*/ static char url2[1024]; -/* Test redirect */ -static char* url3 = -"http://tiggeUser:tigge@thredds-test.ucar.edu/thredds/dodsC/restrict/testData.nc"; +/* Test redirect from different machine*/ +static char url3[1024]; -/* .dodsrc file */ -static char* CONTENT = "HTTP.CREDENTIALS.USER=tiggeUser\nHTTP.CREDENTIALS.PASSWORD=tigge\n"; +static int testrc(const char* prefix, const char* url); +static void fillrc(const char* path); +static void killrc(); #ifdef DEBUG static void @@ -32,7 +47,7 @@ CHECK(int e, const char* msg) { if(e == NC_NOERR) return; if(msg == NULL) msg = "Error"; - printf("%s: %s\n", msg, nc_strerror(e)); + fprintf(stderr,"%s: %s\n", msg, nc_strerror(e)); exit(1); } #endif @@ -41,78 +56,152 @@ int main(int argc, char** argv) { int ncid,retval,pass; - FILE* dodsrc; - char* envv; + FILE* rc; + const char* dfaltsvc; + char buffer[8192]; + const char* home; - envv = getenv("THREDDSTESTSERVER"); - if(envv == NULL) { - envv = "remotetest.unidata.ucar.edu"; - } else { /* walk past the schema and // */ - char* p = strchr(envv,':'); - if(p == NULL) { - fprintf(stderr,"URL has no schema: %s\n",url1); - exit(1); - } - envv = p+3; - } - snprintf(url1,sizeof(url1),URL1,envv); - snprintf(url2,sizeof(url2),URL2,envv); + fprintf(stderr,"Testing: Authorization\n"); -printf("url1: %s\n",url1); -printf("url2: %s\n",url2); -fflush(stdout); + dfaltsvc = DEFAULTTESTSERVER; + snprintf(url1,sizeof(url1),URL1,USERPWD,dfaltsvc); /* embedded */ + snprintf(url2,sizeof(url2),URL2,dfaltsvc); /* using rc file */ + +#ifdef DEBUG +fprintf(stderr,"url1: %s\n",url1); +fprintf(stderr,"url2: %s\n",url2); +fflush(stderr); +#endif pass = 1; /* assume success */ + killrc(); - dodsrc = fopen(".dodsrc","w"); - if(dodsrc == NULL) { - fprintf(stderr,"Cannot create .dodsrc\n"); - exit(1); - } - fprintf(dodsrc,CONTENT); - fclose(dodsrc); - - printf("Testing: Http Basic Authorization\n\n"); - if(1) { - printf("Embedded user:pwd: %s\n",url1); + fprintf(stderr,"Testing: Http Basic Authorization\n\n"); +#ifndef NOEMBED + { + fprintf(stderr,"Testing: Embedded user:pwd: %s\n",url1); retval = nc_open(url1, 0, &ncid); if(retval != NC_NOERR) { pass = 0; - printf("*** FAIL: Embedded user:pwd\n"); + fprintf(stderr,"*** FAIL: Testing embedded user:pwd\n"); } else { - printf("*** PASS: Embedded user:pwd\n"); + fprintf(stderr,"*** PASS: Testing embedded user:pwd\n"); retval = nc_close(ncid); } - fflush(stdout); + fflush(stderr); } +#endif - if(1) { - printf(".dodsrc user:pwd: %s\n",url2); - - retval = nc_open(url2, 0, &ncid); - if(retval != NC_NOERR) { - pass = 0; - printf("*** FAIL: .dodsrc user:pwd\n"); - } else { - retval = nc_close(ncid); - printf("*** PASS: .dodsrc user:pwd\n"); +#ifndef NOLOCAL + { + /* Test 1: RC in ./ */ + fprintf(stderr,"Testing: user:pwd in %s/%s: %s\n",".",RC); + if(!testrc(".",url2)) { + fprintf(stderr,"user:pwd in %s/%s failed\n",".",RC); + exit(1); } - fflush(stdout); } - unlink(".dodsrc"); /* delete the file */ +#endif - printf("Testing: Http Basic Redirect\n\n"); - if(1) { - printf("Basic redirect: %s\n",url3); +#ifndef NOHOME + { + /* Test 1: RC in HOME */ + home = getenv("HOME"); + fprintf(stderr,"user:pwd in %s/%s: %s\n",home,RC); + if(!testrc(home,url2)) { + fprintf(stderr,"user:pwd in %s/%s failed\n",home,RC); + exit(1); + } + } +#endif + +#ifndef NOREDIR + { + fprintf(stderr,"Testing: Http Basic Redirect\n\n"); + snprintf(url3,sizeof(url3),URL3,USERPWD); + fprintf(stderr,"Basic redirect: %s\n",url3); retval = nc_open(url3, 0, &ncid); if(retval != NC_NOERR) { - printf("*** XFAIL: Basic redirect\n"); + fprintf(stderr,"*** XFAIL: Basic redirect\n"); } else { - printf("*** PASS: Basic redirect\n"); + fprintf(stderr,"*** PASS: Basic redirect\n"); retval = nc_close(ncid); } - fflush(stdout); + fflush(stderr); } +#endif return !pass; } + +static int +testrc(const char* prefix, const char* url) +{ + int pass = 1; + int retval; + int ncid; + char rcpath[8192]; + FILE* rc; + + snprintf(rcpath,sizeof(rcpath),"%s/%s",prefix,RC); + rc = fopen(rcpath,"w"); + if(rc == NULL) { + fprintf(stderr,"Cannot create ./%s\n",RC); + exit(1); + } + fclose(rc); + fillrc(rcpath); + retval = nc_open(url, 0, &ncid); + if(retval != NC_NOERR) { + pass = 0; + fprintf(stderr,"*** FAIL: Testing: user:pwd in %s\n",rcpath); + } else { + retval = nc_close(ncid); + fprintf(stderr,"*** PASS: Testing: user:pwd in %s\n",rcpath); + } + fflush(stderr); +#ifndef KEEPRC + unlink(rcpath); /* delete the file */ +#endif + return pass; +} + +static void +fillrc(const char* path) +{ + FILE* rc; + killrc(); + + rc = fopen(path,"w"); + if(rc == NULL) { + fprintf(stderr,"cannot create rc file: %s\n",path); + exit(1); + } +#ifdef DEBUG + fprintf(rc,"HTTP.VERBOSE=1\n"); +#endif + fprintf(rc,"HTTP.COOKIEJAR=%s\n",COOKIEFILE); + fprintf(rc,"HTTP.VALIDATE=1\n"); + fprintf(rc,"HTTP.CREDENTIALS.USERPASSWORD=%s\n",USERPWD); + fclose(rc); +} + +static void +killrc() +{ + const char* home; + char path[1024]; +#ifdef KEEPRC + fprintf(stderr,"kill: ./%s\n",RC); +#else + snprintf(path,sizeof(path),"%s/%s",".",RC); + unlink(path); /* delete the file */ +#endif + home = getenv("HOME"); +#ifdef KEEPRC + fprintf(stderr,"kill: %s/%s\n",home,RC); +#else + snprintf(path,sizeof(path),"%s/%s",home,RC); + unlink(path); +#endif +} diff --git a/ncdap_test/test_nstride_cached.c b/ncdap_test/test_nstride_cached.c index ca1ec4c4b..f98ce48e0 100644 --- a/ncdap_test/test_nstride_cached.c +++ b/ncdap_test/test_nstride_cached.c @@ -67,7 +67,7 @@ Float64 lon_rho[eta_rho = 336][xi_rho = 896]; Float64 lat_rho[eta_rho = 336][xi_rho = 896]; */ -#define URL "%s/thredds/dodsC/testdods/rtofs.nc" +#define URL "%s/dodsC/testdods/rtofs.nc" #define VAR1 "Latitude" #define VAR2 "Longitude" #define XSIZE 850 @@ -98,15 +98,16 @@ main() const char* testserver[2]; testserver[0] = svc; testserver[1] = NULL; - svc = NC_findtestserver("dts",testserver); + svc = NC_findtestserver("thredds",testserver); } else - svc = NC_findtestserver("dts",NULL); + svc = NC_findtestserver("thredds",NULL); if(svc == NULL) { fprintf(stderr,"Cannot locate test server\n"); exit(0); } + strcpy(url,URL); snprintf(url,sizeof(url),URL,svc); for (idim=0; idim<5; idim++) { diff --git a/ncdap_test/tst_ncdap.sh b/ncdap_test/tst_ncdap.sh index 7e978e6c8..7669db597 100755 --- a/ncdap_test/tst_ncdap.sh +++ b/ncdap_test/tst_ncdap.sh @@ -67,6 +67,7 @@ fi rm -fr ${RESULTSDIR} mkdir "${RESULTSDIR}" +rm -f ./.dodsrc ./.ocrc passcount=0 xfailcount=0 failcount=0 @@ -76,8 +77,6 @@ echo " Base URL: ${TESTURL}" echo " Client Parameters: ${PARAMS}" cd ${RESULTSDIR} -rm -f ./.dodsrc -echo '#DODSRC' >./.dodsrc for x in ${TESTSET} ; do url="${PARAMS}${TESTURL}/$x" diff --git a/ncdap_test/tst_remote.sh b/ncdap_test/tst_remote.sh index 2617e2e86..18406264d 100755 --- a/ncdap_test/tst_remote.sh +++ b/ncdap_test/tst_remote.sh @@ -1,6 +1,6 @@ #!/bin/sh -set -x +#set -x quiet=0 leakcheck=0 timing=0 @@ -244,9 +244,8 @@ for i in $WHICHTESTS ; do *) echo "Unknown which test: $i" ;; esac +rm -f ./.dodsrc ./.ocrc cd ${RESULTSDIR} -rm -f ./.dodsrc -echo '#DODSRC' >./.dodsrc for t in ${TESTSET} ; do # see if we are using constraints diff --git a/oc2/Make0 b/oc2/Make0 index 20f1059d7..daf3f81d3 100755 --- a/oc2/Make0 +++ b/oc2/Make0 @@ -1,6 +1,6 @@ THISDIR=../oc2 -OCDIR=/home/dmh/git/oc -#OCIR=f:/git/oc +#OCDIR=/home/dmh/git/oc +OCDIR=f:/git/oc # Make consistent with Makefile.am SRC=oc.c \ @@ -29,6 +29,7 @@ all:: makeoc:: rm -f ${THISDIR}/*.[chy] for file in ${FILES} ; do \ + echo "${OCDIR}/$$file" ; \ f="${OCDIR}/$$file" ; \ base=`basename $$f` ; \ cat $$f | tr -d ' ' >${THISDIR}/$$base; \ diff --git a/oc2/oc.c b/oc2/oc.c index fc23c71ee..89f2aa802 100644 --- a/oc2/oc.c +++ b/oc2/oc.c @@ -33,11 +33,10 @@ static int ocinitialized = 0; #define OCDEREF(T,s,x) (s)=(T)(x) /**************************************************/ - -static int +static OCerror oc_initialize(void) { - int status = OC_NOERR; + OCerror status = OC_NOERR; status = ocinternalinitialize(); ocinitialized = 1; return status; @@ -2090,3 +2089,64 @@ oc_set_curl_callback(OClink link, oc_curl_callback* callback, void* userstate) state->usercurldata = userstate; return OCTHROW(OC_NOERR); } + +OCerror +oc_set_rcfile(const char* rcfile) +{ + FILE* f; + if(!ocinitialized) oc_initialize(); /* so ocglobalstate is defined */ + if(rcfile == NULL || strlen(rcfile) == 0) + return OCTHROW(OC_EINVAL); + f = fopen(rcfile,"r"); + if(f == NULL) + return OCTHROW(OC_ERCFILE); + fclose(f); + ocglobalstate.rc.rcfile = strdup(rcfile); + return OCTHROW(OC_NOERR); +} + +OCerror +oc_set_rcsearchpath(const char* path) +{ + char* p; + char *q; + int nelems; + int plen; + char* rcp; + + if(!ocinitialized) oc_initialize(); /* so ocglobalstate is defined */ + if(path == NULL || strlen(path) == 0) + return OCTHROW(OC_EINVAL); + plen = strlen(path); + rcp = strdup(path); + /* Count number of path elements */ + for(nelems=1,p=rcp;*p;p++) { + if(*p==';' || *p==':') nelems++; + } + ocglobalstate.rc.searchpath = (char**)malloc(sizeof(char*)*(nelems+1)); /* +1 for null terminator */ + ocglobalstate.rc.searchpath[nelems] = NULL; + if(nelems == 1) { + ocglobalstate.rc.searchpath[0] = rcp; rcp = NULL; + } else { + int i; + for(i=0,q=rcp,p=rcp;;p++) { + if(*p==';' || *p==':' || *p == '\0') { + ocglobalstate.rc.searchpath[i] = strdup(q); + if(*p == '\0') break; + *p = '\0'; + p = p+1; q = p; + } + } + } + return OCTHROW(OC_NOERR); +} + +OCerror +oc_set_esg(OClink link, int tf) +{ + OCstate* state; + OCVERIFY(OC_State,link); + OCDEREF(OCstate*,state,link); + state->curlflags.esg = tf; + return OCTHROW(OC_NOERR); +} diff --git a/oc2/oc.h b/oc2/oc.h index 43e0daa0f..e34cbc72f 100644 --- a/oc2/oc.h +++ b/oc2/oc.h @@ -583,4 +583,12 @@ extern OCerror oc_set_curl_callback(OClink,oc_curl_callback*,void* state); } #endif +/**************************************************/ +/* Experimental methods to deal with rc file + and with ESG style authorization redirection. +*/ + +/* Allow specification of the rc file */ +extern OCerror oc_set_rcfile(const char* rcfilepath); + #endif /*OC_H*/ diff --git a/oc2/occurlfunctions.c b/oc2/occurlfunctions.c index 596f25518..9294d68b4 100644 --- a/oc2/occurlfunctions.c +++ b/oc2/occurlfunctions.c @@ -79,11 +79,13 @@ Do not think this is correct } #endif if (flags->cookiejar) { + /* Assume we will read and write cookies to same place */ cstat = curl_easy_setopt(curl, CURLOPT_COOKIEJAR, flags->cookiejar); if (cstat != CURLE_OK) goto done; OCDBG1(1,"CURLOPT_COOKIEJAR=%s",flags->cookiejar); cstat = curl_easy_setopt(curl, CURLOPT_COOKIEFILE, flags->cookiejar); if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_COOKIEFILE=%s",flags->cookiejar); } if (flags->verbose) { cstat = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); @@ -104,15 +106,19 @@ Do not think this is correct } /* Following are always set */ -#if 0 /*Turn off since it introduces a potential security risk*/ cstat = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); + +#if 0 + /*This potentially introduces a potential security risk; + */ + cstat = curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1L); + OCDBG1(1,"CURLOPT_UNRESTRICTED_AUTH=%ld",1L); #endif - cstat = curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1L); - OCDBG1(1,"CURLOPT_UNRESTRICTED_AUTH=%ld",1L); cstat = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, OC_MAX_REDIRECTS); OCDBG1(1,"CURLOPT_MAXREDIRS=%ld",OC_MAX_REDIRECTS); + #if 0 cstat = curl_setopt(curl,CURLOPT_RETURNTRANSFER, 1L); OCDBG1(1,"CURLOPT_RETURNTRANSFER=%ld",1L); diff --git a/oc2/ocinternal.c b/oc2/ocinternal.c index ce1ca01c7..29c372f48 100644 --- a/oc2/ocinternal.c +++ b/oc2/ocinternal.c @@ -36,20 +36,15 @@ #define CLBRACE '{' #define CRBRACE '}' - -/* Define default rc files and aliases*/ -static char* rcfilenames[4] = {".ocrc", ".dodsrc", ".daprc",NULL}; - static OCerror ocextractddsinmemory(OCstate*,OCtree*,int); static OCerror ocextractddsinfile(OCstate*,OCtree*,int); static char* constraintescape(const char* url); static OCerror createtempfile(OCstate*,OCtree*); static int dataError(XXDR* xdrs, OCstate*); +static OCerror rc_search(const char* prefix, const char* rcfile, char** pathp); static OCerror ocsetcurlproperties(OCstate*); -static OCerror rc_search(const char* prefix, char** pathp); - extern OCnode* makeunlimiteddimension(void); #if defined(_WIN32) || defined(_WIN64) @@ -67,6 +62,9 @@ extern OCnode* makeunlimiteddimension(void); /* Collect global state info in one place */ struct OCGLOBALSTATE ocglobalstate; +/* Define default rc files and aliases*/ +static char* rcfilenames[] = {".dodsrc",".ocrc",NULL}; + OCerror ocinternalinitialize(void) { @@ -78,32 +76,6 @@ ocinternalinitialize(void) ocglobalstate.initialized = 1; } - /* Capture $HOME */ - { - char* p; - char* q; - char* home = getenv("HOME"); - char cwd[4096]; - if(ocglobalstate.home == NULL) { -#if defined(_WIN32) || defined(_WIN64) - home = getenv("TEMP"); -#else - home = "/tmp"; -#endif - } - if(home == NULL) { - home = getcwd(cwd,sizeof(cwd)); - if(home == NULL || *home == '\0') home = "."; - } - - /* Convert '\' to '/' */ - ocglobalstate.home = (char*)malloc(strlen(home) + 1); - for(p=home,q=ocglobalstate.home;*p;p++,q++) { - if(*p == '\\') {*q = '/'; } else {*q = *p;} - } - *q = '\0'; - } - /* Compute some xdr related flags */ xxdr_init(); @@ -111,74 +83,103 @@ ocinternalinitialize(void) oc_curl_protocols(&ocglobalstate); /* see what protocols are supported */ - /* compile the .dodsrc, if any */ + /* Capture temp dir*/ { - /* locate the configuration files: first in '.', then $HOME */ - stat = rc_search("./",&path); - if(stat == OC_NOERR && path == NULL) /* try $HOME */ - stat = rc_search(ocglobalstate.home,&path); - if(stat != OC_NOERR) - goto done; + char* tempdir; + char* p; + char* q; + char cwd[4096]; +#if defined(_WIN32) || defined(_WIN64) + tempdir = getenv("TEMP"); +#else + tempdir = "/tmp"; +#endif + if(tempdir == NULL) { + fprintf(stderr,"Cannot find a temp dir; using ./\n"); + tempdir = getcwd(cwd,sizeof(cwd)); + if(tempdir == NULL || *tempdir == '\0') tempdir = "."; + } + ocglobalstate.tempdir= (char*)malloc(strlen(tempdir) + 1); + for(p=tempdir,q=ocglobalstate.tempdir;*p;p++,q++) { + if((*p == '/' && *(p+1) == '/') + || (*p == '\\' && *(p+1) == '\\')) {p++;} + *q = *p; + } + *q = '\0'; +#if defined(_WIN32) || defined(_WIN64) +#else + /* Canonicalize */ + for(p=ocglobalstate.tempdir;*p;p++) { + if(*p == '\\') {*p = '/'; }; + } + *q = '\0'; +#endif + } + + /* Capture $HOME */ + { + char* p; + char* q; + char* home = getenv("HOME"); + + if(home == NULL) { + /* use tempdir */ + home = ocglobalstate.tempdir; + } + ocglobalstate.home = (char*)malloc(strlen(home) + 1); + for(p=home,q=ocglobalstate.home;*p;p++,q++) { + if((*p == '/' && *(p+1) == '/') + || (*p == '\\' && *(p+1) == '\\')) {p++;} + *q = *p; + } + *q = '\0'; +#if defined(_WIN32) || defined(_WIN64) +#else + /* Canonicalize */ + for(p=home;*p;p++) { + if(*p == '\\') {*p = '/'; }; + } +#endif + } + + { + /* Compute the rc file location */ + char* path = NULL; + /* locate the configuration files: first if specified, + then '.', then $HOME */ + if(ocglobalstate.rc.rcfile != NULL) { + /* always use this */ + } else { + char** rcname; + path = NULL; + for(rcname=rcfilenames;*rcname;rcname++) { + stat = rc_search(".",*rcname,&path); + if(stat != OC_NOERR) { + goto done; + } + if(path == NULL) { /* try $HOME */ + stat = rc_search(ocglobalstate.home,*rcname,&path); + if(stat != OC_NOERR) { + goto done; + } + } + if(path != NULL) + break; + } + } if(path == NULL) { - oclog(OCLOGDBG,"Cannot find runtime configuration file"); - } else { - if(ocdebug > 1) - fprintf(stderr, "DODS RC file: %s\n", path); - if(ocdodsrc_read(path) == 0) - oclog(OCLOGERR, "Error parsing %s\n",path); - } + oclog(OCLOGWARN,"Cannot find runtime configuration file; continuing"); + } else { + ocglobalstate.rc.rcfile = path; + path = NULL; + } } - + done: - if(path != NULL) - free(path); + if(path != NULL) free(path); return OCTHROW(stat); } -/** - * Prefix must end in '/' - */ -static -OCerror -rc_search(const char* prefix, char** pathp) -{ - char* path = NULL; - char** alias; - FILE* f = NULL; - int plen = strlen(prefix); - OCerror stat = OC_NOERR; - - for(alias=rcfilenames;*alias;alias++) { - size_t pathlen = plen+strlen(*alias)+1; - path = (char*)malloc(pathlen); - if(path == NULL) { - stat = OC_ENOMEM; - goto done; - } - if(!occopycat(path,pathlen,2,prefix,*alias)) { - stat = OC_EOVERRUN; - goto done; - } - /* see if file is readable */ - f = fopen(path,"r"); - if(f != NULL) - goto done; - free(path); - path = NULL; - } - -done: - if(f != NULL) - fclose(f); - if(stat != OC_NOERR) { - if(path != NULL) - free(path); - path = NULL; - } - if(pathp != NULL) - *pathp = path; - return OCTHROW(stat); -} /**************************************************/ OCerror @@ -722,3 +723,40 @@ done: xxdr_setpos(xdrs,ckp); return errfound; } + +static +OCerror +rc_search(const char* prefix, const char* rcname, char** pathp) +{ + char* path = NULL; + char** alias; + 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 = fopen(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; + return OCTHROW(stat); +} diff --git a/oc2/ocinternal.h b/oc2/ocinternal.h index e45dbccba..f9fbadc08 100644 --- a/oc2/ocinternal.h +++ b/oc2/ocinternal.h @@ -132,8 +132,13 @@ extern struct OCGLOBALSTATE { int proto_file; int proto_https; } curl; - struct OCTriplestore* ocdodsrc; /* the .dodsrc triple store */ + char* tempdir; /* track a usable temp dir */ char* home; /* track $HOME for use in creating $HOME/.oc dir */ + struct { + struct OCTriplestore* ocdodsrc; /* the .dodsrc triple store */ + char* rcfile; /* specified rcfile; overrides anything else */ + char** searchpath; /* Where to search */ + } rc; } ocglobalstate; /*! Specifies the OCstate = non-opaque version of OClink */ @@ -156,10 +161,10 @@ struct OCstate { int compress; int verbose; int timeout; - int followlocation; int maxredirs; char* useragent; char* cookiejar; + int esg; } curlflags; struct OCSSL { int validate; diff --git a/oc2/ocrc.c b/oc2/ocrc.c index 19fb9e4b3..cc9e36bc0 100644 --- a/oc2/ocrc.c +++ b/oc2/ocrc.c @@ -23,6 +23,9 @@ #define HTTPPREFIXDEPRECATED "CURL." #define HTTPPREFIX "HTTP." +static OCerror ocdodsrc_read(const char* path); +static OCerror ocreadrc(void); + static int parseproxy(OCstate* state, char* v); static int rcreadline(FILE* f, char* more, int morelen); static void rctrim(char* text); @@ -211,7 +214,7 @@ sorttriplestore(void) { int i, nsorted; struct OCTriple* sorted = NULL; - struct OCTriplestore* ocdodsrc = ocglobalstate.ocdodsrc; + struct OCTriplestore* ocdodsrc = ocglobalstate.rc.ocdodsrc; if(ocdodsrc == NULL) return; /* nothing to sort */ if(ocdodsrc->ntriples <= 1) return; /* nothing to sort */ @@ -266,7 +269,7 @@ ocdodsrc_read(const char* path) char line0[MAXRCLINESIZE+1]; FILE *in_file = NULL; int linecount = 0; - struct OCTriplestore* ocdodsrc = ocglobalstate.ocdodsrc; + struct OCTriplestore* ocdodsrc = ocglobalstate.rc.ocdodsrc; if(ocdodsrc == NULL) { ocdodsrc = (struct OCTriplestore*)malloc(sizeof(struct OCTriplestore)); @@ -274,7 +277,7 @@ ocdodsrc_read(const char* path) oclog(OCLOGERR,"ocdodsrc_read: out of memory"); return 0; } - ocglobalstate.ocdodsrc = ocdodsrc; + ocglobalstate.rc.ocdodsrc = ocdodsrc; } ocdodsrc->ntriples = 0; @@ -348,9 +351,16 @@ ocdodsrc_process(OCstate* state) int stat = 0; char* value = NULL; char* url = ocuribuild(state->uri,NULL,NULL,OCURIENCODE); - struct OCTriplestore* ocdodsrc = ocglobalstate.ocdodsrc; + struct OCTriplestore* ocdodsrc; + if(ocglobalstate.rc.ocdodsrc == NULL) + ocreadrc(); + if(ocglobalstate.rc.ocdodsrc == NULL) + return OC_NOERR; + + ocdodsrc = ocglobalstate.rc.ocdodsrc; if(ocdodsrc == NULL) goto done; + value = curllookup("DEFLATE",url); if(value != NULL) { if(atoi(value)) state->curlflags.compress = 1; @@ -484,8 +494,16 @@ char* ocdodsrc_lookup(char* key, char* url) { int i,found; - struct OCTriplestore* ocdodsrc = ocglobalstate.ocdodsrc; - struct OCTriple* triple = ocdodsrc->triples; + struct OCTriplestore* ocdodsrc; + struct OCTriple* triple; + + if(ocglobalstate.rc.ocdodsrc == NULL) + ocreadrc(); + if(ocglobalstate.rc.ocdodsrc == NULL) + return NULL; + + ocdodsrc = ocglobalstate.rc.ocdodsrc; + triple = ocdodsrc->triples; if(key == NULL || ocdodsrc == NULL) return NULL; if(url == NULL) url = ""; @@ -514,7 +532,7 @@ static void ocdodsrcdump(char* msg, struct OCTriple* triples, int ntriples) { int i; - struct OCTriplestore* ocdodsrc = ocglobalstate.ocdodsrc; + struct OCTriplestore* ocdodsrc = ocglobalstate.rc.ocdodsrc; if(msg != NULL) fprintf(stderr,"%s\n",msg); if(ocdodsrc == NULL) { @@ -549,3 +567,24 @@ curllookup(char* suffix, char* url) } return value; } + +/* compile the .dodsrc, if any */ +OCerror +ocreadrc(void) +{ + OCerror stat = OC_NOERR; + if(ocglobalstate.rc.rcfile == NULL) { + oclog(OCLOGNOTE,"No dods rc file specified\n"); + return OC_NOERR; + } + if(ocdebug > 0) + fprintf(stderr, "Dods rc file: %s\n", ocglobalstate.rc.rcfile); + if(ocglobalstate.rc.rcfile != NULL) { + if(ocdodsrc_read(ocglobalstate.rc.rcfile) == 0) { + oclog(OCLOGERR, "Error parsing %s\n",ocglobalstate.rc.rcfile); + stat = OC_ERCFILE; + } + } + return stat; +} + diff --git a/oc2/ocrc.h b/oc2/ocrc.h index 2b4c30c5f..784af937d 100644 --- a/oc2/ocrc.h +++ b/oc2/ocrc.h @@ -26,8 +26,7 @@ extern struct OCTriplestore { } triples[MAXRCLINES]; } *ocdodsrc; -extern int ocdodsrc_read(const char* path); -extern int ocdodsrc_process(OCstate* state); +extern OCerror ocdodsrc_process(OCstate* state); extern char* ocdodsrc_lookup(char* key, char* url); #endif /* RC_H_ */