#define DIR "/home/ghio/alpha"
#define DOMAIN "alpha.c2.org"
#define REMAILER "remailer"
#define SENDMAIL "/usr/lib/sendmail"
#define INQUEUE "in.queue"
#define NYMSDIR "nyms"

#define PGP "/usr/local/bin/pgp"
#define PGPPATH DIR
#define LS "/bin/ls"

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h> /* some os need this one also */
/*File io stuff:*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

FILE *infile;
FILE *outfile;
FILE *tempfile;
FILE *file2;
char nym[256]="";
char key[256]="";
char from[256]="";

void reap(){
        while(wait3(0,WNOHANG,0)>0);
      }

int search(char str1[],char str2[]) {
  int x=0;
  int y=0;
  int match=0;

  while(str2[x]!=0) {
    y=0;
    while ((str2[x+y]==str1[y]||str2[x+y]==(str1[y]-32))&&str2[x+y]!=0) {
      y++;
      if (str1[y]==0) match=1;
    }
    x++;
  }
  return(match);
}


/* call pgp to encrypt messages with password */
void pwencrypt(){
  char input[256];
  int pipefd[2];
  int pipe2fd[2];

  input[255]=0;
  pipe(pipefd);
  pipe(pipe2fd);
  if(!fork()) {
    dup2(pipefd[0],0);
    dup2(pipe2fd[1],1);
    close(pipefd[1]);
    close(pipe2fd[0]);
    chdir(DIR);
    execl(PGP,"pgp","-fcta","+BATCHMODE","+ARMORLINES=0","-z",key,(char *)0);
  }
  close(pipefd[0]);close(pipe2fd[1]);
  file2=fdopen(pipefd[1],"w");
  while(fgets(input,255,infile)) {
    fprintf(file2,"%s",input);
  }
  fclose(file2);
  file2=fdopen(pipe2fd[0],"r");
  while(fgets(input,255,file2)) {
    fprintf(outfile,"%s",input);
  }
  fclose(file2);
}


