1 /*
2 * Copyright (c) 1989 Jan-Simon Pendry
3 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * %sccs.include.redist.c%
8 *
9 * @(#)fsi_util.c 8.1 (Berkeley) 06/06/93
10 *
11 * $Id: fsi_util.c,v 5.2.2.1 1992/02/09 15:09:39 jsp beta $
12 *
13 */
14
15 #include "../fsinfo/fsinfo.h"
16
17 /*
18 * Lots of ways of reporting errors...
19 */
error(s,s1,s2,s3,s4)20 void error(s, s1, s2, s3, s4)
21 char *s, *s1, *s2, *s3, *s4;
22 {
23 col_cleanup(0);
24 fprintf(stderr, "%s: Error, ", progname);
25 fprintf(stderr, s, s1, s2, s3, s4);
26 fputc('\n', stderr);
27 errors++;
28 }
29
lerror(l,s,s1,s2,s3,s4)30 void lerror(l, s, s1, s2, s3, s4)
31 ioloc *l;
32 char *s, *s1, *s2, *s3, *s4;
33 {
34 col_cleanup(0);
35 fprintf(stderr, "%s:%d: ", l->i_file, l->i_line);
36 fprintf(stderr, s, s1, s2, s3, s4);
37 fputc('\n', stderr);
38 errors++;
39 }
40
lwarning(l,s,s1,s2,s3,s4)41 void lwarning(l, s, s1, s2, s3, s4)
42 ioloc *l;
43 char *s, *s1, *s2, *s3, *s4;
44 {
45 col_cleanup(0);
46 fprintf(stderr, "%s:%d: ", l->i_file, l->i_line);
47 fprintf(stderr, s, s1, s2, s3, s4);
48 fputc('\n', stderr);
49
50 }
51
fatal(s,s1,s2,s3,s4)52 void fatal(s, s1, s2, s3, s4)
53 char *s, *s1, *s2, *s3, *s4;
54 {
55 col_cleanup(1);
56 fprintf(stderr, "%s: Fatal, ", progname);
57 fprintf(stderr, s, s1, s2, s3, s4);
58 fputc('\n', stderr);
59 exit(1);
60 }
61
62 /*
63 * Dup a string
64 */
strdup(s)65 char *strdup(s)
66 char *s;
67 {
68 int len = strlen(s);
69 char *sp = (char *) xmalloc(len+1);
70
71 bcopy(s, sp, len);
72 sp[len] = 0;
73
74 return sp;
75 }
76
77 /*
78 * Debug log
79 */
log(s,s1,s2,s3,s4)80 void log(s, s1, s2, s3, s4)
81 char *s, *s1, *s2, *s3, *s4;
82 {
83 if (verbose > 0) {
84 fputc('#', stdout);
85 fprintf(stdout, "%s: ", progname);
86 fprintf(stdout, s, s1, s2, s3, s4);
87 putc('\n', stdout);
88 }
89 }
90
info_hdr(ef,info)91 void info_hdr(ef, info)
92 FILE *ef;
93 char *info;
94 {
95 fprintf(ef, "# *** NOTE: This file contains %s info\n", info);
96 }
97
gen_hdr(ef,hn)98 void gen_hdr(ef, hn)
99 FILE *ef;
100 char *hn;
101 {
102 fprintf(ef, "# *** NOTE: Only for use on %s\n", hn);
103 }
104
make_banner(fp)105 static void make_banner(fp)
106 FILE *fp;
107 {
108 time_t t = time((time_t*) 0);
109 char *ctime(), *cp = ctime(&t);
110
111 fprintf(fp,
112 "\
113 # *** This file was automatically generated -- DO NOT EDIT HERE ***\n\
114 # \"%s\" run by %s@%s on %s\
115 #\n\
116 ",
117 progname, username, hostname, cp);
118 }
119
120 static int show_range = 10;
121 static int col = 0;
122 static int total_shown = 0;
123 static int total_mmm = 8;
124
col_output(len)125 static int col_output(len)
126 int len;
127 {
128 int wrapped = 0;
129 col += len;
130 if (col > 77) {
131 fputc('\n', stdout);
132 col = len;
133 wrapped = 1;
134 }
135 return wrapped;
136 }
137
show_total()138 static void show_total()
139 {
140 if (total_mmm != -show_range+1) {
141 char n[8];
142 int len;
143 if (total_mmm < 0)
144 fputc('*', stdout);
145 sprintf(n, "%d", total_shown);
146 len = strlen(n);
147 if (col_output(len))
148 fputc(' ', stdout);
149 fputs(n, stdout); fflush(stdout);
150 total_mmm = -show_range;
151 }
152 }
153
col_cleanup(eoj)154 col_cleanup(eoj)
155 int eoj;
156 {
157 if (verbose < 0) return;
158 if (eoj) {
159 show_total();
160 fputs(")]", stdout);
161 }
162 if (col) {
163 fputc('\n', stdout);
164 col = 0;
165 }
166 }
167
show_new(msg)168 void show_new(msg)
169 char *msg;
170 {
171 if (verbose < 0) return;
172 total_shown++;
173 if (total_mmm > show_range) {
174 show_total();
175 } else if (total_mmm == 0) {
176 fputc('*', stdout); fflush(stdout);
177 col += 1;
178 }
179 total_mmm++;
180 }
181
show_area_being_processed(area,n)182 void show_area_being_processed(area, n)
183 char *area;
184 int n;
185 {
186 static char *last_area = 0;
187 if (verbose < 0) return;
188 if (last_area) {
189 if (total_shown)
190 show_total();
191 fputs(")", stdout);
192 col += 1;
193 }
194 if (!last_area || strcmp(area, last_area) != 0) {
195 if (last_area) {
196 col_cleanup(0);
197 total_shown = 0;
198 total_mmm = show_range+1;
199 }
200 (void) col_output(strlen(area)+2);
201 fprintf(stdout, "[%s", area);
202 last_area = area;
203 }
204
205 fputs(" (", stdout);
206 col += 2;
207 show_range = n;
208 total_mmm = n + 1;
209
210 fflush(stdout);
211 }
212
213 /*
214 * Open a file with the given prefix and name
215 */
pref_open(pref,hn,hdr,arg)216 FILE *pref_open(pref, hn, hdr, arg)
217 char *pref;
218 char *hn;
219 void (*hdr)();
220 char *arg;
221 {
222 char p[MAXPATHLEN];
223 FILE *ef;
224 sprintf(p, "%s%s", pref, hn);
225 log("Writing %s info for %s to %s", pref, hn, p);
226 ef = fopen(p, "w");
227 if (ef) {
228 (*hdr)(ef, arg);
229 make_banner(ef, hn);
230 } else {
231 error("can't open %s for writing", p);
232 }
233
234 return ef;
235 }
236
pref_close(fp)237 int pref_close(fp)
238 FILE *fp;
239 {
240 return fclose(fp) == 0;
241 }
242
243 /*
244 * Determine where Amd would automount the host/volname pair
245 */
compute_automount_point(buf,hp,vn)246 void compute_automount_point(buf, hp, vn)
247 char *buf;
248 host *hp;
249 char *vn;
250 {
251 #ifdef AMD_USES_HOSTPATH
252 sprintf(buf, "%s/%s%s", autodir, hp->h_hostpath, vn);
253 #else
254 sprintf(buf, "%s/%s%s", autodir, hp->h_lochost, vn);
255 #endif
256 }
257
xcalloc(i,s)258 char *xcalloc(i, s)
259 int i;
260 int s;
261 {
262 char *p = (char *) calloc(i, (unsigned) s);
263 if (!p)
264 fatal("Out of memory");
265 return p;
266 }
267
xmalloc(i)268 char *xmalloc(i)
269 int i;
270 {
271 char *p = (char *) malloc(i);
272 if (!p)
273 fatal("Out of memory");
274 return p;
275 }
276
277 /*
278 * Data constructors..
279 */
280
new_automount(name)281 automount *new_automount(name)
282 char *name;
283 {
284 automount *ap = ALLOC(automount);
285 ap->a_ioloc = current_location();
286 ap->a_name = name;
287 ap->a_volname = 0;
288 ap->a_mount = 0;
289 show_new("automount");
290 return ap;
291 }
292
new_auto_tree(def,ap)293 auto_tree *new_auto_tree(def, ap)
294 char *def;
295 qelem *ap;
296 {
297 auto_tree *tp = ALLOC(auto_tree);
298 tp->t_ioloc = current_location();
299 tp->t_defaults = def;
300 tp->t_mount = ap;
301 show_new("auto_tree");
302 return tp;
303 }
304
new_host()305 host *new_host()
306 {
307 host *hp = ALLOC(host);
308 hp->h_ioloc = current_location();
309 hp->h_mask = 0;
310 show_new("host");
311 return hp;
312 }
313
set_host(hp,k,v)314 void set_host(hp, k, v)
315 host *hp;
316 int k;
317 char *v;
318 {
319 int m = 1 << k;
320 if (hp->h_mask & m) {
321 yyerror("host field \"%s\" already set", host_strings[k]);
322 return;
323 }
324
325 hp->h_mask |= m;
326
327 switch (k) {
328 case HF_HOST: {
329 char *p = strdup(v);
330 dict_ent *de = dict_locate(dict_of_hosts, v);
331 if (de)
332 yyerror("duplicate host %s!", v);
333 else
334 dict_add(dict_of_hosts, v, (char *) hp);
335 hp->h_hostname = v;
336 domain_strip(p, hostname);
337 if (strchr(p, '.') != 0)
338 free(p);
339 else
340 hp->h_lochost = p;
341 } break;
342 case HF_CONFIG: {
343 qelem *q;
344 qelem *vq = (qelem *) v;
345 hp->h_mask &= ~m;
346 if (hp->h_config)
347 q = hp->h_config;
348 else
349 q = hp->h_config = new_que();
350 ins_que(vq, q->q_back);
351 } break;
352 case HF_ETHER: {
353 qelem *q;
354 qelem *vq = (qelem *) v;
355 hp->h_mask &= ~m;
356 if (hp->h_ether)
357 q = hp->h_ether;
358 else
359 q = hp->h_ether = new_que();
360 ins_que(vq, q->q_back);
361 } break;
362 case HF_ARCH: hp->h_arch = v; break;
363 case HF_OS: hp->h_os = v; break;
364 case HF_CLUSTER: hp->h_cluster = v; break;
365 default: abort(); break;
366 }
367 }
368
new_ether_if()369 ether_if *new_ether_if()
370 {
371 ether_if *ep = ALLOC(ether_if);
372 ep->e_mask = 0;
373 ep->e_ioloc = current_location();
374 show_new("ether_if");
375 return ep;
376 }
377
set_ether_if(ep,k,v)378 void set_ether_if(ep,k, v)
379 ether_if *ep;
380 int k;
381 char *v;
382 {
383 int m = 1 << k;
384 if (ep->e_mask & m) {
385 yyerror("netif field \"%s\" already set", ether_if_strings[k]);
386 return;
387 }
388
389 ep->e_mask |= m;
390
391 switch (k) {
392 case EF_INADDR: {
393 extern u_long inet_addr();
394 ep->e_inaddr.s_addr = inet_addr(v);
395 if (ep->e_inaddr.s_addr == (u_long) -1)
396 yyerror("malformed IP dotted quad: %s", v);
397 free(v);
398 } break;
399 case EF_NETMASK: {
400 u_long nm = 0;
401 if ((sscanf(v, "0x%lx", &nm) == 1 || sscanf(v, "%lx", &nm) == 1) && nm != 0)
402 ep->e_netmask = htonl(nm);
403 else
404 yyerror("malformed netmask: %s", v);
405 free(v);
406 } break;
407 case EF_HWADDR:
408 ep->e_hwaddr = v;
409 break;
410 default: abort(); break;
411 }
412 }
413
set_disk_fs(dp,k,v)414 void set_disk_fs(dp, k, v)
415 disk_fs *dp;
416 int k;
417 char *v;
418 {
419 int m = 1 << k;
420 if (dp->d_mask & m) {
421 yyerror("fs field \"%s\" already set", disk_fs_strings[k]);
422 return;
423 }
424
425 dp->d_mask |= m;
426
427 switch (k) {
428 case DF_FSTYPE: dp->d_fstype = v; break;
429 case DF_OPTS: dp->d_opts = v; break;
430 case DF_DUMPSET: dp->d_dumpset = v; break;
431 case DF_LOG: dp->d_log = v; break;
432 case DF_PASSNO: dp->d_passno = atoi(v); free(v); break;
433 case DF_FREQ: dp->d_freq = atoi(v); free(v); break;
434 case DF_MOUNT: dp->d_mount = &((mount *) v)->m_q; break;
435 default: abort(); break;
436 }
437 }
438
new_disk_fs()439 disk_fs *new_disk_fs()
440 {
441 disk_fs *dp = ALLOC(disk_fs);
442 dp->d_ioloc = current_location();
443 show_new("disk_fs");
444 return dp;
445 }
446
set_mount(mp,k,v)447 void set_mount(mp, k, v)
448 mount *mp;
449 int k;
450 char *v;
451 {
452 int m = 1 << k;
453 if (mp->m_mask & m) {
454 yyerror("mount tree field \"%s\" already set", mount_strings[k]);
455 return;
456 }
457
458 mp->m_mask |= m;
459
460 switch (k) {
461 case DM_VOLNAME:
462 dict_add(dict_of_volnames, v, (char *) mp);
463 mp->m_volname = v;
464 break;
465 case DM_EXPORTFS:
466 mp->m_exportfs = v;
467 break;
468 case DM_SEL:
469 mp->m_sel = v;
470 break;
471 default: abort(); break;
472 }
473 }
474
new_mount()475 mount *new_mount()
476 {
477 mount *fp = ALLOC(mount);
478 fp->m_ioloc = current_location();
479 show_new("mount");
480 return fp;
481 }
482
set_fsmount(fp,k,v)483 void set_fsmount(fp, k, v)
484 fsmount *fp;
485 int k;
486 char *v;
487 {
488 int m = 1 << k;
489 if (fp->f_mask & m) {
490 yyerror("mount field \"%s\" already set", fsmount_strings[k]);
491 return;
492 }
493
494 fp->f_mask |= m;
495
496 switch (k) {
497 case FM_LOCALNAME: fp->f_localname = v; break;
498 case FM_VOLNAME: fp->f_volname = v; break;
499 case FM_FSTYPE: fp->f_fstype = v; break;
500 case FM_OPTS: fp->f_opts = v; break;
501 case FM_FROM: fp->f_from = v; break;
502 default: abort(); break;
503 }
504 }
505
new_fsmount()506 fsmount *new_fsmount()
507 {
508 fsmount *fp = ALLOC(fsmount);
509 fp->f_ioloc = current_location();
510 show_new("fsmount");
511 return fp;
512 }
513
init_que(q)514 void init_que(q)
515 qelem *q;
516 {
517 q->q_forw = q->q_back = q;
518 }
519
new_que()520 qelem *new_que()
521 {
522 qelem *q = ALLOC(qelem);
523 init_que(q);
524 return q;
525 }
526
ins_que(elem,pred)527 void ins_que(elem, pred)
528 qelem *elem, *pred;
529 {
530 qelem *p;
531 p = pred->q_forw;
532 elem->q_back = pred;
533 elem->q_forw = p;
534 pred->q_forw = elem;
535 p->q_back = elem;
536 }
537
rem_que(elem)538 void rem_que(elem)
539 qelem *elem;
540 {
541 qelem *p, *p2;
542 p = elem->q_forw;
543 p2 = elem->q_back;
544
545 p2->q_forw = p;
546 p->q_back = p2;
547 }
548