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.127 2006/03/15 16:26:13 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 UNKNOWN, ANY, COMMA, LBRACE, RBRACE, NL, END,
60 IDENT, INT, LONG, AM64, BOOL, REAL, STRING, TIME,
62 /* config parameters */
64 ORG, MAILTO, DUMPUSER,
65 TAPECYCLE, TAPEDEV, CHNGRDEV, CHNGRFILE, LABELSTR,
66 BUMPPERCENT, BUMPSIZE, BUMPDAYS, BUMPMULT, ETIMEOUT, DTIMEOUT, CTIMEOUT,
67 TAPEBUFS, TAPELIST, DISKFILE, INFOFILE, LOGDIR, LOGFILE,
68 DISKDIR, DISKSIZE, INDEXDIR, NETUSAGE, INPARALLEL, DUMPORDER, TIMEOUT,
70 DEFINE, DUMPTYPE, TAPETYPE, INTERFACE,
71 PRINTER, AUTOFLUSH, RESERVE, MAXDUMPSIZE,
73 AMRECOVER_DO_FSF, AMRECOVER_CHECK_LABEL, AMRECOVER_CHANGER,
76 TAPERALGO, FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST, LAST,
80 KRB5KEYTAB, KRB5PRINCIPAL,
83 COMMENT, DIRECTORY, USE, CHUNKSIZE,
86 /*COMMENT,*/ PROGRAM, DUMPCYCLE, RUNSPERCYCLE, MAXCYCLE, MAXDUMPS,
87 OPTIONS, PRIORITY, FREQUENCY, INDEX, MAXPROMOTEDAY,
88 STARTTIME, COMPRESS, ENCRYPT, AUTH, STRATEGY, ESTIMATE,
89 SKIP_INCR, SKIP_FULL, RECORD, HOLDING,
90 EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE, TAPE_SPLITSIZE,
91 SPLIT_DISKBUFFER, FALLBACK_SPLITSIZE, SRVCOMPPROG, CLNTCOMPPROG,
92 SRV_ENCRYPT, CLNT_ENCRYPT, SRV_DECRYPT_OPT, CLNT_DECRYPT_OPT,
95 /*COMMENT,*/ BLOCKSIZE, FILE_PAD, LBL_TEMPL, FILEMARK, LENGTH, SPEED,
97 /* network interface */
100 /* dump options (obsolete) */
101 EXCLUDE_FILE, EXCLUDE_LIST,
103 /* compress, estimate, encryption */
104 NONE, FAST, BEST, SERVER, CLIENT, CALCSIZE, CUSTOM,
110 SKIP, STANDARD, NOFULL, NOINC, HANOI, INCRONLY,
113 LIST, EFILE, APPEND, OPTIONAL,
116 INFINITY, MULT1, MULT7, MULT1K, MULT1M, MULT1G,
124 typedef struct { /* token table entry */
139 /* this corresponds to the normal output of amanda, but may
140 * be adapted to any spacing as you like.
142 ColumnInfo ColumnData[] = {
143 { "HostName", 0, 12, 12, 0, "%-*.*s", "HOSTNAME" },
144 { "Disk", 1, 11, 11, 0, "%-*.*s", "DISK" },
145 { "Level", 1, 1, 1, 0, "%*.*d", "L" },
146 { "OrigKB", 1, 7, 0, 0, "%*.*f", "ORIG-KB" },
147 { "OutKB", 1, 7, 0, 0, "%*.*f", "OUT-KB" },
148 { "Compress", 1, 6, 1, 0, "%*.*f", "COMP%" },
149 { "DumpTime", 1, 7, 7, 0, "%*.*s", "MMM:SS" },
150 { "DumpRate", 1, 6, 1, 0, "%*.*f", "KB/s" },
151 { "TapeTime", 1, 6, 6, 0, "%*.*s", "MMM:SS" },
152 { "TapeRate", 1, 6, 1, 0, "%*.*f", "KB/s" },
153 { NULL, 0, 0, 0, 0, NULL, NULL }
156 char *config_name = NULL;
157 char *config_dir = NULL;
159 /* visible holding disk variables */
161 holdingdisk_t *holdingdisks;
162 int num_holdingdisks;
164 long int unit_divisor = 1;
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_bumppercent;
202 static val_t conf_bumpsize;
203 static val_t conf_bumpdays;
204 static val_t conf_etimeout;
205 static val_t conf_dtimeout;
206 static val_t conf_ctimeout;
207 static val_t conf_tapebufs;
208 static val_t conf_autoflush;
209 static val_t conf_reserve;
210 static val_t conf_maxdumpsize;
211 static val_t conf_amrecover_do_fsf;
212 static val_t conf_amrecover_check_label;
213 static val_t conf_taperalgo;
214 static val_t conf_displayunit;
215 static val_t conf_krb5keytab;
216 static val_t conf_krb5principal;
217 static val_t conf_label_new_tapes;
220 static val_t conf_bumpmult;
222 /* other internal variables */
223 static holdingdisk_t hdcur;
225 static tapetype_t tpcur;
227 static dumptype_t dpcur;
229 static interface_t ifcur;
232 static int seen_mailto;
233 static int seen_dumpuser;
234 static int seen_rawtapedev;
235 static int seen_printer;
236 static int seen_tapedev;
237 static int seen_tpchanger;
238 static int seen_chngrdev;
239 static int seen_chngrfile;
240 static int seen_labelstr;
241 static int seen_runtapes;
242 static int seen_maxdumps;
243 static int seen_tapelist;
244 static int seen_infofile;
245 static int seen_diskfile;
246 static int seen_diskdir;
247 static int seen_logdir;
248 static int seen_bumppercent;
249 static int seen_bumpsize;
250 static int seen_bumpmult;
251 static int seen_bumpdays;
252 static int seen_tapetype;
253 static int seen_dumpcycle;
254 static int seen_runspercycle;
255 static int seen_maxcycle;
256 static int seen_tapecycle;
257 static int seen_disksize;
258 static int seen_netusage;
259 static int seen_inparallel;
260 static int seen_dumporder;
261 static int seen_timeout;
262 static int seen_indexdir;
263 static int seen_etimeout;
264 static int seen_dtimeout;
265 static int seen_ctimeout;
266 static int seen_tapebufs;
267 static int seen_autoflush;
268 static int seen_reserve;
269 static int seen_maxdumpsize;
270 static int seen_columnspec;
271 static int seen_amrecover_do_fsf;
272 static int seen_amrecover_check_label;
273 static int seen_amrecover_changer;
274 static int seen_taperalgo;
275 static int seen_displayunit;
276 static int seen_krb5keytab;
277 static int seen_krb5principal;
278 static int seen_label_new_tapes;
280 static int allow_overwrites;
281 static int token_pushed;
283 static tok_t tok, pushed_tok;
284 static val_t tokenval;
286 static int line_num, got_parserror;
287 static dumptype_t *dumplist = NULL;
288 static tapetype_t *tapelist = NULL;
289 static interface_t *interface_list = NULL;
290 static FILE *conf = (FILE *)NULL;
291 static char *confname = NULL;
293 /* predeclare local functions */
295 static void init_defaults P((void));
296 static void read_conffile_recursively P((char *filename));
298 static int read_confline P((void));
299 static void get_holdingdisk P((void));
300 static void init_holdingdisk_defaults P((void));
301 static void save_holdingdisk P((void));
302 static void get_dumptype P((void));
303 static void init_dumptype_defaults P((void));
304 static void save_dumptype P((void));
305 static void copy_dumptype P((void));
306 static void get_tapetype P((void));
307 static void init_tapetype_defaults P((void));
308 static void save_tapetype P((void));
309 static void copy_tapetype P((void));
310 static void get_interface P((void));
311 static void init_interface_defaults P((void));
312 static void save_interface P((void));
313 static void copy_interface P((void));
314 static void get_dumpopts P((void));
315 static void get_comprate P((void));
316 static void get_compress P((void));
317 static void get_encrypt P((void));
318 static void get_priority P((void));
319 static void get_strategy P((void));
320 static void get_estimate P((void));
321 static void get_exclude P((void));
322 static void get_include P((void));
323 static void get_taperalgo P((val_t *c_taperalgo, int *s_taperalgo));
325 static void get_simple P((val_t *var, int *seen, tok_t type));
326 static int get_time P((void));
327 static int get_int P((void));
328 static long get_long P((void));
329 static am64_t get_am64_t P((void));
330 static int get_bool P((void));
331 static void ckseen P((int *seen));
332 static void parserror P((char *format, ...))
333 __attribute__ ((format (printf, 1, 2)));
334 static tok_t lookup_keyword P((char *str));
335 static void unget_conftoken P((void));
336 static void get_conftoken P((tok_t exp));
339 ** ------------------------
340 ** External entry points
341 ** ------------------------
344 int read_conffile(filename)
351 /* We assume that confname & conf are initialized to NULL above */
352 read_conffile_recursively(filename);
354 if(got_parserror != -1 ) {
355 if(lookup_tapetype(conf_tapetype.s) == NULL) {
356 char *save_confname = confname;
360 parserror("default tapetype %s not defined", conf_tapetype.s);
362 line_num = seen_tapetype;
363 parserror("tapetype %s not defined", conf_tapetype.s);
365 confname = save_confname;
369 ip = alloc(sizeof(interface_t));
372 ip->seen = seen_netusage;
373 ip->comment = "implicit from NETUSAGE";
374 ip->maxusage = conf_netusage.i;
376 ip->next = interface_list;
379 return got_parserror;
386 } byname_table [] = {
387 { "ORG", CNF_ORG, STRING },
388 { "MAILTO", CNF_MAILTO, STRING },
389 { "DUMPUSER", CNF_DUMPUSER, STRING },
390 { "PRINTER", CNF_PRINTER, STRING },
391 { "TAPEDEV", CNF_TAPEDEV, STRING },
392 { "TPCHANGER", CNF_TPCHANGER, STRING },
393 { "CHANGERDEV", CNF_CHNGRDEV, STRING },
394 { "CHANGERFILE", CNF_CHNGRFILE, STRING },
395 { "LABELSTR", CNF_LABELSTR, STRING },
396 { "TAPELIST", CNF_TAPELIST, STRING },
397 { "DISKFILE", CNF_DISKFILE, STRING },
398 { "INFOFILE", CNF_INFOFILE, STRING },
399 { "LOGDIR", CNF_LOGDIR, STRING },
400 /*{ "LOGFILE", CNF_LOGFILE, STRING },*/
401 /*{ "DISKDIR", CNF_DISKDIR, STRING },*/
402 { "INDEXDIR", CNF_INDEXDIR, STRING },
403 { "TAPETYPE", CNF_TAPETYPE, STRING },
404 { "DUMPCYCLE", CNF_DUMPCYCLE, INT },
405 { "RUNSPERCYCLE", CNF_RUNSPERCYCLE, INT },
406 { "MINCYCLE", CNF_DUMPCYCLE, INT },
407 { "RUNTAPES", CNF_RUNTAPES, INT },
408 { "TAPECYCLE", CNF_TAPECYCLE, INT },
409 /*{ "DISKSIZE", CNF_DISKSIZE, INT },*/
410 { "BUMPDAYS", CNF_BUMPDAYS, INT },
411 { "BUMPSIZE", CNF_BUMPSIZE, INT },
412 { "BUMPPERCENT", CNF_BUMPPERCENT, INT },
413 { "BUMPMULT", CNF_BUMPMULT, REAL },
414 { "NETUSAGE", CNF_NETUSAGE, INT },
415 { "INPARALLEL", CNF_INPARALLEL, INT },
416 { "DUMPORDER", CNF_DUMPORDER, STRING },
417 /*{ "TIMEOUT", CNF_TIMEOUT, INT },*/
418 { "MAXDUMPS", CNF_MAXDUMPS, INT },
419 { "ETIMEOUT", CNF_ETIMEOUT, INT },
420 { "DTIMEOUT", CNF_DTIMEOUT, INT },
421 { "CTIMEOUT", CNF_CTIMEOUT, INT },
422 { "TAPEBUFS", CNF_TAPEBUFS, INT },
423 { "RAWTAPEDEV", CNF_RAWTAPEDEV, STRING },
424 { "COLUMNSPEC", CNF_COLUMNSPEC, STRING },
425 { "AMRECOVER_DO_FSF", CNF_AMRECOVER_DO_FSF, BOOL },
426 { "AMRECOVER_CHECK_LABEL", CNF_AMRECOVER_CHECK_LABEL, BOOL },
427 { "AMRECOVER_CHANGER", CNF_AMRECOVER_CHANGER, STRING },
428 { "TAPERALGO", CNF_TAPERALGO, INT },
429 { "DISPLAYUNIT", CNF_DISPLAYUNIT, STRING },
430 { "AUTOFLUSH", CNF_AUTOFLUSH, BOOL },
431 { "RESERVE", CNF_RESERVE, INT },
432 { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, AM64 },
433 { "KRB5KEYTAB", CNF_KRB5KEYTAB, STRING },
434 { "KRB5PRINCIPAL", CNF_KRB5PRINCIPAL, STRING },
435 { "LABEL_NEW_TAPES", CNF_LABEL_NEW_TAPES, STRING },
439 char *getconf_byname(str)
443 char number[NUM_STR_SIZE];
448 tmpstr = stralloc(str);
450 while((ch = *s++) != '\0') {
451 if(islower((int)ch)) s[-1] = toupper(ch);
454 for(np = byname_table; np->name != NULL; np++)
455 if(strcmp(np->name, tmpstr) == 0) break;
457 if(np->name == NULL) return NULL;
460 snprintf(number, sizeof(number), "%d", getconf_int(np->parm));
461 tmpstr = newstralloc(tmpstr, number);
462 } else if(np->typ == BOOL) {
463 if(getconf_int(np->parm) == 0) {
464 tmpstr = newstralloc(tmpstr, "off");
467 tmpstr = newstralloc(tmpstr, "on");
469 } else if(np->typ == REAL) {
470 snprintf(number, sizeof(number), "%f", getconf_real(np->parm));
471 tmpstr = newstralloc(tmpstr, number);
473 tmpstr = newstralloc(tmpstr, getconf_str(np->parm));
479 int getconf_seen(parm)
483 case CNF_ORG: return seen_org;
484 case CNF_MAILTO: return seen_mailto;
485 case CNF_DUMPUSER: return seen_dumpuser;
486 case CNF_PRINTER: return seen_printer;
487 case CNF_TAPEDEV: return seen_tapedev;
488 case CNF_TPCHANGER: return seen_tpchanger;
489 case CNF_CHNGRDEV: return seen_chngrdev;
490 case CNF_CHNGRFILE: return seen_chngrfile;
491 case CNF_LABELSTR: return seen_labelstr;
492 case CNF_RUNTAPES: return seen_runtapes;
493 case CNF_MAXDUMPS: return seen_maxdumps;
494 case CNF_TAPELIST: return seen_tapelist;
495 case CNF_INFOFILE: return seen_infofile;
496 case CNF_DISKFILE: return seen_diskfile;
497 /*case CNF_DISKDIR: return seen_diskdir;*/
498 case CNF_LOGDIR: return seen_logdir;
499 /*case CNF_LOGFILE: return seen_logfile;*/
500 case CNF_BUMPPERCENT: return seen_bumppercent;
501 case CNF_BUMPSIZE: return seen_bumpsize;
502 case CNF_BUMPMULT: return seen_bumpmult;
503 case CNF_BUMPDAYS: return seen_bumpdays;
504 case CNF_TAPETYPE: return seen_tapetype;
505 case CNF_DUMPCYCLE: return seen_dumpcycle;
506 case CNF_RUNSPERCYCLE: return seen_runspercycle;
507 /*case CNF_MAXCYCLE: return seen_maxcycle;*/
508 case CNF_TAPECYCLE: return seen_tapecycle;
509 /*case CNF_DISKSIZE: return seen_disksize;*/
510 case CNF_NETUSAGE: return seen_netusage;
511 case CNF_INPARALLEL: return seen_inparallel;
512 case CNF_DUMPORDER: return seen_dumporder;
513 /*case CNF_TIMEOUT: return seen_timeout;*/
514 case CNF_INDEXDIR: return seen_indexdir;
515 case CNF_ETIMEOUT: return seen_etimeout;
516 case CNF_DTIMEOUT: return seen_dtimeout;
517 case CNF_CTIMEOUT: return seen_ctimeout;
518 case CNF_TAPEBUFS: return seen_tapebufs;
519 case CNF_RAWTAPEDEV: return seen_rawtapedev;
520 case CNF_AUTOFLUSH: return seen_autoflush;
521 case CNF_RESERVE: return seen_reserve;
522 case CNF_MAXDUMPSIZE: return seen_maxdumpsize;
523 case CNF_AMRECOVER_DO_FSF: return seen_amrecover_do_fsf;
524 case CNF_AMRECOVER_CHECK_LABEL: return seen_amrecover_check_label;
525 case CNF_AMRECOVER_CHANGER: return seen_amrecover_changer;
526 case CNF_TAPERALGO: return seen_taperalgo;
527 case CNF_DISPLAYUNIT: return seen_displayunit;
528 case CNF_KRB5KEYTAB: return seen_krb5keytab;
529 case CNF_KRB5PRINCIPAL: return seen_krb5principal;
530 case CNF_LABEL_NEW_TAPES: return seen_label_new_tapes;
535 int getconf_int(parm)
542 case CNF_DUMPCYCLE: r = conf_dumpcycle.i; break;
543 case CNF_RUNSPERCYCLE: r = conf_runspercycle.i; break;
544 case CNF_TAPECYCLE: r = conf_tapecycle.i; break;
545 case CNF_RUNTAPES: r = conf_runtapes.i; break;
546 /*case CNF_DISKSIZE: r = conf_disksize.i; break;*/
547 case CNF_BUMPPERCENT: r = conf_bumppercent.i; break;
548 case CNF_BUMPSIZE: r = conf_bumpsize.i; break;
549 case CNF_BUMPDAYS: r = conf_bumpdays.i; break;
550 case CNF_NETUSAGE: r = conf_netusage.i; break;
551 case CNF_INPARALLEL: r = conf_inparallel.i; break;
552 /*case CNF_TIMEOUT: r = conf_timeout.i; break;*/
553 case CNF_MAXDUMPS: r = conf_maxdumps.i; break;
554 case CNF_ETIMEOUT: r = conf_etimeout.i; break;
555 case CNF_DTIMEOUT: r = conf_dtimeout.i; break;
556 case CNF_CTIMEOUT: r = conf_ctimeout.i; break;
557 case CNF_TAPEBUFS: r = conf_tapebufs.i; break;
558 case CNF_AUTOFLUSH: r = conf_autoflush.i; break;
559 case CNF_RESERVE: r = conf_reserve.i; break;
560 case CNF_AMRECOVER_DO_FSF: r = conf_amrecover_do_fsf.i; break;
561 case CNF_AMRECOVER_CHECK_LABEL: r = conf_amrecover_check_label.i; break;
562 case CNF_TAPERALGO: r = conf_taperalgo.i; break;
565 error("error [unknown getconf_int parm: %d]", parm);
571 am64_t getconf_am64(parm)
577 case CNF_MAXDUMPSIZE: r = conf_maxdumpsize.am64; break;
580 error("error [unknown getconf_am64 parm: %d]", parm);
586 double getconf_real(parm)
593 case CNF_BUMPMULT: r = conf_bumpmult.r; break;
596 error("error [unknown getconf_real parm: %d]", parm);
602 char *getconf_str(parm)
609 case CNF_ORG: r = conf_org.s; break;
610 case CNF_MAILTO: r = conf_mailto.s; break;
611 case CNF_DUMPUSER: r = conf_dumpuser.s; break;
612 case CNF_PRINTER: r = conf_printer.s; break;
613 case CNF_TAPEDEV: r = conf_tapedev.s; break;
614 case CNF_TPCHANGER: r = conf_tpchanger.s; break;
615 case CNF_CHNGRDEV: r = conf_chngrdev.s; break;
616 case CNF_CHNGRFILE: r = conf_chngrfile.s; break;
617 case CNF_LABELSTR: r = conf_labelstr.s; break;
618 case CNF_TAPELIST: r = conf_tapelist.s; break;
619 case CNF_INFOFILE: r = conf_infofile.s; break;
620 case CNF_DUMPORDER: r = conf_dumporder.s; break;
621 case CNF_LOGDIR: r = conf_logdir.s; break;
622 /*case CNF_LOGFILE: r = conf_logfile.s; break;*/
623 case CNF_DISKFILE: r = conf_diskfile.s; break;
624 /*case CNF_DISKDIR: r = conf_diskdir.s; break;*/
625 case CNF_TAPETYPE: r = conf_tapetype.s; break;
626 case CNF_INDEXDIR: r = conf_indexdir.s; break;
627 case CNF_RAWTAPEDEV: r = conf_rawtapedev.s; break;
628 case CNF_COLUMNSPEC: r = conf_columnspec.s; break;
629 case CNF_AMRECOVER_CHANGER: r = conf_amrecover_changer.s; break;
630 case CNF_DISPLAYUNIT: r = conf_displayunit.s; break;
631 case CNF_KRB5PRINCIPAL: r = conf_krb5principal.s; break;
632 case CNF_KRB5KEYTAB: r = conf_krb5keytab.s; break;
633 case CNF_LABEL_NEW_TAPES: r = conf_label_new_tapes.s; break;
636 error("error [unknown getconf_str parm: %d]", parm);
642 holdingdisk_t *getconf_holdingdisks()
647 dumptype_t *lookup_dumptype(str)
652 for(p = dumplist; p != NULL; p = p->next) {
653 if(strcmp(p->name, str) == 0) return p;
658 tapetype_t *lookup_tapetype(str)
663 for(p = tapelist; p != NULL; p = p->next) {
664 if(strcmp(p->name, str) == 0) return p;
669 interface_t *lookup_interface(str)
674 if(str == NULL) return interface_list;
675 for(p = interface_list; p != NULL; p = p->next) {
676 if(strcmp(p->name, str) == 0) return p;
683 ** ------------------------
685 ** ------------------------
689 static void init_defaults()
693 /* defaults for exported variables */
695 #ifdef DEFAULT_CONFIG
700 conf_org.s = stralloc(s);
701 malloc_mark(conf_org.s);
702 conf_mailto.s = stralloc("operators");
703 malloc_mark(conf_mailto.s);
704 conf_dumpuser.s = stralloc(CLIENT_LOGIN);
705 malloc_mark(conf_dumpuser.s);
706 #ifdef DEFAULT_TAPE_DEVICE
707 s = DEFAULT_TAPE_DEVICE;
711 conf_tapedev.s = stralloc(s);
712 malloc_mark(conf_tapedev.s);
713 #ifdef DEFAULT_RAW_TAPE_DEVICE
714 s = DEFAULT_RAW_TAPE_DEVICE;
718 conf_rawtapedev.s = stralloc(s);
719 malloc_mark(conf_rawtapedev.s);
720 conf_tpchanger.s = stralloc("");
721 malloc_mark(conf_tpchanger.s);
722 #ifdef DEFAULT_CHANGER_DEVICE
723 s = DEFAULT_CHANGER_DEVICE;
727 conf_chngrdev.s = stralloc(s);
728 malloc_mark(conf_chngrdev.s);
729 conf_chngrfile.s = stralloc("/usr/adm/amanda/changer-status");
730 malloc_mark(conf_chngrfile.s);
731 conf_labelstr.s = stralloc(".*");
732 malloc_mark(conf_labelstr.s);
733 conf_tapelist.s = stralloc("tapelist");
734 malloc_mark(conf_tapelist.s);
735 conf_infofile.s = stralloc("/usr/adm/amanda/curinfo");
736 malloc_mark(conf_infofile.s);
737 conf_logdir.s = stralloc("/usr/adm/amanda");
738 malloc_mark(conf_logdir.s);
739 conf_diskfile.s = stralloc("disklist");
740 malloc_mark(conf_diskfile.s);
741 conf_diskdir.s = stralloc("/dumps/amanda");
742 malloc_mark(conf_diskdir.s);
743 conf_tapetype.s = stralloc("EXABYTE");
744 malloc_mark(conf_tapetype.s);
745 conf_indexdir.s = stralloc("/usr/adm/amanda/index");
746 malloc_mark(conf_indexdir.s);
747 conf_columnspec.s = stralloc("");
748 malloc_mark(conf_columnspec.s);
749 conf_dumporder.s = stralloc("ttt");
750 malloc_mark(conf_dumporder.s);
751 conf_amrecover_changer.s = stralloc("");
752 conf_printer.s = stralloc("");
753 conf_displayunit.s = stralloc("k");
754 conf_label_new_tapes.s = stralloc("");
756 conf_krb5keytab.s = stralloc("/.amanda-v5-keytab");
757 conf_krb5principal.s = stralloc("service/amanda");
759 conf_dumpcycle.i = 10;
760 conf_runspercycle.i = 0;
761 conf_tapecycle.i = 15;
764 conf_netusage.i = 300;
765 conf_inparallel.i = 10;
768 conf_bumppercent.i = 0;
769 conf_bumpsize.i = 10*1024;
771 conf_bumpmult.r = 1.5;
772 conf_etimeout.i = 300;
773 conf_dtimeout.i = 1800;
774 conf_ctimeout.i = 30;
775 conf_tapebufs.i = 20;
776 conf_autoflush.i = 0;
777 conf_reserve.i = 100;
778 conf_maxdumpsize.am64 = -1;
779 conf_amrecover_do_fsf.i = 1;
780 conf_amrecover_check_label.i = 1;
781 conf_taperalgo.i = 0;
783 /* defaults for internal variables */
802 seen_bumppercent = 0;
808 seen_runspercycle = 0;
823 seen_maxdumpsize = 0;
825 seen_amrecover_do_fsf = 0;
826 seen_amrecover_check_label = 0;
827 seen_amrecover_changer = 0;
829 seen_displayunit = 0;
831 seen_krb5principal = 0;
832 seen_label_new_tapes = 0;
834 line_num = got_parserror = 0;
835 allow_overwrites = 0;
838 while(holdingdisks != NULL) {
842 holdingdisks = holdingdisks->next;
845 num_holdingdisks = 0;
847 /* free any previously declared dump, tape and interface types */
849 while(dumplist != NULL) {
853 dumplist = dumplist->next;
856 while(tapelist != NULL) {
860 tapelist = tapelist->next;
863 while(interface_list != NULL) {
867 interface_list = interface_list->next;
871 /* create some predefined dumptypes for backwards compatability */
872 init_dumptype_defaults();
873 dpcur.name = "NO-COMPRESS"; dpcur.seen = -1;
874 dpcur.compress = COMP_NONE; dpcur.s_compress = -1;
877 init_dumptype_defaults();
878 dpcur.name = "COMPRESS-FAST"; dpcur.seen = -1;
879 dpcur.compress = COMP_FAST; dpcur.s_compress = -1;
882 init_dumptype_defaults();
883 dpcur.name = "COMPRESS-BEST"; dpcur.seen = -1;
884 dpcur.compress = COMP_BEST; dpcur.s_compress = -1;
887 init_dumptype_defaults();
888 dpcur.name = "COMPRESS-CUST"; dpcur.seen = -1;
889 dpcur.compress = COMP_CUST; dpcur.s_compress = -1;
892 init_dumptype_defaults();
893 dpcur.name = "SRVCOMPRESS"; dpcur.seen = -1;
894 dpcur.compress = COMP_SERV_FAST; dpcur.s_compress = -1;
897 init_dumptype_defaults();
898 dpcur.name = "BSD-AUTH"; dpcur.seen = -1;
899 amfree(dpcur.security_driver);
900 dpcur.security_driver = stralloc("BSD"); dpcur.s_security_driver = -1;
903 init_dumptype_defaults();
904 dpcur.name = "KRB4-AUTH"; dpcur.seen = -1;
905 amfree(dpcur.security_driver);
906 dpcur.security_driver = stralloc("KRB4"); dpcur.s_security_driver = -1;
909 init_dumptype_defaults();
910 dpcur.name = "NO-RECORD"; dpcur.seen = -1;
911 dpcur.record = 0; dpcur.s_record = -1;
914 init_dumptype_defaults();
915 dpcur.name = "NO-HOLD"; dpcur.seen = -1;
916 dpcur.no_hold = 1; dpcur.s_no_hold = -1;
919 init_dumptype_defaults();
920 dpcur.name = "NO-FULL"; dpcur.seen = -1;
921 dpcur.strategy = DS_NOFULL; dpcur.s_strategy = -1;
925 static void read_conffile_recursively(filename)
930 /* Save globals used in read_confline(), elsewhere. */
931 int save_line_num = line_num;
932 FILE *save_conf = conf;
933 char *save_confname = confname;
935 if (*filename == '/' || config_dir == NULL) {
936 confname = stralloc(filename);
938 confname = stralloc2(config_dir, filename);
941 if((conf = fopen(confname, "r")) == NULL) {
942 fprintf(stderr, "could not open conf file \"%s\": %s\n", confname,
951 /* read_confline() can invoke us recursively via "includefile" */
952 while(read_confline());
957 /* Restore globals */
958 line_num = save_line_num;
960 confname = save_confname;
964 /* ------------------------ */
967 keytab_t main_keytable[] = {
968 { "BUMPDAYS", BUMPDAYS },
969 { "BUMPMULT", BUMPMULT },
970 { "BUMPSIZE", BUMPSIZE },
971 { "BUMPPERCENT", BUMPPERCENT },
972 { "DEFINE", DEFINE },
973 { "DISKDIR", DISKDIR }, /* XXX - historical */
974 { "DISKFILE", DISKFILE },
975 { "DISKSIZE", DISKSIZE }, /* XXX - historical */
976 { "DUMPCYCLE", DUMPCYCLE },
977 { "RUNSPERCYCLE", RUNSPERCYCLE },
978 { "DUMPTYPE", DUMPTYPE },
979 { "DUMPUSER", DUMPUSER },
980 { "PRINTER", PRINTER },
981 { "HOLDINGDISK", HOLDING },
982 { "INCLUDEFILE", INCLUDEFILE },
983 { "INDEXDIR", INDEXDIR },
984 { "INFOFILE", INFOFILE },
985 { "INPARALLEL", INPARALLEL },
986 { "DUMPORDER", DUMPORDER },
987 { "INTERFACE", INTERFACE },
988 { "LABELSTR", LABELSTR },
989 { "LOGDIR", LOGDIR },
990 { "LOGFILE", LOGFILE }, /* XXX - historical */
991 { "MAILTO", MAILTO },
992 { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */
993 { "MAXDUMPS", MAXDUMPS },
994 { "MINCYCLE", DUMPCYCLE }, /* XXX - historical */
995 { "NETUSAGE", NETUSAGE }, /* XXX - historical */
997 { "RUNTAPES", RUNTAPES },
998 { "TAPECYCLE", TAPECYCLE },
999 { "TAPEDEV", TAPEDEV },
1000 { "TAPELIST", TAPELIST },
1001 { "TAPETYPE", TAPETYPE },
1002 { "TIMEOUT", TIMEOUT }, /* XXX - historical */
1003 { "TPCHANGER", TPCHANGER },
1004 { "CHANGERDEV", CHNGRDEV },
1005 { "CHANGERFILE", CHNGRFILE },
1006 { "ETIMEOUT", ETIMEOUT },
1007 { "DTIMEOUT", DTIMEOUT },
1008 { "CTIMEOUT", CTIMEOUT },
1009 { "TAPEBUFS", TAPEBUFS },
1010 { "RAWTAPEDEV", RAWTAPEDEV },
1011 { "AUTOFLUSH", AUTOFLUSH },
1012 { "RESERVE", RESERVE },
1013 { "MAXDUMPSIZE", MAXDUMPSIZE },
1014 { "COLUMNSPEC", COLUMNSPEC },
1015 { "AMRECOVER_DO_FSF", AMRECOVER_DO_FSF },
1016 { "AMRECOVER_CHECK_LABEL", AMRECOVER_CHECK_LABEL },
1017 { "AMRECOVER_CHANGER", AMRECOVER_CHANGER },
1018 { "TAPERALGO", TAPERALGO },
1019 { "DISPLAYUNIT", DISPLAYUNIT },
1020 { "KRB5KEYTAB", KRB5KEYTAB },
1021 { "KRB5PRINCIPAL", KRB5PRINCIPAL },
1022 { "LABEL_NEW_TAPES", LABEL_NEW_TAPES },
1026 static int read_confline()
1028 keytable = main_keytable;
1037 get_conftoken(STRING);
1039 read_conffile_recursively(fn);
1043 case ORG: get_simple(&conf_org, &seen_org, STRING); break;
1044 case MAILTO: get_simple(&conf_mailto, &seen_mailto, STRING); break;
1045 case DUMPUSER: get_simple(&conf_dumpuser, &seen_dumpuser, STRING); break;
1046 case PRINTER: get_simple(&conf_printer, &seen_printer, STRING); break;
1047 case DUMPCYCLE: get_simple(&conf_dumpcycle, &seen_dumpcycle, INT);
1048 if(conf_dumpcycle.i < 0) {
1049 parserror("dumpcycle must be positive");
1052 case RUNSPERCYCLE: get_simple(&conf_runspercycle, &seen_runspercycle, INT);
1053 if(conf_runspercycle.i < -1) {
1054 parserror("runspercycle must be >= -1");
1057 case MAXCYCLE: get_simple(&conf_maxcycle, &seen_maxcycle, INT); break;
1058 case TAPECYCLE: get_simple(&conf_tapecycle, &seen_tapecycle, INT);
1059 if(conf_tapecycle.i < 1) {
1060 parserror("tapecycle must be positive");
1063 case RUNTAPES: get_simple(&conf_runtapes, &seen_runtapes, INT);
1064 if(conf_runtapes.i < 0) {
1065 parserror("runtapes must be positive");
1068 case TAPEDEV: get_simple(&conf_tapedev, &seen_tapedev, STRING); break;
1069 case RAWTAPEDEV:get_simple(&conf_rawtapedev,&seen_rawtapedev,STRING); break;
1070 case TPCHANGER: get_simple(&conf_tpchanger, &seen_tpchanger, STRING); break;
1071 case CHNGRDEV: get_simple(&conf_chngrdev, &seen_chngrdev, STRING); break;
1072 case CHNGRFILE: get_simple(&conf_chngrfile, &seen_chngrfile, STRING); break;
1073 case LABELSTR: get_simple(&conf_labelstr, &seen_labelstr, STRING); break;
1074 case TAPELIST: get_simple(&conf_tapelist, &seen_tapelist, STRING); break;
1075 case INFOFILE: get_simple(&conf_infofile, &seen_infofile, STRING); break;
1076 case LOGDIR: get_simple(&conf_logdir, &seen_logdir, STRING); break;
1077 case DISKFILE: get_simple(&conf_diskfile, &seen_diskfile, STRING); break;
1078 case BUMPMULT: get_simple(&conf_bumpmult, &seen_bumpmult, REAL);
1079 if(conf_bumpmult.r < 0.999) {
1080 parserror("bumpmult must be positive");
1083 case BUMPPERCENT: get_simple(&conf_bumppercent, &seen_bumppercent, INT);
1084 if(conf_bumppercent.i < 0 || conf_bumppercent.i > 100) {
1085 parserror("bumppercent must be between 0 and 100");
1088 case BUMPSIZE: get_simple(&conf_bumpsize, &seen_bumpsize, INT);
1089 if(conf_bumpsize.i < 1) {
1090 parserror("bumpsize must be positive");
1093 case BUMPDAYS: get_simple(&conf_bumpdays, &seen_bumpdays, INT);
1094 if(conf_bumpdays.i < 1) {
1095 parserror("bumpdays must be positive");
1098 case NETUSAGE: get_simple(&conf_netusage, &seen_netusage, INT);
1099 if(conf_netusage.i < 1) {
1100 parserror("netusage must be positive");
1103 case INPARALLEL:get_simple(&conf_inparallel,&seen_inparallel,INT);
1104 if(conf_inparallel.i < 1 || conf_inparallel.i >MAX_DUMPERS){
1106 "inparallel must be between 1 and MAX_DUMPERS (%d)",
1110 case DUMPORDER: get_simple(&conf_dumporder, &seen_dumporder, STRING); break;
1111 case TIMEOUT: get_simple(&conf_timeout, &seen_timeout, INT); break;
1112 case MAXDUMPS: get_simple(&conf_maxdumps, &seen_maxdumps, INT);
1113 if(conf_maxdumps.i < 1) {
1114 parserror("maxdumps must be positive");
1117 case TAPETYPE: get_simple(&conf_tapetype, &seen_tapetype, IDENT); break;
1118 case INDEXDIR: get_simple(&conf_indexdir, &seen_indexdir, STRING); break;
1119 case ETIMEOUT: get_simple(&conf_etimeout, &seen_etimeout, INT); break;
1120 case DTIMEOUT: get_simple(&conf_dtimeout, &seen_dtimeout, INT);
1121 if(conf_dtimeout.i < 1) {
1122 parserror("dtimeout must be positive");
1125 case CTIMEOUT: get_simple(&conf_ctimeout, &seen_ctimeout, INT);
1126 if(conf_ctimeout.i < 1) {
1127 parserror("ctimeout must be positive");
1130 case TAPEBUFS: get_simple(&conf_tapebufs, &seen_tapebufs, INT);
1131 if(conf_tapebufs.i < 1) {
1132 parserror("tapebufs must be positive");
1135 case AUTOFLUSH: get_simple(&conf_autoflush, &seen_autoflush, BOOL); break;
1136 case RESERVE: get_simple(&conf_reserve, &seen_reserve, INT);
1137 if(conf_reserve.i < 0 || conf_reserve.i > 100) {
1138 parserror("reserve must be between 0 and 100");
1141 case MAXDUMPSIZE:get_simple(&conf_maxdumpsize,&seen_maxdumpsize,AM64); break;
1142 case COLUMNSPEC:get_simple(&conf_columnspec,&seen_columnspec,STRING); break;
1144 case AMRECOVER_DO_FSF: get_simple(&conf_amrecover_do_fsf,&seen_amrecover_do_fsf, BOOL); break;
1145 case AMRECOVER_CHECK_LABEL: get_simple(&conf_amrecover_check_label,&seen_amrecover_check_label, BOOL); break;
1146 case AMRECOVER_CHANGER: get_simple(&conf_amrecover_changer,&seen_amrecover_changer, STRING); break;
1148 case TAPERALGO: get_taperalgo(&conf_taperalgo,&seen_taperalgo); break;
1149 case DISPLAYUNIT: get_simple(&conf_displayunit,&seen_displayunit, STRING);
1150 if(strcmp(conf_displayunit.s,"k") == 0 ||
1151 strcmp(conf_displayunit.s,"K") == 0) {
1152 conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
1155 else if(strcmp(conf_displayunit.s,"m") == 0 ||
1156 strcmp(conf_displayunit.s,"M") == 0) {
1157 conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
1160 else if(strcmp(conf_displayunit.s,"g") == 0 ||
1161 strcmp(conf_displayunit.s,"G") == 0) {
1162 conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
1163 unit_divisor=1024*1024;
1165 else if(strcmp(conf_displayunit.s,"t") == 0 ||
1166 strcmp(conf_displayunit.s,"T") == 0) {
1167 conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
1168 unit_divisor=1024*1024*1024;
1171 parserror("displayunit must be k,m,g or t.");
1175 /* kerberos 5 bits. only useful when kerberos 5 built in... */
1176 case KRB5KEYTAB: get_simple(&conf_krb5keytab, &seen_krb5keytab, STRING); break;
1177 case KRB5PRINCIPAL: get_simple(&conf_krb5principal,&seen_krb5principal,STRING); break;
1179 case LOGFILE: /* XXX - historical */
1180 /* truncate the filename part and pretend he said "logdir" */
1184 get_simple(&conf_logdir, &seen_logdir, STRING);
1186 p = strrchr(conf_logdir.s, '/');
1187 if (p != (char *)0) *p = '\0';
1195 get_conftoken(STRING);
1199 conf_diskdir.s = newstralloc(conf_diskdir.s, s);
1200 seen_diskdir = line_num;
1203 init_holdingdisk_defaults();
1204 hdcur.name = "default from DISKDIR";
1205 hdcur.seen = line_num;
1206 hdcur.diskdir = stralloc(s);
1207 hdcur.s_disk = line_num;
1208 hdcur.disksize = conf_disksize.i;
1209 hdcur.s_size = seen_disksize;
1219 i = (i / DISK_BLOCK_KB) * DISK_BLOCK_KB;
1221 if(!seen_disksize) {
1222 conf_disksize.i = i;
1223 seen_disksize = line_num;
1226 if(holdingdisks != NULL)
1227 holdingdisks->disksize = i;
1238 if(tok == DUMPTYPE) get_dumptype();
1239 else if(tok == TAPETYPE) get_tapetype();
1240 else if(tok == INTERFACE) get_interface();
1241 else parserror("DUMPTYPE, INTERFACE or TAPETYPE expected");
1243 case LABEL_NEW_TAPES:
1244 get_simple(&conf_label_new_tapes, &seen_label_new_tapes, STRING);
1247 case NL: /* empty line */
1249 case END: /* end of file */
1252 parserror("configuration keyword expected");
1254 if(tok != NL) get_conftoken(NL);
1258 keytab_t holding_keytable[] = {
1259 { "DIRECTORY", DIRECTORY },
1260 { "COMMENT", COMMENT },
1262 { "CHUNKSIZE", CHUNKSIZE },
1266 static void get_holdingdisk()
1269 int save_overwrites;
1272 save_overwrites = allow_overwrites;
1273 allow_overwrites = 1;
1276 keytable = holding_keytable;
1278 init_holdingdisk_defaults();
1280 get_conftoken(IDENT);
1281 hdcur.name = stralloc(tokenval.s);
1282 malloc_mark(hdcur.name);
1283 hdcur.seen = line_num;
1285 get_conftoken(LBRACE);
1295 get_simple((val_t *)&hdcur.comment, &hdcur.s_comment, STRING);
1298 get_simple((val_t *)&hdcur.diskdir, &hdcur.s_disk, STRING);
1301 get_simple((val_t *)&hdcur.disksize, &hdcur.s_size, LONG);
1302 hdcur.disksize = am_floor(hdcur.disksize, DISK_BLOCK_KB);
1305 get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, LONG);
1306 if(hdcur.chunksize == 0) {
1307 hdcur.chunksize = ((INT_MAX / 1024) - (2 * DISK_BLOCK_KB));
1308 } else if(hdcur.chunksize < 0) {
1309 parserror("Negative chunksize (%ld) is no longer supported",
1312 hdcur.chunksize = am_floor(hdcur.chunksize, DISK_BLOCK_KB);
1317 case NL: /* empty line */
1319 case END: /* end of file */
1322 parserror("holding disk parameter expected");
1324 if(tok != NL && tok != END) get_conftoken(NL);
1329 allow_overwrites = save_overwrites;
1333 static void init_holdingdisk_defaults()
1335 hdcur.comment = stralloc("");
1336 hdcur.diskdir = stralloc(conf_diskdir.s);
1337 malloc_mark(hdcur.diskdir);
1339 hdcur.chunksize = 1024*1024/**1024*/; /* 1 Gb = 1M counted in 1Kb blocks */
1341 hdcur.s_comment = 0;
1346 hdcur.up = (void *)0;
1349 static void save_holdingdisk()
1353 hp = alloc(sizeof(holdingdisk_t));
1356 hp->next = holdingdisks;
1363 keytab_t dumptype_keytable[] = {
1365 { "BUMPDAYS", BUMPDAYS },
1366 { "BUMPMULT", BUMPMULT },
1367 { "BUMPSIZE", BUMPSIZE },
1368 { "BUMPPERCENT", BUMPPERCENT },
1369 { "COMMENT", COMMENT },
1370 { "COMPRATE", COMPRATE },
1371 { "COMPRESS", COMPRESS },
1372 { "ENCRYPT", ENCRYPT },
1373 { "SERVER_DECRYPT_OPTION", SRV_DECRYPT_OPT },
1374 { "CLIENT_DECRYPT_OPTION", CLNT_DECRYPT_OPT },
1375 { "DUMPCYCLE", DUMPCYCLE },
1376 { "EXCLUDE", EXCLUDE },
1377 { "FREQUENCY", FREQUENCY }, /* XXX - historical */
1378 { "HOLDINGDISK", HOLDING },
1379 { "IGNORE", IGNORE },
1380 { "INCLUDE", INCLUDE },
1382 { "KENCRYPT", KENCRYPT },
1383 { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */
1384 { "MAXDUMPS", MAXDUMPS },
1385 { "MAXPROMOTEDAY", MAXPROMOTEDAY },
1386 { "OPTIONS", OPTIONS }, /* XXX - historical */
1387 { "PRIORITY", PRIORITY },
1388 { "PROGRAM", PROGRAM },
1389 { "RECORD", RECORD },
1390 { "SKIP-FULL", SKIP_FULL },
1391 { "SKIP-INCR", SKIP_INCR },
1392 { "STARTTIME", STARTTIME },
1393 { "STRATEGY", STRATEGY },
1394 { "TAPE_SPLITSIZE", TAPE_SPLITSIZE },
1395 { "SPLIT_DISKBUFFER", SPLIT_DISKBUFFER },
1396 { "FALLBACK_SPLITSIZE", FALLBACK_SPLITSIZE },
1397 { "ESTIMATE", ESTIMATE },
1398 { "SERVER_CUSTOM_COMPRESS", SRVCOMPPROG },
1399 { "CLIENT_CUSTOM_COMPRESS", CLNTCOMPPROG },
1400 { "SERVER_ENCRYPT", SRV_ENCRYPT },
1401 { "CLIENT_ENCRYPT", CLNT_ENCRYPT },
1405 dumptype_t *read_dumptype(name, from, fname, linenum)
1412 int save_overwrites;
1415 FILE *saved_conf = NULL;
1416 char *saved_fname = NULL;
1424 saved_fname = confname;
1429 line_num = *linenum;
1431 save_overwrites = allow_overwrites;
1432 allow_overwrites = 1;
1435 keytable = dumptype_keytable;
1437 init_dumptype_defaults();
1442 get_conftoken(IDENT);
1443 dpcur.name = stralloc(tokenval.s);
1444 malloc_mark(dpcur.name);
1447 dpcur.seen = line_num;
1450 get_conftoken(LBRACE);
1461 get_simple((val_t *)&dpcur.security_driver,
1462 &dpcur.s_security_driver, STRING);
1465 get_simple((val_t *)&dpcur.comment, &dpcur.s_comment, STRING);
1476 case SRV_DECRYPT_OPT:
1477 get_simple((val_t *)&dpcur.srv_decrypt_opt, &dpcur.s_srv_decrypt_opt, STRING);
1479 case CLNT_DECRYPT_OPT:
1480 get_simple((val_t *)&dpcur.clnt_decrypt_opt, &dpcur.s_clnt_decrypt_opt, STRING);
1483 get_simple((val_t *)&dpcur.dumpcycle, &dpcur.s_dumpcycle, INT);
1484 if(dpcur.dumpcycle < 0) {
1485 parserror("dumpcycle must be positive");
1492 get_simple((val_t *)&dpcur.frequency, &dpcur.s_frequency, INT);
1495 get_simple(&tmpval, &dpcur.s_no_hold, BOOL);
1496 dpcur.no_hold = (tmpval.i == 0);
1499 get_simple(&tmpval, &dpcur.s_ignore, BOOL);
1500 dpcur.ignore = (tmpval.i != 0);
1506 get_simple(&tmpval, &dpcur.s_index, BOOL);
1507 dpcur.index = (tmpval.i != 0);
1510 get_simple(&tmpval, &dpcur.s_kencrypt, BOOL);
1511 dpcur.kencrypt = (tmpval.i != 0);
1514 get_simple((val_t *)&conf_maxcycle, &dpcur.s_maxcycle, INT);
1517 get_simple((val_t *)&dpcur.maxdumps, &dpcur.s_maxdumps, INT);
1518 if(dpcur.maxdumps < 1) {
1519 parserror("maxdumps must be positive");
1523 get_simple((val_t *)&dpcur.maxpromoteday, &dpcur.s_maxpromoteday, INT);
1524 if(dpcur.maxpromoteday < 0) {
1525 parserror("dpcur.maxpromoteday must be >= 0");
1529 get_simple((val_t *)&dpcur.bumppercent, &dpcur.s_bumppercent, INT);
1530 if(dpcur.bumppercent < 0 || dpcur.bumppercent > 100) {
1531 parserror("bumppercent must be between 0 and 100");
1535 get_simple((val_t *)&dpcur.bumpsize, &dpcur.s_bumpsize, INT);
1536 if(dpcur.bumpsize < 1) {
1537 parserror("bumpsize must be positive");
1541 get_simple((val_t *)&dpcur.bumpdays, &dpcur.s_bumpdays, INT);
1542 if(dpcur.bumpdays < 1) {
1543 parserror("bumpdays must be positive");
1547 get_simple((val_t *)&dpcur.bumpmult, &dpcur.s_bumpmult, REAL);
1548 if(dpcur.bumpmult < 0.999) {
1549 parserror("bumpmult must be positive (%f)",dpcur.bumpmult);
1559 get_simple((val_t *)&dpcur.program, &dpcur.s_program, STRING);
1562 get_simple(&tmpval, &dpcur.s_record, BOOL);
1563 dpcur.record = (tmpval.i != 0);
1566 get_simple(&tmpval, &dpcur.s_skip_full, BOOL);
1567 dpcur.skip_full = (tmpval.i != 0);
1570 get_simple(&tmpval, &dpcur.s_skip_incr, BOOL);
1571 dpcur.skip_incr = (tmpval.i != 0);
1574 get_simple((val_t *)&dpcur.start_t, &dpcur.s_start_t, TIME);
1585 case TAPE_SPLITSIZE:
1586 get_simple((val_t *)&dpcur.tape_splitsize, &dpcur.s_tape_splitsize, INT);
1587 if(dpcur.tape_splitsize < 0) {
1588 parserror("tape_splitsize must be >= 0");
1591 case SPLIT_DISKBUFFER:
1592 get_simple((val_t *)&dpcur.split_diskbuffer, &dpcur.s_split_diskbuffer, STRING);
1594 case FALLBACK_SPLITSIZE:
1595 get_simple((val_t *)&dpcur.fallback_splitsize, &dpcur.s_fallback_splitsize, INT);
1596 if(dpcur.fallback_splitsize < 0) {
1597 parserror("fallback_splitsize must be >= 0");
1601 get_simple((val_t *)&dpcur.srvcompprog, &dpcur.s_srvcompprog, STRING);
1604 get_simple((val_t *)&dpcur.clntcompprog, &dpcur.s_clntcompprog, STRING);
1607 get_simple((val_t *)&dpcur.srv_encrypt, &dpcur.s_srv_encrypt, STRING);
1610 get_simple((val_t *)&dpcur.clnt_encrypt, &dpcur.s_clnt_encrypt, STRING);
1615 case NL: /* empty line */
1617 case END: /* end of file */
1620 parserror("dump type parameter expected");
1622 if(tok != NL && tok != END &&
1623 /* When a name is specified, we shouldn't consume the NL
1624 after the RBRACE. */
1625 (tok != RBRACE || name == 0))
1629 /* XXX - there was a stupidity check in here for skip-incr and
1630 ** skip-full. This check should probably be somewhere else. */
1634 allow_overwrites = save_overwrites;
1638 *linenum = line_num;
1641 confname = saved_fname;
1646 return lookup_dumptype(dpcur.name);
1649 static void get_dumptype()
1651 read_dumptype(NULL, NULL, NULL, NULL);
1654 static void init_dumptype_defaults()
1656 dpcur.comment = stralloc("");
1657 dpcur.program = stralloc("DUMP");
1658 dpcur.srvcompprog = stralloc("");
1659 dpcur.clntcompprog = stralloc("");
1660 dpcur.srv_encrypt = stralloc("");
1661 dpcur.clnt_encrypt = stralloc("");
1662 dpcur.exclude_file = NULL;
1663 dpcur.exclude_list = NULL;
1664 dpcur.include_file = NULL;
1665 dpcur.include_list = NULL;
1667 dpcur.dumpcycle = conf_dumpcycle.i;
1668 dpcur.maxcycle = conf_maxcycle.i;
1669 dpcur.frequency = 1;
1670 dpcur.maxdumps = conf_maxdumps.i;
1671 dpcur.maxpromoteday = 10000;
1672 dpcur.bumppercent = conf_bumppercent.i;
1673 dpcur.bumpsize = conf_bumpsize.i;
1674 dpcur.bumpdays = conf_bumpdays.i;
1675 dpcur.bumpmult = conf_bumpmult.r;
1677 dpcur.security_driver = stralloc("BSD");
1681 dpcur.strategy = DS_STANDARD;
1682 dpcur.estimate = ES_CLIENT;
1683 dpcur.compress = COMP_FAST;
1684 dpcur.encrypt = ENCRYPT_NONE;
1685 dpcur.srv_decrypt_opt = stralloc("-d");
1686 dpcur.clnt_decrypt_opt = stralloc("-d");
1687 dpcur.comprate[0] = dpcur.comprate[1] = 0.50;
1688 dpcur.skip_incr = dpcur.skip_full = 0;
1693 dpcur.tape_splitsize = 0;
1694 dpcur.split_diskbuffer = NULL;
1695 dpcur.fallback_splitsize = 10 * 1024;
1697 dpcur.s_comment = 0;
1698 dpcur.s_program = 0;
1699 dpcur.s_srvcompprog = 0;
1700 dpcur.s_clntcompprog = 0;
1701 dpcur.s_clnt_encrypt= 0;
1702 dpcur.s_srv_encrypt= 0;
1704 dpcur.s_exclude_file = 0;
1705 dpcur.s_exclude_list = 0;
1706 dpcur.s_include_file = 0;
1707 dpcur.s_include_list = 0;
1708 dpcur.s_priority = 0;
1709 dpcur.s_dumpcycle = 0;
1710 dpcur.s_maxcycle = 0;
1711 dpcur.s_frequency = 0;
1712 dpcur.s_maxdumps = 0;
1713 dpcur.s_maxpromoteday = 0;
1714 dpcur.s_bumppercent = 0;
1715 dpcur.s_bumpsize = 0;
1716 dpcur.s_bumpdays = 0;
1717 dpcur.s_bumpmult = 0;
1718 dpcur.s_start_t = 0;
1719 dpcur.s_security_driver = 0;
1721 dpcur.s_strategy = 0;
1722 dpcur.s_estimate = 0;
1723 dpcur.s_compress = 0;
1724 dpcur.s_encrypt = 0;
1725 dpcur.s_srv_decrypt_opt = 0;
1726 dpcur.s_clnt_decrypt_opt = 0;
1727 dpcur.s_comprate = 0;
1728 dpcur.s_skip_incr = 0;
1729 dpcur.s_skip_full = 0;
1730 dpcur.s_no_hold = 0;
1731 dpcur.s_kencrypt = 0;
1734 dpcur.s_tape_splitsize = 0;
1735 dpcur.s_split_diskbuffer = 0;
1736 dpcur.s_fallback_splitsize = 0;
1739 static void save_dumptype()
1743 dp = lookup_dumptype(dpcur.name);
1745 if(dp != (dumptype_t *)0) {
1746 parserror("dumptype %s already defined on line %d", dp->name, dp->seen);
1750 dp = alloc(sizeof(dumptype_t));
1753 dp->next = dumplist;
1757 static void copy_dumptype()
1761 dt = lookup_dumptype(tokenval.s);
1764 parserror("dump type parameter expected");
1768 #define dtcopy(v,s) if(dt->s) { dpcur.v = dt->v; dpcur.s = dt->s; }
1771 dpcur.comment = newstralloc(dpcur.comment, dt->comment);
1772 dpcur.s_comment = dt->s_comment;
1775 dpcur.program = newstralloc(dpcur.program, dt->program);
1776 dpcur.s_program = dt->s_program;
1778 if(dt->s_security_driver) {
1779 dpcur.security_driver = newstralloc(dpcur.security_driver,
1780 dt->security_driver);
1781 dpcur.s_security_driver = dt->s_security_driver;
1783 if(dt->s_srvcompprog) {
1784 dpcur.srvcompprog = newstralloc(dpcur.srvcompprog, dt->srvcompprog);
1785 dpcur.s_srvcompprog = dt->s_srvcompprog;
1787 if(dt->s_clntcompprog) {
1788 dpcur.clntcompprog = newstralloc(dpcur.clntcompprog, dt->clntcompprog);
1789 dpcur.s_clntcompprog = dt->s_clntcompprog;
1791 if(dt->s_srv_encrypt) {
1792 dpcur.srv_encrypt = newstralloc(dpcur.srv_encrypt, dt->srv_encrypt);
1793 dpcur.s_srv_encrypt = dt->s_srv_encrypt;
1795 if(dt->s_clnt_encrypt) {
1796 dpcur.clnt_encrypt = newstralloc(dpcur.clnt_encrypt, dt->clnt_encrypt);
1797 dpcur.s_clnt_encrypt = dt->s_clnt_encrypt;
1799 if(dt->s_srv_decrypt_opt) {
1800 dpcur.srv_decrypt_opt = newstralloc(dpcur.srv_decrypt_opt, dt->srv_decrypt_opt);
1801 dpcur.s_srv_decrypt_opt = dt->s_srv_decrypt_opt;
1803 if(dt->s_clnt_decrypt_opt) {
1804 dpcur.clnt_decrypt_opt = newstralloc(dpcur.clnt_decrypt_opt, dt->clnt_decrypt_opt);
1805 dpcur.s_clnt_decrypt_opt = dt->s_clnt_decrypt_opt;
1808 if(dt->s_exclude_file) {
1809 dpcur.exclude_file = duplicate_sl(dt->exclude_file);
1810 dpcur.s_exclude_file = dt->s_exclude_file;
1812 if(dt->s_exclude_list) {
1813 dpcur.exclude_list = duplicate_sl(dt->exclude_list);
1814 dpcur.s_exclude_list = dt->s_exclude_list;
1816 if(dt->s_include_file) {
1817 dpcur.include_file = duplicate_sl(dt->include_file);
1818 dpcur.s_include_file = dt->s_include_file;
1820 if(dt->s_include_list) {
1821 dpcur.include_list = duplicate_sl(dt->include_list);
1822 dpcur.s_include_list = dt->s_include_list;
1824 dtcopy(priority, s_priority);
1825 dtcopy(dumpcycle, s_dumpcycle);
1826 dtcopy(maxcycle, s_maxcycle);
1827 dtcopy(frequency, s_frequency);
1828 dtcopy(maxdumps, s_maxdumps);
1829 dtcopy(maxpromoteday, s_maxpromoteday);
1830 dtcopy(bumppercent, s_bumppercent);
1831 dtcopy(bumpsize, s_bumpsize);
1832 dtcopy(bumpdays, s_bumpdays);
1833 dtcopy(bumpmult, s_bumpmult);
1834 dtcopy(start_t, s_start_t);
1835 dtcopy(record, s_record);
1836 dtcopy(strategy, s_strategy);
1837 dtcopy(estimate, s_estimate);
1838 dtcopy(compress, s_compress);
1839 dtcopy(encrypt, s_encrypt);
1840 dtcopy(comprate[0], s_comprate);
1841 dtcopy(comprate[1], s_comprate);
1842 dtcopy(skip_incr, s_skip_incr);
1843 dtcopy(skip_full, s_skip_full);
1844 dtcopy(no_hold, s_no_hold);
1845 dtcopy(kencrypt, s_kencrypt);
1846 dtcopy(ignore, s_ignore);
1847 dtcopy(index, s_index);
1848 dtcopy(tape_splitsize, s_tape_splitsize);
1849 dtcopy(split_diskbuffer, s_split_diskbuffer);
1850 dtcopy(fallback_splitsize, s_fallback_splitsize);
1853 keytab_t tapetype_keytable[] = {
1854 { "COMMENT", COMMENT },
1855 { "LBL-TEMPL", LBL_TEMPL },
1856 { "BLOCKSIZE", BLOCKSIZE },
1857 { "FILE-PAD", FILE_PAD },
1858 { "FILEMARK", FILEMARK },
1859 { "LENGTH", LENGTH },
1864 static void get_tapetype()
1867 int save_overwrites;
1872 save_overwrites = allow_overwrites;
1873 allow_overwrites = 1;
1876 keytable = tapetype_keytable;
1878 init_tapetype_defaults();
1880 get_conftoken(IDENT);
1881 tpcur.name = stralloc(tokenval.s);
1882 malloc_mark(tpcur.name);
1883 tpcur.seen = line_num;
1885 get_conftoken(LBRACE);
1898 get_simple((val_t *)&tpcur.comment, &tpcur.s_comment, STRING);
1901 get_simple((val_t *)&tpcur.lbl_templ, &tpcur.s_lbl_templ, STRING);
1904 get_simple((val_t *)&tpcur.blocksize, &tpcur.s_blocksize, LONG);
1905 if(tpcur.blocksize < DISK_BLOCK_KB) {
1906 parserror("Tape blocksize must be at least %d KBytes",
1908 } else if(tpcur.blocksize > MAX_TAPE_BLOCK_KB) {
1909 parserror("Tape blocksize must not be larger than %d KBytes",
1914 get_simple(&value, &tpcur.s_file_pad, BOOL);
1915 tpcur.file_pad = (value.i != 0);
1918 get_simple(&value, &tpcur.s_length, LONG);
1920 parserror("Tape length must be positive");
1923 tpcur.length = (unsigned long) value.l;
1927 get_simple(&value, &tpcur.s_filemark, LONG);
1929 parserror("Tape file mark size must be positive");
1932 tpcur.filemark = (unsigned long) value.l;
1936 get_simple((val_t *)&tpcur.speed, &tpcur.s_speed, INT);
1937 if(tpcur.speed < 0) {
1938 parserror("Speed must be positive");
1944 case NL: /* empty line */
1946 case END: /* end of file */
1949 parserror("tape type parameter expected");
1951 if(tok != NL && tok != END) get_conftoken(NL);
1956 allow_overwrites = save_overwrites;
1960 static void init_tapetype_defaults()
1962 tpcur.comment = stralloc("");
1963 tpcur.lbl_templ = stralloc("");
1964 tpcur.blocksize = (DISK_BLOCK_KB);
1966 tpcur.length = 2000 * 1024;
1967 tpcur.filemark = 1000;
1970 tpcur.s_comment = 0;
1971 tpcur.s_lbl_templ = 0;
1972 tpcur.s_blocksize = 0;
1973 tpcur.s_file_pad = 0;
1975 tpcur.s_filemark = 0;
1979 static void save_tapetype()
1983 tp = lookup_tapetype(tpcur.name);
1985 if(tp != (tapetype_t *)0) {
1987 parserror("tapetype %s already defined on line %d", tp->name, tp->seen);
1991 tp = alloc(sizeof(tapetype_t));
1994 tp->next = tapelist;
1998 static void copy_tapetype()
2002 tp = lookup_tapetype(tokenval.s);
2005 parserror("tape type parameter expected");
2009 #define ttcopy(v,s) if(tp->s) { tpcur.v = tp->v; tpcur.s = tp->s; }
2012 tpcur.comment = newstralloc(tpcur.comment, tp->comment);
2013 tpcur.s_comment = tp->s_comment;
2015 if(tp->s_lbl_templ) {
2016 tpcur.lbl_templ = newstralloc(tpcur.lbl_templ, tp->lbl_templ);
2017 tpcur.s_lbl_templ = tp->s_lbl_templ;
2019 ttcopy(blocksize, s_blocksize);
2020 ttcopy(file_pad, s_file_pad);
2021 ttcopy(length, s_length);
2022 ttcopy(filemark, s_filemark);
2023 ttcopy(speed, s_speed);
2026 keytab_t interface_keytable[] = {
2027 { "COMMENT", COMMENT },
2032 static void get_interface()
2035 int save_overwrites;
2038 save_overwrites = allow_overwrites;
2039 allow_overwrites = 1;
2042 keytable = interface_keytable;
2044 init_interface_defaults();
2046 get_conftoken(IDENT);
2047 ifcur.name = stralloc(tokenval.s);
2048 malloc_mark(ifcur.name);
2049 ifcur.seen = line_num;
2051 get_conftoken(LBRACE);
2064 get_simple((val_t *)&ifcur.comment, &ifcur.s_comment, STRING);
2067 get_simple((val_t *)&ifcur.maxusage, &ifcur.s_maxusage, INT);
2068 if(ifcur.maxusage <1) {
2069 parserror("use must bbe positive");
2075 case NL: /* empty line */
2077 case END: /* end of file */
2080 parserror("interface parameter expected");
2082 if(tok != NL && tok != END) get_conftoken(NL);
2087 allow_overwrites = save_overwrites;
2093 static void init_interface_defaults()
2095 ifcur.comment = stralloc("");
2096 ifcur.maxusage = 300;
2098 ifcur.s_comment = 0;
2099 ifcur.s_maxusage = 0;
2104 static void save_interface()
2108 ip = lookup_interface(ifcur.name);
2110 if(ip != (interface_t *)0) {
2111 parserror("interface %s already defined on line %d", ip->name, ip->seen);
2115 ip = alloc(sizeof(interface_t));
2118 ip->next = interface_list;
2119 interface_list = ip;
2122 static void copy_interface()
2126 ip = lookup_interface(tokenval.s);
2129 parserror("interface parameter expected");
2133 #define ifcopy(v,s) if(ip->s) { ifcur.v = ip->v; ifcur.s = ip->s; }
2136 ifcur.comment = newstralloc(ifcur.comment, ip->comment);
2137 ifcur.s_comment = ip->s_comment;
2139 ifcopy(maxusage, s_maxusage);
2142 keytab_t dumpopts_keytable[] = {
2143 { "COMPRESS", COMPRESS },
2144 { "ENCRYPT", ENCRYPT },
2146 { "EXCLUDE-FILE", EXCLUDE_FILE },
2147 { "EXCLUDE-LIST", EXCLUDE_LIST },
2148 { "KENCRYPT", KENCRYPT },
2149 { "SKIP-FULL", SKIP_FULL },
2150 { "SKIP-INCR", SKIP_INCR },
2154 static void get_dumpopts() /* XXX - for historical compatability */
2160 keytable = dumpopts_keytable;
2166 case COMPRESS: ckseen(&dpcur.s_compress); dpcur.compress = COMP_FAST; break;
2167 case ENCRYPT: ckseen(&dpcur.s_encrypt); dpcur.encrypt = ENCRYPT_NONE; break;
2169 ckseen(&dpcur.s_exclude_file);
2170 get_conftoken(STRING);
2171 dpcur.exclude_file = append_sl(dpcur.exclude_file, tokenval.s);
2174 ckseen(&dpcur.s_exclude_list);
2175 get_conftoken(STRING);
2176 dpcur.exclude_list = append_sl(dpcur.exclude_list, tokenval.s);
2178 case KENCRYPT: ckseen(&dpcur.s_kencrypt); dpcur.kencrypt = 1; break;
2179 case SKIP_INCR: ckseen(&dpcur.s_skip_incr); dpcur.skip_incr= 1; break;
2180 case SKIP_FULL: ckseen(&dpcur.s_skip_full); dpcur.skip_full= 1; break;
2181 case INDEX: ckseen(&dpcur.s_index); dpcur.index = 1; break;
2185 case NL: done = 1; break;
2190 parserror("dump option expected");
2197 static void get_comprate()
2201 get_simple(&var, &dpcur.s_comprate, REAL);
2202 dpcur.comprate[0] = dpcur.comprate[1] = var.r;
2203 if(dpcur.comprate[0] < 0) {
2204 parserror("full compression rate must be >= 0");
2217 get_conftoken(REAL);
2218 dpcur.comprate[1] = tokenval.r;
2219 if(dpcur.comprate[1] < 0) {
2220 parserror("incremental compression rate must be >= 0");
2224 keytab_t compress_keytable[] = {
2226 { "CLIENT", CLIENT },
2229 { "SERVER", SERVER },
2230 { "CUSTOM", CUSTOM },
2234 static void get_compress()
2237 int serv, clie, none, fast, best, custom;
2242 keytable = compress_keytable;
2244 ckseen(&dpcur.s_compress);
2246 serv = clie = none = fast = best = custom = 0;
2252 case NONE: none = 1; break;
2253 case FAST: fast = 1; break;
2254 case BEST: best = 1; break;
2255 case CLIENT: clie = 1; break;
2256 case SERVER: serv = 1; break;
2257 case CUSTOM: custom=1; break;
2258 case NL: done = 1; break;
2261 serv = clie = 1; /* force an error */
2265 if(serv + clie == 0) clie = 1; /* default to client */
2266 if(none + fast + best + custom == 0) fast = 1; /* default to fast */
2271 if(none && !fast && !best && !custom) comp = COMP_NONE;
2272 if(!none && fast && !best && !custom) comp = COMP_FAST;
2273 if(!none && !fast && best && !custom) comp = COMP_BEST;
2274 if(!none && !fast && !best && custom) comp = COMP_CUST;
2278 if(none && !fast && !best && !custom) comp = COMP_NONE;
2279 if(!none && fast && !best && !custom) comp = COMP_SERV_FAST;
2280 if(!none && !fast && best && !custom) comp = COMP_SERV_BEST;
2281 if(!none && !fast && !best && custom) comp = COMP_SERV_CUST;
2285 parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected");
2289 dpcur.compress = comp;
2294 keytab_t encrypt_keytable[] = {
2296 { "CLIENT", CLIENT },
2297 { "SERVER", SERVER },
2301 static void get_encrypt()
2307 keytable = encrypt_keytable;
2309 ckseen(&dpcur.s_encrypt);
2314 encrypt = ENCRYPT_NONE;
2317 encrypt = ENCRYPT_CUST;
2320 encrypt = ENCRYPT_SERV_CUST;
2323 parserror("NONE, CLIENT or SERVER expected");
2324 encrypt = ENCRYPT_NONE;
2327 dpcur.encrypt = encrypt;
2331 keytab_t taperalgo_keytable[] = {
2333 { "FIRSTFIT", FIRSTFIT },
2334 { "LARGEST", LARGEST },
2335 { "LARGESTFIT", LARGESTFIT },
2336 { "SMALLEST", SMALLEST },
2341 static void get_taperalgo(c_taperalgo, s_taperalgo)
2348 keytable = taperalgo_keytable;
2350 ckseen(s_taperalgo);
2354 case FIRST: c_taperalgo->i = ALGO_FIRST; break;
2355 case FIRSTFIT: c_taperalgo->i = ALGO_FIRSTFIT; break;
2356 case LARGEST: c_taperalgo->i = ALGO_LARGEST; break;
2357 case LARGESTFIT: c_taperalgo->i = ALGO_LARGESTFIT; break;
2358 case SMALLEST: c_taperalgo->i = ALGO_SMALLEST; break;
2359 case LAST: c_taperalgo->i = ALGO_LAST; break;
2361 parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected");
2367 keytab_t priority_keytable[] = {
2370 { "MEDIUM", MEDIUM },
2374 static void get_priority()
2380 keytable = priority_keytable;
2382 ckseen(&dpcur.s_priority);
2386 case LOW: pri = 0; break;
2387 case MEDIUM: pri = 1; break;
2388 case HIGH: pri = 2; break;
2389 case INT: pri = tokenval.i; break;
2391 parserror("LOW, MEDIUM, HIGH or integer expected");
2394 dpcur.priority = pri;
2399 keytab_t strategy_keytable[] = {
2401 { "NOFULL", NOFULL },
2404 { "STANDARD", STANDARD },
2405 { "INCRONLY", INCRONLY },
2409 static void get_strategy()
2415 keytable = strategy_keytable;
2417 ckseen(&dpcur.s_strategy);
2425 strat = DS_STANDARD;
2437 strat = DS_INCRONLY;
2440 parserror("STANDARD or NOFULL expected");
2441 strat = DS_STANDARD;
2443 dpcur.strategy = strat;
2448 keytab_t estimate_keytable[] = {
2449 { "CLIENT", CLIENT },
2450 { "SERVER", SERVER },
2451 { "CALCSIZE", CALCSIZE }
2454 static void get_estimate()
2460 keytable = estimate_keytable;
2462 ckseen(&dpcur.s_estimate);
2473 estime = ES_CALCSIZE;
2476 parserror("CLIENT, SERVER or CALCSIZE expected");
2479 dpcur.estimate = estime;
2484 keytab_t exclude_keytable[] = {
2487 { "APPEND", APPEND },
2488 { "OPTIONAL", OPTIONAL },
2492 static void get_exclude()
2494 int list, got_one = 0;
2501 keytable = exclude_keytable;
2506 exclude = dpcur.exclude_list;
2507 ckseen(&dpcur.s_exclude_list);
2512 exclude = dpcur.exclude_file;
2513 ckseen(&dpcur.s_exclude_file);
2514 if(tok == EFILE) get_conftoken(ANY);
2517 if(tok == OPTIONAL) {
2532 while(tok == STRING) {
2533 exclude = append_sl(exclude, tokenval.s);
2539 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
2542 dpcur.exclude_file = exclude;
2544 dpcur.exclude_list = exclude;
2545 if(!append || optional)
2546 dpcur.exclude_optional = optional;
2553 static void get_include()
2555 int list, got_one = 0;
2562 keytable = exclude_keytable;
2567 include = dpcur.include_list;
2568 ckseen(&dpcur.s_include_list);
2573 include = dpcur.include_file;
2574 ckseen(&dpcur.s_include_file);
2575 if(tok == EFILE) get_conftoken(ANY);
2578 if(tok == OPTIONAL) {
2593 while(tok == STRING) {
2594 include = append_sl(include, tokenval.s);
2600 if(got_one == 0) { free_sl(include); include = NULL; }
2603 dpcur.include_file = include;
2605 dpcur.include_list = include;
2606 if(!append || optional)
2607 dpcur.include_optional = optional;
2614 /* ------------------------ */
2617 static void get_simple(var, seen, type)
2627 get_conftoken(type);
2628 var->s = newstralloc(var->s, tokenval.s);
2629 malloc_mark(var->s);
2635 var->l = get_long();
2638 var->am64 = get_am64_t();
2641 var->i = get_bool();
2644 get_conftoken(REAL);
2645 var->r = tokenval.r;
2648 var->i = get_time();
2651 error("error [unknown get_simple type: %d]", type);
2657 static int get_time()
2659 time_t st = start_time.r.tv_sec;
2666 stm = localtime(&st);
2667 st -= stm->tm_sec + 60 * (stm->tm_min + 60 * stm->tm_hour);
2668 st += ((hhmm/100*60) + hhmm%100)*60;
2670 if (st-start_time.r.tv_sec<-43200)
2676 keytab_t numb_keytable[] = {
2683 { "INF", INFINITY },
2687 { "KBYTE", MULT1K },
2688 { "KBYTES", MULT1K },
2689 { "KILOBYTE", MULT1K },
2690 { "KILOBYTES", MULT1K },
2695 { "MBYTE", MULT1M },
2696 { "MBYTES", MULT1M },
2698 { "MEGABYTE", MULT1M },
2699 { "MEGABYTES", MULT1M },
2703 { "GBYTE", MULT1G },
2704 { "GBYTES", MULT1G },
2706 { "GIGABYTE", MULT1G },
2707 { "GIGABYTES", MULT1G },
2716 static int get_int()
2722 keytable = numb_keytable;
2728 if(abs(tokenval.am64) > INT_MAX)
2729 parserror("value too large");
2730 val = (int) tokenval.am64;
2736 parserror("an integer expected");
2740 /* get multiplier, if any */
2744 case NL: /* multiply by one */
2749 if(abs(val) > INT_MAX/7)
2750 parserror("value too large");
2754 if(abs(val) > INT_MAX/1024)
2755 parserror("value too large");
2759 if(abs(val) > INT_MAX/(1024*1024))
2760 parserror("value too large");
2763 default: /* it was not a multiplier */
2772 static long get_long()
2778 keytable = numb_keytable;
2784 if(tokenval.am64 > LONG_MAX || tokenval.am64 < LONG_MIN)
2785 parserror("value too large");
2786 val = (long) tokenval.am64;
2789 val = (long) LONG_MAX;
2792 parserror("a long expected");
2796 /* get multiplier, if any */
2800 case NL: /* multiply by one */
2805 if(val > LONG_MAX/7 || val < LONG_MIN/7)
2806 parserror("value too large");
2810 if(val > LONG_MAX/1024 || val < LONG_MIN/7)
2811 parserror("value too large");
2815 if(val > LONG_MAX/(1024*1024) || val < LONG_MIN/(1024*1024))
2816 parserror("value too large");
2819 default: /* it was not a multiplier */
2828 static am64_t get_am64_t()
2834 keytable = numb_keytable;
2840 val = tokenval.am64;
2846 parserror("a am64 expected %d", tok);
2850 /* get multiplier, if any */
2854 case NL: /* multiply by one */
2859 if(val > AM64_MAX/7 || val < AM64_MIN/7)
2860 parserror("value too large");
2864 if(val > AM64_MAX/1024 || val < AM64_MIN/1024)
2865 parserror("value too large");
2869 if(val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
2870 parserror("value too large");
2873 default: /* it was not a multiplier */
2882 keytab_t bool_keytable[] = {
2891 { "FALSE", AFALSE },
2896 static int get_bool()
2902 keytable = bool_keytable;
2908 val = tokenval.i ? 1 : 0;
2919 val = 2; /* no argument - most likely TRUE */
2927 static void ckseen(seen)
2930 if(*seen && !allow_overwrites) {
2931 parserror("duplicate parameter, prev def on line %d", *seen);
2936 printf_arglist_function(static void parserror, char *, format)
2940 /* print error message */
2942 fprintf(stderr, "\"%s\", line %d: ", confname, line_num);
2943 arglist_start(argp, format);
2944 vfprintf(stderr, format, argp);
2946 fputc('\n', stderr);
2951 static tok_t lookup_keyword(str)
2956 /* switch to binary search if performance warrants */
2958 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
2959 if(strcmp(kwp->keyword, str) == 0) break;
2964 static char tkbuf[4096];
2966 /* push the last token back (can only unget ANY tokens) */
2967 static void unget_conftoken()
2975 static void get_conftoken(exp)
2987 /* If it looked like a key word before then look it
2988 ** up again in the current keyword table. */
2990 case LONG: case AM64:
2991 case INT: case REAL: case STRING:
2992 case LBRACE: case RBRACE: case COMMA:
2993 case NL: case END: case UNKNOWN:
2996 if(exp == IDENT) tok = IDENT;
2997 else tok = lookup_keyword(tokenval.s);
3003 while(ch != EOF && ch != '\n' && isspace(ch)) ch = getc(conf);
3004 if(ch == '#') { /* comment - eat everything but eol/eof */
3005 while((ch = getc(conf)) != EOF && ch != '\n') {}
3008 if(isalpha(ch)) { /* identifier */
3012 if(islower(ch)) ch = toupper(ch);
3013 if(buf < tkbuf+sizeof(tkbuf)-1) {
3017 if(!token_overflow) {
3018 parserror("token too long: %.20s...", tkbuf);
3023 } while(isalnum(ch) || ch == '_' || ch == '-');
3030 if(token_overflow) tok = UNKNOWN;
3031 else if(exp == IDENT) tok = IDENT;
3032 else tok = lookup_keyword(tokenval.s);
3034 else if(isdigit(ch)) { /* integer */
3039 negative_number: /* look for goto negative_number below */
3044 tokenval.am64 = tokenval.am64 * 10 + (ch - '0');
3046 } while(isdigit(ch));
3052 else if(exp == LONG) {
3056 else if(exp != REAL) {
3058 tokenval.am64 *= sign;
3060 /* automatically convert to real when expected */
3061 am64 = tokenval.am64;
3062 tokenval.r = sign * (double) am64;
3067 /* got a real number, not an int */
3068 am64 = tokenval.am64;
3069 tokenval.r = sign * (double) am64;
3072 while(isdigit(ch)) {
3073 am64 = am64 * 10 + (ch - '0');
3077 tokenval.r += sign * ((double)am64)/d;
3084 case '"': /* string */
3088 while(ch != '"' && ch != '\n' && ch != EOF) {
3089 if(buf < tkbuf+sizeof(tkbuf)-1) {
3093 if(!token_overflow) {
3094 parserror("string too long: %.20s...", tkbuf);
3101 parserror("missing end quote");
3106 if(token_overflow) tok = UNKNOWN;
3113 goto negative_number;
3119 case ',': tok = COMMA; break;
3120 case '{': tok = LBRACE; break;
3121 case '}': tok = RBRACE; break;
3122 case '\n': tok = NL; break;
3123 case EOF: tok = END; break;
3124 default: tok = UNKNOWN;
3128 if(exp != ANY && tok != exp) {
3133 case LBRACE: str = "\"{\""; break;
3134 case RBRACE: str = "\"}\""; break;
3135 case COMMA: str = "\",\""; break;
3137 case NL: str = "end of line"; break;
3138 case END: str = "end of file"; break;
3139 case INT: str = "an integer"; break;
3140 case REAL: str = "a real number"; break;
3141 case STRING: str = "a quoted string"; break;
3142 case IDENT: str = "an identifier"; break;
3144 for(kwp = keytable; kwp->keyword != NULL; kwp++)
3145 if(exp == kwp->token) break;
3146 if(kwp->keyword == NULL) str = "token not";
3147 else str = kwp->keyword;
3149 parserror("%s expected", str);
3151 if(tok == INT) tokenval.i = 0;
3152 else tokenval.s = "";
3158 int ColumnDataCount()
3160 return sizeof(ColumnData) / sizeof(ColumnData[0]);
3163 /* conversion from string to table index
3171 for (cn=0; ColumnData[cn].Name != NULL; cn++) {
3172 if (strcasecmp(s, ColumnData[cn].Name) == 0) {
3183 return s[strlen(s)-1];
3187 SetColumDataFromString(ci, s, errstr)
3192 /* Convert from a Columspec string to our internal format
3193 * of columspec. The purpose is to provide this string
3194 * as configuration paramter in the amanda.conf file or
3195 * (maybe) as environment variable.
3197 * This text should go as comment into the sample amanda.conf
3199 * The format for such a ColumnSpec string s is a ',' seperated
3200 * list of triples. Each triple consists of
3201 * -the name of the column (as in ColumnData.Name)
3202 * -prefix before the column
3203 * -the width of the column
3204 * if set to -1 it will be recalculated
3205 * to the maximum length of a line to print.
3207 * "Disk=1:17,HostName=1:10,OutKB=1:7"
3209 * "Disk=1:-1,HostName=1:10,OutKB=1:7"
3211 * You need only specify those colums that should be changed from
3212 * the default. If nothing is specified in the configfile, the
3213 * above compiled in values will be in effect, resulting in an
3214 * output as it was all the time.
3218 char *myname= "SetColumDataFromString";
3224 char *eon= strchr(s, '=');
3227 *errstr = stralloc2("invalid columnspec: ", s);
3229 fprintf(stderr, "%s: %s\n", myname, *errstr);
3234 cn=StringToColumn(s);
3235 if (ColumnData[cn].Name == NULL) {
3236 *errstr = stralloc2("invalid column name: ", s);
3238 fprintf(stderr, "%s: %s\n", myname, *errstr);
3242 if (sscanf(eon+1, "%d:%d", &Space, &Width) != 2) {
3243 *errstr = stralloc2("invalid format: ", eon + 1);
3245 fprintf(stderr, "%s: %s\n", myname, *errstr);
3249 ColumnData[cn].Width= Width;
3250 ColumnData[cn].PrefixSpace= Space;
3251 if (LastChar(ColumnData[cn].Format) == 's') {
3253 ColumnData[cn].MaxWidth= 1;
3255 if (Width > ColumnData[cn].Precision)
3256 ColumnData[cn].Precision= Width;
3258 else if (Width < ColumnData[cn].Precision)
3259 ColumnData[cn].Precision= Width;
3260 s= strchr(eon+1, ',');
3268 char *taperalgo2str(taperalgo)
3271 if(taperalgo == ALGO_FIRST) return "FIRST";
3272 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
3273 if(taperalgo == ALGO_LARGEST) return "LARGEST";
3274 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
3275 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
3276 if(taperalgo == ALGO_LAST) return "LAST";
3280 long int getconf_unit_divisor()
3282 return unit_divisor;
3285 /* ------------------------ */
3291 dump_configuration(filename)
3301 printf("AMANDA CONFIGURATION FROM FILE \"%s\":\n\n", filename);
3303 printf("conf_org = \"%s\"\n", getconf_str(CNF_ORG));
3304 printf("conf_mailto = \"%s\"\n", getconf_str(CNF_MAILTO));
3305 printf("conf_dumpuser = \"%s\"\n", getconf_str(CNF_DUMPUSER));
3306 printf("conf_printer = \"%s\"\n", getconf_str(CNF_PRINTER));
3307 printf("conf_tapedev = \"%s\"\n", getconf_str(CNF_TAPEDEV));
3308 printf("conf_rawtapedev = \"%s\"\n", getconf_str(CNF_RAWTAPEDEV));
3309 printf("conf_tpchanger = \"%s\"\n", getconf_str(CNF_TPCHANGER));
3310 printf("conf_chngrdev = \"%s\"\n", getconf_str(CNF_CHNGRDEV));
3311 printf("conf_chngrfile = \"%s\"\n", getconf_str(CNF_CHNGRFILE));
3312 printf("conf_labelstr = \"%s\"\n", getconf_str(CNF_LABELSTR));
3313 printf("conf_tapelist = \"%s\"\n", getconf_str(CNF_TAPELIST));
3314 printf("conf_infofile = \"%s\"\n", getconf_str(CNF_INFOFILE));
3315 printf("conf_logdir = \"%s\"\n", getconf_str(CNF_LOGDIR));
3316 printf("conf_diskfile = \"%s\"\n", getconf_str(CNF_DISKFILE));
3317 printf("conf_tapetype = \"%s\"\n", getconf_str(CNF_TAPETYPE));
3319 printf("conf_dumpcycle = %d\n", getconf_int(CNF_DUMPCYCLE));
3320 printf("conf_runspercycle = %d\n", getconf_int(CNF_RUNSPERCYCLE));
3321 printf("conf_runtapes = %d\n", getconf_int(CNF_RUNTAPES));
3322 printf("conf_tapecycle = %d\n", getconf_int(CNF_TAPECYCLE));
3323 printf("conf_bumppercent = %d\n", getconf_int(CNF_BUMPPERCENT));
3324 printf("conf_bumpsize = %d\n", getconf_int(CNF_BUMPSIZE));
3325 printf("conf_bumpdays = %d\n", getconf_int(CNF_BUMPDAYS));
3326 printf("conf_bumpmult = %f\n", getconf_real(CNF_BUMPMULT));
3327 printf("conf_netusage = %d\n", getconf_int(CNF_NETUSAGE));
3328 printf("conf_inparallel = %d\n", getconf_int(CNF_INPARALLEL));
3329 printf("conf_dumporder = \"%s\"\n", getconf_str(CNF_DUMPORDER));
3330 /*printf("conf_timeout = %d\n", getconf_int(CNF_TIMEOUT));*/
3331 printf("conf_maxdumps = %d\n", getconf_int(CNF_MAXDUMPS));
3332 printf("conf_etimeout = %d\n", getconf_int(CNF_ETIMEOUT));
3333 printf("conf_dtimeout = %d\n", getconf_int(CNF_DTIMEOUT));
3334 printf("conf_ctimeout = %d\n", getconf_int(CNF_CTIMEOUT));
3335 printf("conf_tapebufs = %d\n", getconf_int(CNF_TAPEBUFS));
3336 printf("conf_autoflush = %d\n", getconf_int(CNF_AUTOFLUSH));
3337 printf("conf_reserve = %d\n", getconf_int(CNF_RESERVE));
3338 printf("conf_maxdumpsize = " AM64_FMT "\n", getconf_am64(CNF_MAXDUMPSIZE));
3339 printf("conf_amrecover_do_fsf = %d\n", getconf_int(CNF_AMRECOVER_DO_FSF));
3340 printf("conf_amrecover_check_label = %d\n", getconf_int(CNF_AMRECOVER_CHECK_LABEL));
3341 printf("conf_amrecover_changer = \"%s\"\n", getconf_str(CNF_AMRECOVER_CHANGER));
3342 printf("conf_taperalgo = %s\n", taperalgo2str(getconf_int(CNF_TAPERALGO)));
3343 printf("conf_displayunit = %s\n", getconf_str(CNF_DISPLAYUNIT));
3345 /*printf("conf_diskdir = \"%s\"\n", getconf_str(CNF_DISKDIR));*/
3346 /*printf("conf_disksize = %d\n", getconf_int(CNF_DISKSIZE));*/
3347 printf("conf_columnspec = \"%s\"\n", getconf_str(CNF_COLUMNSPEC));
3348 printf("conf_indexdir = \"%s\"\n", getconf_str(CNF_INDEXDIR));
3349 printf("num_holdingdisks = %d\n", num_holdingdisks);
3350 printf("conf_krb5keytab = \"%s\"\n", getconf_str(CNF_KRB5KEYTAB));
3351 printf("conf_krb5principal = \"%s\"\n", getconf_str(CNF_KRB5PRINCIPAL));
3352 printf("conf_label_new_tapes = \"%s\"\n", getconf_str(CNF_LABEL_NEW_TAPES));
3353 for(hp = holdingdisks; hp != NULL; hp = hp->next) {
3354 printf("\nHOLDINGDISK %s:\n", hp->name);
3355 printf(" COMMENT \"%s\"\n", hp->comment);
3356 printf(" DISKDIR \"%s\"\n", hp->diskdir);
3357 printf(" SIZE %ld\n", (long)hp->disksize);
3358 printf(" CHUNKSIZE %ld\n", (long)hp->chunksize);
3361 for(tp = tapelist; tp != NULL; tp = tp->next) {
3362 printf("\nTAPETYPE %s:\n", tp->name);
3363 printf(" COMMENT \"%s\"\n", tp->comment);
3364 printf(" LBL_TEMPL %s\n", tp->lbl_templ);
3365 printf(" BLOCKSIZE %ld\n", (long)tp->blocksize);
3366 printf(" FILE_PAD %s\n", (tp->file_pad) ? "YES" : "NO");
3367 printf(" LENGTH %lu\n", (unsigned long)tp->length);
3368 printf(" FILEMARK %lu\n", (unsigned long)tp->filemark);
3369 printf(" SPEED %ld\n", (long)tp->speed);
3372 for(dp = dumplist; dp != NULL; dp = dp->next) {
3373 printf("\nDUMPTYPE %s:\n", dp->name);
3374 printf(" COMMENT \"%s\"\n", dp->comment);
3375 printf(" PROGRAM \"%s\"\n", dp->program);
3376 printf(" SERVER_CUSTOM_COMPRESS \"%s\"\n", dp->srvcompprog);
3377 printf(" CLIENT_CUSTOM_COMPRESS \"%s\"\n", dp->clntcompprog);
3378 printf(" SERVER_ENCRYPT \"%s\"\n", dp->srv_encrypt);
3379 printf(" CLIENT_ENCRYPT \"%s\"\n", dp->clnt_encrypt);
3380 printf(" SERVER_DECRYPT_OPTION \"%s\"\n", dp->srv_decrypt_opt);
3381 printf(" CLIENT_DECRYPT_OPTION \"%s\"\n", dp->clnt_decrypt_opt);
3382 printf(" PRIORITY %ld\n", (long)dp->priority);
3383 printf(" DUMPCYCLE %ld\n", (long)dp->dumpcycle);
3386 stm = localtime(&st);
3387 printf(" STARTTIME %d:%02d:%02d\n",
3388 stm->tm_hour, stm->tm_min, stm->tm_sec);
3390 if(dp->exclude_file) {
3392 printf(" EXCLUDE FILE");
3393 for(excl = dp->exclude_file->first; excl != NULL; excl =excl->next){
3394 printf(" \"%s\"", excl->name);
3398 if(dp->exclude_list) {
3400 printf(" EXCLUDE LIST");
3401 for(excl = dp->exclude_list->first; excl != NULL; excl =excl->next){
3402 printf(" \"%s\"", excl->name);
3406 if(dp->include_file) {
3408 printf(" INCLUDE FILE");
3409 for(incl = dp->include_file->first; incl != NULL; incl =incl->next){
3410 printf(" \"%s\"", incl->name);
3414 if(dp->include_list) {
3416 printf(" INCLUDE LIST");
3417 for(incl = dp->include_list->first; incl != NULL; incl =incl->next){
3418 printf(" \"%s\"", incl->name);
3422 printf(" FREQUENCY %ld\n", (long)dp->frequency);
3423 printf(" MAXDUMPS %d\n", dp->maxdumps);
3424 printf(" MAXPROMOTEDAY %d\n", dp->maxpromoteday);
3425 printf(" STRATEGY ");
3426 switch(dp->strategy) {
3447 printf(" ESTIMATE ");
3448 switch(dp->estimate) {
3460 printf(" COMPRATE %f, %f\n", dp->comprate[0], dp->comprate[1]);
3462 printf(" OPTIONS: ");
3464 switch(dp->compress) {
3466 printf("NO-COMPRESS ");
3469 printf("COMPRESS-FAST ");
3472 printf("COMPRESS-BEST ");
3475 printf("COMPRESS-CUST ");
3477 case COMP_SERV_FAST:
3478 printf("SRVCOMP-FAST ");
3480 case COMP_SERV_BEST:
3481 printf("SRVCOMP-BEST ");
3483 case COMP_SERV_CUST:
3484 printf("SRVCOMP-CUST ");
3488 switch(dp->encrypt) {
3490 printf("ENCRYPT-NONE ");
3493 printf("ENCRYPT-CUST ");
3495 case ENCRYPT_SERV_CUST:
3496 printf("ENCRYPT-SERV-CUST ");
3500 if(!dp->record) printf("NO-");
3502 printf(" %s-AUTH", dp->security_driver);
3503 if(dp->skip_incr) printf(" SKIP-INCR");
3504 if(dp->skip_full) printf(" SKIP-FULL");
3505 if(dp->no_hold) printf(" NO-HOLD");
3506 if(dp->kencrypt) printf(" KENCRYPT");
3507 /* an ignored disk will never reach this point */
3508 assert(!dp->ignore);
3509 if(dp->index) printf(" INDEX");
3513 for(ip = interface_list; ip != NULL; ip = ip->next) {
3514 printf("\nINTERFACE %s:\n", ip->name);
3515 printf(" COMMENT \"%s\"\n", ip->comment);
3516 printf(" USE %d\n", ip->maxusage);
3529 unsigned long malloc_hist_1, malloc_size_1;
3530 unsigned long malloc_hist_2, malloc_size_2;
3534 set_pname("conffile");
3536 /* Don't die when child closes pipe */
3537 signal(SIGPIPE, SIG_IGN);
3539 malloc_size_1 = malloc_inuse(&malloc_hist_1);
3544 if (argv[1][0] == '/') {
3545 config_dir = stralloc(argv[1]);
3546 config_name = strrchr(config_dir, '/') + 1;
3547 config_name[-1] = '\0';
3548 config_dir = newstralloc2(config_dir, config_dir, "/");
3550 config_name = stralloc(argv[1]);
3551 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
3554 char my_cwd[STR_SIZE];
3556 if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
3557 error("cannot determine current working directory");
3559 config_dir = stralloc2(my_cwd, "/");
3560 if ((config_name = strrchr(my_cwd, '/')) != NULL) {
3561 config_name = stralloc(config_name + 1);
3565 conffile = stralloc2(config_dir, CONFFILE_NAME);
3566 result = read_conffile(conffile);
3568 diskfile = getconf_str(CNF_DISKFILE);
3569 if (diskfile != NULL && access(diskfile, R_OK) == 0) {
3570 result = read_diskfile(diskfile, &lst);
3573 dump_configuration(CONFFILE_NAME);
3576 malloc_size_2 = malloc_inuse(&malloc_hist_2);
3578 if(malloc_size_1 != malloc_size_2) {
3579 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
3588 generic_get_security_conf(string, arg)
3592 if(!string || !*string)
3595 if(strcmp(string, "krb5principal")==0) {
3596 return(getconf_str(CNF_KRB5PRINCIPAL));
3597 } else if(strcmp(string, "krb5keytab")==0) {
3598 return(getconf_str(CNF_KRB5KEYTAB));