OSDN Git Service

global variable, outfile was removed
[lha/olha.git] / add.c
1 #include <dirent.h>
2 #include <string.h>
3 #include <sys/stat.h>
4 #include "ar.h"
5
6 extern int unpackable;
7 extern unsigned long compsize, origsize;
8
9 static unsigned long
10 store(FILE *rfp, FILE *wfp)
11 {
12     uint n;
13     char buf[MAXDICSIZ];
14     unsigned long sz = 0;
15
16     crc = INIT_CRC;
17     while ((n = fread(buf, 1, sizeof(buf), rfp)) != 0) {
18         fwrite_crc(buf, n, wfp);
19         sz += n;
20     }
21     return sz;
22 }
23
24 int
25 add_dir(struct lzh_ostream *wp, int replace_flag, struct lzh_header *h)
26 {
27     long headerpos, arcpos;
28     uint r;
29
30     h->origsize = h->compsize = 0;
31     h->file_crc = INIT_CRC;
32
33     headerpos = ftell(wp->fp);
34     write_header(wp->fp, h);
35     arcpos = ftell(wp->fp);
36
37     if (opts.quiet < 2)
38         printf(" %d.%d%%\n", r / 10, r % 10);
39     return 1;                   /* success */
40 }
41
42 static int
43 add_1(struct lzh_ostream *wp, int replace_flag, struct lzh_header *h)
44 {
45     long headerpos, arcpos;
46     uint r;
47
48     if ((infile = fopen(h->filename, "rb")) == NULL) {
49         fprintf(stderr, "Can't open %s\n", h->filename);
50         return 0;               /* failure */
51     }
52     if (replace_flag) {
53         if (opts.quiet < 2)
54             printf("Replacing %s ", h->filename);
55     }
56     else {
57         if (opts.quiet < 2)
58             printf("Adding %s ", h->filename);
59     }
60
61     headerpos = ftell(wp->fp);
62     write_header(wp->fp, h);
63     arcpos = ftell(wp->fp);
64
65     origsize = compsize = 0;
66     crc = INIT_CRC;
67     if (opts.nocompress) {
68         unpackable = 1;
69     }
70     else {
71         unpackable = 0;
72         encode(wp);
73     }
74
75     if (unpackable) {
76         memcpy(h->method, "-lh0-", sizeof(h->method));  /* store */
77         rewind(infile);
78         fseek(wp->fp, arcpos, SEEK_SET);
79         h->compsize = h->origsize = store(infile, wp->fp);
80     }
81     else {
82         h->compsize = compsize;
83         h->origsize = origsize;
84     }
85     h->file_crc = crc ^ INIT_CRC;
86     fclose(infile);
87
88     fseek(wp->fp, headerpos, SEEK_SET);
89     write_header(wp->fp, h);
90     fseek(wp->fp, 0L, SEEK_END);
91     r = ratio(compsize, origsize);
92     if (opts.quiet < 2)
93         printf(" %d.%d%%\n", r / 10, r % 10);
94     return 1;                   /* success */
95 }
96
97 int
98 add(struct lzh_ostream *wp, int replace_flag, char *filename, int namelen)
99 {
100     struct lzh_header h;
101     struct stat st;
102
103     memset(&h, 0, sizeof(h));
104
105     h.level = opts.header_level;
106
107     strcpy(h.filename, filename);
108     h.namelen = namelen;
109
110     stat(h.filename, &st);
111
112     h.mtime = st.st_mtime;
113     if (S_ISDIR(st.st_mode)) {
114         DIR *dir;
115         struct dirent *ent;
116
117         memcpy(h.method, "-lhd-", sizeof(h.method));  /* directory */
118         add_dir(wp, replace_flag, &h);
119
120         dir = opendir(h.filename);
121         if (dir == NULL)
122             error("cannot open directory: \"%s\"", h.filename);
123
124         while ((ent = readdir(dir)) != 0) {
125             char filename[1024];
126
127             if (string_equal(ent->d_name, ".") ||
128                 string_equal(ent->d_name, ".."))
129                 continue;
130
131             h.namelen = path_addsep(h.filename, sizeof(h.filename));
132
133             string_cat(filename, sizeof(filename),
134                        h.filename, ent->d_name, NULL);
135
136             add(wp, replace_flag, filename, strlen(filename));
137         }
138         closedir(dir);
139     }
140     else {
141         memcpy(h.method, opts.method->id, sizeof(h.method));  /* compress */
142         add_1(wp, replace_flag, &h);
143     }
144 }