home *** CD-ROM | disk | FTP | other *** search
- /*{{{ defines*/
-
- /*************************************************
- LHarc version 1.13b (c)Yoshi, 1988-89.
- main module : 1989/ 5/14
-
- adaption to ATARI ST with TURBO-C 1.1
- and some corrections
- by J. Moeller 1990/01/31
-
- Assembly and more corrections with
- Turbo-C 1.0, 2.0, by Thomas Quester
-
- HTAB = 4
- *************************************************/
-
- #define ThisSystem 'A' /* Atari */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <process.h>
- #include <stdlib.h>
- #include <setjmp.h>
- #include <errno.h>
- #include <tos.h>
-
- #ifdef Japanese
- #include "usage_j.h"
- #else
- #ifdef German
- #include "usage_d.h"
- #else
- #include "usage_e.h"
- #endif
- #endif
- #define from extern
- #ifndef __TOS__
- #include <alloc.h>
- #include <fcntl.h>
- #include <io.h>
- #include <dir.h>
- #include <dos.h>
- #else
- #include <ext.h>
- #include <tos.h>
- #define MAXPATH 119
- #define MAXDIR 102
- #define MAXNUMFILES 128
- #define far
- #define huge
- #define setmode(stream,mode) /* sorry: no such function known */
- #include "goodputc.h"
- #endif
-
- #define UNKNOWNERR 0
- #define INVCMDERR 1
- #define MANYPATERR 2
- #define NOARCNMERR 3
- #define NOFNERR 4
- #define NOARCERR 5
- #define RENAMEERR 6
- #define MKTMPERR 7
- #define DUPFNERR 8
- #define TOOMANYERR 9
- #define TOOLONGERR 10
- #define NOFILEERR 11
- #define MKFILEERR 12
- #define RDERR 13
- #define WTERR 14
- #define MEMOVRERR 15
- #define INVSWERR 16
- #define CTRLBRK 17
- #define NOMATCHERR 18
- #define COPYERR 19
- #define NOTLZH 20
- #define OVERWT 21
- #define MKDIR 22
- #define MKDIRERR 23
- #define CRCERR 24
- #define RDONLY 25
-
-
- #ifndef __TOS__
- #define PAGER "less"
- #define BUFFERSIZ 4096L
- #else
- #define PAGER "less.ttp"
- #define BUFFERSIZ 16384L
- #endif
- #define MAXBLK 64
- #define MAX_PAT 512
- #define FAULT 0
- #define SUCCS ~FAULT
-
- #ifndef __TOS__
- #define getch() (bdos(0x08, 0, 0) & 0xff)
- #endif
- #define min(a,b) ((a>b) ? b : a)
- typedef unsigned char uchar;
- typedef unsigned int uint;
- typedef unsigned long ulong;
-
- FILE *file1, *file2, *file3;
- from FILE *infile;
- from FILE *outfile;
- from int FileFits; /* 1, wenn File passt */
- int cmd; /* command */
- int cmdupdate; /* Not zero, when updating archive */
- int errorlevel = 0; /* return value */
- jmp_buf exit_jmp; /* Jump to exit of program */
- extern long textsize; /* file size before compression */
- extern long codesize; /* file size after compression */
- from long blocksize; /* Bytes bis "*" (norm. 4096) */
- long arcpos0; /* position pointer for archive */
- uchar *basedir; /* base directory (home-directory) */
- uchar *wdir = ""; /* work directory */
- uchar workdir[MAXPATH]; /* work directory */
- uchar *infname; /* input file name (for error message) */
- uchar *outfname; /* output file name (for error message)*/
- int attr; /* file attributes for search files */
- int Nfile; /* number of files which was found */
- /* >> fbmax is used to compute the total amout used by filenames << */
- ulong fblft, fbsize;
- ulong fbmax,fbfiles; /* for buffers handling file names */
- #ifndef __TOS__
- uint seg; /* beginning segment of file name buffers */
- #endif
- uchar far *fbuf, huge *fbnxt; /* pointer to file name buffers */
- uchar arcname[MAXPATH]; /* archive name */
- uchar pathname[MAXPATH]; /* work for file name (extracting) */
- uchar dospathname[MAXPATH]; /* work for filename (8+3 chars) */
- uchar filename[MAXPATH]; /* work for file name (for file in archive) */
- uchar comment[MAXPATH]; /* Komments in archives */
- uchar SystemId; /* Archiv createt on system */
- uchar freezing=0; /* Enables extended headers */
- uchar UseExthdr=0; /* 1, if gethdr has to use exthdrs */
- int patno; /* No. of path names in command line */
- int UnixFile; /* !=0 if filename is not 8+3 */
- uchar patfile[MAX_PAT][12]; /* file name in command line */
- uchar *patpath[MAX_PAT]; /* directory name in command line */
- int patcnt[MAX_PAT]; /* counts which this name matched */
- uchar patnul[] = "*.*"; /* default path name */
- uchar backup1[MAXPATH], backup2[MAXPATH]; /* temporary file names */
- char *TheInputBuf; /* Input-Buffer */
- char *TheOutputBuf;
- from int unpackable;
- /* temporary file names */
- uchar flg_r = 0, flg_p = 0, flg_x = 0, flg_m = 0;
- uchar flg_a = 0, flg_c = 0, flg_v = 0, flg_w = 0;
- uchar flg_d = 0, flg_u = 0, flg_s = 0, flg_k = 0;
- uchar flg_e = 0;
- uchar flg_unpacked; /* Set to 1, if 100% used in pack_afx */
- uchar elen=3;
-
- from uchar flg_n = 0;
- uchar flg_t = 0;
- uchar flg_5 = 0;
- uchar flg_arc = 0,flg_backup=0;
- uchar method=5, FlgMethod=5;
- #ifdef __TOS__
- uchar flg_h = 0;
- #endif
- /* switches */
- uchar copying = 0; /* turn on when copying temporary file */
- uchar crcflg = 0; /* force copyfile() to calculate CRC*/
- uchar tstflg = 0; /* turn on in 't' command */
- uchar swchar; /* switch character */
- uchar *pager = PAGER; /* utility used in 'p /v' mode */
- from uint crc; /* calculated CRC code */
- uchar *keyword = ""; /* key word for auto-execution */
-
- struct filebuf { /* work for file name buffer */
- void far *next;
- uchar fpos; /* position of file name */
- uchar cpos; /* position of effective path name */
- uchar dir[MAXDIR]; /* full path name */
- } fb0, fb1;
-
- extern char *errmes[]; /* array of pointers to error messages */
- /* extern uchar use[]; */ /* usage */
- extern uchar buf2[], buf3[]; /* I/O buffers */
-
- #ifdef Japanese
- /* routines for handling Japanese strings (import from util.c) */
- extern uchar *j_strupr(uchar *p);
- extern int j_strcmp(char *p, char *q);
- extern uchar *j_strchr(char *p, uint c);
- extern uchar *j_strrchr(char *p, uint c);
- extern void slash2yen(uchar *p); /* convert '/' to '\' */
- extern void yen2shlas(uchar *p);
-
- #define strupr j_strupr
- #define strcmp j_strcmp
- #define strchr j_strchr
- #define strrchr j_strrchr
- #else
- extern void slash2yen(uchar *p); /* convert '/' to '\' */
- extern void yen2slash(uchar *p);
-
- /* #define slash2yen(p) */ /*
- extern void slash2yen(uchar *p); /* convert '/' to '\' */
-
- #endif
-
- extern int getfattr(uchar *fn); /* get file attributes */
- extern void setfattr(uchar *fn, int attr);/* set file attributes */
- #ifndef __TOS__
- extern uchar getswchar(void); /* get switch character */
- extern int test_afx(char *s); /* Überprüft, ob Datei gepackt ist */
- #else
- extern char *stpcpy (char *dest, char *source);
- extern int mkdir (char *path);
- #define getswchar() ('/')
- #endif
-
- #ifdef __TOS__
- struct outbuf
- {
- char *ptr; /* aktuelles Zeichen */
- char *last; /* letztes Zeichen */
- char *base; /* erstes Zeichen */
- FILE *file; /* dateiname */
- } OutBufMem;
- struct outbuf *OutBuf;
-
- #endif __TOS__
-
- extern void mkcrc (void); /* import from 'LZS.*' */
- extern void copyfile (FILE *Source, FILE *Dest, long size);
- extern void Encode (void); /* import from 'LZHUF.*' */
- extern ulong encode5(ulong orgsize);
- extern void init_encode5(void);
- extern void EncodeOld(void);
- extern void Decode (void);
- extern void decode_lh5(ulong orgsize,ulong pacsize);
- extern void DecodeOld(void);
-
- extern char M_NOMATCHERR[];
- extern char M_COPYERR[];
- extern char M_NOTLZH[];
- extern char M_OVERWT[];
- extern char M_MKDIR[];
- extern char M_MKDIRERR[];
- extern char M_CRCERR[];
- extern char M_RDONLY[];
-
- struct ftime arcstamp /* = {0L} */; /* time stamp for archive */
-
- struct LzHead { /* file header */
- uchar HeadSiz, HeadChk, HeadID[5];
- ulong PacSiz, OrgSiz; /* 16- and 32-bit Intel format !!!*/
- struct ftime Ftime;
- uint Attr;
- uchar Fname[MAXPATH]; /* packed filename + crc */
- } Hdr1, Hdr2;
-
- #ifndef __TOS__
- struct exeHead { /* EXE header for SFX */
- uint exeID, byte, page, reloc;
- uint hdrsize, minalloc, maxalloc, initSS;
- uint initSP, chksum, initIP, initCS;
- uint reloctab, overlay, dummy1, dummy2;
- } ExeHdr = {
- 'MZ', 0, 0, 0, 2, 0, 0xffff, 0xfff0,
- 0x100, 0, 0x100, 0xfff0, 0x1e, 0, 0, 0
- };
- #endif
-
- #define FTimeToUIntTime(t) ((((t.ft_hour << 6) | t.ft_min) << 5) | t.ft_tsec)
- #define FTimeToUIntDate(t) ((((t.ft_year << 4) | t.ft_month) << 5) | t.ft_day)
- #define FTimeToULong(t) (((ulong)FTimeToUIntDate(t) << 16) | \
- (ulong)FTimeToUIntTime(t))
-
- uchar mksum(struct LzHead *h);
-
- #ifdef __TOS__
- extern int argvmain (int, uchar **, uchar **);
-
- static DTA _mydta;
- #endif __TOS__
- /*}}} */
- /*{{{ setcrc:*/
-
-
- #ifndef __TOS__
- #define setcrc(h, crc) (*(uint *)(&(h)->Fname[1]+(h)->Fname[0])=(crc))
- #define getcrc(h) (*(uint *)(&(h)->Fname[1]+(h)->Fname[0]))
- #else
- static void setcrc (struct LzHead *h, uint crc)
- {
- uchar *CrcPtr = &h->Fname[1] + h->Fname[0];
-
- *CrcPtr++ = (uchar)(crc & 0xff);
- *CrcPtr++ = (uchar)(crc >> 8);
- *CrcPtr++ = (uchar)(ThisSystem); /* SystemId */
- if (freezing==0) {
- /* *CrcPtr++ = (uchar) 0;
- *CrcPtr++ = (uchar) 0; */
- }
- }
- /*}}} */
- /*{{{ getcrc:*/
-
- static uint getcrc (struct LzHead *h)
- {
- uchar *CrcPtr = &h->Fname[1] + h->Fname[0];
-
- return ((uint)*CrcPtr) | ((uint)*(CrcPtr + 1) << 8);
- }
- #endif
- /*}}} */
- /*{{{ usage: display helps*/
- /*******************************
- display helps
- *******************************/
- void usage(void)
- {
- int i;
- char *s,c;
- s=use;
- i=1;
- while ( (c=*s++) != 0) {
- if (c=='\n')
- if (i++ == 24) {
- fflush (stdin); /* wait for keystroke when used */
- printf ("\n%s",M_PRESSKEY); /* with GEM-Desktop */
- getch ();
- putchar ('\n');
- i=1;
- }
- putchar(c);
- }
- putchar ('\n');
- longjmp (exit_jmp, 1);
- }
- /*}}} */
- /*{{{ message: Display a message*/
-
- /*******************************
- display a message
- *******************************/
-
- void message(uchar *p, uchar *q)
- {
- if (flg_d == 0) {
- printf("%s", p);
- if (q) {
- printf(" : '%s'", q);
- }
- printf("\n");
- }
- }
- /*}}} */
- /*{{{ error: process for an error*/
-
- /*******************************
- process for an error
- *******************************/
- void error(int errcode, uchar *p)
- {
- if (copying) { /* error during copying temporary? */
- fprintf(stderr, "\n%s\n", M_COPYERR);
- fclose(file1);
- unlink(arcname); /* erase incomplete archive */
- file1 = NULL;
- }
- fprintf(stderr, "\n%s", errmes[errcode]);
- if (p) {
- fprintf(stderr, " : '%s'", p);
- }
- fprintf(stderr, "\n");
- if (file3) {
- fclose(file3);
- if (!cmdupdate) /* during extracting */
- unlink(pathname); /* delete the file */
- file3=NULL;
- }
- if (file1) {
- fclose(file1);
- if (cmdupdate) /* during updating */
- rename(backup1, arcname); /* recover old archive */
- }
- if (file2) {
- fclose(file2);
- if (!copying) { /* if not copying */
- unlink(backup2); /* delete temporary */
- file2=NULL;
- }
- }
- if (copying)
- errorlevel = 3;
- else
- errorlevel = 2;
- longjmp (exit_jmp, 1);
- }
-
- /*}}} */
- /*{{{ userbreak: handle user break*/
- /*******************************
- handle user break
- *******************************/
- #ifndef __TOS__
- void userbreak(void)
- {
- error(CTRLBRK, NULL);
- }
- #endif
- /*}}} */
- /*{{{ e_fopen: fopen with detecting error*/
-
- /*******************************
- fopen with detecting error
- *******************************/
- FILE *e_fopen(uchar *fname, uchar *mode, int errID)
- {
- FILE *f;
-
- if ((f = fopen(fname, mode)) == NULL) {
- if (errno == EACCES)
- error(RDONLY, fname);
- error(errID, fname);
- }
- return f;
- }
- /*}}} */
- /*{{{ e_rename: rename with detecting erorr*/
-
- /*******************************
- rename with detecting error
- *******************************/
- void e_rename(uchar *old, uchar *new)
- {
- if (rename(old, new))
- error(RENAMEERR, old);
- }
- /*}}} */
- /*{{{ getyn: ask 'Y' or 'N'*/
- /*******************************
- ask 'Y' or 'N'
- *******************************/
- uint getyn(void)
- {
- uint yn;
-
- do {
- yn = toupper(getch());
- #ifdef German
- } while (yn != 'J' && yn != 'N');
- #else
- } while (yn != 'Y' && yn != 'N');
- #endif
- fprintf(stderr, "%c\n", yn);
- #ifdef German
- if (yn == 'J') yn = 'Y';
- #endif
- return yn;
- }
- /*}}} */
- /*{{{ getynr: ask 'Y', 'N' or 'R'*/
- /*******************************
- ask 'Y' or 'N'
- *******************************/
- uint getynr(void)
- {
- uint yn;
-
- do {
- yn = toupper(getch());
- #ifdef German
- } while (yn != 'J' && yn != 'N' && yn != 'R');
- #else
- } while (yn != 'Y' && yn != 'N' && yn != 'R');
- #endif
- fprintf(stderr, "%c\n", yn);
- #ifdef German
- if (yn == 'J') yn = 'Y';
- #endif
- return yn;
- }
- /*}}} */
- /*{{{ extfn: File name -> internal format*/
-
- /*******************************
- file name -> internal format
- *******************************/
- void extfn(uchar *p, uchar *pb)
- {
- int i;
- uchar * q;
-
- if ((q = strrchr(p, '\\')) != NULL ||
- (q = strchr(p, ':')) != NULL)
- p = q + 1;
- q = p;
- for (i = 8; i > 0; i--, pb++) {
- switch (*p) {
- case '*':
- *pb = '?';
- break;
- case '.':
- case '\0':
- *pb = ' ';
- break;
- default:
- *pb = *p++;
- }
- }
- while (+(*p != '\0' && *p++ != '.'));
- for (i = 3; i > 0; i--, pb++) {
- switch (*p) {
- case '*':
- *pb = '?';
- break;
- case '\0':
- *pb = ' ';
- break;
- default:
- *pb = *p++;
- }
- }
- *q = *pb = '\0';
- }
- /*}}} */
- /*{{{ packfn: internal format -> file name*/
-
- /*******************************
- internal format -> file name
- *******************************/
- void packfn(uchar *p, uchar *q)
- {
- int i;
-
- for (i = 8; i > 0; i--) {
- if (*q != ' ')
- *p++ = *q;
- q++;
- }
- *p++ = '.';
- for (i = 3; i > 0; i--) {
- if (*q != ' ')
- *p++ = *q;
- q++;
- }
- if (p[-1] == '.')
- p--;
- *p = '\0';
- }
- /*}}} */
- /*{{{ backpath get back to parent directory*/
- /*******************************
- get back to parent directory
- *******************************/
- uchar *backpath(uchar *p)
- {
- uchar *q;
-
- if ((q = strrchr(p, '\\')) == NULL &&
- (q = strchr(p, ':')) == NULL) {
- *p = '\0';
- q = p;
- } else {
- *++q = '\0';
- }
- return q;
- }
- /*}}} */
- /*{{{ tstpat : whether path name was used or not*/
-
- /***********************************
- whether path name was used or not
- ***********************************/
- void tstpat(void)
- {
- int i, cnt;
- uchar path[MAXPATH];
-
- cnt = 0;
- for (i = 0; i < patno; i++)
- cnt += patcnt[i];
- if (cnt == 0) /* no file matched */
- error(NOFILEERR, NULL);
- for (i = 0; i < patno; i++) {
- if (patcnt[i] == 0) { /* if any path name was not used */
- packfn(stpcpy(path, patpath[i]), patfile[i]);
- fprintf(stderr, "%s : '%s'\n", M_NOMATCHERR, path);
- errorlevel = 1; /* display warning */
- }
- }
- }
- /*}}} */
- /*{{{ sethdr: make a file header*/
-
- /*******************************
- make a file header
- *******************************/
- void sethdr(uchar *fn, uint attr, struct LzHead *h)
- {
- uint l;
-
- memset(h, 0, sizeof(struct LzHead));
- l = (uint)strlen(fn); /* length of file name */
- h -> Fname[0] = l;
- memcpy(h -> Fname + 1, fn, l);
- l += 20 + elen +2; /* size of header */
- h -> HeadSiz = l;
- fseek(file3, 0L, SEEK_END);
- h -> OrgSiz = textsize = ftell(file3); /* original size of a file */
- h -> PacSiz = codesize = 0;
- method=FlgMethod;
- /* if (h->OrgSiz < 5000 && FlgMethod==5) method=1; */
- rewind(file3);
- getftime(fileno(file3), &(h -> Ftime)); /* get time stamp */
- h -> Attr = attr; /* file attributes */
- if (method==0) memcpy(h->HeadID,"-lz5-",5);
- if (method==1) memcpy(h->HeadID,"-lh1-",5);
- if (method==5) memcpy(h->HeadID,"-lh5-",5);
- if (cmd== 'C') memcpy(h->HeadID,"-afx-",5);
- }
- /*}}} */
- /*{{{ wthdr680x0: write a file header on atari (or any system)*/
-
- #ifdef __TOS__
- /*******************************
- write a file header on
- Atari ST (680x0)
- *******************************/
- int wthdr680x0 (register struct LzHead *h,
- FILE *file)
- {
- uchar buffer [256];
- uchar chksum,*ptr2;
- int comlen;
- register uchar *ptr,*co,*ptr1;
- union { uint x;
- uchar bytes [2]; } swap16;
- union { ulong x;
- uchar bytes [4]; } swap32;
-
- register int i;
- int len;
- char c;
-
- if (comment[0] == 0) comlen = 0; else
- { comlen = 4 + strlen(comment);
- h->PacSiz += comlen; }
- if (flg_s) yen2slash(&(h->Fname));
- h -> HeadChk = mksum(h); /* header sum */
-
- ptr = buffer;
- *ptr++ = h->HeadSiz;
- *ptr++ = h->HeadChk;
- for (i = 0; i < 5; i++)
- *ptr++ = h->HeadID [i];
- swap32.x = h->PacSiz;
- for (i = 3; i >= 0; i--) /* convert motorola --> intel */
- *ptr++ = swap32.bytes [i];
- swap32.x = h->OrgSiz;
- for (i = 3; i >= 0; i--) /* convert motorola --> intel */
- *ptr++ = swap32.bytes [i];
- swap32.x = FTimeToULong (h->Ftime);
- for (i = 3; i >= 0; i--) /* convert motorola --> intel */
- *ptr++ = swap32.bytes [i];
- swap16.x = h->Attr;
- for (i = 1; i >= 0; i--) /* convert motorola --> intel */
- *ptr++ = swap16.bytes [i];
- len = *ptr++ = h->Fname [0];
- for (i = 1; i <= len + elen+2; i++) *ptr++ = h->Fname[i];
- if (freezing && flg_k==0) {
- ptr2=ptr-1;
- if (comlen) {
- ptr-=2;
- *ptr++=comlen;
- *ptr++=0;
- *ptr++=0x3f;
- co=comment;
- while (*co) *ptr++=*co++;
- *ptr++=0xff;
- *ptr++=0x0;
- *ptr++=0x0;
- }
- ptr1=&buffer[2];
- chksum=0;
- while (ptr1 != ptr2)
- chksum = chksum + *ptr1++;
- buffer[1]=chksum;
- len = (int) fwrite (buffer, ptr-buffer , 1, file);
- } else
- len = (int) fwrite (buffer, h->HeadSiz +2 , 1, file);
-
-
- /* slash2yen(&(h->Fname)); */
- h -> HeadChk = mksum(h); /* header sum */
- return len;
- }
- #endif
- /*}}} */
- /*{{{ wthdr: write a file header*/
-
- /*******************************
- write a file header
- *******************************/
- void wthdr(struct LzHead *h)
- {
- arcpos0 = ftell(file2); /* memorize this position */
- #ifndef __TOS__
- if (fwrite(h, h -> HeadSiz + 2, 1, file2) == 0)
- error(WTERR, backup2);
- #else
- if (wthdr680x0 (h, file2) == 0)
- error(WTERR, backup2);
- #endif
- }
- /*}}} */
- /*{{{ mksum: calculate check-sum*/
- /*******************************
- calculate check-sum of header
- *******************************/
- uchar umksum(struct LzHead *h)
- {
- uchar *p, *q;
- uchar i;
-
- p = (uchar *)h ;
- q = p + h -> HeadSiz;
- p+=2; q+=2;
- for (i = 0; p < q; p++)
- i += *p;
- return i;
- }
-
- #ifndef __TOS__
- uchar mksum(struct LzHead *h)
- {
- uchar *p, *q;
- uchar i;
-
- p = (uchar *)h + 2;
- q = p + h -> HeadSiz;
- for (i = 0; p < q; p++)
- i += *p;
- return i;
- }
- #else
- uchar mksum(struct LzHead *h)
- {
- union { uint x;
- uchar bytes [2]; } swap16;
- union { ulong x;
- uchar bytes [4]; } swap32;
- char *s;
- register uchar sum;
- register int i;
- int len;
-
- sum = 0;
- for (i = 0; i < 5; i++)
- sum += h->HeadID [i];
- swap32.x = h->PacSiz;
- for (i = 3; i >= 0; i--)
- sum += swap32.bytes [i];
- swap32.x = h->OrgSiz;
- for (i = 3; i >= 0; i--)
- sum += swap32.bytes [i];
- swap32.x = FTimeToULong (h->Ftime);
- for (i = 3; i >= 0; i--)
- sum += swap32.bytes [i];
- swap16.x = h->Attr;
- for (i = 1; i >= 0; i--)
- sum += swap16.bytes [i];
- sum += h->Fname [0];
- len = (int) h->Fname [0];
- s=h->Fname; s++;
- for (i = 1; i <= h->HeadSiz - 20; i++)
- sum += *s++;
-
- return sum;
- }
- #endif
- /*}}} */
- /*{{{ remkhdr: remake file header and write*/
-
- /*******************************
- remake file header & write
- *******************************/
- void remkhdr(struct LzHead *h)
- {
- int flg;
- long arcpos1;
-
- flg = 0;
- h -> PacSiz = codesize; /* packed size of a file */
- setcrc (h, crc);
- flg_unpacked=0;
- if (h -> OrgSiz <= codesize && flg_5==0) { /* if packed size >= original size */
- flg = 1; /* select method "simple copy" */
- flg_unpacked=1;
- memcpy(h->HeadID,"-lh0-",5);
- h -> PacSiz = h -> OrgSiz;
- }
- h -> HeadChk = mksum(h); /* header sum */
-
- if (flg_u && flg_5 == 0) { /* without compression */
- crcflg=1; crc=0;
- copyfile(file3, file2, h -> OrgSiz); /* do simple copy */
- flg = 0;
- setcrc(h,crc);
- }
- arcpos1 = ftell(file2); /* memorize this position */
- fseek(file2, arcpos0, SEEK_SET); /* seek to header */
- #ifndef __TOS__
- fwrite(h, h -> HeadSiz + 2, 1, file2); /* rewrite header */
- #else
- wthdr680x0 (h, file2);
- #endif
- if (flg && flg_5 == 0) {
- rewind(file3);
- copyfile(file3, file2, h -> OrgSiz); /* do simple copy */
- } else {
- fseek(file2, arcpos1, SEEK_SET); /* return to the end */
- }
- }
- /*}}} */
- /*{{{ rdhdr680x0: read a file header on Atari*/
- #ifdef __TOS__
- /*******************************
- read a file header on
- Atari ST (680x0)
- *******************************/
- int rdhdr680x0 (register struct LzHead *h,
- FILE *file)
- {
- uchar buffer [sizeof (struct LzHead)];
- register uchar *ptr;
- union { uint x;
- uchar bytes [2]; } swap16;
- union { ulong x;
- uchar bytes [4]; } swap32;
- register int i;
- int len;
-
- if ((h -> HeadSiz = getc (file)) <= 0 ||
- ferror (file) ||
- h->HeadSiz > sizeof buffer - 1 ||
- fread (buffer, (int) h->HeadSiz + 1, 1, file) == 0)
- {
- return FAULT;
- }
-
- ptr = buffer;
- h->HeadChk = *ptr++;
- for (i = 0; i < 5; i++)
- h->HeadID [i] = *ptr++;
- for (i = 3; i >= 0; i--) /* convert intel --> motorola */
- swap32.bytes [i] = *ptr++;
- h->PacSiz = swap32.x;
- for (i = 3; i >= 0; i--) /* convert intel --> motorola */
- swap32.bytes [i] = *ptr++;
- h->OrgSiz = swap32.x;
- for (i = 3; i >= 0; i--) /* convert intel --> motorola */
- swap32.bytes [i] = *ptr++;
- h->Ftime.ft_tsec = (uint)(swap32.x & 0x1f);
- h->Ftime.ft_min = (uint)((swap32.x >> 5) & 0x3f);
- h->Ftime.ft_hour = (uint)((swap32.x >> 11) & 0x1f);
- h->Ftime.ft_day = (uint)((swap32.x >> 16) & 0x1f);
- h->Ftime.ft_month = (uint)((swap32.x >> 21) & 0x0f);
- h->Ftime.ft_year = (uint)((swap32.x >> 25) & 0x7f);
- for (i = 1; i >= 0; i--) /* convert intel --> motorola */
- swap16.bytes [i] = *ptr++;
- h->Attr = swap16.x;
- for (i=0;i<=MAXPATH;i++) h->Fname[i]=0;
- len = h->Fname [0] = *ptr++;
- for (i = 1; i <= h->HeadSiz - 20; i++)
- h->Fname [i] = *ptr++;
-
- return SUCCS;
- }
- #endif
- /*}}} */
- /*{{{ gethdr : get a file header*/
- /*******************************
- get a file header
- *******************************/
- uchar *gethdr(FILE *arc, struct LzHead *h)
- {
- uchar *q,*p,*p1, i;
- uint extsize;
- char exthdr[256];
- char fname[256];
-
- #ifndef __TOS__
- if ((h -> HeadSiz = getc(arc)) <= 0 ||
- h -> HeadSiz > sizeof(struct LzHead) - 3 ||
- fread(&(h -> HeadChk), h -> HeadSiz + 1, 1, arc) == 0)
- { /* read file header */
- return NULL;
- }
- #else
- if (!rdhdr680x0 (h, arc))
- return NULL;
- #endif
- if (mksum(h) != h -> HeadChk)
- if (umksum(h) != h -> HeadChk) /* if sum is wrong */
- return NULL;
- i = *(h -> Fname);
- strncpy(filename, h -> Fname + 1, i);
- *(filename + i) = '\0';
-
- if ( (flg_k == 0) && UseExthdr) {
- extsize=h->Fname[h->Fname[0]+4];
- SystemId = h->Fname[h->Fname[0]+3];
- comment[0] = 0; /* Prevent showing an illegal comment */
- if (extsize != 0) {
- fread(exthdr,1,extsize-2,arc);
- /* h->PacSiz-=extsize;
- extsize=fgetc(arc);
- extsize+=(uint)fgetc(arc)<<8; */
- while (extsize != 0) {
- if (exthdr[0] == 2) { /* pathname-header */
- p=fname; p1=&exthdr[1];
- while ( (*p++=*p1++) != 0xff);
- p--;
- *p++='\\';
- strcpy(p,filename);
- strcpy(filename,fname);
- }
- if (exthdr[0] == 0x3f) { /* Komment - Header */
- p=comment;p1=&exthdr[1];
- while ((*p++=*p1++) != 0xff); p--; *p=0;
- }
-
- h->PacSiz-=extsize;
- extsize=fgetc(arc);
- extsize+=(uint)fgetc(arc)<<8;
-
- if (extsize) {
- if (extsize > 250) {
- fseek(arc,extsize-2,SEEK_CUR); /* Header to long, skip */
- exthdr[0]=255; }
- else {
- fread(exthdr,1,extsize-2,arc);
- }
- }
-
- }
- }
- }
- if ((q = strrchr(filename, '\\')) == NULL &&
- (q = strrchr(filename, '/')) == NULL &&
- (q = strchr(filename, ':')) == NULL)
- q = filename;
- else
- q++;
- return q; /* return the portion of file name */
- }
- /*}}} */
- /*{{{ matchpat: test match of file name*/
- /*******************************
- test match of file name
- *******************************/
- int matchpat(uchar *p)
- {
- uchar buf[12], name[MAXPATH];
- int i, j, retcode;
-
- retcode = FAULT;
- strcpy(name, p);
- extfn(name, buf);
- for (i = 0; i < patno; i++) {
- if (flg_p || *patpath[i]) { /* should compare full path ? */
- if (strcmp(name, patpath[i]))
- continue;
- }
- for (j = 0; j < 11; j++) { /* compare file name */
- if (patfile[i][j] != buf[j] && patfile[i][j] != '?')
- break;
- }
- if (j == 11) { /* if matched */
- patcnt[i]++;
- retcode = SUCCS;
- }
- }
- return retcode;
- }
- /*}}} */
- /*{{{ ratio: ratio * 1000*/
- /*******************************
- ratio * 1000
- *******************************/
- uint ratio(ulong a, ulong b)
- {
- int i;
-
- if (!b) return 0; /* if diviser == 0 */
- for (i = 0; i < 3 && a < 0x19999999L; i++) {
- a *= 10; /* while not overflow */
- } /* upto 1000 times */
- for (; i < 3; i++) { /* the case of overflow */
- b /= 10;
- }
- a += b / 2; /* for round up */
- return (uint)(a / b); /* return (a * 1000 / b) */
- }
- /*}}} */
- /*{{{ cmpname: compare names*/
- /*******************************
- compare names
- *******************************/
- int cmpname(uchar *f0, uchar *f1, uchar *p0, uchar *p1)
- {
- int c;
-
- c = strcmp(f0, f1); /* compare only file names */
- if (c == 0) {
- c = (int)(strlen(p0) - strlen(p1)); /* compare lengths of path names */
- if (c == 0) {
- c = strcmp(p0, p1); /* compare path names */
- }
- }
- return c;
- }
- /*}}} */
- /*{{{ regfile: regist file names*/
- /*******************************
- regist file names
- *******************************/
- int regfile(uchar *p, uchar *q, uchar *f, int attrib)
- /*
- p: full path name including base directory
- q: directory name to be registed
- f: file name
- */
- {
- uchar path[MAXPATH];
- struct filebuf far *f0;
- struct filebuf far *f1;
- uchar *s;
- int c,size;
-
- if (flg_arc)
- if ((attrib & 0x20) == 0) return 0;
-
- if (strstr(f, "LHARC.)1(") || strstr(f, "LHARC.)2("))
- return 0; /* temporary file ? */
- stpcpy(stpcpy(path, q), f);
- stpcpy(s = stpcpy(fb1.dir, p), f);
- fb1.fpos = s - (uchar *)&fb1;
- fb1.cpos = flg_x ? (q - p) + (fb1.dir - (uchar *)&fb1) : fb1.fpos;
- if (fbuf == NULL) { /* for first entry */
- fbfiles=0; /* >> Number of files matched << */
- #ifndef __TOS__
- if (allocmem(fbsize = 0x100, &seg) != -1)
- error(MEMOVRERR, NULL);
- fbuf = (uchar far *)fbnxt = MK_FP(seg, 0);
- fbleft = 0x100;
-
- #else
- /* >> get all the memory. fbmax holds the number of bytes available << */
- fbsize=sizeof(struct filebuf) * MAXNUMFILES;
- fbmax= (long) Malloc(-1);
- fbuf = fbnxt = Malloc(fbmax);
- if (fbuf == NULL)
- error(MEMOVRERR, NULL);
- fblft = fbmax;
- #endif
- *(long far *)fbuf = 0;
- fbnxt += 4;
- }
- f0 = (struct filebuf far *)fbuf;
- do { /* search position in which should be inserted*/
- f1 = f0;
- if ((f0 = f0 -> next) == NULL)
- break;
- fb0 = *f0;
- c = cmpname((uchar *)&fb0 + fb0.fpos, (uchar *)&fb1 + fb1.fpos,
- (uchar *)&fb0 + fb0.cpos, (uchar *)&fb1 + fb1.cpos);
- } while (c < 0);
-
- if (f0 && c == 0 && strcmp(fb0.dir, fb1.dir)) {
- error(DUPFNERR, (uchar *)&fb1 + fb1.cpos);
- } /* same registing names of different files */
-
- if (f0 == NULL || c) { /* do regist */
- size = (int)(strlen(fb1.dir) +
- (fb1.dir - (uchar *)&fb1)) + 1;
- #ifndef __TOS__
- if (fblft < sizeof(struct filebuf)) { /* if buffer is short */
- if (setblock(seg, fbsize += 0x100) != -1)
- error(TOOMANYERR, NULL);
- fblft += 0x100;
- }
- #else
- size += size & 1; /* size must be even to avoid address error! */
- if (fblft < sizeof (struct filebuf))
- error(TOOMANYERR, NULL);
- #endif
- fb1.next = f0;
- f0 = (struct filebuf far *)fbnxt;
- f1 -> next = f0;
- *f0 = fb1;
- fblft -= size;
- fbnxt += size;
- fbfiles++; /* >> Count files << */
- }
- return 1;
- }
- /*}}} */
- /*{{{ travel: recursive collection of files*/
- /*******************************
- recursive collection of files
- *******************************/
- int travel(uchar *p, uchar *q, uchar *f)
- {
- struct ffblk ffb;
- static uchar buf[12];
- uchar *r, *s;
- int done, cnt, j;
-
- cnt = 0;
- if (flg_r == 1 || strrchr(q, '\\') == q + strlen(q) - 1) {
- stpcpy(s = q + strlen(q), "*.*");
- }
- done = findfirst(p, &ffb, attr); /* search the first file */
- s = backpath(q);
- while (! done) {
- if (ffb.ff_attrib & 0x10) { /* if this is a sub-directory */
- if (ffb.ff_name[0] != '.') {
- r = stpcpy(stpcpy(s, ffb.ff_name), "\\");
- if (r - p > MAXPATH)
- error(TOOLONGERR, p);
- cnt += travel(p, q, f); /* search recursively */
- *s = '\0';
- }
- } else /* if this is a file */
- if (flg_r == 2) { /* in /r2 mode */
- cnt += regfile(p, q, ffb.ff_name,ffb.ff_attrib); /* regist name */
- } else { /* in /r+ mode */
- stpcpy(s, ffb.ff_name);
- extfn(s, buf);
- for (j = 0; j < 11; j++) { /* test file names */
- if (f[j] != buf[j] && f[j] != '?')
- break;
- }
- if (j == 11) {
- cnt += regfile(p, q, ffb.ff_name,ffb.ff_attrib); /* if match, regist */
- }
- }
- done = findnext(&ffb);
- }
- return cnt; /* number of registed files */
- }
- /*}}} */
- /*{{{ findfile: non-recursive collection of files*/
- /**********************************
- non-recursive collection of files
- **********************************/
- int findfile(uchar *p, uchar *q)
- {
- struct ffblk ffb;
- int done, cnt;
-
- cnt = 0;
- done = findfirst(p, &ffb, attr);
- backpath(p);
- while (! done) {
- cnt += regfile(p, q, ffb.ff_name,ffb.ff_attrib);
- done = findnext(&ffb);
- }
- return cnt;
- }
- /*}}} */
- /*{{{ mklilst: make file list to append*/
- /*******************************
- make file lists to append
- *******************************/
- void mklist(void)
- {
- uchar path[MAXPATH], *p, *q, *r;
- int i, cnt;
-
- Nfile = 0;
- if (flg_a) { /* set attributes for search */
- attr = 0x07;
- } else {
- attr = 0;
- }
- if (flg_r) {
- attr |= 0x10;
- }
- for (i = 0; i < patno; i++) {
- p = patpath[i];
- q = path;
- if (*p && p[1] == ':') { /* if path name includes drive */
- q = stpcpy(path, p); /* ignore base directory */
- r = path + 2; /* don't regist drive name */
- } else {
- q = stpcpy(r = stpcpy(path, basedir), p);
- }
- if (flg_r == 1) { /* /r+ mode */
- cnt = travel(path, r, patfile[i]);
- } else if (flg_r > 1) { /* /r2 mode */
- packfn(q, patfile[i]);
- cnt = travel(path, r, NULL);
- } else { /* /r- mode */
- packfn(q, patfile[i]);
- cnt = findfile(path, r);
- }
- Nfile += patcnt[i] = cnt;
- }
-
- #ifdef __TOS__
- /* >> After registering all files, free the unused memory << */
- Mshrink(0,fbuf,fbmax-fblft+5);
- if (flg_d == 0) printf("Files matched: %ld\n",fbfiles);
- #endif
- }
- /*}}} */
- /*{{{ mkhdr: make file header*/
- /*******************************
- make file header
- *******************************/
- uchar *mkhdr(struct filebuf far *f, struct LzHead *h)
- {
- int attr;
-
- fb0 = *f;
- attr = getfattr(fb0.dir);
- file3 = e_fopen(fb0.dir, "rb", RDERR);
-
- sethdr((uchar *)&fb0 + fb0.cpos, attr, h);
- return (uchar *)&fb0 + fb0.fpos; /* position of file name */
- }
-
- extern uint blkcnt;
- uint curcnt;
- uint nxtcnt;
- /*}}} */
- /*{{{ blkdisp: calculate and display*/
- /*******************************
- calculate and display
- for indicator
- *******************************/
-
- void blkdisp(long l, char *s) {
- uint i;
-
- if (flg_n == 0) {
- blocksize=4096;
- printf("\n %s : ", s);
- blkcnt = (uint)((l + 4095) / 4096);
- if (blkcnt > MAXBLK) {
- blkcnt = MAXBLK;
- blocksize= l / MAXBLK;
- }
- i = blkcnt;
- while (i-- > 0) {
- putchar('.');
- }
- printf("\r %s : ", s);
- curcnt = nxtcnt = 0;
- } else {
- curcnt = 0;
- nxtcnt = -1;
- }
- }
- /*}}} */
- /*{{{ curback: let cursor back after displaying indicator*/
-
- /*******************************
- let cursor back after
- displaying indicator
- *******************************/
- void curback(void)
- {
- if (flg_n == 0) {
- printf("\r ");
- }
- }
- /*}}} */
- /*{{{ MKinputbuf: make buffers for reading*/
-
- /* Try to read the complete file. If the position is odd, begin reading at */
- /* an even position and dicard one byte */
-
- void MKinputbuf(long filesize)
- {
- long bufsize;
- long Pos;
-
- bufsize=(long)Malloc(-1)-50000;
- if (bufsize < 0) bufsize=8192;
- bufsize=min(filesize,bufsize)+1024;
- TheInputBuf=(char *) Malloc(bufsize+2);
- if (TheInputBuf < 0) error(MEMOVRERR,NULL);
- if (TheInputBuf>0) {
- if ((bufsize & 1) == 1) bufsize--; /* Make bufsize even */
- if ((ftell(infile) & 1) == 1) { /* Odd position */
- fseek(infile,ftell(infile)-1,0); /* go to even pos. */
- setvbuf(infile,TheInputBuf, _IOFBF, bufsize); /* set buffer */
- getc(infile); /* fill buffer, dicard char */
- } else
- { fseek(infile,ftell(infile),0); /* even position is ok */
- setvbuf(infile,TheInputBuf, _IOFBF, bufsize);
- }
- FileFits=1; /* signal file fits into mem */
- } else FileFits=0;
-
-
- }
- /*}}} */
- /*{{{ mkoutboutb Make buffers for writing*/
-
- void MKoutputbuf( void )
- {
- long bufsize;
- char *start,ende;
- bufsize=(long)Malloc(-1)-20000;
- TheOutputBuf=Malloc(bufsize);
- fseek(outfile,ftell(outfile),0);
- if (TheOutputBuf>0) {
- setvbuf(outfile,TheOutputBuf,_IOFBF,bufsize);
- } else {
- setvbuf(outfile,buf3,_IOFBF,BUFFERSIZ);
- }
- }
- /*}}} */
- /*{{{ freeze: freeze a file*/
-
-
- /*******************************
- freeze a file
- *******************************/
- void freeze(uchar *p)
- {
- char *hp;
- char iname[128];
- if (FTimeToULong (arcstamp) < FTimeToULong (Hdr2.Ftime))
- arcstamp = Hdr2.Ftime;
- strcpy(iname,p);
-
- freezing=1;
- if (flg_d == 0) printf("%s ", p);
- if (flg_e) { /* Enter comment THQ */
- printf("\n");
- printf(M_COMMENT);
- gets(comment);
- }
-
- if (method!=5)
- blkdisp(Hdr2.OrgSiz, "Freezing ");
- else
- blkdisp(Hdr2.OrgSiz/2, "Freezing ");
-
-
- wthdr(&Hdr2);
- if (method == 5) init_encode5();
- setvbuf(file3, buf3, _IOFBF, BUFFERSIZ);
- infile = file3;
- outfile = file2;
- MKinputbuf(Hdr2.OrgSiz);
- infname = p;
- textsize = Hdr2.OrgSiz;
- crc = 0;
- codesize=0;
- if (flg_u) codesize = Hdr2.OrgSiz + 1; else {
- if (method==0) EncodeOld();
- if (method==1) Encode();
- if (method==5) codesize=encode5(Hdr2.OrgSiz);
- }
- fflush(outfile);
-
- fseek(infile,ftell(infile),0);
- setvbuf(file3,buf3,_IOFBF,BUFFERSIZ);
- fseek(file2,0,SEEK_END);
-
- Mfree(TheInputBuf);
-
- if (flg_backup)
- Fattrib(iname,1,Fattrib(iname,0,0) & 0xff-0x20);
- remkhdr(&Hdr2);
- curback();
- if (flg_d == 0) printf("Frozen(%3d%%) \n", ratio(Hdr2.PacSiz, Hdr2.OrgSiz) / 10);
- comment[0] = 0;
- freezing=0;
- }
- /*}}} */
- /*{{{ copyold: copy file from old archiv*/
-
-
- /*******************************
- Copy a file from
- old archive
- *******************************/
- void copyold(void)
- {
- if (FTimeToULong (arcstamp) < FTimeToULong (Hdr1.Ftime))
- arcstamp = Hdr1.Ftime;
- wthdr(&Hdr1); /* copy from old archive */
- copyfile(file1, file2, Hdr1.PacSiz);
- }
- /*}}} */
- /*{{{ execappend: execute one of a, u, m commands*/
-
- /*******************************
- execute one of a, u, m
- commands
- *******************************/
- int execappend(void)
- {
- struct filebuf far *f0;
- uchar *p, *q;
- int c, d;
- int cnt = 0;
-
- q = file1 ? gethdr(file1, &Hdr1) : NULL; /* read header from old arc */
- if ((f0 = ((struct filebuf far *)fbuf) -> next) != NULL) {
- p = mkhdr(f0, &Hdr2); /* make header from the file list */
- }
- while (1) {
- if (f0 == NULL) {
- d = 1;
- if (q == NULL)
- break;
- } else if (q == NULL) {
- d = -1;
- } else {
- d = cmpname(p, q, (uchar *)&fb0 + fb0.cpos, filename);
- }
- c = d;
- if (c == 0) {
- if (flg_c || FTimeToULong (Hdr1.Ftime) <
- FTimeToULong (Hdr2.Ftime)) {
- c = -1;
- } else {
- c = 1;
- }
- }
- if (c < 0) { /* freeze a new file */
- if (d == 0) {
- fseek(file1, Hdr1.PacSiz, SEEK_CUR);
- q = gethdr(file1, &Hdr1); /* skip a file in old */
- } /* archive */
- freeze(fb0.dir);
- fclose(file3);
- cnt++;
- if ((f0 = fb0.next) != NULL) { /* make header of the next */
- p = mkhdr(f0, &Hdr2); /* file in file list */
- }
- } else { /* copy a file from old archive */
- if (d == 0) {
- fclose(file3);
- if ((f0 = fb0.next) != NULL) { /* make header of the next */
- p = mkhdr(f0, &Hdr2); /* file in file list */
- }
- }
- copyold();
- q = gethdr(file1, &Hdr1); /* get the next header */
- } /* in old archive */
- }
- return cnt;
- }
- /*}}} */
- /*{{{ delfile: delete files after execution of updating in 'm' command*/
-
- /*******************************
- delete files after
- execution of updating
- in 'm' command
- *******************************/
- void delfile(void)
- {
- struct filebuf far *f0;
- struct filebuf fb0;
-
- f0 = (struct filebuf far *)fbuf;
- while ((f0 = f0 -> next) != NULL) {
- fb0 = *f0;
- unlink(fb0.dir);
- };
- }
- /*}}} */
- /*{{{ openarc1: open an old archiv*/
-
- /*******************************
- open an old archive
- *******************************/
- void openarc1(void)
- {
- uchar *p, *q;
-
- file1 = e_fopen(infname = arcname, "rb", NOARCERR);
- /* >> Because some SFX-Versions for the ST have a header bigger 2048 Bytes
- 4096 bytes are read here << */
- q = buf2 - 5 + fread(buf2, 1, 4096, file1);
- for (p = buf2; p < q; p++) {
- if (p[0] == '-' && p[4] == '-')
- if (p[1] == 'l' || p[1] == 'a') break;
- }
- if (p >= q) {
- error(NOFILEERR, arcname);
- }
- fseek(file1, (long)(p - buf2 - 2), SEEK_SET);
- }
- /*}}} */
- /*{{{ openrwarc1: open an archiv in rd/wt for testing read-only*/
-
- /*******************************
- open an archive in rd/wt
- for testing read-only
- *******************************/
- void openrwarc1(void)
- {
- file1 = e_fopen(arcname, "r+b", NOARCERR);
- }
- /*}}} */
- /*{{{ openbackup1 close an old archiv & rename to temporary*/
- /*******************************
- close an old archive
- & rename to temporary
- *******************************/
- static void openbackup1(void)
- {
- fclose(file1);
- stpcpy(backpath(strcpy(backup1, arcname)), "lharc.)1(");
- e_rename(arcname, backup1);
- file1 = fopen(infname = backup1, "rb");
- }
- /*}}} */
- /*{{{ openbackup2 open a temporary file for a new archiv*/
- /*******************************
- open a temporary file
- for a new archive
- *******************************/
- static void openbackup2(void)
- {
- if (flg_w) {
- stpcpy(stpcpy(backup2, workdir), "lharc.)2(");
- } else {
- strcat(backpath(strcpy(backup2, arcname)), "lharc.)2(");
- }
- file2 = e_fopen(outfname = backup2, "w+b", MKTMPERR);
- setvbuf(file2, buf2, _IOFBF, BUFFERSIZ);
- }
- /*}}} */
- /*{{{ stclosearc: set time & close an archive*/
- /*******************************
- set time & close an archive
- *******************************/
- void stclosearc(FILE *f)
- {
- if (flg_t) {
- fflush(f);
- setftime(fileno(f), &arcstamp);
- }
- fclose(f);
- }
- /*}}} */
- /*{{{ endofupdate end-of-job process in making new archive*/
-
- /*******************************
- end-of-job process
- in making new archive
- *******************************/
- void endofupdate(int cnt)
- {
- if (file1)
- stclosearc(file1);
- tstpat();
- if (cnt) { /* if any files are manipulated */
- if (file1)
- if (unlink(backup1)) /* delete an old archive */
- printf("debug : Failed in deleting '%s'.", backup1);
- if ((arcpos0 = ftell(file2)) != 0) {
- if (putc(0, file2) == EOF)
- error(WTERR, backup2);
- if (flg_w) { /* if work directory is assigned */
- rewind(file2);
- infname = backup2;
- copying = 1; /* copy temporary to new archive */
- file1 = e_fopen(outfname = arcname, "wb", MKFILEERR);
- if (flg_d == 0) printf("Copying Temp to Archive ...");
- copyfile(file2, file1, arcpos0 + 1);
- if (flg_d == 0) printf("\n");
- copying = 0;
- stclosearc(file1);
- fclose(file2);
- unlink(backup2);
- } else {
- stclosearc(file2); /* else rename temporary to archive */
- rename(backup2, arcname);
- }
- } else {
- fclose(file2);
- unlink(backup2);
- }
- } else { /* if no change was made in archive */
- fclose(file2);
- unlink(backup2);
- rename(backup1, arcname); /* restore the old archive */
- }
- }
- /*}}} */
- /*{{{ append: a,u,m command*/
- /*******************************
- a, u, m command
- *******************************/
- void append(void)
- {
- int cnt;
-
- file1 = fopen(arcname, "r+b");
- if (file1) {
- openbackup1(); /* if archive presents, rename to temp */
- } else {
- if (errno == EACCES)
- error(RDONLY, arcname); /* read-only error */
- }
- mklist(); /* make a file list */
- if (Nfile == 0) {
- error(NOFILEERR, NULL);
- }
- if (file1) {
- message("Updating archive", arcname);
- } else {
- message("Creating archive", arcname);
- }
- openbackup2(); /* open temporary for new archive */
- cnt = execappend(); /* execute updating archive */
- endofupdate(cnt); /* end-of-job process */
- if (cmd == 'M')
- delfile(); /* if 'm' command, delete files */
- #ifndef __TOS__
- freemem(seg);
- #else
- free (fbuf);
- #endif
- }
- /*}}} */
- /*{{{ open_afxb: open backup-file for afx*/
- void open_afxbackup(char *s)
- {
- char *p,*d,c;
- p=backup2; d=p; *backup2='\0';
- while ( (c=*s++) != 0) {
- if ((c=='\\') || (c==':'))
- d=p+1;
- *p++=c;
- }
- strcpy(d,"__temp__.lzs");
- file2=e_fopen(outfname=backup2,"w+b",MKTMPERR);
- setvbuf(file2,buf2,_IOFBF,BUFFERSIZ);
- }
- /*}}} */
- /*{{{ pack_aafx: subprocess in packing afx*/
- void pack_aafx(void)
- {
- struct filebuf far *f0;
- uchar *p, *q;
- int c, d;
- int cnt = 0;
- if ((f0 = ((struct filebuf far *)fbuf) -> next) != NULL) {
- p = mkhdr(f0, &Hdr2); /* make header from the file list */
- }
- while (f0 != NULL) {
- switch(test_afx(fb0.dir)) {
- case 0: open_afxbackup(fb0.dir);
- freeze(fb0.dir);
- fclose(file3);
- fclose(file2);
- if (flg_unpacked==0) {
- unlink(fb0.dir);
- if (rename(backup2,fb0.dir) != 0)
- error(RENAMEERR, fb0.dir);
- } else
- unlink(backup2);
- break;
- case 1: printf("%s\n already in AFX-format\n",fb0.dir); break;
- case 2: printf("%s\n already in LHarc-format\n",fb0.dir); break;
- case 3: printf("%s\n Program-file\n",fb0.dir); break;
- }
- if (file2 != NULL) fclose(file2);
- if (file3 != NULL) fclose(file3);
- cnt++;
- if ((f0 = fb0.next) != NULL) { /* make header of the next */
- p = mkhdr(f0, &Hdr2); /* file in file list */
- }
- }
- return cnt;
- }
- /*}}} */
- /*{{{ pack_afx: pack-afx*/
- void pack_afx(void)
- {
- int cnt;
- char *p;
-
- mklist(); /* make a file list */
- if (Nfile == 0) {
- error(NOFILEERR, NULL);
- }
- FlgMethod=0;
- pack_aafx();
- #ifndef __TOS__
- freemem(seg);
- #else
- free (fbuf);
- #endif
- }
- /*}}} */
- /*{{{ freshen: f command*/
- /*******************************
- f command
- *******************************/
- void freshen(void)
- {
- uchar path[MAXPATH];
- int c;
- int cnt = 0;
-
- openrwarc1(); /* open an archive */
- message("Freshening archive", arcname);
- openbackup1(); /* rename the archive to temp. */
- openbackup2(); /* open temp. for a new archive */
- while (gethdr(file1, &Hdr1)) {
- c = 0;
- if (matchpat(filename)) {
- stpcpy(stpcpy(path, basedir), filename);
- if ((file3 = fopen(path, "rb")) != NULL) {
- sethdr(filename, getfattr(path), &Hdr2);
- if (flg_c || FTimeToULong (Hdr1.Ftime) <
- FTimeToULong (Hdr2.Ftime)) {
- c = 1; /* found the file to be updated */
- }
- }
- }
- if (c) {
- freeze(path); /* do updating */
- cnt++;
- fseek(file1, Hdr1.PacSiz, SEEK_CUR);
- } else {
- copyold();
- }
- if (file3)
- fclose(file3);
- }
- endofupdate(cnt); /* end-of-job process */
- }
- /*}}} */
- /*{{{ tstdir: test the file which should be melted*/
- /*******************************
- test the file which
- should be melted
- *******************************/
- int tstdir(uchar *name)
- {
- uchar path[MAXPATH], *p, yn;
- struct ffblk ffb;
- Again:
- p = name;
-
- if (*p && p[1] == ':') /* skip a drive name */
- p += 2;
- if (*p == '\\') /* skip a root mark('\') */
- p++;
- yn = flg_m ? 'Y' : 'N';
- while ((p = strchr(p, '\\')) != NULL) { /* skip to next '\' */
- memcpy(path, name, p - name);
- path[p - name] = '\0';
- if (findfirst(path, &ffb, 0x1f)) { /* Is there this directory? */
- if (yn == 'N') {
- printf("'%s' : %s", name, M_MKDIR);
- yn = getyn();
- }
- if (yn == 'N') {
- return FAULT;
- } else {
- if (strcmp(path,".") != 0)
- if (mkdir(path)) { /* make directory */
- error(MKDIRERR, path);
- }
- }
- } else {
- if ((ffb.ff_attrib & 0x10) == 0) {
- error(MKDIRERR, path); /* if the name isn't directory */
- }
- }
- p++;
- }
- if (! findfirst(name, &ffb, 0x1f)) { /* if a file has the same name */
- if (ffb.ff_attrib & 0x01 && ffb.ff_attrib != Hdr1.Attr) {
- /* if the file is read-only, */
- /* attributes must match */
- fprintf(stderr, "'%s' %s\n", M_RDONLY);
- return FAULT;
- }
- yn = 'Y';
- #ifdef __TOS__
- if (flg_c == 0 && UnixFile == 0) {
- #else
- if (flg_c == 0) {
- #endif
- if (((ulong)ffb.ff_fdate << 16) + (ulong)ffb.ff_ftime
- < FTimeToULong (Hdr1.Ftime)) { /* compare time stamps */
- yn = 'Y';
- } else {
- printf("Skipped : '%s' : New or same file exists.\n", name);
- yn = 'N';
- }
- }
- if (yn == 'Y' && flg_m == 0) {
- fprintf(stderr, "'%s' : %s", name, M_OVERWT);
- yn = getynr(); /* may overwrite? */
- if (yn == 'R') {
- printf(M_ENTERNEW);
- scanf("%s",name);
- goto Again;
- }
- }
- if (yn == 'N') {
- return FAULT;
- }
- setfattr(name, 0x20); /* reset attributes */
- }
- return SUCCS;
- }
- /*}}} */
- /*{{{ tstID: read header-ID (method)*/
- /*******************************
- read header-ID (method)
- *******************************/
- int tstID(uchar *h)
- {
- int m;
- static uchar IDpat[6][6] =
- {"-lz4-", "-lz5-", "-lh0-", "-lh1-","-lh5-","-afx-"};
- /* 0 1 2 3 4 5 */
- m = (int)((sizeof IDpat) / (sizeof IDpat [0]));
- while (m >= 0 && memcmp(h, IDpat[m], 5)) {
- m--;
- }
- if (m==5) m=1;
- return m;
- }
- /*}}} */
- /*{{{ Dos1File: Dateiname nach 8+3 Zeichen wandeln*/
- #ifdef __TOS__
-
- char LegalChar(char c)
- {
- if (c <= 32) return 0;
- if (c == '*' || c == '?') return 0;
- return 1;
- }
-
- char *Dos1File(char *s, char *d) /* Ein Dateiname ohne Ordner wird überprüft */
- {
- char c,*t;
- int p;
- int l;
- int i;
- int j;
- int k;
- int m;
-
- /* Suche von hinten den letzten Punkt. i ist die Position des
- letzten Zeichens vor der Extension */
-
- l = strlen(s);
- for (i=l; i>=0;i--) if (s[i] == '.') break;
- m = i-1;
- if (i<=0) m = l;
-
- /* Kopiere maximal 8 Zeichen des Dateinamens. Überspringe Punkte
- und illegale Zeichen */
-
- j = 0; k = 0;
- t=s;
- for (j = 0; j<=7; j++) {
- c = *t++;
- if (i>0) if (k++>i) break;
- if (c=='\0') break;
- if (j > m) break;
- if (c != '.' && c > 32 && c != ':') {
- if (LegalChar(c)) *d++ = c;}
- else j--;
- }
- if (i>0) {
- *d++ = '.';
- i++;
- for (j=0; j<=2; j++) {
- c=s[i++];
- if (c==0) break;
- if (c > 32 && c != ':') if (LegalChar(c)) *d++ = c;
- }
- }
- *d='\0';
- return d;
- }
- /*}}} */
- /*{{{ DosFile: File mit Ordnername nach 8+3 wandeln*/
- /* Auftrennen des Files in einzelne Ordner (falls nötig) und anpassung
- jedes Ordners an 8+3 Zeichen */
- void DosFile(char *s)
- {
- char file[128], *f=file;
- char dest[128], *d=dest;
- char c,*s1=s;
- *d=0;
- while (( c= *s++) != 0) {
- if (c=='/') c = '\\';
- if (c==':' || c == '\\') {
- *d=0;
- f=Dos1File(dest,f);
- *f++=c; *f='\0';
- d=dest;
- } else *d++=c;
- }
- *d=0;
- f=Dos1File(dest,f);
- strcpy(s1,file);
- }
- #endif
- /*}}} */
- /*{{{ extract: a,x,p,t command*/
-
- /*******************************
- e, x, p, t command
- *******************************/
- int extract(void)
- {
- uchar *p, *q;
- int m;
- int cnt = 0;
-
- openarc1(); /* open an archive */
- setvbuf(file1, buf2, _IOFBF, 1024);
- message("Extract from", arcname);
- if (flg_v == 1)
- fprintf(file3, "Extract from '%s'\n", arcname);
- UseExthdr=1;
- while ((p = gethdr(file1, &Hdr1)) != NULL) {
-
- if (matchpat(filename)) {
- arcpos0 = ftell(file1) + Hdr1.PacSiz;
- infile=file1;
- MKinputbuf(Hdr1.PacSiz);
- if (cmd == 'E') { /* if extract command, */
- if (flg_x) { /* get the destination path name */
- p = stpcpy(pathname, basedir);
- if (filename[0] == '\\') {
- p = pathname;
- if (*p && p[1] == ':') {
- p += 2;
- }
- }
- stpcpy(p, filename);
- } else {
- stpcpy(stpcpy(pathname, basedir), p);
- }
- }
- slash2yen(pathname);
- strcpy(dospathname,pathname);
- if (pathname[0] == 0)
- #ifdef __TOS__
- DosFile(dospathname);
- UnixFile = strcmp(dospathname,pathname);
- if (dospathname[strlen(dospathname)-1]=='\\')
- goto weiter;
- #endif
- m=tstID(Hdr1.HeadID);
- if (cmd != 'E' || tstdir(dospathname)) {
- if ((m = tstID(Hdr1.HeadID)) < 0) {
- printf("Skipped : '%s' : Unknown method\n", pathname);
- } else
- {
- cnt++;
- p = "Melting ";
- q = "Melted ";
- switch (cmd) {
- case 'X':
- case 'E':
-
- if (flg_d == 0) printf("%s ", pathname);
- file3 = fopen(outfname = dospathname, "wb");
- break;
- case 'T':
- if (flg_d == 0) printf("%s ", filename);
- #ifndef __TOS__
- file3 = fopen ("nul", "wb");
- #else
- file3 = NULL; /* no NUL-Device supported! */
- #endif
- p = "Testing ";
- q = "Tested ";
- break;
- case 'P':
- if (flg_v != 2)
- fprintf(file3, "<<< %s >>>\n", filename);
- if (flg_v)
- printf("%s ", filename);
- fflush(file3);
-
-
- setmode(fileno(file3), O_BINARY);
- break;
- }
- #ifndef __TOS__
- if ((ioctl(fileno(file3), 0) & 0x82) == 0x82) {
- flg_n = 1; /* Console output ? */
- } else {
- setvbuf(file3, buf3, _IOFBF, BUFFERSIZ);
- }
- #else
- if (file3 != NULL) {
- if (file3 == stdout) {
- flg_n = 1; /* Console output ? */
- } else {
- outfile=file3;
- /* MKoutputbuf(); */
- /* setvbuf(file3, buf3, _IOFBF, BUFFERSIZ); */
-
- }
- } else OutBuf=NULL;
- #endif
- if (m != 4)
- blkdisp(Hdr1.OrgSiz, p);
- else
- blkdisp(Hdr1.OrgSiz/2,p);
-
- outfile = file3;
- infile = file1;
-
-
- textsize = Hdr1.OrgSiz;
- codesize = Hdr1.PacSiz;
- crc = 0;
- if (m == 3) {
- Decode(); /* extract LHarc's file */
- } else if (m == 1) {
- DecodeOld(); /* extract LArc's file */
- } else if (m == 4) {
- decode_lh5(Hdr1.OrgSiz,Hdr1.PacSiz);
- } else {
- crcflg = 1;
- copyfile(infile, outfile, Hdr1.OrgSiz);
- crcflg = 0; /* only stored file */
- }
- fflush(file1);
- fseek(file1,ftell(file1),0);
- setvbuf(file1, buf2, _IOFBF, 1024);
- Mfree(TheInputBuf);
- if (file3 != NULL) {
- Mfree(TheOutputBuf);
- }
- if (file3 != NULL && fflush(file3)) {
- error(WTERR, outfname);
- }
- if (pathname[0] != 0)
- if (cmd == 'E') {
- setftime(fileno(file3), &Hdr1.Ftime);
- fclose(file3);
- setfattr(pathname, Hdr1.Attr);
- file3 = NULL;
- } else if (cmd == 'T') {
- #ifndef __TOS__
- fclose(file3);
- #endif
- } else {
- setmode(fileno(file3), O_TEXT);
- if (flg_v != 2)
- fprintf(file3, "\n");
- }
- curback();
- if (getcrc (&Hdr1) != crc) {
- errorlevel = 1; /* test CRC */
- printf("CRC err\n");
- if (flg_m == 0) getchar();
- } else if (cmd != 'P' || flg_v != 0) {
- if (flg_d == 0) printf("%s\n", q);
- }
- }
- }
- weiter:
- fseek(file1, arcpos0, SEEK_SET); /* move pointer to next file */
- } else {
- fseek(file1, Hdr1.PacSiz, SEEK_CUR);
- }
- }
- fclose(file1);
- file1 = NULL;
- return cnt;
- }
- /*}}} */
- /*{{{ delete: d command*/
-
- /*******************************
- d command
- *******************************/
- void delete(void)
- {
- int cnt = 0;
-
- openrwarc1(); /* open archive */
- if (patno == 0) {
- error(NOFNERR, NULL);
- }
- message("Updating archive", arcname);
- openbackup1(); /* rename to temporary name */
- openbackup2(); /* open another temporary file */
- while (gethdr(file1, &Hdr1)) {
- if (matchpat(filename)) {
- message("Deleting", filename);
- cnt++;
- fseek(file1, Hdr1.PacSiz, SEEK_CUR); /* skip file */
- } else {
- copyold();
- }
- }
- endofupdate(cnt); /* end-of-job process */
- }
- /*}}} */
- /*{{{ self: s command*/
-
- /*******************************
- s command
- *******************************/
- void self(void)
- {
- #ifndef __TOS__
- uchar *p, /* *q,*/ buf[12], yn;
- int flg, i;
- long l, m, n;
- void sfx(void), sfx2(void);
-
- openarc1(); /* open archive */
- message("Making Sfx from archive", arcname);
- stpcpy(stpcpy(backup2, workdir), "lharc.)2(");
- file2 = e_fopen(outfname = backup2, "w+b", MKTMPERR);
- /* open temporary */
- while (gethdr(file1, &Hdr1)) {
- flg = 0;
- if (matchpat(filename)) {
- if (flg_d == 0) printf("Extracting '%s' ", filename);
- if (tstID(Hdr1.HeadID) < 2) {
- printf("(not supported) skipped.");
- } else {
- if (flg_x == 0 && (p = strrchr(filename, '\\')) != NULL) {
- p++; /* delete directory part */
- Hdr1.Fname[0] = strlen(p);
- i = p - filename;
- Hdr1.HeadSiz -= i;
- memcpy(Hdr1.Fname + 1, Hdr1.Fname + 1 + i,
- Hdr1.Fname[0] + 2);
- Hdr1.HeadChk = mksum(&Hdr1); /* recalculate sum */
- }
- wthdr(&Hdr1);
- copyfile(file1, file2, Hdr1.PacSiz);
- flg = 1;
- }
- printf("\n");
- }
- if (flg == 0) {
- fseek(file1, Hdr1.PacSiz, SEEK_CUR);
- }
- }
- fclose(file1);
- if (putc(0, file2) == EOF) /* end-mark of archive */
- error(WTERR, backup2);
- if ((l = ftell(file2)) <= 1) {
- goto self9;
- }
- if (flg_x == 0) {
- m = (uchar*)sfx2 - (uchar*)sfx; /* size of sfx routine */
- } else {
- m = (uchar*)usage - (uchar*)sfx2;
- }
- n = l + m; /* total size of sfx file */
- rewind(file2);
- infname = backup2;
- extfn(arcname, buf); /* make the name of sfx */
- p = stpcpy(pathname, basedir);
- strcpy(&buf[8], "COM");
- if (flg_x || n > 0xfe80ul) {
- strcpy(&buf[8], "EXE");
- }
- packfn(p, buf);
- if ((getfattr(pathname) & 0x8000) == 0) { /* if the same name exists */
- fprintf(stderr, "'%s' : %s", pathname, M_OVERWT);
- yn = getyn(); /* may overwrite */
- if (yn == 'N') {
- goto self9;
- }
- }
- file3 = e_fopen(outfname = pathname, "wb", MKFILEERR);
- if (buf[8] == 'E') { /* if .EXE */
- if (flg_x) {
- n = m;
- }
- n += 0x20;
- ExeHdr.page = (n + 511) / 512;
- ExeHdr.byte = n % 512;
- ExeHdr.minalloc = (flg_x ? 0x66c0 : 0x2560) / 0x10;
- if (fwrite(&ExeHdr, 0x20, 1, file3) == 0)
- error(WTERR, pathname);
- }
- movedata(_CS, (flg_x ? (unsigned)sfx2 : (unsigned)sfx),
- _DS, (unsigned)buf2, m);
- if (flg_x) {
- memcpy(buf2 + 0x34, p, strlen(p)); /* large ver. */
- } else {
- *((uint *)buf2 + 1) = (l + m + 0x10f) / 0x10; /* small ver. */
- }
- if (fwrite(buf2, m, 1, file3) == 0) /* write sfx routine */
- error(WTERR, pathname);
- if (flg_x) {
- if (fwrite(keyword, strlen(keyword) + 1, 1, file3) == 0)
- error(WTERR, pathname);
- }
- copyfile(file2, file3, l); /* write an archive */
- printf("\nCreated : '%s'\n", pathname);
- fclose(file3);
- self9:
- fclose(file2);
- unlink(backup2);
- #else
- fprintf (stderr, "Self-Extracting-Files: NOT YET IMPLEMENTED!!!\7\n");
- errorlevel = 1;
- longjmp (exit_jmp, 1); /* NOT YET IMPLEMENTED !!! */
- #endif
- }
- /*}}} */
- /*{{{ sysid*/
-
- char *sysid( void )
- {
- char *s;
- if (flg_k == 0) {
- switch(SystemId) {
- case 'M' : s="MSDOS "; break;
- case '2' : s="OS/2 "; break;
- case '9' : s="OS9 "; break;
- case 'K' : s="OS/68K"; break;
- case '3' : s="OS/386"; break;
- case 'H' : s="HUMAN "; break;
- case 'U' : s="UNIX "; break;
- case 'C' : s="CP/M "; break;
- case 'm' : s="Mac "; break;
- case 'R' : s="Runser"; break;
- case 'A' : s="Atari "; break;
- default : s=" "; break;
- }
- } else s=" ";
- return s;
- }
-
- /*}}} */
- /*{{{ list: l,v command*/
-
-
- /*******************************
- l, v command
- *******************************/
- void list(void)
- {
- uint rt;
- uchar buf[79], *p,*b;
- static uchar attr[7] = "ohs--a";
- int i, j, k, Fno;
- ulong Osize, Psize;
-
- Osize = Psize = 0L;
- Fno = 0;
- openarc1(); /* open archive */
- UseExthdr=1;
- #ifdef German
- printf("Inhalt von : '%s'\n\n", arcname);
- printf(" Name Original Gepackt Rate"
- " Datum Zeit Attr Typ CRC\n");
- #else
- printf("Listing of archive : '%s'\n\n", arcname);
- printf(" Name Original Packed Ratio"
- " Date Time Attr Type CRC\n");
- #endif
- printf("-------------- -------- -------- ------"
- " -------- -------- ---- ----- ----\n");
- while ((p = gethdr(file1, &Hdr1)) != NULL) {
- if (matchpat(filename)) {
- rt = ratio(Hdr1.PacSiz, Hdr1.OrgSiz);
- sprintf(buf, " %10lu%10lu %3d.%1d%% "
- "%2d-%02d-%02d %2d:%02d:%02d ---w %04X\n",
- Hdr1.OrgSiz, Hdr1.PacSiz, rt / 10, rt % 10,
- (Hdr1.Ftime.ft_year + 80) % 100, Hdr1.Ftime.ft_month,
- Hdr1.Ftime.ft_day, Hdr1.Ftime.ft_hour,
- Hdr1.Ftime.ft_min, Hdr1.Ftime.ft_tsec * 2,
- getcrc (&Hdr1));
- memcpy(&buf[65], Hdr1.HeadID, 5);
- for (i = 0, j = 1; i < 6; i++, j <<= 1) { /* attributes */
- if (Hdr1.Attr & j) {
- k = attr[i];
- if (i <= 2) {
- buf[63 - i] = k;
- } else {
- buf[60] = k;
- }
- }
- }
- if (flg_x) {
- printf("%s\n", filename); /* display in 2 lines */
- p=sysid(); b = buf;
- while (*p != 0) *b++=*p++;
-
- if (comment[0] != 0) printf("%s\n",comment);
- } else {
- if (p != filename) { /* display in one line */
- *buf = '+';
- }
- memcpy(&buf[2], p, strlen(p));
- }
- printf("%s", buf);
- Fno ++;
- Osize += Hdr1.OrgSiz;
- Psize += Hdr1.PacSiz;
- }
- if (fseek(file1, Hdr1.PacSiz, 1))
- break;
- }
- if (Fno) {
- printf("-------------- -------- -------- ------"
- " -------- --------\n");
- rt = ratio(Psize, Osize);
- getftime(fileno(file1), &arcstamp);
- printf(" %3d files %10lu%10lu %3d.%1d%% "
- "%2d-%02d-%02d %2d:%02d:%02d\n",
- Fno, Osize, Psize, rt / 10, rt % 10,
- (arcstamp.ft_year + 80) % 100, arcstamp.ft_month,
- arcstamp.ft_day, arcstamp.ft_hour,
- arcstamp.ft_min, arcstamp.ft_tsec * 2);
- } else {
- printf(" no file\n");
- }
- fclose(file1);
- }
- /*}}} */
- /*{{{ getsw: get switches*/
-
- /*******************************
- get switches
- *******************************/
- void getsw(uchar *p)
- {
- #ifndef __TOS__
- static uchar flg[] = "rpxmacntvwyb";
- static uchar *flgpos[] = {&flg_r, &flg_p, &flg_x, &flg_m,
- &flg_a, &flg_c, &flg_n, &flg_t,
- &flg_v, &flg_w};
- #else
- static uchar flg[] = "rpxmacntvwhybludoske5";
- static uchar *flgpos[] = {&flg_r, &flg_p, &flg_x, &flg_m,
- &flg_a, &flg_c, &flg_n, &flg_t,
- &flg_v, &flg_w, &flg_h};
- #endif
- int i;
- uchar s;
- uchar *q;
-
- while ((s = *p++) != 0) {
- q = strchr(flg, s); /* search switch */
- if (q) {
- i = (int)(q - flg);
- if (*p == '+') {
- *flgpos[i] = 1;
- p++;
- } else if (*p == '-') {
- *flgpos[i] = 0;
- p++;
- } else if (*p == '2') {
- *flgpos[i] = 2;
- p++;
- } else if (s == 'v' && *p) {
- if (flg_v == 0) /* process of '/vSTRING' */
- flg_v = 1;
- pager = p;
- p = "";
- } else if (s == 'y') flg_arc = 1;
- else if (s == 'k') { flg_k=1; elen=0; }
- else if (s == 'b') {
- flg_arc=1;
- flg_backup=1;
- } else if (s == '5') flg_5=1;
- else if (s == 'l') FlgMethod=0;
- else if (s == 'o') FlgMethod=1;
- else if (s == 's') flg_s=1;
- else if (s == 'u') flg_u = 1;
- else if (s == 'e') flg_e = 1;
- else if (s == 'w' && *p) {
- flg_w = 1; /* process of '/wSTRING' */
- wdir = p;
- p = "";
- } else if (s == 'd') flg_n = flg_d = 1;
- else {
- if (*flgpos[i]) { /* flip-flop */
- *flgpos[i] = 0;
- } else {
- *flgpos[i] = 1;
- }
- }
- if (s == 'r' && flg_r > 0) {
- flg_x = 1;
- }
- #ifndef __TOS__
- } else if (s == 'k') {
- keyword = p;
- p = "";
- #endif
- }
- else {
- if (s == '?') usage();
- error(INVSWERR, NULL);
- }
- }
- }
- /*}}} */
- /*{{{ executecmd: execute command*/
-
- /*******************************
- execute command
- *******************************/
- void executecmd(void)
- {
- int cnt;
-
- switch (cmd) {
- case 'A':
- flg_c++;
- case 'U':
- case 'M':
- append();
- break;
- case 'C':
- pack_afx();
- break;
- case 'F':
- freshen();
- break;
- case 'P':
- if (flg_v == 0) {
- file3 = stdout;
- goto common;
- }
- stpcpy(stpcpy(pathname, workdir), "LHARC.TMP"); /* view files */
- file3 = e_fopen(outfname = pathname, "w", MKTMPERR);
- cnt = extract();
- fclose(file3);
- if (cnt) /* if any files extracted */
- #ifndef __TOS__
- stpcpy(stpcpy(stpcpy(buf2, pager), " "), pathname);
- execute(buf2); /* execute by INT 0x2e */
- #else
- {
- int retcode;
-
- exec (pager, pathname, "", &retcode);
- }
- #endif
- #if 0
- spawnlp(P_WAIT, pager, pager, pathname, NULL);
- #endif
- unlink(pathname);
- break;
- case 'T':
- tstflg = 1;
- goto common;
- case 'X':
- case 'E':
- cmd = 'E';
- common:
- flg_v = 0;
- extract();
- break;
- case 'V':
- flg_x++;
- case 'L':
- list();
- break;
- case 'D':
- delete();
- break;
- case 'S':
- self();
- break;
- }
- if (!flg_d) putchar('\n');
- }
- /*}}} */
- /*{{{ recoverbrk: handle userbreak*/
-
- /*******************************
- handle userbreak
- *******************************/
- #ifndef __TOS__
- int cbrk;
-
- void recovercbrk(void) {
- setcbrk(cbrk);
- }
- #endif
- /*}}} */
- /*{{{ OneNewFile:*/
- void OneNewFile(char *p)
- {
- char *s;
- s = strchr(p,'\n');
- if (s != NULL) *s='\0';
- if (patno == 0 && basedir == NULL &&
- (strrchr(p, '\\') == p + strlen(p) - 1 ||
- p[strlen(p) - 1] == ':')) {
- basedir = p; /* get base (or home) directory */
- } else if (patno >= MAX_PAT) {
- message("File table overflow. ignore", p);
- } else {
- patpath[patno] = p;
- extfn(p, patfile[patno]);
- patno++; /* regist path names */
- }
- }
- /*}}} */
- /*{{{ newfile*/
- void newfile(char *p)
- {
- char file[128]; /* Dateiname bei &datei */
- FILE *f;
- if (*p == '&')
- {
- if (strcmp("-",&p[1]) == 0)
- f=stdin; else f=fopen(&p[1],"r");
- if (f != NULL)
- {
- while ( fgets(file,127,f) != NULL)
- OneNewFile(strdup(file)); /* regist copy of filecontents */
- fclose(f);
- }
- } else OneNewFile(p);
- }
- /*}}} */
- /*{{{ argv_main: main routine*/
- /*******************************
- main routine
- *******************************/
- #ifndef __GEM__
- #ifdef __TOS__
- int argvmain(int argc, uchar **argv,uchar **envp)
- #else
- int main(int argc, uchar *argv[])
- #endif
- {
- uchar *p, *q, *env, *env9;
- uchar ptitel=0;
- int yn;
- extern char title[];
- struct ffblk ffb;
- FILE *fp;
- char buffer[256];
-
-
-
- if (!setjmp (exit_jmp)) {
- #ifndef __TOS__
- ctrlbrk(userbreak); /* set vector for '^C' */
- cbrk = getcbrk();
- setcbrk(1);
- atexit(recovercbrk);
- #endif
-
- remove("LHARC.)1(");
- remove("LHARC.)2(");
-
- mkcrc(); /* make CRC table */
- swchar = getswchar(); /* get the setting of switch char */
- argc--;
- argv++;
- if (argc-- == 0)
- {
- flg_h = 1;
- usage(); /* if no parameter given */
- }
- p = (argv++)[0];
- cmd = toupper(*p);
- if (strlen(p) - 1 || strchr("EXTDLVAUMFPSC", cmd) == 0) {
- cmd = 'X'; /* if no command, assume 'X' command */
- argc++;
- argv--;
- flg_x = 1; /* @@25.5.91 Ohne Kommando x -rm */
- flg_m = 1;
- }
- cmdupdate = (int)strchr("AUMFD", cmd);
- /* command updating archive? */
- if ((env = getenv("TMP")) != NULL) { /* get 'TMP' from environment */
- wdir = env;
- flg_w = 1;
- }
- if ((env = getenv("LHARC")) != NULL) {
- /* get 'LHARC' from environment */
- for (p = env; *p != '\0'; p++) {
- if (*p == ' ' || *p == '\x08')
- *p = '\0';
- }
- env9 = p;
- p = env;
- while (p < env9) {
- while (*p == '\0') p++;
- if (*p == swchar || *p == '-') p++;
- getsw(p);
- while (*p) p++;
- }
- }
- patno = -1;
- if (cmd == 'C') patno=0;
- basedir = NULL;
- while (argc--) {
- p = (argv++)[0];
- if (*p == swchar || *p == '-') {
- getsw(++p);
- } else {
- if (ptitel == 0 && flg_d == 0) {
- puts(title); /* output title */
- if ((fp = fopen("lharc.ttp","rb")) != NULL ||
- (fp = fopen("lzh.ttp","rb")) != NULL ||
- (fp = fopen("lharcd.ttp","rb")) != NULL) {
- fread(buffer,1,256,fp);
- if (strncmp(buffer+30,"LArc's PFX",10) == 0)
- printf(morefiles);
- fclose(fp);
- }
- putchar('\n');
- ptitel=1;
- }
- strupr(p);
- slash2yen(p); /* convert '/' to '\' */
- /* in japanese version */
- if (patno < 0) { /* get archive name */
- strcpy(arcname, p);
- if ((p = strrchr(arcname, '\\')) == NULL) {
- p = arcname; /* pointer of the part of file name */
- }
- if ((q = strchr(p, '.')) == NULL) {
- strcat(arcname, ".LZH"); /* if no extension */
- } else if (strcmp(".LZH", q) && flg_m == 0 && cmdupdate) {
- fprintf(stderr, M_NOTLZH, arcname);
- yn = getyn(); /* if the extension is not '.LZH' */
- if (yn == 'N') {
- errorlevel = 1;
- longjmp (exit_jmp, 1);
- }
- }
- patno++;
- } else {
- newfile(p); /* Register file or files */
- }
- }
- }
- if (patno < 0) {
- error(NOARCNMERR, NULL);
- }
- if (patno == 0 && cmd != 'D') { /* if no name given */
- extfn(patpath[0] = patnul, patfile[0]); /* '*.*' is assumed */
- patno++;
- }
- p = stpcpy(workdir, wdir) - 1;
- if (*workdir != '\0' && strrchr(workdir, '\\') != p && *p != ':') {
- strcat(workdir, "\\"); /* concatenate '\' after the work dir. */
- }
- if (cmdupdate) {
- if (strchr(arcname, '*') || strchr(arcname, '?')) {
- error(NOARCERR, arcname);
- } /* when updating archive, wild cards can't used */
- executecmd();
- }
- else {
- if (cmd == 'C') executecmd();
- else {
- if (findfirst(arcname, &ffb, 0x07)) {
- error(NOARCERR, arcname);
- }
- do {
- strcpy(backpath(arcname), ffb.ff_name);
- executecmd();
- } while (!findnext(&ffb));
- if (cmd != 'L' && cmd != 'V')
- tstpat(); /* whether all given names were used? */
- }
- }
- }
-
- #ifdef __TOS__
- if (flg_h)
- {
- fflush (stdin); /* wait for keystroke when used */
- printf (M_PRESSKEY); /* with GEM-Desktop */
- getch ();
- putchar ('\n');
- }
- #endif
- return errorlevel;
- }
- /*}}} */
- /*{{{ main: argv calculations*/
- int main (int argc, char *argv[], char *envp[])
- {
- char **myargv;
- extern BASPAG *_BasPag;
- char *env;
- char *startpar;
- char *oldline;
-
-
- int count = 0;
- int i;
-
- Fsetdta (&_mydta);
-
- /* Anfang der alten Kommandozeile */
- oldline = &_BasPag->p_cmdlin[1];
-
- /* Flag fuer Verwendung von ARGV */
- if (_BasPag->p_cmdlin[0] != 127)
- return argvmain (argc, argv, envp);
-
- /* Zeiger auf Env-Var merken */
- env = getenv("ARGV");
- if (!env)
- return argvmain (argc, argv, envp);
-
- /* alle weiteren envp's loeschen */
- i = 0;
- while (strncmp (envp[i], "ARGV", 4)) i++;
- envp[i] = NULL;
-
- /* alles, was dahinter kommt, abschneiden */
- if (env[0] && env[-1])
- {
- *env++ = 0; /* kill it */
- while (*env++);
- }
-
- /* Parameterstart */
- startpar = env;
-
- while (*env)
- {
- count++;
- while (*env++);
- }
-
- /* Speicher fuer neuen Argument-Vektor */
- myargv = Malloc ((count+1)*sizeof (char *));
- env = startpar;
-
- count = 0;
- while (*env)
- {
- myargv[count++] = env;
- while (*env++);
- }
- myargv[count] = NULL;
-
- /* moeglichst viele Parameter in alte Kommandozeile */
- {
- int i;
-
- *oldline = 0;
- i = 1;
-
- while ((i < count) && (strlen (oldline) + strlen (myargv[i]) < 120))
- {
- if (i > 1) strcat (oldline, " ");
- strcat (oldline, myargv[i]);
- i++;
- }
-
- if (i < count) strcat (oldline, " ...");
- }
-
-
- /* und ...argvmain() starten */
- count = argvmain (count, myargv, envp);
- Mfree (myargv);
- return count;
- }
- #endif
- /*}}} */
-