1995-11-29 07:40:04 +00:00
|
|
|
/* print.c
|
|
|
|
|
|
|
|
Turn data structures into printable text. */
|
|
|
|
|
|
|
|
/*
|
1999-03-16 05:50:46 +00:00
|
|
|
* Copyright (c) 1996-1999 Internet Software Consortium.
|
|
|
|
* Use is subject to license terms which appear in the file named
|
|
|
|
* ISC-LICENSE that should have accompanied this file when you
|
|
|
|
* received it. If a file named ISC-LICENSE did not accompany this
|
|
|
|
* file, or you are not sure the one you have is correct, you may
|
|
|
|
* obtain an applicable copy of the license at:
|
1995-11-29 07:40:04 +00:00
|
|
|
*
|
1999-03-16 05:50:46 +00:00
|
|
|
* http://www.isc.org/isc-license-1.0.html.
|
1995-11-29 07:40:04 +00:00
|
|
|
*
|
1999-03-16 05:50:46 +00:00
|
|
|
* This file is part of the ISC DHCP distribution. The documentation
|
|
|
|
* associated with this file is listed in the file DOCUMENTATION,
|
|
|
|
* included in the top-level directory of this release.
|
1995-11-29 07:40:04 +00:00
|
|
|
*
|
1999-03-16 05:50:46 +00:00
|
|
|
* Support and other services are available for ISC products - see
|
|
|
|
* http://www.isc.org for more information.
|
1995-11-29 07:40:04 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef lint
|
|
|
|
static char copyright[] =
|
1999-03-16 05:50:46 +00:00
|
|
|
"$Id: print.c,v 1.21 1999/03/16 05:50:36 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
1995-11-29 07:40:04 +00:00
|
|
|
#endif /* not lint */
|
|
|
|
|
1996-02-06 20:25:56 +00:00
|
|
|
#include "dhcpd.h"
|
|
|
|
|
1995-11-29 07:40:04 +00:00
|
|
|
char *print_hw_addr (htype, hlen, data)
|
|
|
|
int htype;
|
|
|
|
int hlen;
|
|
|
|
unsigned char *data;
|
|
|
|
{
|
|
|
|
static char habuf [49];
|
|
|
|
char *s;
|
|
|
|
int i;
|
|
|
|
|
1996-02-21 12:11:09 +00:00
|
|
|
if (htype == 0 || hlen == 0) {
|
|
|
|
strcpy (habuf, "<null>");
|
|
|
|
} else {
|
|
|
|
s = habuf;
|
|
|
|
for (i = 0; i < hlen; i++) {
|
1997-11-29 07:52:10 +00:00
|
|
|
sprintf (s, "%02x", data [i]);
|
1996-02-21 12:11:09 +00:00
|
|
|
s += strlen (s);
|
|
|
|
*s++ = ':';
|
|
|
|
}
|
|
|
|
*--s = 0;
|
1995-11-29 07:40:04 +00:00
|
|
|
}
|
|
|
|
return habuf;
|
|
|
|
}
|
|
|
|
|
1996-02-21 12:11:09 +00:00
|
|
|
void print_lease (lease)
|
|
|
|
struct lease *lease;
|
|
|
|
{
|
|
|
|
struct tm *t;
|
|
|
|
char tbuf [32];
|
|
|
|
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug (" Lease %s",
|
1996-02-29 18:32:57 +00:00
|
|
|
piaddr (lease -> ip_addr));
|
1996-02-21 12:11:09 +00:00
|
|
|
|
|
|
|
t = gmtime (&lease -> starts);
|
1999-02-14 19:04:05 +00:00
|
|
|
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug (" start %s", tbuf);
|
1996-02-21 12:11:09 +00:00
|
|
|
|
|
|
|
t = gmtime (&lease -> ends);
|
1999-02-14 19:04:05 +00:00
|
|
|
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug (" end %s", tbuf);
|
1996-02-21 12:11:09 +00:00
|
|
|
|
|
|
|
t = gmtime (&lease -> timestamp);
|
1999-02-14 19:04:05 +00:00
|
|
|
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug (" stamp %s", tbuf);
|
1996-02-21 12:11:09 +00:00
|
|
|
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug (" hardware addr = %s",
|
1996-02-29 18:32:57 +00:00
|
|
|
print_hw_addr (lease -> hardware_addr.htype,
|
1996-02-21 12:11:09 +00:00
|
|
|
lease -> hardware_addr.hlen,
|
|
|
|
lease -> hardware_addr.haddr));
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug (" host %s ",
|
1997-03-05 06:33:06 +00:00
|
|
|
lease -> host ? lease -> host -> name : "<none>");
|
1996-02-21 12:11:09 +00:00
|
|
|
}
|
1996-02-25 21:28:38 +00:00
|
|
|
|
1998-11-05 18:44:11 +00:00
|
|
|
#if defined (DEBUG)
|
1996-02-25 21:28:38 +00:00
|
|
|
void dump_packet (tp)
|
|
|
|
struct packet *tp;
|
|
|
|
{
|
|
|
|
struct dhcp_packet *tdp = tp -> raw;
|
|
|
|
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug ("packet length %d", tp -> packet_length);
|
|
|
|
log_debug ("op = %d htype = %d hlen = %d hops = %d",
|
1996-02-25 21:28:38 +00:00
|
|
|
tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug ("xid = %x secs = %d flags = %x",
|
1996-02-25 21:28:38 +00:00
|
|
|
tdp -> xid, tdp -> secs, tdp -> flags);
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr));
|
|
|
|
log_debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
|
|
|
|
log_debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
|
|
|
|
log_debug ("giaddr = %s", inet_ntoa (tdp -> giaddr));
|
|
|
|
log_debug ("chaddr = %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
|
1996-02-25 21:28:38 +00:00
|
|
|
((unsigned char *)(tdp -> chaddr)) [0],
|
|
|
|
((unsigned char *)(tdp -> chaddr)) [1],
|
|
|
|
((unsigned char *)(tdp -> chaddr)) [2],
|
|
|
|
((unsigned char *)(tdp -> chaddr)) [3],
|
|
|
|
((unsigned char *)(tdp -> chaddr)) [4],
|
|
|
|
((unsigned char *)(tdp -> chaddr)) [5]);
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug ("filename = %s", tdp -> file);
|
|
|
|
log_debug ("server_name = %s", tdp -> sname);
|
1996-02-25 21:28:38 +00:00
|
|
|
if (tp -> options_valid) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
if (tp -> options [i].data)
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug (" %s = %s",
|
1996-02-25 21:28:38 +00:00
|
|
|
dhcp_options [i].name,
|
|
|
|
pretty_print_option
|
|
|
|
(i, tp -> options [i].data,
|
1997-06-02 22:32:37 +00:00
|
|
|
tp -> options [i].len, 1, 1));
|
1996-02-25 21:28:38 +00:00
|
|
|
}
|
|
|
|
}
|
1999-02-24 17:56:53 +00:00
|
|
|
log_debug ("");
|
1996-02-29 18:32:57 +00:00
|
|
|
}
|
1998-11-05 18:44:11 +00:00
|
|
|
#endif
|
1996-02-29 18:32:57 +00:00
|
|
|
|
|
|
|
void dump_raw (buf, len)
|
|
|
|
unsigned char *buf;
|
|
|
|
int len;
|
|
|
|
{
|
|
|
|
int i;
|
1996-05-13 00:06:44 +00:00
|
|
|
char lbuf [80];
|
|
|
|
int lbix = 0;
|
1996-02-29 18:32:57 +00:00
|
|
|
|
1996-05-28 18:15:22 +00:00
|
|
|
lbuf [0] = 0;
|
|
|
|
|
1996-02-29 18:32:57 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
1996-05-13 00:06:44 +00:00
|
|
|
if ((i & 15) == 0) {
|
|
|
|
if (lbix)
|
1999-02-24 17:56:53 +00:00
|
|
|
log_info (lbuf);
|
1996-05-13 00:06:44 +00:00
|
|
|
sprintf (lbuf, "%03x:", i);
|
|
|
|
lbix = 4;
|
|
|
|
} else if ((i & 7) == 0)
|
|
|
|
lbuf [lbix++] = ' ';
|
|
|
|
sprintf (&lbuf [lbix], " %02x", buf [i]);
|
|
|
|
lbix += 3;
|
1996-02-29 18:32:57 +00:00
|
|
|
}
|
1999-02-24 17:56:53 +00:00
|
|
|
log_info (lbuf);
|
1996-02-25 21:28:38 +00:00
|
|
|
}
|
|
|
|
|
1996-05-22 07:28:42 +00:00
|
|
|
void hash_dump (table)
|
|
|
|
struct hash_table *table;
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct hash_bucket *bp;
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < table -> hash_count; i++) {
|
|
|
|
if (!table -> buckets [i])
|
|
|
|
continue;
|
1999-02-24 17:56:53 +00:00
|
|
|
log_info ("hash bucket %d:", i);
|
1996-05-22 07:28:42 +00:00
|
|
|
for (bp = table -> buckets [i]; bp; bp = bp -> next) {
|
|
|
|
if (bp -> len)
|
|
|
|
dump_raw (bp -> name, bp -> len);
|
|
|
|
else
|
1999-02-24 17:56:53 +00:00
|
|
|
log_info ((char *)bp -> name);
|
1996-05-22 07:28:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-11-05 18:44:11 +00:00
|
|
|
|
|
|
|
#define HBLEN 60
|
|
|
|
|
|
|
|
#define DECLARE_HEX_PRINTER(x) \
|
|
|
|
char *print_hex##x (len, data, limit) \
|
|
|
|
int len; \
|
|
|
|
u_int8_t *data; \
|
|
|
|
{ \
|
|
|
|
\
|
|
|
|
static char hex_buf##x [HBLEN + 1]; \
|
|
|
|
int i; \
|
|
|
|
\
|
|
|
|
if (limit > HBLEN) \
|
|
|
|
limit = HBLEN; \
|
|
|
|
\
|
|
|
|
for (i = 0; i < (limit - 2) && i < len; i++) { \
|
|
|
|
if (!isascii (data [i]) || !isprint (data [i])) { \
|
|
|
|
for (i = 0; i < limit / 3 && i < len; i++) { \
|
|
|
|
sprintf (&hex_buf##x [i * 3], \
|
|
|
|
"%02x:", data [i]); \
|
|
|
|
} \
|
|
|
|
hex_buf##x [i * 3 - 1] = 0; \
|
|
|
|
return hex_buf##x; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
hex_buf##x [0] = '"'; \
|
|
|
|
i = len; \
|
|
|
|
if (i > limit - 2) \
|
|
|
|
i = limit - 2; \
|
|
|
|
memcpy (&hex_buf##x [1], data, i); \
|
|
|
|
hex_buf##x [i + 1] = '"'; \
|
|
|
|
hex_buf##x [i + 2] = 0; \
|
|
|
|
return hex_buf##x; \
|
|
|
|
}
|
|
|
|
|
|
|
|
DECLARE_HEX_PRINTER (_1)
|
|
|
|
DECLARE_HEX_PRINTER (_2)
|
|
|
|
DECLARE_HEX_PRINTER (_3)
|
|
|
|
|
|
|
|
#define DQLEN 80
|
|
|
|
|
|
|
|
char *print_dotted_quads (len, data)
|
|
|
|
int len;
|
|
|
|
u_int8_t *data;
|
|
|
|
{
|
|
|
|
static char dq_buf [DQLEN + 1];
|
|
|
|
int i;
|
|
|
|
char *s, *last;
|
|
|
|
|
|
|
|
s = &dq_buf [0];
|
|
|
|
last = s;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
sprintf (s, "%d.%d.%d.%d, ",
|
|
|
|
data [i], data [i + 1], data [i + 2], data [i + 3]);
|
|
|
|
s += strlen (s);
|
|
|
|
i += 4;
|
|
|
|
} while ((s - &dq_buf [0] > DQLEN - 21) &&
|
|
|
|
i + 3 < len);
|
|
|
|
if (i == len)
|
|
|
|
s [-2] = 0;
|
|
|
|
else
|
|
|
|
strcpy (s, "...");
|
|
|
|
return dq_buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *print_dec_1 (val)
|
|
|
|
int val;
|
|
|
|
{
|
|
|
|
static char vbuf [32];
|
|
|
|
sprintf (vbuf, "%d", val);
|
|
|
|
return vbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *print_dec_2 (val)
|
|
|
|
int val;
|
|
|
|
{
|
|
|
|
static char vbuf [32];
|
|
|
|
sprintf (vbuf, "%d", val);
|
|
|
|
return vbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int print_subexpression PROTO ((struct expression *, char *, int));
|
|
|
|
|
|
|
|
static int print_subexpression (expr, buf, len)
|
|
|
|
struct expression *expr;
|
|
|
|
char *buf;
|
|
|
|
int len;
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
switch (expr -> op) {
|
|
|
|
case expr_none:
|
|
|
|
if (len > 3) {
|
|
|
|
strcpy (buf, "nil");
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_match:
|
|
|
|
if (len > 7) {
|
|
|
|
strcpy (buf, "(match)");
|
|
|
|
return 7;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_check:
|
|
|
|
rv = 10 + strlen (expr -> data.check -> name);
|
|
|
|
if (len > rv) {
|
|
|
|
sprintf (buf, "(check %s)",
|
|
|
|
expr -> data.check -> name);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_equal:
|
|
|
|
if (len > 6) {
|
|
|
|
rv = 4;
|
|
|
|
strcpy (buf, "(eq ");
|
|
|
|
rv += print_subexpression (expr -> data.equal [0],
|
|
|
|
buf + rv, len - rv - 2);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression (expr -> data.equal [1],
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_substring:
|
|
|
|
if (len > 11) {
|
|
|
|
rv = 8;
|
|
|
|
strcpy (buf, "(substr ");
|
|
|
|
rv += print_subexpression (expr -> data.substring.expr,
|
|
|
|
buf + rv, len - rv - 3);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression
|
|
|
|
(expr -> data.substring.offset,
|
|
|
|
buf + rv, len - rv - 2);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression (expr -> data.substring.len,
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_suffix:
|
|
|
|
if (len > 10) {
|
|
|
|
rv = 8;
|
|
|
|
strcpy (buf, "(substr ");
|
|
|
|
rv += print_subexpression (expr -> data.suffix.expr,
|
|
|
|
buf + rv, len - rv - 2);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression (expr -> data.suffix.len,
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_concat:
|
|
|
|
if (len > 10) {
|
|
|
|
rv = 8;
|
|
|
|
strcpy (buf, "(concat ");
|
|
|
|
rv += print_subexpression (expr -> data.concat [0],
|
|
|
|
buf + rv, len - rv - 2);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression (expr -> data.concat [1],
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_host_lookup:
|
|
|
|
rv = 15 + strlen (expr -> data.host_lookup -> hostname);
|
|
|
|
if (len > rv) {
|
|
|
|
sprintf (buf, "(dns-lookup %s)",
|
|
|
|
expr -> data.host_lookup -> hostname);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_and:
|
|
|
|
if (len > 7) {
|
|
|
|
rv = 5;
|
|
|
|
strcpy (buf, "(and ");
|
|
|
|
rv += print_subexpression (expr -> data.and [0],
|
|
|
|
buf + rv, len - rv - 2);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression (expr -> data.and [1],
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_or:
|
|
|
|
if (len > 6) {
|
|
|
|
rv = 4;
|
|
|
|
strcpy (buf, "(or ");
|
|
|
|
rv += print_subexpression (expr -> data.or [0],
|
|
|
|
buf + rv, len - rv - 2);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression (expr -> data.or [1],
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_not:
|
|
|
|
if (len > 6) {
|
|
|
|
rv = 5;
|
|
|
|
strcpy (buf, "(not ");
|
|
|
|
rv += print_subexpression (expr -> data.not,
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_option:
|
|
|
|
rv = 10 + (strlen (expr -> data.option -> name) +
|
|
|
|
strlen (expr -> data.option -> universe -> name));
|
|
|
|
if (len > rv) {
|
|
|
|
sprintf (buf, "(option %s.%s)",
|
|
|
|
expr -> data.option -> universe -> name,
|
|
|
|
expr -> data.option -> name);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_hardware:
|
|
|
|
if (len > 10) {
|
|
|
|
strcpy (buf, "(hardware)");
|
|
|
|
return 10;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_packet:
|
|
|
|
if (len > 10) {
|
|
|
|
rv = 8;
|
|
|
|
strcpy (buf, "(substr ");
|
|
|
|
rv += print_subexpression (expr -> data.packet.offset,
|
|
|
|
buf + rv, len - rv - 2);
|
|
|
|
buf [rv++] = ' ';
|
|
|
|
rv += print_subexpression (expr -> data.packet.len,
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_const_data:
|
|
|
|
s = print_hex_1 (expr -> data.const_data.len,
|
|
|
|
expr -> data.const_data.data, len);
|
|
|
|
rv = strlen (s);
|
|
|
|
if (rv >= len)
|
|
|
|
rv = len - 1;
|
|
|
|
strncpy (buf, s, rv);
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
case expr_extract_int8:
|
|
|
|
if (len > 7) {
|
|
|
|
rv = 6;
|
|
|
|
strcpy (buf, "(int8 ");
|
|
|
|
rv += print_subexpression (expr -> data.extract_int,
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_extract_int16:
|
|
|
|
if (len > 8) {
|
|
|
|
rv = 7;
|
|
|
|
strcpy (buf, "(int16 ");
|
|
|
|
rv += print_subexpression (expr -> data.extract_int,
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_extract_int32:
|
|
|
|
if (len > 8) {
|
|
|
|
rv = 7;
|
|
|
|
strcpy (buf, "(int32 ");
|
|
|
|
rv += print_subexpression (expr -> data.extract_int,
|
|
|
|
buf + rv, len - rv - 1);
|
|
|
|
buf [rv++] = ')';
|
|
|
|
buf [rv] = 0;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_const_int:
|
|
|
|
s = print_dec_1 (expr -> data.const_int);
|
|
|
|
rv = strlen (s);
|
|
|
|
if (len > rv) {
|
|
|
|
strcpy (buf, s);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case expr_exists:
|
|
|
|
rv = 10 + (strlen (expr -> data.option -> name) +
|
|
|
|
strlen (expr -> data.option -> universe -> name));
|
|
|
|
if (len > rv) {
|
|
|
|
sprintf (buf, "(exists %s.%s)",
|
|
|
|
expr -> data.option -> universe -> name,
|
|
|
|
expr -> data.option -> name);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_expression (name, expr)
|
|
|
|
char *name;
|
|
|
|
struct expression *expr;
|
|
|
|
{
|
|
|
|
char buf [1024];
|
|
|
|
|
|
|
|
print_subexpression (expr, buf, sizeof buf);
|
1999-02-24 17:56:53 +00:00
|
|
|
log_info ("%s: %s", name, buf);
|
1998-11-05 18:44:11 +00:00
|
|
|
}
|
|
|
|
|