4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
33 #include <sys/types.h>
42 #include "pkglocale.h"
43 #include "pkglibmsgs.h"
46 * Defines for cpio/compression checks.
49 #define BLOCK_MASK 0x80
51 #define MASK_CK(x, y) (((x) & (y)) == (y))
52 #define ISCOMPCPIO ((unsigned char) cm.c_mag[0] == m_h[0] && \
53 (unsigned char) cm.c_mag[1] == m_h[1] && \
54 (MASK_CK((unsigned char) cm.c_mag[2], BLOCK_MASK) || \
55 MASK_CK((unsigned char) cm.c_mag[2], BIT_MASK)))
57 #define ISCPIO (cm.b_mag != CMN_BIN && \
58 (strcmp(cm.c_mag, CMS_ASC) == 0) && \
59 (strcmp(cm.c_mag, CMS_CHR) == 0) && \
60 (strcmp(cm.c_mag, CMS_CRC) == 0))
62 /* location of distributed file system types database */
64 #define REMOTE_FS_DBFILE "/etc/dfs/fstypes"
66 /* character array used to hold dfs types database contents */
68 static long numRemoteFstypes
= -1;
69 static char **remoteFstypes
= (char **)NULL
;
71 /* forward declarations */
73 static void _InitRemoteFstypes(void);
75 int isFdRemote(int a_fd
);
76 int isPathRemote(char *a_path
);
77 int isFstypeRemote(char *a_fstype
);
78 int isdir(char *path
);
79 int isfile(char *dir
, char *file
);
80 int iscpio(char *path
, int *iscomp
);
84 * Description: determine if specified path exists and is a directory
85 * Arguments: path - pointer to string representing the path to verify
86 * returns: 0 - directory exists
87 * 1 - directory does not exist or is not a directory
88 * NOTE: errno is set appropriately
96 /* return error if path does not exist */
98 if (stat(path
, &statbuf
) != 0) {
102 /* return error if path is not a directory */
104 if ((statbuf
.st_mode
& S_IFMT
) != S_IFDIR
) {
114 * Description: determine if specified path exists and is a directory
115 * Arguments: dir - pointer to string representing the directory where
116 * the file is located
117 * == NULL - use "file" argument only
118 * file - pointer to string representing the file to verify
119 * Returns: 0 - success - file exists
120 * 1 - failure - file does not exist OR is not a file
121 * NOTE: errno is set appropriately
125 isfile(char *dir
, char *file
)
130 /* construct full path if directory specified */
133 (void) snprintf(path
, sizeof (path
), "%s/%s", dir
, file
);
137 /* return error if path does not exist */
139 if (stat(file
, &statbuf
) != 0) {
143 /* return error if path is a directory */
145 if ((statbuf
.st_mode
& S_IFMT
) == S_IFDIR
) {
150 /* return error if path is not a file */
152 if ((statbuf
.st_mode
& S_IFMT
) != S_IFREG
) {
161 iscpio(char *path
, int *iscomp
)
164 * Compressed File Header.
166 unsigned char m_h
[] = { "\037\235" }; /* 1F 9D */
179 if ((fd
= open(path
, O_RDONLY
, 0)) == -1) {
180 if (errno
!= ENOENT
) {
182 (void) fprintf(stderr
, pkg_gt(ERR_ISCPIO_OPEN
), path
);
186 if (fstat(fd
, &statb
) == -1) {
188 (void) fprintf(stderr
, pkg_gt(ERR_ISCPIO_FSTAT
), path
);
192 if (S_ISREG(statb
.st_mode
)) { /* Must be a file */
193 if (read(fd
, cm
.c_mag
, sizeof (cm
.c_mag
)) !=
196 (void) fprintf(stderr
,
197 pkg_gt(ERR_ISCPIO_READ
), path
);
202 * Try to determine if the file is a compressed
203 * file, if that fails, try to determine if it
204 * is a cpio archive, if that fails, then we
212 (void) fprintf(stderr
,
213 pkg_gt(ERR_ISCPIO_NOCPIO
),
230 * Description: determine if a path object is local or remote
231 * Arguments: a_path - [RO, *RO] - (char *)
232 * Pointer to string representing the path to check
234 * 1 - the path is remote
235 * 0 - the path is local to this system
236 * -1 - cannot determine if path is remote or local
240 isPathRemote(char *a_path
)
245 r
= lstat(a_path
, &statbuf
);
250 return (isFstypeRemote(statbuf
.st_fstype
));
255 * Description: determine if an open file is local or remote
256 * Arguments: a_fd - [RO, *RO] - (int)
257 * Integer representing open file to check
259 * 1 - the path is remote
260 * 0 - the path is local to this system
261 * -1 - cannot determine if path is remote or local
270 r
= fstat(a_fd
, &statbuf
);
275 return (isFstypeRemote(statbuf
.st_fstype
));
279 * Name: isFstypeRemote
280 * Description: determine if a file system type is remote (distributed)
281 * Arguments: a_fstype - [RO, *RO] - (char *)
282 * Pointer to string representing the file system type
285 * 1 - the file system type is remote
286 * 0 - the file system type is local to this system
290 isFstypeRemote(char *a_fstype
)
294 /* initialize the list if it is not yet initialized */
296 _InitRemoteFstypes();
298 /* scan the list looking for the specified type */
300 for (i
= 0; i
< numRemoteFstypes
; i
++) {
301 if (strcmp(remoteFstypes
[i
], a_fstype
) == 0) {
306 /* type not found in remote file system type list - is not remote */
312 * Name: _InitRemoteFstypes
313 * Description: initialize table of remote file system type names
317 * - The global array "(char **)remoteFstypes" is set to the
318 * address of an array of string pointers, each of which represents
319 * a single remote file system type
320 * - The global variable "(long) numRemoteFstypes" is set to the total
321 * number of remote file system type strings (names) that are
322 * contained in the "remoteFstypes" global array.
323 * - numRemoteFstypes is initialized to "-1" before any attempt has been
324 * made to read the remote file system type name database.
327 _InitRemoteFstypes(void)
330 char line_buf
[LINE_MAX
];
332 /* return if already initialized */
334 if (numRemoteFstypes
> 0) {
338 /* if list is uninitialized, start with zero */
340 if (numRemoteFstypes
== -1) {
341 numRemoteFstypes
= 0;
344 /* open the remote file system type database file */
346 if ((fp
= fopen(REMOTE_FS_DBFILE
, "r")) == NULL
) {
347 /* no remote type database: use predefined remote types */
348 remoteFstypes
= (char **)realloc(remoteFstypes
,
349 sizeof (char *) * (numRemoteFstypes
+2));
350 remoteFstypes
[numRemoteFstypes
++] = "nfs"; /* +1 */
351 remoteFstypes
[numRemoteFstypes
++] = "autofs"; /* +2 */
356 * Read the remote file system type database; from fstypes(4):
358 * fstypes resides in directory /etc/dfs and lists distributed file
359 * system utilities packages installed on the system. For each installed
360 * distributed file system type, there is a line that begins with the
361 * file system type name (for example, ``nfs''), followed by white space
362 * and descriptive text.
364 * Lines will look at lot like this:
367 * autofs AUTOFS Utilities
370 while (fgets(line_buf
, sizeof (line_buf
), fp
) != NULL
) {
372 static char format
[128] = {'\0'};
374 if (format
[0] == '\0') {
375 /* create bounded format: %ns */
376 (void) snprintf(format
, sizeof (format
),
377 "%%%ds", sizeof (buf
)-1);
380 (void) sscanf(line_buf
, format
, buf
);
382 remoteFstypes
= realloc(remoteFstypes
,
383 sizeof (char *) * (numRemoteFstypes
+1));
384 remoteFstypes
[numRemoteFstypes
++] = strdup(buf
);
387 /* close database file and return */