xref: /onnv-gate/usr/src/cmd/devmgmt/mkdtab/mkdtab.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /*	#ident	"@(#)devintf:mkdtab/mkdtab.c	1.1.3.1"	*/
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate #include	<stdio.h>
35*0Sstevel@tonic-gate #include	<stdlib.h>
36*0Sstevel@tonic-gate #include	<string.h>
37*0Sstevel@tonic-gate #include	<fcntl.h>
38*0Sstevel@tonic-gate #include	<sys/types.h>
39*0Sstevel@tonic-gate #include	<unistd.h>
40*0Sstevel@tonic-gate #include	<devmgmt.h>
41*0Sstevel@tonic-gate #include	<devtab.h>
42*0Sstevel@tonic-gate #include	<dirent.h>
43*0Sstevel@tonic-gate #include	<libgen.h>
44*0Sstevel@tonic-gate #include	<sys/stat.h>
45*0Sstevel@tonic-gate #include	<sys/vtoc.h>
46*0Sstevel@tonic-gate #include	<sys/vfstab.h>
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate /*
49*0Sstevel@tonic-gate  * Update device.tab and dgroup.tab to reflect current configuration.
50*0Sstevel@tonic-gate  * Designed so it can be run either once at installation time or after
51*0Sstevel@tonic-gate  * every reboot.  The alias naming scheme used is non-intuitive but
52*0Sstevel@tonic-gate  * is consistent with existing conventions and documentation and with
53*0Sstevel@tonic-gate  * the device numbering scheme used by the disks command.
54*0Sstevel@tonic-gate  * Code borrowed liberally from prtconf, disks and prtvtoc commands.
55*0Sstevel@tonic-gate  */
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate /*
58*0Sstevel@tonic-gate  * make this long enough to start out with.
59*0Sstevel@tonic-gate  * there are place we write into putdevcmd
60*0Sstevel@tonic-gate  * where we are not testing for overrun.
61*0Sstevel@tonic-gate  */
62*0Sstevel@tonic-gate #define	ORIGLEN	1024
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate static struct dpart {
65*0Sstevel@tonic-gate 	char	alias[20];
66*0Sstevel@tonic-gate 	char	*cdevice;
67*0Sstevel@tonic-gate 	char	*bdevice;
68*0Sstevel@tonic-gate 	long	capacity;
69*0Sstevel@tonic-gate };
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate static int		vfsnum;
72*0Sstevel@tonic-gate static char		*putdevcmd;
73*0Sstevel@tonic-gate static char		cmd[80];
74*0Sstevel@tonic-gate static int		lastlen = ORIGLEN;
75*0Sstevel@tonic-gate #ifdef att3b2
76*0Sstevel@tonic-gate static struct mainedt	*edtp;
77*0Sstevel@tonic-gate #endif
78*0Sstevel@tonic-gate static struct vfstab	*vfstab;
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate static void checkandresize(int);
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate static char *
83*0Sstevel@tonic-gate memstr(const char *str)
84*0Sstevel@tonic-gate {
85*0Sstevel@tonic-gate 	char	*mem;
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate 	if ((mem = (char *)malloc((uint_t)strlen(str) + 1)) == NULL) {
88*0Sstevel@tonic-gate 		(void) fprintf(stderr,
89*0Sstevel@tonic-gate 		    "%s: can't update device tables:Out of memory\n", cmd);
90*0Sstevel@tonic-gate 		exit(1);
91*0Sstevel@tonic-gate 	}
92*0Sstevel@tonic-gate 	return (strcpy(mem, str));
93*0Sstevel@tonic-gate }
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate /*
98*0Sstevel@tonic-gate  * Add device table entry for the floppy drive.
99*0Sstevel@tonic-gate  */
100*0Sstevel@tonic-gate static void
101*0Sstevel@tonic-gate fdisk(const int diskno, const char *disknm)
102*0Sstevel@tonic-gate {
103*0Sstevel@tonic-gate 	if (snprintf(putdevcmd, lastlen, "/usr/bin/putdev -a diskette%d \
104*0Sstevel@tonic-gate cdevice=/dev/r%s bdevice=/dev/%s desc=\"Floppy Drive\" \
105*0Sstevel@tonic-gate mountpt=/mnt volume=diskette \
106*0Sstevel@tonic-gate type=diskette removable=true capacity=2880 \
107*0Sstevel@tonic-gate fmtcmd=\"/usr/bin/fdformat -f -v /dev/r%s\" \
108*0Sstevel@tonic-gate erasecmd=\"/usr/sbin/fdformat -f -v /dev/r%s\" \
109*0Sstevel@tonic-gate removecmd=\"/usr/bin/eject\" copy=true \
110*0Sstevel@tonic-gate mkfscmd=\"/usr/sbin/mkfs -F ufs /dev/r%s 2880 18 2 4096 512 80 2 5 3072 t\"",
111*0Sstevel@tonic-gate diskno, disknm, disknm, disknm, disknm, disknm) >= lastlen) {
112*0Sstevel@tonic-gate 		(void) fprintf(stderr,
113*0Sstevel@tonic-gate 		    "%s: Command too long: %s\n", cmd, putdevcmd);
114*0Sstevel@tonic-gate 		exit(1);
115*0Sstevel@tonic-gate 	}
116*0Sstevel@tonic-gate 	(void) system(putdevcmd);
117*0Sstevel@tonic-gate }
118*0Sstevel@tonic-gate 
119*0Sstevel@tonic-gate static void
120*0Sstevel@tonic-gate do_fdisks(void)
121*0Sstevel@tonic-gate {
122*0Sstevel@tonic-gate 	DIR *dp;
123*0Sstevel@tonic-gate 	struct dirent *dirp;
124*0Sstevel@tonic-gate 	int drive = 1;
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	if ((dp = opendir("/dev")) == NULL) {
127*0Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: can't open /dev\n", cmd);
128*0Sstevel@tonic-gate 		return;
129*0Sstevel@tonic-gate 	}
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 	while ((dirp = readdir(dp)) != NULL) {
132*0Sstevel@tonic-gate 		if (gmatch(dirp->d_name, "diskette*")) {
133*0Sstevel@tonic-gate 			fdisk(drive++, dirp->d_name);
134*0Sstevel@tonic-gate 		}
135*0Sstevel@tonic-gate 	}
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 	(void) closedir(dp);
138*0Sstevel@tonic-gate }
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate /*
141*0Sstevel@tonic-gate  * hdisk() gets information about the specified hard drive from the vtoc
142*0Sstevel@tonic-gate  * and vfstab and adds the disk and partition entries to device.tab. If
143*0Sstevel@tonic-gate  * we can't access the raw disk we simply assume it isn't properly configured
144*0Sstevel@tonic-gate  * and we add no entries to device.tab.
145*0Sstevel@tonic-gate  */
146*0Sstevel@tonic-gate static void
147*0Sstevel@tonic-gate hdisk(const int drive, const char *drivepfx)
148*0Sstevel@tonic-gate {
149*0Sstevel@tonic-gate 	char		*cdskpath;
150*0Sstevel@tonic-gate 	char		*bdskpath;
151*0Sstevel@tonic-gate 	char		*mountpoint;
152*0Sstevel@tonic-gate 	int		i, j, dpartcnt, fd;
153*0Sstevel@tonic-gate 	struct vtoc	vtoc;
154*0Sstevel@tonic-gate 	static struct dpart    *dparttab;
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 	if ((cdskpath = (char *)malloc(strlen(drivepfx) + 13)) == NULL) {
157*0Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: Memory request failed\n", cmd);
158*0Sstevel@tonic-gate 		exit(1);
159*0Sstevel@tonic-gate 	}
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 	(void) snprintf(cdskpath, strlen(drivepfx) + 13, "/dev/rdsk/%ss2",
162*0Sstevel@tonic-gate 	    drivepfx);
163*0Sstevel@tonic-gate 	if ((fd = open(cdskpath, O_RDONLY)) == -1) {
164*0Sstevel@tonic-gate 		free(cdskpath);
165*0Sstevel@tonic-gate 		return;
166*0Sstevel@tonic-gate 	}
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	/*
170*0Sstevel@tonic-gate 	 * Read volume table of contents.
171*0Sstevel@tonic-gate 	 */
172*0Sstevel@tonic-gate 	if (read_vtoc(fd, &vtoc) < 0) {
173*0Sstevel@tonic-gate 		(void) close(fd);
174*0Sstevel@tonic-gate 		free(cdskpath);
175*0Sstevel@tonic-gate 		return;
176*0Sstevel@tonic-gate 	}
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	(void) close(fd);
179*0Sstevel@tonic-gate 
180*0Sstevel@tonic-gate 	/*
181*0Sstevel@tonic-gate 	 * Begin building the putdev command string that will be
182*0Sstevel@tonic-gate 	 * used to make the entry for this disk.
183*0Sstevel@tonic-gate 	 */
184*0Sstevel@tonic-gate 
185*0Sstevel@tonic-gate 	if ((bdskpath = (char *)malloc(strlen(drivepfx) + 13)) == NULL) {
186*0Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: Memory request failed\n", cmd);
187*0Sstevel@tonic-gate 		exit(1);
188*0Sstevel@tonic-gate 	}
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	(void) snprintf(bdskpath, strlen(drivepfx) + 13, "/dev/dsk/%ss2",
191*0Sstevel@tonic-gate 	    drivepfx);
192*0Sstevel@tonic-gate 	if (snprintf(putdevcmd, lastlen, "/usr/bin/putdev -a disk%d \
193*0Sstevel@tonic-gate cdevice=%s bdevice=%s \
194*0Sstevel@tonic-gate desc=\"Disk Drive\" type=disk \
195*0Sstevel@tonic-gate part=true removable=false capacity=%ld dpartlist=",
196*0Sstevel@tonic-gate 	    drive, cdskpath, bdskpath, vtoc.v_part[6].p_size) >= lastlen) {
197*0Sstevel@tonic-gate 		(void) fprintf(stderr,
198*0Sstevel@tonic-gate 		    "%s: Command too long: %s\n", cmd, putdevcmd);
199*0Sstevel@tonic-gate 		exit(1);
200*0Sstevel@tonic-gate 	}
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate 	free(cdskpath);
203*0Sstevel@tonic-gate 	free(bdskpath);
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	/*
206*0Sstevel@tonic-gate 	 * Build a table of disk partitions we are interested in and finish
207*0Sstevel@tonic-gate 	 * the putdev command string for the disk by adding the dpartlist.
208*0Sstevel@tonic-gate 	 */
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 	if ((dparttab =
211*0Sstevel@tonic-gate 		(struct dpart *)malloc((int)vtoc.v_nparts *
212*0Sstevel@tonic-gate 				sizeof (struct dpart))) == NULL) {
213*0Sstevel@tonic-gate 		(void) fprintf(stderr,
214*0Sstevel@tonic-gate 			"%s: can't disk partitions table: Out of memory\n",
215*0Sstevel@tonic-gate 			cmd);
216*0Sstevel@tonic-gate 		exit(1);
217*0Sstevel@tonic-gate 	}
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate 	dpartcnt = 0;
220*0Sstevel@tonic-gate 	for (i = 0; i < (int)vtoc.v_nparts; ++i) {
221*0Sstevel@tonic-gate 		if (vtoc.v_part[i].p_size == 0 || vtoc.v_part[i].p_flag != 0)
222*0Sstevel@tonic-gate 			continue;
223*0Sstevel@tonic-gate 		(void) sprintf(dparttab[dpartcnt].alias, "dpart%d%02d", drive,
224*0Sstevel@tonic-gate 		    i);
225*0Sstevel@tonic-gate 
226*0Sstevel@tonic-gate 		if ((dparttab[dpartcnt].cdevice =
227*0Sstevel@tonic-gate 			(char *)malloc(strlen(drivepfx) + 14)) == NULL) {
228*0Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: Out of memory\n", cmd);
229*0Sstevel@tonic-gate 			exit(1);
230*0Sstevel@tonic-gate 		}
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 		(void) snprintf(dparttab[dpartcnt].cdevice,
233*0Sstevel@tonic-gate 		    strlen(drivepfx) + 14, "/dev/rdsk/%ss%x", drivepfx, i);
234*0Sstevel@tonic-gate 		if ((dparttab[dpartcnt].bdevice =
235*0Sstevel@tonic-gate 			(char *)malloc(strlen(drivepfx) + 14)) == NULL) {
236*0Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: Out of memory\n", cmd);
237*0Sstevel@tonic-gate 			exit(1);
238*0Sstevel@tonic-gate 		}
239*0Sstevel@tonic-gate 		(void) snprintf(dparttab[dpartcnt].bdevice,
240*0Sstevel@tonic-gate 		    strlen(drivepfx) + 14, "/dev/dsk/%ss%x", drivepfx, i);
241*0Sstevel@tonic-gate 		dparttab[dpartcnt].capacity = vtoc.v_part[i].p_size;
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate 		if (dpartcnt != 0)
244*0Sstevel@tonic-gate 			(void) strcat(putdevcmd, ",");
245*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, dparttab[dpartcnt].alias);
246*0Sstevel@tonic-gate 		dpartcnt++;
247*0Sstevel@tonic-gate 	}
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 	(void) system(putdevcmd);
250*0Sstevel@tonic-gate 
251*0Sstevel@tonic-gate 	/*
252*0Sstevel@tonic-gate 	 * We assemble the rest of the information about the partitions by
253*0Sstevel@tonic-gate 	 * looking in the vfstab.
254*0Sstevel@tonic-gate 	 */
255*0Sstevel@tonic-gate 	for (i = 0; i < dpartcnt; i++) {
256*0Sstevel@tonic-gate 		for (j = 0; j < vfsnum; j++) {
257*0Sstevel@tonic-gate 			if (vfstab[j].vfs_special != NULL &&
258*0Sstevel@tonic-gate 			    strcmp(dparttab[i].bdevice,
259*0Sstevel@tonic-gate 				vfstab[j].vfs_special) == 0)
260*0Sstevel@tonic-gate 				break;
261*0Sstevel@tonic-gate 		}
262*0Sstevel@tonic-gate 		if (j < vfsnum) {
263*0Sstevel@tonic-gate 			/*
264*0Sstevel@tonic-gate 			 * Partition found in vfstab.
265*0Sstevel@tonic-gate 			 */
266*0Sstevel@tonic-gate 			if (vfstab[j].vfs_mountp == NULL ||
267*0Sstevel@tonic-gate 			    strcmp(vfstab[j].vfs_mountp, "-") == 0)
268*0Sstevel@tonic-gate 				mountpoint="/mnt";
269*0Sstevel@tonic-gate 			else
270*0Sstevel@tonic-gate 				mountpoint=vfstab[j].vfs_mountp;
271*0Sstevel@tonic-gate 			if (snprintf(putdevcmd, lastlen, "/usr/bin/putdev \
272*0Sstevel@tonic-gate -a %s cdevice=%s bdevice=%s desc=\"Disk Partition\" type=dpart removable=false \
273*0Sstevel@tonic-gate capacity=%ld dparttype=fs fstype=%s mountpt=%s", dparttab[i].alias,
274*0Sstevel@tonic-gate dparttab[i].cdevice, dparttab[i].bdevice, dparttab[i].capacity,
275*0Sstevel@tonic-gate vfstab[j].vfs_fstype, mountpoint) >= lastlen) {
276*0Sstevel@tonic-gate 					(void) fprintf(stderr,
277*0Sstevel@tonic-gate 					    "%s: Command too long: %s\n",
278*0Sstevel@tonic-gate 					    cmd, putdevcmd);
279*0Sstevel@tonic-gate 					exit(1);
280*0Sstevel@tonic-gate 				}
281*0Sstevel@tonic-gate 				(void) system(putdevcmd);
282*0Sstevel@tonic-gate 		}
283*0Sstevel@tonic-gate 		free(dparttab[i].cdevice);
284*0Sstevel@tonic-gate 		free(dparttab[i].bdevice);
285*0Sstevel@tonic-gate 	}
286*0Sstevel@tonic-gate 	free(dparttab);
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate static void
290*0Sstevel@tonic-gate do_hdisks(void)
291*0Sstevel@tonic-gate {
292*0Sstevel@tonic-gate 	DIR *dp;
293*0Sstevel@tonic-gate 	struct dirent *dirp;
294*0Sstevel@tonic-gate 	int drive = 1;	char disknm[MAXNAMLEN+1];
295*0Sstevel@tonic-gate 
296*0Sstevel@tonic-gate 	if ((dp = opendir("/dev/rdsk")) == NULL) {
297*0Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: can't open /dev/rdsk\n", cmd);
298*0Sstevel@tonic-gate 		return;
299*0Sstevel@tonic-gate 	}
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate 	while ((dirp = readdir(dp)) != NULL) {
302*0Sstevel@tonic-gate 		if (gmatch(dirp->d_name, "c[0-9]*s2")) {
303*0Sstevel@tonic-gate 			(void) strcpy(disknm, dirp->d_name);
304*0Sstevel@tonic-gate 			/*
305*0Sstevel@tonic-gate 			 * now know off the 's2'
306*0Sstevel@tonic-gate 			 */
307*0Sstevel@tonic-gate 			disknm[strlen(disknm)-2] = '\0';
308*0Sstevel@tonic-gate 			/*
309*0Sstevel@tonic-gate 			 * And do it!
310*0Sstevel@tonic-gate 			 */
311*0Sstevel@tonic-gate 			hdisk(drive++, disknm);
312*0Sstevel@tonic-gate 		}
313*0Sstevel@tonic-gate 	}
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate 	(void) closedir(dp);
316*0Sstevel@tonic-gate }
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate 
319*0Sstevel@tonic-gate /*
320*0Sstevel@tonic-gate  * Add device table entry for the cartridge tape drive.
321*0Sstevel@tonic-gate  */
322*0Sstevel@tonic-gate static void
323*0Sstevel@tonic-gate tape(const int driveno, const char *drivenm)
324*0Sstevel@tonic-gate {
325*0Sstevel@tonic-gate 	if (snprintf(putdevcmd, lastlen, "/usr/bin/putdev -a ctape%d \
326*0Sstevel@tonic-gate cdevice=/dev/rmt/%s \
327*0Sstevel@tonic-gate desc=\"Tape Drive\" volume=\"tape\" \
328*0Sstevel@tonic-gate type=ctape removable=true capacity=45539 bufsize=15872 \
329*0Sstevel@tonic-gate erasecmd=\"/usr/bin/mt -f /dev/rmt/%s erase\" \
330*0Sstevel@tonic-gate removecmd=\"/usr/bin/mt -f /dev/rmt/%s offline\"",
331*0Sstevel@tonic-gate 	    driveno, drivenm, drivenm, drivenm) >= lastlen) {
332*0Sstevel@tonic-gate 		(void) fprintf(stderr,
333*0Sstevel@tonic-gate 		    "%s: Command too long: %s\n", cmd, putdevcmd);
334*0Sstevel@tonic-gate 		exit(1);
335*0Sstevel@tonic-gate 	}
336*0Sstevel@tonic-gate 	(void) system(putdevcmd);
337*0Sstevel@tonic-gate }
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate static void
340*0Sstevel@tonic-gate do_tapes(void)
341*0Sstevel@tonic-gate {
342*0Sstevel@tonic-gate 	DIR *dp;
343*0Sstevel@tonic-gate 	struct dirent *dirp;
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 	if ((dp = opendir("/dev/rmt")) == NULL) {
346*0Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: can't open /dev/rmt\n", cmd);
347*0Sstevel@tonic-gate 		return;
348*0Sstevel@tonic-gate 	}
349*0Sstevel@tonic-gate 
350*0Sstevel@tonic-gate 	while ((dirp = readdir(dp)) != NULL) {
351*0Sstevel@tonic-gate 		if (gmatch(dirp->d_name, "[0-9]") ||
352*0Sstevel@tonic-gate 		    gmatch(dirp->d_name, "[1-9][0-9]")) {
353*0Sstevel@tonic-gate 			tape(atoi(dirp->d_name), dirp->d_name);
354*0Sstevel@tonic-gate 		}
355*0Sstevel@tonic-gate 	}
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 	(void) closedir(dp);
358*0Sstevel@tonic-gate }
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate static void
361*0Sstevel@tonic-gate initialize(void)
362*0Sstevel@tonic-gate {
363*0Sstevel@tonic-gate 	FILE		*fp;
364*0Sstevel@tonic-gate 	int		i;
365*0Sstevel@tonic-gate 	struct vfstab	vfsent;
366*0Sstevel@tonic-gate 	char		*criteria[5];
367*0Sstevel@tonic-gate 	char		**olddevlist;
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate 	/*
370*0Sstevel@tonic-gate 	 * Build a copy of vfstab in memory for later use.
371*0Sstevel@tonic-gate 	 */
372*0Sstevel@tonic-gate 	if ((fp = fopen("/etc/vfstab", "r")) == NULL) {
373*0Sstevel@tonic-gate 		(void) fprintf(stderr,
374*0Sstevel@tonic-gate 		    "%s: can't update device tables:Can't open /etc/vfstab\n",
375*0Sstevel@tonic-gate 			cmd);
376*0Sstevel@tonic-gate 		exit(1);
377*0Sstevel@tonic-gate 	}
378*0Sstevel@tonic-gate 
379*0Sstevel@tonic-gate 	/*
380*0Sstevel@tonic-gate 	 * Go through the vfstab file once to get the number of entries so
381*0Sstevel@tonic-gate 	 * we can allocate the right amount of contiguous memory.
382*0Sstevel@tonic-gate 	 */
383*0Sstevel@tonic-gate 	vfsnum = 0;
384*0Sstevel@tonic-gate 	while (getvfsent(fp, &vfsent) == 0)
385*0Sstevel@tonic-gate 		vfsnum++;
386*0Sstevel@tonic-gate 	rewind(fp);
387*0Sstevel@tonic-gate 
388*0Sstevel@tonic-gate 	if ((vfstab = (struct vfstab *)malloc(vfsnum * sizeof (struct vfstab)))
389*0Sstevel@tonic-gate 	    == NULL) {
390*0Sstevel@tonic-gate 		(void) fprintf(stderr,
391*0Sstevel@tonic-gate 			"%s: can't update device tables:Out of memory\n",
392*0Sstevel@tonic-gate 		    cmd);
393*0Sstevel@tonic-gate 		exit(1);
394*0Sstevel@tonic-gate 	}
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate 	/*
397*0Sstevel@tonic-gate 	 * Go through the vfstab file one more time to populate our copy in
398*0Sstevel@tonic-gate 	 * memory.  We only populate the fields we'll need.
399*0Sstevel@tonic-gate 	 */
400*0Sstevel@tonic-gate 	i = 0;
401*0Sstevel@tonic-gate 	while (getvfsent(fp, &vfsent) == 0 && i < vfsnum) {
402*0Sstevel@tonic-gate 		if (vfsent.vfs_special == NULL)
403*0Sstevel@tonic-gate 			vfstab[i].vfs_special = NULL;
404*0Sstevel@tonic-gate 		else
405*0Sstevel@tonic-gate 			vfstab[i].vfs_special = memstr(vfsent.vfs_special);
406*0Sstevel@tonic-gate 		if (vfsent.vfs_mountp == NULL)
407*0Sstevel@tonic-gate 			vfstab[i].vfs_mountp = NULL;
408*0Sstevel@tonic-gate 		else
409*0Sstevel@tonic-gate 			vfstab[i].vfs_mountp = memstr(vfsent.vfs_mountp);
410*0Sstevel@tonic-gate 		if (vfsent.vfs_fstype == NULL)
411*0Sstevel@tonic-gate 			vfstab[i].vfs_fstype = NULL;
412*0Sstevel@tonic-gate 		else
413*0Sstevel@tonic-gate 			vfstab[i].vfs_fstype = memstr(vfsent.vfs_fstype);
414*0Sstevel@tonic-gate 		i++;
415*0Sstevel@tonic-gate 	}
416*0Sstevel@tonic-gate 	(void) fclose(fp);
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate 	/*
419*0Sstevel@tonic-gate 	 * Now remove all current entries of type disk, dpart, ctape
420*0Sstevel@tonic-gate 	 * and diskette from the device and device group tables.
421*0Sstevel@tonic-gate 	 * Any changes made manually since the last time this command
422*0Sstevel@tonic-gate 	 * was run will be lost.  Note that after this we are committed
423*0Sstevel@tonic-gate 	 * to try our best to rebuild the tables (i.e. the command
424*0Sstevel@tonic-gate 	 * should try not to fail completely after this point).
425*0Sstevel@tonic-gate 	 */
426*0Sstevel@tonic-gate 	criteria[0] = "type=disk";
427*0Sstevel@tonic-gate 	criteria[1] = "type=dpart";
428*0Sstevel@tonic-gate 	criteria[2] = "type=ctape";
429*0Sstevel@tonic-gate 	criteria[3] = "type=diskette";
430*0Sstevel@tonic-gate 	criteria[4] = (char *)NULL;
431*0Sstevel@tonic-gate 	olddevlist = getdev((char **)NULL, criteria, 0);
432*0Sstevel@tonic-gate 	_enddevtab();	/* getdev() should do this but doesn't */
433*0Sstevel@tonic-gate 
434*0Sstevel@tonic-gate 	putdevcmd = malloc(ORIGLEN);
435*0Sstevel@tonic-gate 
436*0Sstevel@tonic-gate 	if (putdevcmd == NULL) {
437*0Sstevel@tonic-gate 		perror("malloc");
438*0Sstevel@tonic-gate 		exit (-1);
439*0Sstevel@tonic-gate 	}
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate 	(void) memset(putdevcmd, 0, ORIGLEN);
442*0Sstevel@tonic-gate 
443*0Sstevel@tonic-gate 	for (i = 0; olddevlist[i] != (char *)NULL; i++) {
444*0Sstevel@tonic-gate 		if (snprintf(putdevcmd, lastlen,
445*0Sstevel@tonic-gate 		    "/usr/bin/putdev -d %s", olddevlist[i]) >= lastlen) {
446*0Sstevel@tonic-gate 			(void) fprintf(stderr,
447*0Sstevel@tonic-gate 			    "%s: Command too long: %s\n", cmd, putdevcmd);
448*0Sstevel@tonic-gate 			exit(1);
449*0Sstevel@tonic-gate 		}
450*0Sstevel@tonic-gate 		(void) system(putdevcmd);
451*0Sstevel@tonic-gate 	}
452*0Sstevel@tonic-gate 
453*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp -d disk 2>/dev/null");
454*0Sstevel@tonic-gate 	(void) system(putdevcmd);
455*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp -d dpart 2>/dev/null");
456*0Sstevel@tonic-gate 	(void) system(putdevcmd);
457*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp -d ctape 2>/dev/null");
458*0Sstevel@tonic-gate 	(void) system(putdevcmd);
459*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp -d diskette 2>/dev/null");
460*0Sstevel@tonic-gate 	(void) system(putdevcmd);
461*0Sstevel@tonic-gate }
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate /*
465*0Sstevel@tonic-gate  * Update the dgroup.tab file with information from the updated device.tab.
466*0Sstevel@tonic-gate  */
467*0Sstevel@tonic-gate static void
468*0Sstevel@tonic-gate mkdgroups(void)
469*0Sstevel@tonic-gate {
470*0Sstevel@tonic-gate 	int	i;
471*0Sstevel@tonic-gate 	char	*criteria[2];
472*0Sstevel@tonic-gate 	char	**devlist;
473*0Sstevel@tonic-gate 
474*0Sstevel@tonic-gate 	criteria[1] = (char *)NULL;
475*0Sstevel@tonic-gate 
476*0Sstevel@tonic-gate 	criteria[0] = "type=disk";
477*0Sstevel@tonic-gate 
478*0Sstevel@tonic-gate 	devlist = getdev((char **)NULL, criteria, DTAB_ANDCRITERIA);
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp disk");
481*0Sstevel@tonic-gate 	for (i = 0; devlist[i] != (char *)NULL; i++) {
482*0Sstevel@tonic-gate 		checkandresize((strlen(putdevcmd) + strlen(devlist[i]) + 2));
483*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, " ");
484*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, devlist[i]);
485*0Sstevel@tonic-gate 	}
486*0Sstevel@tonic-gate 	if (i != 0)
487*0Sstevel@tonic-gate 		(void) system(putdevcmd);
488*0Sstevel@tonic-gate 
489*0Sstevel@tonic-gate 	criteria[0] = "type=dpart";
490*0Sstevel@tonic-gate 
491*0Sstevel@tonic-gate 	devlist = getdev((char **)NULL, criteria, DTAB_ANDCRITERIA);
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp dpart");
494*0Sstevel@tonic-gate 	for (i = 0; devlist[i] != (char *)NULL; i++) {
495*0Sstevel@tonic-gate 		checkandresize((strlen(putdevcmd) + strlen(devlist[i]) + 2));
496*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, " ");
497*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, devlist[i]);
498*0Sstevel@tonic-gate 	}
499*0Sstevel@tonic-gate 	if (i != 0)
500*0Sstevel@tonic-gate 		(void) system(putdevcmd);
501*0Sstevel@tonic-gate 
502*0Sstevel@tonic-gate 	criteria[0] = "type=ctape";
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate 	devlist = getdev((char **)NULL, criteria, DTAB_ANDCRITERIA);
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp ctape");
507*0Sstevel@tonic-gate 	for (i = 0; devlist[i] != (char *)NULL; i++) {
508*0Sstevel@tonic-gate 		checkandresize((strlen(putdevcmd) + strlen(devlist[i]) + 2));
509*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, " ");
510*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, devlist[i]);
511*0Sstevel@tonic-gate 	}
512*0Sstevel@tonic-gate 	if (i != 0)
513*0Sstevel@tonic-gate 		(void) system(putdevcmd);
514*0Sstevel@tonic-gate 
515*0Sstevel@tonic-gate 	criteria[0] = "type=diskette";
516*0Sstevel@tonic-gate 
517*0Sstevel@tonic-gate 	devlist = getdev((char **)NULL, criteria, DTAB_ANDCRITERIA);
518*0Sstevel@tonic-gate 
519*0Sstevel@tonic-gate 	(void) sprintf(putdevcmd, "/usr/bin/putdgrp diskette");
520*0Sstevel@tonic-gate 	for (i = 0; devlist[i] != (char *)NULL; i++) {
521*0Sstevel@tonic-gate 		checkandresize((strlen(putdevcmd) + strlen(devlist[i]) + 2));
522*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, " ");
523*0Sstevel@tonic-gate 		(void) strcat(putdevcmd, devlist[i]);
524*0Sstevel@tonic-gate 	}
525*0Sstevel@tonic-gate 	if (i != 0)
526*0Sstevel@tonic-gate 		(void) system(putdevcmd);
527*0Sstevel@tonic-gate }
528*0Sstevel@tonic-gate 
529*0Sstevel@tonic-gate static void
530*0Sstevel@tonic-gate checkandresize(int size)
531*0Sstevel@tonic-gate {
532*0Sstevel@tonic-gate 	if (size >= lastlen) {
533*0Sstevel@tonic-gate 		putdevcmd = realloc(putdevcmd, lastlen * 2);
534*0Sstevel@tonic-gate 		lastlen = lastlen * 2;
535*0Sstevel@tonic-gate 	}
536*0Sstevel@tonic-gate }
537*0Sstevel@tonic-gate 
538*0Sstevel@tonic-gate /*ARGSUSED*/
539*0Sstevel@tonic-gate void
540*0Sstevel@tonic-gate main(int argc, char **argv)
541*0Sstevel@tonic-gate {
542*0Sstevel@tonic-gate 	(void) strncpy(cmd, argv[0], 80);
543*0Sstevel@tonic-gate 
544*0Sstevel@tonic-gate 	initialize();
545*0Sstevel@tonic-gate 
546*0Sstevel@tonic-gate 	/*
547*0Sstevel@tonic-gate 	 * AT&T code looked at the 3B2 EDT here.  Since we have a known-good
548*0Sstevel@tonic-gate 	 * /dev directory ( presuming 'disks' has already been run), we simply
549*0Sstevel@tonic-gate 	 * look in the /dev subdirectories.
550*0Sstevel@tonic-gate 	 */
551*0Sstevel@tonic-gate 	do_hdisks();
552*0Sstevel@tonic-gate 
553*0Sstevel@tonic-gate 	do_fdisks();
554*0Sstevel@tonic-gate 
555*0Sstevel@tonic-gate 	do_tapes();
556*0Sstevel@tonic-gate 
557*0Sstevel@tonic-gate 	/*
558*0Sstevel@tonic-gate 	 * Update the dgroup.tab file.
559*0Sstevel@tonic-gate 	 */
560*0Sstevel@tonic-gate 	mkdgroups();
561*0Sstevel@tonic-gate 
562*0Sstevel@tonic-gate 	exit(0);
563*0Sstevel@tonic-gate 
564*0Sstevel@tonic-gate }
565