/*************************************************
    ScanLZH : Scan files in LHA's archive
    
    Copyright © 1994 Manolis S Pappas.
    All rights reserved.
    
*************************************************/

#include <stdio.h>
#include <string.h>

#define BUFSZ 4096
#define OVER  4096
#define VERSION "1.1"
#define CLI_VERSION "$VER: ScanLZH v1.1"

char name[256];
unsigned char buf[BUFSZ + OVER];
unsigned char id[5] = {'-', 'l', 'h', '?', '-'};

void exthdr(unsigned char *header)
{
	int i;

#if 0
	while ((i = header[-2] + header[-1] * 256) != 0) {
#else
	/* limits extended header upto 255 bytes */
	while (header[-1] == 0 && (i = header[-2]) != 0) {
#endif
		if (header[0] == 1) {
			strncpy(name, &header[1], i - 3);
		}
		header += i;
	}
}

void main(int argc, char *argv[])
{
	FILE *f;
	unsigned long a, b, old_b, pos;
	int  c, s, i, left, comp_max;
	unsigned char *p, *comp_max_pos, *header;

	strcpy(name, argv[1]);
	f = fopen(name, "rb");
	if (f == NULL) {
		strcat(name, ".lzh");
		f = fopen(name, "rb");
		if (f == NULL) {
			printf("ScanLZH v%s\n",VERSION);
			printf("Copyright (©) 1994-95, The Xperts Group Inc.\n");
                        printf("All Rights Reserved Worldwide.\n");
                        printf("Author: Manolis S Pappas.\n\n");
			fprintf(stderr, "Usage : %s bad-lzh [ >info-file ]\n",argv[0]);
			return;
		}
	}
	left = fread(buf, 1, BUFSZ + OVER, f);
	pos = 0;
	s = old_b = 0;
	do {
		comp_max = (left < BUFSZ) ? left : BUFSZ;
		comp_max_pos = buf + comp_max + 2;
		for (p = buf + 2; p < comp_max_pos; p++) {
			s = 0;
			do {
				c = p[s];
				switch (s) {
				case 0:
				case 1:
				case 2:
				case 4:
					if (c == id[s]) {
						s++;
					} else {
						s = 0;
					}
					break;
				case 3:
					if (c >= '0' && c <= '9' || c == 'd') {
						s++;
					} else {
						s = 0;
					}
					break;
				case 5:
					memset(name, 0, sizeof(name));
					header = p - 2;
					a = pos + (header - buf);
					b = header[10];
					b = b * 256 + header[9];
					b = b * 256 + header[8];
					b = b * 256 + header[7] + a;
					switch (header[20]) {
					case 0:
					case 1:
						i = header[0] + 2;
						b += i;
						strncpy(name, &header[22], header[21]);
						if (header[20] == 1) {
							exthdr(header + i);
						}
						break;
					case 2:
						b += header[1] * 256 + header[0];
						exthdr(header + 26);
						break;
					default:
						s = 0;
					}
					if (s) {
						if (old_b != a) printf("=================\n");
						printf("%08lx %08lx %s\n", a, b, name);
						old_b = b;
						s = 0;
					}
					break;
				}
			} while (s);
		}
		memcpy(buf, buf + comp_max, OVER);
		pos += comp_max;
		left -= comp_max;
	} while (left += fread(buf + OVER, 1, BUFSZ, f));
	fclose(f);
}

void do_nothing()
{
        printf("%s",CLI_VERSION);
}
