From be0ca741fd12897337408d1d7a7d8f5f18e1fac9 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <kb9vqf@pearsoncomputing.net>
Date: Wed, 16 Nov 2011 16:06:07 -0600
Subject: Finish rename from prior commit

---
 libtdenetwork/CMakeLists.txt                       |   20 +
 libtdenetwork/Makefile.am                          |    7 +
 libtdenetwork/gpgmepp/CMakeLists.txt               |   54 +
 libtdenetwork/gpgmepp/Makefile.am                  |   52 +
 libtdenetwork/gpgmepp/README.gpgme++               |   82 +
 libtdenetwork/gpgmepp/callbacks.cpp                |  138 +
 libtdenetwork/gpgmepp/callbacks.h                  |   39 +
 libtdenetwork/gpgmepp/configure.in.bot             |   10 +
 libtdenetwork/gpgmepp/configure.in.in              |  193 +
 libtdenetwork/gpgmepp/context.cpp                  |  763 +++
 libtdenetwork/gpgmepp/context.h                    |  328 ++
 libtdenetwork/gpgmepp/context_p.h                  |   76 +
 libtdenetwork/gpgmepp/data.cpp                     |  160 +
 libtdenetwork/gpgmepp/data.h                       |   72 +
 libtdenetwork/gpgmepp/data_p.h                     |   39 +
 libtdenetwork/gpgmepp/decryptionresult.cpp         |   85 +
 libtdenetwork/gpgmepp/decryptionresult.h           |   59 +
 libtdenetwork/gpgmepp/encryptionresult.cpp         |  165 +
 libtdenetwork/gpgmepp/encryptionresult.h           |   84 +
 libtdenetwork/gpgmepp/engineinfo.cpp               |   99 +
 libtdenetwork/gpgmepp/engineinfo.h                 |   53 +
 libtdenetwork/gpgmepp/eventloopinteractor.cpp      |  185 +
 libtdenetwork/gpgmepp/eventloopinteractor.h        |  148 +
 libtdenetwork/gpgmepp/gpgme-0-3-compat.h           |   49 +
 libtdenetwork/gpgmepp/gpgmefw.h                    |   60 +
 libtdenetwork/gpgmepp/importresult.cpp             |  204 +
 libtdenetwork/gpgmepp/importresult.h               |  103 +
 libtdenetwork/gpgmepp/interfaces/CMakeLists.txt    |   14 +
 libtdenetwork/gpgmepp/interfaces/Makefile.am       |    3 +
 libtdenetwork/gpgmepp/interfaces/dataprovider.h    |   48 +
 libtdenetwork/gpgmepp/interfaces/editinteractor.h  |   35 +
 .../gpgmepp/interfaces/passphraseprovider.h        |   38 +
 .../gpgmepp/interfaces/progressprovider.h          |   36 +
 libtdenetwork/gpgmepp/key.cpp                      |  926 ++++
 libtdenetwork/gpgmepp/key.h                        |  285 ++
 libtdenetwork/gpgmepp/keygenerationresult.cpp      |   73 +
 libtdenetwork/gpgmepp/keygenerationresult.h        |   53 +
 libtdenetwork/gpgmepp/keylistresult.cpp            |   92 +
 libtdenetwork/gpgmepp/keylistresult.h              |   62 +
 libtdenetwork/gpgmepp/result.h                     |   47 +
 libtdenetwork/gpgmepp/result_p.h                   |   69 +
 libtdenetwork/gpgmepp/shared.h                     |   54 +
 libtdenetwork/gpgmepp/signingresult.cpp            |  283 ++
 libtdenetwork/gpgmepp/signingresult.h              |  124 +
 libtdenetwork/gpgmepp/trustitem.cpp                |  109 +
 libtdenetwork/gpgmepp/trustitem.h                  |   61 +
 libtdenetwork/gpgmepp/util.h                       |   75 +
 libtdenetwork/gpgmepp/verificationresult.cpp       |  357 ++
 libtdenetwork/gpgmepp/verificationresult.h         |  144 +
 libtdenetwork/libgpg-error-copy/Makefile.am        |   87 +
 libtdenetwork/libgpg-error-copy/code-from-errno.c  |   69 +
 libtdenetwork/libgpg-error-copy/code-to-errno.c    |   42 +
 libtdenetwork/libgpg-error-copy/err-codes.h.in     |  289 ++
 libtdenetwork/libgpg-error-copy/err-sources.h.in   |   55 +
 libtdenetwork/libgpg-error-copy/errnos.in          |  172 +
 libtdenetwork/libgpg-error-copy/gettext.h          |   75 +
 libtdenetwork/libgpg-error-copy/gpg-error.h.in     |  258 +
 libtdenetwork/libgpg-error-copy/mkerrcodes.awk     |   99 +
 libtdenetwork/libgpg-error-copy/mkerrcodes.c       |   78 +
 libtdenetwork/libgpg-error-copy/mkerrcodes1.awk    |   90 +
 libtdenetwork/libgpg-error-copy/mkerrcodes2.awk    |  134 +
 libtdenetwork/libgpg-error-copy/mkerrnos.awk       |   97 +
 libtdenetwork/libgpg-error-copy/mkheader.awk       |  190 +
 libtdenetwork/libgpg-error-copy/mkstrtable.awk     |  186 +
 libtdenetwork/libgpg-error-copy/strerror.c         |  169 +
 libtdenetwork/libgpg-error-copy/strsource.c        |   37 +
 libtdenetwork/libgpgme-copy/Makefile.am            |    1 +
 libtdenetwork/libgpgme-copy/assuan/ChangeLog       |  829 +++
 libtdenetwork/libgpgme-copy/assuan/Makefile.am     |   58 +
 libtdenetwork/libgpgme-copy/assuan/assuan-buffer.c |  550 ++
 libtdenetwork/libgpgme-copy/assuan/assuan-client.c |  234 +
 .../libgpgme-copy/assuan/assuan-connect.c          |   79 +
 libtdenetwork/libgpgme-copy/assuan/assuan-defs.h   |  323 ++
 .../libgpgme-copy/assuan/assuan-handler.c          |  774 +++
 .../libgpgme-copy/assuan/assuan-inquire.c          |  241 +
 libtdenetwork/libgpgme-copy/assuan/assuan-io.c     |   87 +
 libtdenetwork/libgpgme-copy/assuan/assuan-listen.c |  157 +
 .../libgpgme-copy/assuan/assuan-logging.c          |  241 +
 .../libgpgme-copy/assuan/assuan-pipe-connect.c     |  889 ++++
 .../libgpgme-copy/assuan/assuan-pipe-server.c      |  187 +
 .../libgpgme-copy/assuan/assuan-socket-connect.c   |  184 +
 .../libgpgme-copy/assuan/assuan-socket-server.c    |  187 +
 libtdenetwork/libgpgme-copy/assuan/assuan-socket.c |  148 +
 libtdenetwork/libgpgme-copy/assuan/assuan-uds.c    |  311 ++
 libtdenetwork/libgpgme-copy/assuan/assuan-util.c   |  171 +
 libtdenetwork/libgpgme-copy/assuan/assuan.h        |  565 +++
 libtdenetwork/libgpgme-copy/assuan/funopen.c       |   64 +
 libtdenetwork/libgpgme-copy/assuan/mkerrors        |  228 +
 libtdenetwork/libgpgme-copy/configure.in.in        |  364 ++
 libtdenetwork/libgpgme-copy/gpgme/ChangeLog        | 5312 ++++++++++++++++++++
 libtdenetwork/libgpgme-copy/gpgme/Makefile.am      |   50 +
 libtdenetwork/libgpgme-copy/gpgme/ath-pth-compat.c |  123 +
 libtdenetwork/libgpgme-copy/gpgme/ath-pth.c        |  178 +
 .../libgpgme-copy/gpgme/ath-pthread-compat.c       |  104 +
 libtdenetwork/libgpgme-copy/gpgme/ath-pthread.c    |  175 +
 libtdenetwork/libgpgme-copy/gpgme/ath.c            |  169 +
 libtdenetwork/libgpgme-copy/gpgme/ath.h            |   89 +
 libtdenetwork/libgpgme-copy/gpgme/context.h        |  118 +
 libtdenetwork/libgpgme-copy/gpgme/conversion.c     |  414 ++
 libtdenetwork/libgpgme-copy/gpgme/data-compat.c    |  209 +
 libtdenetwork/libgpgme-copy/gpgme/data-fd.c        |   78 +
 libtdenetwork/libgpgme-copy/gpgme/data-mem.c       |  251 +
 libtdenetwork/libgpgme-copy/gpgme/data-stream.c    |  101 +
 libtdenetwork/libgpgme-copy/gpgme/data-user.c      |   89 +
 libtdenetwork/libgpgme-copy/gpgme/data.c           |  293 ++
 libtdenetwork/libgpgme-copy/gpgme/data.h           |  132 +
 libtdenetwork/libgpgme-copy/gpgme/debug.c          |  221 +
 libtdenetwork/libgpgme-copy/gpgme/debug.h          |  127 +
 libtdenetwork/libgpgme-copy/gpgme/decrypt-verify.c |  103 +
 libtdenetwork/libgpgme-copy/gpgme/decrypt.c        |  340 ++
 libtdenetwork/libgpgme-copy/gpgme/delete.c         |  109 +
 libtdenetwork/libgpgme-copy/gpgme/edit.c           |  177 +
 libtdenetwork/libgpgme-copy/gpgme/encrypt-sign.c   |  110 +
 libtdenetwork/libgpgme-copy/gpgme/encrypt.c        |  222 +
 libtdenetwork/libgpgme-copy/gpgme/engine-backend.h |  110 +
 libtdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c   | 1750 +++++++
 libtdenetwork/libgpgme-copy/gpgme/engine.c         |  744 +++
 libtdenetwork/libgpgme-copy/gpgme/engine.h         |  133 +
 libtdenetwork/libgpgme-copy/gpgme/error.c          |   92 +
 libtdenetwork/libgpgme-copy/gpgme/export.c         |  117 +
 libtdenetwork/libgpgme-copy/gpgme/fakes.c          |   24 +
 libtdenetwork/libgpgme-copy/gpgme/funopen.c        |   43 +
 libtdenetwork/libgpgme-copy/gpgme/genkey.c         |  206 +
 libtdenetwork/libgpgme-copy/gpgme/get-env.c        |   59 +
 libtdenetwork/libgpgme-copy/gpgme/gpgme.c          |  582 +++
 libtdenetwork/libgpgme-copy/gpgme/gpgme.h          | 1706 +++++++
 libtdenetwork/libgpgme-copy/gpgme/import.c         |  273 +
 libtdenetwork/libgpgme-copy/gpgme/io.h             |   65 +
 libtdenetwork/libgpgme-copy/gpgme/isascii.c        |   28 +
 libtdenetwork/libgpgme-copy/gpgme/key.c            |  722 +++
 libtdenetwork/libgpgme-copy/gpgme/keylist.c        |  980 ++++
 libtdenetwork/libgpgme-copy/gpgme/libgpgme.vers    |  167 +
 libtdenetwork/libgpgme-copy/gpgme/memrchr.c        |  210 +
 libtdenetwork/libgpgme-copy/gpgme/mkstatus         |   52 +
 libtdenetwork/libgpgme-copy/gpgme/op-support.c     |  280 ++
 libtdenetwork/libgpgme-copy/gpgme/ops.h            |  169 +
 libtdenetwork/libgpgme-copy/gpgme/passphrase.c     |  153 +
 libtdenetwork/libgpgme-copy/gpgme/posix-io.c       |  497 ++
 libtdenetwork/libgpgme-copy/gpgme/posix-sema.c     |   62 +
 libtdenetwork/libgpgme-copy/gpgme/posix-util.c     |   57 +
 libtdenetwork/libgpgme-copy/gpgme/priv-io.h        |   67 +
 libtdenetwork/libgpgme-copy/gpgme/progress.c       |   81 +
 libtdenetwork/libgpgme-copy/gpgme/putc_unlocked.c  |   31 +
 libtdenetwork/libgpgme-copy/gpgme/rungpg.c         | 2111 ++++++++
 libtdenetwork/libgpgme-copy/gpgme/sema.h           |   67 +
 libtdenetwork/libgpgme-copy/gpgme/sig-notation.c   |  260 +
 libtdenetwork/libgpgme-copy/gpgme/sign.c           |  328 ++
 libtdenetwork/libgpgme-copy/gpgme/signers.c        |   95 +
 libtdenetwork/libgpgme-copy/gpgme/status-table.h   |   94 +
 libtdenetwork/libgpgme-copy/gpgme/stpcpy.c         |   55 +
 libtdenetwork/libgpgme-copy/gpgme/trust-item.c     |  171 +
 libtdenetwork/libgpgme-copy/gpgme/trustlist.c      |  248 +
 libtdenetwork/libgpgme-copy/gpgme/util.h           |  106 +
 libtdenetwork/libgpgme-copy/gpgme/vasprintf.c      |  192 +
 libtdenetwork/libgpgme-copy/gpgme/verify.c         |  992 ++++
 libtdenetwork/libgpgme-copy/gpgme/version.c        |  231 +
 libtdenetwork/libgpgme-copy/gpgme/w32-io.c         | 1152 +++++
 libtdenetwork/libgpgme-copy/gpgme/w32-sema.c       |  115 +
 libtdenetwork/libgpgme-copy/gpgme/w32-util.c       |  317 ++
 libtdenetwork/libgpgme-copy/gpgme/wait-global.c    |  384 ++
 libtdenetwork/libgpgme-copy/gpgme/wait-private.c   |  147 +
 libtdenetwork/libgpgme-copy/gpgme/wait-user.c      |  122 +
 libtdenetwork/libgpgme-copy/gpgme/wait.c           |  204 +
 libtdenetwork/libgpgme-copy/gpgme/wait.h           |   82 +
 libtdenetwork/qgpgme/CMakeLists.txt                |   41 +
 libtdenetwork/qgpgme/Makefile.am                   |   18 +
 libtdenetwork/qgpgme/dataprovider.cpp              |  107 +
 libtdenetwork/qgpgme/dataprovider.h                |   62 +
 libtdenetwork/qgpgme/eventloopinteractor.cpp       |   99 +
 libtdenetwork/qgpgme/eventloopinteractor.h         |   90 +
 libtdenetwork/qgpgme/tests/Makefile.am             |    9 +
 libtdenetwork/qgpgme/tests/dataprovidertest.cpp    |  125 +
 libtdenetwork/tests/.gitignore                     |    0
 173 files changed, 42092 insertions(+)
 create mode 100644 libtdenetwork/CMakeLists.txt
 create mode 100644 libtdenetwork/Makefile.am
 create mode 100644 libtdenetwork/gpgmepp/CMakeLists.txt
 create mode 100644 libtdenetwork/gpgmepp/Makefile.am
 create mode 100644 libtdenetwork/gpgmepp/README.gpgme++
 create mode 100644 libtdenetwork/gpgmepp/callbacks.cpp
 create mode 100644 libtdenetwork/gpgmepp/callbacks.h
 create mode 100644 libtdenetwork/gpgmepp/configure.in.bot
 create mode 100644 libtdenetwork/gpgmepp/configure.in.in
 create mode 100644 libtdenetwork/gpgmepp/context.cpp
 create mode 100644 libtdenetwork/gpgmepp/context.h
 create mode 100644 libtdenetwork/gpgmepp/context_p.h
 create mode 100644 libtdenetwork/gpgmepp/data.cpp
 create mode 100644 libtdenetwork/gpgmepp/data.h
 create mode 100644 libtdenetwork/gpgmepp/data_p.h
 create mode 100644 libtdenetwork/gpgmepp/decryptionresult.cpp
 create mode 100644 libtdenetwork/gpgmepp/decryptionresult.h
 create mode 100644 libtdenetwork/gpgmepp/encryptionresult.cpp
 create mode 100644 libtdenetwork/gpgmepp/encryptionresult.h
 create mode 100644 libtdenetwork/gpgmepp/engineinfo.cpp
 create mode 100644 libtdenetwork/gpgmepp/engineinfo.h
 create mode 100644 libtdenetwork/gpgmepp/eventloopinteractor.cpp
 create mode 100644 libtdenetwork/gpgmepp/eventloopinteractor.h
 create mode 100644 libtdenetwork/gpgmepp/gpgme-0-3-compat.h
 create mode 100644 libtdenetwork/gpgmepp/gpgmefw.h
 create mode 100644 libtdenetwork/gpgmepp/importresult.cpp
 create mode 100644 libtdenetwork/gpgmepp/importresult.h
 create mode 100644 libtdenetwork/gpgmepp/interfaces/CMakeLists.txt
 create mode 100644 libtdenetwork/gpgmepp/interfaces/Makefile.am
 create mode 100644 libtdenetwork/gpgmepp/interfaces/dataprovider.h
 create mode 100644 libtdenetwork/gpgmepp/interfaces/editinteractor.h
 create mode 100644 libtdenetwork/gpgmepp/interfaces/passphraseprovider.h
 create mode 100644 libtdenetwork/gpgmepp/interfaces/progressprovider.h
 create mode 100644 libtdenetwork/gpgmepp/key.cpp
 create mode 100644 libtdenetwork/gpgmepp/key.h
 create mode 100644 libtdenetwork/gpgmepp/keygenerationresult.cpp
 create mode 100644 libtdenetwork/gpgmepp/keygenerationresult.h
 create mode 100644 libtdenetwork/gpgmepp/keylistresult.cpp
 create mode 100644 libtdenetwork/gpgmepp/keylistresult.h
 create mode 100644 libtdenetwork/gpgmepp/result.h
 create mode 100644 libtdenetwork/gpgmepp/result_p.h
 create mode 100644 libtdenetwork/gpgmepp/shared.h
 create mode 100644 libtdenetwork/gpgmepp/signingresult.cpp
 create mode 100644 libtdenetwork/gpgmepp/signingresult.h
 create mode 100644 libtdenetwork/gpgmepp/trustitem.cpp
 create mode 100644 libtdenetwork/gpgmepp/trustitem.h
 create mode 100644 libtdenetwork/gpgmepp/util.h
 create mode 100644 libtdenetwork/gpgmepp/verificationresult.cpp
 create mode 100644 libtdenetwork/gpgmepp/verificationresult.h
 create mode 100644 libtdenetwork/libgpg-error-copy/Makefile.am
 create mode 100644 libtdenetwork/libgpg-error-copy/code-from-errno.c
 create mode 100644 libtdenetwork/libgpg-error-copy/code-to-errno.c
 create mode 100644 libtdenetwork/libgpg-error-copy/err-codes.h.in
 create mode 100644 libtdenetwork/libgpg-error-copy/err-sources.h.in
 create mode 100644 libtdenetwork/libgpg-error-copy/errnos.in
 create mode 100644 libtdenetwork/libgpg-error-copy/gettext.h
 create mode 100644 libtdenetwork/libgpg-error-copy/gpg-error.h.in
 create mode 100644 libtdenetwork/libgpg-error-copy/mkerrcodes.awk
 create mode 100644 libtdenetwork/libgpg-error-copy/mkerrcodes.c
 create mode 100644 libtdenetwork/libgpg-error-copy/mkerrcodes1.awk
 create mode 100644 libtdenetwork/libgpg-error-copy/mkerrcodes2.awk
 create mode 100644 libtdenetwork/libgpg-error-copy/mkerrnos.awk
 create mode 100644 libtdenetwork/libgpg-error-copy/mkheader.awk
 create mode 100644 libtdenetwork/libgpg-error-copy/mkstrtable.awk
 create mode 100644 libtdenetwork/libgpg-error-copy/strerror.c
 create mode 100644 libtdenetwork/libgpg-error-copy/strsource.c
 create mode 100644 libtdenetwork/libgpgme-copy/Makefile.am
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/ChangeLog
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/Makefile.am
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-buffer.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-client.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-connect.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-defs.h
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-handler.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-inquire.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-io.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-listen.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-logging.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-pipe-connect.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-pipe-server.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-socket-connect.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-socket-server.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-socket.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-uds.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan-util.c
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/assuan.h
 create mode 100644 libtdenetwork/libgpgme-copy/assuan/funopen.c
 create mode 100755 libtdenetwork/libgpgme-copy/assuan/mkerrors
 create mode 100644 libtdenetwork/libgpgme-copy/configure.in.in
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ChangeLog
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/Makefile.am
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ath-pth-compat.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ath-pth.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ath-pthread-compat.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ath-pthread.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ath.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ath.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/context.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/conversion.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/data-compat.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/data-fd.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/data-mem.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/data-stream.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/data-user.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/data.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/data.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/debug.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/debug.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/decrypt-verify.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/decrypt.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/delete.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/edit.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/encrypt-sign.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/encrypt.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/engine-backend.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/engine.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/engine.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/error.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/export.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/fakes.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/funopen.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/genkey.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/get-env.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/gpgme.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/gpgme.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/import.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/io.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/isascii.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/key.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/keylist.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/libgpgme.vers
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/memrchr.c
 create mode 100755 libtdenetwork/libgpgme-copy/gpgme/mkstatus
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/op-support.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/ops.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/passphrase.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/posix-io.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/posix-sema.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/posix-util.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/priv-io.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/progress.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/putc_unlocked.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/rungpg.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/sema.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/sig-notation.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/sign.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/signers.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/status-table.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/stpcpy.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/trust-item.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/trustlist.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/util.h
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/vasprintf.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/verify.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/version.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/w32-io.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/w32-sema.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/w32-util.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/wait-global.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/wait-private.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/wait-user.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/wait.c
 create mode 100644 libtdenetwork/libgpgme-copy/gpgme/wait.h
 create mode 100644 libtdenetwork/qgpgme/CMakeLists.txt
 create mode 100644 libtdenetwork/qgpgme/Makefile.am
 create mode 100644 libtdenetwork/qgpgme/dataprovider.cpp
 create mode 100644 libtdenetwork/qgpgme/dataprovider.h
 create mode 100644 libtdenetwork/qgpgme/eventloopinteractor.cpp
 create mode 100644 libtdenetwork/qgpgme/eventloopinteractor.h
 create mode 100644 libtdenetwork/qgpgme/tests/Makefile.am
 create mode 100644 libtdenetwork/qgpgme/tests/dataprovidertest.cpp
 create mode 100644 libtdenetwork/tests/.gitignore

(limited to 'libtdenetwork')

diff --git a/libtdenetwork/CMakeLists.txt b/libtdenetwork/CMakeLists.txt
new file mode 100644
index 000000000..1eaefeaa5
--- /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 000000000..e1014e581
--- /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 000000000..cf4efc7f7
--- /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 000000000..d4ebfde99
--- /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 000000000..ecda2c9ac
--- /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 000000000..b352515d0
--- /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 000000000..cc5b93552
--- /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 000000000..e4b1a8842
--- /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 000000000..6361be451
--- /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 000000000..547adde95
--- /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 000000000..054f8bee7
--- /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 000000000..dfff58634
--- /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 000000000..52471be9b
--- /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 000000000..e12064729
--- /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 000000000..38981cce9
--- /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 000000000..2efcc67d9
--- /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 000000000..da4833bbd
--- /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 000000000..f827ca839
--- /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 000000000..4339bef56
--- /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 000000000..461a61db3
--- /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 000000000..c07d2817a
--- /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 000000000..cdac7d567
--- /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 000000000..c3688833c
--- /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 000000000..5f8c5b616
--- /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 000000000..8fe43746e
--- /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 000000000..3b4b713c7
--- /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 000000000..61675a299
--- /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 000000000..db5b88ee8
--- /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 000000000..ad2f79e42
--- /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 000000000..34dd4a7e1
--- /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 000000000..e1f31eed1
--- /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 000000000..37ff6a8bc
--- /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 000000000..b51765b74
--- /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 000000000..13cd0a7ee
--- /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 000000000..15d09371e
--- /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 000000000..76045ee29
--- /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 000000000..7b2d98e84
--- /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 000000000..17dc3a46d
--- /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 000000000..068210c02
--- /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 000000000..aa91cf984
--- /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 000000000..cc1d2793f
--- /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 000000000..f9c79e0cc
--- /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 000000000..6996eef7a
--- /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 000000000..1ee7a8def
--- /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 000000000..59840ebb6
--- /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 000000000..61c74617b
--- /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 000000000..8246cfc32
--- /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 000000000..abf30d96c
--- /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 000000000..e572ecfee
--- /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 000000000..5f3ed9e6f
--- /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 000000000..f51dd155e
--- /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 000000000..40d472d23
--- /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 000000000..167de9c75
--- /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 000000000..4d8794870
--- /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 000000000..8a47bcce4
--- /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 000000000..0cae5f458
--- /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 000000000..cc1aaea83
--- /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 000000000..66e20c3c2
--- /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 000000000..a92f6d9e0
--- /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 000000000..f93416eee
--- /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 000000000..1dccb7faa
--- /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 000000000..3f7664adb
--- /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 000000000..74d369199
--- /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 000000000..6339dbe70
--- /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 000000000..59b8e9ae8
--- /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 000000000..95614358a
--- /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 000000000..34527396a
--- /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 000000000..b53ac7fd3
--- /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 000000000..aea8f558c
--- /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 000000000..7a1879877
--- /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 000000000..978c69546
--- /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 000000000..92995d8c1
--- /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 000000000..fa04f0b29
--- /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 000000000..866db2259
--- /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 000000000..897e0773b
--- /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 000000000..d1f0d5e48
--- /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 000000000..04db68ce0
--- /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 000000000..cfc3d846f
--- /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 000000000..8ee9c748b
--- /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 000000000..f88516143
--- /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 000000000..5953f1c33
--- /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 000000000..45c227d6d
--- /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 000000000..6aa570896
--- /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 000000000..e9e81016c
--- /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 000000000..d12277fcc
--- /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 000000000..8d0a3960d
--- /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 000000000..ac31007a6
--- /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 000000000..57485411a
--- /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 000000000..afcc995c2
--- /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 000000000..85fd28d30
--- /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.
+	(_gpgme_op_sign_status_handler): Fix prototype.
+	* op-support.c: Include <errno.h> and <string.h>.
+	(_gpgme_parse_inv_userid): New function.
+	* sign.c: Include <errno.h> and "gpgme.h", but not <stdio.h>,
+	<assert.h> and "util.h".
+	(SKIP_TOKEN_OR_RETURN): Remove macro.
+	(struct sign_result): Change to op_data_t type and rework it.
+	(release_sign_result): Rename to ...
+	(release_op_data): ... this and rewrite it.
+	(append_xml_info): Remove function.
+	(gpgme_op_sign_result): New function.
+	(parse_sig_created): New function.
+	(_gpgme_sign_status_handler): Change first argument to void *.
+	Rewrite the function to use the new result structure and functions.
+	(_gpgme_op_sign_init_result): New function.
+	(_gpgme_op_sign_start): Rename to ...
+	(sign_start): ... this.  Call _gpgme_op_sign_init_result.
+	(gpgme_op_sign_start): Use sign_start instead _gpgme_op_sign_start.
+	(gpgme_op_sign): Likewise.
+	* encrypt-sign.c (_gpgme_op_encrypt_sign_start): Call
+	_gpgme_op_sign_init_result.
+	
+	* delete.c: Include <errno.h> and "gpgme.h", but not "util.h" or
+	"key.h".
+	(enum delete_problem): Move into function delete_status_handler.
+	(delete_status_handler): Change first argument to void *.  Parse
+	delete problem with strtol instead atoi.  Return better error
+	values.
+	(_gpgme_op_delete_start): Rename to ...
+	(delete_start): ... this.  Rework error handling.
+	(gpgme_op_delete_start): Use delete_start instead
+	_gpgme_op_delete_start.
+	(gpgme_op_delete): Likewise.
+	* gpgme.h (GpgmeDataType): Removed.
+
+2003-04-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h: Change GPGME_IMPORT_PRIVATE to GPGME_IMPORT_SECRET.
+	* import.c (parse_import_res): Parse unchanged field.
+
+	* gpgme.h: New enum for GPGME_IMPORT_NEW, GPGME_IMPORT_UID,
+	GPGME_IMPORT_SIG, GPGME_IMPORT_SUBKEY, GPGME_IMPORT_PRIVATE.
+	(GpgmeError): GPGME_Unknown_Reason, GPGME_Not_Found,
+	GPGME_Ambiguous_Specification, GPGME_Wrong_Key_Usage,
+	GPGME_Key_Revoked, GPGME_Key_Expired, GPGME_No_CRL_Known,
+	GPGME_CRL_Too_Old, GPGME_Policy_Mismatch, GPGME_No_Secret_Key,
+	GPGME_Key_Not_Trusted, GPGME_Issuer_Missing, GPGME_Chain_Too_Long,
+	GPGME_Unsupported_Algorithm, GPGME_Sig_Expired,
+	GPGME_Bad_Signature, GPGME_No_Public_Key added as new error codes.
+	(struct _gpgme_import_status): New structure.
+	(GpgmeImporttqStatus): New type.
+	(struct _gpgme_op_import_result): New structure.
+	(GpgmeImportResult): New type.
+	(gpgme_op_import_result): New function.
+	* import.c: Include <errno.h> and "gpgme.h", but not "util.h".
+	(struct import_result): Change to type op_data_t.
+	(release_import_result): Rename to ...
+	(release_op_data): ... this.
+	(append_xml_impinfo): Function removed.
+	(gpgme_op_import_result): New function.
+	(parse_import): New function.
+	(parse_import_res): Likewise.
+	(import_status_handler): Change first argument to void *.  Rewrite
+	to use new functions.
+	(_gpgme_op_import_start): Rework error handling.
+
+	* edit.c: Do not include <assert.h>, "util.h", but "gpgme.h".
+	(edit_resut): Change to typedef for op_data_t.
+	(edit_status_handler): Change first argument to void *.
+	Rework error handling.
+	(command_handler): Rework error handling.
+	(_gpgme_op_edit_start): Rename to ...
+	(edit_start): ... this.  Rework error handling.
+	(gpgme_op_edit_start): Rewrite using edit_start.
+	(gpgme_op_edit): Likewise.
+
+	* ops.h (_gpgme_passphrase_start): Remove prototype.
+	* passphrase.c: Do not include <assert.h>, "util.h" or
+	"debug.h", but "gpgme.h".
+	(struct passphrase_result): Change to typedef for op_data_t.
+	(release_passphrase_result): Rename to release_op_data.
+	(_gpgme_passphrase_status_handler): Change first argument to void *.
+	Use new op_data_t type.
+	(_gpgme_passphrase_command_handler): Use new op_data_t type.
+	(_gpgme_passphrase_start): Remove function.
+	* decrypt.c (_gpgme_decrypt_start): Rewrite error handling.  Do
+	not call _gpgme_passphrase_start, but install command handler.
+	* encrypt.c (_gpgme_op_encrypt_start): Likewise.
+	* encrypt-sign.c (_gpgme_op_encrypt_sign_start): Likewise.
+	* sign.c (_gpgme_op_sign_start): Likewise.
+
+	* context.h (struct gpgme_context_s): Remove member initialized,
+	use_cms and help_data_1.  Add member protocol.  Make use_armor and
+	use_textmode bit flags.  Make keylist_mode, include_certs,
+	signers_len and signers_size unsigned.
+	* gpgme.c (gpgme_new): Initialize CTX->protocol.
+	(gpgme_set_protocol): Do not check CTX.  Use CTX->protocol.
+	(gpgme_get_protocol): Likewise.
+	(gpgme_release): Do not release CTX->help_data_1.
+	* op-support.c (_gpgme_op_reset): Use CTX->protocol.
+
+	* wait-private.c (_gpgme_wait_private_event_cb): Remove variable CTX.
+
+	* data.c: Do not include <assert.h>, but "gpgme.h".
+	(_gpgme_data_inbound_handler): Expand _gpgme_data_append, because
+	it will go.  Do not assert DH.
+	(_gpgme_data_outbound_handler): Do not assert DH.
+	
+	* export.c: Do not include <stdlib.h>, "debug.h" and "util.h", but
+	"gpgme.h".
+	(export_status_handler): Change type of first argument to void *.
+	(_gpgme_op_export_start): Rename to ...
+	(export_start): ... this.  Rework error handling.
+	(gpgme_op_export_start): Rewritten to use export_start instead
+	_gpgme_op_export_start.
+	(gpgme_op_export): Likewise.
+
+	* gpgme.h (GpgmeError): Add GPGME_Busy, GPGME_No_Request.
+	(GPGME_No_Recipients, GPGME_Invalid_Recipient,
+	GPGME_No_Passphrase): New macros.
+
+	* key.c (gpgme_key_get_string_attr): Fix validity attribute.
+
+2003-04-24  Marcus Brinkmann  <marcus@g10code.de>
+	
+	* gpgme.h (struct _gpgme_op_genkey_result): New structure.
+	(GpgmeGenKeyResult): New type.
+	(gpgme_op_genkey): Drop last argument.
+	(gpgme_op_genkey_result): New function.
+	* genkey.c: Do not include "util.h", but "gpgme.h".
+	(struct genkey_result): Replace with ...
+	(op_data_t): ... this new type.
+	(release_genkey_result): Replace with ...
+	(release_op_data): ... this new function.
+	(gpgme_op_genkey_result): New function.
+	(genkey_status_handler): Rewritten using new op_data_t type.
+	(get_key_parameter): New function.
+	(_gpgme_op_genkey_start): Renamed to
+	(genkey_start): ... this and rewritten.
+	(gpgme_op_genkey_start): Use genkey_start instead
+	_gpgme_op_genkey_start.
+	(gpgme_op_genkey): Rewritten.  Remove FPR argument.
+
+	* context.h (struct gpgme_context_s): Remove member verbosity.
+	* gpgme.c (gpgme_new): Do not set member verbosity.
+	* engine.h (_gpgme_engine_set_verbosity): Remove prototype.
+	* engine.c (_gpgme_engine_set_verbosity): Remove function.
+	* engine-backend.h (struct engine_ops): Remove set_verbosity.
+	* engine-gpgsm.c (_gpgme_engine_ops_gpgsm): Remove set_verbosity member.
+	* rungpg.c (_gpgme_engine_ops_gpg): Likewise.
+	(gpg_set_verbosity): Remove function.
+	* decrypt.c (_gpgme_decrypt_start): Don't call
+	_gpgme_engine_set_verbosity.
+	* delete.c (_gpgme_op_delete_start): Likewise.
+	* edit.c (_gpgme_op_edit_start): Likewise.
+	* encrypt.c (_gpgme_op_encrypt_start): Likewise.
+	* encrypt-sign.c (_gpgme_op_encrypt_sign_start): Likewise.
+	* export.c (_gpgme_op_export_start): Likewise.
+	* genkey.c (_gpgme_op_genkey_start): Likewise.
+	* import.c (_gpgme_op_import_start): Likewise.
+	* keylist.c (gpgme_op_keylist_start): Likewise.
+	(gpgme_op_keylist_ext_start): Likewise.
+	* sign.c (_gpgme_op_sign_start): Likewise.
+	* verify.c (_gpgme_op_verify_start): Likewise.
+
+	* Makefile.am (libgpgme_la_SOURCES): Add key-cache.c.
+	* key.c (key_cache_initialized, key_cache_size,
+	key_cache_max_chain_length, ): Removed.
+	(struct key_cache_item_s, key_cache_lock, key_cache,
+	key_cache_unused_items, hash_key, _gpgme_key_cache_add,
+	_gpgme_key_cache_get, gpgme_get_key): Moved to ...
+	* key-cache.c: ... here.  New file.
+	* key.h (_gpgme_key_cache_init): Remove prototypes.
+	(_gpgme_key_cache_add,_gpgme_key_cache_get): Move to ...
+	* ops.h: ... here.
+	* version.c: Do not include "key.h".
+	(do_subsystem_inits): Do not call _gpgme_key_cache_init.
+
+	* mkstatus: Strip trailing comma.
+	* gpgme.h (GpgmetqStatus): Pretty print.
+
+	* gpgme.h (GpgmeError): Rename GPGME_No_Passphrase to
+	GPGME_Bad_Passphrase.
+	* passphrase.c (_gpgme_passphrase_status_handler): Use
+	GPGME_Bad_Passphrase instead GPGME_No_Passphrase.
+
+	* gpgme.h (GpgmeError): Rename GPGME_No_Recipients to
+	GPGME_No_UserID and GPGME_Invalid_Recipient to
+	GPGME_Invalid_UserID.
+	* encrypt.c (_gpgme_encrypt_status_handler): Use GPGME_No_UserID
+	instead GPGME_No_Recipients and GPGME_Invalid_UserID instead
+	GPGME_Invalid_Recipient.
+	(_gpgme_op_encrypt_start): Likewise.
+
+	* gpgme.h (GpgmeError): Remove GPGME_Busy and GPGME_No_Request.
+	* wait-user.c (_gpgme_wait_user_event_cb): Don't clear CTX->pending.
+	* wait-private.c (_gpgme_wait_private_event_cb): Likewise.
+	* wait-global.c (gpgme_wait): Likewise.
+	* verify.c (_gpgme_op_verify_start): Likewise.
+	(gpgme_get_sig_status): Don't check pending flag.
+	(gpgme_get_sig_string_attr): Likewise.
+	(gpgme_get_sig_ulong_attr): Likewise.
+	(gpgme_get_sig_key): Likewise.
+	* op-support.c (_gpgme_op_reset): Likewise.
+	* trustlist.c (gpgme_op_trustlist_start): Don't clear pending flag.
+	(gpgme_op_trustlist_next): Don't check or clear pending flag.
+	(gpgme_op_trustlist_end): Likewise.
+	* sign.c (_gpgme_op_sign_start): Likewise.
+	* context.h (struct gpgme_context_s): Remove member PENDING.
+	* decrypt.c (_gpgme_decrypt_start): Likewise.
+	* delete.c (_gpgme_op_delete_start): Likewise.
+	* edit.c (_gpgme_op_edit_start): Likewise.
+	* encrypt.c (_gpgme_op_encrypt_start): Likewise.
+	* encrypt-sign.c (_gpgme_op_encrypt_sign_start): Likewise.
+	* export.c (_gpgme_op_export_start): Likewise.
+	* genkey.c (_gpgme_op_genkey_start): Likewise.
+	* import.c (_gpgme_op_import_start): Likewise.
+	* key.c (gpgme_get_key): Likewise.
+	* keylist.c (gpgme_op_keylist_start): Likewise.
+	(gpgme_op_keylist_ext_start): Likewise.
+	(gpgme_op_keylist_next): Likewise.
+	(gpgme_op_keylist_end): Likewise.
+	* data-compat.c (gpgme_error_to_errno): Don't convert EBUSY.
+
+2003-02-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h (GpgmePassphraseCb): Change type to return GpgmeError,
+	and add argument for returning the result string.
+	(gpgme_cancel): Remove prototype.
+	* gpgme.c (gpgme_cancel): Remove function.
+	* context.h (struct gpgme_context_s): Remove member cancel.
+	* passphrase.c (_gpgme_passphrase_command_handler): Call the
+	passphrase callback in the new way.
+
+2003-01-30  Marcus Brinkmann  <marcus@g10code.de>
+
+	* edit.c (_gpgme_edit_status_handler): Call the progress status
+	handler.
+
+2003-02-05  Marcus Brinkmann  <marcus@g10code.de>
+
+	* wait-user.c (_gpgme_wait_user_remove_io_cb): Move check for no
+	I/O handlers left to ...
+	(_gpgme_user_io_cb_handler): ... here.
+
+2003-02-04  Marcus Brinkmann  <marcus@g10code.de>
+
+	* trustlist.c (trustlist_colon_handler): Release ITEM if name
+	could not be allocated.
+	(gpgme_trust_item_release): Only release name if it is allocated.
+	Reported by Marc Mutz <Marc.Mutz@uni-bielefeld.de>.
+
+2003-02-04  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (read_status): If he status handler returns an error,
+	return it.
+	(status_handler): If read_status fails, just return the error.
+
+2003-02-01  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (start): Handle all errors, not only most of
+	them.
+	(xtoi_1, xtoi_2): Remove macro.
+	(status_handler): Replace use of xtoi_2 with _gpgme_hextobyte.
+
+2003-02-01  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (map_assuan_error): Replace
+	ASSUAN_Bad_Certificate_Path with ASSUAN_Bad_Certificate_Chain.
+	(gpgsm_new): Use assuan_pipe_connect instead assuan_pipe_connect2.
+
+	* util.h (DIMof): Remove macro.
+
+	* ops.h (_gpgme_op_event_cb, _gpgme_op_event_cb_user,
+	_gpgme_data_unread): Prototypes removed.
+
+2003-01-30  Marcus Brinkmann  <marcus@g10code.de>
+
+	* types.h: File removed.
+	* Makefile.am (libgpgme_la_SOURCES): Remove types.h.
+	* io.h (struct spawn_fd_item_s): Do not include "types.h".
+	* key.h: Likewise.
+	* context.h: Likewise.
+	* cengine-gpgsm.h: Likewise.
+	* engine.h: Include "gpgme.h" instead "types.h".  Add prototypes
+	for EngineStatusHandler, EngineColonLineHandler and
+	EngineCommandHandler.
+	(_gpgme_engine_set_status_handler): Change parameter type from
+	GpgmeStatusHandler to EngineStatusHandler.
+	(_gpgme_engine_set_command_handler): Change parameter type from
+	GpgmeCommandHandler to EngineCommandHandler.
+	(_gpgme_engine_set_colon_line_handler): Change parameter type from
+	GpgmeColonLineHandler to EngineColonLineHandler.
+	* engine-backend.h: Include "engine.h" instead "types.h".
+	(struct engine_ops): Change Gpgme*Handler parameters in members
+	set_command_handler, set_colon_line_handler and set_status_handler
+	to Engine*Handler.
+	* engine.c (_gpgme_engine_set_status_handler): Change parameter
+	type from GpgmeStatusHandler to EngineStatusHandler.
+	(_gpgme_engine_set_command_handler): Change parameter type from
+	GpgmeCommandHandler to EngineCommandHandler.
+	(_gpgme_engine_set_colon_line_handler): Change parameter type from
+	GpgmeColonLineHandler to EngineColonLineHandler.
+	* rungpg.c (struct gpg_object_s): Change type of member status.fnc
+	from GpgmeStatusHandler to EngineStatusHandler.  Change type of
+	member colon.fnc from GpgmeColonLineHandler to
+	EngineColonLineHandler.  Change type of member cmd.fnc from
+	GpgmeCommandHandler to EngineCommandHandler.
+	* engine-gpgsm.c (struct gpgsm_object_s): Likewise.
+	* rungpg.c (gpg_set_status_handler): Change parameter type from
+	GpgmeStatusHandler to EngineStatusHandler.
+	* engine-gpgsm.c (gpgsm_set_status_handler): Likewise.
+	(assuan_simple_command): Likewise.
+	* rungpg.c (gpg_set_colon_line_handler): Change parameter type
+	from GpgmeColonLineHandler to EngineColonLineHandler.
+	* engine-gpgsm.c (gpgsm_set_colon_line_handler): Likewise.
+	* rungpg.c (gpg_set_command_handler): Change parameter type from
+	GpgmeCommandHandler to EngineCommandHandler.
+
+	* engine-gpgsm.c (status_handler): Do not close status fd at end
+	of function.
+
+	* ops.h (_gpgme_op_data_lookup): Add prototype.
+	* op-support.c: Include <stdlib.h>.
+	(_gpgme_op_data_lookup): New function.
+	* decrypt.c (_gpgme_release_decrypt_result): Function removed.
+	(struct decrypt_result_s): Rename to ...
+	(struct decrypt_resul): ... this.
+	(DecryptResult): New type.
+	(_gpgme_decrypt_status_handler): Don't use
+	test_and_allocate_result, but use _gpgme_op_data_lookup to
+	retrieve result data object.
+	* sign.c (_gpgme_release_sign_result): Function removed.
+	(release_sign_result): New function.
+	(struct sign_result_s): Rename to ...
+	(struct sign_result): ... this.
+	(SignResult): New type.
+	(_gpgme_sign_status_handler): Don't use
+	test_and_allocate_result, but use _gpgme_op_data_lookup to
+	retrieve result data object.
+	* encrypt.c (struct encrypt_result_s): Rename to ...
+	(struct encrypt_result): ... this.
+	(_gpgme_release_encrypt_result): Function removed.
+	(release_encrypt_result): New function.
+	(_gpgme_encrypt_status_handler): Don't use
+	test_and_allocate_result, but use _gpgme_op_data_lookup to
+	retrieve result data object.
+	* verify.c (struct verify_result_s): Rename to ...
+	(struct verify_result): ... this.  Remove member next.
+	(VerifyResult): New type.
+	(_gpgme_release_verify_result): Function removed.
+	(release_verify_result): New function.
+	(finish_sig): Change first argument to type VerifyResult.  Diddle
+	the type of the op_data structure.
+	(add_notation): Change first argument to type VerifyResult.
+	(_gpgme_verify_status_handler): Don't use
+	test_and_allocate_result, but use _gpgme_op_data_lookup to
+	retrieve result data object.
+	* passphrase.c (struct passphrase_result_s): Rename to ...
+	(struct passphrase_result): ... this.  Remove member next.
+	(PassphraseResult): New type.
+	(_gpgme_release_passphrase_result): Function removed.
+	(release_passphrase_result): New function.
+	(_gpgme_passphrase_status_handler): Don't use
+	test_and_allocate_result, but use _gpgme_op_data_lookup to
+	retrieve result data object.
+	(_gpgme_passphrase_command_handler): Likewise.
+	* keylist.c (struct keylist_result_s): Rename to ...
+	(struct keylist_result): ... this.  Remove member next.
+	(KeylistResult): New type.
+	(_gpgme_release_keylist_result): Function removed.
+	(release_keylist_result): New function.
+	(keylist_status_handler): Don't use
+	test_and_allocate_result, but use _gpgme_op_data_lookup to
+	retrieve result data object.
+	* edit.c (struct edit_result_s): Rename to ...
+	(struct edit_result): ... this.  Remove member next.
+	(EditResult): New type.
+	(_gpgme_release_edit_result): Function removed.
+	(release_edit_result): New function.
+	(edit_status_handler): Don't use
+	test_and_allocate_result, but use _gpgme_op_data_lookup to
+	retrieve result data object.
+	(command_handler): Likewise.
+	* types.h (DecryptResult, SignResult, EncryptResult,
+	PassphraseResult, ImportResult, DeleteResult, GenKeyResult,
+	KeylistResult, EditResult): Types removed.
+	* ops.h: Don't include "types.h", but "gpgme.h" and "context.h".
+	(test_and_allocate_result): Remove macro.
+	(_gpgme_release_decrypt_result): Remove prototype.
+	(_gpgme_decrypt_result): Remove prototype.
+	(_gpgme_release_sign_result): Remove prototype.
+	(_gpgme_release_encrypt_result): Remove prototype.
+	(_gpgme_release_passphrase_result): Remove prototype.
+	(_gpgme_release_import_result): Remove prototype.
+	(_gpgme_release_delete_result): Remove prototype.
+	(_gpgme_release_genkey_result): Remove prototype.
+	(_gpgme_release_keylist_result): Remove prototype.
+	(_gpgme_release_edit_result): Remove prototype.
+	(_gpgme_release_verify_result): Remove prototype.
+	* gpgme.c (_gpgme_release_result): Rewritten.
+	* context.h (enum ctx_op_data_type): New enum.
+	(struct ctx_op_data): New structure.
+	(struct gpgme_context_s): Replace the member result with a member
+	op_data.
+	(fail_on_pending_request): Remove macro.
+	* op-support.c (_gpgme_op_reset): Expand macro
+	fail_on_pending_request.
+	* util.h: Don't include "types.h" or "debug.h", but include "gpgme.h".
+
+2003-01-30  Marcus Brinkmann  <marcus@g10code.de>
+
+	* types.h (EngineObject): Move typedef to ...
+	* engine.h: ... here.
+	* types.h (GpgObject): Move typedef to ...
+	* rungpg.c: ... here.
+	* types.h (GpgsmObject): Move typedef to ...
+	* engine-gpgsm.c: ... here.
+
+	* util.h (return_if_fail, return_null_if_fail,
+	return_val_if_fail): Remove macro.
+	* gpgme.c (gpgme_cancel): Don't use return_if_fail.
+	* key.c (gpgme_key_ref): Likewise.
+	* signers.c (gpgme_signers_enum): Likewise.
+	(gpgme_signers_clear): Likewise.
+
+	* engine-backend.h (struct engine_ops): Rename get_path to
+	get_file_name.
+	* gpgme.h (struct _gpgme_engine_info): Rename member path to
+	file_name.
+	* version.c: Do not include <stdio.h>, <stdlib.h>, context.h and
+	util.h.  Other clean ups.
+	(parse_version_number): Protect more seriously against
+	overflow.
+	(gpgme_get_engine_info): Move to ...
+	* engine.c (gpgme_get_engine_info): ... here.
+	(_gpgme_engine_get_info): Function removed.
+	(_gpgme_engine_get_path): Make static and rename to ...
+	(engine_get_file_name): .. this.
+	(_gpgme_engine_get_version): Make static and rename to ...
+	(engine_get_version): ... this.
+	(_gpgme_engine_get_req_version): Make static and rename to ...
+	(engine_get_req_version): ... this.
+	* engine.h (_gpgme_engine_get_path, _gpgme_engine_get_version,
+	_gpgme_engine_req_version, _gpgme_engine_get_info.): Remove
+	prototypes.
+
+	* gpgme.h (enum GpgmeProtocol): Remove GPGME_PROTOCOL_AUTO.
+	* gpgme.c (gpgme_set_protocol): Don't handle GPGME_PROTOCOL_AUTO.
+	(gpgme_get_protocol_name): New function.
+
+	* engine-backend.h (struct engine_ops): New member
+	get_req_version, remove member check_version.
+	* engine.h (_gpgme_Engine_get_version): New prototype.
+	* rungpg.c (gpg_get_req_version): New function.
+	(gpg_check_version): Function removed.
+	(_gpgme_engine_ops_gpg): Add gpg_get_req_version, remove
+	gpg_check_version.
+	* engine-gpgsm.c (gpgsm_get_req_version): New function.
+	(gpgsm_check_version): Function removed.
+	(_gpgme_engine_ops_gpgsm): Add gpgsm_get_req_version, remove
+	gpgsm_check_version.
+	* engine.c: Include ops.h.
+	 (_gpgme_engine_get_req_version): New function.
+	(gpgme_engine_check_version): Rewritten.
+	* version.c (gpgme_get_engine_info): Rewritten.
+	* gpgme.h (gpgme_engine_info): New structure.
+	(GpgmeEngineInfo): New type.
+	
+2003-01-29  Marcus Brinkmann  <marcus@g10code.de>
+
+	* types.h: Remove byte and ulong types.
+	* util.h (_gpgme_hextobyte): Change prototype to unsigned char
+	instead byte.
+	* conversion.c (_gpgme_hextobyte): Change argument to unsigned
+	char instead byte.
+	(_gpgme_decode_c_string): Likewise, and beautify.  Also support a
+	few more escaped characters.  Be more strict about buffer size.
+	(_gpgme_data_append_percentstring_for_xml): Change type of SRC,
+	BUF and DST to unsigned char instead byte.
+	* progress.c (_gpgme_progress_status_handler): Use unsigned char
+	instead byte.
+	* debug.c (trim_spaces): Likewise.
+
+	* util.h (mk_error): Remove macro.
+	* conversion.c, data.c, data-compat.c, decrypt.c, delete.c,
+	edit.c, encrypt.c, encrypt-sign.c, engine.c, engine-gpgsm.c,
+	export.c, genkey.c, gpgme.c, import.c, key.c, keylist.c,
+	passphrase.c, progress.c, recipient.c, rungpg.c, sign.c,
+	signers.c, trustlist.c, verify.c, wait.c, wait-global.c,
+	wait-private (literally everywhere): Expand the mk_error macro.
+
+	* context.h (wait_on_request_or_fail): Remove macro.
+
+	* context.h (gpgme_context_s): Remove member ERROR.
+	* types.h (GpgmeStatusHandler): Change return type to GpgmeError.
+	(GpgmeCommandHandler): Change return type to GpgmeError and add
+	new argument RESULT.
+	* gpgme.h (GpgmeIOCb): Change return type to GpgmeError.
+	(GpgmeEventIO): New event GPGME_EVENT_START.
+	(GpgmeIdleFunc): Remove type.
+	(gpgme_register_idle): Remove prototype.
+	* data.c: Include <assert.h>.
+	(_gpgme_data_inbound_handler): Change return type to GpgmeError.
+	Return any error instead ignoring it, don't close file descriptor
+	on error.
+	(_gpgme_data_outbound_handler): Likewise.
+	* decrypt.c: Do not include <stdio.h>, <string.h> and <assert.h>.
+	(_gpgme_decrypt_status_handler): Change return type to GpgmeError.
+	Return error instead setting ctx->error.  Return success at end of
+	function.
+	(gpgme_op_decrypt): Don't work around the old kludge anymore.
+	* decrypt-verify.c (decrypt_verify_status_handler): Change return
+	type to GpgmeError.  Return possible errors.
+	* delete.c: Do not include <stdio.h>, <string.h>, <time.h> and
+	<assert.h>.
+	(delete_status_handler): Change return type to GpgmeError.  Return
+	error instead setting ctx->error.  Return success at end of
+	function.
+	* edit.c: Do not include <stdio.h> and <string.h>.
+	(_gpgme_edit_status_handler): Change type to GpgmeError,
+	make static and rename to ...
+	(edit_status_handler): ... this.  Return error directly.
+	(command_handler): Change return type to GpgmeError, add result
+	argument.  Return error directly.
+	* encrypt.c (status_handler_finish): Remove function.
+	(_gpgme_encrypt_status_handler): Change return type to GpgmeError.
+	Return error directly.
+	(_gpgme_encrypt_sym_status_handler): Likewise.
+	* encrypt-sign.c (encrypt_sign_status_handler): Likewise.
+	* engine-gpgsm.c (close_notify_handler): Do not signal done event
+	anymore.
+	(status_handler): Change return type to GpgmeError.  Diddle things
+	around a bit to return errors directly.
+	(start): Send start event.
+	* export.c: Do not include <stdio.h>, <string.h> and <assert.h>.
+	(export_status_handler): Change return type to GpgmeError.  Don't
+	check ctx->error.
+	* genkey.c: Do not include <stdio.h> and <assert.h>.
+	(genkey_status_handler): Change return type to GpgmeError.  Don't
+	check ctx->error.  Return errors directly.
+	* gpgme.c (_gpgme_release_result): Do not initialize ctx->error.
+	(_gpgme_op_event_cb): Function removed.
+	(_gpgme_op_event_cb_user): Likewise.
+	* import.c: Do not include <stdio.h>, <string.h> and <assert.h>.
+	(import_status_handler): Change return type to GpgmeError.  Don't
+	check ctx->error.
+	* keylist.c (keylist_colon_handler, keylist_status_handler, finish_key):
+	Change return type to GpgmeError, return error directly.
+	* Makefile (libgpgme_la_SOURCES): Add wait-global.c,
+	wait-private.c and wait-user.c
+	* ops.h (test_and_allocate_result): Return error instead setting
+	ctx->error.
+	(_gpgme_data_inbound_handler, _gpgme_data_outbound_handler,
+	_gpgme_verify_status_handler, _gpgme_decrypt_status_handler,
+	_gpgme_sign_status_handler, _gpgme_encrypt_staus_handler,
+	_gpgme_passphrase_status_handler, _gpgme_progress_status_handler):
+	Change return type to GpgmeError.
+	(_gpgme_passphease_command_handler): Change return type to
+	GpgmeError and add new argument RESULT.
+	* op-support.c: Use new callback functions, and change private
+	data to ctx everywhere.
+	* passphrase.c (_gpgme_passphrase_status_handler): Change return
+	type to GpgmeError, return error directly.
+	(_gpgme_passphrase_command_handler): Change return type to
+	GpgmeError, add result argument.  Return results accordingly.
+	* progress.c (_gpgme_progress_status_handler): Change return type
+	to GpgmeError, return errors directly.
+	* rungpg.c (status_handler): Change return type to GpgmeError.
+	Return error directly.
+	(close_notify_handler): Don't send done event.
+	(colon_line_handler): Change return type to GpgmeError, return
+	errors directly.
+	* rungpg.c (start): Send start event.
+	* sign.c (_gpgme_sign_status_handler): Change return type to
+	GpgmeError, return errors directly.
+	* trustlist.c (trustlist_status_handler): Change return type to
+	GpgmeError.  Return 0.
+	(trustlist_colon_handler): Change return type GpgmeError.  Return
+	errors directly.
+	* verify.c (add_notation): Change return type to GpgmeError,
+	return errors directly.
+	(_gpgme_verify_status_handler): Likewise.
+	* wait.h (struct fd_table): Remove lock member.
+	(struct wait_item_s): Moved here from wait.c.
+	(struct tag): New structure.
+	(_gpgme_wait_event_cb): Remove prototype.
+	(_gpgme_wait_private_event_cb, _gpgme_wait_global_event_cb,
+	_gpgme_wait_user_add_io_cb, _gpgme_wait_user_remove_io_cb,
+	_gpgme_wait_user_event_io_cb): New prototypes.
+	* wait.c: Don't include <stdio.h>.
+	(ftd_global, ctx_done_list, ctx_done_list_size,
+	ctx_done_list_length, ctx_done_list_lock, idle_function): Remove
+	global variable.
+	(gpgme_register_idle, do_select, _gpgme_wait_event_cb): Remove
+	function.
+	(gpgme_wait): Move to file wait-global.c.
+	(_gpgme_add_io_cb): Take ctx as private argument, initialize ctx
+	member in wait item and tag.
+	(_gpgme_remove_io_cb): Take ctx from tag.  Don't use FDT lock.
+	(_gpgme_wait_one, _gpgme_wait_on_condition): Move to
+	wait-private.c.
+	(gpgme_fd_table_init): Don't initialize FDT->lock.
+	(gpgme_fd_table_deinit): Don't destroy FDT->lock.
+	(_gpgme_fd_table_put): Make static and rename to ...
+	(fd_table_put): ... this function.  Don't use FDT->lock.
+	(struct wait_item_s): Move to wait.h.
+	* wait-global.c: New file.
+	* wait-private.c: New file.
+	* wait-user.c: New file.
+
+	* key.c (gpgme_key_sig_get_string_attr): Use validity_to_string
+	instead otrust_to_string to calculate validity.
+	
+2003-01-19  Miguel Coca  <mcoca@gnu.org>
+
+	* w32-io.c (_gpgme_io_select): Add missing argument in calls to
+	DEBUG_BEGIN.
+	* w32-util.c: Include "sema.h".
+	(find_program_in_registry): Change DEBUG1 to DEBUG2, fixes compilation
+	error.
+
+2003-01-19  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_engine_ops_gpg): Remove gpg_start.
+	(gpg_start): Rename to ...
+	(start): ... this function.  Change arguments to GpgObject.
+	(gpg_decrypt): Call start.
+	(gpg_edit): Likewise.
+	(gpg_encrypt): Likewise.
+	(gpg_encrypt_sign): Likewise.
+	(gpg_export): Likewise.
+	(gpg_import): Likewise.
+	(gpg_keylist): Likewise.
+	(gpg_keylist_ext): Likewise.
+	(gpg_trustlist): Likewise.
+	(gpg_verify): Likewise.
+
+	* engine-gpgsm.c (_gpgme_engine_ops_encrypt): Remove gpgsm_start.
+	(gpgsm_start): Rename to ...
+	(struct gpgsm_object_s): Remove member command.
+	(gpgsm_release): Don't free command.
+	(start): ... this function.  Change arguments to GpgsmObject and
+	const char *.
+	(gpgsm_decrypt): Call start.
+	(gpgsm_delete): Likewise.
+	(gpgsm_encrypt): Likewise.
+	(gpgsm_export): Likewise.
+	(gpgsm_genkey): Likewise.
+	(gpgsm_import): Likewise.
+	(gpgsm_keylist): Likewise.
+	(gpgsm_keylist_ext): Likewise.
+	(gpgsm_verify): Likewise.
+
+	* decrypt.c (_gpgme_decrypt_start): Don't call
+	_gpgme_engine_start.
+	* delete.c (_gpgme_op_delete_start): Likewise.
+	* edit.c (_gpgme_op_edit_start): Likewise.
+	* encrypt.c (_gpgme_op_encrypt_start): 
+	* encrypt-sign.c (_gpgme_op_encrypt_sign_start): 
+	* export.c (_gpgme_op_export_start): Likewise.
+	* genkey.c (_gpgme_op_genkey_start): Likewise.
+	* import.c (_gpgme_op_import_start): Likewise.
+	* keylist.c (gpgme_op_keylist_ext_start): Likewise.
+	(gpgme_op_keylist_start): Likewise.
+	* sign.c (_gpgme_op_sign_start): Likewise.
+	* trustlist.c (gpgme_op_trustlist_start): Likewise.
+	* verify.c (_gpgme_op_verify_start): Likewise.
+
+	* engine-backend.h (struct engine_ops): Remove member start.
+
+	* engine.h (_gpgme_engine_start): Remove prototype.
+	* engine.c (_gpgme_engine_start): Remove function.
+
+2003-01-06  Werner Koch  <wk@gnupg.org>
+
+	* keylist.c (set_mainkey_capability): Handle 'd' and 'D' used
+	since gpg 1.3 to denote disabled keys.
+
+2003-01-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* data-mem.c: Include <string.h>.
+	* engine.c: Likewise.
+
+2003-01-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (libgpgme_la_DEPENDENCIES): Correct bug in last change.
+
+2002-12-24  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h (gpgme_op_verify, gpgme_op_decrypt_verify): Drop R_STAT
+	argument.
+	* decrypt-verify.c (gpgme_op_decrypt_verify): Drop R_STAT
+	argument.
+	* verify.c (gpgme_op_verify): Drop R_STAT argument.
+	(_gpgme_intersect_stati): Function removed.
+	* ops.h (_gpgme_intersect_stati): Remove prototype.
+
+2002-12-24  Marcus Brinkmann  <marcus@g10code.de>
+
+	* libgpgme.vers: New file.
+	* Makefile.am (EXTRA_DIST): Add libgpgme.vers.
+	(libgpgme_version_script_cmd): New variable.
+	(libgpgme_la_LDFLAGS): Add libgpgme_version_script_cmd here.
+	(libgpgme_la_DEPENDENCIES): New variable.
+
+2002-12-23  Marcus Brinkmann  <marcus@g10code.de>
+
+	* key.c (gpgme_key_get_string_attr): Don't accept GPGME_ATTR_IS_SECRET.
+	(otrust_to_string): New function.
+	(gpgme_key_get_as_xml): Use it.
+	(validity_to_string): New function.
+	(gpgme_key_get_string_attr): Beautify using above functions.
+	(gpgme_key_get_ulong_attr): Likewise.
+
+2002-12-23  Marcus Brinkmann  <marcus@g10code.de>
+
+	* data-mem.c (mem_release): Fix gcc warning.
+	* data-user.c (user_release): Likewise.
+
+2002-12-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* data.h (gpgme_data_release_cb): Change return type to void.
+	(gpgme_data_read_cb): Change return type to ssize_t.
+	* data.c (gpgme_data_read): Likewise.
+	* data-stream.c (stream_read): Likewise.
+	* data-fd.c (fd_read): Likewise.
+	* data-mem.c (mem_read): Likewise.
+	(mem_release): Change return type to void.
+	* data-user.c (user_read): Change return type to ssize_t.
+	(user_release): Change return type to void.
+	* data-compat.c (old_user_read): Change return type to ssize_t.	
+	* gpgme.h (GpgmeDataReadCb): Likewise.
+	(gpgme_data_read): Likewise.
+	(GpgmeDataSeekCb): Change return type to off_t.
+
+2002-12-04  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h: Add prototype for gpgme_get_key.
+	* key.c (gpgme_get_key): New function.
+	* verify.c (gpgme_get_sig_key): Rewrite using gpgme_get_key.
+
+	* gpgme.h: Add prototypes for new interfaces
+	gpgme_key_sig_get_string_attr and gpgme_key_get_ulong_attr.
+	(enum GpgmeAttr): New attribute GPGME_ATTR_SIG_CLASS.
+	* gpgme.c (gpgme_set_keylist_mode): Allow GPGME_KEYLIST_MODE_SIGS.
+	* key.h (struct certsig_s): New members ALGO, NAME_PART,
+	EMAIL_PART, COMMENT_PART, NAME, SIG_STAT and SIG_CLASS.
+
+	* conversion.c (_gpgme_decode_c_string): Add new parameter LEN.
+	Use that to determine if allocation is desired or not.
+	* util.h: Adjust prototype of _gpgme_decode_c_string.
+	* keylist.c (keylist_colon_handler): Adjust caller of
+	_gpgme_decode_c_string.
+
+	* key.h (struct gpgme_key_s): New member last_uid.
+	* key.c (_gpgme_key_append_name): Rewritten using
+	_gpgme_decode_c_string and the last_uid pointer.
+	(my_isdigit): Macro removed.
+	(ALLOC_CHUNK): Likewise.
+	* keylist.c (set_userid_flags): Use last_uid member of KEY.
+
+	* context.h (struct user_id_s): New member last_certsig.
+	* key.h: Add prototype for _gpgme_key_add_certsig.
+	* key.c (_gpgme_key_add_certsig): New function.
+	(set_user_id_part): Move function before _gpgme_key_add_certsig.
+	(parse_user_id): Change first argument to SRC, add new arguments
+	NAME, EMAIL and COMMENT.  Change code to use these arguments
+	instead going through UID.  Move function before
+	_gpgme_add_certsig.
+	(parse_x509_user_id): Likewise.
+	(_gpgme_key_append_name): Adjust arguments to parse_x509_user_id
+	and parse_user_id invocation.
+	(one_certsig_as_xml): New function.
+	(one_uid_as_xml): Print signatures.
+	* context.h (struct gpgme_context_s): New member TMP_UID.
+	* keylist.c (keylist_colon_handler): Rewritten, implement "sig"
+	record entries.
+
+	* key.c (get_certsig): New function.
+	(gpgme_key_sig_get_string_attr): Likewise.
+	(gpgme_key_sig_get_ulong_attr): Likewise.
+
+	* keylist.c: Include <ctype.h>.
+	(my_isdigit): Macro removed.
+	(set_mainkey_trust_info): Use isdigit, not my_isdigit.
+	(set_userid_flags): Likewise.
+	(set_subkey_trust_info): Likewise.
+	(set_ownertrust): Likewise.
+	(finish_key): Move function up a bit and remove prototype.
+
+	* rungpg.c (gpg_keylist_ext): Correct precedence of signature
+	listing mode.
+	(gpg_keylist_ext): Implement signature listing mode.
+
+2002-11-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_spawn): Do not set parent fds to -1.
+	* posix-io.c (_gpgme_io_spawn): Call _gpgme_io_close instead close
+	for parent fds.
+	* w32-io.c (_gpgme_io_spawn): Call _gpgme_io_close instead
+	CloseHandle for parent fds.
+
+2002-11-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h [_MSC_VER]: Define ssize_t as long.
+
+2002-11-22  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_new): Save the result of a first
+	setlocale before doing another setlocale.
+
+2002-11-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* decrypt.c: Some beautyfication.
+
+	* verify.c (_gpgme_verify_status_handler): Treat
+	GPGME_STATUS_UNEXPECTED like GPGME_STATUS_NODATA.
+	Reported by Miguel Coca <e970095@zipi.fi.upm.es>.
+
+2002-11-19  Marcus Brinkmann  <marcus@g10code.de>
+
+	* genkey.c: Only include <config.h> if [HAVE_CONFIG_H].
+	(struct genkey_result_s): Add new member FPR.
+	(_gpgme_release_genkey_result): Free RESULT->fpr if set.
+	(genkey_status_handler): Extract the fingerprint from the status
+	line.
+	(gpgme_op_genkey): Add new argument FPR and return the fingerprint
+	in it.
+	* gpgme.h: Adjust prototype of gpgme_op_genkey.
+
+2002-11-19  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (gpg_keylist): Add --with-fingerprint to gpg invocation
+	twice, to get fingerprints on subkeys.  Suggested by Timo Schulz
+	<twoaday@freakmail.de>.
+	(gpg_keylist_ext): Likewise.
+
+2002-11-05  Marcus Brinkmann  <marcus@g10code.de>
+
+	* import.c (append_xml_impinfo): Use
+	_gpgme_data_append_string_for_xml rather than
+	_gpgme_data_append_string for the field content.
+	Submitted by Miguel Coca <e970095@zipi.fi.upm.es>.
+	
+2002-10-10  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.h, engine-gpgsm.h: File removed.
+	* engine-backend.h: New file.
+	* Makefile.am (gpgsm_components): New variable, set depending on
+	automake conditional HAVE_GPGSM.
+	(libgpgme_la_SOURCES): Add engine-backend.h, remove rungpg.h and
+	engine-gpgsm.h.  Replace engine-gpgsm.c with ${gpgsm_components}.
+	(status-table.h): Depend on gpgme.h, not rungpg.h.
+	* conversion.c: Include <stdlib.h>.
+	* engine-gpgsm.c: Do not set ENABLE_GPGSM here.  Include
+	"engine-backend.h" instead "engine-gpgsm.h".  Reorder some
+	functions and remove all function prototypes.
+	(_gpgme_gpgsm_get_version): Make static and rename to ...
+	(gpgsm_get_version): ... this.
+	(_gpgme_gpgsm_check_version): Make static and rename to ...
+	(gpgsm_check_version): ... this.
+	(_gpgme_gpgsm_new): Make static.  Change argument type from
+	GpgsmObject * to void **.  Call gpgsm_release instead
+	_gpgme_gpgsm_release.
+	(_gpgme_gpgsm_op_decrypt): Make static and rename to ...
+	(gpgsm_check_decrypt): ... this.
+	(_gpgme_gpgsm_op_delete): Make static and rename to ...
+	(gpgsm_check_delete): ... this.
+	(_gpgme_gpgsm_set_recipients): Make static and rename to ...
+	(gpgsm_check_set_recipients): ... this.
+	(_gpgme_gpgsm_op_encrypt): Make static and rename to ...
+	(gpgsm_encrypt): ... this.
+	(_gpgme_gpgsm_op_export): Make static and rename to ...
+	(gpgsm_export): ... this.
+	(_gpgme_gpgsm_op_genkey): Make static and rename to ...
+	(gpgsm_genkey): ... this.
+	(_gpgme_gpgsm_op_import): Make static and rename to ...
+	(gpgsm_import): ... this.
+	(_gpgme_gpgsm_op_keylist): Make static and rename to ...
+	(gpgsm_keylist): ... this.
+	(_gpgme_gpgsm_op_keylist_ext): Make static and rename to ...
+	(gpgsm_keylist_ext): ... this.
+	(_gpgme_gpgsm_op_sign): Make static and rename to ...
+	(gpgsm_sign): ... this.
+	(_gpgme_gpgsm_op_trustlist): Make static and rename to ...
+	(gpgsm_trustlist): ... this.
+	(_gpgme_gpgsm_op_verify): Make static and rename to ...
+	(gpgsm_verify): ... this.
+	(gpgsm_status_handler): Rename to ...
+	(status_handler): ... this.
+	(_gpgme_gpgsm_set_status_handler): Make static and rename to ...
+	(gpgsm_set_status_handler): ... this.
+	(_gpgme_gpgsm_set_colon_line_handler): Make static and rename to ...
+	(gpgsm_set_colon_line_handler): ... this.
+	(_gpgme_gpgsm_add_io_cb): Rename to ...
+	(add_io_cb): ... this.
+	(_gpgme_gpgsm_start): Make static and rename to ...
+	(gpgsm_start): ... this.
+	(_gpgme_gpgsm_set_io_cb): Make static and rename to ...
+	(gpgsm_set_io_cb): ... this.
+	(_gpgme_gpgsm_io_event): Make static and rename to ...
+	(gpgsm_io_event): ... this.
+	(struct _gpgme_engine_ops_gpgsm): New variable.
+	[!ENABLE_GPGSM]: Removed.
+	* engine.c: Do not include <time.h>, <sys/types.h>, <string.h>,
+	<assert.h>, "io.h", "rungpg.h" and "engine-gpgsm.h".  Include
+	<stdlib.h> and "engine-backend.h".
+	(struct engine_object_s): Rewritten.
+	(engine_ops): New variable.
+	* engine.c (_gpgme_engine_get_path, _gpgme_engine_get_version,
+	_gpgme_engine_check_version, _gpgme_engine_new,
+	_gpgme_engine_release, _gpgme_engine_set_verbosity,
+	_gpgme_engine_set_status_handler,
+	_gpgme_engine_set_command_handler,
+	_gpgme_engine_set_colon_line_handler, _gpgme_engine_op_decrypt,
+	_gpgme_engine_op_delete, _gpgme_engine_op_edit,
+	_gpgme_engine_op_encrypt, _gpgme_engine_op_encrypt_sign,
+	_gpgme_engine_op_export, _gpgme_engine_op_genkey,
+	_gpgme_engine_op_import, _gpgme_engine_op_keylist,
+	_gpgme_engine_op_keylist_ext, _gpgme_engine_op_sign,
+	_gpgme_engine_op_trustlist, _gpgme_engine_op_verify,
+	_gpgme_engine_start, _gpgme_engine_set_io_cbs,
+	_gpgme_engine_io_event): Reimplement.
+	* engine.h: Fix a few comments and a variable name in a prototype.
+	* ops.h: Do not include "rungpg.h".
+	* passphrase.c: Include config.h only if [HAVE_CONFIG_H].  Do not
+	include "rungpg.h".
+	* recipient.c: Likewise.
+	* signers.c: Likewise.
+	* version.c: Likewise.
+	* rungpg.c: Likewise.  Include "engine-backend.h".  Reorder
+	functions and remove prototypes.
+	(_gpgme_gpg_get_version): Make static and rename to ...
+	(gpg_get_version): ... this.
+	(_gpgme_gpg_check_version): Make static and rename to ...
+	(gpg_check_version): ... this.
+	(_gpgme_gpg_new): Make static.  Change argument type from
+	GpgObject * to void **.  Call gpg_release instead
+	_gpgme_gpg_release.
+	(_gpgme_gpg_op_decrypt): Make static and rename to ...
+	(gpg_check_decrypt): ... this.
+	(_gpgme_gpg_op_delete): Make static and rename to ...
+	(gpg_check_delete): ... this.
+	(_gpgme_gpg_set_recipients): Make static and rename to ...
+	(gpg_check_set_recipients): ... this.
+	(_gpgme_gpg_op_encrypt): Make static and rename to ...
+	(gpg_encrypt): ... this.
+	(_gpgme_gpg_op_export): Make static and rename to ...
+	(gpg_export): ... this.
+	(_gpgme_gpg_op_genkey): Make static and rename to ...
+	(gpg_genkey): ... this.
+	(_gpgme_gpg_op_import): Make static and rename to ...
+	(gpg_import): ... this.
+	(_gpgme_gpg_op_keylist): Make static and rename to ...
+	(gpg_keylist): ... this.
+	(_gpgme_gpg_op_keylist_ext): Make static and rename to ...
+	(gpg_keylist_ext): ... this.
+	(_gpgme_gpg_op_sign): Make static and rename to ...
+	(gpg_sign): ... this.
+	(_gpgme_gpg_op_trustlist): Make static and rename to ...
+	(gpg_trustlist): ... this.
+	(_gpgme_gpg_op_verify): Make static and rename to ...
+	(gpg_verify): ... this.
+	(gpg_status_handler): Rename to ...
+	(status_handler): ... this.
+	(_gpgme_gpg_set_status_handler): Make static and rename to ...
+	(gpg_set_status_handler): ... this.
+	(_gpgme_gpg_set_colon_line_handler): Make static and rename to ...
+	(gpg_set_colon_line_handler): ... this.
+	(gpgme_gpg_add_io_cb): Rename to ...
+	(add_io_cb): ... this.
+	(_gpgme_gpg_start): Make static and rename to ...
+	(gpg_start): ... this.
+	(_gpgme_gpg_set_io_cb): Make static and rename to ...
+	(gpg_set_io_cb): ... this.
+	(_gpgme_gpg_io_event): Make static and rename to ...
+	(gpg_io_event): ... this.
+	(struct _gpgme_engine_ops_gpg): New variable.
+
+2002-10-10  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_verify) [!ENABLE_GPGSM]: Add
+	missing argument.
+
+2002-10-09  Marcus Brinkmann  <marcus@g10code.de>
+
+	* data.h, data-user.c, data-stream.c, data-mem.c, data-fd.c,
+	data-compat.c: New file.  Really check them in this time, completes
+	2002-10-08 change.
+
+	* rungpg.h (GpgStatusHandler): Rename type to GpgmeStatusHandler
+	and move to ...
+	* types.h (GpgmeStatusHandler): ... here.
+	* rungpg.h (GpgColonLineHandler): Rename type to GpgmeColonLineHandler.
+	and move to ...
+	* types.h (GpgmeColonLineHandler): ... here.
+	* rungpg.h (GpgCommandHandler): Rename type to GpgmeCommandHandler.
+	and move to ...
+	* types.h (GpgmeCommandHandler): ... here.
+	* engine.h: Don't include "rungpg.h".
+	(_gpgme_engine_set_status_handler): Change type of
+	argument from GpgStatusHandler to GpgmeStatusHandler.
+	(_gpgme_engine_set_colon_line_handler): Change type of
+	argument from GpgColonLineHandler to GpgmeColonLineHandler.
+	(_gpgme_engine_set_command_handler): Change type of
+	argument from GpgCommandHandler to GpgmeCommandHandler.
+	* engine-gpgsm.h: Don't include "rungpg.h".
+	(_gpgme_gpgsm_set_status_handler): Change type of
+	argument from GpgStatusHandler to GpgmeStatusHandler.
+	(_gpgme_gpgsm_set_colon_line_handler): Change type of
+	argument from GpgColonLineHandler to GpgmeColonLineHandler.
+	* engine-gpgsm.c: Do not include "rungpg.h".
+	(struct gpgsm_object_s): Change type of
+	status.fnc to GpgmeStatusHandler.  Change type of colon.fnc to
+	GpgmeColonLineHandler.
+	(gpgsm_assuan_simple_command): Change type of argument from
+	GpgStatusHandler to GpgmeStatusHandler.
+	(_gpgme_gpgsm_set_status_handler): Likewise.
+	(_gpgme_gpgsm_set_colon_line_handler): Change type of argument from
+	GpgColonLineHandler to GpgmeColonLineHandler.
+	* rungpg.h (_gpgme_gpg_set_status_handler): Change type of
+	argument from GpgStatusHandler to GpgmeStatusHandler.
+	(_gpgme_gpg_set_colon_line_handler): Change type of
+	argument from GpgColonLineHandler to GpgmeColonLineHandler.
+	(_gpgme_gpg_set_command_handler): Change type of
+	argument from GpgCommandHandler to GpgmeCommandHandler.
+	* rungpg.c (struct gpg_object_s): Change type of status.fnc to
+	GpgmeStatusHandler.  Change type of colon.fnc to
+	GpgmeColonLineHandler.  Change type of cmd.fnc to
+	GpgmeCommandLineHandler.
+	(_gpgme_gpg_set_status_handler): Change type of argument FNC to
+	GpgmeStatusHandler.
+	(_gpgme_gpg_set_colon_line_handler): Change type of argument FNC
+	to GpgmeColonLineHandler.
+	(_gpgme_gpg_set_command_handler): Change type of argument FNC to
+	GpgmeCommandHandler.
+	* engine.c (_gpgme_engine_set_status_handler): Change type of
+	argument FNC to GpgmeStatusHandler.
+	(_gpgme_engine_set_colon_line_handler): Change type of argument FNC
+	to GpgmeColonLineHandler.
+	(_gpgme_engine_set_command_handler): Change type of argument FNC to
+	GpgmeCommandHandler.
+
+	* rungpg.h (_gpgme_gpg_enable_pipemode): Remove prototype.
+	* rungpg.c (struct gpg_object_s): Remove PM.
+	(pipemode_cb): Prototype removed.
+	(add_pm_data): Function removed.
+	(_gpgme_gpg_enable_pipemode): Likewise.
+	(pipemode_copy): Likewise.
+	(pipemode_cb): Likewise.
+	(add_arg): Don't check for pipemode.
+	(add_data): Likewise.
+	(_gpgme_gpg_set_status_handler): Likewise.
+	(_gpgme_gpg_set_colon_line_handler): Likewise.
+	(_gpgme_gpg_set_command_handler): Likewise.
+	(_gpgme_gpg_spawn): Likewise.
+	(_gpgme_gpg_spawn): Don't set PM.active.
+	(_gpgme_gpg_op_verify): Remove pipemode case.
+	* verify.c (_gpgme_op_verify_start): Remove pipemode case.
+
+	* rungpg.h (_gpgme_gpg_add_arg, _gpgme_gpg_add_data,
+	_gpgme_gpg_add_pm_data, _gpgme_gpg_housecleaning,
+	_gpgme_gpg_set_simple_line_handler): Prototype removed.
+	(_gpgme_gpg_set_verbosity): New prototype.
+	* rungpg.c (_gpgme_gpg_add_data): Make static and rename to ...
+	(add_data): ... this.
+	(_gpgme_gpg_add_pm_data): Call add_data, not _gpgme_gpg_add_data.
+	(_gpgme_gpg_set_command_handler): Likewise.
+	(_gpgme_gpg_op_decrypt, _gpgme_gpg_op_edit, _gpgme_gpg_op_encrypt,
+	_gpgme_gpg_op_encrypt_sign, _gpgme_gpg_op_export,
+	_gpgme_gpg_op_genkey, _gpgme_gpg_op_import, _gpgme_gpg_op_sign,
+	_gpgme_gpg_op_verify): Likewise.
+	(_gpgme_gpg_add_pm_data): Rename to ...
+	(add_pm_data): ... this.
+	(_gpgme_gpg_op_verify): Call add_pm_data, not
+	_gpgme_gpg_add_pm_data.
+	(_gpgme_gpg_add_arg): Make static and rename to ...
+	(add_arg): ... this.
+	(_gpgme_gpg_set_command_handler, _gpgme_gpg_new,
+	_gpgme_gpg_op_decrypt, _gpgme_gpg_op_delete,
+	_gpgme_append_gpg_args_from_signers, _gpgme_gpg_op_edit,
+	_gpgme_append_gpg_args_from_recipients, _gpgme_gpg_op_encrypt,
+	_gpgme_gpg_op_encrypt_sign, _gpgme_gpg_op_export,
+	_gpgme_gpg_op_genkey, _gpgme_gpg_op_import, _gpgme_gpg_op_keylist,
+	_gpgme_gpg_op_keylist_ext, _gpgme_gpg_op_trustlist,
+	_gpgme_gpg_op_sign, _gpgme_gpg_op_verify): Use add_arg, not
+	_gpgme_gpg_add_arg.
+	(_gpgme_gpg_set_verbosity): New function.
+	(struct gpg_object_s): Remove member simple from colon.
+	(_gpgme_gpg_set_colon_line_handler): Don't initialize simple.
+	(_gpgme_gpg_set_simple_line_handler): Removed function.
+	(read_colon_line): Don't check the GPG->colon.simple.
+	* engine.c (_gpgme_engine_set_verbosity): Call
+	_gpgme_gpg_set_verbosity instead _gpgme_gpg_add_arg.
+
+2002-10-08  Marcus Brinkmann  <marcus@g10code.de>
+
+	* util.h (_gpgme_malloc, _gpgme_realloc, _gpgme_calloc,
+	_gpgme_strdup, _gpgme_free): Remove prototypes.
+	(xtrymalloc, xtrycalloc, xtryrealloc, xtrystrdup, xfree): Remove
+	macros.
+	* util.c: File removed.
+	* Makefile.am (libgpgme_la_SOURCES): Remove util.h.
+	* conversion.c (_gpgme_decode_c_string): Use malloc instead of
+	xtrymalloc, realloc instead of xtryrealloc, calloc instead of
+	xtrycalloc, free instead of xfree.
+	(_gpgme_data_append_percentstring_for_xml): Likewise.
+	* data.c (_gpgme_data_new, _gpgme_data_release): Likewise.
+	* data-compat.c (gpgme_data_new_from_filepart): Likewise.
+	* data-mem.c (mem_write, mem_release, gpgme_data_new_from_mem,
+	_gpgme_data_get_as_string): Likewise.
+	* debug.c (debug_init): Likewise.
+	* decrypt.c (_gpgme_release_decrypt_result): Likewise.
+	* delete.c (_gpgme_release_delete_result): Likewise.
+	* edit.c (_gpgme_release_edit_result, _gpgme_op_edit_start):
+	Likewise.
+	* encrypt.c (_gpgme_release_encrypt_result): Likewise.
+	* engine.c (_gpgme_engine_get_info, _gpgme_engine_new,
+	_gpgme_engine_release): Likewise.
+	* engine-gpgsm.c (_gpgme_gpgsm_new, _gpgme_gpgsm_release,
+	_gpgme_gpgsm_op_decrypt, _gpgme_gpgsm_op_delete,
+	gpgsm_set_recipients, _gpgme_gpgsm_op_encrypt,
+	_gpgme_gpgsm_op_export, _gpgme_gpgsm_op_genkey,
+	_gpgme_gpgsm_op_import, _gpgme_gpgsm_op_keylist,
+	_gpgme_gpgsm_op_keylist_ext, _gpgme_gpgsm_op_sign,
+	_gpgme_gpgsm_op_verify, gpgsm_status_handler): Likewise.
+	* genkey.c (_gpgme_release_genkey_result): Likewise.
+	* gpgme.c (gpgme_new, gpgme_release): Likewise.
+	* import.c (_gpgme_release_import_result): Likewise.
+	* key.c (_gpgme_key_cache_init, _gpgme_key_cache_add, key_new,
+	add_subkey, gpgme_key_release, _gpgme_key_append_name): Likewise.
+	* keylist.c (_gpgme_release_keylist_result, keylist_colon_handler,
+	_gpgme_op_keylist_event_cb, gpgme_op_keylist_next): Likewise.
+	* ops.h (test_and_allocate_result): Likewise.
+	* passphrase.c (_gpgme_release_passphrase_result,
+	_gpgme_passphrase_status_handler,
+	_gpgme_passphrase_command_handler): Likewise.
+	* progress.c (_gpgme_progress_status_handler): Likewise.
+	* recipient.c (gpgme_recipients_new, gpgme_recipients_release,
+	gpgme_recipients_add_name_with_validity): Likewise.
+	* rungpg.c (_gpgme_gpg_new, _gpgme_gpg_release,
+	_gpgme_gpg_add_arg, _gpgme_gpg_add_data,
+	_gpgme_gpg_set_colon_line_handler, free_argv, free_fd_data_map,
+	build_argv, _gpgme_gpg_spawn, read_status, read_colon_line):
+	Likewise.
+	* sign.c (_gpgme_release_sign_result): Likewise.
+	* signers.c (_gpgme_signers_add): Likewise.
+	* trustlist.c (trust_item_new, trustlist_colon_handler,
+	_gpgme_op_trustlist_event_cb, gpgme_op_trustlist_next,
+	gpgme_trustitem_release): Likewise.
+	* verify.c (_gpgme_release_verify_result, finish_sig): Likewise.
+	* version.c (gpgme_get_engine_info, _gpgme_get_program_version):
+	Likewise.
+	* w32-io.c (create_reader, create_writer, destroy_reader,
+	destroy_writer, build_commandline, _gpgme_io_spawn): Likewise.
+	* w32-sema.c (critsect_init, _gpgme_sema_cs_destroy): Likewise.
+	* w32-util.c (read_w32_registry_string): Likewise.
+	* wait.c (_gpgme_fd_table_deinit, _gpgme_fd_table_put,
+	_gpgme_wait_event_cb, _gpgme_add_io_cb, _gpgme_remove_io_cb)
+	* data-compat.c: Include <stdlib.h>.
+
+2002-10-08  Marcus Brinkmann  <marcus@g10code.de>
+
+	New data object component:
+
+	* gpgme.h (GpgmeDataReadCb, GpgmeDataWriteCb, GpgmeDataSeekCb,
+	GpgmeDataReleaseCb): New types.
+	(struct GpgmeDataCbs): New structure.
+	(gpgme_data_read): Changed prototype to match that of read() closely.
+	(gpgme_data_write): Similar for write().
+	(gpgme_data_seek, gpgme_data_new_from_cbs, gpgme_data_new_from_fd,
+	gpgme_data_new_from_stream): New prototypes.
+	(gpgme_data_get_type, gpgme_check_engine): Prototype removed.
+
+	* Makefile.am (libgpgme_la_SOURCES): Add data.h, data-fd.c,
+	data-stream.c, data-mem.c, data-user.c and data-compat.c.
+	* data.c: Reimplemented from scratch.
+	* (data-compat.c, data-fd.c, data.h, data-mem.c, data-stream.c,
+	data-user.c): New file.
+	* context.h (struct gpgme_data_s): Removed.
+	* conversion.c: Include <errno.h> and <sys/types.h>.
+	(_gpgme_data_append): New function.
+	* data.c (_gpgme_data_append_string): Move to ...
+	* conversion.c (_gpgme_data_append_string): ... here.
+	* data.c (_gpgme_data_append_for_xml): Move to ...
+	* conversion.c (_gpgme_data_append_for_xml): ... here.
+	* data.c (_gpgme_data_append_string_for_xml): Move to ...
+	* conversion.c (_gpgme_data_append_string_for_xml): ... here.
+	* data.c (_gpgme_data_append_percentstring_for_xml): Move to ...
+	* conversion.c (_gpgme_data_append_percentstring_for_xml): ... here.
+
+	* ops.h (_gpgme_data_get_mode, _gpgme_data_set_mode): Prototype
+	removed.
+	* types.h (GpgmeDataMode): Type removed.
+
+	* decrypt.c (_gpgme_decrypt_start): Don't check data type or mode.
+	* edit.c (_gpgme_op_edit_start): Likewise.
+	* encrypt.c (_gpgme_op_encrypt_start): Likewise.
+	* encrypt-sign.c (_gpgme_op_encrypt_sign_start): Likewise.
+	* encrypt-sign.c (_gpgme_op_encrypt_sign_start): Likewise.
+	* export.c (_gpgme_op_export_start): Likewise.
+	* genkey.c (_gpgme_op_genkey_start): Likewise.
+	* import.c (_gpgme_op_import_start): Likewise.
+	* sign.c (_gpgme_op_sign_start): Likewise.
+	* verify.c (_gpgme_op_verify_start): Likewise.
+	
+	* encrypt.c (gpgme_op_encrypt): Remove hack that returns invalid
+	no recipient if no data was returned.
+	* encrypt-sign.c (gpgme_op_encrypt_sign): Remove hack that returns
+	no recipient if no data was returned.
+	* encrypt-sign.c (gpgme_op_encrypt_sign): Remove hack that returns
+	no recipient if no data was returned.
+
+	* engine.c (_gpgme_engine_op_verify): Add new argument to
+	differentiate detached from normal signatures.
+	* engine.h (_gpgme_engine_op_verify): Likewise for prototype.
+	* engine-gpgsm.c (_gpgme_gpgsm_op_verify): Likewise.  Don't check
+	mode of data argument.
+	* engine-gpgsm.h (_gpgme_gpgsm_op_verify): Likewise for prototype.
+	* gpgme.h (gpgme_op_verify_start): Likewise for prototype.
+	(gpgme_op_verify): Likewise for prototype.
+	* rungpg.c (_gpgme_gpg_op_verify): Likewise.
+	* rungpg.h (_gpgme_gpg_op_verify): Likewise for prototype.
+	* verify.c (_gpgme_op_verify_start): Likewise.
+	(gpgme_op_verify_start): Likewise.
+	(gpgme_op_verify): Likewise.
+
+	* rungpg.c (struct arg_and_data_s): New member INBOUND to hold
+	direction of data object.
+	(_gpgme_gpg_add_data): Add new argument INBOUND.  Use it to
+	determine direction of data object.
+	(_gpgme_gpg_add_pm_data, _gpgme_gpg_set_command_handler,
+	_gpgme_gpg_op_decrypt, _gpgme_gpg_op_edit, _gpgme_gpg_op_encrypt,
+	_gpgme_gpg_op_encrypt_sign, _gpgme_gpg_op_export,
+	_gpgme_gpg_op_genkey, _gpgme_gpg_op_import, _gpgme_gpg_op_sign,
+	_gpgme_gpg_op_verify): Add new argument to _gpgme_gpg_add_data
+	invocation.
+	(build_argv): Use new member INBOUND to determine direction of
+	file descriptor.  Don't check the data type.
+	* rungpg.h (_gpgme_gpg_add_data): Add new argument to prototype.
+	
+	* gpgme.c (gpgme_get_op_info): Don't call
+	_gpgme_data_get_as_string if CTX->op_info is NULL.
+
+	* version.c (gpgme_check_engine): Function removed.
+
+2002-09-30  Werner Koch  <wk@gnupg.org>
+
+	* keylist.c (keylist_colon_handler): Take care when printing a
+	NULL with the DEBUG.
+
+	* engine-gpgsm.c (struct gpgsm_object_s): New member ANY.
+	(gpgsm_status_handler): Run the colon function to indicate EOF.
+	(_gpgme_gpgsm_set_colon_line_handler): Better reset ANY here.
+
+2002-09-28  Marcus Brinkmann  <marcus@g10code.de>
+
+	* conversion.c (_gpgme_hextobyte): Prevent superfluous
+	multiplication with base.  Reported by St�phane Corth�sy.
+
+	* keylist.c (gpgme_op_keylist_ext_start): Use private asynchronous
+	operation type in invocation of _gpgme_op_reset.
+
+2002-09-20  Werner Koch  <wk@gnupg.org>
+
+	* ath.c: Include sys/time.h if sys/select.h is not available.
+
+2002-09-13  Marcus Brinkmann  <marcus@g10code.de>
+
+	* keylist.c (keylist_status_handler): Do not call finish_key() here.
+	(gpgme_op_keylist_ext_start): Set CTX->tmp_key to NULL.
+
+2002-09-03  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (assuan_libobjs): Remove @LTLIBOBJS@ as we link them
+	into gpgme unconditionally.
+	(libgpgme_la_LIBADD): Change @LIBOBJS@ into @LTLIBOBJS@.
+
+2002-09-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (assuan_libobjs): Use @LTLIBOBJS@ instead @LIBOBJS@.
+
+2002-09-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	* debug.c (_gpgme_debug_add): Test *LINE, not LINE.
+	(_gpgme_debug_end): Likewise.
+	Reported by Dr. Stefan Dalibor <Dr.Stefan.Dalibor@bfa.de>.
+
+2002-09-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	* posix-io.c (_gpgme_io_select): Don't use a non-constant struct
+	initializer.
+	* version.c (_gpgme_get_program_version): Likewise.
+	Reported by Dr. Stefan Dalibor <Dr.Stefan.Dalibor@bfa.de>.
+
+2002-09-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	* conversion.c (_gpgme_decode_c_string): Set DESTP before
+	modifying DEST.
+
+	* conversion.c (_gpgme_decode_c_string): Fix off by one error in
+	last change.
+	* rungpg.c (_gpgme_append_gpg_args_from_signers): Move before
+	_gpgme_op_edit so its prototype is known early on.
+
+	* conversion.c: New file.
+	* util.h: Add prototypes for _gpgme_decode_c_string and
+	_gpgme_hextobyte.
+	* keylist.c (keylist_colon_handler): Call _gpgme_decode_c_string
+	on issuer name.
+	* Makefile.am (libgpgme_la_SOURCES): Add conversion.c
+	* key.c (_gpgme_key_append_name): Replace calls to hextobyte by
+	calls to _gpgme_hextobyte.
+	(hash_key): Likewise.
+
+2002-09-01  Marcus Brinkmann  <marcus@g10code.de>
+
+	* op-support.c (_gpgme_op_reset): Set CTX->pending after calling
+	_gpgme_engine_release, as this will reset pending to zero in the
+	event done callback on cancelled operations.
+
+2002-08-30  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_op_edit): Add args from signers.
+	Suggested by Miguel Coca <e970095@zipi.fi.upm.es>.
+
+	* rungpg.c (_gpgme_gpg_op_edit): Add bogus ctx argument.
+	* rungpg.h: Also to prototype.
+	* engine.c (_gpgme_engine_op_edit): Likewise.
+	* engine.h: Likewise.
+	* edit.c (_gpgme_op_edit_start): Likewise.
+
+2002-08-29  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_sign): Implement signer
+	selection.
+	* vasprintf.c (va_copy): Define macro if not yet defined.
+
+2002-08-29  Marcus Brinkmann  <marcus@g10code.de>
+
+	* passphrase.c (_gpgme_passphrase_status_handler): Reset
+	CTX->result.passphrase->no_passphrase if passphrase is given (good
+	or bad).  Submitted by Jean DIRAISON <jean.diraison@free.fr>.
+
+2002-08-28  Marcus Brinkmann  <marcus@g10code.de>
+
+	* posix-io.c (_gpgme_io_spawn): Use a double-fork approach.
+	Return 0 on success, -1 on error.
+	* version.c (_gpgme_get_program_version): Don't wait for the child.
+	* engine.c (_gpgme_engine_housecleaning): Function removed.
+	(do_reaping): Likewise.
+	(_gpgme_engine_add_child_to_reap_list): Likewise.
+	(struct reap_s): Removed.
+	(reap_list): Likewise.
+	(reap_list_lock): Likewise.
+	* engine.h (_gpgme_engine_io_event): Remove prototypes for
+	_gpgme_engine_housecleaning and
+	_gpgme_engine_add_child_to_reap_list.
+	* rungpg.c (_gpgme_gpg_release): Don't add child to reap list.
+	(struct gpg_object_s): Remove PID member.
+	(_gpgme_gpg_new): Don't initialize GPG->pid.
+	(_gpgme_gpg_spawn): Don't set GPG->pid.
+	* wait.c (run_idle): Removed.
+	(gpgme_wait): Run idle_function directly.
+
+2002-08-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* encrypt-sign.c (encrypt_sign_status_handler): Remove dead
+	variables encrypt_info and encrypt_info_len.
+	* trustlist.c (gpgme_op_trustlist_start): Set colon line handler.
+	* posix-sema.c (sema_fatal): Remove function.
+	All these reported by St�phane Corth�sy.
+
+2002-08-23  Werner Koch  <wk@gnupg.org>
+
+	* gpgme-config.in: Made --prefix work for --libs. 
+
+2002-08-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* ath.h: Update list of symbols that get a prefix: Rename the
+	ath_mutex_*_available symbols to ath_*_available.
+
+2002-08-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* stpcpy.c: New file from gnulib.
+	* Makefile.am (assuan_libobjs): Remove jnlib.
+
+2002-08-20  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h: Add prototype for gpgme_op_import_ext.
+	* import.c (struct import_result_s): New member `nr_considered'.
+	Rename `any_imported' to `nr_imported'.
+	(import_status_handler): Increment nr_imported.  Set nr_considered
+	if appropriate.
+	(gpgme_op_import_ext): New function.
+	(gpgme_op_import): Implement in terms of gpgme_op_import_ext.
+
+2002-08-20  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.m4: Replaced with a new and faster version.  This does not
+	anymore try to build test programs.  If we really need test
+	programs, we should add an option to gpgme-config to do so. 
+
+	* vasprintf.c (int_vasprintf): Hack to handle NULL passed for %s.
+
+2002-08-20  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c (_gpgme_set_op_info): Append data on subsequent calls.
+	* encrypt-sign.c (encrypt_sign_status_handler): Remove op_info
+	handling.
+
+2002-08-19  Werner Koch  <wk@gnupg.org>
+
+	* decrypt.c (is_token,skip_token): Duplicated from verify.c
+	(gpgme_op_decrypt): Hack to properly return Decryption_Failed..
+	(_gpgme_decrypt_status_handler): Create an operation info.
+
+2002-08-14  Werner Koch  <wk@gnupg.org>
+
+	* key.h (struct certsig_s): New.  Use it in gpgme_key_s.
+	* key.c (gpgme_key_release): Release it. We need to add more code
+	of course.
+	(_gpgme_key_append_name): Use memset to intialize the struct.
+	* gpgme.h (GPGME_KEYLIST_MODE_SIGS): New.
+	* rungpg.c (_gpgme_gpg_op_keylist): Include sigs in listing depending
+	non the list mode.
+	
+	* key.c (gpgme_key_get_string_attr): Use GPGME_ATTR_TYPE to return
+	information about the key type (PGP or X.509).
+	(gpgme_key_get_ulong_attr): Likewise.
+
+	* keylist.c (keylist_colon_handler): Include 1 in the check for
+	valid algorithms so that RSA is usable.  Store the issuer name and
+	serial number also for "crs" records.  Parse the expire date for
+	subkeys.
+	(set_userid_flags): Put them onto the last appended key.
+
+2002-07-29  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_op_edit): Use --with-colons.
+
+2002-07-28  Marcus Brinkmann  <marcus@g10code.de>
+
+	* data.c (gpgme_data_read): For GPGME_DATA_TYPE_NONE, return EOF
+	instead an error.
+
+	The following changes make it possible to flush an inbound data
+	pipe before invoking a command handler:
+
+	* posix-io.c (_gpgme_io_select): Accept new argument NONBLOCK to
+	_gpgme_io_select.  Set timeout of 0 if this is set.
+	* w32-io.c (_gpgme_io_select): Likewise.
+	* io.h: Add new argument NONBLOCK to _gpgme_io_select prototype.
+	* wait.c (do_select): Add new argument to _gpgme_io_select
+	invocation.
+	* rungpg.h (_gpgme_gpg_set_command_handler): Add new argument
+	linked_data to prototype.
+	* engine.h (_gpgme_engine_set_command_handler): Likewise.
+	* engine.c (_gpgme_engine_set_command_handler): Likewise.
+	* passphrase.c (_gpgme_passphrase_start): Pass NULL as linked_data
+	argument to _gpgme_engine_set_command_handler.
+	* rungpg.c (struct gpg_object_s): New members linked_data and
+	linked_idx in CMD.
+	(_gpgme_gpg_new): Initialize those new members.
+	(_gpgme_gpg_set_command_handler): Accept new argument linked_data.
+	(build_argv): Handle linked_data in the same hack as cb_data.
+	(read_status): If linked_data is in use, flush the pipe before
+	activating the command handler.
+	* gpgme.h: Add prototypes for gpgme_op_edit_start and
+	gpgme_op_edit.
+
+	The next changes export the status codes to the user:
+
+	* decrypt.c (_gpgme_decrypt_status_handler): Likewise, also prefix
+	all STATUS_ with GPGME_.
+	* delete.c (delete_status_handler): Likewise.
+	* decrypt-verify.c (decrypt_verify_status_handler): Likewise.
+	* encrypt.c (_gpgme_encrypt_status_handler): Likewise.
+	(_gpgme_encrypt_sym_status_handler): Likewise.
+	* encrypt-sign.c (encrypt_sign_status_handler): Likewise.
+	* engine-gpgsm.c (parse_status): Likewise.
+	(gpgsm_status_handler): Likewise.
+	(gpgsm_set_recipients): Likewise.
+	* export.c (export_status_handler): Likewise.
+	* genkey.c (genkey_status_handler): Likewise.
+	* import.c (append_xml_impinfo): Likewise.
+	(import_status_handler): Likewise.
+	* keylist.c (keylist_status_handler): Likewise.
+	* passphrase.c (_gpgme_passphrase_status_handler): Likewise.
+	(command_handler): Likewise.
+	* progress.c (_gpgme_progress_status_handler): Likewise.
+	* sign.c (_gpgme_sign_status_handler): Likewise.
+	* trustlist.c (trustlist_status_handler): Likewise.
+	* verify.c (_gpgme_verify_status_handler): Likewise.
+	* gpgme.h (GpgmeEditCb): New type.
+	* rungpg.h (GpgStatusCode): Rename and move to ...
+	* gpgme.h (GpgmeStatusCode): ... this and here.
+	* Makefile.am (status-table.h): Run mkstatus on gpgme.h, not rungpg.h.
+	* mkstatus: Prefix STATUS with GPGME_.
+	* rungpg.h (GpgStatusHandler, GpgCommandHandler): Change type
+	accordingly.
+	* ops.h (_gpgme_verify_status_handler,
+	_gpgme_decrypt_status_handler, _gpgme_sign_status_handler,
+	_gpgme_encrypt_status_handler, _gpgme_passphrase_status_handler,
+	_gpgme_progress_status_handler): Likewise.
+	* rungpg.c (struct gpg_object_s): Likewise for CMD.code.
+
+	These changes add an edit operation to GPGME:
+	
+	* context.h (struct gpgme_context_s): New member RESULT.edit.  *
+	ops.h: Add prototype for _gpgme_release_edit_result and
+	_gpgme_passphrase_command_handler.
+	* passphrase.c (command_handler): Make non-static and rename to ...
+	(_gpgme_passphrase_command_handler): ... this.
+	(_gpgme_passphrase_start): Use new name for command handler.
+	* types.h: Add EditResult type.
+	* gpgme.c (_gpgme_release_result): Release EDIT result.
+	* edit.c: New file.
+	* Makefile.am (libgpgme_la_SOURCES): Add edit.c.
+	(libgpgme_la_LDADD): Rename to libgpgme_la_LIBADD, and include
+	assuan_libobjs.
+	(assuan_libobjs): New variable, set this instead
+	libgpgme_la_LIBADD.
+	* engine.h (_gpgme_engine_op_edit): New prototype.
+	* engine.c (_gpgme_engine_op_edit): New function.
+	* rungpg.h (_gpgme_gpg_op_edit): New prototype.
+	* rungpg.c (_gpgme_gpg_op_edit): New function.
+
+2002-07-27  Marcus Brinkmann  <marcus@g10code.de>
+
+	* delete.c (delete_problem): New case ambigious specification.
+	(delete_status_handler): Handle new case (poorly).
+
+2002-07-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_delete): Implement this.
+
+2002-07-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (libgpgme_la_LDADD): Add @LIBOBJS@ for vasprintf and
+	fopencookie.
+	* vasprintf.c: Update to more recent libiberty version.
+	* debug.h: Replace #elsif with #elif.
+
+	Submitted by St�phane Corth�sy:
+	* util.h (vasprintf): Correct prototype.
+	* encrypt-sign.c: Include <stddef.h>.
+	(encrypt_sign_status_handler): Change type of ENCRYPT_INFO_LEN to
+	size_t.
+	* ath-pthread.c: Include <stdlib.h>, not <malloc.h>.
+	* ath-pth.c: Likewise.
+
+2002-07-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* wait.c (fdt_global): Make static.  Reported by St�phane
+	Corth�sy.
+
+	* rungpg.c (_gpgme_gpg_op_keylist_ext): Skip empty string
+	patterns.  Reported by St�phane Corth�sy.
+
+	* key.c (gpgme_key_get_as_xml): Add OTRUST attribute.  Requested
+	by St�phane Corth�sy.
+	(gpgme_key_get_string_attr): Add GPGME_ATTR_SIG_SUMMARY case to
+	silence gcc warning.
+
+	* rungpg.c (_gpgme_gpg_new): Always set utf8 as charset.
+
+2002-07-03  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c (gpgme_set_io_cbs): Deal with CTX being NULL.
+
+	* gpgme.c (_gpgme_op_event_cb_user): New function.
+	* op-support.c (_gpgme_op_reset): Support a new mode of operation
+	for private or user event loop.  Use new user event callback
+	wrapper.
+	* trustlist.c (gpgme_op_trustlist_start): Use this new mode.
+	* keylist.c (gpgme_op_keylist_start): Likewise.
+
+	* rungpg.c (_gpgme_gpg_io_event): New function.
+	* rungpg.h (_gpgme_gpg_io_event): New prototype.
+	* engine-gpgsm.c (_gpgme_gpg_io_event): New function.
+	* engine-gpgsm.h (_gpgme_gpgsm_io_event): New prototype.
+	* engine.c (_gpgme_engine_io_event): New function.
+	* engine.h (_gpgme_engine_io_event): New prototype.
+	* keylist.c (finish_key): Call _gpgme_engine_io_event, and move
+	the real work for the default IO callback routines to ...
+	(_gpgme_op_keylist_event_cb): ... here.  New function.
+	* trustlist.c (trustlist_colon_handler): Signal
+	GPGME_EVENT_NEXT_TRUSTITEM.  Move queue manipulation to ...
+	(_gpgme_op_trustlist_event_cb): ... here.  New function.
+	* gpgme.c (_gpgme_op_event_cb): Call _gpgme_op_keylist_event_cb
+	and _gpgme_op_trustlist_event_cb when appropriate.
+	* ops.h (_gpgme_op_keylist_event_cb): New prototype.
+	(_gpgme_op_trustlist_event_cb): Likewise.
+	* op-support.c (_gpgme_op_reset): Add comment why we don't use the
+	user provided event handler directly.
+	* gpgme.h (GpgmeRegisterIOCb): Return GpgmeError value, and TAG in
+	a pointer argument.
+	* wait.c (_gpgme_add_io_cb): Likewise.
+	* wait.h (_gpgme_add_io_cb): Likewise for prototype.
+	* rungpg.c (_gpgme_gpg_add_io_cb): Call IO_CBS->add with new
+	argument.  Fix up error handling.
+	* engine-gpgsm.c (_gpgme_gpgsm_add_io_cb): Call IO_CBS->add with
+	new argument, fix up error handling.
+
+2002-07-03  Werner Koch  <wk@gnupg.org>
+
+	* encrypt.c (status_handler_finish): New.
+	(_gpgme_encrypt_status_handler): Moved some code out to the new
+	function and call this function also in case we get into the
+	status handler with an error which might happen due to a kludge in
+	engine-gpgsm.c
+
+2002-06-28  Marcus Brinkmann  <marcus@g10code.de>
+
+	* keylist.c (gpgme_op_keylist_ext_start): Always use our own FD
+	table (eg use synchronous mode).
+
+2002-06-28  Marcus Brinkmann  <marcus@g10code.de>
+
+	* ops.h (_gpgme_wait_on_condition): Remove HANG argument from
+	prototype and change return type to GpgmeError.
+	(_gpgme_wait_one): New prototype.
+	* wait.c (gpgme_wait): Replace with the meat from
+	_gpgme_wait_on_condition here, and remove the support for
+	conditions.
+	(_gpgme_wait_on_condition): Remove HANG argument from prototype
+	and change return type to GpgmeError.  Replace with meat from
+	_gpgme_wait_one and add support for conditions.
+	(_gpgme_wait_one): Just call _gpgme_wait_on_condition without
+	condition.
+	* keylist.c (gpgme_op_keylist_ext_start): Always use our own FD
+	table (eg use synchronous mode).
+	(gpgme_op_keylist_next): Remove HANG argument from
+	_gpgme_wait_on_condition.  Check its return value.
+	* trustlist.c (gpgme_op_trustlist_start): Always use our own FD
+	table (eg use synchronous mode).
+	(gpgme_op_trustlist_next): Remove HANG argument from
+	_gpgme_wait_on_condition.  Check its return value.
+	
+2002-06-27  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h: Fix documentation of key attribute retrieval functions.
+
+2002-06-26  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (map_assuan_error): Map No_Data_Available to EOF.
+
+	* import.c (append_xml_impinfo): Kludge to print fingerprint
+	instead of keyid for use with gpgsm.
+	(import_status_handler): Set a flag to know whether any import
+	occured.
+	(gpgme_op_import): Reurn -1 if no certificate ewas imported.
+
+2002-06-25  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_set_io_cbs) [ENABLE_GPGSM]: Fixed
+	function arguments.
+
+2002-06-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_export): Only export the keys
+	listed in RECP.
+	* export.c (gpgme_op_export): If no data was returned, return
+	GPGME_No_Recipients.
+
+2002-06-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_export): Implement.
+
+2002-06-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (gpgsm_assuan_simple_command): Return ERR.
+	(parse_status): New function.
+	(gpgsm_status_handler): Use parse_status.
+	(gpgsm_assuan_simple_command): Accept new arguments STATUS_FNC and
+	STATUS_FNC_VALUE and process status messages.
+	(gpgsm_set_recipients): Pass new arugments to gpgsm_assuan_simple_command.
+	(gpgsm_set_fd): Likewise.
+	(_gpgme_gpgsm_op_keylist): Likewise.
+	(_gpgme_gpgsm_op_keylist_ext): Likewise.
+	(_gpgme_gpgsm_op_sign): Likewise.
+
+2002-06-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* wait.c (_gpgme_remove_io_cb): Unlock FDT->lock.
+
+2002-06-20  Werner Koch  <wk@gnupg.org>
+
+	* rungpg.c (build_argv): Ignore GPG_AGENT_INFO if set but empty.
+
+	* verify.c (calc_sig_summary): Set bad policy for wrong key usage.
+	(skip_token): New.
+	(_gpgme_verify_status_handler): Watch out for wrong key usage.
+	(gpgme_get_sig_string_attr): Hack to return info on the key
+	usage.  Does now make use of the former RESERVED argument which
+	has been renamed to WHATIDX.
+	(gpgme_get_sig_ulong_attr): Renamed RESERVED to WHATIDX.
+
+2002-06-14  Marcus Brinkmann  <marcus@g10code.de>
+
+	* wait.c (do_select): Return -1 on error, and 0 if nothing to run.
+	(_gpgme_wait_one): Only set HANG to zero if do_select returned an
+	error, or there are no more file descriptors to wait on.
+	(_gpgme_wait_on_condition): Ignore return value from do_select for
+	now.
+
+2002-06-13  Werner Koch  <wk@gnupg.org>
+
+	* verify.c (gpgme_op_verify): Make sure that we never access an
+	unitialized result structure.
+
+2002-06-12  Werner Koch  <wk@gnupg.org>
+
+	* keylist.c (struct keylist_result_s): New.
+	(_gpgme_release_keylist_result): Release it here 
+	(keylist_status_handler): Handle truncated.
+	(append_xml_keylistinfo): New.
+	* gpgme.c (_gpgme_release_result): and use it here.
+	* types.h: Declare the new type here.
+	* context.h (struct gpgme_context_s): Use it here.
+
+2002-06-11  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_release): Close status_cb.fd.
+	(_gpgme_gpgsm_new): Duplicate status file descriptor, so we can
+	use our own close notification mechanism without interfering with
+	assuan.
+
+2002-06-11  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.h: Add GPGME_ATTR_SIG_SUMMARY and the GPGME_SIGSUM_
+	constants.
+	* verify.c (calc_sig_summary): New.
+	(gpgme_get_sig_ulong_attr): And use it here.
+
+2002-06-10  Werner Koch  <wk@gnupg.org>
+
+	* rungpg.h: Add new status codes TRUNCATED and ERROR.
+	* verify.c (is_token, copy_token): New.
+	(_gpgme_verify_status_handler): Use copy_token, handle the new
+	ERROR status and store the errorcode used withgpgsm and trust
+	status codes.
+	* gpgme.h: New attribute ERRTOK.
+	* key.c (gpgme_key_get_string_attr): Add dummy case for it.
+	(gpgme_get_sig_string_attr): Use it here to return the last error.
+
+2002-06-10  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_start): Move the code that sets the
+	close notification for the status fd to ...
+	(_gpgme_gpgsm_new): ... here.
+	* wait.h: Include "sema.h".  Remove prototypes of
+	_gpgme_remove_proc_from_wait_queue and
+	_gpgme_register_pipe_handler.  Add prototypes of
+	_gpgme_fd_table_init, _gpgme_fd_table_deinit, _gpgme_fd_table_put,
+	_gpgme_add_io_cb, _gpgme_remove_io_cb, _gpgme_wait_event_cb and
+	_gpgme_wait_one..
+	* wait.c: Remove global variables PROC_QUEUE, PROC_QUEUE_LOCK,
+	FD_TABLE_SIZE, FD_TABLE, FD_TABLE_LOCK.  New global variables
+	FDT_GLOBAL, CTX_DONE_LIST, CTX_DONE_LIST_SIZE,
+	CTX_DONE_LIST_LENGTH and CTX_DONE_LIST_LOCK.  Remove struct
+	proc_s.  Replace struct wait_item_s.
+	(_gpgme_fd_table_init): New function.
+	(_gpgme_fd_table_deinit): Likewise.
+	(_gpgme_fd_table_put): Likewise.
+	(set_process_done): Remove function.
+	(do_select): Take argument FDT.  Use that to decide which fds to
+	select on.
+	(_gpgme_remove_proc_from_wait_queue): Remove function.
+	(_gpgme_wait_event_cb): New function.
+	(_gpgme_wait_one): Likewise.
+	(_gpgme_register_pipe_hanldler): Remove function.
+	(_gpgme_add_io_cb): New function.
+	(_gpgme_remove_io_cb): Likewise.
+	(_gpgme_freeze_fd): Remove function.
+	(_gpgme_thaw_fd): Remove function.
+	* rungpg.c (struct fd_data_map_s): Add new member TAG.
+	(struct gpg_object_s): Likewise for STATUS and COLON.  Add member
+	IDX to CMD.  Add new member IO_CBS.
+	(close_notify_handler): New variables POSSIBLY_DONE and NOT_DONE.
+	For each I/O callback, check if it should be unregistered.  If all
+	callbacks have been unregistered, trigger GPGME_EVENT_DONE.
+	Remove member RUNNING.
+	(_gpgme_gpg_new): Initialize new members.
+	(_gpgme_gpg_release): Check PID not RUNNING.  Don't call
+	_gpgme_remove_proc_from_wait_queue.  Close GPG->CMD.FD if set.
+	(build_argv): Store away the index instead the file descriptor for
+	CMD.
+	(_gpgme_gpg_add_io_cb): New function.
+	(_gpgme_gpg_spawn): Use _gpgme_gpg_add_io_cb to register IO
+	callbacks.
+	(gpg_status_handler): Change return type to void, remove PID
+	argument, close filedescriptor if EOF or error occurs.
+	(read_status): Use _gpgme_gpg_add_io_cb instead _gpgme_thaw_fd.
+	Use IO_CBS->remove instead _gpgme_freeze_fd.
+	(gpg_colon_line_handler): Change return type to void, remove PID
+	argument, close filedescriptor if EOF or error occurs.
+	(command_cb): Use IO_CBS->remove instead _gpgme_freeze_fd.
+	(_gpgme_gpg_set_io_cbs): New function.
+	* rungpg.h (_gpgme_gpg_set_io_cbs): Prototype for
+	_gpgme_gpg_set_io_cbs.
+	* gpgme.h (GpgmeIOCb): New type.
+	(GpgmeRegisterIOCb): Likewise.
+	(GpgmeRemoveIOCb): Likewise.
+	(GpgmeEventIO): Likewise.
+	(GpgmeEventIOCb): Likewise.
+	(struct GpgmeIOCbs): New structure to hold I/O callbacks.
+	(gpgme_set_op_io_cbs): New prototype.
+	(gpgme_get_op_io_cbs): Likewise.
+	* ops.h: New prototype for _gpgme_op_event_cb.  Remove prototypes
+	for _gpgme_freeze_fd and _gpgme_thaw_fd.  Remove PID argument from
+	_gpgme_data_inbound_handler and _gpgme_data_outbound_handler
+	prototype.  Add prototype for _gpgme_op_reset.
+	Add synchronous argument to _gpgme_decrypt_start prototype.
+	* io.h: Beautification.
+	* gpgme.c: Include "wait.h".
+	(gpgme_new): Initialize FDT.
+	(gpgme_set_io_cbs): New function.
+	(gpgme_get_io_cbs): Likewise.
+	(_gpgme_op_event_cb): Likewise.
+	* data.c (_gpgme_data_inbound_handler): Change return type to
+	void.  Drop PID argument.  Close FD on error and EOF.
+	(write_mem_data): Don't close FD here ...
+	(write_cb_data): ... or here ...
+	(_gpgme_data_outbound_handler): ... but here.  Change return type
+	to void.  Drop PID argument.
+	* context.h: Include "wait.h".
+	(struct gpgme_context_s): New members FDT and IO_CBS.
+	* op-support.c: New file.
+	* Makefile.am (libgpgme_la_SOURCES): Add op-support.c.
+	* ops.h: Add prototype for _gpgme_op_reset().
+	* decrypt.c (_gpgme_decrypt_start): New argument SYNCHRONOUS.  Use
+	_gpgme_op_reset.
+	(gpgme_op_decrypt_start): Add synchronous argument.
+	(gpgme_op_decrypt): Likewise.  Use _gpgme_wait_one instead
+	gpgme_wait.
+	* delete.c (gpgme_op_delete_start): Rename to ...
+	(_gpgme_op_delete_start): ... this.  New argument SYNCHRONOUS.
+	Use _gpgme_op_reset.  Make function static.
+	(gpgme_op_delete_start): Just a wrapper around
+	_gpgme_op_delete_start now.
+	(gpgme_op_delete): Add synchronous argument.  Use _gpgme_wait_one
+	instead gpgme_wait.
+	* encrypt.c: Include "wait.h".
+	(ggpgme_op_encrypt_start): Rename to ...
+	(_gpgme_op_encrypt_start): ... this.  New argument SYNCHRONOUS.
+	Use _gpgme_op_reset.  Make function static.
+	(gpgme_op_encrypt_start): Just a wrapper around
+	_gpgme_op_encrypt_start now.
+	(gpgme_op_encrypt): Add synchronous argument.  Use _gpgme_wait_one
+	instead gpgme_wait.
+	* encrypt_sign.c (gpgme_op_encrypt_sign_start): Rename to ...
+	(_gpgme_op_encrypt_sign_start): ... this.  New argument
+	SYNCHRONOUS.  Use _gpgme_op_reset.  Make function static.
+	(gpgme_op_encrypt_sign_start): Just a wrapper around
+	_gpgme_op_encrypt_sign_start now.
+	(gpgme_op_encrypt_sign): Add synchronous argument.  Use
+	_gpgme_wait_one instead gpgme_wait.
+	* export.c (gpgme_op_export_start): Rename to ...
+	(_gpgme_op_export_start): ... this.  New argument SYNCHRONOUS.
+	Use _gpgme_op_reset.  Make function static.
+	(gpgme_op_export_start): Just a wrapper around
+	_gpgme_op_export_start now.
+	(gpgme_op_export): Add synchronous argument.  Use _gpgme_wait_one
+	instead gpgme_wait.
+	* genkey.c (gpgme_op_genkey_start): Rename to ...
+	(_gpgme_op_genkey_start): ... this.  New argument SYNCHRONOUS.
+	Use _gpgme_op_reset.  Make function static.
+	(gpgme_op_genkey_start): Just a wrapper around
+	_gpgme_op_genkey_start now.
+	(gpgme_op_genkey): Add synchronous argument.  Use _gpgme_wait_one
+	instead gpgme_wait.
+	* import.c (gpgme_op_import_start): Rename to ...
+	(_gpgme_op_import_start): ... this.  New argument SYNCHRONOUS.
+	Use _gpgme_op_reset.  Make function static.
+	(gpgme_op_import_start): Just a wrapper around
+	_gpgme_op_import_start now.
+	(gpgme_op_import): Add synchronous argument.  Use _gpgme_wait_one
+	instead gpgme_wait.
+	* keylist.c (gpgme_op_keylist_start): Use _gpgme_op_reset.
+	(gpgme_op_keylist_ext_start): Likewise.
+	* sign.c (gpgme_op_sign_start): Rename to ...
+	(_gpgme_op_sign_start): ... this.  New argument SYNCHRONOUS.  Use
+	_gpgme_op_reset.  Make function static.
+	(gpgme_op_sign_start): Just a wrapper around _gpgme_op_sign_start
+	now.
+	(gpgme_op_sign): Add synchronous argument.  Use _gpgme_wait_one
+	instead gpgme_wait.
+	* trustlist.c (gpgme_op_trustlist_start): Use _gpgme_op_reset.
+	* verify.c (gpgme_op_verify_start): Rename to ...
+	(_gpgme_op_verify_start): ... this.  New argument SYNCHRONOUS.
+	Use _gpgme_op_reset.  Make function static.
+	(gpgme_op_verify_start): Just a wrapper around
+	_gpgme_op_verify_start now.
+	(gpgme_op_verify): Add synchronous argument.  Use _gpgme_wait_one
+	instead gpgme_wait.
+	* engine-gpgsm.c (iocb_data_t): New type.
+	(struct gpgsm_object_s): New member status_cb.  Replace input_fd
+	and input_data with input_cb.  Replace output_fd and output_data
+	with output_cb.  Replace message_fd and message_data with
+	message_cb.  New member io_cbs.
+	(_gpgme_gpgsm_new): Initialize all new members (and drop the old
+	ones).
+	(close_notify_handler): New variable POSSIBLY_DONE.  For each I/O
+	callback, check if it should be unregistered.  If all callbacks
+	have been unregistered, trigger GPGME_EVENT_DONE.
+	(_gpgme_gpgsm_release): Remove variable PID.  Use new variable
+	names to close the file descriptors.
+	(_gpgme_gpgsm_op_decrypt): Use new variable names,
+	(_gpgme_gpgsm_op_encrypt): Likewise.
+	(_gpgme_gpgsm_op_genkey): Likewise.
+	(_gpgme_gpgsm_op_import): Likewise.
+	(_gpgme_gpgsm_op_keylist): Likewise.
+	(_gpgme_gpgsm_op_keylist_ext): Likewise.
+	(_gpgme_gpgsm_op_sign): Likewise.
+	(_gpgme_gpgsm_op_verify): Likewise.
+	(gpgsm_status_handler): Drop argument PID.  Change return type to
+	void.  Close status pipe before returning because of EOF or error.
+	(_gpgme_gpgsm_add_io_cb): New function.
+	(_gpgme_gpgsm_start): Use _gpgme_gpgsm_add_io_cb to register
+	callback function.
+	(_gpgme_gpgsm_set_io_cbs): New function.
+	* engine-gpgsm.h: New prototype for _gpgme_gpgsm_set_io_cbs.
+	* engine.c (_gpgme_engine_set_io_cbs): New function.
+	* engine.h: New prototype for _gpgme_engine_set_io_cbs.
+
+2002-06-04  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (libgpgme_la_SOURCES): Remove mutex.h.
+
+2002-06-03  Marcus Brinkmann  <marcus@g10code.de>
+
+	* key.c: Include <ctype.h>.
+	(_gpgme_key_append_name): Skip one more char when
+	processing escaped char.  Submitted by Marc Mutz <mutz@kde.org>.
+	Handle hexadecimal encodings.  Also reported by Marc.  Thanks!
+
+2002-06-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	* ath.h: Enable the _gpgme_ prefix.  Fix all those prefix macros.
+	* posix-sema.c: Use that prefix here.
+	* posix-io.c: Include "ath.h".
+	(_gpgme_io_read): Use _gpgme_ath_read instead read.
+	(_gpgme_io_write): Use _gpgme_ath_write instead write.
+	(_gpgme_io_waitpid): Use _gpgme_ath_waitpid instead waitpid.
+	(_gpgme_io_select): Use _gpgme_ath_select instead select.
+
+2002-06-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (ath_components): New variable.
+	(ath_components_pthread): Likewise.
+	(ath_components_pth): Likewise.
+	(system_components): Add ath_componentes.
+
+	* ath.h: New file.
+	* ath.c: Likewise.
+	* ath-pthread.c: Likewise.
+	* ath-pth.c: Likewise.
+	* posix-sema.c (_gpgme_sema_cs_enter): Rework to use the ATH
+	interface.
+	* mutex.h: Remove file.
+
+2002-05-30  Werner Koch  <wk@gnupg.org>
+
+	* key.c (gpgme_key_get_string_attr): Return NULL when asking for
+	an issuer with IDX > 0.  We don't support altIssuerNames for now.
+
+2002-05-22  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext): Aehmm, added
+	missing variable definition.  Oohh - Marcus was faster.
+
+2002-05-22  Marcus Brinkmann  <marcus@gnu.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext): Fix last change.
+
+2002-05-21  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist)
+	(_gpgme_gpgsm_op_keylist_ext):  Pass the keylist mode to gpgsm.
+
+2002-05-10  Werner Koch  <wk@gnupg.org>
+
+	* key.h (gpgme_key_s): Add OTRUST.
+	* keylist.c (set_ownertrust): New.
+	(keylist_colon_handler): Get the ownertrust value
+	* key.c (gpgme_key_get_string_attr,gpgme_key_get_ulong_attr):
+	Return that value.
+
+2002-05-08  Marcus Brinkmann  <marcus@g10code.de>
+
+	* w32-util.c: New static variable GET_PATH_LOCK.
+	(_gpgme_get_gpg_path): Remove superfluous NULL initializer.
+	Take lock while determining path.
+	(_gpgme_get_gpgsm_path): Likewise.
+	* version.c (do_subsystem_inits): Set DONE to 1 after
+	initialization.
+	(gpgme_get_engine_info): New variable ENGINE_INFO_LOCK.  Take lock
+	while determining engine info.
+	* rungpg.c (_gpgme_gpg_get_version): New variable
+	GPG_VERSION_LOCK.  Take the lock while determining the program
+	version.
+	* posix-io.c: Include "sema.h".
+	(_gpgme_io_spawn): New variable FIXED_SIGNALS_LOCK.  Take the lock
+	while fixing the Q_SIGNALS.
+	(_gpgme_io_select): Make READFDS and WRITEFDS non-static.
+	* key.c: Include "sema.h".  New globals KEY_CACHE_LOCK and
+	KEY_REF_LOCK.
+	(capabilities_to_string): Make STRINGS very const.
+	(_gpgme_key_cache_add): Lock the key cache.
+	(_gpgme_key_cache_get): Likewise.
+	(gpgme_key_ref, gpgme_key_release): Lock the key_ref_lock.
+	* import.c (append_xml_impinfo): Make IMPORTED_FIELDS and
+	IMPORT_RES_FIELDS very const.  Make FIELD and FIELD_NAME a litle
+	const.
+	* engine.c (_gpgme_engine_get_info): New variable
+	ENGINE_INFO_LOCK.  Take lock while determining engine info.
+	* engine-gpgsm.c: Include "sema.h".
+	(_gpgme_gpgsm_get_version): New variable GPGSM_VERSION_LOCK.  Take
+	lock while getting program version.
+
+2002-05-08  Marcus Brinkmann  <marcus@g10code.de>
+
+	* debug.h: New file.
+	* Makefile.am (libgpgme_la_SOURCES): Add debug.h.
+	* util.h: Removed all prototypes and declarations related to
+	debugging.  Include "debug.h".
+
+	* debug.c (debug_level): Comment variable and remove superfluous
+	zero initializer.
+	(errfp): Likewise.
+	(_gpgme_debug_enabled): Function removed.
+	(struct debug_control_s): Definition removed.
+	(_gpgme_debug_level): Function removed.
+	(_gpgme_debug_begin): Rewritten to use vasprintf.  Accept a
+	pritnf-style format specification and a variable number of
+	arguments.
+	(_gpgme_debug_add): Rewritten using vasprintf.  Expect that format
+	starts out with "%s" for simplicity.
+	(_gpgme_debug_end): Rewritten using vasprintf.  Do not accept a
+	TEXT argument anymore.
+
+	* posix-io.c (_gpgme_io_select): Use new level argument for
+	DEBUG_BEGIN instead explicit if construct.
+
+	* debug.c (debug_init): Remove superfluous zero initializer,
+	remove volatile flag of INITIALIZED.  Do not use the
+	double-checked locking algorithm, it is fundamentally flawed and
+	will empty your fridge (on a more serious note, despite the
+	volatile flag it doesn't give you the guarantee you would expect,
+	for example on a DEC Alpha or an SMP machine.  The volatile only
+	serializes accesses to the volatile variable, but not to the other
+	variables).
+
+2002-05-03  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_new): Redirect any gpgsm error
+	output to /dev/null.
+
+	* verify.c (gpgme_get_sig_key): Set the protocol of the listctx.
+	* gpgme.c (gpgme_get_protocol): New.
+
+	* data.c (gpgme_data_write): Changed type of BUFFER to void*.
+	(gpgme_data_read): Ditto.
+
+	* verify.c (_gpgme_verify_status_handler): Handle TRUST_* status
+	lines so that a claim can be made without looking up the key.
+	(gpgme_get_sig_string_attr): New. 
+	(gpgme_get_sig_ulong_attr): New.
+
+	* gpgme.h (GpgmeAttr): Added GPGME_ATTR_SIG_STATUS.
+
+	* rungpg.h: Add new status codes from gpg 1.0.7 and formatted the
+	list to align with the status.h file from gnupg.
+
+	* gpgme.h (GpgmeSigStat): Add _GOOD_EXP and _GOOD_EXPKEY.
+	* verify.c (_gpgme_verify_status_handler, finish_sig): Handle
+	these new status codes.  Store the expiration time 
+
+2002-04-27  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.h (GpgmeData_Encoding): New.
+	* data.c (gpgme_data_get_encoding,gpgme_data_set_encoding): New.
+	* engine-gpgsm.c (map_input_enc): New. Use it in all local
+	functions where the INPUT command gets send.
+
+2002-04-27  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_verify): Close the output
+	descriptor only when we don't need it anymore.  Close the message
+	descriptor if we don't need it.
+
+2002-04-26  Werner Koch  <wk@gnupg.org>
+
+	* Makefile.am (libgpgme_la_LIBADD): Use libtool libraries.
+
+2002-04-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_release): Call gpgme_data_release on
+	GPG->cmd.cb_data, not xfree.
+
+2002-04-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_new): Set the display, ttyname,
+	ttytype, lc_ctype and lc_messages options in the server.
+
+2002-04-24  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (map_assuan_error): Add new error codes.
+
+2002-04-23  Werner Koch  <wk@gnupg.org>
+
+	* key.c (gpgme_key_get_ulong_attr): Swapped use of can_encrypt and
+	can_certify to return the requested values.
+
+2002-04-23  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c (gpgme_get_progress_cb): Allow either return parameter
+	to be NULL.
+	(gpgme_get_passphrase_cb): Likewise.
+
+2002-04-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c (gpgme_get_passphrase_cb): New function.
+	(gpgme_get_progress_cb): New function.
+	* gpgme.h: Add new prototypes for gpgme_get_passphrase_cb and
+	gpgme_get_progress_cb.
+
+2002-03-28  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.h (GpgmeAttr): Add values for issuer and chaining.
+	* key.h (gpgme_key_s): Add issuer and chaining elements for X509.
+	* keylist.c (keylist_colon_handler): Store them.
+	* key.c	(gpgme_key_release): Free them.
+	(gpgme_key_get_as_xml,gpgme_key_get_string_attr): Print them.
+
+2002-03-26  Werner Koch  <wk@gnupg.org>
+
+	* Makefile.am (libgpgme_la_SOURCES): Add mutex.h
+
+2002-03-21  Werner Koch  <wk@gnupg.org>
+
+	* util.h [!HAVE_FOPENCOOKIE]: Make sure off_t and ssize_t are
+	defined.
+
+2002-03-18  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (system_components): New variable, set depending on
+	HAVE_DOSISH_SYSTEM.
+	(libgpgme_la_SOURCES): Use system_components.  Remove `syshdr.h'.
+	* syshdr.h: File removed.
+
+	* posix-io.c: Remove !HAVE_DOSISH_SYSTEM safeguard.  Clean up source.
+	* posix-sema.c: Likewise.
+	* posix-util.c: Likewise.
+
+	* w32-io.c: Remove HAVE_DOSISH_SYSTEM safeguard.
+	* w32-sema.c: Likewise.
+	* w32-util.c: Likewise.
+
+	* posix-io.c: Include `unistd.h', do not include `syshdr.h'.
+	* posix-sema.c: Likewise.
+	* w32-io.c: Include `io.h', do not include `syshdr.h'
+	* w32-sema.c: Likewise.
+	* w32-util.c: Likewise.
+	* data.c: Do not include `syshdr.h'.
+	* wait.c: Likewise.
+	* wait.h: Code cleanup.
+
+	* mutex.h: New file.
+	* posix-sema.c: Implement.
+
+2002-03-08  Werner Koch  <wk@gnupg.org>
+
+	* util.h [!HAVE_FOPENCOOKIE]: Fixed type.  Thanks to Frank Heckenbach.
+
+2002-03-07  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.h (gpgme_op_keylist_ext_start): Add prototype.
+
+2002-03-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* encrypt.c (_gpgme_encrypt_sym_status_handler): New function.
+	(gpgme_op_encrypt_start): New variable SYMMETRIC, set it if RECP
+	is null, and if it is set, use _gpgme_encrypt_sym_status_handler
+	as status handler and run _gpgme_passphrase_start.
+	* rungpg.c (_gpgme_gpg_op_encrypt): If RECP is zero, do symmetric
+	encryption.
+	* engine-gpgsm.c (_gpgme_gpgsm_op_encrypt): If RECP is zero,
+	return error value.
+
+	* rungpg.c (_gpgme_gpg_op_verify): Add "--" argument.
+
+2002-03-03  Marcus Brinkmann  <marcus@g10code.de>
+
+	* passphrase.c (_gpgme_passphrase_status_handler): Also set the
+	error No_Passphrase if only a bad passphrase was provided.
+
+2002-03-03  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_op_verify): If TEXT is of mode
+	GPGME_DATA_MODE_IN, construct a command line that stores the
+	plaintext in TEXT.
+	* verify.c (gpgme_op_verify_start): Accept TEXT being
+	uninitialized, and in this case interpret SIG as a normal or
+	cleartext signature and TEXT as a return data object.
+	* engine-gpgsm.c (_gpgme_gpgsm_op_verify): Likewise.
+
+2002-03-03  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext) [!ENABLE_GPGSM]:
+	Add stub function.
+
+2002-02-28  Werner Koch  <wk@gnupg.org>
+
+	* key.h (subkey_s): New member expires_at.
+	* keylist.c (keylist_colon_handler): Set it here
+	* key.c (gpgme_key_get_as_xml,gpgme_key_get_ulong_attr): Return it.
+
+2002-02-27  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.h (_gpgme_gpg_op_keylist_ext): New prototype.
+	* rungpg.c (_gpgme_gpg_op_keylist_ext): New function.
+	* engine-gpgsm.h (_gpgme_gpgsm_op_keylist_ext): New prototype.
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext): New function.
+	* engine.h (_gpgme_engine_op_keylist_ext): New prototype.
+	* engine.c (_gpgme_engine_op_keylist_ext): New function.
+	* keylist.c (gpgme_op_keylist_ext_start): New function.
+
+2002-02-27  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h: Add new error code GPGME_Invalid_Recipient.
+	* encrypt.c (struct encrypt_result_s): New member invalid_recipients,
+	rename no_recipients to no_valid_recipients.
+	(_gpgme_encrypt_status_handler): Include error for invalid
+	recipients.
+	* engine-gpgsm.c (gpgsm_set_recipients): Change type of first
+	argument to GpgsmObject.  Use that to report back the status about
+	the recipients.
+
+2002-02-26  Marcus Brinkmann  <marcus@g10code.de>
+
+	* verify.c (_gpgme_verify_status_handler): Fix the last change.
+
+2002-02-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine.c (_gpgme_engine_op_encrypt_sign): New function.
+	* engine.h (_gpgme_engine_op_encrypt_sign): New prototype.
+	* rungpg.c (_gpgme_append_gpg_args_from_signers): New function.
+	(_gpgme_gpg_op_sign): Use that new function.
+	(_gpgme_gpg_op_encrypt_sign): New function.
+	* rungpg.h (_gpgme_gpg_op_encrypt_sign): New prototype. 
+	* gpgme.h (gpgme_op_encrypt_sign_start): New prototype.
+	(gpgme_op_encrypt_sign): Likewise.
+	* Makefile.am (libgpgme_la_SOURCES): Add encrypt-sign.c.
+	* ops.h (_gpgme_encrypt_status_handler): Add prototype.
+	(_gpgme_sign_status_handler): Add prototype.
+	* sign.c (sign_status_handler): Rename to ...
+	(_gpgme_sign_status_handler): ... this and make non-static.
+	* encrypt.c (encrypt_status_handler): Rename to ...
+	(_gpgme_encrypt_status_handler): ... this and make non-static.
+	* encrypt.c (gpgme_op_encrypt_start): Use new status handler name.
+	* sign.c (gpgme_op_sign_start): Likewise.
+	
+2002-02-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* verify.c (_gpgme_verify_status_handler): Parse the args line to
+	see if the problem is due to a missing key, and report that back
+	to the user.
+
+2002-02-25  Marcus Brinkmann  <marcus@g10code.de>
+
+	* context.h (struct gpgme_context_s): New member include_certs.
+	* gpgme.h (gpgme_set_include_certs): Add prototype.
+	(gpgme_get_include_certs): Likewise.
+	* gpgme.c (gpgme_set_include_certs): New function.
+	(gpgme_get_include_certs): Likewise.
+	(gpgme_new): Set include_certs to 1 (the default).
+	* engine.c (_gpgme_engine_op_sign): Accept new argument include_certs,
+	and pass it to _gpgme_gpgsm_op_sign.
+	* engine.h (_gpgme_engine_op_sign): Likewise for prototype.
+	* engine-gpgsm.c (_gpgme_gpgsm_op_sign): Accept new argument
+	include_certs and handle it.
+	* engine-gpgsm.h (_gpgme_gpgsm_start): Add new argument include_certs.
+	* sign.c (gpgme_op_sign_start): Add new argument to
+	_gpgme_engine_op_sign call.
+
+2002-02-14  Werner Koch  <wk@gnupg.org>
+
+	* keylist.c (gpgme_op_keylist_start): Do not use a verbose listing.
+
+2002-02-13  Werner Koch  <wk@gnupg.org>
+
+	* vasprintf.c, fopencookie.c: Add replacement functions.
+	* util.h: Add prototypes for them.
+
+2002-02-09  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (gpgsm_assuan_simple_command): Return 0 if we
+	reach the end of the function.
+
+2002-02-09  Marcus Brinkmann  <marcus@g10code.de>
+
+	* genkey.c (gpgme_op_genkey_start): Fix logic in validity check.
+	(gpgme_op_genkey_start): Skip newlines after opening tag.
+
+	* engine-gpgsm.c (_gpgme_gpgsm_start): Remove cruft.
+
+2002-02-08  Marcus Brinkmann  <marcus@g10code.de>
+
+	* genkey.c (gpgme_op_genkey_start): Allow PUBKEY and SECKEY to be
+	set, and pass them down to the crypto engine.
+	* engine-gpgsm.h (_gpgme_gpgsm_start): New arguments PUBKEY and SECKEY.
+	* engine.h: Likewise.
+	* rungpg.h (_gpgme_gpg_spawn): Likewise.
+	* engine.c (_gpgme_engine_op_genkey): Likewise.  Use those
+	arguments.
+	* rungpg.c (_gpgme_gpg_op_genkey): Likewise.  Complain if those
+	arguments are set.
+	* engine-gpgsm.c (_gpgme_gpgsm_op_genkey): Likewise.  Implement
+	function.
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist): Beautify comment.
+
+2002-02-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_op_keylist): Remove handling of keylist
+	mode (for now).
+
+2002-02-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* wait.c (gpgme_wait): Add new argument STATUS, in which the
+	status of the returned context is returned.
+	(_gpgme_wait_on_condition): Rework the function a bit, to make it
+	aware of cancelled processes, and to allow to use gpgme_wait with
+	CTX being NULL (as documented in the source).
+	(struct proc_s): New member REPORTED.
+	* gpgme.h: Fix prototype.
+	* verify.c (gpgme_op_verify): Fix use of gpgme_wait.
+	* sign.c (gpgme_op_sign): Likewise.
+	* import.c (gpgme_op_import): Likewise.
+	* genkey.c (gpgme_op_genkey): Likewise.
+	* export.c (gpgme_op_export): Likewise.
+	* encrypt.c (gpgme_op_encrypt): Likewise.
+	* delete.c (gpgme_op_delete): Likewise.
+	* decrypt-verify.c (gpgme_op_decrypt_verify): Likewise.
+
+2002-02-06  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c (gpgme_set_keylist_mode): Possibly return an error
+	value.
+	(gpgme_get_keylist_mode): New function.
+	(gpgme_new): Set the default for keylist_mode member of CTX.
+
+	* gpgme.h (gpgme_set_keylist_mode): Fix prototype.
+	(gpgme_get_keylist_mode): New prototype.
+	(GPGME_KEYLIST_MODE_LOCAL): New macro.
+	(GPGME_KEYLIST_MODE_EXTERN): Likewise..
+
+2002-02-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	This patch has gotten a bit large... mmh.  The main thing that
+	happens here is that error values are now not determined in the
+	operation function after gpgme_wait completed, but in the status
+	handler when EOF is received.  It should always be the case that
+	either an error is flagged or EOF is received, so that after a
+	gpgme_wait you should never have the situation that no error is
+	flagged and EOF is not received.  One problem is that the engine
+	status handlers don't have access to the context, a horrible
+	kludge works around this for now.  All errors that happen during a
+	pending operation should be catched and reported in ctx->error,
+	including out-of-core and cancellation.  This rounds up neatly a
+	couple of loose ends, and makes it possible to pass up any errors
+	in the communication with the backend as well.  As a bonus, there
+	will be a function to access gpgme->wait, so that the operations
+	can truly be implemented with their _start function.
+
+	* engine-gpgsm.c (gpgsm_status_handler): Horrible kludge to report
+	error back to the context.
+	* rungpg.c (gpg_status_handler): Same horrible kludge applied here.
+
+	* engine-gpgsm.c (gpgsm_assuan_simple_command): Add error checking.
+
+	* wait.c (_gpgme_wait_on_condition): If canceled, set CTX->error
+	to a value indication that.
+
+	* verify.c (add_notation): Set error, not out_of_core.
+	(finish_sig): Likewise.
+	(gpgme_op_verify_start): Don't clear out_of_core.
+	(_gpgme_verify_status_handler): At EOF, clean up the notation data.
+	(gpgme_op_verify): And don't do it here.
+
+	* trustlist.c (trustlist_status_handler): Check error, not out_of_core.
+	(gpgme_op_trustlist_start): Don't clear out_of_core.
+	(gpgme_op_trustlist_next): Check error, not out_of_core.
+	(gpgme_op_trustlist_end): Likewise.
+
+	* ops.h (test_and_allocate_result): New macro.
+	(_gpgme_passphrase_result): Remove prototype.
+	* delete.c (gpgme_op_delete): Return error from context.
+	(delete_status_handler): Use macro test_and_allocate_result.
+	Perform error checking at EOF.
+	(gpgme_op_delete_start): Release result.
+	* passphrase.c (_gpgme_passphrase_status_handler): Use macro
+	test_and_allocate_result, and perform error checking here.
+	(_gpgme_passphrase_result): Function removed.
+	* sign.c (gpgme_op_sign_start): Do not set out_of_core to zero.
+	(gpgme_op_sign): Just return the error value from the context.
+	(sign_status_handler): Only progress if no error is set yet.  If
+	we process an EOF, set the resulting error value (if any).
+	* decrypt.c (_gpgme_decrypt_result): Function removed.
+	(create_result_struct): Function removed.
+	(_gpgme_decrypt_status_handler): Use macro test_and_allocate_result,
+	caclulate error on EOF, do not progress with errors.
+	(_gpgme_decrypt_start): Do not set out_of_core to zero.
+	(gpgme_op_decrypt): Just return the error value from the context.
+	* encrypt.c (encrypt_status_handler): Perform the error checking
+	here.
+	(gpgme_op_encrypt_start): Do not clear out_of_core.
+	* export.c (export_status_handler): Return if error is set in context.
+	(gpgme_op_export_start): Release result.
+	(gpgme_op_export): Return error from context.
+	* decrypt-verify.c (gpgme_op_decrypt_verify): Return the error in
+	the context.
+	* genkey.c (genkey_status_handler): Use macro
+	test_and_allocate_result.  Perform error checking at EOF.
+	(gpgme_op_genkey): Just return the error from context.
+	* import.c (gpgme_op_import): Return the error from context.
+	(import_status_handler): Use macro test_and_allocate_result.
+	* keylist.c (gpgme_op_keylist_start): Do not clear out_of_core.
+	(gpgme_op_keylist_next): Return error of context.
+	(keylist_colon_handler): Set error instead out_of_code.
+	(finish_key): Likewise.
+
+	* context.h: Remove member out_of_core, add member error.
+	* gpgme.c (_gpgme_release_result): Clear error flag.
+
+	* engine.h (_gpgme_engine_get_error): New prototype.
+	* engine.c (_gpgme_engine_get_error): New function.
+	* engine-gpgsm.c (_gpgme_gpgsm_get_error): New function.
+
+	* engine-gpgsm.c (map_assuan_error): New function.
+	(gpgsm_assuan_simple_command): Change return type to GpgmeError,
+	use the new function to map error values.
+	(gpgsm_set_fd): Change return type tp GpgmeError.
+	(_gpgme_gpgsm_op_decrypt): Change type of ERR to GpgmeError.
+	(gpgsm_set_recipients): Likewise.  Change type of return value
+	equivalently.  Adjust error values.
+	(_gpgme_gpgsm_op_import): Likewise.
+	(_gpgme_gpgsm_op_sign): Likewise.
+	(struct gpgsm_object_s): New member error.
+	(gpgsm_status_handler): Set error if error occurs.  Determine
+	error number from ERR line received.  If assuan_read_line fails,
+	terminate the connection.
+
+2002-02-01  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (MOSTLYCLEANFILES): New variable.
+
+2002-02-01  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (gpgsm_status_handler): At error, terminate the
+	connection to the server.
+
+2002-01-31  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.h: Add STATUS_KEY_CREATED.
+
+	* progress.c: New file.
+	* Makefile.am (libgpgme_la_SOURCES): Add progress.c.
+
+	* genkey.c (genkey_status_handler): Use
+	_gpgme_progress_status_handler.  Add check for status.
+	(struct genkey_result_s): New structure.
+	(_gpgme_release_genkey_result): New function.
+	(gpgme_op_genkey): Check for error.
+	* gpgme.c (_gpgme_release_result): Call
+	_gpgme_release_genkey_result.
+	* ops.h (_gpgme_release_genkey_result): Add prototype.
+	* types.h (GenKeyResult): New type.
+	* context.h (gpgme_context_s): Add GenKeyResult to member result.
+
+2002-01-30  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c (_gpgme_release_result): Call
+	_gpgme_release_delete_result.
+	* ops.h (_gpgme_release_delete_result): Add prototype.
+	* types.h (DeleteResult): New type.
+	* context.h (gpgme_context_s): Add DeleteResult to member result.
+
+	* delete.c (enum delete_problem): New type.
+	(struct delete_result_s): New structure.
+	(_gpgme_release_delete_result): New function.
+	(delete_status_handler): Implement more status codes.
+	(gpgme_op_delete): Return error on failure.
+
+	* import.c (MAX_IMPORTED_FIELDS): Bump up to 14.
+
+2002-01-30  Marcus Brinkmann  <marcus@g10code.de>
+
+	* import.c (struct import_result_s): New structure.
+	(_gpgme_release_import_result): New function.
+	(append_xml_impinfo): Likewise.
+	(import_status_handler): Implement.
+	* gpgme.c (_gpgme_release_result): Add call to
+	_gpgme_release_import_result.
+	* ops.h (_gpgme_release_import_result): Add prototype.
+	* types.h (ImportResult): New type.
+	* context.h (gpgme_context_s): Add ImportResult to member result.
+
+	* encrypt.c (gpgme_op_encrypt): Code clean up.
+
+2002-01-30  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h: Add lots of comment and fix the formatting.  Add
+	gpgme_trustlist_end prototype.
+
+2002-01-29  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h: Add new type GpgmeIdleFunc.  Change type of
+	gpgme_register_idle to return and accept this type.
+	* wait.c (gpgme_register_idle): Fix type.
+	Save and return old value of idle_function.
+
+2002-01-29  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist): Implement secret only mode.
+
+	* keylist.c (keylist_colon_handler): Add support for the new "crs"
+	record type.
+
+2002-01-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_release): Call assuan_disconnect,
+	not assuan_pipe_disconnect.
+
+	* Makefile.am (libgpgme_la_LIBADD): Change to link assuan and
+	jnlib (needed by assuan) statically into libgpgme.  Linking a
+	static library into a shared library this way is not portable.
+
+2002-01-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h (GpgmePassphraseCb): Change type of R_HD from void* to
+	void**.
+
+2002-01-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* data.c (gpgme_data_new_from_filepart): Change type of LENGTH
+	from off_t to size_t.
+	* gpgme.h: Likewise.
+
+2002-01-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* wait.c (_gpgme_wait_on_condition): If the process finished,
+	reset the pending flag.  Also if the operation was cancelled.
+
+	(struct proc_s): Rename READY to DONE.
+	(wait_item_s): Likewise.
+	(set_process_ready): Rename to ...
+	(set_process_done): ... this.
+	(_gpgme_remove_proc_from_wait_queue): Call set_process_done
+	instead set_process_ready.
+	(_gpgme_wait_on_condition): Likewise.
+	(do_select): Rename READY to DONE.
+
+	* verify.c (gpgme_op_verify): Do not set pending to zero here.
+	* sign.c (gpgme_op_sign): Likewise.
+	* import.c (gpgme_op_import): Likewise.
+	* genkey.c (gpgme_op_genkey): Likewise.
+	* export.c (gpgme_op_export): Likewise.
+	* encrypt.c (gpgme_op_encrypt): Likewise.
+	* delete.c (gpgme_op_delete): Likewise.
+	* decrypt-verify.c (gpgme_op_decrypt_verify): Likewise.
+	* decrypt.c (gpgme_op_decrypt): Likewise.
+
+2002-01-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* export.c: Cleanup.
+
+2002-01-15  Marcus Brinkmann  <marcus@g10code.de>
+
+	* trustlist.c: Various source clean ups.
+	(my_isdigit): Removed.
+	(gpgme_op_trustlist_end): New function.
+
+2002-01-13  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c: Various source clean ups, like renaming C to CTX where
+	appropriate.
+	(gpgme_new): Clear R_CTX before starting the work.
+	(my_isdigit): Removed.
+	(my_isxdigit): Likewise.
+
+	* data.c: Various source clean ups.
+	(gpgme_data_new_from_mem): Check BUFFER after clearing R_DH.
+	(gpgme_data_new_with_read_cb): Similar for READ_CB.
+	(gpgme_data_new_from_file): Loop over fread while EINTR.
+	(gpgme_data_new_from_filepart): Rediddled a bit.  Allow LENGTH to
+	be zero.  Loop over fread while EINTR.
+
+	(my_isdigit): Removed.
+	(my_isxdigit): Likewise.
+
+2001-12-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_new): Replace General_Error with
+	Pipe_Error where appropriate.
+
+2001-12-19  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine.c: Include `string.h'.  Reported by St�phane Corth�sy.
+
+	* version.c (get_engine_info): Remove prototype.
+
+2001-12-19  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_new): New variable CHILD_FDS.
+	Fill it with the servers fds, and pass it to assuan_pipe_connect.
+
+2001-12-18  Marcus Brinkmann  <marcus@g10code.de>
+
+	* keylist.c (gpgme_op_keylist_end): New function.
+	* gpgme.h (gpgme_op_keylist_end): New prototype.
+
+	* engine.h (gpgme_engine_check_version): Move prototype to ...
+	* gpgme.h (gpgme_engine_check_version): ... here.
+
+	* genkey.c (gpgme_op_genkey_start): Remove unused variable.
+
+2001-12-18  Marcus Brinkmann  <marcus@g10code.de>
+
+	* version.c (gpgme_get_engine_info): Reimplemented.
+	(gpgme_check_engine): Reimplemented.
+	(_gpgme_compare_versions): Return NULL if MY_VERSION is NULL.
+
+	* engine.c: Include `io.h'.
+	(gpgme_engine_get_info): New function.
+	* engine.h (gpgme_engine_check_version, _gpgme_engine_get_info):
+	Add prototype.
+
+2001-12-18  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (struct reap_s, reap_list, reap_list_lock): Moved to ...
+	* engine.c (struct reap_s, reap_list, reap_list_lock): ... here.
+	Include `time.h', `sys/types.h', `assert.h', and `sema.h'.
+
+	* rungpg.c (_gpgme_engine_add_child_to_reap_list): New function.
+	(do_reaping, _gpgme_gpg_housecleaning): Moved to ...
+	* engine.c (do_reaping, _gpgme_engine_housecleaning): ... here.
+	* rungpg.c (_gpgme_gpg_release): Replace code that is now in its
+	own function by call to _gpgme_engine_add_child_to_reap_list().
+
+	* wait.c: Include `engine.h'.
+	(run_idle): Call _gpgme_engine_housecleaning(), not
+	_gpgme_gpg_housecleaning().
+	
+2001-12-18  Marcus Brinkmann  <marcus@g10code.de>
+
+	* key.c (_gpgme_key_append_name): Append, not prepend, the uid.
+	Initialize the next field of the uid structure.
+	(gpgme_key_get_as_xml): Do not list last uid first.
+
+2001-12-17  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_set_colon_line_handler): New
+	function [!ENABLE_GPGSM].
+
+2001-12-14  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_verify): Put TEXT into
+	message_data, not SIG.
+	(_gpgme_gpgsm_op_sign): Use `--detached', not `--detach'.
+
+	* sign.c (sign_status_handler): Call
+	_gpgme_passphrase_status_handler early.
+
+2001-12-14  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c: Revert last change.
+
+2001-12-14  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (gpgsm_status_handler): Freeze the output file
+	handler when ending this operation, otherwise the wait function
+	will sit on it.
+
+2001-12-14  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (struct gpgsm_object_s): New member colon.attic.
+	(_gpgme_gpgsm_new): Initialize some more members.
+	(_gpgme_gpgsm_release): Free the colon line handler's attic line.
+	(gpgsm_status_handler): Rework the inline-data processing.
+
+2001-12-13  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_spawn): Do not add the fds to the child
+	list that are not dup'ed, for those the close-on-exec flag is set
+	now.
+	* version.c (_gpgme_get_program_version): Remove first entry in
+	CFD, as the close-on-exec flag is now set for this fd.
+
+2001-12-13  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_encrypt): Do not add `armor'
+	option to `ENCRYPT'.
+	* engine-gpgsm.c (gpgsm_set_recipients): Free LINE when returning
+	successfully.
+
+2001-12-13  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (close_notify_handler): New function.
+	(_gpgme_gpgsm_new): Manage the file descriptors a
+	bit differently.  Do not set close-on-exec flags.
+	(_gpgme_gpgsm_op_decrypt): Do not set message_fd
+	to -1, this is done by the close handler.
+	(_gpgme_gpgsm_op_encrypt): Likewise.
+	(_gpgme_gpgsm_op_import): Likewise (also for output_fd).
+	(_gpgme_gpgsm_op_keylist): Likewise (also for input_fd and output_fd).
+	(_gpgme_gpgsm_op_sign): Likewise.
+	(_gpgme_gpgsm_op_verify): Likewise, but for output_fd.
+
+	* posix-io.c (_gpgme_io_pipe): Set the close-on-exec flag for the
+	non-inherited file descriptor index of the pipe.
+
+2001-12-13  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_set_colon_line_handler): New.
+	(gpgsm_status_handler): Pass datalines to a colon handler
+	* engine.c (_gpgme_engine_set_colon_line_handler): Set the colon
+	handler for gpgsm.
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_keylist): Allow NULL for
+	pattern.
+	(gpgsm_assuan_simple_command): Removed underscore from
+	assuan_write_line.
+	(_gpgme_gpgsm_start): Ditto.
+	(gpgsm_assuan_simple_command): Replaced interal Assuan read
+	function by the new assuan_read_line.  Removed the use of the
+	internal header.
+	(gpgsm_status_handler): Ditto. Use the new assuan_pending_line.
+	(_gpgme_gpgsm_start): Use the documented way to get an fd from
+	assuan.
+
+	* keylist.c (keylist_colon_handler): Handle "crt" records
+	* key.h (gpgme_key_s): Add an x509 flag.
+	* key.c (parse_x509_user_id): New.
+	(_gpgme_key_append_name): Handle x.509 names.
+
+2001-12-05  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (gpgsm_status_handler): Make it work with current
+	version of assuan.
+
+2001-12-05  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (gpgsm_set_fd): Accept one more argument OPT.
+	(_gpgme_gpgsm_op_encrypt): Pass armor argument to gpgsm_set_fd for
+	output descriptor.
+	(_gpgme_gpgsm_op_sign): Likewise.
+
+2001-12-05  Marcus Brinkmann  <marcus@g10code.de>
+
+	* keylist.c (gpgme_op_keylist_next): Set pending to 0 if EOF
+	occurs.
+
+2001-11-26  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_sign): Fix stupid typo.
+
+2001-11-24  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (gpgsm_status_handler): Don't break if bsearch fails.
+	Deal with assuan read line returning more than one line (for now).
+
+2001-11-23  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_sign): Implement it according to
+	the current protocol definition.
+
+2001-11-23  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_new): Set CLOEXEC flag for parent
+	ends of the pipe.
+
+2001-11-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c: Include stdlib.h and string.h.  Also include,
+	for now, rungpg.h and status-table.h.
+	(gpgsm_status_handler): Implement more of the status handler.
+
+2001-11-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine.c (_gpgme_engine_op_decrypt): Implement CMS case.
+	(_gpgme_engine_op_delete): Likewise.
+	(_gpgme_engine_op_encrypt): Likewise.
+	(_gpgme_engine_op_export): Likewise.
+	(_gpgme_engine_op_genkey): Likewise.
+	(_gpgme_engine_op_keylist): Likewise.
+	(_gpgme_engine_op_sign): Likewise.
+	(_gpgme_engine_op_trustlist): Likewise.
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_encrypt): New function.
+	(gpgsm_assuan_simple_command): Likewise.
+	(gpgsm_set_recipients): Likewise.
+	(gpgsm_set_fd): Reimplement using gpgsm_assuan_simple_command.
+	(_gpgme_gpgsm_op_delete): New function.
+	(_gpgme_gpgsm_op_export): Likewise.
+	(_gpgme_gpgsm_op_genkey): Likewise.
+	(_gpgme_gpgsm_op_sign): Likewise.
+	(_gpgme_gpgsm_op_keylist): Likewise.
+	(_gpgme_gpgsm_op_trustlist): Likewise.
+	(_gpgme_gpgsm_release): Release command.
+	(_gpgme_gpgsm_op_decrypt): Allocate command.
+	(_gpgme_gpgsm_op_import): Likewise.
+	(gpgsm_status_handler): Also treat `ERR' strings as EOF.
+
+2001-11-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.h (gpgme_set_protocol): New prototype.
+
+2001-11-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c (_gpgme_gpgsm_op_decrypt): New function.
+	(_gpgme_gpgsm_op_import): Likewise.
+
+2001-11-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* engine-gpgsm.c: Shuffle around header inclusion a bit, to still
+	keep them seperate.
+	(_gpgme_set_status_handler) [!ENABLE_GPGSM]: New function.
+
+2001-11-22  Werner Koch  <wk@gnupg.org>
+
+	* engine-gpgsm.c: Include more headers so that NULL and mk_error
+	is defined even with an undefined GPGSM_PATH.
+
+2001-11-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (gpg_inbound_handler, write_mem_data, write_cb_data,
+	gpg_outbound_handler): Moved to ...
+	* data.c (_gpgme_data_inbound_handler, write_mem_data,
+	write_cb_data, _gpgme_data_outbound_handler): ... here.  Make the
+	_gpgme_* ones non-static.
+	* data.c: Include io.h.
+
+	* ops.h (_gpgme_data_inbound_handler): New prototype.
+	(_gpgme_data_outbound_handler): Likewise.
+	(_gpgme_gpg_spawn): Use these new functions.
+
+	* engine-gpgsm.h (_gpgme_gpgsm_op_decrypt, _gpgme_gpgsm_op_delete,
+	_gpgme_gpgsm_op_encrypt, _gpgme_gpgsm_op_export,
+	_gpgme_gpgsm_op_genkey, _gpgme_gpgsm_op_import,
+	_gpgme_gpgsm_op_keylist, _gpgme_gpgsm_op_sign,
+	_gpgme_gpgsm_op_trustlist, _gpgme_gpgsm_op_verify,
+	_gpgme_gpgsm_start, _gpgme_gpgsm_set_status_handler): New prototype.
+	Include <rungpg.h> for status handler function.
+
+	* engine-gpgsm.c (struct gpgsm_object_s): New members input_fd,
+	input_data, output_fd, output_data, message_fd, message_data, command
+	and status.
+	(_gpgme_gpgsm_new): Open input, output and message pipes before
+	connecting to the client.  Close server's ends afterwards.
+	(_gpgme_gpgsm_release): Close open file descriptors.  Remove
+	server process from wait queue.
+	(_gpgme_gpgsm_op_verify, _gpgme_gpgsm_start,
+	_gpgme_gpgsm_set_status_handler, gpgms_status_handler): New function.
+	
+	* engine.c (_gpgme_engine_start): Implement for GPGME_PROTOCOL_CMS.
+	(_gpgme_engine_set_status_handler): Likewise.
+	(_gpgme_engine_op_verify): Likewise.
+
+2001-11-21  Marcus Brinkmann  <marcus@g10code.de>
+
+	* context.h: Do not include rungpg.h, but engine.h.
+	(struct gpgme_context_s): Replace member gpg with engine.
+	* gpgme.c (gpgme_release): Release engine, not gpg.
+
+	* recipient.c (_gpgme_append_gpg_args_from_recifgpients): Function
+	moved ...
+	* rungpg.c (_gpgme_append_gpg_args_from_recipients): ... here.
+	Make static, change order of arguments, and return an error value.
+	* ops.h (_gpgme_append_gpg_args_from_recipients): Removed prototype.
+
+	* rungpg.h (_gpgme_gpg_op_verify): Add prototype.
+	(_gpgme_gpg_op_encrypt): Likewise.
+	(_gpgme_gpg_op_decrypt): Likewise.
+	(_gpgme_gpg_op_delete): Likewise.
+	(_gpgme_gpg_op_export): Likewise.
+	(_gpgme_gpg_op_genkey): Likewise.
+	(_gpgme_gpg_op_import): Likewise.
+	(_gpgme_gpg_op_keylist): Likewise.
+	(_gpgme_gpg_op_sign): Likewise.
+	(_gpgme_gpg_op_trustlist): Likewise.
+	* rungpg.c (_gpgme_gpg_op_verify): New function.
+	(_gpgme_gpg_op_encrypt): Likewise.
+	(_gpgme_gpg_op_decrypt): Likewise.
+	(_gpgme_gpg_op_delete): Likewise.
+	(_gpgme_gpg_op_export): Likewise.
+	(_gpgme_gpg_op_genkey): Likewise.
+	(_gpgme_gpg_op_import): Likewise.
+	(_gpgme_gpg_op_keylist): Likewise.
+	(_gpgme_gpg_op_sign): Likewise.
+	(_gpgme_gpg_op_trustlist): Likewise.
+
+	* engine.h (_gpgme_engine_set_status_handler): Add prototype.
+	(_gpgme_engine_set_command_handler): Likewise.
+	(_gpgme_engine_set_colon_line_handler): Likewise.
+	(_gpgme_engine_op_decrypt): Likewise.
+	(_gpgme_engine_op_delete): Likewise.
+	(_gpgme_engine_op_encrypt): Likewise.
+	(_gpgme_engine_op_export): Likewise.
+	(_gpgme_engine_op_genkey): Likewise.
+	(_gpgme_engine_op_import): Likewise.
+	(_gpgme_engine_op_keylist): Likewise.
+	(_gpgme_engine_op_sign): Likewise.
+	(_gpgme_engine_op_trustlist): Likewise.
+	(_gpgme_engine_op_verify): Likewise.
+	(_gpgme_engine_start): Likewise.
+	* engine.c (_gpgme_engine_set_status_handler): New function.
+	(_gpgme_engine_set_command_handler): Likewise.
+	(_gpgme_engine_set_colon_line_handler): Likewise.
+	(_gpgme_engine_op_decrypt): Likewise.
+	(_gpgme_engine_op_delete): Likewise.
+	(_gpgme_engine_op_encrypt): Likewise.
+	(_gpgme_engine_op_export): Likewise.
+	(_gpgme_engine_op_genkey): Likewise.
+	(_gpgme_engine_op_import): Likewise.
+	(_gpgme_engine_op_keylist): Likewise.
+	(_gpgme_engine_op_sign): Likewise.
+	(_gpgme_engine_op_trustlist): Likewise.
+	(_gpgme_engine_op_verify): Likewise.
+	(_gpgme_engine_start): Likewise.
+
+	* verify.c (gpgme_op_verify_start): Reimplement in terms of above
+	functions.
+	* encrypt.c (gpgme_op_encrypt_start): Likewise.
+	* decrypt.c (_gpgme_decrypt_start): Likewise.
+	* passphrase.c (_gpgme_passphrase_start): Likewise.
+	* keylist.c (gpgme_op_keylist_start): Likewise.
+
+2001-11-20  Marcus Brinkmann  <marcus@g10code.de>
+
+	* types.h: Add types EngineObject and GpgsmObject.
+
+	* Makefile.am (libgpgme_la_SOURCES): Add engine-gpgsm.h,
+	engine-gpgsm.c, engine.h and engine.c.
+	* engine.h: New file.
+	* engine.c: Likewise.
+	* engine-gpgsm.h: Likewise.
+	* engine-gpgsm.c: Likewise.
+	
+	* rungpg.c (_gpgme_gpg_get_version): New function.
+	(_gpgme_gpg_check_version): Likewise.
+	* rungpg.h: Add prototypes for _gpgme_gpg_get_version and
+	_gpgme_gpg_check_version.
+
+	* version.c (compare_versions): Rename to ...
+	(_gpgme_compare_versions): ... this.  Make non-static.
+	(gpgme_check_version): Use _gpgme_compare_versions rather than
+	compare_versions.
+	(gpgme_check_engine): Likewise.
+	* ops.h (_gpgme_get_program_version): Add prototype.
+
+2001-11-20  Marcus Brinkmann  <marcus@g10code.de>
+
+	* Makefile.am (libgpgme_la_INCLUDES): Remove obsolete directive.
+	(AM_CPPFLAGS): New directive [BUILD_ASSUAN].
+	(libgpgme_la_LIBADD): Likewise.
+
+2001-11-20  Marcus Brinkmann  <marcus@g10code.de>
+
+	* version.c: Remove global variables lineno and
+	tmp_engine_version.
+	(version_handler): Removed.
+	(_gpgme_get_program_version): New function.
+	(get_engine_info): Don't use context and version_handler,
+	but _gpgme_get_program_version.
+	* ops.h (_gpgme_get_program_version): Add prototype for
+	_gpgme_get_program_version (we expect to use it elsewhere soon).
+
+2001-11-18  Marcus Brinkmann  <marcus@g10code.de>
+
+	* version.c (get_engine_info): If GnuPG is not available, return
+	an error message.
+	* posix-util.c (_gpgme_get_gpg_path): Allow GPG_PATH to be
+	undefined.
+	(_gpgme_get_gpgsm_path): New function.
+	* w32-util.c (find_program_in_registry): New static function.
+	(_gpgme_get_gpg_path): Allow GPG_PATH to be undefined.  Rework
+	to use find_program_in_registry.
+	(_gpgme_get_gpgsm_path): New function.
+	(util.h): Prototype _gpgme_get_gpgsm_path).
+	* rungpg.c (_gpgme_gpg_spawn): Verify that _gpgme_get_gpg_path()
+	returns non-null.
+
+2001-11-16  Marcus Brinkmann  <marcus@g10code.de>
+
+	* decrypt-verify.c: New file.
+	* Makefile.am (libgpgme_la_SOURCES): Add decrypt-verify.c.
+	* types.h: Add decrypt-verify types.
+	* ops.h: Likewise.
+	* context.h: Add result type for decrypt-verify.
+	* gpgme.h: Add decrypt-verify prototypes.
+
+	* decrypt.c (decrypt_status_handler): Renamed to ...
+	(_gpgme_decrypt_status_handler): ... this.  Make non-static.
+	(_gpgme_decrypt_start): New function, derived from
+	gpgme_op_decrypt_start.
+	(gpgme_op_decrypt_start): Reimplement in terms of
+	_gpgme_decrypt_start.
+	(_gpgme_decrypt_result): New function to retrieve error value.
+	(gpgme_op_decrypt): Use _gpgme_decrypt_result.
+	* ops.h: Add prototypes for new functions.
+
+	* verify.c (verify_status_handler): Renamed to ...
+	(_gpgme_verify_status_handler): ... this.  Make non-static.
+	(gpgme_op_verify_start): Use new function name.
+	(intersect_stati): Renamed to ...
+	(_gpgme_intersect_stati): ... this.  Make non-static.
+	(gpgme_op_verify): Use new name.
+	* ops.h: Add prototypes for new functions.
+
+2001-11-16  Marcus Brinkmann  <marcus@g10code.de>
+
+	* passphrase.c: New file.
+	* Makefile.am (libgpgme_la_SOURCES): Add passphrase.c.
+	* ops.h (_gpgme_passphrase_result): Add prototypes from
+	passphrase.c.
+	* types.h: Likewise.
+	* context.h: Add member passphrase to result.
+	* gpgme.c (_gpgme_release_result): Release passphrase member.
+
+	* decrypt.c: Some formatting and variable name changes (like
+	CTX instead C).
+	(struct decrypt_result_s): Remove members now found in
+	passphrase result.
+	(_gpgme_release_decrypt_result): Don't release removed members.
+	(decrypt_status_handler): Call _gpgme_passphrase_status_handler,
+	and don't handle the cases catched there.
+	(command_handler): Removed.
+	(gpgme_op_decrypt_start): Don't set command handler, but invoke
+	_gpgme_passphrase_start which does it.
+	(gpgme_op_decrypt): Invoke _gpgme_passphrase_result and drop the
+	cases covered by it.
+
+	* sign.c Some formatting and variable name changes (like
+	CTX instead C).
+	(struct sign_result_s): Remove members now found in
+	passphrase result.
+	(_gpgme_release_sign_result): Don't release removed members.
+	(sign_status_handler): Call _gpgme_passphrase_status_handler,
+	and don't handle the cases catched there.
+	(command_handler): Removed.
+	(gpgme_op_sign_start): Don't set command handler, but invoke
+	_gpgme_passphrase_start which does it.
+	(gpgme_op_sign): Invoke _gpgme_passphrase_result and drop the
+	cases covered by it.
+
+2001-11-15  Marcus Brinkmann  <marcus@g10code.de>
+
+	* decrypt.c (command_handler): Fix last change.
+
+2001-11-15  Marcus Brinkmann  <marcus@g10code.de>
+
+	* verify.c (_gpgme_release_verify_result): Rename RES to RESULT.
+	Rename R2 to NEXT_RESULT.
+	(intersect_stati): Rename RES to RESULT.
+	(gpgme_get_sig_status): Likewise.  Do not check return_type, but
+	the member verify of result.
+	(gpgme_get_sig_key): Likewise.
+
+	* sign.c (_gpgme_release_sign_result): Rename RES to RESULT.  If
+	RESULT is zero, return.
+	(sign_status_handler, command_handler): Do not check return_type,
+	but the member sign of result.
+	(gpgme_op_sign): Likewise.  Drop assertion.
+
+	* encrypt.c (_gpgme_release_encrypt_result): Rename RES to RESULT.
+	If RESULT is zero, return.
+	(encrypt_status_handler): Do not check return_type, but the member
+	encrypt of result.
+	(gpgme_op_encrypt): Likewise.  Drop assertion.
+
+	* decrypt.c (_gpgme_release_decrypt_result): Rename RES to RESULT.
+	(create_result_struct): Do not set result_type.
+	(command_handler, decrypt_status_handler): Do not check
+	return_type, but the member decrypt of result.
+	(gpgme_op_decrypt): Likewise.  Drop assertion.
+
+	* context.h (enum ResultType): Removed.
+	(struct gpgme_context_s): Remove member result_type.
+	(struct result): Replaces union result.
+	* gpgme.c: Include string.h.
+	(_gpgme_release_result): Release all members of c->result, which
+	is now a struct.  Zero out all members of the struct afterwards.
+
+2001-11-11  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (_gpgme_gpg_release): Release GPG->cmd.cb_data.
+	Release all members of the list GPG->arglist.
+	Reported by Michael Schmidt <mschmidt@cs.uni-sb.de>.
+
+2001-11-02  Marcus Brinkmann  <marcus@g10code.de>
+
+	* rungpg.c (pipemode_copy): Change type of NBYTES to size_t.
+
+	* key.c: Include string.h.
+	* data.c: Likewise.
+	* recipient.c: Likewise.
+
+2001-10-29  Marcus Brinkmann  <marcus@g10code.de>
+
+	* context.h: New member signers_len.
+	* signers.c (gpgme_signers_clear): Require that signers are
+	non-NULL with assertion.  Use signers_len to determine how much
+	keys to release.  Add documentation.
+	(gpgme_signers_add): Use signers_len to determine if the buffer is
+	large enough.  Use xtryrealloc rather than xtrymalloc and copying.
+	Add documentation.
+	(gpgme_signers_enum): Use signers_len to determine if key is
+	available.  Add documentation.
+
+2001-10-22  Marcus Brinkmann  <marcus@g10code.de>
+
+	* data.c (_gpgme_data_append): Check if LENGTH is smaller than
+	ALLOC_CHUNK, not DH->length.
+
+2001-10-17  Marcus Brinkmann  <marcus@g10code.de>
+
+	* gpgme.c (gpgme_set_protocol): Fix last change.
+
+2001-10-15  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.h (GpgmeProtocol): New.
+	* gpgme.c (gpgme_set_protocol): New.
+
+2001-09-26  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.c (gpgme_set_passphrase_cb): Ignore a NULL context.
+	(gpgme_set_progress_cb): Ditto. Suggested by Mark Mutz.
+
+2001-09-17  Werner Koch  <wk@gnupg.org>
+
+	* keylist.c (finish_key): Shortcut for no tmp_key.  Changed all
+	callers to use this function without a check for tmp_key.
+	
+	* keylist.c (gpgme_op_keylist_next): Reset the key_cond after
+	emptying the queue.  Bug reported by St�phane Corth�sy.
+
+2001-09-12  Werner Koch  <wk@gnupg.org>
+
+	* data.c (gpgme_data_rewind): Allow rewind for callbacks.
+
+2001-09-07  Werner Koch  <wk@gnupg.org>
+
+	* rungpg.h: Add NO_RECP.
+	* encrypt.c (encrypt_status_handler): Take on No_RECP.
+	(gpgme_op_encrypt): Better error return.
+
+	* verify.c (verify_status_handler): Take on NODATA.
+
+2001-09-03  Werner Koch  <wk@gnupg.org>
+
+	* rungpg.h: Added STATUS_INV_RECP.
+	* gpgme.c (_gpgme_release_result): Add support for new
+	EncryptResult object.
+	* encrypt.c (append_xml_encinfo): New.
+	(encrypt_status_handler): Add some status parsing.
+	(_gpgme_release_encrypt_result): New.
+
+2001-08-29  Werner Koch  <wk@gnupg.org>
+
+	* recipient.c (gpgme_recipients_release): Free the list.  By Timo.
+
+	* keylist.c (keylist_colon_handler): Do a finish key if we receive
+	an EOF here.  This is probably the reason for a lot of bugs
+	related to keylisting.  It is so obvious.  Kudos to Enno Cramer
+	for pointing that out. 
+
+2001-08-28  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.c, gpgme.h (gpgme_get_op_info): New.
+	(_gpgme_set_op_info): New. 
+	(_gpgme_release_result): Reset the op_info here.
+	* sign.c (append_xml_siginfo): New.
+	(sign_status_handler): Store the sig create information.
+
+2001-07-31  Werner Koch  <wk@gnupg.org>
+
+	* encrypt.c (gpgme_op_encrypt): Hack to detect no valid recipients.
+
+2001-07-30  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.c (gpgme_get_armor,gpgme_get_textmode): New.
+
+	* rungpg.c (build_argv): Disable armor comments
+	* w32-io.c (build_commandline): Need to add quotes here
+
+2001-07-24  Werner Koch  <wk@gnupg.org>
+
+	* data.c (gpgme_data_read): Add a a way to return the available bytes.
+
+2001-07-23  Werner Koch  <wk@gnupg.org>
+
+	* util.c: Removed stpcpy() because we use the version from jnlib.
+
+2001-07-19  Werner Koch  <wk@gnupg.org>
+
+	* mkstatus: Define the collating sequence for sort.
+
+2001-06-26  Werner Koch  <wk@gnupg.org>
+
+	* rungpg.h: Add STATUS_UNEXPECTED as suggested by Timo.
+
+2001-06-15  Werner Koch  <wk@gnupg.org>
+
+	* keylist.c (set_userid_flags): Fixed the assigned values. Kudos
+	to Timo for pointing this out.
+
+2001-06-01  Werner Koch  <wk@gnupg.org>
+
+	* debug.c (_gpgme_debug_begin): Fixed a /tmp race.  Noted by
+	Johannes Poehlmann.
+
+2001-05-28  Werner Koch  <wk@gnupg.org>
+
+	* version.c (gpgme_check_engine): Stop version number parsing at
+	the opening angle and not the closing one.  By Tommy Reynolds.
+
+2001-05-01  Jos� Carlos Garc�a Sogo <jose@jaimedelamo.eu.org>
+
+	* encrypt.c (gpgme_op_encrypt_start): Deleted the assert ( !c->gpg )
+	line, because it gave an error if another operation had been made 
+	before using the same context.
+	
+	* decrypt.c (gpgme_op_decrypt_start): The same as above. Also added 
+	one line to release the gpg object in the context (if any).
+	
+2001-04-26  Werner Koch  <wk@gnupg.org>
+
+	* key.c, key.h (_gpgme_key_cache_init): New.
+	(_gpgme_key_cache_add): New.
+	(_gpgme_key_cache_get): New.
+	* version.c (do_subsystem_inits): Init the cache.
+	* keylist.c (finish_key): Put key into the cache
+	* verify.c (gpgme_get_sig_key): First look into the cache.
+
+2001-04-19  Werner Koch  <wk@gnupg.org>
+
+	* keylist.c (parse_timestamp): Adjusted for the changed
+	--fixed-list-mode of gpg 1.0.4h.
+
+2001-04-05  Werner Koch  <wk@gnupg.org>
+
+	* verify.c (gpgme_op_verify_start): Enabled pipemode for detached sigs.
+
+2001-04-04  Werner Koch  <wk@gnupg.org>
+
+	* w32-io.c (_gpgme_io_select): Don't select on the writer if there
+	are still bytes pending.  Timo found this not easy to track down
+	race condition. 
+
+2001-04-02  Werner Koch  <wk@gnupg.org>
+
+	* gpgme.h: Add GPGME_ATTR_KEY_{EXPIRED,DISABLED}.
+	* key.c (gpgme_key_get_ulong_attr): And return those attribs.
+
+	* verify.c (gpgme_get_sig_key): Set keyliosting mode depending on 
+	the mode set in the current context.  Suggested by Timo.
+
+	* key.c (gpgme_key_get_ulong_attr): Return can_certify and not
+	can_encrypt. By Timo.
+
+2001-03-30  Werner Koch  <wk@gnupg.org>
+
+	* debug.c (debug_init): Allow to specify a debug file.
+	(_gpgme_debug_level): New.
+
+	* posix-io.c (_gpgme_io_read, _gpgme_io_write): Print output.
+	(_gpgme_io_select): Debug only with level > 2.
+
+2001-03-15  Werner Koch  <wk@gnupg.org>
+
+	* rungpg.c: Included time.h.
+
+	* key.h: New keyflags for capabilities.
+	* keylist.c (set_mainkey_capability, set_subkey_capability): New.
+	(keylist_colon_handler): Parse them.
+	* gpgme.h: New attribute values for capabilties.
+	* key.c (gpgme_key_get_string_attr): Return them.
+	(capabilities_to_string): New.
+	(gpgme_key_get_ulong_attr): Return the global caps.
+
+2001-03-14  Werner Koch  <wk@gnupg.org>
+
+	* w32-io.c (destroy_reader,destroy_writer): Fixed syntax error. 
+	Thanks to Jan Oliver Wagner.
+
+2001-03-13  Werner Koch  <wk@gnupg.org>
+
+	* context.h: Add invalid and revoke flags to user_id structure.
+	* keylist.c (gpgme_op_keylist_start): Use --fixed-list-mode.
+	(keylist_colon_handler): Adjust for that.
+ 	(set_userid_flags): New. 
+	(set_mainkey_trust_info): Handle new key invalid flag
+	(set_subkey_trust_info): Ditto.
+	* gpgme.h: Add new attributes for key and user ID flags.
+	* key.c (_gpgme_key_append_name): Init these flags
+	(gpgme_key_get_as_xml): Print them.
+	(one_uid_as_xml): New helper for above.
+	(gpgme_key_get_string_attr, gpgme_key_get_ulong_attr):
+	Return the new attributes.  Enhanced, so that subkey information
+	can be returned now.
+
+2001-02-28  Werner Koch  <wk@gnupg.org>
+
+	* w32-io.c (destroy_reader): Set stop_me flag.
+	(writer,create_writer,destroy_writer,find_writer,kill_writer): New.
+	(_gpgme_io_write): Use a writer thread to avaoid blocking.
+	(_gpgme_io_close): Cleanup a writer thread
+	(_gpgme_io_select): Repalce tthe faked wait on writing by a real
+	waiting which is now possible due to the use of a writer thread.
+
+2001-02-20  Werner Koch  <wk@gnupg.org>
+
+	* w32-io.c (destroy_reader,kill_reader): New. 
+	(create_reader, reader): Add a new event to stop the thread.
+	(_gpgme_io_close): Kill the reader thread.
+
+	* posix-io.c (_gpgme_io_select): Handle frozen fds here. 
+	* 32-io.c (_gpgme_io_select): Ditto. Removed a bunch of unused code.
+
+	* wait.c: Reworked the whole thing.
+	* rungpg.c (_gpgme_gpg_new): Init pid to -1.
+	(_gpgme_gpg_release): Remove the process from the wait queue.
+
+2001-02-19  Werner Koch  <wk@gnupg.org>
+
+	* w32-io.c (_gpgme_io_set_close_notify): New.
+	(_gpgme_io_close): Do the notification.
+
+	* posix-io.c (_gpgme_io_select): Use a 1 sec timeout and not 200
+	microseconds.
+
+	* wait.c (remove_process): Don't close the fd here.
+	(do_select): Set the fd to -1 and remove the is_closed flag everywhere.
+	(_gpgme_wait_on_condition): Remove the assert on the queue and
+	break out if we could not find the queue.  The whole thing should
+	be reworked.
+
+	* posix-io.c (_gpgme_io_set_close_notify): New.
+	(_gpgme_io_close): Do the notification.
+
+	* rungpg.c (close_notify_handler): New. 
+	(_gpgme_gpg_new): Register a callback for the fd.
+	(_gpgme_gpg_set_colon_line_handler): Ditto.
+	(build_argv): Ditto
+
+2001-02-13  Werner Koch  <wk@gnupg.org>
+
+	* rungpg.c (struct reap_s): Replaced pid_t by int.
+
+	* types.h: Add ulong typedef.
+
+	* rungpg.c (do_reaping,_gpgme_gpg_housecleaning): New.
+	(_gpgme_gpg_release): Reap tqchildren.
+	* io.h, posix-io.c (_gpgme_io_kill): New.
+	* w32-io.c (_gpgme_io_kill): New (dummy).
+
+	* keylist.c (gpgme_op_keylist_start): Cancel a pending request.
+
+	* posix-io.c (_gpgme_io_read): Add some debug output. 
+	(_gpgme_io_write): Ditto.
+	(_gpgme_io_select): Increased the timeout.
+
+2001-02-12  Werner Koch  <wk@gnupg.org>
+
+	Enhanced the signature verification, so that it can how handle
+	more than one signature and is able to return more information on 
+	the signatures.
+	* verify.c (gpgme_get_sig_key): New.
+	(gpgme_get_sig_status): New.
+
+	* gpgme.h: Add stdio.h. 
+	(GpgmeSigStat): New status DIFF.
+
+2001-02-01  Werner Koch  <wk@gnupg.org>
+
+	* w32-io.c (set_synchronize): Add EVENT_MODIFY_STATE.  Add Debug
+	code to all Set/ResetEvent().
+
+	* rungpg.c (read_status): Check for end of stream only if we have
+	an r.  By Timo.
+
+2001-01-31  Werner Koch  <wk@gnupg.org>
+
+	* wait.c (_gpgme_wait_on_condition): Removed all exit code processing.
+	(propagate_term_results,clear_active_fds): Removed.
+	(count_active_fds): Renamed to .. 
+	(count_active_and_thawed_fds): .. this and count only thawed fds. 
+
+	* rungpg.c (gpg_colon_line_handler): Return colon.eof and not
+	status.eof ;-)
+
+2001-01-30  Werner Koch  <wk@gnupg.org>
+
+	* w32-io.c (_gpgme_io_spawn): Use the supplied path arg.
+
+	* version.c (get_engine_info): Return better error information.
+
+	* posix-util.c, w32-util.c: New.
+	(_gpgme_get_gpg_path): New, suggested by Jan-Oliver.
+	* rungpg.c (_gpgme_gpg_spawn): Use new function to get GPG's path.
+
+	* signers.c (gpgme_signers_add): Ooops, one should test code and
+	not just write it; the newarr was not assigned.  Thanks to Jos�
+	for pointing this out.  Hmmm, still not tested, why shoudl a coder
+	test his fix :-)
+
+	* w32-io.c: Does now use reader threads, so that we can use
+	WaitForMultipleObjects. 
+	* sema.h, posix-sema.c, w32-sema.c: Support for Critcial sections.
+	Does currently only work for W32.
+
+	* debug.c, util.h : New. Changed all fprintfs to use this new
+	set of debugging functions.
+
+2001-01-23  Werner Koch  <wk@gnupg.org>
+
+	* data.c (_gpgme_data_release_and_return_string): Fixed string
+	termination.
+
+2001-01-22  Werner Koch  <wk@gnupg.org>
+
+	* delete.c: New.
+
+	* signers.c: New.
+	* key.c (gpgme_key_ref, gpgme_key_unref): New.
+	* sign.c (gpgme_op_sign_start): Allow the use of other keys.
+
+	* version.c (gpgme_get_engine_info,gpgme_check_engine): New.
+	* rungpg.c (_gpgme_gpg_set_simple_line_handler): New.
+
+2001-01-05  Werner Koch  <wk@gnupg.org>
+
+	* data.c (gpgme_data_rewind): Allow to rewind data_type_none.
+
+
+ Copyright 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
+
+ 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/gpgme/Makefile.am b/libtdenetwork/libgpgme-copy/gpgme/Makefile.am
new file mode 100644
index 000000000..5ea41e091
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/Makefile.am
@@ -0,0 +1,50 @@
+# 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 automake to produce Makefile.in
+
+noinst_LTLIBRARIES = libgpgme-real.la libgpgme.la
+
+assuan_cppflags = -I$(srcdir)/../assuan
+assuan_libobjs = ../assuan/libassuan.la
+
+libgpgme_real_la_SOURCES =						\
+	conversion.c get-env.c 	\
+	data.c data-fd.c data-stream.c data-mem.c data-user.c	\
+	data-compat.c							\
+	signers.c							\
+	wait.c wait-global.c wait-private.c wait-user.c 		\
+	op-support.c							\
+	encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c	\
+	sign.c passphrase.c progress.c					\
+	key.c keylist.c trust-item.c trustlist.c			\
+	import.c export.c genkey.c delete.c edit.c			\
+	engine.c rungpg.c 	\
+	posix-util.c posix-sema.c posix-io.c	\
+	engine-gpgsm.c sig-notation.c funopen.c \
+	debug.c gpgme.c version.c error.c
+
+libgpgme_la_SOURCES = ath.c
+
+AM_CPPFLAGS = $(assuan_cppflags) -I$(srcdir)/../../libgpg-error-copy -I../../libgpg-error-copy
+
+libgpgme_la_LIBADD = libgpgme-real.la ../../libgpg-error-copy/libgpg-error.la $(assuan_libobjs)
+
+status-table.h : $(srcdir)/gpgme.h
+	$(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h
diff --git a/libtdenetwork/libgpgme-copy/gpgme/ath-pth-compat.c b/libtdenetwork/libgpgme-copy/gpgme/ath-pth-compat.c
new file mode 100644
index 000000000..7bdea8762
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/ath-pth-compat.c
@@ -0,0 +1,123 @@
+/* ath-pth.c - Pth module for self-adapting thread-safeness library
+ *      Copyright (C) 2002 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
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <pth.h>
+
+#include "ath.h"
+
+#pragma weak pth_mutex_init
+#pragma weak pth_mutex_acquire
+#pragma weak pth_mutex_release
+#pragma weak pth_read
+#pragma weak pth_write
+#pragma weak pth_select
+#pragma weak pth_waitpid
+#pragma weak pth_accept
+#pragma weak pth_connect
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pth_init (void **priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pth_mutex_acquire (&check_init_lock, 0, NULL);
+  if (!*priv || !just_check)
+    {
+      pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
+      if (!lock)
+	err = ENOMEM;
+      if (!err)
+	{
+	  err = pth_mutex_init (lock);
+	  if (err == FALSE)
+	    err = errno;
+	  else
+	    err = 0;
+
+	  if (err)
+	    free (lock);
+	  else
+	    *priv = lock;
+	}
+    }
+  if (just_check)
+    pth_mutex_release (&check_init_lock);
+  return err;
+}
+
+
+static int
+mutex_pth_destroy (void *priv)
+{
+  free (priv);
+  return 0;
+}
+
+
+static int
+mutex_pth_lock (void *priv)
+{
+  int ret = pth_mutex_acquire ((pth_mutex_t *) priv, 0, NULL);
+  return ret == FALSE ? errno : 0;
+}
+
+
+static int
+mutex_pth_unlock (void *priv)
+{
+  int ret = pth_mutex_release ((pth_mutex_t *) priv);
+  return ret == FALSE ? errno : 0;
+}
+
+
+static struct ath_ops ath_pth_ops =
+  {
+    mutex_pth_init,
+    mutex_pth_destroy,
+    mutex_pth_lock,
+    mutex_pth_unlock,
+    pth_read,
+    pth_write,
+    pth_select,
+    pth_waitpid,
+    pth_accept,
+    pth_connect,
+    NULL,	/* FIXME: When GNU PTh has sendmsg.  */
+    NULL	/* FIXME: When GNU PTh has recvmsg.  */
+  };
+
+
+struct ath_ops *
+ath_pth_available (void)
+{
+  if (pth_mutex_init && pth_mutex_acquire && pth_mutex_release
+      && pth_read && pth_write && pth_select && pth_waitpid)
+    return &ath_pth_ops;
+  else
+    return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/ath-pth.c b/libtdenetwork/libgpgme-copy/gpgme/ath-pth.c
new file mode 100644
index 000000000..74eb20422
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/ath-pth.c
@@ -0,0 +1,178 @@
+/* ath-pth.c - Pth module for self-adapting thread-safeness library
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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 <errno.h>
+
+#include <pth.h>
+
+#include "ath.h"
+
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pth_init (ath_mutex_t *priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pth_mutex_acquire (&check_init_lock, 0, NULL);
+  if (!*priv || !just_check)
+    {
+      pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
+      if (!lock)
+	err = ENOMEM;
+      if (!err)
+	{
+	  err = pth_mutex_init (lock);
+	  if (err == FALSE)
+	    err = errno;
+	  else
+	    err = 0;
+
+	  if (err)
+	    free (lock);
+	  else
+	    *priv = (ath_mutex_t) lock;
+	}
+    }
+  if (just_check)
+    pth_mutex_release (&check_init_lock);
+  return err;
+}
+
+
+void
+ath_init (void)
+{
+  /* Nothing to do.  */
+}
+
+
+int
+ath_mutex_init (ath_mutex_t *lock)
+{
+  return mutex_pth_init (lock, 0);
+}
+
+
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+  int err = mutex_pth_init (lock, 1);
+  if (!err)
+    {
+      /* GNU Pth has no destructor function.  */
+      free (*lock);
+    }
+  return err;
+}
+
+
+int
+ath_mutex_lock (ath_mutex_t *lock)
+{
+  int ret = mutex_pth_init (lock, 1);
+  if (ret)
+    return ret;
+
+  ret = pth_mutex_acquire ((pth_mutex_t *) *lock, 0, NULL);
+  return ret == FALSE ? errno : 0;
+}
+
+
+int
+ath_mutex_unlock (ath_mutex_t *lock)
+{
+  int ret = mutex_pth_init (lock, 1);
+  if (ret)
+    return ret;
+
+  ret = pth_mutex_release ((pth_mutex_t *) *lock);
+  return ret == FALSE ? errno : 0;
+}
+
+
+ssize_t
+ath_read (int fd, void *buf, size_t nbytes)
+{
+  return pth_read (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_write (int fd, const void *buf, size_t nbytes)
+{
+  return pth_write (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+	    struct timeval *timeout)
+{
+  return pth_select (nfd, rset, wset, eset, timeout);
+}
+
+ 
+ssize_t
+ath_waitpid (pid_t pid, int *status, int options)
+{
+  return pth_waitpid (pid, status, options);
+}
+
+
+int
+ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
+{
+  return pth_accept (s, addr, length_ptr);
+}
+
+
+int
+ath_connect (int s, const struct sockaddr *addr, socklen_t length)
+{
+  return pth_connect (s, addr, length);
+}
+
+int
+ath_sendmsg (int s, const struct msghdr *msg, int flags)
+{
+  /* FIXME: GNU Pth is missing pth_sendmsg.  */
+  return sendmsg (s, msg, flags);
+}
+
+
+int
+ath_recvmsg (int s, struct msghdr *msg, int flags)
+{
+  /* FIXME: GNU Pth is missing pth_recvmsg.  */
+  return recvmsg (s, msg, flags);
+}
+
diff --git a/libtdenetwork/libgpgme-copy/gpgme/ath-pthread-compat.c b/libtdenetwork/libgpgme-copy/gpgme/ath-pthread-compat.c
new file mode 100644
index 000000000..b65fa0514
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/ath-pthread-compat.c
@@ -0,0 +1,104 @@
+/* ath-pthread.c - pthread module for self-adapting thread-safeness library
+ *      Copyright (C) 2002 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
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include "ath.h"
+
+/* Need to include pthread_create in our check, as the GNU C library
+   has the pthread_mutex_* functions in their public interface.  */
+#pragma weak pthread_create
+#pragma weak pthread_mutex_init
+#pragma weak pthread_mutex_destroy
+#pragma weak pthread_mutex_lock
+#pragma weak pthread_mutex_unlock
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pthread_init (void **priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pthread_mutex_lock (&check_init_lock);
+  if (!*priv || !just_check)
+    {
+      pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
+      if (!lock)
+	err = ENOMEM;
+      if (!err)
+	{
+	  err = pthread_mutex_init (lock, NULL);
+	  if (err)
+	    free (lock);
+	  else
+	    *priv = lock;
+	}
+    }
+  if (just_check)
+    pthread_mutex_unlock (&check_init_lock);
+  return err;
+}
+
+
+static int
+mutex_pthread_destroy (void *priv)
+{
+  int err = pthread_mutex_destroy ((pthread_mutex_t *) priv);
+  free (priv);
+  return err;
+}
+
+
+static struct ath_ops ath_pthread_ops =
+  {
+    mutex_pthread_init,
+    mutex_pthread_destroy,
+    (int (*) (void *)) pthread_mutex_lock,
+    (int (*) (void *)) pthread_mutex_unlock,
+    NULL,	/* read */
+    NULL,	/* write */
+    NULL,	/* select */
+    NULL,	/* waitpid */
+    NULL,	/* accept */
+    NULL,	/* connect */
+    NULL,	/* sendmsg */
+    NULL	/* recvmsg */
+  };
+
+
+struct ath_ops *
+ath_pthread_available (void)
+{
+  /* Need to include pthread_create in our check, as the GNU C library
+     has the pthread_mutex_* functions in their public interface.  */
+  if (pthread_create
+      && pthread_mutex_init && pthread_mutex_destroy
+      && pthread_mutex_lock && pthread_mutex_unlock)
+    return &ath_pthread_ops;
+  else
+    return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/ath-pthread.c b/libtdenetwork/libgpgme-copy/gpgme/ath-pthread.c
new file mode 100644
index 000000000..5a70d2e43
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/ath-pthread.c
@@ -0,0 +1,175 @@
+/* ath-pthread.c - pthread module for self-adapting thread-safeness library
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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 <errno.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#else
+# include <sys/time.h>
+#endif
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <pthread.h>
+
+#include "ath.h"
+
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pthread_init (ath_mutex_t *priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pthread_mutex_lock (&check_init_lock);
+  if (!*priv || !just_check)
+    {
+      pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
+      if (!lock)
+	err = ENOMEM;
+      if (!err)
+	{
+	  err = pthread_mutex_init (lock, NULL);
+	  if (err)
+	    free (lock);
+	  else
+	    *priv = (ath_mutex_t) lock;
+	}
+    }
+  if (just_check)
+    pthread_mutex_unlock (&check_init_lock);
+  return err;
+}
+
+
+void
+ath_init (void)
+{
+  /* Nothing to do.  */
+}
+
+
+int
+ath_mutex_init (ath_mutex_t *lock)
+{
+  return mutex_pthread_init (lock, 0);
+}
+
+
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+  int err = mutex_pthread_init (lock, 1);
+  if (!err)
+    {
+      err = pthread_mutex_destroy ((pthread_mutex_t *) *lock);
+      free (*lock);
+    }
+  return err;
+}
+
+
+int
+ath_mutex_lock (ath_mutex_t *lock)
+{
+  int ret = mutex_pthread_init (lock, 1);
+  if (ret)
+    return ret;
+
+  return pthread_mutex_lock ((pthread_mutex_t *) *lock);
+}
+
+
+int
+ath_mutex_unlock (ath_mutex_t *lock)
+{
+  int ret = mutex_pthread_init (lock, 1);
+  if (ret)
+    return ret;
+
+  return pthread_mutex_unlock ((pthread_mutex_t *) *lock);
+}
+
+
+ssize_t
+ath_read (int fd, void *buf, size_t nbytes)
+{
+  return read (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_write (int fd, const void *buf, size_t nbytes)
+{
+  return write (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+	    struct timeval *timeout)
+{
+  return select (nfd, rset, wset, eset, timeout);
+}
+
+ 
+ssize_t
+ath_waitpid (pid_t pid, int *status, int options)
+{
+  return waitpid (pid, status, options);
+}
+
+
+int
+ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
+{
+  return accept (s, addr, length_ptr);
+}
+
+
+int
+ath_connect (int s, const struct sockaddr *addr, socklen_t length)
+{
+  return connect (s, addr, length);
+}
+
+int
+ath_sendmsg (int s, const struct msghdr *msg, int flags)
+{
+  return sendmsg (s, msg, flags);
+}
+
+
+int
+ath_recvmsg (int s, struct msghdr *msg, int flags)
+{
+  return recvmsg (s, msg, flags);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/ath.c b/libtdenetwork/libgpgme-copy/gpgme/ath.c
new file mode 100644
index 000000000..cb6d80d74
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/ath.c
@@ -0,0 +1,169 @@
+/* ath.c - Thread-safeness library.
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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 <assert.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#else
+# include <sys/time.h>
+#endif
+#include <sys/types.h>
+#ifndef HAVE_W32_SYSTEM
+#include <sys/wait.h>
+#endif
+
+#include "ath.h"
+
+
+#define MUTEX_UNLOCKED	((ath_mutex_t) 0)
+#define MUTEX_LOCKED	((ath_mutex_t) 1)
+#define MUTEX_DESTROYED	((ath_mutex_t) 2)
+
+
+int
+ath_mutex_init (ath_mutex_t *lock)
+{
+#ifndef NDEBUG
+  *lock = MUTEX_UNLOCKED;
+#endif
+  return 0;
+}
+
+
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+#ifndef NDEBUG
+  assert (*lock == MUTEX_UNLOCKED);
+
+  *lock = MUTEX_DESTROYED;
+#endif
+  return 0;
+}
+
+
+int
+ath_mutex_lock (ath_mutex_t *lock)
+{
+#ifndef NDEBUG
+  assert (*lock == MUTEX_UNLOCKED);
+
+  *lock = MUTEX_LOCKED;
+#endif
+  return 0;
+}
+
+
+int
+ath_mutex_unlock (ath_mutex_t *lock)
+{
+#ifndef NDEBUG
+  assert (*lock == MUTEX_LOCKED);
+
+  *lock = MUTEX_UNLOCKED;
+#endif
+  return 0;
+}
+
+
+ssize_t
+ath_read (int fd, void *buf, size_t nbytes)
+{
+  return read (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_write (int fd, const void *buf, size_t nbytes)
+{
+  return write (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+	    struct timeval *timeout)
+{
+#ifdef HAVE_W32_SYSTEM
+  return -1; /* Not supported. */
+#else
+  return select (nfd, rset, wset, eset, timeout);
+#endif
+}
+
+ 
+ssize_t
+ath_waitpid (pid_t pid, int *status, int options)
+{
+#ifdef HAVE_W32_SYSTEM
+  return -1; /* Not supported. */
+#else
+  return waitpid (pid, status, options);
+#endif
+}
+
+
+int
+ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
+{
+#ifdef HAVE_W32_SYSTEM
+  return -1; /* Not supported. */
+#else
+  return accept (s, addr, length_ptr);
+#endif
+}
+
+
+int
+ath_connect (int s, const struct sockaddr *addr, socklen_t length)
+{
+#ifdef HAVE_W32_SYSTEM
+  return -1; /* Not supported. */
+#else
+  return connect (s, addr, length);
+#endif
+}
+
+
+int
+ath_sendmsg (int s, const struct msghdr *msg, int flags)
+{
+#ifdef HAVE_W32_SYSTEM
+  return -1; /* Not supported. */
+#else
+  return sendmsg (s, msg, flags);
+#endif
+}
+
+
+int
+ath_recvmsg (int s, struct msghdr *msg, int flags)
+{
+#ifdef HAVE_W32_SYSTEM
+  return -1; /* Not supported. */
+#else
+  return recvmsg (s, msg, flags);
+#endif
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/ath.h b/libtdenetwork/libgpgme-copy/gpgme/ath.h
new file mode 100644
index 000000000..1a9be5d01
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/ath.h
@@ -0,0 +1,89 @@
+/* ath.h - Interfaces for thread-safeness library.
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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 ATH_H
+#define ATH_H
+
+#ifdef HAVE_W32_SYSTEM
+  /* fixme: Check how we did it in libgcrypt.  */
+  struct msghdr { int dummy; };
+  typedef int socklen_t;
+# include <windows.h>
+# include <io.h>
+
+#else /*!HAVE_W32_SYSTEM*/
+
+# ifdef HAVE_SYS_SELECT_H
+#  include <sys/select.h>
+# else
+#  include <sys/time.h>
+# endif
+# include <sys/types.h>
+# include <sys/socket.h>
+
+#endif  /*!HAVE_W32_SYSTEM*/
+
+
+
+/* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols
+   a prefix.  */
+#define _ATH_EXT_SYM_PREFIX _gpgme_
+
+#ifdef _ATH_EXT_SYM_PREFIX
+#define _ATH_PREFIX1(x,y) x ## y
+#define _ATH_PREFIX2(x,y) _ATH_PREFIX1(x,y)
+#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
+#define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
+#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
+#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
+#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
+#define ath_read _ATH_PREFIX(ath_read)
+#define ath_write _ATH_PREFIX(ath_write)
+#define ath_select _ATH_PREFIX(ath_select)
+#define ath_waitpid _ATH_PREFIX(ath_waitpid)
+#define ath_connect _ATH_PREFIX(ath_connect)
+#define ath_accept _ATH_PREFIX(ath_accept)
+#define ath_sendmsg _ATH_PREFIX(ath_sendmsg)
+#define ath_recvmsg _ATH_PREFIX(ath_recvmsg)
+#endif
+
+
+typedef void *ath_mutex_t;
+#define ATH_MUTEX_INITIALIZER 0;
+
+/* Functions for mutual exclusion.  */
+int ath_mutex_init (ath_mutex_t *mutex);
+int ath_mutex_destroy (ath_mutex_t *mutex);
+int ath_mutex_lock (ath_mutex_t *mutex);
+int ath_mutex_unlock (ath_mutex_t *mutex);
+
+/* Replacement for the POSIX functions, which can be used to allow
+   other (user-level) threads to run.  */
+ssize_t ath_read (int fd, void *buf, size_t nbytes);
+ssize_t ath_write (int fd, const void *buf, size_t nbytes);
+ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+		    struct timeval *timeout);
+ssize_t ath_waitpid (pid_t pid, int *status, int options);
+int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
+int ath_connect (int s, const struct sockaddr *addr, socklen_t length);
+int ath_sendmsg (int s, const struct msghdr *msg, int flags);
+int ath_recvmsg (int s, struct msghdr *msg, int flags);
+
+#endif	/* ATH_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/context.h b/libtdenetwork/libgpgme-copy/gpgme/context.h
new file mode 100644
index 000000000..e74b84c58
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/context.h
@@ -0,0 +1,118 @@
+/* context.h - Definitions for a GPGME context.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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 CONTEXT_H
+#define CONTEXT_H
+
+#include "gpgme.h"
+#include "engine.h"
+#include "wait.h"
+
+
+/* Operations might require to remember arbitrary information and data
+   objects during invocations of the status handler.  The
+   ctx_op_data structure provides a generic framework to hook in
+   such additional data.  */
+typedef enum
+  {
+    OPDATA_DECRYPT, OPDATA_SIGN, OPDATA_ENCRYPT, OPDATA_PASSPHRASE,
+    OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT,
+    OPDATA_VERIFY, OPDATA_TRUSTLIST
+  } ctx_op_data_id_t;
+
+
+struct ctx_op_data
+{
+  /* The next element in the linked list, or NULL if this is the last
+     element.  */
+  struct ctx_op_data *next;
+
+  /* The type of the hook data, which can be used by a routine to
+     lookup the hook data.  */
+  ctx_op_data_id_t type;
+
+  /* The function to release HOOK and all its associated resources.
+     Can be NULL if no special dealllocation routine is necessary.  */
+  void (*cleanup) (void *hook);
+
+  /* The hook that points to the operation data.  */
+  void *hook;
+};
+typedef struct ctx_op_data *ctx_op_data_t;
+
+
+/* The context defines an environment in which crypto operations can
+   be performed (sequentially).  */
+struct gpgme_context
+{
+  /* The engine info for this context.  */
+  gpgme_engine_info_t engine_info;
+
+  /* The protocol used by this context.  */
+  gpgme_protocol_t protocol;
+
+  /* The running engine process.  */
+  engine_t engine;
+
+  /* True if armor mode should be used.  */
+  unsigned int use_armor : 1;
+
+  /* True if text mode should be used.  */
+  unsigned int use_textmode : 1;
+
+  /* Flags for keylist mode.  */
+  gpgme_keylist_mode_t keylist_mode;
+
+  /* Number of certs to be included.  */
+  unsigned int include_certs;
+
+  /* The number of keys in signers.  */
+  unsigned int signers_len;
+
+  /* Size of the following array.  */
+  unsigned int signers_size;
+  gpgme_key_t *signers;
+
+  /* The signature notations for this context.  */
+  gpgme_sig_notation_t sig_notations;
+
+  /* The locale for the pinentry.  */
+  char *lc_ctype;
+  char *lc_messages;
+
+  /* The operation data hooked into the context.  */
+  ctx_op_data_t op_data;
+
+  /* The user provided passphrase callback and its hook value.  */
+  gpgme_passphrase_cb_t passphrase_cb;
+  void *passphrase_cb_value;
+
+  /* The user provided progress callback and its hook value.  */
+  gpgme_progress_cb_t progress_cb;
+  void *progress_cb_value;
+
+  /* A list of file descriptors in active use by the current
+     operation.  */
+  struct fd_table fdt;
+  struct gpgme_io_cbs io_cbs;
+};
+
+#endif	/* CONTEXT_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/conversion.c b/libtdenetwork/libgpgme-copy/gpgme/conversion.c
new file mode 100644
index 000000000..01e5cae7e
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/conversion.c
@@ -0,0 +1,414 @@
+/* conversion.c - String conversion helper functions.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "util.h"
+
+
+#define atoi_1(p)   (*(p) - '0' )
+#define atoi_2(p)   ((atoi_1(p) * 10) + atoi_1((p)+1))
+#define atoi_4(p)   ((atoi_2(p) * 100) + atoi_2((p)+2))
+
+
+
+/* Convert two hexadecimal digits from STR to the value they
+   represent.  Returns -1 if one of the characters is not a
+   hexadecimal digit.  */
+int
+_gpgme_hextobyte (const char *str)
+{
+  int val = 0;
+  int i;
+
+#define NROFHEXDIGITS 2
+  for (i = 0; i < NROFHEXDIGITS; i++)
+    {
+      if (*str >= '0' && *str <= '9')
+	val += *str - '0';
+      else if (*str >= 'A' && *str <= 'F')
+	val += 10 + *str - 'A';
+      else if (*str >= 'a' && *str <= 'f')
+	val += 10 + *str - 'a';
+      else
+	return -1;
+      if (i < NROFHEXDIGITS - 1)
+	val *= 16;
+      str++;
+    }
+  return val;
+}
+
+
+/* Decode the C formatted string SRC and store the result in the
+   buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
+   large enough buffer is allocated with malloc and *DESTP is set to
+   the result.  Currently, LEN is only used to specify if allocation
+   is desired or not, the caller is expected to make sure that *DESTP
+   is large enough if LEN is not zero.  */
+gpgme_error_t
+_gpgme_decode_c_string (const char *src, char **destp, size_t len)
+{
+  char *dest;
+
+  /* Set up the destination buffer.  */
+  if (len)
+    {
+      if (len < strlen (src) + 1)
+	return gpg_error (GPG_ERR_INTERNAL);
+
+      dest = *destp;
+    }
+  else
+    {
+      /* The converted string will never be larger than the original
+	 string.  */
+      dest = malloc (strlen (src) + 1);
+      if (!dest)
+	return gpg_error_from_errno (errno);
+
+      *destp = dest;
+    }
+
+  /* Convert the string.  */
+  while (*src)
+    {
+      if (*src != '\\')
+	{
+	  *(dest++) = *(src++);
+	  continue;
+	}
+
+      switch (src[1])
+	{
+#define DECODE_ONE(match,result)	\
+	case match:			\
+	  src += 2;			\
+	  *(dest++) = result;		\
+	  break;
+
+	  DECODE_ONE ('\'', '\'');
+	  DECODE_ONE ('\"', '\"');
+	  DECODE_ONE ('\?', '\?');
+	  DECODE_ONE ('\\', '\\');
+	  DECODE_ONE ('a', '\a');
+	  DECODE_ONE ('b', '\b');
+	  DECODE_ONE ('f', '\f');
+	  DECODE_ONE ('n', '\n');
+	  DECODE_ONE ('r', '\r');
+	  DECODE_ONE ('t', '\t');
+	  DECODE_ONE ('v', '\v');
+
+	case 'x':
+	  {
+	    int val = _gpgme_hextobyte (&src[2]);
+
+	    if (val == -1)
+	      {
+		/* Should not happen.  */
+		*(dest++) = *(src++);
+		*(dest++) = *(src++);
+		if (*src)
+		  *(dest++) = *(src++);
+		if (*src)
+		  *(dest++) = *(src++);
+	      }
+	    else
+	      {
+		if (!val)
+		  {
+		    /* A binary zero is not representable in a C
+		       string.  */
+		    *(dest++) = '\\';
+		    *(dest++) = '0'; 
+		  }
+		else 
+		  *((unsigned char *) dest++) = val;
+		src += 4;
+	      }
+	  }
+	  break;
+
+	default:
+	  {
+	    /* Should not happen.  */
+	    *(dest++) = *(src++);
+	    *(dest++) = *(src++);
+	  }
+        } 
+    }
+  *(dest++) = 0;
+
+  return 0;
+}
+
+
+/* Decode the percent escaped string SRC and store the result in the
+   buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
+   large enough buffer is allocated with malloc and *DESTP is set to
+   the result.  Currently, LEN is only used to specify if allocation
+   is desired or not, the caller is expected to make sure that *DESTP
+   is large enough if LEN is not zero.  If BINARY is 1, then '\0'
+   characters are allowed in the output.  */
+gpgme_error_t
+_gpgme_decode_percent_string (const char *src, char **destp, size_t len,
+			      int binary)
+{
+  char *dest;
+
+  /* Set up the destination buffer.  */
+  if (len)
+    {
+      if (len < strlen (src) + 1)
+	return gpg_error (GPG_ERR_INTERNAL);
+
+      dest = *destp;
+    }
+  else
+    {
+      /* The converted string will never be larger than the original
+	 string.  */
+      dest = malloc (strlen (src) + 1);
+      if (!dest)
+	return gpg_error_from_errno (errno);
+
+      *destp = dest;
+    }
+
+  /* Convert the string.  */
+  while (*src)
+    {
+      if (*src != '%')
+	{
+	  *(dest++) = *(src++);
+	  continue;
+	}
+      else
+	{
+	  int val = _gpgme_hextobyte (&src[1]);
+	  
+	  if (val == -1)
+	    {
+	      /* Should not happen.  */
+	      *(dest++) = *(src++);
+	      if (*src)
+		*(dest++) = *(src++);
+	      if (*src)
+		*(dest++) = *(src++);
+	    }
+	  else
+	    {
+	      if (!val && !binary)
+		{
+		  /* A binary zero is not representable in a C
+		     string.  */
+		  *(dest++) = '\\';
+		  *(dest++) = '0'; 
+		}
+	      else 
+		*((unsigned char *) dest++) = val;
+	      src += 3;
+	    }
+	}
+    }
+  *(dest++) = 0;
+
+  return 0;
+}
+
+
+/* Parse the string TIMESTAMP into a time_t.  The string may either be
+   seconds since Epoch or in the ISO 8601 format like
+   "20390815T143012".  Returns 0 for an empty string or seconds since
+   Epoch. Leading spaces are skipped. If ENDP is not NULL, it will
+   point to the next non-parsed character in TIMESTRING. */
+time_t
+_gpgme_parse_timestamp (const char *timestamp, char **endp)
+{
+  /* Need to skip leading spaces, because that is what strtoul does
+     but not our ISO 8601 checking code. */
+  while (*timestamp && *timestamp== ' ')
+    timestamp++;
+  if (!*timestamp)
+    return 0;
+
+  if (strlen (timestamp) >= 15 && timestamp[8] == 'T')
+    {
+      struct tm buf;
+      int year;
+
+      year = atoi_4 (timestamp);
+      if (year < 1900)
+        return (time_t)(-1);
+
+      /* Fixme: We would better use a configure test to see whether
+         mktime can handle dates beyond 2038. */
+      if (sizeof (time_t) <= 4 && year >= 2038)
+        return (time_t)2145914603; /* 2037-12-31 23:23:23 */
+
+      memset (&buf, 0, sizeof buf);
+      buf.tm_year = year - 1900;
+      buf.tm_mon = atoi_2 (timestamp+4) - 1; 
+      buf.tm_mday = atoi_2 (timestamp+6);
+      buf.tm_hour = atoi_2 (timestamp+9);
+      buf.tm_min = atoi_2 (timestamp+11);
+      buf.tm_sec = atoi_2 (timestamp+13);
+
+      if (endp)
+        *endp = (char*)(timestamp + 15);
+#ifdef HAVE_TIMEGM
+      return timegm (&buf);
+#else
+      {
+        time_t tim;
+        
+        putenv ("TZ=UTC");
+        tim = mktime (&buf);
+#ifdef __GNUC__
+#warning fixme: we must somehow reset TZ here.  It is not threadsafe anyway.
+#endif
+        return tim;
+      }
+#endif /* !HAVE_TIMEGM */
+    }
+  else
+    return (time_t)strtoul (timestamp, endp, 10);
+}
+
+
+
+
+static struct
+{
+  char *name;
+  gpgme_error_t err;
+} gnupg_errors[] =
+  {
+    { "EOF", GPG_ERR_EOF },
+    { "No_Error", GPG_ERR_NO_ERROR },
+    { "General_Error", GPG_ERR_GENERAL },
+    { "Out_Of_Core", GPG_ERR_ENOMEM },
+    { "Invalid_Value", GPG_ERR_INV_VALUE },
+    { "IO_Error", GPG_ERR_GENERAL },
+    { "Resource_Limit", GPG_ERR_RESOURCE_LIMIT },
+    { "Internal_Error", GPG_ERR_INTERNAL },
+    { "Bad_Certificate", GPG_ERR_BAD_CERT },
+    { "Bad_Certificate_Chain", GPG_ERR_BAD_CERT_CHAIN},
+    { "Missing_Certificate", GPG_ERR_MISSING_CERT },
+    { "No_Data", GPG_ERR_NO_DATA },
+    { "Bad_Signature", GPG_ERR_BAD_SIGNATURE },
+    { "Not_Implemented", GPG_ERR_NOT_IMPLEMENTED },
+    { "Conflict", GPG_ERR_CONFLICT },
+    { "Bug", GPG_ERR_BUG },
+    { "Read_Error", GPG_ERR_GENERAL },
+    { "Write_Error", GPG_ERR_GENERAL },
+    { "Invalid_Line", GPG_ERR_GENERAL },
+    { "Incomplete_Line", GPG_ERR_INCOMPLETE_LINE },
+    { "Invalid_Response", GPG_ERR_INV_RESPONSE },
+    { "Agent_Error", GPG_ERR_AGENT },
+    { "No_Public_Key", GPG_ERR_NO_PUBKEY },
+    { "No_Secret_Key", GPG_ERR_NO_SECKEY },
+    { "File_Open_Error", GPG_ERR_GENERAL },
+    { "File_Create_Error", GPG_ERR_GENERAL },
+    { "File_Error", GPG_ERR_GENERAL },
+    { "Not_Supported", GPG_ERR_NOT_SUPPORTED },
+    { "Invalid_Data", GPG_ERR_INV_DATA },
+    { "Assuan_Server_Fault", GPG_ERR_ASSUAN_SERVER_FAULT },
+    { "Assuan_Error", GPG_ERR_ASSUAN },
+    { "Invalid_Session_Key", GPG_ERR_INV_SESSION_KEY },
+    { "Invalid_Sexp", GPG_ERR_INV_SEXP },
+    { "Unsupported_Algorithm", GPG_ERR_UNSUPPORTED_ALGORITHM },
+    { "No_PIN_Entry", GPG_ERR_NO_PIN_ENTRY },
+    { "PIN_Entry_Error", GPG_ERR_NO_PIN_ENTRY },
+    { "Bad_PIN", GPG_ERR_BAD_PIN },
+    { "Bad_Passphrase", GPG_ERR_BAD_PASSPHRASE },
+    { "Invalid_Name", GPG_ERR_INV_NAME },
+    { "Bad_Public_Key", GPG_ERR_BAD_PUBKEY },
+    { "Bad_Secret_Key", GPG_ERR_BAD_SECKEY },
+    { "Bad_Data", GPG_ERR_BAD_DATA },
+    { "Invalid_Parameter", GPG_ERR_INV_PARAMETER },
+    { "Tribute_to_D_A", GPG_ERR_TRIBUTE_TO_D_A },
+    { "No_Dirmngr", GPG_ERR_NO_DIRMNGR },
+    { "Dirmngr_Error", GPG_ERR_DIRMNGR },
+    { "Certificate_Revoked", GPG_ERR_CERT_REVOKED },
+    { "No_CRL_Known", GPG_ERR_NO_CRL_KNOWN },
+    { "CRL_Too_Old", GPG_ERR_CRL_TOO_OLD },
+    { "Line_Too_Long", GPG_ERR_LINE_TOO_LONG },
+    { "Not_Trusted", GPG_ERR_NOT_TRUSTED },
+    { "Canceled", GPG_ERR_CANCELED },
+    { "Bad_CA_Certificate", GPG_ERR_BAD_CA_CERT },
+    { "Certificate_Expired", GPG_ERR_CERT_EXPIRED },
+    { "Certificate_Too_Young", GPG_ERR_CERT_TOO_YOUNG },
+    { "Unsupported_Certificate", GPG_ERR_UNSUPPORTED_CERT },
+    { "Unknown_Sexp", GPG_ERR_UNKNOWN_SEXP },
+    { "Unsupported_Protection", GPG_ERR_UNSUPPORTED_PROTECTION },
+    { "Corrupted_Protection", GPG_ERR_CORRUPTED_PROTECTION },
+    { "Ambiguous_Name", GPG_ERR_AMBIGUOUS_NAME },
+    { "Card_Error", GPG_ERR_CARD },
+    { "Card_Reset", GPG_ERR_CARD_RESET },
+    { "Card_Removed", GPG_ERR_CARD_REMOVED },
+    { "Invalid_Card", GPG_ERR_INV_CARD },
+    { "Card_Not_Present", GPG_ERR_CARD_NOT_PRESENT },
+    { "No_PKCS15_App", GPG_ERR_NO_PKCS15_APP },
+    { "Not_Confirmed", GPG_ERR_NOT_CONFIRMED },
+    { "Configuration_Error", GPG_ERR_CONFIGURATION },
+    { "No_Policy_Match", GPG_ERR_NO_POLICY_MATCH },
+    { "Invalid_Index", GPG_ERR_INV_INDEX },
+    { "Invalid_Id", GPG_ERR_INV_ID },
+    { "No_Scdaemon", GPG_ERR_NO_SCDAEMON },
+    { "Scdaemon_Error", GPG_ERR_SCDAEMON },
+    { "Unsupported_Protocol", GPG_ERR_UNSUPPORTED_PROTOCOL },
+    { "Bad_PIN_Method", GPG_ERR_BAD_PIN_METHOD },
+    { "Card_Not_Initialized", GPG_ERR_CARD_NOT_INITIALIZED },
+    { "Unsupported_Operation", GPG_ERR_UNSUPPORTED_OPERATION },
+    { "Wrong_Key_Usage", GPG_ERR_WRONG_KEY_USAGE }
+  };
+    
+
+gpgme_error_t
+_gpgme_map_gnupg_error (char *err)
+{
+  unsigned int i;
+
+  /* Future version of GnuPG might return the error code directly, so
+     we first test for a a numerical value and use that verbatim.
+     Note that this numerical value might be followed by an
+     underschore and the textual representation of the error code. */
+  if (*err >= '0' && *err <= '9')
+    return strtoul (err, NULL, 10);
+
+  /* Well, this is a token, use the mapping table to get the error.
+     The drawback is that we won't receive an error source and have to
+     use GPG as source. */
+  for (i = 0; i < DIM (gnupg_errors); i++)
+    if (!strcmp (gnupg_errors[i].name, err))
+      return gpg_err_make (GPG_ERR_SOURCE_GPG, gnupg_errors[i].err);
+
+  return gpg_err_make (GPG_ERR_SOURCE_GPG, GPG_ERR_GENERAL);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/data-compat.c b/libtdenetwork/libgpgme-copy/gpgme/data-compat.c
new file mode 100644
index 000000000..37cb4ff55
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/data-compat.c
@@ -0,0 +1,209 @@
+/* data-compat.c - Compatibility interfaces for data objects.
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "data.h"
+#include "util.h"
+
+
+/* Create a new data buffer filled with LENGTH bytes starting from
+   OFFSET within the file FNAME or stream STREAM (exactly one must be
+   non-zero).  */
+gpgme_error_t
+gpgme_data_new_from_filepart (gpgme_data_t *dh, const char *fname,
+			      FILE *stream, off_t offset, size_t length)
+{
+  gpgme_error_t err;
+  char *buf = NULL;
+  int res;
+
+  if (stream && fname)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (fname)
+    stream = fopen (fname, "rb");
+  if (!stream)
+    return gpg_error_from_errno (errno);
+
+#ifdef HAVE_FSEEKO
+  res = fseeko (stream, offset, SEEK_SET);
+#else
+  /* FIXME: Check for overflow, or at least bail at compilation.  */
+  res = fseek (stream, offset, SEEK_SET);
+#endif
+
+  if (res)
+    {
+      int saved_errno = errno;
+      if (fname)
+	fclose (stream);
+      return gpg_error_from_errno (saved_errno);
+    }
+
+  buf = malloc (length);
+  if (!buf)
+    {
+      int saved_errno = errno;
+      if (fname)
+	fclose (stream);
+      return gpg_error_from_errno (saved_errno);
+    }
+
+  while (fread (buf, length, 1, stream) < 1
+	 && ferror (stream) && errno == EINTR);
+  if (ferror (stream))
+    {
+      int saved_errno = errno;
+      if (buf)
+	free (buf);
+      if (fname)
+	fclose (stream);
+      return gpg_error_from_errno (saved_errno);
+    }
+
+  if (fname)
+    fclose (stream);
+
+  err = gpgme_data_new (dh);
+  if (err)
+    {
+      if (buf)
+	free (buf);
+      return err;
+    }
+
+  (*dh)->data.mem.buffer = buf;
+  (*dh)->data.mem.size = length;
+  (*dh)->data.mem.length = length;
+  return 0;
+}
+
+
+/* Create a new data buffer filled with the content of file FNAME.
+   COPY must be non-zero (delayed reads are not supported yet).  */
+gpgme_error_t
+gpgme_data_new_from_file (gpgme_data_t *dh, const char *fname, int copy)
+{
+  struct stat statbuf;
+
+  if (!fname || !copy)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (stat (fname, &statbuf) < 0)
+    return gpg_error_from_errno (errno);
+
+  return gpgme_data_new_from_filepart (dh, fname, NULL, 0, statbuf.st_size);
+}
+
+
+static int
+gpgme_error_to_errno (gpgme_error_t err)
+{
+  int no = gpg_err_code_to_errno (err);
+
+  if (no)
+    {
+      errno = no;
+      return -1;
+    }
+
+  switch (gpg_err_code (err))
+    {
+    case GPG_ERR_EOF:
+      return 0;
+    case GPG_ERR_INV_VALUE:
+      errno = EINVAL;
+      return -1;
+    case GPG_ERR_NOT_SUPPORTED:
+      errno = ENOSYS;
+      return -1;
+    default:
+      /* FIXME: Yeah, well.  */
+      errno = EINVAL;
+      return -1;
+    }
+}
+
+
+static ssize_t
+old_user_read (gpgme_data_t dh, void *buffer, size_t size)
+{
+  size_t amt;
+  gpgme_error_t err = (*dh->data.old_user.cb) (dh->data.old_user.handle,
+					       buffer, size, &amt);
+  if (err)
+    return gpgme_error_to_errno (err);
+  return amt;
+}
+
+
+static off_t
+old_user_seek (gpgme_data_t dh, off_t offset, int whence)
+{
+  gpgme_error_t err;
+  if (whence != SEEK_SET || offset)
+    return EINVAL;
+  err = (*dh->data.old_user.cb) (dh->data.old_user.handle, NULL, 0, NULL);
+  if (err)
+    return gpgme_error_to_errno (err);
+  return 0;
+}
+
+
+static struct _gpgme_data_cbs old_user_cbs =
+  {
+    old_user_read,
+    NULL,
+    old_user_seek,
+    NULL
+  };
+
+
+/* Create a new data buffer which retrieves the data from the callback
+   function READ_CB.  */
+gpgme_error_t
+gpgme_data_new_with_read_cb (gpgme_data_t *dh,
+                             int (*read_cb) (void *, char *, size_t, size_t *),
+                             void *read_cb_value)
+{
+  gpgme_error_t err = _gpgme_data_new (dh, &old_user_cbs);
+  if (err)
+    return err;
+
+  (*dh)->data.old_user.cb = read_cb;
+  (*dh)->data.old_user.handle = read_cb_value;
+  return 0;
+}
+
+
+gpgme_error_t
+gpgme_data_rewind (gpgme_data_t dh)
+{
+  return (gpgme_data_seek (dh, 0, SEEK_SET) == -1)
+    ? gpg_error_from_errno (errno) : 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/data-fd.c b/libtdenetwork/libgpgme-copy/gpgme/data-fd.c
new file mode 100644
index 000000000..b543a770d
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/data-fd.c
@@ -0,0 +1,78 @@
+/* data-fd.c - A file descripor based data object.
+   Copyright (C) 2002, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "data.h"
+
+
+static ssize_t
+fd_read (gpgme_data_t dh, void *buffer, size_t size)
+{
+  return read (dh->data.fd, buffer, size);
+}
+
+
+static ssize_t
+fd_write (gpgme_data_t dh, const void *buffer, size_t size)
+{
+  return write (dh->data.fd, buffer, size);
+}
+
+
+static off_t
+fd_seek (gpgme_data_t dh, off_t offset, int whence)
+{
+  return lseek (dh->data.fd, offset, whence);
+}
+
+
+static int
+fd_get_fd (gpgme_data_t dh)
+{
+  return (dh->data.fd);
+}
+
+
+static struct _gpgme_data_cbs fd_cbs =
+  {
+    fd_read,
+    fd_write,
+    fd_seek,
+    NULL,
+    fd_get_fd
+  };
+
+
+gpgme_error_t
+gpgme_data_new_from_fd (gpgme_data_t *dh, int fd)
+{
+  gpgme_error_t err = _gpgme_data_new (dh, &fd_cbs);
+  if (err)
+    return err;
+
+  (*dh)->data.fd = fd;
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/data-mem.c b/libtdenetwork/libgpgme-copy/gpgme/data-mem.c
new file mode 100644
index 000000000..3f9bc95c1
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/data-mem.c
@@ -0,0 +1,251 @@
+/* data-mem.c - A memory based data object.
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+
+#include "data.h"
+#include "util.h"
+
+
+static ssize_t
+mem_read (gpgme_data_t dh, void *buffer, size_t size)
+{
+  size_t amt = dh->data.mem.length - dh->data.mem.offset;
+  const char *src;
+
+  if (!amt)
+    return 0;
+
+  if (size < amt)
+    amt = size;
+
+  src = dh->data.mem.buffer ? dh->data.mem.buffer : dh->data.mem.orig_buffer;
+  memcpy (buffer, src + dh->data.mem.offset, amt);
+  dh->data.mem.offset += amt;
+  return amt;
+}
+
+
+static ssize_t
+mem_write (gpgme_data_t dh, const void *buffer, size_t size)
+{
+  size_t unused;
+
+  if (!dh->data.mem.buffer && dh->data.mem.orig_buffer)
+    {
+      size_t new_size = dh->data.mem.size;
+      char *new_buffer;
+
+      if (new_size < dh->data.mem.offset + size)
+	new_size = dh->data.mem.offset + size;
+
+      new_buffer = malloc (new_size);
+      if (!new_buffer)
+	return -1;
+      memcpy (new_buffer, dh->data.mem.orig_buffer, dh->data.mem.length);
+
+      dh->data.mem.buffer = new_buffer;      
+      dh->data.mem.size = new_size;
+    }
+
+  unused = dh->data.mem.size - dh->data.mem.offset;
+  if (unused < size)
+    {
+      /* Allocate a large enough buffer with exponential backoff.  */
+#define INITIAL_ALLOC 512
+      size_t new_size = dh->data.mem.size
+	? (2 * dh->data.mem.size) : INITIAL_ALLOC;
+      char *new_buffer;
+
+      if (new_size < dh->data.mem.offset + size)
+	new_size = dh->data.mem.offset + size;
+
+      new_buffer = realloc (dh->data.mem.buffer, new_size);
+      if (!new_buffer && new_size > dh->data.mem.offset + size)
+	{
+	  /* Maybe we were too greedy, try again.  */
+	  new_size = dh->data.mem.offset + size;
+	  new_buffer = realloc (dh->data.mem.buffer, new_size);
+	}
+      if (!new_buffer)
+	return -1;
+      dh->data.mem.buffer = new_buffer;
+      dh->data.mem.size = new_size;
+    }
+
+  memcpy (dh->data.mem.buffer + dh->data.mem.offset, buffer, size);
+  dh->data.mem.offset += size;
+  if (dh->data.mem.length < dh->data.mem.offset)
+    dh->data.mem.length = dh->data.mem.offset;
+  return size;
+}
+
+
+static off_t
+mem_seek (gpgme_data_t dh, off_t offset, int whence)
+{
+  switch (whence)
+    {
+    case SEEK_SET:
+      if (offset < 0 || offset > dh->data.mem.length)
+	{
+	  errno = EINVAL;
+	  return -1;
+	}
+      dh->data.mem.offset = offset;
+      break;
+    case SEEK_CUR:
+      if ((offset > 0 && dh->data.mem.length - dh->data.mem.offset < offset)
+	  || (offset < 0 && dh->data.mem.offset < -offset)) 
+	{
+	  errno = EINVAL;
+	  return -1;
+	}
+      dh->data.mem.offset += offset;
+      break;
+    case SEEK_END:
+      if (offset > 0 || -offset > dh->data.mem.length)
+	{
+	  errno = EINVAL;
+	  return -1;
+	}
+      dh->data.mem.offset = dh->data.mem.length - offset;
+      break;
+    default:
+      errno = EINVAL;
+      return -1;
+    }
+  return dh->data.mem.offset;
+}
+
+
+static void
+mem_release (gpgme_data_t dh)
+{
+  if (dh->data.mem.buffer)
+    free (dh->data.mem.buffer);
+}
+
+
+static struct _gpgme_data_cbs mem_cbs =
+  {
+    mem_read,
+    mem_write,
+    mem_seek,
+    mem_release,
+    NULL
+  };
+
+
+/* Create a new data buffer and return it in R_DH.  */
+gpgme_error_t
+gpgme_data_new (gpgme_data_t *dh)
+{
+  gpgme_error_t err = _gpgme_data_new (dh, &mem_cbs);
+  if (err)
+    return err;
+
+  return 0;
+}
+
+
+/* Create a new data buffer filled with SIZE bytes starting from
+   BUFFER.  If COPY is zero, copying is delayed until necessary, and
+   the data is taken from the original location when needed.  */
+gpgme_error_t
+gpgme_data_new_from_mem (gpgme_data_t *dh, const char *buffer,
+			 size_t size, int copy)
+{
+  gpgme_error_t err = _gpgme_data_new (dh, &mem_cbs);
+  if (err)
+    return err;
+
+  if (copy)
+    {
+      char *bufcpy = malloc (size);
+      if (!bufcpy)
+	_gpgme_data_release (*dh);
+      memcpy (bufcpy, buffer, size);
+      (*dh)->data.mem.buffer = bufcpy;
+    }
+  else
+    (*dh)->data.mem.orig_buffer = buffer;
+  
+  (*dh)->data.mem.size = size;
+  (*dh)->data.mem.length = size;
+  return 0;
+}
+
+
+/* Destroy the data buffer DH and return a pointer to its content.
+   The memory has be to released with gpgme_free() by the user.  It's
+   size is returned in R_LEN.  */
+char *
+gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
+{
+  char *str = NULL;
+
+  if (!dh || dh->cbs != &mem_cbs)
+    {
+      gpgme_data_release (dh);
+      return NULL;
+    }
+
+  str = dh->data.mem.buffer;
+  if (!str && dh->data.mem.orig_buffer)
+    {
+      str = malloc (dh->data.mem.length);
+      if (!str)
+	{
+	  gpgme_data_release (dh);
+	  return NULL;
+	}
+      memcpy (str, dh->data.mem.orig_buffer, dh->data.mem.length);
+    }
+  else
+    /* Prevent mem_release from releasing the buffer memory.  We must
+       not fail from this point.  */
+    dh->data.mem.buffer = NULL;
+
+  if (r_len)
+    *r_len = dh->data.mem.length;
+
+  gpgme_data_release (dh);
+
+  return str;
+}
+
+
+/* Release the memory returned by gpgme_data_release_and_get_mem().  */
+void
+gpgme_free (void *buffer)
+{
+  if (buffer)
+    free (buffer);
+}
+
diff --git a/libtdenetwork/libgpgme-copy/gpgme/data-stream.c b/libtdenetwork/libgpgme-copy/gpgme/data-stream.c
new file mode 100644
index 000000000..eb8768d3c
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/data-stream.c
@@ -0,0 +1,101 @@
+/* data-stream.c - A stream based data object.
+   Copyright (C) 2002, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "data.h"
+
+
+static ssize_t
+stream_read (gpgme_data_t dh, void *buffer, size_t size)
+{
+  size_t amt = fread (buffer, 1, size, dh->data.stream);
+  if (amt > 0)
+    return amt;
+  return ferror (dh->data.stream) ? -1 : 0;
+}
+
+
+static ssize_t
+stream_write (gpgme_data_t dh, const void *buffer, size_t size)
+{
+  size_t amt = fwrite (buffer, 1, size, dh->data.stream);
+  if (amt > 0)
+    return amt;
+  return ferror (dh->data.stream) ? -1 : 0;
+}
+
+
+static off_t
+stream_seek (gpgme_data_t dh, off_t offset, int whence)
+{
+  int err;
+
+#ifdef HAVE_FSEEKO
+  err = fseeko (dh->data.stream, offset, whence);
+#else
+  /* FIXME: Check for overflow, or at least bail at compilation.  */
+  err = fseek (dh->data.stream, offset, whence);
+#endif
+
+  if (err)
+    return -1;
+
+#ifdef HAVE_FSEEKO
+  return ftello (dh->data.stream);
+#else
+  return ftell (dh->data.stream);
+#endif
+}
+
+
+static int
+stream_get_fd (gpgme_data_t dh)
+{
+  fflush (dh->data.stream);
+  return fileno (dh->data.stream);
+}
+
+
+static struct _gpgme_data_cbs stream_cbs =
+  {
+    stream_read,
+    stream_write,
+    stream_seek,
+    NULL,
+    stream_get_fd
+  };
+
+
+gpgme_error_t
+gpgme_data_new_from_stream (gpgme_data_t *dh, FILE *stream)
+{
+  gpgme_error_t err = _gpgme_data_new (dh, &stream_cbs);
+  if (err)
+    return err;
+
+  (*dh)->data.stream = stream;
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/data-user.c b/libtdenetwork/libgpgme-copy/gpgme/data-user.c
new file mode 100644
index 000000000..d33d71a06
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/data-user.c
@@ -0,0 +1,89 @@
+/* data-user.c - A user callback based data object.
+   Copyright (C) 2002, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+
+#include "data.h"
+
+
+static ssize_t
+user_read (gpgme_data_t dh, void *buffer, size_t size)
+{
+  if (!dh->data.user.cbs->read)
+    return EBADF;
+
+  return (*dh->data.user.cbs->read) (dh->data.user.handle, buffer, size);
+}
+
+
+static ssize_t
+user_write (gpgme_data_t dh, const void *buffer, size_t size)
+{
+  if (!dh->data.user.cbs->write)
+    return EBADF;
+
+  return (*dh->data.user.cbs->write) (dh->data.user.handle, buffer, size);
+}
+
+
+static off_t
+user_seek (gpgme_data_t dh, off_t offset, int whence)
+{
+  if (!dh->data.user.cbs->seek)
+    return EBADF;
+
+  return (*dh->data.user.cbs->seek) (dh->data.user.handle, offset, whence);
+}
+
+
+static void
+user_release (gpgme_data_t dh)
+{
+  if (dh->data.user.cbs->release)
+    (*dh->data.user.cbs->release) (dh->data.user.handle);
+}
+
+
+static struct _gpgme_data_cbs user_cbs =
+  {
+    user_read,
+    user_write,
+    user_seek,
+    user_release,
+    NULL
+  };
+
+
+gpgme_error_t
+gpgme_data_new_from_cbs (gpgme_data_t *dh, gpgme_data_cbs_t cbs, void *handle)
+{
+  gpgme_error_t err = _gpgme_data_new (dh, &user_cbs);
+  if (err)
+    return err;
+
+  (*dh)->data.user.cbs = cbs;
+  (*dh)->data.user.handle = handle;
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/data.c b/libtdenetwork/libgpgme-copy/gpgme/data.c
new file mode 100644
index 000000000..6ffae324e
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/data.c
@@ -0,0 +1,293 @@
+/* data.c - An abstraction for data objects.
+   Copyright (C) 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include "gpgme.h"
+#include "data.h"
+#include "util.h"
+#include "ops.h"
+#include "priv-io.h"
+
+
+gpgme_error_t
+_gpgme_data_new (gpgme_data_t *r_dh, struct _gpgme_data_cbs *cbs)
+{
+  gpgme_data_t dh;
+
+  if (!r_dh)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  *r_dh = NULL;
+  dh = calloc (1, sizeof (*dh));
+  if (!dh)
+    return gpg_error_from_errno (errno);
+
+  dh->cbs = cbs;
+
+  *r_dh = dh;
+  return 0;
+}
+
+
+void
+_gpgme_data_release (gpgme_data_t dh)
+{
+  if (!dh)
+    return;
+
+  if (dh->file_name)
+    free (dh->file_name);
+  free (dh);
+}
+
+
+/* Read up to SIZE bytes into buffer BUFFER from the data object with
+   the handle DH.  Return the number of characters read, 0 on EOF and
+   -1 on error.  If an error occurs, errno is set.  */
+ssize_t
+gpgme_data_read (gpgme_data_t dh, void *buffer, size_t size)
+{
+  if (!dh)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  if (!dh->cbs->read)
+    {
+      errno = ENOSYS;
+      return -1;
+    }
+  return (*dh->cbs->read) (dh, buffer, size);
+}
+
+
+/* Write up to SIZE bytes from buffer BUFFER to the data object with
+   the handle DH.  Return the number of characters written, or -1 on
+   error.  If an error occurs, errno is set.  */
+ssize_t
+gpgme_data_write (gpgme_data_t dh, const void *buffer, size_t size)
+{
+  if (!dh)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  if (!dh->cbs->write)
+    {
+      errno = ENOSYS;
+      return -1;
+    }
+  return (*dh->cbs->write) (dh, buffer, size);
+}
+
+
+/* Set the current position from where the next read or write starts
+   in the data object with the handle DH to OFFSET, relativ to
+   WHENCE.  */
+off_t
+gpgme_data_seek (gpgme_data_t dh, off_t offset, int whence)
+{
+  if (!dh)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  if (!dh->cbs->seek)
+    {
+      errno = ENOSYS;
+      return -1;
+    }
+
+  /* For relative movement, we must take into account the actual
+     position of the read counter.  */
+  if (whence == SEEK_CUR)
+    offset -= dh->pending_len;
+
+  offset = (*dh->cbs->seek) (dh, offset, whence);
+  if (offset >= 0)
+    dh->pending_len = 0;
+
+  return offset;
+}
+
+
+/* Release the data object with the handle DH.  */
+void
+gpgme_data_release (gpgme_data_t dh)
+{
+  if (!dh)
+    return;
+
+  if (dh->cbs->release)
+    (*dh->cbs->release) (dh);
+  _gpgme_data_release (dh);
+}
+
+
+/* Get the current encoding meta information for the data object with
+   handle DH.  */
+gpgme_data_encoding_t
+gpgme_data_get_encoding (gpgme_data_t dh)
+{
+  return dh ? dh->encoding : GPGME_DATA_ENCODING_NONE;
+}
+
+
+/* Set the encoding meta information for the data object with handle
+   DH to ENC.  */
+gpgme_error_t
+gpgme_data_set_encoding (gpgme_data_t dh, gpgme_data_encoding_t enc)
+{
+  if (!dh)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (enc < 0 || enc > GPGME_DATA_ENCODING_ARMOR)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  dh->encoding = enc;
+  return 0;
+}
+
+
+/* Set the file name associated with the data object with handle DH to
+   FILE_NAME.  */
+gpgme_error_t
+gpgme_data_set_file_name (gpgme_data_t dh, const char *file_name)
+{
+  if (!dh)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (dh->file_name)
+    free (dh->file_name);
+
+  if (file_name)
+    {
+      dh->file_name = strdup (file_name);
+      if (!dh->file_name)
+	return gpg_error_from_errno (errno);
+    }
+  else
+    dh->file_name = 0;
+
+  return 0;
+}
+
+/* Get the file name associated with the data object with handle DH,
+   or NULL if there is none.  */
+char *
+gpgme_data_get_file_name (gpgme_data_t dh)
+{
+  if (!dh)
+    return NULL;
+
+  return dh->file_name;
+}
+
+
+/* Functions to support the wait interface.  */
+
+gpgme_error_t
+_gpgme_data_inbound_handler (void *opaque, int fd)
+{
+  gpgme_data_t dh = (gpgme_data_t) opaque;
+  char buffer[BUFFER_SIZE];
+  char *bufp = buffer;
+  ssize_t buflen;
+
+  buflen = _gpgme_io_read (fd, buffer, BUFFER_SIZE);
+  if (buflen < 0)
+    return gpg_error_from_errno (errno);
+  if (buflen == 0)
+    {
+      _gpgme_io_close (fd);
+      return 0;
+    }
+
+  do
+    {
+      ssize_t amt = gpgme_data_write (dh, bufp, buflen);
+      if (amt == 0 || (amt < 0 && errno != EINTR))
+	return gpg_error_from_errno (errno);
+      bufp += amt;
+      buflen -= amt;
+    }
+  while (buflen > 0);
+  return 0;
+}
+
+
+gpgme_error_t
+_gpgme_data_outbound_handler (void *opaque, int fd)
+{
+  gpgme_data_t dh = (gpgme_data_t) opaque;
+  ssize_t nwritten;
+
+  if (!dh->pending_len)
+    {
+      ssize_t amt = gpgme_data_read (dh, dh->pending, BUFFER_SIZE);
+      if (amt < 0)
+	return gpg_error_from_errno (errno);
+      if (amt == 0)
+	{
+	  _gpgme_io_close (fd);
+	  return 0;
+	}
+      dh->pending_len = amt;
+    }
+
+  nwritten = _gpgme_io_write (fd, dh->pending, dh->pending_len);
+  if (nwritten == -1 && errno == EAGAIN)
+    return 0;
+
+  if (nwritten == -1 && errno == EPIPE)
+    {
+      /* Not much we can do.  The other end closed the pipe, but we
+	 still have data.  This should only ever happen if the other
+	 end is going to tell us what happened on some other channel.
+	 Silently close our end.  */
+      _gpgme_io_close (fd);
+      return 0;
+    }
+
+  if (nwritten <= 0)
+    return gpg_error_from_errno (errno);
+
+  if (nwritten < dh->pending_len)
+    memmove (dh->pending, dh->pending + nwritten, dh->pending_len - nwritten);
+  dh->pending_len -= nwritten;
+  return 0;
+}
+
+
+/* Get the file descriptor associated with DH, if possible.  Otherwise
+   return -1.  */
+int
+_gpgme_data_get_fd (gpgme_data_t dh)
+{
+  if (!dh || !dh->cbs->get_fd)
+    return -1;
+  return (*dh->cbs->get_fd) (dh);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/data.h b/libtdenetwork/libgpgme-copy/gpgme/data.h
new file mode 100644
index 000000000..984c1e1fb
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/data.h
@@ -0,0 +1,132 @@
+/* data.h - Internal data object abstraction interface.
+   Copyright (C) 2002, 2004, 2005 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 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.
+   
+   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
+   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 DATA_H
+#define DATA_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <limits.h>
+
+#include "gpgme.h"
+
+
+/* Read up to SIZE bytes into buffer BUFFER from the data object with
+   the handle DH.  Return the number of characters read, 0 on EOF and
+   -1 on error.  If an error occurs, errno is set.  */
+typedef ssize_t (*gpgme_data_read_cb) (gpgme_data_t dh, void *buffer,
+				       size_t size);
+
+/* Write up to SIZE bytes from buffer BUFFER to the data object with
+   the handle DH.  Return the number of characters written, or -1 on
+   error.  If an error occurs, errno is set.  */
+typedef ssize_t (*gpgme_data_write_cb) (gpgme_data_t dh, const void *buffer,
+					size_t size);
+
+/* Set the current position from where the next read or write starts
+   in the data object with the handle DH to OFFSET, relativ to
+   WHENCE.  */
+typedef off_t (*gpgme_data_seek_cb) (gpgme_data_t dh, off_t offset,
+				     int whence);
+
+/* Release the data object with the handle DH.  */
+typedef void (*gpgme_data_release_cb) (gpgme_data_t dh);
+
+/* Get the FD associated with the handle DH, or -1.  */
+typedef int (*gpgme_data_get_fd_cb) (gpgme_data_t dh);
+
+struct _gpgme_data_cbs
+{
+  gpgme_data_read_cb read;
+  gpgme_data_write_cb write;
+  gpgme_data_seek_cb seek;
+  gpgme_data_release_cb release;
+  gpgme_data_get_fd_cb get_fd;
+};
+
+struct gpgme_data
+{
+  struct _gpgme_data_cbs *cbs;
+  gpgme_data_encoding_t encoding;
+
+#ifdef PIPE_BUF
+#define BUFFER_SIZE PIPE_BUF
+#else
+#ifdef _POSIX_PIPE_BUF
+#define BUFFER_SIZE _POSIX_PIPE_BUF
+#else
+#define BUFFER_SIZE 512
+#endif
+#endif
+  char pending[BUFFER_SIZE];
+  int pending_len;
+
+  /* File name of the data object.  */
+  char *file_name;
+
+  union
+  {
+    /* For gpgme_data_new_from_fd.  */
+    int fd;
+
+    /* For gpgme_data_new_from_stream.  */
+    FILE *stream;
+
+    /* For gpgme_data_new_from_cbs.  */
+    struct
+    {
+      gpgme_data_cbs_t cbs;
+      void *handle;
+    } user;
+
+    /* For gpgme_data_new_from_mem.  */
+    struct
+    {
+      char *buffer;
+      const char *orig_buffer;
+      /* Allocated size of BUFFER.  */
+      size_t size;
+      size_t length;
+      off_t offset;
+    } mem;
+
+    /* For gpgme_data_new_from_read_cb.  */
+    struct
+    {
+      int (*cb) (void *, char *, size_t, size_t *);
+      void *handle;
+    } old_user;
+  } data;
+};
+
+
+gpgme_error_t _gpgme_data_new (gpgme_data_t *r_dh,
+			       struct _gpgme_data_cbs *cbs);
+
+void _gpgme_data_release (gpgme_data_t dh);
+
+/* Get the file descriptor associated with DH, if possible.  Otherwise
+   return -1.  */
+int _gpgme_data_get_fd (gpgme_data_t dh);
+
+#endif	/* DATA_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/debug.c b/libtdenetwork/libgpgme-copy/gpgme/debug.c
new file mode 100644
index 000000000..3351059e1
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/debug.c
@@ -0,0 +1,221 @@
+/* debug.c - helpful output in desperate situations
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <ctype.h>
+#ifndef HAVE_DOSISH_SYSTEM
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <fcntl.h>
+#endif
+#include <assert.h>
+
+#include "util.h"
+#include "sema.h"
+
+
+/* Lock to serialize initialization of the debug output subsystem and
+   output of actual debug messages.  */
+DEFINE_STATIC_LOCK (debug_lock);
+
+/* The amount of detail requested by the user, per environment
+   variable GPGME_DEBUG.  */
+static int debug_level;
+
+/* The output stream for the debug messages.  */
+static FILE *errfp;
+
+
+/* Remove leading and trailing white spaces.  */
+static char *
+trim_spaces (char *str)
+{
+  char *string, *p, *mark;
+
+  string = str;
+  /* Find first non space character.  */
+  for (p = string; *p && isspace (*(unsigned char *) p); p++)
+    ;
+  /* Move characters.  */
+  for (mark = NULL; (*string = *p); string++, p++)
+    if (isspace (*(unsigned char *) p))
+      {
+	if (!mark)
+	  mark = string;
+      }
+    else
+      mark = NULL;
+  if (mark)
+    *mark = '\0';	/* Remove trailing spaces.  */
+
+  return str;
+}
+
+
+static void
+debug_init (void)
+{
+  static int initialized;
+
+  LOCK (debug_lock);
+  if (!initialized)
+    {
+      gpgme_error_t err;
+      char *e;
+      const char *s1, *s2;;
+
+      err = _gpgme_getenv ("GPGME_DEBUG", &e);
+      if (err)
+	{
+	  UNLOCK (debug_lock);
+	  return;
+	}
+
+      initialized = 1;
+      errfp = stderr;
+      if (e)
+	{
+	  debug_level = atoi (e);
+	  s1 = strchr (e, PATHSEP_C);
+	  if (s1)
+	    {
+#ifndef HAVE_DOSISH_SYSTEM
+	      if (getuid () == geteuid ())
+		{
+#endif
+		  char *p;
+		  FILE *fp;
+
+		  s1++;
+		  if (!(s2 = strchr (s1, PATHSEP_C)))
+		    s2 = s1 + strlen (s1);
+		  p = malloc (s2 - s1 + 1);
+		  if (p)
+		    {
+		      memcpy (p, s1, s2 - s1);
+		      p[s2-s1] = 0;
+		      trim_spaces (p);
+		      fp = fopen (p,"a");
+		      if (fp)
+			{
+			  setvbuf (fp, NULL, _IOLBF, 0);
+			  errfp = fp;
+			}
+		      free (p);
+		    }
+#ifndef HAVE_DOSISH_SYSTEM
+		}
+#endif
+	    }
+	  free (e);
+        }
+
+      if (debug_level > 0)
+	fprintf (errfp, "gpgme_debug: level=%d\n", debug_level);
+    }
+  UNLOCK (debug_lock);
+}
+
+
+/* Log the formatted string FORMAT at debug level LEVEL or higher.  */
+void
+_gpgme_debug (int level, const char *format, ...)
+{
+  va_list arg_ptr;
+
+  debug_init ();
+  if (debug_level < level)
+    return;
+    
+  va_start (arg_ptr, format);
+  LOCK (debug_lock);
+  vfprintf (errfp, format, arg_ptr);
+  va_end (arg_ptr);
+  if(format && *format && format[strlen (format) - 1] != '\n')
+    putc ('\n', errfp);
+  UNLOCK (debug_lock);
+  fflush (errfp);
+}
+
+
+/* Start a new debug line in *LINE, logged at level LEVEL or higher,
+   and starting with the formatted string FORMAT.  */
+void
+_gpgme_debug_begin (void **line, int level, const char *format, ...)
+{
+  va_list arg_ptr;
+
+  debug_init ();
+  if (debug_level < level)
+    {
+      /* Disable logging of this line.  */
+      *line = NULL;
+      return;
+    }
+
+  va_start (arg_ptr, format);
+  vasprintf ((char **) line, format, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+/* Add the formatted string FORMAT to the debug line *LINE.  */
+void
+_gpgme_debug_add (void **line, const char *format, ...)
+{
+  va_list arg_ptr;
+  char *toadd;
+  char *result;
+
+  if (!*line)
+    return;
+
+  va_start (arg_ptr, format);
+  vasprintf (&toadd, format, arg_ptr);
+  va_end (arg_ptr);
+  asprintf (&result, "%s%s", *(char **) line, toadd);
+  free (*line);
+  free (toadd);
+  *line = result;
+}
+
+
+/* Finish construction of *LINE and send it to the debug output
+   stream.  */
+void
+_gpgme_debug_end (void **line)
+{
+  if (!*line)
+    return;
+
+  /* The smallest possible level is 1, so force logging here by
+     using that.  */
+  _gpgme_debug (1, "%s", *line);
+  free (*line);
+  *line = NULL;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/debug.h b/libtdenetwork/libgpgme-copy/gpgme/debug.h
new file mode 100644
index 000000000..6a322634a
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/debug.h
@@ -0,0 +1,127 @@
+/* debug.h - interface to debugging functions
+   Copyright (C) 2002, 2004, 2005 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 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.
+   
+   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
+   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 DEBUG_H
+#define DEBUG_H
+
+#include <string.h>
+
+/* Remove path components from filenames (i.e. __FILE__) for cleaner
+   logs. */
+static __inline__ const char *_gpgme_debug_srcname (const char *file);
+
+static __inline__ const char *
+_gpgme_debug_srcname (const char *file)
+{
+  const char *s = strrchr (file, '/');
+  return s? s+1:file;
+}
+
+/* Log the formatted string FORMAT at debug level LEVEL or higher.  */
+void _gpgme_debug (int level, const char *format, ...);
+
+/* Start a new debug line in *LINE, logged at level LEVEL or higher,
+   and starting with the formatted string FORMAT.  */
+void _gpgme_debug_begin (void **helper, int level, const char *format, ...);
+
+/* Add the formatted string FORMAT to the debug line *LINE.  */
+void _gpgme_debug_add (void **helper, const char *format, ...);
+
+/* Finish construction of *LINE and send it to the debug output
+   stream.  */
+void _gpgme_debug_end (void **helper);
+
+/* Indirect stringification, requires __STDC__ to work.  */
+#define STRINGIFY(v) #v
+#define XSTRINGIFY(v) STRINGIFY(v)
+
+#if 0
+/* Only works in GNU.  */
+#define DEBUG(fmt, arg...) \
+  _gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__) , ##arg)
+#define DEBUG_BEGIN(hlp, lvl, fmt, arg...) \
+  _gpgme_debug_begin (&(hlp), lvl, "%s:%s: " fmt, __FILE__, \
+		      XSTRINGIFY (__LINE__) , ##arg)
+#define DEBUG_ADD(hlp, fmt, arg...) \
+  _gpgme_debug_add (&(hlp), fmt , ##arg)
+#define DEBUG_END(hlp, fmt, arg...) \
+  _gpgme_debug_add (&(hlp), fmt , ##arg); \
+  _gpgme_debug_end (&(hlp))
+#elif 0
+/* Only works in C99.  */
+#define DEBUG0(fmt) \
+  _gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__))
+#define DEBUG(fmt, ...) \
+  _gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__), __VA_ARGS__)
+#define DEBUG_BEGIN(hlp, lvl, fmt) \
+  _gpgme_debug_begin (&(hlp), lvl, "%s:%s: " fmt, __FILE__, \
+		      XSTRINGIFY (__LINE__))
+#define DEBUG_BEGINX(hlp, lvl, fmt, ...) \
+  _gpgme_debug_begin (&(hlp), lvl, "%s:%s: " fmt, __FILE__, \
+		      XSTRINGIFY (__LINE__), __VA_ARGS__)
+#define DEBUG_ADD0(hlp, fmt) \
+  _gpgme_debug_add (&(hlp), fmt)
+#define DEBUG_ADD(hlp, fmt, ...) \
+  _gpgme_debug_add (&(hlp), fmt, __VA_ARGS__)
+#define DEBUG_END(hlp, fmt) \
+  _gpgme_debug_add (&(hlp), fmt); \
+  _gpgme_debug_end (&(hlp))
+#define DEBUG_ENDX(hlp, fmt, ...) \
+  _gpgme_debug_add (&(hlp), fmt, __VA_ARGS__); \
+  _gpgme_debug_end (&(hlp))
+#else
+/* This finally works everywhere, horror.  */
+#define DEBUG0(fmt) \
+  _gpgme_debug (1, "%s:%s: " fmt, _gpgme_debug_srcname (__FILE__), \
+                XSTRINGIFY (__LINE__))
+#define DEBUG1(fmt,a) \
+  _gpgme_debug (1, "%s:%s: " fmt, _gpgme_debug_srcname (__FILE__), \
+                XSTRINGIFY (__LINE__), (a))
+#define DEBUG2(fmt,a,b) \
+  _gpgme_debug (1, "%s:%s: " fmt, _gpgme_debug_srcname (__FILE__), \
+                XSTRINGIFY (__LINE__), (a), (b))
+#define DEBUG3(fmt,a,b,c) \
+  _gpgme_debug (1, "%s:%s: " fmt, _gpgme_debug_srcname (__FILE__), \
+                XSTRINGIFY (__LINE__), (a), (b), (c))
+#define DEBUG4(fmt,a,b,c,d) \
+  _gpgme_debug (1, "%s:%s: " fmt, _gpgme_debug_srcname (__FILE__), \
+                XSTRINGIFY (__LINE__), (a), (b), (c), (d))
+#define DEBUG5(fmt,a,b,c,d,e) \
+  _gpgme_debug (1, "%s:%s: " fmt, _gpgme_debug_srcname (__FILE__), \
+                XSTRINGIFY (__LINE__), (a), (b), (c), (d), (e))
+#define DEBUG_BEGIN(hlp,lvl,fmt) \
+  _gpgme_debug_begin (&(hlp), lvl, "%s:%s: " fmt, \
+                      _gpgme_debug_srcname (__FILE__), XSTRINGIFY (__LINE__))
+#define DEBUG_ADD0(hlp,fmt) \
+  _gpgme_debug_add (&(hlp), fmt)
+#define DEBUG_ADD1(hlp,fmt,a) \
+  _gpgme_debug_add (&(hlp), fmt, (a))
+#define DEBUG_ADD2(hlp,fmt,a,b) \
+  _gpgme_debug_add (&(hlp), fmt, (a), (b))
+#define DEBUG_ADD3(hlp,fmt,a,b,c) \
+  _gpgme_debug_add (&(hlp), fmt, (a), (b), (c))
+#define DEBUG_END(hlp,fmt) \
+  _gpgme_debug_add (&(hlp), fmt); \
+  _gpgme_debug_end (&(hlp))
+#endif
+
+#define DEBUG_ENABLED(hlp) (!!(hlp))
+
+#endif	/* DEBUG_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/decrypt-verify.c b/libtdenetwork/libgpgme-copy/gpgme/decrypt-verify.c
new file mode 100644
index 000000000..dd6a4db68
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/decrypt-verify.c
@@ -0,0 +1,103 @@
+/* decrypt-verify.c - Decrypt and verify function.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gpgme.h"
+#include "ops.h"
+
+
+static gpgme_error_t
+decrypt_verify_status_handler (void *priv, gpgme_status_code_t code,
+			       char *args)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_progress_status_handler (priv, code, args);
+  if (!err)
+    err = _gpgme_decrypt_status_handler (priv, code, args);
+  if (!err)
+      err = _gpgme_verify_status_handler (priv, code, args);
+  return err;
+}
+
+
+static gpgme_error_t
+decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
+		      gpgme_data_t cipher, gpgme_data_t plain)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  err = _gpgme_op_decrypt_init_result (ctx);
+  if (err)
+    return err;
+
+  err = _gpgme_op_verify_init_result (ctx);
+  if (err)
+    return err;
+
+  if (!cipher)
+    return gpg_error (GPG_ERR_NO_DATA);
+  if (!plain)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (ctx->passphrase_cb)
+    {
+      err = _gpgme_engine_set_command_handler
+	(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
+      if (err)
+	return err;
+    }
+
+  _gpgme_engine_set_status_handler (ctx->engine,
+				    decrypt_verify_status_handler, ctx);
+  
+  return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain);
+}
+
+
+/* Decrypt ciphertext CIPHER and make a signature verification within
+   CTX and store the resulting plaintext in PLAIN.  */
+gpgme_error_t
+gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
+			       gpgme_data_t plain)
+{
+  return decrypt_verify_start (ctx, 0, cipher, plain);
+}
+
+
+/* Decrypt ciphertext CIPHER and make a signature verification within
+   CTX and store the resulting plaintext in PLAIN.  */
+gpgme_error_t
+gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
+			 gpgme_data_t plain)
+{
+  gpgme_error_t err = decrypt_verify_start (ctx, 1, cipher, plain);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/decrypt.c b/libtdenetwork/libgpgme-copy/gpgme/decrypt.c
new file mode 100644
index 000000000..8d93239ed
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/decrypt.c
@@ -0,0 +1,340 @@
+/* decrypt.c - Decrypt function.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+
+
+typedef struct
+{
+  struct _gpgme_op_decrypt_result result;
+
+  int okay;
+  int failed;
+  
+  /* A pointer to the next pointer of the last recipient in the list.
+     This makes appending new invalid signers painless while
+     preserving the order.  */
+  gpgme_recipient_t *last_recipient_p;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+
+  if (opd->result.unsupported_algorithm)
+    free (opd->result.unsupported_algorithm);
+
+  if (opd->result.file_name)
+    free (opd->result.file_name);
+}
+
+
+gpgme_decrypt_result_t
+gpgme_op_decrypt_result (gpgme_ctx_t ctx)
+{
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
+  opd = hook;
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+static gpgme_error_t
+parse_enc_to (char *args, gpgme_recipient_t *recp)
+{
+  gpgme_recipient_t rec;
+  char *tail;
+  int i;
+
+  rec = malloc (sizeof (*rec));
+  if (!rec)
+    return gpg_error_from_errno (errno);
+
+  rec->next = NULL;
+  rec->keyid = rec->_keyid;
+  rec->status = 0;
+
+  for (i = 0; i < sizeof (rec->_keyid) - 1; i++)
+    {
+      if (args[i] == '\0' || args[i] == ' ')
+	break;
+
+      rec->_keyid[i] = args[i];
+    }
+  rec->_keyid[i] = '\0';
+
+  args = &args[i];
+  if (*args != '\0' && *args != ' ')
+    {
+      free (rec);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+
+  while (*args == ' ')
+    args++;
+
+  if (*args)
+    {
+      errno = 0;
+      rec->pubkey_algo = strtol (args, &tail, 0);
+      if (errno || args == tail || *tail != ' ')
+	{
+	  /* The crypto backend does not behave.  */
+	  free (rec);
+	  return gpg_error (GPG_ERR_INV_ENGINE);
+	}
+    }
+
+  /* FIXME: The key length is always 0 right now, so no need to parse
+     it.  */
+
+  *recp = rec;
+  return 0;
+}
+
+
+gpgme_error_t
+_gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
+			       char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_passphrase_status_handler (priv, code, args);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  switch (code)
+    {
+    case GPGME_STATUS_EOF:
+      /* FIXME: These error values should probably be attributed to
+	 the underlying crypto engine (as error source).  */
+      if (opd->failed)
+	return gpg_error (GPG_ERR_DECRYPT_FAILED);
+      else if (!opd->okay)
+	return gpg_error (GPG_ERR_NO_DATA);
+      break;
+
+    case GPGME_STATUS_DECRYPTION_OKAY:
+      opd->okay = 1;
+      break;
+
+    case GPGME_STATUS_DECRYPTION_FAILED:
+      opd->failed = 1;
+      break;
+
+    case GPGME_STATUS_ERROR:
+      /* Note that this is an informational status code which should
+         not lead to an error return unless it is something not
+         related to the backend.  */
+      {
+	const char d_alg[] = "decrypt.algorithm";
+	const char u_alg[] = "Unsupported_Algorithm";
+	const char k_alg[] = "decrypt.keyusage";
+
+	if (!strncmp (args, d_alg, sizeof (d_alg) - 1))
+	  {
+	    args += sizeof (d_alg) - 1;
+	    while (*args == ' ')
+	      args++;
+
+	    if (!strncmp (args, u_alg, sizeof (u_alg) - 1))
+	      {
+		char *end;
+
+		args += sizeof (u_alg) - 1;
+		while (*args == ' ')
+		  args++;
+
+		end = strchr (args, ' ');
+		if (end)
+		  *end = '\0';
+
+		if (!(*args == '?' && *(args + 1) == '\0'))
+		  {
+		    opd->result.unsupported_algorithm = strdup (args);
+		    if (!opd->result.unsupported_algorithm)
+		      return gpg_error_from_errno (errno);
+		  }
+	      }
+	  }
+	else if (!strncmp (args, k_alg, sizeof (k_alg) - 1))
+	  {
+	    args += sizeof (k_alg) - 1;
+	    while (*args == ' ')
+	      args++;
+
+	    err = _gpgme_map_gnupg_error (args);
+	    if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
+	      opd->result.wrong_key_usage = 1;
+	  }
+      }
+      break;
+
+    case GPGME_STATUS_ENC_TO:
+      err = parse_enc_to (args, opd->last_recipient_p);
+      if (err)
+	return err;
+
+      opd->last_recipient_p = &(*opd->last_recipient_p)->next;
+      break;
+
+    case GPGME_STATUS_NO_SECKEY:
+      {
+	gpgme_recipient_t rec = opd->result.recipients;
+
+	while (rec)
+	  {
+	    if (!strcmp (rec->keyid, args))
+	      {
+		rec->status = gpg_error (GPG_ERR_NO_SECKEY);
+		break;
+	      }
+	    rec = rec->next;
+	  }
+	/* FIXME: Is this ok?  */
+	if (!rec)
+	  return gpg_error (GPG_ERR_INV_ENGINE);
+      }
+      break;
+
+    case GPGME_STATUS_PLAINTEXT:
+      err = _gpgme_parse_plaintext (args, &opd->result.file_name);
+      if (err)
+	return err;
+      
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+
+static gpgme_error_t
+decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_progress_status_handler (priv, code, args);
+  if (!err)
+    err = _gpgme_decrypt_status_handler (priv, code, args);
+  return err;
+}
+
+
+gpgme_error_t
+_gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  opd->last_recipient_p = &opd->result.recipients;
+  return 0;
+}
+
+
+static gpgme_error_t
+decrypt_start (gpgme_ctx_t ctx, int synchronous,
+		      gpgme_data_t cipher, gpgme_data_t plain)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  err = _gpgme_op_decrypt_init_result (ctx);
+  if (err)
+    return err;
+
+  if (!cipher)
+    return gpg_error (GPG_ERR_NO_DATA);
+  if (!plain)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (err)
+    return err;
+
+  if (ctx->passphrase_cb)
+    {
+      err = _gpgme_engine_set_command_handler
+	(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
+      if (err)
+	return err;
+    }
+
+  _gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
+
+  return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain);
+}
+
+
+gpgme_error_t
+gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
+			gpgme_data_t plain)
+{
+  return decrypt_start (ctx, 0, cipher, plain);
+}
+
+
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+   plaintext in PLAIN.  */
+gpgme_error_t
+gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
+{
+  gpgme_error_t err = decrypt_start (ctx, 1, cipher, plain);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/delete.c b/libtdenetwork/libgpgme-copy/gpgme/delete.c
new file mode 100644
index 000000000..1f2d1a9bb
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/delete.c
@@ -0,0 +1,109 @@
+/* delete.c - Delete a key.
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+static gpgme_error_t
+delete_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  if (code == GPGME_STATUS_DELETE_PROBLEM)
+    {
+      enum delete_problem
+	{
+	  DELETE_No_Problem = 0,
+	  DELETE_No_Such_Key = 1,
+	  DELETE_Must_Delete_Secret_Key = 2,
+	  DELETE_Ambiguous_Specification = 3
+	};
+      long problem;
+      char *tail;
+
+      errno = 0;
+      problem = strtol (args, &tail, 0);
+      if (errno || (*tail && *tail != ' '))
+	return gpg_error (GPG_ERR_INV_ENGINE);
+
+      switch (problem)
+	{
+	case DELETE_No_Problem:
+	  break;
+
+	case DELETE_No_Such_Key:
+	  return gpg_error (GPG_ERR_NO_PUBKEY);
+
+	case DELETE_Must_Delete_Secret_Key:
+	  return gpg_error (GPG_ERR_CONFLICT);
+
+	case DELETE_Ambiguous_Specification:
+	  return gpg_error (GPG_ERR_AMBIGUOUS_NAME);
+
+	default:
+	  return gpg_error (GPG_ERR_GENERAL);
+	}
+    }
+  return 0;
+}
+
+
+static gpgme_error_t
+delete_start (gpgme_ctx_t ctx, int synchronous, const gpgme_key_t key,
+	      int allow_secret)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, delete_status_handler, ctx);
+
+  return _gpgme_engine_op_delete (ctx->engine, key, allow_secret);
+}
+
+
+/* Delete KEY from the keyring.  If ALLOW_SECRET is non-zero, secret
+   keys are also deleted.  */
+gpgme_error_t
+gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key,
+		       int allow_secret)
+{
+  return delete_start (ctx, 0, key, allow_secret);
+}
+
+
+/* Delete KEY from the keyring.  If ALLOW_SECRET is non-zero, secret
+   keys are also deleted.  */
+gpgme_error_t
+gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret)
+{
+  gpgme_error_t err = delete_start (ctx, 1, key, allow_secret);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/edit.c b/libtdenetwork/libgpgme-copy/gpgme/edit.c
new file mode 100644
index 000000000..7c6396770
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/edit.c
@@ -0,0 +1,177 @@
+/* edit.c - Key edit function.
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+typedef struct
+{
+  /* The user callback function and its hook value.  */
+  gpgme_edit_cb_t fnc;
+  void *fnc_value;
+} *op_data_t;
+
+
+static gpgme_error_t
+edit_status_handler (void *priv, gpgme_status_code_t status, char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_passphrase_status_handler (priv, status, args);
+  if (err)
+    return err;
+
+  err = _gpgme_progress_status_handler (priv, status, args);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  return (*opd->fnc) (opd->fnc_value, status, args, -1);
+}
+
+
+static gpgme_error_t
+command_handler (void *priv, gpgme_status_code_t status, const char *args,
+		 int fd, int *processed_r)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  int processed = 0;
+
+  if (ctx->passphrase_cb)
+    {
+      err = _gpgme_passphrase_command_handler (ctx, status, args,
+					       fd, &processed);
+      if (err)
+	return err;
+    }
+
+  if (!processed)
+    {
+      void *hook;
+      op_data_t opd;
+
+      err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
+      opd = hook;
+      if (err)
+	return err;
+
+      /* FIXME: We expect the user to handle _all_ status codes.
+	 Later, we may fix the callback interface to allow the user
+	 indicate if it processed the status code or not.  */
+      *processed_r = 1;
+
+      return (*opd->fnc) (opd->fnc_value, status, args, fd);
+    }
+
+  *processed_r = processed;
+  return 0;
+}
+
+
+static gpgme_error_t
+edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
+	    gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  if (!fnc || !out)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  opd->fnc = fnc;
+  opd->fnc_value = fnc_value;
+
+  err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
+					   ctx, out);
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
+
+  return _gpgme_engine_op_edit (ctx->engine, type, key, out, ctx);
+}
+
+
+gpgme_error_t
+gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+		     gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
+{
+  return edit_start (ctx, 0, 0, key, fnc, fnc_value, out);
+}
+
+
+/* Edit the key KEY.  Send status and command requests to FNC and
+   output of edit commands to OUT.  */
+gpgme_error_t
+gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+	       gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
+{
+  gpgme_error_t err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
+
+
+gpgme_error_t
+gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+			  gpgme_edit_cb_t fnc, void *fnc_value,
+			  gpgme_data_t out)
+{
+  return edit_start (ctx, 0, 1, key, fnc, fnc_value, out);
+}
+
+
+/* Edit the card for the key KEY.  Send status and command requests to
+   FNC and output of edit commands to OUT.  */
+gpgme_error_t
+gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+		    gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
+{
+  gpgme_error_t err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/encrypt-sign.c b/libtdenetwork/libgpgme-copy/gpgme/encrypt-sign.c
new file mode 100644
index 000000000..d678ed67a
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/encrypt-sign.c
@@ -0,0 +1,110 @@
+/* encrypt-sign.c -  encrypt and verify functions
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+static gpgme_error_t
+encrypt_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_progress_status_handler (priv, code, args);
+  if (!err)
+    err = _gpgme_encrypt_status_handler (priv, code, args);
+  if (!err)
+    err = _gpgme_sign_status_handler (priv, code, args);
+  return err;
+}
+
+
+static gpgme_error_t
+encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
+		    gpgme_encrypt_flags_t flags,
+		    gpgme_data_t plain, gpgme_data_t cipher)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  if (!plain)
+    return gpg_error (GPG_ERR_NO_DATA);
+  if (!cipher || !recp)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_encrypt_init_result (ctx);
+  if (err)
+    return err;
+
+  err = _gpgme_op_sign_init_result (ctx);
+  if (err)
+    return err;
+
+  if (ctx->passphrase_cb)
+    {
+      err = _gpgme_engine_set_command_handler
+	(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
+      if (err)
+	return err;
+    }
+
+  _gpgme_engine_set_status_handler (ctx->engine,
+				    encrypt_sign_status_handler, ctx);
+  
+  return _gpgme_engine_op_encrypt_sign (ctx->engine, recp, flags, plain,
+					cipher, ctx->use_armor,
+					ctx /* FIXME */);
+}
+
+
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+   store the resulting ciphertext in CIPHER.  Also sign the ciphertext
+   with the signers in CTX.  */
+gpgme_error_t
+gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
+			     gpgme_encrypt_flags_t flags,
+			     gpgme_data_t plain, gpgme_data_t cipher)
+{
+  return encrypt_sign_start (ctx, 0, recp, flags, plain, cipher);
+}
+
+
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+   store the resulting ciphertext in CIPHER.  Also sign the ciphertext
+   with the signers in CTX.  */
+gpgme_error_t
+gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
+		       gpgme_encrypt_flags_t flags,
+		       gpgme_data_t plain, gpgme_data_t cipher)
+{
+  gpgme_error_t err = encrypt_sign_start (ctx, 1, recp, flags, plain, cipher);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/encrypt.c b/libtdenetwork/libgpgme-copy/gpgme/encrypt.c
new file mode 100644
index 000000000..089c69999
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/encrypt.c
@@ -0,0 +1,222 @@
+/* encrypt.c - Encrypt function.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+typedef struct
+{
+  struct _gpgme_op_encrypt_result result;
+
+  /* A pointer to the next pointer of the last invalid recipient in
+     the list.  This makes appending new invalid recipients painless
+     while preserving the order.  */
+  gpgme_invalid_key_t *lastp;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+  gpgme_invalid_key_t invalid_recipient = opd->result.invalid_recipients;
+
+  while (invalid_recipient)
+    {
+      gpgme_invalid_key_t next = invalid_recipient->next;
+      if (invalid_recipient->fpr)
+	free (invalid_recipient->fpr);
+      invalid_recipient = next;
+    }
+}
+
+
+gpgme_encrypt_result_t
+gpgme_op_encrypt_result (gpgme_ctx_t ctx)
+{
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
+  opd = hook;
+
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+gpgme_error_t
+_gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
+			       char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  switch (code)
+    {
+    case GPGME_STATUS_EOF:
+      if (opd->result.invalid_recipients)
+	return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
+      break;
+
+    case GPGME_STATUS_INV_RECP:
+      err = _gpgme_parse_inv_recp (args, opd->lastp);
+      if (err)
+	return err;
+
+      opd->lastp = &(*opd->lastp)->next;
+      break;
+
+    case GPGME_STATUS_NO_RECP:
+      /* Should not happen, because we require at least one recipient.  */
+      return gpg_error (GPG_ERR_GENERAL);
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+
+static gpgme_error_t
+encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_progress_status_handler (priv, code, args);
+  if (!err)
+    err = _gpgme_passphrase_status_handler (priv, code, args);
+  return err;
+}
+
+
+static gpgme_error_t
+encrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  return _gpgme_progress_status_handler (priv, code, args)
+    || _gpgme_encrypt_status_handler (priv, code, args);
+}
+
+
+gpgme_error_t
+_gpgme_op_encrypt_init_result (gpgme_ctx_t ctx)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, sizeof (*opd),
+			       release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  opd->lastp = &opd->result.invalid_recipients;
+  return 0;
+}
+
+
+static gpgme_error_t
+encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
+	       gpgme_encrypt_flags_t flags,
+	       gpgme_data_t plain, gpgme_data_t cipher)
+{
+  gpgme_error_t err;
+  int symmetric = 0;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  err = _gpgme_op_encrypt_init_result (ctx);
+  if (err)
+    return err;
+
+  if (!recp)
+    symmetric = 1;
+
+  if (!plain)
+    return gpg_error (GPG_ERR_NO_DATA);
+  if (!cipher)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (recp && ! *recp)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (symmetric && ctx->passphrase_cb)
+    {
+      /* Symmetric encryption requires a passphrase.  */
+      err = _gpgme_engine_set_command_handler
+	(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
+      if (err)
+	return err;
+    }
+
+  _gpgme_engine_set_status_handler (ctx->engine,
+				    symmetric
+				    ? encrypt_sym_status_handler
+				    : encrypt_status_handler,
+				    ctx);
+
+  return _gpgme_engine_op_encrypt (ctx->engine, recp, flags, plain, cipher,
+				   ctx->use_armor);
+}
+
+
+gpgme_error_t
+gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
+			gpgme_encrypt_flags_t flags,
+			gpgme_data_t plain, gpgme_data_t cipher)
+{
+  return encrypt_start (ctx, 0, recp, flags, plain, cipher);
+}
+
+
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+   store the resulting ciphertext in CIPHER.  */
+gpgme_error_t
+gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
+		  gpgme_encrypt_flags_t flags,
+		  gpgme_data_t plain, gpgme_data_t cipher)
+{
+  gpgme_error_t err = encrypt_start (ctx, 1, recp, flags, plain, cipher);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/engine-backend.h b/libtdenetwork/libgpgme-copy/gpgme/engine-backend.h
new file mode 100644
index 000000000..f2b978796
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/engine-backend.h
@@ -0,0 +1,110 @@
+/* engine-backend.h - A crypto backend for the engine interface.
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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 ENGINE_BACKEND_H
+#define ENGINE_BACKEND_H
+
+#include "engine.h"
+
+/* FIXME: Correct check?  */
+#ifdef GPGSM_PATH
+#define ENABLE_GPGSM 1
+#endif
+
+struct engine_ops
+{
+  /* Static functions.  */
+
+  /* Return the default file name for the binary of this engine.  */
+  const char *(*get_file_name) (void);
+
+  /* Returns a malloced string containing the version of the engine
+     with the given binary file name (or the default if FILE_NAME is
+     NULL.  */
+  char *(*get_version) (const char *file_name);
+
+  /* Returns a statically allocated string containing the required
+     version.  */
+  const char *(*get_req_version) (void);
+
+  gpgme_error_t (*new) (void **r_engine,
+			const char *file_name, const char *home_dir);
+
+  /* Member functions.  */
+  void (*release) (void *engine);
+  gpgme_error_t (*reset) (void *engine);
+  void (*set_status_handler) (void *engine, engine_status_handler_t fnc,
+			      void *fnc_value);
+  gpgme_error_t (*set_command_handler) (void *engine,
+					engine_command_handler_t fnc,
+					void *fnc_value, gpgme_data_t data);
+  gpgme_error_t (*set_colon_line_handler) (void *engine,
+					   engine_colon_line_handler_t fnc,
+					   void *fnc_value);
+  gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
+  gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph,
+			    gpgme_data_t plain);
+  gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret);
+  gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
+			 gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
+  gpgme_error_t (*encrypt) (void *engine, gpgme_key_t recp[],
+			    gpgme_encrypt_flags_t flags,
+			    gpgme_data_t plain, gpgme_data_t ciph,
+			    int use_armor);
+  gpgme_error_t (*encrypt_sign) (void *engine, gpgme_key_t recp[],
+				 gpgme_encrypt_flags_t flags,
+				 gpgme_data_t plain, gpgme_data_t ciph,
+				 int use_armor, gpgme_ctx_t ctx /* FIXME */);
+  gpgme_error_t (*export) (void *engine, const char *pattern,
+			   unsigned int reserved, gpgme_data_t keydata,
+			   int use_armor);
+  gpgme_error_t (*export_ext) (void *engine, const char *pattern[],
+			       unsigned int reserved, gpgme_data_t keydata,
+			       int use_armor);
+  gpgme_error_t (*genkey) (void *engine, gpgme_data_t help_data, int use_armor,
+			   gpgme_data_t pubkey, gpgme_data_t seckey);
+  gpgme_error_t (*import) (void *engine, gpgme_data_t keydata);
+  gpgme_error_t (*keylist) (void *engine, const char *pattern,
+			    int secret_only, gpgme_keylist_mode_t mode);
+  gpgme_error_t (*keylist_ext) (void *engine, const char *pattern[],
+				int secret_only, int reserved,
+				gpgme_keylist_mode_t mode);
+  gpgme_error_t (*sign) (void *engine, gpgme_data_t in, gpgme_data_t out,
+			 gpgme_sig_mode_t mode, int use_armor,
+			 int use_textmode,
+			 int include_certs, gpgme_ctx_t ctx /* FIXME */);
+  gpgme_error_t (*trustlist) (void *engine, const char *pattern);
+  gpgme_error_t (*verify) (void *engine, gpgme_data_t sig,
+			   gpgme_data_t signed_text,
+			   gpgme_data_t plaintext);
+  
+  void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs);
+  void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data);
+
+  gpgme_error_t (*cancel) (void *engine);
+};
+
+
+extern struct engine_ops _gpgme_engine_ops_gpg;		/* OpenPGP.  */
+#ifdef ENABLE_GPGSM
+extern struct engine_ops _gpgme_engine_ops_gpgsm;	/* CMS.  */
+#endif
+
+#endif /* ENGINE_BACKEND_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c b/libtdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c
new file mode 100644
index 000000000..7ad8dc6f2
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/engine-gpgsm.c
@@ -0,0 +1,1750 @@
+/* engine-gpgsm.c - GpgSM engine.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_W32_SYSTEM
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <unistd.h>
+#include <locale.h>
+#include <fcntl.h> /* FIXME */
+#include <errno.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "ops.h"
+#include "wait.h"
+#include "priv-io.h"
+#include "sema.h"
+
+#include "assuan.h"
+#include "status-table.h"
+#include "debug.h"
+
+#include "engine-backend.h"
+
+
+typedef struct
+{
+  int fd;	/* FD we talk about.  */
+  int server_fd; /* Server FD for this connection.  */
+  int dir;	/* Inbound/Outbound, maybe given implicit?  */
+  void *data;	/* Handler-specific data.  */
+  void *tag;	/* ID from the user for gpgme_remove_io_callback.  */
+} iocb_data_t;
+
+
+struct engine_gpgsm
+{
+  assuan_context_t assuan_ctx;
+
+  int lc_ctype_set;
+  int lc_messages_set;
+
+  iocb_data_t status_cb;
+
+  /* Input, output etc are from the servers perspective.  */
+  iocb_data_t input_cb;
+
+  iocb_data_t output_cb;
+
+  iocb_data_t message_cb;
+
+  struct
+  {
+    engine_status_handler_t fnc;
+    void *fnc_value;
+  } status;
+
+  struct
+  {
+    engine_colon_line_handler_t fnc;
+    void *fnc_value;
+    struct
+    {
+      char *line;
+      int linesize;
+      int linelen;
+    } attic;
+    int any; /* any data line seen */
+  } colon; 
+
+  struct gpgme_io_cbs io_cbs;
+};
+
+typedef struct engine_gpgsm *engine_gpgsm_t;
+
+
+static char *
+gpgsm_get_version (const char *file_name)
+{
+  return _gpgme_get_program_version (file_name ? file_name
+				     : _gpgme_get_gpgsm_path ());
+}
+
+
+static const char *
+gpgsm_get_req_version (void)
+{
+  return NEED_GPGSM_VERSION;
+}
+
+
+static void
+close_notify_handler (int fd, void *opaque)
+{
+  engine_gpgsm_t gpgsm = opaque;
+
+  assert (fd != -1);
+  if (gpgsm->status_cb.fd == fd)
+    {
+      if (gpgsm->status_cb.tag)
+	(*gpgsm->io_cbs.remove) (gpgsm->status_cb.tag);
+      gpgsm->status_cb.fd = -1;
+      gpgsm->status_cb.tag = NULL;
+    }
+  else if (gpgsm->input_cb.fd == fd)
+    {
+      if (gpgsm->input_cb.tag)
+	(*gpgsm->io_cbs.remove) (gpgsm->input_cb.tag);
+      gpgsm->input_cb.fd = -1;
+      gpgsm->input_cb.tag = NULL;
+    }
+  else if (gpgsm->output_cb.fd == fd)
+    {
+      if (gpgsm->output_cb.tag)
+	(*gpgsm->io_cbs.remove) (gpgsm->output_cb.tag);
+      gpgsm->output_cb.fd = -1;
+      gpgsm->output_cb.tag = NULL;
+    }
+  else if (gpgsm->message_cb.fd == fd)
+    {
+      if (gpgsm->message_cb.tag)
+	(*gpgsm->io_cbs.remove) (gpgsm->message_cb.tag);
+      gpgsm->message_cb.fd = -1;
+      gpgsm->message_cb.tag = NULL;
+    }
+}
+
+
+static gpgme_error_t
+map_assuan_error (gpg_error_t err)
+{
+  if (!err)
+    return 0;
+
+  if (err == -1)
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  /* New code will use gpg_error_t values.  */
+  if (gpg_err_source (err))
+    return (gpgme_error_t) err;
+
+  /* Legacy code will use old values.  */
+  switch (err)
+    {
+    case ASSUAN_No_Error:
+      return gpg_error (GPG_ERR_NO_ERROR);
+    case ASSUAN_General_Error:
+      return gpg_error (GPG_ERR_GENERAL);
+    case ASSUAN_Out_Of_Core:
+      return gpg_error (GPG_ERR_ENOMEM);
+    case ASSUAN_Invalid_Value:
+      return gpg_error (GPG_ERR_INV_VALUE);
+    case ASSUAN_Timeout:
+      return gpg_error (GPG_ERR_ETIMEDOUT);
+    case ASSUAN_Read_Error:
+      return gpg_error (GPG_ERR_GENERAL);
+    case ASSUAN_Write_Error:
+      return gpg_error (GPG_ERR_GENERAL);
+
+    case ASSUAN_Problem_Starting_Server:
+    case ASSUAN_Not_A_Server:
+    case ASSUAN_Not_A_Client:
+    case ASSUAN_Nested_Commands:
+    case ASSUAN_No_Data_Callback:
+    case ASSUAN_No_Inquire_Callback:
+    case ASSUAN_Connect_Failed:
+    case ASSUAN_Accept_Failed:
+    case ASSUAN_Invalid_Command:
+    case ASSUAN_Unknown_Command:
+    case ASSUAN_Syntax_Error:
+    case ASSUAN_Parameter_Error:
+    case ASSUAN_Parameter_Conflict:
+    case ASSUAN_No_Input:
+    case ASSUAN_No_Output:
+    case ASSUAN_No_Data_Available:
+    case ASSUAN_Too_Much_Data:
+    case ASSUAN_Inquire_Unknown:
+    case ASSUAN_Inquire_Error:
+    case ASSUAN_Invalid_Option:
+    case ASSUAN_Unexpected_tqStatus:
+    case ASSUAN_Unexpected_Data:
+    case ASSUAN_Invalid_tqStatus:
+      return gpg_error (GPG_ERR_ASSUAN);
+
+    case ASSUAN_Invalid_Response:
+      return gpg_error (GPG_ERR_INV_RESPONSE);
+
+    case ASSUAN_Not_Implemented:
+      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+    case ASSUAN_Line_Too_Long:
+      return gpg_error (GPG_ERR_LINE_TOO_LONG);
+    case ASSUAN_Line_Not_Terminated:
+      return gpg_error (GPG_ERR_INCOMPLETE_LINE);
+    case ASSUAN_Canceled:
+      return gpg_error (GPG_ERR_CANCELED);
+
+    case ASSUAN_Unsupported_Algorithm:
+      return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+    case ASSUAN_Server_Resource_Problem:
+      return gpg_error (GPG_ERR_RESOURCE_LIMIT);
+    case ASSUAN_Server_IO_Error:
+      return gpg_error (GPG_ERR_GENERAL);
+    case ASSUAN_Server_Bug:
+      return gpg_error (GPG_ERR_BUG);
+    case ASSUAN_Invalid_Data:
+      return gpg_error (GPG_ERR_INV_DATA);
+    case ASSUAN_Invalid_Index:
+      return gpg_error (GPG_ERR_INV_INDEX);
+    case ASSUAN_Not_Confirmed:
+      return gpg_error (GPG_ERR_NOT_CONFIRMED);
+    case ASSUAN_Bad_Certificate:
+      return gpg_error (GPG_ERR_BAD_CERT);
+    case ASSUAN_Bad_Certificate_Chain:
+      return gpg_error (GPG_ERR_BAD_CERT_CHAIN);
+    case ASSUAN_Missing_Certificate:
+      return gpg_error (GPG_ERR_MISSING_CERT);
+    case ASSUAN_Bad_Signature:
+      return gpg_error (GPG_ERR_BAD_SIGNATURE);
+    case ASSUAN_No_Agent:
+      return gpg_error (GPG_ERR_NO_AGENT);
+    case ASSUAN_Agent_Error:
+      return gpg_error (GPG_ERR_AGENT);
+    case ASSUAN_No_Public_Key:
+      return gpg_error (GPG_ERR_NO_PUBKEY);
+    case ASSUAN_No_Secret_Key:
+      return gpg_error (GPG_ERR_NO_SECKEY);
+    case ASSUAN_Invalid_Name:
+      return gpg_error (GPG_ERR_INV_NAME);
+      
+    case ASSUAN_Cert_Revoked:
+      return gpg_error (GPG_ERR_CERT_REVOKED);
+    case ASSUAN_No_CRL_For_Cert:
+      return gpg_error (GPG_ERR_NO_CRL_KNOWN);
+    case ASSUAN_CRL_Too_Old:
+      return gpg_error (GPG_ERR_CRL_TOO_OLD);
+    case ASSUAN_Not_Trusted:
+      return gpg_error (GPG_ERR_NOT_TRUSTED);
+
+    case ASSUAN_Card_Error:
+      return gpg_error (GPG_ERR_CARD);
+    case ASSUAN_Invalid_Card:
+      return gpg_error (GPG_ERR_INV_CARD);
+    case ASSUAN_No_PKCS15_App:
+      return gpg_error (GPG_ERR_NO_PKCS15_APP);
+    case ASSUAN_Card_Not_Present:
+      return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
+    case ASSUAN_Invalid_Id:
+      return gpg_error (GPG_ERR_INV_ID);
+    default:
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+}
+
+
+static gpgme_error_t
+gpgsm_cancel (void *engine)
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  if (!gpgsm)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (gpgsm->status_cb.fd != -1)
+    _gpgme_io_close (gpgsm->status_cb.fd);
+  if (gpgsm->input_cb.fd != -1)
+    _gpgme_io_close (gpgsm->input_cb.fd);
+  if (gpgsm->output_cb.fd != -1)
+    _gpgme_io_close (gpgsm->output_cb.fd);
+  if (gpgsm->message_cb.fd != -1)
+    _gpgme_io_close (gpgsm->message_cb.fd);
+
+  if (gpgsm->assuan_ctx)
+    {
+      assuan_disconnect (gpgsm->assuan_ctx);
+      gpgsm->assuan_ctx = NULL;
+    }
+
+  return 0;
+}
+
+
+static void
+gpgsm_release (void *engine)
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  if (!gpgsm)
+    return;
+
+  gpgsm_cancel (engine);
+
+  free (gpgsm->colon.attic.line);
+  free (gpgsm);
+}
+
+
+static gpgme_error_t
+gpgsm_new (void **engine, const char *file_name, const char *home_dir)
+{
+  gpgme_error_t err = 0;
+  engine_gpgsm_t gpgsm;
+  const char *argv[5];
+  int argc;
+#if !USE_DESCRIPTOR_PASSING
+  int fds[2];
+  int child_fds[4];
+#endif
+  char *dft_display = NULL;
+  char dft_ttyname[64];
+  char *dft_ttytype = NULL;
+  char *optstr;
+
+  gpgsm = calloc (1, sizeof *gpgsm);
+  if (!gpgsm)
+    return gpg_error_from_errno (errno);
+
+  gpgsm->status_cb.fd = -1;
+  gpgsm->status_cb.dir = 1;
+  gpgsm->status_cb.tag = 0;
+  gpgsm->status_cb.data = gpgsm;
+
+  gpgsm->input_cb.fd = -1;
+  gpgsm->input_cb.dir = 0;
+  gpgsm->input_cb.tag = 0;
+  gpgsm->input_cb.server_fd = -1;
+  gpgsm->output_cb.fd = -1;
+  gpgsm->output_cb.dir = 1;
+  gpgsm->output_cb.tag = 0;
+  gpgsm->output_cb.server_fd = -1;
+  gpgsm->message_cb.fd = -1;
+  gpgsm->message_cb.dir = 0;
+  gpgsm->message_cb.tag = 0;
+  gpgsm->message_cb.server_fd = -1;
+
+  gpgsm->status.fnc = 0;
+  gpgsm->colon.fnc = 0;
+  gpgsm->colon.attic.line = 0;
+  gpgsm->colon.attic.linesize = 0;
+  gpgsm->colon.attic.linelen = 0;
+  gpgsm->colon.any = 0;
+
+  gpgsm->io_cbs.add = NULL;
+  gpgsm->io_cbs.add_priv = NULL;
+  gpgsm->io_cbs.remove = NULL;
+  gpgsm->io_cbs.event = NULL;
+  gpgsm->io_cbs.event_priv = NULL;
+
+#if !USE_DESCRIPTOR_PASSING
+  if (_gpgme_io_pipe (fds, 0) < 0)
+    {
+      err = gpg_error_from_errno (errno);
+      goto leave;
+    }
+  gpgsm->input_cb.fd = fds[1];
+  gpgsm->input_cb.server_fd = fds[0];
+
+  if (_gpgme_io_pipe (fds, 1) < 0)
+    {
+      err = gpg_error_from_errno (errno);
+      goto leave;
+    }
+  gpgsm->output_cb.fd = fds[0];
+  gpgsm->output_cb.server_fd = fds[1];
+
+  if (_gpgme_io_pipe (fds, 0) < 0)
+    {
+      err = gpg_error_from_errno (errno);
+      goto leave;
+    }
+  gpgsm->message_cb.fd = fds[1];
+  gpgsm->message_cb.server_fd = fds[0];
+
+  child_fds[0] = gpgsm->input_cb.server_fd;
+  child_fds[1] = gpgsm->output_cb.server_fd;
+  child_fds[2] = gpgsm->message_cb.server_fd;
+  child_fds[3] = -1;
+#endif
+
+  argc = 0;
+  argv[argc++] = "gpgsm";
+  if (home_dir)
+    {
+      argv[argc++] = "--homedir";
+      argv[argc++] = home_dir;
+    }
+  argv[argc++] = "--server";
+  argv[argc++] = NULL;
+
+#if USE_DESCRIPTOR_PASSING
+  err = assuan_pipe_connect_ext
+    (&gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (),
+     argv, NULL, NULL, NULL, 1);
+#else
+  err = assuan_pipe_connect
+    (&gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (),
+     argv, child_fds);
+#endif
+  if (err)
+    goto leave;
+
+  err = _gpgme_getenv ("DISPLAY", &dft_display);
+  if (err)
+    goto leave;
+  if (dft_display)
+    {
+      if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+        {
+	  free (dft_display);
+	  err = gpg_error_from_errno (errno);
+	  goto leave;
+	}
+      free (dft_display);
+
+      err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
+			     NULL, NULL, NULL);
+      free (optstr);
+      if (err)
+	{
+	  err = map_assuan_error (err);
+	  goto leave;
+	}
+    }
+
+  if (isatty (1))
+    {
+      if (ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)))
+	{
+	  err = gpg_error_from_errno (errno);
+	  goto leave;
+	}
+      else
+	{
+	  if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+	    {
+	      err = gpg_error_from_errno (errno);
+	      goto leave;
+	    }
+	  err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
+				 NULL, NULL, NULL);
+	  free (optstr);
+	  if (err)
+	    {
+	      err = map_assuan_error (err);
+	      goto leave;
+	    }
+
+	  err = _gpgme_getenv ("TERM", &dft_ttytype);
+	  if (err)
+	    goto leave;
+	  if (dft_ttytype)
+	    {
+	      if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+		{
+		  free (dft_ttytype);
+		  err = gpg_error_from_errno (errno);
+		  goto leave;
+		}
+	      free (dft_ttytype);
+
+	      err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL,
+				     NULL, NULL, NULL, NULL);
+	      free (optstr);
+	      if (err)
+		{
+		  err = map_assuan_error (err);
+		  goto leave;
+		}
+	    }
+	}
+    }
+
+#if !USE_DESCRIPTOR_PASSING
+  if (!err
+      && (_gpgme_io_set_close_notify (gpgsm->input_cb.fd,
+				      close_notify_handler, gpgsm)
+	  || _gpgme_io_set_close_notify (gpgsm->output_cb.fd,
+					 close_notify_handler, gpgsm)
+	  || _gpgme_io_set_close_notify (gpgsm->message_cb.fd,
+					 close_notify_handler, gpgsm)))
+    {
+      err = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
+    }
+#endif
+
+ leave:
+  /* Close the server ends of the pipes.  Our ends are closed in
+     gpgsm_release().  */
+#if !USE_DESCRIPTOR_PASSING
+  if (gpgsm->input_cb.server_fd != -1)
+    _gpgme_io_close (gpgsm->input_cb.server_fd);
+  if (gpgsm->output_cb.server_fd != -1)
+    _gpgme_io_close (gpgsm->output_cb.server_fd);
+  if (gpgsm->message_cb.server_fd != -1)
+    _gpgme_io_close (gpgsm->message_cb.server_fd);
+#endif
+
+  if (err)
+    gpgsm_release (gpgsm);
+  else
+    *engine = gpgsm;
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_set_locale (void *engine, int category, const char *value)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+  char *optstr;
+  char *catstr;
+
+  /* FIXME: If value is NULL, we need to reset the option to default.
+     But we can't do this.  So we error out here.  GPGSM needs support
+     for this.  */
+  if (category == LC_CTYPE)
+    {
+      catstr = "lc-ctype";
+      if (!value && gpgsm->lc_ctype_set)
+	return gpg_error (GPG_ERR_INV_VALUE);
+      if (value)
+	gpgsm->lc_ctype_set = 1;
+    }
+#ifdef LC_MESSAGES
+  else if (category == LC_MESSAGES)
+    {
+      catstr = "lc-messages";
+      if (!value && gpgsm->lc_messages_set)
+	return gpg_error (GPG_ERR_INV_VALUE);
+      if (value)
+	gpgsm->lc_messages_set = 1;
+    }
+#endif /* LC_MESSAGES */
+  else
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+    err = gpg_error_from_errno (errno);
+  else
+    {
+      err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL,
+			     NULL, NULL, NULL, NULL);
+      free (optstr);
+      if (err)
+	err = map_assuan_error (err);
+    }
+  return err;
+}
+
+
+/* Forward declaration.  */
+static gpgme_status_code_t parse_status (const char *name);
+
+static gpgme_error_t
+gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
+			     engine_status_handler_t status_fnc,
+			     void *status_fnc_value)
+{
+  gpg_error_t err;
+  char *line;
+  size_t linelen;
+
+  err = assuan_write_line (ctx, cmd);
+  if (err)
+    return map_assuan_error (err);
+
+  do
+    {
+      err = assuan_read_line (ctx, &line, &linelen);
+      if (err)
+	return map_assuan_error (err);
+
+      if (*line == '#' || !linelen)
+	continue;
+
+      if (linelen >= 2
+	  && line[0] == 'O' && line[1] == 'K'
+	  && (line[2] == '\0' || line[2] == ' '))
+	return 0;
+      else if (linelen >= 4
+	  && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
+	  && line[3] == ' ')
+	err = map_assuan_error (atoi (&line[4]));
+      else if (linelen >= 2
+	       && line[0] == 'S' && line[1] == ' ')
+	{
+	  char *rest;
+	  gpgme_status_code_t r;
+
+	  rest = strchr (line + 2, ' ');
+	  if (!rest)
+	    rest = line + linelen; /* set to an empty string */
+	  else
+	    *(rest++) = 0;
+
+	  r = parse_status (line + 2);
+
+	  if (r >= 0 && status_fnc)
+	    err = status_fnc (status_fnc_value, r, rest);
+	  else
+	    err = gpg_error (GPG_ERR_GENERAL);
+	}
+      else
+	err = gpg_error (GPG_ERR_GENERAL);
+    }
+  while (!err);
+
+  return err;
+}
+
+
+typedef enum { INPUT_FD, OUTPUT_FD, MESSAGE_FD } fd_type_t;
+
+static void
+gpgsm_clear_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type)
+{
+#if !USE_DESCRIPTOR_PASSING
+  switch (fd_type)
+    {
+    case INPUT_FD:
+      _gpgme_io_close (gpgsm->input_cb.fd);
+      break;
+    case OUTPUT_FD:
+      _gpgme_io_close (gpgsm->output_cb.fd);
+      break;
+    case MESSAGE_FD:
+      _gpgme_io_close (gpgsm->message_cb.fd);
+      break;
+    }
+#endif
+}
+
+#define COMMANDLINELEN 40
+static gpgme_error_t
+gpgsm_set_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type, const char *opt)
+{
+  gpg_error_t err = 0;
+  char line[COMMANDLINELEN];
+  char *which;
+  iocb_data_t *iocb_data;
+  int dir;
+  int fd;
+
+  switch (fd_type)
+    {
+    case INPUT_FD:
+      which = "INPUT";
+      iocb_data = &gpgsm->input_cb;
+      break;
+
+    case OUTPUT_FD:
+      which = "OUTPUT";
+      iocb_data = &gpgsm->output_cb;
+      break;
+
+    case MESSAGE_FD:
+      which = "MESSAGE";
+      iocb_data = &gpgsm->message_cb;
+      break;
+
+    default:
+      return gpg_error (GPG_ERR_INV_VALUE);
+    }
+
+  dir = iocb_data->dir;
+
+#if USE_DESCRIPTOR_PASSING
+  /* We try to short-cut the communication by giving GPGSM direct
+     access to the file descriptor, rather than using a pipe.  */
+  iocb_data->server_fd = _gpgme_data_get_fd (iocb_data->data);
+  if (iocb_data->server_fd < 0)
+    {
+      int fds[2];
+
+      if (_gpgme_io_pipe (fds, 0) < 0)
+	return gpg_error_from_errno (errno);
+
+      iocb_data->fd = dir ? fds[0] : fds[1];
+      iocb_data->server_fd = dir ? fds[1] : fds[0];
+
+      if (_gpgme_io_set_close_notify (iocb_data->fd,
+				      close_notify_handler, gpgsm))
+	{
+	  err = gpg_error (GPG_ERR_GENERAL);
+	  goto leave_set_fd;
+	}
+    }
+#endif
+
+  fd = iocb_data->server_fd;
+
+#if USE_DESCRIPTOR_PASSING
+  err = assuan_sendfd (gpgsm->assuan_ctx, fd);
+  if (err)
+    goto leave_set_fd;
+
+  _gpgme_io_close (fd);
+
+  if (opt)
+    snprintf (line, COMMANDLINELEN, "%s FD %s", which, opt);
+  else
+    snprintf (line, COMMANDLINELEN, "%s FD", which);
+#else
+  if (opt)
+    snprintf (line, COMMANDLINELEN, "%s FD=%i %s", which, fd, opt);
+  else
+    snprintf (line, COMMANDLINELEN, "%s FD=%i", which, fd);
+#endif
+
+  err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
+
+#if USE_DESCRIPTOR_PASSING
+ leave_set_fd:
+  if (err)
+    {
+      _gpgme_io_close (iocb_data->fd);
+      _gpgme_io_close (iocb_data->server_fd);
+      iocb_data->fd = -1;
+      iocb_data->server_fd = -1;
+    }
+#endif
+
+  return err;
+}
+
+
+static const char *
+map_input_enc (gpgme_data_t d)
+{
+  switch (gpgme_data_get_encoding (d))
+    {
+    case GPGME_DATA_ENCODING_NONE:
+      break;
+    case GPGME_DATA_ENCODING_BINARY:
+      return "--binary";
+    case GPGME_DATA_ENCODING_BASE64:
+      return "--base64";
+    case GPGME_DATA_ENCODING_ARMOR:
+      return "--armor";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+
+static int
+status_cmp (const void *ap, const void *bp)
+{
+  const struct status_table_s *a = ap;
+  const struct status_table_s *b = bp;
+
+  return strcmp (a->name, b->name);
+}
+
+
+static gpgme_status_code_t
+parse_status (const char *name)
+{
+  struct status_table_s t, *r;
+  t.name = name;
+  r = bsearch (&t, status_table, DIM(status_table) - 1,
+	       sizeof t, status_cmp);
+  return r ? r->code : -1;
+}
+
+
+static gpgme_error_t
+status_handler (void *opaque, int fd)
+{
+  gpg_error_t assuan_err;
+  gpgme_error_t err = 0;
+  engine_gpgsm_t gpgsm = opaque;
+  char *line;
+  size_t linelen;
+
+  do
+    {
+      assuan_err = assuan_read_line (gpgsm->assuan_ctx, &line, &linelen);
+      if (assuan_err)
+	{
+	  /* Try our best to terminate the connection friendly.  */
+	  /*	  assuan_write_line (gpgsm->assuan_ctx, "BYE"); */
+	  err = map_assuan_error (assuan_err);
+          DEBUG3 ("fd %d: error from assuan (%d) getting status line : %s \n",
+                  fd, assuan_err, gpg_strerror (err));
+	}
+      else if (linelen >= 3
+	       && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
+	       && (line[3] == '\0' || line[3] == ' '))
+	{
+	  if (line[3] == ' ')
+	    err = map_assuan_error (atoi (&line[4]));
+	  else
+	    err = gpg_error (GPG_ERR_GENERAL);
+          DEBUG2 ("fd %d: ERR line - mapped to: %s\n",
+                  fd, err? gpg_strerror (err):"ok");
+	}
+      else if (linelen >= 2
+	       && line[0] == 'O' && line[1] == 'K'
+	       && (line[2] == '\0' || line[2] == ' '))
+	{
+	  if (gpgsm->status.fnc)
+	    err = gpgsm->status.fnc (gpgsm->status.fnc_value,
+				     GPGME_STATUS_EOF, "");
+	  
+	  if (!err && gpgsm->colon.fnc && gpgsm->colon.any )
+            {
+              /* We must tell a colon function about the EOF. We do
+                 this only when we have seen any data lines.  Note
+                 that this inlined use of colon data lines will
+                 eventually be changed into using a regular data
+                 channel. */
+              gpgsm->colon.any = 0;
+              err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, NULL);
+            }
+	  _gpgme_io_close (gpgsm->status_cb.fd);
+          DEBUG2 ("fd %d: OK line - final status: %s\n",
+                  fd, err? gpg_strerror (err):"ok");
+	  return err;
+	}
+      else if (linelen > 2
+	       && line[0] == 'D' && line[1] == ' '
+	       && gpgsm->colon.fnc)
+        {
+	  /* We are using the colon handler even for plain inline data
+             - strange name for that function but for historic reasons
+             we keep it.  */
+          /* FIXME We can't use this for binary data because we
+             assume this is a string.  For the current usage of colon
+             output it is correct.  */
+          char *src = line + 2;
+	  char *end = line + linelen;
+	  char *dst;
+          char **aline = &gpgsm->colon.attic.line;
+	  int *alinelen = &gpgsm->colon.attic.linelen;
+
+	  if (gpgsm->colon.attic.linesize
+	      < *alinelen + linelen + 1)
+	    {
+	      char *newline = realloc (*aline, *alinelen + linelen + 1);
+	      if (!newline)
+		err = gpg_error_from_errno (errno);
+	      else
+		{
+		  *aline = newline;
+		  gpgsm->colon.attic.linesize += linelen + 1;
+		}
+	    }
+	  if (!err)
+	    {
+	      dst = *aline + *alinelen;
+
+	      while (!err && src < end)
+		{
+		  if (*src == '%' && src + 2 < end)
+		    {
+		      /* Handle escaped characters.  */
+		      ++src;
+		      *dst = _gpgme_hextobyte (src);
+		      (*alinelen)++;
+		      src += 2;
+		    }
+		  else
+		    {
+		      *dst = *src++;
+		      (*alinelen)++;
+		    }
+		  
+		  if (*dst == '\n')
+		    {
+		      /* Terminate the pending line, pass it to the colon
+			 handler and reset it.  */
+		      
+		      gpgsm->colon.any = 1;
+		      if (*alinelen > 1 && *(dst - 1) == '\r')
+			dst--;
+		      *dst = '\0';
+
+		      /* FIXME How should we handle the return code?  */
+		      err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, *aline);
+		      if (!err)
+			{
+			  dst = *aline;
+			  *alinelen = 0;
+			}
+		    }
+		  else
+		    dst++;
+		}
+	    }
+          DEBUG2 ("fd %d: D line; final status: %s\n",
+                  fd, err? gpg_strerror (err):"ok");
+        }
+      else if (linelen > 2
+	       && line[0] == 'S' && line[1] == ' ')
+	{
+	  char *rest;
+	  gpgme_status_code_t r;
+	  
+	  rest = strchr (line + 2, ' ');
+	  if (!rest)
+	    rest = line + linelen; /* set to an empty string */
+	  else
+	    *(rest++) = 0;
+
+	  r = parse_status (line + 2);
+
+	  if (r >= 0)
+	    {
+	      if (gpgsm->status.fnc)
+		err = gpgsm->status.fnc (gpgsm->status.fnc_value, r, rest);
+	    }
+	  else
+	    fprintf (stderr, "[UNKNOWN STATUS]%s %s", line + 2, rest);
+          DEBUG3 ("fd %d: S line (%s) - final status: %s\n",
+                  fd, line+2, err? gpg_strerror (err):"ok");
+	}
+    }
+  while (!err && assuan_pending_line (gpgsm->assuan_ctx));
+	  
+  return err;
+}
+
+
+static gpgme_error_t
+add_io_cb (engine_gpgsm_t gpgsm, iocb_data_t *iocbd, gpgme_io_cb_t handler)
+{
+  gpgme_error_t err;
+
+  err = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv,
+			      iocbd->fd, iocbd->dir,
+			      handler, iocbd->data, &iocbd->tag);
+  if (err)
+    return err;
+  if (!iocbd->dir)
+    /* FIXME Kludge around poll() problem.  */
+    err = _gpgme_io_set_nonblocking (iocbd->fd);
+  return err;
+}
+
+
+static gpgme_error_t
+start (engine_gpgsm_t gpgsm, const char *command)
+{
+  gpgme_error_t err;
+  int fdlist[5];
+  int nfds;
+
+  /* We need to know the fd used by assuan for reads.  We do this by
+     using the assumption that the first returned fd from
+     assuan_get_active_fds() is always this one.  */
+  nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
+                                fdlist, DIM (fdlist));
+  if (nfds < 1)
+    return gpg_error (GPG_ERR_GENERAL);	/* FIXME */
+
+  /* We duplicate the file descriptor, so we can close it without
+     disturbing assuan.  Alternatively, we could special case
+     status_fd and register/unregister it manually as needed, but this
+     increases code duplication and is more complicated as we can not
+     use the close notifications etc.  */
+  gpgsm->status_cb.fd = dup (fdlist[0]);
+  if (gpgsm->status_cb.fd < 0)
+    return gpg_error_from_syserror ();
+
+  if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
+				  close_notify_handler, gpgsm))
+    {
+      close (gpgsm->status_cb.fd);
+      gpgsm->status_cb.fd = -1;
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+
+  err = add_io_cb (gpgsm, &gpgsm->status_cb, status_handler);
+  if (!err && gpgsm->input_cb.fd != -1)
+    err = add_io_cb (gpgsm, &gpgsm->input_cb, _gpgme_data_outbound_handler);
+  if (!err && gpgsm->output_cb.fd != -1)
+    err = add_io_cb (gpgsm, &gpgsm->output_cb, _gpgme_data_inbound_handler);
+  if (!err && gpgsm->message_cb.fd != -1)
+    err = add_io_cb (gpgsm, &gpgsm->message_cb, _gpgme_data_outbound_handler);
+
+  if (!err)
+    err = map_assuan_error (assuan_write_line (gpgsm->assuan_ctx, command));
+
+  if (!err)
+    (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, GPGME_EVENT_START, NULL);
+
+  return err;
+}
+
+
+#if USE_DESCRIPTOR_PASSING
+static gpgme_error_t
+gpgsm_reset (void *engine)
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  /* We must send a reset because we need to reset the list of
+     signers.  Note that RESET does not reset OPTION commands. */
+  return gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET", NULL, NULL);
+}
+#endif
+
+
+static gpgme_error_t
+gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+
+  if (!gpgsm)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  gpgsm->input_cb.data = ciph;
+  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data));
+  if (err)
+    return gpg_error (GPG_ERR_GENERAL);	/* FIXME */
+  gpgsm->output_cb.data = plain;
+  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0);
+  if (err)
+    return gpg_error (GPG_ERR_GENERAL);	/* FIXME */
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (engine, "DECRYPT");
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_delete (void *engine, gpgme_key_t key, int allow_secret)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+  char *fpr = key->subkeys ? key->subkeys->fpr : NULL;
+  char *linep = fpr;
+  char *line;
+  int length = 8;	/* "DELKEYS " */
+
+  if (!fpr)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  while (*linep)
+    {
+      length++;
+      if (*linep == '%' || *linep == ' ' || *linep == '+')
+	length += 2;
+      linep++;
+    }
+  length++;
+
+  line = malloc (length);
+  if (!line)
+    return gpg_error_from_errno (errno);
+
+  strcpy (line, "DELKEYS ");
+  linep = &line[8];
+
+  while (*fpr)
+    {
+      switch (*fpr)
+	{
+	case '%':
+	  *(linep++) = '%';
+	  *(linep++) = '2';
+	  *(linep++) = '5';
+	  break;
+	case ' ':
+	  *(linep++) = '%';
+	  *(linep++) = '2';
+	  *(linep++) = '0';
+	  break;
+	case '+':
+	  *(linep++) = '%';
+	  *(linep++) = '2';
+	  *(linep++) = 'B';
+	  break;
+	default:
+	  *(linep++) = *fpr;
+	  break;
+	}
+      fpr++;
+    }
+  *linep = '\0';
+
+  gpgsm_clear_fd (gpgsm, OUTPUT_FD);
+  gpgsm_clear_fd (gpgsm, INPUT_FD);
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, line);
+  free (line);
+
+  return err;
+}
+
+
+static gpgme_error_t
+set_recipients (engine_gpgsm_t gpgsm, gpgme_key_t recp[])
+{
+  gpgme_error_t err = 0;
+  assuan_context_t ctx = gpgsm->assuan_ctx;
+  char *line;
+  int linelen;
+  int invalid_recipients = 0;
+  int i = 0;
+
+  linelen = 10 + 40 + 1;	/* "RECIPIENT " + guess + '\0'.  */
+  line = malloc (10 + 40 + 1);
+  if (!line)
+    return gpg_error_from_errno (errno);
+  strcpy (line, "RECIPIENT ");
+  while (!err && recp[i])
+    {
+      char *fpr;
+      int newlen;
+
+      if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
+	{
+	  invalid_recipients++;
+	  continue;
+	}
+      fpr = recp[i]->subkeys->fpr;
+
+      newlen = 11 + strlen (fpr);
+      if (linelen < newlen)
+	{
+	  char *newline = realloc (line, newlen);
+	  if (! newline)
+	    {
+	      int saved_errno = errno;
+	      free (line);
+	      return gpg_error_from_errno (saved_errno);
+	    }
+	  line = newline;
+	  linelen = newlen;
+	}
+      strcpy (&line[10], fpr);
+
+      err = gpgsm_assuan_simple_command (ctx, line, gpgsm->status.fnc,
+					 gpgsm->status.fnc_value);
+      /* FIXME: This requires more work.  */
+      if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
+	invalid_recipients++;
+      else if (err)
+	{
+	  free (line);
+	  return err;
+	}
+      i++;
+    }
+  free (line);
+  return gpg_error (invalid_recipients
+		    ? GPG_ERR_UNUSABLE_PUBKEY : GPG_ERR_NO_ERROR);
+}
+
+
+static gpgme_error_t
+gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
+	       gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+
+  if (!gpgsm)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!recp)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  gpgsm->input_cb.data = plain;
+  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data));
+  if (err)
+    return err;
+  gpgsm->output_cb.data = ciph;
+  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0);
+  if (err)
+    return err;
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = set_recipients (gpgsm, recp);
+
+  if (!err)
+    err = start (gpgsm, "ENCRYPT");
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_export (void *engine, const char *pattern, unsigned int reserved,
+	      gpgme_data_t keydata, int use_armor)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err = 0;
+  char *cmd;
+
+  if (!gpgsm || reserved)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!pattern)
+    pattern = "";
+
+  cmd = malloc (7 + strlen (pattern) + 1);
+  if (!cmd)
+    return gpg_error_from_errno (errno);
+  strcpy (cmd, "EXPORT ");
+  strcpy (&cmd[7], pattern);
+
+  gpgsm->output_cb.data = keydata;
+  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0);
+  if (err)
+    return err;
+  gpgsm_clear_fd (gpgsm, INPUT_FD);
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, cmd);
+  free (cmd);
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_export_ext (void *engine, const char *pattern[], unsigned int reserved,
+		  gpgme_data_t keydata, int use_armor)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err = 0;
+  char *line;
+  /* Length is "EXPORT " + p + '\0'.  */
+  int length = 7 + 1;
+  char *linep;
+
+  if (!gpgsm || reserved)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (pattern && *pattern)
+    {
+      const char **pat = pattern;
+
+      while (*pat)
+	{
+	  const char *patlet = *pat;
+
+	  while (*patlet)
+	    {
+	      length++;
+	      if (*patlet == '%' || *patlet == ' ' || *patlet == '+')
+		length += 2;
+	      patlet++;
+	    }
+	  pat++;
+	  length++;
+	}
+    }
+  line = malloc (length);
+  if (!line)
+    return gpg_error_from_errno (errno);
+
+  strcpy (line, "EXPORT ");
+  linep = &line[7];
+
+  if (pattern && *pattern)
+    {
+      while (*pattern)
+	{
+	  const char *patlet = *pattern;
+
+	  while (*patlet)
+	    {
+	      switch (*patlet)
+		{
+		case '%':
+		  *(linep++) = '%';
+		  *(linep++) = '2';
+		  *(linep++) = '5';
+		  break;
+		case ' ':
+		  *(linep++) = '%';
+		  *(linep++) = '2';
+		  *(linep++) = '0';
+		  break;
+		case '+':
+		  *(linep++) = '%';
+		  *(linep++) = '2';
+		  *(linep++) = 'B';
+		  break;
+		default:
+		  *(linep++) = *patlet;
+		  break;
+		}
+	      patlet++;
+	    }
+	  pattern++;
+          if (*pattern)
+            *linep++ = ' ';
+	}
+    }
+  *linep = '\0';
+
+  gpgsm->output_cb.data = keydata;
+  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0);
+  if (err)
+    return err;
+  gpgsm_clear_fd (gpgsm, INPUT_FD);
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, line);
+  free (line);
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_genkey (void *engine, gpgme_data_t help_data, int use_armor,
+	      gpgme_data_t pubkey, gpgme_data_t seckey)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+
+  if (!gpgsm || !pubkey || seckey)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  gpgsm->input_cb.data = help_data;
+  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data));
+  if (err)
+    return err;
+  gpgsm->output_cb.data = pubkey;
+  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0);
+  if (err)
+    return err;
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, "GENKEY");
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_import (void *engine, gpgme_data_t keydata)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+
+  if (!gpgsm)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  gpgsm->input_cb.data = keydata;
+  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data));
+  if (err)
+    return err;
+  gpgsm_clear_fd (gpgsm, OUTPUT_FD);
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, "IMPORT");
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_keylist (void *engine, const char *pattern, int secret_only,
+	       gpgme_keylist_mode_t mode)
+{
+  engine_gpgsm_t gpgsm = engine;
+  char *line;
+  gpgme_error_t err;
+  int list_mode = 0;
+
+  if (mode & GPGME_KEYLIST_MODE_LOCAL)
+    list_mode |= 1;
+  if (mode & GPGME_KEYLIST_MODE_EXTERN)
+    list_mode |= 2;
+
+  if (!pattern)
+    pattern = "";
+
+  /* Always send list-mode option because RESET does not reset it.  */
+  if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
+    return gpg_error_from_errno (errno);
+  err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
+  free (line);
+  if (err)
+    return err;
+
+
+  /* Always send key validation because RESET does not reset it.  */
+
+  /* Use the validation mode if required.  We don't check for an error
+     yet because this is a pretty fresh gpgsm features. */
+  gpgsm_assuan_simple_command (gpgsm->assuan_ctx, 
+                               (mode & GPGME_KEYLIST_MODE_VALIDATE)?
+                               "OPTION with-validation=1":
+                               "OPTION with-validation=0" ,
+                               NULL, NULL);
+
+
+  /* Length is "LISTSECRETKEYS " + p + '\0'.  */
+  line = malloc (15 + strlen (pattern) + 1);
+  if (!line)
+    return gpg_error_from_errno (errno);
+  if (secret_only)
+    {
+      strcpy (line, "LISTSECRETKEYS ");
+      strcpy (&line[15], pattern);
+    }
+  else
+    {
+      strcpy (line, "LISTKEYS ");
+      strcpy (&line[9], pattern);
+    }
+
+  gpgsm_clear_fd (gpgsm, INPUT_FD);
+  gpgsm_clear_fd (gpgsm, OUTPUT_FD);
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, line);
+  free (line);
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
+		   int reserved, gpgme_keylist_mode_t mode)
+{
+  engine_gpgsm_t gpgsm = engine;
+  char *line;
+  gpgme_error_t err;
+  /* Length is "LISTSECRETKEYS " + p + '\0'.  */
+  int length = 15 + 1;
+  char *linep;
+  int any_pattern = 0;
+  int list_mode = 0;
+
+  if (reserved)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (mode & GPGME_KEYLIST_MODE_LOCAL)
+    list_mode |= 1;
+  if (mode & GPGME_KEYLIST_MODE_EXTERN)
+    list_mode |= 2;
+
+  /* Always send list-mode option because RESET does not reset it.  */
+  if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
+    return gpg_error_from_errno (errno);
+  err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
+  free (line);
+  if (err)
+    return err;
+
+  /* Always send key validation because RESET does not reset it.  */
+  /* Use the validation mode if required.  We don't check for an error
+     yet because this is a pretty fresh gpgsm features. */
+  gpgsm_assuan_simple_command (gpgsm->assuan_ctx, 
+                               (mode & GPGME_KEYLIST_MODE_VALIDATE)?
+                               "OPTION with-validation=1":
+                               "OPTION with-validation=0" ,
+                               NULL, NULL);
+
+
+  if (pattern && *pattern)
+    {
+      const char **pat = pattern;
+
+      while (*pat)
+	{
+	  const char *patlet = *pat;
+
+	  while (*patlet)
+	    {
+	      length++;
+	      if (*patlet == '%' || *patlet == ' ' || *patlet == '+')
+		length += 2;
+	      patlet++;
+	    }
+	  pat++;
+	  length++;
+	}
+    }
+  line = malloc (length);
+  if (!line)
+    return gpg_error_from_errno (errno);
+  if (secret_only)
+    {
+      strcpy (line, "LISTSECRETKEYS ");
+      linep = &line[15];
+    }
+  else
+    {
+      strcpy (line, "LISTKEYS ");
+      linep = &line[9];
+    }
+
+  if (pattern && *pattern)
+    {
+      while (*pattern)
+	{
+	  const char *patlet = *pattern;
+
+	  while (*patlet)
+	    {
+	      switch (*patlet)
+		{
+		case '%':
+		  *(linep++) = '%';
+		  *(linep++) = '2';
+		  *(linep++) = '5';
+		  break;
+		case ' ':
+		  *(linep++) = '%';
+		  *(linep++) = '2';
+		  *(linep++) = '0';
+		  break;
+		case '+':
+		  *(linep++) = '%';
+		  *(linep++) = '2';
+		  *(linep++) = 'B';
+		  break;
+		default:
+		  *(linep++) = *patlet;
+		  break;
+		}
+	      patlet++;
+	    }
+          any_pattern = 1;
+          *linep++ = ' ';
+	  pattern++;
+	}
+    }
+  if (any_pattern)
+    linep--;
+  *linep = '\0';
+
+  gpgsm_clear_fd (gpgsm, INPUT_FD);
+  gpgsm_clear_fd (gpgsm, OUTPUT_FD);
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, line);
+  free (line);
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
+	    gpgme_sig_mode_t mode, int use_armor, int use_textmode,
+	    int include_certs, gpgme_ctx_t ctx /* FIXME */)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+  char *assuan_cmd;
+  int i;
+  gpgme_key_t key;
+
+  if (!gpgsm)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  /* FIXME: This does not work as RESET does not reset it so we can't
+     revert back to default.  */
+  if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT)
+    {
+      /* FIXME: Make sure that if we run multiple operations, that we
+	 can reset any previously set value in case the default is
+	 requested.  */
+
+      if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0)
+	return gpg_error_from_errno (errno);
+      err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, assuan_cmd,
+					 NULL, NULL);
+      free (assuan_cmd);
+      if (err)
+	return err;
+    }
+
+  for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
+    {
+      const char *s = key->subkeys ? key->subkeys->fpr : NULL;
+      if (s && strlen (s) < 80)
+	{
+          char buf[100];
+
+          strcpy (stpcpy (buf, "SIGNER "), s);
+          err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, buf,
+                                             NULL, NULL);
+	}
+      else
+        err = gpg_error (GPG_ERR_INV_VALUE);
+      gpgme_key_unref (key);
+      if (err) 
+        return err;
+    }
+
+  gpgsm->input_cb.data = in;
+  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data));
+  if (err)
+    return err;
+  gpgsm->output_cb.data = out;
+  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0);
+  if (err)
+    return err;
+  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+
+  err = start (gpgsm, mode == GPGME_SIG_MODE_DETACH
+	       ? "SIGN --detached" : "SIGN");
+  return err;
+}
+
+
+static gpgme_error_t
+gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
+	      gpgme_data_t plaintext)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgme_error_t err;
+
+  if (!gpgsm)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  gpgsm->input_cb.data = sig;
+  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_input_enc (gpgsm->input_cb.data));
+  if (err)
+    return err;
+  if (plaintext)
+    {
+      /* Normal or cleartext signature.  */
+      gpgsm->output_cb.data = plaintext;
+      err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0);
+      gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+    }
+  else
+    {
+      /* Detached signature.  */
+      gpgsm->message_cb.data = signed_text;
+      err = gpgsm_set_fd (gpgsm, MESSAGE_FD, 0);
+      gpgsm_clear_fd (gpgsm, OUTPUT_FD);
+    }
+
+  if (!err)
+    err = start (gpgsm, "VERIFY");
+
+  return err;
+}
+
+
+static void
+gpgsm_set_status_handler (void *engine, engine_status_handler_t fnc,
+			  void *fnc_value) 
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  gpgsm->status.fnc = fnc;
+  gpgsm->status.fnc_value = fnc_value;
+}
+
+
+static gpgme_error_t
+gpgsm_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc,
+			      void *fnc_value) 
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  gpgsm->colon.fnc = fnc;
+  gpgsm->colon.fnc_value = fnc_value;
+  gpgsm->colon.any = 0;
+  return 0;
+}
+
+
+static void
+gpgsm_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
+{
+  engine_gpgsm_t gpgsm = engine;
+  gpgsm->io_cbs = *io_cbs;
+}
+
+
+static void
+gpgsm_io_event (void *engine, gpgme_event_io_t type, void *type_data)
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  if (gpgsm->io_cbs.event)
+    (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, type, type_data);
+}
+
+
+struct engine_ops _gpgme_engine_ops_gpgsm =
+  {
+    /* Static functions.  */
+    _gpgme_get_gpgsm_path,
+    gpgsm_get_version,
+    gpgsm_get_req_version,
+    gpgsm_new,
+
+    /* Member functions.  */
+    gpgsm_release,
+#if USE_DESCRIPTOR_PASSING
+    gpgsm_reset,
+#else
+    NULL,			/* reset */
+#endif
+    gpgsm_set_status_handler,
+    NULL,		/* set_command_handler */
+    gpgsm_set_colon_line_handler,
+    gpgsm_set_locale,
+    gpgsm_decrypt,
+    gpgsm_delete,
+    NULL,		/* edit */
+    gpgsm_encrypt,
+    NULL,		/* encrypt_sign */
+    gpgsm_export,
+    gpgsm_export_ext,
+    gpgsm_genkey,
+    gpgsm_import,
+    gpgsm_keylist,
+    gpgsm_keylist_ext,
+    gpgsm_sign,
+    NULL,		/* trustlist */
+    gpgsm_verify,
+    gpgsm_set_io_cbs,
+    gpgsm_io_event,
+    gpgsm_cancel
+  };
+
+#endif /*!HAVE_W32_SYSTEM*/
diff --git a/libtdenetwork/libgpgme-copy/gpgme/engine.c b/libtdenetwork/libgpgme-copy/gpgme/engine.c
new file mode 100644
index 000000000..ae5bc8674
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/engine.c
@@ -0,0 +1,744 @@
+/* engine.c - GPGME engine support.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2006 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 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.
+   
+   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
+   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 <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "sema.h"
+#include "ops.h"
+
+#include "engine.h"
+#include "engine-backend.h"
+
+
+struct engine
+{
+  struct engine_ops *ops;
+  void *engine;
+};
+
+
+static struct engine_ops *engine_ops[] =
+  {
+    &_gpgme_engine_ops_gpg,		/* OpenPGP.  */
+#ifdef ENABLE_GPGSM
+    &_gpgme_engine_ops_gpgsm		/* CMS.  */
+#else
+    NULL
+#endif
+  };
+
+
+/* The engine info.  */
+static gpgme_engine_info_t engine_info;
+DEFINE_STATIC_LOCK (engine_info_lock);
+
+
+/* Get the file name of the engine for PROTOCOL.  */
+static const char *
+engine_get_file_name (gpgme_protocol_t proto)
+{
+  if (proto > DIM (engine_ops))
+    return NULL;
+
+  if (engine_ops[proto] && engine_ops[proto]->get_file_name)
+    return (*engine_ops[proto]->get_file_name) ();
+  else
+    return NULL;
+}
+
+
+/* Get a malloced string containing the version number of the engine
+   for PROTOCOL.  */
+static char *
+engine_get_version (gpgme_protocol_t proto, const char *file_name)
+{
+  if (proto > DIM (engine_ops))
+    return NULL;
+
+  if (engine_ops[proto] && engine_ops[proto]->get_version)
+    return (*engine_ops[proto]->get_version) (file_name);
+  else
+    return NULL;
+}
+
+
+/* Get the required version number of the engine for PROTOCOL.  */
+static const char *
+engine_get_req_version (gpgme_protocol_t proto)
+{
+  if (proto > DIM (engine_ops))
+    return NULL;
+
+  if (engine_ops[proto] && engine_ops[proto]->get_req_version)
+    return (*engine_ops[proto]->get_req_version) ();
+  else
+    return NULL;
+}
+
+
+/* Verify the version requirement for the engine for PROTOCOL.  */
+gpgme_error_t
+gpgme_engine_check_version (gpgme_protocol_t proto)
+{
+  gpgme_error_t err;
+  gpgme_engine_info_t info;
+  int result;
+
+  LOCK (engine_info_lock);
+  info = engine_info;
+  if (!info)
+    {
+      /* Make sure it is initialized.  */
+      UNLOCK (engine_info_lock);
+      err = gpgme_get_engine_info (&info);
+      if (err)
+	return err;
+
+      LOCK (engine_info_lock);
+    }
+
+  while (info && info->protocol != proto)
+    info = info->next;
+
+  if (!info)
+    result = 0;
+  else
+    result = _gpgme_compare_versions (info->version,
+				      info->req_version);
+
+  UNLOCK (engine_info_lock);
+  return result ? 0 : gpg_error (GPG_ERR_INV_ENGINE);
+}
+
+
+/* Release the engine info INFO.  */
+void
+_gpgme_engine_info_release (gpgme_engine_info_t info)
+{
+  while (info)
+    {
+      gpgme_engine_info_t next_info = info->next;
+
+      assert (info->file_name);
+      free (info->file_name);
+      if (info->home_dir)
+	free (info->home_dir);
+      if (info->version)
+	free (info->version);
+      free (info);
+      info = next_info;
+    }
+}
+
+
+/* Get the information about the configured and installed engines.  A
+   pointer to the first engine in the statically allocated linked list
+   is returned in *INFO.  If an error occurs, it is returned.  The
+   returned data is valid until the next gpgme_set_engine_info.  */
+gpgme_error_t
+gpgme_get_engine_info (gpgme_engine_info_t *info)
+{
+  LOCK (engine_info_lock);
+  if (!engine_info)
+    {
+      gpgme_engine_info_t *lastp = &engine_info;
+      gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
+					GPGME_PROTOCOL_CMS };
+      unsigned int proto;
+
+      for (proto = 0; proto < DIM (proto_list); proto++)
+	{
+	  const char *ofile_name = engine_get_file_name (proto_list[proto]);
+	  char *file_name;
+
+	  if (!ofile_name)
+	    continue;
+
+	  file_name = strdup (ofile_name);
+
+	  *lastp = malloc (sizeof (*engine_info));
+	  if (!*lastp || !file_name)
+	    {
+	      int saved_errno = errno;
+
+	      _gpgme_engine_info_release (engine_info);
+	      engine_info = NULL;
+
+	      if (file_name)
+		free (file_name);
+
+	      UNLOCK (engine_info_lock);
+	      return gpg_error_from_errno (saved_errno);
+	    }
+
+	  (*lastp)->protocol = proto_list[proto];
+	  (*lastp)->file_name = file_name;
+	  (*lastp)->home_dir = NULL;
+	  (*lastp)->version = engine_get_version (proto_list[proto], NULL);
+	  (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
+	  (*lastp)->next = NULL;
+	  lastp = &(*lastp)->next;
+	}
+    }
+
+  *info = engine_info;
+  UNLOCK (engine_info_lock);
+  return 0;
+}
+
+
+/* Get a deep copy of the engine info and return it in INFO.  */
+gpgme_error_t
+_gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
+{
+  gpgme_error_t err = 0;
+  gpgme_engine_info_t info;
+  gpgme_engine_info_t new_info;
+  gpgme_engine_info_t *lastp;
+
+  LOCK (engine_info_lock);
+  info = engine_info;
+  if (!info)
+    {
+      /* Make sure it is initialized.  */
+      UNLOCK (engine_info_lock);
+      err = gpgme_get_engine_info (&info);
+      if (err)
+	return err;
+
+      LOCK (engine_info_lock);
+    }
+
+  new_info = NULL;
+  lastp = &new_info;
+
+  while (info)
+    {
+      char *file_name;
+      char *home_dir;
+      char *version;
+
+      assert (info->file_name);
+      file_name = strdup (info->file_name);
+
+      if (info->home_dir)
+	{
+	  home_dir = strdup (info->home_dir);
+	  if (!home_dir)
+	    err = gpg_error_from_errno (errno);
+	}
+      else
+	home_dir = NULL;
+
+      if (info->version)
+	{
+	  version = strdup (info->version);
+	  if (!version)
+	    err = gpg_error_from_errno (errno);
+	}
+      else
+	version = NULL;
+
+      *lastp = malloc (sizeof (*engine_info));
+      if (!*lastp || !file_name || err)
+	{
+	  int saved_errno = errno;
+
+	  _gpgme_engine_info_release (new_info);
+
+	  if (file_name)
+	    free (file_name);
+	  if (home_dir)
+	    free (home_dir);
+	  if (version)
+	    free (version);
+
+	  UNLOCK (engine_info_lock);
+	  return gpg_error_from_errno (saved_errno);
+	}
+
+      (*lastp)->protocol = info->protocol;
+      (*lastp)->file_name = file_name;
+      (*lastp)->home_dir = home_dir;
+      (*lastp)->version = version;
+      (*lastp)->req_version = info->req_version;
+      (*lastp)->next = NULL;
+      lastp = &(*lastp)->next;
+
+      info = info->next;
+    }
+
+  *r_info = new_info;
+  UNLOCK (engine_info_lock);
+  return 0;
+}
+
+
+/* Set the engine info for the info list INFO, protocol PROTO, to the
+   file name FILE_NAME and the home directory HOME_DIR.  */
+gpgme_error_t
+_gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
+			const char *file_name, const char *home_dir)
+{
+  char *new_file_name;
+  char *new_home_dir;
+
+  /* FIXME: Use some PROTO_MAX definition.  */
+  if (proto > DIM (engine_ops))
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  while (info && info->protocol != proto)
+    info = info->next;
+
+  if (!info)
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  /* Prepare new members.  */
+  if (file_name)
+    new_file_name = strdup (file_name);
+  else
+    {
+      const char *ofile_name = engine_get_file_name (proto);
+      assert (ofile_name);
+      new_file_name = strdup (ofile_name);
+    }
+  if (!new_file_name)
+    return gpg_error_from_errno (errno);
+
+  if (home_dir)
+    {
+      new_home_dir = strdup (home_dir);
+      if (!new_home_dir)
+	{
+	  free (new_file_name);
+	  return gpg_error_from_errno (errno);
+	}
+    }
+  else
+    new_home_dir = NULL;
+
+  /* Remove the old members.  */
+  assert (info->file_name);
+  free (info->file_name);
+  if (info->home_dir)
+    free (info->home_dir);
+  if (info->version)
+    free (info->version);
+
+  /* Install the new members.  */
+  info->file_name = new_file_name;
+  info->home_dir = new_home_dir;
+  info->version = engine_get_version (proto, new_file_name);
+
+  return 0;
+}
+
+
+/* Set the default engine info for the protocol PROTO to the file name
+   FILE_NAME and the home directory HOME_DIR.  */
+gpgme_error_t
+gpgme_set_engine_info (gpgme_protocol_t proto,
+		       const char *file_name, const char *home_dir)
+{
+  gpgme_error_t err;
+  gpgme_engine_info_t info;
+
+  LOCK (engine_info_lock);
+  info = engine_info;
+  if (!info)
+    {
+      /* Make sure it is initialized.  */
+      UNLOCK (engine_info_lock);
+      err = gpgme_get_engine_info (&info);
+      if (err)
+	return err;
+
+      LOCK (engine_info_lock);
+    }
+
+  err = _gpgme_set_engine_info (info, proto, file_name, home_dir);
+  UNLOCK (engine_info_lock);
+  return err;
+}
+
+
+gpgme_error_t
+_gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
+{
+  engine_t engine;
+
+  if (!info->file_name || !info->version)
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  engine = calloc (1, sizeof *engine);
+  if (!engine)
+    return gpg_error_from_errno (errno);
+
+  engine->ops = engine_ops[info->protocol];
+  if (engine->ops->new)
+    {
+      gpgme_error_t err;
+      err = (*engine->ops->new) (&engine->engine,
+				 info->file_name, info->home_dir);
+      if (err)
+	{
+	  free (engine);
+	  return err;
+	}
+    }
+  else
+    engine->engine = NULL;
+
+  *r_engine = engine;
+  return 0;
+}
+
+
+gpgme_error_t
+_gpgme_engine_reset (engine_t engine)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->reset)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->reset) (engine->engine);
+}
+
+
+void
+_gpgme_engine_release (engine_t engine)
+{
+  if (!engine)
+    return;
+
+  if (engine->ops->release)
+    (*engine->ops->release) (engine->engine);
+  free (engine);
+}
+
+
+void
+_gpgme_engine_set_status_handler (engine_t engine,
+				  engine_status_handler_t fnc, void *fnc_value)
+{
+  if (!engine)
+    return;
+
+  if (engine->ops->set_status_handler)
+    (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
+}
+
+
+gpgme_error_t
+_gpgme_engine_set_command_handler (engine_t engine,
+				   engine_command_handler_t fnc,
+				   void *fnc_value,
+				   gpgme_data_t linked_data)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->set_command_handler)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->set_command_handler) (engine->engine,
+					      fnc, fnc_value, linked_data);
+}
+
+gpgme_error_t
+_gpgme_engine_set_colon_line_handler (engine_t engine,
+				      engine_colon_line_handler_t fnc,
+				      void *fnc_value)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->set_colon_line_handler)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->set_colon_line_handler) (engine->engine,
+						 fnc, fnc_value);
+}
+
+gpgme_error_t
+_gpgme_engine_set_locale (engine_t engine, int category,
+			  const char *value)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->set_locale)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->set_locale) (engine->engine, category, value);
+}
+
+gpgme_error_t
+_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
+			  gpgme_data_t plain)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->decrypt)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->decrypt) (engine->engine, ciph, plain);
+}
+
+gpgme_error_t
+_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
+			 int allow_secret)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->delete)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->delete) (engine->engine, key, allow_secret);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
+		       gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->edit)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->edit) (engine->engine, type, key, out, ctx);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
+			  gpgme_encrypt_flags_t flags,
+			  gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->encrypt)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
+				  use_armor);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
+			       gpgme_encrypt_flags_t flags,
+			       gpgme_data_t plain, gpgme_data_t ciph,
+			       int use_armor, gpgme_ctx_t ctx /* FIXME */)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->encrypt_sign)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
+				       plain, ciph, use_armor, ctx);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_export (engine_t engine, const char *pattern,
+			 unsigned int reserved, gpgme_data_t keydata,
+			 int use_armor)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->export)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->export) (engine->engine, pattern, reserved,
+				 keydata, use_armor);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
+			     unsigned int reserved, gpgme_data_t keydata,
+			     int use_armor)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->export_ext)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
+				     keydata, use_armor);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_genkey (engine_t engine, gpgme_data_t help_data,
+			 int use_armor, gpgme_data_t pubkey,
+			 gpgme_data_t seckey)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->genkey)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
+				 pubkey, seckey);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->import)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->import) (engine->engine, keydata);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_keylist (engine_t engine, const char *pattern,
+			  int secret_only, gpgme_keylist_mode_t mode)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->keylist)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
+			      int secret_only, int reserved,
+			      gpgme_keylist_mode_t mode)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->keylist_ext)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
+				      reserved, mode);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
+		       gpgme_sig_mode_t mode, int use_armor,
+		       int use_textmode, int include_certs,
+		       gpgme_ctx_t ctx /* FIXME */)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->sign)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
+			       use_textmode, include_certs, ctx);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->trustlist)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->trustlist) (engine->engine, pattern);
+}
+
+
+gpgme_error_t
+_gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
+			 gpgme_data_t signed_text, gpgme_data_t plaintext)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->verify)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
+}
+
+
+void
+_gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
+{
+  if (!engine)
+    return;
+
+  (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
+}
+
+
+void
+_gpgme_engine_io_event (engine_t engine,
+			gpgme_event_io_t type, void *type_data)
+{
+  if (!engine)
+    return;
+
+  (*engine->ops->io_event) (engine->engine, type, type_data);
+}
+
+
+gpgme_error_t
+_gpgme_engine_cancel (engine_t engine)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->cancel)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->cancel) (engine->engine);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/engine.h b/libtdenetwork/libgpgme-copy/gpgme/engine.h
new file mode 100644
index 000000000..079c215a1
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/engine.h
@@ -0,0 +1,133 @@
+/* engine.h - GPGME engine interface.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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 ENGINE_H
+#define ENGINE_H
+
+#include "gpgme.h"
+ 
+struct engine;
+typedef struct engine *engine_t;
+
+typedef gpgme_error_t (*engine_status_handler_t) (void *priv,
+						  gpgme_status_code_t code,
+						  char *args);
+typedef gpgme_error_t (*engine_colon_line_handler_t) (void *priv, char *line);
+typedef gpgme_error_t (*engine_command_handler_t) (void *priv,
+						   gpgme_status_code_t code,
+						   const char *keyword,
+						   int fd, int *processed);
+
+/* Get a deep copy of the engine info and return it in INFO.  */
+gpgme_error_t _gpgme_engine_info_copy (gpgme_engine_info_t *r_info);
+
+/* Release the engine info INFO.  */
+void _gpgme_engine_info_release (gpgme_engine_info_t info);
+
+/* Set the engine info for the info list INFO, protocol PROTO, to the
+   file name FILE_NAME and the home directory HOME_DIR.  */
+gpgme_error_t _gpgme_set_engine_info (gpgme_engine_info_t info,
+				      gpgme_protocol_t praoto,
+				      const char *file_name,
+				      const char *home_dir);
+
+
+gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info,
+				 engine_t *r_engine);
+gpgme_error_t _gpgme_engine_reset (engine_t engine);
+
+gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
+					const char *value);
+
+void _gpgme_engine_release (engine_t engine);
+void _gpgme_engine_set_status_handler (engine_t engine,
+				       engine_status_handler_t fnc,
+				       void *fnc_value);
+gpgme_error_t _gpgme_engine_set_command_handler (engine_t engine,
+						 engine_command_handler_t fnc,
+						 void *fnc_value,
+						 gpgme_data_t data);
+gpgme_error_t
+_gpgme_engine_set_colon_line_handler (engine_t engine,
+				      engine_colon_line_handler_t fnc,
+				      void *fnc_value);
+gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine,
+					gpgme_data_t ciph,
+					gpgme_data_t plain);
+gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
+				       int allow_secret);
+gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,
+				     gpgme_key_t key, gpgme_data_t out,
+				     gpgme_ctx_t ctx /* FIXME */);
+gpgme_error_t _gpgme_engine_op_encrypt (engine_t engine,
+					gpgme_key_t recp[],
+					gpgme_encrypt_flags_t flags,
+					gpgme_data_t plain, gpgme_data_t ciph,
+					int use_armor);
+gpgme_error_t _gpgme_engine_op_encrypt_sign (engine_t engine,
+					     gpgme_key_t recp[],
+					     gpgme_encrypt_flags_t flags,
+					     gpgme_data_t plain,
+					     gpgme_data_t ciph,
+					     int use_armor,
+					     gpgme_ctx_t ctx /* FIXME */);
+gpgme_error_t _gpgme_engine_op_export (engine_t engine, const char *pattern,
+				       unsigned int reserved,
+				       gpgme_data_t keydata, int use_armor);
+gpgme_error_t _gpgme_engine_op_export_ext (engine_t engine,
+					   const char *pattern[],
+					   unsigned int reserved,
+					   gpgme_data_t keydata,
+					   int use_armor);
+gpgme_error_t _gpgme_engine_op_genkey (engine_t engine,
+				       gpgme_data_t help_data,
+				       int use_armor, gpgme_data_t pubkey,
+				       gpgme_data_t seckey);
+gpgme_error_t _gpgme_engine_op_import (engine_t engine,
+				       gpgme_data_t keydata);
+gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,
+					const char *pattern,
+					int secret_only,
+					gpgme_keylist_mode_t mode);
+gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine,
+					    const char *pattern[],
+					    int secret_only,
+					    int reserved,
+					    gpgme_keylist_mode_t mode);
+gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in,
+				     gpgme_data_t out, gpgme_sig_mode_t mode,
+				     int use_armor, int use_textmode,
+				     int include_certs,
+				     gpgme_ctx_t ctx /* FIXME */);
+gpgme_error_t _gpgme_engine_op_trustlist (engine_t engine,
+					  const char *pattern);
+gpgme_error_t _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
+				       gpgme_data_t signed_text,
+				       gpgme_data_t plaintext);
+
+void _gpgme_engine_set_io_cbs (engine_t engine,
+			       gpgme_io_cbs_t io_cbs);
+void _gpgme_engine_io_event (engine_t engine,
+			     gpgme_event_io_t type, void *type_data);
+
+gpgme_error_t _gpgme_engine_cancel (engine_t engine);
+
+#endif /* ENGINE_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/error.c b/libtdenetwork/libgpgme-copy/gpgme/error.c
new file mode 100644
index 000000000..f0ea4929d
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/error.c
@@ -0,0 +1,92 @@
+/* error.c - Error handling for GPGME.
+   Copyright (C) 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gpgme.h>
+
+/* Return a pointer to a string containing a description of the error
+   code in the error value ERR.  */
+const char *
+gpgme_strerror (gpgme_error_t err)
+{
+  return gpg_strerror (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
+gpgme_strerror_r (gpg_error_t err, char *buf, size_t buflen)
+{
+  return gpg_strerror_r (err, buf, buflen);
+}
+
+
+/* Return a pointer to a string containing a description of the error
+   source in the error value ERR.  */
+const char *
+gpgme_strsource (gpgme_error_t err)
+{
+  return gpg_strsource (err);
+}
+
+  
+/* Retrieve the error code for the system error ERR.  This returns
+   GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+   this).  */
+gpgme_err_code_t
+gpgme_err_code_from_errno (int err)
+{
+  return gpg_err_code_from_errno (err);
+}
+
+
+/* Retrieve the system error for the error code CODE.  This returns 0
+   if CODE is not a system error code.  */
+int
+gpgme_err_code_to_errno (gpgme_err_code_t code)
+{
+  return gpg_err_code_from_errno (code);
+}
+
+  
+/* Return an error value with the error source SOURCE and the system
+   error ERR.  */
+gpgme_error_t
+gpgme_err_make_from_errno (gpg_err_source_t source, int err)
+{
+  return gpg_err_make_from_errno (source, err);
+}
+
+
+/* Return an error value with the system error ERR.  */
+gpgme_err_code_t
+gpgme_error_from_errno (int err)
+{
+  return gpgme_error (gpg_err_code_from_errno (err));
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/export.c b/libtdenetwork/libgpgme-copy/gpgme/export.c
new file mode 100644
index 000000000..176ec66c4
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/export.c
@@ -0,0 +1,117 @@
+/* export.c - Export a key.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+static gpgme_error_t
+export_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  return 0;
+}
+
+
+static gpgme_error_t
+export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
+	      unsigned int reserved, gpgme_data_t keydata)
+{
+  gpgme_error_t err;
+
+  if (!keydata)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
+
+  return _gpgme_engine_op_export (ctx->engine, pattern, reserved, keydata,
+				  ctx->use_armor);
+}
+
+
+/* Export the keys listed in RECP into KEYDATA.  */
+gpgme_error_t
+gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern,
+		       unsigned int reserved, gpgme_data_t keydata)
+{
+  return export_start (ctx, 0, pattern, reserved, keydata);
+}
+
+
+/* Export the keys listed in RECP into KEYDATA.  */
+gpgme_error_t
+gpgme_op_export (gpgme_ctx_t ctx, const char *pattern, unsigned int reserved,
+		 gpgme_data_t keydata)
+{
+  gpgme_error_t err = export_start (ctx, 1, pattern, reserved, keydata);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
+
+
+static gpgme_error_t
+export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
+		  unsigned int reserved, gpgme_data_t keydata)
+{
+  gpgme_error_t err;
+
+  if (!keydata)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
+
+  return _gpgme_engine_op_export_ext (ctx->engine, pattern, reserved, keydata,
+				      ctx->use_armor);
+}
+
+
+/* Export the keys listed in RECP into KEYDATA.  */
+gpgme_error_t
+gpgme_op_export_ext_start (gpgme_ctx_t ctx, const char *pattern[],
+			   unsigned int reserved, gpgme_data_t keydata)
+{
+  return export_ext_start (ctx, 0, pattern, reserved, keydata);
+}
+
+
+/* Export the keys listed in RECP into KEYDATA.  */
+gpgme_error_t
+gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[],
+		     unsigned int reserved, gpgme_data_t keydata)
+{
+  gpgme_error_t err = export_ext_start (ctx, 1, pattern, reserved, keydata);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/fakes.c b/libtdenetwork/libgpgme-copy/gpgme/fakes.c
new file mode 100644
index 000000000..44d5940f1
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/fakes.c
@@ -0,0 +1,24 @@
+#include <config.h>
+
+/** How can this work? The prototypes are not defined anywhere for code using those functions.... */
+
+#ifndef HAVE_STPCPY
+#include "stpcpy.c"
+#endif
+
+/*#ifndef HAVE_ISASCII
+#include "isascii.c"
+#endif*/
+
+#ifndef HAVE_PUTC_UNLOCKED
+#ifndef __FreeBSD__
+#include "putc_unlocked.c"
+#endif
+#endif
+
+#ifndef HAVE_MEMRCHR
+#include "memrchr.c"
+#endif
+
+
+
diff --git a/libtdenetwork/libgpgme-copy/gpgme/funopen.c b/libtdenetwork/libgpgme-copy/gpgme/funopen.c
new file mode 100644
index 000000000..67b6fc2b7
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/funopen.c
@@ -0,0 +1,43 @@
+/* funopen.c - Replacement for funopen.
+   Copyright (C) 2004 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 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.
+   
+   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
+   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>
+
+#ifdef HAVE_FOPENCOOKIE
+FILE *
+funopen(const 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 = { read: readfn, write: writefn, 
+			       seek: seekfn, close: closefn };
+
+  return fopencookie ((void *) cookie,
+		      readfn ? (writefn ? "rw" : "r")
+		      : (writefn ? "w" : ""), io);
+}
+#else
+#error No known way to implement funopen.
+#endif
diff --git a/libtdenetwork/libgpgme-copy/gpgme/genkey.c b/libtdenetwork/libgpgme-copy/gpgme/genkey.c
new file mode 100644
index 000000000..daaeb2848
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/genkey.c
@@ -0,0 +1,206 @@
+/* genkey.c - Key generation.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+typedef struct
+{
+  struct _gpgme_op_genkey_result result;
+
+  /* The key parameters passed to the crypto engine.  */
+  gpgme_data_t key_parameter;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+  
+  if (opd->result.fpr)
+    free (opd->result.fpr);
+  if (opd->key_parameter)
+    gpgme_data_release (opd->key_parameter);
+}
+
+
+gpgme_genkey_result_t
+gpgme_op_genkey_result (gpgme_ctx_t ctx)
+{
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook, -1, NULL);
+  opd = hook;
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+static gpgme_error_t
+genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  /* Pipe the status code through the progress status handler.  */
+  err = _gpgme_progress_status_handler (ctx, code, args);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  switch (code)
+    {
+    case GPGME_STATUS_KEY_CREATED:
+      if (args && *args)
+	{
+	  if (*args == 'B' || *args == 'P')
+	    opd->result.primary = 1;
+	  if (*args == 'B' || *args == 'S')
+	    opd->result.sub = 1;
+	  if (args[1] == ' ')
+	    {
+	      if (opd->result.fpr)
+		free (opd->result.fpr);
+	      opd->result.fpr = strdup (&args[2]);
+	      if (!opd->result.fpr)
+		return gpg_error_from_errno (errno);
+	    }
+	}
+      break;
+
+    case GPGME_STATUS_EOF:
+      /* FIXME: Should return some more useful error value.  */
+      if (!opd->result.primary && !opd->result.sub)
+	return gpg_error (GPG_ERR_GENERAL);
+      break;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+
+static gpgme_error_t
+get_key_parameter (const char *parms, gpgme_data_t *key_parameter)
+{
+  const char *content;
+  const char *attrib;
+  const char *endtag;
+
+  /* Extract the key parameter from the XML structure.  */
+  parms = strstr (parms, "<GnupgKeyParms ");
+  if (!parms)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  content = strchr (parms, '>');
+  if (!content)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  content++;
+
+  attrib = strstr (parms, "format=\"internal\"");
+  if (!attrib || attrib >= content)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  endtag = strstr (content, "</GnupgKeyParms>");
+  /* FIXME: Check that there are no control statements inside.  */
+  while (content[0] == '\n'
+	 || (content[0] == '\r' && content[1] == '\n'))
+    content++;
+
+  return gpgme_data_new_from_mem (key_parameter, content,
+				  endtag - content, 1);
+}
+
+
+static gpgme_error_t
+genkey_start (gpgme_ctx_t ctx, int synchronous, const char *parms,
+	      gpgme_data_t pubkey, gpgme_data_t seckey)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+  
+  err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  err = get_key_parameter (parms, &opd->key_parameter);
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
+
+  return _gpgme_engine_op_genkey (ctx->engine, opd->key_parameter,
+				  ctx->use_armor, pubkey, seckey);
+}
+
+
+/* Generate a new keypair and add it to the keyring.  PUBKEY and
+   SECKEY should be null for now.  PARMS specifies what keys should be
+   generated.  */
+gpgme_error_t
+gpgme_op_genkey_start (gpgme_ctx_t ctx, const char *parms,
+		       gpgme_data_t pubkey, gpgme_data_t seckey)
+{
+  return genkey_start (ctx, 0, parms, pubkey, seckey);
+}
+
+
+/* Generate a new keypair and add it to the keyring.  PUBKEY and
+   SECKEY should be null for now.  PARMS specifies what keys should be
+   generated.  */
+gpgme_error_t
+gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms, gpgme_data_t pubkey,
+		 gpgme_data_t seckey)
+{
+  gpgme_error_t err;
+
+  err = genkey_start (ctx, 1, parms, pubkey, seckey);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/get-env.c b/libtdenetwork/libgpgme-copy/gpgme/get-env.c
new file mode 100644
index 000000000..b5884048e
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/get-env.c
@@ -0,0 +1,59 @@
+/* get_env.c - A getenv() replacement.
+   Copyright (C) 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "util.h"
+
+
+#if defined(HAVE_THREAD_SAFE_GETENV) || !defined (HAVE_GETENV_R)
+/* We prefer using getenv() if it is thread-safe.  */
+
+/* Retrieve the environment variable NAME and return a copy of it in a
+   malloc()'ed buffer in *VALUE.  If the environment variable is not
+   set, return NULL in *VALUE.  */
+gpgme_error_t
+_gpgme_getenv (const char *name, char **value)
+{
+  char *env_value;
+
+  env_value = getenv (name);
+  if (!env_value)
+    *value = NULL;
+  else
+    {
+      *value = strdup (env_value);
+      if (!*value)
+	return gpg_error_from_errno (errno);
+    }
+  return 0;
+}
+
+#else
+
+/* FIXME: Implement this when we have the specification for it.  */
+#error Use of getenv_r not implemented.
+
+#endif
diff --git a/libtdenetwork/libgpgme-copy/gpgme/gpgme.c b/libtdenetwork/libgpgme-copy/gpgme/gpgme.c
new file mode 100644
index 000000000..9a2f90b8d
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/gpgme.c
@@ -0,0 +1,582 @@
+/* gpgme.c - GnuPG Made Easy.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <locale.h>
+
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+#include "wait.h"
+
+
+/* The default locale.  */
+DEFINE_STATIC_LOCK (def_lc_lock);
+static char *def_lc_ctype;
+static char *def_lc_messages;
+
+
+/* Create a new context as an environment for GPGME crypto
+   operations.  */
+gpgme_error_t
+gpgme_new (gpgme_ctx_t *r_ctx)
+{
+  gpgme_ctx_t ctx;
+
+  ctx = calloc (1, sizeof *ctx);
+  if (!ctx)
+    return gpg_error_from_errno (errno);
+
+  _gpgme_engine_info_copy (&ctx->engine_info);
+  if (!ctx->engine_info)
+    {
+      free (ctx);
+      return gpg_error_from_errno (errno);
+    }
+
+  ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
+  ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
+  ctx->protocol = GPGME_PROTOCOL_OpenPGP;
+  _gpgme_fd_table_init (&ctx->fdt);
+
+  LOCK (def_lc_lock);
+  if (def_lc_ctype)
+    {
+      ctx->lc_ctype = strdup (def_lc_ctype);
+      if (!ctx->lc_ctype)
+	{
+	  UNLOCK (def_lc_lock);
+	  _gpgme_engine_info_release (ctx->engine_info);
+	  free (ctx);
+	  return gpg_error_from_errno (errno);
+	}
+    }
+  else
+    def_lc_ctype = NULL;
+
+  if (def_lc_messages)
+    {
+      ctx->lc_messages = strdup (def_lc_messages);
+      if (!ctx->lc_messages)
+	{
+	  UNLOCK (def_lc_lock);
+	  if (ctx->lc_ctype)
+	    free (ctx->lc_ctype);
+	  _gpgme_engine_info_release (ctx->engine_info);
+	  free (ctx);
+	  return gpg_error_from_errno (errno);
+	}
+    }
+  else
+    def_lc_messages = NULL;
+  UNLOCK (def_lc_lock);
+
+  *r_ctx = ctx;
+  return 0;
+}
+
+
+/* Cancel a pending asynchronous operation.  */
+gpgme_error_t
+gpgme_cancel (gpgme_ctx_t ctx)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_engine_cancel (ctx->engine);
+  if (err)
+    return err;
+
+  err = gpg_error (GPG_ERR_CANCELED);
+  _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+
+  return 0;
+}
+
+/* Release all resources associated with the given context.  */
+void
+gpgme_release (gpgme_ctx_t ctx)
+{
+  _gpgme_engine_release (ctx->engine);
+  _gpgme_fd_table_deinit (&ctx->fdt);
+  _gpgme_release_result (ctx);
+  gpgme_signers_clear (ctx);
+  if (ctx->signers)
+    free (ctx->signers);
+  if (ctx->lc_ctype)
+    free (ctx->lc_ctype);
+  if (ctx->lc_messages)
+    free (ctx->lc_messages);
+  _gpgme_engine_info_release (ctx->engine_info);
+  free (ctx);
+}
+
+
+void
+_gpgme_release_result (gpgme_ctx_t ctx)
+{
+  struct ctx_op_data *data = ctx->op_data;
+
+  while (data)
+    {
+      struct ctx_op_data *next_data = data->next;
+      if (data->cleanup)
+	(*data->cleanup) (data->hook);
+      free (data);
+      data = next_data;
+    }
+  ctx->op_data = NULL;
+}
+
+
+gpgme_error_t
+gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
+{
+  if (protocol != GPGME_PROTOCOL_OpenPGP && protocol != GPGME_PROTOCOL_CMS)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (ctx->protocol != protocol)
+    {
+      /* Shut down the engine when switching protocols.  */
+      if (ctx->engine)
+	{
+	  _gpgme_engine_release (ctx->engine);
+	  ctx->engine = NULL;
+	}
+
+      ctx->protocol = protocol;
+    }
+  return 0;
+}
+
+
+gpgme_protocol_t
+gpgme_get_protocol (gpgme_ctx_t ctx)
+{
+  return ctx->protocol;
+}
+
+
+const char *
+gpgme_get_protocol_name (gpgme_protocol_t protocol)
+{
+  switch (protocol)
+    {
+    case GPGME_PROTOCOL_OpenPGP:
+      return "OpenPGP";
+
+    case GPGME_PROTOCOL_CMS:
+      return "CMS";
+
+    default:
+      return NULL;
+    }
+}
+
+/* Enable or disable the use of an ascii armor for all output.  */
+void
+gpgme_set_armor (gpgme_ctx_t ctx, int yes)
+{
+  ctx->use_armor = yes;
+}
+
+
+/* Return the state of the armor flag.  */
+int
+gpgme_get_armor (gpgme_ctx_t ctx)
+{
+  return ctx->use_armor;
+}
+
+
+/* Enable or disable the use of the special textmode.  Textmode is for
+  example used for the RFC2015 signatures; note that the updated RFC
+  3156 mandates that the MUA does some preparations so that textmode
+  is not needed anymore.  */
+void
+gpgme_set_textmode (gpgme_ctx_t ctx, int yes)
+{
+  ctx->use_textmode = yes;
+}
+
+/* Return the state of the textmode flag.  */
+int
+gpgme_get_textmode (gpgme_ctx_t ctx)
+{
+  return ctx->use_textmode;
+}
+
+
+/* Set the number of certifications to include in an S/MIME message.
+   The default is GPGME_INCLUDE_CERTS_DEFAULT.  -1 means all certs,
+   and -2 means all certs except the root cert.  */
+void
+gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
+{
+  if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
+    ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
+  else if (nr_of_certs < -2)
+    ctx->include_certs = -2;
+  else
+    ctx->include_certs = nr_of_certs;
+}
+
+
+/* Get the number of certifications to include in an S/MIME
+   message.  */
+int
+gpgme_get_include_certs (gpgme_ctx_t ctx)
+{
+  return ctx->include_certs;
+}
+
+
+/* This function changes the default behaviour of the keylisting
+   functions.  MODE is a bitwise-OR of the GPGME_KEYLIST_* flags.  The
+   default mode is GPGME_KEYLIST_MODE_LOCAL.  */
+gpgme_error_t
+gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
+{
+  ctx->keylist_mode = mode;
+  return 0;
+}
+
+/* This function returns the default behaviour of the keylisting
+   functions.  */
+gpgme_keylist_mode_t
+gpgme_get_keylist_mode (gpgme_ctx_t ctx)
+{
+  return ctx->keylist_mode;
+}
+
+
+/* This function sets a callback function to be used to pass a
+   passphrase to gpg.  */
+void
+gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
+			 void *cb_value)
+{
+  ctx->passphrase_cb = cb;
+  ctx->passphrase_cb_value = cb_value;
+}
+
+
+/* This function returns the callback function to be used to pass a
+   passphrase to the crypto engine.  */
+void
+gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
+			 void **r_cb_value)
+{
+  if (r_cb)
+    *r_cb = ctx->passphrase_cb;
+  if (r_cb_value)
+    *r_cb_value = ctx->passphrase_cb_value;
+}
+
+
+/* This function sets a callback function to be used as a progress
+   indicator.  */
+void
+gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
+{
+  ctx->progress_cb = cb;
+  ctx->progress_cb_value = cb_value;
+}
+
+
+/* This function returns the callback function to be used as a
+   progress indicator.  */
+void
+gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
+		       void **r_cb_value)
+{
+  if (r_cb)
+    *r_cb = ctx->progress_cb;
+  if (r_cb_value)
+    *r_cb_value = ctx->progress_cb_value;
+}
+
+
+/* Set the I/O callback functions for CTX to IO_CBS.  */
+void
+gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
+{
+  if (io_cbs)
+    ctx->io_cbs = *io_cbs;
+  else
+    {
+      ctx->io_cbs.add = NULL;
+      ctx->io_cbs.add_priv = NULL;
+      ctx->io_cbs.remove = NULL;
+      ctx->io_cbs.event = NULL;
+      ctx->io_cbs.event_priv = NULL;
+    }
+}
+
+
+/* This function returns the callback function for I/O.  */
+void
+gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
+{
+  *io_cbs = ctx->io_cbs;
+}
+
+
+/* This function sets the locale for the context CTX, or the default
+   locale if CTX is a null pointer.  */
+gpgme_error_t
+gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
+{
+  int failed = 0;
+  char *new_lc_ctype = NULL;
+  char *new_lc_messages = NULL;
+
+#define PREPARE_ONE_LOCALE(lcat, ucat)				\
+  if (!failed && value						\
+      && (category == LC_ALL || category == LC_ ## ucat))	\
+    {								\
+      new_lc_ ## lcat = strdup (value);				\
+      if (!new_lc_ ## lcat)					\
+        failed = 1;						\
+    }
+
+  PREPARE_ONE_LOCALE (ctype, CTYPE);
+#ifdef LC_MESSAGES
+  PREPARE_ONE_LOCALE (messages, MESSAGES);
+#endif
+
+  if (failed)
+    {
+      int saved_errno = errno;
+
+      if (new_lc_ctype)
+	free (new_lc_ctype);
+      if (new_lc_messages)
+	free (new_lc_messages);
+
+      return gpg_error_from_errno (saved_errno);
+    }
+
+#define SET_ONE_LOCALE(lcat, ucat)			\
+  if (category == LC_ALL || category == LC_ ## ucat)	\
+    {							\
+      if (ctx)						\
+	{						\
+	  if (ctx->lc_ ## lcat)				\
+	    free (ctx->lc_ ## lcat);			\
+	  ctx->lc_ ## lcat = new_lc_ ## lcat;		\
+	}						\
+      else						\
+	{						\
+	  if (def_lc_ ## lcat)				\
+	    free (def_lc_ ## lcat);			\
+	  def_lc_ ## lcat = new_lc_ ## lcat;		\
+	}						\
+    }
+
+  if (!ctx)
+    LOCK (def_lc_lock);
+  SET_ONE_LOCALE (ctype, CTYPE);
+#ifdef LC_MESSAGES
+  SET_ONE_LOCALE (messages, MESSAGES);
+#endif
+  if (!ctx)
+    UNLOCK (def_lc_lock);
+
+  return 0;
+}
+
+
+/* Get the information about the configured engines.  A pointer to the
+   first engine in the statically allocated linked list is returned.
+   The returned data is valid until the next gpgme_ctx_set_engine_info.  */
+gpgme_engine_info_t
+gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
+{
+  return ctx->engine_info;
+}
+
+
+/* Set the engine info for the context CTX, protocol PROTO, to the
+   file name FILE_NAME and the home directory HOME_DIR.  */
+gpgme_error_t
+gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
+			   const char *file_name, const char *home_dir)
+{
+  /* Shut down the engine when changing engine info.  */
+  if (ctx->engine)
+    {
+      _gpgme_engine_release (ctx->engine);
+      ctx->engine = NULL;
+    }
+  return _gpgme_set_engine_info (ctx->engine_info, proto,
+				 file_name, home_dir);
+}
+
+
+/* Clear all notation data from the context.  */
+void
+gpgme_sig_notation_clear (gpgme_ctx_t ctx)
+{
+  gpgme_sig_notation_t notation;
+
+  if (!ctx)
+    return;
+
+  notation = ctx->sig_notations;
+  while (notation)
+    {
+      gpgme_sig_notation_t next_notation = notation->next;
+      _gpgme_sig_notation_free (notation);
+      notation = next_notation;
+    }
+}
+
+
+/* Add the human-readable notation data with name NAME and value VALUE
+   to the context CTX, using the flags FLAGS.  If NAME is NULL, then
+   VALUE should be a policy URL.  The flag
+   GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
+   data, and false for policy URLs.  */
+gpgme_error_t
+gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
+			const char *value, gpgme_sig_notation_flags_t flags)
+{
+  gpgme_error_t err;
+  gpgme_sig_notation_t notation;
+  gpgme_sig_notation_t *lastp;
+
+  if (!ctx)
+     gpg_error (GPG_ERR_INV_VALUE);
+
+  if (name)
+    flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
+  else
+    flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
+
+  err = _gpgme_sig_notation_create (&notation, name, name ? strlen (name) : 0,
+				    value, value ? strlen (value) : 0, flags);
+  if (err)
+    return err;
+
+  lastp = &ctx->sig_notations;
+  while (*lastp)
+    lastp = &(*lastp)->next;
+
+  *lastp = notation;
+  return 0;
+}
+
+
+/* Get the sig notations for this context.  */
+gpgme_sig_notation_t
+gpgme_sig_notation_get (gpgme_ctx_t ctx)
+{
+  if (!ctx)
+    return NULL;
+
+  return ctx->sig_notations;
+}
+  
+
+const char *
+gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
+{
+  switch (algo)
+    {
+    case GPGME_PK_RSA:
+      return "RSA";
+
+    case GPGME_PK_RSA_E:
+      return "RSA-E";
+
+    case GPGME_PK_RSA_S:
+      return "RSA-S";
+
+    case GPGME_PK_ELG_E:
+      return "ELG-E";
+
+    case GPGME_PK_DSA:
+      return "DSA";
+
+    case GPGME_PK_ELG:
+      return "ELG";
+
+    default:
+      return NULL;
+    }
+}
+
+
+const char *
+gpgme_hash_algo_name (gpgme_hash_algo_t algo)
+{
+  switch (algo)
+    {
+    case GPGME_MD_MD5:
+      return "MD5";
+
+    case GPGME_MD_SHA1:
+      return "SHA1";
+
+    case GPGME_MD_RMD160:
+      return "RIPEMD160";
+
+    case GPGME_MD_MD2:
+      return "MD2";
+
+    case GPGME_MD_TIGER:
+      return "TIGER192";
+
+    case GPGME_MD_HAVAL:
+      return "HAVAL";
+
+    case GPGME_MD_SHA256:
+      return "SHA256";
+
+    case GPGME_MD_SHA384:
+      return "SHA384";
+
+    case GPGME_MD_SHA512:
+      return "SHA512";
+
+    case GPGME_MD_MD4:
+      return "MD4";
+
+    case GPGME_MD_CRC32:
+      return "CRC32";
+
+    case GPGME_MD_CRC32_RFC1510:
+      return "CRC32RFC1510";
+
+    case GPGME_MD_CRC24_RFC2440:
+      return "CRC24RFC2440";
+
+    default:
+      return NULL;
+    }
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/gpgme.h b/libtdenetwork/libgpgme-copy/gpgme/gpgme.h
new file mode 100644
index 000000000..f6f31ae2a
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/gpgme.h
@@ -0,0 +1,1706 @@
+/* gpgme.h - Public interface to GnuPG Made Easy.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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 GPGME_H
+#define GPGME_H
+
+#ifdef __GNUC__
+#define _GPGME_INLINE __inline__
+#elif __STDC_VERSION__ >= 199901L
+#define _GPGME_INLINE inline
+#else
+#define _GPGME_INLINE
+#endif
+
+/* Include stdio.h for the FILE type definition.  */
+#include <stdio.h>
+
+#ifdef _MSC_VER
+  typedef long off_t;
+  typedef long ssize_t;
+#else
+# include <sys/types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* just to make Emacs auto-indent happy */
+}
+#endif
+#endif /* __cplusplus */
+
+#include <gpg-error.h>
+
+
+/* Check for compiler features.  */
+#if __GNUC__
+#define _GPGME_GCC_VERSION (__GNUC__ * 10000 \
+                            + __GNUC_MINOR__ * 100 \
+                            + __GNUC_PATCHLEVEL__)
+
+#if _GPGME_GCC_VERSION > 30100
+#define _GPGME_DEPRECATED	__attribute__ ((__deprecated__))
+#endif
+#endif
+
+#ifndef _GPGME_DEPRECATED
+#define _GPGME_DEPRECATED
+#endif
+
+
+/* The version of this header should match the one of the library.  Do
+   not use this symbol in your application, use gpgme_check_version
+   instead.  The purpose of this macro is to let autoconf (using the
+   AM_PATH_GPGME macro) check that this header matches the installed
+   library.  Warning: Do not edit the next line.  configure will do
+   that for you!  */
+#define GPGME_VERSION "1.1.4"
+
+
+
+/* Some opaque data types used by GPGME.  */
+
+/* The context holds some global state and configration options, as
+   well as the results of a crypto operation.  */
+struct gpgme_context;
+typedef struct gpgme_context *gpgme_ctx_t;
+
+/* The data object is used by GPGME to exchange arbitrary data.  */
+struct gpgme_data;
+typedef struct gpgme_data *gpgme_data_t;
+
+
+/* Wrappers for the libgpg-error library.  */
+
+typedef gpg_error_t gpgme_error_t;
+typedef gpg_err_code_t gpgme_err_code_t;
+typedef gpg_err_source_t gpgme_err_source_t;
+
+
+static _GPGME_INLINE gpgme_error_t
+gpgme_err_make (gpgme_err_source_t source, gpgme_err_code_t code)
+{
+  return gpg_err_make (source, code);
+}
+
+
+/* The user can define GPGME_ERR_SOURCE_DEFAULT before including this
+   file to specify a default source for gpgme_error.  */
+#ifndef GPGME_ERR_SOURCE_DEFAULT
+#define GPGME_ERR_SOURCE_DEFAULT  GPG_ERR_SOURCE_USER_1
+#endif
+
+static _GPGME_INLINE gpgme_error_t
+gpgme_error (gpgme_err_code_t code)
+{
+  return gpgme_err_make (GPGME_ERR_SOURCE_DEFAULT, code);
+}
+
+
+static _GPGME_INLINE gpgme_err_code_t
+gpgme_err_code (gpgme_error_t err)
+{
+  return gpg_err_code (err);
+}
+
+
+static _GPGME_INLINE gpgme_err_source_t
+gpgme_err_source (gpgme_error_t err)
+{
+  return gpg_err_source (err);
+}
+
+
+/* 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 *gpgme_strerror (gpgme_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 gpgme_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 *gpgme_strsource (gpgme_error_t err);
+
+
+/* Retrieve the error code for the system error ERR.  This returns
+   GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+   this).  */
+gpgme_err_code_t gpgme_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 gpgme_err_code_to_errno (gpgme_err_code_t code);
+
+  
+/* Return an error value with the error source SOURCE and the system
+   error ERR.  */
+gpgme_error_t gpgme_err_make_from_errno (gpgme_err_source_t source, int err);
+
+
+/* Return an error value with the system error ERR.  */
+gpgme_err_code_t gpgme_error_from_errno (int err);
+
+
+/* The possible encoding mode of gpgme_data_t objects.  */
+typedef enum
+  {
+    GPGME_DATA_ENCODING_NONE   = 0,	/* Not specified.  */
+    GPGME_DATA_ENCODING_BINARY = 1,
+    GPGME_DATA_ENCODING_BASE64 = 2,
+    GPGME_DATA_ENCODING_ARMOR  = 3	/* Either PEM or OpenPGP Armor.  */
+  }
+gpgme_data_encoding_t;
+
+
+/* Public key algorithms from libgcrypt.  */
+typedef enum
+  {
+    GPGME_PK_RSA   = 1,
+    GPGME_PK_RSA_E = 2,
+    GPGME_PK_RSA_S = 3,
+    GPGME_PK_ELG_E = 16,
+    GPGME_PK_DSA   = 17,
+    GPGME_PK_ELG   = 20
+  }
+gpgme_pubkey_algo_t;
+
+
+/* Hash algorithms from libgcrypt.  */
+typedef enum
+  {
+    GPGME_MD_NONE          = 0,  
+    GPGME_MD_MD5           = 1,
+    GPGME_MD_SHA1          = 2,
+    GPGME_MD_RMD160        = 3,
+    GPGME_MD_MD2           = 5,
+    GPGME_MD_TIGER         = 6,   /* TIGER/192. */
+    GPGME_MD_HAVAL         = 7,   /* HAVAL, 5 pass, 160 bit. */
+    GPGME_MD_SHA256        = 8,
+    GPGME_MD_SHA384        = 9,
+    GPGME_MD_SHA512        = 10,
+    GPGME_MD_MD4           = 301,
+    GPGME_MD_CRC32	   = 302,
+    GPGME_MD_CRC32_RFC1510 = 303,
+    GPGME_MD_CRC24_RFC2440 = 304
+  }
+gpgme_hash_algo_t;
+
+
+/* The possible signature stati.  Deprecated, use error value in sig
+   status.  */
+typedef enum
+  {
+    GPGME_SIG_STAT_NONE  = 0,
+    GPGME_SIG_STAT_GOOD  = 1,
+    GPGME_SIG_STAT_BAD   = 2,
+    GPGME_SIG_STAT_NOKEY = 3,
+    GPGME_SIG_STAT_NOSIG = 4,
+    GPGME_SIG_STAT_ERROR = 5,
+    GPGME_SIG_STAT_DIFF  = 6,
+    GPGME_SIG_STAT_GOOD_EXP = 7,
+    GPGME_SIG_STAT_GOOD_EXPKEY = 8
+  }
+_gpgme_sig_stat_t;
+typedef _gpgme_sig_stat_t gpgme_sig_stat_t _GPGME_DEPRECATED;
+
+
+/* The available signature modes.  */
+typedef enum
+  {
+    GPGME_SIG_MODE_NORMAL = 0,
+    GPGME_SIG_MODE_DETACH = 1,
+    GPGME_SIG_MODE_CLEAR  = 2
+  }
+gpgme_sig_mode_t;
+
+
+/* The available key and signature attributes.  Deprecated, use the
+   individual result structures instead.  */
+typedef enum
+  {
+    GPGME_ATTR_KEYID        = 1,
+    GPGME_ATTR_FPR          = 2,
+    GPGME_ATTR_ALGO         = 3,
+    GPGME_ATTR_LEN          = 4,
+    GPGME_ATTR_CREATED      = 5,
+    GPGME_ATTR_EXPIRE       = 6,
+    GPGME_ATTR_OTRUST       = 7,
+    GPGME_ATTR_USERID       = 8,
+    GPGME_ATTR_NAME         = 9,
+    GPGME_ATTR_EMAIL        = 10,
+    GPGME_ATTR_COMMENT      = 11,
+    GPGME_ATTR_VALIDITY     = 12,
+    GPGME_ATTR_LEVEL        = 13,
+    GPGME_ATTR_TYPE         = 14,
+    GPGME_ATTR_IS_SECRET    = 15,
+    GPGME_ATTR_KEY_REVOKED  = 16,
+    GPGME_ATTR_KEY_INVALID  = 17,
+    GPGME_ATTR_UID_REVOKED  = 18,
+    GPGME_ATTR_UID_INVALID  = 19,
+    GPGME_ATTR_KEY_CAPS     = 20,
+    GPGME_ATTR_CAN_ENCRYPT  = 21,
+    GPGME_ATTR_CAN_SIGN     = 22,
+    GPGME_ATTR_CAN_CERTIFY  = 23,
+    GPGME_ATTR_KEY_EXPIRED  = 24,
+    GPGME_ATTR_KEY_DISABLED = 25,
+    GPGME_ATTR_SERIAL       = 26,
+    GPGME_ATTR_ISSUER       = 27,
+    GPGME_ATTR_CHAINID      = 28,
+    GPGME_ATTR_SIG_STATUS   = 29,
+    GPGME_ATTR_ERRTOK       = 30,
+    GPGME_ATTR_SIG_SUMMARY  = 31,
+    GPGME_ATTR_SIG_CLASS    = 32
+  }
+_gpgme_attr_t;
+typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED;
+
+
+/* The available validities for a trust item or key.  */
+typedef enum
+  {
+    GPGME_VALIDITY_UNKNOWN   = 0,
+    GPGME_VALIDITY_UNDEFINED = 1,
+    GPGME_VALIDITY_NEVER     = 2,
+    GPGME_VALIDITY_MARGINAL  = 3,
+    GPGME_VALIDITY_FULL      = 4,
+    GPGME_VALIDITY_ULTIMATE  = 5
+  }
+gpgme_validity_t;
+
+
+/* The available protocols.  */
+typedef enum
+  {
+    GPGME_PROTOCOL_OpenPGP = 0,  /* The default mode.  */
+    GPGME_PROTOCOL_CMS     = 1
+  }
+gpgme_protocol_t;
+
+
+/* The available keylist mode flags.  */
+#define GPGME_KEYLIST_MODE_LOCAL		1
+#define GPGME_KEYLIST_MODE_EXTERN		2
+#define GPGME_KEYLIST_MODE_SIGS			4
+#define GPGME_KEYLIST_MODE_SIG_NOTATIONS	8
+#define GPGME_KEYLIST_MODE_VALIDATE		256
+
+typedef unsigned int gpgme_keylist_mode_t;
+
+
+/* Signature notations.  */
+
+/* The available signature notation flags.  */
+#define GPGME_SIG_NOTATION_HUMAN_READABLE	1
+#define GPGME_SIG_NOTATION_CRITICAL		2
+
+typedef unsigned int gpgme_sig_notation_flags_t;
+
+struct _gpgme_sig_notation
+{
+  struct _gpgme_sig_notation *next;
+
+  /* If NAME is a null pointer, then VALUE contains a policy URL
+     rather than a notation.  */
+  char *name;
+
+  /* The value of the notation data.  */
+  char *value;
+
+  /* The length of the name of the notation data.  */
+  int name_len;
+
+  /* The length of the value of the notation data.  */
+  int value_len;
+
+  /* The accumulated flags.  */
+  gpgme_sig_notation_flags_t flags;
+
+  /* Notation data is human-readable.  */
+  unsigned int human_readable : 1;
+
+  /* Notation data is critical.  */
+  unsigned int critical : 1;
+
+  /* Internal to GPGME, do not use.  */
+  int _unused : 30;
+};
+typedef struct _gpgme_sig_notation *gpgme_sig_notation_t;
+
+
+/* The possible stati for the edit operation.  */
+typedef enum
+  {
+    GPGME_STATUS_EOF,
+    /* mkstatus processing starts here */
+    GPGME_STATUS_ENTER,
+    GPGME_STATUS_LEAVE,
+    GPGME_STATUS_ABORT,
+
+    GPGME_STATUS_GOODSIG,
+    GPGME_STATUS_BADSIG,
+    GPGME_STATUS_ERRSIG,
+
+    GPGME_STATUS_BADARMOR,
+
+    GPGME_STATUS_RSA_OR_IDEA,
+    GPGME_STATUS_KEYEXPIRED,
+    GPGME_STATUS_KEYREVOKED,
+
+    GPGME_STATUS_TRUST_UNDEFINED,
+    GPGME_STATUS_TRUST_NEVER,
+    GPGME_STATUS_TRUST_MARGINAL,
+    GPGME_STATUS_TRUST_FULLY,
+    GPGME_STATUS_TRUST_ULTIMATE,
+
+    GPGME_STATUS_SHM_INFO,
+    GPGME_STATUS_SHM_GET,
+    GPGME_STATUS_SHM_GET_BOOL,
+    GPGME_STATUS_SHM_GET_HIDDEN,
+
+    GPGME_STATUS_NEED_PASSPHRASE,
+    GPGME_STATUS_VALIDSIG,
+    GPGME_STATUS_SIG_ID,
+    GPGME_STATUS_ENC_TO,
+    GPGME_STATUS_NODATA,
+    GPGME_STATUS_BAD_PASSPHRASE,
+    GPGME_STATUS_NO_PUBKEY,
+    GPGME_STATUS_NO_SECKEY,
+    GPGME_STATUS_NEED_PASSPHRASE_SYM,
+    GPGME_STATUS_DECRYPTION_FAILED,
+    GPGME_STATUS_DECRYPTION_OKAY,
+    GPGME_STATUS_MISSING_PASSPHRASE,
+    GPGME_STATUS_GOOD_PASSPHRASE,
+    GPGME_STATUS_GOODMDC,
+    GPGME_STATUS_BADMDC,
+    GPGME_STATUS_ERRMDC,
+    GPGME_STATUS_IMPORTED,
+    GPGME_STATUS_IMPORT_OK,
+    GPGME_STATUS_IMPORT_PROBLEM,
+    GPGME_STATUS_IMPORT_RES,
+    GPGME_STATUS_FILE_START,
+    GPGME_STATUS_FILE_DONE,
+    GPGME_STATUS_FILE_ERROR,
+
+    GPGME_STATUS_BEGIN_DECRYPTION,
+    GPGME_STATUS_END_DECRYPTION,
+    GPGME_STATUS_BEGIN_ENCRYPTION,
+    GPGME_STATUS_END_ENCRYPTION,
+
+    GPGME_STATUS_DELETE_PROBLEM,
+    GPGME_STATUS_GET_BOOL,
+    GPGME_STATUS_GET_LINE,
+    GPGME_STATUS_GET_HIDDEN,
+    GPGME_STATUS_GOT_IT,
+    GPGME_STATUS_PROGRESS,
+    GPGME_STATUS_SIG_CREATED,
+    GPGME_STATUS_SESSION_KEY,
+    GPGME_STATUS_NOTATION_NAME,
+    GPGME_STATUS_NOTATION_DATA,
+    GPGME_STATUS_POLICY_URL,
+    GPGME_STATUS_BEGIN_STREAM,
+    GPGME_STATUS_END_STREAM,
+    GPGME_STATUS_KEY_CREATED,
+    GPGME_STATUS_USERID_HINT,
+    GPGME_STATUS_UNEXPECTED,
+    GPGME_STATUS_INV_RECP,
+    GPGME_STATUS_NO_RECP,
+    GPGME_STATUS_ALREADY_SIGNED,
+    GPGME_STATUS_SIGEXPIRED,
+    GPGME_STATUS_EXPSIG,
+    GPGME_STATUS_EXPKEYSIG,
+    GPGME_STATUS_TRUNCATED,
+    GPGME_STATUS_ERROR,
+    GPGME_STATUS_NEWSIG,
+    GPGME_STATUS_REVKEYSIG,
+    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,
+    GPGME_STATUS_PKA_TRUST_BAD,
+    GPGME_STATUS_PKA_TRUST_GOOD,
+
+    GPGME_STATUS_PLAINTEXT
+  }
+gpgme_status_code_t;
+
+
+/* The engine information structure.  */
+struct _gpgme_engine_info
+{
+  struct _gpgme_engine_info *next;
+
+  /* The protocol ID.  */
+  gpgme_protocol_t protocol;
+
+  /* The file name of the engine binary.  */
+  char *file_name;
+  
+  /* The version string of the installed engine.  */
+  char *version;
+
+  /* The minimum version required for GPGME.  */
+  const char *req_version;
+
+  /* The home directory used, or NULL if default.  */
+  char *home_dir;
+};
+typedef struct _gpgme_engine_info *gpgme_engine_info_t;
+
+
+/* A subkey from a key.  */
+struct _gpgme_subkey
+{
+  struct _gpgme_subkey *next;
+
+  /* True if subkey is revoked.  */
+  unsigned int revoked : 1;
+
+  /* True if subkey is expired.  */
+  unsigned int expired : 1;
+
+  /* True if subkey is disabled.  */
+  unsigned int disabled : 1;
+
+  /* True if subkey is invalid.  */
+  unsigned int invalid : 1;
+
+  /* True if subkey can be used for encryption.  */
+  unsigned int can_encrypt : 1;
+
+  /* True if subkey can be used for signing.  */
+  unsigned int can_sign : 1;
+
+  /* True if subkey can be used for certification.  */
+  unsigned int can_certify : 1;
+
+  /* True if subkey is secret.  */
+  unsigned int secret : 1;
+
+  /* True if subkey can be used for authentication.  */
+  unsigned int can_authenticate : 1;
+
+  /* True if subkey is qualified for signatures according to German law.  */
+  unsigned int is_qualified : 1;
+
+  /* Internal to GPGME, do not use.  */
+  unsigned int _unused : 22;
+  
+  /* Public key algorithm supported by this subkey.  */
+  gpgme_pubkey_algo_t pubkey_algo;
+
+  /* Length of the subkey.  */
+  unsigned int length;
+
+  /* The key ID of the subkey.  */
+  char *keyid;
+
+  /* Internal to GPGME, do not use.  */
+  char _keyid[16 + 1];
+
+  /* The fingerprint of the subkey in hex digit form.  */
+  char *fpr;
+
+  /* The creation timestamp, -1 if invalid, 0 if not available.  */
+  long int timestamp;
+
+  /* The expiration timestamp, 0 if the subkey does not expire.  */
+  long int expires;
+};
+typedef struct _gpgme_subkey *gpgme_subkey_t;
+
+
+/* A signature on a user ID.  */
+struct _gpgme_key_sig
+{
+  struct _gpgme_key_sig *next;
+
+  /* True if the signature is a revocation signature.  */
+  unsigned int revoked : 1;
+
+  /* True if the signature is expired.  */
+  unsigned int expired : 1;
+
+  /* True if the signature is invalid.  */
+  unsigned int invalid : 1;
+
+  /* True if the signature should be exported.  */
+  unsigned int exportable : 1;
+
+  /* Internal to GPGME, do not use.  */
+  unsigned int _unused : 28;
+
+  /* The public key algorithm used to create the signature.  */
+  gpgme_pubkey_algo_t pubkey_algo;
+
+  /* The key ID of key used to create the signature.  */
+  char *keyid;
+
+  /* Internal to GPGME, do not use.  */
+  char _keyid[16 + 1];
+
+  /* The creation timestamp, -1 if invalid, 0 if not available.  */
+  long int timestamp;
+
+  /* The expiration timestamp, 0 if the subkey does not expire.  */
+  long int expires;
+
+  /* Same as in gpgme_signature_t.  */
+  gpgme_error_t status;
+
+#ifdef __cplusplus
+  unsigned int _obsolete_class _GPGME_DEPRECATED;
+#else
+  /* Must be set to SIG_CLASS below.  */
+  unsigned int class _GPGME_DEPRECATED;
+#endif
+
+  /* The user ID string.  */
+  char *uid;
+
+  /* The name part of the user ID.  */
+  char *name;
+
+  /* The email part of the user ID.  */
+  char *email;
+
+  /* The comment part of the user ID.  */
+  char *comment;
+
+  /* Crypto backend specific signature class.  */
+  unsigned int sig_class;
+
+  /* Notation data and policy URLs.  */
+  gpgme_sig_notation_t notations;
+
+  /* Internal to GPGME, do not use.  */
+  gpgme_sig_notation_t _last_notation;
+};
+typedef struct _gpgme_key_sig *gpgme_key_sig_t;
+
+
+/* An user ID from a key.  */
+struct _gpgme_user_id
+{
+  struct _gpgme_user_id *next;
+
+  /* True if the user ID is revoked.  */
+  unsigned int revoked : 1;
+
+  /* True if the user ID is invalid.  */
+  unsigned int invalid : 1;
+
+  /* Internal to GPGME, do not use.  */
+  unsigned int _unused : 30;
+
+  /* The validity of the user ID.  */
+  gpgme_validity_t validity; 
+
+  /* The user ID string.  */
+  char *uid;
+
+  /* The name part of the user ID.  */
+  char *name;
+
+  /* The email part of the user ID.  */
+  char *email;
+
+  /* The comment part of the user ID.  */
+  char *comment;
+
+  /* The signatures of the user ID.  */
+  gpgme_key_sig_t signatures;
+
+  /* Internal to GPGME, do not use.  */
+  gpgme_key_sig_t _last_keysig;
+};
+typedef struct _gpgme_user_id *gpgme_user_id_t;
+
+
+/* A key from the keyring.  */
+struct _gpgme_key
+{
+  /* Internal to GPGME, do not use.  */
+  unsigned int _refs;
+
+  /* True if key is revoked.  */
+  unsigned int revoked : 1;
+
+  /* True if key is expired.  */
+  unsigned int expired : 1;
+
+  /* True if key is disabled.  */
+  unsigned int disabled : 1;
+
+  /* True if key is invalid.  */
+  unsigned int invalid : 1;
+
+  /* True if key can be used for encryption.  */
+  unsigned int can_encrypt : 1;
+
+  /* True if key can be used for signing.  */
+  unsigned int can_sign : 1;
+
+  /* True if key can be used for certification.  */
+  unsigned int can_certify : 1;
+
+  /* True if key is secret.  */
+  unsigned int secret : 1;
+
+  /* True if key can be used for authentication.  */
+  unsigned int can_authenticate : 1;
+
+  /* True if subkey is qualified for signatures according to German law.  */
+  unsigned int is_qualified : 1;
+
+  /* Internal to GPGME, do not use.  */
+  unsigned int _unused : 22;
+
+  /* This is the protocol supported by this key.  */
+  gpgme_protocol_t protocol;
+
+  /* If protocol is GPGME_PROTOCOL_CMS, this string contains the
+     issuer serial.  */
+  char *issuer_serial;
+
+  /* If protocol is GPGME_PROTOCOL_CMS, this string contains the
+     issuer name.  */
+  char *issuer_name;
+
+  /* If protocol is GPGME_PROTOCOL_CMS, this string contains the chain
+     ID.  */
+  char *chain_id;
+
+  /* If protocol is GPGME_PROTOCOL_OpenPGP, this field contains the
+     owner trust.  */
+  gpgme_validity_t owner_trust;
+
+  /* The subkeys of the key.  */
+  gpgme_subkey_t subkeys;
+
+  /* The user IDs of the key.  */
+  gpgme_user_id_t uids;
+
+  /* Internal to GPGME, do not use.  */
+  gpgme_subkey_t _last_subkey;
+
+  /* Internal to GPGME, do not use.  */
+  gpgme_user_id_t _last_uid;
+
+  /* The keylist mode that was active when listing the key.  */
+  gpgme_keylist_mode_t keylist_mode;
+};
+typedef struct _gpgme_key *gpgme_key_t;
+
+
+
+/* Types for callback functions.  */
+
+/* Request a passphrase from the user.  */
+typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook,
+						const char *uid_hint,
+						const char *passphrase_info,
+						int prev_was_bad, int fd);
+
+/* Inform the user about progress made.  */
+typedef void (*gpgme_progress_cb_t) (void *opaque, const char *what,
+				     int type, int current, int total);
+
+/* Interact with the user about an edit operation.  */
+typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
+					  gpgme_status_code_t status,
+					  const char *args, int fd);
+
+
+/* Context management functions.  */
+
+/* Create a new context and return it in CTX.  */
+gpgme_error_t gpgme_new (gpgme_ctx_t *ctx);
+
+/* Release the context CTX.  */
+void gpgme_release (gpgme_ctx_t ctx);
+
+/* Set the protocol to be used by CTX to PROTO.  */
+gpgme_error_t gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t proto);
+
+/* Get the protocol used with CTX */
+gpgme_protocol_t gpgme_get_protocol (gpgme_ctx_t ctx);
+
+/* Get the string describing protocol PROTO, or NULL if invalid.  */
+const char *gpgme_get_protocol_name (gpgme_protocol_t proto);
+
+/* If YES is non-zero, enable armor mode in CTX, disable it otherwise.  */
+void gpgme_set_armor (gpgme_ctx_t ctx, int yes);
+
+/* Return non-zero if armor mode is set in CTX.  */
+int gpgme_get_armor (gpgme_ctx_t ctx);
+
+/* If YES is non-zero, enable text mode in CTX, disable it otherwise.  */
+void gpgme_set_textmode (gpgme_ctx_t ctx, int yes);
+
+/* Return non-zero if text mode is set in CTX.  */
+int gpgme_get_textmode (gpgme_ctx_t ctx);
+
+/* Use whatever the default of the backend crypto engine is.  */
+#define GPGME_INCLUDE_CERTS_DEFAULT	-256
+
+/* Include up to NR_OF_CERTS certificates in an S/MIME message.  */
+void gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs);
+
+/* Return the number of certs to include in an S/MIME message.  */
+int gpgme_get_include_certs (gpgme_ctx_t ctx);
+
+/* Set keylist mode in CTX to MODE.  */
+gpgme_error_t gpgme_set_keylist_mode (gpgme_ctx_t ctx,
+				      gpgme_keylist_mode_t mode);
+
+/* Get keylist mode in CTX.  */
+gpgme_keylist_mode_t gpgme_get_keylist_mode (gpgme_ctx_t ctx);
+
+/* Set the passphrase callback function in CTX to CB.  HOOK_VALUE is
+   passed as first argument to the passphrase callback function.  */
+void gpgme_set_passphrase_cb (gpgme_ctx_t ctx,
+                              gpgme_passphrase_cb_t cb, void *hook_value);
+
+/* Get the current passphrase callback function in *CB and the current
+   hook value in *HOOK_VALUE.  */
+void gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *cb,
+			      void **hook_value);
+
+/* Set the progress callback function in CTX to CB.  HOOK_VALUE is
+   passed as first argument to the progress callback function.  */
+void gpgme_set_progress_cb (gpgme_ctx_t c, gpgme_progress_cb_t cb,
+			    void *hook_value);
+
+/* Get the current progress callback function in *CB and the current
+   hook value in *HOOK_VALUE.  */
+void gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *cb,
+			    void **hook_value);
+
+/* This function sets the locale for the context CTX, or the default
+   locale if CTX is a null pointer.  */
+gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category,
+				const char *value);
+
+/* Get the information about the configured engines.  A pointer to the
+   first engine in the statically allocated linked list is returned.
+   The returned data is valid until the next gpgme_ctx_set_engine_info.  */
+gpgme_engine_info_t gpgme_ctx_get_engine_info (gpgme_ctx_t ctx);
+
+/* Set the engine info for the context CTX, protocol PROTO, to the
+   file name FILE_NAME and the home directory HOME_DIR.  */
+gpgme_error_t gpgme_ctx_set_engine_info (gpgme_ctx_t ctx,
+					 gpgme_protocol_t proto,
+					 const char *file_name,
+					 const char *home_dir);
+
+
+/* Return a statically allocated string with the name of the public
+   key algorithm ALGO, or NULL if that name is not known.  */
+const char *gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo);
+
+/* Return a statically allocated string with the name of the hash
+   algorithm ALGO, or NULL if that name is not known.  */
+const char *gpgme_hash_algo_name (gpgme_hash_algo_t algo);
+
+
+/* Delete all signers from CTX.  */
+void gpgme_signers_clear (gpgme_ctx_t ctx);
+
+/* Add KEY to list of signers in CTX.  */
+gpgme_error_t gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key);
+
+/* Return the SETQth signer's key in CTX.  */
+gpgme_key_t gpgme_signers_enum (const gpgme_ctx_t ctx, int seq);
+
+/* Retrieve the signature status of signature IDX in CTX after a
+   successful verify operation in R_STAT (if non-null).  The creation
+   time stamp of the signature is returned in R_CREATED (if non-null).
+   The function returns a string containing the fingerprint.
+   Deprecated, use verify result directly.  */
+const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx,
+                                  _gpgme_sig_stat_t *r_stat,
+				  time_t *r_created) _GPGME_DEPRECATED;
+
+/* Retrieve certain attributes of a signature.  IDX is the index
+   number of the signature after a successful verify operation.  WHAT
+   is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
+   one.  WHATIDX is to be passed as 0 for most attributes . */
+unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t c, int idx,
+                                        _gpgme_attr_t what, int whatidx)
+     _GPGME_DEPRECATED;
+const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx,
+				       _gpgme_attr_t what, int whatidx)
+     _GPGME_DEPRECATED;
+
+
+/* Get the key used to create signature IDX in CTX and return it in
+   R_KEY.  */
+gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
+     _GPGME_DEPRECATED;
+
+
+/* Clear all notation data from the context.  */
+void gpgme_sig_notation_clear (gpgme_ctx_t ctx);
+
+/* Add the human-readable notation data with name NAME and value VALUE
+   to the context CTX, using the flags FLAGS.  If NAME is NULL, then
+   VALUE should be a policy URL.  The flag
+   GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
+   data, and false for policy URLs.  */
+gpgme_error_t gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
+				      const char *value,
+				      gpgme_sig_notation_flags_t flags);
+
+/* Get the sig notations for this context.  */
+gpgme_sig_notation_t gpgme_sig_notation_get (gpgme_ctx_t ctx);
+
+
+/* Run control.  */
+
+/* The type of an I/O callback function.  */
+typedef gpgme_error_t (*gpgme_io_cb_t) (void *data, int fd);
+
+/* The type of a function that can register FNC as the I/O callback
+   function for the file descriptor FD with direction dir (0: for writing,
+   1: for reading).  FNC_DATA should be passed as DATA to FNC.  The
+   function should return a TAG suitable for the corresponding
+   gpgme_remove_io_cb_t, and an error value.  */
+typedef gpgme_error_t (*gpgme_register_io_cb_t) (void *data, int fd, int dir,
+						 gpgme_io_cb_t fnc,
+						 void *fnc_data, void **tag);
+
+/* The type of a function that can remove a previously registered I/O
+   callback function given TAG as returned by the register
+   function.  */
+typedef void (*gpgme_remove_io_cb_t) (void *tag);
+
+typedef enum
+  {
+    GPGME_EVENT_START,
+    GPGME_EVENT_DONE,
+    GPGME_EVENT_NEXT_KEY,
+    GPGME_EVENT_NEXT_TRUSTITEM
+  }
+gpgme_event_io_t;
+
+/* The type of a function that is called when a context finished an
+   operation.  */
+typedef void (*gpgme_event_io_cb_t) (void *data, gpgme_event_io_t type,
+				     void *type_data);
+
+struct gpgme_io_cbs
+{
+  gpgme_register_io_cb_t add;
+  void *add_priv;
+  gpgme_remove_io_cb_t remove;
+  gpgme_event_io_cb_t event;
+  void *event_priv;
+};
+typedef struct gpgme_io_cbs *gpgme_io_cbs_t;
+
+/* Set the I/O callback functions in CTX to IO_CBS.  */
+void gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs);
+
+/* Get the current I/O callback functions.  */
+void gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs);
+
+/* Process the pending operation and, if HANG is non-zero, wait for
+   the pending operation to finish.  */
+gpgme_ctx_t gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang);
+
+
+/* Functions to handle data objects.  */
+
+/* Read up to SIZE bytes into buffer BUFFER from the data object with
+   the handle HANDLE.  Return the number of characters read, 0 on EOF
+   and -1 on error.  If an error occurs, errno is set.  */
+typedef ssize_t (*gpgme_data_read_cb_t) (void *handle, void *buffer,
+					 size_t size);
+
+/* Write up to SIZE bytes from buffer BUFFER to the data object with
+   the handle HANDLE.  Return the number of characters written, or -1
+   on error.  If an error occurs, errno is set.  */
+typedef ssize_t (*gpgme_data_write_cb_t) (void *handle, const void *buffer,
+					  size_t size);
+
+/* Set the current position from where the next read or write starts
+   in the data object with the handle HANDLE to OFFSET, relativ to
+   WHENCE.  */
+typedef off_t (*gpgme_data_seek_cb_t) (void *handle, off_t offset, int whence);
+
+/* Close the data object with the handle DL.  */
+typedef void (*gpgme_data_release_cb_t) (void *handle);
+
+struct gpgme_data_cbs
+{
+  gpgme_data_read_cb_t read;
+  gpgme_data_write_cb_t write;
+  gpgme_data_seek_cb_t seek;
+  gpgme_data_release_cb_t release;
+};
+typedef struct gpgme_data_cbs *gpgme_data_cbs_t;
+
+/* Read up to SIZE bytes into buffer BUFFER from the data object with
+   the handle DH.  Return the number of characters read, 0 on EOF and
+   -1 on error.  If an error occurs, errno is set.  */
+ssize_t gpgme_data_read (gpgme_data_t dh, void *buffer, size_t size);
+
+/* Write up to SIZE bytes from buffer BUFFER to the data object with
+   the handle DH.  Return the number of characters written, or -1 on
+   error.  If an error occurs, errno is set.  */
+ssize_t gpgme_data_write (gpgme_data_t dh, const void *buffer, size_t size);
+
+/* Set the current position from where the next read or write starts
+   in the data object with the handle DH to OFFSET, relativ to
+   WHENCE.  */
+off_t gpgme_data_seek (gpgme_data_t dh, off_t offset, int whence);
+
+/* Create a new data buffer and return it in R_DH.  */
+gpgme_error_t gpgme_data_new (gpgme_data_t *r_dh);
+
+/* Destroy the data buffer DH.  */
+void gpgme_data_release (gpgme_data_t dh);
+
+/* Create a new data buffer filled with SIZE bytes starting from
+   BUFFER.  If COPY is zero, copying is delayed until necessary, and
+   the data is taken from the original location when needed.  */
+gpgme_error_t gpgme_data_new_from_mem (gpgme_data_t *r_dh,
+				       const char *buffer, size_t size,
+				       int copy);
+
+/* Destroy the data buffer DH and return a pointer to its content.
+   The memory has be to released with gpgme_free() by the user.  It's
+   size is returned in R_LEN.  */
+char *gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len);
+
+/* Release the memory returned by gpgme_data_release_and_get_mem().  */
+void gpgme_free (void *buffer);
+
+gpgme_error_t gpgme_data_new_from_cbs (gpgme_data_t *dh,
+				       gpgme_data_cbs_t cbs,
+				       void *handle);
+
+gpgme_error_t gpgme_data_new_from_fd (gpgme_data_t *dh, int fd);
+
+gpgme_error_t gpgme_data_new_from_stream (gpgme_data_t *dh, FILE *stream);
+
+/* Return the encoding attribute of the data buffer DH */
+gpgme_data_encoding_t gpgme_data_get_encoding (gpgme_data_t dh);
+
+/* Set the encoding attribute of data buffer DH to ENC */
+gpgme_error_t gpgme_data_set_encoding (gpgme_data_t dh,
+				       gpgme_data_encoding_t enc);
+
+/* Get the file name associated with the data object with handle DH, or
+   NULL if there is none.  */
+char *gpgme_data_get_file_name (gpgme_data_t dh);
+
+/* Set the file name associated with the data object with handle DH to
+   FILE_NAME.  */
+gpgme_error_t gpgme_data_set_file_name (gpgme_data_t dh,
+					const char *file_name);
+
+
+/* Create a new data buffer which retrieves the data from the callback
+   function READ_CB.  Deprecated, please use gpgme_data_new_from_cbs
+   instead.  */
+gpgme_error_t gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
+					   int (*read_cb) (void*,char *,
+							   size_t,size_t*),
+					   void *read_cb_value)
+     _GPGME_DEPRECATED;
+
+/* Create a new data buffer filled with the content of file FNAME.
+   COPY must be non-zero.  For delayed read, please use
+   gpgme_data_new_from_fd or gpgme_data_new_from stream instead.  */
+gpgme_error_t gpgme_data_new_from_file (gpgme_data_t *r_dh,
+					const char *fname,
+					int copy);
+
+/* Create a new data buffer filled with LENGTH bytes starting from
+   OFFSET within the file FNAME or stream FP (exactly one must be
+   non-zero).  */
+gpgme_error_t gpgme_data_new_from_filepart (gpgme_data_t *r_dh,
+					    const char *fname, FILE *fp,
+					    off_t offset, size_t length);
+
+/* Reset the read pointer in DH.  Deprecated, please use
+   gpgme_data_seek instead.  */
+gpgme_error_t gpgme_data_rewind (gpgme_data_t dh) _GPGME_DEPRECATED;
+
+
+/* Key and trust functions.  */
+
+/* Get the key with the fingerprint FPR from the crypto backend.  If
+   SECRET is true, get the secret key.  */
+gpgme_error_t gpgme_get_key (gpgme_ctx_t ctx, const char *fpr,
+			     gpgme_key_t *r_key, int secret);
+
+/* Acquire a reference to KEY.  */
+void gpgme_key_ref (gpgme_key_t key);
+
+/* Release a reference to KEY.  If this was the last one the key is
+   destroyed.  */
+void gpgme_key_unref (gpgme_key_t key);
+void gpgme_key_release (gpgme_key_t key);
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+   representable by a string.  IDX specifies the sub key or user ID
+   for attributes related to sub keys or user IDs.  Deprecated, use
+   key structure directly instead. */
+const char *gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
+				       const void *reserved, int idx)
+     _GPGME_DEPRECATED;
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+   representable by an unsigned integer.  IDX specifies the sub key or
+   user ID for attributes related to sub keys or user IDs.
+   Deprecated, use key structure directly instead.  */
+unsigned long gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
+					const void *reserved, int idx)
+     _GPGME_DEPRECATED;
+
+/* Return the value of the attribute WHAT of a signature on user ID
+   UID_IDX in KEY, which has to be representable by a string.  IDX
+   specifies the signature.  Deprecated, use key structure directly
+   instead.  */
+const char *gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
+					   _gpgme_attr_t what,
+					   const void *reserved, int idx)
+     _GPGME_DEPRECATED;
+
+/* Return the value of the attribute WHAT of a signature on user ID
+   UID_IDX in KEY, which has to be representable by an unsigned
+   integer string.  IDX specifies the signature.  Deprecated, use key
+   structure directly instead.  */
+unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
+					    _gpgme_attr_t what,
+					    const void *reserved, int idx)
+     _GPGME_DEPRECATED;
+
+
+/* Crypto Operations.  */
+
+/* Cancel a pending asynchronous operation.  */
+gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx);
+
+
+struct _gpgme_invalid_key
+{
+  struct _gpgme_invalid_key *next;
+  char *fpr;
+  gpgme_error_t reason;
+};
+typedef struct _gpgme_invalid_key *gpgme_invalid_key_t;
+
+
+/* Encryption.  */
+struct _gpgme_op_encrypt_result
+{
+  /* The list of invalid recipients.  */
+  gpgme_invalid_key_t invalid_recipients;
+};
+typedef struct _gpgme_op_encrypt_result *gpgme_encrypt_result_t;
+
+/* Retrieve a pointer to the result of the encrypt operation.  */
+gpgme_encrypt_result_t gpgme_op_encrypt_result (gpgme_ctx_t ctx);
+
+/* The valid encryption flags.  */
+typedef enum
+  {
+    GPGME_ENCRYPT_ALWAYS_TRUST = 1
+  }
+gpgme_encrypt_flags_t;
+
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+   store the resulting ciphertext in CIPHER.  */
+gpgme_error_t gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
+				      gpgme_encrypt_flags_t flags,
+				      gpgme_data_t plain, gpgme_data_t cipher);
+gpgme_error_t gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
+				gpgme_encrypt_flags_t flags,
+				gpgme_data_t plain, gpgme_data_t cipher);
+
+/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
+   store the resulting ciphertext in CIPHER.  Also sign the ciphertext
+   with the signers in CTX.  */
+gpgme_error_t gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx,
+					   gpgme_key_t recp[],
+					   gpgme_encrypt_flags_t flags,
+					   gpgme_data_t plain,
+					   gpgme_data_t cipher);
+gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
+				     gpgme_encrypt_flags_t flags,
+				     gpgme_data_t plain, gpgme_data_t cipher);
+
+
+/* Decryption.  */
+
+struct _gpgme_recipient
+{
+  struct _gpgme_recipient *next;
+
+  /* The key ID of key for which the text was encrypted.  */
+  char *keyid;
+
+  /* Internal to GPGME, do not use.  */
+  char _keyid[16 + 1];
+
+  /* The public key algorithm of the recipient key.  */
+  gpgme_pubkey_algo_t pubkey_algo;
+
+  /* The status of the recipient.  */
+  gpgme_error_t status;
+};
+typedef struct _gpgme_recipient *gpgme_recipient_t;
+
+struct _gpgme_op_decrypt_result
+{
+  char *unsupported_algorithm;
+
+  /* Key should not have been used for encryption.  */
+  unsigned int wrong_key_usage : 1;
+
+  /* Internal to GPGME, do not use.  */
+  int _unused : 31;
+
+  gpgme_recipient_t recipients;
+
+  /* The original file name of the plaintext message, if
+     available.  */
+  char *file_name;
+};
+typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t;
+
+/* Retrieve a pointer to the result of the decrypt operation.  */
+gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx);
+
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+   plaintext in PLAIN.  */
+gpgme_error_t gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
+				      gpgme_data_t plain);
+gpgme_error_t gpgme_op_decrypt (gpgme_ctx_t ctx,
+				gpgme_data_t cipher, gpgme_data_t plain);
+
+/* Decrypt ciphertext CIPHER and make a signature verification within
+   CTX and store the resulting plaintext in PLAIN.  */
+gpgme_error_t gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx,
+					     gpgme_data_t cipher,
+					     gpgme_data_t plain);
+gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
+				       gpgme_data_t plain);
+
+
+/* Signing.  */
+struct _gpgme_new_signature
+{
+  struct _gpgme_new_signature *next;
+
+  /* The type of the signature.  */
+  gpgme_sig_mode_t type;
+
+  /* The public key algorithm used to create the signature.  */
+  gpgme_pubkey_algo_t pubkey_algo;
+
+  /* The hash algorithm used to create the signature.  */
+  gpgme_hash_algo_t hash_algo;
+
+  /* Internal to GPGME, do not use.  Must be set to the same value as
+     CLASS below.  */
+  unsigned long _obsolete_class;
+
+  /* Signature creation time.  */
+  long int timestamp;
+
+  /* The fingerprint of the signature.  */
+  char *fpr;
+
+#ifdef __cplusplus
+  unsigned int _obsolete_class_2;
+#else
+  /* Must be set to SIG_CLASS below.  */
+  unsigned int class _GPGME_DEPRECATED;
+#endif
+
+  /* Crypto backend specific signature class.  */
+  unsigned int sig_class;
+};
+typedef struct _gpgme_new_signature *gpgme_new_signature_t;
+
+struct _gpgme_op_sign_result
+{
+  /* The list of invalid signers.  */
+  gpgme_invalid_key_t invalid_signers;
+  gpgme_new_signature_t signatures;
+};
+typedef struct _gpgme_op_sign_result *gpgme_sign_result_t;
+
+/* Retrieve a pointer to the result of the signing operation.  */
+gpgme_sign_result_t gpgme_op_sign_result (gpgme_ctx_t ctx);
+
+/* Sign the plaintext PLAIN and store the signature in SIG.  */
+gpgme_error_t gpgme_op_sign_start (gpgme_ctx_t ctx,
+				   gpgme_data_t plain, gpgme_data_t sig,
+				   gpgme_sig_mode_t mode);
+gpgme_error_t gpgme_op_sign (gpgme_ctx_t ctx,
+			     gpgme_data_t plain, gpgme_data_t sig,
+			     gpgme_sig_mode_t mode);
+
+
+/* Verify.  */
+
+/* Flags used for the SUMMARY field in a gpgme_signature_t.  */
+typedef enum
+  {
+    GPGME_SIGSUM_VALID       = 0x0001,  /* The signature is fully valid.  */
+    GPGME_SIGSUM_GREEN       = 0x0002,  /* The signature is good.  */
+    GPGME_SIGSUM_RED         = 0x0004,  /* The signature is bad.  */
+    GPGME_SIGSUM_KEY_REVOKED = 0x0010,  /* One key has been revoked.  */
+    GPGME_SIGSUM_KEY_EXPIRED = 0x0020,  /* One key has expired.  */
+    GPGME_SIGSUM_SIG_EXPIRED = 0x0040,  /* The signature has expired.  */
+    GPGME_SIGSUM_KEY_MISSING = 0x0080,  /* Can't verify: key missing.  */
+    GPGME_SIGSUM_CRL_MISSING = 0x0100,  /* CRL not available.  */
+    GPGME_SIGSUM_CRL_TOO_OLD = 0x0200,  /* Available CRL is too old.  */
+    GPGME_SIGSUM_BAD_POLICY  = 0x0400,  /* A policy was not met.  */
+    GPGME_SIGSUM_SYS_ERROR   = 0x0800   /* A system error occured.  */
+  }
+gpgme_sigsum_t;
+
+struct _gpgme_signature
+{
+  struct _gpgme_signature *next;
+
+  /* A summary of the signature status.  */
+  gpgme_sigsum_t summary;
+
+  /* The fingerprint or key ID of the signature.  */
+  char *fpr;
+
+  /* The status of the signature.  */
+  gpgme_error_t status;
+
+  /* Notation data and policy URLs.  */
+  gpgme_sig_notation_t notations;
+
+  /* Signature creation time.  */
+  unsigned long timestamp;
+
+  /* Signature exipration time or 0.  */
+  unsigned long exp_timestamp;
+
+  /* Key should not have been used for signing.  */
+  unsigned int wrong_key_usage : 1;
+
+  /* PKA status: 0 = not available, 1 = bad, 2 = okay, 3 = RFU. */
+  unsigned int pka_trust : 2;
+
+  /* Internal to GPGME, do not use.  */
+  int _unused : 29;
+
+  gpgme_validity_t validity;
+  gpgme_error_t validity_reason;
+
+  /* The public key algorithm used to create the signature.  */
+  gpgme_pubkey_algo_t pubkey_algo;
+
+  /* The hash algorithm used to create the signature.  */
+  gpgme_hash_algo_t hash_algo;
+
+  /* The mailbox from the PKA information or NULL. */
+  char *pka_address;
+};
+typedef struct _gpgme_signature *gpgme_signature_t;
+
+struct _gpgme_op_verify_result
+{
+  gpgme_signature_t signatures;
+
+  /* The original file name of the plaintext message, if
+     available.  */
+  char *file_name;
+};
+typedef struct _gpgme_op_verify_result *gpgme_verify_result_t;
+
+/* Retrieve a pointer to the result of the verify operation.  */
+gpgme_verify_result_t gpgme_op_verify_result (gpgme_ctx_t ctx);
+
+/* Verify within CTX that SIG is a valid signature for TEXT.  */
+gpgme_error_t gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
+				     gpgme_data_t signed_text,
+				     gpgme_data_t plaintext);
+gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig,
+			       gpgme_data_t signed_text,
+			       gpgme_data_t plaintext);
+
+
+/* Import.  */
+
+/* The key was new.  */
+#define GPGME_IMPORT_NEW	1
+
+/* The key contained new user IDs.  */
+#define GPGME_IMPORT_UID	2
+
+/* The key contained new signatures.  */
+#define GPGME_IMPORT_SIG	4
+
+/* The key contained new sub keys.  */
+#define GPGME_IMPORT_SUBKEY	8
+
+/* The key contained a secret key.  */
+#define GPGME_IMPORT_SECRET	16
+
+
+struct _gpgme_import_status
+{
+  struct _gpgme_import_status *next;
+
+  /* Fingerprint.  */
+  char *fpr;
+
+  /* If a problem occured, the reason why the key could not be
+     imported.  Otherwise GPGME_No_Error.  */
+  gpgme_error_t result;
+
+  /* The result of the import, the GPGME_IMPORT_* values bit-wise
+     ORed.  0 means the key was already known and no new components
+     have been added.  */
+  unsigned int status;
+};
+typedef struct _gpgme_import_status *gpgme_import_status_t;
+
+/* Import.  */
+struct _gpgme_op_import_result
+{
+  /* Number of considered keys.  */
+  int considered;
+
+  /* Keys without user ID.  */
+  int no_user_id;
+
+  /* Imported keys.  */
+  int imported;
+
+  /* Imported RSA keys.  */
+  int imported_rsa;
+
+  /* Unchanged keys.  */
+  int unchanged;
+
+  /* Number of new user ids.  */
+  int new_user_ids;
+
+  /* Number of new sub keys.  */
+  int new_sub_keys;
+
+  /* Number of new signatures.  */
+  int new_signatures;
+
+  /* Number of new revocations.  */
+  int new_revocations;
+
+  /* Number of secret keys read.  */
+  int secret_read;
+
+  /* Number of secret keys imported.  */
+  int secret_imported;
+
+  /* Number of secret keys unchanged.  */
+  int secret_unchanged;
+
+  /* Number of new keys skipped.  */
+  int skipped_new_keys;
+
+  /* Number of keys not imported.  */
+  int not_imported;
+
+  /* List of keys for which an import was attempted.  */
+  gpgme_import_status_t imports;
+};
+typedef struct _gpgme_op_import_result *gpgme_import_result_t;
+
+/* Retrieve a pointer to the result of the import operation.  */
+gpgme_import_result_t gpgme_op_import_result (gpgme_ctx_t ctx);
+
+/* Import the key in KEYDATA into the keyring.  */
+gpgme_error_t gpgme_op_import_start (gpgme_ctx_t ctx, gpgme_data_t keydata);
+gpgme_error_t gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata);
+gpgme_error_t gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata,
+				   int *nr) _GPGME_DEPRECATED;
+
+
+/* Export the keys found by PATTERN into KEYDATA.  */
+gpgme_error_t gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern,
+				     unsigned int reserved,
+				     gpgme_data_t keydata);
+gpgme_error_t gpgme_op_export (gpgme_ctx_t ctx, const char *pattern,
+			       unsigned int reserved, gpgme_data_t keydata);
+
+gpgme_error_t gpgme_op_export_ext_start (gpgme_ctx_t ctx,
+					 const char *pattern[],
+					 unsigned int reserved,
+					 gpgme_data_t keydata);
+gpgme_error_t gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[],
+				   unsigned int reserved,
+				   gpgme_data_t keydata);
+
+
+/* Key generation.  */
+struct _gpgme_op_genkey_result
+{
+  /* A primary key was generated.  */
+  unsigned int primary : 1;
+
+  /* A sub key was generated.  */
+  unsigned int sub : 1;
+
+  /* Internal to GPGME, do not use.  */
+  unsigned int _unused : 30;
+
+  /* The fingerprint of the generated key.  */
+  char *fpr;
+};
+typedef struct _gpgme_op_genkey_result *gpgme_genkey_result_t;
+
+/* Generate a new keypair and add it to the keyring.  PUBKEY and
+   SECKEY should be null for now.  PARMS specifies what keys should be
+   generated.  */
+gpgme_error_t gpgme_op_genkey_start (gpgme_ctx_t ctx, const char *parms,
+				     gpgme_data_t pubkey, gpgme_data_t seckey);
+gpgme_error_t gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms,
+			       gpgme_data_t pubkey, gpgme_data_t seckey);
+
+/* Retrieve a pointer to the result of the genkey operation.  */
+gpgme_genkey_result_t gpgme_op_genkey_result (gpgme_ctx_t ctx);
+
+
+/* Delete KEY from the keyring.  If ALLOW_SECRET is non-zero, secret
+   keys are also deleted.  */
+gpgme_error_t gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key,
+				     int allow_secret);
+gpgme_error_t gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key,
+			       int allow_secret);
+
+
+/* Edit the key KEY.  Send status and command requests to FNC and
+   output of edit commands to OUT.  */
+gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+				   gpgme_edit_cb_t fnc, void *fnc_value,
+				   gpgme_data_t out);
+gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+			     gpgme_edit_cb_t fnc, void *fnc_value,
+			     gpgme_data_t out);
+
+/* Edit the card for the key KEY.  Send status and command requests to
+   FNC and output of edit commands to OUT.  */
+gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+					gpgme_edit_cb_t fnc, void *fnc_value,
+					gpgme_data_t out);
+gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+				  gpgme_edit_cb_t fnc, void *fnc_value,
+				  gpgme_data_t out);
+
+
+/* Key management functions.  */
+struct _gpgme_op_keylist_result
+{
+  unsigned int truncated : 1;
+
+  /* Internal to GPGME, do not use.  */
+  unsigned int _unused : 31;
+};
+typedef struct _gpgme_op_keylist_result *gpgme_keylist_result_t;
+
+/* Retrieve a pointer to the result of the key listing operation.  */
+gpgme_keylist_result_t gpgme_op_keylist_result (gpgme_ctx_t ctx);
+
+/* Start a keylist operation within CTX, searching for keys which
+   match PATTERN.  If SECRET_ONLY is true, only secret keys are
+   returned.  */
+gpgme_error_t gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern,
+				      int secret_only);
+gpgme_error_t gpgme_op_keylist_ext_start (gpgme_ctx_t ctx,
+					  const char *pattern[],
+					  int secret_only, int reserved);
+
+/* Return the next key from the keylist in R_KEY.  */
+gpgme_error_t gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key);
+
+/* Terminate a pending keylist operation within CTX.  */
+gpgme_error_t gpgme_op_keylist_end (gpgme_ctx_t ctx);
+
+
+/* Trust items and operations.  */
+
+struct _gpgme_trust_item
+{
+  /* Internal to GPGME, do not use.  */
+  unsigned int _refs;
+
+  /* The key ID to which the trust item belongs.  */
+  char *keyid;
+
+  /* Internal to GPGME, do not use.  */
+  char _keyid[16 + 1];
+
+  /* The type of the trust item, 1 refers to a key, 2 to a user ID.  */
+  int type;
+
+  /* The trust level.  */
+  int level;
+
+  /* The owner trust if TYPE is 1.  */
+  char *owner_trust;
+
+  /* Internal to GPGME, do not use.  */
+  char _owner_trust[2];
+
+  /* The calculated validity.  */
+  char *validity;
+ 
+  /* Internal to GPGME, do not use.  */
+  char _validity[2];
+
+  /* The user name if TYPE is 2.  */
+  char *name;
+};
+typedef struct _gpgme_trust_item *gpgme_trust_item_t;
+
+/* Start a trustlist operation within CTX, searching for trust items
+   which match PATTERN.  */
+gpgme_error_t gpgme_op_trustlist_start (gpgme_ctx_t ctx,
+					const char *pattern, int max_level);
+
+/* Return the next trust item from the trustlist in R_ITEM.  */
+gpgme_error_t gpgme_op_trustlist_next (gpgme_ctx_t ctx,
+				       gpgme_trust_item_t *r_item);
+
+/* Terminate a pending trustlist operation within CTX.  */
+gpgme_error_t gpgme_op_trustlist_end (gpgme_ctx_t ctx);
+
+/* Acquire a reference to ITEM.  */
+void gpgme_trust_item_ref (gpgme_trust_item_t item);
+
+/* Release a reference to ITEM.  If this was the last one the trust
+   item is destroyed.  */
+void gpgme_trust_item_unref (gpgme_trust_item_t item);
+
+/* Release the trust item ITEM.  Deprecated, use
+   gpgme_trust_item_unref.  */
+void gpgme_trust_item_release (gpgme_trust_item_t item) _GPGME_DEPRECATED;
+
+/* Return the value of the attribute WHAT of ITEM, which has to be
+   representable by a string.  Deprecated, use trust item structure
+   directly.  */
+const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item,
+					      _gpgme_attr_t what,
+					      const void *reserved, int idx)
+     _GPGME_DEPRECATED;
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+   representable by an integer.  IDX specifies a running index if the
+   attribute appears more than once in the key.  Deprecated, use trust
+   item structure directly.  */
+int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
+				   const void *reserved, int idx)
+     _GPGME_DEPRECATED;
+
+
+/* Various functions.  */
+
+/* Check that the library fulfills the version requirement.  */
+const char *gpgme_check_version (const char *req_version);
+
+/* Get the information about the configured and installed engines.  A
+   pointer to the first engine in the statically allocated linked list
+   is returned in *INFO.  If an error occurs, it is returned.  The
+   returned data is valid until the next gpgme_set_engine_info.  */
+gpgme_error_t gpgme_get_engine_info (gpgme_engine_info_t *engine_info);
+
+/* Set the default engine info for the protocol PROTO to the file name
+   FILE_NAME and the home directory HOME_DIR.  */
+gpgme_error_t gpgme_set_engine_info (gpgme_protocol_t proto,
+				     const char *file_name,
+				     const char *home_dir);
+
+
+/* Engine support functions.  */
+
+/* Verify that the engine implementing PROTO is installed and
+   available.  */
+gpgme_error_t gpgme_engine_check_version (gpgme_protocol_t proto);
+
+
+/* Deprecated types.  */
+typedef gpgme_ctx_t GpgmeCtx _GPGME_DEPRECATED;
+typedef gpgme_data_t GpgmeData _GPGME_DEPRECATED;
+typedef gpgme_error_t GpgmeError _GPGME_DEPRECATED;
+typedef gpgme_data_encoding_t GpgmeDataEncoding _GPGME_DEPRECATED;
+typedef gpgme_pubkey_algo_t GpgmePubKeyAlgo _GPGME_DEPRECATED;
+typedef gpgme_hash_algo_t GpgmeHashAlgo _GPGME_DEPRECATED;
+typedef gpgme_sig_stat_t GpgmeSigStat _GPGME_DEPRECATED;
+typedef gpgme_sig_mode_t GpgmeSigMode _GPGME_DEPRECATED;
+typedef gpgme_attr_t GpgmeAttr _GPGME_DEPRECATED;
+typedef gpgme_validity_t GpgmeValidity _GPGME_DEPRECATED;
+typedef gpgme_protocol_t GpgmeProtocol _GPGME_DEPRECATED;
+typedef gpgme_engine_info_t GpgmeEngineInfo _GPGME_DEPRECATED;
+typedef gpgme_subkey_t GpgmeSubkey _GPGME_DEPRECATED;
+typedef gpgme_key_sig_t GpgmeKeySig _GPGME_DEPRECATED;
+typedef gpgme_user_id_t GpgmeUserID _GPGME_DEPRECATED;
+typedef gpgme_key_t GpgmeKey _GPGME_DEPRECATED;
+typedef gpgme_passphrase_cb_t GpgmePassphraseCb _GPGME_DEPRECATED;
+typedef gpgme_progress_cb_t GpgmeProgressCb _GPGME_DEPRECATED;
+typedef gpgme_io_cb_t GpgmeIOCb _GPGME_DEPRECATED;
+typedef gpgme_register_io_cb_t GpgmeRegisterIOCb _GPGME_DEPRECATED;
+typedef gpgme_remove_io_cb_t GpgmeRemoveIOCb _GPGME_DEPRECATED;
+typedef gpgme_event_io_t GpgmeEventIO _GPGME_DEPRECATED;
+typedef gpgme_event_io_cb_t GpgmeEventIOCb _GPGME_DEPRECATED;
+#define GpgmeIOCbs gpgme_io_cbs
+typedef gpgme_data_read_cb_t GpgmeDataReadCb _GPGME_DEPRECATED;
+typedef gpgme_data_write_cb_t GpgmeDataWriteCb _GPGME_DEPRECATED;
+typedef gpgme_data_seek_cb_t GpgmeDataSeekCb _GPGME_DEPRECATED;
+typedef gpgme_data_release_cb_t GpgmeDataReleaseCb _GPGME_DEPRECATED;
+#define GpgmeDataCbs gpgme_data_cbs
+typedef gpgme_encrypt_result_t GpgmeEncryptResult _GPGME_DEPRECATED;
+typedef gpgme_sig_notation_t GpgmeSigNotation _GPGME_DEPRECATED;
+typedef	gpgme_signature_t GpgmeSignature _GPGME_DEPRECATED;
+typedef gpgme_verify_result_t GpgmeVerifyResult _GPGME_DEPRECATED;
+typedef gpgme_import_status_t GpgmeImportqStatus _GPGME_DEPRECATED;
+typedef gpgme_import_result_t GpgmeImportResult _GPGME_DEPRECATED;
+typedef gpgme_genkey_result_t GpgmeGenKeyResult _GPGME_DEPRECATED;
+typedef	gpgme_trust_item_t GpgmeTrustItem _GPGME_DEPRECATED;
+typedef gpgme_status_code_t GpgmeStatusCode _GPGME_DEPRECATED;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* GPGME_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/import.c b/libtdenetwork/libgpgme-copy/gpgme/import.c
new file mode 100644
index 000000000..03967f745
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/import.c
@@ -0,0 +1,273 @@
+/* import.c - Import a key.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+typedef struct
+{
+  struct _gpgme_op_import_result result;
+
+  /* A pointer to the next pointer of the last import status in the
+     list.  This makes appending new imports painless while preserving
+     the order.  */
+  gpgme_import_status_t *lastp;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+  gpgme_import_status_t import = opd->result.imports;
+
+  while (import)
+    {
+      gpgme_import_status_t next = import->next;
+      free (import->fpr);
+      free (import);
+      import = next;
+    }
+}
+
+
+gpgme_import_result_t
+gpgme_op_import_result (gpgme_ctx_t ctx)
+{
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL);
+  opd = hook;
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+static gpgme_error_t
+parse_import (char *args, gpgme_import_status_t *import_status, int problem)
+{
+  gpgme_import_status_t import;
+  char *tail;
+  long int nr;
+
+  import = malloc (sizeof (*import));
+  if (!import)
+    return gpg_error_from_errno (errno);
+  import->next = NULL;
+
+  errno = 0;
+  nr = strtol (args, &tail, 0);
+  if (errno || args == tail || *tail != ' ')
+    {
+      /* The crypto backend does not behave.  */
+      free (import);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+  args = tail;
+
+  if (problem)
+    {
+      switch (nr)
+	{
+	case 0:
+	case 4:
+	default:
+	  import->result = gpg_error (GPG_ERR_GENERAL);
+	  break;
+
+	case 1:
+	  import->result = gpg_error (GPG_ERR_BAD_CERT);
+	  break;
+
+	case 2:
+	  import->result = gpg_error (GPG_ERR_MISSING_CERT);
+	  break;
+
+	case 3:
+	  import->result = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
+	  break;
+	}
+      import->status = 0;
+    }
+  else
+    {
+      import->result = gpg_error (GPG_ERR_NO_ERROR);
+      import->status = nr;
+    }
+
+  while (*args == ' ')
+    args++;
+  tail = strchr (args, ' ');
+  if (tail)
+    *tail = '\0';
+
+  import->fpr = strdup (args);
+  if (!import->fpr)
+    {
+      int saved_errno = errno;
+      free (import);
+      return gpg_error_from_errno (saved_errno);
+    }
+
+  *import_status = import;
+  return 0;
+}
+
+
+
+gpgme_error_t
+parse_import_res (char *args, gpgme_import_result_t result)
+{
+  char *tail;
+
+  errno = 0;
+
+#define PARSE_NEXT(x)					\
+  (x) = strtol (args, &tail, 0);			\
+  if (errno || args == tail || *tail != ' ')		\
+    /* The crypto backend does not behave.  */		\
+    return gpg_error (GPG_ERR_INV_ENGINE);		\
+  args = tail;
+
+  PARSE_NEXT (result->considered);
+  PARSE_NEXT (result->no_user_id);
+  PARSE_NEXT (result->imported);
+  PARSE_NEXT (result->imported_rsa);
+  PARSE_NEXT (result->unchanged);
+  PARSE_NEXT (result->new_user_ids);
+  PARSE_NEXT (result->new_sub_keys);
+  PARSE_NEXT (result->new_signatures);
+  PARSE_NEXT (result->new_revocations);
+  PARSE_NEXT (result->secret_read);
+  PARSE_NEXT (result->secret_imported);
+  PARSE_NEXT (result->secret_unchanged);
+  PARSE_NEXT (result->skipped_new_keys);
+  PARSE_NEXT (result->not_imported);
+
+  return 0;
+}
+
+
+static gpgme_error_t
+import_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  switch (code)
+    {
+    case GPGME_STATUS_IMPORT_OK:
+    case GPGME_STATUS_IMPORT_PROBLEM:
+      err = parse_import (args, opd->lastp,
+			  code == GPGME_STATUS_IMPORT_OK ? 0 : 1);
+      if (err)
+	return err;
+
+      opd->lastp = &(*opd->lastp)->next;
+      break;
+
+    case GPGME_STATUS_IMPORT_RES:
+      err = parse_import_res (args, &opd->result);
+      break;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+
+static gpgme_error_t
+_gpgme_op_import_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t keydata)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+  opd->lastp = &opd->result.imports;
+
+  if (!keydata)
+    return gpg_error (GPG_ERR_NO_DATA);
+
+  _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
+
+  return _gpgme_engine_op_import (ctx->engine, keydata);
+}
+
+
+gpgme_error_t
+gpgme_op_import_start (gpgme_ctx_t ctx, gpgme_data_t keydata)
+{
+  return _gpgme_op_import_start (ctx, 0, keydata);
+}
+
+
+/* Import the key in KEYDATA into the keyring.  */
+gpgme_error_t
+gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata)
+{
+  gpgme_error_t err = _gpgme_op_import_start (ctx, 1, keydata);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
+
+
+gpgme_error_t
+gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata, int *nr)
+{
+  gpgme_error_t err = gpgme_op_import (ctx, keydata);
+  if (!err && nr)
+    {
+      gpgme_import_result_t result = gpgme_op_import_result (ctx);
+      *nr = result->considered;
+    }
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/io.h b/libtdenetwork/libgpgme-copy/gpgme/io.h
new file mode 100644
index 000000000..47b748f8b
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/io.h
@@ -0,0 +1,65 @@
+/* io.h - Interface to the I/O functions.
+   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 GPGME; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef IO_H
+#define IO_H
+
+/* A single file descriptor passed to spawn.  For child fds, dup_to
+   specifies the fd it should become in the child.  */
+struct spawn_fd_item_s
+{
+  int fd;
+  int dup_to;
+};
+
+struct io_select_fd_s
+{
+  int fd;
+  int for_read;
+  int for_write;
+  int signaled;
+  int frozen;
+  void *opaque;
+};
+
+/* These function are either defined in posix-io.c or w32-io.c.  */
+void _gpgme_io_subsystem_init (void);
+int _gpgme_io_read (int fd, void *buffer, size_t count);
+int _gpgme_io_write (int fd, const void *buffer, size_t count);
+int _gpgme_io_pipe (int filedes[2], int inherit_idx);
+int _gpgme_io_close (int fd);
+int _gpgme_io_set_close_notify (int fd, void (*handler) (int, void *),
+				void *value);
+int _gpgme_io_set_nonblocking (int fd);
+
+/* Spawn the executable PATH with ARGV as arguments, after forking
+   close all fds in FD_PARENT_LIST in the parent and close or dup all
+   fds in FD_CHILD_LIST in the child.  */
+int _gpgme_io_spawn (const char *path, char **argv,
+		     struct spawn_fd_item_s *fd_child_list,
+		     struct spawn_fd_item_s *fd_parent_list);
+int _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal);
+int _gpgme_io_kill (int pid, int hard);
+int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);
+
+#endif /* IO_H */
+
+
+
diff --git a/libtdenetwork/libgpgme-copy/gpgme/isascii.c b/libtdenetwork/libgpgme-copy/gpgme/isascii.c
new file mode 100644
index 000000000..d2d73de72
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/isascii.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1991,92,93,95,96,97,98,99,2001,2002,2004
+        Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library 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.
+
+   The GNU C Library 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 the GNU C Library; 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
+
+int
+isascii (int c)
+{
+  return (((c) & ~0x7f) == 0);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/key.c b/libtdenetwork/libgpgme-copy/gpgme/key.c
new file mode 100644
index 000000000..d411e572d
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/key.c
@@ -0,0 +1,722 @@
+/* key.c - Key objects.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "util.h"
+#include "ops.h"
+#include "sema.h"
+
+
+/* Protects all reference counters in keys.  All other accesses to a
+   key are read only.  */
+DEFINE_STATIC_LOCK (key_ref_lock);
+
+
+/* Create a new key.  */
+gpgme_error_t
+_gpgme_key_new (gpgme_key_t *r_key)
+{
+  gpgme_key_t key;
+
+  key = calloc (1, sizeof *key);
+  if (!key)
+    return gpg_error_from_errno (errno);
+  key->_refs = 1;
+
+  *r_key = key;
+  return 0;
+}
+
+
+gpgme_error_t
+_gpgme_key_add_subkey (gpgme_key_t key, gpgme_subkey_t *r_subkey)
+{
+  gpgme_subkey_t subkey;
+
+  subkey = calloc (1, sizeof *subkey);
+  if (!subkey)
+    return gpg_error_from_errno (errno);
+  subkey->keyid = subkey->_keyid;
+  subkey->_keyid[16] = '\0';
+
+  if (!key->subkeys)
+    key->subkeys = subkey;
+  if (key->_last_subkey)
+    key->_last_subkey->next = subkey;
+  key->_last_subkey = subkey;
+
+  *r_subkey = subkey;
+  return 0;
+}
+
+
+static char *
+set_user_id_part (char *tail, const char *buf, size_t len)
+{
+  while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t')) 
+    len--;
+  for (; len; len--)
+    *tail++ = *buf++;
+  *tail++ = 0;
+  return tail;
+}
+
+
+static void
+parse_user_id (char *src, char **name, char **email,
+	       char **comment, char *tail)
+{
+  const char *start = NULL;
+  int in_name = 0;
+  int in_email = 0;
+  int in_comment = 0;
+
+  while (*src)
+    {
+      if (in_email)
+	{
+	  if (*src == '<')
+	    /* Not legal but anyway.  */
+	    in_email++;
+	  else if (*src == '>')
+	    {
+	      if (!--in_email && !*email)
+		{
+		  *email = tail;
+		  tail = set_user_id_part (tail, start, src - start);
+		}
+	    }
+	}
+      else if (in_comment)
+	{
+	  if (*src == '(')
+	    in_comment++;
+	  else if (*src == ')')
+	    {
+	      if (!--in_comment && !*comment)
+		{
+		  *comment = tail;
+		  tail = set_user_id_part (tail, start, src - start);
+		}
+	    }
+	}
+      else if (*src == '<')
+	{
+	  if (in_name)
+	    {
+	      if (!*name)
+		{
+		  *name = tail;
+		  tail = set_user_id_part (tail, start, src - start);
+		}
+	      in_name = 0;
+	    }
+	  in_email = 1;
+	  start = src + 1;
+	}
+      else if (*src == '(')
+	{
+	  if (in_name)
+	    {
+	      if (!*name)
+		{
+		  *name = tail;
+		  tail = set_user_id_part (tail, start, src - start);
+		}
+	      in_name = 0;
+	    }
+	  in_comment = 1;
+	  start = src + 1;
+	}
+      else if (!in_name && *src != ' ' && *src != '\t')
+	{
+	  in_name = 1;
+	  start = src;
+	}    
+      src++;
+    }
+ 
+  if (in_name)
+    {
+      if (!*name)
+	{
+	  *name = tail;
+	  tail = set_user_id_part (tail, start, src - start);
+	}
+    }
+ 
+  /* Let unused parts point to an EOS.  */
+  tail--;
+  if (!*name)
+    *name = tail;
+  if (!*email)
+    *email = tail;
+  if (!*comment)
+    *comment = tail;
+}
+
+
+static void
+parse_x509_user_id (char *src, char **name, char **email,
+		    char **comment, char *tail)
+{
+  if (*src == '<' && src[strlen (src) - 1] == '>')
+    *email = src;
+  
+  /* Let unused parts point to an EOS.  */
+  tail--;
+  if (!*name)
+    *name = tail;
+  if (!*email)
+    *email = tail;
+  if (!*comment)
+    *comment = tail;
+}
+
+
+/* Take a name from the --with-colon listing, remove certain escape
+   sequences sequences and put it into the list of UIDs.  */
+gpgme_error_t
+_gpgme_key_append_name (gpgme_key_t key, char *src)
+{
+  gpgme_user_id_t uid;
+  char *dst;
+  int src_len = strlen (src);
+
+  assert (key);
+  /* We can malloc a buffer of the same length, because the converted
+     string will never be larger. Actually we allocate it twice the
+     size, so that we are able to store the parsed stuff there too.  */
+  uid = malloc (sizeof (*uid) + 2 * src_len + 3);
+  if (!uid)
+    return gpg_error_from_errno (errno);
+  memset (uid, 0, sizeof *uid);
+
+  uid->uid = ((char *) uid) + sizeof (*uid);
+  dst = uid->uid;
+  _gpgme_decode_c_string (src, &dst, src_len + 1);
+
+  dst += strlen (dst) + 1;
+  if (key->protocol == GPGME_PROTOCOL_CMS)
+    parse_x509_user_id (uid->uid, &uid->name, &uid->email,
+			&uid->comment, dst);
+  else
+    parse_user_id (uid->uid, &uid->name, &uid->email,
+		   &uid->comment, dst);
+
+  if (!key->uids)
+    key->uids = uid;
+  if (key->_last_uid)
+    key->_last_uid->next = uid;
+  key->_last_uid = uid;
+
+  return 0;
+}
+
+
+gpgme_key_sig_t
+_gpgme_key_add_sig (gpgme_key_t key, char *src)
+{
+  int src_len = src ? strlen (src) : 0;
+  gpgme_user_id_t uid;
+  gpgme_key_sig_t sig;
+
+  assert (key);	/* XXX */
+
+  uid = key->_last_uid;
+  assert (uid);	/* XXX */
+
+  /* We can malloc a buffer of the same length, because the converted
+     string will never be larger. Actually we allocate it twice the
+     size, so that we are able to store the parsed stuff there too.  */
+  sig = malloc (sizeof (*sig) + 2 * src_len + 3);
+  if (!sig)
+    return NULL;
+  memset (sig, 0, sizeof *sig);
+
+  sig->keyid = sig->_keyid;
+  sig->_keyid[16] = '\0';
+  sig->uid = ((char *) sig) + sizeof (*sig);
+
+  if (src)
+    {
+      char *dst = sig->uid;
+      _gpgme_decode_c_string (src, &dst, src_len + 1);
+      dst += strlen (dst) + 1;
+      if (key->protocol == GPGME_PROTOCOL_CMS)
+	parse_x509_user_id (sig->uid, &sig->name, &sig->email,
+			    &sig->comment, dst);
+      else
+	parse_user_id (sig->uid, &sig->name, &sig->email,
+		       &sig->comment, dst);
+    }
+
+  if (!uid->signatures)
+    uid->signatures = sig;
+  if (uid->_last_keysig)
+    uid->_last_keysig->next = sig;
+  uid->_last_keysig = sig;
+
+  return sig;
+}
+
+
+/* Acquire a reference to KEY.  */
+void
+gpgme_key_ref (gpgme_key_t key)
+{
+  LOCK (key_ref_lock);
+  key->_refs++;
+  UNLOCK (key_ref_lock);
+}
+
+
+/* gpgme_key_unref releases the key object.  Note, that this function
+   may not do an actual release if there are other shallow copies of
+   the objects.  You have to call this function for every newly
+   created key object as well as for every gpgme_key_ref() done on the
+   key object.  */
+void
+gpgme_key_unref (gpgme_key_t key)
+{
+  gpgme_user_id_t uid;
+  gpgme_subkey_t subkey;
+
+  if (!key)
+    return;
+
+  LOCK (key_ref_lock);
+  assert (key->_refs > 0);
+  if (--key->_refs)
+    {
+      UNLOCK (key_ref_lock);
+      return;
+    }
+  UNLOCK (key_ref_lock);
+
+  subkey = key->subkeys;
+  while (subkey)
+    {
+      gpgme_subkey_t next = subkey->next;
+      if (subkey->fpr)
+	free (subkey->fpr);
+      free (subkey);
+      subkey = next;
+    }
+
+  uid = key->uids;
+  while (uid)
+    {
+      gpgme_user_id_t next_uid = uid->next;
+      gpgme_key_sig_t keysig = uid->signatures;
+
+      while (keysig)
+	{
+	  gpgme_key_sig_t next_keysig = keysig->next;
+	  gpgme_sig_notation_t notation = keysig->notations;
+
+	  while (notation)
+	    {
+	      gpgme_sig_notation_t next_notation = notation->next;
+
+	      _gpgme_sig_notation_free (notation);
+	      notation = next_notation;
+	    }
+
+          free (keysig);
+	  keysig = next_keysig;
+        }
+      free (uid);
+      uid = next_uid;
+    }
+  
+  if (key->issuer_serial)
+    free (key->issuer_serial);
+  if (key->issuer_name)
+    free (key->issuer_name);
+
+  if (key->chain_id)
+    free (key->chain_id);
+
+  free (key);
+}
+
+
+/* Compatibility interfaces.  */
+
+void
+gpgme_key_release (gpgme_key_t key)
+{
+  gpgme_key_unref (key);
+}
+
+
+static const char *
+otrust_to_string (int otrust)
+{
+  switch (otrust)
+    {
+    case GPGME_VALIDITY_NEVER:
+      return "n";
+
+    case GPGME_VALIDITY_MARGINAL:
+      return "m";
+
+    case GPGME_VALIDITY_FULL:
+      return "f";
+
+    case GPGME_VALIDITY_ULTIMATE:
+      return "u";
+
+    default:
+      return "?";
+    }
+}
+
+
+static const char *
+validity_to_string (int validity)
+{
+  switch (validity)
+    {
+    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";
+
+    case GPGME_VALIDITY_UNKNOWN:
+    default:
+      return "?";
+    }
+}
+
+
+static const char *
+capabilities_to_string (gpgme_subkey_t subkey)
+{
+  static const char *const strings[8] =
+    {
+      "",
+      "c",
+      "s",
+      "sc",
+      "e",
+      "ec",
+      "es",
+      "esc"
+    };
+  return strings[(!!subkey->can_encrypt << 2)
+		 | (!!subkey->can_sign << 1)
+		 | (!!subkey->can_certify)];
+}
+
+
+/* Return the value of the attribute WHAT of ITEM, which has to be
+   representable by a string.  */
+const char *
+gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
+			   const void *reserved, int idx)
+{
+  gpgme_subkey_t subkey;
+  gpgme_user_id_t uid;
+  int i;
+
+  if (!key || reserved || idx < 0)
+    return NULL;
+
+  /* Select IDXth subkey.  */
+  subkey = key->subkeys;
+  for (i = 0; i < idx; i++)
+    {
+      subkey = subkey->next;
+      if (!subkey)
+	break;
+    }
+
+  /* Select the IDXth user ID.  */
+  uid = key->uids;
+  for (i = 0; i < idx; i++)
+    {
+      uid = uid->next;
+      if (!uid)
+	break;
+    }
+
+  switch (what)
+    {
+    case GPGME_ATTR_KEYID:
+      return subkey ? subkey->keyid : NULL;
+
+    case GPGME_ATTR_FPR:
+      return subkey ? subkey->fpr : NULL;
+
+    case GPGME_ATTR_ALGO:    
+      return subkey ? gpgme_pubkey_algo_name (subkey->pubkey_algo) : NULL;
+
+    case GPGME_ATTR_TYPE:
+      return key->protocol == GPGME_PROTOCOL_CMS ? "X.509" : "PGP";
+
+    case GPGME_ATTR_OTRUST:
+      return otrust_to_string (key->owner_trust);
+
+    case GPGME_ATTR_USERID:  
+      return uid ? uid->uid : NULL;
+
+    case GPGME_ATTR_NAME:   
+      return uid ? uid->name : NULL;
+
+    case GPGME_ATTR_EMAIL:
+      return uid ? uid->email : NULL;
+
+    case GPGME_ATTR_COMMENT:
+      return uid ? uid->comment : NULL;
+
+    case GPGME_ATTR_VALIDITY:
+      return uid ? validity_to_string (uid->validity) : NULL;
+
+    case GPGME_ATTR_KEY_CAPS:    
+      return subkey ? capabilities_to_string (subkey) : NULL;
+
+    case GPGME_ATTR_SERIAL:
+      return key->issuer_serial;
+
+    case GPGME_ATTR_ISSUER:
+      return idx ? NULL : key->issuer_name;
+
+    case GPGME_ATTR_CHAINID:
+      return key->chain_id;
+
+    default:
+      return NULL;
+    }
+}
+
+
+unsigned long
+gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
+			  const void *reserved, int idx)
+{
+  gpgme_subkey_t subkey;
+  gpgme_user_id_t uid;
+  int i;
+
+  if (!key || reserved || idx < 0)
+    return 0;
+
+  /* Select IDXth subkey.  */
+  subkey = key->subkeys;
+  for (i = 0; i < idx; i++)
+    {
+      subkey = subkey->next;
+      if (!subkey)
+	break;
+    }
+
+  /* Select the IDXth user ID.  */
+  uid = key->uids;
+  for (i = 0; i < idx; i++)
+    {
+      uid = uid->next;
+      if (!uid)
+	break;
+    }
+
+  switch (what)
+    {
+    case GPGME_ATTR_ALGO:
+      return subkey ? (unsigned long) subkey->pubkey_algo : 0;
+
+    case GPGME_ATTR_LEN:
+      return subkey ? (unsigned long) subkey->length : 0;
+
+    case GPGME_ATTR_TYPE:
+      return key->protocol == GPGME_PROTOCOL_CMS ? 1 : 0;
+
+    case GPGME_ATTR_CREATED:
+      return (subkey && subkey->timestamp >= 0)
+	? (unsigned long) subkey->timestamp : 0;
+
+    case GPGME_ATTR_EXPIRE: 
+      return (subkey && subkey->expires >= 0)
+	? (unsigned long) subkey->expires : 0;
+
+    case GPGME_ATTR_VALIDITY:
+      return uid ? uid->validity : 0;
+
+    case GPGME_ATTR_OTRUST:
+      return key->owner_trust;
+
+    case GPGME_ATTR_IS_SECRET:
+      return !!key->secret;
+
+    case GPGME_ATTR_KEY_REVOKED:
+      return subkey ? subkey->revoked : 0;
+
+    case GPGME_ATTR_KEY_INVALID:
+      return subkey ? subkey->invalid : 0;
+
+    case GPGME_ATTR_KEY_EXPIRED:
+      return subkey ? subkey->expired : 0;
+
+    case GPGME_ATTR_KEY_DISABLED:
+      return subkey ? subkey->disabled : 0;
+
+    case GPGME_ATTR_UID_REVOKED:
+      return uid ? uid->revoked : 0;
+
+    case GPGME_ATTR_UID_INVALID:
+      return uid ? uid->invalid : 0;
+
+    case GPGME_ATTR_CAN_ENCRYPT:
+      return key->can_encrypt;
+
+    case GPGME_ATTR_CAN_SIGN:
+      return key->can_sign;
+
+    case GPGME_ATTR_CAN_CERTIFY:
+      return key->can_certify;
+
+    default:
+      return 0;
+    }
+}
+
+
+static gpgme_key_sig_t
+get_keysig (gpgme_key_t key, int uid_idx, int idx)
+{
+  gpgme_user_id_t uid;
+  gpgme_key_sig_t sig;
+
+  if (!key || uid_idx < 0 || idx < 0)
+    return NULL;
+
+  uid = key->uids;
+  while (uid && uid_idx > 0)
+    {
+      uid = uid->next;
+      uid_idx--;
+    }
+  if (!uid)
+    return NULL;
+
+  sig = uid->signatures;
+  while (sig && idx > 0)
+    {
+      sig = sig->next;
+      idx--;
+    }
+  return sig;
+}
+
+
+const char *
+gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
+			       _gpgme_attr_t what,
+			       const void *reserved, int idx)
+{
+  gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
+
+  if (!certsig || reserved)
+    return NULL;
+
+  switch (what)
+    {
+    case GPGME_ATTR_KEYID:
+      return certsig->keyid;
+
+    case GPGME_ATTR_ALGO:    
+      return gpgme_pubkey_algo_name (certsig->pubkey_algo);
+
+    case GPGME_ATTR_USERID:
+      return certsig->uid;
+
+    case GPGME_ATTR_NAME:   
+      return certsig->name;
+
+    case GPGME_ATTR_EMAIL:
+      return certsig->email;
+
+    case GPGME_ATTR_COMMENT:
+      return certsig->comment;
+   
+    default:
+      return NULL;
+    }
+}
+
+
+unsigned long
+gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, _gpgme_attr_t what,
+			      const void *reserved, int idx)
+{
+  gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
+
+  if (!certsig || reserved)
+    return 0;
+
+  switch (what)
+    {
+    case GPGME_ATTR_ALGO:    
+      return (unsigned long) certsig->pubkey_algo;
+
+    case GPGME_ATTR_CREATED: 
+      return certsig->timestamp < 0 ? 0L : (unsigned long) certsig->timestamp;
+
+    case GPGME_ATTR_EXPIRE: 
+      return certsig->expires < 0 ? 0L : (unsigned long) certsig->expires;
+
+    case GPGME_ATTR_KEY_REVOKED:
+      return certsig->revoked;
+
+    case GPGME_ATTR_KEY_INVALID:
+      return certsig->invalid;
+
+    case GPGME_ATTR_KEY_EXPIRED:
+      return certsig->expired;
+
+    case GPGME_ATTR_SIG_CLASS:
+      return certsig->sig_class;
+
+    case GPGME_ATTR_SIG_STATUS:
+      return certsig->status;
+
+    default:
+      return 0;
+    }
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/keylist.c b/libtdenetwork/libgpgme-copy/gpgme/keylist.c
new file mode 100644
index 000000000..442409bef
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/keylist.c
@@ -0,0 +1,980 @@
+/* keylist.c - Listing keys.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2006 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+#include "debug.h"
+
+
+struct key_queue_item_s
+{
+  struct key_queue_item_s *next;
+  gpgme_key_t key;
+};
+
+typedef struct
+{
+  struct _gpgme_op_keylist_result result;
+
+  gpgme_key_t tmp_key;
+
+  /* This points to the last uid in tmp_key.  */
+  gpgme_user_id_t tmp_uid;
+
+  /* This points to the last sig in tmp_uid.  */
+  gpgme_key_sig_t tmp_keysig;
+
+  /* Something new is available.  */
+  int key_cond;
+  struct key_queue_item_s *key_queue;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+  struct key_queue_item_s *key = opd->key_queue;
+
+  if (opd->tmp_key)
+    gpgme_key_unref (opd->tmp_key);
+
+  /* opd->tmp_uid and opd->tmp_keysig are actually part of opd->tmp_key,
+     so we do not need to release them here.  */
+
+  while (key)
+    {
+      struct key_queue_item_s *next = key->next;
+
+      gpgme_key_unref (key->key);
+      key = next;
+    }
+}
+
+
+gpgme_keylist_result_t
+gpgme_op_keylist_result (gpgme_ctx_t ctx)
+{
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
+  opd = hook;
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+static gpgme_error_t
+keylist_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  switch (code)
+    {
+    case GPGME_STATUS_TRUNCATED:
+      opd->result.truncated = 1;
+      break;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+
+static void
+set_subkey_trust_info (gpgme_subkey_t subkey, const char *src)
+{
+  while (*src && !isdigit (*src))
+    {
+      switch (*src)
+	{
+	case 'e':
+	  subkey->expired = 1;
+	  break;
+
+	case 'r':
+	  subkey->revoked = 1;
+	  break;
+
+	case 'd':
+          /* Note that gpg 1.3 won't print that anymore but only uses
+             the capabilities field. */
+	  subkey->disabled = 1;
+	  break;
+
+	case 'i':
+	  subkey->invalid = 1;
+	  break;
+        }
+      src++;
+    }
+}
+
+
+static void
+set_mainkey_trust_info (gpgme_key_t key, const char *src)
+{
+  /* First set the trust info of the main key (the first subkey).  */
+  set_subkey_trust_info (key->subkeys, src);
+
+  /* Now set the summarized trust info.  */
+  while (*src && !isdigit (*src))
+    {
+      switch (*src)
+	{
+	case 'e':
+	  key->expired = 1;
+	  break;
+
+	case 'r':
+	  key->revoked = 1;
+	  break;
+
+	case 'd':
+          /* Note that gpg 1.3 won't print that anymore but only uses
+             the capabilities field.  However, it is still used for
+             external key listings.  */
+	  key->disabled = 1;
+	  break;
+
+	case 'i':
+	  key->invalid = 1;
+	  break;
+        }
+      src++;
+    }
+}
+
+
+static void
+set_userid_flags (gpgme_key_t key, const char *src)
+{
+  gpgme_user_id_t uid = key->_last_uid;
+
+  assert (uid);
+  /* Look at letters and stop at the first digit.  */
+  while (*src && !isdigit (*src))
+    {
+      switch (*src)
+	{
+	case 'r':
+	  uid->revoked = 1;
+	  break;
+	  
+	case 'i':
+	  uid->invalid = 1;
+	  break;
+
+	case 'n':
+	  uid->validity = GPGME_VALIDITY_NEVER;
+	  break;
+
+	case 'm':
+	  uid->validity = GPGME_VALIDITY_MARGINAL;
+	  break;
+
+	case 'f':
+	  uid->validity = GPGME_VALIDITY_FULL;
+	  break;
+
+	case 'u':
+	  uid->validity = GPGME_VALIDITY_ULTIMATE;
+	  break;
+        }
+      src++;
+    }
+}
+
+
+static void
+set_subkey_capability (gpgme_subkey_t subkey, const char *src)
+{
+  while (*src)
+    {
+      switch (*src)
+	{
+	case 'e':
+	  subkey->can_encrypt = 1;
+	  break;
+
+	case 's':
+	  subkey->can_sign = 1;
+	  break;
+
+	case 'c':
+	  subkey->can_certify = 1;
+	  break;
+
+	case 'a':
+	  subkey->can_authenticate = 1;
+	  break;
+
+	case 'q':
+	  subkey->is_qualified = 1;
+	  break;
+
+	case 'd':
+	  subkey->disabled = 1;
+	  break;
+        }
+      src++;
+    }
+}
+
+
+static void
+set_mainkey_capability (gpgme_key_t key, const char *src)
+{
+  /* First set the capabilities of the main key (the first subkey).  */
+  set_subkey_capability (key->subkeys, src);
+
+  while (*src)
+    {
+      switch (*src)
+	{
+	case 'd':
+        case 'D':
+          /* Note, that this flag is also set using the key validity
+             field for backward compatibility with gpg 1.2.  We use d
+             and D, so that a future gpg version will be able to
+             disable certain subkeys. Currently it is expected that
+             gpg sets this for the primary key. */
+       	  key->disabled = 1;
+          break;
+
+	case 'e':
+	case 'E':
+	  key->can_encrypt = 1;
+	  break;
+
+	case 's':
+	case 'S':
+	  key->can_sign = 1;
+	  break;
+
+	case 'c':
+	case 'C':
+	  key->can_certify = 1;
+	  break;
+
+	case 'a':
+	case 'A':
+	  key->can_authenticate = 1;
+	  break;
+
+	case 'q':
+	case 'Q':
+	  key->is_qualified = 1;
+	  break;
+        }
+      src++;
+    }
+}
+
+
+static void
+set_ownertrust (gpgme_key_t key, const char *src)
+{
+  /* Look at letters and stop at the first digit.  */
+  while (*src && !isdigit (*src))
+    {
+      switch (*src)
+	{
+	case 'n':
+	  key->owner_trust = GPGME_VALIDITY_NEVER;
+	  break;
+
+	case 'm':
+	  key->owner_trust = GPGME_VALIDITY_MARGINAL;
+	  break;
+
+	case 'f':
+	  key->owner_trust = GPGME_VALIDITY_FULL;
+	  break;
+
+	case 'u':
+	  key->owner_trust = GPGME_VALIDITY_ULTIMATE;
+	  break;
+
+        default:
+	  key->owner_trust = GPGME_VALIDITY_UNKNOWN;
+	  break;
+        }
+      src++;
+    }
+}
+
+
+/* We have read an entire key into tmp_key and should now finish it.
+   It is assumed that this releases tmp_key.  */
+static void
+finish_key (gpgme_ctx_t ctx, op_data_t opd)
+{
+  gpgme_key_t key = opd->tmp_key;
+
+  opd->tmp_key = NULL;
+  opd->tmp_uid = NULL;
+  opd->tmp_keysig = NULL;
+
+  if (key)
+    _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
+}
+
+
+/* Note: We are allowed to modify LINE.  */
+static gpgme_error_t
+keylist_colon_handler (void *priv, char *line)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  enum
+    {
+      RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR,
+      RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
+    }
+  rectype = RT_NONE;
+#define NR_FIELDS 16
+  char *field[NR_FIELDS];
+  int fields = 0;
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+  gpgme_key_t key;
+  gpgme_subkey_t subkey = NULL;
+  gpgme_key_sig_t keysig = NULL;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  key = opd->tmp_key;
+
+  DEBUG3 ("keylist_colon_handler ctx = %p, key = %p, line = %s\n",
+	  ctx, key, line ? line : "(null)");
+
+  if (!line)
+    {
+      /* End Of File.  */
+      finish_key (ctx, opd);
+      return 0;
+    }
+
+  while (line && fields < NR_FIELDS)
+    {
+      field[fields++] = line;
+      line = strchr (line, ':');
+      if (line)
+	*(line++) = '\0';
+    }
+
+  if (!strcmp (field[0], "sig"))
+    rectype = RT_SIG;
+  else if (!strcmp (field[0], "rev"))
+    rectype = RT_REV;
+  else if (!strcmp (field[0], "pub"))
+    rectype = RT_PUB;
+  else if (!strcmp (field[0], "sec"))
+    rectype = RT_SEC;
+  else if (!strcmp (field[0], "crt"))
+    rectype = RT_CRT;
+  else if (!strcmp (field[0], "crs"))
+    rectype = RT_CRS;
+  else if (!strcmp (field[0], "fpr") && key) 
+    rectype = RT_FPR;
+  else if (!strcmp (field[0], "uid") && key)
+    rectype = RT_UID;
+  else if (!strcmp (field[0], "sub") && key)
+    rectype = RT_SUB; 
+  else if (!strcmp (field[0], "ssb") && key)
+    rectype = RT_SSB;
+  else if (!strcmp (field[0], "spk") && key)
+    rectype = RT_SPK;
+  else 
+    rectype = RT_NONE;
+
+  /* Only look at signatures immediately following a user ID.  For
+     this, clear the user ID pointer when encountering anything but a
+     signature.  */
+  if (rectype != RT_SIG && rectype != RT_REV)
+    opd->tmp_uid = NULL;
+
+  /* Only look at subpackets immediately following a signature.  For
+     this, clear the signature pointer when encountering anything but
+     a subpacket.  */
+  if (rectype != RT_SPK)
+    opd->tmp_keysig = NULL;
+
+  switch (rectype)
+    {
+    case RT_PUB:
+    case RT_SEC:
+    case RT_CRT:
+    case RT_CRS:
+      /* Start a new keyblock.  */
+      err = _gpgme_key_new (&key);
+      if (err)
+	return err;
+      key->keylist_mode = ctx->keylist_mode;
+      err = _gpgme_key_add_subkey (key, &subkey);
+      if (err)
+	{
+	  gpgme_key_unref (key);
+	  return err;
+	}
+
+      if (rectype == RT_SEC || rectype == RT_CRS)
+	key->secret = subkey->secret = 1;
+      if (rectype == RT_CRT || rectype == RT_CRS)
+	key->protocol = GPGME_PROTOCOL_CMS;
+      finish_key (ctx, opd);
+      opd->tmp_key = key;
+
+      /* Field 2 has the trust info.  */
+      if (fields >= 2)
+	set_mainkey_trust_info (key, field[1]);
+
+      /* Field 3 has the key length.  */
+      if (fields >= 3)
+	{
+	  int i = atoi (field[2]);
+	  /* Ignore invalid values.  */
+	  if (i > 1)
+	    subkey->length = i; 
+	}
+
+      /* Field 4 has the public key algorithm.  */
+      if (fields >= 4)
+	{
+	  int i = atoi (field[3]);
+	  if (i >= 1 && i < 128)
+	    subkey->pubkey_algo = i;
+	}
+
+      /* Field 5 has the long keyid.  Allow short key IDs for the
+	 output of an external keyserver listing.  */
+      if (fields >= 5 && strlen (field[4]) <= DIM(subkey->_keyid) - 1)
+	strcpy (subkey->_keyid, field[4]);
+
+      /* Field 6 has the timestamp (seconds).  */
+      if (fields >= 6)
+	subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
+
+      /* Field 7 has the expiration time (seconds).  */
+      if (fields >= 7)
+	subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
+
+      /* Field 8 has the X.509 serial number.  */
+      if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS))
+	{
+	  key->issuer_serial = strdup (field[7]);
+	  if (!key->issuer_serial)
+	    return gpg_error_from_errno (errno);
+	}
+	  
+      /* Field 9 has the ownertrust.  */
+      if (fields >= 9)
+	set_ownertrust (key, field[8]);
+
+      /* Field 10 is not used for gpg due to --fixed-list-mode option
+	 but GPGSM stores the issuer name.  */
+      if (fields >= 10 && (rectype == RT_CRT || rectype == RT_CRS))
+	if (_gpgme_decode_c_string (field[9], &key->issuer_name, 0))
+	  return gpg_error (GPG_ERR_ENOMEM);	/* FIXME */
+
+      /* Field 11 has the signature class.  */
+
+      /* Field 12 has the capabilities.  */
+      if (fields >= 12)
+	set_mainkey_capability (key, field[11]);
+
+      /* Field 15 carries special flags of a secret key.  We reset the
+         SECRET flag of a subkey here if the key is actually only a
+         stub. The SECRET flag of the key will be true even then. */
+      if (fields >= 15 && key->secret)
+        if (*field[14] == '#')
+          subkey->secret = 0;
+      break;
+
+    case RT_SUB:
+    case RT_SSB:
+      /* Start a new subkey.  */
+      err = _gpgme_key_add_subkey (key, &subkey);
+      if (err)
+	return err;
+
+      if (rectype == RT_SSB)
+	subkey->secret = 1;
+
+      /* Field 2 has the trust info.  */
+      if (fields >= 2)
+	set_subkey_trust_info (subkey, field[1]);
+
+      /* Field 3 has the key length.  */
+      if (fields >= 3)
+	{
+	  int i = atoi (field[2]);
+	  /* Ignore invalid values.  */
+	  if (i > 1)
+	    subkey->length = i;
+	}
+
+      /* Field 4 has the public key algorithm.  */
+      if (fields >= 4)
+	{
+	  int i = atoi (field[3]);
+	  if (i >= 1 && i < 128)
+	    subkey->pubkey_algo = i;
+	}
+
+      /* Field 5 has the long keyid.  */
+      if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
+	strcpy (subkey->_keyid, field[4]);
+
+      /* Field 6 has the timestamp (seconds).  */
+      if (fields >= 6)
+	subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
+
+      /* Field 7 has the expiration time (seconds).  */
+      if (fields >= 7)
+	subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
+
+      /* Field 8 is reserved (LID).  */
+      /* Field 9 has the ownertrust.  */
+      /* Field 10, the user ID, is n/a for a subkey.  */
+      
+      /* Field 11 has the signature class.  */
+
+      /* Field 12 has the capabilities.  */
+      if (fields >= 12)
+	set_subkey_capability (subkey, field[11]);
+
+      /* Field 15 carries special flags of a secret key. */
+      if (fields >= 15 && key->secret)
+        if (*field[14] == '#')
+          subkey->secret = 0;
+      break;
+
+    case RT_UID:
+      /* Field 2 has the trust info, and field 10 has the user ID.  */
+      if (fields >= 10)
+	{
+	  if (_gpgme_key_append_name (key, field[9]))
+	    return gpg_error_from_errno (GPG_ERR_ENOMEM);	/* FIXME */
+	  else
+	    {
+	      if (field[1])
+		set_userid_flags (key, field[1]);
+	      opd->tmp_uid = key->_last_uid;
+	    }
+	}
+      break;
+
+    case RT_FPR:
+      /* Field 10 has the fingerprint (take only the first one).  */
+      if (fields >= 10 && field[9] && *field[9])
+	{
+          /* Need to apply it to the last subkey because all subkeys
+             do have fingerprints. */
+          subkey = key->_last_subkey;
+          if (!subkey->fpr)
+            {
+              subkey->fpr = strdup (field[9]);
+              if (!subkey->fpr)
+                return gpg_error_from_errno (errno);
+            }
+	}
+
+      /* Field 13 has the gpgsm chain ID (take only the first one).  */
+      if (fields >= 13 && !key->chain_id && *field[12])
+	{
+	  key->chain_id = strdup (field[12]);
+	  if (!key->chain_id)
+	    return gpg_error_from_errno (errno);
+	}
+      break;
+
+    case RT_SIG:
+    case RT_REV:
+      if (!opd->tmp_uid)
+	return 0;
+
+      /* Start a new (revoked) signature.  */
+      assert (opd->tmp_uid == key->_last_uid);
+      keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
+      if (!keysig)
+	return gpg_error (GPG_ERR_ENOMEM);	/* FIXME */
+
+      /* Field 2 has the calculated trust ('!', '-', '?', '%').  */
+      if (fields >= 2)
+	switch (field[1][0])
+	  {
+	  case '!':
+	    keysig->status = gpg_error (GPG_ERR_NO_ERROR);
+	    break;
+
+	  case '-':
+	    keysig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
+	    break;
+
+	  case '?':
+	    keysig->status = gpg_error (GPG_ERR_NO_PUBKEY);
+	    break;
+
+	  case '%':
+	    keysig->status = gpg_error (GPG_ERR_GENERAL);
+	    break;
+
+	  default:
+	    keysig->status = gpg_error (GPG_ERR_NO_ERROR);
+	    break;
+	  }
+
+      /* Field 4 has the public key algorithm.  */
+      if (fields >= 4)
+	{
+	  int i = atoi (field[3]);
+	  if (i >= 1 && i < 128)
+	    keysig->pubkey_algo = i;
+	}
+      
+      /* Field 5 has the long keyid.  */
+      if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
+	strcpy (keysig->_keyid, field[4]);
+      
+      /* Field 6 has the timestamp (seconds).  */
+      if (fields >= 6)
+	keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
+
+      /* Field 7 has the expiration time (seconds).  */
+      if (fields >= 7)
+	keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
+
+      /* Field 11 has the signature class (eg, 0x30 means revoked).  */
+      if (fields >= 11)
+	if (field[10][0] && field[10][1])
+	  {
+	    int sig_class = _gpgme_hextobyte (field[10]);
+	    if (sig_class >= 0)
+	      {
+		keysig->sig_class = sig_class;
+		keysig->class = keysig->sig_class;
+		if (sig_class == 0x30)
+		  keysig->revoked = 1;
+	      }
+	    if (field[10][2] == 'x')
+	      keysig->exportable = 1;
+	  }
+
+      opd->tmp_keysig = keysig;
+      break;
+
+    case RT_SPK:
+      if (!opd->tmp_keysig)
+	return 0;
+      assert (opd->tmp_keysig == key->_last_uid->_last_keysig);
+
+      if (fields >= 4)
+	{
+	  /* Field 2 has the subpacket type.  */
+	  int type = atoi (field[1]);
+
+	  /* Field 3 has the flags.  */
+	  int flags = atoi (field[2]);
+
+	  /* Field 4 has the length.  */
+	  int len = atoi (field[3]);
+
+	  /* Field 5 has the data.  */
+	  char *data = field[4];
+
+	  /* Type 20: Notation data.  */
+	  /* Type 26: Policy URL.  */
+	  if (type == 20 || type == 26)
+	    {
+	      gpgme_sig_notation_t notation;
+
+	      keysig = opd->tmp_keysig;
+
+	      /* At this time, any error is serious.  */
+	      err = _gpgme_parse_notation (&notation, type, flags, len, data);
+	      if (err)
+		return err;
+
+	      /* Add a new notation.  FIXME: Could be factored out.  */
+	      if (!keysig->notations)
+		keysig->notations = notation;
+	      if (keysig->_last_notation)
+		keysig->_last_notation->next = notation;
+	      keysig->_last_notation = notation;
+	    }
+	}
+    
+    case RT_NONE:
+      /* Unknown record.  */
+      break;
+    }
+  return 0;
+}
+
+
+void
+_gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, void *type_data)
+{
+  gpgme_error_t err;
+  gpgme_ctx_t ctx = (gpgme_ctx_t) data;
+  gpgme_key_t key = (gpgme_key_t) type_data;
+  void *hook;
+  op_data_t opd;
+  struct key_queue_item_s *q, *q2;
+
+  assert (type == GPGME_EVENT_NEXT_KEY);
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return;
+
+  q = malloc (sizeof *q);
+  if (!q)
+    {
+      gpgme_key_unref (key);
+      /* FIXME       return GPGME_Out_Of_Core; */
+      return;
+    }
+  q->key = key;
+  q->next = NULL;
+  /* FIXME: Use a tail pointer?  */
+  if (!(q2 = opd->key_queue))
+    opd->key_queue = q;
+  else
+    {
+      for (; q2->next; q2 = q2->next)
+	;
+      q2->next = q;
+    }
+  opd->key_cond = 1;
+}
+
+
+/* Start a keylist operation within CTX, searching for keys which
+   match PATTERN.  If SECRET_ONLY is true, only secret keys are
+   returned.  */
+gpgme_error_t
+gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_reset (ctx, 2);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
+
+  err = _gpgme_engine_set_colon_line_handler (ctx->engine,
+					      keylist_colon_handler, ctx);
+  if (err)
+    return err;
+
+  return _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
+				   ctx->keylist_mode);
+}
+
+
+/* Start a keylist operation within CTX, searching for keys which
+   match PATTERN.  If SECRET_ONLY is true, only secret keys are
+   returned.  */
+gpgme_error_t
+gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
+			    int secret_only, int reserved)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_reset (ctx, 2);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
+  err = _gpgme_engine_set_colon_line_handler (ctx->engine,
+					      keylist_colon_handler, ctx);
+  if (err)
+    return err;
+
+  return _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
+				       reserved, ctx->keylist_mode);
+}
+
+
+/* Return the next key from the keylist in R_KEY.  */
+gpgme_error_t
+gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
+{
+  gpgme_error_t err;
+  struct key_queue_item_s *queue_item;
+  void *hook;
+  op_data_t opd;
+
+  if (!ctx || !r_key)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  *r_key = NULL;
+  if (!ctx)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+  if (opd == NULL)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!opd->key_queue)
+    {
+      err = _gpgme_wait_on_condition (ctx, &opd->key_cond);
+      if (err)
+	return err;
+
+      if (!opd->key_cond)
+	return gpg_error (GPG_ERR_EOF);
+
+      opd->key_cond = 0; 
+      assert (opd->key_queue);
+    }
+  queue_item = opd->key_queue;
+  opd->key_queue = queue_item->next;
+  if (!opd->key_queue)
+    opd->key_cond = 0;
+  
+  *r_key = queue_item->key;
+  free (queue_item);
+  return 0;
+}
+
+
+/* Terminate a pending keylist operation within CTX.  */
+gpgme_error_t
+gpgme_op_keylist_end (gpgme_ctx_t ctx)
+{
+  if (!ctx)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  return 0;
+}
+
+
+/* Get the key with the fingerprint FPR from the crypto backend.  If
+   SECRET is true, get the secret key.  */
+gpgme_error_t
+gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
+	       int secret)
+{
+  gpgme_ctx_t listctx;
+  gpgme_error_t err;
+  gpgme_key_t key;
+
+  if (!ctx || !r_key || !fpr)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  
+  if (strlen (fpr) < 8)	/* We have at least a key ID.  */
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  /* FIXME: We use our own context because we have to avoid the user's
+     I/O callback handlers.  */
+  err = gpgme_new (&listctx);
+  if (err)
+    return err;
+  {
+    gpgme_protocol_t proto;
+    gpgme_engine_info_t info;
+
+    /* Clone the relevant state.  */
+    proto = gpgme_get_protocol (ctx);
+    gpgme_set_protocol (listctx, proto);
+    gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
+    info = gpgme_ctx_get_engine_info (ctx);
+    while (info && info->protocol != proto)
+      info = info->next;
+    if (info)
+      gpgme_ctx_set_engine_info (listctx, proto,
+				 info->file_name, info->home_dir);
+  }
+
+  err = gpgme_op_keylist_start (listctx, fpr, secret);
+  if (!err)
+    err = gpgme_op_keylist_next (listctx, r_key);
+  if (!err)
+    {
+      err = gpgme_op_keylist_next (listctx, &key);
+      if (gpgme_err_code (err) == GPG_ERR_EOF)
+	err = gpg_error (GPG_ERR_NO_ERROR);
+      else
+	{
+	  if (!err)
+	    {
+	      gpgme_key_unref (key);
+	      err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
+	    }
+	  gpgme_key_unref (*r_key);
+	}
+    }
+  gpgme_release (listctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/libgpgme.vers b/libtdenetwork/libgpgme-copy/gpgme/libgpgme.vers
new file mode 100644
index 000000000..11571b9e5
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/libgpgme.vers
@@ -0,0 +1,167 @@
+# libgpgme.vers - List of symbols to export.
+# Copyright (C) 2002, 2004, 2005 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 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.
+#
+# 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 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
+
+#-------------------------------------------------------
+# Please remember to add new functions also to gpgme.def
+#-------------------------------------------------------
+
+GPGME_1.1 {
+  global:
+    gpgme_set_engine_info;
+
+    gpgme_ctx_get_engine_info;
+    gpgme_ctx_set_engine_info;
+
+    gpgme_data_set_file_name;
+    gpgme_data_get_file_name;
+
+    gpgme_sig_notation_clear;
+    gpgme_sig_notation_add;
+    gpgme_sig_notation_get;
+
+    gpgme_free;
+};
+
+
+GPGME_1.0 {
+  global:
+    gpgme_check_version;
+    gpgme_get_engine_info;
+    gpgme_engine_check_version;
+
+    gpgme_err_code_from_errno;
+    gpgme_err_code_to_errno;
+    gpgme_err_make_from_errno;
+    gpgme_error_from_errno;
+    gpgme_strerror;
+    gpgme_strerror_r;
+    gpgme_strsource;
+
+    gpgme_data_get_encoding;
+    gpgme_data_new;
+    gpgme_data_new_from_cbs;
+    gpgme_data_new_from_fd;
+    gpgme_data_new_from_file;
+    gpgme_data_new_from_filepart;
+    gpgme_data_new_from_mem;
+    gpgme_data_new_from_stream;
+    gpgme_data_read;
+    gpgme_data_release;
+    gpgme_data_release_and_get_mem;
+    gpgme_data_seek;
+    gpgme_data_set_encoding;
+    gpgme_data_write;
+
+    gpgme_get_protocol_name;
+    gpgme_hash_algo_name;
+    gpgme_pubkey_algo_name;
+
+    gpgme_new;
+    gpgme_get_armor;
+    gpgme_get_include_certs;
+    gpgme_get_io_cbs;
+    gpgme_get_keylist_mode;
+    gpgme_get_passphrase_cb;
+    gpgme_get_progress_cb;
+    gpgme_get_protocol;
+    gpgme_get_textmode;
+    gpgme_release;
+    gpgme_set_armor;
+    gpgme_set_include_certs;
+    gpgme_set_io_cbs;
+    gpgme_set_keylist_mode;
+    gpgme_set_locale;
+    gpgme_set_passphrase_cb;
+    gpgme_set_progress_cb;
+    gpgme_set_protocol;
+    gpgme_set_textmode;
+    gpgme_signers_add;
+    gpgme_signers_clear;
+    gpgme_signers_enum;
+
+    gpgme_key_ref;
+    gpgme_key_unref;
+    gpgme_key_release;
+
+    gpgme_trust_item_ref;
+    gpgme_trust_item_unref;
+
+    gpgme_cancel;
+    gpgme_op_card_edit;
+    gpgme_op_card_edit_start;
+    gpgme_op_decrypt;
+    gpgme_op_decrypt_result;
+    gpgme_op_decrypt_start;
+    gpgme_op_decrypt_verify;
+    gpgme_op_decrypt_verify_start;
+    gpgme_op_delete;
+    gpgme_op_delete_start;
+    gpgme_op_edit;
+    gpgme_op_edit_start;
+    gpgme_op_encrypt;
+    gpgme_op_encrypt_result;
+    gpgme_op_encrypt_sign;
+    gpgme_op_encrypt_sign_start;
+    gpgme_op_encrypt_start;
+    gpgme_op_export;
+    gpgme_op_export_ext;
+    gpgme_op_export_ext_start;
+    gpgme_op_export_start;
+    gpgme_op_genkey;
+    gpgme_op_genkey_result;
+    gpgme_op_genkey_start;
+    gpgme_get_key;
+    gpgme_op_import;
+    gpgme_op_import_result;
+    gpgme_op_import_start;
+    gpgme_op_keylist_end;
+    gpgme_op_keylist_ext_start;
+    gpgme_op_keylist_next;
+    gpgme_op_keylist_result;
+    gpgme_op_keylist_start;
+    gpgme_op_sign;
+    gpgme_op_sign_result;
+    gpgme_op_sign_start;
+    gpgme_op_trustlist_end;
+    gpgme_op_trustlist_next;
+    gpgme_op_trustlist_start;
+    gpgme_op_verify;
+    gpgme_op_verify_result;
+    gpgme_op_verify_start;
+    gpgme_wait;
+
+    gpgme_data_new_with_read_cb;
+    gpgme_data_rewind;
+    gpgme_get_sig_status;
+    gpgme_get_sig_string_attr;
+    gpgme_get_sig_ulong_attr;
+    gpgme_get_sig_key;
+    gpgme_key_get_string_attr;
+    gpgme_key_get_ulong_attr;
+    gpgme_key_sig_get_string_attr;
+    gpgme_key_sig_get_ulong_attr;
+    gpgme_op_import_ext;
+    gpgme_trust_item_get_int_attr;
+    gpgme_trust_item_get_string_attr;
+    gpgme_trust_item_release;
+
+  local:
+    *;
+
+};
diff --git a/libtdenetwork/libgpgme-copy/gpgme/memrchr.c b/libtdenetwork/libgpgme-copy/gpgme/memrchr.c
new file mode 100644
index 000000000..4f91ef2bd
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/memrchr.c
@@ -0,0 +1,210 @@
+/* memrchr -- find the last occurrence of a byte in a memory block
+   Copyright (C) 1991, 93, 96, 97, 99, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+   with help from Dan Sahlin (dan@sics.se) and
+   commentary by Jim Blandy (jimb@ai.mit.edu);
+   adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+   and implemented by Roland McGrath (roland@ai.mit.edu).
+
+   The GNU C Library 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.
+
+   The GNU C Library 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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+#include <stdlib.h>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#undef __ptr_t
+#if defined __cplusplus || (defined __STDC__ && __STDC__)
+# define __ptr_t void *
+#else /* Not C++ or ANSI C.  */
+# define __ptr_t char *
+#endif /* C++ or ANSI C.  */
+
+#if defined _LIBC
+# include <string.h>
+# include <memcopy.h>
+#else
+# define reg_char char
+#endif
+
+#if defined HAVE_LIMITS_H || defined _LIBC
+# include <limits.h>
+#endif
+
+#define LONG_MAX_32_BITS 2147483647
+
+#ifndef LONG_MAX
+# define LONG_MAX LONG_MAX_32_BITS
+#endif
+
+#include <sys/types.h>
+
+#undef __memrchr
+#undef memrchr
+
+#ifndef weak_alias
+# define __memrchr memrchr
+#endif
+
+/* Search no more than N bytes of S for C.  */
+__ptr_t
+__memrchr (s, c_in, n)
+     const __ptr_t s;
+     int c_in;
+     size_t n;
+{
+  const unsigned char *char_ptr;
+  const unsigned long int *longword_ptr;
+  unsigned long int longword, magic_bits, charmask;
+  unsigned reg_char c;
+
+  c = (unsigned char) c_in;
+
+  /* Handle the last few characters by reading one character at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = (const unsigned char *) s + n;
+       n > 0 && ((unsigned long int) char_ptr
+		 & (sizeof (longword) - 1)) != 0;
+       --n)
+    if (*--char_ptr == c)
+      return (__ptr_t) char_ptr;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to 8-byte longwords.  */
+
+  longword_ptr = (const unsigned long int *) char_ptr;
+
+  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
+     the "holes."  Note that there is a hole just to the left of
+     each byte, with an extra at the end:
+
+     bits:  01111110 11111110 11111110 11111111
+     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+     The 1-bits make sure that carries propagate to the next 0-bit.
+     The 0-bits provide holes for carries to fall into.  */
+
+  if (sizeof (longword) != 4 && sizeof (longword) != 8)
+    abort ();
+
+#if LONG_MAX <= LONG_MAX_32_BITS
+  magic_bits = 0x7efefeff;
+#else
+  magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
+#endif
+
+  /* Set up a longword, each of whose bytes is C.  */
+  charmask = c | (c << 8);
+  charmask |= charmask << 16;
+#if LONG_MAX > LONG_MAX_32_BITS
+  charmask |= charmask << 32;
+#endif
+
+  /* Instead of the traditional loop which tests each character,
+     we will test a longword at a time.  The tricky part is testing
+     if *any of the four* bytes in the longword in question are zero.  */
+  while (n >= sizeof (longword))
+    {
+      /* We tentatively exit the loop if adding MAGIC_BITS to
+	 LONGWORD fails to change any of the hole bits of LONGWORD.
+
+	 1) Is this safe?  Will it catch all the zero bytes?
+	 Suppose there is a byte with all zeros.  Any carry bits
+	 propagating from its left will fall into the hole at its
+	 least significant bit and stop.  Since there will be no
+	 carry from its most significant bit, the LSB of the
+	 byte to the left will be unchanged, and the zero will be
+	 detected.
+
+	 2) Is this worthwhile?  Will it ignore everything except
+	 zero bytes?  Suppose every byte of LONGWORD has a bit set
+	 somewhere.  There will be a carry into bit 8.  If bit 8
+	 is set, this will carry into bit 16.  If bit 8 is clear,
+	 one of bits 9-15 must be set, so there will be a carry
+	 into bit 16.  Similarly, there will be a carry into bit
+	 24.  If one of bits 24-30 is set, there will be a carry
+	 into bit 31, so all of the hole bits will be changed.
+
+	 The one misfire occurs when bits 24-30 are clear and bit
+	 31 is set; in this case, the hole at bit 31 is not
+	 changed.  If we had access to the processor carry flag,
+	 we could close this loophole by putting the fourth hole
+	 at bit 32!
+
+	 So it ignores everything except 128's, when they're aligned
+	 properly.
+
+	 3) But wait!  Aren't we looking for C, not zero?
+	 Good point.  So what we do is XOR LONGWORD with a longword,
+	 each of whose bytes is C.  This turns each byte that is C
+	 into a zero.  */
+
+      longword = *--longword_ptr ^ charmask;
+
+      /* Add MAGIC_BITS to LONGWORD.  */
+      if ((((longword + magic_bits)
+
+	    /* Set those bits that were unchanged by the addition.  */
+	    ^ ~longword)
+
+	   /* Look at only the hole bits.  If any of the hole bits
+	      are unchanged, most likely one of the bytes was a
+	      zero.  */
+	   & ~magic_bits) != 0)
+	{
+	  /* Which of the bytes was C?  If none of them were, it was
+	     a misfire; continue the search.  */
+
+	  const unsigned char *cp = (const unsigned char *) longword_ptr;
+
+#if LONG_MAX > 2147483647
+	  if (cp[7] == c)
+	    return (__ptr_t) &cp[7];
+	  if (cp[6] == c)
+	    return (__ptr_t) &cp[6];
+	  if (cp[5] == c)
+	    return (__ptr_t) &cp[5];
+	  if (cp[4] == c)
+	    return (__ptr_t) &cp[4];
+#endif
+	  if (cp[3] == c)
+	    return (__ptr_t) &cp[3];
+	  if (cp[2] == c)
+	    return (__ptr_t) &cp[2];
+	  if (cp[1] == c)
+	    return (__ptr_t) &cp[1];
+	  if (cp[0] == c)
+	    return (__ptr_t) cp;
+	}
+
+      n -= sizeof (longword);
+    }
+
+  char_ptr = (const unsigned char *) longword_ptr;
+
+  while (n-- > 0)
+    {
+      if (*--char_ptr == c)
+	return (__ptr_t) char_ptr;
+    }
+
+  return 0;
+}
+#ifdef weak_alias
+weak_alias (__memrchr, memrchr)
+#endif
diff --git a/libtdenetwork/libgpgme-copy/gpgme/mkstatus b/libtdenetwork/libgpgme-copy/gpgme/mkstatus
new file mode 100755
index 000000000..2c6420178
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/mkstatus
@@ -0,0 +1,52 @@
+#!/bin/sh
+# mkstatus - Extract error strings from rungpg.h
+#            and create a lookup table
+#	Copyright (C) 2000 Werner Koch (dd9jn)
+#       Copyright (C) 2001 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
+
+# resetting collate is important, so that the bsearch works properly
+LC_ALL=C
+LC_COLLATE=C
+export LC_ALL LC_COLLATE
+
+cat <<EOF
+/* Generated automatically by mkstatus */
+/* Do not edit! */
+
+struct status_table_s {
+    const char *name;
+    gpgme_status_code_t code;
+};
+
+static struct status_table_s status_table[] = 
+{
+EOF
+
+awk '
+/GPGME_STATUS_ENTER/      { okay = 1 }
+!okay                     { next }
+/}/                       { exit 0 }
+/GPGME_STATUS_[A-Za-z_]*/ { sub (/,/, "", $1); printf "  { \"%s\", %s },\n", substr($1,14), $1 }
+' | sort  
+
+cat <<EOF
+  {NULL, 0}
+};
+
+EOF
diff --git a/libtdenetwork/libgpgme-copy/gpgme/op-support.c b/libtdenetwork/libgpgme-copy/gpgme/op-support.c
new file mode 100644
index 000000000..87e47f42b
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/op-support.c
@@ -0,0 +1,280 @@
+/* op-support.c 
+   Copyright (C) 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <locale.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+gpgme_error_t
+_gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
+		       int size, void (*cleanup) (void *))
+{
+  struct ctx_op_data *data = ctx->op_data;
+  while (data && data->type != type)
+    data = data->next;
+  if (!data)
+    {
+      if (size < 0)
+	{
+	  *hook = NULL;
+	  return 0;
+	}
+
+      data = calloc (1, sizeof (struct ctx_op_data) + size);
+      if (!data)
+	return gpg_error_from_errno (errno);
+      data->next = ctx->op_data;
+      data->type = type;
+      data->cleanup = cleanup;
+      data->hook = (void *) (((char *) data) + sizeof (struct ctx_op_data));
+      ctx->op_data = data;
+    }
+  *hook = data->hook;
+  return 0;
+}
+
+
+/* type is: 0: asynchronous operation (use global or user event loop).
+            1: synchronous operation (always use private event loop).
+            2: asynchronous private operation (use private or user
+            event loop).  */
+gpgme_error_t
+_gpgme_op_reset (gpgme_ctx_t ctx, int type)
+{
+  gpgme_error_t err = 0;
+  struct gpgme_io_cbs io_cbs;
+
+  _gpgme_release_result (ctx);
+
+  if (ctx->engine)
+    {
+      /* Attempt to reset an existing engine.  */
+
+      err = _gpgme_engine_reset (ctx->engine);
+      if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+	{
+	  _gpgme_engine_release (ctx->engine);
+	  ctx->engine = NULL;
+	}
+    }
+
+  if (!ctx->engine)
+    {
+      gpgme_engine_info_t info;
+      info = ctx->engine_info;
+      while (info && info->protocol != ctx->protocol)
+	info = info->next;
+
+      if (!info)
+	return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+
+      /* Create an engine object.  */
+      err = _gpgme_engine_new (info, &ctx->engine);
+      if (err)
+	return err;
+    }
+
+  err = _gpgme_engine_set_locale (ctx->engine, LC_CTYPE, ctx->lc_ctype);
+#ifdef LC_MESSAGES
+  if (!err)
+    err = _gpgme_engine_set_locale (ctx->engine,
+				    LC_MESSAGES, ctx->lc_messages);
+#endif
+
+  if (err)
+    {
+      _gpgme_engine_release (ctx->engine);
+      ctx->engine = NULL;
+      return err;
+    }
+
+  if (type == 1 || (type == 2 && !ctx->io_cbs.add))
+    {
+      /* Use private event loop.  */
+      io_cbs.add = _gpgme_add_io_cb;
+      io_cbs.add_priv = ctx;
+      io_cbs.remove = _gpgme_remove_io_cb;
+      io_cbs.event = _gpgme_wait_private_event_cb;
+      io_cbs.event_priv = ctx;
+    }
+  else if (! ctx->io_cbs.add)
+    {
+      /* Use global event loop.  */
+      io_cbs.add = _gpgme_add_io_cb;
+      io_cbs.add_priv = ctx;
+      io_cbs.remove = _gpgme_remove_io_cb;
+      io_cbs.event = _gpgme_wait_global_event_cb;
+      io_cbs.event_priv = ctx;
+    }
+  else
+    {
+      /* Use user event loop.  */
+      io_cbs.add = _gpgme_wait_user_add_io_cb;
+      io_cbs.add_priv = ctx;
+      io_cbs.remove = _gpgme_wait_user_remove_io_cb;
+      io_cbs.event = _gpgme_wait_user_event_cb;
+      io_cbs.event_priv = ctx;
+    }
+  _gpgme_engine_set_io_cbs (ctx->engine, &io_cbs);
+  return err;
+}
+
+
+/* Parse the INV_RECP status line in ARGS and return the result in
+   KEY.  */
+gpgme_error_t
+_gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
+{
+  gpgme_invalid_key_t inv_key;
+  char *tail;
+  long int reason;
+
+  inv_key = malloc (sizeof (*inv_key));
+  if (!inv_key)
+    return gpg_error_from_errno (errno);
+  inv_key->next = NULL;
+  errno = 0;
+  reason = strtol (args, &tail, 0);
+  if (errno || args == tail || *tail != ' ')
+    {
+      /* The crypto backend does not behave.  */
+      free (inv_key);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+
+  switch (reason)
+    {
+    default:
+    case 0:
+      inv_key->reason = gpg_error (GPG_ERR_GENERAL);
+      break;
+
+    case 1:
+      inv_key->reason = gpg_error (GPG_ERR_NO_PUBKEY);
+      break;
+
+    case 2:
+      inv_key->reason = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
+      break;
+
+    case 3:
+      inv_key->reason = gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+      break;
+
+    case 4:
+      inv_key->reason = gpg_error (GPG_ERR_CERT_REVOKED);
+      break;
+
+    case 5:
+      inv_key->reason = gpg_error (GPG_ERR_CERT_EXPIRED);
+      break;
+
+    case 6:
+      inv_key->reason = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+      break;
+
+    case 7:
+      inv_key->reason = gpg_error (GPG_ERR_CRL_TOO_OLD);
+      break;
+
+    case 8:
+      inv_key->reason = gpg_error (GPG_ERR_NO_POLICY_MATCH);
+      break;
+
+    case 9:
+      inv_key->reason = gpg_error (GPG_ERR_NO_SECKEY);
+      break;
+
+    case 10:
+      inv_key->reason = gpg_error (GPG_ERR_PUBKEY_NOT_TRUSTED);
+      break;
+    }
+
+  while (*tail == ' ')
+    tail++;
+  if (*tail)
+    {
+      inv_key->fpr = strdup (tail);
+      if (!inv_key->fpr)
+	{
+	  int saved_errno = errno;
+	  free (inv_key);
+	  return gpg_error_from_errno (saved_errno);
+	}
+    }
+  else
+    inv_key->fpr = NULL;
+
+  *key = inv_key;
+  return 0;
+}
+
+
+/* Parse the PLAINTEXT status line in ARGS and return the result in
+   FILENAMEP.  */
+gpgme_error_t
+_gpgme_parse_plaintext (char *args, char **filenamep)
+{
+  char *tail;
+
+  while (*args == ' ')
+    args++;
+  if (*args == '\0')
+    return 0;
+
+  /* First argument is file type.  */
+  while (*args != ' ' && *args != '\0')
+    args++;
+  while (*args == ' ')
+    args++;
+  if (*args == '\0')
+    return 0;
+
+  /* Second argument is the timestamp.  */
+  while (*args != ' ' && *args != '\0')
+    args++;
+  while (*args == ' ')
+    args++;
+  if (*args == '\0')
+    return 0;
+
+  tail = args;
+  while (*tail != ' ' && *tail != '\0')
+    tail++;
+  *tail = '\0';
+  if (filenamep && *args != '\0')
+    {
+      char *filename = strdup (args);
+      if (!filename)
+	return gpg_error_from_errno (errno);
+
+      *filenamep = filename;
+    }
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/ops.h b/libtdenetwork/libgpgme-copy/gpgme/ops.h
new file mode 100644
index 000000000..fd857dd56
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/ops.h
@@ -0,0 +1,169 @@
+/* ops.h - Internal operation support.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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 OPS_H
+#define OPS_H
+
+#include "gpgme.h"
+#include "context.h"
+
+
+/* From gpgme.c.  */
+void _gpgme_release_result (gpgme_ctx_t ctx);
+
+
+/* From wait.c.  */
+gpgme_error_t _gpgme_wait_one (gpgme_ctx_t ctx);
+gpgme_error_t _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond);
+
+
+/* From data.c.  */
+gpgme_error_t _gpgme_data_inbound_handler (void *opaque, int fd);
+gpgme_error_t _gpgme_data_outbound_handler (void *opaque, int fd);
+
+
+/* From op-support.c.  */
+
+/* Find or create the op data object of type TYPE.  */
+gpgme_error_t _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type,
+				     void **hook, int size,
+				     void (*cleanup) (void *));
+
+/* Prepare a new operation on CTX.  */
+gpgme_error_t _gpgme_op_reset (gpgme_ctx_t ctx, int synchronous);
+
+/* Parse the INV_RECP status line in ARGS and return the result in
+   KEY.  */
+gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key);
+
+/* Parse the PLAINTEXT status line in ARGS and return the result in
+   FILENAMEP.  */
+gpgme_error_t _gpgme_parse_plaintext (char *args, char **filenamep);
+
+
+
+/* From verify.c.  */
+gpgme_error_t _gpgme_op_verify_init_result (gpgme_ctx_t ctx);
+gpgme_error_t _gpgme_verify_status_handler (void *priv,
+					    gpgme_status_code_t code,
+					    char *args);
+
+
+/* From decrypt.c.  */
+gpgme_error_t _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx);
+gpgme_error_t _gpgme_decrypt_status_handler (void *priv,
+					     gpgme_status_code_t code,
+					     char *args);
+
+
+/* From sign.c.  */
+
+/* Create an initial op data object for signing.  Needs to be called
+   once before calling _gpgme_sign_status_handler.  */
+gpgme_error_t _gpgme_op_sign_init_result (gpgme_ctx_t ctx);
+
+/* Process a status line for signing operations.  */
+gpgme_error_t _gpgme_sign_status_handler (void *priv,
+					  gpgme_status_code_t code,
+					  char *args);
+
+
+/* From encrypt.c.  */
+
+/* Create an initial op data object for encrypt.  Needs to be called
+   once before calling _gpgme_encrypt_status_handler.  */
+gpgme_error_t _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx);
+
+/* Process a status line for encryption operations.  */
+gpgme_error_t _gpgme_encrypt_status_handler (void *priv,
+					     gpgme_status_code_t code,
+					     char *args);
+
+
+/* From passphrase.c.  */
+gpgme_error_t _gpgme_passphrase_status_handler (void *priv,
+						gpgme_status_code_t code,
+						char *args);
+gpgme_error_t _gpgme_passphrase_command_handler (void *opaque,
+						 gpgme_status_code_t code,
+						 const char *key, int fd,
+						 int *processed);
+
+
+/* From progress.c.  */
+gpgme_error_t _gpgme_progress_status_handler (void *priv,
+					      gpgme_status_code_t code,
+					      char *args);
+
+
+/* From key.c.  */
+gpgme_error_t _gpgme_key_new (gpgme_key_t *r_key);
+gpgme_error_t _gpgme_key_add_subkey (gpgme_key_t key,
+				     gpgme_subkey_t *r_subkey);
+gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, char *src);
+gpgme_key_sig_t _gpgme_key_add_sig (gpgme_key_t key, char *src);
+
+
+/* From keylist.c.  */
+void _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type,
+				 void *type_data);
+
+
+/* From trust-item.c.  */
+
+/* Create a new trust item.  */
+gpgme_error_t _gpgme_trust_item_new (gpgme_trust_item_t *r_item);
+
+
+/* From trustlist.c.  */
+void _gpgme_op_trustlist_event_cb (void *data, gpgme_event_io_t type,
+				   void *type_data);
+
+
+/* From version.c.  */
+
+/* Return true if MY_VERSION is at least RETQ_VERSION, and false
+   otherwise.  */
+int _gpgme_compare_versions (const char *my_version,
+			     const char *req_version);
+char *_gpgme_get_program_version (const char *const path);
+
+
+/* From sig-notation.c.  */
+
+/* Create a new, empty signature notation data object.  */
+gpgme_error_t _gpgme_sig_notation_create (gpgme_sig_notation_t *notationp,
+					  const char *name, int name_len,
+					  const char *value, int value_len,
+					  gpgme_sig_notation_flags_t flags);
+
+/* Free the signature notation object and all associated resources.
+   The object must already be removed from any linked list as the next
+   pointer is ignored.  */
+void _gpgme_sig_notation_free (gpgme_sig_notation_t notation);
+
+/* Parse a notation or policy URL subpacket.  If the packet type is
+   not known, return no error but NULL in NOTATION.  */
+gpgme_error_t _gpgme_parse_notation (gpgme_sig_notation_t *notationp,
+				     int type, int pkflags, int len,
+				     char *data);
+
+#endif /* OPS_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/passphrase.c b/libtdenetwork/libgpgme-copy/gpgme/passphrase.c
new file mode 100644
index 000000000..a07cb8d4d
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/passphrase.c
@@ -0,0 +1,153 @@
+/* passphrase.c - Passphrase callback.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+
+
+typedef struct
+{
+  int no_passphrase;
+  char *uid_hint;
+  char *passphrase_info;
+  int bad_passphrase;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+
+  if (opd->passphrase_info)
+    free (opd->passphrase_info);
+  if (opd->uid_hint)
+    free (opd->uid_hint);
+}
+
+
+gpgme_error_t
+_gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
+				  char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_PASSPHRASE, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  switch (code)
+    {
+    case GPGME_STATUS_USERID_HINT:
+      if (opd->uid_hint)
+	free (opd->uid_hint);
+      if (!(opd->uid_hint = strdup (args)))
+      return gpg_error_from_errno (errno);
+      break;
+
+    case GPGME_STATUS_BAD_PASSPHRASE:
+      opd->bad_passphrase++;
+      opd->no_passphrase = 0;
+      break;
+
+    case GPGME_STATUS_GOOD_PASSPHRASE:
+      opd->bad_passphrase = 0;
+      opd->no_passphrase = 0;
+      break;
+
+    case GPGME_STATUS_NEED_PASSPHRASE:
+    case GPGME_STATUS_NEED_PASSPHRASE_SYM:
+    case GPGME_STATUS_NEED_PASSPHRASE_PIN:
+      if (opd->passphrase_info)
+	free (opd->passphrase_info);
+      opd->passphrase_info = strdup (args);
+      if (!opd->passphrase_info)
+	return gpg_error_from_errno (errno);
+      break;
+
+    case GPGME_STATUS_MISSING_PASSPHRASE:
+      opd->no_passphrase = 1;
+      break;
+
+    case GPGME_STATUS_EOF:
+      if (opd->no_passphrase || opd->bad_passphrase)
+	return gpg_error (GPG_ERR_BAD_PASSPHRASE);
+      break;
+
+    default:
+      /* Ignore all other codes.  */
+      break;
+    }
+  return 0;
+}
+
+
+gpgme_error_t
+_gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code,
+				   const char *key, int fd, int *processed)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  assert (ctx->passphrase_cb);
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_PASSPHRASE, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  if (code == GPGME_STATUS_GET_HIDDEN 
+      && (!strcmp (key, "passphrase.enter")
+          || !strcmp (key, "passphrase.pin.ask")))
+    {
+      if (processed)
+	*processed = 1;
+
+      err = ctx->passphrase_cb (ctx->passphrase_cb_value,
+				opd->uid_hint, opd->passphrase_info,
+				opd->bad_passphrase, fd);
+
+      /* Reset bad passphrase flag, in case it is correct now.  */
+      opd->bad_passphrase = 0;
+
+      return err;
+    }
+
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/posix-io.c b/libtdenetwork/libgpgme-copy/gpgme/posix-io.c
new file mode 100644
index 000000000..7f3b80e70
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/posix-io.c
@@ -0,0 +1,497 @@
+/* posix-io.c - Posix I/O functions
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2004, 2005 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 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.
+   
+   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
+   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 <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "util.h"
+#include "priv-io.h"
+#include "sema.h"
+#include "ath.h"
+#include "debug.h"
+
+
+void
+_gpgme_io_subsystem_init (void)
+{
+  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);
+    }
+}
+
+
+/* Write the printable version of FD to the buffer BUF of length
+   BUFLEN.  The printable version is the representation on the command
+   line that the child process expects.  */
+int
+_gpgme_io_fd2str (char *buf, int buflen, int fd)
+{
+  return snprintf (buf, buflen, "%d", fd);
+}
+
+
+static struct
+{
+  void (*handler) (int,void*);
+  void *value;
+} notify_table[256];
+
+int
+_gpgme_io_read (int fd, void *buffer, size_t count)
+{
+  int nread;
+  int saved_errno;
+
+  DEBUG2 ("fd %d: about to read %d bytes\n", fd, (int) count);
+  do
+    {
+      nread = _gpgme_ath_read (fd, buffer, count);
+    }
+  while (nread == -1 && errno == EINTR);
+  saved_errno = errno;
+  DEBUG2 ("fd %d: got %d bytes\n", fd, nread);
+  if (nread > 0)
+    _gpgme_debug (2, "fd %d: got `%.*s'\n", fd, nread, buffer);
+  errno = saved_errno;
+  return nread;
+}
+
+
+int
+_gpgme_io_write (int fd, const void *buffer, size_t count)
+{
+  int saved_errno;
+  int nwritten;
+
+  DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int) count);
+  _gpgme_debug (2, "fd %d: write `%.*s'\n", fd, (int) count, buffer);
+  do
+    {
+      nwritten = _gpgme_ath_write (fd, buffer, count);
+    }
+  while (nwritten == -1 && errno == EINTR);
+  saved_errno = errno;
+  DEBUG2 ("fd %d:          wrote %d bytes\n", fd, (int) nwritten);
+  errno = saved_errno;
+  return nwritten;
+}
+
+
+int
+_gpgme_io_pipe (int filedes[2], int inherit_idx)
+{
+  int saved_errno;
+  int err;
+
+  err = pipe (filedes);
+  if (err < 0)
+    return err;
+  /* FIXME: Should get the old flags first.  */
+  err = fcntl (filedes[1 - inherit_idx], F_SETFD, FD_CLOEXEC);
+  saved_errno = errno;
+  if (err < 0)
+    {
+      close (filedes[0]);
+      close (filedes[1]);
+    }
+  errno = saved_errno;
+  return err;
+}
+
+
+int
+_gpgme_io_close (int fd)
+{
+  if (fd == -1)
+    return -1;
+  /* First call the notify handler.  */
+  DEBUG1 ("closing fd %d", fd);
+  if (fd >= 0 && fd < (int) DIM (notify_table))
+    {
+      if (notify_table[fd].handler)
+	{
+	  notify_table[fd].handler (fd, notify_table[fd].value);
+	  notify_table[fd].handler = NULL;
+	  notify_table[fd].value = NULL;
+        }
+    }
+  /* Then do the close.  */    
+  return close (fd);
+}
+
+
+int
+_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value)
+{
+  assert (fd != -1);
+
+  if (fd < 0 || fd >= (int) DIM (notify_table))
+    return -1;
+  DEBUG1 ("set notification for fd %d", fd);
+  notify_table[fd].handler = handler;
+  notify_table[fd].value = value;
+  return 0;
+}
+
+
+int
+_gpgme_io_set_nonblocking (int fd)
+{
+  int flags;
+
+  flags = fcntl (fd, F_GETFL, 0);
+  if (flags == -1)
+    return -1;
+  flags |= O_NONBLOCK;
+  return fcntl (fd, F_SETFL, flags);
+}
+
+
+static int
+_gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal)
+{
+  int status;
+
+  *r_status = 0;
+  *r_signal = 0;
+  if (_gpgme_ath_waitpid (pid, &status, hang? 0 : WNOHANG) == pid)
+    {
+      if (WIFSIGNALED (status))
+	{
+	  *r_status = 4; /* Need some value here.  */
+	  *r_signal = WTERMSIG (status);
+	}
+      else if (WIFEXITED (status))
+	*r_status = WEXITSTATUS (status);
+      else
+	*r_status = 4; /* Oops.  */
+      return 1;
+    }
+  return 0;
+}
+
+
+/* Returns 0 on success, -1 on error.  */
+int
+_gpgme_io_spawn (const char *path, char **argv,
+		 struct spawn_fd_item_s *fd_child_list,
+		 struct spawn_fd_item_s *fd_parent_list)
+{
+  pid_t pid;
+  int i;
+  int status, signo;
+
+  pid = fork ();
+  if (pid == -1) 
+    return -1;
+
+  if (!pid)
+    {
+      /* Intermediate child to prevent zombie processes.  */
+      if ((pid = fork ()) == 0)
+	{
+	  /* Child.  */
+	  int duped_stdin = 0;
+	  int duped_stderr = 0;
+
+	  /* First close all fds which will not be duped.  */
+	  for (i=0; fd_child_list[i].fd != -1; i++)
+	    if (fd_child_list[i].dup_to == -1)
+	      close (fd_child_list[i].fd);
+
+	  /* And now dup and close the rest.  */
+	  for (i=0; fd_child_list[i].fd != -1; i++)
+	    {
+	      if (fd_child_list[i].dup_to != -1)
+		{
+		  if (dup2 (fd_child_list[i].fd,
+			    fd_child_list[i].dup_to) == -1)
+		    {
+		      DEBUG1 ("dup2 failed in child: %s\n", strerror (errno));
+		      _exit (8);
+		    }
+		  if (fd_child_list[i].dup_to == 0)
+		    duped_stdin=1;
+		  if (fd_child_list[i].dup_to == 2)
+		    duped_stderr=1;
+		  close (fd_child_list[i].fd);
+		}
+	    }
+	  
+	  if (!duped_stdin || !duped_stderr)
+	    {
+	      int fd = open ("/dev/null", O_RDWR);
+	      if (fd == -1)
+		{
+		  DEBUG1 ("can't open `/dev/null': %s\n", strerror (errno));
+		  _exit (8);
+		}
+	      /* Make sure that the process has a connected stdin.  */
+	      if (!duped_stdin)
+		{
+		  if (dup2 (fd, 0) == -1)
+		    {
+		      DEBUG1("dup2(/dev/null, 0) failed: %s\n",
+			     strerror (errno));
+		      _exit (8);
+		    }
+		}
+	      if (!duped_stderr)
+		if (dup2 (fd, 2) == -1)
+		  {
+		    DEBUG1 ("dup2(dev/null, 2) failed: %s\n",
+			    strerror (errno));
+		    _exit (8);
+		  }
+	      close (fd);
+	    }
+    
+	  execv ( path, argv );
+	  /* Hmm: in that case we could write a special status code to the
+	     status-pipe.  */
+	  DEBUG1 ("exec of `%s' failed\n", path);
+	  _exit (8);
+	} /* End child.  */
+      if (pid == -1)
+	_exit (1);
+      else
+	_exit (0);
+    }
+    
+  _gpgme_io_waitpid (pid, 1, &status, &signo);
+  if (status)
+    return -1;
+
+  /* .dup_to is not used in the parent list.  */
+  for (i = 0; fd_parent_list[i].fd != -1; i++)
+    _gpgme_io_close (fd_parent_list[i].fd);
+
+  return 0;
+}
+
+
+/*
+ * Select on the list of fds.
+ * Returns: -1 = error
+ *           0 = timeout or nothing to select
+ *          >0 = number of signaled fds
+ */
+int
+_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
+{
+  fd_set readfds;
+  fd_set writefds;
+  unsigned int i;
+  int any, max_fd, n, count;
+  struct timeval timeout = { 1, 0 }; /* Use a 1s timeout.  */
+  void *dbg_help = NULL;
+
+  FD_ZERO (&readfds);
+  FD_ZERO (&writefds);
+  max_fd = 0;
+  if (nonblock)
+    timeout.tv_sec = 0;
+
+  DEBUG_BEGIN (dbg_help, 3, "gpgme:select on [ ");
+  any = 0;
+  for (i = 0; i < nfds; i++)
+    {
+      if (fds[i].fd == -1) 
+	continue;
+      if (fds[i].frozen)
+	DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd);
+      else if (fds[i].for_read)
+	{
+	  assert (!FD_ISSET (fds[i].fd, &readfds));
+	  FD_SET (fds[i].fd, &readfds);
+	  if (fds[i].fd > max_fd)
+	    max_fd = fds[i].fd;
+	  DEBUG_ADD1 (dbg_help, "r%d ", fds[i].fd);
+	  any = 1;
+        }
+      else if (fds[i].for_write)
+	{
+	  assert (!FD_ISSET (fds[i].fd, &writefds));
+	  FD_SET (fds[i].fd, &writefds);
+	  if (fds[i].fd > max_fd)
+	    max_fd = fds[i].fd;
+	  DEBUG_ADD1 (dbg_help, "w%d ", fds[i].fd);
+	  any = 1;
+        }
+      fds[i].signaled = 0;
+    }
+  DEBUG_END (dbg_help, "]"); 
+  if (!any)
+    return 0;
+
+  do
+    {
+      count = _gpgme_ath_select (max_fd + 1, &readfds, &writefds, NULL,
+				 &timeout);
+    }
+  while (count < 0 && errno == EINTR);
+  if (count < 0)
+    {
+      int saved_errno = errno;
+      DEBUG1 ("_gpgme_io_select failed: %s\n", strerror (errno));
+      errno = saved_errno;
+      return -1; /* error */
+    }
+
+  DEBUG_BEGIN (dbg_help, 3, "select OK [ ");
+  if (DEBUG_ENABLED (dbg_help))
+    {
+      for (i = 0; i <= max_fd; i++)
+	{
+	  if (FD_ISSET (i, &readfds))
+	    DEBUG_ADD1 (dbg_help, "r%d ", i);
+	  if (FD_ISSET (i, &writefds))
+	    DEBUG_ADD1 (dbg_help, "w%d ", i);
+        }
+      DEBUG_END (dbg_help, "]");
+    }
+    
+  /* n is used to optimize it a little bit.  */
+  for (n = count, i = 0; i < nfds && n; i++)
+    {
+      if (fds[i].fd == -1)
+	;
+      else if (fds[i].for_read)
+	{
+	  if (FD_ISSET (fds[i].fd, &readfds))
+	    {
+	      fds[i].signaled = 1;
+	      n--;
+            }
+        }
+      else if (fds[i].for_write)
+	{
+	  if (FD_ISSET (fds[i].fd, &writefds))
+	    {
+	      fds[i].signaled = 1;
+	      n--;
+            }
+        }
+    }
+  return count;
+}
+
+
+int
+_gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags)
+{
+  int nread;
+  int saved_errno;
+  struct iovec *iov;
+
+  nread = 0;
+  iov = msg->msg_iov;
+  while (iov < msg->msg_iov + msg->msg_iovlen)
+    {
+      nread += iov->iov_len;
+      iov++;
+    }
+  
+  DEBUG2 ("fd %d: about to receive %d bytes\n",
+	  fd, (int) nread);
+  do
+    {
+      nread = _gpgme_ath_recvmsg (fd, msg, flags);
+    }
+  while (nread == -1 && errno == EINTR);
+  saved_errno = errno;
+  DEBUG2 ("fd %d: got %d bytes\n", fd, nread);
+  if (nread > 0)
+    {
+      int nr = nread;
+
+      iov = msg->msg_iov;
+      while (nr > 0)
+	{
+	  int len = nr > iov->iov_len ? iov->iov_len : nr;
+	  _gpgme_debug (2, "fd %d: got `%.*s'\n", fd, len,
+			msg->msg_iov->iov_base);
+	  iov++;
+	  nr -= len;
+	}
+    }
+  errno = saved_errno;
+  return nread;
+}
+
+
+int
+_gpgme_io_sendmsg (int fd, const struct msghdr *msg, int flags)
+{
+  int saved_errno;
+  int nwritten;
+  struct iovec *iov;
+
+  nwritten = 0;
+  iov = msg->msg_iov;
+  while (iov < msg->msg_iov + msg->msg_iovlen)
+    {
+      nwritten += iov->iov_len;
+      iov++;
+    }
+
+  DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int) nwritten);
+  iov = msg->msg_iov;
+  while (nwritten > 0)
+    {
+      int len = nwritten > iov->iov_len ? iov->iov_len : nwritten;
+      _gpgme_debug (2, "fd %d: write `%.*s'\n", fd, len,
+		    msg->msg_iov->iov_base);
+      iov++;
+      nwritten -= len;
+    }
+
+  do
+    {
+      nwritten = _gpgme_ath_sendmsg (fd, msg, flags);
+    }
+  while (nwritten == -1 && errno == EINTR);
+  saved_errno = errno;
+  DEBUG2 ("fd %d:          wrote %d bytes\n", fd, (int) nwritten);
+  errno = saved_errno;
+  return nwritten;
+}
+
+
diff --git a/libtdenetwork/libgpgme-copy/gpgme/posix-sema.c b/libtdenetwork/libgpgme-copy/gpgme/posix-sema.c
new file mode 100644
index 000000000..477f07872
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/posix-sema.c
@@ -0,0 +1,62 @@
+/* posix-sema.c 
+   Copyright (C) 2001 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2004 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 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.
+   
+   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
+   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 <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include "util.h"
+#include "sema.h"
+#include "ath.h"
+
+void
+_gpgme_sema_subsystem_init ()
+{
+}
+
+void
+_gpgme_sema_cs_enter (struct critsect_s *s)
+{
+  _gpgme_ath_mutex_lock (&s->private);
+}
+
+void
+_gpgme_sema_cs_leave (struct critsect_s *s)
+{
+  _gpgme_ath_mutex_unlock (&s->private);
+}
+
+void
+_gpgme_sema_cs_destroy (struct critsect_s *s)
+{
+  _gpgme_ath_mutex_destroy (&s->private);
+  s->private = NULL;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/posix-util.c b/libtdenetwork/libgpgme-copy/gpgme/posix-util.c
new file mode 100644
index 000000000..ecb597617
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/posix-util.c
@@ -0,0 +1,57 @@
+/* posix-util.c - Utility functions for Posix
+   Copyright (C) 2001 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2004 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 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.
+   
+   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
+   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 <assert.h>
+
+#include "util.h"
+
+const char *
+_gpgme_get_gpg_path (void)
+{
+#ifdef GPG_PATH
+  return GPG_PATH;
+#else
+  return NULL;
+#endif
+}
+
+const char *
+_gpgme_get_gpgsm_path (void)
+{
+#ifdef GPGSM_PATH
+  return GPGSM_PATH;
+#else
+  return NULL;
+#endif
+}
+
+/* See w32-util.c */
+int
+_gpgme_get_conf_int (const char *key, int *value)
+{
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/priv-io.h b/libtdenetwork/libgpgme-copy/gpgme/priv-io.h
new file mode 100644
index 000000000..9a908570f
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/priv-io.h
@@ -0,0 +1,67 @@
+/* priv-io.h - Interface to the private I/O functions.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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 IO_H
+#define IO_H
+
+
+/* A single file descriptor passed to spawn.  For child fds, dup_to
+   specifies the fd it should become in the child.  */
+struct spawn_fd_item_s
+{
+  int fd;
+  int dup_to;
+};
+
+struct io_select_fd_s
+{
+  int fd;
+  int for_read;
+  int for_write;
+  int signaled;
+  int frozen;
+  void *opaque;
+};
+
+/* These function are either defined in posix-io.c or w32-io.c.  */
+void _gpgme_io_subsystem_init (void);
+int _gpgme_io_read (int fd, void *buffer, size_t count);
+int _gpgme_io_write (int fd, const void *buffer, size_t count);
+int _gpgme_io_pipe (int filedes[2], int inherit_idx);
+int _gpgme_io_close (int fd);
+int _gpgme_io_set_close_notify (int fd, void (*handler) (int, void *),
+				void *value);
+int _gpgme_io_set_nonblocking (int fd);
+
+/* Spawn the executable PATH with ARGV as arguments, after forking
+   close all fds in FD_PARENT_LIST in the parent and close or dup all
+   fds in FD_CHILD_LIST in the child.  */
+int _gpgme_io_spawn (const char *path, char **argv,
+		     struct spawn_fd_item_s *fd_child_list,
+		     struct spawn_fd_item_s *fd_parent_list);
+int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);
+
+/* Write the printable version of FD to the buffer BUF of length
+   BUFLEN.  The printable version is the representation on the command
+   line that the child process expects.  */
+int _gpgme_io_fd2str (char *buf, int buflen, int fd);
+
+#endif /* IO_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/progress.c b/libtdenetwork/libgpgme-copy/gpgme/progress.c
new file mode 100644
index 000000000..cdc87eb8a
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/progress.c
@@ -0,0 +1,81 @@
+/* progress.c -  status handler for progress status
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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 <string.h>
+#include <errno.h>
+
+#include "util.h"
+#include "context.h"
+
+
+gpgme_error_t
+_gpgme_progress_status_handler (void *priv, gpgme_status_code_t code,
+				char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  char *p;
+  char *args_cpy;
+  int type = 0;
+  int current = 0;
+  int total = 0;
+
+  if (code != GPGME_STATUS_PROGRESS || !*args || !ctx->progress_cb)
+    return 0;
+
+  args_cpy = strdup (args);
+  if (!args_cpy)
+    return gpg_error_from_errno (errno);
+
+  p = strchr (args_cpy, ' ');
+  if (p)
+    {
+      *p++ = 0;
+      if (*p)
+	{
+	  type = *(unsigned char *)p;
+	  p = strchr (p+1, ' ');
+	  if (p)
+	    {
+	      *p++ = 0;
+	      if (*p)
+		{
+		  current = atoi (p);
+		  p = strchr (p+1, ' ');
+		  if (p)
+		    {
+		      *p++ = 0;
+		      total = atoi (p);
+		    }
+		}
+	    }
+	}
+    }           
+
+  if (type != 'X')
+    ctx->progress_cb (ctx->progress_cb_value, args_cpy, type, current, total);
+
+  free (args_cpy);
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/putc_unlocked.c b/libtdenetwork/libgpgme-copy/gpgme/putc_unlocked.c
new file mode 100644
index 000000000..a11d1ceab
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/putc_unlocked.c
@@ -0,0 +1,31 @@
+/* putc_unlocked.c - Replacement for putc_unlocked.
+   Copyright (C) 2004 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 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.
+   
+   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
+   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>
+
+int
+putc_unlocked (int c, FILE *stream)
+{
+  return putc (c, stream);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/rungpg.c b/libtdenetwork/libgpgme-copy/gpgme/rungpg.c
new file mode 100644
index 000000000..d09cdf3b6
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/rungpg.c
@@ -0,0 +1,2111 @@
+/* rungpg.c - Gpg Engine.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <locale.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "ops.h"
+#include "wait.h"
+#include "context.h"  /*temp hack until we have GpmeData methods to do I/O */
+#include "priv-io.h"
+#include "sema.h"
+#include "debug.h"
+
+#include "status-table.h"
+#include "engine-backend.h"
+
+
+/* This type is used to build a list of gpg arguments and data
+   sources/sinks.  */
+struct arg_and_data_s
+{
+  struct arg_and_data_s *next;
+  gpgme_data_t data;  /* If this is not NULL, use arg below.  */
+  int inbound;     /* True if this is used for reading from gpg.  */
+  int dup_to;
+  int print_fd;    /* Print the fd number and not the special form of it.  */
+  char arg[1];     /* Used if data above is not used.  */
+};
+
+
+struct fd_data_map_s
+{
+  gpgme_data_t data;
+  int inbound;  /* true if this is used for reading from gpg */
+  int dup_to;
+  int fd;       /* the fd to use */
+  int peer_fd;  /* the outher side of the pipe */
+  void *tag;
+};
+
+
+typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
+
+struct engine_gpg
+{
+  char *file_name;
+
+  char *lc_messages;
+  char *lc_ctype;
+
+  struct arg_and_data_s *arglist;
+  struct arg_and_data_s **argtail;
+
+  struct
+  {
+    int fd[2];  
+    size_t bufsize;
+    char *buffer;
+    size_t readpos;
+    int eof;
+    engine_status_handler_t fnc;
+    void *fnc_value;
+    void *tag;
+  } status;
+
+  /* This is a kludge - see the comment at colon_line_handler.  */
+  struct
+  {
+    int fd[2];  
+    size_t bufsize;
+    char *buffer;
+    size_t readpos;
+    int eof;
+    engine_colon_line_handler_t fnc;  /* this indicate use of this structrue */
+    void *fnc_value;
+    void *tag;
+    colon_preprocessor_t preprocess_fnc;
+  } colon;
+
+  char **argv;  
+  struct fd_data_map_s *fd_data_map;
+
+  /* stuff needed for interactive (command) mode */
+  struct
+  {
+    int used;
+    int fd;
+    void *cb_data;
+    int idx;		/* Index in fd_data_map */
+    gpgme_status_code_t code;  /* last code */
+    char *keyword;       /* what has been requested (malloced) */
+    engine_command_handler_t fnc; 
+    void *fnc_value;
+    /* The kludges never end.  This is used to couple command handlers
+       with output data in edit key mode.  */
+    gpgme_data_t linked_data;
+    int linked_idx;
+  } cmd;
+
+  struct gpgme_io_cbs io_cbs;
+};
+
+typedef struct engine_gpg *engine_gpg_t;
+
+
+static void
+gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data)
+{
+  engine_gpg_t gpg = engine;
+
+  if (gpg->io_cbs.event)
+    (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data);
+}
+
+
+static void
+close_notify_handler (int fd, void *opaque)
+{
+  engine_gpg_t gpg = opaque;
+  assert (fd != -1);
+
+  if (gpg->status.fd[0] == fd)
+    {
+      if (gpg->status.tag)
+	(*gpg->io_cbs.remove) (gpg->status.tag);
+      gpg->status.fd[0] = -1;
+    }
+  else if (gpg->status.fd[1] == fd)
+    gpg->status.fd[1] = -1;
+  else if (gpg->colon.fd[0] == fd)
+    {
+      if (gpg->colon.tag)
+	(*gpg->io_cbs.remove) (gpg->colon.tag);
+      gpg->colon.fd[0] = -1;
+    }
+  else if (gpg->colon.fd[1] == fd)
+    gpg->colon.fd[1] = -1;
+  else if (gpg->fd_data_map)
+    {
+      int i;
+
+      for (i = 0; gpg->fd_data_map[i].data; i++)
+	{
+	  if (gpg->fd_data_map[i].fd == fd)
+	    {
+	      if (gpg->fd_data_map[i].tag)
+		(*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag);
+	      gpg->fd_data_map[i].fd = -1;
+	      break;
+            }
+	  if (gpg->fd_data_map[i].peer_fd == fd)
+	    {
+	      gpg->fd_data_map[i].peer_fd = -1;
+	      break;
+            }
+        }
+    }
+}
+
+/* If FRONT is true, push at the front of the list.  Use this for
+   options added late in the process.  */
+static gpgme_error_t
+add_arg_ext (engine_gpg_t gpg, const char *arg, int front)
+{
+  struct arg_and_data_s *a;
+
+  assert (gpg);
+  assert (arg);
+
+  a = malloc (sizeof *a + strlen (arg));
+  if (!a)
+    return gpg_error_from_errno (errno);
+
+  a->data = NULL;
+  a->dup_to = -1;
+  strcpy (a->arg, arg);
+  if (front)
+    {
+      a->next = gpg->arglist;
+      if (!gpg->arglist)
+	{
+	  /* If this is the first argument, we need to update the tail
+	     pointer.  */
+	  gpg->argtail = &a->next;
+	}
+      gpg->arglist = a;
+    }
+  else
+    {
+      a->next = NULL;
+      *gpg->argtail = a;
+      gpg->argtail = &a->next;
+    }
+
+  return 0;
+}
+
+static gpgme_error_t
+add_arg (engine_gpg_t gpg, const char *arg)
+{
+  return add_arg_ext (gpg, arg, 0);
+}
+
+static gpgme_error_t
+add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
+{
+  struct arg_and_data_s *a;
+
+  assert (gpg);
+  assert (data);
+
+  a = malloc (sizeof *a - 1);
+  if (!a)
+    return gpg_error_from_errno (errno);
+  a->next = NULL;
+  a->data = data;
+  a->inbound = inbound;
+  if (dup_to == -2)
+    {
+      a->print_fd = 1;
+      a->dup_to = -1;
+    }
+  else
+    {
+      a->print_fd = 0;
+      a->dup_to = dup_to;
+    }
+  *gpg->argtail = a;
+  gpg->argtail = &a->next;
+  return 0;
+}
+
+
+static char *
+gpg_get_version (const char *file_name)
+{
+  return _gpgme_get_program_version (file_name ? file_name
+				     : _gpgme_get_gpg_path ());
+}
+
+
+static const char *
+gpg_get_req_version (void)
+{
+  return NEED_GPG_VERSION;
+}
+
+
+static void
+free_argv (char **argv)
+{
+  int i;
+
+  for (i = 0; argv[i]; i++)
+    free (argv[i]);
+  free (argv);
+}
+
+
+static void
+free_fd_data_map (struct fd_data_map_s *fd_data_map)
+{
+  int i;
+
+  if (!fd_data_map)
+    return;
+
+  for (i = 0; fd_data_map[i].data; i++)
+    {
+      if (fd_data_map[i].fd != -1)
+	_gpgme_io_close (fd_data_map[i].fd);
+      if (fd_data_map[i].peer_fd != -1)
+	_gpgme_io_close (fd_data_map[i].peer_fd);
+      /* Don't release data because this is only a reference.  */
+    }
+  free (fd_data_map);
+}
+
+
+static gpgme_error_t
+gpg_cancel (void *engine)
+{
+  engine_gpg_t gpg = engine;
+
+  if (!gpg)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (gpg->status.fd[0] != -1)
+    _gpgme_io_close (gpg->status.fd[0]);
+  if (gpg->status.fd[1] != -1)
+    _gpgme_io_close (gpg->status.fd[1]);
+  if (gpg->colon.fd[0] != -1)
+    _gpgme_io_close (gpg->colon.fd[0]);
+  if (gpg->colon.fd[1] != -1)
+    _gpgme_io_close (gpg->colon.fd[1]);
+  if (gpg->fd_data_map)
+    {
+      free_fd_data_map (gpg->fd_data_map);
+      gpg->fd_data_map = NULL;
+    }
+  if (gpg->cmd.fd != -1)
+    _gpgme_io_close (gpg->cmd.fd);
+
+  return 0;
+}
+
+static void
+gpg_release (void *engine)
+{
+  engine_gpg_t gpg = engine;
+
+  if (!gpg)
+    return;
+
+  gpg_cancel (engine);
+
+  if (gpg->file_name)
+    free (gpg->file_name);
+
+  if (gpg->lc_messages)
+    free (gpg->lc_messages);
+  if (gpg->lc_ctype)
+    free (gpg->lc_ctype);
+
+  while (gpg->arglist)
+    {
+      struct arg_and_data_s *next = gpg->arglist->next;
+
+      if (gpg->arglist)
+	free (gpg->arglist);
+      gpg->arglist = next;
+    }
+
+  if (gpg->status.buffer)
+    free (gpg->status.buffer);
+  if (gpg->colon.buffer)
+    free (gpg->colon.buffer);
+  if (gpg->argv)
+    free_argv (gpg->argv);
+  if (gpg->cmd.keyword)
+    free (gpg->cmd.keyword);
+
+  free (gpg);
+}
+
+
+static gpgme_error_t
+gpg_new (void **engine, const char *file_name, const char *home_dir)
+{
+  engine_gpg_t gpg;
+  gpgme_error_t rc = 0;
+  char *dft_display = NULL;
+  char dft_ttyname[64];
+  char *dft_ttytype = NULL;
+
+  gpg = calloc (1, sizeof *gpg);
+  if (!gpg)
+    return gpg_error_from_errno (errno);
+
+  if (file_name)
+    {
+      gpg->file_name = strdup (file_name);
+      if (!gpg->file_name)
+	{
+	  rc = gpg_error_from_errno (errno);
+	  goto leave;
+	}
+    }
+
+  gpg->argtail = &gpg->arglist;
+  gpg->status.fd[0] = -1;
+  gpg->status.fd[1] = -1;
+  gpg->colon.fd[0] = -1;
+  gpg->colon.fd[1] = -1;
+  gpg->cmd.fd = -1;
+  gpg->cmd.idx = -1;
+  gpg->cmd.linked_data = NULL;
+  gpg->cmd.linked_idx = -1;
+
+  /* Allocate the read buffer for the status pipe.  */
+  gpg->status.bufsize = 1024;
+  gpg->status.readpos = 0;
+  gpg->status.buffer = malloc (gpg->status.bufsize);
+  if (!gpg->status.buffer)
+    {
+      rc = gpg_error_from_errno (errno);
+      goto leave;
+    }
+  /* In any case we need a status pipe - create it right here and
+     don't handle it with our generic gpgme_data_t mechanism.  */
+  if (_gpgme_io_pipe (gpg->status.fd, 1) == -1)
+    {
+      rc = gpg_error_from_errno (errno);
+      goto leave;
+    }
+  if (_gpgme_io_set_close_notify (gpg->status.fd[0],
+				  close_notify_handler, gpg)
+      || _gpgme_io_set_close_notify (gpg->status.fd[1],
+				     close_notify_handler, gpg))
+    {
+      rc = gpg_error (GPG_ERR_GENERAL);
+      goto leave;
+    }
+  gpg->status.eof = 0;
+
+  if (home_dir)
+    {
+      rc = add_arg (gpg, "--homedir");
+      if (!rc)
+	rc = add_arg (gpg, home_dir);
+      if (rc)
+	goto leave;
+    }
+
+  rc = add_arg (gpg, "--status-fd");
+  if (rc)
+    goto leave;
+
+  {
+    char buf[25];
+    _gpgme_io_fd2str (buf, sizeof (buf), gpg->status.fd[1]);
+    rc = add_arg (gpg, buf);
+    if (rc)
+      goto leave;
+  }
+
+  rc = add_arg (gpg, "--no-tty");
+  if (!rc)
+    rc = add_arg (gpg, "--charset");
+  if (!rc)
+    rc = add_arg (gpg, "utf8");
+  if (!rc)
+    rc = add_arg (gpg, "--enable-progress-filter");
+  if (rc)
+    goto leave;
+
+  rc = _gpgme_getenv ("DISPLAY", &dft_display);
+  if (dft_display)
+    {
+      rc = add_arg (gpg, "--display");
+      if (!rc)
+	rc = add_arg (gpg, dft_display);
+
+      free (dft_display);
+    }
+  if (rc)
+    goto leave;
+
+  if (isatty (1))
+    {
+      if (ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)))
+	rc = gpg_error_from_errno (errno);
+      else
+	{
+	  rc = add_arg (gpg, "--ttyname");
+	  if (!rc)
+	    rc = add_arg (gpg, dft_ttyname);
+	  if (!rc)
+	    {
+	      rc = _gpgme_getenv ("TERM", &dft_ttytype);
+	      if (!rc)
+		goto leave;
+
+	      rc = add_arg (gpg, "--ttytype");
+	      if (!rc)
+		rc = add_arg (gpg, dft_ttytype);
+
+	      free (dft_ttytype);
+	    }
+	}
+      if (rc)
+	goto leave;
+    }
+
+ leave:
+  if (rc)
+    gpg_release (gpg);
+  else
+    *engine = gpg;
+  return rc;
+}
+
+
+static gpgme_error_t
+gpg_set_locale (void *engine, int category, const char *value)
+{
+  engine_gpg_t gpg = engine;
+
+  if (category == LC_CTYPE)
+    {
+      if (gpg->lc_ctype)
+        {
+          free (gpg->lc_ctype);
+          gpg->lc_ctype = NULL;
+        }
+      if (value)
+	{
+	  gpg->lc_ctype = strdup (value);
+	  if (!gpg->lc_ctype)
+	    return gpg_error_from_syserror ();
+	}
+    }
+#ifdef LC_MESSAGES
+  else if (category == LC_MESSAGES)
+    {
+      if (gpg->lc_messages)
+        {
+          free (gpg->lc_messages);
+          gpg->lc_messages = NULL;
+        }
+      if (value)
+	{
+	  gpg->lc_messages = strdup (value);
+	  if (!gpg->lc_messages)
+	    return gpg_error_from_syserror ();
+	}
+    }
+#endif /* LC_MESSAGES */
+  else
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  return 0;
+}
+
+
+/* Note, that the status_handler is allowed to modifiy the args
+   value.  */
+static void
+gpg_set_status_handler (void *engine, engine_status_handler_t fnc,
+			void *fnc_value)
+{
+  engine_gpg_t gpg = engine;
+
+  gpg->status.fnc = fnc;
+  gpg->status.fnc_value = fnc_value;
+}
+
+/* Kludge to process --with-colon output.  */
+static gpgme_error_t
+gpg_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc,
+			    void *fnc_value)
+{
+  engine_gpg_t gpg = engine;
+
+  gpg->colon.bufsize = 1024;
+  gpg->colon.readpos = 0;
+  gpg->colon.buffer = malloc (gpg->colon.bufsize);
+  if (!gpg->colon.buffer)
+    return gpg_error_from_errno (errno);
+
+  if (_gpgme_io_pipe (gpg->colon.fd, 1) == -1) 
+    {
+      int saved_errno = errno;
+      free (gpg->colon.buffer);
+      gpg->colon.buffer = NULL;
+      return gpg_error_from_errno (saved_errno);
+    }
+  if (_gpgme_io_set_close_notify (gpg->colon.fd[0], close_notify_handler, gpg)
+      || _gpgme_io_set_close_notify (gpg->colon.fd[1],
+				     close_notify_handler, gpg))
+    return gpg_error (GPG_ERR_GENERAL);
+  gpg->colon.eof = 0;
+  gpg->colon.fnc = fnc;
+  gpg->colon.fnc_value = fnc_value;
+  return 0;
+}
+
+
+static gpgme_error_t
+command_handler (void *opaque, int fd)
+{
+  gpgme_error_t err;
+  engine_gpg_t gpg = (engine_gpg_t) opaque;
+  int processed = 0;
+
+  assert (gpg->cmd.used);
+  assert (gpg->cmd.code);
+  assert (gpg->cmd.fnc);
+
+  err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd,
+		      &processed);
+  if (err)
+    return err;
+
+  /* We always need to send at least a newline character.  */
+  if (!processed)
+    _gpgme_io_write (fd, "\n", 1);
+
+  gpg->cmd.code = 0;
+  /* And sleep again until read_status will wake us up again.  */
+  /* XXX We must check if there are any more fds active after removing
+     this one.  */
+  (*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag);
+  gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
+  gpg->fd_data_map[gpg->cmd.idx].fd = -1;
+
+  return 0;
+}
+
+
+
+/* The Fnc will be called to get a value for one of the commands with
+   a key KEY.  If the Code pssed to FNC is 0, the function may release
+   resources associated with the returned value from another call.  To
+   match such a second call to a first call, the returned value from
+   the first call is passed as keyword.  */
+static gpgme_error_t
+gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
+			 void *fnc_value, gpgme_data_t linked_data)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t rc;
+
+  rc = add_arg (gpg, "--command-fd");
+  if (rc)
+    return rc;
+
+  /* This is a hack.  We don't have a real data object.  The only
+     thing that matters is that we use something unique, so we use the
+     address of the cmd structure in the gpg object.  */
+  rc = add_data (gpg, (void *) &gpg->cmd, -2, 0);
+  if (rc)
+    return rc;
+
+  gpg->cmd.fnc = fnc;
+  gpg->cmd.cb_data = (void *) &gpg->cmd;
+  gpg->cmd.fnc_value = fnc_value;
+  gpg->cmd.linked_data = linked_data;
+  gpg->cmd.used = 1;
+  return 0;
+}
+
+
+static gpgme_error_t
+build_argv (engine_gpg_t gpg)
+{
+  gpgme_error_t err;
+  struct arg_and_data_s *a;
+  struct fd_data_map_s *fd_data_map;
+  size_t datac=0, argc=0;  
+  char **argv;
+  int need_special = 0;
+  int use_agent = 0;
+  char *p;
+
+  /* We don't want to use the agent with a malformed environment
+     variable.  This is only a very basic test but sufficient to make
+     our life in the regression tests easier. */
+  err = _gpgme_getenv ("GPG_AGENT_INFO", &p);
+  if (err)
+    return err;
+  use_agent = (p && strchr (p, ':'));
+  if (p)
+    free (p);
+
+  if (gpg->argv)
+    {
+      free_argv (gpg->argv);
+      gpg->argv = NULL;
+    }
+  if (gpg->fd_data_map)
+    {
+      free_fd_data_map (gpg->fd_data_map);
+      gpg->fd_data_map = NULL;
+    }
+
+  argc++;	/* For argv[0].  */
+  for (a = gpg->arglist; a; a = a->next)
+    {
+      argc++;
+      if (a->data)
+	{
+	  /*fprintf (stderr, "build_argv: data\n" );*/
+	  datac++;
+	  if (a->dup_to == -1 && !a->print_fd)
+	    need_special = 1;
+        }
+      else
+	{
+	  /*   fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/
+        }
+    }
+  if (need_special)
+    argc++;
+  if (use_agent)
+    argc++;
+  if (!gpg->cmd.used)
+    argc++;	/* --batch */
+  argc += 1;	/* --no-sk-comment */
+
+  argv = calloc (argc + 1, sizeof *argv);
+  if (!argv)
+    return gpg_error_from_errno (errno);
+  fd_data_map = calloc (datac + 1, sizeof *fd_data_map);
+  if (!fd_data_map)
+    {
+      int saved_errno = errno;
+      free_argv (argv);
+      return gpg_error_from_errno (saved_errno);
+    }
+
+  argc = datac = 0;
+  argv[argc] = strdup ("gpg"); /* argv[0] */
+  if (!argv[argc])
+    {
+      int saved_errno = errno;
+      free (fd_data_map);
+      free_argv (argv);
+      return gpg_error_from_errno (saved_errno);
+    }
+  argc++;
+  if (need_special)
+    {
+      argv[argc] = strdup ("--enable-special-filenames");
+      if (!argv[argc])
+	{
+	  int saved_errno = errno;
+	  free (fd_data_map);
+	  free_argv (argv);
+	  return gpg_error_from_errno (saved_errno);
+        }
+      argc++;
+    }
+  if (use_agent)
+    {
+      argv[argc] = strdup ("--use-agent");
+      if (!argv[argc])
+	{
+	  int saved_errno = errno;
+	  free (fd_data_map);
+	  free_argv (argv);
+	  return gpg_error_from_errno (saved_errno);
+        }
+      argc++;
+    }
+  if (!gpg->cmd.used)
+    {
+      argv[argc] = strdup ("--batch");
+      if (!argv[argc])
+	{
+	  int saved_errno = errno;
+	  free (fd_data_map);
+	  free_argv (argv);
+	  return gpg_error_from_errno (saved_errno);
+        }
+      argc++;
+    }
+  argv[argc] = strdup ("--no-sk-comment");
+  if (!argv[argc])
+    {
+      int saved_errno = errno;
+      free (fd_data_map);
+      free_argv (argv);
+      return gpg_error_from_errno (saved_errno);
+    }
+  argc++;
+  for (a = gpg->arglist; a; a = a->next)
+    {
+      if (a->data)
+	{
+	  /* Create a pipe to pass it down to gpg.  */
+	  fd_data_map[datac].inbound = a->inbound;
+
+	  /* Create a pipe.  */
+	  {   
+	    int fds[2];
+	    
+	    if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0)
+		== -1)
+	      {
+		int saved_errno = errno;
+		free (fd_data_map);
+		free_argv (argv);
+		return gpg_error (saved_errno);
+	      }
+	    if (_gpgme_io_set_close_notify (fds[0],
+					    close_notify_handler, gpg)
+		|| _gpgme_io_set_close_notify (fds[1],
+					       close_notify_handler,
+					       gpg))
+	      {
+		return gpg_error (GPG_ERR_GENERAL);
+	      }
+	    /* If the data_type is FD, we have to do a dup2 here.  */
+	    if (fd_data_map[datac].inbound)
+	      {
+		fd_data_map[datac].fd       = fds[0];
+		fd_data_map[datac].peer_fd  = fds[1];
+	      }
+	    else
+	      {
+		fd_data_map[datac].fd       = fds[1];
+		fd_data_map[datac].peer_fd  = fds[0];
+	      }
+	  }
+
+	  /* Hack to get hands on the fd later.  */
+	  if (gpg->cmd.used)
+	    {
+	      if (gpg->cmd.cb_data == a->data)
+		{
+		  assert (gpg->cmd.idx == -1);
+		  gpg->cmd.idx = datac;
+		}
+	      else if (gpg->cmd.linked_data == a->data)
+		{
+		  assert (gpg->cmd.linked_idx == -1);
+		  gpg->cmd.linked_idx = datac;
+		}
+	    }
+
+	  fd_data_map[datac].data = a->data;
+	  fd_data_map[datac].dup_to = a->dup_to;
+	  if (a->dup_to == -1)
+	    {
+	      char *ptr;
+	      int buflen = 25;
+
+	      argv[argc] = malloc (buflen);
+	      if (!argv[argc])
+		{
+		  int saved_errno = errno;
+		  free (fd_data_map);
+		  free_argv (argv);
+		  return gpg_error_from_errno (saved_errno);
+                }
+
+	      ptr = argv[argc];
+	      if (!a->print_fd)
+		{
+		  *(ptr++) = '-';
+		  *(ptr++) = '&';
+		  buflen -= 2;
+		}
+	      
+	      _gpgme_io_fd2str (ptr, buflen, fd_data_map[datac].peer_fd);
+	      argc++;
+            }
+	  datac++;
+        }
+      else
+	{
+	  argv[argc] = strdup (a->arg);
+	  if (!argv[argc])
+	    {
+	      int saved_errno = errno;
+	      free (fd_data_map);
+	      free_argv (argv);
+	      return gpg_error_from_errno (saved_errno);
+            }
+            argc++;
+        }
+    }
+
+  gpg->argv = argv;
+  gpg->fd_data_map = fd_data_map;
+  return 0;
+}
+
+
+static gpgme_error_t
+add_io_cb (engine_gpg_t gpg, int fd, int dir, gpgme_io_cb_t handler, void *data,
+	   void **tag)
+{
+  gpgme_error_t err;
+
+  err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag);
+  if (err)
+    return err;
+  if (!dir)
+    /* FIXME Kludge around poll() problem.  */
+    err = _gpgme_io_set_nonblocking (fd);
+  return err;
+}
+
+
+static int
+status_cmp (const void *ap, const void *bp)
+{
+  const struct status_table_s *a = ap;
+  const struct status_table_s *b = bp;
+
+  return strcmp (a->name, b->name);
+}
+
+
+/* Handle the status output of GnuPG.  This function does read entire
+   lines and passes them as C strings to the callback function (we can
+   use C Strings because the status output is always UTF-8 encoded).
+   Of course we have to buffer the lines to cope with long lines
+   e.g. with a large user ID.  Note: We can optimize this to only cope
+   with status line code we know about and skip all other stuff
+   without buffering (i.e. without extending the buffer).  */
+static gpgme_error_t
+read_status (engine_gpg_t gpg)
+{
+  char *p;
+  int nread;
+  size_t bufsize = gpg->status.bufsize; 
+  char *buffer = gpg->status.buffer;
+  size_t readpos = gpg->status.readpos; 
+
+  assert (buffer);
+  if (bufsize - readpos < 256)
+    { 
+      /* Need more room for the read.  */
+      bufsize += 1024;
+      buffer = realloc (buffer, bufsize);
+      if (!buffer)
+	return gpg_error_from_errno (errno);
+    }
+
+  nread = _gpgme_io_read (gpg->status.fd[0],
+			  buffer + readpos, bufsize-readpos);
+  if (nread == -1)
+    return gpg_error_from_errno (errno);
+
+  if (!nread)
+    {
+      gpg->status.eof = 1;
+      if (gpg->status.fnc)
+	{
+	  gpgme_error_t err;
+	  err = gpg->status.fnc (gpg->status.fnc_value, GPGME_STATUS_EOF, "");
+	  if (err)
+	    return err;
+	}
+      return 0;
+    }
+
+  while (nread > 0)
+    {
+      for (p = buffer + readpos; nread; nread--, p++)
+	{
+	  if (*p == '\n')
+	    {
+	      /* (we require that the last line is terminated by a LF) */
+	      if (p > buffer && p[-1] == '\r')
+		p[-1] = 0;
+	      *p = 0;
+	      if (!strncmp (buffer, "[GNUPG:] ", 9)
+		  && buffer[9] >= 'A' && buffer[9] <= 'Z')
+		{
+		  struct status_table_s t, *r;
+		  char *rest;
+
+		  rest = strchr (buffer + 9, ' ');
+		  if (!rest)
+		    rest = p; /* Set to an empty string.  */
+		  else
+		    *rest++ = 0;
+                    
+		  t.name = buffer+9;
+		  /* (the status table has one extra element) */
+		  r = bsearch (&t, status_table, DIM(status_table) - 1,
+			       sizeof t, status_cmp);
+		  if (r)
+		    {
+		      if (gpg->cmd.used
+			  && (r->code == GPGME_STATUS_GET_BOOL
+			      || r->code == GPGME_STATUS_GET_LINE
+			      || r->code == GPGME_STATUS_GET_HIDDEN))
+			{
+			  gpg->cmd.code = r->code;
+			  if (gpg->cmd.keyword)
+			    free (gpg->cmd.keyword);
+			  gpg->cmd.keyword = strdup (rest);
+			  if (!gpg->cmd.keyword)
+			    return gpg_error_from_errno (errno);
+			  /* This should be the last thing we have
+			     received and the next thing will be that
+			     the command handler does its action.  */
+			  if (nread > 1)
+			    DEBUG0 ("ERROR, unexpected data in read_status");
+
+			  add_io_cb (gpg, gpg->cmd.fd, 0,
+				     command_handler, gpg,
+				     &gpg->fd_data_map[gpg->cmd.idx].tag);
+			  gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
+			  gpg->cmd.fd = -1;
+                        }
+		      else if (gpg->status.fnc)
+			{
+			  gpgme_error_t err;
+			  err = gpg->status.fnc (gpg->status.fnc_value, 
+						 r->code, rest);
+			  if (err)
+			    return err;
+                        }
+                    
+		      if (r->code == GPGME_STATUS_END_STREAM)
+			{
+			  if (gpg->cmd.used)
+			    {
+			      /* Before we can actually add the
+				 command fd, we might have to flush
+				 the linked output data pipe.  */
+			      if (gpg->cmd.linked_idx != -1
+				  && gpg->fd_data_map[gpg->cmd.linked_idx].fd
+				  != -1)
+				{
+				  struct io_select_fd_s fds;
+				  fds.fd =
+				    gpg->fd_data_map[gpg->cmd.linked_idx].fd;
+				  fds.for_read = 1;
+				  fds.for_write = 0;
+				  fds.frozen = 0;
+				  fds.opaque = NULL;
+				  do
+				    {
+				      fds.signaled = 0;
+				      _gpgme_io_select (&fds, 1, 1);
+				      if (fds.signaled)
+					_gpgme_data_inbound_handler
+					  (gpg->cmd.linked_data, fds.fd);
+				    }
+				  while (fds.signaled);
+				}
+
+			      /* XXX We must check if there are any
+				 more fds active after removing this
+				 one.  */
+			      (*gpg->io_cbs.remove)
+				(gpg->fd_data_map[gpg->cmd.idx].tag);
+			      gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
+			      gpg->fd_data_map[gpg->cmd.idx].fd = -1;
+			    }
+                        }
+                    }
+                }
+	      /* To reuse the buffer for the next line we have to
+		 shift the remaining data to the buffer start and
+		 restart the loop Hmmm: We can optimize this function
+		 by looking forward in the buffer to see whether a
+		 second complete line is available and in this case
+		 avoid the memmove for this line.  */
+	      nread--; p++;
+	      if (nread)
+		memmove (buffer, p, nread);
+	      readpos = 0;
+	      break; /* the for loop */
+            }
+	  else
+	    readpos++;
+        }
+    } 
+
+  /* Update the gpg object.  */
+  gpg->status.bufsize = bufsize;
+  gpg->status.buffer = buffer;
+  gpg->status.readpos = readpos;
+  return 0;
+}
+
+
+static gpgme_error_t
+status_handler (void *opaque, int fd)
+{
+  engine_gpg_t gpg = opaque;
+  int err;
+
+  assert (fd == gpg->status.fd[0]);
+  err = read_status (gpg);
+  if (err)
+    return err;
+  if (gpg->status.eof)
+    _gpgme_io_close (fd);
+  return 0;
+}
+
+
+static gpgme_error_t
+read_colon_line (engine_gpg_t gpg)
+{
+  char *p;
+  int nread;
+  size_t bufsize = gpg->colon.bufsize; 
+  char *buffer = gpg->colon.buffer;
+  size_t readpos = gpg->colon.readpos; 
+
+  assert (buffer);
+  if (bufsize - readpos < 256)
+    { 
+      /* Need more room for the read.  */
+      bufsize += 1024;
+      buffer = realloc (buffer, bufsize);
+      if (!buffer) 
+	return gpg_error_from_errno (errno);
+    }
+
+  nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos);
+  if (nread == -1)
+    return gpg_error_from_errno (errno);
+
+  if (!nread)
+    {
+      gpg->colon.eof = 1;
+      assert (gpg->colon.fnc);
+      gpg->colon.fnc (gpg->colon.fnc_value, NULL);
+      return 0;
+    }
+
+  while (nread > 0)
+    {
+      for (p = buffer + readpos; nread; nread--, p++)
+	{
+	  if ( *p == '\n' )
+	    {
+	      /* (we require that the last line is terminated by a LF)
+		 and we skip empty lines.  Note: we use UTF8 encoding
+		 and escaping of special characters.  We require at
+		 least one colon to cope with some other printed
+		 information.  */
+	      *p = 0;
+	      if (*buffer && strchr (buffer, ':'))
+		{
+		  char *line = NULL;
+
+		  if (gpg->colon.preprocess_fnc)
+		    {
+		      gpgme_error_t err;
+
+		      err = gpg->colon.preprocess_fnc (buffer, &line);
+		      if (err)
+			return err;
+		    }
+
+		  assert (gpg->colon.fnc);
+		  gpg->colon.fnc (gpg->colon.fnc_value, line ? line : buffer);
+		  if (line)
+		    free (line);
+		}
+            
+	      /* To reuse the buffer for the next line we have to
+		 shift the remaining data to the buffer start and
+		 restart the loop Hmmm: We can optimize this function
+		 by looking forward in the buffer to see whether a
+		 second complete line is available and in this case
+		 avoid the memmove for this line.  */
+	      nread--; p++;
+	      if (nread)
+		memmove (buffer, p, nread);
+	      readpos = 0;
+	      break; /* The for loop.  */
+            }
+	  else
+	    readpos++;
+        }
+    } 
+
+  /* Update the gpg object.  */
+  gpg->colon.bufsize = bufsize;
+  gpg->colon.buffer  = buffer;
+  gpg->colon.readpos = readpos;
+  return 0;
+}
+
+
+/* This colonline handler thing is not the clean way to do it.  It
+   might be better to enhance the gpgme_data_t object to act as a wrapper
+   for a callback.  Same goes for the status thing.  For now we use
+   this thing here because it is easier to implement.  */
+static gpgme_error_t
+colon_line_handler (void *opaque, int fd)
+{
+  engine_gpg_t gpg = opaque;
+  gpgme_error_t rc = 0;
+
+  assert (fd == gpg->colon.fd[0]);
+  rc = read_colon_line (gpg);
+  if (rc)
+    return rc;
+  if (gpg->colon.eof)
+    _gpgme_io_close (fd);
+  return 0;
+}
+
+
+static gpgme_error_t
+start (engine_gpg_t gpg)
+{
+  gpgme_error_t rc;
+  int saved_errno;
+  int i, n;
+  int status;
+  struct spawn_fd_item_s *fd_child_list, *fd_parent_list;
+
+  if (!gpg)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!gpg->file_name && !_gpgme_get_gpg_path ())
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  if (gpg->lc_ctype)
+    {
+      rc = add_arg_ext (gpg, gpg->lc_ctype, 1);
+      if (!rc)
+	rc = add_arg_ext (gpg, "--lc-ctype", 1);
+      if (rc)
+	return rc;
+    }
+
+  if (gpg->lc_messages)
+    {
+      rc = add_arg_ext (gpg, gpg->lc_messages, 1);
+      if (!rc)
+	rc = add_arg_ext (gpg, "--lc-messages", 1);
+      if (rc)
+	return rc;
+    }
+
+  rc = build_argv (gpg);
+  if (rc)
+    return rc;
+
+  n = 3; /* status_fd, colon_fd and end of list */
+  for (i = 0; gpg->fd_data_map[i].data; i++) 
+    n++;
+  fd_child_list = calloc (n + n, sizeof *fd_child_list);
+  if (!fd_child_list)
+    return gpg_error_from_errno (errno);
+  fd_parent_list = fd_child_list + n;
+
+  /* build the fd list for the child */
+  n = 0;
+  if (gpg->colon.fnc)
+    {
+      fd_child_list[n].fd = gpg->colon.fd[1]; 
+      fd_child_list[n].dup_to = 1; /* dup to stdout */
+      n++;
+    }
+  for (i = 0; gpg->fd_data_map[i].data; i++)
+    {
+      if (gpg->fd_data_map[i].dup_to != -1)
+	{
+	  fd_child_list[n].fd = gpg->fd_data_map[i].peer_fd;
+	  fd_child_list[n].dup_to = gpg->fd_data_map[i].dup_to;
+	  n++;
+        }
+    }
+  fd_child_list[n].fd = -1;
+  fd_child_list[n].dup_to = -1;
+
+  /* Build the fd list for the parent.  */
+  n = 0;
+  if (gpg->status.fd[1] != -1)
+    {
+      fd_parent_list[n].fd = gpg->status.fd[1];
+      fd_parent_list[n].dup_to = -1;
+      n++;
+    }
+  if (gpg->colon.fd[1] != -1)
+    {
+      fd_parent_list[n].fd = gpg->colon.fd[1];
+      fd_parent_list[n].dup_to = -1;
+      n++;
+    }
+  for (i = 0; gpg->fd_data_map[i].data; i++)
+    {
+      fd_parent_list[n].fd = gpg->fd_data_map[i].peer_fd;
+      fd_parent_list[n].dup_to = -1;
+      n++;
+    }        
+  fd_parent_list[n].fd = -1;
+  fd_parent_list[n].dup_to = -1;
+
+  status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
+			    _gpgme_get_gpg_path (),
+			    gpg->argv, fd_child_list, fd_parent_list);
+  saved_errno = errno;
+  free (fd_child_list);
+  if (status == -1)
+    return gpg_error_from_errno (saved_errno);
+
+  /*_gpgme_register_term_handler ( closure, closure_value, pid );*/
+
+  rc = add_io_cb (gpg, gpg->status.fd[0], 1, status_handler, gpg,
+		  &gpg->status.tag);
+  if (rc)
+    /* FIXME: kill the child */
+    return rc;
+
+  if (gpg->colon.fnc)
+    {
+      assert (gpg->colon.fd[0] != -1);
+      rc = add_io_cb (gpg, gpg->colon.fd[0], 1, colon_line_handler, gpg,
+		      &gpg->colon.tag);
+      if (rc)
+	/* FIXME: kill the child */
+	return rc;
+    }
+
+  for (i = 0; gpg->fd_data_map[i].data; i++)
+    {
+      if (gpg->cmd.used && i == gpg->cmd.idx)
+	{
+	  /* Park the cmd fd.  */
+	  gpg->cmd.fd = gpg->fd_data_map[i].fd;
+	  gpg->fd_data_map[i].fd = -1;
+	}
+      else
+	{
+	  rc = add_io_cb (gpg, gpg->fd_data_map[i].fd,
+			  gpg->fd_data_map[i].inbound,
+			  gpg->fd_data_map[i].inbound
+			  ? _gpgme_data_inbound_handler
+			  : _gpgme_data_outbound_handler,
+			  gpg->fd_data_map[i].data, &gpg->fd_data_map[i].tag);
+	  
+	  if (rc)
+	    /* FIXME: kill the child */
+	    return rc;
+	}
+    }
+
+  (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, GPGME_EVENT_START, NULL);
+  
+  /* fixme: check what data we can release here */
+  return 0;
+}
+
+
+static gpgme_error_t
+gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  err = add_arg (gpg, "--decrypt");
+
+  /* Tell the gpg object about the data.  */
+  if (!err)
+    err = add_arg (gpg, "--output");
+  if (!err)
+    err = add_arg (gpg, "-");
+  if (!err)
+    err = add_data (gpg, plain, 1, 1);
+  if (!err)
+    err = add_data (gpg, ciph, 0, 0);
+
+  if (!err)
+    start (gpg);
+  return err;
+}
+
+static gpgme_error_t
+gpg_delete (void *engine, gpgme_key_t key, int allow_secret)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key"
+		 : "--delete-key");
+  if (!err)
+    err = add_arg (gpg, "--");
+  if (!err)
+    {
+      if (!key->subkeys || !key->subkeys->fpr)
+	return gpg_error (GPG_ERR_INV_VALUE);
+      else
+	err = add_arg (gpg, key->subkeys->fpr);
+    }
+
+  if (!err)
+    start (gpg);
+  return err;
+}
+
+
+static gpgme_error_t
+append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
+{
+  gpgme_error_t err = 0;
+  int i;
+  gpgme_key_t key;
+
+  for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
+    {
+      const char *s = key->subkeys ? key->subkeys->keyid : NULL;
+      if (s)
+	{
+	  if (!err)
+	    err = add_arg (gpg, "-u");
+	  if (!err)
+	    err = add_arg (gpg, s);
+	}
+      gpgme_key_unref (key);
+      if (err) break;
+    }
+  return err;
+}
+
+
+static gpgme_error_t
+append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
+{
+  gpgme_error_t err = 0;
+  gpgme_sig_notation_t notation;
+
+  notation = gpgme_sig_notation_get (ctx);
+
+  while (!err && notation)
+    {
+      if (notation->name
+	  && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
+	err = gpg_error (GPG_ERR_INV_VALUE);
+      else if (notation->name)
+	{
+	  char *arg;
+
+	  /* Maximum space needed is one byte for the "critical" flag,
+	     the name, one byte for '=', the value, and a terminating
+	     '\0'.  */
+
+	  arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1);
+	  if (!arg)
+	    err = gpg_error_from_errno (errno);
+
+	  if (!err)
+	    {
+	      char *argp = arg;
+
+	      if (notation->critical)
+		*(argp++) = '!';
+
+	      memcpy (argp, notation->name, notation->name_len);
+	      argp += notation->name_len;
+
+	      *(argp++) = '=';
+
+	      /* We know that notation->name is '\0' terminated.  */
+	      strcpy (argp, notation->value);
+	    }
+
+	  if (!err)
+	    err = add_arg (gpg, "--sig-notation");
+	  if (!err)
+	    err = add_arg (gpg, arg);
+
+	  if (arg)
+	    free (arg);
+	}
+      else
+	{
+	  /* This is a policy URL.  */
+
+	  char *value;
+
+	  if (notation->critical)
+	    {
+	      value = malloc (1 + notation->value_len + 1);
+	      if (!value)
+		err = gpg_error_from_errno (errno);
+	      else
+		{
+		  value[0] = '!';
+		  /* We know that notation->value is '\0' terminated.  */
+		  strcpy (&value[1], notation->value);
+		}
+	    }
+	  else
+	    value = notation->value;
+
+	  if (!err)
+	    err = add_arg (gpg, "--sig-policy-url");
+	  if (!err)
+	    err = add_arg (gpg, value);
+
+	  if (value != notation->value)
+	    free (value);
+      	}
+
+      notation = notation->next;
+    }
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
+	  gpgme_ctx_t ctx /* FIXME */)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  err = add_arg (gpg, "--with-colons");
+  if (!err)
+    err = append_args_from_signers (gpg, ctx);
+  if (!err)
+  err = add_arg (gpg, type == 0 ? "--edit-key" : "--card-edit");
+  if (!err)
+    err = add_data (gpg, out, 1, 1);
+  if (!err)
+    err = add_arg (gpg, "--");
+  if (!err && type == 0)
+    {
+      const char *s = key->subkeys ? key->subkeys->fpr : NULL;
+      if (!s)
+	err = gpg_error (GPG_ERR_INV_VALUE);
+      else
+	err = add_arg (gpg, s);
+    }
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
+{
+  gpgme_error_t err = 0;
+  int i = 0;
+
+  while (recp[i])
+    {
+      if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
+	err = gpg_error (GPG_ERR_INV_VALUE);
+      if (!err)
+	err = add_arg (gpg, "-r");
+      if (!err)
+	err = add_arg (gpg, recp[i]->subkeys->fpr);
+      if (err)
+	break;
+      i++;
+    }    
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
+	     gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+  int symmetric = !recp;
+
+  err = add_arg (gpg, symmetric ? "--symmetric" : "--encrypt");
+
+  if (!err && use_armor)
+    err = add_arg (gpg, "--armor");
+
+  if (!symmetric)
+    {
+      /* If we know that all recipients are valid (full or ultimate trust)
+	 we can suppress further checks.  */
+      if (!err && !symmetric && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
+	err = add_arg (gpg, "--always-trust");
+
+      if (!err)
+	err = append_args_from_recipients (gpg, recp);
+    }
+
+  /* Tell the gpg object about the data.  */
+  if (!err)
+    err = add_arg (gpg, "--output");
+  if (!err)
+    err = add_arg (gpg, "-");
+  if (!err)
+    err = add_data (gpg, ciph, 1, 1);
+  if (gpgme_data_get_file_name (plain))
+    {
+      if (!err)
+	err = add_arg (gpg, "--set-filename");
+      if (!err)
+	err = add_arg (gpg, gpgme_data_get_file_name (plain));
+    }
+  if (!err)
+    err = add_arg (gpg, "--");
+  if (!err)
+    err = add_data (gpg, plain, 0, 0);
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
+		  gpgme_encrypt_flags_t flags, gpgme_data_t plain,
+		  gpgme_data_t ciph, int use_armor,
+		  gpgme_ctx_t ctx /* FIXME */)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  err = add_arg (gpg, "--encrypt");
+  if (!err)
+    err = add_arg (gpg, "--sign");
+  if (!err && use_armor)
+    err = add_arg (gpg, "--armor");
+
+  /* If we know that all recipients are valid (full or ultimate trust)
+     we can suppress further checks.  */
+  if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
+    err = add_arg (gpg, "--always-trust");
+
+  if (!err)
+    err = append_args_from_recipients (gpg, recp);
+
+  if (!err)
+    err = append_args_from_signers (gpg, ctx);
+  if (!err)
+    err = append_args_from_sig_notations (gpg, ctx);
+
+  /* Tell the gpg object about the data.  */
+  if (!err)
+    err = add_arg (gpg, "--output");
+  if (!err)
+    err = add_arg (gpg, "-");
+  if (!err)
+    err = add_data (gpg, ciph, 1, 1);
+  if (gpgme_data_get_file_name (plain))
+    {
+      if (!err)
+	err = add_arg (gpg, "--set-filename");
+      if (!err)
+	err = add_arg (gpg, gpgme_data_get_file_name (plain));
+    }
+  if (!err)
+    err = add_arg (gpg, "--");
+  if (!err)
+    err = add_data (gpg, plain, 0, 0);
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_export (void *engine, const char *pattern, unsigned int reserved,
+	    gpgme_data_t keydata, int use_armor)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  if (reserved)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = add_arg (gpg, "--export");
+  if (!err && use_armor)
+    err = add_arg (gpg, "--armor");
+  if (!err)
+    err = add_data (gpg, keydata, 1, 1);
+  if (!err)
+    err = add_arg (gpg, "--");
+
+  if (!err && pattern && *pattern)
+    err = add_arg (gpg, pattern);
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_export_ext (void *engine, const char *pattern[], unsigned int reserved,
+		gpgme_data_t keydata, int use_armor)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  if (reserved)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = add_arg (gpg, "--export");
+  if (!err && use_armor)
+    err = add_arg (gpg, "--armor");
+  if (!err)
+    err = add_data (gpg, keydata, 1, 1);
+  if (!err)
+    err = add_arg (gpg, "--");
+
+  if (pattern)
+    {
+      while (!err && *pattern && **pattern)
+	err = add_arg (gpg, *(pattern++));
+    }
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_genkey (void *engine, gpgme_data_t help_data, int use_armor,
+	    gpgme_data_t pubkey, gpgme_data_t seckey)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  if (!gpg)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  /* We need a special mechanism to get the fd of a pipe here, so that
+     we can use this for the %pubring and %secring parameters.  We
+     don't have this yet, so we implement only the adding to the
+     standard keyrings.  */
+  if (pubkey || seckey)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  err = add_arg (gpg, "--gen-key");
+  if (!err && use_armor)
+    err = add_arg (gpg, "--armor");
+  if (!err)
+    err = add_data (gpg, help_data, 0, 0);
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_import (void *engine, gpgme_data_t keydata)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  err = add_arg (gpg, "--import");
+  if (!err)
+    err = add_data (gpg, keydata, 0, 0);
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+/* The output for external keylistings in GnuPG is different from all
+   the other key listings.  We catch this here with a special
+   preprocessor that reformats the colon handler lines.  */
+static gpgme_error_t
+gpg_keylist_preprocess (char *line, char **r_line)
+{
+  enum
+    {
+      RT_NONE, RT_INFO, RT_PUB, RT_UID
+    }
+  rectype = RT_NONE;
+#define NR_FIELDS 16
+  char *field[NR_FIELDS];
+  int fields = 0;
+
+  *r_line = NULL;
+
+  while (line && fields < NR_FIELDS)
+    {
+      field[fields++] = line;
+      line = strchr (line, ':');
+      if (line)
+	*(line++) = '\0';
+    }
+
+  if (!strcmp (field[0], "info"))
+    rectype = RT_INFO;
+  else if (!strcmp (field[0], "pub"))
+    rectype = RT_PUB;
+  else if (!strcmp (field[0], "uid"))
+    rectype = RT_UID;
+  else 
+    rectype = RT_NONE;
+
+  switch (rectype)
+    {
+    case RT_INFO:
+      /* FIXME: Eventually, check the version number at least.  */
+      return 0;
+
+    case RT_PUB:
+      if (fields < 7)
+	return 0;
+
+      /* The format is:
+
+	 pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
+
+	 as defined in 5.2. Machine Readable Indexes of the OpenPGP
+	 HTTP Keyserver Protocol (draft). 
+
+	 We want:
+	 pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
+      */
+
+      if (asprintf (r_line, "pub:o%s:%s:%s:%s:%s:%s::::::::",
+		    field[6], field[3], field[2], field[1],
+		    field[4], field[5]) < 0)
+	return gpg_error_from_errno (errno);
+      return 0;
+
+    case RT_UID:
+      /* The format is:
+
+         uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
+
+	 as defined in 5.2. Machine Readable Indexes of the OpenPGP
+	 HTTP Keyserver Protocol (draft). 
+
+	 We want:
+	 uid:o<flags>::::<creatdate>:<expdate>:::<uid>:
+      */
+
+      if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
+		    field[4], field[2], field[3], field[1]) < 0)
+	return gpg_error_from_errno (errno);
+      return 0;
+
+    case RT_NONE:
+      /* Unknown record.  */
+      break;
+    }
+  return 0;
+
+}
+
+
+static gpgme_error_t
+gpg_keylist (void *engine, const char *pattern, int secret_only,
+	     gpgme_keylist_mode_t mode)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  if (mode & GPGME_KEYLIST_MODE_EXTERN)
+    {
+      if ((mode & GPGME_KEYLIST_MODE_LOCAL)
+	  || secret_only)
+	return gpg_error (GPG_ERR_NOT_SUPPORTED);
+    }
+  
+  err = add_arg (gpg, "--with-colons");
+  if (!err)
+    err = add_arg (gpg, "--fixed-list-mode");
+  if (!err)
+    err = add_arg (gpg, "--with-fingerprint");
+  if (!err)
+    err = add_arg (gpg, "--with-fingerprint");
+  if (!err && (mode & GPGME_KEYLIST_MODE_SIGS)
+      && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
+    {
+      err = add_arg (gpg, "--list-options");
+      if (!err)
+	err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
+    }
+  if (!err)
+    {
+      if (mode & GPGME_KEYLIST_MODE_EXTERN)
+	{
+	  err = add_arg (gpg, "--search-keys");
+	  gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
+	}
+      else
+	{
+	  err = add_arg (gpg, secret_only ? "--list-secret-keys"
+			 : ((mode & GPGME_KEYLIST_MODE_SIGS)
+			    ? "--check-sigs" : "--list-keys"));
+	}
+    }
+
+  /* Tell the gpg object about the data.  */
+  if (!err)
+    err = add_arg (gpg, "--");
+  if (!err && pattern && *pattern)
+    err = add_arg (gpg, pattern);
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
+		 int reserved, gpgme_keylist_mode_t mode)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  if (reserved)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = add_arg (gpg, "--with-colons");
+  if (!err)
+    err = add_arg (gpg, "--fixed-list-mode");
+  if (!err)
+    err = add_arg (gpg, "--with-fingerprint");
+  if (!err)
+    err = add_arg (gpg, "--with-fingerprint");
+  if (!err && (mode & GPGME_KEYLIST_MODE_SIGS)
+      && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
+    {
+      err = add_arg (gpg, "--list-options");
+      if (!err)
+	err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
+    }
+  if (!err)
+    err = add_arg (gpg, secret_only ? "--list-secret-keys"
+		   : ((mode & GPGME_KEYLIST_MODE_SIGS)
+		      ? "--check-sigs" : "--list-keys"));
+  if (!err)
+    err = add_arg (gpg, "--");
+
+  if (pattern)
+    {
+      while (!err && *pattern && **pattern)
+	err = add_arg (gpg, *(pattern++));
+    }
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
+	  gpgme_sig_mode_t mode, int use_armor, int use_textmode,
+	  int include_certs, gpgme_ctx_t ctx /* FIXME */)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  if (mode == GPGME_SIG_MODE_CLEAR)
+    err = add_arg (gpg, "--clearsign");
+  else
+    {
+      err = add_arg (gpg, "--sign");
+      if (!err && mode == GPGME_SIG_MODE_DETACH)
+	err = add_arg (gpg, "--detach");
+      if (!err && use_armor)
+	err = add_arg (gpg, "--armor");
+      if (!err && use_textmode)
+	err = add_arg (gpg, "--textmode");
+    }
+
+  if (!err)
+    err = append_args_from_signers (gpg, ctx);
+  if (!err)
+    err = append_args_from_sig_notations (gpg, ctx);
+
+  if (gpgme_data_get_file_name (in))
+    {
+      if (!err)
+	err = add_arg (gpg, "--set-filename");
+      if (!err)
+	err = add_arg (gpg, gpgme_data_get_file_name (in));
+    }
+
+  /* Tell the gpg object about the data.  */
+  if (!err)
+    err = add_data (gpg, in, 0, 0);
+  if (!err)
+    err = add_data (gpg, out, 1, 1);
+
+  if (!err)
+    start (gpg);
+
+  return err;
+}
+
+static gpgme_error_t
+gpg_trustlist (void *engine, const char *pattern)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err;
+
+  err = add_arg (gpg, "--with-colons");
+  if (!err)
+    err = add_arg (gpg, "--list-trust-path");
+  
+  /* Tell the gpg object about the data.  */
+  if (!err)
+    err = add_arg (gpg, "--");
+  if (!err)
+    err = add_arg (gpg, pattern);
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static gpgme_error_t
+gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
+	    gpgme_data_t plaintext)
+{
+  engine_gpg_t gpg = engine;
+  gpgme_error_t err = 0;
+
+  if (plaintext)
+    {
+      /* Normal or cleartext signature.  */
+
+      err = add_arg (gpg, "--output");
+      if (!err)
+	err = add_arg (gpg, "-");
+      if (!err)
+	err = add_arg (gpg, "--");
+      if (!err)
+	err = add_data (gpg, sig, 0, 0);
+      if (!err)
+	err = add_data (gpg, plaintext, 1, 1);
+    }
+  else
+    {
+      err = add_arg (gpg, "--verify");
+      if (!err)
+	err = add_arg (gpg, "--");
+      if (!err)
+	err = add_data (gpg, sig, -1, 0);
+      if (signed_text)
+	{
+	  if (!err)
+	    err = add_arg (gpg, "-");
+	  if (!err)
+	    err = add_data (gpg, signed_text, 0, 0);
+	}
+    }
+
+  if (!err)
+    err = start (gpg);
+
+  return err;
+}
+
+
+static void
+gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
+{
+  engine_gpg_t gpg = engine;
+
+  gpg->io_cbs = *io_cbs;
+}
+
+
+struct engine_ops _gpgme_engine_ops_gpg =
+  {
+    /* Static functions.  */
+    _gpgme_get_gpg_path,
+    gpg_get_version,
+    gpg_get_req_version,
+    gpg_new,
+
+    /* Member functions.  */
+    gpg_release,
+    NULL,				/* reset */
+    gpg_set_status_handler,
+    gpg_set_command_handler,
+    gpg_set_colon_line_handler,
+    gpg_set_locale,
+    gpg_decrypt,
+    gpg_delete,
+    gpg_edit,
+    gpg_encrypt,
+    gpg_encrypt_sign,
+    gpg_export,
+    gpg_export_ext,
+    gpg_genkey,
+    gpg_import,
+    gpg_keylist,
+    gpg_keylist_ext,
+    gpg_sign,
+    gpg_trustlist,
+    gpg_verify,
+    gpg_set_io_cbs,
+    gpg_io_event,
+    gpg_cancel
+  };
diff --git a/libtdenetwork/libgpgme-copy/gpgme/sema.h b/libtdenetwork/libgpgme-copy/gpgme/sema.h
new file mode 100644
index 000000000..640bb7156
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/sema.h
@@ -0,0 +1,67 @@
+/* sema.h - Definitions for semaphores.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2003, 2004 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 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.
+   
+   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
+   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 SEMA_H
+#define SEMA_H
+
+struct critsect_s
+{
+  const char *name;
+  void *private;
+};
+
+#define DEFINE_GLOBAL_LOCK(name) \
+  struct critsect_s name = { #name, NULL }
+#define DEFINE_STATIC_LOCK(name) \
+  static struct critsect_s name  = { #name, NULL }
+
+#define DECLARE_LOCK(name) \
+  struct critsect_s name
+#define INIT_LOCK(a)			\
+  do					\
+    {					\
+      (a).name = #a;			\
+      (a).private = NULL;		\
+    }					\
+  while (0)
+#define DESTROY_LOCK(name) _gpgme_sema_cs_destroy (&(name))
+                       
+
+#define LOCK(name)			\
+  do					\
+    {					\
+      _gpgme_sema_cs_enter (&(name));	\
+    }					\
+  while (0)
+
+#define UNLOCK(name)			\
+  do					\
+    {					\
+      _gpgme_sema_cs_leave (&(name));	\
+    }					\
+  while (0)
+
+void _gpgme_sema_subsystem_init (void);
+void _gpgme_sema_cs_enter (struct critsect_s *s);
+void _gpgme_sema_cs_leave (struct critsect_s *s);
+void _gpgme_sema_cs_destroy (struct critsect_s *s);
+
+#endif /* SEMA_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/sig-notation.c b/libtdenetwork/libgpgme-copy/gpgme/sig-notation.c
new file mode 100644
index 000000000..a5558ece8
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/sig-notation.c
@@ -0,0 +1,260 @@
+/* sig-notation.c - Signature notation data support.
+   Copyright (C) 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+
+
+/* Free the signature notation object and all associated resources.
+   The object must already be removed from any linked list as the next
+   pointer is ignored.  */
+void
+_gpgme_sig_notation_free (gpgme_sig_notation_t notation)
+{
+  if (notation->name)
+    free (notation->name);
+
+  if (notation->value)
+    free (notation->value);
+
+  free (notation);
+}
+
+
+/* Set the flags of NOTATION to FLAGS.  */
+static void
+sig_notation_set_flags (gpgme_sig_notation_t notation,
+			gpgme_sig_notation_flags_t flags)
+{
+  /* We copy the flags into individual bits to make them easier
+     accessible individually for the user.  */
+  notation->human_readable = flags & GPGME_SIG_NOTATION_HUMAN_READABLE ? 1 : 0;
+  notation->critical = flags & GPGME_SIG_NOTATION_CRITICAL ? 1 : 0; 
+
+  notation->flags = flags;
+}
+
+
+/* Create a new, empty signature notation data object.  */
+gpgme_error_t
+_gpgme_sig_notation_create (gpgme_sig_notation_t *notationp,
+			    const char *name, int name_len,
+			    const char *value, int value_len,
+			    gpgme_sig_notation_flags_t flags)
+{
+  gpgme_error_t err = 0;
+  gpgme_sig_notation_t notation;
+
+  /* Currently, we require all notations to be human-readable.  */
+  if (name && !(flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  notation = calloc (1, sizeof (*notation));
+  if (!notation)
+    return gpg_error_from_errno (errno);
+
+  /* This is critical.  We want to reliably identify policy URLs by
+     using a NULL pointer for NAME.  So all notations must have a NAME
+     string, even if it is empty.  */
+  if (name)
+    {
+      /* We add a trailing '\0' for stringification in the good
+	 case.  */
+      notation->name = malloc (name_len + 1);
+      if (!notation->name)
+	{
+	  err = gpg_error_from_errno (errno);
+	  goto err;
+	}
+
+      memcpy (notation->name, name, name_len);
+      notation->name[name_len] = '\0';
+      notation->name_len = name_len;
+    }
+
+  if (value)
+    {
+      /* We add a trailing '\0' for stringification in the good
+	 case.  */
+      notation->value = malloc (value_len + 1);
+      if (!notation->value)
+	{
+	  err = gpg_error_from_errno (errno);
+	  goto err;
+	}
+
+      memcpy (notation->value, value, value_len);
+      notation->value[value_len] = '\0';
+      notation->value_len = value_len;
+    }
+
+  sig_notation_set_flags (notation, flags);
+
+  *notationp = notation;
+  return 0;
+
+ err:
+  _gpgme_sig_notation_free (notation);
+  return err;
+}
+
+
+/* GnuPG subpacket flags.  */
+
+/* This subpacket data is part of the hashed data.  */
+#define GNUPG_SPK_HASHED	0x01
+
+/* This subpacket is marked critical.  */
+#define GNUPG_SPK_CRITICAL	0x02
+
+/* Parse a notation or policy URL subpacket.  If the packet type is
+   not known, return no error but NULL in NOTATION.  */
+gpgme_error_t
+_gpgme_parse_notation (gpgme_sig_notation_t *notationp,
+		       int type, int pkflags, int len, char *data)
+{
+  gpgme_error_t err;
+  char *name = NULL;
+  int name_len = 0;
+  char *value = NULL;
+  int value_len = 0;
+  gpgme_sig_notation_flags_t flags = 0;
+  char *decoded_data;
+  unsigned char *bdata;
+
+  /* Type 20: Notation data.  */
+  /* Type 26: Policy URL.  */
+  if (type != 20 && type != 26)
+    {
+      *notationp = NULL;
+      return 0;
+    }
+
+  /* A few simple sanity checks.  */
+  if (len > strlen (data))
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  /* See below for the format of a notation subpacket.  It has at
+     least four octets of flags and two times two octets of length
+     information.  */
+  if (type == 20 && len < 4 + 2 + 2)
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  err = _gpgme_decode_percent_string (data, &decoded_data, 0, 1);
+  if (err)
+    return err;
+  bdata = (unsigned char *) decoded_data;
+
+  /* Flags common to notation data and policy URL.  */
+  if (pkflags & GNUPG_SPK_CRITICAL)
+    flags |= GPGME_SIG_NOTATION_CRITICAL;
+
+  /* This information is relevant in parsing multi-octet numbers below:
+
+     3.1. Scalar numbers
+
+     Scalar numbers are unsigned, and are always stored in big-endian
+     format.  Using n[k] to refer to the kth octet being interpreted,
+     the value of a two-octet scalar is ((n[0] << 8) + n[1]).  The
+     value of a four-octet scalar is ((n[0] << 24) + (n[1] << 16) +
+     (n[2] << 8) + n[3]).
+
+     From RFC2440: OpenPGP Message Format.  Copyright (C) The Internet
+     Society (1998).  All Rights Reserved.  */
+#define RFC2440_GET_WORD(chr) ((((int)((unsigned char *)(chr))[0]) << 8) \
+			       + ((int)((unsigned char *)(chr))[1]))
+
+  if (type == 20)
+    {
+      /* 5.2.3.15. Notation Data
+
+	 (4 octets of flags, 2 octets of name length (M),
+	 2 octets of value length (N), M octets of name data,
+	 N octets of value data)
+
+	 [...] The "flags" field holds four octets of flags.
+	 All undefined flags MUST be zero. Defined flags are:
+
+	 First octet: 0x80 = human-readable. [...]
+	 Other octets:  none.
+
+	 From RFC2440: OpenPGP Message Format.  Copyright (C) The
+	 Internet Society (1998).  All Rights Reserved.  */
+
+      int chr;
+
+      /* First octet of flags.  */
+#define RFC2440_SPK20_FLAG1_HUMAN_READABLE 0x80
+
+      chr = *bdata;
+      bdata++;
+
+      if (chr & RFC2440_SPK20_FLAG1_HUMAN_READABLE)
+	flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
+
+      /* The second, third and four octet of flags are unused.  */
+      bdata++;
+      bdata++;
+      bdata++;
+
+      name_len = RFC2440_GET_WORD (bdata);
+      bdata += 2;
+
+      value_len = RFC2440_GET_WORD (bdata);
+      bdata += 2;
+
+      /* Small sanity check.  */
+      if (4 + 2 + 2 + name_len + value_len > len)
+	{
+	  free (decoded_data);
+	  return gpg_error (GPG_ERR_INV_ENGINE);
+	}
+
+      name = (char *) bdata;
+      bdata += name_len;
+
+      value = (char *) bdata;
+    }
+  else
+    {
+      /* Type is 26.  */
+
+      /* NAME is NULL, name_len is 0.  */
+
+      value = (char *) bdata;
+      value_len = strlen (value);
+    }
+
+  err = _gpgme_sig_notation_create (notationp, name, name_len,
+				    value, value_len, flags);
+
+  free (decoded_data);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/sign.c b/libtdenetwork/libgpgme-copy/gpgme/sign.c
new file mode 100644
index 000000000..f766c0437
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/sign.c
@@ -0,0 +1,328 @@
+/* sign.c - Signing function.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "ops.h"
+#include "util.h"
+
+
+typedef struct
+{
+  struct _gpgme_op_sign_result result;
+
+  /* A pointer to the next pointer of the last invalid signer in
+     the list.  This makes appending new invalid signers painless
+     while preserving the order.  */
+  gpgme_invalid_key_t *last_signer_p;
+
+  /* Likewise for signature information.  */
+  gpgme_new_signature_t *last_sig_p;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+  gpgme_invalid_key_t invalid_signer = opd->result.invalid_signers;
+  gpgme_new_signature_t sig = opd->result.signatures;
+
+  while (invalid_signer)
+    {
+      gpgme_invalid_key_t next = invalid_signer->next;
+      if (invalid_signer->fpr)
+	free (invalid_signer->fpr);
+      free (invalid_signer);
+      invalid_signer = next;
+    }
+
+  while (sig)
+    {
+      gpgme_new_signature_t next = sig->next;
+      free (sig->fpr);
+      free (sig);
+      sig = next;
+    }
+}
+
+
+gpgme_sign_result_t
+gpgme_op_sign_result (gpgme_ctx_t ctx)
+{
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, &hook, -1, NULL);
+  opd = hook;
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+static gpgme_error_t
+parse_sig_created (char *args, gpgme_new_signature_t *sigp)
+{
+  gpgme_new_signature_t sig;
+  char *tail;
+
+  sig = malloc (sizeof (*sig));
+  if (!sig)
+    return gpg_error_from_errno (errno);
+
+  sig->next = NULL;
+  switch (*args)
+    {
+    case 'S':
+      sig->type = GPGME_SIG_MODE_NORMAL;
+      break;
+
+    case 'D':
+      sig->type = GPGME_SIG_MODE_DETACH;
+      break;
+
+    case 'C':
+      sig->type = GPGME_SIG_MODE_CLEAR;
+      break;
+
+    default:
+      /* The backend engine is not behaving.  */
+      free (sig);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+
+  args++;
+  if (*args != ' ')
+    {
+      free (sig);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+
+  errno = 0;
+  sig->pubkey_algo = strtol (args, &tail, 0);
+  if (errno || args == tail || *tail != ' ')
+    {
+      /* The crypto backend does not behave.  */
+      free (sig);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+  args = tail;
+
+  sig->hash_algo = strtol (args, &tail, 0);
+  if (errno || args == tail || *tail != ' ')
+    {
+      /* The crypto backend does not behave.  */
+      free (sig);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+  args = tail;
+
+  sig->sig_class = strtol (args, &tail, 0);
+  sig->class = sig->sig_class;
+  sig->_obsolete_class = sig->sig_class;
+  if (errno || args == tail || *tail != ' ')
+    {
+      /* The crypto backend does not behave.  */
+      free (sig);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+  args = tail;
+
+  sig->timestamp = _gpgme_parse_timestamp (args, &tail);
+  if (sig->timestamp == -1 || args == tail || *tail != ' ')
+    {
+      /* The crypto backend does not behave.  */
+      free (sig);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+  args = tail;
+  while (*args == ' ')
+    args++;
+
+  if (!*args)
+    {
+      /* The crypto backend does not behave.  */
+      free (sig);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+
+  tail = strchr (args, ' ');
+  if (tail)
+    *tail = '\0';
+
+  sig->fpr = strdup (args);
+  if (!sig->fpr)
+    {
+      int saved_errno = errno;
+      free (sig);
+      return gpg_error_from_errno (saved_errno);
+    }
+  *sigp = sig;
+  return 0;
+}
+
+
+gpgme_error_t
+_gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_passphrase_status_handler (priv, code, args);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  switch (code)
+    {
+    case GPGME_STATUS_SIG_CREATED:
+      err = parse_sig_created (args, opd->last_sig_p);
+      if (err)
+	return err;
+
+      opd->last_sig_p = &(*opd->last_sig_p)->next;
+      break;
+
+    case GPGME_STATUS_INV_RECP:
+      err = _gpgme_parse_inv_recp (args, opd->last_signer_p);
+      if (err)
+	return err;
+
+      opd->last_signer_p = &(*opd->last_signer_p)->next;
+      break;
+
+    case GPGME_STATUS_EOF:
+      if (opd->result.invalid_signers)
+	return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
+      break;
+
+    default:
+      break;
+    }
+  return err;
+}
+
+
+static gpgme_error_t
+sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_progress_status_handler (priv, code, args);
+  if (!err)
+    err = _gpgme_sign_status_handler (priv, code, args);
+  return err;
+}
+
+
+gpgme_error_t
+_gpgme_op_sign_init_result (gpgme_ctx_t ctx)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, &hook,
+			       sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+  opd->last_signer_p = &opd->result.invalid_signers;
+  opd->last_sig_p = &opd->result.signatures;
+  return 0;
+}
+
+
+static gpgme_error_t
+sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain,
+	    gpgme_data_t sig, gpgme_sig_mode_t mode)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  err = _gpgme_op_sign_init_result (ctx);
+  if (err)
+    return err;
+
+  if (mode != GPGME_SIG_MODE_NORMAL && mode != GPGME_SIG_MODE_DETACH
+      && mode != GPGME_SIG_MODE_CLEAR)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!plain)
+    return gpg_error (GPG_ERR_NO_DATA);
+  if (!sig)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (ctx->passphrase_cb)
+    {
+      err = _gpgme_engine_set_command_handler
+	(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
+      if (err)
+	return err;
+    }
+
+  _gpgme_engine_set_status_handler (ctx->engine, sign_status_handler,
+				    ctx);
+
+  return _gpgme_engine_op_sign (ctx->engine, plain, sig, mode, ctx->use_armor,
+				ctx->use_textmode, ctx->include_certs,
+				ctx /* FIXME */);
+}
+
+
+/* Sign the plaintext PLAIN and store the signature in SIG.  */
+gpgme_error_t
+gpgme_op_sign_start (gpgme_ctx_t ctx, gpgme_data_t plain, gpgme_data_t sig,
+		     gpgme_sig_mode_t mode)
+{
+  return sign_start (ctx, 0, plain, sig, mode);
+}
+
+
+/* Sign the plaintext PLAIN and store the signature in SIG.  */
+gpgme_error_t
+gpgme_op_sign (gpgme_ctx_t ctx, gpgme_data_t plain, gpgme_data_t sig,
+	       gpgme_sig_mode_t mode)
+{
+  gpgme_error_t err = sign_start (ctx, 1, plain, sig, mode);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/signers.c b/libtdenetwork/libgpgme-copy/gpgme/signers.c
new file mode 100644
index 000000000..e60d2dd35
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/signers.c
@@ -0,0 +1,95 @@
+/* signers.c - Maintain signer sets.
+   Copyright (C) 2001 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "util.h"
+#include "context.h"
+
+
+/* Delete all signers from CTX.  */
+void
+gpgme_signers_clear (gpgme_ctx_t ctx)
+{
+  unsigned int i;
+
+  if (!ctx || !ctx->signers)
+    return;
+
+  for (i = 0; i < ctx->signers_len; i++)
+    {
+      assert (ctx->signers[i]);
+      gpgme_key_unref (ctx->signers[i]);
+      ctx->signers[i] = NULL;
+    }
+  ctx->signers_len = 0;
+}
+
+/* Add KEY to list of signers in CTX.  */
+gpgme_error_t
+gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key)
+{
+  if (!ctx || !key)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (ctx->signers_len == ctx->signers_size)
+    {
+      gpgme_key_t *newarr;
+      int n = ctx->signers_size + 5;
+      int j;
+
+      newarr = realloc (ctx->signers, n * sizeof (*newarr));
+      if (!newarr)
+	return gpg_error_from_errno (errno);
+      for (j = ctx->signers_size; j < n; j++)
+	newarr[j] = NULL;
+      ctx->signers = newarr;
+      ctx->signers_size = n;
+    }
+
+  gpgme_key_ref (key);
+  ctx->signers[ctx->signers_len++] = key;
+  return 0;
+}
+
+
+/* Return the SETQth signer's key in CTX with one reference.  */
+gpgme_key_t
+gpgme_signers_enum (const gpgme_ctx_t ctx, int seq)
+{
+  unsigned int seqno;
+
+  if (!ctx || seq < 0)
+    return NULL;
+
+  seqno = (unsigned int) seq;
+  if (seqno >= ctx->signers_len)
+    return NULL;
+  gpgme_key_ref (ctx->signers[seqno]);
+  return ctx->signers[seqno];
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/status-table.h b/libtdenetwork/libgpgme-copy/gpgme/status-table.h
new file mode 100644
index 000000000..e2ae5c3b6
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/status-table.h
@@ -0,0 +1,94 @@
+/* Generated automatically by mkstatus */
+/* Do not edit! */
+
+struct status_table_s {
+    const char *name;
+    gpgme_status_code_t code;
+};
+
+static struct status_table_s status_table[] = 
+{
+  { "ABORT", GPGME_STATUS_ABORT },
+  { "ALREADY_SIGNED", GPGME_STATUS_ALREADY_SIGNED },
+  { "BACKUP_KEY_CREATED", GPGME_STATUS_BACKUP_KEY_CREATED },
+  { "BADARMOR", GPGME_STATUS_BADARMOR },
+  { "BADMDC", GPGME_STATUS_BADMDC },
+  { "BADSIG", GPGME_STATUS_BADSIG },
+  { "BAD_PASSPHRASE", GPGME_STATUS_BAD_PASSPHRASE },
+  { "BEGIN_DECRYPTION", GPGME_STATUS_BEGIN_DECRYPTION },
+  { "BEGIN_ENCRYPTION", GPGME_STATUS_BEGIN_ENCRYPTION },
+  { "BEGIN_STREAM", GPGME_STATUS_BEGIN_STREAM },
+  { "CARDCTRL", GPGME_STATUS_CARDCTRL },
+  { "DECRYPTION_FAILED", GPGME_STATUS_DECRYPTION_FAILED },
+  { "DECRYPTION_OKAY", GPGME_STATUS_DECRYPTION_OKAY },
+  { "DELETE_PROBLEM", GPGME_STATUS_DELETE_PROBLEM },
+  { "ENC_TO", GPGME_STATUS_ENC_TO },
+  { "END_DECRYPTION", GPGME_STATUS_END_DECRYPTION },
+  { "END_ENCRYPTION", GPGME_STATUS_END_ENCRYPTION },
+  { "END_STREAM", GPGME_STATUS_END_STREAM },
+  { "ENTER", GPGME_STATUS_ENTER },
+  { "ERRMDC", GPGME_STATUS_ERRMDC },
+  { "ERROR", GPGME_STATUS_ERROR },
+  { "ERRSIG", GPGME_STATUS_ERRSIG },
+  { "EXPKEYSIG", GPGME_STATUS_EXPKEYSIG },
+  { "EXPSIG", GPGME_STATUS_EXPSIG },
+  { "FILE_DONE", GPGME_STATUS_FILE_DONE },
+  { "FILE_ERROR", GPGME_STATUS_FILE_ERROR },
+  { "FILE_START", GPGME_STATUS_FILE_START },
+  { "GET_BOOL", GPGME_STATUS_GET_BOOL },
+  { "GET_HIDDEN", GPGME_STATUS_GET_HIDDEN },
+  { "GET_LINE", GPGME_STATUS_GET_LINE },
+  { "GOODMDC", GPGME_STATUS_GOODMDC },
+  { "GOODSIG", GPGME_STATUS_GOODSIG },
+  { "GOOD_PASSPHRASE", GPGME_STATUS_GOOD_PASSPHRASE },
+  { "GOT_IT", GPGME_STATUS_GOT_IT },
+  { "IMPORTED", GPGME_STATUS_IMPORTED },
+  { "IMPORT_OK", GPGME_STATUS_IMPORT_OK },
+  { "IMPORT_PROBLEM", GPGME_STATUS_IMPORT_PROBLEM },
+  { "IMPORT_RES", GPGME_STATUS_IMPORT_RES },
+  { "INV_RECP", GPGME_STATUS_INV_RECP },
+  { "KEYEXPIRED", GPGME_STATUS_KEYEXPIRED },
+  { "KEYREVOKED", GPGME_STATUS_KEYREVOKED },
+  { "KEY_CREATED", GPGME_STATUS_KEY_CREATED },
+  { "LEAVE", GPGME_STATUS_LEAVE },
+  { "MISSING_PASSPHRASE", GPGME_STATUS_MISSING_PASSPHRASE },
+  { "NEED_PASSPHRASE", GPGME_STATUS_NEED_PASSPHRASE },
+  { "NEED_PASSPHRASE_PIN", GPGME_STATUS_NEED_PASSPHRASE_PIN },
+  { "NEED_PASSPHRASE_SYM", GPGME_STATUS_NEED_PASSPHRASE_SYM },
+  { "NEWSIG", GPGME_STATUS_NEWSIG },
+  { "NODATA", GPGME_STATUS_NODATA },
+  { "NOTATION_DATA", GPGME_STATUS_NOTATION_DATA },
+  { "NOTATION_NAME", GPGME_STATUS_NOTATION_NAME },
+  { "NO_PUBKEY", GPGME_STATUS_NO_PUBKEY },
+  { "NO_RECP", GPGME_STATUS_NO_RECP },
+  { "NO_SECKEY", GPGME_STATUS_NO_SECKEY },
+  { "PKA_TRUST_BAD", GPGME_STATUS_PKA_TRUST_BAD },
+  { "PKA_TRUST_GOOD", GPGME_STATUS_PKA_TRUST_GOOD },
+  { "PLAINTEXT", GPGME_STATUS_PLAINTEXT },
+  { "POLICY_URL", GPGME_STATUS_POLICY_URL },
+  { "PROGRESS", GPGME_STATUS_PROGRESS },
+  { "REVKEYSIG", GPGME_STATUS_REVKEYSIG },
+  { "RSA_OR_IDEA", GPGME_STATUS_RSA_OR_IDEA },
+  { "SC_OP_FAILURE", GPGME_STATUS_SC_OP_FAILURE },
+  { "SC_OP_SUCCESS", GPGME_STATUS_SC_OP_SUCCESS },
+  { "SESSION_KEY", GPGME_STATUS_SESSION_KEY },
+  { "SHM_GET", GPGME_STATUS_SHM_GET },
+  { "SHM_GET_BOOL", GPGME_STATUS_SHM_GET_BOOL },
+  { "SHM_GET_HIDDEN", GPGME_STATUS_SHM_GET_HIDDEN },
+  { "SHM_INFO", GPGME_STATUS_SHM_INFO },
+  { "SIGEXPIRED", GPGME_STATUS_SIGEXPIRED },
+  { "SIG_CREATED", GPGME_STATUS_SIG_CREATED },
+  { "SIG_ID", GPGME_STATUS_SIG_ID },
+  { "SIG_SUBPACKET", GPGME_STATUS_SIG_SUBPACKET },
+  { "TRUNCATED", GPGME_STATUS_TRUNCATED },
+  { "TRUST_FULLY", GPGME_STATUS_TRUST_FULLY },
+  { "TRUST_MARGINAL", GPGME_STATUS_TRUST_MARGINAL },
+  { "TRUST_NEVER", GPGME_STATUS_TRUST_NEVER },
+  { "TRUST_ULTIMATE", GPGME_STATUS_TRUST_ULTIMATE },
+  { "TRUST_UNDEFINED", GPGME_STATUS_TRUST_UNDEFINED },
+  { "UNEXPECTED", GPGME_STATUS_UNEXPECTED },
+  { "USERID_HINT", GPGME_STATUS_USERID_HINT },
+  { "VALIDSIG", GPGME_STATUS_VALIDSIG },
+  {NULL, 0}
+};
+
diff --git a/libtdenetwork/libgpgme-copy/gpgme/stpcpy.c b/libtdenetwork/libgpgme-copy/gpgme/stpcpy.c
new file mode 100644
index 000000000..4e9fc10a0
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/stpcpy.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1992, 1995, 1997, 2002, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library 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.
+
+   The GNU C Library 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 the GNU C Library; 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 <string.h>
+
+#undef __stpcpy
+#undef stpcpy
+
+#ifndef weak_alias
+# define __stpcpy stpcpy
+#endif
+
+/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */
+char *
+__stpcpy (dest, src)
+     char *dest;
+     const char *src;
+{
+  register char *d = dest;
+  register const char *s = src;
+
+  do
+    *d++ = *s;
+  while (*s++ != '\0');
+
+  return d - 1;
+}
+#ifdef libc_hidden_def
+libc_hidden_def (__stpcpy)
+#endif
+#ifdef weak_alias
+weak_alias (__stpcpy, stpcpy)
+#endif
+#ifdef libc_hidden_builtin_def
+libc_hidden_builtin_def (stpcpy)
+#endif
diff --git a/libtdenetwork/libgpgme-copy/gpgme/trust-item.c b/libtdenetwork/libgpgme-copy/gpgme/trust-item.c
new file mode 100644
index 000000000..84d7e659f
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/trust-item.c
@@ -0,0 +1,171 @@
+/* trust-item.c - Trust item objects.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "util.h"
+#include "ops.h"
+#include "sema.h"
+
+
+/* Protects all reference counters in trust items.  All other accesses
+   to a trust item are either read only or happen before the trust
+   item is available to the user.  */
+DEFINE_STATIC_LOCK (trust_item_ref_lock);
+
+
+/* Create a new trust item.  */
+gpgme_error_t
+_gpgme_trust_item_new (gpgme_trust_item_t *r_item)
+{
+  gpgme_trust_item_t item;
+
+  item = calloc (1, sizeof *item);
+  if (!item)
+    return gpg_error_from_errno (errno);
+  item->_refs = 1;
+  item->keyid = item->_keyid;
+  item->_keyid[16] = '\0';
+  item->owner_trust = item->_owner_trust;
+  item->_owner_trust[1] = '\0';
+  item->validity = item->_validity;
+  item->_validity[1] = '\0';
+  *r_item = item;
+  return 0;
+}
+
+
+/* Acquire a reference to ITEM.  */
+void
+gpgme_trust_item_ref (gpgme_trust_item_t item)
+{
+  LOCK (trust_item_ref_lock);
+  item->_refs++;
+  UNLOCK (trust_item_ref_lock);
+}
+
+
+/* gpgme_trust_item_unref releases the trust item object. Note that
+   this function may not do an actual release if there are other
+   shallow copies of the object.  You have to call this function for
+   every newly created trust item object as well as for every
+   gpgme_trust_item_ref() done on the trust item object.  */
+void
+gpgme_trust_item_unref (gpgme_trust_item_t item)
+{
+  LOCK (trust_item_ref_lock);
+  assert (item->_refs > 0);
+  if (--item->_refs)
+    {
+      UNLOCK (trust_item_ref_lock);
+      return;
+    }
+  UNLOCK (trust_item_ref_lock);
+
+  if (item->name)
+    free (item->name);
+  free (item);
+}
+
+
+/* Compatibility interfaces.  */
+void
+gpgme_trust_item_release (gpgme_trust_item_t item)
+{
+  gpgme_trust_item_unref (item);
+}
+
+/* Return the value of the attribute WHAT of ITEM, which has to be
+   representable by a string.  */
+const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item,
+					      _gpgme_attr_t what,
+					      const void *reserved, int idx)
+{
+  const char *val = NULL;
+
+  if (!item)
+    return NULL;
+  if (reserved)
+    return NULL;
+  if (idx)
+    return NULL;
+
+  switch (what)
+    {
+    case GPGME_ATTR_KEYID:
+      val = item->keyid;
+      break;
+
+    case GPGME_ATTR_OTRUST:  
+      val = item->owner_trust;
+      break;
+
+    case GPGME_ATTR_VALIDITY:
+      val = item->validity;
+      break;
+
+    case GPGME_ATTR_USERID:  
+      val = item->name;
+      break;
+
+    default:
+      break;
+    }
+  return val;
+}
+
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+   representable by an integer.  IDX specifies a running index if the
+   attribute appears more than once in the key.  */
+int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
+				   const void *reserved, int idx)
+{
+  int val = 0;
+
+  if (!item)
+    return 0;
+  if (reserved)
+    return 0;
+  if (idx)
+    return 0;
+
+  switch (what)
+    {
+    case GPGME_ATTR_LEVEL:    
+      val = item->level;
+      break;
+
+    case GPGME_ATTR_TYPE:    
+      val = item->type;
+      break;
+
+    default:
+      break;
+    }
+  return val;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/trustlist.c b/libtdenetwork/libgpgme-copy/gpgme/trustlist.c
new file mode 100644
index 000000000..664e67cd7
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/trustlist.c
@@ -0,0 +1,248 @@
+/* trustlist.c - Trust item listing.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+
+
+struct trust_queue_item_s
+{
+  struct trust_queue_item_s *next;
+  gpgme_trust_item_t item;
+};
+
+typedef struct
+{
+  /* Something new is available.  */
+  int trust_cond;
+  struct trust_queue_item_s *trust_queue;
+} *op_data_t;
+
+
+
+static gpgme_error_t
+trustlist_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  return 0;
+}
+
+
+/* This handler is used to parse the output of --list-trust-path:
+   Format:
+   level:keyid:type:recno:ot:val:mc:cc:name:
+   With TYPE = U for a user ID
+               K for a key
+   The RECNO is either the one of the dir record or the one of the uid
+   record.  OT is the the usual trust letter and only availabel on K
+   lines.  VAL is the calcualted validity MC is the marginal trust
+   counter and only available on U lines CC is the same for the
+   complete count NAME ist the username and only printed on U
+   lines.  */
+static gpgme_error_t
+trustlist_colon_handler (void *priv, char *line)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  char *p, *pend;
+  int field = 0;
+  gpgme_trust_item_t item = NULL;
+
+  if (!line)
+    return 0; /* EOF */
+
+  for (p = line; p; p = pend)
+    {
+      field++;
+      pend = strchr (p, ':');
+      if (pend) 
+	*pend++ = 0;
+
+      switch (field)
+	{
+	case 1: /* level */
+	  err = _gpgme_trust_item_new (&item);
+	  if (err)
+	    return err;
+	  item->level = atoi (p);
+	  break;
+	case 2: /* long keyid */
+	  if (strlen (p) == DIM(item->keyid) - 1)
+	    strcpy (item->keyid, p);
+	  break;
+	case 3: /* type */
+	  item->type = *p == 'K'? 1 : *p == 'U'? 2 : 0;
+	  break;
+	case 5: /* owner trust */
+	  item->_owner_trust[0] = *p;
+	  break;
+	case 6: /* validity */
+	  item->_validity[0] = *p;
+	  break;
+	case 9: /* user ID */
+	  item->name = strdup (p);
+	  if (!item->name)
+	    {
+	      int saved_errno = errno;
+	      gpgme_trust_item_unref (item);
+	      return gpg_error_from_errno (saved_errno);
+	    }
+	  break;
+        }
+    }
+
+  if (item)
+    _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_TRUSTITEM, item);
+  return 0;
+}
+
+
+void
+_gpgme_op_trustlist_event_cb (void *data, gpgme_event_io_t type,
+			      void *type_data)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) data;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+  gpgme_trust_item_t item = (gpgme_trust_item_t) type_data;
+  struct trust_queue_item_s *q, *q2;
+
+  assert (type == GPGME_EVENT_NEXT_TRUSTITEM);
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return;
+
+  q = malloc (sizeof *q);
+  if (!q)
+    {
+      gpgme_trust_item_unref (item);
+      /* FIXME: GPGME_Out_Of_Core; */
+      return;
+    }
+  q->item = item;
+  q->next = NULL;
+  /* FIXME: Use a tail pointer */
+  q2 = opd->trust_queue;
+  if (!q2)
+    opd->trust_queue = q;
+  else
+    {
+      while (q2->next)
+	q2 = q2->next;
+      q2->next = q;
+    }
+  /* FIXME: unlock queue */
+  opd->trust_cond = 1;
+}
+
+
+gpgme_error_t
+gpgme_op_trustlist_start (gpgme_ctx_t ctx, const char *pattern, int max_level)
+{
+  gpgme_error_t err = 0;
+  void *hook;
+  op_data_t opd;
+
+  if (!pattern || !*pattern)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_reset (ctx, 2);
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook,
+			       sizeof (*opd), NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine,
+				    trustlist_status_handler, ctx);
+  err = _gpgme_engine_set_colon_line_handler (ctx->engine,
+					      trustlist_colon_handler, ctx);
+  if (err)
+    return err;
+
+  return _gpgme_engine_op_trustlist (ctx->engine, pattern);
+}
+
+
+gpgme_error_t
+gpgme_op_trustlist_next (gpgme_ctx_t ctx, gpgme_trust_item_t *r_item)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+  struct trust_queue_item_s *q;
+
+  if (!r_item)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  *r_item = NULL;
+  if (!ctx)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+  if (opd == NULL)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!opd->trust_queue)
+    {
+      err = _gpgme_wait_on_condition (ctx, &opd->trust_cond);
+      if (err)
+	return err;
+      if (!opd->trust_cond)
+	return gpg_error (GPG_ERR_EOF);
+      opd->trust_cond = 0; 
+      assert (opd->trust_queue);
+    }
+  q = opd->trust_queue;
+  opd->trust_queue = q->next;
+
+  *r_item = q->item;
+  free (q);
+  return 0;
+}
+
+
+/* Terminate a pending trustlist operation within CTX.  */
+gpgme_error_t
+gpgme_op_trustlist_end (gpgme_ctx_t ctx)
+{
+  if (!ctx)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  return 0;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/util.h b/libtdenetwork/libgpgme-copy/gpgme/util.h
new file mode 100644
index 000000000..05fd69d56
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/util.h
@@ -0,0 +1,106 @@
+/* util.h 
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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 UTIL_H
+#define UTIL_H
+
+#include "gpgme.h"
+
+
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+
+
+/*-- {posix,w32}-util.c --*/
+const char *_gpgme_get_gpg_path (void);
+const char *_gpgme_get_gpgsm_path (void);
+int _gpgme_get_conf_int (const char *key, int *value);
+
+
+/*-- replacement functions in <funcname>.c --*/
+#ifdef HAVE_CONFIG_H
+
+#ifndef HAVE_STPCPY
+static _GPGME_INLINE char *
+_gpgme_stpcpy (char *a, const char *b)
+{
+  while (*b)
+    *a++ = *b++;
+  *a = 0;
+  return a;
+}
+#define stpcpy(a,b) _gpgme_stpcpy ((a), (b))
+#endif /*!HAVE_STPCPY*/
+
+#if !HAVE_VASPRINTF
+#include <stdarg.h>
+int vasprintf (char **result, const char *format, va_list args);
+int asprintf (char **result, const char *format, ...);
+#endif
+
+#ifndef HAVE_TTYNAME_R
+int ttyname_r (int fd, char *buf, size_t buflen);
+#endif
+#endif
+
+
+/*-- conversion.c --*/
+/* Convert two hexadecimal digits from STR to the value they
+   represent.  Returns -1 if one of the characters is not a
+   hexadecimal digit.  */
+int _gpgme_hextobyte (const char *str);
+
+/* Decode the C formatted string SRC and store the result in the
+   buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
+   large enough buffer is allocated with malloc and *DESTP is set to
+   the result.  Currently, LEN is only used to specify if allocation
+   is desired or not, the caller is expected to make sure that *DESTP
+   is large enough if LEN is not zero.  */
+gpgme_error_t _gpgme_decode_c_string (const char *src, char **destp,
+				      size_t len);
+
+/* Decode the percent escaped string SRC and store the result in the
+   buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
+   large enough buffer is allocated with malloc and *DESTP is set to
+   the result.  Currently, LEN is only used to specify if allocation
+   is desired or not, the caller is expected to make sure that *DESTP
+   is large enough if LEN is not zero.  If BINARY is 1, then '\0'
+   characters are allowed in the output.  */
+gpgme_error_t _gpgme_decode_percent_string (const char *src, char **destp,
+					    size_t len, int binary);
+
+
+/* Parse the string TIMESTAMP into a time_t.  The string may either be
+   seconds since Epoch or in the ISO 8601 format like
+   "20390815T143012".  Returns 0 for an empty string or seconds since
+   Epoch. Leading spaces are skipped. If ENDP is not NULL, it will
+   point to the next non-parsed character in TIMESTRING. */
+time_t _gpgme_parse_timestamp (const char *timestamp, char **endp);
+
+
+gpgme_error_t _gpgme_map_gnupg_error (char *err);
+
+
+/* Retrieve the environment variable NAME and return a copy of it in a
+   malloc()'ed buffer in *VALUE.  If the environment variable is not
+   set, return NULL in *VALUE.  */
+gpgme_error_t _gpgme_getenv (const char *name, char **value);
+
+#endif /* UTIL_H */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/vasprintf.c b/libtdenetwork/libgpgme-copy/gpgme/vasprintf.c
new file mode 100644
index 000000000..b41d2ff91
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/vasprintf.c
@@ -0,0 +1,192 @@
+/* Like vsprintf but provides a pointer to malloc'd storage, which must
+   be freed by the caller.
+   Copyright (C) 1994, 2002 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty 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 of the License, or (at your option) any later version.
+
+Libiberty 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 libiberty; see the file COPYING.LIB.  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 <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+
+#ifndef va_copy /* According to POSIX, va_copy is a macro. */
+#if defined (__GNUC__) && defined (__PPC__) \
+     && (defined (_CALL_SYSV) || defined (_WIN32))
+#define va_copy(d, s) (*(d) = *(s))
+#elif defined (MUST_COPY_VA_BYVAL)
+#define va_copy(d, s) ((d) = (s))
+#else 
+#define va_copy(d, s) memcpy ((d), (s), sizeof (va_list))
+#endif 
+#endif 
+
+
+#ifdef TEST
+int global_total_width;
+#endif
+
+static int int_vasprintf (char **, const char *, va_list *);
+
+static int
+int_vasprintf (result, format, args)
+     char **result;
+     const char *format;
+     va_list *args;
+{
+  const char *p = format;
+  /* Add one to make sure that it is never zero, which might cause malloc
+     to return NULL.  */
+  int total_width = strlen (format) + 1;
+  va_list ap;
+
+  va_copy (ap, *args);
+
+  while (*p != '\0')
+    {
+      if (*p++ == '%')
+	{
+	  while (strchr ("-+ #0", *p))
+	    ++p;
+	  if (*p == '*')
+	    {
+	      ++p;
+	      total_width += abs (va_arg (ap, int));
+	    }
+	  else
+	    total_width += strtoul (p, (char **) &p, 10);
+	  if (*p == '.')
+	    {
+	      ++p;
+	      if (*p == '*')
+		{
+		  ++p;
+		  total_width += abs (va_arg (ap, int));
+		}
+	      else
+	      total_width += strtoul (p, (char **) &p, 10);
+	    }
+	  while (strchr ("hlL", *p))
+	    ++p;
+	  /* Should be big enough for any format specifier except %s and floats.  */
+	  total_width += 30;
+	  switch (*p)
+	    {
+	    case 'd':
+	    case 'i':
+	    case 'o':
+	    case 'u':
+	    case 'x':
+	    case 'X':
+	    case 'c':
+	      (void) va_arg (ap, int);
+	      break;
+	    case 'f':
+	    case 'e':
+	    case 'E':
+	    case 'g':
+	    case 'G':
+	      (void) va_arg (ap, double);
+	      /* Since an ieee double can have an exponent of 307, we'll
+		 make the buffer wide enough to cover the gross case. */
+	      total_width += 307;
+	      break;
+	    case 's':
+              {
+                char *tmp = va_arg (ap, char *);
+                if (tmp)
+                  total_width += strlen (tmp);
+                else /* in case the vsprintf does prints a text */
+                  total_width += 25; /* e.g. "(null pointer reference)" */
+              }
+	      break;
+	    case 'p':
+	    case 'n':
+	      (void) va_arg (ap, char *);
+	      break;
+	    }
+	  p++;
+	}
+    }
+#ifdef TEST
+  global_total_width = total_width;
+#endif
+  *result = malloc (total_width);
+  if (*result != NULL)
+    return vsprintf (*result, format, *args);
+  else
+    return 0;
+}
+
+int
+vasprintf (result, format, args)
+     char **result;
+     const char *format;
+#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
+     _BSD_VA_LIST_ args;
+#else
+     va_list args;
+#endif
+{
+  return int_vasprintf (result, format, &args);
+}
+
+
+int
+asprintf (char **buf, const char *fmt, ...)
+{
+  int status;
+  va_list ap;
+
+  va_start (ap, fmt);
+  status = vasprintf (buf, fmt, ap);
+  va_end (ap);
+  return status;
+}
+
+
+#ifdef TEST
+void
+checkit (const char* format, ...)
+{
+  va_list args;
+  char *result;
+
+  va_start (args, format);
+  vasprintf (&result, format, args);
+  if (strlen (result) < global_total_width)
+    printf ("PASS: ");
+  else
+    printf ("FAIL: ");
+  printf ("%d %s\n", global_total_width, result);
+}
+
+int
+main (void)
+{
+  checkit ("%d", 0x12345678);
+  checkit ("%200d", 5);
+  checkit ("%.300d", 6);
+  checkit ("%100.150d", 7);
+  checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
+777777777777777777333333333333366666666666622222222222777777777777733333");
+  checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
+}
+#endif /* TEST */
diff --git a/libtdenetwork/libgpgme-copy/gpgme/verify.c b/libtdenetwork/libgpgme-copy/gpgme/verify.c
new file mode 100644
index 000000000..4000a61c7
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/verify.c
@@ -0,0 +1,992 @@
+/* verify.c - Signature verification.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+
+
+typedef struct
+{
+  struct _gpgme_op_verify_result result;
+
+  gpgme_signature_t current_sig;
+  int did_prepare_new_sig;
+  int only_newsig_seen;
+  int plaintext_seen;
+} *op_data_t;
+
+
+static void
+release_op_data (void *hook)
+{
+  op_data_t opd = (op_data_t) hook;
+  gpgme_signature_t sig = opd->result.signatures;
+
+  while (sig)
+    {
+      gpgme_signature_t next = sig->next;
+      gpgme_sig_notation_t notation = sig->notations;
+
+      while (notation)
+	{
+	  gpgme_sig_notation_t next_nota = notation->next;
+
+	  _gpgme_sig_notation_free (notation);
+	  notation = next_nota;
+	}
+
+      if (sig->fpr)
+	free (sig->fpr);
+      if (sig->pka_address)
+	free (sig->pka_address);
+      free (sig);
+      sig = next;
+    }
+
+  if (opd->result.file_name)
+    free (opd->result.file_name);
+}
+
+
+gpgme_verify_result_t
+gpgme_op_verify_result (gpgme_ctx_t ctx)
+{
+  void *hook;
+  op_data_t opd;
+  gpgme_error_t err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook, -1, NULL);
+  opd = hook;
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+/* Build a summary vector from RESULT. */
+static void
+calc_sig_summary (gpgme_signature_t sig)
+{
+  unsigned long sum = 0;
+  
+  /* Calculate the red/green flag.  */
+  if (sig->validity == GPGME_VALIDITY_FULL
+      || sig->validity == GPGME_VALIDITY_ULTIMATE)
+    {
+      if (gpg_err_code (sig->status) == GPG_ERR_NO_ERROR
+	  || gpg_err_code (sig->status) == GPG_ERR_SIG_EXPIRED
+	  || gpg_err_code (sig->status) == GPG_ERR_KEY_EXPIRED)
+	sum |= GPGME_SIGSUM_GREEN;
+    }
+  else if (sig->validity == GPGME_VALIDITY_NEVER)
+    {
+      if (gpg_err_code (sig->status) == GPG_ERR_NO_ERROR
+	  || gpg_err_code (sig->status) == GPG_ERR_SIG_EXPIRED
+	  || gpg_err_code (sig->status) == GPG_ERR_KEY_EXPIRED)
+	sum |= GPGME_SIGSUM_RED;
+    }
+  else if (gpg_err_code (sig->status) == GPG_ERR_BAD_SIGNATURE)
+    sum |= GPGME_SIGSUM_RED;
+
+
+  /* FIXME: handle the case when key and message are expired. */
+  switch (gpg_err_code (sig->status))
+    {
+    case GPG_ERR_SIG_EXPIRED:
+      sum |= GPGME_SIGSUM_SIG_EXPIRED;
+      break;
+
+    case GPG_ERR_KEY_EXPIRED:
+      sum |= GPGME_SIGSUM_KEY_EXPIRED;
+      break;
+
+    case GPG_ERR_NO_PUBKEY:
+      sum |= GPGME_SIGSUM_KEY_MISSING;
+      break;
+
+    case GPG_ERR_BAD_SIGNATURE:
+    case GPG_ERR_NO_ERROR:
+      break;
+
+    default:
+      sum |= GPGME_SIGSUM_SYS_ERROR;
+      break;
+    }
+  
+  /* Now look at the certain reason codes.  */
+  switch (gpg_err_code (sig->validity_reason))
+    {
+    case GPG_ERR_CRL_TOO_OLD:
+      if (sig->validity == GPGME_VALIDITY_UNKNOWN)
+        sum |= GPGME_SIGSUM_CRL_TOO_OLD;
+      break;
+        
+    case GPG_ERR_CERT_REVOKED:
+      sum |= GPGME_SIGSUM_KEY_REVOKED;
+      break;
+
+    default:
+      break;
+    }
+
+  /* Check other flags. */
+  if (sig->wrong_key_usage)
+    sum |= GPGME_SIGSUM_BAD_POLICY;
+  
+  /* Set the valid flag when the signature is unquestionable
+     valid. */
+  if ((sum & GPGME_SIGSUM_GREEN) && !(sum & ~GPGME_SIGSUM_GREEN))
+    sum |= GPGME_SIGSUM_VALID;
+  
+  sig->summary = sum;
+}
+  
+
+static gpgme_error_t
+prepare_new_sig (op_data_t opd)
+{
+  gpgme_signature_t sig;
+
+  if (opd->only_newsig_seen && opd->current_sig)
+    {
+      /* We have only seen the NEWSIG status and nothing else - we
+         better skip this signature therefore and reuse it for the
+         next possible signature. */
+      sig = opd->current_sig;
+      memset (sig, 0, sizeof *sig);
+      assert (opd->result.signatures == sig);
+    }
+  else
+    {
+      sig = calloc (1, sizeof (*sig));
+      if (!sig)
+        return gpg_error_from_errno (errno);
+      if (!opd->result.signatures)
+        opd->result.signatures = sig;
+      if (opd->current_sig)
+        opd->current_sig->next = sig;
+      opd->current_sig = sig;
+    }
+  opd->did_prepare_new_sig = 1;
+  opd->only_newsig_seen = 0;
+  return 0;
+}
+
+static gpgme_error_t
+parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
+{
+  gpgme_signature_t sig;
+  char *end = strchr (args, ' ');
+  char *tail;
+
+  if (end)
+    {
+      *end = '\0';
+      end++;
+    }
+
+  if (!opd->did_prepare_new_sig)
+    {
+      gpg_error_t err;
+
+      err = prepare_new_sig (opd);
+      if (err)
+        return err;
+    }
+  assert (opd->did_prepare_new_sig);
+  opd->did_prepare_new_sig = 0;
+
+  assert (opd->current_sig);
+  sig = opd->current_sig;
+
+  /* FIXME: We should set the source of the state.  */
+  switch (code)
+    {
+    case GPGME_STATUS_GOODSIG:
+      sig->status = gpg_error (GPG_ERR_NO_ERROR);
+      break;
+
+    case GPGME_STATUS_EXPSIG:
+      sig->status = gpg_error (GPG_ERR_SIG_EXPIRED);
+      break;
+
+    case GPGME_STATUS_EXPKEYSIG:
+      sig->status = gpg_error (GPG_ERR_KEY_EXPIRED);
+      break;
+
+    case GPGME_STATUS_BADSIG:
+      sig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
+      break;
+
+    case GPGME_STATUS_REVKEYSIG:
+      sig->status = gpg_error (GPG_ERR_CERT_REVOKED);
+      break;
+
+    case GPGME_STATUS_ERRSIG:
+      /* Parse the pubkey algo.  */
+      if (!end)
+	goto parse_err_sig_fail;
+      errno = 0;
+      sig->pubkey_algo = strtol (end, &tail, 0);
+      if (errno || end == tail || *tail != ' ')
+	goto parse_err_sig_fail;
+      end = tail;
+      while (*end == ' ')
+	end++;
+     
+      /* Parse the hash algo.  */
+      if (!*end)
+	goto parse_err_sig_fail;
+      errno = 0;
+      sig->hash_algo = strtol (end, &tail, 0);
+      if (errno || end == tail || *tail != ' ')
+	goto parse_err_sig_fail;
+      end = tail;
+      while (*end == ' ')
+	end++;
+
+      /* Skip the sig class.  */
+      end = strchr (end, ' ');
+      if (!end)
+	goto parse_err_sig_fail;
+      while (*end == ' ')
+	end++;
+
+      /* Parse the timestamp.  */
+      sig->timestamp = _gpgme_parse_timestamp (end, &tail);
+      if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' '))
+	return gpg_error (GPG_ERR_INV_ENGINE);
+      end = tail;
+      while (*end == ' ')
+	end++;
+      
+      /* Parse the return code.  */
+      if (end[0] && (!end[1] || end[1] == ' '))
+	{
+	  switch (end[0])
+	    {
+	    case '4':
+	      sig->status = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+	      break;
+	      
+	    case '9':
+	      sig->status = gpg_error (GPG_ERR_NO_PUBKEY);
+	      break;
+	      
+	    default:
+	      sig->status = gpg_error (GPG_ERR_GENERAL);
+	    }
+	}
+      else
+	goto parse_err_sig_fail;
+
+      goto parse_err_sig_ok;
+      
+    parse_err_sig_fail:
+      sig->status = gpg_error (GPG_ERR_GENERAL);
+    parse_err_sig_ok:
+      break;
+      
+    default:
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+
+  if (*args)
+    {
+      sig->fpr = strdup (args);
+      if (!sig->fpr)
+	return gpg_error_from_errno (errno);
+    }
+  return 0;
+}
+
+
+static gpgme_error_t
+parse_valid_sig (gpgme_signature_t sig, char *args)
+{
+  char *end = strchr (args, ' ');
+  if (end)
+    {
+      *end = '\0';
+      end++;
+    }
+
+  if (!*args)
+    /* We require at least the fingerprint.  */
+    return gpg_error (GPG_ERR_GENERAL);
+
+  if (sig->fpr)
+    free (sig->fpr);
+  sig->fpr = strdup (args);
+  if (!sig->fpr)
+    return gpg_error_from_errno (errno);
+
+  /* Skip the creation date.  */
+  end = strchr (end, ' ');
+  if (end)
+    {
+      char *tail;
+
+      sig->timestamp = _gpgme_parse_timestamp (end, &tail);
+      if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' '))
+	return gpg_error (GPG_ERR_INV_ENGINE);
+      end = tail;
+     
+      sig->exp_timestamp = _gpgme_parse_timestamp (end, &tail);
+      if (sig->exp_timestamp == -1 || end == tail || (*tail && *tail != ' '))
+	return gpg_error (GPG_ERR_INV_ENGINE);
+      end = tail;
+
+      while (*end == ' ')
+	end++;
+      /* Skip the signature version.  */
+      end = strchr (end, ' ');
+      if (end)
+	{
+	  while (*end == ' ')
+	    end++;
+
+	  /* Skip the reserved field.  */
+	  end = strchr (end, ' ');
+	  if (end)
+	    {
+	      /* Parse the pubkey algo.  */
+	      errno = 0;
+	      sig->pubkey_algo = strtol (end, &tail, 0);
+	      if (errno || end == tail || *tail != ' ')
+		return gpg_error (GPG_ERR_INV_ENGINE);
+	      end = tail;
+
+	      while (*end == ' ')
+		end++;
+
+	      if (*end)
+		{
+		  /* Parse the hash algo.  */
+
+		  errno = 0;
+		  sig->hash_algo = strtol (end, &tail, 0);
+		  if (errno || end == tail || *tail != ' ')
+		    return gpg_error (GPG_ERR_INV_ENGINE);
+		  end = tail;
+		}
+	    }
+	}
+    }
+  return 0;
+}
+
+
+static gpgme_error_t
+parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
+{
+  gpgme_error_t err;
+  gpgme_sig_notation_t *lastp = &sig->notations;
+  gpgme_sig_notation_t notation = sig->notations;
+  char *end = strchr (args, ' ');
+
+  if (end)
+    *end = '\0';
+
+  if (code == GPGME_STATUS_NOTATION_NAME || code == GPGME_STATUS_POLICY_URL)
+    {
+      /* FIXME: We could keep a pointer to the last notation in the list.  */
+      while (notation && notation->value)
+	{
+	  lastp = &notation->next;
+	  notation = notation->next;
+	}
+
+      if (notation)
+	/* There is another notation name without data for the
+	   previous one.  The crypto backend misbehaves.  */
+	return gpg_error (GPG_ERR_INV_ENGINE);
+
+      err = _gpgme_sig_notation_create (&notation, NULL, 0, NULL, 0, 0);
+      if (err)
+	return err;
+
+      if (code == GPGME_STATUS_NOTATION_NAME)
+	{
+	  err = _gpgme_decode_percent_string (args, &notation->name, 0, 0);
+	  if (err)
+	    {
+	      _gpgme_sig_notation_free (notation);
+	      return err;
+	    }
+
+	  notation->name_len = strlen (notation->name);
+
+	  /* FIXME: For now we fake the human-readable flag.  The
+	     critical flag can not be reported as it is not
+	     provided.  */
+	  notation->flags = GPGME_SIG_NOTATION_HUMAN_READABLE;
+	  notation->human_readable = 1;
+	}
+      else
+	{
+	  /* This is a policy URL.  */
+
+	  err = _gpgme_decode_percent_string (args, &notation->value, 0, 0);
+	  if (err)
+	    {
+	      _gpgme_sig_notation_free (notation);
+	      return err;
+	    }
+
+	  notation->value_len = strlen (notation->value);
+	}
+      *lastp = notation;
+    }
+  else if (code == GPGME_STATUS_NOTATION_DATA)
+    {
+      int len = strlen (args) + 1;
+      char *dest;
+
+      /* FIXME: We could keep a pointer to the last notation in the list.  */
+      while (notation && notation->next)
+	{
+	  lastp = &notation->next;
+	  notation = notation->next;
+	}
+
+      if (!notation || !notation->name)
+	/* There is notation data without a previous notation
+	   name.  The crypto backend misbehaves.  */
+	return gpg_error (GPG_ERR_INV_ENGINE);
+      
+      if (!notation->value)
+	{
+	  dest = notation->value = malloc (len);
+	  if (!dest)
+	    return gpg_error_from_errno (errno);
+	}
+      else
+	{
+	  int cur_len = strlen (notation->value);
+	  dest = realloc (notation->value, len + strlen (notation->value));
+	  if (!dest)
+	    return gpg_error_from_errno (errno);
+	  notation->value = dest;
+	  dest += cur_len;
+	}
+      
+      err = _gpgme_decode_percent_string (args, &dest, len, 0);
+      if (err)
+	return err;
+
+      notation->value_len += strlen (dest);
+    }
+  else
+    return gpg_error (GPG_ERR_INV_ENGINE);
+  return 0;
+}
+
+
+static gpgme_error_t
+parse_trust (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
+{
+  char *end = strchr (args, ' ');
+
+  if (end)
+    *end = '\0';
+
+  switch (code)
+    {
+    case GPGME_STATUS_TRUST_UNDEFINED:
+    default:
+      sig->validity = GPGME_VALIDITY_UNKNOWN;
+      break;
+
+    case GPGME_STATUS_TRUST_NEVER:
+      sig->validity = GPGME_VALIDITY_NEVER;
+      break;
+
+    case GPGME_STATUS_TRUST_MARGINAL:
+      sig->validity = GPGME_VALIDITY_MARGINAL;
+      break;
+
+    case GPGME_STATUS_TRUST_FULLY:
+    case GPGME_STATUS_TRUST_ULTIMATE:
+      sig->validity = GPGME_VALIDITY_FULL;
+      break;
+    }
+
+  if (*args)
+    sig->validity_reason = _gpgme_map_gnupg_error (args);
+  else
+    sig->validity_reason = 0;
+
+  return 0;
+}
+
+
+/* Parse an error status line and if SET_STATUS is true update the
+   result status as appropriate.  With SET_STATUS being false, only
+   check for an error.  */
+static gpgme_error_t
+parse_error (gpgme_signature_t sig, char *args, int set_status)
+{
+  gpgme_error_t err;
+  char *where = strchr (args, ' ');
+  char *which;
+
+  if (where)
+    {
+      *where = '\0';
+      which = where + 1;
+
+      where = strchr (which, ' ');
+      if (where)
+	*where = '\0';
+
+      where = args;      
+    }
+  else
+    return gpg_error (GPG_ERR_INV_ENGINE);
+
+  err = _gpgme_map_gnupg_error (which);
+
+  if (!strcmp (where, "proc_pkt.plaintext")
+      && gpg_err_code (err) == GPG_ERR_BAD_DATA)
+    {
+      /* This indicates a double plaintext.  The only solid way to
+         handle this is by failing the oepration.  */
+      return gpg_error (GPG_ERR_BAD_DATA);
+    }
+  else if (!set_status)
+    ;
+  else if (!strcmp (where, "verify.findkey"))
+    sig->status = err;
+  else if (!strcmp (where, "verify.keyusage")
+	   && gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
+    sig->wrong_key_usage = 1;
+
+  return 0;
+}
+
+
+gpgme_error_t
+_gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+  gpgme_signature_t sig;
+  char *end;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook, -1, NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  sig = opd->current_sig;
+
+  switch (code)
+    {
+    case GPGME_STATUS_NEWSIG:
+      if (sig)
+        calc_sig_summary (sig);
+      err = prepare_new_sig (opd);
+      opd->only_newsig_seen = 1;
+      return err;
+
+    case GPGME_STATUS_GOODSIG:
+    case GPGME_STATUS_EXPSIG:
+    case GPGME_STATUS_EXPKEYSIG:
+    case GPGME_STATUS_BADSIG:
+    case GPGME_STATUS_ERRSIG:
+    case GPGME_STATUS_REVKEYSIG:
+      if (sig && !opd->did_prepare_new_sig)
+	calc_sig_summary (sig);
+      opd->only_newsig_seen = 0;
+      return parse_new_sig (opd, code, args);
+
+    case GPGME_STATUS_VALIDSIG:
+      opd->only_newsig_seen = 0;
+      return sig ? parse_valid_sig (sig, args)
+	: gpg_error (GPG_ERR_INV_ENGINE);
+
+    case GPGME_STATUS_NODATA:
+      opd->only_newsig_seen = 0;
+      if (!sig)
+	return gpg_error (GPG_ERR_NO_DATA);
+      sig->status = gpg_error (GPG_ERR_NO_DATA);
+      break;
+
+    case GPGME_STATUS_UNEXPECTED:
+      opd->only_newsig_seen = 0;
+      if (!sig)
+	return gpg_error (GPG_ERR_GENERAL);
+      sig->status = gpg_error (GPG_ERR_NO_DATA);
+      break;
+
+    case GPGME_STATUS_NOTATION_NAME:
+    case GPGME_STATUS_NOTATION_DATA:
+    case GPGME_STATUS_POLICY_URL:
+      opd->only_newsig_seen = 0;
+      return sig ? parse_notation (sig, code, args)
+	: gpg_error (GPG_ERR_INV_ENGINE);
+
+    case GPGME_STATUS_TRUST_UNDEFINED:
+    case GPGME_STATUS_TRUST_NEVER:
+    case GPGME_STATUS_TRUST_MARGINAL:
+    case GPGME_STATUS_TRUST_FULLY:
+    case GPGME_STATUS_TRUST_ULTIMATE:
+      opd->only_newsig_seen = 0;
+      return sig ? parse_trust (sig, code, args)
+	: gpg_error (GPG_ERR_INV_ENGINE);
+
+    case GPGME_STATUS_PKA_TRUST_BAD:
+    case GPGME_STATUS_PKA_TRUST_GOOD:
+      opd->only_newsig_seen = 0;
+      /* Check that we only get one of these status codes per
+         signature; if not the crypto backend misbehaves.  */
+      if (!sig || sig->pka_trust || sig->pka_address)
+        return gpg_error (GPG_ERR_INV_ENGINE);
+      sig->pka_trust = code == GPGME_STATUS_PKA_TRUST_GOOD? 2 : 1;
+      end = strchr (args, ' ');
+      if (end)
+        *end = 0;
+      sig->pka_address = strdup (args);
+      break;
+
+    case GPGME_STATUS_ERROR:
+      opd->only_newsig_seen = 0;
+      /* Some  error stati are informational, so we don't return an
+         error code if we are not ready to process this status.  */
+      return parse_error (sig, args, !!sig );
+
+    case GPGME_STATUS_EOF:
+      if (sig && !opd->did_prepare_new_sig)
+	calc_sig_summary (sig);
+      if (opd->only_newsig_seen && sig)
+        {
+          gpgme_signature_t sig2;
+          /* The last signature has no valid information - remove it
+             from the list. */
+          assert (!sig->next);
+          if (sig == opd->result.signatures)
+            opd->result.signatures = NULL;
+          else
+            {
+              for (sig2 = opd->result.signatures; sig2; sig2 = sig2->next)
+                if (sig2->next == sig)
+                  {
+                    sig2->next = NULL;
+                    break;
+                  }
+            }
+          /* Note that there is no need to release the members of SIG
+             because we won't be here if they have been set. */
+          free (sig);
+          opd->current_sig = NULL;
+        }
+      opd->only_newsig_seen = 0;
+      break;
+
+    case GPGME_STATUS_PLAINTEXT:
+      if (++opd->plaintext_seen > 1)
+        return gpg_error (GPG_ERR_BAD_DATA);
+      err = _gpgme_parse_plaintext (args, &opd->result.file_name);
+      if (err)
+	return err;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+
+static gpgme_error_t
+verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_progress_status_handler (priv, code, args);
+  if (!err)
+    err = _gpgme_verify_status_handler (priv, code, args);
+  return err;
+}
+
+
+gpgme_error_t
+_gpgme_op_verify_init_result (gpgme_ctx_t ctx)
+{  
+  void *hook;
+  op_data_t opd;
+
+  return _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook,
+				sizeof (*opd), release_op_data);
+}
+
+
+static gpgme_error_t
+verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
+	      gpgme_data_t signed_text, gpgme_data_t plaintext)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  err = _gpgme_op_verify_init_result (ctx);
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, verify_status_handler, ctx);
+
+  if (!sig)
+    return gpg_error (GPG_ERR_NO_DATA);
+  if (!signed_text && !plaintext)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext);
+}
+
+
+/* Decrypt ciphertext CIPHER and make a signature verification within
+   CTX and store the resulting plaintext in PLAIN.  */
+gpgme_error_t
+gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
+		       gpgme_data_t signed_text, gpgme_data_t plaintext)
+{
+  return verify_start (ctx, 0, sig, signed_text, plaintext);
+}
+
+
+/* Decrypt ciphertext CIPHER and make a signature verification within
+   CTX and store the resulting plaintext in PLAIN.  */
+gpgme_error_t
+gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text,
+		 gpgme_data_t plaintext)
+{
+  gpgme_error_t err;
+
+  err = verify_start (ctx, 1, sig, signed_text, plaintext);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
+
+
+/* Compatibility interfaces.  */
+
+/* Get the key used to create signature IDX in CTX and return it in
+   R_KEY.  */
+gpgme_error_t
+gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
+{
+  gpgme_verify_result_t result;
+  gpgme_signature_t sig;
+
+  result = gpgme_op_verify_result (ctx);
+  sig = result->signatures;
+
+  while (sig && idx)
+    {
+      sig = sig->next;
+      idx--;
+    }
+  if (!sig || idx)
+    return gpg_error (GPG_ERR_EOF);
+
+  return gpgme_get_key (ctx, sig->fpr, r_key, 0);
+}
+
+
+/* Retrieve the signature status of signature IDX in CTX after a
+   successful verify operation in R_STAT (if non-null).  The creation
+   time stamp of the signature is returned in R_CREATED (if non-null).
+   The function returns a string containing the fingerprint.  */
+const char *
+gpgme_get_sig_status (gpgme_ctx_t ctx, int idx,
+                      _gpgme_sig_stat_t *r_stat, time_t *r_created)
+{
+  gpgme_verify_result_t result;
+  gpgme_signature_t sig;
+
+  result = gpgme_op_verify_result (ctx);
+  sig = result->signatures;
+
+  while (sig && idx)
+    {
+      sig = sig->next;
+      idx--;
+    }
+  if (!sig || idx)
+    return NULL;
+
+  if (r_stat)
+    {
+      switch (gpg_err_code (sig->status))
+	{
+	case GPG_ERR_NO_ERROR:
+	  *r_stat = GPGME_SIG_STAT_GOOD;
+	  break;
+	  
+	case GPG_ERR_BAD_SIGNATURE:
+	  *r_stat = GPGME_SIG_STAT_BAD;
+	  break;
+	  
+	case GPG_ERR_NO_PUBKEY:
+	  *r_stat = GPGME_SIG_STAT_NOKEY;
+	  break;
+	  
+	case GPG_ERR_NO_DATA:
+	  *r_stat = GPGME_SIG_STAT_NOSIG;
+	  break;
+	  
+	case GPG_ERR_SIG_EXPIRED:
+	  *r_stat = GPGME_SIG_STAT_GOOD_EXP;
+	  break;
+	  
+	case GPG_ERR_KEY_EXPIRED:
+	  *r_stat = GPGME_SIG_STAT_GOOD_EXPKEY;
+	  break;
+	  
+	default:
+	  *r_stat = GPGME_SIG_STAT_ERROR;
+	  break;
+	}
+    }
+  if (r_created)
+    *r_created = sig->timestamp;
+  return sig->fpr;
+}
+
+
+/* Retrieve certain attributes of a signature.  IDX is the index
+   number of the signature after a successful verify operation.  WHAT
+   is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
+   one.  WHATIDX is to be passed as 0 for most attributes . */
+unsigned long 
+gpgme_get_sig_ulong_attr (gpgme_ctx_t ctx, int idx,
+                          _gpgme_attr_t what, int whatidx)
+{
+  gpgme_verify_result_t result;
+  gpgme_signature_t sig;
+
+  result = gpgme_op_verify_result (ctx);
+  sig = result->signatures;
+
+  while (sig && idx)
+    {
+      sig = sig->next;
+      idx--;
+    }
+  if (!sig || idx)
+    return 0;
+
+  switch (what)
+    {
+    case GPGME_ATTR_CREATED:
+      return sig->timestamp;
+
+    case GPGME_ATTR_EXPIRE:
+      return sig->exp_timestamp;
+
+    case GPGME_ATTR_VALIDITY:
+      return (unsigned long) sig->validity;
+
+    case GPGME_ATTR_SIG_STATUS:
+      switch (gpg_err_code (sig->status))
+	{
+	case GPG_ERR_NO_ERROR:
+	  return GPGME_SIG_STAT_GOOD;
+	  
+	case GPG_ERR_BAD_SIGNATURE:
+	  return GPGME_SIG_STAT_BAD;
+	  
+	case GPG_ERR_NO_PUBKEY:
+	  return GPGME_SIG_STAT_NOKEY;
+	  
+	case GPG_ERR_NO_DATA:
+	  return GPGME_SIG_STAT_NOSIG;
+	  
+	case GPG_ERR_SIG_EXPIRED:
+	  return GPGME_SIG_STAT_GOOD_EXP;
+	  
+	case GPG_ERR_KEY_EXPIRED:
+	  return GPGME_SIG_STAT_GOOD_EXPKEY;
+	  
+	default:
+	  return GPGME_SIG_STAT_ERROR;
+	}
+
+    case GPGME_ATTR_SIG_SUMMARY:
+      return sig->summary;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+
+const char *
+gpgme_get_sig_string_attr (gpgme_ctx_t ctx, int idx,
+                           _gpgme_attr_t what, int whatidx)
+{
+  gpgme_verify_result_t result;
+  gpgme_signature_t sig;
+
+  result = gpgme_op_verify_result (ctx);
+  sig = result->signatures;
+
+  while (sig && idx)
+    {
+      sig = sig->next;
+      idx--;
+    }
+  if (!sig || idx)
+    return NULL;
+
+  switch (what)
+    {
+    case GPGME_ATTR_FPR:
+      return sig->fpr;
+
+    case GPGME_ATTR_ERRTOK:
+      if (whatidx == 1)
+        return sig->wrong_key_usage ? "Wrong_Key_Usage" : "";
+      else
+	return "";
+    default:
+      break;
+    }
+
+  return NULL;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/version.c b/libtdenetwork/libgpgme-copy/gpgme/version.c
new file mode 100644
index 000000000..133b23c7e
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/version.c
@@ -0,0 +1,231 @@
+/* version.c - Version check routines.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+
+#include "gpgme.h"
+#include "priv-io.h"
+
+/* For _gpgme_sema_subsystem_init ().  */
+#include "sema.h"
+
+#ifdef HAVE_ASSUAN_H
+#include "assuan.h"
+#endif
+
+
+/* Bootstrap the subsystems needed for concurrent operation.  This
+   must be done once at startup.  We can not guarantee this using a
+   lock, though, because the semaphore subsystem needs to be
+   initialized itself before it can be used.  So we expect that the
+   user performs the necessary syncrhonization.  */
+static void
+do_subsystem_inits (void)
+{
+  static int done = 0;
+
+  if (done)
+    return;
+
+  _gpgme_sema_subsystem_init ();
+  _gpgme_io_subsystem_init ();
+#ifdef HAVE_ASSUAN_H
+  assuan_set_assuan_err_source (GPG_ERR_SOURCE_GPGME);
+#endif
+
+  done = 1;
+}
+
+
+/* Read the next number in the version string STR and return it in
+   *NUMBER.  Return a pointer to the tail of STR after parsing, or
+   *NULL if the version string was invalid.  */
+static const char *
+parse_version_number (const char *str, int *number)
+{
+#define MAXVAL ((INT_MAX - 10) / 10)
+  int val = 0;
+
+  /* Leading zeros are not allowed.  */
+  if (*str == '0' && isdigit(str[1]))
+    return NULL;
+
+  while (isdigit (*str) && val <= MAXVAL)
+    {
+      val *= 10;
+      val += *(str++) - '0';
+    }
+  *number = val;
+  return val > MAXVAL ? NULL : str;
+}
+
+
+/* Parse the version string STR in the format MAJOR.MINOR.MICRO (for
+   example, 9.3.2) and return the components in MAJOR, MINOR and MICRO
+   as integers.  The function returns the tail of the string that
+   follows the version number.  This might be te empty string if there
+   is nothing following the version number, or a patchlevel.  The
+   function returns NULL if the version string is not valid.  */
+static const char *
+parse_version_string (const char *str, int *major, int *minor, int *micro)
+{
+  str = parse_version_number (str, major);
+  if (!str || *str != '.')
+    return NULL;
+  str++;
+
+  str = parse_version_number (str, minor);
+  if (!str || *str != '.')
+    return NULL;
+  str++;
+
+  str = parse_version_number (str, micro);
+  if (!str)
+    return NULL;
+
+  /* A patchlevel might follow.  */
+  return str;
+}
+
+
+/* Return true if MY_VERSION is at least RETQ_VERSION, and false
+   otherwise.  */
+int
+_gpgme_compare_versions (const char *my_version,
+			 const char *rq_version)
+{
+  int my_major, my_minor, my_micro;
+  int rq_major, rq_minor, rq_micro;
+  const char *my_plvl, *rq_plvl;
+
+  if (!rq_version)
+    return 1;
+  if (!my_version)
+    return 0;
+
+  my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
+  if (!my_plvl)
+    return 0;
+
+  rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro);
+  if (!rq_plvl)
+    return 0;
+
+  if (my_major > rq_major
+      || (my_major == rq_major && my_minor > rq_minor)
+      || (my_major == rq_major && my_minor == rq_minor 
+	  && my_micro > rq_micro)
+      || (my_major == rq_major && my_minor == rq_minor
+	  && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
+    return 1;
+
+  return 0;
+}
+
+
+/* Check that the the version of the library is at minimum the
+   requested one and return the version string; return NULL if the
+   condition is not met.  If a NULL is passed to this function, no
+   check is done and the version string is simply returned.
+
+   This function must be run once at startup, as it also initializes
+   some subsystems.  Its invocation must be synchronized against
+   calling any of the other functions in a multi-threaded
+   environments.  */
+const char *
+gpgme_check_version (const char *req_version)
+{
+  do_subsystem_inits ();
+  return _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL;
+}
+
+
+#define LINELENGTH 80
+
+/* Retrieve the version number from the --version output of the
+   program FILE_NAME.  */
+char *
+_gpgme_get_program_version (const char *const file_name)
+{
+  char line[LINELENGTH] = "";
+  int linelen = 0;
+  char *mark = NULL;
+  int rp[2];
+  int nread;
+  char *argv[] = {NULL /* file_name */, "--version", 0};
+  struct spawn_fd_item_s pfd[] = { {0, -1}, {-1, -1} };
+  struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */}, {-1, -1} };
+  int status;
+
+  if (!file_name)
+    return NULL;
+  argv[0] = (char *) file_name;
+
+  if (_gpgme_io_pipe (rp, 1) < 0)
+    return NULL;
+
+  pfd[0].fd = rp[1];
+  cfd[0].fd = rp[1];
+
+  status = _gpgme_io_spawn (file_name, argv, cfd, pfd);
+  if (status < 0)
+    {
+      _gpgme_io_close (rp[0]);
+      _gpgme_io_close (rp[1]);
+      return NULL;
+    }
+
+  do
+    {
+      nread = _gpgme_io_read (rp[0], &line[linelen], LINELENGTH - linelen - 1);
+      if (nread > 0)
+	{
+	  line[linelen + nread] = '\0';
+	  mark = strchr (&line[linelen], '\n');
+	  if (mark)
+	    {
+	      if (mark > &line[0] && *mark == '\r')
+		mark--;
+	      *mark = '\0';
+	      break;
+	    }
+	  linelen += nread;
+	}
+    }
+  while (nread > 0 && linelen < LINELENGTH - 1);
+
+  _gpgme_io_close (rp[0]);
+
+  if (mark)
+    {
+      mark = strrchr (line, ' ');
+      if (!mark)
+	return NULL;
+      return strdup (mark + 1);
+    }
+
+  return NULL;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/w32-io.c b/libtdenetwork/libgpgme-copy/gpgme/w32-io.c
new file mode 100644
index 000000000..677c14e30
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/w32-io.c
@@ -0,0 +1,1152 @@
+/* w32-io.c - W32 API I/O functions.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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 <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <windows.h>
+#include <io.h>
+
+#include "util.h"
+#include "sema.h"
+#include "priv-io.h"
+#include "debug.h"
+
+/* 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))
+
+#define READBUF_SIZE 4096
+#define WRITEBUF_SIZE 4096
+#define PIPEBUF_SIZE  4096
+#define MAX_READERS 20
+#define MAX_WRITERS 20
+
+static struct {
+    int inuse;
+    int fd;
+    void (*handler)(int,void*);
+    void *value;
+} notify_table[256];
+DEFINE_STATIC_LOCK (notify_table_lock);
+
+
+struct reader_context_s {
+    HANDLE file_hd;
+    HANDLE thread_hd;	
+    DECLARE_LOCK (mutex);
+
+    int stop_me;
+    int eof;
+    int eof_shortcut;
+    int error;
+    int error_code;
+
+    HANDLE have_data_ev;  /* manually reset */
+    HANDLE have_space_ev; /* auto reset */
+    HANDLE stopped;
+    size_t readpos, writepos;
+    char buffer[READBUF_SIZE];
+};
+
+
+static struct {
+    volatile int used;
+    int fd;
+    struct reader_context_s *context;
+} reader_table[MAX_READERS];
+static int reader_table_size= MAX_READERS;
+DEFINE_STATIC_LOCK (reader_table_lock);
+
+
+struct writer_context_s {
+    HANDLE file_hd;
+    HANDLE thread_hd;	
+    DECLARE_LOCK (mutex);
+
+    int stop_me;
+    int error;
+    int error_code;
+
+    HANDLE have_data;  /* manually reset */
+    HANDLE is_empty;
+    HANDLE stopped;
+    size_t nbytes; 
+    char buffer[WRITEBUF_SIZE];
+};
+
+
+static struct {
+    volatile int used;
+    int fd;
+    struct writer_context_s *context;
+} writer_table[MAX_WRITERS];
+static int writer_table_size= MAX_WRITERS;
+DEFINE_STATIC_LOCK (writer_table_lock);
+
+
+
+static int
+get_desired_thread_priority (void)
+{
+  int value;
+
+  if (!_gpgme_get_conf_int ("IOThreadPriority", &value))
+    {
+      value = THREAD_PRIORITY_HIGHEST;
+      DEBUG1 ("** Using standard IOThreadPriority of %d\n", value);
+    }
+  else
+    DEBUG1 ("** Configured IOThreadPriority is %d\n", value);
+
+  return value;
+}
+
+
+static HANDLE
+set_synchronize (HANDLE h)
+{
+    HANDLE tmp;
+    
+    /* For NT we have to set the sync flag.  It seems that the only
+     * way to do it is by duplicating the handle.  Tsss.. */
+    if (!DuplicateHandle( GetCurrentProcess(), h,
+                          GetCurrentProcess(), &tmp,
+                          EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, 0 ) ) {
+        DEBUG1 ("** Set SYNCRONIZE failed: ec=%d\n", (int)GetLastError());
+    }
+    else {
+        CloseHandle (h);
+        h = tmp;
+    }
+    return h;
+}
+
+
+
+static DWORD CALLBACK 
+reader (void *arg)
+{
+    struct reader_context_s *c = arg;
+    int nbytes;
+    DWORD nread;
+
+    DEBUG2 ("reader thread %p for file %p started", c->thread_hd, c->file_hd );
+    for (;;) {
+        LOCK (c->mutex);
+        /* leave a 1 byte gap so that we can see whether it is empty or full*/
+        if ((c->writepos + 1) % READBUF_SIZE == c->readpos) { 
+            /* wait for space */
+            if (!ResetEvent (c->have_space_ev) )
+                DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
+            UNLOCK (c->mutex);
+            DEBUG1 ("reader thread %p: waiting for space ...", c->thread_hd );
+            WaitForSingleObject (c->have_space_ev, INFINITE);
+            DEBUG1 ("reader thread %p: got space", c->thread_hd );
+            LOCK (c->mutex);
+       	}
+        if ( c->stop_me ) {
+            UNLOCK (c->mutex);
+            break;
+        }
+        nbytes = (c->readpos + READBUF_SIZE - c->writepos-1) % READBUF_SIZE;
+        if ( nbytes > READBUF_SIZE - c->writepos )
+            nbytes = READBUF_SIZE - c->writepos;
+        UNLOCK (c->mutex);
+
+        DEBUG2 ("reader thread %p: reading %d bytes", c->thread_hd, nbytes );
+        if ( !ReadFile ( c->file_hd,
+                         c->buffer+c->writepos, nbytes, &nread, NULL) ) {
+            c->error_code = (int)GetLastError ();
+            if (c->error_code == ERROR_BROKEN_PIPE ) {
+                c->eof=1;
+                DEBUG1 ("reader thread %p: got eof (broken pipe)",
+                        c->thread_hd );
+            }
+            else {
+                c->error = 1;
+                DEBUG2 ("reader thread %p: read error: ec=%d",
+                        c->thread_hd, c->error_code );
+            }
+            break;
+        }
+        if ( !nread ) {
+            c->eof = 1;
+            DEBUG1 ("reader thread %p: got eof", c->thread_hd );
+            break;
+        }
+        DEBUG2 ("reader thread %p: got %d bytes", c->thread_hd, (int)nread );
+      
+        LOCK (c->mutex);
+        if (c->stop_me) {
+            UNLOCK (c->mutex);
+            break;
+        }
+        c->writepos = (c->writepos + nread) % READBUF_SIZE;
+        if ( !SetEvent (c->have_data_ev) )
+            DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
+        UNLOCK (c->mutex);
+    }
+    /* indicate that we have an error or eof */
+    if ( !SetEvent (c->have_data_ev) )
+        DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
+    DEBUG1 ("reader thread %p ended", c->thread_hd );
+    SetEvent (c->stopped);
+
+    return 0;
+}
+
+
+static struct reader_context_s *
+create_reader (HANDLE fd)
+{
+    struct reader_context_s *c;
+    SECURITY_ATTRIBUTES sec_attr;
+    DWORD tid;
+
+    DEBUG1 ("creating new read thread for file handle %p", fd );
+    memset (&sec_attr, 0, sizeof sec_attr );
+    sec_attr.nLength = sizeof sec_attr;
+    sec_attr.bInheritHandle = FALSE;
+
+    c = calloc (1, sizeof *c );
+    if (!c)
+        return NULL;
+
+    c->file_hd = fd;
+    c->have_data_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
+    c->have_space_ev = CreateEvent (&sec_attr, FALSE, TRUE, NULL);
+    c->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
+    if (!c->have_data_ev || !c->have_space_ev || !c->stopped ) {
+        DEBUG1 ("** CreateEvent failed: ec=%d\n", (int)GetLastError ());
+        if (c->have_data_ev)
+            CloseHandle (c->have_data_ev);
+        if (c->have_space_ev)
+            CloseHandle (c->have_space_ev);
+        if (c->stopped)
+            CloseHandle (c->stopped);
+        free (c);
+        return NULL;
+    }
+
+    c->have_data_ev = set_synchronize (c->have_data_ev);
+    INIT_LOCK (c->mutex);
+
+    c->thread_hd = CreateThread (&sec_attr, 0, reader, c, 0, &tid );
+    if (!c->thread_hd) {
+        DEBUG1 ("** failed to create reader thread: ec=%d\n",
+                 (int)GetLastError ());
+        DESTROY_LOCK (c->mutex);
+        if (c->have_data_ev)
+            CloseHandle (c->have_data_ev);
+        if (c->have_space_ev)
+            CloseHandle (c->have_space_ev);
+        if (c->stopped)
+            CloseHandle (c->stopped);
+        free (c);
+        return NULL;
+    }    
+    else {
+      /* We set the priority of the thread higher because we know that
+         it only runs for a short time.  This greatly helps to increase
+         the performance of the I/O. */
+      SetThreadPriority (c->thread_hd, get_desired_thread_priority ());
+    }
+
+    return c;
+}
+
+static void
+destroy_reader (struct reader_context_s *c)
+{
+    LOCK (c->mutex);
+    c->stop_me = 1;
+    if (c->have_space_ev) 
+        SetEvent (c->have_space_ev);
+    UNLOCK (c->mutex);
+
+    DEBUG1 ("waiting for thread %p termination ...", c->thread_hd );
+    WaitForSingleObject (c->stopped, INFINITE);
+    DEBUG1 ("thread %p has terminated", c->thread_hd );
+    
+    if (c->stopped)
+        CloseHandle (c->stopped);
+    if (c->have_data_ev)
+        CloseHandle (c->have_data_ev);
+    if (c->have_space_ev)
+        CloseHandle (c->have_space_ev);
+    CloseHandle (c->thread_hd);
+    DESTROY_LOCK (c->mutex);
+    free (c);
+}
+
+
+/* 
+ * Find a reader context or create a new one 
+ * Note that the reader context will last until a io_close.
+ */
+static struct reader_context_s *
+find_reader (int fd, int start_it)
+{
+    int i;
+
+    for (i=0; i < reader_table_size ; i++ ) {
+        if ( reader_table[i].used && reader_table[i].fd == fd )
+            return reader_table[i].context;
+    }
+    if (!start_it)
+        return NULL;
+
+    LOCK (reader_table_lock);
+    for (i=0; i < reader_table_size; i++ ) {
+        if (!reader_table[i].used) {
+            reader_table[i].fd = fd;
+            reader_table[i].context = create_reader (fd_to_handle (fd));
+            reader_table[i].used = 1;
+            UNLOCK (reader_table_lock);
+            return reader_table[i].context;
+        }
+    }
+    UNLOCK (reader_table_lock);
+    return NULL;
+}
+
+
+static void
+kill_reader (int fd)
+{
+    int i;
+
+    LOCK (reader_table_lock);
+    for (i=0; i < reader_table_size; i++ ) {
+        if (reader_table[i].used && reader_table[i].fd == fd ) {
+            destroy_reader (reader_table[i].context);
+            reader_table[i].context = NULL;
+            reader_table[i].used = 0;
+            break;
+        }
+    }
+    UNLOCK (reader_table_lock);
+}
+
+
+
+int
+_gpgme_io_read ( int fd, void *buffer, size_t count )
+{
+    int nread;
+    struct reader_context_s *c = find_reader (fd,1);
+
+    DEBUG2 ("fd %d: about to read %d bytes\n", fd, (int)count );
+    if ( !c ) {
+        DEBUG0 ( "no reader thread\n");
+        return -1;
+    }
+    if (c->eof_shortcut) {
+        DEBUG1 ("fd %d: EOF (again)", fd );
+        return 0;
+    }
+
+    LOCK (c->mutex);
+    if (c->readpos == c->writepos && !c->error) { /*no data avail*/
+        UNLOCK (c->mutex);
+        DEBUG2 ("fd %d: waiting for data from thread %p", fd, c->thread_hd);
+        WaitForSingleObject (c->have_data_ev, INFINITE);
+        DEBUG2 ("fd %d: data from thread %p available", fd, c->thread_hd);
+        LOCK (c->mutex);
+    }
+    
+    if (c->readpos == c->writepos || c->error) {
+        UNLOCK (c->mutex);
+        c->eof_shortcut = 1;
+        if (c->eof) {
+            DEBUG1 ("fd %d: EOF", fd );
+            return 0;
+        }
+        if (!c->error) {
+            DEBUG1 ("fd %d: EOF but eof flag not set", fd );
+            return 0;
+        }
+        DEBUG1 ("fd %d: read error", fd );
+        return -1;
+    }
+      
+    nread = c->readpos < c->writepos? c->writepos - c->readpos
+                                    : READBUF_SIZE - c->readpos;
+    if (nread > count)
+        nread = count;
+    memcpy (buffer, c->buffer+c->readpos, nread);
+    c->readpos = (c->readpos + nread) % READBUF_SIZE;
+    if (c->readpos == c->writepos && !c->eof) {
+        if ( !ResetEvent (c->have_data_ev) )
+            DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
+    }
+    if (!SetEvent (c->have_space_ev))
+        DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
+    UNLOCK (c->mutex);
+
+    DEBUG2 ("fd %d: got %d bytes\n", fd, nread );
+    if (nread > 0)
+      _gpgme_debug (2, "fd %d: got `%.*s'\n", fd, nread, buffer);
+
+    return nread;
+}
+/*
+ * The writer does use a simple buffering strategy so that we are
+ * informed about write errors as soon as possible (i.e. with the the
+ * next call to the write function
+ */
+static DWORD CALLBACK 
+writer (void *arg)
+{
+    struct writer_context_s *c = arg;
+    DWORD nwritten;
+
+    DEBUG2 ("writer thread %p for file %p started", c->thread_hd, c->file_hd );
+    for (;;) {
+        LOCK (c->mutex);
+        if ( c->stop_me ) {
+            UNLOCK (c->mutex);
+            break;
+        }
+        if ( !c->nbytes ) { 
+            if (!SetEvent (c->is_empty))
+                DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
+            if (!ResetEvent (c->have_data) )
+                DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
+            UNLOCK (c->mutex);
+            DEBUG1 ("writer thread %p: idle ...", c->thread_hd );
+            WaitForSingleObject (c->have_data, INFINITE);
+            DEBUG1 ("writer thread %p: got data to send", c->thread_hd );
+            LOCK (c->mutex);
+       	}
+        if ( c->stop_me ) {
+            UNLOCK (c->mutex);
+            break;
+        }
+        UNLOCK (c->mutex);
+
+        DEBUG2 ("writer thread %p: writing %d bytes",
+                c->thread_hd, c->nbytes );
+        if ( c->nbytes && !WriteFile ( c->file_hd,  c->buffer, c->nbytes,
+                                       &nwritten, NULL)) {
+            c->error_code = (int)GetLastError ();
+            c->error = 1;
+            DEBUG2 ("writer thread %p: write error: ec=%d",
+                    c->thread_hd, c->error_code );
+            break;
+        }
+        DEBUG2 ("writer thread %p: wrote %d bytes",
+                c->thread_hd, (int)nwritten );
+      
+        LOCK (c->mutex);
+        c->nbytes -= nwritten;
+        UNLOCK (c->mutex);
+    }
+    /* indicate that we have an error  */
+    if ( !SetEvent (c->is_empty) )
+        DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
+    DEBUG1 ("writer thread %p ended", c->thread_hd );
+    SetEvent (c->stopped);
+
+    return 0;
+}
+
+
+static struct writer_context_s *
+create_writer (HANDLE fd)
+{
+    struct writer_context_s *c;
+    SECURITY_ATTRIBUTES sec_attr;
+    DWORD tid;
+
+    DEBUG1 ("creating new write thread for file handle %p", fd );
+    memset (&sec_attr, 0, sizeof sec_attr );
+    sec_attr.nLength = sizeof sec_attr;
+    sec_attr.bInheritHandle = FALSE;
+
+    c = calloc (1, sizeof *c );
+    if (!c)
+        return NULL;
+
+    c->file_hd = fd;
+    c->have_data = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
+    c->is_empty  = CreateEvent (&sec_attr, TRUE, TRUE, NULL);
+    c->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
+    if (!c->have_data || !c->is_empty || !c->stopped ) {
+        DEBUG1 ("** CreateEvent failed: ec=%d\n", (int)GetLastError ());
+        if (c->have_data)
+            CloseHandle (c->have_data);
+        if (c->is_empty)
+            CloseHandle (c->is_empty);
+        if (c->stopped)
+            CloseHandle (c->stopped);
+        free (c);
+        return NULL;
+    }
+
+    c->is_empty = set_synchronize (c->is_empty);
+    INIT_LOCK (c->mutex);
+
+    c->thread_hd = CreateThread (&sec_attr, 0, writer, c, 0, &tid );
+    if (!c->thread_hd) {
+        DEBUG1 ("** failed to create writer thread: ec=%d\n",
+                 (int)GetLastError ());
+        DESTROY_LOCK (c->mutex);
+        if (c->have_data)
+            CloseHandle (c->have_data);
+        if (c->is_empty)
+            CloseHandle (c->is_empty);
+        if (c->stopped)
+            CloseHandle (c->stopped);
+        free (c);
+        return NULL;
+    }    
+    else {
+      /* We set the priority of the thread higher because we know that
+         it only runs for a short time.  This greatly helps to increase
+         the performance of the I/O. */
+      SetThreadPriority (c->thread_hd, get_desired_thread_priority ());
+    }
+
+    return c;
+}
+
+static void
+destroy_writer (struct writer_context_s *c)
+{
+    LOCK (c->mutex);
+    c->stop_me = 1;
+    if (c->have_data) 
+        SetEvent (c->have_data);
+    UNLOCK (c->mutex);
+
+    DEBUG1 ("waiting for thread %p termination ...", c->thread_hd );
+    WaitForSingleObject (c->stopped, INFINITE);
+    DEBUG1 ("thread %p has terminated", c->thread_hd );
+    
+    if (c->stopped)
+        CloseHandle (c->stopped);
+    if (c->have_data)
+        CloseHandle (c->have_data);
+    if (c->is_empty)
+        CloseHandle (c->is_empty);
+    CloseHandle (c->thread_hd);
+    DESTROY_LOCK (c->mutex);
+    free (c);
+}
+
+
+/* 
+ * Find a writer context or create a new one 
+ * Note that the writer context will last until a io_close.
+ */
+static struct writer_context_s *
+find_writer (int fd, int start_it)
+{
+    int i;
+
+    for (i=0; i < writer_table_size ; i++ ) {
+        if ( writer_table[i].used && writer_table[i].fd == fd )
+            return writer_table[i].context;
+    }
+    if (!start_it)
+        return NULL;
+
+    LOCK (writer_table_lock);
+    for (i=0; i < writer_table_size; i++ ) {
+        if (!writer_table[i].used) {
+            writer_table[i].fd = fd;
+            writer_table[i].context = create_writer (fd_to_handle (fd));
+            writer_table[i].used = 1;
+            UNLOCK (writer_table_lock);
+            return writer_table[i].context;
+        }
+    }
+    UNLOCK (writer_table_lock);
+    return NULL;
+}
+
+
+static void
+kill_writer (int fd)
+{
+    int i;
+
+    LOCK (writer_table_lock);
+    for (i=0; i < writer_table_size; i++ ) {
+        if (writer_table[i].used && writer_table[i].fd == fd ) {
+            destroy_writer (writer_table[i].context);
+            writer_table[i].context = NULL;
+            writer_table[i].used = 0;
+            break;
+        }
+    }
+    UNLOCK (writer_table_lock);
+}
+
+
+
+
+int
+_gpgme_io_write ( int fd, const void *buffer, size_t count )
+{
+    struct writer_context_s *c = find_writer (fd,1);
+
+    DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int)count );
+    _gpgme_debug (2, "fd %d: write `%.*s'\n", fd, (int) count, buffer);
+    if ( !c ) {
+        DEBUG0 ( "no writer thread\n");
+        return -1;
+    }
+
+    LOCK (c->mutex);
+    if ( c->nbytes ) { /* bytes are pending for send */
+        /* Reset the is_empty event.  Better safe than sorry.  */
+        if (!ResetEvent (c->is_empty))
+            DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
+        UNLOCK (c->mutex);
+        DEBUG2 ("fd %d: waiting for empty buffer in thread %p",
+                fd, c->thread_hd);
+        WaitForSingleObject (c->is_empty, INFINITE);
+        DEBUG2 ("fd %d: thread %p buffer is empty", fd, c->thread_hd);
+        LOCK (c->mutex);
+    }
+    
+    if ( c->error) {
+        UNLOCK (c->mutex);
+        DEBUG1 ("fd %d: write error", fd );
+        return -1;
+    }
+
+    /* If no error occured, the number of bytes in the buffer must be
+       zero.  */
+    assert (!c->nbytes);
+
+    if (count > WRITEBUF_SIZE)
+        count = WRITEBUF_SIZE;
+    memcpy (c->buffer, buffer, count);
+    c->nbytes = count;
+
+    /* We have to reset the is_empty event early, because it is also
+       used by the select() implementation to probe the channel.  */
+    if (!ResetEvent (c->is_empty))
+        DEBUG1 ("ResetEvent failed: ec=%d", (int)GetLastError ());
+    if (!SetEvent (c->have_data))
+        DEBUG1 ("SetEvent failed: ec=%d", (int)GetLastError ());
+    UNLOCK (c->mutex);
+
+    DEBUG2 ("fd %d:         copied %d bytes\n",
+                   fd, (int)count );
+    return (int)count;
+}
+
+
+int
+_gpgme_io_pipe ( int filedes[2], int inherit_idx )
+{
+    HANDLE r, w;
+    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, PIPEBUF_SIZE))
+        return -1;
+    /* Make one end inheritable. */
+    if ( inherit_idx == 0 ) {
+        HANDLE h;
+        if (!DuplicateHandle( GetCurrentProcess(), r,
+                              GetCurrentProcess(), &h, 0,
+                              TRUE, DUPLICATE_SAME_ACCESS ) ) {
+            DEBUG1 ("DuplicateHandle failed: ec=%d\n", (int)GetLastError());
+            CloseHandle (r);
+            CloseHandle (w);
+            return -1;
+        }
+        CloseHandle (r);
+        r = h;
+    }
+    else if ( inherit_idx == 1 ) {
+        HANDLE h;
+        if (!DuplicateHandle( GetCurrentProcess(), w,
+                              GetCurrentProcess(), &h, 0,
+                              TRUE, DUPLICATE_SAME_ACCESS ) ) {
+            DEBUG1 ("DuplicateHandle failed: ec=%d\n", (int)GetLastError());
+            CloseHandle (r);
+            CloseHandle (w);
+            return -1;
+        }
+        CloseHandle (w);
+        w = h;
+    }
+
+    filedes[0] = handle_to_fd (r);
+    filedes[1] = handle_to_fd (w);
+    DEBUG5 ("CreatePipe %p %p %d %d inherit=%d\n", r, w,
+                   filedes[0], filedes[1], inherit_idx );
+    return 0;
+}
+
+int
+_gpgme_io_close ( int fd )
+{
+    int i;
+    void (*handler)(int, void*) = NULL;
+    void *value = NULL;
+
+    if ( fd == -1 )
+        return -1;
+
+    DEBUG1 ("** closing handle for fd %d\n", fd);
+    kill_reader (fd);
+    kill_writer (fd);
+    LOCK (notify_table_lock);
+    for ( i=0; i < DIM (notify_table); i++ ) {
+        if (notify_table[i].inuse && notify_table[i].fd == fd) {
+            handler = notify_table[i].handler;
+            value   = notify_table[i].value;
+            notify_table[i].handler = NULL;
+            notify_table[i].value = NULL;
+            notify_table[i].inuse = 0;
+            break;
+        }
+    }
+    UNLOCK (notify_table_lock);
+    if (handler)
+        handler (fd, value);
+
+    if ( !CloseHandle (fd_to_handle (fd)) ) { 
+        DEBUG2 ("CloseHandle for fd %d failed: ec=%d\n",
+                 fd, (int)GetLastError ());
+        return -1;
+    }
+
+    return 0;
+}
+
+int
+_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value)
+{
+    int i;
+
+    assert (fd != -1);
+
+    LOCK (notify_table_lock);
+    for (i=0; i < DIM (notify_table); i++ ) {
+        if ( notify_table[i].inuse && notify_table[i].fd == fd )
+            break;
+    }
+    if ( i == DIM (notify_table) ) {
+        for (i=0; i < DIM (notify_table); i++ ) {
+            if ( !notify_table[i].inuse )
+                break;
+        }
+    }
+    if ( i == DIM (notify_table) ) {
+        UNLOCK (notify_table_lock);
+        return -1;
+    }
+    notify_table[i].fd = fd;
+    notify_table[i].handler = handler;
+    notify_table[i].value = value;
+    notify_table[i].inuse = 1;
+    UNLOCK (notify_table_lock);
+    DEBUG2 ("set notification for fd %d (idx=%d)", fd, i );
+    return 0;
+}
+
+
+int
+_gpgme_io_set_nonblocking ( int fd )
+{
+    return 0;
+}
+
+
+static char *
+build_commandline (char **argv)
+{
+  int i;
+  int j;
+  int n = 0;
+  char *buf;
+  char *p;
+  
+  /* We have to quote some things because under Windows the program
+     parses the commandline and does some unquoting.  We enclose the
+     whole argument in double-quotes, and escape literal double-quotes
+     as well as backslashes with a backslash.  We end up with a
+     trailing space at the end of the line, but that is harmless.  */
+  for (i = 0; argv[i]; i++)
+    {
+      p = argv[i];
+      /* The leading double-quote.  */
+      n++;
+      while (*p)
+	{
+	  /* An extra one for each literal that must be escaped.  */
+	  if (*p == '\\' || *p == '"')
+	    n++;
+	  n++;
+	  p++;
+	}
+      /* The trailing double-quote and the delimiter.  */
+      n += 2;
+    }
+  /* And a trailing zero.  */
+  n++;
+
+  buf = p = malloc (n);
+  if (!buf)
+    return NULL;
+  for (i = 0; argv[i]; i++)
+    {
+      char *argvp = argv[i];
+
+      *(p++) = '"';
+      while (*argvp)
+	{
+	  if (*argvp == '\\' || *argvp == '"')
+	    *(p++) = '\\';
+	  *(p++) = *(argvp++);
+	}
+      *(p++) = '"';
+      *(p++) = ' ';
+    }
+  *(p++) = 0;
+
+  return buf;
+}
+
+
+int
+_gpgme_io_spawn ( const char *path, char **argv,
+                  struct spawn_fd_item_s *fd_child_list,
+                  struct spawn_fd_item_s *fd_parent_list )
+{
+    SECURITY_ATTRIBUTES sec_attr;
+    PROCESS_INFORMATION pi = {
+        NULL,      /* returns process handle */
+        0,         /* returns primary thread handle */
+        0,         /* returns pid */
+        0         /* returns tid */
+    };
+    STARTUPINFO si;
+    char *envblock = NULL;
+    int cr_flags = CREATE_DEFAULT_ERROR_MODE
+                 | GetPriorityClass (GetCurrentProcess ());
+    int i;
+    char *arg_string;
+    int duped_stdin = 0;
+    int duped_stderr = 0;
+    HANDLE hnul = INVALID_HANDLE_VALUE;
+    /* FIXME.  */
+    int debug_me = 0;
+
+    memset (&sec_attr, 0, sizeof sec_attr );
+    sec_attr.nLength = sizeof sec_attr;
+    sec_attr.bInheritHandle = FALSE;
+
+    arg_string = build_commandline ( argv );
+    if (!arg_string )
+        return -1; 
+
+    memset (&si, 0, sizeof si);
+    si.cb = sizeof (si);
+    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+    si.wShowWindow = debug_me? SW_SHOW : SW_HIDE;
+    si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+    si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+    si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
+
+    for (i=0; fd_child_list[i].fd != -1; i++ ) {
+        if (fd_child_list[i].dup_to == 0 ) {
+            si.hStdInput = fd_to_handle (fd_child_list[i].fd);
+            DEBUG1 ("using %d for stdin", fd_child_list[i].fd );
+            duped_stdin=1;
+        }
+        else if (fd_child_list[i].dup_to == 1 ) {
+            si.hStdOutput = fd_to_handle (fd_child_list[i].fd);
+            DEBUG1 ("using %d for stdout", fd_child_list[i].fd );
+        }
+        else if (fd_child_list[i].dup_to == 2 ) {
+            si.hStdError = fd_to_handle (fd_child_list[i].fd);
+            DEBUG1 ("using %d for stderr", fd_child_list[i].fd );
+            duped_stderr = 1;
+        }
+    }
+
+    if( !duped_stdin || !duped_stderr ) {
+        SECURITY_ATTRIBUTES sa;
+
+        memset (&sa, 0, sizeof sa );
+        sa.nLength = sizeof sa;
+        sa.bInheritHandle = TRUE;
+        hnul = CreateFile ( "nul",
+                            GENERIC_READ|GENERIC_WRITE,
+                            FILE_SHARE_READ|FILE_SHARE_WRITE,
+                            &sa,
+                            OPEN_EXISTING,
+                            FILE_ATTRIBUTE_NORMAL,
+                            NULL );
+        if ( hnul == INVALID_HANDLE_VALUE ) {
+            DEBUG1 ("can't open `nul': ec=%d\n", (int)GetLastError ());
+            free (arg_string);
+            return -1;
+        }
+        /* Make sure that the process has a connected stdin */
+        if ( !duped_stdin ) {
+            si.hStdInput = hnul;
+            DEBUG1 ("using %d for dummy stdin", (int)hnul );
+        }
+        /* We normally don't want all the normal output */
+        if ( !duped_stderr ) {
+            si.hStdError = hnul;
+            DEBUG1 ("using %d for dummy stderr", (int)hnul );
+        }
+    }
+
+    DEBUG2 ("CreateProcess, path=`%s' args=`%s'", path, arg_string);
+    cr_flags |= CREATE_SUSPENDED; 
+    if ( !CreateProcessA (path,
+                          arg_string,
+                          &sec_attr,     /* process security attributes */
+                          &sec_attr,     /* thread security attributes */
+                          TRUE,          /* inherit handles */
+                          cr_flags,      /* creation flags */
+                          envblock,      /* environment */
+                          NULL,          /* use current drive/directory */
+                          &si,           /* startup information */
+                          &pi            /* returns process information */
+        ) ) {
+        DEBUG1 ("CreateProcess failed: ec=%d\n", (int) GetLastError ());
+        free (arg_string);
+        return -1;
+    }
+
+    /* Close the /dev/nul handle if used. */
+    if (hnul != INVALID_HANDLE_VALUE ) {
+        if ( !CloseHandle ( hnul ) )
+            DEBUG1 ("CloseHandle(hnul) failed: ec=%d\n", (int)GetLastError());
+    }
+
+    /* Close the other ends of the pipes. */
+    for (i = 0; fd_parent_list[i].fd != -1; i++)
+      _gpgme_io_close (fd_parent_list[i].fd);
+
+    DEBUG4 ("CreateProcess ready\n"
+            "-   hProcess=%p  hThread=%p\n"
+            "-   dwProcessID=%d dwThreadId=%d\n",
+            pi.hProcess, pi.hThread, 
+            (int) pi.dwProcessId, (int) pi.dwThreadId);
+
+    if ( ResumeThread ( pi.hThread ) < 0 ) {
+        DEBUG1 ("ResumeThread failed: ec=%d\n", (int)GetLastError ());
+    }
+
+    if ( !CloseHandle (pi.hThread) ) { 
+        DEBUG1 ("CloseHandle of thread failed: ec=%d\n",
+                 (int)GetLastError ());
+    }
+
+    return handle_to_pid (pi.hProcess);
+}
+
+
+/*
+ * Select on the list of fds.
+ * Returns: -1 = error
+ *           0 = timeout or nothing to select
+ *          >0 = number of signaled fds
+ */
+int
+_gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds, int nonblock )
+{
+    HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS];
+    int    waitidx[MAXIMUM_WAIT_OBJECTS];
+    int code, nwait;
+    int i, any;
+    int count;
+    void *dbg_help;
+
+ restart:
+    DEBUG_BEGIN (dbg_help, 3, "select on [ ");
+    any = 0;
+    nwait = 0;
+    count = 0;
+    for ( i=0; i < nfds; i++ ) {
+        if ( fds[i].fd == -1 ) 
+            continue;
+        fds[i].signaled = 0;
+        if ( fds[i].for_read || fds[i].for_write ) {
+            if ( fds[i].frozen ) {
+                DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd );
+            }
+            else if ( fds[i].for_read ) {
+                struct reader_context_s *c = find_reader (fds[i].fd,1);
+                
+                if (!c) { 
+                    DEBUG1 ("oops: no reader thread for fd %d", fds[i].fd);
+                }
+                else {
+                    if ( nwait >= DIM (waitbuf) ) {
+                        DEBUG_END (dbg_help, "oops ]");
+                        DEBUG0 ("Too many objects for WFMO!" );
+                        return -1;
+                    }
+                    waitidx[nwait]   = i;
+                    waitbuf[nwait++] = c->have_data_ev;
+                }
+                DEBUG_ADD1 (dbg_help, "r%d ", fds[i].fd );
+                any = 1;
+            }
+            else if ( fds[i].for_write ) {
+                struct writer_context_s *c = find_writer (fds[i].fd,1);
+                
+                if (!c) { 
+                    DEBUG1 ("oops: no writer thread for fd %d", fds[i].fd);
+                }
+                else {
+                    if ( nwait >= DIM (waitbuf) ) {
+                        DEBUG_END (dbg_help, "oops ]");
+                        DEBUG0 ("Too many objects for WFMO!" );
+                        return -1;
+                    }
+		    waitidx[nwait]   = i;
+		    waitbuf[nwait++] = c->is_empty;
+                }
+		DEBUG_ADD1 (dbg_help, "w%d ", fds[i].fd );
+		any = 1;
+            }
+        }
+    }
+    DEBUG_END (dbg_help, "]");
+    if (!any) 
+        return 0;
+
+    code = WaitForMultipleObjects ( nwait, waitbuf, 0, nonblock ? 0 : 1000);
+    if ( code >= WAIT_OBJECT_0 && code < WAIT_OBJECT_0 + nwait ) {
+        /* This WFMO is a really silly function:  It does return either
+         * the index of the signaled object or if 2 objects have been
+         * signalled at the same time, the index of the object with the
+         * lowest object is returned - so and how do we find out
+         * how many objects have been signaled???.
+         * The only solution I can imagine is to test each object starting
+         * with the returned index individually - how dull.
+         */
+        any = 0;
+        for (i=code - WAIT_OBJECT_0; i < nwait; i++ ) {
+            if (WaitForSingleObject (waitbuf[i], 0) == WAIT_OBJECT_0) {
+                assert (waitidx[i] >=0 && waitidx[i] < nfds);
+                fds[waitidx[i]].signaled = 1;
+                any = 1;
+                count++;
+            }
+        }
+        if (!any) {
+            DEBUG0 ("Oops: No signaled objects found after WFMO");
+            count = -1;
+        }
+    }
+    else if ( code == WAIT_TIMEOUT ) {
+        DEBUG0 ("WFMO timed out\n" );
+    }  
+    else if (code == WAIT_FAILED ) {
+        int le = (int)GetLastError ();
+        if ( le == ERROR_INVALID_HANDLE ) {
+            int k, j = handle_to_fd (waitbuf[i]);
+                    
+            DEBUG1 ("WFMO invalid handle %d removed\n", j);
+            for (k=0 ; k < nfds; k++ ) {
+                if ( fds[k].fd == j ) {
+                    fds[k].for_read = fds[k].for_write = 0;
+                    goto restart;
+                }
+            }
+            DEBUG0 (" oops, or not???\n");
+        }
+        DEBUG1 ("WFMO failed: %d\n", le );
+        count = -1;
+    }
+    else {
+        DEBUG1 ("WFMO returned %d\n", code );
+        count = -1;
+    }
+
+    if ( count ) {
+        DEBUG_BEGIN (dbg_help, 3, " signaled [ ");
+        for ( i=0; i < nfds; i++ ) {
+            if ( fds[i].fd == -1 ) 
+                continue;
+            if ( (fds[i].for_read || fds[i].for_write) && fds[i].signaled ) {
+                DEBUG_ADD2 (dbg_help, "%c%d ",
+                            fds[i].for_read? 'r':'w',fds[i].fd );
+            }
+        }
+        DEBUG_END (dbg_help, "]");
+    }
+    
+    return count;
+}
+
+void
+_gpgme_io_subsystem_init (void)
+{
+  
+}
+
+
+/* Write the printable version of FD to the buffer BUF of length
+   BUFLEN.  The printable version is the representation on the command
+   line that the child process expects.  */
+int
+_gpgme_io_fd2str (char *buf, int buflen, int fd)
+{
+  return snprintf (buf, buflen, "%d", fd);
+}
+
+
+/* The following interface is only useful for GPGME Glib.  */
+
+/* Look up the giochannel for file descriptor FD.  */
+void *
+gpgme_get_giochannel (int fd)
+{
+  return NULL;
+}
+
diff --git a/libtdenetwork/libgpgme-copy/gpgme/w32-sema.c b/libtdenetwork/libgpgme-copy/gpgme/w32-sema.c
new file mode 100644
index 000000000..2b20cab3e
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/w32-sema.c
@@ -0,0 +1,115 @@
+/* w32-sema.c 
+   Copyright (C) 2001 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2004 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 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.
+   
+   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
+   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 <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <windows.h>
+#include <io.h>
+
+#include "util.h"
+#include "sema.h"
+#include "debug.h"
+
+static void
+sema_fatal (const char *text)
+{
+    fprintf (stderr, "sema.c: %s\n", text);
+    abort ();
+}
+
+
+static void
+critsect_init (struct critsect_s *s)
+{
+    CRITICAL_SECTION *mp;
+    static CRITICAL_SECTION init_lock;
+    static int initialized;
+    
+    if (!initialized) {
+        /* The very first time we call this function, we assume that
+	   only one thread is running, so that we can bootstrap the
+	   semaphore code.  */
+        InitializeCriticalSection (&init_lock);
+        initialized = 1;
+    }
+    if (!s)
+        return; /* we just want to initialize ourself */
+
+    /* first test whether it is really not initialized */
+    EnterCriticalSection (&init_lock);
+    if ( s->private ) {
+        LeaveCriticalSection (&init_lock);
+        return;
+    }
+    /* now init it */
+    mp = malloc ( sizeof *mp );
+    if (!mp) {
+        LeaveCriticalSection (&init_lock);
+        sema_fatal ("out of core while creating critical section lock");
+    }
+    InitializeCriticalSection (mp);
+    s->private = mp;
+    LeaveCriticalSection (&init_lock);
+}
+
+void
+_gpgme_sema_subsystem_init ()
+{
+    /* fixme: we should check that there is only one thread running */
+    critsect_init (NULL);
+}
+
+
+void
+_gpgme_sema_cs_enter ( struct critsect_s *s )
+{
+    if (!s->private)
+        critsect_init (s);
+    EnterCriticalSection ( (CRITICAL_SECTION*)s->private );
+}
+
+void
+_gpgme_sema_cs_leave (struct critsect_s *s)
+{
+    if (!s->private)
+        critsect_init (s);
+    LeaveCriticalSection ((CRITICAL_SECTION*)s->private);
+}
+
+void
+_gpgme_sema_cs_destroy ( struct critsect_s *s )
+{
+    if (s && s->private) {
+        DeleteCriticalSection ((CRITICAL_SECTION*)s->private);
+        free (s->private);
+        s->private = NULL;
+    }
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/w32-util.c b/libtdenetwork/libgpgme-copy/gpgme/w32-util.c
new file mode 100644
index 000000000..646f4a009
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/w32-util.c
@@ -0,0 +1,317 @@
+/* w32-util.c - Utility functions for the W32 API
+   Copyright (C) 1999 Free Software Foundation, Inc
+   Copyright (C) 2001 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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 <assert.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <windows.h>
+#include <shlobj.h>
+#include <io.h>
+
+#include "util.h"
+#include "sema.h"
+#include "debug.h"
+
+DEFINE_STATIC_LOCK (get_path_lock);
+
+
+#define RTLD_LAZY 0
+
+static __inline__ void *
+dlopen (const char * name, int flag)
+{
+  void * hd = LoadLibrary (name);
+  return hd;
+}
+
+static __inline__ void *
+dlsym (void * hd, const char * sym)
+{
+  if (hd && sym)
+    {
+      void * fnc = GetProcAddress (hd, sym);
+      if (!fnc)
+        return NULL;
+      return fnc;
+    }
+  return NULL;
+}
+
+static __inline__ int
+dlclose (void * hd)
+{
+  if (hd)
+    {
+      FreeLibrary (hd);
+      return 0;
+    }
+  return -1;
+}  
+
+
+/* Return a string from the W32 Registry or NULL in case of error.
+   Caller must release the return value.  A NULL for root is an alias
+   for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */
+static char *
+read_w32_registry_string (const char *root, const char *dir, const char *name)
+{
+  HKEY root_key, key_handle;
+  DWORD n1, nbytes, type;
+  char *result = NULL;
+	
+  if ( !root )
+    root_key = HKEY_CURRENT_USER;
+  else if ( !strcmp( root, "HKEY_CLASSES_ROOT" ) )
+    root_key = HKEY_CLASSES_ROOT;
+  else if ( !strcmp( root, "HKEY_CURRENT_USER" ) )
+    root_key = HKEY_CURRENT_USER;
+  else if ( !strcmp( root, "HKEY_LOCAL_MACHINE" ) )
+    root_key = HKEY_LOCAL_MACHINE;
+  else if ( !strcmp( root, "HKEY_USERS" ) )
+    root_key = HKEY_USERS;
+  else if ( !strcmp( root, "HKEY_PERFORMANCE_DATA" ) )
+    root_key = HKEY_PERFORMANCE_DATA;
+  else if ( !strcmp( root, "HKEY_CURRENT_CONFIG" ) )
+    root_key = HKEY_CURRENT_CONFIG;
+  else
+    return NULL;
+	
+  if ( RegOpenKeyEx ( root_key, dir, 0, KEY_READ, &key_handle ) )
+    {
+      if (root)
+        return NULL; /* no need for a RegClose, so return direct */
+      /* It seems to be common practise to fall back to HKLM. */
+      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) )
+        return NULL; /* still no need for a RegClose, so return direct */
+    }
+
+  nbytes = 1;
+  if ( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) )
+    {
+      if (root)
+        goto leave;
+      /* Try to fallback to HKLM also vor a missing value.  */
+      RegCloseKey (key_handle);
+      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) )
+        return NULL; /* Nope.  */
+      if (RegQueryValueEx ( key_handle, name, 0, NULL, NULL, &nbytes))
+        goto leave;
+    }
+  result = malloc ( (n1=nbytes+1) );
+  if ( !result )
+    goto leave;
+  if ( RegQueryValueEx ( key_handle, name, 0, &type, result, &n1 ) )
+    {
+      free(result); result = NULL;
+      goto leave;
+    }
+  result[nbytes] = 0; /* Make sure it is really a string.  */
+  if (type == REG_EXPAND_SZ && strchr (result, '%')) 
+    {
+      char *tmp;
+        
+      n1 += 1000;
+      tmp = malloc (n1+1);
+      if (!tmp)
+        goto leave;
+      nbytes = ExpandEnvironmentStrings (result, tmp, n1);
+      if (nbytes && nbytes > n1)
+        {
+          free (tmp);
+          n1 = nbytes;
+          tmp = malloc (n1 + 1);
+          if (!tmp)
+            goto leave;
+          nbytes = ExpandEnvironmentStrings (result, tmp, n1);
+          if (nbytes && nbytes > n1) {
+            free (tmp); /* Oops - truncated, better don't expand at all. */
+            goto leave;
+          }
+          tmp[nbytes] = 0;
+          free (result);
+          result = tmp;
+        }
+      else if (nbytes)  /* Okay, reduce the length. */
+        {
+          tmp[nbytes] = 0;
+          free (result);
+          result = malloc (strlen (tmp)+1);
+          if (!result)
+            result = tmp;
+          else 
+            {
+              strcpy (result, tmp);
+              free (tmp);
+            }
+        }
+      else  /* Error - don't expand. */
+        {
+          free (tmp);
+        }
+    }
+
+ leave:
+  RegCloseKey( key_handle );
+  return result;
+}
+
+
+/* This is a helper function to load and run a Windows function from
+   either of one DLLs. */
+static HRESULT
+w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
+{
+  static int initialized;
+  static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
+
+  if (!initialized)
+    {
+      static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
+      void *handle;
+      int i;
+
+      initialized = 1;
+
+      for (i=0, handle = NULL; !handle && dllnames[i]; i++)
+        {
+          handle = dlopen (dllnames[i], RTLD_LAZY);
+          if (handle)
+            {
+              func = dlsym (handle, "SHGetFolderPathA");
+              if (!func)
+                {
+                  dlclose (handle);
+                  handle = NULL;
+                }
+            }
+        }
+    }
+
+  if (func)
+    return func (a,b,c,d,e);
+  else
+    return -1;
+}
+
+
+static char *
+find_program_in_registry (const char *name)
+{
+  char *program = NULL;
+    
+  program = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", name);
+  if (program)
+    {
+      int i;
+
+      DEBUG2 ("found %s in registry: `%s'", name, program);
+      for (i = 0; program[i]; i++)
+	{
+	  if (program[i] == '/')
+	    program[i] = '\\';
+	}
+    }
+  return program;
+}
+
+
+static char *
+find_program_at_standard_place (const char *name)
+{
+  char path[MAX_PATH];
+  char *result = NULL;
+      
+  if (w32_shgetfolderpath (NULL, CSIDL_PROGRAM_FILES, NULL, 0, path) >= 0) 
+    {
+      result = malloc (strlen (path) + 1 + strlen (name) + 1);
+      if (result)
+        {
+          strcpy (stpcpy (stpcpy (result, path), "\\"), name);
+          if (access (result, F_OK))
+            {
+              free (result);
+              result = NULL;
+            }
+        }
+    }
+  return result;
+}
+
+const char *
+_gpgme_get_gpg_path (void)
+{
+  static char *gpg_program;
+
+  LOCK (get_path_lock);
+  if (!gpg_program)
+    gpg_program = find_program_in_registry ("gpgProgram");
+  if (!gpg_program)
+    gpg_program = find_program_at_standard_place ("GNU\\GnuPG\\gpg.exe");
+#ifdef GPG_PATH
+  if (!gpg_program)
+    gpg_program = GPG_PATH;
+#endif
+  UNLOCK (get_path_lock);
+  return gpg_program;
+}
+
+const char *
+_gpgme_get_gpgsm_path (void)
+{
+  static char *gpgsm_program;
+
+  LOCK (get_path_lock);
+  if (!gpgsm_program)
+    gpgsm_program = find_program_in_registry ("gpgsmProgram");
+  if (!gpgsm_program)
+    gpgsm_program = find_program_at_standard_place ("GNU\\GnuPG\\gpgsm.exe");
+#ifdef GPGSM_PATH
+  if (!gpgsm_program)
+    gpgsm_program = GPGSM_PATH;
+#endif
+  UNLOCK (get_path_lock);
+  return gpgsm_program;
+}
+
+
+/* Return an integer value from gpgme specific configuration
+   entries. VALUE receives that value; function returns true if a value
+   has been configured and false if not. */
+int
+_gpgme_get_conf_int (const char *key, int *value)
+{
+  char *tmp = read_w32_registry_string (NULL, "Software\\GNU\\gpgme", key);
+  if (!tmp)
+    return 0;
+  *value = atoi (tmp);
+  free (tmp);
+  return 1;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/wait-global.c b/libtdenetwork/libgpgme-copy/gpgme/wait-global.c
new file mode 100644
index 000000000..bfa618dd1
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/wait-global.c
@@ -0,0 +1,384 @@
+/* wait-global.c 
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "sema.h"
+#include "util.h"
+#include "context.h"
+#include "wait.h"
+#include "priv-io.h"
+
+/* The global event loop is used for all asynchronous operations
+   (except key listing) for which no user I/O callbacks are specified.
+
+   A context sets up its initial I/O callbacks and then sends the
+   GPGME_EVENT_START event.  After that, it is added to the global
+   list of active contexts.
+
+   The gpgme_wait function contains a select() loop over all file
+   descriptors in all active contexts.  If an error occurs, it closes
+   all fds in that context and moves the context to the global done
+   list.  Likewise, if a context has removed all I/O callbacks, it is
+   moved to the global done list.
+
+   All contexts in the global done list are eligible for being
+   returned by gpgme_wait if requested by the caller.  */
+
+/* The ctx_list_lock protects the list of active and done contexts.
+   Insertion into any of these lists is only allowed when the lock is
+   held.  This allows a muli-threaded program to loop over gpgme_wait
+   and in parallel start asynchronous gpgme operations.
+
+   However, the fd tables in the contexts are not protected by this
+   lock.  They are only allowed to change either before the context is
+   added to the active list (ie, before the start event is signalled)
+   or in a callback handler.  */
+DEFINE_STATIC_LOCK (ctx_list_lock);
+
+/* A ctx_list_item is an item in the global list of active or done
+   contexts.  */
+struct ctx_list_item
+{
+  /* Every ctx_list_item is an element in a doubly linked list.  The
+     list pointers are protected by the ctx_list_lock.  */
+  struct ctx_list_item *next;
+  struct ctx_list_item *prev;
+
+  gpgme_ctx_t ctx;
+  /* The status is set when the ctx is moved to the done list.  */
+  gpgme_error_t status;
+};
+
+/* The active list contains all contexts that are in the global event
+   loop, have active I/O callbacks, and have already seen the start
+   event.  */
+static struct ctx_list_item *ctx_active_list;
+
+/* The done list contains all contexts that have previously been
+   active but now are not active any longer, either because they
+   finished successfully or an I/O callback returned an error.  The
+   status field in the list item contains the error value (or 0 if
+   successful).  */
+static struct ctx_list_item *ctx_done_list;
+
+
+/* Enter the context CTX into the active list.  */
+static gpgme_error_t
+ctx_active (gpgme_ctx_t ctx)
+{
+  struct ctx_list_item *li = malloc (sizeof (struct ctx_list_item));
+  if (!li)
+    return gpg_error_from_errno (errno);
+  li->ctx = ctx;
+
+  LOCK (ctx_list_lock);
+  /* Add LI to active list.  */
+  li->next = ctx_active_list;
+  li->prev = NULL;
+  if (ctx_active_list)
+    ctx_active_list->prev = li;
+  ctx_active_list = li;
+  UNLOCK (ctx_list_lock);
+  return 0;
+}
+
+
+/* Enter the context CTX into the done list with status STATUS.  */
+static void
+ctx_done (gpgme_ctx_t ctx, gpgme_error_t status)
+{
+  struct ctx_list_item *li;
+
+  LOCK (ctx_list_lock);
+  li = ctx_active_list;
+  while (li && li->ctx != ctx)
+    li = li->next;
+  assert (li);
+
+  /* Remove LI from active list.  */
+  if (li->next)
+    li->next->prev = li->prev;
+  if (li->prev)
+    li->prev->next = li->next;
+  else
+    ctx_active_list = li->next;
+
+  li->status = status;
+
+  /* Add LI to done list.  */
+  li->next = ctx_done_list;
+  li->prev = NULL;
+  if (ctx_done_list)
+    ctx_done_list->prev = li;
+  ctx_done_list = li;
+  UNLOCK (ctx_list_lock);
+}
+
+
+/* Find finished context CTX (or any context if CTX is NULL) and
+   return its status in STATUS after removing it from the done list.
+   If a matching context could be found, return it.  Return NULL if no
+   context could be found.  */
+static gpgme_ctx_t
+ctx_wait (gpgme_ctx_t ctx, gpgme_error_t *status)
+{
+  struct ctx_list_item *li;
+
+  LOCK (ctx_list_lock);
+  li = ctx_done_list;
+  if (ctx)
+    {
+      /* A specific context is requested.  */
+      while (li && li->ctx != ctx)
+	li = li->next;
+    }
+  if (li)
+    {
+      ctx = li->ctx;
+      if (status)
+	*status = li->status;
+
+      /* Remove LI from done list.  */
+      if (li->next)
+	li->next->prev = li->prev;
+      if (li->prev)
+	li->prev->next = li->next;
+      else
+	ctx_done_list = li->next;
+      free (li);
+    }
+  else
+    ctx = NULL;
+  UNLOCK (ctx_list_lock);
+  return ctx;
+}
+
+
+/* Internal I/O callback functions.  */
+
+/* The add_io_cb and remove_io_cb handlers are shared with the private
+   event loops.  */
+
+void
+_gpgme_wait_global_event_cb (void *data, gpgme_event_io_t type,
+			     void *type_data)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) data;
+
+  assert (ctx);
+
+  switch (type)
+    {
+    case GPGME_EVENT_START:
+      {
+	gpgme_error_t err = ctx_active (ctx);
+
+	if (err)
+	  {
+	    /* An error occured.  Close all fds in this context, and
+	       send the error in a done event.  */
+	    unsigned int idx;
+	    
+	    for (idx = 0; idx <= ctx->fdt.size; idx++)
+	      if (ctx->fdt.fds[idx].fd != -1)
+		_gpgme_io_close (ctx->fdt.fds[idx].fd);
+	    _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+	  }
+      }
+      break;
+
+    case GPGME_EVENT_DONE:
+      {
+	gpgme_error_t *errp = (gpgme_error_t *) type_data;
+	assert (errp);
+	ctx_done (ctx, *errp);
+      }
+      break;
+
+    case GPGME_EVENT_NEXT_KEY:
+      assert (!"Unexpected event GPGME_EVENT_NEXT_KEY");
+      break;
+
+    case GPGME_EVENT_NEXT_TRUSTITEM:
+      assert (!"Unexpected event GPGME_EVENT_NEXT_TRUSTITEM");
+      break;
+
+    default:
+      assert (!"Unexpected event");
+      break;
+    }
+}
+
+
+
+/* Perform asynchronous operations in the global event loop (ie, any
+   asynchronous operation except key listing and trustitem listing
+   operations).  If CTX is not a null pointer, the function will
+   return if the asynchronous operation in the context CTX finished.
+   Otherwise the function will return if any asynchronous operation
+   finished.  If HANG is zero, the function will not block for a long
+   time.  Otherwise the function does not return until an operation
+   matching CTX finished.
+
+   If a matching context finished, it is returned, and *STATUS is set
+   to the error value of the operation in that context.  Otherwise, if
+   the timeout expires, NULL is returned and *STATUS is 0.  If an
+   error occurs, NULL is returned and *STATUS is set to the error
+   value.  */
+gpgme_ctx_t
+gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
+{
+  do
+    {
+      unsigned int i = 0;
+      struct ctx_list_item *li;
+      struct fd_table fdt;
+      int nr;
+
+      /* Collect the active file descriptors.  */
+      LOCK (ctx_list_lock);
+      for (li = ctx_active_list; li; li = li->next)
+	i += li->ctx->fdt.size;
+      fdt.fds = malloc (i * sizeof (struct io_select_fd_s));
+      if (!fdt.fds)
+	{
+	  int saved_errno = errno;
+	  UNLOCK (ctx_list_lock);
+	  if (status)
+	    *status = gpg_error_from_errno (saved_errno);
+	  return NULL;
+	}
+      fdt.size = i;
+      i = 0;
+      for (li = ctx_active_list; li; li = li->next)
+	{
+	  memcpy (&fdt.fds[i], li->ctx->fdt.fds,
+		  li->ctx->fdt.size * sizeof (struct io_select_fd_s));
+	  i += li->ctx->fdt.size;
+	}
+      UNLOCK (ctx_list_lock);
+
+      nr = _gpgme_io_select (fdt.fds, fdt.size, 0);
+      if (nr < 0)
+	{
+	  int saved_errno = errno;
+	  free (fdt.fds);
+	  if (status)
+	    *status = gpg_error_from_errno (saved_errno);
+	  return NULL;
+	}
+
+      for (i = 0; i < fdt.size && nr; i++)
+	{
+	  if (fdt.fds[i].fd != -1 && fdt.fds[i].signaled)
+	    {
+	      gpgme_ctx_t ictx;
+	      gpgme_error_t err;
+	      struct wait_item_s *item;
+	      
+	      assert (nr);
+	      nr--;
+	      
+	      item = (struct wait_item_s *) fdt.fds[i].opaque;
+	      assert (item);
+	      ictx = item->ctx;
+	      assert (ictx);
+
+	      err = _gpgme_run_io_cb (&fdt.fds[i], 0);
+	      if (err)
+		{
+		  /* An error occured.  Close all fds in this context,
+		     and signal it.  */
+		  unsigned int idx;
+	    
+		  for (idx = 0; idx < ictx->fdt.size; idx++)
+		    if (ictx->fdt.fds[idx].fd != -1)
+		      _gpgme_io_close (ictx->fdt.fds[idx].fd);
+		  _gpgme_engine_io_event (ictx->engine, GPGME_EVENT_DONE,
+					  &err);
+
+		  /* Break out of the loop, and retry the select()
+		     from scratch, because now all fds should be
+		     gone.  */
+		  break;
+		}
+	    }
+	}
+      free (fdt.fds);
+
+      /* Now some contexts might have finished successfully.  */
+      LOCK (ctx_list_lock);
+    retry:
+      for (li = ctx_active_list; li; li = li->next)
+	{
+	  gpgme_ctx_t actx = li->ctx;
+
+	  for (i = 0; i < actx->fdt.size; i++)
+	    if (actx->fdt.fds[i].fd != -1)
+	      break;
+	  if (i == actx->fdt.size)
+	    {
+	      gpgme_error_t err = 0;
+
+	      /* FIXME: This does not perform too well.  We have to
+		 release the lock because the I/O event handler
+		 acquires it to remove the context from the active
+		 list.  Two alternative strategies are worth
+		 considering: Either implement the DONE event handler
+		 here in a lock-free manner, or save a list of all
+		 contexts to be released and call the DONE events
+		 afterwards.  */
+	      UNLOCK (ctx_list_lock);
+	      _gpgme_engine_io_event (actx->engine, GPGME_EVENT_DONE, &err);
+	      LOCK (ctx_list_lock);
+	      goto retry;
+	    }
+	}
+      UNLOCK (ctx_list_lock);
+
+      {
+	gpgme_ctx_t dctx = ctx_wait (ctx, status);
+
+	if (dctx)
+	  {
+	    ctx = dctx;
+	    hang = 0;
+	  }
+	else if (!hang)
+	  {
+	    ctx = NULL;
+	    if (status)
+	      *status = 0;
+	  }
+      }
+    }
+  while (hang);
+
+  return ctx;
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/wait-private.c b/libtdenetwork/libgpgme-copy/gpgme/wait-private.c
new file mode 100644
index 000000000..3f2b819d2
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/wait-private.c
@@ -0,0 +1,147 @@
+/* wait-private.c 
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <errno.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "wait.h"
+#include "ops.h"
+#include "priv-io.h"
+#include "util.h"
+
+
+/* The private event loops are used for all blocking operations, and
+   for the key and trust item listing operations.  They are completely
+   separated from each other.  */
+
+
+/* Internal I/O callback functions.  */
+
+/* The add_io_cb and remove_io_cb handlers are shared with the global
+   event loops.  */
+
+void
+_gpgme_wait_private_event_cb (void *data, gpgme_event_io_t type,
+			      void *type_data)
+{
+  switch (type)
+    {
+    case GPGME_EVENT_START:
+      /* Nothing to do here, as the wait routine is called after the
+	 initialization is finished.  */
+      break;
+
+    case GPGME_EVENT_DONE:
+      break;
+
+    case GPGME_EVENT_NEXT_KEY:
+      _gpgme_op_keylist_event_cb (data, type, type_data);
+      break;
+
+    case GPGME_EVENT_NEXT_TRUSTITEM:
+      _gpgme_op_trustlist_event_cb (data, type, type_data);
+      break;
+    }
+}
+
+
+/* If COND is a null pointer, wait until the blocking operation in CTX
+   finished and return its error value.  Otherwise, wait until COND is
+   satisfied or the operation finished.  */
+gpgme_error_t
+_gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
+{
+  gpgme_error_t err = 0;
+  int hang = 1;
+
+  do
+    {
+      int nr = _gpgme_io_select (ctx->fdt.fds, ctx->fdt.size, 0);
+      unsigned int i;
+
+      if (nr < 0)
+	{
+	  /* An error occured.  Close all fds in this context, and
+	     signal it.  */
+	  unsigned int idx;
+
+	  err = gpg_error_from_errno (errno);
+	  for (idx = 0; idx < ctx->fdt.size; idx++)
+	    if (ctx->fdt.fds[idx].fd != -1)
+	      _gpgme_io_close (ctx->fdt.fds[idx].fd);
+	  _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+
+	  return err;
+	}
+      
+      for (i = 0; i < ctx->fdt.size && nr; i++)
+	{
+	  if (ctx->fdt.fds[i].fd != -1 && ctx->fdt.fds[i].signaled)
+	    {
+	      ctx->fdt.fds[i].signaled = 0;
+	      assert (nr);
+	      nr--;
+
+	      err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0);
+	      if (err)
+		{
+		  /* An error occured.  Close all fds in this context,
+		     and signal it.  */
+		  unsigned int idx;
+		  
+		  for (idx = 0; idx < ctx->fdt.size; idx++)
+		    if (ctx->fdt.fds[idx].fd != -1)
+		      _gpgme_io_close (ctx->fdt.fds[idx].fd);
+		  _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+		  return err;
+		}
+	    }
+	}
+
+      for (i = 0; i < ctx->fdt.size; i++)
+	if (ctx->fdt.fds[i].fd != -1)
+	  break;
+      if (i == ctx->fdt.size)
+	{
+	  _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+	  hang = 0;
+	}
+      if (cond && *cond)
+	hang = 0;
+    }
+  while (hang);
+
+  return 0;
+}
+
+
+/* Wait until the blocking operation in context CTX has finished and
+   return the error value.  */
+gpgme_error_t
+_gpgme_wait_one (gpgme_ctx_t ctx)
+{
+  return _gpgme_wait_on_condition (ctx, NULL);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/wait-user.c b/libtdenetwork/libgpgme-copy/gpgme/wait-user.c
new file mode 100644
index 000000000..064d80095
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/wait-user.c
@@ -0,0 +1,122 @@
+/* wait-user.c 
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+
+#include "gpgme.h"
+#include "context.h"
+#include "priv-io.h"
+#include "wait.h"
+
+
+/* The user event loops are used for all asynchronous operations for
+   which a user callback is defined.  */
+
+
+/* Internal I/O Callbacks.  */
+
+gpgme_error_t
+_gpgme_user_io_cb_handler (void *data, int fd)
+{
+  gpgme_error_t err;
+  struct tag *tag = (struct tag *) data;
+  gpgme_ctx_t ctx;
+
+  assert (data);
+  ctx = tag->ctx;
+  assert (ctx);
+
+  err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0);
+  if (err)
+    {
+      unsigned int idx;
+
+      for (idx = 0; idx < ctx->fdt.size; idx++)
+	if (ctx->fdt.fds[idx].fd != -1)
+	  _gpgme_io_close (ctx->fdt.fds[idx].fd);
+      _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+    }
+  else
+    {
+      unsigned int i;
+
+      for (i = 0; i < ctx->fdt.size; i++)
+	if (ctx->fdt.fds[i].fd != -1)
+	  break;
+      if (i == ctx->fdt.size)
+	_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+    }
+  return 0;
+}
+
+
+/* Register the file descriptor FD with the handler FNC (which gets
+   FNC_DATA as its first argument) for the direction DIR.  DATA should
+   be the context for which the fd is added.  R_TAG will hold the tag
+   that can be used to remove the fd.  */
+gpgme_error_t
+_gpgme_wait_user_add_io_cb (void *data, int fd, int dir, gpgme_io_cb_t fnc,
+			    void *fnc_data, void **r_tag)
+{
+  gpgme_ctx_t ctx = (gpgme_ctx_t) data;
+  struct tag *tag;
+  gpgme_error_t err;
+
+  assert (ctx);
+  err = _gpgme_add_io_cb (data, fd, dir, fnc, fnc_data, r_tag);
+  if (err)
+    return err;
+  tag = *r_tag;
+  assert (tag);
+  err = (*ctx->io_cbs.add) (ctx->io_cbs.add_priv, fd, dir,
+			    _gpgme_user_io_cb_handler, *r_tag,
+			    &tag->user_tag);
+  if (err)
+    _gpgme_remove_io_cb (*r_tag);
+  return err;
+}
+
+
+void
+_gpgme_wait_user_remove_io_cb (void *data)
+{
+  struct tag *tag = (struct tag *) data;
+  gpgme_ctx_t ctx;
+
+  assert (tag);
+  ctx = tag->ctx;
+
+  (*ctx->io_cbs.remove) (tag->user_tag);
+  _gpgme_remove_io_cb (data);
+}
+
+
+void
+_gpgme_wait_user_event_cb (void *data, gpgme_event_io_t type, void *type_data)
+{
+  gpgme_ctx_t ctx = data;
+
+  if (ctx->io_cbs.event)
+    (*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, type_data);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/wait.c b/libtdenetwork/libgpgme-copy/gpgme/wait.c
new file mode 100644
index 000000000..dca8d5003
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/wait.c
@@ -0,0 +1,204 @@
+/* wait.c 
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 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.
+   
+   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
+   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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+#include "wait.h"
+#include "sema.h"
+#include "priv-io.h"
+#include "engine.h"
+#include "debug.h"
+
+
+void
+_gpgme_fd_table_init (fd_table_t fdt)
+{
+  fdt->fds = NULL;
+  fdt->size = 0;
+}
+
+void
+_gpgme_fd_table_deinit (fd_table_t fdt)
+{
+  if (fdt->fds)
+    free (fdt->fds);
+}
+
+
+/* XXX We should keep a marker and roll over for speed.  */
+static gpgme_error_t
+fd_table_put (fd_table_t fdt, int fd, int dir, void *opaque, int *idx)
+{
+  unsigned int i, j;
+  struct io_select_fd_s *new_fds;
+
+  for (i = 0; i < fdt->size; i++)
+    {
+      if (fdt->fds[i].fd == -1)
+	break;
+    }
+  if (i == fdt->size)
+    {
+#define FDT_ALLOCSIZE 10
+      new_fds = realloc (fdt->fds, (fdt->size + FDT_ALLOCSIZE)
+			 * sizeof (*new_fds));
+      if (!new_fds)
+	return gpg_error_from_errno (errno);
+      
+      fdt->fds = new_fds;
+      fdt->size += FDT_ALLOCSIZE;
+      for (j = 0; j < FDT_ALLOCSIZE; j++)
+	fdt->fds[i + j].fd = -1;
+    }
+
+  fdt->fds[i].fd = fd;
+  fdt->fds[i].for_read = (dir == 1);
+  fdt->fds[i].for_write = (dir == 0);
+  fdt->fds[i].frozen = 0;
+  fdt->fds[i].signaled = 0;
+  fdt->fds[i].opaque = opaque;
+  *idx = i;
+  return 0;
+}
+
+
+/* Register the file descriptor FD with the handler FNC (which gets
+   FNC_DATA as its first argument) for the direction DIR.  DATA should
+   be the context for which the fd is added.  R_TAG will hold the tag
+   that can be used to remove the fd.  */
+gpgme_error_t
+_gpgme_add_io_cb (void *data, int fd, int dir, gpgme_io_cb_t fnc,
+		  void *fnc_data, void **r_tag)
+{
+  gpgme_error_t err;
+  gpgme_ctx_t ctx = (gpgme_ctx_t) data;
+  fd_table_t fdt;
+  struct wait_item_s *item;
+  struct tag *tag;
+
+  assert (fnc);
+  assert (ctx);
+
+  fdt = &ctx->fdt;
+  assert (fdt);
+
+  tag = malloc (sizeof *tag);
+  if (!tag)
+    return gpg_error_from_errno (errno);
+  tag->ctx = ctx;
+
+  /* Allocate a structure to hold information about the handler.  */
+  item = calloc (1, sizeof *item);
+  if (!item)
+    {
+      int saved_errno = errno;
+      free (tag);
+      return gpg_error_from_errno (saved_errno);
+    }
+  item->ctx = ctx;
+  item->dir = dir;
+  item->handler = fnc;
+  item->handler_value = fnc_data;
+
+  err = fd_table_put (fdt, fd, dir, item, &tag->idx);
+  if (err)
+    {
+      free (tag);
+      free (item);
+      return err;
+    }
+
+  *r_tag = tag;
+  return 0;
+}
+
+
+void
+_gpgme_remove_io_cb (void *data)
+{
+  struct tag *tag = data;
+  gpgme_ctx_t ctx;
+  fd_table_t fdt;
+  int idx;
+
+  assert (tag);
+  ctx = tag->ctx;
+  assert (ctx);
+  fdt = &ctx->fdt;
+  assert (fdt);
+  idx = tag->idx;
+
+  DEBUG2 ("setting fd %d (item=%p) done", fdt->fds[idx].fd,
+	  fdt->fds[idx].opaque);
+  free (fdt->fds[idx].opaque);
+  free (tag);
+
+  /* Free the table entry.  */
+  fdt->fds[idx].fd = -1;
+  fdt->fds[idx].for_read = 0;
+  fdt->fds[idx].for_write = 0;
+  fdt->fds[idx].opaque = NULL;
+}
+
+
+/* This is slightly embarrassing.  The problem is that running an I/O
+   callback _may_ influence the status of other file descriptors.  Our
+   own event loops could compensate for that, but the external event
+   loops cannot.  FIXME: We may still want to optimize this a bit when
+   we are called from our own event loops.  So if CHECKED is 1, the
+   check is skipped.  */
+gpgme_error_t
+_gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked)
+{
+  struct wait_item_s *item;
+  item = (struct wait_item_s *) an_fds->opaque;
+  assert (item);
+
+  if (!checked)
+    {
+      int nr;
+      struct io_select_fd_s fds;
+
+      fds = *an_fds;
+      fds.signaled = 0;
+      /* Just give it a quick poll.  */
+      nr = _gpgme_io_select (&fds, 1, 1);
+      assert (nr <= 1);
+      if (nr < 0)
+	return errno;
+      else if (nr == 0)
+	/* The status changed in the meantime, there is nothing left
+	   to do.  */
+	return 0;
+    }
+
+  return item->handler (item->handler_value, an_fds->fd);
+}
diff --git a/libtdenetwork/libgpgme-copy/gpgme/wait.h b/libtdenetwork/libgpgme-copy/gpgme/wait.h
new file mode 100644
index 000000000..79582f884
--- /dev/null
+++ b/libtdenetwork/libgpgme-copy/gpgme/wait.h
@@ -0,0 +1,82 @@
+/* wait.h - Definitions for the wait queue interface.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004 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 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.
+   
+   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
+   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 WAIT_H
+#define WAIT_H
+
+#include "gpgme.h"
+#include "sema.h"
+
+struct fd_table
+{
+  struct io_select_fd_s *fds;
+  size_t size;
+};
+typedef struct fd_table *fd_table_t;
+
+/* Wait items are hooked into the io_select_fd_s to connect an fd with
+   a callback handler.  */
+struct wait_item_s
+{
+  gpgme_ctx_t ctx;
+  gpgme_io_cb_t handler;
+  void *handler_value;
+  int dir;
+};
+
+/* A registered fd handler is removed later using the tag that
+   identifies it.  */
+struct tag
+{
+  /* The context for which the fd was registered.  */
+  gpgme_ctx_t ctx;
+
+  /* The index into the fd table for this context.  */
+  int idx;
+
+  /* This is used by the wrappers for the user event loop.  */
+  void *user_tag;
+};
+
+
+void _gpgme_fd_table_init (fd_table_t fdt);
+void _gpgme_fd_table_deinit (fd_table_t fdt);
+
+gpgme_error_t _gpgme_add_io_cb (void *data, int fd, int dir,
+			     gpgme_io_cb_t fnc, void *fnc_data, void **r_tag);
+void _gpgme_remove_io_cb (void *tag);
+void _gpgme_wait_private_event_cb (void *data, gpgme_event_io_t type,
+				   void *type_data);
+void _gpgme_wait_global_event_cb (void *data, gpgme_event_io_t type,
+				  void *type_data);
+
+gpgme_error_t _gpgme_wait_user_add_io_cb (void *data, int fd, int dir,
+					  gpgme_io_cb_t fnc, void *fnc_data,
+					  void **r_tag);
+void _gpgme_wait_user_remove_io_cb (void *tag);
+void _gpgme_wait_user_event_cb (void *data, gpgme_event_io_t type,
+				void *type_data);
+
+gpgme_error_t _gpgme_wait_one (gpgme_ctx_t ctx);
+
+gpgme_error_t _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked);
+
+#endif	/* WAIT_H */
diff --git a/libtdenetwork/qgpgme/CMakeLists.txt b/libtdenetwork/qgpgme/CMakeLists.txt
new file mode 100644
index 000000000..1de99beb5
--- /dev/null
+++ b/libtdenetwork/qgpgme/CMakeLists.txt
@@ -0,0 +1,41 @@
+#################################################
+#
+#  (C) 2010-2011 Serghei Amelian
+#  serghei (DOT) amelian (AT) gmail.com
+#
+#  Improvements and feedback are welcome
+#
+#  This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+  ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_BINARY_DIR}
+  ${CMAKE_SOURCE_DIR}/libtdenetwork
+  ${CMAKE_SOURCE_DIR}/libtdepim
+  ${TDE_INCLUDE_DIR}
+  ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+  ${TQT_LIBRARY_DIRS}
+)
+
+
+##### headers ###################################
+
+install( FILES
+    eventloopinteractor.h dataprovider.h
+  DESTINATION ${INCLUDE_INSTALL_DIR}/kde/qgpgme )
+
+
+##### qgpgme (shared) ###########################
+
+tde_add_library( qgpgme SHARED AUTOMOC
+  SOURCES
+    eventloopinteractor.cpp dataprovider.cpp
+  VERSION 0.0.0
+  LINK gpgme++-shared ${TQT_LIBRARIES}
+  DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/libtdenetwork/qgpgme/Makefile.am b/libtdenetwork/qgpgme/Makefile.am
new file mode 100644
index 000000000..108760a05
--- /dev/null
+++ b/libtdenetwork/qgpgme/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = . tests
+
+INCLUDES = -I$(top_srcdir)/libtdenetwork $(all_includes)
+
+lib_LTLIBRARIES = libqgpgme.la
+
+qgpgmedir = $(includedir)/qgpgme
+qgpgme_HEADERS = eventloopinteractor.h dataprovider.h
+
+libqgpgme_la_SOURCES = eventloopinteractor.cpp dataprovider.cpp
+libqgpgme_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -no-undefined
+libqgpgme_la_LIBADD = $(LIB_QT) ../gpgmepp/libgpgme++.la
+
+METASOURCES = AUTO
+
+messages:
+	$(XGETTEXT) *.cpp *.h -o $(podir)/libqgpgme.pot
+
diff --git a/libtdenetwork/qgpgme/dataprovider.cpp b/libtdenetwork/qgpgme/dataprovider.cpp
new file mode 100644
index 000000000..052b84c48
--- /dev/null
+++ b/libtdenetwork/qgpgme/dataprovider.cpp
@@ -0,0 +1,107 @@
+/* dataprovider.cpp
+   Copyright (C) 2004 Klar�lvdalens Datakonsult AB
+
+   This file is part of TQGPGME.
+
+   TQGPGME 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.
+
+   TQGPGME 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 TQGPGME; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+// -*- c++ -*-
+
+#include <config.h>
+
+#include <qgpgme/dataprovider.h>
+
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+static bool resizeAndInit( TQByteArray & ba, size_t newSize ) {
+  const size_t oldSize = ba.size();
+  bool ok = ba.tqresize( newSize );
+  if ( ok )
+    memset( ba.data() + oldSize, 0, newSize - oldSize );
+  return ok;
+}
+
+QGpgME::TQByteArrayDataProvider::TQByteArrayDataProvider()
+  : GpgME::DataProvider(), mOff( 0 ) {}
+
+QGpgME::TQByteArrayDataProvider::TQByteArrayDataProvider( const TQByteArray & initialData )
+  : GpgME::DataProvider(), mArray( initialData ), mOff( 0 ) {}
+
+QGpgME::TQByteArrayDataProvider::~TQByteArrayDataProvider() {}
+
+ssize_t QGpgME::TQByteArrayDataProvider::read( void * buffer, size_t bufSize ) {
+#ifndef NDEBUG
+  //qDebug( "QGpgME::TQByteArrayDataProvider::read( %p, %d )", buffer, bufSize );
+#endif
+  if ( bufSize == 0 )
+    return 0;
+  if ( mOff >= mArray.size() )
+    return 0; // EOF
+  size_t amount = TQMIN( bufSize, mArray.size() - mOff );
+  assert( amount > 0 );
+  memcpy( buffer, mArray.data() + mOff, amount );
+  mOff += amount;
+  return amount;
+}
+
+ssize_t QGpgME::TQByteArrayDataProvider::write( const void * buffer, size_t bufSize ) {
+#ifndef NDEBUG
+  qDebug( "QGpgME::TQByteArrayDataProvider::write( %p, %d )", buffer, bufSize );
+#endif
+  if ( bufSize == 0 )
+    return 0;
+  if ( mOff >= mArray.size() )
+    resizeAndInit( mArray, mOff + bufSize );
+  if ( mOff >= mArray.size() ) {
+    errno = EIO;
+    return -1;
+  }
+  assert( bufSize <= mArray.size() - mOff );
+  memcpy( mArray.data() + mOff, buffer, bufSize );
+  mOff += bufSize;
+  return bufSize;
+}
+
+off_t QGpgME::TQByteArrayDataProvider::seek( off_t offset, int whence ) {
+#ifndef NDEBUG
+  qDebug( "QGpgME::TQByteArrayDataProvider::seek( %d, %d )", int(offset), whence );
+#endif
+  int newOffset = mOff;
+  switch ( whence ) {
+  case SEEK_SET:
+    newOffset = offset;
+    break;
+  case SEEK_CUR:
+    newOffset += offset;
+    break;
+  case SEEK_END:
+    newOffset = mArray.size() + offset;
+    break;
+  default:
+    errno = EINVAL;
+    return (off_t)-1;
+  }
+  return mOff = newOffset;
+}
+
+void QGpgME::TQByteArrayDataProvider::release() {
+#ifndef NDEBUG
+  qDebug( "QGpgME::TQByteArrayDataProvider::release()" );
+#endif
+  mArray = TQByteArray();
+}
diff --git a/libtdenetwork/qgpgme/dataprovider.h b/libtdenetwork/qgpgme/dataprovider.h
new file mode 100644
index 000000000..58c097d1e
--- /dev/null
+++ b/libtdenetwork/qgpgme/dataprovider.h
@@ -0,0 +1,62 @@
+/* dataprovider.h
+   Copyright (C) 2004 Klar�lvdalens Datakonsult AB
+
+   This file is part of TQGPGME.
+ 
+   TQGPGME 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.
+ 
+   TQGPGME 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 TQGPGME; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+// -*- c++ -*-
+#ifndef __TQGPGME_DATAPROVIDER_H__
+#define __TQGPGME_DATAPROVIDER_H__
+
+#include <gpgmepp/interfaces/dataprovider.h>
+
+#include <tqcstring.h>
+#include <tdepimmacros.h>
+
+namespace QGpgME {
+
+  class KDE_EXPORT TQByteArrayDataProvider : public GpgME::DataProvider {
+  public:
+    TQByteArrayDataProvider();
+    TQByteArrayDataProvider( const TQByteArray & initialData );
+    ~TQByteArrayDataProvider();
+
+    const TQByteArray & data() const { return mArray; }
+
+  private:
+    // these shall only be accessed through the dataprovider
+    // interface, where they're public:
+    /*! \reimp */
+    bool isSupported( Operation ) const { return true; }
+    /*! \reimp */
+    ssize_t read( void * buffer, size_t bufSize );
+    /*! \reimp */
+    ssize_t write( const void * buffer, size_t bufSize );
+    /*! \reimp */
+    off_t seek( off_t offset, int whence );
+    /*! \reimp */
+    void release();
+
+  private:
+    TQByteArray mArray;
+    off_t mOff;
+  };
+
+} // namespace QGpgME
+
+#endif // __TQGPGME_EVENTLOOPINTERACTOR_H__
+
+
diff --git a/libtdenetwork/qgpgme/eventloopinteractor.cpp b/libtdenetwork/qgpgme/eventloopinteractor.cpp
new file mode 100644
index 000000000..fdf25af04
--- /dev/null
+++ b/libtdenetwork/qgpgme/eventloopinteractor.cpp
@@ -0,0 +1,99 @@
+/* qeventloopinteractor.cpp
+   Copyright (C) 2003 Klar�lvdalens Datakonsult AB
+
+   This file is part of TQGPGME.
+ 
+   TQGPGME 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.
+ 
+   TQGPGME 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 TQGPGME; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+// -*- c++ -*-
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qgpgme/eventloopinteractor.h>
+
+#include <gpgmepp/context.h>
+
+#include <tqsocketnotifier.h>
+#include <tqapplication.h>
+
+using namespace GpgME;
+
+QGpgME::EventLoopInteractor::EventLoopInteractor( TQObject * parent, const char * name )
+ : TQObject( parent, name ), GpgME::EventLoopInteractor()
+{
+  if ( !parent )
+    if ( tqApp ) {
+      connect( tqApp, TQT_SIGNAL(aboutToQuit()), TQT_SLOT(deleteLater()) );
+      connect( tqApp, TQT_SIGNAL(aboutToQuit()), TQT_SIGNAL(aboutToDestroy()) );
+    }
+  mSelf = this;
+}
+
+QGpgME::EventLoopInteractor::~EventLoopInteractor() {
+  emit aboutToDestroy();
+  mSelf = 0;
+}
+
+QGpgME::EventLoopInteractor * QGpgME::EventLoopInteractor::mSelf = 0;
+
+QGpgME::EventLoopInteractor * QGpgME::EventLoopInteractor::instance() {
+  if ( !mSelf )
+#ifndef NDEBUG
+    if ( !tqApp )
+      qWarning( "QGpgME::EventLoopInteractor: Need a TQApplication object before calling instance()!" );
+    else
+#endif
+      (void)new EventLoopInteractor( 0, "QGpgME::EventLoopInteractor::instance()" );
+  return mSelf;
+}
+
+void * QGpgME::EventLoopInteractor::registerWatcher( int fd, Direction dir, bool & ok ) {
+  TQSocketNotifier * sn = new TQSocketNotifier( fd, 
+      dir == Read ? TQSocketNotifier::Read : TQSocketNotifier::Write );
+  if ( dir == Read )
+    connect( sn, TQT_SIGNAL(activated(int)), TQT_SLOT(slotReadActivity(int)) );
+  else
+    connect( sn, TQT_SIGNAL(activated(int)), TQT_SLOT(slotWriteActivity(int)) );
+  ok = true; // Can above operations fails?
+  return sn;
+}
+
+void QGpgME::EventLoopInteractor::unregisterWatcher( void * tag ) {
+  delete static_cast<TQSocketNotifier*>( tag );
+}
+
+void QGpgME::EventLoopInteractor::slotWriteActivity( int socket ) {
+  actOn( socket , Write );
+}
+
+void QGpgME::EventLoopInteractor::slotReadActivity( int socket ) {
+  actOn( socket , Read );
+}
+
+void QGpgME::EventLoopInteractor::nextTrustItemEvent( GpgME::Context * context, const GpgME::TrustItem & item ) {
+  emit nextTrustItemEventSignal( context, item );
+}
+
+void QGpgME::EventLoopInteractor::nextKeyEvent( GpgME::Context * context, const GpgME::Key & key ) {
+  emit nextKeyEventSignal( context, key );
+}
+
+void QGpgME::EventLoopInteractor::operationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+  emit operationDoneEventSignal( context, e );
+}
+
+#include "eventloopinteractor.moc"
diff --git a/libtdenetwork/qgpgme/eventloopinteractor.h b/libtdenetwork/qgpgme/eventloopinteractor.h
new file mode 100644
index 000000000..c1e5859a4
--- /dev/null
+++ b/libtdenetwork/qgpgme/eventloopinteractor.h
@@ -0,0 +1,90 @@
+/* qeventloopinteractor.h
+   Copyright (C) 2003 Klar�lvdalens Datakonsult AB
+
+   This file is part of TQGPGME.
+ 
+   TQGPGME 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.
+ 
+   TQGPGME 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 TQGPGME; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+// -*- c++ -*-
+#ifndef __TQGPGME_EVENTLOOPINTERACTOR_H__
+#define __TQGPGME_EVENTLOOPINTERACTOR_H__
+
+#include <gpgmepp/eventloopinteractor.h>
+
+#include <tqobject.h>
+#include <tdepimmacros.h>
+
+namespace GpgME {
+  class Context;
+  class Error;
+  class TrustItem;
+  class Key;
+} // namespace GpgME
+  
+namespace QGpgME {
+
+  class KDE_EXPORT EventLoopInteractor : public TQObject, public GpgME::EventLoopInteractor {
+    Q_OBJECT
+  TQ_OBJECT
+  protected:
+    EventLoopInteractor( TQObject * parent, const char * name=0 );
+  public:
+    virtual ~EventLoopInteractor();
+
+    static EventLoopInteractor * instance();
+
+  signals:
+    void nextTrustItemEventSignal( GpgME::Context * context, const GpgME::TrustItem & item  );
+    void nextKeyEventSignal( GpgME::Context * context, const GpgME::Key & key );
+    void operationDoneEventSignal( GpgME::Context * context, const GpgME::Error & e );
+
+    void aboutToDestroy();
+
+  protected slots:
+    void slotWriteActivity( int socket );
+    void slotReadActivity( int socket );
+    
+  protected:
+    //
+    // IO Notification Interface
+    //
+
+    /*! \reimp */
+    void * registerWatcher( int fd, Direction dir, bool & ok );
+    /*! \reimp */
+    void unregisterWatcher( void * tag );
+
+    //
+    // Event Handler Interface
+    //
+
+    /*! \reimp */
+    void nextTrustItemEvent( GpgME::Context * context, const GpgME::TrustItem & item );
+    /*! \reimp */
+    void nextKeyEvent( GpgME::Context * context, const GpgME::Key & key );
+    /*! \reimp */
+    void operationDoneEvent( GpgME::Context * context, const GpgME::Error & e );
+
+  private:
+    class Private;
+    Private * d;
+    static EventLoopInteractor * mSelf;
+  };
+
+} // namespace QGpgME
+
+#endif // __TQGPGME_EVENTLOOPINTERACTOR_H__
+
+
diff --git a/libtdenetwork/qgpgme/tests/Makefile.am b/libtdenetwork/qgpgme/tests/Makefile.am
new file mode 100644
index 000000000..5c2436d04
--- /dev/null
+++ b/libtdenetwork/qgpgme/tests/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I$(top_srcdir)/libtdenetwork $(GPGME_CFLAGS) $(all_includes)
+
+check_PROGRAMS = dataprovidertest
+
+TESTS = $(check_PROGRAMS)
+
+dataprovidertest_SOURCES = dataprovidertest.cpp
+
+LDADD = ../libqgpgme.la #?$(LIB_QT)
diff --git a/libtdenetwork/qgpgme/tests/dataprovidertest.cpp b/libtdenetwork/qgpgme/tests/dataprovidertest.cpp
new file mode 100644
index 000000000..675c85ea8
--- /dev/null
+++ b/libtdenetwork/qgpgme/tests/dataprovidertest.cpp
@@ -0,0 +1,125 @@
+/* tests/dataprovidertest.cpp
+   Copyright (C) 2004 Klar�lvdalens Datakonsult AB
+
+   This file is part of TQGPGME's regression test suite.
+ 
+   TQGPGME 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.
+ 
+   TQGPGME 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 TQGPGME; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+// -*- c++ -*-
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qgpgme/dataprovider.h>
+#include <gpgmepp/data.h>
+#include <gpgmepp/data_p.h>
+#include <gpgme.h>
+
+#include <iostream>
+
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+using namespace GpgME;
+
+static const char input[] = "foo bar baz\0foo bar baz";
+static const size_t inputSize = sizeof (input) / sizeof (*input) - 1;
+static const char nulls[256] = { '\0' };
+
+#define assertEqual( expr, expected ) \
+do { \
+  long long foo = (expr); \
+  if ( foo != (long long)expected ) { \
+    std::cerr << #expr << ": expected " << expected << "; got " << foo \
+              << ";errno: " << errno << "(" << strerror( errno ) << ")" << std::endl; \
+    exit( 1 ); \
+  } \
+} while( 0 )
+
+int main( int, char** ) {
+
+  {
+    //
+    // TQByteArrayDataProvider
+    //
+
+    // writing:
+    QGpgME::TQByteArrayDataProvider qba_dp;
+    Data data( &qba_dp );
+
+    assertEqual( data.write( input, inputSize ), inputSize );
+
+    const TQByteArray ba1 = qba_dp.data();
+    assertEqual( ba1.size(), inputSize );
+    assertEqual( memcmp( ba1.data(), input, inputSize ), 0 );
+
+    // seeking and reading:
+    assertEqual( data.seek( 0, SEEK_CUR ), inputSize );
+    assertEqual( data.seek( 4, SEEK_SET ), 4 );
+    char ch = '\0';
+    assertEqual( data.read( &ch, 1 ), 1 );
+    assertEqual( ch, input[4] );
+    assertEqual( data.read( &ch, 1 ), 1 );
+    assertEqual( ch, input[5] );
+
+    char buf[ inputSize + 10 ] = { '\0' };
+    assertEqual( data.seek( 0, SEEK_SET ), 0 );
+    assertEqual( data.read( buf, sizeof buf ), inputSize );
+    assertEqual( memcmp( buf, input, inputSize ), 0 );
+
+    // writing single char at end:
+    assertEqual( data.seek( 0, SEEK_END ), inputSize );
+    assertEqual( data.write( &ch, 1 ) , 1 );
+    const TQByteArray ba2 = qba_dp.data();
+    assertEqual( ba2.size(), inputSize + 1 );
+    assertEqual( memcmp( ba2.data(), input, inputSize ), 0 );
+    assertEqual( ba2[inputSize], ch );
+
+    // writing past end of buffer:
+    assertEqual( data.seek( 10, SEEK_END ), inputSize + 11 );
+    assertEqual( data.write( &ch, 1 ), 1 );
+    const TQByteArray ba3 = qba_dp.data();
+    assertEqual( ba3.size(), inputSize + 12 );
+    assertEqual( memcmp( ba3.data(), input, inputSize ), 0 );
+    assertEqual( ba3[inputSize], ch );
+    assertEqual( ba3[inputSize+11], ch );
+    assertEqual( memcmp( ba3.data() + inputSize + 1, nulls, 10 ), 0 );
+  }
+
+  {
+    //
+    // TQByteArrayDataProvider with initial data:
+    //
+    TQByteArray ba;
+    ba.duplicate( input, inputSize );
+    QGpgME::TQByteArrayDataProvider qba_dp( ba );
+    Data data( &qba_dp );
+
+    assertEqual( data.seek( 0, SEEK_END ), inputSize );
+    assertEqual( data.seek( 0, SEEK_SET ), 0 );
+    const TQByteArray ba1 = qba_dp.data();
+    assertEqual( ba1.size(), inputSize );
+    assertEqual( memcmp( ba1.data(), input, inputSize ), 0 );
+  }
+  return 0;
+}
diff --git a/libtdenetwork/tests/.gitignore b/libtdenetwork/tests/.gitignore
new file mode 100644
index 000000000..e69de29bb
-- 
cgit v1.2.1