15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland * CDDL HEADER START
35c51f124SMoriah Waterland *
45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland *
85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland * See the License for the specific language governing permissions
115c51f124SMoriah Waterland * and limitations under the License.
125c51f124SMoriah Waterland *
135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland *
195c51f124SMoriah Waterland * CDDL HEADER END
205c51f124SMoriah Waterland */
215c51f124SMoriah Waterland
225c51f124SMoriah Waterland /*
23*b46ec01aSok199659 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
245c51f124SMoriah Waterland * Use is subject to license terms.
255c51f124SMoriah Waterland */
265c51f124SMoriah Waterland
275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
285c51f124SMoriah Waterland /* All Rights Reserved */
295c51f124SMoriah Waterland
305c51f124SMoriah Waterland
315c51f124SMoriah Waterland #include <stdio.h>
325c51f124SMoriah Waterland #include <sys/types.h>
335c51f124SMoriah Waterland #include <sys/stat.h>
345c51f124SMoriah Waterland #include <archives.h>
355c51f124SMoriah Waterland #include <errno.h>
365c51f124SMoriah Waterland #include <fcntl.h>
375c51f124SMoriah Waterland #include <limits.h>
385c51f124SMoriah Waterland #include <stdlib.h>
395c51f124SMoriah Waterland #include <unistd.h>
405c51f124SMoriah Waterland #include <string.h>
415c51f124SMoriah Waterland #include "pkglocale.h"
425c51f124SMoriah Waterland #include "pkglibmsgs.h"
435c51f124SMoriah Waterland
445c51f124SMoriah Waterland /*
455c51f124SMoriah Waterland * Defines for cpio/compression checks.
465c51f124SMoriah Waterland */
475c51f124SMoriah Waterland #define BIT_MASK 0x1f
485c51f124SMoriah Waterland #define BLOCK_MASK 0x80
495c51f124SMoriah Waterland
505c51f124SMoriah Waterland #define MASK_CK(x, y) (((x) & (y)) == (y))
515c51f124SMoriah Waterland #define ISCOMPCPIO ((unsigned char) cm.c_mag[0] == m_h[0] && \
525c51f124SMoriah Waterland (unsigned char) cm.c_mag[1] == m_h[1] && \
535c51f124SMoriah Waterland (MASK_CK((unsigned char) cm.c_mag[2], BLOCK_MASK) || \
545c51f124SMoriah Waterland MASK_CK((unsigned char) cm.c_mag[2], BIT_MASK)))
555c51f124SMoriah Waterland
565c51f124SMoriah Waterland #define ISCPIO (cm.b_mag != CMN_BIN && \
575c51f124SMoriah Waterland (strcmp(cm.c_mag, CMS_ASC) == 0) && \
585c51f124SMoriah Waterland (strcmp(cm.c_mag, CMS_CHR) == 0) && \
595c51f124SMoriah Waterland (strcmp(cm.c_mag, CMS_CRC) == 0))
605c51f124SMoriah Waterland
615c51f124SMoriah Waterland /* location of distributed file system types database */
625c51f124SMoriah Waterland
635c51f124SMoriah Waterland #define REMOTE_FS_DBFILE "/etc/dfs/fstypes"
645c51f124SMoriah Waterland
655c51f124SMoriah Waterland /* character array used to hold dfs types database contents */
665c51f124SMoriah Waterland
675c51f124SMoriah Waterland static long numRemoteFstypes = -1;
685c51f124SMoriah Waterland static char **remoteFstypes = (char **)NULL;
695c51f124SMoriah Waterland
705c51f124SMoriah Waterland /* forward declarations */
715c51f124SMoriah Waterland
725c51f124SMoriah Waterland static void _InitRemoteFstypes(void);
735c51f124SMoriah Waterland
745c51f124SMoriah Waterland int isFdRemote(int a_fd);
755c51f124SMoriah Waterland int isPathRemote(char *a_path);
765c51f124SMoriah Waterland int isFstypeRemote(char *a_fstype);
775c51f124SMoriah Waterland int isdir(char *path);
785c51f124SMoriah Waterland int isfile(char *dir, char *file);
795c51f124SMoriah Waterland int iscpio(char *path, int *iscomp);
805c51f124SMoriah Waterland
815c51f124SMoriah Waterland /*
825c51f124SMoriah Waterland * Name: isdir
835c51f124SMoriah Waterland * Description: determine if specified path exists and is a directory
845c51f124SMoriah Waterland * Arguments: path - pointer to string representing the path to verify
855c51f124SMoriah Waterland * returns: 0 - directory exists
865c51f124SMoriah Waterland * 1 - directory does not exist or is not a directory
875c51f124SMoriah Waterland * NOTE: errno is set appropriately
885c51f124SMoriah Waterland */
895c51f124SMoriah Waterland
905c51f124SMoriah Waterland int
isdir(char * path)915c51f124SMoriah Waterland isdir(char *path)
925c51f124SMoriah Waterland {
935c51f124SMoriah Waterland struct stat statbuf;
945c51f124SMoriah Waterland
955c51f124SMoriah Waterland /* return error if path does not exist */
965c51f124SMoriah Waterland
975c51f124SMoriah Waterland if (stat(path, &statbuf) != 0) {
985c51f124SMoriah Waterland return (1);
995c51f124SMoriah Waterland }
1005c51f124SMoriah Waterland
1015c51f124SMoriah Waterland /* return error if path is not a directory */
1025c51f124SMoriah Waterland
1035c51f124SMoriah Waterland if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
1045c51f124SMoriah Waterland errno = ENOTDIR;
1055c51f124SMoriah Waterland return (1);
1065c51f124SMoriah Waterland }
1075c51f124SMoriah Waterland
1085c51f124SMoriah Waterland return (0);
1095c51f124SMoriah Waterland }
1105c51f124SMoriah Waterland
1115c51f124SMoriah Waterland /*
1125c51f124SMoriah Waterland * Name: isfile
1135c51f124SMoriah Waterland * Description: determine if specified path exists and is a directory
1145c51f124SMoriah Waterland * Arguments: dir - pointer to string representing the directory where
1155c51f124SMoriah Waterland * the file is located
1165c51f124SMoriah Waterland * == NULL - use "file" argument only
1175c51f124SMoriah Waterland * file - pointer to string representing the file to verify
1185c51f124SMoriah Waterland * Returns: 0 - success - file exists
1195c51f124SMoriah Waterland * 1 - failure - file does not exist OR is not a file
1205c51f124SMoriah Waterland * NOTE: errno is set appropriately
1215c51f124SMoriah Waterland */
1225c51f124SMoriah Waterland
1235c51f124SMoriah Waterland int
isfile(char * dir,char * file)1245c51f124SMoriah Waterland isfile(char *dir, char *file)
1255c51f124SMoriah Waterland {
1265c51f124SMoriah Waterland struct stat statbuf;
1275c51f124SMoriah Waterland char path[PATH_MAX];
1285c51f124SMoriah Waterland
1295c51f124SMoriah Waterland /* construct full path if directory specified */
1305c51f124SMoriah Waterland
1315c51f124SMoriah Waterland if (dir) {
1325c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s/%s", dir, file);
1335c51f124SMoriah Waterland file = path;
1345c51f124SMoriah Waterland }
1355c51f124SMoriah Waterland
1365c51f124SMoriah Waterland /* return error if path does not exist */
1375c51f124SMoriah Waterland
1385c51f124SMoriah Waterland if (stat(file, &statbuf) != 0) {
1395c51f124SMoriah Waterland return (1);
1405c51f124SMoriah Waterland }
1415c51f124SMoriah Waterland
1425c51f124SMoriah Waterland /* return error if path is a directory */
1435c51f124SMoriah Waterland
1445c51f124SMoriah Waterland if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
1455c51f124SMoriah Waterland errno = EISDIR;
1465c51f124SMoriah Waterland return (1);
1475c51f124SMoriah Waterland }
1485c51f124SMoriah Waterland
1495c51f124SMoriah Waterland /* return error if path is not a file */
1505c51f124SMoriah Waterland
1515c51f124SMoriah Waterland if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
1525c51f124SMoriah Waterland errno = EINVAL;
1535c51f124SMoriah Waterland return (1);
1545c51f124SMoriah Waterland }
1555c51f124SMoriah Waterland
1565c51f124SMoriah Waterland return (0);
1575c51f124SMoriah Waterland }
1585c51f124SMoriah Waterland
1595c51f124SMoriah Waterland int
iscpio(char * path,int * iscomp)1605c51f124SMoriah Waterland iscpio(char *path, int *iscomp)
1615c51f124SMoriah Waterland {
1625c51f124SMoriah Waterland /*
1635c51f124SMoriah Waterland * Compressed File Header.
1645c51f124SMoriah Waterland */
1655c51f124SMoriah Waterland unsigned char m_h[] = { "\037\235" }; /* 1F 9D */
1665c51f124SMoriah Waterland
1675c51f124SMoriah Waterland static union {
1685c51f124SMoriah Waterland short int b_mag;
1695c51f124SMoriah Waterland char c_mag[CMS_LEN];
1705c51f124SMoriah Waterland } cm;
1715c51f124SMoriah Waterland
1725c51f124SMoriah Waterland struct stat statb;
1735c51f124SMoriah Waterland int fd;
1745c51f124SMoriah Waterland
1755c51f124SMoriah Waterland
1765c51f124SMoriah Waterland *iscomp = 0;
1775c51f124SMoriah Waterland
1785c51f124SMoriah Waterland if ((fd = open(path, O_RDONLY, 0)) == -1) {
1795c51f124SMoriah Waterland if (errno != ENOENT) {
1805c51f124SMoriah Waterland perror("");
1815c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_ISCPIO_OPEN), path);
1825c51f124SMoriah Waterland }
1835c51f124SMoriah Waterland return (0);
1845c51f124SMoriah Waterland } else {
1855c51f124SMoriah Waterland if (fstat(fd, &statb) == -1) {
1865c51f124SMoriah Waterland perror("");
1875c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_ISCPIO_FSTAT), path);
1885c51f124SMoriah Waterland (void) close(fd);
1895c51f124SMoriah Waterland return (0);
1905c51f124SMoriah Waterland } else {
1915c51f124SMoriah Waterland if (S_ISREG(statb.st_mode)) { /* Must be a file */
1925c51f124SMoriah Waterland if (read(fd, cm.c_mag, sizeof (cm.c_mag)) !=
1935c51f124SMoriah Waterland sizeof (cm.c_mag)) {
1945c51f124SMoriah Waterland perror("");
1955c51f124SMoriah Waterland (void) fprintf(stderr,
1965c51f124SMoriah Waterland pkg_gt(ERR_ISCPIO_READ), path);
1975c51f124SMoriah Waterland (void) close(fd);
1985c51f124SMoriah Waterland return (0);
1995c51f124SMoriah Waterland }
2005c51f124SMoriah Waterland /*
2015c51f124SMoriah Waterland * Try to determine if the file is a compressed
2025c51f124SMoriah Waterland * file, if that fails, try to determine if it
2035c51f124SMoriah Waterland * is a cpio archive, if that fails, then we
2045c51f124SMoriah Waterland * fail!
2055c51f124SMoriah Waterland */
2065c51f124SMoriah Waterland if (ISCOMPCPIO) {
2075c51f124SMoriah Waterland *iscomp = 1;
2085c51f124SMoriah Waterland (void) close(fd);
2095c51f124SMoriah Waterland return (1);
2105c51f124SMoriah Waterland } else if (ISCPIO) {
2115c51f124SMoriah Waterland (void) fprintf(stderr,
2125c51f124SMoriah Waterland pkg_gt(ERR_ISCPIO_NOCPIO),
2135c51f124SMoriah Waterland path);
2145c51f124SMoriah Waterland (void) close(fd);
2155c51f124SMoriah Waterland return (0);
2165c51f124SMoriah Waterland }
2175c51f124SMoriah Waterland (void) close(fd);
2185c51f124SMoriah Waterland return (1);
2195c51f124SMoriah Waterland } else {
2205c51f124SMoriah Waterland (void) close(fd);
2215c51f124SMoriah Waterland return (0);
2225c51f124SMoriah Waterland }
2235c51f124SMoriah Waterland }
2245c51f124SMoriah Waterland }
2255c51f124SMoriah Waterland }
2265c51f124SMoriah Waterland
2275c51f124SMoriah Waterland /*
2285c51f124SMoriah Waterland * Name: isPathRemote
2295c51f124SMoriah Waterland * Description: determine if a path object is local or remote
2305c51f124SMoriah Waterland * Arguments: a_path - [RO, *RO] - (char *)
2315c51f124SMoriah Waterland * Pointer to string representing the path to check
2325c51f124SMoriah Waterland * Returns: int
2335c51f124SMoriah Waterland * 1 - the path is remote
2345c51f124SMoriah Waterland * 0 - the path is local to this system
2355c51f124SMoriah Waterland * -1 - cannot determine if path is remote or local
2365c51f124SMoriah Waterland */
2375c51f124SMoriah Waterland
2385c51f124SMoriah Waterland int
isPathRemote(char * a_path)2395c51f124SMoriah Waterland isPathRemote(char *a_path)
2405c51f124SMoriah Waterland {
2415c51f124SMoriah Waterland int r;
2425c51f124SMoriah Waterland struct stat statbuf;
2435c51f124SMoriah Waterland
2445c51f124SMoriah Waterland r = lstat(a_path, &statbuf);
2455c51f124SMoriah Waterland if (r < 0) {
2465c51f124SMoriah Waterland return (-1);
2475c51f124SMoriah Waterland }
2485c51f124SMoriah Waterland
2495c51f124SMoriah Waterland return (isFstypeRemote(statbuf.st_fstype));
2505c51f124SMoriah Waterland }
2515c51f124SMoriah Waterland
2525c51f124SMoriah Waterland /*
2535c51f124SMoriah Waterland * Name: isFdRemote
2545c51f124SMoriah Waterland * Description: determine if an open file is local or remote
2555c51f124SMoriah Waterland * Arguments: a_fd - [RO, *RO] - (int)
2565c51f124SMoriah Waterland * Integer representing open file to check
2575c51f124SMoriah Waterland * Returns: int
2585c51f124SMoriah Waterland * 1 - the path is remote
2595c51f124SMoriah Waterland * 0 - the path is local to this system
2605c51f124SMoriah Waterland * -1 - cannot determine if path is remote or local
2615c51f124SMoriah Waterland */
2625c51f124SMoriah Waterland
2635c51f124SMoriah Waterland int
isFdRemote(int a_fd)2645c51f124SMoriah Waterland isFdRemote(int a_fd)
2655c51f124SMoriah Waterland {
2665c51f124SMoriah Waterland int r;
2675c51f124SMoriah Waterland struct stat statbuf;
2685c51f124SMoriah Waterland
2695c51f124SMoriah Waterland r = fstat(a_fd, &statbuf);
2705c51f124SMoriah Waterland if (r < 0) {
2715c51f124SMoriah Waterland return (-1);
2725c51f124SMoriah Waterland }
2735c51f124SMoriah Waterland
2745c51f124SMoriah Waterland return (isFstypeRemote(statbuf.st_fstype));
2755c51f124SMoriah Waterland }
2765c51f124SMoriah Waterland
2775c51f124SMoriah Waterland /*
2785c51f124SMoriah Waterland * Name: isFstypeRemote
2795c51f124SMoriah Waterland * Description: determine if a file system type is remote (distributed)
2805c51f124SMoriah Waterland * Arguments: a_fstype - [RO, *RO] - (char *)
2815c51f124SMoriah Waterland * Pointer to string representing the file system type
2825c51f124SMoriah Waterland * to check
2835c51f124SMoriah Waterland * Returns: int
2845c51f124SMoriah Waterland * 1 - the file system type is remote
2855c51f124SMoriah Waterland * 0 - the file system type is local to this system
2865c51f124SMoriah Waterland */
2875c51f124SMoriah Waterland
2885c51f124SMoriah Waterland int
isFstypeRemote(char * a_fstype)2895c51f124SMoriah Waterland isFstypeRemote(char *a_fstype)
2905c51f124SMoriah Waterland {
2915c51f124SMoriah Waterland int i;
2925c51f124SMoriah Waterland
2935c51f124SMoriah Waterland /* initialize the list if it is not yet initialized */
2945c51f124SMoriah Waterland
2955c51f124SMoriah Waterland _InitRemoteFstypes();
2965c51f124SMoriah Waterland
2975c51f124SMoriah Waterland /* scan the list looking for the specified type */
2985c51f124SMoriah Waterland
2995c51f124SMoriah Waterland for (i = 0; i < numRemoteFstypes; i++) {
3005c51f124SMoriah Waterland if (strcmp(remoteFstypes[i], a_fstype) == 0) {
3015c51f124SMoriah Waterland return (1);
3025c51f124SMoriah Waterland }
3035c51f124SMoriah Waterland }
3045c51f124SMoriah Waterland
3055c51f124SMoriah Waterland /* type not found in remote file system type list - is not remote */
3065c51f124SMoriah Waterland
3075c51f124SMoriah Waterland return (0);
3085c51f124SMoriah Waterland }
3095c51f124SMoriah Waterland
3105c51f124SMoriah Waterland /*
3115c51f124SMoriah Waterland * Name: _InitRemoteFstypes
3125c51f124SMoriah Waterland * Description: initialize table of remote file system type names
3135c51f124SMoriah Waterland * Arguments: none
3145c51f124SMoriah Waterland * Returns: none
3155c51f124SMoriah Waterland * Side Effects:
3165c51f124SMoriah Waterland * - The global array "(char **)remoteFstypes" is set to the
3175c51f124SMoriah Waterland * address of an array of string pointers, each of which represents
3185c51f124SMoriah Waterland * a single remote file system type
3195c51f124SMoriah Waterland * - The global variable "(long) numRemoteFstypes" is set to the total
3205c51f124SMoriah Waterland * number of remote file system type strings (names) that are
3215c51f124SMoriah Waterland * contained in the "remoteFstypes" global array.
3225c51f124SMoriah Waterland * - numRemoteFstypes is initialized to "-1" before any attempt has been
3235c51f124SMoriah Waterland * made to read the remote file system type name database.
3245c51f124SMoriah Waterland */
3255c51f124SMoriah Waterland static void
_InitRemoteFstypes(void)3265c51f124SMoriah Waterland _InitRemoteFstypes(void)
3275c51f124SMoriah Waterland {
3285c51f124SMoriah Waterland FILE *fp;
3295c51f124SMoriah Waterland char line_buf[LINE_MAX];
3305c51f124SMoriah Waterland
3315c51f124SMoriah Waterland /* return if already initialized */
3325c51f124SMoriah Waterland
3335c51f124SMoriah Waterland if (numRemoteFstypes > 0) {
3345c51f124SMoriah Waterland return;
3355c51f124SMoriah Waterland }
3365c51f124SMoriah Waterland
3375c51f124SMoriah Waterland /* if list is uninitialized, start with zero */
3385c51f124SMoriah Waterland
3395c51f124SMoriah Waterland if (numRemoteFstypes == -1) {
3405c51f124SMoriah Waterland numRemoteFstypes = 0;
3415c51f124SMoriah Waterland }
3425c51f124SMoriah Waterland
3435c51f124SMoriah Waterland /* open the remote file system type database file */
3445c51f124SMoriah Waterland
3455c51f124SMoriah Waterland if ((fp = fopen(REMOTE_FS_DBFILE, "r")) == NULL) {
3465c51f124SMoriah Waterland /* no remote type database: use predefined remote types */
3475c51f124SMoriah Waterland remoteFstypes = (char **)realloc(remoteFstypes,
3485c51f124SMoriah Waterland sizeof (char *) * (numRemoteFstypes+3));
3495c51f124SMoriah Waterland remoteFstypes[numRemoteFstypes++] = "nfs"; /* +1 */
3505c51f124SMoriah Waterland remoteFstypes[numRemoteFstypes++] = "autofs"; /* +2 */
3515c51f124SMoriah Waterland remoteFstypes[numRemoteFstypes++] = "cachefs"; /* +3 */
3525c51f124SMoriah Waterland return;
3535c51f124SMoriah Waterland }
3545c51f124SMoriah Waterland
3555c51f124SMoriah Waterland /*
3565c51f124SMoriah Waterland * Read the remote file system type database; from fstypes(4):
3575c51f124SMoriah Waterland *
3585c51f124SMoriah Waterland * fstypes resides in directory /etc/dfs and lists distributed file
3595c51f124SMoriah Waterland * system utilities packages installed on the system. For each installed
3605c51f124SMoriah Waterland * distributed file system type, there is a line that begins with the
3615c51f124SMoriah Waterland * file system type name (for example, ``nfs''), followed by white space
3625c51f124SMoriah Waterland * and descriptive text.
3635c51f124SMoriah Waterland *
3645c51f124SMoriah Waterland * Lines will look at lot like this:
3655c51f124SMoriah Waterland *
3665c51f124SMoriah Waterland * nfs NFS Utilities
3675c51f124SMoriah Waterland * autofs AUTOFS Utilities
3685c51f124SMoriah Waterland * cachefs CACHEFS Utilities
3695c51f124SMoriah Waterland */
3705c51f124SMoriah Waterland
3715c51f124SMoriah Waterland while (fgets(line_buf, sizeof (line_buf), fp) != NULL) {
3725c51f124SMoriah Waterland char buf[LINE_MAX];
3735c51f124SMoriah Waterland static char format[128] = {'\0'};
3745c51f124SMoriah Waterland
3755c51f124SMoriah Waterland if (format[0] == '\0') {
3765c51f124SMoriah Waterland /* create bounded format: %ns */
3775c51f124SMoriah Waterland (void) snprintf(format, sizeof (format),
3785c51f124SMoriah Waterland "%%%ds", sizeof (buf)-1);
3795c51f124SMoriah Waterland }
3805c51f124SMoriah Waterland
3815c51f124SMoriah Waterland (void) sscanf(line_buf, format, buf);
3825c51f124SMoriah Waterland
3835c51f124SMoriah Waterland remoteFstypes = realloc(remoteFstypes,
3845c51f124SMoriah Waterland sizeof (char *) * (numRemoteFstypes+1));
3855c51f124SMoriah Waterland remoteFstypes[numRemoteFstypes++] = strdup(buf);
3865c51f124SMoriah Waterland }
3875c51f124SMoriah Waterland
3885c51f124SMoriah Waterland /* close database file and return */
3895c51f124SMoriah Waterland
3905c51f124SMoriah Waterland (void) fclose(fp);
3915c51f124SMoriah Waterland }
392