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