New common unarchive code.
[oweals/busybox.git] / archival / libunarchive / check_header_gzip.c
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include "libbb.h"
4
5 extern void check_header_gzip(int src_fd)
6 {
7         union {
8                 unsigned char raw[10];
9                 struct {
10                         unsigned char magic[2];
11                         unsigned char method;
12                         unsigned char flags;
13                         unsigned int mtime;
14                         unsigned char xtra_flags;
15                         unsigned char os_flags;
16                 } formated;
17         } header;
18
19         xread_all(src_fd, header.raw, 10);
20
21    /* Magic header for gzip files, 1F 8B = \037\213 */
22         if ((header.formated.magic[0] != 0x1F)
23                 || (header.formated.magic[1] != 0x8b)) {
24                 error_msg_and_die("Invalid gzip magic");
25         }
26
27    /* Check the compression method */
28         if (header.formated.method != 8) {
29                 error_msg_and_die("Unknown compression method %d",
30                                                   header.formated.method);
31         }
32
33         if (header.formated.flags & 0x04) {
34                 /* bit 2 set: extra field present */
35                 unsigned char extra_short;
36
37                 extra_short = xread_char(src_fd);
38                 extra_short += xread_char(src_fd) << 8;
39                 while (extra_short > 0) {
40                    /* Ignore extra field */
41                         xread_char(src_fd);
42                         extra_short--;
43                 }
44         }
45
46    /* Discard original name if any */
47         if (header.formated.flags & 0x08) {
48            /* bit 3 set: original file name present */
49                 char tmp;
50
51                 do {
52                         read(src_fd, &tmp, 1);
53                 } while (tmp != 0);
54         }
55
56    /* Discard file comment if any */
57         if (header.formated.flags & 0x10) {
58            /* bit 4 set: file comment present */
59                 char tmp;
60
61                 do {
62                         read(src_fd, &tmp, 1);
63                 } while (tmp != 0);
64         }
65
66    /* Read the header checksum */
67         if (header.formated.flags & 0x02) {
68                 char tmp;
69
70                 read(src_fd, &tmp, 1);
71                 read(src_fd, &tmp, 1);
72         }
73
74         return;
75 }