OSDN Git Service

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