From c8d2c9316ef968e8d83ceb1b9ca1ee90298efe77 Mon Sep 17 00:00:00 2001
From: Stephen Paul Weber <singpolyma@singpolyma.net>
Date: Sun, 24 Apr 2011 16:33:48 -0500
Subject: [PATCH 17/18] Many fewer temp files

---
 src/core/Makefile |  1 +
 src/core/tools.c  | 43 +++++++++++++++++++------------------------
 2 files changed, 20 insertions(+), 24 deletions(-)

--- a/src/core/Makefile
+++ b/src/core/Makefile
@@ -11,6 +11,7 @@
 	rosters-tools.c \
 	stanzas.c \
 	tools.c \
+	popenRWE.c \
 	xep/chatstates.c \
 	xep/composing.c \
 	xep/datetime.c \
--- a/src/core/tools.c
+++ b/src/core/tools.c
@@ -27,6 +27,7 @@
 #include "settings.h"
 #include "signals.h"
 #include "xmpp-servers.h"
+#include "popenRWE.h"
 
 #define XMPP_PRIORITY_MIN -128
 #define XMPP_PRIORITY_MAX 127
@@ -35,9 +36,9 @@
 
 char *call_gpg(char *switches, char *input, char *input2, \
                int get_stderr, int snip_data) {
-	int pipefd[2], tmp_fd, tmp2_fd = 0, in_data = !snip_data;
-	FILE *cstream;
-	char *cmd, *tmp_path, *tmp2_path = NULL, *output = NULL;
+	int pipefd[2], rwepipe[3], childpid, tmp2_fd = 0, in_data = !snip_data;
+	FILE* cstream;
+	char *cmd, *tmp2_path = NULL, *output = NULL;
 	size_t output_size = 0;
 	char buf[100], buf2[100] = "";
 	const char *keyid = settings_get_str("xmpp_pgp");
@@ -45,19 +46,13 @@
 	if(keyid) { /* If no keyID, then we don't need a password */
 		if(pipe(pipefd)) goto pgp_error;
 		if(!pgp_passwd) pgp_passwd = get_password("OpenPGP Password:");
+		if(!pgp_passwd) goto pgp_error;
 
 		if(write(pipefd[1], pgp_passwd, strlen(pgp_passwd)) < 1) goto pgp_error;
 		if(close(pipefd[1])) goto pgp_error;
 	}
 
-	if(!(tmp_path = tempnam(NULL, "irssi-xmpp-gpg"))) goto pgp_error;
-	if((tmp_fd = open(tmp_path, O_WRONLY|O_CREAT|O_EXCL, \
-		 S_IRUSR|S_IWUSR)) < 0)
-		goto pgp_error;
-
-	if(write(tmp_fd, input, strlen(input)) < 0) goto pgp_error;
-
-	if(input2) {
+	if(input2) { /* NOTE for security it might be better if this were a named pipe */
 		if(!(tmp2_path = tempnam(NULL, "irssi-xmpp-gpg"))) goto pgp_error;
 		if((tmp2_fd = open(tmp2_path, O_WRONLY|O_CREAT|O_EXCL, \
 			 S_IRUSR|S_IWUSR)) < 0)
@@ -67,8 +62,8 @@
 	}
 
 	cmd = malloc(sizeof("gpg -u '' --passphrase-fd '' --trust-model always" \
-	              " -qo - --batch --no-tty '' '' 2>/dev/null") \
-	              +strlen(switches)+8+strlen(tmp_path)+ \
+	              " -qo - --batch --no-tty - ''") \
+	              +strlen(switches)+8+ \
 	              (tmp2_path ? strlen(tmp2_path) : 0));
 	if(keyid) {
 		sprintf(cmd, "gpg -u '%s' --passphrase-fd '%d' ", keyid, pipefd[0]);
@@ -76,9 +71,7 @@
 		strcpy(cmd, "gpg ");
 	}
 	strcat(cmd, switches);
-	strcat(cmd, " --trust-model always -qo - --batch --no-tty '");
-	strcat(cmd, tmp_path);
-	strcat(cmd, "' ");
+	strcat(cmd, " --trust-model always -qo - --batch --no-tty - ");
 
 	if(tmp2_path) {
 		strcat(cmd, "'");
@@ -86,14 +79,18 @@
 		strcat(cmd, "'");
 	}
 
+	fflush(NULL);
+	childpid = popenRWE(rwepipe, cmd);
+
+	if(write(rwepipe[0], input, strlen(input)) < 0) goto pgp_error;
+	if(close(rwepipe[0])) goto pgp_error;
+
 	if(get_stderr) {
-		strcat(cmd, " 2>&1");
+		cstream = fdopen(rwepipe[2], "r");
 	} else {
-		strcat(cmd, " 2>/dev/null");
+		cstream = fdopen(rwepipe[1], "r");
 	}
-
-	fflush(NULL);
-	cstream = popen(cmd, "r");
+	if(!cstream) goto pgp_error;
 
 	while(fgets(buf, sizeof(buf)-1, cstream)) {
 		if(strlen(buf2) > 0) {
@@ -121,14 +118,12 @@
 		strcat(output, buf2);
 	}
 
-	if(pclose(cstream) == 512) { /* TODO: more check exit code */
+	if(pcloseRWE(childpid, rwepipe) == 512) { /* TODO: more check exit code */
 		g_free(pgp_passwd);
 		pgp_passwd = NULL;
 		output = call_gpg(switches, input, input2, get_stderr, snip_data);
 	}
 
-	close(tmp_fd);
-	free(tmp_path);
 	if(tmp2_fd)   close(tmp2_fd);
 	if(tmp2_path) free(tmp2_path);
 	if(keyid)     close(pipefd[0]);
