xref: /onnv-gate/usr/src/cmd/allocate/mkdevalloc.c (revision 11529:0396f567d7e1)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51676Sjpk  * Common Development and Distribution License (the "License").
61676Sjpk  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211676Sjpk 
220Sstevel@tonic-gate /*
23*11529SJan.Parcel@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate  * scan /dev directory for mountable objects and construct device_allocate
290Sstevel@tonic-gate  * file for allocate....
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  * devices are:
320Sstevel@tonic-gate  *	tape (cartridge)
330Sstevel@tonic-gate  *		/dev/rst*
340Sstevel@tonic-gate  *		/dev/nrst*
350Sstevel@tonic-gate  *		/dev/rmt/...
360Sstevel@tonic-gate  *	audio
370Sstevel@tonic-gate  *		/dev/audio
380Sstevel@tonic-gate  *		/dev/audioctl
390Sstevel@tonic-gate  *		/dev/sound/...
400Sstevel@tonic-gate  *	floppy
410Sstevel@tonic-gate  *		/dev/diskette
420Sstevel@tonic-gate  *		/dev/fd*
430Sstevel@tonic-gate  *		/dev/rdiskette
440Sstevel@tonic-gate  *		/dev/rfd*
450Sstevel@tonic-gate  *	CD
460Sstevel@tonic-gate  *		/dev/sr*
470Sstevel@tonic-gate  *		/dev/nsr*
480Sstevel@tonic-gate  *		/dev/dsk/c?t?d0s?
490Sstevel@tonic-gate  *		/dev/rdsk/c?t?d0s?
501676Sjpk  *
510Sstevel@tonic-gate  */
520Sstevel@tonic-gate 
531676Sjpk #include <errno.h>
541676Sjpk #include <fcntl.h>
550Sstevel@tonic-gate #include <sys/types.h>	/* for stat(2), etc. */
560Sstevel@tonic-gate #include <sys/stat.h>
570Sstevel@tonic-gate #include <dirent.h>	/* for readdir(3), etc. */
580Sstevel@tonic-gate #include <unistd.h>	/* for readlink(2) */
591676Sjpk #include <stropts.h>
600Sstevel@tonic-gate #include <string.h>	/* for strcpy(3), etc. */
610Sstevel@tonic-gate #include <strings.h>	/* for bcopy(3C), etc. */
620Sstevel@tonic-gate #include <stdio.h>	/* for perror(3) */
630Sstevel@tonic-gate #include <stdlib.h>	/* for atoi(3) */
641676Sjpk #include <sys/dkio.h>
650Sstevel@tonic-gate #include <locale.h>
660Sstevel@tonic-gate #include <libintl.h>
671676Sjpk #include <libdevinfo.h>
681676Sjpk #include <secdb.h>
694746Srica #include <deflt.h>
700Sstevel@tonic-gate #include <auth_attr.h>
710Sstevel@tonic-gate #include <auth_list.h>
721676Sjpk #include <bsm/devices.h>
731676Sjpk #include <bsm/devalloc.h>
741676Sjpk #include <tsol/label.h>
750Sstevel@tonic-gate 
760Sstevel@tonic-gate #ifndef TEXT_DOMAIN
770Sstevel@tonic-gate #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
780Sstevel@tonic-gate #endif
790Sstevel@tonic-gate 
801676Sjpk #define	MKDEVALLOC	"mkdevalloc"
811676Sjpk #define	MKDEVMAPS	"mkdevmaps"
821676Sjpk 
830Sstevel@tonic-gate #define	DELTA	5	/* array size delta when full */
841676Sjpk #define	SECLIB	"/etc/security/lib"
850Sstevel@tonic-gate 
860Sstevel@tonic-gate /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */
870Sstevel@tonic-gate struct tape {
880Sstevel@tonic-gate 	char	*name;
890Sstevel@tonic-gate 	char	*device;
900Sstevel@tonic-gate 	int	number;
910Sstevel@tonic-gate } *tape;
920Sstevel@tonic-gate #define	DFLT_NTAPE  10		/* size of initial array */
930Sstevel@tonic-gate #define	SIZE_OF_RST  3		/* |rmt| */
940Sstevel@tonic-gate #define	SIZE_OF_NRST 4		/* |nrmt| */
95*11529SJan.Parcel@Sun.COM #define	SIZE_OF_TMP 4		/* |/tmp| */
960Sstevel@tonic-gate #define	SIZE_OF_RMT  8		/* |/dev/rmt| */
971676Sjpk #define	TAPE_CLEAN    SECLIB"/st_clean"
980Sstevel@tonic-gate 
990Sstevel@tonic-gate /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */
1000Sstevel@tonic-gate struct audio {
1010Sstevel@tonic-gate 	char	*name;
1020Sstevel@tonic-gate 	char	*device;
1030Sstevel@tonic-gate 	int	number;
1040Sstevel@tonic-gate } *audio;
1050Sstevel@tonic-gate #define	DFLT_NAUDIO   10	/* size of initial array */
1060Sstevel@tonic-gate #define	SIZE_OF_SOUND 10	/* |/dev/sound| */
1071676Sjpk #define	AUDIO_CLEAN   SECLIB"/audio_clean"
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
1100Sstevel@tonic-gate struct cd {
1110Sstevel@tonic-gate 	char	*name;
1120Sstevel@tonic-gate 	char	*device;
1130Sstevel@tonic-gate 	int	id;
1140Sstevel@tonic-gate 	int	controller;
1150Sstevel@tonic-gate 	int	number;
1160Sstevel@tonic-gate } *cd;
1170Sstevel@tonic-gate #define	DFLT_NCD    10		/* size of initial array */
1180Sstevel@tonic-gate #define	SIZE_OF_SR   2		/* |sr| */
1190Sstevel@tonic-gate #define	SIZE_OF_RSR  3		/* |rsr| */
1200Sstevel@tonic-gate #define	SIZE_OF_DSK  8		/* |/dev/dsk| */
1210Sstevel@tonic-gate #define	SIZE_OF_RDSK 9		/* |/dev/rdsk| */
1221676Sjpk #define	CD_CLEAN    SECLIB"/sr_clean"
1230Sstevel@tonic-gate 
1241676Sjpk /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
1251676Sjpk struct rmdisk {
1261676Sjpk 	char	*name;
1271676Sjpk 	char	*device;
1281676Sjpk 	int	id;
1291676Sjpk 	int	controller;
1301676Sjpk 	int	number;
1311676Sjpk } *rmdisk, *rmdisk_r;
1321676Sjpk #define	DFLT_RMDISK	10	/* size of initial array */
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
1350Sstevel@tonic-gate struct fp {
1360Sstevel@tonic-gate 	char *name;
1370Sstevel@tonic-gate 	char *device;
1380Sstevel@tonic-gate 	int number;
1390Sstevel@tonic-gate } *fp;
1400Sstevel@tonic-gate #define	DFLT_NFP    10		/* size of initial array */
1410Sstevel@tonic-gate #define	SIZE_OF_FD0  3		/* |fd0| */
1420Sstevel@tonic-gate #define	SIZE_OF_RFD0 4		/* |rfd0| */
1431676Sjpk #define	FLOPPY_CLEAN SECLIB"/fd_clean"
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate static void dotape();
1460Sstevel@tonic-gate static void doaudio();
1470Sstevel@tonic-gate static void dofloppy();
1481676Sjpk static int docd();
1491676Sjpk static void dormdisk(int);
1500Sstevel@tonic-gate static void initmem();
1510Sstevel@tonic-gate static int  expandmem(int, void **, int);
1520Sstevel@tonic-gate static void no_memory(void);
1530Sstevel@tonic-gate 
1541676Sjpk int		system_labeled = 0;
1551676Sjpk int		do_devalloc = 0;
1561676Sjpk int		do_devmaps = 0;
1571676Sjpk int		do_files = 0;
1581676Sjpk devlist_t	devlist;
1591676Sjpk 
160394Spaulson int
main(int argc,char ** argv)1611676Sjpk main(int argc, char **argv)
1620Sstevel@tonic-gate {
1631676Sjpk 	int		cd_count = 0;
1641676Sjpk 	char		*progname;
1651676Sjpk 
1660Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1670Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1680Sstevel@tonic-gate 
1691676Sjpk 	if ((progname = strrchr(argv[0], '/')) == NULL)
1701676Sjpk 		progname = argv[0];
1711676Sjpk 	else
1721676Sjpk 		progname++;
1731676Sjpk 	if (strcmp(progname, MKDEVALLOC) == 0)
1741676Sjpk 		do_devalloc = 1;
1751676Sjpk 	else if (strcmp(progname, MKDEVMAPS) == 0)
1761676Sjpk 		do_devmaps = 1;
1771676Sjpk 	else
1781676Sjpk 		exit(1);
1790Sstevel@tonic-gate 
1801676Sjpk 	system_labeled = is_system_labeled();
1812621Sllai1 
1824746Srica 	if (!system_labeled) {
1834746Srica 		/*
1844746Srica 		 * is_system_labeled() will return false in case we are
1854746Srica 		 * starting before the first reboot after Trusted Extensions
1864746Srica 		 * is enabled.  Check the setting in /etc/system to see if
1874746Srica 		 * TX is enabled (even if not yet booted).
1884746Srica 		 */
1894746Srica 		if (defopen("/etc/system") == 0) {
1904746Srica 			if (defread("set sys_labeling=1") != NULL)
1914746Srica 				system_labeled = 1;
1924746Srica 
1934746Srica 			/* close defaults file */
1944746Srica 			(void) defopen(NULL);
1954746Srica 		}
1964746Srica 	}
1974746Srica 
1984746Srica #ifdef DEBUG
1992621Sllai1 	/* test hook: see also devfsadm.c and allocate.c */
2002621Sllai1 	if (!system_labeled) {
2014746Srica 		struct stat	tx_stat;
2024746Srica 
2032621Sllai1 		system_labeled = is_system_labeled_debug(&tx_stat);
2042621Sllai1 		if (system_labeled) {
2052621Sllai1 			fprintf(stderr, "/ALLOCATE_FORCE_LABEL is set,\n"
2062621Sllai1 			    "forcing system label on for testing...\n");
2072621Sllai1 		}
2082621Sllai1 	}
2094746Srica #endif
2100Sstevel@tonic-gate 
2111676Sjpk 	if (system_labeled && do_devalloc && (argc == 2) &&
2121676Sjpk 	    (strcmp(argv[1], DA_IS_LABELED) == 0)) {
2131676Sjpk 		/*
2141676Sjpk 		 * write device entries to device_allocate and device_maps.
2151676Sjpk 		 * default is to print them on stdout.
2161676Sjpk 		 */
2171676Sjpk 		do_files = 1;
2181676Sjpk 	}
2190Sstevel@tonic-gate 
2201676Sjpk 	initmem();		/* initialize memory */
2211676Sjpk 	dotape();
2221676Sjpk 	doaudio();
2231676Sjpk 	dofloppy();
2241676Sjpk 	cd_count = docd();
2251676Sjpk 	if (system_labeled)
2261676Sjpk 		dormdisk(cd_count);
227394Spaulson 
228394Spaulson 	return (0);
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate static void
dotape()2320Sstevel@tonic-gate dotape()
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate 	DIR *dirp;
2350Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
2361676Sjpk 	int	i, j;
2370Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
2380Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
2390Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
2400Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
2410Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
2420Sstevel@tonic-gate 	int	ntape;		/* max array size */
2431676Sjpk 	int	tape_count;
2441676Sjpk 	int	first = 0;
2451676Sjpk 	char	*dname, *dtype, *dclean;
2461676Sjpk 	da_args	dargs;
2471676Sjpk 	deventry_t *entry;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	ntape = DFLT_NTAPE;
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	/*
2520Sstevel@tonic-gate 	 * look for rst* and nrst*
2530Sstevel@tonic-gate 	 */
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
2560Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
2570Sstevel@tonic-gate 		exit(1);
2580Sstevel@tonic-gate 	}
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate 	i = 0;
2610Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
2620Sstevel@tonic-gate 		/* ignore if neither rst* nor nrst* */
2630Sstevel@tonic-gate 		if (strncmp(dep->d_name, "rst", SIZE_OF_RST) &&
2640Sstevel@tonic-gate 		    strncmp(dep->d_name, "nrst", SIZE_OF_NRST))
2650Sstevel@tonic-gate 			continue;
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 		/* if array full, then expand it */
2680Sstevel@tonic-gate 		if (i == ntape) {
2690Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
2700Sstevel@tonic-gate 			ntape = expandmem(i, (void **)&tape,
2714746Srica 			    sizeof (struct tape));
2720Sstevel@tonic-gate 		}
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate 		/* save name (/dev + / + d_name + \0) */
2750Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
2760Sstevel@tonic-gate 		if (nm == NULL)
2770Sstevel@tonic-gate 			no_memory();
2780Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
2790Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
2800Sstevel@tonic-gate 		tape[i].name = nm;
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
2830Sstevel@tonic-gate 		if (lstat(tape[i].name, &stat) < 0) {
2840Sstevel@tonic-gate 			perror("stat(2) failed ");
2850Sstevel@tonic-gate 			exit(1);
2860Sstevel@tonic-gate 		}
2870Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
2880Sstevel@tonic-gate 			continue;
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate 		/* get name from symbolic link */
2910Sstevel@tonic-gate 		if ((sz = readlink(tape[i].name, linkvalue,
2924746Srica 		    sizeof (linkvalue))) < 0)
2930Sstevel@tonic-gate 			continue;
2940Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
2950Sstevel@tonic-gate 		if (nm == NULL)
2960Sstevel@tonic-gate 			no_memory();
2970Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
2980Sstevel@tonic-gate 		nm[sz] = '\0';
2990Sstevel@tonic-gate 		tape[i].device = nm;
3000Sstevel@tonic-gate 
3010Sstevel@tonic-gate 		/* get device number */
3020Sstevel@tonic-gate 		cp = strrchr(tape[i].device, '/');
3030Sstevel@tonic-gate 		cp++;				/* advance to device # */
3040Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &tape[i].number);
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 		i++;
3070Sstevel@tonic-gate 	}
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	(void) closedir(dirp);
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate 	/*
3120Sstevel@tonic-gate 	 * scan /dev/rmt and add entry to table
3130Sstevel@tonic-gate 	 */
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate 	if ((dirp = opendir("/dev/rmt")) == NULL) {
3160Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
3170Sstevel@tonic-gate 		exit(1);
3180Sstevel@tonic-gate 	}
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
3210Sstevel@tonic-gate 		/* skip . .. etc... */
3220Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
3230Sstevel@tonic-gate 			continue;
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate 		/* if array full, then expand it */
3260Sstevel@tonic-gate 		if (i == ntape) {
3270Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
3280Sstevel@tonic-gate 			ntape = expandmem(i, (void **)&tape,
3294746Srica 			    sizeof (struct tape));
3300Sstevel@tonic-gate 		}
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 		/* save name (/dev/rmt + / + d_name + \0) */
3330Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1);
3340Sstevel@tonic-gate 		if (nm == NULL)
3350Sstevel@tonic-gate 			no_memory();
3360Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/rmt/");
3370Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
3380Sstevel@tonic-gate 		tape[i].name = nm;
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 		/* save device name (rmt/ + d_name + \0) */
3410Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
3420Sstevel@tonic-gate 		if (nm == NULL)
3430Sstevel@tonic-gate 			no_memory();
3440Sstevel@tonic-gate 		(void) strcpy(nm, "rmt/");
3450Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
3460Sstevel@tonic-gate 		tape[i].device = nm;
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 		(void) sscanf(dep->d_name, "%d", &tape[i].number);
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 		i++;
3510Sstevel@tonic-gate 	}
3521676Sjpk 	tape_count = i;
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate 	(void) closedir(dirp);
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate 	/* remove duplicate entries */
3571676Sjpk 	for (i = 0; i < tape_count - 1; i++) {
3581676Sjpk 		for (j = i + 1; j < tape_count; j++) {
3590Sstevel@tonic-gate 			if (strcmp(tape[i].device, tape[j].device))
3600Sstevel@tonic-gate 				continue;
3610Sstevel@tonic-gate 			tape[j].number = -1;
3620Sstevel@tonic-gate 		}
3630Sstevel@tonic-gate 	}
3640Sstevel@tonic-gate 
3651676Sjpk 	if (system_labeled) {
3661676Sjpk 		dname = DA_TAPE_NAME;
3671676Sjpk 		dtype = DA_TAPE_TYPE;
3681676Sjpk 		dclean = DA_DEFAULT_TAPE_CLEAN;
3691676Sjpk 	} else {
3701676Sjpk 		dname = "st";
3711676Sjpk 		dtype = "st";
3721676Sjpk 		dclean = TAPE_CLEAN;
3731676Sjpk 	}
3740Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
3751676Sjpk 		for (j = 0; j < tape_count; j++) {
3761676Sjpk 			if (tape[j].number != i)
3771676Sjpk 				continue;
3781676Sjpk 			if (do_files) {
3791676Sjpk 				(void) da_add_list(&devlist, tape[j].name, i,
3801676Sjpk 				    DA_TAPE);
3811676Sjpk 			} else if (do_devalloc) {
3821676Sjpk 				/* print device_allocate for tape devices */
3831676Sjpk 				if (system_labeled) {
3841676Sjpk 					(void) printf("%s%d%s\\\n",
3851676Sjpk 					    dname, i, KV_DELIMITER);
3861676Sjpk 					(void) printf("\t%s%s\\\n",
3871676Sjpk 					    DA_TAPE_TYPE, KV_DELIMITER);
3881676Sjpk 					(void) printf("\t%s%s\\\n",
3891676Sjpk 					    DA_RESERVED, KV_DELIMITER);
3901676Sjpk 					(void) printf("\t%s%s\\\n",
3911676Sjpk 					    DA_RESERVED, KV_DELIMITER);
3921676Sjpk 					(void) printf("\t%s%s\\\n",
3931676Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
3941676Sjpk 					    KV_DELIMITER);
3951676Sjpk 					(void) printf("\t%s\n\n", dclean);
3961676Sjpk 				} else {
3971676Sjpk 					(void) printf(
3981676Sjpk 					    "st%d;st;reserved;reserved;%s;",
3991676Sjpk 					    i, DEFAULT_DEV_ALLOC_AUTH);
4001676Sjpk 					(void) printf("%s%s\n", SECLIB,
4011676Sjpk 					    "/st_clean");
4021676Sjpk 				}
4030Sstevel@tonic-gate 				break;
4041676Sjpk 			} else if (do_devmaps) {
4051676Sjpk 				/* print device_maps for tape devices */
4061676Sjpk 				if (first) {
4071676Sjpk 					(void) printf(" ");
4081676Sjpk 				} else {
4091676Sjpk 					if (system_labeled) {
4101676Sjpk 						(void) printf("%s%d%s\\\n",
4111676Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
4121676Sjpk 						(void) printf("\t%s%s\\\n",
4131676Sjpk 						    dtype, KV_TOKEN_DELIMIT);
4141676Sjpk 						(void) printf("\t");
4151676Sjpk 					} else {
4161676Sjpk 						(void) printf("st%d:\\\n", i);
4171676Sjpk 						(void) printf("\trmt:\\\n");
4181676Sjpk 						(void) printf("\t");
4191676Sjpk 					}
4201676Sjpk 						first++;
4211676Sjpk 				}
4221676Sjpk 				(void) printf("%s", tape[j].name);
4230Sstevel@tonic-gate 			}
4240Sstevel@tonic-gate 		}
4251676Sjpk 		if (do_devmaps && first) {
4261676Sjpk 			(void) printf("\n\n");
4271676Sjpk 			first = 0;
4281676Sjpk 		}
4291676Sjpk 	}
4301676Sjpk 	if (do_files && tape_count) {
4311676Sjpk 		dargs.rootdir = NULL;
4321676Sjpk 		dargs.devnames = NULL;
4331676Sjpk 		dargs.optflag = DA_ADD;
4341676Sjpk 		for (entry = devlist.tape; entry != NULL; entry = entry->next) {
4351676Sjpk 			dargs.devinfo = &(entry->devinfo);
4361676Sjpk 			(void) da_update_device(&dargs);
4371676Sjpk 		}
4380Sstevel@tonic-gate 	}
4390Sstevel@tonic-gate }
4400Sstevel@tonic-gate 
4410Sstevel@tonic-gate static void
doaudio()4420Sstevel@tonic-gate doaudio()
4430Sstevel@tonic-gate {
4440Sstevel@tonic-gate 	DIR *dirp;
4450Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
4461676Sjpk 	int	i, j;
4470Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
4480Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
4490Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
4500Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
4510Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
4520Sstevel@tonic-gate 	int	naudio;		/* max array size */
4531676Sjpk 	int	audio_count = 0;
4541676Sjpk 	int	len, slen;
4551676Sjpk 	int	first = 0;
4561676Sjpk 	char	dname[128];
4571676Sjpk 	char	*dclean;
4581676Sjpk 	da_args	dargs;
4591676Sjpk 	deventry_t *entry;
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate 	naudio = DFLT_NAUDIO;
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
4640Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
4650Sstevel@tonic-gate 		exit(1);
4660Sstevel@tonic-gate 	}
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate 	i = 0;
4690Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
4700Sstevel@tonic-gate 		if (strcmp(dep->d_name, "audio") &&
4710Sstevel@tonic-gate 		    strcmp(dep->d_name, "audioctl"))
4720Sstevel@tonic-gate 			continue;
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate 		/* if array full, then expand it */
4750Sstevel@tonic-gate 		if (i == naudio) {
4760Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
4770Sstevel@tonic-gate 			naudio = expandmem(i, (void **)&audio,
4784746Srica 			    sizeof (struct audio));
4790Sstevel@tonic-gate 		}
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate 		/* save name (/dev + 1 + d_name + \0) */
4820Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
4830Sstevel@tonic-gate 		if (nm == NULL)
4840Sstevel@tonic-gate 			no_memory();
4850Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
4860Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
4870Sstevel@tonic-gate 		audio[i].name = nm;
4880Sstevel@tonic-gate 
4890Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
4900Sstevel@tonic-gate 		if (lstat(audio[i].name, &stat) < 0) {
4910Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
4920Sstevel@tonic-gate 			exit(1);
4930Sstevel@tonic-gate 		}
4940Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
4950Sstevel@tonic-gate 			continue;
4960Sstevel@tonic-gate 
4970Sstevel@tonic-gate 		/* get name from symbolic link */
4980Sstevel@tonic-gate 		if ((sz = readlink(audio[i].name, linkvalue,
4994746Srica 		    sizeof (linkvalue))) < 0)
5000Sstevel@tonic-gate 			continue;
5010Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
5020Sstevel@tonic-gate 		if (nm == NULL)
5030Sstevel@tonic-gate 			no_memory();
5040Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
5050Sstevel@tonic-gate 		nm[sz] = '\0';
5060Sstevel@tonic-gate 		audio[i].device = nm;
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate 		cp = strrchr(audio[i].device, '/');
5090Sstevel@tonic-gate 		cp++;				/* advance to device # */
5100Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &audio[i].number);
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate 		i++;
5130Sstevel@tonic-gate 	}
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 	(void) closedir(dirp);
5160Sstevel@tonic-gate 
5170Sstevel@tonic-gate 	if ((dirp = opendir("/dev/sound")) == NULL) {
5180Sstevel@tonic-gate 		goto skip;
5190Sstevel@tonic-gate 	}
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
5220Sstevel@tonic-gate 		/* skip . .. etc... */
5230Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
5240Sstevel@tonic-gate 			continue;
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate 		/* if array full, then expand it */
5270Sstevel@tonic-gate 		if (i == naudio) {
5280Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
5290Sstevel@tonic-gate 			naudio = expandmem(i, (void **)&audio,
5304746Srica 			    sizeof (struct audio));
5310Sstevel@tonic-gate 		}
5320Sstevel@tonic-gate 
5330Sstevel@tonic-gate 		/* save name (/dev/sound + / + d_name + \0) */
5340Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
5350Sstevel@tonic-gate 		    strlen(dep->d_name) + 1);
5360Sstevel@tonic-gate 		if (nm == NULL)
5370Sstevel@tonic-gate 			no_memory();
5380Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/sound/");
5390Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
5400Sstevel@tonic-gate 		audio[i].name = nm;
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
5430Sstevel@tonic-gate 		    strlen(dep->d_name) + 1);
5440Sstevel@tonic-gate 		if (nm == NULL)
5450Sstevel@tonic-gate 			no_memory();
5460Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/sound/");
5470Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
5480Sstevel@tonic-gate 		audio[i].device = nm;
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 		(void) sscanf(dep->d_name, "%d", &audio[i].number);
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 		i++;
5530Sstevel@tonic-gate 	}
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate 	(void) closedir(dirp);
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate skip:
5581676Sjpk 	audio_count = i;
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate 	/* remove duplicate entries */
5611676Sjpk 	for (i = 0; i < audio_count - 1; i++) {
5621676Sjpk 		for (j = i + 1; j < audio_count; j++) {
5630Sstevel@tonic-gate 			if (strcmp(audio[i].device, audio[j].device))
5640Sstevel@tonic-gate 				continue;
5650Sstevel@tonic-gate 			audio[j].number = -1;
5660Sstevel@tonic-gate 		}
5670Sstevel@tonic-gate 	}
5680Sstevel@tonic-gate 
5691676Sjpk 	/* print out device_allocate entries for audio devices */
5701676Sjpk 	(void) strcpy(dname, DA_AUDIO_NAME);
5711676Sjpk 	slen = strlen(DA_AUDIO_NAME);
5721676Sjpk 	len = sizeof (dname) - slen;
5731676Sjpk 	dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN;
5740Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
5751676Sjpk 		for (j = 0; j < audio_count; j++) {
5761676Sjpk 			if (audio[j].number != i)
5771676Sjpk 				continue;
5781676Sjpk 			if (system_labeled)
5791676Sjpk 				(void) snprintf(dname+slen, len, "%d", i);
5801676Sjpk 			if (do_files) {
5811676Sjpk 				(void) da_add_list(&devlist, audio[j].name,
5821676Sjpk 				    i, DA_AUDIO);
5831676Sjpk 			} else if (do_devalloc) {
5841676Sjpk 				/* print device_allocate for audio devices */
5851676Sjpk 				if (system_labeled) {
5861676Sjpk 					(void) printf("%s%s\\\n",
5871676Sjpk 					    dname, KV_DELIMITER);
5881676Sjpk 					(void) printf("\t%s%s\\\n",
5891676Sjpk 					    DA_AUDIO_TYPE, KV_DELIMITER);
5901676Sjpk 					(void) printf("\t%s%s\\\n",
5911676Sjpk 					    DA_RESERVED, KV_DELIMITER);
5921676Sjpk 					(void) printf("\t%s%s\\\n",
5931676Sjpk 					    DA_RESERVED, KV_DELIMITER);
5941676Sjpk 					(void) printf("\t%s%s\\\n",
5951676Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
5961676Sjpk 					    KV_DELIMITER);
5971676Sjpk 					(void) printf("\t%s\n\n", dclean);
5981676Sjpk 				} else {
5991676Sjpk 					(void) printf("audio;audio;");
6001676Sjpk 					(void) printf("reserved;reserved;%s;",
6011676Sjpk 					    DEFAULT_DEV_ALLOC_AUTH);
6021676Sjpk 					(void) printf("%s%s\n", SECLIB,
6031676Sjpk 					    "/audio_clean");
6041676Sjpk 				}
6050Sstevel@tonic-gate 				break;
6061676Sjpk 			} else if (do_devmaps) {
6071676Sjpk 				/* print device_maps for audio devices */
6081676Sjpk 				if (first) {
6091676Sjpk 					(void) printf(" ");
6101676Sjpk 				} else {
6111676Sjpk 					if (system_labeled) {
6121676Sjpk 						(void) printf("%s%s\\\n",
6131676Sjpk 						    dname, KV_TOKEN_DELIMIT);
6141676Sjpk 						(void) printf("\t%s%s\\\n",
6151676Sjpk 						    DA_AUDIO_TYPE,
6161676Sjpk 						    KV_TOKEN_DELIMIT);
6171676Sjpk 						(void) printf("\t");
6181676Sjpk 					} else {
6191676Sjpk 						(void) printf("audio:\\\n");
6201676Sjpk 						(void) printf("\taudio:\\\n");
6211676Sjpk 						(void) printf("\t");
6221676Sjpk 					}
6231676Sjpk 					first++;
6241676Sjpk 				}
6251676Sjpk 				(void) printf("%s", audio[j].name);
6260Sstevel@tonic-gate 			}
6270Sstevel@tonic-gate 		}
6281676Sjpk 		if (do_devmaps && first) {
6291676Sjpk 			(void) printf("\n\n");
6301676Sjpk 			first = 0;
6311676Sjpk 		}
6321676Sjpk 	}
6331676Sjpk 	if (do_files && audio_count) {
6341676Sjpk 		dargs.rootdir = NULL;
6351676Sjpk 		dargs.devnames = NULL;
6361676Sjpk 		dargs.optflag = DA_ADD;
6371676Sjpk 		for (entry = devlist.audio; entry != NULL;
6381676Sjpk 		    entry = entry->next) {
6391676Sjpk 			dargs.devinfo = &(entry->devinfo);
6401676Sjpk 			(void) da_update_device(&dargs);
6411676Sjpk 		}
6420Sstevel@tonic-gate 	}
6430Sstevel@tonic-gate }
6440Sstevel@tonic-gate 
6450Sstevel@tonic-gate static void
dofloppy()6460Sstevel@tonic-gate dofloppy()
6470Sstevel@tonic-gate {
6480Sstevel@tonic-gate 	DIR *dirp;
6490Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
6501676Sjpk 	int i, j;
6510Sstevel@tonic-gate 	char *nm;		/* name/device of special device */
6520Sstevel@tonic-gate 	char linkvalue[2048];	/* symlink value */
6530Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
6540Sstevel@tonic-gate 	int sz;			/* size of symlink value */
6550Sstevel@tonic-gate 	char *cp;		/* pointer into string */
6560Sstevel@tonic-gate 	int nfp;		/* max array size */
6571676Sjpk 	int floppy_count = 0;
6581676Sjpk 	int first = 0;
6591676Sjpk 	char *dname, *dclean;
6601676Sjpk 	da_args dargs;
6611676Sjpk 	deventry_t *entry;
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	nfp = DFLT_NFP;
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate 	/*
6660Sstevel@tonic-gate 	 * look for fd* and rfd*
6670Sstevel@tonic-gate 	 */
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
6700Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
6710Sstevel@tonic-gate 		exit(1);
6720Sstevel@tonic-gate 	}
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 	i = 0;
6750Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
6760Sstevel@tonic-gate 		/* ignore if neither rst* nor nrst* */
6770Sstevel@tonic-gate 		if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) &&
6780Sstevel@tonic-gate 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) &&
6790Sstevel@tonic-gate 		    strncmp(dep->d_name, "fd1", SIZE_OF_FD0) &&
6800Sstevel@tonic-gate 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0))
6810Sstevel@tonic-gate 			continue;
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 		/* if array full, then expand it */
6840Sstevel@tonic-gate 		if (i == nfp) {
6850Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
6860Sstevel@tonic-gate 			nfp = expandmem(i, (void **)&fp, sizeof (struct fp));
6870Sstevel@tonic-gate 		}
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate 		/* save name (/dev + 1 + d_name + \0) */
6900Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
6910Sstevel@tonic-gate 		if (nm == NULL)
6920Sstevel@tonic-gate 			no_memory();
6930Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
6940Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
6950Sstevel@tonic-gate 		fp[i].name = nm;
6960Sstevel@tonic-gate 
6970Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
6980Sstevel@tonic-gate 		if (lstat(fp[i].name, &stat) < 0) {
6990Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
7000Sstevel@tonic-gate 			exit(1);
7010Sstevel@tonic-gate 		}
7020Sstevel@tonic-gate 		if ((stat.st_mode&S_IFMT) != S_IFLNK)
7030Sstevel@tonic-gate 			continue;
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate 		/* get name from symbolic link */
7060Sstevel@tonic-gate 		if ((sz = readlink(fp[i].name, linkvalue,
7070Sstevel@tonic-gate 		    sizeof (linkvalue))) < 0)
7080Sstevel@tonic-gate 			continue;
7090Sstevel@tonic-gate 		nm = (char *)malloc(sz+1);
7100Sstevel@tonic-gate 		if (nm == NULL)
7110Sstevel@tonic-gate 			no_memory();
7120Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
7130Sstevel@tonic-gate 		nm[sz] = '\0';
7140Sstevel@tonic-gate 		fp[i].device = nm;
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 		/* get device number */
7170Sstevel@tonic-gate 		cp = strchr(fp[i].name, 'd');
7180Sstevel@tonic-gate 		cp++;				/* advance to device # */
7190Sstevel@tonic-gate 		cp = strchr(cp, 'd');
7200Sstevel@tonic-gate 		cp++;				/* advance to device # */
7210Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &fp[i].number);
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 		i++;
7240Sstevel@tonic-gate 	}
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 	(void) closedir(dirp);
7270Sstevel@tonic-gate 
7281676Sjpk 	floppy_count = i;
7290Sstevel@tonic-gate 
7301676Sjpk 	/* print out device_allocate entries for floppy devices */
7311676Sjpk 	if (system_labeled) {
7321676Sjpk 		dname = DA_FLOPPY_NAME;
7331676Sjpk 		dclean = DA_DEFAULT_DISK_CLEAN;
7341676Sjpk 	} else {
7351676Sjpk 		dname = "fd";
7361676Sjpk 		dclean = FLOPPY_CLEAN;
7371676Sjpk 	}
7380Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
7391676Sjpk 		for (j = 0; j < floppy_count; j++) {
7401676Sjpk 			if (fp[j].number != i)
7411676Sjpk 				continue;
7421676Sjpk 			if (do_files) {
7431676Sjpk 				(void) da_add_list(&devlist, fp[j].name, i,
7441676Sjpk 				    DA_FLOPPY);
7451676Sjpk 			} else if (do_devalloc) {
7461676Sjpk 				/* print device_allocate for floppy devices */
7471676Sjpk 				if (system_labeled) {
7481676Sjpk 					(void) printf("%s%d%s\\\n",
7491676Sjpk 					    dname, i, KV_DELIMITER);
7501676Sjpk 					(void) printf("\t%s%s\\\n",
7511676Sjpk 					    DA_FLOPPY_TYPE, KV_DELIMITER);
7521676Sjpk 					(void) printf("\t%s%s\\\n",
7531676Sjpk 					    DA_RESERVED, KV_DELIMITER);
7541676Sjpk 					(void) printf("\t%s%s\\\n",
7551676Sjpk 					    DA_RESERVED, KV_DELIMITER);
7561676Sjpk 					(void) printf("\t%s%s\\\n",
7571676Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
7581676Sjpk 					    KV_DELIMITER);
7591676Sjpk 					(void) printf("\t%s\n\n", dclean);
7601676Sjpk 				} else {
7611676Sjpk 					(void) printf(
7621676Sjpk 					    "fd%d;fd;reserved;reserved;%s;",
7631676Sjpk 					    i, DEFAULT_DEV_ALLOC_AUTH);
7641676Sjpk 					(void) printf("%s%s\n", SECLIB,
7651676Sjpk 					    "/fd_clean");
7661676Sjpk 				}
7671676Sjpk 				break;
7681676Sjpk 			} else if (do_devmaps) {
7691676Sjpk 				/* print device_maps for floppy devices */
7701676Sjpk 				if (first) {
7711676Sjpk 					(void) printf(" ");
7721676Sjpk 				} else {
7731676Sjpk 					if (system_labeled) {
7741676Sjpk 						(void) printf("%s%d%s\\\n",
7751676Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
7761676Sjpk 						(void) printf("\t%s%s\\\n",
7771676Sjpk 						    DA_FLOPPY_TYPE,
7781676Sjpk 						    KV_TOKEN_DELIMIT);
7791676Sjpk 						(void) printf("\t");
7801676Sjpk 					} else {
7811676Sjpk 						(void) printf("fd%d:\\\n", i);
7821676Sjpk 						(void) printf("\tfd:\\\n");
7831676Sjpk 						(void) printf("\t");
7841676Sjpk 					}
7851676Sjpk 					if (i == 0) {
7861676Sjpk 						(void) printf("/dev/diskette ");
7871676Sjpk 						(void) printf(
7881676Sjpk 						    "/dev/rdiskette ");
7891676Sjpk 					}
7901676Sjpk 					first++;
7911676Sjpk 				}
7921676Sjpk 				(void) printf("%s", fp[j].name);
7931676Sjpk 			}
7940Sstevel@tonic-gate 		}
7951676Sjpk 		if (do_devmaps && first) {
7961676Sjpk 			(void) printf("\n\n");
7971676Sjpk 			first = 0;
7981676Sjpk 		}
7991676Sjpk 	}
8001676Sjpk 	if (do_files && floppy_count) {
8011676Sjpk 		dargs.rootdir = NULL;
8021676Sjpk 		dargs.devnames = NULL;
8031676Sjpk 		dargs.optflag = DA_ADD;
8041676Sjpk 		for (entry = devlist.floppy; entry != NULL;
8051676Sjpk 		    entry = entry->next) {
8061676Sjpk 			dargs.devinfo = &(entry->devinfo);
8071676Sjpk 			(void) da_update_device(&dargs);
8081676Sjpk 		}
8090Sstevel@tonic-gate 	}
8100Sstevel@tonic-gate }
8110Sstevel@tonic-gate 
8121676Sjpk static int
docd()8130Sstevel@tonic-gate docd()
8140Sstevel@tonic-gate {
8150Sstevel@tonic-gate 	DIR *dirp;
8160Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
8171676Sjpk 	int	i, j;
8180Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
8190Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
8200Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
8210Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
8220Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
8230Sstevel@tonic-gate 	int	id;		/* disk id */
8240Sstevel@tonic-gate 	int	ctrl;		/* disk controller */
8250Sstevel@tonic-gate 	int	ncd;		/* max array size */
8261676Sjpk 	int	cd_count = 0;
8271676Sjpk 	int	first = 0;
8281676Sjpk 	char	*dname, *dclean;
8291676Sjpk 	da_args	dargs;
8301676Sjpk 	deventry_t *entry;
8310Sstevel@tonic-gate 
8320Sstevel@tonic-gate 	ncd = DFLT_NCD;
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 	/*
8350Sstevel@tonic-gate 	 * look for sr* and rsr*
8360Sstevel@tonic-gate 	 */
8370Sstevel@tonic-gate 
8380Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
8390Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
8400Sstevel@tonic-gate 		exit(1);
8410Sstevel@tonic-gate 	}
8420Sstevel@tonic-gate 
8430Sstevel@tonic-gate 	i = 0;
8440Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
8450Sstevel@tonic-gate 		/* ignore if neither sr* nor rsr* */
8460Sstevel@tonic-gate 		if (strncmp(dep->d_name, "sr", SIZE_OF_SR) &&
8470Sstevel@tonic-gate 		    strncmp(dep->d_name, "rsr", SIZE_OF_RSR))
8480Sstevel@tonic-gate 			continue;
8490Sstevel@tonic-gate 
8500Sstevel@tonic-gate 		/* if array full, then expand it */
8510Sstevel@tonic-gate 		if (i == ncd) {
8520Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
8530Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
8540Sstevel@tonic-gate 		}
8550Sstevel@tonic-gate 
8560Sstevel@tonic-gate 		/* save name (/dev + / + d_name + \0) */
8570Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
8580Sstevel@tonic-gate 		if (nm == NULL)
8590Sstevel@tonic-gate 			no_memory();
8600Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
8610Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
8620Sstevel@tonic-gate 		cd[i].name = nm;
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
8650Sstevel@tonic-gate 		if (lstat(cd[i].name, &stat) < 0) {
8660Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
8670Sstevel@tonic-gate 			exit(1);
8680Sstevel@tonic-gate 		}
8690Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
8700Sstevel@tonic-gate 			continue;
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate 		/* get name from symbolic link */
8730Sstevel@tonic-gate 		if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
8740Sstevel@tonic-gate 		    0)
8750Sstevel@tonic-gate 			continue;
8761676Sjpk 
8770Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
8780Sstevel@tonic-gate 		if (nm == NULL)
8790Sstevel@tonic-gate 			no_memory();
8800Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
8810Sstevel@tonic-gate 		nm[sz] = '\0';
8820Sstevel@tonic-gate 		cd[i].device = nm;
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 		cp = strrchr(cd[i].device, '/');
8850Sstevel@tonic-gate 		cp++;				/* advance to device # */
8860Sstevel@tonic-gate 		(void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number);
8872728Saj 		cd[i].id = cd[i].number;
8880Sstevel@tonic-gate 
8890Sstevel@tonic-gate 		i++;
8900Sstevel@tonic-gate 	}
8911676Sjpk 	cd_count = i;
8920Sstevel@tonic-gate 
8930Sstevel@tonic-gate 	(void) closedir(dirp);
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 	/*
8960Sstevel@tonic-gate 	 * scan /dev/dsk for cd devices
8970Sstevel@tonic-gate 	 */
8980Sstevel@tonic-gate 
8990Sstevel@tonic-gate 	if ((dirp = opendir("/dev/dsk")) == NULL) {
9000Sstevel@tonic-gate 		perror("gettext(open /dev/dsk failure)");
9010Sstevel@tonic-gate 		exit(1);
9020Sstevel@tonic-gate 	}
9030Sstevel@tonic-gate 
9040Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
9050Sstevel@tonic-gate 		/* skip . .. etc... */
9060Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
9070Sstevel@tonic-gate 			continue;
9080Sstevel@tonic-gate 
9090Sstevel@tonic-gate 		/* get device # (disk #) */
910*11529SJan.Parcel@Sun.COM 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
9110Sstevel@tonic-gate 			continue;
9120Sstevel@tonic-gate 
9130Sstevel@tonic-gate 		/* see if this is one of the cd special devices */
9141676Sjpk 		for (j = 0; j < cd_count; j++) {
9150Sstevel@tonic-gate 			if (cd[j].number == id && cd[j].controller == ctrl)
9160Sstevel@tonic-gate 				goto found;
9170Sstevel@tonic-gate 		}
9180Sstevel@tonic-gate 		continue;
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate 		/* add new entry to table (/dev/dsk + / + d_name + \0) */
9210Sstevel@tonic-gate found:
9220Sstevel@tonic-gate 		/* if array full, then expand it */
9230Sstevel@tonic-gate 		if (i == ncd) {
9240Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
9250Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
9260Sstevel@tonic-gate 		}
9270Sstevel@tonic-gate 
9280Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
9290Sstevel@tonic-gate 		if (nm == NULL)
9300Sstevel@tonic-gate 			no_memory();
9310Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/dsk/");
9320Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
9330Sstevel@tonic-gate 		cd[i].name = nm;
9340Sstevel@tonic-gate 
9350Sstevel@tonic-gate 		cd[i].id = cd[j].id;
9360Sstevel@tonic-gate 
9370Sstevel@tonic-gate 		cd[i].device = "";
9380Sstevel@tonic-gate 
9390Sstevel@tonic-gate 		cd[i].number = id;
9400Sstevel@tonic-gate 
9410Sstevel@tonic-gate 		i++;
9420Sstevel@tonic-gate 	}
9430Sstevel@tonic-gate 
9440Sstevel@tonic-gate 	(void) closedir(dirp);
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 	/*
9470Sstevel@tonic-gate 	 * scan /dev/rdsk for cd devices
9480Sstevel@tonic-gate 	 */
9490Sstevel@tonic-gate 
9500Sstevel@tonic-gate 	if ((dirp = opendir("/dev/rdsk")) == NULL) {
9510Sstevel@tonic-gate 		perror(gettext("open /dev/dsk failure"));
9520Sstevel@tonic-gate 		exit(1);
9530Sstevel@tonic-gate 	}
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
9560Sstevel@tonic-gate 		/* skip . .. etc... */
9570Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
9580Sstevel@tonic-gate 			continue;
9590Sstevel@tonic-gate 
9600Sstevel@tonic-gate 		/* get device # (disk #) */
9610Sstevel@tonic-gate 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
9620Sstevel@tonic-gate 			continue;
9630Sstevel@tonic-gate 
9640Sstevel@tonic-gate 		/* see if this is one of the cd special devices */
9651676Sjpk 		for (j = 0; j < cd_count; j++) {
9660Sstevel@tonic-gate 			if (cd[j].number == id && cd[j].controller == ctrl)
9670Sstevel@tonic-gate 				goto found1;
9680Sstevel@tonic-gate 		}
9690Sstevel@tonic-gate 		continue;
9700Sstevel@tonic-gate 
9710Sstevel@tonic-gate 		/* add new entry to table (/dev/rdsk + / + d_name + \0) */
9720Sstevel@tonic-gate found1:
9730Sstevel@tonic-gate 		/* if array full, then expand it */
9740Sstevel@tonic-gate 		if (i == ncd) {
9750Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
9760Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
9770Sstevel@tonic-gate 		}
9780Sstevel@tonic-gate 
9790Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1);
9800Sstevel@tonic-gate 		if (nm == NULL)
9810Sstevel@tonic-gate 			no_memory();
9820Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/rdsk/");
9830Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
9840Sstevel@tonic-gate 		cd[i].name = nm;
9850Sstevel@tonic-gate 
9860Sstevel@tonic-gate 		cd[i].id = cd[j].id;
9870Sstevel@tonic-gate 
9880Sstevel@tonic-gate 		cd[i].device = "";
9890Sstevel@tonic-gate 
9900Sstevel@tonic-gate 		cd[i].number = id;
9910Sstevel@tonic-gate 
9920Sstevel@tonic-gate 		cd[i].controller = ctrl;
9930Sstevel@tonic-gate 
9940Sstevel@tonic-gate 		i++;
9950Sstevel@tonic-gate 	}
9960Sstevel@tonic-gate 
9970Sstevel@tonic-gate 	(void) closedir(dirp);
9980Sstevel@tonic-gate 
9991676Sjpk 	cd_count = i;
10000Sstevel@tonic-gate 
10011676Sjpk 	if (system_labeled) {
10021676Sjpk 		dname = DA_CD_NAME;
10031676Sjpk 		dclean = DA_DEFAULT_DISK_CLEAN;
10041676Sjpk 	} else {
10051676Sjpk 		dname = "sr";
10061676Sjpk 		dclean = CD_CLEAN;
10071676Sjpk 	}
10080Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
10091676Sjpk 		for (j = 0; j < cd_count; j++) {
10101676Sjpk 			if (cd[j].id != i)
10111676Sjpk 				continue;
10121676Sjpk 			if (do_files) {
10131676Sjpk 				(void) da_add_list(&devlist, cd[j].name, i,
10141676Sjpk 				    DA_CD);
10151676Sjpk 			} else if (do_devalloc) {
10161676Sjpk 				/* print device_allocate for cd devices */
10171676Sjpk 				if (system_labeled) {
10181676Sjpk 					(void) printf("%s%d%s\\\n",
10191676Sjpk 					    dname, i, KV_DELIMITER);
10201676Sjpk 					(void) printf("\t%s%s\\\n",
10211676Sjpk 					    DA_CD_TYPE, KV_DELIMITER);
10221676Sjpk 					(void) printf("\t%s%s\\\n",
10231676Sjpk 					    DA_RESERVED, KV_DELIMITER);
10241676Sjpk 					(void) printf("\t%s%s\\\n",
10251676Sjpk 					    DA_RESERVED, KV_DELIMITER);
10261676Sjpk 					(void) printf("\t%s%s\\\n",
10271676Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
10281676Sjpk 					    KV_DELIMITER);
10291676Sjpk 					(void) printf("\t%s\n\n", dclean);
10301676Sjpk 				} else {
10311676Sjpk 					(void) printf(
10321676Sjpk 					    "sr%d;sr;reserved;reserved;%s;",
10331676Sjpk 					    i, DEFAULT_DEV_ALLOC_AUTH);
10341676Sjpk 					(void) printf("%s%s\n", SECLIB,
10351676Sjpk 					    "/sr_clean");
10361676Sjpk 				}
10371676Sjpk 				break;
10381676Sjpk 			} else if (do_devmaps) {
10391676Sjpk 				/* print device_maps for cd devices */
10401676Sjpk 				if (first) {
10411676Sjpk 					(void) printf(" ");
10421676Sjpk 				} else {
10431676Sjpk 					if (system_labeled) {
10441676Sjpk 						(void) printf("%s%d%s\\\n",
10451676Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
10461676Sjpk 						(void) printf("\t%s%s\\\n",
10471676Sjpk 						    DA_CD_TYPE,
10481676Sjpk 						    KV_TOKEN_DELIMIT);
10491676Sjpk 						(void) printf("\t");
10501676Sjpk 					} else {
10511676Sjpk 						(void) printf("sr%d:\\\n", i);
10521676Sjpk 						(void) printf("\tsr:\\\n");
10531676Sjpk 						(void) printf("\t");
10541676Sjpk 					}
10551676Sjpk 					first++;
10561676Sjpk 				}
10571676Sjpk 				(void) printf("%s", cd[j].name);
10581676Sjpk 			}
10591676Sjpk 		}
10601676Sjpk 		if (do_devmaps && first) {
10611676Sjpk 			(void) printf("\n\n");
10621676Sjpk 			first = 0;
10631676Sjpk 		}
10641676Sjpk 	}
10651676Sjpk 	if (do_files && cd_count) {
10661676Sjpk 		dargs.rootdir = NULL;
10671676Sjpk 		dargs.devnames = NULL;
10681676Sjpk 		dargs.optflag = DA_ADD;
10691676Sjpk 		for (entry = devlist.cd; entry != NULL; entry = entry->next) {
10701676Sjpk 			dargs.devinfo = &(entry->devinfo);
10711676Sjpk 			(void) da_update_device(&dargs);
10721676Sjpk 		}
10731676Sjpk 	}
10741676Sjpk 
10751676Sjpk 	return (cd_count);
10761676Sjpk }
10771676Sjpk 
10781676Sjpk static void
dormdisk(int cd_count)10791676Sjpk dormdisk(int cd_count)
10801676Sjpk {
10811676Sjpk 	DIR *dirp;
10821676Sjpk 	struct dirent *dep;	/* directory entry pointer */
10831676Sjpk 	int	i, j;
10841676Sjpk 	char	*nm;		/* name/device of special device */
10851676Sjpk 	int	id;		/* disk id */
10861676Sjpk 	int	ctrl;		/* disk controller */
10871676Sjpk 	int	nrmdisk;	/* max array size */
10881676Sjpk 	int	fd = -1;
10891676Sjpk 	int	rmdisk_count;
10901676Sjpk 	int	first = 0;
10911676Sjpk 	int	is_cd;
10921676Sjpk 	int	checked;
10931676Sjpk 	int	removable;
10941676Sjpk 	char	path[MAXPATHLEN];
10951676Sjpk 	da_args	dargs;
10961676Sjpk 	deventry_t *entry;
10971676Sjpk 
10981676Sjpk 	nrmdisk = DFLT_RMDISK;
10991676Sjpk 	i = rmdisk_count = 0;
11001676Sjpk 
11011676Sjpk 	/*
11021676Sjpk 	 * scan /dev/dsk for rmdisk devices
11031676Sjpk 	 */
11041676Sjpk 	if ((dirp = opendir("/dev/dsk")) == NULL) {
11051676Sjpk 		perror("gettext(open /dev/dsk failure)");
11061676Sjpk 		exit(1);
11071676Sjpk 	}
11081676Sjpk 
11091676Sjpk 	while (dep = readdir(dirp)) {
11101676Sjpk 		is_cd = 0;
11111676Sjpk 		checked = 0;
11121676Sjpk 		removable = 0;
11131676Sjpk 		/* skip . .. etc... */
11141676Sjpk 		if (strncmp(dep->d_name, ".", 1) == NULL)
11151676Sjpk 			continue;
11161676Sjpk 
11171676Sjpk 		/* get device # (disk #) */
1118*11529SJan.Parcel@Sun.COM 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
11191676Sjpk 			continue;
11201676Sjpk 
11211676Sjpk 		/* see if we've already examined this device */
11221676Sjpk 		for (j = 0; j < i; j++) {
11231676Sjpk 			if (id == rmdisk[j].id &&
11241676Sjpk 			    ctrl == rmdisk[j].controller &&
11251676Sjpk 			    (strcmp(dep->d_name, rmdisk[j].name) == 0)) {
11261676Sjpk 				checked = 1;
11270Sstevel@tonic-gate 				break;
11280Sstevel@tonic-gate 			}
11291676Sjpk 			if (id == rmdisk[j].id && ctrl != rmdisk[j].controller)
11301676Sjpk 				/*
11311676Sjpk 				 * c2t0d0s0 is a different rmdisk than c3t0d0s0.
11321676Sjpk 				 */
11331676Sjpk 				id = rmdisk[j].id + 1;
11341676Sjpk 		}
11351676Sjpk 		if (checked)
11361676Sjpk 			continue;
11371676Sjpk 
11381676Sjpk 		/* ignore if this is a cd */
11391676Sjpk 		for (j = 0; j < cd_count; j++) {
11402728Saj 			if (id == cd[j].id && ctrl == cd[j].controller) {
11411676Sjpk 				is_cd = 1;
11421676Sjpk 				break;
11431676Sjpk 			}
11441676Sjpk 		}
11451676Sjpk 		if (is_cd)
11461676Sjpk 			continue;
11471676Sjpk 
11481676Sjpk 		/* see if device is removable */
11491676Sjpk 		(void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/",
11501676Sjpk 		    dep->d_name);
11511676Sjpk 		if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
11521676Sjpk 			continue;
11531676Sjpk 		(void) ioctl(fd, DKIOCREMOVABLE, &removable);
11541676Sjpk 		(void) close(fd);
11551676Sjpk 		if (removable == 0)
11561676Sjpk 			continue;
11571676Sjpk 
11581676Sjpk 		/*
11591676Sjpk 		 * add new entry to table (/dev/dsk + / + d_name + \0)
11601676Sjpk 		 * if array full, then expand it
11611676Sjpk 		 */
11621676Sjpk 		if (i == nrmdisk) {
11631676Sjpk 			/* will exit(1) if insufficient memory */
11641676Sjpk 			nrmdisk = expandmem(i, (void **)&rmdisk,
11651676Sjpk 			    sizeof (struct rmdisk));
1166*11529SJan.Parcel@Sun.COM 			/* When we expand rmdisk, need to expand rmdisk_r */
1167*11529SJan.Parcel@Sun.COM 			(void) expandmem(i, (void **)&rmdisk_r,
1168*11529SJan.Parcel@Sun.COM 			    sizeof (struct rmdisk));
11691676Sjpk 		}
11701676Sjpk 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
11711676Sjpk 		if (nm == NULL)
11721676Sjpk 			no_memory();
11731676Sjpk 		(void) strcpy(nm, "/dev/dsk/");
11741676Sjpk 		(void) strcat(nm, dep->d_name);
11751676Sjpk 		rmdisk[i].name = nm;
11761676Sjpk 		rmdisk[i].id = id;
11771676Sjpk 		rmdisk[i].controller = ctrl;
11781676Sjpk 		rmdisk[i].device = "";
11791676Sjpk 		rmdisk[i].number = id;
11801676Sjpk 		rmdisk_r[i].name = strdup(path);
11811676Sjpk 		i++;
11821676Sjpk 	}
11831676Sjpk 
11841676Sjpk 	rmdisk_count = i;
11851676Sjpk 	(void) closedir(dirp);
11861676Sjpk 
11871676Sjpk 	for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) {
11881676Sjpk 		if (j == nrmdisk) {
11891676Sjpk 			/* will exit(1) if insufficient memory */
11901676Sjpk 			nrmdisk = expandmem(j, (void **)&rmdisk,
11911676Sjpk 			    sizeof (struct rmdisk));
11921676Sjpk 		}
11931676Sjpk 		rmdisk[j].name = rmdisk_r[i].name;
11941676Sjpk 		rmdisk[j].id = rmdisk[i].id;
11951676Sjpk 		rmdisk[j].controller = rmdisk[i].controller;
11961676Sjpk 		rmdisk[j].device = rmdisk[i].device;
11971676Sjpk 		rmdisk[j].number = rmdisk[i].number;
11981676Sjpk 	}
11991676Sjpk 	rmdisk_count = j;
12001676Sjpk 
12011676Sjpk 	for (i = 0; i < 8; i++) {
12021676Sjpk 		for (j = 0; j < rmdisk_count; j++) {
12031676Sjpk 			if (rmdisk[j].id != i)
12041676Sjpk 				continue;
12051676Sjpk 			if (do_files) {
12061676Sjpk 				(void) da_add_list(&devlist, rmdisk[j].name, i,
12071676Sjpk 				    DA_RMDISK);
12081676Sjpk 			} else if (do_devalloc) {
12091676Sjpk 				/* print device_allocate for rmdisk devices */
12101676Sjpk 				(void) printf("%s%d%s\\\n",
12111676Sjpk 				    DA_RMDISK_NAME, i, KV_DELIMITER);
12121676Sjpk 				(void) printf("\t%s%s\\\n",
12131676Sjpk 				    DA_RMDISK_TYPE, KV_DELIMITER);
12141676Sjpk 				(void) printf("\t%s%s\\\n",
12151676Sjpk 				    DA_RESERVED, KV_DELIMITER);
12161676Sjpk 				(void) printf("\t%s%s\\\n",
12171676Sjpk 				    DA_RESERVED, KV_DELIMITER);
12181676Sjpk 				(void) printf("\t%s%s\\\n",
12191676Sjpk 				    DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER);
12201676Sjpk 				(void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN);
12211676Sjpk 				break;
12221676Sjpk 			} else if (do_devmaps) {
12231676Sjpk 				/* print device_maps for rmdisk devices */
12241676Sjpk 				if (first) {
12251676Sjpk 					(void) printf(" ");
12261676Sjpk 				} else {
12271676Sjpk 					(void) printf("%s%d%s\\\n",
12281676Sjpk 					    DA_RMDISK_NAME, i,
12291676Sjpk 					    KV_TOKEN_DELIMIT);
12301676Sjpk 					(void) printf("\t%s%s\\\n",
12311676Sjpk 					    DA_RMDISK_TYPE, KV_TOKEN_DELIMIT);
12321676Sjpk 					(void) printf("\t");
12331676Sjpk 					first++;
12341676Sjpk 				}
12351676Sjpk 				(void) printf("%s", rmdisk[j].name);
12361676Sjpk 			}
12371676Sjpk 		}
12381676Sjpk 		if (do_devmaps && first) {
12391676Sjpk 			(void) printf("\n\n");
12401676Sjpk 			first = 0;
12411676Sjpk 		}
12421676Sjpk 	}
12431676Sjpk 	if (do_files && rmdisk_count) {
12441676Sjpk 		dargs.rootdir = NULL;
12451676Sjpk 		dargs.devnames = NULL;
12461676Sjpk 		dargs.optflag = DA_ADD;
12471676Sjpk 		for (entry = devlist.rmdisk; entry != NULL;
12481676Sjpk 		    entry = entry->next) {
12491676Sjpk 			dargs.devinfo = &(entry->devinfo);
12501676Sjpk 			(void) da_update_device(&dargs);
12510Sstevel@tonic-gate 		}
12520Sstevel@tonic-gate 	}
12530Sstevel@tonic-gate }
12540Sstevel@tonic-gate 
12550Sstevel@tonic-gate /* set default array sizes */
12560Sstevel@tonic-gate static void
initmem()12570Sstevel@tonic-gate initmem()
12580Sstevel@tonic-gate {
12590Sstevel@tonic-gate 	tape  = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape));
12600Sstevel@tonic-gate 	audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
12610Sstevel@tonic-gate 	cd    = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
12620Sstevel@tonic-gate 	fp    = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
12631676Sjpk 	if (system_labeled) {
12641676Sjpk 		rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK,
12651676Sjpk 		    sizeof (struct rmdisk));
12661676Sjpk 		if (rmdisk == NULL)
12671676Sjpk 			no_memory();
12681676Sjpk 		rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK,
12691676Sjpk 		    sizeof (struct rmdisk));
12701676Sjpk 		if (rmdisk_r == NULL)
12711676Sjpk 			no_memory();
12721676Sjpk 	}
12730Sstevel@tonic-gate 
12740Sstevel@tonic-gate 	if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
12750Sstevel@tonic-gate 		no_memory();
12761676Sjpk 
12771676Sjpk 	devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk =
12781676Sjpk 	    devlist.tape = NULL;
12790Sstevel@tonic-gate }
12800Sstevel@tonic-gate 
12810Sstevel@tonic-gate /* note n will be # elments in array (and could be 0) */
12820Sstevel@tonic-gate static int
expandmem(int n,void ** array,int size)12830Sstevel@tonic-gate expandmem(int n, void **array, int size)
12840Sstevel@tonic-gate {
12850Sstevel@tonic-gate 	void *old = *array;
12860Sstevel@tonic-gate 	void *new;
12870Sstevel@tonic-gate 
12880Sstevel@tonic-gate 	/* get new array space (n + DELTA) */
12890Sstevel@tonic-gate 	new = (void *)calloc(n + DELTA,  size);
12900Sstevel@tonic-gate 
12910Sstevel@tonic-gate 	if (new == NULL) {
12920Sstevel@tonic-gate 		perror("memory allocation failed");
12930Sstevel@tonic-gate 		exit(1);
12940Sstevel@tonic-gate 	}
12950Sstevel@tonic-gate 
12960Sstevel@tonic-gate 	/* copy old array into new space */
12970Sstevel@tonic-gate 	bcopy(old, new, n * size);
12980Sstevel@tonic-gate 
12990Sstevel@tonic-gate 	/* now release old arrary */
13000Sstevel@tonic-gate 	free(old);
13010Sstevel@tonic-gate 
13020Sstevel@tonic-gate 	*array = new;
13030Sstevel@tonic-gate 
13040Sstevel@tonic-gate 	return (n + DELTA);
13050Sstevel@tonic-gate }
13060Sstevel@tonic-gate 
13070Sstevel@tonic-gate static void
no_memory(void)13080Sstevel@tonic-gate no_memory(void)
13090Sstevel@tonic-gate {
13100Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
13110Sstevel@tonic-gate 	    gettext("out of memory"));
13120Sstevel@tonic-gate 	exit(1);
13130Sstevel@tonic-gate 	/* NOT REACHED */
13140Sstevel@tonic-gate }
1315