Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
OCerror
ocfetch(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 per-fetch curl properties */
#if 0 /* temporarily make per-link */
    if((stat=ocset_flags_perfetch(state))!= OC_NOERR) goto fail;
#endif

    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 & OCONDISK) != 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 fail;}
            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;
    default:
	break;
    }/*switch*/
    /* Obtain any http code */
    state->error.httpcode = ocfetchhttpcode(state->curl);
    if(stat != OC_NOERR) {
	if(state->error.httpcode >= 400) {
	    oclog(OCLOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode);
	} else {
	    oclog(OCLOGWARN,"oc_open: Could not read url");
	}
	goto fail;
    }

    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) {
	oclog(OCLOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"",
		  state->error.code,
		  (state->error.message?state->error.message:""));
    }
    if(stat) {OCTHROWCHK(stat); goto fail;}
    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 fail;}
	break;
    case OCDDS:
        if(root->octype != OC_Dataset)
	    {OCTHROWCHK(stat=OC_EDDS); goto fail;}
	break;
    case OCDATADDS:
        if(root->octype != OC_Dataset)
	    {OCTHROWCHK(stat=OC_EDATADDS); goto fail;}
	/* Modify the tree kind */
	tree->dxdclass = OCDATADDS;
	break;
    default: return OC_EINVAL;
    }

    if(kind != OCDAS) {
        /* 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 & OCONDISK) != 0) {
            tree->data.xdrs = xxdr_filecreate(tree->data.file,tree->data.bod);
	} else {
#ifdef OCDEBUG
fprintf(stderr,"ocfetch.datadds.memory: datasize=%lu bod=%lu\n",
	(unsigned long)tree->data.datasize,(unsigned long)tree->data.bod);
#endif
	    /* 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);
	/* Do a quick check to see if server returned an ERROR {}
           at the beginning of the data
         */
	if(dataError(tree->data.xdrs,state)) {
	    stat = OC_EDATADDS;
	    oclog(OCLOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"",
		  state->error.code,
		  (state->error.message?state->error.message:""));
	    goto fail;
	}

	/* Compile the data into a more accessible format */
	stat = occompile(state,tree->root);
	if(stat != OC_NOERR)
	    goto fail;
    }

    /* Put root into the state->trees list */
    oclistpush(state->trees,(void*)root);

    if(rootp) *rootp = root;
    return stat;

fail:
    if(root != NULL)
	ocroot_free(root);
    else if(tree != NULL)
	octree_free(tree);
    return OCTHROW(stat);
}
Exemplo n.º 5
0
int
ocgetcontent(OCstate* state, OCcontent* content, void* memory, size_t memsize,
                 size_t start, size_t count)
{
    int stat = OC_NOERR;
    XDR* xdrs;
    OCtype etype;
    int isscalar;
    size_t elemsize, totalsize;
    int packed;
    unsigned int xdrcount;

    if(state == NULL || content == NULL || memory == NULL)
	{OCTHROWCHK(stat=OC_EINVAL); goto done;}
    if(content->node->octype != OC_Primitive)
	{OCTHROWCHK(stat=OC_EINVAL); goto done;}
    if(content->maxindex > 0 && content->maxindex < start+count)
	return OCTHROW(OC_ENODATA);

    etype = content->node->etype;
    isscalar = (content->node->array.rank == 0);
    if(isscalar && (start != 0 || count != 1))
	{OCTHROWCHK(stat=OC_EINVALCOORDS); goto done;}

    /* validate memory space*/
    elemsize = octypesize(etype);
    totalsize = elemsize*count;
    if(memsize < totalsize) return OCTHROW(OC_EINVAL);

    OCASSERT((occontentmode(state,content)==Dimmode || isscalar));

    if(content->memdata != NULL) { /* Get data from the compiled version */
	stat = ocgetmemdata(state,content,memory,memsize,start,count);
	goto done;
    }
    /* No memdata => use xdr */
    xdrs = content->tree->data.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    /* check if the data is packed*/
    packed = (!isscalar && (etype == OC_Byte || etype == OC_UByte || etype == OC_Char));

    content->packed = packed;

    /* Make sure we are at the proper offset: ie at count if !scalar */
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) goto shortxdr;

    if(!isscalar) {
        /* Collect the dimension count from the xdr data packet*/
        if(!xdr_u_int(xdrs,&xdrcount)) goto shortxdr;
        if(xdrcount < start) return OCTHROW(OC_EINVALCOORDS);
        if(xdrcount < start+count) return OCTHROW(OC_EINVALCOORDS);
        /* pull out redundant second count*/
        /* (note that String/URL do not have redundant count)*/
        if(etype != OC_String && etype != OC_URL) {
            if(!xdr_u_int(xdrs,&xdrcount)) goto shortxdr;
        }
    }
    /* Extract the data */
#ifdef OCPROGRESS
    oc_log(LOGNOTE,"reading xdr: %lu bytes",(unsigned long)memsize);
#endif
    stat = ocxdrread(xdrs,(char*)memory,memsize,packed,content->node->etype,start,count);
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror(); /* restore location*/
done:
    return OCTHROW(stat);
