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