home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 51
/
Amiga_Dream_51.iso
/
Atari
/
Desktops
/
nodsk302.lzh
/
SRC
/
ARCDRV
/
W_LHARC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-22
|
9KB
|
385 lines
/*==================================================================*/
/* */
/* noDesk */
/* */
/* Version 3.0 */
/* */
/* written 1989-1994 by */
/* Andreas Fahrig Ralph Mertens Christian Stamm */
/* */
/* (c)1989-93 by DesaSoft GbR, all Rights reserved */
/* (c)1994- by no|Soft GmbH, all Rights reserved */
/* */
/*==================================================================*/
/* */
/* Archiv-Treiber für LHARC-Dateien */
/* */
/*==================================================================*/
#include <types.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <ext.h>
#include <tos.h>
#include "warc.h"
/*-------------------------------------------------------------------
Konstanten und Makros
--------------------------------------------------------------------*/
/*
#define DR_DEBUG
*/
#ifdef DR_DEBUG
# define DebugAlert(SS) {printf("\033H\n\n%s\n", SS); Cnecin(); }
#else
# define DebugAlert(SS)
#endif
/*-------------------------------------------------------------------
Typen und Strukturen
--------------------------------------------------------------------*/
union stamp { /* time stamp */
struct ftime s;
unsigned long u;
};
struct Lzh_Head { /* file header */
unsigned char head_chk;
unsigned char head_id[5];
unsigned long pac_siz;
unsigned long org_siz;
union stamp file_time;
unsigned word file_attr;
unsigned char file_name[MAXPATHLEN];
} Hdr1;
/*-------------------------------------------------------------------
Variablen
--------------------------------------------------------------------*/
char arcProg[MAXPATHLEN],
tmpFile[MAXPATHLEN];
Warc_File *fileBuf;
int maxFiles,
fileAnz;
char *envBuff;
uchar HeadSiz;
uchar buf2[2048];
char filename[MAXPATHLEN];
/*-------------------------------------------------------------------
Funktionen
--------------------------------------------------------------------*/
/*
* calculate check-sum of header
*/
uchar _CalcCRC(struct Lzh_Head *h, uchar headsize) {
uchar *p, *q;
uchar i;
p = (uchar *)h + 1;
q = p + headsize;
for (i = 0; p < q; p++)
i += *p;
return i;
} /* _CalcCRC */
/*
* open an old archive
*/
FILE *_OpenArc1(char *fname) {
uchar *p, *q;
FILE *fP;
if ((fP = fopen(fname, "rb")) == NULL)
return NULL;
q = buf2 - 5 + fread(buf2, 1, 2048, fP);
for (p = buf2; p < q; p++) {
if (p[0] == '-' && p[1] == 'l' && p[4] == '-') break;
}
if (p >= q) {
fclose(fP);
return NULL;
}
fseek(fP, (long)(p - buf2 - 2), SEEK_SET);
return(fP);
} /* _OpenArc1 */
void _Swap(void *vP, int size) {
int i;
char buf[4];
for(i = 0; i < size; i++) buf[size - i - 1] = *((char *)vP + i);
if (size == 4) *(ulong *)vP = *(ulong *)buf;
if (size == 2) *(uword *)vP = *(uword *)buf;
} /* _Swap */
/*
* get a file header
*/
uchar *_GetHdr(FILE *fP, struct Lzh_Head *h) {
uchar *q, i;
if (((HeadSiz = getc(fP)) <= 0) ||
(HeadSiz > sizeof(struct Lzh_Head) - 3) ||
(fread(h, HeadSiz + 1, 1, fP) == 0))
{ /* read file header */
return NULL;
}
if (_CalcCRC(h, HeadSiz) != h->head_chk) /* if sum is wrong */
return NULL;
_Swap(&h->org_siz, 4);
_Swap(&h->pac_siz, 4);
_Swap((int *)&h->file_time.u, 2);
_Swap((int *)&h->file_time.u + 1, 2);
_Swap(&h->file_attr, 2);
i = h->file_name[0];
strncpy(filename, (char *)&h->file_name[1], i);
*(filename + i) = '\0';
if ((q = (uchar *)strrchr(filename, '\\')) == NULL &&
(q = (uchar *)strchr(filename, ':')) == NULL)
q = (uchar *)filename;
else
q++;
return q; /* return the portion of file name */
} /* _GetHdr */
/*
* _Ratio * 1000
*/
static uword _Ratio(ulong a, ulong b) {
int i;
if (!b) return 0; /* if diviser == 0 */
for (i = 0; i < 3 && a < 0x19999999UL; 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 ((uword)(a / b)); /* return (a * 1000 / b) */
} /* _Ratio */
static void _FillLE(Warc_File *wfP) {
wfP->orig_len = Hdr1.org_siz;
wfP->packed_len = Hdr1.pac_siz;
/* AFA 7.12.94: ----------------------
wfP->t_d.td.jar = (Hdr1.file_time.s.ft_year + 80) % 100;
------------------------------------*/
wfP->t_d.td.jar = Hdr1.file_time.s.ft_year;
wfP->t_d.td.mon = Hdr1.file_time.s.ft_month;
wfP->t_d.td.tag = Hdr1.file_time.s.ft_day;
wfP->t_d.td.std = Hdr1.file_time.s.ft_hour;
wfP->t_d.td.min = Hdr1.file_time.s.ft_min;
wfP->t_d.td.sek = Hdr1.file_time.s.ft_tsec * 2;
wfP->attrib = Hdr1.file_attr;
} /* _FillLE */
static Warc_File *_AddLEDir(uchar level, int ref_no, char *dirname) {
static Warc_File *_AddLE(uchar, int, char *, Warc_File *);
Warc_File wf;
wf.orig_len = 0L;
wf.packed_len = 0L;
wf.t_d.td.jar = 0;
wf.t_d.td.mon = 1;
wf.t_d.td.tag = 1;
wf.t_d.td.std = 0;
wf.t_d.td.min = 0;
wf.t_d.td.sek = 0;
wf.attrib = FA_SUBDIR;
return(_AddLE(level, ref_no, dirname, &wf));
} /* _AddLEDir */
static Warc_File *_AddLE(uchar level, int ref_no, char *fname, Warc_File *newwfP) {
char *cP;
Warc_File *wfP;
int i;
if (fileAnz >= maxFiles) {
DebugAlert("too much");
return(NULL);
}
cP = strchr(fname, '\\');
if (cP) {
*cP = '\0';
for (i=0, wfP = fileBuf; i<fileAnz; i++, wfP++) {
if (!(wfP->attrib & FA_SUBDIR)) continue;
if (wfP->level!=level || wfP->ref_no!=ref_no) continue;
if (!strcmp(wfP->fname, fname)) break;
}
if (i >= fileAnz) wfP = _AddLEDir(level, ref_no, fname);
*cP = '\\';
if (!wfP) return(NULL);
fname = cP+1;
return (_AddLE(level+1, wfP->physcnt, fname, newwfP));
}
if (newwfP->attrib & FA_SUBDIR) {
for (i=0, wfP = fileBuf; i<fileAnz; i++, wfP++) {
if (!(wfP->attrib & FA_SUBDIR)) continue;
if (wfP->level!=level || wfP->ref_no!=ref_no) continue;
if (!strcmp(wfP->fname, fname)) return(wfP);
}
}
wfP = &fileBuf[fileAnz++];
wfP->physcnt = fileAnz;
wfP->ref_no = ref_no;
wfP->level = level;
wfP->attrib = newwfP->attrib;
wfP->t_d.ul = newwfP->t_d.ul;
wfP->orig_len = newwfP->orig_len;
wfP->packed_len = newwfP->packed_len;
strncpy(wfP->fname, fname, 13);
wfP->fname[13] = '\0';
while (level > 0) {
if (fileBuf[ref_no].t_d.ul >= wfP->t_d.ul) break;
fileBuf[ref_no].t_d.ul = wfP->t_d.ul;
wfP = &fileBuf[ref_no];
level--;
}
return(wfP);
} /* _AddLE */
int DoConvertArc(Warc_Info *aiP) {
FILE *fP;
Warc_File wf;
char *cP;
int err = DE_DRERROR;
if ((fP = _OpenArc1(aiP->arc_name)) == NULL) { /* open archive */
err = DE_BADFILE;
goto arc_read_err;
}
maxFiles = aiP->buf_size;
fileBuf = aiP->buf;
fileAnz = 0;
while (_GetHdr(fP, &Hdr1) != NULL) {
filename[MAXPATHLEN-1] = '\0';
if (!filename[0]) continue;
for (cP = filename; *cP; cP++);
cP--;
if (*cP == '\\') *cP = '\0';
if (!filename[0]) continue;
if (filename[1] == ':') {
sprintf((char *)aiP->buf,
"Das Archiv enthält absolute\n"
"Pfade incl. Laufwerksangaben!");
err = DE_TXTERROR;
goto arc_read_err;
}
_FillLE(&wf);
if (!_AddLE(0, 0, filename, &wf)) {
err = DE_DRERROR;
goto arc_read_err;
}
if (fseek(fP, Hdr1.pac_siz, 1) || feof(fP))
break;
}
fclose(fP);
aiP->buf_size = fileAnz;
return(DE_OK);
arc_read_err:
if (fP) fclose(fP);
if (err == DE_DRERROR) {
if (fileAnz >= maxFiles) err = DE_TOOMUCH;
else {
sprintf((char *)aiP->buf,
"Fehler beim Lesen von\n%s",aiP->arc_name);
err = DE_TXTERROR;
}
}
fileAnz = 0;
return (err);
} /* DoConvertArc */
int ReadArchive(Warc_Info *aiP) {
if (Fattrib(aiP->arc_name, 0, 0) < 0) {
DebugAlert("Archiv");
strcpy((char *)aiP->buf, "Das Archiv ist vom\n"
"Treiber nicht zu finden!");
return(DE_TXTERROR);
}
return (DoConvertArc(aiP));
} /* ReadArchive */
static Warc_Info *_ScanArg(char *arg) {
int i = 0;
long l = 0L;
Warc_Info *aiP;
while ((i < 8) && isxdigit(*arg)) {
if ((*arg >= '0')&&(*arg <= '9')) l = (l << 4) + (*arg - '0');
else if ((*arg >= 'A')&&(*arg <= 'F')) l = (l << 4) + (*arg - 'A'+10);
else l = (l << 4) + (*arg - 'a'+10);
arg++;
i++;
}
if ((i != 8) || (*arg != 0)) return(NULL);
aiP = (Warc_Info *)l;
if (strncmp(aiP->magic, WARC_MAGIC, 8)) return(NULL);
return(aiP);
} /* _ScanArg */
int main(int ac, char **av, char **env) {
Warc_Info *aiP;
int ret;
envBuff = *env;
if (ac != 2) return(DE_DRERROR);
if ((aiP = _ScanArg(av[1])) == NULL) {
DebugAlert("Arguments");
return(DE_DRERROR);
}
ret = ReadArchive(aiP);
if (ret == DE_TOOMUCH) {
sprintf((char *)aiP->buf,
"Das Archiv enthält mehr\nals %d Dateien.\n"
"Bitte die Optionen für\nLS-Fenster ändern!", aiP->buf_size);
ret = DE_TXTERROR;
}
return (ret);
} /* main */