OSDN Git Service

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