diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-16 16:06:07 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-16 16:06:07 -0600 |
commit | be0ca741fd12897337408d1d7a7d8f5f18e1fac9 (patch) | |
tree | b9fa3458193a17180d8773a0204ee05ae206cd99 /libtdenetwork | |
parent | bbb7afdb6da2969535e7f05715e2cb95cfdc917c (diff) | |
download | tdepim-be0ca741fd12897337408d1d7a7d8f5f18e1fac9.tar.gz tdepim-be0ca741fd12897337408d1d7a7d8f5f18e1fac9.zip |
Finish rename from prior commit
Diffstat (limited to 'libtdenetwork')
173 files changed, 42092 insertions, 0 deletions
diff --git a/libtdenetwork/CMakeLists.txt b/libtdenetwork/CMakeLists.txt new file mode 100644 index 00000000..1eaefeaa --- /dev/null +++ b/libtdenetwork/CMakeLists.txt @@ -0,0 +1,20 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +project( libtdenetwork ) + +add_subdirectory( gpgmepp ) +add_subdirectory( qgpgme ) + + +##### install import cmake modules ############### + +tde_install_export( ) diff --git a/libtdenetwork/Makefile.am b/libtdenetwork/Makefile.am new file mode 100644 index 00000000..e1014e58 --- /dev/null +++ b/libtdenetwork/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = $(all_includes) + +if needs_gpgme_copy +GPGME_COPY_SUBDIRS = libgpg-error-copy libgpgme-copy +endif +SUBDIRS = $(GPGME_COPY_SUBDIRS) gpgmepp qgpgme . + diff --git a/libtdenetwork/gpgmepp/CMakeLists.txt b/libtdenetwork/gpgmepp/CMakeLists.txt new file mode 100644 index 00000000..cf4efc7f --- /dev/null +++ b/libtdenetwork/gpgmepp/CMakeLists.txt @@ -0,0 +1,54 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +add_subdirectory( interfaces ) + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/libtdenetwork + ${CMAKE_SOURCE_DIR}/libtdepim + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} + ${GPGME_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### headers ################################### + +install( FILES + context.h key.h trustitem.h eventloopinteractor.h + data.h gpgmefw.h result.h keylistresult.h + keygenerationresult.h importresult.h decryptionresult.h + verificationresult.h signingresult.h encryptionresult.h + engineinfo.h + DESTINATION ${INCLUDE_INSTALL_DIR}/kde/gpgme++ ) + + +##### gpgme++ (shared) ########################## + +tde_add_library( gpgme++ SHARED + SOURCES + context.cpp key.cpp trustitem.cpp data.cpp + callbacks.cpp eventloopinteractor.cpp + keylistresult.cpp keygenerationresult.cpp + importresult.cpp decryptionresult.cpp + verificationresult.cpp signingresult.cpp + encryptionresult.cpp engineinfo.cpp + VERSION 0.4.0 + LINK ${TQT_LIBRARIES} ${GPGME_LIBRARIES} + DESTINATION ${LIB_INSTALL_DIR} +) diff --git a/libtdenetwork/gpgmepp/Makefile.am b/libtdenetwork/gpgmepp/Makefile.am new file mode 100644 index 00000000..d4ebfde9 --- /dev/null +++ b/libtdenetwork/gpgmepp/Makefile.am @@ -0,0 +1,52 @@ +KDE_OPTIONS = foreign +#AM_CXXFLAGS = -Wno-deprecated-declarations + +SUBDIRS = interfaces . + +INCLUDES = -I$(top_srcdir)/libtdenetwork -I$(top_srcdir)/libtdenetwork/gpgmepp \ + $(GPGME_CFLAGS) $(all_includes) + +gpgmeppdir = $(includedir)/gpgme++ +gpgmepp_HEADERS = context.h \ + key.h \ + trustitem.h \ + eventloopinteractor.h \ + data.h \ + gpgmefw.h \ + result.h \ + keylistresult.h \ + keygenerationresult.h \ + importresult.h \ + decryptionresult.h \ + verificationresult.h \ + signingresult.h \ + encryptionresult.h \ + engineinfo.h + +noinst_HEADERS = context_p.h data_p.h shared.h callbacks.h gpgme-0-3-compat.h result_p.h util.h + +lib_LTLIBRARIES = libgpgme++.la +libgpgme___la_SOURCES = context.cpp \ + key.cpp \ + trustitem.cpp \ + data.cpp \ + callbacks.cpp \ + eventloopinteractor.cpp \ + keylistresult.cpp \ + keygenerationresult.cpp \ + importresult.cpp \ + decryptionresult.cpp \ + verificationresult.cpp \ + signingresult.cpp \ + encryptionresult.cpp \ + engineinfo.cpp + +# --version-info CURRENT:REVISION:AGE +# (Code changed: REVISION++) +# (Interfaces added/removed/changed: CURRENT++, REVISION=0) +# (Interfaces added: AGE++) +# (Interfaces removed/changed: AGE=0) +libgpgme___la_LDFLAGS = -no-undefined -version-info 4:0:4 +libgpgme___la_LIBADD = $(GPGME_LIBS) +libgpgme___la_DEPENDENCIES = $(GPGME_LIBS_DEP) + diff --git a/libtdenetwork/gpgmepp/README.gpgme++ b/libtdenetwork/gpgmepp/README.gpgme++ new file mode 100644 index 00000000..ecda2c9a --- /dev/null +++ b/libtdenetwork/gpgmepp/README.gpgme++ @@ -0,0 +1,82 @@ + GpgME++ - C++ bindings/wrapper for gpgme + ------------------------------------ + Version 0.0.1 + + Copyright (c) 2003, 2004 Klarälvdalens Datakonsult AB + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + + + Overview + -------- + + GpgME++ is a C++ wrapper (or C++ bindings) for the GnuPG project's + gpgme (GnuPG Made Easy) library, version 0.4.4 and later. + + It is fairly complete, with some minor things still missing (in + particular, the key edit interface). It is mostly tested using + external event loops, for which its design is optimised. + + The design principles of this library are as follows: + + 1. A value-based interface (most clases are implicitly shared) + 2. Callbacks are replaced by C++ interfaces (classes with only + abstract methods). + 3. No exceptions are thrown + 4. There is (as yet) no explicit support for multi-threaded use + (other than what gpgme itself provides; most notably the + refcounting for implicit sharing is not thread-safe) + 5. To avoid binary incompatible interface changes, we make + extensive use of the d-pointer pattern and avoid virtual + methods; any polymorphism present is already provided by gpgme + itself, anyway (see e.g. Data). A notable exception of the + no-virtuals rule is the use of abstract classes to cover + C-callbacks. + + The authors hope that once there are more users of this library, + the GnuPG project will include it as the official C++ binding for + gpgme. Currently, this is not the case, since it was felt that C++ + bindings can be provided with different design decisions, and that + it is not clear that the decisions made for GpgME++ are broad + enough to be universally applicable (e.g. a pivotal design + decision was to not use exceptions to wrap gpgme_error_t). + + GpgME++ depends on gpgme, which in turn depends on libgpg-error, both + of which must be installed correctly before GpgME++ is to be + built. Furthermore, GpgME++ should be recompiled if the underlying + gpgme is changed. This is to allow closer integration and to + abstract away possible interface changes. Therefore, once this + libray becomes stable, we intend to follow gpgme's versioning. + + Currently, we use the KDE CVS repository to develop our code, + basically because GpgME++ is used in KMail and Kleopatra. However, + the library is in no way dependant on KDE or Qt libraries, and you + are free to use it in your own projects, provided you follow the + license. If you _do_ want to use GpgME++ in Qt/KDE applications, + have a look at QGpgME, which provides integration with QEventLoop + and some Qt datatypes (e.g. QByteArray). + + + Mailing List + ------------ + + Discussion of this library and questions regarding it's use and + design should happen on gpa-dev@gnupg.org or gnupg-devel@gnupg.org. + + + License + ------- + + This library is licensed under the GNU General Public License + (GPL), just as gpgme is. We feel that using a different license + than the one gpgme itself uses doesn't make sense. OTOH, we shall + relicense this library to the GNU Lesser General Public License + (LGPL) should gpgme itself be made available under this license at + any time in the future. diff --git a/libtdenetwork/gpgmepp/callbacks.cpp b/libtdenetwork/gpgmepp/callbacks.cpp new file mode 100644 index 00000000..b352515d --- /dev/null +++ b/libtdenetwork/gpgmepp/callbacks.cpp @@ -0,0 +1,138 @@ +/* callbacks.cpp - callback targets for internal use: + Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "callbacks.h" + +#include <gpgmepp/interfaces/progressprovider.h> +#include <gpgmepp/interfaces/passphraseprovider.h> +#include <gpgmepp/interfaces/dataprovider.h> +#include <gpgmepp/context.h> // for Error + +#include <cassert> +#include <cerrno> +#include <unistd.h> +#include <cstdlib> +#include <string.h> +#include <cstdlib> + +static inline gpg_error_t makeErrorFromErrno() { + return gpg_err_make_from_errno( (gpg_err_source_t)22, errno ); +} +static inline gpg_error_t makeError( gpg_err_code_t code ) { + return gpg_err_make( (gpg_err_source_t)22, code ); +} + +using GpgME::ProgressProvider; +using GpgME::PassphraseProvider; +using GpgME::DataProvider; + +void progress_callback( void * opaque, const char * what, + int type, int current, int total ) { + ProgressProvider * provider = static_cast<ProgressProvider*>( opaque ); + if ( provider ) + provider->showProgress( what, type, current, total ); +} + +static void wipe( char * buf, size_t len ) { + for ( size_t i = 0 ; i < len ; ++i ) + buf[i] = '\0'; +} + +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 = makeError( GPG_ERR_CANCELED ); + else + if ( passphrase && *passphrase ) { + size_t passphrase_length = strlen( passphrase ); + size_t written = 0; + do { + ssize_t now_written = write( fd, passphrase + written, passphrase_length - written ); + if ( now_written < 0 ) { + err = makeErrorFromErrno(); + break; + } + written += now_written; + } while ( written < passphrase_length ); + } + + if ( passphrase && *passphrase ) + wipe( passphrase, strlen( passphrase ) ); + free( passphrase ); + write( fd, "\n", 1 ); + return err; +} + + + +static ssize_t +data_read_callback( void * opaque, void * buf, size_t buflen ) { + DataProvider * provider = static_cast<DataProvider*>( opaque ); + if ( !provider ) { + errno = EINVAL; + return -1; + } + return provider->read( buf, buflen ); +} + +static ssize_t +data_write_callback( void * opaque, const void * buf, size_t buflen ) { + DataProvider * provider = static_cast<DataProvider*>( opaque ); + if ( !provider ) { + errno = EINVAL; + return -1; + } + return provider->write( buf, buflen ); +} + +static off_t +data_seek_callback( void * opaque, off_t offset, int whence ) { + DataProvider * provider = static_cast<DataProvider*>( opaque ); + if ( !provider ) { + errno = EINVAL; + return -1; + } + if ( whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END ) { + errno = EINVAL; + return -1; + } + return provider->seek( offset, whence ); +} + +static void data_release_callback( void * opaque ) { + DataProvider * provider = static_cast<DataProvider*>( opaque ); + if ( provider ) + provider->release(); +} + +gpgme_data_cbs data_provider_callbacks = { + &data_read_callback, + &data_write_callback, + &data_seek_callback, + &data_release_callback +}; + diff --git a/libtdenetwork/gpgmepp/callbacks.h b/libtdenetwork/gpgmepp/callbacks.h new file mode 100644 index 00000000..cc5b9355 --- /dev/null +++ b/libtdenetwork/gpgmepp/callbacks.h @@ -0,0 +1,39 @@ +/* callbacks.h - callback targets for internal use: + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + This is an internal header file, subject to change without + notice. DO NOT USE. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_CALLBACKS_H__ +#define __GPGMEPP_CALLBACKS_H__ + +#include <gpgme.h> + +extern "C" { + + void progress_callback( void * opaque, const char * what, + int type, int current, int total ); + gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, + const char * desc, int prev_was_bad, int fd ); +} + +extern gpgme_data_cbs data_provider_callbacks; + +#endif // __GPGME_CALLBACKS_H__ diff --git a/libtdenetwork/gpgmepp/configure.in.bot b/libtdenetwork/gpgmepp/configure.in.bot new file mode 100644 index 00000000..e4b1a884 --- /dev/null +++ b/libtdenetwork/gpgmepp/configure.in.bot @@ -0,0 +1,10 @@ +if test -z "$GPGME_LIBS" || test -n "$tdepim_needs_gpgme_copy" ; then + echo + echo "You are missing gpgme 0.4.5 or higher." + echo "Gpgme will be built statically from libtdenetwork/libgpgme-copy." + echo "If you are a packager, we most strongly recommend to build against" + echo "the system's shared gpgme." + echo "Consider downloading gpgme >= 0.4.5 from ftp://ftp.gnupg.org/gcrypt/alpha/gpgme" + echo "or use the --with-gpgme-prefix=/path/where/gpgme/is/installed option." + echo +fi diff --git a/libtdenetwork/gpgmepp/configure.in.in b/libtdenetwork/gpgmepp/configure.in.in new file mode 100644 index 00000000..6361be45 --- /dev/null +++ b/libtdenetwork/gpgmepp/configure.in.in @@ -0,0 +1,193 @@ +dnl BEGIN inline of gpgme.m4 from gpgme 0.4.4 +dnl remaned from AM_PATH_GPGME to TDEPIM_PATH_GPGME and inlined here +dnl to not require aclocal fiddling... + +dnl Autoconf macros for libgpgme +dnl Id: gpgme.m4,v 1.6 2003/09/03 01:15:56 marcus Exp + +AC_DEFUN([_TDEPIM_PATH_GPGME_CONFIG], +[ AC_ARG_WITH(gpgme-prefix, + AC_HELP_STRING([--with-gpgme-prefix=PFX], + [prefix where GPGME is installed (optional)]), + gpgme_config_prefix="$withval", gpgme_config_prefix="") + if test "x$gpgme_config_prefix" != x ; then + gpgme_config_path="$gpgme_config_prefix/bin" + else + gpgme_config_path="$PATH:/usr/local/bin" + fi + AC_PATH_PROG(GPGME_CONFIG, gpgme-config, no, $gpgme_config_path) + + if test "x$GPGME_CONFIG" != "xno" ; then + gpgme_version=`$GPGME_CONFIG --version` + gpgme_version_major=`echo $gpgme_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + gpgme_version_minor=`echo $gpgme_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + gpgme_version_micro=`echo $gpgme_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + fi +]) + +dnl AM_PATH_GPGME([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libgpgme and define GPGME_CFLAGS and GPGME_LIBS. +dnl +AC_DEFUN([TDEPIM_PATH_GPGME], +[ AC_REQUIRE([_TDEPIM_PATH_GPGME_CONFIG])dnl + min_gpgme_version=ifelse([$1], ,0.4.2,$1) + AC_MSG_CHECKING(for GPGME - version >= $min_gpgme_version) + ok=no + if test "$GPGME_CONFIG" != "no" ; then + req_major=`echo $min_gpgme_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + req_minor=`echo $min_gpgme_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + req_micro=`echo $min_gpgme_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` + if test "$gpgme_version_major" -gt "$req_major"; then + ok=yes + else + if test "$gpgme_version_major" -eq "$req_major"; then + if test "$gpgme_version_minor" -gt "$req_minor"; then + ok=yes + else + if test "$gpgme_version_minor" -eq "$req_minor"; then + if test "$gpgme_version_micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi + fi + if test $ok = yes; then + GPGME_CFLAGS=`$GPGME_CONFIG --cflags` + GPGME_LIBS=`$GPGME_CONFIG --libs` + if test "x$GPGME_LIBS" != x ; then + if test "x`echo $GPGME_LIBS | grep lgpg-error`" = x ; then + GPGME_LIBS="$GPGME_LIBS -lgpg-error" + fi + fi + AC_MSG_RESULT([yes]) + ifelse([$2], , :, [$2]) + else + GPGME_CFLAGS="" + GPGME_LIBS="" + AC_MSG_RESULT([no, will use local libgpgme-copy]) + ifelse([$3], , :, [$3]) + fi + AC_SUBST(GPGME_CFLAGS) + AC_SUBST(GPGME_LIBS) +]) + +dnl +dnl snip AM_PATH_GPGME_{PTH,PTHREAD} +dnl + +dnl END inline of gpgme.m4 + +# The minimum required gpgme version is 0.4.5. +# It was the first useable one for C++ (class keyword) and KDE (largefile support). +# If you change this minimum version here, update also configure.in.bot + +tdepim_needs_gpgme_copy="" +TDEPIM_PATH_GPGME(0.4.5,[ + AC_LANG_SAVE + AC_LANG_C + tdepim_gpgmepp_save_cflags="$CFLAGS" + tdepim_gpgmepp_save_libs="$LIBS" + CFLAGS="$GPGME_CFLAGS" + LIBS="$GPGME_LIBS" + + AC_MSG_CHECKING([if gpgme has GPGME_KEYLIST_MODE_VALIDATE]) + AC_TRY_COMPILE([#include <gpgme.h>], [ + gpgme_keylist_mode_t mode = GPGME_KEYLIST_MODE_VALIDATE; + ], [ + AC_DEFINE(HAVE_GPGME_KEYLIST_MODE_VALIDATE, 1, [Define to 1 if your gpgme supports GPGME_KEYLIST_MODE_VALIDATE]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + AC_MSG_CHECKING([if gpgme has gpgme_cancel]) + AC_TRY_LINK([#include <gpgme.h>], [ + gpgme_ctx_t ctx = 0; + gpgme_error_t e = gpgme_cancel( ctx ); + ], [ + AC_DEFINE(HAVE_GPGME_CANCEL, 1, [Define to 1 if your gpgme supports gpgme_cancel()]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + AC_MSG_CHECKING([if gpgme has gpgme_key_t->keylist_mode]) + AC_TRY_COMPILE([#include <gpgme.h>], [ + gpgme_key_t key = 0; + key->keylist_mode = 0; + ], [ + AC_DEFINE(HAVE_GPGME_KEY_T_KEYLIST_MODE, 1, [Define to 1 if your gpgme's gpgme_key_t has the keylist_mode member]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + AC_MSG_CHECKING([if gpgme has gpgme_decrypt_result_t->wrong_key_usage]) + AC_TRY_COMPILE([#include <gpgme.h>], [ + gpgme_decrypt_result_t res; + unsigned int wku = res->wrong_key_usage; + ], [ + AC_DEFINE(HAVE_GPGME_WRONG_KEY_USAGE, 1, [Define to 1 if your gpgme's gpgme_decrypt_result_t has the wrong_key_usage member]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + AC_MSG_CHECKING([if gpgme has GPGME_INCLUDE_CERTS_DEFAULT]) + AC_TRY_COMPILE([#include <gpgme.h>], [ + int i = GPGME_INCLUDE_CERTS_DEFAULT; + ], [ + AC_DEFINE(HAVE_GPGME_INCLUDE_CERTS_DEFAULT, 1, [Define to 1 if your gpgme has the GPGME_INCLUDE_CERTS_DEFAULT macro]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + AC_MSG_CHECKING([if gpgme has gpgme_op_getauditlog]) + AC_TRY_LINK([#include <gpgme.h>], [ + gpgme_ctx_t ctx = 0; + gpgme_data_t data = 0; + unsigned int flags = 0; + gpgme_error_t e = gpgme_op_getauditlog( ctx, data, flags ); + ], [ + AC_DEFINE(HAVE_GPGME_OP_GETAUDITLOG, 1, [Define to 1 if your gpgme supports gpgme_op_getauditlog]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$tdepim_gpgmepp_save_cflags" + LIBS="$tdepim_gpgmepp_save_libs" + AC_LANG_RESTORE + +],[ + tdepim_needs_gpgme_copy="true" + GPGME_CFLAGS='-I$(top_srcdir)/libtdenetwork/libgpgme-copy/gpgme -I$(top_srcdir)/libtdenetwork/libgpg-error-copy -I$(top_builddir)/libtdenetwork/libgpg-error-copy' + GPGME_LIBS='$(top_builddir)/libtdenetwork/libgpgme-copy/gpgme/libgpgme.la' + GPGME_LIBS_DEP='$(GPGME_LIBS)' + # All of this is in gpgme-copy + AC_DEFINE(HAVE_GPGME_KEYLIST_MODE_VALIDATE, 1, [Define to 1 if your gpgme supports GPGME_KEYLIST_MODE_VALIDATE]) + AC_DEFINE(HAVE_GPGME_KEY_T_KEYLIST_MODE, 1, [Define to 1 if your gpgme's gpgme_key_t has the keylist_mode member]) + AC_DEFINE(HAVE_GPGME_CANCEL, 1, [Define to 1 if your gpgme supports gpgme_cancel()]) +]) + +AC_SUBST(GPGME_LIBS_DEP) + +AM_CONDITIONAL(needs_gpgme_copy, test -n "$tdepim_needs_gpgme_copy") + +dnl Always true - either from the local copy or from the system lib. +dnl Still used in gpgmepp/gpgmefw.h for some reason. +AC_DEFINE(HAVE_GPGME_0_4_BRANCH, 1, [Always set since we use gpgme-copy if gpgme isn't available]) + +dnl Used by Makefile.am +AC_PROG_AWK + diff --git a/libtdenetwork/gpgmepp/context.cpp b/libtdenetwork/gpgmepp/context.cpp new file mode 100644 index 00000000..547adde9 --- /dev/null +++ b/libtdenetwork/gpgmepp/context.cpp @@ -0,0 +1,763 @@ +/* context.cpp - wraps a gpgme key context + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/context.h> +#include <gpgmepp/eventloopinteractor.h> +#include <gpgmepp/trustitem.h> +#include <gpgmepp/keylistresult.h> +#include <gpgmepp/keygenerationresult.h> +#include <gpgmepp/importresult.h> +#include <gpgmepp/decryptionresult.h> +#include <gpgmepp/verificationresult.h> +#include <gpgmepp/signingresult.h> +#include <gpgmepp/encryptionresult.h> +#include <gpgmepp/engineinfo.h> + +#include "callbacks.h" +#include "data_p.h" +#include "context_p.h" +#include "util.h" + +#include <gpgme.h> +#include <gpg-error.h> + +//#include <string> +//using std::string; +#include <istream> +#ifndef NDEBUG +#include <iostream> +using std::cerr; +using std::endl; +#endif + +#include <cassert> + +namespace GpgME { + + void initializeLibrary() { + gpgme_check_version( 0 ); + } + + const char * Error::source() const { + return gpgme_strsource( (gpgme_error_t)mErr ); + } + + const char * Error::asString() const { + return gpgme_strerror( (gpgme_error_t)mErr ); + } + + int Error::code() const { + return gpgme_err_code( mErr ); + } + + int Error::sourceID() const { + return gpgme_err_source( mErr ); + } + + bool Error::isCanceled() const { + return code() == GPG_ERR_CANCELED; + } + + std::ostream & operator<<( std::ostream & os, Error err ) { + return os << "GpgME::Error(" << err.operator int() << " (" << err.asString() << "))"; + } + + Context::Context( gpgme_ctx_t ctx ) { + d = new Private( ctx ); + } + + Context::~Context() { + delete d; d = 0; + } + + Context * Context::createForProtocol( Protocol proto ) { + gpgme_ctx_t ctx = 0; + if ( gpgme_new ( &ctx ) != 0 ) + return 0; + + switch ( proto ) { + case OpenPGP: + if ( gpgme_set_protocol( ctx, GPGME_PROTOCOL_OpenPGP ) != 0 ) { + gpgme_release( ctx ); + return 0; + } + break; + case CMS: + if ( gpgme_set_protocol( ctx, GPGME_PROTOCOL_CMS ) != 0 ) { + gpgme_release( ctx ); + return 0; + } + break; + default: + return 0; + } + + return new Context( ctx ); + } + + // + // + // Context attributes: + // + // + + Context::Protocol Context::protocol() const { + gpgme_protocol_t p = gpgme_get_protocol( d->ctx ); + switch ( p ) { + case GPGME_PROTOCOL_OpenPGP: return OpenPGP; + case GPGME_PROTOCOL_CMS: return CMS; + default: return Unknown; + } + } + + + void Context::setArmor( bool useArmor ) { + gpgme_set_armor( d->ctx, int( useArmor ) ); + } + bool Context::armor() const { + return gpgme_get_armor( d->ctx ); + } + + void Context::setTextMode( bool useTextMode ) { + gpgme_set_textmode( d->ctx, int( useTextMode ) ); + } + bool Context::textMode() const { + return gpgme_get_textmode( d->ctx ); + } + + void Context::setIncludeCertificates( int which ) { + if ( which == DefaultCertificates ) { +#ifdef HAVE_GPGME_INCLUDE_CERTS_DEFAULT + which = GPGME_INCLUDE_CERTS_DEFAULT; +#else + which = 1; +#endif + } + gpgme_set_include_certs( d->ctx, which ); + } + + int Context::includeCertificates() const { + return gpgme_get_include_certs( d->ctx ); + } + + void Context::setKeyListMode( unsigned int mode ) { + gpgme_set_keylist_mode( d->ctx, add_to_gpgme_keylist_mode_t( 0, mode ) ); + } + + void Context::addKeyListMode( unsigned int mode ) { + const unsigned int cur = gpgme_get_keylist_mode( d->ctx ); + gpgme_set_keylist_mode( d->ctx, add_to_gpgme_keylist_mode_t( cur, mode ) ); + } + + + unsigned int Context::keyListMode() const { + return convert_from_gpgme_keylist_mode_t( gpgme_get_keylist_mode( d->ctx ) ); + } + + void Context::setProgressProvider( ProgressProvider * provider ) { + gpgme_set_progress_cb( d->ctx, provider ? &progress_callback : 0, provider ); + } + ProgressProvider * Context::progressProvider() const { + void * pp = 0; + gpgme_progress_cb_t pcb = &progress_callback; + gpgme_get_progress_cb( d->ctx, &pcb, &pp ); + return static_cast<ProgressProvider*>( pp ); + } + + void Context::setPassphraseProvider( PassphraseProvider * provider ) { + gpgme_set_passphrase_cb( d->ctx, provider ? &passphrase_callback : 0, provider ); + } + + PassphraseProvider * Context::passphraseProvider() const { + void * pp = 0; + gpgme_passphrase_cb_t pcb = &passphrase_callback; + gpgme_get_passphrase_cb( d->ctx, &pcb, &pp ); + return static_cast<PassphraseProvider*>( pp ); + } + + void Context::setManagedByEventLoopInteractor( bool manage ) { + if ( !EventLoopInteractor::instance() ) { +#ifndef NDEBUG + cerr << "Context::setManagedByEventLoopInteractor(): " + "You must create an instance of EventLoopInteractor " + "before using anything that needs one." << endl; +#endif + return; + } + if ( manage ) + EventLoopInteractor::instance()->manage( this ); + else + EventLoopInteractor::instance()->unmanage( this ); + } + bool Context::managedByEventLoopInteractor() const { + return d->iocbs != 0; + } + + + void Context::installIOCallbacks( gpgme_io_cbs * iocbs ) { + if ( !iocbs ) { + uninstallIOCallbacks(); + return; + } + gpgme_set_io_cbs( d->ctx, iocbs ); + delete d->iocbs; d->iocbs = iocbs; + } + + void Context::uninstallIOCallbacks() { + static gpgme_io_cbs noiocbs = { 0, 0, 0, 0, 0 }; + // io.add == 0 means disable io callbacks: + gpgme_set_io_cbs( d->ctx, &noiocbs ); + delete d->iocbs; d->iocbs = 0; + } + + Error Context::setLocale( int cat, const char * val ) { + return d->lasterr = gpgme_set_locale( d->ctx, cat, val ); + } + + // + // + // Key Management + // + // + + Error Context::startKeyListing( const char * pattern, bool secretOnly ) { + d->lastop = Private::KeyList; + return d->lasterr = gpgme_op_keylist_start( d->ctx, pattern, int( secretOnly ) ); + } + + Error Context::startKeyListing( const char * patterns[], bool secretOnly ) { + d->lastop = Private::KeyList; + return d->lasterr = gpgme_op_keylist_ext_start( d->ctx, patterns, int( secretOnly ), 0 ); + } + + Key Context::nextKey( GpgME::Error & e ) { + d->lastop = Private::KeyList; + gpgme_key_t key; + e = d->lasterr = gpgme_op_keylist_next( d->ctx, &key ); + return Key( key, false, keyListMode() ); + } + + KeyListResult Context::endKeyListing() { + d->lasterr = gpgme_op_keylist_end( d->ctx ); + return keyListResult(); + } + + KeyListResult Context::keyListResult() const { + return KeyListResult( d->ctx, d->lasterr ); + } + + Key Context::key( const char * fingerprint, GpgME::Error & e , bool secret /*, bool forceUpdate*/ ) { + d->lastop = Private::KeyList; + gpgme_key_t key; + e = d->lasterr = gpgme_get_key( d->ctx, fingerprint, &key, int( secret )/*, int( forceUpdate )*/ ); + return Key( key, false, keyListMode() ); + } + + KeyGenerationResult Context::generateKey( const char * parameters, Data & pubKey ) { + d->lastop = Private::KeyGen; + Data::Private * dp = pubKey.impl(); + d->lasterr = gpgme_op_genkey( d->ctx, parameters, dp ? dp->data : 0, 0 ); + return KeyGenerationResult( d->ctx, d->lasterr ); + } + + Error Context::startKeyGeneration( const char * parameters, Data & pubKey ) { + d->lastop = Private::KeyGen; + Data::Private * dp = pubKey.impl(); + return d->lasterr = gpgme_op_genkey_start( d->ctx, parameters, dp ? dp->data : 0, 0 ); + } + + KeyGenerationResult Context::keyGenerationResult() const { + if ( d->lastop & Private::KeyGen ) + return KeyGenerationResult( d->ctx, d->lasterr ); + else + return KeyGenerationResult(); + } + + Error Context::exportPublicKeys( const char * pattern, Data & keyData ) { + d->lastop = Private::Export; + Data::Private * dp = keyData.impl(); + return d->lasterr = gpgme_op_export( d->ctx, pattern, 0, dp ? dp->data : 0 ); + } + + Error Context::exportPublicKeys( const char * patterns[], Data & keyData ) { + d->lastop = Private::Export; + Data::Private * dp = keyData.impl(); + return d->lasterr = gpgme_op_export_ext( d->ctx, patterns, 0, dp ? dp->data : 0 ); + } + + Error Context::startPublicKeyExport( const char * pattern, Data & keyData ) { + d->lastop = Private::Export; + Data::Private * dp = keyData.impl(); + return d->lasterr = gpgme_op_export_start( d->ctx, pattern, 0, dp ? dp->data : 0 ); + } + + Error Context::startPublicKeyExport( const char * patterns[], Data & keyData ) { + d->lastop = Private::Export; + Data::Private * dp = keyData.impl(); + return d->lasterr = gpgme_op_export_ext_start( d->ctx, patterns, 0, dp ? dp->data : 0 ); + } + + + ImportResult Context::importKeys( const Data & data ) { + d->lastop = Private::Import; + Data::Private * dp = data.impl(); + d->lasterr = gpgme_op_import( d->ctx, dp ? dp->data : 0 ); + return ImportResult( d->ctx, d->lasterr ); + } + + Error Context::startKeyImport( const Data & data ) { + d->lastop = Private::Import; + Data::Private * dp = data.impl(); + return d->lasterr = gpgme_op_import_start( d->ctx, dp ? dp->data : 0 ); + } + + ImportResult Context::importResult() const { + if ( d->lastop & Private::Import ) + return ImportResult( d->ctx, d->lasterr ); + else + return ImportResult(); + } + + Error Context::deleteKey( const Key & key, bool allowSecretKeyDeletion ) { + d->lastop = Private::Delete; + return d->lasterr = gpgme_op_delete( d->ctx, key.impl(), int( allowSecretKeyDeletion ) ); + } + + Error Context::startKeyDeletion( const Key & key, bool allowSecretKeyDeletion ) { + d->lastop = Private::Delete; + return d->lasterr = gpgme_op_delete_start( d->ctx, key.impl(), int( allowSecretKeyDeletion ) ); + } + + Error Context::startTrustItemListing( const char * pattern, int maxLevel ) { + d->lastop = Private::TrustList; + return d->lasterr = gpgme_op_trustlist_start( d->ctx, pattern, maxLevel ); + } + + TrustItem Context::nextTrustItem( Error & e ) { + gpgme_trust_item_t ti = 0; + e = d->lasterr = gpgme_op_trustlist_next( d->ctx, &ti ); + return ti; + } + + Error Context::endTrustItemListing() { + return d->lasterr = gpgme_op_trustlist_end( d->ctx ); + } + + DecryptionResult Context::decrypt( const Data & cipherText, Data & plainText ) { + d->lastop = Private::Decrypt; + Data::Private * cdp = cipherText.impl(); + Data::Private * pdp = plainText.impl(); + d->lasterr = gpgme_op_decrypt( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 ); + return DecryptionResult( d->ctx, d->lasterr ); + } + + Error Context::startDecryption( const Data & cipherText, Data & plainText ) { + d->lastop = Private::Decrypt; + Data::Private * cdp = cipherText.impl(); + Data::Private * pdp = plainText.impl(); + return d->lasterr = gpgme_op_decrypt_start( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 ); + } + + DecryptionResult Context::decryptionResult() const { + if ( d->lastop & Private::Decrypt ) + return DecryptionResult( d->ctx, d->lasterr ); + else + return DecryptionResult(); + } + + + + VerificationResult Context::verifyDetachedSignature( const Data & signature, const Data & signedText ) { + d->lastop = Private::Verify; + Data::Private * sdp = signature.impl(); + Data::Private * tdp = signedText.impl(); + d->lasterr = gpgme_op_verify( d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0 ); + return VerificationResult( d->ctx, d->lasterr ); + } + + VerificationResult Context::verifyOpaqueSignature( const Data & signedData, Data & plainText ) { + d->lastop = Private::Verify; + Data::Private * sdp = signedData.impl(); + Data::Private * pdp = plainText.impl(); + d->lasterr = gpgme_op_verify( d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0 ); + return VerificationResult( d->ctx, d->lasterr ); + } + + Error Context::startDetachedSignatureVerification( const Data & signature, const Data & signedText ) { + d->lastop = Private::Verify; + Data::Private * sdp = signature.impl(); + Data::Private * tdp = signedText.impl(); + return d->lasterr = gpgme_op_verify_start( d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0 ); + } + + Error Context::startOpaqueSignatureVerification( const Data & signedData, Data & plainText ) { + d->lastop = Private::Verify; + Data::Private * sdp = signedData.impl(); + Data::Private * pdp = plainText.impl(); + return d->lasterr = gpgme_op_verify_start( d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0 ); + } + + VerificationResult Context::verificationResult() const { + if ( d->lastop & Private::Verify ) + return VerificationResult( d->ctx, d->lasterr ); + else + return VerificationResult(); + } + + + std::pair<DecryptionResult,VerificationResult> Context::decryptAndVerify( const Data & cipherText, Data & plainText ) { + d->lastop = Private::DecryptAndVerify; + Data::Private * cdp = cipherText.impl(); + Data::Private * pdp = plainText.impl(); + d->lasterr = gpgme_op_decrypt_verify( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 ); + return std::make_pair( DecryptionResult( d->ctx, d->lasterr ), + VerificationResult( d->ctx, d->lasterr ) ); + } + + Error Context::startCombinedDecryptionAndVerification( const Data & cipherText, Data & plainText ) { + d->lastop = Private::DecryptAndVerify; + Data::Private * cdp = cipherText.impl(); + Data::Private * pdp = plainText.impl(); + return d->lasterr = gpgme_op_decrypt_verify_start( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 ); + } + +#ifdef HAVE_GPGME_OP_GETAUDITLOG + unsigned int to_auditlog_flags( unsigned int flags ) { + unsigned int result = 0; + if ( flags & Context::HtmlAuditLog ) + result |= GPGME_AUDITLOG_HTML; + if ( flags & Context::AuditLogWithHelp ) + result |= GPGME_AUDITLOG_WITH_HELP; + return result; + } +#endif // HAVE_GPGME_OP_GETAUDITLOG + + + Error Context::startGetAuditLog( Data & output, unsigned int flags ) { + d->lastop = Private::GetAuditLog; +#ifdef HAVE_GPGME_OP_GETAUDITLOG + Data::Private * const odp = output.impl(); + return Error( d->lasterr = gpgme_op_getauditlog_start( d->ctx, odp ? odp->data : 0, to_auditlog_flags( flags ) ) ); +#else + (void)output; (void)flags; + return Error( d->lasterr = gpg_error( GPG_ERR_NOT_IMPLEMENTED ) ); +#endif + } + + Error Context::getAuditLog( Data & output, unsigned int flags ) { + d->lastop = Private::GetAuditLog; +#ifdef HAVE_GPGME_OP_GETAUDITLOG + Data::Private * const odp = output.impl(); + return Error( d->lasterr = gpgme_op_getauditlog( d->ctx, odp ? odp->data : 0, to_auditlog_flags( flags ) ) ); +#else + (void)output; (void)flags; + return Error( d->lasterr = gpg_error( GPG_ERR_NOT_IMPLEMENTED ) ); +#endif + } + + void Context::clearSigningKeys() { + gpgme_signers_clear( d->ctx ); + } + + Error Context::addSigningKey( const Key & key ) { + return d->lasterr = gpgme_signers_add( d->ctx, key.impl() ); + } + + Key Context::signingKey( unsigned int idx ) const { + gpgme_key_t key = gpgme_signers_enum( d->ctx, idx ); + return Key( key, false, keyListMode() ); + } + + + static gpgme_sig_mode_t sigmode2sigmode( Context::SignatureMode mode ) { + switch ( mode ) { + default: + case Context::Normal: return GPGME_SIG_MODE_NORMAL; + case Context::Detached: return GPGME_SIG_MODE_DETACH; + case Context::Clearsigned: return GPGME_SIG_MODE_CLEAR; + } + } + + SigningResult Context::sign( const Data & plainText, Data & signature, SignatureMode mode ) { + d->lastop = Private::Sign; + Data::Private * pdp = plainText.impl(); + Data::Private * sdp = signature.impl(); + d->lasterr = gpgme_op_sign( d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode( mode ) ); + return SigningResult( d->ctx, d->lasterr ); + } + + + Error Context::startSigning( const Data & plainText, Data & signature, SignatureMode mode ) { + d->lastop = Private::Sign; + Data::Private * pdp = plainText.impl(); + Data::Private * sdp = signature.impl(); + return d->lasterr = gpgme_op_sign_start( d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode( mode ) ); + } + + SigningResult Context::signingResult() const { + if ( d->lastop & Private::Sign ) + return SigningResult( d->ctx, d->lasterr ); + else + return SigningResult(); + } + + + EncryptionResult Context::encrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) { + d->lastop = Private::Encrypt; + Data::Private * pdp = plainText.impl(); + Data::Private * cdp = cipherText.impl(); + gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ]; + gpgme_key_t * keys_it = keys; + for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it ) + if ( it->impl() ) + *keys_it++ = it->impl(); + *keys_it++ = 0; + d->lasterr = gpgme_op_encrypt( d->ctx, keys, + flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0, + pdp ? pdp->data : 0, cdp ? cdp->data : 0 ); + delete[] keys; + return EncryptionResult( d->ctx, d->lasterr ); + } + + Error Context::encryptSymmetrically( const Data & plainText, Data & cipherText ) { + d->lastop = Private::Encrypt; + Data::Private * pdp = plainText.impl(); + Data::Private * cdp = cipherText.impl(); + return d->lasterr = gpgme_op_encrypt( d->ctx, 0, (gpgme_encrypt_flags_t)0, + pdp ? pdp->data : 0, cdp ? cdp->data : 0 ); + } + + Error Context::startEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) { + d->lastop = Private::Encrypt; + Data::Private * pdp = plainText.impl(); + Data::Private * cdp = cipherText.impl(); + gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ]; + gpgme_key_t * keys_it = keys; + for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it ) + if ( it->impl() ) + *keys_it++ = it->impl(); + *keys_it++ = 0; + d->lasterr = gpgme_op_encrypt_start( d->ctx, keys, + flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0, + pdp ? pdp->data : 0, cdp ? cdp->data : 0 ); + delete[] keys; + return d->lasterr; + } + + EncryptionResult Context::encryptionResult() const { + if ( d->lastop & Private::Encrypt ) + return EncryptionResult( d->ctx, d->lasterr ); + else + return EncryptionResult(); + } + + std::pair<SigningResult,EncryptionResult> Context::signAndEncrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) { + d->lastop = Private::SignAndEncrypt; + Data::Private * pdp = plainText.impl(); + Data::Private * cdp = cipherText.impl(); + gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ]; + gpgme_key_t * keys_it = keys; + for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it ) + if ( it->impl() ) + *keys_it++ = it->impl(); + *keys_it++ = 0; + d->lasterr = gpgme_op_encrypt_sign( d->ctx, keys, + flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0, + pdp ? pdp->data : 0, cdp ? cdp->data : 0 ); + delete[] keys; + return std::make_pair( SigningResult( d->ctx, d->lasterr ), + EncryptionResult( d->ctx, d->lasterr ) ); + } + + Error Context::startCombinedSigningAndEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) { + d->lastop = Private::SignAndEncrypt; + Data::Private * pdp = plainText.impl(); + Data::Private * cdp = cipherText.impl(); + gpgme_key_t * keys = new gpgme_key_t[ recipients.size() + 1 ]; + gpgme_key_t * keys_it = keys; + for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it ) + if ( it->impl() ) + *keys_it++ = it->impl(); + *keys_it++ = 0; + d->lasterr = gpgme_op_encrypt_sign_start( d->ctx, keys, + flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0, + pdp ? pdp->data : 0, cdp ? cdp->data : 0 ); + delete[] keys; + return d->lasterr; + } + + + Error Context::cancelPendingOperation() { +#ifdef HAVE_GPGME_CANCEL + return gpgme_cancel( d->ctx ); +#else + return 0; +#endif + } + + bool Context::poll() { + gpgme_error_t e = GPG_ERR_NO_ERROR; + const bool finished = gpgme_wait( d->ctx, &e, 0 ); + if ( finished ) + d->lasterr = e; + return finished; + } + + Error Context::wait() { + gpgme_error_t e = GPG_ERR_NO_ERROR; + gpgme_wait( d->ctx, &e, 1 ); + return d->lasterr = e; + } + + Error Context::lastError() const { + return d->lasterr; + } + + std::ostream & operator<<( std::ostream & os, Context::Protocol proto ) { + os << "GpgME::Context::Protocol("; + switch ( proto ) { + case Context::OpenPGP: + os << "OpenPGP"; + break; + case Context::CMS: + os << "CMS"; + break; + default: + case Context::Unknown: + os << "Unknown"; + break; + } + return os << ')'; + } + + std::ostream & operator<<( std::ostream & os, Context::CertificateInclusion incl ) { + os << "GpgME::Context::CertificateInclusion(" << static_cast<int>( incl ); + switch ( incl ) { + case Context::DefaultCertificates: + os << "(DefaultCertificates)"; + break; + case Context::AllCertificatesExceptRoot: + os << "(AllCertificatesExceptRoot)"; + break; + case Context::AllCertificates: + os << "(AllCertificates)"; + break; + case Context::NoCertificates: + os << "(NoCertificates)"; + break; + case Context::OnlySenderCertificate: + os << "(OnlySenderCertificate)"; + break; + } + return os << ')'; + } + + std::ostream & operator<<( std::ostream & os, Context::KeyListMode mode ) { + os << "GpgME::Context::KeyListMode("; +#define CHECK( x ) if ( !(mode & (Context::x)) ) {} else do { os << #x " "; } while (0) + CHECK( Local ); + CHECK( Extern ); + CHECK( Signatures ); + CHECK( Validate ); +#undef CHECK + return os << ')'; + } + + std::ostream & operator<<( std::ostream & os, Context::SignatureMode mode ) { + os << "GpgME::Context::SignatureMode("; + switch ( mode ) { +#define CHECK( x ) case Context::x: os << #x; break + CHECK( Normal ); + CHECK( Detached ); + CHECK( Clearsigned ); +#undef CHECK + default: + os << "???" "(" << static_cast<int>( mode ) << ')'; + break; + } + return os << ')'; + } + + std::ostream & operator<<( std::ostream & os, Context::EncryptionFlags flags ) { + os << "GpgME::Context::EncryptionFlags("; +#define CHECK( x ) if ( !(flags & (Context::x)) ) {} else do { os << #x " "; } while (0) + CHECK( AlwaysTrust ); +#undef CHECK + return os << ')'; + } + + std::ostream & operator<<( std::ostream & os, Context::AuditLogFlags flags ) { + os << "GpgME::Context::AuditLogFlags("; +#define CHECK( x ) if ( !(flags & (Context::x)) ) {} else do { os << #x " "; } while (0) + CHECK( HtmlAuditLog ); + CHECK( AuditLogWithHelp ); +#undef CHECK + return os << ')'; + } + + + +} // namespace GpgME + +GpgME::Error GpgME::setDefaultLocale( int cat, const char * val ) { + return gpgme_set_locale( 0, cat, val ); +} + +GpgME::EngineInfo GpgME::engineInfo( Context::Protocol proto ) { + gpgme_engine_info_t ei = 0; + if ( gpgme_get_engine_info( &ei ) ) + return EngineInfo(); + + gpgme_protocol_t p = proto == Context::CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ; + + for ( gpgme_engine_info_t i = ei ; i ; i = i->next ) + if ( i->protocol == p ) + return EngineInfo( i ); + + return EngineInfo(); +} + +GpgME::Error GpgME::checkEngine( Context::Protocol proto ) { + gpgme_protocol_t p = proto == Context::CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ; + + return gpgme_engine_check_version( p ); +} + +static const unsigned long supported_features = 0 +#ifdef HAVE_GPGME_KEYLIST_MODE_VALIDATE + | GpgME::ValidatingKeylistModeFeature +#endif +#ifdef HAVE_GPGME_CANCEL + | GpgME::CancelOperationFeature +#endif +#ifdef HAVE_GPGME_WRONG_KEY_USAGE + | GpgME::WrongKeyUsageFeature +#endif +#ifdef HAVE_GPGME_OP_GETAUDITLOG + | GpgME::AuditLogFeature +#endif + ; + +bool GpgME::hasFeature( unsigned long features ) { + return features == ( features & supported_features ); +} diff --git a/libtdenetwork/gpgmepp/context.h b/libtdenetwork/gpgmepp/context.h new file mode 100644 index 00000000..054f8bee --- /dev/null +++ b/libtdenetwork/gpgmepp/context.h @@ -0,0 +1,328 @@ +/* context.h - wraps a gpgme key context + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +// -*- c++ -*- +#ifndef __GPGMEPP_CONTEXT_H__ +#define __GPGMEPP_CONTEXT_H__ + +#include <gpgmepp/gpgmefw.h> + +#include <vector> +#include <utility> +#include <iosfwd> + +#include <tdepimmacros.h> + +namespace GpgME { + + class Key; + class Data; + class TrustItem; + class ProgressProvider; + class PassphraseProvider; + class EventLoopInteractor; + + class KeyListResult; + class KeyGenerationResult; + class ImportResult; + class DecryptionResult; + class VerificationResult; + class SigningResult; + class EncryptionResult; + + class EngineInfo; + + class KDE_EXPORT Error { + public: + Error( int e=0 ) : mErr( e ) {} + + const char * source() const; + const char * asString() const; + + int code() const; + int sourceID() const; + + bool isCanceled() const; + + operator int() const { return mErr; } + operator bool() const { return mErr && !isCanceled(); } + private: + int mErr; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Error err ); + + class KDE_EXPORT Context { + Context( gpgme_ctx_t ); + public: + enum Protocol { OpenPGP, CMS, Unknown }; + + // + // Creation and destruction: + // + + static Context * createForProtocol( Protocol proto ); + virtual ~Context(); + + // + // Context Attributes + // + + Protocol protocol() const; + + void setArmor( bool useArmor ); + bool armor() const; + + void setTextMode( bool useTextMode ); + bool textMode() const; + + enum CertificateInclusion { + DefaultCertificates = -256, + AllCertificatesExceptRoot = -2, + AllCertificates = -1, + NoCertificates = 0, + OnlySenderCertificate = 1 + }; + void setIncludeCertificates( int which ); + int includeCertificates() const; + + enum KeyListMode { + Local = 0x1, + Extern = 0x2, + Signatures = 0x4, + Validate = 0x10 + }; + void setKeyListMode( unsigned int keyListMode ); + void addKeyListMode( unsigned int keyListMode ); + unsigned int keyListMode() const; + + void setPassphraseProvider( PassphraseProvider * provider ); + PassphraseProvider * passphraseProvider() const; + + void setProgressProvider( ProgressProvider * provider ); + ProgressProvider * progressProvider() const; + + void setManagedByEventLoopInteractor( bool managed ); + bool managedByEventLoopInteractor() const; + + GpgME::Error setLocale( int category, const char * value ); + + private: + friend class EventLoopInteractor; + void installIOCallbacks( gpgme_io_cbs * iocbs ); + void uninstallIOCallbacks(); + + public: + // + // + // Key Management + // + // + + // + // Key Listing + // + + GpgME::Error startKeyListing( const char * pattern=0, bool secretOnly=false ); + GpgME::Error startKeyListing( const char * patterns[], bool secretOnly=false ); + + Key nextKey( GpgME::Error & e ); + + KeyListResult endKeyListing(); + KeyListResult keyListResult() const; + + Key key( const char * fingerprint, GpgME::Error & e, bool secret=false ); + + // + // Key Generation + // + + KeyGenerationResult generateKey( const char * parameters, Data & pubKey ); + GpgME::Error startKeyGeneration( const char * parameters, Data & pubkey ); + KeyGenerationResult keyGenerationResult() const; + + // + // Key Export + // + + GpgME::Error exportPublicKeys( const char * pattern, Data & keyData ); + GpgME::Error exportPublicKeys( const char * pattern[], Data & keyData ); + GpgME::Error startPublicKeyExport( const char * pattern, Data & keyData ); + GpgME::Error startPublicKeyExport( const char * pattern[], Data & keyData ); + + // + // Key Import + // + + ImportResult importKeys( const Data & data ); + GpgME::Error startKeyImport( const Data & data ); + ImportResult importResult() const; + + // + // Key Deletion + // + + GpgME::Error deleteKey( const Key & key, bool allowSecretKeyDeletion=false ); + GpgME::Error startKeyDeletion( const Key & key, bool allowSecretKeyDeletion=false ); + + // + // Trust Item Management + // + + GpgME::Error startTrustItemListing( const char * pattern, int maxLevel ); + TrustItem nextTrustItem( GpgME::Error & e ); + GpgME::Error endTrustItemListing(); + + // + // + // Crypto Operations + // + // + + // + // Decryption + // + + DecryptionResult decrypt( const Data & cipherText, Data & plainText ); + GpgME::Error startDecryption( const Data & cipherText, Data & plainText ); + DecryptionResult decryptionResult() const; + + // + // Signature Verification + // + + VerificationResult verifyDetachedSignature( const Data & signature, const Data & signedText ); + VerificationResult verifyOpaqueSignature( const Data & signedData, Data & plainText ); + GpgME::Error startDetachedSignatureVerification( const Data & signature, const Data & signedText ); + GpgME::Error startOpaqueSignatureVerification( const Data & signedData, Data & plainText ); + VerificationResult verificationResult() const; + + // + // Combined Decryption and Signature Verification + // + + std::pair<DecryptionResult,VerificationResult> decryptAndVerify( const Data & cipherText, Data & plainText ); + GpgME::Error startCombinedDecryptionAndVerification( const Data & cipherText, Data & plainText ); + // use verificationResult() and decryptionResult() to retrieve the result objects... + + // + // Signing + // + + void clearSigningKeys(); + GpgME::Error addSigningKey( const Key & signer ); + Key signingKey( unsigned int index ) const; + + enum SignatureMode { Normal, Detached, Clearsigned }; + SigningResult sign( const Data & plainText, Data & signature, SignatureMode mode ); + GpgME::Error startSigning( const Data & plainText, Data & signature, SignatureMode mode ); + SigningResult signingResult() const; + + // + // Encryption + // + + enum EncryptionFlags { None=0, AlwaysTrust=1 }; + EncryptionResult encrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ); + GpgME::Error encryptSymmetrically( const Data & plainText, Data & cipherText ); + GpgME::Error startEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ); + EncryptionResult encryptionResult() const; + + // + // Combined Signing and Encryption + // + + std::pair<SigningResult,EncryptionResult> signAndEncrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ); + GpgME::Error startCombinedSigningAndEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ); + // use encryptionResult() and signingResult() to retrieve the result objects... + + // + // + // Audit Log + // + // + enum AuditLogFlags { + HtmlAuditLog = 1, + AuditLogWithHelp = 128 + }; + GpgME::Error startGetAuditLog( Data & output, unsigned int flags=0 ); + GpgME::Error getAuditLog( Data & output, unsigned int flags=0 ); + + // + // + // Run Control + // + // + + bool poll(); + GpgME::Error wait(); + GpgME::Error lastError() const; + GpgME::Error cancelPendingOperation(); + + class Private; + Private * impl() const { return d; } + private: + Private * d; + + private: // disable... + Context( const Context & ); + const Context & operator=( const Context & ); + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Context::Protocol proto ); + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Context::CertificateInclusion incl ); + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Context::KeyListMode mode ); + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Context::SignatureMode mode ); + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Context::EncryptionFlags flags ); + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Context::AuditLogFlags flags ); + + // + // + // Globals + // + // + + KDE_EXPORT void initializeLibrary(); + + KDE_EXPORT GpgME::Error setDefaultLocale( int category, const char * value ); + + KDE_EXPORT Context * wait( GpgME::Error & e, bool hang=true ); + typedef void (*IdleFunction)(void); + KDE_EXPORT IdleFunction registerIdleFunction( IdleFunction idleFunction ); + + typedef void (*IOCallback)( void * data, int fd ); + + KDE_EXPORT EngineInfo engineInfo( Context::Protocol proto ); + + KDE_EXPORT GpgME::Error checkEngine( Context::Protocol proto ); + + enum Feature { + ValidatingKeylistModeFeature = 0x00000001, + CancelOperationFeature = 0x00000002, + WrongKeyUsageFeature = 0x00000004, + + AuditLogFeature = 0x00001000, + + FeatureMaxValue = 0x80000000 + }; + KDE_EXPORT bool hasFeature( unsigned long feature ); + +} // namespace GpgME + +#endif // __GPGMEPP_CONTEXT_H__ diff --git a/libtdenetwork/gpgmepp/context_p.h b/libtdenetwork/gpgmepp/context_p.h new file mode 100644 index 00000000..dfff5863 --- /dev/null +++ b/libtdenetwork/gpgmepp/context_p.h @@ -0,0 +1,76 @@ +/* context_p.h - wraps a gpgme key context (private part) + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + + +// -*- c++ -*- +#ifndef __GPGMEPP_CONTEXT_P_H__ +#define __GPGMEPP_CONTEXT_P_H__ + +#include <gpgmepp/context.h> + +#include <gpgme.h> + +namespace GpgME { + + + struct Context::Private { + enum Operation { + None = 0, + + Encrypt = 0x001, + Decrypt = 0x002, + Sign = 0x004, + Verify = 0x008, + DecryptAndVerify = Decrypt|Verify, + SignAndEncrypt = Sign|Encrypt, + + Import = 0x010, + Export = 0x020, // no gpgme_export_result_t, but nevertheless... + Delete = 0x040, // no gpgme_delete_result_t, but nevertheless... + + KeyGen = 0x080, + KeyList = 0x100, + TrustList = 0x200, // gpgme_trustlist_result_t, but nevertheless... + + GetAuditLog = 0x1000 // no gpgme_getauditlog_result_t, but nevertheless... + }; + + Private( gpgme_ctx_t c=0 ) + : ctx( c ), + iocbs( 0 ), + lastop( None ), + lasterr( GPG_ERR_NO_ERROR ) {} + ~Private() { + if ( ctx ) { + gpgme_release( ctx ); + ctx = 0; + } + delete iocbs; + } + + gpgme_ctx_t ctx; + gpgme_io_cbs * iocbs; + //EditInteractor * edit; + Operation lastop; + gpgme_error_t lasterr; + }; + +} // namespace GpgME + +#endif // __GPGMEPP_CONTEXT_P_H__ diff --git a/libtdenetwork/gpgmepp/data.cpp b/libtdenetwork/gpgmepp/data.cpp new file mode 100644 index 00000000..52471be9 --- /dev/null +++ b/libtdenetwork/gpgmepp/data.cpp @@ -0,0 +1,160 @@ +/* data.cpp - wraps a gpgme data object + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/context.h> // Error +#include <gpgmepp/interfaces/dataprovider.h> +#include "data_p.h" + +#include <gpgme.h> + +#ifndef NDEBUG +#include <iostream> +#endif + +GpgME::Data::Private::~Private() { + if ( data ) + gpgme_data_release( data ); +} + +GpgME::Data GpgME::Data::null( (gpgme_data_t)0 ); + +GpgME::Data::Data() { + gpgme_data_t data; + const gpgme_error_t e = gpgme_data_new( &data ); + d = new Private( e ? 0 : data ); + d->ref(); +} + +GpgME::Data::Data( gpgme_data_t data ) { + d = new Private( data ); + d->ref(); +} + +GpgME::Data::Data( const Data & other ) + : d( other.d ) +{ + d->ref(); +} + +GpgME::Data::~Data() { + d->unref(); d = 0; +} + + +const GpgME::Data & GpgME::Data::operator=( const Data & other ) { + if ( this->d == other.d ) return *this; + + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->unref(); + this->d = other.d; + + return *this; +} + +GpgME::Data::Data( const char * buffer, size_t size, bool copy ) { + gpgme_data_t data; + const gpgme_error_t e = gpgme_data_new_from_mem( &data, buffer, size, int( copy ) ); + d = new Private( e ? 0 : data ); + d->ref(); +} + +GpgME::Data::Data( const char * filename ) { + gpgme_data_t data; + const gpgme_error_t e = gpgme_data_new_from_file( &data, filename, 1 ); + d = new Private( e ? 0 : data ); + d->ref(); +} + +GpgME::Data::Data( const char * filename, off_t offset, size_t length ) { + gpgme_data_t data; + const gpgme_error_t e = gpgme_data_new_from_filepart( &data, filename, 0, offset, length ); + d = new Private( e ? 0 : data ); + d->ref(); +} + +GpgME::Data::Data( FILE * fp ) { + gpgme_data_t data; + const gpgme_error_t e = gpgme_data_new_from_stream( &data, fp ); + d = new Private( e ? 0 : data ); + d->ref(); +} + +GpgME::Data::Data( FILE * fp, off_t offset, size_t length ) { + gpgme_data_t data; + const gpgme_error_t e = gpgme_data_new_from_filepart( &data, 0, fp, offset, length ); + d = new Private( e ? 0 : data ); + d->ref(); +} + +GpgME::Data::Data( int fd ) { + gpgme_data_t data; + const gpgme_error_t e = gpgme_data_new_from_fd( &data, fd ); + d = new Private( e ? 0 : data ); + d->ref(); +} + +GpgME::Data::Data( DataProvider * dp ) { + d = new Private(); + d->ref(); + if ( !dp ) + return; + if ( !dp->isSupported( DataProvider::Read ) ) + d->cbs.read = 0; + if ( !dp->isSupported( DataProvider::Write ) ) + d->cbs.write = 0; + if ( !dp->isSupported( DataProvider::Seek ) ) + d->cbs.seek = 0; + if ( !dp->isSupported( DataProvider::Release ) ) + d->cbs.release = 0; + const gpgme_error_t e = gpgme_data_new_from_cbs( &d->data, &d->cbs, dp ); + if ( e ) + d->data = 0; +#ifndef NDEBUG +// std::cerr << "GpgME::Data(): DataProvider supports: " +// << ( d->cbs.read ? "read" : "no read" ) << ", " +// << ( d->cbs.write ? "write" : "no write" ) << ", " +// << ( d->cbs.seek ? "seek" : "no seek" ) << ", " +// << ( d->cbs.release ? "release" : "no release" ) << std::endl; +#endif +} + + + +bool GpgME::Data::isNull() const { + return !d || !d->data; +} + +ssize_t GpgME::Data::read( void * buffer, size_t length ) { + return gpgme_data_read( d->data, buffer, length ); +} + +ssize_t GpgME::Data::write( const void * buffer, size_t length ) { + return gpgme_data_write( d->data, buffer, length ); +} + +off_t GpgME::Data::seek( off_t offset, int whence ) { + return gpgme_data_seek( d->data, offset, whence ); +} diff --git a/libtdenetwork/gpgmepp/data.h b/libtdenetwork/gpgmepp/data.h new file mode 100644 index 00000000..e1206472 --- /dev/null +++ b/libtdenetwork/gpgmepp/data.h @@ -0,0 +1,72 @@ +/* data.h - wraps a gpgme data object + Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_DATA_H__ +#define __GPGMEPP_DATA_H__ + +#include <gpgmepp/gpgmefw.h> + +#include <sys/types.h> // for size_t, off_t +#include <cstdio> // FILE +#include <tdepimmacros.h> + +namespace GpgME { + + class DataProvider; + class Error; + + class KDE_EXPORT Data { + public: + Data(); + Data( gpgme_data_t data ); + Data( const Data & other ); + + // Memory-Based Data Buffers: + Data( const char * buffer, size_t size, bool copy=true ); + Data( const char * filename ); + Data( const char * filename, off_t offset, size_t length ); + Data( FILE * fp, off_t offset, size_t length ); + // File-Based Data Buffers: + Data( FILE * fp ); + Data( int fd ); + // Callback-Based Data Buffers: + Data( DataProvider * provider ); + + virtual ~Data(); + + static Data null; + + const Data & operator=( const Data & other ); + + bool isNull() const; + + ssize_t read( void * buffer, size_t length ); + ssize_t write( const void * buffer, size_t length ); + off_t seek( off_t offset, int whence ); + + class Private; + Private * impl() const { return d; } + private: + Private * d; + }; + +} + +#endif // __GPGMEPP_DATA_H__ diff --git a/libtdenetwork/gpgmepp/data_p.h b/libtdenetwork/gpgmepp/data_p.h new file mode 100644 index 00000000..38981cce --- /dev/null +++ b/libtdenetwork/gpgmepp/data_p.h @@ -0,0 +1,39 @@ +/* data_p.h - wraps a gpgme data object, private part -*- c++ -*- + Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_DATA_P_H__ +#define __GPGMEPP_DATA_P_H__ + +#include <gpgmepp/data.h> +#include "shared.h" +#include "callbacks.h" + +class GpgME::Data::Private : public GpgME::Shared { +public: + Private( gpgme_data_t d=0 ) + : Shared(), data( d ), cbs( data_provider_callbacks ) {} + ~Private(); + + gpgme_data_t data; + gpgme_data_cbs cbs; +}; + + +#endif // __GPGMEPP_DATA_P_H__ diff --git a/libtdenetwork/gpgmepp/decryptionresult.cpp b/libtdenetwork/gpgmepp/decryptionresult.cpp new file mode 100644 index 00000000..2efcc67d --- /dev/null +++ b/libtdenetwork/gpgmepp/decryptionresult.cpp @@ -0,0 +1,85 @@ +/* decryptionresult.cpp - wraps a gpgme keygen result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/decryptionresult.h> +#include "shared.h" +#include "result_p.h" +#include "util.h" + +#include <gpgme.h> + +#include <cstring> +#include <cstdlib> +#include <istream> + +class GpgME::DecryptionResult::Private : public GpgME::Shared { +public: + Private( const _gpgme_op_decrypt_result & r ) : Shared(), res( r ) { + if ( res.unsupported_algorithm ) + res.unsupported_algorithm = strdup( res.unsupported_algorithm ); + } + ~Private() { + if ( res.unsupported_algorithm ) + std::free( res.unsupported_algorithm ); + res.unsupported_algorithm = 0; + } + + _gpgme_op_decrypt_result res; +}; + +GpgME::DecryptionResult::DecryptionResult( gpgme_ctx_t ctx, int error ) + : GpgME::Result( error ), d( 0 ) +{ + if ( error || !ctx ) + return; + gpgme_decrypt_result_t res = gpgme_op_decrypt_result( ctx ); + if ( !res ) + return; + d = new Private( *res ); + d->ref(); +} + +make_standard_stuff(DecryptionResult) + +const char * GpgME::DecryptionResult::unsupportedAlgortihm() const { + return d ? d->res.unsupported_algorithm : 0 ; +} + +bool GpgME::DecryptionResult::wrongKeyUsage() const { +#ifdef HAVE_GPGME_WRONG_KEY_USAGE + if ( d ) + return d->res.wrong_key_usage; +#endif + return false; +} + +std::ostream & GpgME::operator<<( std::ostream & os, const DecryptionResult & result ) { + os << "GpgME::DecryptionResult("; + if ( !result.isNull() ) + os << "\n error: " << result.error() + << "\n unsupportedAlgortihm: " << protect( result.unsupportedAlgortihm() ) + << "\n wrongKeyUsage: " << result.wrongKeyUsage() + << '\n'; + return os << ')'; +} diff --git a/libtdenetwork/gpgmepp/decryptionresult.h b/libtdenetwork/gpgmepp/decryptionresult.h new file mode 100644 index 00000000..da4833bb --- /dev/null +++ b/libtdenetwork/gpgmepp/decryptionresult.h @@ -0,0 +1,59 @@ +/* decryptionresult.h - wraps a gpgme keygen result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_DECRYPTIONRESULT_H__ +#define __GPGMEPP_DECRYPTIONRESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/result.h> + +#include <iosfwd> + +#include <tdepimmacros.h> + +namespace GpgME { + + class Error; + + class KDE_EXPORT DecryptionResult : public Result { + public: + DecryptionResult( gpgme_ctx_t ctx=0, int error=0 ); + explicit DecryptionResult( const Error & err ); + DecryptionResult( const DecryptionResult & other ); + ~DecryptionResult(); + + const DecryptionResult & operator=( const DecryptionResult & other ); + + bool isNull() const; + + const char * unsupportedAlgortihm() const; + + bool wrongKeyUsage() const; + + private: + class Private; + Private * d; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const DecryptionResult & result ); + +} + +#endif // __GPGMEPP_DECRYPTIONRESULT_H__ diff --git a/libtdenetwork/gpgmepp/encryptionresult.cpp b/libtdenetwork/gpgmepp/encryptionresult.cpp new file mode 100644 index 00000000..f827ca83 --- /dev/null +++ b/libtdenetwork/gpgmepp/encryptionresult.cpp @@ -0,0 +1,165 @@ +/* encryptionresult.cpp - wraps a gpgme verify result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/encryptionresult.h> +#include "shared.h" +#include "result_p.h" +#include "util.h" + +#include <gpgme.h> + +#include <cstring> +#include <cstdlib> +#include <istream> +#include <algorithm> +#include <iterator> + +class GpgME::EncryptionResult::Private : public GpgME::Shared { +public: + Private( const gpgme_encrypt_result_t r ) : Shared() { + if ( !r ) + return; + for ( gpgme_invalid_key_t ik = r->invalid_recipients ; ik ; ik = ik->next ) { + gpgme_invalid_key_t copy = new _gpgme_invalid_key( *ik ); + if ( ik->fpr ) + copy->fpr = strdup( ik->fpr ); + copy->next = 0; + invalid.push_back( copy ); + } + } + ~Private() { + for ( std::vector<gpgme_invalid_key_t>::iterator it = invalid.begin() ; it != invalid.end() ; ++it ) { + std::free( (*it)->fpr ); + delete *it; *it = 0; + } + } + + std::vector<gpgme_invalid_key_t> invalid; +}; + +GpgME::EncryptionResult::EncryptionResult( gpgme_ctx_t ctx, int error ) + : GpgME::Result( error ), d( 0 ) +{ + if ( error || !ctx ) + return; + gpgme_encrypt_result_t res = gpgme_op_encrypt_result( ctx ); + if ( !res ) + return; + d = new Private( res ); + d->ref(); +} + +make_standard_stuff(EncryptionResult) + + +unsigned int GpgME::EncryptionResult::numInvalidRecipients() const { + return d ? d->invalid.size() : 0 ; +} + +GpgME::InvalidRecipient GpgME::EncryptionResult::invalidEncryptionKey( unsigned int idx ) const { + return InvalidRecipient( d, idx ); +} + +std::vector<GpgME::InvalidRecipient> GpgME::EncryptionResult::invalidEncryptionKeys() const { + if ( !d ) + return std::vector<GpgME::InvalidRecipient>(); + std::vector<GpgME::InvalidRecipient> result; + result.reserve( d->invalid.size() ); + for ( unsigned int i = 0 ; i < d->invalid.size() ; ++i ) + result.push_back( InvalidRecipient( d, i ) ); + return result; +} + + + + +GpgME::InvalidRecipient::InvalidRecipient( EncryptionResult::Private * parent, unsigned int i ) + : d( parent ), idx( i ) +{ + if ( d ) + d->ref(); +} + +GpgME::InvalidRecipient::InvalidRecipient() : d( 0 ), idx( 0 ) {} + +GpgME::InvalidRecipient::InvalidRecipient( const InvalidRecipient & other ) + : d( other.d ), idx( other.idx ) +{ + if ( d ) + d->ref(); +} + +GpgME::InvalidRecipient::~InvalidRecipient() { + if ( d ) + d->unref(); +} + +const GpgME::InvalidRecipient & GpgME::InvalidRecipient::operator=( const InvalidRecipient & other ) { + if ( this->d != other.d ) { + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->unref(); + this->d = other.d; + } + + this->idx = other.idx; + return *this; +} + + +bool GpgME::InvalidRecipient::isNull() const { + return !d || idx >= d->invalid.size() ; +} + +const char * GpgME::InvalidRecipient::fingerprint() const { + return isNull() ? 0 : d->invalid[idx]->fpr ; +} + +GpgME::Error GpgME::InvalidRecipient::reason() const { + return isNull() ? 0 : d->invalid[idx]->reason ; +} + + + +std::ostream & GpgME::operator<<( std::ostream & os, const EncryptionResult & result ) { + os << "GpgME::EncryptionResult("; + if ( !result.isNull() ) { + os << "\n error: " << result.error() + << "\n invalid recipients:\n"; + const std::vector<InvalidRecipient> ir = result.invalidEncryptionKeys(); + std::copy( ir.begin(), ir.end(), + std::ostream_iterator<InvalidRecipient>( os, "\n" ) ); + } + return os << ')'; +} + +std::ostream & GpgME::operator<<( std::ostream & os, const InvalidRecipient & ir ) { + os << "GpgME::InvalidRecipient("; + if ( !ir.isNull() ) + os << "\n fingerprint: " << protect( ir.fingerprint() ) + << "\n reason: " << ir.reason() + << '\n'; + return os << ')'; +} diff --git a/libtdenetwork/gpgmepp/encryptionresult.h b/libtdenetwork/gpgmepp/encryptionresult.h new file mode 100644 index 00000000..4339bef5 --- /dev/null +++ b/libtdenetwork/gpgmepp/encryptionresult.h @@ -0,0 +1,84 @@ +/* encryptionresult.h - wraps a gpgme sign result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_ENCRYPTIONRESULT_H__ +#define __GPGMEPP_ENCRYPTIONRESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/result.h> + +#include <vector> +#include <iosfwd> + +#include <tdepimmacros.h> + +namespace GpgME { + + class Error; + class InvalidRecipient; + + class KDE_EXPORT EncryptionResult : public Result { + public: + EncryptionResult( gpgme_ctx_t ctx=0, int error=0 ); + explicit EncryptionResult( const Error & err ); + EncryptionResult( const EncryptionResult & other ); + ~EncryptionResult(); + + const EncryptionResult & operator=( const EncryptionResult & other ); + + bool isNull() const; + + unsigned int numInvalidRecipients() const; + + InvalidRecipient invalidEncryptionKey( unsigned int index ) const; + std::vector<InvalidRecipient> invalidEncryptionKeys() const; + + class Private; + private: + Private * d; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const EncryptionResult & result ); + + class KDE_EXPORT InvalidRecipient { + friend class EncryptionResult; + InvalidRecipient( EncryptionResult::Private * parent, unsigned int index ); + public: + InvalidRecipient(); + InvalidRecipient( const InvalidRecipient & other ); + ~InvalidRecipient(); + + const InvalidRecipient & operator=( const InvalidRecipient & other ); + + bool isNull() const; + + const char * fingerprint() const; + Error reason() const; + + private: + EncryptionResult::Private * d; + unsigned int idx; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const InvalidRecipient & recipient ); + +} + +#endif // __GPGMEPP_ENCRYPTIONRESULT_H__ diff --git a/libtdenetwork/gpgmepp/engineinfo.cpp b/libtdenetwork/gpgmepp/engineinfo.cpp new file mode 100644 index 00000000..461a61db --- /dev/null +++ b/libtdenetwork/gpgmepp/engineinfo.cpp @@ -0,0 +1,99 @@ +/* engineinfo.h + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "engineinfo.h" +#include "shared.h" + +#include <gpgme.h> + +struct GpgME::EngineInfo::Private : public GpgME::Shared { + Private( gpgme_engine_info_t engine=0 ) : Shared(), info( engine ) {} + ~Private() { info = 0; } + + gpgme_engine_info_t info; +}; + + +GpgME::EngineInfo::EngineInfo() : d(0) {} + +GpgME::EngineInfo::EngineInfo( gpgme_engine_info_t engine ) + : d(0) +{ + d = new Private( engine ); + d->ref(); +} + +GpgME::EngineInfo::EngineInfo( const EngineInfo & other ) + : d( other.d ) +{ + if ( d ) + d->ref(); +} + + +GpgME::EngineInfo::~EngineInfo() { + if ( d ) + d->deref(); +} + +const GpgME::EngineInfo & GpgME::EngineInfo::operator=( const GpgME::EngineInfo & other ) { + if ( this->d == other.d ) + return *this; + + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->unref(); + + this->d = other.d; + return *this; +} + +bool GpgME::EngineInfo::isNull() const { + return !d || !d->info; +} + +GpgME::Context::Protocol GpgME::EngineInfo::protocol() const { + if ( isNull() ) + return Context::Unknown; + switch( d->info->protocol ) { + case GPGME_PROTOCOL_OpenPGP: return Context::OpenPGP; + case GPGME_PROTOCOL_CMS: return Context::CMS; + default: + return Context::Unknown; + } +} + +const char * GpgME::EngineInfo::fileName() const { + return isNull() ? 0 : d->info->file_name; +} + +const char * GpgME::EngineInfo::version() const { + return isNull() ? 0 : d->info->version; +} + +const char * GpgME::EngineInfo::requiredVersion() const { + return isNull() ? 0 : d->info->req_version; +} + diff --git a/libtdenetwork/gpgmepp/engineinfo.h b/libtdenetwork/gpgmepp/engineinfo.h new file mode 100644 index 00000000..c07d2817 --- /dev/null +++ b/libtdenetwork/gpgmepp/engineinfo.h @@ -0,0 +1,53 @@ +/* engineinfo.h + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_ENGINEINFO_H__ +#define __GPGMEPP_ENGINEINFO_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/context.h> + +#include <tdepimmacros.h> + +namespace GpgME { + + class KDE_EXPORT EngineInfo { + public: + EngineInfo(); + EngineInfo( gpgme_engine_info_t engine ); + EngineInfo( const EngineInfo & other ); + ~EngineInfo(); + + const EngineInfo & operator=( const EngineInfo & other ); + + bool isNull() const; + + Context::Protocol protocol() const; + const char * fileName() const; + const char * version() const; + const char * requiredVersion() const; + private: + class Private; + Private * d; + }; + +} + +#endif // __GPGMEPP_ENGINEINFO_H__ diff --git a/libtdenetwork/gpgmepp/eventloopinteractor.cpp b/libtdenetwork/gpgmepp/eventloopinteractor.cpp new file mode 100644 index 00000000..cdac7d56 --- /dev/null +++ b/libtdenetwork/gpgmepp/eventloopinteractor.cpp @@ -0,0 +1,185 @@ +/* eventloopinteractor.cpp + Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/eventloopinteractor.h> + +#include <gpgmepp/context.h> +#include "context_p.h" +#include <gpgmepp/key.h> +#include <gpgmepp/trustitem.h> + +#include <gpgme.h> + +#include <vector> +using std::vector; +#ifndef NDEBUG +# include <iostream> +#endif +#include <cassert> + +namespace GpgME { + + // + // EventLoopInteractor::Private Declaration + // + + struct EventLoopInteractor::Private { + struct OneFD { + OneFD( int aFd, int aDir, gpgme_io_cb_t aFnc, + void * aFncData, void * aExternalTag ) + : fd( aFd ), dir( aDir ), fnc( aFnc ), + fncData( aFncData ), externalTag( aExternalTag ) {} + int fd; + int dir; + gpgme_io_cb_t fnc; + void * fncData; + void * externalTag; + }; + + vector<OneFD*> mCallbacks; + + static void removeIOCb( void * tag ); + static gpgme_error_t registerIOCb( void * data, int fd, int dir, + gpgme_io_cb_t fnc, void * fnc_data, + void ** r_tag ); + static void eventIOCb( void *, gpgme_event_io_t type, void * type_data ); + + static gpgme_io_cbs iocbs; + }; + + gpgme_io_cbs EventLoopInteractor::Private::iocbs = { + &EventLoopInteractor::Private::registerIOCb, + 0, + &EventLoopInteractor::Private::removeIOCb, + &EventLoopInteractor::Private::eventIOCb, + 0 + }; + + + // + // EventLoopInteractor::Private IO Callback Implementations + // + + gpgme_error_t EventLoopInteractor::Private::registerIOCb( void *, int fd, int dir, + gpgme_io_cb_t fnc, void * fnc_data, + void ** r_tag ) + { + assert( instance() ); assert( instance()->d ); + bool ok = false; + void * etag = instance()->registerWatcher( fd, dir ? Read : Write, ok ); + if ( !ok ) return GPG_ERR_GENERAL; + instance()->d->mCallbacks.push_back( new OneFD( fd, dir, fnc, fnc_data, etag ) ); + if ( r_tag ) + *r_tag = instance()->d->mCallbacks.back(); + return GPG_ERR_NO_ERROR; + } + + void EventLoopInteractor::Private::removeIOCb( void * tag ) { + assert( instance() ); assert( instance()->d ); + + for ( vector<OneFD*>::iterator it = instance()->d->mCallbacks.begin() ; + it != instance()->d->mCallbacks.end() ; ++it ) { + if ( *it == tag ) { + instance()->unregisterWatcher( (*it)->externalTag ); + delete *it; *it = 0; + instance()->d->mCallbacks.erase( it ); + return; + } + } + } + + void EventLoopInteractor::Private::eventIOCb( void * data, gpgme_event_io_t type, void * type_data ) { + assert( instance() ); + Context * ctx = static_cast<Context*>( data ); + switch( type ) { + case GPGME_EVENT_START: + { + // hmmm, what to do here? + } + break; + case GPGME_EVENT_DONE: + { + gpgme_error_t e = *static_cast<gpgme_error_t*>( type_data ); + if ( ctx && ctx->impl() ) + ctx->impl()->lasterr = e; + instance()->operationDoneEvent( ctx, e ); + } + break; + case GPGME_EVENT_NEXT_KEY: + { + gpgme_key_t key = static_cast<gpgme_key_t>( type_data ); + instance()->nextKeyEvent( ctx, Key( key, false, ctx ? ctx->keyListMode() : 0 ) ); + } + break; + case GPGME_EVENT_NEXT_TRUSTITEM: + { + gpgme_trust_item_t item = static_cast<gpgme_trust_item_t>( type_data ); + instance()->nextTrustItemEvent( ctx, TrustItem( item ) ); + gpgme_trust_item_unref( item ); + } + break; + default: // warn + ; + } + } + + // + // EventLoopInteractor Implementation + // + + EventLoopInteractor * EventLoopInteractor::mSelf = 0; + + EventLoopInteractor::EventLoopInteractor() { + assert( !mSelf ); + d = new Private(); + mSelf = this; + } + + EventLoopInteractor::~EventLoopInteractor() { + // warn if there are still callbacks registered + mSelf = 0; + delete d; d = 0; + } + + void EventLoopInteractor::manage( Context * context ) { + if ( !context || context->managedByEventLoopInteractor() ) return; + gpgme_io_cbs * iocbs = new gpgme_io_cbs( Private::iocbs ); + iocbs->event_priv = context; + context->installIOCallbacks( iocbs ); + } + + void EventLoopInteractor::unmanage( Context * context ) { + if ( context ) + context->uninstallIOCallbacks(); + } + + void EventLoopInteractor::actOn( int fd, Direction dir ) { + for ( vector<Private::OneFD*>::const_iterator it = d->mCallbacks.begin() ; + it != d->mCallbacks.end() ; ++it ) + if ( (*it)->fd == fd && ( (*it)->dir ? Read : Write ) == dir ) { + (*((*it)->fnc))( (*it)->fncData, fd ); + break; + } + } + +} // namespace GpgME diff --git a/libtdenetwork/gpgmepp/eventloopinteractor.h b/libtdenetwork/gpgmepp/eventloopinteractor.h new file mode 100644 index 00000000..c3688833 --- /dev/null +++ b/libtdenetwork/gpgmepp/eventloopinteractor.h @@ -0,0 +1,148 @@ +/* eventloopinteractor.h + Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +// -*- c++ -*- +#ifndef __GPGMEPP_EVENTLOOPINTERACTOR_H__ +#define __GPGMEPP_EVENTLOOPINTERACTOR_H__ + +#include <tdepimmacros.h> + +namespace GpgME { + + class Context; + class Error; + class TrustItem; + class Key; + + /*! \file eventloopinteractor.h + \brief Abstract base class for gpgme's external event loop support + + This class does most of the work involved with hooking GpgME++ + up with external event loops, such as the GTK or TQt ones. + + It actually provides two interfaces: An interface to the gpgme + IO Callback handling and one for gpgme events. The IO Callback + interface consists of the three methods \c actOn(), \c + registerWatcher() and \c unregisterWatcher(). The event + interface consists of the three methods \c nextTrustItemEvent(), + \c nextKeyEvent() and \c operationDoneEvent(). + + \sect General Usage + + \c EventLoopInteractor is designed to be used as a + singleton. However, in order to make any use of it, you have to + subclass it and reimplement it's pure virtual methods (see + below). We suggest you keep the constructor protected and + provide a static \c instance() method that returns the single + instance. Alternatively, you can create an instance on the + stack, e.g. in \c main(). + + If you want \c EventLoopInteractor to manage a particular \c + Context, just call \c manage() on the \c Context. OTOH, if you + want to disable IO callbacks for a \c Context, use \c unmanage(). + + \sect IO Callback Interface + + One part of this interface is represented by \c + registerWatcher() and \c unregisterWatcher(), both of which are + pure virtual. \c registerWatcher() should do anything necessary + to hook up watching of file descriptor \c fd for reading (\c dir + = \c Read) or writing (\c dir = Write) to the event loop you use + and return a tag identifying that particular watching process + uniquely. This could be the index into an array of objects you + use for that purpose or the address of such an object. E.g. in + TQt, you'd essentially just create a new \c TQSocketNotifier: + + \verbatim + void * registerWatcher( int fd, Direction dir ) { + return new TQSocketNotifier( fd, dir == Read ? TQSocketNotifier::Read : TQSocketNotifier::Write ); + // misses connecting to the activated() signal... + } + \endverbatim + + which uses the address of the created object as unique tag. The + tag returned by \c registerWatcher is stored by \c + EventLoopInteractor and passed as argument to \c + unregisterWatcher(). So, in the picture above, you'd implement \c + unregisterWatcher() like this: + + \verbatim + void unregisterWatcher( void * tag ) { + delete static_cast<TQSocketNotifier*>( tag ); + } + \endverbatim + + The other part of the IO callback interface is \c actOn(), which + you should call if you receive notification from your event loop + about activity on file descriptor \c fd in direction \c dir. In + the picture above, you'd call this from the slot connected to + the socket notifier's \c activated() signal. + + \note \c registerWatcher() as well as \c unregisterWatcher() may + be called from within \c actOn(), so be careful with + e.g. locking in threaded environments and keep in mind that the + object you used to find the \c fd and \c dir fo the \c actOn() + call might be deleted when \c actOn() returns! + + \sect Event Handler Interface + + + */ + class KDE_EXPORT EventLoopInteractor { + protected: + EventLoopInteractor(); + public: + virtual ~EventLoopInteractor(); + + static EventLoopInteractor * instance() { return mSelf; } + + void manage( Context * context ); + void unmanage( Context * context ); + + enum Direction { Read, Write }; + protected: + // + // IO Notification Interface + // + + /** Call this if your event loop detected activity on file + descriptor fd, with direction dir */ + void actOn( int fd, Direction dir ); + + virtual void * registerWatcher( int fd, Direction dir, bool & ok ) = 0; + virtual void unregisterWatcher( void * tag ) = 0; + + // + // Event Handler Interface + // + + virtual void nextTrustItemEvent( Context * context, const TrustItem & item ) = 0; + virtual void nextKeyEvent( Context * context, const Key & key ) = 0; + virtual void operationDoneEvent( Context * context, const Error & e ) = 0; + + private: + class Private; + friend class Private; + Private * d; + static EventLoopInteractor * mSelf; + }; + +} + +#endif // __GPGMEPP_EVENTLOOPINTERACTOR_H__ diff --git a/libtdenetwork/gpgmepp/gpgme-0-3-compat.h b/libtdenetwork/gpgmepp/gpgme-0-3-compat.h new file mode 100644 index 00000000..5f8c5b61 --- /dev/null +++ b/libtdenetwork/gpgmepp/gpgme-0-3-compat.h @@ -0,0 +1,49 @@ +/* gpgmefw.h - Forwards declarations for gpgme (0.3 and 0.4) + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_GPGME_0_3_COMPAT_H__ +#define __GPGMEPP_GPGME_0_3_COMPAT_H__ + +#include <gpgme.h> + +#ifndef HAVE_GPGME_0_4_BRANCH +// make gpgme-0.4 names available even if we have only 0.3: +typedef GpgmeError gpgme_error_t; +typedef GpgmeIOCb gpgme_io_cb_t; +typedef GpgmeIOCbs gpgme_io_cbs; +typedef GpgmeEventIO gpgme_event_io_t; +typedef GpgmeEventIOCb gpgme_event_io_cb_t; +typedef GpgmeRegisterIOCb gpgme_register_io_cb_t; +typedef GpgmeRemoveIOCb gpgme_remove_io_cb_t; +typedef GpgmeSigStat gpgme_sig_stat_t; +typedef GpgmeAttr gpgme_attr_t; +typedef GpgmeTrustItem gpgme_trust_item_t; +typedef GpgmeCtx gpgme_ctx_t; +typedef GpgmeProtocol gpgme_protocol_t; +typedef GpgmeData gpgme_data_t; +typedef GpgmeKey gpgme_key_t; + +#define GPG_ERR_GENERAL GPGME_General_Error +#define GPG_ERR_NO_ERROR GPGME_No_Error +#define GPG_ERR_EOF GPGME_EOF +#define gpg_err_code(x) (x) +#endif + +#endif // __GPGMEPP_GPGME_0_3_COMPAT_H__ diff --git a/libtdenetwork/gpgmepp/gpgmefw.h b/libtdenetwork/gpgmepp/gpgmefw.h new file mode 100644 index 00000000..8fe43746 --- /dev/null +++ b/libtdenetwork/gpgmepp/gpgmefw.h @@ -0,0 +1,60 @@ +/* gpgmefw.h - Forwards declarations for gpgme (0.3 and 0.4) + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_GPGMEFW_H__ +#define __GPGMEPP_GPGMEFW_H__ + +#ifndef HAVE_GPGME_0_4_BRANCH +#error You need gpgme 0.4.x, x >= 4, to compile gpgme++ +#endif + +struct gpgme_context; +typedef gpgme_context * gpgme_ctx_t; + +struct gpgme_data; +typedef gpgme_data * gpgme_data_t; + +struct gpgme_io_cbs; + +struct _gpgme_key; +typedef struct _gpgme_key * gpgme_key_t; + +struct _gpgme_trust_item; +typedef struct _gpgme_trust_item * gpgme_trust_item_t; + +struct _gpgme_subkey; +typedef struct _gpgme_subkey * gpgme_sub_key_t; + +struct _gpgme_user_id; +typedef struct _gpgme_user_id * gpgme_user_id_t; + +struct _gpgme_key_sig; +typedef struct _gpgme_key_sig * gpgme_key_sig_t; + +struct _gpgme_sig_notation; +typedef struct _gpgme_sig_notation * gpgme_sig_notation_t; + +struct _gpgme_engine_info; +typedef struct _gpgme_engine_info * gpgme_engine_info_t; + +struct _gpgme_op_keylist_result; +typedef struct _gpgme_op_keylist_result * gpgme_keylist_result_t; + +#endif // __GPGMEPP_GPGMEFW_H__ diff --git a/libtdenetwork/gpgmepp/importresult.cpp b/libtdenetwork/gpgmepp/importresult.cpp new file mode 100644 index 00000000..3b4b713c --- /dev/null +++ b/libtdenetwork/gpgmepp/importresult.cpp @@ -0,0 +1,204 @@ +/* importresult.cpp - wraps a gpgme import result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/importresult.h> +#include "shared.h" +#include "result_p.h" + +#include <gpgme.h> +#include <cstring> +#include <cstdlib> +#include <cstdlib> + +class GpgME::ImportResult::Private : public GpgME::Shared { +public: + Private( const _gpgme_op_import_result & r ) : Shared(), res( r ) { + // copy recursively, using compiler-generated copy ctor. + // We just need to handle the pointers in the structs: + for ( gpgme_import_status_t is = r.imports ; is ; is = is->next ) { + gpgme_import_status_t copy = new _gpgme_import_status( *is ); + copy->fpr = strdup( is->fpr ); + copy->next = 0; + imports.push_back( copy ); + } + res.imports = 0; + } + ~Private() { + for ( std::vector<gpgme_import_status_t>::iterator it = imports.begin() ; it != imports.end() ; ++it ) { + std::free( (*it)->fpr ); + delete *it; *it = 0; + } + } + + _gpgme_op_import_result res; + std::vector<gpgme_import_status_t> imports; +}; + +GpgME::ImportResult::ImportResult( gpgme_ctx_t ctx, int error ) + : GpgME::Result( error ), d( 0 ) +{ + if ( error || !ctx ) + return; + gpgme_import_result_t res = gpgme_op_import_result( ctx ); + if ( !res ) + return; + d = new Private( *res ); + d->ref(); +} + +make_standard_stuff(ImportResult) + +int GpgME::ImportResult::numConsidered() const { + return d ? d->res.considered : 0 ; +} + +int GpgME::ImportResult::numKeysWithoutUserID() const { + return d ? d->res.no_user_id : 0 ; +} + +int GpgME::ImportResult::numImported() const { + return d ? d->res.imported : 0 ; +} + +int GpgME::ImportResult::numRSAImported() const { + return d ? d->res.imported_rsa : 0 ; +} + +int GpgME::ImportResult::numUnchanged() const { + return d ? d->res.unchanged : 0 ; +} + +int GpgME::ImportResult::newUserIDs() const { + return d ? d->res.new_user_ids : 0 ; +} + +int GpgME::ImportResult::newSubkeys() const { + return d ? d->res.new_sub_keys : 0 ; +} + +int GpgME::ImportResult::newSignatures() const { + return d ? d->res.new_signatures : 0 ; +} + +int GpgME::ImportResult::newRevocations() const { + return d ? d->res.new_revocations : 0 ; +} + +int GpgME::ImportResult::numSecretKeysConsidered() const { + return d ? d->res.secret_read : 0 ; +} + +int GpgME::ImportResult::numSecretKeysImported() const { + return d ? d->res.secret_imported : 0 ; +} + +int GpgME::ImportResult::numSecretKeysUnchanged() const { + return d ? d->res.secret_unchanged : 0 ; +} + +int GpgME::ImportResult::notImported() const { + return d ? d->res.not_imported : 0 ; +} + +GpgME::Import GpgME::ImportResult::import( unsigned int idx ) const { + return Import( d, idx ); +} + +std::vector<GpgME::Import> GpgME::ImportResult::imports() const { + if ( !d ) + return std::vector<Import>(); + std::vector<Import> result; + result.reserve( d->imports.size() ); + for ( unsigned int i = 0 ; i < d->imports.size() ; ++i ) + result.push_back( Import( d, i ) ); + return result; +} + + + + + + +GpgME::Import::Import( ImportResult::Private * parent, unsigned int i ) + : d( parent ), idx( i ) +{ + if ( d ) + d->ref(); +} + +GpgME::Import::Import() : d( 0 ), idx( 0 ) {} + +GpgME::Import::Import( const Import & other ) + : d( other.d ), idx( other.idx ) +{ + if ( d ) + d->ref(); +} + +GpgME::Import::~Import() { + if ( d ) + d->unref(); +} + +const GpgME::Import & GpgME::Import::operator=( const Import & other ) { + if ( this->d != other.d ) { + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->unref(); + this->d = other.d; + } + + this->idx = other.idx; + return *this; +} + + +bool GpgME::Import::isNull() const { + return !d || idx >= d->imports.size() ; +} + + + + +const char * GpgME::Import::fingerprint() const { + return isNull() ? 0 : d->imports[idx]->fpr ; +} + +GpgME::Error GpgME::Import::error() const { + return isNull() ? 0 : d->imports[idx]->result ; +} + +GpgME::Import::tqStatus GpgME::Import::status() const { + if ( isNull() ) + return Unknown; + unsigned int s = d->imports[idx]->status; + unsigned int result = Unknown; + if ( s & GPGME_IMPORT_NEW ) result |= NewKey; + if ( s & GPGME_IMPORT_UID ) result |= NewUserIDs; + if ( s & GPGME_IMPORT_SIG ) result |= NewSignatures; + if ( s & GPGME_IMPORT_SUBKEY ) result |= NewSubkeys; + if ( s & GPGME_IMPORT_SECRET ) result |= ContainedSecretKey; + return static_cast<tqStatus>( result ); +} diff --git a/libtdenetwork/gpgmepp/importresult.h b/libtdenetwork/gpgmepp/importresult.h new file mode 100644 index 00000000..61675a29 --- /dev/null +++ b/libtdenetwork/gpgmepp/importresult.h @@ -0,0 +1,103 @@ +/* importresult.h - wraps a gpgme import result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_IMPORTRESULT_H__ +#define __GPGMEPP_IMPORTRESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/result.h> + +#include <vector> +#include <tdepimmacros.h> + +namespace GpgME { + + class Error; + class Import; + + class KDE_EXPORT ImportResult : public Result { + public: + ImportResult( gpgme_ctx_t ctx=0, int error=0 ); + explicit ImportResult( const Error & error ); + ImportResult( const ImportResult & other ); + ~ImportResult(); + + const ImportResult & operator=( const ImportResult & other ); + + bool isNull() const; + + int numConsidered() const; + int numKeysWithoutUserID() const; + int numImported() const; + int numRSAImported() const; + int numUnchanged() const; + + int newUserIDs() const; + int newSubkeys() const; + int newSignatures() const; + int newRevocations() const; + + int numSecretKeysConsidered() const; + int numSecretKeysImported() const; + int numSecretKeysUnchanged() const; + + int notImported() const; + + Import import( unsigned int idx ) const; + std::vector<Import> imports() const; + + class Private; + private: + Private * d; + }; + + class KDE_EXPORT Import { + friend class ImportResult; + Import( ImportResult::Private * parent, unsigned int idx ); + public: + Import(); + Import( const Import & other ); + ~Import(); + + const Import & operator=( const Import & other ); + + bool isNull() const; + + const char * fingerprint() const; + Error error() const; + + enum tqStatus { + Unknown = 0x0, + NewKey = 0x1, + NewUserIDs = 0x2, + NewSignatures = 0x4, + NewSubkeys = 0x8, + ContainedSecretKey = 0x10 + }; + tqStatus status() const; + + private: + ImportResult::Private * d; + unsigned int idx; + }; + +} + +#endif // __GPGMEPP_IMPORTRESULT_H__ diff --git a/libtdenetwork/gpgmepp/interfaces/CMakeLists.txt b/libtdenetwork/gpgmepp/interfaces/CMakeLists.txt new file mode 100644 index 00000000..db5b88ee --- /dev/null +++ b/libtdenetwork/gpgmepp/interfaces/CMakeLists.txt @@ -0,0 +1,14 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES + editinteractor.h passphraseprovider.h progressprovider.h + DESTINATION ${INCLUDE_INSTALL_DIR}/gpgme++/interfaces ) diff --git a/libtdenetwork/gpgmepp/interfaces/Makefile.am b/libtdenetwork/gpgmepp/interfaces/Makefile.am new file mode 100644 index 00000000..ad2f79e4 --- /dev/null +++ b/libtdenetwork/gpgmepp/interfaces/Makefile.am @@ -0,0 +1,3 @@ +gpgmeppinterfacesdir = $(includedir)/gpgme++/interfaces +gpgmeppinterfaces_HEADERS = editinteractor.h \ + passphraseprovider.h progressprovider.h diff --git a/libtdenetwork/gpgmepp/interfaces/dataprovider.h b/libtdenetwork/gpgmepp/interfaces/dataprovider.h new file mode 100644 index 00000000..34dd4a7e --- /dev/null +++ b/libtdenetwork/gpgmepp/interfaces/dataprovider.h @@ -0,0 +1,48 @@ +/* interface/dataprovider.h - Interface for data sources + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_INTERFACES_DATAPROVIDER_H__ +#define __GPGMEPP_INTERFACES_DATAPROVIDER_H__ + +#include <sys/types.h> + +#include <tdepimmacros.h> + +namespace GpgME { + + class KDE_EXPORT DataProvider { + public: + virtual ~DataProvider() {} + + enum Operation { + Read, Write, Seek, Release + }; + virtual bool isSupported( Operation op ) const = 0; + + + virtual ssize_t read( void * buffer, size_t bufSize ) = 0; + virtual ssize_t write( const void * buffer, size_t bufSize ) = 0; + virtual off_t seek( off_t offset, int whence ) = 0; + virtual void release() = 0; + }; + +} // namespace GpgME + +#endif // __GPGMEPP_INTERFACES_DATAPROVIDER_H__ diff --git a/libtdenetwork/gpgmepp/interfaces/editinteractor.h b/libtdenetwork/gpgmepp/interfaces/editinteractor.h new file mode 100644 index 00000000..e1f31eed --- /dev/null +++ b/libtdenetwork/gpgmepp/interfaces/editinteractor.h @@ -0,0 +1,35 @@ +/* interface/editinteractor.h - Interface for key edit functions + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_INTERFACES_EDITINTERACTOR_H__ +#define __GPGMEPP_INTERFACES_EDITINTERACTOR_H__ + +namespace GpgME { + + class EditInteractor { + public: + virtual ~EditInteractor() {} + + virtual bool interactiveEdit( int status, const char * args, const char ** reply ) = 0; + }; + +} // namespace GpgME + +#endif // __GPGMEPP_INTERFACES_EDITINTERACTOR_H__ diff --git a/libtdenetwork/gpgmepp/interfaces/passphraseprovider.h b/libtdenetwork/gpgmepp/interfaces/passphraseprovider.h new file mode 100644 index 00000000..37ff6a8b --- /dev/null +++ b/libtdenetwork/gpgmepp/interfaces/passphraseprovider.h @@ -0,0 +1,38 @@ +/* interface/passphraseprovider.h - Interface for passphrase callbacks + Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_INTERFACES_PASSPHRASEPROVIDER_H__ +#define __GPGMEPP_INTERFACES_PASSPHRASEPROVIDER_H__ + +#include <string> + +namespace GpgME { + + class PassphraseProvider { + public: + virtual ~PassphraseProvider() {} + + virtual char * getPassphrase( const char * useridHint, const char * description, + bool previousWasbad, bool & canceled ) = 0; + }; + +} // namespace GpgME + +#endif // __GPGMEPP_INTERFACES_PASSPHRASEPROVIDER_H__ diff --git a/libtdenetwork/gpgmepp/interfaces/progressprovider.h b/libtdenetwork/gpgmepp/interfaces/progressprovider.h new file mode 100644 index 00000000..b51765b7 --- /dev/null +++ b/libtdenetwork/gpgmepp/interfaces/progressprovider.h @@ -0,0 +1,36 @@ +/* interface/progressprovider.h - Interface for progress reports + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_INTERFACES_PROGRESSPROVIDER_H__ +#define __GPGMEPP_INTERFACES_PROGRESSPROVIDER_H__ + +namespace GpgME { + + class ProgressProvider { + public: + virtual ~ProgressProvider() {} + + virtual void showProgress( const char * what, int type, + int current, int total ) = 0; + }; + +} // namespace GpgME + +#endif // __GPGMEPP_INTERFACES_PROGRESSPROVIDER_H__ diff --git a/libtdenetwork/gpgmepp/key.cpp b/libtdenetwork/gpgmepp/key.cpp new file mode 100644 index 00000000..13cd0a7e --- /dev/null +++ b/libtdenetwork/gpgmepp/key.cpp @@ -0,0 +1,926 @@ +/* key.cpp - wraps a gpgme key + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/key.h> + +#include "util.h" + +#include <gpgme.h> + +#include <string.h> + +GpgME::Key GpgME::Key::null; + +namespace GpgME { + + using std::vector; + + struct Key::Private { + Private( gpgme_key_t aKey, unsigned int aMode ) + : key( aKey ), +#ifdef HAVE_GPGME_KEY_T_KEYLIST_MODE + mode( 0 ) +#else + mode( aMode ) +#endif + {} + gpgme_key_t key; + unsigned int mode; + }; + + Key::Key() { + d = new Private( 0, 0 ); + } + + Key::Key( gpgme_key_t key, bool ref, unsigned int mode ) { + d = new Private( key, mode ); + if ( ref && d->key ) + gpgme_key_ref( d->key ); + } + + Key::Key( const Key & other ) { + d = new Private( other.d->key, other.d->mode ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + Key::~Key() { + if ( d->key ) + gpgme_key_unref( d->key ); + delete d; d = 0; + } + + const Key & Key::operator=( const Key & other ) { + if ( d == other.d ) return *this; + + if ( other.d->key ) + gpgme_key_ref( other.d->key ); + if ( d->key ) + gpgme_key_unref( d->key ); + *d = *other.d; + return *this; + } + + bool Key::isNull() const { + return d->key == 0; + } + + gpgme_key_t Key::impl() const { + return d->key; + } + + + + UserID Key::userID( unsigned int index ) const { + return UserID( d->key, index ); + } + + Subkey Key::subkey( unsigned int index ) const { + return Subkey( d->key, index ); + } + + + unsigned int Key::numUserIDs() const { + if ( !d->key ) + return 0; + unsigned int count = 0; + for ( gpgme_user_id_t uid = d->key->uids ; uid ; uid = uid->next ) + ++count; + return count; + } + + unsigned int Key::numSubkeys() const { + if ( !d->key ) + return 0; + unsigned int count = 0; + for ( gpgme_sub_key_t subkey = d->key->subkeys ; subkey ; subkey = subkey->next ) + ++count; + return count; + } + + vector<UserID> Key::userIDs() const { + if ( !d->key ) + return vector<UserID>(); + + vector<UserID> v; + v.reserve( numUserIDs() ); + for ( gpgme_user_id_t uid = d->key->uids ; uid ; uid = uid->next ) + v.push_back( UserID( d->key, uid ) ); + return v; + } + + vector<Subkey> Key::subkeys() const { + if ( !d->key ) + return vector<Subkey>(); + + vector<Subkey> v; + v.reserve( numSubkeys() ); + for ( gpgme_sub_key_t subkey = d->key->subkeys ; subkey ; subkey = subkey->next ) + v.push_back( Subkey( d->key, subkey ) ); + return v; + } + + Key::OwnerTrust Key::ownerTrust() const { + if ( !d->key ) + return Unknown; + switch ( d->key->owner_trust ) { + default: + case GPGME_VALIDITY_UNKNOWN: return Unknown; + case GPGME_VALIDITY_UNDEFINED: return Undefined; + case GPGME_VALIDITY_NEVER: return Never; + case GPGME_VALIDITY_MARGINAL: return Marginal; + case GPGME_VALIDITY_FULL: return Full; + case GPGME_VALIDITY_ULTIMATE: return Ultimate; + } + } + char Key::ownerTrustAsString() const { + if ( !d->key ) + return '?'; + switch ( d->key->owner_trust ) { + default: + case GPGME_VALIDITY_UNKNOWN: return '?'; + case GPGME_VALIDITY_UNDEFINED: return 'q'; + case GPGME_VALIDITY_NEVER: return 'n'; + case GPGME_VALIDITY_MARGINAL: return 'm'; + case GPGME_VALIDITY_FULL: return 'f'; + case GPGME_VALIDITY_ULTIMATE: return 'u'; + } + } + + Context::Protocol Key::protocol() const { + if ( !d->key ) + return Context::Unknown; + switch ( d->key->protocol ) { + case GPGME_PROTOCOL_CMS: return Context::CMS; + case GPGME_PROTOCOL_OpenPGP: return Context::OpenPGP; + default: return Context::Unknown; + } + } + + const char * Key::protocolAsString() const { + return d->key ? gpgme_get_protocol_name( d->key->protocol ) : 0 ; + } + + bool Key::isRevoked() const { + return d->key && d->key->revoked; + } + + bool Key::isExpired() const { + return d->key && d->key->expired; + } + + bool Key::isDisabled() const { + return d->key && d->key->disabled; + } + + bool Key::isInvalid() const { + return d->key && d->key->invalid; + } + + bool Key::hasSecret() const { + return d->key && d->key->secret; + } + + bool Key::isRoot() const { + return d->key && d->key->subkeys && d->key->subkeys->fpr && d->key->chain_id && + strcasecmp( d->key->subkeys->fpr, d->key->chain_id ) == 0; + } + + bool Key::canEncrypt() const { + return d->key && d->key->can_encrypt; + } + + bool Key::canSign() const { +#ifndef GPGME_CAN_SIGN_ON_SECRET_OPENPGP_KEYLISTING_NOT_BROKEN + if ( d->key && d->key->protocol == GPGME_PROTOCOL_OpenPGP ) + return true; +#endif + return d->key && d->key->can_sign; + } + + bool Key::canCertify() const { + return d->key && d->key->can_certify; + } + + bool Key::canAuthenticate() const { + return d->key && d->key->can_authenticate; + } + + const char * Key::issuerSerial() const { + return d->key ? d->key->issuer_serial : 0 ; + } + const char * Key::issuerName() const { + return d->key ? d->key->issuer_name : 0 ; + } + const char * Key::chainID() const { + return d->key ? d->key->chain_id : 0 ; + } + + const char * Key::keyID() const { +#ifdef HAVE_GPGME_KEY_T_KEYID + return d->key ? d->key->keyid : 0 ; +#else + if ( !d->key || !d->key->subkeys || !d->key->subkeys->fpr ) + return 0; + const int len = strlen( d->key->subkeys->fpr ); + if ( len < 16 ) + return 0; + return d->key->subkeys->fpr + len - 16; // return the last 8 bytes (in hex notation) +#endif + } + + const char * Key::shortKeyID() const { + if ( const char * keyid = keyID() ) + return keyid + 8 ; + else + return 0; + } + + const char * Key::primaryFingerprint() const { +#ifdef HAVE_GPGME_KEY_T_FPR + return d->key ? d->key->fpr : 0 ; +#else + return d->key && d->key->subkeys ? d->key->subkeys->fpr : 0 ; +#endif + } + + unsigned int Key::keyListMode() const { +#ifdef HAVE_GPGME_KEY_T_KEYLIST_MODE + return d->key ? convert_from_gpgme_keylist_mode_t( d->key->keylist_mode ) : 0 ; +#else + return d ? d->mode : 0 ; +#endif + } + + // + // + // class Subkey + // + // + + struct Subkey::Private { + Private( gpgme_key_t aKey, unsigned int idx ) + : key( aKey ), subkey( 0 ) + { + if ( key ) + for ( gpgme_sub_key_t s = key->subkeys ; s ; s = s->next, --idx ) + if ( idx == 0 ) { + subkey = s; + break; + } + if ( !subkey ) + key = 0; + } + + Private( gpgme_key_t aKey, gpgme_sub_key_t aSubkey ) + : key( aKey ), subkey( 0 ) + { + if ( key ) + for ( gpgme_sub_key_t s = key->subkeys ; s ; s = s->next ) + if ( s == aSubkey ) { // verify this subkey really belongs to this key + subkey = aSubkey; + break; + } + if ( !subkey ) + key = 0; + } + + gpgme_key_t key; + gpgme_sub_key_t subkey; + }; + + Subkey::Subkey( gpgme_key_t key, unsigned int idx ) { + d = new Private( key, idx ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + Subkey::Subkey( gpgme_key_t key, gpgme_sub_key_t subkey ) { + d = new Private( key, subkey ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + Subkey::Subkey( const Subkey & other ) { + d = new Private( other.d->key, other.d->subkey ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + Subkey::~Subkey() { + if ( d->key ) + gpgme_key_unref( d->key ); + delete d; d = 0; + } + + const Subkey & Subkey::operator=( const Subkey & other ) { + if ( &other == this ) return *this; + + if ( other.d->key ) + gpgme_key_ref( other.d->key ); + if ( d->key ) + gpgme_key_unref( d->key ); + *d = *other.d; + return *this; + } + + bool Subkey::isNull() const { + return !d || !d->key || !d->subkey; + } + + Key Subkey::parent() const { + return Key( d->key, true ); + } + + const char * Subkey::keyID() const { + return d->subkey ? d->subkey->keyid : 0 ; + } + + const char * Subkey::fingerprint() const { + return d->subkey ? d->subkey->fpr : 0 ; + } + + unsigned int Subkey::publicKeyAlgorithm() const { + return d->subkey ? d->subkey->pubkey_algo : 0 ; + } + + const char * Subkey::publicKeyAlgorithmAsString() const { + return gpgme_pubkey_algo_name( d->subkey ? d->subkey->pubkey_algo : (gpgme_pubkey_algo_t)0 ); + } + + bool Subkey::canEncrypt() const { + return d->subkey && d->subkey->can_encrypt; + } + + bool Subkey::canSign() const { + return d->subkey && d->subkey->can_sign; + } + + bool Subkey::canCertify() const { + return d->subkey && d->subkey->can_certify; + } + + bool Subkey::canAuthenticate() const { + return d->subkey && d->subkey->can_authenticate; + } + + bool Subkey::isSecret() const { + return d->subkey && d->subkey->secret; + } + + unsigned int Subkey::length() const { + return d->subkey ? d->subkey->length : 0 ; + } + + time_t Subkey::creationTime() const { + return static_cast<time_t>( d->subkey ? d->subkey->timestamp : 0 ); + } + + time_t Subkey::expirationTime() const { + return static_cast<time_t>( d->subkey ? d->subkey->expires : 0 ); + } + + bool Subkey::neverExpires() const { + return expirationTime() == time_t(0); + } + + bool Subkey::isRevoked() const { + return d->subkey && d->subkey->revoked; + } + + bool Subkey::isInvalid() const { + return d->subkey && d->subkey->invalid; + } + + bool Subkey::isExpired() const { + return d->subkey && d->subkey->expired; + } + + bool Subkey::isDisabled() const { + return d->subkey && d->subkey->disabled; + } + + // + // + // class UserID + // + // + + struct UserID::Private { + Private( gpgme_key_t aKey, unsigned int idx ) + : key( aKey ), uid( 0 ) + { + if ( key ) + for ( gpgme_user_id_t u = key->uids ; u ; u = u->next, --idx ) + if ( idx == 0 ) { + uid = u; + break; + } + if ( !uid ) + key = 0; + } + + Private( gpgme_key_t aKey, gpgme_user_id_t aUid ) + : key( aKey ), uid( 0 ) + { + if ( key ) + for ( gpgme_user_id_t u = key->uids ; u ; u = u->next ) + if ( u == aUid ) { + uid = u; + break; + } + if ( !uid ) + key = 0; + } + + gpgme_key_t key; + gpgme_user_id_t uid; + }; + + UserID::UserID( gpgme_key_t key, gpgme_user_id_t uid ) { + d = new Private( key, uid ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::UserID( gpgme_key_t key, unsigned int idx ) { + d = new Private( key, idx ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::UserID( const UserID & other ) { + d = new Private( other.d->key, other.d->uid ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::~UserID() { + if ( d->key ) + gpgme_key_unref( d->key ); + delete d; d = 0; + } + + const UserID & UserID::operator=( const UserID & other ) { + if ( &other == this ) return *this; + + if ( other.d->key ) + gpgme_key_ref( other.d->key ); + if ( d->key ) + gpgme_key_unref( d->key ); + *d = *other.d; + return *this; + } + + bool UserID::isNull() const { + return !d || !d->key || !d->uid; + } + + Key UserID::parent() const { + return Key( d->key, true ); + } + + UserID::Signature UserID::signature( unsigned int index ) const { + return Signature( d->key, d->uid, index ); + } + + unsigned int UserID::numSignatures() const { + if ( !d->uid ) + return 0; + unsigned int count = 0; + for ( gpgme_key_sig_t sig = d->uid->signatures ; sig ; sig = sig->next ) + ++count; + return count; + } + + vector<UserID::Signature> UserID::signatures() const { + if ( !d->uid ) + return vector<Signature>(); + + vector<Signature> v; + v.reserve( numSignatures() ); + for ( gpgme_key_sig_t sig = d->uid->signatures ; sig ; sig = sig->next ) + v.push_back( Signature( d->key, d->uid, sig ) ); + return v; + } + + const char * UserID::id() const { + return d->uid ? d->uid->uid : 0 ; + } + + const char * UserID::name() const { + return d->uid ? d->uid->name : 0 ; + } + + const char * UserID::email() const { + return d->uid ? d->uid->email : 0 ; + } + + const char * UserID::comment() const { + return d->uid ? d->uid->comment : 0 ; + } + + UserID::Validity UserID::validity() const { + if ( !d->uid ) + return Unknown; + switch ( d->uid->validity ) { + default: + case GPGME_VALIDITY_UNKNOWN: return Unknown; + case GPGME_VALIDITY_UNDEFINED: return Undefined; + case GPGME_VALIDITY_NEVER: return Never; + case GPGME_VALIDITY_MARGINAL: return Marginal; + case GPGME_VALIDITY_FULL: return Full; + case GPGME_VALIDITY_ULTIMATE: return Ultimate; + } + } + + char UserID::validityAsString() const { + if ( !d->uid ) + return '?'; + switch ( d->uid->validity ) { + default: + case GPGME_VALIDITY_UNKNOWN: return '?'; + case GPGME_VALIDITY_UNDEFINED: return 'q'; + case GPGME_VALIDITY_NEVER: return 'n'; + case GPGME_VALIDITY_MARGINAL: return 'm'; + case GPGME_VALIDITY_FULL: return 'f'; + case GPGME_VALIDITY_ULTIMATE: return 'u'; + } + } + + bool UserID::isRevoked() const { + return d->uid && d->uid->revoked; + } + + bool UserID::isInvalid() const { + return d->uid && d->uid->invalid; + } + + // + // + // class Signature + // + // + + struct UserID::Signature::Private { + Private( gpgme_key_t aKey, gpgme_user_id_t aUid, unsigned int idx ) + : key( aKey ), uid( 0 ), sig( 0 ) + { + if ( key ) + for ( gpgme_user_id_t u = key->uids ; u ; u = u->next ) + if ( u == aUid ) { + uid = u; + for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, --idx ) + if ( idx == 0 ) { + sig = s; + break; + } + break; + } + if ( !uid || !sig ) { + uid = 0; + sig = 0; + key = 0; + } + } + + Private( gpgme_key_t aKey, gpgme_user_id_t aUid, gpgme_key_sig_t aSig ) + : key( aKey ), uid( 0 ), sig( 0 ) + { + if ( key ) + for ( gpgme_user_id_t u = key->uids ; u ; u = u->next ) + if ( u == aUid ) { + uid = u; + for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next ) + if ( s == aSig ) { + sig = s; + break; + } + break; + } + if ( !uid || !sig ) { + uid = 0; + sig = 0; + key = 0; + } + } + + gpgme_key_t key; + gpgme_user_id_t uid; + gpgme_key_sig_t sig; + }; + + UserID::Signature::Signature( gpgme_key_t key, gpgme_user_id_t uid, unsigned int idx ) { + d = new Private( key, uid, idx ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::Signature::Signature( gpgme_key_t key, gpgme_user_id_t uid, gpgme_key_sig_t sig ) { + d = new Private( key, uid, sig ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::Signature::Signature( const Signature & other ) { + d = new Private( other.d->key, other.d->uid, other.d->sig ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::Signature::~Signature() { + if ( d->key ) + gpgme_key_unref( d->key ); + delete d; d = 0; + } + + const UserID::Signature & UserID::Signature::operator=( const Signature & other ) { + if ( &other == this ) return *this; + + if ( other.d->key ) + gpgme_key_ref( other.d->key ); + if ( d->key ) + gpgme_key_unref( d->key ); + *d = *other.d; + return *this; + } + + bool UserID::Signature::isNull() const { + return !d || !d->key || !d->uid || !d->sig; + } + + UserID UserID::Signature::parent() const { + return UserID( d->key, d->uid ); + } + + const char * UserID::Signature::signerKeyID() const { + return d->sig ? d->sig->keyid : 0 ; + } + + const char * UserID::Signature::algorithmAsString() const { + return gpgme_pubkey_algo_name( d->sig ? d->sig->pubkey_algo : (gpgme_pubkey_algo_t)0 ); + } + + unsigned int UserID::Signature::algorithm() const { + return d->sig ? d->sig->pubkey_algo : 0 ; + } + + time_t UserID::Signature::creationTime() const { + return static_cast<time_t>( d->sig ? d->sig->timestamp : 0 ); + } + + time_t UserID::Signature::expirationTime() const { + return static_cast<time_t>( d->sig ? d->sig->expires : 0 ); + } + + bool UserID::Signature::neverExpires() const { + return expirationTime() == time_t(0); + } + + bool UserID::Signature::isRevokation() const { + return d->sig && d->sig->revoked; + } + + bool UserID::Signature::isInvalid() const { + return d->sig && d->sig->invalid; + } + + bool UserID::Signature::isExpired() const { + return d->sig && d->sig->expired; + } + + bool UserID::Signature::isExportable() const { + return d->sig && d->sig->exportable; + } + + const char * UserID::Signature::signerUserID() const { + return d->sig ? d->sig->uid : 0 ; + } + + const char * UserID::Signature::signerName() const { + return d->sig ? d->sig->name : 0 ; + } + + const char * UserID::Signature::signerEmail() const { + return d->sig ? d->sig->email : 0 ; + } + + const char * UserID::Signature::signerComment() const { + return d->sig ? d->sig->comment : 0 ; + } + + unsigned int UserID::Signature::certClass() const { + return d->sig ? d->sig->sig_class : 0 ; + } + + UserID::Signature::tqStatus UserID::Signature::status() const { + if ( !d->sig ) + return GeneralError; + + switch ( gpgme_err_code(d->sig->status) ) { + case GPG_ERR_NO_ERROR: return NoError; + case GPG_ERR_SIG_EXPIRED: return SigExpired; + case GPG_ERR_KEY_EXPIRED: return KeyExpired; + case GPG_ERR_BAD_SIGNATURE: return BadSignature; + case GPG_ERR_NO_PUBKEY: return NoPublicKey; + default: + case GPG_ERR_GENERAL: return GeneralError; + } + } + + const char * UserID::Signature::statusAsString() const { + return d->sig ? gpgme_strerror( d->sig->status ) : 0 ; + } + + UserID::Signature::Notation UserID::Signature::notation( unsigned int idx ) const { + return Notation( d->key, d->uid, d->sig, idx ); + } + + unsigned int UserID::Signature::numNotations() const { + if ( !d->sig ) + return 0; + unsigned int count = 0; +#ifdef HAVE_GPGME_KEY_SIG_NOTATIONS + for ( gpgme_sig_notation_t nota = d->sig->notations ; nota ; nota = nota->next ) + if ( nota->name ) ++count; // others are policy URLs... +#endif + return count; + } + + vector<UserID::Signature::Notation> UserID::Signature::notations() const { + if ( !d->sig ) + return vector<Notation>(); + vector<Notation> v; +#ifdef HAVE_GPGME_KEY_SIG_NOTATIONS + v.reserve( numNotations() ); + for ( gpgme_sig_notation_t nota = d->sig->notations ; nota ; nota = nota->next ) + if ( nota->name ) + v.push_back( Notation( d->key, d->uid, d->sig, nota ) ); +#endif + return v; + } + + const char * UserID::Signature::policyURL() const { +#ifdef HAVE_GPGME_KEY_SIG_NOTATIONS + if ( !d->sig ) + return 0; + for ( gpgme_sig_notation_t nota = d->sig->notations ; nota ; nota = nota->next ) + if ( !nota->name ) + return nota->value; +#endif + return 0; + } + + + + // + // + // class Notation + // + // + + struct UserID::Signature::Notation::Private { + Private( gpgme_key_t aKey, gpgme_user_id_t aUid, + gpgme_key_sig_t aSig, unsigned int idx ) + : key( aKey ), uid( 0 ), sig( 0 ), nota( 0 ) + { + if ( key ) + for ( gpgme_user_id_t u = key->uids ; u ; u = u->next ) + if ( u == aUid ) { + uid = u; + for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next ) + if ( s == aSig ) { + sig = s; +#ifdef HAVE_GPGME_KEY_SIG_NOTATIONS + for ( gpgme_sig_notation_t n = sig->notations ; n ; n = n->next, --idx ) + if ( n == aNota ) { + nota = n; + break; + } +#else + (void)idx; +#endif + break; + } + break; + } + if ( !uid || !sig || !nota ) { + uid = 0; + sig = 0; + key = 0; + nota = 0; + } + } + + Private( gpgme_key_t aKey, gpgme_user_id_t aUid, + gpgme_key_sig_t aSig, gpgme_sig_notation_t aNota ) + : key( aKey ), uid( 0 ), sig( 0 ), nota( 0 ) + { + if ( key ) + for ( gpgme_user_id_t u = key->uids ; u ; u = u->next ) + if ( u == aUid ) { + uid = u; + for ( gpgme_key_sig_t s = uid->signatures ; s ; s = s->next ) + if ( s == aSig ) { + sig = s; +#ifdef HAVE_GPGME_KEY_SIG_NOTATIONS + for ( gpgme_sig_notation_t n = sig->notations ; n ; n = n->next ) + if ( n == aNota ) { + nota = n; + break; + } +#else + (void)aNota; +#endif + break; + } + break; + } + if ( !uid || !sig || !nota ) { + uid = 0; + sig = 0; + key = 0; + nota = 0; + } + } + + gpgme_key_t key; + gpgme_user_id_t uid; + gpgme_key_sig_t sig; + gpgme_sig_notation_t nota; + }; + + UserID::Signature::Notation::Notation( gpgme_key_t key, gpgme_user_id_t uid, + gpgme_key_sig_t sig, unsigned int idx ) { + d = new Private( key, uid, sig, idx ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::Signature::Notation::Notation( gpgme_key_t key, gpgme_user_id_t uid, + gpgme_key_sig_t sig, gpgme_sig_notation_t nota ) { + d = new Private( key, uid, sig, nota ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::Signature::Notation::Notation( const Notation & other ) { + d = new Private( other.d->key, other.d->uid, other.d->sig, other.d->nota ); + if ( d->key ) + gpgme_key_ref( d->key ); + } + + UserID::Signature::Notation::~Notation() { + if ( d->key ) + gpgme_key_unref( d->key ); + delete d; d = 0; + } + + const UserID::Signature::Notation & UserID::Signature::Notation::operator=( const Notation & other ) { + if ( &other == this ) return *this; + + if ( other.d->key ) + gpgme_key_ref( other.d->key ); + if ( d->key ) + gpgme_key_unref( d->key ); + *d = *other.d; + return *this; + } + + bool UserID::Signature::Notation::isNull() const { + return !d || !d->key || !d->uid || !d->sig || !d->nota; + } + + UserID::Signature UserID::Signature::Notation::parent() const { + return Signature( d->key, d->uid, d->sig ); + } + + const char * UserID::Signature::Notation::name() const { + return d->nota ? d->nota->name : 0 ; + } + + const char * UserID::Signature::Notation::value() const { + return d->nota ? d->nota->value : 0 ; + } + +} // namespace GpgME diff --git a/libtdenetwork/gpgmepp/key.h b/libtdenetwork/gpgmepp/key.h new file mode 100644 index 00000000..15d09371 --- /dev/null +++ b/libtdenetwork/gpgmepp/key.h @@ -0,0 +1,285 @@ +/* key.h - wraps a gpgme key + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +// -*- c++ -*- +#ifndef __GPGMEPP_KEY_H__ +#define __GPGMEPP_KEY_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/context.h> + +#include <sys/time.h> + +#include <vector> +#include <tdepimmacros.h> + +namespace GpgME { + + class Subkey; + class UserID; + + // + // class Key + // + + class KDE_EXPORT Key { + friend class Context; + public: + Key(); + Key( gpgme_key_t key, bool acquireRef, unsigned int keyListMode=0 ); + Key( const Key & key ); + ~Key(); + + static Key null; + + const Key & operator=( const Key & other ); + + bool isNull() const; + + UserID userID( unsigned int index ) const; + Subkey subkey( unsigned int index ) const; + + unsigned int numUserIDs() const; + unsigned int numSubkeys() const; + + std::vector<UserID> userIDs() const; + std::vector<Subkey> subkeys() const; + + bool isRevoked() const; + bool isExpired() const; + bool isDisabled() const; + bool isInvalid() const; + + bool canEncrypt() const; + bool canSign() const; + bool canCertify() const; + bool canAuthenticate() const; + + bool hasSecret() const; + bool isSecret() const { return hasSecret(); } + + /*! + @return true if this is a X.509 root certificate (currently + equivalent to something like + strcmp( chainID(), subkey(0).fingerprint() ) == 0 ) + */ + bool isRoot() const; + + enum OwnerTrust { Unknown=0, Undefined=1, Never=2, + Marginal=3, Full=4, Ultimate=5 }; + + OwnerTrust ownerTrust() const; + char ownerTrustAsString() const; + + typedef Context::Protocol Protocol; + Protocol protocol() const; + const char * protocolAsString() const; + + const char * issuerSerial() const; + const char * issuerName() const; + const char * chainID() const; + + const char * keyID() const; + const char * shortKeyID() const; + const char * primaryFingerprint() const; + + typedef Context::KeyListMode KeyListMode; + unsigned int keyListMode() const; + + private: + gpgme_key_t impl() const; + class Private; + Private * d; + }; + + // + // class Subkey + // + + class KDE_EXPORT Subkey { + public: + Subkey( gpgme_key_t key=0, gpgme_sub_key_t subkey=0 ); + Subkey( gpgme_key_t key, unsigned int idx ); + Subkey( const Subkey & other ); + ~Subkey(); + + const Subkey & operator=( const Subkey & other ); + + bool isNull() const; + + Key parent() const; + + const char * keyID() const; + const char * fingerprint() const; + + time_t creationTime() const; + time_t expirationTime() const; + bool neverExpires() const; + + bool isRevoked() const; + bool isExpired() const; + bool isInvalid() const; + bool isDisabled() const; + + bool canEncrypt() const; + bool canSign() const; + bool canCertify() const; + bool canAuthenticate() const; + + bool isSecret() const; + + unsigned int publicKeyAlgorithm() const; + const char * publicKeyAlgorithmAsString() const; + + unsigned int length() const; + + private: + class Private; + Private * d; + }; + + // + // class UserID + // + + class KDE_EXPORT UserID { + public: + class Signature; + + UserID( gpgme_key_t key=0, gpgme_user_id_t uid=0 ); + UserID( gpgme_key_t key, unsigned int idx ); + UserID( const UserID & other ); + ~UserID(); + + const UserID & operator=( const UserID & other ); + + bool isNull() const; + + Key parent() const; + + unsigned int numSignatures() const; + Signature signature( unsigned int index ) const; + std::vector<Signature> signatures() const; + + const char * id() const; + const char * name() const; + const char * email() const; + const char * comment() const; + + enum Validity { Unknown=0, Undefined=1, Never=2, + Marginal=3, Full=4, Ultimate=5 }; + + Validity validity() const; + char validityAsString() const; + + bool isRevoked() const; + bool isInvalid() const; + + private: + class Private; + Private * d; + }; + + // + // class UserID::Signature + // + + class KDE_EXPORT UserID::Signature { + public: + class Notation; + + Signature( gpgme_key_t key=0, gpgme_user_id_t uid=0, gpgme_key_sig_t sig=0 ); + Signature( gpgme_key_t key, gpgme_user_id_t uid, unsigned int idx ); + Signature( const Signature & other ); + ~Signature(); + + const Signature & operator=( const Signature & other ); + + bool isNull() const; + + UserID parent() const; + + const char * signerKeyID() const; + + const char * algorithmAsString() const; + unsigned int algorithm() const; + time_t creationTime() const; + time_t expirationTime() const; + bool neverExpires() const; + + bool isRevokation() const; + bool isInvalid() const; + bool isExpired() const; + bool isExportable() const; + + const char * signerUserID() const; + const char * signerName() const; + const char * signerEmail() const; + const char * signerComment() const; + + unsigned int certClass() const; + + enum tqStatus { NoError = 0, SigExpired, KeyExpired, + BadSignature, NoPublicKey, GeneralError }; + tqStatus status() const; + const char * statusAsString() const; + + const char * policyURL() const; + + unsigned int numNotations() const; + Notation notation( unsigned int idx ) const; + std::vector<Notation> notations() const; + + private: + class Private; + Private * d; + }; + + // + // + // class UserID::Signature::Notation + // + // + + class KDE_EXPORT UserID::Signature::Notation { + public: + Notation( gpgme_key_t key=0, gpgme_user_id_t uid=0, + gpgme_key_sig_t sig=0, gpgme_sig_notation_t nota=0 ); + Notation( gpgme_key_t key, gpgme_user_id_t uid, + gpgme_key_sig_t sig, unsigned int idx ); + Notation( const Notation & other ); + ~Notation(); + + const Notation & operator=( const Notation & other ); + + bool isNull() const; + + Signature parent() const; + + const char * name() const; + const char * value() const; + + private: + class Private; + Private * d; + }; + +} // namespace GpgME + +#endif // __GPGMEPP_KEY_H__ diff --git a/libtdenetwork/gpgmepp/keygenerationresult.cpp b/libtdenetwork/gpgmepp/keygenerationresult.cpp new file mode 100644 index 00000000..76045ee2 --- /dev/null +++ b/libtdenetwork/gpgmepp/keygenerationresult.cpp @@ -0,0 +1,73 @@ +/* keygenerationresult.cpp - wraps a gpgme keygen result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/keygenerationresult.h> +#include "shared.h" +#include "result_p.h" + +#include <gpgme.h> + +#include <cstring> +#include <cstdlib> + +class GpgME::KeyGenerationResult::Private : public GpgME::Shared { +public: + Private( const _gpgme_op_genkey_result & r ) : Shared(), res( r ) { + if ( res.fpr ) + res.fpr = strdup( res.fpr ); + } + ~Private() { + if ( res.fpr ) + std::free( res.fpr ); + res.fpr = 0; + } + + _gpgme_op_genkey_result res; +}; + +GpgME::KeyGenerationResult::KeyGenerationResult( gpgme_ctx_t ctx, int error ) + : GpgME::Result( error ), d( 0 ) +{ + if ( error || !ctx ) + return; + gpgme_genkey_result_t res = gpgme_op_genkey_result( ctx ); + if ( !res ) + return; + d = new Private( *res ); + d->ref(); +} + +make_standard_stuff(KeyGenerationResult) + +bool GpgME::KeyGenerationResult::primaryKeyGenerated() const { + return d && d->res.primary; +} + +bool GpgME::KeyGenerationResult::subkeyGenerated() const { + return d && d->res.sub; +} + +const char * GpgME::KeyGenerationResult::fingerprint() const { + return d ? d->res.fpr : 0 ; +} diff --git a/libtdenetwork/gpgmepp/keygenerationresult.h b/libtdenetwork/gpgmepp/keygenerationresult.h new file mode 100644 index 00000000..7b2d98e8 --- /dev/null +++ b/libtdenetwork/gpgmepp/keygenerationresult.h @@ -0,0 +1,53 @@ +/* keygenerationresult.h - wraps a gpgme keygen result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_KEYGENERATIONRESULT_H__ +#define __GPGMEPP_KEYGENERATIONRESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/result.h> +#include <tdepimmacros.h> +namespace GpgME { + + class Error; + + class KDE_EXPORT KeyGenerationResult : public Result { + public: + KeyGenerationResult( gpgme_ctx_t ctx=0, int error=0 ); + explicit KeyGenerationResult( const Error & err ); + KeyGenerationResult( const KeyGenerationResult & other ); + ~KeyGenerationResult(); + + const KeyGenerationResult & operator=( const KeyGenerationResult & other ); + + bool isNull() const; + + bool primaryKeyGenerated() const; + bool subkeyGenerated() const; + const char * fingerprint() const; + + private: + class Private; + Private * d; + }; + +} + +#endif // __GPGMEPP_KEYGENERATIONRESULT_H__ diff --git a/libtdenetwork/gpgmepp/keylistresult.cpp b/libtdenetwork/gpgmepp/keylistresult.cpp new file mode 100644 index 00000000..17dc3a46 --- /dev/null +++ b/libtdenetwork/gpgmepp/keylistresult.cpp @@ -0,0 +1,92 @@ +/* keylistresult.cpp - wraps a gpgme keylist result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/keylistresult.h> +#include "shared.h" +#include "result_p.h" + +#include <gpgme.h> + +#include <cstring> +#include <cassert> + +class GpgME::KeyListResult::Private : public GpgME::Shared { +public: + Private( const _gpgme_op_keylist_result & r ) : Shared(), res( r ) {} + Private( const Private & other ) : Shared(), res( other.res ) {} + + _gpgme_op_keylist_result res; +}; + +GpgME::KeyListResult::KeyListResult( gpgme_ctx_t ctx, int error ) + : GpgME::Result( error ), d( 0 ) +{ + if ( error || !ctx ) + return; + gpgme_keylist_result_t res = gpgme_op_keylist_result( ctx ); + if ( !res ) + return; + d = new Private( *res ); + d->ref(); +} + +GpgME::KeyListResult::KeyListResult( const Error & error, const _gpgme_op_keylist_result & res ) + : GpgME::Result( error ), d( 0 ) +{ + d = new Private( res ); + d->ref(); +} + +make_standard_stuff(KeyListResult) + +void GpgME::KeyListResult::detach() { + if ( !d || d->refCount() <= 1 ) + return; + d->unref(); + d = new Private( *d ); +} + +void GpgME::KeyListResult::mergeWith( const KeyListResult & other ) { + if ( other.isNull() ) + return; + if ( isNull() ) { // just assign + operator=( other ); + return; + } + // merge the truncated flag (try to keep detaching to a minimum): + if ( other.isTruncated() && !this->isTruncated() ) { + assert( other.d ); + detach(); + if ( !d ) + d = new Private( *other.d ); + else + d->res.truncated = true; + } + if ( !error() ) // only merge the error when there was none yet. + Result::operator=( other ); +} + +bool GpgME::KeyListResult::isTruncated() const { + return d && d->res.truncated; +} diff --git a/libtdenetwork/gpgmepp/keylistresult.h b/libtdenetwork/gpgmepp/keylistresult.h new file mode 100644 index 00000000..068210c0 --- /dev/null +++ b/libtdenetwork/gpgmepp/keylistresult.h @@ -0,0 +1,62 @@ +/* keylistresult.h - wraps a gpgme keylist result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_KEYLISTRESULT_H__ +#define __GPGMEPP_KEYLISTRESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/result.h> +#include <tdepimmacros.h> + +namespace GpgME { + + class Context; + class Error; + + class KDE_EXPORT KeyListResult : public Result { + public: + KeyListResult( gpgme_ctx_t ctx=0, int error=0 ); + explicit KeyListResult( const Error & err ); + KeyListResult( const Error & err, const _gpgme_op_keylist_result & res ); + KeyListResult( const KeyListResult & other ); + ~KeyListResult(); + + const KeyListResult & operator=( const KeyListResult & other ); + + const KeyListResult & operator+=( const KeyListResult & other ) { + mergeWith( other ); + return *this; + } + + void mergeWith( const KeyListResult & other ); + + bool isNull() const; + + bool isTruncated() const; + + private: + void detach(); + class Private; + Private * d; + }; + +} + +#endif // __GPGMEPP_KEYLISTRESULT_H__ diff --git a/libtdenetwork/gpgmepp/result.h b/libtdenetwork/gpgmepp/result.h new file mode 100644 index 00000000..aa91cf98 --- /dev/null +++ b/libtdenetwork/gpgmepp/result.h @@ -0,0 +1,47 @@ +/* result.h - base class for results + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_RESULT_H__ +#define __GPGMEPP_RESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/context.h> + +namespace GpgME { + + class Result { + public: + Result( int error=0 ) : mError( error ) {} + Result( const Result & other ) : mError( other.error() ) {} + + const Result & operator=( const Result & other ) { + mError = other.mError; + return *this; + } + + const Error & error() const { return mError; } + + private: + Error mError; + }; + +} + +#endif // __GPGMEPP_RESULT_H__ diff --git a/libtdenetwork/gpgmepp/result_p.h b/libtdenetwork/gpgmepp/result_p.h new file mode 100644 index 00000000..cc1d2793 --- /dev/null +++ b/libtdenetwork/gpgmepp/result_p.h @@ -0,0 +1,69 @@ +/* result.h - base class for results + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_RESULT_P_H__ +#define __GPGMEPP_RESULT_P_H__ + +#define make_copy_ctor(x) \ +GpgME::x::x( const x & other ) \ + : GpgME::Result( other ), d( other.d ) \ +{ \ + if ( d ) \ + d->ref(); \ +} + +#define make_error_ctor(x) \ +GpgME::x::x( const Error & error ) \ + : GpgME::Result( error ), d( 0 ) \ +{ \ + \ +} + +#define make_assignment_operator(x) \ +const GpgME::x & GpgME::x::operator=( const x & other ) { \ + if ( other.d ) \ + other.d->ref(); \ + if ( this->d ) \ + this->d->unref(); \ + this->d = other.d; \ + \ + Result::operator=( other ); \ + \ + return *this; \ +} + +#define make_dtor(x) \ +GpgME::x::~x() { \ + if ( d ) \ + d->unref(); \ + d = 0; \ +} + +#define make_isNull(x) bool GpgME::x::isNull() const { return !d && !error(); } + +#define make_standard_stuff(x) \ +make_copy_ctor(x) \ +make_error_ctor(x) \ +make_assignment_operator(x) \ +make_isNull(x) \ +make_dtor(x) + + +#endif // __GPGMEPP_RESULT_P_H__ diff --git a/libtdenetwork/gpgmepp/shared.h b/libtdenetwork/gpgmepp/shared.h new file mode 100644 index 00000000..f9c79e0c --- /dev/null +++ b/libtdenetwork/gpgmepp/shared.h @@ -0,0 +1,54 @@ +/* shared.h - internal tool for refcounting -*- c++ -*- + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_SHARED_H__ +#define __GPGMEPP_SHARED_H__ + +#include <cassert> + +namespace GpgME { + + class Shared { + protected: + Shared() : mRefCount( 0 ) {} + virtual ~Shared() { + assert( mRefCount <= 0 ); + } + + public: + int ref() { return ++mRefCount; } + int deref() { return unref(); } + int unref() { + if ( --mRefCount <= 0 ) { + delete this; + return 0; + } + return mRefCount; + } + int refCount() { return mRefCount; } + + private: + int mRefCount; + }; + +} + + +#endif // __GPGMEPP_SHARED_H__ diff --git a/libtdenetwork/gpgmepp/signingresult.cpp b/libtdenetwork/gpgmepp/signingresult.cpp new file mode 100644 index 00000000..6996eef7 --- /dev/null +++ b/libtdenetwork/gpgmepp/signingresult.cpp @@ -0,0 +1,283 @@ +/* signingresult.cpp - wraps a gpgme verify result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/signingresult.h> +#include "shared.h" +#include "result_p.h" +#include "util.h" + +#include <gpgme.h> + +#include <cstring> +#include <cstdlib> +#include <algorithm> +#include <istream> +#include <iterator> + +class GpgME::SigningResult::Private : public GpgME::Shared { +public: + Private( const gpgme_sign_result_t r ) : Shared() { + if ( !r ) + return; + for ( gpgme_new_signature_t is = r->signatures ; is ; is = is->next ) { + gpgme_new_signature_t copy = new _gpgme_new_signature( *is ); + if ( is->fpr ) + copy->fpr = strdup( is->fpr ); + copy->next = 0; + created.push_back( copy ); + } + for ( gpgme_invalid_key_t ik = r->invalid_signers ; ik ; ik = ik->next ) { + gpgme_invalid_key_t copy = new _gpgme_invalid_key( *ik ); + if ( ik->fpr ) + copy->fpr = strdup( ik->fpr ); + copy->next = 0; + invalid.push_back( copy ); + } + } + ~Private() { + for ( std::vector<gpgme_new_signature_t>::iterator it = created.begin() ; it != created.end() ; ++it ) { + std::free( (*it)->fpr ); + delete *it; *it = 0; + } + for ( std::vector<gpgme_invalid_key_t>::iterator it = invalid.begin() ; it != invalid.end() ; ++it ) { + std::free( (*it)->fpr ); + delete *it; *it = 0; + } + } + + std::vector<gpgme_new_signature_t> created; + std::vector<gpgme_invalid_key_t> invalid; +}; + +GpgME::SigningResult::SigningResult( gpgme_ctx_t ctx, int error ) + : GpgME::Result( error ), d( 0 ) +{ + if ( error || !ctx ) + return; + gpgme_sign_result_t res = gpgme_op_sign_result( ctx ); + if ( !res ) + return; + d = new Private( res ); + d->ref(); +} + +make_standard_stuff(SigningResult) + +GpgME::CreatedSignature GpgME::SigningResult::createdSignature( unsigned int idx ) const { + return CreatedSignature( d, idx ); +} + +std::vector<GpgME::CreatedSignature> GpgME::SigningResult::createdSignatures() const { + if ( !d ) + return std::vector<CreatedSignature>(); + std::vector<CreatedSignature> result; + result.reserve( d->created.size() ); + for ( unsigned int i = 0 ; i < d->created.size() ; ++i ) + result.push_back( CreatedSignature( d, i ) ); + return result; +} + + +GpgME::InvalidSigningKey GpgME::SigningResult::invalidSigningKey( unsigned int idx ) const { + return InvalidSigningKey( d, idx ); +} + +std::vector<GpgME::InvalidSigningKey> GpgME::SigningResult::invalidSigningKeys() const { + if ( !d ) + return std::vector<GpgME::InvalidSigningKey>(); + std::vector<GpgME::InvalidSigningKey> result; + result.reserve( d->invalid.size() ); + for ( unsigned int i = 0 ; i < d->invalid.size() ; ++i ) + result.push_back( InvalidSigningKey( d, i ) ); + return result; +} + + + + +GpgME::InvalidSigningKey::InvalidSigningKey( SigningResult::Private * parent, unsigned int i ) + : d( parent ), idx( i ) +{ + if ( d ) + d->ref(); +} + +GpgME::InvalidSigningKey::InvalidSigningKey() : d( 0 ), idx( 0 ) {} + +GpgME::InvalidSigningKey::InvalidSigningKey( const InvalidSigningKey & other ) + : d( other.d ), idx( other.idx ) +{ + if ( d ) + d->ref(); +} + +GpgME::InvalidSigningKey::~InvalidSigningKey() { + if ( d ) + d->unref(); +} + +const GpgME::InvalidSigningKey & GpgME::InvalidSigningKey::operator=( const InvalidSigningKey & other ) { + if ( this->d != other.d ) { + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->unref(); + this->d = other.d; + } + + this->idx = other.idx; + return *this; +} + + +bool GpgME::InvalidSigningKey::isNull() const { + return !d || idx >= d->invalid.size() ; +} + +const char * GpgME::InvalidSigningKey::fingerprint() const { + return isNull() ? 0 : d->invalid[idx]->fpr ; +} + +GpgME::Error GpgME::InvalidSigningKey::reason() const { + return isNull() ? 0 : d->invalid[idx]->reason ; +} + + + +GpgME::CreatedSignature::CreatedSignature( SigningResult::Private * parent, unsigned int i ) + : d( parent ), idx( i ) +{ + if ( d ) + d->ref(); +} + +GpgME::CreatedSignature::CreatedSignature() : d( 0 ), idx( 0 ) {} + +GpgME::CreatedSignature::CreatedSignature( const CreatedSignature & other ) + : d( other.d ), idx( other.idx ) +{ + if ( d ) + d->ref(); +} + +GpgME::CreatedSignature::~CreatedSignature() { + if ( d ) + d->unref(); +} + +const GpgME::CreatedSignature & GpgME::CreatedSignature::operator=( const CreatedSignature & other ) { + if ( this->d != other.d ) { + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->unref(); + this->d = other.d; + } + + this->idx = other.idx; + return *this; +} + + +bool GpgME::CreatedSignature::isNull() const { + return !d || idx >= d->created.size() ; +} + +const char * GpgME::CreatedSignature::fingerprint() const { + return isNull() ? 0 : d->created[idx]->fpr ; +} + +time_t GpgME::CreatedSignature::creationTime() const { + return static_cast<time_t>( isNull() ? 0 : d->created[idx]->timestamp ); +} + +GpgME::Context::SignatureMode GpgME::CreatedSignature::mode() const { + if ( isNull() ) + return Context::Normal; + switch ( d->created[idx]->type ) { + default: + case GPGME_SIG_MODE_NORMAL: return Context::Normal; + case GPGME_SIG_MODE_DETACH: return Context::Detached; + case GPGME_SIG_MODE_CLEAR: return Context::Clearsigned; + } +} + +unsigned int GpgME::CreatedSignature::publicKeyAlgorithm() const { + return isNull() ? 0 : d->created[idx]->pubkey_algo ; +} + +const char * GpgME::CreatedSignature::publicKeyAlgorithmAsString() const { + return gpgme_pubkey_algo_name( isNull() ? (gpgme_pubkey_algo_t)0 : d->created[idx]->pubkey_algo ); +} + +unsigned int GpgME::CreatedSignature::hashAlgorithm() const { + return isNull() ? 0 : d->created[idx]->hash_algo ; +} + +const char * GpgME::CreatedSignature::hashAlgorithmAsString() const { + return gpgme_hash_algo_name( isNull() ? (gpgme_hash_algo_t)0 : d->created[idx]->hash_algo ); +} + +unsigned int GpgME::CreatedSignature::signatureClass() const { + return isNull() ? 0 : d->created[idx]->sig_class ; +} + + +std::ostream & GpgME::operator<<( std::ostream & os, const SigningResult & result ) { + os << "GpgME::SigningResult("; + if ( !result.isNull() ) { + os << "\n error: " << result.error() + << "\n createdSignatures:\n"; + const std::vector<CreatedSignature> cs = result.createdSignatures(); + std::copy( cs.begin(), cs.end(), + std::ostream_iterator<CreatedSignature>( os, "\n" ) ); + os << " invalidSigningKeys:\n"; + const std::vector<InvalidSigningKey> isk = result.invalidSigningKeys(); + std::copy( isk.begin(), isk.end(), + std::ostream_iterator<InvalidSigningKey>( os, "\n" ) ); + } + return os << ')'; +} + +std::ostream & GpgME::operator<<( std::ostream & os, const CreatedSignature & sig ) { + os << "GpgME::CreatedSignature("; + if ( !sig.isNull() ) + os << "\n fingerprint: " << protect( sig.fingerprint() ) + << "\n creationTime: " << sig.creationTime() + << "\n mode: " << sig.mode() + << "\n publicKeyAlgorithm: " << protect( sig.publicKeyAlgorithmAsString() ) + << "\n hashAlgorithm: " << protect( sig.hashAlgorithmAsString() ) + << "\n signatureClass: " << sig.signatureClass() + << '\n'; + return os << ')'; +} + +std::ostream & GpgME::operator<<( std::ostream & os, const InvalidSigningKey & key ) { + os << "GpgME::InvalidSigningKey("; + if ( !key.isNull() ) + os << "\n fingerprint: " << protect( key.fingerprint() ) + << "\n reason: " << key.reason() + << '\n'; + return os << ')'; +} diff --git a/libtdenetwork/gpgmepp/signingresult.h b/libtdenetwork/gpgmepp/signingresult.h new file mode 100644 index 00000000..1ee7a8de --- /dev/null +++ b/libtdenetwork/gpgmepp/signingresult.h @@ -0,0 +1,124 @@ +/* signingresult.h - wraps a gpgme sign result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_SIGNINGRESULT_H__ +#define __GPGMEPP_SIGNINGRESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/result.h> +#include <gpgmepp/context.h> + +#include <time.h> + +#include <vector> +#include <iosfwd> + +#include <tdepimmacros.h> + +namespace GpgME { + + class Error; + class CreatedSignature; + class InvalidSigningKey; + + class KDE_EXPORT SigningResult : public Result { + public: + SigningResult( gpgme_ctx_t ctx=0, int error=0 ); + explicit SigningResult( const Error & err ); + SigningResult( const SigningResult & other ); + ~SigningResult(); + + const SigningResult & operator=( const SigningResult & other ); + + bool isNull() const; + + CreatedSignature createdSignature( unsigned int index ) const; + std::vector<CreatedSignature> createdSignatures() const; + + InvalidSigningKey invalidSigningKey( unsigned int index ) const; + std::vector<InvalidSigningKey> invalidSigningKeys() const; + + class Private; + private: + Private * d; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const SigningResult & result ); + + class KDE_EXPORT InvalidSigningKey { + friend class SigningResult; + InvalidSigningKey( SigningResult::Private * parent, unsigned int index ); + public: + InvalidSigningKey(); + InvalidSigningKey( const InvalidSigningKey & other ); + ~InvalidSigningKey(); + + const InvalidSigningKey & operator=( const InvalidSigningKey & other ); + + bool isNull() const; + + const char * fingerprint() const; + Error reason() const; + + private: + SigningResult::Private * d; + unsigned int idx; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const InvalidSigningKey & key ); + + class KDE_EXPORT CreatedSignature { + friend class SigningResult; + CreatedSignature( SigningResult::Private * parent, unsigned int index ); + public: + class Notation; + + CreatedSignature(); + CreatedSignature( const CreatedSignature & other ); + ~CreatedSignature(); + + const CreatedSignature & operator=( const CreatedSignature & other ); + + bool isNull() const; + + const char * fingerprint() const; + + time_t creationTime() const; + + Context::SignatureMode mode() const; + + unsigned int publicKeyAlgorithm() const; + const char * publicKeyAlgorithmAsString() const; + + unsigned int hashAlgorithm() const; + const char * hashAlgorithmAsString() const; + + unsigned int signatureClass() const; + + private: + SigningResult::Private * d; + unsigned int idx; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const CreatedSignature & sig ); + +} + +#endif // __GPGMEPP_SIGNINGRESULT_H__ diff --git a/libtdenetwork/gpgmepp/trustitem.cpp b/libtdenetwork/gpgmepp/trustitem.cpp new file mode 100644 index 00000000..59840ebb --- /dev/null +++ b/libtdenetwork/gpgmepp/trustitem.cpp @@ -0,0 +1,109 @@ +/* trustitem.cpp - wraps a gpgme trust item + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/trustitem.h> + +#include <gpgme.h> + +#include <cassert> + +namespace GpgME { + + struct TrustItem::Private { + Private( gpgme_trust_item_t aItem ) + : item( aItem ) + { + } + + gpgme_trust_item_t item; + }; + + TrustItem::TrustItem( gpgme_trust_item_t item ) { + d = new Private( item ); + if ( d->item ) + gpgme_trust_item_ref( d->item ); + } + + TrustItem::TrustItem( const TrustItem & other ) { + d = new Private( other.d->item ); + if ( d->item ) + gpgme_trust_item_ref( d->item ); + } + + const TrustItem & TrustItem::operator=( const TrustItem & other ) { + if ( &other == this ) return *this; + + if ( other.d->item ) + gpgme_trust_item_ref( other.d->item ); + if ( d->item ) + gpgme_trust_item_unref( d->item ); + *d = *other.d; + return *this; + } + + TrustItem::~TrustItem() { + if ( d->item ) + gpgme_trust_item_unref( d->item ); + delete d; d = 0; + } + + bool TrustItem::isNull() const { + return !d || !d->item; + } + + gpgme_trust_item_t TrustItem::impl() const { + return d->item; + } + + + const char * TrustItem::keyID() const { + return d->item ? d->item->keyid : 0 ; + } + + const char * TrustItem::userID() const { + return d->item ? d->item->name : 0 ; + } + + const char * TrustItem::ownerTrustAsString() const { + return d->item ? d->item->owner_trust : 0 ; + } + + const char * TrustItem::validityAsString() const { + return d->item ? d->item->validity : 0 ; + } + + int TrustItem::trustLevel() const { + return d->item ? d->item->level : 0 ; + } + + TrustItem::Type TrustItem::type() const { + if ( !d->item ) + return Unknown; + else + return + d->item->type == 1 ? Key : + d->item->type == 2 ? UserID : + Unknown ; + } + +} // namespace GpgME diff --git a/libtdenetwork/gpgmepp/trustitem.h b/libtdenetwork/gpgmepp/trustitem.h new file mode 100644 index 00000000..61c74617 --- /dev/null +++ b/libtdenetwork/gpgmepp/trustitem.h @@ -0,0 +1,61 @@ +/* trustitem.h - wraps a gpgme trust item + Copyright (C) 2003 Klarälvdalens Datakonsult AB + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +// -*- c++ -*- +#ifndef __GPGMEPP_TRUSTITEM_H__ +#define __GPGMEPP_TRUSTITEM_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/key.h> + +namespace GpgME { + + class Context; + + class TrustItem { + friend class Context; + public: + TrustItem( gpgme_trust_item_t item=0 ); + TrustItem( const TrustItem & other ); + virtual ~TrustItem(); + + const TrustItem & operator=( const TrustItem & other ); + + bool isNull() const; + + const char * keyID() const; + const char * userID() const; + + const char * ownerTrustAsString() const; + const char * validityAsString() const; + + int trustLevel() const; + + enum Type { Unknown=0, Key=1, UserID=2 }; + Type type() const; + + private: + gpgme_trust_item_t impl() const; + class Private; + Private * d; + }; + +} // namepace GpgME + +#endif // __GPGMEPP_TRUSTITEM_H__ diff --git a/libtdenetwork/gpgmepp/util.h b/libtdenetwork/gpgmepp/util.h new file mode 100644 index 00000000..8246cfc3 --- /dev/null +++ b/libtdenetwork/gpgmepp/util.h @@ -0,0 +1,75 @@ +/* util.h - some inline helper functions + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +// -*- c++ -*- +#ifndef __GPGMEPP_UTIL_H__ +#define __GPGMEPP_UTIL_H__ + +#include <gpgme.h> +#include <context.h> + +#ifndef NDEBUG +#include <iostream> +#endif + +static inline const char * protect( const char * s ) { + return s ? s : "<null>" ; +} + +static inline gpgme_keylist_mode_t add_to_gpgme_keylist_mode_t( unsigned int oldmode, unsigned int newmodes ) { + if ( newmodes & GpgME::Context::Local ) oldmode |= GPGME_KEYLIST_MODE_LOCAL; + if ( newmodes & GpgME::Context::Extern ) oldmode |= GPGME_KEYLIST_MODE_EXTERN; + if ( newmodes & GpgME::Context::Signatures ) oldmode |= GPGME_KEYLIST_MODE_SIGS; + if ( newmodes & GpgME::Context::Validate ) { +#ifdef HAVE_GPGME_KEYLIST_MODE_VALIDATE + oldmode |= GPGME_KEYLIST_MODE_VALIDATE; +#elif !defined(NDEBUG) + std::cerr << "GpgME::Context: ignoring Valdidate keylist flag (gpgme too old)." << std::endl; +#endif + } +#ifndef NDEBUG + if ( newmodes & ~(GpgME::Context::Local|GpgME::Context::Extern|GpgME::Context::Signatures|GpgME::Context::Validate) ) + std::cerr << "GpgME::Context: keylist mode must be one of Local, " + "Extern, Signatures, or Validate, or a combination thereof!" << std::endl; +#endif + return static_cast<gpgme_keylist_mode_t>( oldmode ); +} + +static inline unsigned int convert_from_gpgme_keylist_mode_t( unsigned int mode ) { + unsigned int result = 0; + if ( mode & GPGME_KEYLIST_MODE_LOCAL ) result |= GpgME::Context::Local; + if ( mode & GPGME_KEYLIST_MODE_EXTERN ) result |= GpgME::Context::Extern; + if ( mode & GPGME_KEYLIST_MODE_SIGS ) result |= GpgME::Context::Signatures; +#ifdef HAVE_GPGME_KEYLIST_MODE_VALIDATE + if ( mode & GPGME_KEYLIST_MODE_VALIDATE ) result |= GpgME::Context::Validate; +#endif +#ifndef NDEBUG + if ( mode & ~(GPGME_KEYLIST_MODE_LOCAL| + GPGME_KEYLIST_MODE_EXTERN| +#ifdef HAVE_GPGME_KEYLIST_MODE_VALIDATE + GPGME_KEYLIST_MODE_VALIDATE| +#endif + GPGME_KEYLIST_MODE_SIGS) ) + std::cerr << "GpgME::Context: WARNING: gpgme_get_keylist_mode() returned an unknown flag!" << std::endl; +#endif // NDEBUG + return result; +} + + +#endif // __GPGMEPP_UTIL_H__ diff --git a/libtdenetwork/gpgmepp/verificationresult.cpp b/libtdenetwork/gpgmepp/verificationresult.cpp new file mode 100644 index 00000000..abf30d96 --- /dev/null +++ b/libtdenetwork/gpgmepp/verificationresult.cpp @@ -0,0 +1,357 @@ +/* verificationresult.cpp - wraps a gpgme verify result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpgmepp/verificationresult.h> +#include "shared.h" +#include "result_p.h" +#include "util.h" + +#include <gpgme.h> + +#include <istream> +#include <algorithm> +#include <iterator> +#include <cstring> +#include <cstdlib> + +class GpgME::VerificationResult::Private : public GpgME::Shared { +public: + Private( const gpgme_verify_result_t r ) : Shared() { + if ( !r ) + return; + // copy recursively, using compiler-generated copy ctor. + // We just need to handle the pointers in the structs: + for ( gpgme_signature_t is = r->signatures ; is ; is = is->next ) { + gpgme_signature_t scopy = new _gpgme_signature( *is ); + if ( is->fpr ) + scopy->fpr = strdup( is->fpr ); + scopy->next = 0; + sigs.push_back( scopy ); + // copy notations: + nota.push_back( std::vector<Nota>() ); + purls.push_back( 0 ); + for ( gpgme_sig_notation_t in = is->notations ; in ; in = in->next ) { + if ( !in->name ) { + if ( in->value ) + purls.back() = strdup( in->value ); // policy url + continue; + } + Nota n = { 0, 0 }; + n.name = strdup( in->name ); + if ( in->value ) + n.value = strdup( in->value ); + nota.back().push_back( n ); + } + } + } + ~Private() { + for ( std::vector<gpgme_signature_t>::iterator it = sigs.begin() ; it != sigs.end() ; ++it ) { + std::free( (*it)->fpr ); + delete *it; *it = 0; + } + for ( std::vector< std::vector<Nota> >::iterator it = nota.begin() ; it != nota.end() ; ++it ) + for ( std::vector<Nota>::iterator jt = it->begin() ; jt != it->end() ; ++jt ) { + std::free( jt->name ); jt->name = 0; + std::free( jt->value ); jt->value = 0; + } + std::for_each( purls.begin(), purls.end(), &std::free ); + } + + struct Nota { + char * name; + char * value; + }; + + std::vector<gpgme_signature_t> sigs; + std::vector< std::vector<Nota> > nota; + std::vector<char*> purls; +}; + +GpgME::VerificationResult::VerificationResult( gpgme_ctx_t ctx, int error ) + : GpgME::Result( error ), d( 0 ) +{ + if ( error || !ctx ) + return; + gpgme_verify_result_t res = gpgme_op_verify_result( ctx ); + if ( !res ) + return; + d = new Private( res ); + d->ref(); +} + +make_standard_stuff(VerificationResult) + +GpgME::Signature GpgME::VerificationResult::signature( unsigned int idx ) const { + return Signature( d, idx ); +} + +std::vector<GpgME::Signature> GpgME::VerificationResult::signatures() const { + if ( !d ) + return std::vector<Signature>(); + std::vector<Signature> result; + result.reserve( d->sigs.size() ); + for ( unsigned int i = 0 ; i < d->sigs.size() ; ++i ) + result.push_back( Signature( d, i ) ); + return result; +} + + + + + + +GpgME::Signature::Signature( VerificationResult::Private * parent, unsigned int i ) + : d( parent ), idx( i ) +{ + if ( d ) + d->ref(); +} + +GpgME::Signature::Signature() : d( 0 ), idx( 0 ) {} + +GpgME::Signature::Signature( const Signature & other ) + : d( other.d ), idx( other.idx ) +{ + if ( d ) + d->ref(); +} + +GpgME::Signature::~Signature() { + if ( d ) + d->unref(); +} + +const GpgME::Signature & GpgME::Signature::operator=( const Signature & other ) { + if ( this->d != other.d ) { + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->unref(); + this->d = other.d; + } + + this->idx = other.idx; + return *this; +} + + +bool GpgME::Signature::isNull() const { + return !d || idx >= d->sigs.size() ; +} + + +GpgME::Signature::Summary GpgME::Signature::summary() const { + if ( isNull() ) + return None; + gpgme_sigsum_t sigsum = d->sigs[idx]->summary; + unsigned int result = 0; + if ( sigsum & GPGME_SIGSUM_VALID ) result |= Valid; + if ( sigsum & GPGME_SIGSUM_GREEN ) result |= Green; + if ( sigsum & GPGME_SIGSUM_RED ) result |= Red; + if ( sigsum & GPGME_SIGSUM_KEY_REVOKED ) result |= KeyRevoked; + if ( sigsum & GPGME_SIGSUM_KEY_EXPIRED ) result |= KeyExpired; + if ( sigsum & GPGME_SIGSUM_SIG_EXPIRED ) result |= SigExpired; + if ( sigsum & GPGME_SIGSUM_KEY_MISSING ) result |= KeyMissing; + if ( sigsum & GPGME_SIGSUM_CRL_MISSING ) result |= CrlMissing; + if ( sigsum & GPGME_SIGSUM_CRL_TOO_OLD ) result |= CrlTooOld; + if ( sigsum & GPGME_SIGSUM_BAD_POLICY ) result |= BadPolicy; + if ( sigsum & GPGME_SIGSUM_SYS_ERROR ) result |= SysError; + return static_cast<Summary>( result ); +} + +const char * GpgME::Signature::fingerprint() const { + return isNull() ? 0 : d->sigs[idx]->fpr ; +} + +GpgME::Error GpgME::Signature::status() const { + return isNull() ? 0 : d->sigs[idx]->status ; +} + +time_t GpgME::Signature::creationTime() const { + return static_cast<time_t>( isNull() ? 0 : d->sigs[idx]->timestamp ); +} + +time_t GpgME::Signature::expirationTime() const { + return static_cast<time_t>( isNull() ? 0 : d->sigs[idx]->exp_timestamp ); +} + +bool GpgME::Signature::neverExpires() const { + return expirationTime() == (time_t)0; +} + +bool GpgME::Signature::wrongKeyUsage() const { + return !isNull() && d->sigs[idx]->wrong_key_usage; +} + +GpgME::Signature::Validity GpgME::Signature::validity() const { + if ( isNull() ) + return Unknown; + switch ( d->sigs[idx]->validity ) { + default: + case GPGME_VALIDITY_UNKNOWN: return Unknown; + case GPGME_VALIDITY_UNDEFINED: return Undefined; + case GPGME_VALIDITY_NEVER: return Never; + case GPGME_VALIDITY_MARGINAL: return Marginal; + case GPGME_VALIDITY_FULL: return Full; + case GPGME_VALIDITY_ULTIMATE: return Ultimate; + } +} + + +char GpgME::Signature::validityAsString() const { + if ( isNull() ) + return '?'; + switch ( d->sigs[idx]->validity ) { + default: + case GPGME_VALIDITY_UNKNOWN: return '?'; + case GPGME_VALIDITY_UNDEFINED: return 'q'; + case GPGME_VALIDITY_NEVER: return 'n'; + case GPGME_VALIDITY_MARGINAL: return 'm'; + case GPGME_VALIDITY_FULL: return 'f'; + case GPGME_VALIDITY_ULTIMATE: return 'u'; + } +} + +GpgME::Error GpgME::Signature::nonValidityReason() const { + return isNull() ? 0 : d->sigs[idx]->validity_reason ; +} + + +GpgME::Signature::Notation GpgME::Signature::notation( unsigned int nidx ) const { + return Notation( d, idx, nidx ); +} + +std::vector<GpgME::Signature::Notation> GpgME::Signature::notations() const { + if ( isNull() ) + return std::vector<Notation>(); + std::vector<Notation> result; + result.reserve( d->nota[idx].size() ); + for ( unsigned int i = 0 ; i < d->nota[idx].size() ; ++i ) + result.push_back( Notation( d, idx, i ) ); + return result; +} + + +GpgME::Signature::Notation::Notation( VerificationResult::Private * parent, unsigned int sindex, unsigned int nindex ) + : d( parent ), sidx( sindex ), nidx( nindex ) +{ + if ( d ) + d->ref(); +} + +GpgME::Signature::Notation::Notation() + : d( 0 ), sidx( 0 ), nidx( 0 ) {} + +GpgME::Signature::Notation::Notation( const Notation & other ) + : d( other.d ), sidx( other.sidx ), nidx( other.nidx ) +{ + if ( d ) + d->ref(); +} + +GpgME::Signature::Notation::~Notation() { + if ( d ) + d->unref(); +} + +const GpgME::Signature::Notation & GpgME::Signature::Notation::operator=( const Notation & other ) { + if ( this->d != other.d ) { + if ( other.d ) + other.d->ref(); + if ( this->d ) + this->d->ref(); + this->d = other.d; + } + + sidx = other.sidx; + nidx = other.nidx; + return *this; +} + +bool GpgME::Signature::Notation::isNull() const { + return !d || sidx >= d->nota.size() || nidx >= d->nota[sidx].size() ; +} + + +const char * GpgME::Signature::Notation::name() const { + return isNull() ? 0 : d->nota[sidx][nidx].name ; +} + +const char * GpgME::Signature::Notation::value() const { + return isNull() ? 0 : d->nota[sidx][nidx].value ; +} + + +std::ostream & GpgME::operator<<( std::ostream & os, const VerificationResult & result ) { + os << "GpgME::VerificationResult("; + if ( !result.isNull() ) { + os << "\n error: " << result.error() + << "\n signatures:\n"; + const std::vector<Signature> sigs = result.signatures(); + std::copy( sigs.begin(), sigs.end(), + std::ostream_iterator<Signature>( os, "\n" ) ); + } + return os << ')'; +} + +std::ostream & GpgME::operator<<( std::ostream & os, Signature::Summary summary ) { +#define OUTPUT( x ) if ( !(summary & (GpgME::Signature:: x)) ) {} else do { os << #x " "; } while(0) + os << "GpgME::Signature::Summary("; + OUTPUT( Valid ); + OUTPUT( Green ); + OUTPUT( Red ); + OUTPUT( KeyRevoked ); + OUTPUT( KeyExpired ); + OUTPUT( SigExpired ); + OUTPUT( KeyMissing ); + OUTPUT( CrlMissing ); + OUTPUT( CrlTooOld ); + OUTPUT( BadPolicy ); + OUTPUT( SysError ); +#undef OUTPUT + return os << ')'; +} + +std::ostream & GpgME::operator<<( std::ostream & os, const Signature & sig ) { + os << "GpgME::Signature("; + if ( !sig.isNull() ) { + os << "\n Summary: " << sig.summary() + << "\n Fingerprint: " << protect( sig.fingerprint() ) + << "\n Status: " << sig.status() + << "\n creationTime: " << sig.creationTime() + << "\n expirationTime: " << sig.expirationTime() + << "\n wrongKeyUsage: " << sig.wrongKeyUsage() + << "\n validity: " << sig.validityAsString() + << "\n nonValidityReason: " << sig.nonValidityReason() + << "\n notations:\n"; + const std::vector<Signature::Notation> nota = sig.notations(); + std::copy( nota.begin(), nota.end(), + std::ostream_iterator<Signature::Notation>( os, "\n" ) ); + } + return os << ')'; +} + +std::ostream & GpgME::operator<<( std::ostream & os, const Signature::Notation & nota ) { + return os << "GpgME::Signature::Notation( \"" << protect( nota.name() ) << "\", \"" << protect( nota.value() ) << "\")"; +} diff --git a/libtdenetwork/gpgmepp/verificationresult.h b/libtdenetwork/gpgmepp/verificationresult.h new file mode 100644 index 00000000..e572ecfe --- /dev/null +++ b/libtdenetwork/gpgmepp/verificationresult.h @@ -0,0 +1,144 @@ +/* verificationresult.h - wraps a gpgme verify result + Copyright (C) 2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GPGME++ is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GPGME++; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __GPGMEPP_VERIFICATIONRESULT_H__ +#define __GPGMEPP_VERIFICATIONRESULT_H__ + +#include <gpgmepp/gpgmefw.h> +#include <gpgmepp/result.h> + +#include <time.h> + +#include <vector> +#include <iosfwd> + +#include <tdepimmacros.h> + +namespace GpgME { + + class Error; + class Signature; + + class KDE_EXPORT VerificationResult : public Result { + public: + VerificationResult( gpgme_ctx_t ctx=0, int error=0 ); + explicit VerificationResult( const Error & err ); + VerificationResult( const VerificationResult & other ); + ~VerificationResult(); + + const VerificationResult & operator=( const VerificationResult & other ); + + bool isNull() const; + + Signature signature( unsigned int index ) const; + std::vector<Signature> signatures() const; + + class Private; + private: + Private * d; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const VerificationResult & result ); + + class KDE_EXPORT Signature { + friend class VerificationResult; + Signature( VerificationResult::Private * parent, unsigned int index ); + public: + class Notation; + + Signature(); + Signature( const Signature & other ); + ~Signature(); + + const Signature & operator=( const Signature & other ); + + bool isNull() const; + + + enum Summary { + None = 0x000, + Valid = 0x001, + Green = 0x002, + Red = 0x004, + KeyRevoked = 0x008, + KeyExpired = 0x010, + SigExpired = 0x020, + KeyMissing = 0x040, + CrlMissing = 0x080, + CrlTooOld = 0x100, + BadPolicy = 0x200, + SysError = 0x400 + }; + Summary summary() const; + + const char * fingerprint() const; + + Error status() const; + + time_t creationTime() const; + time_t expirationTime() const; + bool neverExpires() const; + + bool wrongKeyUsage() const; + + enum Validity { + Unknown, Undefined, Never, Marginal, Full, Ultimate + }; + Validity validity() const; + char validityAsString() const; + Error nonValidityReason() const; + + Notation notation( unsigned int index ) const; + std::vector<Notation> notations() const; + + private: + VerificationResult::Private * d; + unsigned int idx; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const Signature & sig ); + KDE_EXPORT std::ostream & operator<<( std::ostream & os, Signature::Summary summary ); + + class KDE_EXPORT Signature::Notation { + friend class Signature; + Notation( VerificationResult::Private * parent, unsigned int sindex, unsigned int nindex ); + public: + Notation(); + Notation( const Notation & other ); + ~Notation(); + + const Notation & operator=( const Notation & other ); + + bool isNull() const; + + const char * name() const; + const char * value() const; + + private: + VerificationResult::Private * d; + unsigned int sidx; + unsigned int nidx; + }; + + KDE_EXPORT std::ostream & operator<<( std::ostream & os, const Signature::Notation & nota ); + +} + +#endif // __GPGMEPP_VERIFICATIONRESULT_H__ diff --git a/libtdenetwork/libgpg-error-copy/Makefile.am b/libtdenetwork/libgpg-error-copy/Makefile.am new file mode 100644 index 00000000..5f3ed9e6 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/Makefile.am @@ -0,0 +1,87 @@ +# Makefile.am for libgpg-error. +# Copyright (C) 2003 g10 Code GmbH +# +# This file is part of libgpg-error. +# +# libgpg-error is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# libgpg-error is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +# We distribute the generated sources err-sources.h and err-codes.h, +# because they are needed to build the po directory, and they don't +# depend on the configuration anyway. +#EXTRA_DIST = mkstrtable.awk err-sources.h.in err-codes.h.in \ +# mkerrnos.awk errnos.in mkerrcodes1.awk mkerrcodes2.awk \ +# err-sources.h err-codes.h gpg-error.m4 +#BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h +CLEANFILES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h gpg-error.h mkerrcodes.h mkerrcodes + +#bin_SCRIPTS = gpg-error-config +#m4datadir = $(datadir)/aclocal +#m4data_DATA = gpg-error.m4 +# +#include_HEADERS = gpg-error.h + +noinst_LTLIBRARIES = libgpg-error.la + +#libgpg_error_la_LDFLAGS = -version-info @LIBGPG_ERROR_LT_CURRENT@:@LIBGPG_ERROR_LT_REVISION@:@LIBGPG_ERROR_LT_AGE@ + +libgpg_error_la_SOURCES = strsource.c strerror.c code-to-errno.c code-from-errno.c + +#libgpg_error_la_LIBADD = @LTLIBINTL@ + +#We don't need the gpg-error command-line tool + +# Dependencies on generated files. +strsource.lo: err-sources.h gpg-error.h +strerror.lo: err-codes.h gpg-error.h +code-to-errno.lo: code-to-errno.h gpg-error.h +code-from-errno.lo: code-from-errno.h gpg-error.h + +err-sources.h: $(srcdir)/mkstrtable.awk $(srcdir)/err-sources.h.in + $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 \ + $(srcdir)/err-sources.h.in >$@ + +#We don't need err-sources-sym.h, err-codes-sym.h, errnos-sym.h. +# since those are for the gpg-error binary + +err-codes.h: $(srcdir)/mkstrtable.awk err-codes.h.in + $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 \ + $(srcdir)/err-codes.h.in >$@ + +code-to-errno.h: mkerrnos.awk errnos.in + $(AWK) -f $(srcdir)/mkerrnos.awk $(srcdir)/errnos.in >$@ + +# It is correct to use $(CPP). We want the host's idea of the error codes. +mkerrcodes.h: mkerrcodes.awk + $(AWK) -f $(srcdir)/mkerrcodes1.awk $(srcdir)/errnos.in \ + | $(CPP) - | grep GPG_ERR_ | $(AWK) -f $(srcdir)/mkerrcodes.awk >$@ + +# It is correct to use $(CC_FOR_BUILD) here. We want to run the +# program at build time. +# DF: we have no such thing in KDE. Using $(CC) instead. +mkerrcodes: mkerrcodes.c mkerrcodes.h + $(CC) -I. -I$(srcdir) -o $@ $(srcdir)/mkerrcodes.c + +code-from-errno.h: mkerrcodes + ./mkerrcodes | $(AWK) -f $(srcdir)/mkerrcodes2.awk > $@ + +gpg-error.h: mkheader.awk \ + err-sources.h.in err-codes.h.in errnos.in gpg-error.h.in + $(AWK) -f $(srcdir)/mkheader.awk \ + $(srcdir)/err-sources.h.in \ + $(srcdir)/err-codes.h.in \ + $(srcdir)/errnos.in \ + $(srcdir)/gpg-error.h.in > $@ + +# Removed all dependencies on Makefiles, since for us Makefile is in builddir. diff --git a/libtdenetwork/libgpg-error-copy/code-from-errno.c b/libtdenetwork/libgpg-error-copy/code-from-errno.c new file mode 100644 index 00000000..f51dd155 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/code-from-errno.c @@ -0,0 +1,69 @@ +/* code-from-errno.c - Mapping errnos to error codes. + Copyright (C) 2003 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> + +#include <gpg-error.h> + +#include "code-from-errno.h" + +/* Retrieve the error code for the system error ERR. This returns + GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report + this). */ +gpg_err_code_t +gpg_err_code_from_errno (int err) +{ + int idx; + + if (!err) + return GPG_ERR_NO_ERROR; + + idx = errno_to_idx (err); + + if (idx < 0) + return GPG_ERR_UNKNOWN_ERRNO; + + return GPG_ERR_SYSTEM_ERROR | err_code_from_index[idx]; +} + + +/* Retrieve the error code directly from the ERRNO variable. This + returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped + (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */ +gpg_err_code_t +gpg_err_code_from_syserror (void) +{ + int err = errno; + int idx; + + if (!err) + return GPG_ERR_MISSING_ERRNO; + + idx = errno_to_idx (err); + + if (idx < 0) + return GPG_ERR_UNKNOWN_ERRNO; + + return GPG_ERR_SYSTEM_ERROR | err_code_from_index[idx]; +} diff --git a/libtdenetwork/libgpg-error-copy/code-to-errno.c b/libtdenetwork/libgpg-error-copy/code-to-errno.c new file mode 100644 index 00000000..40d472d2 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/code-to-errno.c @@ -0,0 +1,42 @@ +/* code-to-errno.c - Mapping error codes to errnos. + Copyright (C) 2003 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpg-error.h> + +#include "code-to-errno.h" + +/* Retrieve the system error for the error code CODE. This returns 0 + if CODE is not a system error code. */ +int +gpg_err_code_to_errno (gpg_err_code_t code) +{ + if (!(code & GPG_ERR_SYSTEM_ERROR)) + return 0; + code &= ~GPG_ERR_SYSTEM_ERROR; + + if (code < sizeof (err_code_to_errno) / sizeof (err_code_to_errno[0])) + return err_code_to_errno[code]; + else + return 0; +} diff --git a/libtdenetwork/libgpg-error-copy/err-codes.h.in b/libtdenetwork/libgpg-error-copy/err-codes.h.in new file mode 100644 index 00000000..167de9c7 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/err-codes.h.in @@ -0,0 +1,289 @@ +# err-codes.h.in - List of error codes and their description input file. +/* err-codes.h - List of error codes and their description. + Copyright (C) 2003, 2004 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +# Everything up to the first line that starts with a number in the +# first column is copied into the output verbatim. Then, empty lines +# are ignored. Other lines must have an error code number, followed +# by one or more <tab> characters, followed by the error code symbol, +# followed by one or more <tab> characters, followed by the error +# message. Trailing whitespace is removed. The error codes should be +# sorted. The last line should not have a number, but only a <tab>, +# followed by a dummy field, followed by a <tab>, followed by a +# description for error codes that are not in the list. + +0 GPG_ERR_NO_ERROR Success +1 GPG_ERR_GENERAL General error +2 GPG_ERR_UNKNOWN_PACKET Unknown packet +3 GPG_ERR_UNKNOWN_VERSION Unknown version in packet +4 GPG_ERR_PUBKEY_ALGO Invalid public key algorithm +5 GPG_ERR_DIGEST_ALGO Invalid digest algorithm +6 GPG_ERR_BAD_PUBKEY Bad public key +7 GPG_ERR_BAD_SECKEY Bad secret key +8 GPG_ERR_BAD_SIGNATURE Bad signature +9 GPG_ERR_NO_PUBKEY No public key +10 GPG_ERR_CHECKSUM Checksum error +11 GPG_ERR_BAD_PASSPHRASE Bad passphrase +12 GPG_ERR_CIPHER_ALGO Invalid cipher algorithm +13 GPG_ERR_KEYRING_OPEN Keyring open +14 GPG_ERR_INV_PACKET Invalid packet +15 GPG_ERR_INV_ARMOR Invalid armor +16 GPG_ERR_NO_USER_ID No user ID +17 GPG_ERR_NO_SECKEY No secret key +18 GPG_ERR_WRONG_SECKEY Wrong secret key used +19 GPG_ERR_BAD_KEY Bad session key +20 GPG_ERR_COMPR_ALGO Unknown compression algorithm +21 GPG_ERR_NO_PRIME Number is not prime +22 GPG_ERR_NO_ENCODING_METHOD Invalid encoding method +23 GPG_ERR_NO_ENCRYPTION_SCHEME Invalid encryption scheme +24 GPG_ERR_NO_SIGNATURE_SCHEME Invalid signature scheme +25 GPG_ERR_INV_ATTR Invalid attribute +26 GPG_ERR_NO_VALUE No value +27 GPG_ERR_NOT_FOUND Not found +28 GPG_ERR_VALUE_NOT_FOUND Value not found +29 GPG_ERR_SYNTAX Syntax error +30 GPG_ERR_BAD_MPI Bad MPI value +31 GPG_ERR_INV_PASSPHRASE Invalid passphrase +32 GPG_ERR_SIG_CLASS Invalid signature class +33 GPG_ERR_RESOURCE_LIMIT Resources exhausted +34 GPG_ERR_INV_KEYRING Invalid keyring +35 GPG_ERR_TRUSTDB Trust DB error +36 GPG_ERR_BAD_CERT Bad certificate +37 GPG_ERR_INV_USER_ID Invalid user ID +38 GPG_ERR_UNEXPECTED Unexpected error +39 GPG_ERR_TIME_CONFLICT Time conflict +40 GPG_ERR_KEYSERVER Keyserver error +41 GPG_ERR_WRONG_PUBKEY_ALGO Wrong public key algorithm +42 GPG_ERR_TRIBUTE_TO_D_A Tribute to D. A. +43 GPG_ERR_WEAK_KEY Weak encryption key +44 GPG_ERR_INV_KEYLEN Invalid key length +45 GPG_ERR_INV_ARG Invalid argument +46 GPG_ERR_BAD_URI Syntax error in URI +47 GPG_ERR_INV_URI Invalid URI +48 GPG_ERR_NETWORK Network error +49 GPG_ERR_UNKNOWN_HOST Unknown host +50 GPG_ERR_SELFTEST_FAILED Selftest failed +51 GPG_ERR_NOT_ENCRYPTED Data not encrypted +52 GPG_ERR_NOT_PROCESSED Data not processed +53 GPG_ERR_UNUSABLE_PUBKEY Unusable public key +54 GPG_ERR_UNUSABLE_SECKEY Unusable secret key +55 GPG_ERR_INV_VALUE Invalid value +56 GPG_ERR_BAD_CERT_CHAIN Bad certificate chain +57 GPG_ERR_MISSING_CERT Missing certificate +58 GPG_ERR_NO_DATA No data +59 GPG_ERR_BUG Bug +60 GPG_ERR_NOT_SUPPORTED Not supported +61 GPG_ERR_INV_OP Invalid operation code +62 GPG_ERR_TIMEOUT Timeout +63 GPG_ERR_INTERNAL Internal error +64 GPG_ERR_EOF_GCRYPT EOF (gcrypt) +65 GPG_ERR_INV_OBJ Invalid object +66 GPG_ERR_TOO_SHORT Provided object is too short +67 GPG_ERR_TOO_LARGE Provided object is too large +68 GPG_ERR_NO_OBJ Missing item in object +69 GPG_ERR_NOT_IMPLEMENTED Not implemented +70 GPG_ERR_CONFLICT Conflicting use +71 GPG_ERR_INV_CIPHER_MODE Invalid cipher mode +72 GPG_ERR_INV_FLAG Invalid flag +73 GPG_ERR_INV_HANDLE Invalid handle +74 GPG_ERR_TRUNCATED Result truncated +75 GPG_ERR_INCOMPLETE_LINE Incomplete line +76 GPG_ERR_INV_RESPONSE Invalid response +77 GPG_ERR_NO_AGENT No agent running +78 GPG_ERR_AGENT agent error +79 GPG_ERR_INV_DATA Invalid data +80 GPG_ERR_ASSUAN_SERVER_FAULT Unspecific Assuan server fault +81 GPG_ERR_ASSUAN General Assuan error +82 GPG_ERR_INV_SESSION_KEY Invalid session key +83 GPG_ERR_INV_SEXP Invalid S-expression +84 GPG_ERR_UNSUPPORTED_ALGORITHM Unsupported algorithm +85 GPG_ERR_NO_PIN_ENTRY No pinentry +86 GPG_ERR_PIN_ENTRY pinentry error +87 GPG_ERR_BAD_PIN Bad PIN +88 GPG_ERR_INV_NAME Invalid name +89 GPG_ERR_BAD_DATA Bad data +90 GPG_ERR_INV_PARAMETER Invalid parameter +91 GPG_ERR_WRONG_CARD Wrong card +92 GPG_ERR_NO_DIRMNGR No dirmngr +93 GPG_ERR_DIRMNGR dirmngr error +94 GPG_ERR_CERT_REVOKED Certificate revoked +95 GPG_ERR_NO_CRL_KNOWN No CRL known +96 GPG_ERR_CRL_TOO_OLD CRL too old +97 GPG_ERR_LINE_TOO_LONG Line too long +98 GPG_ERR_NOT_TRUSTED Not trusted +99 GPG_ERR_CANCELED Operation cancelled +100 GPG_ERR_BAD_CA_CERT Bad CA certificate +101 GPG_ERR_CERT_EXPIRED Certificate expired +102 GPG_ERR_CERT_TOO_YOUNG Certificate too young +103 GPG_ERR_UNSUPPORTED_CERT Unsupported certificate +104 GPG_ERR_UNKNOWN_SEXP Unknown S-expression +105 GPG_ERR_UNSUPPORTED_PROTECTION Unsupported protection +106 GPG_ERR_CORRUPTED_PROTECTION Corrupted protection +107 GPG_ERR_AMBIGUOUS_NAME Ambiguous name +108 GPG_ERR_CARD Card error +109 GPG_ERR_CARD_RESET Card reset required +110 GPG_ERR_CARD_REMOVED Card removed +111 GPG_ERR_INV_CARD Invalid card +112 GPG_ERR_CARD_NOT_PRESENT Card not present +113 GPG_ERR_NO_PKCS15_APP No PKCS15 application +114 GPG_ERR_NOT_CONFIRMED Not confirmed +115 GPG_ERR_CONFIGURATION Configuration error +116 GPG_ERR_NO_POLICY_MATCH No policy match +117 GPG_ERR_INV_INDEX Invalid index +118 GPG_ERR_INV_ID Invalid ID +119 GPG_ERR_NO_SCDAEMON No SmartCard daemon +120 GPG_ERR_SCDAEMON SmartCard daemon error +121 GPG_ERR_UNSUPPORTED_PROTOCOL Unsupported protocol +122 GPG_ERR_BAD_PIN_METHOD Bad PIN method +123 GPG_ERR_CARD_NOT_INITIALIZED Card not initialized +124 GPG_ERR_UNSUPPORTED_OPERATION Unsupported operation +125 GPG_ERR_WRONG_KEY_USAGE Wrong key usage +126 GPG_ERR_NOTHING_FOUND Nothing found +127 GPG_ERR_WRONG_BLOB_TYPE Wrong blob type +128 GPG_ERR_MISSING_VALUE Missing value +129 GPG_ERR_HARDWARE Hardware problem +130 GPG_ERR_PIN_BLOCKED PIN blocked +131 GPG_ERR_USE_CONDITIONS Conditions of use not satisfied +132 GPG_ERR_PIN_NOT_SYNCED PINs are not synced +133 GPG_ERR_INV_CRL Invalid CRL +134 GPG_ERR_BAD_BER BER error +135 GPG_ERR_INV_BER Invalid BER +136 GPG_ERR_ELEMENT_NOT_FOUND Element not found +137 GPG_ERR_IDENTIFIER_NOT_FOUND Identifier not found +138 GPG_ERR_INV_TAG Invalid tag +139 GPG_ERR_INV_LENGTH Invalid length +140 GPG_ERR_INV_KEYINFO Invalid key info +141 GPG_ERR_UNEXPECTED_TAG Unexpected tag +142 GPG_ERR_NOT_DER_ENCODED Not DER encoded +143 GPG_ERR_NO_CMS_OBJ No CMS object +144 GPG_ERR_INV_CMS_OBJ Invalid CMS object +145 GPG_ERR_UNKNOWN_CMS_OBJ Unknown CMS object +146 GPG_ERR_UNSUPPORTED_CMS_OBJ Unsupported CMS object +147 GPG_ERR_UNSUPPORTED_ENCODING Unsupported encoding +148 GPG_ERR_UNSUPPORTED_CMS_VERSION Unsupported CMS version +149 GPG_ERR_UNKNOWN_ALGORITHM Unknown algorithm +150 GPG_ERR_INV_ENGINE Invalid crypto engine +151 GPG_ERR_PUBKEY_NOT_TRUSTED Public key not trusted +152 GPG_ERR_DECRYPT_FAILED Decryption failed +153 GPG_ERR_KEY_EXPIRED Key expired +154 GPG_ERR_SIG_EXPIRED Signature expired +155 GPG_ERR_ENCODING_PROBLEM Encoding problem +156 GPG_ERR_INV_STATE Invalid state +157 GPG_ERR_DUP_VALUE Duplicated value +158 GPG_ERR_MISSING_ACTION Missing action +159 GPG_ERR_MODULE_NOT_FOUND ASN.1 module not found +160 GPG_ERR_INV_OID_STRING Invalid OID string +161 GPG_ERR_INV_TIME Invalid time +162 GPG_ERR_INV_CRL_OBJ Invalid CRL object +163 GPG_ERR_UNSUPPORTED_CRL_VERSION Unsupported CRL version +164 GPG_ERR_INV_CERT_OBJ Invalid certificate object +165 GPG_ERR_UNKNOWN_NAME Unknown name +166 GPG_ERR_LOCALE_PROBLEM A locale function failed +167 GPG_ERR_NOT_LOCKED Not locked +168 GPG_ERR_PROTOCOL_VIOLATION Protocol violation +169 GPG_ERR_INV_MAC Invalid MAC +170 GPG_ERR_INV_REQUEST Invalid request +171 GPG_ERR_UNKNOWN_EXTN Unknown extension +172 GPG_ERR_UNKNOWN_CRIT_EXTN Unknown critical extension +173 GPG_ERR_LOCKED Locked +174 GPG_ERR_UNKNOWN_OPTION Unknown option +175 GPG_ERR_UNKNOWN_COMMAND Unknown command +# 176 to 199 are free to be used. + +200 GPG_ERR_BUFFER_TOO_SHORT Buffer too short + +# Error codes pertaining to S-expressions. + +201 GPG_ERR_SEXP_INV_LEN_SPEC Invalid length specifier in S-expression +202 GPG_ERR_SEXP_STRING_TOO_LONG String too long in S-expression +203 GPG_ERR_SEXP_UNMATCHED_PAREN Unmatched parentheses in S-expression +204 GPG_ERR_SEXP_NOT_CANONICAL S-expression not canonical +205 GPG_ERR_SEXP_BAD_CHARACTER Bad character in S-expression +206 GPG_ERR_SEXP_BAD_TQUOTATION Bad quotation in S-expression +207 GPG_ERR_SEXP_ZERO_PREFIX Zero prefix in S-expression +208 GPG_ERR_SEXP_NESTED_DH Nested display hints in S-expression +209 GPG_ERR_SEXP_UNMATCHED_DH Unmatched display hints +210 GPG_ERR_SEXP_UNEXPECTED_PUNC Unexpected reserved punctuation in S-expression +211 GPG_ERR_SEXP_BAD_HEX_CHAR Bad hexadecimal character in S-expression +212 GPG_ERR_SEXP_ODD_HEX_NUMBERS Odd hexadecimal numbers in S-expression +213 GPG_ERR_SEXP_BAD_OCT_CHAR Bad octadecimal character in S-expression + +# 214 to 254 are free to be used. 255 and 256 are RFU. + +# Error codes pertaining to the Assuan IPC interface +257 GPG_ERR_ASS_GENERAL General IPC error +258 GPG_ERR_ASS_ACCEPT_FAILED IPC accept call failed +259 GPG_ERR_ASS_CONNECT_FAILED IPC connect call failed +260 GPG_ERR_ASS_INV_RESPONSE Invalid IPC response +261 GPG_ERR_ASS_INV_VALUE Invalid value passed to IPC +262 GPG_ERR_ASS_INCOMPLETE_LINE Incomplete line passed to IPC +263 GPG_ERR_ASS_LINE_TOO_LONG Line passed to IPC too long +264 GPG_ERR_ASS_NESTED_COMMANDS Nested IPC commands +265 GPG_ERR_ASS_NO_DATA_CB No data callback in IPC +266 GPG_ERR_ASS_NO_INTQUIRE_CB No inquire callback in IPC +267 GPG_ERR_ASS_NOT_A_SERVER Not an IPC server +268 GPG_ERR_ASS_NOT_A_CLIENT Not an IPC client +269 GPG_ERR_ASS_SERVER_START Problem starting IPC server +270 GPG_ERR_ASS_READ_ERROR IPC read error +271 GPG_ERR_ASS_WRITE_ERROR IPC write error +# reserved +273 GPG_ERR_ASS_TOO_MUCH_DATA Too much data for IPC layer +274 GPG_ERR_ASS_UNEXPECTED_CMD Unexpected IPC command +275 GPG_ERR_ASS_UNKNOWN_CMD Unknown IPC command +276 GPG_ERR_ASS_SYNTAX IPC syntax error +277 GPG_ERR_ASS_CANCELED IPC call has been cancelled +278 GPG_ERR_ASS_NO_INPUT No input source for IPC +279 GPG_ERR_ASS_NO_OUTPUT No output source for IPC +280 GPG_ERR_ASS_PARAMETER IPC parameter error +281 GPG_ERR_ASS_UNKNOWN_INTQUIRE Unknown IPC inquire + +# 282 to 299 are reserved for future assuan codes. + +# 300 to 1023 are free to be used. + +# For free use by non-GnuPG components. +1024 GPG_ERR_USER_1 User defined error code 1 +1025 GPG_ERR_USER_2 User defined error code 2 +1026 GPG_ERR_USER_3 User defined error code 3 +1027 GPG_ERR_USER_4 User defined error code 4 +1028 GPG_ERR_USER_5 User defined error code 5 +1029 GPG_ERR_USER_6 User defined error code 6 +1030 GPG_ERR_USER_7 User defined error code 7 +1031 GPG_ERR_USER_8 User defined error code 8 +1032 GPG_ERR_USER_9 User defined error code 9 +1033 GPG_ERR_USER_10 User defined error code 10 +1034 GPG_ERR_USER_11 User defined error code 11 +1035 GPG_ERR_USER_12 User defined error code 12 +1036 GPG_ERR_USER_13 User defined error code 13 +1037 GPG_ERR_USER_14 User defined error code 14 +1038 GPG_ERR_USER_15 User defined error code 15 +1039 GPG_ERR_USER_16 User defined error code 16 + +# 1040 to 16380 are free to be used. + +16381 GPG_ERR_MISSING_ERRNO System error w/o errno +16382 GPG_ERR_UNKNOWN_ERRNO Unknown system error +16383 GPG_ERR_EOF End of file + +# 16384 - 32767 are reserved for future extensions. + +# GPG_SYSTEM_ERROR | (141 to 32767) are to be used for system errors. + + GPG_ERR_CODE_DIM Unknown error code diff --git a/libtdenetwork/libgpg-error-copy/err-sources.h.in b/libtdenetwork/libgpg-error-copy/err-sources.h.in new file mode 100644 index 00000000..4d879487 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/err-sources.h.in @@ -0,0 +1,55 @@ +# err-sources.h.in - List of error sources and their description input file. +/* err-sources.h - List of error sources and their description. + Copyright (C) 2003, 2004 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +# Everything up to the first line that starts with a number in the +# first column is copied into the output verbatim. Then, empty lines +# are ignored. Other lines must have an error source number, followed +# by one or more <tab> characters, followed by the error source +# symbol, followed by one or more <tab> characters, followed by the +# error source name. Trailing whitespace is removed. The error +# sources should be sorted. The last line should not have a number, +# but only a <tab>, followed by a description for error sources that +# are not in the list. + +0 GPG_ERR_SOURCE_UNKNOWN Unspecified source +1 GPG_ERR_SOURCE_GCRYPT gcrypt +2 GPG_ERR_SOURCE_GPG GnuPG +3 GPG_ERR_SOURCE_GPGSM GpgSM +4 GPG_ERR_SOURCE_GPGAGENT GPG Agent +5 GPG_ERR_SOURCE_PINENTRY Pinentry +6 GPG_ERR_SOURCE_SCD SCD +7 GPG_ERR_SOURCE_GPGME GPGME +8 GPG_ERR_SOURCE_KEYBOX Keybox +9 GPG_ERR_SOURCE_KSBA KSBA +10 GPG_ERR_SOURCE_DIRMNGR Dirmngr +11 GPG_ERR_SOURCE_GSTI GSTI + +# 11 to 30 are free to be used. + +31 GPG_ERR_SOURCE_ANY Any source +32 GPG_ERR_SOURCE_USER_1 User defined source 1 +33 GPG_ERR_SOURCE_USER_2 User defined source 2 +34 GPG_ERR_SOURCE_USER_3 User defined source 3 +35 GPG_ERR_SOURCE_USER_4 User defined source 4 + +# 36 to 255 are free to be used. + + GPG_ERR_SOURCE_DIM Unknown source diff --git a/libtdenetwork/libgpg-error-copy/errnos.in b/libtdenetwork/libgpg-error-copy/errnos.in new file mode 100644 index 00000000..8a47bcce --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/errnos.in @@ -0,0 +1,172 @@ +# errnos.h.in - List of system error values input file. +/* errnos.h - List of system error values. + Copyright (C) 2003, 2004 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +# Everything up to the first line that starts with a number in the +# first column is copied into the output verbatim. Then, empty lines +# are ignored. Other lines must have an error code number, followed +# by one or more <tab> characters, followed by the error name. +# +# IMPORTANT: For now, the numbering must be consecutive. Some of the +# scripts (notably mkerrnos.h) do not deal correctly with a numbering +# that is out of order or has gaps. + + +0 E2BIG +1 EACCES +2 EADDRINUSE +3 EADDRNOTAVAIL +4 EADV +5 EAFNOSUPPORT +6 EAGAIN +7 EALREADY +8 EAUTH +9 EBACKGROUND +10 EBADE +11 EBADF +12 EBADFD +13 EBADMSG +14 EBADR +15 EBADRPC +16 EBADRQC +17 EBADSLT +18 EBFONT +19 EBUSY +20 ECANCELED +21 ECHILD +22 ECHRNG +23 ECOMM +24 ECONNABORTED +25 ECONNREFUSED +26 ECONNRESET +27 ED +28 EDEADLK +29 EDEADLOCK +30 EDESTADDRREQ +31 EDIED +32 EDOM +33 EDOTDOT +34 EDQUOT +35 EEXIST +36 EFAULT +37 EFBIG +38 EFTYPE +39 EGRATUITOUS +40 EGREGIOUS +41 EHOSTDOWN +42 EHOSTUNREACH +43 EIDRM +44 EIEIO +45 EILSEQ +46 EINPROGRESS +47 EINTR +48 EINVAL +49 EIO +50 EISCONN +51 EISDIR +52 EISNAM +53 EL2HLT +54 EL2NSYNC +55 EL3HLT +56 EL3RST +57 ELIBACC +58 ELIBBAD +59 ELIBEXEC +60 ELIBMAX +61 ELIBSCN +62 ELNRNG +63 ELOOP +64 EMEDIUMTYPE +65 EMFILE +66 EMLINK +67 EMSGSIZE +68 EMULTIHOP +69 ENAMETOOLONG +70 ENAVAIL +71 ENEEDAUTH +72 ENETDOWN +73 ENETRESET +74 ENETUNREACH +75 ENFILE +76 ENOANO +77 ENOBUFS +78 ENOCSI +79 ENODATA +80 ENODEV +81 ENOENT +82 ENOEXEC +83 ENOLCK +84 ENOLINK +85 ENOMEDIUM +86 ENOMEM +87 ENOMSG +88 ENONET +89 ENOPKG +90 ENOPROTOOPT +91 ENOSPC +92 ENOSR +93 ENOSTR +94 ENOSYS +95 ENOTBLK +96 ENOTCONN +97 ENOTDIR +98 ENOTEMPTY +99 ENOTNAM +100 ENOTSOCK +101 ENOTSUP +102 ENOTTY +103 ENOTUNIQ +104 ENXIO +105 EOPNOTSUPP +106 EOVERFLOW +107 EPERM +108 EPFNOSUPPORT +109 EPIPE +110 EPROCLIM +111 EPROCUNAVAIL +112 EPROGMISMATCH +113 EPROGUNAVAIL +114 EPROTO +115 EPROTONOSUPPORT +116 EPROTOTYPE +117 ERANGE +118 EREMCHG +119 EREMOTE +120 EREMOTEIO +121 ERESTART +122 EROFS +123 ERPCMISMATCH +124 ESHUTDOWN +125 ESOCKTNOSUPPORT +126 ESPIPE +127 ESRCH +128 ESRMNT +129 ESTALE +130 ESTRPIPE +131 ETIME +132 ETIMEDOUT +133 ETOOMANYREFS +134 ETXTBSY +135 EUCLEAN +136 EUNATCH +137 EUSERS +138 EWOULDBLOCK +139 EXDEV +140 EXFULL diff --git a/libtdenetwork/libgpg-error-copy/gettext.h b/libtdenetwork/libgpg-error-copy/gettext.h new file mode 100644 index 00000000..0cae5f45 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/gettext.h @@ -0,0 +1,75 @@ +/* Convenience header for conditional use of GNU <libintl.h>. + Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +#if HAVE_W32_SYSTEM +/* Redirect the gettext calls to an internal implementation on W32 + targets. */ +# include "w32-gettext.h" +#else +/* Get declarations of GNU message catalog functions. */ +# include <libintl.h> +#endif + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of <locale.h> a NOP. We don't include <libintl.h> + as well because people using "gettext.h" will not include <libintl.h>, + and also including <libintl.h> would fail on SunOS 4, whereas <locale.h> + is OK. */ +#if defined(__sun) +# include <locale.h> +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ diff --git a/libtdenetwork/libgpg-error-copy/gpg-error.h.in b/libtdenetwork/libgpg-error-copy/gpg-error.h.in new file mode 100644 index 00000000..cc1aaea8 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/gpg-error.h.in @@ -0,0 +1,258 @@ +/* gpg-error.h - Public interface to libgpg-error. + Copyright (C) 2003, 2004 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef GPG_ERROR_H +#define GPG_ERROR_H 1 + +#include <stddef.h> + +#ifdef __GNUC__ +#define GPG_ERR_INLINE __inline__ +#elif __STDC_VERSION__ >= 199901L +#define GPG_ERR_INLINE inline +#else +#ifndef GPG_ERR_INLINE +#define GPG_ERR_INLINE +#endif +#endif + + +#ifdef __cplusplus +extern "C" { +#if 0 /* just to make Emacs auto-indent happy */ +} +#endif +#endif /* __cplusplus */ + +/* The GnuPG project consists of many components. Error codes are + exchanged between all components. The common error codes and their + user-presentable descriptions are kept into a shared library to + allow adding new error codes and components without recompiling any + of the other components. The interface will not change in a + backward incompatible way. + + An error code together with an error source build up an error + value. As the error value is been passed from one component to + another, it preserver the information about the source and nature + of the error. + + A component of the GnuPG project can define the following macro to + tune the behaviour of the library: + + GPG_ERR_SOURCE_DEFAULT: Define to an error source of type + gpg_err_source_t to make that source the default for gpg_error(). + Otherwise GPG_ERR_SOURCE_UNKNOWN is used as default. */ + + +/* The error source type gpg_err_source_t. + + Where as the Poo out of a welle small + Taketh his firste springing and his sours. + --Chaucer. */ + +/* Only use free slots, never change or reorder the existing + entries. */ +typedef enum + { +@include err-sources.h.in + + /* This is one more than the largest allowed entry. */ + GPG_ERR_SOURCE_DIM = 256 + } gpg_err_source_t; + + +/* The error code type gpg_err_code_t. */ + +/* Only use free slots, never change or reorder the existing + entries. */ +typedef enum + { +@include err-codes.h.in + + /* The following error codes are used to map system errors. */ +#define GPG_ERR_SYSTEM_ERROR (1 << 15) +@include errnos.in + + /* This is one more than the largest allowed entry. */ + GPG_ERR_CODE_DIM = 65536 + } gpg_err_code_t; + + +/* The error value type gpg_error_t. */ + +/* We would really like to use bit-fields in a struct, but using + structs as return values can cause binary compatibility issues, in + particular if you want to do it effeciently (also see + -freg-struct-return option to GCC). */ +typedef unsigned int gpg_error_t; + +/* We use the lowest 16 bits of gpg_error_t for error codes. The 16th + bit indicates system errors. */ +#define GPG_ERR_CODE_MASK (GPG_ERR_CODE_DIM - 1) + +/* Bits 17 to 24 are reserved. */ + +/* We use the upper 8 bits of gpg_error_t for error sources. */ +#define GPG_ERR_SOURCE_MASK (GPG_ERR_SOURCE_DIM - 1) +#define GPG_ERR_SOURCE_SHIFT 24 + + +/* GCC feature test. */ +#undef _GPG_ERR_HAVE_CONSTRUCTOR +#if __GNUC__ +#define _GPG_ERR_GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if _GPG_ERR_GCC_VERSION > 30100 +#define _GPG_ERR_CONSTRUCTOR __attribute__ ((__constructor__)) +#define _GPG_ERR_HAVE_CONSTRUCTOR +#endif +#endif + +#ifndef _GPG_ERR_CONSTRUCTOR +#define _GPG_ERR_CONSTRUCTOR +#endif + + +/* Initialization function. */ + +/* Initialize the library. This function should be run early. */ +gpg_error_t gpg_err_init (void) _GPG_ERR_CONSTRUCTOR; + +/* If this is defined, the library is already initialized by the + constructor and does not need to be initialized explicitely. */ +#undef GPG_ERR_INITIALIZED +#ifdef _GPG_ERR_HAVE_CONSTRUCTOR +#define GPG_ERR_INITIALIZED 1 +#endif + + +/* Constructor and accessor functions. */ + +/* Construct an error value from an error code and source. Within a + subsystem, use gpg_error. */ +static GPG_ERR_INLINE gpg_error_t +gpg_err_make (gpg_err_source_t source, gpg_err_code_t code) +{ + return code == GPG_ERR_NO_ERROR ? GPG_ERR_NO_ERROR + : (((source & GPG_ERR_SOURCE_MASK) << GPG_ERR_SOURCE_SHIFT) + | (code & GPG_ERR_CODE_MASK)); +} + + +/* The user should define GPG_ERR_SOURCE_DEFAULT before including this + file to specify a default source for gpg_error. */ +#ifndef GPG_ERR_SOURCE_DEFAULT +#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_UNKNOWN +#endif + +static GPG_ERR_INLINE gpg_error_t +gpg_error (gpg_err_code_t code) +{ + return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, code); +} + + +/* Retrieve the error code from an error value. */ +static GPG_ERR_INLINE gpg_err_code_t +gpg_err_code (gpg_error_t err) +{ + return (gpg_err_code_t) (err & GPG_ERR_CODE_MASK); +} + + +/* Retrieve the error source from an error value. */ +static GPG_ERR_INLINE gpg_err_source_t +gpg_err_source (gpg_error_t err) +{ + return (gpg_err_source_t) ((err >> GPG_ERR_SOURCE_SHIFT) + & GPG_ERR_SOURCE_MASK); +} + + +/* String functions. */ + +/* Return a pointer to a string containing a description of the error + code in the error value ERR. This function is not thread-safe. */ +const char *gpg_strerror (gpg_error_t err); + +/* Return the error string for ERR in the user-supplied buffer BUF of + size BUFLEN. This function is, in contrast to gpg_strerror, + thread-safe if a thread-safe strerror_r() function is provided by + the system. If the function succeeds, 0 is returned and BUF + contains the string describing the error. If the buffer was not + large enough, ERANGE is returned and BUF contains as much of the + beginning of the error string as fits into the buffer. */ +int gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen); + +/* Return a pointer to a string containing a description of the error + source in the error value ERR. */ +const char *gpg_strsource (gpg_error_t err); + + +/* Mapping of system errors (errno). */ + +/* Retrieve the error code for the system error ERR. This returns + GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report + this). */ +gpg_err_code_t gpg_err_code_from_errno (int err); + + +/* Retrieve the system error for the error code CODE. This returns 0 + if CODE is not a system error code. */ +int gpg_err_code_to_errno (gpg_err_code_t code); + + +/* Retrieve the error code directly from the ERRNO variable. This + returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped + (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */ +gpg_err_code_t gpg_err_code_from_syserror (void); + + + + +/* Self-documenting convenience functions. */ + +static GPG_ERR_INLINE gpg_error_t +gpg_err_make_from_errno (gpg_err_source_t source, int err) +{ + return gpg_err_make (source, gpg_err_code_from_errno (err)); +} + + +static GPG_ERR_INLINE gpg_error_t +gpg_error_from_errno (int err) +{ + return gpg_error (gpg_err_code_from_errno (err)); +} + +static GPG_ERR_INLINE gpg_error_t +gpg_error_from_syserror (void) +{ + return gpg_error (gpg_err_code_from_syserror ()); +} + +#ifdef __cplusplus +} +#endif + + +#endif /* GPG_ERROR_H */ diff --git a/libtdenetwork/libgpg-error-copy/mkerrcodes.awk b/libtdenetwork/libgpg-error-copy/mkerrcodes.awk new file mode 100644 index 00000000..66e20c3c --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/mkerrcodes.awk @@ -0,0 +1,99 @@ +# mkerrcodes.awk +# Copyright (C) 2004, 2005 g10 Code GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception, g10 Code GmbH gives unlimited permission to +# copy, distribute and modify the C source files that are the output +# of mkerrcodes.awk. You need not follow the terms of the GNU General +# Public License when using or distributing such scripts, even though +# portions of the text of mkerrcodes.awk appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the mkerrcodes.awk program. +# +# Certain portions of the mkerrcodes.awk source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# mkerrcodes.awk. We call these the "data" portions. The rest of the +# mkerrcodes.awk source text consists of comments plus executable code +# that decides which of the data portions to output in any given case. +# We call these comments and executable code the "non-data" portions. +# mkerrcodes.h never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of mkerrcodes.awk +# released by g10 Code GmbH. When you make and distribute a modified version +# of mkerrcodes.awk, you may extend this special exception to the GPL to +# apply to your modified version as well, *unless* your modified version +# has the potential to copy into its output some of the text that was the +# non-data portion of the version that you started with. (In other words, +# unless your change moves or copies text from the non-data portions to the +# data portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified version. + +# This script outputs an intermediate file that contains the following output: +# static struct +# { +# int err; +# const char *err_sym; +# } err_table[] = +# { +# { 7, "GPG_ERR_E2BIG" }, +# [...] +# }; +# +# The input file is a list of possible system errors, followed by a GPG_ERR_* name: +# +# 7 GPG_ERR_E2BIG +# +# Comments (starting with # and ending at the end of the line) are removed, +# as is trailing whitespace. + +BEGIN { + FS="[ \t]+GPG_ERR_"; + print "/* Output of mkerrcodes.awk. DO NOT EDIT. */"; + print ""; + header = 1; +} + +/^#/ { next; } + +header { + if (! /^[ \t]*$/) + { + header = 0; + + print "static struct"; + print " {"; + print " int err;"; + print " const char *err_sym;"; + print " } err_table[] = "; + print "{"; + } + else + print; +} + +!header { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + + print " { " $1 ", \"GPG_ERR_" $2 "\" },"; +} + +END { + print "};"; +} diff --git a/libtdenetwork/libgpg-error-copy/mkerrcodes.c b/libtdenetwork/libgpg-error-copy/mkerrcodes.c new file mode 100644 index 00000000..a92f6d9e --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/mkerrcodes.c @@ -0,0 +1,78 @@ +/* mkerrcodes.c - Generate list of system error values. + Copyright (C) 2004 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* This file must not include config.h, as that is for the host + system, while this file will be run on the build system. */ + +#include <stdio.h> + +#include "mkerrcodes.h" + +static const char header[] = +"/* errnos.h - List of system error values.\n" +" Copyright (C) 2004 g10 Code GmbH\n" +" This file is part of libgpg-error.\n" +"\n" +" libgpg-error is free software; you can redistribute it and/or\n" +" modify it under the terms of the GNU Lesser General Public License\n" +" as published by the Free Software Foundation; either version 2.1 of\n" +" the License, or (at your option) any later version.\n" +"\n" +" libgpg-error is distributed in the hope that it will be useful, but\n" +" WITHOUT ANY WARRANTY; without even the implied warranty of\n" +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" +" Lesser General Public License for more details.\n" +"\n" +" You should have received a copy of the GNU Lesser General Public\n" +" License along with libgpg-error; if not, write to the Free\n" +" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n" +" 02110-1301, USA. */\n" +"\n"; + +int +main (int argc, char **argv) +{ + int sorted; + int i; + + printf ("%s", header); + do + { + sorted = 1; + for (i = 0; i < sizeof (err_table) / sizeof (err_table[0]) - 1; i++) + if (err_table[i].err > err_table[i + 1].err) + { + int err = err_table[i].err; + const char *err_sym = err_table[i].err_sym; + + err_table[i].err = err_table[i + 1].err; + err_table[i].err_sym = err_table[i + 1].err_sym; + err_table[i + 1].err = err; + err_table[i + 1].err_sym = err_sym; + sorted = 0; + } + } + while (!sorted); + + for (i = 0; i < sizeof (err_table) / sizeof (err_table[0]); i++) + printf ("%i\t%s\n", err_table[i].err, err_table[i].err_sym); + + return 0; +} diff --git a/libtdenetwork/libgpg-error-copy/mkerrcodes1.awk b/libtdenetwork/libgpg-error-copy/mkerrcodes1.awk new file mode 100644 index 00000000..f93416ee --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/mkerrcodes1.awk @@ -0,0 +1,90 @@ +# mkerrcodes.awk +# Copyright (C) 2003, 2004 g10 Code GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception, g10 Code GmbH gives unlimited permission to +# copy, distribute and modify the C source files that are the output +# of mkerrcodes.awk. You need not follow the terms of the GNU General +# Public License when using or distributing such scripts, even though +# portions of the text of mkerrcodes.awk appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the mkerrcodes.awk program. +# +# Certain portions of the mkerrcodes.awk source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# mkerrcodes.awk. We call these the "data" portions. The rest of the +# mkerrcodes.awk source text consists of comments plus executable code +# that decides which of the data portions to output in any given case. +# We call these comments and executable code the "non-data" portions. +# mkerrcodes.h never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of mkerrcodes.awk +# released by g10 Code GmbH. When you make and distribute a modified version +# of mkerrcodes.awk, you may extend this special exception to the GPL to +# apply to your modified version as well, *unless* your modified version +# has the potential to copy into its output some of the text that was the +# non-data portion of the version that you started with. (In other words, +# unless your change moves or copies text from the non-data portions to the +# data portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified version. + +# This script outputs an intermediate file that contains the following block +# for each error value symbol in the input file (example for EINVAL): +# +# #ifdef EINVAL +# EINVAL GPG_ERR_EINVAL +# #endif +# +# The input file is a list of possible system errors in the column errnoidx +# (defaults to 2). +# +# Comments (starting with # and ending at the end of the line) are removed, +# as is trailing whitespace. + +BEGIN { + FS="[\t]+"; + header = 1; + if (errnoidx == 0) + errnoidx = 2; + + print "/* Output of mkerrcodes.awk. DO NOT EDIT. */"; + print ""; +} + +/^#/ { next; } + +header { + if ($1 ~ /^[0-9]/) + { + print "#include <errno.h>"; + print ""; + header = 0; + } + else + print; +} + +!header { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + + print "#ifdef " $errnoidx; + print $errnoidx "\tGPG_ERR_" $errnoidx; + print "#endif"; +} diff --git a/libtdenetwork/libgpg-error-copy/mkerrcodes2.awk b/libtdenetwork/libgpg-error-copy/mkerrcodes2.awk new file mode 100644 index 00000000..1dccb7fa --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/mkerrcodes2.awk @@ -0,0 +1,134 @@ +# mkstrtable.awk +# Copyright (C) 2003 g10 Code GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception, g10 Code GmbH gives unlimited permission to +# copy, distribute and modify the C source files that are the output +# of mkerrcodes2.awk. You need not follow the terms of the GNU General +# Public License when using or distributing such scripts, even though +# portions of the text of mkerrcodes2.awk appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the mkerrcodes2.awk program. +# +# Certain portions of the mkerrcodes2.awk source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# mkerrcodes2.awk. We call these the "data" portions. The rest of the +# mkerrcodes2.awk source text consists of comments plus executable code +# that decides which of the data portions to output in any given case. +# We call these comments and executable code the "non-data" portions. +# mkstrtable.h never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of mkerrcodes2.awk +# released by g10 Code GmbH. When you make and distribute a modified version +# of mkerrcodes2.awk, you may extend this special exception to the GPL to +# apply to your modified version as well, *unless* your modified version +# has the potential to copy into its output some of the text that was the +# non-data portion of the version that you started with. (In other words, +# unless your change moves or copies text from the non-data portions to the +# data portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified version. + +# This script outputs a source file that does define the following +# symbols: +# +# static const char msgstr[]; +# A string containing all messages in the list. +# +# static const int msgidx[]; +# A list of index numbers, one for each message, that points to the +# beginning of the string in msgstr. +# +# msgidxof (code); +# A macro that maps code numbers to idx numbers. If a DEFAULT MESSAGE +# is provided (see below), its index will be returned for unknown codes. +# Otherwise -1 is returned for codes that do not appear in the list. +# You can lookup the message with code CODE with: +# msgstr + msgidx[msgidxof (code)]. +# +# The input file has the following format: +# CODE1 MESSAGE1 (Code number, <tab>, message string) +# CODE2 MESSAGE2 (Code number, <tab>, message string) +# ... +# CODEn MESSAGEn (Code number, <tab>, message string) +# DEFAULT MESSAGE (<tab>, fall-back message string) +# +# Comments (starting with # and ending at the end of the line) are removed, +# as is trailing whitespace. The last line is optional; if no DEFAULT +# MESSAGE is given, msgidxof will return the number -1 for unknown +# index numbers. + +BEGIN { +# msg holds the number of messages. + msg = 0; + print "/* Output of mkerrcodes2.awk. DO NOT EDIT. */"; + print ""; + header = 1; +} + +/^#/ { next; } + +header { + if ($1 ~ /^[0123456789]+$/) + { + print "static const int err_code_from_index[] = {"; + header = 0; + } + else + print; +} + +!header { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + +# Print the string msgstr line by line. We delay output by one line to be able +# to treat the last line differently (see END). + print " " $2 ","; + +# Remember the error value and index of each error code. + code[msg] = $1; + pos[msg] = $2; + msg++; +} +END { + print "};"; + print ""; + print "#define errno_to_idx(code) (0 ? -1 \\"; + +# Gather the ranges. + skip = code[0]; + start = code[0]; + stop = code[0]; + for (i = 1; i < msg; i++) + { + if (code[i] == stop + 1) + stop++; + else + { + print " : ((code >= " start ") && (code <= " stop ")) ? (code - " \ + skip ") \\"; + skip += code[i] - stop - 1; + start = code[i]; + stop = code[i]; + } + } + print " : ((code >= " start ") && (code <= " stop ")) ? (code - " \ + skip ") \\"; + print " : -1)"; +} diff --git a/libtdenetwork/libgpg-error-copy/mkerrnos.awk b/libtdenetwork/libgpg-error-copy/mkerrnos.awk new file mode 100644 index 00000000..3f7664ad --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/mkerrnos.awk @@ -0,0 +1,97 @@ +# mkerrnos.awk +# Copyright (C) 2003, 2004 g10 Code GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception, g10 Code GmbH gives unlimited permission to +# copy, distribute and modify the C source files that are the output +# of mkerrnos.awk. You need not follow the terms of the GNU General +# Public License when using or distributing such scripts, even though +# portions of the text of mkerrnos.awk appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the mkerrnos.awk program. +# +# Certain portions of the mkerrnos.awk source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# mkerrnos.awk. We call these the "data" portions. The rest of the +# mkerrnos.awk source text consists of comments plus executable code +# that decides which of the data portions to output in any given case. +# We call these comments and executable code the "non-data" portions. +# mkerrnos.h never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of mkerrnos.awk +# released by g10 Code GmbH. When you make and distribute a modified version +# of mkerrnos.awk, you may extend this special exception to the GPL to +# apply to your modified version as well, *unless* your modified version +# has the potential to copy into its output some of the text that was the +# non-data portion of the version that you started with. (In other words, +# unless your change moves or copies text from the non-data portions to the +# data portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified version. + +# This script outputs a source file that does define the following +# symbols: +# +# static const int err_code_to_errno[]; +# A mapping of gpg_err_code_t numbers to system errno. The index of an +# error code in the table can be obtained after removing the system error +# code indication bit. +# +# The input file is a list of possible system errors in the column errnoidx +# (defaults to 2). +# +# Comments (starting with # and ending at the end of the line) are removed, +# as is trailing whitespace. + +BEGIN { + FS="[\t]+"; + header = 1; + if (errnoidx == 0) + errnoidx = 2; + + print "/* Output of mkerrnos.awk. DO NOT EDIT. */"; + print ""; +} + +/^#/ { next; } + +header { + if ($1 ~ /^[0-9]/) + { + print "#include <errno.h>"; + print ""; + print "static const int err_code_to_errno [] = {"; + header = 0; + } + else + print; +} + +!header { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + + print "#ifdef " $errnoidx; + print " " $errnoidx ","; + print "#else"; + print " 0,"; + print "#endif"; +} +END { + print "};"; +} diff --git a/libtdenetwork/libgpg-error-copy/mkheader.awk b/libtdenetwork/libgpg-error-copy/mkheader.awk new file mode 100644 index 00000000..74d36919 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/mkheader.awk @@ -0,0 +1,190 @@ +# mkheader.awk +# Copyright (C) 2003, 2004 g10 Code GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception, g10 Code GmbH gives unlimited permission to +# copy, distribute and modify the C source files that are the output +# of mkheader.awk. You need not follow the terms of the GNU General +# Public License when using or distributing such scripts, even though +# portions of the text of mkheader.awk appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the mkheader.awk program. +# +# Certain portions of the mkheader.awk source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# mkheader.awk. We call these the "data" portions. The rest of the +# mkheader.awk source text consists of comments plus executable code +# that decides which of the data portions to output in any given case. +# We call these comments and executable code the "non-data" portions. +# mkheader.h never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of mkheader.awk +# released by g10 Code GmbH. When you make and distribute a modified version +# of mkheader.awk, you may extend this special exception to the GPL to +# apply to your modified version as well, *unless* your modified version +# has the potential to copy into its output some of the text that was the +# non-data portion of the version that you started with. (In other words, +# unless your change moves or copies text from the non-data portions to the +# data portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified version. + +# This script processes gpg-error.h.in in an awful way. +# Its input is, one after another, the content of the err-sources.h.in file, +# the err-codes.h.in file, the errnos.in file, and then gpg-error.h.in. +# There is nothing fancy about this. +# +# An alternative would be to use getline to get the content of the first three files, +# but then we need to pre-process gpg-error.h.in with configure to get +# at the full path of the files in @srcdir@. + +BEGIN { + FS = "[\t]+"; +# sources_nr holds the number of error sources. + sources_nr = 0; +# codes_nr holds the number of error codes. + codes_nr = 0; +# errnos_nr holds the number of system errors. + errnos_nr = 0; + +# These variables walk us through our input. + sources_header = 1; + sources_body = 0; + between_sources_and_codes = 0; + codes_body = 0; + between_codes_and_errnos = 0; + errnos_body = 0; + gpg_error_h = 0; + + print "/* Output of mkheader.awk. DO NOT EDIT. */"; + print ""; + +} + +sources_header { + if ($1 ~ /^[0123456789]+$/) + { + sources_header = 0; + sources_body = 1; + } +} + +sources_body { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + + if ($1 == "") + { + sources_body = 0; + between_sources_and_codes = 1; + } + else + { +# Remember the error source number and symbol of each error source. + sources_idx[sources_nr] = $1; + sources_sym[sources_nr] = $2; + sources_nr++; + } +} + +between_sources_and_codes { + if ($1 ~ /^[0123456789]+$/) + { + between_sources_and_codes = 0; + codes_body = 1; + } +} + +codes_body { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + + if ($1 == "") + { + codes_body = 0; + between_codes_and_errnos = 1; + } + else + { +# Remember the error code number and symbol of each error source. + codes_idx[codes_nr] = $1; + codes_sym[codes_nr] = $2; + codes_nr++; + } +} + +between_codes_and_errnos { + if ($1 ~ /^[0-9]/) + { + between_codes_and_errnos = 0; + errnos_body = 1; + } +} + +errnos_body { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + + if ($1 !~ /^[0-9]/) + { +# Note that this assumes that gpg-error.h.in doesn't start with a digit. + errnos_body = 0; + gpg_error_h = 1; + } + else + { + errnos_idx[errnos_nr] = "GPG_ERR_SYSTEM_ERROR | " $1; + errnos_sym[errnos_nr] = "GPG_ERR_" $2; + errnos_nr++; + } +} + +gpg_error_h { + if ($0 ~ /^@include err-sources/) + { + for (i = 0; i < sources_nr; i++) + { + print " " sources_sym[i] " = " sources_idx[i] ","; +# print "#define " sources_sym[i] " (" sources_idx[i] ")"; + } + } + else if ($0 ~ /^@include err-codes/) + { + for (i = 0; i < codes_nr; i++) + { + print " " codes_sym[i] " = " codes_idx[i] ","; +# print "#define " codes_sym[i] " (" codes_idx[i] ")"; + } + } + else if ($0 ~ /^@include errnos/) + { + for (i = 0; i < errnos_nr; i++) + { + print " " errnos_sym[i] " = " errnos_idx[i] ","; +# print "#define " errnos_sym[i] " (" errnos_idx[i] ")"; + } + } + else + print; +} diff --git a/libtdenetwork/libgpg-error-copy/mkstrtable.awk b/libtdenetwork/libgpg-error-copy/mkstrtable.awk new file mode 100644 index 00000000..6339dbe7 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/mkstrtable.awk @@ -0,0 +1,186 @@ +# mkstrtable.awk +# Copyright (C) 2003, 2004 g10 Code GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception, g10 Code GmbH gives unlimited permission to +# copy, distribute and modify the C source files that are the output +# of mkstrtable.awk. You need not follow the terms of the GNU General +# Public License when using or distributing such scripts, even though +# portions of the text of mkstrtable.awk appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the mkstrtable.awk program. +# +# Certain portions of the mkstrtable.awk source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# mkstrtable.awk. We call these the "data" portions. The rest of the +# mkstrtable.awk source text consists of comments plus executable code +# that decides which of the data portions to output in any given case. +# We call these comments and executable code the "non-data" portions. +# mkstrtable.h never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of mkstrtable.awk +# released by g10 Code GmbH. When you make and distribute a modified version +# of mkstrtable.awk, you may extend this special exception to the GPL to +# apply to your modified version as well, *unless* your modified version +# has the potential to copy into its output some of the text that was the +# non-data portion of the version that you started with. (In other words, +# unless your change moves or copies text from the non-data portions to the +# data portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified version. + +# This script outputs a source file that does define the following +# symbols: +# +# static const char msgstr[]; +# A string containing all messages in the list. +# +# static const int msgidx[]; +# A list of index numbers, one for each message, that points to the +# beginning of the string in msgstr. +# +# msgidxof (code); +# A macro that maps code numbers to idx numbers. If a DEFAULT MESSAGE +# is provided (see below), its index will be returned for unknown codes. +# Otherwise -1 is returned for codes that do not appear in the list. +# You can lookup the message with code CODE with: +# msgstr + msgidx[msgidxof (code)]. +# +# The input file has the following format: +# CODE1 ... MESSAGE1 (code nr, <tab>, something, <tab>, msg) +# CODE2 ... MESSAGE2 (code nr, <tab>, something, <tab>, msg) +# ... +# CODEn ... MESSAGEn (code nr, <tab>, something, <tab>, msg) +# ... DEFAULT-MESSAGE (<tab>, something, <tab>, fall-back msg) +# +# Comments (starting with # and ending at the end of the line) are removed, +# as is trailing whitespace. The last line is optional; if no DEFAULT +# MESSAGE is given, msgidxof will return the number -1 for unknown +# index numbers. +# +# The field to be used is specified with the variable "textidx" on +# the command line. It defaults to 2. +# +# The variable nogettext can be set to 1 to suppress gettext markers. +# +# The variable prefix can be used to prepend a string to each message. +# +# The variable namespace can be used to prepend a string to each +# variable and macro name. + +BEGIN { + FS = "[\t]+"; +# cpos holds the current position in the message string. + cpos = 0; +# msg holds the number of messages. + msg = 0; + print "/* Output of mkstrtable.awk. DO NOT EDIT. */"; + print ""; + header = 1; + if (textidx == 0) + textidx = 2; +# nogettext can be set to 1 to suppress gettext noop markers. +} + +/^#/ { next; } + +header { + if ($1 ~ /^[0123456789]+$/) + { + print "/* The purpose of this complex string table is to produce"; + print " optimal code with a minimum of relocations. */"; + print ""; + print "static const char " namespace "msgstr[] = "; + header = 0; + } + else + print; +} + +!header { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + +# Print the string msgstr line by line. We delay output by one line to be able +# to treat the last line differently (see END). + if (last_msgstr) + { + if (nogettext) + print " \"" last_msgstr "\" \"\\0\""; + else + print " gettext_noop (\"" last_msgstr "\") \"\\0\""; + } + last_msgstr = prefix $textidx; + +# Remember the error code and msgidx of each error message. + code[msg] = $1; + pos[msg] = cpos; + cpos += length (last_msgstr) + 1; + msg++; + + if ($1 == "") + { + has_default = 1; + exit; + } +} +END { + if (has_default) + coded_msgs = msg - 1; + else + coded_msgs = msg; + + if (nogettext) + print " \"" prefix last_msgstr "\";"; + else + print " gettext_noop (\"" prefix last_msgstr "\");"; + print ""; + print "static const int " namespace "msgidx[] ="; + print " {"; + for (i = 0; i < coded_msgs; i++) + print " " pos[i] ","; + print " " pos[coded_msgs]; + print " };"; + print ""; + print "#define " namespace "msgidxof(code) (0 ? -1 \\"; + +# Gather the ranges. + skip = code[0]; + start = code[0]; + stop = code[0]; + for (i = 1; i < coded_msgs; i++) + { + if (code[i] == stop + 1) + stop++; + else + { + print " : ((code >= " start ") && (code <= " stop ")) ? (code - " \ + skip ") \\"; + skip += code[i] - stop - 1; + start = code[i]; + stop = code[i]; + } + } + print " : ((code >= " start ") && (code <= " stop ")) ? (code - " \ + skip ") \\"; + if (has_default) + print " : " stop + 1 " - " skip ")"; + else + print " : -1)"; + + } diff --git a/libtdenetwork/libgpg-error-copy/strerror.c b/libtdenetwork/libgpg-error-copy/strerror.c new file mode 100644 index 00000000..59b8e9ae --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/strerror.c @@ -0,0 +1,169 @@ +/* strerror.c - Describing an error code. + Copyright (C) 2003 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <gpg-error.h> + +#include "gettext.h" +#include "err-codes.h" + +/* Return a pointer to a string containing a description of the error + code in the error value ERR. This function is not thread-safe. */ +const char * +gpg_strerror (gpg_error_t err) +{ + gpg_err_code_t code = gpg_err_code (err); + + if (code & GPG_ERR_SYSTEM_ERROR) + { + int no = gpg_err_code_to_errno (code); + if (no) + return strerror (no); + else + code = GPG_ERR_UNKNOWN_ERRNO; + } + return dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]); +} + + +#ifdef HAVE_STRERROR_R +#ifdef STRERROR_R_CHAR_P +/* The GNU C library and probably some other systems have this weird + variant of strerror_r. */ + +/* Return a dynamically allocated string in *STR describing the system + error NO. If this call succeeds, return 1. If this call fails due + to a resource shortage, set *STR to NULL and return 1. If this + call fails because the error number is not valid, don't set *STR + and return 0. */ +static int +system_strerror_r (int no, char *buf, size_t buflen) +{ + char *errstr; + + errstr = strerror_r (no, buf, buflen); + if (errstr != buf) + { + size_t errstr_len = strlen (errstr) + 1; + size_t cpy_len = errstr_len < buflen ? errstr_len : buflen; + memcpy (buf, errstr, cpy_len); + + return cpy_len == errstr_len ? 0 : ERANGE; + } + else + { + /* We can not tell if the buffer was large enough, but we can + try to make a guess. */ + if (strlen (buf) + 1 >= buflen) + return ERANGE; + + return 0; + } +} + +#else /* STRERROR_R_CHAR_P */ +/* Now the POSIX version. */ + +static int +system_strerror_r (int no, char *buf, size_t buflen) +{ + return strerror_r (no, buf, buflen); +} + +#endif /* STRERROR_R_CHAR_P */ + +#else /* HAVE_STRERROR_H */ +/* Without strerror_r(), we can still provide a non-thread-safe + version. Maybe we are even lucky and the system's strerror() is + already thread-safe. */ + +static int +system_strerror_r (int no, char *buf, size_t buflen) +{ + char *errstr = strerror (no); + + if (!errstr) + { + int saved_errno = errno; + + if (saved_errno != EINVAL) + snprintf (buf, buflen, "strerror failed: %i\n", errno); + return saved_errno; + } + else + { + size_t errstr_len = strlen (errstr) + 1; + size_t cpy_len = errstr_len < buflen ? errstr_len : buflen; + memcpy (buf, errstr, cpy_len); + return cpy_len == errstr_len ? 0 : ERANGE; + } +} +#endif + + +/* Return the error string for ERR in the user-supplied buffer BUF of + size BUFLEN. This function is, in contrast to gpg_strerror, + thread-safe if a thread-safe strerror_r() function is provided by + the system. If the function succeeds, 0 is returned and BUF + contains the string describing the error. If the buffer was not + large enough, ERANGE is returned and BUF contains as much of the + beginning of the error string as fits into the buffer. */ +int +gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen) +{ + gpg_err_code_t code = gpg_err_code (err); + const char *errstr; + size_t errstr_len; + size_t cpy_len; + + if (code & GPG_ERR_SYSTEM_ERROR) + { + int no = gpg_err_code_to_errno (code); + if (no) + { + int system_err = system_strerror_r (no, buf, buflen); + + if (system_err != EINVAL) + { + if (buflen) + buf[buflen - 1] = '\0'; + return system_err; + } + } + code = GPG_ERR_UNKNOWN_ERRNO; + } + + errstr = dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]); + errstr_len = strlen (errstr) + 1; + cpy_len = errstr_len < buflen ? errstr_len : buflen; + memcpy (buf, errstr, cpy_len); + if (buflen) + buf[buflen - 1] = '\0'; + + return cpy_len == errstr_len ? 0 : ERANGE; +} diff --git a/libtdenetwork/libgpg-error-copy/strsource.c b/libtdenetwork/libgpg-error-copy/strsource.c new file mode 100644 index 00000000..95614358 --- /dev/null +++ b/libtdenetwork/libgpg-error-copy/strsource.c @@ -0,0 +1,37 @@ +/* strsource.c - Describing an error source. + Copyright (C) 2003 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + libgpg-error is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libgpg-error; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gpg-error.h> + +#include "gettext.h" +#include "err-sources.h" + +/* Return a pointer to a string containing a description of the error + source in the error value ERR. */ +const char * +gpg_strsource (gpg_error_t err) +{ + gpg_err_source_t source = gpg_err_source (err); + return dgettext (PACKAGE, msgstr + msgidx[msgidxof (source)]); +} diff --git a/libtdenetwork/libgpgme-copy/Makefile.am b/libtdenetwork/libgpgme-copy/Makefile.am new file mode 100644 index 00000000..34527396 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = assuan gpgme diff --git a/libtdenetwork/libgpgme-copy/assuan/ChangeLog b/libtdenetwork/libgpgme-copy/assuan/ChangeLog new file mode 100644 index 00000000..b53ac7fd --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/ChangeLog @@ -0,0 +1,829 @@ +2006-11-22 Werner Koch <wk@g10code.com> + + * assuan-handler.c (fun1_cookie_write, fun2_cookie_write): New. + (assuan_get_data_fp) [HAVE_FUNOPEN]: Use it. + +2006-11-21 Werner Koch <wk@g10code.com> + + * Makefile.am (libassuan_pth_a_CFLAGS): New. + + * assuan-pipe-server.c (_assuan_release_context): Free CMDTBL. + +2006-11-14 Werner Koch <wk@g10code.com> + + * libassuan.m4 (AM_CHECK_LIBASSUAN): New. + + * assuan-handler.c (assuan_register_post_cmd_notify) + (assuan_register_post_cmd_notify): New. + * assuan-util.c (assuan_set_io_monitor): New. + * assuan-buffer.c (_assuan_read_line): Use it. + (_assuan_write_line): Ditto. + (_assuan_cookie_write_data): Ditto. + (_assuan_cookie_write_flush): Ditto. + +2006-10-18 Werner Koch <wk@g10code.com> + + * libassuan.m4: Pass "pthread" to the common macro. Reported by + Rex Dieter. + +2006-10-16 Werner Koch <wk@g10code.com> + + * mkerrors: Map ASSUAN_Not_Confirmed. + +2006-10-10 Werner Koch <wk@g10code.com> + + * libassuan.m4 (AM_PATH_LIBASSUAN_PTH) + (AM_PATH_LIBASSUAN_PTHREAD): Fixed. + + * assuan-buffer.c (assuan_sendfd): Implement a runtime detection + of implemented descripotr passing. + + * assuan-uds.c: Take care of USE_DESCRIPTOR_PASSING. + + * assuan-defs.h: Add missing semicolon. + +2006-10-09 Werner Koch <wk@g10code.com> + + * assuan-handler.c (process_request): Use weak pragma for the sake + of old gcc's. Reported by Alain Guibert. + + * assuan-io.c: Removed Pth support. + * assuan-io-pth.c: New. Based on assuan-io.c + +2006-10-06 Werner Koch <wk@g10code.com> + + * libassuan-config.in: New options --api-version and --thread. + +2006-10-04 Werner Koch <wk@g10code.com> + + * assuan-client.c (assuan_transact): Need to map old assuan status + codes so that for example CANCELED is correctly mapped. + +2006-09-28 Marcus Brinkmann <marcus@g10code.de> + + * assuan-client.c (assuan_transact): Do not convert error on + status line, it is already a gpg-error. Do convert + ASSUAN_Server_Fault. + +2006-09-19 Marcus Brinkmann <marcus@g10code.de> + + * assuan.h (assuan_init_socket_server_ext) + [_ASSUAN_EXT_SYM_PREFIX]: Fix typo in macro. + +2006-09-19 Werner Koch <wk@g10code.com> + + * assuan-defs.h (putc_unlocked): Add prototype. + + * assuan-socket-server.c (accept_connection): Made LEN a socklen_t. + + * assuan.h: Replaced assuan error code enum by simple defines and + made assuan_error_t an int. + * mkerrors: Changed parser accordingly. + +2006-09-19 Marcus Brinkmann <marcus@g10code.de> + + * assuan-pipe-connect.c: Add hacks for Slowaris. + * assuan-socket.c: Likewise here. + + * assuan.h (enum): Avoid trailing comma in enumerator list. Ugh. + + * mkerrors (_assuan_error): Change return type to assuan_error_t. + * assuan-buffer.c (_assuan_read_line): Change return type to + assuan_error_t. Map returned value of -1. + (_assuan_write_line): Change type of RC to assuan_error_t. + * assuan-defs.h (_assuan_read_line, _assuan_error): Likewise for + prototypes. + + * assuan-defs.h (unsetenv): Define correctly. + +2006-09-14 Werner Koch <wk@g10code.com> + + * assuan-io.c (_assuan_waitpid): New. Changed all waitpid calls + to this. + + * assuan.h (_ASSUAN_DEPRECATED): New internal macro. + (assuan_pipe_connect2): Declare deprecated. + (assuan_init_connected_socket_server): Declare deprecated. + + * assuan-connect.c (assuan_get_peercred): New. + * assuan-socket-server.c (accept_connection_bottom): Save uid and gid. + +2006-09-13 Werner Koch <wk@g10code.com> + + * assuan-client.c (assuan_transact): Need to map the error code. + * mkerrors: Need to map ASSUAN_No_Secret_Key. + + * assuan-pipe-server.c (is_valid_socket): New. + (assuan_init_pipe_server): Use UDS with the environmet variable is + set and a valid descriptor is given. Ignore FILEDES in this case. + + * assuan-socket-server.c (assuan_init_socket_server_ext): New. + Changed other init fucntions to make use of it. + + * assuan-handler.c (assuan_command_parse_fd): Allow for lowercase + "fd". + (std_handler_reset): Close pending fds. + * assuan-uds.c (uds_receivefd): Fixed. + (_assuan_uds_close_fds): New. + + * assuan-socket-connect.c (assuan_socket_connect_ext): New. Takes + all code of assuan_socket_connect plus an option to use sendmsg. + * assuan-pipe-connect.c (assuan_pipe_connect_ext): New arg FLAGS. + +2006-09-12 Werner Koch <wk@g10code.com> + + * assuan-buffer.c (_assuan_write_line): Also log the prefix. + + * assuan-defs.h (DIM, DIMof): New. + + * assuan-domain-server.c: Removed. + * assuan-domain-connect.c: Renamed to .. + * assuan-uds.c: this. + (domain_reader, domain_writer, domain_sendfd, domain_receivefd) + (assuan_domain_connect, _assuan_domain_init): Removed. + (uds_reader, uds_writer, uds_sendfd, uds_receivefd) + (_assuan_init_uds_io): New. + (_assuan_uds_deinit): New. + + * assuan-io.c (_assuan_simple_sendmsg, _assuan_simple_recvmsg): New. + (my_pth_fdmode, my_pth_select): New. + +2006-09-11 Werner Koch <wk@g10code.com> + + * assuan-pipe-server.c (assuan_init_pipe_server): Allow for + FILEDES to be NULL and try to start as a socketpair server in this + case. + + * assuan-pipe-connect.c (assuan_pipe_connect2): Split up into two + functions (unix and w32) for clarity. + (pipe_connect_unix): This is the new fucntion. Add USE_CMSG flag. + (pipe_connect_w32): Ditto. + (initial_handshake): Factored out code. + (socketpair_connect): New. + (assuan_pipe_connect_ext): New. + (do_finish): Handle case if outbound and inbound fd are the same. + This is to support socketpairs. + +2006-09-10 Werner Koch <wk@g10code.com> + + * assuan-util.c (_assuan_log_print_buffer) + (_assuan_log_sanitized_string,assuan_set_log_stream): Moved to .. + * assuan-logging.c: .. here. + (_assuan_log_print_buffer): Only print the leading bytes in hex + log mode unless the new env variable ASSUAN_FULL_LOGGING has been + set. + (_assuan_set_default_log_stream): Test this env variable. + +2006-09-06 Werner Koch <wk@g10code.com> + + * assuan.h (_ASSUAN_ONLY_GPG_ERRORS): New. + + * assuan-handler.c (dispatch_command): Use Syntax_Error instead of + Invalid_Command. + + * assuan-domain-connect.c: Changed alloc malloc/free/realloc to + xtrymalloc et al. + (read_int, write_int): Make args void pointers. + (domain_receivefd): Take care of realloc shrinking failure. + + * assuan-buffer.c (_assuan_read_line, _assuan_write_line) + (assuan_write_line, _assuan_cookie_write_data) + (_assuan_cookie_write_flush): Print the inbound fd instead of the + address of the context when logging I/0. This makes it more + readable. + +2006-09-05 Werner Koch <wk@g10code.com> + + * assuan-defs.h (err_code, err_is_eof): New. + + * mkerrors (_assuan_error): New. Wrapped all error code + assignments in a call to this. + (assuan_strerror): Map gpg-style error codes back. Also print a + string for the old EOF code. + (assuan_set_assuan_err_source): New. + + * assuan-logging.c (_assuan_log_printf): Do not change ERRNO and + print the pid. + + * assuan-domain-connect.c (domain_reader): Replaced plain printf + by assuan_log function. + +2005-10-24 Werner Koch <wk@g10code.com> + + * putc_unlocked.c, memrchr.c, isascii.c, funopen.c: Changed + distribution terms to LGPL. This are small and trivial files so + there are no obstacles of doing so. + * assuan-socket.c: Likewise, the stated GPL was not intended. + +2005-10-08 Marcus Brinkmann <marcus@g10code.de> + + * assuan-defs.h (setenv, unsetenv, clearenv) [!HAVE_SETENV]: + Define to _assuan_*. + * setenv.c: Include "assuan-defs.h". + (__add_to_environ): Make static. + +2005-10-07 Marcus Brinkmann <marcus@g10code.de> + + * assuan-defs.h (memrchr) [!HAVE_MEMRCHR]: New prototype. + (stpcpy) [!HAVE_STPCPY]: Likewise. + * stpcpy.c: New LGPL'ed file from the GNU C Library. + * setenv.c: New file. + * assuan-domain-connect.c (read_int): New function. + (write_int): New function. + (domain_reader): Use read_int. + (domain_sendfd): Use write_int. + +2005-10-01 Marcus Brinkmann <marcus@g10code.de> + + * assuan.h (assuan_pipe_connect, assuan_pipe_connect2): Make type + of ARGV parameter const in prototype. + * assuan-pipe-connect.c (assuan_pipe_connect, + assuan_pipe_connect2): Likewise in declaration. + (assuan_pipe_connect2): Add braindead cast to make execv happy. + + * assuan-client.c (assuan_transact): Change LINE, S and D from + unsigned char * to char * to silence gcc warning. + * assuan-util.c (_assuan_log_sanitized_string): Add explicit cast + to silence gcc warning. + * assuan-inquire.c (assuan_inquire): Likewise. + +2005-08-19 Werner Koch <wk@g10code.com> + + * funopen.c, assuan-socket.c: Copied from libassuan CVS. + * assuan-pipe-connect.c (assuan_pipe_connect2): Add missing + declaration of PID. + +2005-08-09 Werner Koch <wk@g10code.com> + + * README.1st: Adjusted to cope with changes done in upstream Assuan. + + Merged changes for W32 support from libassuan. + + * assuan.h [_ASSUAN_EXT_SYM_PREFIX]: New. + * assuan-io.c [_ASSUAN_NO_PTH]: New. + * assuan-pipe-connect.c (fix_Q_SIGNALS) [_ASSUAN_NO_FIXED_SIGNALS]: New. + (assuan_pipe_connect2) [_ASSUAN_USE_DOUBLE_FORK]: Use double fork. + (fix_Q_SIGNALS) [_ASSUAN_USE_DOUBLE_FORK]: Do not wait.. + * assuan-logging.c, assuan-io.c: Include config.h + Replaced all usages of _WIN32 by the new HAVE_W32_SYSTEM because + there is nothing winning in this API. + * assuan-pipe-connect.c (assuan_pipe_connect2) [_WIN32]: Return + error Not Imlemented. + * assuan-logging.c (_assuan_w32_strerror): New. + * assuan-defs.h (w32_strerror): new. + * assuan-pipe-connect.c (assuan_pipe_connect2, fix_Q_SIGNALS): + Factored signal code out to new function. + (build_w32_commandline, create_inheritable_pipe): New. Taken + from gnupg 1.9. + (assuan_pipe_connect2) [W32]: Implemented for W32. + * assuan-pipe-server.c (assuan_init_pipe_server) [W32]: Map file + descriptors using _get_osfhandle. + * assuan-socket-connect.c (assuan_socket_connect) [W32]: Allow for + a drive letter in the path. + * assuan-client.c (assuan_transact): Handle empty and comment + commands correctly. + * assuan-util.c (_assuan_calloc): Avoid integer overflow. + * assuan-util.c (assuan_set_flag, assuan_get_flag): New. + * assuan-defs.h (struct assuan_context_s): New field flags. + * assuan.h (assuan_flag_t): New with one flag value + ASSUAN_NO_WAITPID for now. + * assuan-pipe-connect.c (do_finish): Take care of the no_waitpid + flag. + * mkerrors: Include config.h into assuan-errors.c. This is + required so that assuan.h knows about the W32 macro. + +2005-08-09 Timo Schulz <twoaday@g10code.com> (ported from libassuan by wk) + + * assuan-io.c (_assuan_simple_read, _assuan_simple_write): W32 + support. + * assuan-socket.c (_assuan_close): New. + (_assuan_sock_new): New. + (_assuan_sock_bind): New. + +2005-03-22 Werner Koch <wk@g10code.com> + + * assuan-defs.h (struct assuan_io): Renamed elements READ and + WRITE to READFNC and WRITEFNC to avoid problems with read defined + as macro. Changed callers. Noted by Ville Skyttä. + +2004-12-16 Marcus Brinkmann <marcus@g10code.de> + + * assuan-pipe-connect.c (do_finish): Do not wait for child to finish. + (assuan_pipe_connect): Use double-fork approach. + * assuan-connect.c (assuan_disconnect): Do not write BYE to the + status line. + +2004-12-07 Marcus Brinkmann <marcus@g10code.de> + + * README.1st: Add copyright notice. + +2004-06-23 Marcus Brinkmann <marcus@g10code.de> + + * assuan-domain-connect.c [HAVE_SYS_UIO_H]: Include <sys/uio.h>. + + * assuan-handler.c: Include <errno.h>. + +2004-06-08 Marcus Brinkmann <marcus@g10code.de> + + * assuan-buffer.c (assuan_write_line): If the line is longer than + the maximum line length, bail out early. + +2004-04-19 Werner Koch <wk@gnupg.org> + + * assuan-socket-connect.c: Include sys/types.h + * assuan-socket-server.c: Ditto + * assuan-domain-connect.c: Ditto. + +2004-02-18 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_get_data_fp): Fail with ENOSYS if we + can't implement this. + +2004-02-13 Werner Koch <wk@gnupg.org> + + * assuan-domain-connect.c: Removed the unneeded alloca.h + +2003-08-13 Werner Koch <wk@gnupg.org> + + * assuan-inquire.c (assuan_inquire): Increase length of cmdbuf to + the Assuan limit. + +2003-06-24 Werner Koch <wk@gnupg.org> + + * mkerrors: Kludge to print libgpg-error values in an easier + readable way. + +2003-04-29 Werner Koch <wk@gnupg.org> + + * libassuan.m4: New. Based on libgrypt.m4. + * Makefile.am (m4data_DATA): New. + + * assuan.h (AssuanCommand): Removed. + + * assuan-handler.c: Remove the cmd_id element, + (assuan_register_command): Likewise. Note that semantics changed. + (_assuan_register_std_commands): Adjusted. + +2003-02-22 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (bin_SCRIPTS): Renamed from bin_PROGRAMS. + +2003-02-18 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (libassuan_a_LIBADD): New variable. + * funopen.c: Move from ../common. + * isascii.c: Likewise. + * memrchr.c: Likewise. + * putc_unlocked.c: Likewise. + +2003-02-18 Neal H. Walfield <neal@g10code.de> + + * assuan-handler.c (_IO_cookie_io_functions_t): Remove. + (cookie_io_functions_t): Remove. + (fopencookie): Remove prototype. + (assuan_get_data_fp): Use funopen, not fopencookie. + +2003-02-18 Neal H. Walfield <neal@g10code.de> + + * libassuan-config.in: New file. + * Makefile.am (bin_PROGRAMS): New variable. + +2003-02-17 Neal H. Walfield <neal@g10code.de> + + * .cvsignore: New file. + +2003-02-17 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (lib_LIBRARIES): Use this instead of . . . + (noinst_LIBRARIES): . . . this. + (include_HEADERS): New variable. + (libassuan_a_SOURCES): Remove assuan.h, add assuan-logging.c. + + * assuan.h (assuan_set_assuan_log_stream): New prototype. + (assuan_get_assuan_log_stream): Likewise. + (assuan_get_assuan_log_prefix): Likewise. + * assuan-logging.c: New file. + + * assuan-buffer.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (my_log_prefix): Remove function. + (_assuan_read_line): Use assuan_get_assuan_log_prefix in lieu of + my_log_prefix. + (assuan_write_line): Likewise. + (_assuan_cookie_write_data): Likewise. + (_assuan_cookie_write_flush): Likewise. + * assuan-domain-connect.c (LOGERROR, LOGERROR1, LOGERROR2, + LOGERRORX): Remove. + (LOG): New macro. + (domain_reader): Use it. + (domain_writer): Likewise. + (domain_sendfd): Likewise. + (domain_receivefd): Likewise. + (_assuan_domain_init): Likewise. + (assuan_domain_connect): Likewise. + * assuan-pipe-connect.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove. + (LOG): New macro. + (assuan_pipe_connect): Use it. + * assuan-socket-connect.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove. + (LOG): New macro. + (assuan_socket_connect): Use it. + (socket_reader): Remove dead code. + (socket_writer): Likewise. + * assuan-util.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (_assuan_log_sanitized_string): Use assuan_get_assuan_log_stream, + not jnlib. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan.h (assuan_command_parse_fd): New prototype. + * assuan-handler.c (assuan_command_parse_fd): Rename from + parse_cmd_input_output. Export. + (std_handler_input): Update to use assuan_command_parse_fd. + (std_handler_output): Likewise. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan.h (assuan_sendfd): New prototype. + (assuan_receivefd): New prototype. + * assuan-buffer.c (assuan_sendfd): New function. + (assuan_receivefd): New function. + * assuan-handler.c (parse_cmd_input_output): Recognize incoming + file descriptors and act appropriately. + * assuan-defs.h (struct assuan_io): Add fields sendfd and + receivefd. + (struct assuan_context_s): Add fields pendingfds and + pendingfdscount. + * assuan-pipe-server.c (_assuan_new_context): Update IO to reflect + new features. + * assuan-domain-connect.c (do_deinit): Cleanup any unreceived file + descriptors. + (domain_reader): Receive file descriptors. + (domain_sendfd): New function. + (domain_receivefd): New function. + (_assuan_domain_init): Update initialization code to reflect new + features. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan-domain-connect.c (do_finish): Remove. + (_assuan_domain_init): Use default handlers where possible. + Add an assert and update comments. + * assuan-domain-server.c (accept_connection): Remove. + (assuan_init_domain_server): Use default handlers where possible. + Put the server in pipe mode: it can only be used by a single + client. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan.h: Add prototype for assuan_domain_connect and + assuan_init_domain_server. + * assuan-defs.h: Include <unistd.h>. + Add prototype for _assuan_domain_init. + * assuan-domain-connect.c: New file. + * assuan-domain-server.c: New file. + * Makefile.am (libassuan_a_SOURCES): Add assuan-domain-connect.c + and assuan-domain-server.c + +2002-11-23 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (libassuan_a_SOURCES): Add assuan-io.c. + * assuan-io.c: Restore. + (_assuan_simple_read): Rename from _assuan_read. + (_assuan_simple_write): Rename from _assuan_write. + * assuan-defs.h (_assuan_simple_read): New prototype. + (_assuan_simple_write): Likewise. + * assuan-pipe-server.c (pipe_reader): Remove. + (pipe_writer): Remove. + (_assuan_new_context): Initialize IO is with _assuan_simple_read + and _assuan_simple_write. + * assuan-socket-connect.c (socket_reader): Remove. + (socket_writer): Remove. + (assuan_socket_connect): Initialize IO is with _assuan_simple_read + and _assuan_simple_write. + * assuan-socket-server.c (io): New local variable. + (assuan_init_socket_server): Initialize CTX->io. + (assuan_init_connected_socket_server): Likewise. + +2002-11-23 Neal H. Walfield <neal@g10code.de> + + * assuan-buffer.c (readline): Use memrchr. + (_assuan_read_line): Rewritten to use the string functions. + +2002-11-20 Neal H. Walfield <neal@g10code.de> + + * assuan-socket-connect.c (assuan_socket_connect): Pass PF_LOCAL + to socket(), not AF_UNIX: it expects a PF_* macro and the former + is more portable. + (assuan_socket_connect): Use AF_LOCAL, not AF_UNIX which is more + POSIXy. + +2002-11-20 Neal H. Walfield <neal@g10code.de> + + * assuan-defs.h (struct assuan_io): New structure. + (struct assuan_context_s): New field, io. + (_assuan_read): Depreciated. + (_assuan_write): Likewise. + * assuan-pipe-server.c: Include <unistd.h>. + (pipe_reader): New function. + (pipe_writer): Likewise. + (_assuan_new_context.IO): New local static. Set to pipe_reader + and pipe_writer. Use it to initialize new context. + * assuan-socket-connect.c (socket_reader): New function. + (socket_writer): New function. + (assuan_socket_connect.IO): New local static. Set to socket_reader + and socket_writer. Use it to initialize new context. + * assuan-buffer.c (writen): Take an ASSUAN_CONTEXT rather than a + file descriptor. Do not use _assuan_write but the write method + in the supplied context. + (readline): Likewise for _assuan_read. + (assuan_write_line): When calling writen, pass CTX; not the file + descriptor directly. + (_assuan_cookie_write_data): Likewise. + (_assuan_cookie_write_flush): Likewise. + (_assuan_read_line): Likewise for readline. + * Makefile.am (libassuan_a_SOURCES): Remove assuan-io.c. + * assuan-io.c: Removed. + +2002-11-10 Werner Koch <wk@gnupg.org> + + * assuan-pipe-connect.c (assuan_pipe_connect): Changed the order + of the dups to handle cases where we have already used fd 2 for + other things. + +2002-10-31 Neal H. Walfield <neal@g10code.de> + + * assuan-util.c: Include <ctype.h>. + (_assuan_log_print_buffer): Elide the magic numbers preferring the + standard isfoo functions. Use putc_unlocked where possible. + (_assuan_log_sanitized_string): Rewrite to use putc_unlocked and + the isfoo functions. + +2002-09-05 Neal H. Walfield <neal@g10code.de> + + * assuan-defs.h (_assuan_read_wrapper): Depreciated. + * assuan-util.c (_assuan_read_wrapper): Removed. + * assuan-defs.h (_assuan_write_wrapper): Depreciated. + * assuan-util.c (_assuan_write_wrapper): Removed. + * assuan.h (assuan_set_io_fun): Depreciated. + * assuan-util.c (assuan_set_io_fun): Removed. + + * assuan-defs.h (_assuan_read): New function. + (_assuan_write): Likewise. + * assuan-io.c: New file. + + * assuan-buffer.c (writen): Use _assuan_write rather than doing + the work here. + (readline): Likewise for _assuan_read. + + * Makefile.am (libassuan_a_SOURCES): Add assuan-io.c. + +2002-08-16 Werner Koch <wk@gnupg.org> + + * assuan.h: Renamed Bad_Certificate_Path to Bad_Certificate_Chain. + +2002-07-30 Werner Koch <wk@gnupg.org> + + Changed the license from GPL to LGPL. + +2002-07-23 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (_IO_cookie_io_functions_t): Define it here if + it does not exists. + +2002-06-27 Werner Koch <wk@gnupg.org> + + * assuan-pipe-connect.c (assuan_pipe_connect): No special handling + for the log_fd and stderr. Connect stderr to /dev/null if it + should not be retained. + +2002-06-26 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (assuan_write_line): Make sure we never + accidently print an extra LF. + +2002-05-23 Werner Koch <wk@gnupg.org> + + * assuan-util.c (assuan_set_io_func): New. + * assuan-buffer.c (writen, readline): Use the new functions + instead of pth. + * assuan-socket-server.c (accept_connection): Don't use the + pth_accept - using the assuan included accept code would be a bad + idea within Pth so we don't need a replacement function. + +2002-05-22 Werner Koch <wk@gnupg.org> + + * assuan-socket-server.c (assuan_init_connected_socket_server): New. + (accept_connection): Factored most code out to.. + (accept_connection_bottom): .. new function. + +2002-04-04 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (my_log_prefix): New. Use it for all i/o debug + output. + +2002-03-06 Werner Koch <wk@gnupg.org> + + * assuan-client.c (_assuan_read_from_server): Detect END. + (assuan_transact): Pass it to the data callback. + +2002-02-27 Werner Koch <wk@gnupg.org> + + * assuan-client.c (assuan_transact): Add 2 more arguments to + support status lines. Passing NULL yields the old behaviour. + + * assuan-handler.c (process_request): Flush data lines send + without using the data fp. + +2002-02-14 Werner Koch <wk@gnupg.org> + + * assuan-inquire.c (assuan_inquire): Check for a cancel command + and return ASSUAN_Canceled. Allow for non-data inquiry. + + * assuan.h: Add a few token specific error codes. + +2002-02-13 Werner Koch <wk@gnupg.org> + + * assuan-defs.h (assuan_context_s): New var CLIENT_PID. + * assuan-pipe-server.c (_assuan_new_context): set default value. + * assuan-socket-server.c (accept_connection): get the actual pid. + +2002-02-12 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (writen,readline) [USE_GNU_PT]: Use pth_read/write. + * assuan-socket-server.c (accept_connection) [USE_GNU_PTH]: Ditto. + +2002-02-01 Marcus Brinkmann <marcus@g10code.de> + + * Makefile.am (MOSTLYCLEANFILES): New variable. + +2002-01-23 Werner Koch <wk@gnupg.org> + + * assuan-socket-connect.c (LOGERRORX): and removed typo. + +2002-01-22 Marcus Brinkmann <marcus@g10code.de> + + * assuan-socket-connect.c (LOGERRORX): Reverse arguments to fputs. + +2002-01-21 Werner Koch <wk@gnupg.org> + + * assuan-connect.c: Move all except assuan_get_pid to... + * assuan-pipe-connect.c: this. + (assuan_pipe_disconnect): Removed. + (do_finish, do_deinit): New + (assuan_pipe_connect): and set them into the context. + * assuan-socket-connect.c: New. + + * assuan-util.c (_assuan_log_sanitized_string): New. + + * assuan-pipe-server.c (assuan_init_pipe_server): Factored most + code out to ... + (_assuan_new_context): new func. + (_assuan_release_context): New + * assuan-connect.c (assuan_pipe_connect): Use the new functions. + +2002-01-20 Werner Koch <wk@gnupg.org> + + * assuan.h: Added Invalid Option error code. + + * assuan-handler.c (std_handler_option): New. + (std_cmd_tbl): Add OPTION as standard command. + (assuan_register_option_handler): New. + (dispatch_command): Use case insensitive matching as a fallback. + (my_strcasecmp): New. + +2002-01-19 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (_assuan_read_line): Add output logging. + (assuan_write_line): Ditto. + (_assuan_cookie_write_data): Ditto. + (_assuan_cookie_write_flush): Ditto. + * assuan-util.c (_assuan_log_print_buffer): New. + (assuan_set_log_stream): New. + (assuan_begin_confidential): New. + (assuan_end_confidential): New. + + * assuan-defs.h: Add a few handler variables. + * assuan-pipe-server.c (assuan_deinit_pipe_server): Removed. + (deinit_pipe_server): New. + (assuan_deinit_server): New. Changed all callers to use this. + * assuan-listen.c (assuan_accept): Use the accept handler. + * assuan-handler.c (process_request): Use the close Handler. + * assuan-socket-server.c: New. + +2002-01-14 Werner Koch <wk@gnupg.org> + + * assuan-client.c (_assuan_read_from_server): Skip spaces after + the keyword. + +2002-01-03 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_set_okay_line): New. + (process_request): And use it here. + +2002-01-02 Werner Koch <wk@gnupg.org> + + * assuan-inquire.c (init_membuf,put_membuf,get_membuf): Apply a + hidden 0 behind the buffer so that the buffer can be used as a + string in certain contexts. + +2001-12-14 Marcus Brinkmann <marcus@g10code.de> + + * assuan-connect.c (assuan_pipe_connect): New argument + FD_CHILD_LIST. Don't close those fds. + * assuan.h: Likewise for prototype. + +2001-12-14 Werner Koch <wk@gnupg.org> + + * assuan-listen.c (assuan_close_input_fd): New. + (assuan_close_output_fd): New. + * assuan-handler.c (std_handler_reset): Always close them after a + reset command. + (std_handler_bye): Likewise. + +2001-12-14 Marcus Brinkmann <marcus@g10code.de> + + * assuan-buffer.c (_assuan_read_line): New variable ATTICLEN, use + it to save the length of the attic line. + Rediddle the code a bit to make it more clear what happens. + +2001-12-14 Marcus Brinkmann <marcus@g10code.de> + + * assuan-defs.h (LINELENGTH): Define as ASSUAN_LINELENGTH. + assuan.h: Define ASSUAN_LINELENGTH. + +2001-12-13 Marcus Brinkmann <marcus@g10code.de> + + * assuan-buffer.c (assuan_read_line): Fix order of execution to + get correct return values. + +2001-12-13 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_get_active_fds): Fixed silly bug, + pretty obvious that nobody ever tested this function. + +2001-12-12 Werner Koch <wk@gnupg.org> + + * assuan-connect.c (assuan_pipe_connect): Implemented the inital + handshake. + * assuan-client.c (read_from_server): Renamed to + (_assuan_read_from_server): this and made external. + + * assuan-listen.c (assuan_set_hello_line): New. + (assuan_accept): Use a custom hello line is available. + + * assuan-buffer.c (assuan_read_line): New. + (assuan_pending_line): New. + (_assuan_write_line): Renamed to .. + (assuan_write_line): this, made public and changed all callers. + +2001-12-04 Werner Koch <wk@gnupg.org> + + * assuan-connect.c (assuan_pipe_connect): Add more error reporting. + * assuan-client.c: New. + + * assuan-inquire.c: New. + * assuan-handler.c (process_request): Check for nested invocations. + +2001-11-27 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_register_input_notify): New. + (assuan_register_output_notify): New. + +2001-11-26 Werner Koch <wk@gnupg.org> + + * assuan.h: Added more status codes. + +2001-11-25 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_register_bye_notify) + (assuan_register_reset_notify) + (assuan_register_cancel_notify): New and call them from the + standard handlers. + (assuan_process): Moved bulk of function to .. + (process_request): .. new. + (assuan_process_next): One shot version of above. + (assuan_get_active_fds): New. + +2001-11-24 Werner Koch <wk@gnupg.org> + + * assuan-connect.c (assuan_get_pid): New. + + * assuan-buffer.c (_assuan_read_line): Deal with reads of more + than a line. + * assuan-defs.h: Add space in the context for this. + + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/libtdenetwork/libgpgme-copy/assuan/Makefile.am b/libtdenetwork/libgpgme-copy/assuan/Makefile.am new file mode 100644 index 00000000..aea8f558 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/Makefile.am @@ -0,0 +1,58 @@ +# Assuan Makefile +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# +# This file is part of Assuan. +# +# Assuan is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Assuan is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +## Process this file with automake to produce Makefile.in + +#EXTRA_DIST = mkerrors +INCLUDES = -I.. # -I$(top_srcdir)/include +#BUILT_SOURCES = assuan-errors.c +#MOSTLYCLEANFILES = assuan-errors.c + +noinst_LTLIBRARIES = libassuan.la + +AM_CPPFLAGS = -D_ASSUAN_IN_GPGME_BUILD_ASSUAN + +#libassuan_la_LDFLAGS = +libassuan_la_SOURCES = \ + assuan-util.c \ + assuan-errors.c \ + assuan-buffer.c \ + assuan-handler.c \ + assuan-inquire.c \ + assuan-listen.c \ + assuan-connect.c \ + assuan-client.c \ + assuan-pipe-server.c \ + assuan-socket-server.c \ + assuan-pipe-connect.c \ + assuan-socket-connect.c \ + assuan-socket.c \ + assuan-io.c \ + assuan-uds.c \ + funopen.c \ + assuan-logging.c + +libassuan_la_COMPILE_FIRST=assuan-errors.c + +assuan-errors.c : $(srcdir)/assuan.h + $(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c + +CLEANFILES=assuan-errors.c + + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-buffer.c b/libtdenetwork/libgpgme-copy/assuan/assuan-buffer.c new file mode 100644 index 00000000..7a187987 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-buffer.c @@ -0,0 +1,550 @@ +/* assuan-buffer.c - read and send data + * Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <assert.h> +#ifdef HAVE_W32_SYSTEM +#include <process.h> +#endif +#include "assuan-defs.h" + + +/* Extended version of write(2) to guarantee that all bytes are + written. Returns 0 on success or -1 and ERRNO on failure. */ +static int +writen (assuan_context_t ctx, const char *buffer, size_t length) +{ + while (length) + { + ssize_t nwritten = ctx->io->writefnc (ctx, buffer, length); + + if (nwritten < 0) + { + if (errno == EINTR) + continue; + return -1; /* write error */ + } + length -= nwritten; + buffer += nwritten; + } + return 0; /* okay */ +} + +/* Read an entire line. Returns 0 on success or -1 and ERRNo on + failure. EOF is indictated by setting the integer at address + R_EOF. */ +static int +readline (assuan_context_t ctx, char *buf, size_t buflen, + int *r_nread, int *r_eof) +{ + size_t nleft = buflen; + char *p; + + *r_eof = 0; + *r_nread = 0; + while (nleft > 0) + { + ssize_t n = ctx->io->readfnc (ctx, buf, nleft); + + if (n < 0) + { + if (errno == EINTR) + continue; + return -1; /* read error */ + } + else if (!n) + { + *r_eof = 1; + break; /* allow incomplete lines */ + } + p = buf; + nleft -= n; + buf += n; + *r_nread += n; + + p = memrchr (p, '\n', n); + if (p) + break; /* at least one full line available - that's enough for now */ + } + + return 0; +} + + +/* Function returns an Assuan error. */ +assuan_error_t +_assuan_read_line (assuan_context_t ctx) +{ + char *line = ctx->inbound.line; + int nread, atticlen; + int rc; + char *endp = 0; + + if (ctx->inbound.eof) + return _assuan_error (-1); + + atticlen = ctx->inbound.attic.linelen; + if (atticlen) + { + memcpy (line, ctx->inbound.attic.line, atticlen); + ctx->inbound.attic.linelen = 0; + + endp = memchr (line, '\n', atticlen); + if (endp) + /* Found another line in the attic. */ + { + rc = 0; + nread = atticlen; + atticlen = 0; + } + else + /* There is pending data but not a full line. */ + { + assert (atticlen < LINELENGTH); + rc = readline (ctx, line + atticlen, + LINELENGTH - atticlen, &nread, &ctx->inbound.eof); + } + } + else + /* No pending data. */ + rc = readline (ctx, line, LINELENGTH, + &nread, &ctx->inbound.eof); + if (rc) + { + if (ctx->log_fp) + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd, + strerror (errno)); + return _assuan_error (ASSUAN_Read_Error); + } + if (!nread) + { + assert (ctx->inbound.eof); + if (ctx->log_fp) + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [EOF]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + return _assuan_error (-1); + } + + ctx->inbound.attic.pending = 0; + nread += atticlen; + + if (! endp) + endp = memchr (line, '\n', nread); + + if (endp) + { + unsigned monitor_result; + int n = endp - line + 1; + + if (n < nread) + /* LINE contains more than one line. We copy it to the attic + now as handlers are allowed to modify the passed + buffer. */ + { + int len = nread - n; + memcpy (ctx->inbound.attic.line, endp + 1, len); + ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0; + ctx->inbound.attic.linelen = len; + } + + if (endp != line && endp[-1] == '\r') + endp --; + *endp = 0; + + ctx->inbound.linelen = endp - line; + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 0, + ctx->inbound.line, + ctx->inbound.linelen) + : 0); + if ( (monitor_result & 2) ) + ctx->inbound.linelen = 0; + + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + _assuan_log_print_buffer (ctx->log_fp, + ctx->inbound.line, + ctx->inbound.linelen); + putc ('\n', ctx->log_fp); + } + return 0; + } + else + { + if (ctx->log_fp) + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Invalid line]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + *line = 0; + ctx->inbound.linelen = 0; + return _assuan_error (ctx->inbound.eof + ? ASSUAN_Line_Not_Terminated + : ASSUAN_Line_Too_Long); + } +} + + +/* Read the next line from the client or server and return a pointer + in *LINE to a buffer holding the line. LINELEN is the length of + *LINE. The buffer is valid until the next read operation on it. + The caller may modify the buffer. The buffer is invalid (i.e. must + not be used) if an error is returned. + + Returns 0 on success or an assuan error code. + See also: assuan_pending_line(). +*/ +assuan_error_t +assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen) +{ + assuan_error_t err; + + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + + err = _assuan_read_line (ctx); + *line = ctx->inbound.line; + *linelen = ctx->inbound.linelen; + return err; +} + + +/* Return true if a full line is buffered (i.e. an entire line may be + read without any I/O). */ +int +assuan_pending_line (assuan_context_t ctx) +{ + return ctx && ctx->inbound.attic.pending; +} + + +assuan_error_t +_assuan_write_line (assuan_context_t ctx, const char *prefix, + const char *line, size_t len) +{ + assuan_error_t rc = 0; + size_t prefixlen = prefix? strlen (prefix):0; + unsigned int monitor_result; + + /* Make sure that the line is short enough. */ + if (len + prefixlen + 2 > ASSUAN_LINELENGTH) + { + if (ctx->log_fp) + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> " + "[supplied line too long -truncated]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + if (prefixlen > 5) + prefixlen = 5; + if (len > ASSUAN_LINELENGTH - prefixlen - 2) + len = ASSUAN_LINELENGTH - prefixlen - 2 - 1; + } + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 1, line, len) + : 0); + + /* Fixme: we should do some kind of line buffering. */ + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + { + if (prefixlen) + _assuan_log_print_buffer (ctx->log_fp, prefix, prefixlen); + _assuan_log_print_buffer (ctx->log_fp, line, len); + } + putc ('\n', ctx->log_fp); + } + + if (prefixlen && !(monitor_result & 2)) + { + rc = writen (ctx, prefix, prefixlen); + if (rc) + rc = _assuan_error (ASSUAN_Write_Error); + } + if (!rc && !(monitor_result & 2)) + { + rc = writen (ctx, line, len); + if (rc) + rc = _assuan_error (ASSUAN_Write_Error); + if (!rc) + { + rc = writen (ctx, "\n", 1); + if (rc) + rc = _assuan_error (ASSUAN_Write_Error); + } + } + return rc; +} + + +assuan_error_t +assuan_write_line (assuan_context_t ctx, const char *line) +{ + size_t len; + const char *s; + + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + + /* Make sure that we never take a LF from the user - this might + violate the protocol. */ + s = strchr (line, '\n'); + len = s? (s-line) : strlen (line); + + if (ctx->log_fp && s) + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> " + "[supplied line contained a LF - truncated]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + + return _assuan_write_line (ctx, NULL, line, len); +} + + + +/* Write out the data in buffer as datalines with line wrapping and + percent escaping. This function is used for GNU's custom streams. */ +int +_assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size) +{ + assuan_context_t ctx = cookie; + size_t size = orig_size; + char *line; + size_t linelen; + + if (ctx->outbound.data.error) + return 0; + + line = ctx->outbound.data.line; + linelen = ctx->outbound.data.linelen; + line += linelen; + while (size) + { + unsigned int monitor_result; + + /* Insert data line header. */ + if (!linelen) + { + *line++ = 'D'; + *line++ = ' '; + linelen += 2; + } + + /* Copy data, keep space for the CRLF and to escape one character. */ + while (size && linelen < LINELENGTH-2-2) + { + if (*buffer == '%' || *buffer == '\r' || *buffer == '\n') + { + sprintf (line, "%%%02X", *(unsigned char*)buffer); + line += 3; + linelen += 3; + buffer++; + } + else + { + *line++ = *buffer++; + linelen++; + } + size--; + } + + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 1, + ctx->outbound.data.line, linelen) + : 0); + + if (linelen >= LINELENGTH-2-2) + { + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + _assuan_log_print_buffer (ctx->log_fp, + ctx->outbound.data.line, + linelen); + putc ('\n', ctx->log_fp); + } + *line++ = '\n'; + linelen++; + if ( !(monitor_result & 2) + && writen (ctx, ctx->outbound.data.line, linelen)) + { + ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error); + return 0; + } + line = ctx->outbound.data.line; + linelen = 0; + } + } + + ctx->outbound.data.linelen = linelen; + return (int)orig_size; +} + + +/* Write out any buffered data + This function is used for GNU's custom streams */ +int +_assuan_cookie_write_flush (void *cookie) +{ + assuan_context_t ctx = cookie; + char *line; + size_t linelen; + unsigned int monitor_result; + + if (ctx->outbound.data.error) + return 0; + + line = ctx->outbound.data.line; + linelen = ctx->outbound.data.linelen; + line += linelen; + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 1, + ctx->outbound.data.line, linelen) + : 0); + + if (linelen) + { + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + _assuan_log_print_buffer (ctx->log_fp, + ctx->outbound.data.line, linelen); + putc ('\n', ctx->log_fp); + } + *line++ = '\n'; + linelen++; + if ( !(monitor_result & 2) + && writen (ctx, ctx->outbound.data.line, linelen)) + { + ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error); + return 0; + } + ctx->outbound.data.linelen = 0; + } + return 0; +} + + +/** + * assuan_send_data: + * @ctx: An assuan context + * @buffer: Data to send or NULL to flush + * @length: length of the data to send/ + * + * This function may be used by the server or the client to send data + * lines. The data will be escaped as required by the Assuan protocol + * and may get buffered until a line is full. To force sending the + * data out @buffer may be passed as NULL (in which case @length must + * also be 0); however when used by a client this flush operation does + * also send the terminating "END" command to terminate the reponse on + * a INTQUIRE response. However, when assuan_transact() is used, this + * function takes care of sending END itself. + * + * Return value: 0 on success or an error code + **/ + +assuan_error_t +assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!buffer && length) + return _assuan_error (ASSUAN_Invalid_Value); + + if (!buffer) + { /* flush what we have */ + _assuan_cookie_write_flush (ctx); + if (ctx->outbound.data.error) + return ctx->outbound.data.error; + if (!ctx->is_server) + return assuan_write_line (ctx, "END"); + } + else + { + _assuan_cookie_write_data (ctx, buffer, length); + if (ctx->outbound.data.error) + return ctx->outbound.data.error; + } + + return 0; +} + +assuan_error_t +assuan_sendfd (assuan_context_t ctx, int fd) +{ + /* It is explicitly allowed to use (NULL, -1) as a runtime test to + check whether descriptor passing is available. */ + if (!ctx && fd == -1) +#ifdef USE_DESCRIPTOR_PASSING + return 0; +#else + return _assuan_error (ASSUAN_Not_Implemented); +#endif + + if (! ctx->io->sendfd) + return set_error (ctx, Not_Implemented, + "server does not support sending and receiving " + "of file descriptors"); + return ctx->io->sendfd (ctx, fd); +} + +assuan_error_t +assuan_receivefd (assuan_context_t ctx, int *fd) +{ + if (! ctx->io->receivefd) + return set_error (ctx, Not_Implemented, + "server does not support sending and receiving " + "of file descriptors"); + return ctx->io->receivefd (ctx, fd); +} diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-client.c b/libtdenetwork/libgpgme-copy/assuan/assuan-client.c new file mode 100644 index 00000000..978c6954 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-client.c @@ -0,0 +1,234 @@ +/* assuan-client.c - client functions + * Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <assert.h> + +#include "assuan-defs.h" + +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + + +assuan_error_t +_assuan_read_from_server (assuan_context_t ctx, int *okay, int *off) +{ + char *line; + int linelen; + assuan_error_t rc; + + *okay = 0; + *off = 0; + do + { + rc = _assuan_read_line (ctx); + if (rc) + return rc; + line = ctx->inbound.line; + linelen = ctx->inbound.linelen; + } + while (*line == '#' || !linelen); + + if (linelen >= 1 + && line[0] == 'D' && line[1] == ' ') + { + *okay = 2; /* data line */ + *off = 2; + } + else if (linelen >= 1 + && line[0] == 'S' + && (line[1] == '\0' || line[1] == ' ')) + { + *okay = 4; + *off = 1; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 2 + && line[0] == 'O' && line[1] == 'K' + && (line[2] == '\0' || line[2] == ' ')) + { + *okay = 1; + *off = 2; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 3 + && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' + && (line[3] == '\0' || line[3] == ' ')) + { + *okay = 0; + *off = 3; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 7 + && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q' + && line[3] == 'U' && line[4] == 'I' && line[5] == 'R' + && line[6] == 'E' + && (line[7] == '\0' || line[7] == ' ')) + { + *okay = 3; + *off = 7; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 3 + && line[0] == 'E' && line[1] == 'N' && line[2] == 'D' + && (line[3] == '\0' || line[3] == ' ')) + { + *okay = 5; /* end line */ + *off = 3; + } + else + rc = _assuan_error (ASSUAN_Invalid_Response); + return rc; +} + + + +/** + * assuan_transact: + * @ctx: The Assuan context + * @command: Command line to be send to the server + * @data_cb: Callback function for data lines + * @data_cb_arg: first argument passed to @data_cb + * @inquire_cb: Callback function for a inquire response + * @inquire_cb_arg: first argument passed to @inquire_cb + * @status_cb: Callback function for a status response + * @status_cb_arg: first argument passed to @status_cb + * + * FIXME: Write documentation + * + * Return value: 0 on success or error code. The error code may be + * the one one returned by the server in error lines or from the + * callback functions. Take care: When a callback returns an error + * this function returns immediately with an error and thus the caller + * will altter return an Assuan error (write erro in most cases). + **/ +assuan_error_t +assuan_transact (assuan_context_t ctx, + const char *command, + int (*data_cb)(void *, const void *, size_t), + void *data_cb_arg, + int (*inquire_cb)(void*, const char *), + void *inquire_cb_arg, + int (*status_cb)(void*, const char *), + void *status_cb_arg) +{ + assuan_error_t rc; + int okay, off; + char *line; + int linelen; + + rc = assuan_write_line (ctx, command); + if (rc) + return rc; + + if (*command == '#' || !*command) + return 0; /* Don't expect a response for a comment line. */ + + again: + rc = _assuan_read_from_server (ctx, &okay, &off); + if (rc) + return rc; /* error reading from server */ + + line = ctx->inbound.line + off; + linelen = ctx->inbound.linelen - off; + + if (!okay) + { + rc = atoi (line); + if (rc > 0 && rc < 100) + rc = _assuan_error (ASSUAN_Server_Fault); + else if (rc > 0 && rc <= 128) + rc = _assuan_error (rc); + } + else if (okay == 2) + { + if (!data_cb) + rc = _assuan_error (ASSUAN_No_Data_Callback); + else + { + char *s, *d; + + for (s=d=line; linelen; linelen--) + { + if (*s == '%' && linelen > 2) + { /* handle escaping */ + s++; + *d++ = xtoi_2 (s); + s += 2; + linelen -= 2; + } + else + *d++ = *s++; + } + *d = 0; /* add a hidden string terminator */ + rc = data_cb (data_cb_arg, line, d - line); + if (!rc) + goto again; + } + } + else if (okay == 3) + { + if (!inquire_cb) + { + assuan_write_line (ctx, "END"); /* get out of inquire mode */ + _assuan_read_from_server (ctx, &okay, &off); /* dummy read */ + rc = _assuan_error (ASSUAN_No_Inquire_Callback); + } + else + { + rc = inquire_cb (inquire_cb_arg, line); + if (!rc) + rc = assuan_send_data (ctx, NULL, 0); /* flush and send END */ + if (!rc) + goto again; + } + } + else if (okay == 4) + { + if (status_cb) + rc = status_cb (status_cb_arg, line); + if (!rc) + goto again; + } + else if (okay == 5) + { + if (!data_cb) + rc = _assuan_error (ASSUAN_No_Data_Callback); + else + { + rc = data_cb (data_cb_arg, NULL, 0); + if (!rc) + goto again; + } + } + + return rc; +} + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-connect.c b/libtdenetwork/libgpgme-copy/assuan/assuan-connect.c new file mode 100644 index 00000000..92995d8c --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-connect.c @@ -0,0 +1,79 @@ +/* assuan-connect.c - Establish a connection (client) + * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/wait.h> +#endif + +#include "assuan-defs.h" + +/* Disconnect and release the context CTX. */ +void +assuan_disconnect (assuan_context_t ctx) +{ + if (ctx) + { + assuan_write_line (ctx, "BYE"); + ctx->finish_handler (ctx); + ctx->deinit_handler (ctx); + ctx->deinit_handler = NULL; + _assuan_release_context (ctx); + } +} + +/* Return the PID of the peer or -1 if not known. This function works + in some situations where assuan_get_ucred fails. */ +pid_t +assuan_get_pid (assuan_context_t ctx) +{ + return (ctx && ctx->pid)? ctx->pid : -1; +} + + +/* Return user credentials. PID, UID and GID amy be gived as NULL if + you are not interested in this value. For getting the pid of the + peer the assuan_get_pid is usually better suited. */ +assuan_error_t +assuan_get_peercred (assuan_context_t ctx, pid_t *pid, uid_t *uid, gid_t *gid) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!ctx->peercred.valid) + return _assuan_error (ASSUAN_General_Error); + if (pid) + *pid = ctx->peercred.pid; + if (uid) + *uid = ctx->peercred.uid; + if (gid) + *gid = ctx->peercred.gid; + return 0; +} diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-defs.h b/libtdenetwork/libgpgme-copy/assuan/assuan-defs.h new file mode 100644 index 00000000..fa04f0b2 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-defs.h @@ -0,0 +1,323 @@ +/* assuan-defs.c - Internal definitions to Assuan + * Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef ASSUAN_DEFS_H +#define ASSUAN_DEFS_H + +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif +#include <unistd.h> + +#include "assuan.h" + +#ifndef HAVE_W32_SYSTEM +#define DIRSEP_C '/' +#else +#define DIRSEP_C '\\' +#endif + +#ifdef HAVE_W32_SYSTEM +#define AF_LOCAL AF_UNIX +/* We need to prefix the structure with a sockaddr_in header so we can + use it later for sendto and recvfrom. */ +struct sockaddr_un +{ + short sun_family; + unsigned short sun_port; + struct in_addr sun_addr; + char sun_path[108-2-4]; /* Path name. */ +}; + +/* Not needed anymore because the current mingw32 defines this in + sys/types.h */ +/* typedef int ssize_t; */ + +/* Missing W32 functions */ +int putc_unlocked (int c, FILE *stream); +void * memrchr (const void *block, int c, size_t size); +char * stpcpy (char *dest, const char *src); +#endif + +#define LINELENGTH ASSUAN_LINELENGTH + + +struct cmdtbl_s +{ + const char *name; + int (*handler)(assuan_context_t, char *line); +}; + + +/* A structure to dispatch I/O functions. All these functions need to + return 0 on success and set ERRNO on failure. */ +struct assuan_io +{ + /* Routine to read from input_fd. */ + ssize_t (*readfnc) (assuan_context_t, void *, size_t); + /* Routine to write to output_fd. */ + ssize_t (*writefnc) (assuan_context_t, const void *, size_t); + /* Send a file descriptor. */ + assuan_error_t (*sendfd) (assuan_context_t, int); + /* Receive a file descriptor. */ + assuan_error_t (*receivefd) (assuan_context_t, int *); +}; + + +/* The context we use with most functions. */ +struct assuan_context_s +{ + assuan_error_t err_no; + const char *err_str; + int os_errno; /* Last system error number used with certain + error codes. */ + + /* Context specific flags (cf. assuan_flag_t). */ + struct + { + unsigned int no_waitpid:1; /* See ASSUAN_NO_WAITPID. */ + } flags; + + int confidential; + int is_server; /* Set if this is context belongs to a server */ + int in_inquire; + char *hello_line; + char *okay_line; /* See assuan_set_okay_line() */ + + void *user_pointer; /* For assuan_get_pointer and assuan_set_pointer (). */ + + FILE *log_fp; + + struct { + int fd; + int eof; + char line[LINELENGTH]; + int linelen; /* w/o CR, LF - might not be the same as + strlen(line) due to embedded nuls. However a nul + is always written at this pos. */ + struct { + char line[LINELENGTH]; + int linelen ; + int pending; /* i.e. at least one line is available in the attic */ + } attic; + } inbound; + + struct { + int fd; + struct { + FILE *fp; + char line[LINELENGTH]; + int linelen; + int error; + } data; + } outbound; + + int pipe_mode; /* We are in pipe mode, i.e. we can handle just one + connection and must terminate then. */ + pid_t pid; /* The pid of the peer. */ + int listen_fd; /* The fd we are listening on (used by socket servers) */ + int connected_fd; /* helper */ + + struct { + int valid; /* Whether this structure has valid information. */ + pid_t pid; /* The pid of the peer. */ + uid_t uid; /* The uid of the peer. */ + gid_t gid; /* The gid of the peer. */ + } peercred; + + /* Used for Unix domain sockets. */ + struct sockaddr_un myaddr; + struct sockaddr_un serveraddr; + + /* Structure used for unix domain socket buffering. FIXME: We don't + use datagrams anymore thus we could get away with a simpler + buffering approach. */ + struct { + void *buffer; /* Malloced buffer. */ + int bufferallocated; /* Memory allocated. */ + int bufferoffset; /* Offset of start of buffer. */ + int buffersize; /* Bytes buffered. */ + + int pendingfds[5]; /* Array to save received descriptors. */ + int pendingfdscount; /* Number of received descriptors. */ + } uds; + + void (*deinit_handler)(assuan_context_t); + int (*accept_handler)(assuan_context_t); + int (*finish_handler)(assuan_context_t); + + struct cmdtbl_s *cmdtbl; + size_t cmdtbl_used; /* used entries */ + size_t cmdtbl_size; /* allocated size of table */ + + void (*bye_notify_fnc)(assuan_context_t); + void (*reset_notify_fnc)(assuan_context_t); + void (*cancel_notify_fnc)(assuan_context_t); + int (*option_handler_fnc)(assuan_context_t,const char*, const char*); + void (*input_notify_fnc)(assuan_context_t, const char *); + void (*output_notify_fnc)(assuan_context_t, const char *); + + /* This function is called right after a command has been processed. + It may be used to command related cleanup. */ + void (*post_cmd_notify_fnc)(assuan_context_t, int); + + /* If set, this is called right before logging an I/O line. With + DIRECTION set to 1 it is called for an output oeration; 0 means + an input operation. If bit 0 is set in the return value, the + logging of the will be suppressed. With bit 1 set, the entire + line will be ignored. */ + unsigned int (*io_monitor)(assuan_context_t ctx, + int direction, + const char *line, + size_t linelen); + + int input_fd; /* set by INPUT command */ + int output_fd; /* set by OUTPUT command */ + + /* io routines. */ + struct assuan_io *io; +}; + +/*-- assuan-pipe-server.c --*/ +int _assuan_new_context (assuan_context_t *r_ctx); +void _assuan_release_context (assuan_context_t ctx); + +/*-- assuan-uds.c --*/ +void _assuan_uds_close_fds (assuan_context_t ctx); +void _assuan_uds_deinit (assuan_context_t ctx); +void _assuan_init_uds_io (assuan_context_t ctx); + + +/*-- assuan-handler.c --*/ +int _assuan_register_std_commands (assuan_context_t ctx); + +/*-- assuan-buffer.c --*/ +assuan_error_t _assuan_read_line (assuan_context_t ctx); +int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size); +int _assuan_cookie_write_flush (void *cookie); +assuan_error_t _assuan_write_line (assuan_context_t ctx, const char *prefix, + const char *line, size_t len); + +/*-- assuan-client.c --*/ +assuan_error_t _assuan_read_from_server (assuan_context_t ctx, + int *okay, int *off); + +/*-- assuan-error.c --*/ + + +/* Map error codes as used in this implementaion to the libgpg-error + codes. */ +assuan_error_t _assuan_error (int oldcode); + +/* Extrac the erro code from A. This works for both the old and the + new style error codes. This needs to be whenever an error code is + compared. */ +#define err_code(a) ((a) & 0x00ffffff) + +/* Check whether A is the erro code for EOF. We allow forold and new + style EOF error codes here. */ +#define err_is_eof(a) ((a) == (-1) || err_code (a) == 16383) + + + +/*-- assuan-util.c --*/ +void *_assuan_malloc (size_t n); +void *_assuan_calloc (size_t n, size_t m); +void *_assuan_realloc (void *p, size_t n); +void _assuan_free (void *p); + +#define xtrymalloc(a) _assuan_malloc ((a)) +#define xtrycalloc(a,b) _assuan_calloc ((a),(b)) +#define xtryrealloc(a,b) _assuan_realloc((a),(b)) +#define xfree(a) _assuan_free ((a)) + +#define set_error(c,e,t) \ + assuan_set_error ((c), _assuan_error (ASSUAN_ ## e), (t)) + +#ifdef HAVE_W32_SYSTEM +const char *_assuan_w32_strerror (int ec); +#define w32_strerror(e) _assuan_w32_strerror ((e)) +#endif /*HAVE_W32_SYSTEM*/ + + +/*-- assuan-logging.c --*/ +void _assuan_set_default_log_stream (FILE *fp); + +void _assuan_log_printf (const char *format, ...) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) + __attribute__ ((format (printf,1,2))) +#endif + ; +void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length); +void _assuan_log_sanitized_string (const char *string); + + +/*-- assuan-io.c --*/ +pid_t _assuan_waitpid (pid_t pid, int *status, int options); + +ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size); +ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, + size_t size); +ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg); +ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg); + +/*-- assuan-socket.c --*/ +int _assuan_close (int fd); +int _assuan_sock_new (int domain, int type, int proto); +int _assuan_sock_bind (int sockfd, struct sockaddr *addr, int addrlen); +int _assuan_sock_connect (int sockfd, struct sockaddr *addr, int addrlen); + +#ifdef HAVE_FOPENCOOKIE +/* We have to implement funopen in terms of glibc's fopencookie. */ +FILE *_assuan_funopen(void *cookie, + cookie_read_function_t *readfn, + cookie_write_function_t *writefn, + cookie_seek_function_t *seekfn, + cookie_close_function_t *closefn); +#define funopen(a,r,w,s,c) _assuan_funopen ((a), (r), (w), (s), (c)) +#endif /*HAVE_FOPENCOOKIE*/ + +/* Prototypes for replacement functions. */ +#ifndef HAVE_MEMRCHR +void *memrchr (const void *block, int c, size_t size); +#endif +#ifndef HAVE_STPCPY +char *stpcpy (char *dest, const char *src); +#endif +#ifndef HAVE_SETENV +#define setenv _assuan_setenv +#define unsetenv _assuan_unsetenv +#define clearenv _assuan_clearenv +int setenv (const char *name, const char *value, int replace); +#endif +#ifndef HAVE_PUTC_UNLOCKED +int putc_unlocked (int c, FILE *stream); +#endif + +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) + + +#endif /*ASSUAN_DEFS_H*/ diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-handler.c b/libtdenetwork/libgpgme-copy/assuan/assuan-handler.c new file mode 100644 index 00000000..866db225 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-handler.c @@ -0,0 +1,774 @@ +/* assuan-handler.c - dispatch commands + * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include "assuan-defs.h" + + + +#define spacep(p) (*(p) == ' ' || *(p) == '\t') +#define digitp(a) ((a) >= '0' && (a) <= '9') + +static int my_strcasecmp (const char *a, const char *b); + + + +static int +dummy_handler (assuan_context_t ctx, char *line) +{ + return set_error (ctx, Server_Fault, "no handler registered"); +} + + +static int +std_handler_nop (assuan_context_t ctx, char *line) +{ + return 0; /* okay */ +} + +static int +std_handler_cancel (assuan_context_t ctx, char *line) +{ + if (ctx->cancel_notify_fnc) + ctx->cancel_notify_fnc (ctx); + return set_error (ctx, Not_Implemented, NULL); +} + +static int +std_handler_option (assuan_context_t ctx, char *line) +{ + char *key, *value, *p; + + for (key=line; spacep (key); key++) + ; + if (!*key) + return set_error (ctx, Syntax_Error, "argument required"); + if (*key == '=') + return set_error (ctx, Syntax_Error, "no option name given"); + for (value=key; *value && !spacep (value) && *value != '='; value++) + ; + if (*value) + { + if (spacep (value)) + *value++ = 0; /* terminate key */ + for (; spacep (value); value++) + ; + if (*value == '=') + { + *value++ = 0; /* terminate key */ + for (; spacep (value); value++) + ; + if (!*value) + return set_error (ctx, Syntax_Error, "option argument expected"); + } + if (*value) + { + for (p = value + strlen(value) - 1; p > value && spacep (p); p--) + ; + if (p > value) + *++p = 0; /* strip trailing spaces */ + } + } + + if (*key == '-' && key[1] == '-' && key[2]) + key += 2; /* the double dashes are optional */ + if (*key == '-') + return set_error (ctx, Syntax_Error, + "option should not begin with one dash"); + + if (ctx->option_handler_fnc) + return ctx->option_handler_fnc (ctx, key, value); + return 0; +} + +static int +std_handler_bye (assuan_context_t ctx, char *line) +{ + if (ctx->bye_notify_fnc) + ctx->bye_notify_fnc (ctx); + assuan_close_input_fd (ctx); + assuan_close_output_fd (ctx); + return -1; /* pretty simple :-) */ +} + +static int +std_handler_auth (assuan_context_t ctx, char *line) +{ + return set_error (ctx, Not_Implemented, NULL); +} + +static int +std_handler_reset (assuan_context_t ctx, char *line) +{ + if (ctx->reset_notify_fnc) + ctx->reset_notify_fnc (ctx); + assuan_close_input_fd (ctx); + assuan_close_output_fd (ctx); + _assuan_uds_close_fds (ctx); + return 0; +} + +static int +std_handler_end (assuan_context_t ctx, char *line) +{ + return set_error (ctx, Not_Implemented, NULL); +} + +assuan_error_t +assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd) +{ + char *endp; + + if ( (strncmp (line, "FD", 2) && strncmp (line, "fd", 2)) + || (line[2] != '=' && line[2] != '\0')) + return set_error (ctx, Syntax_Error, "FD[=<n>] expected"); + line += 2; + if (*line == '=') + { + line ++; + if (!digitp (*line)) + return set_error (ctx, Syntax_Error, "number required"); + *rfd = strtoul (line, &endp, 10); + /* Remove that argument so that a notify handler won't see it. */ + memset (line, ' ', endp? (endp-line):strlen(line)); + + if (*rfd == ctx->inbound.fd) + return set_error (ctx, Parameter_Conflict, "fd same as inbound fd"); + if (*rfd == ctx->outbound.fd) + return set_error (ctx, Parameter_Conflict, "fd same as outbound fd"); + return 0; + } + else + /* Our peer has sent the file descriptor. */ + return assuan_receivefd (ctx, rfd); +} + +/* Format is INPUT FD=<n> */ +static int +std_handler_input (assuan_context_t ctx, char *line) +{ + int rc, fd; + + rc = assuan_command_parse_fd (ctx, line, &fd); + if (rc) + return rc; + ctx->input_fd = fd; + if (ctx->input_notify_fnc) + ctx->input_notify_fnc (ctx, line); + return 0; +} + +/* Format is OUTPUT FD=<n> */ +static int +std_handler_output (assuan_context_t ctx, char *line) +{ + int rc, fd; + + rc = assuan_command_parse_fd (ctx, line, &fd); + if (rc) + return rc; + ctx->output_fd = fd; + if (ctx->output_notify_fnc) + ctx->output_notify_fnc (ctx, line); + return 0; +} + + + + + +/* This is a table with the standard commands and handler for them. + The table is used to initialize a new context and associate strings + with default handlers */ +static struct { + const char *name; + int (*handler)(assuan_context_t, char *line); + int always; /* always initialize this command */ +} std_cmd_table[] = { + { "NOP", std_handler_nop, 1 }, + { "CANCEL", std_handler_cancel, 1 }, + { "OPTION", std_handler_option, 1 }, + { "BYE", std_handler_bye, 1 }, + { "AUTH", std_handler_auth, 1 }, + { "RESET", std_handler_reset, 1 }, + { "END", std_handler_end, 1 }, + + { "INPUT", std_handler_input }, + { "OUTPUT", std_handler_output }, + { "OPTION", std_handler_option, 1 }, + { NULL } +}; + + +/** + * assuan_register_command: + * @ctx: the server context + * @cmd_name: A string with the command name + * @handler: The handler function to be called or NULL to use a default + * handler. + * + * Register a handler to be used for a given command. Note that + * several default handlers are already regsitered with a new context. + * This function however allows to override them. + * + * Return value: 0 on success or an error code + **/ +int +assuan_register_command (assuan_context_t ctx, + const char *cmd_name, + int (*handler)(assuan_context_t, char *)) +{ + int i; + const char *s; + + if (cmd_name && !*cmd_name) + cmd_name = NULL; + + if (!cmd_name) + return _assuan_error (ASSUAN_Invalid_Value); + + if (!handler) + { /* find a default handler. */ + for (i=0; (s=std_cmd_table[i].name) && strcmp (cmd_name, s); i++) + ; + if (!s) + { /* Try again but case insensitive. */ + for (i=0; (s=std_cmd_table[i].name) + && my_strcasecmp (cmd_name, s); i++) + ; + } + if (s) + handler = std_cmd_table[i].handler; + if (!handler) + handler = dummy_handler; /* Last resort is the dummy handler. */ + } + + if (!ctx->cmdtbl) + { + ctx->cmdtbl_size = 50; + ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl); + if (!ctx->cmdtbl) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->cmdtbl_used = 0; + } + else if (ctx->cmdtbl_used >= ctx->cmdtbl_size) + { + struct cmdtbl_s *x; + + x = xtryrealloc ( ctx->cmdtbl, (ctx->cmdtbl_size+10) * sizeof *x); + if (!x) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->cmdtbl = x; + ctx->cmdtbl_size += 50; + } + + ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name; + ctx->cmdtbl[ctx->cmdtbl_used].handler = handler; + ctx->cmdtbl_used++; + return 0; +} + +int +assuan_register_post_cmd_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, int)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->post_cmd_notify_fnc = fnc; + return 0; +} + +int +assuan_register_bye_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->bye_notify_fnc = fnc; + return 0; +} + +int +assuan_register_reset_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->reset_notify_fnc = fnc; + return 0; +} + +int +assuan_register_cancel_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->cancel_notify_fnc = fnc; + return 0; +} + +int +assuan_register_option_handler (assuan_context_t ctx, + int (*fnc)(assuan_context_t, + const char*, const char*)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->option_handler_fnc = fnc; + return 0; +} + +int +assuan_register_input_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->input_notify_fnc = fnc; + return 0; +} + +int +assuan_register_output_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->output_notify_fnc = fnc; + return 0; +} + + +/* Helper to register the standards commands */ +int +_assuan_register_std_commands (assuan_context_t ctx) +{ + int i, rc; + + for (i=0; std_cmd_table[i].name; i++) + { + if (std_cmd_table[i].always) + { + rc = assuan_register_command (ctx, std_cmd_table[i].name, NULL); + if (rc) + return rc; + } + } + return 0; +} + + + +/* Process the special data lines. The "D " has already been removed + from the line. As all handlers this function may modify the line. */ +static int +handle_data_line (assuan_context_t ctx, char *line, int linelen) +{ + return set_error (ctx, Not_Implemented, NULL); +} + +/* like ascii_strcasecmp but assume that B is already uppercase */ +static int +my_strcasecmp (const char *a, const char *b) +{ + if (a == b) + return 0; + + for (; *a && *b; a++, b++) + { + if (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) != *b) + break; + } + return *a == *b? 0 : (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) - *b); +} + +/* Parse the line, break out the command, find it in the command + table, remove leading and white spaces from the arguments, call the + handler with the argument line and return the error */ +static int +dispatch_command (assuan_context_t ctx, char *line, int linelen) +{ + char *p; + const char *s; + int shift, i; + + if (*line == 'D' && line[1] == ' ') /* divert to special handler */ + return handle_data_line (ctx, line+2, linelen-2); + + for (p=line; *p && *p != ' ' && *p != '\t'; p++) + ; + if (p==line) + return set_error (ctx, Syntax_Error, "leading white-space"); + if (*p) + { /* Skip over leading WS after the keyword */ + *p++ = 0; + while ( *p == ' ' || *p == '\t') + p++; + } + shift = p - line; + + for (i=0; (s=ctx->cmdtbl[i].name); i++) + { + if (!strcmp (line, s)) + break; + } + if (!s) + { /* and try case insensitive */ + for (i=0; (s=ctx->cmdtbl[i].name); i++) + { + if (!my_strcasecmp (line, s)) + break; + } + } + if (!s) + return set_error (ctx, Unknown_Command, NULL); + line += shift; + linelen -= shift; + +/* fprintf (stderr, "DBG-assuan: processing %s `%s'\n", s, line); */ + return ctx->cmdtbl[i].handler (ctx, line); +} + + + + +static int +process_request (assuan_context_t ctx) +{ + int rc; + + if (ctx->in_inquire) + return _assuan_error (ASSUAN_Nested_Commands); + + rc = _assuan_read_line (ctx); + if (rc) + return rc; + if (*ctx->inbound.line == '#' || !ctx->inbound.linelen) + return 0; /* comment line - ignore */ + + ctx->outbound.data.error = 0; + ctx->outbound.data.linelen = 0; + /* dispatch command and return reply */ + rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen); + /* check from data write errors */ + if (ctx->outbound.data.fp) + { /* Flush the data lines */ + fclose (ctx->outbound.data.fp); + ctx->outbound.data.fp = NULL; + if (!rc && ctx->outbound.data.error) + rc = ctx->outbound.data.error; + } + else /* flush any data send w/o using the data fp */ + { + assuan_send_data (ctx, NULL, 0); + if (!rc && ctx->outbound.data.error) + rc = ctx->outbound.data.error; + } + /* Error handling */ + if (!rc) + { + rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK"); + } + else if (err_is_eof (rc)) + { /* No error checking because the peer may have already disconnect. */ + assuan_write_line (ctx, "OK closing connection"); + ctx->finish_handler (ctx); + } + else + { + char errline[300]; + + if (rc < 100) + sprintf (errline, "ERR %d server fault (%.50s)", + _assuan_error (ASSUAN_Server_Fault), assuan_strerror (rc)); + else + { + const char *text = ctx->err_no == rc? ctx->err_str:NULL; + +#if defined(__GNUC__) && defined(__ELF__) + /* If we have weak symbol support we try to use the error + strings from libgpg-error without creating a dependency. + They are used for debugging purposes only, so there is no + problem if they are not available. We need to make sure + that we are using ELF because only this guarantees that + weak symbol support is available in case GNU ld is not + used. It seems that old gcc versions don't implement the + weak attribute properly but it works with the weak + pragma. */ + + unsigned int source, code; + + int gpg_strerror_r (unsigned int err, char *buf, size_t buflen) + __attribute__ ((weak)); + const char *gpg_strsource (unsigned int err) + __attribute__ ((weak)); +#if !defined(HAVE_W32_SYSTEM) && __GNUC__ < 3 +#pragma weak gpg_strerror_r +#pragma weak gpg_strsource +#endif + + source = ((rc >> 24) & 0xff); + code = (rc & 0x00ffffff); + if (source && gpg_strsource && gpg_strerror_r) + { + /* Assume this is an libgpg-error. */ + char ebuf[50]; + + gpg_strerror_r (rc, ebuf, sizeof ebuf ); + sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s", + rc, + ebuf, + gpg_strsource (rc), + text? " - ":"", text?text:""); + } + else +#endif /* __GNUC__ && __ELF__ */ + sprintf (errline, "ERR %d %.50s%s%.100s", + rc, assuan_strerror (rc), text? " - ":"", text?text:""); + } + rc = assuan_write_line (ctx, errline); + } + + if (ctx->post_cmd_notify_fnc) + ctx->post_cmd_notify_fnc (ctx, rc); + + ctx->confidential = 0; + if (ctx->okay_line) + { + xfree (ctx->okay_line); + ctx->okay_line = NULL; + } + return rc; +} + +/** + * assuan_process: + * @ctx: assuan context + * + * This function is used to handle the assuan protocol after a + * connection has been established using assuan_accept(). This is the + * main protocol handler. + * + * Return value: 0 on success or an error code if the assuan operation + * failed. Note, that no error is returned for operational errors. + **/ +int +assuan_process (assuan_context_t ctx) +{ + int rc; + + do { + rc = process_request (ctx); + } while (!rc); + + if (err_is_eof (rc)) + rc = 0; + + return rc; +} + + +/** + * assuan_process_next: + * @ctx: Assuan context + * + * Same as assuan_process() but the user has to provide the outer + * loop. He should loop as long as the return code is zero and stop + * otherwise; -1 is regular end. + * + * See also: assuan_get_active_fds() + * Return value: -1 for end of server, 0 on success or an error code + **/ +int +assuan_process_next (assuan_context_t ctx) +{ + return process_request (ctx); +} + + +/** + * assuan_get_active_fds: + * @ctx: Assuan context + * @what: 0 for read fds, 1 for write fds + * @fdarray: Caller supplied array to store the FDs + * @fdarraysize: size of that array + * + * Return all active filedescriptors for the given context. This + * function can be used to select on the fds and call + * assuan_process_next() if there is an active one. The first fd in + * the array is the one used for the command connection. + * + * Note, that write FDs are not yet supported. + * + * Return value: number of FDs active and put into @fdarray or -1 on + * error which is most likely a too small fdarray. + **/ +int +assuan_get_active_fds (assuan_context_t ctx, int what, + int *fdarray, int fdarraysize) +{ + int n = 0; + + if (!ctx || fdarraysize < 2 || what < 0 || what > 1) + return -1; + + if (!what) + { + if (ctx->inbound.fd != -1) + fdarray[n++] = ctx->inbound.fd; + } + else + { + if (ctx->outbound.fd != -1) + fdarray[n++] = ctx->outbound.fd; + if (ctx->outbound.data.fp) + fdarray[n++] = fileno (ctx->outbound.data.fp); + } + + return n; +} + + +/* Two simple wrappers to make the expected function types match. */ +#ifdef HAVE_FUNOPEN +static int +fun1_cookie_write (void *cookie, const char *buffer, int orig_size) +{ + return _assuan_cookie_write_data (cookie, buffer, orig_size); +} +#endif /*HAVE_FUNOPEN*/ +#ifdef HAVE_FOPENCOOKIE +static ssize_t +fun2_cookie_write (void *cookie, const char *buffer, size_t orig_size) +{ + return _assuan_cookie_write_data (cookie, buffer, orig_size); +} +#endif /*HAVE_FOPENCOOKIE*/ + +/* Return a FP to be used for data output. The FILE pointer is valid + until the end of a handler. So a close is not needed. Assuan does + all the buffering needed to insert the status line as well as the + required line wappping and quoting for data lines. + + We use GNU's custom streams here. There should be an alternative + implementaion for systems w/o a glibc, a simple implementation + could use a child process */ +FILE * +assuan_get_data_fp (assuan_context_t ctx) +{ +#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) + if (ctx->outbound.data.fp) + return ctx->outbound.data.fp; + +#ifdef HAVE_FUNOPEN + ctx->outbound.data.fp = funopen (ctx, 0, fun1_cookie_write, + 0, _assuan_cookie_write_flush); +#else + ctx->outbound.data.fp = funopen (ctx, 0, fun2_cookie_write, + 0, _assuan_cookie_write_flush); +#endif + + ctx->outbound.data.error = 0; + return ctx->outbound.data.fp; +#else + errno = ENOSYS; + return NULL; +#endif +} + + +/* Set the text used for the next OK reponse. This string is + automatically reset to NULL after the next command. */ +assuan_error_t +assuan_set_okay_line (assuan_context_t ctx, const char *line) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!line) + { + xfree (ctx->okay_line); + ctx->okay_line = NULL; + } + else + { + /* FIXME: we need to use gcry_is_secure() to test whether + we should allocate the entire line in secure memory */ + char *buf = xtrymalloc (3+strlen(line)+1); + if (!buf) + return _assuan_error (ASSUAN_Out_Of_Core); + strcpy (buf, "OK "); + strcpy (buf+3, line); + xfree (ctx->okay_line); + ctx->okay_line = buf; + } + return 0; +} + + + +assuan_error_t +assuan_write_status (assuan_context_t ctx, + const char *keyword, const char *text) +{ + char buffer[256]; + char *helpbuf; + size_t n; + assuan_error_t ae; + + if ( !ctx || !keyword) + return _assuan_error (ASSUAN_Invalid_Value); + if (!text) + text = ""; + + n = 2 + strlen (keyword) + 1 + strlen (text) + 1; + if (n < sizeof (buffer)) + { + strcpy (buffer, "S "); + strcat (buffer, keyword); + if (*text) + { + strcat (buffer, " "); + strcat (buffer, text); + } + ae = assuan_write_line (ctx, buffer); + } + else if ( (helpbuf = xtrymalloc (n)) ) + { + strcpy (helpbuf, "S "); + strcat (helpbuf, keyword); + if (*text) + { + strcat (helpbuf, " "); + strcat (helpbuf, text); + } + ae = assuan_write_line (ctx, helpbuf); + xfree (helpbuf); + } + else + ae = 0; + return ae; +} diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-inquire.c b/libtdenetwork/libgpgme-copy/assuan/assuan-inquire.c new file mode 100644 index 00000000..897e0773 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-inquire.c @@ -0,0 +1,241 @@ +/* assuan-inquire.c - handle inquire stuff + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "assuan-defs.h" + +#define digitp(a) ((a) >= '0' && (a) <= '9') +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + + +struct membuf +{ + size_t len; + size_t size; + char *buf; + int out_of_core; + int too_large; + size_t maxlen; +}; + + + +/* A simple implemnation of a dynamic buffer. Use init_membuf() to + create a buffer, put_membuf to append bytes and get_membuf to + release and return the buffer. Allocation errors are detected but + only returned at the final get_membuf(), this helps not to clutter + the code with out of core checks. */ + +static void +init_membuf (struct membuf *mb, int initiallen, size_t maxlen) +{ + mb->len = 0; + mb->size = initiallen; + mb->out_of_core = 0; + mb->too_large = 0; + mb->maxlen = maxlen; + /* we need to allocate one byte more for get_membuf */ + mb->buf = xtrymalloc (initiallen+1); + if (!mb->buf) + mb->out_of_core = 1; +} + +static void +put_membuf (struct membuf *mb, const void *buf, size_t len) +{ + if (mb->out_of_core || mb->too_large) + return; + + if (mb->maxlen && mb->len + len > mb->maxlen) + { + mb->too_large = 1; + return; + } + + if (mb->len + len >= mb->size) + { + char *p; + + mb->size += len + 1024; + /* we need to allocate one byte more for get_membuf */ + p = xtryrealloc (mb->buf, mb->size+1); + if (!p) + { + mb->out_of_core = 1; + return; + } + mb->buf = p; + } + memcpy (mb->buf + mb->len, buf, len); + mb->len += len; +} + +static void * +get_membuf (struct membuf *mb, size_t *len) +{ + char *p; + + if (mb->out_of_core || mb->too_large) + { + xfree (mb->buf); + mb->buf = NULL; + return NULL; + } + + mb->buf[mb->len] = 0; /* there is enough space for the hidden eos */ + p = mb->buf; + *len = mb->len; + mb->buf = NULL; + mb->out_of_core = 1; /* don't allow a reuse */ + return p; +} + +static void +free_membuf (struct membuf *mb) +{ + xfree (mb->buf); + mb->buf = NULL; +} + + +/** + * assuan_inquire: + * @ctx: An assuan context + * @keyword: The keyword used for the inquire + * @r_buffer: Returns an allocated buffer + * @r_length: Returns the length of this buffer + * @maxlen: If not 0, the size limit of the inquired data. + * + * A Server may use this to Send an inquire. r_buffer, r_length and + * maxlen may all be NULL/0 to indicate that no real data is expected. + * + * Return value: 0 on success or an ASSUAN error code + **/ +assuan_error_t +assuan_inquire (assuan_context_t ctx, const char *keyword, + unsigned char **r_buffer, size_t *r_length, size_t maxlen) +{ + assuan_error_t rc; + struct membuf mb; + char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INTQUIRE ")+CR,LF) */ + unsigned char *line, *p; + int linelen; + int nodataexpected; + + if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) + return _assuan_error (ASSUAN_Invalid_Value); + nodataexpected = !r_buffer && !r_length && !maxlen; + if (!nodataexpected && (!r_buffer || !r_length)) + return _assuan_error (ASSUAN_Invalid_Value); + if (!ctx->is_server) + return _assuan_error (ASSUAN_Not_A_Server); + if (ctx->in_inquire) + return _assuan_error (ASSUAN_Nested_Commands); + + ctx->in_inquire = 1; + if (nodataexpected) + memset (&mb, 0, sizeof mb); /* avoid compiler warnings */ + else + init_membuf (&mb, maxlen? maxlen:1024, maxlen); + + strcpy (stpcpy (cmdbuf, "INTQUIRE "), keyword); + rc = assuan_write_line (ctx, cmdbuf); + if (rc) + goto leave; + + for (;;) + { + do + { + rc = _assuan_read_line (ctx); + if (rc) + goto leave; + line = (unsigned char *) ctx->inbound.line; + linelen = ctx->inbound.linelen; + } + while (*line == '#' || !linelen); + if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' + && (!line[3] || line[3] == ' ')) + break; /* END command received*/ + if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') + { + rc = _assuan_error (ASSUAN_Canceled); + goto leave; + } + if (line[0] != 'D' || line[1] != ' ' || nodataexpected) + { + rc = _assuan_error (ASSUAN_Unexpected_Command); + goto leave; + } + if (linelen < 3) + continue; + line += 2; + linelen -= 2; + + p = line; + while (linelen) + { + for (;linelen && *p != '%'; linelen--, p++) + ; + put_membuf (&mb, line, p-line); + if (linelen > 2) + { /* handle escaping */ + unsigned char tmp[1]; + p++; + *tmp = xtoi_2 (p); + p += 2; + linelen -= 3; + put_membuf (&mb, tmp, 1); + } + line = p; + } + if (mb.too_large) + { + rc = _assuan_error (ASSUAN_Too_Much_Data); + goto leave; + } + } + + if (!nodataexpected) + { + *r_buffer = get_membuf (&mb, r_length); + if (!*r_buffer) + rc = _assuan_error (ASSUAN_Out_Of_Core); + } + + leave: + if (!nodataexpected) + free_membuf (&mb); + ctx->in_inquire = 0; + return rc; +} + + + + + + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-io.c b/libtdenetwork/libgpgme-copy/assuan/assuan-io.c new file mode 100644 index 00000000..d1f0d5e4 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-io.c @@ -0,0 +1,87 @@ +/* assuan-io.c - Wraps the read and write functions. + * Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <errno.h> +#ifdef HAVE_W32_SYSTEM +# include <windows.h> +#else +# include <sys/wait.h> +#endif + +#include "assuan-defs.h" + + +#ifndef HAVE_W32_SYSTEM +pid_t +_assuan_waitpid (pid_t pid, int *status, int options) +{ + return waitpid (pid, status, options); +} +#endif + + +ssize_t +_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) +{ + return read (ctx->inbound.fd, buffer, size); +} + +ssize_t +_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) +{ + return write (ctx->outbound.fd, buffer, size); +} + + +ssize_t +_assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg) +{ +#ifdef HAVE_W32_SYSTEM + return _assuan_error (ASSUAN_Not_Implemented); +#else + int ret; + while ( (ret = sendmsg (ctx->outbound.fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#endif +} + + +ssize_t +_assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg) +{ +#ifdef HAVE_W32_SYSTEM + return _assuan_error (ASSUAN_Not_Implemented); +#else + int ret; + while ( (ret = recvmsg (ctx->inbound.fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#endif +} diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-listen.c b/libtdenetwork/libgpgme-copy/assuan/assuan-listen.c new file mode 100644 index 00000000..04db68ce --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-listen.c @@ -0,0 +1,157 @@ +/* assuan-listen.c - Wait for a connection (server) + * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include "assuan-defs.h" + +assuan_error_t +assuan_set_hello_line (assuan_context_t ctx, const char *line) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!line) + { + xfree (ctx->hello_line); + ctx->hello_line = NULL; + } + else + { + char *buf = xtrymalloc (3+strlen(line)+1); + if (!buf) + return _assuan_error (ASSUAN_Out_Of_Core); + if (strchr (line, '\n')) + strcpy (buf, line); + else + { + strcpy (buf, "OK "); + strcpy (buf+3, line); + } + xfree (ctx->hello_line); + ctx->hello_line = buf; + } + return 0; +} + + +/** + * assuan_accept: + * @ctx: context + * + * Cancel any existing connection and wait for a connection from a + * client. The initial handshake is performed which may include an + * initial authentication or encryption negotiation. + * + * Return value: 0 on success or an error if the connection could for + * some reason not be established. + **/ +assuan_error_t +assuan_accept (assuan_context_t ctx) +{ + int rc; + const char *p, *pend; + + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + + if (ctx->pipe_mode > 1) + return -1; /* second invocation for pipemode -> terminate */ + ctx->finish_handler (ctx); + + rc = ctx->accept_handler (ctx); + if (rc) + return rc; + + /* Send the hello. */ + p = ctx->hello_line; + if (p && (pend = strchr (p, '\n'))) + { /* This is a multi line hello. Send all but the last line as + comments. */ + do + { + rc = _assuan_write_line (ctx, "# ", p, pend - p); + if (rc) + return rc; + p = pend + 1; + pend = strchr (p, '\n'); + } + while (pend); + rc = _assuan_write_line (ctx, "OK ", p, strlen (p)); + } + else if (p) + rc = assuan_write_line (ctx, p); + else + rc = assuan_write_line (ctx, "OK Pleased to meet you"); + if (rc) + return rc; + + if (ctx->pipe_mode) + ctx->pipe_mode = 2; + + return 0; +} + + + +int +assuan_get_input_fd (assuan_context_t ctx) +{ + return ctx? ctx->input_fd : -1; +} + + +int +assuan_get_output_fd (assuan_context_t ctx) +{ + return ctx? ctx->output_fd : -1; +} + + +/* Close the fd descriptor set by the command INPUT FD=n. We handle + this fd inside assuan so that we can do some initial checks */ +assuan_error_t +assuan_close_input_fd (assuan_context_t ctx) +{ + if (!ctx || ctx->input_fd == -1) + return _assuan_error (ASSUAN_Invalid_Value); + _assuan_close (ctx->input_fd); + ctx->input_fd = -1; + return 0; +} + +/* Close the fd descriptor set by the command OUTPUT FD=n. We handle + this fd inside assuan so that we can do some initial checks */ +assuan_error_t +assuan_close_output_fd (assuan_context_t ctx) +{ + if (!ctx || ctx->output_fd == -1) + return _assuan_error (ASSUAN_Invalid_Value); + + _assuan_close (ctx->output_fd); + ctx->output_fd = -1; + return 0; +} + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-logging.c b/libtdenetwork/libgpgme-copy/assuan/assuan-logging.c new file mode 100644 index 00000000..cfc3d846 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-logging.c @@ -0,0 +1,241 @@ +/* assuan-logging.c - Default logging function. + * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#ifdef HAVE_W32_SYSTEM +#include <windows.h> +#endif /*HAVE_W32_SYSTEM*/ +#include <errno.h> +#include <ctype.h> + +#include "assuan-defs.h" + +static char prefix_buffer[80]; +static FILE *_assuan_log; +static int full_logging; + +void +_assuan_set_default_log_stream (FILE *fp) +{ + if (!_assuan_log) + { + _assuan_log = fp; + full_logging = !!getenv ("ASSUAN_FULL_LOGGING"); + } +} + +void +assuan_set_assuan_log_stream (FILE *fp) +{ + _assuan_log = fp; +} + + +/* Set the per context log stream. Also enable the default log stream + if it has not been set. */ +void +assuan_set_log_stream (assuan_context_t ctx, FILE *fp) +{ + if (ctx) + { + if (ctx->log_fp) + fflush (ctx->log_fp); + ctx->log_fp = fp; + _assuan_set_default_log_stream (fp); + } +} + + +FILE * +assuan_get_assuan_log_stream (void) +{ + return _assuan_log ? _assuan_log : stderr; +} + + +/* Set the prefix to be used for logging to TEXT or + resets it to the default if TEXT is NULL. */ +void +assuan_set_assuan_log_prefix (const char *text) +{ + if (text) + { + strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1); + prefix_buffer[sizeof (prefix_buffer)-1] = 0; + } + else + *prefix_buffer = 0; +} + +const char * +assuan_get_assuan_log_prefix (void) +{ + return prefix_buffer; +} + + +void +_assuan_log_printf (const char *format, ...) +{ + va_list arg_ptr; + FILE *fp; + const char *prf; + int save_errno = errno; + + fp = assuan_get_assuan_log_stream (); + prf = assuan_get_assuan_log_prefix (); + if (*prf) + fprintf (fp, "%s[%u]: ", prf, (unsigned int)getpid ()); + + va_start (arg_ptr, format); + vfprintf (fp, format, arg_ptr ); + va_end (arg_ptr); + errno = save_errno; +} + + +/* Dump a possibly binary string (used for debugging). Distinguish + ascii text from binary and print it accordingly. This function + takes FILE pointer arg becuase logging may be enabled on a per + context basis. */ +void +_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length) +{ + const unsigned char *s; + int n; + + for (n=length,s=buffer; n; n--, s++) + if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80)) + break; + + s = buffer; + if (!n && *s != '[') + fwrite (buffer, length, 1, fp); + else + { +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + putc_unlocked ('[', fp); + if ( length > 16 && !full_logging) + { + for (n=0; n < 12; n++, s++) + fprintf (fp, " %02x", *s); + fprintf (fp, " ...(%d bytes skipped)", (int)length - 12); + } + else + { + for (n=0; n < length; n++, s++) + fprintf (fp, " %02x", *s); + } + putc_unlocked (' ', fp); + putc_unlocked (']', fp); +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif + } +} + +/* Log a user supplied string. Escapes non-printable before + printing. */ +void +_assuan_log_sanitized_string (const char *string) +{ + const unsigned char *s = (const unsigned char *) string; + FILE *fp = assuan_get_assuan_log_stream (); + + if (! *s) + return; + +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + + for (; *s; s++) + { + int c = 0; + + switch (*s) + { + case '\r': + c = 'r'; + break; + + case '\n': + c = 'n'; + break; + + case '\f': + c = 'f'; + break; + + case '\v': + c = 'v'; + break; + + case '\b': + c = 'b'; + break; + + default: + if ((isascii (*s) && isprint (*s)) || (*s >= 0x80)) + putc_unlocked (*s, fp); + else + { + putc_unlocked ('\\', fp); + fprintf (fp, "x%02x", *s); + } + } + + if (c) + { + putc_unlocked ('\\', fp); + putc_unlocked (c, fp); + } + } + +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif +} + + + +#ifdef HAVE_W32_SYSTEM +const char * +_assuan_w32_strerror (int ec) +{ + static char strerr[256]; + + if (ec == -1) + ec = (int)GetLastError (); + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + strerr, sizeof (strerr)-1, NULL); + return strerr; +} +#endif /*HAVE_W32_SYSTEM*/ diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-pipe-connect.c b/libtdenetwork/libgpgme-copy/assuan/assuan-pipe-connect.c new file mode 100644 index 00000000..8ee9c748 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-pipe-connect.c @@ -0,0 +1,889 @@ +/* assuan-pipe-connect.c - Establish a pipe connection (client) + * Copyright (C) 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/wait.h> +#else +#include <windows.h> +#endif + +#include "assuan-defs.h" + +/* Hacks for Slowaris. */ +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + + +#ifdef _POSIX_OPEN_MAX +#define MAX_OPEN_FDS _POSIX_OPEN_MAX +#else +#define MAX_OPEN_FDS 20 +#endif + +#ifdef HAVE_W32_SYSTEM +/* We assume that a HANDLE can be represented by an int which should + be true for all i386 systems (HANDLE is defined as void *) and + these are the only systems for which Windows is available. Further + we assume that -1 denotes an invalid handle. */ +#define fd_to_handle(a) ((HANDLE)(a)) +#define handle_to_fd(a) ((int)(a)) +#define pid_to_handle(a) ((HANDLE)(a)) +#define handle_to_pid(a) ((int)(a)) +#endif /*HAVE_W32_SYSTEM*/ + + +/* This should be called to make sure that SIGPIPE gets ignored. */ +static void +fix_signals (void) +{ +#ifndef _ASSUAN_NO_FIXED_SIGNALS +#ifndef HAVE_DOSISH_SYSTEM /* No SIGPIPE for these systems. */ + static int fixed_signals; + + if (!fixed_signals) + { + struct sigaction act; + + sigaction (SIGPIPE, NULL, &act); + if (act.sa_handler == SIG_DFL) + { + act.sa_handler = SIG_IGN; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + sigaction (SIGPIPE, &act, NULL); + } + fixed_signals = 1; + /* FIXME: This is not MT safe */ + } +#endif /*HAVE_DOSISH_SYSTEM*/ +#endif /*!_ASSUAN_NO_FIXED_SIGNALS*/ +} + + +#ifndef HAVE_W32_SYSTEM +static int +writen (int fd, const char *buffer, size_t length) +{ + while (length) + { + int nwritten = write (fd, buffer, length); + + if (nwritten < 0) + { + if (errno == EINTR) + continue; + return -1; /* write error */ + } + length -= nwritten; + buffer += nwritten; + } + return 0; /* okay */ +} +#endif + +static int +do_finish (assuan_context_t ctx) +{ + if (ctx->inbound.fd != -1) + { + _assuan_close (ctx->inbound.fd); + if (ctx->inbound.fd == ctx->outbound.fd) + ctx->outbound.fd = -1; + ctx->inbound.fd = -1; + } + if (ctx->outbound.fd != -1) + { + _assuan_close (ctx->outbound.fd); + ctx->outbound.fd = -1; + } + if (ctx->pid != -1 && ctx->pid) + { +#ifndef HAVE_W32_SYSTEM +#ifndef _ASSUAN_USE_DOUBLE_FORK + if (!ctx->flags.no_waitpid) + _assuan_waitpid (ctx->pid, NULL, 0); + ctx->pid = -1; +#endif +#endif /*!HAVE_W32_SYSTEM*/ + } + return 0; +} + +static void +do_deinit (assuan_context_t ctx) +{ + do_finish (ctx); +} + + +/* Helper for pipe_connect. */ +static assuan_error_t +initial_handshake (assuan_context_t *ctx) +{ + int okay, off; + assuan_error_t err; + + err = _assuan_read_from_server (*ctx, &okay, &off); + if (err) + _assuan_log_printf ("can't connect server: %s\n", + assuan_strerror (err)); + else if (okay != 1) + { + _assuan_log_printf ("can't connect server: `%s'\n", + (*ctx)->inbound.line); + err = _assuan_error (ASSUAN_Connect_Failed); + } + + if (err) + { + assuan_disconnect (*ctx); + *ctx = NULL; + } + return err; +} + + +#ifndef HAVE_W32_SYSTEM +#define pipe_connect pipe_connect_unix +/* Unix version of the pipe connection code. We use an extra macro to + make ChangeLog entries easier. */ +static assuan_error_t +pipe_connect_unix (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue) +{ + assuan_error_t err; + int rp[2]; + int wp[2]; + char mypidstr[50]; + + if (!ctx || !name || !argv || !argv[0]) + return _assuan_error (ASSUAN_Invalid_Value); + + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); + + if (pipe (rp) < 0) + return _assuan_error (ASSUAN_General_Error); + + if (pipe (wp) < 0) + { + close (rp[0]); + close (rp[1]); + return _assuan_error (ASSUAN_General_Error); + } + + err = _assuan_new_context (ctx); + if (err) + { + close (rp[0]); + close (rp[1]); + close (wp[0]); + close (wp[1]); + return err; + } + (*ctx)->pipe_mode = 1; + (*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */ + (*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */ + (*ctx)->deinit_handler = do_deinit; + (*ctx)->finish_handler = do_finish; + + /* FIXME: For GPGME we should better use _gpgme_io_spawn. The PID + stored here is actually soon useless. */ + (*ctx)->pid = fork (); + if ((*ctx)->pid < 0) + { + close (rp[0]); + close (rp[1]); + close (wp[0]); + close (wp[1]); + _assuan_release_context (*ctx); + return _assuan_error (ASSUAN_General_Error); + } + + if ((*ctx)->pid == 0) + { +#ifdef _ASSUAN_USE_DOUBLE_FORK + pid_t pid; + + if ((pid = fork ()) == 0) +#endif + { + int i, n; + char errbuf[512]; + int *fdp; + + if (atfork) + atfork (atforkvalue, 0); + + /* Dup handles to stdin/stdout. */ + if (rp[1] != STDOUT_FILENO) + { + if (dup2 (rp[1], STDOUT_FILENO) == -1) + { + _assuan_log_printf ("dup2 failed in child: %s\n", + strerror (errno)); + _exit (4); + } + } + if (wp[0] != STDIN_FILENO) + { + if (dup2 (wp[0], STDIN_FILENO) == -1) + { + _assuan_log_printf ("dup2 failed in child: %s\n", + strerror (errno)); + _exit (4); + } + } + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + int fd = open ("/dev/null", O_WRONLY); + if (fd == -1) + { + _assuan_log_printf ("can't open `/dev/null': %s\n", + strerror (errno)); + _exit (4); + } + if (dup2 (fd, STDERR_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null, 2) failed: %s\n", + strerror (errno)); + _exit (4); + } + } + + + /* Close all files which will not be duped and are not in the + fd_child_list. */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) + { + if ( i == STDIN_FILENO || i == STDOUT_FILENO + || i == STDERR_FILENO) + continue; + fdp = fd_child_list; + if (fdp) + { + while (*fdp != -1 && *fdp != i) + fdp++; + } + + if (!(fdp && *fdp != -1)) + close(i); + } + errno = 0; + + /* We store our parents pid in the environment so that the + execed assuan server is able to read the actual pid of the + client. The server can't use getppid because it might have + been double forked before the assuan server has been + initialized. */ + setenv ("_assuan_pipe_connect_pid", mypidstr, 1); + + /* Make sure that we never pass a connection fd variable + when using a simple pipe. */ + unsetenv ("_assuan_connection_fd"); + + execv (name, (char *const *) argv); + /* oops - use the pipe to tell the parent about it */ + snprintf (errbuf, sizeof(errbuf)-1, + "ERR %d can't exec `%s': %.50s\n", + _assuan_error (ASSUAN_Problem_Starting_Server), + name, strerror (errno)); + errbuf[sizeof(errbuf)-1] = 0; + writen (1, errbuf, strlen (errbuf)); + _exit (4); + } +#ifdef _ASSUAN_USE_DOUBLE_FORK + if (pid == -1) + _exit (1); + else + _exit (0); +#endif + } + +#ifdef _ASSUAN_USE_DOUBLE_FORK + _assuan_waitpid ((*ctx)->pid, NULL, 0); + (*ctx)->pid = -1; +#endif + + close (rp[1]); + close (wp[0]); + + return initial_handshake (ctx); +} +#endif /*!HAVE_W32_SYSTEM*/ + + +#ifndef HAVE_W32_SYSTEM +/* This function is similar to pipe_connect but uses a socketpair and + sets the I/O up to use sendmsg/recvmsg. */ +static assuan_error_t +socketpair_connect (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue) +{ + assuan_error_t err; + int fds[2]; + char mypidstr[50]; + + if (!ctx + || (name && (!argv || !argv[0])) + || (!name && argv)) + return _assuan_error (ASSUAN_Invalid_Value); + + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); + + if ( socketpair (AF_LOCAL, SOCK_STREAM, 0, fds) ) + { + _assuan_log_printf ("socketpair failed: %s\n", strerror (errno)); + return _assuan_error (ASSUAN_General_Error); + } + + err = _assuan_new_context (ctx); + if (err) + { + close (fds[0]); + close (fds[1]); + return err; + } + (*ctx)->pipe_mode = 1; + (*ctx)->inbound.fd = fds[0]; + (*ctx)->outbound.fd = fds[0]; + _assuan_init_uds_io (*ctx); + (*ctx)->deinit_handler = _assuan_uds_deinit; + (*ctx)->finish_handler = do_finish; + + (*ctx)->pid = fork (); + if ((*ctx)->pid < 0) + { + close (fds[0]); + close (fds[1]); + _assuan_release_context (*ctx); + *ctx = NULL; + return _assuan_error (ASSUAN_General_Error); + } + + if ((*ctx)->pid == 0) + { +#ifdef _ASSUAN_USE_DOUBLE_FORK + pid_t pid; + + if ((pid = fork ()) == 0) +#endif + { + int fd, i, n; + char errbuf[512]; + int *fdp; + + if (atfork) + atfork (atforkvalue, 0); + + /* Connect stdin and stdout to /dev/null. */ + fd = open ("/dev/null", O_RDONLY); + if (fd == -1 || dup2 (fd, STDIN_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null) failed: %s\n", + strerror (errno)); + _exit (4); + } + fd = open ("/dev/null", O_WRONLY); + if (fd == -1 || dup2 (fd, STDOUT_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null) failed: %s\n", + strerror (errno)); + _exit (4); + } + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + fd = open ("/dev/null", O_WRONLY); + if (fd == -1 || dup2 (fd, STDERR_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null) failed: %s\n", + strerror (errno)); + _exit (4); + } + } + + + /* Close all files which will not be duped, are not in the + fd_child_list and are not the connection fd. */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) + { + if ( i == STDIN_FILENO || i == STDOUT_FILENO + || i == STDERR_FILENO || i == fds[1]) + continue; + fdp = fd_child_list; + if (fdp) + { + while (*fdp != -1 && *fdp != i) + fdp++; + } + + if (!(fdp && *fdp != -1)) + close(i); + } + errno = 0; + + /* We store our parents pid in the environment so that the + execed assuan server is able to read the actual pid of the + client. The server can't use getppid becuase it might have + been double forked before the assuan server has been + initialized. */ + setenv ("_assuan_pipe_connect_pid", mypidstr, 1); + + /* Now set the environment variable used to convey the + connection's file descriptor. */ + sprintf (mypidstr, "%d", fds[1]); + if (setenv ("_assuan_connection_fd", mypidstr, 1)) + { + _assuan_log_printf ("setenv failed: %s\n", strerror (errno)); + _exit (4); + } + + if (!name && !argv) + { + /* No name and no args given, thus we don't do an exec + but continue the forked process. */ + _assuan_release_context (*ctx); + *ctx = NULL; + return 0; + } + + execv (name, (char *const *) argv); + /* oops - use the pipe to tell the parent about it */ + snprintf (errbuf, sizeof(errbuf)-1, + "ERR %d can't exec `%s': %.50s\n", + _assuan_error (ASSUAN_Problem_Starting_Server), + name, strerror (errno)); + errbuf[sizeof(errbuf)-1] = 0; + writen (fds[1], errbuf, strlen (errbuf)); + _exit (4); + } +#ifdef _ASSUAN_USE_DOUBLE_FORK + if (pid == -1) + _exit (1); + else + _exit (0); +#endif + } + + +#ifdef _ASSUAN_USE_DOUBLE_FORK + _assuan_waitpid ((*ctx)->pid, NULL, 0); + (*ctx)->pid = -1; +#endif + + close (fds[1]); + + return initial_handshake (ctx); +} +#endif /*!HAVE_W32_SYSTEM*/ + + + +#ifdef HAVE_W32_SYSTEM +/* Build a command line for use with W32's CreateProcess. On success + CMDLINE gets the address of a newly allocated string. */ +static int +build_w32_commandline (char * const *argv, char **cmdline) +{ + int i, n; + const char *s; + char *buf, *p; + + *cmdline = NULL; + n = 0; + for (i=0; (s=argv[i]); i++) + { + n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ + for (; *s; s++) + if (*s == '\"') + n++; /* Need to double inner quotes. */ + } + n++; + + buf = p = xtrymalloc (n); + if (!buf) + return -1; + + for (i=0; argv[i]; i++) + { + if (i) + p = stpcpy (p, " "); + if (!*argv[i]) /* Empty string. */ + p = stpcpy (p, "\"\""); + else if (strpbrk (argv[i], " \t\n\v\f\"")) + { + p = stpcpy (p, "\""); + for (s=argv[i]; *s; s++) + { + *p++ = *s; + if (*s == '\"') + *p++ = *s; + } + *p++ = '\"'; + *p = 0; + } + else + p = stpcpy (p, argv[i]); + } + + *cmdline= buf; + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +/* Create pipe where one end end is inheritable. */ +static int +create_inheritable_pipe (int filedes[2], int for_write) +{ + HANDLE r, w, h; + SECURITY_ATTRIBUTES sec_attr; + + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + if (!CreatePipe (&r, &w, &sec_attr, 0)) + { + _assuan_log_printf ("CreatePipe failed: %s\n", w32_strerror (-1)); + return -1; + } + + if (!DuplicateHandle (GetCurrentProcess(), for_write? r : w, + GetCurrentProcess(), &h, 0, + TRUE, DUPLICATE_SAME_ACCESS )) + { + _assuan_log_printf ("DuplicateHandle failed: %s\n", w32_strerror (-1)); + CloseHandle (r); + CloseHandle (w); + return -1; + } + if (for_write) + { + CloseHandle (r); + r = h; + } + else + { + CloseHandle (w); + w = h; + } + + filedes[0] = handle_to_fd (r); + filedes[1] = handle_to_fd (w); + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +#define pipe_connect pipe_connect_w32 +/* W32 version of the pipe connection code. */ +static assuan_error_t +pipe_connect_w32 (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue) +{ + assuan_error_t err; + int rp[2]; + int wp[2]; + char mypidstr[50]; + char *cmdline; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* Returns process handle. */ + 0, /* Returns primary thread handle. */ + 0, /* Returns pid. */ + 0 /* Returns tid. */ + }; + STARTUPINFO si; + int fd, *fdp; + HANDLE nullfd = INVALID_HANDLE_VALUE; + + if (!ctx || !name || !argv || !argv[0]) + return _assuan_error (ASSUAN_Invalid_Value); + + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); + + /* Build the command line. */ + if (build_w32_commandline (argv, &cmdline)) + return _assuan_error (ASSUAN_Out_Of_Core); + + /* Create thew two pipes. */ + if (create_inheritable_pipe (rp, 0)) + { + xfree (cmdline); + return _assuan_error (ASSUAN_General_Error); + } + + if (create_inheritable_pipe (wp, 1)) + { + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + xfree (cmdline); + return _assuan_error (ASSUAN_General_Error); + } + + + err = _assuan_new_context (ctx); + if (err) + { + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + CloseHandle (fd_to_handle (wp[1])); + xfree (cmdline); + return _assuan_error (ASSUAN_General_Error); + } + + (*ctx)->pipe_mode = 1; + (*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */ + (*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */ + (*ctx)->deinit_handler = do_deinit; + (*ctx)->finish_handler = do_finish; + + + /* fixme: Actually we should set the "_assuan_pipe_connect_pid" env + variable. However this requires us to write a full environment + handler, because the strings are expected in sorted order. The + suggestion given in the MS Reference Library, to save the old + value, changeit, create proces and restore it, is not thread + safe. */ + + /* Start the process. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = fd_to_handle (wp[0]); + si.hStdOutput = fd_to_handle (rp[1]); + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fd = fileno (stderr); + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != fd; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + nullfd = CreateFile ("nul", GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + if (nullfd == INVALID_HANDLE_VALUE) + { + _assuan_log_printf ("can't open `nul': %s\n", w32_strerror (-1)); + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + CloseHandle (fd_to_handle (wp[1])); + xfree (cmdline); + _assuan_release_context (*ctx); + return -1; + } + si.hStdError = nullfd; + } + else + si.hStdError = fd_to_handle (_get_osfhandle (fd)); + + + /* Note: We inherit all handles flagged as inheritable. This seems + to be a security flaw but there seems to be no way of selecting + handles to inherit. */ + /* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */ + /* name, cmdline); */ + if (!CreateProcess (name, /* Program to start. */ + cmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED), /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + _assuan_log_printf ("CreateProcess failed: %s\n", w32_strerror (-1)); + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + CloseHandle (fd_to_handle (wp[1])); + if (nullfd != INVALID_HANDLE_VALUE) + CloseHandle (nullfd); + xfree (cmdline); + _assuan_release_context (*ctx); + return _assuan_error (ASSUAN_General_Error); + } + xfree (cmdline); + cmdline = NULL; + if (nullfd != INVALID_HANDLE_VALUE) + { + CloseHandle (nullfd); + nullfd = INVALID_HANDLE_VALUE; + } + + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + + /* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */ + /* " dwProcessID=%d dwThreadId=%d\n", */ + /* pi.hProcess, pi.hThread, */ + /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + ResumeThread (pi.hThread); + CloseHandle (pi.hThread); + (*ctx)->pid = 0; /* We don't use the PID. */ + CloseHandle (pi.hProcess); /* We don't need to wait for the process. */ + + return initial_handshake (ctx); +} +#endif /*HAVE_W32_SYSTEM*/ + + +/* Connect to a server over a pipe, creating the assuan context and + returning it in CTX. The server filename is NAME, the argument + vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file + descriptors not to close in the child. */ +assuan_error_t +assuan_pipe_connect (assuan_context_t *ctx, const char *name, + const char *const argv[], int *fd_child_list) +{ + return pipe_connect (ctx, name, argv, fd_child_list, NULL, NULL); +} + + + +assuan_error_t +assuan_pipe_connect2 (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue) +{ + return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue); +} + + +/* Connect to a server over a full-duplex socket (i.e. created by + socketpair), creating the assuan context and returning it in CTX. + The server filename is NAME, the argument vector in ARGV. + FD_CHILD_LIST is a -1 terminated list of file descriptors not to + close in the child. ATFORK is called in the child right after the + fork; ATFORKVALUE is passed as the first argument and 0 is passed + as the second argument. The ATFORK function should only act if the + second value is 0. + + For now FLAGS may either take the value 0 to behave like + assuan_pipe_connect2 or 1 to enable the described full-duplex + socket behaviour. + + If NAME as well as ARGV are NULL, no exec is done but the same + process is continued. However all file descriptors are closed and + some special environment variables are set. To let the caller + detect whether the child or the parent continues, the child returns + a CTX of NULL. */ +assuan_error_t +assuan_pipe_connect_ext (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue, unsigned int flags) +{ + if ((flags & 1)) + { +#ifdef HAVE_W32_SYSTEM + return _assuan_error (ASSUAN_Not_Implemented); +#else + return socketpair_connect (ctx, name, argv, fd_child_list, + atfork, atforkvalue); +#endif + } + else + return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue); +} + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-pipe-server.c b/libtdenetwork/libgpgme-copy/assuan/assuan-pipe-server.c new file mode 100644 index 00000000..f8851614 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-pipe-server.c @@ -0,0 +1,187 @@ +/* assuan-pipe-server.c - Assuan server working over a pipe + * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#ifdef HAVE_W32_SYSTEM +#include <windows.h> +#include <fcntl.h> +#endif + +#include "assuan-defs.h" + + +static void +deinit_pipe_server (assuan_context_t ctx) +{ + /* nothing to do for this simple server */ +} + +static int +accept_connection (assuan_context_t ctx) +{ + /* This is a NOP for a pipe server */ + return 0; +} + +static int +finish_connection (assuan_context_t ctx) +{ + /* This is a NOP for a pipe server */ + return 0; +} + +/* Create a new context. Note that the handlers are set up for a pipe + server/client - this way we don't need extra dummy functions */ +int +_assuan_new_context (assuan_context_t *r_ctx) +{ + static struct assuan_io io = { _assuan_simple_read, + _assuan_simple_write, + 0, 0 }; + + assuan_context_t ctx; + int rc; + + *r_ctx = NULL; + ctx = xtrycalloc (1, sizeof *ctx); + if (!ctx) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->input_fd = -1; + ctx->output_fd = -1; + + ctx->inbound.fd = -1; + ctx->outbound.fd = -1; + ctx->io = &io; + + ctx->listen_fd = -1; + /* Use the pipe server handler as a default. */ + ctx->deinit_handler = deinit_pipe_server; + ctx->accept_handler = accept_connection; + ctx->finish_handler = finish_connection; + + rc = _assuan_register_std_commands (ctx); + if (rc) + xfree (ctx); + else + *r_ctx = ctx; + return rc; +} + + +/* Returns true if atoi(S) denotes a valid socket. */ +static int +is_valid_socket (const char *s) +{ + struct stat buf; + + if ( fstat (atoi (s), &buf ) ) + return 0; + return S_ISSOCK (buf.st_mode); +} + + +int +assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]) +{ + int rc; + + rc = _assuan_new_context (r_ctx); + if (!rc) + { + assuan_context_t ctx = *r_ctx; + const char *s; + unsigned long ul; + + ctx->is_server = 1; +#ifdef HAVE_W32_SYSTEM + /* MS Windows has so many different types of handle that one + needs to tranlsate them at many place forth and back. Also + make sure that the fiel descriptos are in binary mode. */ + setmode (filedes[0], O_BINARY); + setmode (filedes[1], O_BINARY); + ctx->inbound.fd = _get_osfhandle (filedes[0]); + ctx->outbound.fd = _get_osfhandle (filedes[1]); +#else + s = getenv ("_assuan_connection_fd"); + if (s && *s && is_valid_socket (s) ) + { + /* Well, we are called with an bi-directional file + descriptor. Prepare for using sendmsg/recvmsg. In this + case we ignore the passed file descriptors. */ + ctx->inbound.fd = ctx->outbound.fd = atoi (s); + _assuan_init_uds_io (ctx); + ctx->deinit_handler = _assuan_uds_deinit; + } + else if (filedes && filedes[0] != -1 && filedes[1] != -1 ) + { + /* Standard pipe server. */ + ctx->inbound.fd = filedes[0]; + ctx->outbound.fd = filedes[1]; + } + else + { + _assuan_release_context (*r_ctx); + *r_ctx = NULL; + return ASSUAN_Problem_Starting_Server; + } +#endif + ctx->pipe_mode = 1; + + s = getenv ("_assuan_pipe_connect_pid"); + if (s && (ul=strtoul (s, NULL, 10)) && ul) + ctx->pid = (pid_t)ul; + else + ctx->pid = (pid_t)-1; + + } + return rc; +} + + +void +_assuan_release_context (assuan_context_t ctx) +{ + if (ctx) + { + xfree (ctx->hello_line); + xfree (ctx->okay_line); + xfree (ctx->cmdtbl); + xfree (ctx); + } +} + +void +assuan_deinit_server (assuan_context_t ctx) +{ + if (ctx) + { + /* We use this function pointer to avoid linking other server + when not needed but still allow for a generic deinit function. */ + ctx->deinit_handler (ctx); + ctx->deinit_handler = NULL; + _assuan_release_context (ctx); + } +} diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-socket-connect.c b/libtdenetwork/libgpgme-copy/assuan/assuan-socket-connect.c new file mode 100644 index 00000000..5953f1c3 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-socket-connect.c @@ -0,0 +1,184 @@ +/* assuan-socket-connect.c - Assuan socket based client + * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif + +#include "assuan-defs.h" + +/* Hacks for Slowaris. */ +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + +#ifndef SUN_LEN +# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + + strlen ((ptr)->sun_path)) +#endif + + +static int +do_finish (assuan_context_t ctx) +{ + if (ctx->inbound.fd != -1) + { + _assuan_close (ctx->inbound.fd); + } + ctx->inbound.fd = -1; + ctx->outbound.fd = -1; + return 0; +} + +static void +do_deinit (assuan_context_t ctx) +{ + do_finish (ctx); +} + + +/* Make a connection to the Unix domain socket NAME and return a new + Assuan context in CTX. SERVER_PID is currently not used but may + become handy in the future. */ +assuan_error_t +assuan_socket_connect (assuan_context_t *r_ctx, + const char *name, pid_t server_pid) +{ + return assuan_socket_connect_ext (r_ctx, name, server_pid, 0); +} + + +/* Make a connection to the Unix domain socket NAME and return a new + Assuan context in CTX. SERVER_PID is currently not used but may + become handy in the future. With flags set to 1 sendmsg and + recvmesg are used. */ +assuan_error_t +assuan_socket_connect_ext (assuan_context_t *r_ctx, + const char *name, pid_t server_pid, + unsigned int flags) +{ + static struct assuan_io io = { _assuan_simple_read, + _assuan_simple_write }; + + assuan_error_t err; + assuan_context_t ctx; + int fd; + struct sockaddr_un srvr_addr; + size_t len; + const char *s; + + if (!r_ctx || !name) + return _assuan_error (ASSUAN_Invalid_Value); + *r_ctx = NULL; + + /* We require that the name starts with a slash, so that we + eventually can reuse this function for other socket types. To + make things easier we allow an optional dirver prefix. */ + s = name; + if (*s && s[1] == ':') + s += 2; + if (*s != DIRSEP_C && *s != '/') + return _assuan_error (ASSUAN_Invalid_Value); + + if (strlen (name)+1 >= sizeof srvr_addr.sun_path) + return _assuan_error (ASSUAN_Invalid_Value); + + err = _assuan_new_context (&ctx); + if (err) + return err; + ctx->deinit_handler = ((flags&1))? _assuan_uds_deinit : do_deinit; + ctx->finish_handler = do_finish; + + fd = _assuan_sock_new (PF_LOCAL, SOCK_STREAM, 0); + if (fd == -1) + { + _assuan_log_printf ("can't create socket: %s\n", strerror (errno)); + _assuan_release_context (ctx); + return _assuan_error (ASSUAN_General_Error); + } + + memset (&srvr_addr, 0, sizeof srvr_addr); + srvr_addr.sun_family = AF_LOCAL; + strncpy (srvr_addr.sun_path, name, sizeof (srvr_addr.sun_path) - 1); + srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0; + len = SUN_LEN (&srvr_addr); + + + if (_assuan_sock_connect (fd, (struct sockaddr *) &srvr_addr, len) == -1) + { + _assuan_log_printf ("can't connect to `%s': %s\n", + name, strerror (errno)); + _assuan_release_context (ctx); + _assuan_close (fd); + return _assuan_error (ASSUAN_Connect_Failed); + } + + ctx->inbound.fd = fd; + ctx->outbound.fd = fd; + ctx->io = &io; + if ((flags&1)) + _assuan_init_uds_io (ctx); + + /* initial handshake */ + { + int okay, off; + + err = _assuan_read_from_server (ctx, &okay, &off); + if (err) + _assuan_log_printf ("can't connect to server: %s\n", + assuan_strerror (err)); + else if (okay != 1) + { + /*LOG ("can't connect to server: `");*/ + _assuan_log_sanitized_string (ctx->inbound.line); + fprintf (assuan_get_assuan_log_stream (), "'\n"); + err = _assuan_error (ASSUAN_Connect_Failed); + } + } + + if (err) + { + assuan_disconnect (ctx); + } + else + *r_ctx = ctx; + return 0; +} + + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-socket-server.c b/libtdenetwork/libgpgme-copy/assuan/assuan-socket-server.c new file mode 100644 index 00000000..45c227d6 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-socket-server.c @@ -0,0 +1,187 @@ +/* assuan-socket-server.c - Assuan socket based server + * Copyright (C) 2002 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif + +#include "assuan-defs.h" + +static struct assuan_io io = { _assuan_simple_read, + _assuan_simple_write }; + + +static int +accept_connection_bottom (assuan_context_t ctx) +{ + int fd = ctx->connected_fd; + + ctx->peercred.valid = 0; +#ifdef HAVE_SO_PEERCRED + { + struct ucred cr; + socklen_t cl = sizeof cr; + + if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)) + { + ctx->peercred.pid = cr.pid; + ctx->peercred.uid = cr.uid; + ctx->peercred.gid = cr.gid; + ctx->peercred.valid = 1; + + /* This overrides any already set PID if the function returns + a valid one. */ + if (cr.pid != (pid_t)-1 && cr.pid) + ctx->pid = cr.pid; + } + } +#endif + + ctx->inbound.fd = fd; + ctx->inbound.eof = 0; + ctx->inbound.linelen = 0; + ctx->inbound.attic.linelen = 0; + ctx->inbound.attic.pending = 0; + + ctx->outbound.fd = fd; + ctx->outbound.data.linelen = 0; + ctx->outbound.data.error = 0; + + ctx->confidential = 0; + + return 0; +} + + +static int +accept_connection (assuan_context_t ctx) +{ + int fd; + struct sockaddr_un clnt_addr; + socklen_t len = sizeof clnt_addr; + + fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len ); + if (fd == -1) + { + ctx->os_errno = errno; + return _assuan_error (ASSUAN_Accept_Failed); + } + + ctx->connected_fd = fd; + return accept_connection_bottom (ctx); +} + +static int +finish_connection (assuan_context_t ctx) +{ + if (ctx->inbound.fd != -1) + { + _assuan_close (ctx->inbound.fd); + } + ctx->inbound.fd = -1; + ctx->outbound.fd = -1; + return 0; +} + + +static void +deinit_socket_server (assuan_context_t ctx) +{ + finish_connection (ctx); +} + +/* Initialize a server for the socket LISTEN_FD which has already be + put into listen mode */ +int +assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd) +{ + return assuan_init_socket_server_ext (r_ctx, listen_fd, 0); +} + +/* Initialize a server using the already accepted socket FD. This + fucntion is deprecated. */ +int +assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd) +{ + return assuan_init_socket_server_ext (r_ctx, fd, 2); +} + + +/* + Flag bits: 0 - use sendmsg/recvmsg to allow descriptor passing + 1 - FD has already been accepted. +*/ +int +assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd, + unsigned int flags) +{ + assuan_context_t ctx; + int rc; + + *r_ctx = NULL; + ctx = xtrycalloc (1, sizeof *ctx); + if (!ctx) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->is_server = 1; + if ((flags & 2)) + ctx->pipe_mode = 1; /* We want a second accept to indicate EOF. */ + ctx->input_fd = -1; + ctx->output_fd = -1; + + ctx->inbound.fd = -1; + ctx->outbound.fd = -1; + + if ((flags & 2)) + { + ctx->listen_fd = -1; + ctx->connected_fd = fd; + } + else + { + ctx->listen_fd = fd; + ctx->connected_fd = -1; + } + ctx->deinit_handler = (flags & 1)? _assuan_uds_deinit:deinit_socket_server; + ctx->accept_handler = ((flags & 2) + ? accept_connection_bottom + : accept_connection); + ctx->finish_handler = finish_connection; + + ctx->io = &io; + if ((flags & 1)) + _assuan_init_uds_io (ctx); + + rc = _assuan_register_std_commands (ctx); + if (rc) + xfree (ctx); + else + *r_ctx = ctx; + return rc; +} diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-socket.c b/libtdenetwork/libgpgme-copy/assuan/assuan-socket.c new file mode 100644 index 00000000..6aa57089 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-socket.c @@ -0,0 +1,148 @@ +/* assuan-socket.c + * Copyright (C) 2004, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdio.h> +#ifdef HAVE_W32_SYSTEM +#include <windows.h> +#include <io.h> +#else +#include <sys/types.h> +#include <sys/socket.h> +#endif +#include "assuan-defs.h" + +/* Hacks for Slowaris. */ +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + +int +_assuan_close (int fd) +{ +#ifndef HAVE_W32_SYSTEM + return close (fd); +#else + int rc = closesocket (fd); + if (rc && WSAGetLastError () == WSAENOTSOCK) + rc = close (fd); + return rc; +#endif +} + + +int +_assuan_sock_new (int domain, int type, int proto) +{ +#ifndef HAVE_W32_SYSTEM + return socket (domain, type, proto); +#else + if (domain == AF_UNIX || domain == AF_LOCAL) + domain = AF_INET; + return socket (domain, type, proto); +#endif +} + + +int +_assuan_sock_connect (int sockfd, struct sockaddr * addr, int addrlen) +{ +#ifndef HAVE_W32_SYSTEM + return connect (sockfd, addr, addrlen); +#else + struct sockaddr_in myaddr; + struct sockaddr_un * unaddr; + FILE * fp; + int port = 0; + + unaddr = (struct sockaddr_un *)addr; + fp = fopen (unaddr->sun_path, "rb"); + if (!fp) + return -1; + fscanf (fp, "%d", &port); + fclose (fp); + /* XXX: set errno in this case */ + if (port < 0 || port > 65535) + return -1; + + myaddr.sin_family = AF_INET; + myaddr.sin_port = port; + myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + /* we need this later. */ + unaddr->sun_family = myaddr.sin_family; + unaddr->sun_port = myaddr.sin_port; + unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; + + return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr); +#endif +} + + +int +_assuan_sock_bind (int sockfd, struct sockaddr * addr, int addrlen) +{ +#ifndef HAVE_W32_SYSTEM + return bind (sockfd, addr, addrlen); +#else + if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX) + { + struct sockaddr_in myaddr; + struct sockaddr_un * unaddr; + FILE * fp; + int len = sizeof myaddr; + int rc; + + myaddr.sin_port = 0; + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + rc = bind (sockfd, (struct sockaddr *)&myaddr, len); + if (rc) + return rc; + rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len); + if (rc) + return rc; + unaddr = (struct sockaddr_un *)addr; + fp = fopen (unaddr->sun_path, "wb"); + if (!fp) + return -1; + fprintf (fp, "%d", myaddr.sin_port); + fclose (fp); + + /* we need this later. */ + unaddr->sun_family = myaddr.sin_family; + unaddr->sun_port = myaddr.sin_port; + unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; + + return 0; + } + return bind (sockfd, addr, addrlen); +#endif +} + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-uds.c b/libtdenetwork/libgpgme-copy/assuan/assuan-uds.c new file mode 100644 index 00000000..e9e81016 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-uds.c @@ -0,0 +1,311 @@ +/* assuan-uds.c - Assuan unix domain socket utilities + * Copyright (C) 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif +#if HAVE_SYS_UIO_H +#include <sys/uio.h> +#endif +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <assert.h> + +#include "assuan-defs.h" + +#ifdef USE_DESCRIPTOR_PASSING +/* Provide replacement for missing CMSG maccros. We assume that + size_t matches the tqalignment requirement. */ +#define MY_ALIGN(n) ((((n))+ sizeof(size_t)-1) & (size_t)~(sizeof(size_t)-1)) +#ifndef CMSG_SPACE +#define CMSG_SPACE(n) (MY_ALIGN(sizeof(struct cmsghdr)) + MY_ALIGN((n))) +#endif +#ifndef CMSG_LEN +#define CMSG_LEN(n) (MY_ALIGN(sizeof(struct cmsghdr)) + (n)) +#endif +#ifndef CMSG_FIRSTHDR +#define CMSG_FIRSTHDR(mhdr) \ + ((size_t)(mhdr)->msg_controllen >= sizeof (struct cmsghdr) \ + ? (struct cmsghdr*) (mhdr)->msg_control : (struct cmsghdr*)NULL) +#endif +#ifndef CMSG_DATA +#define CMSG_DATA(cmsg) ((unsigned char*)((struct cmsghdr*)(cmsg)+1)) +#endif +#endif /*USE_DESCRIPTOR_PASSING*/ + + +/* Read from a unix domain socket using sendmsg. + + FIXME: We don't need the buffering. It is a leftover from the time + when we used datagrams. */ +static ssize_t +uds_reader (assuan_context_t ctx, void *buf, size_t buflen) +{ + int len = ctx->uds.buffersize; + +#ifndef HAVE_W32_SYSTEM + if (!ctx->uds.bufferallocated) + { + ctx->uds.buffer = xtrymalloc (2048); + if (!ctx->uds.buffer) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->uds.bufferallocated = 2048; + } + + while (!len) /* No data is buffered. */ + { + struct msghdr msg; + struct iovec iovec; +#ifdef USE_DESCRIPTOR_PASSING + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof (int))]; + } control_u; + struct cmsghdr *cmptr; +#endif /*USE_DESCRIPTOR_PASSING*/ + + memset (&msg, 0, sizeof (msg)); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iovec; + msg.msg_iovlen = 1; + iovec.iov_base = ctx->uds.buffer; + iovec.iov_len = ctx->uds.bufferallocated; +#ifdef USE_DESCRIPTOR_PASSING + msg.msg_control = control_u.control; + msg.msg_controllen = sizeof (control_u.control); +#endif + + len = _assuan_simple_recvmsg (ctx, &msg); + if (len < 0) + return -1; + + ctx->uds.buffersize = len; + ctx->uds.bufferoffset = 0; + +#ifdef USE_DESCRIPTOR_PASSING + cmptr = CMSG_FIRSTHDR (&msg); + if (cmptr && cmptr->cmsg_len == CMSG_LEN (sizeof(int))) + { + if (cmptr->cmsg_level != SOL_SOCKET + || cmptr->cmsg_type != SCM_RIGHTS) + _assuan_log_printf ("unexpected ancillary data received\n"); + else + { + int fd = *((int*)CMSG_DATA (cmptr)); + + if (ctx->uds.pendingfdscount >= DIM (ctx->uds.pendingfds)) + { + _assuan_log_printf ("too many descriptors pending - " + "closing received descriptor %d\n", fd); + _assuan_close (fd); + } + else + ctx->uds.pendingfds[ctx->uds.pendingfdscount++] = fd; + } + } +#endif /*USE_DESCRIPTOR_PASSING*/ + } + +#else /*HAVE_W32_SYSTEM*/ + + len = recvfrom (ctx->inbound.fd, buf, buflen, 0, NULL, NULL); + +#endif /*HAVE_W32_SYSTEM*/ + + /* Return some data to the user. */ + + if (len > buflen) /* We have more than the user requested. */ + len = buflen; + + memcpy (buf, ctx->uds.buffer + ctx->uds.bufferoffset, len); + ctx->uds.buffersize -= len; + assert (ctx->uds.buffersize >= 0); + ctx->uds.bufferoffset += len; + assert (ctx->uds.bufferoffset <= ctx->uds.bufferallocated); + + return len; +} + + +/* Write to the domain server. */ +static ssize_t +uds_writer (assuan_context_t ctx, const void *buf, size_t buflen) +{ +#ifndef HAVE_W32_SYSTEM + struct msghdr msg; + struct iovec iovec; + ssize_t len; + + memset (&msg, 0, sizeof (msg)); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iovlen = 1; + msg.msg_iov = &iovec; + iovec.iov_base = (void*)buf; + iovec.iov_len = buflen; + + len = _assuan_simple_sendmsg (ctx, &msg); +#else /*HAVE_W32_SYSTEM*/ + int len; + + len = sendto (ctx->outbound.fd, buf, buflen, 0, + (struct sockaddr *)&ctx->serveraddr, + sizeof (struct sockaddr_in)); +#endif /*HAVE_W32_SYSTEM*/ + return len; +} + + +static assuan_error_t +uds_sendfd (assuan_context_t ctx, int fd) +{ +#ifdef USE_DESCRIPTOR_PASSING + struct msghdr msg; + struct iovec iovec; + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof (int))]; + } control_u; + struct cmsghdr *cmptr; + int len; + char buffer[80]; + + /* We need to send some real data so that a read won't return 0 + which will be taken as an EOF. It also helps with debugging. */ + snprintf (buffer, sizeof(buffer)-1, "# descriptor %d is in flight\n", fd); + buffer[sizeof(buffer)-1] = 0; + + memset (&msg, 0, sizeof (msg)); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iovlen = 1; + msg.msg_iov = &iovec; + iovec.iov_base = buffer; + iovec.iov_len = strlen (buffer); + + msg.msg_control = control_u.control; + msg.msg_controllen = sizeof (control_u.control); + cmptr = CMSG_FIRSTHDR (&msg); + cmptr->cmsg_len = CMSG_LEN(sizeof(int)); + cmptr->cmsg_level = SOL_SOCKET; + cmptr->cmsg_type = SCM_RIGHTS; + *((int*)CMSG_DATA (cmptr)) = fd; + + len = _assuan_simple_sendmsg (ctx, &msg); + if (len < 0) + { + _assuan_log_printf ("uds_sendfd: %s\n", strerror (errno)); + return _assuan_error (ASSUAN_Write_Error); + } + else + return 0; +#else + return _assuan_error (ASSUAN_Not_Implemented); +#endif +} + + +static assuan_error_t +uds_receivefd (assuan_context_t ctx, int *fd) +{ +#ifdef USE_DESCRIPTOR_PASSING + int i; + + if (!ctx->uds.pendingfdscount) + { + _assuan_log_printf ("no pending file descriptors!\n"); + return _assuan_error (ASSUAN_General_Error); + } + assert (ctx->uds.pendingfdscount <= DIM(ctx->uds.pendingfds)); + + *fd = ctx->uds.pendingfds[0]; + for (i=1; i < ctx->uds.pendingfdscount; i++) + ctx->uds.pendingfds[i-1] = ctx->uds.pendingfds[i]; + ctx->uds.pendingfdscount--; + + return 0; +#else + return _assuan_error (ASSUAN_Not_Implemented); +#endif +} + + +/* Close all pending fds. */ +void +_assuan_uds_close_fds (assuan_context_t ctx) +{ + int i; + + for (i = 0; i < ctx->uds.pendingfdscount; i++) + _assuan_close (ctx->uds.pendingfds[i]); + ctx->uds.pendingfdscount = 0; +} + +/* Deinitialize the unix domain socket I/O functions. */ +void +_assuan_uds_deinit (assuan_context_t ctx) +{ + /* First call the finish_handler which should close descriptors etc. */ + ctx->finish_handler (ctx); + + if (ctx->uds.buffer) + { + assert (ctx->uds.bufferallocated); + ctx->uds.bufferallocated = 0; + xfree (ctx->uds.buffer); + } + + _assuan_uds_close_fds (ctx); +} + + +/* Helper function to initialize a context for domain I/O. */ +void +_assuan_init_uds_io (assuan_context_t ctx) +{ + static struct assuan_io io = { uds_reader, uds_writer, + uds_sendfd, uds_receivefd }; + + ctx->io = &io; + ctx->uds.buffer = 0; + ctx->uds.bufferoffset = 0; + ctx->uds.buffersize = 0; + ctx->uds.bufferallocated = 0; + ctx->uds.pendingfdscount = 0; +} + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan-util.c b/libtdenetwork/libgpgme-copy/assuan/assuan-util.c new file mode 100644 index 00000000..d12277fc --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan-util.c @@ -0,0 +1,171 @@ +/* assuan-util.c - Utility functions for Assuan + * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> + +#include "assuan-defs.h" + +static void *(*alloc_func)(size_t n) = malloc; +static void *(*realloc_func)(void *p, size_t n) = realloc; +static void (*free_func)(void*) = free; + +void +assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), + void *(*new_realloc_func)(void *p, size_t n), + void (*new_free_func)(void*) ) +{ + alloc_func = new_alloc_func; + realloc_func = new_realloc_func; + free_func = new_free_func; +} + +void * +_assuan_malloc (size_t n) +{ + return alloc_func (n); +} + +void * +_assuan_realloc (void *a, size_t n) +{ + return realloc_func (a, n); +} + +void * +_assuan_calloc (size_t n, size_t m) +{ + void *p; + size_t nbytes; + + nbytes = n * m; + if (m && nbytes / m != n) + { + errno = ENOMEM; + return NULL; + } + + p = _assuan_malloc (nbytes); + if (p) + memset (p, 0, nbytes); + return p; +} + +void +_assuan_free (void *p) +{ + if (p) + free_func (p); +} + + +/* Store the error in the context so that the error sending function + can take out a descriptive text. Inside the assuan code, use the + macro set_error instead of this function. */ +int +assuan_set_error (assuan_context_t ctx, int err, const char *text) +{ + ctx->err_no = err; + ctx->err_str = text; + return err; +} + +void +assuan_set_pointer (assuan_context_t ctx, void *pointer) +{ + if (ctx) + ctx->user_pointer = pointer; +} + +void * +assuan_get_pointer (assuan_context_t ctx) +{ + return ctx? ctx->user_pointer : NULL; +} + + +void +assuan_begin_confidential (assuan_context_t ctx) +{ + if (ctx) + { + ctx->confidential = 1; + } +} + +void +assuan_end_confidential (assuan_context_t ctx) +{ + if (ctx) + { + ctx->confidential = 0; + } +} + + +void +assuan_set_io_monitor (assuan_context_t ctx, + unsigned int (*monitor)(assuan_context_t ctx, + int direction, + const char *line, + size_t linelen)) +{ + if (ctx) + { + ctx->io_monitor = monitor; + } +} + + + + +/* For context CTX, set the flag FLAG to VALUE. Values for flags + are usually 1 or 0 but certain flags might allow for other values; + see the description of the type assuan_flag_t for details. */ +void +assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value) +{ + if (!ctx) + return; + switch (flag) + { + case ASSUAN_NO_WAITPID: ctx->flags.no_waitpid = value; break; + } +} + +/* Return the VALUE of FLAG in context CTX. */ +int +assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag) +{ + if (!ctx) + return 0; + switch (flag) + { + case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid; + } + return 0; +} + + diff --git a/libtdenetwork/libgpgme-copy/assuan/assuan.h b/libtdenetwork/libgpgme-copy/assuan/assuan.h new file mode 100644 index 00000000..8d0a3960 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/assuan.h @@ -0,0 +1,565 @@ +/* assuan.c - Definitions for the Assuan IPC library + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef ASSUAN_H +#define ASSUAN_H + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + + +/* To use this file with libraries the following macros are useful: + + #define _ASSUAN_EXT_SYM_PREFIX _foo_ + + This prefixes all external symbols with "_foo_". + + #define _ASSUAN_ONLY_GPG_ERRORS + + If this is defined all old-style Assuan error codes are made + inactive as well as other dereacted stuff. + + The follwing macros are used internally in the implementation of + libassuan: + + #define _ASSUAN_NO_PTH + + This avoids inclusion of special GNU Pth hacks. + + #define _ASSUAN_NO_FIXED_SIGNALS + + This disables changing of certain signal handler; i.e. SIGPIPE. + + #define _ASSUAN_USE_DOUBLE_FORK + + Use a double fork approach when connecting to a server through + a pipe. + */ +/**** Begin GPGME specific modifications. ******/ +#define _ASSUAN_EXT_SYM_PREFIX _gpgme_ +#define _ASSUAN_NO_PTH +#define _ASSUAN_NO_FIXED_SIGNALS +#define _ASSUAN_USE_DOUBLE_FORK + +#ifdef _ASSUAN_IN_GPGME_BUILD_ASSUAN +int _gpgme_io_read (int fd, void *buffer, size_t count); +int _gpgme_io_write (int fd, const void *buffer, size_t count); +ssize_t _gpgme_ath_waitpid (pid_t pid, int *status, int options); +#ifdef HAVE_W32_SYSTEM +int _gpgme_ath_accept (int s, void *addr, int *length_ptr); +#else /*!HAVE_W32_SYSTEM*/ +struct sockaddr; +struct msghdr; +ssize_t _gpgme_ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout); +int _gpgme_ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr); +int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length); +int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags); +int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags); +int _gpgme_io_sendmsg (int sock, const struct msghdr *msg, int flags); +int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags); +#endif /*!HAVE_W32_SYSTEM*/ + +#define read _gpgme_io_read +#define write _gpgme_io_write +#define waitpid _gpgme_ath_waitpid +#define select _gpgme_ath_select +#define accept _gpgme_ath_accept +#define connect _gpgme_ath_connect +#define sendmsg _gpgme_io_sendmsg +#define recvmsg _gpgme_io_recvmsg +#endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/ +/**** End GPGME specific modifications. ******/ + + +#ifdef _ASSUAN_EXT_SYM_PREFIX +#define _ASSUAN_PREFIX1(x,y) x ## y +#define _ASSUAN_PREFIX2(x,y) _ASSUAN_PREFIX1(x,y) +#define _ASSUAN_PREFIX(x) _ASSUAN_PREFIX2(_ASSUAN_EXT_SYM_PREFIX,x) +#define assuan_ _ASSUAN_PREFIX(assuan_) +#define assuan_register_command _ASSUAN_PREFIX(assuan_register_command) +#define assuan_register_post_cmd_notify \ + _ASSUAN_PREFIX(assuan_register_post_cmd_notify) +#define assuan_register_bye_notify _ASSUAN_PREFIX(assuan_register_bye_notify) +#define assuan_register_reset_notify \ + _ASSUAN_PREFIX(assuan_register_reset_notify) +#define assuan_register_cancel_notify \ + _ASSUAN_PREFIX(assuan_register_cancel_notify) +#define assuan_register_input_notify \ + _ASSUAN_PREFIX(assuan_register_input_notify) +#define assuan_register_output_notify \ + _ASSUAN_PREFIX(assuan_register_output_notify) +#define assuan_register_option_handler \ + _ASSUAN_PREFIX(assuan_register_option_handler) +#define assuan_process _ASSUAN_PREFIX(assuan_process) +#define assuan_process_next _ASSUAN_PREFIX(assuan_process_next) +#define assuan_get_active_fds _ASSUAN_PREFIX(assuan_get_active_fds) +#define assuan_get_data_fp _ASSUAN_PREFIX(assuan_get_data_fp) +#define assuan_set_okay_line _ASSUAN_PREFIX(assuan_set_okay_line) +#define assuan_write_status _ASSUAN_PREFIX(assuan_write_status) +#define assuan_command_parse_fd _ASSUAN_PREFIX(assuan_command_parse_fd) +#define assuan_set_hello_line _ASSUAN_PREFIX(assuan_set_hello_line) +#define assuan_accept _ASSUAN_PREFIX(assuan_accept) +#define assuan_get_input_fd _ASSUAN_PREFIX(assuan_get_input_fd) +#define assuan_get_output_fd _ASSUAN_PREFIX(assuan_get_output_fd) +#define assuan_close_input_fd _ASSUAN_PREFIX(assuan_close_input_fd) +#define assuan_close_output_fd _ASSUAN_PREFIX(assuan_close_output_fd) +#define assuan_init_pipe_server _ASSUAN_PREFIX(assuan_init_pipe_server) +#define assuan_deinit_server _ASSUAN_PREFIX(assuan_deinit_server) +#define assuan_init_socket_server _ASSUAN_PREFIX(assuan_init_socket_server) +#define assuan_init_connected_socket_server \ + _ASSUAN_PREFIX(assuan_init_connected_socket_server) +#define assuan_init_socket_server_ext \ + _ASSUAN_PREFIX(assuan_init_socket_server_ext) +#define assuan_pipe_connect _ASSUAN_PREFIX(assuan_pipe_connect) +#define assuan_pipe_connect_ext _ASSUAN_PREFIX(assuan_pipe_connect_ext) +#define assuan_socket_connect _ASSUAN_PREFIX(assuan_socket_connect) +#define assuan_socket_connect_ext _ASSUAN_PREFIX(assuan_socket_connect_ext) +#define assuan_disconnect _ASSUAN_PREFIX(assuan_disconnect) +#define assuan_get_pid _ASSUAN_PREFIX(assuan_get_pid) +#define assuan_get_peercred _ASSUAN_PREFIX(assuan_get_peercred) +#define assuan_transact _ASSUAN_PREFIX(assuan_transact) +#define assuan_inquire _ASSUAN_PREFIX(assuan_inquire) +#define assuan_read_line _ASSUAN_PREFIX(assuan_read_line) +#define assuan_pending_line _ASSUAN_PREFIX(assuan_pending_line) +#define assuan_write_line _ASSUAN_PREFIX(assuan_write_line) +#define assuan_send_data _ASSUAN_PREFIX(assuan_send_data) +#define assuan_sendfd _ASSUAN_PREFIX(assuan_sendfd) +#define assuan_receivefd _ASSUAN_PREFIX(assuan_receivefd) +#define assuan_set_malloc_hooks _ASSUAN_PREFIX(assuan_set_malloc_hooks) +#define assuan_set_log_stream _ASSUAN_PREFIX(assuan_set_log_stream) +#define assuan_set_error _ASSUAN_PREFIX(assuan_set_error) +#define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer) +#define assuan_get_pointer _ASSUAN_PREFIX(assuan_get_pointer) +#define assuan_set_io_monitor _ASSUAN_PREFIX(assuan_set_io_monitor) +#define assuan_begin_confidential _ASSUAN_PREFIX(assuan_begin_confidential) +#define assuan_end_confidential _ASSUAN_PREFIX(assuan_end_confidential) +#define assuan_strerror _ASSUAN_PREFIX(assuan_strerror) +#define assuan_set_assuan_err_source \ + _ASSUAN_PREFIX(assuan_set_assuan_err_source) +#define assuan_set_assuan_log_stream \ + _ASSUAN_PREFIX(assuan_set_assuan_log_stream) +#define assuan_get_assuan_log_stream \ + _ASSUAN_PREFIX(assuan_get_assuan_log_stream) +#define assuan_get_assuan_log_prefix \ + _ASSUAN_PREFIX(assuan_get_assuan_log_prefix) +#define assuan_set_flag _ASSUAN_PREFIX(assuan_set_flag) +#define assuan_get_flag _ASSUAN_PREFIX(assuan_get_flag) + +/* And now the internal functions, argh... */ +#define _assuan_read_line _ASSUAN_PREFIX(_assuan_read_line) +#define _assuan_cookie_write_data _ASSUAN_PREFIX(_assuan_cookie_write_data) +#define _assuan_cookie_write_flush _ASSUAN_PREFIX(_assuan_cookie_write_flush) +#define _assuan_read_from_server _ASSUAN_PREFIX(_assuan_read_from_server) +#define _assuan_domain_init _ASSUAN_PREFIX(_assuan_domain_init) +#define _assuan_register_std_commands \ + _ASSUAN_PREFIX(_assuan_register_std_commands) +#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read) +#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write) +#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read) +#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write) +#define _assuan_new_context _ASSUAN_PREFIX(_assuan_new_context) +#define _assuan_release_context _ASSUAN_PREFIX(_assuan_release_context) +#define _assuan_malloc _ASSUAN_PREFIX(_assuan_malloc) +#define _assuan_realloc _ASSUAN_PREFIX(_assuan_realloc) +#define _assuan_calloc _ASSUAN_PREFIX(_assuan_calloc) +#define _assuan_free _ASSUAN_PREFIX(_assuan_free) +#define _assuan_log_print_buffer _ASSUAN_PREFIX(_assuan_log_print_buffer) +#define _assuan_log_sanitized_string \ + _ASSUAN_PREFIX(_assuan_log_sanitized_string) +#define _assuan_log_printf _ASSUAN_PREFIX(_assuan_log_printf) +#define _assuan_set_default_log_stream \ + _ASSUAN_PREFIX(_assuan_set_default_log_stream) +#define _assuan_w32_strerror _ASSUAN_PREFIX(_assuan_w32_strerror) +#define _assuan_write_line _ASSUAN_PREFIX(_assuan_write_line) +#define _assuan_close _ASSUAN_PREFIX(_assuan_close) +#define _assuan_sock_new _ASSUAN_PREFIX(_assuan_sock_new) +#define _assuan_sock_bind _ASSUAN_PREFIX(_assuan_sock_bind) +#define _assuan_sock_connect _ASSUAN_PREFIX(_assuan_sock_connect) + +#endif /*_ASSUAN_EXT_SYM_PREFIX*/ + + +#ifdef __cplusplus +extern "C" +{ +#if 0 +} +#endif +#endif + + +/* Check for compiler features. */ +#if __GNUC__ +#define _ASSUAN_GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if _ASSUAN_GCC_VERSION > 30100 +#define _ASSUAN_DEPRECATED __attribute__ ((__deprecated__)) +#endif +#endif +#ifndef _ASSUAN_DEPRECATED +#define _ASSUAN_DEPRECATED +#endif + + +/* Assuan error codes. These are only used by old applications or + those applications which won't make use of libgpg-error. */ +#ifndef _ASSUAN_ONLY_GPG_ERRORS +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_No_Error 0 +#endif +#define ASSUAN_General_Error 1 +#define ASSUAN_Out_Of_Core 2 +#define ASSUAN_Invalid_Value 3 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Timeout 4 +#endif +#define ASSUAN_Read_Error 5 +#define ASSUAN_Write_Error 6 +#define ASSUAN_Problem_Starting_Server 7 +#define ASSUAN_Not_A_Server 8 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Not_A_Client 9 +#endif +#define ASSUAN_Nested_Commands 10 +#define ASSUAN_Invalid_Response 11 +#define ASSUAN_No_Data_Callback 12 +#define ASSUAN_No_Inquire_Callback 13 +#define ASSUAN_Connect_Failed 14 +#define ASSUAN_Accept_Failed 15 + + /* Error codes above 99 are meant as status codes */ +#define ASSUAN_Not_Implemented 100 +#define ASSUAN_Server_Fault 101 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Invalid_Command 102 +#endif +#define ASSUAN_Unknown_Command 103 +#define ASSUAN_Syntax_Error 104 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Parameter_Error 105 +#endif +#define ASSUAN_Parameter_Conflict 106 +#define ASSUAN_Line_Too_Long 107 +#define ASSUAN_Line_Not_Terminated 108 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_No_Input 109 +#define ASSUAN_No_Output 110 +#endif +#define ASSUAN_Canceled 111 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Unsupported_Algorithm 112 +#define ASSUAN_Server_Resource_Problem 113 +#define ASSUAN_Server_IO_Error 114 +#define ASSUAN_Server_Bug 115 +#define ASSUAN_No_Data_Available 116 +#define ASSUAN_Invalid_Data 117 +#endif +#define ASSUAN_Unexpected_Command 118 +#define ASSUAN_Too_Much_Data 119 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Inquire_Unknown 120 +#define ASSUAN_Inquire_Error 121 +#define ASSUAN_Invalid_Option 122 +#define ASSUAN_Invalid_Index 123 +#define ASSUAN_Unexpected_tqStatus 124 +#define ASSUAN_Unexpected_Data 125 +#define ASSUAN_Invalid_tqStatus 126 +#define ASSUAN_Locale_Problem 127 +#endif +#define ASSUAN_Not_Confirmed 128 + + /* Warning: Don't use the Error codes, below they are deprecated. */ +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Bad_Certificate 201 +#define ASSUAN_Bad_Certificate_Chain 202 +#define ASSUAN_Missing_Certificate 203 +#define ASSUAN_Bad_Signature 204 +#define ASSUAN_No_Agent 205 +#define ASSUAN_Agent_Error 206 +#define ASSUAN_No_Public_Key 207 +#define ASSUAN_No_Secret_Key 208 +#define ASSUAN_Invalid_Name 209 + +#define ASSUAN_Cert_Revoked 301 +#define ASSUAN_No_CRL_For_Cert 302 +#define ASSUAN_CRL_Too_Old 303 +#define ASSUAN_Not_Trusted 304 + +#define ASSUAN_Card_Error 401 +#define ASSUAN_Invalid_Card 402 +#define ASSUAN_No_PKCS15_App 403 +#define ASSUAN_Card_Not_Present 404 +#define ASSUAN_Invalid_Id 405 + + /* Error codes in the range 1000 to 9999 may be used by applications + at their own discretion. */ +#define ASSUAN_USER_ERROR_FIRST 1000 +#define ASSUAN_USER_ERROR_LAST 9999 +#endif + +typedef int assuan_error_t; + +typedef assuan_error_t AssuanError _ASSUAN_DEPRECATED; + +/* This is a list of pre-registered ASSUAN commands */ +/* Note, these command IDs are now deprectated and solely exists for + compatibility reasons. */ +typedef enum +{ + ASSUAN_CMD_NOP = 0, + ASSUAN_CMD_CANCEL, /* cancel the current request */ + ASSUAN_CMD_BYE, + ASSUAN_CMD_AUTH, + ASSUAN_CMD_RESET, + ASSUAN_CMD_OPTION, + ASSUAN_CMD_DATA, + ASSUAN_CMD_END, + ASSUAN_CMD_INPUT, + ASSUAN_CMD_OUTPUT, + + ASSUAN_CMD_USER = 256 /* Other commands should be used with this offset*/ +} AssuanCommand; + + +#else /*!_ASSUAN_ONLY_GPG_ERRORS*/ + +typedef int assuan_error_t; + +#endif /*!_ASSUAN_ONLY_GPG_ERRORS*/ + + +/* Definitions of flags for assuan_set_flag(). */ +typedef enum + { + /* When using a pipe server, by default Assuan will wait for the + forked process to die in assuan_disconnect. In certain cases + this is not desirable. By setting this flag, the waitpid will + be skipped and the caller is responsible to cleanup a forked + process. */ + ASSUAN_NO_WAITPID = 1 + } +assuan_flag_t; + +#define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */ + +struct assuan_context_s; +typedef struct assuan_context_s *assuan_context_t; +#ifndef _ASSUAN_ONLY_GPG_ERRORS +typedef struct assuan_context_s *ASSUAN_CONTEXT _ASSUAN_DEPRECATED; +#endif /*_ASSUAN_ONLY_GPG_ERRORS*/ + +/*-- assuan-handler.c --*/ +int assuan_register_command (assuan_context_t ctx, + const char *cmd_string, + int (*handler)(assuan_context_t, char *)); +int assuan_register_post_cmd_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, int)); +int assuan_register_bye_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_reset_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_cancel_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_input_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)); +int assuan_register_output_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)); + +int assuan_register_option_handler (assuan_context_t ctx, + int (*fnc)(assuan_context_t, + const char*, const char*)); + +int assuan_process (assuan_context_t ctx); +int assuan_process_next (assuan_context_t ctx); +int assuan_get_active_fds (assuan_context_t ctx, int what, + int *fdarray, int fdarraysize); + + +FILE *assuan_get_data_fp (assuan_context_t ctx); +assuan_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line); +assuan_error_t assuan_write_status (assuan_context_t ctx, + const char *keyword, const char *text); + +/* Negotiate a file descriptor. If LINE contains "FD=N", returns N + assuming a local file descriptor. If LINE contains "FD" reads a + file descriptor via CTX and stores it in *RDF (the CTX must be + capable of passing file descriptors). */ +assuan_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line, + int *rfd); + +/*-- assuan-listen.c --*/ +assuan_error_t assuan_set_hello_line (assuan_context_t ctx, const char *line); +assuan_error_t assuan_accept (assuan_context_t ctx); +int assuan_get_input_fd (assuan_context_t ctx); +int assuan_get_output_fd (assuan_context_t ctx); +assuan_error_t assuan_close_input_fd (assuan_context_t ctx); +assuan_error_t assuan_close_output_fd (assuan_context_t ctx); + + +/*-- assuan-pipe-server.c --*/ +int assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]); +void assuan_deinit_server (assuan_context_t ctx); + +/*-- assuan-socket-server.c --*/ +int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd); +int assuan_init_connected_socket_server (assuan_context_t *r_ctx, + int fd) _ASSUAN_DEPRECATED; +int assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd, + unsigned int flags); + +/*-- assuan-pipe-connect.c --*/ +assuan_error_t assuan_pipe_connect (assuan_context_t *ctx, + const char *name, + const char *const argv[], + int *fd_child_list); +assuan_error_t assuan_pipe_connect2 (assuan_context_t *ctx, + const char *name, + const char *const argv[], + int *fd_child_list, + void (*atfork) (void*, int), + void *atforkvalue) _ASSUAN_DEPRECATED; +assuan_error_t assuan_pipe_connect_ext (assuan_context_t *ctx, + const char *name, + const char *const argv[], + int *fd_child_list, + void (*atfork) (void *, int), + void *atforkvalue, + unsigned int flags); + +/*-- assuan-socket-connect.c --*/ +assuan_error_t assuan_socket_connect (assuan_context_t *ctx, + const char *name, + pid_t server_pid); +assuan_error_t assuan_socket_connect_ext (assuan_context_t *ctx, + const char *name, + pid_t server_pid, + unsigned int flags); + +/*-- assuan-connect.c --*/ +void assuan_disconnect (assuan_context_t ctx); +pid_t assuan_get_pid (assuan_context_t ctx); +assuan_error_t assuan_get_peercred (assuan_context_t ctx, + pid_t *pid, uid_t *uid, gid_t *gid); + +/*-- assuan-client.c --*/ +assuan_error_t +assuan_transact (assuan_context_t ctx, + const char *command, + int (*data_cb)(void *, const void *, size_t), + void *data_cb_arg, + int (*inquire_cb)(void*, const char *), + void *inquire_cb_arg, + int (*status_cb)(void*, const char *), + void *status_cb_arg); + + +/*-- assuan-inquire.c --*/ +assuan_error_t assuan_inquire (assuan_context_t ctx, const char *keyword, + unsigned char **r_buffer, size_t *r_length, + size_t maxlen); + +/*-- assuan-buffer.c --*/ +assuan_error_t assuan_read_line (assuan_context_t ctx, + char **line, size_t *linelen); +int assuan_pending_line (assuan_context_t ctx); +assuan_error_t assuan_write_line (assuan_context_t ctx, const char *line ); +assuan_error_t assuan_send_data (assuan_context_t ctx, + const void *buffer, size_t length); + +/* The file descriptor must be pending before assuan_receivefd is + called. This means that assuan_sendfd should be called *before* the + trigger is sent (normally via assuan_write_line ("INPUT FD")). */ +assuan_error_t assuan_sendfd (assuan_context_t ctx, int fd); +assuan_error_t assuan_receivefd (assuan_context_t ctx, int *fd); + +/*-- assuan-util.c --*/ +void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), + void *(*new_realloc_func)(void *p, size_t n), + void (*new_free_func)(void*) ); +void assuan_set_log_stream (assuan_context_t ctx, FILE *fp); +int assuan_set_error (assuan_context_t ctx, int err, const char *text); +void assuan_set_pointer (assuan_context_t ctx, void *pointer); +void *assuan_get_pointer (assuan_context_t ctx); + +void assuan_begin_confidential (assuan_context_t ctx); +void assuan_end_confidential (assuan_context_t ctx); + +void assuan_set_io_monitor (assuan_context_t ctx, + unsigned int (*monitor)(assuan_context_t ctx, + int direction, + const char *line, + size_t linelen)); + +/* For context CTX, set the flag FLAG to VALUE. Values for flags + are usually 1 or 0 but certain flags might allow for other values; + see the description of the type assuan_flag_t for details. */ +void assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value); + +/* Return the VALUE of FLAG in context CTX. */ +int assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag); + + +/*-- assuan-errors.c --*/ + +#ifndef _ASSUAN_ONLY_GPG_ERRORS +/* Return a string describing the assuan error. The use of this + function is deprecated; it is better to call + assuan_set_assuan_err_source once and then make use libgpg-error. */ +const char *assuan_strerror (assuan_error_t err); +#endif /*_ASSUAN_ONLY_GPG_ERRORS*/ + +/* Enable gpg-error style error codes. ERRSOURCE is one of gpg-error + sources. Note, that this function is not thread-safe and should be + used right at startup. Switching back to the old style mode is not + supported. */ +void assuan_set_assuan_err_source (int errsource); + +/*-- assuan-logging.c --*/ + +/* Set the stream to which assuan should log message not associated + with a context. By default, this is stderr. The default value + will be changed when the first log stream is associated with a + context. Note, that this function is not thread-safe and should + in general be used right at startup. */ +extern void assuan_set_assuan_log_stream (FILE *fp); + +/* Return the stream which is currently being using for global logging. */ +extern FILE *assuan_get_assuan_log_stream (void); + +/* Set the prefix to be used at the start of a line emitted by assuan + on the log stream. The default is the empty string. Note, that + this function is not thread-safe and should in general be used + right at startup. */ +void assuan_set_assuan_log_prefix (const char *text); + +/* Return a prefix to be used at the start of a line emitted by assuan + on the log stream. The default implementation returns the empty + string, i.e. "" */ +const char *assuan_get_assuan_log_prefix (void); + +#ifdef __cplusplus +} +#endif +#endif /* ASSUAN_H */ diff --git a/libtdenetwork/libgpgme-copy/assuan/funopen.c b/libtdenetwork/libgpgme-copy/assuan/funopen.c new file mode 100644 index 00000000..ac31007a --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/funopen.c @@ -0,0 +1,64 @@ +/* funopen.c - Replacement for funopen. + * Copyright (C) 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> + + +/* Replacement for the *BSD function: + + FILE *funopen (void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), + int (*closefn)(void *)); + + The functions to provide my either be NULL if not required or + similar to the unistd function with the exception of using the + cookie instead of the fiel descripor. +*/ + + +#ifdef HAVE_FOPENCOOKIE +FILE * +_assuan_funopen(void *cookie, + cookie_read_function_t *readfn, + cookie_write_function_t *writefn, + cookie_seek_function_t *seekfn, + cookie_close_function_t *closefn) +{ + cookie_io_functions_t io = { NULL }; + + io.read = readfn; + io.write = writefn; + io.seek = seekfn; + io.close = closefn; + + return fopencookie (cookie, + readfn ? ( writefn ? "rw" : "r" ) + : ( writefn ? "w" : ""), io); +} +#else +#error No known way to implement funopen. +#endif diff --git a/libtdenetwork/libgpgme-copy/assuan/mkerrors b/libtdenetwork/libgpgme-copy/assuan/mkerrors new file mode 100755 index 00000000..57485411 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/assuan/mkerrors @@ -0,0 +1,228 @@ +#!/bin/sh +# mkerrors - Extract error strings from assuan.h +# and create C source for assuan_strerror +# Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. +# +# This file is part of Assuan. +# +# Assuan is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Assuan is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +cat <<EOF +/* Generated automatically by mkerrors */ +/* Do not edit! See mkerrors for copyright notice. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <assert.h> +#include <errno.h> + +#undef _ASSUAN_IN_LIBASSUAN /* undef to get all error codes. */ +#include "assuan.h" + +/* If true the modern gpg-error style error codes are used in the + API. */ +static unsigned int err_source; + +/* Enable gpg-error style error codes. ERRSOURCE is one of gpg-error + sources. Note, that this function is not thread-safe and should be + used right at startup. Switching back to the old style mode is not + supported. */ +void +assuan_set_assuan_err_source (int errsource) +{ + errsource &= 0xff; + err_source = errsource? errsource : 31 /*GPG_ERR_SOURCE_ANY*/; +} + + +/* Helper to map old style Assuan error codes to gpg-error codes. + This is used internally to keep an compatible ABI. */ +assuan_error_t +_assuan_error (int oldcode) +{ + unsigned int n; + + if (!err_source) + return (oldcode & 0x00ffffff); /* Make sure that the gpg-error + source part is cleared. */ + + switch (oldcode) + { + case ASSUAN_General_Error: n = 257; break; + case ASSUAN_Accept_Failed: n = 258; break; + case ASSUAN_Connect_Failed: n = 259; break; + case ASSUAN_Invalid_Response: n = 260; break; + case ASSUAN_Invalid_Value: n = 261; break; + case ASSUAN_Line_Not_Terminated: n = 262; break; + case ASSUAN_Line_Too_Long: n = 263; break; + case ASSUAN_Nested_Commands: n = 264; break; + case ASSUAN_No_Data_Callback: n = 265; break; + case ASSUAN_No_Inquire_Callback: n = 266; break; + case ASSUAN_Not_A_Server: n = 267; break; + case ASSUAN_Not_Implemented: n = 69; break; + case ASSUAN_Parameter_Conflict: n = 280; break; + case ASSUAN_Problem_Starting_Server: n = 269; break; + case ASSUAN_Server_Fault: n = 80; break; + case ASSUAN_Syntax_Error: n = 276; break; + case ASSUAN_Too_Much_Data: n = 273; break; + case ASSUAN_Unexpected_Command: n = 274; break; + case ASSUAN_Unknown_Command: n = 275; break; + case ASSUAN_Canceled: n = 277; break; + case ASSUAN_No_Secret_Key: n = 17; break; + case ASSUAN_Not_Confirmed: n = 114; break; + + case ASSUAN_Read_Error: + switch (errno) + { + case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break; + default: n = 270; /*GPG_ERR_ASS_READ_ERROR*/ break; + } + break; + + case ASSUAN_Write_Error: + switch (errno) + { + case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break; + default: n = 271; /*GPG_ERR_ASS_WRITE_ERROR*/ break; + } + break; + + case ASSUAN_Out_Of_Core: + switch (errno) + { + case 0: /* Should not happen but a user might have provided + an incomplete implemented malloc function. Give + him a chance to correct this fault but make sure + an error is indeed returned. */ + n = 16381; /*GPG_ERR_MISSING_ERRNO*/ + break; + case ENOMEM: n = (1 << 15) | 86; break; + default: + n = 16382; /*GPG_ERR_UNKNOWN_ERRNO*/ + break; + } + break; + + case -1: n = 16383 /*GPG_ERR_EOF*/; break; + + default: + n = 257; + break; + } + + return ((err_source << 24) | (n & 0x00ffffff)); + +} + + +/** + * assuan_strerror: + * @err: Error code + * + * This function returns a textual representaion of the given + * errorcode. If this is an unknown value, a string with the value + * is returned (Beware: it is hold in a static buffer). + * + * Return value: String with the error description. + **/ +const char * +assuan_strerror (assuan_error_t err) +{ + const char *s; + static char buf[50]; + + switch (err) + { +EOF + +awk ' +/ASSUAN_No_Error/ { okay=1 } +!okay {next} +/^#define[ ]+ASSUAN_[A-Za-z_]*/ { print_code($2) } +/ASSUAN_USER_ERROR_LAST/ { exit 0 } + + +function print_code( s ) +{ +printf " case %s: s=\"", s ; +gsub(/_/, " ", s ); +printf "%s\"; break;\n", tolower(substr(s,8)); +} +' + +cat <<EOF + case -1: s = "EOF (-1)"; break; + default: + { + unsigned int source, code, n; + + source = ((err >> 24) & 0xff); + code = (err & 0x00ffffff); + if (source) + { + /* Assume this is an libgpg-error and try to map the codes + back. */ + switch (code) + { + case 257: n = ASSUAN_General_Error ; break; + case 258: n = ASSUAN_Accept_Failed ; break; + case 259: n = ASSUAN_Connect_Failed ; break; + case 260: n = ASSUAN_Invalid_Response ; break; + case 261: n = ASSUAN_Invalid_Value ; break; + case 262: n = ASSUAN_Line_Not_Terminated ; break; + case 263: n = ASSUAN_Line_Too_Long ; break; + case 264: n = ASSUAN_Nested_Commands ; break; + case 265: n = ASSUAN_No_Data_Callback ; break; + case 266: n = ASSUAN_No_Inquire_Callback ; break; + case 267: n = ASSUAN_Not_A_Server ; break; + case 69: n = ASSUAN_Not_Implemented ; break; + case 280: n = ASSUAN_Parameter_Conflict ; break; + case 269: n = ASSUAN_Problem_Starting_Server; break; + case 270: n = ASSUAN_Read_Error ; break; + case 271: n = ASSUAN_Write_Error ; break; + case 80: n = ASSUAN_Server_Fault ; break; + case 276: n = ASSUAN_Syntax_Error ; break; + case 273: n = ASSUAN_Too_Much_Data ; break; + case 274: n = ASSUAN_Unexpected_Command ; break; + case 275: n = ASSUAN_Unknown_Command ; break; + case 277: n = ASSUAN_Canceled ; break; + case 114: n = ASSUAN_Not_Confirmed ; break; + case ((1<<15)|86): n = ASSUAN_Out_Of_Core ; break; + default: n = 0; break; + } + if (n) + s = assuan_strerror (n); + else + { + sprintf (buf, "ec=%u.%u", source, code ); + s=buf; + } + } + else + { + sprintf (buf, "ec=%d", err ); + s=buf; + } + } + break; + } + + return s; +} + +EOF diff --git a/libtdenetwork/libgpgme-copy/configure.in.in b/libtdenetwork/libgpgme-copy/configure.in.in new file mode 100644 index 00000000..afcc995c --- /dev/null +++ b/libtdenetwork/libgpgme-copy/configure.in.in @@ -0,0 +1,364 @@ +# configure.in for GPGME +# Copyright (C) 2000 Werner Koch (dd9jn) +# Copyright (C) 2001, 2002, 2003 g10 Code GmbH +# +# This file is part of GPGME. +# +# GPGME is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GPGME is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +# (Process this file with autoconf to produce a configure script.) + +#AC_PREREQ(2.57) +#min_automake_version="1.7.6" + +# Version number: Remember to change it immediately *after* a release. +#AC_INIT(gpgme, 0.4.4, [bug-gpgme@gnupg.org]) +# LT Version numbers, remember to change them just *before* a release. +# (Code changed: REVISION++) +# (Interfaces added/removed/changed: CURRENT++, REVISION=0) +# (Interfaces added: AGE++) +# (Interfaces removed: AGE=0) +# +#LIBGPGME_LT_CURRENT=12 +#LIBGPGME_LT_AGE=1 +#LIBGPGME_LT_REVISION=1 +NEED_GPG_VERSION=1.2.2 +NEED_GPGSM_VERSION=1.9.3 +############################################## +#AC_PREREQ(2.52) +#AC_REVISION($Revision$) + +#PACKAGE=$PACKAGE_NAME +#VERSION=$PACKAGE_VERSION + +#AC_CONFIG_SRCDIR(gpgme/gpgme.h) +#AM_CONFIG_HEADER(config.h) +#AM_INIT_AUTOMAKE($PACKAGE, $VERSION) +#AM_MAINTAINER_MODE +#AC_CANONICAL_HOST + +AH_VERBATIM([_GNU_SOURCE], +[/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif]) + +dnl AH_VERBATIM([_REENTRANT], +dnl [/* To allow the use of GPGME in multithreaded programs we have to use +dnl special features from the library. +dnl IMPORTANT: gpgme is not yet fully reentrant and you should use it +dnl only from one thread. */ +dnl #ifndef _REENTRANT +dnl # define _REENTRANT 1 +dnl #endif]) + + +dnl AC_PROG_CC + + +dnl AC_SUBST(LIBGPGME_LT_CURRENT) +dnl AC_SUBST(LIBGPGME_LT_AGE) +dnl AC_SUBST(LIBGPGME_LT_REVISION) +AC_DEFINE_UNQUOTED(NEED_GPG_VERSION, "$NEED_GPG_VERSION", + [Min. needed GnuPG version.]) +AC_DEFINE_UNQUOTED(NEED_GPGSM_VERSION, "$NEED_GPGSM_VERSION", + [Min. needed GPGSM version.]) + +dnl AC_SUBST(PACKAGE) +dnl AC_SUBST(VERSION) +dnl AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package]) +dnl AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) + +# Don't default to build static libs. +dnl AC_DISABLE_STATIC +dnl AC_PROG_LIBTOOL + +dnl # For now we hardcode the use of version scripts. It would be better +dnl # to write a test for this or even implement this within libtool. +dnl have_ld_version_script=no +dnl case "${host}" in +dnl *-*-linux*) +dnl have_ld_version_script=yes +dnl ;; +dnl *-*-gnu*) +dnl have_ld_version_script=yes +dnl ;; +dnl esac +dnl AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") + +GPG_DEFAULT=no +GPGSM_DEFAULT=no +component_system=None +case "${host}" in + *-*-mingw32* | i?86-emx-os2 | i?86-*-os2*emx | i?86-*-msdosdjgpp* ) + # special stuff for Windoze NT + # OS/2 with the EMX environment + # DOS with the DJGPP environment + AC_DEFINE(HAVE_DRIVE_LETTERS, , + [Defined if we run on some of the PCDOS like systems (DOS, + Windoze, OS/2) with special properties like no file modes.]) + AC_DEFINE(HAVE_DOSISH_SYSTEM, , + [Defined if the filesystem uses driver letters.]) + have_dosish_system=yes + GPG_DEFAULT='c:\\gnupg\\gpg.exe' + # XXX Assuan is not supported in this configuration. + #GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe' + #component_system='COM+' + ;; + *) +dnl AC_CHECK_PTH(1.2.0,,,no,have_pth=yes) +dnl if test "$have_pth" = yes; then +dnl AC_DEFINE(HAVE_PTH, ,[Define if we have Pth.]) +dnl CFLAGS="$CFLAGS $PTH_CFLAGS" +dnl fi +dnl AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes) +dnl if test "$have_pthread" = yes; then +dnl AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.]) +dnl fi + + # XXX: Probably use exec-prefix here? +# GPG_DEFAULT='/usr/bin/gpg' +# GPGSM_DEFAULT='/usr/bin/gpgsm' + ;; +esac + +if test "$have_dosish_system" = yes; then + AC_DEFINE(HAVE_DOSISH_SYSTEM,1, + [Defined if we run on some of the PCDOS like systems· + (DOS, Windoze. OS/2) with special properties like + no file modes]) +fi +AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = "yes") +dnl AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes") +dnl AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes") +dnl dnl + +# Checks for header files. +AC_CHECK_HEADERS(sys/select.h) + + +# Type checks. +AC_CHECK_SIZEOF(unsigned int) + + +# Checks for compiler features. +dnl if test "$GCC" = yes; then +dnl GPGME_OWN_CFLAGS="-Wall -Wcast-align -Wshadow -Wstrict-prototypes" +dnl else +dnl GPGME_OWN_CFLAGS="" +dnl fi +dnl AC_SUBST(GPGME_OWN_CFLAGS) + + +# Checks for library functions. +AC_CHECK_FUNCS(stpcpy) + +AC_CHECK_FUNCS(vasprintf) +if test "$ac_cv_func_vasprintf" != yes; then + GNUPG_CHECK_VA_COPY +fi + +# Try to find a thread-safe version of getenv(). +have_thread_safe_getenv=no + +dnl Definition of jm_GLIBC21 inlined: + AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, + ac_cv_gnu_library_2_1, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include <features.h> +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2_1=yes, + ac_cv_gnu_library_2_1=no) + ] + ) + AC_SUBST(GLIBC21) + GLIBC21="$ac_cv_gnu_library_2_1" + +dnl + +if test $GLIBC21 = yes; then + have_thread_safe_getenv=yes +fi +if test $have_thread_safe_getenv = yes; then + AC_DEFINE(HAVE_THREAD_SAFE_GETENV, [1], [Define if getenv() is thread-safe]) +fi +have_getenv_r=no +AC_CHECK_FUNCS(getenv_r, have_getenv_r=yes) +if test $have_getenv_r = no && test $have_thread_safe_getenv = no; then + AC_MSG_WARN([ +*** +*** getenv() is not thread-safe and getenv_r() does not exist +***]) +fi + +# For converting time strings to seconds since Epoch, we need the timegm +# function. +AC_CHECK_FUNCS(timegm) +if test "$ac_cv_func_timegm" != yes; then + AC_MSG_WARN([ +*** +*** timegm() not available - a non-thread-safe kludge will be used +*** and the TZ variable might be changed at runtime. +***]) +fi + +# Add a few constants to help porting to W32 +AH_VERBATIM([SEPCONSTANTS], +[ +/* Separators as used in file names and $PATH. Please note that the + string version must not contain more than one character because + the using code assumes strlen()==1 */ +#ifdef HAVE_DOSISH_SYSTEM +#define DIRSEP_C '\\\\' +#define EXTSEP_C '.' +#define DIRSEP_S "\\\\" +#define EXTSEP_S "." +#define PATHSEP_C ';' +#define PATHSEP_S ";" +#else +#define DIRSEP_C '/' +#define EXTSEP_C '.' +#define DIRSEP_S "/" +#define EXTSEP_S "." +#define PATHSEP_C ':' +#define PATHSEP_S ":" +#endif +]) + +AH_BOTTOM([ +/* Definition of GCC specific attributes. */ +#if __GNUC__ > 2 +# define GPGME_GCC_A_PURE __attribute__ ((__pure__)) +#else +# define GPGME_GCC_A_PURE +#endif +]) + +dnl # Checking for libgpg-error. +dnl AM_PATH_GPG_ERROR(0.5,, AC_MSG_ERROR([libgpg-error was not found])) +dnl AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME, +dnl [The default error source for GPGME.]) + + + +# Checks for system services +NO_OVERRIDE=no +AC_ARG_WITH(gpg, + AC_HELP_STRING([--with-gpg=PATH], [use GnuPG binary at PATH]), + GPG=$withval, NO_OVERRIDE=yes) +if test "$NO_OVERRIDE" = "yes" || test "$GPG" = "yes"; then + GPG= + NO_OVERRIDE=yes + if test "$cross_compiling" != "yes"; then + AC_PATH_PROG(GPG, gpg) + fi + if test -z "$GPG"; then + GPG="$GPG_DEFAULT" + fi +fi +if test "$GPG" = no; then + if test "$NO_OVERRIDE" = "yes"; then + if test "$cross_compiling" != "yes"; then + AC_MSG_WARN([ +*** +*** Could not find GnuPG, install GnuPG or use --with-gpg=PATH to enable it +***]) + else + AC_MSG_ERROR([ +*** +*** Can not determine path to GnuPG when cross-compiling, use --with-gpg=PATH +***]) + fi + fi +else + AC_DEFINE_UNQUOTED(GPG_PATH, "$GPG", [Path to the GnuPG binary.]) + AC_SUBST(GPG) +fi +AM_CONDITIONAL(RUN_GPG_TESTS, + [test "$cross_compiling" != "yes" && test -n "$GPG" && test -r "$GPG"]) +AC_SUBST(GPG_PATH) + +NO_OVERRIDE=no +AC_ARG_WITH(gpgsm, + AC_HELP_STRING([--with-gpgsm=PATH], [use GpgSM binary at PATH]), + GPGSM=$withval, NO_OVERRIDE=yes) +if test "$NO_OVERRIDE" = "yes" || test "$GPGSM" = "yes"; then + GPGSM= + NO_OVERRIDE=yes + if test "$cross_compiling" != "yes"; then + AC_PATH_PROG(GPGSM, gpgsm) + fi + if test -z "$GPGSM"; then + GPGSM="$GPGSM_DEFAULT" + fi +fi +if test "$GPGSM" = no; then + if test "$NO_OVERRIDE" = "yes"; then + if test "$cross_compiling" != "yes"; then + AC_MSG_WARN([ +*** +*** Could not find GpgSM, install GpgSM or use --with-gpgsm=PATH to enable it +***]) + else + AC_MSG_ERROR([ +*** +*** Can not determine path to GpgSM when cross-compiling, use --with-gpgsm=PATH +***]) + fi + fi +else + AC_DEFINE_UNQUOTED(GPGSM_PATH, "$GPGSM", [Path to the GPGSM binary.]) + AC_SUBST(GPGSM) +fi +AM_CONDITIONAL(HAVE_GPGSM, [test -n "$GPGSM" && test -r "$GPGSM"]) +dnl AM_CONDITIONAL(RUN_GPGSM_TESTS, +dnl [test "$cross_compiling" != "yes" && test -n "$GPGSM" && test -r "$GPGSM"]) + +dnl # FIXME: Only build if supported. +dnl AM_CONDITIONAL(BUILD_ASSUAN, test "$GPGSM" != "no") + +AC_CHECK_FUNCS(funopen) + +if test "$GPGSM" != "no"; then + if test $ac_cv_func_funopen != yes; then + # No funopen but we can implement that in terms of fopencookie. + AC_CHECK_FUNCS(fopencookie, funopen, AC_MSG_ERROR([[No implementation of fopencookie or funopen available.]])) + fi + + dnl it's a #define !!! + dnl AC_CHECK_FUNCS(isascii) + + AC_CHECK_FUNCS(putc_unlocked) + AC_CHECK_FUNCS(memrchr) +fi + +# More assuan checks. +AC_CHECK_HEADERS([sys/uio.h]) + +echo " + GPGME v${VERSION} has been configured as follows: + + GnuPG version: min. $NEED_GPG_VERSION + GnuPG path: $GPG + + GpgSM version: min. $NEED_GPGSM_VERSION + GpgSM path: $GPGSM +" diff --git a/libtdenetwork/libgpgme-copy/gpgme/ChangeLog b/libtdenetwork/libgpgme-copy/gpgme/ChangeLog new file mode 100644 index 00000000..85fd28d3 --- /dev/null +++ b/libtdenetwork/libgpgme-copy/gpgme/ChangeLog @@ -0,0 +1,5312 @@ +2007-02-26 Werner Koch <wk@g10code.com> + + * verify.c (op_data_t): New element PLAINTEXT_SEEN. + (_gpgme_verify_status_handler): Return an error if more than one + plaintext has been seen. + (parse_error): New arg SET_STATUS. Also detect it based on an + ERROR status (gpg > 1.4.6). + +2007-01-26 Werner Koch <wk@g10code.com> + + * w32-io.c (build_commandline): Fixed stupid quoting bug. + * w32-glib-io.c (build_commandline): Ditto. + + * rungpg.c (gpg_set_locale): Avoid dangling pointer after free. + + * gpgme-config.in: New options --get-gpg and --get-gpgsm. + +2007-01-18 Marcus Brinkmann <marcus@g10code.de> + + * data.h (_gpgme_data_get_fd): Add prototype. + (gpgme_data_get_fd_cb): New type. + (struct _gpgme_data_cbs): New member get_fd. + * data.c (_gpgme_data_get_fd): New function. + * data-fd.c (fd_get_fd): New function. + (fd_cbs): Add fd_get_fd. + * data-stream.c (stream_get_fd): New function. + (stream_cbs): Add stream_get_fd. + * data-mem.c (mem_cbs): Add NULL for get_fd callback. + * data-user.c (user_cbs): Likewise. + * engine-gpgsm.c (gpgsm_set_fd) [USE_DESCRIPTOR_PASSING]: Try to + short-cut by passing the data descriptor directly. + +2007-01-17 Marcus Brinkmann <marcus@g10code.de> + + * w32-io.c (build_commandline): Quote all command line arguments. + * w32-glib-io.c (build_commandline): Likewise. + +2007-01-10 Werner Koch <wk@g10code.com> + + * ttyname_r.c (ttyname_r) [W32]: Return a dummy name. + +2007-01-08 Werner Koch <wk@g10code.com> + + * version.c (do_subsystem_inits): Do assuan init only if building + with Assuan. + * setenv.c: Include assuan-def.h only if building with Assuan + support. + + * op-support.c (_gpgme_op_reset): Set LC_MESSAGES only if + if defined. + * engine-gpgsm.c (gpgsm_set_locale): Ditto. + * rungpg.c (gpg_set_locale): Ditto. + +2006-12-17 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.c (gpgme_set_protocol): Shut down the engine when + switching protocols. + (gpgme_ctx_set_engine_info): Likewise for engine info. + * engine.h (_gpgme_engine_reset): New function prototype. + * engine.c (_gpgme_engine_reset): New function. + * engine-backend.h (struct engine_ops): New member RESET. + * rungpg.c (_gpgme_engine_ops_gpg): Add NULL for reset function. + * engine-gpgsm.c (_gpgme_engine_ops_gpgsm) + [USE_DESCRIPTOR_PASSING]: Add gpgsm_reset for reset. + (_gpgme_engine_ops_gpgsm) [!USE_DESCRIPTOR_PASSING]: Add NULL for + reset function. + (gpgsm_reset) [USE_DESCRIPTOR_PASSING]: New function. + * op-support.c (_gpgme_op_reset): Try to use the engine's reset + function if available. + * engine-gpgsm.c (gpgsm_new): Move code to dup status_fd to ... + (start): ... here. + * posix-io.c (_gpgme_io_recvmsg, _gpgme_io_sendmsg): New functions. + + * engine.h (_gpgme_engine_new): Remove arguments lc_ctype and + lc_messages from prototype. + (_gpgme_engine_set_locale): New prototype. + * engine.c (_gpgme_engine_set_locale): New function. + * op-support.c (_gpgme_op_reset): Call _gpgme_engine_set_locale. + * engine-backend.h (struct engine_ops): Add new member SET_LOCALE. + Remove arguments lc_messages and lc_ctype from member NEW. + * engine-gpgsm.c (struct engine_gpgsm): New members lc_ctype_set + and lc_messages_set. + (gpgsm_new): Remove lc_messages and lc_ctype + arguments. + (gpgsm_set_locale): New function. + (_gpgme_engine_ops_gpgsm): Add gpgsm_set_locale. + * rungpg.c (struct engine_gpg): Add new members lc_messages and + lc_ctype. + (gpg_release): Release lc_messages and lc_ctype if set. + (gpg_new): Remove lc_messages and lc_ctype arguments. + (gpg_set_locale): New function. + (_gpgme_engine_ops_gpg): Add gpg_set_locale. + (add_arg): Implement in terms of: + (add_arg_ext): New function. + (start): Set lc-messages and lc-ctype arguments here. + +2006-12-03 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c (struct engine_gpgsm): Move members + input_fd_server, output_fd_server, message_fd_server to ... + (iocb_data): ... here (as server_fd). + (close_notify_handler): Reset tags as well. + (gpgsm_new): Implement support for descriptor + passing. + (fd_type_t): New type. + (gpgsm_clear_fd): New function. Use it instead of _gpgsm_io_close + for unused communication channels. + (gpgsm_set_fd): Rewritten to support descriptor passing. All + relevant callers adjusted as well (previously of _gpgme_io_close). + +2006-12-02 Marcus Brinkmann <marcus@g10code.de> + + * version.c: Include "assuan.h". + (do_subsystem_inits): Call assuan_set_assuan_err_source. + +2006-12-01 Marcus Brinkmann <marcus@g10code.de> + + * Makefile.am (libgpgme_real_la_SOURCES): Rename to main_sources. + (libgpgme_la_SOURCES, libgpgme_pthread_la_SOURCES, + libgpgme_glib_la_SOURCES, libgpgme_pth_la_SOURCES): Add + $(main_sources). + (libgpgme_la_DEPENDENCIES, libgpgme_la_LIBADD, + libgpgme_pthread_la_DEPENDENCIES, libgpgme_pthread_la_LIBADD, + libgpgme_pth_la_DEPENDENCIES, libgpgme_pth_la_LIBADD, + libgpgme_glib_la_DEPENDENCIES, libgpgme_glib_la_LIBADD): Remove + libgpgme-real.la. + (noinst_LTLIBRARIES): Removed. + (libgpgme_glib_la_CFLAGS, libgpgme_pth_la_CFLAGS): Removed. + (AM_CFLAGS): New variable. + +2006-11-30 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c: Replace AssuanError with gpg_error_t and + ASSUAN_CONTEXT with assuan_context_t. + +2006-11-29 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c (gpgsm_new): Check return value of + assuan_pipe_connect. + + * rungpg.c: Include <unistd.h>. + (gpg_new): Support --display, --ttyname, --ttytype, --lc-ctype and + --lc-messages. Fixes issue 734. + +2006-10-24 Marcus Brinkmann <marcus@g10code.de> + + * trustlist.c (gpgme_op_trustlist_next): Return error if OPD is + NULL. + +2006-10-23 Marcus Brinkmann <marcus@g10code.de> + + * wait-global.c (gpgme_wait): Unlock CTX_LIST_LOCK while calling + _gpgme_engine_io_event(). + + * keylist.c (gpgme_op_keylist_next): Return error if OPD is NULL. + +2006-09-25 Marcus Brinkmann <marcus@g10code.de> + + * data-mem.c (gpgme_data_release_and_get_mem): Release the data + object properly. + +2006-09-22 Marcus Brinkmann <marcus@g10code.de> + + * keylist.c (keylist_colon_handler): Move debug output after + initialising KEY. + +2006-07-29 Marcus Brinkmann <marcus@g10code.de> + + * gpgme-config.in (Options): Add NETLIBS. + * Makefile.am (libgpgme_la_LIBADD, libgpgme_pthread_la_LIBADD, + libgpgme_pth_la_LIBADD, libgpgme_glib_la_LIBADD): Add NETLIBS. + + * rungpg.c (read_status): Fix comparison disguising as an + assignment. + +2005-03-24 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.c (gpgme_set_locale): Remove conditional on + HAVE_W32_SYSTEM, and just check for LC_MESSAGES. + +2006-07-16 Marcus Brinkmann <marcus@g10code.de> + + * rungpg.c (read_status): Strip potential carriage return. + * genkey.c (get_key_parameter): Skip potential carriage return. + * version.c (_gpgme_get_program_version): Strip potential carriage + return. + + * data.c (gpgme_data_set_file_name): Allow to clear the file name + by passing NULL. + +2006-06-22 Marcus Brinkmann <marcus@g10code.de> + + * keylist.c (gpgme_get_key): Also clone the engine info. + +2006-03-06 Marcus Brinkmann <marcus@g10code.de> + + * gpgme-config.in (cflags_pth): Revert accidential removal of + pthread support with last change. + +2006-02-28 Marcus Brinkmann <marcus@g10code.de> + + * w32-glib-io.c (O_BINARY) [!O_BINARY]: New macro. + (_gpgme_io_pipe): Open pipes in binary mode. + +2006-02-22 Marcus Brinkmann <marcus@g10code.de> + + * engine.c (gpgme_engine_check_version): Reimplemented to allow + checking the version correctly even after changing the engine + information. Bug reported by Stéphane Corthésy. + + * rungpg.c (read_colon_line): Invoke colon preprocess handler if + it is set. + (colon_preprocessor_t): New type. + (struct engine_gpg): New member colon.preprocess_fnc. + (gpg_keylist_preprocess): New function. + * keylist.c (keylist_colon_handler): Allow short key IDs. + +2006-02-15 Marcus Brinkmann <marcus@g10code.de> + + * w32-io.c (create_writer): Make C->have_data a manually resetted + event. + (writer): Move code from end of if block to beginning, so it + is also run the first time. + (_gpgme_io_write): Move assert check after error check. Reset + the is_empty event, and also do it eagerly. + (_gpgme_io_select): Unconditionally wait for the is_empty event. + +2006-01-26 Werner Koch <wk@g10code.com> + + * w32-util.c (_gpgme_get_conf_int): New. + * posix-util.c (_gpgme_get_conf_int): New. + * w32-io.c (get_desired_thread_priority): New. + (create_reader, create_writer): Use it here. + +2006-01-04 Werner Koch <wk@g10code.com> + + * debug.h (_gpgme_debug_srcname): New. Use it with the debug macros. + + * w32-glib-io.c (_gpgme_io_set_nonblocking): Add debug + statements. Disable error return for failed nonblocking call. + +2006-01-03 Marcus Brinkmann <marcus@g10code.de> + + * w32-glib-io.c (_gpgme_io_close): Only close fd if there is no + channel for it. + +2005-12-31 Marcus Brinkmann <marcus@g10code.de> + + * w32-glib-io.c (find_channel): Set channel to unbuffered. + (_gpgme_io_select): Fix debug output. + +2005-12-23 Werner Koch <wk@g10code.com> + + * gpgme.h (struct _gpgme_signature): Append field PKA_ADDRESS. + * verify.c (release_op_data, _gpgme_verify_status_handler): Set + this field. + +2005-12-20 Werner Koch <wk@g10code.com> + + * gpgme.h (gpgme_status_code_t): Added GPGME_STATUS_PKA_TRUST_BAD + and GPGME_STATUS_PKA_TRUST_GOOD. + (struct _gpgme_signature): New field pka_trust. + * verify.c (_gpgme_verify_status_handler): Set pka_trust. + +2005-12-06 Werner Koch <wk@g10code.com> + + * keylist.c (keylist_colon_handler): Store fingerprints of the + subkeys. Reset the secret flag of subkeys for stub secret keys. + (NR_FIELDS): Bumped up to 16 + +2005-11-27 Marcus Brinkmann <marcus@g10code.de> + + * engine.c (_gpgme_set_engine_info): Use new_file_name in + engine_get_version invocation. Reported by Stéphane Corthésy. + +2005-11-24 Marcus Brinkmann <marcus@g10code.de> + + * w32-glib-io.c (_gpgme_io_fd2str): Remove debug printf. + +2005-11-18 Werner Koch <wk@g10code.com> + + * w32-glib-io.c: Include glib.h before windows to avoid a symbol + shadowing warning. + (find_channel): Better use g_io_channel_win32_new_fd instead of + the autodetection function g_io_channel_unix_new. + (_gpgme_io_select): Rewritten. It is now a fully working select + implementation. + +2005-11-18 Marcus Brinkmann <marcus@g10code.de> + + * priv-io.h (_gpgme_io_fd2str): New prototype. + * posix-io.c (_gpgme_io_fd2str): New function. + * w32-io.c (_gpgme_io_fd2str): New function. + * rungpg.c: Use this new function. + * w32-glib-io.c (_gpgme_io_fd2str): Rewrote the file handle code + again. Two's company, three's the musketeers. + + * w32-glib-io.c: Rewrote the file handle code. We don't create + system fds for every handle (doesn't work for inherited handles), + but we create pseudo fds in a private namespace that designate a + handle and potentially a giochannel. + +2005-11-18 Werner Koch <wk@g10code.com> + + * versioninfo.rc.in: Set file version to LT-version + Svn-revision. + +2005-11-17 Marcus Brinkmann <marcus@g10code.de> + + * w32-glib-io.c: New file. + * gpgme.def (gpgme_get_giochannel): Add symbol. + * Makefile.am (system_components) [HAVE_DOSISH_SYSTEM]: Remove + w32-io.c. + (ltlib_gpgme_extra): New variable. + (lib_LTLIBRARIES): Add $(ltlib_gpgme_extra). + (system_components_not_extra): New variable. + (libgpgme_la_SOURCES, libgpgme_pthread_la_SOURCES, + (libgpgme_pth_la_SOURCES): Add $(system_components_not_extra). + (libgpgme_glib_la_LDFLAGS, libgpgme_glib_la_DEPENDENCIES, + (libgpgme_glib_la_LIBADD, libgpgme_glib_la_CFLAGS) + [BUILD_W32_GLIB]: New variables. + * gpgme-config.in (glib): New option. + * gpgme.m4 (AM_PATH_GPGME_GLIB): New macro. + +2005-11-17 Marcus Brinkmann <marcus@g10code.de> + + * priv-io.h (_gpgme_io_waitpid, _gpgme_io_kill): Removed. + * w32-io.c (_gpgme_io_waitpid, _gpgme_io_kill): Removed. + * posix-io.c (_gpgme_io_kill): Removed. + (_gpgme_io_waitpid): Declare static. + +2005-10-24 Marcus Brinkmann <marcus@g10code.de> + + * w32-io.c (_gpgme_io_spawn): Don't minimize window, hide it. + +2005-10-21 Werner Koch <wk@g10code.com> + + * Makefile.am: Fixed cut+paste problem + +2005-10-20 Marcus Brinkmann <marcus@g10code.de> + + * Makefile.am: Build versioninfo.lo, not versioninfo.o. Also, fix + the whole mess. + +2005-10-16 Marcus Brinkmann <marcus@g10code.de> + + * rungpg.c (gpg_edit): Don't add a key argument if in card edit + mode. + +2005-10-06 Marcus Brinkmann <marcus@g10code.de> + + * Makefile.am (gpgme.dll gpgme.dll.a): Use $(srcdir) for + gpgme.def. + + * gpgme.h (gpgme_free): New prototype. + * data-mem.c (gpgme_free): New function. + * libgpgme.vers (GPGME_1.1): Add gpgme_free. + * gpgme.def: Add gpgme_free. + +2005-10-02 Marcus Brinkmann <marcus@g10code.de> + + * util.h (_gpgme_decode_percent_string): Add new argument BINARY + to prototype. + * verify.c (parse_notation): Likewise for invocation. + * conversion.c (_gpgme_decode_percent_string): Likewise to + declaration. If set, do not replace '\0' characters with a + printable string. + * gpgme.h (struct _gpgme_key_sig): New field notations. + * ops.h (_gpgme_parse_notation): New prototype. + * sig-notation.c (_gpgme_parse_notation): New function. + * key.c (gpgme_key_unref): Free all signature notations. + * keylist.c (op_data_t): New member tmp_keysig. + (finish_key): Clear OPD->tmp_keysig. + * gpgme.c (gpgme_set_keylist_mode): Remove check. + * rungpg.c (gpg_keylist): Support listing signature notations. + (gpg_keylist_ext): Likewise. + +2005-10-01 Marcus Brinkmann <marcus@g10code.de> + + * engine.h (_gpgme_set_engine_info): Add prototype. + * engine-backend.h (struct engine_ops): Change return type of + get_file_name() to const char * to silence gcc warning. + * engine.c (engine_get_file_name): Change return type to const + char * to silence gcc warning. + (gpgme_get_engine_info): Use transitional variable to go from + const char * to char * to silence gcc warning. + (_gpgme_set_engine_info): Likewise. + * engine-gpgsm.c (struct engine_gpgsm): Change type of LINE to + char * to silence gcc warning. + (gpgsm_new): Make ARGV a pointer to const char. + (status_handler): Change type of SRC, END, DST, ALINE and NEWLINE + to char * to silence gcc warning. + + * gpgme.def: Add gpgme_data_set_file_name, + gpgme_data_get_file_name, gpgme_sig_notation_clear, + gpgme_sig_notation_add and gpgme_sig_notation_get. + * libgpgme.vers: Add gpgme_sig_notation_clear, + gpgme_sig_notation_add and gpgme_sig_notation_get. + * Makefile.am (libgpgme_real_la_SOURCES): Add sig-notation.c. + * context.h (struct gpgme_context): New field sig_notations. + * gpgme.h (struct _gpgme_sig_notation): New member value_len and + critical. + (GPGME_SIG_NOTATION_CRITICAL): New symbol. + (gpgme_sig_notation_flags_t): New type. + (gpgme_sig_notation_add, gpgme_sig_notation_clear, + gpgme_sig_notation_get): New prototypes. + * ops.h (_gpgme_sig_notation_create, _gpgme_sig_notation_free): + New prototypes. + * sig-notation.c (_gpgme_sig_notation_free): New file. + * verify.c (parse_notation): Use support functions. + (release_op_data): Likewise. + * rungpg.c (append_args_from_sig_notations): New function. + (gpg_encrypt_sign, gpg_sign): Call it. + +2005-09-30 Marcus Brinkmann <marcus@g10code.de> + + * data.h (struct gpgme_data): New member file_name. + * data.c (gpgme_data_set_filename): New function. + (_gpgme_data_release): Free DH->filename if necessary. + (gpgme_data_get_filename): New function. + * rungpg.c (gpg_encrypt): Set filename option. + (gpg_encrypt_sign): Likewise. + (gpg_sign): Likewise. + * libgpgme.vers (GPGME_1.1): Add gpgme_data_set_file_name and + gpgme_data_get_file_name. + + * decrpyt.c, verify.c, gpgme.h: Replace plaintext_filename with + file_name. + +2005-09-29 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_key): Add field is_qualified. + (struct _gpgme_subkey): Likewise. + * keylist.c (set_subkey_capability, set_mainkey_capability): Set + field is_qualified. + +2005-09-23 Werner Koch <wk@g10code.com> + + * w32-io.c (_gpgme_io_pipe): Removed use of environment variable + again. + (create_reader, create_writer): Set thread priority higher. + +2005-09-19 Werner Koch <wk@g10code.com> + + * w32-io.c (_gpgme_io_pipe): New environment variable to change + the size of the pipe buffer. + +2005-09-13 Werner Koch <wk@g10code.com> + + * ath.c: Changes to make it work under W32. + +2005-09-12 Marcus Brinkmann <marcus@g10code.de> + + * Makefile.am (libgpgme_la_SOURCES): Set to ath.h and ath.c. + (ath_pth_src, ath_pthread_src): Removed. + (w32_o_files): Replace ath-compat.o with ath.o. + (libgpgme_pth_la_CFLAGS): New variable. + * ath-compat.c, ath-pthread-compat.c, ath-pth-compat.c: Removed. + * ath.h (ath_pthread_available, ath_pth_available): Removed. + (ath_init) [!_ATH_EXT_SYM_PREFIX]: Do not define macro. + (struct ath_ops, ath_init) [_ATH_COMPAT]: Removed. + (_ATH_COMPAT): Macro removed. + * posix-sema.c (_gpgme_sema_subsystem_init): Do not call + _gpgme_ath_init. + +2005-09-12 Marcus Brinkmann <marcus@g10code.de> + + * keylist.c (release_op_data): Do not free opd->tmp_uid. + +2005-09-07 Werner Koch <wk@g10code.com> + + * w32-io.c (build_commandline): Quote argv[0]. + +2005-08-26 Marcus Brinkmann <marcus@g10code.de> + + * rungpg.c (command_handler): Use _gpgme_io_write instead of write. + + * edit.c (command_handler): Do not depend on PROCESSED being + available. + + * engine.h (engine_command_handler_t): Add new argument processed. + * ops.h (_gpgme_passphrase_command_handler_internal): Rename + prototype to ... + (_gpgme_passphrase_command_handler): ... this one. + * passphrase.c (_gpgme_passphrase_command_handler_internal): + Rename to ... + (_gpgme_passphrase_command_handler): ... this one. + * edit.c (command_handler): Add new argument processed. Remove + local variable with the same name. Always return processed as + true. + * rungpg.c (command_handler): Send a newline character if the + handler did not. + +2005-08-26 Werner Koch <wk@g10code.com> + + * w32-util.c (read_w32_registry_string): Updated from code used by + GnuPG. This allows for expanding strings and features the + implicit fallback key. + (w32_shgetfolderpath, find_program_at_standard_place): New. + (_gpgme_get_gpg_path, _gpgme_get_gpgsm_path): With no registry + entry, locate the programs at the standard place. + (dlopen, dlsym, dlclose): New, so that we can keep on using what + we are accustomed to. + + * debug.c (debug_init): Use PATHSEP_C so that under W32 a + semicolon is used which allows us to create files with drive + letters. + + * w32-io.c (_gpgme_io_read, _gpgme_io_write): Print content in + debug mode too. + +2005-08-19 Werner Koch <wk@g10code.com> + + * gpgme.def: New. + * versioninfo.rc.in: New. + * Makefile.am: Addes support for building a W32 DLL. + + * ttyname_r.c (ttyname_r) [W32]: Return error. + * ath-compat.c [W32]: select and co are not yet supported; return + error. + * data-stream.c (stream_seek): Use ftell if ftello is not available. + +2005-08-08 Werner Koch <wk@g10code.com> + + * util.h (stpcpy): Renamed to .. + (_gpgme_stpcpy): .. this and made inline. This avoids duplicate + definitions when linking statically. + * stpcpy.c: Removed. + +2005-07-27 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (gpgme_status_code_t): Add GPGME_STATUS_PLAINTEXT. + (struct _gpgme_op_decrypt_result): New member plaintext_filename. + (struct _gpgme_op_verify_result): Likewise. + * ops.h (_gpgme_parse_plaintext): Add prototype. + * op-support.c (_gpgme_parse_plaintext): New function. + * decrypt.c (release_op_data): Release + OPD->result.plaintext_filename. + (_gpgme_decrypt_status_handler): Handle GPGME_STATUS_PLAINTEXT. + * verify.c (release_op_data): Release + OPD->result.plaintext_filename. + (_gpgme_verify_status_handler): Handle GPGME_STATUS_PLAINTEXT. + +2005-07-26 Marcus Brinkmann <marcus@g10code.de> + + * keylist.c (gpgme_get_key): Allow key IDs. + +2005-06-20 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.m4: Only call GPGME_CONFIG if found. + +2005-06-03 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_signature): New members pubkey_algo and + hash_algo. + * verify.c (parse_valid_sig): Parse pubkey and hash algo numbers. + (parse_new_sig): Parse pubkey, hash algo and timestamp for ERRSIG. + + (_gpgme_decrypt_status_handler): Fix last change. + + * gpgme.h (struct _gpgme_recipient): New structure. + (gpgme_recipient_t): New type. + (struct _gpgme_op_decrypt_result): Add member recipients. + * decrypt.c (op_data_t): New member last_recipient_p. + (_gpgme_op_decrypt_init_result): Initialize last_recipient_p. + (parse_enc_to): New function. + (_gpgme_decrypt_status_handler): Handle status ENC_TO and + NO_SECKEY. + + * wait-global.c (gpgme_wait): Break out of the fd processing loop + after an error. + Reported by Igor Belyi <gpgme@katehok.ac93.org>. + +2005-06-02 Marcus Brinkmann <marcus@g10code.de> + + * wait.h (_gpgme_run_io_cb): New prototype. + * wait.c (_gpgme_run_io_cb): New function. + * wait-global.c (gpgme_wait): Call it. + * wait-user.c (_gpgme_user_io_cb_handler): Likewise. + * wait-private.c (_gpgme_wait_on_condition): Likewise. + +2005-06-02 Werner Koch <wk@g10code.com> + + * passphrase.c (_gpgme_passphrase_status_handler): Take care of + GPGME_STATUS_NEED_PASSPHRASE_PIN. + (_gpgme_passphrase_command_handler_internal): Also act on the key + "passphrase.pin.ask". + + * gpgme.h: Added status codes GPGME_STATUS_SIG_SUBPACKET, + GPGME_STATUS_NEED_PASSPHRASE_PIN, GPGME_STATUS_SC_OP_FAILURE, + GPGME_STATUS_SC_OP_SUCCESS, GPGME_STATUS_CARDCTRL, + GPGME_STATUS_BACKUP_KEY_CREATED. + +2005-05-28 Marcus Brinkmann <marcus@g10code.de> + + * data-user.c: Include <errno.h>. + +2005-05-17 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.c (gpgme_new): Set the CTX->include_certs default to the + default. + +2005-05-11 Marcus Brinkmann <marcus@g10code.de> + + * w32-io.c (_gpgme_io_select): Fix loop increment. + +2005-05-05 Marcus Brinkmann <marcus@g10code.de> + + * data-user.c (user_release): Only call user hook if provided. + (user_seek): Return EBADF if no user hook is provided. + (user_read): Likewise. + (user_write): Likewise. + +2005-04-28 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (GPGME_INCLUDE_CERTS_DEFAULT): New macro. + * engine-gpgsm.c (gpgsm_sign): Send the include-certs option after + the reset, just for cleanliness, and do not sent it at all if the + default is requested. + * gpgme.c (gpgme_set_include_certs): Allow to use + GPGME_INCLUDE_CERTS_DEFAULT. + +2005-04-21 Werner Koch <wk@g10code.com> + + * verify.c (calc_sig_summary): Set the key revoked bit. + +2005-04-14 Marcus Brinkmann <marcus@g10code.de> + + * wait-global.c (gpgme_wait): Use LI->ctx when checking a context + in the list, not the user-provided CTX. + Reported by Igor Belyi <gpgme@katehok.ac93.org>. + + * wait-global.c (gpgme_wait): If no context is found, and we + should not hang, set *status to 0 and return NULL. + Reported by Igor Belyi <gpgme@katehok.ac93.org>. + +2005-03-24 Marcus Brinkmann <marcus@g10code.de> + + * data.h (EOPNOTSUPP) [_WIN32]: Remove definition. + * data.c (EOPNOTSUPP) [HAVE_W32_SYSTEM]: Remove definition. + (gpgme_data_read, gpgme_data_write, gpgme_data_seek): Return + ENOSYS instead EOPNOTSUPP. + * data-compat.c (EOPNOTSUPP) [HAVE_W32_SYSTEM]: Remove definition. + (gpgme_error_to_errno): Map GPG_ERR_NOT_SUPPORTED + to ENOSYS. + +2005-03-24 Marcus Brinkmann <marcus@g10code.de> + + * io.h: Rename to ... + * priv-io.h: ... this. + * Makefile.am (libgpgme_real_la_SOURCES): Change io.h to priv-io.h. + * data.c, engine-gpgsm.c, posix-io.c, rungpg.c, version.c, + w32-io.c, wait-private.c, wait-global.c, wait-user.c, wait.c: + Change all includes of "io.h" to "priv-io.h" + +2005-03-09 Werner Koch <wk@g10code.com> + + * w32-util.c (_gpgme_get_gpg_path, _gpgme_get_gpgsm_path): Do not + cast away type checks. + + * io.h [W32]: Do not include stdio.h. If it is needed do it at + the right place. + + * data.h [W32]: Removed kludge for EOPNOTSUP. + * data.c, data-compat.c [W32]: Explicitly test for it here. + + Replaced use of _WIN32 by HAVE_W32_SYSTEM except for public header + files. + +2005-03-07 Timo Schulz <twoaday@g10code.de> + + * gpgme.h: [_WIN32] Removed ssize_t typedef. + * ath.h: [_WIN32] Added some (dummy) types. + * io.h: [_WIN32] include stdio.h. + * data.h: [_WIN32] Define EOPNOTSUPP. + * w32-io.c [_WIN32] (_gpgme_io_subsystem_init): New. + * gpgme.c [_WIN32] (gpgme_set_locale): Disabled. + +2004-12-12 Marcus Brinkmann <marcus@g10code.de> + + * engine.c (_gpgme_set_engine_info): Fix assertion. + +2004-12-11 Marcus Brinkmann <marcus@g10code.de> + + * util.h [HAVE_CONFIG_H && HAVE_TTYNAME_R] (ttyname_r): Define + prototype. + * ttyname_r.c: New file. + +2004-12-07 Marcus Brinkmann <marcus@g10code.de> + + * putc_unlocked.c, funopen.c: I just claim copyright on these + files and change their license to LGPL, because they are totally + trivial wrapper functions. + * isascii.c: Change copyright notice to the one from ctype/ctype.h + in the GNU C Library (CVS Head 2004-10-10), where isascii is + defined as a macro doing exactly the same as the function in this + file. + * memrchr.c: Update from the GNU C Library (CVS Head 2001-07-06). + * stpcpy.c: Update from the GNU C Library (CVS Head 2004-10-10). + * ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c, + ath-pthread.c, ath-pthread-compat.c, context.h, conversion.c, + data.c, data-compat.c, data-fd.c, data.h, data-mem.c, + data-stream.c, data-user.c, debug.c, debug.h, decrypt.c, + decrypt-verify.c, delete.c, edit.c, encrypt.c, encrypt-sign.c, + engine-backend.h, engine.c, engine-gpgsm.c, engine.h, error.c, + export.c, genkey.c, get-env.c, gpgme.c, gpgme.h, import.c, io.h, + key.c, keylist.c, mkstatus, Makefile.am, ops.h, op-support.c, + passphrase.c, posix-io.c, posix-sema.c, posix-util.c, progress.c, + rungpg.c, sema.h, sign.c, signers.c, trust-item.c, trustlist.c, + util.h, verify.c, version.c, w32-io.c, w32-sema.c, w32-util.c, + wait.c, wait-global.c, wait.h, wait-private.c, wait-user.c: Change + license to LGPL. + +2004-12-07 Marcus Brinkmann <marcus@g10code.de> + + * libgpgme.vers (GPGME_1.1): New version. + * engine-backend.h (struct engine_ops): Add argument FILE_NAME to + member get_version(). Add arguments FILE_NAME and HOME_DIR to + member new(). Change return type of get_file_name and get_version + to char *. + * engine-gpgsm.c (gpgsm_get_version): Change return type to char + pointer. Do not cache result. + (gpgsm_new): Add file_name and home_dir argument, and use them + instead of the defaults, if set. + * rungpg.c (struct engine_gpg): New member file_name. + (gpg_get_version): Change return type to char pointer, and do not + cache result. + (gpg_release): Free gpg->file_name. + (gpg_new): Take new arguments file_name and home_dir. Set the + --homedir argument if HOME_DIR is not NULL. Set gpg->file_name. + (start): Use gpg->file_name instead _gpgme_get_gpg_path, if set. + * engine.h (_gpgme_engine_info_copy, _gpgme_engine_info_release): + New prototypes. + (_gpgme_engine_new): Change first argument to gpgme_engine_info_t + info. + * engine.c: Include <assert.h>. + (gpgme_get_engine_info): Set *INFO within the lock. Move + ENGINE_INFO and ENGINE_INFO_LOCK to .... + (engine_info, engine_info_lock): ... here. New static variables. + (engine_get_version): Add file_name argument to + get_version invocation. Change return type to char pointer. + (gpgme_engine_check_version): Rewritten to free() the return value + of engine_get_version after using it. + (_gpgme_engine_info_release): New function. + (gpgme_get_engine_info): Rewritten. + (_gpgme_engine_info_copy): New function. + (_gpgme_set_engine_info): New function. + (gpgme_set_engine_info): New function. + (_gpgme_engine_new): Change first argument to gpgme_engine_info_t + info, and use that. + * gpgme.h (struct _gpgme_engine_info): Change type of file_name + and version to char * (remove the const). New member home_dir. + (gpgme_set_engine_info, gpgme_ctx_get_engine_info, + gpgme_ctx_set_engine_info): New prototypes. + * context.h (struct gpgme_context): New member engine_info. + * gpgme.c (gpgme_new): Allocate CTX->engine_info. + (gpgme_release): Deallocate CTX->engine_info. + (gpgme_ctx_get_engine_info, gpgme_ctx_set_engine_info): New + functions. + * op-support.c (_gpgme_op_reset): Look for correct engine info and + pass it to _gpgme_engine_new. + * version.c (gpgme_check_version): Adjust to + _gpgme_compare_versions returning an int. + (_gpgme_compare_versions): Return an int value, not a const char + pointer. + * ops.h (_gpgme_compare_versions): Same for prototype. + +2004-10-03 Marcus Brinkmann <marcus@g10code.de> + + * verify.c (parse_trust): If no reason is provided, set + SIG->validity_reason to 0. + (calc_sig_summary): Set GPGME_SIGSUM_CRL_TOO_OLD if appropriate. + +2004-10-22 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c (map_assuan_error): Return 0 if ERR is 0. + (start): Call map_assuan_error on return value of + assuan_write_line. + +2004-10-05 Marcus Brinkmann <marcus@g10code.de> + + * op-support.c (_gpgme_op_data_lookup): Use char pointer for + pointer arithmetic. + +2004-09-30 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.m4: Implement the --api-version check. + + * rungpg.c (read_status): Move the polling of the output data pipe + to just before removing the command fd, from just before adding + it. This avoids buffering problems. + + * data.c (_gpgme_data_inbound_handler): Use _gpgme_io_read, not + read, to improve debug output. + +2004-09-29 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (GPGME_IMPORT_NEW, GPGME_IMPORT_UID, GPGME_IMPORT_SIG, + GPGME_IMPORT_SUBKEY, GPGME_IMPORT_SECRET, + (GPGME_KEYLIST_MODE_LOCAL, GPGME_KEYLIST_MODERN_EXTERN, + GPGME_KEYLIST_MODE_SIGS, GPGME_KEYLIST_MODE_VALIDATE): Change from + enum to macros. + (gpgme_keylist_mode_t): Define as unsigned int. + (gpgme_key_t): Change type of keylist_mode to + gpgme_keylist_mode_t. + +2004-09-23 Marcus Brinkmann <marcus@g10code.de> + + * data.c (_gpgme_data_outbound_handler): Close the file descriptor + if we get an EPIPE. + + * data-stream.c (stream_seek): Call ftello and return the current + offset. + * data.h (struct gpgme_data): Change type of data.mem.offset to + off_t. + * data.c (gpgme_data_seek): Check dh->cbs->seek callback, not read + callback. If SEEK_CUR, adjust the offset by the pending buffer + size. Clear pending buffer on success. + + +2004-09-14 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.m4: Add copyright notice. + +2004-08-18 Marcus Brinkmann <marcus@g10code.de> + + * passphrase.c (_gpgme_passphrase_status_handler): Always run the + status handler. + +2004-08-17 Marcus Brinkmann <marcus@g10code.de> + + * rungpg.c (build_argv): Use --no-sk-comment, not --no-comment. + +2004-06-23 Marcus Brinkmann <marcus@g10code.de> + + * key.c (_gpgme_key_append_name): Make sure tail points to the + byte following the uid. + (_gpgme_key_add_sig): Likewise. Don't use calloc, but malloc and + memset. + +2004-06-02 Marcus Brinkmann <marcus@g10code.de> + + * libgpgme.vers: Remove C-style comment, which is not supported by + older binutils. + +2004-05-21 Marcus Brinkmann <marcus@g10code.de> + + * gpgme-config.in (Options): Support --api-version. + + * libgpgme.vers: List all gpgme symbols under version GPGME_1.0. + + * decrypt.c (_gpgme_decrypt_status_handler): Fix last change. + * verify.c (parse_error): Likewise. + + * verify.c (parse_error): Do not skip location of where token. + + * gpgme.h (gpgme_status_code_t): Add GPGME_STATUS_REVKEYSIG. + * verify.c (_gpgme_verify_status_handler): Add handling of + GPGME_STATUS_REVKEYSIG. + (parse_trust): Likewise. + +2004-05-21 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_decrypt_result): New fields + wrong_key_usage and _unused. + * decrypt.c (_gpgme_decrypt_status_handler): Don't skip over + character after a matched string, as in a protocol error this + could skip over the trailing binary zero. + Handle decrypt.keyusage error notifications. + + * gpgme.h (struct _gpgme_key): New member keylist_mode. + * keylist.c (keylist_colon_handler): Set the keylist_mode of KEY. + +2004-04-29 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_signature): Change member WRONG_KEY_USAGE + to unsigned int. Same for member _unused. + + * keylist.c (set_mainkey_trust_info): Rewritten. + (set_subkey_capability): Handle 'd' (disabled). + (set_mainkey_capability): Rewritten. + +2004-04-22 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.m4: Quote first argument to AC_DEFUN. + +2004-04-21 Werner Koch <wk@gnupg.org> + + * key.c (gpgme_key_unref): Allow passing NULL like free does. + The rule of least surprise. + +2004-04-15 Werner Koch <wk@gnupg.org> + + * verify.c (prepare_new_sig, _gpgme_verify_status_handler): Remove + unused result.signatures items. + + * keylist.c (gpgme_get_key): Return an error if FPR is NULL. + +2004-04-08 Werner Koch <wk@gnupg.org> + + * verify.c (_gpgme_verify_status_handler): Ignore the error status + if we can't process it. + * decrypt-verify.c (decrypt_verify_status_handler): Backed out + yesterday's hack. It is not any longer required. + +2004-04-07 Werner Koch <wk@gnupg.org> + + * decrypt-verify.c (decrypt_verify_status_handler): Hack to cope + with meaningless error codes from the verify status function. + +2004-04-05 Werner Koch <wk@gnupg.org> + + * gpgme.h: Add GPGME_STATUS_NEWSIG. + + * verify.c (parse_error): Compare only the last part of the where + token. + (prepare_new_sig): New. + (parse_new_sig): Use prepare_new_sig when required. + (_gpgme_verify_status_handler): Handle STATUS_NEWSIG. + + * engine-gpgsm.c (gpgsm_keylist_ext): Send with-validation + option. Fixed pattern construction. + (status_handler): Add debugging output. + +2004-03-23 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c (gpgsm_new): Protect _only_ tty related code with + isatty(). Submitted by Bernhard Herzog. + +2004-03-11 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c (gpgsm_new): Protect all tty related code with + isatty(). + + * rungpg.c (gpg_cancel): Set GPG->fd_data_map to NULL after + releasing it. + * engine-gpgsm.c (gpgsm_cancel): Only call assuan_disconnect if + GPGSM->assuan_ctx is not NULL. Set it to NULL afterwards. + +2004-03-07 Marcus Brinkmann <marcus@g10code.de> + + * gpgme-config.in: Do not emit include and lib directory for + prefix "/usr" or "". + +2004-03-03 Werner Koch <wk@gnupg.org> + + * engine-gpgsm.c (gpgsm_export_ext): Properly insert a space + beween patterns. + +2004-02-18 Werner Koch <wk@gnupg.org> + + * gpgme-config.in: Ignore setting of --prefix. + +2004-02-25 Marcus Brinkmann <marcus@g10code.de> + + * rungpg.c (gpg_cancel): New function. + (gpg_release): Call it here. + (_gpgme_engine_ops_gpg): Add it here. + * engine-gpgsm.c (gpgsm_cancel): Fix last change. + +2004-02-24 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.c (gpgme_cancel): New function. + * engine-backend.h (struct engine_ops): New member cancel. + * engine.h (_gpgme_engine_cancel): New prototype. + * engine.c (_gpgme_engine_cancel): New function. + * engine-gpgsm.c (_gpgme_engine_ops_gpgsm): Add new member cancel. + (gpgsm_cancel): New function. + (gpgsm_release): Use it. + * rungpg.c (_gpgme_engine_ops_gpg): Add new member cancel. + +2004-02-17 Werner Koch <wk@gnupg.org> + + * gpgme.h: Add GPGME_KEYLIST_MODE_VALIDATE. + * engine-gpgsm.c (gpgsm_keylist): Send this to gpgsm. + +2004-02-15 Werner Koch <wk@gnupg.org> + + * memrchr.c (memrchr): Fixed implementation. Problem pointed out + by Adriaan de Groot. + +2004-02-01 Marcus Brinkmann <marcus@g10code.de> + + * rungpg.c (build_argv): Use --no-comment, not --comment "". + + * data-compat.c (gpgme_data_new_from_filepart): Call fseeko if + available. + * data-stream.c (stream_seek): Likewise. + +2004-01-16 Werner Koch <wk@gnupg.org> + + * conversion.c (_gpgme_map_gnupg_error): Handle numerical codes as + used by GnuPG 1.9.x + +2004-01-13 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_key_sig): Fix comment on REVOKED. + +2004-01-12 Werner Koch <wk@gnupg.org> + + * sign.c: Include util.h for prototype of _gpgme_parse_timestamp. + +2003-12-25 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (_GPGME_D_CLASS): Revert this change. + (struct _gpgme_key_sig): For C++ compilers, rename class + member to _obsolete_class. Add new member sig_class. + (struct _gpgme_new_signature): Same here. + * key.c (gpgme_key_sig_get_ulong_attr): Use CERTSIG->sig_class, + not CERTSIG->class. + * keylist.c (keylist_colon_handler): Likewise for KEYSIG, but keep + setting KEYSIG->class, too. Rename variable CLASS to SIG_CLASS. + * sign.c (parse_sig_created): Set SIG->sig_class. + +2003-12-22 Werner Koch <wk@gnupg.org> + + * gpgme.h (_GPGME_D_CLASS): Kludge for C++ compatibility without + changing the C API. + +2003-11-19 Werner Koch <wk@gnupg.org> + + * conversion.c (_gpgme_parse_timestamp): New. + (atoi_1, atoi_2, atoi_4): New. + * keylist.c (parse_timestamp): Removed. Changed all callers to use + the new function. + * verify.c (parse_valid_sig): Ditto. Repalced the errno check. + * sign.c (parse_sig_created): Ditto. + +2003-10-31 Werner Koch <wk@gnupg.org> + + * keylist.c (parse_timestamp): Detect ISO 8601 timestamps and try + to convert them. + +2003-10-10 Marcus Brinkmann <marcus@g10code.de> + + * genkey.c (get_key_parameter): Make a copy of the key parameters. + Submitted by Miguel Coca <e970095@zipi.fi.upm.es>. + +2003-10-06 Marcus Brinkmann <marcus@g10code.de> + + * data-compat.c: Include <sys/time.h> before <sys/stat.h> for + broken systems. + + * engine-gpgsm.c (map_assuan_error): If ERR is -1, return sensible + error. + + * io.h (_gpgme_io_subsystem_init): New prototype. + * posix-io.c (_gpgme_io_subsystem_init): Add function. + (_gpgme_io_spawn): Do not fixup signal handler here. + * version.c (do_subsystem_inits): Call _gpgme_io_subsystem_init. + + * debug.c (debug_init): Drop const qualifier from E. + + * ath.h (struct ath_ops): Make ADDR argument of CONNECT prototype + const. + (ath_connect): Make ADDR argument const. + * ath-pthread.c (ath_connect): Likewise. + * ath-pth.c (ath_connect): Likewise. + * ath-compat.c (ath_connect): Likewise. + * ath.c (ath_connect): Likewise. + + * ath.h [HAVE_SYS_SELECT_H]: Include <sys/select.h> for fd_set. + [!HAVE_SYS_SELECT_H]: Include <sys/time.h>. + + * conversion.c (_gpgme_hextobyte): Drop "unsigned" from type of + SRC argument. + * util.h (_gpgme_hextobyte): Likewise for prototype. + + * gpgme.h: Remove trailing comma in enum. + + * rungpg.c: Do not include <time.h>, <sys/time.h>, <sys/types.h>, + <signal.h>, <fcntl.h>, or "unistd.h". + +2003-10-02 Marcus Brinkmann <marcus@g10code.de> + + * engine-backend.h (struct engine_ops): Add argument TYPE. + * engine.c (_gpgme_engine_op_edit): Likewise. + * engine.h: Likewise. + * rungpg.c (gpg_edit): Likewise. Use it. + * edit.c (edit_start): Likewise. Pass it on. + (gpgme_op_edit_start, gpgme_op_edit): Likewise. + (gpgme_op_card_edit_start, gpgme_op_card_edit): New functions. + +2003-09-30 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (gpg_strerror_r): Change prototype to match + gpg_strerror_r change. + * error.c (gpg_strerror_r): Likewise, also update implementation. + + * gpgme.c (gpgme_hash_algo_name): Change name of RMD160 to + RIPEMD160, name of TIGER to TIGER192, name of CRC32-RFC1510 to + CRC32RFC1510, and name of CRC24-RFC2440 to CRC24RFC2440. + +2003-09-14 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h: Add prototype for gpgme_set_locale. + + * gpgme.h: Define macro _GPGME_INLINE depending on the compiler + characteristics and use that instead __inline__. + + * context.h (struct gpgme_context): New members lc_ctype and + lc_messages. + * gpgme.c: Include <locale.h>. + (def_lc_lock, def_lc_ctype, def_lc_messages): New static + variables. + (gpgme_set_locale): New function. + * engine.c (_gpgme_engine_new): Add arguments lc_ctype and + lc_messages. + * engine.h (_gpgme_engine_new): Likewise. + * engine-gpgsm.c (gpgsm_new): Likewise. + * rungpg.c (gpg_new): Likewise. + * engine-backend.h (struct engine_ops): Likewise to NEW. + * op-support.c (_gpgme_op_reset): Likewise to invocation of + _gpgme_engine_new. + +2003-09-13 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (gpgme_strerror_r): New prototype. + * error.c (gpgme_strerror_r): New function. + + * get-env.c: New file. + * util.h (_gpgme_getenv): Add prototype. + * Makefile.am (libgpgme_real_la_SOURCES): Add get-env.c. + * rungpg.c (build_argv): Use _gpgme_getenv. + * debug.c (debug_init): Likewise. + * engine-gpgsm.c (gpgsm_new): Likewise. + (gpgsm_new): Use ttyname_r. + * w32-io.c (_gpgme_io_spawn): Disable debugging for now. + +2003-09-03 Marcus Brinkmann <marcus@g10code.de> + + * gpgme-config.in: Use $libdir, not @libdir@, for the echo + command. + + * gpgme-config.in: Rewritten. + * gpgme.m4: Rewritten. + +2003-08-19 Marcus Brinkmann <marcus@g10code.de> + + The ath files (ath.h, ath.c, ath-pth.c, ath-pthread.c, + ath-compat.c, ath-pth-compat.c and ath-pthread-compat.c) have been + updated to have better thread support, and the Makefile.am was + changed to reflect that. + + * util.h [!HAVE_FOPENCOOKIE]: Remove fopencookie declaration. + * engine-gpgsm.c (gpgsm_assuan_simple_command): Set ERR to return + value of status_fnc. + * rungpg.c (start): Return SAVED_ERRNO, not errno. + +2003-08-18 Marcus Brinkmann <marcus@g10code.de> + + * rungpg.c (start): Use saved_errno instead errno. + +2003-08-18 Marcus Brinkmann <marcus@g10code.de> + + * funopen.c, putc_unlocked.c, isascii.c, memrchr.c: New files. + * fopencookie.c: File removed. + +2003-08-15 Marcus Brinkmann <marcus@g10code.de> + + * gpgme-config.in: Put gpg-error related flags after gpgme's. + +2003-08-14 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_new_signature): Rename member CLASS to + _OBSOLETE_CLASS, add member CLASS with type unsigned int. + * sign.c (parse_sig_created): Also set SIG->_unused_class for + backward compatibility. + +2003-08-04 Marcus Brinkmann <marcus@g10code.de> + + * verify.c (parse_new_sig): Fix status parsing case. + +2003-07-31 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_subkey): Add flag CAN_AUTHENTICATE. + Lower _UNUSED to 23 bits. + (struct _gpgme_key): Likewise. + * keylist.c (set_mainkey_capability): Support 'a' and 'A'. + (set_subkey_capability): Support 'a'. + + * keylist.c (gpgme_get_key): Check if there is more than one key + listed, and return GPG_ERR_AMBIGUOUS_NAME in that case. + + * util.h (_gpgme_decode_c_string): Change type of LEN argument to + size_t. + (_gpgme_decode_percent_string): Likewise. + * conversion.c (_gpgme_decode_c_string): Likewise. + (_gpgme_decode_percent_string): Likewise. + (_gpgme_map_gnupg_error): Change type of I to unsigned int. + * signers.c (gpgme_signers_clear): Likewise. + (gpgme_signers_enum): New unsigned variable SEQNO, set to SEQ. + Use SEQNO instead SEQ. + * wait.c (fd_table_put): Change type of I and J to unsigned int. + * wait-global.c (_gpgme_wait_global_event_cb): Change type of IDX + to unsigned int. + (gpgme_wait): Change type of I and IDX to unsigned int. + * wait-private.c (_gpgme_wait_on_condition): Change type of IDX + and I to unsigned int. + * posix-io.c (_gpgme_io_close): Cast return value of macro DIM to + int to suppress gcc warning. + (_gpgme_io_set_close_notify): Likewise. + (_gpgme_io_select): Change type of I to unsigned int. + * engine.c (gpgme_get_engine_info): Change type of PROTO to + unsigned int. + * wait-user.c (_gpgme_user_io_cb_handler): Change type of IDX and + I to unsigned int. + +2003-07-29 Marcus Brinkmann <marcus@g10code.de> + + * decrypt-verify.c (decrypt_verify_status_handler): Expand silly + and wrong expression. + * encrypt-sign.c (encrypt_sign_status_handler): Likewise. + * encrypt.c (encrypt_sym_status_handler): Likewise. + * sign.c (sign_status_handler): Likewise. + * verify.c (verify_status_handler): Likewise. + * decrypt.c (decrypt_status_handler): Likewise. + + * engine.c (gpgme_get_engine_info): Initialize NULL. + +2003-07-23 Marcus Brinkmann <marcus@g10code.de> + + * gpgme-config.in (gpg_error_libs): Quote GPG_ERROR_CFLAGS and + GPG_ERROR_LIBS when setting the corresponding variables. + Reported by Stéphane Corthésy. + +2003-07-22 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c (set_recipients): Move declaration of NEWLEN to + the beginning of the block. + +2003-06-22 Marcus Brinkmann <marcus@g10code.de> + + * data-mem.c (mem_write): Copy original buffer content. + +2003-06-22 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (gpgme_user_ids_release, gpgme_user_ids_append): Remove + prototypes. + +2003-06-06 Marcus Brinkmann <marcus@g10code.de> + + * Makefile.am (AM_CPPFLAGS): Add @GPG_ERROR_CFLAGS@. + * gpgme-config.in (gpg_error_libs, gpg_error_cflags): New variables. + Print them. + + * op-support.c (_gpgme_parse_inv_userid): Rename to + _gpgme_parse_inv_recp and change to new datatype. + * ops.h (_gpgme_parse_inv_key): Fix prototype. + * gpgme.h (struct _gpgme_invalid_user_id): Rename to + __gpgme_invalid_key. Rename field ID to KEY. + (gpgme_invalid_user_id_t): Rename to gpgme_invalid_key_t. + (struct _gpgme_op_encrypt_result): Here, too. + (struct _gpgme_op_sign_result): Likewise. + * encrypt.c (struct op_data): Likewise. + (release_op_data): Likewise. + * sign.c (struct op_data): Likewise. + (release_op_data): Likewise. + + * posix-io.c (_gpgme_io_read): Save errno across debug calls. + (_gpgme_io_write): Likewise. + (_gpgme_io_pipe): Likewise. + (_gpgme_io_select): Likewise. + + * rungpg.c (struct engine_gpg): Remove arg_error. + (add_arg): Don't set arg_error. + (add_data): Likewise. + (start): Don't check arg_error. + (gpg_new): Check return value of add_arg. + * verify.c (parse_notation): Free allocated memory at error. + +2003-06-05 Marcus Brinkmann <marcus@g10code.de> + + Everywhere: Use libgpg-error error codes. + + * Makefile.am (EXTRA_DIST): Remove mkerrors. + (BUILT_SOURCES): Remove errors.c. + (MOSTLYCLEANFILES): Likewise. + (libgpgme_la_SOURCES): Likewise. Add error.c. + (errors.c): Remove target. + * mkerrors: File removed. + * error.c: New file. + + * gpgme.h (gpgme_error_t): Change to type gpg_error_t. + (gpgme_err_code_t, gpgme_err_source_t): New types. + (gpgme_err_code, gpgme_err_source, gpgme_error, gpgme_err_make): + New static inline functions. + (gpgme_strsource, gpgme_err_code_from_errno, + gpgme_err_code_to_errno, gpgme_err_make_from_errno, + gpgme_error_from_errno): New prototypes. + +2003-05-29 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (gpgme_op_export_start): Change second arg to const char *. + (gpgme_op_export): Likewise. + (gpgme_op_export_ext_start): New prototype. + (gpgme_op_export_ext): Likewise. + * engine.h: Likewise for _gpgme_engine_op_export and + _gpgme_engine_op_export_ext. + * engine-backend.h (struct engine_ops): Change second argument of + prototype of export to const char *, and add reserverd int as + third argument. Add prototype for export_ext. + * engine.c (_gpgme_engine_op_export_ext): New function. + (_gpgme_engine_op_export): Change second argument of prototype of + export to const char *, and add reserverd int as third argument. + * rungpg.c (gpg_export): Change second argument of prototype of + export to const char *, and add reserverd int as third argument. + (gpg_export_ext): New function. + (gpg_keylist_ext): Break loop at error. + (_gpgme_engine_ops_gpg): Add gpg_export_ext. + * engine-gpgsm.c (gpgsm_export): Change second argument of + prototype of export to const char *, and add reserverd int as + third argument. + (gpgsm_export_ext): New function. + (_gpgme_engine_ops_gpgsm): Add gpgsm_export_ext. + * export.c (export_start): Change second argument of prototype of + export to const char *, and add reserverd int as third argument. + (gpgme_op_export_start): Likewise. + (export_ext_start): New function. + (gpgme_op_export_ext_start): Likewise. + (gpgme_op_export_ext): Likewise. + + * gpgme.h (gpgme_keylist_mode_t): New type for anonymous enum. + (gpgme_sigsum_t): New type for anonymous enum. + + * encrypt-sign.c (encrypt_sign_start): Check for errors earlier, + and return an error if RECP is not set. + + * Makefile.am (libgpgme_la_SOURCES): Remove user-id.c. + * user-id.c: Remove file. + * ops.h: Remove prototype for _gpgme_user_ids_all_valid. + * gpgme.h (gpgme_encrypt_flags_t): New type. + (gpgme_op_encrypt_start): Change second parameter to type + gpgme_key_t[], and add third parameter. + (gpgme_op_encrypt): Likewise. + (gpgme_op_encrypt_sign_start): Likewise. + (gpgme_op_encrypt_sign): Likewise. + * encrypt.c (encrypt_start): Likewise. + (gpgme_op_encrypt_start): Likewise. + (gpgme_op_encrypt): Likewise. Pass flags to engine. + * encrypt-sign.c (encrypt_sign_start): Likewise. + (gpgme_op_encrypt_sign_start): Likewise. + (gpgme_op_encrypt_sign): Likewise. + * engine-backend.h (struct engine_ops): Likewise for prototypes of + encrypt and encrypt_sign. + * engine.h: Likewise for prototypes of _gpgme_engine_op_encrypt + and _gpgme_engine_op_encrypt_sign. + * engine.c (_gpgme_engine_op_encrypt): Likewise. + (_gpgme_engine_op_encrypt_sign): Likewise. + * rungpg.c (gpg_encrypt): Likewise. + (gpg_encrypt_sign): Likewise. + * rungpg.c (gpg_encrypt): Check flags for always trust option. + * engine-gpgsm.c (gpgsm_encrypt): Likewise. + (set_recipients): Rewritten to use keys instead user IDs. + * rungpg.c (append_args_from_recipients): Rewritten to use keys + instead user IDs. + * encrypt.c (_gpgme_encrypt_status_handler): Change errors + returned to GPGME_Invalid_Key and GPGME_General_Error. + +2003-05-28 Marcus Brinkmann <marcus@g10code.de> + + * engine-gpgsm.c: Rename GpgsmObject to engine_gpgsm_t. + (struct gpgsm_object_s): Rename to struct engine_gpgsm. + * rungpg.c: Rename GpgObject to engine_gpg_t. + (struct gpg_object_s): Rename to struct engine_gpg. + + * context.h (struct gpgme_context): Change EngineObject to + engine_object_t. + (enum ctx_op_data_type): Rename to ctx_op_data_id_t. + (ctx_op_data_t): New type. + (struct gpgme_context): Use it. + * ops.h (_gpgme_op_data_lookup): Use new type name. + * op-support.c (_gpgme_op_data_lookup): Likewise. + * engine.c: Rename EngineObject to engine_t in the file. Also + EngineStatusHandler to engine_status_handler_t, + EngineCommandHandler to engine_command_handler_t and + EngineColonLineHandler to engine_colon_line_handler. + * rungpg.c (start): Likewise. + * engine-gpgsm.c: Likewise. + * engine-backend.h (struct engine_ops): Likewise + * engine.h (struct engine_object_s): Rename to struct engine. + (EngineObject): Rename to engine_t. Also everywhere else in the + file. + (EngineStatusHandler): Rename to engine_status_handler_t. + (EngineColonLineHandler): Rename to engine_colon_line_handler_t. + (EngineCommandHandler): Rename to engine_command_handler_t. + + * engine-gpgsm.c (gpgsm_export): Fix bug in last change. + + * Makefile.am (libgpgme_la_SOURCES): Remove recipient.c, add + user-id.c. + * gpgme.h (gpgme_recipients_t): Removed. + (gpgme_recipients_new, gpgme_recipients_release, + gpgme_recipients_add_name, + gpgme_recipients_add_name_with_validity, gpgme_recipients_count, + gpgme_recipients_enum_open, gpgme_recipients_enum_read, + gpgme_recipients_enum_close): Removed. + (gpgme_op_encrypt, gpgme_op_encrypt_start, gpgme_op_encrypt_sign, + gpgme_op_encrypt_sign_start, gpgme_op_export_start, + gpgme_op_export): Change second argument to gpgme_user_id_t. + (gpgme_user_ids_release): New prototype. + (gpgme_user_ids_append): Likewise. + * ops.h (_gpgme_recipients_all_valid): Remove. + (_gpgme_user_ids_all_valid): Add. + * context.h (struct gpgme_recipients): Removed. + * user-id.c: New file. + * recipient.c: Removed file. + * rungpg.c (append_args_from_recipients): Change last arg to + gpgme_user_id_t. Reimplement. + (gpg_encrypt): Change second arg to gpgme_user_id_t. + (gpg_encrypt_sign): Likewise. + (gpg_export): Likewise. Rewrite user ID list code. + * engine.c (_gpgme_engine_op_encrypt): Change second arg to + gpgme_user_id_t. + (_gpgme_engine_op_encrypt_sign): Likewise. + (_gpgme_engine_op_export): Likewise. + * engine.h (_gpgme_engine_op_encrypt, _gpgme_engine_op_encrypt_sign, + _gpgme_engine_op_export): Likewise. + * engine-gpgsm.c (set_recipients): Likewise. Rewrite loop code. + (gpgsm_encrypt): Likewise. + (gpgsm_export): Likewise. + * engine-backend.h (struct engine_ops): Likewise for members + ENCRYPT, ENCRYPT_SIGN and EXPORT. + * export.c (export_start, gpgme_op_export_start, gpgme_op_export): + Likewise. + * encrypt.c (encrypt_start): Likewise. Don't check for count of + recipients. + (gpgme_op_encrypt_start): Likewise. + (gpgme_op_encrypt): Likewise. + * encrypt-sign.c (encrypt_sign_start): Likewise. + (gpgme_op_encrypt_sign): Likewise. + (gpgme_op_encrypt_sign_start): Likewise. + +2003-05-27 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (struct _gpgme_op_import_result): Add skipped_new_keys. + * import.c (parse_import_res): Add skipped_new_keys parser. + + * op-support.c (_gpgme_parse_inv_userid): Add missing break + statements. + * encrypt.c (gpgme_op_encrypt): Use gpgme_error_t instead of int. + +2003-05-27 Marcus Brinkmann <marcus@g10code.de> + + * encrypt.c (gpgme_op_encrypt_result): Use intermediate variable + HOOK to avoid compiler warning. Don't ask, you don't want to know. + (_gpgme_encrypt_status_handler): Likewise. + (_gpgme_op_encrypt_init_result): Likewise. + * decrypt.c (gpgme_op_decrypt_result): Likewise. + (_gpgme_decrypt_status_handler): Likewise. + (_gpgme_op_decrypt_init_result): Likewise. + * verify.c (gpgme_op_verify_result): Likewise. + (_gpgme_verify_status_handler): Likewise. + (_gpgme_op_verify_init_result): Likewise. + * edit.c (edit_status_handler): Likewise. + (command_handler): Likewise. + (edit_start): Likewise. + * genkey.c (gpgme_op_genkey_result): Likewise. + (genkey_status_handler): Likewise. + (genkey_start): Likewise. + * import.c (gpgme_op_import_result): Likewise. + (import_status_handler): Likewise. + (_gpgme_op_import_start): Likewise. + * trustlist.c (gpgme_op_trustlist_next): Likewise. + (_gpgme_op_trustlist_event_cb): Likewise. + (gpgme_op_trustlist_start): Likewise. + * keylist.c (gpgme_op_keylist_result): Likewise. + (keylist_colon_handler): Likewise. + (keylist_status_handler): Likewise. + (_gpgme_op_keylist_event_cb): Likewise. + (gpgme_op_keylist_start): Likewise. + (gpgme_op_keylist_ext_start): Likewise. + (gpgme_op_keylist_next): Likewise. + * passphrase.c (_gpgme_passphrase_status_handler): Likewise. + (_gpgme_passphrase_command_handler_internal): Likewise. + * sign.c (gpgme_op_sign_result): Likewise. + (_gpgme_sign_status_handler): Likewise. + (_gpgme_op_sign_init_result): Likewise. + + * passphrase.c (_gpgme_passphrase_command_handler_internal): Fix + access to pointer type. + +2003-05-26 Marcus Brinkmann <marcus@g10code.de> + + * engine.h (EngineCommandHandler): Change last argument to int fd. + * gpgme.h (gpgme_passphrase_cb_t): Rewritten to take parts of the + description and fd. + (gpgme_edit_cb_t): Change last argument to int fd. + * ops.h (_gpgme_passphrase_command_handler_internal): New prototype. + * passphrase.c: Include <assert.h>. + (op_data_t): Rename userid_hint to uid_hint, remove last_pw_handle. + (release_op_data): Check values before calling free. + (_gpgme_passphrase_status_handler): Likewise. + (_gpgme_passphrase_command_handler_internal): New function. + (_gpgme_passphrase_command_handler): Rewritten. + * edit.c (edit_status_handler): Pass -1 as fd argument. + (command_handler): Update prototype. New variable processed. Use + it to store return value of + _gpgme_passphrase_command_handler_internal which is now used + instead _gpgme_passphrase_command_handler. Use it also to check + if we should call the user's edit function. Pass fd to user's + edit function. + * rungpg.c (struct gpg_object_s): Change type of cmd.cb_data to + void *. + (gpg_release): Check value before calling free. Do not release + cmd.cb_data. + (command_cb): Function removed. + (command_handler): New function. Thus we don't use a data object + for command handler stuff anymore, but handle it directly. This + allows proper error reporting (cancel of passphrase requests, for + example). Also all callbacks work via direct writes to the file + descriptor (so that passphrases are not kept in insecure memory). + (gpg_set_command_handler): Rewritten to use even more ugly hacks. + (read_status): Check cmd.keyword before calling free. Install + command_handler as the I/O callback handler with GPG as private + data. + + * rungpg.c (gpg_new): Add --enable-progress-filter to gpg + invocation. + * decrypt-verify.c (_gpgme_op_decrypt_verify_start): Rename to + decrypt_verify_start. + (gpgme_op_decrypt_verify_start): Call decrypt_verify_start. + (gpgme_op_decrypt_verify): Likewise. + * verify.c (verify_status_handler): New function that also calls + progress status handler. + (_gpgme_op_verify_start): Set status handler to verify_status_handler. + Rename to (verify_start). + (gpgme_op_verify_start): Call verify_start. + (gpgme_op_verify): Likewise. + * encrypt.c (encrypt_status_handler): New function. + (_gpgme_encrypt_sym_status_handler): Call progress status handler. + Make static. Rename to encrypt_sym_status_handler. + (encrypt_start): Set status handler to encrypt_sym_status_handler + or encrypt_status_handler. + * sign.c (sign_status_handler): New function. + (sign_start): Set status handler to sign_status_handler. + * decrypt.c (decrypt_status_handler): New function that also calls + progress status handler. + (decrypt_start): Set status handler to decrypt_status_handler. + * encrypt-sign.c (encrypt_sign_status_handler): Likewise. + * decrypt-verify.c (decrypt_verify_status_handler): Call + _gpgme_progress_status_handler. + + * conversion.c (_gpgme_decode_c_string): Add missing break + statement. + + * recipient.c (gpgme_recipients_add_name_with_validity): Add one + to buffer to allocate. + +2003-05-19 Marcus Brinkmann <marcus@g10code.de> + + * verify.c (parse_new_sig): Fix ERRSIG case. + Submitted by Benjamin Lee <benjaminlee@users.sf.net>. + +2003-05-18 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h: The following types are renamed. The old name is kept + as a deprecated typedef. + (GpgmeCtx): Rename to gpgme_ctx_t. + (GpgmeData): Rename to gpgme_data_t. + (GpgmeRecipients): Rename to gpgme_recipients_t. + (GpgmeError): Rename to gpgme_error_t. + (GpgmeDataEncoding): Rename to gpgme_data_encoding_t. + (GpgmePubKeyAlgo): Rename to gpgme_pubkey_algo_t. + (GpgmeHashAlgo): Rename to gpgme_hash_algo_t. + (GpgmeSigStat): Rename to gpgme_sig_stat_t. + (GpgmeSigMode): Rename to gpgme_sig_mode_t. + (GpgmeAttr): Rename to gpgme_attr_t. + (GpgmeValidity): Rename to gpgme_validity_t. + (GpgmeProtocol): Rename to gpgme_protocol_t. + (GpgmeStatusCode): Rename to gpgme_status_code_t. + (GpgmeEngineInfo): Rename to gpgme_engine_info_t. + (GpgmeSubkey): Rename to gpgme_subkey_t. + (GpgmeKeySig): Rename to gpgme_keysig_t. + (GpgmeUserID): Rename to gpgme_user_id_t. + (GpgmePassphraseCb): Rename to gpgme_passphrase_cb_t. + (GpgmeProgressCb): Rename to gpgme_progress_cb_t. + (GpgmeEditCb): Rename to gpgme_edit_cb_t. + (GpgmeIOCb): Rename to gpgme_io_cb_t. + (GpgmeRegisterIOCb): Rename to gpgme_register_io_cb_t. + (GpgmeRemoveIOCb): Rename to gpgme_remove_io_cb_t. + (GpgmeEventIO): Rename to gpgme_event_io_t. + (GpgmeEventIOCb): Rename to gpgme_event_io_cb_t. + (GpgmeIOCbs): Rename to gpgme_io_cbs. + (gpgme_io_cbs_t): New type. + (GpgmeDataReadCb): Rename to gpgme_data_read_cb_t. + (GpgmeDataWriteCb): Rename to gpgme_data_write_cb_t. + (GpgmeDataSeekCb): Rename to gpgme_data_seek_cb_t. + (GpgmeDataReleaseCb): Rename to gpgme_data_release_cb_t. + (GpgmeDataCbs): Rename to gpgme_data_cbs. + (gpgme_data_cbs_t): New type. + (GpgmeInvalidUserID): Rename to gpgme_invalid_user_id_t. + (GpgmeEncryptResult): Rename to gpgme_encrypt_result_t. + (GpgmeDecryptResult): Rename to gpgme_decrypt_result_t. + (GpgmeNewSignature): Rename to gpgme_new_signature_t. + (GpgmeSignResult): Rename to gpgme_sign_result_t. + (GpgmeSigNotation): Rename to gpgme_sig_notation_t. + (GpgmeSignature): Rename to gpgme_signature_t. + (GpgmeVerifyResult): Rename to gpgme_verify_result_t. + (GpgmeImporttqStatus): Rename to gpgme_import_status_t. + (GpgmeImportResult): Rename to gpgme_import_result_t. + (GpgmeGenKeyResult): Rename to gpgme_genkey_result_t. + (GpgmeKeyListResult): Rename to gpgme_keylist_result_t. + (GpgmeTrustItem): Rename to gpgme_trust_item_t. + * gpgme.h (gpgme_deprecated_error_t): New type, swallowing macros + GPGME_No_Recipients, GPGME_Invalid_Recipient and + GPGME_No_Passphrase. + * data.h (struct gpgme_data_s): Rename to struct gpgme_data. + * context.h (struct gpgme_context_s): Rename to struct + gpgme_context. + (struct gpgme_recipients_s): Rename to gpgme_recipients. + +2003-05-18 Marcus Brinkmann <marcus@g10code.de> + + * keylist.c (finish_key): Clear OPD->tmp_uid. + +2003-05-18 Marcus Brinkmann <marcus@g10code.de> + + * verify.c (_gpgme_verify_status_handler): Return GPGME_No_Data + for NODATA status without signatures. + +2003-05-05 Marcus Brinkmann <marcus@g10code.de> + + * key.c (_gpgme_key_append_name): Use decoded string to parse user id. + (_gpgme_key_add_sig): Likewise. + +2003-05-04 Marcus Brinkmann <marcus@g10code.de> + + * context.h (struct gpgme_context_s): Remove member op_info. + + * key.c (_gpgme_key_add_sig): Initialize SIG->uid. + + * gpgme.h (GpgmeError): Add deprecated values for + GPGME_Invalid_Type and GPGME_Invalid_Mode. + +2003-04-30 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (gpgme_get_op_info): Remove prototype. + * ops.h (_gpgme_set_op_info, + _gpgme_data_release_and_return_string, _gpgme_data_get_as_string, + _gpgme_data_append, _gpgme_data_append_string, + _gpgme_data_append_string_for_xml, _gpgme_data_append_for_xml, + _gpgme_data_append_percentstring_for_xml): Likewise. + (_gpgme_progress_status_handler): Change first arg to void *. + * progress.c (_gpgme_progress_status_handler): Likewise. + * conversion.c: Do not include <string.h>, <errno.h>, <ctype.h>, + and <sys/types.h>, but <string.h>. + (_gpgme_data_append): Remove function. + (_gpgme_data_append_string): Likewise. + (_gpgme_data_append_for_xml): Likewise. + (_gpgme_data_append_string_for_xml): Likewise. + (_gpgme_data_append_percentstring_for_xml): Likewise. + * data-mem.c (_gpgme_data_get_as_string): Likewise. + (_gpgme_data_release_and_return_string): Likewise. + * gpgme.c (gpgme_get_op_info): Likewise. + (_gpgme_set_op_info): Likewise. + + * gpgme.h (struct _gpgme_key): New structure. + (GpgmeKey): Define using _gpgme_key. + (struct _gpgme_subkey): New structure. + (GpgmeSubKey): New type. + (struct _gpgme_key_sig): New structure. + (GpgmeKeySig): New type. + (struct _gpgme_user_id): New structure. + (GpgmeUserID): New type. + (struct _gpgme_op_keylist_result): New structure. + (GpgmeKeyListResult): New type. + (gpgme_op_keylist_result): New function. + (gpgme_key_get_as_xml): Remove prototype. + * context.h (struct gpgme_context_s): Remove members tmp_key, + tmp_uid, key_cond and key_queue. + (struct key_queue_item_s): Remove structure. + (struct user_id_s): Remove structure. + (struct gpgme_recipients_s): Replace with simple + GpgmeUserID list. + * gpgme.c (gpgme_release): Do not release CTX->tmp_key. + * ops.h (_gpgme_key_add_subkey, _gpgme_key_append_name, + _gpgme_key_add_sig, _gpgme_trust_item_new): New prototypes. + * rungpg.c (command_cb): Return GpgmeError instead int. + New variable ERR. Use it to hold return value of cmd handler. + (gpg_delete): Access fingerprint of key directly. + (append_args_from_signers): Likewise. + (gpg_edit): Likewise. + (append_args_from_recipients): Use GpgmeUserID for recipient list. + * engine-gpgsm.c: Do not include "key.h". + (gpgsm_delete): Access fingerprint of key directly. + (gpgsm_sign): Likewise. + (set_recipients): Use GpgmeUserID for recipients. Invert invalid + user ID flag. + * key.h: File removed. + * key.c: Completely reworked to use exposed GpgmeKey data types. + * keylist.c: Likewise. + * recipient.c: Completely reworked to use GpgmeUserID. + +2003-04-29 Marcus Brinkmann <marcus@g10code.de> + + * gpgme.h (gpgme_get_key): Remove force_update argument. + * key-cache.c: File removed. + * Makefile.am (libgpgme_la_SOURCES): Remove key-cache.c. + * ops.h (_gpgme_key_cache_add, _gpgme_key_cache_get): Remove + prototypes. + * keylist.c (_gpgme_op_keylist_event_cb): Don't call + _gpgme_key_cache_add. + (gpgme_get_key): New function. + * verify.c (gpgme_get_sig_key): Remove last argument to + gpgme_get_key invocation. + + * gpgme.h (struct _gpgme_trust_item): New structure. + (GpgmeTrustItem): New type. + (gpgme_trust_item_ref, gpgme_trust_item_unref): New prototypes. + * context.h (struct trust_queue_item_s): Remove structure. + (struct gpgme_context_s): Remove trust_queue member. + * Makefile.am (libgpgme_la_SOURCES): Add trust-item.c. + * trust-item.c: New file. + * trustlist.c: Do not include <stdio.h> or <time.h>, but + "gpgme.h". + (struct trust_queue_item_s): Change to new type op_data_t. + (trust_status_handler): Change first argument to void *. + (trust_colon_handler): Likewise. + (_gpgme_op_trustlist_event_cb): Use op_data_t type. + (gpgme_op_trustlist_start): Use op_data_t and rework error + handling. + (gpgme_op_trustlist_next): Use op_data_t. + (gpgme_trust_item_release): Remove function. + (gpgme_trust_item_get_string_attr): Likewise. + (gpgme_trust_item_get_int_attr): Likewise. + + * verify.c (calc_sig_summary): Do not set GPGME_SIGSUM_SYS_ERROR + for bad signatures. + +2003-04-28 Marcus Brinkmann <marcus@g10code.de> + + * context.h: Remove OPDATA_VERIFY_COLLECTING. + (struct gpgme_context_s): Remove member notation. + * gpgme.h: Make enum for GPGME_KEYLIST_MODE_* values. + + * gpgme.h (struct _gpgme_sig_notation): New structure. + (GpgmeSigNotation): New type. + (struct _gpgme_signature): New structure. + (GpgmeSignature): New type. + (struct _gpgme_op_verify_result): New structure. + (GpgmeVerifyResult): New type. + (gpgme_op_verify_result): New prototype. + (gpgme_get_notation): Remove prototype. + * ops.h (_gpgme_op_verify_init_result): New prototype. + (_gpgme_verify_status_handler): Change first argument to void *. + * util.h (_gpgme_decode_percent_string, _gpgme_map_gnupg_error): + New prototypes. + * conversion.c (_gpgme_decode_percent_string): New function. + (gnupg_errors): New static global. + (_gpgme_map_gnupg_error): New function. + * gpgme.c (gpgme_release): Don't release CTX->notation. + (gpgme_get_notation): Remove function. + * decrypt-verify.c (_gpgme_op_decrypt_verify_start): Call + _gpgme_op_verify_init_result. + * verify.c: Do not include <stdio.h>, <assert.h> and "key.h", but + do include "gpgme.h". + (struct verify_result): Replace with ... + (op_data_t): ... this type. + (release_verify_result): Remove function. + (release_op_data): New function. + (is_token): Remove function. + (skip_token): Remove function. + (copy_token): Remove function. + (gpgme_op_verify_result): New function. + (calc_sig_summary): Rewritten. + (finish_sig): Remove function. + (parse_new_sig): New function. + (parse_valid_sig): New function. + (parse_notation): New function. + (parse_trust): New function. + (parse_error): New function. + (_gpgme_verify_status_handler): Rewritten. Change first argument + to void *. + (_gpgme_op_verify_start): Rework error handling. Call + _gpgme_op_verify_init_result. + (gpgme_op_verify): Do not release or clear CTX->notation. + (gpgme_get_sig_status): Rewritten. + (gpgme_get_sig_string_attr): Likewise. + (gpgme_get_sig_ulong_attr): Likewise. + (gpgme_get_sig_key): Likewise. + + * gpgme.h (struct _gpgme_op_decrypt_result): New structure. + (GpgmeDecryptResult): New type. + (gpgme_op_decrypt_result): New prototype. + * ops.h (_gpgme_op_decrypt_init_result): New prototype. + (_gpgme_decrypt_status_handler): Fix prototype. + (_gpgme_decrypt_start): Remove prototype. + * decrypt-verify.c: Do not include <stdio.h>, <stdlib.h>, + <string.h> and <assert.h>, "util.h" and "context.h", but + "gpgme.h". + (decrypt_verify_status_handler): Change first argument to void *, + and rework error handling. + (_gpgme_op_decrypt_verify_start): New function. + (gpgme_op_decrypt_verify_start): Rewrite using + _gpgme_op_decrypt_verify_start. + (gpgme_op_decrypt_verify): Likewise. + * decrypt.c: Include <string.h>, "gpgme.h" and "util.h". + (struct decrypt_result): Change to typedef op_data_t, rewritten. + (is_token): Remove function. + (release_op_data): New function. + (skip_token): Remove function. + (gpgme_op_decrypt_result): New function. + (_gpgme_decrypt_status_handler): Change first argument to void *. + Rework error handling. + (_gpgme_decrypt_start): Rename to ... + (decrypt_start): ... this. Call _gpgme_op_decrypt_init_result. + (_gpgme_op_decrypt_init_result): New function. + (gpgme_op_decrypt_start): Use decrypt_start. + (gpgme_op_decrypt): Likewise. + +2003-04-27 Marcus Brinkmann <marcus@g10code.de> + + * encrypt-sign.c: Do not include <stddef.h>, <stdio.h>, + <stdlib.h>, <string.h>, <assert.h> and "util.h", but "gpgme.h". + (_gpgme_op_encrypt_sign_start): Rename to ... + (encrypt_sign_start): ... this. + (gpgme_op_encrypt_sign_start): Use encrypt_sign_start, not + _gpgme_op_encrypt_sign_start. + (gpgme_op_encrypt_sign): Likewise. + + * gpgme.h (GpgmeEncryptResult): New data type. + (gpgme_op_encrypt_result): New prototype. + * ops.h (_gpgme_op_encrypt_init_result): New prototype. + (_gpgme_op_encrypt_status_handler): Fix prototype. + * encrypt-sign.c (_gpgme_op_encrypt_sign_start): Call + _gpgme_op_encrypt_init_result. + * encrypt.c: Do not include <stdio.h>, <assert.h>, "util.h" and + "wait.h". Include <errno.h> and "gpgme.h". + (SKIP_TOKEN_OR_RETURN): Remove macro. + (struct encrypt_result): Rename to ... + (op_data_t): ... new data type. Rewrite for user result data. + (append_xml_encinfo): Remove function. + (release_op_data): New function. + (gpgme_op_encrypt_result): New function. + (_gpgme_op_encrypt_status_handler): Change first argument to void *. + Rewrite result parsing. + (_gpgme_op_encrypt_sym_status_handler): Change first argument to + void *. + (_gpgme_op_encrypt_init_result): New function. + (_gpgme_op_encrypt_start): Rename to ... + (encrypt_start): ... this. + (gpgme_op_encrypt_start): Use encrypt_start, not + gpgme_op_encrypt_start. + (gpgme_op_encrypt): Likewise. + + * gpgme.h (GpgmePubKeyAlgo, GpgmeHashAlgo, GpgmeInvalidUserID, + GpgmeNewSignature, GpgmeSignResult): New data types. + (gpgme_op_sign_result, gpgme_pubkey_algo_name, + gpgme_hash_algo_name): New prototypes. + * gpgme.c (gpgme_pubkey_algo_name): New function. + (gpgme_hash_algo_name): Likewise. + * ops.h (_gpgme_parse_inv_userid, _gpgme_op_sign_init_result): New + prototype. |