/* Generated by Interface Builder */

#import "Crypter.h"
#import "NXPGPDelegate.h"
#import <defaults/defaults.h>
#import <strings.h>
#import <libc.h>
#import <stdlib.h>
#import <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>

#define ENCRYPT 0
#define DECRYPT 1
#define SIGN 2
#define CHECKSIG 3
#define ADDKEY 4

#define ENCRYPT_F 5
#define DECRYPT_F 6
#define SIGN_F 7
#define CHECKSIG_F 8
#define ADDKEY_F 9

@implementation Crypter

- (char **)encodeText:(const char *)plainText   length:(int)length
{
    char                lineopts[24];

 
	if (sign) {
		sprintf(lineopts, "-feast");
		sprintf(userIdStr, "-u %s", userID);
    } else {
		sprintf(lineopts, "-feat");
		sprintf(userIdStr, " ");
    }

    [self runpgp:ENCRYPT lineOpts:lineopts data:plainText length:&length];
	return textBuffer;
}

#ifndef S_ISDIR
#define S_ISDIR(mode)   (((mode) & (_S_IFMT)) == (_S_IFDIR))
#endif

- (char **)encodeFile:(const char *)plainText   length:(int)length
{
    char                lineopts[2048];
	char newName[1024];
	struct stat buf;
	
	sprintf(newName,"%s", plainText);
	
	if(stat(plainText, &buf)<0) {
		sprintf(newName,"PGP:%s", plainText);
		perror(newName);

	}
	else {
		if(S_ISDIR(buf.st_mode)) {
			char *ll;
			sprintf(newName,"%s.tar.Z", plainText);
			ll=strrchr(plainText, '/')+1;
			sprintf(lineopts, "cd %s; cd ..; gnutar cZf %s %s", plainText, newName, ll);
			system(lineopts);
		}
	}
		
	if (sign) {
		sprintf(lineopts, "-es %s", newName);
		sprintf(userIdStr, "-u %s", userID);
    } else {
		sprintf(lineopts, "-e %s", newName);
		sprintf(userIdStr, " ");
    }

    [self runpgp:ENCRYPT lineOpts:lineopts data:NULL length:&length];

	if(S_ISDIR(buf.st_mode)) {
		unlink(newName);
	}
	return textBuffer;
}

- (char **)decodeText:(const char *)cipherText length:(int *)lengthptr
{
    char                lineopts[24];

    strcpy(lineopts, "-f");

    [self runpgp:DECRYPT lineOpts:lineopts data:cipherText length:lengthptr];

    return textBuffer;
}

- (char **)decodeFile:(const char *)cipherText length:(int *)lengthptr
{
    char                lineopts[2048];

    sprintf(lineopts, "%s", cipherText);

    [self runpgp:DECRYPT lineOpts:lineopts data:NULL length:lengthptr];

    return textBuffer;
}

- (char **)signText:(const char *)plainText length:(int *)lengthptr
{
    char                lineopts[24];

    strcpy(lineopts, "-fast");
    sprintf(userIdStr, "-u %s", userID);
    [self runpgp:SIGN lineOpts:lineopts data:plainText length:lengthptr];
    
    return textBuffer;
}

- (char **)signFile:(const char *)plainText length:(int *)lengthptr
{
    char                lineopts[2048];

    sprintf(lineopts, "-s %s", plainText);
    sprintf(userIdStr, "-u %s", userID);
    [self runpgp:SIGN lineOpts:lineopts data:NULL length:lengthptr];
    
    return textBuffer;
}

- (char **)checkSig:(const char *)signedText length:(int *)lengthptr
{
    char                lineopts[24];

    strcpy(lineopts, "-f");

    [self runpgp:CHECKSIG lineOpts:lineopts data:signedText length:lengthptr];
    return textBuffer;

}

- (char **)checkFileSig:(const char *)signedText length:(int *)lengthptr
{
    char                lineopts[2048];

    sprintf(lineopts, "-f < %s", signedText);

    [self runpgp:CHECKSIG lineOpts:lineopts data:NULL length:lengthptr];
    return textBuffer;

}

-(char **)addKey:(const char *)plainText length:(int *)lengthptr
{
	char lineopts[24];

	strcpy(lineopts, "-fka");
	[self runpgp:ADDKEY lineOpts:lineopts data:plainText length:lengthptr];

	return textBuffer;
}

-(char **)addKeyFile:(const char *)plainText length:(int *)lengthptr
{
	char lineopts[2048];

	sprintf(lineopts, "-ka %s", plainText);
	[self runpgp:ADDKEY lineOpts:lineopts data:NULL length:lengthptr];

	return textBuffer;
}

