xref: /titanic_53/usr/src/cmd/allocate/mkdevalloc.c (revision 45916cd2fec6e79bca5dee0421bd39e3c2910d1e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*45916cd2Sjpk  * Common Development and Distribution License (the "License").
6*45916cd2Sjpk  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*45916cd2Sjpk 
227c478bd9Sstevel@tonic-gate /*
23*45916cd2Sjpk  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * scan /dev directory for mountable objects and construct device_allocate
317c478bd9Sstevel@tonic-gate  * file for allocate....
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * devices are:
347c478bd9Sstevel@tonic-gate  *	tape (cartridge)
357c478bd9Sstevel@tonic-gate  *		/dev/rst*
367c478bd9Sstevel@tonic-gate  *		/dev/nrst*
377c478bd9Sstevel@tonic-gate  *		/dev/rmt/...
387c478bd9Sstevel@tonic-gate  *	audio
397c478bd9Sstevel@tonic-gate  *		/dev/audio
407c478bd9Sstevel@tonic-gate  *		/dev/audioctl
417c478bd9Sstevel@tonic-gate  *		/dev/sound/...
427c478bd9Sstevel@tonic-gate  *	floppy
437c478bd9Sstevel@tonic-gate  *		/dev/diskette
447c478bd9Sstevel@tonic-gate  *		/dev/fd*
457c478bd9Sstevel@tonic-gate  *		/dev/rdiskette
467c478bd9Sstevel@tonic-gate  *		/dev/rfd*
477c478bd9Sstevel@tonic-gate  *	CD
487c478bd9Sstevel@tonic-gate  *		/dev/sr*
497c478bd9Sstevel@tonic-gate  *		/dev/nsr*
507c478bd9Sstevel@tonic-gate  *		/dev/dsk/c?t?d0s?
517c478bd9Sstevel@tonic-gate  *		/dev/rdsk/c?t?d0s?
52*45916cd2Sjpk  *
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate 
55*45916cd2Sjpk #include <errno.h>
56*45916cd2Sjpk #include <fcntl.h>
577c478bd9Sstevel@tonic-gate #include <sys/types.h>	/* for stat(2), etc. */
587c478bd9Sstevel@tonic-gate #include <sys/stat.h>
597c478bd9Sstevel@tonic-gate #include <dirent.h>	/* for readdir(3), etc. */
607c478bd9Sstevel@tonic-gate #include <unistd.h>	/* for readlink(2) */
61*45916cd2Sjpk #include <stropts.h>
627c478bd9Sstevel@tonic-gate #include <string.h>	/* for strcpy(3), etc. */
637c478bd9Sstevel@tonic-gate #include <strings.h>	/* for bcopy(3C), etc. */
647c478bd9Sstevel@tonic-gate #include <stdio.h>	/* for perror(3) */
657c478bd9Sstevel@tonic-gate #include <stdlib.h>	/* for atoi(3) */
66*45916cd2Sjpk #include <sys/dkio.h>
677c478bd9Sstevel@tonic-gate #include <locale.h>
687c478bd9Sstevel@tonic-gate #include <libintl.h>
69*45916cd2Sjpk #include <libdevinfo.h>
70*45916cd2Sjpk #include <secdb.h>
717c478bd9Sstevel@tonic-gate #include <auth_attr.h>
727c478bd9Sstevel@tonic-gate #include <auth_list.h>
73*45916cd2Sjpk #include <bsm/devices.h>
74*45916cd2Sjpk #include <bsm/devalloc.h>
75*45916cd2Sjpk #include <tsol/label.h>
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN
787c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
797c478bd9Sstevel@tonic-gate #endif
807c478bd9Sstevel@tonic-gate 
81*45916cd2Sjpk #define	MKDEVALLOC	"mkdevalloc"
82*45916cd2Sjpk #define	MKDEVMAPS	"mkdevmaps"
83*45916cd2Sjpk 
847c478bd9Sstevel@tonic-gate #define	DELTA	5	/* array size delta when full */
85*45916cd2Sjpk #define	SECLIB	"/etc/security/lib"
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */
887c478bd9Sstevel@tonic-gate struct tape {
897c478bd9Sstevel@tonic-gate 	char	*name;
907c478bd9Sstevel@tonic-gate 	char	*device;
917c478bd9Sstevel@tonic-gate 	int	number;
927c478bd9Sstevel@tonic-gate } *tape;
937c478bd9Sstevel@tonic-gate #define	DFLT_NTAPE  10		/* size of initial array */
947c478bd9Sstevel@tonic-gate #define	SIZE_OF_RST  3		/* |rmt| */
957c478bd9Sstevel@tonic-gate #define	SIZE_OF_NRST 4		/* |nrmt| */
967c478bd9Sstevel@tonic-gate #define	SIZE_OF_TMP  4		/* |/tmp| */
977c478bd9Sstevel@tonic-gate #define	SIZE_OF_RMT  8		/* |/dev/rmt| */
98*45916cd2Sjpk #define	TAPE_CLEAN    SECLIB"/st_clean"
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */
1017c478bd9Sstevel@tonic-gate struct audio {
1027c478bd9Sstevel@tonic-gate 	char	*name;
1037c478bd9Sstevel@tonic-gate 	char	*device;
1047c478bd9Sstevel@tonic-gate 	int	number;
1057c478bd9Sstevel@tonic-gate } *audio;
1067c478bd9Sstevel@tonic-gate #define	DFLT_NAUDIO   10	/* size of initial array */
1077c478bd9Sstevel@tonic-gate #define	SIZE_OF_SOUND 10	/* |/dev/sound| */
108*45916cd2Sjpk #define	AUDIO_CLEAN   SECLIB"/audio_clean"
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
1117c478bd9Sstevel@tonic-gate struct cd {
1127c478bd9Sstevel@tonic-gate 	char	*name;
1137c478bd9Sstevel@tonic-gate 	char	*device;
1147c478bd9Sstevel@tonic-gate 	int	id;
1157c478bd9Sstevel@tonic-gate 	int	controller;
1167c478bd9Sstevel@tonic-gate 	int	number;
1177c478bd9Sstevel@tonic-gate } *cd;
1187c478bd9Sstevel@tonic-gate #define	DFLT_NCD    10		/* size of initial array */
1197c478bd9Sstevel@tonic-gate #define	SIZE_OF_SR   2		/* |sr| */
1207c478bd9Sstevel@tonic-gate #define	SIZE_OF_RSR  3		/* |rsr| */
1217c478bd9Sstevel@tonic-gate #define	SIZE_OF_DSK  8		/* |/dev/dsk| */
1227c478bd9Sstevel@tonic-gate #define	SIZE_OF_RDSK 9		/* |/dev/rdsk| */
123*45916cd2Sjpk #define	CD_CLEAN    SECLIB"/sr_clean"
1247c478bd9Sstevel@tonic-gate 
125*45916cd2Sjpk /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
126*45916cd2Sjpk struct rmdisk {
127*45916cd2Sjpk 	char	*name;
128*45916cd2Sjpk 	char	*device;
129*45916cd2Sjpk 	int	id;
130*45916cd2Sjpk 	int	controller;
131*45916cd2Sjpk 	int	number;
132*45916cd2Sjpk } *rmdisk, *rmdisk_r;
133*45916cd2Sjpk #define	DFLT_RMDISK	10	/* size of initial array */
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
1367c478bd9Sstevel@tonic-gate struct fp {
1377c478bd9Sstevel@tonic-gate 	char *name;
1387c478bd9Sstevel@tonic-gate 	char *device;
1397c478bd9Sstevel@tonic-gate 	int number;
1407c478bd9Sstevel@tonic-gate } *fp;
1417c478bd9Sstevel@tonic-gate #define	DFLT_NFP    10		/* size of initial array */
1427c478bd9Sstevel@tonic-gate #define	SIZE_OF_FD0  3		/* |fd0| */
1437c478bd9Sstevel@tonic-gate #define	SIZE_OF_RFD0 4		/* |rfd0| */
144*45916cd2Sjpk #define	FLOPPY_CLEAN SECLIB"/fd_clean"
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate static void dotape();
1477c478bd9Sstevel@tonic-gate static void doaudio();
1487c478bd9Sstevel@tonic-gate static void dofloppy();
149*45916cd2Sjpk static int docd();
150*45916cd2Sjpk static void dormdisk(int);
1517c478bd9Sstevel@tonic-gate static void initmem();
1527c478bd9Sstevel@tonic-gate static int  expandmem(int, void **, int);
1537c478bd9Sstevel@tonic-gate static void no_memory(void);
1547c478bd9Sstevel@tonic-gate 
155*45916cd2Sjpk int		system_labeled = 0;
156*45916cd2Sjpk int		do_devalloc = 0;
157*45916cd2Sjpk int		do_devmaps = 0;
158*45916cd2Sjpk int		do_files = 0;
159*45916cd2Sjpk devlist_t	devlist;
160*45916cd2Sjpk 
1617883e825Spaulson int
162*45916cd2Sjpk main(int argc, char **argv)
1637c478bd9Sstevel@tonic-gate {
164*45916cd2Sjpk 	int		cd_count = 0;
165*45916cd2Sjpk 	char		*progname;
166*45916cd2Sjpk 	struct stat	tx_stat;
167*45916cd2Sjpk 
1687c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1697c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1707c478bd9Sstevel@tonic-gate 
171*45916cd2Sjpk 	if ((progname = strrchr(argv[0], '/')) == NULL)
172*45916cd2Sjpk 		progname = argv[0];
173*45916cd2Sjpk 	else
174*45916cd2Sjpk 		progname++;
175*45916cd2Sjpk 	if (strcmp(progname, MKDEVALLOC) == 0)
176*45916cd2Sjpk 		do_devalloc = 1;
177*45916cd2Sjpk 	else if (strcmp(progname, MKDEVMAPS) == 0)
178*45916cd2Sjpk 		do_devmaps = 1;
179*45916cd2Sjpk 	else
180*45916cd2Sjpk 		exit(1);
181*45916cd2Sjpk 
182*45916cd2Sjpk 	system_labeled = is_system_labeled();
183*45916cd2Sjpk 	if (system_labeled == 0) {
184*45916cd2Sjpk 		/*
185*45916cd2Sjpk 		 * is_system_labeled() will return false in case we are
186*45916cd2Sjpk 		 * starting before the first reboot after Trusted Extensions
187*45916cd2Sjpk 		 * is installed. we check for a well known TX binary to
188*45916cd2Sjpk 		 * to see if TX is installed.
189*45916cd2Sjpk 		 */
190*45916cd2Sjpk 		if (stat(DA_LABEL_CHECK, &tx_stat) == 0)
191*45916cd2Sjpk 			system_labeled = 1;
192*45916cd2Sjpk 	}
193*45916cd2Sjpk 
194*45916cd2Sjpk 	if (system_labeled && do_devalloc && (argc == 2) &&
195*45916cd2Sjpk 	    (strcmp(argv[1], DA_IS_LABELED) == 0)) {
196*45916cd2Sjpk 		/*
197*45916cd2Sjpk 		 * write device entries to device_allocate and device_maps.
198*45916cd2Sjpk 		 * default is to print them on stdout.
199*45916cd2Sjpk 		 */
200*45916cd2Sjpk 		do_files = 1;
201*45916cd2Sjpk 	}
202*45916cd2Sjpk 
2037c478bd9Sstevel@tonic-gate 	initmem();		/* initialize memory */
204*45916cd2Sjpk 	dotape();
205*45916cd2Sjpk 	doaudio();
206*45916cd2Sjpk 	dofloppy();
207*45916cd2Sjpk 	cd_count = docd();
208*45916cd2Sjpk 	if (system_labeled)
209*45916cd2Sjpk 		dormdisk(cd_count);
2107883e825Spaulson 
2117883e825Spaulson 	return (0);
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate static void
2157c478bd9Sstevel@tonic-gate dotape()
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate 	DIR *dirp;
2187c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
219*45916cd2Sjpk 	int	i, j;
2207c478bd9Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
2217c478bd9Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
2227c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
2237c478bd9Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
2247c478bd9Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
2257c478bd9Sstevel@tonic-gate 	int	ntape;		/* max array size */
226*45916cd2Sjpk 	int	tape_count;
227*45916cd2Sjpk 	int	first = 0;
228*45916cd2Sjpk 	char	*dname, *dtype, *dclean;
229*45916cd2Sjpk 	da_args	dargs;
230*45916cd2Sjpk 	deventry_t *entry;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	ntape = DFLT_NTAPE;
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	/*
2357c478bd9Sstevel@tonic-gate 	 * look for rst* and nrst*
2367c478bd9Sstevel@tonic-gate 	 */
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
2397c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
2407c478bd9Sstevel@tonic-gate 		exit(1);
2417c478bd9Sstevel@tonic-gate 	}
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	i = 0;
2447c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
2457c478bd9Sstevel@tonic-gate 		/* ignore if neither rst* nor nrst* */
2467c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, "rst", SIZE_OF_RST) &&
2477c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "nrst", SIZE_OF_NRST))
2487c478bd9Sstevel@tonic-gate 			continue;
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
2517c478bd9Sstevel@tonic-gate 		if (i == ntape) {
2527c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
2537c478bd9Sstevel@tonic-gate 			ntape = expandmem(i, (void **)&tape,
2547c478bd9Sstevel@tonic-gate 					sizeof (struct tape));
2557c478bd9Sstevel@tonic-gate 		}
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 		/* save name (/dev + / + d_name + \0) */
2587c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
2597c478bd9Sstevel@tonic-gate 		if (nm == NULL)
2607c478bd9Sstevel@tonic-gate 			no_memory();
2617c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
2627c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
2637c478bd9Sstevel@tonic-gate 		tape[i].name = nm;
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
2667c478bd9Sstevel@tonic-gate 		if (lstat(tape[i].name, &stat) < 0) {
2677c478bd9Sstevel@tonic-gate 			perror("stat(2) failed ");
2687c478bd9Sstevel@tonic-gate 			exit(1);
2697c478bd9Sstevel@tonic-gate 		}
2707c478bd9Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
2717c478bd9Sstevel@tonic-gate 			continue;
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
2747c478bd9Sstevel@tonic-gate 		if ((sz = readlink(tape[i].name, linkvalue,
2757c478bd9Sstevel@tonic-gate 				sizeof (linkvalue))) < 0)
2767c478bd9Sstevel@tonic-gate 			continue;
2777c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
2787c478bd9Sstevel@tonic-gate 		if (nm == NULL)
2797c478bd9Sstevel@tonic-gate 			no_memory();
2807c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
2817c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
2827c478bd9Sstevel@tonic-gate 		tape[i].device = nm;
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 		/* get device number */
2857c478bd9Sstevel@tonic-gate 		cp = strrchr(tape[i].device, '/');
2867c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
2877c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &tape[i].number);
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 		i++;
2907c478bd9Sstevel@tonic-gate 	}
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	/*
2957c478bd9Sstevel@tonic-gate 	 * scan /dev/rmt and add entry to table
2967c478bd9Sstevel@tonic-gate 	 */
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/rmt")) == NULL) {
2997c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
3007c478bd9Sstevel@tonic-gate 		exit(1);
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
3047c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
3057c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
3067c478bd9Sstevel@tonic-gate 			continue;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
3097c478bd9Sstevel@tonic-gate 		if (i == ntape) {
3107c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
3117c478bd9Sstevel@tonic-gate 			ntape = expandmem(i, (void **)&tape,
3127c478bd9Sstevel@tonic-gate 					sizeof (struct tape));
3137c478bd9Sstevel@tonic-gate 		}
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 		/* save name (/dev/rmt + / + d_name + \0) */
3167c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1);
3177c478bd9Sstevel@tonic-gate 		if (nm == NULL)
3187c478bd9Sstevel@tonic-gate 			no_memory();
3197c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/rmt/");
3207c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
3217c478bd9Sstevel@tonic-gate 		tape[i].name = nm;
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 		/* save device name (rmt/ + d_name + \0) */
3247c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
3257c478bd9Sstevel@tonic-gate 		if (nm == NULL)
3267c478bd9Sstevel@tonic-gate 			no_memory();
3277c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "rmt/");
3287c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
3297c478bd9Sstevel@tonic-gate 		tape[i].device = nm;
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 		(void) sscanf(dep->d_name, "%d", &tape[i].number);
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 		i++;
3347c478bd9Sstevel@tonic-gate 	}
335*45916cd2Sjpk 	tape_count = i;
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	/* remove duplicate entries */
340*45916cd2Sjpk 	for (i = 0; i < tape_count - 1; i++) {
341*45916cd2Sjpk 		for (j = i + 1; j < tape_count; j++) {
3427c478bd9Sstevel@tonic-gate 			if (strcmp(tape[i].device, tape[j].device))
3437c478bd9Sstevel@tonic-gate 				continue;
3447c478bd9Sstevel@tonic-gate 			tape[j].number = -1;
3457c478bd9Sstevel@tonic-gate 		}
3467c478bd9Sstevel@tonic-gate 	}
3477c478bd9Sstevel@tonic-gate 
348*45916cd2Sjpk 	if (system_labeled) {
349*45916cd2Sjpk 		dname = DA_TAPE_NAME;
350*45916cd2Sjpk 		dtype = DA_TAPE_TYPE;
351*45916cd2Sjpk 		dclean = DA_DEFAULT_TAPE_CLEAN;
352*45916cd2Sjpk 	} else {
353*45916cd2Sjpk 		dname = "st";
354*45916cd2Sjpk 		dtype = "st";
355*45916cd2Sjpk 		dclean = TAPE_CLEAN;
356*45916cd2Sjpk 	}
3577c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
358*45916cd2Sjpk 		for (j = 0; j < tape_count; j++) {
359*45916cd2Sjpk 			if (tape[j].number != i)
360*45916cd2Sjpk 				continue;
361*45916cd2Sjpk 			if (do_files) {
362*45916cd2Sjpk 				(void) da_add_list(&devlist, tape[j].name, i,
363*45916cd2Sjpk 				    DA_TAPE);
364*45916cd2Sjpk 			} else if (do_devalloc) {
365*45916cd2Sjpk 				/* print device_allocate for tape devices */
366*45916cd2Sjpk 				if (system_labeled) {
367*45916cd2Sjpk 					(void) printf("%s%d%s\\\n",
368*45916cd2Sjpk 					    dname, i, KV_DELIMITER);
369*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
370*45916cd2Sjpk 					    DA_TAPE_TYPE, KV_DELIMITER);
371*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
372*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
373*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
374*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
375*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
376*45916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
377*45916cd2Sjpk 					    KV_DELIMITER);
378*45916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
379*45916cd2Sjpk 				} else {
3807c478bd9Sstevel@tonic-gate 					(void) printf(
3817c478bd9Sstevel@tonic-gate 					    "st%d;st;reserved;reserved;%s;",
3827c478bd9Sstevel@tonic-gate 					    i, DEFAULT_DEV_ALLOC_AUTH);
383*45916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
384*45916cd2Sjpk 					    "/st_clean");
3857c478bd9Sstevel@tonic-gate 				}
386*45916cd2Sjpk 				break;
387*45916cd2Sjpk 			} else if (do_devmaps) {
388*45916cd2Sjpk 				/* print device_maps for tape devices */
389*45916cd2Sjpk 				if (first) {
390*45916cd2Sjpk 					(void) printf(" ");
391*45916cd2Sjpk 				} else {
392*45916cd2Sjpk 					if (system_labeled) {
393*45916cd2Sjpk 						(void) printf("%s%d%s\\\n",
394*45916cd2Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
395*45916cd2Sjpk 						(void) printf("\t%s%s\\\n",
396*45916cd2Sjpk 						    dtype, KV_TOKEN_DELIMIT);
397*45916cd2Sjpk 						(void) printf("\t");
398*45916cd2Sjpk 					} else {
399*45916cd2Sjpk 						(void) printf("st%d:\\\n", i);
400*45916cd2Sjpk 						(void) printf("\trmt:\\\n");
401*45916cd2Sjpk 						(void) printf("\t");
402*45916cd2Sjpk 					}
403*45916cd2Sjpk 						first++;
404*45916cd2Sjpk 				}
405*45916cd2Sjpk 				(void) printf("%s", tape[j].name);
406*45916cd2Sjpk 			}
407*45916cd2Sjpk 		}
408*45916cd2Sjpk 		if (do_devmaps && first) {
409*45916cd2Sjpk 			(void) printf("\n\n");
410*45916cd2Sjpk 			first = 0;
411*45916cd2Sjpk 		}
412*45916cd2Sjpk 	}
413*45916cd2Sjpk 	if (do_files && tape_count) {
414*45916cd2Sjpk 		dargs.rootdir = NULL;
415*45916cd2Sjpk 		dargs.devnames = NULL;
416*45916cd2Sjpk 		dargs.optflag = DA_ADD;
417*45916cd2Sjpk 		for (entry = devlist.tape; entry != NULL; entry = entry->next) {
418*45916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
419*45916cd2Sjpk 			(void) da_update_device(&dargs);
4207c478bd9Sstevel@tonic-gate 		}
4217c478bd9Sstevel@tonic-gate 	}
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate static void
4257c478bd9Sstevel@tonic-gate doaudio()
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate 	DIR *dirp;
4287c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
429*45916cd2Sjpk 	int	i, j;
4307c478bd9Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
4317c478bd9Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
4327c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
4337c478bd9Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
4347c478bd9Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
4357c478bd9Sstevel@tonic-gate 	int	naudio;		/* max array size */
436*45916cd2Sjpk 	int	audio_count = 0;
437*45916cd2Sjpk 	int	len, slen;
438*45916cd2Sjpk 	int	first = 0;
439*45916cd2Sjpk 	char	dname[128];
440*45916cd2Sjpk 	char	*dclean;
441*45916cd2Sjpk 	da_args	dargs;
442*45916cd2Sjpk 	deventry_t *entry;
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 	naudio = DFLT_NAUDIO;
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
4477c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
4487c478bd9Sstevel@tonic-gate 		exit(1);
4497c478bd9Sstevel@tonic-gate 	}
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	i = 0;
4527c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
4537c478bd9Sstevel@tonic-gate 		if (strcmp(dep->d_name, "audio") &&
4547c478bd9Sstevel@tonic-gate 		    strcmp(dep->d_name, "audioctl"))
4557c478bd9Sstevel@tonic-gate 			continue;
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
4587c478bd9Sstevel@tonic-gate 		if (i == naudio) {
4597c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
4607c478bd9Sstevel@tonic-gate 			naudio = expandmem(i, (void **)&audio,
4617c478bd9Sstevel@tonic-gate 					sizeof (struct audio));
4627c478bd9Sstevel@tonic-gate 		}
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 		/* save name (/dev + 1 + d_name + \0) */
4657c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
4667c478bd9Sstevel@tonic-gate 		if (nm == NULL)
4677c478bd9Sstevel@tonic-gate 			no_memory();
4687c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
4697c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
4707c478bd9Sstevel@tonic-gate 		audio[i].name = nm;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
4737c478bd9Sstevel@tonic-gate 		if (lstat(audio[i].name, &stat) < 0) {
4747c478bd9Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
4757c478bd9Sstevel@tonic-gate 			exit(1);
4767c478bd9Sstevel@tonic-gate 		}
4777c478bd9Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
4787c478bd9Sstevel@tonic-gate 			continue;
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
4817c478bd9Sstevel@tonic-gate 		if ((sz = readlink(audio[i].name, linkvalue,
4827c478bd9Sstevel@tonic-gate 				sizeof (linkvalue))) < 0)
4837c478bd9Sstevel@tonic-gate 			continue;
4847c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
4857c478bd9Sstevel@tonic-gate 		if (nm == NULL)
4867c478bd9Sstevel@tonic-gate 			no_memory();
4877c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
4887c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
4897c478bd9Sstevel@tonic-gate 		audio[i].device = nm;
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 		cp = strrchr(audio[i].device, '/');
4927c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
4937c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &audio[i].number);
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate 		i++;
4967c478bd9Sstevel@tonic-gate 	}
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/sound")) == NULL) {
5017c478bd9Sstevel@tonic-gate 		goto skip;
5027c478bd9Sstevel@tonic-gate 	}
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
5057c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
5067c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
5077c478bd9Sstevel@tonic-gate 			continue;
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
5107c478bd9Sstevel@tonic-gate 		if (i == naudio) {
5117c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
5127c478bd9Sstevel@tonic-gate 			naudio = expandmem(i, (void **)&audio,
5137c478bd9Sstevel@tonic-gate 					sizeof (struct audio));
5147c478bd9Sstevel@tonic-gate 		}
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 		/* save name (/dev/sound + / + d_name + \0) */
5177c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
5187c478bd9Sstevel@tonic-gate 		    strlen(dep->d_name) + 1);
5197c478bd9Sstevel@tonic-gate 		if (nm == NULL)
5207c478bd9Sstevel@tonic-gate 			no_memory();
5217c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/sound/");
5227c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
5237c478bd9Sstevel@tonic-gate 		audio[i].name = nm;
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
5267c478bd9Sstevel@tonic-gate 		    strlen(dep->d_name) + 1);
5277c478bd9Sstevel@tonic-gate 		if (nm == NULL)
5287c478bd9Sstevel@tonic-gate 			no_memory();
5297c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/sound/");
5307c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
5317c478bd9Sstevel@tonic-gate 		audio[i].device = nm;
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 		(void) sscanf(dep->d_name, "%d", &audio[i].number);
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 		i++;
5367c478bd9Sstevel@tonic-gate 	}
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate skip:
541*45916cd2Sjpk 	audio_count = i;
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 	/* remove duplicate entries */
544*45916cd2Sjpk 	for (i = 0; i < audio_count - 1; i++) {
545*45916cd2Sjpk 		for (j = i + 1; j < audio_count; j++) {
5467c478bd9Sstevel@tonic-gate 			if (strcmp(audio[i].device, audio[j].device))
5477c478bd9Sstevel@tonic-gate 				continue;
5487c478bd9Sstevel@tonic-gate 			audio[j].number = -1;
5497c478bd9Sstevel@tonic-gate 		}
5507c478bd9Sstevel@tonic-gate 	}
5517c478bd9Sstevel@tonic-gate 
552*45916cd2Sjpk 	/* print out device_allocate entries for audio devices */
553*45916cd2Sjpk 	(void) strcpy(dname, DA_AUDIO_NAME);
554*45916cd2Sjpk 	slen = strlen(DA_AUDIO_NAME);
555*45916cd2Sjpk 	len = sizeof (dname) - slen;
556*45916cd2Sjpk 	dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN;
5577c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
558*45916cd2Sjpk 		for (j = 0; j < audio_count; j++) {
559*45916cd2Sjpk 			if (audio[j].number != i)
560*45916cd2Sjpk 				continue;
561*45916cd2Sjpk 			if (system_labeled)
562*45916cd2Sjpk 				(void) snprintf(dname+slen, len, "%d", i);
563*45916cd2Sjpk 			if (do_files) {
564*45916cd2Sjpk 				(void) da_add_list(&devlist, audio[j].name,
565*45916cd2Sjpk 				    i, DA_AUDIO);
566*45916cd2Sjpk 			} else if (do_devalloc) {
567*45916cd2Sjpk 				/* print device_allocate for audio devices */
568*45916cd2Sjpk 				if (system_labeled) {
569*45916cd2Sjpk 					(void) printf("%s%s\\\n",
570*45916cd2Sjpk 					    dname, KV_DELIMITER);
571*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
572*45916cd2Sjpk 					    DA_AUDIO_TYPE, KV_DELIMITER);
573*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
574*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
575*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
576*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
577*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
578*45916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
579*45916cd2Sjpk 					    KV_DELIMITER);
580*45916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
581*45916cd2Sjpk 				} else {
5827c478bd9Sstevel@tonic-gate 					(void) printf("audio;audio;");
5837c478bd9Sstevel@tonic-gate 					(void) printf("reserved;reserved;%s;",
5847c478bd9Sstevel@tonic-gate 					    DEFAULT_DEV_ALLOC_AUTH);
585*45916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
586*45916cd2Sjpk 					    "/audio_clean");
5877c478bd9Sstevel@tonic-gate 				}
588*45916cd2Sjpk 				break;
589*45916cd2Sjpk 			} else if (do_devmaps) {
590*45916cd2Sjpk 				/* print device_maps for audio devices */
591*45916cd2Sjpk 				if (first) {
592*45916cd2Sjpk 					(void) printf(" ");
593*45916cd2Sjpk 				} else {
594*45916cd2Sjpk 					if (system_labeled) {
595*45916cd2Sjpk 						(void) printf("%s%s\\\n",
596*45916cd2Sjpk 						    dname, KV_TOKEN_DELIMIT);
597*45916cd2Sjpk 						(void) printf("\t%s%s\\\n",
598*45916cd2Sjpk 						    DA_AUDIO_TYPE,
599*45916cd2Sjpk 						    KV_TOKEN_DELIMIT);
600*45916cd2Sjpk 						(void) printf("\t");
601*45916cd2Sjpk 					} else {
602*45916cd2Sjpk 						(void) printf("audio:\\\n");
603*45916cd2Sjpk 						(void) printf("\taudio:\\\n");
604*45916cd2Sjpk 						(void) printf("\t");
605*45916cd2Sjpk 					}
606*45916cd2Sjpk 					first++;
607*45916cd2Sjpk 				}
608*45916cd2Sjpk 				(void) printf("%s", audio[j].name);
609*45916cd2Sjpk 			}
610*45916cd2Sjpk 		}
611*45916cd2Sjpk 		if (do_devmaps && first) {
612*45916cd2Sjpk 			(void) printf("\n\n");
613*45916cd2Sjpk 			first = 0;
614*45916cd2Sjpk 		}
615*45916cd2Sjpk 	}
616*45916cd2Sjpk 	if (do_files && audio_count) {
617*45916cd2Sjpk 		dargs.rootdir = NULL;
618*45916cd2Sjpk 		dargs.devnames = NULL;
619*45916cd2Sjpk 		dargs.optflag = DA_ADD;
620*45916cd2Sjpk 		for (entry = devlist.audio; entry != NULL;
621*45916cd2Sjpk 		    entry = entry->next) {
622*45916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
623*45916cd2Sjpk 			(void) da_update_device(&dargs);
6247c478bd9Sstevel@tonic-gate 		}
6257c478bd9Sstevel@tonic-gate 	}
6267c478bd9Sstevel@tonic-gate }
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate static void
6297c478bd9Sstevel@tonic-gate dofloppy()
6307c478bd9Sstevel@tonic-gate {
6317c478bd9Sstevel@tonic-gate 	DIR *dirp;
6327c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
633*45916cd2Sjpk 	int i, j;
6347c478bd9Sstevel@tonic-gate 	char *nm;		/* name/device of special device */
6357c478bd9Sstevel@tonic-gate 	char linkvalue[2048];	/* symlink value */
6367c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
6377c478bd9Sstevel@tonic-gate 	int sz;			/* size of symlink value */
6387c478bd9Sstevel@tonic-gate 	char *cp;		/* pointer into string */
6397c478bd9Sstevel@tonic-gate 	int nfp;		/* max array size */
640*45916cd2Sjpk 	int floppy_count = 0;
641*45916cd2Sjpk 	int first = 0;
642*45916cd2Sjpk 	char *dname, *dclean;
643*45916cd2Sjpk 	da_args dargs;
644*45916cd2Sjpk 	deventry_t *entry;
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	nfp = DFLT_NFP;
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 	/*
6497c478bd9Sstevel@tonic-gate 	 * look for fd* and rfd*
6507c478bd9Sstevel@tonic-gate 	 */
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
6537c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
6547c478bd9Sstevel@tonic-gate 		exit(1);
6557c478bd9Sstevel@tonic-gate 	}
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate 	i = 0;
6587c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
6597c478bd9Sstevel@tonic-gate 		/* ignore if neither rst* nor nrst* */
6607c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) &&
6617c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) &&
6627c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "fd1", SIZE_OF_FD0) &&
6637c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0))
6647c478bd9Sstevel@tonic-gate 			continue;
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
6677c478bd9Sstevel@tonic-gate 		if (i == nfp) {
6687c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
6697c478bd9Sstevel@tonic-gate 			nfp = expandmem(i, (void **)&fp, sizeof (struct fp));
6707c478bd9Sstevel@tonic-gate 		}
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 		/* save name (/dev + 1 + d_name + \0) */
6737c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
6747c478bd9Sstevel@tonic-gate 		if (nm == NULL)
6757c478bd9Sstevel@tonic-gate 			no_memory();
6767c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
6777c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
6787c478bd9Sstevel@tonic-gate 		fp[i].name = nm;
6797c478bd9Sstevel@tonic-gate 
6807c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
6817c478bd9Sstevel@tonic-gate 		if (lstat(fp[i].name, &stat) < 0) {
6827c478bd9Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
6837c478bd9Sstevel@tonic-gate 			exit(1);
6847c478bd9Sstevel@tonic-gate 		}
6857c478bd9Sstevel@tonic-gate 		if ((stat.st_mode&S_IFMT) != S_IFLNK)
6867c478bd9Sstevel@tonic-gate 			continue;
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
6897c478bd9Sstevel@tonic-gate 		if ((sz = readlink(fp[i].name, linkvalue,
6907c478bd9Sstevel@tonic-gate 		    sizeof (linkvalue))) < 0)
6917c478bd9Sstevel@tonic-gate 			continue;
6927c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz+1);
6937c478bd9Sstevel@tonic-gate 		if (nm == NULL)
6947c478bd9Sstevel@tonic-gate 			no_memory();
6957c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
6967c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
6977c478bd9Sstevel@tonic-gate 		fp[i].device = nm;
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 		/* get device number */
7007c478bd9Sstevel@tonic-gate 		cp = strchr(fp[i].name, 'd');
7017c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
7027c478bd9Sstevel@tonic-gate 		cp = strchr(cp, 'd');
7037c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
7047c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &fp[i].number);
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 		i++;
7077c478bd9Sstevel@tonic-gate 	}
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
7107c478bd9Sstevel@tonic-gate 
711*45916cd2Sjpk 	floppy_count = i;
7127c478bd9Sstevel@tonic-gate 
713*45916cd2Sjpk 	/* print out device_allocate entries for floppy devices */
714*45916cd2Sjpk 	if (system_labeled) {
715*45916cd2Sjpk 		dname = DA_FLOPPY_NAME;
716*45916cd2Sjpk 		dclean = DA_DEFAULT_DISK_CLEAN;
717*45916cd2Sjpk 	} else {
718*45916cd2Sjpk 		dname = "fd";
719*45916cd2Sjpk 		dclean = FLOPPY_CLEAN;
720*45916cd2Sjpk 	}
7217c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
722*45916cd2Sjpk 		for (j = 0; j < floppy_count; j++) {
723*45916cd2Sjpk 			if (fp[j].number != i)
724*45916cd2Sjpk 				continue;
725*45916cd2Sjpk 			if (do_files) {
726*45916cd2Sjpk 				(void) da_add_list(&devlist, fp[j].name, i,
727*45916cd2Sjpk 				    DA_FLOPPY);
728*45916cd2Sjpk 			} else if (do_devalloc) {
729*45916cd2Sjpk 				/* print device_allocate for floppy devices */
730*45916cd2Sjpk 				if (system_labeled) {
731*45916cd2Sjpk 					(void) printf("%s%d%s\\\n",
732*45916cd2Sjpk 					    dname, i, KV_DELIMITER);
733*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
734*45916cd2Sjpk 					    DA_FLOPPY_TYPE, KV_DELIMITER);
735*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
736*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
737*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
738*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
739*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
740*45916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
741*45916cd2Sjpk 					    KV_DELIMITER);
742*45916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
743*45916cd2Sjpk 				} else {
744*45916cd2Sjpk 					(void) printf(
745*45916cd2Sjpk 					    "fd%d;fd;reserved;reserved;%s;",
7467c478bd9Sstevel@tonic-gate 					    i, DEFAULT_DEV_ALLOC_AUTH);
747*45916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
748*45916cd2Sjpk 					    "/fd_clean");
7497c478bd9Sstevel@tonic-gate 				}
750*45916cd2Sjpk 				break;
751*45916cd2Sjpk 			} else if (do_devmaps) {
752*45916cd2Sjpk 				/* print device_maps for floppy devices */
753*45916cd2Sjpk 				if (first) {
754*45916cd2Sjpk 					(void) printf(" ");
755*45916cd2Sjpk 				} else {
756*45916cd2Sjpk 					if (system_labeled) {
757*45916cd2Sjpk 						(void) printf("%s%d%s\\\n",
758*45916cd2Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
759*45916cd2Sjpk 						(void) printf("\t%s%s\\\n",
760*45916cd2Sjpk 						    DA_FLOPPY_TYPE,
761*45916cd2Sjpk 						    KV_TOKEN_DELIMIT);
762*45916cd2Sjpk 						(void) printf("\t");
763*45916cd2Sjpk 					} else {
764*45916cd2Sjpk 						(void) printf("fd%d:\\\n", i);
765*45916cd2Sjpk 						(void) printf("\tfd:\\\n");
766*45916cd2Sjpk 						(void) printf("\t");
767*45916cd2Sjpk 					}
768*45916cd2Sjpk 					if (i == 0) {
769*45916cd2Sjpk 						(void) printf("/dev/diskette ");
770*45916cd2Sjpk 						(void) printf(
771*45916cd2Sjpk 						    "/dev/rdiskette ");
772*45916cd2Sjpk 					}
773*45916cd2Sjpk 					first++;
774*45916cd2Sjpk 				}
775*45916cd2Sjpk 				(void) printf("%s", fp[j].name);
776*45916cd2Sjpk 			}
777*45916cd2Sjpk 		}
778*45916cd2Sjpk 		if (do_devmaps && first) {
779*45916cd2Sjpk 			(void) printf("\n\n");
780*45916cd2Sjpk 			first = 0;
781*45916cd2Sjpk 		}
782*45916cd2Sjpk 	}
783*45916cd2Sjpk 	if (do_files && floppy_count) {
784*45916cd2Sjpk 		dargs.rootdir = NULL;
785*45916cd2Sjpk 		dargs.devnames = NULL;
786*45916cd2Sjpk 		dargs.optflag = DA_ADD;
787*45916cd2Sjpk 		for (entry = devlist.floppy; entry != NULL;
788*45916cd2Sjpk 		    entry = entry->next) {
789*45916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
790*45916cd2Sjpk 			(void) da_update_device(&dargs);
7917c478bd9Sstevel@tonic-gate 		}
7927c478bd9Sstevel@tonic-gate 	}
7937c478bd9Sstevel@tonic-gate }
7947c478bd9Sstevel@tonic-gate 
795*45916cd2Sjpk static int
7967c478bd9Sstevel@tonic-gate docd()
7977c478bd9Sstevel@tonic-gate {
7987c478bd9Sstevel@tonic-gate 	DIR *dirp;
7997c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
800*45916cd2Sjpk 	int	i, j;
8017c478bd9Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
8027c478bd9Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
8037c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
8047c478bd9Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
8057c478bd9Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
8067c478bd9Sstevel@tonic-gate 	int	id;		/* disk id */
8077c478bd9Sstevel@tonic-gate 	int	ctrl;		/* disk controller */
8087c478bd9Sstevel@tonic-gate 	int	ncd;		/* max array size */
809*45916cd2Sjpk 	int	cd_count = 0;
810*45916cd2Sjpk 	int	first = 0;
811*45916cd2Sjpk 	char	*dname, *dclean;
812*45916cd2Sjpk 	da_args	dargs;
813*45916cd2Sjpk 	deventry_t *entry;
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	ncd = DFLT_NCD;
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 	/*
8187c478bd9Sstevel@tonic-gate 	 * look for sr* and rsr*
8197c478bd9Sstevel@tonic-gate 	 */
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
8227c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
8237c478bd9Sstevel@tonic-gate 		exit(1);
8247c478bd9Sstevel@tonic-gate 	}
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate 	i = 0;
8277c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
8287c478bd9Sstevel@tonic-gate 		/* ignore if neither sr* nor rsr* */
8297c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, "sr", SIZE_OF_SR) &&
8307c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "rsr", SIZE_OF_RSR))
8317c478bd9Sstevel@tonic-gate 			continue;
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
8347c478bd9Sstevel@tonic-gate 		if (i == ncd) {
8357c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
8367c478bd9Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
8377c478bd9Sstevel@tonic-gate 		}
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate 		/* save name (/dev + / + d_name + \0) */
8407c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
8417c478bd9Sstevel@tonic-gate 		if (nm == NULL)
8427c478bd9Sstevel@tonic-gate 			no_memory();
8437c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
8447c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
8457c478bd9Sstevel@tonic-gate 		cd[i].name = nm;
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 		/* save id # */
8487c478bd9Sstevel@tonic-gate 		if (dep->d_name[0] == 'r')
8497c478bd9Sstevel@tonic-gate 			(void) sscanf(dep->d_name, "rsr%d", &cd[i].id);
8507c478bd9Sstevel@tonic-gate 		else
8517c478bd9Sstevel@tonic-gate 			(void) sscanf(dep->d_name, "sr%d", &cd[i].id);
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
8547c478bd9Sstevel@tonic-gate 		if (lstat(cd[i].name, &stat) < 0) {
8557c478bd9Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
8567c478bd9Sstevel@tonic-gate 			exit(1);
8577c478bd9Sstevel@tonic-gate 		}
8587c478bd9Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
8597c478bd9Sstevel@tonic-gate 			continue;
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
8627c478bd9Sstevel@tonic-gate 		if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
8637c478bd9Sstevel@tonic-gate 		    0)
8647c478bd9Sstevel@tonic-gate 			continue;
865*45916cd2Sjpk 
8667c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
8677c478bd9Sstevel@tonic-gate 		if (nm == NULL)
8687c478bd9Sstevel@tonic-gate 			no_memory();
8697c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
8707c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
8717c478bd9Sstevel@tonic-gate 		cd[i].device = nm;
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate 		cp = strrchr(cd[i].device, '/');
8747c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
8757c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number);
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 		i++;
8787c478bd9Sstevel@tonic-gate 	}
879*45916cd2Sjpk 	cd_count = i;
8807c478bd9Sstevel@tonic-gate 
8817c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 	/*
8847c478bd9Sstevel@tonic-gate 	 * scan /dev/dsk for cd devices
8857c478bd9Sstevel@tonic-gate 	 */
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/dsk")) == NULL) {
8887c478bd9Sstevel@tonic-gate 		perror("gettext(open /dev/dsk failure)");
8897c478bd9Sstevel@tonic-gate 		exit(1);
8907c478bd9Sstevel@tonic-gate 	}
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
8937c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
8947c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
8957c478bd9Sstevel@tonic-gate 			continue;
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate 		/* get device # (disk #) */
8987c478bd9Sstevel@tonic-gate 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0)
8997c478bd9Sstevel@tonic-gate 			continue;
9007c478bd9Sstevel@tonic-gate 
9017c478bd9Sstevel@tonic-gate 		/* see if this is one of the cd special devices */
902*45916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
9037c478bd9Sstevel@tonic-gate 			if (cd[j].number == id && cd[j].controller == ctrl)
9047c478bd9Sstevel@tonic-gate 				goto found;
9057c478bd9Sstevel@tonic-gate 		}
9067c478bd9Sstevel@tonic-gate 		continue;
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate 		/* add new entry to table (/dev/dsk + / + d_name + \0) */
9097c478bd9Sstevel@tonic-gate found:
9107c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
9117c478bd9Sstevel@tonic-gate 		if (i == ncd) {
9127c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
9137c478bd9Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
9147c478bd9Sstevel@tonic-gate 		}
9157c478bd9Sstevel@tonic-gate 
9167c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
9177c478bd9Sstevel@tonic-gate 		if (nm == NULL)
9187c478bd9Sstevel@tonic-gate 			no_memory();
9197c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/dsk/");
9207c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
9217c478bd9Sstevel@tonic-gate 		cd[i].name = nm;
9227c478bd9Sstevel@tonic-gate 
9237c478bd9Sstevel@tonic-gate 		cd[i].id = cd[j].id;
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 		cd[i].device = "";
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate 		cd[i].number = id;
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 		i++;
9307c478bd9Sstevel@tonic-gate 	}
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate 	/*
9357c478bd9Sstevel@tonic-gate 	 * scan /dev/rdsk for cd devices
9367c478bd9Sstevel@tonic-gate 	 */
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/rdsk")) == NULL) {
9397c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev/dsk failure"));
9407c478bd9Sstevel@tonic-gate 		exit(1);
9417c478bd9Sstevel@tonic-gate 	}
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
9447c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
9457c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
9467c478bd9Sstevel@tonic-gate 			continue;
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate 		/* get device # (disk #) */
9497c478bd9Sstevel@tonic-gate 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
9507c478bd9Sstevel@tonic-gate 			continue;
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate 		/* see if this is one of the cd special devices */
953*45916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
9547c478bd9Sstevel@tonic-gate 			if (cd[j].number == id && cd[j].controller == ctrl)
9557c478bd9Sstevel@tonic-gate 				goto found1;
9567c478bd9Sstevel@tonic-gate 		}
9577c478bd9Sstevel@tonic-gate 		continue;
9587c478bd9Sstevel@tonic-gate 
9597c478bd9Sstevel@tonic-gate 		/* add new entry to table (/dev/rdsk + / + d_name + \0) */
9607c478bd9Sstevel@tonic-gate found1:
9617c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
9627c478bd9Sstevel@tonic-gate 		if (i == ncd) {
9637c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
9647c478bd9Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
9657c478bd9Sstevel@tonic-gate 		}
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1);
9687c478bd9Sstevel@tonic-gate 		if (nm == NULL)
9697c478bd9Sstevel@tonic-gate 			no_memory();
9707c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/rdsk/");
9717c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
9727c478bd9Sstevel@tonic-gate 		cd[i].name = nm;
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 		cd[i].id = cd[j].id;
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 		cd[i].device = "";
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 		cd[i].number = id;
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 		cd[i].controller = ctrl;
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate 		i++;
9837c478bd9Sstevel@tonic-gate 	}
9847c478bd9Sstevel@tonic-gate 
9857c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
9867c478bd9Sstevel@tonic-gate 
987*45916cd2Sjpk 	cd_count = i;
9887c478bd9Sstevel@tonic-gate 
989*45916cd2Sjpk 	if (system_labeled) {
990*45916cd2Sjpk 		dname = DA_CD_NAME;
991*45916cd2Sjpk 		dclean = DA_DEFAULT_DISK_CLEAN;
992*45916cd2Sjpk 	} else {
993*45916cd2Sjpk 		dname = "sr";
994*45916cd2Sjpk 		dclean = CD_CLEAN;
995*45916cd2Sjpk 	}
9967c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
997*45916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
998*45916cd2Sjpk 			if (cd[j].id != i)
999*45916cd2Sjpk 				continue;
1000*45916cd2Sjpk 			if (do_files) {
1001*45916cd2Sjpk 				(void) da_add_list(&devlist, cd[j].name, i,
1002*45916cd2Sjpk 				    DA_CD);
1003*45916cd2Sjpk 			} else if (do_devalloc) {
1004*45916cd2Sjpk 				/* print device_allocate for cd devices */
1005*45916cd2Sjpk 				if (system_labeled) {
1006*45916cd2Sjpk 					(void) printf("%s%d%s\\\n",
1007*45916cd2Sjpk 					    dname, i, KV_DELIMITER);
1008*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
1009*45916cd2Sjpk 					    DA_CD_TYPE, KV_DELIMITER);
1010*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
1011*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
1012*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
1013*45916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
1014*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
1015*45916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
1016*45916cd2Sjpk 					    KV_DELIMITER);
1017*45916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
1018*45916cd2Sjpk 				} else {
10197c478bd9Sstevel@tonic-gate 					(void) printf(
10207c478bd9Sstevel@tonic-gate 					    "sr%d;sr;reserved;reserved;%s;",
10217c478bd9Sstevel@tonic-gate 					    i, DEFAULT_DEV_ALLOC_AUTH);
1022*45916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
1023*45916cd2Sjpk 					    "/sr_clean");
1024*45916cd2Sjpk 				}
1025*45916cd2Sjpk 				break;
1026*45916cd2Sjpk 			} else if (do_devmaps) {
1027*45916cd2Sjpk 				/* print device_maps for cd devices */
1028*45916cd2Sjpk 				if (first) {
1029*45916cd2Sjpk 					(void) printf(" ");
1030*45916cd2Sjpk 				} else {
1031*45916cd2Sjpk 					if (system_labeled) {
1032*45916cd2Sjpk 						(void) printf("%s%d%s\\\n",
1033*45916cd2Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
1034*45916cd2Sjpk 						(void) printf("\t%s%s\\\n",
1035*45916cd2Sjpk 						    DA_CD_TYPE,
1036*45916cd2Sjpk 						    KV_TOKEN_DELIMIT);
1037*45916cd2Sjpk 						(void) printf("\t");
1038*45916cd2Sjpk 					} else {
1039*45916cd2Sjpk 						(void) printf("sr%d:\\\n", i);
1040*45916cd2Sjpk 						(void) printf("\tsr:\\\n");
1041*45916cd2Sjpk 						(void) printf("\t");
1042*45916cd2Sjpk 					}
1043*45916cd2Sjpk 					first++;
1044*45916cd2Sjpk 				}
1045*45916cd2Sjpk 				(void) printf("%s", cd[j].name);
1046*45916cd2Sjpk 			}
1047*45916cd2Sjpk 		}
1048*45916cd2Sjpk 		if (do_devmaps && first) {
1049*45916cd2Sjpk 			(void) printf("\n\n");
1050*45916cd2Sjpk 			first = 0;
1051*45916cd2Sjpk 		}
1052*45916cd2Sjpk 	}
1053*45916cd2Sjpk 	if (do_files && cd_count) {
1054*45916cd2Sjpk 		dargs.rootdir = NULL;
1055*45916cd2Sjpk 		dargs.devnames = NULL;
1056*45916cd2Sjpk 		dargs.optflag = DA_ADD;
1057*45916cd2Sjpk 		for (entry = devlist.cd; entry != NULL; entry = entry->next) {
1058*45916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
1059*45916cd2Sjpk 			(void) da_update_device(&dargs);
1060*45916cd2Sjpk 		}
1061*45916cd2Sjpk 	}
1062*45916cd2Sjpk 
1063*45916cd2Sjpk 	return (cd_count);
1064*45916cd2Sjpk }
1065*45916cd2Sjpk 
1066*45916cd2Sjpk static void
1067*45916cd2Sjpk dormdisk(int cd_count)
1068*45916cd2Sjpk {
1069*45916cd2Sjpk 	DIR *dirp;
1070*45916cd2Sjpk 	struct dirent *dep;	/* directory entry pointer */
1071*45916cd2Sjpk 	int	i, j;
1072*45916cd2Sjpk 	char	*nm;		/* name/device of special device */
1073*45916cd2Sjpk 	int	id;		/* disk id */
1074*45916cd2Sjpk 	int	ctrl;		/* disk controller */
1075*45916cd2Sjpk 	int	nrmdisk;	/* max array size */
1076*45916cd2Sjpk 	int	fd = -1;
1077*45916cd2Sjpk 	int	rmdisk_count;
1078*45916cd2Sjpk 	int	first = 0;
1079*45916cd2Sjpk 	int	is_cd;
1080*45916cd2Sjpk 	int	checked;
1081*45916cd2Sjpk 	int	removable;
1082*45916cd2Sjpk 	char	path[MAXPATHLEN];
1083*45916cd2Sjpk 	da_args	dargs;
1084*45916cd2Sjpk 	deventry_t *entry;
1085*45916cd2Sjpk 
1086*45916cd2Sjpk 	nrmdisk = DFLT_RMDISK;
1087*45916cd2Sjpk 	i = rmdisk_count = 0;
1088*45916cd2Sjpk 
1089*45916cd2Sjpk 	/*
1090*45916cd2Sjpk 	 * scan /dev/dsk for rmdisk devices
1091*45916cd2Sjpk 	 */
1092*45916cd2Sjpk 	if ((dirp = opendir("/dev/dsk")) == NULL) {
1093*45916cd2Sjpk 		perror("gettext(open /dev/dsk failure)");
1094*45916cd2Sjpk 		exit(1);
1095*45916cd2Sjpk 	}
1096*45916cd2Sjpk 
1097*45916cd2Sjpk 	while (dep = readdir(dirp)) {
1098*45916cd2Sjpk 		is_cd = 0;
1099*45916cd2Sjpk 		checked = 0;
1100*45916cd2Sjpk 		removable = 0;
1101*45916cd2Sjpk 		/* skip . .. etc... */
1102*45916cd2Sjpk 		if (strncmp(dep->d_name, ".", 1) == NULL)
1103*45916cd2Sjpk 			continue;
1104*45916cd2Sjpk 
1105*45916cd2Sjpk 		/* get device # (disk #) */
1106*45916cd2Sjpk 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0)
1107*45916cd2Sjpk 			continue;
1108*45916cd2Sjpk 
1109*45916cd2Sjpk 		/* see if we've already examined this device */
1110*45916cd2Sjpk 		for (j = 0; j < i; j++) {
1111*45916cd2Sjpk 			if (id == rmdisk[j].id &&
1112*45916cd2Sjpk 			    ctrl == rmdisk[j].controller &&
1113*45916cd2Sjpk 			    (strcmp(dep->d_name, rmdisk[j].name) == 0)) {
1114*45916cd2Sjpk 				checked = 1;
11157c478bd9Sstevel@tonic-gate 				break;
11167c478bd9Sstevel@tonic-gate 			}
1117*45916cd2Sjpk 			if (id == rmdisk[j].id && ctrl != rmdisk[j].controller)
1118*45916cd2Sjpk 				/*
1119*45916cd2Sjpk 				 * c2t0d0s0 is a different rmdisk than c3t0d0s0.
1120*45916cd2Sjpk 				 */
1121*45916cd2Sjpk 				id = rmdisk[j].id + 1;
1122*45916cd2Sjpk 		}
1123*45916cd2Sjpk 		if (checked)
1124*45916cd2Sjpk 			continue;
1125*45916cd2Sjpk 
1126*45916cd2Sjpk 		/* ignore if this is a cd */
1127*45916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
1128*45916cd2Sjpk 			if (id == cd[j].number && ctrl == cd[j].controller) {
1129*45916cd2Sjpk 				is_cd = 1;
1130*45916cd2Sjpk 				break;
1131*45916cd2Sjpk 			}
1132*45916cd2Sjpk 		}
1133*45916cd2Sjpk 		if (is_cd)
1134*45916cd2Sjpk 			continue;
1135*45916cd2Sjpk 
1136*45916cd2Sjpk 		/* see if device is removable */
1137*45916cd2Sjpk 		(void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/",
1138*45916cd2Sjpk 		    dep->d_name);
1139*45916cd2Sjpk 		if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
1140*45916cd2Sjpk 			continue;
1141*45916cd2Sjpk 		(void) ioctl(fd, DKIOCREMOVABLE, &removable);
1142*45916cd2Sjpk 		(void) close(fd);
1143*45916cd2Sjpk 		if (removable == 0)
1144*45916cd2Sjpk 			continue;
1145*45916cd2Sjpk 
1146*45916cd2Sjpk 		/*
1147*45916cd2Sjpk 		 * add new entry to table (/dev/dsk + / + d_name + \0)
1148*45916cd2Sjpk 		 * if array full, then expand it
1149*45916cd2Sjpk 		 */
1150*45916cd2Sjpk 		if (i == nrmdisk) {
1151*45916cd2Sjpk 			/* will exit(1) if insufficient memory */
1152*45916cd2Sjpk 			nrmdisk = expandmem(i, (void **)&rmdisk,
1153*45916cd2Sjpk 			    sizeof (struct rmdisk));
1154*45916cd2Sjpk 		}
1155*45916cd2Sjpk 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
1156*45916cd2Sjpk 		if (nm == NULL)
1157*45916cd2Sjpk 			no_memory();
1158*45916cd2Sjpk 		(void) strcpy(nm, "/dev/dsk/");
1159*45916cd2Sjpk 		(void) strcat(nm, dep->d_name);
1160*45916cd2Sjpk 		rmdisk[i].name = nm;
1161*45916cd2Sjpk 		rmdisk[i].id = id;
1162*45916cd2Sjpk 		rmdisk[i].controller = ctrl;
1163*45916cd2Sjpk 		rmdisk[i].device = "";
1164*45916cd2Sjpk 		rmdisk[i].number = id;
1165*45916cd2Sjpk 		rmdisk_r[i].name = strdup(path);
1166*45916cd2Sjpk 		i++;
1167*45916cd2Sjpk 	}
1168*45916cd2Sjpk 
1169*45916cd2Sjpk 	rmdisk_count = i;
1170*45916cd2Sjpk 	(void) closedir(dirp);
1171*45916cd2Sjpk 
1172*45916cd2Sjpk 	for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) {
1173*45916cd2Sjpk 		if (j == nrmdisk) {
1174*45916cd2Sjpk 			/* will exit(1) if insufficient memory */
1175*45916cd2Sjpk 			nrmdisk = expandmem(j, (void **)&rmdisk,
1176*45916cd2Sjpk 			    sizeof (struct rmdisk));
1177*45916cd2Sjpk 		}
1178*45916cd2Sjpk 		rmdisk[j].name = rmdisk_r[i].name;
1179*45916cd2Sjpk 		rmdisk[j].id = rmdisk[i].id;
1180*45916cd2Sjpk 		rmdisk[j].controller = rmdisk[i].controller;
1181*45916cd2Sjpk 		rmdisk[j].device = rmdisk[i].device;
1182*45916cd2Sjpk 		rmdisk[j].number = rmdisk[i].number;
1183*45916cd2Sjpk 	}
1184*45916cd2Sjpk 	rmdisk_count = j;
1185*45916cd2Sjpk 
1186*45916cd2Sjpk 	for (i = 0; i < 8; i++) {
1187*45916cd2Sjpk 		for (j = 0; j < rmdisk_count; j++) {
1188*45916cd2Sjpk 			if (rmdisk[j].id != i)
1189*45916cd2Sjpk 				continue;
1190*45916cd2Sjpk 			if (do_files) {
1191*45916cd2Sjpk 				(void) da_add_list(&devlist, rmdisk[j].name, i,
1192*45916cd2Sjpk 				    DA_RMDISK);
1193*45916cd2Sjpk 			} else if (do_devalloc) {
1194*45916cd2Sjpk 				/* print device_allocate for rmdisk devices */
1195*45916cd2Sjpk 				(void) printf("%s%d%s\\\n",
1196*45916cd2Sjpk 				    DA_RMDISK_NAME, i, KV_DELIMITER);
1197*45916cd2Sjpk 				(void) printf("\t%s%s\\\n",
1198*45916cd2Sjpk 				    DA_RMDISK_TYPE, KV_DELIMITER);
1199*45916cd2Sjpk 				(void) printf("\t%s%s\\\n",
1200*45916cd2Sjpk 				    DA_RESERVED, KV_DELIMITER);
1201*45916cd2Sjpk 				(void) printf("\t%s%s\\\n",
1202*45916cd2Sjpk 				    DA_RESERVED, KV_DELIMITER);
1203*45916cd2Sjpk 				(void) printf("\t%s%s\\\n",
1204*45916cd2Sjpk 				    DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER);
1205*45916cd2Sjpk 				(void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN);
1206*45916cd2Sjpk 				break;
1207*45916cd2Sjpk 			} else if (do_devmaps) {
1208*45916cd2Sjpk 				/* print device_maps for rmdisk devices */
1209*45916cd2Sjpk 				if (first) {
1210*45916cd2Sjpk 					(void) printf(" ");
1211*45916cd2Sjpk 				} else {
1212*45916cd2Sjpk 					(void) printf("%s%d%s\\\n",
1213*45916cd2Sjpk 					    DA_RMDISK_NAME, i,
1214*45916cd2Sjpk 					    KV_TOKEN_DELIMIT);
1215*45916cd2Sjpk 					(void) printf("\t%s%s\\\n",
1216*45916cd2Sjpk 					    DA_RMDISK_TYPE, KV_TOKEN_DELIMIT);
1217*45916cd2Sjpk 					(void) printf("\t");
1218*45916cd2Sjpk 					first++;
1219*45916cd2Sjpk 				}
1220*45916cd2Sjpk 				(void) printf("%s", rmdisk[j].name);
1221*45916cd2Sjpk 			}
1222*45916cd2Sjpk 		}
1223*45916cd2Sjpk 		if (do_devmaps && first) {
1224*45916cd2Sjpk 			(void) printf("\n\n");
1225*45916cd2Sjpk 			first = 0;
1226*45916cd2Sjpk 		}
1227*45916cd2Sjpk 	}
1228*45916cd2Sjpk 	if (do_files && rmdisk_count) {
1229*45916cd2Sjpk 		dargs.rootdir = NULL;
1230*45916cd2Sjpk 		dargs.devnames = NULL;
1231*45916cd2Sjpk 		dargs.optflag = DA_ADD;
1232*45916cd2Sjpk 		for (entry = devlist.rmdisk; entry != NULL;
1233*45916cd2Sjpk 		    entry = entry->next) {
1234*45916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
1235*45916cd2Sjpk 			(void) da_update_device(&dargs);
12367c478bd9Sstevel@tonic-gate 		}
12377c478bd9Sstevel@tonic-gate 	}
12387c478bd9Sstevel@tonic-gate }
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate /* set default array sizes */
12417c478bd9Sstevel@tonic-gate static void
12427c478bd9Sstevel@tonic-gate initmem()
12437c478bd9Sstevel@tonic-gate {
12447c478bd9Sstevel@tonic-gate 	tape  = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape));
12457c478bd9Sstevel@tonic-gate 	audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
12467c478bd9Sstevel@tonic-gate 	cd    = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
12477c478bd9Sstevel@tonic-gate 	fp    = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
1248*45916cd2Sjpk 	if (system_labeled) {
1249*45916cd2Sjpk 		rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK,
1250*45916cd2Sjpk 		    sizeof (struct rmdisk));
1251*45916cd2Sjpk 		if (rmdisk == NULL)
1252*45916cd2Sjpk 			no_memory();
1253*45916cd2Sjpk 		rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK,
1254*45916cd2Sjpk 		    sizeof (struct rmdisk));
1255*45916cd2Sjpk 		if (rmdisk_r == NULL)
1256*45916cd2Sjpk 			no_memory();
1257*45916cd2Sjpk 	}
12587c478bd9Sstevel@tonic-gate 
12597c478bd9Sstevel@tonic-gate 	if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
12607c478bd9Sstevel@tonic-gate 		no_memory();
1261*45916cd2Sjpk 
1262*45916cd2Sjpk 	devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk =
1263*45916cd2Sjpk 	    devlist.tape = NULL;
12647c478bd9Sstevel@tonic-gate }
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate /* note n will be # elments in array (and could be 0) */
12677c478bd9Sstevel@tonic-gate static int
12687c478bd9Sstevel@tonic-gate expandmem(int n, void **array, int size)
12697c478bd9Sstevel@tonic-gate {
12707c478bd9Sstevel@tonic-gate 	void *old = *array;
12717c478bd9Sstevel@tonic-gate 	void *new;
12727c478bd9Sstevel@tonic-gate 
12737c478bd9Sstevel@tonic-gate 	/* get new array space (n + DELTA) */
12747c478bd9Sstevel@tonic-gate 	new = (void *)calloc(n + DELTA,  size);
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate 	if (new == NULL) {
12777c478bd9Sstevel@tonic-gate 		perror("memory allocation failed");
12787c478bd9Sstevel@tonic-gate 		exit(1);
12797c478bd9Sstevel@tonic-gate 	}
12807c478bd9Sstevel@tonic-gate 
12817c478bd9Sstevel@tonic-gate 	/* copy old array into new space */
12827c478bd9Sstevel@tonic-gate 	bcopy(old, new, n * size);
12837c478bd9Sstevel@tonic-gate 
12847c478bd9Sstevel@tonic-gate 	/* now release old arrary */
12857c478bd9Sstevel@tonic-gate 	free(old);
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	*array = new;
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 	return (n + DELTA);
12907c478bd9Sstevel@tonic-gate }
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate static void
12937c478bd9Sstevel@tonic-gate no_memory(void)
12947c478bd9Sstevel@tonic-gate {
12957c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
12967c478bd9Sstevel@tonic-gate 	    gettext("out of memory"));
12977c478bd9Sstevel@tonic-gate 	exit(1);
12987c478bd9Sstevel@tonic-gate 	/* NOT REACHED */
12997c478bd9Sstevel@tonic-gate }
1300