OCerror ocdata_ithfield(OCstate* state, OCdata* container, size_t index, OCdata** fieldp) { OCdata* field; OCnode* pattern; OCASSERT(state != NULL); OCASSERT(container != NULL); pattern = container->pattern; if(!ociscontainer(pattern->octype)) return OCTHROW(OC_EBADTYPE); /* Validate index */ if(index >= container->ninstances) return OCTHROW(OC_EINDEX); field = container->instances[index]; if(fieldp) *fieldp = field; octrace("ithfield", state, field); return OC_NOERR; }
/* Assume we are operating on the datadds tree */ int occompile(OCstate* state, OCnode* xroot) { OCerror ocstat = OC_NOERR; OCmemdata* memdata = NULL; XDR* xdrs; OCtree* xtree; if(state == NULL || xroot->tree == NULL) return OCTHROW(OC_ENODATA); xtree = xroot->tree; if(xtree->dxdclass != OCDATADDS) return OCTHROW(OC_EINVAL); /* See if the compiler has already been invoked */ if(xtree->data.memdata != NULL) return OC_NOERR; if(xtree->data.datasize > OCCOMPILELIMIT) { return OCTHROW(OC_ENOMEM); } xdrs = xtree->data.xdrs; if(xdrs == NULL) return OCTHROW(OC_EXDR); ocstat = occompile1(state,xtree->root,&memdata,xdrs); if(ocstat == OC_NOERR) { xtree->data.memdata = memdata; #ifndef OC_DISK_STORAGE freeocmemdata(xtree->data.xdrdata); xtree->data.xdrdata = NULL; xtree->data.datasize = 0; xtree->data.bod = 0; xtree->data.ddslen = 0; #endif } return OCTHROW(ocstat); }
static int readfile(const char* path, const char* suffix, OCbytes* packet) { int stat = OC_NOERR; char buf[1024]; char filename[1024]; int fd = -1; int flags = 0; off_t filesize = 0; off_t totalread = 0; /* check for leading file:/// */ if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/ if(!occopycat(filename,sizeof(filename),2,path,(suffix != NULL ? suffix : ""))) return OCTHROW(OC_EOVERRUN); flags = O_RDONLY; #ifdef O_BINARY flags |= O_BINARY; #endif fd = open(filename,flags); if(fd < 0) { oclog(OCLOGERR,"open failed:%s",filename); return OCTHROW(OC_EOPEN); } /* Get the file size */ filesize = lseek(fd,(off_t)0,SEEK_END); if(filesize < 0) { stat = OC_EIO; oclog(OCLOGERR,"lseek failed: %s",filename); goto done; } /* Move file pointer back to the beginning of the file */ (void)lseek(fd,(off_t)0,SEEK_SET); stat = OC_NOERR; for(totalread=0;;) { off_t count = (off_t)read(fd,buf,sizeof(buf)); if(count == 0) break; /*eof*/ else if(count < 0) { stat = OC_EIO; oclog(OCLOGERR,"read failed: %s",filename); goto done; } ocbytesappendn(packet,buf,(unsigned long)count); totalread += count; } if(totalread < filesize) { stat = OC_EIO; oclog(OCLOGERR,"short read: |%s|=%lu read=%lu\n", filename,(unsigned long)filesize,(unsigned long)totalread); goto done; } done: #ifdef OCDEBUG fprintf(stderr,"readfile: filesize=%lu totalread=%lu\n", (unsigned long)filesize,(unsigned long)totalread); #endif if(fd >= 0) close(fd); return OCTHROW(stat); }
/* Move to the ith sequence record. */ OCerror ocdata_ithrecord(OCstate* state, OCdata* data, size_t index, /* record number */ OCdata** recordp ) { int stat = OC_NOERR; OCdata* record; OCnode* pattern; OCASSERT(state != NULL); OCASSERT(data != NULL); pattern = data->pattern; /* Must be a Sequence */ if(pattern->octype != OC_Sequence || !fisset(data->datamode,OCDT_SEQUENCE)) return OCTHROW(OC_EBADTYPE); /* Validate index */ if(index >= data->ninstances) return OCTHROW(OC_EINDEX); record = data->instances[index]; if(recordp) *recordp = record; octrace("ithrecord", state, record); return OCTHROW(stat); }
static int occompilefields(OCstate* state, OCnode* xnode, OCmemdata** memdatap, XDR* xdrs) { OCmemdata* structdata = NULL; OCmemdata** qmem; OCerror ocstat = OC_NOERR; unsigned int i,nfields; nfields = oclistlength(xnode->subnodes); structdata = makememdata(OC_Structure,OC_NAT,nfields); MEMCHECK(structdata,OC_ENOMEM); qmem = (OCmemdata**)&structdata->data; structdata->mode = Fieldmode; for(i=0;i<nfields;i++) { OCnode* field = (OCnode*)oclistget(xnode->subnodes,i); OCmemdata* fielddata; ocstat = occompile1(state,field,&fielddata,xdrs); if(ocstat == OC_ENODATA) { fielddata = NULL; } else if(ocstat != OC_NOERR) { freeocmemdata(structdata); return OCTHROW(ocstat); } qmem[i] = fielddata; } if(memdatap) *memdatap = structdata; return OCTHROW(ocstat); }
static int ocgetmemdata(OCstate* state, OCcontent* content, void* memory, size_t memsize, size_t start, size_t count) { OCmemdata* md = content->memdata; unsigned short* d16; unsigned int* d32; #ifdef HAVE_LONG_LONG_INT unsigned long long* d64; #endif char* dchar; char** dstring; size_t totalsize; size_t elemsize; OCtype etype; /* Validate the etypes */ etype = content->node->etype; if(etype != md->etype) return OCTHROW(OC_EINVAL); elemsize = octypesize(etype); totalsize = elemsize*count; switch (etype) { case OC_Char: case OC_Byte: case OC_UByte: dchar = (char*)md->data.data; memcpy((void*)memory,(void*)(dchar+start),totalsize); break; case OC_Int16: case OC_UInt16: d16 = (unsigned short*)md->data.data; memcpy((void*)memory,(void*)(d16+start),totalsize); break; case OC_Int32: case OC_UInt32: case OC_Float32: d32 = (unsigned int*)md->data.data; memcpy((void*)memory,(void*)(d32+start),totalsize); break; #ifdef HAVE_LONG_LONG_INT case OC_Int64: case OC_UInt64: case OC_Float64: d64 = (unsigned long long*)md->data.data; memcpy((void*)memory,(void*)(d64+start),totalsize); break; #endif case OC_String: case OC_URL: { unsigned int i; char** memstrings = (char**)memory; dstring = (char**)md->data.data; for(i=0;i<count;i++) { memstrings[i] = nulldup(dstring[start+i]); } } break; default: OCPANIC1("unexpected etype: %d",content->node->etype); } return OCTHROW(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, off_t* 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 oclog(OCLOGNOTE,"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: oclog(OCLOGERR, "curl error: %s", curl_easy_strerror(cstat)); return OCTHROW(OC_ECURL); }
static OCerror ocextract_credentials(const char *url, char **userpwd, char **result_url) { OCURI* parsed = NULL; if(!ocuriparse(url,&parsed)) return OCTHROW(OC_EBADURL); if(parsed->userpwd == NULL) { ocurifree(parsed); return OCTHROW(OC_EBADURL); } if(userpwd) *userpwd = strdup(parsed->userpwd); ocurifree(parsed); return OC_NOERR; }
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->header.magic = OCMAGIC; state->header.occlass = OC_State; state->curl = curl; state->trees = oclistnew(); state->uri = tmpurl; if(!ocuridecodeparams(state->uri)) { oclog(OCLOGWARN,"Could not parse client parameters"); } state->packet = ocbytesnew(); ocbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/ /* capture curl properties for this link from rc file1*/ stat = ocset_curlproperties(state); if(stat != OC_NOERR) goto fail; /* Set the one-time curl flags */ if((stat=ocset_flags_perlink(state))!= OC_NOERR) goto fail; #if 1 /* temporarily make per-link */ if((stat=ocset_flags_perfetch(state))!= OC_NOERR) goto fail; #endif if(statep) *statep = state; else { if(state != NULL) ocfree(state); } return OCTHROW(stat); fail: ocurifree(tmpurl); if(state != NULL) ocfree(state); if(curl != NULL) occurlclose(curl); return OCTHROW(stat); }
OCerror ocdata_read(OCstate* state, OCdata* data, size_t start, size_t count, void* memory, size_t memsize) { int stat = OC_NOERR; XXDR* xdrs; OCtype etype, octype; int isscalar; size_t elemsize, totalsize, countsize; OCnode* pattern; octrace("read", state, data); assert(state != NULL); assert(data != NULL); assert(memory != NULL); assert(memsize > 0); pattern = data->pattern; octype = pattern->octype; assert(octype == OC_Atomic); etype = pattern->etype; isscalar = (pattern->array.rank == 0 ? 1 : 0); /* validate memory space*/ elemsize = octypesize(etype); totalsize = elemsize*data->ninstances; countsize = elemsize*count; if(totalsize < countsize || memsize < countsize) return OCTHROW(OC_EINVAL); /* Get XXDR* */ xdrs = pattern->root->tree->data.xdrs; if(isscalar) { /* Extract the data */ stat = ocread(data,xdrs,(char*)memory,memsize,0,1); } else { /* Validate the start and count */ if(start >= data->ninstances || (start+count) > data->ninstances) return OCTHROW(OC_EINVALCOORDS); /* Extract the data */ stat = ocread(data,xdrs,(char*)memory,memsize,start,count); } return OCTHROW(stat); }
static OCerror ocextractddsinmemory(OCstate* state, OCtree* tree, OCflags flags) { OCerror stat = OC_NOERR; size_t ddslen, bod, bodfound; /* Read until we find the separator (or EOF)*/ bodfound = findbod(state->packet,&bod,&ddslen); if(!bodfound) {/* No BOD; pretend */ bod = tree->data.bod; ddslen = tree->data.datasize; } tree->data.bod = bod; tree->data.ddslen = ddslen; /* copy out the dds */ if(ddslen > 0) { tree->text = (char*)ocmalloc(ddslen+1); memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen); tree->text[ddslen] = '\0'; } else tree->text = NULL; /* Extract the inmemory contents */ tree->data.memory = ocbytesextract(state->packet); #ifdef IGNORE /* guarantee the data part is on an 8 byte boundary */ if(tree->data.bod % 8 != 0) { unsigned long count = tree->data.datasize - tree->data.bod; memcpy(tree->xdrmemory,tree->xdrmemory+tree->data.bod,count); tree->data.datasize = count; tree->data.bod = 0; tree->data.ddslen = 0; } #endif if(tree->text == NULL) stat = OC_EDATADDS; return OCTHROW(stat); }
static int readfiletofile(const char* path, const char* suffix, FILE* stream, off_t* sizep) { int stat = OC_NOERR; OCbytes* packet = ocbytesnew(); size_t len; /* check for leading file:/// */ if(ocstrncmp(path,"file:///",8)==0) path += 7; /* assume absolute path*/ stat = readfile(path,suffix,packet); #ifdef OCDEBUG fprintf(stderr,"readfiletofile: packet.size=%lu\n", (unsigned long)ocbyteslength(packet)); #endif if(stat != OC_NOERR) goto unwind; len = oclistlength(packet); if(stat == OC_NOERR) { size_t written; fseek(stream,0,SEEK_SET); written = fwrite(ocbytescontents(packet),1,len,stream); if(written != len) { #ifdef OCDEBUG fprintf(stderr,"readfiletofile: written!=length: %lu :: %lu\n", (unsigned long)written,(unsigned long)len); #endif stat = OC_EIO; } } if(sizep != NULL) *sizep = len; unwind: ocbytesfree(packet); return OCTHROW(stat); }
/* Use this to attach to a data tree for a DATADDS */ OCerror ocdata_getroot(OCstate* state, OCnode* root, OCdata** datap) { OCdata* data; assert(root->tree->dxdclass == OCDATADDS); assert(root->octype == OC_Dataset); if(root->tree->data.data == NULL) return OCTHROW(OC_ENODATA); data = root->tree->data.data; if(datap) *datap = data; octrace("attach",state,data); return OCTHROW(OC_NOERR); }
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); }
OCerror ocset_useragent(OCstate* state, const char* agent) { OCerror stat = OC_NOERR; if(state->curlflags.useragent != NULL) free(state->curlflags.useragent); state->curlflags.useragent = strdup(agent); if(state->curlflags.useragent == NULL) return OCTHROW(OC_ENOMEM); stat = ocset_curlflag(state,CURLOPT_USERAGENT); return stat; }
OCerror ocset_netrc(OCstate* state, const char* path) { OCerror stat = OC_NOERR; if(state->curlflags.netrc != NULL) free(state->curlflags.netrc); state->curlflags.netrc = strdup(path); if(state->curlflags.netrc == NULL) return OCTHROW(OC_ENOMEM); stat = ocset_curlflag(state,CURLOPT_NETRC); return stat; }
/* DRNO need to explicitly get and walk string values*/ int oc_stringcontent(OCstate* state, OCcontent* content, char** stringp, size_t* slenp) { int stat = OC_NOERR; XDR* xdrs; unsigned int slen; char* stringmemory; if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL); if(content->node->octype != OC_Primitive) return OCTHROW(OC_EINVAL); if(content->node->etype != OC_String && content->node->etype != OC_URL) return OCTHROW(OC_EINVAL); xdrs = state->dap.xdrs; if(xdrs == NULL) return OCTHROW(OC_EXDR); if(oc_contentmode(state,content) != Datamode) return OCTHROW(OC_EINVAL); /* We are at a single instance of a string data type*/ if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror(); if(!xdr_u_int(xdrs,&slen)) return xdrerror(); stringmemory = (char*)ocmalloc(slen+1); MEMCHECK(stringmemory,OC_ENOMEM); if(!xdr_opaque(xdrs,stringmemory,slen)) return xdrerror(); stringmemory[slen] = '\0'; /* restore location*/ if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror(); if(stringp != NULL) *stringp = stringmemory; if(slenp != NULL) *slenp = slen; return OCTHROW(stat); }
int ocrootcontent(OCstate* state, OCnode* root, OCcontent* content) { OCtree* tree; if(state == NULL || root == NULL || content == NULL) return OCTHROW(OC_EINVAL); if(root->tree == NULL) return OCTHROW(OC_EINVAL); tree = root->tree; if(tree->dxdclass != OCDATADDS) return OCTHROW(OC_ENODATA); if(tree->nodes == NULL) return OCTHROW(OC_EINVAL); if(tree->data.memdata == NULL && tree->data.xdrs == NULL) return OCTHROW(OC_EXDR); ocresetcontent(state,content); content->state = state; /* make sure*/ content->mode = Fieldmode; content->node = root; content->tree = tree; content->maxindex = oclistlength(content->node->subnodes); if(tree->data.memdata == NULL) { content->xdrpos.offset = tree->data.bod; content->xdrpos.valid = 1; } else { content->memdata = tree->data.memdata; content->mode = tree->data.memdata->mode; } return OCTHROW(OC_NOERR); }
OCerror ocdata_position(OCstate* state, OCdata* data, size_t* indices) { OCnode* pattern; OCASSERT(state != NULL); OCASSERT(data != NULL); OCASSERT(indices != NULL); pattern = data->pattern; if(fisset(data->datamode,OCDT_RECORD)) indices[0] = data->index; else if(fisset(data->datamode,OCDT_ELEMENT)) { /* Transform the linearized array index into a set of indices */ ocarrayindices(data->index, pattern->array.rank, pattern->array.sizes, indices); } else return OCTHROW(OC_EBADTYPE); return OCTHROW(OC_NOERR); }
OCerror ocdata_container(OCstate* state, OCdata* data, OCdata** containerp) { OCdata* container; OCnode* pattern; OCASSERT(state != NULL); pattern = data->pattern; if(pattern->container == NULL) return OCTHROW(OC_EBADTYPE); container = data->container; if(container == NULL) return OCTHROW(OC_EBADTYPE); if(containerp) *containerp = container; octrace("container", state, container); return OC_NOERR; }
OCerror ocupdatelastmodifieddata(OCstate* state) { OCerror status = OC_NOERR; long lastmodified; char* base = NULL; base = ocuribuild(state->uri,NULL,NULL,OCURIENCODE); status = ocfetchlastmodified(state->curl, base, &lastmodified); free(base); if(status == OC_NOERR) { state->datalastmodified = lastmodified; } return OCTHROW(status); }
OCerror ocdata_ithelement(OCstate* state, OCdata* data, size_t* indices, OCdata** elementp) { int stat = OC_NOERR; OCdata* element; OCnode* pattern; size_t index,rank; OCASSERT(state != NULL); OCASSERT(data != NULL); pattern = data->pattern; rank = pattern->array.rank; /* Must be a dimensioned Structure */ if(pattern->octype != OC_Structure || rank == 0) return OCTHROW(OC_EBADTYPE); /* Validate indices */ if(!ocvalidateindices(rank,pattern->array.sizes,indices)) return OCTHROW(OC_EINVALCOORDS); /* compute linearized index */ index = ocarrayoffset(rank,pattern->array.sizes,indices); if(index >= data->ninstances) return OCTHROW(OC_EINDEX); element = data->instances[index]; if(elementp) *elementp = element; octrace("ithelement", state, element); return OCTHROW(stat); }
OCerror ocdata_recordcount(OCstate* state, OCdata* data, size_t* countp) { OCASSERT(state != NULL); OCASSERT(data != NULL); OCASSERT(countp != NULL); if(data->pattern->octype != OC_Sequence || !fisset(data->datamode,OCDT_SEQUENCE)) return OCTHROW(OC_EBADTYPE); *countp = data->ninstances; return OC_NOERR; }
int readDATADDS(OCstate* state, OCtree* tree, OCflags flags) { int stat = OC_NOERR; long lastmod = -1; #ifdef OCDEBUG fprintf(stderr,"readDATADDS:\n"); #endif if((flags & OCONDISK) == 0) { ocurisetconstraints(state->uri,tree->constraint); stat = readpacket(state,state->uri,state->packet,OCDATADDS,&lastmod); if(stat == OC_NOERR) state->datalastmodified = lastmod; tree->data.datasize = ocbyteslength(state->packet); } else { /*((flags & OCONDISK) != 0) */ OCURI* url = state->uri; int fileprotocol = 0; char* readurl = NULL; fileprotocol = (strcmp(url->protocol,"file")==0); if(fileprotocol && !state->curlflags.proto_file) { readurl = ocuribuild(url,NULL,NULL,0); stat = readfiletofile(readurl, ".dods", tree->data.file, &tree->data.datasize); } else { int flags = 0; if(!fileprotocol) flags |= OCURICONSTRAINTS; flags |= OCURIENCODE; flags |= OCURIUSERPWD; ocurisetconstraints(url,tree->constraint); readurl = ocuribuild(url,NULL,".dods",flags); MEMCHECK(readurl,OC_ENOMEM); if (ocdebug > 0) {fprintf(stderr, "fetch url=%s\n", readurl);fflush(stderr);} stat = ocfetchurl_file(state->curl, readurl, tree->data.file, &tree->data.datasize, &lastmod); if(stat == OC_NOERR) state->datalastmodified = lastmod; if (ocdebug > 0) {fprintf(stderr,"fetch complete\n"); fflush(stderr);} } free(readurl); } return OCTHROW(stat); }
static OCerror ocextractddsinfile(OCstate* state, OCtree* tree, OCflags flags) { OCerror stat = OC_NOERR; size_t ddslen, bod, bodfound; /* Read until we find the separator (or EOF)*/ ocbytesclear(state->packet); rewind(tree->data.file); bodfound = 0; do { char chunk[1024]; size_t count; /* read chunks of the file until we find the separator*/ count = fread(chunk,1,sizeof(chunk),tree->data.file); if(count <= 0) break; /* EOF;*/ ocbytesappendn(state->packet,chunk,count); bodfound = ocfindbod(state->packet,&bod,&ddslen); } while(!bodfound); if(!bodfound) {/* No BOD; pretend */ bod = tree->data.bod; ddslen = tree->data.datasize; #ifdef OCDEBUG fprintf(stderr,"missing bod: ddslen=%lu bod=%lu\n", (unsigned long)ddslen,(unsigned long)bod); #endif } tree->data.bod = bod; tree->data.ddslen = ddslen; /* copy out the dds */ if(ddslen > 0) { tree->text = (char*)ocmalloc(ddslen+1); memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen); tree->text[ddslen] = '\0'; } else tree->text = NULL; /* reset the position of the tmp file*/ if(fseek(tree->data.file,(long)tree->data.bod,SEEK_SET) < 0 || tree->text == NULL) stat = OC_EDATADDS; return OCTHROW(stat); }
static int readpacket(OCstate* state, OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodified) { int stat = OC_NOERR; int fileprotocol = 0; const char* suffix = ocdxdextension(dxd); char* fetchurl = NULL; CURL* curl = state->curl; fileprotocol = (strcmp(url->protocol,"file")==0); if(fileprotocol && !state->curlflags.proto_file) { /* Short circuit file://... urls*/ /* We do this because the test code always needs to read files*/ fetchurl = ocuribuild(url,NULL,NULL,0); stat = readfile(fetchurl,suffix,packet); } else { int flags = 0; if(!fileprotocol) { flags |= OCURICONSTRAINTS; } flags |= OCURIENCODE; fetchurl = ocuribuild(url,NULL,suffix,flags); MEMCHECK(fetchurl,OC_ENOMEM); if(ocdebug > 0) {fprintf(stderr,"fetch url=%s\n",fetchurl); fflush(stderr);} stat = ocfetchurl(curl,fetchurl,packet,lastmodified,&state->creds); if(stat) oc_curl_printerror(state); if(ocdebug > 0) {fprintf(stderr,"fetch complete\n"); fflush(stderr);} } free(fetchurl); #ifdef OCDEBUG { fprintf(stderr,"readpacket: packet.size=%lu\n", (unsigned long)ocbyteslength(packet)); } #endif return OCTHROW(stat); }
static OCerror createtempfile(OCstate* state, OCtree* tree) { int stat = OC_NOERR; char* path = NULL; char* name = NULL; int len; len = strlen(ocglobalstate.tempdir) + 1 /* '/' */ + strlen(DATADDSFILE); path = (char*)malloc(len+1); if(path == NULL) return OC_ENOMEM; occopycat(path,len,3,ocglobalstate.tempdir,"/",DATADDSFILE); stat = ocmktmp(path,&name); free(path); if(stat != OC_NOERR) goto fail; #ifdef OCDEBUG oclog(OCLOGNOTE,"oc_open: creating tmp file: %s",name); #endif tree->data.filename = name; /* remember our tmp file name */ name = NULL; tree->data.file = fopen(tree->data.filename,"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 stat; fail: if(name != NULL) { oclog(OCLOGERR,"oc_open: attempt to create tmp file failed: %s",name); free(name); } else { oclog(OCLOGERR,"oc_open: attempt to create tmp file failed: NULL"); } return OCTHROW(stat); }
/** * Prefix must end in '/' */ static OCerror rc_search(const char* prefix, const char* rcname, char** pathp) { char* path = NULL; FILE* f = NULL; int plen = strlen(prefix); int rclen = strlen(rcname); OCerror stat = OC_NOERR; size_t pathlen = plen+rclen+1+1; /*+1 for '/' +1 for nul*/ path = (char*)malloc(pathlen); if(path == NULL) { stat = OC_ENOMEM; goto done; } if(!occopycat(path,pathlen,3,prefix,"/",rcname)) { stat = OC_EOVERRUN; goto done; } /* see if file is readable */ f = fopen(path,"r"); if(f != NULL) oclog(OCLOGDBG, "Found rc file=%s",path); done: if(f == NULL || stat != OC_NOERR) { if(path != NULL) free(path); path = NULL; } if(f != NULL) fclose(f); if(pathp != NULL) *pathp = path; return OCTHROW(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); }