shortxdr:
    oc_log(LOGERR,"DAP DATADDS appears to be too short");
    return OC_EDATADDS;
}
Exemplo n.º 6
0
/*
The ocfieldcontent procedure has to deal with the fact
that the dap constraints may have removed some fields
from the datadds and hence some fields may have no
representation in the xdr data (or compiled data).
*/
int
ocfieldcontent(OCstate* state, OCcontent* content, OCcontent* fieldcontent, size_t index)
{
    unsigned int i;
    int stat = OC_NOERR;
    XDR* xdrs;
    OCtype octype,etype;
    int packed;

    if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL);
    if(content->mode != Fieldmode) return OCTHROW(OC_EINVAL);

    if(content->maxindex > 0 && content->maxindex <= index)
	return OCTHROW(OC_EINVALCOORDS);

    content->index = index; /* Track our location in parent content */

    octype = content->node->octype;
    etype = content->node->etype;

    /* check if the data is packed*/
    packed = (octype == OC_Primitive &&
              (etype == OC_Byte || etype == OC_UByte || etype == OC_Char));

    ocresetcontent(state,fieldcontent);
    /* Set the state of the new content*/
    fieldcontent->state = state; /* make sure*/
    fieldcontent->tree = content->tree;
    fieldcontent->node = (OCnode*)oclistget(content->node->subnodes,index);
    fieldcontent->packed = packed;
    fieldcontent->mode = modetransition(fieldcontent->node, content->mode);
    fieldcontent->index = 0; /* record where we want to be */
    fieldcontent->maxindex = maxindexfor(fieldcontent->node,content->mode);

    if(content->memdata != NULL) { /* Get data from the compiled version */
	OCmemdata* md = content->memdata;
	OCmemdata* next;
        OCASSERT((md->mode == Fieldmode));
	if(md->count <= index) {OCTHROWCHK(stat=OC_ENODATA); goto done;}
	next = ((OCmemdata**)md->data.data)[index];
	if(next == NULL) {OCTHROWCHK(stat=OC_ENODATA); goto done;}
	fieldcontent->memdata = next;
	goto done;
    }

    xdrs = content->tree->data.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    /* 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 xdrerror();

    switch (content->node->octype) {
    case OC_Grid:
	/* Note that the Grid array is field 0 and the maps are 1..nsubnodes*/
    case OC_Sequence:
    case OC_Dataset:
    case OC_Structure:
	if(index >= oclistlength(content->node->subnodes)) return OCTHROW(OC_EINVALCOORDS);
        for(i=0;i<index;i++) {
  	    OCnode* field = (OCnode*)oclistget(content->node->subnodes,i);
	    stat = ocskip(field,xdrs);
	    if(stat != OC_NOERR) return OCTHROW(stat);
        }
        fieldcontent->xdrpos.offset = xdr_getpos(xdrs);
	fieldcontent->xdrpos.valid = 1;
	break;

    case OC_Primitive:
    default: return OCTHROW(OC_EINVAL);
    }

    /* move back to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

done:
    return OCTHROW(stat);
}
Exemplo n.º 7
0
int
ocrecordcontent(OCstate* state,OCcontent* content, OCcontent* recordcontent, size_t index)
{
    unsigned int i;
    int stat = OC_NOERR;
    XDR* xdrs;
    char tmp[BYTES_PER_XDR_UNIT];
    OCtype octype,etype;
    int packed;

    if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL);
    if(content->mode != Recordmode) return OCTHROW(OC_EINVAL);

    if(content->maxindex > 0 && content->maxindex <= index)
	return OCTHROW(OC_EINVALCOORDS);
    content->index = index; /* Track our location in parent content */

    octype = content->node->octype;
    etype = content->node->etype;

    /* check if the data is packed*/
    packed = (octype == OC_Primitive &&
              (etype == OC_Byte || etype == OC_UByte || etype == OC_Char));

    ocresetcontent(state,recordcontent);
    /* Set some of the new content*/
    recordcontent->state = state; /* make sure*/
    recordcontent->tree = content->tree;
    recordcontent->node = content->node;
    recordcontent->packed = packed;
    recordcontent->mode = modetransition(recordcontent->node, content->mode);
    recordcontent->index = 0;
    recordcontent->maxindex = maxindexfor(recordcontent->node,content->mode);

    if(content->memdata != NULL) { /* Get data from the compiled version */
	OCmemdata* next;
        OCASSERT((content->memdata->mode == Recordmode));
	if(content->memdata->count <= index)
	    {OCTHROWCHK(stat=OC_ENODATA); goto done;}
	next = ((OCmemdata**)content->memdata->data.data)[index];
	recordcontent->memdata = next;
	goto done;
    }

    xdrs = content->tree->data.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    /* 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 xdrerror();

    switch (content->node->octype) {
    case OC_Sequence:
        for(i=0;i<index;i++) {
            /* pick up the sequence record begin marker*/
            /* extract the tag byte*/
            if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) return xdrerror();
            if(tmp[0] == StartOfoclist) {
                /* skip instance*/
                stat = ocskipinstance(content->node,xdrs);
            } else if(tmp[0] == EndOfoclist) {
                stat = OC_EINVALCOORDS; /* not enough records*/
                break;
            } else {
                oc_log(LOGERR,"missing/invalid begin/end record marker\n");
                stat = OC_EINVAL;
                break;
            }
        }
	if(stat != OC_NOERR) return OCTHROW(stat);

	/* skip the sequence begin marker for the chosen record*/
	/* so we are at its contents*/
        if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) return xdrerror();
        if(tmp[0] != StartOfoclist) return OCTHROW(OC_EINVALCOORDS);

	/* Set contents of the output content*/
        recordcontent->xdrpos.offset = xdr_getpos(xdrs);
	recordcontent->xdrpos.valid = 1;
	break;

    case OC_Dataset:
    case OC_Structure:
    case OC_Grid:
    case OC_Primitive:
    default: return OCTHROW(OC_EINVAL);
    }

    /* move back to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

done:
    return OCTHROW(stat);
}