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