/*
 *	Copyright (C) 1990  TGV, Incorporated
 *
 *	Code to manipulate the BBOARD "last-read" dates
 */
#define GETUID()	((getgid() << 16) + getuid())
#include <fab.h>
#include <nam.h>

static Do_Bboard_Read_Date();
static New_Extension();
static Fully_Qualified_Filename();
static BBoard_Dates_File();


/*
 *	Get the BBoard last read date
 */
Get_Bboard_Read_Date(Mail_File_Name, Message_File_Last_ModifiedP)
char *Mail_File_Name;
int *Message_File_Last_ModifiedP;
{
	int fd;
	int Our_UID;
	int i;
	struct {long int Uid; long int Date;} Buffer;
	char Filename[128];

	/*
	 *	Assume bboard file NEVER read
	 */
	*Message_File_Last_ModifiedP = 0;
	/*
	 *	Try to access the "New-Style" Bboard date file
	 */
	Do_Bboard_Read_Date(Mail_File_Name, Message_File_Last_ModifiedP, 0);
	if (*Message_File_Last_ModifiedP != 0) return;
	/*
	 *	Open the ".DAT" file and find the "Old-Style" Last Modified date
	 */
	New_Extension(Mail_File_Name, Filename, "dat");
	fd = open(Filename,0,0,"shr=get","shr=put","shr=upd");
	Our_UID = GETUID();
	if (fd > 0) {
		/*
		 *	Read through the ".DAT" file for our UID
		 */
		while(read(fd,&Buffer,sizeof(Buffer)) == sizeof(Buffer)) {
			if (Buffer.Uid == Our_UID) {
				*Message_File_Last_ModifiedP = Buffer.Date;
				break;
			}
		}
		close(fd);
	}
}


/*
 *	Set the BBoard last read date
 */
Set_Bboard_Read_Date(Mail_File_Name, Message_File_Last_Modified)
char *Mail_File_Name;
int Message_File_Last_Modified;
{
	/*
	 *	Set the BBOARD read date the "New-Style" way
	 */
	Do_Bboard_Read_Date(Mail_File_Name, &Message_File_Last_Modified, 1);
}


/*
 *	Read the user's bboard dates file and either return
 *	the read date for the indicated BBOARD file, or set
 *	its new read date
 */
static Do_Bboard_Read_Date(Mail_File_Name, DateP, Update_Date)
char *Mail_File_Name;
int *DateP;
int Update_Date;
{
	register char *cp, *cp1;
	int fd;
	int Offset_To_Buffer = 0;
	int Offset;
	char Buffer[1024];
	char True_Mail_File_Name[256];
	int True_Mail_File_Name_Size;
	int i,j;

	/*
	 *	Open the BBoard dates file
	 */
	BBoard_Dates_File(Buffer);
	fd = open(Buffer, Update_Date ? 2 : 0, "shr=get", "shr=put", "shr=upd");
	/*
	 *	If its not there, create it
	 */
	if (fd < 0) {
		if (!Update_Date) return;
		fd = creat(Buffer, 0600);
		if (fd < 0) return;
	}
	/*
	 *	Get the true mail file name
	 */
	Fully_Qualified_Filename(Mail_File_Name, True_Mail_File_Name);
	True_Mail_File_Name_Size = strlen(True_Mail_File_Name);
	/*
	 *	Read through it and find the offset
	 *	to the date
	 */
	Offset = 0;
	Offset_To_Buffer = 0;
	while(1) {
		/*
		 *	Fill the buffer as much as we can
		 */
		i = read(fd, Buffer+Offset, sizeof(Buffer) - Offset);
		if (i <= 0) break;
		i += Offset;
		/*
		 *	Scan the lines in the buffer, looking
		 *	for the one that describes our BBOARD
		 */
		Offset = 0;
		cp = Buffer;
		while(1) {
			/*
			 *	See how many bytes we have left in the
			 *	buffer and make sure there are enough
			 *	to hold the record we are looking for
			 */
			j = (i-Offset);
			if (j <= (True_Mail_File_Name_Size + (1+8))) break;
			/*
			 *	Scan for end of line
			 */
			cp1 = cp;
			while(--j >= 0) {
				if (*cp1++ == '\n') {cp1--; break;}
			}
			if (*cp1 != '\n') break;
			/*
			 *	Is it big enough for this name?
			 */
			if ((cp1-cp) == (True_Mail_File_Name_Size + (1+8))) {
				char *Saved_cp = cp;
				char *Saved_cp1 = cp1;

				/*
				 *	Yes: Does the filename match?
				 */
				cp1 = True_Mail_File_Name;
				while(*cp1)
					if (*cp++ != *cp1++) {cp1--; break;};
				if ((*cp1 == 0) &&
				    (*cp++ == ' ')) {
					/*
					 *	Yes: Retrieve the date?
					 */
					if (Update_Date == 0) {
						/*
						 *	Yes: Decode the Hex date value
						 */
						*DateP = 0;
						for(j = 0; j < 8; j++) {
							if ((*cp >= '0') &&
							    (*cp <= '9')) {
								*DateP = (*DateP << 4) |
									    *cp++ - '0';
							} else {
								*DateP = (*DateP << 4) |
									    *cp++ - 'A' + 10;
							}
						}
						/*
						 *	Done
						 */
						close(fd);
						return;
					}
					/*
					 *	Store the new date:
					 *	  Seek to where this line starts
					 *	  and then fall into the "Append" code
					 */
					lseek(fd, Offset_To_Buffer + Offset, 0);
					goto Append_Date_Line;
				}
				/*
				 *	Restore cp/cp1 and try the next line
				 */
				cp = Saved_cp;
				cp1 = Saved_cp1;
			}
			/*
			 *	Skip this line
			 */
			j = cp1 - cp + 1;
			Offset += j;
			cp += j;
		}
		Offset_To_Buffer += Offset;
		if (Offset < i) {
			bcopy(Buffer + Offset, Buffer, i - Offset);
			Offset = i - Offset;
		} else {
			Offset = 0;
		}
	}
	/*
	 *	Not Found: Do we need to append a new Date line?
	 */
	if (Update_Date) {
		/*
		 *	Yes: Append the new Date line
		 */
Append_Date_Line:
		/*
		 *	Bboard file name
		 */
		cp = True_Mail_File_Name;
		cp1 = Buffer;
		while(*cp) *cp1++ = *cp++;
		/*
		 *	Followed by <SPACE>
		 */
		*cp1++ = ' ';
		/*
		 *	Followed by the Date (in HEX)
		 */
		i = *DateP;
		for(j = 0; j < 8; j++) {
			*cp1 = (i & 0xf0000000) >> 28;
			*cp1 += (*cp1 >= 10) ? 'A'-10 : '0';
			cp1++;
			i <<= 4;
		}
		/*
		 *	End-Of-Line
		 */
		*cp1++ = '\n';
		/*
		 *	Write it
		 */
		write(fd, Buffer, cp1 - Buffer);
	}
	/*
	 *	Done
	 */
	close(fd);
	return;
}

