|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T e
Length: 39567 (0x9a8f)
Types: TextFile
Names: »enc.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦041b9c0f8⟧ »EurOpenD22/isode/pepsy.system-6.0.Z«
└─⟦d49939f05⟧
└─⟦6a28ec38e⟧ »pepsy.tar«
└─⟦this⟧ »pepsy/enc.c«
/* Copyright 1989 CSIRO Division of Information Technology
* May be given away but not sold for profit - See Copyright file for details
*/
/*
* These routines are the driving routines for parsing encoding and printing
* data
*/
#include <stdio.h>
#include <ctype.h>
#include "../h/psap.h"
#include "pep.h"
#include "pepdefs.h"
#ifndef PEPYPARM
#define PEPYPARM char *
#endif
extern PE pr_seq(), pr_seqof(), pr_set(), pr_setof(), pr_type();
extern PE en_seq(), en_seqof(), en_set(), en_setof(), en_type();
extern PE pr_choice(), en_choice(), en_etype(), pr_etype(), en_obj();
extern tpe *next_tpe();
extern int _pverbose;
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)
/*
* 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;
PEPYPARM parm;
{
register tpe *p;
if (typ < 0 || typ >= mod->md_nentries)
ferrd(1, "enc_f:Illegal typ %d\n", typ);
p = mod->md_etab[typ];
if (p->pe_type != PE_START)
ferr(1, "enc_f: missing PE_START\n");
p++;
if (((*pe) = en_obj(parm, p, mod)) == NULLPE)
return (NOTOK);
return (OK);
}
/*
* 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.
*/
PE
en_obj(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
PE pe;
int cnt = 0;
tpe *tmp;
if (_pverbose > 5)
printf("Encoding the type %d\n", p->pe_type);
while (p->pe_type != PE_END) {
switch (p->pe_type) {
case PE_END:
case PE_START:
return (NULLPE);
case UCODE:
break;
case ETAG:
if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE) {
printf("en_obj: out of memory");
return NULLPE;
}
switch (p->pe_ucode) {
default:
p++;
pe->pe_cons = en_obj(parm, p, mod);
}
break;
case SEQ_START:
pe = en_seq(parm, p, mod);
break;
case SEQOF_START:
pe = en_seqof(parm, p, mod);
break;
case SET_START:
pe = en_set(parm, p, mod);
break;
case SETOF_START:
pe = en_setof(parm, p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, (parm));
else
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
break;
case OBJECT:
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(parm, p, mod);
break;
default:
pe = en_type(parm, p, mod);
break;
}
if (ISDTYPE(p) && cnt++ > 0) {
dmp_tpe("en_obj:compound type found", p, mod);
ferr(1, "en_obj:compound type found\n");
}
if (ISDTYPE(p)) {
if (pe == NULLPE) {
dmp_tpe("en_obj: missing mandatory value", p, mod);
ferrd(1, "en_obj: %d missing mandatory value\n",
p->pe_type);
}
}
if (ISDTYPE(p) && pe != NULLPE)
return (pe);
/*SUPPRESS 288*/
next:
NEXT_TPE(p);
}
return (pe);
}
/*
* Encode a single type.
* If a basic type encode it, if a compound type call the appropriate
* encoding routine
*/
PE
en_type(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
PE pe;
int cnt = 0;
int i; /* Integer for encoding type */
tpe *tmp;
char *cp;
if (_pverbose > 5)
printf("Encoding the type %d\n", p->pe_type);
while (p->pe_type != PE_END) {
switch (p->pe_type) {
case PE_END:
case PE_START:
return (NULLPE);
case DFLT_F:
p++;
if (same(p, p - 1, parm, mod)) {
return (NULLPE); /* don't encode it */
}
continue;
case UCODE:
break;
case ETAG:
if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE) {
printf("en_type: out of memory");
return NULLPE;
}
switch (p->pe_ucode) {
default:
p++;
pe->pe_cons = en_etype(parm, p, mod);
}
break;
#if 0
case SEQ_START:
pe = en_seq(parm + p->pe_ucode, p, mod);
break;
case SEQOF_START:
pe = en_seqof(parm + p->pe_ucode, p, mod);
break;
case SET_START:
pe = en_set(parm + p->pe_ucode, p, mod);
break;
case SETOF_START:
pe = en_setof(parm + p->pe_ucode, p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, (parm + p->pe_ucode));
else if (p->pe_type == SOBJECT) {
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod);
} else
pe = en_obj(parm + p->pe_ucode,
mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
break;
case OBJECT:
pe = en_obj(parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(parm + p->pe_ucode, p, mod);
break;
#endif
#if 1
case SEQ_START:
pe = en_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
pe = en_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SET_START:
pe = en_set(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SETOF_START:
pe = en_setof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, *(char **) (parm + p->pe_ucode));
else if (p->pe_type == SOBJECT) {
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod);
} else
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag]+1, mod);
break;
case OBJECT:
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_seq: missing EXTMOD", p, mod);
ferr(1, "en_seq:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
(char *) parm);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_seq: missing EXTMOD", p, mod);
ferr(1, "en_seq:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
*(char **) (parm + p->pe_ucode));
break;
#endif
case INTEGER:
if (_pverbose > 5) {
printf("offset is %d\n",p->pe_ucode);
printf("value is %d\n", *(int *)(parm + p->pe_ucode));
}
if ((pe = num2prim(*(int *)(parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE) {
printf("en_type:out of memory");
return (NULLPE);
}
break;
case BOOLEAN:
if (_pverbose > 5) {
printf("offset is %d\n",p->pe_ucode);
printf("value is %d\n", *(char *)(parm + p->pe_ucode));
}
if ((pe = flag2prim(*(char *)(parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE) {
printf("en_type:out of memory");
return (NULLPE);
}
break;
case T_NULL:
if (_pverbose > 5)
printf("offset is %d\n",p->pe_ucode);
if ((pe = pe_alloc(CLASS(p), PE_FORM_PRIM,
TAG(p))) == NULLPE) {
printf("en_type:out of memory");
return (NULLPE);
}
break;
case SCONS_ANY:
case SANY:
(pe = (PE ) parm) -> pe_refcnt++;
break;
case CONS_ANY:
(pe = *(PE *) (parm + p->pe_ucode)) -> pe_refcnt++;
break;
case ANY:
(pe = *(PE *) (parm + p->pe_ucode)) -> pe_refcnt++;
break;
#if 0
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_type: missing EXTMOD", p, mod);
ferr(1, "en_type:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL, parm);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_type: missing EXTMOD", p, mod);
ferr(1, "en_type:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL, parm + p->pe_ucode);
break;
#endif
case SOCTETSTRING:
if ((pe = qb2prim((struct qbuf *)parm, CLASS(p), TAG(p)))
== NULLPE) {
printf("en_type:SOCTETSTRING: out of memory");
return (NULLPE);
}
break;
case OCTETSTRING:
if ((pe = qb2prim(*(struct qbuf **)(parm + p->pe_ucode),
CLASS(p), TAG(p))) == NULLPE) {
printf("en_type:OCTETSTRING: out of memory");
return (NULLPE);
}
break;
case SBITSTRING:
if ((cp = bitstr2strb((PE )parm, &i)) == NULL) {
printf("en_type:SBIT STRING: out of memory");
return (NULLPE);
}
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE) {
printf("en_type:SBIT STRING: out of memory");
return (NULLPE);
}
free(cp);
if ((pe = bit2prim(pe)) == NULLPE) {
printf("en_type:SBIT STRING:bit2prim: out of memory");
return (NULLPE);
}
break;
case BITSTRING:
if ((cp = bitstr2strb(*(PE *)(parm + p->pe_ucode), &i))
== NULL) {
printf("en_type:BIT STRING: out of memory");
return (NULLPE);
}
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE) {
printf("en_type:BIT STRING: out of memory");
return (NULLPE);
}
free(cp);
if ((pe = bit2prim(pe)) == NULLPE) {
printf("en_type:BIT STRING:bit2prim: out of memory");
return (NULLPE);
}
break;
case SOBJID:
if ((pe = obj2prim((OID )(parm), CLASS(p), TAG(p))) == NULLPE) {
printf("en_type:Object Identifier: out of memory");
return (NULLPE);
}
break;
case OBJID:
if ((pe = obj2prim(*(OID *)(parm + p->pe_ucode), CLASS(p), TAG(p)))
== NULLPE) {
printf("en_type:Object Identifier: out of memory");
return (NULLPE);
}
break;
default:
dmp_tpe("en_type: type not implemented", p, mod);
ferrd(1, "en_type: %d not implemented\n", p->pe_type);
break;
}
if (ISDTYPE(p) && cnt++ > 0) {
dmp_tpe("en_type:compound type found", p, mod);
ferr(1, "en_type:compound type found\n");
}
if (ISDTYPE(p)) {
if (pe == NULLPE) {
dmp_tpe("en_type: missing mandatory value", p, mod);
ferrd(1, "en_type: %d missing mandatory value\n",
p->pe_type);
}
}
if (ISDTYPE(p) && pe != NULLPE)
return (pe);
/*SUPPRESS 288*/
next:
NEXT_TPE(p);
}
return (pe);
}
/*
* Build a sequence, calling appropriate routines to build each sub type
*/
PE
en_seq(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
PE head;
PE pe;
tpe *tmp; /* first entry in list */
int *popt = NULL; /* Pointer to optional field */
int optcnt = 0; /* Number of optionals bits so far */
if (p->pe_type != SEQ_START)
ferr(1, "en_seq: missing SEQ_START\n");
if ((head = pe_alloc (CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE) {
printf("en_type: out of memory");
return (NULLPE);
}
p++;
while (p->pe_type != PE_END) {
if (_pverbose > 5)
printf("en_seq with the type%d\n",p->pe_type);
if (ISDTYPE(p) && OPTIONAL(p)) {
switch (p->pe_type) {
case INTEGER:
case BOOLEAN:
case T_NULL:
if (!TESTBIT(*popt, optcnt++))
goto next; /* Missing so skip */
break;
case ETAG:
if (!hasdata(parm, p + 1, mod, popt, optcnt))
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:
pe = en_type(parm, p, mod);
break;
case SEQ_START:
pe = en_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
pe = en_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SET_START:
pe = en_set(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SETOF_START:
pe = en_setof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, *(char **) (parm + p->pe_ucode));
else if (p->pe_type == SOBJECT) {
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod);
} else
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag]+1, mod);
break;
case OBJECT:
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_seq: missing EXTMOD", p, mod);
ferr(1, "en_seq:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
(char *) parm);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_seq: missing EXTMOD", p, mod);
ferr(1, "en_seq:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
*(char **) (parm + p->pe_ucode));
break;
default:
pe = en_type(parm, p, mod);
break;
/*
ferrd(1, "en_seq: unknown type %d\n", p->pe_type);
*/
}
if (_pverbose > 5) {
print_pe(pe, 1);
printf("\n\n");
}
if (ISDTYPE(p) && pe != NULLPE) {
if (seq_add (head, pe, -1) == NOTOK) {
printf("en_seq bad sequence: %s",
pe_error (pe -> pe_errno));
return (NULLPE);
}
if (_pverbose > 7) {
print_pe(head, 1);
printf("\n\n");
}
}
next:
NEXT_TPE(p);
}
return (head);
}
/*
* Parse a set, calling appropriate routines to parse each sub type
*/
PE
en_set(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
PE head;
PE pe;
tpe *tmp;
int *popt = NULL; /* Pointer to optional field */
int optcnt = 0; /* Number of optionals bits so far */
if (p->pe_type != SET_START)
ferr(1, "en_set: missing SET_START\n");
if ((head = pe_alloc (CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE) {
printf("en_set: out of memory");
return (NULLPE);
}
p++;
while (p->pe_type != PE_END) {
if (_pverbose > 5)
printf("en_set with the type%d\n",p->pe_type);
if (ISDTYPE(p) && OPTIONAL(p)) {
switch (p->pe_type) {
case INTEGER:
case BOOLEAN:
case T_NULL:
if (!TESTBIT(*popt, optcnt++))
goto next; /* Missing so skip */
break;
case ETAG:
if (!hasdata(parm, p + 1, mod, popt, optcnt))
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:
pe = en_type(parm, p, mod);
break;
case SEQ_START:
pe = en_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
pe = en_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SET_START:
pe = en_set(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SETOF_START:
pe = en_setof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, *(char **) (parm + p->pe_ucode));
else if (p->pe_type == SOBJECT) {
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod);
} else
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
break;
case OBJECT:
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_set: missing EXTMOD", p, mod);
ferr(1, "en_set:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
parm);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_set: missing EXTMOD", p, mod);
ferr(1, "en_set:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
*(char **) (parm + p->pe_ucode));
break;
default:
pe = en_type(parm, p, mod);
break;
/*
ferrd(1, "en_set: unknown type %d\n", p->pe_type);
*/
}
if (_pverbose > 5) {
print_pe(pe, 1);
printf("\n\n");
}
if (ISDTYPE(p) && pe != NULLPE) {
if (set_add (head, pe) == NOTOK) {
printf("en_set bad set: %s",
pe_error (pe -> pe_errno));
return (NULLPE);
}
}
if (_pverbose > 7) {
print_pe(head, 1);
printf("\n\n");
}
next:
NEXT_TPE(p);
}
return (head);
}
/*
* Parse a sequence of calling appropriate routines to parse each sub type
*/
PE
en_seqof(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
PE head;
PE pe;
tpe *start; /* first entry in list */
tpe *tmp;
if (p->pe_type != SEQOF_START) {
dmp_tpe("en_seqof: missing SEQOF_START", p, mod);
ferr(1, "en_seqof: missing SEQOF_START\n");
}
if ((head = pe_alloc (CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE) {
printf("en_type: out of memory");
return (NULLPE);
}
start = p;
while ((char *)parm != NULL) {
p++;
while (p->pe_type != PE_END) {
if (_pverbose > 5)
printf("en_seqof with the type%d\n",p->pe_type);
switch (p->pe_type) {
case UCODE:
break;
case ETAG:
pe = en_type(parm, p, mod);
break;
case SEQ_START:
pe = en_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
pe = en_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SET_START:
pe = en_set(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SETOF_START:
pe = en_setof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, *(char **) (parm + p->pe_ucode));
else if (p->pe_type == SOBJECT) {
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod);
} else
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
break;
case OBJECT:
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_seqof: missing EXTMOD", p, mod);
ferr(1, "en_seqof:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
parm);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_seqof: missing EXTMOD", p, mod);
ferr(1, "en_seqof:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
*(char **) (parm + p->pe_ucode));
break;
default:
pe = en_type(parm, p, mod);
break;
/*
ferrd(1, "en_seqof: unknown type %d\n", p->pe_type);
*/
}
if (_pverbose > 5) {
print_pe(pe, 1);
printf("\n\n");
}
if (ISDTYPE(p) && pe != NULLPE) {
if (seq_add (head, pe, -1) == NOTOK) {
printf("en_seqof bad sequence: %s",
pe_error (pe -> pe_errno));
return (NULLPE);
}
}
if (_pverbose > 7) {
print_pe(head, 1);
printf("\n\n");
}
/*SUPPRESS 288*/
next:
NEXT_TPE(p);
}
parm = *(char **)(parm + p->pe_ucode); /* Any more ? */
p = start;
}
return (head);
}
/*
* Parse a setof, calling appropriate routines to parse each sub type
*/
PE
en_setof(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
PE head;
PE pe, last = NULLPE;
tpe *start;
tpe *tmp;
if (p->pe_type != SETOF_START) {
dmp_tpe("en_setof: missing SETOF_START", p, mod);
ferr(1, "en_setof: missing SETOF_START\n");
}
if ((head = pe_alloc (CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE) {
printf("en_type: out of memory");
return (NULLPE);
}
#if 0
p++;
if (p->pe_type != SCTRL)
ferr(1, "en_setof: missing SCTRL information\n");
if (p->pe_tag != 0)
ferr(1, "en_setof: tag field != 0\n");
#endif
start = p;
while ((char *)parm != NULL) {
p++;
while (p->pe_type != PE_END) {
if (_pverbose > 5)
printf("en_setof with the type%d\n", p->pe_type);
switch (p->pe_type) {
case UCODE:
break;
case ETAG:
pe = en_type(parm, p, mod);
break;
case SEQ_START:
pe = en_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
pe = en_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SET_START:
pe = en_set(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SETOF_START:
pe = en_setof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, *(char **) (parm + p->pe_ucode));
else if (p->pe_type == SOBJECT) {
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod);
} else
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
break;
case OBJECT:
pe = en_obj(*(char **) (parm + p->pe_ucode), mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_setof: missing EXTMOD", p, mod);
ferr(1, "en_setof:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
parm);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_setof: missing EXTMOD", p, mod);
ferr(1, "en_setof:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
*(char **) (parm + p->pe_ucode));
break;
default:
pe = en_type(parm, p, mod);
break;
/*
ferrd(1, "en_seq: unknown type %d\n", p->pe_type);
*/
}
if (_pverbose > 5) {
print_pe(pe, 1);
printf("\n\n");
}
if (ISDTYPE(p) && pe != NULLPE) {
if (set_addon (head, last, pe) == NOTOK) {
printf("en_setof bad set: %s",
pe_error (pe -> pe_errno));
return (NULLPE);
}
else
last = pe;
}
if (_pverbose > 7) {
print_pe(head, 1);
printf("\n\n");
}
/*SUPPRESS 288 */
next:
NEXT_TPE(p);
}
parm = *(char **)(parm + p->pe_ucode); /* Any more ? */
p = start;
}
return (head);
}
/*
* encode a choice field. This means find which choice is taken and call
* en_type to encode it
*/
PE
en_choice(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
int cnt;
if (p->pe_type != CHOICE_START) {
dmp_tpe("pr_choice:missing CHOICE_START", p, mod);
ferrd(1, "pr_choice:illegal table entry %d\n", p->pe_type);
}
p++;
if (p->pe_type != SCTRL) {
dmp_tpe("pr_choice:missing SCTRL", p, mod);
ferr(1, "en_choice: missing SCTRL information\n");
}
cnt = *(int *) (parm + p->pe_ucode);
if (_pverbose > 5)
printf("cnt is %d\n",cnt);
if (cnt != 0)
cnt--;
if (cnt < 0) {
dmp_tpe("en_choice:offset negative", p, mod);
return (NULLPE);
}
for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
if (ISDTYPE(p)) {
if (cnt == 0)
return(en_etype(parm, p, mod));
cnt--;
}
}
dmp_tpe("en_choice: no choice taken", p, mod);
return (NULLPE);
}
/*
* check to see if the object is present or not
*/
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);
}
/*
print the PE sructure pointed to by pe
*/
print_pe(pe, n)
PE pe;
int n;
{
if (pe == NULL)
return;
printf("%*s",4*n,"");
#if 0
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)
printf(" errno = %d", pe->pe_errno);
if (pe->pe_class == PE_CLASS_UNIV)
printf(" %s", idname(pe->pe_id));
else if (pe->pe_class == PE_CLASS_CONT)
printf("[%d]", pe->pe_id);
else
printf("[%s %d]", clname(pe->pe_class), pe->pe_id);
printf("\n");
#if 0
printf("%*s",4*n,"");
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 {
printf("%*s",4*n,"");
switch(pe->pe_id) {
case PE_PRIM_BOOL:
printf("%d", prim2flag(pe));
break;
case PE_PRIM_INT:
printf(" %d", prim2num(pe));
break;
case PE_PRIM_BITS:
prntbits(pe);
break;
case PE_PRIM_OCTS:
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:
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:
printf("UNimplemented %d ", pe->pe_id);
break;
}
printf("\n");
}
if (pe->pe_next != NULLPE) {
printf("%*s",4*n,"pe_next:\n");
print_pe(pe->pe_next,n);
}
}
/*
* return the string describing that class
*/
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:
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
*/
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:
sprintf(buf, "Unknown Universal %d", id);
p = buf;
break;
}
return (p);
}
/*
* 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
*/
PE
en_etype(parm, p, mod)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
tpe *tmp;
PE pe;
switch (p->pe_type) {
case PE_END:
case PE_START:
return (NULLPE);
case UCODE:
break;
case ETAG:
if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE) {
printf("en_etype: out of memory");
return NULLPE;
}
switch (p->pe_ucode) {
default:
p++;
pe->pe_cons = en_etype(parm, p, mod);
}
break;
case SEQ_START:
pe = en_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
pe = en_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SET_START:
pe = en_set(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SETOF_START:
pe = en_setof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
tmp = p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1,
NULL, NULL, *(char **) (parm + p->pe_ucode));
else if (p->pe_type == SOBJECT) {
pe = en_obj((char *) parm, mod->md_etab[p->pe_tag] + 1,
mod);
} else
pe = en_obj(*(char **) (parm + p->pe_ucode),
mod->md_etab[p->pe_tag] + 1, mod);
pe->pe_class = CLASS(tmp);
pe->pe_id = TAG(tmp);
break;
case SOBJECT:
pe = en_obj(parm, mod->md_etab[p->pe_tag] + 1, mod);
break;
case OBJECT:
pe = en_obj(*(char **) (parm + p->pe_ucode), mod->md_etab[p->pe_tag] + 1, mod);
break;
case CHOICE_START:
pe = en_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case INTEGER:
if (_pverbose > 5) {
printf("offset is %d\n",p->pe_ucode);
printf("value is %d\n", *(int *)(parm + p->pe_ucode));
}
if ((pe = num2prim(*(int *)(parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE) {
printf("en_etype:out of memory");
return (NULLPE);
}
break;
case BOOLEAN:
if (_pverbose > 5) {
printf("offset is %d\n",p->pe_ucode);
printf("value is %d\n", *(char *)(parm + p->pe_ucode));
}
if ((pe = flag2prim(*(char *)(parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE) {
printf("en_etype:out of memory");
return (NULLPE);
}
break;
case T_NULL:
if (_pverbose > 5)
printf("offset is %d\n",p->pe_ucode);
if ((pe = pe_alloc(CLASS(p), PE_FORM_PRIM, TAG(p))) == NULLPE) {
printf("en_etype:out of memory");
return (NULLPE);
}
break;
case SCONS_ANY:
case SANY:
(pe = (PE )parm) -> pe_refcnt++;
break;
case CONS_ANY:
case ANY:
(pe = *(PE *) (parm + p->pe_ucode)) -> pe_refcnt++;
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_etype: missing EXTMOD", p, mod);
ferr(1, "en_etype:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL, parm);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("en_etype: missing EXTMOD", p, mod);
ferr(1, "en_etype:internal error\n");
}
enc_f(p->pe_tag, (modtyp *)p[1].pe_ucode, &pe, 1, NULL, NULL,
*(char **) (parm + p->pe_ucode));
break;
case SOCTETSTRING:
if ((pe = qb2prim((struct qbuf *)parm, CLASS(p), TAG(p))) == NULLPE) {
printf("en_etype:SOCTETSTRING: out of memory");
return (NULLPE);
}
break;
case SBITSTRING:
{
char *cp;
int i;
if ((cp = bitstr2strb((PE ) parm, &i)) == NULL) {
printf("en_etype:SBIT STRING: out of memory");
return (NULLPE);
}
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE) {
printf("en_etype:SBIT STRING: out of memory");
return (NULLPE);
}
free(cp);
}
break;
case OCTETSTRING:
if ((pe = qb2prim(*(struct qbuf **)(parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE) {
printf("en_etype:OCTETSTRING: out of memory");
return (NULLPE);
}
break;
case BITSTRING:
{
char *cp;
int i;
if ((cp = bitstr2strb(*(PE *)(parm + p->pe_ucode), &i)) == NULL) {
printf("en_etype:BIT STRING: out of memory");
return (NULLPE);
}
if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE) {
printf("en_etype:BIT STRING: out of memory");
return (NULLPE);
}
free(cp);
}
break;
case SOBJID:
if ((pe = obj2prim((OID )(parm), CLASS(p), TAG(p))) == NULLPE) {
printf("en_etype:Object Identifier: out of memory");
return (NULLPE);
}
break;
case OBJID:
if ((pe = obj2prim(*(OID *)(parm + p->pe_ucode), CLASS(p), TAG(p)))
== NULLPE) {
printf("en_etype:Object Identifier: out of memory");
return (NULLPE);
}
break;
default:
dmp_tpe("en_etype: type not implemented", p, mod);
ferrd(1, "en_etype: %d not implemented\n", p->pe_type);
break;
}
return (pe);
}
/*
* Print out the value of a bits string
*/
prntbits(pe)
PE pe;
{
int len, i;
if ((len = pe->pe_nbits) < 0) {
printf("prntbits:Bad bistring\n");
return;
}
printf("Bits:");
for (i = 0; i < len; i++)
if (bit_test(pe, i))
printf(" %d", i);
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
*/
pclen(s, len)
register char *s;
register int len;
{
register int cnt = 0;
while (len-- > 0) {
if (cnt % 8 == 0)
printf("\n%d:", cnt/8 + 1);
if (isprint(*s&0x7f))
printf("\t%02x(%c)", *s&0xff, *s&0x7f);
else
printf("\t%02x", *s&0xff);
s++;
cnt++;
}
putchar('\n');
}
/*
* print out an octet string
*/
prntos(pe)
PE pe;
{
struct qbuf *qb;
if ((qb = prim2qb(pe)) == NULL) {
bad:
printf("prntos:bad octet string\n");
return (-1);
}
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 (0);
}
/*
* print out a string which should be printable
*/
prntstr(pe)
PE pe;
{
struct qbuf *qb;
if ((qb = prim2qb(pe)) == NULL) {
bad:
printf("prntstr:bad string\n");
return (-1);
}
if (qb_pullup(qb) == NOTOK)
goto bad;
if (qb->qb_forw->qb_data == NULL || qb->qb_forw->qb_len < 0)
goto bad;
printf("\"%s\"", qb->qb_forw->qb_data);
return (0);
}
/*
* Is data present for the optional item? 1 for yes 0 for no
*/
hasdata(parm, p, mod, popt, optcnt)
PEPYPARM parm;
tpe *p;
modtyp *mod; /* Module it is from */
int *popt, optcnt;
{
switch (p->pe_type) {
case INTEGER:
case BOOLEAN:
case T_NULL:
if (DEFAULT(p)) {
/* Default's don't have bit map */
if (p[1].pe_type == DFLT_B && same(p, p + 1, parm, mod)
|| p[-1].pe_type == DFLT_F && same(p, p - 1, parm, mod))
goto next;
break;
}
if (!TESTBIT(*popt, optcnt++))
goto next; /* Missing so skip */
break;
case ETAG:
if (!hasdata(parm, p + 1, mod, popt, optcnt))
goto next;
break;
case IMP_OBJ:
if (p[1].pe_type == SOBJECT && parm == NULL
|| *((char **)(parm + p[1].pe_ucode)) == NULL)
goto next;
break;
default:
if (*((char **)(parm + p->pe_ucode)) == NULL)
goto next;
break;
}
return (1);
next:
return (0);
}
/*
* determine if the default value is the same as the value in the structure
* and if so return non zero (meaning don't encode this item).
*/
same(typ, dflt, parm, mod)
tpe *typ, *dflt;
char *parm;
modtyp *mod; /* Module it is from */
{
int val;
char *p1;
PE pe;
struct qbuf *qb;
switch (typ->pe_type) {
case INTEGER:
val = IVAL(dflt) == *(int *)(parm + typ->pe_ucode);
break;
case BOOLEAN:
val = IVAL(dflt) == *(char *)(parm + typ->pe_ucode);
break;
case T_NULL:
val = 1; /* Only one value */
break;
case SBITSTRING:
if ((pe = (PE )parm) == NULL) {
val = 1;
break;
}
goto bstring;
case BITSTRING:
if ((pe = *(PE *)(parm + typ->pe_ucode)) == NULL) {
val = 1;
break;
}
bstring:
if ((p1 = bitstr2strb(pe, &val)) == NULL)
ferr(1, "same:bad bitstring\n");
if (val != IVAL(dflt) || bitscmp(PVAL(dflt), p1, val))
val = 0;
else
val = 1;
free(p1);
break;
case SOCTETSTRING:
if ((qb = (struct qbuf *)parm) == NULL) {
val = 1;
break;
}
goto ostring;
case OCTETSTRING:
if ((qb = *(struct qbuf **)(parm + typ->pe_ucode)) == NULL) {
val = 1;
break;
}
ostring:
if (ostrcmp(PVAL(dflt), IVAL(dflt), qb))
val = 0;
else
val = 1;
break;
case OBJECT:
if (*(char **)(parm + typ->pe_ucode) == NULL) {
val = 1; /* to conform with pepy's way of doing default */
break;
}
val = same(mod->md_etab[typ->pe_tag] + 1, dflt,
*(char **) (parm + typ->pe_ucode), mod);
break;
case SOBJECT:
if ((char *)parm == NULL) {
val = 1; /* to conform with pepy's way of doing default */
break;
}
val = same(mod->md_etab[typ->pe_tag] + 1, dflt, parm, mod);
break;
case IMP_OBJ:
typ++; /* fall through */
case SCONS_ANY:
case ANY:
case CONS_ANY:
case SANY:
case SEXTOBJ:
case EXTOBJ:
case OBJID:
case SOBJID:
case SEQ_START:
case SET_START:
case -1: /* Just use the pepy method of null pointers */
/* This is the posy/pepy hack way of doing things at the moment */
val = *(char **)(parm + typ->pe_ucode) == NULL;
break;
default:
/* dmp_tpe("same: type not implemented", typ, mod); - need mod*/
ferrd(1, "same: %d not implemented\n", typ->pe_type);
break;
}
return (val);
}