Imported Upstream version 2.5.0
[debian/amanda] / server-src / conffile.c
index 62e17626915451bdf52b03d8ec13a8be4f332cc5..f80137263e7113ce14f64f53eeacce33b2efb846 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: conffile.c,v 1.54.2.16.2.5.2.20 2003/11/26 16:12:19 martinea Exp $
+ * $Id: conffile.c,v 1.127 2006/03/15 16:26:13 martinea Exp $
  *
  * read configuration file
  */
 
 /* internal types and variables */
 
-/*
- * XXX - this is used by the krb4 stuff.
- * Hopefully nobody will need this here.  (not very likely).  -kovert
- */
-#if defined(INTERFACE)
-#  undef INTERFACE
-#endif
-
 typedef enum {
     UNKNOWN, ANY, COMMA, LBRACE, RBRACE, NL, END,
-    IDENT, INT, BOOL, REAL, STRING, TIME,
+    IDENT, INT, LONG, AM64, BOOL, REAL, STRING, TIME,
 
     /* config parameters */
     INCLUDEFILE,
     ORG, MAILTO, DUMPUSER,
     TAPECYCLE, TAPEDEV, CHNGRDEV, CHNGRFILE, LABELSTR,
-    BUMPSIZE, BUMPDAYS, BUMPMULT, ETIMEOUT, DTIMEOUT, CTIMEOUT,
+    BUMPPERCENT, BUMPSIZE, BUMPDAYS, BUMPMULT, ETIMEOUT, DTIMEOUT, CTIMEOUT,
     TAPEBUFS, TAPELIST, DISKFILE, INFOFILE, LOGDIR, LOGFILE,
     DISKDIR, DISKSIZE, INDEXDIR, NETUSAGE, INPARALLEL, DUMPORDER, TIMEOUT,
     TPCHANGER, RUNTAPES,
@@ -79,8 +71,13 @@ typedef enum {
     PRINTER, AUTOFLUSH, RESERVE, MAXDUMPSIZE,
     COLUMNSPEC, 
     AMRECOVER_DO_FSF, AMRECOVER_CHECK_LABEL, AMRECOVER_CHANGER,
+    LABEL_NEW_TAPES,
 
     TAPERALGO, FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST, LAST,
+    DISPLAYUNIT,
+
+    /* kerberos 5 */
+    KRB5KEYTAB, KRB5PRINCIPAL, 
 
     /* holding disk */
     COMMENT, DIRECTORY, USE, CHUNKSIZE,
@@ -88,9 +85,11 @@ typedef enum {
     /* dump type */
     /*COMMENT,*/ PROGRAM, DUMPCYCLE, RUNSPERCYCLE, MAXCYCLE, MAXDUMPS,
     OPTIONS, PRIORITY, FREQUENCY, INDEX, MAXPROMOTEDAY,
-    STARTTIME, COMPRESS, AUTH, STRATEGY,
+    STARTTIME, COMPRESS, ENCRYPT, AUTH, STRATEGY, ESTIMATE,
     SKIP_INCR, SKIP_FULL, RECORD, HOLDING,
-    EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE,
+    EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE, TAPE_SPLITSIZE,
+    SPLIT_DISKBUFFER, FALLBACK_SPLITSIZE, SRVCOMPPROG, CLNTCOMPPROG,
+    SRV_ENCRYPT, CLNT_ENCRYPT, SRV_DECRYPT_OPT, CLNT_DECRYPT_OPT,
 
     /* tape type */
     /*COMMENT,*/ BLOCKSIZE, FILE_PAD, LBL_TEMPL, FILEMARK, LENGTH, SPEED,
@@ -101,15 +100,12 @@ typedef enum {
     /* dump options (obsolete) */
     EXCLUDE_FILE, EXCLUDE_LIST,
 
-    /* compress */
-    NONE, FAST, BEST, SERVER, CLIENT,
+    /* compress, estimate, encryption */
+    NONE, FAST, BEST, SERVER, CLIENT, CALCSIZE, CUSTOM,
 
     /* priority */
     LOW, MEDIUM, HIGH,
 
-    /* authentication */
-    KRB4_AUTH, BSD_AUTH,
-
     /* dump strategy */
     SKIP, STANDARD, NOFULL, NOINC, HANOI, INCRONLY,
 
@@ -134,6 +130,8 @@ keytab_t *keytable;
 
 typedef union {
     int i;
+    long l;
+    am64_t am64;
     double r;
     char *s;
 } val_t;
@@ -146,12 +144,12 @@ ColumnInfo ColumnData[] = {
     { "Disk",       1, 11, 11, 0, "%-*.*s", "DISK" },
     { "Level",      1, 1,  1,  0, "%*.*d",  "L" },
     { "OrigKB",     1, 7,  0,  0, "%*.*f",  "ORIG-KB" },
-    { "OutKB",      0, 7,  0,  0, "%*.*f",  "OUT-KB" },
-    { "Compress",   0, 6,  1,  0, "%*.*f",  "COMP%" },
-    { "DumpTime",   0, 7,  7,  0, "%*.*s",  "MMM:SS" },
-    { "DumpRate",   0, 6,  1,  0, "%*.*f",  "KB/s" },
+    { "OutKB",      1, 7,  0,  0, "%*.*f",  "OUT-KB" },
+    { "Compress",   1, 6,  1,  0, "%*.*f",  "COMP%" },
+    { "DumpTime",   1, 7,  7,  0, "%*.*s",  "MMM:SS" },
+    { "DumpRate",   1, 6,  1,  0, "%*.*f",  "KB/s" },
     { "TapeTime",   1, 6,  6,  0, "%*.*s",  "MMM:SS" },
-    { "TapeRate",   0, 6,  1,  0, "%*.*f",  "KB/s" },
+    { "TapeRate",   1, 6,  1,  0, "%*.*f",  "KB/s" },
     { NULL,         0, 0,  0,  0, NULL,     NULL }
 };
 
@@ -163,6 +161,8 @@ char *config_dir = NULL;
 holdingdisk_t *holdingdisks;
 int num_holdingdisks;
 
+long int unit_divisor = 1;
+
 /* configuration parameters */
 
 /* strings */
@@ -198,6 +198,7 @@ static val_t conf_netusage;
 static val_t conf_inparallel;
 static val_t conf_timeout;
 static val_t conf_maxdumps;
+static val_t conf_bumppercent;
 static val_t conf_bumpsize;
 static val_t conf_bumpdays;
 static val_t conf_etimeout;
@@ -210,6 +211,10 @@ static val_t conf_maxdumpsize;
 static val_t conf_amrecover_do_fsf;
 static val_t conf_amrecover_check_label;
 static val_t conf_taperalgo;
+static val_t conf_displayunit;
+static val_t conf_krb5keytab;
+static val_t conf_krb5principal;
+static val_t conf_label_new_tapes;
 
 /* reals */
 static val_t conf_bumpmult;
@@ -240,6 +245,7 @@ static int seen_infofile;
 static int seen_diskfile;
 static int seen_diskdir;
 static int seen_logdir;
+static int seen_bumppercent;
 static int seen_bumpsize;
 static int seen_bumpmult;
 static int seen_bumpdays;
@@ -266,6 +272,10 @@ static int seen_amrecover_do_fsf;
 static int seen_amrecover_check_label;
 static int seen_amrecover_changer;
 static int seen_taperalgo;
+static int seen_displayunit;
+static int seen_krb5keytab;
+static int seen_krb5principal;
+static int seen_label_new_tapes;
 
 static int allow_overwrites;
 static int token_pushed;
@@ -304,16 +314,19 @@ static void copy_interface P((void));
 static void get_dumpopts P((void));
 static void get_comprate P((void));
 static void get_compress P((void));
+static void get_encrypt P((void));
 static void get_priority P((void));
-static void get_auth P((void));
 static void get_strategy P((void));
+static void get_estimate P((void));
 static void get_exclude P((void));
 static void get_include P((void));
 static void get_taperalgo P((val_t *c_taperalgo, int *s_taperalgo));
 
 static void get_simple P((val_t *var, int *seen, tok_t type));
 static int get_time P((void));
-static int get_number P((void));
+static int get_int P((void));
+static long get_long P((void));
+static am64_t get_am64_t P((void));
 static int get_bool P((void));
 static void ckseen P((int *seen));
 static void parserror P((char *format, ...))
@@ -396,6 +409,7 @@ struct byname {
     /*{ "DISKSIZE", CNF_DISKSIZE, INT },*/
     { "BUMPDAYS", CNF_BUMPDAYS, INT },
     { "BUMPSIZE", CNF_BUMPSIZE, INT },
+    { "BUMPPERCENT", CNF_BUMPPERCENT, INT },
     { "BUMPMULT", CNF_BUMPMULT, REAL },
     { "NETUSAGE", CNF_NETUSAGE, INT },
     { "INPARALLEL", CNF_INPARALLEL, INT },
@@ -412,9 +426,13 @@ struct byname {
     { "AMRECOVER_CHECK_LABEL", CNF_AMRECOVER_CHECK_LABEL, BOOL },
     { "AMRECOVER_CHANGER", CNF_AMRECOVER_CHANGER, STRING },
     { "TAPERALGO", CNF_TAPERALGO, INT },
+    { "DISPLAYUNIT", CNF_DISPLAYUNIT, STRING },
     { "AUTOFLUSH", CNF_AUTOFLUSH, BOOL },
     { "RESERVE", CNF_RESERVE, INT },
-    { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, INT },
+    { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, AM64 },
+    { "KRB5KEYTAB", CNF_KRB5KEYTAB, STRING },
+    { "KRB5PRINCIPAL", CNF_KRB5PRINCIPAL, STRING },
+    { "LABEL_NEW_TAPES", CNF_LABEL_NEW_TAPES, STRING },
     { NULL }
 };
 
@@ -430,7 +448,7 @@ char *str;
     tmpstr = stralloc(str);
     s = tmpstr;
     while((ch = *s++) != '\0') {
-       if(islower((int) ch)) s[-1] = toupper(ch);
+       if(islower((int)ch)) s[-1] = toupper(ch);
     }
 
     for(np = byname_table; np->name != NULL; np++)
@@ -439,10 +457,17 @@ char *str;
     if(np->name == NULL) return NULL;
 
     if(np->typ == INT) {
-       ap_snprintf(number, sizeof(number), "%d", getconf_int(np->parm));
+       snprintf(number, sizeof(number), "%d", getconf_int(np->parm));
        tmpstr = newstralloc(tmpstr, number);
+    } else if(np->typ == BOOL) {
+       if(getconf_int(np->parm) == 0) {
+           tmpstr = newstralloc(tmpstr, "off");
+       }
+       else {
+           tmpstr = newstralloc(tmpstr, "on");
+       }
     } else if(np->typ == REAL) {
-       ap_snprintf(number, sizeof(number), "%f", getconf_real(np->parm));
+       snprintf(number, sizeof(number), "%f", getconf_real(np->parm));
        tmpstr = newstralloc(tmpstr, number);
     } else {
        tmpstr = newstralloc(tmpstr, getconf_str(np->parm));
@@ -472,6 +497,7 @@ confparm_t parm;
     /*case CNF_DISKDIR: return seen_diskdir;*/
     case CNF_LOGDIR: return seen_logdir;
     /*case CNF_LOGFILE: return seen_logfile;*/
+    case CNF_BUMPPERCENT: return seen_bumppercent;
     case CNF_BUMPSIZE: return seen_bumpsize;
     case CNF_BUMPMULT: return seen_bumpmult;
     case CNF_BUMPDAYS: return seen_bumpdays;
@@ -498,6 +524,10 @@ confparm_t parm;
     case CNF_AMRECOVER_CHECK_LABEL: return seen_amrecover_check_label;
     case CNF_AMRECOVER_CHANGER: return seen_amrecover_changer;
     case CNF_TAPERALGO: return seen_taperalgo;
+    case CNF_DISPLAYUNIT: return seen_displayunit;
+    case CNF_KRB5KEYTAB: return seen_krb5keytab;
+    case CNF_KRB5PRINCIPAL: return seen_krb5principal;
+    case CNF_LABEL_NEW_TAPES: return seen_label_new_tapes;
     default: return 0;
     }
 }
@@ -514,6 +544,7 @@ confparm_t parm;
     case CNF_TAPECYCLE: r = conf_tapecycle.i; break;
     case CNF_RUNTAPES: r = conf_runtapes.i; break;
     /*case CNF_DISKSIZE: r = conf_disksize.i; break;*/
+    case CNF_BUMPPERCENT: r = conf_bumppercent.i; break;
     case CNF_BUMPSIZE: r = conf_bumpsize.i; break;
     case CNF_BUMPDAYS: r = conf_bumpdays.i; break;
     case CNF_NETUSAGE: r = conf_netusage.i; break;
@@ -526,7 +557,6 @@ confparm_t parm;
     case CNF_TAPEBUFS: r = conf_tapebufs.i; break;
     case CNF_AUTOFLUSH: r = conf_autoflush.i; break;
     case CNF_RESERVE: r = conf_reserve.i; break;
-    case CNF_MAXDUMPSIZE: r = conf_maxdumpsize.i; break;
     case CNF_AMRECOVER_DO_FSF: r = conf_amrecover_do_fsf.i; break;
     case CNF_AMRECOVER_CHECK_LABEL: r = conf_amrecover_check_label.i; break;
     case CNF_TAPERALGO: r = conf_taperalgo.i; break;
@@ -538,6 +568,21 @@ confparm_t parm;
     return r;
 }
 
+am64_t getconf_am64(parm)
+confparm_t parm;
+{
+    am64_t r = 0;
+
+    switch(parm) {
+    case CNF_MAXDUMPSIZE: r = conf_maxdumpsize.am64; break;
+
+    default:
+       error("error [unknown getconf_am64 parm: %d]", parm);
+       /* NOTREACHED */
+    }
+    return r;
+}
+
 double getconf_real(parm)
 confparm_t parm;
 {
@@ -582,6 +627,10 @@ confparm_t parm;
     case CNF_RAWTAPEDEV: r = conf_rawtapedev.s; break;
     case CNF_COLUMNSPEC: r = conf_columnspec.s; break;
     case CNF_AMRECOVER_CHANGER: r = conf_amrecover_changer.s; break;
+    case CNF_DISPLAYUNIT: r = conf_displayunit.s; break;
+    case CNF_KRB5PRINCIPAL: r = conf_krb5principal.s; break;
+    case CNF_KRB5KEYTAB: r = conf_krb5keytab.s; break;
+    case CNF_LABEL_NEW_TAPES: r = conf_label_new_tapes.s; break;
 
     default:
        error("error [unknown getconf_str parm: %d]", parm);
@@ -701,6 +750,11 @@ static void init_defaults()
     malloc_mark(conf_dumporder.s);
     conf_amrecover_changer.s = stralloc("");
     conf_printer.s = stralloc("");
+    conf_displayunit.s = stralloc("k");
+    conf_label_new_tapes.s = stralloc("");
+
+    conf_krb5keytab.s = stralloc("/.amanda-v5-keytab");
+    conf_krb5principal.s = stralloc("service/amanda");
 
     conf_dumpcycle.i   = 10;
     conf_runspercycle.i        = 0;
@@ -711,6 +765,7 @@ static void init_defaults()
     conf_inparallel.i  = 10;
     conf_maxdumps.i    = 1;
     conf_timeout.i     = 2;
+    conf_bumppercent.i = 0;
     conf_bumpsize.i    = 10*1024;
     conf_bumpdays.i    = 2;
     conf_bumpmult.r    = 1.5;
@@ -720,9 +775,9 @@ static void init_defaults()
     conf_tapebufs.i     = 20;
     conf_autoflush.i   = 0;
     conf_reserve.i     = 100;
-    conf_maxdumpsize.i = -1;
-    conf_amrecover_do_fsf.i = 0;
-    conf_amrecover_check_label.i = 0;
+    conf_maxdumpsize.am64      = -1;
+    conf_amrecover_do_fsf.i = 1;
+    conf_amrecover_check_label.i = 1;
     conf_taperalgo.i = 0;
 
     /* defaults for internal variables */
@@ -744,6 +799,7 @@ static void init_defaults()
     seen_diskfile = 0;
     seen_diskdir = 0;
     seen_logdir = 0;
+    seen_bumppercent = 0;
     seen_bumpsize = 0;
     seen_bumpmult = 0;
     seen_bumpdays = 0;
@@ -770,6 +826,11 @@ static void init_defaults()
     seen_amrecover_check_label = 0;
     seen_amrecover_changer = 0;
     seen_taperalgo = 0;
+    seen_displayunit = 0;
+    seen_krb5keytab = 0;
+    seen_krb5principal = 0;
+    seen_label_new_tapes = 0;
+
     line_num = got_parserror = 0;
     allow_overwrites = 0;
     token_pushed = 0;
@@ -823,6 +884,11 @@ static void init_defaults()
     dpcur.compress = COMP_BEST; dpcur.s_compress = -1;
     save_dumptype();
 
+    init_dumptype_defaults();
+    dpcur.name = "COMPRESS-CUST"; dpcur.seen = -1;
+    dpcur.compress = COMP_CUST; dpcur.s_compress = -1;
+    save_dumptype();
+
     init_dumptype_defaults();
     dpcur.name = "SRVCOMPRESS"; dpcur.seen = -1;
     dpcur.compress = COMP_SERV_FAST; dpcur.s_compress = -1;
@@ -830,12 +896,14 @@ static void init_defaults()
 
     init_dumptype_defaults();
     dpcur.name = "BSD-AUTH"; dpcur.seen = -1;
-    dpcur.auth = AUTH_BSD; dpcur.s_auth = -1;
+    amfree(dpcur.security_driver);
+    dpcur.security_driver = stralloc("BSD"); dpcur.s_security_driver = -1;
     save_dumptype();
 
     init_dumptype_defaults();
     dpcur.name = "KRB4-AUTH"; dpcur.seen = -1;
-    dpcur.auth = AUTH_KRB4; dpcur.s_auth = -1;
+    amfree(dpcur.security_driver);
+    dpcur.security_driver = stralloc("KRB4"); dpcur.s_security_driver = -1;
     save_dumptype();
 
     init_dumptype_defaults();
@@ -900,6 +968,7 @@ keytab_t main_keytable[] = {
     { "BUMPDAYS", BUMPDAYS },
     { "BUMPMULT", BUMPMULT },
     { "BUMPSIZE", BUMPSIZE },
+    { "BUMPPERCENT", BUMPPERCENT },
     { "DEFINE", DEFINE },
     { "DISKDIR", DISKDIR },    /* XXX - historical */
     { "DISKFILE", DISKFILE },
@@ -947,6 +1016,10 @@ keytab_t main_keytable[] = {
     { "AMRECOVER_CHECK_LABEL", AMRECOVER_CHECK_LABEL },
     { "AMRECOVER_CHANGER", AMRECOVER_CHANGER },
     { "TAPERALGO", TAPERALGO },
+    { "DISPLAYUNIT", DISPLAYUNIT },
+    { "KRB5KEYTAB", KRB5KEYTAB },
+    { "KRB5PRINCIPAL", KRB5PRINCIPAL },
+    { "LABEL_NEW_TAPES", LABEL_NEW_TAPES },
     { NULL, IDENT }
 };
 
@@ -988,7 +1061,7 @@ static int read_confline()
                    }
                    break;
     case RUNTAPES:  get_simple(&conf_runtapes,  &seen_runtapes,  INT);
-                   if(conf_runtapes.i < 1) {
+                   if(conf_runtapes.i < 0) {
                        parserror("runtapes must be positive");
                    }
                    break;
@@ -1007,6 +1080,11 @@ static int read_confline()
                        parserror("bumpmult must be positive");
                    }
                    break;
+    case BUMPPERCENT:  get_simple(&conf_bumppercent,  &seen_bumppercent,  INT);
+                   if(conf_bumppercent.i < 0 || conf_bumppercent.i > 100) {
+                       parserror("bumppercent must be between 0 and 100");
+                   }
+                   break;
     case BUMPSIZE:  get_simple(&conf_bumpsize,  &seen_bumpsize,  INT);
                    if(conf_bumpsize.i < 1) {
                        parserror("bumpsize must be positive");
@@ -1060,7 +1138,7 @@ static int read_confline()
                        parserror("reserve must be between 0 and 100");
                    }
                    break;
-    case MAXDUMPSIZE:get_simple(&conf_maxdumpsize,&seen_maxdumpsize,INT); break;
+    case MAXDUMPSIZE:get_simple(&conf_maxdumpsize,&seen_maxdumpsize,AM64); break;
     case COLUMNSPEC:get_simple(&conf_columnspec,&seen_columnspec,STRING); break;
 
     case AMRECOVER_DO_FSF: get_simple(&conf_amrecover_do_fsf,&seen_amrecover_do_fsf, BOOL); break;
@@ -1068,6 +1146,35 @@ static int read_confline()
     case AMRECOVER_CHANGER: get_simple(&conf_amrecover_changer,&seen_amrecover_changer, STRING); break;
 
     case TAPERALGO: get_taperalgo(&conf_taperalgo,&seen_taperalgo); break;
+    case DISPLAYUNIT: get_simple(&conf_displayunit,&seen_displayunit, STRING);
+                     if(strcmp(conf_displayunit.s,"k") == 0 ||
+                        strcmp(conf_displayunit.s,"K") == 0) {
+                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
+                         unit_divisor=1;
+                     }
+                     else if(strcmp(conf_displayunit.s,"m") == 0 ||
+                        strcmp(conf_displayunit.s,"M") == 0) {
+                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
+                         unit_divisor=1024;
+                     }
+                     else if(strcmp(conf_displayunit.s,"g") == 0 ||
+                        strcmp(conf_displayunit.s,"G") == 0) {
+                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
+                         unit_divisor=1024*1024;
+                     }
+                     else if(strcmp(conf_displayunit.s,"t") == 0 ||
+                        strcmp(conf_displayunit.s,"T") == 0) {
+                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
+                         unit_divisor=1024*1024*1024;
+                     }
+                     else {
+                         parserror("displayunit must be k,m,g or t.");
+                     }
+                     break;
+
+    /* kerberos 5 bits.  only useful when kerberos 5 built in... */
+    case KRB5KEYTAB:    get_simple(&conf_krb5keytab,   &seen_krb5keytab,   STRING); break;
+    case KRB5PRINCIPAL: get_simple(&conf_krb5principal,&seen_krb5principal,STRING); break;
 
     case LOGFILE: /* XXX - historical */
        /* truncate the filename part and pretend he said "logdir" */
@@ -1108,7 +1215,7 @@ static int read_confline()
        {
            int i;
 
-           i = get_number();
+           i = get_int();
            i = (i / DISK_BLOCK_KB) * DISK_BLOCK_KB;
 
            if(!seen_disksize) {
@@ -1133,6 +1240,9 @@ static int read_confline()
        else if(tok == INTERFACE) get_interface();
        else parserror("DUMPTYPE, INTERFACE or TAPETYPE expected");
        break;
+    case LABEL_NEW_TAPES:
+        get_simple(&conf_label_new_tapes, &seen_label_new_tapes, STRING);
+        break;
 
     case NL:   /* empty line */
        break;
@@ -1188,11 +1298,11 @@ static void get_holdingdisk()
            get_simple((val_t *)&hdcur.diskdir, &hdcur.s_disk, STRING);
            break;
        case USE:
-           get_simple((val_t *)&hdcur.disksize, &hdcur.s_size, INT);
+           get_simple((val_t *)&hdcur.disksize, &hdcur.s_size, LONG);
            hdcur.disksize = am_floor(hdcur.disksize, DISK_BLOCK_KB);
            break;
        case CHUNKSIZE:
-           get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, INT);
+           get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, LONG);
            if(hdcur.chunksize == 0) {
                hdcur.chunksize =  ((INT_MAX / 1024) - (2 * DISK_BLOCK_KB));
            } else if(hdcur.chunksize < 0) {
@@ -1226,7 +1336,7 @@ static void init_holdingdisk_defaults()
     hdcur.diskdir = stralloc(conf_diskdir.s);
     malloc_mark(hdcur.diskdir);
     hdcur.disksize = 0;
-    hdcur.chunksize = 1024*1024*1024; /* 1 Gb */
+    hdcur.chunksize = 1024*1024/**1024*/; /* 1 Gb = 1M counted in 1Kb blocks */
 
     hdcur.s_comment = 0;
     hdcur.s_disk = 0;
@@ -1252,9 +1362,16 @@ static void save_holdingdisk()
 
 keytab_t dumptype_keytable[] = {
     { "AUTH", AUTH },
+    { "BUMPDAYS", BUMPDAYS },
+    { "BUMPMULT", BUMPMULT },
+    { "BUMPSIZE", BUMPSIZE },
+    { "BUMPPERCENT", BUMPPERCENT },
     { "COMMENT", COMMENT },
     { "COMPRATE", COMPRATE },
     { "COMPRESS", COMPRESS },
+    { "ENCRYPT", ENCRYPT },
+    { "SERVER_DECRYPT_OPTION", SRV_DECRYPT_OPT },
+    { "CLIENT_DECRYPT_OPTION", CLNT_DECRYPT_OPT },
     { "DUMPCYCLE", DUMPCYCLE },
     { "EXCLUDE", EXCLUDE },
     { "FREQUENCY", FREQUENCY },        /* XXX - historical */
@@ -1274,6 +1391,14 @@ keytab_t dumptype_keytable[] = {
     { "SKIP-INCR", SKIP_INCR },
     { "STARTTIME", STARTTIME },
     { "STRATEGY", STRATEGY },
+    { "TAPE_SPLITSIZE", TAPE_SPLITSIZE },
+    { "SPLIT_DISKBUFFER", SPLIT_DISKBUFFER },
+    { "FALLBACK_SPLITSIZE", FALLBACK_SPLITSIZE },
+    { "ESTIMATE", ESTIMATE },
+    { "SERVER_CUSTOM_COMPRESS", SRVCOMPPROG },
+    { "CLIENT_CUSTOM_COMPRESS", CLNTCOMPPROG },
+    { "SERVER_ENCRYPT", SRV_ENCRYPT },
+    { "CLIENT_ENCRYPT", CLNT_ENCRYPT },
     { NULL, IDENT }
 };
 
@@ -1333,7 +1458,8 @@ dumptype_t *read_dumptype(name, from, fname, linenum)
        switch(tok) {
 
        case AUTH:
-           get_auth();
+           get_simple((val_t *)&dpcur.security_driver,
+               &dpcur.s_security_driver, STRING);
            break;
        case COMMENT:
            get_simple((val_t *)&dpcur.comment, &dpcur.s_comment, STRING);
@@ -1344,6 +1470,15 @@ dumptype_t *read_dumptype(name, from, fname, linenum)
        case COMPRESS:
            get_compress();
            break;
+       case ENCRYPT:
+           get_encrypt();
+           break;
+       case SRV_DECRYPT_OPT:
+           get_simple((val_t *)&dpcur.srv_decrypt_opt, &dpcur.s_srv_decrypt_opt, STRING);
+           break;
+       case CLNT_DECRYPT_OPT:
+           get_simple((val_t *)&dpcur.clnt_decrypt_opt, &dpcur.s_clnt_decrypt_opt, STRING);
+           break;
        case DUMPCYCLE:
            get_simple((val_t *)&dpcur.dumpcycle, &dpcur.s_dumpcycle, INT);
            if(dpcur.dumpcycle < 0) {
@@ -1390,6 +1525,30 @@ dumptype_t *read_dumptype(name, from, fname, linenum)
                parserror("dpcur.maxpromoteday must be >= 0");
            }
            break;
+       case BUMPPERCENT:
+           get_simple((val_t *)&dpcur.bumppercent,  &dpcur.s_bumppercent,  INT);
+           if(dpcur.bumppercent < 0 || dpcur.bumppercent > 100) {
+               parserror("bumppercent must be between 0 and 100");
+           }
+           break;
+       case BUMPSIZE:
+           get_simple((val_t *)&dpcur.bumpsize,  &dpcur.s_bumpsize,  INT);
+           if(dpcur.bumpsize < 1) {
+               parserror("bumpsize must be positive");
+           }
+           break;
+       case BUMPDAYS:
+           get_simple((val_t *)&dpcur.bumpdays,  &dpcur.s_bumpdays,  INT);
+           if(dpcur.bumpdays < 1) {
+               parserror("bumpdays must be positive");
+           }
+           break;
+       case BUMPMULT:
+           get_simple((val_t *)&dpcur.bumpmult,  &dpcur.s_bumpmult,  REAL);
+           if(dpcur.bumpmult < 0.999) {
+               parserror("bumpmult must be positive (%f)",dpcur.bumpmult);
+           }
+           break;
        case OPTIONS:
            get_dumpopts();
            break;
@@ -1398,9 +1557,6 @@ dumptype_t *read_dumptype(name, from, fname, linenum)
            break;
        case PROGRAM:
            get_simple((val_t *)&dpcur.program, &dpcur.s_program, STRING);
-           if(strcmp(dpcur.program, "DUMP")
-              && strcmp(dpcur.program, "GNUTAR"))
-               parserror("backup program \"%s\" unknown", dpcur.program);
            break;
        case RECORD:
            get_simple(&tmpval, &dpcur.s_record, BOOL);
@@ -1420,11 +1576,39 @@ dumptype_t *read_dumptype(name, from, fname, linenum)
        case STRATEGY:
            get_strategy();
            break;
-
+       case ESTIMATE:
+           get_estimate();
+           break;
        case IDENT:
            copy_dumptype();
            break;
-
+       case TAPE_SPLITSIZE:
+           get_simple((val_t *)&dpcur.tape_splitsize,  &dpcur.s_tape_splitsize,  INT);
+           if(dpcur.tape_splitsize < 0) {
+             parserror("tape_splitsize must be >= 0");
+           }
+           break;
+       case SPLIT_DISKBUFFER:
+           get_simple((val_t *)&dpcur.split_diskbuffer, &dpcur.s_split_diskbuffer, STRING);
+           break;
+       case FALLBACK_SPLITSIZE:
+           get_simple((val_t *)&dpcur.fallback_splitsize,  &dpcur.s_fallback_splitsize,  INT);
+           if(dpcur.fallback_splitsize < 0) {
+             parserror("fallback_splitsize must be >= 0");
+           }
+           break;
+       case SRVCOMPPROG:
+           get_simple((val_t *)&dpcur.srvcompprog, &dpcur.s_srvcompprog, STRING);
+           break;
+        case CLNTCOMPPROG:
+           get_simple((val_t *)&dpcur.clntcompprog, &dpcur.s_clntcompprog, STRING);
+           break;
+       case SRV_ENCRYPT:
+           get_simple((val_t *)&dpcur.srv_encrypt, &dpcur.s_srv_encrypt, STRING);
+           break;
+        case CLNT_ENCRYPT:
+           get_simple((val_t *)&dpcur.clnt_encrypt, &dpcur.s_clnt_encrypt, STRING);
+           break;
        case RBRACE:
            done = 1;
            break;
@@ -1471,6 +1655,10 @@ static void init_dumptype_defaults()
 {
     dpcur.comment = stralloc("");
     dpcur.program = stralloc("DUMP");
+    dpcur.srvcompprog = stralloc("");
+    dpcur.clntcompprog = stralloc("");
+    dpcur.srv_encrypt = stralloc("");
+    dpcur.clnt_encrypt = stralloc("");
     dpcur.exclude_file = NULL;
     dpcur.exclude_list = NULL;
     dpcur.include_file = NULL;
@@ -1481,23 +1669,38 @@ static void init_dumptype_defaults()
     dpcur.frequency = 1;
     dpcur.maxdumps = conf_maxdumps.i;
     dpcur.maxpromoteday = 10000;
+    dpcur.bumppercent = conf_bumppercent.i;
+    dpcur.bumpsize = conf_bumpsize.i;
+    dpcur.bumpdays = conf_bumpdays.i;
+    dpcur.bumpmult = conf_bumpmult.r;
     dpcur.start_t = 0;
-
-    dpcur.auth = AUTH_BSD;
+    dpcur.security_driver = stralloc("BSD");
 
     /* options */
     dpcur.record = 1;
     dpcur.strategy = DS_STANDARD;
+    dpcur.estimate = ES_CLIENT;
     dpcur.compress = COMP_FAST;
+    dpcur.encrypt = ENCRYPT_NONE;
+    dpcur.srv_decrypt_opt = stralloc("-d");
+    dpcur.clnt_decrypt_opt = stralloc("-d");
     dpcur.comprate[0] = dpcur.comprate[1] = 0.50;
     dpcur.skip_incr = dpcur.skip_full = 0;
     dpcur.no_hold = 0;
     dpcur.kencrypt = 0;
     dpcur.ignore = 0;
     dpcur.index = 0;
+    dpcur.tape_splitsize = 0;
+    dpcur.split_diskbuffer = NULL;
+    dpcur.fallback_splitsize = 10 * 1024;
 
     dpcur.s_comment = 0;
     dpcur.s_program = 0;
+    dpcur.s_srvcompprog = 0;
+    dpcur.s_clntcompprog = 0;
+    dpcur.s_clnt_encrypt= 0;
+    dpcur.s_srv_encrypt= 0;
+
     dpcur.s_exclude_file = 0;
     dpcur.s_exclude_list = 0;
     dpcur.s_include_file = 0;
@@ -1508,11 +1711,19 @@ static void init_dumptype_defaults()
     dpcur.s_frequency = 0;
     dpcur.s_maxdumps = 0;
     dpcur.s_maxpromoteday = 0;
+    dpcur.s_bumppercent = 0;
+    dpcur.s_bumpsize = 0;
+    dpcur.s_bumpdays = 0;
+    dpcur.s_bumpmult = 0;
     dpcur.s_start_t = 0;
-    dpcur.s_auth = 0;
+    dpcur.s_security_driver = 0;
     dpcur.s_record = 0;
     dpcur.s_strategy = 0;
+    dpcur.s_estimate = 0;
     dpcur.s_compress = 0;
+    dpcur.s_encrypt = 0;
+    dpcur.s_srv_decrypt_opt = 0;
+    dpcur.s_clnt_decrypt_opt = 0;
     dpcur.s_comprate = 0;
     dpcur.s_skip_incr = 0;
     dpcur.s_skip_full = 0;
@@ -1520,6 +1731,9 @@ static void init_dumptype_defaults()
     dpcur.s_kencrypt = 0;
     dpcur.s_ignore = 0;
     dpcur.s_index = 0;
+    dpcur.s_tape_splitsize = 0;
+    dpcur.s_split_diskbuffer = 0;
+    dpcur.s_fallback_splitsize = 0;
 }
 
 static void save_dumptype()
@@ -1561,6 +1775,36 @@ static void copy_dumptype()
        dpcur.program = newstralloc(dpcur.program, dt->program);
        dpcur.s_program = dt->s_program;
     }
+    if(dt->s_security_driver) {
+       dpcur.security_driver = newstralloc(dpcur.security_driver,
+                                           dt->security_driver);
+       dpcur.s_security_driver = dt->s_security_driver;
+    }
+    if(dt->s_srvcompprog) {
+       dpcur.srvcompprog = newstralloc(dpcur.srvcompprog, dt->srvcompprog);
+       dpcur.s_srvcompprog = dt->s_srvcompprog;
+    }
+    if(dt->s_clntcompprog) {
+       dpcur.clntcompprog = newstralloc(dpcur.clntcompprog, dt->clntcompprog);
+       dpcur.s_clntcompprog = dt->s_clntcompprog;
+    }
+    if(dt->s_srv_encrypt) {
+       dpcur.srv_encrypt = newstralloc(dpcur.srv_encrypt, dt->srv_encrypt);
+       dpcur.s_srv_encrypt = dt->s_srv_encrypt;
+    }
+    if(dt->s_clnt_encrypt) {
+       dpcur.clnt_encrypt = newstralloc(dpcur.clnt_encrypt, dt->clnt_encrypt);
+       dpcur.s_clnt_encrypt = dt->s_clnt_encrypt;
+    }
+    if(dt->s_srv_decrypt_opt) {
+       dpcur.srv_decrypt_opt = newstralloc(dpcur.srv_decrypt_opt, dt->srv_decrypt_opt);
+       dpcur.s_srv_decrypt_opt = dt->s_srv_decrypt_opt;
+    }
+    if(dt->s_clnt_decrypt_opt) {
+       dpcur.clnt_decrypt_opt = newstralloc(dpcur.clnt_decrypt_opt, dt->clnt_decrypt_opt);
+       dpcur.s_clnt_decrypt_opt = dt->s_clnt_decrypt_opt;
+    }
+
     if(dt->s_exclude_file) {
        dpcur.exclude_file = duplicate_sl(dt->exclude_file);
        dpcur.s_exclude_file = dt->s_exclude_file;
@@ -1583,11 +1827,16 @@ static void copy_dumptype()
     dtcopy(frequency, s_frequency);
     dtcopy(maxdumps, s_maxdumps);
     dtcopy(maxpromoteday, s_maxpromoteday);
+    dtcopy(bumppercent, s_bumppercent);
+    dtcopy(bumpsize, s_bumpsize);
+    dtcopy(bumpdays, s_bumpdays);
+    dtcopy(bumpmult, s_bumpmult);
     dtcopy(start_t, s_start_t);
-    dtcopy(auth, s_auth);
     dtcopy(record, s_record);
     dtcopy(strategy, s_strategy);
+    dtcopy(estimate, s_estimate);
     dtcopy(compress, s_compress);
+    dtcopy(encrypt, s_encrypt);
     dtcopy(comprate[0], s_comprate);
     dtcopy(comprate[1], s_comprate);
     dtcopy(skip_incr, s_skip_incr);
@@ -1596,6 +1845,9 @@ static void copy_dumptype()
     dtcopy(kencrypt, s_kencrypt);
     dtcopy(ignore, s_ignore);
     dtcopy(index, s_index);
+    dtcopy(tape_splitsize, s_tape_splitsize);
+    dtcopy(split_diskbuffer, s_split_diskbuffer);
+    dtcopy(fallback_splitsize, s_fallback_splitsize);
 }
 
 keytab_t tapetype_keytable[] = {
@@ -1649,7 +1901,7 @@ static void get_tapetype()
            get_simple((val_t *)&tpcur.lbl_templ, &tpcur.s_lbl_templ, STRING);
            break;
        case BLOCKSIZE:
-           get_simple((val_t *)&tpcur.blocksize, &tpcur.s_blocksize, INT);
+           get_simple((val_t *)&tpcur.blocksize, &tpcur.s_blocksize, LONG);
            if(tpcur.blocksize < DISK_BLOCK_KB) {
                parserror("Tape blocksize must be at least %d KBytes",
                          DISK_BLOCK_KB);
@@ -1663,21 +1915,21 @@ static void get_tapetype()
            tpcur.file_pad = (value.i != 0);
            break;
        case LENGTH:
-           get_simple(&value, &tpcur.s_length, INT);
-           if(value.i < 0) {
+           get_simple(&value, &tpcur.s_length, LONG);
+           if(value.l < 0) {
                parserror("Tape length must be positive");
            }
            else {
-               tpcur.length = value.i;
+               tpcur.length = (unsigned long) value.l;
            }
            break;
        case FILEMARK:
-           get_simple(&value, &tpcur.s_filemark, INT);
-           if(value.i < 0) {
+           get_simple(&value, &tpcur.s_filemark, LONG);
+           if(value.l < 0) {
                parserror("Tape file mark size must be positive");
            }
            else {
-               tpcur.filemark = value.i;
+               tpcur.filemark = (unsigned long) value.l;
            }
            break;
        case SPEED:
@@ -1889,6 +2141,7 @@ static void copy_interface()
 
 keytab_t dumpopts_keytable[] = {
     { "COMPRESS", COMPRESS },
+    { "ENCRYPT", ENCRYPT },
     { "INDEX", INDEX },
     { "EXCLUDE-FILE", EXCLUDE_FILE },
     { "EXCLUDE-LIST", EXCLUDE_LIST },
@@ -1911,15 +2164,16 @@ static void get_dumpopts() /* XXX - for historical compatability */
        get_conftoken(ANY);
        switch(tok) {
        case COMPRESS:   ckseen(&dpcur.s_compress);  dpcur.compress = COMP_FAST; break;
+       case ENCRYPT:   ckseen(&dpcur.s_encrypt);  dpcur.encrypt = ENCRYPT_NONE; break;
        case EXCLUDE_FILE:
            ckseen(&dpcur.s_exclude_file);
            get_conftoken(STRING);
-           dpcur.exclude_file = append_sl(dpcur.exclude_file, stralloc(tokenval.s));
+           dpcur.exclude_file = append_sl(dpcur.exclude_file, tokenval.s);
            break;
        case EXCLUDE_LIST:
            ckseen(&dpcur.s_exclude_list);
            get_conftoken(STRING);
-           dpcur.exclude_list = append_sl(dpcur.exclude_list, stralloc(tokenval.s));
+           dpcur.exclude_list = append_sl(dpcur.exclude_list, tokenval.s);
            break;
        case KENCRYPT:   ckseen(&dpcur.s_kencrypt);  dpcur.kencrypt = 1; break;
        case SKIP_INCR:  ckseen(&dpcur.s_skip_incr); dpcur.skip_incr= 1; break;
@@ -1973,13 +2227,14 @@ keytab_t compress_keytable[] = {
     { "FAST", FAST },
     { "NONE", NONE },
     { "SERVER", SERVER },
+    { "CUSTOM", CUSTOM },
     { NULL, IDENT }
 };
 
 static void get_compress()
 {
     keytab_t *save_kt;
-    int serv, clie, none, fast, best;
+    int serv, clie, none, fast, best, custom;
     int done;
     int comp;
 
@@ -1988,7 +2243,7 @@ static void get_compress()
 
     ckseen(&dpcur.s_compress);
 
-    serv = clie = none = fast = best = 0;
+    serv = clie = none = fast = best = custom  = 0;
 
     done = 0;
     do {
@@ -1999,6 +2254,7 @@ static void get_compress()
        case BEST:   best = 1; break;
        case CLIENT: clie = 1; break;
        case SERVER: serv = 1; break;
+       case CUSTOM: custom=1; break;
        case NL:     done = 1; break;
        default:
            done = 1;
@@ -2007,24 +2263,26 @@ static void get_compress()
     } while(!done);
 
     if(serv + clie == 0) clie = 1;     /* default to client */
-    if(none + fast + best == 0) fast = 1; /* default to fast */
+    if(none + fast + best + custom  == 0) fast = 1; /* default to fast */
 
     comp = -1;
 
     if(!serv && clie) {
-       if(none && !fast && !best) comp = COMP_NONE;
-       if(!none && fast && !best) comp = COMP_FAST;
-       if(!none && !fast && best) comp = COMP_BEST;
+       if(none && !fast && !best && !custom) comp = COMP_NONE;
+       if(!none && fast && !best && !custom) comp = COMP_FAST;
+       if(!none && !fast && best && !custom) comp = COMP_BEST;
+       if(!none && !fast && !best && custom) comp = COMP_CUST;
     }
 
     if(serv && !clie) {
-       if(none && !fast && !best) comp = COMP_NONE;
-       if(!none && fast && !best) comp = COMP_SERV_FAST;
-       if(!none && !fast && best) comp = COMP_SERV_BEST;
+       if(none && !fast && !best && !custom) comp = COMP_NONE;
+       if(!none && fast && !best && !custom) comp = COMP_SERV_FAST;
+       if(!none && !fast && best && !custom) comp = COMP_SERV_BEST;
+       if(!none && !fast && !best && custom) comp = COMP_SERV_CUST;
     }
 
     if(comp == -1) {
-       parserror("NONE, CLIENT FAST, CLIENT BEST, SERVER FAST or SERVER BEST expected");
+       parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected");
        comp = COMP_NONE;
     }
 
@@ -2033,6 +2291,43 @@ static void get_compress()
     keytable = save_kt;
 }
 
+keytab_t encrypt_keytable[] = {
+    { "NONE", NONE },
+    { "CLIENT", CLIENT },
+    { "SERVER", SERVER },
+    { NULL, IDENT }
+};
+
+static void get_encrypt()
+{
+   keytab_t *save_kt;
+   int encrypt;
+
+   save_kt = keytable;
+   keytable = encrypt_keytable;
+
+   ckseen(&dpcur.s_encrypt);
+
+   get_conftoken(ANY);
+   switch(tok) {
+   case NONE:  
+     encrypt = ENCRYPT_NONE; 
+     break;
+   case CLIENT:  
+     encrypt = ENCRYPT_CUST;
+     break;
+   case SERVER: 
+     encrypt = ENCRYPT_SERV_CUST;
+     break;
+   default:
+     parserror("NONE, CLIENT or SERVER expected");
+     encrypt = ENCRYPT_NONE;
+   }
+
+   dpcur.encrypt = encrypt;
+   keytable = save_kt; 
+}
+
 keytab_t taperalgo_keytable[] = {
     { "FIRST", FIRST },
     { "FIRSTFIT", FIRSTFIT },
@@ -2101,39 +2396,6 @@ static void get_priority()
     keytable = save_kt;
 }
 
-keytab_t auth_keytable[] = {
-    { "BSD", BSD_AUTH },
-    { "KRB4", KRB4_AUTH },
-    { NULL, IDENT }
-};
-
-static void get_auth()
-{
-    auth_t auth;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = auth_keytable;
-
-    ckseen(&dpcur.s_auth);
-
-    get_conftoken(ANY);
-    switch(tok) {
-    case BSD_AUTH:
-       auth = AUTH_BSD;
-       break;
-    case KRB4_AUTH:
-       auth = AUTH_KRB4;
-       break;
-    default:
-       parserror("BSD or KRB4 expected");
-       auth = AUTH_BSD;
-    }
-    dpcur.auth = auth;
-
-    keytable = save_kt;
-}
-
 keytab_t strategy_keytable[] = {
     { "HANOI", HANOI },
     { "NOFULL", NOFULL },
@@ -2183,6 +2445,42 @@ static void get_strategy()
     keytable = save_kt;
 }
 
+keytab_t estimate_keytable[] = {
+    { "CLIENT", CLIENT },
+    { "SERVER", SERVER },
+    { "CALCSIZE", CALCSIZE }
+};
+
+static void get_estimate()
+{
+    int estime;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = estimate_keytable;
+
+    ckseen(&dpcur.s_estimate);
+
+    get_conftoken(ANY);
+    switch(tok) {
+    case CLIENT:
+       estime = ES_CLIENT;
+       break;
+    case SERVER:
+       estime = ES_SERVER;
+       break;
+    case CALCSIZE:
+       estime = ES_CALCSIZE;
+       break;
+    default:
+       parserror("CLIENT, SERVER or CALCSIZE expected");
+       estime = ES_CLIENT;
+    }
+    dpcur.estimate = estime;
+
+    keytable = save_kt;
+}
+
 keytab_t exclude_keytable[] = {
     { "LIST", LIST },
     { "FILE", EFILE },
@@ -2331,7 +2629,13 @@ tok_t type;
        malloc_mark(var->s);
        break;
     case INT:
-       var->i = get_number();
+       var->i = get_int();
+       break;
+    case LONG:
+       var->l = get_long();
+       break;
+    case AM64:
+       var->am64 = get_am64_t();
        break;
     case BOOL:
        var->i = get_bool();
@@ -2409,7 +2713,7 @@ keytab_t numb_keytable[] = {
     { NULL, IDENT }
 };
 
-static int get_number()
+static int get_int()
 {
     int val;
     keytab_t *save_kt;
@@ -2420,11 +2724,13 @@ static int get_number()
     get_conftoken(ANY);
 
     switch(tok) {
-    case INT:
-       val = tokenval.i;
+    case AM64:
+       if(abs(tokenval.am64) > INT_MAX)
+           parserror("value too large");
+       val = (int) tokenval.am64;
        break;
     case INFINITY:
-       val = BIGINT;
+       val = (int) BIGINT;
        break;
     default:
        parserror("an integer expected");
@@ -2440,12 +2746,128 @@ static int get_number()
     case MULT1K:
        break;
     case MULT7:
+       if(abs(val) > INT_MAX/7)
+           parserror("value too large");
        val *= 7;
        break;
     case MULT1M:
+       if(abs(val) > INT_MAX/1024)
+           parserror("value too large");
        val *= 1024;
        break;
     case MULT1G:
+       if(abs(val) > INT_MAX/(1024*1024))
+           parserror("value too large");
+       val *= 1024*1024;
+       break;
+    default:   /* it was not a multiplier */
+       unget_conftoken();
+    }
+
+    keytable = save_kt;
+
+    return val;
+}
+
+static long get_long()
+{
+    long val;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = numb_keytable;
+
+    get_conftoken(ANY);
+
+    switch(tok) {
+    case AM64:
+       if(tokenval.am64 > LONG_MAX || tokenval.am64 < LONG_MIN)
+           parserror("value too large");
+       val = (long) tokenval.am64;
+       break;
+    case INFINITY:
+       val = (long) LONG_MAX;
+       break;
+    default:
+       parserror("a long expected");
+       val = 0;
+    }
+
+    /* get multiplier, if any */
+    get_conftoken(ANY);
+
+    switch(tok) {
+    case NL:                   /* multiply by one */
+    case MULT1:
+    case MULT1K:
+       break;
+    case MULT7:
+       if(val > LONG_MAX/7 || val < LONG_MIN/7)
+           parserror("value too large");
+       val *= 7;
+       break;
+    case MULT1M:
+       if(val > LONG_MAX/1024 || val < LONG_MIN/7)
+           parserror("value too large");
+       val *= 1024;
+       break;
+    case MULT1G:
+       if(val > LONG_MAX/(1024*1024) || val < LONG_MIN/(1024*1024))
+           parserror("value too large");
+       val *= 1024*1024;
+       break;
+    default:   /* it was not a multiplier */
+       unget_conftoken();
+    }
+
+    keytable = save_kt;
+
+    return val;
+}
+
+static am64_t get_am64_t()
+{
+    am64_t val;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = numb_keytable;
+
+    get_conftoken(ANY);
+
+    switch(tok) {
+    case AM64:
+       val = tokenval.am64;
+       break;
+    case INFINITY:
+       val = AM64_MAX;
+       break;
+    default:
+       parserror("a am64 expected %d", tok);
+       val = 0;
+    }
+
+    /* get multiplier, if any */
+    get_conftoken(ANY);
+
+    switch(tok) {
+    case NL:                   /* multiply by one */
+    case MULT1:
+    case MULT1K:
+       break;
+    case MULT7:
+       if(val > AM64_MAX/7 || val < AM64_MIN/7)
+           parserror("value too large");
+       val *= 7;
+       break;
+    case MULT1M:
+       if(val > AM64_MAX/1024 || val < AM64_MIN/1024)
+           parserror("value too large");
+       val *= 1024;
+       break;
+    case MULT1G:
+       if(val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
+           parserror("value too large");
        val *= 1024*1024;
        break;
     default:   /* it was not a multiplier */
@@ -2553,7 +2975,8 @@ static void unget_conftoken()
 static void get_conftoken(exp)
 tok_t exp;
 {
-    int ch, i, d;
+    int ch, d;
+    am64_t am64;
     char *buf;
     int token_overflow;
 
@@ -2564,6 +2987,7 @@ tok_t exp;
        /* If it looked like a key word before then look it
        ** up again in the current keyword table. */
        switch(tok) {
+       case LONG:    case AM64:
        case INT:     case REAL:    case STRING:
        case LBRACE:  case RBRACE:  case COMMA:
        case NL:      case END:     case UNKNOWN:
@@ -2615,34 +3039,42 @@ tok_t exp;
            negative_number: /* look for goto negative_number below */
                sign = -1;
            }
-           tokenval.i = 0;
+           tokenval.am64 = 0;
            do {
-               tokenval.i = tokenval.i * 10 + (ch - '0');
+               tokenval.am64 = tokenval.am64 * 10 + (ch - '0');
                ch = getc(conf);
            } while(isdigit(ch));
            if(ch != '.') {
-               if(exp != REAL) {
+               if(exp == INT) {
                    tok = INT;
                    tokenval.i *= sign;
+               }
+               else if(exp == LONG) {
+                   tok = LONG;
+                   tokenval.l *= sign;
+               }
+               else if(exp != REAL) {
+                   tok = AM64;
+                   tokenval.am64 *= sign;
                } else {
                    /* automatically convert to real when expected */
-                   i = tokenval.i;
-                   tokenval.r = sign * (double) i;
+                   am64 = tokenval.am64;
+                   tokenval.r = sign * (double) am64;
                    tok = REAL;
                }
            }
            else {
                /* got a real number, not an int */
-               i = tokenval.i;
-               tokenval.r = sign * (double) i;
-               i=0; d=1;
+               am64 = tokenval.am64;
+               tokenval.r = sign * (double) am64;
+               am64=0; d=1;
                ch = getc(conf);
                while(isdigit(ch)) {
-                   i = i * 10 + (ch - '0');
+                   am64 = am64 * 10 + (ch - '0');
                    d = d * 10;
                    ch = getc(conf);
                }
-               tokenval.r += sign * ((double)i)/d;
+               tokenval.r += sign * ((double)am64)/d;
                tok = REAL;
            }
            ungetc(ch,conf);
@@ -2730,8 +3162,12 @@ int ColumnDataCount()
 
 /* conversion from string to table index
  */
-int StringToColumn(char *s) {
+int
+StringToColumn(s)
+    char *s;
+{
     int cn;
+
     for (cn=0; ColumnData[cn].Name != NULL; cn++) {
        if (strcasecmp(s, ColumnData[cn].Name) == 0) {
            break;
@@ -2740,11 +3176,19 @@ int StringToColumn(char *s) {
     return cn;
 }
 
-char LastChar(char *s) {
+char
+LastChar(s)
+    char *s;
+{
     return s[strlen(s)-1];
 }
 
-int SetColumDataFromString(ColumnInfo* ci, char *s, char **errstr) {
+int
+SetColumDataFromString(ci, s, errstr)
+    ColumnInfo* ci;
+    char *s;
+    char **errstr;
+{
     /* Convert from a Columspec string to our internal format
      * of columspec. The purpose is to provide this string
      * as configuration paramter in the amanda.conf file or
@@ -2833,6 +3277,10 @@ int taperalgo;
     return "UNKNOWN";
 }
 
+long int getconf_unit_divisor()
+{
+    return unit_divisor;
+}
 
 /* ------------------------ */
 
@@ -2872,6 +3320,7 @@ dump_configuration(filename)
     printf("conf_runspercycle = %d\n", getconf_int(CNF_RUNSPERCYCLE));
     printf("conf_runtapes = %d\n", getconf_int(CNF_RUNTAPES));
     printf("conf_tapecycle = %d\n", getconf_int(CNF_TAPECYCLE));
+    printf("conf_bumppercent = %d\n", getconf_int(CNF_BUMPPERCENT));
     printf("conf_bumpsize = %d\n", getconf_int(CNF_BUMPSIZE));
     printf("conf_bumpdays = %d\n", getconf_int(CNF_BUMPDAYS));
     printf("conf_bumpmult = %f\n", getconf_real(CNF_BUMPMULT));
@@ -2886,17 +3335,21 @@ dump_configuration(filename)
     printf("conf_tapebufs = %d\n", getconf_int(CNF_TAPEBUFS));
     printf("conf_autoflush  = %d\n", getconf_int(CNF_AUTOFLUSH));
     printf("conf_reserve  = %d\n", getconf_int(CNF_RESERVE));
-    printf("conf_maxdumpsize  = %d\n", getconf_int(CNF_MAXDUMPSIZE));
+    printf("conf_maxdumpsize  = " AM64_FMT "\n", getconf_am64(CNF_MAXDUMPSIZE));
     printf("conf_amrecover_do_fsf  = %d\n", getconf_int(CNF_AMRECOVER_DO_FSF));
     printf("conf_amrecover_check_label  = %d\n", getconf_int(CNF_AMRECOVER_CHECK_LABEL));
     printf("conf_amrecover_changer = \"%s\"\n", getconf_str(CNF_AMRECOVER_CHANGER));
     printf("conf_taperalgo  = %s\n", taperalgo2str(getconf_int(CNF_TAPERALGO)));
+    printf("conf_displayunit  = %s\n", getconf_str(CNF_DISPLAYUNIT));
 
     /*printf("conf_diskdir = \"%s\"\n", getconf_str(CNF_DISKDIR));*/
     /*printf("conf_disksize = %d\n", getconf_int(CNF_DISKSIZE));*/
     printf("conf_columnspec = \"%s\"\n", getconf_str(CNF_COLUMNSPEC));
     printf("conf_indexdir = \"%s\"\n", getconf_str(CNF_INDEXDIR));
     printf("num_holdingdisks = %d\n", num_holdingdisks);
+    printf("conf_krb5keytab = \"%s\"\n", getconf_str(CNF_KRB5KEYTAB));
+    printf("conf_krb5principal = \"%s\"\n", getconf_str(CNF_KRB5PRINCIPAL));
+    printf("conf_label_new_tapes  = \"%s\"\n", getconf_str(CNF_LABEL_NEW_TAPES));
     for(hp = holdingdisks; hp != NULL; hp = hp->next) {
        printf("\nHOLDINGDISK %s:\n", hp->name);
        printf("        COMMENT \"%s\"\n", hp->comment);
@@ -2920,6 +3373,12 @@ dump_configuration(filename)
        printf("\nDUMPTYPE %s:\n", dp->name);
        printf("        COMMENT \"%s\"\n", dp->comment);
        printf("        PROGRAM \"%s\"\n", dp->program);
+       printf("        SERVER_CUSTOM_COMPRESS \"%s\"\n", dp->srvcompprog);
+       printf("        CLIENT_CUSTOM_COMPRESS \"%s\"\n", dp->clntcompprog);
+       printf("        SERVER_ENCRYPT \"%s\"\n", dp->srv_encrypt);
+       printf("        CLIENT_ENCRYPT \"%s\"\n", dp->clnt_encrypt);
+       printf("        SERVER_DECRYPT_OPTION \"%s\"\n", dp->srv_decrypt_opt);
+       printf("        CLIENT_DECRYPT_OPTION \"%s\"\n", dp->clnt_decrypt_opt);
        printf("        PRIORITY %ld\n", (long)dp->priority);
        printf("        DUMPCYCLE %ld\n", (long)dp->dumpcycle);
        st = dp->start_t;
@@ -2985,6 +3444,19 @@ dump_configuration(filename)
            break;
        }
        putchar('\n');
+       printf("        ESTIMATE ");
+       switch(dp->estimate) {
+       case ES_CLIENT:
+           printf("CLIENT");
+           break;
+       case ES_SERVER:
+           printf("SERVER");
+           break;
+       case ES_CALCSIZE:
+           printf("CALCSIZE");
+           break;
+       }
+       putchar('\n');
        printf("        COMPRATE %f, %f\n", dp->comprate[0], dp->comprate[1]);
 
        printf("        OPTIONS: ");
@@ -2999,19 +3471,35 @@ dump_configuration(filename)
        case COMP_BEST:
            printf("COMPRESS-BEST ");
            break;
+       case COMP_CUST:
+           printf("COMPRESS-CUST ");
+           break;
        case COMP_SERV_FAST:
            printf("SRVCOMP-FAST ");
            break;
        case COMP_SERV_BEST:
            printf("SRVCOMP-BEST ");
            break;
+       case COMP_SERV_CUST:
+           printf("SRVCOMP-CUST ");
+           break;
+       }
+
+       switch(dp->encrypt) {
+       case ENCRYPT_NONE:
+           printf("ENCRYPT-NONE ");
+           break;
+       case ENCRYPT_CUST:
+           printf("ENCRYPT-CUST ");
+           break;
+       case ENCRYPT_SERV_CUST:
+           printf("ENCRYPT-SERV-CUST ");
+           break;
        }
 
        if(!dp->record) printf("NO-");
        printf("RECORD");
-       if(dp->auth == AUTH_BSD) printf(" BSD-AUTH");
-       else if(dp->auth == AUTH_KRB4) printf(" KRB4-AUTH");
-       else printf(" UNKNOWN-AUTH");
+       printf(" %s-AUTH", dp->security_driver);
        if(dp->skip_incr) printf(" SKIP-INCR");
        if(dp->skip_full) printf(" SKIP-FULL");
        if(dp->no_hold) printf(" NO-HOLD");
@@ -3036,23 +3524,18 @@ main(argc, argv)
 {
   char *conffile;
   char *diskfile;
+  disklist_t lst;
   int result;
-  int fd;
   unsigned long malloc_hist_1, malloc_size_1;
   unsigned long malloc_hist_2, malloc_size_2;
 
-  for(fd = 3; fd < FD_SETSIZE; fd++) {
-    /*
-     * Make sure nobody spoofs us with a lot of extra open files
-     * that would cause an open we do to get a very high file
-     * descriptor, which in turn might be used as an index into
-     * an array (e.g. an fd_set).
-     */
-    close(fd);
-  }
+  safe_fd(-1, 0);
 
   set_pname("conffile");
 
+  /* Don't die when child closes pipe */
+  signal(SIGPIPE, SIG_IGN);
+
   malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
   startclock();
@@ -3082,10 +3565,10 @@ main(argc, argv)
   conffile = stralloc2(config_dir, CONFFILE_NAME);
   result = read_conffile(conffile);
   if (result == 0) {
-    diskfile = getconf_str(CNF_DISKFILE);
-    if (diskfile != NULL && access(diskfile, R_OK) == 0) {
-      result = (read_diskfile(diskfile) == NULL);
-    }
+      diskfile = getconf_str(CNF_DISKFILE);
+      if (diskfile != NULL && access(diskfile, R_OK) == 0) {
+         result = read_diskfile(diskfile, &lst);
+      }
   }
   dump_configuration(CONFFILE_NAME);
   amfree(conffile);
@@ -3100,3 +3583,19 @@ main(argc, argv)
 }
 
 #endif /* TEST */
+
+char *
+generic_get_security_conf(string, arg)
+       char *string;
+       void *arg;
+{
+       if(!string || !*string)
+               return(NULL);
+
+       if(strcmp(string, "krb5principal")==0) {
+               return(getconf_str(CNF_KRB5PRINCIPAL));
+       } else if(strcmp(string, "krb5keytab")==0) {
+               return(getconf_str(CNF_KRB5KEYTAB));
+       }
+       return(NULL);
+}