/*
 *	Get the fully qualified name of the
 *	mail file
 */
static Fully_Qualified_Filename(Input, Output)
char *Input;
char *Output;
{
	struct FAB Fab;
	struct NAM Nam;
	char Es_String[256];

	/*
	 *	Fill out the FAB
	 */
	bzero(&Fab, sizeof(Fab));
	Fab.fab$b_bid = FAB$C_BID;
	Fab.fab$b_bln = sizeof(Fab);
	Fab.fab$l_fna = Input;
	Fab.fab$b_fns = strlen(Input);
	Fab.fab$l_nam = &Nam;
	/*
	 *	Fill out the NAM
	 */
	bzero(&Nam,sizeof(Nam));
	Nam.nam$b_bid = NAM$C_BID;
	Nam.nam$b_bln = sizeof(Nam);
	Nam.nam$l_rsa = Output;
	Nam.nam$b_rss = 255;
	Nam.nam$l_esa = Es_String;
	Nam.nam$b_ess = 255;
	/*
	 *	Parse the filename
	 */
	if (SYS$PARSE(&Fab) & 1) {
		/*
		 *	Now search for the file
		 */
		if (SYS$SEARCH(&Fab) & 1) {
			/*
			 *	Terminate the resultant
			 *	string killing the version #
			 */
			*(char *)Nam.nam$l_ver = 0;
			/*
			 *	Done
			 */
			return;
		}
	}
	/*
	 *	Failed, use the filename as is
	 */
	strcpy(Output, Input);
}


/*
 *	Append new extension to given filename
 */
static New_Extension(File_Name,Dest,Extension)
char *File_Name;
char *Dest;
char *Extension;
{
	register char *cp,*cp1;

	/*
	 *	Copy to output buffer and massage there
	 */
	cp = File_Name;
	cp1 = Dest;
	while((*cp1++ = *cp++) != 0) ;
	cp1--;
	/*
	 *	Back over any version numbers
	 */
	while(cp1 > Dest) {
		if ((cp1[-1] < '0') || (cp1[-1] > '9')) {
			if ((cp1[-1] == '.') ||
			    (cp1[-1] == ';')) {
				*--cp1 = 0;
				break;
			}
			while(*cp1) cp1++;
			break;
		}
		cp1--;
	}
	/*
	 *	Change the extension
	 */
	while(cp1 > Dest) {
		if (cp1[-1] == '.') break;
		cp1--;
	}
	cp = Extension;
	while((*cp1++ = *cp++) != 0);
}


/*
 *	Get the name of the BBoard dates file
 */
static BBoard_Dates_File(Buffer)
char *Buffer;
{
	strcpy(Buffer, "SYS$LOGIN:BBOARD.DATES");
}
