libkdenetwork Library API Documentation

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