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