#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <md5.h>

#include "libpgp2.h"

/*------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
  int ch;
  int convflag = 0, delit = 0, textflg = 0, encflag = 1;
  extern char *optarg;
  unsigned char passwdhash[16], t;
  unsigned long long keyid = 0LL;
  char obuf[256];
  FILE *chkf = stdin, *inf = stdin, *outf = stdout;

  while ((ch = getopt(argc, argv, "a:cde:i:k:l:o:p:q:t:u:xz")) != -1) {
    if (ch == 'k') {
      if (!setkeyring(optarg))
        fprintf(stderr, "Keyring not found, defaulting\n");
    } else if (ch == 'p')       /* password */
      MD5(optarg, strlen(optarg), passwdhash);
    else if (ch == 'c')
      convflag++;
    else if (ch == 'd')
      delit++;
    else if (ch == 'f') {
      chkf = fopen(optarg, "rb");
      if (chkf == NULL)
        exit(-1);
    } else if (ch == 'i') {
      inf = fopen(optarg, "rb");
      chkf = inf;
      if (inf == NULL)
        exit(-1);
    } else if (ch == 'o') {
      outf = fopen(optarg, "wb");
      if (outf == NULL)
        exit(-1);
    } else if (ch == 't')
      sscanf(optarg, "%d", &textflg);
    else if (ch == 'e') {       /* one pke for each recip */
      sscanf(optarg, "%qx", &keyid);
      if (!pkeenc2(outf, keyid, passwdhash, encflag)) {
        encflag = 0;
        convflag++;
      }
    } else if (ch == 'u') {
      sscanf(optarg, "%qx", &keyid);
      return (sigmak2(inf, outf, passwdhash, keyid, delit, textflg));
    } else if (ch == 'a')
      return (armor(inf, outf, optarg, NULL));
    else if (ch == 'l')
      return (enlit(inf, outf, optarg, textflg));
    else if (ch == 'x')
      return (getlit(inf, outf));
    else if (ch == 'z')
      return (pgpcomp(inf, outf, 1));
    else if (ch == 'q') {
      strncpy(obuf, optarg, 255);
      if (!getkey2(NULL, obuf, NULL, &keyid))
        fprintf(stderr, "(%lX) %lX %s\n", (unsigned long) (keyid >> 32),
                (unsigned long) keyid & 0xffffffff, obuf);
      return 0;
    } else {
      fprintf(stderr,
              "usage:\n"
              "minipgp [-d] [-k krf] [-f cksigf] [-p hpp] <in.pgp >out\n"
              "        dearmor, decrypt, decompress, or check a signature\n"
              "minipgp [-k krf] {-e HXKID} <in >out encrypt with pubkey(s)\n"
              "minipgp -p password -c <in >out      conventional encryption\n"
              "minipgp [-k krf] [-d] [-t] [-p hpp] -u HXKID <f >f.sig\n"
              "                                     create a signature\n"
              "minipgp -z <in >out                  Compress\n"
              "minipgp [-t 1] -l litfname <in >out  Embed in literal\n"
              "minipgp -x <in >out                  Extract from Literal\n"
              "minipgp -a \"MESSAGE\" <in >out      Armor\n"
              "minipgp -q \"User Name\"             Query Keyid for ID\n"
              "\nThe following options should occur first:\n\n"
              "-p hashpass   the secret key or conventional passphrase\n"
              "-k ring.pgp   a different keyring\n"
              "-f file       the file for the signature\n"
              "-d            bypass any literal packet for signatures\n"
              "-t n          set text or signature mode flags\n"
              "-i infile     instead of <infile, must be first\n"
              "-o outfile    instead of >outfile, must be first\n"
        );
      exit(-1);
    }
  }
  if (convflag)
    return (cnvenc2(inf, outf, passwdhash));
  t = fgetc(inf);               /* autodetect */
  ungetc(t, inf);
  if (t == 0xa3)
    return (pgpcomp(inf, outf, 0));
  else if ((t & 0xfc) == 0x88) {
    if (!(ch = sigchk2(inf, chkf, delit)))
      fprintf(stderr, "Good Signature\n");
    return ch;
  } else if ((t & 0xfc) == 0x84) {  /* public key encrypted */
    /* passwdhash seckeypass in, convpass out when successful */
    while ((ch = pkedec2(inf, passwdhash)) > 0);
    if (!ch)
      return (cnvdec2(inf, outf, passwdhash));
    else
      return ch;
  } else if ((t & 0xfc) == 0xA4)  /* else must be conventionally encrypted */
    return (cnvdec2(inf, outf, passwdhash));
  else if (t < 0x80)
    return (dearmor(inf, outf));
  return -1;
}
