xref: /titanic_53/usr/src/cmd/allocate/mkdevalloc.c (revision facf4a8d7b59fde89a8662b4f4c73a758e6c402c)
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
545916cd2Sjpk  * Common Development and Distribution License (the "License").
645916cd2Sjpk  * 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  */
2145916cd2Sjpk 
227c478bd9Sstevel@tonic-gate /*
2345916cd2Sjpk  * 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?
5245916cd2Sjpk  *
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate 
5545916cd2Sjpk #include <errno.h>
5645916cd2Sjpk #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) */
6145916cd2Sjpk #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) */
6645916cd2Sjpk #include <sys/dkio.h>
677c478bd9Sstevel@tonic-gate #include <locale.h>
687c478bd9Sstevel@tonic-gate #include <libintl.h>
6945916cd2Sjpk #include <libdevinfo.h>
7045916cd2Sjpk #include <secdb.h>
717c478bd9Sstevel@tonic-gate #include <auth_attr.h>
727c478bd9Sstevel@tonic-gate #include <auth_list.h>
7345916cd2Sjpk #include <bsm/devices.h>
7445916cd2Sjpk #include <bsm/devalloc.h>
7545916cd2Sjpk #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 
8145916cd2Sjpk #define	MKDEVALLOC	"mkdevalloc"
8245916cd2Sjpk #define	MKDEVMAPS	"mkdevmaps"
8345916cd2Sjpk 
847c478bd9Sstevel@tonic-gate #define	DELTA	5	/* array size delta when full */
8545916cd2Sjpk #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| */
9845916cd2Sjpk #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| */
10845916cd2Sjpk #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| */
12345916cd2Sjpk #define	CD_CLEAN    SECLIB"/sr_clean"
1247c478bd9Sstevel@tonic-gate 
12545916cd2Sjpk /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
12645916cd2Sjpk struct rmdisk {
12745916cd2Sjpk 	char	*name;
12845916cd2Sjpk 	char	*device;
12945916cd2Sjpk 	int	id;
13045916cd2Sjpk 	int	controller;
13145916cd2Sjpk 	int	number;
13245916cd2Sjpk } *rmdisk, *rmdisk_r;
13345916cd2Sjpk #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| */
14445916cd2Sjpk #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();
14945916cd2Sjpk static int docd();
15045916cd2Sjpk 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 
15545916cd2Sjpk int		system_labeled = 0;
15645916cd2Sjpk int		do_devalloc = 0;
15745916cd2Sjpk int		do_devmaps = 0;
15845916cd2Sjpk int		do_files = 0;
15945916cd2Sjpk devlist_t	devlist;
16045916cd2Sjpk 
1617883e825Spaulson int
16245916cd2Sjpk main(int argc, char **argv)
1637c478bd9Sstevel@tonic-gate {
16445916cd2Sjpk 	int		cd_count = 0;
16545916cd2Sjpk 	char		*progname;
16645916cd2Sjpk 	struct stat	tx_stat;
16745916cd2Sjpk 
1687c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1697c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1707c478bd9Sstevel@tonic-gate 
17145916cd2Sjpk 	if ((progname = strrchr(argv[0], '/')) == NULL)
17245916cd2Sjpk 		progname = argv[0];
17345916cd2Sjpk 	else
17445916cd2Sjpk 		progname++;
17545916cd2Sjpk 	if (strcmp(progname, MKDEVALLOC) == 0)
17645916cd2Sjpk 		do_devalloc = 1;
17745916cd2Sjpk 	else if (strcmp(progname, MKDEVMAPS) == 0)
17845916cd2Sjpk 		do_devmaps = 1;
17945916cd2Sjpk 	else
18045916cd2Sjpk 		exit(1);
18145916cd2Sjpk 
18245916cd2Sjpk 	system_labeled = is_system_labeled();
183*facf4a8dSllai1 
184*facf4a8dSllai1 	/* test hook: see also devfsadm.c and allocate.c */
185*facf4a8dSllai1 	if (!system_labeled) {
186*facf4a8dSllai1 		system_labeled = is_system_labeled_debug(&tx_stat);
187*facf4a8dSllai1 		if (system_labeled) {
188*facf4a8dSllai1 			fprintf(stderr, "/ALLOCATE_FORCE_LABEL is set,\n"
189*facf4a8dSllai1 			    "forcing system label on for testing...\n");
190*facf4a8dSllai1 		}
191*facf4a8dSllai1 	}
192*facf4a8dSllai1 
19345916cd2Sjpk 	if (system_labeled == 0) {
19445916cd2Sjpk 		/*
19545916cd2Sjpk 		 * is_system_labeled() will return false in case we are
19645916cd2Sjpk 		 * starting before the first reboot after Trusted Extensions
19745916cd2Sjpk 		 * is installed. we check for a well known TX binary to
19845916cd2Sjpk 		 * to see if TX is installed.
19945916cd2Sjpk 		 */
20045916cd2Sjpk 		if (stat(DA_LABEL_CHECK, &tx_stat) == 0)
20145916cd2Sjpk 			system_labeled = 1;
20245916cd2Sjpk 	}
20345916cd2Sjpk 
20445916cd2Sjpk 	if (system_labeled && do_devalloc && (argc == 2) &&
20545916cd2Sjpk 	    (strcmp(argv[1], DA_IS_LABELED) == 0)) {
20645916cd2Sjpk 		/*
20745916cd2Sjpk 		 * write device entries to device_allocate and device_maps.
20845916cd2Sjpk 		 * default is to print them on stdout.
20945916cd2Sjpk 		 */
21045916cd2Sjpk 		do_files = 1;
21145916cd2Sjpk 	}
21245916cd2Sjpk 
2137c478bd9Sstevel@tonic-gate 	initmem();		/* initialize memory */
21445916cd2Sjpk 	dotape();
21545916cd2Sjpk 	doaudio();
21645916cd2Sjpk 	dofloppy();
21745916cd2Sjpk 	cd_count = docd();
21845916cd2Sjpk 	if (system_labeled)
21945916cd2Sjpk 		dormdisk(cd_count);
2207883e825Spaulson 
2217883e825Spaulson 	return (0);
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate static void
2257c478bd9Sstevel@tonic-gate dotape()
2267c478bd9Sstevel@tonic-gate {
2277c478bd9Sstevel@tonic-gate 	DIR *dirp;
2287c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
22945916cd2Sjpk 	int	i, j;
2307c478bd9Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
2317c478bd9Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
2327c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
2337c478bd9Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
2347c478bd9Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
2357c478bd9Sstevel@tonic-gate 	int	ntape;		/* max array size */
23645916cd2Sjpk 	int	tape_count;
23745916cd2Sjpk 	int	first = 0;
23845916cd2Sjpk 	char	*dname, *dtype, *dclean;
23945916cd2Sjpk 	da_args	dargs;
24045916cd2Sjpk 	deventry_t *entry;
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	ntape = DFLT_NTAPE;
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 	/*
2457c478bd9Sstevel@tonic-gate 	 * look for rst* and nrst*
2467c478bd9Sstevel@tonic-gate 	 */
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
2497c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
2507c478bd9Sstevel@tonic-gate 		exit(1);
2517c478bd9Sstevel@tonic-gate 	}
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	i = 0;
2547c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
2557c478bd9Sstevel@tonic-gate 		/* ignore if neither rst* nor nrst* */
2567c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, "rst", SIZE_OF_RST) &&
2577c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "nrst", SIZE_OF_NRST))
2587c478bd9Sstevel@tonic-gate 			continue;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
2617c478bd9Sstevel@tonic-gate 		if (i == ntape) {
2627c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
2637c478bd9Sstevel@tonic-gate 			ntape = expandmem(i, (void **)&tape,
2647c478bd9Sstevel@tonic-gate 					sizeof (struct tape));
2657c478bd9Sstevel@tonic-gate 		}
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 		/* save name (/dev + / + d_name + \0) */
2687c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
2697c478bd9Sstevel@tonic-gate 		if (nm == NULL)
2707c478bd9Sstevel@tonic-gate 			no_memory();
2717c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
2727c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
2737c478bd9Sstevel@tonic-gate 		tape[i].name = nm;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
2767c478bd9Sstevel@tonic-gate 		if (lstat(tape[i].name, &stat) < 0) {
2777c478bd9Sstevel@tonic-gate 			perror("stat(2) failed ");
2787c478bd9Sstevel@tonic-gate 			exit(1);
2797c478bd9Sstevel@tonic-gate 		}
2807c478bd9Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
2817c478bd9Sstevel@tonic-gate 			continue;
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
2847c478bd9Sstevel@tonic-gate 		if ((sz = readlink(tape[i].name, linkvalue,
2857c478bd9Sstevel@tonic-gate 				sizeof (linkvalue))) < 0)
2867c478bd9Sstevel@tonic-gate 			continue;
2877c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
2887c478bd9Sstevel@tonic-gate 		if (nm == NULL)
2897c478bd9Sstevel@tonic-gate 			no_memory();
2907c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
2917c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
2927c478bd9Sstevel@tonic-gate 		tape[i].device = nm;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 		/* get device number */
2957c478bd9Sstevel@tonic-gate 		cp = strrchr(tape[i].device, '/');
2967c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
2977c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &tape[i].number);
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 		i++;
3007c478bd9Sstevel@tonic-gate 	}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	/*
3057c478bd9Sstevel@tonic-gate 	 * scan /dev/rmt and add entry to table
3067c478bd9Sstevel@tonic-gate 	 */
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/rmt")) == NULL) {
3097c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
3107c478bd9Sstevel@tonic-gate 		exit(1);
3117c478bd9Sstevel@tonic-gate 	}
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
3147c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
3157c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
3167c478bd9Sstevel@tonic-gate 			continue;
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
3197c478bd9Sstevel@tonic-gate 		if (i == ntape) {
3207c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
3217c478bd9Sstevel@tonic-gate 			ntape = expandmem(i, (void **)&tape,
3227c478bd9Sstevel@tonic-gate 					sizeof (struct tape));
3237c478bd9Sstevel@tonic-gate 		}
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 		/* save name (/dev/rmt + / + d_name + \0) */
3267c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1);
3277c478bd9Sstevel@tonic-gate 		if (nm == NULL)
3287c478bd9Sstevel@tonic-gate 			no_memory();
3297c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/rmt/");
3307c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
3317c478bd9Sstevel@tonic-gate 		tape[i].name = nm;
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 		/* save device name (rmt/ + d_name + \0) */
3347c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
3357c478bd9Sstevel@tonic-gate 		if (nm == NULL)
3367c478bd9Sstevel@tonic-gate 			no_memory();
3377c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "rmt/");
3387c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
3397c478bd9Sstevel@tonic-gate 		tape[i].device = nm;
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 		(void) sscanf(dep->d_name, "%d", &tape[i].number);
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate 		i++;
3447c478bd9Sstevel@tonic-gate 	}
34545916cd2Sjpk 	tape_count = i;
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 	/* remove duplicate entries */
35045916cd2Sjpk 	for (i = 0; i < tape_count - 1; i++) {
35145916cd2Sjpk 		for (j = i + 1; j < tape_count; j++) {
3527c478bd9Sstevel@tonic-gate 			if (strcmp(tape[i].device, tape[j].device))
3537c478bd9Sstevel@tonic-gate 				continue;
3547c478bd9Sstevel@tonic-gate 			tape[j].number = -1;
3557c478bd9Sstevel@tonic-gate 		}
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 
35845916cd2Sjpk 	if (system_labeled) {
35945916cd2Sjpk 		dname = DA_TAPE_NAME;
36045916cd2Sjpk 		dtype = DA_TAPE_TYPE;
36145916cd2Sjpk 		dclean = DA_DEFAULT_TAPE_CLEAN;
36245916cd2Sjpk 	} else {
36345916cd2Sjpk 		dname = "st";
36445916cd2Sjpk 		dtype = "st";
36545916cd2Sjpk 		dclean = TAPE_CLEAN;
36645916cd2Sjpk 	}
3677c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
36845916cd2Sjpk 		for (j = 0; j < tape_count; j++) {
36945916cd2Sjpk 			if (tape[j].number != i)
37045916cd2Sjpk 				continue;
37145916cd2Sjpk 			if (do_files) {
37245916cd2Sjpk 				(void) da_add_list(&devlist, tape[j].name, i,
37345916cd2Sjpk 				    DA_TAPE);
37445916cd2Sjpk 			} else if (do_devalloc) {
37545916cd2Sjpk 				/* print device_allocate for tape devices */
37645916cd2Sjpk 				if (system_labeled) {
37745916cd2Sjpk 					(void) printf("%s%d%s\\\n",
37845916cd2Sjpk 					    dname, i, KV_DELIMITER);
37945916cd2Sjpk 					(void) printf("\t%s%s\\\n",
38045916cd2Sjpk 					    DA_TAPE_TYPE, KV_DELIMITER);
38145916cd2Sjpk 					(void) printf("\t%s%s\\\n",
38245916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
38345916cd2Sjpk 					(void) printf("\t%s%s\\\n",
38445916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
38545916cd2Sjpk 					(void) printf("\t%s%s\\\n",
38645916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
38745916cd2Sjpk 					    KV_DELIMITER);
38845916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
38945916cd2Sjpk 				} else {
3907c478bd9Sstevel@tonic-gate 					(void) printf(
3917c478bd9Sstevel@tonic-gate 					    "st%d;st;reserved;reserved;%s;",
3927c478bd9Sstevel@tonic-gate 					    i, DEFAULT_DEV_ALLOC_AUTH);
39345916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
39445916cd2Sjpk 					    "/st_clean");
3957c478bd9Sstevel@tonic-gate 				}
39645916cd2Sjpk 				break;
39745916cd2Sjpk 			} else if (do_devmaps) {
39845916cd2Sjpk 				/* print device_maps for tape devices */
39945916cd2Sjpk 				if (first) {
40045916cd2Sjpk 					(void) printf(" ");
40145916cd2Sjpk 				} else {
40245916cd2Sjpk 					if (system_labeled) {
40345916cd2Sjpk 						(void) printf("%s%d%s\\\n",
40445916cd2Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
40545916cd2Sjpk 						(void) printf("\t%s%s\\\n",
40645916cd2Sjpk 						    dtype, KV_TOKEN_DELIMIT);
40745916cd2Sjpk 						(void) printf("\t");
40845916cd2Sjpk 					} else {
40945916cd2Sjpk 						(void) printf("st%d:\\\n", i);
41045916cd2Sjpk 						(void) printf("\trmt:\\\n");
41145916cd2Sjpk 						(void) printf("\t");
41245916cd2Sjpk 					}
41345916cd2Sjpk 						first++;
41445916cd2Sjpk 				}
41545916cd2Sjpk 				(void) printf("%s", tape[j].name);
41645916cd2Sjpk 			}
41745916cd2Sjpk 		}
41845916cd2Sjpk 		if (do_devmaps && first) {
41945916cd2Sjpk 			(void) printf("\n\n");
42045916cd2Sjpk 			first = 0;
42145916cd2Sjpk 		}
42245916cd2Sjpk 	}
42345916cd2Sjpk 	if (do_files && tape_count) {
42445916cd2Sjpk 		dargs.rootdir = NULL;
42545916cd2Sjpk 		dargs.devnames = NULL;
42645916cd2Sjpk 		dargs.optflag = DA_ADD;
42745916cd2Sjpk 		for (entry = devlist.tape; entry != NULL; entry = entry->next) {
42845916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
42945916cd2Sjpk 			(void) da_update_device(&dargs);
4307c478bd9Sstevel@tonic-gate 		}
4317c478bd9Sstevel@tonic-gate 	}
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate static void
4357c478bd9Sstevel@tonic-gate doaudio()
4367c478bd9Sstevel@tonic-gate {
4377c478bd9Sstevel@tonic-gate 	DIR *dirp;
4387c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
43945916cd2Sjpk 	int	i, j;
4407c478bd9Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
4417c478bd9Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
4427c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
4437c478bd9Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
4447c478bd9Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
4457c478bd9Sstevel@tonic-gate 	int	naudio;		/* max array size */
44645916cd2Sjpk 	int	audio_count = 0;
44745916cd2Sjpk 	int	len, slen;
44845916cd2Sjpk 	int	first = 0;
44945916cd2Sjpk 	char	dname[128];
45045916cd2Sjpk 	char	*dclean;
45145916cd2Sjpk 	da_args	dargs;
45245916cd2Sjpk 	deventry_t *entry;
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 	naudio = DFLT_NAUDIO;
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
4577c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
4587c478bd9Sstevel@tonic-gate 		exit(1);
4597c478bd9Sstevel@tonic-gate 	}
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	i = 0;
4627c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
4637c478bd9Sstevel@tonic-gate 		if (strcmp(dep->d_name, "audio") &&
4647c478bd9Sstevel@tonic-gate 		    strcmp(dep->d_name, "audioctl"))
4657c478bd9Sstevel@tonic-gate 			continue;
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
4687c478bd9Sstevel@tonic-gate 		if (i == naudio) {
4697c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
4707c478bd9Sstevel@tonic-gate 			naudio = expandmem(i, (void **)&audio,
4717c478bd9Sstevel@tonic-gate 					sizeof (struct audio));
4727c478bd9Sstevel@tonic-gate 		}
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 		/* save name (/dev + 1 + d_name + \0) */
4757c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
4767c478bd9Sstevel@tonic-gate 		if (nm == NULL)
4777c478bd9Sstevel@tonic-gate 			no_memory();
4787c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
4797c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
4807c478bd9Sstevel@tonic-gate 		audio[i].name = nm;
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
4837c478bd9Sstevel@tonic-gate 		if (lstat(audio[i].name, &stat) < 0) {
4847c478bd9Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
4857c478bd9Sstevel@tonic-gate 			exit(1);
4867c478bd9Sstevel@tonic-gate 		}
4877c478bd9Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
4887c478bd9Sstevel@tonic-gate 			continue;
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
4917c478bd9Sstevel@tonic-gate 		if ((sz = readlink(audio[i].name, linkvalue,
4927c478bd9Sstevel@tonic-gate 				sizeof (linkvalue))) < 0)
4937c478bd9Sstevel@tonic-gate 			continue;
4947c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
4957c478bd9Sstevel@tonic-gate 		if (nm == NULL)
4967c478bd9Sstevel@tonic-gate 			no_memory();
4977c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
4987c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
4997c478bd9Sstevel@tonic-gate 		audio[i].device = nm;
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate 		cp = strrchr(audio[i].device, '/');
5027c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
5037c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &audio[i].number);
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 		i++;
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/sound")) == NULL) {
5117c478bd9Sstevel@tonic-gate 		goto skip;
5127c478bd9Sstevel@tonic-gate 	}
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
5157c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
5167c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
5177c478bd9Sstevel@tonic-gate 			continue;
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
5207c478bd9Sstevel@tonic-gate 		if (i == naudio) {
5217c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
5227c478bd9Sstevel@tonic-gate 			naudio = expandmem(i, (void **)&audio,
5237c478bd9Sstevel@tonic-gate 					sizeof (struct audio));
5247c478bd9Sstevel@tonic-gate 		}
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 		/* save name (/dev/sound + / + d_name + \0) */
5277c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
5287c478bd9Sstevel@tonic-gate 		    strlen(dep->d_name) + 1);
5297c478bd9Sstevel@tonic-gate 		if (nm == NULL)
5307c478bd9Sstevel@tonic-gate 			no_memory();
5317c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/sound/");
5327c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
5337c478bd9Sstevel@tonic-gate 		audio[i].name = nm;
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
5367c478bd9Sstevel@tonic-gate 		    strlen(dep->d_name) + 1);
5377c478bd9Sstevel@tonic-gate 		if (nm == NULL)
5387c478bd9Sstevel@tonic-gate 			no_memory();
5397c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/sound/");
5407c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
5417c478bd9Sstevel@tonic-gate 		audio[i].device = nm;
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 		(void) sscanf(dep->d_name, "%d", &audio[i].number);
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 		i++;
5467c478bd9Sstevel@tonic-gate 	}
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate skip:
55145916cd2Sjpk 	audio_count = i;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	/* remove duplicate entries */
55445916cd2Sjpk 	for (i = 0; i < audio_count - 1; i++) {
55545916cd2Sjpk 		for (j = i + 1; j < audio_count; j++) {
5567c478bd9Sstevel@tonic-gate 			if (strcmp(audio[i].device, audio[j].device))
5577c478bd9Sstevel@tonic-gate 				continue;
5587c478bd9Sstevel@tonic-gate 			audio[j].number = -1;
5597c478bd9Sstevel@tonic-gate 		}
5607c478bd9Sstevel@tonic-gate 	}
5617c478bd9Sstevel@tonic-gate 
56245916cd2Sjpk 	/* print out device_allocate entries for audio devices */
56345916cd2Sjpk 	(void) strcpy(dname, DA_AUDIO_NAME);
56445916cd2Sjpk 	slen = strlen(DA_AUDIO_NAME);
56545916cd2Sjpk 	len = sizeof (dname) - slen;
56645916cd2Sjpk 	dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN;
5677c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
56845916cd2Sjpk 		for (j = 0; j < audio_count; j++) {
56945916cd2Sjpk 			if (audio[j].number != i)
57045916cd2Sjpk 				continue;
57145916cd2Sjpk 			if (system_labeled)
57245916cd2Sjpk 				(void) snprintf(dname+slen, len, "%d", i);
57345916cd2Sjpk 			if (do_files) {
57445916cd2Sjpk 				(void) da_add_list(&devlist, audio[j].name,
57545916cd2Sjpk 				    i, DA_AUDIO);
57645916cd2Sjpk 			} else if (do_devalloc) {
57745916cd2Sjpk 				/* print device_allocate for audio devices */
57845916cd2Sjpk 				if (system_labeled) {
57945916cd2Sjpk 					(void) printf("%s%s\\\n",
58045916cd2Sjpk 					    dname, KV_DELIMITER);
58145916cd2Sjpk 					(void) printf("\t%s%s\\\n",
58245916cd2Sjpk 					    DA_AUDIO_TYPE, KV_DELIMITER);
58345916cd2Sjpk 					(void) printf("\t%s%s\\\n",
58445916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
58545916cd2Sjpk 					(void) printf("\t%s%s\\\n",
58645916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
58745916cd2Sjpk 					(void) printf("\t%s%s\\\n",
58845916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
58945916cd2Sjpk 					    KV_DELIMITER);
59045916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
59145916cd2Sjpk 				} else {
5927c478bd9Sstevel@tonic-gate 					(void) printf("audio;audio;");
5937c478bd9Sstevel@tonic-gate 					(void) printf("reserved;reserved;%s;",
5947c478bd9Sstevel@tonic-gate 					    DEFAULT_DEV_ALLOC_AUTH);
59545916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
59645916cd2Sjpk 					    "/audio_clean");
5977c478bd9Sstevel@tonic-gate 				}
59845916cd2Sjpk 				break;
59945916cd2Sjpk 			} else if (do_devmaps) {
60045916cd2Sjpk 				/* print device_maps for audio devices */
60145916cd2Sjpk 				if (first) {
60245916cd2Sjpk 					(void) printf(" ");
60345916cd2Sjpk 				} else {
60445916cd2Sjpk 					if (system_labeled) {
60545916cd2Sjpk 						(void) printf("%s%s\\\n",
60645916cd2Sjpk 						    dname, KV_TOKEN_DELIMIT);
60745916cd2Sjpk 						(void) printf("\t%s%s\\\n",
60845916cd2Sjpk 						    DA_AUDIO_TYPE,
60945916cd2Sjpk 						    KV_TOKEN_DELIMIT);
61045916cd2Sjpk 						(void) printf("\t");
61145916cd2Sjpk 					} else {
61245916cd2Sjpk 						(void) printf("audio:\\\n");
61345916cd2Sjpk 						(void) printf("\taudio:\\\n");
61445916cd2Sjpk 						(void) printf("\t");
61545916cd2Sjpk 					}
61645916cd2Sjpk 					first++;
61745916cd2Sjpk 				}
61845916cd2Sjpk 				(void) printf("%s", audio[j].name);
61945916cd2Sjpk 			}
62045916cd2Sjpk 		}
62145916cd2Sjpk 		if (do_devmaps && first) {
62245916cd2Sjpk 			(void) printf("\n\n");
62345916cd2Sjpk 			first = 0;
62445916cd2Sjpk 		}
62545916cd2Sjpk 	}
62645916cd2Sjpk 	if (do_files && audio_count) {
62745916cd2Sjpk 		dargs.rootdir = NULL;
62845916cd2Sjpk 		dargs.devnames = NULL;
62945916cd2Sjpk 		dargs.optflag = DA_ADD;
63045916cd2Sjpk 		for (entry = devlist.audio; entry != NULL;
63145916cd2Sjpk 		    entry = entry->next) {
63245916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
63345916cd2Sjpk 			(void) da_update_device(&dargs);
6347c478bd9Sstevel@tonic-gate 		}
6357c478bd9Sstevel@tonic-gate 	}
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate static void
6397c478bd9Sstevel@tonic-gate dofloppy()
6407c478bd9Sstevel@tonic-gate {
6417c478bd9Sstevel@tonic-gate 	DIR *dirp;
6427c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
64345916cd2Sjpk 	int i, j;
6447c478bd9Sstevel@tonic-gate 	char *nm;		/* name/device of special device */
6457c478bd9Sstevel@tonic-gate 	char linkvalue[2048];	/* symlink value */
6467c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
6477c478bd9Sstevel@tonic-gate 	int sz;			/* size of symlink value */
6487c478bd9Sstevel@tonic-gate 	char *cp;		/* pointer into string */
6497c478bd9Sstevel@tonic-gate 	int nfp;		/* max array size */
65045916cd2Sjpk 	int floppy_count = 0;
65145916cd2Sjpk 	int first = 0;
65245916cd2Sjpk 	char *dname, *dclean;
65345916cd2Sjpk 	da_args dargs;
65445916cd2Sjpk 	deventry_t *entry;
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 	nfp = DFLT_NFP;
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	/*
6597c478bd9Sstevel@tonic-gate 	 * look for fd* and rfd*
6607c478bd9Sstevel@tonic-gate 	 */
6617c478bd9Sstevel@tonic-gate 
6627c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
6637c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
6647c478bd9Sstevel@tonic-gate 		exit(1);
6657c478bd9Sstevel@tonic-gate 	}
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 	i = 0;
6687c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
6697c478bd9Sstevel@tonic-gate 		/* ignore if neither rst* nor nrst* */
6707c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) &&
6717c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) &&
6727c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "fd1", SIZE_OF_FD0) &&
6737c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0))
6747c478bd9Sstevel@tonic-gate 			continue;
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
6777c478bd9Sstevel@tonic-gate 		if (i == nfp) {
6787c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
6797c478bd9Sstevel@tonic-gate 			nfp = expandmem(i, (void **)&fp, sizeof (struct fp));
6807c478bd9Sstevel@tonic-gate 		}
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate 		/* save name (/dev + 1 + d_name + \0) */
6837c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
6847c478bd9Sstevel@tonic-gate 		if (nm == NULL)
6857c478bd9Sstevel@tonic-gate 			no_memory();
6867c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
6877c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
6887c478bd9Sstevel@tonic-gate 		fp[i].name = nm;
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
6917c478bd9Sstevel@tonic-gate 		if (lstat(fp[i].name, &stat) < 0) {
6927c478bd9Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
6937c478bd9Sstevel@tonic-gate 			exit(1);
6947c478bd9Sstevel@tonic-gate 		}
6957c478bd9Sstevel@tonic-gate 		if ((stat.st_mode&S_IFMT) != S_IFLNK)
6967c478bd9Sstevel@tonic-gate 			continue;
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
6997c478bd9Sstevel@tonic-gate 		if ((sz = readlink(fp[i].name, linkvalue,
7007c478bd9Sstevel@tonic-gate 		    sizeof (linkvalue))) < 0)
7017c478bd9Sstevel@tonic-gate 			continue;
7027c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz+1);
7037c478bd9Sstevel@tonic-gate 		if (nm == NULL)
7047c478bd9Sstevel@tonic-gate 			no_memory();
7057c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
7067c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
7077c478bd9Sstevel@tonic-gate 		fp[i].device = nm;
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate 		/* get device number */
7107c478bd9Sstevel@tonic-gate 		cp = strchr(fp[i].name, 'd');
7117c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
7127c478bd9Sstevel@tonic-gate 		cp = strchr(cp, 'd');
7137c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
7147c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "%d", &fp[i].number);
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 		i++;
7177c478bd9Sstevel@tonic-gate 	}
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
7207c478bd9Sstevel@tonic-gate 
72145916cd2Sjpk 	floppy_count = i;
7227c478bd9Sstevel@tonic-gate 
72345916cd2Sjpk 	/* print out device_allocate entries for floppy devices */
72445916cd2Sjpk 	if (system_labeled) {
72545916cd2Sjpk 		dname = DA_FLOPPY_NAME;
72645916cd2Sjpk 		dclean = DA_DEFAULT_DISK_CLEAN;
72745916cd2Sjpk 	} else {
72845916cd2Sjpk 		dname = "fd";
72945916cd2Sjpk 		dclean = FLOPPY_CLEAN;
73045916cd2Sjpk 	}
7317c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
73245916cd2Sjpk 		for (j = 0; j < floppy_count; j++) {
73345916cd2Sjpk 			if (fp[j].number != i)
73445916cd2Sjpk 				continue;
73545916cd2Sjpk 			if (do_files) {
73645916cd2Sjpk 				(void) da_add_list(&devlist, fp[j].name, i,
73745916cd2Sjpk 				    DA_FLOPPY);
73845916cd2Sjpk 			} else if (do_devalloc) {
73945916cd2Sjpk 				/* print device_allocate for floppy devices */
74045916cd2Sjpk 				if (system_labeled) {
74145916cd2Sjpk 					(void) printf("%s%d%s\\\n",
74245916cd2Sjpk 					    dname, i, KV_DELIMITER);
74345916cd2Sjpk 					(void) printf("\t%s%s\\\n",
74445916cd2Sjpk 					    DA_FLOPPY_TYPE, KV_DELIMITER);
74545916cd2Sjpk 					(void) printf("\t%s%s\\\n",
74645916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
74745916cd2Sjpk 					(void) printf("\t%s%s\\\n",
74845916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
74945916cd2Sjpk 					(void) printf("\t%s%s\\\n",
75045916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
75145916cd2Sjpk 					    KV_DELIMITER);
75245916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
75345916cd2Sjpk 				} else {
75445916cd2Sjpk 					(void) printf(
75545916cd2Sjpk 					    "fd%d;fd;reserved;reserved;%s;",
7567c478bd9Sstevel@tonic-gate 					    i, DEFAULT_DEV_ALLOC_AUTH);
75745916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
75845916cd2Sjpk 					    "/fd_clean");
7597c478bd9Sstevel@tonic-gate 				}
76045916cd2Sjpk 				break;
76145916cd2Sjpk 			} else if (do_devmaps) {
76245916cd2Sjpk 				/* print device_maps for floppy devices */
76345916cd2Sjpk 				if (first) {
76445916cd2Sjpk 					(void) printf(" ");
76545916cd2Sjpk 				} else {
76645916cd2Sjpk 					if (system_labeled) {
76745916cd2Sjpk 						(void) printf("%s%d%s\\\n",
76845916cd2Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
76945916cd2Sjpk 						(void) printf("\t%s%s\\\n",
77045916cd2Sjpk 						    DA_FLOPPY_TYPE,
77145916cd2Sjpk 						    KV_TOKEN_DELIMIT);
77245916cd2Sjpk 						(void) printf("\t");
77345916cd2Sjpk 					} else {
77445916cd2Sjpk 						(void) printf("fd%d:\\\n", i);
77545916cd2Sjpk 						(void) printf("\tfd:\\\n");
77645916cd2Sjpk 						(void) printf("\t");
77745916cd2Sjpk 					}
77845916cd2Sjpk 					if (i == 0) {
77945916cd2Sjpk 						(void) printf("/dev/diskette ");
78045916cd2Sjpk 						(void) printf(
78145916cd2Sjpk 						    "/dev/rdiskette ");
78245916cd2Sjpk 					}
78345916cd2Sjpk 					first++;
78445916cd2Sjpk 				}
78545916cd2Sjpk 				(void) printf("%s", fp[j].name);
78645916cd2Sjpk 			}
78745916cd2Sjpk 		}
78845916cd2Sjpk 		if (do_devmaps && first) {
78945916cd2Sjpk 			(void) printf("\n\n");
79045916cd2Sjpk 			first = 0;
79145916cd2Sjpk 		}
79245916cd2Sjpk 	}
79345916cd2Sjpk 	if (do_files && floppy_count) {
79445916cd2Sjpk 		dargs.rootdir = NULL;
79545916cd2Sjpk 		dargs.devnames = NULL;
79645916cd2Sjpk 		dargs.optflag = DA_ADD;
79745916cd2Sjpk 		for (entry = devlist.floppy; entry != NULL;
79845916cd2Sjpk 		    entry = entry->next) {
79945916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
80045916cd2Sjpk 			(void) da_update_device(&dargs);
8017c478bd9Sstevel@tonic-gate 		}
8027c478bd9Sstevel@tonic-gate 	}
8037c478bd9Sstevel@tonic-gate }
8047c478bd9Sstevel@tonic-gate 
80545916cd2Sjpk static int
8067c478bd9Sstevel@tonic-gate docd()
8077c478bd9Sstevel@tonic-gate {
8087c478bd9Sstevel@tonic-gate 	DIR *dirp;
8097c478bd9Sstevel@tonic-gate 	struct dirent *dep;	/* directory entry pointer */
81045916cd2Sjpk 	int	i, j;
8117c478bd9Sstevel@tonic-gate 	char	*nm;		/* name/device of special device */
8127c478bd9Sstevel@tonic-gate 	char	linkvalue[2048];	/* symlink value */
8137c478bd9Sstevel@tonic-gate 	struct stat stat;	/* determine if it's a symlink */
8147c478bd9Sstevel@tonic-gate 	int	sz;		/* size of symlink value */
8157c478bd9Sstevel@tonic-gate 	char	*cp;		/* pointer into string */
8167c478bd9Sstevel@tonic-gate 	int	id;		/* disk id */
8177c478bd9Sstevel@tonic-gate 	int	ctrl;		/* disk controller */
8187c478bd9Sstevel@tonic-gate 	int	ncd;		/* max array size */
81945916cd2Sjpk 	int	cd_count = 0;
82045916cd2Sjpk 	int	first = 0;
82145916cd2Sjpk 	char	*dname, *dclean;
82245916cd2Sjpk 	da_args	dargs;
82345916cd2Sjpk 	deventry_t *entry;
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate 	ncd = DFLT_NCD;
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 	/*
8287c478bd9Sstevel@tonic-gate 	 * look for sr* and rsr*
8297c478bd9Sstevel@tonic-gate 	 */
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev")) == NULL) {
8327c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev failure"));
8337c478bd9Sstevel@tonic-gate 		exit(1);
8347c478bd9Sstevel@tonic-gate 	}
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate 	i = 0;
8377c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
8387c478bd9Sstevel@tonic-gate 		/* ignore if neither sr* nor rsr* */
8397c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, "sr", SIZE_OF_SR) &&
8407c478bd9Sstevel@tonic-gate 		    strncmp(dep->d_name, "rsr", SIZE_OF_RSR))
8417c478bd9Sstevel@tonic-gate 			continue;
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
8447c478bd9Sstevel@tonic-gate 		if (i == ncd) {
8457c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
8467c478bd9Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
8477c478bd9Sstevel@tonic-gate 		}
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 		/* save name (/dev + / + d_name + \0) */
8507c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
8517c478bd9Sstevel@tonic-gate 		if (nm == NULL)
8527c478bd9Sstevel@tonic-gate 			no_memory();
8537c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/");
8547c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
8557c478bd9Sstevel@tonic-gate 		cd[i].name = nm;
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate 		/* save id # */
8587c478bd9Sstevel@tonic-gate 		if (dep->d_name[0] == 'r')
8597c478bd9Sstevel@tonic-gate 			(void) sscanf(dep->d_name, "rsr%d", &cd[i].id);
8607c478bd9Sstevel@tonic-gate 		else
8617c478bd9Sstevel@tonic-gate 			(void) sscanf(dep->d_name, "sr%d", &cd[i].id);
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate 		/* ignore if not symbolic link (note i not incremented) */
8647c478bd9Sstevel@tonic-gate 		if (lstat(cd[i].name, &stat) < 0) {
8657c478bd9Sstevel@tonic-gate 			perror(gettext("stat(2) failed "));
8667c478bd9Sstevel@tonic-gate 			exit(1);
8677c478bd9Sstevel@tonic-gate 		}
8687c478bd9Sstevel@tonic-gate 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
8697c478bd9Sstevel@tonic-gate 			continue;
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 		/* get name from symbolic link */
8727c478bd9Sstevel@tonic-gate 		if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
8737c478bd9Sstevel@tonic-gate 		    0)
8747c478bd9Sstevel@tonic-gate 			continue;
87545916cd2Sjpk 
8767c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(sz + 1);
8777c478bd9Sstevel@tonic-gate 		if (nm == NULL)
8787c478bd9Sstevel@tonic-gate 			no_memory();
8797c478bd9Sstevel@tonic-gate 		(void) strncpy(nm, linkvalue, sz);
8807c478bd9Sstevel@tonic-gate 		nm[sz] = '\0';
8817c478bd9Sstevel@tonic-gate 		cd[i].device = nm;
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 		cp = strrchr(cd[i].device, '/');
8847c478bd9Sstevel@tonic-gate 		cp++;				/* advance to device # */
8857c478bd9Sstevel@tonic-gate 		(void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number);
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 		i++;
8887c478bd9Sstevel@tonic-gate 	}
88945916cd2Sjpk 	cd_count = i;
8907c478bd9Sstevel@tonic-gate 
8917c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate 	/*
8947c478bd9Sstevel@tonic-gate 	 * scan /dev/dsk for cd devices
8957c478bd9Sstevel@tonic-gate 	 */
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/dsk")) == NULL) {
8987c478bd9Sstevel@tonic-gate 		perror("gettext(open /dev/dsk failure)");
8997c478bd9Sstevel@tonic-gate 		exit(1);
9007c478bd9Sstevel@tonic-gate 	}
9017c478bd9Sstevel@tonic-gate 
9027c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
9037c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
9047c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
9057c478bd9Sstevel@tonic-gate 			continue;
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate 		/* get device # (disk #) */
9087c478bd9Sstevel@tonic-gate 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0)
9097c478bd9Sstevel@tonic-gate 			continue;
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 		/* see if this is one of the cd special devices */
91245916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
9137c478bd9Sstevel@tonic-gate 			if (cd[j].number == id && cd[j].controller == ctrl)
9147c478bd9Sstevel@tonic-gate 				goto found;
9157c478bd9Sstevel@tonic-gate 		}
9167c478bd9Sstevel@tonic-gate 		continue;
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 		/* add new entry to table (/dev/dsk + / + d_name + \0) */
9197c478bd9Sstevel@tonic-gate found:
9207c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
9217c478bd9Sstevel@tonic-gate 		if (i == ncd) {
9227c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
9237c478bd9Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
9247c478bd9Sstevel@tonic-gate 		}
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
9277c478bd9Sstevel@tonic-gate 		if (nm == NULL)
9287c478bd9Sstevel@tonic-gate 			no_memory();
9297c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/dsk/");
9307c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
9317c478bd9Sstevel@tonic-gate 		cd[i].name = nm;
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 		cd[i].id = cd[j].id;
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 		cd[i].device = "";
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate 		cd[i].number = id;
9387c478bd9Sstevel@tonic-gate 
9397c478bd9Sstevel@tonic-gate 		i++;
9407c478bd9Sstevel@tonic-gate 	}
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 	/*
9457c478bd9Sstevel@tonic-gate 	 * scan /dev/rdsk for cd devices
9467c478bd9Sstevel@tonic-gate 	 */
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate 	if ((dirp = opendir("/dev/rdsk")) == NULL) {
9497c478bd9Sstevel@tonic-gate 		perror(gettext("open /dev/dsk failure"));
9507c478bd9Sstevel@tonic-gate 		exit(1);
9517c478bd9Sstevel@tonic-gate 	}
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate 	while (dep = readdir(dirp)) {
9547c478bd9Sstevel@tonic-gate 		/* skip . .. etc... */
9557c478bd9Sstevel@tonic-gate 		if (strncmp(dep->d_name, ".", 1) == NULL)
9567c478bd9Sstevel@tonic-gate 			continue;
9577c478bd9Sstevel@tonic-gate 
9587c478bd9Sstevel@tonic-gate 		/* get device # (disk #) */
9597c478bd9Sstevel@tonic-gate 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
9607c478bd9Sstevel@tonic-gate 			continue;
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate 		/* see if this is one of the cd special devices */
96345916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
9647c478bd9Sstevel@tonic-gate 			if (cd[j].number == id && cd[j].controller == ctrl)
9657c478bd9Sstevel@tonic-gate 				goto found1;
9667c478bd9Sstevel@tonic-gate 		}
9677c478bd9Sstevel@tonic-gate 		continue;
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate 		/* add new entry to table (/dev/rdsk + / + d_name + \0) */
9707c478bd9Sstevel@tonic-gate found1:
9717c478bd9Sstevel@tonic-gate 		/* if array full, then expand it */
9727c478bd9Sstevel@tonic-gate 		if (i == ncd) {
9737c478bd9Sstevel@tonic-gate 			/* will exit(1) if insufficient memory */
9747c478bd9Sstevel@tonic-gate 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
9757c478bd9Sstevel@tonic-gate 		}
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 		nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1);
9787c478bd9Sstevel@tonic-gate 		if (nm == NULL)
9797c478bd9Sstevel@tonic-gate 			no_memory();
9807c478bd9Sstevel@tonic-gate 		(void) strcpy(nm, "/dev/rdsk/");
9817c478bd9Sstevel@tonic-gate 		(void) strcat(nm, dep->d_name);
9827c478bd9Sstevel@tonic-gate 		cd[i].name = nm;
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate 		cd[i].id = cd[j].id;
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate 		cd[i].device = "";
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 		cd[i].number = id;
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 		cd[i].controller = ctrl;
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 		i++;
9937c478bd9Sstevel@tonic-gate 	}
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
9967c478bd9Sstevel@tonic-gate 
99745916cd2Sjpk 	cd_count = i;
9987c478bd9Sstevel@tonic-gate 
99945916cd2Sjpk 	if (system_labeled) {
100045916cd2Sjpk 		dname = DA_CD_NAME;
100145916cd2Sjpk 		dclean = DA_DEFAULT_DISK_CLEAN;
100245916cd2Sjpk 	} else {
100345916cd2Sjpk 		dname = "sr";
100445916cd2Sjpk 		dclean = CD_CLEAN;
100545916cd2Sjpk 	}
10067c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++) {
100745916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
100845916cd2Sjpk 			if (cd[j].id != i)
100945916cd2Sjpk 				continue;
101045916cd2Sjpk 			if (do_files) {
101145916cd2Sjpk 				(void) da_add_list(&devlist, cd[j].name, i,
101245916cd2Sjpk 				    DA_CD);
101345916cd2Sjpk 			} else if (do_devalloc) {
101445916cd2Sjpk 				/* print device_allocate for cd devices */
101545916cd2Sjpk 				if (system_labeled) {
101645916cd2Sjpk 					(void) printf("%s%d%s\\\n",
101745916cd2Sjpk 					    dname, i, KV_DELIMITER);
101845916cd2Sjpk 					(void) printf("\t%s%s\\\n",
101945916cd2Sjpk 					    DA_CD_TYPE, KV_DELIMITER);
102045916cd2Sjpk 					(void) printf("\t%s%s\\\n",
102145916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
102245916cd2Sjpk 					(void) printf("\t%s%s\\\n",
102345916cd2Sjpk 					    DA_RESERVED, KV_DELIMITER);
102445916cd2Sjpk 					(void) printf("\t%s%s\\\n",
102545916cd2Sjpk 					    DEFAULT_DEV_ALLOC_AUTH,
102645916cd2Sjpk 					    KV_DELIMITER);
102745916cd2Sjpk 					(void) printf("\t%s\n\n", dclean);
102845916cd2Sjpk 				} else {
10297c478bd9Sstevel@tonic-gate 					(void) printf(
10307c478bd9Sstevel@tonic-gate 					    "sr%d;sr;reserved;reserved;%s;",
10317c478bd9Sstevel@tonic-gate 					    i, DEFAULT_DEV_ALLOC_AUTH);
103245916cd2Sjpk 					(void) printf("%s%s\n", SECLIB,
103345916cd2Sjpk 					    "/sr_clean");
103445916cd2Sjpk 				}
103545916cd2Sjpk 				break;
103645916cd2Sjpk 			} else if (do_devmaps) {
103745916cd2Sjpk 				/* print device_maps for cd devices */
103845916cd2Sjpk 				if (first) {
103945916cd2Sjpk 					(void) printf(" ");
104045916cd2Sjpk 				} else {
104145916cd2Sjpk 					if (system_labeled) {
104245916cd2Sjpk 						(void) printf("%s%d%s\\\n",
104345916cd2Sjpk 						    dname, i, KV_TOKEN_DELIMIT);
104445916cd2Sjpk 						(void) printf("\t%s%s\\\n",
104545916cd2Sjpk 						    DA_CD_TYPE,
104645916cd2Sjpk 						    KV_TOKEN_DELIMIT);
104745916cd2Sjpk 						(void) printf("\t");
104845916cd2Sjpk 					} else {
104945916cd2Sjpk 						(void) printf("sr%d:\\\n", i);
105045916cd2Sjpk 						(void) printf("\tsr:\\\n");
105145916cd2Sjpk 						(void) printf("\t");
105245916cd2Sjpk 					}
105345916cd2Sjpk 					first++;
105445916cd2Sjpk 				}
105545916cd2Sjpk 				(void) printf("%s", cd[j].name);
105645916cd2Sjpk 			}
105745916cd2Sjpk 		}
105845916cd2Sjpk 		if (do_devmaps && first) {
105945916cd2Sjpk 			(void) printf("\n\n");
106045916cd2Sjpk 			first = 0;
106145916cd2Sjpk 		}
106245916cd2Sjpk 	}
106345916cd2Sjpk 	if (do_files && cd_count) {
106445916cd2Sjpk 		dargs.rootdir = NULL;
106545916cd2Sjpk 		dargs.devnames = NULL;
106645916cd2Sjpk 		dargs.optflag = DA_ADD;
106745916cd2Sjpk 		for (entry = devlist.cd; entry != NULL; entry = entry->next) {
106845916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
106945916cd2Sjpk 			(void) da_update_device(&dargs);
107045916cd2Sjpk 		}
107145916cd2Sjpk 	}
107245916cd2Sjpk 
107345916cd2Sjpk 	return (cd_count);
107445916cd2Sjpk }
107545916cd2Sjpk 
107645916cd2Sjpk static void
107745916cd2Sjpk dormdisk(int cd_count)
107845916cd2Sjpk {
107945916cd2Sjpk 	DIR *dirp;
108045916cd2Sjpk 	struct dirent *dep;	/* directory entry pointer */
108145916cd2Sjpk 	int	i, j;
108245916cd2Sjpk 	char	*nm;		/* name/device of special device */
108345916cd2Sjpk 	int	id;		/* disk id */
108445916cd2Sjpk 	int	ctrl;		/* disk controller */
108545916cd2Sjpk 	int	nrmdisk;	/* max array size */
108645916cd2Sjpk 	int	fd = -1;
108745916cd2Sjpk 	int	rmdisk_count;
108845916cd2Sjpk 	int	first = 0;
108945916cd2Sjpk 	int	is_cd;
109045916cd2Sjpk 	int	checked;
109145916cd2Sjpk 	int	removable;
109245916cd2Sjpk 	char	path[MAXPATHLEN];
109345916cd2Sjpk 	da_args	dargs;
109445916cd2Sjpk 	deventry_t *entry;
109545916cd2Sjpk 
109645916cd2Sjpk 	nrmdisk = DFLT_RMDISK;
109745916cd2Sjpk 	i = rmdisk_count = 0;
109845916cd2Sjpk 
109945916cd2Sjpk 	/*
110045916cd2Sjpk 	 * scan /dev/dsk for rmdisk devices
110145916cd2Sjpk 	 */
110245916cd2Sjpk 	if ((dirp = opendir("/dev/dsk")) == NULL) {
110345916cd2Sjpk 		perror("gettext(open /dev/dsk failure)");
110445916cd2Sjpk 		exit(1);
110545916cd2Sjpk 	}
110645916cd2Sjpk 
110745916cd2Sjpk 	while (dep = readdir(dirp)) {
110845916cd2Sjpk 		is_cd = 0;
110945916cd2Sjpk 		checked = 0;
111045916cd2Sjpk 		removable = 0;
111145916cd2Sjpk 		/* skip . .. etc... */
111245916cd2Sjpk 		if (strncmp(dep->d_name, ".", 1) == NULL)
111345916cd2Sjpk 			continue;
111445916cd2Sjpk 
111545916cd2Sjpk 		/* get device # (disk #) */
111645916cd2Sjpk 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0)
111745916cd2Sjpk 			continue;
111845916cd2Sjpk 
111945916cd2Sjpk 		/* see if we've already examined this device */
112045916cd2Sjpk 		for (j = 0; j < i; j++) {
112145916cd2Sjpk 			if (id == rmdisk[j].id &&
112245916cd2Sjpk 			    ctrl == rmdisk[j].controller &&
112345916cd2Sjpk 			    (strcmp(dep->d_name, rmdisk[j].name) == 0)) {
112445916cd2Sjpk 				checked = 1;
11257c478bd9Sstevel@tonic-gate 				break;
11267c478bd9Sstevel@tonic-gate 			}
112745916cd2Sjpk 			if (id == rmdisk[j].id && ctrl != rmdisk[j].controller)
112845916cd2Sjpk 				/*
112945916cd2Sjpk 				 * c2t0d0s0 is a different rmdisk than c3t0d0s0.
113045916cd2Sjpk 				 */
113145916cd2Sjpk 				id = rmdisk[j].id + 1;
113245916cd2Sjpk 		}
113345916cd2Sjpk 		if (checked)
113445916cd2Sjpk 			continue;
113545916cd2Sjpk 
113645916cd2Sjpk 		/* ignore if this is a cd */
113745916cd2Sjpk 		for (j = 0; j < cd_count; j++) {
113845916cd2Sjpk 			if (id == cd[j].number && ctrl == cd[j].controller) {
113945916cd2Sjpk 				is_cd = 1;
114045916cd2Sjpk 				break;
114145916cd2Sjpk 			}
114245916cd2Sjpk 		}
114345916cd2Sjpk 		if (is_cd)
114445916cd2Sjpk 			continue;
114545916cd2Sjpk 
114645916cd2Sjpk 		/* see if device is removable */
114745916cd2Sjpk 		(void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/",
114845916cd2Sjpk 		    dep->d_name);
114945916cd2Sjpk 		if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
115045916cd2Sjpk 			continue;
115145916cd2Sjpk 		(void) ioctl(fd, DKIOCREMOVABLE, &removable);
115245916cd2Sjpk 		(void) close(fd);
115345916cd2Sjpk 		if (removable == 0)
115445916cd2Sjpk 			continue;
115545916cd2Sjpk 
115645916cd2Sjpk 		/*
115745916cd2Sjpk 		 * add new entry to table (/dev/dsk + / + d_name + \0)
115845916cd2Sjpk 		 * if array full, then expand it
115945916cd2Sjpk 		 */
116045916cd2Sjpk 		if (i == nrmdisk) {
116145916cd2Sjpk 			/* will exit(1) if insufficient memory */
116245916cd2Sjpk 			nrmdisk = expandmem(i, (void **)&rmdisk,
116345916cd2Sjpk 			    sizeof (struct rmdisk));
116445916cd2Sjpk 		}
116545916cd2Sjpk 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
116645916cd2Sjpk 		if (nm == NULL)
116745916cd2Sjpk 			no_memory();
116845916cd2Sjpk 		(void) strcpy(nm, "/dev/dsk/");
116945916cd2Sjpk 		(void) strcat(nm, dep->d_name);
117045916cd2Sjpk 		rmdisk[i].name = nm;
117145916cd2Sjpk 		rmdisk[i].id = id;
117245916cd2Sjpk 		rmdisk[i].controller = ctrl;
117345916cd2Sjpk 		rmdisk[i].device = "";
117445916cd2Sjpk 		rmdisk[i].number = id;
117545916cd2Sjpk 		rmdisk_r[i].name = strdup(path);
117645916cd2Sjpk 		i++;
117745916cd2Sjpk 	}
117845916cd2Sjpk 
117945916cd2Sjpk 	rmdisk_count = i;
118045916cd2Sjpk 	(void) closedir(dirp);
118145916cd2Sjpk 
118245916cd2Sjpk 	for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) {
118345916cd2Sjpk 		if (j == nrmdisk) {
118445916cd2Sjpk 			/* will exit(1) if insufficient memory */
118545916cd2Sjpk 			nrmdisk = expandmem(j, (void **)&rmdisk,
118645916cd2Sjpk 			    sizeof (struct rmdisk));
118745916cd2Sjpk 		}
118845916cd2Sjpk 		rmdisk[j].name = rmdisk_r[i].name;
118945916cd2Sjpk 		rmdisk[j].id = rmdisk[i].id;
119045916cd2Sjpk 		rmdisk[j].controller = rmdisk[i].controller;
119145916cd2Sjpk 		rmdisk[j].device = rmdisk[i].device;
119245916cd2Sjpk 		rmdisk[j].number = rmdisk[i].number;
119345916cd2Sjpk 	}
119445916cd2Sjpk 	rmdisk_count = j;
119545916cd2Sjpk 
119645916cd2Sjpk 	for (i = 0; i < 8; i++) {
119745916cd2Sjpk 		for (j = 0; j < rmdisk_count; j++) {
119845916cd2Sjpk 			if (rmdisk[j].id != i)
119945916cd2Sjpk 				continue;
120045916cd2Sjpk 			if (do_files) {
120145916cd2Sjpk 				(void) da_add_list(&devlist, rmdisk[j].name, i,
120245916cd2Sjpk 				    DA_RMDISK);
120345916cd2Sjpk 			} else if (do_devalloc) {
120445916cd2Sjpk 				/* print device_allocate for rmdisk devices */
120545916cd2Sjpk 				(void) printf("%s%d%s\\\n",
120645916cd2Sjpk 				    DA_RMDISK_NAME, i, KV_DELIMITER);
120745916cd2Sjpk 				(void) printf("\t%s%s\\\n",
120845916cd2Sjpk 				    DA_RMDISK_TYPE, KV_DELIMITER);
120945916cd2Sjpk 				(void) printf("\t%s%s\\\n",
121045916cd2Sjpk 				    DA_RESERVED, KV_DELIMITER);
121145916cd2Sjpk 				(void) printf("\t%s%s\\\n",
121245916cd2Sjpk 				    DA_RESERVED, KV_DELIMITER);
121345916cd2Sjpk 				(void) printf("\t%s%s\\\n",
121445916cd2Sjpk 				    DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER);
121545916cd2Sjpk 				(void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN);
121645916cd2Sjpk 				break;
121745916cd2Sjpk 			} else if (do_devmaps) {
121845916cd2Sjpk 				/* print device_maps for rmdisk devices */
121945916cd2Sjpk 				if (first) {
122045916cd2Sjpk 					(void) printf(" ");
122145916cd2Sjpk 				} else {
122245916cd2Sjpk 					(void) printf("%s%d%s\\\n",
122345916cd2Sjpk 					    DA_RMDISK_NAME, i,
122445916cd2Sjpk 					    KV_TOKEN_DELIMIT);
122545916cd2Sjpk 					(void) printf("\t%s%s\\\n",
122645916cd2Sjpk 					    DA_RMDISK_TYPE, KV_TOKEN_DELIMIT);
122745916cd2Sjpk 					(void) printf("\t");
122845916cd2Sjpk 					first++;
122945916cd2Sjpk 				}
123045916cd2Sjpk 				(void) printf("%s", rmdisk[j].name);
123145916cd2Sjpk 			}
123245916cd2Sjpk 		}
123345916cd2Sjpk 		if (do_devmaps && first) {
123445916cd2Sjpk 			(void) printf("\n\n");
123545916cd2Sjpk 			first = 0;
123645916cd2Sjpk 		}
123745916cd2Sjpk 	}
123845916cd2Sjpk 	if (do_files && rmdisk_count) {
123945916cd2Sjpk 		dargs.rootdir = NULL;
124045916cd2Sjpk 		dargs.devnames = NULL;
124145916cd2Sjpk 		dargs.optflag = DA_ADD;
124245916cd2Sjpk 		for (entry = devlist.rmdisk; entry != NULL;
124345916cd2Sjpk 		    entry = entry->next) {
124445916cd2Sjpk 			dargs.devinfo = &(entry->devinfo);
124545916cd2Sjpk 			(void) da_update_device(&dargs);
12467c478bd9Sstevel@tonic-gate 		}
12477c478bd9Sstevel@tonic-gate 	}
12487c478bd9Sstevel@tonic-gate }
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate /* set default array sizes */
12517c478bd9Sstevel@tonic-gate static void
12527c478bd9Sstevel@tonic-gate initmem()
12537c478bd9Sstevel@tonic-gate {
12547c478bd9Sstevel@tonic-gate 	tape  = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape));
12557c478bd9Sstevel@tonic-gate 	audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
12567c478bd9Sstevel@tonic-gate 	cd    = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
12577c478bd9Sstevel@tonic-gate 	fp    = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
125845916cd2Sjpk 	if (system_labeled) {
125945916cd2Sjpk 		rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK,
126045916cd2Sjpk 		    sizeof (struct rmdisk));
126145916cd2Sjpk 		if (rmdisk == NULL)
126245916cd2Sjpk 			no_memory();
126345916cd2Sjpk 		rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK,
126445916cd2Sjpk 		    sizeof (struct rmdisk));
126545916cd2Sjpk 		if (rmdisk_r == NULL)
126645916cd2Sjpk 			no_memory();
126745916cd2Sjpk 	}
12687c478bd9Sstevel@tonic-gate 
12697c478bd9Sstevel@tonic-gate 	if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
12707c478bd9Sstevel@tonic-gate 		no_memory();
127145916cd2Sjpk 
127245916cd2Sjpk 	devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk =
127345916cd2Sjpk 	    devlist.tape = NULL;
12747c478bd9Sstevel@tonic-gate }
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate /* note n will be # elments in array (and could be 0) */
12777c478bd9Sstevel@tonic-gate static int
12787c478bd9Sstevel@tonic-gate expandmem(int n, void **array, int size)
12797c478bd9Sstevel@tonic-gate {
12807c478bd9Sstevel@tonic-gate 	void *old = *array;
12817c478bd9Sstevel@tonic-gate 	void *new;
12827c478bd9Sstevel@tonic-gate 
12837c478bd9Sstevel@tonic-gate 	/* get new array space (n + DELTA) */
12847c478bd9Sstevel@tonic-gate 	new = (void *)calloc(n + DELTA,  size);
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 	if (new == NULL) {
12877c478bd9Sstevel@tonic-gate 		perror("memory allocation failed");
12887c478bd9Sstevel@tonic-gate 		exit(1);
12897c478bd9Sstevel@tonic-gate 	}
12907c478bd9Sstevel@tonic-gate 
12917c478bd9Sstevel@tonic-gate 	/* copy old array into new space */
12927c478bd9Sstevel@tonic-gate 	bcopy(old, new, n * size);
12937c478bd9Sstevel@tonic-gate 
12947c478bd9Sstevel@tonic-gate 	/* now release old arrary */
12957c478bd9Sstevel@tonic-gate 	free(old);
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	*array = new;
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate 	return (n + DELTA);
13007c478bd9Sstevel@tonic-gate }
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate static void
13037c478bd9Sstevel@tonic-gate no_memory(void)
13047c478bd9Sstevel@tonic-gate {
13057c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
13067c478bd9Sstevel@tonic-gate 	    gettext("out of memory"));
13077c478bd9Sstevel@tonic-gate 	exit(1);
13087c478bd9Sstevel@tonic-gate 	/* NOT REACHED */
13097c478bd9Sstevel@tonic-gate }
1310