Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndml_config.c
1 /*
2  * Copyright (c) 1998,1999,2000
3  *      Traakan, Inc., Los Altos, CA
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *
35  */
36
37
38 #include "ndmlib.h"
39
40 #define CFG_BUF_SIZE    512
41 #define CFG_MAX_SV      32
42
43 /* control block */
44 struct cfg_cb {
45         FILE *                  fp;
46         ndmp9_config_info *     config_info;
47         char                    buf[CFG_BUF_SIZE];
48         char *                  sv[CFG_MAX_SV];
49         int                     sc;
50         int                     n_error;
51 };
52
53
54 static int      cfg_butype (struct cfg_cb *cb);
55 static int      cfg_fs (struct cfg_cb *cb);
56 static int      cfg_tape (struct cfg_cb *cb);
57 static int      cfg_scsi (struct cfg_cb *cb);
58 static int      cfg_device (struct cfg_cb *cb, u_int *n_device,
59                         ndmp9_device_info **pp);
60 static int      cfg_add_env (struct cfg_cb *cb, u_int *n_env,
61                         ndmp9_pval **pp, char *name, char *value);
62
63
64
65
66 int
67 ndmcfg_load (char *filename, ndmp9_config_info *config_info)
68 {
69         FILE *          fp;
70         int             rc;
71
72         fp = fopen (filename, "r");
73         if (!fp)
74                 return -1;
75
76         rc = ndmcfg_loadfp (fp, config_info);
77
78         fclose (fp);
79
80         return rc;
81 }
82
83 int
84 ndmcfg_loadfp (FILE *fp, ndmp9_config_info *config_info)
85 {
86         struct cfg_cb   _cb, *cb = &_cb;
87         int             rc;
88
89         NDMOS_MACRO_ZEROFILL(cb);
90
91         cb->fp = fp;
92         cb->config_info = config_info;
93
94         for (;;) {
95                 rc = ndmstz_getstanza (cb->fp, cb->buf, sizeof cb->buf);
96                 if (rc == EOF) {
97                         break;
98                 }
99
100                 cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
101                 if (cb->sc < 1) {
102                         continue;
103                 }
104
105                 if (strcmp (cb->sv[0], "butype") == 0 && cb->sc == 2) {
106                         cfg_butype (cb);
107                         continue;
108                 }
109
110                 if (strcmp (cb->sv[0], "fs") == 0 && cb->sc == 2) {
111                         cfg_fs (cb);
112                         continue;
113                 }
114
115                 if (strcmp (cb->sv[0], "tape") == 0 && cb->sc == 2) {
116                         cfg_tape (cb);
117                         continue;
118                 }
119
120                 if (strcmp (cb->sv[0], "scsi") == 0 && cb->sc == 2) {
121                         cfg_scsi (cb);
122                         continue;
123                 }
124
125                 /*
126                  * Unrecognized stanzas are deemed for other purposes
127                  * and tolerated.
128                  */
129         }
130
131         return cb->n_error;
132 }
133
134 /*
135  * [butype BUTYPE]
136  *      v2attr  0xATTR
137  *      v3attr  0xATTR
138  *      v4attr  0xATTR
139  *      default_env NAME VALUE
140  */
141
142 static int
143 cfg_butype (struct cfg_cb *cb)
144 {
145         ndmp9_config_info *     cfg = cb->config_info;
146         ndmp9_butype_info *     ent = cfg->butype_info.butype_info_val;
147         int                     n_ent = cfg->butype_info.butype_info_len;
148         int                     i, rc;
149
150         if (!ent)
151                 n_ent = 0;
152
153         ent = NDMOS_MACRO_NEWN(ndmp9_butype_info, n_ent+1);
154         if (!ent) {
155                 cb->n_error++;
156                 return -1;
157         }
158
159         for (i = 0; i < n_ent; i++) {
160                 ent[i] = cfg->butype_info.butype_info_val[i];
161         }
162
163         if (cfg->butype_info.butype_info_val) {
164                 NDMOS_API_FREE (cfg->butype_info.butype_info_val);
165         }
166         cfg->butype_info.butype_info_val = ent;
167         cfg->butype_info.butype_info_len = n_ent+1;
168         ent += n_ent;
169
170         NDMOS_MACRO_ZEROFILL (ent);
171
172         ent->butype_name = NDMOS_API_STRDUP (cb->sv[1]);
173
174         for (;;) {
175                 rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE);
176                 if (rc < 0)
177                         break;
178
179                 cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
180                 if (cb->sc < 1) {
181                         continue;
182                 }
183
184                 if (strcmp (cb->sv[0], "v2attr") == 0 && cb->sc == 2) {
185                         ent->v2attr.valid = NDMP9_VALIDITY_VALID;
186                         ent->v2attr.value = strtol (cb->sv[1], 0, 0);
187                         continue;
188                 }
189
190                 if (strcmp (cb->sv[0], "v3attr") == 0 && cb->sc == 2) {
191                         ent->v3attr.valid = NDMP9_VALIDITY_VALID;
192                         ent->v3attr.value = strtol (cb->sv[1], 0, 0);
193                         continue;
194                 }
195
196                 if (strcmp (cb->sv[0], "v4attr") == 0 && cb->sc == 2) {
197                         ent->v4attr.valid = NDMP9_VALIDITY_VALID;
198                         ent->v4attr.value = strtol (cb->sv[1], 0, 0);
199                         continue;
200                 }
201
202                 if (strcmp (cb->sv[0], "default_env") == 0 && cb->sc == 3) {
203                         cfg_add_env (cb, &ent->default_env.default_env_len,
204                                 &ent->default_env.default_env_val,
205                                 cb->sv[1], cb->sv[2]);
206                         continue;
207                 }
208
209                 /*
210                  * Unrecognized lines are deemed version differences
211                  * and tolerated.
212                  */
213         }
214
215         return 0;
216 }
217
218 /*
219  * [fs MOUNTPOINT]
220  *      fs_type TYPE
221  *      fs_physical_device DEVICEPATH
222  *      fs_status "COMMENT"
223  *      fs_env NAME VALUE
224  */
225
226 static int
227 cfg_fs (struct cfg_cb *cb)
228 {
229         ndmp9_config_info *     cfg = cb->config_info;
230         ndmp9_fs_info *         ent = cfg->fs_info.fs_info_val;
231         int                     n_ent = cfg->fs_info.fs_info_len;
232         int                     i, rc;
233
234         if (!ent)
235                 n_ent = 0;
236
237         ent = NDMOS_MACRO_NEWN(ndmp9_fs_info, n_ent+1);
238         if (!ent) {
239                 cb->n_error++;
240                 return -1;
241         }
242
243         for (i = 0; i < n_ent; i++) {
244                 ent[i] = cfg->fs_info.fs_info_val[i];
245         }
246
247         if (cfg->fs_info.fs_info_val) {
248                 NDMOS_API_FREE (cfg->fs_info.fs_info_val);
249         }
250         cfg->fs_info.fs_info_val = ent;
251         cfg->fs_info.fs_info_len = n_ent+1;
252         ent += n_ent;
253
254         NDMOS_MACRO_ZEROFILL (ent);
255
256         ent->fs_logical_device = NDMOS_API_STRDUP (cb->sv[1]);
257
258         for (;;) {
259                 rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE);
260                 if (rc < 0)
261                         break;
262
263                 cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
264                 if (cb->sc < 1) {
265                         continue;
266                 }
267
268                 if (strcmp (cb->sv[0], "fs_type") == 0 && cb->sc == 2) {
269                         ent->fs_type = NDMOS_API_STRDUP (cb->sv[1]);
270                         continue;
271                 }
272
273                 if (strcmp (cb->sv[0], "fs_physical_device") == 0
274                  && cb->sc == 2) {
275                         ent->fs_physical_device = NDMOS_API_STRDUP (cb->sv[1]);
276                         continue;
277                 }
278
279                 if (strcmp (cb->sv[0], "fs_status") == 0 && cb->sc == 2) {
280                         ent->fs_status = NDMOS_API_STRDUP (cb->sv[1]);
281                         continue;
282                 }
283
284                 if (strcmp (cb->sv[0], "fs_env") == 0 && cb->sc == 3) {
285                         cfg_add_env (cb, &ent->fs_env.fs_env_len,
286                                 &ent->fs_env.fs_env_val,
287                                 cb->sv[1], cb->sv[2]);
288                         continue;
289                 }
290
291                 /*
292                  * Unrecognized lines are deemed version differences
293                  * and tolerated.
294                  */
295         }
296
297         return 0;
298 }
299
300 static int
301 cfg_tape (struct cfg_cb *cb)
302 {
303         ndmp9_config_info *     cfg = cb->config_info;
304
305         return cfg_device (cb, &cfg->tape_info.tape_info_len,
306                                 &cfg->tape_info.tape_info_val);
307 }
308
309 static int
310 cfg_scsi (struct cfg_cb *cb)
311 {
312         ndmp9_config_info *     cfg = cb->config_info;
313
314         return cfg_device (cb, &cfg->scsi_info.scsi_info_len,
315                                 &cfg->scsi_info.scsi_info_val);
316 }
317
318 /*
319  * [tape IDENT]  or  [scsi IDENT]
320  *      device DEVICEPATH
321  *      v3attr 0xATTR
322  *      v4attr 0xATTR
323  *      capability NAME VALUE
324  */
325
326 static int
327 cfg_device (struct cfg_cb *cb, u_int *n_device, ndmp9_device_info **pp)
328 {
329         ndmp9_device_info *     ent = *pp;
330         ndmp9_device_capability *dcap;
331         int                     rc;
332         unsigned int            i, n_ent = *n_device;
333
334         if (!ent)
335                 n_ent = 0;
336
337         for (i = 0; i < n_ent; i++) {
338                 if (strcmp(ent[i].model, (*pp)[i].model) == 0) {
339                         ent += i;
340                         goto got_model;
341                 }
342         }
343
344         ent = NDMOS_MACRO_NEWN(ndmp9_device_info, n_ent+1);
345         if (!ent) {
346                 cb->n_error++;
347                 return -1;
348         }
349
350         for (i = 0; i < n_ent; i++) {
351                 ent[i] = (*pp)[i];
352         }
353
354         if (*pp) {
355                 NDMOS_API_FREE (*pp);
356         }
357         *pp = ent;
358         *n_device = n_ent+1;
359         ent += n_ent;
360
361         NDMOS_MACRO_ZEROFILL (ent);
362         ent->model = NDMOS_API_STRDUP (cb->sv[1]);
363
364   got_model:
365         dcap = NDMOS_MACRO_NEWN (ndmp9_device_capability,
366                         ent->caplist.caplist_len+1);
367         if (!dcap) {
368                 cb->n_error++;
369                 return -1;
370         }
371
372         for (i = 0; i < ent->caplist.caplist_len; i++) {
373                 dcap[i] = ent->caplist.caplist_val[i];
374         }
375         if (ent->caplist.caplist_val) {
376                 NDMOS_API_FREE (ent->caplist.caplist_val);
377         }
378
379         ent->caplist.caplist_val = dcap;
380         dcap += ent->caplist.caplist_len++;
381         NDMOS_MACRO_ZEROFILL(dcap);
382
383         for (;;) {
384                 rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE);
385                 if (rc < 0)
386                         break;
387
388                 cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV);
389                 if (cb->sc < 1) {
390                         continue;
391                 }
392
393                 if (strcmp (cb->sv[0], "device") == 0 && cb->sc == 2) {
394                         dcap->device = NDMOS_API_STRDUP (cb->sv[1]);
395                         continue;
396                 }
397
398                 if (strcmp (cb->sv[0], "v3attr") == 0 && cb->sc == 2) {
399                         dcap->v3attr.valid = NDMP9_VALIDITY_VALID;
400                         dcap->v3attr.value = strtol (cb->sv[1], 0, 0);
401                         continue;
402                 }
403
404                 if (strcmp (cb->sv[0], "v4attr") == 0 && cb->sc == 2) {
405                         dcap->v4attr.valid = NDMP9_VALIDITY_VALID;
406                         dcap->v4attr.value = strtol (cb->sv[1], 0, 0);
407                         continue;
408                 }
409
410                 if (strcmp (cb->sv[0], "capability") == 0 && cb->sc == 3) {
411                         cfg_add_env (cb, &dcap->capability.capability_len,
412                                 &dcap->capability.capability_val,
413                                 cb->sv[1], cb->sv[2]);
414                         continue;
415                 }
416
417                 /*
418                  * Unrecognized lines are deemed version differences
419                  * and tolerated.
420                  */
421         }
422
423         return 0;
424 }
425
426 static int
427 cfg_add_env (struct cfg_cb *cb, u_int *n_env,
428   ndmp9_pval **pp, char *name, char *value)
429 {
430         ndmp9_pval *            ent = *pp;
431         int                     n_ent = *n_env;
432         int                     i;
433
434         if (!ent)
435                 n_ent = 0;
436
437         ent = NDMOS_MACRO_NEWN(ndmp9_pval, n_ent+1);
438         if (!ent) {
439                 cb->n_error++;
440                 return -1;
441         }
442
443         for (i = 0; i < n_ent; i++) {
444                 ent[i] = (*pp)[i];
445         }
446
447         if (*pp) {
448                 NDMOS_API_FREE (*pp);
449         }
450
451         *pp = ent;
452         *n_env = n_ent+1;
453         ent += n_ent;
454
455         NDMOS_MACRO_ZEROFILL (ent);
456         ent->name = NDMOS_API_STRDUP (name);
457         ent->value = NDMOS_API_STRDUP (value);
458
459         return 0;
460 }
461
462 #ifdef SELF_TEST
463
464 int
465 main (int argc, char *argv[])
466 {
467         ndmp9_config_info       config_info;
468         int                     rc, i, j, k;
469
470         if (argc != 2) {
471                 printf ("usage: %s FILE\n", argv[0]);
472                 return 1;
473         }
474
475         NDMOS_MACRO_ZEROFILL (&config_info);
476
477         rc = ndmcfg_load (argv[1], &config_info);
478         printf ("%d errors\n", rc);
479
480         for (i = 0; i < config_info.butype_info.butype_info_len; i++) {
481                 ndmp9_butype_info *     bu;
482
483                 bu = &config_info.butype_info.butype_info_val[i];
484                 printf ("butype[%d] name='%s'\n", i, bu->butype_name);
485                 if (bu->v2attr.valid) {
486                         printf ("  v2attr 0x%x\n", bu->v2attr.value);
487                 } else {
488                         printf ("  v2attr -invalid-\n");
489                 }
490                 if (bu->v3attr.valid) {
491                         printf ("  v3attr 0x%x\n", bu->v3attr.value);
492                 } else {
493                         printf ("  v3attr -invalid-\n");
494                 }
495                 if (bu->v4attr.valid) {
496                         printf ("  v4attr 0x%x\n", bu->v4attr.value);
497                 } else {
498                         printf ("  v4attr -invalid-\n");
499                 }
500                 for (j = 0; j < bu->default_env.default_env_len; j++) {
501                         ndmp9_pval *    env;
502
503                         env = &bu->default_env.default_env_val[j];
504                         printf ("  default_env[%d] '%s'='%s'\n",
505                                 j, env->name, env->value);
506                 }
507         }
508
509         for (i = 0; i < config_info.fs_info.fs_info_len; i++) {
510                 ndmp9_fs_info * fs;
511
512                 fs = &config_info.fs_info.fs_info_val[i];
513                 printf ("fs[%d] fs_logical_device='%s'\n",
514                          i, fs->fs_logical_device);
515                 if (fs->fs_physical_device) {
516                         printf ("  fs_physical_device '%s'\n",
517                                 fs->fs_physical_device);
518                 } else {
519                         printf ("  fs_physical_device -null-\n");
520                 }
521                 if (fs->fs_type) {
522                         printf ("  fs_type '%s'\n", fs->fs_type);
523                 } else {
524                         printf ("  fs_type -null-\n");
525                 }
526                 if (fs->fs_status) {
527                         printf ("  fs_status '%s'\n", fs->fs_status);
528                 } else {
529                         printf ("  fs_status -null-\n");
530                 }
531                 if (fs->total_size.valid) {
532                         printf ("  total_size %llu\n", fs->total_size.value);
533                 } else {
534                         printf ("  total_size -invalid-\n");
535                 }
536                 if (fs->used_size.valid) {
537                         printf ("  used_size %llu\n", fs->used_size.value);
538                 } else {
539                         printf ("  used_size -invalid-\n");
540                 }
541                 if (fs->avail_size.valid) {
542                         printf ("  avail_size %llu\n", fs->avail_size.value);
543                 } else {
544                         printf ("  avail_size -invalid-\n");
545                 }
546                 if (fs->total_inodes.valid) {
547                         printf ("  total_inodes %llu\n",
548                                 fs->total_inodes.value);
549                 } else {
550                         printf ("  total_inodes -invalid-\n");
551                 }
552                 if (fs->used_inodes.valid) {
553                         printf ("  used_inodes %llu\n", fs->used_inodes.value);
554                 } else {
555                         printf ("  used_inodes -invalid-\n");
556                 }
557
558                 for (j = 0; j < fs->fs_env.fs_env_len; j++) {
559                         ndmp9_pval *    env;
560
561                         env = &fs->fs_env.fs_env_val[j];
562                         printf ("  fs_env[%d] '%s'='%s'\n",
563                                 j, env->name, env->value);
564                 }
565         }
566
567         for (i = 0; i < config_info.tape_info.tape_info_len; i++) {
568                 ndmp9_device_info *     dev;
569
570                 dev = &config_info.tape_info.tape_info_val[i];
571                 printf ("tape[%d] model='%s'\n", i, dev->model);
572
573                 for (j = 0; j < dev->caplist.caplist_len; j++) {
574                         struct ndmp9_device_capability *dcap;
575
576                         dcap = &dev->caplist.caplist_val[j];
577                         printf (" capability %d\n", j);
578
579                         if (dcap->device) {
580                                 printf ("  device '%s'\n", dcap->device);
581                         } else {
582                                 printf ("  device -null-\n");
583                         }
584                         if (dcap->v3attr.valid) {
585                                 printf ("  v3attr 0x%x\n", dcap->v3attr.value);
586                         } else {
587                                 printf ("  v3attr -invalid-\n");
588                         }
589                         if (dcap->v4attr.valid) {
590                                 printf ("  v4attr 0x%x\n", dcap->v4attr.value);
591                         } else {
592                                 printf ("  v4attr -invalid-\n");
593                         }
594                         k = 0;
595                         for (; k < dcap->capability.capability_len; k++) {
596                                 ndmp9_pval *env;
597                                 env = &dcap->capability.capability_val[k];
598                                 printf ("  capability[%d] '%s'='%s'\n",
599                                         k, env->name, env->value);
600                         }
601                 }
602         }
603
604         for (i = 0; i < config_info.scsi_info.scsi_info_len; i++) {
605                 ndmp9_device_info *     dev;
606
607                 dev = &config_info.scsi_info.scsi_info_val[i];
608                 printf ("scsi[%d] model='%s'\n", i, dev->model);
609
610                 for (j = 0; j < dev->caplist.caplist_len; j++) {
611                         struct ndmp9_device_capability *dcap;
612
613                         dcap = &dev->caplist.caplist_val[j];
614                         printf (" capability %d\n", j);
615
616                         if (dcap->device) {
617                                 printf ("  device '%s'\n", dcap->device);
618                         } else {
619                                 printf ("  device -null-\n");
620                         }
621                         if (dcap->v3attr.valid) {
622                                 printf ("  v3attr 0x%x\n", dcap->v3attr.value);
623                         } else {
624                                 printf ("  v3attr -invalid-\n");
625                         }
626                         if (dcap->v4attr.valid) {
627                                 printf ("  v4attr 0x%x\n", dcap->v4attr.value);
628                         } else {
629                                 printf ("  v4attr -invalid-\n");
630                         }
631                         k = 0;
632                         for (; k < dcap->capability.capability_len; k++) {
633                                 ndmp9_pval *env;
634                                 env = &dcap->capability.capability_val[k];
635                                 printf ("  capability[%d] '%s'='%s'\n",
636                                         k, env->name, env->value);
637                         }
638                 }
639         }
640
641
642         return 0;
643 }
644
645 #endif /* SELF_TEST */