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); }
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); }
char* ocdodsrc_lookup(char* key, char* url) { int i,found; struct OCTriplestore* ocdodsrc = ocglobalstate.ocdodsrc; struct OCTriple* triple = ocdodsrc->triples; if(key == NULL || ocdodsrc == NULL) return NULL; if(url == NULL) url = ""; /* Assume that the triple store has been properly sorted */ for(found=0,i=0;i<ocdodsrc->ntriples;i++,triple++) { int triplelen = strlen(triple->url); int t; if(strcmp(key,triple->key) != 0) continue; /* keys do not match */ /* If the triple entry has no url, then use it (because we have checked all other cases)*/ if(triplelen == 0) {found=1;break;} /* do url prefix comparison */ t = ocstrncmp(url,triple->url,triplelen); if(t == 0) {found=1; break;} } if(ocdebug > 2) { if(found) { fprintf(stderr,"lookup %s: [%s]%s = %s\n",url,triple->url,triple->key,triple->value); } } return (found ? triple->value : NULL); }
int ocfindbod(OCbytes* buffer, size_t* bodp, size_t* ddslenp) { unsigned int i; char* content; size_t len = ocbyteslength(buffer); char** marks; content = ocbytescontents(buffer); for(marks = DDSdatamarks;*marks;marks++) { char* mark = *marks; int tlen = strlen(mark); for(i=0;i<len;i++) { if((i+tlen) <= len && (ocstrncmp(content+i,mark,tlen)==0)) { *ddslenp = i; i += tlen; *bodp = i; return 1; } } } *ddslenp = 0; *bodp = 0; return 0; /* tag not found; not necessarily an error*/ }
static int isdodsname(const char* name) { int len = strlen(name); int glen = strlen("DODS"); if(len < glen) return 0; if(ocstrncmp(name,"DODS",glen) != 0) return 0; return 1; }
/** Directly set any options starting with 'CURL.' */ static OCerror oc_set_curl_options(OCstate* state) { OCerror stat = OC_NOERR; struct OCTriplestore* store = NULL; struct OCTriple* triple = NULL; int i; char* hostport = NULL; struct OCCURLFLAG* ocflag = NULL; hostport = occombinehostport(state->uri); if(hostport == NULL) { hostport = (char*)malloc(sizeof(char)*1); *hostport = ""; } store = &ocglobalstate.rc.ocrc; triple = store->triples; /* Assume that the triple store has been properly sorted */ for(i=0;i<store->ntriples;i++,triple++) { size_t hostlen = strlen(triple->host); const char* flagname; if(ocstrncmp("CURL.",triple->key,5) != 0) continue; /* not a curl flag */ /* do hostport prefix comparison */ if(hostlen > 0) { int t = ocstrncmp(hostport,triple->host,hostlen); if(t != 0) continue; } flagname = triple->key+5; /* 5 == strlen("CURL."); */ ocflag = occurlflagbyname(flagname); if(ocflag == NULL) {stat = OC_ECURL; goto done;} stat = ocset_curlopt(state,ocflag->flag,cvt(triple->value,ocflag->type)); } done: if(hostport && strcmp(hostport,"") != 0) free(hostport); return 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 {" int i,j; size_t 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,(off_t)0); /* read the whole thing */ contents = (char*)malloc(len+1); (void)xxdr_getbytes(xdrs,contents,(off_t)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; } oclog(OCLOGERR,"DATADDS failure, possible message: '%s'\n", contents+i); goto done; } } xxdr_setpos(xdrs,ckp); done: return; }
static int dataError(XXDR* xdrs, OCstate* state) { int depth=0; int errfound = 0; off_t ckp=0,avail=0; int i=0; char* errmsg = NULL; char errortext[16]; /* bigger thant |ERROR_TAG|*/ avail = xxdr_getavail(xdrs); if(avail < strlen(ERROR_TAG)) goto done; /* assume it is ok */ ckp = xxdr_getpos(xdrs); /* Read enough characters to test for 'ERROR ' */ errortext[0] = '\0'; xxdr_getbytes(xdrs,errortext,(off_t)strlen(ERROR_TAG)); if(ocstrncmp(errortext,ERROR_TAG,strlen(ERROR_TAG)) != 0) goto done; /* not an immediate error */ /* Try to locate the whole error body */ xxdr_setpos(xdrs,ckp); for(depth=0,i=0;i<avail;i++) { xxdr_getbytes(xdrs,errortext,(off_t)1); if(errortext[0] == CLBRACE) depth++; else if(errortext[0] == CRBRACE) { depth--; if(depth == 0) {i++; break;} } } errmsg = (char*)malloc((size_t)i+1); if(errmsg == NULL) {errfound = 1; goto done;} xxdr_setpos(xdrs,ckp); xxdr_getbytes(xdrs,errmsg,(off_t)i); errmsg[i] = '\0'; state->error.message = errmsg; state->error.code = strdup("?"); state->error.httpcode = 404; xxdr_setpos(xdrs,ckp); errfound = 1; done: xxdr_setpos(xdrs,ckp); return errfound; }
struct OCTriple* ocrc_triple_iterate(char* key, char* url, struct OCTriple* prev) { struct OCTriple* next; if(prev == NULL) next = ocrc_locate(key,url); else next = prev+1; if(next == NULL) return NULL; for(; strlen(next->key) > 0; next++) { /* See if key as prefix still matches */ int cmp = strcmp(key,next->key); if(cmp != 0) {next = NULL; break;} /* key mismatch */ /* compare url */ cmp = ocstrncmp(url,next->host,strlen(next->host)); if(cmp == 0) break; } return next; }