|
|
1.1 ! root 1: /* objects.c - SMI object handling */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/snmp/RCS/objects.c,v 7.10 90/07/09 14:48:54 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/snmp/RCS/objects.c,v 7.10 90/07/09 14:48:54 mrose Exp $ ! 9: * ! 10: * Contributed by NYSERNet Inc. This work was partially supported by the ! 11: * U.S. Defense Advanced Research Projects Agency and the Rome Air Development ! 12: * Center of the U.S. Air Force Systems Command under contract number ! 13: * F30602-88-C-0016. ! 14: * ! 15: * ! 16: * $Log: objects.c,v $ ! 17: * Revision 7.10 90/07/09 14:48:54 mrose ! 18: * sync ! 19: * ! 20: * Revision 7.9 90/06/21 21:26:23 mrose ! 21: * 0.0 ! 22: * ! 23: * Revision 7.8 90/06/20 21:38:21 mrose ! 24: * update ! 25: * ! 26: * Revision 7.7 90/06/12 09:22:06 mrose ! 27: * write-only ! 28: * ! 29: * Revision 7.6 90/05/28 21:49:51 mrose ! 30: * not-accessible ! 31: * ! 32: * Revision 7.5 90/05/13 16:18:14 mrose ! 33: * views ! 34: * ! 35: * Revision 7.4 90/05/12 17:37:04 mrose ! 36: * typo ! 37: * ! 38: * Revision 7.3 90/02/19 15:54:04 mrose ! 39: * touch-up ! 40: * ! 41: * Revision 7.2 90/02/17 10:38:22 mrose ! 42: * smux ! 43: * ! 44: * Revision 7.1 90/01/11 18:34:23 mrose ! 45: * real-sync ! 46: * ! 47: * Revision 7.0 89/11/23 22:23:18 mrose ! 48: * Release 6.0 ! 49: * ! 50: */ ! 51: ! 52: /* ! 53: * NOTICE ! 54: * ! 55: * Acquisition, use, and distribution of this module and related ! 56: * materials are subject to the restrictions of a license agreement. ! 57: * Consult the Preface in the User's Manual for the full terms of ! 58: * this agreement. ! 59: * ! 60: */ ! 61: ! 62: ! 63: #include <ctype.h> ! 64: #include <stdio.h> ! 65: #include "objects.h" ! 66: #include "tailor.h" ! 67: ! 68: /* DATA */ ! 69: ! 70: #define TBUCKETS 0x80 ! 71: ! 72: static int once_only = 0; ! 73: static OT Tbuckets[TBUCKETS]; ! 74: ! 75: static OT anchor; ! 76: static OT chain; ! 77: ! 78: ! 79: OID resolve (); ! 80: ! 81: ! 82: extern int errno; ! 83: ! 84: /* OBJECTS */ ! 85: ! 86: static int THASH (name) ! 87: char *name; ! 88: { ! 89: char c; ! 90: register char *cp, ! 91: *dp; ! 92: ! 93: for (c = *(dp = cp = name); *cp; cp++) ! 94: if (isupper (*cp)) ! 95: c = tolower (*(dp = cp)); ! 96: if (*++dp) ! 97: return (((c - *dp) & 0x1f) + (*(dp + 1) & 0x5f)); ! 98: else ! 99: return (c & 0x7f); ! 100: } ! 101: ! 102: ! 103: #define OT_XXX 0x04 ! 104: ! 105: static int ot_compar (a, b) ! 106: OT *a, ! 107: *b; ! 108: { ! 109: int i = oid_cmp ((*a) -> ot_name, (*b) -> ot_name); ! 110: ! 111: if (i == 0 ! 112: && (!((*a) -> ot_access & OT_XXX) ! 113: || !((*b) -> ot_access & OT_XXX))) { ! 114: OID oid = (*a) -> ot_name; ! 115: register unsigned int *ip = oid -> oid_elements; ! 116: ! 117: /* XXX: 0.0 is a special case */ ! 118: if (oid -> oid_nelem == 2 && ip[0] == 0 && ip[1] == 0) ! 119: return 0; ! 120: ! 121: if (PY_pepy[0]) ! 122: (void) sprintf (PY_pepy + strlen (PY_pepy), ", "); ! 123: else ! 124: (void) sprintf (PY_pepy, "duplicate objects: "); ! 125: (void) sprintf (PY_pepy + strlen (PY_pepy), "\"%s\" and \"%s\"", ! 126: (*a) -> ot_text, (*b) -> ot_text); ! 127: (*a) -> ot_access |= OT_XXX, (*b) -> ot_access |= OT_XXX; ! 128: } ! 129: ! 130: return i; ! 131: } ! 132: ! 133: ! 134: static char *roots[] = { "ccitt", "iso", "joint-iso-ccitt" }; ! 135: ! 136: int readobjects (file) ! 137: char *file; ! 138: { ! 139: register int j; ! 140: int again, ! 141: hit, ! 142: i; ! 143: register char *cp, ! 144: **ap; ! 145: char buffer[BUFSIZ], ! 146: line[BUFSIZ], ! 147: *vec[NVEC + NSLACK + 1]; ! 148: register OT ot, ! 149: *op, ! 150: *ep; ! 151: OT *base, ! 152: oz; ! 153: FILE *fp; ! 154: ! 155: if (once_only == 0) { ! 156: bzero ((char *) Tbuckets, sizeof Tbuckets); ! 157: ! 158: readsyntax (); ! 159: ! 160: for (ap = roots + (sizeof roots / sizeof roots[0]) - 1; ! 161: ap >= roots; ! 162: ap--) { ! 163: (void) sprintf (buffer, "%d", ap - roots); ! 164: if (read_name (*ap, buffer) == NOTOK) ! 165: return NOTOK; ! 166: } ! 167: ! 168: once_only = 1; ! 169: } ! 170: ! 171: if (file == NULL) ! 172: file = "objects.defs"; ! 173: if ((fp = fopen (file, "r")) == NULL ! 174: && (fp = fopen (cp = isodefile (file, 0), "r")) == NULL) { ! 175: (void) sprintf (PY_pepy, "unable to read %s: %s", ! 176: cp, sys_errname (errno)); ! 177: return NOTOK; ! 178: } ! 179: ! 180: while (fgets (buffer, sizeof buffer, fp)) { ! 181: if (*buffer == '#' || strncmp (buffer, "--", 2) == 0) ! 182: continue; ! 183: if (cp = index (buffer, '\n')) ! 184: *cp = NULL; ! 185: (void) strcpy (line, buffer); ! 186: ! 187: bzero ((char *) vec, sizeof vec); ! 188: switch (str2vec (buffer, vec)) { ! 189: case 0: ! 190: break; ! 191: ! 192: case 2: ! 193: if (read_name (vec[0], vec[1]) == NOTOK) ! 194: return NOTOK; ! 195: break; ! 196: ! 197: case 5: ! 198: if (read_type (vec) == NOTOK) ! 199: return NOTOK; ! 200: break; ! 201: ! 202: default: ! 203: (void) sprintf (PY_pepy, "malformed line: \"%s\"", line); ! 204: return NOTOK; ! 205: } ! 206: } ! 207: ! 208: (void) fclose (fp); ! 209: ! 210: hit = 1, oz = NULLOT; ! 211: do { ! 212: if (!hit) { ! 213: (void) sprintf (PY_pepy, "unable to resolve object \"%s\"", ! 214: oz -> ot_text); ! 215: return NOTOK; ! 216: } ! 217: ! 218: again = hit = 0; ! 219: ! 220: for (i = 0; i < TBUCKETS; i++) ! 221: for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) ! 222: if (ot -> ot_name == NULLOID) ! 223: if (ot -> ot_name = resolve (ot -> ot_id, ot)) ! 224: hit = 1; ! 225: else ! 226: oz = ot, again = 1; ! 227: } while (again); ! 228: ! 229: #ifdef notdef ! 230: dump_objects_by_text (); ! 231: #endif ! 232: ! 233: j = 0; ! 234: for (i = 0; i < TBUCKETS; i++) ! 235: for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) ! 236: j++; ! 237: ! 238: /* j > 1 ALWAYS */ ! 239: ! 240: if ((base = (OT *) malloc ((unsigned) (j * sizeof *base))) == NULL) { ! 241: (void) sprintf (PY_pepy, "out of memory"); ! 242: return NOTOK; ! 243: } ! 244: ! 245: op = base; ! 246: for (i = 0; i < TBUCKETS; i++) ! 247: for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) ! 248: *op++ = ot; ! 249: ep = op; ! 250: ! 251: PY_pepy[0] = NULL; ! 252: qsort ((char *) base, j, sizeof *base, ot_compar); ! 253: ! 254: op = base; ! 255: anchor = ot = *op++; ! 256: while (op < ep) { ! 257: ot -> ot_next = *op; ! 258: ot = *op++; ! 259: } ! 260: (chain = ot) -> ot_next = NULL; ! 261: ! 262: free ((char *) base); ! 263: ! 264: return (PY_pepy[0] ? NOTOK : OK); ! 265: } ! 266: ! 267: /* */ ! 268: ! 269: static int read_name (name, value) ! 270: char *name, ! 271: *value; ! 272: { ! 273: int i; ! 274: register OT ot; ! 275: ! 276: if (text2obj (name)) { ! 277: (void) sprintf (PY_pepy, "duplicate object \"%s\"", name); ! 278: return NOTOK; ! 279: } ! 280: ! 281: if ((ot = (OT) calloc (1, sizeof *ot)) == NULL) { ! 282: (void) sprintf (PY_pepy, "out of memory"); ! 283: return NOTOK; ! 284: } ! 285: if ((ot -> ot_text = strdup (name)) == NULL ! 286: || (ot -> ot_id = strdup (value)) == NULL) { ! 287: (void) sprintf (PY_pepy, "out of memory"); ! 288: return NOTOK; ! 289: } ! 290: ! 291: ot -> ot_chain = Tbuckets[i = THASH (name)]; ! 292: Tbuckets[i] = ot; ! 293: ! 294: return OK; ! 295: } ! 296: ! 297: /* */ ! 298: ! 299: static int read_type (vec) ! 300: char **vec; ! 301: { ! 302: int i; ! 303: register OT ot; ! 304: ! 305: if (text2obj (*vec)) { ! 306: (void) sprintf (PY_pepy, "duplicate object \"%s\"", *vec); ! 307: return NOTOK; ! 308: } ! 309: ! 310: if ((ot = (OT) calloc (1, sizeof *ot)) == NULL) { ! 311: (void) sprintf (PY_pepy, "out of memory"); ! 312: return NOTOK; ! 313: } ! 314: if ((ot -> ot_text = strdup (*vec++)) == NULL ! 315: || (ot -> ot_id = strdup (*vec++)) == NULL) { ! 316: (void) sprintf (PY_pepy, "out of memory"); ! 317: return NOTOK; ! 318: } ! 319: if ((ot -> ot_syntax = text2syn (*vec)) == NULL ! 320: && lexequ (*vec, "Aggregate") ! 321: && debug) ! 322: fprintf (stderr, ! 323: "warning: object \"%s\" has unknown SYNTAX \"%s\"\n", ! 324: ot -> ot_text, *vec); ! 325: vec++; ! 326: ! 327: if (lexequ (*vec, "read-only") == 0) ! 328: ot -> ot_access = OT_RDONLY; ! 329: else ! 330: if (lexequ (*vec, "read-write") == 0) ! 331: ot -> ot_access = OT_RDWRITE; ! 332: else ! 333: if (lexequ (*vec, "write-only") == 0) ! 334: ot -> ot_access = OT_WRONLY; ! 335: else ! 336: if (lexequ (*vec, "not-accessible") && debug) ! 337: fprintf (stderr, ! 338: "warning: object \"%s\" has unknown ACCESS \"%s\"\n", ! 339: ot -> ot_text, *vec); ! 340: vec++; ! 341: ! 342: if (lexequ (*vec, "mandatory") == 0) ! 343: ot -> ot_status = OT_MANDATORY; ! 344: else ! 345: if (lexequ (*vec, "optional") == 0) ! 346: ot -> ot_status = OT_OPTIONAL; ! 347: else ! 348: if (lexequ (*vec, "deprecated") == 0) ! 349: ot -> ot_status = OT_DEPRECATED; ! 350: else ! 351: if (lexequ (*vec, "obsolete") && debug) ! 352: fprintf (stderr, ! 353: "warning: object \"%s\" has unknown STATUS \"%s\"\n", ! 354: ot -> ot_text, *vec); ! 355: vec++; ! 356: ! 357: ot -> ot_chain = Tbuckets[i = THASH (ot -> ot_text)]; ! 358: Tbuckets[i] = ot; ! 359: ! 360: return OK; ! 361: } ! 362: ! 363: /* */ ! 364: ! 365: /* does not insert into THASH table... */ ! 366: ! 367: int add_objects (ot) ! 368: register OT ot; ! 369: { ! 370: register OID oid = ot -> ot_name; ! 371: register OT ot2, ! 372: *otp; ! 373: ! 374: if (oid_cmp (chain -> ot_name, oid) < 0) { ! 375: chain -> ot_next = ot; ! 376: (chain = ot) -> ot_next = NULLOT; ! 377: } ! 378: else { ! 379: for (otp = &anchor; ot2 = *otp; otp = &ot2 -> ot_next) ! 380: if (oid_cmp (ot2 -> ot_name, oid) > 0) ! 381: break; ! 382: ot -> ot_next = ot2; ! 383: *otp = ot; ! 384: } ! 385: ! 386: for (ot = anchor; ot; ot = ot -> ot_next) ! 387: ot -> ot_sibling = ot -> ot_children = NULLOT; ! 388: ! 389: for (ot = anchor; ot; ot = ot -> ot_next) { ! 390: OIDentifier oids; ! 391: ! 392: if (ot -> ot_name -> oid_nelem <= 1) ! 393: continue; ! 394: ot2 = NULLOT; ! 395: for (oids.oid_elements = ot -> ot_name -> oid_elements, ! 396: oids.oid_nelem = ot -> ot_name -> oid_nelem - 1; ! 397: oids.oid_nelem > 0; ! 398: oids.oid_nelem--) ! 399: if (ot2 = name2obj (&oids)) ! 400: break; ! 401: if (ot2) { ! 402: ot -> ot_sibling = ot2 -> ot_children; ! 403: ot2 -> ot_children = ot; ! 404: } ! 405: else ! 406: if (debug) ! 407: fprintf (stderr, "no distant parent for %s", ! 408: sprintoid (ot -> ot_name)); ! 409: } ! 410: } ! 411: ! 412: /* */ ! 413: ! 414: OID text2oid (name) ! 415: char *name; ! 416: { ! 417: int i, ! 418: j; ! 419: register unsigned int *ip, ! 420: *jp; ! 421: unsigned int elements[NELEM + 1]; ! 422: register char *cp; ! 423: OID oid, ! 424: new; ! 425: ! 426: for (cp = name + strlen (name) - 1; cp >= name; cp--) ! 427: if (!isdigit (*cp) && *cp != '.') ! 428: break; ! 429: cp++; ! 430: if (isdigit (*cp) && cp != name) ! 431: for (cp++; *cp; cp++) ! 432: if (*cp == '.') ! 433: break; ! 434: ! 435: if (*cp == NULL) /* name */ ! 436: i = 0; ! 437: else ! 438: if (cp == name) { /* 1.3.6.1.2.1.1.1.0 */ ! 439: if ((i = str2elem (cp, elements)) < 2) ! 440: return NULL; ! 441: } ! 442: else /* name.numbers */ ! 443: if ((i = str2elem (cp + 1, elements)) < 1) ! 444: return NULL; ! 445: ! 446: if (cp != name) { ! 447: *cp = NULL; ! 448: if ((oid = resolve (name, NULLOT)) == NULLOID) ! 449: return NULL; ! 450: if (i == 0) ! 451: return oid; ! 452: ! 453: j = oid -> oid_nelem; ! 454: } ! 455: else ! 456: oid = NULL, j = 0; ! 457: ! 458: if ((new = (OID) malloc (sizeof *new)) == NULLOID) { ! 459: oid_free (oid); ! 460: return NULL; ! 461: } ! 462: if ((ip = (unsigned int *) malloc ((unsigned) (i + j + 1) * sizeof *ip)) ! 463: == NULL) { ! 464: oid_free (oid); ! 465: free ((char *) new); ! 466: } ! 467: new -> oid_elements = ip, new -> oid_nelem = i + j; ! 468: ! 469: if (oid) { ! 470: for (j = 0, jp = oid -> oid_elements; j < oid -> oid_nelem; j++, jp++) ! 471: *ip++ = *jp; ! 472: ! 473: oid_free (oid); ! 474: } ! 475: if (i > 0) ! 476: for (j = 0, jp = elements; j < i; j++, jp++) ! 477: *ip++ = *jp; ! 478: ! 479: new -> oid_nelem = ip - new -> oid_elements; ! 480: ! 481: return new; ! 482: } ! 483: ! 484: ! 485: static OID resolve (id, ot) ! 486: char *id; ! 487: register OT ot; ! 488: { ! 489: int i; ! 490: unsigned int elements[NELEM + 1]; ! 491: register char *cp; ! 492: register OT ot2; ! 493: struct OIDentifier oids; ! 494: register OID oid = &oids; ! 495: ! 496: oid -> oid_elements = elements; ! 497: ! 498: if (cp = index (id, '.')) ! 499: *cp = NULL; ! 500: if (isdigit (*id)) { ! 501: ot2 = NULLOT; ! 502: oid -> oid_nelem = 1; ! 503: oid -> oid_elements[0] = atoi (id); ! 504: if (cp) ! 505: *cp = '.'; ! 506: } ! 507: else { ! 508: ot2 = text2obj (id); ! 509: if (cp) ! 510: *cp = '.'; ! 511: if (ot2 == NULLOT || ot2 -> ot_name == NULLOID) ! 512: return NULLOID; ! 513: ! 514: oid -> oid_nelem = ot2 -> ot_name -> oid_nelem; ! 515: bcopy ((char *) ot2 -> ot_name -> oid_elements, ! 516: (char *) oid -> oid_elements, ! 517: oid -> oid_nelem * sizeof *elements); ! 518: } ! 519: ! 520: if (cp) { ! 521: if ((i = str2elem (++cp, oid -> oid_elements + oid -> oid_nelem)) < 1) ! 522: return NULLOID; ! 523: oid -> oid_nelem += i; ! 524: if (ot && ot2) { /* XXX: not normalized... */ ! 525: ot -> ot_sibling = ot2 -> ot_children; ! 526: ot2 -> ot_children = ot; ! 527: } ! 528: } ! 529: ! 530: return oid_cpy (oid); ! 531: } ! 532: ! 533: /* */ ! 534: ! 535: /* partial matches are made only on leaf nodes... */ ! 536: ! 537: OT name2obj (oid) ! 538: OID oid; ! 539: { ! 540: register int i, ! 541: j; ! 542: register unsigned *ip; ! 543: register OID nm; ! 544: register OT ot; ! 545: ! 546: if (oid == NULLOID ! 547: || oid -> oid_nelem < 1 ! 548: || (i = (ip = oid -> oid_elements)[0]) ! 549: >= (sizeof roots / sizeof roots[0]) ! 550: || (ot = text2obj (roots[i])) == NULL) ! 551: return NULLOT; ! 552: ! 553: i = 0; ! 554: while (ot) { ! 555: if ((j = (nm = ot -> ot_name) -> oid_nelem) > oid -> oid_nelem) ! 556: return NULLOT; ! 557: ! 558: if (bcmp ((char *) ip, (char *) (nm -> oid_elements + i), ! 559: (j - i) * sizeof *ip)) ! 560: ot = ot -> ot_sibling; ! 561: else ! 562: if (oid -> oid_nelem == j ! 563: || ot -> ot_children == NULLOT ! 564: || ot -> ot_smux) ! 565: break; ! 566: else { ! 567: ot = ot -> ot_children; ! 568: ip = oid -> oid_elements + j, i = j; ! 569: } ! 570: } ! 571: ! 572: return ot; ! 573: } ! 574: ! 575: /* */ ! 576: ! 577: OT text2obj (text) ! 578: char *text; ! 579: { ! 580: register OT ot; ! 581: ! 582: if (text == NULL || once_only == 0) ! 583: return NULLOT; ! 584: ! 585: for (ot = Tbuckets[THASH (text)]; ! 586: ot && strcmp (ot -> ot_text, text); ! 587: ot = ot -> ot_chain) ! 588: continue; ! 589: ! 590: return ot; ! 591: } ! 592: ! 593: /* */ ! 594: ! 595: /* ARGSUSED */ ! 596: ! 597: char *oid2ode_aux (oid, quoted) ! 598: OID oid; ! 599: int quoted; ! 600: { ! 601: register int i; ! 602: register char *bp; ! 603: register unsigned int *ip; ! 604: register OID oid2; ! 605: register OT ot; ! 606: static char buffer[BUFSIZ]; ! 607: ! 608: if ((oid -> oid_nelem == 2 /* XXX: 0.0 is a special case */ ! 609: && oid -> oid_elements[0] == 0 ! 610: && oid -> oid_elements[1] == 0) ! 611: || (ot = name2obj (oid)) == NULLOT) ! 612: return sprintoid (oid); ! 613: ! 614: (void) strcpy (bp = buffer, ot -> ot_text); ! 615: bp += strlen (bp); ! 616: for (ip = oid -> oid_elements + (oid2 = ot -> ot_name) -> oid_nelem, ! 617: i = oid -> oid_nelem - oid2 -> oid_nelem; ! 618: i-- > 0; ! 619: ip++) { ! 620: (void) sprintf (bp, ".%u", *ip); ! 621: bp += strlen (bp); ! 622: } ! 623: ! 624: return buffer; ! 625: } ! 626: ! 627: /* */ ! 628: ! 629: OI name2inst (oid) ! 630: OID oid; ! 631: { ! 632: static object_instance ois; ! 633: register OI oi = &ois; ! 634: ! 635: if ((oi -> oi_type = name2obj (oi -> oi_name = oid)) == NULLOT) ! 636: return NULLOI; ! 637: ! 638: return oi; ! 639: } ! 640: ! 641: ! 642: OI next2inst (oid) ! 643: OID oid; ! 644: { ! 645: static object_instance ois; ! 646: register OI oi = &ois; ! 647: register OT ot; ! 648: ! 649: for (ot = anchor; ot; ot = ot -> ot_next) { ! 650: if (ot -> ot_smux) { ! 651: if (oid -> oid_nelem < ot -> ot_name -> oid_nelem ! 652: || bcmp ((char *) oid -> oid_elements, ! 653: (char *) ot -> ot_name -> oid_elements, ! 654: ot -> ot_name -> oid_nelem ! 655: * sizeof oid -> oid_elements[0])) ! 656: continue; ! 657: } ! 658: else ! 659: if (oid_cmp (oid, ot -> ot_name) > 0) ! 660: continue; ! 661: ! 662: oi -> oi_name = (oi -> oi_type = ot) -> ot_name; ! 663: return oi; ! 664: } ! 665: ! 666: return NULLOI; ! 667: } ! 668: ! 669: /* */ ! 670: ! 671: OI text2inst (text) ! 672: char *text; ! 673: { ! 674: static object_instance ois; ! 675: register OI oi = &ois; ! 676: static OID oid = NULLOID; ! 677: ! 678: if (oid) ! 679: oid_free (oid), oid = NULLOID; ! 680: ! 681: if ((oid = text2oid (text)) == NULLOID) ! 682: return NULLOI; ! 683: if ((oi -> oi_type = name2obj (oi -> oi_name = oid)) == NULLOT) { ! 684: if (debug) ! 685: fprintf (stderr, "got name \"%s\", but not object\n", text); ! 686: return NULLOI; ! 687: } ! 688: ! 689: return oi; ! 690: } ! 691: ! 692: /* DUMP */ ! 693: ! 694: #ifdef DEBUG ! 695: dump_objects_by_text () ! 696: { ! 697: int hit; ! 698: register int i; ! 699: register OT ot; ! 700: ! 701: for (i = 0; i < TBUCKETS; i++) { ! 702: hit = 0; ! 703: for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) { ! 704: if (!hit) ! 705: printf ("Bucket %d:\n", i), hit = 1; ! 706: dump_object (ot, 2); ! 707: } ! 708: } ! 709: ! 710: printf ("///////\n"); ! 711: } ! 712: ! 713: ! 714: dump_objects_by_tree () ! 715: { ! 716: register char **ap; ! 717: char **bp; ! 718: register OT ot; ! 719: ! 720: for (bp = (ap = roots) + (sizeof roots / sizeof roots[0]); ap < bp; ap++) { ! 721: if (ot = text2obj (*ap)) ! 722: dump_object_by_tree (ot, 0); ! 723: else ! 724: printf ("no object for root \"%s\"\n", *ap); ! 725: } ! 726: ! 727: printf ("///////\n"); ! 728: } ! 729: ! 730: ! 731: dump_object_by_tree (ot, i) ! 732: register OT ot; ! 733: int i; ! 734: { ! 735: if (ot == NULL) ! 736: return; ! 737: ! 738: dump_object (ot, i); ! 739: dump_object_by_tree (ot -> ot_children, i + 1); ! 740: dump_object_by_tree (ot -> ot_sibling, i); ! 741: } ! 742: ! 743: ! 744: dump_objects_by_xxx () ! 745: { ! 746: register OT ot; ! 747: ! 748: for (ot = anchor; ot; ot = ot -> ot_next) ! 749: dump_object (ot, 0); ! 750: ! 751: printf ("///////\n"); ! 752: } ! 753: ! 754: ! 755: static dump_object (ot, i) ! 756: register OT ot; ! 757: int i; ! 758: { ! 759: printf ("%*.*s%s %s %s %s %d %d 0x%x\n", i, i, "", ! 760: ot -> ot_text, ot -> ot_id, sprintoid (ot -> ot_name), ! 761: ot -> ot_syntax ? ot -> ot_syntax -> os_name : "NULL", ! 762: ot -> ot_access, ot -> ot_status, ot -> ot_smux); ! 763: } ! 764: #endif ! 765: ! 766: /* MISCELLANY */ ! 767: ! 768: char *strdup (s) ! 769: char *s; ! 770: { ! 771: char *p; ! 772: ! 773: if (p = malloc ((unsigned) (strlen (s) + 1))) ! 774: (void) strcpy (p, s); ! 775: ! 776: return p; ! 777: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.