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/* ------------------------------------------------------------------------ */
19extern unsigned short crc;
20extern int      quiet;
21/* ------------------------------------------------------------------------ */
22long
23copyfile(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/* ------------------------------------------------------------------------ */
81int
82encode_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/* ------------------------------------------------------------------------ */
102unsigned char  *
103convdelim(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. */
134boolean
135archive_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 */
149boolean
150skip_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#ifdef NOSTRDUP
186char           *
187strdup(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__)
205void           *
206memmove(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(NOFTRUNCATE) && !defined(_MINIX)
233
234/* ------------------------------------------------------------------------ */
235int
236rename(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				/* NOFTRUNCATE */
265/* ------------------------------------------------------------------------ */
266
267#ifdef	NOMKDIR
268#ifndef	MKDIRPATH
269#define	MKDIRPATH	"/bin/mkdir"
270#endif
271#ifndef	RMDIRPATH
272#define	RMDIRPATH	"/bin/rmdir"
273#endif
274int
275rmdir(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/* ------------------------------------------------------------------------ */
297int
298mkdir(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 USESTRCASECMP
333static int
334my_toupper(n)
335	register int    n;
336{
337	if (n >= 'a' && n <= 'z')
338		return n & (~('a' - 'A'));
339	return n;
340}
341
342/* ------------------------------------------------------------------------ */
343int
344strucmp(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#ifdef NOMEMSET
358/* Public Domain memset(3) */
359char           *
360memset(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
371/* Local Variables: */
372/* mode:c */
373/* tab-width:4 */
374/* compile-command:"gcc -c util.c" */
375/* End: */
376