/* 
 * MULTI-server for FBB
 * PA3FWM@PI8DAZ.#TWE.NLD.EU / pa3fwm@amsat.org
 * 19981221-24, 19991218, 19991223
 * 
 * Adapted for FBB 7.02 new file-tree
 * PA3AES@PI8WFL.#NH1.NLD.EU / pa3aes@amsat.org
 * 20001001
 *
 * Distribution: Gnu Public License, version 2
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <fbb_conf.h>

char bbs_call[80];
char syst_dir[80];
char mail_in[80];


int read_fbbconf(void);
char *back2slash (char *);
int mail_error(char *);

#define MAXDEST 1000

char *sender,*myname;


int main(int argc,char **argv)
{
   FILE *fin;
   FILE *fout;
   FILE *fdest;
   char buf[160];
   char line1[82];
   char subject[82];
   char *p,*q;
   int i,j,l;
   char dest[MAXDEST][80];
   char hiddendest[MAXDEST][80];
   int ndest=0;
   int nhiddendest=0;
   int pos;


   if (read_fbbconf()) return 1;
   
   if (argc!=2) {
      puts("MULTI server for xfbb\nversion oct 1, 2000\nby: pa3fwm@amsat.org, adapted for FBB 7.02 by pa3aes@amsat.org");
      return 1;
   }
   fin=fopen(argv[1],"r");
   if (!fin) return 1;

/* read and parse first line of input: SP MULTI < PA3XXX */
   fgets(line1,80,fin);
   p=line1;
   while (isgraph(*p)) p++; while (isspace(*p)) p++;
   myname = p;
   while (isgraph(*p)) p++; 
   if (*p) *p++=0;
   while (isspace(*p)) p++;
   while (isgraph(*p)) p++; while (isspace(*p)) p++;
   sender = p;
   while (isgraph(*p)) p++; 
   *p=0;

/* read second line of input: subject */
   fgets(subject,80,fin);
   if ((p=strchr(subject,'\r'))) *p=0;
   if ((p=strchr(subject,'\n'))) *p=0;

/* skip R: lines */
   do {
      pos=ftell(fin);
      fgets(buf,160,fin);
   } while (buf[0]=='R' && buf[1]==':');
   fseek(fin,pos,SEEK_SET);

   if (!strcmp(myname,"MULTI")) {    /* mail addressed to MULTI ? Then destinations are in mail itself */
      do {  /* skip empty lines and lines like From: etc. */
         fgets(buf,160,fin);
         p=buf;
         while (isspace(*p)) p++;
      } while (*p==0 || strchr(p,':'));
      fdest=fin;
   } else {                          /* else: destinations must be read from a file */
      strcpy(buf,syst_dir);
      strcat(buf,"/multi.cfg/");
      strcat(buf,myname);
      strcat(buf,".usr");
      fdest=fopen(back2slash(buf),"r");
      if (!fdest) return 1;
      fgets(buf,160,fdest);
   }

/* read destinations */
   while (memcmp(buf,"---",3) && memcmp(buf,"/EX",2) && !feof(fdest)) {
      int hide=0;
      p=buf;
      while (*p) *p++=toupper(*p);
      p=buf;
      while (isspace(*p)) p++;
      if (*p && p[1]==' ') {    /* skip single letter at beginning of line, for compatibility with LA6CU's MULTI server for DOS; if it's 'h', hide this callsign */
         if (p[0]=='h' || p[0]=='H') hide=1;
         p+=2;
         while (isspace(*p)) p++;
      }
      while (*p) {
         q=p;
         while (*p!=',' && *p!=0 && *p!='\r' && *p!='\n') p++;
         while (isspace(p[-1])) p--;
         if (!hide) {
            if (!(fdest!=fin && !strncmp(sender,q,strlen(sender)) && !isalnum(q[strlen(sender)]))   /* if destinations are read from file, don't send copy to sender even if (s)he is in destination list */
                && p-q<80 && ndest<MAXDEST) {
               memcpy(dest[ndest],q,p-q);
               dest[ndest][p-q]=0;
               ndest++;
            }
         } else {
            if (!(fdest!=fin && !strncmp(sender,q,strlen(sender)) && !isalnum(q[strlen(sender)]))   /* if destinations are read from file, don't send copy to sender even if (s)he is in destination list */
                && p-q<80 && nhiddendest<MAXDEST) {
               memcpy(hiddendest[nhiddendest],q,p-q);
               hiddendest[nhiddendest][p-q]=0;
               nhiddendest++;
            }
         }
         while (*p==',' || isspace(*p)) p++;
      }
      fgets(buf,160,fdest);
   }

   if (fdest==fin && memcmp(buf,"---",3)) return mail_error("No \"----\" separator found after list of addresses\n");
   if (ndest+nhiddendest==0) return mail_error("Zero destinations, so no mail sent.\n");

   if (fin!=fdest) fclose(fdest);

   pos=ftell(fin);

