mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-19 17:30:27 +08:00
Make public a limited API for programmatic access to internal .rc tables
re: https://github.com/Unidata/netcdf-c/issues/2337 re: https://github.com/Unidata/netcdf-c/issues/2407 Add two functions to netcdf.h to allow programs to get/set selected entries into the internal .rc tables. This should fix the above issues by allowing HTTP.CAINFO to be set to the certificates directory. Note that the changes should be performed as early as possible in the program because some of the .rc table entries may get cached internally and changing the entry after that caching occurs may have no effect. The new signatures are as follows: 1. Get the value of a simple .rc entry of the form "key=value". Note that caller must free the returned value, which might be NULL. ```` char* nc_rc_get(char* const * key); @param key table entry key @return value if .rc table has entry of the form key=value @return NULL if no such entry is found. ```` 2. Insert/Overwrite the specified key=value pair in the .rc table. ```` int nc_rc_set(const char* key, const char* value); @param key table entry key -- may not be NULL @param value table entry value -- may not be NULL @return NC_NOERR if no error @return NC_EINVAL if error ```` Addendum: re: https://github.com/Unidata/netcdf-c/issues/2407 Modify dhttp.c to use the .rc entry HTTP.CAINFO if defined.
This commit is contained in:
parent
7375f4bfb3
commit
aabbdbf64c
@ -69,7 +69,7 @@ endif()
|
||||
if(MSVC)
|
||||
SET(ISMSVC yes)
|
||||
endif()
|
||||
if(osname MATCHES "MINGW.*")
|
||||
if(osname MATCHES "MINGW.*" OR osname MATCHES "MSYS.*")
|
||||
SET(ISMINGW yes)
|
||||
SET(MINGW yes)
|
||||
endif()
|
||||
|
@ -7,7 +7,7 @@ This file contains a high-level description of this package's evolution. Release
|
||||
|
||||
## 4.9.1 - T.B.D.
|
||||
|
||||
|
||||
* [Enhancement] Provide a simple API to allow user access to the internal .rc file table: supports get/set/overwrite of entries of the form "key=value". See [Github #????](https://github.com/Unidata/netcdf-c/pull/????).
|
||||
* [Bug Fix] Use env variable USERPROFILE instead of HOME for windows and mingw. See [Github #2405](https://github.com/Unidata/netcdf-c/pull/2405).
|
||||
* [Bug Fix] Fix the nc_def_var_fletcher32 code in hdf5 to properly test value of the fletcher32 argument. See [Github #2403](https://github.com/Unidata/netcdf-c/pull/2403).
|
||||
|
||||
|
@ -107,6 +107,7 @@ case "`uname`" in
|
||||
Darwin*) ISOSX=yes;;
|
||||
WIN*) ISMSVC=yes;;
|
||||
MINGW*) ISMINGW=yes;;
|
||||
MSYS*) ISMINGW=yes;;
|
||||
esac
|
||||
|
||||
if test "x$MSYSTEM" != x ; then
|
||||
|
@ -28,7 +28,7 @@ and accessing rc files (e.g. .daprc).
|
||||
|
||||
typedef struct NCRCentry {
|
||||
char* host; /* combined host:port */
|
||||
char* path; /* prefix to match or NULL */
|
||||
char* urlpath; /* prefix to match or NULL */
|
||||
char* key;
|
||||
char* value;
|
||||
} NCRCentry;
|
||||
@ -67,7 +67,7 @@ extern "C" {
|
||||
|
||||
/* From drc.c */
|
||||
EXTERNL void ncrc_initialize(void);
|
||||
EXTERNL int NC_rcfile_insert(const char* key, const char* value, const char* hostport, const char* path);
|
||||
EXTERNL int NC_rcfile_insert(const char* key, const char* hostport, const char* path, const char* value);
|
||||
EXTERNL char* NC_rclookup(const char* key, const char* hostport, const char* path);
|
||||
EXTERNL char* NC_rclookupx(NCURI* uri, const char* key);
|
||||
|
||||
|
@ -2095,6 +2095,14 @@ EXTERNL int nc_initialize(void);
|
||||
*/
|
||||
EXTERNL int nc_finalize(void);
|
||||
|
||||
/* Programmatic access to the internal .rc table */
|
||||
|
||||
/* Get the value corresponding to key | return NULL; caller frees result */
|
||||
EXTERNL char* nc_rc_get(const char* key);
|
||||
|
||||
/* Set/overwrite the value corresponding to key */
|
||||
EXTERNL int nc_rc_set(const char* key, const char* value);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -95,7 +95,6 @@ NCDISPATCH_initialize(void)
|
||||
NCpathcanonical(home,&globalstate->home);
|
||||
nullfree(home);
|
||||
}
|
||||
fprintf(stderr,">>> HOME=|%s|\n",globalstate->home); fflush(stderr);
|
||||
|
||||
/* Capture $CWD */
|
||||
{
|
||||
|
@ -22,7 +22,9 @@
|
||||
#include "nclog.h"
|
||||
#include "ncbytes.h"
|
||||
#include "nclist.h"
|
||||
#include "ncuri.h"
|
||||
#include "nchttp.h"
|
||||
#include "ncauth.h"
|
||||
|
||||
#undef TRACE
|
||||
|
||||
@ -482,6 +484,23 @@ setupconn(NC_HTTP_STATE* state, const char* objecturl)
|
||||
cstat = curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
if (cstat != CURLE_OK) goto fail;
|
||||
|
||||
/* Pull some values from .rc tables */
|
||||
{
|
||||
NCURI* uri = NULL;
|
||||
char* hostport = NULL;
|
||||
char* value = NULL;
|
||||
ncuriparse(objecturl,&uri);
|
||||
if(uri == NULL) goto fail;
|
||||
hostport = NC_combinehostport(uri);
|
||||
value = NC_rclookup("HTTP.CAINFO",hostport,NULL);
|
||||
if(value == NULL)
|
||||
value = NC_rclookup("HTTP.CAINFO",NULL,NULL);
|
||||
if(value != NULL) {
|
||||
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_CAINFO, value));
|
||||
if (cstat != CURLE_OK) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the method */
|
||||
if((stat = nc_http_set_method(state,state->request.method))) goto done;
|
||||
|
||||
|
@ -38,8 +38,6 @@ See COPYRIGHT for license information.
|
||||
#define RTAG ']'
|
||||
#define LTAG '['
|
||||
|
||||
#define TRIMCHARS " \t\r\n"
|
||||
|
||||
#undef MEMCHECK
|
||||
#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
|
||||
|
||||
@ -52,9 +50,12 @@ static char* rcreadline(char** nextlinep);
|
||||
static void rctrim(char* text);
|
||||
static void rcorder(NClist* rc);
|
||||
static int rccompile(const char* path);
|
||||
static struct NCRCentry* rclocate(const char* key, const char* hostport, const char* path);
|
||||
static int rcequal(NCRCentry* e1, NCRCentry* e2);
|
||||
static int rclocatepos(const char* key, const char* hostport, const char* urlpath);
|
||||
static struct NCRCentry* rclocate(const char* key, const char* hostport, const char* urlpath);
|
||||
static int rcsearch(const char* prefix, const char* rcname, char** pathp);
|
||||
static void rcfreeentries(NClist* rc);
|
||||
static void rcfreeentry(NCRCentry* t);
|
||||
#ifdef DRCDEBUG
|
||||
static void storedump(char* msg, NClist* entrys);
|
||||
#endif
|
||||
@ -68,11 +69,63 @@ static const char* rcfilenames[] = {".ncrc", ".daprc", ".dodsrc",NULL};
|
||||
/* Read these files */
|
||||
static const char* awsconfigfiles[] = {".aws/credentials",".aws/config",NULL};
|
||||
|
||||
static int NCRCinitialized = 0;
|
||||
|
||||
/**************************************************/
|
||||
/* User API */
|
||||
|
||||
/**
|
||||
The most common case is to get the most general value for a key,
|
||||
where most general means that the urlpath and hostport are null
|
||||
So this function returns the value associated with the key
|
||||
where the .rc entry has the simple form "key=value".
|
||||
If that entry is not found, then return NULL.
|
||||
|
||||
@param key table entry key field
|
||||
@return value matching the key -- caller frees
|
||||
@return NULL if no entry of the form key=value exists
|
||||
*/
|
||||
char*
|
||||
nc_rc_get(const char* key)
|
||||
{
|
||||
NCglobalstate* ncg = NULL;
|
||||
char* value = NULL;
|
||||
|
||||
if(!NCRCinitialized) ncrc_initialize();
|
||||
ncg = NC_getglobalstate();
|
||||
assert(ncg != NULL && ncg->rcinfo != NULL && ncg->rcinfo->entries != NULL);
|
||||
if(ncg->rcinfo->ignore) return NC_NOERR;
|
||||
value = NC_rclookup(key,NULL,NULL);
|
||||
return nulldup(value);
|
||||
}
|
||||
|
||||
/**
|
||||
Set simple key=value in .rc table.
|
||||
Will overwrite any existing value.
|
||||
|
||||
@param key
|
||||
@param value
|
||||
@return NC_NOERR if success
|
||||
@return NC_EINVAL if fail
|
||||
*/
|
||||
int
|
||||
nc_rc_set(const char* key, const char* value)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
NCglobalstate* ncg = NULL;
|
||||
NCRCentry* entry = NULL;
|
||||
|
||||
if(!NCRCinitialized) ncrc_initialize();
|
||||
ncg = NC_getglobalstate();
|
||||
assert(ncg != NULL && ncg->rcinfo != NULL && ncg->rcinfo->entries != NULL);
|
||||
if(ncg->rcinfo->ignore) return NC_NOERR;
|
||||
stat = NC_rcfile_insert(key,NULL,NULL,value);
|
||||
return stat;
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* External Entry Points */
|
||||
|
||||
static int NCRCinitialized = 0;
|
||||
|
||||
/*
|
||||
Initialize defaults and load:
|
||||
* .ncrc
|
||||
@ -96,13 +149,14 @@ ncrc_initialize(void)
|
||||
if(NCRCinitialized) return;
|
||||
NCRCinitialized = 1; /* prevent recursion */
|
||||
|
||||
ncg = NC_getglobalstate();
|
||||
|
||||
#ifndef NOREAD
|
||||
/* Load entrys */
|
||||
if((stat = NC_rcload())) {
|
||||
nclog(NCLOGWARN,".rc loading failed");
|
||||
}
|
||||
/* Load .aws/config */
|
||||
ncg = NC_getglobalstate();
|
||||
if((stat = aws_load_credentials(ncg))) {
|
||||
nclog(NCLOGWARN,"AWS config file not loaded");
|
||||
}
|
||||
@ -120,6 +174,9 @@ ncrc_setrchome(void)
|
||||
if(tmp == NULL || strlen(tmp) == 0)
|
||||
tmp = ncg->home;
|
||||
ncg->rcinfo->rchome = strdup(tmp);
|
||||
#ifdef DRCDEBUG
|
||||
fprintf(stderr,"ncrc_setrchome: %s\n",ncg->rcinfo->rchome);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -132,16 +189,23 @@ NC_rcclear(NCRCinfo* info)
|
||||
freeprofilelist(info->s3profiles);
|
||||
}
|
||||
|
||||
static void
|
||||
rcfreeentry(NCRCentry* t)
|
||||
{
|
||||
nullfree(t->host);
|
||||
nullfree(t->urlpath);
|
||||
nullfree(t->key);
|
||||
nullfree(t->value);
|
||||
free(t);
|
||||
}
|
||||
|
||||
static void
|
||||
rcfreeentries(NClist* rc)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<nclistlength(rc);i++) {
|
||||
NCRCentry* t = (NCRCentry*)nclistget(rc,i);
|
||||
nullfree(t->host);
|
||||
nullfree(t->key);
|
||||
nullfree(t->value);
|
||||
free(t);
|
||||
rcfreeentry(t);
|
||||
}
|
||||
nclistfree(rc);
|
||||
}
|
||||
@ -182,8 +246,7 @@ NC_rcload(void)
|
||||
const char* dirnames[3];
|
||||
const char** dir;
|
||||
|
||||
|
||||
/* Make sure rcinfo.rchome is defined */
|
||||
/* Make sure rcinfo.rchome is defined */
|
||||
ncrc_setrchome();
|
||||
dirnames[0] = globalstate->rcinfo->rchome;
|
||||
dirnames[1] = globalstate->cwd;
|
||||
@ -214,15 +277,15 @@ done:
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a entry by property key and host+port (may be null|"")
|
||||
* Locate a entry by property key and host+port (may be null)
|
||||
* If duplicate keys, first takes precedence.
|
||||
*/
|
||||
char*
|
||||
NC_rclookup(const char* key, const char* hostport, const char* path)
|
||||
NC_rclookup(const char* key, const char* hostport, const char* urlpath)
|
||||
{
|
||||
struct NCRCentry* entry = NULL;
|
||||
if(!NCRCinitialized) ncrc_initialize();
|
||||
entry = rclocate(key,hostport,path);
|
||||
entry = rclocate(key,hostport,urlpath);
|
||||
return (entry == NULL ? NULL : entry->value);
|
||||
}
|
||||
|
||||
@ -248,8 +311,7 @@ Set the absolute path to use for the rc file.
|
||||
WARNING: this MUST be called before any other
|
||||
call in order for this to take effect.
|
||||
|
||||
\param[in] rcfile The path to use. If NULL, or "",
|
||||
then do not use any rcfile.
|
||||
\param[in] rcfile The path to use. If NULL then do not use any rcfile.
|
||||
|
||||
\retval OC_NOERR if the request succeeded.
|
||||
\retval OC_ERCFILE if the file failed to load
|
||||
@ -305,25 +367,26 @@ rcreadline(char** nextlinep)
|
||||
static void
|
||||
rctrim(char* text)
|
||||
{
|
||||
char* p = text;
|
||||
char* p;
|
||||
char* q;
|
||||
size_t len = 0;
|
||||
int i;
|
||||
|
||||
if(text == NULL) return;
|
||||
if(text == NULL || *text == '\0') return;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* elide upto first non-trimchar */
|
||||
for(q=text,p=text;*p;p++) {
|
||||
if(*p != ' ' && *p != '\t' && *p != '\r') {*q++ = *p;}
|
||||
}
|
||||
len = strlen(p);
|
||||
/* 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;
|
||||
}
|
||||
p = &text[i];
|
||||
if(*p != ' ' && *p != '\t' && *p != '\r') {break;}
|
||||
*p = '\0'; /* elide trailing trimchars */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -339,22 +402,22 @@ rcorder(NClist* rc)
|
||||
NClist* tmprc = NULL;
|
||||
if(rc == NULL || len == 0) return;
|
||||
tmprc = nclistnew();
|
||||
/* Copy rc into tmprc and clear rc */
|
||||
for(i=0;i<len;i++) {
|
||||
NCRCentry* ti = nclistget(rc,i);
|
||||
nclistpush(tmprc,ti);
|
||||
}
|
||||
nclistclear(rc);
|
||||
/* Two passes: 1) pull entries with host */
|
||||
for(i=0;i<len;i++) {
|
||||
NCRCentry* ti = nclistget(tmprc,i);
|
||||
NCRCentry* ti = nclistget(rc,i);
|
||||
if(ti->host == NULL) continue;
|
||||
nclistpush(rc,ti);
|
||||
nclistpush(tmprc,ti);
|
||||
}
|
||||
/* pass 2 pull entries without host*/
|
||||
for(i=0;i<len;i++) {
|
||||
NCRCentry* ti = nclistget(tmprc,i);
|
||||
NCRCentry* ti = nclistget(rc,i);
|
||||
if(ti->host != NULL) continue;
|
||||
nclistpush(tmprc,ti);
|
||||
}
|
||||
/* Move tmp to rc */
|
||||
nclistsetlength(rc,0);
|
||||
for(i=0;i<len;i++) {
|
||||
NCRCentry* ti = nclistget(tmprc,i);
|
||||
nclistpush(rc,ti);
|
||||
}
|
||||
#ifdef DRCDEBUG
|
||||
@ -365,7 +428,7 @@ rcorder(NClist* rc)
|
||||
|
||||
/* Merge a entry store from a file*/
|
||||
static int
|
||||
rccompile(const char* path)
|
||||
rccompile(const char* filepath)
|
||||
{
|
||||
int ret = NC_NOERR;
|
||||
NClist* rc = NULL;
|
||||
@ -376,8 +439,8 @@ rccompile(const char* path)
|
||||
NCglobalstate* globalstate = NC_getglobalstate();
|
||||
char* bucket = NULL;
|
||||
|
||||
if((ret=NC_readfile(path,tmp))) {
|
||||
nclog(NCLOGWARN, "Could not open configuration file: %s",path);
|
||||
if((ret=NC_readfile(filepath,tmp))) {
|
||||
nclog(NCLOGWARN, "Could not open configuration file: %s",filepath);
|
||||
goto done;
|
||||
}
|
||||
contents = ncbytesextract(tmp);
|
||||
@ -394,6 +457,7 @@ rccompile(const char* path)
|
||||
char* key = NULL;
|
||||
char* value = NULL;
|
||||
char* host = NULL;
|
||||
char* urlpath = NULL;
|
||||
size_t llen;
|
||||
NCRCentry* entry;
|
||||
|
||||
@ -406,7 +470,7 @@ rccompile(const char* path)
|
||||
char* url = ++line;
|
||||
char* rtag = strchr(line,RTAG);
|
||||
if(rtag == NULL) {
|
||||
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
|
||||
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",filepath,line);
|
||||
continue;
|
||||
}
|
||||
line = rtag + 1;
|
||||
@ -414,17 +478,18 @@ rccompile(const char* path)
|
||||
/* compile the url and pull out the host and protocol */
|
||||
if(uri) ncurifree(uri);
|
||||
if(ncuriparse(url,&uri)) {
|
||||
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
|
||||
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",filepath,line);
|
||||
continue;
|
||||
}
|
||||
{ NCURI* newuri = NULL;
|
||||
/* Rebuild the url to path format */
|
||||
/* Rebuild the url to S3 "path" format */
|
||||
nullfree(bucket);
|
||||
if((ret = NC_s3urlrebuild(uri,&newuri,&bucket,NULL))) goto done;
|
||||
ncurifree(uri);
|
||||
uri = newuri;
|
||||
newuri = NULL;
|
||||
}
|
||||
/* Get the host+port */
|
||||
ncbytesclear(tmp);
|
||||
ncbytescat(tmp,uri->host);
|
||||
if(uri->port != NULL) {
|
||||
@ -433,8 +498,11 @@ rccompile(const char* path)
|
||||
}
|
||||
ncbytesnull(tmp);
|
||||
host = ncbytesextract(tmp);
|
||||
if(strlen(host)==0)
|
||||
if(strlen(host)==0) /* nullify host */
|
||||
{free(host); host = NULL;}
|
||||
/* Get the url path part */
|
||||
urlpath = uri->path;
|
||||
if(urlpath && strlen(urlpath)==0) urlpath = NULL; /* nullify */
|
||||
}
|
||||
/* split off key and value */
|
||||
key=line;
|
||||
@ -446,31 +514,33 @@ rccompile(const char* path)
|
||||
value++;
|
||||
}
|
||||
/* See if key already exists */
|
||||
entry = rclocate(key,host,path);
|
||||
if(entry != NULL) {
|
||||
nullfree(entry->host);
|
||||
nullfree(entry->key);
|
||||
nullfree(entry->value);
|
||||
} else {
|
||||
entry = rclocate(key,host,urlpath);
|
||||
if(entry == NULL) {
|
||||
entry = (NCRCentry*)calloc(1,sizeof(NCRCentry));
|
||||
if(entry == NULL) {ret = NC_ENOMEM; goto done;}
|
||||
nclistpush(rc,entry);
|
||||
entry->host = host; host = NULL;
|
||||
entry->urlpath = nulldup(urlpath);
|
||||
entry->key = nulldup(key);
|
||||
rctrim(entry->host);
|
||||
rctrim(entry->urlpath);
|
||||
rctrim(entry->key);
|
||||
}
|
||||
entry->host = host; host = NULL;
|
||||
entry->key = nulldup(key);
|
||||
nullfree(entry->value);
|
||||
entry->value = nulldup(value);
|
||||
rctrim(entry->host);
|
||||
rctrim(entry->key);
|
||||
rctrim(entry->value);
|
||||
|
||||
#ifdef DRCDEBUG
|
||||
fprintf(stderr,"rc: host=%s key=%s value=%s\n",
|
||||
fprintf(stderr,"rc: host=%s urlpath=%s key=%s value=%s\n",
|
||||
(entry->host != NULL ? entry->host : "<null>"),
|
||||
(entry->urlpath != NULL ? entry->urlpath : "<null>"),
|
||||
entry->key,entry->value);
|
||||
#endif
|
||||
|
||||
entry = NULL;
|
||||
}
|
||||
#ifdef DRCDEBUG
|
||||
fprintf(stderr,"reorder.path=%s\n",filepath);
|
||||
#endif
|
||||
rcorder(rc);
|
||||
|
||||
done:
|
||||
@ -480,47 +550,84 @@ done:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
Encapsulate equality comparison: return 1|0
|
||||
*/
|
||||
static int
|
||||
rcequal(NCRCentry* e1, NCRCentry* e2)
|
||||
{
|
||||
int nulltest;
|
||||
if(e1->key == NULL || e2->key == NULL) return 0;
|
||||
if(strcmp(e1->key,e2->key) != 0) return 0;
|
||||
/* test hostport; take NULL into account*/
|
||||
nulltest = 0;
|
||||
if(e1->host == NULL) nulltest |= 1;
|
||||
if(e2->host == NULL) nulltest |= 2;
|
||||
switch (nulltest) {
|
||||
case 0: if(strcmp(e1->host,e2->host) != 0) {return 0;} break;
|
||||
case 1: return 0;
|
||||
case 2: return 0;
|
||||
case 3: break;
|
||||
default: return 0;
|
||||
}
|
||||
/* test urlpath take NULL into account*/
|
||||
nulltest = 0;
|
||||
if(e1->urlpath == NULL) nulltest |= 1;
|
||||
if(e2->urlpath == NULL) nulltest |= 2;
|
||||
switch (nulltest) {
|
||||
case 0: if(strcmp(e1->urlpath,e2->urlpath) != 0) {return 0;} break;
|
||||
case 1: return 0;
|
||||
case 2: return 0;
|
||||
case 3: break;
|
||||
default: return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Locate a entry by property key and host+port (may be null) and urlpath (may be null)
|
||||
* If duplicate keys, first takes precedence.
|
||||
*/
|
||||
static int
|
||||
rclocatepos(const char* key, const char* hostport, const char* urlpath)
|
||||
{
|
||||
int i;
|
||||
NCglobalstate* globalstate = NC_getglobalstate();
|
||||
struct NCRCinfo* info = globalstate->rcinfo;
|
||||
NCRCentry* entry = NULL;
|
||||
NCRCentry candidate;
|
||||
NClist* rc = info->entries;
|
||||
|
||||
if(info->ignore) return -1;
|
||||
|
||||
candidate.key = (char*)key;
|
||||
candidate.value = (char*)NULL;
|
||||
candidate.host = (char*)hostport;
|
||||
candidate.urlpath = (char*)urlpath;
|
||||
|
||||
for(i=0;i<nclistlength(rc);i++) {
|
||||
entry = (NCRCentry*)nclistget(rc,i);
|
||||
if(rcequal(entry,&candidate)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Locate a entry by property key and host+port (may be null or "").
|
||||
* If duplicate keys, first takes precedence.
|
||||
*/
|
||||
static struct NCRCentry*
|
||||
rclocate(const char* key, const char* hostport, const char* path)
|
||||
rclocate(const char* key, const char* hostport, const char* urlpath)
|
||||
{
|
||||
int i,found;
|
||||
int pos;
|
||||
NCglobalstate* globalstate = NC_getglobalstate();
|
||||
NClist* rc = globalstate->rcinfo->entries;
|
||||
NCRCentry* entry = NULL;
|
||||
struct NCRCinfo* info = globalstate->rcinfo;
|
||||
|
||||
if(globalstate->rcinfo->ignore)
|
||||
return NULL;
|
||||
|
||||
if(key == NULL || rc == NULL) return NULL;
|
||||
if(hostport == NULL) hostport = "";
|
||||
|
||||
for(found=0,i=0;i<nclistlength(rc);i++) {
|
||||
int t;
|
||||
size_t hplen;
|
||||
entry = (NCRCentry*)nclistget(rc,i);
|
||||
|
||||
hplen = (entry->host == NULL ? 0 : strlen(entry->host));
|
||||
|
||||
if(strcmp(key,entry->key) != 0) continue; /* keys do not match */
|
||||
/* If the entry entry has no url, then use it
|
||||
(because we have checked all other cases)*/
|
||||
if(hplen == 0) {found=1;break;}
|
||||
/* do hostport match */
|
||||
t = 0;
|
||||
if(entry->host != NULL)
|
||||
t = strcmp(hostport,entry->host);
|
||||
/* do path prefix match */
|
||||
if(entry->path != NULL) {
|
||||
size_t pathlen = strlen(entry->path);
|
||||
t = strncmp(path,entry->path,pathlen);
|
||||
}
|
||||
if(t == 0) {found=1; break;}
|
||||
}
|
||||
return (found?entry:NULL);
|
||||
if(globalstate->rcinfo->ignore) return NULL;
|
||||
if(key == NULL || info == NULL) return NULL;
|
||||
pos = rclocatepos(key,hostport,urlpath);
|
||||
if(pos < 0) return NULL;
|
||||
return NC_rcfile_ith(info,(size_t)pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -562,7 +669,7 @@ done:
|
||||
}
|
||||
|
||||
int
|
||||
NC_rcfile_insert(const char* key, const char* value, const char* hostport, const char* path)
|
||||
NC_rcfile_insert(const char* key, const char* hostport, const char* urlpath, const char* value)
|
||||
{
|
||||
int ret = NC_NOERR;
|
||||
/* See if this key already defined */
|
||||
@ -571,6 +678,10 @@ NC_rcfile_insert(const char* key, const char* value, const char* hostport, const
|
||||
NClist* rc = NULL;
|
||||
|
||||
if(!NCRCinitialized) ncrc_initialize();
|
||||
|
||||
if(key == NULL || value == NULL)
|
||||
{ret = NC_EINVAL; goto done;}
|
||||
|
||||
globalstate = NC_getglobalstate();
|
||||
rc = globalstate->rcinfo->entries;
|
||||
|
||||
@ -579,19 +690,25 @@ NC_rcfile_insert(const char* key, const char* value, const char* hostport, const
|
||||
globalstate->rcinfo->entries = rc;
|
||||
if(rc == NULL) {ret = NC_ENOMEM; goto done;}
|
||||
}
|
||||
entry = rclocate(key,hostport,path);
|
||||
entry = rclocate(key,hostport,urlpath);
|
||||
if(entry == NULL) {
|
||||
entry = (NCRCentry*)calloc(1,sizeof(NCRCentry));
|
||||
if(entry == NULL) {ret = NC_ENOMEM; goto done;}
|
||||
entry->key = strdup(key);
|
||||
entry->value = NULL;
|
||||
rctrim(entry->key);
|
||||
entry->host = (hostport == NULL ? NULL : strdup(hostport));
|
||||
entry->host = nulldup(hostport);
|
||||
rctrim(entry->host);
|
||||
entry->urlpath = nulldup(urlpath);
|
||||
rctrim(entry->urlpath);
|
||||
nclistpush(rc,entry);
|
||||
}
|
||||
if(entry->value != NULL) free(entry->value);
|
||||
entry->value = strdup(value);
|
||||
rctrim(entry->value);
|
||||
#ifdef DRCDEBUG
|
||||
storedump("NC_rcfile_insert",rc);
|
||||
#endif
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
@ -2105,8 +2105,12 @@ NC_createglobalstate(void)
|
||||
nc_globalstate = calloc(1,sizeof(NCglobalstate));
|
||||
}
|
||||
/* Initialize struct pointers */
|
||||
nc_globalstate->rcinfo = (struct NCRCinfo*)calloc(1,sizeof(struct NCRCinfo));
|
||||
if(nc_globalstate == NULL) return NC_ENOMEM;
|
||||
if((nc_globalstate->rcinfo = calloc(1,sizeof(struct NCRCinfo)))==NULL)
|
||||
{stat = NC_ENOMEM; goto done;}
|
||||
if((nc_globalstate->rcinfo->entries = nclistnew())==NULL)
|
||||
{stat = NC_ENOMEM; goto done;}
|
||||
if((nc_globalstate->rcinfo->s3profiles = nclistnew())==NULL)
|
||||
{stat = NC_ENOMEM; goto done;}
|
||||
|
||||
/* Get environment variables */
|
||||
if(getenv(NCRCENVIGNORE) != NULL)
|
||||
@ -2119,6 +2123,7 @@ NC_createglobalstate(void)
|
||||
nc_globalstate->chunkcache.nelems = CHUNK_CACHE_NELEMS; /**< Default chunk cache number of elements. */
|
||||
nc_globalstate->chunkcache.preemption = CHUNK_CACHE_PREEMPTION; /**< Default chunk cache preemption. */
|
||||
|
||||
done:
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ main(int argc, char **argv)
|
||||
/* This test code based on test code from Jeff Whitaker. See
|
||||
* https://github.com/Unidata/netcdf-c/issues/2357. This is a
|
||||
* simplified version. */
|
||||
int i, varid, ncid;
|
||||
int varid, ncid;
|
||||
int dimids[NDIM2];
|
||||
size_t start[NDIM2] = {0, 0}, count[NDIM2] = {DATALEN2, 1}, dimlen;
|
||||
int data[DATALEN2] = {42, 42};
|
||||
@ -422,7 +422,7 @@ main(int argc, char **argv)
|
||||
SUMMARIZE_ERR;
|
||||
printf("*** testing dimlen with NC_UNLIMITED reopen and rewrite...");
|
||||
{
|
||||
int i, varid, ncid;
|
||||
int varid, ncid;
|
||||
int dimid;
|
||||
size_t start[NDIM1] = {0}, count[NDIM1] = {DATALEN2}, dimlen;
|
||||
int data[DATALEN2] = {42, 42};
|
||||
|
@ -418,7 +418,7 @@ main(int argc, char **argv)
|
||||
if (nc_close(ncid)) ERR;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
#ifdef HAVE_H5Z_SZIP
|
||||
#ifdef HAVE_SZ
|
||||
printf("**** testing simple szip filter setup...");
|
||||
{
|
||||
int ncid;
|
||||
@ -757,6 +757,6 @@ main(int argc, char **argv)
|
||||
if (nc_close(ncid)) ERR;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
#endif /* HAVE_H5Z_SZIP */
|
||||
#endif /* HAVE_SZ */
|
||||
FINAL_RESULTS;
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ IF(ENABLE_TESTS)
|
||||
ADD_EXECUTABLE(nctrunc nctrunc.c)
|
||||
if(RCMERGE)
|
||||
ADD_EXECUTABLE(tst_rcmerge tst_rcmerge.c)
|
||||
ADD_EXECUTABLE(tst_rcmerge tst_rcapi.c)
|
||||
endif()
|
||||
TARGET_LINK_LIBRARIES(rewrite-scalar netcdf)
|
||||
TARGET_LINK_LIBRARIES(bom netcdf)
|
||||
@ -112,6 +113,7 @@ endif()
|
||||
TARGET_LINK_LIBRARIES(nctrunc netcdf)
|
||||
if(RCMERGE)
|
||||
TARGET_LINK_LIBRARIES(tst_rcmerge netcdf)
|
||||
TARGET_LINK_LIBRARIES(tst_rcapi netcdf)
|
||||
endif()
|
||||
|
||||
IF(USE_HDF5)
|
||||
@ -154,6 +156,11 @@ endif()
|
||||
SET_TARGET_PROPERTIES(tst_rcmerge PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_TARGET_PROPERTIES(tst_rcmerge PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_TARGET_PROPERTIES(tst_rcapi PROPERTIES RUNTIME_OUTPUT_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_TARGET_PROPERTIES(tst_rcapi PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_TARGET_PROPERTIES(tst_rcapi PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
IF(USE_HDF5)
|
||||
|
@ -79,7 +79,7 @@ man_MANS = ncdump.1 nccopy.1
|
||||
if BUILD_TESTSETS
|
||||
# C programs needed by shell scripts for classic tests.
|
||||
check_PROGRAMS = rewrite-scalar ref_ctest ref_ctest64 ncdump tst_utf8 \
|
||||
bom tst_dimsizes nctrunc tst_rcmerge
|
||||
bom tst_dimsizes nctrunc tst_rcmerge tst_rcapi
|
||||
|
||||
# Tests for classic and 64-bit offset files.
|
||||
TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ref_ctest \
|
||||
@ -203,7 +203,8 @@ ref_roman_szip_simple.cdl ref_roman_szip_unlim.cdl ref_tst_perdimspecs.cdl \
|
||||
test_keywords.sh ref_keyword1.cdl ref_keyword2.cdl ref_keyword3.cdl ref_keyword4.cdl \
|
||||
ref_tst_nofilters.cdl test_scope.sh \
|
||||
test_rcmerge.sh ref_rcmerge1.txt ref_rcmerge2.txt ref_rcmerge3.txt \
|
||||
scope_ancestor_only.cdl scope_ancestor_subgroup.cdl scope_group_only.cdl scope_preorder.cdl
|
||||
scope_ancestor_only.cdl scope_ancestor_subgroup.cdl scope_group_only.cdl scope_preorder.cdl \
|
||||
ref_rcapi.txt
|
||||
|
||||
# The L512.bin file is file containing exactly 512 bytes each of value 0.
|
||||
# It is used for creating hdf5 files with varying offsets for testing.
|
||||
|
7
ncdump/ref_rcapi.txt
Normal file
7
ncdump/ref_rcapi.txt
Normal file
@ -0,0 +1,7 @@
|
||||
load:
|
||||
insert: key=key1 value=value1
|
||||
insert: before: key1 = (null)
|
||||
insert: after: key1 = value1
|
||||
replace: key=key1 value=value2
|
||||
replace: before: key1 = value1
|
||||
replace: after: key1 = value2
|
@ -54,7 +54,8 @@ resetrc() {
|
||||
rm -fr $HOMERCFILES
|
||||
rm -f $LOCALRCFILES
|
||||
unset NCRCENV_RC
|
||||
rm -f tmpoutput.txt
|
||||
rm -f tmp_rcmerge.txt
|
||||
rm -f tmp_rcapi.txt
|
||||
rm -f allfiles1 allfiles2 allfiles3
|
||||
}
|
||||
|
||||
@ -70,36 +71,40 @@ fi
|
||||
mergecase1() {
|
||||
# create everything with different keys to test merge
|
||||
resetrc
|
||||
rm -f tmp_rcmerge.txt tmpoutput.txt
|
||||
rm -f tmp_rcmerge.txt tmp_rcmerge.txt
|
||||
echo "for r=ncrc daprc dodsrc"
|
||||
for r in "ncrc" "daprc" "dodsrc"; do
|
||||
echo "${r}_home=${r}" >> $RCHOME/".${r}";
|
||||
echo "${r}_local=${r}" >> $WD/".${r}"
|
||||
done;
|
||||
union 1
|
||||
${abs_execdir}/tst_rcmerge |sort > tmpoutput.txt
|
||||
${abs_execdir}/tst_rcmerge |sort > tmp_rcmerge.txt
|
||||
# echo ">>merge1"; cat ${abs_srcdir}/ref_rcmerge1.txt;
|
||||
# echo "====="; cat tmpoutput.txt
|
||||
diff -b ${abs_srcdir}/ref_rcmerge1.txt tmpoutput.txt
|
||||
# echo "====="; cat tmp_rcmerge.txt
|
||||
diff -b ${abs_srcdir}/ref_rcmerge1.txt tmp_rcmerge.txt
|
||||
}
|
||||
|
||||
mergecase2() {
|
||||
# create with some same keys to test override
|
||||
resetrc
|
||||
rm -f tmp_rcmerge.txt tmpoutput.txt
|
||||
rm -f tmp_rcmerge.txt tmp_rcmerge.txt
|
||||
echo "Create in $RCHOME"
|
||||
for r in "ncrc" "daprc" "dodsrc" ; do
|
||||
echo "${r}=${r}" >> $RCHOME/".${r}";
|
||||
done;
|
||||
echo "Create in $WD"
|
||||
for r in "ncrc" "daprc" "dodsrc" ; do
|
||||
echo "${r}=${r}" >> $WD/".${r}"
|
||||
done;
|
||||
union 2
|
||||
${abs_execdir}/tst_rcmerge |sort > tmpoutput.txt
|
||||
diff -b ${abs_srcdir}/ref_rcmerge2.txt tmpoutput.txt
|
||||
${abs_execdir}/tst_rcmerge |sort > tmp_rcmerge.txt
|
||||
diff -b ${abs_srcdir}/ref_rcmerge2.txt tmp_rcmerge.txt
|
||||
}
|
||||
|
||||
mergecase3() {
|
||||
# Test cross file overrides
|
||||
resetrc
|
||||
rm -f tmp_rcmerge.txt tmpoutput.txt
|
||||
rm -f tmp_rcmerge.txt tmp_rcmerge.txt
|
||||
echo "ncrc=ncrc1" >> $HOME/.ncrc
|
||||
echo "ncrcx=ncrcx" >> $RCHOME/.ncrc
|
||||
echo "ncrc=ncrc2" >> $RCHOME/.dodsrc
|
||||
@ -111,8 +116,18 @@ mergecase3() {
|
||||
echo "daprc=daprc" >> $WD/.dodsrc
|
||||
echo "ncrcx=ncrcy" >> $WD/.dodsrc
|
||||
union 3
|
||||
${abs_execdir}/tst_rcmerge |sort -d > tmpoutput.txt
|
||||
diff -b ${abs_srcdir}/ref_rcmerge3.txt tmpoutput.txt
|
||||
${abs_execdir}/tst_rcmerge |sort -d > tmp_rcmerge.txt
|
||||
diff -b ${abs_srcdir}/ref_rcmerge3.txt tmp_rcmerge.txt
|
||||
}
|
||||
|
||||
rcapi1() {
|
||||
resetrc
|
||||
echo "[http://github.com/a/b/c]ncrc=ncrc1" >> $WD/.ncrc
|
||||
echo "ncrc=ncrc2" >> $WD/.ncrc
|
||||
echo "[http://github.com:8080/a/b/c]key0=v0" >> $WD/.ncrc
|
||||
echo "[http://github.com]key0=v1" >> $WD/.ncrc
|
||||
${abs_execdir}/tst_rcapi > tmp_rcapi.txt
|
||||
diff -b ${abs_srcdir}/ref_rcapi.txt ./tmp_rcapi.txt
|
||||
}
|
||||
|
||||
resetrc
|
||||
@ -120,5 +135,10 @@ resetrc
|
||||
mergecase1
|
||||
mergecase2
|
||||
mergecase3
|
||||
# Test the .rc api
|
||||
rcapi1
|
||||
|
||||
# Test the .rc api
|
||||
rcapi1
|
||||
|
||||
resetrc
|
||||
|
92
ncdump/tst_rcapi.c
Executable file
92
ncdump/tst_rcapi.c
Executable file
@ -0,0 +1,92 @@
|
||||
/* This is part of the netCDF package.
|
||||
Copyright 2018 University Corporation for Atmospheric Research/Unidata
|
||||
See COPYRIGHT file for conditions of use.
|
||||
|
||||
Test HDF5 alignment
|
||||
Dennis Heimbigner
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "netcdf.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifndef nullfree
|
||||
#define nullfree(x) {if((x)!=NULL) free(x);}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void
|
||||
printrc(NCglobalstate* ngs)
|
||||
{
|
||||
size_t i,nentries = 0;
|
||||
NCRCinfo* info = NULL;
|
||||
NCRCentry* entry = NULL;
|
||||
|
||||
info = ngs->rcinfo;
|
||||
if(info->ignore) {
|
||||
fprintf(stderr,".rc ignored\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print out the .rc entries */
|
||||
if((nentries = NC_rcfile_length(info))==0) {
|
||||
printf("<empty>\n");
|
||||
exit(0);
|
||||
}
|
||||
for(i=0;i<nentries;i++) {
|
||||
entry = NC_rcfile_ith(info,i);
|
||||
if(entry == NULL) abort();
|
||||
if(entry->host != NULL) {
|
||||
printf("[%s ",entry->host);
|
||||
if(entry->urlpath != NULL)
|
||||
printf("/%s] ",entry->urlpath);
|
||||
printf("]");
|
||||
}
|
||||
printf("|%s|->|%s|\n",entry->key,entry->value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
const char* key;
|
||||
const char* value;
|
||||
char* newvalue;
|
||||
|
||||
printf("load:\n");
|
||||
if ((stat=nc_initialize())) {fprintf(stderr,"***fail\n"); exit(1);}
|
||||
|
||||
key = "key1";
|
||||
value = "value1";
|
||||
printf("insert: key=%s value=%s\n",key, value);
|
||||
newvalue = nc_rc_get(key);
|
||||
printf("insert: before: %s = %s\n",key,newvalue);
|
||||
nullfree(newvalue);
|
||||
stat = nc_rc_set(key, value);
|
||||
newvalue = nc_rc_get(key);
|
||||
printf("insert: after: %s = %s\n",key,newvalue);
|
||||
nullfree(newvalue);
|
||||
|
||||
key = "key1";
|
||||
value = "value2";
|
||||
printf("replace: key=%s value=%s\n",key, value);
|
||||
newvalue = nc_rc_get(key);
|
||||
printf("replace: before: %s = %s\n",key,newvalue);
|
||||
nullfree(newvalue);
|
||||
stat = nc_rc_set(key, value);
|
||||
newvalue = nc_rc_get(key);
|
||||
printf("replace: after: %s = %s\n",key,newvalue);
|
||||
nullfree(newvalue);
|
||||
|
||||
nc_finalize();
|
||||
return 0;
|
||||
}
|
@ -5,23 +5,17 @@
|
||||
#include "ncrc.h"
|
||||
#include "nc4internal.h"
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
static void
|
||||
printrc(NCglobalstate* ngs)
|
||||
{
|
||||
size_t i,nentries = 0;
|
||||
NCglobalstate* ngs = NC_getglobalstate();
|
||||
NCRCinfo* info = NULL;
|
||||
NCRCentry* entry = NULL;
|
||||
|
||||
/* Cause the .rc files to be read and merged */
|
||||
nc_initialize();
|
||||
|
||||
if((ngs = NC_getglobalstate())==NULL) abort();
|
||||
info = ngs->rcinfo;
|
||||
|
||||
if(info->ignore) {
|
||||
fprintf(stderr,".rc ignored\n");
|
||||
exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print out the .rc entries */
|
||||
@ -34,11 +28,24 @@ main(int argc, char** argv)
|
||||
if(entry == NULL) abort();
|
||||
if(entry->host != NULL) {
|
||||
printf("[%s ",entry->host);
|
||||
if(entry->path != NULL)
|
||||
printf("/%s] ",entry->path);
|
||||
if(entry->urlpath != NULL)
|
||||
printf("/%s] ",entry->urlpath);
|
||||
printf("]");
|
||||
}
|
||||
printf("|%s|->|%s|\n",entry->key,entry->value);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
NCglobalstate* ngs = NC_getglobalstate();
|
||||
|
||||
/* Cause the .rc files to be read and merged */
|
||||
nc_initialize();
|
||||
|
||||
if((ngs = NC_getglobalstate())==NULL) abort();
|
||||
printrc(ngs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user