Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndml_config.c
diff --git a/ndmp-src/ndml_config.c b/ndmp-src/ndml_config.c
new file mode 100644 (file)
index 0000000..74b8870
--- /dev/null
@@ -0,0 +1,645 @@
+/*
+ * Copyright (c) 1998,1999,2000
+ *     Traakan, Inc., Los Altos, CA
+ *     All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Project:  NDMJOB
+ * Ident:    $Id: $
+ *
+ * Description:
+ *
+ */
+
+
+#include "ndmlib.h"
+
+#define CFG_BUF_SIZE   512
+#define CFG_MAX_SV     32
+
+/* control block */
+struct cfg_cb {
+       FILE *                  fp;
+       ndmp9_config_info *     config_info;
+       char                    buf[CFG_BUF_SIZE];
+       char *                  sv[CFG_MAX_SV];
+       int                     sc;
+       int                     n_error;
+};
+
+
+static int     cfg_butype (struct cfg_cb *cb);
+static int     cfg_fs (struct cfg_cb *cb);
+static int     cfg_tape (struct cfg_cb *cb);
+static int     cfg_scsi (struct cfg_cb *cb);
+static int     cfg_device (struct cfg_cb *cb, u_int *n_device,
+                       ndmp9_device_info **pp);
+static int     cfg_add_env (struct cfg_cb *cb, u_int *n_env,
+                       ndmp9_pval **pp, char *name, char *value);
+
+
+
+
+int
+ndmcfg_load (char *filename, ndmp9_config_info *config_info)
+{
+       FILE *          fp;
+       int             rc;
+
+       fp = fopen (filename, "r");
+       if (!fp)
+               return -1;
+
+       rc = ndmcfg_loadfp (fp, config_info);
+
+       fclose (fp);
+
+       return rc;
+}
+
+int
+ndmcfg_loadfp (FILE *fp, ndmp9_config_info *config_info)
+{
+       struct cfg_cb   _cb, *cb = &_cb;
+       int             rc;
+
+       NDMOS_MACRO_ZEROFILL(cb);
+
+       cb->fp = fp;
+       cb->config_info = config_info;
+
+       for (;;) {
+               rc = ndmstz_getstanza (cb->fp, cb->buf, sizeof cb->buf);
+               if (rc == EOF) {
+                       break;
+               }
+
+               cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
+               if (cb->sc < 1) {
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "butype") == 0 && cb->sc == 2) {
+                       cfg_butype (cb);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "fs") == 0 && cb->sc == 2) {
+                       cfg_fs (cb);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "tape") == 0 && cb->sc == 2) {
+                       cfg_tape (cb);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "scsi") == 0 && cb->sc == 2) {
+                       cfg_scsi (cb);
+                       continue;
+               }
+
+               /*
+                * Unrecognized stanzas are deemed for other purposes
+                * and tolerated.
+                */
+       }
+
+       return cb->n_error;
+}
+
+/*
+ * [butype BUTYPE]
+ *     v2attr  0xATTR
+ *     v3attr  0xATTR
+ *     v4attr  0xATTR
+ *     default_env NAME VALUE
+ */
+
+static int
+cfg_butype (struct cfg_cb *cb)
+{
+       ndmp9_config_info *     cfg = cb->config_info;
+       ndmp9_butype_info *     ent = cfg->butype_info.butype_info_val;
+       int                     n_ent = cfg->butype_info.butype_info_len;
+       int                     i, rc;
+
+       if (!ent)
+               n_ent = 0;
+
+       ent = NDMOS_MACRO_NEWN(ndmp9_butype_info, n_ent+1);
+       if (!ent) {
+               cb->n_error++;
+               return -1;
+       }
+
+       for (i = 0; i < n_ent; i++) {
+               ent[i] = cfg->butype_info.butype_info_val[i];
+       }
+
+       if (cfg->butype_info.butype_info_val) {
+               NDMOS_API_FREE (cfg->butype_info.butype_info_val);
+       }
+       cfg->butype_info.butype_info_val = ent;
+       cfg->butype_info.butype_info_len = n_ent+1;
+       ent += n_ent;
+
+       NDMOS_MACRO_ZEROFILL (ent);
+
+       ent->butype_name = NDMOS_API_STRDUP (cb->sv[1]);
+
+       for (;;) {
+               rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE);
+               if (rc < 0)
+                       break;
+
+               cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
+               if (cb->sc < 1) {
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "v2attr") == 0 && cb->sc == 2) {
+                       ent->v2attr.valid = NDMP9_VALIDITY_VALID;
+                       ent->v2attr.value = strtol (cb->sv[1], 0, 0);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "v3attr") == 0 && cb->sc == 2) {
+                       ent->v3attr.valid = NDMP9_VALIDITY_VALID;
+                       ent->v3attr.value = strtol (cb->sv[1], 0, 0);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "v4attr") == 0 && cb->sc == 2) {
+                       ent->v4attr.valid = NDMP9_VALIDITY_VALID;
+                       ent->v4attr.value = strtol (cb->sv[1], 0, 0);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "default_env") == 0 && cb->sc == 3) {
+                       cfg_add_env (cb, &ent->default_env.default_env_len,
+                               &ent->default_env.default_env_val,
+                               cb->sv[1], cb->sv[2]);
+                       continue;
+               }
+
+               /*
+                * Unrecognized lines are deemed version differences
+                * and tolerated.
+                */
+       }
+
+       return 0;
+}
+
+/*
+ * [fs MOUNTPOINT]
+ *     fs_type TYPE
+ *     fs_physical_device DEVICEPATH
+ *     fs_status "COMMENT"
+ *     fs_env NAME VALUE
+ */
+
+static int
+cfg_fs (struct cfg_cb *cb)
+{
+       ndmp9_config_info *     cfg = cb->config_info;
+       ndmp9_fs_info *         ent = cfg->fs_info.fs_info_val;
+       int                     n_ent = cfg->fs_info.fs_info_len;
+       int                     i, rc;
+
+       if (!ent)
+               n_ent = 0;
+
+       ent = NDMOS_MACRO_NEWN(ndmp9_fs_info, n_ent+1);
+       if (!ent) {
+               cb->n_error++;
+               return -1;
+       }
+
+       for (i = 0; i < n_ent; i++) {
+               ent[i] = cfg->fs_info.fs_info_val[i];
+       }
+
+       if (cfg->fs_info.fs_info_val) {
+               NDMOS_API_FREE (cfg->fs_info.fs_info_val);
+       }
+       cfg->fs_info.fs_info_val = ent;
+       cfg->fs_info.fs_info_len = n_ent+1;
+       ent += n_ent;
+
+       NDMOS_MACRO_ZEROFILL (ent);
+
+       ent->fs_logical_device = NDMOS_API_STRDUP (cb->sv[1]);
+
+       for (;;) {
+               rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE);
+               if (rc < 0)
+                       break;
+
+               cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
+               if (cb->sc < 1) {
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "fs_type") == 0 && cb->sc == 2) {
+                       ent->fs_type = NDMOS_API_STRDUP (cb->sv[1]);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "fs_physical_device") == 0
+                && cb->sc == 2) {
+                       ent->fs_physical_device = NDMOS_API_STRDUP (cb->sv[1]);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "fs_status") == 0 && cb->sc == 2) {
+                       ent->fs_status = NDMOS_API_STRDUP (cb->sv[1]);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "fs_env") == 0 && cb->sc == 3) {
+                       cfg_add_env (cb, &ent->fs_env.fs_env_len,
+                               &ent->fs_env.fs_env_val,
+                               cb->sv[1], cb->sv[2]);
+                       continue;
+               }
+
+               /*
+                * Unrecognized lines are deemed version differences
+                * and tolerated.
+                */
+       }
+
+       return 0;
+}
+
+static int
+cfg_tape (struct cfg_cb *cb)
+{
+       ndmp9_config_info *     cfg = cb->config_info;
+
+       return cfg_device (cb, &cfg->tape_info.tape_info_len,
+                               &cfg->tape_info.tape_info_val);
+}
+
+static int
+cfg_scsi (struct cfg_cb *cb)
+{
+       ndmp9_config_info *     cfg = cb->config_info;
+
+       return cfg_device (cb, &cfg->scsi_info.scsi_info_len,
+                               &cfg->scsi_info.scsi_info_val);
+}
+
+/*
+ * [tape IDENT]  or  [scsi IDENT]
+ *     device DEVICEPATH
+ *     v3attr 0xATTR
+ *     v4attr 0xATTR
+ *     capability NAME VALUE
+ */
+
+static int
+cfg_device (struct cfg_cb *cb, u_int *n_device, ndmp9_device_info **pp)
+{
+       ndmp9_device_info *     ent = *pp;
+       ndmp9_device_capability *dcap;
+       int                     rc;
+       unsigned int            i, n_ent = *n_device;
+
+       if (!ent)
+               n_ent = 0;
+
+       for (i = 0; i < n_ent; i++) {
+               if (strcmp(ent[i].model, (*pp)[i].model) == 0) {
+                       ent += i;
+                       goto got_model;
+               }
+       }
+
+       ent = NDMOS_MACRO_NEWN(ndmp9_device_info, n_ent+1);
+       if (!ent) {
+               cb->n_error++;
+               return -1;
+       }
+
+       for (i = 0; i < n_ent; i++) {
+               ent[i] = (*pp)[i];
+       }
+
+       if (*pp) {
+               NDMOS_API_FREE (*pp);
+       }
+       *pp = ent;
+       *n_device = n_ent+1;
+       ent += n_ent;
+
+       NDMOS_MACRO_ZEROFILL (ent);
+       ent->model = NDMOS_API_STRDUP (cb->sv[1]);
+
+  got_model:
+       dcap = NDMOS_MACRO_NEWN (ndmp9_device_capability,
+                       ent->caplist.caplist_len+1);
+       if (!dcap) {
+               cb->n_error++;
+               return -1;
+       }
+
+       for (i = 0; i < ent->caplist.caplist_len; i++) {
+               dcap[i] = ent->caplist.caplist_val[i];
+       }
+       if (ent->caplist.caplist_val) {
+               NDMOS_API_FREE (ent->caplist.caplist_val);
+       }
+
+       ent->caplist.caplist_val = dcap;
+       dcap += ent->caplist.caplist_len++;
+       NDMOS_MACRO_ZEROFILL(dcap);
+
+       for (;;) {
+               rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE);
+               if (rc < 0)
+                       break;
+
+               cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
+               if (cb->sc < 1) {
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "device") == 0 && cb->sc == 2) {
+                       dcap->device = NDMOS_API_STRDUP (cb->sv[1]);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "v3attr") == 0 && cb->sc == 2) {
+                       dcap->v3attr.valid = NDMP9_VALIDITY_VALID;
+                       dcap->v3attr.value = strtol (cb->sv[1], 0, 0);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "v4attr") == 0 && cb->sc == 2) {
+                       dcap->v4attr.valid = NDMP9_VALIDITY_VALID;
+                       dcap->v4attr.value = strtol (cb->sv[1], 0, 0);
+                       continue;
+               }
+
+               if (strcmp (cb->sv[0], "capability") == 0 && cb->sc == 3) {
+                       cfg_add_env (cb, &dcap->capability.capability_len,
+                               &dcap->capability.capability_val,
+                               cb->sv[1], cb->sv[2]);
+                       continue;
+               }
+
+               /*
+                * Unrecognized lines are deemed version differences
+                * and tolerated.
+                */
+       }
+
+       return 0;
+}
+
+static int
+cfg_add_env (struct cfg_cb *cb, u_int *n_env,
+  ndmp9_pval **pp, char *name, char *value)
+{
+       ndmp9_pval *            ent = *pp;
+       int                     n_ent = *n_env;
+       int                     i;
+
+       if (!ent)
+               n_ent = 0;
+
+       ent = NDMOS_MACRO_NEWN(ndmp9_pval, n_ent+1);
+       if (!ent) {
+               cb->n_error++;
+               return -1;
+       }
+
+       for (i = 0; i < n_ent; i++) {
+               ent[i] = (*pp)[i];
+       }
+
+       if (*pp) {
+               NDMOS_API_FREE (*pp);
+       }
+
+       *pp = ent;
+       *n_env = n_ent+1;
+       ent += n_ent;
+
+       NDMOS_MACRO_ZEROFILL (ent);
+       ent->name = NDMOS_API_STRDUP (name);
+       ent->value = NDMOS_API_STRDUP (value);
+
+       return 0;
+}
+
+#ifdef SELF_TEST
+
+int
+main (int argc, char *argv[])
+{
+       ndmp9_config_info       config_info;
+       int                     rc, i, j, k;
+
+       if (argc != 2) {
+               printf ("usage: %s FILE\n", argv[0]);
+               return 1;
+       }
+
+       NDMOS_MACRO_ZEROFILL (&config_info);
+
+       rc = ndmcfg_load (argv[1], &config_info);
+       printf ("%d errors\n", rc);
+
+       for (i = 0; i < config_info.butype_info.butype_info_len; i++) {
+               ndmp9_butype_info *     bu;
+
+               bu = &config_info.butype_info.butype_info_val[i];
+               printf ("butype[%d] name='%s'\n", i, bu->butype_name);
+               if (bu->v2attr.valid) {
+                       printf ("  v2attr 0x%x\n", bu->v2attr.value);
+               } else {
+                       printf ("  v2attr -invalid-\n");
+               }
+               if (bu->v3attr.valid) {
+                       printf ("  v3attr 0x%x\n", bu->v3attr.value);
+               } else {
+                       printf ("  v3attr -invalid-\n");
+               }
+               if (bu->v4attr.valid) {
+                       printf ("  v4attr 0x%x\n", bu->v4attr.value);
+               } else {
+                       printf ("  v4attr -invalid-\n");
+               }
+               for (j = 0; j < bu->default_env.default_env_len; j++) {
+                       ndmp9_pval *    env;
+
+                       env = &bu->default_env.default_env_val[j];
+                       printf ("  default_env[%d] '%s'='%s'\n",
+                               j, env->name, env->value);
+               }
+       }
+
+       for (i = 0; i < config_info.fs_info.fs_info_len; i++) {
+               ndmp9_fs_info * fs;
+
+               fs = &config_info.fs_info.fs_info_val[i];
+               printf ("fs[%d] fs_logical_device='%s'\n",
+                        i, fs->fs_logical_device);
+               if (fs->fs_physical_device) {
+                       printf ("  fs_physical_device '%s'\n",
+                               fs->fs_physical_device);
+               } else {
+                       printf ("  fs_physical_device -null-\n");
+               }
+               if (fs->fs_type) {
+                       printf ("  fs_type '%s'\n", fs->fs_type);
+               } else {
+                       printf ("  fs_type -null-\n");
+               }
+               if (fs->fs_status) {
+                       printf ("  fs_status '%s'\n", fs->fs_status);
+               } else {
+                       printf ("  fs_status -null-\n");
+               }
+               if (fs->total_size.valid) {
+                       printf ("  total_size %llu\n", fs->total_size.value);
+               } else {
+                       printf ("  total_size -invalid-\n");
+               }
+               if (fs->used_size.valid) {
+                       printf ("  used_size %llu\n", fs->used_size.value);
+               } else {
+                       printf ("  used_size -invalid-\n");
+               }
+               if (fs->avail_size.valid) {
+                       printf ("  avail_size %llu\n", fs->avail_size.value);
+               } else {
+                       printf ("  avail_size -invalid-\n");
+               }
+               if (fs->total_inodes.valid) {
+                       printf ("  total_inodes %llu\n",
+                               fs->total_inodes.value);
+               } else {
+                       printf ("  total_inodes -invalid-\n");
+               }
+               if (fs->used_inodes.valid) {
+                       printf ("  used_inodes %llu\n", fs->used_inodes.value);
+               } else {
+                       printf ("  used_inodes -invalid-\n");
+               }
+
+               for (j = 0; j < fs->fs_env.fs_env_len; j++) {
+                       ndmp9_pval *    env;
+
+                       env = &fs->fs_env.fs_env_val[j];
+                       printf ("  fs_env[%d] '%s'='%s'\n",
+                               j, env->name, env->value);
+               }
+       }
+
+       for (i = 0; i < config_info.tape_info.tape_info_len; i++) {
+               ndmp9_device_info *     dev;
+
+               dev = &config_info.tape_info.tape_info_val[i];
+               printf ("tape[%d] model='%s'\n", i, dev->model);
+
+               for (j = 0; j < dev->caplist.caplist_len; j++) {
+                       struct ndmp9_device_capability *dcap;
+
+                       dcap = &dev->caplist.caplist_val[j];
+                       printf (" capability %d\n", j);
+
+                       if (dcap->device) {
+                               printf ("  device '%s'\n", dcap->device);
+                       } else {
+                               printf ("  device -null-\n");
+                       }
+                       if (dcap->v3attr.valid) {
+                               printf ("  v3attr 0x%x\n", dcap->v3attr.value);
+                       } else {
+                               printf ("  v3attr -invalid-\n");
+                       }
+                       if (dcap->v4attr.valid) {
+                               printf ("  v4attr 0x%x\n", dcap->v4attr.value);
+                       } else {
+                               printf ("  v4attr -invalid-\n");
+                       }
+                       k = 0;
+                       for (; k < dcap->capability.capability_len; k++) {
+                               ndmp9_pval *env;
+                               env = &dcap->capability.capability_val[k];
+                               printf ("  capability[%d] '%s'='%s'\n",
+                                       k, env->name, env->value);
+                       }
+               }
+       }
+
+       for (i = 0; i < config_info.scsi_info.scsi_info_len; i++) {
+               ndmp9_device_info *     dev;
+
+               dev = &config_info.scsi_info.scsi_info_val[i];
+               printf ("scsi[%d] model='%s'\n", i, dev->model);
+
+               for (j = 0; j < dev->caplist.caplist_len; j++) {
+                       struct ndmp9_device_capability *dcap;
+
+                       dcap = &dev->caplist.caplist_val[j];
+                       printf (" capability %d\n", j);
+
+                       if (dcap->device) {
+                               printf ("  device '%s'\n", dcap->device);
+                       } else {
+                               printf ("  device -null-\n");
+                       }
+                       if (dcap->v3attr.valid) {
+                               printf ("  v3attr 0x%x\n", dcap->v3attr.value);
+                       } else {
+                               printf ("  v3attr -invalid-\n");
+                       }
+                       if (dcap->v4attr.valid) {
+                               printf ("  v4attr 0x%x\n", dcap->v4attr.value);
+                       } else {
+                               printf ("  v4attr -invalid-\n");
+                       }
+                       k = 0;
+                       for (; k < dcap->capability.capability_len; k++) {
+                               ndmp9_pval *env;
+                               env = &dcap->capability.capability_val[k];
+                               printf ("  capability[%d] '%s'='%s'\n",
+                                       k, env->name, env->value);
+                       }
+               }
+       }
+
+
+       return 0;
+}
+
+#endif /* SELF_TEST */