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
/
mn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-24
|
13KB
|
678 lines
/*
* mn.c -- main module of LH
* Copyright (C) 1988-1992, Haruyasu YOSHIZAKI
* Copyright (C) 1991-1996, Satoshi HIRAMATSU (OS/2 HPFS version)
*
* $Log$
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <stdio.h>
#include <io.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include "typedef.h"
#include "port2.h"
#include "lh.h"
#include "header.h"
#include "errmes.h"
#include "intrface.h"
#include "disp.h"
#define SECURITY 0
char work[4096];
char lhtmp1[MAXPATHLEN];
char lhtmp2[MAXPATHLEN];
FILE *inredir = NULL, *response = NULL;
int outredir;
int paramcount = -2;
char cmd;
int cmdupdate;
char *env;
char workdir[MAXPATHLEN];
#if 0
char *pager = "less";
char *keyword = "";
#endif
char arcname[MAXPATHLEN];
char filename1[MAXPATHLEN];
char filename2[MAXPATHLEN];
char filename3[MAXPATHLEN];
FILE *file1, *file2, *file3;
int errorlevel = 0;
#ifdef __SUPPORT_UID_GID__
uid_t uid = 0; /* root */
gid_t gid = 0; /* wheel */
#endif
#ifdef __SUPPORT_EA__
FEA2LIST *arcea = (FEA2LIST *)NULL;
#endif
#ifndef __SUPPORT_CTIME_ATIME__
static time_t arcstamp;
#else
static struct
{
time_t mtime;
time_t ctime;
time_t atime;
} arcstamp;
#endif
/* display usages */
void
usage(void)
{
flg_n = 2;
#ifndef FIRST_COMPILATION
extract_internal(stdout, use);
#endif
exit(2);
}
#ifndef __SUPPORT_CTIME_ATIME__
void
update_arcstamp(void)
{
if(arcstamp < hpb.mtime)
arcstamp = hpb.mtime;
}
static void
set_arcstamp(FILE *f)
{
if(flg_t)
setfiletime(f, arcstamp);
}
#else
void
update_arcstamp(void)
{
if(arcstamp.mtime < hpb.mtime)
{
arcstamp.mtime = hpb.mtime;
arcstamp.atime = hpb.atime;
}
}
static void
set_arcstamp(FILE *f)
{
if(flg_t)
setfiletime(f, &arcstamp.mtime, (time_t *)NULL, &arcstamp.atime);
}
#endif
static char *
readword(FILE *file)
{
char *p;
int c;
while(((unsigned)(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 *bdir, *path;
ulong size0, size;
int _flg_n;
struct stat statbuf;
int existarc = 0;
make_crctable();
err = 0;
#ifndef __SUPPORT_CTIME_ATIME__
arcstamp = 0;
#else
arcstamp.mtime = arcstamp.ctime = arcstamp.atime = 0;
#endif
modified = 0;
strcpy(filename1, arcname);
if(cmdupdate)
{
strcpy(filename1, lhtmp1);
if(remove(filename1) && errno != ENOENT)
error(RDONLY, filename1); /* already EXIST tmpfile */
existarc = stat(arcname, &statbuf);
if(rename(arcname, filename1) && !existarc)
{
/* copy */
file1 = myeopen(filename1, "wb", NULL);
file2 = myeopen(arcname, "rb", NULL);
_flg_n = flg_n;
flg_n = 2; /* silent */
copyfile(file2, file1, statbuf.st_size, 0);
flg_n = _flg_n;
fclose(file1);
fclose(file2);
}
}
file1 = myeopen(filename1, "rb", NULL);
if(cmdupdate || cmd == 'S')
{
if(file1 == NULL)
{
fclose(mywopen(arcname, MKFILEERR));
remove(arcname);
}
strcpy(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':
setmode(fileno(stdout), O_BINARY);
disparcname("Extracting from");
break;
case 'T':
disparcname("Testing");
break;
#if 0
case 'S':
disparcname("Making SFX of");
initsfx();
break;
#endif
}
if(file1)
{
size0 = inithdr(file1);
if(cmd == 'T' &&
stricmp(arcname + strlen(arcname) - 4, ".lzh") == 0 && size0 != 0)
eprintf(EXTRADATA);
while(file1 && (path = gethdr(file1, &hpb)) != 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(&hpb);
break;
case 'P':
flg_n = 2;
case 'E':
case 'T':
if(bdir)
extract(bdir);
break;
#if 0
case 'S':
if(bdir)
if(copysfx())
modified++;
break;
#endif
}
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;
#if 0
case 'S':
makesfx(bdir);
break;
#endif
}
}
#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))
{
flg_n = 2;
if(!flg_f && (diskspace(filename1) < size))
error(COPYERR, NULL);
eprintf("Copying TMP to ARCHIVE ... ");
rename(filename1, arcname);
file1 = mywopen(arcname, COPYERR);
file2 = myropen(filename2);
copyfile(file2, file1, size, 0);
set_arcstamp(file1);
fclose(file1);
#ifdef __SUPPORT_EA__
if(arcea)
SetEA(arcname, arcea);
#endif
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;
unsigned 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);
#ifdef __SUPPORT_EA__
if(findbuf.ea)
arcea = findbuf.ea;
#endif
executecmd();
}
else
{
do
{
#ifdef __SUPPORT_EA__
if(findbuf.ea)
free(findbuf.ea);
#endif
backpath(arcname);
strcat(arcname, findbuf.name);
testflag |= (unsigned)executecmd();
}
while(!_dos_findnext(&findbuf));
}
if(cmd != 'L' && testflag == 0)
tstpat();
return 0;
}
int
main(int argc, char *argv[])
{
uchar c, *p, *q;
int i;
static fileinputflag = 0;
static char *basedir = "";
int __ifs__;
initbreak();
getswchar();
initpat();
SetMessage();
if((p = getenv("TMPDIR")) != NULL && (p = strtok(p, " \t")) != NULL)
{
strcpy(workdir, p);
flg_w = 1;
}
else if((p = getenv("TMP")) != NULL && (p = strtok(p, " \t")) != NULL)
{
strcpy(workdir, p);
flg_w = 1;
}
else if((p = getenv("TEMP")) != NULL && (p = strtok(p, " \t")) != NULL)
{
strcpy(workdir, p);
flg_w = 1;
}
if((env = getenv("LHA")) == NULL)
env = getenv("LHARC");
#ifdef __SUPPORT_UID_GID__
#ifdef __OS2__
if(p = getenv("UNIX.UID"))
uid = 0xffff & atoi(p);
if(p = getenv("UNIX.GID"))
gid = 0xffff & atoi(p);
#endif
#endif
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);
#ifndef __SUPPORT_HPFS__
regpat("+", basedir); /* We can use '+' for filename on OS/2 HPFS. */
#else
regpat("\xff", basedir); /* special case */
#endif
}
if(flg_o)
flg_h = 0;
if(flg_d)
{
flg_r = 2;
flg_x = 1;
flg_a = 2;
}
else if(flg_x && (flg_r == 2) && (flg_a == 2))
flg_d = 1;
SetFileSystem(cmdupdate, basedir);
/* make temporary filenames. */
convdelim(workdir, DELIM);
__ifs__ = GetFileSystem(workdir);
strcpy(lhtmp2, workdir);
if(*(lhtmp2 + strlen(lhtmp2) - 1) != DELIM)
strcat(lhtmp2, DELIMSTR);
if(__ifs__ == FAT)
strcat(lhtmp2, "l2XXXXXX");
else
strcat(lhtmp2, "lha2.XXXXXX");
convdelim(arcname, DELIM);
__ifs__ = GetFileSystem(arcname);
strcpy(lhtmp1, arcname);
if(lhtmp1[1] != ':')
strcpy(lhtmp1, workdir); /* current drive */
else
strcat(backpath(lhtmp1), "\0");
if(*(lhtmp1 + strlen(lhtmp1) - 1) != DELIM)
strcat(lhtmp1, DELIMSTR);
if(__ifs__ == FAT)
strcat(lhtmp1, "l1XXXXXX");
else
strcat(lhtmp1, "lha1.XXXXXX");
mktemp(lhtmp1);
mktemp(lhtmp2);
__ifs__ = GetFileSystem(arcname);
p = convdelim(arcname, DELIM);
if ((q = strchr(p, '.')) == NULL)
strcat(arcname, ".lzh"); /* if no extension */
q = arcname + strlen(arcname) - 4;
if(stricmp(".lzh", q) && stricmp(".lzs", q) && __ifs__ == HPFS)
strcat(arcname, ".lzh"); /* if no extension */
else if(stricmp(".lzh", q) && cmdupdate && __ifs__ == FAT)
{
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;
}