|
|
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.