97
static QByteArray hexencode( const QByteArray & in ) {
99
// changed from returning QByteArray to returning std::string
100
static std::string hexencode( const QByteArray & in ) {
98
101
if ( in.isNull() )
100
const std::string result = hexencode( std::string( in.constData() ) );
101
return QByteArray( result.data(), result.size() );
102
return std::string();
103
return hexencode( std::string( in.data(), in.size() ) );
103
105
// end copied from kleopatra/utils/hex.cpp
188
190
void Command::setOptionValue( const char * name, const QVariant & value, bool critical ) {
189
191
if ( !name || !*name )
191
const QMutexLocker locker( &d->mutex );
192
193
const Private::Option opt = {
198
const QMutexLocker locker( &d->mutex );
197
199
d->inputs.options[name] = opt;
259
261
return d->inputs.filePaths;
265
void Command::setRecipients( const QStringList & recipients, bool informative ) {
266
const QMutexLocker locker( &d->mutex );
267
d->inputs.recipients = recipients;
268
d->inputs.areRecipientsInformative = informative;
271
QStringList Command::recipients() const {
272
const QMutexLocker locker( &d->mutex );
273
return d->inputs.recipients;
276
bool Command::areRecipientsInformative() const {
277
const QMutexLocker locker( &d->mutex );
278
return d->inputs.areRecipientsInformative;
282
void Command::setSenders( const QStringList & senders, bool informative ) {
283
const QMutexLocker locker( &d->mutex );
284
d->inputs.senders = senders;
285
d->inputs.areSendersInformative = informative;
288
QStringList Command::senders() const {
289
const QMutexLocker locker( &d->mutex );
290
return d->inputs.senders;
293
bool Command::areSendersInformative() const {
294
const QMutexLocker locker( &d->mutex );
295
return d->inputs.areSendersInformative;
299
void Command::setInquireData( const char * what, const QByteArray & data ) {
300
const QMutexLocker locker( &d->mutex );
301
d->inputs.inquireData[what] = data;
304
void Command::unsetInquireData( const char * what ) {
305
const QMutexLocker locker( &d->mutex );
306
d->inputs.inquireData.erase( what );
309
QByteArray Command::inquireData( const char * what ) const {
310
const QMutexLocker locker( &d->mutex );
311
const std::map<std::string,QByteArray>::const_iterator it = d->inputs.inquireData.find( what );
312
if ( it == d->inputs.inquireData.end() )
318
bool Command::isInquireDataSet( const char * what ) const {
319
const QMutexLocker locker( &d->mutex );
320
const std::map<std::string,QByteArray>::const_iterator it = d->inputs.inquireData.find( what );
321
return it != d->inputs.inquireData.end();
262
325
QByteArray Command::receivedData() const {
263
326
const QMutexLocker locker( &d->mutex );
264
327
return d->outputs.data;
279
342
// here comes the ugly part
346
static void my_assuan_release( assuan_context_t ctx ) {
348
assuan_release( ctx );
282
352
typedef shared_ptr< remove_pointer<assuan_context_t>::type > AssuanContextBase;
284
354
struct AssuanClientContext : AssuanContextBase {
285
355
AssuanClientContext() : AssuanContextBase() {}
286
357
explicit AssuanClientContext( assuan_context_t ctx ) : AssuanContextBase( ctx, &assuan_disconnect ) {}
287
358
void reset( assuan_context_t ctx=0 ) { AssuanContextBase::reset( ctx, &assuan_disconnect ); }
360
explicit AssuanClientContext( assuan_context_t ctx ) : AssuanContextBase( ctx, &my_assuan_release ) {}
361
void reset( assuan_context_t ctx=0 ) { AssuanContextBase::reset( ctx, &my_assuan_release ); }
367
// compatibility typedef - remove when we require assuan v2...
368
typedef gpg_error_t assuan_error_t;
291
371
static assuan_error_t
292
372
my_assuan_transact( const AssuanClientContext & ctx,
293
373
const char *command,
416
static QString uiserver_executable() {
417
return QLatin1String( "kleopatra" );
336
420
static QString start_uiserver() {
337
return Command::tr("start_uiserver: not yet implemented");
421
if ( !QProcess::startDetached( uiserver_executable(), QStringList() << QLatin1String( "--daemon" ) ) )
422
return Command::tr( "Failed to start uiserver %1" ).arg( uiserver_executable() );
340
427
static assuan_error_t getinfo_pid_cb( void * opaque, const void * buffer, size_t length ) {
440
struct inquire_data {
441
const std::map<std::string,QByteArray> * map;
442
const AssuanClientContext * ctx;
446
static assuan_error_t command_inquire_cb( void * opaque, const char * what ) {
449
const inquire_data & id = *static_cast<const inquire_data*>( opaque );
450
const std::map<std::string,QByteArray>::const_iterator it = id.map->find( what );
451
if ( it != id.map->end() ) {
452
const QByteArray & v = it->second;
453
assuan_send_data( id.ctx->get(), v.data(), v.size() );
458
static inline std::ostream & operator<<( std::ostream & s, const QByteArray & ba ) {
459
return s << std::string( ba.data(), ba.size() );
352
462
static assuan_error_t send_option( const AssuanClientContext & ctx, const char * name, const QVariant & value ) {
463
std::stringstream ss;
464
ss << "OPTION " << name;
353
465
if ( value.isValid() )
354
return my_assuan_transact( ctx, QString().sprintf( "OPTION %s=%s", name, value.toString().toUtf8().constData() ).toUtf8().constData() );
356
return my_assuan_transact( ctx, QString().sprintf( "OPTION %s", name ).toUtf8().constData() );
466
ss << '=' << value.toString().toUtf8();
467
return my_assuan_transact( ctx, ss.str().c_str() );
359
470
static assuan_error_t send_file( const AssuanClientContext & ctx, const QString & file ) {
360
return my_assuan_transact( ctx, QString().sprintf( "FILE %s", hexencode( QFile::encodeName( file ) ).constData() ).toUtf8().constData() );
471
std::stringstream ss;
472
ss << "FILE " << hexencode( QFile::encodeName( file ) );
473
return my_assuan_transact( ctx, ss.str().c_str() );
476
static assuan_error_t send_recipient( const AssuanClientContext & ctx, const QString & recipient, bool info ) {
477
std::stringstream ss;
481
ss << "--" << hexencode( recipient.toUtf8() );
482
return my_assuan_transact( ctx, ss.str().c_str() );
485
static assuan_error_t send_sender( const AssuanClientContext & ctx, const QString & sender, bool info ) {
486
std::stringstream ss;
490
ss << "--" << hexencode( sender.toUtf8() );
491
return my_assuan_transact( ctx, ss.str().c_str() );
363
494
void Command::Private::run() {
374
505
out.canceled = false;
376
assuan_error_t err = 0;
507
if ( out.serverLocation.isEmpty() )
508
out.serverLocation = default_socket_name();
378
511
assuan_context_t naked_ctx = 0;
379
513
AssuanClientContext ctx;
514
assuan_error_t err = 0;
381
if ( out.serverLocation.isEmpty() )
382
out.serverLocation = default_socket_name();
516
inquire_data id = { &in.inquireData, &ctx };
384
518
const QString socketName = out.serverLocation;
385
519
if ( socketName.isEmpty() ) {
390
525
err = assuan_socket_connect( &naked_ctx, QFile::encodeName( socketName ).constData(), -1 );
528
assuan_context_t naked_ctx = 0;
529
err = assuan_new( &naked_ctx );
531
out.errorString = tr( "Could not allocate resources to connect to Kleopatra UI server at %1: %2" )
532
.arg( socketName, to_error_string( err ) );
536
ctx.reset( naked_ctx );
540
err = assuan_socket_connect( ctx.get(), QFile::encodeName( socketName ).constData(), -1, 0 );
392
543
qDebug( "UI server not running, starting it" );
400
551
// give it a bit of time to start up and try a couple of times
401
552
for ( int i = 0 ; err && i < 20 ; ++i ) {
403
555
err = assuan_socket_connect( &naked_ctx, QFile::encodeName( socketName ).constData(), -1 );
557
err = assuan_socket_connect( ctx.get(), QFile::encodeName( socketName ).constData(), -1, 0 );
434
591
if ( in.parentWId ) {
592
#if defined(Q_OS_WIN32) || defined(_WIN32_WCE)
436
593
err = send_option( ctx, "window-id", QString().sprintf( "%lx", reinterpret_cast<unsigned long>( in.parentWId ) ) );
438
595
err = send_option( ctx, "window-id", QString().sprintf( "%lx", static_cast<unsigned long>( in.parentWId ) ) );
619
Q_FOREACH( const QString & sender, in.senders )
620
if ( ( err = send_sender( ctx, sender, in.areSendersInformative ) ) ) {
621
out.errorString = tr("Failed to send sender %1: %2")
622
.arg( sender, to_error_string( err ) );
626
Q_FOREACH( const QString & recipient, in.recipients )
627
if ( ( err = send_recipient( ctx, recipient, in.areRecipientsInformative ) ) ) {
628
out.errorString = tr("Failed to send recipient %1: %2")
629
.arg( recipient, to_error_string( err ) );
466
err = my_assuan_transact( ctx, in.command.constData(), &command_data_cb, &out.data );
637
err = my_assuan_transact( ctx, in.command.constData(), &command_data_cb, &out.data, &command_inquire_cb, &id );
468
639
if ( gpg_err_code( err ) == GPG_ERR_CANCELED )
469
640
out.canceled = true;