void main(int argc,char *argv[]) {
  char input[256];
  int x,y;
  pid_t mypid,otherpid;
  char filename[256];
  char filename2[256];
  int pipefd[2];
  int pipe2fd[2];
  char envstr[256];
  char address[256];
  char msgsentflag;

  struct sigaction sa;
  sigemptyset (&sa.sa_mask);
  sa.sa_flags = 0;
  sa.sa_handler = reap;
  sigaction(SIGCHLD, &sa, 0);

  chdir(DIR);
  mypid=getpid();otherpid=0;
  if(infile=fopen("pid","rb")) {
    fread(&otherpid,sizeof(pid_t),1,infile);
    fclose(infile);
  }
  /* If there is another process already running, exit */
  if(otherpid) { if(kill(otherpid,SIGCONT)==0) exit(0); }

in_loop:

  /* Open an input file from in.queue */
  chdir(DIR);chdir(INQUEUE);
  pipe(pipefd);
  filename[0]=0;
  if(!fork()) {
    dup2(pipefd[1],1);
    close(pipefd[0]);
    execl(LS,"ls","-1",(char *)0);
  }
  x=0;close(pipefd[1]);
  infile=fdopen(pipefd[0],"r");
  while(fgets(filename,256,infile)) x++;
  fclose(infile);
  if(filename[0]==0) exit(0);
#ifdef SPAM_THRESHOLD
  if(x>SPAM_THRESHOLD) exit(0);
#endif
  for(x=0;filename[x]>32;x++){} filename[x]=0;
  if(!(infile=fopen(filename,"r"))){}
  
  /* Get nym */
  fgets(input,255,infile);
  for(x=5;(input[x]!=0)&&(input[x-1]!=32||input[x-2]!='r'||input[x-3]!='o'
   ||input[x-4]!='f'||input[x-5]!=32);x++);
  for(y=0;input[x]&&input[x]!='@';) nym[y++]=input[x++];
  nym[y]=0;
  /* de-capitalize and remove funky characters */
  /* (don't allow any create-a-file-anywhere hacks! :) */
  x=0;
  while(nym[x]!=0){
    if (nym[x]>='A'&&nym[x]<='Z') {
      nym[x]+=32;
    }
    if ((nym[x]<'a'||nym[x]>'z')&&
        (nym[x]<'0'||nym[x]>'9')&&nym[x]!='-') {
      nym[x]='_';
    }
    x++;
  }
  /* Get return-address */
  fgets(input,255,infile);
  x=6;
  for(y=0;input[x]>32;) from[y++]=input[x++];
  from[y]=0;

  msgsentflag=0;

  /* Encrypt and send with reply-block */
  sprintf(filename2,"%s/%s/%s.password",DIR,NYMSDIR,nym);
  if(file2=fopen(filename2,"r")){
    fgets(key,256,file2);
    fclose(file2);
    for(x=0;key[x]&224;x++);key[x]=0;
    
    sprintf(filename2,"%s/%s/%s.replyblock",DIR,NYMSDIR,nym);
    if(file2=fopen(filename2,"r")){
      pipe(pipe2fd);
      if(!fork()) {
        /*Child*/
        dup2(pipe2fd[0],0);close(pipe2fd[1]);
        execl(SENDMAIL,SENDMAIL,/*"-f",RETURN,*/REMAILER,(char *)0);
        fprintf(stderr,"ERROR: Cannot execute sendmail!\n");
        exit(1);
      }
      close(pipe2fd[0]);
      outfile=fdopen(pipe2fd[1],"w");
      fprintf(outfile,"\n");
      while(fgets(input,256,file2)) {
        fprintf(outfile,"%s",input);
      }
      fclose(file2);
      fseek(infile,0,0);
      pwencrypt();
      fclose(outfile);
      msgsentflag=1;
    }
  }
  
  /* Forward without encryption */
  sprintf(filename2,"%s/%s/%s.forward",DIR,NYMSDIR,nym);
  if(file2=fopen(filename2,"r")){
    fgets(address,256,file2);
    fclose(file2);
    for(x=0;address[x]&224;x++);address[x]=0;
    
    pipe(pipe2fd);
    if(!fork()) {
      /*Child*/
      dup2(pipe2fd[0],0);close(pipe2fd[1]);
      execl(SENDMAIL,SENDMAIL,/*"-f",RETURN,*/address,(char *)0);
      fprintf(stderr,"ERROR: Cannot execute sendmail!\n");
      exit(1);
    }
    close(pipe2fd[0]);
    outfile=fdopen(pipe2fd[1],"w");

    /* Copy message */
    fseek(infile,0,0);
    while(fgets(input,256,infile)) {
      fprintf(outfile,"%s",input);
    }
    fclose(outfile);
    msgsentflag=1;
  }
  
  /* No valid recipient, bounce */
  if(!msgsentflag) {
    pipe(pipe2fd);
    if(!fork()) {
      /*Child*/
      dup2(pipe2fd[0],0);close(pipe2fd[1]);
      execl(SENDMAIL,SENDMAIL,"-i","-f","nobody",from,(char *)0);
      /* We must use -i when calling sendmail here, otherwise
         messages containing dots will end the message, causing
         a sigpipe */
      fprintf(stderr,"ERROR: Cannot execute sendmail!\n");
      exit(1);
    }
    close(pipe2fd[0]);
    outfile=fdopen(pipe2fd[1],"w");
    fprintf(outfile,"From: MAILER-DAEMON@%s\n",DOMAIN);
    fprintf(outfile,"Subject: mail failed, returning to sender\n\n");
    fprintf(outfile,"Unknown addressee: %s@%s\n\n",nym,DOMAIN);
    fprintf(outfile,"----- Unsent Message Follows -----\n\n");
    /* Copy message */
    fseek(infile,0,0);
    while(fgets(input,256,infile)) {
      fprintf(outfile,"%s",input);
    }
    fclose(outfile);
  }
  
  fclose(infile);
  unlink(filename);
  goto in_loop;
}
