Index: Makefile.am
===================================================================
--- Makefile.am	(revision 10557e655b3e9d7d904e1c92e4e79e331de9c01f)
+++ Makefile.am	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
@@ -9,5 +9,5 @@
 barnowl_bin_SOURCES = $(BASE_SRCS) \
      owl.h owl_perl.h config.h \
-     owl.c \
+     owl.c filterproc.c \
      $(GEN_C) $(GEN_H)
 
@@ -38,5 +38,5 @@
      perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \
      regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
-     keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c \
+     keypress.c keymap.c keybinding.c cmd.c context.c \
      aim.c buddy.c buddylist.c style.c errqueue.c \
      zbuddylist.c popexec.c obarray.c select.c wcwidth.c \
Index: commands.c
===================================================================
--- commands.c	(revision f449096479541df1434d1d796890d0bd2939f072)
+++ commands.c	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
@@ -1962,5 +1962,4 @@
 char *owl_command_zcrypt(int argc, const char *const *argv, const char *buff)
 {
-#ifdef OWL_ENABLE_ZCRYPT
   owl_zwrite z;
 
@@ -1984,8 +1983,4 @@
   }
   return(NULL);
-#else
-  owl_function_makemsg("This Owl does not support zcrypt");
-  return NULL;
-#endif
 }
 
Index: filterproc.c
===================================================================
--- filterproc.c	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
+++ filterproc.c	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
@@ -0,0 +1,118 @@
+#include <signal.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <glib.h>
+
+int send_receive(int rfd, int wfd, const char *out, char **in)
+{
+  GString *str = g_string_new("");
+  char buf[1024];
+  nfds_t nfds;
+  int err = 0;
+  struct pollfd fds[2];
+  struct sigaction sig = {.sa_handler = SIG_IGN}, old;
+
+  fcntl(rfd, F_SETFL, O_NONBLOCK | fcntl(rfd, F_GETFL));
+  fcntl(wfd, F_SETFL, O_NONBLOCK | fcntl(wfd, F_GETFL));
+
+  fds[0].fd = rfd;
+  fds[0].events = POLLIN;
+  fds[1].fd = wfd;
+  fds[1].events = POLLOUT;
+
+  sigaction(SIGPIPE, &sig, &old);
+  
+  while(1) {
+    if(out && *out) {
+      nfds = 2;
+    } else {
+      nfds = 1;
+    }
+    err = poll(fds, nfds, -1);
+    if(err < 0) {
+      break;
+    }
+    if(out && *out) {
+      if(fds[1].revents & POLLOUT) {
+        err = write(wfd, out, strlen(out));
+        if(err > 0) {
+          out += err;
+        }
+        if(err < 0) {
+          out = NULL;
+        }
+      }
+      if(!out || !*out || fds[1].revents & (POLLERR | POLLHUP)) {
+        close(wfd);
+        out = NULL;
+      }
+    }
+    if(fds[0].revents & POLLIN) {
+      err = read(rfd, buf, sizeof(buf));
+      if(err <= 0) {
+        break;
+      }
+      g_string_append_len(str, buf, err);
+    } else if(fds[0].revents & (POLLHUP | POLLERR)) {
+      err = 0;
+      break;
+    }
+  }
+
+  *in = g_string_free(str, err < 0);
+  sigaction(SIGPIPE, &old, NULL);
+  return err;
+}
+
+int call_filter(const char *prog, const char *const *argv, const char *in, char **out, int *status)
+{
+  int err = 0;
+  pid_t pid;
+  int rfd[2];
+  int wfd[2];
+
+  if((err = pipe(rfd))) goto out;
+  if((err = pipe(wfd))) goto out_close_rfd;
+
+  pid = fork();
+  if(pid < 0) {
+    err = pid;
+    goto out_close_all;
+  }
+  if(pid) {
+    /* parent */
+    close(rfd[1]);
+    close(wfd[0]);
+    err = send_receive(rfd[0], wfd[1], in, out);
+    if(err == 0) {
+      waitpid(pid, status, 0);
+    }
+  } else {
+    /* child */
+    close(rfd[0]);
+    close(wfd[1]);
+    dup2(rfd[1], 1);
+    dup2(wfd[0], 0);
+    close(rfd[1]);
+    close(wfd[0]);
+
+    if(execvp(prog, (char *const *)argv)) {
+      _exit(-1);
+    }
+  }
+
+ out_close_all:
+  close(wfd[0]);
+  close(wfd[1]);
+ out_close_rfd:
+  close(rfd[0]);
+  close(rfd[1]);
+ out:
+  return err;
+}
Index: filterproc.h
===================================================================
--- filterproc.h	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
+++ filterproc.h	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
@@ -0,0 +1,9 @@
+#ifndef __FILTER_PROC_H__
+#define __FILTER_PROC_H__
+
+int call_filter(const char *prog,
+                const char *const *argv,
+                const char *in,
+                char **out, int *status);
+
+#endif
Index: functions.c
===================================================================
--- functions.c	(revision dfe94f9e62f7d20eae661ced19e86e150a17bba8)
+++ functions.c	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
@@ -12,4 +12,5 @@
 #include <signal.h>
 #include "owl.h"