/* open mail.in */
   fout=fopen(back2slash(mail_in),"a");
   if (!fout) return 1;

/* write multiple copies of mail */
   for (j=0;j<ndest+nhiddendest;j++) {
      fseek(fin,pos,SEEK_SET);
      fprintf(fout,"#\r\n");
      if (j<ndest) fprintf(fout,"SP %s < %s\r\n",dest[j],sender);
      else fprintf(fout,"SP %s < %s\r\n",hiddendest[j-ndest],sender);
      fprintf(fout,"%s\r\n",subject);
      fprintf(fout,"------------------------------------------------------------------------------\r\n"
                    "Message via %s %s-server, with copies to:\r\n ",bbs_call,myname);
      l=0;
      for (i=0;i<ndest;i++) {
         if (l>2 && l+strlen(dest[i])>75) {
            fprintf(fout,",\r\n  %s",dest[i]);
            l=2+strlen(dest[i]);
         } else {
            fprintf(fout,", %s"+(i==0),dest[i]);
            l+=2+strlen(dest[i]);
         }
      }
      if (l>2) fprintf(fout,"\r\n");
      fprintf(fout,"------------------------------------------------------------------------------\r\n");
      while ((l=fread(buf,1,128,fin))) fwrite(buf,1,l,fout);
   }

/* write ack for sender */
   fprintf(fout,"#\r\n");
   fprintf(fout,"SP %s < %s\r\n",sender,bbs_call);
   fprintf(fout,"%s@%s: message sent\r\n",myname,bbs_call);
   fprintf(fout,"Your message (subject: %s) has been sent to:\r\n ",subject);
   l=0;
   for (i=0;i<ndest;i++) {
      if (l>2 && l+strlen(dest[i])>75) {
         fprintf(fout,",\r\n  %s",dest[i]);
         l=2+strlen(dest[i]);
      } else {
         fprintf(fout,", %s"+(i==0),dest[i]);
         l+=2+strlen(dest[i]);
      }
   }
   if (l>2) fprintf(fout,"\r\n");
   if (nhiddendest>0) {
      fprintf(fout,"Furthermore, hidden copies have been sent to:\r\n ");
      l=0;
      for (i=0;i<nhiddendest;i++) {
         if (l>2 && l+strlen(hiddendest[i])>75) {
            fprintf(fout,",\r\n  %s",hiddendest[i]);
            l=2+strlen(hiddendest[i]);
         } else {
            fprintf(fout,", %s"+(i==0),hiddendest[i]);
            l+=2+strlen(hiddendest[i]);
         }
      }
      if (l>2) fprintf(fout,"\r\n");
   }
   fprintf(fout,"/EX\r\n");

   fclose(fout);
   fclose(fin);

   return 0;
}



int mail_error(char *str)
{
   FILE *fout;
   fout=fopen(back2slash(mail_in),"a");
   if (!fout) return 1;
   fprintf(fout,"#\r\n");
   fprintf(fout,"SP %s < %s\r\n",sender,bbs_call);
   fprintf(fout,"%s@%s: message sent\r\n",myname,bbs_call);
   fprintf(fout,"%s",str);
   fclose(fout);
   return 0;
}



char *back2slash (char *str)         /* copied from F6FBB's example REQDIR server */
{
	static char buf[256];
	char *ptr = buf;
	int nb = 0;

	if ((strlen (str) > 2) && (str[1] == ':'))
		str += 2;

	while (*str)
	{
		if (*str == '\\')
			*ptr = '/';
		else if (isupper (*str))
			*ptr = tolower (*str);
		else
			*ptr = *str;
		++ptr;
		++str;
		if (++nb == 255)
			break;
	}
	*ptr = '\0';
	return (buf);
}

int read_fbbconf(void)          /* copied and slightly modified from F6FBB's example REQDIR server */
{				/* made compatible with 7.02g file-tree by pa3aes@amsat.org*/

char *ptr;

if (read_fbb_conf (NULL) > 0)
    exit (1);
    
ptr = find_fbb_conf("call",0);
if (ptr == NULL)
    exit (1);
    
sscanf (ptr, "%[0-9A-Za-z]", bbs_call);        /* Callsign */


    
ptr = find_fbb_conf("sdir",0);
if (ptr == NULL)
    exit (1);

sscanf (ptr, "%s", syst_dir);	/* Server dir */


ptr = find_fbb_conf("impo",0);
if (ptr == NULL)
    exit (1);
    
sscanf (ptr, "%s", mail_in);        /* Mail in file */
    
    
   return 0;
}

