home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1997 November
/
PCWorld_1997-11_cd.bin
/
software
/
sharware
/
utility
/
PACKERS
/
LZH
/
LHASRC.EXE
/
MN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-03
|
9KB
|
445 lines
/***********************************************************
mn.c -- main module of LH
***********************************************************/
#include <ctype.h>
#include <stdio.h>
#include <io.h>
#include <dos.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "lh.h"
#include "errmes.h"
#include "intrface.h"
#include "disp.h"
#define SECURITY 0
#define CRCPOLY 0xA001 /* CRC-16 */
char work[4096];
char lhtmp1[] = "LHTMP)1(.LZH";
char lhtmp2[] = "LHTMP)2(.LZH";
FILE *inredir = NULL, *response = NULL;
int outredir;
int paramcount = -2;
char cmd;
int cmdupdate;
char *env;
char workdir[MAX_PATH];
#if 0
char *pager = "LESS";
char *keyword = "";
#endif
char arcname[MAX_PATH];
char filename1[MAX_PATH];
char filename2[MAX_PATH];
char filename3[MAX_PATH];
FILE *file1, *file2, *file3;
int errorlevel = 0;
static time_t arcstamp;
/*******************************
display usages
*******************************/
void usage(void)
{
extract_internal(stdout, use);
exit(2);
}
void update_arcstamp(void)
{
if (arcstamp < hpb.utc) arcstamp = hpb.utc;
}
static void set_arcstamp(FILE *f)
{
if (flg_t) setfiletime(f, arcstamp);
}
static char *readword(FILE *file)
{
char *p;
int c;
while (((c = getc(file)) & 0xff) <= ' ');
if (c < 0) {
fclose(file);
return NULL;
}
p = work;
do {
*p++ = c;
} while ((c = getc(file)) > ' ');
*p++ = '\0';
return work;
}
static void disparcname(char *title)
{
FILE *f;
f = (cmd == 'L') ? stdout : stderr;
if (flg_n == 0) {
fprintf(f, "\n%s archive : %s\n\n", title, arcname);
}
}
static int executecmd(void)
{
int modified, err;
char far *bdir, *path;
ulong size0, size;
uchar c;
make_crctable(CRCPOLY);
err = 0;
arcstamp = 0;
modified = 0;
strcpy(filename1, arcname);
if (cmdupdate) {
strcpy(backpath(filename1), lhtmp1);
if (remove(filename1) && errno != ENOENT)
error(RDONLY, filename1);
rename(arcname, filename1);
}
file1 = myeopen(filename1, "rb", NULL);
if (cmdupdate || cmd == 'S') {
if (file1 == NULL) {
fclose(mywopen(arcname, MKFILEERR));
remove(arcname);
}
if (flg_w) {
strcpy(filename2, workdir);
convdelim(filename2, DELIM);
c = filename2[strlen(filename2) - 1];
if (c != DELIM && c != ':') strcat(filename2, DELIMSTR);
strcat(filename2, lhtmp2);
} else {
strcpy(filename2, arcname);
strcpy(backpath(filename2), lhtmp2);
}
file2 = mywopen(filename2, NULL);
if (file2 == NULL) {
file2 = mywopen(lhtmp2, NULL);
if (file2 == NULL)
error(MKTMPERR, filename2);
strcpy(filename2, lhtmp2);
}
setvbuf(file2, NULL, _IOFBF, 0x2000);
} else {
setvbuf(file1, NULL, _IOFBF, 0x2000);
}
switch (cmd) {
case 'V':
flg_x = 1;
cmd = 'L';
case 'L':
disparcname("Listing of");
initlist();
break;
case 'A':
flg_c = 1;
cmd = 'U';
case 'U':
case 'M':
if (file1) {
disparcname("Updating");
} else {
disparcname("Creating");
}
mklist();
break;
case 'F':
disparcname("Freshening");
break;
case 'D':
disparcname("Deleting from");
break;
case 'P':
case 'E':
disparcname("Extracting from");
break;
case 'T':
disparcname("Testing");
break;
case 'S':
disparcname("Making SFX of");
initsfx();
break;
}
/************/
if (file1) {
size0 = inithdr();
if (cmd == 'T' &&
stricmp(arcname + strlen(arcname) - 4, ".LZH") == 0 &&
size0 != 0) {
eprintf(EXTRADATA);
}
if (cmdupdate) {
rewind(file1);
copyfile(file1, file2, size0, 0);
}
while (file1 && (path = gethdr(&err)) != NULL) {
bdir = matchpat(path);
switch (cmd) {
case 'L':
if (bdir) {
list();
}
break;
case 'U':
case 'M':
modified += append();
break;
case 'F':
modified += freshen(bdir);
break;
case 'D':
if (bdir) {
dispalone("Deleted");
eprintf("\n");
modified++;
} else {
copylzh();
}
break;
case 'E':
case 'P':
case 'T':
if (bdir) {
extract(bdir);
}
break;
case 'S':
if (bdir) {
if (copysfx()) modified++;
}
break;
}
free(path);
}
} else {
size0 = 0;
if (!cmdupdate) error(NOARCERR, arcname);
}
/************/
if (!err) {
switch (cmd) {
case 'L':
endlist(getfiletime(file1));
break;
case 'U':
case 'M':
modified += endappend();
break;
case 'S':
makesfx(bdir);
break;
}
}
#if SECURITY
if (cmd == 'T') {
extern int security(void);
if (security()) return 1;
}
#endif
if (err) error(BROKENARC, arcname);
if (cmd == 'M') deletefiles();
if (cmdupdate || (cmd == 'S' && file2)) {
putc('\0', file2);
size = ftell(file2);
fflush(file2);
if (ferror(file2)) error(WTERR, filename2);
set_arcstamp(file2);
fclose(file2);
if (file1) {
set_arcstamp(file1);
fclose(file1);
}
if (modified == 0) {
rename(filename1, arcname); /* restore the old archive */
remove(filename2);
} else {
if (rename(filename2, arcname)) {
if (diskspace(filename1) < size) error(COPYERR, NULL);
eprintf("Copying TMP to ARC ... ");
rename(filename1, arcname);
file1 = mywopen(arcname, COPYERR);
file2 = myropen(filename2);
copyfile(file2, file1, size, 0);
#if 0
if (fflush(file1)) error(WTERR, filename2);
#endif
set_arcstamp(file1);
fclose(file1);
fclose(file2);
remove(filename2);
eprintf("done.\n");
} else {
if (cmd != 'S') remove(filename1);
}
if (size - size0 <= 1) remove(arcname);
}
} else {
fclose(file1);
}
return 0;
}
static int execute(void)
{
struct find_t findbuf;
int nofile;
int testflag;
testflag = 0;
nofile = _dos_findfirst(arcname, 0x07, &findbuf);
if (nofile && strchr("AUM", cmd) == NULL)
error(NOARCERR, arcname);
if (cmdupdate) {
if (strpbrk(arcname, "*?")) error(NOARCERR, arcname);
/* when updating archive, wild cards can't used */
if (!nofile && findbuf.attrib & 0x01)
error(RDONLY, arcname);
executecmd();
} else {
do {
backpath(arcname);
strcat(arcname, findbuf.name);
testflag |= executecmd();
} while (!_dos_findnext(&findbuf));
}
if (cmd != 'L' && testflag == 0) tstpat();
}
int main(int argc, char *argv[])
{
uchar c, *p, *q;
int i;
static fileinputflag = 0;
static char far *basedir = "";
initbreak();
getswchar();
initpat();
if ((p = getenv("TMP")) != NULL
&& (p = strtok(p, " \t")) != NULL) {
strcpy(workdir, p);
flg_w = 1;
}
if ((env = getenv("LHA")) == NULL)
env = getenv("LHARC");
if (!isatty(0)) {
fileinputflag = 1;
inredir = fdopen(dup(0), "rt");
fclose(stdin);
fopen("con", "rt"); /* open stdin */
}
outredir = !isatty(1);
argc--;
argv++;
while (1) {
if (env) {
while (*env && (uchar)*env <= ' ') env++;
if (*env == '\0') {
env = NULL;
continue;
}
p = env;
while (*env > ' ') env++;
if (*env) {
*env++ = '\0';
}
} else if (response) {
fileinputflag = 1;
if ((p = readword(response)) == NULL) {
response = NULL;
continue;
}
} else if (argc) {
argc--;
p = *argv++;
} else if (inredir == NULL || (p = readword(inredir)) == NULL) {
break;
}
if (*p == swchar && swchar != '-' || *p == '-' && !flg_at) {
p++;
getopt(p);
continue;
} else if (*p == '@' && !flg_at) {
if (!response) {
p++;
if ((response = fopen(p, "rt")) == NULL)
error(RDERR, p);
continue;
}
}
if (paramcount == -2) {
/* get command */
cmd = toupper(*p);
if (p[1] != '\0' || !strchr("EXTDLVAUMFPS", cmd)) {
cmd = 'L';
paramcount++;
}
/* command updating archive? */
cmdupdate = (int)strchr("AUMFD", cmd);
/* command 'X' = 'E -x1m1' */
if (cmd == 'X') {
cmd = 'E';
flg_x = flg_m = 1;
}
}
if (paramcount == -1) {
/* get archive name */
i = strlen(p);
strcpy(arcname, p);
} else if (paramcount >= 0) {
convdelim(p, DELIM);
c = p[strlen(p) - 1];
if (c == DELIM || c == ':') {
basedir = strcmp(p, "." DELIMSTR) ? regbdir(p) : "";
continue;
} else {
regpat(p, basedir);
}
}
paramcount++;
}
if (paramcount == -2) usage();
if (paramcount == -1) error(NOARCNMERR, NULL);
if (paramcount == 0) {
if (cmd == 'D' || fileinputflag) {
error(NOFNERR, NULL);
}
regpat("+", basedir);
}
if (flg_o) flg_h = 0;
p = convdelim(arcname, DELIM);
if ((q = strchr(p, '.')) == NULL) {
strcat(arcname, ".LZH"); /* if no extension */
} else if (stricmp(".LZH", q) && cmdupdate) {
if (flg_m == 0) {
eprintf(NOTLZH, arcname);
c = getyn(); /* if the extension is not '.LZH' */
if (c == 'N') {
return(2);
}
}
flg_h = 0;
}
execute();
return errorlevel;
}