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,
59 u_int* n_device,
60 ndmp9_device_info** pp);
61 static int cfg_add_env(struct cfg_cb* cb,
62 u_int* n_env,
63 ndmp9_pval** pp,
64 char* name,
65 char* value);
66
67
ndmcfg_load(char * filename,ndmp9_config_info * config_info)68 int ndmcfg_load(char* filename, ndmp9_config_info* config_info)
69 {
70 FILE* fp;
71 int rc;
72
73 fp = fopen(filename, "r");
74 if (!fp) return -1;
75
76 rc = ndmcfg_loadfp(fp, config_info);
77
78 fclose(fp);
79
80 return rc;
81 }
82
ndmcfg_loadfp(FILE * fp,ndmp9_config_info * config_info)83 int ndmcfg_loadfp(FILE* fp, ndmp9_config_info* config_info)
84 {
85 struct cfg_cb _cb, *cb = &_cb;
86 int rc;
87
88 NDMOS_MACRO_ZEROFILL(cb);
89
90 cb->fp = fp;
91 cb->config_info = config_info;
92
93 for (;;) {
94 rc = ndmstz_getstanza(cb->fp, cb->buf, sizeof cb->buf);
95 if (rc == EOF) { break; }
96
97 cb->sc = ndmstz_parse(cb->buf, cb->sv, CFG_MAX_SV);
98 if (cb->sc < 1) { continue; }
99
100 if (strcmp(cb->sv[0], "butype") == 0 && cb->sc == 2) {
101 cfg_butype(cb);
102 continue;
103 }
104
105 if (strcmp(cb->sv[0], "fs") == 0 && cb->sc == 2) {
106 cfg_fs(cb);
107 continue;
108 }
109
110 if (strcmp(cb->sv[0], "tape") == 0 && cb->sc == 2) {
111 cfg_tape(cb);
112 continue;
113 }
114
115 if (strcmp(cb->sv[0], "scsi") == 0 && cb->sc == 2) {
116 cfg_scsi(cb);
117 continue;
118 }
119
120 /*
121 * Unrecognized stanzas are deemed for other purposes
122 * and tolerated.
123 */
124 }
125
126 return cb->n_error;
127 }
128
129 /*
130 * [butype BUTYPE]
131 * v2attr 0xATTR
132 * v3attr 0xATTR
133 * v4attr 0xATTR
134 * default_env NAME VALUE
135 */
136
cfg_butype(struct cfg_cb * cb)137 static int cfg_butype(struct cfg_cb* cb)
138 {
139 ndmp9_config_info* cfg = cb->config_info;
140 ndmp9_butype_info* ent = cfg->butype_info.butype_info_val;
141 int n_ent = cfg->butype_info.butype_info_len;
142 int i, rc;
143
144 if (!ent) n_ent = 0;
145
146 ent = NDMOS_MACRO_NEWN(ndmp9_butype_info, n_ent + 1);
147 if (!ent) {
148 cb->n_error++;
149 return -1;
150 }
151
152 for (i = 0; i < n_ent; i++) { ent[i] = cfg->butype_info.butype_info_val[i]; }
153
154 if (cfg->butype_info.butype_info_val) {
155 NDMOS_API_FREE(cfg->butype_info.butype_info_val);
156 }
157 cfg->butype_info.butype_info_val = ent;
158 cfg->butype_info.butype_info_len = n_ent + 1;
159 ent += n_ent;
160
161 NDMOS_MACRO_ZEROFILL(ent);
162
163 ent->butype_name = NDMOS_API_STRDUP(cb->sv[1]);
164
165 for (;;) {
166 rc = ndmstz_getline(cb->fp, cb->buf, CFG_BUF_SIZE);
167 if (rc < 0) break;
168
169 cb->sc = ndmstz_parse(cb->buf, cb->sv, CFG_MAX_SV);
170 if (cb->sc < 1) { continue; }
171
172 if (strcmp(cb->sv[0], "v2attr") == 0 && cb->sc == 2) {
173 ent->v2attr.valid = NDMP9_VALIDITY_VALID;
174 ent->v2attr.value = strtol(cb->sv[1], 0, 0);
175 continue;
176 }
177
178 if (strcmp(cb->sv[0], "v3attr") == 0 && cb->sc == 2) {
179 ent->v3attr.valid = NDMP9_VALIDITY_VALID;
180 ent->v3attr.value = strtol(cb->sv[1], 0, 0);
181 continue;
182 }
183
184 if (strcmp(cb->sv[0], "v4attr") == 0 && cb->sc == 2) {
185 ent->v4attr.valid = NDMP9_VALIDITY_VALID;
186 ent->v4attr.value = strtol(cb->sv[1], 0, 0);
187 continue;
188 }
189
190 if (strcmp(cb->sv[0], "default_env") == 0 && cb->sc == 3) {
191 cfg_add_env(cb, &ent->default_env.default_env_len,
192 &ent->default_env.default_env_val, cb->sv[1], cb->sv[2]);
193 continue;
194 }
195
196 /*
197 * Unrecognized lines are deemed version differences
198 * and tolerated.
199 */
200 }
201
202 return 0;
203 }
204
205 /*
206 * [fs MOUNTPOINT]
207 * fs_type TYPE
208 * fs_physical_device DEVICEPATH
209 * fs_status "COMMENT"
210 * fs_env NAME VALUE
211 */
212
cfg_fs(struct cfg_cb * cb)213 static int cfg_fs(struct cfg_cb* cb)
214 {
215 ndmp9_config_info* cfg = cb->config_info;
216 ndmp9_fs_info* ent = cfg->fs_info.fs_info_val;
217 int n_ent = cfg->fs_info.fs_info_len;
218 int i, rc;
219
220 if (!ent) n_ent = 0;
221
222 ent = NDMOS_MACRO_NEWN(ndmp9_fs_info, n_ent + 1);
223 if (!ent) {
224 cb->n_error++;
225 return -1;
226 }
227
228 for (i = 0; i < n_ent; i++) { ent[i] = cfg->fs_info.fs_info_val[i]; }
229
230 if (cfg->fs_info.fs_info_val) { NDMOS_API_FREE(cfg->fs_info.fs_info_val); }
231 cfg->fs_info.fs_info_val = ent;
232 cfg->fs_info.fs_info_len = n_ent + 1;
233 ent += n_ent;
234
235 NDMOS_MACRO_ZEROFILL(ent);
236
237 ent->fs_logical_device = NDMOS_API_STRDUP(cb->sv[1]);
238
239 for (;;) {
240 rc = ndmstz_getline(cb->fp, cb->buf, CFG_BUF_SIZE);
241 if (rc < 0) break;
242
243 cb->sc = ndmstz_parse(cb->buf, cb->sv, CFG_MAX_SV);
244 if (cb->sc < 1) { continue; }
245
246 if (strcmp(cb->sv[0], "fs_type") == 0 && cb->sc == 2) {
247 ent->fs_type = NDMOS_API_STRDUP(cb->sv[1]);
248 continue;
249 }
250
251 if (strcmp(cb->sv[0], "fs_physical_device") == 0 && cb->sc == 2) {
252 ent->fs_physical_device = NDMOS_API_STRDUP(cb->sv[1]);
253 continue;
254 }
255
256 if (strcmp(cb->sv[0], "fs_status") == 0 && cb->sc == 2) {
257 ent->fs_status = NDMOS_API_STRDUP(cb->sv[1]);
258 continue;
259 }
260
261 if (strcmp(cb->sv[0], "fs_env") == 0 && cb->sc == 3) {
262 cfg_add_env(cb, &ent->fs_env.fs_env_len, &ent->fs_env.fs_env_val,
263 cb->sv[1], cb->sv[2]);
264 continue;
265 }
266
267 /*
268 * Unrecognized lines are deemed version differences
269 * and tolerated.
270 */
271 }
272
273 return 0;
274 }
275
cfg_tape(struct cfg_cb * cb)276 static int cfg_tape(struct cfg_cb* cb)
277 {
278 ndmp9_config_info* cfg = cb->config_info;
279
280 return cfg_device(cb, &cfg->tape_info.tape_info_len,
281 &cfg->tape_info.tape_info_val);
282 }
283
cfg_scsi(struct cfg_cb * cb)284 static int cfg_scsi(struct cfg_cb* cb)
285 {
286 ndmp9_config_info* cfg = cb->config_info;
287
288 return cfg_device(cb, &cfg->scsi_info.scsi_info_len,
289 &cfg->scsi_info.scsi_info_val);
290 }
291
292 /*
293 * [tape IDENT] or [scsi IDENT]
294 * device DEVICEPATH
295 * v3attr 0xATTR
296 * v4attr 0xATTR
297 * capability NAME VALUE
298 */
299
cfg_device(struct cfg_cb * cb,u_int * n_device,ndmp9_device_info ** pp)300 static int cfg_device(struct cfg_cb* cb,
301 u_int* n_device,
302 ndmp9_device_info** pp)
303 {
304 ndmp9_device_info* ent = *pp;
305 ndmp9_device_capability* dcap;
306 int rc;
307 unsigned int i, n_ent = *n_device;
308
309 if (!ent) n_ent = 0;
310
311 for (i = 0; i < n_ent; i++) {
312 if (strcmp(ent[i].model, (*pp)[i].model) == 0) {
313 ent += i;
314 goto got_model;
315 }
316 }
317
318 ent = NDMOS_MACRO_NEWN(ndmp9_device_info, n_ent + 1);
319 if (!ent) {
320 cb->n_error++;
321 return -1;
322 }
323
324 for (i = 0; i < n_ent; i++) { ent[i] = (*pp)[i]; }
325
326 if (*pp) { NDMOS_API_FREE(*pp); }
327 *pp = ent;
328 *n_device = n_ent + 1;
329 ent += n_ent;
330
331 NDMOS_MACRO_ZEROFILL(ent);
332 ent->model = NDMOS_API_STRDUP(cb->sv[1]);
333
334 got_model:
335 dcap =
336 NDMOS_MACRO_NEWN(ndmp9_device_capability, ent->caplist.caplist_len + 1);
337 if (!dcap) {
338 cb->n_error++;
339 return -1;
340 }
341
342 for (i = 0; i < ent->caplist.caplist_len; i++) {
343 dcap[i] = ent->caplist.caplist_val[i];
344 }
345 if (ent->caplist.caplist_val) { NDMOS_API_FREE(ent->caplist.caplist_val); }
346
347 ent->caplist.caplist_val = dcap;
348 dcap += ent->caplist.caplist_len++;
349 NDMOS_MACRO_ZEROFILL(dcap);
350
351 for (;;) {
352 rc = ndmstz_getline(cb->fp, cb->buf, CFG_BUF_SIZE);
353 if (rc < 0) break;
354
355 cb->sc = ndmstz_parse(cb->buf, cb->sv, CFG_MAX_SV);
356 if (cb->sc < 1) { continue; }
357
358 if (strcmp(cb->sv[0], "device") == 0 && cb->sc == 2) {
359 dcap->device = NDMOS_API_STRDUP(cb->sv[1]);
360 continue;
361 }
362
363 if (strcmp(cb->sv[0], "v3attr") == 0 && cb->sc == 2) {
364 dcap->v3attr.valid = NDMP9_VALIDITY_VALID;
365 dcap->v3attr.value = strtol(cb->sv[1], 0, 0);
366 continue;
367 }
368
369 if (strcmp(cb->sv[0], "v4attr") == 0 && cb->sc == 2) {
370 dcap->v4attr.valid = NDMP9_VALIDITY_VALID;
371 dcap->v4attr.value = strtol(cb->sv[1], 0, 0);
372 continue;
373 }
374
375 if (strcmp(cb->sv[0], "capability") == 0 && cb->sc == 3) {
376 cfg_add_env(cb, &dcap->capability.capability_len,
377 &dcap->capability.capability_val, cb->sv[1], cb->sv[2]);
378 continue;
379 }
380
381 /*
382 * Unrecognized lines are deemed version differences
383 * and tolerated.
384 */
385 }
386
387 return 0;
388 }
389
cfg_add_env(struct cfg_cb * cb,u_int * n_env,ndmp9_pval ** pp,char * name,char * value)390 static int cfg_add_env(struct cfg_cb* cb,
391 u_int* n_env,
392 ndmp9_pval** pp,
393 char* name,
394 char* value)
395 {
396 ndmp9_pval* ent = *pp;
397 int n_ent = *n_env;
398 int i;
399
400 if (!ent) n_ent = 0;
401
402 ent = NDMOS_MACRO_NEWN(ndmp9_pval, n_ent + 1);
403 if (!ent) {
404 cb->n_error++;
405 return -1;
406 }
407
408 for (i = 0; i < n_ent; i++) { ent[i] = (*pp)[i]; }
409
410 if (*pp) { NDMOS_API_FREE(*pp); }
411
412 *pp = ent;
413 *n_env = n_ent + 1;
414 ent += n_ent;
415
416 NDMOS_MACRO_ZEROFILL(ent);
417 ent->name = NDMOS_API_STRDUP(name);
418 ent->value = NDMOS_API_STRDUP(value);
419
420 return 0;
421 }
422
423 #ifdef SELF_TEST
424
main(int argc,char * argv[])425 int main(int argc, char* argv[])
426 {
427 ndmp9_config_info config_info;
428 int rc, i, j, k;
429
430 if (argc != 2) {
431 printf("usage: %s FILE\n", argv[0]);
432 return 1;
433 }
434
435 NDMOS_MACRO_ZEROFILL(&config_info);
436
437 rc = ndmcfg_load(argv[1], &config_info);
438 printf("%d errors\n", rc);
439
440 for (i = 0; i < config_info.butype_info.butype_info_len; i++) {
441 ndmp9_butype_info* bu;
442
443 bu = &config_info.butype_info.butype_info_val[i];
444 printf("butype[%d] name='%s'\n", i, bu->butype_name);
445 if (bu->v2attr.valid) {
446 printf(" v2attr 0x%x\n", bu->v2attr.value);
447 } else {
448 printf(" v2attr -invalid-\n");
449 }
450 if (bu->v3attr.valid) {
451 printf(" v3attr 0x%x\n", bu->v3attr.value);
452 } else {
453 printf(" v3attr -invalid-\n");
454 }
455 if (bu->v4attr.valid) {
456 printf(" v4attr 0x%x\n", bu->v4attr.value);
457 } else {
458 printf(" v4attr -invalid-\n");
459 }
460 for (j = 0; j < bu->default_env.default_env_len; j++) {
461 ndmp9_pval* env;
462
463 env = &bu->default_env.default_env_val[j];
464 printf(" default_env[%d] '%s'='%s'\n", j, env->name, env->value);
465 }
466 }
467
468 for (i = 0; i < config_info.fs_info.fs_info_len; i++) {
469 ndmp9_fs_info* fs;
470
471 fs = &config_info.fs_info.fs_info_val[i];
472 printf("fs[%d] fs_logical_device='%s'\n", i, fs->fs_logical_device);
473 if (fs->fs_physical_device) {
474 printf(" fs_physical_device '%s'\n", fs->fs_physical_device);
475 } else {
476 printf(" fs_physical_device -null-\n");
477 }
478 if (fs->fs_type) {
479 printf(" fs_type '%s'\n", fs->fs_type);
480 } else {
481 printf(" fs_type -null-\n");
482 }
483 if (fs->fs_status) {
484 printf(" fs_status '%s'\n", fs->fs_status);
485 } else {
486 printf(" fs_status -null-\n");
487 }
488 if (fs->total_size.valid) {
489 printf(" total_size %llu\n", fs->total_size.value);
490 } else {
491 printf(" total_size -invalid-\n");
492 }
493 if (fs->used_size.valid) {
494 printf(" used_size %llu\n", fs->used_size.value);
495 } else {
496 printf(" used_size -invalid-\n");
497 }
498 if (fs->avail_size.valid) {
499 printf(" avail_size %llu\n", fs->avail_size.value);
500 } else {
501 printf(" avail_size -invalid-\n");
502 }
503 if (fs->total_inodes.valid) {
504 printf(" total_inodes %llu\n", fs->total_inodes.value);
505 } else {
506 printf(" total_inodes -invalid-\n");
507 }
508 if (fs->used_inodes.valid) {
509 printf(" used_inodes %llu\n", fs->used_inodes.value);
510 } else {
511 printf(" used_inodes -invalid-\n");
512 }
513
514 for (j = 0; j < fs->fs_env.fs_env_len; j++) {
515 ndmp9_pval* env;
516
517 env = &fs->fs_env.fs_env_val[j];
518 printf(" fs_env[%d] '%s'='%s'\n", j, env->name, env->value);
519 }
520 }
521
522 for (i = 0; i < config_info.tape_info.tape_info_len; i++) {
523 ndmp9_device_info* dev;
524
525 dev = &config_info.tape_info.tape_info_val[i];
526 printf("tape[%d] model='%s'\n", i, dev->model);
527
528 for (j = 0; j < dev->caplist.caplist_len; j++) {
529 struct ndmp9_device_capability* dcap;
530
531 dcap = &dev->caplist.caplist_val[j];
532 printf(" capability %d\n", j);
533
534 if (dcap->device) {
535 printf(" device '%s'\n", dcap->device);
536 } else {
537 printf(" device -null-\n");
538 }
539 if (dcap->v3attr.valid) {
540 printf(" v3attr 0x%x\n", dcap->v3attr.value);
541 } else {
542 printf(" v3attr -invalid-\n");
543 }
544 if (dcap->v4attr.valid) {
545 printf(" v4attr 0x%x\n", dcap->v4attr.value);
546 } else {
547 printf(" v4attr -invalid-\n");
548 }
549 k = 0;
550 for (; k < dcap->capability.capability_len; k++) {
551 ndmp9_pval* env;
552 env = &dcap->capability.capability_val[k];
553 printf(" capability[%d] '%s'='%s'\n", k, env->name, env->value);
554 }
555 }
556 }
557
558 for (i = 0; i < config_info.scsi_info.scsi_info_len; i++) {
559 ndmp9_device_info* dev;
560
561 dev = &config_info.scsi_info.scsi_info_val[i];
562 printf("scsi[%d] model='%s'\n", i, dev->model);
563
564 for (j = 0; j < dev->caplist.caplist_len; j++) {
565 struct ndmp9_device_capability* dcap;
566
567 dcap = &dev->caplist.caplist_val[j];
568 printf(" capability %d\n", j);
569
570 if (dcap->device) {
571 printf(" device '%s'\n", dcap->device);
572 } else {
573 printf(" device -null-\n");
574 }
575 if (dcap->v3attr.valid) {
576 printf(" v3attr 0x%x\n", dcap->v3attr.value);
577 } else {
578 printf(" v3attr -invalid-\n");
579 }
580 if (dcap->v4attr.valid) {
581 printf(" v4attr 0x%x\n", dcap->v4attr.value);
582 } else {
583 printf(" v4attr -invalid-\n");
584 }
585 k = 0;
586 for (; k < dcap->capability.capability_len; k++) {
587 ndmp9_pval* env;
588 env = &dcap->capability.capability_val[k];
589 printf(" capability[%d] '%s'='%s'\n", k, env->name, env->value);
590 }
591 }
592 }
593
594
595 return 0;
596 }
597
598 #endif /* SELF_TEST */
599