Imported Upstream version 2.5.2p1
[debian/amanda] / common-src / util.c
index d168b6f1c3143a7956f24c347baf01bcb23a1232..bb27cfac0618d1af986bd06eae9a231d61111a0e 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: util.c,v 1.42.2.13 2007/01/24 18:33:29 martinea Exp $
+ * $Id: util.c,v 1.42 2006/08/24 01:57:15 paddy_s Exp $
  */
 
 #include "amanda.h"
 #include "arglist.h"
 #include "clock.h"
 
-int allow_overwrites;
-int token_pushed;
-
-tok_t tok, pushed_tok;
-val_t tokenval;
-keytab_t *keytable;
-
-int conf_line_num, got_parserror;
-FILE *conf_conf = (FILE *)NULL;
-char *conf_confname = NULL;
-char *conf_line = NULL;
-char *conf_char = NULL;
-
 /*#define NET_READ_DEBUG*/
 
 #ifdef NET_READ_DEBUG
@@ -53,12 +40,9 @@ char *conf_char = NULL;
 #define netprintf(x)
 #endif
 
-static int make_socket(void);
-static int connect_port(struct sockaddr_in *addrp, in_port_t port, char *proto,
-                       struct sockaddr_in *svaddr, int nonblock);
-
-int conftoken_getc(void);
-int conftoken_ungetc(int c);
+static int make_socket(sa_family_t family);
+static int connect_port(struct sockaddr_storage *addrp, in_port_t port, char *proto,
+                       struct sockaddr_storage *svaddr, int nonblock);
 
 /*
  * Keep calling read() until we've read buflen's worth of data, or EOF,
@@ -123,7 +107,8 @@ fullwrite(
 }
 
 static int
-make_socket(void)
+make_socket(
+    sa_family_t family)
 {
     int s;
     int save_errno;
@@ -132,10 +117,11 @@ make_socket(void)
     int r;
 #endif
 
-    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+    s = socket(family, SOCK_STREAM, 0);
+    if (s == -1) {
         save_errno = errno;
         dbprintf(("%s: make_socket: socket() failed: %s\n",
-                  debug_prefix(NULL),
+                  debug_prefix_time(NULL),
                   strerror(save_errno)));
         errno = save_errno;
         return -1;
@@ -151,7 +137,7 @@ make_socket(void)
     if (r < 0) {
        save_errno = errno;
        dbprintf(("%s: stream_server: setsockopt(SO_REUSEADDR) failed: %s\n",
-                 debug_prefix(NULL),
+                 debug_prefix_time(NULL),
                  strerror(errno)));
        errno = save_errno;
     }
@@ -163,7 +149,7 @@ make_socket(void)
     if (r == -1) {
        save_errno = errno;
        dbprintf(("%s: make_socket: setsockopt() failed: %s\n",
-                  debug_prefix(NULL),
+                  debug_prefix_time(NULL),
                   strerror(save_errno)));
        aclose(s);
        errno = save_errno;
@@ -180,11 +166,11 @@ make_socket(void)
 /* return -1     on failure */
 int
 connect_portrange(
-    struct sockaddr_in *addrp,
+    struct sockaddr_storage *addrp,
     in_port_t          first_port,
     in_port_t          last_port,
     char *             proto,
-    struct sockaddr_in *svaddr,
+    struct sockaddr_storage *svaddr,
     int                        nonblock)
 {
     int                        s;
@@ -194,7 +180,6 @@ connect_portrange(
     int                        i;
 
     assert(first_port <= last_port);
-
     /* Try a port already used */
     for(i=0; i < nb_port_in_use; i++) {
        port = port_in_use[i];
@@ -232,15 +217,16 @@ connect_portrange(
 /* return >0: this is the connected socket */
 int
 connect_port(
-    struct sockaddr_in *addrp,
+    struct sockaddr_storage *addrp,
     in_port_t                  port,
     char *             proto,
-    struct sockaddr_in *svaddr,
+    struct sockaddr_storage *svaddr,
     int                        nonblock)
 {
     int                        save_errno;
     struct servent *   servPort;
     socklen_t          len;
+    socklen_t          socklen;
     int                        s;
 
     servPort = getservbyport((int)htons(port), proto);
@@ -258,11 +244,11 @@ connect_port(
                  debug_prefix_time(NULL), port, servPort->s_name));
     }
 
-    if ((s = make_socket()) == -1) return -2;
+    if ((s = make_socket(addrp->ss_family)) == -1) return -2;
 
-    addrp->sin_port = (in_port_t)htons(port);
-
-    if (bind(s, (struct sockaddr *)addrp, sizeof(*addrp)) != 0) {
+    SS_SET_PORT(addrp, port);
+    socklen = SS_LEN(addrp);
+    if (bind(s, (struct sockaddr *)addrp, socklen) != 0) {
        save_errno = errno;
        aclose(s);
        if (save_errno != EADDRINUSE) {
@@ -281,7 +267,7 @@ connect_port(
     if (getsockname(s, (struct sockaddr *)addrp, &len) == -1) {
        save_errno = errno;
        dbprintf(("%s: connect_port: getsockname() failed: %s\n",
-                 debug_prefix(NULL),
+                 debug_prefix_time(NULL),
                  strerror(save_errno)));
        aclose(s);
        errno = save_errno;
@@ -290,18 +276,15 @@ connect_port(
 
     if (nonblock)
        fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0)|O_NONBLOCK);
-    if (connect(s, (struct sockaddr *)svaddr,
-               (socklen_t)sizeof(*svaddr)) == -1 && !nonblock) {
+    if (connect(s, (struct sockaddr *)svaddr, SS_LEN(svaddr)) == -1 && !nonblock) {
        save_errno = errno;
-       dbprintf(("%s: connect_portrange: connect from %s.%d failed: %s\n",
+       dbprintf(("%s: connect_portrange: connect from %s failed: %s\n",
                  debug_prefix_time(NULL),
-                 inet_ntoa(addrp->sin_addr),
-                 ntohs(addrp->sin_port),
+                 str_sockaddr(addrp),
                  strerror(save_errno)));
-       dbprintf(("%s: connect_portrange: connect to %s.%d failed: %s\n",
+       dbprintf(("%s: connect_portrange: connect to %s failed: %s\n",
                  debug_prefix_time(NULL),
-                 inet_ntoa(svaddr->sin_addr),
-                 ntohs(svaddr->sin_port),
+                 str_sockaddr(svaddr),
                  strerror(save_errno)));
        aclose(s);
        errno = save_errno;
@@ -314,14 +297,12 @@ connect_port(
        return -1;
     }
 
-    dbprintf(("%s: connected to %s.%d\n",
+    dbprintf(("%s: connected to %s\n",
               debug_prefix_time(NULL),
-              inet_ntoa(svaddr->sin_addr),
-              ntohs(svaddr->sin_port)));
-    dbprintf(("%s: our side is %s.%d\n",
-              debug_prefix(NULL),
-              inet_ntoa(addrp->sin_addr),
-              ntohs(addrp->sin_port)));
+              str_sockaddr(svaddr)));
+    dbprintf(("%s: our side is %s\n",
+              debug_prefix_time(NULL),
+              str_sockaddr(addrp)));
     return s;
 }
 
@@ -335,13 +316,14 @@ connect_port(
 int
 bind_portrange(
     int                        s,
-    struct sockaddr_in *addrp,
+    struct sockaddr_storage *addrp,
     in_port_t          first_port,
     in_port_t          last_port,
     char *             proto)
 {
     in_port_t port;
     in_port_t cnt;
+    socklen_t socklen;
     struct servent *servPort;
     const in_port_t num_ports = (in_port_t)(last_port - first_port + 1);
 
@@ -368,8 +350,9 @@ bind_portrange(
                dbprintf(("%s: bind_portrange2: Try  port %d: Owned by %s - ",
                      debug_prefix_time(NULL), port, servPort->s_name));
            }
-           addrp->sin_port = (in_port_t)htons(port);
-           if (bind(s, (struct sockaddr *)addrp, (socklen_t)sizeof(*addrp)) >= 0) {
+           SS_SET_PORT(addrp, port);
+           socklen = SS_LEN(addrp);
+           if (bind(s, (struct sockaddr *)addrp, socklen) >= 0) {
                dbprintf(("Success\n"));
                return 0;
            }
@@ -607,14 +590,14 @@ hexdump(
 {
     ssize_t rc = -1;
 
-    FILE *stream = popen("od -w10 -c -x -", "w");
+    FILE *stream = popen("od -c -x -", "w");
        
     if (stream != NULL) {
        fflush(stdout);
        rc = (ssize_t)fwrite(buffer, len, 1, stream);
        if (ferror(stream))
            rc = -1;
-       fclose(stream);
+       pclose(stream);
     }
     return rc;
 }
@@ -633,2074 +616,137 @@ validate_mailto(
 }
 
 
-t_conf_var *
-get_np(
-    t_conf_var *get_var,
-    int        parm)
-{
-    t_conf_var *np;
-
-    for(np = get_var; np->token != CONF_UNKNOWN; np++) {
-       if(np->parm == parm)
-           break;
-    }
-
-    if(np->token == CONF_UNKNOWN) {
-       error("error [unknown getconf_np parm: %d]", parm);
-       /* NOTREACHED */
-    }
-    return np;
-}
-
 void
-get_simple(
-    val_t  *var,
-    tok_t  type)
-{
-    ckseen(&var->seen);
-
-    switch(type) {
-    case CONF_STRING:
-    case CONF_IDENT:
-       get_conftoken(type);
-       var->v.s = newstralloc(var->v.s, tokenval.v.s);
-       malloc_mark(var->v.s);
-       break;
-
-    case CONF_INT:
-       var->v.i = get_int();
-       break;
-
-    case CONF_LONG:
-       var->v.l = get_long();
-       break;
-
-    case CONF_SIZE:
-       var->v.size = get_size();
-       break;
-
-    case CONF_AM64:
-       var->v.am64 = get_am64_t();
-       break;
-
-    case CONF_BOOL:
-       var->v.i = get_bool();
-       break;
-
-    case CONF_REAL:
-       get_conftoken(CONF_REAL);
-       var->v.r = tokenval.v.r;
-       break;
-
-    case CONF_TIME:
-       var->v.t = get_time();
-       break;
-
-    default:
-       error("error [unknown get_simple type: %d]", type);
-       /* NOTREACHED */
-    }
-    return;
-}
-
-time_t
-get_time(void)
-{
-    time_t hhmm;
-
-    get_conftoken(CONF_ANY);
-    switch(tok) {
-    case CONF_INT:
-#if SIZEOF_TIME_T < SIZEOF_INT
-       if ((off_t)tokenval.v.i >= (off_t)TIME_MAX)
-           conf_parserror("value too large");
-#endif
-       hhmm = (time_t)tokenval.v.i;
-       break;
-
-    case CONF_LONG:
-#if SIZEOF_TIME_T < SIZEOF_LONG
-       if ((off_t)tokenval.v.l >= (off_t)TIME_MAX)
-           conf_parserror("value too large");
-#endif
-       hhmm = (time_t)tokenval.v.l;
-       break;
-
-    case CONF_SIZE:
-#if SIZEOF_TIME_T < SIZEOF_SSIZE_T
-       if ((off_t)tokenval.v.size >= (off_t)TIME_MAX)
-           conf_parserror("value too large");
-#endif
-       hhmm = (time_t)tokenval.v.size;
-       break;
-
-    case CONF_AM64:
-#if SIZEOF_TIME_T < SIZEOF_LONG_LONG
-       if ((off_t)tokenval.v.am64 >= (off_t)TIME_MAX)
-           conf_parserror("value too large");
-#endif
-       hhmm = (time_t)tokenval.v.am64;
-       break;
-
-    case CONF_AMINFINITY:
-       hhmm = TIME_MAX;
-       break;
-
-    default:
-       conf_parserror("a time is expected");
-       hhmm = 0;
-       break;
-    }
-    return hhmm;
-}
-
-keytab_t numb_keytable[] = {
-    { "B", CONF_MULT1 },
-    { "BPS", CONF_MULT1 },
-    { "BYTE", CONF_MULT1 },
-    { "BYTES", CONF_MULT1 },
-    { "DAY", CONF_MULT1 },
-    { "DAYS", CONF_MULT1 },
-    { "INF", CONF_AMINFINITY },
-    { "K", CONF_MULT1K },
-    { "KB", CONF_MULT1K },
-    { "KBPS", CONF_MULT1K },
-    { "KBYTE", CONF_MULT1K },
-    { "KBYTES", CONF_MULT1K },
-    { "KILOBYTE", CONF_MULT1K },
-    { "KILOBYTES", CONF_MULT1K },
-    { "KPS", CONF_MULT1K },
-    { "M", CONF_MULT1M },
-    { "MB", CONF_MULT1M },
-    { "MBPS", CONF_MULT1M },
-    { "MBYTE", CONF_MULT1M },
-    { "MBYTES", CONF_MULT1M },
-    { "MEG", CONF_MULT1M },
-    { "MEGABYTE", CONF_MULT1M },
-    { "MEGABYTES", CONF_MULT1M },
-    { "G", CONF_MULT1G },
-    { "GB", CONF_MULT1G },
-    { "GBPS", CONF_MULT1G },
-    { "GBYTE", CONF_MULT1G },
-    { "GBYTES", CONF_MULT1G },
-    { "GIG", CONF_MULT1G },
-    { "GIGABYTE", CONF_MULT1G },
-    { "GIGABYTES", CONF_MULT1G },
-    { "MPS", CONF_MULT1M },
-    { "TAPE", CONF_MULT1 },
-    { "TAPES", CONF_MULT1 },
-    { "WEEK", CONF_MULT7 },
-    { "WEEKS", CONF_MULT7 },
-    { NULL, CONF_IDENT }
-};
-
-int
-get_int(void)
+dump_sockaddr(
+    struct sockaddr_storage *sa)
 {
-    int val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(CONF_ANY);
-    switch(tok) {
-    case CONF_INT:
-       val = tokenval.v.i;
-       break;
-
-    case CONF_LONG:
-#if SIZEOF_INT < SIZEOF_LONG
-       if ((off_t)tokenval.v.l > (off_t)INT_MAX)
-           conf_parserror("value too large");
-       if ((off_t)tokenval.v.l < (off_t)INT_MIN)
-           conf_parserror("value too small");
-#endif
-       val = (int)tokenval.v.l;
-       break;
-
-    case CONF_SIZE:
-#if SIZEOF_INT < SIZEOF_SSIZE_T
-       if ((off_t)tokenval.v.size > (off_t)INT_MAX)
-           conf_parserror("value too large");
-       if ((off_t)tokenval.v.size < (off_t)INT_MIN)
-           conf_parserror("value too small");
+#ifdef WORKING_IPV6
+    char ipstr[INET6_ADDRSTRLEN];
+#else
+    char ipstr[INET_ADDRSTRLEN];
 #endif
-       val = (int)tokenval.v.size;
-       break;
-
-    case CONF_AM64:
-#if SIZEOF_INT < SIZEOF_LONG_LONG
-       if (tokenval.v.am64 > (off_t)INT_MAX)
-           conf_parserror("value too large");
-       if (tokenval.v.am64 < (off_t)INT_MIN)
-           conf_parserror("value too small");
+    int port;
+
+    port = SS_GET_PORT(sa);
+#ifdef WORKING_IPV6
+    if ( sa->ss_family == (sa_family_t)AF_INET6) {
+       inet_ntop(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr,
+                 ipstr, sizeof(ipstr));
+       dbprintf(("%s: (sockaddr_in6 *)%p = { %d, %d, %s }\n",
+                 debug_prefix_time(NULL), sa,
+                 ((struct sockaddr_in6 *)sa)->sin6_family,
+                 port,
+                 ipstr));
+    } else
 #endif
-       val = (int)tokenval.v.am64;
-       break;
-
-    case CONF_AMINFINITY:
-       val = INT_MAX;
-       break;
-
-    default:
-       conf_parserror("an int is expected");
-       val = 0;
-       break;
-    }
-
-    /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_END:
-    case CONF_MULT1:
-    case CONF_MULT1K:
-       break;
-
-    case CONF_MULT7:
-       if (val > (INT_MAX / 7))
-           conf_parserror("value too large");
-       if (val < (INT_MIN / 7))
-           conf_parserror("value too small");
-       val *= 7;
-       break;
-
-    case CONF_MULT1M:
-       if (val > (INT_MAX / 1024))
-           conf_parserror("value too large");
-       if (val < (INT_MIN / 1024))
-           conf_parserror("value too small");
-       val *= 1024;
-       break;
-
-    case CONF_MULT1G:
-       if (val > (INT_MAX / (1024 * 1024)))
-           conf_parserror("value too large");
-       if (val < (INT_MIN / (1024 * 1024)))
-           conf_parserror("value too small");
-       val *= 1024 * 1024;
-       break;
-
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-       break;
+    {
+       inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, ipstr,
+                 sizeof(ipstr));
+       dbprintf(("%s: (sockaddr_in *)%p = { %d, %d, %s }\n",
+                 debug_prefix_time(NULL), sa,
+                 ((struct sockaddr_in *)sa)->sin_family,
+                 port,
+                 ipstr));
     }
-
-    keytable = save_kt;
-    return val;
 }
 
-long
-get_long(void)
-{
-    long val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(CONF_ANY);
 
-    switch(tok) {
-    case CONF_LONG:
-       val = tokenval.v.l;
-       break;
-
-    case CONF_INT:
-#if SIZEOF_LONG < SIZEOF_INT
-       if ((off_t)tokenval.v.i > (off_t)LONG_MAX)
-           conf_parserror("value too large");
-       if ((off_t)tokenval.v.i < (off_t)LONG_MIN)
-           conf_parserror("value too small");
-#endif
-       val = (long)tokenval.v.i;
-       break;
-
-    case CONF_SIZE:
-#if SIZEOF_LONG < SIZEOF_SSIZE_T
-       if ((off_t)tokenval.v.size > (off_t)LONG_MAX)
-           conf_parserror("value too large");
-       if ((off_t)tokenval.v.size < (off_t)LONG_MIN)
-           conf_parserror("value too small");
-#endif
-       val = (long)tokenval.v.size;
-       break;
-
-    case CONF_AM64:
-#if SIZEOF_LONG < SIZEOF_LONG_LONG
-       if (tokenval.v.am64 > (off_t)LONG_MAX)
-           conf_parserror("value too large");
-       if (tokenval.v.am64 < (off_t)LONG_MIN)
-           conf_parserror("value too small");
+#ifdef WORKING_IPV6
+static char mystr_sockaddr[INET6_ADDRSTRLEN + 20];
+#else
+static char mystr_sockaddr[INET_ADDRSTRLEN + 20];
 #endif
-       val = (long)tokenval.v.am64;
-       break;
-
-    case CONF_AMINFINITY:
-       val = (long)LONG_MAX;
-       break;
-
-    default:
-       conf_parserror("a long is expected");
-       val = 0;
-       break;
-    }
-
-    /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_MULT1:
-    case CONF_MULT1K:
-       break;
-
-    case CONF_MULT7:
-       if (val > (LONG_MAX / 7L))
-           conf_parserror("value too large");
-       if (val < (LONG_MIN / 7L))
-           conf_parserror("value too small");
-       val *= 7L;
-       break;
-
-    case CONF_MULT1M:
-       if (val > (LONG_MAX / 1024L))
-           conf_parserror("value too large");
-       if (val < (LONG_MIN / 1024L))
-           conf_parserror("value too small");
-       val *= 1024L;
-       break;
-
-    case CONF_MULT1G:
-       if (val > (LONG_MAX / (1024L * 1024L)))
-           conf_parserror("value too large");
-       if (val < (LONG_MIN / (1024L * 1024L)))
-           conf_parserror("value too small");
-       val *= 1024L * 1024L;
-       break;
-
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-       break;
-    }
-
-    keytable = save_kt;
-    return val;
-}
 
-ssize_t
-get_size(void)
+char *
+str_sockaddr(
+    struct sockaddr_storage *sa)
 {
-    ssize_t val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_SIZE:
-       val = tokenval.v.size;
-       break;
-
-    case CONF_INT:
-#if SIZEOF_SIZE_T < SIZEOF_INT
-       if ((off_t)tokenval.v.i > (off_t)SSIZE_MAX)
-           conf_parserror("value too large");
-       if ((off_t)tokenval.v.i < (off_t)SSIZE_MIN)
-           conf_parserror("value too small");
-#endif
-       val = (ssize_t)tokenval.v.i;
-       break;
-
-    case CONF_LONG:
-#if SIZEOF_SIZE_T < SIZEOF_LONG
-       if ((off_t)tokenval.v.l > (off_t)SSIZE_MAX)
-           conf_parserror("value too large");
-       if ((off_t)tokenval.v.l < (off_t)SSIZE_MIN)
-           conf_parserror("value too small");
+#ifdef WORKING_IPV6
+    char ipstr[INET6_ADDRSTRLEN];
+#else
+    char ipstr[INET_ADDRSTRLEN];
 #endif
-       val = (ssize_t)tokenval.v.l;
-       break;
-
-    case CONF_AM64:
-#if SIZEOF_SIZE_T < SIZEOF_LONG_LONG
-       if (tokenval.v.am64 > (off_t)SSIZE_MAX)
-           conf_parserror("value too large");
-       if (tokenval.v.am64 < (off_t)SSIZE_MIN)
-           conf_parserror("value too small");
+    int port;
+
+    port = SS_GET_PORT(sa);
+#ifdef WORKING_IPV6
+    if ( sa->ss_family == (sa_family_t)AF_INET6) {
+       inet_ntop(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr,
+                 ipstr, sizeof(ipstr));
+    } else
 #endif
-       val = (ssize_t)tokenval.v.am64;
-       break;
-
-    case CONF_AMINFINITY:
-       val = (ssize_t)SSIZE_MAX;
-       break;
-
-    default:
-       conf_parserror("an integer is expected");
-       val = 0;
-       break;
-    }
-
-    /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_MULT1:
-    case CONF_MULT1K:
-       break;
-
-    case CONF_MULT7:
-       if (val > (ssize_t)(SSIZE_MAX / 7))
-           conf_parserror("value too large");
-       if (val < (ssize_t)(SSIZE_MIN / 7))
-           conf_parserror("value too small");
-       val *= (ssize_t)7;
-       break;
-
-    case CONF_MULT1M:
-       if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
-           conf_parserror("value too large");
-       if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
-           conf_parserror("value too small");
-       val *= (ssize_t)1024;
-       break;
-
-    case CONF_MULT1G:
-       if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
-           conf_parserror("value too large");
-       if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
-           conf_parserror("value too small");
-       val *= (ssize_t)(1024 * 1024);
-       break;
-
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-       break;
-    }
-
-    keytable = save_kt;
-    return val;
-}
-
-off_t
-get_am64_t(void)
-{
-    off_t val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_INT:
-       val = (off_t)tokenval.v.i;
-       break;
-
-    case CONF_LONG:
-       val = (off_t)tokenval.v.l;
-       break;
-
-    case CONF_SIZE:
-       val = (off_t)tokenval.v.size;
-       break;
-
-    case CONF_AM64:
-       val = tokenval.v.am64;
-       break;
-
-    case CONF_AMINFINITY:
-       val = AM64_MAX;
-       break;
-
-    default:
-       conf_parserror("an am64 is expected %d", tok);
-       val = 0;
-       break;
+    {
+       inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, ipstr,
+                 sizeof(ipstr));
     }
-
-    /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_MULT1:
-    case CONF_MULT1K:
-       break;
-
-    case CONF_MULT7:
-       if (val > AM64_MAX/7 || val < AM64_MIN/7)
-           conf_parserror("value too large");
-       val *= 7;
-       break;
-
-    case CONF_MULT1M:
-       if (val > AM64_MAX/1024 || val < AM64_MIN/1024)
-           conf_parserror("value too large");
-       val *= 1024;
-       break;
-
-    case CONF_MULT1G:
-       if (val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
-           conf_parserror("value too large");
-       val *= 1024*1024;
-       break;
-
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-       break;
-    }
-
-    keytable = save_kt;
-
-    return val;
+    snprintf(mystr_sockaddr,sizeof(mystr_sockaddr),"%s.%d", ipstr, port);
+    return mystr_sockaddr;
 }
 
-keytab_t bool_keytable[] = {
-    { "Y", CONF_ATRUE },
-    { "YES", CONF_ATRUE },
-    { "T", CONF_ATRUE },
-    { "TRUE", CONF_ATRUE },
-    { "ON", CONF_ATRUE },
-    { "N", CONF_AFALSE },
-    { "NO", CONF_AFALSE },
-    { "F", CONF_AFALSE },
-    { "FALSE", CONF_AFALSE },
-    { "OFF", CONF_AFALSE },
-    { NULL, CONF_IDENT }
-};
 
 int
-get_bool(void)
-{
-    int val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = bool_keytable;
-
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_INT:
-       if (tokenval.v.i != 0)
-           val = 1;
-       else
-           val = 0;
-       break;
-
-    case CONF_LONG:
-       if (tokenval.v.l != 0L)
-           val = 1;
-       else
-           val = 0;
-       break;
-
-    case CONF_SIZE:
-       if (tokenval.v.size != (size_t)0)
-           val = 1;
-       else
-           val = 0;
-       break;
-
-    case CONF_AM64:
-       if (tokenval.v.am64 != (off_t)0)
-           val = 1;
-       else
-           val = 0;
-       break;
-
-    case CONF_ATRUE:
-       val = 1;
-       break;
-
-    case CONF_AFALSE:
-       val = 0;
-       break;
-
-    case CONF_NL:
-       unget_conftoken();
-       val = 2; /* no argument - most likely TRUE */
-       break;
-    default:
-       unget_conftoken();
-       val = 3; /* a bad argument - most likely TRUE */
-       conf_parserror("YES, NO, TRUE, FALSE, ON, OFF expected");
-       break;
-    }
-
-    keytable = save_kt;
-    return val;
-}
-
-void
-ckseen(
-    int *seen)
-{
-    if (*seen && !allow_overwrites && conf_line_num != -2) {
-       conf_parserror("duplicate parameter, prev def on line %d", *seen);
-    }
-    *seen = conf_line_num;
-}
-
-printf_arglist_function(void conf_parserror, const char *, format)
-{
-    va_list argp;
-
-    /* print error message */
-
-    if(conf_line)
-       fprintf(stderr, "argument \"%s\": ", conf_line);
-    else
-       fprintf(stderr, "\"%s\", line %d: ", conf_confname, conf_line_num);
-    arglist_start(argp, format);
-    vfprintf(stderr, format, argp);
-    arglist_end(argp);
-    fputc('\n', stderr);
-
-    got_parserror = 1;
-}
-
-tok_t
-lookup_keyword(
-    char *     str)
-{
-    keytab_t *kwp;
-
-    /* switch to binary search if performance warrants */
-
-    for(kwp = keytable; kwp->keyword != NULL; kwp++) {
-       if (strcasecmp(kwp->keyword, str) == 0) break;
+cmp_sockaddr(
+    struct sockaddr_storage *ss1,
+    struct sockaddr_storage *ss2,
+    int addr_only)
+{
+    /* if addresses are v4mapped, "unmap" them */
+#ifdef WORKING_IPV6
+#ifdef IN6_IS_ADDR_V4MAPPED
+    struct sockaddr_in ss1_v4;
+    struct sockaddr_in ss2_v4;
+
+    if (ss1->ss_family == AF_INET6 &&
+        IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss1)->sin6_addr)) {
+       memset(&ss1_v4, 0, sizeof(struct sockaddr_in));
+       memcpy(&ss1_v4.sin_addr.s_addr,
+              &(((struct sockaddr_in6 *)ss1)->sin6_addr.s6_addr[12]),
+              sizeof(struct in_addr));
+       ss1_v4.sin_family = AF_INET;
+       SS_SET_PORT((struct sockaddr_storage *)&ss1_v4, SS_GET_PORT(ss1));
+       ss1 = (struct sockaddr_storage *)&ss1_v4;
+    }
+
+    if (ss2->ss_family == AF_INET6 &&
+        IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss2)->sin6_addr)) {
+       memset(&ss2_v4, 0, sizeof(struct sockaddr_in));
+       memcpy(&ss2_v4.sin_addr.s_addr,
+              &(((struct sockaddr_in6 *)ss2)->sin6_addr.s6_addr[12]),
+              sizeof(struct in_addr));
+       ss2_v4.sin_family = AF_INET;
+       SS_SET_PORT((struct sockaddr_storage *)&ss2_v4, SS_GET_PORT(ss2));
+       ss2 = (struct sockaddr_storage *)&ss2_v4;
     }
-    return kwp->token;
-}
-
-char tkbuf[4096];
-
-/* push the last token back (can only unget ANY tokens) */
-void
-unget_conftoken(void)
-{
-    token_pushed = 1;
-    pushed_tok = tok;
-    tok = CONF_UNKNOWN;
-    return;
-}
-
-int
-conftoken_getc(void)
-{
-    if(conf_line == NULL)
-       return getc(conf_conf);
-    if(*conf_char == '\0')
-       return -1;
-    return(*conf_char++);
-}
+#endif
+#endif
 
-int
-conftoken_ungetc(
-    int c)
-{
-    if(conf_line == NULL)
-       return ungetc(c, conf_conf);
-    else if(conf_char > conf_line) {
-       if(c == -1)
-           return c;
-       conf_char--;
-       if(*conf_char != c) {
-           error("*conf_char != c   : %c %c", *conf_char, c);
-           /* NOTREACHED */
-       }
+    if (ss1->ss_family == ss2->ss_family) {
+        if (addr_only) {
+#ifdef WORKING_IPV6
+            if(ss1->ss_family == (sa_family_t)AF_INET6)
+                return memcmp(
+                    &((struct sockaddr_in6 *)ss1)->sin6_addr,
+                    &((struct sockaddr_in6 *)ss2)->sin6_addr,
+                    sizeof(((struct sockaddr_in6 *)ss1)->sin6_addr));
+            else
+#endif
+                return memcmp(
+                    &((struct sockaddr_in *)ss1)->sin_addr,
+                    &((struct sockaddr_in *)ss2)->sin_addr,
+                    sizeof(((struct sockaddr_in *)ss1)->sin_addr));
+        } else {
+            return memcmp(ss1, ss2, SS_LEN(ss1));
+        }
     } else {
-       error("conf_char == conf_line");
-       /* NOTREACHED */
-    }
-    return c;
-}
-
-void
-get_conftoken(
-    tok_t      exp)
-{
-    int ch, d;
-    off_t am64;
-    char *buf;
-    char *tmps;
-    int token_overflow;
-    int inquote = 0;
-    int escape = 0;
-    int sign;
-
-    if (token_pushed) {
-       token_pushed = 0;
-       tok = pushed_tok;
-
-       /*
-       ** If it looked like a key word before then look it
-       ** up again in the current keyword table.
-       */
-       switch(tok) {
-       case CONF_LONG:    case CONF_AM64:    case CONF_SIZE:
-       case CONF_INT:     case CONF_REAL:    case CONF_STRING:
-       case CONF_LBRACE:  case CONF_RBRACE:  case CONF_COMMA:
-       case CONF_NL:      case CONF_END:     case CONF_UNKNOWN:
-       case CONF_TIME:
-           break;
-
-       default:
-           if (exp == CONF_IDENT)
-               tok = CONF_IDENT;
-           else
-               tok = lookup_keyword(tokenval.v.s);
-           break;
-       }
-    }
-    else {
-       ch = conftoken_getc();
-
-       while(ch != EOF && ch != '\n' && isspace(ch))
-           ch = conftoken_getc();
-       if (ch == '#') {        /* comment - eat everything but eol/eof */
-           while((ch = conftoken_getc()) != EOF && ch != '\n') {
-               (void)ch; /* Quiet empty loop complaints */     
-           }
-       }
-
-       if (isalpha(ch)) {              /* identifier */
-           buf = tkbuf;
-           token_overflow = 0;
-           do {
-               if (buf < tkbuf+sizeof(tkbuf)-1) {
-                   *buf++ = (char)ch;
-               } else {
-                   *buf = '\0';
-                   if (!token_overflow) {
-                       conf_parserror("token too long: %.20s...", tkbuf);
-                   }
-                   token_overflow = 1;
-               }
-               ch = conftoken_getc();
-           } while(isalnum(ch) || ch == '_' || ch == '-');
-
-           if (ch != EOF && conftoken_ungetc(ch) == EOF) {
-               if (ferror(conf_conf)) {
-                   conf_parserror("Pushback of '%c' failed: %s",
-                                  ch, strerror(ferror(conf_conf)));
-               } else {
-                   conf_parserror("Pushback of '%c' failed: EOF", ch);
-               }
-           }
-           *buf = '\0';
-
-           tokenval.v.s = tkbuf;
-
-           if (token_overflow) tok = CONF_UNKNOWN;
-           else if (exp == CONF_IDENT) tok = CONF_IDENT;
-           else tok = lookup_keyword(tokenval.v.s);
-       }
-       else if (isdigit(ch)) { /* integer */
-           sign = 1;
-
-negative_number: /* look for goto negative_number below sign is set there */
-           am64 = 0;
-           do {
-               am64 = am64 * 10 + (ch - '0');
-               ch = conftoken_getc();
-           } while (isdigit(ch));
-
-           if (ch != '.') {
-               if (exp == CONF_INT) {
-                   tok = CONF_INT;
-                   tokenval.v.i = sign * (int)am64;
-               } else if (exp == CONF_LONG) {
-                   tok = CONF_LONG;
-                   tokenval.v.l = (long)sign * (long)am64;
-               } else if (exp != CONF_REAL) {
-                   tok = CONF_AM64;
-                   tokenval.v.am64 = (off_t)sign * am64;
-               } else {
-                   /* automatically convert to real when expected */
-                   tokenval.v.r = (double)sign * (double)am64;
-                   tok = CONF_REAL;
-               }
-           } else {
-               /* got a real number, not an int */
-               tokenval.v.r = sign * (double) am64;
-               am64 = 0;
-               d = 1;
-               ch = conftoken_getc();
-               while (isdigit(ch)) {
-                   am64 = am64 * 10 + (ch - '0');
-                   d = d * 10;
-                   ch = conftoken_getc();
-               }
-               tokenval.v.r += sign * ((double)am64) / d;
-               tok = CONF_REAL;
-           }
-
-           if (ch != EOF &&  conftoken_ungetc(ch) == EOF) {
-               if (ferror(conf_conf)) {
-                   conf_parserror("Pushback of '%c' failed: %s",
-                                  ch, strerror(ferror(conf_conf)));
-               } else {
-                   conf_parserror("Pushback of '%c' failed: EOF", ch);
-               }
-           }
-       } else switch(ch) {
-       case '"':                       /* string */
-           buf = tkbuf;
-           token_overflow = 0;
-           inquote = 1;
-           *buf++ = (char)ch;
-           while (inquote && ((ch = conftoken_getc()) != EOF)) {
-               if (ch == '\n') {
-                   if (!escape)
-                       break;
-                   escape = 0;
-                   buf--; /* Consume escape in buffer */
-               } else if (ch == '\\') {
-                   escape = 1;
-               } else {
-                   if (ch == '"') {
-                       if (!escape)
-                           inquote = 0;
-                   }
-                   escape = 0;
-               }
-
-               if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
-                   if (!token_overflow) {
-                       conf_parserror("string too long: %.20s...", tkbuf);
-                   }
-                   token_overflow = 1;
-                   break;
-               }
-               *buf++ = (char)ch;
-           }
-           *buf = '\0';
-
-           /*
-            * A little manuver to leave a fully unquoted, unallocated  string
-            * in tokenval.v.s
-            */
-           tmps = unquote_string(tkbuf);
-           strncpy(tkbuf, tmps, sizeof(tkbuf));
-           amfree(tmps);
-           tokenval.v.s = tkbuf;
-
-           tok = (token_overflow) ? CONF_UNKNOWN :
-                       (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
-           break;
-
-       case '-':
-           ch = conftoken_getc();
-           if (isdigit(ch)) {
-               sign = -1;
-               goto negative_number;
-           }
-           else {
-               if (ch != EOF && conftoken_ungetc(ch) == EOF) {
-                   if (ferror(conf_conf)) {
-                       conf_parserror("Pushback of '%c' failed: %s",
-                                      ch, strerror(ferror(conf_conf)));
-                   } else {
-                       conf_parserror("Pushback of '%c' failed: EOF", ch);
-                   }
-               }
-               tok = CONF_UNKNOWN;
-           }
-           break;
-
-       case ',':
-           tok = CONF_COMMA;
-           break;
-
-       case '{':
-           tok = CONF_LBRACE;
-           break;
-
-       case '}':
-           tok = CONF_RBRACE;
-           break;
-
-       case '\n':
-           tok = CONF_NL;
-           break;
-
-       case EOF:
-           tok = CONF_END;
-           break;
-
-       default:
-           tok = CONF_UNKNOWN;
-           break;
-       }
-    }
-
-    if (exp != CONF_ANY && tok != exp) {
-       char *str;
-       keytab_t *kwp;
-
-       switch(exp) {
-       case CONF_LBRACE:
-           str = "\"{\"";
-           break;
-
-       case CONF_RBRACE:
-           str = "\"}\"";
-           break;
-
-       case CONF_COMMA:
-           str = "\",\"";
-           break;
-
-       case CONF_NL:
-           str = "end of line";
-           break;
-
-       case CONF_END:
-           str = "end of file";
-           break;
-
-       case CONF_INT:
-           str = "an integer";
-           break;
-
-       case CONF_REAL:
-           str = "a real number";
-           break;
-
-       case CONF_STRING:
-           str = "a quoted string";
-           break;
-
-       case CONF_IDENT:
-           str = "an identifier";
-           break;
-
-       default:
-           for(kwp = keytable; kwp->keyword != NULL; kwp++) {
-               if (exp == kwp->token)
-                   break;
-           }
-           if (kwp->keyword == NULL)
-               str = "token not";
-           else
-               str = kwp->keyword;
-           break;
-       }
-       conf_parserror("%s is expected", str);
-       tok = exp;
-       if (tok == CONF_INT)
-           tokenval.v.i = 0;
-       else
-           tokenval.v.s = "";
+        /* compare families to give a total order */
+        if (ss1->ss_family < ss2->ss_family)
+            return -1;
+        else
+            return 1;
     }
 }
 
 
-void
-read_string(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    get_conftoken(CONF_STRING);
-    val->v.s = newstralloc(val->v.s, tokenval.v.s);
-}
-
-void
-read_ident(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    get_conftoken(CONF_IDENT);
-    val->v.s = newstralloc(val->v.s, tokenval.v.s);
-}
-
-void
-read_int(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    val->v.i = get_int();
-}
-
-void
-read_long(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    val->v.l = get_long();
-}
-
-void
-read_size(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    val->v.size = get_size();
-}
-
-void
-read_am64(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    val->v.am64 = get_am64_t();
-}
-
-void
-read_bool(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    val->v.i = get_bool();
-}
-
-void
-read_real(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    get_conftoken(CONF_REAL);
-    val->v.r = tokenval.v.r;
-}
-
-void
-read_time(
-    t_conf_var *np,
-    val_t *val)
-{
-    np = np;
-    ckseen(&val->seen);
-    val->v.t = get_time();
-}
-
-void
-copy_val_t(
-    val_t *valdst,
-    val_t *valsrc)
-{
-    if(valsrc->seen) {
-       valdst->type = valsrc->type;
-       valdst->seen = valsrc->seen;
-       switch(valsrc->type) {
-       case CONFTYPE_INT:
-       case CONFTYPE_BOOL:
-       case CONFTYPE_COMPRESS:
-       case CONFTYPE_ENCRYPT:
-       case CONFTYPE_HOLDING:
-       case CONFTYPE_ESTIMATE:
-       case CONFTYPE_STRATEGY:
-       case CONFTYPE_TAPERALGO:
-       case CONFTYPE_PRIORITY:
-           valdst->v.i = valsrc->v.i;
-           break;
-
-       case CONFTYPE_LONG:
-           valdst->v.l = valsrc->v.l;
-           break;
-
-       case CONFTYPE_SIZE:
-           valdst->v.size = valsrc->v.size;
-           break;
-
-       case CONFTYPE_AM64:
-           valdst->v.am64 = valsrc->v.am64;
-           break;
-
-       case CONFTYPE_REAL:
-           valdst->v.r = valsrc->v.r;
-           break;
-
-       case CONFTYPE_RATE:
-           valdst->v.rate[0] = valsrc->v.rate[0];
-           valdst->v.rate[1] = valsrc->v.rate[1];
-           break;
-
-       case CONFTYPE_IDENT:
-       case CONFTYPE_STRING:
-           valdst->v.s = stralloc(valsrc->v.s);
-           break;
-
-       case CONFTYPE_TIME:
-           valdst->v.t = valsrc->v.t;
-           break;
-
-       case CONFTYPE_SL:
-           valdst->v.sl = duplicate_sl(valsrc->v.sl);
-           break;
-
-       case CONFTYPE_EXINCLUDE:
-           valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
-           valdst->v.exinclude.sl_list = duplicate_sl(valsrc->v.exinclude.sl_list);
-           valdst->v.exinclude.sl_file = duplicate_sl(valsrc->v.exinclude.sl_file);
-           break;
-       }
-    }
-}
-
-void
-free_val_t(
-    val_t *val)
-{
-    switch(val->type) {
-       case CONFTYPE_INT:
-       case CONFTYPE_BOOL:
-       case CONFTYPE_COMPRESS:
-       case CONFTYPE_ENCRYPT:
-       case CONFTYPE_HOLDING:
-       case CONFTYPE_ESTIMATE:
-       case CONFTYPE_STRATEGY:
-       case CONFTYPE_SIZE:
-       case CONFTYPE_TAPERALGO:
-       case CONFTYPE_PRIORITY:
-       case CONFTYPE_LONG:
-       case CONFTYPE_AM64:
-       case CONFTYPE_REAL:
-       case CONFTYPE_RATE:
-           break;
-
-       case CONFTYPE_IDENT:
-       case CONFTYPE_STRING:
-           amfree(val->v.s);
-           break;
-
-       case CONFTYPE_TIME:
-           break;
-
-       case CONFTYPE_SL:
-           free_sl(val->v.sl);
-           break;
-
-       case CONFTYPE_EXINCLUDE:
-           free_sl(val->v.exinclude.sl_list);
-           free_sl(val->v.exinclude.sl_file);
-           break;
-    }
-    val->seen = 0;
-}
-
-char *
-taperalgo2str(
-    int taperalgo)
-{
-    if(taperalgo == ALGO_FIRST) return "FIRST";
-    if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
-    if(taperalgo == ALGO_LARGEST) return "LARGEST";
-    if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
-    if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
-    if(taperalgo == ALGO_LAST) return "LAST";
-    return "UNKNOWN";
-}
-
-static char buffer_conf_print[1025];
-
-char *
-conf_print(
-    val_t *val,
-    int    str_need_quote)
-{
-    buffer_conf_print[0] = '\0';
-    switch(val->type) {
-    case CONFTYPE_INT:
-       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%d", val->v.i);
-       break;
-
-    case CONFTYPE_LONG:
-       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%ld", val->v.l);
-       break;
-
-    case CONFTYPE_SIZE:
-       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), SSIZE_T_FMT,
-               (SSIZE_T_FMT_TYPE)val->v.size);
-       break;
-
-    case CONFTYPE_AM64:
-       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), OFF_T_FMT ,
-                (OFF_T_FMT_TYPE)val->v.am64);
-       break;
-
-    case CONFTYPE_REAL:
-       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%0.5f" , val->v.r);
-       break;
-
-    case CONFTYPE_RATE:
-       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%0.5f %0.5f" , val->v.rate[0], val->v.rate[1]);
-       break;
-
-    case CONFTYPE_IDENT:
-       if(val->v.s) {
-           strncpy(buffer_conf_print, val->v.s, SIZEOF(buffer_conf_print));
-           buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
-       } else
-           buffer_conf_print[0] = '\0';
-       break;
-
-    case CONFTYPE_STRING:
-       if(str_need_quote) {
-           buffer_conf_print[0] = '"';
-           if(val->v.s) {
-               strncpy(&buffer_conf_print[1], val->v.s,
-                       SIZEOF(buffer_conf_print) - 1);
-               buffer_conf_print[SIZEOF(buffer_conf_print) - 2] = '\0';
-               buffer_conf_print[strlen(buffer_conf_print)] = '"';
-           } else {
-               buffer_conf_print[1] = '"';
-               buffer_conf_print[2] = '\0';
-           }
-       } else {
-           if(val->v.s) {
-               strncpy(&buffer_conf_print[0], val->v.s,
-                       SIZEOF(buffer_conf_print));
-               buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
-           } else {
-               buffer_conf_print[0] = '\0';
-           }
-       }
-       break;
-
-    case CONFTYPE_TIME:
-       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print),
-                "%2d%02d", (int)val->v.t/100, (int)val->v.t % 100);
-       break;
-
-    case CONFTYPE_SL:
-       buffer_conf_print[0] = '\0';
-       break;
-
-    case CONFTYPE_EXINCLUDE:
-       strcpy(buffer_conf_print, "ERROR: use print_conf_exinclude");
-       break;
-
-    case CONFTYPE_BOOL:
-       if(val->v.i)
-           strncpy(buffer_conf_print, "yes", SIZEOF(buffer_conf_print));
-       else
-           strncpy(buffer_conf_print, "no", SIZEOF(buffer_conf_print));
-       break;
-
-    case CONFTYPE_STRATEGY:
-       switch(val->v.i) {
-       case DS_SKIP:
-           strncpy(buffer_conf_print, "SKIP", SIZEOF(buffer_conf_print));
-           break;
-
-       case DS_STANDARD:
-           strncpy(buffer_conf_print, "STANDARD", SIZEOF(buffer_conf_print));
-           break;
-
-       case DS_NOFULL:
-           strncpy(buffer_conf_print, "NOFULL", SIZEOF(buffer_conf_print));
-           break;
-
-       case DS_NOINC:
-           strncpy(buffer_conf_print, "NOINC", SIZEOF(buffer_conf_print));
-           break;
-
-       case DS_HANOI:
-           strncpy(buffer_conf_print, "HANOI", SIZEOF(buffer_conf_print));
-           break;
-
-       case DS_INCRONLY:
-           strncpy(buffer_conf_print, "INCRONLY", SIZEOF(buffer_conf_print));
-           break;
-       }
-       break;
-
-    case CONFTYPE_COMPRESS:
-       switch(val->v.i) {
-       case COMP_NONE:
-           strncpy(buffer_conf_print, "NONE", SIZEOF(buffer_conf_print));
-           break;
-
-       case COMP_FAST:
-           strncpy(buffer_conf_print, "CLIENT FAST", SIZEOF(buffer_conf_print));
-           break;
-
-       case COMP_BEST:
-           strncpy(buffer_conf_print, "CLIENT BEST", SIZEOF(buffer_conf_print));
-           break;
-
-       case COMP_CUST:
-           strncpy(buffer_conf_print, "CLIENT CUSTOM", SIZEOF(buffer_conf_print));
-           break;
-
-       case COMP_SERV_FAST:
-           strncpy(buffer_conf_print, "SERVER FAST", SIZEOF(buffer_conf_print));
-           break;
-
-       case COMP_SERV_BEST:
-           strncpy(buffer_conf_print, "SERVER FAST", SIZEOF(buffer_conf_print));
-           break;
-
-       case COMP_SERV_CUST:
-           strncpy(buffer_conf_print, "SERVER CUSTOM", SIZEOF(buffer_conf_print));
-           break;
-       }
-       break;
-
-    case CONFTYPE_ESTIMATE:
-       switch(val->v.i) {
-       case ES_CLIENT:
-           strncpy(buffer_conf_print, "CLIENT", SIZEOF(buffer_conf_print));
-           break;
-
-       case ES_SERVER:
-           strncpy(buffer_conf_print, "SERVER", SIZEOF(buffer_conf_print));
-           break;
-
-       case ES_CALCSIZE:
-           strncpy(buffer_conf_print, "CALCSIZE", SIZEOF(buffer_conf_print));
-           break;
-       }
-       break;
-
-     case CONFTYPE_ENCRYPT:
-       switch(val->v.i) {
-       case ENCRYPT_NONE:
-           strncpy(buffer_conf_print, "NONE", SIZEOF(buffer_conf_print));
-           break;
-
-       case ENCRYPT_CUST:
-           strncpy(buffer_conf_print, "CLIENT", SIZEOF(buffer_conf_print));
-           break;
-
-       case ENCRYPT_SERV_CUST:
-           strncpy(buffer_conf_print, "SERVER", SIZEOF(buffer_conf_print));
-           break;
-       }
-       break;
-
-     case CONFTYPE_HOLDING:
-       switch(val->v.i) {
-       case HOLD_NEVER:
-           strncpy(buffer_conf_print, "NEVER", SIZEOF(buffer_conf_print));
-           break;
-
-       case HOLD_AUTO:
-           strncpy(buffer_conf_print, "AUTO", SIZEOF(buffer_conf_print));
-           break;
-
-       case HOLD_REQUIRED:
-           strncpy(buffer_conf_print, "REQUIRED", SIZEOF(buffer_conf_print));
-           break;
-       }
-       break;
-
-     case CONFTYPE_TAPERALGO:
-       strncpy(buffer_conf_print, taperalgo2str(val->v.i), SIZEOF(buffer_conf_print));
-       break;
-
-     case CONFTYPE_PRIORITY:
-       switch(val->v.i) {
-       case 0:
-           strncpy(buffer_conf_print, "LOW", SIZEOF(buffer_conf_print));
-           break;
-
-       case 1:
-           strncpy(buffer_conf_print, "MEDIUM", SIZEOF(buffer_conf_print));
-           break;
-
-       case 2:
-           strncpy(buffer_conf_print, "HIGH", SIZEOF(buffer_conf_print));
-           break;
-       }
-       break;
-    }
-    buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
-    return buffer_conf_print;
-}
-
-char *
-conf_print_exinclude(
-    val_t *val,
-    int    str_need_quote,
-    int    file)
-{
-    int    pos;
-    sl_t  *sl;
-    sle_t *excl;
-
-    (void)str_need_quote;
-    buffer_conf_print[0] = '\0';
-    if (val->type != CONFTYPE_EXINCLUDE) {
-       strcpy(buffer_conf_print, "ERROR: conf_print_exinclude called for type != CONFTYPE_EXINCLUDE");
-       return buffer_conf_print;
-    }
-
-    if (file == 0) {
-       sl = val->v.exinclude.sl_list;
-       strncpy(buffer_conf_print, "LIST ", SIZEOF(buffer_conf_print));
-       pos = 5;
-    } else {
-       sl = val->v.exinclude.sl_file;
-       strncpy(buffer_conf_print, "FILE ", SIZEOF(buffer_conf_print));
-       pos = 5;
-    }
-
-    if(val->v.exinclude.optional == 1) {
-       strncpy(&buffer_conf_print[pos], "OPTIONAL ", SIZEOF(buffer_conf_print)-pos);
-       pos += 9;
-    }
-
-    if( sl != NULL) {
-       for(excl = sl->first; excl != NULL; excl = excl->next) {
-           if (pos + 3 + strlen(excl->name) < SIZEOF(buffer_conf_print)) {
-               buffer_conf_print[pos++] = ' ';
-               buffer_conf_print[pos++] = '"';
-               strcpy(&buffer_conf_print[pos], excl->name);
-               pos += strlen(excl->name);
-               buffer_conf_print[pos++] = '"';
-           }
-       }
-    }
-
-    buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
-    return buffer_conf_print;
-}
-
-void
-conf_init_string(
-    val_t *val,
-    char  *s)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_STRING;
-    if(s)
-       val->v.s = stralloc(s);
-    else
-       val->v.s = NULL;
-}
-
-void
-conf_init_ident(
-    val_t *val,
-    char  *s)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_IDENT;
-    if(s)
-       val->v.s = stralloc(s);
-    else
-       val->v.s = NULL;
-}
-
-void
-conf_init_int(
-    val_t *val,
-    int    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_INT;
-    val->v.i = i;
-}
-
-void
-conf_init_bool(
-    val_t *val,
-    int    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_BOOL;
-    val->v.i = i;
-}
-
-void
-conf_init_strategy(
-    val_t *val,
-    int    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_STRATEGY;
-    val->v.i = i;
-}
-
-void
-conf_init_estimate(
-    val_t *val,
-    int    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_ESTIMATE;
-    val->v.i = i;
-}
-
-void
-conf_init_taperalgo(
-    val_t *val,
-    int    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_TAPERALGO;
-    val->v.i = i;
-}
-
-void
-conf_init_priority(
-    val_t *val,
-    int    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_PRIORITY;
-    val->v.i = i;
-}
-
-void
-conf_init_compress(
-    val_t *val,
-    comp_t    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_COMPRESS;
-    val->v.i = (int)i;
-}
-
-void
-conf_init_encrypt(
-    val_t *val,
-    encrypt_t    i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_ENCRYPT;
-    val->v.i = (int)i;
-}
-
-void
-conf_init_holding(
-    val_t              *val,
-    dump_holdingdisk_t  i)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_HOLDING;
-    val->v.i = (int)i;
-}
-
-void
-conf_init_long(
-    val_t *val,
-    long   l)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_LONG;
-    val->v.l = l;
-}
-
-void
-conf_init_size(
-    val_t *val,
-    ssize_t   sz)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_SIZE;
-    val->v.size = sz;
-}
-
-void
-conf_init_am64(
-    val_t *val,
-    off_t   l)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_AM64;
-    val->v.am64 = l;
-}
-
-void
-conf_init_real(
-    val_t  *val,
-    double r)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_REAL;
-    val->v.r = r;
-}
-
-void
-conf_init_rate(
-    val_t  *val,
-    double r1,
-    double r2)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_RATE;
-    val->v.rate[0] = r1;
-    val->v.rate[1] = r2;
-}
-
-void
-conf_init_time(
-    val_t *val,
-    time_t   t)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_TIME;
-    val->v.t = t;
-}
-
-void
-conf_init_sl(
-    val_t *val,
-    sl_t  *sl)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_AM64;
-    val->v.sl = sl;
-}
-
-void
-conf_init_exinclude(
-    val_t *val)
-{
-    val->seen = 0;
-    val->type = CONFTYPE_EXINCLUDE;
-    val->v.exinclude.optional = 0;
-    val->v.exinclude.sl_list = NULL;
-    val->v.exinclude.sl_file = NULL;
-}
-
-void
-conf_set_string(
-    val_t *val,
-    char *s)
-{
-    val->seen = -1;
-    val->type = CONFTYPE_STRING;
-    amfree(val->v.s);
-    val->v.s = stralloc(s);
-}
-
-void
-conf_set_int(
-    val_t *val,
-    int    i)
-{
-    val->seen = -1;
-    val->type = CONFTYPE_INT;
-    val->v.i = i;
-}
-
-void
-conf_set_bool(
-    val_t *val,
-    int    i)
-{
-    val->seen = -1;
-    val->type = CONFTYPE_BOOL;
-    val->v.i = i;
-}
-
-void
-conf_set_compress(
-    val_t *val,
-    comp_t    i)
-{
-    val->seen = -1;
-    val->type = CONFTYPE_COMPRESS;
-    val->v.i = (int)i;
-}
-
-void
-conf_set_encrypt(
-    val_t *val,
-    encrypt_t    i)
-{
-    val->seen = -1;
-    val->type = CONFTYPE_COMPRESS;
-    val->v.i = (int)i;
-}
-
-void
-conf_set_holding(
-    val_t              *val,
-    dump_holdingdisk_t  i)
-{
-    val->seen = -1;
-    val->type = CONFTYPE_HOLDING;
-    val->v.i = (int)i;
-}
-
-void
-conf_set_strategy(
-    val_t *val,
-    int    i)
-{
-    val->seen = -1;
-    val->type = CONFTYPE_STRATEGY;
-    val->v.i = i;
-}
-
-
-int
-get_conftype_int(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_INT) {
-       error("get_conftype_int: val.type is not CONFTYPE_INT");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-long
-get_conftype_long(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_LONG) {
-       error("get_conftype_long: val.type is not CONFTYPE_LONG");
-       /*NOTREACHED*/
-    }
-    return val->v.l;
-}
-
-off_t
-get_conftype_am64(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_AM64) {
-       error("get_conftype_am64: val.type is not CONFTYPE_AM64");
-       /*NOTREACHED*/
-    }
-    return val->v.am64;
-}
-
-double
-get_conftype_real(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_REAL) {
-       error("get_conftype_real: val.type is not CONFTYPE_REAL");
-       /*NOTREACHED*/
-    }
-    return val->v.r;
-}
-
-char *
-get_conftype_string(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_STRING) {
-       error("get_conftype_string: val.type is not CONFTYPE_STRING");
-       /*NOTREACHED*/
-    }
-    return val->v.s;
-}
-
-char *
-get_conftype_ident(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_IDENT) {
-       error("get_conftype_ident: val.type is not CONFTYPE_IDENT");
-       /*NOTREACHED*/
-    }
-    return val->v.s;
-}
-
-time_t
-get_conftype_time(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_TIME) {
-       error("get_conftype_time: val.type is not CONFTYPE_TIME");
-       /*NOTREACHED*/
-    }
-    return val->v.t;
-}
-
-ssize_t
-get_conftype_size(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_SIZE) {
-       error("get_conftype_size: val.type is not CONFTYPE_SIZE");
-       /*NOTREACHED*/
-    }
-    return val->v.size;
-}
-
-sl_t *
-get_conftype_sl(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_SL) {
-       error("get_conftype_size: val.type is not CONFTYPE_SL");
-       /*NOTREACHED*/
-    }
-    return val->v.sl;
-}
-
-int
-get_conftype_bool(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_BOOL) {
-       error("get_conftype_bool: val.type is not CONFTYPE_BOOL");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-int
-get_conftype_hold(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_HOLDING) {
-       error("get_conftype_hold: val.type is not CONFTYPE_HOLDING");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-int
-get_conftype_compress(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_COMPRESS) {
-       error("get_conftype_compress: val.type is not CONFTYPE_COMPRESS");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-int
-get_conftype_encrypt(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_ENCRYPT) {
-       error("get_conftype_encrypt: val.type is not CONFTYPE_ENCRYPT");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-int
-get_conftype_estimate(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_ESTIMATE) {
-       error("get_conftype_extimate: val.type is not CONFTYPE_ESTIMATE");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-int
-get_conftype_strategy(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_STRATEGY) {
-       error("get_conftype_strategy: val.type is not CONFTYPE_STRATEGY");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-int
-get_conftype_taperalgo(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_TAPERALGO) {
-       error("get_conftype_taperalgo: val.type is not CONFTYPE_TAPERALGO");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-int
-get_conftype_priority(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_PRIORITY) {
-       error("get_conftype_priority: val.type is not CONFTYPE_PRIORITY");
-       /*NOTREACHED*/
-    }
-    return val->v.i;
-}
-
-exinclude_t
-get_conftype_exinclude(
-    val_t *val)
-{
-    if (val->type != CONFTYPE_EXINCLUDE) {
-       error("get_conftype_exinclude: val.type is not CONFTYPE_EXINCLUDE");
-       /*NOTREACHED*/
-    }
-    return val->v.exinclude;
-}
-
-
-void
-dump_sockaddr(
-       struct sockaddr_in *    sa)
-{
-       dbprintf(("%s: (sockaddr_in *)%p = { %d, %d, %s }\n",
-               debug_prefix_time(NULL), sa, sa->sin_family,
-               (int)ntohs(sa->sin_port),
-               inet_ntoa(sa->sin_addr)));
-}
-
-void
-read_block(
-    command_option_t *command_options,
-    t_conf_var    *read_var,
-    keytab_t *keytab,
-    val_t    *valarray,
-    char     *prefix,
-    char     *errormsg,
-    int       read_brace,
-    void      (*copy_function)(void))
-{
-    t_conf_var *np;
-    int    saved_conf_line_num;
-    int    done;
-
-    if(read_brace) {
-       get_conftoken(CONF_LBRACE);
-       get_conftoken(CONF_NL);
-    }
-
-    done = 0;
-    do {
-       conf_line_num += 1;
-       get_conftoken(CONF_ANY);
-       switch(tok) {
-       case CONF_RBRACE:
-           done = 1;
-           break;
-       case CONF_NL:   /* empty line */
-           break;
-       case CONF_END:  /* end of file */
-           done = 1;
-           break;
-        case CONF_IDENT:
-        case CONF_STRING:
-           if(copy_function) 
-               copy_function();
-           else
-               conf_parserror("ident not expected");
-           break;
-       default:
-           {
-               for(np = read_var; np->token != CONF_UNKNOWN; np++)
-                   if(np->token == tok) break;
-
-               if(np->token == CONF_UNKNOWN)
-                   conf_parserror(errormsg);
-               else {
-                   np->read_function(np, &valarray[np->parm]);
-                   if(np->validate)
-                       np->validate(np, &valarray[np->parm]);
-               }
-           }
-       }
-       if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
-           get_conftoken(CONF_NL);
-    } while(!done);
-
-    /* overwrite with command line option */
-    saved_conf_line_num = conf_line_num;
-    command_overwrite(command_options, read_var, keytab, valarray, prefix);
-    conf_line_num = saved_conf_line_num;
-}
-
-void
-command_overwrite(
-    command_option_t *command_options,
-    t_conf_var    *overwrite_var,
-    keytab_t *keytab,
-    val_t    *valarray,
-    char     *prefix)
-{
-    t_conf_var      *np;
-    keytab_t        *kt;
-    char            *myprefix;
-    command_option_t *command_option;
-    int                      duplicate;
-
-    if(!command_options) return;
-
-    for(np = overwrite_var; np->token != CONF_UNKNOWN; np++) {
-       for(kt = keytab; kt->token != CONF_UNKNOWN; kt++)
-           if(kt->token == np->token) break;
-
-       if(kt->token == CONF_UNKNOWN) {
-           error("read_conf: invalid token");
-           /* NOTREACHED */
-       }
-
-       for(command_option = command_options; command_option->name != NULL;
-                                                           command_option++) {
-           myprefix = stralloc2(prefix, kt->keyword);
-           if(strcasecmp(myprefix, command_option->name) == 0) {
-               duplicate = 0;
-               if (command_option->used == 0 &&
-                   valarray[np->parm].seen == -2) {
-                   duplicate = 1;
-               }
-               command_option->used = 1;
-               valarray[np->parm].seen = -2;
-               if(np->type == CONFTYPE_STRING &&
-                  command_option->value[0] != '"') {
-                   conf_line = vstralloc("\"", command_option->value, "\"",
-                                         NULL);
-               }
-               else {
-                   conf_line = stralloc(command_option->value);
-               }
-               conf_char = conf_line;
-               token_pushed = 0;
-               conf_line_num = -2;
-               np->read_function(np, &valarray[np->parm]);
-               amfree(conf_line);
-               conf_line = conf_char = NULL;
-
-               if (np->validate)
-                   np->validate(np, &valarray[np->parm]);
-               if (duplicate == 1) {
-                   fprintf(stderr,"Duplicate %s option, using %s\n",
-                           command_option->name, command_option->value);
-               }
-           }
-           amfree(myprefix);
-       }
-    }
-}
-
-void
-free_new_argv(
-    int new_argc,
-    char **new_argv)
-{
-    int i;
-    for(i=0; i<new_argc; i++)
-       amfree(new_argv[i]);
-    amfree(new_argv);
-}
-
-
 int copy_file(
     char  *dst,
     char  *src,
@@ -2716,7 +762,7 @@ int copy_file(
        save_errno = errno;
        quoted = quote_string(src);
        *errmsg = vstralloc("Can't open file ", quoted, " for reading: %s",
-                           strerror(save_errno));
+                           strerror(save_errno), NULL);
        amfree(quoted);
        return -1;
     }
@@ -2725,7 +771,7 @@ int copy_file(
        save_errno = errno;
        quoted = quote_string(dst);
        *errmsg = vstralloc("Can't open file ", quoted, " for writting: %s",
-                           strerror(save_errno));
+                           strerror(save_errno), NULL);
        amfree(quoted);
        close(infd);
        return -1;
@@ -2736,7 +782,7 @@ int copy_file(
            save_errno = errno;
            quoted = quote_string(dst);
            *errmsg = vstralloc("Error writing to \"", quoted, "\":",
-                               strerror(save_errno));
+                               strerror(save_errno), NULL);
            amfree(quoted);
            close(infd);
            close(outfd);
@@ -2748,7 +794,7 @@ int copy_file(
        save_errno = errno;
        quoted = quote_string(src);
        *errmsg = vstralloc("Error reading from \"", quoted, "\":",
-                           strerror(save_errno));
+                           strerror(save_errno), NULL);
        amfree(quoted);
        close(infd);
        close(outfd);