xref: /original-bsd/usr.sbin/amd/fsinfo/fsi_util.c (revision c3e32dec)
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  */
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 
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 
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 
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  */
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  */
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 
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 
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 
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 
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 
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 
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 
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 
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  */
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 
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  */
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
514 void init_que(q)
515 qelem *q;
516 {
517 	q->q_forw = q->q_back = q;
518 }
519 
520 qelem *new_que()
521 {
522 	qelem *q = ALLOC(qelem);
523 	init_que(q);
524 	return q;
525 }
526 
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 
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