/*
  
Title:	MsgEd
  
File:	readmail.c
  
Author:	Jim Nutt
	
Copr:	1987 by Jim Nutt
  
Description:
	
	handles all disk i/o for msged
	
Revision History:
  
	0.00	12 December 1987
	
Support Files:
  
	msged.h
	dos.h
  
*/

#include "msged.h"
#ifdef __MSC__
#include <sys\types.h>
#include <fcntl.h>
#endif
#include <sys\stat.h>
#ifdef __TURBOC__
#include <fcntl.h>
#include <dir.h>
#endif

static void checkrecvd(MSG * m);

int     scanmail(char *mp)

{
#ifdef __ZTC__
	struct FIND *fileinfo = NULL;
#endif
#ifdef __TURBOC__
	struct ffblk fileinfo;
#endif
#ifdef __MSC__
	struct find_t fileinfo;
#endif
	char    path[PATHLEN];
	int     cnt = 0;
	int     msgnum;
	FILE   *fp = NULL;
	unsigned int status;

	if (messages != NULL)
		free(messages);

        checkmem(messages = (char *) calloc(2, 1));     /* allocate for 1
							 * message */
	messages[1] = FALSE;
	arealist[area].last = 1;
	strcpy(path, mp);
	strcat(path, "\\*.msg");

#ifdef __ZTC__
	fileinfo = findfirst(path, 0);
	while (fileinfo != NULL) {
		msgnum = atoi(fileinfo->name);
                if ((msgnum != 0) && (fileinfo->size >= (long) sizeof(MSGHEADER))) {
			cnt++;
			if (msgnum > arealist[area].last) {
                                checkmem(messages = realloc(messages,msgnum + 1));
				arealist[area].last++;
				while (arealist[area].last < msgnum)
					messages[arealist[area].last++] = FALSE;
			}
			messages[msgnum] = TRUE;
		}
		fileinfo = findnext();
	}
#else
#ifdef __TURBOC__
	status = findfirst(path, &fileinfo, 0);
	while (status == 0) {
		msgnum = atoi(fileinfo.ff_name);
                if ((msgnum != 0) && (fileinfo.ff_fsize >= (long) sizeof(MSGHEADER))) {
			cnt++;
			if (msgnum > arealist[area].last) {
				checkmem(messages = realloc(messages,
							    msgnum + 1));
				arealist[area].last++;
				while (arealist[area].last < msgnum)
					messages[arealist[area].last++] = FALSE;
			}
			messages[msgnum] = TRUE;
		}
		status = findnext(&fileinfo);
	}
#else
#ifdef __MSC__
	status = _dos_findfirst(path, 0, &fileinfo);
	while (status == 0) {
		msgnum = atoi(fileinfo.name);
                if ((msgnum != 0) && (fileinfo.size >= (long) sizeof(MSGHEADER))) {
			cnt++;
			if (msgnum > arealist[area].last) {
				checkmem(messages = realloc(messages,
							    msgnum + 1));
				arealist[area].last++;
				while (arealist[area].last < msgnum)
					messages[arealist[area].last++] = FALSE;
			}
			messages[msgnum] = TRUE;
		}
		status = _dos_findnext(&fileinfo);
	}
#else
#error scanmail() requires zortech, quick or turbo c to compile
#endif
#endif
#endif

	strcpy(path, mp);
	strcat(path, "\\lastread");
	fp = fopen(path, "rb");
	if (fp != NULL) {
                fread(&arealist[area].lastread, 2, 1, fp);
                if (fread(&arealist[area].current,2,1,fp) != 1)
                        arealist[area].current = arealist[area].lastread;
		fclose(fp);
	}
	else {
		fp = fopen(path, "wb");
		fputc(0, fp);
                fputc(0, fp);
                fputc(0, fp);
                fputc(0, fp);
		fclose(fp);
	}

	for (arealist[area].first = 1;
	     (arealist[area].first < arealist[area].last) &&
	     !messages[arealist[area].first];
	     arealist[area].first++)
		;

	if (!messages[arealist[area].lastread])
		arealist[area].lastread = arealist[area].last;

        if ((arealist[area].current) == 0)
		arealist[area].current = arealist[area].lastread =
			arealist[area].last;

	if (cnt == 0)
		arealist[area].current = arealist[area].lastread =
                        arealist[area].first = arealist[area].last = 0;

        arealist[area].current = min(arealist[area].current, arealist[area].last);
        arealist[area].lastread= min(arealist[area].lastread,arealist[area].last);

	return (cnt);
}

