OSDN Git Service

remove global variables on maketree.c
[lha/olha.git] / extract.c
1 #include <errno.h>
2 #include <utime.h>
3 #include <string.h>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include "ar.h"
7
8 void
9 extract(struct lzh_istream *rp, int to_file, struct lzh_header *h)
10 {
11     FILE *outfile = NULL;
12     unsigned int crc;
13
14     if (to_file) {
15         if (memcmp(h->method, "-lhd-", sizeof(h->method)) == 0) {
16             /* directory */
17             if (mkdir(h->filename, 0777) == -1) {
18                 if (errno != EEXIST)
19                     error("cannot make directory \"%s\"", opts.outdir);
20             }
21         }
22         else {
23             /* regular file */
24             if (file_exists(h->filename)) {
25                 if (!opts.force_extract) {
26                     message("'%s' has been already exist. skip", h->filename);
27                     skip(rp->fp, h);
28                     return;
29                 }
30             }
31             while ((outfile = fopen(h->filename, "wb")) == NULL) {
32                 fprintf(stderr, "Can't open %s\nNew filename: ", h->filename);
33                 if (get_line(h->filename, sizeof(h->filename)) == 0) {
34                     fprintf(stderr, "Not extracted\n");
35                     skip(rp->fp, h);
36                     return;
37                 }
38                 h->namelen = strlen(h->filename);
39             }
40         }
41         if (opts.quiet < 2)
42             printf("Extracting %s ", h->filename);
43     }
44     else {
45         outfile = stdout;
46         if (opts.quiet < 2)
47             printf("===== %s =====\n", h->filename);
48     }
49     crc = INIT_CRC;
50     opts.method = which_method(h->method);
51     if (opts.method == NULL) {
52         fprintf(stderr, "Unknown method: %.5s\n", h->method);
53         skip(rp->fp, h);
54     }
55     else {
56         char buf[MAXDICSIZ];
57         unsigned int slide_off = 0;
58         int slide_len = 0;
59         unsigned long remainder = h->origsize;
60
61         crc = INIT_CRC;
62         if (opts.method->dicbit != 0)
63             decode_start(rp);
64         while (remainder != 0) {
65             uint n = (uint)MIN(remainder, MAXDICSIZ);
66             if (opts.method->dicbit != 0)
67                 decode(rp, n, buf, &slide_off, &slide_len);
68             else {
69                 /* no compress */
70                 if (fread(buf, 1, n, rp->fp) != n)
71                     error("Can't read");
72             }
73             fwrite_crc(buf, n, outfile, &crc);
74             if (outfile != stdout && opts.quiet < 1) {
75                 putc('.', stdout);
76             }
77             remainder -= n;
78         }
79     }
80
81     if ((crc ^ INIT_CRC) != h->file_crc)
82         error("CRC error");
83
84     if (to_file) {
85         fprintf(stdout, "\n");
86         if (outfile) {
87             struct utimbuf ut;
88
89             fclose(outfile);
90
91             ut.actime = ut.modtime = h->mtime;
92             utime(h->filename, &ut);
93         }
94     }
95     outfile = NULL;
96 }