* University of Maryland at College Park
*/
/*
- * $Id: diskfile.c,v 1.27.4.6.4.3.2.15 2003/12/16 22:36:45 martinea Exp $
+ * $Id: diskfile.c,v 1.95 2006/07/26 15:17:37 martinea Exp $
*
* read disklist file
*/
#include "arglist.h"
#include "conffile.h"
#include "diskfile.h"
+#include "util.h"
-
-static disklist_t lst;
-static FILE *diskf;
-static char *diskfname = NULL;
-static host_t *hostlist;
-static int line_num, got_parserror;
+static am_host_t *hostlist;
/* local functions */
-static char *upcase P((char *st));
-static int read_diskline P((void));
-static void parserror P((char *format, ...))
- __attribute__ ((format (printf, 1, 2)));
+static char *upcase(char *st);
+static int parse_diskline(disklist_t *, const char *, FILE *, int *, char **);
+static void disk_parserror(const char *, int, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
-disklist_t *read_diskfile(filename)
-char *filename;
+int
+read_diskfile(
+ const char *filename,
+ disklist_t *lst)
{
- extern int errno;
+ FILE *diskf;
+ int line_num;
+ char *line;
/* initialize */
-
hostlist = NULL;
- lst.head = lst.tail = NULL;
- diskfname = newstralloc(diskfname, filename);
- malloc_mark(diskfname);
- line_num = got_parserror = 0;
+ lst->head = lst->tail = NULL;
+ line_num = 0;
- if((diskf = fopen(filename, "r")) == NULL)
- error("could not open disklist file \"%s\": %s",
- filename, strerror(errno));
+ if ((diskf = fopen(filename, "r")) == NULL) {
+ return -1;
+ /*NOTREACHED*/
+ }
- while(read_diskline());
- afclose(diskf);
+ while ((line = agets(diskf)) != NULL) {
+ line_num++;
+ if (line[0] != '\0') {
+ if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
+ amfree(line);
+ afclose(diskf);
+ return (-1);
+ }
+ }
+ amfree(line);
+ }
- if(got_parserror) return NULL;
- else return &lst;
+ afclose(diskf);
+ return (0);
}
-host_t *lookup_host(hostname)
-char *hostname;
+am_host_t *
+lookup_host(
+ const char *hostname)
{
- host_t *p;
+ am_host_t *p;
- for(p = hostlist; p != NULL; p = p->next) {
+ for (p = hostlist; p != NULL; p = p->next) {
if(strcasecmp(p->hostname, hostname) == 0) return p;
}
- return NULL;
+ return (NULL);
}
-disk_t *lookup_disk(hostname, diskname)
-char *hostname, *diskname;
+disk_t *
+lookup_disk(
+ const char *hostname,
+ const char *diskname)
{
- host_t *host;
+ am_host_t *host;
disk_t *disk;
host = lookup_host(hostname);
- if(host == NULL) return NULL;
+ if (host == NULL)
+ return (NULL);
- for(disk = host->disks; disk != NULL; disk = disk->hostnext) {
- if(strcmp(disk->name, diskname) == 0) return disk;
+ for (disk = host->disks; disk != NULL; disk = disk->hostnext) {
+ if (strcmp(disk->name, diskname) == 0)
+ return (disk);
}
- return NULL;
+ return (NULL);
}
-void enqueue_disk(list, disk) /* put disk on end of queue */
-disklist_t *list;
-disk_t *disk;
+
+/*
+ * put disk on end of queue
+ */
+
+void
+enqueue_disk(
+ disklist_t *list,
+ disk_t * disk)
{
if(list->tail == NULL) list->head = disk;
else list->tail->next = disk;
disk->next = NULL;
}
-void headqueue_disk(list, disk) /* put disk on head of queue */
-disklist_t *list;
-disk_t *disk;
+
+/*
+ * put disk on head of queue
+ */
+
+void
+headqueue_disk(
+ disklist_t *list,
+ disk_t * disk)
{
if(list->head == NULL) list->tail = disk;
else list->head->prev = disk;
disk->prev = NULL;
}
-void insert_disk(list, disk, cmp) /* insert in sorted order */
-disklist_t *list;
-disk_t *disk;
-int (*cmp) P((disk_t *a, disk_t *b));
+
+/*
+ * insert in sorted order
+ */
+
+void
+insert_disk(
+ disklist_t *list,
+ disk_t * disk,
+ int (*cmp)(disk_t *a, disk_t *b))
{
disk_t *prev, *ptr;
else ptr->prev = disk;
}
-disk_t *add_disk(hostname, diskname)
-char *hostname;
-char *diskname;
+disk_t *
+add_disk(
+ disklist_t *list,
+ char * hostname,
+ char * diskname)
{
disk_t *disk;
- host_t *host;
+ am_host_t *host;
- disk = alloc(sizeof(disk_t));
+ disk = alloc(SIZEOF(disk_t));
disk->line = 0;
+ disk->tape_splitsize = (off_t)0;
+ disk->split_diskbuffer = NULL;
+ disk->fallback_splitsize = (off_t)0;
+ disk->hostname = stralloc(hostname);
disk->name = stralloc(diskname);
disk->device = stralloc(diskname);
disk->spindle = -1;
disk->up = NULL;
disk->compress = COMP_NONE;
+ disk->encrypt = ENCRYPT_NONE;
disk->start_t = 0;
disk->todo = 1;
+ disk->index = 1;
+ disk->exclude_list = NULL;
+ disk->exclude_file = NULL;
+ disk->include_list = NULL;
+ disk->include_file = NULL;
host = lookup_host(hostname);
if(host == NULL) {
- host = alloc(sizeof(host_t));
+ host = alloc(SIZEOF(am_host_t));
host->next = hostlist;
hostlist = host;
host->up = NULL;
host->features = NULL;
}
- enqueue_disk(&lst, disk);
+ enqueue_disk(list, disk);
disk->host = host;
disk->hostnext = host->disks;
return disk;
}
-int find_disk(list, disk)
-disklist_t *list;
-disk_t *disk;
-/* check if disk is present in list. Return true if so, false otherwise. */
-{
-disk_t *t;
- for( t = list->head; t && t != disk; t = t->next );
+/*
+ * check if disk is present in list. Return true if so, false otherwise.
+ */
+
+int
+find_disk(
+ disklist_t *list,
+ disk_t * disk)
+{
+ disk_t *t;
- return t == disk;
+ t = list->head;
+ while ((t != NULL) && (t != disk)) {
+ t = t->next;
+ }
+ return (t == disk);
}
-void sort_disk(in, out, cmp) /* sort a whole queue */
-disklist_t *in;
-disklist_t *out;
-int (*cmp) P((disk_t *a, disk_t *b));
+
+/*
+ * sort a whole queue
+ */
+
+void
+sort_disk(
+ disklist_t *in,
+ disklist_t *out,
+ int (*cmp)(disk_t *a, disk_t *b))
{
disklist_t *tmp;
disk_t *disk;
insert_disk(out, disk, cmp);
}
-disk_t *dequeue_disk(list) /* remove disk from front of queue */
-disklist_t *list;
+
+/*
+ * remove disk from front of queue
+ */
+
+disk_t *
+dequeue_disk(
+ disklist_t *list)
{
disk_t *disk;
return disk;
}
-void remove_disk(list, disk)
-disklist_t *list;
-disk_t *disk;
+void
+remove_disk(
+ disklist_t *list,
+ disk_t * disk)
{
if(disk->prev == NULL) list->head = disk->next;
else disk->prev->next = disk->next;
disk->prev = disk->next = NULL;
}
-static char *upcase(st)
-char *st;
+void
+free_disklist(
+ disklist_t* dl)
+{
+ disk_t *dp;
+ am_host_t *host, *hostnext;
+
+ while (dl->head != NULL) {
+ dp = dequeue_disk(dl);
+ amfree(dp->name);
+ free_sl(dp->exclude_file);
+ free_sl(dp->exclude_list);
+ free_sl(dp->include_file);
+ free_sl(dp->include_list);
+ free(dp);
+ }
+
+ for(host=hostlist; host != NULL; host = hostnext) {
+ amfree(host->hostname);
+ am_release_feature_set(host->features);
+ host->features = NULL;
+ hostnext = host->next;
+ amfree(host);
+ }
+ hostlist=NULL;
+}
+
+static char *
+upcase(
+ char *st)
{
char *s = st;
while(*s) {
- if(islower((int)*s)) *s = toupper(*s);
+ if(islower((int)*s)) *s = (char)toupper((int)*s);
s++;
}
return st;
}
-static int read_diskline()
+/* return 0 on success */
+/* return -1 on error */
+static int
+parse_diskline(
+ disklist_t *lst,
+ const char *filename,
+ FILE * diskf,
+ int * line_num_p,
+ /*@keep@*/ char ** line_p)
{
- host_t *host;
+ am_host_t *host;
disk_t *disk;
dumptype_t *dtype;
interface_t *netif = 0;
char *hostname = NULL;
char *diskname, *diskdevice;
- static char *line = NULL;
- char *s = NULL, *fp;
- int ch = '\0', dup = 0;
- char *dn;
-
- amfree(line);
- for(; (line = agets(diskf)) != NULL; free(line)) {
- line_num += 1;
- s = line;
- ch = *s++;
+ char *dumptype;
+ char *s, *fp;
+ int ch, dup = 0;
+ char *line = *line_p;
+ int line_num = *line_num_p;
+ struct tm *stm;
+ time_t st;
+ char *shost, *sdisk;
+ am_host_t *p;
+ disk_t *dp;
- skip_whitespace(s, ch);
- if(ch != '\0' && ch != '#') break;
- }
- if(line == NULL) return 0;
+ assert(filename != NULL);
+ assert(line_num > 0);
+ assert(line != NULL);
+
+ s = line;
+ ch = *s++;
+ skip_whitespace(s, ch);
+ if(ch == '\0' || ch == '#')
+ return (0);
fp = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
host = lookup_host(fp);
if (host == NULL) {
- hostname = stralloc(fp);
- malloc_mark(hostname);
+ hostname = stralloc(fp);
+ malloc_mark(hostname);
} else {
- hostname = host->hostname;
+ hostname = stralloc(host->hostname);
+ if (strcmp(host->hostname, fp) != 0) {
+ disk_parserror(filename, line_num, "Same host with different case: \"%s\" and \"%s\".", host->hostname, fp);
+ return -1;
+ }
+ }
+
+ shost = sanitise_filename(hostname);
+ for (p = hostlist; p != NULL; p = p->next) {
+ char *shostp = sanitise_filename(p->hostname);
+ if (!strcmp(hostname, p->hostname) &&
+ strcmp(shost, shostp)) {
+ disk_parserror(filename, line_num, "Two host are mapping to the same name: \"%s\" and \"%s\"", p->hostname, hostname);
+ return(-1);
+ }
+ else if (strcasecmp(hostname, p->hostname) &&
+ match_host(hostname, p->hostname) &&
+ match_host(p->hostname, hostname)) {
+ disk_parserror(filename, line_num, "Duplicate host name: \"%s\" and \"%s\"", p->hostname, hostname);
+ return(-1);
+ }
+ amfree(shostp);
}
+ amfree(shost);
skip_whitespace(s, ch);
if(ch == '\0' || ch == '#') {
- parserror("disk device name expected");
- return 1;
+ disk_parserror(filename, line_num, "disk device name expected");
+ amfree(hostname);
+ return (-1);
}
+
fp = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- diskname = stralloc(fp);
+ diskname = unquote_string(fp);
skip_whitespace(s, ch);
if(ch == '\0' || ch == '#') {
- parserror("disk dumptype expected");
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num, "disk dumptype expected");
+ amfree(hostname);
amfree(diskname);
- return 1;
+ return (-1);
}
fp = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
/* diskdevice */
- dn = stralloc(fp);
- if(fp[0] != '{' && (dtype = lookup_dumptype(upcase(fp))) == NULL) {
- diskdevice = dn;
- skip_whitespace(s, ch);
- if(ch == '\0' || ch == '#') {
- parserror("disk dumptype expected");
- if(host == NULL) amfree(hostname);
- amfree(diskname);
- amfree(diskdevice);
- return 1;
+ dumptype = NULL;
+ diskdevice = NULL;
+ if(fp[0] != '{') {
+ dumptype = unquote_string(fp);
+ if ((dtype = lookup_dumptype(dumptype)) == NULL) {
+ diskdevice = dumptype;
+ skip_whitespace(s, ch);
+ if(ch == '\0' || ch == '#') {
+ disk_parserror(filename, line_num,
+ "disk dumptype '%s' not found", dumptype);
+ amfree(hostname);
+ amfree(diskdevice);
+ amfree(diskname);
+ return (-1);
+ }
+
+ fp = s - 1;
+ skip_quoted_string(s, ch);
+ s[-1] = '\0';
+ if (fp[0] != '{') {
+ dumptype = unquote_string(fp);
+ }
}
- fp = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- }
- else {
- diskdevice = NULL;
- amfree(dn);
}
/* check for duplicate disk */
- if(host && (disk = lookup_disk(hostname, diskname)) != NULL) {
- parserror("duplicate disk record, previous on line %d", disk->line);
- dup = 1;
- } else {
- disk = alloc(sizeof(disk_t));
+ disk = NULL;
+ if (host) {
+ if ((disk = lookup_disk(hostname, diskname)) != NULL) {
+ dup = 1;
+ } else {
+ disk = host->disks;
+ do {
+ if (match_disk(diskname, disk->name) &&
+ match_disk(disk->name, diskname)) {
+ dup = 1;
+ } else {
+ disk = disk->hostnext;
+ }
+ }
+ while (dup == 0 && disk != NULL);
+ }
+ if (dup == 1) {
+ disk_parserror(filename, line_num,
+ "duplicate disk record, previous on line %d",
+ disk->line);
+ }
+ }
+ if (!disk) {
+ disk = alloc(SIZEOF(disk_t));
malloc_mark(disk);
disk->line = line_num;
+ disk->hostname = stralloc(hostname);
disk->name = diskname;
disk->device = diskdevice;
malloc_mark(disk->name);
disk->inprogress = 0;
}
+ if (host) {
+ sdisk = sanitise_filename(diskname);
+ for (dp = host->disks; dp != NULL; dp = dp->next) {
+ char *sdiskp = sanitise_filename(dp->name);
+ if (strcmp(diskname, dp->name) != 0 &&
+ strcmp(sdisk, sdiskp) == 0) {
+ disk_parserror(filename, line_num,
+ "Two disk are mapping to the same name: \"%s\" and \"%s\""
+ ", you must use different diskname",
+ dp->name, diskname);
+ return(-1);
+ }
+ amfree(sdiskp);
+ }
+ amfree(sdisk);
+ }
+
if (fp[0] == '{') {
- s[-1] = ch;
+ s[-1] = (char)ch;
s = fp+2;
skip_whitespace(s, ch);
if (ch != '\0' && ch != '#') {
- parserror("expected line break after `{\', ignoring rest of line");
+ disk_parserror(filename, line_num,
+ "expected line break after `{\', ignoring rest of line");
}
if (strchr(s-1, '}') &&
(strchr(s-1, '#') == NULL ||
strchr(s-1, '}') < strchr(s-1, '#'))) {
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num,"'}' on same line than '{'");
+ amfree(hostname);
if(!dup) {
+ amfree(disk->device);
amfree(disk->name);
amfree(disk);
+ } else {
+ amfree(diskdevice);
+ amfree(diskname);
}
- return 1;
+ return (-1);
}
- amfree(line);
-
dtype = read_dumptype(vstralloc("custom(", hostname,
- ":", disk->name, ")", 0),
- diskf, diskfname, &line_num);
-
- line = agets(diskf);
- /* line_num += 1; */ /* read_dumptype did it already */
-
+ ":", disk->name, ")", NULL),
+ diskf, (char*)filename, line_num_p);
if (dtype == NULL || dup) {
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num,
+ "read of custom dumptype failed");
+ amfree(hostname);
if(!dup) {
- amfree(disk->name);
- amfree(disk);
+ amfree(disk->device);
+ amfree(disk->name);
+ amfree(disk);
+ } else {
+ amfree(diskdevice);
+ amfree(diskname);
}
- return line != NULL;
+ return (-1);
}
+ amfree(line);
+
+ *line_p = line = agets(diskf);
+ line_num = *line_num_p; /* no incr, read_dumptype did it already */
if (line == NULL)
- line = stralloc("");
+ *line_p = line = stralloc("");
s = line;
ch = *s++;
- } else if((dtype = lookup_dumptype(upcase(fp))) == NULL) {
- parserror("undefined dumptype `%s'", fp);
- if(host == NULL) amfree(hostname);
- if(!dup) {
- amfree(disk->name);
- amfree(disk);
+ } else {
+ if((dtype = lookup_dumptype(dumptype)) == NULL) {
+ char *qdt = quote_string(dumptype);
+
+ disk_parserror(filename, line_num, "undefined dumptype `%s'", qdt);
+ amfree(qdt);
+ amfree(dumptype);
+ amfree(hostname);
+ if (!dup) {
+ amfree(disk->device);
+ amfree(disk->name);
+ amfree(disk);
+ } else {
+ amfree(diskdevice);
+ amfree(diskname);
+ }
+ return (-1);
}
- return 1;
}
if (dup) {
- if(host == NULL) amfree(hostname);
- return 1;
+ amfree(hostname);
+ amfree(diskdevice);
+ amfree(diskname);
+ return (-1);
}
- disk->dtype_name = dtype->name;
- disk->program = dtype->program;
- disk->exclude_file = duplicate_sl(dtype->exclude_file);
- disk->exclude_list = duplicate_sl(dtype->exclude_list);
- disk->include_file = duplicate_sl(dtype->include_file);
- disk->include_list = duplicate_sl(dtype->include_list);
- disk->exclude_optional = dtype->exclude_optional;
- disk->include_optional = dtype->include_optional;
- disk->priority = dtype->priority;
- disk->dumpcycle = dtype->dumpcycle;
- disk->frequency = dtype->frequency;
- disk->auth = dtype->auth;
- disk->maxdumps = dtype->maxdumps;
- disk->maxpromoteday = dtype->maxpromoteday;
- disk->start_t = dtype->start_t;
- disk->strategy = dtype->strategy;
- disk->compress = dtype->compress;
- disk->comprate[0] = dtype->comprate[0];
- disk->comprate[1] = dtype->comprate[1];
- disk->record = dtype->record;
- disk->skip_incr = dtype->skip_incr;
- disk->skip_full = dtype->skip_full;
- disk->no_hold = dtype->no_hold;
- disk->kencrypt = dtype->kencrypt;
- disk->index = dtype->index;
- disk->todo = 1;
+ disk->dtype_name = dtype->name;
+ disk->program = dumptype_get_program(dtype);
+ disk->exclude_list = duplicate_sl(dumptype_get_exclude(dtype).sl_list);
+ disk->exclude_file = duplicate_sl(dumptype_get_exclude(dtype).sl_file);
+ disk->exclude_optional = dumptype_get_exclude(dtype).optional;
+ disk->include_list = duplicate_sl(dumptype_get_include(dtype).sl_list);
+ disk->include_file = duplicate_sl(dumptype_get_include(dtype).sl_file);
+ disk->include_optional = dumptype_get_include(dtype).optional;
+ disk->priority = dumptype_get_priority(dtype);
+ disk->dumpcycle = dumptype_get_dumpcycle(dtype);
+/* disk->frequency = dumptype_get_frequency(dtype);*/
+ disk->security_driver = dumptype_get_security_driver(dtype);
+ disk->maxdumps = dumptype_get_maxdumps(dtype);
+ disk->tape_splitsize = dumptype_get_tape_splitsize(dtype);
+ disk->split_diskbuffer = dumptype_get_split_diskbuffer(dtype);
+ disk->fallback_splitsize = dumptype_get_fallback_splitsize(dtype);
+ disk->maxpromoteday = dumptype_get_maxpromoteday(dtype);
+ disk->bumppercent = dumptype_get_bumppercent(dtype);
+ disk->bumpsize = dumptype_get_bumpsize(dtype);
+ disk->bumpdays = dumptype_get_bumpdays(dtype);
+ disk->bumpmult = dumptype_get_bumpmult(dtype);
+ disk->starttime = dumptype_get_starttime(dtype);
+ disk->start_t = 0;
+ if (disk->starttime > 0) {
+ st = time(NULL);
+ disk->start_t = st;
+ stm = localtime(&st);
+ disk->start_t -= stm->tm_sec + 60 * stm->tm_min + 3600 * stm->tm_hour;
+ disk->start_t += disk->starttime / 100 * 3600 +
+ disk->starttime % 100 * 60;
+ if ((disk->start_t - st) < -43200)
+ disk->start_t += 86400;
+ }
+ disk->strategy = dumptype_get_strategy(dtype);
+ disk->ignore = dumptype_get_ignore(dtype);
+ disk->estimate = dumptype_get_estimate(dtype);
+ disk->compress = dumptype_get_compress(dtype);
+ disk->srvcompprog = dumptype_get_srvcompprog(dtype);
+ disk->clntcompprog = dumptype_get_clntcompprog(dtype);
+ disk->encrypt = dumptype_get_encrypt(dtype);
+ disk->srv_decrypt_opt = dumptype_get_srv_decrypt_opt(dtype);
+ disk->clnt_decrypt_opt = dumptype_get_clnt_decrypt_opt(dtype);
+ disk->srv_encrypt = dumptype_get_srv_encrypt(dtype);
+ disk->clnt_encrypt = dumptype_get_clnt_encrypt(dtype);
+ disk->amandad_path = dumptype_get_amandad_path(dtype);
+ disk->client_username = dumptype_get_client_username(dtype);
+ disk->ssh_keys = dumptype_get_ssh_keys(dtype);
+ disk->comprate[0] = dumptype_get_comprate(dtype)[0];
+ disk->comprate[1] = dumptype_get_comprate(dtype)[1];
+
+ /*
+ * Boolean parameters with no value (Appears here as value 2) defaults
+ * to TRUE for backward compatibility and for logical consistency.
+ */
+ disk->record = dumptype_get_record(dtype) != 0;
+ disk->skip_incr = dumptype_get_skip_incr(dtype) != 0;
+ disk->skip_full = dumptype_get_skip_full(dtype) != 0;
+ disk->to_holdingdisk = dumptype_get_to_holdingdisk(dtype);
+ disk->kencrypt = dumptype_get_kencrypt(dtype) != 0;
+ disk->index = dumptype_get_index(dtype) != 0;
+
+ disk->todo = 1;
skip_whitespace(s, ch);
fp = s - 1;
if(ch && ch != '#') { /* get optional spindle number */
+ char *fp1;
+ int is_digit=1;
+
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ fp1=fp;
+ if (*fp1 == '-') fp1++;
+ for(;*fp1!='\0';fp1++) {
+ if(!isdigit((int)*fp1)) {
+ is_digit = 0;
+ }
+ }
+ if(is_digit == 0) {
+ disk_parserror(filename, line_num, "non-integer spindle `%s'", fp);
+ amfree(hostname);
+ amfree(disk->name);
+ amfree(disk);
+ return (-1);
+ }
disk->spindle = atoi(fp);
skip_integer(s, ch);
}
skip_non_whitespace(s, ch);
s[-1] = '\0';
if((netif = lookup_interface(upcase(fp))) == NULL) {
- parserror("undefined network interface `%s'", fp);
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num,
+ "undefined network interface `%s'", fp);
+ amfree(hostname);
amfree(disk->name);
amfree(disk);
- return 1;
+ return (-1);
}
} else {
- netif = lookup_interface("");
+ netif = lookup_interface("default");
}
skip_whitespace(s, ch);
if(ch && ch != '#') { /* now we have garbage, ignore it */
- parserror("end of line expected");
+ disk_parserror(filename, line_num, "end of line expected");
}
- if(dtype->ignore || dtype->strategy == DS_SKIP) {
- amfree(diskname);
- free_sl(disk->exclude_file);
- free_sl(disk->exclude_list);
- free_sl(disk->include_file);
- free_sl(disk->include_list);
- amfree(disk);
- return 1;
+ if(dumptype_get_ignore(dtype) || dumptype_get_strategy(dtype) == DS_SKIP) {
+ disk->todo = 0;
}
/* success, add disk to lists */
if(host == NULL) { /* new host */
- host = alloc(sizeof(host_t));
+ host = alloc(SIZEOF(am_host_t));
malloc_mark(host);
host->next = hostlist;
hostlist = host;
host->start_t = 0;
host->up = NULL;
host->features = NULL;
+ } else {
+ amfree(hostname);
}
host->netif = netif;
- enqueue_disk(&lst, disk);
+ enqueue_disk(lst, disk);
disk->host = host;
disk->hostnext = host->disks;
host->disks = disk;
host->maxdumps = disk->maxdumps;
- return 1;
+ return (0);
}
-printf_arglist_function(static void parserror, char *, format)
+printf_arglist_function2(void disk_parserror, const char *, filename,
+ int, line_num, const char *, format)
{
va_list argp;
/* print error message */
- fprintf(stderr, "\"%s\", line %d: ", diskfname, line_num);
+ fprintf(stderr, "\"%s\", line %d: ", filename, line_num);
arglist_start(argp, format);
vfprintf(stderr, format, argp);
arglist_end(argp);
fputc('\n', stderr);
-
- got_parserror = 1;
}
-void dump_queue(st, q, npr, f)
-char *st;
-disklist_t q;
-int npr; /* we print first npr disks on queue, plus last two */
-FILE *f;
+void
+dump_queue(
+ char * st,
+ disklist_t q,
+ int npr, /* we print first npr disks on queue, plus last two */
+ FILE * f)
{
disk_t *d,*p;
int pos;
+ char *qname;
if(empty(q)) {
fprintf(f, "%s QUEUE: empty\n", st);
}
fprintf(f, "%s QUEUE:\n", st);
for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
+ qname = quote_string(d->name);
if(pos < npr) fprintf(f, "%3d: %-10s %-4s\n",
- pos, d->host->hostname, d->name);
+ pos, d->host->hostname, qname);
+ amfree(qname);
}
if(pos > npr) {
if(pos > npr+2) fprintf(f, " ...\n");
}
}
-char *optionstr(dp, their_features, fdout)
-disk_t *dp;
-am_feature_t * their_features;
-FILE *fdout;
+char *
+optionstr(
+ disk_t * dp,
+ am_feature_t * their_features,
+ FILE * fdout)
{
char *auth_opt = NULL;
char *kencrypt_opt = "";
char *compress_opt = "";
+ char *encrypt_opt = stralloc("");
+ char *decrypt_opt = stralloc("");
char *record_opt = "";
char *index_opt = "";
char *exclude_file = NULL;
sle_t *excl;
int nb_exclude_file;
int nb_include_file;
-
- /* modification by BIS@BBN 4/25/2003:
- * The first "if" statement has a number of problems, so I removed the
- * am_has_feature(dp->host->features, fe_options_auth)
- * condition and caused the first case to always fail.
- * 1) If dp->host is a NULL pointer, subsequent tests which look
- * at dp->host->features or dp->host->hostname will cause a dump.
- * It appears that there should be an assertion that dp->host
- * is NOT NULL.
- * 2) The code which checks for the kencrypt feature is only executed
- * in the case where dp->auth == AUTH_KRB4. If we enable Kerberos IV
- * in the first case, then the code checking for kencrypt will never
- * be executed.
- * 3) The option processing code in server-src/dumper.c and
- * client-src/sendbackup.c do not yet handle the "auth=krb4"
- * option style of specifying Kerberos IV.
- * Getting rid of the whole first case seems to take care of problems
- * 2 and 3, but not problem 1.
- */
- if(dp->host && 0)
- /* && am_has_feature(dp->host->features, fe_options_auth)) */ {
- auth_opt = stralloc("auth=");
- if(dp->auth == AUTH_BSD) {
- strappend(auth_opt, "bsd");
- } else if(dp->auth == AUTH_KRB4) {
- strappend(auth_opt, "krb4");
- } else {
- strappend(auth_opt, "unknown");
- }
- strappend(auth_opt, ";");
- } else if(dp->auth == AUTH_BSD) {
- if(am_has_feature(dp->host->features, fe_options_bsd_auth)) {
+ char *qdpname;
+ char *qname;
+ int err=0;
+
+ assert(dp != NULL);
+ assert(dp->host != NULL);
+
+ qdpname = quote_string(dp->name);
+ if(am_has_feature(dp->host->features, fe_options_auth)) {
+ auth_opt = vstralloc("auth=", dp->security_driver, ";", NULL);
+ } else if(strcasecmp(dp->security_driver, "bsd") == 0) {
+ if(am_has_feature(dp->host->features, fe_options_bsd_auth))
auth_opt = stralloc("bsd-auth;");
- }
else if(fdout) {
- fprintf(fdout, "WARNING: %s:%s does not support bsd-auth\n",
- dp->host->hostname, dp->name);
+ fprintf(fdout,
+ "WARNING: %s:%s does not support auth or bsd-auth\n",
+ dp->host->hostname, qdpname);
}
- } else if(dp->auth == AUTH_KRB4) {
- if(am_has_feature(dp->host->features, fe_options_krb4_auth)) {
+ } else if(strcasecmp(dp->security_driver, "krb4") == 0) {
+ if(am_has_feature(dp->host->features, fe_options_krb4_auth))
auth_opt = stralloc("krb4-auth;");
- }
else if(fdout) {
- fprintf(fdout, "WARNING: %s:%s does not support krb4-auth\n",
- dp->host->hostname, dp->name);
+ fprintf(fdout,
+ "WARNING: %s:%s does not support auth or krb4-auth\n",
+ dp->host->hostname, qdpname);
}
if(dp->kencrypt) {
if(am_has_feature(dp->host->features, fe_options_kencrypt)) {
kencrypt_opt = "kencrypt;";
}
else if(fdout) {
- fprintf(fdout,
- "WARNING: %s:%s does not support kencrypt\n",
- dp->host->hostname, dp->name);
+ fprintf(fdout,
+ "WARNING: %s:%s does not support kencrypt\n",
+ dp->host->hostname, qdpname);
}
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support fast compression\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
break;
case COMP_BEST:
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support best compression\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
+ }
+ break;
+ case COMP_CUST:
+ if(am_has_feature(their_features, fe_options_compress_cust)) {
+ compress_opt = vstralloc("comp-cust=", dp->clntcompprog, ";", NULL);
+ if (BSTRNCMP(compress_opt, "comp-cust=;") == 0){
+ if(fdout) {
+ fprintf(fdout,
+ "ERROR: %s:%s client custom compression with no compression program specified\n",
+ dp->host->hostname, qdpname);
+ }
+ err++;
+ }
+ }
+ else if(fdout) {
+ fprintf(fdout,
+ "WARNING: %s:%s does not support client custom compression\n",
+ dp->host->hostname, qdpname);
}
break;
- case COMP_SERV_FAST:
+ case COMP_SERVER_FAST:
if(am_has_feature(their_features, fe_options_srvcomp_fast)) {
compress_opt = "srvcomp-fast;";
}
break;
- case COMP_SERV_BEST:
+ case COMP_SERVER_BEST:
if(am_has_feature(their_features, fe_options_srvcomp_best)) {
compress_opt = "srvcomp-best;";
}
break;
+ case COMP_SERVER_CUST:
+ if(am_has_feature(their_features, fe_options_srvcomp_cust)) {
+ compress_opt = vstralloc("srvcomp-cust=", dp->srvcompprog, ";", NULL);
+ if (BSTRNCMP(compress_opt, "srvcomp-cust=;") == 0){
+ if(fdout) {
+ fprintf(fdout,
+ "ERROR: %s:%s server custom compression with no compression program specified\n",
+ dp->host->hostname, qdpname);
+ }
+ err++;
+ }
+ }
+ else if(fdout) {
+ fprintf(fdout,
+ "WARNING: %s:%s does not support server custom compression\n",
+ dp->host->hostname, qdpname);
+ }
+ break;
}
+ switch(dp->encrypt) {
+ case ENCRYPT_CUST:
+ if(am_has_feature(their_features, fe_options_encrypt_cust)) {
+ encrypt_opt = newvstralloc(encrypt_opt, "encrypt-cust=",
+ dp->clnt_encrypt, ";", NULL);
+ if (BSTRNCMP(encrypt_opt, "encrypt-cust=;") == 0) {
+ if(fdout) {
+ fprintf(fdout,
+ "ERROR: %s:%s encrypt client with no encryption program specified\n",
+ dp->host->hostname, qdpname);
+ }
+ err++;
+ }
+ if ( dp->compress == COMP_SERVER_FAST ||
+ dp->compress == COMP_SERVER_BEST ||
+ dp->compress == COMP_SERVER_CUST ) {
+ if(fdout) {
+ fprintf(fdout,
+ "ERROR: %s:Client encryption with server compression is not supported. See amanda.conf(5) for detail.\n", dp->host->hostname);
+ }
+ err++;
+ }
+ if(dp->clnt_decrypt_opt) {
+ if(am_has_feature(their_features, fe_options_client_decrypt_option)) {
+ decrypt_opt = newvstralloc(decrypt_opt, "client-decrypt-option=",
+ dp->clnt_decrypt_opt, ";", NULL);
+ }
+ else if(fdout) {
+ fprintf(fdout,
+ "WARNING: %s:%s does not support client decrypt option\n",
+ dp->host->hostname, qdpname);
+ }
+ }
+ }
+ else if(fdout) {
+ fprintf(fdout,
+ "WARNING: %s:%s does not support client data encryption\n",
+ dp->host->hostname, qdpname);
+ }
+ break;
+ case ENCRYPT_SERV_CUST:
+ if(am_has_feature(their_features, fe_options_encrypt_serv_cust)) {
+ encrypt_opt = newvstralloc(encrypt_opt, "encrypt-serv-cust=",
+ dp->srv_encrypt, ";", NULL);
+ if (BSTRNCMP(encrypt_opt, "encrypt-serv-cust=;") == 0){
+ if(fdout) {
+ fprintf(fdout,
+ "ERROR: %s:%s encrypt server with no encryption program specified\n",
+ dp->host->hostname, qdpname);
+ }
+ err++;
+ }
+ if(dp->srv_decrypt_opt) {
+ if(am_has_feature(their_features, fe_options_server_decrypt_option)) {
+ decrypt_opt = newvstralloc(decrypt_opt, "server-decrypt-option=",
+ dp->srv_decrypt_opt, ";", NULL);
+ }
+ else if(fdout) {
+ fprintf(fdout,
+ "WARNING: %s:%s does not support server decrypt option\n",
+ dp->host->hostname, qdpname);
+ }
+ }
+ }
+ else if(fdout) {
+ fprintf(fdout,
+ "WARNING: %s:%s does not support server data encryption\n",
+ dp->host->hostname, qdpname);
+ }
+ break;
+ }
+
if(!dp->record) {
if(am_has_feature(their_features, fe_options_no_record)) {
record_opt = "no-record;";
}
else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support no record\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
}
else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support index\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
+ if(dp->kencrypt) kencrypt_opt = "kencrypt;";
+
+
exclude_file = stralloc("");
nb_exclude_file = 0;
if(dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
dp->exclude_file->nb_element == 1) {
for(excl = dp->exclude_file->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "exclude-file=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc( exc, "exclude-file=", qname, ";", NULL);
strappend(exclude_file, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "exclude-file=",
- dp->exclude_file->last->name, ";", NULL);
+ qname = quote_string(dp->exclude_file->last->name);
+ exc = newvstralloc(exc, "exclude-file=", qname, ";", NULL);
strappend(exclude_file, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple exclude\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support exclude file\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
exclude_list = stralloc("");
(dp->exclude_list->nb_element == 1 && nb_exclude_file == 0)) {
for(excl = dp->exclude_list->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "exclude-list=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc( exc, "exclude-list=", qname, ";", NULL);
strappend(exclude_list, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "exclude-list=",
- dp->exclude_list->last->name, ";", NULL);
+ qname = quote_string(dp->exclude_list->last->name);
+ exc = newvstralloc(exc, "exclude-list=", qname, ";", NULL);
strappend(exclude_list, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple exclude\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support exclude list\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
dp->include_file->nb_element == 1) {
for(excl = dp->include_file->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "include-file=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
strappend(include_file, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "include-file=",
- dp->include_file->last->name, ";", NULL);
+ qname = quote_string(dp->include_file->last->name);
+ exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
strappend(include_file, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple include\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support include file\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
include_list = stralloc("");
(dp->include_list->nb_element == 1 && nb_include_file == 0)) {
for(excl = dp->include_list->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "include-list=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
strappend(include_list, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "include-list=",
- dp->include_list->last->name, ";", NULL);
+ qname = quote_string(dp->include_list->last->name);
+ exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
strappend(include_list, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple include\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support include list\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support optional exclude\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
if(dp->include_optional) {
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support optional include\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
auth_opt,
kencrypt_opt,
compress_opt,
+ encrypt_opt,
+ decrypt_opt,
record_opt,
index_opt,
exclude_file,
excl_opt,
incl_opt,
NULL);
+ amfree(qdpname);
amfree(auth_opt);
- amfree(exclude_file);
amfree(exclude_list);
+ amfree(exclude_file);
amfree(include_file);
amfree(include_list);
amfree(exc);
+ amfree(decrypt_opt);
+ amfree(encrypt_opt);
- return result;
+ /* result contains at least 'auth=...' */
+ if ( err ) {
+ amfree(result);
+ return NULL;
+ } else {
+ return result;
+ }
}
-void match_disklist(disklist_t *origqp, int sargc, char **sargv)
+char *
+match_disklist(
+ disklist_t *origqp,
+ int sargc,
+ char ** sargv)
{
char *prevhost = NULL;
+ char *errstr = NULL;
int i;
int match_a_host;
int match_a_disk;
disk_t *dp;
if(sargc <= 0)
- return;
+ return NULL;
for(dp = origqp->head; dp != NULL; dp = dp->next) {
if(dp->todo == 1)
(dp->device && match_disk(sargv[i], dp->device)))) {
if(match_a_host) {
error("Argument %s match a host and a disk",sargv[i]);
+ /*NOTREACHED*/
}
else {
if(dp->todo == -1) {
prev_match = 1;
}
else {
- prev_match = 0;
- /*error("%s match nothing",sargv[i]);*/
+ vstrextend(&errstr, "Argument '", sargv[i], "' match neither a host nor a disk.\n", NULL);
}
}
}
if(dp->todo == -1)
dp->todo = 0;
}
+
+ return errstr;
}
-
+
#ifdef TEST
-void
-dump_disk(dp)
-disk_t *dp;
+static void dump_disk(const disk_t *);
+static void dump_disklist(const disklist_t *);
+int main(int, char *[]);
+
+static void
+dump_disk(
+ const disk_t * dp)
{
printf(" DISK %s (HOST %s, LINE %d) TYPE %s NAME %s SPINDLE %d\n",
dp->name, dp->host->hostname, dp->line, dp->dtype_name,
dp->spindle);
}
-void
-dump_disklist()
+static void
+dump_disklist(
+ const disklist_t * lst)
{
- disk_t *dp, *prev;
- host_t *hp;
+ const disk_t *dp, *prev;
+ const am_host_t *hp;
if(hostlist == NULL) {
printf("DISKLIST not read in\n");
printf("DISKLIST IN FILE ORDER:\n");
prev = NULL;
- for(dp = lst.head; dp != NULL; prev = dp, dp = dp->next) {
+ for(dp = lst->head; dp != NULL; prev = dp, dp = dp->next) {
dump_disk(dp);
/* check pointers */
if(dp->prev != prev) printf("*** prev pointer mismatch!\n");
- if(dp->next == NULL && lst.tail != dp) printf("tail mismatch!\n");
+ if(dp->next == NULL && lst->tail != dp) printf("tail mismatch!\n");
}
}
int
-main(argc, argv)
-int argc;
-char *argv[];
+main(
+ int argc,
+ char ** argv)
{
char *conffile;
char *conf_diskfile;
+ disklist_t lst;
int result;
- int fd;
unsigned long malloc_hist_1, malloc_size_1;
unsigned long malloc_hist_2, malloc_size_2;
- for(fd = 3; fd < FD_SETSIZE; fd++) {
- /*
- * Make sure nobody spoofs us with a lot of extra open files
- * that would cause an open we do to get a very high file
- * descriptor, which in turn might be used as an index into
- * an array (e.g. an fd_set).
- */
- close(fd);
- }
+ safe_fd(-1, 0);
set_pname("diskfile");
+ dbopen(DBG_SUBDIR_SERVER);
+
+ /* Don't die when child closes pipe */
+ signal(SIGPIPE, SIG_IGN);
+
malloc_size_1 = malloc_inuse(&malloc_hist_1);
if (argc>1) {
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if((result = (read_diskfile(conf_diskfile) == NULL)) == 0) {
- dump_disklist();
+ result = read_diskfile(conf_diskfile, &lst);
+ if(result == 0) {
+ dump_disklist(&lst);
}
amfree(conf_diskfile);
}
return result;
}
-
#endif /* TEST */