33 #include "gnupgprocessbase.h"
38 #include <tqsocketnotifier.h>
39 #include <tqtextcodec.h>
40 #include <tqstringlist.h>
47 struct Kleo::GnuPGProcessBase::Private {
48 Private() : usetStatusFD( false ), statnot( 0 ) {
49 statusFD[0] = statusFD[1] = -1;
54 TQSocketNotifier * statnot;
55 TQCString statusBuffer;
59 Kleo::GnuPGProcessBase::GnuPGProcessBase( TQObject * parent,
const char * name )
60 : TDEProcess( parent, name )
65 Kleo::GnuPGProcessBase::~GnuPGProcessBase() {
69 void Kleo::GnuPGProcessBase::setUsetStatusFD(
bool use ) {
71 d->usetStatusFD = use;
75 if ( d->usetStatusFD ) {
80 if ( ::pipe( d->statusFD ) < 0 ) {
81 kdDebug( 5150 ) <<
"Kleo::GnuPGProcessBase::start: pipe(2) failed: " << perror << endl;
84 ::fcntl( d->statusFD[0], F_SETFD, FD_CLOEXEC );
85 ::fcntl( d->statusFD[1], F_SETFD, FD_CLOEXEC );
86 if ( !arguments.empty() ) {
87 TQValueList<TQCString>::iterator it = arguments.begin();
89 arguments.insert( it,
"--status-fd" );
91 sprintf( buf,
"%d", d->statusFD[1] );
92 arguments.insert( it, buf );
93 arguments.insert( it,
"--no-tty" );
97 return TDEProcess::start( runmode, comm );
101 if (
int ok = TDEProcess::setupCommunication( comm ) )
103 if ( d->usetStatusFD ) {
105 ::close( d->statusFD[0] );
106 ::close( d->statusFD[1] );
107 d->statusFD[0] = d->statusFD[1] = -1;
113 if ( d->usetStatusFD ) {
114 ::close( d->statusFD[1] );
115 d->statnot =
new TQSocketNotifier( d->statusFD[0], TQSocketNotifier::Read,
this );
116 connect( d->statnot, TQ_SIGNAL(activated(
int)), TQ_SLOT(slotChildStatus(
int)) );
118 return TDEProcess::commSetupDoneP();
122 if ( d->usetStatusFD )
123 ::fcntl( d->statusFD[1], F_SETFD, 0 );
124 return TDEProcess::commSetupDoneC();
127 void Kleo::GnuPGProcessBase::slotChildStatus(
int fd ) {
128 if ( !childStatus(fd) )
132 bool Kleo::GnuPGProcessBase::closetStatus() {
133 if ( !d->usetStatusFD )
135 d->usetStatusFD =
false;
136 delete d->statnot; d->statnot = 0;
137 ::close( d->statusFD[0] ); d->statusFD[0] = -1;
141 int Kleo::GnuPGProcessBase::childStatus(
int fd ) {
143 const int len = ::read( fd, buf,
sizeof(buf)-1 );
146 d->statusBuffer += buf;
147 parsetStatusOutput();
152 static TQString fromHexEscapedUtf8(
const TQCString & str ) {
153 return KURL::decode_string( str.data(), 106 );
156 void Kleo::GnuPGProcessBase::parsetStatusOutput() {
157 static const char startToken[] =
"[GNUPG:] ";
158 static const int startTokenLen =
sizeof startToken /
sizeof *startToken - 1;
161 for (
int lineEnd = d->statusBuffer.find(
'\n' ) ; lineEnd >= 0 ; lineEnd = d->statusBuffer.find(
'\n', lineStart = lineEnd+1 ) ) {
163 const TQCString line = d->statusBuffer.mid( lineStart, lineEnd - lineStart ).stripWhiteSpace();
164 if ( line.isEmpty() )
167 if ( line.left( startTokenLen ) != startToken ) {
168 kdDebug( 5150 ) <<
"Kleo::GnuPGProcessBase::childStatus: status-fd protocol error: line doesn't begin with \""
169 << startToken <<
"\"" << endl;
173 const TQCString command = line.mid( startTokenLen ).simplifyWhiteSpace() +
' ';
174 if ( command ==
" " ) {
175 kdDebug( 5150 ) <<
"Kleo::GnuPGProcessBase::childStatus: status-fd protocol error: line without content." << endl;
182 for (
int tagEnd = command.find(
' ' ) ; tagEnd >= 0 ; tagEnd = command.find(
' ', tagStart = tagEnd+1 ) ) {
183 const TQCString tag = command.mid( tagStart, tagEnd - tagStart );
185 cmd = fromHexEscapedUtf8( tag );
187 args.push_back( fromHexEscapedUtf8( tag ) );
189 emit status(
this, cmd, args );
191 d->statusBuffer = d->statusBuffer.mid( lineStart );
195 TDEProcess::virtual_hook(
id, data );
198 #include "gnupgprocessbase.moc"
int setupCommunication(Communication comm)
void virtual_hook(int id, void *data)
bool start(RunMode runmode, Communication comm)