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