Annotation of embedaddon/dhcp/common/print.c, revision 1.1
1.1 ! misho 1: /* print.c
! 2:
! 3: Turn data structures into printable text. */
! 4:
! 5: /*
! 6: * Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC")
! 7: * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
! 8: * Copyright (c) 1995-2003 by Internet Software Consortium
! 9: *
! 10: * Permission to use, copy, modify, and distribute this software for any
! 11: * purpose with or without fee is hereby granted, provided that the above
! 12: * copyright notice and this permission notice appear in all copies.
! 13: *
! 14: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
! 15: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 16: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
! 17: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 18: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 19: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 20: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 21: *
! 22: * Internet Systems Consortium, Inc.
! 23: * 950 Charter Street
! 24: * Redwood City, CA 94063
! 25: * <info@isc.org>
! 26: * https://www.isc.org/
! 27: *
! 28: * This software has been written for Internet Systems Consortium
! 29: * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
! 30: * To learn more about Internet Systems Consortium, see
! 31: * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
! 32: * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
! 33: * ``http://www.nominum.com''.
! 34: */
! 35:
! 36: #include "dhcpd.h"
! 37:
! 38: int db_time_format = DEFAULT_TIME_FORMAT;
! 39:
! 40: char *quotify_string (const char *s, const char *file, int line)
! 41: {
! 42: unsigned len = 0;
! 43: const char *sp;
! 44: char *buf, *nsp;
! 45:
! 46: for (sp = s; sp && *sp; sp++) {
! 47: if (*sp == ' ')
! 48: len++;
! 49: else if (!isascii ((int)*sp) || !isprint ((int)*sp))
! 50: len += 4;
! 51: else if (*sp == '"' || *sp == '\\')
! 52: len += 2;
! 53: else
! 54: len++;
! 55: }
! 56:
! 57: buf = dmalloc (len + 1, file, line);
! 58: if (buf) {
! 59: nsp = buf;
! 60: for (sp = s; sp && *sp; sp++) {
! 61: if (*sp == ' ')
! 62: *nsp++ = ' ';
! 63: else if (!isascii ((int)*sp) || !isprint ((int)*sp)) {
! 64: sprintf (nsp, "\\%03o",
! 65: *(const unsigned char *)sp);
! 66: nsp += 4;
! 67: } else if (*sp == '"' || *sp == '\\') {
! 68: *nsp++ = '\\';
! 69: *nsp++ = *sp;
! 70: } else
! 71: *nsp++ = *sp;
! 72: }
! 73: *nsp++ = 0;
! 74: }
! 75: return buf;
! 76: }
! 77:
! 78: char *quotify_buf (const unsigned char *s, unsigned len,
! 79: const char *file, int line)
! 80: {
! 81: unsigned nulen = 0;
! 82: char *buf, *nsp;
! 83: int i;
! 84:
! 85: for (i = 0; i < len; i++) {
! 86: if (s [i] == ' ')
! 87: nulen++;
! 88: else if (!isascii (s [i]) || !isprint (s [i]))
! 89: nulen += 4;
! 90: else if (s [i] == '"' || s [i] == '\\')
! 91: nulen += 2;
! 92: else
! 93: nulen++;
! 94: }
! 95:
! 96: buf = dmalloc (nulen + 1, MDL);
! 97: if (buf) {
! 98: nsp = buf;
! 99: for (i = 0; i < len; i++) {
! 100: if (s [i] == ' ')
! 101: *nsp++ = ' ';
! 102: else if (!isascii (s [i]) || !isprint (s [i])) {
! 103: sprintf (nsp, "\\%03o", s [i]);
! 104: nsp += 4;
! 105: } else if (s [i] == '"' || s [i] == '\\') {
! 106: *nsp++ = '\\';
! 107: *nsp++ = s [i];
! 108: } else
! 109: *nsp++ = s [i];
! 110: }
! 111: *nsp++ = 0;
! 112: }
! 113: return buf;
! 114: }
! 115:
! 116: char *print_base64 (const unsigned char *buf, unsigned len,
! 117: const char *file, int line)
! 118: {
! 119: char *s, *b;
! 120: unsigned bl;
! 121: int i;
! 122: unsigned val, extra;
! 123: static char to64 [] =
! 124: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
! 125:
! 126: bl = ((len * 4 + 2) / 3) + 1;
! 127: b = dmalloc (bl + 1, file, line);
! 128: if (!b)
! 129: return (char *)0;
! 130:
! 131: i = 0;
! 132: s = b;
! 133: while (i != len) {
! 134: val = buf [i++];
! 135: extra = val & 3;
! 136: val = val >> 2;
! 137: *s++ = to64 [val];
! 138: if (i == len) {
! 139: *s++ = to64 [extra << 4];
! 140: *s++ = '=';
! 141: break;
! 142: }
! 143: val = (extra << 8) + buf [i++];
! 144: extra = val & 15;
! 145: val = val >> 4;
! 146: *s++ = to64 [val];
! 147: if (i == len) {
! 148: *s++ = to64 [extra << 2];
! 149: *s++ = '=';
! 150: break;
! 151: }
! 152: val = (extra << 8) + buf [i++];
! 153: extra = val & 0x3f;
! 154: val = val >> 6;
! 155: *s++ = to64 [val];
! 156: *s++ = to64 [extra];
! 157: }
! 158: if (!len)
! 159: *s++ = '=';
! 160: *s++ = 0;
! 161: if (s > b + bl + 1)
! 162: abort ();
! 163: return b;
! 164: }
! 165:
! 166: char *print_hw_addr (htype, hlen, data)
! 167: int htype;
! 168: int hlen;
! 169: unsigned char *data;
! 170: {
! 171: static char habuf [49];
! 172: char *s;
! 173: int i;
! 174:
! 175: if (hlen <= 0)
! 176: habuf [0] = 0;
! 177: else {
! 178: s = habuf;
! 179: for (i = 0; i < hlen; i++) {
! 180: sprintf (s, "%02x", data [i]);
! 181: s += strlen (s);
! 182: *s++ = ':';
! 183: }
! 184: *--s = 0;
! 185: }
! 186: return habuf;
! 187: }
! 188:
! 189: void print_lease (lease)
! 190: struct lease *lease;
! 191: {
! 192: struct tm *t;
! 193: char tbuf [32];
! 194:
! 195: log_debug (" Lease %s",
! 196: piaddr (lease -> ip_addr));
! 197:
! 198: t = gmtime (&lease -> starts);
! 199: strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
! 200: log_debug (" start %s", tbuf);
! 201:
! 202: t = gmtime (&lease -> ends);
! 203: strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
! 204: log_debug (" end %s", tbuf);
! 205:
! 206: if (lease -> hardware_addr.hlen)
! 207: log_debug (" hardware addr = %s",
! 208: print_hw_addr (lease -> hardware_addr.hbuf [0],
! 209: lease -> hardware_addr.hlen - 1,
! 210: &lease -> hardware_addr.hbuf [1]));
! 211: log_debug (" host %s ",
! 212: lease -> host ? lease -> host -> name : "<none>");
! 213: }
! 214:
! 215: #if defined (DEBUG_PACKET)
! 216: void dump_packet_option (struct option_cache *oc,
! 217: struct packet *packet,
! 218: struct lease *lease,
! 219: struct client_state *client,
! 220: struct option_state *in_options,
! 221: struct option_state *cfg_options,
! 222: struct binding_scope **scope,
! 223: struct universe *u, void *foo)
! 224: {
! 225: const char *name, *dot;
! 226: struct data_string ds;
! 227: memset (&ds, 0, sizeof ds);
! 228:
! 229: if (u != &dhcp_universe) {
! 230: name = u -> name;
! 231: dot = ".";
! 232: } else {
! 233: name = "";
! 234: dot = "";
! 235: }
! 236: if (evaluate_option_cache (&ds, packet, lease, client,
! 237: in_options, cfg_options, scope, oc, MDL)) {
! 238: log_debug (" option %s%s%s %s;\n",
! 239: name, dot, oc -> option -> name,
! 240: pretty_print_option (oc -> option,
! 241: ds.data, ds.len, 1, 1));
! 242: data_string_forget (&ds, MDL);
! 243: }
! 244: }
! 245:
! 246: void dump_packet (tp)
! 247: struct packet *tp;
! 248: {
! 249: struct dhcp_packet *tdp = tp -> raw;
! 250:
! 251: log_debug ("packet length %d", tp -> packet_length);
! 252: log_debug ("op = %d htype = %d hlen = %d hops = %d",
! 253: tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
! 254: log_debug ("xid = %x secs = %ld flags = %x",
! 255: tdp -> xid, (unsigned long)tdp -> secs, tdp -> flags);
! 256: log_debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr));
! 257: log_debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
! 258: log_debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
! 259: log_debug ("giaddr = %s", inet_ntoa (tdp -> giaddr));
! 260: log_debug ("chaddr = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
! 261: ((unsigned char *)(tdp -> chaddr)) [0],
! 262: ((unsigned char *)(tdp -> chaddr)) [1],
! 263: ((unsigned char *)(tdp -> chaddr)) [2],
! 264: ((unsigned char *)(tdp -> chaddr)) [3],
! 265: ((unsigned char *)(tdp -> chaddr)) [4],
! 266: ((unsigned char *)(tdp -> chaddr)) [5]);
! 267: log_debug ("filename = %s", tdp -> file);
! 268: log_debug ("server_name = %s", tdp -> sname);
! 269: if (tp -> options_valid) {
! 270: int i;
! 271:
! 272: for (i = 0; i < tp -> options -> universe_count; i++) {
! 273: if (tp -> options -> universes [i]) {
! 274: option_space_foreach (tp, (struct lease *)0,
! 275: (struct client_state *)0,
! 276: (struct option_state *)0,
! 277: tp -> options,
! 278: &global_scope,
! 279: universes [i], 0,
! 280: dump_packet_option);
! 281: }
! 282: }
! 283: }
! 284: log_debug ("%s", "");
! 285: }
! 286: #endif
! 287:
! 288: void dump_raw (buf, len)
! 289: const unsigned char *buf;
! 290: unsigned len;
! 291: {
! 292: int i;
! 293: char lbuf [80];
! 294: int lbix = 0;
! 295:
! 296: /*
! 297: 1 2 3 4 5 6 7
! 298: 01234567890123456789012345678901234567890123456789012345678901234567890123
! 299: 280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
! 300: */
! 301:
! 302: memset(lbuf, ' ', 79);
! 303: lbuf [79] = 0;
! 304:
! 305: for (i = 0; i < len; i++) {
! 306: if ((i & 15) == 0) {
! 307: if (lbix) {
! 308: lbuf[53]=' ';
! 309: lbuf[54]=' ';
! 310: lbuf[55]=' ';
! 311: lbuf[73]='\0';
! 312: log_info ("%s", lbuf);
! 313: }
! 314: memset(lbuf, ' ', 79);
! 315: lbuf [79] = 0;
! 316: sprintf (lbuf, "%03x:", i);
! 317: lbix = 4;
! 318: } else if ((i & 7) == 0)
! 319: lbuf [lbix++] = ' ';
! 320:
! 321: if(isprint(buf[i])) {
! 322: lbuf[56+(i%16)]=buf[i];
! 323: } else {
! 324: lbuf[56+(i%16)]='.';
! 325: }
! 326:
! 327: sprintf (&lbuf [lbix], " %02x", buf [i]);
! 328: lbix += 3;
! 329: lbuf[lbix]=' ';
! 330:
! 331: }
! 332: lbuf[53]=' ';
! 333: lbuf[54]=' ';
! 334: lbuf[55]=' ';
! 335: lbuf[73]='\0';
! 336: log_info ("%s", lbuf);
! 337: }
! 338:
! 339: void hash_dump (table)
! 340: struct hash_table *table;
! 341: {
! 342: int i;
! 343: struct hash_bucket *bp;
! 344:
! 345: if (!table)
! 346: return;
! 347:
! 348: for (i = 0; i < table -> hash_count; i++) {
! 349: if (!table -> buckets [i])
! 350: continue;
! 351: log_info ("hash bucket %d:", i);
! 352: for (bp = table -> buckets [i]; bp; bp = bp -> next) {
! 353: if (bp -> len)
! 354: dump_raw (bp -> name, bp -> len);
! 355: else
! 356: log_info ("%s", (const char *)bp -> name);
! 357: }
! 358: }
! 359: }
! 360:
! 361: /*
! 362: * print a string as hex. This only outputs
! 363: * colon separated hex list no matter what
! 364: * the input looks like. See print_hex
! 365: * for a function that prints either cshl
! 366: * or a string if all bytes are printible
! 367: * It only uses limit characters from buf
! 368: * and doesn't do anything if buf == NULL
! 369: *
! 370: * len - length of data
! 371: * data - input data
! 372: * limit - length of buf to use
! 373: * buf - output buffer
! 374: */
! 375: void print_hex_only (len, data, limit, buf)
! 376: unsigned len;
! 377: const u_int8_t *data;
! 378: unsigned limit;
! 379: char *buf;
! 380: {
! 381: unsigned i;
! 382:
! 383: if ((buf == NULL) || (limit < 3))
! 384: return;
! 385:
! 386: for (i = 0; (i < limit / 3) && (i < len); i++) {
! 387: sprintf(&buf[i*3], "%02x:", data[i]);
! 388: }
! 389: buf[(i * 3) - 1] = 0;
! 390: return;
! 391: }
! 392:
! 393: /*
! 394: * print a string as either text if all the characters
! 395: * are printable or colon separated hex if they aren't
! 396: *
! 397: * len - length of data
! 398: * data - input data
! 399: * limit - length of buf to use
! 400: * buf - output buffer
! 401: */
! 402: void print_hex_or_string (len, data, limit, buf)
! 403: unsigned len;
! 404: const u_int8_t *data;
! 405: unsigned limit;
! 406: char *buf;
! 407: {
! 408: unsigned i;
! 409: if ((buf == NULL) || (limit < 3))
! 410: return;
! 411:
! 412: for (i = 0; (i < (limit - 3)) && (i < len); i++) {
! 413: if (!isascii(data[i]) || !isprint(data[i])) {
! 414: print_hex_only(len, data, limit, buf);
! 415: return;
! 416: }
! 417: }
! 418:
! 419: buf[0] = '"';
! 420: i = len;
! 421: if (i > (limit - 3))
! 422: i = limit - 3;
! 423: memcpy(&buf[1], data, i);
! 424: buf[i + 1] = '"';
! 425: buf[i + 2] = 0;
! 426: return;
! 427: }
! 428:
! 429: /*
! 430: * print a string as either hex or text
! 431: * using static buffers to hold the output
! 432: *
! 433: * len - length of data
! 434: * data - input data
! 435: * limit - length of buf
! 436: * buf_num - the output buffer to use
! 437: */
! 438: #define HBLEN 1024
! 439: char *print_hex(len, data, limit, buf_num)
! 440: unsigned len;
! 441: const u_int8_t *data;
! 442: unsigned limit;
! 443: unsigned buf_num;
! 444: {
! 445: static char hex_buf_1[HBLEN + 1];
! 446: static char hex_buf_2[HBLEN + 1];
! 447: static char hex_buf_3[HBLEN + 1];
! 448: char *hex_buf;
! 449:
! 450: switch(buf_num) {
! 451: case 0:
! 452: hex_buf = hex_buf_1;
! 453: if (limit >= sizeof(hex_buf_1))
! 454: limit = sizeof(hex_buf_1);
! 455: break;
! 456: case 1:
! 457: hex_buf = hex_buf_2;
! 458: if (limit >= sizeof(hex_buf_2))
! 459: limit = sizeof(hex_buf_2);
! 460: break;
! 461: case 2:
! 462: hex_buf = hex_buf_3;
! 463: if (limit >= sizeof(hex_buf_3))
! 464: limit = sizeof(hex_buf_3);
! 465: break;
! 466: default:
! 467: return(NULL);
! 468: }
! 469:
! 470: print_hex_or_string(len, data, limit, hex_buf);
! 471: return(hex_buf);
! 472: }
! 473:
! 474: #define DQLEN 80
! 475:
! 476: char *print_dotted_quads (len, data)
! 477: unsigned len;
! 478: const u_int8_t *data;
! 479: {
! 480: static char dq_buf [DQLEN + 1];
! 481: int i;
! 482: char *s, *last;
! 483:
! 484: s = &dq_buf [0];
! 485: last = s;
! 486:
! 487: i = 0;
! 488:
! 489: /* %Audit% Loop bounds checks to 21 bytes. %2004.06.17,Safe%
! 490: * The sprintf can't exceed 18 bytes, and since the loop enforces
! 491: * 21 bytes of space per iteration at no time can we exit the
! 492: * loop without at least 3 bytes spare.
! 493: */
! 494: do {
! 495: sprintf (s, "%u.%u.%u.%u, ",
! 496: data [i], data [i + 1], data [i + 2], data [i + 3]);
! 497: s += strlen (s);
! 498: i += 4;
! 499: } while ((s - &dq_buf [0] > DQLEN - 21) &&
! 500: i + 3 < len);
! 501: if (i == len)
! 502: s [-2] = 0;
! 503: else
! 504: strcpy (s, "...");
! 505: return dq_buf;
! 506: }
! 507:
! 508: char *print_dec_1 (val)
! 509: unsigned long val;
! 510: {
! 511: static char vbuf [32];
! 512: sprintf (vbuf, "%lu", val);
! 513: return vbuf;
! 514: }
! 515:
! 516: char *print_dec_2 (val)
! 517: unsigned long val;
! 518: {
! 519: static char vbuf [32];
! 520: sprintf (vbuf, "%lu", val);
! 521: return vbuf;
! 522: }
! 523:
! 524: static unsigned print_subexpression (struct expression *, char *, unsigned);
! 525:
! 526: static unsigned print_subexpression (expr, buf, len)
! 527: struct expression *expr;
! 528: char *buf;
! 529: unsigned len;
! 530: {
! 531: unsigned rv, left;
! 532: const char *s;
! 533:
! 534: switch (expr -> op) {
! 535: case expr_none:
! 536: if (len > 3) {
! 537: strcpy (buf, "nil");
! 538: return 3;
! 539: }
! 540: break;
! 541:
! 542: case expr_match:
! 543: if (len > 7) {
! 544: strcpy (buf, "(match)");
! 545: return 7;
! 546: }
! 547: break;
! 548:
! 549: case expr_check:
! 550: rv = 10 + strlen (expr -> data.check -> name);
! 551: if (len > rv) {
! 552: sprintf (buf, "(check %s)",
! 553: expr -> data.check -> name);
! 554: return rv;
! 555: }
! 556: break;
! 557:
! 558: case expr_equal:
! 559: if (len > 6) {
! 560: rv = 4;
! 561: strcpy (buf, "(eq ");
! 562: rv += print_subexpression (expr -> data.equal [0],
! 563: buf + rv, len - rv - 2);
! 564: buf [rv++] = ' ';
! 565: rv += print_subexpression (expr -> data.equal [1],
! 566: buf + rv, len - rv - 1);
! 567: buf [rv++] = ')';
! 568: buf [rv] = 0;
! 569: return rv;
! 570: }
! 571: break;
! 572:
! 573: case expr_not_equal:
! 574: if (len > 7) {
! 575: rv = 5;
! 576: strcpy (buf, "(neq ");
! 577: rv += print_subexpression (expr -> data.equal [0],
! 578: buf + rv, len - rv - 2);
! 579: buf [rv++] = ' ';
! 580: rv += print_subexpression (expr -> data.equal [1],
! 581: buf + rv, len - rv - 1);
! 582: buf [rv++] = ')';
! 583: buf [rv] = 0;
! 584: return rv;
! 585: }
! 586: break;
! 587:
! 588: case expr_regex_match:
! 589: if (len > 10) {
! 590: rv = 4;
! 591: strcpy(buf, "(regex ");
! 592: rv += print_subexpression(expr->data.equal[0],
! 593: buf + rv, len - rv - 2);
! 594: buf[rv++] = ' ';
! 595: rv += print_subexpression(expr->data.equal[1],
! 596: buf + rv, len - rv - 1);
! 597: buf[rv++] = ')';
! 598: buf[rv] = 0;
! 599: return rv;
! 600: }
! 601: break;
! 602:
! 603: case expr_substring:
! 604: if (len > 11) {
! 605: rv = 8;
! 606: strcpy (buf, "(substr ");
! 607: rv += print_subexpression (expr -> data.substring.expr,
! 608: buf + rv, len - rv - 3);
! 609: buf [rv++] = ' ';
! 610: rv += print_subexpression
! 611: (expr -> data.substring.offset,
! 612: buf + rv, len - rv - 2);
! 613: buf [rv++] = ' ';
! 614: rv += print_subexpression (expr -> data.substring.len,
! 615: buf + rv, len - rv - 1);
! 616: buf [rv++] = ')';
! 617: buf [rv] = 0;
! 618: return rv;
! 619: }
! 620: break;
! 621:
! 622: case expr_suffix:
! 623: if (len > 10) {
! 624: rv = 8;
! 625: strcpy (buf, "(suffix ");
! 626: rv += print_subexpression (expr -> data.suffix.expr,
! 627: buf + rv, len - rv - 2);
! 628: if (len > rv)
! 629: buf [rv++] = ' ';
! 630: rv += print_subexpression (expr -> data.suffix.len,
! 631: buf + rv, len - rv - 1);
! 632: if (len > rv)
! 633: buf [rv++] = ')';
! 634: buf [rv] = 0;
! 635: return rv;
! 636: }
! 637: break;
! 638:
! 639: case expr_lcase:
! 640: if (len > 9) {
! 641: rv = 7;
! 642: strcpy(buf, "(lcase ");
! 643: rv += print_subexpression(expr->data.lcase,
! 644: buf + rv, len - rv - 1);
! 645: buf[rv++] = ')';
! 646: buf[rv] = 0;
! 647: return rv;
! 648: }
! 649: break;
! 650:
! 651: case expr_ucase:
! 652: if (len > 9) {
! 653: rv = 7;
! 654: strcpy(buf, "(ucase ");
! 655: rv += print_subexpression(expr->data.ucase,
! 656: buf + rv, len - rv - 1);
! 657: buf[rv++] = ')';
! 658: buf[rv] = 0;
! 659: return rv;
! 660: }
! 661: break;
! 662:
! 663: case expr_concat:
! 664: if (len > 10) {
! 665: rv = 8;
! 666: strcpy (buf, "(concat ");
! 667: rv += print_subexpression (expr -> data.concat [0],
! 668: buf + rv, len - rv - 2);
! 669: buf [rv++] = ' ';
! 670: rv += print_subexpression (expr -> data.concat [1],
! 671: buf + rv, len - rv - 1);
! 672: buf [rv++] = ')';
! 673: buf [rv] = 0;
! 674: return rv;
! 675: }
! 676: break;
! 677:
! 678: case expr_pick_first_value:
! 679: if (len > 8) {
! 680: rv = 6;
! 681: strcpy (buf, "(pick1st ");
! 682: rv += print_subexpression
! 683: (expr -> data.pick_first_value.car,
! 684: buf + rv, len - rv - 2);
! 685: buf [rv++] = ' ';
! 686: rv += print_subexpression
! 687: (expr -> data.pick_first_value.cdr,
! 688: buf + rv, len - rv - 1);
! 689: buf [rv++] = ')';
! 690: buf [rv] = 0;
! 691: return rv;
! 692: }
! 693: break;
! 694:
! 695: case expr_host_lookup:
! 696: rv = 15 + strlen (expr -> data.host_lookup -> hostname);
! 697: if (len > rv) {
! 698: sprintf (buf, "(dns-lookup %s)",
! 699: expr -> data.host_lookup -> hostname);
! 700: return rv;
! 701: }
! 702: break;
! 703:
! 704: case expr_and:
! 705: s = "and";
! 706: binop:
! 707: rv = strlen (s);
! 708: if (len > rv + 4) {
! 709: buf [0] = '(';
! 710: strcpy (&buf [1], s);
! 711: rv += 1;
! 712: buf [rv++] = ' ';
! 713: rv += print_subexpression (expr -> data.and [0],
! 714: buf + rv, len - rv - 2);
! 715: buf [rv++] = ' ';
! 716: rv += print_subexpression (expr -> data.and [1],
! 717: buf + rv, len - rv - 1);
! 718: buf [rv++] = ')';
! 719: buf [rv] = 0;
! 720: return rv;
! 721: }
! 722: break;
! 723:
! 724: case expr_or:
! 725: s = "or";
! 726: goto binop;
! 727:
! 728: case expr_add:
! 729: s = "+";
! 730: goto binop;
! 731:
! 732: case expr_subtract:
! 733: s = "-";
! 734: goto binop;
! 735:
! 736: case expr_multiply:
! 737: s = "*";
! 738: goto binop;
! 739:
! 740: case expr_divide:
! 741: s = "/";
! 742: goto binop;
! 743:
! 744: case expr_remainder:
! 745: s = "%";
! 746: goto binop;
! 747:
! 748: case expr_binary_and:
! 749: s = "&";
! 750: goto binop;
! 751:
! 752: case expr_binary_or:
! 753: s = "|";
! 754: goto binop;
! 755:
! 756: case expr_binary_xor:
! 757: s = "^";
! 758: goto binop;
! 759:
! 760: case expr_not:
! 761: if (len > 6) {
! 762: rv = 5;
! 763: strcpy (buf, "(not ");
! 764: rv += print_subexpression (expr -> data.not,
! 765: buf + rv, len - rv - 1);
! 766: buf [rv++] = ')';
! 767: buf [rv] = 0;
! 768: return rv;
! 769: }
! 770: break;
! 771:
! 772: case expr_config_option:
! 773: s = "cfg-option";
! 774: goto dooption;
! 775:
! 776: case expr_option:
! 777: s = "option";
! 778: dooption:
! 779: rv = strlen (s) + 2 + (strlen (expr -> data.option -> name) +
! 780: strlen (expr -> data.option -> universe -> name));
! 781: if (len > rv) {
! 782: sprintf (buf, "(option %s.%s)",
! 783: expr -> data.option -> universe -> name,
! 784: expr -> data.option -> name);
! 785: return rv;
! 786: }
! 787: break;
! 788:
! 789: case expr_hardware:
! 790: if (len > 10) {
! 791: strcpy (buf, "(hardware)");
! 792: return 10;
! 793: }
! 794: break;
! 795:
! 796: case expr_packet:
! 797: if (len > 10) {
! 798: rv = 8;
! 799: strcpy (buf, "(substr ");
! 800: rv += print_subexpression (expr -> data.packet.offset,
! 801: buf + rv, len - rv - 2);
! 802: buf [rv++] = ' ';
! 803: rv += print_subexpression (expr -> data.packet.len,
! 804: buf + rv, len - rv - 1);
! 805: buf [rv++] = ')';
! 806: buf [rv] = 0;
! 807: return rv;
! 808: }
! 809: break;
! 810:
! 811: case expr_const_data:
! 812: s = print_hex_1 (expr -> data.const_data.len,
! 813: expr -> data.const_data.data, len);
! 814: rv = strlen (s);
! 815: if (rv >= len)
! 816: rv = len - 1;
! 817: strncpy (buf, s, rv);
! 818: buf [rv] = 0;
! 819: return rv;
! 820:
! 821: case expr_encapsulate:
! 822: rv = 13;
! 823: strcpy (buf, "(encapsulate ");
! 824: rv += expr -> data.encapsulate.len;
! 825: if (rv + 2 > len)
! 826: rv = len - 2;
! 827: strncpy (buf,
! 828: (const char *)expr -> data.encapsulate.data, rv - 13);
! 829: buf [rv++] = ')';
! 830: buf [rv++] = 0;
! 831: break;
! 832:
! 833: case expr_extract_int8:
! 834: if (len > 7) {
! 835: rv = 6;
! 836: strcpy (buf, "(int8 ");
! 837: rv += print_subexpression (expr -> data.extract_int,
! 838: buf + rv, len - rv - 1);
! 839: buf [rv++] = ')';
! 840: buf [rv] = 0;
! 841: return rv;
! 842: }
! 843: break;
! 844:
! 845: case expr_extract_int16:
! 846: if (len > 8) {
! 847: rv = 7;
! 848: strcpy (buf, "(int16 ");
! 849: rv += print_subexpression (expr -> data.extract_int,
! 850: buf + rv, len - rv - 1);
! 851: buf [rv++] = ')';
! 852: buf [rv] = 0;
! 853: return rv;
! 854: }
! 855: break;
! 856:
! 857: case expr_extract_int32:
! 858: if (len > 8) {
! 859: rv = 7;
! 860: strcpy (buf, "(int32 ");
! 861: rv += print_subexpression (expr -> data.extract_int,
! 862: buf + rv, len - rv - 1);
! 863: buf [rv++] = ')';
! 864: buf [rv] = 0;
! 865: return rv;
! 866: }
! 867: break;
! 868:
! 869: case expr_encode_int8:
! 870: if (len > 7) {
! 871: rv = 6;
! 872: strcpy (buf, "(to-int8 ");
! 873: rv += print_subexpression (expr -> data.encode_int,
! 874: buf + rv, len - rv - 1);
! 875: buf [rv++] = ')';
! 876: buf [rv] = 0;
! 877: return rv;
! 878: }
! 879: break;
! 880:
! 881: case expr_encode_int16:
! 882: if (len > 8) {
! 883: rv = 7;
! 884: strcpy (buf, "(to-int16 ");
! 885: rv += print_subexpression (expr -> data.encode_int,
! 886: buf + rv, len - rv - 1);
! 887: buf [rv++] = ')';
! 888: buf [rv] = 0;
! 889: return rv;
! 890: }
! 891: break;
! 892:
! 893: case expr_encode_int32:
! 894: if (len > 8) {
! 895: rv = 7;
! 896: strcpy (buf, "(to-int32 ");
! 897: rv += print_subexpression (expr -> data.encode_int,
! 898: buf + rv, len - rv - 1);
! 899: buf [rv++] = ')';
! 900: buf [rv] = 0;
! 901: return rv;
! 902: }
! 903: break;
! 904:
! 905: case expr_const_int:
! 906: s = print_dec_1 (expr -> data.const_int);
! 907: rv = strlen (s);
! 908: if (len > rv) {
! 909: strcpy (buf, s);
! 910: return rv;
! 911: }
! 912: break;
! 913:
! 914: case expr_exists:
! 915: rv = 10 + (strlen (expr -> data.option -> name) +
! 916: strlen (expr -> data.option -> universe -> name));
! 917: if (len > rv) {
! 918: sprintf (buf, "(exists %s.%s)",
! 919: expr -> data.option -> universe -> name,
! 920: expr -> data.option -> name);
! 921: return rv;
! 922: }
! 923: break;
! 924:
! 925: case expr_variable_exists:
! 926: rv = 10 + strlen (expr -> data.variable);
! 927: if (len > rv) {
! 928: sprintf (buf, "(defined %s)", expr -> data.variable);
! 929: return rv;
! 930: }
! 931: break;
! 932:
! 933: case expr_variable_reference:
! 934: rv = strlen (expr -> data.variable);
! 935: if (len > rv) {
! 936: sprintf (buf, "%s", expr -> data.variable);
! 937: return rv;
! 938: }
! 939: break;
! 940:
! 941: case expr_known:
! 942: s = "known";
! 943: astring:
! 944: rv = strlen (s);
! 945: if (len > rv) {
! 946: strcpy (buf, s);
! 947: return rv;
! 948: }
! 949: break;
! 950:
! 951: case expr_leased_address:
! 952: s = "leased-address";
! 953: goto astring;
! 954:
! 955: case expr_client_state:
! 956: s = "client-state";
! 957: goto astring;
! 958:
! 959: case expr_host_decl_name:
! 960: s = "host-decl-name";
! 961: goto astring;
! 962:
! 963: case expr_lease_time:
! 964: s = "lease-time";
! 965: goto astring;
! 966:
! 967: case expr_static:
! 968: s = "static";
! 969: goto astring;
! 970:
! 971: case expr_filename:
! 972: s = "filename";
! 973: goto astring;
! 974:
! 975: case expr_sname:
! 976: s = "server-name";
! 977: goto astring;
! 978:
! 979: case expr_reverse:
! 980: if (len > 11) {
! 981: rv = 13;
! 982: strcpy (buf, "(reverse ");
! 983: rv += print_subexpression (expr -> data.reverse.width,
! 984: buf + rv, len - rv - 2);
! 985: buf [rv++] = ' ';
! 986: rv += print_subexpression (expr -> data.reverse.buffer,
! 987: buf + rv, len - rv - 1);
! 988: buf [rv++] = ')';
! 989: buf [rv] = 0;
! 990: return rv;
! 991: }
! 992: break;
! 993:
! 994: case expr_binary_to_ascii:
! 995: if (len > 5) {
! 996: rv = 9;
! 997: strcpy (buf, "(b2a ");
! 998: rv += print_subexpression (expr -> data.b2a.base,
! 999: buf + rv, len - rv - 4);
! 1000: buf [rv++] = ' ';
! 1001: rv += print_subexpression (expr -> data.b2a.width,
! 1002: buf + rv, len - rv - 3);
! 1003: buf [rv++] = ' ';
! 1004: rv += print_subexpression (expr -> data.b2a.separator,
! 1005: buf + rv, len - rv - 2);
! 1006: buf [rv++] = ' ';
! 1007: rv += print_subexpression (expr -> data.b2a.buffer,
! 1008: buf + rv, len - rv - 1);
! 1009: buf [rv++] = ')';
! 1010: buf [rv] = 0;
! 1011: return rv;
! 1012: }
! 1013: break;
! 1014:
! 1015: case expr_dns_transaction:
! 1016: rv = 10;
! 1017: if (len < rv + 2) {
! 1018: buf [0] = '(';
! 1019: strcpy (&buf [1], "ns-update ");
! 1020: while (len < rv + 2) {
! 1021: rv += print_subexpression
! 1022: (expr -> data.dns_transaction.car,
! 1023: buf + rv, len - rv - 2);
! 1024: buf [rv++] = ' ';
! 1025: expr = expr -> data.dns_transaction.cdr;
! 1026: }
! 1027: buf [rv - 1] = ')';
! 1028: buf [rv] = 0;
! 1029: return rv;
! 1030: }
! 1031: return 0;
! 1032:
! 1033: case expr_ns_delete:
! 1034: s = "delete";
! 1035: left = 4;
! 1036: goto dodnsupd;
! 1037: case expr_ns_exists:
! 1038: s = "exists";
! 1039: left = 4;
! 1040: goto dodnsupd;
! 1041: case expr_ns_not_exists:
! 1042: s = "not_exists";
! 1043: left = 4;
! 1044: goto dodnsupd;
! 1045: case expr_ns_add:
! 1046: s = "update";
! 1047: left = 5;
! 1048: dodnsupd:
! 1049: rv = strlen (s);
! 1050: if (len > strlen (s) + 1) {
! 1051: buf [0] = '(';
! 1052: strcpy (buf + 1, s);
! 1053: rv++;
! 1054: buf [rv++] = ' ';
! 1055: s = print_dec_1 (expr -> data.ns_add.rrclass);
! 1056: if (len > rv + strlen (s) + left) {
! 1057: strcpy (&buf [rv], s);
! 1058: rv += strlen (&buf [rv]);
! 1059: }
! 1060: buf [rv++] = ' ';
! 1061: left--;
! 1062: s = print_dec_1 (expr -> data.ns_add.rrtype);
! 1063: if (len > rv + strlen (s) + left) {
! 1064: strcpy (&buf [rv], s);
! 1065: rv += strlen (&buf [rv]);
! 1066: }
! 1067: buf [rv++] = ' ';
! 1068: left--;
! 1069: rv += print_subexpression
! 1070: (expr -> data.ns_add.rrname,
! 1071: buf + rv, len - rv - left);
! 1072: buf [rv++] = ' ';
! 1073: left--;
! 1074: rv += print_subexpression
! 1075: (expr -> data.ns_add.rrdata,
! 1076: buf + rv, len - rv - left);
! 1077: buf [rv++] = ' ';
! 1078: left--;
! 1079: rv += print_subexpression
! 1080: (expr -> data.ns_add.ttl,
! 1081: buf + rv, len - rv - left);
! 1082: buf [rv++] = ')';
! 1083: buf [rv] = 0;
! 1084: return rv;
! 1085: }
! 1086: break;
! 1087:
! 1088: case expr_null:
! 1089: if (len > 6) {
! 1090: strcpy (buf, "(null)");
! 1091: return 6;
! 1092: }
! 1093: break;
! 1094: case expr_funcall:
! 1095: rv = 12 + strlen (expr -> data.funcall.name);
! 1096: if (len > rv + 1) {
! 1097: strcpy (buf, "(funcall ");
! 1098: strcpy (buf + 9, expr -> data.funcall.name);
! 1099: buf [rv++] = ' ';
! 1100: rv += print_subexpression
! 1101: (expr -> data.funcall.arglist, buf + rv,
! 1102: len - rv - 1);
! 1103: buf [rv++] = ')';
! 1104: buf [rv] = 0;
! 1105: return rv;
! 1106: }
! 1107: break;
! 1108:
! 1109: case expr_arg:
! 1110: rv = print_subexpression (expr -> data.arg.val, buf, len);
! 1111: if (expr -> data.arg.next && rv + 2 < len) {
! 1112: buf [rv++] = ' ';
! 1113: rv += print_subexpression (expr -> data.arg.next,
! 1114: buf, len);
! 1115: if (rv + 1 < len)
! 1116: buf [rv++] = 0;
! 1117: return rv;
! 1118: }
! 1119: break;
! 1120:
! 1121: case expr_function:
! 1122: rv = 9;
! 1123: if (len > rv + 1) {
! 1124: struct string_list *foo;
! 1125: strcpy (buf, "(function");
! 1126: for (foo = expr -> data.func -> args;
! 1127: foo; foo = foo -> next) {
! 1128: if (len > rv + 2 + strlen (foo -> string)) {
! 1129: buf [rv - 1] = ' ';
! 1130: strcpy (&buf [rv], foo -> string);
! 1131: rv += strlen (foo -> string);
! 1132: }
! 1133: }
! 1134: buf [rv++] = ')';
! 1135: buf [rv] = 0;
! 1136: return rv;
! 1137: }
! 1138:
! 1139: default:
! 1140: log_fatal("Impossible case at %s:%d (undefined expression "
! 1141: "%d).", MDL, expr->op);
! 1142: break;
! 1143: }
! 1144: return 0;
! 1145: }
! 1146:
! 1147: void print_expression (name, expr)
! 1148: const char *name;
! 1149: struct expression *expr;
! 1150: {
! 1151: char buf [1024];
! 1152:
! 1153: print_subexpression (expr, buf, sizeof buf);
! 1154: log_info ("%s: %s", name, buf);
! 1155: }
! 1156:
! 1157: int token_print_indent_concat (FILE *file, int col, int indent,
! 1158: const char *prefix,
! 1159: const char *suffix, ...)
! 1160: {
! 1161: va_list list;
! 1162: unsigned len;
! 1163: char *s, *t, *u;
! 1164:
! 1165: va_start (list, suffix);
! 1166: s = va_arg (list, char *);
! 1167: len = 0;
! 1168: while (s) {
! 1169: len += strlen (s);
! 1170: s = va_arg (list, char *);
! 1171: }
! 1172: va_end (list);
! 1173:
! 1174: t = dmalloc (len + 1, MDL);
! 1175: if (!t)
! 1176: log_fatal ("token_print_indent: no memory for copy buffer");
! 1177:
! 1178: va_start (list, suffix);
! 1179: s = va_arg (list, char *);
! 1180: u = t;
! 1181: while (s) {
! 1182: len = strlen (s);
! 1183: strcpy (u, s);
! 1184: u += len;
! 1185: s = va_arg (list, char *);
! 1186: }
! 1187: va_end (list);
! 1188:
! 1189: len = token_print_indent (file, col, indent,
! 1190: prefix, suffix, t);
! 1191: dfree (t, MDL);
! 1192: return col;
! 1193: }
! 1194:
! 1195: int token_indent_data_string (FILE *file, int col, int indent,
! 1196: const char *prefix, const char *suffix,
! 1197: struct data_string *data)
! 1198: {
! 1199: int i;
! 1200: char *buf;
! 1201: char obuf [3];
! 1202:
! 1203: /* See if this is just ASCII. */
! 1204: for (i = 0; i < data -> len; i++)
! 1205: if (!isascii (data -> data [i]) ||
! 1206: !isprint (data -> data [i]))
! 1207: break;
! 1208:
! 1209: /* If we have a purely ASCII string, output it as text. */
! 1210: if (i == data -> len) {
! 1211: buf = dmalloc (data -> len + 3, MDL);
! 1212: if (buf) {
! 1213: buf [0] = '"';
! 1214: memcpy (buf + 1, data -> data, data -> len);
! 1215: buf [data -> len + 1] = '"';
! 1216: buf [data -> len + 2] = 0;
! 1217: i = token_print_indent (file, col, indent,
! 1218: prefix, suffix, buf);
! 1219: dfree (buf, MDL);
! 1220: return i;
! 1221: }
! 1222: }
! 1223:
! 1224: for (i = 0; i < data -> len; i++) {
! 1225: sprintf (obuf, "%2.2x", data -> data [i]);
! 1226: col = token_print_indent (file, col, indent,
! 1227: i == 0 ? prefix : "",
! 1228: (i + 1 == data -> len
! 1229: ? suffix
! 1230: : ""), obuf);
! 1231: if (i + 1 != data -> len)
! 1232: col = token_print_indent (file, col, indent,
! 1233: prefix, suffix, ":");
! 1234: }
! 1235: return col;
! 1236: }
! 1237:
! 1238: int token_print_indent (FILE *file, int col, int indent,
! 1239: const char *prefix,
! 1240: const char *suffix, const char *buf)
! 1241: {
! 1242: int len = strlen (buf) + strlen (prefix);
! 1243: if (col + len > 79) {
! 1244: if (indent + len < 79) {
! 1245: indent_spaces (file, indent);
! 1246: col = indent;
! 1247: } else {
! 1248: indent_spaces (file, col);
! 1249: col = len > 79 ? 0 : 79 - len - 1;
! 1250: }
! 1251: } else if (prefix && *prefix) {
! 1252: fputs (prefix, file);
! 1253: col += strlen (prefix);
! 1254: }
! 1255: fputs (buf, file);
! 1256: col += len;
! 1257: if (suffix && *suffix) {
! 1258: if (col + strlen (suffix) > 79) {
! 1259: indent_spaces (file, indent);
! 1260: col = indent;
! 1261: } else {
! 1262: fputs (suffix, file);
! 1263: col += strlen (suffix);
! 1264: }
! 1265: }
! 1266: return col;
! 1267: }
! 1268:
! 1269: void indent_spaces (FILE *file, int indent)
! 1270: {
! 1271: int i;
! 1272: fputc ('\n', file);
! 1273: for (i = 0; i < indent; i++)
! 1274: fputc (' ', file);
! 1275: }
! 1276:
! 1277: #if defined (NSUPDATE)
! 1278: void print_dns_status (int status, ns_updque *uq)
! 1279: {
! 1280: char obuf [1024];
! 1281: char *s = &obuf [0], *end = &obuf [1022];
! 1282: ns_updrec *u;
! 1283: int position;
! 1284: int ttlp;
! 1285: const char *predicate = "if", *en, *op;
! 1286: int errorp;
! 1287:
! 1288: for (u = ISC_LIST_HEAD (*uq); u; u = ISC_LIST_NEXT (u, r_link)) {
! 1289: ttlp = 0;
! 1290:
! 1291: switch (u -> r_opcode)
! 1292: {
! 1293: case NXRRSET:
! 1294: op = "rrset doesn't exist";
! 1295: position = 1;
! 1296: break;
! 1297: case YXRRSET:
! 1298: op = "rrset exists";
! 1299: position = 1;
! 1300: break;
! 1301: case NXDOMAIN:
! 1302: op = "domain doesn't exist";
! 1303: position = 1;
! 1304: break;
! 1305: case YXDOMAIN:
! 1306: op = "domain exists";
! 1307: position = 1;
! 1308: break;
! 1309: case ADD:
! 1310: op = "add";
! 1311: position = 0;
! 1312: ttlp = 1;
! 1313: break;
! 1314: case DELETE:
! 1315: op = "delete";
! 1316: position = 0;
! 1317: break;
! 1318: default:
! 1319: op = "unknown";
! 1320: position = 0;
! 1321: break;
! 1322: }
! 1323: if (!position) {
! 1324: if (s != &obuf [0] && s + 1 < end)
! 1325: *s++ = ' ';
! 1326: if (s + strlen (op) < end) {
! 1327: strcpy (s, op);
! 1328: s += strlen (s);
! 1329: }
! 1330: } else {
! 1331: if (s != &obuf [0] && s + 1 < end)
! 1332: *s++ = ' ';
! 1333: if (s + strlen (predicate) < end) {
! 1334: strcpy (s, predicate);
! 1335: s += strlen (s);
! 1336: }
! 1337: predicate = "and";
! 1338: }
! 1339: if (u -> r_dname) {
! 1340: if (s + 1 < end)
! 1341: *s++ = ' ';
! 1342: if (s + strlen (u -> r_dname) < end) {
! 1343: strcpy (s, u -> r_dname);
! 1344: s += strlen (s);
! 1345: }
! 1346: }
! 1347: if (ttlp) {
! 1348: if (s + 1 < end)
! 1349: *s++ = ' ';
! 1350: /* 27 is as big as a ttl can get. */
! 1351: if (s + 27 < end) {
! 1352: sprintf (s, "%lu",
! 1353: (unsigned long)(u -> r_ttl));
! 1354: s += strlen (s);
! 1355: }
! 1356: }
! 1357: switch (u -> r_class) {
! 1358: case C_IN:
! 1359: en = "IN";
! 1360: break;
! 1361: case C_CHAOS:
! 1362: en = "CHAOS";
! 1363: break;
! 1364: case C_HS:
! 1365: en = "HS";
! 1366: break;
! 1367: default:
! 1368: en = "UNKNOWN";
! 1369: break;
! 1370: }
! 1371: if (s + strlen (en) < end) {
! 1372: if (s + 1 < end)
! 1373: *s++ = ' ';
! 1374: strcpy (s, en);
! 1375: s += strlen (en);
! 1376: }
! 1377: switch (u -> r_type) {
! 1378: case T_A:
! 1379: en = "A";
! 1380: break;
! 1381: case T_AAAA:
! 1382: en = "AAAA";
! 1383: break;
! 1384: case T_PTR:
! 1385: en = "PTR";
! 1386: break;
! 1387: case T_MX:
! 1388: en = "MX";
! 1389: break;
! 1390: case T_TXT:
! 1391: en = "TXT";
! 1392: break;
! 1393: case T_KEY:
! 1394: en = "KEY";
! 1395: break;
! 1396: case T_CNAME:
! 1397: en = "CNAME";
! 1398: break;
! 1399: default:
! 1400: en = "UNKNOWN";
! 1401: break;
! 1402: }
! 1403: if (s + strlen (en) < end) {
! 1404: if (s + 1 < end)
! 1405: *s++ = ' ';
! 1406: strcpy (s, en);
! 1407: s += strlen (en);
! 1408: }
! 1409: if (u -> r_data) {
! 1410: if (s + 1 < end)
! 1411: *s++ = ' ';
! 1412: if (u -> r_type == T_TXT) {
! 1413: if (s + 1 < end)
! 1414: *s++ = '"';
! 1415: }
! 1416: if(u->r_type == T_KEY) {
! 1417: strcat(s, "<keydata>");
! 1418: s+=strlen("<keydata>");
! 1419: }
! 1420: else {
! 1421: if (s + u -> r_size < end) {
! 1422: memcpy (s, u -> r_data, u -> r_size);
! 1423: s += u -> r_size;
! 1424: if (u -> r_type == T_TXT) {
! 1425: if (s + 1 < end)
! 1426: *s++ = '"';
! 1427: }
! 1428: }
! 1429: }
! 1430: }
! 1431: if (position) {
! 1432: if (s + 1 < end)
! 1433: *s++ = ' ';
! 1434: if (s + strlen (op) < end) {
! 1435: strcpy (s, op);
! 1436: s += strlen (s);
! 1437: }
! 1438: }
! 1439: if (u == ISC_LIST_TAIL (*uq))
! 1440: break;
! 1441: }
! 1442: if (s == &obuf [0]) {
! 1443: strcpy (s, "empty update");
! 1444: s += strlen (s);
! 1445: }
! 1446: if (status == NOERROR)
! 1447: errorp = 0;
! 1448: else
! 1449: errorp = 1;
! 1450: en = isc_result_totext (status);
! 1451: #if 0
! 1452: switch (status) {
! 1453: case -1:
! 1454: en = "resolver failed";
! 1455: break;
! 1456:
! 1457: case FORMERR:
! 1458: en = "format error";
! 1459: break;
! 1460:
! 1461: case NOERROR:
! 1462: en = "succeeded";
! 1463: errorp = 0;
! 1464: break;
! 1465:
! 1466: case NOTAUTH:
! 1467: en = "not authorized";
! 1468: break;
! 1469:
! 1470: case NOTIMP:
! 1471: en = "not implemented";
! 1472: break;
! 1473:
! 1474: case NOTZONE:
! 1475: en = "not a single valid zone";
! 1476: break;
! 1477:
! 1478: case NXDOMAIN:
! 1479: en = "no such domain";
! 1480: break;
! 1481:
! 1482: case NXRRSET:
! 1483: en = "no such record";
! 1484: break;
! 1485:
! 1486: case REFUSED:
! 1487: en = "refused";
! 1488: break;
! 1489:
! 1490: case SERVFAIL:
! 1491: en = "server failed";
! 1492: break;
! 1493:
! 1494: case YXDOMAIN:
! 1495: en = "domain exists";
! 1496: break;
! 1497:
! 1498: case YXRRSET:
! 1499: en = "record exists";
! 1500: break;
! 1501:
! 1502: default:
! 1503: en = "unknown error";
! 1504: break;
! 1505: }
! 1506: #endif
! 1507:
! 1508: if (s + 2 < end) {
! 1509: *s++ = ':';
! 1510: *s++ = ' ';
! 1511: }
! 1512: if (s + strlen (en) < end) {
! 1513: strcpy (s, en);
! 1514: s += strlen (en);
! 1515: }
! 1516: if (s + 1 < end)
! 1517: *s++ = '.';
! 1518: *s++ = 0;
! 1519: if (errorp)
! 1520: log_error ("%s", obuf);
! 1521: else
! 1522: log_info ("%s", obuf);
! 1523: }
! 1524: #endif /* NSUPDATE */
! 1525:
! 1526: /* Format the given time as "A; # B", where A is the format
! 1527: * used by the parser, and B is the local time, for humans.
! 1528: */
! 1529: const char *
! 1530: print_time(TIME t)
! 1531: {
! 1532: static char buf[sizeof("epoch 9223372036854775807; "
! 1533: "# Wed Jun 30 21:49:08 2147483647")];
! 1534: static char buf1[sizeof("# Wed Jun 30 21:49:08 2147483647")];
! 1535: time_t since_epoch;
! 1536: /* The string: "6 2147483647/12/31 23:59:60;"
! 1537: * is smaller than the other, used to declare the buffer size, so
! 1538: * we can use one buffer for both.
! 1539: */
! 1540:
! 1541: if (t == MAX_TIME)
! 1542: return "never;";
! 1543:
! 1544: if (t < 0)
! 1545: return NULL;
! 1546:
! 1547: /* For those lucky enough to have a 128-bit time_t, ensure that
! 1548: * whatever (corrupt) value we're given doesn't exceed the static
! 1549: * buffer.
! 1550: */
! 1551: #if (MAX_TIME > 0x7fffffffffffffff)
! 1552: if (t > 0x7fffffffffffffff)
! 1553: return NULL;
! 1554: #endif
! 1555:
! 1556: if (db_time_format == LOCAL_TIME_FORMAT) {
! 1557: since_epoch = mktime(localtime(&t));
! 1558: if ((strftime(buf1, sizeof(buf1),
! 1559: "# %a %b %d %H:%M:%S %Y",
! 1560: localtime(&t)) == 0) ||
! 1561: (snprintf(buf, sizeof(buf), "epoch %lu; %s",
! 1562: (unsigned long)since_epoch, buf1) >= sizeof(buf)))
! 1563: return NULL;
! 1564:
! 1565: } else {
! 1566: /* No bounds check for the year is necessary - in this case,
! 1567: * strftime() will run out of space and assert an error.
! 1568: */
! 1569: if (strftime(buf, sizeof(buf), "%w %Y/%m/%d %H:%M:%S;",
! 1570: gmtime(&t)) == 0)
! 1571: return NULL;
! 1572: }
! 1573:
! 1574: return buf;
! 1575: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>