netcdf-c/libdap2/dapattr.c
Dennis Heimbigner e632d02041 Re-enable DAP2 authorization tests
The thredds-test server now has some password protected datasets
that can be used to test DAP2 authorization support.
The general location is
````
https://thredds.ucar.edu/thredds/tdscapabilities/authTest.html
````
and specifically:
````
https://thredds.ucar.edu/thredds/dodsC/test3/testData.nc.html
````

This PR replaces old testcases with ncdap_test/testauth.sh.
This testcase allows us to test use of the .dodsrc file and .netrc file
and embedded user+pwd.

As part of this, I had to create a program (ncdap_test/pathcvt.c)
that is essentially the equivalent to cygpath. Given a path in
windows, unix, msys or cygwin format, it converts it to the
equivalent format in one of those four cases.  So it can be used
to convert a cygwin path to a windows path, for example. This is
needed in testpathcvt and testauth to make sure that the paths
in .daprc (e.g. the reference to .netrc) are of the proper
format.

Misc. Other Changes:
1. Fix some memory leaks in libdap2
2. Setting the env variable CURLOPT_VERBOSE allows tracking of curl
   operations.
3. Make tst_charvlenbug be conditional on NC_VLEN_NOTEST.
2021-05-29 21:30:33 -06:00

160 lines
4.6 KiB
C

/*********************************************************************
* Copyright 2018, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*********************************************************************/
#include "dapincludes.h"
#define OCCHECK(exp) if((ocstat = (exp))) {THROWCHK(ocstat); goto done;}
/* Forward */
static NCerror buildattribute(char*,nc_type,size_t,char**,NCattribute**);
/*
Invoke oc_merge_das and then extract special
attributes such as "strlen" and "dimname"
and stuff from DODS_EXTRA.
*/
int
dapmerge(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCddsnode dasroot)
{
int i,j;
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
NClist* allnodes;
OClink conn;
char* ocname = NULL;
char** values = NULL;
conn = nccomm->oc.conn;
if(ddsroot == NULL || dasroot == NULL)
return NC_NOERR;
/* Merge the das tree onto the dds tree */
ocstat = oc_merge_das(nccomm->oc.conn,dasroot,ddsroot->ocnode);
if(ocstat != OC_NOERR) goto done;
/* Create attributes on CDFnodes */
allnodes = ddsroot->tree->nodes;
for(i=0;i<nclistlength(allnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(allnodes,i);
OCddsnode ocnode = node->ocnode;
size_t attrcount;
OCtype ocetype;
OCCHECK(oc_dds_attr_count(conn,ocnode,&attrcount));
for(j=0;j<attrcount;j++) {
size_t nvalues;
NCattribute* att = NULL;
if(ocname != NULL) {
free(ocname); ocname = NULL;
} /* from last loop */
OCCHECK(oc_dds_attr(conn,ocnode,j,&ocname,&ocetype,&nvalues,NULL));
if(nvalues > 0) {
values = (char**)malloc(sizeof(char*)*nvalues);
if(values == NULL) {ncstat = NC_ENOMEM; goto done;}
OCCHECK(oc_dds_attr(conn,ocnode,j,NULL,NULL,NULL,values));
}
ncstat = buildattribute(ocname,octypetonc(ocetype),nvalues,values,&att);
if(ncstat != NC_NOERR) goto done;
if(node->attributes == NULL)
node->attributes = nclistnew();
nclistpush(node->attributes,(void*)att);
if(strncmp(ocname,"DODS",strlen("DODS"))==0) {
att->invisible = 1;
/* Define extra semantics associated with
DODS and DODS_EXTRA attributes */
if(strcmp(ocname,"DODS.strlen")==0
|| strcmp(ocname,"DODS_EXTRA.strlen")==0) {
unsigned int maxstrlen = 0;
if(values != NULL) {
if(0==sscanf(values[0],"%u",&maxstrlen))
maxstrlen = 0;
}
node->dodsspecial.maxstrlen = maxstrlen;
#ifdef DEBUG
fprintf(stderr,"%s.maxstrlen=%d\n",node->ocname,(int)node->dodsspecial.maxstrlen);
#endif
} else if(strcmp(ocname,"DODS.dimName")==0
|| strcmp(ocname,"DODS_EXTRA.dimName")==0) {
nullfree(node->dodsspecial.dimname); /* in case repeated */
node->dodsspecial.dimname = NULL;
if(values != NULL) {
nullfree(node->dodsspecial.dimname);
node->dodsspecial.dimname = nulldup(values[0]);
#ifdef DEBUG
fprintf(stderr,"%s.dimname=%s\n",node->ocname,node->dodsspecial.dimname);
#endif
} else {
nullfree(node->dodsspecial.dimname);
node->dodsspecial.dimname = NULL;
}
} else if(strcmp(ocname,"DODS.Unlimited_Dimension")==0
|| strcmp(ocname,"DODS_EXTRA.Unlimited_Dimension")==0) {
char* val0 = NULL;
if(values != NULL)
val0 = values[0];
if(val0 != NULL) {
if(nccomm->cdf.recorddimname != NULL) {
if(strcmp(nccomm->cdf.recorddimname,val0)!=0)
nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications");
} else {
nccomm->cdf.recorddimname = nulldup(values[0]);
#ifdef DEBUG
fprintf(stderr,"%s.Unlimited_Dimension=%s\n",node->ocname,nccomm->cdf.recorddimname);
#endif
}
}
}
}
/* clean up */
if(values) {
oc_reclaim_strings(nvalues,values);
free(values);
values = NULL;
}
}
}
done:
if(values != NULL) free(values);
if(ocname != NULL) free(ocname);
if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
return THROW(ncstat);
}
/*
Build an NCattribute
from a DAP attribute.
As of Jun 27, 2017, we modify
to suppress nul characters and terminate
the name at the first nul.
*/
static NCerror
buildattribute(char* name, nc_type ptype,
size_t nvalues, char** values, NCattribute** attp)
{
int i;
NCerror ncstat = NC_NOERR;
NCattribute* att = NULL;
att = (NCattribute*)calloc(1,sizeof(NCattribute));
MEMCHECK(att,NC_ENOMEM);
att->name = nulldup(name);
att->etype = ptype;
att->values = nclistnew();
for(i=0;i<nvalues;i++) {
char* copy = nulldup(values[i]);
nclistpush(att->values,(void*)copy);
}
if(attp) *attp = att;
else
free(att);
return THROW(ncstat);
}