- setsign:(BOOL)set
{
    sign = set;
    return self;
}

- setpassPhrase:(const char *)passpointer
{
    passPhrase = passpointer;
    return self;
}

- setkeyRing:(const char *)keyringpointer
{
    keyRing = keyringpointer;
    return self;
}

- setuserID:(const char *)userIDpointer
{
    userID = userIDpointer;
    return self;
}

- setuserString:(const char *)userStringptr
{
    userString = userStringptr;
    return self;
}

- setPGPPATH:(const char *)pgpPATH
{
    pgppath = pgpPATH;
    return self;
}

- runpgp:(int)mode lineOpts:(char *)lineopts data:(const char *)incoming length:(int *)lengthptr
{
    char               *filename[2], *shellcom;
    FILE               *inFile, *pgpproc;
    void               *tempptr;
    int                 i = 0;
    int                 c, j, k = 0,doPassPhraseToo=0;
	int oldMask;

	oldMask=umask(0066);
	
    filename[0] = calloc(55, 1);
    filename[1] = calloc(55, 1);
    shellcom = calloc(2048, 1);

    for (k = 0; k <= 1; k++) {
		for (i = 0; i <= 50; i++)
		  filename[k][i] =  '\0';
    }
    i = 0;
    k = 0;

    j = *lengthptr;
    textBuffer[0] = calloc((j + 2), 1);
    textBuffer[1] = calloc(8192, 1);

    sprintf(filename[0], "/tmp/file000000data#");
    NXGetTempFilename(filename[0], 9);

    sprintf(filename[1], "/tmp/file000000status#");
    NXGetTempFilename(filename[1], 9);

    switch (mode) {

	  case ENCRYPT:
		sprintf(shellcom, "PGPPATH=%s pgp +batchmode %s %s %s  -z \"%s\" >%s 2>%s",pgppath, lineopts, userString, userIdStr, sign ? passPhrase: " ", filename[0], filename[1]);
		if(sign)
		{
			doPassPhraseToo=1;
		}
		break;

	  case DECRYPT:
		sprintf(shellcom, "PGPPATH=%s pgp +batchmode %s  -z \"%s\" >%s 2>%s", pgppath, lineopts,  passPhrase, filename[0], filename[1]);
		doPassPhraseToo=1;
		break;

	  case SIGN:
		sprintf(shellcom, "PGPPATH=%s pgp +batchmode %s +clearsig=on  %s -z \"%s\" >%s 2>%s", pgppath, lineopts, userIdStr, passPhrase, filename[0], filename[1]);
		doPassPhraseToo=1;
		break;

	  case CHECKSIG:
		sprintf(shellcom, "PGPPATH=%s pgp +batchmode %s  >%s 2>%s", pgppath, lineopts, filename[0], filename[1]);
		break;

	  case ADDKEY:
		sprintf(shellcom, "PGPPATH=%s pgp +batchmode %s >%s 2>%s", pgppath, lineopts, filename[0], filename[1]);
		break;
		
	  default:
		fprintf(stderr, "Something wrong. runpgp called with invalid mode.\n");
		exit(-1);
		break;
    }

	pgpproc = popen(shellcom, "w");
		/*    if(doPassPhraseToo)
			  {
			  for (i = 0; i < strlen(passPhrase); i++)
			  {
			  fputc(passPhrase[i], pgpproc);
			  fputc(passPhrase[i], stderr);
			  }
			  fputc('\n',pgpproc);
			  fputc('\n',stderr);
			  fflush(pgpproc);
			  fflush(stderr);
			  }
			  sleep(3);*/
	if(incoming) {
		for (i = 0; i < j; i++)
		  fputc(incoming[i], pgpproc);
		fflush(pgpproc);
	}
	pclose(pgpproc);

    for (k = 0; k <= 1; k++) {
		inFile = fopen(filename[k], "r");
		i = 0;
		while ((c = fgetc(inFile)) != EOF) {
			textBuffer[k][i] = c;
			if (i >= (j - 2)) {
				j += 1024;
				tempptr = malloc(j);
				memcpy(tempptr, textBuffer[k], i + 1);
				free(textBuffer[k]);
				textBuffer[k] = tempptr;
			}
			i++;
		}
		textBuffer[k][i] = '\0';
		fclose(inFile);
		unlink(filename[k]);
		if (k == 0)
		  [delegate setLength:i];
    }
	free(filename[0]);
	free(filename[1]);
	free(shellcom);

	umask(oldMask);
    return self;
}

@end
