/*******************************\
* INIT_BOARDS.C			*
* (C)1986-87, Patrick E. Hughes	*
\*******************************/

#include <exec/types.h>
#include <exec/memory.h>
#include <stdio.h>
#include <fcntl.h>
#include "system.h"
#include "Defines.h"

extern int Boards_Are_Active;
extern struct System System;
extern void *AllocRemember();
extern struct Remember *RememberKey;

int Init_Boards();

static	int Header_Segment();
static	int Data_Segment();

/***********************/
int Init_Boards()
{
int status;

status=Header_Segment();
if(status==FAILURE)
	{		/* non-fatal condition, no boards exist */
	Boards_Are_Active=0;
	return(SUCCESS);
	}

status=Data_Segment();
if(status==FAILURE)
	{		/* decidedly fatal, corrupt or missing files */
	ShutDown("Cannot load a Board's data");
	}

return(SUCCESS);
}

/***********************/
static int Header_Segment()
{
FILE *fp;
int stat;
struct Board_Header *lh;
char trashcan[132];

Boards_Are_Active=0;

fp=fopen("s:Tag_Boards","r");
if(fp==NULL) { return(FAILURE); }

System.Boards_List=AllocRemember(
	&RememberKey,
	(long)sizeof(struct Board_Header),
	MEMF_CLEAR);
if(System.Boards_List==NULL){
	ShutDown("No Memory for Board configuration");
}

lh=System.Boards_List;
FOREVER
	{
	(void)fscanf(fp,"%[^B]",trashcan);
	stat=fscanf(fp, "BOARD:%30[^\n]", lh->Name);
	if(stat!=1)
		{
		if(Boards_Are_Active>0)
			{
			lh->Last_Board->Next_Board=NULL;
			break;
			}
		System.Boards_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^L]",trashcan);

	stat=fscanf(fp, "LOCAT:%80[^\n]", lh->Location);
	if(stat!=1)
		{
		if(Boards_Are_Active>0)
			{
			lh->Last_Board->Next_Board=NULL;
			break;
			}
		System.Boards_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^R]",trashcan);

	stat=fscanf(fp, "READ:%hu",&lh->Read_Low);
	if(stat!=1)
		{
		if(Boards_Are_Active>0)
			{
			lh->Last_Board->Next_Board=NULL;
			break;
			}
		System.Boards_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	stat=fscanf(fp, ",%hu",&lh->Read_High);
	if(stat!=1)
		{
		if(Boards_Are_Active>0)
			{
			lh->Last_Board->Next_Board=NULL;
			break;
			}
		System.Boards_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^W]",trashcan);

	stat=fscanf(fp, "WRITE:%hu",&lh->Write_Low);
	if(stat!=1)
		{
		if(Boards_Are_Active>0)
			{
			lh->Last_Board->Next_Board=NULL;
			break;
			}
		System.Boards_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	stat=fscanf(fp, ",%hu",&lh->Write_High);
	if(stat!=1)
		{
		if(Boards_Are_Active>0)
			{
			lh->Last_Board->Next_Board=NULL;
			break;
			}
		System.Boards_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^P]",trashcan);

	stat=fscanf(fp, "POSTS:%hu", &lh->Maximum);
	if(stat!=1)
		{
		if(Boards_Are_Active>0)
			{
			lh->Last_Board->Next_Board=NULL;
			break;
			}
		System.Boards_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	++Boards_Are_Active;
	lh->Next_Board=AllocRemember(
		&RememberKey,
		(long)sizeof(struct Board_Header),
		MEMF_CLEAR);
	if(lh->Next_Library==NULL)
		{
		ShutDown("No Memory for Board configuration");
		}
	lh->Next_Library->Last_Board=lh;
	lh=lh->Next_Board;
	}

fclose(fp);
return(SUCCESS);
}

/***********************/
static int Data_Segment()
{
int fp;
struct Board_Header *lh;
struct Board_Data *ld, *scan;
int stat;
long count;
char final[133];

lh=System.Boards_List;

do
	{
	strcpy(final,lh->Location);
	strcat(final,"Board.Keys");
	fp=open(final,O_RDONLY);
	if(fp==NULL){ return(FAILURE); }

		/* GET MEMORY ACCORDING TO DATA SIZE */
	ld=AllocRemember(
		&RememberKey,
		(long)sizeof(struct Board_Data)*lh->Maximum,
		MEMF_CLEAR);
	if(ld==NULL) { return(FAILURE); }

		/* LOAD THE ACTUAL FILE */
	stat=read(fp,ld,sizeof(struct Board_Data)*lh->Maximum);
	if(stat==0)
		{
		close(fp);
		return(FAILURE);
		}
	close(fp);

		/* SEARCH FOR HIGHEST MESSAGE */
	lh->Start_of_Data=ld;
	for(count=lh->Maximum-1;count>=0;--count)
		{
		scan=lh->Start_of_Data;
		scan+=count;
		if(scan->Time!=0L) { break; }
		}

		/* SET INFORMATION INTO HEADER */
	++count;
	if(count==0)
		{
		lh->Highest_Post=0;
		lh->Latest_Time=0L;
		}
	else
		{
		lh->Highest_Post=count;
		scan=lh->Start_of_Data;
		scan+=(count-1);
		lh->Latest_Time=scan->Time;
		}

		/* MOVE ON TO NEXT BOARD IN LINE */
	lh=lh->Next_Board;

	} while(lh!=NULL);

return(SUCCESS);
}
