diff -u srcx.orig/vpsdc.cxx srcx/vpsdc.cxx
--- srcx.orig/vpsdc.cxx	Wed Aug 28 18:00:36 1996
+++ srcx/vpsdc.cxx	Thu Jul 31 11:44:12 1997
@@ -256,7 +256,12 @@
 	vNoticeDialog note(theApp);
 	strcpy(msg,"Printing to: \n");
 	if (_printer.GetToFile())	// to file or printer
-	    strcat(msg,dname);
+          {
+            if (dname[0]=='|')
+                strcat(msg,"Program");
+            else
+	        strcat(msg,dname);
+          }
 	else
 	    strcat(msg,"Printer");
 
diff -u srcx.orig/vpsprntr.cxx srcx/vpsprntr.cxx
--- srcx.orig/vpsprntr.cxx	Wed Mar  6 16:22:30 1996
+++ srcx/vpsprntr.cxx	Thu Jul 31 11:41:54 1997
@@ -14,6 +14,11 @@
 #include <v/vicon.h>
 #include <v/vfilesel.h>
 
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <unistd.h>
+
 #define prompt_width 32
 #define prompt_height 32
 static unsigned char prompt_bits[] = {
@@ -165,7 +170,102 @@
     if (_pstream)
 	_pstream->close();
 
-    _pstream = new ofstream(_name);	// open output stream
+    if (_name[0]=='|')
+      {
+        char *cmdname = (char *)&_name[1];
+
+        int pipe_fd[2];
+
+        pipe(pipe_fd);
+
+        if (fork() == 0) // child
+          {
+
+            close(0); dup(pipe_fd[0]); close(pipe_fd[0]);
+
+            int num_args = 1;
+            char *p1, *p2;
+
+            p1=(char *)&cmdname[0]; p2=NULL;
+
+            while (*p1!='\0')
+              {
+                if (p2)
+                  {
+                    if ((*p1==' ') && (*p2!=' '))
+                      {
+                        // if passing from ' ' to another character, or 
+                        // from another character to ' ', there is an 
+                        // argument transition, so count it
+                        num_args++;
+                      }
+                  }
+
+                p2 = p1;
+                p1++;
+              }
+
+            int which_arg = 1; // 0 is the command
+            char *new_argv[num_args+1];
+            new_argv[0] = (char *)&cmdname[0];
+
+            p1=(char *)&cmdname[0]; p2=NULL;
+
+            while (*p1!='\0')
+              {
+                if (p2)
+                  {
+                    if ((*p1!=' ') && (*p2==' '))   
+                      {
+                        // if passing from ' ' to another character, or
+                        // from another character to ' ', there is an
+                        // argument transition, so count it
+                        new_argv[which_arg] = p1;
+                        *p2 = '\0';     // insert NULL to separate args
+                        which_arg++;
+                      }
+                  }
+
+                p2 = p1;
+                p1++;
+              }
+
+            new_argv[which_arg]=NULL;
+
+            char out_char = ' ';
+            write(pipe_fd[1], &out_char, 1);
+            close(pipe_fd[1]);
+
+            execvp(cmdname, &new_argv[1]);
+
+// if we get this far, the execvp() failed, probably due to a mis-typed
+// command.  We could use a smart error here!
+            exit(-1);
+
+          }
+        else // parent
+          {
+
+            char in_char;
+
+            read(pipe_fd[0], &in_char, 1);
+
+            close(pipe_fd[0]);  // unidirectional pipe
+
+            sleep(1);
+
+          }
+
+        _pstream = new ofstream(pipe_fd[1]);
+
+      }
+    else
+      {
+
+        _pstream = new ofstream(_name);	// open output stream
+
+      }
+
     return _pstream;
   }
  
@@ -175,6 +275,9 @@
     if (_pstream)
 	_pstream->close();
     delete _pstream;
+
+    if (_name[0] == '|') wait(NULL);
+
     _pstream = 0;
   }
 
