| /* |
| * 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 */ |
| } |