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
ndmcfg_load(char * filename,ndmp9_config_info * config_info)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
ndmcfg_loadfp(FILE * fp,ndmp9_config_info * config_info)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
cfg_butype(struct cfg_cb * cb)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
cfg_fs(struct cfg_cb * cb)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
cfg_tape(struct cfg_cb * cb)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
cfg_scsi(struct cfg_cb * cb)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
cfg_device(struct cfg_cb * cb,u_int * n_device,ndmp9_device_info ** pp)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
cfg_add_env(struct cfg_cb * cb,u_int * n_env,ndmp9_pval ** pp,char * name,char * value)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
main(int argc,char * argv[])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 */
646