/* return 1 if path looks like a url; 0 otherwise */ int NC_testurl(const char* path) { int isurl = 0; NCURI* tmpurl = NULL; char* p; if(path == NULL) return 0; /* find leading non-blank */ for(p=(char*)path;*p;p++) {if(*p != ' ') break;} /* Do some initial checking to see if this looks like a file path */ if(*p == '/') return 0; /* probably an absolute file path */ /* Ok, try to parse as a url */ if(ncuriparse(path,&tmpurl)) { /* Do some extra testing to make sure this really is a url */ /* Look for a knownprotocol */ struct NCPROTOCOLLIST* protolist; for(protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(tmpurl->protocol,protolist->protocol) == 0) { isurl=1; break; } } ncurifree(tmpurl); return isurl; } return 0; }
NCerror freeNCDAPCOMMON(NCDAPCOMMON* dapcomm) { /* abort the metadata file */ (void)nc_abort(getncid(dapcomm)); freenccache(dapcomm,dapcomm->cdf.cache); nclistfree(dapcomm->cdf.projectedvars); nullfree(dapcomm->cdf.recorddimname); /* free the trees */ freecdfroot34(dapcomm->cdf.ddsroot); dapcomm->cdf.ddsroot = NULL; freecdfroot34(dapcomm->cdf.fullddsroot); dapcomm->cdf.fullddsroot = NULL; if(dapcomm->oc.ocdasroot != NULL) oc_root_free(dapcomm->oc.conn,dapcomm->oc.ocdasroot); dapcomm->oc.ocdasroot = NULL; oc_close(dapcomm->oc.conn); /* also reclaims remaining OC trees */ ncurifree(dapcomm->oc.url); nullfree(dapcomm->oc.urltext); nullfree(dapcomm->oc.rawurltext); dcefree((DCEnode*)dapcomm->oc.dapconstraint); dapcomm->oc.dapconstraint = NULL; free(dapcomm); return NC_NOERR; }
int NC_urlmodel(const char* path) { int model = 0; NCURI* tmpurl = NULL; struct NCPROTOCOLLIST* protolist; if(!ncuriparse(path,&tmpurl)) goto done; /* Look at any prefixed parameters */ if(ncurilookup(tmpurl,"netcdf4",NULL) || ncurilookup(tmpurl,"netcdf-4",NULL)) { model = (NC_DISPATCH_NC4|NC_DISPATCH_NCD); } else if(ncurilookup(tmpurl,"netcdf3",NULL) || ncurilookup(tmpurl,"netcdf-3",NULL)) { model = (NC_DISPATCH_NC3|NC_DISPATCH_NCD); } else if(ncurilookup(tmpurl,"cdmremote",NULL) || ncurilookup(tmpurl,"cdmr",NULL)) { model = (NC_DISPATCH_NCR|NC_DISPATCH_NC4); } if(model == 0) { /* Now look at the protocol */ for(protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(tmpurl->protocol,protolist->protocol) == 0) { model |= protolist->modelflags; if(protolist->substitute) { if(tmpurl->protocol) free(tmpurl->protocol); tmpurl->protocol = strdup(protolist->substitute); } break; } } } /* Force NC_DISPATCH_NC3 if necessary */ if((model & NC_DISPATCH_NC4) == 0) model |= (NC_DISPATCH_NC3 | NC_DISPATCH_NCD); done: ncurifree(tmpurl); return model; }
int nc__testurl(const char* path, char** basenamep) { NCURI* uri; int ok = 0; if(ncuriparse(path,&uri) == NCU_OK) { char* slash = (uri->path == NULL ? NULL : strrchr(uri->path, '/')); char* dot; if(slash == NULL) slash = (char*)path; else slash++; slash = nulldup(slash); if(slash == NULL) dot = NULL; else dot = strrchr(slash, '.'); if(dot != NULL && dot != slash) *dot = '\0'; if(basenamep) *basenamep=slash; else if(slash) free(slash); ncurifree(uri); ok = 1; } return ok; }
/* return 1 if path looks like a url; 0 otherwise */ int NC_testurl(const char* path) { int isurl = 0; NCURI* tmpurl = NULL; if(path == NULL) return 0; /* Ok, try to parse as a url */ if(ncuriparse(path,&tmpurl)==NCU_OK) { /* Do some extra testing to make sure this really is a url */ /* Look for a known/accepted protocol */ struct NCPROTOCOLLIST* protolist; for(protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(tmpurl->protocol,protolist->protocol) == 0) { isurl=1; break; } } ncurifree(tmpurl); return isurl; } return 0; }
int NC_infermodel(const char* path, int* omodep, int iscreate, int useparallel, void* params, NCmodel* model, char** newpathp) { int stat = NC_NOERR; char* newpath = NULL; NCURI* uri = NULL; int omode = *omodep; int isuri = 0; NClist* modeargs = nclistnew(); if((stat = processuri(path, &uri, &newpath, modeargs))) goto done; isuri = (uri != NULL); /* Phase 1: compute the IOSP */ if((stat = extractiosp(modeargs,omode,model))) goto done; assert(model->iosp != 0); /* Phase 2: Process the non-iosp mode arguments */ if(!modelcomplete(model) && isuri) { int i; for(i=0;i<nclistlength(modeargs);i++) { const char* arg = nclistget(modeargs,i); if((stat=processmodearg(arg,model))) goto done; } } /* Phase 3: See if we can infer DAP */ if(!modelcomplete(model) && isuri) { if((stat = NC_dapinfer(modeargs,model))) goto done; } /* Phase 4: mode inference */ if(!modelcomplete(model)) { if((stat = NC_omodeinfer(omode,model))) goto done; } /* Phase 5: Infer from file content, if possible; this has highest precedence, so it may override previous decisions. */ if(!iscreate && isreadable(model->iosp)) { /* Ok, we need to try to read the file */ if((stat = check_file_type(path, omode, useparallel, params, model, uri))) goto done; } /* Phase 6: Infer impl from format */ if(!modelcomplete(model)) { if((stat = NC_implinfer(useparallel, model))) goto done; } assert(modelcomplete(model)); /* Force flag consistency */ switch (model->impl) { case NC_FORMATX_NC4: case NC_FORMATX_NC_HDF4: case NC_FORMATX_DAP4: case NC_FORMATX_UDF0: case NC_FORMATX_UDF1: omode |= NC_NETCDF4; if(model->format == NC_FORMAT_NETCDF4_CLASSIC) omode |= NC_CLASSIC_MODEL; break; case NC_FORMATX_DAP2: omode &= ~(NC_NETCDF4|NC_64BIT_OFFSET|NC_64BIT_DATA); break; case NC_FORMATX_NC3: omode &= ~NC_NETCDF4; /* must be netcdf-3 (CDF-1, CDF-2, CDF-5) */ if(model->format == NC_FORMAT_64BIT_OFFSET) omode |= NC_64BIT_OFFSET; else if(model->format == NC_FORMAT_64BIT_DATA) omode |= NC_64BIT_DATA; break; case NC_FORMATX_PNETCDF: omode &= ~NC_NETCDF4; /* must be netcdf-3 (CDF-1, CDF-2, CDF-5) */ if(model->format == NC_FORMAT_64BIT_OFFSET) omode |= NC_64BIT_OFFSET; else if(model->format == NC_FORMAT_64BIT_DATA) omode |= NC_64BIT_DATA; break; default: {stat = NC_ENOTNC; goto done;} } done: if(uri) ncurifree(uri); nclistfreeall(modeargs); if(stat == NC_NOERR && newpathp) {*newpathp = newpath; newpath = NULL;} nullfree(newpath); *omodep = omode; /* in/out */ return check(stat); }
static int processuri(const char* path, NCURI** urip, char** newpathp, NClist* modeargs) { int stat = NC_NOERR; int found = 0; const char** fragp = NULL; struct NCPROTOCOLLIST* protolist; NCURI* uri = NULL; size_t pathlen = strlen(path); if(path == NULL || pathlen == 0) {stat = NC_EURL; goto done;} /* Defaults */ if(newpathp) *newpathp = NULL; if(urip) *urip = NULL; if(ncuriparse(path,&uri) != NCU_OK) goto done; /* not url */ /* Look up the protocol */ for(found=0,protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(uri->protocol,protolist->protocol) == 0) { found = 1; break; } } if(!found) {stat = NC_EINVAL; goto done;} /* unrecognized URL form */ /* process the corresponding mode arg */ if(protolist->mode != NULL) nclistpush(modeargs,strdup(protolist->mode)); /* Substitute the protocol in any case */ if(protolist->substitute) ncurisetprotocol(uri,protolist->substitute); /* Iterate over the url fragment parameters */ for(fragp=ncurifragmentparams(uri);fragp && *fragp;fragp+=2) { const char* name = fragp[0]; const char* value = fragp[1]; if(strcmp(name,"protocol")==0) { nclistpush(modeargs,strdup(value)); } else if(strcmp(name,"mode")==0) { if((stat = parseurlmode(value,modeargs))) goto done; } else if(issingleton(name) && (value == NULL || strlen(value)==0)) { nclistpush(modeargs,strdup(name)); } /*else ignore*/ } /* At this point modeargs should contain all mode args from the URL */ /* Rebuild the path (including fragment)*/ if(newpathp) *newpathp = ncuribuild(uri,NULL,NULL,NCURIALL); if(urip) { *urip = uri; uri = NULL; } done: if(uri != NULL) ncurifree(uri); return check(stat); }
/* Do a simple uri parse: return 0 if fail, 1 otherwise*/ int ncuriparse(const char* uri0, NCURI** durip) { NCURI* duri = NULL; char* uri = NULL; char* p; struct NC_ProtocolInfo* proto; int i,nprotos; /* accumulate parse points*/ char* protocol = NULL; char* host = NULL; char* port = NULL; char* constraint = NULL; char* user = NULL; char* pwd = NULL; char* file = NULL; char* prefixparams = NULL; char* suffixparams = NULL; if(uri0 == NULL || strlen(uri0) == 0) {THROW(1); goto fail;} duri = (NCURI*)calloc(1,sizeof(NCURI)); if(duri == NULL) {THROW(2); goto fail;} /* save original uri */ duri->uri = nulldup(uri0); /* make local copy of uri */ uri = (char*)malloc(strlen(uri0)+1+PADDING); /* +1 for trailing null, +PADDING for shifting */ if(uri == NULL) {THROW(3); goto fail;} /* strings will be broken into pieces with intermixed '\0; characters; first char is guaranteed to be '\0' */ duri->strings = uri; uri++; /* dup the incoming url */ strcpy(uri,uri0); /* Walk the uri and do the following: 1. remove all whitespace 2. remove all '\\' (Temp hack to remove escape characters inserted by Windows or MinGW) */ for(p=uri;*p;p++) { if(*p == '\\' || *p < ' ') nclshift1(p); /* compress out */ } p = uri; /* break up the uri string into big chunks: prefixparams, protocol, host section, and the file section (i.e. remainder) */ /* collect any prefix bracketed parameters */ if(*p == LBRACKET) { prefixparams = p+1; /* find end of the clientparams; convert LB,RB to '&' */ for(;*p;p++) { if(p[0] == RBRACKET && p[1] == LBRACKET) { p[0] = '&'; nclshift1(p+1); } else if(p[0] == RBRACKET && p[1] != LBRACKET) break; } if(*p == 0) {THROW(4); goto fail; /* malformed client params*/} terminate(p); /* nul term the prefixparams (overwrites the final RBRACKET) */ p++; /* move past the final RBRACKET */ } /* Tag the protocol */ protocol = p; p = strchr(p,':'); if(!p) {THROW(5); goto fail;} terminate(p); /*overwrite colon*/ p++; /* skip the colon */ /* verify that the uri starts with an acceptable protocol*/ nprotos = (sizeof(legalprotocols)/sizeof(struct NC_ProtocolInfo)); proto = NULL; for(i=0;i<nprotos;i++) { if(strcmp(protocol,legalprotocols[i].name)==0) { proto = &legalprotocols[i]; break; } } if(proto == NULL) {THROW(6); goto fail; /* illegal protocol*/} /* skip // */ if(p[0] != '/' && p[1] != '/') {THROW(7); goto fail;} p += 2; /* If this is all we have (proto://) then fail */ if(*p == EOFCHAR) {THROW(8); goto fail;} /* establish the start of the file section */ if(proto->filelike) {/* everything after proto:// */ file = p; host = NULL; /* and no host section */ } else { /*!proto->filelike => This means there should be a host section */ /* locate the end of the host section and therefore the start of the file section */ host = p; p = nclocate(p,"/?#"); if(p == NULL) { file = endof(host); /* there is no file section */ } else { ncrshift1(p); /* make room to terminate the host section without overwriting the leading character */ terminate(p); /* terminate the host section */ file = p+1; /* +1 becauseof the shift */ } } /* If you shift in the code below, you must reset file beginning */ if(host != NULL) {/* Parse the host section */ /* Check for leading user:pwd@ */ p = strchr(host,'@'); if(p) { if(p == host) {THROW(9); goto fail; /* we have proto://@ */} user = host; terminate(p); /* overwrite '@' */ host = p+1; /* start of host ip name */ p = strchr(user,':'); if(p == NULL) {THROW(10); goto fail; /* malformed */} terminate(p); /*overwrite colon */ pwd = p+1; } /* extract host and port */ p = host; p = strchr(p,':'); if(p != NULL) { terminate(p); p++; port = p; if(*port == EOFCHAR) {THROW(11); goto fail; /* we have proto://...:/ */} /* The port must look something like a number */ for(;*p;p++) { if(strchr("0123456789-",*p) == NULL) {THROW(12); goto fail; /* probably not a real port, fail */} } } /* else *p == NULL */ /* check for empty host section */ if(*host == EOFCHAR) {THROW(13); goto fail;} } assert(file != NULL); p = file; /* find the end of the file section and the start of the constraints and/or suffixparams */ p = nclocate(p,"?#"); if(p != NULL) { /* we have constraint and/or suffixparams */ char* fileend = p; /* save the end of the file section */ char* constraintend = NULL; if(*p == '?') constraint = p+1; else constraint = NULL; p = strchr(p,'#'); /* may repeat effect of nclocate above */ if(p != NULL) { constraintend = p; suffixparams = p+1; } else suffixparams = NULL; /* Ok, terminate the pieces */ terminate(fileend); /* terminate file section */ if(constraint != NULL && constraintend != NULL) terminate(constraintend); /* Suffix params are already terminated since they should be the last section of the original url */ } /* check for empty sections */ if(file != NULL && *file == EOFCHAR) file = NULL; /* empty file section */ if(constraint != NULL && *constraint == EOFCHAR) constraint = NULL; /* empty constraint section */ if(suffixparams != NULL && *suffixparams == EOFCHAR) suffixparams = NULL; /* empty suffixparams section */ if(suffixparams != NULL) { /* there really are suffix params; so rebuild the suffix params */ if(*suffixparams == LBRACKET) suffixparams++; p = suffixparams; /* convert RBRACKET LBRACKET to '&' */ for(;*p;p++) { if(p[0] == RBRACKET && p[1] == LBRACKET) { p[0] = '&'; nclshift1(p+1); } else if(p[0] == RBRACKET && p[1] != LBRACKET) { /* terminate suffixparams */ *p = EOFCHAR; break; } } if(*suffixparams == EOFCHAR) suffixparams = NULL; /* suffixparams are empty */ } /* do last minute empty check */ if(protocol != NULL && *protocol == EOFCHAR) protocol = NULL; if(user != NULL && *user == EOFCHAR) user = NULL; if(pwd != NULL && *pwd == EOFCHAR) pwd = NULL; if(host != NULL && *host == EOFCHAR) host = NULL; if(port != NULL && *port == EOFCHAR) port = NULL; if(file != NULL && *file == EOFCHAR) file = NULL; if(constraint != NULL && *constraint == EOFCHAR) constraint = NULL; /* assemble the component pieces */ duri->protocol = protocol; duri->user = user; duri->password = pwd; duri->host = host; duri->port = port; duri->file = file; ncurisetconstraints(duri,constraint); /* concat suffix and prefix params */ if(prefixparams != NULL || suffixparams != NULL) { int plen = prefixparams ? strlen(prefixparams) : 0; int slen = suffixparams ? strlen(suffixparams) : 0; int space = plen + slen + 1; /* add 1 for an extra ampersand if both are defined */ space++; duri->params = (char*)malloc(space); duri->params[0] = EOFCHAR; /* so we can use strcat */ if(plen > 0) { strcat(duri->params,prefixparams); if(slen > 0) strcat(duri->params,"&"); } if(slen > 0) strcat(duri->params,suffixparams); } #ifdef NCXDEBUG { fprintf(stderr,"duri:"); fprintf(stderr," params=|%s|",FIX(duri->params)); fprintf(stderr," protocol=|%s|",FIX(duri->protocol)); fprintf(stderr," host=|%s|",FIX(duri->host)); fprintf(stderr," port=|%s|",FIX(duri->port)); fprintf(stderr," file=|%s|",FIX(duri->file)); fprintf(stderr," constraint=|%s|",FIX(duri->constraint)); fprintf(stderr,"\n"); } #endif if(durip != NULL) *durip = duri; else ncurifree(duri); return 1; fail: if(duri != NULL) { ncurifree(duri); } return 0; }
int NC_urlmodel(const char* path, int cmode, char** newurl, NCmode* model) { int stat = NC_NOERR; int found = 0; struct NCPROTOCOLLIST* protolist; NCURI* url = NULL; const char** fragp = NULL; if(path == NULL) return 0; /* Parse the url */ if(ncuriparse(path,&url) != NCU_OK) return NC_EINVAL; /* Not parseable as url */ /* Look up the protocol */ for(found=0,protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(url->protocol,protolist->protocol) == 0) { found = 1; break; } } if(found) { model->implementation = protolist->implementation; /* Substitute the protocol in any case */ if(protolist->substitute) ncurisetprotocol(url,protolist->substitute); } else {stat = NC_EINVAL; goto done;} /* Again, does not look like a url */ /* Iterate over the url fragment parameters */ for(fragp=ncurifragmentparams(url);fragp && *fragp;fragp+=2) { const char* name = fragp[0]; const char* value = fragp[1]; if(strcmp(name,"protocol")==0) name = value; if(strcasecmp(name,"dap2") == 0) { model->format = NC_FORMAT_NC3; model->implementation = NC_FORMATX_DAP2; /* No need to set iosp field */ } else if(strcasecmp(name,"dap4") == 0) { model->format = NC_FORMAT_NETCDF4; model->implementation = NC_FORMATX_DAP4; /* No need to set iosp field */ } else if(strcmp(name,"mode")==0) { if((stat = url_getmodel(value,model))) goto done; } } if(model->implementation == 0) {/* Last resort: use the cmode */ /* If mode specifies netcdf-4, then this is assumed to be dap4 */ if(cmode & NC_NETCDF4) { model->implementation = NC_FORMATX_DAP4; } else {/* Default is DAP2 */ model->implementation = NC_FORMATX_DAP2; } } if(model->implementation == 0) goto done; /* could not interpret */ switch (model->implementation) { case NC_FORMATX_NC3: model->format = NC_FORMAT_NC3; break; case NC_FORMATX_NC4: model->format = NC_FORMAT_NETCDF4; break; case NC_FORMATX_DAP2: model->format = NC_FORMAT_NC3; break; case NC_FORMATX_DAP4: model->format = NC_FORMAT_NETCDF4; break; case NC_FORMATX_ZARR: model->format = NC_FORMAT_NETCDF4; break; default: stat = NC_EINVAL; goto done; } done: if(newurl) *newurl = ncuribuild(url,NULL,NULL,NCURIALL); if(url) ncurifree(url); return stat; }
int NC_urlmodel(const char* path, int mode, char** newurl) { int found, model = 0; struct NCPROTOCOLLIST* protolist; NCURI* url = NULL; char* p; if(path == NULL) return 0; /* find leading non-blank */ for(p=(char*)path;*p;p++) {if(*p != ' ') break;} /* Do some initial checking to see if this looks like a file path */ if(*p == '/') return 0; /* probably an absolute file path */ /* Parse the url */ if(ncuriparse(path,&url) != NCU_OK) goto fail; /* Not parseable as url */ /* Look up the protocol */ for(found=0,protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(url->protocol,protolist->protocol) == 0) { found = 1; break; } } if(found) { model = protolist->model; /* Substitute the protocol in any case */ if(protolist->substitute) ncurisetprotocol(url,protolist->substitute); } else goto fail; /* Again, does not look like a url */ if(model != NC_FORMATX_DAP2 && model != NC_FORMATX_DAP4) { /* Look for and of the following params: "dap2", "protocol=dap2", "dap4", "protocol=dap4" */ const char* proto = NULL; const char* match = NULL; if((proto=ncurilookup(url,"protocol")) == NULL) proto = NULL; if(proto == NULL) proto = ""; if((match=ncurilookup(url,"dap2")) != NULL || strcmp(proto,"dap2") == 0) model = NC_FORMATX_DAP2; else if((match=ncurilookup(url,"dap4")) != NULL || strcmp(proto,"dap4") == 0) model = NC_FORMATX_DAP4; else model = 0; /* Still don't know */ } if(model == 0) {/* Last resort: use the mode */ /* If mode specifies netcdf-4, then this is assumed to be dap4 */ if(mode & NC_NETCDF4) model = NC_FORMATX_DAP4; else model = NC_FORMATX_DAP2; /* Default */ } if(newurl) *newurl = ncuribuild(url,NULL,NULL,NCURIALL); if(url) ncurifree(url); return model; fail: if(url) ncurifree(url); return 0; }