OSDN Git Service

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