• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

qca

gpgproc.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
00017  *
00018  */
00019 
00020 #include "gpgproc.h"
00021 
00022 #include "sprocess.h"
00023 
00024 #ifdef Q_OS_MAC
00025 #define QT_PIPE_HACK
00026 #endif
00027 
00028 #define QPROC_SIGNAL_RELAY
00029 
00030 using namespace QCA;
00031 
00032 namespace gpgQCAPlugin {
00033 
00034 void releaseAndDeleteLater(QObject *owner, QObject *obj)
00035 {
00036     obj->disconnect(owner);
00037     obj->setParent(0);
00038     obj->deleteLater();
00039 }
00040 
00041 //----------------------------------------------------------------------------
00042 // SafeTimer
00043 //----------------------------------------------------------------------------
00044 SafeTimer::SafeTimer(QObject *parent) :
00045     QObject(parent)
00046 {
00047     timer = new QTimer(this);
00048     connect(timer, SIGNAL(timeout()), SIGNAL(timeout()));
00049 }
00050 
00051 SafeTimer::~SafeTimer()
00052 {
00053     releaseAndDeleteLater(this, timer);
00054 }
00055 
00056 int SafeTimer::interval() const
00057 {
00058     return timer->interval();
00059 }
00060 
00061 bool SafeTimer::isActive() const
00062 {
00063     return timer->isActive();
00064 }
00065 
00066 bool SafeTimer::isSingleShot() const
00067 {
00068     return timer->isSingleShot();
00069 }
00070 
00071 void SafeTimer::setInterval(int msec)
00072 {
00073     timer->setInterval(msec);
00074 }
00075 
00076 void SafeTimer::setSingleShot(bool singleShot)
00077 {
00078     timer->setSingleShot(singleShot);
00079 }
00080 
00081 int SafeTimer::timerId() const
00082 {
00083     return timer->timerId();
00084 }
00085 
00086 void SafeTimer::start(int msec)
00087 {
00088     timer->start(msec);
00089 }
00090 
00091 void SafeTimer::start()
00092 {
00093     timer->start();
00094 }
00095 
00096 void SafeTimer::stop()
00097 {
00098     timer->stop();
00099 }
00100 
00101 //----------------------------------------------------------------------------
00102 // QProcessSignalRelay
00103 //----------------------------------------------------------------------------
00104 class QProcessSignalRelay : public QObject
00105 {
00106     Q_OBJECT
00107 public:
00108     QProcessSignalRelay(QProcess *proc, QObject *parent = 0)
00109     :QObject(parent)
00110     {
00111         qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
00112         connect(proc, SIGNAL(started()), SLOT(proc_started()), Qt::QueuedConnection);
00113         connect(proc, SIGNAL(readyReadStandardOutput()), SLOT(proc_readyReadStandardOutput()), Qt::QueuedConnection);
00114         connect(proc, SIGNAL(readyReadStandardError()), SLOT(proc_readyReadStandardError()), Qt::QueuedConnection);
00115         connect(proc, SIGNAL(bytesWritten(qint64)), SLOT(proc_bytesWritten(qint64)), Qt::QueuedConnection);
00116         connect(proc, SIGNAL(finished(int)), SLOT(proc_finished(int)), Qt::QueuedConnection);
00117         connect(proc, SIGNAL(error(QProcess::ProcessError)), SLOT(proc_error(QProcess::ProcessError)), Qt::QueuedConnection);
00118     }
00119 
00120 signals:
00121     void started();
00122     void readyReadStandardOutput();
00123     void readyReadStandardError();
00124     void bytesWritten(qint64);
00125     void finished(int);
00126     void error(QProcess::ProcessError);
00127 
00128 public slots:
00129     void proc_started()
00130     {
00131         emit started();
00132     }
00133 
00134     void proc_readyReadStandardOutput()
00135     {
00136         emit readyReadStandardOutput();
00137     }
00138 
00139     void proc_readyReadStandardError()
00140     {
00141         emit readyReadStandardError();
00142     }
00143 
00144     void proc_bytesWritten(qint64 x)
00145     {
00146         emit bytesWritten(x);
00147     }
00148 
00149     void proc_finished(int x)
00150     {
00151         emit finished(x);
00152     }
00153 
00154     void proc_error(QProcess::ProcessError x)
00155     {
00156         emit error(x);
00157     }
00158 };
00159 
00160 //----------------------------------------------------------------------------
00161 // GPGProc
00162 //----------------------------------------------------------------------------
00163 enum ResetMode
00164 {
00165     ResetSession        = 0,
00166     ResetSessionAndData = 1,
00167     ResetAll            = 2
00168 };
00169 
00170 class GPGProc::Private : public QObject
00171 {
00172     Q_OBJECT
00173 public:
00174     GPGProc *q;
00175     QString bin;
00176     QStringList args;
00177     GPGProc::Mode mode;
00178     SProcess *proc;
00179 #ifdef QPROC_SIGNAL_RELAY
00180     QProcessSignalRelay *proc_relay;
00181 #endif
00182     QPipe pipeAux, pipeCommand, pipeStatus;
00183     QByteArray statusBuf;
00184     QStringList statusLines;
00185     GPGProc::Error error;
00186     int exitCode;
00187     SafeTimer startTrigger, doneTrigger;
00188 
00189     QByteArray pre_stdin, pre_aux;
00190 #ifdef QPIPE_SECURE
00191     SecureArray pre_command;
00192 #else
00193     QByteArray pre_command;
00194 #endif
00195     bool pre_stdin_close, pre_aux_close, pre_command_close;
00196 
00197     bool need_status, fin_process, fin_process_success, fin_status;
00198     QByteArray leftover_stdout;
00199     QByteArray leftover_stderr;
00200 
00201     Private(GPGProc *_q) : QObject(_q), q(_q), pipeAux(this), pipeCommand(this), pipeStatus(this), startTrigger(this), doneTrigger(this)
00202     {
00203         qRegisterMetaType<gpgQCAPlugin::GPGProc::Error>("gpgQCAPlugin::GPGProc::Error");
00204 
00205         proc = 0;
00206 #ifdef QPROC_SIGNAL_RELAY
00207         proc_relay = 0;
00208 #endif
00209         startTrigger.setSingleShot(true);
00210         doneTrigger.setSingleShot(true);
00211 
00212         connect(&pipeAux.writeEnd(), SIGNAL(bytesWritten(int)), SLOT(aux_written(int)));
00213         connect(&pipeAux.writeEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(aux_error(QCA::QPipeEnd::Error)));
00214         connect(&pipeCommand.writeEnd(), SIGNAL(bytesWritten(int)), SLOT(command_written(int)));
00215         connect(&pipeCommand.writeEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(command_error(QCA::QPipeEnd::Error)));
00216         connect(&pipeStatus.readEnd(), SIGNAL(readyRead()), SLOT(status_read()));
00217         connect(&pipeStatus.readEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(status_error(QCA::QPipeEnd::Error)));
00218         connect(&startTrigger, SIGNAL(timeout()), SLOT(doStart()));
00219         connect(&doneTrigger, SIGNAL(timeout()), SLOT(doTryDone()));
00220 
00221         reset(ResetSessionAndData);
00222     }
00223 
00224     ~Private()
00225     {
00226         reset(ResetSession);
00227     }
00228 
00229     void closePipes()
00230     {
00231 #ifdef QT_PIPE_HACK
00232         pipeAux.readEnd().reset();
00233         pipeCommand.readEnd().reset();
00234         pipeStatus.writeEnd().reset();
00235 #endif
00236 
00237         pipeAux.reset();
00238         pipeCommand.reset();
00239         pipeStatus.reset();
00240     }
00241 
00242     void reset(ResetMode mode)
00243     {
00244 #ifndef QT_PIPE_HACK
00245         closePipes();
00246 #endif
00247 
00248         if(proc)
00249         {
00250             proc->disconnect(this);
00251             if(proc->state() != QProcess::NotRunning)
00252                 proc->terminate();
00253             proc->setParent(0);
00254 #ifdef QPROC_SIGNAL_RELAY
00255             releaseAndDeleteLater(this, proc_relay);
00256             proc_relay = 0;
00257             delete proc; // should be safe to do thanks to relay
00258 #else
00259             proc->deleteLater();
00260 #endif
00261             proc = 0;
00262         }
00263 
00264 #ifdef QT_PIPE_HACK
00265         closePipes();
00266 #endif
00267 
00268         startTrigger.stop();
00269         doneTrigger.stop();
00270 
00271         pre_stdin.clear();
00272         pre_aux.clear();
00273         pre_command.clear();
00274         pre_stdin_close = false;
00275         pre_aux_close = false;
00276         pre_command_close = false;
00277 
00278         need_status = false;
00279         fin_process = false;
00280         fin_status = false;
00281 
00282         if(mode >= ResetSessionAndData)
00283         {
00284             statusBuf.clear();
00285             statusLines.clear();
00286             leftover_stdout.clear();
00287             leftover_stderr.clear();
00288             error = GPGProc::FailedToStart;
00289             exitCode = -1;
00290         }
00291     }
00292 
00293     bool setupPipes(bool makeAux)
00294     {
00295         if(makeAux && !pipeAux.create())
00296         {
00297             closePipes();
00298             emit q->debug("Error creating pipeAux");
00299             return false;
00300         }
00301 
00302 #ifdef QPIPE_SECURE
00303         if(!pipeCommand.create(true)) // secure
00304 #else
00305         if(!pipeCommand.create())
00306 #endif
00307         {
00308             closePipes();
00309             emit q->debug("Error creating pipeCommand");
00310             return false;
00311         }
00312 
00313         if(!pipeStatus.create())
00314         {
00315             closePipes();
00316             emit q->debug("Error creating pipeStatus");
00317             return false;
00318         }
00319 
00320         return true;
00321     }
00322 
00323     void setupArguments()
00324     {
00325         QStringList fullargs;
00326         fullargs += "--no-tty";
00327 
00328         if(mode == ExtendedMode)
00329         {
00330             fullargs += "--enable-special-filenames";
00331 
00332             fullargs += "--status-fd";
00333             fullargs += QString::number(pipeStatus.writeEnd().idAsInt());
00334 
00335             fullargs += "--command-fd";
00336             fullargs += QString::number(pipeCommand.readEnd().idAsInt());
00337         }
00338 
00339         for(int n = 0; n < args.count(); ++n)
00340         {
00341             QString a = args[n];
00342             if(mode == ExtendedMode && a == "-&?")
00343                 fullargs += QString("-&") + QString::number(pipeAux.readEnd().idAsInt());
00344             else
00345                 fullargs += a;
00346         }
00347 
00348         QString fullcmd = fullargs.join(" ");
00349         emit q->debug(QString("Running: [") + bin + ' ' + fullcmd + ']');
00350 
00351         args = fullargs;
00352     }
00353 
00354 public slots:
00355     void doStart()
00356     {
00357 #ifdef Q_OS_WIN
00358         // Note: for unix, inheritability is set in SProcess
00359         if(pipeAux.readEnd().isValid())
00360             pipeAux.readEnd().setInheritable(true);
00361         if(pipeCommand.readEnd().isValid())
00362             pipeCommand.readEnd().setInheritable(true);
00363         if(pipeStatus.writeEnd().isValid())
00364             pipeStatus.writeEnd().setInheritable(true);
00365 #endif
00366 
00367         setupArguments();
00368 
00369         proc->start(bin, args);
00370 
00371         // FIXME: From reading the source to Qt on both windows
00372         //   and unix platforms, we know that fork/CreateProcess
00373         //   are called in start.  However this is not guaranteed
00374         //   from an API perspective.  We should probably call
00375         //   QProcess::waitForStarted() to synchronously ensure
00376         //   fork/CreateProcess are called before closing these
00377         //   pipes.
00378         pipeAux.readEnd().close();
00379         pipeCommand.readEnd().close();
00380         pipeStatus.writeEnd().close();
00381     }
00382 
00383     void aux_written(int x)
00384     {
00385         emit q->bytesWrittenAux(x);
00386     }
00387 
00388     void aux_error(QCA::QPipeEnd::Error)
00389     {
00390         emit q->debug("Aux: Pipe error");
00391         reset(ResetSession);
00392         emit q->error(GPGProc::ErrorWrite);
00393     }
00394 
00395     void command_written(int x)
00396     {
00397         emit q->bytesWrittenCommand(x);
00398     }
00399 
00400     void command_error(QCA::QPipeEnd::Error)
00401     {
00402         emit q->debug("Command: Pipe error");
00403         reset(ResetSession);
00404         emit q->error(GPGProc::ErrorWrite);
00405     }
00406 
00407     void status_read()
00408     {
00409         if(readAndProcessStatusData())
00410             emit q->readyReadStatusLines();
00411     }
00412 
00413     void status_error(QCA::QPipeEnd::Error e)
00414     {
00415         if(e == QPipeEnd::ErrorEOF)
00416             emit q->debug("Status: Closed (EOF)");
00417         else
00418             emit q->debug("Status: Closed (gone)");
00419 
00420         fin_status = true;
00421         doTryDone();
00422     }
00423 
00424     void proc_started()
00425     {
00426         emit q->debug("Process started");
00427 
00428         // Note: we don't close these here anymore.  instead we
00429         //   do it just after calling proc->start().
00430         // close these, we don't need them
00431         /*pipeAux.readEnd().close();
00432         pipeCommand.readEnd().close();
00433         pipeStatus.writeEnd().close();*/
00434 
00435         // do the pre* stuff
00436         if(!pre_stdin.isEmpty())
00437         {
00438             proc->write(pre_stdin);
00439             pre_stdin.clear();
00440         }
00441         if(!pre_aux.isEmpty())
00442         {
00443             pipeAux.writeEnd().write(pre_aux);
00444             pre_aux.clear();
00445         }
00446         if(!pre_command.isEmpty())
00447         {
00448 #ifdef QPIPE_SECURE
00449             pipeCommand.writeEnd().writeSecure(pre_command);
00450 #else
00451             pipeCommand.writeEnd().write(pre_command);
00452 #endif
00453             pre_command.clear();
00454         }
00455 
00456         if(pre_stdin_close)
00457             proc->closeWriteChannel();
00458         if(pre_aux_close)
00459             pipeAux.writeEnd().close();
00460         if(pre_command_close)
00461             pipeCommand.writeEnd().close();
00462     }
00463 
00464     void proc_readyReadStandardOutput()
00465     {
00466         emit q->readyReadStdout();
00467     }
00468 
00469     void proc_readyReadStandardError()
00470     {
00471         emit q->readyReadStderr();
00472     }
00473 
00474     void proc_bytesWritten(qint64 lx)
00475     {
00476         int x = (int)lx;
00477         emit q->bytesWrittenStdin(x);
00478     }
00479 
00480     void proc_finished(int x)
00481     {
00482         emit q->debug(QString("Process finished: %1").arg(x));
00483         exitCode = x;
00484 
00485         fin_process = true;
00486         fin_process_success = true;
00487 
00488         if(need_status && !fin_status)
00489         {
00490             pipeStatus.readEnd().finalize();
00491             fin_status = true;
00492             if(readAndProcessStatusData())
00493             {
00494                 doneTrigger.start();
00495                 emit q->readyReadStatusLines();
00496                 return;
00497             }
00498         }
00499 
00500         doTryDone();
00501     }
00502 
00503     void proc_error(QProcess::ProcessError x)
00504     {
00505         QMap<int, QString> errmap;
00506         errmap[QProcess::FailedToStart] = "FailedToStart";
00507         errmap[QProcess::Crashed]       = "Crashed";
00508         errmap[QProcess::Timedout]      = "Timedout";
00509         errmap[QProcess::WriteError]    = "WriteError";
00510         errmap[QProcess::ReadError]     = "ReadError";
00511         errmap[QProcess::UnknownError]  = "UnknownError";
00512 
00513         emit q->debug(QString("Process error: %1").arg(errmap[x]));
00514 
00515         if(x == QProcess::FailedToStart)
00516             error = GPGProc::FailedToStart;
00517         else if(x == QProcess::WriteError)
00518             error = GPGProc::ErrorWrite;
00519         else
00520             error = GPGProc::UnexpectedExit;
00521 
00522         fin_process = true;
00523         fin_process_success = false;
00524 
00525 #ifdef QT_PIPE_HACK
00526         // If the process fails to start, then the ends of the pipes
00527         // intended for the child process are still open.  Some Mac
00528         // users experience a lockup if we close our ends of the pipes
00529         // when the child's ends are still open.  If we ensure the
00530         // child's ends are closed, we prevent this lockup.  I have no
00531         // idea why the problem even happens or why this fix should
00532         // work.
00533         pipeAux.readEnd().reset();
00534         pipeCommand.readEnd().reset();
00535         pipeStatus.writeEnd().reset();
00536 #endif
00537 
00538         if(need_status && !fin_status)
00539         {
00540             pipeStatus.readEnd().finalize();
00541             fin_status = true;
00542             if(readAndProcessStatusData())
00543             {
00544                 doneTrigger.start();
00545                 emit q->readyReadStatusLines();
00546                 return;
00547             }
00548         }
00549 
00550         doTryDone();
00551     }
00552 
00553     void doTryDone()
00554     {
00555         if(!fin_process)
00556             return;
00557 
00558         if(need_status && !fin_status)
00559             return;
00560 
00561         emit q->debug("Done");
00562 
00563         // get leftover data
00564         proc->setReadChannel(QProcess::StandardOutput);
00565         leftover_stdout = proc->readAll();
00566 
00567         proc->setReadChannel(QProcess::StandardError);
00568         leftover_stderr = proc->readAll();
00569 
00570         reset(ResetSession);
00571         if(fin_process_success)
00572             emit q->finished(exitCode);
00573         else
00574             emit q->error(error);
00575     }
00576 
00577 private:
00578     bool readAndProcessStatusData()
00579     {
00580         QByteArray buf = pipeStatus.readEnd().read();
00581         if(buf.isEmpty())
00582             return false;
00583 
00584         return processStatusData(buf);
00585     }
00586 
00587     // return true if there are newly parsed lines available
00588     bool processStatusData(const QByteArray &buf)
00589     {
00590         statusBuf.append(buf);
00591 
00592         // extract all lines
00593         QStringList list;
00594         while(1)
00595         {
00596             int n = statusBuf.indexOf('\n');
00597             if(n == -1)
00598                 break;
00599 
00600             // extract the string from statusbuf
00601             ++n;
00602             char *p = (char *)statusBuf.data();
00603             QByteArray cs(p, n);
00604             int newsize = statusBuf.size() - n;
00605             memmove(p, p + n, newsize);
00606             statusBuf.resize(newsize);
00607 
00608             // convert to string without newline
00609             QString str = QString::fromUtf8(cs);
00610             str.truncate(str.length() - 1);
00611 
00612             // ensure it has a proper header
00613             if(str.left(9) != "[GNUPG:] ")
00614                 continue;
00615 
00616             // take it off
00617             str = str.mid(9);
00618 
00619             // add to the list
00620             list += str;
00621         }
00622 
00623         if(list.isEmpty())
00624             return false;
00625 
00626         statusLines += list;
00627         return true;
00628     }
00629 };
00630 
00631 GPGProc::GPGProc(QObject *parent)
00632 :QObject(parent)
00633 {
00634     d = new Private(this);
00635 }
00636 
00637 GPGProc::~GPGProc()
00638 {
00639     delete d;
00640 }
00641 
00642 void GPGProc::reset()
00643 {
00644     d->reset(ResetAll);
00645 }
00646 
00647 bool GPGProc::isActive() const
00648 {
00649     return (d->proc ? true : false);
00650 }
00651 
00652 void GPGProc::start(const QString &bin, const QStringList &args, Mode mode)
00653 {
00654     if(isActive())
00655         d->reset(ResetSessionAndData);
00656 
00657     if(mode == ExtendedMode)
00658     {
00659         if(!d->setupPipes(args.contains("-&?")))
00660         {
00661             d->error = FailedToStart;
00662 
00663             // emit later
00664             QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(gpgQCAPlugin::GPGProc::Error, d->error));
00665             return;
00666         }
00667 
00668         d->need_status = true;
00669 
00670         emit debug("Pipe setup complete");
00671     }
00672 
00673     d->proc = new SProcess(d);
00674 
00675 #ifdef Q_OS_UNIX
00676     QList<int> plist;
00677     if(d->pipeAux.readEnd().isValid())
00678         plist += d->pipeAux.readEnd().id();
00679     if(d->pipeCommand.readEnd().isValid())
00680         plist += d->pipeCommand.readEnd().id();
00681     if(d->pipeStatus.writeEnd().isValid())
00682         plist += d->pipeStatus.writeEnd().id();
00683     d->proc->setInheritPipeList(plist);
00684 #endif
00685 
00686     // enable the pipes we want
00687     if(d->pipeAux.writeEnd().isValid())
00688         d->pipeAux.writeEnd().enable();
00689     if(d->pipeCommand.writeEnd().isValid())
00690         d->pipeCommand.writeEnd().enable();
00691     if(d->pipeStatus.readEnd().isValid())
00692         d->pipeStatus.readEnd().enable();
00693 
00694 #ifdef QPROC_SIGNAL_RELAY
00695     d->proc_relay = new QProcessSignalRelay(d->proc, d);
00696     connect(d->proc_relay, SIGNAL(started()), d, SLOT(proc_started()));
00697     connect(d->proc_relay, SIGNAL(readyReadStandardOutput()), d, SLOT(proc_readyReadStandardOutput()));
00698     connect(d->proc_relay, SIGNAL(readyReadStandardError()), d, SLOT(proc_readyReadStandardError()));
00699     connect(d->proc_relay, SIGNAL(bytesWritten(qint64)), d, SLOT(proc_bytesWritten(qint64)));
00700     connect(d->proc_relay, SIGNAL(finished(int)), d, SLOT(proc_finished(int)));
00701     connect(d->proc_relay, SIGNAL(error(QProcess::ProcessError)), d, SLOT(proc_error(QProcess::ProcessError)));
00702 #else
00703     connect(d->proc, SIGNAL(started()), d, SLOT(proc_started()));
00704     connect(d->proc, SIGNAL(readyReadStandardOutput()), d, SLOT(proc_readyReadStandardOutput()));
00705     connect(d->proc, SIGNAL(readyReadStandardError()), d, SLOT(proc_readyReadStandardError()));
00706     connect(d->proc, SIGNAL(bytesWritten(qint64)), d, SLOT(proc_bytesWritten(qint64)));
00707     connect(d->proc, SIGNAL(finished(int)), d, SLOT(proc_finished(int)));
00708     connect(d->proc, SIGNAL(error(QProcess::ProcessError)), d, SLOT(proc_error(QProcess::ProcessError)));
00709 #endif
00710 
00711     d->bin = bin;
00712     d->args = args;
00713     d->mode = mode;
00714     d->startTrigger.start();
00715 }
00716 
00717 QByteArray GPGProc::readStdout()
00718 {
00719     if(d->proc)
00720     {
00721         d->proc->setReadChannel(QProcess::StandardOutput);
00722         return d->proc->readAll();
00723     }
00724     else
00725     {
00726         QByteArray a = d->leftover_stdout;
00727         d->leftover_stdout.clear();
00728         return a;
00729     }
00730 }
00731 
00732 QByteArray GPGProc::readStderr()
00733 {
00734     if(d->proc)
00735     {
00736         d->proc->setReadChannel(QProcess::StandardError);
00737         return d->proc->readAll();
00738     }
00739     else
00740     {
00741         QByteArray a = d->leftover_stderr;
00742         d->leftover_stderr.clear();
00743         return a;
00744     }
00745 }
00746 
00747 QStringList GPGProc::readStatusLines()
00748 {
00749     QStringList out = d->statusLines;
00750     d->statusLines.clear();
00751     return out;
00752 }
00753 
00754 void GPGProc::writeStdin(const QByteArray &a)
00755 {
00756     if(!d->proc || a.isEmpty())
00757         return;
00758 
00759     if(d->proc->state() == QProcess::Running)
00760         d->proc->write(a);
00761     else
00762         d->pre_stdin += a;
00763 }
00764 
00765 void GPGProc::writeAux(const QByteArray &a)
00766 {
00767     if(!d->proc || a.isEmpty())
00768         return;
00769 
00770     if(d->proc->state() == QProcess::Running)
00771         d->pipeAux.writeEnd().write(a);
00772     else
00773         d->pre_aux += a;
00774 }
00775 
00776 #ifdef QPIPE_SECURE
00777 void GPGProc::writeCommand(const SecureArray &a)
00778 #else
00779 void GPGProc::writeCommand(const QByteArray &a)
00780 #endif
00781 {
00782     if(!d->proc || a.isEmpty())
00783         return;
00784 
00785     if(d->proc->state() == QProcess::Running)
00786 #ifdef QPIPE_SECURE
00787         d->pipeCommand.writeEnd().writeSecure(a);
00788 #else
00789         d->pipeCommand.writeEnd().write(a);
00790 #endif
00791     else
00792         d->pre_command += a;
00793 }
00794 
00795 void GPGProc::closeStdin()
00796 {
00797     if(!d->proc)
00798         return;
00799 
00800     if(d->proc->state() == QProcess::Running)
00801         d->proc->closeWriteChannel();
00802     else
00803         d->pre_stdin_close = true;
00804 }
00805 
00806 void GPGProc::closeAux()
00807 {
00808     if(!d->proc)
00809         return;
00810 
00811     if(d->proc->state() == QProcess::Running)
00812         d->pipeAux.writeEnd().close();
00813     else
00814         d->pre_aux_close = true;
00815 }
00816 
00817 void GPGProc::closeCommand()
00818 {
00819     if(!d->proc)
00820         return;
00821 
00822     if(d->proc->state() == QProcess::Running)
00823         d->pipeCommand.writeEnd().close();
00824     else
00825         d->pre_command_close = true;
00826 }
00827 
00828 }
00829 
00830 #include "gpgproc.moc"

qca

Skip menu "qca"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal