1*9781SMoriah.Waterland@Sun.COM /*
2*9781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
3*9781SMoriah.Waterland@Sun.COM  *
4*9781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
5*9781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
6*9781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
7*9781SMoriah.Waterland@Sun.COM  *
8*9781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*9781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
11*9781SMoriah.Waterland@Sun.COM  * and limitations under the License.
12*9781SMoriah.Waterland@Sun.COM  *
13*9781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*9781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*9781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*9781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9781SMoriah.Waterland@Sun.COM  *
19*9781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
20*9781SMoriah.Waterland@Sun.COM  */
21*9781SMoriah.Waterland@Sun.COM 
22*9781SMoriah.Waterland@Sun.COM /*
23*9781SMoriah.Waterland@Sun.COM  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*9781SMoriah.Waterland@Sun.COM  * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM  */
26*9781SMoriah.Waterland@Sun.COM 
27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
29*9781SMoriah.Waterland@Sun.COM 
30*9781SMoriah.Waterland@Sun.COM 
31*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
32*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
33*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
34*9781SMoriah.Waterland@Sun.COM #include <archives.h>
35*9781SMoriah.Waterland@Sun.COM #include <errno.h>
36*9781SMoriah.Waterland@Sun.COM #include <fcntl.h>
37*9781SMoriah.Waterland@Sun.COM #include <limits.h>
38*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
39*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
40*9781SMoriah.Waterland@Sun.COM #include <string.h>
41*9781SMoriah.Waterland@Sun.COM #include "pkglocale.h"
42*9781SMoriah.Waterland@Sun.COM #include "pkglibmsgs.h"
43*9781SMoriah.Waterland@Sun.COM 
44*9781SMoriah.Waterland@Sun.COM /*
45*9781SMoriah.Waterland@Sun.COM  * Defines for cpio/compression checks.
46*9781SMoriah.Waterland@Sun.COM  */
47*9781SMoriah.Waterland@Sun.COM #define	BIT_MASK		0x1f
48*9781SMoriah.Waterland@Sun.COM #define	BLOCK_MASK		0x80
49*9781SMoriah.Waterland@Sun.COM 
50*9781SMoriah.Waterland@Sun.COM #define	MASK_CK(x, y)	(((x) & (y)) == (y))
51*9781SMoriah.Waterland@Sun.COM #define	ISCOMPCPIO	((unsigned char) cm.c_mag[0] == m_h[0] && \
52*9781SMoriah.Waterland@Sun.COM 			(unsigned char) cm.c_mag[1] == m_h[1] && \
53*9781SMoriah.Waterland@Sun.COM 			(MASK_CK((unsigned char) cm.c_mag[2], BLOCK_MASK) || \
54*9781SMoriah.Waterland@Sun.COM 			MASK_CK((unsigned char) cm.c_mag[2], BIT_MASK)))
55*9781SMoriah.Waterland@Sun.COM 
56*9781SMoriah.Waterland@Sun.COM #define	ISCPIO		(cm.b_mag != CMN_BIN && \
57*9781SMoriah.Waterland@Sun.COM 			(strcmp(cm.c_mag, CMS_ASC) == 0) && \
58*9781SMoriah.Waterland@Sun.COM 			(strcmp(cm.c_mag, CMS_CHR) == 0) && \
59*9781SMoriah.Waterland@Sun.COM 			(strcmp(cm.c_mag, CMS_CRC) == 0))
60*9781SMoriah.Waterland@Sun.COM 
61*9781SMoriah.Waterland@Sun.COM /* location of distributed file system types database */
62*9781SMoriah.Waterland@Sun.COM 
63*9781SMoriah.Waterland@Sun.COM #define	REMOTE_FS_DBFILE	"/etc/dfs/fstypes"
64*9781SMoriah.Waterland@Sun.COM 
65*9781SMoriah.Waterland@Sun.COM /* character array used to hold dfs types database contents */
66*9781SMoriah.Waterland@Sun.COM 
67*9781SMoriah.Waterland@Sun.COM static long		numRemoteFstypes = -1;
68*9781SMoriah.Waterland@Sun.COM static char		**remoteFstypes = (char **)NULL;
69*9781SMoriah.Waterland@Sun.COM 
70*9781SMoriah.Waterland@Sun.COM /* forward declarations */
71*9781SMoriah.Waterland@Sun.COM 
72*9781SMoriah.Waterland@Sun.COM static void _InitRemoteFstypes(void);
73*9781SMoriah.Waterland@Sun.COM 
74*9781SMoriah.Waterland@Sun.COM int isFdRemote(int a_fd);
75*9781SMoriah.Waterland@Sun.COM int isPathRemote(char *a_path);
76*9781SMoriah.Waterland@Sun.COM int isFstypeRemote(char *a_fstype);
77*9781SMoriah.Waterland@Sun.COM int isdir(char *path);
78*9781SMoriah.Waterland@Sun.COM int isfile(char *dir, char *file);
79*9781SMoriah.Waterland@Sun.COM int iscpio(char *path, int *iscomp);
80*9781SMoriah.Waterland@Sun.COM 
81*9781SMoriah.Waterland@Sun.COM /*
82*9781SMoriah.Waterland@Sun.COM  * Name:	isdir
83*9781SMoriah.Waterland@Sun.COM  * Description:	determine if specified path exists and is a directory
84*9781SMoriah.Waterland@Sun.COM  * Arguments:	path - pointer to string representing the path to verify
85*9781SMoriah.Waterland@Sun.COM  * returns: 0 - directory exists
86*9781SMoriah.Waterland@Sun.COM  *	    1 - directory does not exist or is not a directory
87*9781SMoriah.Waterland@Sun.COM  * NOTE:	errno is set appropriately
88*9781SMoriah.Waterland@Sun.COM  */
89*9781SMoriah.Waterland@Sun.COM 
90*9781SMoriah.Waterland@Sun.COM int
91*9781SMoriah.Waterland@Sun.COM isdir(char *path)
92*9781SMoriah.Waterland@Sun.COM {
93*9781SMoriah.Waterland@Sun.COM 	struct stat statbuf;
94*9781SMoriah.Waterland@Sun.COM 
95*9781SMoriah.Waterland@Sun.COM 	/* return error if path does not exist */
96*9781SMoriah.Waterland@Sun.COM 
97*9781SMoriah.Waterland@Sun.COM 	if (stat(path, &statbuf) != 0) {
98*9781SMoriah.Waterland@Sun.COM 		return (1);
99*9781SMoriah.Waterland@Sun.COM 	}
100*9781SMoriah.Waterland@Sun.COM 
101*9781SMoriah.Waterland@Sun.COM 	/* return error if path is not a directory */
102*9781SMoriah.Waterland@Sun.COM 
103*9781SMoriah.Waterland@Sun.COM 	if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
104*9781SMoriah.Waterland@Sun.COM 		errno = ENOTDIR;
105*9781SMoriah.Waterland@Sun.COM 		return (1);
106*9781SMoriah.Waterland@Sun.COM 	}
107*9781SMoriah.Waterland@Sun.COM 
108*9781SMoriah.Waterland@Sun.COM 	return (0);
109*9781SMoriah.Waterland@Sun.COM }
110*9781SMoriah.Waterland@Sun.COM 
111*9781SMoriah.Waterland@Sun.COM /*
112*9781SMoriah.Waterland@Sun.COM  * Name:	isfile
113*9781SMoriah.Waterland@Sun.COM  * Description:	determine if specified path exists and is a directory
114*9781SMoriah.Waterland@Sun.COM  * Arguments:	dir - pointer to string representing the directory where
115*9781SMoriah.Waterland@Sun.COM  *			the file is located
116*9781SMoriah.Waterland@Sun.COM  *			== NULL - use "file" argument only
117*9781SMoriah.Waterland@Sun.COM  *		file - pointer to string representing the file to verify
118*9781SMoriah.Waterland@Sun.COM  * Returns:	0 - success - file exists
119*9781SMoriah.Waterland@Sun.COM  *		1 - failure - file does not exist OR is not a file
120*9781SMoriah.Waterland@Sun.COM  * NOTE:	errno is set appropriately
121*9781SMoriah.Waterland@Sun.COM  */
122*9781SMoriah.Waterland@Sun.COM 
123*9781SMoriah.Waterland@Sun.COM int
124*9781SMoriah.Waterland@Sun.COM isfile(char *dir, char *file)
125*9781SMoriah.Waterland@Sun.COM {
126*9781SMoriah.Waterland@Sun.COM 	struct stat statbuf;
127*9781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
128*9781SMoriah.Waterland@Sun.COM 
129*9781SMoriah.Waterland@Sun.COM 	/* construct full path if directory specified */
130*9781SMoriah.Waterland@Sun.COM 
131*9781SMoriah.Waterland@Sun.COM 	if (dir) {
132*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path), "%s/%s", dir, file);
133*9781SMoriah.Waterland@Sun.COM 		file = path;
134*9781SMoriah.Waterland@Sun.COM 	}
135*9781SMoriah.Waterland@Sun.COM 
136*9781SMoriah.Waterland@Sun.COM 	/* return error if path does not exist */
137*9781SMoriah.Waterland@Sun.COM 
138*9781SMoriah.Waterland@Sun.COM 	if (stat(file, &statbuf) != 0) {
139*9781SMoriah.Waterland@Sun.COM 		return (1);
140*9781SMoriah.Waterland@Sun.COM 	}
141*9781SMoriah.Waterland@Sun.COM 
142*9781SMoriah.Waterland@Sun.COM 	/* return error if path is a directory */
143*9781SMoriah.Waterland@Sun.COM 
144*9781SMoriah.Waterland@Sun.COM 	if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
145*9781SMoriah.Waterland@Sun.COM 		errno = EISDIR;
146*9781SMoriah.Waterland@Sun.COM 		return (1);
147*9781SMoriah.Waterland@Sun.COM 	}
148*9781SMoriah.Waterland@Sun.COM 
149*9781SMoriah.Waterland@Sun.COM 	/* return error if path is not a file */
150*9781SMoriah.Waterland@Sun.COM 
151*9781SMoriah.Waterland@Sun.COM 	if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
152*9781SMoriah.Waterland@Sun.COM 		errno = EINVAL;
153*9781SMoriah.Waterland@Sun.COM 		return (1);
154*9781SMoriah.Waterland@Sun.COM 	}
155*9781SMoriah.Waterland@Sun.COM 
156*9781SMoriah.Waterland@Sun.COM 	return (0);
157*9781SMoriah.Waterland@Sun.COM }
158*9781SMoriah.Waterland@Sun.COM 
159*9781SMoriah.Waterland@Sun.COM int
160*9781SMoriah.Waterland@Sun.COM iscpio(char *path, int *iscomp)
161*9781SMoriah.Waterland@Sun.COM {
162*9781SMoriah.Waterland@Sun.COM 	/*
163*9781SMoriah.Waterland@Sun.COM 	 * Compressed File Header.
164*9781SMoriah.Waterland@Sun.COM 	 */
165*9781SMoriah.Waterland@Sun.COM 	unsigned char m_h[] = { "\037\235" };		/* 1F 9D */
166*9781SMoriah.Waterland@Sun.COM 
167*9781SMoriah.Waterland@Sun.COM 	static union {
168*9781SMoriah.Waterland@Sun.COM 		short int	b_mag;
169*9781SMoriah.Waterland@Sun.COM 		char		c_mag[CMS_LEN];
170*9781SMoriah.Waterland@Sun.COM 	}	cm;
171*9781SMoriah.Waterland@Sun.COM 
172*9781SMoriah.Waterland@Sun.COM 	struct stat	statb;
173*9781SMoriah.Waterland@Sun.COM 	int		fd;
174*9781SMoriah.Waterland@Sun.COM 
175*9781SMoriah.Waterland@Sun.COM 
176*9781SMoriah.Waterland@Sun.COM 	*iscomp = 0;
177*9781SMoriah.Waterland@Sun.COM 
178*9781SMoriah.Waterland@Sun.COM 	if ((fd = open(path, O_RDONLY, 0)) == -1) {
179*9781SMoriah.Waterland@Sun.COM 		if (errno != ENOENT) {
180*9781SMoriah.Waterland@Sun.COM 			perror("");
181*9781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, pkg_gt(ERR_ISCPIO_OPEN), path);
182*9781SMoriah.Waterland@Sun.COM 		}
183*9781SMoriah.Waterland@Sun.COM 		return (0);
184*9781SMoriah.Waterland@Sun.COM 	} else {
185*9781SMoriah.Waterland@Sun.COM 		if (fstat(fd, &statb) == -1) {
186*9781SMoriah.Waterland@Sun.COM 			perror("");
187*9781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, pkg_gt(ERR_ISCPIO_FSTAT), path);
188*9781SMoriah.Waterland@Sun.COM 			(void) close(fd);
189*9781SMoriah.Waterland@Sun.COM 			return (0);
190*9781SMoriah.Waterland@Sun.COM 		} else {
191*9781SMoriah.Waterland@Sun.COM 			if (S_ISREG(statb.st_mode)) {	/* Must be a file */
192*9781SMoriah.Waterland@Sun.COM 				if (read(fd, cm.c_mag, sizeof (cm.c_mag)) !=
193*9781SMoriah.Waterland@Sun.COM 				    sizeof (cm.c_mag)) {
194*9781SMoriah.Waterland@Sun.COM 					perror("");
195*9781SMoriah.Waterland@Sun.COM 					(void) fprintf(stderr,
196*9781SMoriah.Waterland@Sun.COM 					    pkg_gt(ERR_ISCPIO_READ), path);
197*9781SMoriah.Waterland@Sun.COM 					(void) close(fd);
198*9781SMoriah.Waterland@Sun.COM 					return (0);
199*9781SMoriah.Waterland@Sun.COM 				}
200*9781SMoriah.Waterland@Sun.COM 				/*
201*9781SMoriah.Waterland@Sun.COM 				 * Try to determine if the file is a compressed
202*9781SMoriah.Waterland@Sun.COM 				 * file, if that fails, try to determine if it
203*9781SMoriah.Waterland@Sun.COM 				 * is a cpio archive, if that fails, then we
204*9781SMoriah.Waterland@Sun.COM 				 * fail!
205*9781SMoriah.Waterland@Sun.COM 				 */
206*9781SMoriah.Waterland@Sun.COM 				if (ISCOMPCPIO) {
207*9781SMoriah.Waterland@Sun.COM 					*iscomp = 1;
208*9781SMoriah.Waterland@Sun.COM 					(void) close(fd);
209*9781SMoriah.Waterland@Sun.COM 					return (1);
210*9781SMoriah.Waterland@Sun.COM 				} else if (ISCPIO) {
211*9781SMoriah.Waterland@Sun.COM 					(void) fprintf(stderr,
212*9781SMoriah.Waterland@Sun.COM 					    pkg_gt(ERR_ISCPIO_NOCPIO),
213*9781SMoriah.Waterland@Sun.COM 					    path);
214*9781SMoriah.Waterland@Sun.COM 					(void) close(fd);
215*9781SMoriah.Waterland@Sun.COM 					return (0);
216*9781SMoriah.Waterland@Sun.COM 				}
217*9781SMoriah.Waterland@Sun.COM 				(void) close(fd);
218*9781SMoriah.Waterland@Sun.COM 				return (1);
219*9781SMoriah.Waterland@Sun.COM 			} else {
220*9781SMoriah.Waterland@Sun.COM 				(void) close(fd);
221*9781SMoriah.Waterland@Sun.COM 				return (0);
222*9781SMoriah.Waterland@Sun.COM 			}
223*9781SMoriah.Waterland@Sun.COM 		}
224*9781SMoriah.Waterland@Sun.COM 	}
225*9781SMoriah.Waterland@Sun.COM }
226*9781SMoriah.Waterland@Sun.COM 
227*9781SMoriah.Waterland@Sun.COM /*
228*9781SMoriah.Waterland@Sun.COM  * Name:	isPathRemote
229*9781SMoriah.Waterland@Sun.COM  * Description:	determine if a path object is local or remote
230*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_path - [RO, *RO] - (char *)
231*9781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the path to check
232*9781SMoriah.Waterland@Sun.COM  * Returns:	int
233*9781SMoriah.Waterland@Sun.COM  *			1 - the path is remote
234*9781SMoriah.Waterland@Sun.COM  *			0 - the path is local to this system
235*9781SMoriah.Waterland@Sun.COM  *			-1 - cannot determine if path is remote or local
236*9781SMoriah.Waterland@Sun.COM  */
237*9781SMoriah.Waterland@Sun.COM 
238*9781SMoriah.Waterland@Sun.COM int
239*9781SMoriah.Waterland@Sun.COM isPathRemote(char *a_path)
240*9781SMoriah.Waterland@Sun.COM {
241*9781SMoriah.Waterland@Sun.COM 	int		r;
242*9781SMoriah.Waterland@Sun.COM 	struct stat	statbuf;
243*9781SMoriah.Waterland@Sun.COM 
244*9781SMoriah.Waterland@Sun.COM 	r = lstat(a_path, &statbuf);
245*9781SMoriah.Waterland@Sun.COM 	if (r < 0) {
246*9781SMoriah.Waterland@Sun.COM 		return (-1);
247*9781SMoriah.Waterland@Sun.COM 	}
248*9781SMoriah.Waterland@Sun.COM 
249*9781SMoriah.Waterland@Sun.COM 	return (isFstypeRemote(statbuf.st_fstype));
250*9781SMoriah.Waterland@Sun.COM }
251*9781SMoriah.Waterland@Sun.COM 
252*9781SMoriah.Waterland@Sun.COM /*
253*9781SMoriah.Waterland@Sun.COM  * Name:	isFdRemote
254*9781SMoriah.Waterland@Sun.COM  * Description:	determine if an open file is local or remote
255*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_fd - [RO, *RO] - (int)
256*9781SMoriah.Waterland@Sun.COM  *			Integer representing open file to check
257*9781SMoriah.Waterland@Sun.COM  * Returns:	int
258*9781SMoriah.Waterland@Sun.COM  *			1 - the path is remote
259*9781SMoriah.Waterland@Sun.COM  *			0 - the path is local to this system
260*9781SMoriah.Waterland@Sun.COM  *			-1 - cannot determine if path is remote or local
261*9781SMoriah.Waterland@Sun.COM  */
262*9781SMoriah.Waterland@Sun.COM 
263*9781SMoriah.Waterland@Sun.COM int
264*9781SMoriah.Waterland@Sun.COM isFdRemote(int a_fd)
265*9781SMoriah.Waterland@Sun.COM {
266*9781SMoriah.Waterland@Sun.COM 	int		r;
267*9781SMoriah.Waterland@Sun.COM 	struct stat	statbuf;
268*9781SMoriah.Waterland@Sun.COM 
269*9781SMoriah.Waterland@Sun.COM 	r = fstat(a_fd, &statbuf);
270*9781SMoriah.Waterland@Sun.COM 	if (r < 0) {
271*9781SMoriah.Waterland@Sun.COM 		return (-1);
272*9781SMoriah.Waterland@Sun.COM 	}
273*9781SMoriah.Waterland@Sun.COM 
274*9781SMoriah.Waterland@Sun.COM 	return (isFstypeRemote(statbuf.st_fstype));
275*9781SMoriah.Waterland@Sun.COM }
276*9781SMoriah.Waterland@Sun.COM 
277*9781SMoriah.Waterland@Sun.COM /*
278*9781SMoriah.Waterland@Sun.COM  * Name:	isFstypeRemote
279*9781SMoriah.Waterland@Sun.COM  * Description:	determine if a file system type is remote (distributed)
280*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_fstype - [RO, *RO] - (char *)
281*9781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the file system type
282*9781SMoriah.Waterland@Sun.COM  *			to check
283*9781SMoriah.Waterland@Sun.COM  * Returns:	int
284*9781SMoriah.Waterland@Sun.COM  *			1 - the file system type is remote
285*9781SMoriah.Waterland@Sun.COM  *			0 - the file system type is local to this system
286*9781SMoriah.Waterland@Sun.COM  */
287*9781SMoriah.Waterland@Sun.COM 
288*9781SMoriah.Waterland@Sun.COM int
289*9781SMoriah.Waterland@Sun.COM isFstypeRemote(char *a_fstype)
290*9781SMoriah.Waterland@Sun.COM {
291*9781SMoriah.Waterland@Sun.COM 	int	i;
292*9781SMoriah.Waterland@Sun.COM 
293*9781SMoriah.Waterland@Sun.COM 	/* initialize the list if it is not yet initialized */
294*9781SMoriah.Waterland@Sun.COM 
295*9781SMoriah.Waterland@Sun.COM 	_InitRemoteFstypes();
296*9781SMoriah.Waterland@Sun.COM 
297*9781SMoriah.Waterland@Sun.COM 	/* scan the list looking for the specified type */
298*9781SMoriah.Waterland@Sun.COM 
299*9781SMoriah.Waterland@Sun.COM 	for (i = 0; i < numRemoteFstypes; i++) {
300*9781SMoriah.Waterland@Sun.COM 		if (strcmp(remoteFstypes[i], a_fstype) == 0) {
301*9781SMoriah.Waterland@Sun.COM 			return (1);
302*9781SMoriah.Waterland@Sun.COM 		}
303*9781SMoriah.Waterland@Sun.COM 	}
304*9781SMoriah.Waterland@Sun.COM 
305*9781SMoriah.Waterland@Sun.COM 	/* type not found in remote file system type list - is not remote */
306*9781SMoriah.Waterland@Sun.COM 
307*9781SMoriah.Waterland@Sun.COM 	return (0);
308*9781SMoriah.Waterland@Sun.COM }
309*9781SMoriah.Waterland@Sun.COM 
310*9781SMoriah.Waterland@Sun.COM /*
311*9781SMoriah.Waterland@Sun.COM  * Name:	_InitRemoteFstypes
312*9781SMoriah.Waterland@Sun.COM  * Description:	initialize table of remote file system type names
313*9781SMoriah.Waterland@Sun.COM  * Arguments:	none
314*9781SMoriah.Waterland@Sun.COM  * Returns:	none
315*9781SMoriah.Waterland@Sun.COM  * Side Effects:
316*9781SMoriah.Waterland@Sun.COM  *	- The global array "(char **)remoteFstypes" is set to the
317*9781SMoriah.Waterland@Sun.COM  *	  address of an array of string pointers, each of which represents
318*9781SMoriah.Waterland@Sun.COM  *	  a single remote file system type
319*9781SMoriah.Waterland@Sun.COM  *	- The global variable "(long) numRemoteFstypes" is set to the total
320*9781SMoriah.Waterland@Sun.COM  *	  number of remote file system type strings (names) that are
321*9781SMoriah.Waterland@Sun.COM  *	  contained in the "remoteFstypes" global array.
322*9781SMoriah.Waterland@Sun.COM  *	- numRemoteFstypes is initialized to "-1" before any attempt has been
323*9781SMoriah.Waterland@Sun.COM  *	  made to read the remote file system type name database.
324*9781SMoriah.Waterland@Sun.COM  */
325*9781SMoriah.Waterland@Sun.COM static void
326*9781SMoriah.Waterland@Sun.COM _InitRemoteFstypes(void)
327*9781SMoriah.Waterland@Sun.COM {
328*9781SMoriah.Waterland@Sun.COM 	FILE    *fp;
329*9781SMoriah.Waterland@Sun.COM 	char    line_buf[LINE_MAX];
330*9781SMoriah.Waterland@Sun.COM 
331*9781SMoriah.Waterland@Sun.COM 	/* return if already initialized */
332*9781SMoriah.Waterland@Sun.COM 
333*9781SMoriah.Waterland@Sun.COM 	if (numRemoteFstypes > 0) {
334*9781SMoriah.Waterland@Sun.COM 		return;
335*9781SMoriah.Waterland@Sun.COM 	}
336*9781SMoriah.Waterland@Sun.COM 
337*9781SMoriah.Waterland@Sun.COM 	/* if list is uninitialized, start with zero */
338*9781SMoriah.Waterland@Sun.COM 
339*9781SMoriah.Waterland@Sun.COM 	if (numRemoteFstypes == -1) {
340*9781SMoriah.Waterland@Sun.COM 		numRemoteFstypes = 0;
341*9781SMoriah.Waterland@Sun.COM 	}
342*9781SMoriah.Waterland@Sun.COM 
343*9781SMoriah.Waterland@Sun.COM 	/* open the remote file system type database file */
344*9781SMoriah.Waterland@Sun.COM 
345*9781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(REMOTE_FS_DBFILE, "r")) == NULL) {
346*9781SMoriah.Waterland@Sun.COM 		/* no remote type database: use predefined remote types */
347*9781SMoriah.Waterland@Sun.COM 		remoteFstypes = (char **)realloc(remoteFstypes,
348*9781SMoriah.Waterland@Sun.COM 					sizeof (char *) * (numRemoteFstypes+3));
349*9781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = "nfs";	/* +1 */
350*9781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = "autofs";	/* +2 */
351*9781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = "cachefs";	/* +3 */
352*9781SMoriah.Waterland@Sun.COM 		return;
353*9781SMoriah.Waterland@Sun.COM 	}
354*9781SMoriah.Waterland@Sun.COM 
355*9781SMoriah.Waterland@Sun.COM 	/*
356*9781SMoriah.Waterland@Sun.COM 	 * Read the remote file system type database; from fstypes(4):
357*9781SMoriah.Waterland@Sun.COM 	 *
358*9781SMoriah.Waterland@Sun.COM 	 * fstypes resides in directory /etc/dfs and lists distributed file
359*9781SMoriah.Waterland@Sun.COM 	 * system utilities packages installed on the system. For each installed
360*9781SMoriah.Waterland@Sun.COM 	 * distributed file system type, there is a line that begins with the
361*9781SMoriah.Waterland@Sun.COM 	 * file system type name (for example, ``nfs''), followed by white space
362*9781SMoriah.Waterland@Sun.COM 	 * and descriptive text.
363*9781SMoriah.Waterland@Sun.COM 	 *
364*9781SMoriah.Waterland@Sun.COM 	 * Lines will look at lot like this:
365*9781SMoriah.Waterland@Sun.COM 	 *
366*9781SMoriah.Waterland@Sun.COM 	 *	nfs NFS Utilities
367*9781SMoriah.Waterland@Sun.COM 	 *	autofs AUTOFS Utilities
368*9781SMoriah.Waterland@Sun.COM 	 *	cachefs CACHEFS Utilities
369*9781SMoriah.Waterland@Sun.COM 	 */
370*9781SMoriah.Waterland@Sun.COM 
371*9781SMoriah.Waterland@Sun.COM 	while (fgets(line_buf, sizeof (line_buf), fp) != NULL) {
372*9781SMoriah.Waterland@Sun.COM 		char		buf[LINE_MAX];
373*9781SMoriah.Waterland@Sun.COM 		static char	format[128] = {'\0'};
374*9781SMoriah.Waterland@Sun.COM 
375*9781SMoriah.Waterland@Sun.COM 		if (format[0] == '\0') {
376*9781SMoriah.Waterland@Sun.COM 			/* create bounded format: %ns */
377*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(format, sizeof (format),
378*9781SMoriah.Waterland@Sun.COM 				"%%%ds", sizeof (buf)-1);
379*9781SMoriah.Waterland@Sun.COM 		}
380*9781SMoriah.Waterland@Sun.COM 
381*9781SMoriah.Waterland@Sun.COM 		(void) sscanf(line_buf, format, buf);
382*9781SMoriah.Waterland@Sun.COM 
383*9781SMoriah.Waterland@Sun.COM 		remoteFstypes = realloc(remoteFstypes,
384*9781SMoriah.Waterland@Sun.COM 					sizeof (char *) * (numRemoteFstypes+1));
385*9781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = strdup(buf);
386*9781SMoriah.Waterland@Sun.COM 	}
387*9781SMoriah.Waterland@Sun.COM 
388*9781SMoriah.Waterland@Sun.COM 	/* close database file and return */
389*9781SMoriah.Waterland@Sun.COM 
390*9781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
391*9781SMoriah.Waterland@Sun.COM }
392