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