home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 December
/
VPR9712A.ISO
/
OLS
/
OS2
/
LHA2P205
/
LHA2P205.LZH
/
lha2-2.05pre
/
source.lzh
/
src
/
extract.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-24
|
8KB
|
388 lines
/*
* extract.c --- extract file from archive
* Copyright (C) 1988-1992, Haruyasu YOSHIZAKI
* Copyright (C) 1991-1996, Satoshi HIRAMATSU (OS/2 HPFS version)
*
* $Log$
*/
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include <direct.h>
#include <time.h>
#include "typedef.h"
#include "port2.h"
#include "lh.h"
#include "header.h"
#include "intrface.h"
#include "slidehuf.h"
#include "disp.h"
#include "errmes.h"
/* 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);
#ifdef __SUPPORT_EA__
if(srchbuf.ea)
free(srchbuf.ea);
#endif
if(absent)
{
if(yn == 'N')
{
*p = DELIM;
eprintf("'%s' : %s", name, MKDIR);
*p = '\0';
yn = getyn();
}
if(yn == 'N')
return 'S';
else
{
#ifdef __API16__
if(__version__ < 1020) /* for OS/2 v1.0 and v1.1. */
{
if (DosMkDir((PSZ) name, 0L)) /* make directory */
if((srchbuf.attrib & 0x10) == 0)
error(MKDIRERR, name);
}
else
{
if(DosMkDir2((PSZ) name, (PEAOP) NULL, 0L))
if((srchbuf.attrib & 0x10) == 0)
error(MKDIRERR, name);
}
#else
if(mkdir(name))
if((srchbuf.attrib & 0x10) == 0)
error(MKDIRERR, name);
#ifdef __SUPPORT_EA__
if(hpb.ea)
SetEA(name, hpb.ea);
#endif /* __SUPPORT_EA__ */
#endif
}
}
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))
{
#ifdef __SUPPORT_EA__
if(srchbuf.ea)
free(srchbuf.ea);
#endif
/* already exists */
if(flg_c == 0 &&
dos2unix((struct ftime *)&srchbuf.wr_time) >= hpb.mtime)
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')
{
if(!flg_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 */
#ifdef __SUPPORT_EA__
if(hpb.ea)
SetEA(name, hpb.ea);
#endif /* __SUPPORT_EA__ */
}
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;
#ifdef __SUPPORT_EA__
if(srchbuf.ea)
free(srchbuf.ea);
#endif
}
return 0;
}
void
extract(char *bdir)
{
char *path;
int method;
hword crc;
dispflg = 0;
memcpy(methods[SENTINEL], hpb.method, 5);
for(method = 0; memcmp(hpb.method, methods[method], 5); method++)
;
if(method == SENTINEL)
{
skipdisp(METHODERR);
return;
}
switch(cmd)
{
case 'E':
if((hpb.attr & 0x06) && flg_a == 0)
{
skipdisp(SPECIALATTR);
return;
}
if(flg_i == 2) /* change to lower charcter. */
jstrlwr(hpb.pathname);
else if(flg_i == 0)
jstrupr(hpb.pathname);
form_path(hpb.pathname);
hpb.filename = getfilename(hpb.pathname);
path = (flg_x) ? hpb.pathname : hpb.filename;
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(!flg_f && (diskspace(filename3) < hpb.original))
{
skipdisp(DISKFULL);
return;
}
/* for UNIX version LHA directory archives. */
/* for OS/2 version LHA directory archives with "-d" option. */
if(*(hpb.pathname + strlen(hpb.pathname) - 1) == DELIM)
{
regdisp(" ", hpb.pathname);
break;
}
file3 = mywopen(filename3, MKFILEERR);
regdisp("Melting ", filename3);
break;
case 'P':
file3 = fdopen(dup(1), "wb");
regdisp("Melting", NULL);
if(!flg_n)
{
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;
interface.infile = file1;
interface.outfile = file3;
interface.original = hpb.original;
interface.packed = hpb.packed;
switch(method)
{
case LH0:
case LZ4:
case LHD:
method = 0;
break;
case LZS:
interface.dicbit = 11;
break;
case LH1:
case LH4:
case LZ5:
interface.dicbit = 12;
break;
}
if(!((flg_n == 2) && (cmd == 'P')))
disp(cmd == 'P' && !outredir, cmd != 'P' && outredir);
initdisp();
if(method)
crc = decode(&interface);
else
crc = copyfile(file1, file3, hpb.original, 1);
if(file3)
{
fflush(file3);
#ifndef __SUPPORT_CTIME_ATIME__
setfiletime(file3, hpb.mtime);
#else
setfiletime(file3, &hpb.mtime, &hpb.ctime, &hpb.atime);
#endif
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
{
/* for directory archive */
if(*(hpb.pathname + strlen(hpb.pathname) - 1) == DELIM)
{
if(cmd != 'P' || outredir)
enddisp("mkdir ");
}
else
{
if(cmd != 'P' || outredir)
enddisp("Melted ");
}
}
if(cmd == 'E' && flg_a)
_dos_setfileattr(filename3, hpb.attr);
#ifdef __SUPPORT_EA__
if(hpb.ea)
SetEA(filename3, hpb.ea);
#endif /* __SUPPORT_EA__ */
}
}
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 = *(ulong *)(p + 4);
interface.packed = *(ulong *)p;
interface.blkcnt = -1;
interface.internal = (char *)(p + 8);
dispflg = 1;
decode(&interface);
}