|
|
Initial revision
/* enc.c */
#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/enc.c,v 1.1 2018/04/24 16:12:56 root Exp $";
#endif
/*
* $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/enc.c,v 1.1 2018/04/24 16:12:56 root Exp $
*
*
* $Log: enc.c,v $
* Revision 1.1 2018/04/24 16:12:56 root
* Initial revision
*
* Revision 7.2 90/07/27 08:49:34 mrose
* update
*
* Revision 7.1 90/07/09 14:52:27 mrose
* sync
*
* Revision 7.0 90/07/01 19:54:16 mrose
* *** empty log message ***
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
#include <stdio.h>
#include <ctype.h>
#include "psap.h"
#include "pepsy.h"
#include "tailor.h"
#ifndef PEPYPARM
#define PEPYPARM char *
#endif
extern tpe *next_tpe();
char *idname(), *clname();
#define NEXT_TPE(p) (p = next_tpe(p))
#define CHKTAG(mod, p, pe) ismatch(p, mod, pe->pe_class, pe->pe_id)
static char oomsg[] = "Out of memory";
#define oom(a,b) pepsylose ((a), (b), NULLPE, oomsg);
#define RET_OK(rpe, pe) *(rpe) = (pe), (OK)
/*
* encode the specified type of the specified module into the given
* pe
*/
enc_f(typ, mod, pe, explicit, len, buf, parm)
/* ARGSUSED */
int typ; /* which type it is */
modtyp *mod; /* Module it is from */
register PE *pe;
int explicit;
int len;
char *buf;
char *parm;
{
register tpe *p;
if (typ < 0 || typ >= mod->md_nentries) {
(void) pepsylose (mod, NULLTPE, NULLPE, "enc_f:Illegal typ %d", typ);
return NOTOK;
}
p = mod->md_etab[typ];
if (p->pe_type != PE_START) {
return (pepsylose (mod, NULLTPE, NULLPE, "enc_f: missing PE_START"));
}
p++;
return (en_obj(parm, p, mod, pe));
}
/*
* Encode an object. If the object is a simple type it may have a
* compressed type reference. If it is a compound type it will not
* have an offset. This is very important as it means we cannot just
* use en_type to handle this which must always assume the field can
* have an offset.
*/
static int
en_obj(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
PE pe = NULLPE; /* for pepsylose calls */
int cnt = 0;
tpe *tmp;
DLOG (psap_log, LLOG_DEBUG, ("en_obj: type %d", p->pe_type));
*rpe = NULLPE; /* default case */
while (p->pe_type != PE_END) {
switch (p->pe_type) {
case PE_END:
case PE_START:
return (pepsylose (mod, p, pe, "en_obj:END/START type"));
case UCODE:
break;
case ETAG:
if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
return oom (mod, p);
switch (p->pe_ucode) {
default:
p++;
if (en_obj(parm, p, mod, &pe->pe_cons) == NOTOK)
goto bad;
}
break;
case SEQ_START:
if (en_seq(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQOF_START:
if (en_seqof(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case SET_START:
if (en_set(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case SETOF_START:
if (en_setof(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
0, (char *)0, (parm)) == NOTOK)
return (NOTOK);
} else if (en_obj(parm, mod->md_etab[p->pe_tag]+1, mod, &pe)==NOTOK)
goto bad;
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
if (en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case OBJECT:
if (en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case CHOICE_START:
if (en_choice(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
default:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
}
if (ISDTYPE(p) && cnt++ > 0)
return pepsylose (mod, p, NULLPE, "en_obj:compound type found");
if (ISDTYPE(p)) {
if (pe == NULLPE)
return pepsylose (mod, p, NULLPE,
"en_obj: missing mandatory value");
}
if (ISDTYPE(p) && pe != NULLPE)
return (RET_OK(rpe, pe));
if (NEXT_TPE(p) == NULLTPE)
goto bad;
}
return (RET_OK(rpe, pe));
bad:
return (NOTOK);
}
/*
* Encode a single type. If a basic type encode it, if a compound
* type call the appropriate encoding routine
*/
static int
en_type(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
PE pe = NULLPE;
int cnt = 0;
int i; /* Integer for encoding type */
tpe *tmp;
char *cp;
DLOG (psap_log, LLOG_DEBUG, ("Encoding the type %d", p->pe_type));
*rpe = NULLPE;
while (p->pe_type != PE_END) {
switch (p->pe_type) {
case PE_END:
case PE_START:
return (pepsylose (mod, p, pe, "en_type:END/START type"));
case DFLT_F:
p++;
if ((i = same(p, p - 1, parm, mod)) == NOTOK)
return (NOTOK); /* Error */
if (i)
return (RET_OK(rpe, NULLPE));/* don't encode it */
continue;
case UCODE:
break;
case ETAG:
if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
return oom (mod, p);
switch (p->pe_ucode) {
default:
p++;
if (en_etype(parm, p, mod, &pe->pe_cons) == NOTOK)
goto bad;
}
break;
case SEQ_START:
if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQOF_START:
if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SET_START:
if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SETOF_START:
if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
} else if (p->pe_type == SOBJECT) {
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1, mod, &pe)
== NOTOK)
goto bad;;
} else
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1, mod, &pe)
== NOTOK)
goto bad;
break;
case OBJECT:
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case CHOICE_START:
if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) ==NOTOK)
goto bad;
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, &p[1], NULLPE,
"en_seq: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
(char *) parm) == NOTOK)
return (NOTOK);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, &p[1], NULLPE,
"en_seq: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
*(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
break;
case INTEGER:
DLOG (psap_log, LLOG_DEBUG,
("en_type:INTEGER offset is %d, value is %d",
p->pe_ucode, *(int *) (parm + p->pe_ucode)));
if ((pe = num2prim(*(int *) (parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
#ifdef PEPSY_REALS
case REALTYPE:
DLOG (psap_log, LLOG_DEBUG, ("en_type:REAL: offset %d valus %d",
p->pe_ucode
*(int *) (parm + p->pe_ucode)));
if ((pe = real2prim(*(double *) (parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
#endif
case BOOLEAN:
DLOG (psap_log, LLOG_DEBUG, ("en_type:BOOLEAN:offset %d value %d",
p->pe_ucode,
*(char *) (parm + p->pe_ucode)));
if ((pe = flag2prim(*(char *) (parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
case T_NULL:
DLOG (psap_log, LLOG_DEBUG, ("en_type:NULL:offset %d",p->pe_ucode));
if ((pe = pe_alloc(CLASS(p), PE_FORM_PRIM,
TAG(p))) == NULLPE)
return oom(mod,p);
break;
case SANY:
(pe = (PE) parm)->pe_refcnt++;
break;
case ANY:
if ((parm + p->pe_ucode) == 0 || *(PE *) (parm + p->pe_ucode) == 0)
#if ROSAP_HACK
/* hack for ROSAP. expects this strangeness */
pe = pe_alloc(PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL);
#else
pe = NULLPE;
#endif
else
(pe = *(PE *) (parm + p->pe_ucode))->pe_refcnt++;
break;
case SOCTETSTRING:
if ((pe = qb2prim((struct qbuf *) parm, CLASS(p), TAG(p)))
== NULLPE)
return oom(mod, p)
break;
case OCTETSTRING:
if ((pe = qb2prim(*(struct qbuf **) (parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
case SBITSTRING:
if ((cp = bitstr2strb((PE) parm, &i)) == NULL)
return oom(mod, p);
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
free(cp);
if ((pe = bit2prim(pe)) == NULLPE)
return oom(mod, p);
break;
case BITSTRING:
if ((cp = bitstr2strb(*(PE *) (parm + p->pe_ucode), &i))
== NULL)
return oom(mod, p);
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
free(cp);
if ((pe = bit2prim(pe)) == NULLPE)
return oom(mod, p);
break;
case SOBJID:
if ((pe = obj2prim((OID) (parm), CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
case OBJID:
if ((pe = obj2prim(*(OID *) (parm + p->pe_ucode), CLASS(p), TAG(p)))
== NULLPE)
return oom(mod, p);
break;
default:
return pepsylose (mod, p, NULLPE, "en_type: type not implemented");
}
if (ISDTYPE(p) && cnt++ > 0)
return pepsylose (mod, p, NULLPE, "en_type:compound type found");
if (ISDTYPE(p)) {
if (pe == NULLPE)
return pepsylose (mod, p, NULLPE,
"en_type: missing mandatory value");
}
if (ISDTYPE(p) && pe != NULLPE)
return (RET_OK(rpe, pe));
if (NEXT_TPE(p) == NULLTPE)
goto bad;
}
return (RET_OK(rpe, pe));
bad:
return (NOTOK);
}
/*
* Build a sequence, calling appropriate routines to build each sub
* type
*/
static int
en_seq(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
PE head;
PE pe = NULLPE;
tpe *tmp; /* first entry in list */
int *popt = NULL; /* Pointer to optional field */
int optcnt = 0; /* Number of optionals bits so far */
int val;
if (p->pe_type != SEQ_START)
return (pepsylose (mod, p, pe, "en_seq: missing SEQ_START\n"));
if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
return oom (mod, p);
p++;
while (p->pe_type != PE_END) {
DLOG (psap_log, LLOG_DEBUG, ("en_seq type%d", p->pe_type));
if (ISDTYPE(p) && OPTIONAL(p)) {
switch (p->pe_type) {
case INTEGER:
case REALTYPE:
case BOOLEAN:
case T_NULL:
if (!TESTBIT(*popt, optcnt++))
goto next; /* Missing so skip */
break;
case ETAG:
if ((val = hasdata(parm, p + 1, mod, popt, optcnt)) == NOTOK)
goto bad;
if (val == 0)
goto next;
break;
case IMP_OBJ:
if (p[1].pe_type == SOBJECT && parm == NULL
|| *((char **) (parm + p[1].pe_ucode)) == NULL)
goto next;
break;
case SOBJECT:
if (((char *) parm) == NULL)
goto next;
break;
default:
if (*((char **) (parm + p->pe_ucode)) == NULL)
goto next;
break;
}
}
switch (p->pe_type) {
case OPTL:
popt = (int *) (parm + p->pe_ucode);
break;
case UCODE:
break;
case ETAG:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQ_START:
if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQOF_START:
if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SET_START:
if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SETOF_START:
if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
} else if (p->pe_type == SOBJECT) {
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1, mod,
&pe) == NOTOK)
goto bad;
} else
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1, mod, &pe)
== NOTOK)
goto bad;
break;
case OBJECT:
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case CHOICE_START:
if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, &p[1], NULLPE, "en_seq: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
(char *) parm) == NOTOK)
return (NOTOK);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, &p[1], NULLPE, "en_seq: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
*(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
break;
default:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
}
if (ISDTYPE(p) && pe != NULLPE) {
if (seq_add(head, pe, -1) == NOTOK)
return pepsylose (mod, p, NULLPE, "en_seq bad sequence: %s",
pe_error(pe->pe_errno));
}
next:
if (NEXT_TPE(p) == NULLTPE)
return (NOTOK);
}
return (RET_OK(rpe, head));
bad:
return (NOTOK);
}
/*
* Parse a set, calling appropriate routines to parse each sub type
*/
static int
en_set(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
PE head;
PE pe = NULLPE;
tpe *tmp;
int *popt = NULL; /* Pointer to optional field */
int optcnt = 0; /* Number of optionals bits so far */
int val;
if (p->pe_type != SET_START)
return pepsylose (mod, p, pe, "en_set: missing SET_START");
if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
return oom(mod, p);
p++;
while (p->pe_type != PE_END) {
DLOG (psap_log, LLOG_DEBUG, ("en_set type %d", p->pe_type));
if (ISDTYPE(p) && OPTIONAL(p)) {
switch (p->pe_type) {
case INTEGER:
case REALTYPE:
case BOOLEAN:
case T_NULL:
if (!TESTBIT(*popt, optcnt++))
goto next; /* Missing so skip */
break;
case ETAG:
if ((val = hasdata(parm, p + 1, mod, popt, optcnt)) == NOTOK)
goto bad;
if (val == 0)
goto next;
break;
case IMP_OBJ:
if (p[1].pe_type == SOBJECT && parm == NULL
|| *((char **) (parm + p[1].pe_ucode)) == NULL)
goto next;
break;
case SOBJECT:
if (((char *) parm) == NULL)
goto next;
break;
default:
if (*((char **) (parm + p->pe_ucode)) == NULL)
goto next;
break;
}
}
switch (p->pe_type) {
case OPTL:
popt = (int *) (parm + p->pe_ucode);
break;
case UCODE:
break;
case ETAG:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQ_START:
if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQOF_START:
if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SET_START:
if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SETOF_START:
if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
} else if (p->pe_type == SOBJECT) {
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1, mod,
&pe) == NOTOK)
goto bad;
} else
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
if (en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case OBJECT:
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case CHOICE_START:
if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) ==NOTOK)
goto bad;
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p, "en_set: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
parm) == NOTOK)
return (NOTOK);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p, "en_set: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
*(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
break;
default:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
}
if (ISDTYPE(p) && pe != NULLPE) {
if (set_add(head, pe) == NOTOK)
return pepsylose (mod, p, NULLPE, "en_set bad set: %s",
pe_error(pe->pe_errno));
}
next:
NEXT_TPE(p);
}
return (RET_OK(rpe, head));
bad:
return (NOTOK);
}
/*
* Parse a sequence of calling appropriate routines to parse each sub
* type
*/
static int
en_seqof(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
PE head;
PE pe = NULLPE;
tpe *start; /* first entry in list */
tpe *tmp;
if (p->pe_type != SEQOF_START)
return pepsylose (mod, p, NULLPE, "en_seqof: missing SEQOF_START");
if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
return oom(mod, p);
start = p;
while ((char *) parm != NULL) {
p++;
while (p->pe_type != PE_END) {
DLOG (psap_log, LLOG_DEBUG, ("en_seqof type%d", p->pe_type));
switch (p->pe_type) {
case UCODE:
break;
case ETAG:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQ_START:
if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
goto bad;
break;
case SEQOF_START:
if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
== NOTOK)
goto bad;
break;
case SET_START:
if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
goto bad;
break;
case SETOF_START:
if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
== NOTOK)
goto bad;
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
} else if (p->pe_type == SOBJECT) {
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod, &pe) == NOTOK)
goto bad;
} else if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
if (en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod, &pe) ==NOTOK)
goto bad;
break;
case OBJECT:
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case CHOICE_START:
if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe)
== NOTOK)
goto bad;
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p+1, NULLPE,
"en_seqof: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
parm) == NOTOK)
return (NOTOK);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p+1, NULLPE,
"en_seqof: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
*(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
break;
default:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
}
if (ISDTYPE(p) && pe != NULLPE) {
if (seq_add(head, pe, -1) == NOTOK)
return pepsylose (mod, p, NULLPE,
"en_seqof bad sequence: %s",
pe_error(pe->pe_errno));
}
if (NEXT_TPE(p) == NULLTPE)
goto bad;
}
parm = *(char **) (parm + p->pe_ucode); /* Any more ? */
p = start;
}
return (RET_OK(rpe, head));
bad:
return (NOTOK);
}
/*
* Parse a setof, calling appropriate routines to parse each sub type
*/
static int
en_setof(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
PE head;
PE pe = NULLPE, last = NULLPE;
tpe *start;
tpe *tmp;
if (p->pe_type != SETOF_START)
return pepsylose (mod, p, NULLPE, "en_setof: missing SETOF_START");
if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
return oom(mod,p);
start = p;
while ((char *) parm != NULL) {
p++;
while (p->pe_type != PE_END) {
DLOG (psap_log, LLOG_DEBUG, ("en_setof type%d",
p->pe_type));
switch (p->pe_type) {
case UCODE:
break;
case ETAG:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQ_START:
if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
goto bad;
break;
case SEQOF_START:
if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
== NOTOK)
goto bad;
break;
case SET_START:
if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
goto bad;
break;
case SETOF_START:
if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
== NOTOK)
goto bad;
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
} else if (p->pe_type == SOBJECT) {
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod, &pe) == NOTOK)
goto bad;
} else
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
if (en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod, &pe) ==NOTOK)
goto bad;
break;
case OBJECT:
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case CHOICE_START:
if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe)
== NOTOK)
goto bad;
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p + 1, NULLPE,
"en_setof: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
parm) == NOTOK)
return (NOTOK);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p + 1, NULLPE,
"en_setof: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
*(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
break;
default:
if (en_type(parm, p, mod, &pe) == NOTOK)
goto bad;
break;
}
if (ISDTYPE(p) && pe != NULLPE) {
if (set_addon(head, last, pe) == NOTOK)
return pepsylose (mod, p, NULLPE, "en_setof bad set: %s",
pe_error(pe->pe_errno));
else
last = pe;
}
if (NEXT_TPE(p) == NULLTPE)
goto bad;;
}
parm = *(char **) (parm + p->pe_ucode); /* Any more ? */
p = start;
}
return (RET_OK(rpe, head));
bad:
return (NOTOK);
}
/*
* encode a choice field. This means find which choice is taken and
* call en_type to encode it
*/
static int
en_choice(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
int cnt;
if (p->pe_type != CHOICE_START)
return pepsylose (mod, p, NULLPE, "en_choice:missing CHOICE_START");
p++;
if (p->pe_type != SCTRL)
return pepsylose (mod, p, NULLPE, "en_choice:missing SCTRL");
cnt = *(int *) (parm + p->pe_ucode);
DLOG (psap_log, LLOG_DEBUG, ("cnt %d", cnt));
if (cnt != 0)
cnt--;
if (cnt < 0)
return pepsylose (mod, p, NULLPE, "en_choice:offset %d negative", cnt);
for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
if (ISDTYPE(p)) {
if (cnt == 0) {
if (en_etype(parm, p, mod, rpe) == NOTOK)
return (NOTOK);
return (OK);
}
cnt--;
}
}
return pepsylose (mod, p, NULLPE, "en_choice: no choice taken");
}
/*
* check to see if the object is present or not
*/
static int
chkobj(mod, p, head)
modtyp *mod;
tpe *p;
PE head;
{
for (; p->pe_type != PE_END; NEXT_TPE(p)) {
if (!ISDTYPE(p))
continue;
if (p->pe_type == OBJECT) {
if (chkobj(mod, p, head))
return (1);
} else if (CHKTAG(mod, p, head))
return (1);
if (OPTIONAL(p) || DEFAULT(p))
continue;
return (0);
}
return (0);
}
#if 0
/*
* print the PE structure pointed to by pe
*/
print_pe(pe, n)
PE pe;
int n;
{
if (pe == NULL)
return;
(void) printf("%*s", 4 * n, "");
#if 0
(void) printf("error = %d, context = %x, class = %x, form = %x, id = %x\n",
pe->pe_errno, pe->pe_context, pe->pe_class, pe->pe_form, pe->pe_id);
#endif
if (pe->pe_errno)
(void) printf(" errno = %d", pe->pe_errno);
if (pe->pe_class == PE_CLASS_UNIV)
(void) printf(" %s", idname( (int )pe->pe_id));
else if (pe->pe_class == PE_CLASS_CONT)
(void) printf("[%d]", pe->pe_id);
else
(void) printf("[%s %d]", clname( (int )pe->pe_class), pe->pe_id);
(void) printf("\n");
#if 0
(void) printf("%*s", 4 * n, "");
(void) printf("cardinality = %d offset = %d\n", pe->pe_cardinal, pe->pe_offset);
#endif
if (pe->pe_form != 0x0) {
if (pe->pe_cons != NULLPE)
print_pe(pe->pe_cons, n + 1);
} else {
(void) printf("%*s", 4 * n, "");
switch (pe->pe_id) {
case PE_PRIM_BOOL:
(void) printf("%d", prim2flag(pe));
break;
case PE_PRIM_INT:
(void) printf(" %d", prim2num(pe));
break;
case PE_PRIM_BITS:
prntbits(pe);
break;
case PE_PRIM_OCTS:
(void) prntos(pe);
break;
case PE_PRIM_NULL:
break;
case PE_DEFN_NUMS:
case PE_DEFN_PRTS:
case PE_DEFN_T61S:
case PE_DEFN_VTXS:
case PE_DEFN_IA5S:
case PE_DEFN_GFXS:
case PE_DEFN_VISS:
case PE_DEFN_GENS:
case PE_DEFN_CHRS:
(void) prntstr(pe);
break;
case PE_PRIM_OID:
case PE_CONS_EXTN:
case PE_PRIM_REAL:
case PE_PRIM_ENUM:
case PE_PRIM_ENCR:
case PE_CONS_SEQ:
case PE_CONS_SET:
case PE_DEFN_UTCT:
case PE_DEFN_GENT:
default:
(void) printf("Unimplemented %d ", pe->pe_id);
break;
}
(void) printf("\n");
}
if (pe->pe_next != NULLPE) {
(void) printf("%*s", 4 * n, "pe_next:\n");
print_pe(pe->pe_next, n);
}
}
/*
* return the string describing that class
*/
static char *
clname(cl)
int cl;
{
char *p;
static char buf[30];
switch (cl) {
case PE_CLASS_UNIV:
p = "Universal";
break;
case PE_CLASS_APPL:
p = "Application";
break;
case PE_CLASS_CONT:
p = "Context";
break;
case PE_CLASS_PRIV:
p = "Private";
break;
default:
(void) sprintf(buf, "Unknown Class %d", cl);
p = buf;
break;
}
return (p);
}
/*
* return the string describing that identity or the number itself
* Assuming a Universal class
*/
static char *
idname(id)
int id;
{
char *p;
static char buf[40];
switch (id) {
case PE_PRIM_BOOL:
p = "Boolean";
break;
case PE_PRIM_INT:
p = "Integer";
break;
case PE_PRIM_BITS:
p = "Bit String";
break;
case PE_PRIM_OCTS:
p = "Octet String";
break;
case PE_PRIM_NULL:
p = "Null";
break;
case PE_PRIM_OID:
p = "Object Descriptor";
break;
case PE_CONS_EXTN:
p = "External";
break;
case PE_PRIM_REAL:
p = "Real";
break;
case PE_PRIM_ENUM:
p = "Enumerated Type";
break;
case PE_PRIM_ENCR:
p = "Encrypted Type";
break;
case PE_CONS_SEQ:
p = "Sequence";
break;
case PE_CONS_SET:
p = "Set";
break;
case PE_DEFN_NUMS:
p = "Numeric String";
break;
case PE_DEFN_PRTS:
p = "Printable String";
break;
case PE_DEFN_T61S:
p = "T.61 String";
break;
case PE_DEFN_VTXS:
p = "Videotex String";
break;
case PE_DEFN_IA5S:
p = "IA5 String";
break;
case PE_DEFN_UTCT:
p = "UTC Time";
break;
case PE_DEFN_GENT:
p = "Generalised Time";
break;
case PE_DEFN_GFXS:
p = "Graphics String";
break;
case PE_DEFN_VISS:
p = "Visable String";
break;
case PE_DEFN_GENS:
p = "General String";
break;
case PE_DEFN_CHRS:
p = "Character String";
break;
default:
(void) sprintf(buf, "Unknown Universal %d", id);
p = buf;
break;
}
return (p);
}
#endif
/*
* Encode a single type for an explicit tag field If a basic type
* encode it, if a compound type call the appropriate encoding
* routine. Similar to en_type except we do the indirection on the
* ucode field
*/
static int
en_etype(parm, p, mod, rpe)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
PE *rpe; /* Return value PE */
{
tpe *tmp;
PE pe = NULLPE;
switch (p->pe_type) {
case PE_END:
case PE_START:
return (pepsylose (mod, p, pe, "en_etype:END/START type"));
case UCODE:
break;
case ETAG:
if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
return oom(mod, p);
switch (p->pe_ucode) {
default:
p++;
if (en_etype(parm, p, mod, &pe->pe_cons) == NOTOK)
goto bad;
}
break;
case SEQ_START:
if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SEQOF_START:
if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SET_START:
if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case SETOF_START:
if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
} else if (p->pe_type == SOBJECT) {
if (en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1, mod, &pe)
== NOTOK)
goto bad;
} else
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
if (en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case OBJECT:
if (en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
goto bad;
break;
case CHOICE_START:
if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
goto bad;
break;
case INTEGER:
DLOG (psap_log, LLOG_DEBUG, ("offset %d value %d",
p->pe_ucode,
*(int *) (parm + p->pe_ucode)));
if ((pe = num2prim(*(int *) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
return oom (mod, p);
break;
#ifdef PEPSY_REALS
case REALTYPE:
DLOG (psap_log, LLOG_DEBUG, ("offset %d value %g",
p->pe_ucode,
*(double *) (parm + p->pe_ucode)));
if ((pe = real2prim(*(double *) (parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
#endif
case BOOLEAN:
DLOG (psap_log, LLOG_DEBUG, ("offset %d value %d",
p->pe_ucode,
*(char *) (parm + p->pe_ucode)));
if ((pe = flag2prim(*(char *) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
case T_NULL:
DLOG (psap_log, LLOG_DEBUG, ("offset %d", p->pe_ucode));
if ((pe = pe_alloc(CLASS(p), PE_FORM_PRIM, TAG(p))) == NULLPE)
return oom(mod, p);
break;
case SANY:
(pe = (PE) parm)->pe_refcnt++;
break;
case ANY:
if ((parm + p->pe_ucode) == 0 || *(PE *) (parm + p->pe_ucode) == 0)
#if ROSAP_HACK
/* hack for ROSAP. expects this strangeness */
pe = pe_alloc(PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL);
#else
pe = NULLPE;
#endif
else
(pe = *(PE *) (parm + p->pe_ucode))->pe_refcnt++;
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p+1, NULLPE, "en_etype: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
parm) == NOTOK)
return (NOTOK);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD)
return pepsylose (mod, p+1, NULLPE, "en_etype: missing EXTMOD");
if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
*(char **) (parm + p->pe_ucode)) == NOTOK)
return (NOTOK);
break;
case SOCTETSTRING:
if ((pe = qb2prim((struct qbuf *) parm, CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
case SBITSTRING:
{
char *cp;
int i;
if ((cp = bitstr2strb((PE) parm, &i)) == NULL)
return oom(mod, p);
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
free(cp);
}
break;
case OCTETSTRING:
if ((pe = qb2prim(*(struct qbuf **) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
case BITSTRING:
{
char *cp;
int i;
if ((cp = bitstr2strb(*(PE *) (parm + p->pe_ucode), &i)) == NULL)
return oom(mod, p);
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
free(cp);
}
break;
case SOBJID:
if ((pe = obj2prim((OID) (parm), CLASS(p), TAG(p))) == NULLPE)
return oom(mod, p);
break;
case OBJID:
if ((pe = obj2prim(*(OID *) (parm + p->pe_ucode), CLASS(p), TAG(p)))
== NULLPE)
return oom(mod, p);
break;
default:
return pepsylose (mod, p, NULLPE, "en_etype: type not implemented");
}
return (RET_OK(rpe, pe));
bad:
return (NOTOK);
}
#if 0
/*
* Print out the value of a bits string
*/
static prntbits(pe)
PE pe;
{
int len, i;
if ((len = pe->pe_nbits) < 0) {
(void) printf("prntbits:Bad bistring\n");
return;
}
(void) printf("Bits:");
for (i = 0; i < len; i++)
if (bit_test(pe, i))
(void) printf(" %d", i);
(void) putchar('\n');
}
/*
* Dump a bunch of hex digits printing out those that are printable
* Print out a given length of octets as hex (with the ASCII
* characters given if they have any
*/
static pclen(s, len)
register char *s;
register int len;
{
register int cnt = 0;
while (len-- > 0) {
if (cnt % 8 == 0)
(void) printf("\n%d:", cnt / 8 + 1);
if (isprint(*s & 0x7f))
(void) printf("\t%02x(%c)", *s & 0xff, *s & 0x7f);
else
(void) printf("\t%02x", *s & 0xff);
s++;
cnt++;
}
(void) putchar('\n');
}
/*
* print out an octet string
*/
static prntos(pe)
PE pe;
{
struct qbuf *qb;
if ((qb = prim2qb(pe)) == NULL) {
bad:
(void) printf("prntos:bad octet string\n");
return (NOTOK);
}
if (qb_pullup(qb) == NOTOK)
goto bad;
if (qb->qb_forw->qb_data == NULL || qb->qb_forw->qb_len < 0)
goto bad;
pclen(qb->qb_forw->qb_data, qb->qb_forw->qb_len);
return (OK);
}
/*
* print out a string which should be printable
*/
static prntstr(pe)
PE pe;
{
struct qbuf *qb;
if ((qb = prim2qb(pe)) == NULL) {
bad:
(void) printf("prntstr:bad string\n");
return (NOTOK);
}
if (qb_pullup(qb) == NOTOK)
goto bad;
if (qb->qb_forw->qb_data == NULL || qb->qb_forw->qb_len < 0)
goto bad;
(void) printf("\"%s\"", qb->qb_forw->qb_data);
return (OK);
}
#endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.