Commits

Thejesh GN committed 3217111

initial

Comments (0)

Files changed (3)

+/* vi: set sw=4 ts=4: */
+/*
+ * Mini randomm implementation for busybox
+* Useful for making shell scripts do random actions. 
+*
+ *
+ * Copyright (C) 2002 Anonymous
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <utime.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include "busybox.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+extern int random_main(int argc, char **argv)
+{
+	int status = 0;
+	int opt;
+	int count = 0;
+	ssize_t fill =0;
+    char alpha[65] = 
+/* to be base 64 compatible, the last character should be "/", but
+  that's not filename safe, and I use this to generate random filenames
+*/
+	  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
+	struct stat statbuf;
+	int uf =-1;
+	unsigned char c;
+
+
+  if (stat("/dev/urandom", &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
+	uf= open("/dev/urandom", O_RDONLY );
+	if ( uf > -1 ){
+       for ( count=0 ; count < 3; count++) {
+		 fill=read ( uf, &c, 1);
+		 if (fill > 0) { break; } 
+		}
+	
+	 if ( fill != 1 ) { return -1; }
+	}
+  } else {
+	return -1;
+  }
+
+	while ((opt = getopt(argc, argv, "rbadnh")) != -1) {
+		switch (opt) {
+ 		case 'r': /* raw mode */
+			printf ( "%s\n" , &c );
+			break;
+		case 'd': /* Decimal 0-9*/
+			c = c % 10;
+			printf ( "%d\n", (int) c );
+			break;
+		case 'n': /* int from 0-254 */
+			printf ( "%d\n", (int) c );
+			break;
+		case 'b': /* binary 1 or 0 */
+		    if ( c < 128) { 
+				printf ("1\n");
+			} else {
+				printf ("0\n");
+			}
+			break;	
+		case 'a': /* one out of 64 filename safe characters only */
+			c = c % 64;
+			alpha[(c+1)]='\0';
+			printf ("%s\n", &alpha[c]);
+			break;
+		case 'h': /* one hex number */
+			c = c % 16;
+			printf ("%X\n", (int) c );
+			break;
+		default:
+			show_usage();
+		}
+	}
+
+	status = 1;
+	return status;
+}

src/gpggrid-version-on-floppy.c

