1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * scan /dev directory for mountable objects and construct device_allocate 31 * file for allocate.... 32 * 33 * devices are: 34 * tape (cartridge) 35 * /dev/rst* 36 * /dev/nrst* 37 * /dev/rmt/... 38 * audio 39 * /dev/audio 40 * /dev/audioctl 41 * /dev/sound/... 42 * floppy 43 * /dev/diskette 44 * /dev/fd* 45 * /dev/rdiskette 46 * /dev/rfd* 47 * CD 48 * /dev/sr* 49 * /dev/nsr* 50 * /dev/dsk/c?t?d0s? 51 * /dev/rdsk/c?t?d0s? 52 * 53 */ 54 55 #include <errno.h> 56 #include <fcntl.h> 57 #include <sys/types.h> /* for stat(2), etc. */ 58 #include <sys/stat.h> 59 #include <dirent.h> /* for readdir(3), etc. */ 60 #include <unistd.h> /* for readlink(2) */ 61 #include <stropts.h> 62 #include <string.h> /* for strcpy(3), etc. */ 63 #include <strings.h> /* for bcopy(3C), etc. */ 64 #include <stdio.h> /* for perror(3) */ 65 #include <stdlib.h> /* for atoi(3) */ 66 #include <sys/dkio.h> 67 #include <locale.h> 68 #include <libintl.h> 69 #include <libdevinfo.h> 70 #include <secdb.h> 71 #include <auth_attr.h> 72 #include <auth_list.h> 73 #include <bsm/devices.h> 74 #include <bsm/devalloc.h> 75 #include <tsol/label.h> 76 77 #ifndef TEXT_DOMAIN 78 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 79 #endif 80 81 #define MKDEVALLOC "mkdevalloc" 82 #define MKDEVMAPS "mkdevmaps" 83 84 #define DELTA 5 /* array size delta when full */ 85 #define SECLIB "/etc/security/lib" 86 87 /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */ 88 struct tape { 89 char *name; 90 char *device; 91 int number; 92 } *tape; 93 #define DFLT_NTAPE 10 /* size of initial array */ 94 #define SIZE_OF_RST 3 /* |rmt| */ 95 #define SIZE_OF_NRST 4 /* |nrmt| */ 96 #define SIZE_OF_TMP 4 /* |/tmp| */ 97 #define SIZE_OF_RMT 8 /* |/dev/rmt| */ 98 #define TAPE_CLEAN SECLIB"/st_clean" 99 100 /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */ 101 struct audio { 102 char *name; 103 char *device; 104 int number; 105 } *audio; 106 #define DFLT_NAUDIO 10 /* size of initial array */ 107 #define SIZE_OF_SOUND 10 /* |/dev/sound| */ 108 #define AUDIO_CLEAN SECLIB"/audio_clean" 109 110 /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */ 111 struct cd { 112 char *name; 113 char *device; 114 int id; 115 int controller; 116 int number; 117 } *cd; 118 #define DFLT_NCD 10 /* size of initial array */ 119 #define SIZE_OF_SR 2 /* |sr| */ 120 #define SIZE_OF_RSR 3 /* |rsr| */ 121 #define SIZE_OF_DSK 8 /* |/dev/dsk| */ 122 #define SIZE_OF_RDSK 9 /* |/dev/rdsk| */ 123 #define CD_CLEAN SECLIB"/sr_clean" 124 125 /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */ 126 struct rmdisk { 127 char *name; 128 char *device; 129 int id; 130 int controller; 131 int number; 132 } *rmdisk, *rmdisk_r; 133 #define DFLT_RMDISK 10 /* size of initial array */ 134 135 /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */ 136 struct fp { 137 char *name; 138 char *device; 139 int number; 140 } *fp; 141 #define DFLT_NFP 10 /* size of initial array */ 142 #define SIZE_OF_FD0 3 /* |fd0| */ 143 #define SIZE_OF_RFD0 4 /* |rfd0| */ 144 #define FLOPPY_CLEAN SECLIB"/fd_clean" 145 146 static void dotape(); 147 static void doaudio(); 148 static void dofloppy(); 149 static int docd(); 150 static void dormdisk(int); 151 static void initmem(); 152 static int expandmem(int, void **, int); 153 static void no_memory(void); 154 155 int system_labeled = 0; 156 int do_devalloc = 0; 157 int do_devmaps = 0; 158 int do_files = 0; 159 devlist_t devlist; 160 161 int 162 main(int argc, char **argv) 163 { 164 int cd_count = 0; 165 char *progname; 166 struct stat tx_stat; 167 168 (void) setlocale(LC_ALL, ""); 169 (void) textdomain(TEXT_DOMAIN); 170 171 if ((progname = strrchr(argv[0], '/')) == NULL) 172 progname = argv[0]; 173 else 174 progname++; 175 if (strcmp(progname, MKDEVALLOC) == 0) 176 do_devalloc = 1; 177 else if (strcmp(progname, MKDEVMAPS) == 0) 178 do_devmaps = 1; 179 else 180 exit(1); 181 182 system_labeled = is_system_labeled(); 183 if (system_labeled == 0) { 184 /* 185 * is_system_labeled() will return false in case we are 186 * starting before the first reboot after Trusted Extensions 187 * is installed. we check for a well known TX binary to 188 * to see if TX is installed. 189 */ 190 if (stat(DA_LABEL_CHECK, &tx_stat) == 0) 191 system_labeled = 1; 192 } 193 194 if (system_labeled && do_devalloc && (argc == 2) && 195 (strcmp(argv[1], DA_IS_LABELED) == 0)) { 196 /* 197 * write device entries to device_allocate and device_maps. 198 * default is to print them on stdout. 199 */ 200 do_files = 1; 201 } 202 203 initmem(); /* initialize memory */ 204 dotape(); 205 doaudio(); 206 dofloppy(); 207 cd_count = docd(); 208 if (system_labeled) 209 dormdisk(cd_count); 210 211 return (0); 212 } 213 214 static void 215 dotape() 216 { 217 DIR *dirp; 218 struct dirent *dep; /* directory entry pointer */ 219 int i, j; 220 char *nm; /* name/device of special device */ 221 char linkvalue[2048]; /* symlink value */ 222 struct stat stat; /* determine if it's a symlink */ 223 int sz; /* size of symlink value */ 224 char *cp; /* pointer into string */ 225 int ntape; /* max array size */ 226 int tape_count; 227 int first = 0; 228 char *dname, *dtype, *dclean; 229 da_args dargs; 230 deventry_t *entry; 231 232 ntape = DFLT_NTAPE; 233 234 /* 235 * look for rst* and nrst* 236 */ 237 238 if ((dirp = opendir("/dev")) == NULL) { 239 perror(gettext("open /dev failure")); 240 exit(1); 241 } 242 243 i = 0; 244 while (dep = readdir(dirp)) { 245 /* ignore if neither rst* nor nrst* */ 246 if (strncmp(dep->d_name, "rst", SIZE_OF_RST) && 247 strncmp(dep->d_name, "nrst", SIZE_OF_NRST)) 248 continue; 249 250 /* if array full, then expand it */ 251 if (i == ntape) { 252 /* will exit(1) if insufficient memory */ 253 ntape = expandmem(i, (void **)&tape, 254 sizeof (struct tape)); 255 } 256 257 /* save name (/dev + / + d_name + \0) */ 258 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); 259 if (nm == NULL) 260 no_memory(); 261 (void) strcpy(nm, "/dev/"); 262 (void) strcat(nm, dep->d_name); 263 tape[i].name = nm; 264 265 /* ignore if not symbolic link (note i not incremented) */ 266 if (lstat(tape[i].name, &stat) < 0) { 267 perror("stat(2) failed "); 268 exit(1); 269 } 270 if ((stat.st_mode & S_IFMT) != S_IFLNK) 271 continue; 272 273 /* get name from symbolic link */ 274 if ((sz = readlink(tape[i].name, linkvalue, 275 sizeof (linkvalue))) < 0) 276 continue; 277 nm = (char *)malloc(sz + 1); 278 if (nm == NULL) 279 no_memory(); 280 (void) strncpy(nm, linkvalue, sz); 281 nm[sz] = '\0'; 282 tape[i].device = nm; 283 284 /* get device number */ 285 cp = strrchr(tape[i].device, '/'); 286 cp++; /* advance to device # */ 287 (void) sscanf(cp, "%d", &tape[i].number); 288 289 i++; 290 } 291 292 (void) closedir(dirp); 293 294 /* 295 * scan /dev/rmt and add entry to table 296 */ 297 298 if ((dirp = opendir("/dev/rmt")) == NULL) { 299 perror(gettext("open /dev failure")); 300 exit(1); 301 } 302 303 while (dep = readdir(dirp)) { 304 /* skip . .. etc... */ 305 if (strncmp(dep->d_name, ".", 1) == NULL) 306 continue; 307 308 /* if array full, then expand it */ 309 if (i == ntape) { 310 /* will exit(1) if insufficient memory */ 311 ntape = expandmem(i, (void **)&tape, 312 sizeof (struct tape)); 313 } 314 315 /* save name (/dev/rmt + / + d_name + \0) */ 316 nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1); 317 if (nm == NULL) 318 no_memory(); 319 (void) strcpy(nm, "/dev/rmt/"); 320 (void) strcat(nm, dep->d_name); 321 tape[i].name = nm; 322 323 /* save device name (rmt/ + d_name + \0) */ 324 nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1); 325 if (nm == NULL) 326 no_memory(); 327 (void) strcpy(nm, "rmt/"); 328 (void) strcat(nm, dep->d_name); 329 tape[i].device = nm; 330 331 (void) sscanf(dep->d_name, "%d", &tape[i].number); 332 333 i++; 334 } 335 tape_count = i; 336 337 (void) closedir(dirp); 338 339 /* remove duplicate entries */ 340 for (i = 0; i < tape_count - 1; i++) { 341 for (j = i + 1; j < tape_count; j++) { 342 if (strcmp(tape[i].device, tape[j].device)) 343 continue; 344 tape[j].number = -1; 345 } 346 } 347 348 if (system_labeled) { 349 dname = DA_TAPE_NAME; 350 dtype = DA_TAPE_TYPE; 351 dclean = DA_DEFAULT_TAPE_CLEAN; 352 } else { 353 dname = "st"; 354 dtype = "st"; 355 dclean = TAPE_CLEAN; 356 } 357 for (i = 0; i < 8; i++) { 358 for (j = 0; j < tape_count; j++) { 359 if (tape[j].number != i) 360 continue; 361 if (do_files) { 362 (void) da_add_list(&devlist, tape[j].name, i, 363 DA_TAPE); 364 } else if (do_devalloc) { 365 /* print device_allocate for tape devices */ 366 if (system_labeled) { 367 (void) printf("%s%d%s\\\n", 368 dname, i, KV_DELIMITER); 369 (void) printf("\t%s%s\\\n", 370 DA_TAPE_TYPE, KV_DELIMITER); 371 (void) printf("\t%s%s\\\n", 372 DA_RESERVED, KV_DELIMITER); 373 (void) printf("\t%s%s\\\n", 374 DA_RESERVED, KV_DELIMITER); 375 (void) printf("\t%s%s\\\n", 376 DEFAULT_DEV_ALLOC_AUTH, 377 KV_DELIMITER); 378 (void) printf("\t%s\n\n", dclean); 379 } else { 380 (void) printf( 381 "st%d;st;reserved;reserved;%s;", 382 i, DEFAULT_DEV_ALLOC_AUTH); 383 (void) printf("%s%s\n", SECLIB, 384 "/st_clean"); 385 } 386 break; 387 } else if (do_devmaps) { 388 /* print device_maps for tape devices */ 389 if (first) { 390 (void) printf(" "); 391 } else { 392 if (system_labeled) { 393 (void) printf("%s%d%s\\\n", 394 dname, i, KV_TOKEN_DELIMIT); 395 (void) printf("\t%s%s\\\n", 396 dtype, KV_TOKEN_DELIMIT); 397 (void) printf("\t"); 398 } else { 399 (void) printf("st%d:\\\n", i); 400 (void) printf("\trmt:\\\n"); 401 (void) printf("\t"); 402 } 403 first++; 404 } 405 (void) printf("%s", tape[j].name); 406 } 407 } 408 if (do_devmaps && first) { 409 (void) printf("\n\n"); 410 first = 0; 411 } 412 } 413 if (do_files && tape_count) { 414 dargs.rootdir = NULL; 415 dargs.devnames = NULL; 416 dargs.optflag = DA_ADD; 417 for (entry = devlist.tape; entry != NULL; entry = entry->next) { 418 dargs.devinfo = &(entry->devinfo); 419 (void) da_update_device(&dargs); 420 } 421 } 422 } 423 424 static void 425 doaudio() 426 { 427 DIR *dirp; 428 struct dirent *dep; /* directory entry pointer */ 429 int i, j; 430 char *nm; /* name/device of special device */ 431 char linkvalue[2048]; /* symlink value */ 432 struct stat stat; /* determine if it's a symlink */ 433 int sz; /* size of symlink value */ 434 char *cp; /* pointer into string */ 435 int naudio; /* max array size */ 436 int audio_count = 0; 437 int len, slen; 438 int first = 0; 439 char dname[128]; 440 char *dclean; 441 da_args dargs; 442 deventry_t *entry; 443 444 naudio = DFLT_NAUDIO; 445 446 if ((dirp = opendir("/dev")) == NULL) { 447 perror(gettext("open /dev failure")); 448 exit(1); 449 } 450 451 i = 0; 452 while (dep = readdir(dirp)) { 453 if (strcmp(dep->d_name, "audio") && 454 strcmp(dep->d_name, "audioctl")) 455 continue; 456 457 /* if array full, then expand it */ 458 if (i == naudio) { 459 /* will exit(1) if insufficient memory */ 460 naudio = expandmem(i, (void **)&audio, 461 sizeof (struct audio)); 462 } 463 464 /* save name (/dev + 1 + d_name + \0) */ 465 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); 466 if (nm == NULL) 467 no_memory(); 468 (void) strcpy(nm, "/dev/"); 469 (void) strcat(nm, dep->d_name); 470 audio[i].name = nm; 471 472 /* ignore if not symbolic link (note i not incremented) */ 473 if (lstat(audio[i].name, &stat) < 0) { 474 perror(gettext("stat(2) failed ")); 475 exit(1); 476 } 477 if ((stat.st_mode & S_IFMT) != S_IFLNK) 478 continue; 479 480 /* get name from symbolic link */ 481 if ((sz = readlink(audio[i].name, linkvalue, 482 sizeof (linkvalue))) < 0) 483 continue; 484 nm = (char *)malloc(sz + 1); 485 if (nm == NULL) 486 no_memory(); 487 (void) strncpy(nm, linkvalue, sz); 488 nm[sz] = '\0'; 489 audio[i].device = nm; 490 491 cp = strrchr(audio[i].device, '/'); 492 cp++; /* advance to device # */ 493 (void) sscanf(cp, "%d", &audio[i].number); 494 495 i++; 496 } 497 498 (void) closedir(dirp); 499 500 if ((dirp = opendir("/dev/sound")) == NULL) { 501 goto skip; 502 } 503 504 while (dep = readdir(dirp)) { 505 /* skip . .. etc... */ 506 if (strncmp(dep->d_name, ".", 1) == NULL) 507 continue; 508 509 /* if array full, then expand it */ 510 if (i == naudio) { 511 /* will exit(1) if insufficient memory */ 512 naudio = expandmem(i, (void **)&audio, 513 sizeof (struct audio)); 514 } 515 516 /* save name (/dev/sound + / + d_name + \0) */ 517 nm = (char *)malloc(SIZE_OF_SOUND + 1 + 518 strlen(dep->d_name) + 1); 519 if (nm == NULL) 520 no_memory(); 521 (void) strcpy(nm, "/dev/sound/"); 522 (void) strcat(nm, dep->d_name); 523 audio[i].name = nm; 524 525 nm = (char *)malloc(SIZE_OF_SOUND + 1 + 526 strlen(dep->d_name) + 1); 527 if (nm == NULL) 528 no_memory(); 529 (void) strcpy(nm, "/dev/sound/"); 530 (void) strcat(nm, dep->d_name); 531 audio[i].device = nm; 532 533 (void) sscanf(dep->d_name, "%d", &audio[i].number); 534 535 i++; 536 } 537 538 (void) closedir(dirp); 539 540 skip: 541 audio_count = i; 542 543 /* remove duplicate entries */ 544 for (i = 0; i < audio_count - 1; i++) { 545 for (j = i + 1; j < audio_count; j++) { 546 if (strcmp(audio[i].device, audio[j].device)) 547 continue; 548 audio[j].number = -1; 549 } 550 } 551 552 /* print out device_allocate entries for audio devices */ 553 (void) strcpy(dname, DA_AUDIO_NAME); 554 slen = strlen(DA_AUDIO_NAME); 555 len = sizeof (dname) - slen; 556 dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN; 557 for (i = 0; i < 8; i++) { 558 for (j = 0; j < audio_count; j++) { 559 if (audio[j].number != i) 560 continue; 561 if (system_labeled) 562 (void) snprintf(dname+slen, len, "%d", i); 563 if (do_files) { 564 (void) da_add_list(&devlist, audio[j].name, 565 i, DA_AUDIO); 566 } else if (do_devalloc) { 567 /* print device_allocate for audio devices */ 568 if (system_labeled) { 569 (void) printf("%s%s\\\n", 570 dname, KV_DELIMITER); 571 (void) printf("\t%s%s\\\n", 572 DA_AUDIO_TYPE, KV_DELIMITER); 573 (void) printf("\t%s%s\\\n", 574 DA_RESERVED, KV_DELIMITER); 575 (void) printf("\t%s%s\\\n", 576 DA_RESERVED, KV_DELIMITER); 577 (void) printf("\t%s%s\\\n", 578 DEFAULT_DEV_ALLOC_AUTH, 579 KV_DELIMITER); 580 (void) printf("\t%s\n\n", dclean); 581 } else { 582 (void) printf("audio;audio;"); 583 (void) printf("reserved;reserved;%s;", 584 DEFAULT_DEV_ALLOC_AUTH); 585 (void) printf("%s%s\n", SECLIB, 586 "/audio_clean"); 587 } 588 break; 589 } else if (do_devmaps) { 590 /* print device_maps for audio devices */ 591 if (first) { 592 (void) printf(" "); 593 } else { 594 if (system_labeled) { 595 (void) printf("%s%s\\\n", 596 dname, KV_TOKEN_DELIMIT); 597 (void) printf("\t%s%s\\\n", 598 DA_AUDIO_TYPE, 599 KV_TOKEN_DELIMIT); 600 (void) printf("\t"); 601 } else { 602 (void) printf("audio:\\\n"); 603 (void) printf("\taudio:\\\n"); 604 (void) printf("\t"); 605 } 606 first++; 607 } 608 (void) printf("%s", audio[j].name); 609 } 610 } 611 if (do_devmaps && first) { 612 (void) printf("\n\n"); 613 first = 0; 614 } 615 } 616 if (do_files && audio_count) { 617 dargs.rootdir = NULL; 618 dargs.devnames = NULL; 619 dargs.optflag = DA_ADD; 620 for (entry = devlist.audio; entry != NULL; 621 entry = entry->next) { 622 dargs.devinfo = &(entry->devinfo); 623 (void) da_update_device(&dargs); 624 } 625 } 626 } 627 628 static void 629 dofloppy() 630 { 631 DIR *dirp; 632 struct dirent *dep; /* directory entry pointer */ 633 int i, j; 634 char *nm; /* name/device of special device */ 635 char linkvalue[2048]; /* symlink value */ 636 struct stat stat; /* determine if it's a symlink */ 637 int sz; /* size of symlink value */ 638 char *cp; /* pointer into string */ 639 int nfp; /* max array size */ 640 int floppy_count = 0; 641 int first = 0; 642 char *dname, *dclean; 643 da_args dargs; 644 deventry_t *entry; 645 646 nfp = DFLT_NFP; 647 648 /* 649 * look for fd* and rfd* 650 */ 651 652 if ((dirp = opendir("/dev")) == NULL) { 653 perror(gettext("open /dev failure")); 654 exit(1); 655 } 656 657 i = 0; 658 while (dep = readdir(dirp)) { 659 /* ignore if neither rst* nor nrst* */ 660 if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) && 661 strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) && 662 strncmp(dep->d_name, "fd1", SIZE_OF_FD0) && 663 strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0)) 664 continue; 665 666 /* if array full, then expand it */ 667 if (i == nfp) { 668 /* will exit(1) if insufficient memory */ 669 nfp = expandmem(i, (void **)&fp, sizeof (struct fp)); 670 } 671 672 /* save name (/dev + 1 + d_name + \0) */ 673 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); 674 if (nm == NULL) 675 no_memory(); 676 (void) strcpy(nm, "/dev/"); 677 (void) strcat(nm, dep->d_name); 678 fp[i].name = nm; 679 680 /* ignore if not symbolic link (note i not incremented) */ 681 if (lstat(fp[i].name, &stat) < 0) { 682 perror(gettext("stat(2) failed ")); 683 exit(1); 684 } 685 if ((stat.st_mode&S_IFMT) != S_IFLNK) 686 continue; 687 688 /* get name from symbolic link */ 689 if ((sz = readlink(fp[i].name, linkvalue, 690 sizeof (linkvalue))) < 0) 691 continue; 692 nm = (char *)malloc(sz+1); 693 if (nm == NULL) 694 no_memory(); 695 (void) strncpy(nm, linkvalue, sz); 696 nm[sz] = '\0'; 697 fp[i].device = nm; 698 699 /* get device number */ 700 cp = strchr(fp[i].name, 'd'); 701 cp++; /* advance to device # */ 702 cp = strchr(cp, 'd'); 703 cp++; /* advance to device # */ 704 (void) sscanf(cp, "%d", &fp[i].number); 705 706 i++; 707 } 708 709 (void) closedir(dirp); 710 711 floppy_count = i; 712 713 /* print out device_allocate entries for floppy devices */ 714 if (system_labeled) { 715 dname = DA_FLOPPY_NAME; 716 dclean = DA_DEFAULT_DISK_CLEAN; 717 } else { 718 dname = "fd"; 719 dclean = FLOPPY_CLEAN; 720 } 721 for (i = 0; i < 8; i++) { 722 for (j = 0; j < floppy_count; j++) { 723 if (fp[j].number != i) 724 continue; 725 if (do_files) { 726 (void) da_add_list(&devlist, fp[j].name, i, 727 DA_FLOPPY); 728 } else if (do_devalloc) { 729 /* print device_allocate for floppy devices */ 730 if (system_labeled) { 731 (void) printf("%s%d%s\\\n", 732 dname, i, KV_DELIMITER); 733 (void) printf("\t%s%s\\\n", 734 DA_FLOPPY_TYPE, KV_DELIMITER); 735 (void) printf("\t%s%s\\\n", 736 DA_RESERVED, KV_DELIMITER); 737 (void) printf("\t%s%s\\\n", 738 DA_RESERVED, KV_DELIMITER); 739 (void) printf("\t%s%s\\\n", 740 DEFAULT_DEV_ALLOC_AUTH, 741 KV_DELIMITER); 742 (void) printf("\t%s\n\n", dclean); 743 } else { 744 (void) printf( 745 "fd%d;fd;reserved;reserved;%s;", 746 i, DEFAULT_DEV_ALLOC_AUTH); 747 (void) printf("%s%s\n", SECLIB, 748 "/fd_clean"); 749 } 750 break; 751 } else if (do_devmaps) { 752 /* print device_maps for floppy devices */ 753 if (first) { 754 (void) printf(" "); 755 } else { 756 if (system_labeled) { 757 (void) printf("%s%d%s\\\n", 758 dname, i, KV_TOKEN_DELIMIT); 759 (void) printf("\t%s%s\\\n", 760 DA_FLOPPY_TYPE, 761 KV_TOKEN_DELIMIT); 762 (void) printf("\t"); 763 } else { 764 (void) printf("fd%d:\\\n", i); 765 (void) printf("\tfd:\\\n"); 766 (void) printf("\t"); 767 } 768 if (i == 0) { 769 (void) printf("/dev/diskette "); 770 (void) printf( 771 "/dev/rdiskette "); 772 } 773 first++; 774 } 775 (void) printf("%s", fp[j].name); 776 } 777 } 778 if (do_devmaps && first) { 779 (void) printf("\n\n"); 780 first = 0; 781 } 782 } 783 if (do_files && floppy_count) { 784 dargs.rootdir = NULL; 785 dargs.devnames = NULL; 786 dargs.optflag = DA_ADD; 787 for (entry = devlist.floppy; entry != NULL; 788 entry = entry->next) { 789 dargs.devinfo = &(entry->devinfo); 790 (void) da_update_device(&dargs); 791 } 792 } 793 } 794 795 static int 796 docd() 797 { 798 DIR *dirp; 799 struct dirent *dep; /* directory entry pointer */ 800 int i, j; 801 char *nm; /* name/device of special device */ 802 char linkvalue[2048]; /* symlink value */ 803 struct stat stat; /* determine if it's a symlink */ 804 int sz; /* size of symlink value */ 805 char *cp; /* pointer into string */ 806 int id; /* disk id */ 807 int ctrl; /* disk controller */ 808 int ncd; /* max array size */ 809 int cd_count = 0; 810 int first = 0; 811 char *dname, *dclean; 812 da_args dargs; 813 deventry_t *entry; 814 815 ncd = DFLT_NCD; 816 817 /* 818 * look for sr* and rsr* 819 */ 820 821 if ((dirp = opendir("/dev")) == NULL) { 822 perror(gettext("open /dev failure")); 823 exit(1); 824 } 825 826 i = 0; 827 while (dep = readdir(dirp)) { 828 /* ignore if neither sr* nor rsr* */ 829 if (strncmp(dep->d_name, "sr", SIZE_OF_SR) && 830 strncmp(dep->d_name, "rsr", SIZE_OF_RSR)) 831 continue; 832 833 /* if array full, then expand it */ 834 if (i == ncd) { 835 /* will exit(1) if insufficient memory */ 836 ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); 837 } 838 839 /* save name (/dev + / + d_name + \0) */ 840 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); 841 if (nm == NULL) 842 no_memory(); 843 (void) strcpy(nm, "/dev/"); 844 (void) strcat(nm, dep->d_name); 845 cd[i].name = nm; 846 847 /* save id # */ 848 if (dep->d_name[0] == 'r') 849 (void) sscanf(dep->d_name, "rsr%d", &cd[i].id); 850 else 851 (void) sscanf(dep->d_name, "sr%d", &cd[i].id); 852 853 /* ignore if not symbolic link (note i not incremented) */ 854 if (lstat(cd[i].name, &stat) < 0) { 855 perror(gettext("stat(2) failed ")); 856 exit(1); 857 } 858 if ((stat.st_mode & S_IFMT) != S_IFLNK) 859 continue; 860 861 /* get name from symbolic link */ 862 if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) < 863 0) 864 continue; 865 866 nm = (char *)malloc(sz + 1); 867 if (nm == NULL) 868 no_memory(); 869 (void) strncpy(nm, linkvalue, sz); 870 nm[sz] = '\0'; 871 cd[i].device = nm; 872 873 cp = strrchr(cd[i].device, '/'); 874 cp++; /* advance to device # */ 875 (void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number); 876 877 i++; 878 } 879 cd_count = i; 880 881 (void) closedir(dirp); 882 883 /* 884 * scan /dev/dsk for cd devices 885 */ 886 887 if ((dirp = opendir("/dev/dsk")) == NULL) { 888 perror("gettext(open /dev/dsk failure)"); 889 exit(1); 890 } 891 892 while (dep = readdir(dirp)) { 893 /* skip . .. etc... */ 894 if (strncmp(dep->d_name, ".", 1) == NULL) 895 continue; 896 897 /* get device # (disk #) */ 898 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0) 899 continue; 900 901 /* see if this is one of the cd special devices */ 902 for (j = 0; j < cd_count; j++) { 903 if (cd[j].number == id && cd[j].controller == ctrl) 904 goto found; 905 } 906 continue; 907 908 /* add new entry to table (/dev/dsk + / + d_name + \0) */ 909 found: 910 /* if array full, then expand it */ 911 if (i == ncd) { 912 /* will exit(1) if insufficient memory */ 913 ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); 914 } 915 916 nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1); 917 if (nm == NULL) 918 no_memory(); 919 (void) strcpy(nm, "/dev/dsk/"); 920 (void) strcat(nm, dep->d_name); 921 cd[i].name = nm; 922 923 cd[i].id = cd[j].id; 924 925 cd[i].device = ""; 926 927 cd[i].number = id; 928 929 i++; 930 } 931 932 (void) closedir(dirp); 933 934 /* 935 * scan /dev/rdsk for cd devices 936 */ 937 938 if ((dirp = opendir("/dev/rdsk")) == NULL) { 939 perror(gettext("open /dev/dsk failure")); 940 exit(1); 941 } 942 943 while (dep = readdir(dirp)) { 944 /* skip . .. etc... */ 945 if (strncmp(dep->d_name, ".", 1) == NULL) 946 continue; 947 948 /* get device # (disk #) */ 949 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2) 950 continue; 951 952 /* see if this is one of the cd special devices */ 953 for (j = 0; j < cd_count; j++) { 954 if (cd[j].number == id && cd[j].controller == ctrl) 955 goto found1; 956 } 957 continue; 958 959 /* add new entry to table (/dev/rdsk + / + d_name + \0) */ 960 found1: 961 /* if array full, then expand it */ 962 if (i == ncd) { 963 /* will exit(1) if insufficient memory */ 964 ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); 965 } 966 967 nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1); 968 if (nm == NULL) 969 no_memory(); 970 (void) strcpy(nm, "/dev/rdsk/"); 971 (void) strcat(nm, dep->d_name); 972 cd[i].name = nm; 973 974 cd[i].id = cd[j].id; 975 976 cd[i].device = ""; 977 978 cd[i].number = id; 979 980 cd[i].controller = ctrl; 981 982 i++; 983 } 984 985 (void) closedir(dirp); 986 987 cd_count = i; 988 989 if (system_labeled) { 990 dname = DA_CD_NAME; 991 dclean = DA_DEFAULT_DISK_CLEAN; 992 } else { 993 dname = "sr"; 994 dclean = CD_CLEAN; 995 } 996 for (i = 0; i < 8; i++) { 997 for (j = 0; j < cd_count; j++) { 998 if (cd[j].id != i) 999 continue; 1000 if (do_files) { 1001 (void) da_add_list(&devlist, cd[j].name, i, 1002 DA_CD); 1003 } else if (do_devalloc) { 1004 /* print device_allocate for cd devices */ 1005 if (system_labeled) { 1006 (void) printf("%s%d%s\\\n", 1007 dname, i, KV_DELIMITER); 1008 (void) printf("\t%s%s\\\n", 1009 DA_CD_TYPE, KV_DELIMITER); 1010 (void) printf("\t%s%s\\\n", 1011 DA_RESERVED, KV_DELIMITER); 1012 (void) printf("\t%s%s\\\n", 1013 DA_RESERVED, KV_DELIMITER); 1014 (void) printf("\t%s%s\\\n", 1015 DEFAULT_DEV_ALLOC_AUTH, 1016 KV_DELIMITER); 1017 (void) printf("\t%s\n\n", dclean); 1018 } else { 1019 (void) printf( 1020 "sr%d;sr;reserved;reserved;%s;", 1021 i, DEFAULT_DEV_ALLOC_AUTH); 1022 (void) printf("%s%s\n", SECLIB, 1023 "/sr_clean"); 1024 } 1025 break; 1026 } else if (do_devmaps) { 1027 /* print device_maps for cd devices */ 1028 if (first) { 1029 (void) printf(" "); 1030 } else { 1031 if (system_labeled) { 1032 (void) printf("%s%d%s\\\n", 1033 dname, i, KV_TOKEN_DELIMIT); 1034 (void) printf("\t%s%s\\\n", 1035 DA_CD_TYPE, 1036 KV_TOKEN_DELIMIT); 1037 (void) printf("\t"); 1038 } else { 1039 (void) printf("sr%d:\\\n", i); 1040 (void) printf("\tsr:\\\n"); 1041 (void) printf("\t"); 1042 } 1043 first++; 1044 } 1045 (void) printf("%s", cd[j].name); 1046 } 1047 } 1048 if (do_devmaps && first) { 1049 (void) printf("\n\n"); 1050 first = 0; 1051 } 1052 } 1053 if (do_files && cd_count) { 1054 dargs.rootdir = NULL; 1055 dargs.devnames = NULL; 1056 dargs.optflag = DA_ADD; 1057 for (entry = devlist.cd; entry != NULL; entry = entry->next) { 1058 dargs.devinfo = &(entry->devinfo); 1059 (void) da_update_device(&dargs); 1060 } 1061 } 1062 1063 return (cd_count); 1064 } 1065 1066 static void 1067 dormdisk(int cd_count) 1068 { 1069 DIR *dirp; 1070 struct dirent *dep; /* directory entry pointer */ 1071 int i, j; 1072 char *nm; /* name/device of special device */ 1073 int id; /* disk id */ 1074 int ctrl; /* disk controller */ 1075 int nrmdisk; /* max array size */ 1076 int fd = -1; 1077 int rmdisk_count; 1078 int first = 0; 1079 int is_cd; 1080 int checked; 1081 int removable; 1082 char path[MAXPATHLEN]; 1083 da_args dargs; 1084 deventry_t *entry; 1085 1086 nrmdisk = DFLT_RMDISK; 1087 i = rmdisk_count = 0; 1088 1089 /* 1090 * scan /dev/dsk for rmdisk devices 1091 */ 1092 if ((dirp = opendir("/dev/dsk")) == NULL) { 1093 perror("gettext(open /dev/dsk failure)"); 1094 exit(1); 1095 } 1096 1097 while (dep = readdir(dirp)) { 1098 is_cd = 0; 1099 checked = 0; 1100 removable = 0; 1101 /* skip . .. etc... */ 1102 if (strncmp(dep->d_name, ".", 1) == NULL) 1103 continue; 1104 1105 /* get device # (disk #) */ 1106 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0) 1107 continue; 1108 1109 /* see if we've already examined this device */ 1110 for (j = 0; j < i; j++) { 1111 if (id == rmdisk[j].id && 1112 ctrl == rmdisk[j].controller && 1113 (strcmp(dep->d_name, rmdisk[j].name) == 0)) { 1114 checked = 1; 1115 break; 1116 } 1117 if (id == rmdisk[j].id && ctrl != rmdisk[j].controller) 1118 /* 1119 * c2t0d0s0 is a different rmdisk than c3t0d0s0. 1120 */ 1121 id = rmdisk[j].id + 1; 1122 } 1123 if (checked) 1124 continue; 1125 1126 /* ignore if this is a cd */ 1127 for (j = 0; j < cd_count; j++) { 1128 if (id == cd[j].number && ctrl == cd[j].controller) { 1129 is_cd = 1; 1130 break; 1131 } 1132 } 1133 if (is_cd) 1134 continue; 1135 1136 /* see if device is removable */ 1137 (void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/", 1138 dep->d_name); 1139 if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0) 1140 continue; 1141 (void) ioctl(fd, DKIOCREMOVABLE, &removable); 1142 (void) close(fd); 1143 if (removable == 0) 1144 continue; 1145 1146 /* 1147 * add new entry to table (/dev/dsk + / + d_name + \0) 1148 * if array full, then expand it 1149 */ 1150 if (i == nrmdisk) { 1151 /* will exit(1) if insufficient memory */ 1152 nrmdisk = expandmem(i, (void **)&rmdisk, 1153 sizeof (struct rmdisk)); 1154 } 1155 nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1); 1156 if (nm == NULL) 1157 no_memory(); 1158 (void) strcpy(nm, "/dev/dsk/"); 1159 (void) strcat(nm, dep->d_name); 1160 rmdisk[i].name = nm; 1161 rmdisk[i].id = id; 1162 rmdisk[i].controller = ctrl; 1163 rmdisk[i].device = ""; 1164 rmdisk[i].number = id; 1165 rmdisk_r[i].name = strdup(path); 1166 i++; 1167 } 1168 1169 rmdisk_count = i; 1170 (void) closedir(dirp); 1171 1172 for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) { 1173 if (j == nrmdisk) { 1174 /* will exit(1) if insufficient memory */ 1175 nrmdisk = expandmem(j, (void **)&rmdisk, 1176 sizeof (struct rmdisk)); 1177 } 1178 rmdisk[j].name = rmdisk_r[i].name; 1179 rmdisk[j].id = rmdisk[i].id; 1180 rmdisk[j].controller = rmdisk[i].controller; 1181 rmdisk[j].device = rmdisk[i].device; 1182 rmdisk[j].number = rmdisk[i].number; 1183 } 1184 rmdisk_count = j; 1185 1186 for (i = 0; i < 8; i++) { 1187 for (j = 0; j < rmdisk_count; j++) { 1188 if (rmdisk[j].id != i) 1189 continue; 1190 if (do_files) { 1191 (void) da_add_list(&devlist, rmdisk[j].name, i, 1192 DA_RMDISK); 1193 } else if (do_devalloc) { 1194 /* print device_allocate for rmdisk devices */ 1195 (void) printf("%s%d%s\\\n", 1196 DA_RMDISK_NAME, i, KV_DELIMITER); 1197 (void) printf("\t%s%s\\\n", 1198 DA_RMDISK_TYPE, KV_DELIMITER); 1199 (void) printf("\t%s%s\\\n", 1200 DA_RESERVED, KV_DELIMITER); 1201 (void) printf("\t%s%s\\\n", 1202 DA_RESERVED, KV_DELIMITER); 1203 (void) printf("\t%s%s\\\n", 1204 DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER); 1205 (void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN); 1206 break; 1207 } else if (do_devmaps) { 1208 /* print device_maps for rmdisk devices */ 1209 if (first) { 1210 (void) printf(" "); 1211 } else { 1212 (void) printf("%s%d%s\\\n", 1213 DA_RMDISK_NAME, i, 1214 KV_TOKEN_DELIMIT); 1215 (void) printf("\t%s%s\\\n", 1216 DA_RMDISK_TYPE, KV_TOKEN_DELIMIT); 1217 (void) printf("\t"); 1218 first++; 1219 } 1220 (void) printf("%s", rmdisk[j].name); 1221 } 1222 } 1223 if (do_devmaps && first) { 1224 (void) printf("\n\n"); 1225 first = 0; 1226 } 1227 } 1228 if (do_files && rmdisk_count) { 1229 dargs.rootdir = NULL; 1230 dargs.devnames = NULL; 1231 dargs.optflag = DA_ADD; 1232 for (entry = devlist.rmdisk; entry != NULL; 1233 entry = entry->next) { 1234 dargs.devinfo = &(entry->devinfo); 1235 (void) da_update_device(&dargs); 1236 } 1237 } 1238 } 1239 1240 /* set default array sizes */ 1241 static void 1242 initmem() 1243 { 1244 tape = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape)); 1245 audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio)); 1246 cd = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd)); 1247 fp = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp)); 1248 if (system_labeled) { 1249 rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK, 1250 sizeof (struct rmdisk)); 1251 if (rmdisk == NULL) 1252 no_memory(); 1253 rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK, 1254 sizeof (struct rmdisk)); 1255 if (rmdisk_r == NULL) 1256 no_memory(); 1257 } 1258 1259 if (tape == NULL || audio == NULL || cd == NULL || fp == NULL) 1260 no_memory(); 1261 1262 devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk = 1263 devlist.tape = NULL; 1264 } 1265 1266 /* note n will be # elments in array (and could be 0) */ 1267 static int 1268 expandmem(int n, void **array, int size) 1269 { 1270 void *old = *array; 1271 void *new; 1272 1273 /* get new array space (n + DELTA) */ 1274 new = (void *)calloc(n + DELTA, size); 1275 1276 if (new == NULL) { 1277 perror("memory allocation failed"); 1278 exit(1); 1279 } 1280 1281 /* copy old array into new space */ 1282 bcopy(old, new, n * size); 1283 1284 /* now release old arrary */ 1285 free(old); 1286 1287 *array = new; 1288 1289 return (n + DELTA); 1290 } 1291 1292 static void 1293 no_memory(void) 1294 { 1295 (void) fprintf(stderr, "%s: %s\n", "mkdevalloc", 1296 gettext("out of memory")); 1297 exit(1); 1298 /* NOT REACHED */ 1299 } 1300