OSDN Git Service

* src/util.c (str_safe_copy): newly added.
[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 size_t
19 copyfile(f1, f2, size, text_flg, crcp)  /* return: size of source file */
20     FILE *f1;
21     FILE *f2;
22     size_t size;
23     int text_flg;               /* 0: binary, 1: read text, 2: write text */
24     unsigned int *crcp;
25 {
26     unsigned short  xsize;
27     char *buf;
28     size_t rsize = 0;
29
30     if (!text_mode)
31         text_flg = 0;
32
33     buf = (char *)xmalloc(BUFFERSIZE);
34     if (crcp)
35         INITIALIZE_CRC(*crcp);
36     if (text_flg)
37         init_code_cache();
38     while (size > 0) {
39         /* read */
40         if (text_flg & 1) {
41             xsize = fread_txt(buf, BUFFERSIZE, f1);
42             if (xsize == 0)
43                 break;
44             if (ferror(f1)) {
45                 fatal_error("file read error");
46             }
47         }
48         else {
49             xsize = (size > BUFFERSIZE) ? BUFFERSIZE : size;
50             if (fread(buf, 1, xsize, f1) != xsize) {
51                 fatal_error("file read error");
52             }
53             if (size < xsize)
54                 size = 0;
55             else
56                 size -= xsize;
57         }
58
59         /* write */
60         if (f2) {
61             if (text_flg & 2) {
62                 if (fwrite_txt(buf, xsize, f2)) {
63                     fatal_error("file write error");
64                 }
65             }
66             else {
67                 if (fwrite(buf, 1, xsize, f2) != xsize) {
68                     fatal_error("file write error");
69                 }
70             }
71         }
72
73         /* calculate crc */
74         if (crcp) {
75             *crcp = calccrc(*crcp, buf, xsize);
76 #ifdef NEED_INCREMENTAL_INDICATOR
77             put_indicator(xsize);
78 #endif
79         }
80         rsize += xsize;
81     }
82     free(buf);
83     return rsize;
84 }
85
86 int
87 encode_stored_crc(ifp, ofp, size, original_size_var, write_size_var)
88     FILE *ifp, *ofp;
89     size_t size;
90     size_t *original_size_var;
91     size_t *write_size_var;
92 {
93     int save_quiet;
94     unsigned int crc;
95
96     save_quiet = quiet;
97     quiet = 1;
98     size = copyfile(ifp, ofp, size, 1, &crc);
99     *original_size_var = *write_size_var = size;
100     quiet = save_quiet;
101     return crc;
102 }
103
104 /* If TRUE, archive file name is msdos SFX file name. */
105 boolean
106 archive_is_msdos_sfx1(name)
107     char *name;
108 {
109     int len = strlen(name);
110
111     if (len >= 4) {
112         if (strcasecmp(".COM", name + len - 4) == 0 ||
113             strcasecmp(".EXE", name + len - 4) == 0)
114             return 1;
115     }
116
117     if (len >= 2 && strcasecmp(".x", name + len - 2) == 0)
118         return 1;
119
120     return 0;
121 }
122
123 /*
124  * strdup(3)
125  */
126 #ifndef HAVE_STRDUP
127 char *
128 strdup(buf)
129     const char *buf;
130 {
131     char *p;
132
133     if ((p = (char *) malloc(strlen(buf) + 1)) == NULL)
134         return NULL;
135     strcpy(p, buf);             /* ok */
136     return p;
137 }
138 #endif
139
140 /*
141  * memmove( char *dst , char *src , size_t cnt )
142  */
143 #ifndef HAVE_MEMMOVE
144 void *
145 memmove(dst, src, cnt)
146     register char *dst, *src;
147     register int cnt;
148 {
149     if (dst == src)
150         return dst;
151     if (src > dst) {
152         while (--cnt >= 0)
153             *dst++ = *src++;
154     }
155     else {
156         dst += cnt;
157         src += cnt;
158         while (--cnt >= 0)
159             *--dst = *--src;
160     }
161     return dst;
162 }
163 #endif
164
165 #ifndef HAVE_STRCASECMP
166 /* public domain rewrite of strcasecmp(3) */
167
168 #include <ctype.h>
169
170 int
171 strcasecmp(p1, p2)
172     const char *p1, *p2;
173 {
174     while (*p1 && *p2) {
175         if (toupper(*p1) != toupper(*p2))
176             return toupper(*p1) - toupper(*p2);
177         p1++;
178         p2++;
179     }
180     return strlen(p1) - strlen(p2);
181 }
182 #endif
183
184 #ifndef HAVE_MEMSET
185 /* Public Domain memset(3) */
186 char *
187 memset(s, c, n)
188     char *s;
189     int c;
190     size_t n;
191 {
192     char *p = s;
193
194     while (n--)
195         *p++ = (char) c;
196     return s;
197 }
198 #endif
199
200 int
201 #if STDC_HEADERS
202 xsnprintf(char *dest, size_t size, char *fmt, ...)
203 #else
204 xsnprintf(dest, size, fmt, va_alist)
205     char *dest, *fmt;
206     size_t size;
207     va_dcl
208 #endif
209 {
210     int len;
211     va_list v;
212
213     va_init(v, fmt);
214     len = vsnprintf(dest, size, fmt, v);
215     va_end(v);
216
217     if (len == -1)
218         return -1;
219
220     if (len >= size) {
221         dest[size-1] = 0;
222         return -1;
223     }
224
225     return 0;
226 }
227
228 #if !STRCHR_8BIT_CLEAN
229 /* 8 bit clean strchr()/strrchr()/memchr()/memrchr() */
230 char *
231 xstrchr(const char *s, int c)
232 {
233     if (c == 0)
234         return s + strlen(s);
235
236     while (*s) {
237         if ((unsigned char)*s == (unsigned char)c)
238             return (char*)s;
239         s++;
240     }
241
242     return 0;
243 }
244
245 char *
246 xstrrchr(const char *s, int c)
247 {
248     char *p = 0;
249
250     while (*s) {
251         if ((unsigned char)*s == (unsigned char)c)
252             p = (char*)s;
253         s++;
254     }
255
256     return p;
257 }
258
259 char *
260 xmemchr(const char *s, int c, size_t n)
261 {
262     char *end = (char*)s + n;
263
264     while (s != end) {
265         if ((unsigned char)*s == (unsigned char)c)
266             return (char*)s;
267         s++;
268     }
269
270     return 0;
271 }
272
273 char *
274 xmemrchr(const char *s, int c, size_t n)
275 {
276     char *end = (char*)s-1;
277     char *p = 0;
278
279     s += n-1;
280     while (s != end) {
281         if ((unsigned char)*s == (unsigned char)c)
282             p = (char*)s;
283         s--;
284     }
285
286     return p;
287 }
288 #endif
289
290 #ifndef HAVE_BASENAME
291 char *
292 basename(char *s)
293 {
294     int len;
295     char *t;
296
297     if (!s || *s == 0)
298         return ".";
299
300     /* strip trailing slashs */
301     t = s + strlen(s) - 1;
302     while (s != t && *t == '/')
303         *t-- = '\0';
304     if (s == t)
305         return s;
306
307     t = strrchr(s, '/');
308     if (t)
309         return t + 1;
310     else
311         return s;
312
313 }
314 #endif
315
316 /* This function is similar to strncpy() but `dst' is always terminated '\0'.
317    Return the copied string length. */
318 int
319 str_safe_copy(char *dst, const char *src, int dstsz)
320 {
321     int i;
322
323     if (dstsz < 1) return 0;
324
325     for (i = 0; i < dstsz; i++) {
326         if ((dst[i] = src[i]) == '\0')
327             return i;
328     }
329
330     /* here is i == dstsz */
331     dst[--i] = '\0';    /* if eliminated this line,
332                            this function was same as strncpy(). */
333
334     return i;
335 }