+/* gpggrid : wrapper for gpg that lets you enter in the password    
+ * optionally stores passphrase in /tmp/ . This is fine if /tmp
+ * is an encrypted ramdisk and this is a single user machine. 
+ * Code is ugly, Error checking is missing.  I != coder. If you are, fix it. 
+ * TODO:
+ * Get by with less file opening & closing while still failing nicely?
+*/
+/*
+Copyright (c) 2002 Anonymous  (anonymous @ nameless.cultists.net)
+All rights reserved. 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:                                                  
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.                          
+* Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or 
+other materials provided with the distribution.                                                     
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES                                   
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                         
+*/
+
+
+
+
+
+#define FILENAME "/tmp/P"
+/*max passphrase size */
+#define PSIZE 256 
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+/* I'm only allowing characters that most people might 
+ actually know what to do with:
+EOT, BEL &etc are out as is newline, which leaves us with ASCII
+8-10,32-128 
+High ascii  could be added, but I haven't checked for nastys
+*/
+
+/* 94 plus 5 unprintables */
+static char printable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{|}~[\\]^_`!\"#$%&\'()*+,-./:;<=>?@";
+/* ASCII order="!\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; */
+
+char row[27];
+char column[10];
+char passphrase[PSIZE+2];
+char SHOWPF=0;
+
+int buildgrid ( char * rand ) {
+  unsigned char a, b, c ;
+  char  * xzero, * yzero;
+  /* char check;*/
+  int i;
+  a = b = c =0;
+
+/* print the static header */ 
+  xzero = &printable[0] + rand[0];
+  i = &printable[26] - xzero;
+  snprintf(row, (size_t) (i+1), "%s", xzero);
+  snprintf(&row[i], (size_t) (rand[0] +1), "%s", &printable[0]);
+  printf ("\n   ");
+  for (i=0;i < 26; i++) {
+    printf("%c ",row[i]);
+  }
+  printf ("\n");
+
+  yzero= &printable[26] +rand[1];
+  i = &printable[52] - yzero ;
+  if (i > 9) { i=9; }
+  snprintf(column, (size_t) (i+1), "%s", yzero);
+  if (i < 9) {
+    snprintf(&column[i], (size_t) (10 -i ), "%s", &printable[26]);
+  }
+  for (i = 0; i < 94; i++) { /*sizeof printable */
+    if ( (i%26) == 0) {
+      printf ("\n"); 
+      printf ("%c  ", column[c]);
+      c++;
+    }
+    printf ("%c ", printable[i]); 
+  }
+ /* UI is hard... Separate lines for these */
+  printf ("\n%c   Backspace ", column[c++]);
+  printf ("\n%c   Tab ", column[c++]);
+  printf ("\n%c   Enter (stop entering characters)  ", column[c++]);
+  printf ("\n%c   Space ", column[c++]);
+  printf ("\n%c   Delete\n\n", column[c++]);
+  return 1;
+}
+
+
+int  getcords ( char * key) {
+char * count, *here;
+int i,ii;
+char x,y;
+char buffer[PSIZE];
+int M=0;
+
+ while ( y==0) {
+   printf("Enter grid column (lowercase) then row (uppercase):");
+   count = fgets( buffer, PSIZE, stdin);
+   if( count != NULL) {
+     for (i=0;i<9;i++){
+       if ( column[i] == count[0]) { 
+	 for (ii=0;ii<26;ii++){ /*or strstr*/
+	   if ( row[ii] == count[1]) { 
+	     x=count[1];
+	     break;
+	   }
+	 }
+	 y=count[0]; 
+       }
+     }
+   }
+ }
+
+ while ( x==0) {
+   printf ("\nplease enter row (CAPS) grid letter: ");
+   count = fgets( buffer, PSIZE, stdin);
+   if( count != NULL) {
+     for (i=0;i<26;i++){
+       if ( row[i] == count[0]) {x=count[0];}
+     }
+   }
+ }
+
+/* figure out how many rows down we are */
+ here = strchr(&column[0], (int) y);
+ M  = 26 * ( here - &column[0]);
+ here = strchr(row,(int)x);
+ M  = M + (here - &row[0]);
+ 
+ if (M > 93)  {
+   switch (M/26) {
+   case 4:
+     strcpy(key,"Backspace");
+     return 2;
+     break;
+   case 5:
+     sprintf(key,"\t");
+     return 1;
+     break;
+   case 6:
+     strcpy(key,"\n"); /* good idea?, I doubt it */
+     return 3;
+     break;
+   case 7:
+     sprintf(key," ");
+     return 1;
+     break;
+   case 8:
+     strcpy(key,"Delete");
+     return 2;
+     break;
+   default:	
+     strcpy(key,"ERR");
+     return -1;
+     break;
+   }
+ } else {
+   *key = printable[M];
+/*	printf ("%d You seem to have chosen %c,%c ,which is %c\n",M, y,x, *key);*/
+   return 1;
+ }
+} 
+
+void fillrand ( char * randbuf, int rs) {
+  printf( "your random is %s", randbuf);
+}
+
+int getpassphrase () {
+char x;
+unsigned char crand[3];
+extern char passphrase[PSIZE+2];
+int check, c;
+int rs=-1;
+char thischar[12];
+char * curletter;
+struct stat statbuf;
+extern char SHOWPF;
+curletter=passphrase;
+
+/* initialize random source */
+ if (stat("/dev/urandom", &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
+   rs= open("/dev/urandom", O_RDONLY );
+   if ( rs < 0 ){
+     perror ("Can't open random source ");
+     exit;
+   } 
+ } else {
+   perror ("Can't find random source ");
+ }
+
+/*add count to check size is less than PSIZE */
+ x=0; c=0;
+ while (x != 3) {
+   if (SHOWPF == 2) { 
+     printf("\n>>%s\n",passphrase);
+   }
+/* reduce to 1 byte */
+   check=read ( rs, crand,2);
+   crand[0] = (crand[0] %26 );
+   crand[1] = (crand[1] %26 );
+   buildgrid (&crand[0]);
+   x =  getcords (&thischar[0]);
+   
+   switch (x) {
+   case 1: 
+     /* if not 257 */   
+     *curletter=thischar[0];
+     printf ("\n\n\n\n\n");
+     if (SHOWPF == 1) {
+       printf ("Last letter was %c \n", *curletter);
+     }
+     curletter++;
+     break;
+   case -1:
+     printf ("please try again \n");
+     break;
+   case 2: /* DEL or backspace */  
+     if ( curletter >= &passphrase[0]) {
+       curletter--;
+       *curletter='\0';
+     } 
+     break;
+   case 3: /* Enter */
+     /* log size of passphrase here */ 
+     return 1;
+   }
+ }  
+ return 0;
+}
+
+
+int main (int argc, char *argv[]) {
+extern char passphrase[PSIZE+2];
+char buffer[PSIZE+4];
+char * count;
+ssize_t pushed, foo;
+extern char SHOWPF;
+char fd_name[6];
+int i, fd_out, fd_gpg;
+char *exec_argv[(argc+4)]; /* BUG: should be enough*/
+struct stat statbuf;
+
+ memset (&passphrase,NULL, sizeof(passphrase));
+ memset (&fd_name,NULL, sizeof(fd_name));
+
+/* check if we already have a cached passphrase */
+ if ((fd_out= open (FILENAME,O_RDONLY, 0600)) == -1 ) {
+   perror ("Damn, can't open passphrase file") ;
+ } else {
+   pushed = read ( fd_out, passphrase, (PSIZE+1) );
+   /* BUG, don't find 1 char short */
+   if ( pushed  <0 ) {
+     perror ("Whoah, writing went strange:");
+   }
+   close (fd_out);
+ }
+
+ if (strlen(passphrase) ==0) {
+   perror ("stat failed:");
+/* Ask if we want to display the passphrase */
+   printf("By default, you will see the last letter you entered. Do you \nwant to display the entire passphrase on the screen instead? \n");
+   printf ("select y for full passphrase, b for no feedback, n for default\n");
+   printf (" [y/b/N]\n");
+
+   count = fgets( buffer, PSIZE, stdin);
+   switch (count[0]) {
+   case 'y':
+   case 'Y':
+     SHOWPF = 2;
+     break;
+   case 'b':
+   case 'B':
+     SHOWPF = 0;
+     break;
+   default:
+     SHOWPF = 1;
+     break;
+   }
+   getpassphrase();
+ 
+/* Ask if we want to save the passphrase */
+
+   printf ("\n\n GPGgrid can store your passphrase on the RAMdisk and re-use \n it later. This saves a lot of time, but does leave the passphrase vulnerable \n  until reboot.\n"); 
+
+   printf("Do you want to store the passphrase in RAM ? [Y/n]\n");
+   count = fgets( buffer, PSIZE, stdin);
+   if ( count[0] != 'n' && count[0] != 'N') {
+     /* write to disk */
+     printf ("writing to disk\n" );
+     if (stat(FILENAME, &statbuf) == 0 && ( S_ISREG(statbuf.st_mode) )) {
+       if ((fd_out= open (FILENAME,O_RDWR | O_CREAT |O_TRUNC , 0600)) == -1 ) {
+	 perror ("Damn, can't write passphrase file") ;
+       }
+       /* BUG: truly lame. Need a write wrapper program */
+       pushed=strlen(passphrase);
+       foo= write(fd_out, passphrase, strlen(passphrase));
+       if (foo != pushed ) {
+	 perror ("can't write out the passphrase: "); 
+       }
+       close (fd_out) ;
+     }
+   }
+ }
+
+ if (SHOWPF == 2)  { 
+   printf("Final result:: %s\n", &passphrase[0]); 
+ }
+ 
+/* OK, we're ready to run GPG */
+ printf ("Running GPG with %u args \n", argc);
+ if ((fd_gpg= open (FILENAME,O_RDONLY, 0600)) == -1 ) {
+   perror ("Damn, can't read passphrase file") ;
+ }
+ sprintf(&fd_name[0], "%d",fd_gpg);
+
+ exec_argv[0]="gpg";
+ exec_argv[1]="--passphrase-fd";
+ exec_argv[2]=&fd_name[0] ;
+ for (i= 1; i <= argc ; i++) {
+   exec_argv[i+2]=argv[i];
+ }
+ execvp ("gpg", exec_argv );
+ return -1;
+}
+/* gpggrid : wrapper for gpg that lets you enter in the password    
+ * optionally stores passphrase in /tmp/ . This is fine if /tmp
+ * is an encrypted ramdisk and this is a single user machine. 
+*/
+
+/*
+Copyright (c) 2002 Anonymous  (anonymous @ nameless.cultists.net)
+                   Morten Poulsen <morten@afdelingp.dk>
+All rights reserved. 
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:                                                  
+* Redistributions of source code must retain the above copyright notice, this 
+list of conditions and the following disclaimer.                          
+* Redistributions in binary form must reproduce the above copyright notice, 
+this list of conditions and the following disclaimer in the documentation 
+and/or other materials provided with the distribution.                                                     
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                         
+*/
+
+/* CHANGES
+* 1.1 release,  code was substantially improved by Morten Poulsen. 
+* User options made somewhat clearer. 
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#define FILENAME "/tmp/P"
+#define PSIZE 256  /* max passphrase size */
+
+#define OUT 0
+#define IN  1
+
+/* I'm only allowing characters that most people might 
+   actually know what to do with:
+   EOT, BEL &etc are out as is newline, which leaves us with ASCII
+   8-10,32-128 
+   High ascii could be added, but I haven't checked for nastys
+*/
+
+/* 94 plus 5 unprintables */
+static char printable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{|}~[\\]^_`!\"#$%&\'()*+,-./:;<=>?@";
+/* ASCII order="!\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; */
+
+char column[26];
+char row[9];
+char passphrase[PSIZE+2];
+char SHOWPF=0;
+
+void buildgrid(char *rand) {
+  int i, r;
+
+  printf ("   ");
+  for (i=0; i<26; i++) {
+    column[i] = printable[0 + ((i+rand[0]) % 26)];
+    printf("%c ", column[i]);
+  }
+  printf ("\n");
+
+  for (i=0; i<9; i++) {
+    row[i] = printable[26 + ((i+rand[1]) % 26)];
+  }
+
+  r = 0;
+  for (i=0; i<strlen(printable); i++) {
+    if ((i % 26) == 0) {
+      printf ("\n"); 
+      printf ("%c  ", row[r++]);
+    }
+    printf ("%c ", printable[i]); 
+  }
+
+  /* UI is hard... Separate lines for these */
+  printf ("\n%c   Backspace", row[r++]);
+  printf ("\n%c   Tab", row[r++]);
+  printf ("\n%c   Enter (stop entering characters)", row[r++]);
+  printf ("\n%c   Space", row[r++]);
+  printf ("\n%c   Delete\n\n", row[r++]);
+}
+
+
+int getcoords (char *key) {
+  char *count;
+  int i;
+  int x = 0, y = 0;
+  char buffer[PSIZE];
+  int M = 0;
+  int xok = 0, yok = 0;
+
+  do {
+    printf("Enter vertical row (lowercase) then horizontal column (UPPERCASE): ");
+    count = fgets(buffer, PSIZE, stdin);
+
+    if (count) {
+      for (i=0; i<9; i++) {
+        if (buffer[0] == row[i]) { 
+          y = i; 
+          yok = 1;
+          break;
+        }
+      }
+      for (i=0; i<26; i++) {
+        if (buffer[1] == column[i]) { 
+          x = i;
+          xok = 1;
+          break;
+        }
+      }
+    }
+
+  } while (!yok);
+
+  /* Be nice to people who accidentally press enter too early */
+  while (!xok) {
+    printf("Please enter horizontal column (UPPER CASE) grid letter: ");
+    count = fgets(buffer, PSIZE, stdin);
+
+    if (count) {
+      for (i=0; i<26; i++) {
+        if (buffer[0] == column[i]) { 
+          x = i;
+          xok = 1;
+          break;
+        }
+      }
+    }
+  }
+
+  M  = 26 * y + x;
+ 
+  if (M > 93)  {
+    switch (M/26) {
+      case 4:
+        strcpy(key, "Backspace");
+        return 2;
+      case 5:
+        strcpy(key, "\t");
+        return 1;
+      case 6:
+        strcpy(key, "\n"); 
+        return 3;
+      case 7:
+        strcpy(key, " ");
+        return 1;
+      case 8:
+        strcpy(key, "Delete");
+        return 2;
+      default:    
+        strcpy(key, "ERR");
+        return -1;
+    }
+
+  } else {
+    *key = printable[M];
+/*    printf ("%d You seem to have chosen %c,%c ,which is %c\n",M, y,x, *key);*/
+    return 1;
+  }
+} 
+
+
+int getpassphrase() {
+  char x;
+  unsigned char crand[3];
+  extern char passphrase[PSIZE+2];
+  int check, c;
+  int rs=-1;
+  char thischar[12];
+  char *curletter;
+  struct stat statbuf;
+  extern char SHOWPF;
+  
+  curletter = passphrase;
+
+  /* initialize random source */
+  if (stat("/dev/urandom", &statbuf) != 0 || !S_ISCHR(statbuf.st_mode)) {
+    perror ("Can't find random source");
+    exit(EXIT_FAILURE);
+  } else {
+    rs = open("/dev/urandom", O_RDONLY);
+    if (rs < 0) {
+      perror("Can't open random source");
+      exit(EXIT_FAILURE);
+    } 
+  }
+
+  x=0; c=0;
+  while (x != 3) {
+    printf("\n\n\n\n\n");
+
+    if (SHOWPF == 2) { 
+      printf(">>%s\n\n", passphrase);
+    }
+
+    check = read(rs, crand, 2);
+    crand[0] = (crand[0] % 26);
+    crand[1] = (crand[1] % 26);
+    buildgrid(crand);
+
+    x = getcoords(thischar);
+
+    switch (x) {
+      case 1: 
+        /* if not 257 */   
+        *curletter = *thischar;
+        if (SHOWPF == 1) {
+           printf ("Letter was %c\n\n", *curletter);
+        }
+        curletter++;
+        break;
+      case -1:
+        printf ("please try again\n");
+        break;
+      case 2: /* DEL or backspace */  
+        if (curletter >= passphrase) {
+          curletter--;
+          *curletter = '\0';
+        } 
+        break;
+      case 3: /* Enter */
+  /* should truncate passphrase at PSIZE.   */
+        return 1;
+    }
+  }  
+  return 0;
+}
+
+
+int main (int argc, char **argv) {
+  extern char passphrase[PSIZE+2];
+  char buffer[PSIZE+4];
+  char *count;
+  ssize_t foo;
+  extern char SHOWPF;
+  char fd_name[6];
+  int i, fd_out;
+  char *exec_argv[(argc+4)]; /* BUG: hardcoded, but should be enough */
+  struct stat statbuf;
+  int p[2];
+
+  memset(&passphrase, 0, sizeof(passphrase));
+  memset(&fd_name, 0, sizeof(fd_name));
+ 
+  /* check if we already have a cached passphrase */
+  if ((fd_out = open(FILENAME, O_RDONLY)) > 0) {
+    printf("Using stored passphrase.\n");
+    read(fd_out, passphrase, (PSIZE+1));
+    /* We don't need to check for errors. If it fails, the user is asked for
+       passphrase anyway. */
+    close(fd_out);
+  }
+
+  if (strlen(passphrase) == 0) {
+    /* Ask if we want to display the passphrase */
+    printf("By default, you will see the last letter you entered. Do you\n");
+    printf("want to display the entire passphrase on the screen instead?\n");
+    printf("select y for full passphrase, n for no feedback, d for default\n");
+    printf(" [y/n/D]\n");
+
+    count = fgets( buffer, PSIZE, stdin);
+    switch (buffer[0]) {
+      case 'y':
+      case 'Y':
+        SHOWPF = 2;
+        break;
+      case 'n':
+      case 'N':
+        SHOWPF = 0;
+        break;
+      default:
+        SHOWPF = 1;
+        break;
+    }
+
+    getpassphrase();
+ 
+    /* Ask if we want to save the passphrase */
+    printf("\n\nGPGgrid can store your passphrase on the RAMdisk and re-use\n");
+    printf("it later. This saves a lot of time, but does leave the passphrase vulnerable\n");
+    printf("until reboot.\n"); 
+    printf("Do you want to store the passphrase in /tmp ? [Y/n]\n");
+    count = fgets(buffer, PSIZE, stdin);
+
+    if (buffer[0] != 'n' && buffer[0] != 'N') {
+
+      /* write to disk */
+      printf ("Writing passphrase to disk.\n" );
+      if ((stat(FILENAME, &statbuf) == 0) && (!S_ISREG(statbuf.st_mode))) {
+        printf(FILENAME " is not a regular file\n");
+      } else {
+        if ((fd_out = open(FILENAME, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
+          perror("can't open passphrase file for writing") ;
+        } else {
+          foo = write(fd_out, passphrase, strlen(passphrase));
+          if (foo != strlen(passphrase)) {
+            perror("can't write out the passphrase"); 
+          }
+          close (fd_out) ;
+        }
+      }
+    }
+  }
+
+  if (SHOWPF == 2)  { 
+    printf("Final result: %s\n", passphrase); 
+  }
+ 
+  /* OK, we're ready to run GPG */
+
+  if (pipe(p) == -1) {
+    perror("unable to create pipe");
+    exit(EXIT_FAILURE);
+  }
+
+  switch (fork()) {
+
+    case -1:  /* failure */
+      perror("unable to fork");
+      exit(EXIT_FAILURE);
+
+    case 0:  /* child */
+      close(p[OUT]);
+      write(p[IN], passphrase, strlen(passphrase));
+      close(p[IN]);
+      exit(EXIT_SUCCESS);
+
+    default:  /* parent */
+      close(p[IN]);
+      sprintf(fd_name, "%d", p[OUT]);
+      exec_argv[0] = "gpg";
+      exec_argv[1] = "--passphrase-fd";
+      exec_argv[2] = fd_name;
+      for (i=1; i<=argc; i++) {  /* <= to get the NULL pointer too */
+        exec_argv[i+2] = argv[i];
+      }
+      execvp("gpg", exec_argv);
+      exit(EXIT_FAILURE);
+  }
+
+  /* never reached */
+  return EXIT_FAILURE;
+
+}