|
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 d
Length: 38054 (0x94a6) Types: TextFile Names: »dec.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦041b9c0f8⟧ »EurOpenD22/isode/pepsy.system-6.0.Z« └─⟦d49939f05⟧ └─⟦6a28ec38e⟧ »pepsy.tar« └─⟦this⟧ »pepsy/dec.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 "../h/psap.h" #include "pep.h" #include "pepdefs.h" #define PEPYPARM char ** #ifndef PEPYPARM #define PEPYPARM char ** #endif extern PEPYPARM NullParm; 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(), pr_obj(); extern PE setpresent(); extern tpe *next_tpe(); extern int _pverbose; #define NEXT_TPE(p) p = next_tpe(p) #define CHKTAG(mod, p, pe) ismatch(p, mod, pe->pe_class, pe->pe_id) /* Have we got an optional object which we have allocated sapce for */ #define ALLOC_MEM(p, parm) (p->pe_type == SOBJECT \ && p[-1].pe_type == MALLOC) /*SUPPRESS 36*/ /* for Saber C */ /* * decode the specified type of the specified module into the given pe */ dec_f(typ, mod, pe, explicit, len, buf, parm) /*ARGSUSED*/ int typ; /* which type it is */ modtyp *mod; /* Module it is from */ PE pe; int explicit; int *len; char **buf; PEPYPARM parm; { tpe *p; if (typ < 0 || typ >= mod->md_nentries) ferrd(1, "dec_f:Illegal typ %d\n", typ); p = mod->md_dtab[typ]; if (p->pe_type != PE_START) ferr(1, "dec_f: missing PE_START\n"); p++; if ((pe = pr_obj(explicit, pe, parm, p, mod)) == NULLPE) return (NOTOK); return (OK); } /* * Parse an object. The top level of an object does not have any offset field * which makes it different to pr_type routine which must assume that it * has an offset. */ PE pr_obj(expl, pe, parm, p, mod) int expl; /* do we look at the tag */ PE pe; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { int cnt = 0; if (_pverbose > 6) { printf("1st Decoding the type %d \n",p->pe_type); } while (p->pe_type != PE_END) { if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) { if (DEFAULT(p)) ferr(1, "pr_obj:Default not implemented\n"); else if (OPTIONAL(p)) { if (ALLOC_MEM(p, parm)) fix_mem(parm, p); goto next; } else { dmp_tpe("pr_obj:missing mandatory parameter", p, mod); return (NULLPE); } } if (_pverbose > 6) { printf("2nd Decoding the type %d \n",p->pe_type); } switch (p->pe_type) { case PE_END: case PE_START: return (NULLPE); case UCODE: if ((*mod->md_ducode)(pe, parm, p, mod) != OK) return (NULLPE); break; case ETAG: switch (p->pe_ucode) { default: p++; if (pr_obj(1, pe->pe_cons, parm, p, mod) == NULLPE) return (NULLPE); } break; case MALLOC: if ((*(parm) = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; break; case SEQ_START: if ((pe = pr_seq(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SEQOF_START: if ((pe = pr_seqof(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SET_START: if ((pe = pr_set(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SETOF_START: if ((pe = pr_setof(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case IMP_OBJ: p++; if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) { dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL, (char **) 0, parm); } else { if (p->pe_type == SOBJECT) { if ((pe = pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } else if ((pe = pr_obj(0, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } break; case SOBJECT: case OBJECT: if ((pe = pr_obj(expl, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case CHOICE_START: if ((pe = pr_choice(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SEXTOBJ: case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_type: missing EXTMOD", p, mod); ferr(1, "pr_type:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, parm); break; default: if ((pe = pr_type(expl, pe, parm, p, mod)) == NULLPE) return (NULLPE); break; } if (ISDTYPE(p) && cnt > 0) ferr(1, "pr_obj:compound type found\n"); if (ISDTYPE(p) && pe != NULLPE) return (pe); next: NEXT_TPE(p); } return (pe); } /* * Parse a single type. * If a basic type parse it, if a compound type call the appropriate * parsing routine */ PE pr_type(expl, pe, parm, p, mod) int expl; /* do we look at the tag */ PE pe; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { int cnt = 0; OID oid; if (_pverbose > 6) { printf("1st Decoding the type %d \n",p->pe_type); } while (p->pe_type != PE_END) { /* print_pe (pe, 1); */ if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) { if (DEFAULT(p)) { setdval(p, p + 1, parm, mod); goto next; } else if (OPTIONAL(p)) { if (ALLOC_MEM(p, parm)) fix_mem(parm, p); goto next; } else { dmp_tpe("pr_type:missing mandatory parameter", p, mod); return (NULLPE); } } if (_pverbose > 6) { printf("2nd Decoding the type %d \n",p->pe_type); } switch (p->pe_type) { case PE_END: case PE_START: return (NULLPE); case UCODE: if ((*mod->md_ducode)(pe, parm, p, mod) != OK) return (NULLPE); break; case ETAG: switch (p->pe_ucode) { default: p++; if (pr_etype(pe->pe_cons, parm, p, mod) == NULLPE) return (NULLPE); } break; case MALLOC: if ((*(parm) = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; break; case SEQ_START: if ((pe = pr_seq(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SEQOF_START: if ((pe = pr_seqof(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SET_START: if ((pe = pr_set(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SETOF_START: if ((pe = pr_setof(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case IMP_OBJ: p++; if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) { dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL, (char **) 0, parm); } else { if (p->pe_type == SOBJECT) { if ((pe = pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } else if ((pe = pr_obj(0, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } break; case SOBJECT: case OBJECT: if ((pe = pr_obj(expl, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case CHOICE_START: if ((pe = pr_choice(pe, parm, p, mod)) == NULLPE) return (NULLPE); break; case SEXTOBJ: case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_type: missing EXTMOD", p, mod); ferr(1, "pr_type:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, parm); break; case INTEGER: if (pe != NULLPE) { if (_pverbose > 6) { printf("integer value is %d\n",prim2num(pe)); } if (((*(int *)(*parm + p->pe_ucode)) = prim2num(pe)) == NOTOK && pe->pe_errno != PE_ERR_NONE) { printf("pr_type:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case BOOLEAN: if (pe != NULLPE) { if (_pverbose > 6) { printf("boolean value is %d\n",prim2flag(pe)); } if (((* (char *)(*parm + p->pe_ucode)) = prim2flag(pe))==NOTOK && pe->pe_errno != PE_ERR_NONE) { printf("pr_type:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case T_NULL: break; case SCONS_ANY: case SANY: if (pe != NULLPE) { ((* (PE *) parm) = pe)->pe_refcnt++; if (pe->pe_errno != PE_ERR_NONE) { printf("pr_type:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case CONS_ANY: case ANY: if (pe != NULLPE) { (* (PE *) (*parm + p->pe_ucode) = pe) ->pe_refcnt++; if (pe->pe_errno != PE_ERR_NONE) { printf("pr_type:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case SOCTETSTRING: if (pe != NULLPE) { if ((*((struct qbuf **) parm) = prim2qb(pe)) == (struct qbuf *) NULL && pe->pe_errno != PE_ERR_NONE) { printf("pr_type:bad octet string %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case OCTETSTRING: if (pe != NULLPE) { if ((*((struct qbuf **) (*parm + p->pe_ucode)) = prim2qb(pe)) == (struct qbuf *) NULL && pe->pe_errno != PE_ERR_NONE) { printf("pr_type:bad octet string %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case SBITSTRING: if (pe != NULLPE) { /* if ((*((PE *)(*parm + p->pe_ucode))=prim2bit(pe))== NULLPE) I think this is a bug in ISODE's routines prim2bit does the wrong thing */ if ((*((PE *)parm)=prim2bit(pe_cpy(pe))) == NULLPE) { printf("pr_type:out of memory"); return (NULLPE); } } break; case BITSTRING: if (pe != NULLPE) { /* if ((*((PE *)(*parm + p->pe_ucode))=prim2bit(pe))== NULLPE) I think this is a bug in ISODE's routines prim2bit does the wrong thing */ if ((*((PE *)(*parm + p->pe_ucode))=prim2bit(pe_cpy(pe))) == NULLPE) { printf("pr_type:out of memory"); return (NULLPE); } } break; case SOBJID: /* This is messy because ISODE's library routine uses a static. Don't * know why they do */ if ((oid = prim2oid(pe)) == NULLOID || (*(OID *)parm = oid_cpy(oid)) == NULLOID) { printf("pr_type:Object Identifier: out of memory"); if (oid && oid->oid_elements) { free(oid->oid_elements); oid->oid_elements = NULL; } return (NULLPE); } if (oid && oid->oid_elements) { free(oid->oid_elements); oid->oid_elements = NULL; } break; case OBJID: if ((oid = prim2oid(pe)) == NULLOID || (*(OID *)(*parm + p->pe_ucode) = oid_cpy(oid)) == NULLOID) { printf("pr_type:Object Identifier: out of memory"); if (oid && oid->oid_elements) { free(oid->oid_elements); oid->oid_elements = NULL; } return (NULLPE); } if (oid && oid->oid_elements) { free(oid->oid_elements); oid->oid_elements = NULL; } break; default: dmp_tpe("pr_type: type not implemented", p, mod); ferrd(1, "pr_type: %d not implemented\n", p->pe_type); break; } if (ISDTYPE(p) && cnt > 0) ferr(1, "pr_type:compound type found\n"); if (ISDTYPE(p) && pe != NULLPE) return (pe); next: NEXT_TPE(p); } return (pe); } /* * Parse a sequence, calling appropriate routines to parse each sub type */ PE pr_seq(head, parm, p, mod) PE head; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { PE pe; int *popt = NULL; /* Pointer to optional field */ int optcnt = 0; /* Number of optionals bits so far */ if (p->pe_type != SEQ_START) ferr(1, "pr_seq: missing SEQ_START\n"); p++; if (p->pe_type == DFLT_B) p++; pe = first_member(head); while (p->pe_type != PE_END) { if (_pverbose > 6) { printf("dec_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 (pe == NULLPE || CHKTAG(mod, p, pe) == 0) { optcnt++; goto next; } SETBIT(*popt, optcnt++); break; #if 0 case ANY: case CONS_ANY: case SANY: case SCONS_ANY: dmp_tpe("pr_seq:optional/default ANY", p, mod); ferr(1, "unable to distinguish tags"); #endif default: if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) { if (ALLOC_MEM(p, parm)) fix_mem(parm, p); goto next; } break; } } else if (ISDTYPE(p) && (pe == NULLPE || CHKTAG(mod, p, pe) == 0)) { if (DEFAULT(p)) { setdval(p, p + 1, parm, mod); goto next; } else { dmp_tpe("pr_seq:missing mandatory parameter", p, mod); return (NULLPE); } } switch (p->pe_type) { case OPTL: popt = (int *) (*parm + p->pe_ucode); break; case UCODE: if ((*mod->md_ducode)(pe, parm, p, mod) != OK) return (NULLPE); break; case ETAG: if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE) return NULLPE; break; case MALLOC: if ((*parm = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; break; case SEQ_START: if ((pe = pr_seq(pe, (char **)(*parm + p->pe_ucode), p, mod)) == NULLPE) return (NULLPE); break; case SEQOF_START: if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SET_START: if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SETOF_START: if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case IMP_OBJ: p++; if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) { dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL, (char **) 0, *parm + p->pe_ucode); } else { if (p->pe_type == SOBJECT) { if ((pe = pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } else if ((pe = pr_obj(0, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } break; case SOBJECT: if ((pe = pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case OBJECT: if ((pe = pr_obj(1, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case CHOICE_START: if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_seq: missing EXTMOD", p, mod); ferr(1, "pr_seq:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, parm); break; case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_seq: missing EXTMOD", p, mod); ferr(1, "pr_seq:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, *parm + p->pe_ucode); break; default: if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE) return (NULLPE); break; /* ferrd(1, "pr_seq: unknown type %d\n", p->pe_type); */ } if (ISDTYPE(p) && pe != NULLPE) pe = next_member(head, pe); next: NEXT_TPE(p); } return (head); } /* * Parse a set, calling appropriate routines to parse each sub type */ PE pr_set(head, parm, p, mod) PE head; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { PE pe; int *popt = NULL; /* Pointer to optional field */ int optcnt = 0; /* Number of optionals bits so far */ if (p->pe_type != SET_START) ferr(1, "pr_seq: missing SET_START\n"); p++; if (p->pe_type == DFLT_B) p++; while (p->pe_type != PE_END) { if (_pverbose > 6) { printf("dec_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 ((pe = setpresent(head, p, mod)) == NULLPE) { optcnt++; goto next; } SETBIT(*popt, optcnt++); break; #if 0 case ANY: case CONS_ANY: case SANY: case SCONS_ANY: dmp_tpe("pr_set:optional/default ANY\n", p, mod); ferr(1, "unable to distinguish tags"); #endif default: if ((pe = setpresent(head, p, mod)) == NULLPE) { if (ALLOC_MEM(p, parm)) fix_mem(parm, p); goto next; } break; } } else if (ISDTYPE(p) && (pe = setpresent(head, p, mod)) == NULLPE) { if (DEFAULT(p)) { setdval(p, p + 1, parm, mod); goto next; } else { dmp_tpe("pr_set:missing mandatory parameter", p, mod); return (NULLPE); } } switch (p->pe_type) { case OPTL: popt = (int *) (*parm + p->pe_ucode); break; case UCODE: if ((*mod->md_ducode)(pe, parm, p, mod) != OK) return (NULLPE); break; case ETAG: if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE) return NULLPE; break; case MALLOC: if ((*parm = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; break; case SEQ_START: if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEQOF_START: if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SET_START: if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SETOF_START: if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case IMP_OBJ: p++; if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) { dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL, (char **) 0, *parm + p->pe_ucode); } else { if (p->pe_type == SOBJECT) { if ((pe = pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } else if ((pe = pr_obj(0, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } break; case SOBJECT: if ((pe = pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case OBJECT: if ((pe = pr_obj(1, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case CHOICE_START: if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_set: missing EXTMOD", p, mod); ferr(1, "pr_set:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, parm); break; case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_set: missing EXTMOD", p, mod); ferr(1, "pr_set:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, *parm + p->pe_ucode); break; default: if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE) return (NULLPE); break; /* ferrd(1, "pr_set: unknown type %d\n", p->pe_type); */ } next: NEXT_TPE(p); } return (head); } /* * Parse a sequence of calling appropriate routines to parse each sub type */ PE pr_seqof(head, parm, p, mod) PE head; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { PE pe; tpe *start; /* first entry in list */ int dflt = 0; if (p->pe_type != SEQOF_START) { dmp_tpe("pr_seqof:missing SEQOF_START", p, mod); ferr(1, "pr_seqof: missing SEQOF_START\n"); } p++; if (p->pe_type == DFLT_B) p++; start = p; pe = first_member(head); while (pe != NULLPE) { while (p->pe_type != PE_END) { if (_pverbose > 6) { printf("dec_seqof with the type %d\n",p->pe_type); } if (ISDTYPE(p) && CHKTAG(mod, p, pe) == 0) { if (DEFAULT(p)) { setdval(p, p + 1, parm, mod); goto next; } else if (OPTIONAL(p)) { if (ALLOC_MEM(p, parm)) fix_mem(parm, p); goto next; } else { dmp_tpe( "pr_seqof:missing mandatory parameter", p, mod); return (NULLPE); } } switch (p->pe_type) { case UCODE: if ((*mod->md_ducode)(pe, parm, p, mod) != OK) return (NULLPE); break; case ETAG: if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE) return NULLPE; break; case MALLOC: if ((*parm = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; break; case SCTRL: parm = (char **) ((char *)*parm + p->pe_ucode); break; case SEQ_START: if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEQOF_START: if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SET_START: if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SETOF_START: if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SOBJECT: if ((pe = pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case OBJECT: if ((pe = pr_obj(1, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case CHOICE_START: if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_seqof: missing EXTMOD", p, mod); ferr(1, "pr_seqof:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, parm); break; case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_seqof: missing EXTMOD", p, mod); ferr(1, "pr_seqof:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, *parm + p->pe_ucode); break; default: if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE) return (NULLPE); break; } if (ISDTYPE(p) && dflt == 0) pe = next_member(head, pe); next: NEXT_TPE(p); } parm = (char **)(*parm + p->pe_ucode); p = start; } return (head); } /* * Parse a setof, calling appropriate routines to parse each sub type */ PE pr_setof(head, parm, p, mod) PE head; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { PE pe; int dflt; tpe *start; if (p->pe_type != SETOF_START) ferr(1, "pr_setof: missing SETOF_START\n"); p++; if (p->pe_type == DFLT_B) p++; start = p; pe = first_member(head); for (pe = first_member(head); pe; pe = next_member(head, pe)) { while (p->pe_type != PE_END) { if (_pverbose > 6) { printf("dec_seqof with the type %d\n", p->pe_type); } if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) { if (DEFAULT(p)) { setdval(p, p + 1, parm, mod); goto next; } else { dmp_tpe( "pr_setof:missing mandatory parameter", p, mod); return (NULLPE); } } else dflt = 0; switch (p->pe_type) { case UCODE: if ((*mod->md_ducode)(pe, parm, p, mod) != OK) return (NULLPE); break; case ETAG: if ((pe = pr_type(1, pe->pe_cons, parm, p, mod)) == NULLPE) return NULLPE; break; case MALLOC: if ((*parm = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; break; case SCTRL: parm = (char **) (*parm + p->pe_ucode); break; case SEQ_START: if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEQOF_START: if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SET_START: if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SETOF_START: if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SOBJECT: if ((pe = pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case OBJECT: if ((pe = pr_obj(1, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case CHOICE_START: if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_setof: missing EXTMOD", p, mod); ferr(1, "pr_setof:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, parm); break; case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_setof: missing EXTMOD", p, mod); ferr(1, "pr_setof:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, *parm + p->pe_ucode); break; default: if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE) return (NULLPE); break; /* ferrd(1, "pr_setof: unknown type %d\n", p->pe_type); */ } #if 0 /* fixup - we only delete in this function */ if (ISDTYPE(p) && dflt == 0) set_del(head, pe->pe_class, pe->pe_id); #endif next: NEXT_TPE(p); } parm = (char **)(*parm + p->pe_ucode); p = start; } return (head); } /* * parse a choice field. This means find which choice is taken */ PE pr_choice(head, parm, p, mod) PE head; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { int *poffset; int cnt; PE pe; 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 == DFLT_B) p++; if (p->pe_type == MALLOC) { if ((*parm = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; p++; } if (p->pe_type == SCTRL) { if ((poffset = (int *) (*parm + p->pe_ucode)) == NULL) return NULLPE; p++; } for (cnt = 1; p->pe_type != PE_END; NEXT_TPE(p), cnt++) { if (ISDTYPE(p) && ismatch(p, mod, head->pe_class, head->pe_id)) { pe = pr_etype(head, parm, p, mod); *poffset = cnt; return (pe); } } dmp_tpe("pr_choice: no choice taken", p, mod); return (NULLPE); } /* * Calculate the next tpe entry in the sequence. Count a sequence as one element */ tpe * next_tpe(p) tpe *p; { int level; level = 0; if (p->pe_type == PE_END) ferr(1, "next_tpe:PE_END"); do { again: switch (p->pe_type) { case SEQ_START: case SEQOF_START: case SET_START: case SETOF_START: case CHOICE_START: level++; break; case UCODE: case MALLOC: case SCTRL: case CH_ACT: case INTEGER: case BOOLEAN: case SANY: case SCONS_ANY: case ANY: case CONS_ANY: case T_NULL: case OBJECT: case SOBJECT: case BITSTRING: case SBITSTRING: case OCTETSTRING: case SOCTETSTRING: case OBJID: case SOBJID: case OPTL: case EXTMOD: case DFLT_B: break; case IMP_OBJ: case ETAG: case EXTOBJ: case SEXTOBJ: case DFLT_F: p++; goto again; case PE_END: level--; break; default: ferrd(1, "next_tpe: unknown type %d\n", p->pe_type); } p++; } while (level > 0 || p->pe_type == DFLT_B); return (p); } /* * check that pe is non null and that the tag and class match and return * zero if the don't */ chktag(mod, p, pe) modtyp *mod; /* Module it is from */ tpe *p; PE pe; { int cl, tag; if (pe == NULLPE) return (0); #if 0 if (p->pe_type == OBJECT && skip_next_tag) /* first time we find skip */ return (1); if (skip_next_tag) { /* 2nd time reset skip */ skip_next_tag = 0; return (1); } #endif if (!findcltag(p, mod, &cl, &tag)) return (0); if (pe->pe_id != tag || pe->pe_class != cl) return (0); return (1); } #if 0 /* test if we need to check the tag associated with the tpe entry p */ legal_tag(p) tpe *p; { int ret; switch (p->pe_type) { case MALLOC: case SCTRL: case CH_ACT: case ANY: case OBJECT: case CHOICE_START: case CONS_ANY: /* case ETAG: don't think we should have this here */ ret = 0; break; default: #if 0 if (skip_next_tag) { skip_next_tag = 0; ret = 0; } else #endif ret = 1; break; } return ret; } #endif /* * Parse a single type for explicit tag * If a basic type parse it, if a compound type call the appropriate * parsing routine */ PE pr_etype(pe, parm, p, mod) PE pe; PEPYPARM parm; tpe *p; modtyp *mod; /* Module it is from */ { switch (p->pe_type) { case PE_END: case PE_START: return (NULLPE); case UCODE: if ((*mod->md_ducode)(pe, parm, p, mod) != OK) return (NULLPE); break; case ETAG: switch (p->pe_ucode) { default: p++; if (pr_etype(pe->pe_cons, parm, p, mod) == NULLPE) return (NULLPE); } break; case MALLOC: if ((*(parm) = (char *) calloc(1, p->pe_tag)) == NULL) return NULLPE; break; case SEQ_START: if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEQOF_START: if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SET_START: if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SETOF_START: if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case IMP_OBJ: p++; if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) { dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL, (char **) 0, *parm + p->pe_ucode); } else { if (p->pe_type == SOBJECT) { if ((pe = pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } else if ((pe = pr_obj(0, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); } break; case SOBJECT: if ((pe = pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case OBJECT: if ((pe = pr_obj(1, pe, *parm + p->pe_ucode, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE) return (NULLPE); break; case CHOICE_START: if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE) return (NULLPE); break; case SEXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_etype: missing EXTMOD", p, mod); ferr(1, "pr_etype:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, parm); break; case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("pr_etype: missing EXTMOD", p, mod); ferr(1, "pr_etype:internal error\n"); } dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL, (char **) 0, *parm + p->pe_ucode); break; case INTEGER: if (pe != NULLPE) { if (_pverbose > 6) { printf("integer value is %d\n",prim2num(pe)); } if (((*(int *)(*parm + p->pe_ucode)) = prim2num(pe))== NOTOK && pe->pe_errno != PE_ERR_NONE) { printf("pr_etype:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case BOOLEAN: if (pe != NULLPE) { if (_pverbose > 6) { printf("boolean value is %d\n",prim2flag(pe)); } if (((* (char *)(*parm + p->pe_ucode)) = prim2flag(pe))==NOTOK && pe->pe_errno != PE_ERR_NONE) { printf("pr_etype:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case T_NULL: break; case ANY: case CONS_ANY: if (pe != NULLPE) { (* (PE *) (*parm + p->pe_ucode) = pe) ->pe_refcnt++; if (pe->pe_errno != PE_ERR_NONE) { printf("pr_etype:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case SANY: case SCONS_ANY: /* This could require changes when I find out what the CONS_ANY type * is really for */ if (pe != NULLPE) { ((PE) (*parm ) = pe) ->pe_refcnt++; if (pe->pe_errno != PE_ERR_NONE) { printf("pr_etype:bad integer %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case SOCTETSTRING: if (pe != NULLPE) { if ((*((struct qbuf **) parm) = prim2qb(pe)) == (struct qbuf *) NULL && pe->pe_errno != PE_ERR_NONE) { printf("pr_etype:bad octet string %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case OCTETSTRING: if (pe != NULLPE) { if ((*((struct qbuf **) (*parm + p->pe_ucode)) = prim2qb(pe)) == (struct qbuf *) NULL && pe->pe_errno != PE_ERR_NONE) { printf("pr_etype:bad octet string %s", pe_error(pe->pe_errno)); return (NULLPE); } } break; case SBITSTRING: if (pe != NULLPE) { if (((*(PE *) parm) = pe_cpy(pe)) == NULLPE) { printf("pr_etype:out of memory"); return (NULLPE); } } break; case BITSTRING: if (pe != NULLPE) { if ((*((PE *) (*parm + p->pe_ucode))= pe_cpy(pe)) == NULLPE) { printf("pr_etype:out of memory"); return (NULLPE); } } break; case SOBJID: if ((*(OID *)parm = oid_cpy(prim2oid(pe))) == NULLOID) { printf("pr_etype:Object Identifier: out of memory"); return (NULLPE); } break; case OBJID: if ((*(OID *)(*parm + p->pe_ucode) = oid_cpy(prim2oid(pe))) == NULLOID) { printf("en_etype:Object Identifier: out of memory"); return (NULLPE); } break; default: ferrd(1, "pr_etype: %d not implemented\n", p->pe_type); break; } return (pe); } /* * determine what the class and tag must be of the given object */ findcltag(p, mod, pcl, ptag) tpe *p; modtyp *mod; /* Module it is from */ int *pcl, *ptag; { if (!ISDTYPE(p)) return (0); if (p->pe_type != OBJECT) { *pcl = CLASS(p); *ptag = TAG(p); return (1); } p = mod->md_dtab[p->pe_tag] + 1; while (p->pe_type != PE_END) { if (ISDTYPE(p)) return (findcltag(p, mod, pcl, ptag)); } dmp_tpe("findcltag:warning:object with no data in it", p, mod); return (0); } /* * Is there a match at for this tag and class pair. Return 1 if yes 0 if no * We will search through contained objects and through choices */ ismatch(p, mod, cl, tag) tpe *p; modtyp *mod; /* Module it is from */ unsigned int cl, tag; { while (!ISDTYPE(p)) p++; switch (p->pe_type) { case SOBJECT: case OBJECT: /* Needs to be changed for optional and default */ return (ismatch(p = mod->md_dtab[p->pe_tag] + 1, mod, cl, tag)); case SEXTOBJ: case EXTOBJ: if (p[1].pe_type != EXTMOD) { dmp_tpe("ismatch: missing EXTMOD", p, mod); ferr(1, "ismatch:internal error\n"); } return(ismatch(((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag] + 1, (modtyp *)p[1].pe_ucode, cl, tag)); case CHOICE_START: for (p++; p->pe_type != PE_END; p = NEXT_TPE(p)) { if (!ISDTYPE(p)) continue; if (ismatch(p, mod, cl, tag)) return (1); } return (0); case SANY: case SCONS_ANY: return (1); default: return (tag == TAG(p) && cl == CLASS(p)); } } /* * determine if the given field is present in the data * This is simple if the field is a simple type with an obvious tag but * in the case of an object or a CHOICE type the tag is not obvious. If the * object is a CHOICE there are more than one possible tag that could match * and in this case we must try to match each one of them. */ PE setpresent(head, p, mod) PE head; tpe *p; modtyp *mod; { PE pe; if (!ISDTYPE(p)) return (NULLPE); switch (p->pe_type) { case OBJECT: case SOBJECT: /* Needs to be changed for optional and default */ return (setpresent(head, p = mod->md_dtab[p->pe_tag] + 1, mod)); case CHOICE_START: for (p++; p->pe_type != PE_END; p = NEXT_TPE(p)) { if (!ISDTYPE(p)) continue; if ((pe = setpresent(head, p, mod))) return (pe); } return (NULLPE); default: return (set_find(head, CLASS(p), TAG(p))); } } /* * set the default value to that value in the structure */ setdval(typ, dflt, parm, mod) tpe *typ, *dflt; char **parm; modtyp *mod; { again: switch (typ->pe_type) { case MALLOC: if ((*(parm) = (char *) calloc(1, typ->pe_tag)) == NULL) ferrd(1, "setdval:calloc failed on %d\n", typ->pe_tag); typ++; goto again; case INTEGER: *(int *)(*parm + typ->pe_ucode) = IVAL(dflt); break; case BOOLEAN: *(char *)(*parm + typ->pe_ucode) = IVAL(dflt); break; case T_NULL: /* Only one value */ break; case SBITSTRING: *(PE *)parm = strb2bitstr(PVAL(dflt), IVAL(dflt), 0, 0); break; case BITSTRING: *(PE *)(*parm + typ->pe_ucode) = strb2bitstr(PVAL(dflt), IVAL(dflt), 0, 0); break; case SOCTETSTRING: *(struct qbuf **)parm = str2qb(PVAL(dflt), IVAL(dflt), 1); break; case OCTETSTRING: *(struct qbuf **)(*parm + typ->pe_ucode) = str2qb(PVAL(dflt), IVAL(dflt), 1); break; case OBJECT: setdval(mod->md_dtab[typ->pe_tag] + 1, dflt, (char **) (*parm + typ->pe_ucode), mod); break; case SOBJECT: setdval(mod->md_dtab[typ->pe_tag] + 1, dflt, parm, mod); break; case IMP_OBJ: typ++; 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 */ *(char **)(*parm + typ->pe_ucode) = NULL; break; default: /* dmp_tpe("setdval: type not implemented", typ, mod); - need mod*/ ferrd(1, "setdval: %d not implemented\n", typ->pe_type); break; } } /* * fix up the allocation of memory. We have allocated memory for an optional * object that is not present. ISODE routines get upset if this is present * because it then believes the object is present and tries to process it ... */ fix_mem(parm, p) char **parm; tpe *p; { if (p->pe_type != SOBJECT || p[-1].pe_type != MALLOC || p[1].pe_type != PE_END) ferr(1, "fix_mem:inconsistency\n"); if (*parm) free(*parm); *parm = NULL; }