3 Turn data structures into printable text. */
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.
23 * Redwood City, CA 94063
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''.
36 static char copyright
[] =
37 "$Id$ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
42 char *quotify_string (const char *s
, const char *file
, int line
)
48 for (sp
= s
; sp
&& *sp
; sp
++) {
51 else if (!isascii (*sp
) || !isprint (*sp
))
53 else if (*sp
== '"' || *sp
== '\\')
59 buf
= dmalloc (len
+ 1, file
, line
);
62 for (sp
= s
; sp
&& *sp
; sp
++) {
65 else if (!isascii (*sp
) || !isprint (*sp
)) {
66 sprintf (nsp
, "\\%03o",
67 *(const unsigned char *)sp
);
69 } else if (*sp
== '"' || *sp
== '\\') {
80 char *quotify_buf (const unsigned char *s
, unsigned len
,
81 const char *file
, int line
)
87 for (i
= 0; i
< len
; i
++) {
90 else if (!isascii (s
[i
]) || !isprint (s
[i
]))
92 else if (s
[i
] == '"' || s
[i
] == '\\')
98 buf
= dmalloc (nulen
+ 1, MDL
);
101 for (i
= 0; i
< len
; i
++) {
104 else if (!isascii (s
[i
]) || !isprint (s
[i
])) {
105 sprintf (nsp
, "\\%03o", s
[i
]);
107 } else if (s
[i
] == '"' || s
[i
] == '\\') {
118 char *print_base64 (const unsigned char *buf
, unsigned len
,
119 const char *file
, int line
)
125 static char to64
[] =
126 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
128 bl
= ((len
* 4 + 2) / 3) + 1;
129 b
= dmalloc (bl
+ 1, file
, line
);
141 *s
++ = to64
[extra
<< 4];
145 val
= (extra
<< 8) + buf
[i
++];
150 *s
++ = to64
[extra
<< 2];
154 val
= (extra
<< 8) + buf
[i
++];
168 char *print_hw_addr (htype
, hlen
, data
)
173 static char habuf
[49];
181 for (i
= 0; i
< hlen
; i
++) {
182 sprintf (s
, "%02x", data
[i
]);
191 void print_lease (lease
)
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
,
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
) {
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
)
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
) {
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,
286 log_debug ("%s", "");
290 void dump_raw (buf
, len
)
291 const unsigned char *buf
;
300 01234567890123456789012345678901234567890123456789012345678901234567890123
301 280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
304 memset(lbuf
, ' ', 79);
307 for (i
= 0; i
< len
; i
++) {
314 log_info ("%s", lbuf
);
316 memset(lbuf
, ' ', 79);
318 sprintf (lbuf
, "%03x:", i
);
320 } else if ((i
& 7) == 0)
323 if(isprint(buf
[i
])) {
324 lbuf
[56+(i
%16)]=buf
[i
];
329 sprintf (&lbuf
[lbix
], " %02x", buf
[i
]);
338 log_info ("%s", lbuf
);
341 void hash_dump (table
)
342 struct hash_table
*table
;
345 struct hash_bucket
*bp
;
350 for (i
= 0; i
< table
-> hash_count
; i
++) {
351 if (!table
-> buckets
[i
])
353 log_info ("hash bucket %d:", i
);
354 for (bp
= table
-> buckets
[i
]; bp
; bp
= bp
-> next
) {
356 dump_raw (bp
-> name
, bp
-> len
);
358 log_info ("%s", (const char *)bp
-> name
);
365 #define DECLARE_HEX_PRINTER(x) \
366 char *print_hex##x (len, data, limit) \
368 const u_int8_t *data; \
372 static char hex_buf##x [HBLEN + 1]; \
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; \
388 hex_buf##x [0] = '"'; \
392 memcpy (&hex_buf##x [1], data, i); \
393 hex_buf##x [i + 1] = '"'; \
394 hex_buf##x [i + 2] = 0; \
398 DECLARE_HEX_PRINTER (_1
)
399 DECLARE_HEX_PRINTER (_2
)
400 DECLARE_HEX_PRINTER (_3
)
404 char *print_dotted_quads (len
, data
)
406 const u_int8_t
*data
;
408 static char dq_buf
[DQLEN
+ 1];
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.
422 sprintf (s
, "%u.%u.%u.%u, ",
423 data
[i
], data
[i
+ 1], data
[i
+ 2], data
[i
+ 3]);
426 } while ((s
- &dq_buf
[0] > DQLEN
- 21) &&
435 char *print_dec_1 (val
)
438 static char vbuf
[32];
439 sprintf (vbuf
, "%lu", val
);
443 char *print_dec_2 (val
)
446 static char vbuf
[32];
447 sprintf (vbuf
, "%lu", val
);
451 static unsigned print_subexpression
PROTO ((struct expression
*,
454 static unsigned print_subexpression (expr
, buf
, len
)
455 struct expression
*expr
;
462 switch (expr
-> op
) {
472 strcpy (buf
, "(match)");
478 rv
= 10 + strlen (expr
-> data
.check
-> name
);
480 sprintf (buf
, "(check %s)",
481 expr
-> data
.check
-> name
);
489 strcpy (buf
, "(eq ");
490 rv
+= print_subexpression (expr
-> data
.equal
[0],
491 buf
+ rv
, len
- rv
- 2);
493 rv
+= print_subexpression (expr
-> data
.equal
[1],
494 buf
+ rv
, len
- rv
- 1);
504 strcpy (buf
, "(neq ");
505 rv
+= print_subexpression (expr
-> data
.equal
[0],
506 buf
+ rv
, len
- rv
- 2);
508 rv
+= print_subexpression (expr
-> data
.equal
[1],
509 buf
+ rv
, len
- rv
- 1);
519 strcpy (buf
, "(substr ");
520 rv
+= print_subexpression (expr
-> data
.substring
.expr
,
521 buf
+ rv
, len
- rv
- 3);
523 rv
+= print_subexpression
524 (expr
-> data
.substring
.offset
,
525 buf
+ rv
, len
- rv
- 2);
527 rv
+= print_subexpression (expr
-> data
.substring
.len
,
528 buf
+ rv
, len
- rv
- 1);
538 strcpy (buf
, "(suffix ");
539 rv
+= print_subexpression (expr
-> data
.suffix
.expr
,
540 buf
+ rv
, len
- rv
- 2);
543 rv
+= print_subexpression (expr
-> data
.suffix
.len
,
544 buf
+ rv
, len
- rv
- 1);
555 strcpy (buf
, "(concat ");
556 rv
+= print_subexpression (expr
-> data
.concat
[0],
557 buf
+ rv
, len
- rv
- 2);
559 rv
+= print_subexpression (expr
-> data
.concat
[1],
560 buf
+ rv
, len
- rv
- 1);
567 case expr_pick_first_value
:
570 strcpy (buf
, "(pick1st ");
571 rv
+= print_subexpression
572 (expr
-> data
.pick_first_value
.car
,
573 buf
+ rv
, len
- rv
- 2);
575 rv
+= print_subexpression
576 (expr
-> data
.pick_first_value
.cdr
,
577 buf
+ rv
, len
- rv
- 1);
584 case expr_host_lookup
:
585 rv
= 15 + strlen (expr
-> data
.host_lookup
-> hostname
);
587 sprintf (buf
, "(dns-lookup %s)",
588 expr
-> data
.host_lookup
-> hostname
);
599 strcpy (&buf
[1], s
);
602 rv
+= print_subexpression (expr
-> data
.and [0],
603 buf
+ rv
, len
- rv
- 2);
605 rv
+= print_subexpression (expr
-> data
.and [1],
606 buf
+ rv
, len
- rv
- 1);
637 case expr_binary_and
:
645 case expr_binary_xor
:
652 strcpy (buf
, "(not ");
653 rv
+= print_subexpression (expr
-> data
.not,
654 buf
+ rv
, len
- rv
- 1);
661 case expr_config_option
:
668 rv
= strlen (s
) + 2 + (strlen (expr
-> data
.option
-> name
) +
669 strlen (expr
-> data
.option
-> universe
-> name
));
671 sprintf (buf
, "(option %s.%s)",
672 expr
-> data
.option
-> universe
-> name
,
673 expr
-> data
.option
-> name
);
680 strcpy (buf
, "(hardware)");
688 strcpy (buf
, "(substr ");
689 rv
+= print_subexpression (expr
-> data
.packet
.offset
,
690 buf
+ rv
, len
- rv
- 2);
692 rv
+= print_subexpression (expr
-> data
.packet
.len
,
693 buf
+ rv
, len
- rv
- 1);
700 case expr_const_data
:
701 s
= print_hex_1 (expr
-> data
.const_data
.len
,
702 expr
-> data
.const_data
.data
, len
);
706 strncpy (buf
, s
, rv
);
710 case expr_encapsulate
:
712 strcpy (buf
, "(encapsulate ");
713 rv
+= expr
-> data
.encapsulate
.len
;
717 (const char *)expr
-> data
.encapsulate
.data
, rv
- 13);
722 case expr_extract_int8
:
725 strcpy (buf
, "(int8 ");
726 rv
+= print_subexpression (expr
-> data
.extract_int
,
727 buf
+ rv
, len
- rv
- 1);
734 case expr_extract_int16
:
737 strcpy (buf
, "(int16 ");
738 rv
+= print_subexpression (expr
-> data
.extract_int
,
739 buf
+ rv
, len
- rv
- 1);
746 case expr_extract_int32
:
749 strcpy (buf
, "(int32 ");
750 rv
+= print_subexpression (expr
-> data
.extract_int
,
751 buf
+ rv
, len
- rv
- 1);
758 case expr_encode_int8
:
761 strcpy (buf
, "(to-int8 ");
762 rv
+= print_subexpression (expr
-> data
.encode_int
,
763 buf
+ rv
, len
- rv
- 1);
770 case expr_encode_int16
:
773 strcpy (buf
, "(to-int16 ");
774 rv
+= print_subexpression (expr
-> data
.encode_int
,
775 buf
+ rv
, len
- rv
- 1);
782 case expr_encode_int32
:
785 strcpy (buf
, "(to-int32 ");
786 rv
+= print_subexpression (expr
-> data
.encode_int
,
787 buf
+ rv
, len
- rv
- 1);
795 s
= print_dec_1 (expr
-> data
.const_int
);
804 rv
= 10 + (strlen (expr
-> data
.option
-> name
) +
805 strlen (expr
-> data
.option
-> universe
-> name
));
807 sprintf (buf
, "(exists %s.%s)",
808 expr
-> data
.option
-> universe
-> name
,
809 expr
-> data
.option
-> name
);
814 case expr_variable_exists
:
815 rv
= 10 + strlen (expr
-> data
.variable
);
817 sprintf (buf
, "(defined %s)", expr
-> data
.variable
);
822 case expr_variable_reference
:
823 rv
= strlen (expr
-> data
.variable
);
825 sprintf (buf
, "%s", expr
-> data
.variable
);
840 case expr_leased_address
:
841 s
= "leased-address";
844 case expr_client_state
:
848 case expr_host_decl_name
:
849 s
= "host-decl-name";
852 case expr_lease_time
:
871 strcpy (buf
, "(reverse ");
872 rv
+= print_subexpression (expr
-> data
.reverse
.width
,
873 buf
+ rv
, len
- rv
- 2);
875 rv
+= print_subexpression (expr
-> data
.reverse
.buffer
,
876 buf
+ rv
, len
- rv
- 1);
883 case expr_binary_to_ascii
:
886 strcpy (buf
, "(b2a ");
887 rv
+= print_subexpression (expr
-> data
.b2a
.base
,
888 buf
+ rv
, len
- rv
- 4);
890 rv
+= print_subexpression (expr
-> data
.b2a
.width
,
891 buf
+ rv
, len
- rv
- 3);
893 rv
+= print_subexpression (expr
-> data
.b2a
.seperator
,
894 buf
+ rv
, len
- rv
- 2);
896 rv
+= print_subexpression (expr
-> data
.b2a
.buffer
,
897 buf
+ rv
, len
- rv
- 1);
904 case expr_dns_transaction
:
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);
914 expr
= expr
-> data
.dns_transaction
.cdr
;
930 case expr_ns_not_exists
:
939 if (len
> strlen (s
) + 1) {
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
]);
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
]);
958 rv
+= print_subexpression
959 (expr
-> data
.ns_add
.rrname
,
960 buf
+ rv
, len
- rv
- left
);
963 rv
+= print_subexpression
964 (expr
-> data
.ns_add
.rrdata
,
965 buf
+ rv
, len
- rv
- left
);
968 rv
+= print_subexpression
969 (expr
-> data
.ns_add
.ttl
,
970 buf
+ rv
, len
- rv
- left
);
979 strcpy (buf
, "(null)");
984 rv
= 12 + strlen (expr
-> data
.funcall
.name
);
986 strcpy (buf
, "(funcall ");
987 strcpy (buf
+ 9, expr
-> data
.funcall
.name
);
989 rv
+= print_subexpression
990 (expr
-> data
.funcall
.arglist
, buf
+ rv
,
999 rv
= print_subexpression (expr
-> data
.arg
.val
, buf
, len
);
1000 if (expr
-> data
.arg
.next
&& rv
+ 2 < len
) {
1002 rv
+= print_subexpression (expr
-> data
.arg
.next
,
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
)) {
1018 strcpy (&buf
[rv
], foo
-> string
);
1019 rv
+= strlen (foo
-> string
);
1030 void print_expression (name
, expr
)
1032 struct expression
*expr
;
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
,
1042 const char *suffix
, ...)
1049 va_start (list
, suffix
);
1050 s
= va_arg (list
, char *);
1054 s
= va_arg (list
, char *);
1058 t
= dmalloc (len
+ 1, MDL
);
1060 log_fatal ("token_print_indent: no memory for copy buffer");
1062 va_start (list
, suffix
);
1063 s
= va_arg (list
, char *);
1072 len
= token_print_indent (file
, col
, indent
,
1078 int token_indent_data_string (FILE *file
, int col
, int indent
,
1079 const char *prefix
, const char *suffix
,
1080 struct data_string
*data
)
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
]))
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
);
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
);
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
1114 if (i
+ 1 != data
-> len
)
1115 col
= token_print_indent (file
, col
, indent
,
1116 prefix
, suffix
, ":");
1121 int token_print_indent (FILE *file
, int col
, int indent
,
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
);
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
);
1140 if (suffix
&& *suffix
) {
1141 if (col
+ strlen (suffix
) > 79) {
1142 indent_spaces (file
, indent
);
1145 fputs (suffix
, file
);
1146 col
+= strlen (suffix
);
1152 void indent_spaces (FILE *file
, int indent
)
1156 for (i
= 0; i
< indent
; i
++)
1160 #if defined (NSUPDATE)
1161 void print_dns_status (int status
, ns_updque
*uq
)
1164 char *s
= &obuf
[0], *end
= &obuf
[1022];
1168 const char *predicate
= "if", *en
, *op
;
1171 for (u
= ISC_LIST_HEAD (*uq
); u
; u
= ISC_LIST_NEXT (u
, r_link
)) {
1174 switch (u
-> r_opcode
)
1177 op
= "rrset doesn't exist";
1181 op
= "rrset exists";
1185 op
= "domain doesn't exist";
1189 op
= "domain exists";
1207 if (s
!= &obuf
[0] && s
+ 1 < end
)
1209 if (s
+ strlen (op
) < end
) {
1214 if (s
!= &obuf
[0] && s
+ 1 < end
)
1216 if (s
+ strlen (predicate
) < end
) {
1217 strcpy (s
, predicate
);
1225 if (s
+ strlen (u
-> r_dname
) < end
) {
1226 strcpy (s
, u
-> r_dname
);
1233 /* 27 is as big as a ttl can get. */
1236 (unsigned long)(u
-> r_ttl
));
1240 switch (u
-> r_class
) {
1254 if (s
+ strlen (en
) < end
) {
1260 switch (u
-> r_type
) {
1283 if (s
+ strlen (en
) < end
) {
1292 if (u
-> r_type
== T_TXT
) {
1296 if(u
->r_type
== T_KEY
) {
1297 strcat(s
, "<keydata>");
1298 s
+=strlen("<keydata>");
1301 if (s
+ u
-> r_size
< end
) {
1302 memcpy (s
, u
-> r_data
, u
-> r_size
);
1304 if (u
-> r_type
== T_TXT
) {
1314 if (s
+ strlen (op
) < end
) {
1319 if (u
== ISC_LIST_TAIL (*uq
))
1322 if (s
== &obuf
[0]) {
1323 strcpy (s
, "empty update");
1326 if (status
== NOERROR
)
1330 en
= isc_result_totext (status
);
1334 en
= "resolver failed";
1338 en
= "format error";
1347 en
= "not authorized";
1351 en
= "not implemented";
1355 en
= "not a single valid zone";
1359 en
= "no such domain";
1363 en
= "no such record";
1371 en
= "server failed";
1375 en
= "domain exists";
1379 en
= "record exists";
1383 en
= "unknown error";
1392 if (s
+ strlen (en
) < end
) {
1400 log_error ("%s", obuf
);
1402 log_info ("%s", obuf
);
1404 #endif /* NSUPDATE */