1 /* 2 * Copyright (c) 1989 Jan-Simon Pendry 3 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 4 * Copyright (c) 1989 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * %sccs.include.redist.c% 8 * 9 * @(#)fsi_util.c 5.4 (Berkeley) 02/09/92 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