|
|
1.1 root 1: /* util.c */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/pepsy/RCS/util.c,v 7.1 90/07/09 14:53:23 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/pepsy/RCS/util.c,v 7.1 90/07/09 14:53:23 mrose Exp $
9: *
10: *
11: * $Log: util.c,v $
12: * Revision 7.1 90/07/09 14:53:23 mrose
13: * sync
14: *
15: * Revision 7.0 90/07/01 19:54:33 mrose
16: * *** empty log message ***
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: #include <stdio.h>
32: #include "psap.h"
33: #include "pepsy.h"
34: #include <varargs.h>
35: #include "tailor.h"
36:
37: #ifndef PEPYPARM
38: #define PEPYPARM char *
39: #endif
40:
41: static char *pr_petype ();
42:
43: #ifdef lint
44: int pepsylose (module, p, pe, str)
45: modtyp *module;
46: tpe *p;
47: char *str;
48: PE pe;
49: {
50: return pepsylose (type, module, pe, str);
51: }
52:
53: #else
54: int pepsylose (va_alist)
55: va_dcl
56: {
57: va_list ap;
58: int type;
59: modtyp *module;
60: tpe *p;
61: char *cp;
62: PE pe;
63: char buffer[BUFSIZ];
64:
65: va_start (ap);
66:
67: module = va_arg (ap, modtyp *);
68: p = va_arg (ap, tpe *);
69: pe = va_arg (ap, PE);
70:
71: _asprintf (buffer, NULLCP, ap);
72: (void) sprintf (PY_pepy, "%s: module %s",
73: buffer, module ? module -> md_name : "<none>");
74: if (p) {
75: cp = PY_pepy + strlen (PY_pepy);
76: (void) sprintf (cp, " %s/class=%s/id=%d",
77: pr_petype (p -> pe_type),
78: pe_classlist[p -> pe_flags & FL_CLASS],
79: p -> pe_tag);
80: }
81: if (pe) {
82: cp = PY_pepy + strlen (PY_pepy);
83: (void) sprintf (cp, " got %s/%d", pe_classlist[pe -> pe_class],
84: pe -> pe_id);
85: }
86:
87: SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
88:
89: va_end (ap);
90: return NOTOK;
91: }
92: #endif
93:
94: /*
95: * Useful little routines
96: */
97: /*
98: * print out the message and if the arguement is greater than 0
99: * terminate
100: */
101: ferr(n, mesg)
102: char *mesg;
103: {
104: (void) printf(mesg);
105: if (n > 0)
106: exit(n);
107: }
108: /*
109: * print out the message and number and if the arguement is greater
110: * than 0 terminate
111: */
112: ferrd(n, mesg, d)
113: char *mesg;
114: int d;
115: {
116: (void) printf(mesg, d);
117: if (n > 0)
118: exit(n);
119: }
120:
121: /*
122: * 0 = Encoding table, 1 = Decoding table, 2 = Printing table
123: */
124: #define TYP_ENC 0
125: #define TYP_DEC 1
126: #define TYP_PRINT 2
127: #define TYP_LAST 2
128:
129: dmp_tpe(s, p, mod)
130: char *s;
131: modtyp *mod; /* Module it is from */
132: tpe *p;
133: {
134: int typ, i, j;
135: tpe **par, **prev;
136: char *name;
137:
138: (void) printf("%s: (%s)", s, mod->md_name);
139: /*
140: * Calculate what table it is in - we assume they are in order of
141: * increasing address
142: */
143:
144: par = NULL;
145: for (typ = 0; typ <= TYP_LAST; typ++) {
146: switch (typ) {
147: case TYP_ENC:
148: if (mod->md_etab != NULL && mod->md_etab[0] < p) {
149: par = mod->md_etab;
150: name = "Encoding:";
151: }
152: break;
153:
154: case TYP_DEC:
155: if (mod->md_dtab != NULL && mod->md_dtab[0] < p) {
156: par = mod->md_dtab;
157: name = "Decoding:";
158: }
159: break;
160:
161: case TYP_PRINT:
162: if (mod->md_ptab != NULL && mod->md_ptab[0] < (ptpe *) p) {
163: (ptpe **) par = mod->md_ptab;
164: name = "Printing:";
165: }
166: break;
167:
168: default:
169: (void) pepsylose (mod, p, NULLPE, "dmp_tpe:typ = %d internal error\n",
170: typ);
171: return;
172: }
173: }
174: if (par == NULL) {
175: (void) printf("can't find entry 0x%x\n", p);
176: return;
177: }
178: prev = par;
179: for (i = mod->md_nentries; i > 0; i--) {
180: if (*par > p)
181: break;
182: par++;
183: }
184: if (par == prev)
185: (void) pepsylose (mod, p, NULLPE,
186: "dmp_tpe:par == prev == 0x%x internal error\n", (int) par);
187: par--;
188: j = p - *par;
189:
190: (void) printf("%s type %d + %d ", name, par - prev, j);
191: pr_entry(p);
192: }
193: #define NENTRY(x) ((sizeof (x)/sizeof (x[0])))
194: /*
195: * Print out a tpe entry
196: */
197: static char *ntypes[] = { "PE_START", "PE_END", "illegal 1", "illegal 2",
198: "XOBJECT", "illegal 4", "illegal 5", "UCODE", "MALLOC", "SCTRL", "CH_ACT",},
199:
200: *otypes[] = { "ANY", "INTEGER", "BOOLEAN", "OBJECT",
201: "BITSTRING", "OCTETSTRING", "SET_START", "SEQ_START", "SEQOF_START",
202: "SETOF_START", "CHOICE_START", "UNKNOWN", "T_NULL", "T_OID",
203: "ETAG", "IMP_OBJ",};
204:
205: static char *pr_petype (type)
206: int type;
207: {
208: static char nbuf[30];
209:
210: if (type >= PE_START && type < NENTRY(ntypes) - 1)
211: return ntypes[type + 1];
212: else if (type >= TYPE_DATA && type < NENTRY(otypes) + TYPE_DATA)
213: return otypes[type - TYPE_DATA];
214: (void) sprintf (nbuf, "%d", type);
215: return nbuf;
216: }
217:
218: pr_entry(p)
219: tpe *p;
220: {
221: printf ("%s, ", pr_petype (p -> pe_type));
222: (void) printf("%d, %d, %d}\n", p->pe_ucode, p->pe_tag, p->pe_flags);
223: }
224:
225: p_pr_entry(p)
226: ptpe *p;
227: {
228: if (p->pe_type >= PE_START && p->pe_type < NENTRY(ntypes) - 1)
229: (void) printf("{%s, ", ntypes[p->pe_type + 1]);
230: else if (p->pe_type >= TYPE_DATA && p->pe_type < NENTRY(otypes) + TYPE_DATA)
231: (void) printf("{%s, ", otypes[p->pe_type - TYPE_DATA]);
232: else
233: (void) printf("{%d, ", p->pe_type);
234:
235: (void) printf("%d, %d, %d}\n", p->pe_ucode, p->pe_tag, p->pe_flags);
236: }
237:
238:
239: #if 0
240: pr_pe(pe)
241: PE pe;
242: {
243: print_pe(pe, 1);
244: }
245: #endif
246: /*
247: * null function for what evr purposes
248: */
249: f_null()
250: {
251: }
252:
253: /*
254: * compare a given number of bits pointed to by the two character
255: * pointers return 0 if they are the same non zero otherwise
256: */
257: bitscmp(p1, p2, len)
258: register char *p1, *p2;
259: int len;
260: {
261: register int i;
262: register unsigned int mask;
263:
264: if (len >= 8 && bcmp(p1, p2, len / 8))
265: return (1);
266:
267: if (len % 8 == 0)
268: return (0);
269: /* Check those last few bits */
270: i = len / 8;
271: mask = (0xff00 >> len % 8) & 0xff;
272: if ((p1[i] & mask) != (p2[i] & mask))
273: return (1);
274:
275: return (0);
276: }
277:
278: #define MIN(a, b) (a < b ? a : b)
279: /*
280: * compare an octet string and a qb and return 0 if they are the same
281: * and non zero otherwise
282: */
283: ostrcmp(p, len, qb)
284: register char *p;
285: register int len;
286: register struct qbuf *qb;
287: {
288: register struct qbuf *qp;
289:
290: if (len < 0 || qb == NULL || p == NULL)
291: return (1);
292: qp = qb;
293: do {
294: if (qp->qb_data != NULL) {
295: if (qp->qb_len < 0)
296: ferrd(1, "ostrcmp:qb_len %d < 0", qp->qb_len);
297: if (qp->qb_len > len)
298: return (1);
299: if (bcmp(qp->qb_data, p, qp->qb_len))
300: return (1);
301: if ((len -= qp->qb_len) == 0)
302: return (0);
303: p += qp->qb_len;
304: }
305: qp = qp->qb_forw;
306: } while (qp != qb);
307:
308: return (len);
309: }
310:
311: /*
312: * Is data present for the optional item? 1 for yes 0 for no
313: */
314: hasdata(parm, p, mod, popt, optcnt)
315: PEPYPARM parm;
316: tpe *p;
317: modtyp *mod; /* Module it is from */
318: int *popt, optcnt;
319: {
320: switch (p->pe_type) {
321: case INTEGER:
322: case REALTYPE:
323: case BOOLEAN:
324: case T_NULL:
325: if (DEFAULT(p)) {
326: /* Default's don't have bit map */
327: if (p[1].pe_type == DFLT_B && same(p, p + 1, parm, mod)
328: || p[-1].pe_type == DFLT_F && same(p, p - 1, parm, mod))
329: goto next;
330: break;
331: }
332: if (!TESTBIT(*popt, optcnt++))
333: goto next; /* Missing so skip */
334: break;
335:
336: case ETAG:
337: if (!hasdata(parm, p + 1, mod, popt, optcnt))
338: goto next;
339: break;
340:
341: case IMP_OBJ:
342: if (p[1].pe_type == SOBJECT && parm == NULL
343: || *((char **) (parm + p[1].pe_ucode)) == NULL)
344: goto next;
345: break;
346:
347: default:
348: if (*((char **) (parm + p->pe_ucode)) == NULL)
349: goto next;
350: break;
351: }
352: return (1);
353:
354: next:
355: return (0);
356: }
357:
358: /*
359: * determine if the default value is the same as the value in the
360: * structure and if so return greater than zero (meaning don't encode this
361: * item). On error return NOTOK
362: */
363: same(typ, dflt, parm, mod)
364: tpe *typ, *dflt;
365: char *parm;
366: modtyp *mod; /* Module it is from */
367: {
368: int val;
369: char *p1;
370: PE pe;
371: struct qbuf *qb;
372:
373: switch (typ->pe_type) {
374: case INTEGER:
375: val = IVAL(mod, dflt) == *(int *) (parm + typ->pe_ucode);
376: break;
377:
378: #ifdef PEPSY_REALS
379: case REALTYPE:
380: val = RVAL(mod, dflt) == *(double *) (parm + typ->pe_ucode);
381: break;
382: #endif
383:
384: case BOOLEAN:
385: val = IVAL(mod, dflt) == *(char *) (parm + typ->pe_ucode);
386: break;
387:
388: case T_NULL:
389: val = 1; /* Only one value */
390: break;
391:
392: case SBITSTRING:
393: if ((pe = (PE) parm) == NULL) {
394: val = 1;
395: break;
396: }
397: goto bstring;
398:
399: case BITSTRING:
400: if ((pe = *(PE *) (parm + typ->pe_ucode)) == NULL) {
401: val = 1;
402: break;
403: }
404: bstring:
405: if ((p1 = bitstr2strb(pe, &val)) == NULL) {
406: (void) pepsylose (mod, typ, pe, "same:bad bitstring\n");
407: return (NOTOK);
408: /* Should really abort encoding here but how can we comunicate this
409: * to the routine that calls us?
410: */
411: }
412: if (val != IVAL(mod, dflt) || bitscmp(PVAL(mod, dflt), p1, val))
413: val = 0;
414: else
415: val = 1;
416: free(p1);
417: break;
418:
419: case SOCTETSTRING:
420: if ((qb = (struct qbuf *) parm) == NULL) {
421: val = 1;
422: break;
423: }
424: goto ostring;
425:
426: case OCTETSTRING:
427: if ((qb = *(struct qbuf **) (parm + typ->pe_ucode)) == NULL) {
428: val = 1;
429: break;
430: }
431: ostring:
432: if (ostrcmp(PVAL(mod, dflt), IVAL(mod, dflt), qb))
433: val = 0;
434: else
435: val = 1;
436: break;
437:
438: case OBJECT:
439: if (*(char **) (parm + typ->pe_ucode) == NULL) {
440: val = 1; /* to conform with pepy's way of
441: * doing default */
442: break;
443: }
444: val = same(mod->md_etab[typ->pe_tag] + 1, dflt,
445: *(char **) (parm + typ->pe_ucode), mod);
446: break;
447:
448: case SOBJECT:
449: if ((char *) parm == NULL) {
450: val = 1; /* to conform with pepy's way of
451: * doing default */
452: break;
453: }
454: val = same(mod->md_etab[typ->pe_tag] + 1, dflt, parm, mod);
455: break;
456:
457: case IMP_OBJ:
458: typ++; /* fall through */
459:
460: case ANY:
461: case SANY:
462: case SEXTOBJ:
463: case EXTOBJ:
464: case OBJID:
465: case SOBJID:
466: case SEQ_START:
467: case SET_START:
468: case -1: /* Just use the pepy method of null
469: * pointers */
470: /*
471: * This is the posy/pepy hack way of doing things at the
472: * moment
473: */
474: val = *(char **) (parm + typ->pe_ucode) == NULL;
475: break;
476:
477: default:
478: (void) pepsylose (mod, typ, NULLPE, "same: %d not implemented\n",
479: typ->pe_type);
480: return (NOTOK);
481: }
482:
483: return (val);
484: }
485:
486: /*
487: * Calculate the next tpe entry in the sequence. Count a sequence as
488: * one element
489: */
490: tpe *
491: next_tpe(p)
492: tpe *p;
493: {
494: int level;
495:
496:
497:
498: level = 0;
499: if (p->pe_type == PE_END) {
500: (void) pepsylose (NULLMODTYP, p, NULLPE,
501: "next_tpe:internal error: unexpected PE_END found");
502: return (p);
503: }
504: do {
505: again:
506: switch (p->pe_type) {
507: case SEQ_START:
508: case SEQOF_START:
509: case SET_START:
510: case SETOF_START:
511: case CHOICE_START:
512: level++;
513: break;
514:
515: case UCODE:
516: case MALLOC:
517: case SCTRL:
518: case CH_ACT:
519: case INTEGER:
520: case REALTYPE:
521: case BOOLEAN:
522: case SANY:
523: case ANY:
524: case T_NULL:
525: case OBJECT:
526: case SOBJECT:
527: case BITSTRING:
528: case SBITSTRING:
529: case OCTETSTRING:
530: case SOCTETSTRING:
531: case OBJID:
532: case SOBJID:
533: case OPTL:
534: case EXTMOD:
535: case DFLT_B:
536: break;
537:
538: case IMP_OBJ:
539: case ETAG:
540: case EXTOBJ:
541: case SEXTOBJ:
542: case DFLT_F:
543: p++;
544: goto again;
545:
546: case PE_END:
547: level--;
548: break;
549:
550: default:
551: ferrd(1, "next_tpe: unknown type %d\n", p->pe_type);
552: }
553: p++;
554: } while (level > 0 || p->pe_type == DFLT_B);
555:
556: return (p);
557: }
558:
559: /*
560: * Is there a match at for this tag and class pair. Return 1 if yes 0
561: * if no We will search through contained objects and through choices
562: */
563: ismatch(p, mod, cl, tag)
564: tpe *p;
565: modtyp *mod; /* Module it is from */
566: unsigned int cl, tag;
567: {
568: while (!ISDTYPE(p))
569: p++;
570:
571: switch (p->pe_type) {
572: case SOBJECT:
573: case OBJECT:
574: /* Needs to be changed for optional and default */
575: return (ismatch(p = mod->md_dtab[p->pe_tag] + 1, mod, cl, tag));
576:
577: case SEXTOBJ:
578: case EXTOBJ:
579: if (p[1].pe_type != EXTMOD) {
580: dmp_tpe("ismatch: missing EXTMOD", p, mod);
581: ferr(1, "ismatch:internal error\n");
582: }
583: return (ismatch(EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag] + 1,
584: EXT2MOD(mod, (p + 1)), cl, tag));
585:
586: case CHOICE_START:
587: for (p++; p->pe_type != PE_END; p = next_tpe (p)) {
588: if (!ISDTYPE(p))
589: continue;
590: if (ismatch(p, mod, cl, tag))
591: return (1);
592: }
593: return (0);
594:
595: case SANY:
596: return (1);
597:
598: case ANY:
599: if (STAG(p) == -1)
600: return (1);
601: /* else fall through - not sure if this is needed */
602:
603: default:
604: return (tag == TAG(p) && cl == CLASS(p));
605: }
606: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.