File indexing completed on 2024-05-19 04:46:24

0001 /*
0002  * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Lesser General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Lesser General Public
0015  * License along with this library; if not, write to the Free Software
0016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
0017  *
0018  */
0019 
0020 #pragma once
0021 
0022 #include "gpgproc.h"
0023 #include "qpipe.h"
0024 #include "sprocess.h"
0025 #include <QObject>
0026 
0027 namespace gpgQCAPlugin {
0028 
0029 class QProcessSignalRelay : public QObject
0030 {
0031     Q_OBJECT
0032 public:
0033     QProcessSignalRelay(QProcess *proc, QObject *parent = nullptr)
0034         : QObject(parent)
0035     {
0036         qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
0037         connect(proc, &QProcess::started, this, &QProcessSignalRelay::proc_started, Qt::QueuedConnection);
0038         connect(proc,
0039                 &QProcess::readyReadStandardOutput,
0040                 this,
0041                 &QProcessSignalRelay::proc_readyReadStandardOutput,
0042                 Qt::QueuedConnection);
0043         connect(proc,
0044                 &QProcess::readyReadStandardError,
0045                 this,
0046                 &QProcessSignalRelay::proc_readyReadStandardError,
0047                 Qt::QueuedConnection);
0048         connect(proc, &QProcess::bytesWritten, this, &QProcessSignalRelay::proc_bytesWritten, Qt::QueuedConnection);
0049         connect(proc,
0050                 QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
0051                 this,
0052                 &QProcessSignalRelay::proc_finished,
0053                 Qt::QueuedConnection);
0054         connect(proc, &QProcess::errorOccurred, this, &QProcessSignalRelay::proc_error, Qt::QueuedConnection);
0055     }
0056 
0057 Q_SIGNALS:
0058     void started();
0059     void readyReadStandardOutput();
0060     void readyReadStandardError();
0061     void bytesWritten(qint64);
0062     void finished(int);
0063     void error(QProcess::ProcessError);
0064 
0065 public Q_SLOTS:
0066     void proc_started()
0067     {
0068         emit started();
0069     }
0070 
0071     void proc_readyReadStandardOutput()
0072     {
0073         emit readyReadStandardOutput();
0074     }
0075 
0076     void proc_readyReadStandardError()
0077     {
0078         emit readyReadStandardError();
0079     }
0080 
0081     void proc_bytesWritten(qint64 x)
0082     {
0083         emit bytesWritten(x);
0084     }
0085 
0086     void proc_finished(int x)
0087     {
0088         emit finished(x);
0089     }
0090 
0091     void proc_error(QProcess::ProcessError x)
0092     {
0093         emit error(x);
0094     }
0095 };
0096 
0097 enum ResetMode
0098 {
0099     ResetSession        = 0,
0100     ResetSessionAndData = 1,
0101     ResetAll            = 2
0102 };
0103 
0104 class GPGProc::Private : public QObject
0105 {
0106     Q_OBJECT
0107 public:
0108     GPGProc             *q;
0109     QString              bin;
0110     QStringList          args;
0111     GPGProc::Mode        mode;
0112     SProcess            *proc;
0113     QProcessSignalRelay *proc_relay;
0114     QCA::QPipe           pipeAux, pipeCommand, pipeStatus;
0115     QByteArray           statusBuf;
0116     QStringList          statusLines;
0117     GPGProc::Error       error;
0118     int                  exitCode;
0119     QCA::SafeTimer       startTrigger, doneTrigger;
0120 
0121     QByteArray pre_stdin, pre_aux;
0122 #ifdef QPIPE_SECURE
0123     QCA::SecureArray pre_command;
0124 #else
0125     QByteArray pre_command;
0126 #endif
0127     bool pre_stdin_close, pre_aux_close, pre_command_close;
0128 
0129     bool       need_status, fin_process, fin_process_success, fin_status;
0130     QByteArray leftover_stdout;
0131     QByteArray leftover_stderr;
0132 
0133     Private(GPGProc *_q);
0134     ~Private() override;
0135     void closePipes();
0136     void reset(ResetMode mode);
0137     bool setupPipes(bool makeAux);
0138     void setupArguments();
0139 
0140 public Q_SLOTS:
0141     void doStart();
0142     void aux_written(int x);
0143     void aux_error(QCA::QPipeEnd::Error);
0144     void command_written(int x);
0145     void command_error(QCA::QPipeEnd::Error);
0146     void status_read();
0147     void status_error(QCA::QPipeEnd::Error e);
0148     void proc_started();
0149     void proc_readyReadStandardOutput();
0150     void proc_readyReadStandardError();
0151     void proc_bytesWritten(qint64 lx);
0152     void proc_finished(int x);
0153     void proc_error(QProcess::ProcessError x);
0154     void doTryDone();
0155 
0156 private:
0157     bool readAndProcessStatusData();
0158     // return true if there are newly parsed lines available
0159     bool processStatusData(const QByteArray &buf);
0160 };
0161 
0162 } // end namespace gpgQCAPlugin