2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-2000 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: James da Silva, Systems Design and Analysis Group
24 * Computer Science Department
25 * University of Maryland at College Park
28 * $Id: conffile.c,v 1.54.2.16.2.5.2.20 2003/11/26 16:12:19 martinea Exp $
30 * read configuration file
34 * XXX - I'm not happy *at all* with this implementation, but I don't
35 * think YACC would be any easier. A more table based implementation
36 * would be better. Also clean up memory leaks.
51 #define INT_MAX 2147483647
54 #define BIGINT 1000000000 /* 2 million yrs @ 1 per day */
56 /* internal types and variables */
59 * XXX - this is used by the krb4 stuff.
60 * Hopefully nobody will need this here. (not very likely). -kovert
62 #if defined(INTERFACE)
67 UNKNOWN, ANY, COMMA, LBRACE, RBRACE, NL, END,
68 IDENT, INT, BOOL, REAL, STRING, TIME,
70 /* config parameters */
72 ORG, MAILTO, DUMPUSER,
73 TAPECYCLE, TAPEDEV, CHNGRDEV, CHNGRFILE, LABELSTR,
74 BUMPSIZE, BUMPDAYS, BUMPMULT, ETIMEOUT, DTIMEOUT, CTIMEOUT,
75 TAPEBUFS, TAPELIST, DISKFILE, INFOFILE, LOGDIR, LOGFILE,
76 DISKDIR, DISKSIZE, INDEXDIR, NETUSAGE, INPARALLEL, DUMPORDER, TIMEOUT,
78 DEFINE, DUMPTYPE, TAPETYPE, INTERFACE,
79 PRINTER, AUTOFLUSH, RESERVE, MAXDUMPSIZE,
81 AMRECOVER_DO_FSF, AMRECOVER_CHECK_LABEL, AMRECOVER_CHANGER,
83 TAPERALGO, FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST, LAST,
86 COMMENT, DIRECTORY, USE, CHUNKSIZE,
89 /*COMMENT,*/ PROGRAM, DUMPCYCLE, RUNSPERCYCLE, MAXCYCLE, MAXDUMPS,
90 OPTIONS, PRIORITY, FREQUENCY, INDEX, MAXPROMOTEDAY,
91 STARTTIME, COMPRESS, AUTH, STRATEGY,
92 SKIP_INCR, SKIP_FULL, RECORD, HOLDING,
93 EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE,
96 /*COMMENT,*/ BLOCKSIZE, FILE_PAD, LBL_TEMPL, FILEMARK, LENGTH, SPEED,
98 /* network interface */
101 /* dump options (obsolete) */
102 EXCLUDE_FILE, EXCLUDE_LIST,
105 NONE, FAST, BEST, SERVER, CLIENT,
114 SKIP, STANDARD, NOFULL, NOINC, HANOI, INCRONLY,
117 LIST, EFILE, APPEND, OPTIONAL,
120 INFINITY, MULT1, MULT7, MULT1K, MULT1M, MULT1G,
128 typedef struct { /* token table entry */
141 /* this corresponds to the normal output of amanda, but may
142 * be adapted to any spacing as you like.
144 ColumnInfo ColumnData[] = {
145 { "HostName", 0, 12, 12, 0, "%-*.*s", "HOSTNAME" },
146 { "Disk", 1, 11, 11, 0, "%-*.*s", "DISK" },
147 { "Level", 1, 1, 1, 0, "%*.*d", "L" },
148 { "OrigKB", 1, 7, 0, 0, "%*.*f", "ORIG-KB" },
149 { "OutKB", 0, 7, 0, 0, "%*.*f", "OUT-KB" },
150 { "Compress", 0, 6, 1, 0, "%*.*f", "COMP%" },
151 { "DumpTime", 0, 7, 7, 0, "%*.*s", "MMM:SS" },
152 { "DumpRate", 0, 6, 1, 0, "%*.*f", "KB/s" },
153 { "TapeTime", 1, 6, 6, 0, "%*.*s", "MMM:SS" },
154 { "TapeRate", 0, 6, 1, 0, "%*.*f", "KB/s" },
155 { NULL, 0, 0, 0, 0, NULL, NULL }
158 char *config_name = NULL;
159 char *config_dir = NULL;
161 /* visible holding disk variables */
163 holdingdisk_t *holdingdisks;
164 int num_holdingdisks;
166 /* configuration parameters */
169 static val_t conf_org;
170 static val_t conf_mailto;
171 static val_t conf_dumpuser;
172 static val_t conf_printer;
173 static val_t conf_tapedev;
174 static val_t conf_rawtapedev;
175 static val_t conf_tpchanger;
176 static val_t conf_chngrdev;
177 static val_t conf_chngrfile;
178 static val_t conf_labelstr;
179 static val_t conf_tapelist;
180 static val_t conf_infofile;
181 static val_t conf_logdir;
182 static val_t conf_diskfile;
183 static val_t conf_diskdir;
184 static val_t conf_tapetype;
185 static val_t conf_indexdir;
186 static val_t conf_columnspec;
187 static val_t conf_dumporder;
188 static val_t conf_amrecover_changer;
191 static val_t conf_dumpcycle;
192 static val_t conf_runspercycle;
193 static val_t conf_maxcycle;
194 static val_t conf_tapecycle;
195 static val_t conf_runtapes;
196 static val_t conf_disksize;
197 static val_t conf_netusage;
198 static val_t conf_inparallel;
199 static val_t conf_timeout;
200 static val_t conf_maxdumps;
201 static val_t conf_bumpsize;
202 static val_t conf_bumpdays;
203 static val_t conf_etimeout;
204 static val_t conf_dtimeout;
205 static val_t conf_ctimeout;
206 static val_t conf_tapebufs;
207 static val_t conf_autoflush;
208 static val_t conf_reserve;
209 static val_t conf_maxdumpsize;
210 static val_t conf_amrecover_do_fsf;
211 static val_t conf_amrecover_check_label;
212 static val_t conf_taperalgo;
215 static val_t conf_bumpmult;
217 /* other internal variables */
218 static holdingdisk_t hdcur;
220 static tapetype_t tpcur;
222 static dumptype_t dpcur;
224 static interface_t ifcur;
227 static int seen_mailto;
228 static int seen_dumpuser;
229 static int seen_rawtapedev;
230 static int seen_printer;
231 static int seen_tapedev;
232 static int seen_tpchanger;
233 static int seen_chngrdev;
234 static int seen_chngrfile;
235 static int seen_labelstr;
236 static int seen_runtapes;
237 static int seen_maxdumps;
238 static int seen_tapelist;
239 static int seen_infofile;
240 static int seen_diskfile;
241 static int seen_diskdir;
242 static int seen_logdir;
243 static int seen_bumpsize;
244 static int seen_bumpmult;
245 static int seen_bumpdays;
246 static int seen_tapetype;
247 static int seen_dumpcycle;
248 static int seen_runspercycle;
249 static int seen_maxcycle;
250 static int seen_tapecycle;
251 static int seen_disksize;
252 static int seen_netusage;
253 static int seen_inparallel;
254 static int seen_dumporder;
255 static int seen_timeout;
256 static int seen_indexdir;
257 static int seen_etimeout;
258 static int seen_dtimeout;
259 static int seen_ctimeout;
260 static int seen_tapebufs;
261 static int seen_autoflush;
262 static int seen_reserve;
263 static int seen_maxdumpsize;
264 static int seen_columnspec;
265 static int seen_amrecover_do_fsf;
266 static int seen_amrecover_check_label;
267 static int seen_amrecover_changer;
268 static int seen_taperalgo;
270 static int allow_overwrites;
271 static int token_pushed;
273 static tok_t tok, pushed_tok;
274 static val_t tokenval;
276 static int line_num, got_parserror;
277 static dumptype_t *dumplist = NULL;
278 static tapetype_t *tapelist = NULL;
279 static interface_t *interface_list = NULL;
280 static FILE *conf = (FILE *)NULL;
281 static char *confname = NULL;
283 /* predeclare local functions */
285 static void init_defaults P((void));
286 static void read_conffile_recursively P((char *filename));
288 static int read_confline P((void));
289 static void get_holdingdisk P((void));
290 static void init_holdingdisk_defaults P((void));
291 static void save_holdingdisk P((void));
292 static void get_dumptype P((void));
293 static void init_dumptype_defaults P((void));
294 static void save_dumptype P((void));
295 static void copy_dumptype P((void));
296 static void get_tapetype P((void));
297 static void init_tapetype_defaults P((void));
298 static void save_tapetype P((void));
299 static void copy_tapetype P((void));
300 static void get_interface P((void));
301 static void init_interface_defaults P((void));
302 static void save_interface P((void));
303 static void copy_interface P((void));
304 static void get_dumpopts P((void));
305 static void get_comprate P((void));
306 static void get_compress P((void));
307 static void get_priority P((void));
308 static void get_auth P((void));
309 static void get_strategy P((void));
310 static void get_exclude P((void));
311 static void get_include P((void));
312 static void get_taperalgo P((val_t *c_taperalgo, int *s_taperalgo));
314 static void get_simple P((val_t *var, int *seen, tok_t type));
315 static int get_time P((void));
316 static int get_number P((void));
317 static int get_bool P((void));
318 static void ckseen P((int *seen));
319 static void parserror P((char *format, ...))
320 __attribute__ ((format (printf, 1, 2)));
321 static tok_t lookup_keyword P((char *str));
322 static void unget_conftoken P((void));
323 static void get_conftoken P((tok_t exp));
326 ** ------------------------
327 ** External entry points
328 ** ------------------------
331 int read_conffile(filename)
338 /* We assume that confname & conf are initialized to NULL above */
339 read_conffile_recursively(filename);
341 if(got_parserror != -1 ) {
342 if(lookup_tapetype(conf_tapetype.s) == NULL) {
343 char *save_confname = confname;
347 parserror("default tapetype %s not defined", conf_tapetype.s);
349 line_num = seen_tapetype;
350 parserror("tapetype %s not defined", conf_tapetype.s);
352 confname = save_confname;
356 ip = alloc(sizeof(interface_t));
359 ip->seen = seen_netusage;
360 ip->comment = "implicit from NETUSAGE";
361 ip->maxusage = conf_netusage.i;
363 ip->next = interface_list;
366 return got_parserror;
373 } byname_table [] = {
374 { "ORG", CNF_ORG, STRING },
375 { "MAILTO", CNF_MAILTO, STRING },
376 { "DUMPUSER", CNF_DUMPUSER, STRING },
377 { "PRINTER", CNF_PRINTER, STRING },
378 { "TAPEDEV", CNF_TAPEDEV, STRING },
379 { "TPCHANGER", CNF_TPCHANGER, STRING },
380 { "CHANGERDEV", CNF_CHNGRDEV, STRING },
381 { "CHANGERFILE", CNF_CHNGRFILE, STRING },
382 { "LABELSTR", CNF_LABELSTR, STRING },
383 { "TAPELIST", CNF_TAPELIST, STRING },
384 { "DISKFILE", CNF_DISKFILE, STRING },
385 { "INFOFILE", CNF_INFOFILE, STRING },
386 { "LOGDIR", CNF_LOGDIR, STRING },
387 /*{ "LOGFILE", CNF_LOGFILE, STRING },*/
388 /*{ "DISKDIR", CNF_DISKDIR, STRING },*/
389 { "INDEXDIR", CNF_INDEXDIR, STRING },
390 { "TAPETYPE", CNF_TAPETYPE, STRING },
391 { "DUMPCYCLE", CNF_DUMPCYCLE, INT },
392 { "RUNSPERCYCLE", CNF_RUNSPERCYCLE, INT },
393 { "MINCYCLE", CNF_DUMPCYCLE, INT },
394 { "RUNTAPES", CNF_RUNTAPES, INT },
395 { "TAPECYCLE", CNF_TAPECYCLE, INT },
396 /*{ "DISKSIZE", CNF_DISKSIZE, INT },*/
397 { "BUMPDAYS", CNF_BUMPDAYS, INT },
398 { "BUMPSIZE", CNF_BUMPSIZE, INT },
399 { "BUMPMULT", CNF_BUMPMULT, REAL },
400 { "NETUSAGE", CNF_NETUSAGE, INT },
401 { "INPARALLEL", CNF_INPARALLEL, INT },
402 { "DUMPORDER", CNF_DUMPORDER, STRING },
403 /*{ "TIMEOUT", CNF_TIMEOUT, INT },*/
404 { "MAXDUMPS", CNF_MAXDUMPS, INT },
405 { "ETIMEOUT", CNF_ETIMEOUT, INT },
406 { "DTIMEOUT", CNF_DTIMEOUT, INT },
407 { "CTIMEOUT", CNF_CTIMEOUT, INT },
408 { "TAPEBUFS", CNF_TAPEBUFS, INT },
409 { "RAWTAPEDEV", CNF_RAWTAPEDEV, STRING },
410 { "COLUMNSPEC", CNF_COLUMNSPEC, STRING },
411 { "AMRECOVER_DO_FSF", CNF_AMRECOVER_DO_FSF, BOOL },
412 { "AMRECOVER_CHECK_LABEL", CNF_AMRECOVER_CHECK_LABEL, BOOL },
413 { "AMRECOVER_CHANGER", CNF_AMRECOVER_CHANGER, STRING },
414 { "TAPERALGO", CNF_TAPERALGO, INT },
415 { "AUTOFLUSH", CNF_AUTOFLUSH, BOOL },
416 { "RESERVE", CNF_RESERVE, INT },
417 { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, INT },
421 char *getconf_byname(str)
425 char number[NUM_STR_SIZE];
430 tmpstr = stralloc(str);
432 while((ch = *s++) != '\0') {
433 if(islower((int) ch)) s[-1] = toupper(ch);
436 for(np = byname_table; np->name != NULL; np++)
437 if(strcmp(np->name, tmpstr) == 0) break;
439 if(np->name == NULL) return NULL;
442 ap_snprintf(number, sizeof(number), "%d", getconf_int(np->parm));
443 tmpstr = newstralloc(tmpstr, number);
444 } else if(np->typ == REAL) {
445 ap_snprintf(number, sizeof(number), "%f", getconf_real(np->parm));
446 tmpstr = newstralloc(tmpstr, number);
448 tmpstr = newstralloc(tmpstr, getconf_str(np->parm));
454 int getconf_seen(parm)
458 case CNF_ORG: return seen_org;
459 case CNF_MAILTO: return seen_mailto;
460 case CNF_DUMPUSER: return seen_dumpuser;
461 case CNF_PRINTER: return seen_printer;
462 case CNF_TAPEDEV: return seen_tapedev;
463 case CNF_TPCHANGER: return seen_tpchanger;
464 case CNF_CHNGRDEV: return seen_chngrdev;
465 case CNF_CHNGRFILE: return seen_chngrfile;
466 case CNF_LABELSTR: return seen_labelstr;
467 case CNF_RUNTAPES: return seen_runtapes;
468 case CNF_MAXDUMPS: return seen_maxdumps;
469 case CNF_TAPELIST: return seen_tapelist;
470 case CNF_INFOFILE: return seen_infofile;
471 case CNF_DISKFILE: return seen_diskfile;
472 /*case CNF_DISKDIR: return seen_diskdir;*/
473 case CNF_LOGDIR: return seen_logdir;
474 /*case CNF_LOGFILE: return seen_logfile;*/
475 case CNF_BUMPSIZE: return seen_bumpsize;
476 case CNF_BUMPMULT: return seen_bumpmult;
477 case CNF_BUMPDAYS: return seen_bumpdays;
478 case CNF_TAPETYPE: return seen_tapetype;
479 case CNF_DUMPCYCLE: return seen_dumpcycle;
480 case CNF_RUNSPERCYCLE: return seen_runspercycle;
481 /*case CNF_MAXCYCLE: return seen_maxcycle;*/
482 case CNF_TAPECYCLE: return seen_tapecycle;
483 /*case CNF_DISKSIZE: return seen_disksize;*/
484 case CNF_NETUSAGE: return seen_netusage;
485 case CNF_INPARALLEL: return seen_inparallel;
486 case CNF_DUMPORDER: return seen_dumporder;
487 /*case CNF_TIMEOUT: return seen_timeout;*/
488 case CNF_INDEXDIR: return seen_indexdir;
489 case CNF_ETIMEOUT: return seen_etimeout;
490 case CNF_DTIMEOUT: return seen_dtimeout;
491 case CNF_CTIMEOUT: return seen_ctimeout;
492 case CNF_TAPEBUFS: return seen_tapebufs;
493 case CNF_RAWTAPEDEV: return seen_rawtapedev;
494 case CNF_AUTOFLUSH: return seen_autoflush;
495 case CNF_RESERVE: return seen_reserve;
496 case CNF_MAXDUMPSIZE: return seen_maxdumpsize;
497 case CNF_AMRECOVER_DO_FSF: return seen_amrecover_do_fsf;
498 case CNF_AMRECOVER_CHECK_LABEL: return seen_amrecover_check_label;
499 case CNF_AMRECOVER_CHANGER: return seen_amrecover_changer;
500 case CNF_TAPERALGO: return seen_taperalgo;
505 int getconf_int(parm)
512 case CNF_DUMPCYCLE: r = conf_dumpcycle.i; break;
513 case CNF_RUNSPERCYCLE: r = conf_runspercycle.i; break;
514 case CNF_TAPECYCLE: r = conf_tapecycle.i; break;
515 case CNF_RUNTAPES: r = conf_runtapes.i; break;
516 /*case CNF_DISKSIZE: r = conf_disksize.i; break;*/
517 case CNF_BUMPSIZE: r = conf_bumpsize.i; break;
518 case CNF_BUMPDAYS: r = conf_bumpdays.i; break;
519 case CNF_NETUSAGE: r = conf_netusage.i; break;
520 case CNF_INPARALLEL: r = conf_inparallel.i; break;
521 /*case CNF_TIMEOUT: r = conf_timeout.i; break;*/
522 case CNF_MAXDUMPS: r = conf_maxdumps.i; break;
523 case CNF_ETIMEOUT: r = conf_etimeout.i; break;
524 case CNF_DTIMEOUT: r = conf_dtimeout.i; break;
525 case CNF_CTIMEOUT: r = conf_ctimeout.i; break;
526 case CNF_TAPEBUFS: r = conf_tapebufs.i; break;
527 case CNF_AUTOFLUSH: r = conf_autoflush.i; break;
528 case CNF_RESERVE: r = conf_reserve.i; break;
529 case CNF_MAXDUMPSIZE: r = conf_maxdumpsize.i; break;
530 case CNF_AMRECOVER_DO_FSF: r = conf_amrecover_do_fsf.i; break;
531 case CNF_AMRECOVER_CHECK_LABEL: r = conf_amrecover_check_label.i; break;
532 case CNF_TAPERALGO: r = conf_taperalgo.i; break;
535 error("error [unknown getconf_int parm: %d]", parm);
541 double getconf_real(parm)
548 case CNF_BUMPMULT: r = conf_bumpmult.r; break;
551 error("error [unknown getconf_real parm: %d]", parm);
557 char *getconf_str(parm)
564 case CNF_ORG: r = conf_org.s; break;
565 case CNF_MAILTO: r = conf_mailto.s; break;
566 case CNF_DUMPUSER: r = conf_dumpuser.s; break;
567 case CNF_PRINTER: r = conf_printer.s; break;
568 case CNF_TAPEDEV: r = conf_tapedev.s; break;
569 case CNF_TPCHANGER: r = conf_tpchanger.s; break;
570 case CNF_CHNGRDEV: r = conf_chngrdev.s; break;
571 case CNF_CHNGRFILE: r = conf_chngrfile.s; break;
572 case CNF_LABELSTR: r = conf_labelstr.s; break;
573 case CNF_TAPELIST: r = conf_tapelist.s; break;
574 case CNF_INFOFILE: r = conf_infofile.s; break;
575 case CNF_DUMPORDER: r = conf_dumporder.s; break;
576 case CNF_LOGDIR: r = conf_logdir.s; break;
577 /*case CNF_LOGFILE: r = conf_logfile.s; break;*/
578 case CNF_DISKFILE: r = conf_diskfile.s; break;
579 /*case CNF_DISKDIR: r = conf_diskdir.s; break;*/
580 case CNF_TAPETYPE: r = conf_tapetype.s; break;
581 case CNF_INDEXDIR: r = conf_indexdir.s; break;
582 case CNF_RAWTAPEDEV: r = conf_rawtapedev.s; break;
583 case CNF_COLUMNSPEC: r = conf_columnspec.s; break;
584 case CNF_AMRECOVER_CHANGER: r = conf_amrecover_changer.s; break;
587 error("error [unknown getconf_str parm: %d]", parm);
593 holdingdisk_t *getconf_holdingdisks()
598 dumptype_t *lookup_dumptype(str)
603 for(p = dumplist; p != NULL; p = p->next) {
604 if(strcmp(p->name, str) == 0) return p;
609 tapetype_t *lookup_tapetype(str)
614 for(p = tapelist; p != NULL; p = p->next) {
615 if(strcmp(p->name, str) == 0) return p;
620 interface_t *lookup_interface(str)
625 if(str == NULL) return interface_list;
626 for(p = interface_list; p != NULL; p = p->next) {
627 if(strcmp(p->name, str) == 0) return p;
634 ** ------------------------
636 ** ------------------------
640 static void init_defaults()
644 /* defaults for exported variables */
646 #ifdef DEFAULT_CONFIG
651 conf_org.s = stralloc(s);
652 malloc_mark(conf_org.s);
653 conf_mailto.s = stralloc("operators");
654 malloc_mark(conf_mailto.s);
655 conf_dumpuser.s = stralloc(CLIENT_LOGIN);
656 malloc_mark(conf_dumpuser.s);
657 #ifdef DEFAULT_TAPE_DEVICE
658 s = DEFAULT_TAPE_DEVICE;
662 conf_tapedev.s = stralloc(s);
663 malloc_mark(conf_tapedev.s);
664 #ifdef DEFAULT_RAW_TAPE_DEVICE
665 s = DEFAULT_RAW_TAPE_DEVICE;
669 conf_rawtapedev.s = stralloc(s);
670 malloc_mark(conf_rawtapedev.s);
671 conf_tpchanger.s = stralloc("");
672 malloc_mark(conf_tpchanger.s);
673 #ifdef DEFAULT_CHANGER_DEVICE
674 s = DEFAULT_CHANGER_DEVICE;
678 conf_chngrdev.s = stralloc(s);
679 malloc_mark(conf_chngrdev.s);
680 conf_chngrfile.s = stralloc("/usr/adm/amanda/changer-status");
681 malloc_mark(conf_chngrfile.s);
682 conf_labelstr.s = stralloc(".*");
683 malloc_mark(conf_labelstr.s);
684 conf_tapelist.s = stralloc("tapelist");
685 malloc_mark(conf_tapelist.s);
686 conf_infofile.s = stralloc("/usr/adm/amanda/curinfo");
687 malloc_mark(conf_infofile.s);
688 conf_logdir.s = stralloc("/usr/adm/amanda");
689 malloc_mark(conf_logdir.s);
690 conf_diskfile.s = stralloc("disklist");
691 malloc_mark(conf_diskfile.s);
692 conf_diskdir.s = stralloc("/dumps/amanda");
693 malloc_mark(conf_diskdir.s);
694 conf_tapetype.s = stralloc("EXABYTE");
695 malloc_mark(conf_tapetype.s);
696 conf_indexdir.s = stralloc("/usr/adm/amanda/index");
697 malloc_mark(conf_indexdir.s);
698 conf_columnspec.s = stralloc("");
699 malloc_mark(conf_columnspec.s);
700 conf_dumporder.s = stralloc("ttt");
701 malloc_mark(conf_dumporder.s);
702 conf_amrecover_changer.s = stralloc("");
703 conf_printer.s = stralloc("");
705 conf_dumpcycle.i = 10;
706 conf_runspercycle.i = 0;
707 conf_tapecycle.i = 15;
710 conf_netusage.i = 300;
711 conf_inparallel.i = 10;
714 conf_bumpsize.i = 10*1024;
716 conf_bumpmult.r = 1.5;
717 conf_etimeout.i = 300;
718 conf_dtimeout.i = 1800;
719 conf_ctimeout.i = 30;
720 conf_tapebufs.i = 20;
721 conf_autoflush.i = 0;
722 conf_reserve.i = 100;
723 conf_maxdumpsize.i = -1;
724 conf_amrecover_do_fsf.i = 0;
725 conf_amrecover_check_label.i = 0;
726 conf_taperalgo.i = 0;
728 /* defaults for internal variables */
752 seen_runspercycle = 0;
767 seen_maxdumpsize = 0;
769 seen_amrecover_do_fsf = 0;
770 seen_amrecover_check_label = 0;
771 seen_amrecover_changer = 0;
773 line_num = got_parserror = 0;
774 allow_overwrites = 0;
777 while(holdingdisks != NULL) {
781 holdingdisks = holdingdisks->next;
784 num_holdingdisks = 0;
786 /* free any previously declared dump, tape and interface types */
788 while(dumplist != NULL) {
792 dumplist = dumplist->next;
795 while(tapelist != NULL) {
799 tapelist = tapelist->next;
802 while(interface_list != NULL) {
806 interface_list = interface_list->next;
810 /* create some predefined dumptypes for backwards compatability */
811 init_dumptype_defaults();
812 dpcur.name = "NO-COMPRESS"; dpcur.seen = -1;
813 dpcur.compress = COMP_NONE; dpcur.s_compress = -1;
816 init_dumptype_defaults();
817 dpcur.name = "COMPRESS-FAST"; dpcur.seen = -1;
818 dpcur.compress = COMP_FAST; dpcur.s_compress = -1;
821 init_dumptype_defaults();
822 dpcur.name = "COMPRESS-BEST"; dpcur.seen = -1;
823 dpcur.compress = COMP_BEST; dpcur.s_compress = -1;
826 init_dumptype_defaults();
827 dpcur.name = "SRVCOMPRESS"; dpcur.seen = -1;
828 dpcur.compress = COMP_SERV_FAST; dpcur.s_compress = -1;
831 init_dumptype_defaults();
832 dpcur.name = "BSD-AUTH"; dpcur.seen = -1;
833 dpcur.auth = AUTH_BSD; dpcur.s_auth = -1;
836 init_dumptype_defaults();
837 dpcur.name = "KRB4-AUTH"; dpcur.seen = -1;
838 dpcur.auth = AUTH_KRB4; dpcur.s_auth = -1;
841 init_dumptype_defaults();
842 dpcur.name = "NO-RECORD"; dpcur.seen = -1;
843 dpcur.record = 0; dpcur.s_record = -1;
846 init_dumptype_defaults();
847 dpcur.name = "NO-HOLD"; dpcur.seen = -1;
848 dpcur.no_hold = 1; dpcur.s_no_hold = -1;
851 init_dumptype_defaults();
852 dpcur.name = "NO-FULL"; dpcur.seen = -1;
853 dpcur.strategy = DS_NOFULL; dpcur.s_strategy = -1;
857 static void read_conffile_recursively(filename)
862 /* Save globals used in read_confline(), elsewhere. */
863 int save_line_num = line_num;
864 FILE *save_conf = conf;
865 char *save_confname = confname;
867 if (*filename == '/' || config_dir == NULL) {
868 confname = stralloc(filename);
870 confname = stralloc2(config_dir, filename);
873 if((conf = fopen(confname, "r")) == NULL) {
874 fprintf(stderr, "could not open conf file \"%s\": %s\n", confname,
883 /* read_confline() can invoke us recursively via "includefile" */
884 while(read_confline());
889 /* Restore globals */
890 line_num = save_line_num;
892 confname = save_confname;
896 /* ------------------------ */
899 keytab_t main_keytable[] = {
900 { "BUMPDAYS", BUMPDAYS },
901 { "BUMPMULT", BUMPMULT },
902 { "BUMPSIZE", BUMPSIZE },
903 { "DEFINE", DEFINE },
904 { "DISKDIR", DISKDIR }, /* XXX - historical */
905 { "DISKFILE", DISKFILE },
906 { "DISKSIZE", DISKSIZE }, /* XXX - historical */
907 { "DUMPCYCLE", DUMPCYCLE },
908 { "RUNSPERCYCLE", RUNSPERCYCLE },
909 { "DUMPTYPE", DUMPTYPE },
910 { "DUMPUSER", DUMPUSER },
911 { "PRINTER", PRINTER },
912 { "HOLDINGDISK", HOLDING },
913 { "INCLUDEFILE", INCLUDEFILE },
914 { "INDEXDIR", INDEXDIR },
915 { "INFOFILE", INFOFILE },
916 { "INPARALLEL", INPARALLEL },
917 { "DUMPORDER", DUMPORDER },
918 { "INTERFACE", INTERFACE },
919 { "LABELSTR", LABELSTR },
920 { "LOGDIR", LOGDIR },
921 { "LOGFILE", LOGFILE }, /* XXX - historical */
922 { "MAILTO", MAILTO },
923 { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */
924 { "MAXDUMPS", MAXDUMPS },
925 { "MINCYCLE", DUMPCYCLE }, /* XXX - historical */
926 { "NETUSAGE", NETUSAGE }, /* XXX - historical */
928 { "RUNTAPES", RUNTAPES },
929 { "TAPECYCLE", TAPECYCLE },
930 { "TAPEDEV", TAPEDEV },
931 { "TAPELIST", TAPELIST },
932 { "TAPETYPE", TAPETYPE },
933 { "TIMEOUT", TIMEOUT }, /* XXX - historical */
934 { "TPCHANGER", TPCHANGER },
935 { "CHANGERDEV", CHNGRDEV },
936 { "CHANGERFILE", CHNGRFILE },
937 { "ETIMEOUT", ETIMEOUT },
938 { "DTIMEOUT", DTIMEOUT },
939 { "CTIMEOUT", CTIMEOUT },
940 { "TAPEBUFS", TAPEBUFS },
941 { "RAWTAPEDEV", RAWTAPEDEV },
942 { "AUTOFLUSH", AUTOFLUSH },
943 { "RESERVE", RESERVE },
944 { "MAXDUMPSIZE", MAXDUMPSIZE },
945 { "COLUMNSPEC", COLUMNSPEC },
946 { "AMRECOVER_DO_FSF", AMRECOVER_DO_FSF },
947 { "AMRECOVER_CHECK_LABEL", AMRECOVER_CHECK_LABEL },
948 { "AMRECOVER_CHANGER", AMRECOVER_CHANGER },
949 { "TAPERALGO", TAPERALGO },
953 static int read_confline()
955 keytable = main_keytable;
964 get_conftoken(STRING);
966 read_conffile_recursively(fn);
970 case ORG: get_simple(&conf_org, &seen_org, STRING); break;
971 case MAILTO: get_simple(&conf_mailto, &seen_mailto, STRING); break;
972 case DUMPUSER: get_simple(&conf_dumpuser, &seen_dumpuser, STRING); break;
973 case PRINTER: get_simple(&conf_printer, &seen_printer, STRING); break;
974 case DUMPCYCLE: get_simple(&conf_dumpcycle, &seen_dumpcycle, INT);
975 if(conf_dumpcycle.i < 0) {
976 parserror("dumpcycle must be positive");
979 case RUNSPERCYCLE: get_simple(&conf_runspercycle, &seen_runspercycle, INT);
980 if(conf_runspercycle.i < -1) {
981 parserror("runspercycle must be >= -1");
984 case MAXCYCLE: get_simple(&conf_maxcycle, &seen_maxcycle, INT); break;
985 case TAPECYCLE: get_simple(&conf_tapecycle, &seen_tapecycle, INT);
986 if(conf_tapecycle.i < 1) {
987 parserror("tapecycle must be positive");
990 case RUNTAPES: get_simple(&conf_runtapes, &seen_runtapes, INT);
991 if(conf_runtapes.i < 1) {
992 parserror("runtapes must be positive");
995 case TAPEDEV: get_simple(&conf_tapedev, &seen_tapedev, STRING); break;
996 case RAWTAPEDEV:get_simple(&conf_rawtapedev,&seen_rawtapedev,STRING); break;
997 case TPCHANGER: get_simple(&conf_tpchanger, &seen_tpchanger, STRING); break;
998 case CHNGRDEV: get_simple(&conf_chngrdev, &seen_chngrdev, STRING); break;
999 case CHNGRFILE: get_simple(&conf_chngrfile, &seen_chngrfile, STRING); break;
1000 case LABELSTR: get_simple(&conf_labelstr, &seen_labelstr, STRING); break;
1001 case TAPELIST: get_simple(&conf_tapelist, &seen_tapelist, STRING); break;
1002 case INFOFILE: get_simple(&conf_infofile, &seen_infofile, STRING); break;
1003 case LOGDIR: get_simple(&conf_logdir, &seen_logdir, STRING); break;
1004 case DISKFILE: get_simple(&conf_diskfile, &seen_diskfile, STRING); break;
1005 case BUMPMULT: get_simple(&conf_bumpmult, &seen_bumpmult, REAL);
1006 if(conf_bumpmult.r < 0.999) {
1007 parserror("bumpmult must be positive");
1010 case BUMPSIZE: get_simple(&conf_bumpsize, &seen_bumpsize, INT);
1011 if(conf_bumpsize.i < 1) {
1012 parserror("bumpsize must be positive");
1015 case BUMPDAYS: get_simple(&conf_bumpdays, &seen_bumpdays, INT);
1016 if(conf_bumpdays.i < 1) {
1017 parserror("bumpdays must be positive");
1020 case NETUSAGE: get_simple(&conf_netusage, &seen_netusage, INT);
1021 if(conf_netusage.i < 1) {
1022 parserror("netusage must be positive");
1025 case INPARALLEL:get_simple(&conf_inparallel,&seen_inparallel,INT);
1026 if(conf_inparallel.i < 1 || conf_inparallel.i >MAX_DUMPERS){
1028 "inparallel must be between 1 and MAX_DUMPERS (%d)",
1032 case DUMPORDER: get_simple(&conf_dumporder, &seen_dumporder, STRING); break;
1033 case TIMEOUT: get_simple(&conf_timeout, &seen_timeout, INT); break;
1034 case MAXDUMPS: get_simple(&conf_maxdumps, &seen_maxdumps, INT);
1035 if(conf_maxdumps.i < 1) {
1036 parserror("maxdumps must be positive");
1039 case TAPETYPE: get_simple(&conf_tapetype, &seen_tapetype, IDENT); break;
1040 case INDEXDIR: get_simple(&conf_indexdir, &seen_indexdir, STRING); break;
1041 case ETIMEOUT: get_simple(&conf_etimeout, &seen_etimeout, INT); break;
1042 case DTIMEOUT: get_simple(&conf_dtimeout, &seen_dtimeout, INT);
1043 if(conf_dtimeout.i < 1) {
1044 parserror("dtimeout must be positive");
1047 case CTIMEOUT: get_simple(&conf_ctimeout, &seen_ctimeout, INT);
1048 if(conf_ctimeout.i < 1) {
1049 parserror("ctimeout must be positive");
1052 case TAPEBUFS: get_simple(&conf_tapebufs, &seen_tapebufs, INT);
1053 if(conf_tapebufs.i < 1) {
1054 parserror("tapebufs must be positive");
1057 case AUTOFLUSH: get_simple(&conf_autoflush, &seen_autoflush, BOOL); break;
1058 case RESERVE: get_simple(&conf_reserve, &seen_reserve, INT);
1059 if(conf_reserve.i < 0 || conf_reserve.i > 100) {
1060 parserror("reserve must be between 0 and 100");
1063 case MAXDUMPSIZE:get_simple(&conf_maxdumpsize,&seen_maxdumpsize,INT); break;
1064 case COLUMNSPEC:get_simple(&conf_columnspec,&seen_columnspec,STRING); break;
1066 case AMRECOVER_DO_FSF: get_simple(&conf_amrecover_do_fsf,&seen_amrecover_do_fsf, BOOL); break;
1067 case AMRECOVER_CHECK_LABEL: get_simple(&conf_amrecover_check_label,&seen_amrecover_check_label, BOOL); break;
1068 case AMRECOVER_CHANGER: get_simple(&conf_amrecover_changer,&seen_amrecover_changer, STRING); break;
1070 case TAPERALGO: get_taperalgo(&conf_taperalgo,&seen_taperalgo); break;
1072 case LOGFILE: /* XXX - historical */
1073 /* truncate the filename part and pretend he said "logdir" */
1077 get_simple(&conf_logdir, &seen_logdir, STRING);
1079 p = strrchr(conf_logdir.s, '/');
1080 if (p != (char *)0) *p = '\0';
1088 get_conftoken(STRING);
1092 conf_diskdir.s = newstralloc(conf_diskdir.s, s);
1093 seen_diskdir = line_num;
1096 init_holdingdisk_defaults();
1097 hdcur.name = "default from DISKDIR";
1098 hdcur.seen = line_num;
1099 hdcur.diskdir = stralloc(s);
1100 hdcur.s_disk = line_num;
1101 hdcur.disksize = conf_disksize.i;
1102 hdcur.s_size = seen_disksize;
1112 i = (i / DISK_BLOCK_KB) * DISK_BLOCK_KB;
1114 if(!seen_disksize) {
1115 conf_disksize.i = i;
1116 seen_disksize = line_num;
1119 if(holdingdisks != NULL)
1120 holdingdisks->disksize = i;
1131 if(tok == DUMPTYPE) get_dumptype();
1132 else if(tok == TAPETYPE) get_tapetype();
1133 else if(tok == INTERFACE) get_interface();
1134 else parserror("DUMPTYPE, INTERFACE or TAPETYPE expected");
1137 case NL: /* empty line */
1139 case END: /* end of file */
1142 parserror("configuration keyword expected");
1144 if(tok != NL) get_conftoken(NL);
1148 keytab_t holding_keytable[] = {
1149 { "DIRECTORY", DIRECTORY },
1150 { "COMMENT", COMMENT },
1152 { "CHUNKSIZE", CHUNKSIZE },
1156 static void get_holdingdisk()
1159 int save_overwrites;
1162 save_overwrites = allow_overwrites;
1163 allow_overwrites = 1;
1166 keytable = holding_keytable;
1168 init_holdingdisk_defaults();
1170 get_conftoken(IDENT);
1171 hdcur.name = stralloc(tokenval.s);
1172 malloc_mark(hdcur.name);
1173 hdcur.seen = line_num;
1175 get_conftoken(LBRACE);
1185 get_simple((val_t *)&hdcur.comment, &hdcur.s_comment, STRING);
1188 get_simple((val_t *)&hdcur.diskdir, &hdcur.s_disk, STRING);
1191 get_simple((val_t *)&hdcur.disksize, &hdcur.s_size, INT);
1192 hdcur.disksize = am_floor(hdcur.disksize, DISK_BLOCK_KB);
1195 get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, INT);
1196 if(hdcur.chunksize == 0) {
1197 hdcur.chunksize = ((INT_MAX / 1024) - (2 * DISK_BLOCK_KB));
1198 } else if(hdcur.chunksize < 0) {
1199 parserror("Negative chunksize (%ld) is no longer supported",
1202 hdcur.chunksize = am_floor(hdcur.chunksize, DISK_BLOCK_KB);
1207 case NL: /* empty line */
1209 case END: /* end of file */
1212 parserror("holding disk parameter expected");
1214 if(tok != NL && tok != END) get_conftoken(NL);
1219 allow_overwrites = save_overwrites;
1223 static void init_holdingdisk_defaults()
1225 hdcur.comment = stralloc("");
1226 hdcur.diskdir = stralloc(conf_diskdir.s);
1227 malloc_mark(hdcur.diskdir);
1229 hdcur.chunksize = 1024*1024*1024; /* 1 Gb */
1231 hdcur.s_comment = 0;
1236 hdcur.up = (void *)0;
1239 static void save_holdingdisk()
1243 hp = alloc(sizeof(holdingdisk_t));
1246 hp->next = holdingdisks;
1253 keytab_t dumptype_keytable[] = {
1255 { "COMMENT", COMMENT },
1256 { "COMPRATE", COMPRATE },
1257 { "COMPRESS", COMPRESS },
1258 { "DUMPCYCLE", DUMPCYCLE },
1259 { "EXCLUDE", EXCLUDE },
1260 { "FREQUENCY", FREQUENCY }, /* XXX - historical */
1261 { "HOLDINGDISK", HOLDING },
1262 { "IGNORE", IGNORE },
1263 { "INCLUDE", INCLUDE },
1265 { "KENCRYPT", KENCRYPT },
1266 { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */
1267 { "MAXDUMPS", MAXDUMPS },
1268 { "MAXPROMOTEDAY", MAXPROMOTEDAY },
1269 { "OPTIONS", OPTIONS }, /* XXX - historical */
1270 { "PRIORITY", PRIORITY },
1271 { "PROGRAM", PROGRAM },
1272 { "RECORD", RECORD },
1273 { "SKIP-FULL", SKIP_FULL },
1274 { "SKIP-INCR", SKIP_INCR },
1275 { "STARTTIME", STARTTIME },
1276 { "STRATEGY", STRATEGY },
1280 dumptype_t *read_dumptype(name, from, fname, linenum)
1287 int save_overwrites;
1290 FILE *saved_conf = NULL;
1291 char *saved_fname = NULL;
1299 saved_fname = confname;
1304 line_num = *linenum;
1306 save_overwrites = allow_overwrites;
1307 allow_overwrites = 1;
1310 keytable = dumptype_keytable;
1312 init_dumptype_defaults();
1317 get_conftoken(IDENT);
1318 dpcur.name = stralloc(tokenval.s);
1319 malloc_mark(dpcur.name);
1322 dpcur.seen = line_num;
1325 get_conftoken(LBRACE);
1339 get_simple((val_t *)&dpcur.comment, &dpcur.s_comment, STRING);
1348 get_simple((val_t *)&dpcur.dumpcycle, &dpcur.s_dumpcycle, INT);
1349 if(dpcur.dumpcycle < 0) {
1350 parserror("dumpcycle must be positive");
1357 get_simple((val_t *)&dpcur.frequency, &dpcur.s_frequency, INT);
1360 get_simple(&tmpval, &dpcur.s_no_hold, BOOL);
1361 dpcur.no_hold = (tmpval.i == 0);
1364 get_simple(&tmpval, &dpcur.s_ignore, BOOL);
1365 dpcur.ignore = (tmpval.i != 0);
1371 get_simple(&tmpval, &dpcur.s_index, BOOL);
1372 dpcur.index = (tmpval.i != 0);
1375 get_simple(&tmpval, &dpcur.s_kencrypt, BOOL);
1376 dpcur.kencrypt = (tmpval.i != 0);
1379 get_simple((val_t *)&conf_maxcycle, &dpcur.s_maxcycle, INT);
1382 get_simple((val_t *)&dpcur.maxdumps, &dpcur.s_maxdumps, INT);
1383 if(dpcur.maxdumps < 1) {
1384 parserror("maxdumps must be positive");
1388 get_simple((val_t *)&dpcur.maxpromoteday, &dpcur.s_maxpromoteday, INT);
1389 if(dpcur.maxpromoteday < 0) {
1390 parserror("dpcur.maxpromoteday must be >= 0");
1400 get_simple((val_t *)&dpcur.program, &dpcur.s_program, STRING);
1401 if(strcmp(dpcur.program, "DUMP")
1402 && strcmp(dpcur.program, "GNUTAR"))
1403 parserror("backup program \"%s\" unknown", dpcur.program);
1406 get_simple(&tmpval, &dpcur.s_record, BOOL);
1407 dpcur.record = (tmpval.i != 0);
1410 get_simple(&tmpval, &dpcur.s_skip_full, BOOL);
1411 dpcur.skip_full = (tmpval.i != 0);
1414 get_simple(&tmpval, &dpcur.s_skip_incr, BOOL);
1415 dpcur.skip_incr = (tmpval.i != 0);
1418 get_simple((val_t *)&dpcur.start_t, &dpcur.s_start_t, TIME);
1431 case NL: /* empty line */
1433 case END: /* end of file */
1436 parserror("dump type parameter expected");
1438 if(tok != NL && tok != END &&
1439 /* When a name is specified, we shouldn't consume the NL
1440 after the RBRACE. */
1441 (tok != RBRACE || name == 0))
1445 /* XXX - there was a stupidity check in here for skip-incr and
1446 ** skip-full. This check should probably be somewhere else. */
1450 allow_overwrites = save_overwrites;
1454 *linenum = line_num;
1457 confname = saved_fname;
1462 return lookup_dumptype(dpcur.name);
1465 static void get_dumptype()
1467 read_dumptype(NULL, NULL, NULL, NULL);
1470 static void init_dumptype_defaults()
1472 dpcur.comment = stralloc("");
1473 dpcur.program = stralloc("DUMP");
1474 dpcur.exclude_file = NULL;
1475 dpcur.exclude_list = NULL;
1476 dpcur.include_file = NULL;
1477 dpcur.include_list = NULL;
1479 dpcur.dumpcycle = conf_dumpcycle.i;
1480 dpcur.maxcycle = conf_maxcycle.i;
1481 dpcur.frequency = 1;
1482 dpcur.maxdumps = conf_maxdumps.i;
1483 dpcur.maxpromoteday = 10000;
1486 dpcur.auth = AUTH_BSD;
1490 dpcur.strategy = DS_STANDARD;
1491 dpcur.compress = COMP_FAST;
1492 dpcur.comprate[0] = dpcur.comprate[1] = 0.50;
1493 dpcur.skip_incr = dpcur.skip_full = 0;
1499 dpcur.s_comment = 0;
1500 dpcur.s_program = 0;
1501 dpcur.s_exclude_file = 0;
1502 dpcur.s_exclude_list = 0;
1503 dpcur.s_include_file = 0;
1504 dpcur.s_include_list = 0;
1505 dpcur.s_priority = 0;
1506 dpcur.s_dumpcycle = 0;
1507 dpcur.s_maxcycle = 0;
1508 dpcur.s_frequency = 0;
1509 dpcur.s_maxdumps = 0;
1510 dpcur.s_maxpromoteday = 0;
1511 dpcur.s_start_t = 0;
1514 dpcur.s_strategy = 0;
1515 dpcur.s_compress = 0;
1516 dpcur.s_comprate = 0;
1517 dpcur.s_skip_incr = 0;
1518 dpcur.s_skip_full = 0;
1519 dpcur.s_no_hold = 0;
1520 dpcur.s_kencrypt = 0;
1525 static void save_dumptype()
1529 dp = lookup_dumptype(dpcur.name);
1531 if(dp != (dumptype_t *)0) {
1532 parserror("dumptype %s already defined on line %d", dp->name, dp->seen);
1536 dp = alloc(sizeof(dumptype_t));
1539 dp->next = dumplist;
1543 static void copy_dumptype()
1547 dt = lookup_dumptype(tokenval.s);
1550 parserror("dump type parameter expected");
1554 #define dtcopy(v,s) if(dt->s) { dpcur.v = dt->v; dpcur.s = dt->s; }
1557 dpcur.comment = newstralloc(dpcur.comment, dt->comment);
1558 dpcur.s_comment = dt->s_comment;
1561 dpcur.program = newstralloc(dpcur.program, dt->program);
1562 dpcur.s_program = dt->s_program;
1564 if(dt->s_exclude_file) {
1565 dpcur.exclude_file = duplicate_sl(dt->exclude_file);
1566 dpcur.s_exclude_file = dt->s_exclude_file;
1568 if(dt->s_exclude_list) {
1569 dpcur.exclude_list = duplicate_sl(dt->exclude_list);
1570 dpcur.s_exclude_list = dt->s_exclude_list;
1572 if(dt->s_include_file) {
1573 dpcur.include_file = duplicate_sl(dt->include_file);
1574 dpcur.s_include_file = dt->s_include_file;
1576 if(dt->s_include_list) {
1577 dpcur.include_list = duplicate_sl(dt->include_list);
1578 dpcur.s_include_list = dt->s_include_list;
1580 dtcopy(priority, s_priority);
1581 dtcopy(dumpcycle, s_dumpcycle);
1582 dtcopy(maxcycle, s_maxcycle);
1583 dtcopy(frequency, s_frequency);
1584 dtcopy(maxdumps, s_maxdumps);
1585 dtcopy(maxpromoteday, s_maxpromoteday);
1586 dtcopy(start_t, s_start_t);
1587 dtcopy(auth, s_auth);
1588 dtcopy(record, s_record);
1589 dtcopy(strategy, s_strategy);
1590 dtcopy(compress, s_compress);
1591 dtcopy(comprate[0], s_comprate);
1592 dtcopy(comprate[1], s_comprate);
1593 dtcopy(skip_incr, s_skip_incr);
1594 dtcopy(skip_full, s_skip_full);
1595 dtcopy(no_hold, s_no_hold);
1596 dtcopy(kencrypt, s_kencrypt);
1597 dtcopy(ignore, s_ignore);
1598 dtcopy(index, s_index);
1601 keytab_t tapetype_keytable[] = {
1602 { "COMMENT", COMMENT },
1603 { "LBL-TEMPL", LBL_TEMPL },
1604 { "BLOCKSIZE", BLOCKSIZE },
1605 { "FILE-PAD", FILE_PAD },
1606 { "FILEMARK", FILEMARK },
1607 { "LENGTH", LENGTH },
1612 static void get_tapetype()
1615 int save_overwrites;
1620 save_overwrites = allow_overwrites;
1621 allow_overwrites = 1;
1624 keytable = tapetype_keytable;
1626 init_tapetype_defaults();
1628 get_conftoken(IDENT);
1629 tpcur.name = stralloc(tokenval.s);
1630 malloc_mark(tpcur.name);
1631 tpcur.seen = line_num;
1633 get_conftoken(LBRACE);
1646 get_simple((val_t *)&tpcur.comment, &tpcur.s_comment, STRING);
1649 get_simple((val_t *)&tpcur.lbl_templ, &tpcur.s_lbl_templ, STRING);
1652 get_simple((val_t *)&tpcur.blocksize, &tpcur.s_blocksize, INT);
1653 if(tpcur.blocksize < DISK_BLOCK_KB) {
1654 parserror("Tape blocksize must be at least %d KBytes",
1656 } else if(tpcur.blocksize > MAX_TAPE_BLOCK_KB) {
1657 parserror("Tape blocksize must not be larger than %d KBytes",
1662 get_simple(&value, &tpcur.s_file_pad, BOOL);
1663 tpcur.file_pad = (value.i != 0);
1666 get_simple(&value, &tpcur.s_length, INT);
1668 parserror("Tape length must be positive");
1671 tpcur.length = value.i;
1675 get_simple(&value, &tpcur.s_filemark, INT);
1677 parserror("Tape file mark size must be positive");
1680 tpcur.filemark = value.i;
1684 get_simple((val_t *)&tpcur.speed, &tpcur.s_speed, INT);
1685 if(tpcur.speed < 0) {
1686 parserror("Speed must be positive");
1692 case NL: /* empty line */
1694 case END: /* end of file */
1697 parserror("tape type parameter expected");
1699 if(tok != NL && tok != END) get_conftoken(NL);
1704 allow_overwrites = save_overwrites;
1708 static void init_tapetype_defaults()
1710 tpcur.comment = stralloc("");
1711 tpcur.lbl_templ = stralloc("");
1712 tpcur.blocksize = (DISK_BLOCK_KB);
1714 tpcur.length = 2000 * 1024;
1715 tpcur.filemark = 1000;
1718 tpcur.s_comment = 0;
1719 tpcur.s_lbl_templ = 0;
1720 tpcur.s_blocksize = 0;
1721 tpcur.s_file_pad = 0;
1723 tpcur.s_filemark = 0;
1727 static void save_tapetype()
1731 tp = lookup_tapetype(tpcur.name);
1733 if(tp != (tapetype_t *)0) {
1735 parserror("tapetype %s already defined on line %d", tp->name, tp->seen);
1739 tp = alloc(sizeof(tapetype_t));
1742 tp->next = tapelist;
1746 static void copy_tapetype()
1750 tp = lookup_tapetype(tokenval.s);
1753 parserror("tape type parameter expected");
1757 #define ttcopy(v,s) if(tp->s) { tpcur.v = tp->v; tpcur.s = tp->s; }
1760 tpcur.comment = newstralloc(tpcur.comment, tp->comment);
1761 tpcur.s_comment = tp->s_comment;
1763 if(tp->s_lbl_templ) {
1764 tpcur.lbl_templ = newstralloc(tpcur.lbl_templ, tp->lbl_templ);
1765 tpcur.s_lbl_templ = tp->s_lbl_templ;
1767 ttcopy(blocksize, s_blocksize);
1768 ttcopy(file_pad, s_file_pad);
1769 ttcopy(length, s_length);
1770 ttcopy(filemark, s_filemark);
1771 ttcopy(speed, s_speed);
1774 keytab_t interface_keytable[] = {
1775 { "COMMENT", COMMENT },
1780 static void get_interface()
1783 int save_overwrites;
1786 save_overwrites = allow_overwrites;
1787 allow_overwrites = 1;
1790 keytable = interface_keytable;
1792 init_interface_defaults();
1794 get_conftoken(IDENT);
1795 ifcur.name = stralloc(tokenval.s);
1796 malloc_mark(ifcur.name);
1797 ifcur.seen = line_num;
1799 get_conftoken(LBRACE);
1812 get_simple((val_t *)&ifcur.comment, &ifcur.s_comment, STRING);
1815 get_simple((val_t *)&ifcur.maxusage, &ifcur.s_maxusage, INT);
1816 if(ifcur.maxusage <1) {
1817 parserror("use must bbe positive");
1823 case NL: /* empty line */
1825 case END: /* end of file */
1828 parserror("interface parameter expected");
1830 if(tok != NL && tok != END) get_conftoken(NL);
1835 allow_overwrites = save_overwrites;
1841 static void init_interface_defaults()
1843 ifcur.comment = stralloc("");
1844 ifcur.maxusage = 300;
1846 ifcur.s_comment = 0;
1847 ifcur.s_maxusage = 0;
1852 static void save_interface()
1856 ip = lookup_interface(ifcur.name);
1858 if(ip != (interface_t *)0) {
1859 parserror("interface %s already defined on line %d", ip->name, ip->seen);
1863 ip = alloc(sizeof(interface_t));
1866 ip->next = interface_list;
1867 interface_list = ip;
1870 static void copy_interface()
1874 ip = lookup_interface(tokenval.s);
1877 parserror("interface parameter expected");
1881 #define ifcopy(v,s) if(ip->s) { ifcur.v = ip->v; ifcur.s = ip->s; }
1884 ifcur.comment = newstralloc(ifcur.comment, ip->comment);
1885 ifcur.s_comment = ip->s_comment;
1887 ifcopy(maxusage, s_maxusage);
1890 keytab_t dumpopts_keytable[] = {
1891 { "COMPRESS", COMPRESS },
1893 { "EXCLUDE-FILE", EXCLUDE_FILE },
1894 { "EXCLUDE-LIST", EXCLUDE_LIST },
1895 { "KENCRYPT", KENCRYPT },
1896 { "SKIP-FULL", SKIP_FULL },
1897 { "SKIP-INCR", SKIP_INCR },
1901 static void get_dumpopts() /* XXX - for historical compatability */
1907 keytable = dumpopts_keytable;
1913 case COMPRESS: ckseen(&dpcur.s_compress); dpcur.compress = COMP_FAST; break;
1915 ckseen(&dpcur.s_exclude_file);
1916 get_conftoken(STRING);
1917 dpcur.exclude_file = append_sl(dpcur.exclude_file, stralloc(tokenval.s));
1920 ckseen(&dpcur.s_exclude_list);
1921 get_conftoken(STRING);
1922 dpcur.exclude_list = append_sl(dpcur.exclude_list, stralloc(tokenval.s));
1924 case KENCRYPT: ckseen(&dpcur.s_kencrypt); dpcur.kencrypt = 1; break;
1925 case SKIP_INCR: ckseen(&dpcur.s_skip_incr); dpcur.skip_incr= 1; break;
1926 case SKIP_FULL: ckseen(&dpcur.s_skip_full); dpcur.skip_full= 1; break;
1927 case INDEX: ckseen(&dpcur.s_index); dpcur.index = 1; break;
1931 case NL: done = 1; break;
1936 parserror("dump option expected");
1943 static void get_comprate()
1947 get_simple(&var, &dpcur.s_comprate, REAL);
1948 dpcur.comprate[0] = dpcur.comprate[1] = var.r;
1949 if(dpcur.comprate[0] < 0) {
1950 parserror("full compression rate must be >= 0");
1963 get_conftoken(REAL);
1964 dpcur.comprate[1] = tokenval.r;
1965 if(dpcur.comprate[1] < 0) {
1966 parserror("incremental compression rate must be >= 0");
1970 keytab_t compress_keytable[] = {
1972 { "CLIENT", CLIENT },
1975 { "SERVER", SERVER },
1979 static void get_compress()
1982 int serv, clie, none, fast, best;
1987 keytable = compress_keytable;
1989 ckseen(&dpcur.s_compress);
1991 serv = clie = none = fast = best = 0;
1997 case NONE: none = 1; break;
1998 case FAST: fast = 1; break;
1999 case BEST: best = 1; break;
2000 case CLIENT: clie = 1; break;
2001 case SERVER: serv = 1; break;
2002 case NL: done = 1; break;
2005 serv = clie = 1; /* force an error */
2009 if(serv + clie == 0) clie = 1; /* default to client */
2010 if(none + fast + best == 0) fast = 1; /* default to fast */
2015 if(none && !fast && !best) comp = COMP_NONE;
2016 if(!none && fast && !best) comp = COMP_FAST;
2017 if(!none && !fast && best) comp = COMP_BEST;
2021 if(none && !fast && !best) comp = COMP_NONE;
2022 if(!none && fast && !best) comp = COMP_SERV_FAST;
2023 if(!none && !fast && best) comp = COMP_SERV_BEST;
2027 parserror("NONE, CLIENT FAST, CLIENT BEST, SERVER FAST or SERVER BEST expected");
2031 dpcur.compress = comp;
2036 keytab_t taperalgo_keytable[] = {
2038 { "FIRSTFIT", FIRSTFIT },
2039 { "LARGEST", LARGEST },
2040 { "LARGESTFIT", LARGESTFIT },
2041 { "SMALLEST", SMALLEST },
2046 static void get_taperalgo(c_taperalgo, s_taperalgo)
2053 keytable = taperalgo_keytable;
2055 ckseen(s_taperalgo);
2059 case FIRST: c_taperalgo->i = ALGO_FIRST; break;
2060 case FIRSTFIT: c_taperalgo->i = ALGO_FIRSTFIT; break;
2061 case LARGEST: c_taperalgo->i = ALGO_LARGEST; break;
2062 case LARGESTFIT: c_taperalgo->i = ALGO_LARGESTFIT; break;
2063 case SMALLEST: c_taperalgo->i = ALGO_SMALLEST; break;
2064 case LAST: c_taperalgo->i = ALGO_LAST; break;
2066 parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected");
2072 keytab_t priority_keytable[] = {
2075 { "MEDIUM", MEDIUM },
2079 static void get_priority()
2085 keytable = priority_keytable;
2087 ckseen(&dpcur.s_priority);
2091 case LOW: pri = 0; break;
2092 case MEDIUM: pri = 1; break;
2093 case HIGH: pri = 2; break;
2094 case INT: pri = tokenval.i; break;
2096 parserror("LOW, MEDIUM, HIGH or integer expected");
2099 dpcur.priority = pri;
2104 keytab_t auth_keytable[] = {
2105 { "BSD", BSD_AUTH },
2106 { "KRB4", KRB4_AUTH },
2110 static void get_auth()
2116 keytable = auth_keytable;
2118 ckseen(&dpcur.s_auth);
2129 parserror("BSD or KRB4 expected");
2137 keytab_t strategy_keytable[] = {
2139 { "NOFULL", NOFULL },
2142 { "STANDARD", STANDARD },
2143 { "INCRONLY", INCRONLY },
2147 static void get_strategy()
2153 keytable = strategy_keytable;
2155 ckseen(&dpcur.s_strategy);
2163 strat = DS_STANDARD;
2175 strat = DS_INCRONLY;
2178 parserror("STANDARD or NOFULL expected");
2179 strat = DS_STANDARD;
2181 dpcur.strategy = strat;
2186 keytab_t exclude_keytable[] = {
2189 { "APPEND", APPEND },
2190 { "OPTIONAL", OPTIONAL },
2194 static void get_exclude()
2196 int list, got_one = 0;
2203 keytable = exclude_keytable;
2208 exclude = dpcur.exclude_list;
2209 ckseen(&dpcur.s_exclude_list);
2214 exclude = dpcur.exclude_file;
2215 ckseen(&dpcur.s_exclude_file);
2216 if(tok == EFILE) get_conftoken(ANY);
2219 if(tok == OPTIONAL) {
2234 while(tok == STRING) {
2235 exclude = append_sl(exclude, tokenval.s);
2241 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
2244 dpcur.exclude_file = exclude;
2246 dpcur.exclude_list = exclude;
2247 if(!append || optional)
2248 dpcur.exclude_optional = optional;
2255 static void get_include()
2257 int list, got_one = 0;
2264 keytable = exclude_keytable;
2269 include = dpcur.include_list;
2270 ckseen(&dpcur.s_include_list);
2275 include = dpcur.include_file;
2276 ckseen(&dpcur.s_include_file);
2277 if(tok == EFILE) get_conftoken(ANY);
2280 if(tok == OPTIONAL) {
2295 while(tok == STRING) {
2296 include = append_sl(include, tokenval.s);
2302 if(got_one == 0) { free_sl(include); include = NULL; }
2305 dpcur.include_file = include;
2307 dpcur.include_list = include;
2308 if(!append || optional)
2309 dpcur.include_optional = optional;
2316 /* ------------------------ */
2319 static void get_simple(var, seen, type)
2329 get_conftoken(type);
2330 var->s = newstralloc(var->s, tokenval.s);
2331 malloc_mark(var->s);
2334 var->i = get_number();
2337 var->i = get_bool();
2340 get_conftoken(REAL);
2341 var->r = tokenval.r;
2344 var->i = get_time();
2347 error("error [unknown get_simple type: %d]", type);
2353 static int get_time()
2355 time_t st = start_time.r.tv_sec;
2362 stm = localtime(&st);
2363 st -= stm->tm_sec + 60 * (stm->tm_min + 60 * stm->tm_hour);
2364 st += ((hhmm/100*60) + hhmm%100)*60;
2366 if (st-start_time.r.tv_sec<-43200)
2372 keytab_t numb_keytable[] = {
2379 { "INF", INFINITY },
2383 { "KBYTE", MULT1K },
2384 { "KBYTES", MULT1K },
2385 { "KILOBYTE", MULT1K },
2386 { "KILOBYTES", MULT1K },
2391 { "MBYTE", MULT1M },
2392 { "MBYTES", MULT1M },
2394 { "MEGABYTE", MULT1M },
2395 { "MEGABYTES", MULT1M },
2399 { "GBYTE", MULT1G },
2400 { "GBYTES", MULT1G },
2402 { "GIGABYTE", MULT1G },
2403 { "GIGABYTES", MULT1G },
2412 static int get_number()
2418 keytable = numb_keytable;
2430 parserror("an integer expected");
2434 /* get multiplier, if any */
2438 case NL: /* multiply by one */
2451 default: /* it was not a multiplier */
2460 keytab_t bool_keytable[] = {
2469 { "FALSE", AFALSE },
2474 static int get_bool()
2480 keytable = bool_keytable;
2486 val = tokenval.i ? 1 : 0;
2497 val = 2; /* no argument - most likely TRUE */
2505 static void ckseen(seen)
2508 if(*seen && !allow_overwrites) {
2509 parserror("duplicate parameter, prev def on line %d", *seen);
2514 printf_arglist_function(static void parserror, char *, format)
2518 /* print error message */
2520 fprintf(stderr, "\"%s\", line %d: ", confname, line_num);
2521 arglist_start(argp, format);
2522 vfprintf(stderr, format, argp);
2524 fputc('\n', stderr);
2529 static tok_t lookup_keyword(str)
2534 /* switch to binary search if performance warrants */
2536 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
2537 if(strcmp(kwp->keyword, str) == 0) break;
2542 static char tkbuf[4096];
2544 /* push the last token back (can only unget ANY tokens) */
2545 static void unget_conftoken()
2553 static void get_conftoken(exp)
2564 /* If it looked like a key word before then look it
2565 ** up again in the current keyword table. */
2567 case INT: case REAL: case STRING:
2568 case LBRACE: case RBRACE: case COMMA:
2569 case NL: case END: case UNKNOWN:
2572 if(exp == IDENT) tok = IDENT;
2573 else tok = lookup_keyword(tokenval.s);
2579 while(ch != EOF && ch != '\n' && isspace(ch)) ch = getc(conf);
2580 if(ch == '#') { /* comment - eat everything but eol/eof */
2581 while((ch = getc(conf)) != EOF && ch != '\n') {}
2584 if(isalpha(ch)) { /* identifier */
2588 if(islower(ch)) ch = toupper(ch);
2589 if(buf < tkbuf+sizeof(tkbuf)-1) {
2593 if(!token_overflow) {
2594 parserror("token too long: %.20s...", tkbuf);
2599 } while(isalnum(ch) || ch == '_' || ch == '-');
2606 if(token_overflow) tok = UNKNOWN;
2607 else if(exp == IDENT) tok = IDENT;
2608 else tok = lookup_keyword(tokenval.s);
2610 else if(isdigit(ch)) { /* integer */
2615 negative_number: /* look for goto negative_number below */
2620 tokenval.i = tokenval.i * 10 + (ch - '0');
2622 } while(isdigit(ch));
2628 /* automatically convert to real when expected */
2630 tokenval.r = sign * (double) i;
2635 /* got a real number, not an int */
2637 tokenval.r = sign * (double) i;
2640 while(isdigit(ch)) {
2641 i = i * 10 + (ch - '0');
2645 tokenval.r += sign * ((double)i)/d;
2652 case '"': /* string */
2656 while(ch != '"' && ch != '\n' && ch != EOF) {
2657 if(buf < tkbuf+sizeof(tkbuf)-1) {
2661 if(!token_overflow) {
2662 parserror("string too long: %.20s...", tkbuf);
2669 parserror("missing end quote");
2674 if(token_overflow) tok = UNKNOWN;
2681 goto negative_number;
2687 case ',': tok = COMMA; break;
2688 case '{': tok = LBRACE; break;
2689 case '}': tok = RBRACE; break;
2690 case '\n': tok = NL; break;
2691 case EOF: tok = END; break;
2692 default: tok = UNKNOWN;
2696 if(exp != ANY && tok != exp) {
2701 case LBRACE: str = "\"{\""; break;
2702 case RBRACE: str = "\"}\""; break;
2703 case COMMA: str = "\",\""; break;
2705 case NL: str = "end of line"; break;
2706 case END: str = "end of file"; break;
2707 case INT: str = "an integer"; break;
2708 case REAL: str = "a real number"; break;
2709 case STRING: str = "a quoted string"; break;
2710 case IDENT: str = "an identifier"; break;
2712 for(kwp = keytable; kwp->keyword != NULL; kwp++)
2713 if(exp == kwp->token) break;
2714 if(kwp->keyword == NULL) str = "token not";
2715 else str = kwp->keyword;
2717 parserror("%s expected", str);
2719 if(tok == INT) tokenval.i = 0;
2720 else tokenval.s = "";
2726 int ColumnDataCount()
2728 return sizeof(ColumnData) / sizeof(ColumnData[0]);
2731 /* conversion from string to table index
2733 int StringToColumn(char *s) {
2735 for (cn=0; ColumnData[cn].Name != NULL; cn++) {
2736 if (strcasecmp(s, ColumnData[cn].Name) == 0) {
2743 char LastChar(char *s) {
2744 return s[strlen(s)-1];
2747 int SetColumDataFromString(ColumnInfo* ci, char *s, char **errstr) {
2748 /* Convert from a Columspec string to our internal format
2749 * of columspec. The purpose is to provide this string
2750 * as configuration paramter in the amanda.conf file or
2751 * (maybe) as environment variable.
2753 * This text should go as comment into the sample amanda.conf
2755 * The format for such a ColumnSpec string s is a ',' seperated
2756 * list of triples. Each triple consists of
2757 * -the name of the column (as in ColumnData.Name)
2758 * -prefix before the column
2759 * -the width of the column
2760 * if set to -1 it will be recalculated
2761 * to the maximum length of a line to print.
2763 * "Disk=1:17,HostName=1:10,OutKB=1:7"
2765 * "Disk=1:-1,HostName=1:10,OutKB=1:7"
2767 * You need only specify those colums that should be changed from
2768 * the default. If nothing is specified in the configfile, the
2769 * above compiled in values will be in effect, resulting in an
2770 * output as it was all the time.
2774 char *myname= "SetColumDataFromString";
2780 char *eon= strchr(s, '=');
2783 *errstr = stralloc2("invalid columnspec: ", s);
2785 fprintf(stderr, "%s: %s\n", myname, *errstr);
2790 cn=StringToColumn(s);
2791 if (ColumnData[cn].Name == NULL) {
2792 *errstr = stralloc2("invalid column name: ", s);
2794 fprintf(stderr, "%s: %s\n", myname, *errstr);
2798 if (sscanf(eon+1, "%d:%d", &Space, &Width) != 2) {
2799 *errstr = stralloc2("invalid format: ", eon + 1);
2801 fprintf(stderr, "%s: %s\n", myname, *errstr);
2805 ColumnData[cn].Width= Width;
2806 ColumnData[cn].PrefixSpace= Space;
2807 if (LastChar(ColumnData[cn].Format) == 's') {
2809 ColumnData[cn].MaxWidth= 1;
2811 if (Width > ColumnData[cn].Precision)
2812 ColumnData[cn].Precision= Width;
2814 else if (Width < ColumnData[cn].Precision)
2815 ColumnData[cn].Precision= Width;
2816 s= strchr(eon+1, ',');
2824 char *taperalgo2str(taperalgo)
2827 if(taperalgo == ALGO_FIRST) return "FIRST";
2828 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
2829 if(taperalgo == ALGO_LARGEST) return "LARGEST";
2830 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
2831 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
2832 if(taperalgo == ALGO_LAST) return "LAST";
2837 /* ------------------------ */
2843 dump_configuration(filename)
2853 printf("AMANDA CONFIGURATION FROM FILE \"%s\":\n\n", filename);
2855 printf("conf_org = \"%s\"\n", getconf_str(CNF_ORG));
2856 printf("conf_mailto = \"%s\"\n", getconf_str(CNF_MAILTO));
2857 printf("conf_dumpuser = \"%s\"\n", getconf_str(CNF_DUMPUSER));
2858 printf("conf_printer = \"%s\"\n", getconf_str(CNF_PRINTER));
2859 printf("conf_tapedev = \"%s\"\n", getconf_str(CNF_TAPEDEV));
2860 printf("conf_rawtapedev = \"%s\"\n", getconf_str(CNF_RAWTAPEDEV));
2861 printf("conf_tpchanger = \"%s\"\n", getconf_str(CNF_TPCHANGER));
2862 printf("conf_chngrdev = \"%s\"\n", getconf_str(CNF_CHNGRDEV));
2863 printf("conf_chngrfile = \"%s\"\n", getconf_str(CNF_CHNGRFILE));
2864 printf("conf_labelstr = \"%s\"\n", getconf_str(CNF_LABELSTR));
2865 printf("conf_tapelist = \"%s\"\n", getconf_str(CNF_TAPELIST));
2866 printf("conf_infofile = \"%s\"\n", getconf_str(CNF_INFOFILE));
2867 printf("conf_logdir = \"%s\"\n", getconf_str(CNF_LOGDIR));
2868 printf("conf_diskfile = \"%s\"\n", getconf_str(CNF_DISKFILE));
2869 printf("conf_tapetype = \"%s\"\n", getconf_str(CNF_TAPETYPE));
2871 printf("conf_dumpcycle = %d\n", getconf_int(CNF_DUMPCYCLE));
2872 printf("conf_runspercycle = %d\n", getconf_int(CNF_RUNSPERCYCLE));
2873 printf("conf_runtapes = %d\n", getconf_int(CNF_RUNTAPES));
2874 printf("conf_tapecycle = %d\n", getconf_int(CNF_TAPECYCLE));
2875 printf("conf_bumpsize = %d\n", getconf_int(CNF_BUMPSIZE));
2876 printf("conf_bumpdays = %d\n", getconf_int(CNF_BUMPDAYS));
2877 printf("conf_bumpmult = %f\n", getconf_real(CNF_BUMPMULT));
2878 printf("conf_netusage = %d\n", getconf_int(CNF_NETUSAGE));
2879 printf("conf_inparallel = %d\n", getconf_int(CNF_INPARALLEL));
2880 printf("conf_dumporder = \"%s\"\n", getconf_str(CNF_DUMPORDER));
2881 /*printf("conf_timeout = %d\n", getconf_int(CNF_TIMEOUT));*/
2882 printf("conf_maxdumps = %d\n", getconf_int(CNF_MAXDUMPS));
2883 printf("conf_etimeout = %d\n", getconf_int(CNF_ETIMEOUT));
2884 printf("conf_dtimeout = %d\n", getconf_int(CNF_DTIMEOUT));
2885 printf("conf_ctimeout = %d\n", getconf_int(CNF_CTIMEOUT));
2886 printf("conf_tapebufs = %d\n", getconf_int(CNF_TAPEBUFS));
2887 printf("conf_autoflush = %d\n", getconf_int(CNF_AUTOFLUSH));
2888 printf("conf_reserve = %d\n", getconf_int(CNF_RESERVE));
2889 printf("conf_maxdumpsize = %d\n", getconf_int(CNF_MAXDUMPSIZE));
2890 printf("conf_amrecover_do_fsf = %d\n", getconf_int(CNF_AMRECOVER_DO_FSF));
2891 printf("conf_amrecover_check_label = %d\n", getconf_int(CNF_AMRECOVER_CHECK_LABEL));
2892 printf("conf_amrecover_changer = \"%s\"\n", getconf_str(CNF_AMRECOVER_CHANGER));
2893 printf("conf_taperalgo = %s\n", taperalgo2str(getconf_int(CNF_TAPERALGO)));
2895 /*printf("conf_diskdir = \"%s\"\n", getconf_str(CNF_DISKDIR));*/
2896 /*printf("conf_disksize = %d\n", getconf_int(CNF_DISKSIZE));*/
2897 printf("conf_columnspec = \"%s\"\n", getconf_str(CNF_COLUMNSPEC));
2898 printf("conf_indexdir = \"%s\"\n", getconf_str(CNF_INDEXDIR));
2899 printf("num_holdingdisks = %d\n", num_holdingdisks);
2900 for(hp = holdingdisks; hp != NULL; hp = hp->next) {
2901 printf("\nHOLDINGDISK %s:\n", hp->name);
2902 printf(" COMMENT \"%s\"\n", hp->comment);
2903 printf(" DISKDIR \"%s\"\n", hp->diskdir);
2904 printf(" SIZE %ld\n", (long)hp->disksize);
2905 printf(" CHUNKSIZE %ld\n", (long)hp->chunksize);
2908 for(tp = tapelist; tp != NULL; tp = tp->next) {
2909 printf("\nTAPETYPE %s:\n", tp->name);
2910 printf(" COMMENT \"%s\"\n", tp->comment);
2911 printf(" LBL_TEMPL %s\n", tp->lbl_templ);
2912 printf(" BLOCKSIZE %ld\n", (long)tp->blocksize);
2913 printf(" FILE_PAD %s\n", (tp->file_pad) ? "YES" : "NO");
2914 printf(" LENGTH %lu\n", (unsigned long)tp->length);
2915 printf(" FILEMARK %lu\n", (unsigned long)tp->filemark);
2916 printf(" SPEED %ld\n", (long)tp->speed);
2919 for(dp = dumplist; dp != NULL; dp = dp->next) {
2920 printf("\nDUMPTYPE %s:\n", dp->name);
2921 printf(" COMMENT \"%s\"\n", dp->comment);
2922 printf(" PROGRAM \"%s\"\n", dp->program);
2923 printf(" PRIORITY %ld\n", (long)dp->priority);
2924 printf(" DUMPCYCLE %ld\n", (long)dp->dumpcycle);
2927 stm = localtime(&st);
2928 printf(" STARTTIME %d:%02d:%02d\n",
2929 stm->tm_hour, stm->tm_min, stm->tm_sec);
2931 if(dp->exclude_file) {
2933 printf(" EXCLUDE FILE");
2934 for(excl = dp->exclude_file->first; excl != NULL; excl =excl->next){
2935 printf(" \"%s\"", excl->name);
2939 if(dp->exclude_list) {
2941 printf(" EXCLUDE LIST");
2942 for(excl = dp->exclude_list->first; excl != NULL; excl =excl->next){
2943 printf(" \"%s\"", excl->name);
2947 if(dp->include_file) {
2949 printf(" INCLUDE FILE");
2950 for(incl = dp->include_file->first; incl != NULL; incl =incl->next){
2951 printf(" \"%s\"", incl->name);
2955 if(dp->include_list) {
2957 printf(" INCLUDE LIST");
2958 for(incl = dp->include_list->first; incl != NULL; incl =incl->next){
2959 printf(" \"%s\"", incl->name);
2963 printf(" FREQUENCY %ld\n", (long)dp->frequency);
2964 printf(" MAXDUMPS %d\n", dp->maxdumps);
2965 printf(" MAXPROMOTEDAY %d\n", dp->maxpromoteday);
2966 printf(" STRATEGY ");
2967 switch(dp->strategy) {
2988 printf(" COMPRATE %f, %f\n", dp->comprate[0], dp->comprate[1]);
2990 printf(" OPTIONS: ");
2992 switch(dp->compress) {
2994 printf("NO-COMPRESS ");
2997 printf("COMPRESS-FAST ");
3000 printf("COMPRESS-BEST ");
3002 case COMP_SERV_FAST:
3003 printf("SRVCOMP-FAST ");
3005 case COMP_SERV_BEST:
3006 printf("SRVCOMP-BEST ");
3010 if(!dp->record) printf("NO-");
3012 if(dp->auth == AUTH_BSD) printf(" BSD-AUTH");
3013 else if(dp->auth == AUTH_KRB4) printf(" KRB4-AUTH");
3014 else printf(" UNKNOWN-AUTH");
3015 if(dp->skip_incr) printf(" SKIP-INCR");
3016 if(dp->skip_full) printf(" SKIP-FULL");
3017 if(dp->no_hold) printf(" NO-HOLD");
3018 if(dp->kencrypt) printf(" KENCRYPT");
3019 /* an ignored disk will never reach this point */
3020 assert(!dp->ignore);
3021 if(dp->index) printf(" INDEX");
3025 for(ip = interface_list; ip != NULL; ip = ip->next) {
3026 printf("\nINTERFACE %s:\n", ip->name);
3027 printf(" COMMENT \"%s\"\n", ip->comment);
3028 printf(" USE %d\n", ip->maxusage);
3041 unsigned long malloc_hist_1, malloc_size_1;
3042 unsigned long malloc_hist_2, malloc_size_2;
3044 for(fd = 3; fd < FD_SETSIZE; fd++) {
3046 * Make sure nobody spoofs us with a lot of extra open files
3047 * that would cause an open we do to get a very high file
3048 * descriptor, which in turn might be used as an index into
3049 * an array (e.g. an fd_set).
3054 set_pname("conffile");
3056 malloc_size_1 = malloc_inuse(&malloc_hist_1);
3061 if (argv[1][0] == '/') {
3062 config_dir = stralloc(argv[1]);
3063 config_name = strrchr(config_dir, '/') + 1;
3064 config_name[-1] = '\0';
3065 config_dir = newstralloc2(config_dir, config_dir, "/");
3067 config_name = stralloc(argv[1]);
3068 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
3071 char my_cwd[STR_SIZE];
3073 if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
3074 error("cannot determine current working directory");
3076 config_dir = stralloc2(my_cwd, "/");
3077 if ((config_name = strrchr(my_cwd, '/')) != NULL) {
3078 config_name = stralloc(config_name + 1);
3082 conffile = stralloc2(config_dir, CONFFILE_NAME);
3083 result = read_conffile(conffile);
3085 diskfile = getconf_str(CNF_DISKFILE);
3086 if (diskfile != NULL && access(diskfile, R_OK) == 0) {
3087 result = (read_diskfile(diskfile) == NULL);
3090 dump_configuration(CONFFILE_NAME);
3093 malloc_size_2 = malloc_inuse(&malloc_hist_2);
3095 if(malloc_size_1 != malloc_size_2) {
3096 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);