2 * Copyright (c) 2007-2014, Juniper Networks, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
33 #include <sys/stdint.h>
38 #define DBG(x) printf x
43 static int pkg_open(const char *, struct open_file
*);
44 static int pkg_close(struct open_file
*);
45 static int pkg_read(struct open_file
*, void *, size_t, size_t *);
46 static off_t
pkg_seek(struct open_file
*, off_t
, int);
47 static int pkg_stat(struct open_file
*, struct stat
*);
48 static int pkg_readdir(struct open_file
*, struct dirent
*);
50 struct fs_ops pkgfs_fsops
= {
61 #define PKG_BUFSIZE 512
62 #define PKG_MAXCACHESZ 4096
64 #define PKG_FILEEXT ".tgz"
67 * Layout of POSIX 'ustar' header.
78 char ut_linkname
[100];
79 char ut_magic
[6]; /* For POSIX: "ustar\0" */
80 char ut_version
[2]; /* For POSIX: "00" */
103 u_char __padding
[12];
110 struct package
*tf_pkg
;
111 struct tarfile
*tf_next
;
112 struct ustar_hdr tf_hdr
;
122 struct package
*pkg_chain
;
126 struct tarfile
*pkg_first
;
127 struct tarfile
*pkg_last
;
128 u_char pkg_buf
[PKG_BUFSIZE
];
131 static struct package
*package
= NULL
;
133 static int new_package(int, struct package
**);
138 struct package
*chain
;
139 struct tarfile
*tf
, *tfn
;
141 while (package
!= NULL
) {
142 inflateEnd(&package
->pkg_zs
);
143 close(package
->pkg_fd
);
145 tf
= package
->pkg_first
;
148 if (tf
->tf_cachesz
> 0)
154 chain
= package
->pkg_chain
;
161 pkgfs_init(const char *pkgname
, struct fs_ops
*proto
)
166 if (proto
!= &pkgfs_fsops
)
169 exclusive_file_system
= proto
;
171 fd
= open(pkgname
, O_RDONLY
);
173 exclusive_file_system
= NULL
;
178 error
= new_package(fd
, &pkg
);
187 pkg
->pkg_chain
= package
;
189 exclusive_file_system
= &pkgfs_fsops
;
193 static int get_mode(struct tarfile
*);
194 static int get_zipped(struct package
*, void *, size_t);
195 static int new_package(int, struct package
**);
196 static struct tarfile
*scan_tarfile(struct package
*, struct tarfile
*);
199 pkg_open(const char *fn
, struct open_file
*f
)
203 if (fn
== NULL
|| f
== NULL
)
210 * We can only read from a package, so reject request to open
211 * for write-only or read-write.
213 if (f
->f_flags
!= F_READ
)
217 * Scan the file headers for the named file. We stop scanning
218 * at the first filename that has the .pkg extension. This is
219 * a package within a package. We assume we have all the files
220 * we need up-front and without having to dig within nested
223 * Note that we preserve streaming properties as much as possible.
229 * Allow opening of the root directory for use by readdir()
230 * to support listing files in the package.
237 tf
= scan_tarfile(package
, NULL
);
239 if (strcmp(fn
, tf
->tf_hdr
.ut_name
) == 0) {
241 tf
->tf_fp
= 0; /* Reset the file pointer. */
244 tf
= scan_tarfile(package
, tf
);
250 pkg_close(struct open_file
*f
)
254 tf
= (struct tarfile
*)f
->f_fsdata
;
259 * Free up the cache if we read all of the file.
261 if (tf
->tf_fp
== tf
->tf_size
&& tf
->tf_cachesz
> 0) {
269 pkg_read(struct open_file
*f
, void *buf
, size_t size
, size_t *res
)
276 tf
= (struct tarfile
*)f
->f_fsdata
;
287 sz
= tf
->tf_size
- fp
;
288 if (fp
< tf
->tf_cachesz
&& tf
->tf_cachesz
< tf
->tf_size
)
289 sz
= tf
->tf_cachesz
- fp
;
295 if (fp
< tf
->tf_cachesz
) {
296 /* Satisfy the request from cache. */
297 memcpy(p
, tf
->tf_cache
+ fp
, sz
);
304 if (get_zipped(tf
->tf_pkg
, p
, sz
) == -1) {
313 if (tf
->tf_cachesz
!= 0)
316 tf
->tf_cachesz
= (sz
<= PKG_MAXCACHESZ
) ? sz
: PKG_MAXCACHESZ
;
317 tf
->tf_cache
= malloc(tf
->tf_cachesz
);
318 if (tf
->tf_cache
!= NULL
)
319 memcpy(tf
->tf_cache
, buf
, tf
->tf_cachesz
);
327 return ((sz
== -1) ? errno
: 0);
331 pkg_seek(struct open_file
*f
, off_t ofs
, int whence
)
339 tf
= (struct tarfile
*)f
->f_fsdata
;
347 delta
= ofs
- tf
->tf_fp
;
353 delta
= tf
->tf_size
- tf
->tf_fp
+ ofs
;
361 DBG(("%s: negative file seek (%jd)\n", __func__
,
367 while (delta
> 0 && tf
->tf_fp
< tf
->tf_size
) {
368 sz
= (delta
> sizeof(buf
)) ? sizeof(buf
) : delta
;
369 error
= pkg_read(f
, buf
, sz
, &res
);
381 pkg_stat(struct open_file
*f
, struct stat
*sb
)
385 tf
= (struct tarfile
*)f
->f_fsdata
;
388 memset(sb
, 0, sizeof(*sb
));
389 sb
->st_mode
= get_mode(tf
);
390 sb
->st_size
= tf
->tf_size
;
391 sb
->st_blocks
= (tf
->tf_size
+ 511) / 512;
396 pkg_readdir(struct open_file
*f
, struct dirent
*d
)
400 tf
= (struct tarfile
*)f
->f_fsdata
;
404 tf
= scan_tarfile(package
, NULL
);
409 d
->d_reclen
= sizeof(*d
);
411 memcpy(d
->d_name
, tf
->tf_hdr
.ut_name
, sizeof(d
->d_name
));
416 * Low-level support functions.
420 get_byte(struct package
*pkg
, off_t
*op
)
424 if (pkg
->pkg_zs
.avail_in
== 0) {
425 c
= read(pkg
->pkg_fd
, pkg
->pkg_buf
, PKG_BUFSIZE
);
428 pkg
->pkg_zs
.avail_in
= c
;
429 pkg
->pkg_zs
.next_in
= pkg
->pkg_buf
;
432 c
= *pkg
->pkg_zs
.next_in
;
433 pkg
->pkg_zs
.next_in
++;
434 pkg
->pkg_zs
.avail_in
--;
440 get_zipped(struct package
*pkg
, void *buf
, size_t bufsz
)
444 pkg
->pkg_zs
.next_out
= buf
;
445 pkg
->pkg_zs
.avail_out
= bufsz
;
447 while (pkg
->pkg_zs
.avail_out
) {
448 if (pkg
->pkg_zs
.avail_in
== 0) {
449 c
= read(pkg
->pkg_fd
, pkg
->pkg_buf
, PKG_BUFSIZE
);
454 pkg
->pkg_zs
.avail_in
= c
;
455 pkg
->pkg_zs
.next_in
= pkg
->pkg_buf
;
458 c
= inflate(&pkg
->pkg_zs
, Z_SYNC_FLUSH
);
459 if (c
!= Z_OK
&& c
!= Z_STREAM_END
) {
465 pkg
->pkg_ofs
+= bufsz
;
470 cache_data(struct tarfile
*tf
)
476 DBG(("%s: no file to cache data for?\n", __func__
));
483 DBG(("%s: no package associated with file?\n", __func__
));
488 if (tf
->tf_ofs
!= pkg
->pkg_ofs
) {
489 DBG(("%s: caching after partial read of file %s?\n",
490 __func__
, tf
->tf_hdr
.ut_name
));
495 /* We don't cache everything... */
496 if (tf
->tf_size
> PKG_MAXCACHESZ
) {
501 /* All files are padded to a multiple of 512 bytes. */
502 sz
= (tf
->tf_size
+ 0x1ff) & ~0x1ff;
504 tf
->tf_cache
= malloc(sz
);
505 if (tf
->tf_cache
== NULL
) {
506 DBG(("%s: could not allocate %d bytes\n", __func__
, (int)sz
));
512 return (get_zipped(pkg
, tf
->tf_cache
, sz
));
516 * Note that this implementation does not (and should not!) obey
517 * locale settings; you cannot simply substitute strtol here, since
518 * it does obey locale.
521 pkg_atol8(const char *p
, unsigned char_cnt
)
523 int64_t l
, limit
, last_digit_limit
;
524 int digit
, sign
, base
;
527 limit
= INT64_MAX
/ base
;
528 last_digit_limit
= INT64_MAX
% base
;
530 while (*p
== ' ' || *p
== '\t')
540 while (digit
>= 0 && digit
< base
&& char_cnt
-- > 0) {
541 if (l
>limit
|| (l
== limit
&& digit
> last_digit_limit
)) {
542 l
= UINT64_MAX
; /* Truncate on overflow. */
545 l
= (l
* base
) + digit
;
548 return (sign
< 0) ? -l
: l
;
552 * Parse a base-256 integer. This is just a straight signed binary
553 * value in big-endian order, except that the high-order bit is
554 * ignored. Remember that "int64_t" may or may not be exactly 64
555 * bits; the implementation here tries to avoid making any assumptions
556 * about the actual size of an int64_t. It does assume we're using
557 * twos-complement arithmetic, though.
560 pkg_atol256(const char *_p
, unsigned char_cnt
)
562 int64_t l
, upper_limit
, lower_limit
;
563 const unsigned char *p
= (const unsigned char *)_p
;
565 upper_limit
= INT64_MAX
/ 256;
566 lower_limit
= INT64_MIN
/ 256;
568 /* Pad with 1 or 0 bits, depending on sign. */
569 if ((0x40 & *p
) == 0x40)
573 l
= (l
<< 6) | (0x3f & *p
++);
574 while (--char_cnt
> 0) {
575 if (l
> upper_limit
) {
576 l
= INT64_MAX
; /* Truncate on overflow */
578 } else if (l
< lower_limit
) {
582 l
= (l
<< 8) | (0xff & (int64_t)*p
++);
588 pkg_atol(const char *p
, unsigned char_cnt
)
591 * Technically, GNU pkg considers a field to be in base-256
592 * only if the first byte is 0xff or 0x80.
595 return (pkg_atol256(p
, char_cnt
));
596 return (pkg_atol8(p
, char_cnt
));
600 get_mode(struct tarfile
*tf
)
602 return (pkg_atol(tf
->tf_hdr
.ut_mode
, sizeof(tf
->tf_hdr
.ut_mode
)));
606 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
607 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
608 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
609 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
610 #define COMMENT 0x10 /* bit 4 set: file comment present */
611 #define RESERVED 0xE0 /* bits 5..7: reserved */
614 new_package(int fd
, struct package
**pp
)
620 pkg
= malloc(sizeof(*pkg
));
624 bzero(pkg
, sizeof(*pkg
));
634 if (get_byte(pkg
, &ofs
) != 0x1f || get_byte(pkg
, &ofs
) != 0x8b)
637 if (get_byte(pkg
, &ofs
) != Z_DEFLATED
)
640 flags
= get_byte(pkg
, &ofs
);
641 if (flags
& RESERVED
)
644 /* Skip time, xflags and OS code. */
645 for (i
= 0; i
< 6; i
++) {
646 if (get_byte(pkg
, &ofs
) == -1)
650 /* Skip extra field. */
651 if (flags
& EXTRA_FIELD
) {
652 i
= (get_byte(pkg
, &ofs
) & 0xff) |
653 ((get_byte(pkg
, &ofs
) << 8) & 0xff);
655 if (get_byte(pkg
, &ofs
) == -1)
660 /* Skip original file name. */
661 if (flags
& ORIG_NAME
) {
663 i
= get_byte(pkg
, &ofs
);
664 } while (i
!= 0 && i
!= -1);
669 /* Print the comment if it's there. */
670 if (flags
& COMMENT
) {
672 i
= get_byte(pkg
, &ofs
);
682 if (flags
& HEAD_CRC
) {
683 if (get_byte(pkg
, &ofs
) == -1)
685 if (get_byte(pkg
, &ofs
) == -1)
690 * Done parsing the ZIP header. Spkgt the inflation engine.
692 error
= inflateInit2(&pkg
->pkg_zs
, -15);
704 static struct tarfile
*
705 scan_tarfile(struct package
*pkg
, struct tarfile
*last
)
712 cur
= (last
!= NULL
) ? last
->tf_next
: pkg
->pkg_first
;
714 ofs
= (last
!= NULL
) ? last
->tf_ofs
+ last
->tf_size
:
716 ofs
= (ofs
+ 0x1ff) & ~0x1ff;
718 /* Check if we've reached EOF. */
719 if (ofs
< pkg
->pkg_ofs
) {
724 if (ofs
!= pkg
->pkg_ofs
) {
725 if (last
!= NULL
&& pkg
->pkg_ofs
== last
->tf_ofs
) {
726 if (cache_data(last
) == -1)
729 sz
= ofs
- pkg
->pkg_ofs
;
731 if (sz
> sizeof(buf
))
733 if (get_zipped(pkg
, buf
, sz
) == -1)
735 sz
= ofs
- pkg
->pkg_ofs
;
740 cur
= malloc(sizeof(*cur
));
743 memset(cur
, 0, sizeof(*cur
));
747 if (get_zipped(pkg
, &cur
->tf_hdr
,
748 sizeof(cur
->tf_hdr
)) == -1) {
754 * There are always 2 empty blocks appended to
755 * a PKG. It marks the end of the archive.
757 if (strncmp(cur
->tf_hdr
.ut_magic
, "ustar", 5) != 0) {
763 cur
->tf_ofs
= pkg
->pkg_ofs
;
764 cur
->tf_size
= pkg_atol(cur
->tf_hdr
.ut_size
,
765 sizeof(cur
->tf_hdr
.ut_size
));
767 if (cur
->tf_hdr
.ut_name
[0] != '+')
771 * Skip package meta-files.
773 ofs
= cur
->tf_ofs
+ cur
->tf_size
;
774 ofs
= (ofs
+ 0x1ff) & ~0x1ff;
775 while (pkg
->pkg_ofs
< ofs
) {
776 if (get_zipped(pkg
, buf
, sizeof(buf
)) == -1) {
786 pkg
->pkg_first
= cur
;