/*
 * mailutil v1.2 for Citadel/UX
 * see copyright.doc for copyright information
 */

#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <pwd.h>
#include <setjmp.h>
#include "citadel.h"

struct config config;

struct passwd *getpwuid();
struct passwd *getpwnam();
char *getenv();
int raflag;
long atol();
long lseek();

char *months[12] = {
	"Jan","Feb","Mar","Apr","May","Jun",
	"Jul","Aug","Sep","Oct","Nov","Dec"   };

int hash(str)
char str[]; {
	int h = 0;
	int i;

	for (i=0; i<strlen(str); ++i) h=h+((i+1)*tolower(str[i]));
	return(h);
	}

long finduser(file,name)
int file;
char *name; {
	FILE *fp;
	int c=0;
	int uh,fh;
	long pp;
	
	uh=hash(name);
	fp=fopen("hashtab","r");
	while(fread((char *)&fh,sizeof(int),1,fp)>0) {
		if (uh==fh) {
			pp=(long)c * (long)sizeof(struct usersupp);
			lseek(file,pp,0);
			return(pp);
			}
		++c;
		}
	fclose(fp);
	return(-1L);
	}
	
msgform(spos)
long spos;
	{
	struct tm *tm;
	int width,a,b,c,d,e,real,old,mtype,mform;
	char aaa[100],bbb[100],ttm[3];
	FILE *fp;
	long now;

	width=80;
	fp=fopen("./msgmain","rb");
	if (fp==NULL) {
			printf("No msgmain file.\n");
			return(1); }
	strcpy(aaa,""); old=255;
	c=1; /* c is the current pos */
	fseek(fp,spos,0);
	e=getc(fp);
	if (e!=255) goto END;
	printf("\n ");
	mtype=getc(fp); mform=getc(fp);
	if (mtype==MES_ANON) printf("   ****\n");
	goto BONFGM;
A:	old=real; a=getc(fp); real=a;
	if (a==0) goto END;
	if (a<0) goto END;
	
	if ( ((a==13)||(a==10)) && (old!=13) && (old!=10) ) a=32;
	if ( ((old==13)||(old==10)) && (isspace(real)) ) {
						printf("\n"); c=1; }
	if (a>126) goto A;

	if (a>32) {
	if ( ((strlen(aaa)+c)>(width-5)) && (strlen(aaa)>(width-5)) )
		{ printf("\n%s",aaa); c=strlen(aaa); aaa[0]=0; }
	 b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
	if (a==32) { 	if ((strlen(aaa)+c)>(width-5)) { 
							printf("\n");
							c=1;
							}
			printf("%s ",aaa); ++c; c=c+strlen(aaa);
			strcpy(aaa,""); goto A; }
	if ((a==13)||(a==10)) {
				printf("%s\n",aaa); c=1;
				strcpy(aaa,""); goto A; }
	goto A;

END:	fclose(fp);
	printf("\n");
	return(0);

A1:	if (mform!=1) goto A;
	while (a=getc(fp), a>0) {
		putc(a,stdout);
		if (a==13) putc(10,stdout);
		}
	goto END;

BONFGM:	b=getc(fp);
	if (b=='M') { printf("\n "); goto A1; }
	fpgetfield(fp,bbb);
	if (mtype==MES_ANON) goto SKIPFGM;
	if (b=='A') printf("from %s ",bbb);
	if (b=='O') printf("in %s> ",bbb);
	if ( (b=='N') && (strcmp(bbb,config.c_nodename)) ) printf("@%s ",bbb);
	if (b=='R') printf("to %s ",bbb);
	if (b=='T') { now=atol(bbb);
		tm=(struct tm *)localtime(&now);
		sprintf(ttm,"%2d",tm->tm_min);
		if (ttm[0]==32) ttm[0]=48;
		printf("%s %2d, %4d %2d:%2s ",
			months[tm->tm_mon],
			tm->tm_mday,(1900+tm->tm_year),
			tm->tm_hour,ttm); }
SKIPFGM:
	goto BONFGM;
}

fpgetfield(fp,string)
FILE *fp;
char string[];
{
int a,b,c;
strcpy(string,"");
a=0;
GFXYZAF:
	b=getc(fp);
	if (b<1) { string[a]=0; return(0); }
	string[a]=b;
	++a;
	if (b!=0) goto GFXYZAF;
}

main(argc,argv)
int argc;
char *argv[]; {
char uname[30];
char aaa[100];
struct usersupp usersupp;
struct msgmain msgmain;
int a,b,c,file;
FILE *fp;
long upos;

	get_config();

	fp=fopen("MMstructure","r");
	fread((char *)&msgmain,sizeof(struct msgmain),1,fp);
	fclose(fp);

	raflag = ( (argc>1) ? 1 : 0);
	if (argc==1) {
		printf("\rEnter username: ");
		gets(uname);
		}
	else {
		uname[0]=0;
		for (a=2; a<=argc; ++a) {
			strcat(uname,argv[a-1]);
			if (a!=argc) strcat(uname," ");
			}
		}

	file=open("usersupp",O_RDONLY);
	upos=finduser(file,uname);
	if (upos==(-1)) {
		printf("No such user.\n");
		close(file);
		exit(0);
		}
	close(file);
	
A:	for (a=0; a<(27-(MAILSLOTS/2)); ++a) printf("\n");
	file=open("usersupp",O_RDONLY);
	lseek(file,upos,0);
	read(file,&usersupp,sizeof(struct usersupp));
	close(file);
	for (a=0; a<MAILSLOTS; ++a) {
		if (usersupp.mailnum[a] < msgmain.MMlowest) {
			usersupp.mailnum[a] = 0L;
			usersupp.mailpos[a] = 0L;
			}
		}
	strcpy(uname,usersupp.fullname);
	if (!raflag) {
		printf("Mailbox for user: %s\n",uname);
		for (a=0; a<=MAILSLOTS/2; ++a) {
			printf("%2d. %7ld %-7ld                     ",
				a,usersupp.mailnum[a],usersupp.mailpos[a]);
			b=(a+(MAILSLOTS/2)+1); if (b<MAILSLOTS)
				printf("%2d. %7ld %-7ld",
				b,usersupp.mailnum[b],usersupp.mailpos[b]);
			printf("\n");
			}
		printf("\nd=delete i=insert r=read q=quit\n");
		printf("Enter command: ");
		gets(aaa);
		a=tolower(aaa[0]);
		}
	else a='r';
	switch(a) {
	 case 'q':	exit(0);
			break;
	 case 'd':	printf("Enter slot number to delete (-1 to abort): ");
			gets(aaa);
			a=atol(aaa);
			if ((a<0)||(a>=MAILSLOTS)) break;
			file=open("usersupp",O_RDWR);
			lseek(file,upos,0);
			read(file,&usersupp,sizeof(struct usersupp));
			for (b=a; b>=1; --b) {
				usersupp.mailnum[b]=usersupp.mailnum[b-1];	
				usersupp.mailpos[b]=usersupp.mailpos[b-1];
				}
			usersupp.mailnum[0]=0L;
			usersupp.mailpos[0]=0L;
			lseek(file,upos,0);
			write(file,&usersupp,sizeof(struct usersupp));
			close(file);
			break;
	case 'i':	file=open("usersupp",O_RDWR);
			lseek(file,upos,0);
			read(file,&usersupp,sizeof(struct usersupp));
			for (a=0; a<(MAILSLOTS-1); ++a) {
				usersupp.mailnum[a]=usersupp.mailnum[a+1];
				usersupp.mailpos[a]=usersupp.mailpos[a+1];
				}
			printf("Enter msgnum: ");
			gets(aaa);
			usersupp.mailnum[MAILSLOTS-1]=atol(aaa);
			printf("Enter msgpos: ");
			gets(aaa);
			usersupp.mailpos[MAILSLOTS-1]=atol(aaa);
			lseek(file,upos,0);
			write(file,&usersupp,sizeof(struct usersupp));
			close(file);
	case 'r':	file=open("usersupp",O_RDONLY);
			lseek(file,upos,0);
			read(file,&usersupp,sizeof(struct usersupp));
			close(file);
			for (a=0; a<MAILSLOTS; ++a) {
				if (usersupp.mailnum[a] < msgmain.MMlowest) {
					usersupp.mailnum[a] = 0L;
					usersupp.mailpos[a] = 0L;
					}
				}
			if (!raflag) {
				printf("Slot number (return for all): ");
				gets(aaa);
				}
			else aaa[0]=0;
			if (aaa[0]==0) {
				for (a=0; a<MAILSLOTS; ++a)
					if (usersupp.mailnum[a]>0L) {
						msgform(usersupp.mailpos[a]);
						if (!raflag) gets(aaa);
						}
				if (raflag) exit(0);
				}
			else {
				a=atol(aaa);
			if ((a>=0)&&(a<MAILSLOTS)) msgform(usersupp.mailpos[a]);
				gets(aaa);
				}
	default:	break;
	 }
	goto A;

}

