/*
 * install.c
 * -force option
 *
 */

//#define HOBBES
//#define AMINET
//#define CICA
#define GAMES

#include <ctype.h>
#include <conio.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if 0
  FileAreaRecType = record
                      AreaName       : Str30;
                      AreaPath       : array[1..4] of DirStr;
                    end;

#endif

// don't pack structures
#pragma -a-
struct file_area_rec_type {
	unsigned char length;
	char area_name[30];
	struct {
		unsigned char length;
		char path[67];
	} area_path[4];
};

struct make_wild_record {
	char dummy1[0x321];
	int max_file_areas;
};

char letter;
int start_area;		/* xxx */

int
highest_area(void) {
	char buf[500];
	int fd;
	int i;
	struct file_area_rec_type area;
	int count = 0;

	if (-1 == (fd = open("filearea.dat", O_RDWR | O_BINARY))) {
		fprintf(stderr, "unable to open 'filearea.dat'\n");
		exit(1);
	}
	
//	printf("%d\n", sizeof(struct file_area_rec_type));

	for (;;) {
		i = read(fd, &area, sizeof(struct file_area_rec_type));
		if (i == 0)
			break;

		if (i != sizeof(struct file_area_rec_type)) {
			fprintf(stderr, "error reading file: (%d) %s\n",
				i, sys_errlist[errno]);
			exit(1);
		}
		++count;
		strncpy(buf, area.area_name, area.length);
		if (area.length == 0)
			continue;
		buf[area.length] = 0;
//		printf("area: `%s'\n", buf);
		for (i = 0; i < 4; i++) {
			if (area.area_path[i].length == 0)
				continue;
			strncpy(buf, area.area_path[i].path,
					area.area_path[i].length);
			buf[area.area_path[i].length] = 0;
//			printf("path %d: `%s'\n", i, buf);
		}
	}
	
	close(fd);
	
	return(count);
}

void
install_areas(void) {
	char vbuf[3000];
	char buf[500];
	int fd;
	int i;
	struct file_area_rec_type area;
	FILE *fh;
	char line[200];
	char description[100];
	char path[100];
	int current_areas;
	char *p;		

	if (-1 == (fd = open("filearea.dat", O_RDWR | O_BINARY))) {
		fprintf(stderr, "unable to open 'filearea.dat'\n");
		exit(1);
	}
	
	sprintf(buf, "%c:\\dirs.txt", letter);
	if (NULL == (fh = fopen(buf, "rt"))) {
		fprintf(stderr, "error opening cdrom directory list ``%s'': %s\n",
			buf, sys_errlist[errno]);
		exit(1);
	}
	
	setvbuf(fh, vbuf, _IOFBF, 2998);

	/* read current areas to end of file */
	current_areas = 0;
	while (1) {
		i = read(fd, &area, sizeof(struct file_area_rec_type));
		if (i == 0)
			break;

		if (i != sizeof(struct file_area_rec_type)) {
			fprintf(stderr, "error reading file: (%d) %s\n",
				i, sys_errlist[errno]);
			exit(1);
		}
		++current_areas;
	}

	memset(&area, 0, sizeof(struct file_area_rec_type));
	/* write null areas into any gap */
	while (current_areas < start_area - 1) {
		i = write(fd, &area, sizeof(struct file_area_rec_type));

		if (i != sizeof(struct file_area_rec_type)) {
			fprintf(stderr, "error writing '%s' file: (%d) %s\n",
				"filearea.dat", i, sys_errlist[errno]);
			fclose(fh);
			exit(1);
		}
		++current_areas;
	}
	
	lseek(fd, (long) (start_area - 1) * sizeof(struct file_area_rec_type),
		SEEK_SET);
	
	while (NULL != fgets(line, 199, fh)) {
		memset(&area, 0, sizeof(struct file_area_rec_type));
		
//		++current_areas;
		
		p = strtok(line, "\n\r\t ");
		if (!p) {
			fprintf(stderr, "line has no path:\n``%s''\n",
				line);
			exit(1);
		}
		
		strcpy(path, p);
		if (line[strlen(path) - 1] == '\\')
			line[strlen(path) - 1] = 0;

		p = line + strlen(path) + 1;
		while (isspace(*p))
			++p;
		if (!p) {
			fprintf(stderr, "line has no description:\n``%s''\n",
				line);
			exit(1);
		}
		strcpy(description, p);
		*(description + strlen(description) - 1) = 0;
		
		sprintf(buf, "%c:%s\\", letter, line);
		strcpy(area.area_path[0].path, buf);
		area.area_path[0].length = (unsigned char)strlen(buf);

		i = strlen(description);
		if (i > 30)
			i = 30;
		fprintf(stderr, "installing: %s\n", description);
		strncpy(area.area_name, description, i);
		area.length = (unsigned char)i;
		
		i = write(fd, &area, sizeof(struct file_area_rec_type));

		if (i != sizeof(struct file_area_rec_type)) {
			fprintf(stderr, "error writing '%s' file: (%d) %s\n",
				"filearea.dat", i, sys_errlist[errno]);
			fclose(fh);
			exit(1);
		}
	}
	
	fclose(fh);
	close(fd);
}

int
count_areas(void) {
	char vbuf[8000];
	char buf[500];
	char line[200];
	FILE *fh;
	int areas;

	sprintf(buf, "%c:\\dirs.txt", letter);
	if (NULL == (fh = fopen(buf, "rt"))) {
		fprintf(stderr, "error opening cdrom directory list ``%s'': %s\n",
			buf, sys_errlist[errno]);
		exit(1);
	}
	
	setvbuf(fh, vbuf, _IOFBF, 7998);

	areas = 0;
	while (NULL != fgets(line, 199, fh)) {
		++areas;
	}
	
	fclose(fh);
	
	return(areas);
}

