/* EMACS_MODES: !lnumb !fill */
#define NAME "fsend"
#define VERSION "2.1"

#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include <stdlib.h>
#include <time.h>
#include <dir.h>


#define nl() printf("\n");
#define OK 0
#define ERROR 1
#define FATAL 2

#define EXTERNAL        0x0006
#define EMAIL           0x0002

#define STX     '\2'        /* End Of Text */
#define LF	'\012'        /* Form Feed (New Page) */
#define FF	'\014'        /* Form Feed (New Page) */

#define MAXP 256                /* Maximum pN.net ie. p1.net ... pN.net */
#define ERRLOG  "fsend.err"  /* File to log errors to */

#define MAXSYS  (unsigned short)65535  /* highest node number for WWIVnet */

#define MAXLINE 128         /* Maximum length of a line in a message */
#define MAXELM  30          /* Maximum number of elements for temp. array */
#define MSGLEN  32000       /* Max number of bytes for a single message */

#define CONFIGFLE "fsend.cfg" /* Config file for this program */
#define CONFITEMS 3           /* Number of items in the config file */

FILE *fe;
char array[MAXELM][MAXLINE];   /* temp array */
int error; /* error flag/counter */
int append; /* append to p1.net flag 1=yes, 0=create p1.net-pN.net */
char message[MSGLEN];

/* From WWIVnet Doc */
typedef struct {
        unsigned short  tosys,         /* destination system */
                        touser,        /* destination user */
                        fromsys,       /* originating system */
                        fromuser;      /* originating user */
        unsigned short  main_type,     /* main message type */
                        minor_type;    /* minor message type */
        unsigned short  list_len;      /* # of entries in system list */
        unsigned long   daten;         /* date/time sent */
        unsigned long   length;        /* # of bytes of msg after header */
        unsigned short  method;        /* method of compression */
} net_header_rec;

#define POSTER "FSEND"

unsigned short tosys;         /* destination system */
unsigned short fromsys;       /* originating system */
unsigned short minor_type;    /* minor message type */
unsigned long  length;        /* # of bytes of msg after header */

net_header_rec nh;

void main(int argc, char *argv[])
{
	int i,j,p;
	long T;
	char s[MAXLINE];
	error=0;
	colour(4);
	printf(" [%s:%s] Copyright (c) 1991 Andrew Gaunt. ",NAME,VERSION);
	colour(0);
	nl();
	colour(3);
	printf("Compiled %s %s",__DATE__,__TIME__);
	colour(0);
	nl();

	if (argc<7){
		printf("usage: tonode fromnode minor_type file data_dir mailto [n]\n",argv[0]);
		exit(0);
	}

	/* Open the error log file */
	if ( (fe=fopen(ERRLOG,"w")) == NULL ){
		colour(6);
		printf("FATAL: can't open error log %s for writing.",ERRLOG);
		colour(0);
		nl();
		myexit(FATAL);
	}

	/* Allow user to specify p?.net file, greater than p0.net */
	p=0;
	if (argc==10){
		p=atoi(argv[9])-1;
		if(p<0){
			p=1;
		}
	}		
	if(create_netfile(argv[1],argv[2],argv[3],argv[4],argv[5],argv[6],p) != OK){
		myexit(FATAL);
	}
        nl();
        colour(4);
	printf(" [%s:%s] Complete ",NAME,VERSION);
	colour(0);
	nl();
        exit(0);
}

