/* return 1 if path looks like a url; 0 otherwise */ int NC_testurl(const char* path) { int isurl = 0; NC_URI* 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(nc_uriparse(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; } } nc_urifree(tmpurl); return isurl; } return 0; }
int NC_urlmodel(const char* path) { int model = 0; NC_URI* tmpurl = NULL; struct NCPROTOCOLLIST* protolist; if(!nc_uriparse(path,&tmpurl)) goto done; /* Look at any prefixed parameters */ if(nc_urilookup(tmpurl,"netcdf4",NULL) || nc_urilookup(tmpurl,"netcdf-4",NULL)) { model = (NC_DISPATCH_NC4|NC_DISPATCH_NCD); } else if(nc_urilookup(tmpurl,"netcdf3",NULL) || nc_urilookup(tmpurl,"netcdf-3",NULL)) { model = (NC_DISPATCH_NC3|NC_DISPATCH_NCD); } else if(nc_urilookup(tmpurl,"cdmremote",NULL) || nc_urilookup(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: nc_urifree(tmpurl); return model; }
/* Do a simple uri parse: return 0 if fail, 1 otherwise*/ int nc_uriparse(const char* uri0, NC_URI** nc_urip) { NC_URI* nc_uri = NULL; char* uri; char** pp; char* p; char* p1; int c; /* accumulate parse points*/ char* protocol = NULL; char* params = NULL; char* host = NULL; char* port = NULL; char* constraint = NULL; char* user = NULL; char* pwd = NULL; char* file = NULL; /* char* stop; */ nc_uri = (NC_URI*)calloc(1,sizeof(NC_URI)); if(nc_uri == NULL) return 0; /* make local copy of uri */ uri = nulldup(uri0); /* remove all whitespace*/ p = uri; p1 = uri; while((c=*p1++)) {if(c != ' ' && c != '\t') *p++ = c;} p = uri; /* stop = p + strlen(p); */ /* break up the uri string into pieces*/ /* 1. leading bracketed parameters */ if(*p == LBRACKET) { params = p+1; /* find end of the clientparams*/ for(;*p;p++) {if(p[0] == RBRACKET && p[1] != LBRACKET) break;} if(*p == 0) goto fail; /* malformed client params*/ *p = '\0'; /* leave off the trailing rbracket for now */ p++; /* move past the params*/ } /* verify that the uri starts with an acceptable protocol*/ for(pp=legalprotocols;*pp;pp++) { if(strncmp(p,*pp,strlen(*pp))==0) break; } if(*pp == NULL) goto fail; /* illegal protocol*/ /* save the protocol */ protocol = *pp; /* 4. skip protocol */ p += strlen(protocol); /* 5. skip // */ if(*p != '/' && *(p+1) != '/') goto fail; p += 2; /* 6. Mark the end of the host section */ file = strchr(p,'/'); if(file) { *file++ = '\0'; /* warning: we just overwrote the leading / */ } /* 7. extract any user:pwd */ p1 = strchr(p,'@'); if(p1) {/* Assume we have user:pwd@ */ *p1 = '\0'; user = p; pwd = strchr(p,':'); if(!pwd) goto fail; /* malformed */ *pwd++ = '\0'; p = pwd+strlen(pwd)+1; } /* 8. extract host and port */ host = p; port = strchr(p,':'); if(port) { *port++ = '\0'; } /* 9. Look for '?' */ constraint = strchr(file,'?'); if(constraint) { *constraint++ = '\0'; } /* assemble the component pieces*/ if(uri0 && strlen(uri0) > 0) nc_uri->uri = nulldup(uri0); if(protocol && strlen(protocol) > 0) { nc_uri->protocol = nulldup(protocol); /* remove trailing ':' */ nc_uri->protocol[strlen(protocol)-1] = '\0'; } if(user && strlen(user) > 0) nc_uri->user = nulldup(user); if(pwd && strlen(pwd) > 0) nc_uri->password = nulldup(pwd); if(host && strlen(host) > 0) nc_uri->host = nulldup(host); if(port && strlen(port) > 0) nc_uri->port = nulldup(port); if(file && strlen(file) > 0) { /* Add back the leading / */ nc_uri->file = malloc(strlen(file)+2); strcpy(nc_uri->file,"/"); strcat(nc_uri->file,file); } if(constraint && strlen(constraint) > 0) nc_uri->constraint = nulldup(constraint); nc_urisetconstraints(nc_uri,constraint); if(params != NULL && strlen(params) > 0) { nc_uri->params = (char*)malloc(1+2+strlen(params)); strcpy(nc_uri->params,"["); strcat(nc_uri->params,params); strcat(nc_uri->params,"]"); } #ifdef NC_XDEBUG { fprintf(stderr,"nc_uri:"); fprintf(stderr," params=|%s|",FIX(nc_uri->params)); fprintf(stderr," protocol=|%s|",FIX(nc_uri->protocol)); fprintf(stderr," host=|%s|",FIX(nc_uri->host)); fprintf(stderr," port=|%s|",FIX(nc_uri->port)); fprintf(stderr," file=|%s|",FIX(nc_uri->file)); fprintf(stderr," constraint=|%s|",FIX(nc_uri->constraint)); fprintf(stderr,"\n"); } #endif free(uri); if(nc_urip != NULL) *nc_urip = nc_uri; return 1; fail: if(nc_uri) nc_urifree(nc_uri); if(uri != NULL) free(uri); return 0; }