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 /* save id # */ 858 if (dep->d_name[0] == 'r') 859 (void) sscanf(dep->d_name, "rsr%d", &cd[i].id); 860 else 861 (void) sscanf(dep->d_name, "sr%d", &cd[i].id); 862 863 /* ignore if not symbolic link (note i not incremented) */ 864 if (lstat(cd[i].name, &stat) < 0) { 865 perror(gettext("stat(2) failed ")); 866 exit(1); 867 } 868 if ((stat.st_mode & S_IFMT) != S_IFLNK) 869 continue; 870 871 /* get name from symbolic link */ 872 if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) < 873 0) 874 continue; 875 876 nm = (char *)malloc(sz + 1); 877 if (nm == NULL) 878 no_memory(); 879 (void) strncpy(nm, linkvalue, sz); 880 nm[sz] = '\0'; 881 cd[i].device = nm; 882 883 cp = strrchr(cd[i].device, '/'); 884 cp++; /* advance to device # */ 885 (void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number); 886 887 i++; 888 } 889 cd_count = i; 890 891 (void) closedir(dirp); 892 893 /* 894 * scan /dev/dsk for cd devices 895 */ 896 897 if ((dirp = opendir("/dev/dsk")) == NULL) { 898 perror("gettext(open /dev/dsk failure)"); 899 exit(1); 900 } 901 902 while (dep = readdir(dirp)) { 903 /* skip . .. etc... */ 904 if (strncmp(dep->d_name, ".", 1) == NULL) 905 continue; 906 907 /* get device # (disk #) */ 908 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0) 909 continue; 910 911 /* see if this is one of the cd special devices */ 912 for (j = 0; j < cd_count; j++) { 913 if (cd[j].number == id && cd[j].controller == ctrl) 914 goto found; 915 } 916 continue; 917 918 /* add new entry to table (/dev/dsk + / + d_name + \0) */ 919 found: 920 /* if array full, then expand it */ 921 if (i == ncd) { 922 /* will exit(1) if insufficient memory */ 923 ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); 924 } 925 926 nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1); 927 if (nm == NULL) 928 no_memory(); 929 (void) strcpy(nm, "/dev/dsk/"); 930 (void) strcat(nm, dep->d_name); 931 cd[i].name = nm; 932 933 cd[i].id = cd[j].id; 934 935 cd[i].device = ""; 936 937 cd[i].number = id; 938 939 i++; 940 } 941 942 (void) closedir(dirp); 943 944 /* 945 * scan /dev/rdsk for cd devices 946 */ 947 948 if ((dirp = opendir("/dev/rdsk")) == NULL) { 949 perror(gettext("open /dev/dsk failure")); 950 exit(1); 951 } 952 953 while (dep = readdir(dirp)) { 954 /* skip . .. etc... */ 955 if (strncmp(dep->d_name, ".", 1) == NULL) 956 continue; 957 958 /* get device # (disk #) */ 959 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2) 960 continue; 961 962 /* see if this is one of the cd special devices */ 963 for (j = 0; j < cd_count; j++) { 964 if (cd[j].number == id && cd[j].controller == ctrl) 965 goto found1; 966 } 967 continue; 968 969 /* add new entry to table (/dev/rdsk + / + d_name + \0) */ 970 found1: 971 /* if array full, then expand it */ 972 if (i == ncd) { 973 /* will exit(1) if insufficient memory */ 974 ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); 975 } 976 977 nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1); 978 if (nm == NULL) 979 no_memory(); 980 (void) strcpy(nm, "/dev/rdsk/"); 981 (void) strcat(nm, dep->d_name); 982 cd[i].name = nm; 983 984 cd[i].id = cd[j].id; 985 986 cd[i].device = ""; 987 988 cd[i].number = id; 989 990 cd[i].controller = ctrl; 991 992 i++; 993 } 994 995 (void) closedir(dirp); 996 997 cd_count = i; 998 999 if (system_labeled) { 1000 dname = DA_CD_NAME; 1001 dclean = DA_DEFAULT_DISK_CLEAN; 1002 } else { 1003 dname = "sr"; 1004 dclean = CD_CLEAN; 1005 } 1006 for (i = 0; i < 8; i++) { 1007 for (j = 0; j < cd_count; j++) { 1008 if (cd[j].id != i) 1009 continue; 1010 if (do_files) { 1011 (void) da_add_list(&devlist, cd[j].name, i, 1012 DA_CD); 1013 } else if (do_devalloc) { 1014 /* print device_allocate for cd devices */ 1015 if (system_labeled) { 1016 (void) printf("%s%d%s\\\n", 1017 dname, i, KV_DELIMITER); 1018 (void) printf("\t%s%s\\\n", 1019 DA_CD_TYPE, KV_DELIMITER); 1020 (void) printf("\t%s%s\\\n", 1021 DA_RESERVED, KV_DELIMITER); 1022 (void) printf("\t%s%s\\\n", 1023 DA_RESERVED, KV_DELIMITER); 1024 (void) printf("\t%s%s\\\n", 1025 DEFAULT_DEV_ALLOC_AUTH, 1026 KV_DELIMITER); 1027 (void) printf("\t%s\n\n", dclean); 1028 } else { 1029 (void) printf( 1030 "sr%d;sr;reserved;reserved;%s;", 1031 i, DEFAULT_DEV_ALLOC_AUTH); 1032 (void) printf("%s%s\n", SECLIB, 1033 "/sr_clean"); 1034 } 1035 break; 1036 } else if (do_devmaps) { 1037 /* print device_maps for cd devices */ 1038 if (first) { 1039 (void) printf(" "); 1040 } else { 1041 if (system_labeled) { 1042 (void) printf("%s%d%s\\\n", 1043 dname, i, KV_TOKEN_DELIMIT); 1044 (void) printf("\t%s%s\\\n", 1045 DA_CD_TYPE, 1046 KV_TOKEN_DELIMIT); 1047 (void) printf("\t"); 1048 } else { 1049 (void) printf("sr%d:\\\n", i); 1050 (void) printf("\tsr:\\\n"); 1051 (void) printf("\t"); 1052 } 1053 first++; 1054 } 1055 (void) printf("%s", cd[j].name); 1056 } 1057 } 1058 if (do_devmaps && first) { 1059 (void) printf("\n\n"); 1060 first = 0; 1061 } 1062 } 1063 if (do_files && cd_count) { 1064 dargs.rootdir = NULL; 1065 dargs.devnames = NULL; 1066 dargs.optflag = DA_ADD; 1067 for (entry = devlist.cd; entry != NULL; entry = entry->next) { 1068 dargs.devinfo = &(entry->devinfo); 1069 (void) da_update_device(&dargs); 1070 } 1071 } 1072 1073 return (cd_count); 1074 } 1075 1076 static void 1077 dormdisk(int cd_count) 1078 { 1079 DIR *dirp; 1080 struct dirent *dep; /* directory entry pointer */ 1081 int i, j; 1082 char *nm; /* name/device of special device */ 1083 int id; /* disk id */ 1084 int ctrl; /* disk controller */ 1085 int nrmdisk; /* max array size */ 1086 int fd = -1; 1087 int rmdisk_count; 1088 int first = 0; 1089 int is_cd; 1090 int checked; 1091 int removable; 1092 char path[MAXPATHLEN]; 1093 da_args dargs; 1094 deventry_t *entry; 1095 1096 nrmdisk = DFLT_RMDISK; 1097 i = rmdisk_count = 0; 1098 1099 /* 1100 * scan /dev/dsk for rmdisk devices 1101 */ 1102 if ((dirp = opendir("/dev/dsk")) == NULL) { 1103 perror("gettext(open /dev/dsk failure)"); 1104 exit(1); 1105 } 1106 1107 while (dep = readdir(dirp)) { 1108 is_cd = 0; 1109 checked = 0; 1110 removable = 0; 1111 /* skip . .. etc... */ 1112 if (strncmp(dep->d_name, ".", 1) == NULL) 1113 continue; 1114 1115 /* get device # (disk #) */ 1116 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0) 1117 continue; 1118 1119 /* see if we've already examined this device */ 1120 for (j = 0; j < i; j++) { 1121 if (id == rmdisk[j].id && 1122 ctrl == rmdisk[j].controller && 1123 (strcmp(dep->d_name, rmdisk[j].name) == 0)) { 1124 checked = 1; 1125 break; 1126 } 1127 if (id == rmdisk[j].id && ctrl != rmdisk[j].controller) 1128 /* 1129 * c2t0d0s0 is a different rmdisk than c3t0d0s0. 1130 */ 1131 id = rmdisk[j].id + 1; 1132 } 1133 if (checked) 1134 continue; 1135 1136 /* ignore if this is a cd */ 1137 for (j = 0; j < cd_count; j++) { 1138 if (id == cd[j].number && ctrl == cd[j].controller) { 1139 is_cd = 1; 1140 break; 1141 } 1142 } 1143 if (is_cd) 1144 continue; 1145 1146 /* see if device is removable */ 1147 (void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/", 1148 dep->d_name); 1149 if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0) 1150 continue; 1151 (void) ioctl(fd, DKIOCREMOVABLE, &removable); 1152 (void) close(fd); 1153 if (removable == 0) 1154 continue; 1155 1156 /* 1157 * add new entry to table (/dev/dsk + / + d_name + \0) 1158 * if array full, then expand it 1159 */ 1160 if (i == nrmdisk) { 1161 /* will exit(1) if insufficient memory */ 1162 nrmdisk = expandmem(i, (void **)&rmdisk, 1163 sizeof (struct rmdisk)); 1164 } 1165 nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1); 1166 if (nm == NULL) 1167 no_memory(); 1168 (void) strcpy(nm, "/dev/dsk/"); 1169 (void) strcat(nm, dep->d_name); 1170 rmdisk[i].name = nm; 1171 rmdisk[i].id = id; 1172 rmdisk[i].controller = ctrl; 1173 rmdisk[i].device = ""; 1174 rmdisk[i].number = id; 1175 rmdisk_r[i].name = strdup(path); 1176 i++; 1177 } 1178 1179 rmdisk_count = i; 1180 (void) closedir(dirp); 1181 1182 for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) { 1183 if (j == nrmdisk) { 1184 /* will exit(1) if insufficient memory */ 1185 nrmdisk = expandmem(j, (void **)&rmdisk, 1186 sizeof (struct rmdisk)); 1187 } 1188 rmdisk[j].name = rmdisk_r[i].name; 1189 rmdisk[j].id = rmdisk[i].id; 1190 rmdisk[j].controller = rmdisk[i].controller; 1191 rmdisk[j].device = rmdisk[i].device; 1192 rmdisk[j].number = rmdisk[i].number; 1193 } 1194 rmdisk_count = j; 1195 1196 for (i = 0; i < 8; i++) { 1197 for (j = 0; j < rmdisk_count; j++) { 1198 if (rmdisk[j].id != i) 1199 continue; 1200 if (do_files) { 1201 (void) da_add_list(&devlist, rmdisk[j].name, i, 1202 DA_RMDISK); 1203 } else if (do_devalloc) { 1204 /* print device_allocate for rmdisk devices */ 1205 (void) printf("%s%d%s\\\n", 1206 DA_RMDISK_NAME, i, KV_DELIMITER); 1207 (void) printf("\t%s%s\\\n", 1208 DA_RMDISK_TYPE, KV_DELIMITER); 1209 (void) printf("\t%s%s\\\n", 1210 DA_RESERVED, KV_DELIMITER); 1211 (void) printf("\t%s%s\\\n", 1212 DA_RESERVED, KV_DELIMITER); 1213 (void) printf("\t%s%s\\\n", 1214 DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER); 1215 (void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN); 1216 break; 1217 } else if (do_devmaps) { 1218 /* print device_maps for rmdisk devices */ 1219 if (first) { 1220 (void) printf(" "); 1221 } else { 1222 (void) printf("%s%d%s\\\n", 1223 DA_RMDISK_NAME, i, 1224 KV_TOKEN_DELIMIT); 1225 (void) printf("\t%s%s\\\n", 1226 DA_RMDISK_TYPE, KV_TOKEN_DELIMIT); 1227 (void) printf("\t"); 1228 first++; 1229 } 1230 (void) printf("%s", rmdisk[j].name); 1231 } 1232 } 1233 if (do_devmaps && first) { 1234 (void) printf("\n\n"); 1235 first = 0; 1236 } 1237 } 1238 if (do_files && rmdisk_count) { 1239 dargs.rootdir = NULL; 1240 dargs.devnames = NULL; 1241 dargs.optflag = DA_ADD; 1242 for (entry = devlist.rmdisk; entry != NULL; 1243 entry = entry->next) { 1244 dargs.devinfo = &(entry->devinfo); 1245 (void) da_update_device(&dargs); 1246 } 1247 } 1248 } 1249 1250 /* set default array sizes */ 1251 static void 1252 initmem() 1253 { 1254 tape = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape)); 1255 audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio)); 1256 cd = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd)); 1257 fp = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp)); 1258 if (system_labeled) { 1259 rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK, 1260 sizeof (struct rmdisk)); 1261 if (rmdisk == NULL) 1262 no_memory(); 1263 rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK, 1264 sizeof (struct rmdisk)); 1265 if (rmdisk_r == NULL) 1266 no_memory(); 1267 } 1268 1269 if (tape == NULL || audio == NULL || cd == NULL || fp == NULL) 1270 no_memory(); 1271 1272 devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk = 1273 devlist.tape = NULL; 1274 } 1275 1276 /* note n will be # elments in array (and could be 0) */ 1277 static int 1278 expandmem(int n, void **array, int size) 1279 { 1280 void *old = *array; 1281 void *new; 1282 1283 /* get new array space (n + DELTA) */ 1284 new = (void *)calloc(n + DELTA, size); 1285 1286 if (new == NULL) { 1287 perror("memory allocation failed"); 1288 exit(1); 1289 } 1290 1291 /* copy old array into new space */ 1292 bcopy(old, new, n * size); 1293 1294 /* now release old arrary */ 1295 free(old); 1296 1297 *array = new; 1298 1299 return (n + DELTA); 1300 } 1301 1302 static void 1303 no_memory(void) 1304 { 1305 (void) fprintf(stderr, "%s: %s\n", "mkdevalloc", 1306 gettext("out of memory")); 1307 exit(1); 1308 /* NOT REACHED */ 1309 } 1310