create_netfile(tonode,fromnode,minor,filepath,data,mailto,p)
char tonode[];
char fromnode[];
char minor[];
char filepath[];
char data[];
char mailto[];
int p;
{
	FILE *fi,*fo;
	struct date datep;
	struct time timep;
	unsigned long num_read;
	char outfile[MAXPATH];
	char s[MAXLINE];
	char title[MAXFILE+MAXEXT+30];
	char post_date[30];
	char drive[MAXDRIVE];
	char dir[MAXDIR];
	char file[MAXFILE];
	char ext[MAXEXT];
	long T;
	int i;
	int msgnum;
	long tot_bytes;


	fnsplit(filepath,drive,dir,file,ext);
	/* Pad the title with spaces - need 40 chars */
	sprintf(title,"%-8s%4s%-28s",file,ext,"                           ");
/* 	printf("Title [%s].\n",title); /* DEBUG */
/* 	printf("[%s]\n",POSTER); /* DEBUG */

	/* Create next for output p?.net */
	i = p;
	do {
		i++;
		sprintf(outfile,"%sP%d.NET",data,i);
		fo = fopen(outfile, "rb");
		if (fo == NULL) {
			fclose(fo);
			nl();
			fo = fopen(outfile, "ab");
			if (fo == NULL){
				sprintf(s,"Can't create %s.\n",outfile);
				errlog(s);
				return(FATAL);
			}
			break;
		} else {
			fclose(fo);
		}
	} while (i < MAXP);
	colour(3);
	printf("Appending/creating %s.\n",outfile);
	colour(0);

	/* Open the input file, specified in the configuration file */
	if ( (fi=fopen(filepath,"rb")) == NULL ){
		sprintf(s,"Can't read input file %s.\n",filepath);
		errlog(s);
		return(FATAL);
	}

	tot_bytes=0;
	msgnum=0;
	while( (num_read=read(fileno(fi),(char *)message,MSGLEN))!=0){
		tot_bytes+=(long)num_read;
		msgnum++;
		time(&T);
		strcpy(s,ctime(&T));
		/* Don't let post_date contain a newline */
		for(i=0;i<strlen(s);i++){
			if (s[i]==LF){
				post_date[i]='\0';
			}
			else{
				post_date[i]=s[i];
			}
		}	
	
		gettime(&timep);
		getdate(&datep);

		tosys=(unsigned short)atoi(tonode);
		fromsys=(unsigned short)atoi(fromnode);
		minor_type=(unsigned short)atoi(minor);

		nh.tosys=tosys;
		nh.touser=1;
		nh.fromsys=fromsys;
		nh.fromuser=1;
		nh.main_type=EXTERNAL;
		nh.minor_type=minor_type;
		nh.list_len=0;
		nh.daten=dostounix(&datep, &timep);
		nh.length=num_read+strlen(title)+1+strlen(POSTER)+1+strlen(post_date)+2+1;
		nh.method=0;
		colour(1);
		print_header();
		colour(0);
		fflush(fo);
	 	write(fileno(fo),(void *)&nh,sizeof(net_header_rec));
		write(fileno(fo),(void *)title,strlen(title));
		write(fileno(fo),'\0',sizeof(char));
		write(fileno(fo),(void *)POSTER,strlen(POSTER));
		fflush(fo);
		fprintf(fo,"\r");
		fflush(fo);
	 	write(fileno(fo),(void *)post_date,strlen(post_date));
		fflush(fo);
		fprintf(fo,"\r\n");
		fflush(fo);
		fputc(STX,fo);
		colour(2);
		printf("#%04d ",msgnum);
                colour(1);
		for(i=0;i<num_read;i++){
			fputc(message[i],fo);
		}
		printf("%d bytes of data, ",i);
		printf("%s",post_date);
		colour(0);
		nl();
	}

        /* SEND SysOp (user #1 of tosys) EMAIL */

	if((short)atoi(mailto)>0){
          sprintf(message,"A file has been sent to this system via FSEND\r\n\
          Filename: [%12s]\r\n\
         File size:  %ld bytes\r\n\
         Main type:  %d, External\r\n\
        Minor type:  %d\r\n\r\n\r\n** FSEND version %s, compiled %s %s - By Quantum, 1@6300\r\n",\
          title,tot_bytes,EXTERNAL,minor_type,VERSION,__DATE__,__TIME__);

          nh.tosys=tosys;
          nh.touser=(short)atoi(mailto);
          nh.fromsys=fromsys;
          nh.fromuser=0;
          nh.main_type=EMAIL;
          nh.minor_type=minor_type;
          nh.list_len=0;
          nh.daten=dostounix(&datep, &timep);
          nh.length=strlen(message)+strlen(title)+1+strlen(POSTER)+1+strlen(post_date)+2;
          nh.method=0;
          fflush(fo);
          write(fileno(fo),(void *)&nh,sizeof(net_header_rec));
          write(fileno(fo),(void *)title,strlen(title));
          write(fileno(fo),'\0',sizeof(char));
          write(fileno(fo),(void *)POSTER,strlen(POSTER));
          fflush(fo);
          fprintf(fo,"\r");
          fflush(fo);
          write(fileno(fo),(void *)post_date,strlen(post_date));
          fflush(fo);
          fprintf(fo,"\r\n%s",message);
          fflush(fo);
          colour(1);
          print_header();
          printf("mail to #1@%-05d, ",nh.tosys);
          printf("%s",post_date);
          colour(0);
	}
	fclose(fi);
	fclose(fo);
	return(OK);
}


