Merge from vendor branch GDB:
[dragonfly.git] / contrib / libarchive / archive_read_support_format_cpio.c
1 /*-
2  * Copyright (c) 2003-2004 Tim Kientzle
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  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "archive_platform.h"
28 __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_cpio.c,v 1.13 2005/04/06 04:19:30 kientzle Exp $");
29
30 #include <sys/stat.h>
31
32 #include <errno.h>
33 /* #include <stdint.h> */ /* See archive_platform.h */
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 #include "archive.h"
39 #include "archive_entry.h"
40 #include "archive_private.h"
41
42 struct cpio_bin_header {
43         unsigned char   c_magic[2];
44         unsigned char   c_dev[2];
45         unsigned char   c_ino[2];
46         unsigned char   c_mode[2];
47         unsigned char   c_uid[2];
48         unsigned char   c_gid[2];
49         unsigned char   c_nlink[2];
50         unsigned char   c_rdev[2];
51         unsigned char   c_mtime[4];
52         unsigned char   c_namesize[2];
53         unsigned char   c_filesize[4];
54 };
55
56 struct cpio_odc_header {
57         char    c_magic[6];
58         char    c_dev[6];
59         char    c_ino[6];
60         char    c_mode[6];
61         char    c_uid[6];
62         char    c_gid[6];
63         char    c_nlink[6];
64         char    c_rdev[6];
65         char    c_mtime[11];
66         char    c_namesize[6];
67         char    c_filesize[11];
68 };
69
70 struct cpio_newc_header {
71         char    c_magic[6];
72         char    c_ino[8];
73         char    c_mode[8];
74         char    c_uid[8];
75         char    c_gid[8];
76         char    c_nlink[8];
77         char    c_mtime[8];
78         char    c_filesize[8];
79         char    c_devmajor[8];
80         char    c_devminor[8];
81         char    c_rdevmajor[8];
82         char    c_rdevminor[8];
83         char    c_namesize[8];
84         char    c_crc[8];
85 };
86
87 struct links_entry {
88         struct links_entry      *next;
89         struct links_entry      *previous;
90         int                      links;
91         dev_t                    dev;
92         ino_t                    ino;
93         char                    *name;
94 };
95
96 #define CPIO_MAGIC   0x13141516
97 struct cpio {
98         int                       magic;
99         int                     (*read_header)(struct archive *, struct cpio *,
100                                      struct stat *, size_t *, size_t *);
101         struct links_entry       *links_head;
102         struct archive_string     entry_name;
103         struct archive_string     entry_linkname;
104         off_t                     entry_bytes_remaining;
105         off_t                     entry_offset;
106         off_t                     entry_padding;
107 };
108
109 static int64_t  atol16(const char *, unsigned);
110 static int64_t  atol8(const char *, unsigned);
111 static int      archive_read_format_cpio_bid(struct archive *);
112 static int      archive_read_format_cpio_cleanup(struct archive *);
113 static int      archive_read_format_cpio_read_data(struct archive *,
114                     const void **, size_t *, off_t *);
115 static int      archive_read_format_cpio_read_header(struct archive *,
116                     struct archive_entry *);
117 static int      be4(const unsigned char *);
118 static int      header_bin_be(struct archive *, struct cpio *, struct stat *,
119                     size_t *, size_t *);
120 static int      header_bin_le(struct archive *, struct cpio *, struct stat *,
121                     size_t *, size_t *);
122 static int      header_newc(struct archive *, struct cpio *, struct stat *,
123                     size_t *, size_t *);
124 static int      header_odc(struct archive *, struct cpio *, struct stat *,
125                     size_t *, size_t *);
126 static int      le4(const unsigned char *);
127 static void     record_hardlink(struct cpio *cpio, struct archive_entry *entry,
128                     const struct stat *st);
129
130 int
131 archive_read_support_format_cpio(struct archive *a)
132 {
133         struct cpio *cpio;
134         int r;
135
136         cpio = malloc(sizeof(*cpio));
137         memset(cpio, 0, sizeof(*cpio));
138         cpio->magic = CPIO_MAGIC;
139
140         r = __archive_read_register_format(a,
141             cpio,
142             archive_read_format_cpio_bid,
143             archive_read_format_cpio_read_header,
144             archive_read_format_cpio_read_data,
145             NULL,
146             archive_read_format_cpio_cleanup);
147
148         if (r != ARCHIVE_OK)
149                 free(cpio);
150         return (ARCHIVE_OK);
151 }
152
153
154 static int
155 archive_read_format_cpio_bid(struct archive *a)
156 {
157         int bid, bytes_read;
158         const void *h;
159         const unsigned char *p;
160         struct cpio *cpio;
161
162         cpio = *(a->pformat_data);
163         bid = 0;
164         bytes_read = (a->compression_read_ahead)(a, &h, 6);
165         /* Convert error code into error return. */
166         if (bytes_read < 0)
167                 return ((int)bytes_read);
168         if (bytes_read < 6)
169                 return (-1);
170
171         p = h;
172         if (memcmp(p, "070707", 6) == 0) {
173                 /* ASCII cpio archive (odc, POSIX.1) */
174                 cpio->read_header = header_odc;
175                 bid += 48;
176                 /*
177                  * XXX TODO:  More verification; Could check that only octal
178                  * digits appear in appropriate header locations. XXX
179                  */
180         } else if (memcmp(p, "070701", 6) == 0) {
181                 /* ASCII cpio archive (SVR4 without CRC) */
182                 cpio->read_header = header_newc;
183                 bid += 48;
184                 /*
185                  * XXX TODO:  More verification; Could check that only hex
186                  * digits appear in appropriate header locations. XXX
187                  */
188         } else if (memcmp(p, "070702", 6) == 0) {
189                 /* ASCII cpio archive (SVR4 with CRC) */
190                 /* XXX TODO: Flag that we should check the CRC. XXX */
191                 cpio->read_header = header_newc;
192                 bid += 48;
193                 /*
194                  * XXX TODO:  More verification; Could check that only hex
195                  * digits appear in appropriate header locations. XXX
196                  */
197         } else if (p[0] * 256 + p[1] == 070707) {
198                 /* big-endian binary cpio archives */
199                 cpio->read_header = header_bin_be;
200                 bid += 16;
201                 /* Is more verification possible here? */
202         } else if (p[0] + p[1] * 256 == 070707) {
203                 /* little-endian binary cpio archives */
204                 cpio->read_header = header_bin_le;
205                 bid += 16;
206                 /* Is more verification possible here? */
207         } else
208                 return (ARCHIVE_WARN);
209
210         return (bid);
211 }
212
213 static int
214 archive_read_format_cpio_read_header(struct archive *a,
215     struct archive_entry *entry)
216 {
217         struct stat st;
218         struct cpio *cpio;
219         size_t bytes;
220         const void *h;
221         size_t namelength;
222         size_t name_pad;
223         int r;
224
225         memset(&st, 0, sizeof(st));
226
227         cpio = *(a->pformat_data);
228         r = (cpio->read_header(a, cpio, &st, &namelength, &name_pad));
229
230         if (r != ARCHIVE_OK)
231                 return (r);
232
233         /* Assign all of the 'stat' fields at once. */
234         archive_entry_copy_stat(entry, &st);
235
236         /* Read name from buffer. */
237         bytes = (a->compression_read_ahead)(a, &h, namelength + name_pad);
238         if (bytes < namelength + name_pad)
239             return (ARCHIVE_FATAL);
240         (a->compression_read_consume)(a, namelength + name_pad);
241         archive_strncpy(&cpio->entry_name, h, namelength);
242         archive_entry_set_pathname(entry, cpio->entry_name.s);
243         cpio->entry_offset = 0;
244
245         /* If this is a symlink, read the link contents. */
246         if (S_ISLNK(st.st_mode)) {
247                 bytes = (a->compression_read_ahead)(a, &h,
248                     cpio->entry_bytes_remaining);
249                 if ((off_t)bytes < cpio->entry_bytes_remaining)
250                         return (ARCHIVE_FATAL);
251                 (a->compression_read_consume)(a, cpio->entry_bytes_remaining);
252                 archive_strncpy(&cpio->entry_linkname, h,
253                     cpio->entry_bytes_remaining);
254                 archive_entry_set_symlink(entry, cpio->entry_linkname.s);
255                 cpio->entry_bytes_remaining = 0;
256         }
257
258         /* Compare name to "TRAILER!!!" to test for end-of-archive. */
259         if (namelength == 11 && strcmp(h,"TRAILER!!!")==0) {
260             /* TODO: Store file location of start of block. */
261             archive_set_error(a, 0, NULL);
262             return (ARCHIVE_EOF);
263         }
264
265         /* Detect and record hardlinks to previously-extracted entries. */
266         record_hardlink(cpio, entry, &st);
267
268         return (ARCHIVE_OK);
269 }
270
271 static int
272 archive_read_format_cpio_read_data(struct archive *a,
273     const void **buff, size_t *size, off_t *offset)
274 {
275         ssize_t bytes_read;
276         struct cpio *cpio;
277
278         cpio = *(a->pformat_data);
279         if (cpio->entry_bytes_remaining > 0) {
280                 bytes_read = (a->compression_read_ahead)(a, buff, 1);
281                 if (bytes_read <= 0)
282                         return (ARCHIVE_FATAL);
283                 if (bytes_read > cpio->entry_bytes_remaining)
284                         bytes_read = cpio->entry_bytes_remaining;
285                 *size = bytes_read;
286                 *offset = cpio->entry_offset;
287                 cpio->entry_offset += bytes_read;
288                 cpio->entry_bytes_remaining -= bytes_read;
289                 (a->compression_read_consume)(a, bytes_read);
290                 return (ARCHIVE_OK);
291         } else {
292                 while (cpio->entry_padding > 0) {
293                         bytes_read = (a->compression_read_ahead)(a, buff, 1);
294                         if (bytes_read <= 0)
295                                 return (ARCHIVE_FATAL);
296                         if (bytes_read > cpio->entry_padding)
297                                 bytes_read = cpio->entry_padding;
298                         (a->compression_read_consume)(a, bytes_read);
299                         cpio->entry_padding -= bytes_read;
300                 }
301                 *buff = NULL;
302                 *size = 0;
303                 *offset = cpio->entry_offset;
304                 return (ARCHIVE_EOF);
305         }
306 }
307
308 static int
309 header_newc(struct archive *a, struct cpio *cpio, struct stat *st,
310     size_t *namelength, size_t *name_pad)
311 {
312         const void *h;
313         const struct cpio_newc_header *header;
314         size_t bytes;
315
316         a->archive_format = ARCHIVE_FORMAT_CPIO;
317         a->archive_format_name = "ASCII cpio (SVR4 with no CRC)";
318
319         /* Read fixed-size portion of header. */
320         bytes = (a->compression_read_ahead)(a, &h, sizeof(struct cpio_newc_header));
321         if (bytes < sizeof(struct cpio_newc_header))
322             return (ARCHIVE_FATAL);
323         (a->compression_read_consume)(a, sizeof(struct cpio_newc_header));
324
325         /* Parse out hex fields into struct stat. */
326         header = h;
327         st->st_ino = atol16(header->c_ino, sizeof(header->c_ino));
328         st->st_mode = atol16(header->c_mode, sizeof(header->c_mode));
329         st->st_uid = atol16(header->c_uid, sizeof(header->c_uid));
330         st->st_gid = atol16(header->c_gid, sizeof(header->c_gid));
331         st->st_nlink = atol16(header->c_nlink, sizeof(header->c_nlink));
332         st->st_mtime = atol16(header->c_mtime, sizeof(header->c_mtime));
333         *namelength = atol16(header->c_namesize, sizeof(header->c_namesize));
334         /* Pad name to 2 more than a multiple of 4. */
335         *name_pad = (2 - *namelength) & 3;
336
337         /*
338          * Note: entry_bytes_remaining is at least 64 bits and
339          * therefore gauranteed to be big enough for a 33-bit file
340          * size.  struct stat.st_size may only be 32 bits, so
341          * assigning there first could lose information.
342          */
343         cpio->entry_bytes_remaining =
344             atol16(header->c_filesize, sizeof(header->c_filesize));
345         st->st_size = cpio->entry_bytes_remaining;
346         /* Pad file contents to a multiple of 4. */
347         cpio->entry_padding = 3 & -cpio->entry_bytes_remaining;
348         return (ARCHIVE_OK);
349 }
350
351 static int
352 header_odc(struct archive *a, struct cpio *cpio, struct stat *st,
353     size_t *namelength, size_t *name_pad)
354 {
355         const void *h;
356         const struct cpio_odc_header *header;
357         size_t bytes;
358
359         a->archive_format = ARCHIVE_FORMAT_CPIO;
360         a->archive_format_name = "POSIX octet-oriented cpio";
361
362         /* Read fixed-size portion of header. */
363         bytes = (a->compression_read_ahead)(a, &h, sizeof(struct cpio_odc_header));
364         if (bytes < sizeof(struct cpio_odc_header))
365             return (ARCHIVE_FATAL);
366         (a->compression_read_consume)(a, sizeof(struct cpio_odc_header));
367
368         /* Parse out octal fields into struct stat. */
369         header = h;
370
371         st->st_dev = atol8(header->c_dev, sizeof(header->c_dev));
372         st->st_ino = atol8(header->c_ino, sizeof(header->c_ino));
373         st->st_mode = atol8(header->c_mode, sizeof(header->c_mode));
374         st->st_uid = atol8(header->c_uid, sizeof(header->c_uid));
375         st->st_gid = atol8(header->c_gid, sizeof(header->c_gid));
376         st->st_nlink = atol8(header->c_nlink, sizeof(header->c_nlink));
377         st->st_rdev = atol8(header->c_rdev, sizeof(header->c_rdev));
378         st->st_mtime = atol8(header->c_mtime, sizeof(header->c_mtime));
379         *namelength = atol8(header->c_namesize, sizeof(header->c_namesize));
380         *name_pad = 0; /* No padding of filename. */
381
382         /*
383          * Note: entry_bytes_remaining is at least 64 bits and
384          * therefore gauranteed to be big enough for a 33-bit file
385          * size.  struct stat.st_size may only be 32 bits, so
386          * assigning there first could lose information.
387          */
388         cpio->entry_bytes_remaining =
389             atol8(header->c_filesize, sizeof(header->c_filesize));
390         st->st_size = cpio->entry_bytes_remaining;
391         cpio->entry_padding = 0;
392         return (ARCHIVE_OK);
393 }
394
395 static int
396 header_bin_le(struct archive *a, struct cpio *cpio, struct stat *st,
397     size_t *namelength, size_t *name_pad)
398 {
399         const void *h;
400         const struct cpio_bin_header *header;
401         size_t bytes;
402
403         a->archive_format = ARCHIVE_FORMAT_CPIO;
404         a->archive_format_name = "cpio (little-endian binary)";
405
406         /* Read fixed-size portion of header. */
407         bytes = (a->compression_read_ahead)(a, &h, sizeof(struct cpio_bin_header));
408         if (bytes < sizeof(struct cpio_bin_header))
409             return (ARCHIVE_FATAL);
410         (a->compression_read_consume)(a, sizeof(struct cpio_bin_header));
411
412         /* Parse out binary fields into struct stat. */
413         header = h;
414
415         st->st_dev = header->c_dev[0] + header->c_dev[1] * 256;
416         st->st_ino = header->c_ino[0] + header->c_ino[1] * 256;
417         st->st_mode = header->c_mode[0] + header->c_mode[1] * 256;
418         st->st_uid = header->c_uid[0] + header->c_uid[1] * 256;
419         st->st_gid = header->c_gid[0] + header->c_gid[1] * 256;
420         st->st_nlink = header->c_nlink[0] + header->c_nlink[1] * 256;
421         st->st_rdev = header->c_rdev[0] + header->c_rdev[1] * 256;
422         st->st_mtime = le4(header->c_mtime);
423         *namelength = header->c_namesize[0] + header->c_namesize[1] * 256;
424         *name_pad = *namelength & 1; /* Pad to even. */
425
426         cpio->entry_bytes_remaining = le4(header->c_filesize);
427         st->st_size = cpio->entry_bytes_remaining;
428         cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
429         return (ARCHIVE_OK);
430 }
431
432 static int
433 header_bin_be(struct archive *a, struct cpio *cpio, struct stat *st,
434     size_t *namelength, size_t *name_pad)
435 {
436         const void *h;
437         const struct cpio_bin_header *header;
438         size_t bytes;
439
440         a->archive_format = ARCHIVE_FORMAT_CPIO;
441         a->archive_format_name = "cpio (big-endian binary)";
442
443         /* Read fixed-size portion of header. */
444         bytes = (a->compression_read_ahead)(a, &h,
445             sizeof(struct cpio_bin_header));
446         if (bytes < sizeof(struct cpio_bin_header))
447             return (ARCHIVE_FATAL);
448         (a->compression_read_consume)(a, sizeof(struct cpio_bin_header));
449
450         /* Parse out binary fields into struct stat. */
451         header = h;
452         st->st_dev = header->c_dev[0] * 256 + header->c_dev[1];
453         st->st_ino = header->c_ino[0] * 256 + header->c_ino[1];
454         st->st_mode = header->c_mode[0] * 256 + header->c_mode[1];
455         st->st_uid = header->c_uid[0] * 256 + header->c_uid[1];
456         st->st_gid = header->c_gid[0] * 256 + header->c_gid[1];
457         st->st_nlink = header->c_nlink[0] * 256 + header->c_nlink[1];
458         st->st_rdev = header->c_rdev[0] * 256 + header->c_rdev[1];
459         st->st_mtime = be4(header->c_mtime);
460         *namelength = header->c_namesize[0] * 256 + header->c_namesize[1];
461         *name_pad = *namelength & 1; /* Pad to even. */
462
463         cpio->entry_bytes_remaining = be4(header->c_filesize);
464         st->st_size = cpio->entry_bytes_remaining;
465         cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
466         return (ARCHIVE_OK);
467 }
468
469 static int
470 archive_read_format_cpio_cleanup(struct archive *a)
471 {
472         struct cpio *cpio;
473
474         cpio = *(a->pformat_data);
475         /* Free inode->name map */
476         while (cpio->links_head != NULL) {
477                 struct links_entry *lp = cpio->links_head->next;
478
479                 if (cpio->links_head->name)
480                         free(cpio->links_head->name);
481                 free(cpio->links_head);
482                 cpio->links_head = lp;
483         }
484
485         free(cpio);
486         *(a->pformat_data) = NULL;
487         return (ARCHIVE_OK);
488 }
489
490 static int
491 le4(const unsigned char *p)
492 {
493         return ((p[0]<<16) + (p[1]<<24) + (p[2]<<0) + (p[3]<<8));
494 }
495
496
497 static int
498 be4(const unsigned char *p)
499 {
500         return (p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24));
501 }
502
503 /*
504  * Note that this implementation does not (and should not!) obey
505  * locale settings; you cannot simply substitute strtol here, since
506  * it does obey locale.
507  */
508 static int64_t
509 atol8(const char *p, unsigned char_cnt)
510 {
511         int64_t l;
512         int digit;
513
514         l = 0;
515         while (char_cnt-- > 0) {
516                 if (*p >= '0' && *p <= '7')
517                         digit = *p - '0';
518                 else
519                         return (l);
520                 p++;
521                 l <<= 3;
522                 l |= digit;
523         }
524         return (l);
525 }
526
527 static int64_t
528 atol16(const char *p, unsigned char_cnt)
529 {
530         int64_t l;
531         int digit;
532
533         l = 0;
534         while (char_cnt-- > 0) {
535                 if (*p >= 'a' && *p <= 'f')
536                         digit = *p - 'a' + 10;
537                 else if (*p >= 'A' && *p <= 'F')
538                         digit = *p - 'A' + 10;
539                 else if (*p >= '0' && *p <= '9')
540                         digit = *p - '0';
541                 else
542                         return (l);
543                 p++;
544                 l <<= 4;
545                 l |= digit;
546         }
547         return (l);
548 }
549
550 static void
551 record_hardlink(struct cpio *cpio, struct archive_entry *entry,
552     const struct stat *st)
553 {
554         struct links_entry      *le;
555
556         /*
557          * First look in the list of multiply-linked files.  If we've
558          * already dumped it, convert this entry to a hard link entry.
559          */
560         for (le = cpio->links_head; le; le = le->next) {
561                 if (le->dev == st->st_dev && le->ino == st->st_ino) {
562                         archive_entry_set_hardlink(entry, le->name);
563
564                         if (--le->links <= 0) {
565                                 if (le->previous != NULL)
566                                         le->previous->next = le->next;
567                                 if (le->next != NULL)
568                                         le->next->previous = le->previous;
569                                 if (cpio->links_head == le)
570                                         cpio->links_head = le->next;
571                                 free(le);
572                         }
573
574                         return;
575                 }
576         }
577
578         le = malloc(sizeof(struct links_entry));
579         if (cpio->links_head != NULL)
580                 cpio->links_head->previous = le;
581         le->next = cpio->links_head;
582         le->previous = NULL;
583         cpio->links_head = le;
584         le->dev = st->st_dev;
585         le->ino = st->st_ino;
586         le->links = st->st_nlink - 1;
587         le->name = strdup(archive_entry_pathname(entry));
588 }