Это код из gpgme ++, который оборачивает основанный на обратном вызове интерфейс в интерфейс C ++:
Интерфейс:
class PassphraseProvider {
public:
virtual ~PassphraseProvider() {}
virtual char * getPassphrase( const char * useridHint,
const char * description,
bool previousWasBad,
bool & canceled ) = 0;
};
Предполагается, что функция отображает description
в качестве приглашения и возвращает введенную фразу-пароль (буфер должен быть malloc()
ed). Он также может установить canceled
на true
, чтобы указать, что пользователь прервал. Параметры useridHint
и previousWasBad
являются просто дополнительной информацией.
А это этот универсальный обратный вызов:
// Code taken from gpgme++, license: LGPLv2+
static
gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, const char * desc,
int prev_was_bad, int fd ) {
PassphraseProvider * provider = static_cast<PassphraseProvider*>( opaque );
bool canceled = false;
gpgme_error_t err = GPG_ERR_NO_ERROR;
char * passphrase = provider ? provider->getPassphrase( uid_hint, desc, prev_was_bad, canceled ) : 0 ;
if ( canceled )
err = make_error( GPG_ERR_CANCELED );
else
if ( passphrase && *passphrase ) {
size_t passphrase_length = std::strlen( passphrase );
size_t written = 0;
do {
#ifdef HAVE_GPGME_IO_READWRITE
ssize_t now_written = gpgme_io_write( fd, passphrase + written, passphrase_length - written );
#else
ssize_t now_written = write( fd, passphrase + written, passphrase_length - written );
#endif
if ( now_written < 0 ) {
err = make_err_from_syserror();
break;
}
written += now_written;
} while ( written < passphrase_length );
}
free( passphrase );
#ifdef HAVE_GPGME_IO_READWRITE
gpgme_io_write( fd, "\n", 1 );
#else
write( fd, "\n", 1 );
#endif
return err;
}
Учитывая реализацию pp
интерфейса PassphraseProvider
, вы бы связали все вместе так:
gpgme_set_passphrase_cb( ctx, &passphrase_callback, pp );