/* 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; }
static OCerror ocread(OCdata* data, XXDR* xdrs, char* memory, size_t memsize, size_t start, size_t count) { int i; OCnode* pattern; OCtype etype; off_t elemsize, totalsize, xdrtotal, xdrstart; int scalar; OCASSERT(data != NULL); OCASSERT(memory != NULL); OCASSERT(memsize > 0); OCASSERT(count > 0); OCASSERT((start+count) <= data->ninstances); pattern = data->pattern; etype = pattern->etype; scalar = (pattern->array.rank == 0); /* Note that for strings, xdrsize == 0 */ xdrtotal = count*data->xdrsize; /* amount (in xdr sizes) to read */ xdrstart = start*data->xdrsize; /* offset from the start of the data */ elemsize = octypesize(etype); /* wrt memory, not xdrsize */ totalsize = elemsize*count; /* validate memory space*/ if(memsize < totalsize) return OCTHROW(OC_EINVAL); /* copy out with appropriate byte-order conversions */ switch (etype) { case OC_Int32: case OC_UInt32: case OC_Float32: xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} if(!xxdr_network_order) { unsigned int* p; for(p=(unsigned int*)memory,i=0;i<count;i++,p++) { swapinline32(p); } } break; case OC_Int64: case OC_UInt64: xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} if(!xxdr_network_order) { unsigned long long* llp; for(llp=(unsigned long long*)memory,i=0;i<count;i++,llp++) { swapinline64(llp); } } break; case OC_Float64: xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} { double* dp; for(dp=(double*)memory,i=0;i<count;i++,dp++) { double swap; xxdrntohdouble((char*)dp,&swap); *dp = swap; } } break; /* non-packed fixed length, but memory size < xdrsize */ case OC_Int16: case OC_UInt16: { /* In order to avoid allocating a lot of space, we do this one int at a time */ /* Remember also that the short is not packed, so its xdr size is twice its memory size */ xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(scalar) { if(!xxdr_ushort(xdrs,(unsigned short*)memory)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } else { unsigned short* sp = (unsigned short*)memory; for(i=0;i<count;i++,sp++) { unsigned int tmp; if(!xxdr_getbytes(xdrs,(char*)&tmp,(off_t)XDRUNIT)) {OCTHROW(OC_EDATADDS); goto xdrfail;} /* convert from network order if necessary */ if(!xxdr_network_order) swapinline32(&tmp); /* store as unsigned short */ *sp = (unsigned short)tmp; } } } break; /* Do the byte types, packed/unpacked */ case OC_Byte: case OC_UByte: case OC_Char: if(scalar) { /* scalar bytes are stored in xdr as int */ xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_uchar(xdrs,(unsigned char*)memory)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } else { /* the xdroffset will always be at the start of the packed data, so we need to add the start count to it */ xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } break; /* Hard case, because strings are variable length */ case OC_String: case OC_URL: { /* use the data->nstrings data->string fields */ char** sp = (char**)memory; if(count > data->nstrings) return OCTHROW(OC_EDATADDS); for(i=0;i<count;i++,sp++) { off_t len; off_t offset = data->strings[start+i]; xxdr_setpos(xdrs,offset); /* get the string */ if(!xxdr_string(xdrs,sp,&len)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } } break; default: OCPANIC("unexpected etype"); break; } return OC_NOERR; xdrfail: oclog(OCLOGERR,"DAP DATADDS packet is apparently too short"); return OCTHROW(OC_EDATADDS); }