void
build_batch(void) {
	char vbuf[3000];
	char vbuf2[3000];
	char buf[500];
	FILE *fh;
	FILE *output;
	char line[200];
	char path[100];
	int a;
	char *p;		
	
	fprintf(stderr, "Building batch file 'install2.bat'... ");

	sprintf(buf, "%c:\\dirs.txt", letter);
	if (NULL == (fh = fopen(buf, "rt"))) {
		fprintf(stderr, "error opening cdrom directory list ``%s'': %s\n",
			buf, sys_errlist[errno]);
		exit(1);
	}
	setvbuf(fh, vbuf, _IOFBF, 2998);
	
	if (NULL == (output = fopen("install2.bat", "wt"))) {
		fprintf(stderr, "error opening \"install2.bat\": %s\n",
			sys_errlist[errno]);
		exit(1);
	}
	setvbuf(output, vbuf2, _IOFBF, 2998);

	a = start_area;
	while (NULL != fgets(line, 199, fh)) {
		p = strtok(line, "\n\r\t ");
		if (!p) {
			fprintf(stderr, "line has no path:\n``%s''\n",
				line);
			exit(1);
		}
		
		strcpy(path, p);
		if (line[strlen(path) - 1] == '\\')
			line[strlen(path) - 1] = 0;

#ifdef CICA		
		fprintf(output,
			"wcfile /A:%d /S:%c:%s /D:%c:%s\\00_index.txt /U:\"CICA CDROM\" /P:1,12,25,80 /R\n",
		a, letter, path, letter, path);
#endif
#ifdef GAMES
		fprintf(output,
			"wcfile /A:%d /S:%c:%s /D:%c:%s\\wildcat.txt /U:\"GigaGames CDROM\" /P:1,12,15,80 /R\n",
		a, letter, path, letter, path);
#endif
#ifdef HOBBES		
		fprintf(output,
			"wcfile /A:%d /S:%c:%s /D:%c:%s\\wildcat.txt /U:\"Hobbes CDROM\" /P:1,12,15,80 /R\n",
		a, letter, path, letter, path);
#endif
		
#ifdef AMINET
		fprintf(output,
			"wcfile /A:%d /S:%c:%s /D:%c:%s\\wildcat.txt /U:\"Aminet CDROM\" /P:1,12,15,80 /R\n",
		a, letter, path, letter, path);
#endif
		++a;
	}
	
	fclose(fh);
	fclose(output);
	fprintf(stderr, "done.");
}


void
main(int argc, char *argv[]) {
	char buf[2000];
	char *p;
	int i;
	int fd;
	int highest_filearea;
	struct make_wild_record rec;
	int force = 0;
	int areas;
	
	if (0 == stricmp(argv[1], "-f")) {
		++force;
		fprintf(stderr, "Forcing overwrite of areas\n");
	}

	highest_filearea = highest_area();
	
	if (-1 == (fd = open("makewild.dat", O_RDWR | O_BINARY))) {
		fprintf(stderr, "unable to open 'makewild.dat'\n");
		exit(1);
	}
	
	i = read(fd, &rec, sizeof(struct make_wild_record));

	if (i != sizeof(struct make_wild_record)) {
		fprintf(stderr, "error reading '%s' file: (%d) %s\n",
			"makewild.dat", i, sys_errlist[errno]);
		exit(1);
	}
	
	lseek(fd, 0L, SEEK_SET);
	
	if (rec.max_file_areas != highest_filearea) {
		fprintf(stderr,
"Size of filearea.dat file area database (%d areas) and # areas\n",
			highest_filearea);
		fprintf(stderr, "configured (%d areas) don't match.\n",
			rec.max_file_areas);
		fprintf(stderr, "Set # of new areas with makewild.\n");
		exit(1);
	}

again:;
	fprintf(stderr, "What DOS drive letter is your CDROM drive?\n");
	gets(buf);
	p = buf;
	while (isspace(*p))
		++p;
	letter = *p;

	areas = count_areas();
	while (1) {
		fprintf(stderr, "What area should this CDROM's areas start at?\n");
		fprintf(stderr, "Your highest area # is %d.  This CDROM disc\n", 
			highest_filearea);
		fprintf(stderr, "has %d areas.  A good starting area is %d.\n", 
			areas, highest_filearea + 1);
		
		gets(buf);
		p = buf;
		while (isspace(*p))
			++p;
		
		start_area = atoi(p);
		if (! force && start_area <= highest_filearea) {
			fprintf(stderr, 
				"Sorry, area %d is already used.  Free areas start\n",
				start_area);
			fprintf(stderr, "with area %d.\n", highest_filearea + 1);
			continue;
		}
		
		break;
	}
	
	fprintf(stderr, 
		"The CDROM drive is DOS drive `%c'.  The new areas will run from\n",
		letter);
	fprintf(stderr, "area %d to area %d with your last area area %d.\n", 
		start_area, start_area + areas, highest_filearea);
	fprintf(stderr, "If this is correct type 'y'.\n");
	
	gets(buf);
	p = buf;
	while (isspace(*p))
		++p;
	
	if (toupper(*p) != 'Y')
		goto again;

	/* write new number of files into global files area */
	rec.max_file_areas = start_area + areas;
	
	i = write(fd, &rec, sizeof(struct make_wild_record));

	if (i != sizeof(struct make_wild_record)) {
		fprintf(stderr, "error writing '%s' file: (%d) %s\n",
			"makewild.dat", i, sys_errlist[errno]);
		exit(1);
	}
	
	/* write file descriptions into filearea.dat */
	install_areas();
	
	/* write batch file to add the files */
	
	build_batch();
	
	close(fd);
}
