OSDN Git Service

79ab837950ec3d9842b8d787075054e3874ed248
[lha/lha.git] / src / util.c
1 /* ------------------------------------------------------------------------ */
2 /* LHa for UNIX                                                                                                                         */
3 /*                              util.c -- LHarc Util                                                                            */
4 /*                                                                                                                                                      */
5 /*              Modified                        Nobutaka Watazaki                                                       */
6 /*                                                                                                                                                      */
7 /*      Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
8 /*  Ver. 1.14e  Support for sfx archives                1999.05.28      T.Okamoto       */
9 /* ------------------------------------------------------------------------ */
10 #include "lha.h"
11 /*
12  * util.c - part of LHa for UNIX Feb 26 1992 modified by Masaru Oki Mar  4
13  * 1992 modified by Masaru Oki #ifndef USESTRCASECMP added. Mar 31 1992
14  * modified by Masaru Oki #ifdef NOMEMSET added.
15  */
16 #include <errno.h>
17
18 /* ------------------------------------------------------------------------ */
19 extern unsigned short crc;
20 extern int      quiet;
21 /* ------------------------------------------------------------------------ */
22 long
23 copyfile(f1, f2, size, crc_flg) /* return: size of source file */
24         FILE           *f1;
25         FILE           *f2;
26         long            size;
27         int             crc_flg;/* 0: no crc, 1: crc check, 2: extract, 3:
28                                  * append */
29 {
30         unsigned short  xsize;
31         char           *buf;
32         long            rsize = 0;
33
34         if ((buf = (char *) malloc(BUFFERSIZE)) == NULL)
35                 fatal_error("virtual memory exhausted.\n");
36         crc = 0;
37         if ((crc_flg == 2 || crc_flg) && text_mode)
38                 init_code_cache();
39         while (size > 0) {
40                 /* read */
41                 if (crc_flg == 3 && text_mode) {
42                         xsize = fread_txt(buf, BUFFERSIZE, f1);
43                         if (xsize == 0)
44                                 break;
45                         if (ferror(f1)) {
46                                 fatal_error("file read error\n");
47                         }
48                 }
49                 else {
50                         xsize = (size > BUFFERSIZE) ? BUFFERSIZE : size;
51                         if (fread(buf, 1, xsize, f1) != xsize) {
52                                 fatal_error("file read error\n");
53                         }
54                 }
55                 /* write */
56                 if (f2) {
57                         if (crc_flg == 2 && text_mode) {
58                                 if (fwrite_txt(buf, xsize, f2)) {
59                                         fatal_error("file write error\n");
60                                 }
61                         }
62                         else {
63                                 if (fwrite(buf, 1, xsize, f2) != xsize) {
64                                         fatal_error("file write error\n");
65                                 }
66                         }
67                 }
68                 /* calculate crc */
69                 if (crc_flg) {
70                         calccrc(buf, xsize);
71                 }
72                 rsize += xsize;
73                 if (crc_flg != 3 || !text_mode)
74                         size -= xsize;
75         }
76         free(buf);
77         return rsize;
78 }
79
80 /* ------------------------------------------------------------------------ */
81 int
82 encode_stored_crc(ifp, ofp, size, original_size_var, write_size_var)
83         FILE           *ifp, *ofp;
84         long            size;
85         long           *original_size_var;
86         long           *write_size_var;
87 {
88         int             save_quiet;
89
90         save_quiet = quiet;
91         quiet = 1;
92         size = copyfile(ifp, ofp, size, 3);
93         *original_size_var = *write_size_var = size;
94         quiet = save_quiet;
95         return crc;
96 }
97
98 /* ------------------------------------------------------------------------ */
99 /*      convert path delimit
100         erreturns *filename                                                                                                             */
101 /* ------------------------------------------------------------------------ */
102 unsigned char  *
103 convdelim(path, delim)
104         unsigned char  *path;
105         unsigned char   delim;
106 {
107         unsigned char   c;
108         unsigned char  *p;
109 #ifdef MULTIBYTE_CHAR
110         int             kflg;
111
112         kflg = 0;
113 #endif
114         for (p = path; (c = *p) != 0; p++) {
115 #ifdef MULTIBYTE_CHAR
116                 if (kflg) {
117                         kflg = 0;
118                 }
119                 else if (MULTIBYTE_FIRST_P(c)) {
120                         kflg = 1;
121                 }
122                 else
123 #endif
124                 if (c == '\\' || c == DELIM || c == DELIM2) {
125                         *p = delim;
126                         path = p + 1;
127                 }
128         }
129         return path;
130 }
131
132 /* ------------------------------------------------------------------------ */
133 /* If TRUE, archive file name is msdos SFX file name. */
134 boolean
135 archive_is_msdos_sfx1(name)
136         char           *name;
137 {
138         int             len = strlen(name);
139
140         return ((len >= 4) &&
141                 (strucmp(".COM", name + len - 4) == 0 ||
142                  strucmp(".EXE", name + len - 4) == 0)) ||
143                 ((len >= 2) &&
144                  (strucmp(".x", name + len - 2) == 0));
145 }
146
147 /* ------------------------------------------------------------------------ */
148 /* skip SFX header */
149 boolean
150 skip_msdos_sfx1_code(fp)
151         FILE           *fp;
152 {
153         unsigned char   buffer[MAXSFXCODE];
154         unsigned char  *p, *q;
155         int             n;
156
157         n = fread(buffer, sizeof(char), MAXSFXCODE, fp);
158
159         for (p = buffer + 2, q = buffer + n - /* 5 */ (I_HEADER_LEVEL+1)-2; p < q; p++) {
160                 /* found "-l??-" keyword (as METHOD type string) */
161                 if (p[0] == '-' && p[1] == 'l' && p[4] == '-') {
162                         /* size and checksum validate check */
163                         if ( (p[I_HEADER_LEVEL-2] == 0 || p[I_HEADER_LEVEL-2] == 0)
164                                 && p[I_HEADER_SIZE-2] > 20
165                                 && p[I_HEADER_CHECKSUM-2] == calc_sum(p, p[-2])) {
166                                         fseek(fp, ((p - 2) - buffer) - n, SEEK_CUR);
167                                 return TRUE;
168                         } else if (p[I_HEADER_LEVEL-2] == 2 && p[I_HEADER_SIZE-2] >= 24
169                                            && p[I_ATTRIBUTE-2] == 0x20) {
170                                 fseek(fp, ((p - 2) - buffer) - n, SEEK_CUR);
171                                 return TRUE;
172                         }
173                 }
174         }
175
176         fseek(fp, -n, SEEK_CUR);
177         return FALSE;
178 }
179
180 /*
181  * strdup(3)
182  */
183
184 /* ------------------------------------------------------------------------ */
185 #ifndef HAVE_STRDUP
186 char           *
187 strdup(buf)
188         char           *buf;
189 {
190         char           *p;
191
192         if ((p = (char *) malloc(strlen(buf) + 1)) == NULL)
193                 return NULL;
194         strcpy(p, buf);
195         return p;
196 }
197 #endif
198
199 /*
200  * memmove( char *dst , char *src , size_t cnt )
201  */
202
203 /* ------------------------------------------------------------------------ */
204 #if defined(NOBSTRING) && !defined(__STDC__)
205 void           *
206 memmove(dst, src, cnt)
207         register char  *dst, *src;
208         register int    cnt;
209 {
210         if (dst == src)
211                 return dst;
212         if (src > dst) {
213                 while (--cnt >= 0)
214                         *dst++ = *src++;
215         }
216         else {
217                 dst += cnt;
218                 src += cnt;
219                 while (--cnt >= 0)
220                         *--dst = *--src;
221         }
222         return dst;
223 }
224 #endif
225
226 /*
227  * rename - change the name of file 91.11.02 by Tomohiro Ishikawa
228  * (ishikawa@gaia.cow.melco.CO.JP) 92.01.20 little modified (added #ifdef) by
229  * Masaru Oki 92.01.28 added mkdir() and rmdir() by Tomohiro Ishikawa
230  */
231
232 #if !defined(HAVE_FTRUNCATE) && !defined(_MINIX)
233
234 /* ------------------------------------------------------------------------ */
235 int
236 rename(from, to)
237         char           *from, *to;
238 {
239         struct stat     s1, s2;
240         extern int      errno;
241
242         if (stat(from, &s1) < 0)
243                 return (-1);
244         /* is 'FROM' file a directory? */
245         if ((s1.st_mode & S_IFMT) == S_IFDIR) {
246                 errno = ENOTDIR;
247                 return (-1);
248         }
249         if (stat(to, &s2) >= 0) {       /* 'TO' exists! */
250                 /* is 'TO' file a directory? */
251                 if ((s2.st_mode & S_IFMT) == S_IFDIR) {
252                         errno = EISDIR;
253                         return (-1);
254                 }
255                 if (unlink(to) < 0)
256                         return (-1);
257         }
258         if (link(from, to) < 0)
259                 return (-1);
260         if (unlink(from) < 0)
261                 return (-1);
262         return (0);
263 }
264 #endif                          /* !HAVE_FTRUNCATE */
265 /* ------------------------------------------------------------------------ */
266
267 #ifndef HAVE_MKDIR
268 #ifndef MKDIRPATH
269 #define MKDIRPATH       "/bin/mkdir"
270 #endif
271 #ifndef RMDIRPATH
272 #define RMDIRPATH       "/bin/rmdir"
273 #endif
274 int
275 rmdir(path)
276         char           *path;
277 {
278         int             stat, rtn = 0;
279         char           *cmdname;
280         if ((cmdname = (char *) malloc(strlen(RMDIRPATH) + 1 + strlen(path) + 1))
281             == 0)
282                 return (-1);
283         strcpy(cmdname, RMDIRPATH);
284         *(cmdname + strlen(RMDIRPATH)) = ' ';
285         strcpy(cmdname + strlen(RMDIRPATH) + 1, path);
286         if ((stat = system(cmdname)) < 0)
287                 rtn = -1;       /* fork or exec error */
288         else if (stat) {        /* RMDIR command error */
289                 errno = EIO;
290                 rtn = -1;
291         }
292         free(cmdname);
293         return (rtn);
294 }
295
296 /* ------------------------------------------------------------------------ */
297 int
298 mkdir(path, mode)
299         char           *path;
300         int             mode;
301 {
302         int             child, stat;
303         char           *cmdname, *cmdpath = MKDIRPATH;
304         if ((cmdname = (char *) strrchr(cmdpath, '/')) == (char *) 0)
305                 cmdname = cmdpath;
306         if ((child = fork()) < 0)
307                 return (-1);    /* fork error */
308         else if (child) {       /* parent process */
309                 while (child != wait(&stat))    /* ignore signals */
310                         continue;
311         }
312         else {                  /* child process */
313                 int             maskvalue;
314                 maskvalue = umask(0);   /* get current umask() value */
315                 umask(maskvalue | (0777 & ~mode));      /* set it! */
316                 execl(cmdpath, cmdname, path, (char *) 0);
317                 /* never come here except execl is error */
318                 return (-1);
319         }
320         if (stat != 0) {
321                 errno = EIO;    /* cannot get error num. */
322                 return (-1);
323         }
324         return (0);
325 }
326 #endif
327
328 /*
329  * strucmp modified: Oct 29 1991 by Masaru Oki
330  */
331
332 #ifndef HAVE_STRCASECMP
333 static int
334 my_toupper(n)
335         register int    n;
336 {
337         if (n >= 'a' && n <= 'z')
338                 return n & (~('a' - 'A'));
339         return n;
340 }
341
342 /* ------------------------------------------------------------------------ */
343 int
344 strucmp(s, t)
345         register char  *s, *t;
346 {
347         while (my_toupper(*s++) == my_toupper(*t++))
348                 if (!*s || !*t)
349                         break;
350         if (!*s && !*t)
351                 return 0;
352         return 1;
353 }
354 #endif
355
356 /* ------------------------------------------------------------------------ */
357 #ifndef HAVE_MEMSET
358 /* Public Domain memset(3) */
359 char           *
360 memset(s, c, n)
361         char           *s;
362         int             c, n;
363 {
364         char           *p = s;
365         while (n--)
366                 *p++ = (char) c;
367         return s;
368 }
369 #endif
370 /* Local Variables: */
371 /* tab-width : 4 */
372 /* End: */