]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - stand/libsa/pkgfs.c
zfs: merge openzfs/zfs@804414aad
[FreeBSD/FreeBSD.git] / stand / libsa / pkgfs.c
1 /*- 
2  * Copyright (c) 2007-2014, Juniper Networks, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 #include "stand.h"
29
30 #include <sys/stat.h>
31 #include <sys/stdint.h>
32 #include <string.h>
33 #include <zlib.h>
34
35 #ifdef PKGFS_DEBUG
36 #define DBG(x)  printf x
37 #else
38 #define DBG(x)
39 #endif
40
41 static int   pkg_open(const char *, struct open_file *);
42 static int   pkg_close(struct open_file *);
43 static int   pkg_read(struct open_file *, void *, size_t, size_t *);
44 static off_t pkg_seek(struct open_file *, off_t, int);
45 static int   pkg_stat(struct open_file *, struct stat *);
46 static int   pkg_readdir(struct open_file *, struct dirent *);
47 static off_t pkg_atol(const char *, unsigned);
48
49 struct fs_ops pkgfs_fsops = {
50         .fs_name = "pkg",
51         .fo_open = pkg_open,
52         .fo_close = pkg_close,
53         .fo_read = pkg_read,
54         .fo_write = null_write,
55         .fo_seek = pkg_seek,
56         .fo_stat = pkg_stat,
57         .fo_readdir = pkg_readdir,
58 };
59
60 #define PKG_BUFSIZE     512
61 #define PKG_MAXCACHESZ  (512 * 1024)
62
63 #define PKG_FILEEXT     ".tgz"
64
65 /*
66  * Layout of POSIX 'ustar' header.
67  */
68 struct ustar_hdr {
69         char    ut_name[100];
70         char    ut_mode[8];
71         char    ut_uid[8];
72         char    ut_gid[8];
73         char    ut_size[12];
74         char    ut_mtime[12];
75         char    ut_checksum[8];
76         char    ut_typeflag[1];
77         char    ut_linkname[100];
78         char    ut_magic[6];            /* For POSIX: "ustar\0" */
79         char    ut_version[2];          /* For POSIX: "00" */
80         char    ut_uname[32];
81         char    ut_gname[32];
82         char    ut_rdevmajor[8];
83         char    ut_rdevminor[8];
84         union {
85                 struct {
86                         char    prefix[155];
87                 } posix;
88                 struct {
89                         char    atime[12];
90                         char    ctime[12];
91                         char    offset[12];
92                         char    longnames[4];
93                         char    unused[1];
94                         struct gnu_sparse {
95                                 char    offset[12];
96                                 char    numbytes[12];
97                         } sparse[4];
98                         char    isextended[1];
99                         char    realsize[12];
100                 } gnu;
101         } u;
102         u_char __padding[12];
103 };
104
105 struct package;
106
107 struct tarfile
108 {
109         struct package *tf_pkg;
110         struct tarfile *tf_next;
111         struct ustar_hdr tf_hdr;
112         off_t   tf_ofs;
113         off_t   tf_size;
114         off_t   tf_fp;
115         size_t  tf_cachesz;
116         void    *tf_cache;
117 };
118
119 struct package
120 {
121         struct package *pkg_chain;
122         int     pkg_fd;
123         off_t   pkg_ofs;
124         z_stream pkg_zs;
125         struct tarfile *pkg_first;
126         struct tarfile *pkg_last;
127         u_char  pkg_buf[PKG_BUFSIZE];
128 };
129
130 static struct package *package = NULL;
131
132 static int new_package(int, struct package **);
133 static int cache_data(struct tarfile *tf, int);
134
135 void
136 pkgfs_cleanup(void)
137 {
138         struct package *chain;
139         struct tarfile *tf, *tfn;
140
141         while (package != NULL) {
142                 inflateEnd(&package->pkg_zs);
143                 close(package->pkg_fd);
144
145                 tf = package->pkg_first;
146                 while (tf != NULL) {
147                         tfn = tf->tf_next;
148                         if (tf->tf_cachesz > 0)
149                                 free(tf->tf_cache);
150                         free(tf);
151                         tf = tfn;
152                 }
153
154                 chain = package->pkg_chain;
155                 free(package);
156                 package = chain;
157         }
158 }
159
160 int
161 pkgfs_init(const char *pkgname, struct fs_ops *proto)
162 {
163         struct package *pkg;
164         int error, fd;
165
166         pkg = NULL;
167         if (proto != &pkgfs_fsops)
168                 pkgfs_cleanup();
169
170         exclusive_file_system = proto;
171
172         fd = open(pkgname, O_RDONLY);
173
174         exclusive_file_system = NULL;
175
176         if (fd == -1)
177                 return (errno);
178
179         error = new_package(fd, &pkg);
180         if (error) {
181                 close(fd);
182                 return (error);
183         }
184
185         if (pkg == NULL)
186                 return (EDOOFUS);
187
188         pkg->pkg_chain = package;
189         package = pkg;
190         exclusive_file_system = &pkgfs_fsops;
191         return (0);
192 }
193
194 static int get_mode(struct tarfile *);
195 static int get_zipped(struct package *, void *, size_t);
196 static int new_package(int, struct package **);
197 static struct tarfile *scan_tarfile(struct package *, struct tarfile *);
198
199 static int
200 pkg_open_follow(const char *fn, struct open_file *f, int lnks)
201 {
202         struct tarfile *tf;
203
204         if (fn == NULL || f == NULL)
205                 return (EINVAL);
206
207         if (package == NULL)
208                 return (ENXIO);
209
210         /*
211          * We can only read from a package, so reject request to open
212          * for write-only or read-write.
213          */
214         if (f->f_flags != F_READ)
215                 return (EPERM);
216
217         /*
218          * Scan the file headers for the named file. We stop scanning
219          * at the first filename that has the .pkg extension. This is
220          * a package within a package. We assume we have all the files
221          * we need up-front and without having to dig within nested
222          * packages.
223          *
224          * Note that we preserve streaming properties as much as possible.
225          */
226         while (*fn == '/')
227                 fn++;
228
229         /*
230          * Allow opening of the root directory for use by readdir()
231          * to support listing files in the package.
232          */
233         if (*fn == '\0') {
234                 f->f_fsdata = NULL;
235                 return (0);
236         }
237
238         tf = scan_tarfile(package, NULL);
239         while (tf != NULL) {
240                 if (strcmp(fn, tf->tf_hdr.ut_name) == 0) {
241                         f->f_fsdata = tf;
242                         tf->tf_fp = 0;  /* Reset the file pointer. */
243                         DBG(("%s: found %s type %c\n", __func__,
244                              fn, tf->tf_hdr.ut_typeflag[0]));
245                         if (tf->tf_hdr.ut_typeflag[0] == '2') {
246                             /* we have a symlink
247                              * Note: ut_linkname is only 100 chars!
248                              */
249                             if (lnks++ >= 8)
250                                 return (EMLINK);
251                             return pkg_open_follow(tf->tf_hdr.ut_linkname,
252                                 f, lnks);
253                         }
254                         return (0);
255                 }
256                 tf = scan_tarfile(package, tf);
257         }
258         return (errno);
259 }
260
261 static int
262 pkg_open(const char *fn, struct open_file *f)
263 {
264     return pkg_open_follow(fn, f, 0);
265 }
266
267 static int
268 pkg_close(struct open_file *f)
269 {
270         struct tarfile *tf;
271
272         tf = (struct tarfile *)f->f_fsdata;
273         if (tf == NULL)
274                 return (0);
275
276         /*
277          * Free up the cache if we read all of the file.
278          */
279         if (tf->tf_fp == tf->tf_size && tf->tf_cachesz > 0) {
280                 free(tf->tf_cache);
281                 tf->tf_cachesz = 0;
282         }
283         return (0);
284 }
285
286 static int
287 pkg_read(struct open_file *f, void *buf, size_t size, size_t *res)
288 {
289         struct tarfile *tf;
290         char *p;
291         off_t fp;
292         size_t sz;
293
294         tf = (struct tarfile *)f->f_fsdata;
295         if (tf == NULL) {
296                 if (res != NULL)
297                         *res = size;
298                 return (EBADF);
299         }
300
301         if (tf->tf_cachesz == 0)
302                 cache_data(tf, 1);
303
304         fp = tf->tf_fp;
305         p = buf;
306         sz = 0;
307         while (size > 0) {
308                 sz = tf->tf_size - fp;
309                 if (fp < tf->tf_cachesz && tf->tf_cachesz < tf->tf_size)
310                         sz = tf->tf_cachesz - fp;
311                 if (size < sz)
312                         sz = size;
313                 if (sz == 0)
314                         break;
315
316                 if (fp < tf->tf_cachesz) {
317                         /* Satisfy the request from cache. */
318                         memcpy(p, tf->tf_cache + fp, sz);
319                         fp += sz;
320                         p += sz;
321                         size -= sz;
322                         continue;
323                 }
324
325                 if (get_zipped(tf->tf_pkg, p, sz) == -1) {
326                         sz = -1;
327                         break;
328                 }
329
330                 fp += sz;
331                 p += sz;
332                 size -= sz;
333         }
334
335         tf->tf_fp = fp;
336         if (res != NULL)
337                 *res = size;
338         return ((sz == -1) ? errno : 0);
339 }
340
341 static off_t
342 pkg_seek(struct open_file *f, off_t ofs, int whence)
343 {
344         char buf[512];
345         struct tarfile *tf;
346         off_t delta;
347         off_t nofs;
348         size_t sz, res;
349         int error;
350
351         tf = (struct tarfile *)f->f_fsdata;
352         if (tf == NULL) {
353                 errno = EBADF;
354                 return (-1);
355         }
356
357         switch (whence) {
358         case SEEK_SET:
359                 delta = ofs - tf->tf_fp;
360                 break;
361         case SEEK_CUR:
362                 delta = ofs;
363                 break;
364         case SEEK_END:
365                 delta = tf->tf_size - tf->tf_fp + ofs;
366                 break;
367         default:
368                 errno = EINVAL;
369                 return (-1);
370         }
371
372         if (delta < 0) {
373                 /* seeking backwards - ok if within cache */
374                 if (tf->tf_cachesz > 0 && tf->tf_fp <= tf->tf_cachesz) {
375                         nofs = tf->tf_fp + delta;
376                         if (nofs >= 0) {
377                                 tf->tf_fp = nofs;
378                                 return (tf->tf_fp);
379                         }
380                 }
381                 DBG(("%s: negative file seek (%jd)\n", __func__,
382                     (intmax_t)delta));
383                 errno = ESPIPE;
384                 return (-1);
385         }
386
387         while (delta > 0 && tf->tf_fp < tf->tf_size) {
388                 sz = (delta > sizeof(buf)) ? sizeof(buf) : delta;
389                 error = pkg_read(f, buf, sz, &res);
390                 if (error != 0) {
391                         errno = error;
392                         return (-1);
393                 }
394                 delta -= sz - res;
395         }
396
397         return (tf->tf_fp);
398 }
399
400 static int
401 pkg_stat(struct open_file *f, struct stat *sb)
402 {
403         struct tarfile *tf;
404
405         tf = (struct tarfile *)f->f_fsdata;
406         if (tf == NULL)
407                 return (EBADF);
408         memset(sb, 0, sizeof(*sb));
409         sb->st_mode = get_mode(tf);
410         if ((sb->st_mode & S_IFMT) == 0) {
411                 /* tar file bug - assume regular file */
412                 sb->st_mode |= S_IFREG;
413         }
414         sb->st_size = tf->tf_size;
415         sb->st_blocks = (tf->tf_size + 511) / 512;
416         sb->st_mtime = pkg_atol(tf->tf_hdr.ut_mtime, 12);
417         sb->st_dev = (off_t)((uintptr_t)tf->tf_pkg);
418         sb->st_ino = tf->tf_ofs;        /* unique per tf_pkg */
419         return (0);
420 }
421
422 static int
423 pkg_readdir(struct open_file *f, struct dirent *d)
424 {
425         struct tarfile *tf;
426
427         tf = (struct tarfile *)f->f_fsdata;
428         if (tf != NULL)
429                 return (EBADF);
430
431         tf = scan_tarfile(package, NULL);
432         if (tf == NULL)
433                 return (ENOENT);
434
435         d->d_fileno = 0;
436         d->d_reclen = sizeof(*d);
437         d->d_type = DT_REG;
438         memcpy(d->d_name, tf->tf_hdr.ut_name, sizeof(d->d_name));
439         return (0);
440 }
441
442 /*
443  * Low-level support functions.
444  */
445
446 static int
447 get_byte(struct package *pkg, off_t *op)
448 {
449         int c;
450
451         if (pkg->pkg_zs.avail_in == 0) {
452                 c = read(pkg->pkg_fd, pkg->pkg_buf, PKG_BUFSIZE);
453                 if (c <= 0)
454                         return (-1);
455                 pkg->pkg_zs.avail_in = c;
456                 pkg->pkg_zs.next_in = pkg->pkg_buf;
457         }
458
459         c = *pkg->pkg_zs.next_in;
460         pkg->pkg_zs.next_in++;
461         pkg->pkg_zs.avail_in--;
462         (*op)++;
463         return (c);
464 }
465
466 static int
467 get_zipped(struct package *pkg, void *buf, size_t bufsz)
468 {
469         int c;
470
471         pkg->pkg_zs.next_out = buf;
472         pkg->pkg_zs.avail_out = bufsz;
473
474         while (pkg->pkg_zs.avail_out) {
475                 if (pkg->pkg_zs.avail_in == 0) {
476                         c = read(pkg->pkg_fd, pkg->pkg_buf, PKG_BUFSIZE);
477                         if (c <= 0) {
478                                 errno = EIO;
479                                 return (-1);
480                         }
481                         pkg->pkg_zs.avail_in = c;
482                         pkg->pkg_zs.next_in = pkg->pkg_buf;
483                 }
484
485                 c = inflate(&pkg->pkg_zs, Z_SYNC_FLUSH);
486                 if (c != Z_OK && c != Z_STREAM_END) {
487                         errno = EIO;
488                         return (-1);
489                 }
490         }
491
492         pkg->pkg_ofs += bufsz;
493         return (0);
494 }
495
496 /**
497  * @brief
498  * cache data of a tarfile
499  *
500  * @param[in] tf
501  *      tarfile pointer
502  *
503  * @param[in] force
504  *      If file size > PKG_MAXCACHESZ, cache that much
505  *
506  * @return 0, -1 (errno set to error value)
507  */
508 static int
509 cache_data(struct tarfile *tf, int force)
510 {
511         struct package *pkg;
512         size_t sz;
513
514         if (tf == NULL) {
515                 DBG(("%s: no file to cache data for?\n", __func__));
516                 errno = EINVAL;
517                 return (-1);
518         }
519
520         pkg = tf->tf_pkg;
521         if (pkg == NULL) {
522                 DBG(("%s: no package associated with file?\n", __func__));
523                 errno = EINVAL;
524                 return (-1);
525         }
526
527         if (tf->tf_cachesz > 0) {
528                 DBG(("%s: data already cached\n", __func__));
529                 errno = EINVAL;
530                 return (-1);
531         }
532
533         if (tf->tf_ofs != pkg->pkg_ofs) {
534                 DBG(("%s: caching after force read of file %s?\n",
535                     __func__, tf->tf_hdr.ut_name));
536                 errno = EINVAL;
537                 return (-1);
538         }
539
540         /* We don't cache everything... */
541         if (tf->tf_size > PKG_MAXCACHESZ && !force)  {
542                 errno = ENOBUFS;
543                 return (-1);
544         }
545
546         sz = tf->tf_size < PKG_MAXCACHESZ ? tf->tf_size : PKG_MAXCACHESZ;
547         /* All files are padded to a multiple of 512 bytes. */
548         sz = (sz + 0x1ff) & ~0x1ff;
549
550         tf->tf_cache = malloc(sz);
551         if (tf->tf_cache == NULL) {
552                 DBG(("%s: could not allocate %d bytes\n", __func__, (int)sz));
553                 errno = ENOMEM;
554                 return (-1);
555         }
556
557         tf->tf_cachesz = sz;
558         return (get_zipped(pkg, tf->tf_cache, sz));
559 }
560
561 /*
562  * Note that this implementation does not (and should not!) obey
563  * locale settings; you cannot simply substitute strtol here, since
564  * it does obey locale.
565  */
566 static off_t
567 pkg_atol8(const char *p, unsigned char_cnt)
568 {
569         int64_t l, limit, last_digit_limit;
570         int digit, sign, base;
571
572         base = 8;
573         limit = INT64_MAX / base;
574         last_digit_limit = INT64_MAX % base;
575
576         while (*p == ' ' || *p == '\t')
577                 p++;
578         if (*p == '-') {
579                 sign = -1;
580                 p++;
581         } else
582                 sign = 1;
583
584         l = 0;
585         digit = *p - '0';
586         while (digit >= 0 && digit < base  && char_cnt-- > 0) {
587                 if (l>limit || (l == limit && digit > last_digit_limit)) {
588                         l = UINT64_MAX; /* Truncate on overflow. */
589                         break;
590                 }
591                 l = (l * base) + digit;
592                 digit = *++p - '0';
593         }
594         return (sign < 0) ? -l : l;
595 }
596
597 /*
598  * Parse a base-256 integer.  This is just a straight signed binary
599  * value in big-endian order, except that the high-order bit is
600  * ignored.  Remember that "int64_t" may or may not be exactly 64
601  * bits; the implementation here tries to avoid making any assumptions
602  * about the actual size of an int64_t.  It does assume we're using
603  * twos-complement arithmetic, though.
604  */
605 static int64_t
606 pkg_atol256(const char *_p, unsigned char_cnt)
607 {
608         int64_t l, upper_limit, lower_limit;
609         const unsigned char *p = (const unsigned char *)_p;
610
611         upper_limit = INT64_MAX / 256;
612         lower_limit = INT64_MIN / 256;
613
614         /* Pad with 1 or 0 bits, depending on sign. */
615         if ((0x40 & *p) == 0x40)
616                 l = (int64_t)-1;
617         else
618                 l = 0;
619         l = (l << 6) | (0x3f & *p++);
620         while (--char_cnt > 0) {
621                 if (l > upper_limit) {
622                         l = INT64_MAX; /* Truncate on overflow */
623                         break;
624                 } else if (l < lower_limit) {
625                         l = INT64_MIN;
626                         break;
627                 }
628                 l = (l << 8) | (0xff & (int64_t)*p++);
629         }
630         return (l);
631 }
632
633 static off_t
634 pkg_atol(const char *p, unsigned char_cnt)
635 {
636         /*
637          * Technically, GNU pkg considers a field to be in base-256
638          * only if the first byte is 0xff or 0x80.
639          */
640         if (*p & 0x80)
641                 return (pkg_atol256(p, char_cnt));
642         return (pkg_atol8(p, char_cnt));
643 }
644
645 static int
646 get_mode(struct tarfile *tf)
647 {
648         return (pkg_atol(tf->tf_hdr.ut_mode, sizeof(tf->tf_hdr.ut_mode)));
649 }
650
651 /* GZip flag byte */
652 #define ASCII_FLAG      0x01 /* bit 0 set: file probably ascii text */
653 #define HEAD_CRC        0x02 /* bit 1 set: header CRC present */
654 #define EXTRA_FIELD     0x04 /* bit 2 set: extra field present */
655 #define ORIG_NAME       0x08 /* bit 3 set: original file name present */
656 #define COMMENT         0x10 /* bit 4 set: file comment present */
657 #define RESERVED        0xE0 /* bits 5..7: reserved */
658
659 static int
660 new_package(int fd, struct package **pp)
661 {
662         struct package *pkg;
663         off_t ofs;
664         int flags, i, error;
665
666         pkg = malloc(sizeof(*pkg));
667         if (pkg == NULL)
668                 return (ENOMEM);
669
670         bzero(pkg, sizeof(*pkg));
671         pkg->pkg_fd = fd;
672
673         /*
674          * Parse the header.
675          */
676         error = EFTYPE;
677         ofs = 0;
678
679         /* Check megic. */
680         if (get_byte(pkg, &ofs) != 0x1f || get_byte(pkg, &ofs) != 0x8b)
681                 goto fail;
682         /* Check method. */
683         if (get_byte(pkg, &ofs) != Z_DEFLATED)
684                 goto fail;
685         /* Check flags. */
686         flags = get_byte(pkg, &ofs);
687         if (flags & RESERVED)
688                 goto fail;
689
690         /* Skip time, xflags and OS code. */
691         for (i = 0; i < 6; i++) {
692                 if (get_byte(pkg, &ofs) == -1)
693                         goto fail;
694         }
695
696         /* Skip extra field. */
697         if (flags & EXTRA_FIELD) {
698                 i = (get_byte(pkg, &ofs) & 0xff) |
699                     ((get_byte(pkg, &ofs) << 8) & 0xff);
700                 while (i-- > 0) {
701                         if (get_byte(pkg, &ofs) == -1)
702                                 goto fail;
703                 }
704         }
705
706         /* Skip original file name. */
707         if (flags & ORIG_NAME) {
708                 do {
709                         i = get_byte(pkg, &ofs);
710                 } while (i != 0 && i != -1);
711                 if (i == -1)
712                         goto fail;
713         }
714
715         /* Print the comment if it's there. */
716         if (flags & COMMENT) {
717                 while (1) {
718                         i = get_byte(pkg, &ofs);
719                         if (i == -1)
720                                 goto fail;
721                         if (i == 0)
722                                 break;
723                         putchar(i);
724                 }
725         }
726
727         /* Skip the CRC. */
728         if (flags & HEAD_CRC) {
729                 if (get_byte(pkg, &ofs) == -1)
730                         goto fail;
731                 if (get_byte(pkg, &ofs) == -1)
732                         goto fail;
733         }
734
735         /*
736          * Done parsing the ZIP header. Spkgt the inflation engine.
737          */
738         error = inflateInit2(&pkg->pkg_zs, -15);
739         if (error != Z_OK)
740                 goto fail;
741
742         *pp = pkg;
743         return (0);
744
745  fail:
746         free(pkg);
747         return (error);
748 }
749
750 static struct tarfile *
751 scan_tarfile(struct package *pkg, struct tarfile *last)
752 {
753         char buf[512];
754         struct tarfile *cur;
755         off_t ofs;
756         size_t sz;
757
758         cur = (last != NULL) ? last->tf_next : pkg->pkg_first;
759         if (cur == NULL) {
760                 ofs = (last != NULL) ? last->tf_ofs + last->tf_size :
761                     pkg->pkg_ofs;
762                 ofs = (ofs + 0x1ff) & ~0x1ff;
763
764                 /* Check if we've reached EOF. */
765                 if (ofs < pkg->pkg_ofs) {
766                         errno = ENOSPC;
767                         return (NULL);
768                 }
769
770                 if (ofs != pkg->pkg_ofs) {
771                         if (last != NULL && pkg->pkg_ofs == last->tf_ofs) {
772                                 if (cache_data(last, 0) == -1)
773                                         return (NULL);
774                         } else {
775                                 sz = ofs - pkg->pkg_ofs;
776                                 while (sz != 0) {
777                                         if (sz > sizeof(buf))
778                                                 sz = sizeof(buf);
779                                         if (get_zipped(pkg, buf, sz) == -1)
780                                                 return (NULL);
781                                         sz = ofs - pkg->pkg_ofs;
782                                 }
783                         }
784                 }
785
786                 cur = malloc(sizeof(*cur));
787                 if (cur == NULL)
788                         return (NULL);
789                 memset(cur, 0, sizeof(*cur));
790                 cur->tf_pkg = pkg;
791
792                 while (1) {
793                         if (get_zipped(pkg, &cur->tf_hdr,
794                             sizeof(cur->tf_hdr)) == -1) {
795                                 free(cur);
796                                 return (NULL);
797                         }
798
799                         /*
800                          * There are always 2 empty blocks appended to
801                          * a PKG. It marks the end of the archive.
802                          */
803                         if (strncmp(cur->tf_hdr.ut_magic, "ustar", 5) != 0) {
804                                 free(cur);
805                                 errno = ENOSPC;
806                                 return (NULL);
807                         }
808
809                         cur->tf_ofs = pkg->pkg_ofs;
810                         cur->tf_size = pkg_atol(cur->tf_hdr.ut_size,
811                             sizeof(cur->tf_hdr.ut_size));
812
813                         if (cur->tf_hdr.ut_name[0] != '+')
814                                 break;
815
816                         /*
817                          * Skip package meta-files.
818                          */
819                         ofs = cur->tf_ofs + cur->tf_size;
820                         ofs = (ofs + 0x1ff) & ~0x1ff;
821                         while (pkg->pkg_ofs < ofs) {
822                                 if (get_zipped(pkg, buf, sizeof(buf)) == -1) {
823                                         free(cur);
824                                         return (NULL);
825                                 }
826                         }
827                 }
828
829                 if (last != NULL)
830                         last->tf_next = cur;
831                 else
832                         pkg->pkg_first = cur;
833                 pkg->pkg_last = cur;
834         }
835
836         return (cur);
837 }