コード例 #1
0
ファイル: ddispatch.c プロジェクト: SiggyF/netcdf-c
/* 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;
}
コード例 #2
0
ファイル: ncdap3a.c プロジェクト: UV-CDAT/netcdf
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;
}
コード例 #3
0
ファイル: ddispatch.c プロジェクト: SiggyF/netcdf-c
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;
}
コード例 #4
0
ファイル: dinfermodel.c プロジェクト: Unidata/netcdf-c
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;
}
コード例 #5
0
ファイル: dinfermodel.c プロジェクト: Unidata/netcdf-c
/* 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;
}
コード例 #6
0
ファイル: dinfermodel.c プロジェクト: Unidata/netcdf-c
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);
}
コード例 #7
0
ファイル: dinfermodel.c プロジェクト: Unidata/netcdf-c
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);
}
コード例 #8
0
ファイル: ncuri.c プロジェクト: SiggyF/netcdf-c
/* 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;
}
コード例 #9
0
ファイル: durlmodel.c プロジェクト: Unidata/netcdf-c
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;
}
コード例 #10
0
ファイル: ddispatch.c プロジェクト: wkliao/netcdf-c
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;
}