comparison lwar/replace.c @ 0:2c24602be78f

Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
author lost@l-w.ca
date Wed, 19 Jan 2011 22:27:17 -0700
parents
children 7317fbe024af
comparison
equal deleted inserted replaced
-1:000000000000 0:2c24602be78f
1 /*
2 replace.c
3 Copyright © 2009 William Astle
4
5 This file is part of LWAR.
6
7 LWAR is free software: you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation, either version 3 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
16
17 You should have received a copy of the GNU General Public License along with
18 this program. If not, see <http://www.gnu.org/licenses/>.
19
20 */
21
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "lwar.h"
28
29 void do_replace(void)
30 {
31 FILE *f;
32 FILE *nf;
33 unsigned char buf[8];
34 long l;
35 int c;
36 FILE *f2;
37 int i;
38 char fnbuf[1024];
39 char fnbuf2[1024];
40
41 sprintf(fnbuf, "%s.tmp", archive_file);
42
43 f = fopen(archive_file, "r+");
44 if (!f)
45 {
46 if (errno == ENOENT)
47 {
48 nf = fopen(fnbuf, "w");
49 if (nf)
50 {
51 fputs("LWAR1V", nf);
52 goto doadd;
53 }
54 }
55 perror("Cannot open archive file");
56 }
57
58 fread(buf, 1, 6, f);
59 if (memcmp("LWAR1V", buf, 6))
60 {
61 fprintf(stderr, "%s is not a valid archive file.\n", archive_file);
62 exit(1);
63 }
64
65 nf = fopen(fnbuf, "w");
66 if (!nf)
67 {
68 perror("Cannot create temp archive file");
69 exit(1);
70 }
71
72 fputs("LWAR1V", nf);
73
74 for (;;)
75 {
76 c = fgetc(f);
77 if (c == EOF && ferror(f))
78 {
79 perror("Reading archive file");
80 exit(1);
81 }
82 if (c == EOF)
83 goto doadd;
84
85 if (!c)
86 {
87 goto doadd;
88 }
89
90 // find the end of the file name
91 i = 0;
92 while (c)
93 {
94 fnbuf2[i++] = c;
95 c = fgetc(f);
96 if (c == EOF || ferror(f))
97 {
98 fprintf(stderr, "Bad archive file\n");
99 exit(1);
100 }
101 }
102 fnbuf2[i] = 0;
103
104 // get length of archive member
105 l = 0;
106 c = fgetc(f);
107 l = c << 24;
108 c = fgetc(f);
109 l |= c << 16;
110 c = fgetc(f);
111 l |= c << 8;
112 c = fgetc(f);
113 l |= c;
114
115 // is it a file we are replacing? if so, do not copy it
116 for (i = 0; i < nfiles; i++)
117 {
118 if (!strcmp(files[i], fnbuf2))
119 break;
120 }
121 if (i < nfiles)
122 {
123 fseek(f, l, SEEK_CUR);
124 }
125 else
126 {
127 // otherwise, copy it
128 fprintf(nf, "%s", fnbuf2);
129 fputc(0, nf);
130 fputc(l >> 24, nf);
131 fputc((l >> 16) & 0xff, nf);
132 fputc((l >> 8) & 0xff, nf);
133 fputc(l & 0xff, nf);
134 while (l)
135 {
136 c = fgetc(f);
137 fputc(c, nf);
138 l--;
139 }
140 }
141 }
142
143 // done with the original file
144 fclose(f);
145 doadd:
146 for (i = 0; i < nfiles; i++)
147 {
148 f2 = fopen(files[i], "r");
149 if (!f2)
150 {
151 fprintf(stderr, "Cannot open file %s:", files[i]);
152 perror("");
153 exit(1);
154 }
155 fread(buf, 1, 6, f2);
156 if (mergeflag && !memcmp("LWAR1V", buf, 6))
157 {
158 // add archive contents...
159 for (;;)
160 {
161 c = fgetc(f2);
162 if (c == EOF || ferror(f2))
163 {
164 perror("Reading input archive file");
165 exit(1);
166 }
167 if (c == EOF)
168 break;
169
170 if (!c)
171 {
172 break;
173 }
174
175 // find the end of the file name
176 while (c)
177 {
178 fputc(c, nf);
179 c = fgetc(f2);
180 if (c == EOF || ferror(f))
181 {
182 fprintf(stderr, "Bad input archive file\n");
183 exit(1);
184 }
185 }
186 fputc(0, nf);
187
188 // get length of archive member
189 l = 0;
190 c = fgetc(f2);
191 fputc(c, nf);
192 l = c << 24;
193 c = fgetc(f2);
194 fputc(c, nf);
195 l |= c << 16;
196 c = fgetc(f2);
197 fputc(c, nf);
198 l |= c << 8;
199 c = fgetc(f2);
200 fputc(c, nf);
201 l |= c;
202
203 while (l)
204 {
205 c = fgetc(f2);
206 fputc(c, nf);
207 l--;
208 }
209 }
210
211 fclose(f2);
212 continue;
213 }
214 fseek(f2, 0, SEEK_END);
215 l = ftell(f2);
216 fseek(f2, 0, SEEK_SET);
217 fputs(files[i], nf);
218 fputc(0, nf);
219 fputc(l >> 24, nf);
220 fputc((l >> 16) & 0xff, nf);
221 fputc((l >> 8) & 0xff, nf);
222 fputc(l & 0xff, nf);
223 while (l)
224 {
225 c = fgetc(f2);
226 fputc(c, nf);
227 l--;
228 }
229 }
230
231 // flag end of file
232 fputc(0, nf);
233
234 fclose(nf);
235
236 if (rename(fnbuf, archive_file) < 0)
237 {
238 perror("Cannot replace old archive file");
239 unlink(fnbuf);
240 }
241 }