$NetBSD: patch-an,v 1.1 2010/09/01 13:45:25 wiz Exp $

libassuan2 support from
http://websvn.kde.org/?view=revision&revision=1078528

--- kleopatra/uiserver/assuanserverconnection.cpp.orig	2009-11-21 09:45:01.000000000 +0000
+++ kleopatra/uiserver/assuanserverconnection.cpp
@@ -116,13 +116,18 @@ static const unsigned int INIT_SOCKET_FL
 static const int FOR_READING = 0;
 static const unsigned int MAX_ACTIVE_FDS = 32;
 
+static void my_assuan_release( assuan_context_t ctx ) {
+    if ( ctx )
+        assuan_release( ctx );
+}
+
 // shared_ptr for assuan_context_t w/ deleter enforced to assuan_deinit_server:
 typedef shared_ptr< remove_pointer<assuan_context_t>::type > AssuanContextBase;
 struct AssuanContext : AssuanContextBase {
     AssuanContext() : AssuanContextBase() {}
-    explicit AssuanContext( assuan_context_t ctx ) : AssuanContextBase( ctx, &assuan_deinit_server ) {}
+    explicit AssuanContext( assuan_context_t ctx ) : AssuanContextBase( ctx, &my_assuan_release ) {}
 
-    void reset( assuan_context_t ctx=0 ) { AssuanContextBase::reset( ctx, &assuan_deinit_server ); }
+    void reset( assuan_context_t ctx=0 ) { AssuanContextBase::reset( ctx, &my_assuan_release ); }
 };
 
 static inline gpg_error_t assuan_process_done_msg( assuan_context_t ctx, gpg_error_t err, const char * err_msg ) {
@@ -240,7 +245,8 @@ Q_SIGNALS:
 public Q_SLOTS:
     void slotReadActivity( int ) {
         assert( ctx );
-        if ( const int err = assuan_process_next( ctx.get() ) ) {
+        int done = false;
+        if ( const int err = assuan_process_next( ctx.get(), &done ) || done ) {
             //if ( err == -1 || gpg_err_code(err) == GPG_ERR_EOF ) {
                 topHalfDeletion();
                 if ( nohupedCommands.empty() )
@@ -296,15 +302,17 @@ private:
     }
 
 private:
-    static void reset_handler( assuan_context_t ctx_ ) {
+    static gpg_error_t reset_handler( assuan_context_t ctx_, char * ) {
         assert( assuan_get_pointer( ctx_ ) );
 
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
 
         conn.reset();
+
+        return 0;
     }
 
-    static int option_handler( assuan_context_t ctx_, const char * key, const char * value ) {
+    static gpg_error_t option_handler( assuan_context_t ctx_, const char * key, const char * value ) {
         assert( assuan_get_pointer( ctx_ ) );
 
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
@@ -317,7 +325,7 @@ private:
         //return gpg_error( GPG_ERR_UNKNOWN_OPTION );
     }
 
-    static int session_handler( assuan_context_t ctx_, char * line ) {
+    static gpg_error_t session_handler( assuan_context_t ctx_, char * line ) {
         assert( assuan_get_pointer( ctx_ ) );
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
 
@@ -344,7 +352,7 @@ private:
         return assuan_process_done( ctx_, 0 );
     }
 
-    static int capabilities_handler( assuan_context_t ctx_, char * line ) {
+    static gpg_error_t capabilities_handler( assuan_context_t ctx_, char * line ) {
         if ( !QByteArray( line ).trimmed().isEmpty() ) {
             static const QString errorString = i18n("CAPABILITIES does not take arguments");
             return assuan_process_done_msg( ctx_, gpg_error( GPG_ERR_ASS_PARAMETER ), errorString );
@@ -357,7 +365,7 @@ private:
         return assuan_process_done( ctx_, assuan_send_data( ctx_, capabilities, sizeof capabilities - 1 ) );
     }
 
-    static int getinfo_handler( assuan_context_t ctx_, char * line ) {
+    static gpg_error_t getinfo_handler( assuan_context_t ctx_, char * line ) {
         assert( assuan_get_pointer( ctx_ ) );
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
 
@@ -386,7 +394,7 @@ private:
         return assuan_process_done( ctx_, assuan_send_data( ctx_, ba.constData(), ba.size() ) );
     }
 
-    static int start_keymanager_handler( assuan_context_t ctx_, char * line ) {
+    static gpg_error_t start_keymanager_handler( assuan_context_t ctx_, char * line ) {
         assert( assuan_get_pointer( ctx_ ) );
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
 
@@ -400,7 +408,7 @@ private:
         return assuan_process_done( ctx_, 0 );
     }
 
-    static int start_confdialog_handler( assuan_context_t ctx_, char * line ) {
+    static gpg_error_t start_confdialog_handler( assuan_context_t ctx_, char * line ) {
         assert( assuan_get_pointer( ctx_ ) );
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
 
@@ -418,7 +426,7 @@ private:
 
     // format: TAG (FD|FD=\d+|FILE=...)
     template <bool in, typename T_memptr>
-    static int IO_handler( assuan_context_t ctx_, char * line_, T_memptr which ) {
+    static gpg_error_t IO_handler( assuan_context_t ctx_, char * line_, T_memptr which ) {
         assert( assuan_get_pointer( ctx_ ) );
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
 
@@ -498,19 +506,19 @@ private:
 
     }
 
-    static int input_handler( assuan_context_t ctx, char * line ) {
+    static gpg_error_t input_handler( assuan_context_t ctx, char * line ) {
         return IO_handler<true>( ctx, line, &Private::inputs );
     }
 
-    static int output_handler( assuan_context_t ctx, char * line ) {
+    static gpg_error_t output_handler( assuan_context_t ctx, char * line ) {
         return IO_handler<false>( ctx, line, &Private::outputs );
     }
 
-    static int message_handler( assuan_context_t ctx, char * line ) {
+    static gpg_error_t message_handler( assuan_context_t ctx, char * line ) {
         return IO_handler<true>( ctx, line, &Private::messages );
     }
 
-    static int file_handler( assuan_context_t ctx_, char * line ) {
+    static gpg_error_t file_handler( assuan_context_t ctx_, char * line ) {
         assert( assuan_get_pointer( ctx_ ) );
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
 
@@ -572,7 +580,7 @@ private:
     }
 
     template <typename T_memptr, typename T_memptr2>
-    static int recipient_sender_handler( T_memptr mp, T_memptr2 info, assuan_context_t ctx, char * line, bool sender=false ) {
+    static gpg_error_t recipient_sender_handler( T_memptr mp, T_memptr2 info, assuan_context_t ctx, char * line, bool sender=false ) {
         assert( assuan_get_pointer( ctx ) );
         AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx ) );
 
@@ -656,11 +664,11 @@ private:
         return assuan_process_done( ctx, 0 );
     }
 
-    static int recipient_handler( assuan_context_t ctx, char * line ) {
+    static gpg_error_t recipient_handler( assuan_context_t ctx, char * line ) {
         return recipient_sender_handler( &Private::recipients, &Private::informativeRecipients, ctx, line );
     }
 
-    static int sender_handler( assuan_context_t ctx, char * line ) {
+    static gpg_error_t sender_handler( assuan_context_t ctx, char * line ) {
         return recipient_sender_handler( &Private::senders, &Private::informativeSenders, ctx, line, true );
     }
 
@@ -792,11 +800,15 @@ AssuanServerConnection::Private::Private
     if ( fd == ASSUAN_INVALID_FD )
         throw Exception( gpg_error( GPG_ERR_INV_ARG ), "pre-assuan_init_socket_server_ext" );
 
-    assuan_context_t naked_ctx = 0;
-    if ( const gpg_error_t err = assuan_init_socket_server_ext( &naked_ctx, fd, INIT_SOCKET_FLAGS ) )
+    {
+        assuan_context_t naked_ctx = 0;
+        if ( const gpg_error_t err = assuan_new( &naked_ctx ) )
+            throw Exception( err, "assuan_new" );
+        ctx.reset( naked_ctx );
+    }
+    if ( const gpg_error_t err = assuan_init_socket_server( ctx.get(), fd, INIT_SOCKET_FLAGS ) )
         throw Exception( err, "assuan_init_socket_server_ext" );
 
-    ctx.reset( naked_ctx ); naked_ctx = 0;
 
     // for callbacks, associate the context with this connection:
     assuan_set_pointer( ctx.get(), this );
@@ -824,34 +836,34 @@ AssuanServerConnection::Private::Private
 
 
     // register our INPUT/OUTPUT/MESSGAE/FILE handlers:
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "INPUT",  input_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "INPUT",  input_handler, "" ) )
         throw Exception( err, "register \"INPUT\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "MESSAGE",  message_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "MESSAGE",  message_handler, "" ) )
         throw Exception( err, "register \"MESSAGE\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "OUTPUT", output_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "OUTPUT", output_handler, "" ) )
         throw Exception( err, "register \"OUTPUT\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "FILE", file_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "FILE", file_handler, "" ) )
         throw Exception( err, "register \"FILE\" handler" );
 
 
     // register user-defined commands:
     Q_FOREACH( shared_ptr<AssuanCommandFactory> fac, factories )
-        if ( const gpg_error_t err = assuan_register_command( ctx.get(), fac->name(), fac->_handler() ) )
+        if ( const gpg_error_t err = assuan_register_command( ctx.get(), fac->name(), fac->_handler(), "" ) )
             throw Exception( err, std::string( "register \"" ) + fac->name() + "\" handler" );
 
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "GETINFO", getinfo_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "GETINFO", getinfo_handler, "" ) )
         throw Exception( err, "register \"GETINFO\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "START_KEYMANAGER", start_keymanager_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "START_KEYMANAGER", start_keymanager_handler, "" ) )
         throw Exception( err, "register \"START_KEYMANAGER\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "START_CONFDIALOG", start_confdialog_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "START_CONFDIALOG", start_confdialog_handler, "" ) )
         throw Exception( err, "register \"START_CONFDIALOG\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "RECIPIENT", recipient_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "RECIPIENT", recipient_handler, "" ) )
         throw Exception( err, "register \"RECIPIENT\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "SENDER", sender_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "SENDER", sender_handler, "" ) )
         throw Exception( err, "register \"SENDER\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "SESSION", session_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "SESSION", session_handler, "" ) )
         throw Exception( err, "register \"SESSION\" handler" );
-    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "CAPABILITIES", capabilities_handler ) )
+    if ( const gpg_error_t err = assuan_register_command( ctx.get(), "CAPABILITIES", capabilities_handler, "" ) )
         throw Exception( err, "register \"CAPABILITIES\" handler" );
 
     assuan_set_hello_line( ctx.get(), "GPG UI server (Kleopatra/" KLEOPATRA_VERSION_STRING ") ready to serve" );
@@ -904,20 +916,14 @@ class InquiryHandler : public QObject {
     Q_OBJECT
 public:
 
-#ifdef HAVE_ASSUAN_INQUIRE_EXT
     explicit InquiryHandler( const char * keyword_, QObject * p=0 )
         : QObject( p ),
-# ifndef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
-          buffer( 0 ),
-          buflen( 0 ),
-# endif
           keyword( keyword_ )
     {
 
     }
 
-# ifdef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
-    static int handler( void * cb_data, int rc, unsigned char * buffer, size_t buflen )
+    static gpg_error_t handler( void * cb_data, gpg_error_t rc, unsigned char * buffer, size_t buflen )
     {
         assert( cb_data );
         InquiryHandler * this_ = static_cast<InquiryHandler*>(cb_data);
@@ -926,26 +932,9 @@ public:
         delete this_;
         return 0;
     }
-# else
-    static int handler( void * cb_data, int rc )
-    {
-        assert( cb_data );
-        InquiryHandler * this_ = static_cast<InquiryHandler*>(cb_data);
-        emit this_->signal( rc, QByteArray::fromRawData( reinterpret_cast<const char*>(this_->buffer), this_->buflen ), this_->keyword );
-        std::free( this_->buffer );
-        delete this_;
-        return 0;
-    }
-# endif
 
 private:
-# ifndef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
-    friend class ::Kleo::AssuanCommand;
-    unsigned char * buffer;
-    size_t buflen;
-# endif
     const char * keyword;
-#endif // HAVE_ASSUAN_INQUIRE_EXT
 
 Q_SIGNALS:
     void signal( int rc, const QByteArray & data, const QByteArray & keyword );
@@ -1157,20 +1146,13 @@ int AssuanCommand::inquire( const char *
     if ( d->nohup )
         return makeError( GPG_ERR_INV_OP );
 
-#ifdef HAVE_ASSUAN_INQUIRE_EXT
     std::auto_ptr<InquiryHandler> ih( new InquiryHandler( keyword, receiver ) );
     receiver->connect( ih.get(), SIGNAL(signal(int,QByteArray,QByteArray)), slot );
     if ( const gpg_error_t err = assuan_inquire_ext( d->ctx.get(), keyword,
-# ifndef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
-                                                     &ih->buffer, &ih->buflen,
-# endif
                                                      maxSize, InquiryHandler::handler, ih.get() ) )
          return err;
     ih.release();
     return 0;
-#else
-    return makeError( GPG_ERR_NOT_SUPPORTED ); // libassuan too old
-#endif // HAVE_ASSUAN_INQUIRE_EXT
 }
 
 void AssuanCommand::done( const GpgME::Error& err, const QString & details ) {
@@ -1262,7 +1244,7 @@ const std::vector<KMime::Types::Mailbox>
     return d->senders;
 }
 
-int AssuanCommandFactory::_handle( assuan_context_t ctx, char * line, const char * commandName ) {
+gpg_error_t AssuanCommandFactory::_handle( assuan_context_t ctx, char * line, const char * commandName ) {
     assert( assuan_get_pointer( ctx ) );
     AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx ) );
 
