home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
msdos
/
opus
/
fvsrc620.arc
/
ARC_VIEW.C
next >
Wrap
C/C++ Source or Header
|
1989-05-26
|
22KB
|
655 lines
/*--------------------------------------------------------------------------*/
/* */
/* Copyright 1989, Doug Boone. FidoNet 119/5 */
/* (916) 893-9019 Data */
/* (916) 891-0748 voice */
/* P.O. Box 5108, Chico, CA. 95928 */
/* */
/* This program is not for sale. It is for the free use with Opus systems. */
/* You may not sell it in ANY way. If you have an access charge to your */
/* Bulletin Board, consider this to be like Opus, you can ONLY make it */
/* available for download in an open area, where non-members can get access */
/* */
/* If you need to modify this source code, please send me a copy of the */
/* changes you've made so that everyone can share in the updates. */
/* */
/* "Don't rip me off!" -- Tom Jennings, FidoNet's founder */
/* */
/*--------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <signal.h>
#include <dos.h>
#ifdef TURBOC
#include <dir.h>
#include <alloc.h>
#else
#include <malloc.h>
#endif
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include <conio.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <opus.h>
#include <process.h>
#include "archdr.h"
#include "arc_view.h"
/* ====================================================================
* start a new screen full while listing the contents of an arc file
* ====================================================================
*/
void arc_header(char *packer,char *name)
{
char temp[80];
char *check;
if (!ctrl_err)
return;
if ((check = strchr(name,'\\')) != NULL)
check++;
else
check =name;
sprintf(temp,"\n %s Contents of %s\n",packer,check);
sdisplay(temp);
sdisplay("Filename Length Method Size Ratio Date Time\n");
sdisplay("-------- ------ ------ ------ ----- ---- ----\n");
return;
}
/*--------------------------------------------------------------------------*/
/* Print out one line of archives */
/*--------------------------------------------------------------------------*/
void one_line(char *name,long org_len,long new_len,char *pack,char *date,char *time)
{
int factor;
char temp[80];
if (!ctrl_err)
return;
if (new_len > 0)
factor = ((int) ((100 * new_len)/org_len));
if (strlen(name) < 13)
sprintf(temp,"%-12s",name);
else
sprintf(temp,"%s\n ",name);
sdisplay(temp);
sprintf(temp," %8ld %10s%8ld %3d%%",org_len,pack,new_len,factor);
sdisplay(temp);
sprintf(temp," %8s %8s\n",date,time);
sdisplay(temp);
return;
}
/*--------------------------------------------------------------------------*/
/* Show grand totals for successful archives */
/*--------------------------------------------------------------------------*/
void do_totals(int totmbrs,long totlen,long totsize,int totsf)
{
char temp[81];
if (!ctrl_err)
return;
sdisplay("----\t\t------\t\t ------ -----\n");
sprintf(temp,"Total %6d %8ld ",totmbrs,totlen);
sdisplay(temp);
sprintf(temp,"\t %8ld %3d%%\n",totsize,totsf);
sdisplay(temp);
return;
}
/* ====================================================================
* start of list arc contents processing
* ====================================================================
*/
int lstarc(char *arcname) /* list files in archive */
{
struct heads *hdr; /* header data */
int totmbrs = 0; /* total members in arc */
long totlen = 0L; /* total of file lengths */
long totsize = 0L; /* total of file sizes */
int totsf;
int ver;
FILE *arc; /* archive file */
char date[9];
char time[9];
char method[11];
hdr = (struct heads *) malloc(sizeof(struct heads));
if((arc=fopen(arcname,"rb")) == NULL ) {
perror(" Cannot read archive: ");
return(-1);
}
mem_used = 0;
fseek(arc,1L,SEEK_SET);
ver = fgetc(arc);
if (!(flags & VIEW))
arc_header("ARC/PAK",arcname);
while (ver > 0 && ver < 11) {
fread(hdr,sizeof(struct heads),1,arc);
if (!(flags & VIEW)) {
totlen += hdr->mbrlen;
totsize += hdr->mbrsize;
totmbrs++;
sprintf(date,"%02d-%02d-%02d",
((hdr->mbrdate >> MONTH_SHIFT) & MONTH_MASK),
(hdr->mbrdate & DAY_MASK),
((hdr->mbrdate >> YEAR_SHIFT) + DOS_EPOCH));
sprintf(time,"%02d:%02d:%02d",
((hdr->mbrtime >> HOUR_SHIFT) & HOUR_MASK),
((hdr->mbrtime >> MINUTE_SHIFT) & MINUTE_MASK),
(hdr->mbrtime & HOUR_MASK)*2);
switch(ver) {
case 1: strcpy(method," -- "); /* 1 - old, no compression */
break;
case 2: strcpy(method," Stored "); /* 2 - new, no compression */
break;
case 3: strcpy(method," Packed "); /* 3 - dle for repeat chars */
break;
case 4: strcpy(method," Squeezed "); /* 4 - huffman encodeing */
break;
case 5: strcpy(method," Crunched "); /* 5 - lz, no dle */
break;
case 6: strcpy(method," Crunched "); /* 6 - lz with dle */
break;
case 7: strcpy(method," Crunched "); /* 7 - lz with readjust */
break;
case 8: strcpy(method," Crunched "); /* 8 - lz with readjust and dle */
break;
case 9: strcpy(method," Squashed "); /* 9 - modified lzw, no dle */
break;
case 10: strcpy(method," Crushed "); /* PAK's new method */
break;
default: strcpy(method," Unknown! ");/* future? */
break;
} /* End of version switch */
one_line(hdr->mbrname,hdr->mbrlen,hdr->mbrsize,method,date,time);
}
strcpy(member[mem_used].name,hdr->mbrname);
member[mem_used].size = ((unsigned int) (hdr->mbrsize/1024L));
if (mem_used < MAX_NAMES)
mem_used++;
fseek(arc,hdr->mbrsize+1L,SEEK_CUR);
ver = fgetc(arc);
if (!(ctrl_err))
ver = 0;
}; /* End of while loop */
fclose(arc); /* then close it */
if (!(flags & VIEW)) {
totsf = 0;
if(totlen>0L)
totsf = (int)(100L - ((100L*totsize)/totlen));
do_totals(totmbrs,totlen,totsize,totsf);
}
free(hdr);
if (mem_used >0) {
mem_used--;
if (ctrl_err)
return(0);
}
return(-1);
}
/*--------------------------------------------------------------------------*/
/* Handle a ZOO archive */
/*--------------------------------------------------------------------------*/
int do_zoo(char *filename)
{
FILE *fhandle;
struct zoo_header *main_head;
struct direntry *one_head;
int result;
unsigned totmbrs=0; /* number of members in Zoo */
long totlen=0L; /* total of all file sizes */
long totsize = 0L;
int totsf;
char method[11];
char time[9];
char date[9];
main_head = (struct zoo_header *) malloc(sizeof(struct zoo_header));
one_head = (struct direntry *) malloc(sizeof(struct direntry));
fhandle = fopen(filename,"rb");
result = fread(main_head,sizeof(struct zoo_header),1,fhandle);
if ((strnicmp(main_head->text,"ZOO",3)) != 0) {
sdisplay(" Not a Zoo archive! ");
fclose(fhandle);
return(-1);
}
mem_used = 0;
if (!(flags & VIEW))
arc_header("ZOO",filename);
fseek(fhandle,main_head->zoo_start,SEEK_SET);
result = fread(one_head,sizeof(struct direntry),1,fhandle);
do {
if (result == 1) {
if (!(flags & VIEW)) {
totmbrs++;
totsize += one_head->org_size;
totlen += one_head->size_now;
switch(one_head->packing_method) {
case 0:
strcpy(method," Stored ");
break;
case 1:
strcpy(method," Norm LZW ");
break;
default:
strcpy(method," Unknown ");
break;
}
sprintf(date,"%02d-%02d-%02d",
((one_head->date >> MONTH_SHIFT) & MONTH_MASK),
(one_head->date & DAY_MASK),
((one_head->date >> YEAR_SHIFT) + DOS_EPOCH));
sprintf(time,"%02d:%02d:%02d",
((one_head->time >> HOUR_SHIFT) & HOUR_MASK),
((one_head->time >> MINUTE_SHIFT) & MINUTE_MASK),
(one_head->time & HOUR_MASK)*2);
one_line(one_head->fname,one_head->org_size,one_head->size_now,
method,date,time);
}
strcpy(member[mem_used].name,one_head->fname);
member[mem_used].size = ((unsigned int) (one_head->org_size/1024L));
if (mem_used < MAX_NAMES)
mem_used++;
fseek(fhandle,one_head->next,SEEK_SET);
}
result = fread(one_head,sizeof(struct direntry),1,fhandle);
if (!(ctrl_err))
result = 0;
} while ((one_head->offset != 0L) &&
(result == 1));
free(one_head);
free(main_head);
if (mem_used > 0)
mem_used--;
result = fclose(fhandle);
if (!(flags & VIEW)) {
if (totlen>0)
totsf=(int)(100L - ((100L*totlen)/totsize));
else
totsf = 0;
do_totals(totmbrs,totlen,totsize,totsf);
}
return(0);
}
/*--------------------------------------------------------------------------*/
/* Read a DWC archive. These are the hardest ones to get into. */
/*--------------------------------------------------------------------------*/
int read_dwc(char *name)
{
long size;
int infile;
unsigned int result;
struct dwc_entry *one_entry;
struct dwc_arc *one_archive;
struct tm *t;
char junkbuffer[256];
char *dwc;
unsigned int junkoffset;
int count; /* total number of files in this archive */
long totsize = 0L;
long totlen = 0L;
int totmbrs = 0;
int totsf;
char date[9];
char time[9];
char method[11];
if((infile = open(name,O_BINARY|O_RDONLY)) < 0) {
sprintf(junkbuffer,"Couldn't open file %s\n",name);
sdisplay(junkbuffer);
return(-1);
}
one_entry = (struct dwc_entry *) malloc(sizeof(struct dwc_entry));
one_archive = (struct dwc_arc *) malloc(sizeof(struct dwc_arc));
count = 0;
mem_used = 0;
do {
totlen = (long) (++count * sizeof(junkbuffer));
size = lseek(infile,-totlen,SEEK_END);
if (size > 0L)
result = read(infile,junkbuffer,sizeof(junkbuffer));
else result = 0;
} while ((count < 20) && (result == sizeof(junkbuffer)) &&
((dwc = memrstr(junkbuffer,"DWC",result)) == NULL));
if ((result < sizeof(junkbuffer)) ||
(count > 19)) { /* Failed to find "DWC", not DWC file */
close (infile);
free(one_archive);
free(one_entry);
return(-1);
}
junkoffset = count * sizeof(junkbuffer) /* start of this buffer block */
- (dwc-junkbuffer) /* minus the offset to the "DWC" in the buffer */
+ sizeof(struct dwc_arc) - 3;
size = lseek (infile,-(long)junkoffset,SEEK_END);
result = read(infile,(void *) one_archive,sizeof(struct dwc_arc));
if (one_archive->size != sizeof(struct dwc_arc)) {
close(infile);
free(one_archive);
free(one_entry);
return(-1);
}
flags |= DWC;
if (!(flags & VIEW))
arc_header("DWC",name);
count = (int) one_archive->entries;
totmbrs = count;
totlen = 0L;
size = lseek(infile,-(long)(count*one_archive->ent_sz+junkoffset),SEEK_END);
while (count>0) {
result = read(infile,(void *) one_entry,sizeof(struct dwc_entry));
totsize += one_entry->size;
totlen += one_entry->new_size;
switch(one_entry->method) {
case 0:
strcpy(method," Stored ");
break;
case 1:
strcpy(method," Norm LZW ");
break;
default:
strcpy(method," Unknown ");
break;
}
totsf = 0;
t = localtime(&one_entry->time);
sprintf(time,"%02d-%02d-%02d",
(t->tm_mon+1),t->tm_mday,t->tm_year);
sprintf(date,"%02d:%02d:%02d",
t->tm_hour,t->tm_min,t->tm_sec);
strcpy(member[mem_used].name,one_entry->name);
member[mem_used].size = ((unsigned int) (one_entry->size/1024L));
if (!(flags & VIEW))
one_line(one_entry->name,one_entry->size,one_entry->new_size,
method,time,date);
count--;
if (!(ctrl_err))
count = 0;
if (mem_used < MAX_NAMES)
mem_used++;
};
close (infile);
free(one_archive);
free(one_entry);
if (mem_used > 0)
mem_used--;
if (!(flags & VIEW)) {
if (totlen>0)
totsf=(int)(100L - ((100L*totlen)/totsize));
else
totsf = 0;
do_totals(totmbrs,totlen,totsize,totsf);
}
return(0);
}
/*--------------------------------------------------------------------------*/
/* memrstr searches backwards through a chunk of memory called "buffer" */
/* that is "buflen" long, looking for a string "target". The search is from */
/* the end of "buffer" forward. It returns a pointer to the start of the */
/* target string */
/*--------------------------------------------------------------------------*/
char *memrstr(char *buffer,char *target,int buflen)
{
char c = ' ';
char *ptr;
int found = 1;
c = target[strlen(target)-1];
ptr = buffer+buflen;
do {
if (c != *ptr)
ptr--;
else {
ptr -= strlen(target)-1;
found = strnicmp(target,ptr,sizeof(target));
if (found != 0)
ptr += strlen(target) - 2;
}
if (ptr < buffer)
ptr = NULL;
} while (found !=0 && ptr != NULL);
return(ptr);
}
/*--------------------------------------------------------------------------*/
/* Do ZIP Archives */
/*--------------------------------------------------------------------------*/
do_zip(char *name)
{
struct ID_Hdr *ID;
struct Local_Hdr *local;
char *mbrname;
long totsize = 0L;
long totlen = 0L;
int totmbrs = 0;
int totsf;
char date[9];
char time[9];
char method[11];
int handle;
int check;
ID = (struct ID_Hdr *) malloc(sizeof(struct ID_Hdr));
local = (struct Local_Hdr *) malloc(sizeof(struct Local_Hdr));
mbrname = (char *) malloc(80);
if (!(flags & VIEW))
arc_header("ZIP",name);
mem_used = 0;
handle = open(name,O_BINARY|O_RDONLY);
do {
check = read(handle,(void *)ID,sizeof(struct ID_Hdr));
if (ID->Head_Type == LOCAL_HEADER) {
if ((check = read(handle,(void *)local,sizeof(struct Local_Hdr))) != -1) {
if (!(flags & VIEW)) {
sprintf(date,"%02d-%02d-%02d",
((local->mod_date >> MONTH_SHIFT) & MONTH_MASK),
(local->mod_date & DAY_MASK),
((local->mod_date >> YEAR_SHIFT) + DOS_EPOCH));
sprintf(time,"%02d:%02d:%02d",
((local->mod_time >> HOUR_SHIFT) & HOUR_MASK),
((local->mod_time >> MINUTE_SHIFT) & MINUTE_MASK),
(local->mod_time & HOUR_MASK)*2);
switch(local->compression) {
case 0: strcpy(method," Stored "); break;
case 1: strcpy(method," Shrunk "); break;
case 2: strcpy(method," Reduce(1)"); break;
case 3: strcpy(method," Reduce(2)"); break;
case 4: strcpy(method," Reduce(3)"); break;
case 5: strcpy(method," Reduce(4)"); break;
}
totsize += local->size_now;
totlen += local->real_size;
totmbrs++;
}
memset(mbrname,EOS,80);
check = read(handle,mbrname,local->name_length);
strcpy(member[mem_used].name,mbrname);
member[mem_used].size = ((unsigned int) (local->real_size/1024L));
if (!(flags & VIEW))
one_line(mbrname,local->real_size,local->size_now,method,date,time);
lseek(handle,local->size_now,SEEK_CUR);
if (!(ctrl_err))
check = 0;
if (mem_used < MAX_NAMES)
mem_used++;
} /* End of one entry */
} /* End of grabbing local directory entries */
else
check = -1;
} while(check >0 && !eof(handle)); /* End of file */
if (mem_used > 0) {
mem_used--;
check = 0;
}
if (!(flags & VIEW)) {
if (totsize>0)
totsf=(int)(100L - ((100L*totsize)/totlen));
else
totsf = 0;
do_totals(totmbrs,totlen,totsize,totsf);
}
close(handle);
free(local);
free(mbrname);
free(ID);
return(check);
}
/*--------------------------------------------------------------------------*/
/* Do LZH (LHARC) files */
/*--------------------------------------------------------------------------*/
int read_lzh(char *name)
{
struct Lharc_Hdr *local;
long totsize = 0L;
long totlen = 0L;
int totmbr = 0;
int totsf;
char date[9];
char time[9];
char method[11];
char *mbrname;
int handle;
int check;
local = (struct Lharc_Hdr *) malloc(sizeof(struct Lharc_Hdr));
mbrname = (char *) malloc(80);
mem_used = 0;
handle = open(name,O_BINARY|O_RDONLY);
if ((check = read(handle,(void *)local,sizeof(struct Lharc_Hdr))) ==
sizeof(struct Lharc_Hdr)) {
if (!((strncmp(local->type,"-lh",3) == 0) &&
(local->type[4] == '-'))) {
close(handle);
free(local);
free(mbrname);
return(-1);
}
}
else {
close(handle);
free(local);
free(mbrname);
return(-1);
}
flags |= LZH;
if (!(flags & VIEW))
arc_header("LHARC",name);
do {
if (!(flags & VIEW)) {
sprintf(date,"%02d-%02d-%02d",
((local->date >> MONTH_SHIFT) & MONTH_MASK),
(local->date & DAY_MASK),
((local->date >> YEAR_SHIFT) + DOS_EPOCH));
sprintf(time,"%02d:%02d:%02d",
((local->time >> HOUR_SHIFT) & HOUR_MASK),
((local->time >> MINUTE_SHIFT) & MINUTE_MASK),
(local->time & HOUR_MASK)*2);
strcpy(method," ");
strcat(method,local->type);
method[7] = EOS;
strcat(method," ");
totsize += local->size_now;
totlen += local->orig_size;
totmbr++;
} /* End of listing stuff */
memset(mbrname,EOS,80);
check = read(handle,mbrname,local->name_len);
strcpy(member[mem_used].name,mbrname);
member[mem_used].size = ((unsigned int) (local->orig_size/1024L));
if (!(flags & VIEW))
one_line(mbrname,local->orig_size,local->size_now,method,date,time);
lseek(handle,local->size_now + 2L,SEEK_CUR);
check = read(handle,(void *)local,sizeof(struct Lharc_Hdr));
if (!(ctrl_err))
check = 0;
if (mem_used < MAX_NAMES)
mem_used++;
} while(check >1 && !eof(handle)); /* End of file */
close(handle);
free(local);
free(mbrname);
if (mem_used > 0) {
mem_used--;
check = 0;
}
if (!(flags & VIEW)) {
if (totsize>0)
totsf=(int)(100L - ((100L*totsize)/totlen));
else
totsf = 0;
printf("----\t\t------\t\t ------ -----\n");
printf("Total %6d %8ld ",totmbr,totlen);
printf("\t %8ld %3d%%\n",totsize,totsf);
}
return(check);
}
void unpack(int input_handle,int output_handle,long size)
{
char *buf;
unsigned done;
unsigned do_what = 8096;
if (size < (long)8096) {
do_what = (unsigned) size;
buf = (char *) malloc(do_what);
read(input_handle,buf,do_what);
write(output_handle,buf,do_what);
free(buf);
}
else {
buf = (char *) malloc(do_what);
while (size > 0L) {
done = read(input_handle,buf,do_what);
write(output_handle,buf,do_what);
size -= (long) done;
if (size < do_what)
do_what = (unsigned) size;
}
free(buf);
}
return;
}