xref: /onnv-gate/usr/src/lib/libpkg/common/isdir.c (revision 10176:7d4731c42dff)
19781SMoriah.Waterland@Sun.COM /*
29781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
39781SMoriah.Waterland@Sun.COM  *
49781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
59781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
69781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
79781SMoriah.Waterland@Sun.COM  *
89781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
119781SMoriah.Waterland@Sun.COM  * and limitations under the License.
129781SMoriah.Waterland@Sun.COM  *
139781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189781SMoriah.Waterland@Sun.COM  *
199781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
209781SMoriah.Waterland@Sun.COM  */
219781SMoriah.Waterland@Sun.COM 
229781SMoriah.Waterland@Sun.COM /*
23*10176Sok199659  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
249781SMoriah.Waterland@Sun.COM  * Use is subject to license terms.
259781SMoriah.Waterland@Sun.COM  */
269781SMoriah.Waterland@Sun.COM 
279781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
289781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
299781SMoriah.Waterland@Sun.COM 
309781SMoriah.Waterland@Sun.COM 
319781SMoriah.Waterland@Sun.COM #include <stdio.h>
329781SMoriah.Waterland@Sun.COM #include <sys/types.h>
339781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
349781SMoriah.Waterland@Sun.COM #include <archives.h>
359781SMoriah.Waterland@Sun.COM #include <errno.h>
369781SMoriah.Waterland@Sun.COM #include <fcntl.h>
379781SMoriah.Waterland@Sun.COM #include <limits.h>
389781SMoriah.Waterland@Sun.COM #include <stdlib.h>
399781SMoriah.Waterland@Sun.COM #include <unistd.h>
409781SMoriah.Waterland@Sun.COM #include <string.h>
419781SMoriah.Waterland@Sun.COM #include "pkglocale.h"
429781SMoriah.Waterland@Sun.COM #include "pkglibmsgs.h"
439781SMoriah.Waterland@Sun.COM 
449781SMoriah.Waterland@Sun.COM /*
459781SMoriah.Waterland@Sun.COM  * Defines for cpio/compression checks.
469781SMoriah.Waterland@Sun.COM  */
479781SMoriah.Waterland@Sun.COM #define	BIT_MASK		0x1f
489781SMoriah.Waterland@Sun.COM #define	BLOCK_MASK		0x80
499781SMoriah.Waterland@Sun.COM 
509781SMoriah.Waterland@Sun.COM #define	MASK_CK(x, y)	(((x) & (y)) == (y))
519781SMoriah.Waterland@Sun.COM #define	ISCOMPCPIO	((unsigned char) cm.c_mag[0] == m_h[0] && \
529781SMoriah.Waterland@Sun.COM 			(unsigned char) cm.c_mag[1] == m_h[1] && \
539781SMoriah.Waterland@Sun.COM 			(MASK_CK((unsigned char) cm.c_mag[2], BLOCK_MASK) || \
549781SMoriah.Waterland@Sun.COM 			MASK_CK((unsigned char) cm.c_mag[2], BIT_MASK)))
559781SMoriah.Waterland@Sun.COM 
569781SMoriah.Waterland@Sun.COM #define	ISCPIO		(cm.b_mag != CMN_BIN && \
579781SMoriah.Waterland@Sun.COM 			(strcmp(cm.c_mag, CMS_ASC) == 0) && \
589781SMoriah.Waterland@Sun.COM 			(strcmp(cm.c_mag, CMS_CHR) == 0) && \
599781SMoriah.Waterland@Sun.COM 			(strcmp(cm.c_mag, CMS_CRC) == 0))
609781SMoriah.Waterland@Sun.COM 
619781SMoriah.Waterland@Sun.COM /* location of distributed file system types database */
629781SMoriah.Waterland@Sun.COM 
639781SMoriah.Waterland@Sun.COM #define	REMOTE_FS_DBFILE	"/etc/dfs/fstypes"
649781SMoriah.Waterland@Sun.COM 
659781SMoriah.Waterland@Sun.COM /* character array used to hold dfs types database contents */
669781SMoriah.Waterland@Sun.COM 
679781SMoriah.Waterland@Sun.COM static long		numRemoteFstypes = -1;
689781SMoriah.Waterland@Sun.COM static char		**remoteFstypes = (char **)NULL;
699781SMoriah.Waterland@Sun.COM 
709781SMoriah.Waterland@Sun.COM /* forward declarations */
719781SMoriah.Waterland@Sun.COM 
729781SMoriah.Waterland@Sun.COM static void _InitRemoteFstypes(void);
739781SMoriah.Waterland@Sun.COM 
749781SMoriah.Waterland@Sun.COM int isFdRemote(int a_fd);
759781SMoriah.Waterland@Sun.COM int isPathRemote(char *a_path);
769781SMoriah.Waterland@Sun.COM int isFstypeRemote(char *a_fstype);
779781SMoriah.Waterland@Sun.COM int isdir(char *path);
789781SMoriah.Waterland@Sun.COM int isfile(char *dir, char *file);
799781SMoriah.Waterland@Sun.COM int iscpio(char *path, int *iscomp);
809781SMoriah.Waterland@Sun.COM 
819781SMoriah.Waterland@Sun.COM /*
829781SMoriah.Waterland@Sun.COM  * Name:	isdir
839781SMoriah.Waterland@Sun.COM  * Description:	determine if specified path exists and is a directory
849781SMoriah.Waterland@Sun.COM  * Arguments:	path - pointer to string representing the path to verify
859781SMoriah.Waterland@Sun.COM  * returns: 0 - directory exists
869781SMoriah.Waterland@Sun.COM  *	    1 - directory does not exist or is not a directory
879781SMoriah.Waterland@Sun.COM  * NOTE:	errno is set appropriately
889781SMoriah.Waterland@Sun.COM  */
899781SMoriah.Waterland@Sun.COM 
909781SMoriah.Waterland@Sun.COM int
isdir(char * path)919781SMoriah.Waterland@Sun.COM isdir(char *path)
929781SMoriah.Waterland@Sun.COM {
939781SMoriah.Waterland@Sun.COM 	struct stat statbuf;
949781SMoriah.Waterland@Sun.COM 
959781SMoriah.Waterland@Sun.COM 	/* return error if path does not exist */
969781SMoriah.Waterland@Sun.COM 
979781SMoriah.Waterland@Sun.COM 	if (stat(path, &statbuf) != 0) {
989781SMoriah.Waterland@Sun.COM 		return (1);
999781SMoriah.Waterland@Sun.COM 	}
1009781SMoriah.Waterland@Sun.COM 
1019781SMoriah.Waterland@Sun.COM 	/* return error if path is not a directory */
1029781SMoriah.Waterland@Sun.COM 
1039781SMoriah.Waterland@Sun.COM 	if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
1049781SMoriah.Waterland@Sun.COM 		errno = ENOTDIR;
1059781SMoriah.Waterland@Sun.COM 		return (1);
1069781SMoriah.Waterland@Sun.COM 	}
1079781SMoriah.Waterland@Sun.COM 
1089781SMoriah.Waterland@Sun.COM 	return (0);
1099781SMoriah.Waterland@Sun.COM }
1109781SMoriah.Waterland@Sun.COM 
1119781SMoriah.Waterland@Sun.COM /*
1129781SMoriah.Waterland@Sun.COM  * Name:	isfile
1139781SMoriah.Waterland@Sun.COM  * Description:	determine if specified path exists and is a directory
1149781SMoriah.Waterland@Sun.COM  * Arguments:	dir - pointer to string representing the directory where
1159781SMoriah.Waterland@Sun.COM  *			the file is located
1169781SMoriah.Waterland@Sun.COM  *			== NULL - use "file" argument only
1179781SMoriah.Waterland@Sun.COM  *		file - pointer to string representing the file to verify
1189781SMoriah.Waterland@Sun.COM  * Returns:	0 - success - file exists
1199781SMoriah.Waterland@Sun.COM  *		1 - failure - file does not exist OR is not a file
1209781SMoriah.Waterland@Sun.COM  * NOTE:	errno is set appropriately
1219781SMoriah.Waterland@Sun.COM  */
1229781SMoriah.Waterland@Sun.COM 
1239781SMoriah.Waterland@Sun.COM int
isfile(char * dir,char * file)1249781SMoriah.Waterland@Sun.COM isfile(char *dir, char *file)
1259781SMoriah.Waterland@Sun.COM {
1269781SMoriah.Waterland@Sun.COM 	struct stat statbuf;
1279781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
1289781SMoriah.Waterland@Sun.COM 
1299781SMoriah.Waterland@Sun.COM 	/* construct full path if directory specified */
1309781SMoriah.Waterland@Sun.COM 
1319781SMoriah.Waterland@Sun.COM 	if (dir) {
1329781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path), "%s/%s", dir, file);
1339781SMoriah.Waterland@Sun.COM 		file = path;
1349781SMoriah.Waterland@Sun.COM 	}
1359781SMoriah.Waterland@Sun.COM 
1369781SMoriah.Waterland@Sun.COM 	/* return error if path does not exist */
1379781SMoriah.Waterland@Sun.COM 
1389781SMoriah.Waterland@Sun.COM 	if (stat(file, &statbuf) != 0) {
1399781SMoriah.Waterland@Sun.COM 		return (1);
1409781SMoriah.Waterland@Sun.COM 	}
1419781SMoriah.Waterland@Sun.COM 
1429781SMoriah.Waterland@Sun.COM 	/* return error if path is a directory */
1439781SMoriah.Waterland@Sun.COM 
1449781SMoriah.Waterland@Sun.COM 	if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
1459781SMoriah.Waterland@Sun.COM 		errno = EISDIR;
1469781SMoriah.Waterland@Sun.COM 		return (1);
1479781SMoriah.Waterland@Sun.COM 	}
1489781SMoriah.Waterland@Sun.COM 
1499781SMoriah.Waterland@Sun.COM 	/* return error if path is not a file */
1509781SMoriah.Waterland@Sun.COM 
1519781SMoriah.Waterland@Sun.COM 	if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
1529781SMoriah.Waterland@Sun.COM 		errno = EINVAL;
1539781SMoriah.Waterland@Sun.COM 		return (1);
1549781SMoriah.Waterland@Sun.COM 	}
1559781SMoriah.Waterland@Sun.COM 
1569781SMoriah.Waterland@Sun.COM 	return (0);
1579781SMoriah.Waterland@Sun.COM }
1589781SMoriah.Waterland@Sun.COM 
1599781SMoriah.Waterland@Sun.COM int
iscpio(char * path,int * iscomp)1609781SMoriah.Waterland@Sun.COM iscpio(char *path, int *iscomp)
1619781SMoriah.Waterland@Sun.COM {
1629781SMoriah.Waterland@Sun.COM 	/*
1639781SMoriah.Waterland@Sun.COM 	 * Compressed File Header.
1649781SMoriah.Waterland@Sun.COM 	 */
1659781SMoriah.Waterland@Sun.COM 	unsigned char m_h[] = { "\037\235" };		/* 1F 9D */
1669781SMoriah.Waterland@Sun.COM 
1679781SMoriah.Waterland@Sun.COM 	static union {
1689781SMoriah.Waterland@Sun.COM 		short int	b_mag;
1699781SMoriah.Waterland@Sun.COM 		char		c_mag[CMS_LEN];
1709781SMoriah.Waterland@Sun.COM 	}	cm;
1719781SMoriah.Waterland@Sun.COM 
1729781SMoriah.Waterland@Sun.COM 	struct stat	statb;
1739781SMoriah.Waterland@Sun.COM 	int		fd;
1749781SMoriah.Waterland@Sun.COM 
1759781SMoriah.Waterland@Sun.COM 
1769781SMoriah.Waterland@Sun.COM 	*iscomp = 0;
1779781SMoriah.Waterland@Sun.COM 
1789781SMoriah.Waterland@Sun.COM 	if ((fd = open(path, O_RDONLY, 0)) == -1) {
1799781SMoriah.Waterland@Sun.COM 		if (errno != ENOENT) {
1809781SMoriah.Waterland@Sun.COM 			perror("");
1819781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, pkg_gt(ERR_ISCPIO_OPEN), path);
1829781SMoriah.Waterland@Sun.COM 		}
1839781SMoriah.Waterland@Sun.COM 		return (0);
1849781SMoriah.Waterland@Sun.COM 	} else {
1859781SMoriah.Waterland@Sun.COM 		if (fstat(fd, &statb) == -1) {
1869781SMoriah.Waterland@Sun.COM 			perror("");
1879781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, pkg_gt(ERR_ISCPIO_FSTAT), path);
1889781SMoriah.Waterland@Sun.COM 			(void) close(fd);
1899781SMoriah.Waterland@Sun.COM 			return (0);
1909781SMoriah.Waterland@Sun.COM 		} else {
1919781SMoriah.Waterland@Sun.COM 			if (S_ISREG(statb.st_mode)) {	/* Must be a file */
1929781SMoriah.Waterland@Sun.COM 				if (read(fd, cm.c_mag, sizeof (cm.c_mag)) !=
1939781SMoriah.Waterland@Sun.COM 				    sizeof (cm.c_mag)) {
1949781SMoriah.Waterland@Sun.COM 					perror("");
1959781SMoriah.Waterland@Sun.COM 					(void) fprintf(stderr,
1969781SMoriah.Waterland@Sun.COM 					    pkg_gt(ERR_ISCPIO_READ), path);
1979781SMoriah.Waterland@Sun.COM 					(void) close(fd);
1989781SMoriah.Waterland@Sun.COM 					return (0);
1999781SMoriah.Waterland@Sun.COM 				}
2009781SMoriah.Waterland@Sun.COM 				/*
2019781SMoriah.Waterland@Sun.COM 				 * Try to determine if the file is a compressed
2029781SMoriah.Waterland@Sun.COM 				 * file, if that fails, try to determine if it
2039781SMoriah.Waterland@Sun.COM 				 * is a cpio archive, if that fails, then we
2049781SMoriah.Waterland@Sun.COM 				 * fail!
2059781SMoriah.Waterland@Sun.COM 				 */
2069781SMoriah.Waterland@Sun.COM 				if (ISCOMPCPIO) {
2079781SMoriah.Waterland@Sun.COM 					*iscomp = 1;
2089781SMoriah.Waterland@Sun.COM 					(void) close(fd);
2099781SMoriah.Waterland@Sun.COM 					return (1);
2109781SMoriah.Waterland@Sun.COM 				} else if (ISCPIO) {
2119781SMoriah.Waterland@Sun.COM 					(void) fprintf(stderr,
2129781SMoriah.Waterland@Sun.COM 					    pkg_gt(ERR_ISCPIO_NOCPIO),
2139781SMoriah.Waterland@Sun.COM 					    path);
2149781SMoriah.Waterland@Sun.COM 					(void) close(fd);
2159781SMoriah.Waterland@Sun.COM 					return (0);
2169781SMoriah.Waterland@Sun.COM 				}
2179781SMoriah.Waterland@Sun.COM 				(void) close(fd);
2189781SMoriah.Waterland@Sun.COM 				return (1);
2199781SMoriah.Waterland@Sun.COM 			} else {
2209781SMoriah.Waterland@Sun.COM 				(void) close(fd);
2219781SMoriah.Waterland@Sun.COM 				return (0);
2229781SMoriah.Waterland@Sun.COM 			}
2239781SMoriah.Waterland@Sun.COM 		}
2249781SMoriah.Waterland@Sun.COM 	}
2259781SMoriah.Waterland@Sun.COM }
2269781SMoriah.Waterland@Sun.COM 
2279781SMoriah.Waterland@Sun.COM /*
2289781SMoriah.Waterland@Sun.COM  * Name:	isPathRemote
2299781SMoriah.Waterland@Sun.COM  * Description:	determine if a path object is local or remote
2309781SMoriah.Waterland@Sun.COM  * Arguments:	a_path - [RO, *RO] - (char *)
2319781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the path to check
2329781SMoriah.Waterland@Sun.COM  * Returns:	int
2339781SMoriah.Waterland@Sun.COM  *			1 - the path is remote
2349781SMoriah.Waterland@Sun.COM  *			0 - the path is local to this system
2359781SMoriah.Waterland@Sun.COM  *			-1 - cannot determine if path is remote or local
2369781SMoriah.Waterland@Sun.COM  */
2379781SMoriah.Waterland@Sun.COM 
2389781SMoriah.Waterland@Sun.COM int
isPathRemote(char * a_path)2399781SMoriah.Waterland@Sun.COM isPathRemote(char *a_path)
2409781SMoriah.Waterland@Sun.COM {
2419781SMoriah.Waterland@Sun.COM 	int		r;
2429781SMoriah.Waterland@Sun.COM 	struct stat	statbuf;
2439781SMoriah.Waterland@Sun.COM 
2449781SMoriah.Waterland@Sun.COM 	r = lstat(a_path, &statbuf);
2459781SMoriah.Waterland@Sun.COM 	if (r < 0) {
2469781SMoriah.Waterland@Sun.COM 		return (-1);
2479781SMoriah.Waterland@Sun.COM 	}
2489781SMoriah.Waterland@Sun.COM 
2499781SMoriah.Waterland@Sun.COM 	return (isFstypeRemote(statbuf.st_fstype));
2509781SMoriah.Waterland@Sun.COM }
2519781SMoriah.Waterland@Sun.COM 
2529781SMoriah.Waterland@Sun.COM /*
2539781SMoriah.Waterland@Sun.COM  * Name:	isFdRemote
2549781SMoriah.Waterland@Sun.COM  * Description:	determine if an open file is local or remote
2559781SMoriah.Waterland@Sun.COM  * Arguments:	a_fd - [RO, *RO] - (int)
2569781SMoriah.Waterland@Sun.COM  *			Integer representing open file to check
2579781SMoriah.Waterland@Sun.COM  * Returns:	int
2589781SMoriah.Waterland@Sun.COM  *			1 - the path is remote
2599781SMoriah.Waterland@Sun.COM  *			0 - the path is local to this system
2609781SMoriah.Waterland@Sun.COM  *			-1 - cannot determine if path is remote or local
2619781SMoriah.Waterland@Sun.COM  */
2629781SMoriah.Waterland@Sun.COM 
2639781SMoriah.Waterland@Sun.COM int
isFdRemote(int a_fd)2649781SMoriah.Waterland@Sun.COM isFdRemote(int a_fd)
2659781SMoriah.Waterland@Sun.COM {
2669781SMoriah.Waterland@Sun.COM 	int		r;
2679781SMoriah.Waterland@Sun.COM 	struct stat	statbuf;
2689781SMoriah.Waterland@Sun.COM 
2699781SMoriah.Waterland@Sun.COM 	r = fstat(a_fd, &statbuf);
2709781SMoriah.Waterland@Sun.COM 	if (r < 0) {
2719781SMoriah.Waterland@Sun.COM 		return (-1);
2729781SMoriah.Waterland@Sun.COM 	}
2739781SMoriah.Waterland@Sun.COM 
2749781SMoriah.Waterland@Sun.COM 	return (isFstypeRemote(statbuf.st_fstype));
2759781SMoriah.Waterland@Sun.COM }
2769781SMoriah.Waterland@Sun.COM 
2779781SMoriah.Waterland@Sun.COM /*
2789781SMoriah.Waterland@Sun.COM  * Name:	isFstypeRemote
2799781SMoriah.Waterland@Sun.COM  * Description:	determine if a file system type is remote (distributed)
2809781SMoriah.Waterland@Sun.COM  * Arguments:	a_fstype - [RO, *RO] - (char *)
2819781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the file system type
2829781SMoriah.Waterland@Sun.COM  *			to check
2839781SMoriah.Waterland@Sun.COM  * Returns:	int
2849781SMoriah.Waterland@Sun.COM  *			1 - the file system type is remote
2859781SMoriah.Waterland@Sun.COM  *			0 - the file system type is local to this system
2869781SMoriah.Waterland@Sun.COM  */
2879781SMoriah.Waterland@Sun.COM 
2889781SMoriah.Waterland@Sun.COM int
isFstypeRemote(char * a_fstype)2899781SMoriah.Waterland@Sun.COM isFstypeRemote(char *a_fstype)
2909781SMoriah.Waterland@Sun.COM {
2919781SMoriah.Waterland@Sun.COM 	int	i;
2929781SMoriah.Waterland@Sun.COM 
2939781SMoriah.Waterland@Sun.COM 	/* initialize the list if it is not yet initialized */
2949781SMoriah.Waterland@Sun.COM 
2959781SMoriah.Waterland@Sun.COM 	_InitRemoteFstypes();
2969781SMoriah.Waterland@Sun.COM 
2979781SMoriah.Waterland@Sun.COM 	/* scan the list looking for the specified type */
2989781SMoriah.Waterland@Sun.COM 
2999781SMoriah.Waterland@Sun.COM 	for (i = 0; i < numRemoteFstypes; i++) {
3009781SMoriah.Waterland@Sun.COM 		if (strcmp(remoteFstypes[i], a_fstype) == 0) {
3019781SMoriah.Waterland@Sun.COM 			return (1);
3029781SMoriah.Waterland@Sun.COM 		}
3039781SMoriah.Waterland@Sun.COM 	}
3049781SMoriah.Waterland@Sun.COM 
3059781SMoriah.Waterland@Sun.COM 	/* type not found in remote file system type list - is not remote */
3069781SMoriah.Waterland@Sun.COM 
3079781SMoriah.Waterland@Sun.COM 	return (0);
3089781SMoriah.Waterland@Sun.COM }
3099781SMoriah.Waterland@Sun.COM 
3109781SMoriah.Waterland@Sun.COM /*
3119781SMoriah.Waterland@Sun.COM  * Name:	_InitRemoteFstypes
3129781SMoriah.Waterland@Sun.COM  * Description:	initialize table of remote file system type names
3139781SMoriah.Waterland@Sun.COM  * Arguments:	none
3149781SMoriah.Waterland@Sun.COM  * Returns:	none
3159781SMoriah.Waterland@Sun.COM  * Side Effects:
3169781SMoriah.Waterland@Sun.COM  *	- The global array "(char **)remoteFstypes" is set to the
3179781SMoriah.Waterland@Sun.COM  *	  address of an array of string pointers, each of which represents
3189781SMoriah.Waterland@Sun.COM  *	  a single remote file system type
3199781SMoriah.Waterland@Sun.COM  *	- The global variable "(long) numRemoteFstypes" is set to the total
3209781SMoriah.Waterland@Sun.COM  *	  number of remote file system type strings (names) that are
3219781SMoriah.Waterland@Sun.COM  *	  contained in the "remoteFstypes" global array.
3229781SMoriah.Waterland@Sun.COM  *	- numRemoteFstypes is initialized to "-1" before any attempt has been
3239781SMoriah.Waterland@Sun.COM  *	  made to read the remote file system type name database.
3249781SMoriah.Waterland@Sun.COM  */
3259781SMoriah.Waterland@Sun.COM static void
_InitRemoteFstypes(void)3269781SMoriah.Waterland@Sun.COM _InitRemoteFstypes(void)
3279781SMoriah.Waterland@Sun.COM {
3289781SMoriah.Waterland@Sun.COM 	FILE    *fp;
3299781SMoriah.Waterland@Sun.COM 	char    line_buf[LINE_MAX];
3309781SMoriah.Waterland@Sun.COM 
3319781SMoriah.Waterland@Sun.COM 	/* return if already initialized */
3329781SMoriah.Waterland@Sun.COM 
3339781SMoriah.Waterland@Sun.COM 	if (numRemoteFstypes > 0) {
3349781SMoriah.Waterland@Sun.COM 		return;
3359781SMoriah.Waterland@Sun.COM 	}
3369781SMoriah.Waterland@Sun.COM 
3379781SMoriah.Waterland@Sun.COM 	/* if list is uninitialized, start with zero */
3389781SMoriah.Waterland@Sun.COM 
3399781SMoriah.Waterland@Sun.COM 	if (numRemoteFstypes == -1) {
3409781SMoriah.Waterland@Sun.COM 		numRemoteFstypes = 0;
3419781SMoriah.Waterland@Sun.COM 	}
3429781SMoriah.Waterland@Sun.COM 
3439781SMoriah.Waterland@Sun.COM 	/* open the remote file system type database file */
3449781SMoriah.Waterland@Sun.COM 
3459781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(REMOTE_FS_DBFILE, "r")) == NULL) {
3469781SMoriah.Waterland@Sun.COM 		/* no remote type database: use predefined remote types */
3479781SMoriah.Waterland@Sun.COM 		remoteFstypes = (char **)realloc(remoteFstypes,
3489781SMoriah.Waterland@Sun.COM 					sizeof (char *) * (numRemoteFstypes+3));
3499781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = "nfs";	/* +1 */
3509781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = "autofs";	/* +2 */
3519781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = "cachefs";	/* +3 */
3529781SMoriah.Waterland@Sun.COM 		return;
3539781SMoriah.Waterland@Sun.COM 	}
3549781SMoriah.Waterland@Sun.COM 
3559781SMoriah.Waterland@Sun.COM 	/*
3569781SMoriah.Waterland@Sun.COM 	 * Read the remote file system type database; from fstypes(4):
3579781SMoriah.Waterland@Sun.COM 	 *
3589781SMoriah.Waterland@Sun.COM 	 * fstypes resides in directory /etc/dfs and lists distributed file
3599781SMoriah.Waterland@Sun.COM 	 * system utilities packages installed on the system. For each installed
3609781SMoriah.Waterland@Sun.COM 	 * distributed file system type, there is a line that begins with the
3619781SMoriah.Waterland@Sun.COM 	 * file system type name (for example, ``nfs''), followed by white space
3629781SMoriah.Waterland@Sun.COM 	 * and descriptive text.
3639781SMoriah.Waterland@Sun.COM 	 *
3649781SMoriah.Waterland@Sun.COM 	 * Lines will look at lot like this:
3659781SMoriah.Waterland@Sun.COM 	 *
3669781SMoriah.Waterland@Sun.COM 	 *	nfs NFS Utilities
3679781SMoriah.Waterland@Sun.COM 	 *	autofs AUTOFS Utilities
3689781SMoriah.Waterland@Sun.COM 	 *	cachefs CACHEFS Utilities
3699781SMoriah.Waterland@Sun.COM 	 */
3709781SMoriah.Waterland@Sun.COM 
3719781SMoriah.Waterland@Sun.COM 	while (fgets(line_buf, sizeof (line_buf), fp) != NULL) {
3729781SMoriah.Waterland@Sun.COM 		char		buf[LINE_MAX];
3739781SMoriah.Waterland@Sun.COM 		static char	format[128] = {'\0'};
3749781SMoriah.Waterland@Sun.COM 
3759781SMoriah.Waterland@Sun.COM 		if (format[0] == '\0') {
3769781SMoriah.Waterland@Sun.COM 			/* create bounded format: %ns */
3779781SMoriah.Waterland@Sun.COM 			(void) snprintf(format, sizeof (format),
3789781SMoriah.Waterland@Sun.COM 				"%%%ds", sizeof (buf)-1);
3799781SMoriah.Waterland@Sun.COM 		}
3809781SMoriah.Waterland@Sun.COM 
3819781SMoriah.Waterland@Sun.COM 		(void) sscanf(line_buf, format, buf);
3829781SMoriah.Waterland@Sun.COM 
3839781SMoriah.Waterland@Sun.COM 		remoteFstypes = realloc(remoteFstypes,
3849781SMoriah.Waterland@Sun.COM 					sizeof (char *) * (numRemoteFstypes+1));
3859781SMoriah.Waterland@Sun.COM 		remoteFstypes[numRemoteFstypes++] = strdup(buf);
3869781SMoriah.Waterland@Sun.COM 	}
3879781SMoriah.Waterland@Sun.COM 
3889781SMoriah.Waterland@Sun.COM 	/* close database file and return */
3899781SMoriah.Waterland@Sun.COM 
3909781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
3919781SMoriah.Waterland@Sun.COM }
392