#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>

#include "gpg.h"

extern int spawn_job (char *path, char *argv[], 
		      int *in_fd, int *out_fd, int *err_fd);

struct VerifySignObject verifySignObj;
struct ReadCryptedObject readCryptedObj;
struct ImportKeyObject importKeyObj;

/* ------------------------------------------------- */
void PA_VerifySignature(struct VerifySignObject *vSO) {
  
  char *strArgs[10];
  char Args0[100];
  char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
  int gpg_pid;
  int gpg_in_fd, out_fd, err_fd;
  int status;
  char txt[LINE_LENGTH];
  char *keyStr;

  /* Copy the incoming object on the internal global object */
  memmove( &verifySignObj, vSO, sizeof(struct VerifySignObject)  );

  strcpy(Args0, "--no-secmem-warning");
  strcpy(Args1, "--keyring");
  strcpy(Args2, verifySignObj.keyRing);
  strcpy(Args3, "--verify");
  if (!strcmp(verifySignObj.iSigFilename, "")) {
    strcpy(Args4, verifySignObj.iDocSigFilename);
  } else {
    strcpy(Args4, verifySignObj.iSigFilename);
    strcpy(Args5, verifySignObj.iDocSigFilename);
  }

  strArgs[0] = Args0;
  strArgs[1] = Args1;  
  strArgs[2] = Args2;  
  strArgs[3] = Args3;
  strArgs[4] = Args4;
  strArgs[5] = Args5;
  strArgs[6] = (char *)0;
  
 
  gpg_in_fd = INPUT_FD;
  out_fd = OUTPUT_FD;
  err_fd = ERROR_FD;
  if ( ( gpg_pid = spawn_job ("gpg", strArgs,
			      &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
    {
      printf ("could not spawn gpg");
    }
  
  if (waitpid (gpg_pid, &status, 0) < 0)
    {
      fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
      printf ("could not reap gpg process");
      /*      exit (1); */
    }
  if (status != 0)
    {
      fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
      printf ("gpg failure");
      /*      exit (1); */
    }


  /* Parsing gpg output */
  vSO->isValid = 0;
  while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL)
    {
      /*             printf ( "GPG output : %s\n", txt );  */
      if (strstr(txt, "Good signature") != NULL)
	vSO->isValid = 1;
      if ((keyStr = strstr(txt, "key ID")) != NULL) {
	keyStr += 7;
	sscanf(keyStr, "%8X\n", &vSO->keyID);
      }
    }
  close (INPUT_FD);
}

/* ------------------------------------------------- */
void PA_Decrypt(struct ReadCryptedObject *rDO) {
  
  char *strArgs[9];
  char clearTextExtension[4] = ".gpg";
  char Args0[100] = "abracadabra";
  char Args1[100];
  char Args2[100];
  char Args3[100];
  char Args4[100];
  char Args5[100];
  char Args6[100];
  int gpg_pid;
  int gpg_in_fd, out_fd, err_fd;
  int status;
  char txt[LINE_LENGTH];


  /* Copy the incoming object on the internal global object */
  memmove( &readCryptedObj, rDO, sizeof(struct ReadCryptedObject)  );

  strcpy(Args0, "--no-tty");
  strcpy(Args1, "--no-secmem-warning");
  strcpy(Args2, "--keyring");
  strcpy(Args3, readCryptedObj.keyRing);
  strcpy(Args4, "--output");
  strcpy(Args5, strcat(readCryptedObj.iFilename, clearTextExtension));
  strcpy(Args6, readCryptedObj.iFilename);
  
  strArgs[0] = Args0;
  strArgs[1] = Args1;  
  strArgs[2] = Args2;  
  strArgs[3] = Args3;  
  strArgs[4] = Args4;  
  strArgs[5] = Args5;  
  strArgs[6] = Args6;  
  strArgs[7] = (char *) 0;   

  gpg_in_fd = INPUT_FD;
  out_fd = OUTPUT_FD;
  err_fd = ERROR_FD;
  if ( ( gpg_pid = spawn_job ("gpg", strArgs,
			      &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
    {
      printf ("could not spawn gpg");
    }
  
  if (waitpid (gpg_pid, &status, 0) < 0)
    {
      fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
      printf ("could not reap gpg process");
      /*      exit (1); */
    }
  if (status != 0)
    {
      fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
      printf ("gpg failure");
      /*      exit (1); */
    }


  /* Parsing gpg output */
  while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL)
    {
      /*      printf ( "GPG output : %s\n", txt );  */
      
      /*      if ((keyStr = strstr(txt, "key")) != NULL) {
	 keyStr += 4;
	 sscanf(keyStr, "%8X\n", &iKO->keyID); 
	 } */
    }
  close (INPUT_FD);
}


/* ------------------------------------------------- */
void PA_ImportKey(struct ImportKeyObject *iKO) {
  
  char *strArgs[9];
  char Args0[100] = "abracadabra";
  char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
  int gpg_pid;
  int gpg_in_fd, out_fd, err_fd;
  int status;
  char txt[LINE_LENGTH];
  char *keyStr;

  /* Copy the incoming object on the internal global object */
  memmove( &importKeyObj, iKO, sizeof(struct ImportKeyObject)  );

  importKeyObj.rc = iKO_GENERALFAILURE;

  strcpy(Args0, "--no-tty");
  strcpy(Args1, "--no-secmem-warning");
  strcpy(Args2, "--keyring");
  strcpy(Args3, importKeyObj.keyRing);
  strcpy(Args4, "--import");
  strcpy(Args5, importKeyObj.iFilename);

  strArgs[0] = Args0;  
  strArgs[1] = Args1;  
  strArgs[2] = Args2;  
  strArgs[3] = Args3;  
  strArgs[4] = Args4;  
  strArgs[5] = Args5;
  strArgs[6] = (char *)0;

  gpg_in_fd = INPUT_FD;
  out_fd = OUTPUT_FD;
  err_fd = ERROR_FD;
  if ( ( gpg_pid = spawn_job ("/usr/local/bin/gpg", strArgs,
			      &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
    {
      printf ("could not spawn gpg");
    }
  
  if (waitpid (gpg_pid, &status, 0) < 0)
    {
      fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
      printf ("could not reap gpg process");
      /*      exit (1); */
    }

  
  if (status != 0)
    {
      fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
      printf ("gpg failure");
      /*      exit (1); */
    }


  /* Parsing gpg output */
  iKO->rc = iKO_GENERALFAILURE;
  while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL)
    {
      /*      printf ( "GPG output : %s\n", txt );    */

      if ((keyStr = strstr(txt, "imported")) != NULL) {
	iKO->rc = iKO_OK;
      }
      if ((keyStr = strstr(txt, "unchanged")) != NULL) {
	iKO->rc = iKO_UNCHANGED;
      }

      if ((keyStr = strstr(txt, "key")) != NULL) {
	 keyStr += 4;
	 sscanf(keyStr, "%8X\n", &iKO->keyID); 
      } 
    }
  close (INPUT_FD);
}


