tools/adflib: build only host variant which is used by Sam440 target
[AROS.git] / workbench / network / stacks / AROSTCP / dhcp / common / print.c
blobf87ff1b93164eaff1c460fa2daa7453735f8fd3f
1 /* print.c
3 Turn data structures into printable text. */
5 /*
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
35 #if 0
36 static char copyright[] =
37 "$Id$ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
38 #endif
40 #include "dhcpd.h"
42 char *quotify_string (const char *s, const char *file, int line)
44 unsigned len = 0;
45 const char *sp;
46 char *buf, *nsp;
48 for (sp = s; sp && *sp; sp++) {
49 if (*sp == ' ')
50 len++;
51 else if (!isascii (*sp) || !isprint (*sp))
52 len += 4;
53 else if (*sp == '"' || *sp == '\\')
54 len += 2;
55 else
56 len++;
59 buf = dmalloc (len + 1, file, line);
60 if (buf) {
61 nsp = buf;
62 for (sp = s; sp && *sp; sp++) {
63 if (*sp == ' ')
64 *nsp++ = ' ';
65 else if (!isascii (*sp) || !isprint (*sp)) {
66 sprintf (nsp, "\\%03o",
67 *(const unsigned char *)sp);
68 nsp += 4;
69 } else if (*sp == '"' || *sp == '\\') {
70 *nsp++ = '\\';
71 *nsp++ = *sp;
72 } else
73 *nsp++ = *sp;
75 *nsp++ = 0;
77 return buf;
80 char *quotify_buf (const unsigned char *s, unsigned len,
81 const char *file, int line)
83 unsigned nulen = 0;
84 char *buf, *nsp;
85 int i;
87 for (i = 0; i < len; i++) {
88 if (s [i] == ' ')
89 nulen++;
90 else if (!isascii (s [i]) || !isprint (s [i]))
91 nulen += 4;
92 else if (s [i] == '"' || s [i] == '\\')
93 nulen += 2;
94 else
95 nulen++;
98 buf = dmalloc (nulen + 1, MDL);
99 if (buf) {
100 nsp = buf;
101 for (i = 0; i < len; i++) {
102 if (s [i] == ' ')
103 *nsp++ = ' ';
104 else if (!isascii (s [i]) || !isprint (s [i])) {
105 sprintf (nsp, "\\%03o", s [i]);
106 nsp += 4;
107 } else if (s [i] == '"' || s [i] == '\\') {
108 *nsp++ = '\\';
109 *nsp++ = s [i];
110 } else
111 *nsp++ = s [i];
113 *nsp++ = 0;
115 return buf;
118 char *print_base64 (const unsigned char *buf, unsigned len,
119 const char *file, int line)
121 char *s, *b;
122 unsigned bl;
123 int i;
124 unsigned val, extra;
125 static char to64 [] =
126 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
128 bl = ((len * 4 + 2) / 3) + 1;
129 b = dmalloc (bl + 1, file, line);
130 if (!b)
131 return (char *)0;
133 i = 0;
134 s = b;
135 while (i != len) {
136 val = buf [i++];
137 extra = val & 3;
138 val = val >> 2;
139 *s++ = to64 [val];
140 if (i == len) {
141 *s++ = to64 [extra << 4];
142 *s++ = '=';
143 break;
145 val = (extra << 8) + buf [i++];
146 extra = val & 15;
147 val = val >> 4;
148 *s++ = to64 [val];
149 if (i == len) {
150 *s++ = to64 [extra << 2];
151 *s++ = '=';
152 break;
154 val = (extra << 8) + buf [i++];
155 extra = val & 0x3f;
156 val = val >> 6;
157 *s++ = to64 [val];
158 *s++ = to64 [extra];
160 if (!len)
161 *s++ = '=';
162 *s++ = 0;
163 if (s > b + bl + 1)
164 abort ();
165 return b;
168 char *print_hw_addr (htype, hlen, data)
169 int htype;
170 int hlen;
171 unsigned char *data;
173 static char habuf [49];
174 char *s;
175 int i;
177 if (hlen <= 0)
178 habuf [0] = 0;
179 else {
180 s = habuf;
181 for (i = 0; i < hlen; i++) {
182 sprintf (s, "%02x", data [i]);
183 s += strlen (s);
184 *s++ = ':';
186 *--s = 0;
188 return habuf;
191 void print_lease (lease)
192 struct lease *lease;
194 struct tm *t;
195 char tbuf [32];
197 log_debug (" Lease %s",
198 piaddr (lease -> ip_addr));
200 t = gmtime (&lease -> starts);
201 strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
202 log_debug (" start %s", tbuf);
204 t = gmtime (&lease -> ends);
205 strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
206 log_debug (" end %s", tbuf);
208 if (lease -> hardware_addr.hlen)
209 log_debug (" hardware addr = %s",
210 print_hw_addr (lease -> hardware_addr.hbuf [0],
211 lease -> hardware_addr.hlen - 1,
212 &lease -> hardware_addr.hbuf [1]));
213 log_debug (" host %s ",
214 lease -> host ? lease -> host -> name : "<none>");
217 #if defined (DEBUG_PACKET)
218 void dump_packet_option (struct option_cache *oc,
219 struct packet *packet,
220 struct lease *lease,
221 struct client_state *client,
222 struct option_state *in_options,
223 struct option_state *cfg_options,
224 struct binding_scope **scope,
225 struct universe *u, void *foo)
227 const char *name, *dot;
228 struct data_string ds;
229 memset (&ds, 0, sizeof ds);
231 if (u != &dhcp_universe) {
232 name = u -> name;
233 dot = ".";
234 } else {
235 name = "";
236 dot = "";
238 if (evaluate_option_cache (&ds, packet, lease, client,
239 in_options, cfg_options, scope, oc, MDL)) {
240 log_debug (" option %s%s%s %s;\n",
241 name, dot, oc -> option -> name,
242 pretty_print_option (oc -> option,
243 ds.data, ds.len, 1, 1));
244 data_string_forget (&ds, MDL);
248 void dump_packet (tp)
249 struct packet *tp;
251 struct dhcp_packet *tdp = tp -> raw;
253 log_debug ("packet length %d", tp -> packet_length);
254 log_debug ("op = %d htype = %d hlen = %d hops = %d",
255 tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
256 log_debug ("xid = %x secs = %ld flags = %x",
257 tdp -> xid, (unsigned long)tdp -> secs, tdp -> flags);
258 log_debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr));
259 log_debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
260 log_debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
261 log_debug ("giaddr = %s", inet_ntoa (tdp -> giaddr));
262 log_debug ("chaddr = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
263 ((unsigned char *)(tdp -> chaddr)) [0],
264 ((unsigned char *)(tdp -> chaddr)) [1],
265 ((unsigned char *)(tdp -> chaddr)) [2],
266 ((unsigned char *)(tdp -> chaddr)) [3],
267 ((unsigned char *)(tdp -> chaddr)) [4],
268 ((unsigned char *)(tdp -> chaddr)) [5]);
269 log_debug ("filename = %s", tdp -> file);
270 log_debug ("server_name = %s", tdp -> sname);
271 if (tp -> options_valid) {
272 int i;
274 for (i = 0; i < tp -> options -> universe_count; i++) {
275 if (tp -> options -> universes [i]) {
276 option_space_foreach (tp, (struct lease *)0,
277 (struct client_state *)0,
278 (struct option_state *)0,
279 tp -> options,
280 &global_scope,
281 universes [i], 0,
282 dump_packet_option);
286 log_debug ("%s", "");
288 #endif
290 void dump_raw (buf, len)
291 const unsigned char *buf;
292 unsigned len;
294 int i;
295 char lbuf [80];
296 int lbix = 0;
299 1 2 3 4 5 6 7
300 01234567890123456789012345678901234567890123456789012345678901234567890123
301 280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
304 memset(lbuf, ' ', 79);
305 lbuf [79] = 0;
307 for (i = 0; i < len; i++) {
308 if ((i & 15) == 0) {
309 if (lbix) {
310 lbuf[53]=' ';
311 lbuf[54]=' ';
312 lbuf[55]=' ';
313 lbuf[73]='\0';
314 log_info ("%s", lbuf);
316 memset(lbuf, ' ', 79);
317 lbuf [79] = 0;
318 sprintf (lbuf, "%03x:", i);
319 lbix = 4;
320 } else if ((i & 7) == 0)
321 lbuf [lbix++] = ' ';
323 if(isprint(buf[i])) {
324 lbuf[56+(i%16)]=buf[i];
325 } else {
326 lbuf[56+(i%16)]='.';
329 sprintf (&lbuf [lbix], " %02x", buf [i]);
330 lbix += 3;
331 lbuf[lbix]=' ';
334 lbuf[53]=' ';
335 lbuf[54]=' ';
336 lbuf[55]=' ';
337 lbuf[73]='\0';
338 log_info ("%s", lbuf);
341 void hash_dump (table)
342 struct hash_table *table;
344 int i;
345 struct hash_bucket *bp;
347 if (!table)
348 return;
350 for (i = 0; i < table -> hash_count; i++) {
351 if (!table -> buckets [i])
352 continue;
353 log_info ("hash bucket %d:", i);
354 for (bp = table -> buckets [i]; bp; bp = bp -> next) {
355 if (bp -> len)
356 dump_raw (bp -> name, bp -> len);
357 else
358 log_info ("%s", (const char *)bp -> name);
363 #define HBLEN 60
365 #define DECLARE_HEX_PRINTER(x) \
366 char *print_hex##x (len, data, limit) \
367 unsigned len; \
368 const u_int8_t *data; \
369 unsigned limit; \
372 static char hex_buf##x [HBLEN + 1]; \
373 unsigned i; \
375 if (limit > HBLEN) \
376 limit = HBLEN; \
378 for (i = 0; i < (limit - 2) && i < len; i++) { \
379 if (!isascii (data [i]) || !isprint (data [i])) { \
380 for (i = 0; i < limit / 3 && i < len; i++) { \
381 sprintf (&hex_buf##x [i * 3], \
382 "%02x:", data [i]); \
384 hex_buf##x [i * 3 - 1] = 0; \
385 return hex_buf##x; \
388 hex_buf##x [0] = '"'; \
389 i = len; \
390 if (i > limit - 2) \
391 i = limit - 2; \
392 memcpy (&hex_buf##x [1], data, i); \
393 hex_buf##x [i + 1] = '"'; \
394 hex_buf##x [i + 2] = 0; \
395 return hex_buf##x; \
398 DECLARE_HEX_PRINTER (_1)
399 DECLARE_HEX_PRINTER (_2)
400 DECLARE_HEX_PRINTER (_3)
402 #define DQLEN 80
404 char *print_dotted_quads (len, data)
405 unsigned len;
406 const u_int8_t *data;
408 static char dq_buf [DQLEN + 1];
409 int i;
410 char *s;
412 s = &dq_buf [0];
414 i = 0;
416 /* %Audit% Loop bounds checks to 21 bytes. %2004.06.17,Safe%
417 * The sprintf can't exceed 18 bytes, and since the loop enforces
418 * 21 bytes of space per iteration at no time can we exit the
419 * loop without at least 3 bytes spare.
421 do {
422 sprintf (s, "%u.%u.%u.%u, ",
423 data [i], data [i + 1], data [i + 2], data [i + 3]);
424 s += strlen (s);
425 i += 4;
426 } while ((s - &dq_buf [0] > DQLEN - 21) &&
427 i + 3 < len);
428 if (i == len)
429 s [-2] = 0;
430 else
431 strcpy (s, "...");
432 return dq_buf;
435 char *print_dec_1 (val)
436 unsigned long val;
438 static char vbuf [32];
439 sprintf (vbuf, "%lu", val);
440 return vbuf;
443 char *print_dec_2 (val)
444 unsigned long val;
446 static char vbuf [32];
447 sprintf (vbuf, "%lu", val);
448 return vbuf;
451 static unsigned print_subexpression PROTO ((struct expression *,
452 char *, unsigned));
454 static unsigned print_subexpression (expr, buf, len)
455 struct expression *expr;
456 char *buf;
457 unsigned len;
459 unsigned rv, left;
460 const char *s;
462 switch (expr -> op) {
463 case expr_none:
464 if (len > 3) {
465 strcpy (buf, "nil");
466 return 3;
468 break;
470 case expr_match:
471 if (len > 7) {
472 strcpy (buf, "(match)");
473 return 7;
475 break;
477 case expr_check:
478 rv = 10 + strlen (expr -> data.check -> name);
479 if (len > rv) {
480 sprintf (buf, "(check %s)",
481 expr -> data.check -> name);
482 return rv;
484 break;
486 case expr_equal:
487 if (len > 6) {
488 rv = 4;
489 strcpy (buf, "(eq ");
490 rv += print_subexpression (expr -> data.equal [0],
491 buf + rv, len - rv - 2);
492 buf [rv++] = ' ';
493 rv += print_subexpression (expr -> data.equal [1],
494 buf + rv, len - rv - 1);
495 buf [rv++] = ')';
496 buf [rv] = 0;
497 return rv;
499 break;
501 case expr_not_equal:
502 if (len > 7) {
503 rv = 5;
504 strcpy (buf, "(neq ");
505 rv += print_subexpression (expr -> data.equal [0],
506 buf + rv, len - rv - 2);
507 buf [rv++] = ' ';
508 rv += print_subexpression (expr -> data.equal [1],
509 buf + rv, len - rv - 1);
510 buf [rv++] = ')';
511 buf [rv] = 0;
512 return rv;
514 break;
516 case expr_substring:
517 if (len > 11) {
518 rv = 8;
519 strcpy (buf, "(substr ");
520 rv += print_subexpression (expr -> data.substring.expr,
521 buf + rv, len - rv - 3);
522 buf [rv++] = ' ';
523 rv += print_subexpression
524 (expr -> data.substring.offset,
525 buf + rv, len - rv - 2);
526 buf [rv++] = ' ';
527 rv += print_subexpression (expr -> data.substring.len,
528 buf + rv, len - rv - 1);
529 buf [rv++] = ')';
530 buf [rv] = 0;
531 return rv;
533 break;
535 case expr_suffix:
536 if (len > 10) {
537 rv = 8;
538 strcpy (buf, "(suffix ");
539 rv += print_subexpression (expr -> data.suffix.expr,
540 buf + rv, len - rv - 2);
541 if (len > rv)
542 buf [rv++] = ' ';
543 rv += print_subexpression (expr -> data.suffix.len,
544 buf + rv, len - rv - 1);
545 if (len > rv)
546 buf [rv++] = ')';
547 buf [rv] = 0;
548 return rv;
550 break;
552 case expr_concat:
553 if (len > 10) {
554 rv = 8;
555 strcpy (buf, "(concat ");
556 rv += print_subexpression (expr -> data.concat [0],
557 buf + rv, len - rv - 2);
558 buf [rv++] = ' ';
559 rv += print_subexpression (expr -> data.concat [1],
560 buf + rv, len - rv - 1);
561 buf [rv++] = ')';
562 buf [rv] = 0;
563 return rv;
565 break;
567 case expr_pick_first_value:
568 if (len > 8) {
569 rv = 6;
570 strcpy (buf, "(pick1st ");
571 rv += print_subexpression
572 (expr -> data.pick_first_value.car,
573 buf + rv, len - rv - 2);
574 buf [rv++] = ' ';
575 rv += print_subexpression
576 (expr -> data.pick_first_value.cdr,
577 buf + rv, len - rv - 1);
578 buf [rv++] = ')';
579 buf [rv] = 0;
580 return rv;
582 break;
584 case expr_host_lookup:
585 rv = 15 + strlen (expr -> data.host_lookup -> hostname);
586 if (len > rv) {
587 sprintf (buf, "(dns-lookup %s)",
588 expr -> data.host_lookup -> hostname);
589 return rv;
591 break;
593 case expr_and:
594 s = "and";
595 binop:
596 rv = strlen (s);
597 if (len > rv + 4) {
598 buf [0] = '(';
599 strcpy (&buf [1], s);
600 rv += 1;
601 buf [rv++] = ' ';
602 rv += print_subexpression (expr -> data.and [0],
603 buf + rv, len - rv - 2);
604 buf [rv++] = ' ';
605 rv += print_subexpression (expr -> data.and [1],
606 buf + rv, len - rv - 1);
607 buf [rv++] = ')';
608 buf [rv] = 0;
609 return rv;
611 break;
613 case expr_or:
614 s = "or";
615 goto binop;
617 case expr_add:
618 s = "+";
619 goto binop;
621 case expr_subtract:
622 s = "-";
623 goto binop;
625 case expr_multiply:
626 s = "*";
627 goto binop;
629 case expr_divide:
630 s = "/";
631 goto binop;
633 case expr_remainder:
634 s = "%";
635 goto binop;
637 case expr_binary_and:
638 s = "&";
639 goto binop;
641 case expr_binary_or:
642 s = "|";
643 goto binop;
645 case expr_binary_xor:
646 s = "^";
647 goto binop;
649 case expr_not:
650 if (len > 6) {
651 rv = 5;
652 strcpy (buf, "(not ");
653 rv += print_subexpression (expr -> data.not,
654 buf + rv, len - rv - 1);
655 buf [rv++] = ')';
656 buf [rv] = 0;
657 return rv;
659 break;
661 case expr_config_option:
662 s = "cfg-option";
663 goto dooption;
665 case expr_option:
666 s = "option";
667 dooption:
668 rv = strlen (s) + 2 + (strlen (expr -> data.option -> name) +
669 strlen (expr -> data.option -> universe -> name));
670 if (len > rv) {
671 sprintf (buf, "(option %s.%s)",
672 expr -> data.option -> universe -> name,
673 expr -> data.option -> name);
674 return rv;
676 break;
678 case expr_hardware:
679 if (len > 10) {
680 strcpy (buf, "(hardware)");
681 return 10;
683 break;
685 case expr_packet:
686 if (len > 10) {
687 rv = 8;
688 strcpy (buf, "(substr ");
689 rv += print_subexpression (expr -> data.packet.offset,
690 buf + rv, len - rv - 2);
691 buf [rv++] = ' ';
692 rv += print_subexpression (expr -> data.packet.len,
693 buf + rv, len - rv - 1);
694 buf [rv++] = ')';
695 buf [rv] = 0;
696 return rv;
698 break;
700 case expr_const_data:
701 s = print_hex_1 (expr -> data.const_data.len,
702 expr -> data.const_data.data, len);
703 rv = strlen (s);
704 if (rv >= len)
705 rv = len - 1;
706 strncpy (buf, s, rv);
707 buf [rv] = 0;
708 return rv;
710 case expr_encapsulate:
711 rv = 13;
712 strcpy (buf, "(encapsulate ");
713 rv += expr -> data.encapsulate.len;
714 if (rv + 2 > len)
715 rv = len - 2;
716 strncpy (buf,
717 (const char *)expr -> data.encapsulate.data, rv - 13);
718 buf [rv++] = ')';
719 buf [rv++] = 0;
720 break;
722 case expr_extract_int8:
723 if (len > 7) {
724 rv = 6;
725 strcpy (buf, "(int8 ");
726 rv += print_subexpression (expr -> data.extract_int,
727 buf + rv, len - rv - 1);
728 buf [rv++] = ')';
729 buf [rv] = 0;
730 return rv;
732 break;
734 case expr_extract_int16:
735 if (len > 8) {
736 rv = 7;
737 strcpy (buf, "(int16 ");
738 rv += print_subexpression (expr -> data.extract_int,
739 buf + rv, len - rv - 1);
740 buf [rv++] = ')';
741 buf [rv] = 0;
742 return rv;
744 break;
746 case expr_extract_int32:
747 if (len > 8) {
748 rv = 7;
749 strcpy (buf, "(int32 ");
750 rv += print_subexpression (expr -> data.extract_int,
751 buf + rv, len - rv - 1);
752 buf [rv++] = ')';
753 buf [rv] = 0;
754 return rv;
756 break;
758 case expr_encode_int8:
759 if (len > 7) {
760 rv = 6;
761 strcpy (buf, "(to-int8 ");
762 rv += print_subexpression (expr -> data.encode_int,
763 buf + rv, len - rv - 1);
764 buf [rv++] = ')';
765 buf [rv] = 0;
766 return rv;
768 break;
770 case expr_encode_int16:
771 if (len > 8) {
772 rv = 7;
773 strcpy (buf, "(to-int16 ");
774 rv += print_subexpression (expr -> data.encode_int,
775 buf + rv, len - rv - 1);
776 buf [rv++] = ')';
777 buf [rv] = 0;
778 return rv;
780 break;
782 case expr_encode_int32:
783 if (len > 8) {
784 rv = 7;
785 strcpy (buf, "(to-int32 ");
786 rv += print_subexpression (expr -> data.encode_int,
787 buf + rv, len - rv - 1);
788 buf [rv++] = ')';
789 buf [rv] = 0;
790 return rv;
792 break;
794 case expr_const_int:
795 s = print_dec_1 (expr -> data.const_int);
796 rv = strlen (s);
797 if (len > rv) {
798 strcpy (buf, s);
799 return rv;
801 break;
803 case expr_exists:
804 rv = 10 + (strlen (expr -> data.option -> name) +
805 strlen (expr -> data.option -> universe -> name));
806 if (len > rv) {
807 sprintf (buf, "(exists %s.%s)",
808 expr -> data.option -> universe -> name,
809 expr -> data.option -> name);
810 return rv;
812 break;
814 case expr_variable_exists:
815 rv = 10 + strlen (expr -> data.variable);
816 if (len > rv) {
817 sprintf (buf, "(defined %s)", expr -> data.variable);
818 return rv;
820 break;
822 case expr_variable_reference:
823 rv = strlen (expr -> data.variable);
824 if (len > rv) {
825 sprintf (buf, "%s", expr -> data.variable);
826 return rv;
828 break;
830 case expr_known:
831 s = "known";
832 astring:
833 rv = strlen (s);
834 if (len > rv) {
835 strcpy (buf, s);
836 return rv;
838 break;
840 case expr_leased_address:
841 s = "leased-address";
842 goto astring;
844 case expr_client_state:
845 s = "client-state";
846 goto astring;
848 case expr_host_decl_name:
849 s = "host-decl-name";
850 goto astring;
852 case expr_lease_time:
853 s = "lease-time";
854 goto astring;
856 case expr_static:
857 s = "static";
858 goto astring;
860 case expr_filename:
861 s = "filename";
862 goto astring;
864 case expr_sname:
865 s = "server-name";
866 goto astring;
868 case expr_reverse:
869 if (len > 11) {
870 rv = 13;
871 strcpy (buf, "(reverse ");
872 rv += print_subexpression (expr -> data.reverse.width,
873 buf + rv, len - rv - 2);
874 buf [rv++] = ' ';
875 rv += print_subexpression (expr -> data.reverse.buffer,
876 buf + rv, len - rv - 1);
877 buf [rv++] = ')';
878 buf [rv] = 0;
879 return rv;
881 break;
883 case expr_binary_to_ascii:
884 if (len > 5) {
885 rv = 9;
886 strcpy (buf, "(b2a ");
887 rv += print_subexpression (expr -> data.b2a.base,
888 buf + rv, len - rv - 4);
889 buf [rv++] = ' ';
890 rv += print_subexpression (expr -> data.b2a.width,
891 buf + rv, len - rv - 3);
892 buf [rv++] = ' ';
893 rv += print_subexpression (expr -> data.b2a.seperator,
894 buf + rv, len - rv - 2);
895 buf [rv++] = ' ';
896 rv += print_subexpression (expr -> data.b2a.buffer,
897 buf + rv, len - rv - 1);
898 buf [rv++] = ')';
899 buf [rv] = 0;
900 return rv;
902 break;
904 case expr_dns_transaction:
905 rv = 10;
906 if (len < rv + 2) {
907 buf [0] = '(';
908 strcpy (&buf [1], "ns-update ");
909 while (len < rv + 2) {
910 rv += print_subexpression
911 (expr -> data.dns_transaction.car,
912 buf + rv, len - rv - 2);
913 buf [rv++] = ' ';
914 expr = expr -> data.dns_transaction.cdr;
916 buf [rv - 1] = ')';
917 buf [rv] = 0;
918 return rv;
920 return 0;
922 case expr_ns_delete:
923 s = "delete";
924 left = 4;
925 goto dodnsupd;
926 case expr_ns_exists:
927 s = "exists";
928 left = 4;
929 goto dodnsupd;
930 case expr_ns_not_exists:
931 s = "not_exists";
932 left = 4;
933 goto dodnsupd;
934 case expr_ns_add:
935 s = "update";
936 left = 5;
937 dodnsupd:
938 rv = strlen (s);
939 if (len > strlen (s) + 1) {
940 buf [0] = '(';
941 strcpy (buf + 1, s);
942 rv++;
943 buf [rv++] = ' ';
944 s = print_dec_1 (expr -> data.ns_add.rrclass);
945 if (len > rv + strlen (s) + left) {
946 strcpy (&buf [rv], s);
947 rv += strlen (&buf [rv]);
949 buf [rv++] = ' ';
950 left--;
951 s = print_dec_1 (expr -> data.ns_add.rrtype);
952 if (len > rv + strlen (s) + left) {
953 strcpy (&buf [rv], s);
954 rv += strlen (&buf [rv]);
956 buf [rv++] = ' ';
957 left--;
958 rv += print_subexpression
959 (expr -> data.ns_add.rrname,
960 buf + rv, len - rv - left);
961 buf [rv++] = ' ';
962 left--;
963 rv += print_subexpression
964 (expr -> data.ns_add.rrdata,
965 buf + rv, len - rv - left);
966 buf [rv++] = ' ';
967 left--;
968 rv += print_subexpression
969 (expr -> data.ns_add.ttl,
970 buf + rv, len - rv - left);
971 buf [rv++] = ')';
972 buf [rv] = 0;
973 return rv;
975 break;
977 case expr_null:
978 if (len > 6) {
979 strcpy (buf, "(null)");
980 return 6;
982 break;
983 case expr_funcall:
984 rv = 12 + strlen (expr -> data.funcall.name);
985 if (len > rv + 1) {
986 strcpy (buf, "(funcall ");
987 strcpy (buf + 9, expr -> data.funcall.name);
988 buf [rv++] = ' ';
989 rv += print_subexpression
990 (expr -> data.funcall.arglist, buf + rv,
991 len - rv - 1);
992 buf [rv++] = ')';
993 buf [rv] = 0;
994 return rv;
996 break;
998 case expr_arg:
999 rv = print_subexpression (expr -> data.arg.val, buf, len);
1000 if (expr -> data.arg.next && rv + 2 < len) {
1001 buf [rv++] = ' ';
1002 rv += print_subexpression (expr -> data.arg.next,
1003 buf, len);
1004 if (rv + 1 < len)
1005 buf [rv++] = 0;
1006 return rv;
1008 break;
1009 case expr_function:
1010 rv = 9;
1011 if (len > rv + 1) {
1012 struct string_list *foo;
1013 strcpy (buf, "(function");
1014 for (foo = expr -> data.func -> args;
1015 foo; foo = foo -> next) {
1016 if (len > rv + 2 + strlen (foo -> string)) {
1017 buf [rv - 1] = ' ';
1018 strcpy (&buf [rv], foo -> string);
1019 rv += strlen (foo -> string);
1022 buf [rv] = ')';
1023 buf [rv++] = 0;
1024 return rv;
1027 return 0;
1030 void print_expression (name, expr)
1031 const char *name;
1032 struct expression *expr;
1034 char buf [1024];
1036 print_subexpression (expr, buf, sizeof buf);
1037 log_info ("%s: %s", name, buf);
1040 int token_print_indent_concat (FILE *file, int col, int indent,
1041 const char *prefix,
1042 const char *suffix, ...)
1044 va_list list;
1045 // char *buf;
1046 unsigned len;
1047 char *s, *t, *u;
1049 va_start (list, suffix);
1050 s = va_arg (list, char *);
1051 len = 0;
1052 while (s) {
1053 len += strlen (s);
1054 s = va_arg (list, char *);
1056 va_end (list);
1058 t = dmalloc (len + 1, MDL);
1059 if (!t)
1060 log_fatal ("token_print_indent: no memory for copy buffer");
1062 va_start (list, suffix);
1063 s = va_arg (list, char *);
1064 u = t;
1065 while (s) {
1066 len = strlen (s);
1067 strcpy (u, s);
1068 u += len;
1070 va_end (list);
1072 len = token_print_indent (file, col, indent,
1073 prefix, suffix, t);
1074 dfree (t, MDL);
1075 return col;
1078 int token_indent_data_string (FILE *file, int col, int indent,
1079 const char *prefix, const char *suffix,
1080 struct data_string *data)
1082 int i;
1083 // char *buf;
1084 char obuf [3];
1086 /* See if this is just ASCII. */
1087 for (i = 0; i < data -> len; i++)
1088 if (!isascii (data -> data [i]) ||
1089 !isprint (data -> data [i]))
1090 break;
1092 /* If we have a purely ASCII string, output it as text. */
1093 if (i == data -> len) {
1094 char *buf = dmalloc (data -> len + 3, MDL);
1095 if (buf) {
1096 buf [0] = '"';
1097 memcpy (buf + 1, data -> data, data -> len);
1098 buf [data -> len + 1] = '"';
1099 buf [data -> len + 2] = 0;
1100 i = token_print_indent (file, col, indent,
1101 prefix, suffix, buf);
1102 dfree (buf, MDL);
1103 return i;
1107 for (i = 0; i < data -> len; i++) {
1108 sprintf (obuf, "%2.2x", data -> data [i]);
1109 col = token_print_indent (file, col, indent,
1110 i == 0 ? prefix : "",
1111 (i + 1 == data -> len
1112 ? suffix
1113 : ""), obuf);
1114 if (i + 1 != data -> len)
1115 col = token_print_indent (file, col, indent,
1116 prefix, suffix, ":");
1118 return col;
1121 int token_print_indent (FILE *file, int col, int indent,
1122 const char *prefix,
1123 const char *suffix, const char *buf)
1125 int len = strlen (buf) + strlen (prefix);
1126 if (col + len > 79) {
1127 if (indent + len < 79) {
1128 indent_spaces (file, indent);
1129 col = indent;
1130 } else {
1131 indent_spaces (file, col);
1132 col = len > 79 ? 0 : 79 - len - 1;
1134 } else if (prefix && *prefix) {
1135 fputs (prefix, file);
1136 col += strlen (prefix);
1138 fputs (buf, file);
1139 col += len;
1140 if (suffix && *suffix) {
1141 if (col + strlen (suffix) > 79) {
1142 indent_spaces (file, indent);
1143 col = indent;
1144 } else {
1145 fputs (suffix, file);
1146 col += strlen (suffix);
1149 return col;
1152 void indent_spaces (FILE *file, int indent)
1154 int i;
1155 fputc ('\n', file);
1156 for (i = 0; i < indent; i++)
1157 fputc (' ', file);
1160 #if defined (NSUPDATE)
1161 void print_dns_status (int status, ns_updque *uq)
1163 char obuf [1024];
1164 char *s = &obuf [0], *end = &obuf [1022];
1165 ns_updrec *u;
1166 int position;
1167 int ttlp;
1168 const char *predicate = "if", *en, *op;
1169 int errorp;
1171 for (u = ISC_LIST_HEAD (*uq); u; u = ISC_LIST_NEXT (u, r_link)) {
1172 ttlp = 0;
1174 switch (u -> r_opcode)
1176 case NXRRSET:
1177 op = "rrset doesn't exist";
1178 position = 1;
1179 break;
1180 case YXRRSET:
1181 op = "rrset exists";
1182 position = 1;
1183 break;
1184 case NXDOMAIN:
1185 op = "domain doesn't exist";
1186 position = 1;
1187 break;
1188 case YXDOMAIN:
1189 op = "domain exists";
1190 position = 1;
1191 break;
1192 case ADD:
1193 op = "add";
1194 position = 0;
1195 ttlp = 1;
1196 break;
1197 case DELETE:
1198 op = "delete";
1199 position = 0;
1200 break;
1201 default:
1202 op = "unknown";
1203 position = 0;
1204 break;
1206 if (!position) {
1207 if (s != &obuf [0] && s + 1 < end)
1208 *s++ = ' ';
1209 if (s + strlen (op) < end) {
1210 strcpy (s, op);
1211 s += strlen (s);
1213 } else {
1214 if (s != &obuf [0] && s + 1 < end)
1215 *s++ = ' ';
1216 if (s + strlen (predicate) < end) {
1217 strcpy (s, predicate);
1218 s += strlen (s);
1220 predicate = "and";
1222 if (u -> r_dname) {
1223 if (s + 1 < end)
1224 *s++ = ' ';
1225 if (s + strlen (u -> r_dname) < end) {
1226 strcpy (s, u -> r_dname);
1227 s += strlen (s);
1230 if (ttlp) {
1231 if (s + 1 < end)
1232 *s++ = ' ';
1233 /* 27 is as big as a ttl can get. */
1234 if (s + 27 < end) {
1235 sprintf (s, "%lu",
1236 (unsigned long)(u -> r_ttl));
1237 s += strlen (s);
1240 switch (u -> r_class) {
1241 case C_IN:
1242 en = "IN";
1243 break;
1244 case C_CHAOS:
1245 en = "CHAOS";
1246 break;
1247 case C_HS:
1248 en = "HS";
1249 break;
1250 default:
1251 en = "UNKNOWN";
1252 break;
1254 if (s + strlen (en) < end) {
1255 if (s + 1 < end)
1256 *s++ = ' ';
1257 strcpy (s, en);
1258 s += strlen (en);
1260 switch (u -> r_type) {
1261 case T_A:
1262 en = "A";
1263 break;
1264 case T_PTR:
1265 en = "PTR";
1266 break;
1267 case T_MX:
1268 en = "MX";
1269 break;
1270 case T_TXT:
1271 en = "TXT";
1272 break;
1273 case T_KEY:
1274 en = "KEY";
1275 break;
1276 case T_CNAME:
1277 en = "CNAME";
1278 break;
1279 default:
1280 en = "UNKNOWN";
1281 break;
1283 if (s + strlen (en) < end) {
1284 if (s + 1 < end)
1285 *s++ = ' ';
1286 strcpy (s, en);
1287 s += strlen (en);
1289 if (u -> r_data) {
1290 if (s + 1 < end)
1291 *s++ = ' ';
1292 if (u -> r_type == T_TXT) {
1293 if (s + 1 < end)
1294 *s++ = '"';
1296 if(u->r_type == T_KEY) {
1297 strcat(s, "<keydata>");
1298 s+=strlen("<keydata>");
1300 else {
1301 if (s + u -> r_size < end) {
1302 memcpy (s, u -> r_data, u -> r_size);
1303 s += u -> r_size;
1304 if (u -> r_type == T_TXT) {
1305 if (s + 1 < end)
1306 *s++ = '"';
1311 if (position) {
1312 if (s + 1 < end)
1313 *s++ = ' ';
1314 if (s + strlen (op) < end) {
1315 strcpy (s, op);
1316 s += strlen (s);
1319 if (u == ISC_LIST_TAIL (*uq))
1320 break;
1322 if (s == &obuf [0]) {
1323 strcpy (s, "empty update");
1324 s += strlen (s);
1326 if (status == NOERROR)
1327 errorp = 0;
1328 else
1329 errorp = 1;
1330 en = isc_result_totext (status);
1331 #if 0
1332 switch (status) {
1333 case -1:
1334 en = "resolver failed";
1335 break;
1337 case FORMERR:
1338 en = "format error";
1339 break;
1341 case NOERROR:
1342 en = "succeeded";
1343 errorp = 0;
1344 break;
1346 case NOTAUTH:
1347 en = "not authorized";
1348 break;
1350 case NOTIMP:
1351 en = "not implemented";
1352 break;
1354 case NOTZONE:
1355 en = "not a single valid zone";
1356 break;
1358 case NXDOMAIN:
1359 en = "no such domain";
1360 break;
1362 case NXRRSET:
1363 en = "no such record";
1364 break;
1366 case REFUSED:
1367 en = "refused";
1368 break;
1370 case SERVFAIL:
1371 en = "server failed";
1372 break;
1374 case YXDOMAIN:
1375 en = "domain exists";
1376 break;
1378 case YXRRSET:
1379 en = "record exists";
1380 break;
1382 default:
1383 en = "unknown error";
1384 break;
1386 #endif
1388 if (s + 2 < end) {
1389 *s++ = ':';
1390 *s++ = ' ';
1392 if (s + strlen (en) < end) {
1393 strcpy (s, en);
1394 s += strlen (en);
1396 if (s + 1 < end)
1397 *s++ = '.';
1398 *s++ = 0;
1399 if (errorp)
1400 log_error ("%s", obuf);
1401 else
1402 log_info ("%s", obuf);
1404 #endif /* NSUPDATE */