1 /* 2 * Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 17 * 18 */ 19 20 #pragma once 21 22 #include "gpgproc.h" 23 #include "qpipe.h" 24 #include "sprocess.h" 25 #include <QObject> 26 27 namespace gpgQCAPlugin { 28 29 class QProcessSignalRelay : public QObject 30 { 31 Q_OBJECT 32 public: 33 QProcessSignalRelay(QProcess *proc, QObject *parent = nullptr) QObject(parent)34 : QObject(parent) 35 { 36 qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); 37 connect(proc, &QProcess::started, this, &QProcessSignalRelay::proc_started, Qt::QueuedConnection); 38 connect(proc, 39 &QProcess::readyReadStandardOutput, 40 this, 41 &QProcessSignalRelay::proc_readyReadStandardOutput, 42 Qt::QueuedConnection); 43 connect(proc, 44 &QProcess::readyReadStandardError, 45 this, 46 &QProcessSignalRelay::proc_readyReadStandardError, 47 Qt::QueuedConnection); 48 connect(proc, &QProcess::bytesWritten, this, &QProcessSignalRelay::proc_bytesWritten, Qt::QueuedConnection); 49 connect(proc, 50 QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), 51 this, 52 &QProcessSignalRelay::proc_finished, 53 Qt::QueuedConnection); 54 connect(proc, &QProcess::errorOccurred, this, &QProcessSignalRelay::proc_error, Qt::QueuedConnection); 55 } 56 57 Q_SIGNALS: 58 void started(); 59 void readyReadStandardOutput(); 60 void readyReadStandardError(); 61 void bytesWritten(qint64); 62 void finished(int); 63 void error(QProcess::ProcessError); 64 65 public Q_SLOTS: proc_started()66 void proc_started() 67 { 68 emit started(); 69 } 70 proc_readyReadStandardOutput()71 void proc_readyReadStandardOutput() 72 { 73 emit readyReadStandardOutput(); 74 } 75 proc_readyReadStandardError()76 void proc_readyReadStandardError() 77 { 78 emit readyReadStandardError(); 79 } 80 proc_bytesWritten(qint64 x)81 void proc_bytesWritten(qint64 x) 82 { 83 emit bytesWritten(x); 84 } 85 proc_finished(int x)86 void proc_finished(int x) 87 { 88 emit finished(x); 89 } 90 proc_error(QProcess::ProcessError x)91 void proc_error(QProcess::ProcessError x) 92 { 93 emit error(x); 94 } 95 }; 96 97 enum ResetMode 98 { 99 ResetSession = 0, 100 ResetSessionAndData = 1, 101 ResetAll = 2 102 }; 103 104 class GPGProc::Private : public QObject 105 { 106 Q_OBJECT 107 public: 108 GPGProc * q; 109 QString bin; 110 QStringList args; 111 GPGProc::Mode mode; 112 SProcess * proc; 113 QProcessSignalRelay *proc_relay; 114 QCA::QPipe pipeAux, pipeCommand, pipeStatus; 115 QByteArray statusBuf; 116 QStringList statusLines; 117 GPGProc::Error error; 118 int exitCode; 119 QCA::SafeTimer startTrigger, doneTrigger; 120 121 QByteArray pre_stdin, pre_aux; 122 #ifdef QPIPE_SECURE 123 QCA::SecureArray pre_command; 124 #else 125 QByteArray pre_command; 126 #endif 127 bool pre_stdin_close, pre_aux_close, pre_command_close; 128 129 bool need_status, fin_process, fin_process_success, fin_status; 130 QByteArray leftover_stdout; 131 QByteArray leftover_stderr; 132 133 Private(GPGProc *_q); 134 ~Private() override; 135 void closePipes(); 136 void reset(ResetMode mode); 137 bool setupPipes(bool makeAux); 138 void setupArguments(); 139 140 public Q_SLOTS: 141 void doStart(); 142 void aux_written(int x); 143 void aux_error(QCA::QPipeEnd::Error); 144 void command_written(int x); 145 void command_error(QCA::QPipeEnd::Error); 146 void status_read(); 147 void status_error(QCA::QPipeEnd::Error e); 148 void proc_started(); 149 void proc_readyReadStandardOutput(); 150 void proc_readyReadStandardError(); 151 void proc_bytesWritten(qint64 lx); 152 void proc_finished(int x); 153 void proc_error(QProcess::ProcessError x); 154 void doTryDone(); 155 156 private: 157 bool readAndProcessStatusData(); 158 // return true if there are newly parsed lines available 159 bool processStatusData(const QByteArray &buf); 160 }; 161 162 } // end namespace gpgQCAPlugin 163