static int readfile(char* path, char* suffix, OCbytes* packet) { int stat; char buf[1024]; char filename[1024]; int count,size,fd; /* check for leading file:/// */ if(strncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/ strcpy(filename,path); if(suffix != NULL) strcat(filename,suffix); fd = open(filename,O_RDONLY); if(fd < 0) { oc_log(LOGERR,"open failed:%s",filename); return THROW(OC_EOPEN); } size=0; stat = OC_NOERR; for(;;) { count = read(fd,buf,sizeof(buf)); if(count <= 0) break; else if(count < 0) { stat = OC_EIO; oc_log(LOGERR,"read failed: %s",filename); break; } ocbytesappendn(packet,buf,count); size += count; } close(fd); return THROW(stat); }
/* Set curl properties for link based on rc files */ static void ocsetcurlproperties(OCstate* state) { CURLcode cstat = CURLE_OK; /* process the triple store wrt to this state */ if(ocdodsrc_process(state) != OC_NOERR) { oc_log(LOGERR,"Malformed .opendaprc configuration file"); goto fail; } if(state->creds.username == NULL && state->creds.password == NULL) { if(state->uri->user != NULL && state->uri->password != NULL) { /* this overrides .dodsrc */ if(state->creds.password) free(state->creds.password); state->creds.password = nulldup(state->uri->password); if(state->creds.username) free(state->creds.username); state->creds.username = nulldup(state->uri->user); } } return; fail: if(cstat != CURLE_OK) oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); return; }
static OCerror createtempfile(OCstate* state, OCtree* tree) { int fd,slen; char* name; slen = strlen(TMPPATH1); if(slen < strlen(TMPPATH2)) slen = strlen(TMPPATH2); slen += strlen("datadds") + strlen("XXXXXX"); name = (char*)ocmalloc(slen+1); MEMCHECK(name,OC_ENOMEM); fd = createtempfile1(name, TMPPATH1); if(fd < 0) fd = createtempfile1(name, TMPPATH2); if(fd < 0) { oc_log(LOGERR,"oc_open: attempt to open tmp file %s failed",name); return errno; } oc_log(LOGNOTE,"oc_open: using tmp file: %s",name); tree->data.filename = name; /* remember our tmp file name */ tree->data.file = fdopen(fd,"w+"); if(tree->data.file == NULL) return OC_EOPEN; /* unlink the temp file so it will automatically be reclaimed */ if(ocdebug == 0) unlink(tree->data.filename); return OC_NOERR; }
int ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime) { int stat = OC_NOERR; CURLcode cstat = CURLE_OK; size_t len; /* Set the URL */ cstat = curl_easy_setopt(curl, CURLOPT_URL, (void*)url); if (cstat != CURLE_OK) goto fail; /* send all data to this function */ cstat = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); if (cstat != CURLE_OK) goto fail; /* we pass our file to the callback function */ cstat = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)buf); if (cstat != CURLE_OK) goto fail; /* One last thing; always try to get the last modified time */ cstat = curl_easy_setopt(curl, CURLOPT_FILETIME, (long)1); cstat = curl_easy_perform(curl); if(cstat == CURLE_PARTIAL_FILE) { /* Log it but otherwise ignore */ oc_log(LOGWARN, "curl error: %s; ignored", curl_easy_strerror(cstat)); cstat = CURLE_OK; } if(cstat != CURLE_OK) goto fail; /* Get the last modified time */ if(filetime != NULL) cstat = curl_easy_getinfo(curl,CURLINFO_FILETIME,filetime); if(cstat != CURLE_OK) goto fail; /* Null terminate the buffer*/ len = ocbyteslength(buf); ocbytesappend(buf, '\0'); ocbytessetlength(buf, len); /* dont count null in buffer size*/ #ifdef OCDEBUG oc_log(LOGNOTE,"buffersize: %lu bytes",(unsigned long)ocbyteslength(buf)); #endif return OCTHROW(stat); fail: oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); return OCTHROW(OC_ECURL); }
int ocfetchurl_file(CURL* curl, const char* url, FILE* stream, unsigned long* sizep, long* filetime) { int stat = OC_NOERR; CURLcode cstat = CURLE_OK; struct Fetchdata fetchdata; /* Set the URL */ cstat = curl_easy_setopt(curl, CURLOPT_URL, (void*)url); if (cstat != CURLE_OK) goto fail; /* send all data to this function */ cstat = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteFileCallback); if (cstat != CURLE_OK) goto fail; /* we pass our file to the callback function */ cstat = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fetchdata); if (cstat != CURLE_OK) goto fail; /* One last thing; always try to get the last modified time */ cstat = curl_easy_setopt(curl, CURLOPT_FILETIME, (long)1); if (cstat != CURLE_OK) goto fail; fetchdata.stream = stream; fetchdata.size = 0; cstat = curl_easy_perform(curl); if (cstat != CURLE_OK) goto fail; if (stat == OC_NOERR) { /* return the file size*/ #ifdef OCDEBUG oc_log(LOGNOTE,"filesize: %lu bytes",fetchdata.size); #endif if (sizep != NULL) *sizep = fetchdata.size; /* Get the last modified time */ if(filetime != NULL) cstat = curl_easy_getinfo(curl,CURLINFO_FILETIME,filetime); if(cstat != CURLE_OK) goto fail; } return OCTHROW(stat); fail: oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); return OCTHROW(OC_ECURL); }
static void ocnotify_flush(struct ocnotify_private ocnotify, const char *host) { enum mapistore_error retval; if (ocnotify.flush) { retval = mapistore_notification_resolver_delete(&ocnotify.mstore_ctx, ocnotify.username, host); if (retval == MAPISTORE_SUCCESS) { oc_log(0, "* [OK] %s resolver entry for user %s deleted", host, ocnotify.username); } else { oc_log(0, "* [ERR] %s resolver entry for user %s not deleted", host, ocnotify.username); } } }
/* Set curl properties for link based on rc files */ static void ocsetcurlproperties(OCstate* state) { CURL* curl = state->curl; CURLcode cstat = CURLE_OK; int stat = OC_NOERR; /* process the triple store wrt to this state */ if(ocdodsrc_process(state) != OC_NOERR) { oc_log(LOGERR,"Malformed .dodsrc"); goto fail; } /* Set username+password from .dodsrc */ stat=ocset_user_password(curl,state->creds.username, state->creds.password); if(stat != OC_NOERR) goto fail; if (occredentials_in_url(state->url.url)) { /* this overrides .dodsrc */ char *result_url = NULL; char* userName = NULL; char* password = NULL; if (ocextract_credentials(state->url.url, &userName, &password, &result_url) != OC_NOERR) goto fail; dapurlclear(&state->url); dapurlparse(result_url,&state->url); /* this overrides .dodsrc */ if(password != NULL && strlen(password) > 0) { if(state->creds.password) free(state->creds.password); state->creds.password = password; } if(userName != NULL && strlen(userName) > 0) { if(state->creds.username) free(state->creds.username); state->creds.username = userName; } } /* Set curl properties */ if((stat=ocset_curl_flags(curl,state)) != OC_NOERR) goto fail; /* Set curl proxy */ if((stat=ocset_proxy(curl,state)) != OC_NOERR) goto fail; /* Set curl ssl */ if((stat=ocset_ssl(curl,state)) != OC_NOERR) goto fail; return; fail: if(cstat != CURLE_OK) oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); return; }
static NCerror cvttype(nc_type etype, char** srcp, char** dstp) { unsigned int typesize = nctypesizeof(etype); char* src = *srcp; char* dst = *dstp; switch (etype) { case NC_STRING: case NC_URL: { char* ssrc = *(char**)src; *((char**)dst) = nulldup(ssrc); srcp += typesize; dstp += typesize; } break; default: if(typesize == 0) goto fail; memcpy((void*)dst,(void*)src,typesize); srcp += typesize; dstp += typesize; break; } return NC_NOERR; fail: oc_log(OCLOGERR,"cvttype bad value: %s",oc_typetostring(etype)); return NC_EINVAL; }
/* This is called with arguments while the other functions in this file are * used with global values read from the.dodsrc file. */ int set_user_password(CURL* curl, const char *userC, const char *passwordC) { CURLcode cstat; int iUserPassSize = strlen(userC) + strlen(passwordC) + 2; char *userPassword = malloc(sizeof(char) * iUserPassSize); if (!userPassword) { oc_log(LOGERR, "Failed to allocate memory for the username and/or password.\n"); return OC_ENOMEM; } strncpy(userPassword, userC, iUserPassSize); strncat(userPassword, ":", iUserPassSize); strncat(userPassword, passwordC, iUserPassSize); cstat = curl_easy_setopt(curl, CURLOPT_USERPWD, userPassword); if (cstat != CURLE_OK) { free(userPassword); return OC_ECURL; } cstat = curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long) CURLAUTH_ANY); if (cstat != CURLE_OK) { free(userPassword); return OC_ECURL; } free(userPassword); return OC_NOERR; }
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; OCbytes* buf = (OCbytes*) data; if(realsize == 0) oc_log(LOGWARN,"WriteMemoryCallback: zero sized chunk"); /* Optimize for reading potentially large dods datasets */ if(!ocbytesavail(buf,realsize)) { /* double the size of the packet */ ocbytessetalloc(buf,2*ocbytesalloc(buf)); } ocbytesappendn(buf, ptr, realsize); #ifdef OCPROGRESS oc_log(LOGNOTE,"callback: %lu bytes",(unsigned long)realsize); #endif return realsize; }
static size_t WriteFileCallback(void* ptr, size_t size, size_t nmemb, void* data) { size_t realsize = size * nmemb; size_t count; struct Fetchdata* fetchdata; fetchdata = (struct Fetchdata*) data; if(realsize == 0) oc_log(LOGWARN,"WriteFileCallback: zero sized chunk"); count = fwrite(ptr, size, nmemb, fetchdata->stream); if (count > 0) { fetchdata->size += (count * size); } else { oc_log(LOGWARN,"WriteFileCallback: zero sized write"); } #ifdef OCPROGRESS oc_log(LOGNOTE,"callback: %lu bytes",(unsigned long)realsize); #endif return count; }
static OCerror createtempfile(OCstate* state, OCtree* tree) { int fd; char* name = NULL; fd = createtempfile1(TMPPATH1,&name); if(fd < 0) fd = createtempfile1(TMPPATH2,&name); if(fd < 0) { oc_log(LOGERR,"oc_open: attempt to open tmp file failed: %s",name); return errno; } #ifdef OCDEBUG oc_log(LOGNOTE,"oc_open: using tmp file: %s",name); #endif tree->data.filename = name; /* remember our tmp file name */ tree->data.file = fdopen(fd,"w+"); if(tree->data.file == NULL) return OC_EOPEN; /* unlink the temp file so it will automatically be reclaimed */ if(ocdebug == 0) unlink(tree->data.filename); return OC_NOERR; }
static void ocnotify_newmail(TALLOC_CTX *mem_ctx, struct ocnotify_private ocnotify, uint32_t count, const char **hosts, const char *data) { enum mapistore_error retval; int sock; int endpoint; int i; int bytes; int timeout; int rc; uint8_t *blob = NULL; size_t msglen; if (ocnotify.backend == NULL) { oc_log(OC_LOG_ERROR, "No backend specified"); exit (1); } retval = mapistore_notification_payload_newmail(mem_ctx, ocnotify.backend, (char *)data, ocnotify.dstfolder, ocnotify.sep, &blob, &msglen); if (retval != MAPISTORE_SUCCESS) { oc_log(OC_LOG_ERROR, "unable to generate newmail payload"); exit (1); } sock = nn_socket(AF_SP, NN_PUSH); if (sock < 0) { oc_log(OC_LOG_FATAL, "unable to create socket"); exit (1); } timeout = 200; rc = nn_setsockopt(sock, NN_SOL_SOCKET, NN_SNDTIMEO, &timeout, sizeof(timeout)); if (rc < 0) { oc_log(OC_LOG_WARNING, "unable to set timeout on socket send"); } for (i = 0; i < count; i++) { endpoint = nn_connect(sock, hosts[i]); if (endpoint < 0) { oc_log(OC_LOG_ERROR, "unable to connect to %s", hosts[i]); ocnotify_flush(ocnotify, hosts[i]); continue; } bytes = nn_send(sock, (char *)blob, msglen, 0); if (bytes != msglen) { oc_log(OC_LOG_WARNING, "Error sending msg: %d sent but %d expected", bytes, msglen); } oc_log(OC_LOG_INFO, "message sent to %s", hosts[i]); nn_shutdown(sock, endpoint); } }
static char* combinecredentials(const char* user, const char* pwd) { int userPassSize = strlen(user) + strlen(pwd) + 2; char *userPassword = malloc(sizeof(char) * userPassSize); if (!userPassword) { oc_log(LOGERR,"Out of Memory\n"); return NULL; } strcpy(userPassword, user); strcat(userPassword, ":"); strcat(userPassword, pwd); return userPassword; }
/* Counting records actually requires walking the xdr packet so it is not necessarily cheap*/ size_t ocrecordcount(OCstate* state, OCcontent* content) { int stat = OC_NOERR; size_t count; OCnode* node = content->node; XDR* xdrs; char tmp[BYTES_PER_XDR_UNIT]; OCASSERT((node != NULL)); OCASSERT((node->octype == OC_Sequence)); OCASSERT((content->mode == Recordmode)); /* If we are using memdata; then use that value */ if(content->memdata != NULL) { return content->memdata->count; } xdrs = content->tree->data.xdrs; OCASSERT((xdrs != NULL)); /* checkpoint the beginning of this instance*/ if(!content->xdrpos.valid) { content->xdrpos.offset = xdr_getpos(xdrs); content->xdrpos.valid = 1; } /* move to checkpoint position*/ if(!xdr_setpos(xdrs,content->xdrpos.offset)) return 0; for(count=0;;count++) { /* pick up the sequence record begin marker*/ /* extract the tag byte*/ if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) return 0; if(tmp[0] == StartOfoclist) { /* skip instance*/ stat = ocskipinstance(content->node,xdrs); if(stat != OC_NOERR) return 0; } else if(tmp[0] == EndOfoclist) { break; /* done with the count*/ } else { oc_log(LOGERR,"missing/invalid begin/end record marker\n"); return 0; } } /* move back to checkpoint position*/ if(!xdr_setpos(xdrs,content->xdrpos.offset)) return 0; return count; }
/* insertion sort the triplestore based on url */ static void sorttriplestore(void) { int i, nsorted; struct OCTriple* sorted = NULL; if(ocdodsrc->ntriples <= 1) return; /* nothing to sort */ if(ocdebug > 2) ocdodsrcdump("initial:",ocdodsrc->triples,ocdodsrc->ntriples); sorted = (struct OCTriple*)malloc(sizeof(struct OCTriple)*ocdodsrc->ntriples); if(sorted == NULL) { oc_log(LOGERR,"sorttriplestore: out of memory"); return; } nsorted = 0; while(nsorted < ocdodsrc->ntriples) { int largest; /* locate first non killed entry */ for(largest=0;largest<ocdodsrc->ntriples;largest++) { if(ocdodsrc->triples[largest].key[0] != '\0') break; } OCASSERT(ocdodsrc->triples[largest].key[0] != '\0'); for(i=0;i<ocdodsrc->ntriples;i++) { if(ocdodsrc->triples[i].key[0] != '\0') { /* avoid empty slots */ int lexorder = strcmp(ocdodsrc->triples[i].url,ocdodsrc->triples[largest].url); int leni = strlen(ocdodsrc->triples[i].url); int lenlarge = strlen(ocdodsrc->triples[largest].url); /* this defines the ordering */ if(leni == 0 && lenlarge == 0) continue; /* if no urls, then leave in order */ if(leni != 0 && lenlarge == 0) largest = i; else if(lexorder > 0) largest = i; } } /* Move the largest entry */ OCASSERT(ocdodsrc->triples[largest].key[0] != 0); sorted[nsorted] = ocdodsrc->triples[largest]; ocdodsrc->triples[largest].key[0] = '\0'; /* kill entry */ nsorted++; if(ocdebug > 2) ocdodsrcdump("pass:"******"final .dodsrc order:",ocdodsrc->triples,ocdodsrc->ntriples); }
static size_t WriteFileCallback(void* ptr, size_t size, size_t nmemb, void* data) { size_t count; struct Fetchdata* fetchdata; fetchdata = (struct Fetchdata*) data; count = fwrite(ptr, size, nmemb, fetchdata->stream); if (count > 0) { fetchdata->size += (count * size); } #ifdef OCPROGRESS oc_log(LOGNOTE,"callback: %lu bytes",(unsigned long)(size*nmemb)); #endif return count; }
OCerror ocopen(OCstate** statep, const char* url) { int stat = OC_NOERR; OCstate * state = NULL; DAPURL tmpurl; CURL* curl = NULL; /* curl handle*/ memset((void*)&tmpurl,0,sizeof(tmpurl)); if(!dapurlparse(url,&tmpurl)) {THROWCHK(stat=OC_EBADURL); goto fail;} stat = occurlopen(&curl); if(stat != OC_NOERR) {THROWCHK(stat); goto fail;} state = (OCstate*)ocmalloc(sizeof(OCstate)); /* ocmalloc zeros memory*/ if(state == NULL) {THROWCHK(stat=OC_ENOMEM); goto fail;} /* Setup DAP state*/ state->magic = OCMAGIC; state->curl = curl; state->trees = oclistnew(); state->contentlist = NULL; state->url = tmpurl; state->clientparams = ocparamdecode(state->url.params); if(state->clientparams == NULL) { oc_log(LOGWARN,"Could not parse client parameters"); } state->packet = ocbytesnew(); ocbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/ /* set curl properties for this link */ ocsetcurlproperties(state); if(statep) *statep = state; return THROW(stat); fail: dapurlclear(&tmpurl); if(state != NULL) ocfree(state); if(curl != NULL) occurlclose(curl); return THROW(stat); }
OCerror ocopen(OCstate** statep, const char* url) { int stat = OC_NOERR; OCstate * state = NULL; OCURI* tmpurl = NULL; CURL* curl = NULL; /* curl handle*/ if(!ocuriparse(url,&tmpurl)) {OCTHROWCHK(stat=OC_EBADURL); goto fail;} stat = occurlopen(&curl); if(stat != OC_NOERR) {OCTHROWCHK(stat); goto fail;} state = (OCstate*)ocmalloc(sizeof(OCstate)); /* ocmalloc zeros memory*/ if(state == NULL) {OCTHROWCHK(stat=OC_ENOMEM); goto fail;} /* Setup DAP state*/ state->magic = OCMAGIC; state->curl = curl; state->trees = oclistnew(); state->uri = tmpurl; if(!ocuridecodeparams(state->uri)) { oc_log(LOGWARN,"Could not parse client parameters"); } state->packet = ocbytesnew(); ocbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/ /* set curl properties for this link */ ocsetcurlproperties(state); /* Set up list to support reuse/reclamation of OCcontent objects. */ state->contentlist = NULL; if(statep) *statep = state; return OCTHROW(stat); fail: ocurifree(tmpurl); if(state != NULL) ocfree(state); if(curl != NULL) occurlclose(curl); return OCTHROW(stat); }
/* if we get OC_EDATADDS error, then try to capture any error message and log it; assumes that in this case, the datadds is not big. */ void ocdataddsmsg(OCstate* state, OCtree* tree) { #define ERRCHUNK 1024 #define ERRFILL ' ' #define ERRTAG "Error {" unsigned int i,j,len; XXDR* xdrs; char* contents; off_t ckp; if(tree == NULL) return; /* get available space */ xdrs = tree->data.xdrs; len = xxdr_length(xdrs); if(len < strlen(ERRTAG)) return; /* no room */ ckp = xxdr_getpos(xdrs); xxdr_setpos(xdrs,0); /* read the whole thing */ contents = (char*)malloc(len+1); xxdr_getbytes(xdrs,contents,len); contents[len] = '\0'; /* Look for error tag */ for(i=0;i<len;i++) { if(ocstrncmp(contents+i,ERRTAG,strlen(ERRTAG))==0) { /* log the error message */ /* Do a quick and dirty escape */ for(j=i;j<len;j++) { int c = contents[i+j]; if(c > 0 && (c < ' ' || c >= '\177')) contents[i+j] = ERRFILL; } oc_log(LOGERR,"DATADDS failure, possible message: '%s'\n", contents+i); goto done; } } xxdr_setpos(xdrs,ckp); done: return; }
int set_proxy(CURL* curl, struct OCproxy *pstructProxy) { CURLcode cstat; cstat = curl_easy_setopt(curl, CURLOPT_PROXY, pstructProxy->host); if (cstat != CURLE_OK) return OC_ECURL; cstat = curl_easy_setopt(curl, CURLOPT_PROXYPORT, pstructProxy->port); if (cstat != CURLE_OK) return OC_ECURL; if (pstructProxy->user) { int userPassSize = strlen(pstructProxy->user) + strlen( pstructProxy->password) + 2; char *userPassword = malloc(sizeof(char) * userPassSize); if (!userPassword) { oc_log(LOGERR, "Out of Memory\n"); return OC_ENOMEM; } strncpy(userPassword, pstructProxy->user, userPassSize); strncat(userPassword, ":", userPassSize); strncat(userPassword, pstructProxy->password, userPassSize); cstat = curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userPassword); if (cstat != CURLE_OK) { free(userPassword); return OC_ECURL; } #ifdef CURLOPT_PROXYAUTH cstat = curl_easy_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); if(cstat != CURLE_OK) goto fail; #endif free(userPassword); } return OC_NOERR; }
int countrecords(OCnode* node, XDR* xdrs, size_t* nrecordsp) { int stat = OC_NOERR; size_t nrecords = 0; unsigned int xdroffset; if(node->octype != OC_Sequence) return THROW(OC_EINVAL); /* checkpoint the xdr position*/ xdroffset = xdr_getpos(xdrs); for(;;) { unsigned int i; /* pick up the sequence record begin marker*/ char tmp[sizeof(unsigned int)]; /* extract the tag byte*/ if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) return xdrerror(); if(tmp[0] == StartOfoclist) { /* Walk each member field*/ for(i=0;i<oclistlength(node->subnodes);i++) { OCnode* member = (OCnode*)oclistget(node->subnodes,i); stat = ocskip(member,xdrs); if(stat != OC_NOERR) break; } nrecords++; } else if(tmp[0] == EndOfoclist) { break; /* we are done with the this sequence instance*/ } else { oc_log(LOGERR,"missing/invalid begin/end record marker\n"); stat = OC_EINVALCOORDS; break; } if(stat != OC_NOERR) break; } /* move to checkpoint position*/ if(!xdr_setpos(xdrs,xdroffset)) return xdrerror(); if(nrecordsp != NULL) *nrecordsp = nrecords; return THROW(stat); }
int ocinternalinitialize(void) { int stat = OC_NOERR; /* Compute some xdr related flags */ xxdr_init(); oc_loginit(); /* Determine if this version of curl supports "file://..." &/or "https://..." urls. */ { const char* const* proto; /*weird*/ curl_version_info_data* curldata; curldata = curl_version_info(CURLVERSION_NOW); oc_curl_file_supported = 0; oc_curl_https_supported = 0; for(proto=curldata->protocols;*proto;proto++) { if(strcmp("file",*proto)==0) {oc_curl_file_supported=1;break;} if(strcmp("https",*proto)==0) {oc_curl_https_supported=1;break;} } if(ocdebug > 0) { oc_log(LOGNOTE,"Curl file:// support = %d",oc_curl_file_supported); oc_log(LOGNOTE,"Curl https:// support = %d",oc_curl_file_supported); } } /* compile the .dodsrc, if any */ { char* path = NULL; char* homepath = NULL; char** alias; FILE* f = NULL; /* locate the configuration files: . first in '.', then $HOME */ for(alias=rcfilenames;*alias;alias++) { path = (char*)malloc(strlen("./")+strlen(*alias)+1); if(path == NULL) return OC_ENOMEM; strcpy(path,"./"); strcat(path,*alias); /* see if file is readable */ f = fopen(path,"r"); if(f != NULL) break; if(path != NULL) {free(path); path = NULL;} /* cleanup */ } if(f == NULL) { /* try $HOME */ OCASSERT(path == NULL); homepath = getenv("HOME"); if (homepath!= NULL) { for(alias=rcfilenames;*alias;alias++) { path = (char*)malloc(strlen(homepath)+1+strlen(*alias)+1); if(path == NULL) return OC_ENOMEM; strcpy(path,homepath); strcat(path,"/"); strcat(path,*alias); f = fopen(path,"r"); if(f != NULL) break; if(path != NULL) {free(path); path=NULL;} } } } if(f == NULL) { oc_log(LOGDBG,"Cannot find runtime configuration file"); } else { OCASSERT(path != NULL); fclose(f); if(ocdebug > 1) fprintf(stderr, "DODS RC file: %s\n", path); if(ocdodsrc_read(*alias,path) == 0) oc_log(LOGERR, "Error parsing %s\n",path); } if(path != NULL) free(path); } return OCTHROW(stat); }
OCerror ocfetchf(OCstate* state, const char* constraint, OCdxd kind, OCflags flags, OCnode** rootp) { OCtree* tree = NULL; OCnode* root = NULL; OCerror stat = OC_NOERR; tree = (OCtree*)ocmalloc(sizeof(OCtree)); MEMCHECK(tree,OC_ENOMEM); memset((void*)tree,0,sizeof(OCtree)); tree->dxdclass = kind; tree->state = state; tree->constraint = constraintescape(constraint); if(tree->constraint == NULL) tree->constraint = nulldup(constraint); /* Set curl properties: pwd, flags, proxies, ssl */ if((stat=ocset_user_password(state))!= OC_NOERR) goto fail; if((stat=ocset_curl_flags(state)) != OC_NOERR) goto fail; if((stat=ocset_proxy(state)) != OC_NOERR) goto fail; if((stat=ocset_ssl(state)) != OC_NOERR) goto fail; ocbytesclear(state->packet); switch (kind) { case OCDAS: stat = readDAS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDAS; } break; case OCDDS: stat = readDDS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDDS; } break; case OCDATADDS: if((flags & OCINMEMORY) == 0) {/* store in file */ /* Create the datadds file immediately so that DRNO can reference it*/ /* Make the tmp file*/ stat = createtempfile(state,tree); if(stat) {OCTHROWCHK(stat); goto unwind;} stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinfile(state,tree,flags); } } else { /*inmemory*/ stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinmemory(state,tree,flags); } } break; }/*switch*/ if(stat != OC_NOERR) { /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(state->error.httpcode >= 400) { oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oc_log(LOGWARN,"oc_open: Could not read url"); } return OCTHROW(stat); } tree->nodes = NULL; stat = DAPparse(state,tree,tree->text); /* Check and report on an error return from the server */ if(stat == OC_EDAPSVC && state->error.code != NULL) { oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {OCTHROWCHK(stat); goto unwind;} root = tree->root; /* make sure */ tree->root = root; root->tree = tree; /* Verify the parse */ switch (kind) { case OCDAS: if(root->octype != OC_Attributeset) {OCTHROWCHK(stat=OC_EDAS); goto unwind;} break; case OCDDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDDS); goto unwind;} break; case OCDATADDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDATADDS); goto unwind;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to assign offsets and sizes where possible */ occomputeskipdata(state,root); /* Process ocnodes to mark those that are cacheable */ ocmarkcacheable(state,root); /* Process ocnodes to handle various semantic issues*/ occomputesemantics(tree->nodes); } /* Process ocnodes to compute name info*/ occomputefullnames(tree->root); if(kind == OCDATADDS) { if((flags & OCINMEMORY) == 0) { tree->data.xdrs = xxdr_filecreate(tree->data.file,tree->data.bod); } else { /* Switch to zero based memory */ tree->data.xdrs = xxdr_memcreate(tree->data.memory,tree->data.datasize,tree->data.bod); } MEMCHECK(tree->data.xdrs,OC_ENOMEM); } /* Put root into the state->trees list */ oclistpush(state->trees,(ocelem)root); if(rootp) *rootp = root; return stat; unwind: ocfreetree(tree); fail: return OCTHROW(stat); }
/* Compute the set of prefetched data; note that even if caching is off, we will still prefetch the small variables. */ NCerror prefetchdata3(NCDAPCOMMON* nccomm) { int i,j; NCerror ncstat = NC_NOERR; NClist* allvars = nccomm->cdf.varnodes; NCconstraint* constraint = nccomm->oc.dapconstraint; NClist* vars = nclistnew(); NCcachenode* cache = NULL; NCconstraint* newconstraint = NULL; /* Check if we can do constraints */ if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) { /*cannot constrain*/ /* If we cannot constrain, then pull in everything */ for(i=0;i<nclistlength(allvars);i++) { nclistpush(vars,nclistget(allvars,i)); } } else { /* can do constraints */ /* pull in those variables of sufficiently small size */ for(i=0;i<nclistlength(allvars);i++) { CDFnode* var = (CDFnode*)nclistget(allvars,i); size_t nelems = 1; /* If var is a sequence or under a sequence, then never prefetch */ if(var->nctype == NC_Sequence || dapinsequence(var)) continue; /* Compute the # of elements in the variable */ for(j=0;j<nclistlength(var->array.dimensions);j++) { CDFnode* dim = (CDFnode*)nclistget(var->array.dimensions,j); nelems *= dim->dim.declsize; } if(nelems <= nccomm->cdf.smallsizelimit) nclistpush(vars,(ncelem)var); } } /* If there are no vars, then do nothing */ if(nclistlength(vars) == 0) { nccomm->cdf.cache->prefetch = NULL; goto done; } newconstraint = createncconstraint(); /* Construct the projections for this set of vars */ /* Initially, the constraints are same as the merged constraints */ newconstraint->projections = clonencprojections(constraint->projections); restrictprojection34(vars,newconstraint->projections); /* similar for selections */ newconstraint->selections = clonencselections(constraint->selections); ncstat = buildcachenode34(nccomm,newconstraint,vars,&cache,1); if(ncstat) goto done; cache->wholevariable = 1; /* All prefetches are whole variable */ if(FLAGSET(nccomm->controls,NCF_SHOWFETCH)) { oc_log(OCLOGNOTE,"prefetch."); } #ifdef DEBUG /* Log the set of prefetch variables */ NCbytes* buf = ncbytesnew(); ncbytescat(buf,"prefetch.vars: "); for(i=0;i<nclistlength(vars);i++) { CDFnode* var = (CDFnode*)nclistget(vars,i); ncbytescat(buf," "); ncbytescat(buf,makesimplepathstring3(var)); } ncbytescat(buf,"\n"); oc_log(OCLOGNOTE,"%s",ncbytescontents(buf)); ncbytesfree(buf); #endif /* Make cache node be the prefetch node */ nccomm->cdf.cache->prefetch = cache; done: nclistfree(vars); freencconstraint(newconstraint); if(ncstat) freenccachenode(nccomm,cache); return THROW(ncstat); }
/* Compute the set of prefetched data */ NCerror prefetchdata4(NCDRNO* drno) { int i,j; NCerror ncstat = NC_NOERR; NClist* allvars = drno->cdf.varnodes; NCconstraint* constraint = &drno->dap.constraint; NClist* vars = nclistnew(); NCcachenode* cache = NULL; NCconstraint newconstraint; /* If caching is off, and we can do constraints, then don't even do prefetch */ if(!FLAGSET(drno,NCF_CACHE) && !FLAGSET(drno,NCF_UNCONSTRAINABLE)) { drno->cdf.cache.prefetch = NULL; goto done; } for(i=0;i<nclistlength(allvars);i++) { CDFnode* var = (CDFnode*)nclistget(allvars,i); size_t nelems = 1; /* Compute the # of elements in the variable */ for(j=0;j<nclistlength(var->array.dimensions);j++) { CDFnode* dim = (CDFnode*)nclistget(var->array.dimensions,j); nelems *= dim->dim.declsize; } /* If we cannot constrain, then pull in everything */ if(FLAGSET(drno,NCF_UNCONSTRAINABLE) || nelems <= drno->cdf.smallsizelimit) nclistpush(vars,(ncelem)var); } /* If we cannot constrain, then pull in everything */ if(FLAGSET(drno,NCF_UNCONSTRAINABLE)) { newconstraint.projections = NULL; newconstraint.selections= NULL; } else { /* Construct the projections for this set of vars */ /* Construct the projections for this set of vars */ /* Initially, the constraints are same as the merged constraints */ newconstraint.projections = cloneprojections(constraint->projections); restrictprojection3(drno,vars,newconstraint.projections); /* similar for selections */ newconstraint.selections = cloneselections(constraint->selections); } ncstat = buildcachenode3(drno,&newconstraint,vars,&cache,0); if(ncstat) goto done; if(FLAGSET(drno,NCF_SHOWFETCH)) { /* Log the set of prefetch variables */ NCbytes* buf = ncbytesnew(); ncbytescat(buf,"prefetch.vars: "); for(i=0;i<nclistlength(vars);i++) { CDFnode* var = (CDFnode*)nclistget(vars,i); ncbytescat(buf," "); ncbytescat(buf,makesimplepathstring3(var)); } ncbytescat(buf,"\n"); oc_log(OCLOGNOTE,ncbytescontents(buf)); ncbytesfree(buf); } done: if(ncstat) { freenccachenode(drno,cache); } return THROW(ncstat); }
int ocinternalinitialize(void) { int stat = OC_NOERR; /* Compute if we are same as network order v-a-v xdr */ #ifdef XDRBYTEORDER { XDR xdrs; union { char tmp[sizeof(unsigned int)]; unsigned int i; } u; int testint = 1; xrmem_create(&xdrs, (caddr_t)&u.tmp,sizeof(u.tmp), XDR_ENCODE); xdr_int(&xdrs, &testint); oc_network_order = (udub.i == testint?1:0); oc_big_endian = oc_network_order; } #else { int testint = 0x00000001; char *byte = (char *)&testint; oc_big_endian = (byte[0] == 0 ? 1 : 0); oc_network_order = oc_big_endian; } #endif /*XDRBYTEORDER*/ { /* It turns out that various machines store double in different formats. This affects the conversion code ocdata.c when reconstructing; probably could deduce this from oc_big_endian, but not sure. */ XDR xdrs; union { double dv; unsigned int i; unsigned int iv[2]; char tmp[sizeof(double)]; } udub; double testdub = 18000; /* verify double vs int size */ if(sizeof(double) != (2 * sizeof(unsigned int))) ocpanic("|double| != 2*|int|"); if(sizeof(udub) != sizeof(double)) ocpanic("|double| != |udub|"); memset((void*)&udub,0,sizeof(udub)); xdrmem_create(&xdrs, (caddr_t)&udub.tmp,sizeof(udub.tmp), XDR_ENCODE); xdr_double(&xdrs, &testdub); udub.iv[0] = ocntoh(udub.iv[0]); udub.iv[1] = ocntoh(udub.iv[1]); if (udub.dv == testdub) oc_invert_xdr_double = 0; else { /* swap and try again */ unsigned int temp = udub.iv[0]; udub.iv[0] = udub.iv[1]; udub.iv[1] = temp; if (udub.dv != testdub) ocpanic("cannot unpack xdr_double"); oc_invert_xdr_double = 1; } } oc_loginit(); /* Determine if this version of curl supports "file://..." &/or "https://..." urls. */ { const char* const* proto; /*weird*/ curl_version_info_data* curldata; curldata = curl_version_info(CURLVERSION_NOW); oc_curl_file_supported = 0; oc_curl_https_supported = 0; for(proto=curldata->protocols;*proto;proto++) { if(strcmp("file",*proto)==0) {oc_curl_file_supported=1;break;} if(strcmp("https",*proto)==0) {oc_curl_https_supported=1;break;} } if(ocdebug > 0) { oc_log(LOGNOTE,"Curl file:// support = %d",oc_curl_file_supported); oc_log(LOGNOTE,"Curl https:// support = %d",oc_curl_file_supported); } } /* compile the .dodsrc, if any */ { char* path = NULL; char* homepath = NULL; FILE* f = NULL; /* locate the configuration files: . first, then $HOME */ path = (char*)malloc(strlen("./")+strlen(DODSRC)+1); if(path == NULL) return OC_ENOMEM; strcpy(path,"./"); strcat(path,DODSRC); /* see if file is readable */ f = fopen(path,"r"); if(f == NULL) { /* try $HOME */ homepath = getenv("HOME"); if (homepath!= NULL) { if(path != NULL) free(path); path = (char*)malloc(strlen(homepath)+1+strlen(DODSRC)+1); if(path == NULL) return OC_ENOMEM; strcpy(path,homepath); strcat(path,"/"); strcat(path,DODSRC); f = fopen(path,"r"); } } if(f == NULL) { oc_log(LOGWARN,"Cannot find runtime .dodsrc configuration file"); } else { fclose(f); if(ocdebug > 1) fprintf(stderr, "DODS RC file: %s\n", path); if(ocdodsrc_read(path) == 0) oc_log(LOGERR, "Error parsing %s\n",path); } if(path != NULL) {free(path) ; path = NULL;} } return THROW(stat); }
int dapmerge3(NCDRNO* drno, CDFnode* ddsroot, OCobject dasroot) { unsigned int i,j; NCerror ncerr = NC_NOERR; OCerror ocstat = OC_NOERR; OCconnection conn = drno->dap.conn; unsigned int nsubnodes, nobjects; OCobject* dasobjects = NULL; NClist* dasglobals = nclistnew(); NClist* dodsextra = nclistnew(); NClist* dasnodes = nclistnew(); NClist* varnodes = nclistnew(); NClist* allddsnodes = ddsroot->tree->nodes; nobjects = oc_inq_nobjects(conn,dasroot); dasobjects = oc_inq_objects(conn,dasroot); /* 1. collect all the relevant DAS nodes; namely those that contain at least one attribute value. Simultaneously look for potential ambiguities if found; complain but continue: result are indeterminate. also collect globals and DODS_EXTRAs separately*/ for(i=0;i<nobjects;i++) { OCobject das = dasobjects[i]; OCtype octype; char* ocname = NULL; int isglobal = 0; int hasattributes = 0; OCobject* subnodes; OCHECK(oc_inq_class(conn,das,&octype)); if(octype == OC_Attribute) continue; /* ignore these for now*/ OCHECK(oc_inq_name(conn,das,&ocname)); OCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes)); isglobal = (ocname == NULL ? 0 : isglobalname3(ocname)); if(ocname == NULL || isglobal) { nclistpush(dasglobals,(ncelem)das); efree(ocname); continue; } if(ocname != NULL && strcmp(ocname,"DODS_EXTRA")==0) { nclistpush(dodsextra,(ncelem)das); efree(ocname); continue; } OCHECK(oc_inq_subnodes(conn,das,&subnodes)); for(j=0;j<nsubnodes;j++) { OCobject subnode = subnodes[j]; OCtype ocsubtype; OCHECK(oc_inq_class(conn,subnode,&ocsubtype)); if(ocsubtype == OC_Attribute) {hasattributes = 1; break;} } efree(subnodes); if(hasattributes) { /* Look for previously collected nodes with same name*/ for(j=0;j<nclistlength(dasnodes);j++) { OCobject das2 = (OCobject)nclistget(dasnodes,j); char* ocname2; OCHECK(oc_inq_name(conn,das2,&ocname2)); if(ocname2 == NULL || ocname == NULL) goto loop; if(strcmp(ocname2,"DODS")==0) goto loop; if(strcmp(ocname,ocname2)==0) oc_log(OCLOGWARN,"nc_mergedas: potentially ambiguous DAS name: %s",ocname2); loop: efree(ocname2); } nclistpush(dasnodes,(ncelem)das); } efree(ocname); } /* 2. collect all the leaf DDS nodes (of type NC_Primitive)*/ for(i=0;i<nclistlength(allddsnodes);i++) { CDFnode* dds = (CDFnode*)nclistget(allddsnodes,i); if(dds->nctype == NC_Primitive) nclistpush(varnodes,(ncelem)dds); } /* 3. For each das node, lncate matching DDS node(s) and attach attributes to the DDS node(s). Match means: 1. DAS->fullname :: DDS->fullname 2. DAS->name :: DDS->fullname (support DAS names with embedded '.' 3. DAS->name :: DDS->name */ for(i=0;i<nclistlength(dasnodes);i++) { OCobject das = (OCobject)nclistget(dasnodes,i); char* ocfullname; char* ocbasename; if(das == OCNULL) continue; ocfullname = makeocpathstring3(conn,das,"."); OCHECK(oc_inq_name(conn,das,&ocbasename)); for(j=0;j<nclistlength(varnodes);j++) { CDFnode* dds = (CDFnode*)nclistget(varnodes,j); char* ddsfullname = makesimplepathstring3(dds); if(strcmp(ocfullname,ddsfullname)==0 || strcmp(ocbasename,ddsfullname)==0 || strcmp(ocbasename,dds->name)==0) { mergedas1(conn,dds,das); /* remove from dasnodes list*/ nclistset(dasnodes,i,(ncelem)NULL); } efree(ddsfullname); } efree(ocfullname); efree(ocbasename); } /* 4. Assign globals*/ for(i=0;i<nclistlength(dasglobals);i++) { OCobject das = (OCobject)nclistget(dasglobals,i); mergedas1(conn,ddsroot,das); } /* process DOD_EXTRA */ if(nclistlength(dodsextra) > 0) dodsextra3(drno,ddsroot,dodsextra); done: /* cleanup*/ efree(dasobjects); nclistfree(dasglobals); nclistfree(dasnodes); nclistfree(dodsextra); nclistfree(varnodes); if(ocstat != OC_NOERR) ncerr = ocerrtoncerr(ocstat); return THROW(ncerr); }
static int occompile1(OCstate* state, OCnode* xnode, OCmemdata** memdatap, XDR* xdrs) { unsigned int i,j,xdrcount; int stat = OC_NOERR; size_t nelements; OCmemdata* memdata = NULL; OCmemdata* structdata = NULL; OClist* records = NULL; OCerror ocstat = OC_NOERR; OCmemdata** pmem = NULL; /* Allocate the space for this memdata chunk */ switch (xnode->octype) { case OC_Dataset: case OC_Grid: case OC_Structure: { if(xnode->array.rank == 0) { ocstat = occompilefields(state,xnode,&memdata,xdrs); if(ocstat != OC_NOERR) goto fail; } else { /* rank > 0 */ /* Compute the actual index count after projections */ nelements = totaldimsize(xnode); if(nelements == 0) return THROW(OC_ENODATA); memdata = makememdata(xnode->octype,OC_NAT,nelements); MEMCHECK(memdata,OC_ENOMEM); memdata->mode = Dimmode; pmem = (OCmemdata**)&memdata->data; /* Consume the leading count field */ if(!xdr_u_int(xdrs,&xdrcount)) {stat = OC_EXDR; goto fail;} /* validate the datadds dimensions */ if(xdrcount != nelements) {stat=OC_EINVALCOORDS; goto fail;} for(i=0;i<nelements;i++) { ocstat = occompilefields(state,xnode,&structdata,xdrs); if(ocstat != OC_NOERR) { if(ocstat != OC_ENODATA) goto fail; structdata = NULL; /* Leave a hole for this element */ } pmem[i] = structdata; structdata = NULL; } } } break; case OC_Sequence:{ /* Since we do not know the # records beforehand, use a oclist to collect the record instances. Query: this stores by recor (where e.g. original ocapi stores by column). How hard would it be to make the storage choice conditional on some user defined flag? */ records = oclistnew(); for(;;) { /* pick up the sequence record begin marker*/ char tmp[sizeof(unsigned int)]; /* extract the tag byte*/ if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) {stat = OC_EXDR; goto fail;} if(tmp[0] == StartOfoclist) { /* Walk each member field*/ ocstat = occompilefields(state,xnode,&structdata,xdrs); if(ocstat != OC_NOERR) goto fail; oclistpush(records,(ocelem)structdata); structdata = NULL; } else if(tmp[0] == EndOfoclist) { break; /* we are done with the this sequence instance*/ } else { oc_log(LOGERR,"missing/invalid begin/end record marker\n"); stat = OC_EINVALCOORDS; goto fail; } } /* Convert the list to a proper OCmemdata */ nelements = oclistlength(records); memdata = makememdata(xnode->octype,OC_NAT,nelements); MEMCHECK(memdata,OC_ENOMEM); memdata->mode = Recordmode; pmem = (OCmemdata**)&memdata->data; for(j=0;j<nelements;j++) { OCmemdata* record = (OCmemdata*)oclistget(records,j); pmem[j] = record; } oclistfree(records); records = NULL; } break; case OC_Primitive: ocstat = occompileprim(state,xnode,&memdata,xdrs); if(ocstat != OC_NOERR) goto fail; break; default: OCPANIC1("ocmap: encountered unexpected node type: %x",xnode->octype); break; } /*ok:*/ if(memdatap) *memdatap = memdata; return THROW(ocstat); fail: if(records != NULL) for(i=0;i<oclistlength(records);i++) freeocmemdata((OCmemdata*)oclistget(records,i)); freeocmemdata(memdata); freeocmemdata(structdata); return THROW(ocstat); }
OCerror ocfetch(OCstate* state, const char* constraint, OCdxd kind, OCnode** rootp) { OCtree* tree = NULL; OCnode* root = NULL; OCerror stat = OC_NOERR; tree = (OCtree*)ocmalloc(sizeof(OCtree)); MEMCHECK(tree,OC_ENOMEM); memset((void*)tree,0,sizeof(OCtree)); tree->dxdclass = kind; tree->state = state; tree->constraint = constraintescape(constraint); if(tree->constraint == NULL) tree->constraint = nulldup(constraint); ocbytesclear(state->packet); switch (kind) { case OCDAS: stat = readDAS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDAS; } break; case OCDDS: stat = readDDS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDDS; } break; case OCDATADDS: #ifdef OC_DISK_STORAGE /* Create the datadds file immediately so that DRNO can reference it*/ /* Make the tmp file*/ stat = createtempfile(state,tree); if(stat) {THROWCHK(stat); goto unwind;} stat = readDATADDS(state,tree); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractdds(state,tree); } #else stat = readDATADDS(state,tree); if(stat == OC_NOERR) { /* Separate the DDS from data*/ stat = ocextractdds(state,tree); tree->data.xdrdata = ocbytesdup(state->packet); } #endif break; } if(stat != OC_NOERR) { /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(state->error.httpcode >= 400) { oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oc_log(LOGWARN,"oc_open: Could not read url"); } return THROW(stat); } tree->nodes = NULL; stat = DAPparse(state,tree,tree->text); /* Check and report on an error return from the server */ if(stat == OC_EDAPSVC && state->error.code != NULL) { oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {THROWCHK(stat); goto unwind;} root = tree->root; /* make sure */ tree->root = root; root->tree = tree; /* Verify the parse */ switch (kind) { case OCDAS: if(root->octype != OC_Attributeset) {THROWCHK(stat=OC_EDAS); goto unwind;} break; case OCDDS: if(root->octype != OC_Dataset) {THROWCHK(stat=OC_EDDS); goto unwind;} break; case OCDATADDS: if(root->octype != OC_Dataset) {THROWCHK(stat=OC_EDATADDS); goto unwind;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to fix various semantic issues*/ computeocsemantics(tree->nodes); } /* Process ocnodes to compute name info*/ computeocfullnames(tree->root); if(kind != OCDAS) { /* Process ocnodes to compute sizes when uniform in size*/ ocsetsize(tree->root); } if(kind == OCDATADDS) { tree->data.xdrs = (XDR*)ocmalloc(sizeof(XDR)); MEMCHECK(tree->data.xdrs,OC_ENOMEM); #ifdef OC_DISK_STORAGE ocxdrstdio_create(tree->data.xdrs,tree->data.file,XDR_DECODE); #else xdrmem_create(tree->data.xdrs,tree->data.xdrdata,tree->data.datasize,XDR_DECODE); #endif if(!xdr_setpos(tree->data.xdrs,tree->data.bod)) return xdrerror(); } #ifdef OC_DISK_STORAGE if(ocdebug == 0 && tree->data.filename != NULL) { unlink(tree->data.filename); } #endif /* Put root into the state->trees list */ oclistpush(state->trees,(ocelem)root); if(rootp) *rootp = root; return stat; unwind: ocfreetree(tree); return THROW(stat); }