home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1997 November
/
PCWorld_1997-11_cd.bin
/
software
/
sharware
/
utility
/
PACKERS
/
LZH
/
LHASRC.EXE
/
EXTRACT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-03
|
6KB
|
268 lines
/***********************************************************
extract.c -- extract file from archive
***********************************************************/
#include <stdio.h>
#include <string.h>
#include <farstr.h>
#include <stdlib.h>
#include <io.h>
#include <dos.h>
#include <direct.h>
#include "lh.h"
#include "intrface.h"
#include "errmes.h"
#include "disp.h"
static char methods[10][5] = {
"-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-",
"-lh5-", "-lzs-", "-lz5-", "-lz4-", "\0\0\0\0\0"
};
/*******************************
test the file name which
should be melted
*******************************/
static char tstdir(char *name)
{
char *p, *q, yn;
int absent;
struct find_t srchbuf;
p = name;
if (*p && p[1] == ':') /* skip a drive name */
p += 2;
if (*p == DELIM) /* skip a root mark('\') */
p++;
yn = flg_m ? 'Y' : 'N';
q = p;
while ((p = strchr(p, DELIM)) != NULL) { /* skip to next '\' */
if (*q != '.') {
*p = '\0';
absent = _dos_findfirst(name, 0x17, &srchbuf);
if (absent) {
if (yn == 'N') {
*p = DELIM;
eprintf("'%s' : %s", name, MKDIR);
*p = '\0';
yn = getyn();
}
if (yn == 'N') {
return 'S';
} else {
if (makedir(name)) { /* make directory */
error(MKDIRERR, name);
}
}
} else {
if ((srchbuf.attrib & 0x10) == 0) {
error(MKDIRERR, name); /* if the name isn't directory */
}
}
*p = DELIM;
}
q = ++p;
}
if (! _dos_findfirst(name, 0x17, &srchbuf)) {
/* already exists */
if (flg_c == 0 &&
dos2unix((struct ftime *)&srchbuf.wr_time) >= hpb.utc) yn = 'S';
switch (flg_m) {
case 0:
if (yn != 'S') {
eprintf("'%s' %s", name, OVERWT);
yn = (getyn() == 'Y') ? 'O' : 'S';
break;
}
case 1:
if (yn == 'S') {
skipdisp(NEWFILE);
break;
}
yn = 'O';
break;
case 2:
yn = 'R';
break;
}
if (yn != 'O') {
return yn;
}
if (srchbuf.attrib & 0x01 &&
srchbuf.attrib != hpb.attr && !flg_a) {
/* if the file is read-only, */
/* attributes must match */
skipdisp(RDONLY);
return 'S';
}
if (srchbuf.attrib & 0x10) {
skipdisp(SAMEDIR);
return 'S';
}
if (srchbuf.attrib & 0x07)
_dos_setfileattr(name, 0x20); /* reset attributes */
}
return 'O';
}
static int rename_ext(char *name)
{
int i;
char *p, *q;
struct find_t srchbuf;
p = strrchr(name, '.');
q = strrchr(name, DELIM);
if (p <= q) p = name + strlen(name);
for (i = 0; i <= 999; i++) {
sprintf(p, ".%03d", i);
if (_dos_findfirst(name, 0x17, &srchbuf)) return 1;
}
return 0;
}
void extract(char far *bdir)
{
char *path;
int method;
memcpy(methods[9], hpb.method, 5);
for (method = 0; memcmp(hpb.method, methods[method], 5); method++);
if (method == 9) {
skipdisp(METHODERR);
return;
}
switch (cmd) {
case 'E':
if ((hpb.attr & 0x06) && flg_a == 0) {
skipdisp(SPECIALATTR);
return;
}
form_path(hpb.pathname);
hpb.filename = getfilename(hpb.pathname);
path = (flg_x) ? hpb.pathname : hpb.filename;
far_strcpy(filename3, bdir);
if (path[1] == ':') path += 2;
if (*(unsigned char *)path == DELIM) {
if (filename3[1] == ':') {
filename3[2] = '\0';
} else {
*filename3 = '\0';
}
}
strcat(filename3, path);
switch (tstdir(filename3)) {
case 'R':
if (rename_ext(filename3)) break;
skipdisp(NOMOREEXT);
case 'S':
return;
}
if (diskspace(filename3) < hpb.original) {
skipdisp(DISKFULL);
return;
}
file3 = mywopen(filename3, MKFILEERR);
regdisp("Melting ", filename3);
break;
case 'P':
file3 = fdopen(dup(1), "wb");
regdisp("Melting", NULL);
fprintf(file3, "\r\n<< %s >>\r\n\r\n", hpb.filename);
fflush(file3);
break;
case 'T':
if (hpb.level < 0) {
skipdisp(NOCRC);
return;
}
regdisp("Testing", NULL);
file3 = NULL;
break;
}
interface.method = method;
interface.dicbit = 13; /* method + 8; */
interface.infile = file1;
interface.outfile = file3;
interface.original = hpb.original;
interface.packed = hpb.packed;
switch (method) {
case 8:
method = 0;
break;
case 6:
interface.dicbit = 11;
break;
case 1:
case 4:
case 7:
interface.dicbit = 12;
break;
}
disp(cmd == 'P' && !outredir, cmd != 'P' && outredir);
initdisp();
if (method) {
decode(&interface);
} else {
copyfile(file1, file3, hpb.original, 1);
}
if (file3) {
#if 0
if (fflush(file3)) error(WTERR, filename3);
#else
fflush(file3);
#endif
setfiletime(file3, hpb.utc);
fclose(file3);
file3 = NULL;
}
if (hpb.level >= 0 && crc != hpb.filecrc) {
errorlevel = 1;
eprintf("\rCRC err\n");
if (cmd == 'E') {
if (flg_m == 0) {
eprintf(MAYDELETE);
if (getyn() == 'Y')
remove(filename3);
} else {
remove(filename3);
}
}
if (flg_m == 0) {
eprintf(MAYCONT);
if (getyn() != 'Y')
error(CTRLBRK, NULL);
}
} else {
if (cmd == 'T') {
enddisp("Test OK");
} else {
if (cmd != 'P' || outredir) enddisp("Melted ");
}
if (cmd == 'E' && flg_a) {
_dos_setfileattr(filename3, hpb.attr);
}
}
}
void extract_internal(FILE *f, char *p)
{
interface.method = 5;
interface.dicbit = 13;
interface.infile = NULL;
interface.outfile = f ? fdopen(dup(fileno(f)), "wb") : f;
interface.original = *(ushort *)(p + 2);
interface.packed = *(ushort *)p;
interface.blkcnt = -1;
interface.internal = (char *)(p + 4);
disp(1, 0);
initdisp();
decode(&interface);
}