+#include "filterproc.h"
 
 char *owl_function_command(const char *cmdbuff)
@@ -402,4 +403,6 @@
   char *cryptmsg;
   owl_message *m;
+  const char *argv[7];
+  int rv, status;
 
   /* create the zwrite and send the message */
@@ -411,7 +414,15 @@
 
   mymsg=owl_zwrite_get_message(&z);
-#ifdef OWL_ENABLE_ZCRYPT
-  cryptmsg = owl_zcrypt_encrypt(mymsg, owl_zwrite_get_class(&z), owl_zwrite_get_instance(&z));
-  if (!cryptmsg) {
+
+  argv[0] = "zcrypt";
+  argv[1] = "-E";
+  argv[2] = "-c"; argv[3] = owl_zwrite_get_class(&z);
+  argv[4] = "-i"; argv[5] = owl_zwrite_get_instance(&z);
+  argv[6] = NULL;
+
+  rv = call_filter("zcrypt", argv, mymsg, &cryptmsg, &status);
+
+  if (rv || status) {
+    if(cryptmsg) owl_free(cryptmsg);
     owl_function_error("Error in zcrypt, possibly no key found.  Message not sent.");
     owl_function_beep();
@@ -419,7 +430,4 @@
     return;
   }
-#else
-  cryptmsg=owl_strdup(mymsg);
-#endif
 
   owl_zwrite_set_message(&z, cryptmsg);
Index: message.c
===================================================================
--- message.c	(revision 66a8cd6f82c4a4dc47992bd57b12563500abb001)
+++ message.c	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
@@ -10,4 +10,5 @@
 #include <time.h>
 #include "owl.h"
+#include "filterproc.h"
 
 static owl_fmtext_cache fmtext_cache[OWL_FMTEXT_CACHE_SIZE];
@@ -838,14 +839,30 @@
   owl_free(tmp);
 
-#ifdef OWL_ENABLE_ZCRYPT
   /* if zcrypt is enabled try to decrypt the message */
   if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
-    char *out = owl_zcrypt_decrypt(owl_message_get_body(m), owl_message_get_class(m), owl_message_get_instance(m));
-    if (out) {
+    const char *argv[] = {
+      "zcrypt",
+      "-D",
+      "-c", owl_message_get_class(m),
+      "-i", owl_message_get_instance(m),
+      NULL
+    };
+    char *out;
+    int rv;
+    int status;
+
+    rv = call_filter("zcrypt", argv, owl_message_get_body(m), &out, &status);
+
+    if(!rv && !status) {
+      int len = strlen(out);
+      if(len >= 8 && !strcmp(out + len - 8, "**END**\n")) {
+        out[len - 8] = 0;
+      }
       owl_message_set_body(m, out);
       owl_free(out);
+    } else if(out) {
+      owl_free(out);
     }
   }
-#endif  
 }
 #else
