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