int init_array()
{
	int i;
	i=0;
	for (i=1;i<MAXELM;i++){
		strcpy(array[i],"");
		i++;
	}
	return(OK);
}



int fgetline(s,max,fp)
char s[];
int max;
FILE *fp;
{
	int i,c;
	i=0;
	while (1){
		if ( (c=fgetc(fp)) == EOF){
			return(EOF);
		}
		if (c=='\r' || c=='\n' || i>=max || c=='\t' ){
			break;
		}
		s[i]=c;
		i++;
	}
	s[i]='\0';
	return(i);
}


/* Read from fi up to max number of items into array */
/* and return number of items read */
/*  int readin_array(fi,max)
FILE *fi;
int max;
{
	int i;
	char s[MAXLINE];

	init_array();
	i=0;
	while ( i<max ){
		if ( fgetline(array[i],MAXLINE,fi) == NULL){
			break;
		}



 		if ( (strcmp(array[i],"")) == NULL){
			break;
		}

		i++;
		if ( i >= MAXELM ){
			sprintf(s,"Array full: %d lines\n",MAXELM);
			errlog(s);
			return(FATAL);
		}
	}
	return(i);
}
*/

errlog(s)
char *s[];
{

	fprintf(fe,"ERROR: %s",s);
	error++;
	return(OK);
}

myexit(r)
int r;
{
	char s[MAXLINE];

	/* close the error log */
	fclose(fe);
	if ( (fe=fopen(ERRLOG,"r")) == NULL ){
		printf("FATAL: can't open error log %s for reading.\n",ERRLOG);
		exit(FATAL);
	}
	colour(6);
	printf("%d ERROR(S) have occuured:\n",error);
	colour(2);
	while ( fgets(s,MAXLINE-1,fe)  ){
		printf("\t%s",s);
	}			
	colour(0);
	fclose(fe);
	exit(r);
	return(OK);
}

print_header()
{
	printf("To %u, ",nh.tosys);
	printf("type %u-%u, ",nh.main_type,nh.minor_type);
/* 	printf("time=%u, msglen=%u",nh.daten,nh.length); */
	return(OK);
}

/*
print_header()
{
	printf("WWIVnet Header Data:\n");
	printf("\tTo system   : %u\n",nh.tosys);
	printf("\tFrom system : %u\n",nh.fromsys);
	printf("\tTo user     : %u\n",nh.touser);
	printf("\tFrom user   : %u\n",nh.fromuser);
	printf("\tMain type   : %u\n",nh.main_type);
	printf("\tMinor type  : %u\n",nh.minor_type);
	printf("\tList length : %u\n",nh.list_len);
	printf("\tTime stamp  : %u\n",nh.daten);
	printf("\tTotal len.  : %u\n",nh.length);
	printf("\tFrom: %s\n",POSTER);
	return(OK);
}
*/

colour(code)
short code;
{
  if (code<=7 && code>=0 ){
    printf("%c%d",'\003',code);
  }
  return(OK);
}

