/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * scan /dev directory for mountable objects and construct device_allocate * file for allocate.... * * devices are: * tape (cartridge) * /dev/rst* * /dev/nrst* * /dev/rmt/... * audio * /dev/audio * /dev/audioctl * /dev/sound/... * floppy * /dev/diskette * /dev/fd* * /dev/rdiskette * /dev/rfd* * CD * /dev/sr* * /dev/nsr* * /dev/dsk/c?t?d0s? * /dev/rdsk/c?t?d0s? * */ #include <errno.h> #include <fcntl.h> #include <sys/types.h> /* for stat(2), etc. */ #include <sys/stat.h> #include <dirent.h> /* for readdir(3), etc. */ #include <unistd.h> /* for readlink(2) */ #include <stropts.h> #include <string.h> /* for strcpy(3), etc. */ #include <strings.h> /* for bcopy(3C), etc. */ #include <stdio.h> /* for perror(3) */ #include <stdlib.h> /* for atoi(3) */ #include <sys/dkio.h> #include <locale.h> #include <libintl.h> #include <libdevinfo.h> #include <secdb.h> #include <auth_attr.h> #include <auth_list.h> #include <bsm/devices.h> #include <bsm/devalloc.h> #include <tsol/label.h> #ifndef TEXT_DOMAIN #define TEXT_DOMAIN "SUNW_OST_OSCMD" #endif #define MKDEVALLOC "mkdevalloc" #define MKDEVMAPS "mkdevmaps" #define DELTA 5 /* array size delta when full */ #define SECLIB "/etc/security/lib" /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */ struct tape { char *name; char *device; int number; } *tape; #define DFLT_NTAPE 10 /* size of initial array */ #define SIZE_OF_RST 3 /* |rmt| */ #define SIZE_OF_NRST 4 /* |nrmt| */ #define SIZE_OF_TMP 4 /* |/tmp| */ #define SIZE_OF_RMT 8 /* |/dev/rmt| */ #define TAPE_CLEAN SECLIB"/st_clean" /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */ struct audio { char *name; char *device; int number; } *audio; #define DFLT_NAUDIO 10 /* size of initial array */ #define SIZE_OF_SOUND 10 /* |/dev/sound| */ #define AUDIO_CLEAN SECLIB"/audio_clean" /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */ struct cd { char *name; char *device; int id; int controller; int number; } *cd; #define DFLT_NCD 10 /* size of initial array */ #define SIZE_OF_SR 2 /* |sr| */ #define SIZE_OF_RSR 3 /* |rsr| */ #define SIZE_OF_DSK 8 /* |/dev/dsk| */ #define SIZE_OF_RDSK 9 /* |/dev/rdsk| */ #define CD_CLEAN SECLIB"/sr_clean" /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */ struct rmdisk { char *name; char *device; int id; int controller; int number; } *rmdisk, *rmdisk_r; #define DFLT_RMDISK 10 /* size of initial array */ /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */ struct fp { char *name; char *device; int number; } *fp; #define DFLT_NFP 10 /* size of initial array */ #define SIZE_OF_FD0 3 /* |fd0| */ #define SIZE_OF_RFD0 4 /* |rfd0| */ #define FLOPPY_CLEAN SECLIB"/fd_clean" static void dotape(); static void doaudio(); static void dofloppy(); static int docd(); static void dormdisk(int); static void initmem(); static int expandmem(int, void **, int); static void no_memory(void); int system_labeled = 0; int do_devalloc = 0; int do_devmaps = 0; int do_files = 0; devlist_t devlist; int main(int argc, char **argv) { int cd_count = 0; char *progname; struct stat tx_stat; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else progname++; if (strcmp(progname, MKDEVALLOC) == 0) do_devalloc = 1; else if (strcmp(progname, MKDEVMAPS) == 0) do_devmaps = 1; else exit(1); system_labeled = is_system_labeled(); if (system_labeled == 0) { /* * is_system_labeled() will return false in case we are * starting before the first reboot after Trusted Extensions * is installed. we check for a well known TX binary to * to see if TX is installed. */ if (stat(DA_LABEL_CHECK, &tx_stat) == 0) system_labeled = 1; } if (system_labeled && do_devalloc && (argc == 2) && (strcmp(argv[1], DA_IS_LABELED) == 0)) { /* * write device entries to device_allocate and device_maps. * default is to print them on stdout. */ do_files = 1; } initmem(); /* initialize memory */ dotape(); doaudio(); dofloppy(); cd_count = docd(); if (system_labeled) dormdisk(cd_count); return (0); } static void dotape() { DIR *dirp; struct dirent *dep; /* directory entry pointer */ int i, j; char *nm; /* name/device of special device */ char linkvalue[2048]; /* symlink value */ struct stat stat; /* determine if it's a symlink */ int sz; /* size of symlink value */ char *cp; /* pointer into string */ int ntape; /* max array size */ int tape_count; int first = 0; char *dname, *dtype, *dclean; da_args dargs; deventry_t *entry; ntape = DFLT_NTAPE; /* * look for rst* and nrst* */ if ((dirp = opendir("/dev")) == NULL) { perror(gettext("open /dev failure")); exit(1); } i = 0; while (dep = readdir(dirp)) { /* ignore if neither rst* nor nrst* */ if (strncmp(dep->d_name, "rst", SIZE_OF_RST) && strncmp(dep->d_name, "nrst", SIZE_OF_NRST)) continue; /* if array full, then expand it */ if (i == ntape) { /* will exit(1) if insufficient memory */ ntape = expandmem(i, (void **)&tape, sizeof (struct tape)); } /* save name (/dev + / + d_name + \0) */ nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/"); (void) strcat(nm, dep->d_name); tape[i].name = nm; /* ignore if not symbolic link (note i not incremented) */ if (lstat(tape[i].name, &stat) < 0) { perror("stat(2) failed "); exit(1); } if ((stat.st_mode & S_IFMT) != S_IFLNK) continue; /* get name from symbolic link */ if ((sz = readlink(tape[i].name, linkvalue, sizeof (linkvalue))) < 0) continue; nm = (char *)malloc(sz + 1); if (nm == NULL) no_memory(); (void) strncpy(nm, linkvalue, sz); nm[sz] = '\0'; tape[i].device = nm; /* get device number */ cp = strrchr(tape[i].device, '/'); cp++; /* advance to device # */ (void) sscanf(cp, "%d", &tape[i].number); i++; } (void) closedir(dirp); /* * scan /dev/rmt and add entry to table */ if ((dirp = opendir("/dev/rmt")) == NULL) { perror(gettext("open /dev failure")); exit(1); } while (dep = readdir(dirp)) { /* skip . .. etc... */ if (strncmp(dep->d_name, ".", 1) == NULL) continue; /* if array full, then expand it */ if (i == ntape) { /* will exit(1) if insufficient memory */ ntape = expandmem(i, (void **)&tape, sizeof (struct tape)); } /* save name (/dev/rmt + / + d_name + \0) */ nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/rmt/"); (void) strcat(nm, dep->d_name); tape[i].name = nm; /* save device name (rmt/ + d_name + \0) */ nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "rmt/"); (void) strcat(nm, dep->d_name); tape[i].device = nm; (void) sscanf(dep->d_name, "%d", &tape[i].number); i++; } tape_count = i; (void) closedir(dirp); /* remove duplicate entries */ for (i = 0; i < tape_count - 1; i++) { for (j = i + 1; j < tape_count; j++) { if (strcmp(tape[i].device, tape[j].device)) continue; tape[j].number = -1; } } if (system_labeled) { dname = DA_TAPE_NAME; dtype = DA_TAPE_TYPE; dclean = DA_DEFAULT_TAPE_CLEAN; } else { dname = "st"; dtype = "st"; dclean = TAPE_CLEAN; } for (i = 0; i < 8; i++) { for (j = 0; j < tape_count; j++) { if (tape[j].number != i) continue; if (do_files) { (void) da_add_list(&devlist, tape[j].name, i, DA_TAPE); } else if (do_devalloc) { /* print device_allocate for tape devices */ if (system_labeled) { (void) printf("%s%d%s\\\n", dname, i, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_TAPE_TYPE, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER); (void) printf("\t%s\n\n", dclean); } else { (void) printf( "st%d;st;reserved;reserved;%s;", i, DEFAULT_DEV_ALLOC_AUTH); (void) printf("%s%s\n", SECLIB, "/st_clean"); } break; } else if (do_devmaps) { /* print device_maps for tape devices */ if (first) { (void) printf(" "); } else { if (system_labeled) { (void) printf("%s%d%s\\\n", dname, i, KV_TOKEN_DELIMIT); (void) printf("\t%s%s\\\n", dtype, KV_TOKEN_DELIMIT); (void) printf("\t"); } else { (void) printf("st%d:\\\n", i); (void) printf("\trmt:\\\n"); (void) printf("\t"); } first++; } (void) printf("%s", tape[j].name); } } if (do_devmaps && first) { (void) printf("\n\n"); first = 0; } } if (do_files && tape_count) { dargs.rootdir = NULL; dargs.devnames = NULL; dargs.optflag = DA_ADD; for (entry = devlist.tape; entry != NULL; entry = entry->next) { dargs.devinfo = &(entry->devinfo); (void) da_update_device(&dargs); } } } static void doaudio() { DIR *dirp; struct dirent *dep; /* directory entry pointer */ int i, j; char *nm; /* name/device of special device */ char linkvalue[2048]; /* symlink value */ struct stat stat; /* determine if it's a symlink */ int sz; /* size of symlink value */ char *cp; /* pointer into string */ int naudio; /* max array size */ int audio_count = 0; int len, slen; int first = 0; char dname[128]; char *dclean; da_args dargs; deventry_t *entry; naudio = DFLT_NAUDIO; if ((dirp = opendir("/dev")) == NULL) { perror(gettext("open /dev failure")); exit(1); } i = 0; while (dep = readdir(dirp)) { if (strcmp(dep->d_name, "audio") && strcmp(dep->d_name, "audioctl")) continue; /* if array full, then expand it */ if (i == naudio) { /* will exit(1) if insufficient memory */ naudio = expandmem(i, (void **)&audio, sizeof (struct audio)); } /* save name (/dev + 1 + d_name + \0) */ nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/"); (void) strcat(nm, dep->d_name); audio[i].name = nm; /* ignore if not symbolic link (note i not incremented) */ if (lstat(audio[i].name, &stat) < 0) { perror(gettext("stat(2) failed ")); exit(1); } if ((stat.st_mode & S_IFMT) != S_IFLNK) continue; /* get name from symbolic link */ if ((sz = readlink(audio[i].name, linkvalue, sizeof (linkvalue))) < 0) continue; nm = (char *)malloc(sz + 1); if (nm == NULL) no_memory(); (void) strncpy(nm, linkvalue, sz); nm[sz] = '\0'; audio[i].device = nm; cp = strrchr(audio[i].device, '/'); cp++; /* advance to device # */ (void) sscanf(cp, "%d", &audio[i].number); i++; } (void) closedir(dirp); if ((dirp = opendir("/dev/sound")) == NULL) { goto skip; } while (dep = readdir(dirp)) { /* skip . .. etc... */ if (strncmp(dep->d_name, ".", 1) == NULL) continue; /* if array full, then expand it */ if (i == naudio) { /* will exit(1) if insufficient memory */ naudio = expandmem(i, (void **)&audio, sizeof (struct audio)); } /* save name (/dev/sound + / + d_name + \0) */ nm = (char *)malloc(SIZE_OF_SOUND + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/sound/"); (void) strcat(nm, dep->d_name); audio[i].name = nm; nm = (char *)malloc(SIZE_OF_SOUND + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/sound/"); (void) strcat(nm, dep->d_name); audio[i].device = nm; (void) sscanf(dep->d_name, "%d", &audio[i].number); i++; } (void) closedir(dirp); skip: audio_count = i; /* remove duplicate entries */ for (i = 0; i < audio_count - 1; i++) { for (j = i + 1; j < audio_count; j++) { if (strcmp(audio[i].device, audio[j].device)) continue; audio[j].number = -1; } } /* print out device_allocate entries for audio devices */ (void) strcpy(dname, DA_AUDIO_NAME); slen = strlen(DA_AUDIO_NAME); len = sizeof (dname) - slen; dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN; for (i = 0; i < 8; i++) { for (j = 0; j < audio_count; j++) { if (audio[j].number != i) continue; if (system_labeled) (void) snprintf(dname+slen, len, "%d", i); if (do_files) { (void) da_add_list(&devlist, audio[j].name, i, DA_AUDIO); } else if (do_devalloc) { /* print device_allocate for audio devices */ if (system_labeled) { (void) printf("%s%s\\\n", dname, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_AUDIO_TYPE, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER); (void) printf("\t%s\n\n", dclean); } else { (void) printf("audio;audio;"); (void) printf("reserved;reserved;%s;", DEFAULT_DEV_ALLOC_AUTH); (void) printf("%s%s\n", SECLIB, "/audio_clean"); } break; } else if (do_devmaps) { /* print device_maps for audio devices */ if (first) { (void) printf(" "); } else { if (system_labeled) { (void) printf("%s%s\\\n", dname, KV_TOKEN_DELIMIT); (void) printf("\t%s%s\\\n", DA_AUDIO_TYPE, KV_TOKEN_DELIMIT); (void) printf("\t"); } else { (void) printf("audio:\\\n"); (void) printf("\taudio:\\\n"); (void) printf("\t"); } first++; } (void) printf("%s", audio[j].name); } } if (do_devmaps && first) { (void) printf("\n\n"); first = 0; } } if (do_files && audio_count) { dargs.rootdir = NULL; dargs.devnames = NULL; dargs.optflag = DA_ADD; for (entry = devlist.audio; entry != NULL; entry = entry->next) { dargs.devinfo = &(entry->devinfo); (void) da_update_device(&dargs); } } } static void dofloppy() { DIR *dirp; struct dirent *dep; /* directory entry pointer */ int i, j; char *nm; /* name/device of special device */ char linkvalue[2048]; /* symlink value */ struct stat stat; /* determine if it's a symlink */ int sz; /* size of symlink value */ char *cp; /* pointer into string */ int nfp; /* max array size */ int floppy_count = 0; int first = 0; char *dname, *dclean; da_args dargs; deventry_t *entry; nfp = DFLT_NFP; /* * look for fd* and rfd* */ if ((dirp = opendir("/dev")) == NULL) { perror(gettext("open /dev failure")); exit(1); } i = 0; while (dep = readdir(dirp)) { /* ignore if neither rst* nor nrst* */ if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) && strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) && strncmp(dep->d_name, "fd1", SIZE_OF_FD0) && strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0)) continue; /* if array full, then expand it */ if (i == nfp) { /* will exit(1) if insufficient memory */ nfp = expandmem(i, (void **)&fp, sizeof (struct fp)); } /* save name (/dev + 1 + d_name + \0) */ nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/"); (void) strcat(nm, dep->d_name); fp[i].name = nm; /* ignore if not symbolic link (note i not incremented) */ if (lstat(fp[i].name, &stat) < 0) { perror(gettext("stat(2) failed ")); exit(1); } if ((stat.st_mode&S_IFMT) != S_IFLNK) continue; /* get name from symbolic link */ if ((sz = readlink(fp[i].name, linkvalue, sizeof (linkvalue))) < 0) continue; nm = (char *)malloc(sz+1); if (nm == NULL) no_memory(); (void) strncpy(nm, linkvalue, sz); nm[sz] = '\0'; fp[i].device = nm; /* get device number */ cp = strchr(fp[i].name, 'd'); cp++; /* advance to device # */ cp = strchr(cp, 'd'); cp++; /* advance to device # */ (void) sscanf(cp, "%d", &fp[i].number); i++; } (void) closedir(dirp); floppy_count = i; /* print out device_allocate entries for floppy devices */ if (system_labeled) { dname = DA_FLOPPY_NAME; dclean = DA_DEFAULT_DISK_CLEAN; } else { dname = "fd"; dclean = FLOPPY_CLEAN; } for (i = 0; i < 8; i++) { for (j = 0; j < floppy_count; j++) { if (fp[j].number != i) continue; if (do_files) { (void) da_add_list(&devlist, fp[j].name, i, DA_FLOPPY); } else if (do_devalloc) { /* print device_allocate for floppy devices */ if (system_labeled) { (void) printf("%s%d%s\\\n", dname, i, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_FLOPPY_TYPE, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER); (void) printf("\t%s\n\n", dclean); } else { (void) printf( "fd%d;fd;reserved;reserved;%s;", i, DEFAULT_DEV_ALLOC_AUTH); (void) printf("%s%s\n", SECLIB, "/fd_clean"); } break; } else if (do_devmaps) { /* print device_maps for floppy devices */ if (first) { (void) printf(" "); } else { if (system_labeled) { (void) printf("%s%d%s\\\n", dname, i, KV_TOKEN_DELIMIT); (void) printf("\t%s%s\\\n", DA_FLOPPY_TYPE, KV_TOKEN_DELIMIT); (void) printf("\t"); } else { (void) printf("fd%d:\\\n", i); (void) printf("\tfd:\\\n"); (void) printf("\t"); } if (i == 0) { (void) printf("/dev/diskette "); (void) printf( "/dev/rdiskette "); } first++; } (void) printf("%s", fp[j].name); } } if (do_devmaps && first) { (void) printf("\n\n"); first = 0; } } if (do_files && floppy_count) { dargs.rootdir = NULL; dargs.devnames = NULL; dargs.optflag = DA_ADD; for (entry = devlist.floppy; entry != NULL; entry = entry->next) { dargs.devinfo = &(entry->devinfo); (void) da_update_device(&dargs); } } } static int docd() { DIR *dirp; struct dirent *dep; /* directory entry pointer */ int i, j; char *nm; /* name/device of special device */ char linkvalue[2048]; /* symlink value */ struct stat stat; /* determine if it's a symlink */ int sz; /* size of symlink value */ char *cp; /* pointer into string */ int id; /* disk id */ int ctrl; /* disk controller */ int ncd; /* max array size */ int cd_count = 0; int first = 0; char *dname, *dclean; da_args dargs; deventry_t *entry; ncd = DFLT_NCD; /* * look for sr* and rsr* */ if ((dirp = opendir("/dev")) == NULL) { perror(gettext("open /dev failure")); exit(1); } i = 0; while (dep = readdir(dirp)) { /* ignore if neither sr* nor rsr* */ if (strncmp(dep->d_name, "sr", SIZE_OF_SR) && strncmp(dep->d_name, "rsr", SIZE_OF_RSR)) continue; /* if array full, then expand it */ if (i == ncd) { /* will exit(1) if insufficient memory */ ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); } /* save name (/dev + / + d_name + \0) */ nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/"); (void) strcat(nm, dep->d_name); cd[i].name = nm; /* save id # */ if (dep->d_name[0] == 'r') (void) sscanf(dep->d_name, "rsr%d", &cd[i].id); else (void) sscanf(dep->d_name, "sr%d", &cd[i].id); /* ignore if not symbolic link (note i not incremented) */ if (lstat(cd[i].name, &stat) < 0) { perror(gettext("stat(2) failed ")); exit(1); } if ((stat.st_mode & S_IFMT) != S_IFLNK) continue; /* get name from symbolic link */ if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) < 0) continue; nm = (char *)malloc(sz + 1); if (nm == NULL) no_memory(); (void) strncpy(nm, linkvalue, sz); nm[sz] = '\0'; cd[i].device = nm; cp = strrchr(cd[i].device, '/'); cp++; /* advance to device # */ (void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number); i++; } cd_count = i; (void) closedir(dirp); /* * scan /dev/dsk for cd devices */ if ((dirp = opendir("/dev/dsk")) == NULL) { perror("gettext(open /dev/dsk failure)"); exit(1); } while (dep = readdir(dirp)) { /* skip . .. etc... */ if (strncmp(dep->d_name, ".", 1) == NULL) continue; /* get device # (disk #) */ if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0) continue; /* see if this is one of the cd special devices */ for (j = 0; j < cd_count; j++) { if (cd[j].number == id && cd[j].controller == ctrl) goto found; } continue; /* add new entry to table (/dev/dsk + / + d_name + \0) */ found: /* if array full, then expand it */ if (i == ncd) { /* will exit(1) if insufficient memory */ ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); } nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/dsk/"); (void) strcat(nm, dep->d_name); cd[i].name = nm; cd[i].id = cd[j].id; cd[i].device = ""; cd[i].number = id; i++; } (void) closedir(dirp); /* * scan /dev/rdsk for cd devices */ if ((dirp = opendir("/dev/rdsk")) == NULL) { perror(gettext("open /dev/dsk failure")); exit(1); } while (dep = readdir(dirp)) { /* skip . .. etc... */ if (strncmp(dep->d_name, ".", 1) == NULL) continue; /* get device # (disk #) */ if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2) continue; /* see if this is one of the cd special devices */ for (j = 0; j < cd_count; j++) { if (cd[j].number == id && cd[j].controller == ctrl) goto found1; } continue; /* add new entry to table (/dev/rdsk + / + d_name + \0) */ found1: /* if array full, then expand it */ if (i == ncd) { /* will exit(1) if insufficient memory */ ncd = expandmem(i, (void **)&cd, sizeof (struct cd)); } nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/rdsk/"); (void) strcat(nm, dep->d_name); cd[i].name = nm; cd[i].id = cd[j].id; cd[i].device = ""; cd[i].number = id; cd[i].controller = ctrl; i++; } (void) closedir(dirp); cd_count = i; if (system_labeled) { dname = DA_CD_NAME; dclean = DA_DEFAULT_DISK_CLEAN; } else { dname = "sr"; dclean = CD_CLEAN; } for (i = 0; i < 8; i++) { for (j = 0; j < cd_count; j++) { if (cd[j].id != i) continue; if (do_files) { (void) da_add_list(&devlist, cd[j].name, i, DA_CD); } else if (do_devalloc) { /* print device_allocate for cd devices */ if (system_labeled) { (void) printf("%s%d%s\\\n", dname, i, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_CD_TYPE, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER); (void) printf("\t%s\n\n", dclean); } else { (void) printf( "sr%d;sr;reserved;reserved;%s;", i, DEFAULT_DEV_ALLOC_AUTH); (void) printf("%s%s\n", SECLIB, "/sr_clean"); } break; } else if (do_devmaps) { /* print device_maps for cd devices */ if (first) { (void) printf(" "); } else { if (system_labeled) { (void) printf("%s%d%s\\\n", dname, i, KV_TOKEN_DELIMIT); (void) printf("\t%s%s\\\n", DA_CD_TYPE, KV_TOKEN_DELIMIT); (void) printf("\t"); } else { (void) printf("sr%d:\\\n", i); (void) printf("\tsr:\\\n"); (void) printf("\t"); } first++; } (void) printf("%s", cd[j].name); } } if (do_devmaps && first) { (void) printf("\n\n"); first = 0; } } if (do_files && cd_count) { dargs.rootdir = NULL; dargs.devnames = NULL; dargs.optflag = DA_ADD; for (entry = devlist.cd; entry != NULL; entry = entry->next) { dargs.devinfo = &(entry->devinfo); (void) da_update_device(&dargs); } } return (cd_count); } static void dormdisk(int cd_count) { DIR *dirp; struct dirent *dep; /* directory entry pointer */ int i, j; char *nm; /* name/device of special device */ int id; /* disk id */ int ctrl; /* disk controller */ int nrmdisk; /* max array size */ int fd = -1; int rmdisk_count; int first = 0; int is_cd; int checked; int removable; char path[MAXPATHLEN]; da_args dargs; deventry_t *entry; nrmdisk = DFLT_RMDISK; i = rmdisk_count = 0; /* * scan /dev/dsk for rmdisk devices */ if ((dirp = opendir("/dev/dsk")) == NULL) { perror("gettext(open /dev/dsk failure)"); exit(1); } while (dep = readdir(dirp)) { is_cd = 0; checked = 0; removable = 0; /* skip . .. etc... */ if (strncmp(dep->d_name, ".", 1) == NULL) continue; /* get device # (disk #) */ if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0) continue; /* see if we've already examined this device */ for (j = 0; j < i; j++) { if (id == rmdisk[j].id && ctrl == rmdisk[j].controller && (strcmp(dep->d_name, rmdisk[j].name) == 0)) { checked = 1; break; } if (id == rmdisk[j].id && ctrl != rmdisk[j].controller) /* * c2t0d0s0 is a different rmdisk than c3t0d0s0. */ id = rmdisk[j].id + 1; } if (checked) continue; /* ignore if this is a cd */ for (j = 0; j < cd_count; j++) { if (id == cd[j].number && ctrl == cd[j].controller) { is_cd = 1; break; } } if (is_cd) continue; /* see if device is removable */ (void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/", dep->d_name); if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0) continue; (void) ioctl(fd, DKIOCREMOVABLE, &removable); (void) close(fd); if (removable == 0) continue; /* * add new entry to table (/dev/dsk + / + d_name + \0) * if array full, then expand it */ if (i == nrmdisk) { /* will exit(1) if insufficient memory */ nrmdisk = expandmem(i, (void **)&rmdisk, sizeof (struct rmdisk)); } nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1); if (nm == NULL) no_memory(); (void) strcpy(nm, "/dev/dsk/"); (void) strcat(nm, dep->d_name); rmdisk[i].name = nm; rmdisk[i].id = id; rmdisk[i].controller = ctrl; rmdisk[i].device = ""; rmdisk[i].number = id; rmdisk_r[i].name = strdup(path); i++; } rmdisk_count = i; (void) closedir(dirp); for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) { if (j == nrmdisk) { /* will exit(1) if insufficient memory */ nrmdisk = expandmem(j, (void **)&rmdisk, sizeof (struct rmdisk)); } rmdisk[j].name = rmdisk_r[i].name; rmdisk[j].id = rmdisk[i].id; rmdisk[j].controller = rmdisk[i].controller; rmdisk[j].device = rmdisk[i].device; rmdisk[j].number = rmdisk[i].number; } rmdisk_count = j; for (i = 0; i < 8; i++) { for (j = 0; j < rmdisk_count; j++) { if (rmdisk[j].id != i) continue; if (do_files) { (void) da_add_list(&devlist, rmdisk[j].name, i, DA_RMDISK); } else if (do_devalloc) { /* print device_allocate for rmdisk devices */ (void) printf("%s%d%s\\\n", DA_RMDISK_NAME, i, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RMDISK_TYPE, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DA_RESERVED, KV_DELIMITER); (void) printf("\t%s%s\\\n", DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER); (void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN); break; } else if (do_devmaps) { /* print device_maps for rmdisk devices */ if (first) { (void) printf(" "); } else { (void) printf("%s%d%s\\\n", DA_RMDISK_NAME, i, KV_TOKEN_DELIMIT); (void) printf("\t%s%s\\\n", DA_RMDISK_TYPE, KV_TOKEN_DELIMIT); (void) printf("\t"); first++; } (void) printf("%s", rmdisk[j].name); } } if (do_devmaps && first) { (void) printf("\n\n"); first = 0; } } if (do_files && rmdisk_count) { dargs.rootdir = NULL; dargs.devnames = NULL; dargs.optflag = DA_ADD; for (entry = devlist.rmdisk; entry != NULL; entry = entry->next) { dargs.devinfo = &(entry->devinfo); (void) da_update_device(&dargs); } } } /* set default array sizes */ static void initmem() { tape = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape)); audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio)); cd = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd)); fp = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp)); if (system_labeled) { rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK, sizeof (struct rmdisk)); if (rmdisk == NULL) no_memory(); rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK, sizeof (struct rmdisk)); if (rmdisk_r == NULL) no_memory(); } if (tape == NULL || audio == NULL || cd == NULL || fp == NULL) no_memory(); devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk = devlist.tape = NULL; } /* note n will be # elments in array (and could be 0) */ static int expandmem(int n, void **array, int size) { void *old = *array; void *new; /* get new array space (n + DELTA) */ new = (void *)calloc(n + DELTA, size); if (new == NULL) { perror("memory allocation failed"); exit(1); } /* copy old array into new space */ bcopy(old, new, n * size); /* now release old arrary */ free(old); *array = new; return (n + DELTA); } static void no_memory(void) { (void) fprintf(stderr, "%s: %s\n", "mkdevalloc", gettext("out of memory")); exit(1); /* NOT REACHED */ }