home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
551.lha
/
Lister_v1.01
/
lister.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-08
|
19KB
|
816 lines
/*
Lister v1.01 Source Code
Copyright 1991 Baf! Technologies
Started : 5/24/91 at 11:24:10 pm
Written by: Geoffrey Faivre-Malloy & Kerry Cianos
jjm7609csci@apsu.bitnet ktc0440csci@apsu.bitnet
Bix - mduck
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
/* our defines */
#define FALSE 0
#define TRUE 1
#define OFF 0
#define ON 1
/* declare a data type */
#define ULONG unsigned long
#define PTR unsigned long int
#define UCHAR unsigned char
/* file type defines */
#define ARC 12
#define LHARC 13
#define ZIP 14
#define ZOO 15
#define SIT 16
#define CPIO 17
#define TAR 18
#define ADD_EXT 19
/* error code defines */
#define FILE_ERROR 101
#define MEMORY_ERROR 102
#define NOT_FOUND 103
#define WRONG_ARCHIVE 104
/* archive types */
struct { char arc,
lharc,
zip,
zoo,
sit,
cpio,
tar;
} types;
/* Structure used for Tar Lister */
struct {
char name[100],
mode[8],
uid[8],
gid[8],
size[12],
mtime[12],
chksum[8],
linkflag[1],
linkname[100],
rdev[6];
} tar;
/* the months of the year */
char *months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
/* totals variables for the archive stats */
long int tcomp, tuncomp;
float tcf;
int tfiles;
/* global vars */
struct EX_STRUCT { char infile[25], time_str[25], ext[4],
line[132], filename[30];
int file_num, error, add, line_num, type, length, line_len;
FILE *fp_in;
} ex;
/* Buffer used for Listing Routines, 132 + '\n' */
unsigned char b[133];
/* Functions */
void usage(), msdog(), init_list(), print_list(), move(), end_stats(),
error(), check_error();
int list_arc(), list_zip(), list_sit(), list_cpio(), convert8();
ULONG get_long(int);
/* main module */
main (argc, argv)
int argc;
char *argv[];
{
int i;
/* check to make sure we have the minimum number of arguments */
if (argc == 2) {
strcpy(ex.infile, argv[1]);
/* auto-detecter */
i = detect();
if (i == ADD_EXT) ex.add = TRUE;
else ex.add = FALSE;
if ((i == TRUE) || (i == ADD_EXT)) {
if (types.arc) check_error (list_arc());
if (types.cpio) check_error (list_cpio());
if (types.lharc) check_error (list_lharc());
if (types.sit) check_error (list_sit());
if (types.tar) check_error (list_tar());
if (types.zip) check_error (list_zip());
if (types.zoo) check_error (list_zoo());
}
/* manual search */
else {
i = list_arc();
if (! i) i = list_cpio();
if (! i) i = list_lharc();
if (! i) i = list_sit();
if (! i) i = list_tar();
if (! i) i = list_zip();
if (! i) i = list_zoo();
}
check_error(i);
}
else usage(0);
return (0);
}
/* prints an error messages, checks for Quiet mode */
void error(str)
char *str;
{
printf("\nError : %s\n\n", str);
exit(0);
}
void check_error(num)
int num;
{
switch (num)
{
case FILE_ERROR : error("File or Disk Error.");
case FALSE : error("Archive file not found.");
case WRONG_ARCHIVE : error("Archive header is invalid.");
}
}
/* print header for listing archives and reset stat values */
void init_list()
{
printf("\n");
switch (ex.type) {
case ARC : printf("Arc");
break;
case CPIO : printf("Cpio");
break;
case LHARC : printf("Lharc");
break;
case SIT : printf("Sit");
break;
case ZIP : printf("Zip");
break;
case TAR : printf("Tar");
break;
case ZOO : printf("Zoo");
break;
}
printf(" Archive: %s\n",ex.infile);
printf("\n---------------------------------------------------------------------------\n");
printf(" Original Compress Ratio Date Time Filename\n");
printf("---------------------------------------------------------------------------\n");
tcomp = tuncomp = tfiles = 0;
}
/* print entry in archive listing and update stats */
void print_list(n, u, c)
char *n;
long int u, c;
{
float f;
if ( (c==0) || (u==0) ) f = 0;
else f = (float) c / (float) u * 100.0;
tfiles ++;
tcomp += c;
tuncomp += u;
printf(" %-10ld%-10ld%-5.1f%% %-22s%s\n", u, c, f, ex.time_str, n);
}
/* prints the total statistics on the archive */
void end_stats()
{
float cf;
char temp[6];
if (tfiles == 1) strcpy(temp, "file");
else strcpy(temp, "files");
if (tuncomp == 0) cf = 0;
else cf = (float) tcomp / (float) tuncomp * 100.0;
printf("---------------------------------------------------------------------------\n");
printf(" %-10ld%-10ld%-5.1f%% %d %s processed.\n\n", tuncomp, tcomp, cf, tfiles, temp);
}
/* Converts from MS-DOG time and date to english format
and places the string into the global ex.time_str */
void msdog(time, date)
int time, date;
{
int i, yr, mo, day, hr, min, sec;
char day_str[3];
ex.error = FALSE;
yr = (date >> 9 & 0x7f) + 1980;
mo = date >> 5 & 0x0f;
day = date & 0x1f;
hr = time >> 11 & 0x1f;
min = time >> 5 & 0x3f;
sec = (time & 0x1f) * 2;
if ( (mo < 1) || (mo > 12) || (day < 1) || (day > 31) || (hr < 0) ||
(hr > 23) || (min < 0) || (min > 59) || (sec < 0) || (sec > 59) ) {
error("Corrupted archive!");
ex.error = TRUE;
return;
}
sprintf(ex.time_str, "%2d-%s-%d %02d:%02d:%02d", day, months[mo-1], yr, hr,
min, sec);
}
/* prints out the usage message and exits with the status number passed */
void usage(number)
int number;
{
printf("\nLister v1.01 - Copyright 1991 Baf! Technologies\n\n");
printf("Usage : Lister <filename>\n");
printf("\n");
exit(number);
}
/* lists an Arc file's contents */
int list_arc()
{
int ct, time, date, done;
ULONG uncomp, comp;
get_filename(".arc");
if ( (ex.fp_in = fopen(ex.filename, "rb")) == NULL) return(FILE_ERROR);
ct = read_buf(29);
/* check ARC signature */
if ( (b[0] != 0x1A) || (ct != 1)) {
fclose(ex.fp_in);
return(FALSE);
}
/* start listing */
ex.type = ARC;
init_list();
/* parse each header block until ARC signature check fails or EOF */
done= FALSE;
while ( ! done) {
comp = get_long(18);
uncomp = get_long(28);
date = b[20] * 256 + b[19];
time = b[22] * 256 + b[21];
msdog(time,date);
if (ex.error) break;
print_list(b+2, uncomp, comp);
fseek (ex.fp_in,comp,SEEK_CUR);
/* get next block and check */
ct = fread(b, 29, 1, ex.fp_in);
if ( (b[0] != 0x1A) || (ct != 1) || (b[1] == 0)) done = TRUE;
}
fclose(ex.fp_in);
end_stats();
return(TRUE);
}
/* lists a CPIO file's contents */
int list_cpio()
{
int ct, done, i;
ULONG uncomp, comp = 0, time;
struct tm *tm;
get_filename(".cpio");
in_open();
ct = fread(b, 76, 1, ex.fp_in);
/* check CPIO signature */
if ( (b[0] != 0x30) || (b[1] != 0x37) ||
(b[2] != 0x30) || (b[3] != 0x37) ||
(b[4] != 0x30) || (b[5] != 0x37) || (ct != 1)) {
fclose(ex.fp_in);
return(FALSE);
}
/* start listing */
ex.type = CPIO;
init_list();
/* parse each header block until CPIO signature check fails or EOF */
done = FALSE;
while ( ! done) {
comp = uncomp = convert8(b+70);
/* get Un*x stored time */
sscanf (b+48,"%11o",&time);
tm = localtime (&time);
sprintf (ex.time_str,"%02d-%s-19%d %02d:%02d:%02d",
tm->tm_mday,months[tm->tm_mon],tm->tm_year,tm->tm_hour,
tm->tm_min,tm->tm_sec);
/* get filename */
i = convert8(b+59);
ct = fread(b, (long) i, 1, ex.fp_in);
print_list(b, uncomp, comp);
fseek(ex.fp_in,uncomp,SEEK_CUR);
/* get next block and check */
ct = fread(b, 76, 1, ex.fp_in);
i = convert8(b+70);
if ( (b[0] != 0x30) || (b[1] != 0x37) ||
(b[2] != 0x30) || (b[3] != 0x37) ||
(b[4] != 0x30) || (b[5] != 0x37) || (ct != 1) || (i == 0) )
done = TRUE;
}
fclose(ex.fp_in);
end_stats();
return(TRUE);
}
/* lists an StuffIt file's contents */
int list_sit()
{
int ct, time, date, done, counter, max;
ULONG uncomp, comp, i;
get_filename(".sit");
in_open();
ct = fread(b, 22, 1, ex.fp_in);
/* check SIT signature and fread status */
if ( (b[0] != 0x53) || (b[1] != 0x49) || (b[2] != 0x54)
|| (b[3] != 0x21) || (ct != 1)) {
/* skip that part and read next section in case of MacBinary header */
ct = fread(b, 106, 1, ex.fp_in);
ct = fread(b, 22, 1, ex.fp_in);
if ( (b[0] != 0x53) || (b[1] != 0x49) || (b[2] != 0x54)
|| (b[3] != 0x21) || (ct != 1)) {
fclose(ex.fp_in);
return (FALSE);
}
}
/* read first header */
max = b[4] * 256 + b[5];
ct = fread(b, 122, 1, ex.fp_in);
counter = 1;
/* start listing */
ex.type = SIT;
init_list();
/* parse each header block until done */
done= FALSE;
while ( counter <= max) {
/* Get Long not used here due to different storage format of long int */
comp = b[92] * 16777216 + b[93] * 65536 + b[94] * 256 +
b[95] + b[96] * 167216 + b[97] * 6536 + b[98] * 256 + b[9];
uncomp = b[84] * 167216 + b[85] * 6536 + b[86] * 256 +
b[87] + b[8] * 167216 + b[89] * 6536 + b[90] * 256 + b[91];
/* print and get next record */
b[b[2] + 3] = '\0';
print_list(b + 3, uncomp, comp);
fseek(ex.fp_in, (comp-10), SEEK_CUR);
ct = fread(b, 122, 1, ex.fp_in);
if ( (ex.error) || (ct < 1) ) break;
counter ++;
}
fclose(ex.fp_in);
end_stats();
return(TRUE);
}
/* lists a Zip file's contents */
int list_zip()
{
int ct, time, date, done, extra;
long int uncomp, comp, i;
get_filename(".zip");
in_open();
ct = fread(b, 30, 1, ex.fp_in);
/* check ZIP signature and fread status */
if ( (b[0] != 0x50) || (b[1] != 0x4b) || (b[2] != 0x03)
|| (b[3] != 0x04) || (ct != 1)) {
fclose(ex.fp_in);
return (FALSE);
}
/* start listing */
ex.type = ZIP;
init_list();
/* parse each header block until done */
done= FALSE;
while ( ! done) {
comp = get_long(21);
uncomp = get_long(25);
date = b[13] * 256 + b[12];
time = b[11] * 256 + b[10];
msdog(time,date);
if (ex.error) break;
i = (long) ( b[26] + b[27] * 256);
extra = (long) ( b[28] + b[29] * 256);
/* get variable length filename */
fread(b, i, 1, ex.fp_in);
b[(int) i] = '\0';
print_list(b, uncomp, comp);
/* get variable length 'extra' bytes */
if (extra != 0) fread(b, extra, 1, ex.fp_in);
fseek(ex.fp_in, comp, SEEK_CUR);
ct = fread(b, 30, 1, ex.fp_in);
/* check ZIP signature */
if ( (b[0] != 0x50) || (b[1] != 0x4b) || (b[2] != 0x03)
|| (b[3] != 0x04) || (ct != 1)) done = TRUE;
}
fclose(ex.fp_in);
end_stats();
return(TRUE);
}
/* routine to convert octal stored ascii into numerical form */
int convert8(str)
char *str;
{
int x = 0;
x = (str[5] - 48) + (str[4] - 48) * 8 + (str[3] - 48) * 64 +
(str[2] - 48) * 512 + (str[1] - 48) * 4096 + (str[0] - 48) * 32768;
return (x);
}
/* Open filename with proper extension. will use 01 for 1 and 1 for 1 */
/* returns TRUE if opened ok. FALSE otherwise. */
int detect()
{
char temp[40];
int i;
/* Convert those four characters to lower case for comparisons */
for (i=0; i < strlen(ex.infile); ex.infile[i] = tolower(ex.infile[i]), i++);
strcpy (temp,ex.infile);
/* Check the file extension - return appropriate value if filetype */
/* Recognized. */
if (strstr (temp,".arc") != 0)
{
types.arc = TRUE;
return (TRUE);
}
if (strstr (temp,".lzh") != 0)
{
types.lharc = TRUE;
return (TRUE);
}
if (strstr (temp,".zip") != 0)
{
types.zip = TRUE;
return (TRUE);
}
if (strstr (temp,".zoo") != 0)
{
types.zoo = TRUE;
return (TRUE);
}
if (strstr (temp,".sit") != 0)
{
types.sit = TRUE;
return (TRUE);
}
if (strstr (temp,".cpio") != 0)
{
types.cpio = TRUE;
return (TRUE);
}
if (strstr (temp,".tar") != 0)
{
types.tar = TRUE;
return (TRUE);
}
/* See if file with .ARC extension can be opened. */
/* ARC_TYPE if it can be opened. */
sprintf(temp,"%s.arc",ex.infile);
if ((ex.fp_in = fopen (temp,"r")) != NULL)
{
fclose (ex.fp_in);
types.arc = TRUE;
}
/* See if file with .CPIO extension can be opened. */
/* CPIO_TYPE if it can be opened. */
sprintf(temp,"%s.cpio",ex.infile);
if ((ex.fp_in = fopen (temp,"r")) != NULL)
{
fclose (ex.fp_in);
types.cpio = TRUE;
}
/* See if file with .LZH extension can be opened. */
/* LZH_TYPE if it can be opened. */
sprintf(temp,"%s.lzh",ex.infile);
if ((ex.fp_in = fopen (temp,"r")) != NULL)
{
fclose (ex.fp_in);
types.lharc = TRUE;
}
/* See if file with .SIT extension can be opened. */
/* SIT_TYPE if it can be opened */
sprintf(temp,"%s.sit",ex.infile);
if ((ex.fp_in = fopen (temp,"r")) != NULL)
{
fclose (ex.fp_in);
types.sit = TRUE;
}
/* See if file with .TAR extension can be opened. */
/* TAR_TYPE if it can be opened. */
sprintf(temp,"%s.tar",ex.infile);
if ((ex.fp_in = fopen (temp,"r")) != NULL)
{
fclose (ex.fp_in);
types.tar = TRUE;
}
/* See if file with .ZIP extension can be opened. */
/* ZIP_TYPE if it can be opened */
sprintf(temp,"%s.zip",ex.infile);
if ((ex.fp_in = fopen (temp,"r")) != NULL)
{
fclose (ex.fp_in);
types.zip = TRUE;
}
/* See if file with .ZOO extension can be opened. Return FALSE if */
/* it can't be opened. ZOO_TYPE otherwise. */
sprintf(temp,"%s.zoo",ex.infile);
if ((ex.fp_in = fopen (temp,"r")) != NULL)
{
fclose (ex.fp_in);
types.zoo = TRUE;
}
if (types.arc || types.lharc || types.zoo || types.sit || types.cpio ||
types.tar || types.zip)
return (ADD_EXT);
else return (FALSE);
}
/* Used to put the filename to be opened in ex.filename */
int get_filename(type)
char *type;
{
if (! ex.add) strcpy (ex.filename,ex.infile);
else sprintf (ex.filename,"%s%s",ex.infile,type);
}
/* This will return an unsigned long integer calculated from the global */
/* buffer used for storage. Pass the high byte to this routine. */
ULONG get_long (temp)
int temp;
{
return ((ULONG) (b[temp] << 24) + (ULONG) (b[temp-1] << 16) +
(ULONG) (b[temp-2] << 8) + (ULONG) b[temp-3]);
}
/* Open the input file */
in_open ()
{
if ((ex.fp_in = fopen(ex.filename,"rb")) == NULL)
exit (1);
}
/* Read x bytes from ex.infile - Do error checking here too */
int read_buf (x)
int x;
{
int count;
count = fread(b,x,1,ex.fp_in);
if (count == 0)
exit (1);
else return (count);
}
/* List an Lharc file's contents */
int list_lharc(bool)
int bool;
{
int ct, time, date, done;
long int uncomp, comp;
unsigned char name[80];
get_filename (".lzh");
/* Open the file - Abort if Error occurs. */
in_open();
/* Read in my bytes */
ct = read_buf (22);
/* Determine if it is an Lharc file */
if ((strncmp(b+(sizeof (char) *2),"-l",2) != 0))
{
fclose (ex.fp_in);
return (WRONG_ARCHIVE);
}
/* Get file name stored in archive */
ct = fread(name,b[21]+2,1,ex.fp_in);
name[b[21]] = 0;
/* Print out header info to standard output */
ex.type = LHARC;
init_list();
done = FALSE;
while (!done)
{
/* Calculate Compressed, Uncompressed, Date,Time, and print it out */
comp = get_long(10);
uncomp = get_long(14);
date = b[18] * 256 + b[17];
time = b [16] * 256 + b[15];
msdog (time,date);
if (ex.error) break;
print_list(name,uncomp,comp);
/* Read in more bytes */
fseek(ex.fp_in,comp,SEEK_CUR);
ct = fread(b,22,1,ex.fp_in);
if ((strncmp(b+(sizeof (char) *2),"-l",2) != 0) || (ct < 1))
done = TRUE;
/* Read in file name again */
ct = fread(name,b[21]+2,1,ex.fp_in);
name[b[21]] = 0;
}
fclose (ex.fp_in);
/* Print ending stats */
end_stats();
return (TRUE);
}
/* List a Tar archive */
int list_tar()
{
long time,size;
int ct, date, done, i;
ULONG uncomp, comp;
struct tm *tm;
/* Get the filename with extension */
get_filename (".tar");
/* Open the file up. Abort if file not found or error occurs */
in_open();
/* Initialize the start of the list */
ex.type = TAR;
init_list();
/* Loop until there is a Zero in the first byte of the name */
while (get_header())
{
/* Read in the uncompressed size */
sscanf (tar.size,"%8o\n",&uncomp);
/* Read in date of stored file and put it in string */
sscanf (tar.mtime,"%12o",&time);
tm = localtime (&time);
sprintf (ex.time_str,"%02d-%s-19%d %02d:%02d:%02d",
tm->tm_mday,months[tm->tm_mon],tm->tm_year,tm->tm_hour,
tm->tm_min,tm->tm_sec);
/* Print out statistics read in */
print_list (tar.name,uncomp,uncomp);
/* Seek to next header in list */
fseek (ex.fp_in,512 - (sizeof tar),SEEK_CUR);
fseek (ex.fp_in,uncomp,SEEK_CUR);
if ( (uncomp != 0) && ((uncomp % 512) != 0) )
{
uncomp = 512 - uncomp % 512;
fseek (ex.fp_in,uncomp,SEEK_CUR);
}
}
/* Close the file and print the ending statistics. */
fclose (ex.fp_in);
end_stats();
return (TRUE);
}
/* Function to read the tar header structure into memory */
int get_header()
{
fread (tar.name,1,100,ex.fp_in);
if (tar.name[0] == 0)
return (FALSE);
fread (tar.mode,1,8,ex.fp_in);
fread (tar.uid,1,8,ex.fp_in);
fread (tar.gid,1,8,ex.fp_in);
fread (tar.size,1,12,ex.fp_in);
fread (tar.mtime,1,12,ex.fp_in);
fread (tar.chksum,1,8,ex.fp_in);
fread (tar.linkflag,1,1,ex.fp_in);
fread (tar.linkname,1,100,ex.fp_in);
fread (tar.rdev,1,6,ex.fp_in);
return (TRUE);
}
/* List a zoo archive */
int list_zoo()
{
int ct, time, date, done, i;
unsigned long int uncomp, comp, pntr, pntr2, temp;
get_filename (".zoo");
/* Open the file - Abort if Error occurs. */
in_open();
ct = read_buf (35);
temp = get_long(23);
/* Determine if it is a Zoo file */
if (temp != 0xFDC4A7DC)
{
fclose (ex.fp_in);
return (WRONG_ARCHIVE);
}
/* Pointer to next header */
pntr = get_long (27);
/* Read in the File Info */
fseek(ex.fp_in,pntr,SEEK_SET);
ct = read_buf(51);
/* Print out header info to standard output */
ex.type = ZOO;
init_list();
done = FALSE;
pntr = get_long (9);
while (!done)
{
/* Calculate Compressed, Uncompressed, Date,Time, and print it out */
comp = get_long(27);
uncomp = get_long(23);
date = b[15] * 256 + b[14];
time = b [17] * 256 + b[16];
msdog (time,date);
if (ex.error) break;
print_list(b+38,uncomp,comp);
fseek (ex.fp_in,pntr,SEEK_SET);
ct = read_buf (51);
pntr = get_long(9);
if (pntr == 0) break;
}
fclose (ex.fp_in);
/* Print ending stats */
end_stats();
return (TRUE);
}