libkpgp

kpgpbase.cpp

00001 /*
00002     kpgpbase.cpp
00003 
00004     Copyright (C) 2001,2002 the KPGP authors
00005     See file AUTHORS.kpgp for details
00006 
00007     This file is part of KPGP, the KDE PGP/GnuPG support library.
00008 
00009     KPGP is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software Foundation,
00016     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include <kdebug.h>
00020 
00021 #include <config.h>
00022 
00023 #include "kpgpbase.h"
00024 #include "kpgp.h"
00025 #include "kpgpblock.h"
00026 
00027 #include <stdlib.h> /* setenv, unsetenv */
00028 #include <unistd.h> /* pipe, close, fork, dup2, execl, _exit, write, read */
00029 #include <sys/poll.h>  /* poll, etc. */
00030 #include <sys/types.h> /* pid_t */
00031 #include <sys/wait.h> /* waitpid */
00032 #include <errno.h>
00033 
00034 #include <tqapplication.h>
00035 
00036 
00037 namespace Kpgp {
00038 
00039 Base::Base()
00040   : input(), output(), error(), errMsg(), status(OK)
00041 {
00042 }
00043 
00044 
00045 Base::~Base()
00046 {
00047 }
00048 
00049 
00050 void
00051 Base::clear()
00052 {
00053   input = TQCString();
00054   output = TQCString();
00055   error = TQCString();
00056   errMsg = TQString();
00057   status = OK;
00058 }
00059 
00060 
00061 int
00062 Base::run( const char *cmd, const TQString &passphrase, bool onlyReadFromPGP )
00063 {
00064   /* the pipe ppass is used for to pass the password to
00065    * pgp. passing the password together with the normal input through
00066    * stdin doesn't seem to work as expected (at least for pgp5.0)
00067    */
00068   char str[1025] = "\0";
00069   int pin[2], pout[2], perr[2], ppass[2];
00070   int len, len2;
00071   FILE *pass;
00072   pid_t child_pid;
00073   int childExiStatus;
00074   struct pollfd pollin, pollout, pollerr;
00075   int pollstatus;
00076 
00077   if (!passphrase.isEmpty())
00078   {
00079     if (pipe(ppass) < 0) {
00080       // An error occurred
00081       // FIXME
00082       printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00083     }
00084 
00085     pass = fdopen(ppass[1], "w");
00086     TQCString pass2 = passphrase.local8Bit();
00087     fwrite(pass2, sizeof(char), pass2.length(), pass);
00088     fwrite("\n", sizeof(char), 1, pass);
00089     fclose(pass);
00090     close(ppass[1]);
00091 
00092     // tell pgp which fd to use for the passphrase
00093     TQCString tmp;
00094     tmp.sprintf("%d",ppass[0]);
00095     ::setenv("PGPPASSFD",tmp.data(),1);
00096 
00097     //Uncomment these lines for testing only! Doing so will decrease security!
00098     //kdDebug(5100) << "pgp PGPPASSFD = " << tmp << endl;
00099     //kdDebug(5100) << "pgp pass = " << passphrase << endl;
00100   }
00101   else
00102     ::unsetenv("PGPPASSFD");
00103 
00104   //Uncomment these lines for testing only! Doing so will decrease security!
00105   kdDebug(5100) << "pgp cmd = " << cmd << endl;
00106   //kdDebug(5100) << "pgp input = " << TQString(input)
00107   //          << "input length = " << input.length() << endl;
00108 
00109   error = "";
00110   output = "";
00111 
00112   if (pipe(pin) < 0) {
00113     // An error occurred
00114     // FIXME
00115     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00116   }
00117   if (pipe(pout) < 0) {
00118     // An error occurred
00119     // FIXME
00120     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00121   }
00122   if (pipe(perr) < 0) {
00123     // An error occurred
00124     // FIXME
00125     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00126   }
00127 
00128   TQApplication::flushX();
00129   if(!(child_pid = fork()))
00130   {
00131     /*We're the child.*/
00132     close(pin[1]);
00133     dup2(pin[0], 0);
00134     close(pin[0]);
00135 
00136     close(pout[0]);
00137     dup2(pout[1], 1);
00138     close(pout[1]);
00139 
00140     close(perr[0]);
00141     dup2(perr[1], 2);
00142     close(perr[1]);
00143 
00144     execl("/bin/sh", "sh", "-c", cmd,  (void *)0);
00145     _exit(127);
00146   }
00147 
00148   /*Only get here if we're the parent.*/
00149   close(pin[0]);
00150   close(pout[1]);
00151   close(perr[1]);
00152 
00153   // poll for "There is data to read."
00154   pollout.fd = pout[0];
00155   pollout.events = POLLIN;
00156   pollout.revents = 0; // init with 0, just in case
00157   pollerr.fd = perr[0];
00158   pollerr.events = POLLIN;
00159   pollerr.revents = 0; // init with 0, just in case
00160 
00161   // poll for "Writing now will not block."
00162   pollin.fd = pin[1];
00163   pollin.events = POLLOUT;
00164   pollin.revents = 0; // init with 0, just in case
00165 
00166   if (!onlyReadFromPGP) {
00167     if (!input.isEmpty()) {
00168       // write to pin[1] one line after the other to prevent dead lock
00169       uint input_length = input.length();
00170       for (unsigned int i=0; i<input_length; i+=len2) {
00171         len2 = 0;
00172 
00173         // check if writing now to pin[1] will not block (5 ms timeout)
00174         //kdDebug(5100) << "Polling pin[1]..." << endl;
00175         pollstatus = poll(&pollin, 1, 5);
00176         if (pollstatus == 1) {
00177           //kdDebug(5100) << "Status for polling pin[1]: " << pollin.revents << endl;
00178           if (pollin.revents & POLLERR) {
00179             kdDebug(5100) << "PGP seems to have hung up" << endl;
00180             break;
00181           }
00182           else if (pollin.revents & POLLOUT) {
00183             // search end of next line
00184             if ((len2 = input.find('\n', i)) == -1)
00185               len2 = input_length - i;
00186             else
00187               len2 = len2 - i + 1;
00188 
00189             //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
00190             len2 = write(pin[1], input.data() + i, len2);
00191             //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
00192           }
00193         }
00194         else if (!pollstatus) {
00195           //kdDebug(5100) << "Timeout while polling pin[1]: "
00196           //              << pollin.revents << endl;
00197         }
00198         else if (pollstatus == -1) {
00199           kdDebug(5100) << "Error while polling pin[1]: "
00200                         << pollin.revents << endl;
00201         }
00202 
00203         if (pout[0] >= 0) {
00204           do {
00205             // check if there is data to read from pout[0]
00206             //kdDebug(5100) << "Polling pout[0]..." << endl;
00207             pollstatus = poll(&pollout, 1, 0);
00208             if (pollstatus == 1) {
00209               //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
00210               if (pollout.revents & POLLIN) {
00211                 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
00212                 if ((len = read(pout[0],str,1024))>0) {
00213                   //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
00214                   str[len] ='\0';
00215                   output += str;
00216                 }
00217                 else
00218                   break;
00219               }
00220             }
00221             else if (pollstatus == -1) {
00222               kdDebug(5100) << "Error while polling pout[0]: "
00223                             << pollout.revents << endl;
00224             }
00225           } while ((pollstatus == 1) && (pollout.revents & POLLIN));
00226         }
00227 
00228         if (perr[0] >= 0) {
00229           do {
00230             // check if there is data to read from perr[0]
00231             //kdDebug(5100) << "Polling perr[0]..." << endl;
00232             pollstatus = poll(&pollerr, 1, 0);
00233             if (pollstatus == 1) {
00234               //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
00235               if (pollerr.revents & POLLIN) {
00236                 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
00237                 if ((len = read(perr[0],str,1024))>0) {
00238                   //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
00239                   str[len] ='\0';
00240                   error += str;
00241                 }
00242                 else
00243                   break;
00244               }
00245             }
00246             else if (pollstatus == -1) {
00247               kdDebug(5100) << "Error while polling perr[0]: "
00248                             << pollerr.revents << endl;
00249             }
00250           } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
00251         }
00252 
00253         // abort writing to PGP if PGP hung up
00254         if ((pollstatus == 1) &&
00255             ((pollout.revents & POLLHUP) || (pollerr.revents & POLLHUP))) {
00256           kdDebug(5100) << "PGP hung up" << endl;
00257           break;
00258         }
00259       }
00260     }
00261     else { // if input.isEmpty()
00262       if (write(pin[1], "\n", 1) < 0) {
00263         // An error occurred
00264         // FIXME
00265         printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00266       }
00267     }
00268     //kdDebug(5100) << "All input was written to pin[1]" << endl;
00269   }
00270   close(pin[1]);
00271 
00272   pid_t waitpidRetVal;
00273 
00274   do {
00275     //kdDebug(5100) << "Checking if PGP is still running..." << endl;
00276     childExiStatus = 0;
00277     waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
00278     //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
00279     if (pout[0] >= 0) {
00280       do {
00281         // check if there is data to read from pout[0]
00282         //kdDebug(5100) << "Polling pout[0]..." << endl;
00283         pollstatus = poll(&pollout, 1, 0);
00284         if (pollstatus == 1) {
00285           //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
00286           if (pollout.revents & POLLIN) {
00287             //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
00288             if ((len = read(pout[0],str,1024))>0) {
00289               //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
00290               str[len] ='\0';
00291               output += str;
00292             } else {
00293               /*
00294                * Apparently, on NetBSD when the child dies, the pipe begins
00295                * receiving empty data packets *before* waitpid() has signaled
00296                * that the child has died.  Also, notice that this happens
00297                * without any error bit being set in pollfd.revents (is this a
00298                * NetBSD bug??? ).  Notice that these anomalous packets exist
00299                * according to poll(), but have length 0 according to read().
00300                * Thus, kde can remain stuck inside this loop.
00301                *
00302                * A solution to this problem is to get out of the inner loop
00303                * when read() returns <=0.  In this way, kde has another chance
00304                * to call waitpid() to check if the child has died -- and this
00305                * time the call should succeed.
00306                *
00307                * Setting POLLHUP in pollfd.revents is not necessary, but I just
00308                * like the idea of signaling that something strange has
00309                * happened.
00310                */
00311               pollout.revents |= POLLHUP;
00312               break;
00313             }
00314           }
00315         }
00316         else if (pollstatus == -1) {
00317           kdDebug(5100) << "Error while polling pout[0]: "
00318                         << pollout.revents << endl;
00319         }
00320       } while ((pollstatus == 1) && (pollout.revents & POLLIN));
00321     }
00322 
00323     if (perr[0] >= 0) {
00324       do {
00325         // check if there is data to read from perr[0]
00326         //kdDebug(5100) << "Polling perr[0]..." << endl;
00327         pollstatus = poll(&pollerr, 1, 0);
00328         if (pollstatus == 1) {
00329           //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
00330           if (pollerr.revents & POLLIN) {
00331             //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
00332             if ((len = read(perr[0],str,1024))>0) {
00333               //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
00334               str[len] ='\0';
00335               error += str;
00336             } else {
00337               /*
00338                * Apparently, on NetBSD when the child dies, the pipe begins
00339                * receiving empty data packets *before* waitpid() has signaled
00340                * that the child has died.  Also, notice that this happens
00341                * without any error bit being set in pollfd.revents (is this a
00342                * NetBSD bug??? ).  Notice that these anomalous packets exist
00343                * according to poll(), but have length 0 according to read().
00344                * Thus, kde can remain stuck inside this loop.
00345                *
00346                * A solution to this problem is to get out of the inner loop
00347                * when read() returns <=0.  In this way, kde has another chance
00348                * to call waitpid() to check if the child has died -- and this
00349                * time the call should succeed.
00350                *
00351                * Setting POLLHUP in pollfd.revents is not necessary, but I just
00352                * like the idea of signaling that something strange has
00353                * happened.
00354                */
00355               pollerr.revents |= POLLHUP;
00356               break;
00357             }
00358           }
00359         }
00360         else if (pollstatus == -1) {
00361           kdDebug(5100) << "Error while polling perr[0]: "
00362                         << pollerr.revents << endl;
00363         }
00364       } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
00365     }
00366   } while (waitpidRetVal == 0);
00367 
00368   close(pout[0]);
00369   close(perr[0]);
00370 
00371   unsetenv("PGPPASSFD");
00372   if (!passphrase.isEmpty())
00373     close(ppass[0]);
00374 
00375   // Did the child exit normally?
00376   if (WIFEXITED(childExiStatus) != 0) {
00377     // Get the return code of the child
00378     childExiStatus = WEXITSTATUS(childExiStatus);
00379     kdDebug(5100) << "PGP exited with exit status " << childExiStatus
00380                   << endl;
00381   }
00382   else {
00383     childExiStatus = -1;
00384     kdDebug(5100) << "PGP exited abnormally!" << endl;
00385   }
00386 
00387   //Uncomment these lines for testing only! Doing so will decrease security!
00388   //kdDebug(5100) << "pgp output = " << TQString(output) << endl;
00389   //kdDebug(5100) << "pgp error = " << error << endl;
00390 
00391   /* Make the information visible, so that a user can
00392    * get to know what's going on during the pgp calls.
00393    */
00394   kdDebug(5100) << error << endl;
00395 
00396   return childExiStatus;
00397 }
00398 
00399 
00400 int
00401 Base::runGpg( const char *cmd, const TQString &passphrase, bool onlyReadFromGnuPG )
00402 {
00403   /* the pipe ppass is used for to pass the password to
00404    * pgp. passing the password together with the normal input through
00405    * stdin doesn't seem to work as expected (at least for pgp5.0)
00406    */
00407   char str[1025] = "\0";
00408   int pin[2], pout[2], perr[2], ppass[2];
00409   int len, len2;
00410   FILE *pass;
00411   pid_t child_pid;
00412   int childExiStatus;
00413   char gpgcmd[1024] = "\0";
00414   struct pollfd poller[3];
00415   int num_pollers = 0;
00416   const int STD_OUT = 0;
00417   const int STD_ERR = 1;
00418   const int STD_IN = 2;
00419   int pollstatus;
00420 
00421   if (!passphrase.isEmpty())
00422   {
00423     if (pipe(ppass) < 0) {
00424       // An error occurred
00425       // FIXME
00426       printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00427     }
00428 
00429     pass = fdopen(ppass[1], "w");
00430     TQCString pass2 = passphrase.local8Bit();
00431     fwrite(pass2, sizeof(char), pass2.length(), pass);
00432     fwrite("\n", sizeof(char), 1, pass);
00433     fclose(pass);
00434     close(ppass[1]);
00435 
00436     //Uncomment these lines for testing only! Doing so will decrease security!
00437     //kdDebug(5100) << "pass = " << passphrase << endl;
00438   }
00439 
00440   //Uncomment these lines for testing only! Doing so will decrease security!
00441   //kdDebug(5100) << "pgp cmd = " << cmd << endl;
00442   //kdDebug(5100) << "pgp input = " << TQString(input)
00443   //          << "input length = " << input.length() << endl;
00444 
00445   error = "";
00446   output = "";
00447 
00448   if (pipe(pin) < 0) {
00449     // An error occurred
00450     // FIXME
00451     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00452   }
00453   if (pipe(pout) < 0) {
00454     // An error occurred
00455     // FIXME
00456     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00457   }
00458   if (pipe(perr) < 0) {
00459     // An error occurred
00460     // FIXME
00461     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00462   }
00463 
00464   if (!passphrase.isEmpty()) {
00465     if( mVersion >= "1.0.7" ) {
00466       // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
00467       if( 0 == getenv("GPG_AGENT_INFO") ) {
00468         // gpg-agent not found, so we tell gpg not to use the agent
00469         snprintf( gpgcmd, 1023,
00470                   "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
00471                   ppass[0], cmd );
00472       }
00473       else {
00474         // gpg-agent seems to be running, so we tell gpg to use the agent
00475         snprintf( gpgcmd, 1023,
00476                   "LANGUAGE=C gpg --use-agent %s",
00477                   cmd );
00478       }
00479     }
00480     else {
00481       // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
00482       snprintf( gpgcmd, 1023,
00483                 "LANGUAGE=C gpg --passphrase-fd %d %s",
00484                 ppass[0], cmd );
00485     }
00486   }
00487   else {
00488     snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
00489   }
00490 
00491   TQApplication::flushX();
00492   if(!(child_pid = fork()))
00493   {
00494     /*We're the child.*/
00495     close(pin[1]);
00496     dup2(pin[0], 0);
00497     close(pin[0]);
00498 
00499     close(pout[0]);
00500     dup2(pout[1], 1);
00501     close(pout[1]);
00502 
00503     close(perr[0]);
00504     dup2(perr[1], 2);
00505     close(perr[1]);
00506 
00507     //#warning FIXME: there has to be a better way to do this
00508      /* this is nasty nasty nasty (but it works) */
00509     if (!passphrase.isEmpty()) {
00510       if( mVersion >= "1.0.7" ) {
00511         // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
00512         if( 0 == getenv("GPG_AGENT_INFO") ) {
00513           // gpg-agent not found, so we tell gpg not to use the agent
00514           snprintf( gpgcmd, 1023,
00515                     "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
00516                     ppass[0], cmd );
00517         }
00518         else {
00519           // gpg-agent seems to be running, so we tell gpg to use the agent
00520           snprintf( gpgcmd, 1023,
00521                     "LANGUAGE=C gpg --use-agent %s",
00522                     cmd );
00523         }
00524       }
00525       else {
00526         // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
00527         snprintf( gpgcmd, 1023,
00528                   "LANGUAGE=C gpg --passphrase-fd %d %s",
00529                   ppass[0], cmd );
00530       }
00531     }
00532     else {
00533       snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
00534     }
00535 
00536     kdDebug(5100) << "pgp cmd = " << gpgcmd << endl;
00537 
00538     execl("/bin/sh", "sh", "-c", gpgcmd,  (void *)0);
00539     _exit(127);
00540   }
00541 
00542   // Only get here if we're the parent.
00543 
00544   close(pin[0]);
00545   close(pout[1]);
00546   close(perr[1]);
00547 
00548   // poll for "There is data to read."
00549   poller[STD_OUT].fd = pout[0];
00550   poller[STD_OUT].events = POLLIN;
00551   poller[STD_ERR].fd = perr[0];
00552   poller[STD_ERR].events = POLLIN;
00553   num_pollers = 2;
00554 
00555   if (!onlyReadFromGnuPG) {
00556     // poll for "Writing now will not block."
00557     poller[STD_IN].fd = pin[1];
00558     poller[STD_IN].events = POLLOUT;
00559     num_pollers = 3;
00560   } else {
00561     close (pin[1]);
00562     pin[1] = -1;
00563   }
00564 
00565   pid_t waitpidRetVal;
00566   unsigned int input_pos = 0;
00567   uint input_length = input.length();
00568 
00569   do {
00570     //kdDebug(5100) << "Checking if GnuPG is still running..." << endl;
00571     childExiStatus = 0;
00572     waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
00573     //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
00574     do {
00575       // poll the pipes
00576       pollstatus = poll(poller, num_pollers, 10);
00577       if( 0 < pollstatus ) {
00578         // Check stdout.
00579         if (poller[STD_OUT].revents & POLLIN) {
00580           //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
00581           if ((len = read(pout[0],str,1024))>0) {
00582             //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
00583             str[len] ='\0';
00584             output += str;
00585           }
00586           else {
00587             // FreeBSD/NetBSD workaround
00588             //
00589             // Apparently, on Free/NetBSD when the child dies, the pipe begins
00590             // receiving empty data packets *before* waitpid() has signaled
00591             // that the child has died.  Also, notice that this happens
00592             // without any error bit being set in pollfd.revents (is this a
00593             // Free/NetBSD bug??? ).  Notice that these anomalous packets exist
00594             // according to poll(), but have length 0 according to read().
00595             // Thus, we can remain stuck inside this loop.
00596             //
00597             // A solution to this problem is to get out of the inner loop
00598             // when read() returns <=0.  In this way, we have another chance
00599             // to call waitpid() to check if the child has died -- and this
00600             // time the call should succeed.
00601             //
00602             // Set POLLHUP in pollfd.revents to signal that something strange
00603             // has happened and disable polling of stdout.
00604             poller[STD_OUT].revents |= POLLHUP;
00605             poller[STD_OUT].events = 0;
00606           }
00607         } else if (poller[STD_OUT].revents & POLLHUP) {
00608           // disable polling of stdout
00609           poller[STD_OUT].events = 0;
00610         }
00611 
00612         // Check stderr.
00613         if (poller[STD_ERR].revents & POLLIN) {
00614           //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
00615           if ((len = read(poller[STD_ERR].fd,str,1024))>0) {
00616             //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
00617             str[len] ='\0';
00618             error += str;
00619           }
00620           else {
00621             // FreeBSD/NetBSD workaround (for details see above)
00622             poller[STD_ERR].revents |= POLLHUP;
00623             poller[STD_ERR].events = 0;
00624           }
00625         } else if (poller[STD_ERR].revents & POLLHUP) {
00626           // disable polling of stderr
00627           poller[STD_ERR].events = 0;
00628         }
00629 
00630         if (num_pollers > 2) {
00631           if (poller[STD_IN].revents & ( POLLERR | POLLHUP ) ) {
00632             kdDebug(5100) << "GnuPG seems to have hung up" << endl;
00633             close (pin[1]);
00634             pin[1] = -1;
00635             --num_pollers;
00636           }
00637           else if (poller[STD_IN].revents & POLLOUT) {
00638             if (!input.isEmpty()) {
00639               // search end of next line
00640               if ((len2 = input.find('\n', input_pos)) == -1)
00641                 len2 = input_length - input_pos;
00642               else
00643                 len2 = len2 - input_pos + 1;
00644 
00645               //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
00646               len2 = write(pin[1], input.data() + input_pos, len2 );
00647               //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
00648               input_pos += len2;
00649 
00650               // We are done.
00651               if (input_pos >= input_length) {
00652                 //kdDebug(5100) << "All input was written to pin[1]" << endl;
00653                 close (pin[1]);
00654                 pin[1] = -1;
00655                 --num_pollers;
00656               }
00657             }
00658             else { // if input.isEmpty()
00659               if (write(pin[1], "\n", 1) < 0) {
00660                 // An error occurred
00661                 // FIXME
00662                 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00663               }
00664               //kdDebug(5100) << "All input was written to pin[1]" << endl;
00665               close (pin[1]);
00666               pin[1] = -1;
00667               --num_pollers;
00668             }
00669           }
00670         }
00671       }
00672     } while ( (pollstatus > 0) && ( (num_pollers > 2)
00673                                     || (poller[STD_OUT].events != 0)
00674                                     || (poller[STD_ERR].events != 0) ) );
00675 
00676     if (pollstatus == -1) {
00677       kdDebug(5100) << "GnuPG poll failed, errno: " << errno << endl;
00678     }
00679 
00680   } while(waitpidRetVal == 0);
00681 
00682   if( 0 <= pin[1] )
00683     close (pin[1]);
00684   close(pout[0]);
00685   close(perr[0]);
00686 
00687   if (!passphrase.isEmpty())
00688     close(ppass[0]);
00689 
00690   // Did the child exit normally?
00691   if (WIFEXITED(childExiStatus) != 0) {
00692     // Get the return code of the child
00693     childExiStatus = WEXITSTATUS(childExiStatus);
00694     kdDebug(5100) << "GnuPG exited with exit status " << childExiStatus
00695                   << endl;
00696   }
00697   else {
00698     childExiStatus = -1;
00699     kdDebug(5100) << "GnuPG exited abnormally!" << endl;
00700   }
00701 
00702   //Uncomment these lines for testing only! Doing so will decrease security!
00703   //kdDebug(5100) << "gpg stdout:\n" << TQString(output) << endl;
00704 
00705   // Make the information visible, so that a user can
00706   // get to know what's going on during the gpg calls.
00707   kdDebug(5100) << "gpg stderr:\n" << error << endl;
00708 
00709   return childExiStatus;
00710 }
00711 
00712 
00713 TQCString
00714 Base::addUserId()
00715 {
00716   TQCString cmd;
00717   TQCString pgpUser = Module::getKpgp()->user();
00718 
00719   if(!pgpUser.isEmpty())
00720   {
00721     cmd += " -u 0x";
00722     cmd += pgpUser;
00723     return cmd;
00724   }
00725   return TQCString();
00726 }
00727 
00728 
00729 } // namespace Kpgp