#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <wait.h>
#include <malloc.h>

#include "libpgp5.h"

FILE *inf, *outf;
int split()
{
  int passpipe[2];

  pipe(passpipe);
  if (!(fork())) {
    inf = fdopen(passpipe[0], "rb");
    close(passpipe[1]);
    return 1;
  }
  outf = fdopen(passpipe[1], "wb");
  close(passpipe[0]);
  return 0;
}

/*-------------------------*/
int main(int argc, char *argv[])
{
  unsigned char dbuf[4096], *bp, pp[256] = "";
  int cnt, halg = 2, salg = 0x11;
  unsigned long long keyid = 0;
  void *signkey;
  extern char *optarg;

  inf = stdin, outf = stdout;

  while ((cnt = getopt(argc, argv, "i:o:k:p:a:A:r:")) != -1) {
    if (cnt == 'k')
      sscanf(optarg, "%qx", &keyid);
    else if (cnt == 'a')
      halg = atoi(optarg);
    else if (cnt == 'A')
      salg = atoi(optarg);
    else if (cnt == 'p')        /* password */
      strncpy(pp, optarg, 255);
    else if (cnt == 'r')
      setkeyring5(optarg);
    else if (cnt == 'i') {
      inf = fopen(optarg, "r");
      if (inf == NULL)
        exit(-1);
    } else if (cnt == 'o') {
      outf = fopen(optarg, "w");
      if (outf == NULL)
        exit(-1);
    } else {
      fprintf(stderr, "Usage: clearsig [-i inf] [-o outf] options...\n"
              "Options: [-k key] [-A siga] [-a hash] [-p passph] [-r skr]\n"
              "Clearsigns text from stdin to stdout (if -i/-o not used)\n");
    }
  }

  fputs("-----BEGIN PGP SIGNED MESSAGE-----\n", stdout);
  switch (halg) {
  case 1:
    fputs("\n", stdout);
    break;
  case 2:
    fputs("Hash: SHA1\n\n", stdout);
    break;
  case 3:
    fputs("Hash: RIPEMD160\n\n", stdout);
    break;
  case 4:
    fputs("Hash: HAVAL\n\n", stdout);
    break;
  case 5:
    fputs("Hash: MD2\n\n", stdout);
    break;
  }
  fflush(stdout);

  if (split()) {
    if (split()) {              /* this won't start until sig done */
      cnt = armor(inf, outf, "SIGNATURE", NULL);
      exit(0);
    } else {
      if (salg == 0x11)
        signkey = DSA_new(),
          cnt = getkey5(NULL, (DSA **) & signkey, pp, &keyid);
#ifndef NOELGSIG
      else if (salg == 0x10)
        signkey = DH_new(),
          cnt = getkey5((DH **) & signkey, NULL, pp, &keyid);
#endif
#ifndef NO_RSA
      else if (salg == 1 || salg == 3)
        signkey = RSA_new(),
          cnt = getkey5((DH **) & signkey, (DSA **) & signkey, pp, &keyid);
#endif
      else
        return -3;
      if (cnt) {
        fprintf(stderr, "No Secret key found %d\n", cnt);
        return -5;
      }
      cnt = sigmak5(signkey, inf, outf, keyid, 2, halg, salg, NULL);
      fclose(outf);
      wait(&cnt);
      exit(0);
    }
  }
  bp = dbuf;
  while (!feof(inf)) {          /* passthrough plain, canonical to child */
    if (NULL == fgets(bp, 4095, inf))
      break;
    if (*bp == '-') {
      memmove(&bp[2], bp, strlen(bp) + 1);
      bp[1] = ' ';
    }
    fputs(bp, stdout);

    while (strlen(bp) && bp[strlen(bp) - 1] <= ' ')
      bp[strlen(bp) - 1] = 0;
    strcat(bp, "\r");
    strcat(bp, "\n");
    if (!strncmp(bp, "- -", 3))
      memmove(bp, &bp[2], strlen(bp));
    fputs(bp, outf);
  }
  fputs("\n", stdout);
  fflush(stdout);
  fclose(outf);
  wait(&cnt);
  return 0;
}
