/*******************************\
* INIT_LIBRARY.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 Libraries_Are_Active;
extern struct System System;
extern void *AllocRemember();
extern struct Remember *RememberKey;

int Init_Libraries();

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

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

status=Header_Segment();
if(status==FAILURE)
	{
	Libraries_Are_Active=0;
	return(SUCCESS);
	}

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

return(SUCCESS);
}

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

Libraries_Are_Active=0;

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

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

lh=System.Libraries_List;
FOREVER
	{
	(void)fscanf(fp,"%[^L]",trashcan);
	stat=fscanf(fp, "LIBRARY:%30[^\n]", lh->Name);
	if(stat!=1)
		{
		if(Libraries_Are_Active>0)
			{
			lh->Last_Library->Next_Library=NULL;
			break;
			}
		System.Libraries_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^L]",trashcan);

	stat=fscanf(fp, "LOCAT:%80[^\n]", lh->Location);
	if(stat!=1)
		{
		if(Libraries_Are_Active>0)
			{
			lh->Last_Library->Next_Library=NULL;
			break;
			}
		System.Libraries_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^U]",trashcan);

	stat=fscanf(fp, "UPLOAD:%hu",&lh->Upload_Low);
	if(stat!=1)
		{
		if(Libraries_Are_Active>0)
			{
			lh->Last_Library->Next_Library=NULL;
			break;
			}
		System.Libraries_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	stat=fscanf(fp, ",%hu",&lh->Upload_High);
	if(stat!=1)
		{
		if(Libraries_Are_Active>0)
			{
			lh->Last_Library->Next_Library=NULL;
			break;
			}
		System.Libraries_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^D]",trashcan);

	stat=fscanf(fp, "DOWNLOAD:%hu",&lh->Download_Low);
	if(stat!=1)
		{
		if(Libraries_Are_Active>0)
			{
			lh->Last_Library->Next_Library=NULL;
			break;
			}
		System.Libraries_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	stat=fscanf(fp, ",%hu",&lh->Download_High);
	if(stat!=1)
		{
		if(Libraries_Are_Active>0)
			{
			lh->Last_Library->Next_Library=NULL;
			break;
			}
		System.Libraries_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	(void)fscanf(fp,"%[^F]",trashcan);

	stat=fscanf(fp, "FILES:%hu", &lh->Maximum);
	if(stat!=1)
		{
		if(Libraries_Are_Active>0)
			{
			lh->Last_Library->Next_Library=NULL;
			break;
			}
		System.Libraries_List=NULL;
		fclose(fp);
		return(FAILURE);
		}
	++Libraries_Are_Active;
	lh->Next_Library=AllocRemember(
		&RememberKey,
		(long)sizeof(struct Library_Header),
		MEMF_CLEAR);
	if(lh->Next_Library==NULL)
		{
		ShutDown("No Memory for Library configuration");
		}
	lh->Next_Library->Last_Library=lh;
	lh=lh->Next_Library;
	}

fclose(fp);
return(SUCCESS);
}

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

lh=System.Libraries_List;

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

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

		/* LOAD THE ACTUAL FILE */
	stat=read(fp,ld,sizeof(struct Library_Data)*lh->Maximum);
	if(stat!=sizeof(struct Library_Data)*lh->Maximum)
		{
		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_File=0;
		lh->Latest_Time=0L;
		}
	else
		{
		lh->Highest_File=count;
		scan=lh->Start_of_Data;
		scan+=(count-1);
		lh->Latest_Time=scan->Time;
		}

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

	} while(lh!=NULL);

return(SUCCESS);
}
