/*
 * qfax.c - Renaissoft Qfax 1.0, an e-mail to fax gateway for use
 * with Efax 0.6.
 * (c) 1994 Robert LeBlanc and Renaissoft
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "qfax.h"

void read_mail(Fax *f)
{
/*
   Read the piped input on stdin from the mailer and parse it, extracting
   useful information from the headers and copying anything else to a
   simple ASCII file which will later be converted into the fax document.

   In the fax.rc file, a "fax comment start" and "fax comment end" header
   can be specified (e.g. X-Fax-Comment-Start:, X-Fax-Comment-End:).  If
   these headers are found at the beginning of the body of the message, any
   text between them is taken to be a comment for the fax cover page.

   The output filename is of the form:

             FAXQUEUE/fax.user.timestamp

	     e.g. /usr/spool/fax/sendq/fax.tom.26Aug230715

   "user" in this context ("tom") is the local username of the sender, and
   "timestamp" is the time and date the message was received by Qfax.
   This is done to ensure that on a multiuser system all fax files have a
   unique identification, since there does exist the possibility that more
   than one user might want to send out a fax at the same time.
*/

  FILE *ifp;
  FILE *of;
  int i, j;
  char tmp[LINELEN];
  char line[LINELEN];
  char header[LINELEN];
  char outfile[LONGLEN];
  enum { headers, commentin, commentout, copy } stage = headers;

  of = stdout;
  ifp = stdin;
  strcpy(line, getsline(ifp));
  while (!feof(ifp)) {
    strcpy(header, "");
    switch (stage) {

    /*
       Look for "official" mail headers, stopping after finding the
       first blank line.  Munge pertinent information from useful
       fields, ignore all others.
    */

    case headers:
      sscanf(line, "%s", header);
      if (strcasecmp(header, "From:") == 0) {
	strcpy(tmp, getfield(line));
	i = 0;
	j = 0;
	while (tmp[i++] != '(');
	while (tmp[i++] != ')')
	  f->fperson.fullname[j++] = tmp[i-1];
	f->fperson.fullname[j] = '\0';
	sscanf(tmp, "%s", f->fperson.username);
      } else if (strcasecmp(header, "Subject:") == 0) {
	strcpy(f->subject, getfield(line));
      } else if (strcasecmp(header, "To:") == 0) {
	strcpy(tmp, getfield(line));
	i = 0;
	j = 0;
	while (tmp[i++] != '@')
	  f->tperson.alias[j++] = tmp[i-1];
	f->tperson.alias[j] = '\0';
	j = 0;
	while (tmp[i++] != '.')
	  f->tcompany.alias[j++] = tmp[i-1];
	f->tcompany.alias[j] = '\0';
      } else if (strcasecmp(header, "Date:") == 0) {
	strcpy(f->date, getfield(line));
      } else if (strcmp(line, "") == 0) {
	stage = commentin;
      }
      break;

    /*
       Look for a user-supplied "fax cover page comment start" header,
       which must be in the first line of the body of the message to
       be recognized.  If it's found, enter "comment mode", otherwise
       assume everything to follow is message text.
    */

    case commentin:
      strcpy(f->tstamp, time_stamp());
      sprintf(outfile, "%s/fax.%s.%s", FAXQUEUE, f->fperson.username,
	      f->tstamp);
      of = fopen(outfile, "w");
      sscanf(line, "%s", header);
      if (strcasecmp(header, f->labels.headerstart) == 0) {
	stage = commentout;
      } else {
	fputs(line, of);
	fputs("\n", of);
	stage = copy;
      }
      break;

    /*
        Consider anything read to be part of a comment for the fax cover
	page, until we find a user-supplied "comment end" header, at
	which point we can comfortably assume the remainder of the text
	is just message text.
    */

    case commentout:
      sscanf(line, "%s", header);
      if (strcasecmp(header, f->labels.headerend) == 0)
	stage = copy;
      else
	strcat(f->comments, line);
      break;

    /*
       Copy everything from stdin directly to the output file verbatim.
    */

    case copy:
      fputs(line, of);
      fputs("\n", of);
      break;
    }
  strcpy(line, getsline(ifp));  
  }
  fclose(of);
  fclose(ifp);
}

void make_fax(Fax *f)
{
/*
   Use Efax to convert the ASCII mailfile to a G3 fax.  This incidentally
   allows us to determine how many pages it will contain, so that we can
   include this information on the cover page.
*/

  char tmp[LINELEN];
  char line[LINELEN];
  int i = 0;
  FILE *ifp;

  sprintf(tmp, "%s make %s/fax.%s.%s > /dev/null", FAX, FAXQUEUE, 
	  f->fperson.username, f->tstamp);
  system(tmp);
  f->pages = 0;
  sprintf(line, "%s/fax.%s.%s.%03d", FAXQUEUE, f->fperson.username,
	  f->tstamp, ++i);
  while ((ifp = fopen(line, "r")) != NULL) {
    fclose(ifp);
    (f->pages)++;
    sprintf(line, "%s/fax.%s.%s.%03d", FAXQUEUE, f->fperson.username,
	    f->tstamp, ++i);
  }
}

void main(void)
{
  Fax f;

  read_config(&f);         /* load fax parameters */
  read_mail(&f);           /* parse the mail headers */
  lookup_db(&f);           /* look up recipient in the phonebook */
  make_fax(&f);            /* turn the mail into a fax */
  make_cover(&f);          /* create a fax cover page */
  insert_cover(&f);        /* make the cover page #1 */
  queue_fax(&f);           /* throw the completed fax onto the spool */
  cleanup(&f);             /* delete any garbage we created */
  exit(EXIT_SUCCESS);      /* we're outta here */
}
