home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- 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);
- }
-