int     readmsg(MSG * m, int n)
{
	struct stat buf;
	char    path[PATHLEN];
	char   *text = NULL;
	int     fd = 0;
        unsigned int     s;
	LINE   *t = NULL;
	int     i = 0, j = 0, flag = 0;
	char    dst[30], src[30],ddom[30], sdom[30];

	if (!messages[n])
		return (FALSE);

	sprintf(path, "%s\\%d.MSG", arealist[area].path, n);

        stat(path, &buf);

        if ((long) buf.st_size < (long) sizeof(MSGHEADER)) {
                messages[n] = FALSE;
                return(FALSE);
        }

        if ((s = (unsigned int)(buf.st_size - sizeof(MSGHEADER))) < 0) {
                messages[n] = FALSE;
                return(FALSE);
        }

        if ((fd = open(path, 0)) == -1) {
                messages[n] = FALSE;
                return (FALSE);
        }

	if (m->to.domain != NULL)
		free(m->to.domain);

	if (m->from.domain != NULL)
		free(m->from.domain);

        m->msgnum = n;

        if (s > 0) {
                if ((text = (char *) calloc(1, (s + 1))) == NULL) {
                        close(fd);
                        messages[n] = FALSE;
                        return(FALSE);
                }
        }
        else
                text = NULL;

        read(fd, (char *) &(m->header), (int) sizeof(MSGHEADER));

        if ((m->from.net = m->header.orig_net) < -1) {
                free(text);
                close(fd);
                messages[n] = FALSE;
                return(FALSE);
        }
        if ((m->from.node = m->header.orig) < -1) {
                free(text);
                close(fd);
                messages[n] = FALSE;
                return(FALSE);
        }
        if ((m->to.net = m->header.dest_net) < -1) {
                free(text);
                close(fd);
                messages[n] = FALSE;
                return(FALSE);
        }
        if ((m->to.node = m->header.dest) < -1) {
                free(text);
                close(fd);
                messages[n] = FALSE;
                return(FALSE);
        }

        if (m->header.recvd && !arealist[area].netmail && readthread) {
                free(text);
                close(fd);
                messages[n] = FALSE;
                return(FALSE);
        }

        if (text == NULL) {
                msgbuf.first = msgbuf.last = NULL;
                close(fd);
                return(TRUE);
        }

        i = read(fd, text, s);

        if ((t = msgbuf.first = buffer(&text)) == NULL) {
                if (text != NULL)
                        free(text);
                close(fd);
                return(TRUE);
	}

	free(text);
	close(fd);

	checkrecvd(m);

	*dst = '\0';
	*src = '\0';

	i = j = 0;
	m->from.point = m->to.point = 0;
	m->from.zone = m->to.zone = thisnode.zone;
	memset(path,0,PATHLEN);
	memset(ddom,0,30);
	memset(sdom,0,30);
	memset(dst,0,30);
	memset(src,0,30);

	while (t != NULL) {

		msgbuf.last = t;

		flag = 0;

		if ((t->text != NULL) && (*(t->text) == '\01')) {
			flag += sscanf(t->text, "\01FMPT %i\n", &(i));
			flag += sscanf(t->text, "\01TOPT %i\n", &(j));
			flag += sscanf(t->text, "\01INTL %s %s\n", dst, src);
			flag += sscanf(t->text, "\01DOMAIN %s %s %s %s\n",ddom,dst,sdom,src);
			flag += sscanf(t->text, "\01---%s", path);
		}

		if ((seenbys != YES) && (strncmp("SEEN-BY: ", t->text, 8) == 0))
			flag = TRUE;

		if (flag && !kludgelines) {
			LINE   *t2;

                        if (t->prev != NULL)
                                t->prev->next = t->next;
                        else
                                msgbuf.first = t->next;

                        if (t->next) {
                                msgbuf.last = t->next;
                                t->next->prev = t->prev;
                        }
                        else
                                msgbuf.last = t->prev;

                        msgbuf.first->prev = NULL;

                        free(t->text);

			t2 = t;
			t = t->next;
			free(t2);
		}
		else
			t = t->next;
	}

	if (*src != '\0')
		m->from = parsenode(src);

	if (*dst != '\0')
		m->to = parsenode(dst);

	if (i)
		m->from.point = i;

	if (j)
		m->to.point = j;

	m->to.domain = NULL;
	m->from.domain = NULL;

        if (*ddom != '\0') {
                m->to.domain = strlwr(strdup(ddom));
                assert(m->to.domain);
        }
	    	
        if (*sdom != '\0') {
                m->from.domain = strlwr(strdup(sdom));
                assert(m->from.domain);
        }

	return (TRUE);
}

MSGHEADER readheader(int n)

{
	char    path[PATHLEN];
	int     fd = 0;
	MSGHEADER m;

	if (!messages[n]) {
		m.dest = -1;
		return (m);
	}

	sprintf(path, "%s\\%d.MSG", arealist[area].path, n);

	if ((fd = open(path, 0)) == -1) {
                m.dest = -1;
		return (m);
	}

	read(fd, (char *) &m, sizeof(MSGHEADER));

	close(fd);
	return (m);
}

char *readtext(int n)

{
	char    path[PATHLEN];
	int     fd = 0;
	char   *t;
	struct stat buf;
	unsigned int s;
	MSGHEADER tmp;
	
	if (!messages[n]) 
		return (NULL);

	sprintf(path, "%s\\%d.MSG", arealist[area].path, n);

	if (stat(path, &buf) == -1)
		return(NULL);

	if ((s = (unsigned int)(buf.st_size - sizeof(MSGHEADER))) < 1)
		return(NULL);

	if ((fd = open(path, 0)) == -1) 
		return (NULL);

        if (read(fd, (char *) &tmp, sizeof(MSGHEADER)) == -1) {
                close(fd);
                return(NULL);
        }

        if ((t = (char *) calloc(1,(s + 145))) == NULL) {
                close(fd);
                return(NULL);
        }

	strncpy(t,tmp.subj,72);
	strncat(t,tmp.from,36);
	strncat(t,tmp.to,36);

	if (read(fd, (t + strlen(t)), s) == -1) {
		if (t) 
                        free(t);
                close(fd);
		return(NULL);
	}

	close(fd);
        t = (char *) realloc(t,strlen(t)+1);
	return (t);
}

static void checkrecvd(MSG * m)
{
        char   *s, *t;

	if (m->header.recvd)
		return;

        s = strlwr(strdup(username));
        assert(s);
        t = (char *) calloc(1, sizeof(m->header.to) + 1);
        memset(t,0,sizeof(t));
        memcpy(t,m->header.to,sizeof(m->header.to) + 1);
        strlwr(t);

        if ((memcmp(s, t, strlen(s)) == 0) || (!arealist[area].netmail && readthread)) {
                m->header.recvd = 1;
                writeheader(m->header, m->msgnum);
	}
	free(s);
	free(t);
}