Index: tester.c
===================================================================
--- tester.c	(revision 30bb10a729361f227f11994cb8b0d640b25b7f57)
+++ tester.c	(revision d564c3d0a07e5929b3445a63f13cb97eb6b52715)
@@ -13,7 +13,4 @@
 int owl_obarray_regtest(void);
 int owl_editwin_regtest(void);
-#ifdef OWL_ENABLE_ZCRYPT
-int owl_zcrypt_regtest(void);
-#endif
 
 int main(int argc, char **argv, char **env)
@@ -36,7 +33,4 @@
   numfailures += owl_obarray_regtest();
   numfailures += owl_editwin_regtest();
-#ifdef OWL_ENABLE_ZCRYPT
-  numfailures += owl_zcrypt_regtest();
-#endif
   if (numfailures) {
       fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures);
@@ -367,23 +361,2 @@
   return numfailed;
 }
-
-#ifdef OWL_ENABLE_ZCRYPT
-int owl_zcrypt_regtest(void)
-{
-  int numfailed = 0;
-  char *encrypted, *decrypted;
-
-  printf("# BEGIN testing owl_zcrypt\n");
-
-  encrypted = owl_zcrypt_encrypt_with_key("Hello, world!", "seekritkey");
-  FAIL_UNLESS("zcrypt encrypt", strcmp(encrypted, "TLJMKQSIGKSJRIJRSIIPIJFFULKRJSPK") == 0);
-  decrypted = owl_zcrypt_decrypt_with_key(encrypted, "seekritkey");
-  FAIL_UNLESS("zcrypt decrypt", strcmp(decrypted, "Hello, world!") == 0);
-  owl_free(decrypted);
-  owl_free(encrypted);
-
-  printf("# END testing owl_zcrypt (%d failures)\n", numfailed);
-
-  return numfailed;
-}
-#endif
Index: rypt.c
===================================================================
--- zcrypt.c	(revision f8074e9c91e6b8e560ef58024ee77e7dc85b6b34)
+++ 	(revision )
@@ -1,291 +1,0 @@
-/* This file is stolen and slightly modified code */
-
-/* zcrypt.c -- Read in a data stream from stdin & dump a decrypted/encrypted *
- *   datastream.  Reads the string to make the key from from the first       *
- *   parameter.  Encrypts or decrypts according to -d or -e flag.  (-e is    *
- *   default.)  Will invoke zwrite if the -c option is provided for          *
- *   encryption.  If a zephyr class is specified & the keyfile name omitted  *
- *   the ~/.crypt-table will be checked for "crypt-classname" and then       *
- *   "crypt-default" for the keyfile name.                                   */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "owl.h"
-
-#ifdef OWL_ENABLE_ZCRYPT
-
-#define BASE_CODE 70
-#define LAST_CODE (BASE_CODE + 15)
-#define OUTPUT_BLOCK_SIZE 16
-#include <unistd.h>
-#include <sys/types.h>
-
-#ifdef HAVE_KERBEROS_IV
-#include <kerberosIV/des.h>
-#else
-#include <openssl/des.h>
-#endif
-
-#define MAX_KEY 128
-
-#define ZWRITE_OPT_NOAUTH     (1<<0)
-#define ZWRITE_OPT_SIGNATURE  (1<<1)
-#define ZWRITE_OPT_IGNOREVARS (1<<2)
-#define ZWRITE_OPT_VERBOSE    (1<<3)
-#define ZWRITE_OPT_QUIET      (1<<4)
-#define ZCRYPT_OPT_MESSAGE    (1<<5)
-#define ZCRYPT_OPT_IGNOREDOT  (1<<6)
-
-typedef struct
-{
-  int flags;
-  char *signature;
-  char *message;
-} ZWRITEOPTIONS;
-
-char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance);
-
-#define M_NONE            0
-#define M_ZEPHYR_ENCRYPT  1
-#define M_DECRYPT         2
-#define M_ENCRYPT         3
-#define M_RANDOMIZE       4
-#define M_SETKEY          5
-
-static void owl_zcrypt_string_to_schedule(const char *keystring, des_key_schedule *schedule) {
-#ifdef HAVE_KERBEROS_IV
-  des_cblock key;
-#else
-  des_cblock _key, *key = &_key;
-#endif
-
-  des_string_to_key(keystring, key);
-  des_key_sched(key, *schedule);
-}
-
-/* The 'owl_zcrypt_decrypt' function was written by kretch for Owl.
- * Decrypt the message in 'in' on class 'class' and instance
- * 'instance'.  Return must be freed by caller.
- */
-char *owl_zcrypt_decrypt(const char *in, const char *class, const char *instance)
-{
-  char *fname, keystring[MAX_KEY];
-  FILE *fkey;
-  
-  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
-  if (!fname) return NULL;
-  fkey=fopen(fname, "r");
-  owl_free(fname);
-  if (!fkey) return NULL;
-  if (!fgets(keystring, MAX_KEY-1, fkey)) {
-    fclose(fkey);
-    return NULL;
-  }
-  fclose(fkey);
-
-  return owl_zcrypt_decrypt_with_key(in, keystring);
-}
-
-char *owl_zcrypt_decrypt_with_key(const char *in, const char *keystring)
-{
-  const char *inptr, *endptr;
-  char *out;
-  des_key_schedule schedule;
-  unsigned char input[8], output[8];
-  int i, c1, c2;
-
-  /* We read in some number of full 16-byte blocks and write out the
-   * same number of 8-byte blocks, plus a null terminator.
-   */
-  out = owl_malloc((strlen(in) / 16) * 8 + 1);
-
-  strcpy(out, "");
-
-  output[0] = '\0';    /* In case no message at all                 */
-
-  owl_zcrypt_string_to_schedule(keystring, &schedule);
-
-  inptr=in;
-  endptr = in + strlen(in);
-  while (inptr + 16 <= endptr) {
-    for (i=0; i<8; i++) {
-      c1=(inptr[0])-BASE_CODE;
-      c2=(inptr[1])-BASE_CODE;
-      input[i]=c1 * 0x10 + c2;
-      inptr+=2;
-    }
-    des_ecb_encrypt(&input, &output, schedule, FALSE);
-    strncat(out, (const char *)output, 8);
-  }
-
-  return out;
-}
-
-char *owl_zcrypt_encrypt(const char *in, const char *class, const char *instance)
-{
-  char *fname, keystring[MAX_KEY];
-  FILE *fkey;
-
-  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
-  if (!fname) return NULL;
-  fkey=fopen(fname, "r");
-  owl_free(fname);
-  if (!fkey) return NULL;
-  if (!fgets(keystring, MAX_KEY-1, fkey)) {
-    fclose(fkey);
-    return NULL;
-  }
-  fclose(fkey);
-
-  return owl_zcrypt_encrypt_with_key(in, keystring);
-}
-
-char *owl_zcrypt_encrypt_with_key(const char *in, const char *keystring)
-{
-  des_key_schedule schedule;
-  char *out;
-  unsigned char input[8], output[8];
-  int size, length, i;
-  const char *inbuff = NULL, *inptr;
-  int num_blocks=0, last_block_size=0;
-
-  owl_zcrypt_string_to_schedule(keystring, &schedule);
-
-  /* Allocate enough space for the crypted message. For each byte of
-   * the message, the encoded cyphertext will have two bytes. Block
-   * size is 8 bytes of input, or 16 bytes of output, so make sure we
-   * have at least one block worth of space allocated. If the message
-   * is empty, no blocks are sent, but we still allocate one
-   * block. The additional 16 bytes also provide space for the null
-   * terminator, as we will never use all of it for cyphertext.
-   */
-  out = owl_malloc((strlen(in) * 2) + 16);
-
-  inbuff=in;
-  length=strlen(inbuff);
-  num_blocks=(length+7)/8;
-  last_block_size=((length+7)%8)+1;
-
-  strcpy(out, "");
-  
-  inptr=inbuff;
-  while (TRUE) {
-    /* Get 8 bytes from buffer */
-    if (num_blocks > 1) {
-      size = 8;
-      memcpy(input, inptr, size);
-      inptr+=8;
-      num_blocks--;
-    } else if (num_blocks == 1) {
-      size=last_block_size;
-      memcpy(input, inptr, size);
-      num_blocks--;
-    } else {
-      size=0;
-    }
-
-    /* Check for EOF and pad the string to 8 chars, if needed */
-    if (size == 0) break;     /* END OF INPUT: BREAK FROM while LOOP! */
-      
-    if (size<8) memset(input + size, 0, 8 - size);
-
-    /* Encrypt and output the block */
-    des_ecb_encrypt(&input, &output, schedule, TRUE);
-
-    for (i = 0; i < 8; i++) {
-      sprintf(out + strlen(out), "%c", ((output[i] & 0xf0) >> 4) + BASE_CODE);
-      sprintf(out + strlen(out), "%c", (output[i] & 0x0f)        + BASE_CODE);
-    }
-
-    if (size < 8) break;
-  }
-  return out;
-}
-
-
-#define MAX_BUFF 258
-#define MAX_SEARCH 3
-/* Find the class/instance in the .crypt-table */
-char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance) {
-  char *keyfile = NULL;
-  char *varname[MAX_SEARCH];
-  int length[MAX_SEARCH], i;
-  char buffer[MAX_BUFF];
-  char *filename;
-  char result[MAX_SEARCH][MAX_BUFF];
-  int numsearch = 0;
-  FILE *fsearch;
-
-  memset(varname, 0, sizeof(varname));
-
-  /* Determine names to look for in .crypt-table */
-  if (instance) {
-    varname[numsearch++] = owl_sprintf("crypt-%s-%s:", (class?class:"message"), instance);
-  }
-  if (class) {
-    varname[numsearch++] = owl_sprintf("crypt-%s:", class);
-  }
-  varname[numsearch++] = owl_strdup("crypt-default:");
-
-  /* Setup the result array, and determine string lengths */
-  for (i = 0; i < numsearch; i++) {
-    result[i][0] = '\0';
-    length[i] = strlen(varname[i]);
-  }
-
-  /* Open~/.crypt-table */
-  filename = owl_sprintf("%s/.crypt-table", getenv("HOME"));
-  fsearch = fopen(filename, "r");
-  if (fsearch) {
-    /* Scan file for a match */
-    while (!feof(fsearch)) {
-      if (!fgets(buffer, MAX_BUFF - 3, fsearch)) break;
-      for (i = 0; i < numsearch; i++) {
-	if (strncasecmp(varname[i], buffer, length[i]) == 0) {
-	  int j;
-	  for (j = length[i]; buffer[j] == ' '; j++)
-	    ;
-	  strcpy(result[i], &buffer[j]);
-	  if (*result[i]) {
-	    if (result[i][strlen(result[i])-1] == '\n') {
-	      result[i][strlen(result[i])-1] = '\0';
-	    }
-	  }
-	}
-      }
-    }
-
-    /* Pick the "best" match found */
-    keyfile = NULL;
-    for (i = 0; i < numsearch; i++) {
-      if (*result[i]) {
-	keyfile = result[i];
-	break;
-      }
-    }
-
-    if (keyfile == NULL) {
-      /* printf("Could not find key table entry.\n"); */
-    } else {
-      /* Prepare result to be returned */
-      keyfile = owl_strdup(keyfile);
-    }
-    
-    fclose(fsearch);
-  } else {
-    /* printf("Could not open key table file: %s\n", filename); */
-  }
-
-  for(i = 0; i < MAX_SEARCH; i++) {
-    owl_free(varname[i]);
-  }
-
-  owl_free(filename);
-
-  return(keyfile);
-}
-
-#endif
