libkpgp

kpgpbase.cpp
1/*
2 kpgpbase.cpp
3
4 Copyright (C) 2001,2002 the KPGP authors
5 See file AUTHORS.kpgp for details
6
7 This file is part of KPGP, the KDE PGP/GnuPG support library.
8
9 KPGP is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <kdebug.h>
20
21#include <config.h>
22
23#include "kpgpbase.h"
24#include "kpgp.h"
25#include "kpgpblock.h"
26
27#include <stdlib.h> /* setenv, unsetenv */
28#include <unistd.h> /* pipe, close, fork, dup2, execl, _exit, write, read */
29#include <sys/poll.h> /* poll, etc. */
30#include <sys/types.h> /* pid_t */
31#include <sys/wait.h> /* waitpid */
32#include <errno.h>
33
34#include <tqapplication.h>
35
36
37namespace Kpgp {
38
39Base::Base()
40 : input(), output(), error(), errMsg(), status(OK)
41{
42}
43
44
45Base::~Base()
46{
47}
48
49
50void
51Base::clear()
52{
53 input = TQCString();
54 output = TQCString();
55 error = TQCString();
56 errMsg = TQString();
57 status = OK;
58}
59
60
61int
62Base::run( const char *cmd, const TQString &passphrase, bool onlyReadFromPGP )
63{
64 /* the pipe ppass is used for to pass the password to
65 * pgp. passing the password together with the normal input through
66 * stdin doesn't seem to work as expected (at least for pgp5.0)
67 */
68 char str[1025] = "\0";
69 int pin[2], pout[2], perr[2], ppass[2];
70 int len, len2;
71 FILE *pass;
72 pid_t child_pid;
73 int childExiStatus;
74 struct pollfd pollin, pollout, pollerr;
75 int pollstatus;
76
77 if (!passphrase.isEmpty())
78 {
79 if (pipe(ppass) < 0) {
80 // An error occurred
81 // FIXME
82 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
83 }
84
85 pass = fdopen(ppass[1], "w");
86 TQCString pass2 = passphrase.local8Bit();
87 fwrite(pass2, sizeof(char), pass2.length(), pass);
88 fwrite("\n", sizeof(char), 1, pass);
89 fclose(pass);
90 close(ppass[1]);
91
92 // tell pgp which fd to use for the passphrase
93 TQCString tmp;
94 tmp.sprintf("%d",ppass[0]);
95 ::setenv("PGPPASSFD",tmp.data(),1);
96
97 //Uncomment these lines for testing only! Doing so will decrease security!
98 //kdDebug(5100) << "pgp PGPPASSFD = " << tmp << endl;
99 //kdDebug(5100) << "pgp pass = " << passphrase << endl;
100 }
101 else
102 ::unsetenv("PGPPASSFD");
103
104 //Uncomment these lines for testing only! Doing so will decrease security!
105 kdDebug(5100) << "pgp cmd = " << cmd << endl;
106 //kdDebug(5100) << "pgp input = " << TQString(input)
107 // << "input length = " << input.length() << endl;
108
109 error = "";
110 output = "";
111
112 if (pipe(pin) < 0) {
113 // An error occurred
114 // FIXME
115 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
116 }
117 if (pipe(pout) < 0) {
118 // An error occurred
119 // FIXME
120 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
121 }
122 if (pipe(perr) < 0) {
123 // An error occurred
124 // FIXME
125 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
126 }
127
128 TQApplication::flushX();
129 if(!(child_pid = fork()))
130 {
131 /*We're the child.*/
132 close(pin[1]);
133 dup2(pin[0], 0);
134 close(pin[0]);
135
136 close(pout[0]);
137 dup2(pout[1], 1);
138 close(pout[1]);
139
140 close(perr[0]);
141 dup2(perr[1], 2);
142 close(perr[1]);
143
144 execl("/bin/sh", "sh", "-c", cmd, (void *)0);
145 _exit(127);
146 }
147
148 /*Only get here if we're the parent.*/
149 close(pin[0]);
150 close(pout[1]);
151 close(perr[1]);
152
153 // poll for "There is data to read."
154 pollout.fd = pout[0];
155 pollout.events = POLLIN;
156 pollout.revents = 0; // init with 0, just in case
157 pollerr.fd = perr[0];
158 pollerr.events = POLLIN;
159 pollerr.revents = 0; // init with 0, just in case
160
161 // poll for "Writing now will not block."
162 pollin.fd = pin[1];
163 pollin.events = POLLOUT;
164 pollin.revents = 0; // init with 0, just in case
165
166 if (!onlyReadFromPGP) {
167 if (!input.isEmpty()) {
168 // write to pin[1] one line after the other to prevent dead lock
169 uint input_length = input.length();
170 for (unsigned int i=0; i<input_length; i+=len2) {
171 len2 = 0;
172
173 // check if writing now to pin[1] will not block (5 ms timeout)
174 //kdDebug(5100) << "Polling pin[1]..." << endl;
175 pollstatus = poll(&pollin, 1, 5);
176 if (pollstatus == 1) {
177 //kdDebug(5100) << "Status for polling pin[1]: " << pollin.revents << endl;
178 if (pollin.revents & POLLERR) {
179 kdDebug(5100) << "PGP seems to have hung up" << endl;
180 break;
181 }
182 else if (pollin.revents & POLLOUT) {
183 // search end of next line
184 if ((len2 = input.find('\n', i)) == -1)
185 len2 = input_length - i;
186 else
187 len2 = len2 - i + 1;
188
189 //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
190 len2 = write(pin[1], input.data() + i, len2);
191 //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
192 }
193 }
194 else if (!pollstatus) {
195 //kdDebug(5100) << "Timeout while polling pin[1]: "
196 // << pollin.revents << endl;
197 }
198 else if (pollstatus == -1) {
199 kdDebug(5100) << "Error while polling pin[1]: "
200 << pollin.revents << endl;
201 }
202
203 if (pout[0] >= 0) {
204 do {
205 // check if there is data to read from pout[0]
206 //kdDebug(5100) << "Polling pout[0]..." << endl;
207 pollstatus = poll(&pollout, 1, 0);
208 if (pollstatus == 1) {
209 //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
210 if (pollout.revents & POLLIN) {
211 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
212 if ((len = read(pout[0],str,1024))>0) {
213 //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
214 str[len] ='\0';
215 output += str;
216 }
217 else
218 break;
219 }
220 }
221 else if (pollstatus == -1) {
222 kdDebug(5100) << "Error while polling pout[0]: "
223 << pollout.revents << endl;
224 }
225 } while ((pollstatus == 1) && (pollout.revents & POLLIN));
226 }
227
228 if (perr[0] >= 0) {
229 do {
230 // check if there is data to read from perr[0]
231 //kdDebug(5100) << "Polling perr[0]..." << endl;
232 pollstatus = poll(&pollerr, 1, 0);
233 if (pollstatus == 1) {
234 //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
235 if (pollerr.revents & POLLIN) {
236 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
237 if ((len = read(perr[0],str,1024))>0) {
238 //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
239 str[len] ='\0';
240 error += str;
241 }
242 else
243 break;
244 }
245 }
246 else if (pollstatus == -1) {
247 kdDebug(5100) << "Error while polling perr[0]: "
248 << pollerr.revents << endl;
249 }
250 } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
251 }
252
253 // abort writing to PGP if PGP hung up
254 if ((pollstatus == 1) &&
255 ((pollout.revents & POLLHUP) || (pollerr.revents & POLLHUP))) {
256 kdDebug(5100) << "PGP hung up" << endl;
257 break;
258 }
259 }
260 }
261 else { // if input.isEmpty()
262 if (write(pin[1], "\n", 1) < 0) {
263 // An error occurred
264 // FIXME
265 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
266 }
267 }
268 //kdDebug(5100) << "All input was written to pin[1]" << endl;
269 }
270 close(pin[1]);
271
272 pid_t waitpidRetVal;
273
274 do {
275 //kdDebug(5100) << "Checking if PGP is still running..." << endl;
276 childExiStatus = 0;
277 waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
278 //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
279 if (pout[0] >= 0) {
280 do {
281 // check if there is data to read from pout[0]
282 //kdDebug(5100) << "Polling pout[0]..." << endl;
283 pollstatus = poll(&pollout, 1, 0);
284 if (pollstatus == 1) {
285 //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
286 if (pollout.revents & POLLIN) {
287 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
288 if ((len = read(pout[0],str,1024))>0) {
289 //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
290 str[len] ='\0';
291 output += str;
292 } else {
293 /*
294 * Apparently, on NetBSD when the child dies, the pipe begins
295 * receiving empty data packets *before* waitpid() has signaled
296 * that the child has died. Also, notice that this happens
297 * without any error bit being set in pollfd.revents (is this a
298 * NetBSD bug??? ). Notice that these anomalous packets exist
299 * according to poll(), but have length 0 according to read().
300 * Thus, kde can remain stuck inside this loop.
301 *
302 * A solution to this problem is to get out of the inner loop
303 * when read() returns <=0. In this way, kde has another chance
304 * to call waitpid() to check if the child has died -- and this
305 * time the call should succeed.
306 *
307 * Setting POLLHUP in pollfd.revents is not necessary, but I just
308 * like the idea of signaling that something strange has
309 * happened.
310 */
311 pollout.revents |= POLLHUP;
312 break;
313 }
314 }
315 }
316 else if (pollstatus == -1) {
317 kdDebug(5100) << "Error while polling pout[0]: "
318 << pollout.revents << endl;
319 }
320 } while ((pollstatus == 1) && (pollout.revents & POLLIN));
321 }
322
323 if (perr[0] >= 0) {
324 do {
325 // check if there is data to read from perr[0]
326 //kdDebug(5100) << "Polling perr[0]..." << endl;
327 pollstatus = poll(&pollerr, 1, 0);
328 if (pollstatus == 1) {
329 //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
330 if (pollerr.revents & POLLIN) {
331 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
332 if ((len = read(perr[0],str,1024))>0) {
333 //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
334 str[len] ='\0';
335 error += str;
336 } else {
337 /*
338 * Apparently, on NetBSD when the child dies, the pipe begins
339 * receiving empty data packets *before* waitpid() has signaled
340 * that the child has died. Also, notice that this happens
341 * without any error bit being set in pollfd.revents (is this a
342 * NetBSD bug??? ). Notice that these anomalous packets exist
343 * according to poll(), but have length 0 according to read().
344 * Thus, kde can remain stuck inside this loop.
345 *
346 * A solution to this problem is to get out of the inner loop
347 * when read() returns <=0. In this way, kde has another chance
348 * to call waitpid() to check if the child has died -- and this
349 * time the call should succeed.
350 *
351 * Setting POLLHUP in pollfd.revents is not necessary, but I just
352 * like the idea of signaling that something strange has
353 * happened.
354 */
355 pollerr.revents |= POLLHUP;
356 break;
357 }
358 }
359 }
360 else if (pollstatus == -1) {
361 kdDebug(5100) << "Error while polling perr[0]: "
362 << pollerr.revents << endl;
363 }
364 } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
365 }
366 } while (waitpidRetVal == 0);
367
368 close(pout[0]);
369 close(perr[0]);
370
371 unsetenv("PGPPASSFD");
372 if (!passphrase.isEmpty())
373 close(ppass[0]);
374
375 // Did the child exit normally?
376 if (WIFEXITED(childExiStatus) != 0) {
377 // Get the return code of the child
378 childExiStatus = WEXITSTATUS(childExiStatus);
379 kdDebug(5100) << "PGP exited with exit status " << childExiStatus
380 << endl;
381 }
382 else {
383 childExiStatus = -1;
384 kdDebug(5100) << "PGP exited abnormally!" << endl;
385 }
386
387 //Uncomment these lines for testing only! Doing so will decrease security!
388 //kdDebug(5100) << "pgp output = " << TQString(output) << endl;
389 //kdDebug(5100) << "pgp error = " << error << endl;
390
391 /* Make the information visible, so that a user can
392 * get to know what's going on during the pgp calls.
393 */
394 kdDebug(5100) << error << endl;
395
396 return childExiStatus;
397}
398
399
400int
401Base::runGpg( const char *cmd, const TQString &passphrase, bool onlyReadFromGnuPG )
402{
403 /* the pipe ppass is used for to pass the password to
404 * pgp. passing the password together with the normal input through
405 * stdin doesn't seem to work as expected (at least for pgp5.0)
406 */
407 char str[1025] = "\0";
408 int pin[2], pout[2], perr[2], ppass[2];
409 int len, len2;
410 FILE *pass;
411 pid_t child_pid;
412 int childExiStatus;
413 char gpgcmd[1024] = "\0";
414 struct pollfd poller[3];
415 int num_pollers = 0;
416 const int STD_OUT = 0;
417 const int STD_ERR = 1;
418 const int STD_IN = 2;
419 int pollstatus;
420
421 if (!passphrase.isEmpty())
422 {
423 if (pipe(ppass) < 0) {
424 // An error occurred
425 // FIXME
426 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
427 }
428
429 pass = fdopen(ppass[1], "w");
430 TQCString pass2 = passphrase.local8Bit();
431 fwrite(pass2, sizeof(char), pass2.length(), pass);
432 fwrite("\n", sizeof(char), 1, pass);
433 fclose(pass);
434 close(ppass[1]);
435
436 //Uncomment these lines for testing only! Doing so will decrease security!
437 //kdDebug(5100) << "pass = " << passphrase << endl;
438 }
439
440 //Uncomment these lines for testing only! Doing so will decrease security!
441 //kdDebug(5100) << "pgp cmd = " << cmd << endl;
442 //kdDebug(5100) << "pgp input = " << TQString(input)
443 // << "input length = " << input.length() << endl;
444
445 error = "";
446 output = "";
447
448 if (pipe(pin) < 0) {
449 // An error occurred
450 // FIXME
451 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
452 }
453 if (pipe(pout) < 0) {
454 // An error occurred
455 // FIXME
456 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
457 }
458 if (pipe(perr) < 0) {
459 // An error occurred
460 // FIXME
461 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
462 }
463
464 if (!passphrase.isEmpty()) {
465 if( mVersion >= "1.0.7" ) {
466 // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
467 if( 0 == getenv("GPG_AGENT_INFO") ) {
468 // gpg-agent not found, so we tell gpg not to use the agent
469 snprintf( gpgcmd, 1023,
470 "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
471 ppass[0], cmd );
472 }
473 else {
474 // gpg-agent seems to be running, so we tell gpg to use the agent
475 snprintf( gpgcmd, 1023,
476 "LANGUAGE=C gpg --use-agent %s",
477 cmd );
478 }
479 }
480 else {
481 // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
482 snprintf( gpgcmd, 1023,
483 "LANGUAGE=C gpg --passphrase-fd %d %s",
484 ppass[0], cmd );
485 }
486 }
487 else {
488 snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
489 }
490
491 TQApplication::flushX();
492 if(!(child_pid = fork()))
493 {
494 /*We're the child.*/
495 close(pin[1]);
496 dup2(pin[0], 0);
497 close(pin[0]);
498
499 close(pout[0]);
500 dup2(pout[1], 1);
501 close(pout[1]);
502
503 close(perr[0]);
504 dup2(perr[1], 2);
505 close(perr[1]);
506
507 //#warning FIXME: there has to be a better way to do this
508 /* this is nasty nasty nasty (but it works) */
509 if (!passphrase.isEmpty()) {
510 if( mVersion >= "1.0.7" ) {
511 // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
512 if( 0 == getenv("GPG_AGENT_INFO") ) {
513 // gpg-agent not found, so we tell gpg not to use the agent
514 snprintf( gpgcmd, 1023,
515 "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
516 ppass[0], cmd );
517 }
518 else {
519 // gpg-agent seems to be running, so we tell gpg to use the agent
520 snprintf( gpgcmd, 1023,
521 "LANGUAGE=C gpg --use-agent %s",
522 cmd );
523 }
524 }
525 else {
526 // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
527 snprintf( gpgcmd, 1023,
528 "LANGUAGE=C gpg --passphrase-fd %d %s",
529 ppass[0], cmd );
530 }
531 }
532 else {
533 snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
534 }
535
536 kdDebug(5100) << "pgp cmd = " << gpgcmd << endl;
537
538 execl("/bin/sh", "sh", "-c", gpgcmd, (void *)0);
539 _exit(127);
540 }
541
542 // Only get here if we're the parent.
543
544 close(pin[0]);
545 close(pout[1]);
546 close(perr[1]);
547
548 // poll for "There is data to read."
549 poller[STD_OUT].fd = pout[0];
550 poller[STD_OUT].events = POLLIN;
551 poller[STD_ERR].fd = perr[0];
552 poller[STD_ERR].events = POLLIN;
553 num_pollers = 2;
554
555 if (!onlyReadFromGnuPG) {
556 // poll for "Writing now will not block."
557 poller[STD_IN].fd = pin[1];
558 poller[STD_IN].events = POLLOUT;
559 num_pollers = 3;
560 } else {
561 close (pin[1]);
562 pin[1] = -1;
563 }
564
565 pid_t waitpidRetVal;
566 unsigned int input_pos = 0;
567 uint input_length = input.length();
568
569 do {
570 //kdDebug(5100) << "Checking if GnuPG is still running..." << endl;
571 childExiStatus = 0;
572 waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
573 //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
574 do {
575 // poll the pipes
576 pollstatus = poll(poller, num_pollers, 10);
577 if( 0 < pollstatus ) {
578 // Check stdout.
579 if (poller[STD_OUT].revents & POLLIN) {
580 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
581 if ((len = read(pout[0],str,1024))>0) {
582 //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
583 str[len] ='\0';
584 output += str;
585 }
586 else {
587 // FreeBSD/NetBSD workaround
588 //
589 // Apparently, on Free/NetBSD when the child dies, the pipe begins
590 // receiving empty data packets *before* waitpid() has signaled
591 // that the child has died. Also, notice that this happens
592 // without any error bit being set in pollfd.revents (is this a
593 // Free/NetBSD bug??? ). Notice that these anomalous packets exist
594 // according to poll(), but have length 0 according to read().
595 // Thus, we can remain stuck inside this loop.
596 //
597 // A solution to this problem is to get out of the inner loop
598 // when read() returns <=0. In this way, we have another chance
599 // to call waitpid() to check if the child has died -- and this
600 // time the call should succeed.
601 //
602 // Set POLLHUP in pollfd.revents to signal that something strange
603 // has happened and disable polling of stdout.
604 poller[STD_OUT].revents |= POLLHUP;
605 poller[STD_OUT].events = 0;
606 }
607 } else if (poller[STD_OUT].revents & POLLHUP) {
608 // disable polling of stdout
609 poller[STD_OUT].events = 0;
610 }
611
612 // Check stderr.
613 if (poller[STD_ERR].revents & POLLIN) {
614 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
615 if ((len = read(poller[STD_ERR].fd,str,1024))>0) {
616 //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
617 str[len] ='\0';
618 error += str;
619 }
620 else {
621 // FreeBSD/NetBSD workaround (for details see above)
622 poller[STD_ERR].revents |= POLLHUP;
623 poller[STD_ERR].events = 0;
624 }
625 } else if (poller[STD_ERR].revents & POLLHUP) {
626 // disable polling of stderr
627 poller[STD_ERR].events = 0;
628 }
629
630 if (num_pollers > 2) {
631 if (poller[STD_IN].revents & ( POLLERR | POLLHUP ) ) {
632 kdDebug(5100) << "GnuPG seems to have hung up" << endl;
633 close (pin[1]);
634 pin[1] = -1;
635 --num_pollers;
636 }
637 else if (poller[STD_IN].revents & POLLOUT) {
638 if (!input.isEmpty()) {
639 // search end of next line
640 if ((len2 = input.find('\n', input_pos)) == -1)
641 len2 = input_length - input_pos;
642 else
643 len2 = len2 - input_pos + 1;
644
645 //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
646 len2 = write(pin[1], input.data() + input_pos, len2 );
647 //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
648 input_pos += len2;
649
650 // We are done.
651 if (input_pos >= input_length) {
652 //kdDebug(5100) << "All input was written to pin[1]" << endl;
653 close (pin[1]);
654 pin[1] = -1;
655 --num_pollers;
656 }
657 }
658 else { // if input.isEmpty()
659 if (write(pin[1], "\n", 1) < 0) {
660 // An error occurred
661 // FIXME
662 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
663 }
664 //kdDebug(5100) << "All input was written to pin[1]" << endl;
665 close (pin[1]);
666 pin[1] = -1;
667 --num_pollers;
668 }
669 }
670 }
671 }
672 } while ( (pollstatus > 0) && ( (num_pollers > 2)
673 || (poller[STD_OUT].events != 0)
674 || (poller[STD_ERR].events != 0) ) );
675
676 if (pollstatus == -1) {
677 kdDebug(5100) << "GnuPG poll failed, errno: " << errno << endl;
678 }
679
680 } while(waitpidRetVal == 0);
681
682 if( 0 <= pin[1] )
683 close (pin[1]);
684 close(pout[0]);
685 close(perr[0]);
686
687 if (!passphrase.isEmpty())
688 close(ppass[0]);
689
690 // Did the child exit normally?
691 if (WIFEXITED(childExiStatus) != 0) {
692 // Get the return code of the child
693 childExiStatus = WEXITSTATUS(childExiStatus);
694 kdDebug(5100) << "GnuPG exited with exit status " << childExiStatus
695 << endl;
696 }
697 else {
698 childExiStatus = -1;
699 kdDebug(5100) << "GnuPG exited abnormally!" << endl;
700 }
701
702 //Uncomment these lines for testing only! Doing so will decrease security!
703 //kdDebug(5100) << "gpg stdout:\n" << TQString(output) << endl;
704
705 // Make the information visible, so that a user can
706 // get to know what's going on during the gpg calls.
707 kdDebug(5100) << "gpg stderr:\n" << error << endl;
708
709 return childExiStatus;
710}
711
712
713TQCString
714Base::addUserId()
715{
716 TQCString cmd;
717 TQCString pgpUser = Module::getKpgp()->user();
718
719 if(!pgpUser.isEmpty())
720 {
721 cmd += " -u 0x";
722 cmd += pgpUser;
723 return cmd;
724 }
725 return TQCString();
726}
727
728
729} // namespace Kpgp