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