|
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); }