/* ------------------------------------------------------------------------ */
-/* LHa for UNIX */
-/* util.c -- LHarc Util */
-/* */
-/* Modified Nobutaka Watazaki */
-/* */
-/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
-/* Ver. 1.14e Support for sfx archives 1999.05.28 T.Okamoto */
+/* LHa for UNIX */
+/* util.c -- LHarc Util */
+/* */
+/* Modified Nobutaka Watazaki */
+/* */
+/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
+/* Ver. 1.14e Support for sfx archives 1999.05.28 T.Okamoto */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/*
*/
#include <errno.h>
-/* ------------------------------------------------------------------------ */
-extern unsigned short crc;
-extern int quiet;
-/* ------------------------------------------------------------------------ */
-long
-copyfile(f1, f2, size, crc_flg) /* return: size of source file */
- FILE *f1;
- FILE *f2;
- long size;
- int crc_flg;/* 0: no crc, 1: crc check, 2: extract, 3:
- * append */
+off_t
+copyfile(f1, f2, size, text_flg, crcp) /* return: size of source file */
+ FILE *f1;
+ FILE *f2;
+ off_t size;
+ int text_flg; /* 0: binary, 1: read text, 2: write text */
+ unsigned int *crcp;
{
- unsigned short xsize;
- char *buf;
- long rsize = 0;
-
- buf = (char *)xmalloc(BUFFERSIZE);
- crc = 0;
- if ((crc_flg == 2 || crc_flg) && text_mode)
- init_code_cache();
- while (size > 0) {
- /* read */
- if (crc_flg == 3 && text_mode) {
- xsize = fread_txt(buf, BUFFERSIZE, f1);
- if (xsize == 0)
- break;
- if (ferror(f1)) {
- fatal_error("file read error");
- }
- }
- else {
- xsize = (size > BUFFERSIZE) ? BUFFERSIZE : size;
- if (fread(buf, 1, xsize, f1) != xsize) {
- fatal_error("file read error");
- }
- }
- /* write */
- if (f2) {
- if (crc_flg == 2 && text_mode) {
- if (fwrite_txt(buf, xsize, f2)) {
- fatal_error("file write error");
- }
- }
- else {
- if (fwrite(buf, 1, xsize, f2) != xsize) {
- fatal_error("file write error");
- }
- }
- }
- /* calculate crc */
- if (crc_flg) {
- calccrc(buf, xsize);
- }
- rsize += xsize;
- if (crc_flg != 3 || !text_mode)
- size -= xsize;
- }
- free(buf);
- return rsize;
+ unsigned short xsize;
+ char *buf;
+ off_t rsize = 0;
+
+ if (!text_mode)
+ text_flg = 0;
+
+ buf = (char *)xmalloc(BUFFERSIZE);
+ if (crcp)
+ INITIALIZE_CRC(*crcp);
+ if (text_flg)
+ init_code_cache();
+ while (size > 0) {
+ /* read */
+ if (text_flg & 1) {
+ xsize = fread_txt(buf, BUFFERSIZE, f1);
+ if (xsize == 0)
+ break;
+ if (ferror(f1)) {
+ fatal_error("file read error");
+ }
+ }
+ else {
+ xsize = (size > BUFFERSIZE) ? BUFFERSIZE : size;
+ if (fread(buf, 1, xsize, f1) != xsize) {
+ fatal_error("file read error");
+ }
+ if (size < xsize)
+ size = 0;
+ else
+ size -= xsize;
+ }
+
+ /* write */
+ if (f2) {
+ if (text_flg & 2) {
+ if (fwrite_txt(buf, xsize, f2)) {
+ fatal_error("file write error");
+ }
+ }
+ else {
+ if (fwrite(buf, 1, xsize, f2) != xsize) {
+ fatal_error("file write error");
+ }
+ }
+ }
+
+ /* calculate crc */
+ if (crcp) {
+ *crcp = calccrc(*crcp, buf, xsize);
+#ifdef NEED_INCREMENTAL_INDICATOR
+ put_indicator(xsize);
+#endif
+ }
+ rsize += xsize;
+ }
+ free(buf);
+ return rsize;
}
-/* ------------------------------------------------------------------------ */
int
encode_stored_crc(ifp, ofp, size, original_size_var, write_size_var)
- FILE *ifp, *ofp;
- long size;
- long *original_size_var;
- long *write_size_var;
+ FILE *ifp, *ofp;
+ off_t size;
+ off_t *original_size_var;
+ off_t *write_size_var;
{
- int save_quiet;
-
- save_quiet = quiet;
- quiet = 1;
- size = copyfile(ifp, ofp, size, 3);
- *original_size_var = *write_size_var = size;
- quiet = save_quiet;
- return crc;
+ int save_quiet;
+ unsigned int crc;
+
+ save_quiet = quiet;
+ quiet = 1;
+ size = copyfile(ifp, ofp, size, 1, &crc);
+ *original_size_var = *write_size_var = size;
+ quiet = save_quiet;
+ return crc;
}
-/* ------------------------------------------------------------------------ */
-/* convert path delimit
- erreturns *filename */
-/* ------------------------------------------------------------------------ */
-unsigned char *
-convdelim(path, delim)
- unsigned char *path;
- unsigned char delim;
-{
- unsigned char c;
- unsigned char *p;
-#ifdef MULTIBYTE_FILENAME
- int kflg;
-
- kflg = 0;
-#endif
- for (p = path; (c = *p) != 0; p++) {
-#ifdef MULTIBYTE_FILENAME
- if (kflg) {
- kflg = 0;
- }
- else if (MULTIBYTE_FIRST_P(c)) {
- kflg = 1;
- }
- else
-#endif
- if (c == '\\' || c == '/' || c == LHA_PATHSEP) {
- *p = delim;
- path = p + 1;
- }
- }
- return path;
-}
-
-/* ------------------------------------------------------------------------ */
/* If TRUE, archive file name is msdos SFX file name. */
boolean
archive_is_msdos_sfx1(name)
- char *name;
+ char *name;
{
- int len = strlen(name);
+ int len = strlen(name);
- return ((len >= 4) &&
- (strucmp(".COM", name + len - 4) == 0 ||
- strucmp(".EXE", name + len - 4) == 0)) ||
- ((len >= 2) &&
- (strucmp(".x", name + len - 2) == 0));
-}
+ if (len >= 4) {
+ if (strcasecmp(".COM", name + len - 4) == 0 ||
+ strcasecmp(".EXE", name + len - 4) == 0)
+ return 1;
+ }
-/* ------------------------------------------------------------------------ */
-/* skip SFX header */
-boolean
-skip_msdos_sfx1_code(fp)
- FILE *fp;
-{
- unsigned char buffer[MAXSFXCODE];
- unsigned char *p, *q;
- int n;
-
- n = fread(buffer, sizeof(char), MAXSFXCODE, fp);
-
- for (p = buffer + 2, q = buffer + n - /* 5 */ (I_HEADER_LEVEL+1)-2; p < q; p++) {
- /* found "-l??-" keyword (as METHOD type string) */
- if (p[0] == '-' && p[1] == 'l' && p[4] == '-') {
- /* size and checksum validate check */
- if ( (p[I_HEADER_LEVEL-2] == 0 || p[I_HEADER_LEVEL-2] == 0)
- && p[I_HEADER_SIZE-2] > 20
- && p[I_HEADER_CHECKSUM-2] == calc_sum(p, p[-2])) {
- fseek(fp, ((p - 2) - buffer) - n, SEEK_CUR);
- return TRUE;
- } else if (p[I_HEADER_LEVEL-2] == 2 && p[I_HEADER_SIZE-2] >= 24
- && p[I_ATTRIBUTE-2] == 0x20) {
- fseek(fp, ((p - 2) - buffer) - n, SEEK_CUR);
- return TRUE;
- }
- }
- }
-
- fseek(fp, -n, SEEK_CUR);
- return FALSE;
+ if (len >= 2 && strcasecmp(".x", name + len - 2) == 0)
+ return 1;
+
+ return 0;
}
/*
* strdup(3)
*/
-
-/* ------------------------------------------------------------------------ */
#ifndef HAVE_STRDUP
-char *
+char *
strdup(buf)
- char *buf;
+ const char *buf;
{
- char *p;
+ char *p;
- if ((p = (char *) malloc(strlen(buf) + 1)) == NULL)
- return NULL;
- strcpy(p, buf);
- return p;
+ if ((p = (char *) malloc(strlen(buf) + 1)) == NULL)
+ return NULL;
+ strcpy(p, buf); /* ok */
+ return p;
}
#endif
/*
* memmove( char *dst , char *src , size_t cnt )
*/
-
-/* ------------------------------------------------------------------------ */
#ifndef HAVE_MEMMOVE
-void *
+void *
memmove(dst, src, cnt)
- register char *dst, *src;
- register int cnt;
-{
- if (dst == src)
- return dst;
- if (src > dst) {
- while (--cnt >= 0)
- *dst++ = *src++;
- }
- else {
- dst += cnt;
- src += cnt;
- while (--cnt >= 0)
- *--dst = *--src;
- }
- return dst;
-}
-#endif
-
-/*
- * rename - change the name of file 91.11.02 by Tomohiro Ishikawa
- * (ishikawa@gaia.cow.melco.CO.JP) 92.01.20 little modified (added #ifdef) by
- * Masaru Oki 92.01.28 added mkdir() and rmdir() by Tomohiro Ishikawa
- */
-
-#if !defined(HAVE_FTRUNCATE) && !defined(_MINIX) && HAVE_LINK
-
-/* ------------------------------------------------------------------------ */
-int
-rename(from, to)
- const char *from, *to;
+ register char *dst, *src;
+ register int cnt;
{
- struct stat s1, s2;
- extern int errno;
-
- if (stat(from, &s1) < 0)
- return (-1);
- /* is 'FROM' file a directory? */
- if ((s1.st_mode & S_IFMT) == S_IFDIR) {
- errno = ENOTDIR;
- return (-1);
- }
- if (stat(to, &s2) >= 0) { /* 'TO' exists! */
- /* is 'TO' file a directory? */
- if ((s2.st_mode & S_IFMT) == S_IFDIR) {
- errno = EISDIR;
- return (-1);
- }
- if (unlink(to) < 0)
- return (-1);
- }
- if (link(from, to) < 0)
- return (-1);
- if (unlink(from) < 0)
- return (-1);
- return (0);
-}
-#endif /* !HAVE_FTRUNCATE */
-/* ------------------------------------------------------------------------ */
-
-#if !HAVE_MKDIR && HAVE_WORKING_FORK
-#ifndef MKDIRPATH
-#define MKDIRPATH "/bin/mkdir"
-#endif
-#ifndef RMDIRPATH
-#define RMDIRPATH "/bin/rmdir"
-#endif
-int
-rmdir(path)
- char *path;
-{
- int stat, rtn = 0;
- char *cmdname;
- if ((cmdname = (char *) malloc(strlen(RMDIRPATH) + 1 + strlen(path) + 1))
- == 0)
- return (-1);
- strcpy(cmdname, RMDIRPATH);
- *(cmdname + strlen(RMDIRPATH)) = ' ';
- strcpy(cmdname + strlen(RMDIRPATH) + 1, path);
- if ((stat = system(cmdname)) < 0)
- rtn = -1; /* fork or exec error */
- else if (stat) { /* RMDIR command error */
- errno = EIO;
- rtn = -1;
- }
- free(cmdname);
- return (rtn);
-}
-
-/* ------------------------------------------------------------------------ */
-int
-mkdir(path, mode)
- char *path;
- int mode;
-{
- int child, stat;
- char *cmdname, *cmdpath = MKDIRPATH;
- if ((cmdname = (char *) strrchr(cmdpath, '/')) == (char *) 0)
- cmdname = cmdpath;
- if ((child = fork()) < 0)
- return (-1); /* fork error */
- else if (child) { /* parent process */
- while (child != wait(&stat)) /* ignore signals */
- continue;
- }
- else { /* child process */
- int maskvalue;
- maskvalue = umask(0); /* get current umask() value */
- umask(maskvalue | (0777 & ~mode)); /* set it! */
- execl(cmdpath, cmdname, path, (char *) 0);
- /* never come here except execl is error */
- return (-1);
- }
- if (stat != 0) {
- errno = EIO; /* cannot get error num. */
- return (-1);
- }
- return (0);
+ if (dst == src)
+ return dst;
+ if (src > dst) {
+ while (--cnt >= 0)
+ *dst++ = *src++;
+ }
+ else {
+ dst += cnt;
+ src += cnt;
+ while (--cnt >= 0)
+ *--dst = *--src;
+ }
+ return dst;
}
#endif
-/*
- * strucmp modified: Oct 29 1991 by Masaru Oki
- */
-
#ifndef HAVE_STRCASECMP
-static int
-my_toupper(n)
- register int n;
-{
- if (n >= 'a' && n <= 'z')
- return n & (~('a' - 'A'));
- return n;
-}
+/* public domain rewrite of strcasecmp(3) */
+
+#include <ctype.h>
-/* ------------------------------------------------------------------------ */
int
-strucmp(s, t)
- register char *s, *t;
+strcasecmp(p1, p2)
+ const char *p1, *p2;
{
- while (my_toupper(*s++) == my_toupper(*t++))
- if (!*s || !*t)
- break;
- if (!*s && !*t)
- return 0;
- return 1;
+ while (*p1 && *p2) {
+ if (toupper(*p1) != toupper(*p2))
+ return toupper(*p1) - toupper(*p2);
+ p1++;
+ p2++;
+ }
+ return strlen(p1) - strlen(p2);
}
#endif
-/* ------------------------------------------------------------------------ */
#ifndef HAVE_MEMSET
/* Public Domain memset(3) */
-char *
+char *
memset(s, c, n)
- char *s;
- int c, n;
+ char *s;
+ int c;
+ size_t n;
{
- char *p = s;
- while (n--)
- *p++ = (char) c;
- return s;
+ char *p = s;
+
+ while (n--)
+ *p++ = (char) c;
+ return s;
}
#endif
char *
xstrchr(const char *s, int c)
{
+ if (c == 0)
+ return s + strlen(s);
+
while (*s) {
if ((unsigned char)*s == (unsigned char)c)
return (char*)s;
}
#endif
-/* Local Variables: */
-/* mode:c */
-/* tab-width:4 */
-/* compile-command:"gcc -c util.c" */
-/* End: */
-/* vi: set tabstop=4: */
+#ifndef HAVE_BASENAME
+char *
+basename(char *s)
+{
+ int len;
+ char *t;
+
+ if (!s || *s == 0)
+ return ".";
+
+ /* strip trailing slashs */
+ t = s + strlen(s) - 1;
+ while (s != t && *t == '/')
+ *t-- = '\0';
+ if (s == t)
+ return s;
+
+ t = strrchr(s, '/');
+ if (t)
+ return t + 1;
+ else
+ return s;
+
+}
+#endif
+
+/* This function is similar to strncpy() but `dst' is always
+ terminated by '\0'. Return the copied string length. */
+int
+str_safe_copy(char *dst, const char *src, int dstsz)
+{
+ int i;
+
+ if (dstsz < 1) return 0;
+
+ for (i = 0; i < dstsz; i++) {
+ if ((dst[i] = src[i]) == '\0')
+ return i;
+ }
+
+ /* here is i == dstsz */
+ dst[--i] = '\0'; /* if eliminated this line,
+ this function was same as strncpy(). */
+
+ return i;
+}