This commit was manufactured by cvs2svn to create tag 'gpgme-0-3-7'.

This commit is contained in:
Repo Admin 2002-06-04 12:20:46 +00:00
parent d3dd502a24
commit 12a7a413d7
180 changed files with 46146 additions and 0 deletions

23
tags/gpgme-0-3-7/AUTHORS Normal file
View File

@ -0,0 +1,23 @@
Program: gpgme
Maintainer: wk@g10gnupg.org
FSF <gnu@gnu.org>
- Code taken from GnuPG 1.0: gpgme/w32-util.c, GnuPG 1.1: jnlib/.
g10 Code GmbH <code@g10code.com>
- All stuff since mid march 2001.
Werner Koch <wk@gnupg.org>
- Design and most stuff.
Copyright 2001 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.

203
tags/gpgme-0-3-7/ChangeLog Normal file
View File

@ -0,0 +1,203 @@
2002-06-04 Marcus Brinkmann <marcus@g10code.de>
Released 0.3.7.
* configure.ac (AC_INIT): Set version to 0.3.7.
(LIBGPGME_LT_REVISION): Add one.
* README: Document version requirement correctly.
2002-06-02 Marcus Brinkmann <marcus@g10code.de>
* acinclude.m4: Fix Pth check so that it doesn't error out if pth
is not found.
2002-06-02 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Add checks for Pth and pthreads.
* acinclude.m4: Add slightly hacked check for pth (seems to be an
autoconf version problem).
2002-05-21 Werner Koch <wk@gnupg.org>
* configure.ac (NEED_GPGSM_VERSION): We need gpgsm 0.3.7.
2002-05-03 Werner Koch <wk@gnupg.org>
Released 0.3.6.
2002-04-05 Marcus Brinkmann <marcus@g10code.de>
* acconfig.h: File removed.
* configure.ac (NEED_GPG_VERSION): Add description.
(NEED_GPGSM_VERSION): Likewise.
(HAVE_DOSISH_SYSTEM): Likewise.
(HAVE_DRIVE_LETTERS): Likewise.
(GPG_PATH): Likewise.
(GPGSM_PATH): Likewise.
* acinclude.m4 (GNUPG_CHECK_TYPEDEF): Likewise.
2002-04-01 Werner Koch <wk@gnupg.org>
Released 0.3.5.
2002-03-17 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Add automake conditional HAVE_DOSISH_SYSTEM.
2002-03-04 Werner Koch <wk@gnupg.org>
* configure.ac: Bumbed version to 0.3.4-cvs to continue development.
Released 0.3.4.
* configure.ac: Bumbed LT version numbers to (7,1,0), requires
gpgsm 0.3.1.
2002-03-03 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AC_INIT): Change version number to snapshot CVS
version.
2002-02-13 Werner Koch <wk@gnupg.org>
* configure.ac (vasprintf,fopencookie): Add checks.
2002-02-12 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AC_INIT): Bump version to 0.3.3.
* jnlib/Makefile.am: Rever to older version that includes xmalloc
but not dotlock and some other files. Reported by Stéphane
Corthésy.
2002-02-10 Marcus Brinkmann <marcus@g10code.de>
* Released 0.3.2.
* configure.ac (AC_INIT): Bump version to 0.3.2.
* jnlib/libjnlibconfig.h: Revert to older version that doesn't
expect libgcrypt. Reported by Jose Carlos Garcia Sogo
<jsogo@debian.org>.
2002-02-09 Marcus Brinkmann <marcus@g10code.de>
* Released 0.3.1.
* configure.ac (LIBGPGME_LT_CURRENT): Bump it up to 6!
(NEED_GPGSM_VERSION): Bump it up to 0.3.0!
(AC_INIT): Bump version to 0.3.1
2002-01-22 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (HAVE_JNLIB_LOGGING): Define always for assuan.
2001-12-19 Werner Koch <wk@gnupg.org>
* configure.ac (VERSION,PACKAGE): Defined and subst. Used for
AM_INIT_AUTOMAKE and moved all version number more to the top.
2001-12-18 Marcus Brinkmann <marcus@g10code.de>
* autogen.sh (libtool_vers): Bump to 1.4.
* configure.ac (LIBGPGME_LT_CURRENT): Increment.
(LIBGPGME_LT_AGE): Reset.
Improve comment.
Fix wrong comment character.
2001-12-18 Werner Koch <wk@gnupg.org>
* acinclude.m4 (GNUPG_FIX_HDR_VERSION): Fixed for new automake.
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (GPG): Substitute this variable.
(GPGSM): Likewise.
2001-11-22 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AC_CONFIG_FILES): Add tests/gpg/Makefile and
tests/gpgsm/Makefile.
2001-11-21 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (gpgmeplug): New variable, set to gpgmeplug if
[BUILD_GPGMEPLUG].
* configure.ac (AC_CONFIG_FILES): Add gpgmeplug/Makefile.
Support --enable-gpgmeplug.
2001-11-21 Marcus Brinkmann <marcus@g10code.de>
* autogen.sh: Tighten version dependencies.
2001-11-20 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (SUBDIRS): Support building the assuan library
(currently if GPGSM_PATH is set)..
* configure.ac: Support building the assuan library.
* assuan: New directory, populated with the Assuan library
(copied from the newpg repository).
2001-11-20 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (NEED_GPGSM_VERSION): New variable. Treat it
similarly to NEED_GPG_VERSION.
* acconfig.h: Likewise.
2001-11-18 Marcus Brinkmann <marcus@g10code.de>
* configure.in: Renamed to ...
* configure.ac: ... this. Update to autoconf 2.52. Lots of small
changes in the transition. Support --with-gpg=PATH and
--with-gpgsm=PATH options. Check if test suites can be run.
* acconfig.h: Add GPGSM_PATH.
* Makefile.am: New variable `tests', set to `tests' if
RUN_GPG_TESTS.
(SUBDIRS): Replace string `tests' with variable `tests'.
2001-10-22 Marcus Brinkmann <marcus@g10code.de>
* autogen.sh: Invoke automake with `-a' (add missing files).
Do not invoke configure.
2001-09-17 Werner Koch <wk@gnupg.org>
Released 0.2.3.
* configure.in (NEED_GPG_VERSION): Set to 1.0.6. Incremented LT
current and age.
* Makefile.am (SUBDIRS): Add doc
2001-06-12 Werner Koch <wk@gnupg.org>
Released 0.2.2.
2001-04-05 Werner Koch <wk@gnupg.org>
* configure.in (NEED_GPG_VERSION): Set to 1.0.4g
2001-04-02 Werner Koch <wk@gnupg.org>
Released 0.2.1.
Changed the copyright notices all over the place.
2001-02-28 Werner Koch <wk@gnupg.org>
Released 0.2.0.
2001-01-18 Werner Koch <wk@gnupg.org>
* autogen.sh: Added option --build-w32.
Copyright 2001, 2002 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.

196
tags/gpgme-0-3-7/INSTALL Normal file
View File

@ -0,0 +1,196 @@
Installation Instructions for GPGME
===================================
Copyright 2001 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.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

View File

@ -0,0 +1,54 @@
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
## Process this file with automake to produce Makefile.in
EXTRA_DIST = README-alpha autogen.sh
if BUILD_ASSUAN
assuan = assuan
else
assuan =
endif
if BUILD_BONOBO
bonobo = bonobo
else
bonobo =
endif
if BUILD_COMPLUS
complus = complus
else
complus =
endif
if RUN_GPG_TESTS
tests = tests
else
tests =
endif
if BUILD_GPGMEPLUG
gpgmeplug = gpgmeplug
else
gpgmeplug =
endif
SUBDIRS = ${assuan} jnlib gpgme ${tests} doc ${bonobo} ${complus} ${gpgmeplug}

253
tags/gpgme-0-3-7/NEWS Normal file
View File

@ -0,0 +1,253 @@
Noteworthy changes in version 0.3.7 (2002-06-04)
------------------------------------------------
* GPGME_ATTR_OTRUST is implemented now.
* A first step toward thread safeness has been achieved, see the
documentation for details. Supported thread libraries are pthread
and Pth.
Noteworthy changes in version 0.3.6 (2002-05-03)
------------------------------------------------
* All error outout of the gpgsm backend is send to the bit bucket.
* The signature verification functions are extended. Instead of
always returning GPGME_SIG_STATUS_GOOD, the functions new codes for
expired signatures. 2 new functions may be used to retrieve more
detailed information like the signature expiration time and a
validity information of the key without an extra key looking.
* The current passphrase callback and progress meter callback can be
retrieved with the new functions gpgme_get_passphrase_cb and
gpgme_get_progress_cb respectively.
* Interface changes relative to the 0.3.5 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_get_passphrase_cb NEW
gpgme_get_progress_cb NEW
GpgmeDataEncoding NEW
gpgme_data_set_encoding NEW
gpgme_data_get_encoding NEW
GPGME_SIG_STAT_GOOD_EXP NEW
GPGME_SIG_STAT_GOOD_EXPKEY NEW
gpgme_op_verify CHANGED: Returns more status codes.
GPGME_ATTR_SIG_STATUS NEW
gpgme_get_sig_string_attr NEW
gpgme_get_sig_ulong_attr NEW
gpgme_get_protocol NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.5 (2002-04-01)
------------------------------------------------
* gpgme_op_encrypt can be called with RECIPIENTS being 0. In this
case, symmetric encryption is performed. Note that this requires a
passphrase from the user.
* More information is returned for X.509 certificates.
* Interface changes relative to the 0.3.4 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_op_encrypt EXTENDED: Symmetric encryption possible
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.4 (2002-03-04)
------------------------------------------------
* gpgme_op_encrypt does now fail with GPGME_Invalid_Recipients if
some recipients have been invalid, whereas earlier versions
succeeded in this case. The plaintext is still encrypted for all valid
recipients, so the application might take this error as a hint that
the ciphertext is not usable for all requested recipients.
Information about invalid recipients is available with gpgme_get_op_info.
* gpgme_op_verify now allows to pass an uninitialized data object as
its plaintext argument to check for normal and cleartext
signatures. The plaintext is then returned in the data object.
* New interfaces gpgme_set_include_certs and gpgme_get_include_certs
to set and get the number of certifications to include in S/MIME
signed messages.
* New interfaces gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start
to encrypt and sign a message in a combined operation.
* New interface gpgme_op_keylist_ext_start to search for multiple patterns.
* gpgme_key_get_ulong_attr supports the GPGME_ATTR_EXPIRE attribute.
* Interface changes relative to the 0.3.3 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_op_encrypt CHANGED: Can fail with GPGME_Invalid_Recipients
gpgme_op_verify EXTENDED: Accepts uninitialized text argument
gpgme_key_get_ulong_attr EXTENDED: Supports GPGME_ATTR_EXPIRE
gpgme_set_include_certs NEW
gpgme_get_include_certs NEW
gpgme_op_encrypt_sign NEW
gpgme_op_encrypt_sign_start NEW
gpgme_op_keylist_ext_start NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.3 (2002-02-12)
------------------------------------------------
* Fix the Makefile in jnlib.
* Fix the test suite (hopefully). It should clean up all its state
with `make check' now.
Noteworthy changes in version 0.3.2 (2002-02-10)
------------------------------------------------
* Remove erroneous dependency on libgcrypt in jnlib.
Noteworthy changes in version 0.3.1 (2002-02-09)
------------------------------------------------
* There is a Texinfo manual documenting the API.
* The gpgme_set_keylist_mode function returns an error, and changed
its meaning. It is no longer usable to select between normal and
fast mode (newer versions of GnuPG will always be fast), but
selects between local keyring, remote keyserver, or both.
For this, two new macros are defined, GPGME_KEYLIST_MODE_LOCAL
and GPGME_KEYLIST_MODE_EXTERN. To make it possible to modify the
current setting, a fucntion gpgme_get_keylist_mode was added to
retrieve the current mode.
* gpgme_wait accepts a new argument STATUS to return the error status
of the operation on the context. Its definition is closer to
waitpid() now than before.
* The LENGTH argument to gpgme_data_new_from_filepart changed its
type from off_t to the unsigned size_t.
* The R_HD argument to the GpgmePassphraseCb type changed its type
from void* to void**.
* New interface gpgme_op_trustlist_end() to match
gpgme_op_keylist_end().
* The CryptPlug modules have been renamed to gpgme-openpgp and
gpgme-smime, and they are installed in pkglibdir by `make install'.
* An idle function can be registered with gpgme_register_idle().
* The GpgSM backend supports key generation with gpgme_op_genkey().
* Interface changes relative to the 0.3.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_data_new_from_filepart CHANGED: Type of LENGTH is size_t.
GpgmePassphraseCb CHANGED: Type of R_HD is void **.
gpgme_wait CHANGED: New argument STATUS.
gpgme_set_keylist_mode CHANGED: Type of return value is GpgmeError.
The function has a new meaning!
gpgme_get_keylist_mode NEW
GPGME_KEYLIST_MODE_LOCAL NEW
GPGME_KEYLIST_MODE_EXTERN NEW
gpgme_op_trustlist_next NEW
GpgmeIdleFunc NEW
gpgme_register_idle NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.0 (2001-12-19)
------------------------------------------------
* New interface gpgme_set_protocol() to set the protocol and thus the
crypto engine to be used by the context. Currently, the OpenPGP
and the CMS protocols are supported. They are specified by the new
preprocessor symbols GPGME_PROTOCOL_OpenPGP and GPGME_PROTOCOL_CMS.
A new context uses the OpenPGP engine by default.
* gpgme_get_engine_info() returns information for all crypto engines
compiled into the library. The XML format has changed. To
reliably get the version of a crypto engine, the <version> tag
after the appropriate <protocol> tag has to be looked for.
* New interface gpgme_engine_check_version(), obsoleting
gpgme_check_engine(). Check the version of all engines you are
supporting in your software.
* GpgmeKey lists the user ids in the order as they are returned by
GnuPG, first the primary key with index 0, then the sub-user ids.
* New operation gpgme_op_decrypt_verify() to decrypt and verify
signatures simultaneously.
* The new interface gpgme_op_keylist_end() terminates a pending
keylist operation. A keylist operation is also terminated when
gpgme_op_keylist_next() returns GPGME_EOF.
* GPGME can be compiled without GnuPG being installed (`--with-gpg=PATH'),
cross-compiled, or even compiled without support for GnuPG
(`--without-gpg').
* GPGME can be compiled with support for GpgSM (GnuPG for S/MIME,
`--with-gpgsm=PATH'). It is enabled by default if the `gpgsm' is found
in the path, but it can also be compiled without support for GpgSM
(`--without-gpgsm').
* CryptPlug modules for GPGME are included and can be enabled at
configure time (`--enable-gpgmeplug'). There is one module which
uses the GnuPG engine (`gpgmeplug') and one module which uses the
GpgSM engine (`gpgsmplug').
* Interface changes relative to the latest 0.2.x release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_key_get_as_xml CHANGED: Sub-user ids reversed in order.
gpgme_key_get_string_attr CHANGED: User ids reversed in order.
gpgme_key_get_ulong_attr CHANGED: User ids reversed in order.
gpgme_get_engine_info CHANGED: New format, extended content.
gpgme_engine_check_version NEW
gpgme_decrypt_verify_start NEW
gpgme_decrypt_verify NEW
gpgme_op_keylist_next NEW
gpgme_set_protocol NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.2.3 (2001-09-17)
------------------------------------------------
* New function gpgme_get_op_info which can be used to get the micalg
parameter needed for MOSS.
* New functions gpgme_get_armor and gpgme_get_textmode.
* The usual bug fixes and some minor functionality improvements.
* Added a simple encryption component for MS-Windows; however the
build procedure might have some problems.
Noteworthy changes in version 0.2.2 (2001-06-12)
------------------------------------------------
* Implemented a key cache.
* Fixed a race condition under W32 and some other bug fixes.
Noteworthy changes in version 0.2.1 (2001-04-02)
------------------------------------------------
* Changed debug output and GPGME_DEBUG variable (gpgme/debug.c)
* Handle GnuPG's new key capabilities output and support revocation
et al. attributes
* Made the W32 support more robust.
Copyright 2001, 2002 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.

42
tags/gpgme-0-3-7/README Normal file
View File

@ -0,0 +1,42 @@
GPGME - GnuPG Made Easy
---------------------------
!!!! THIS IS WORK IN PROGRESS !!!
If you want to hack on it, start with one of the `tests/t-foo'
programs.
For support of the OpenPGP protocol (default), you need the latest CVS
version of GnuPG 1.0, see `http://www.gnupg.org/cvs-access.html'.
You need at least GnuPG 1.0.7, but don't use a 1.1.x version.
If configure can't find the `gpg' binary in your path, you can specify
the location with the --with-gpg=/path/to/gpg argument to configure.
For support of the CMS (Cryptographic Message Syntax) protocol, you
need the latest CVS version of GpgSM, module name `newpg', at
`:pserver:anoncvs@cvs.gnupg.org:/cvs/aegypten'.
You need at least GpgSM 0.3.7.
If configure can't find the `gpgsm' binary in your path, you can
specify the location with the --with-gpgsm=/path/to/gpgsm argument to
configure.
To enable the CryptPlug GPGME PlugIn for both protocols, use the
`--enable-gpgmeplug' option to the configure script. `gpgmeplug' is
experimental and you should not assume that it will stay with gpgme.
The plug-ins are installed by `make install' in `pkglibdir', normally
`PREFIX/lib/gpgme'.
Before building the CVS version following the generic install
instructions in `INSTALL', you need to set up the build scripts with
`./autogen.sh'. To build the W32 version, use `./autogen.sh
--build-w32'. You also need to enable maintainer mode at configure
time with `--enable-maintainer-mode', or the documentation will not
built (because the version.texi won't be generated unless maintainer
mode is enabled).
Please subscribe to the gnupg-devel@gnupg.org mailing list if you want
to do serious work.

View File

@ -0,0 +1 @@
THIS IS WORK IN PROGRESS !!!!

22
tags/gpgme-0-3-7/THANKS Normal file
View File

@ -0,0 +1,22 @@
Alfons Hoogervorst alfons@proteus.demon.nl
Enno Cramer uebergeek@web.de
Frank Heckenbach frank@g-n-u.de
Jan-Oliver Wagner jan@intevation.de
Johannes Poehlmann jhp@caldera.de
Jose C. García Sogo jose@jaimedelamo.eu.org
Mark Mutz mutz@kde.org
Stéphane Corthésy stephane@sente.ch
Timo Schulz twoaday@freakmail.de
Tommy Reynolds reynolds@redhat.com
Copyright 2001, 2002 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.

81
tags/gpgme-0-3-7/TODO Normal file
View File

@ -0,0 +1,81 @@
Hey Emacs, this is -*- outline -*- mode!
* ABI's to break:
** string representation of non-secret keys and ATTR_IS_SECRET is NULL,
which can not be differentiated from the case that it is not
representable.
* Thread support:
** Build thread modules for static linking (which just suck in the
desired symbols the hard way). !!
* Allow to use GTK's main loop instead of the select stuff in
wait.c. !!!
* cleanup the namespace - we use log_* assuan_* ascii_* mutex_*
But those are only used internally. Some linker tricks should make
it possible to hide them from the user (didn't work last time, try
again). !!
* Documentation
** Add note about GPGME clearing out pointer return values.
** validity/trust
* Engines
** Move code common to all engines up from gpg to engine.
** engine operations can return General Error on unknown protocol
(it's an internal error, as select_protocol checks already).
** When server mode is implemented properly, more care has to be taken to
release all resources on error (for example to free assuan_cmd).
** GnuPG
*** For pipemode, make sure to release the pipemode callback data object.
* Operations
** gpgme_wait needs to be made thread safe. !!!
** Passphrase callback should not copy password. !!!
** Export status handler need much more work.
** Import should return a useful error when one happened.
** Genkey should return something more useful than General_Error.
** Factor out common code in _op_*_start functions.
** Add ATTR to return the number of subkeys or uids.
** "When returning a GpgmeKey GPGME_ATTR_COMMENT attribute, characters
like ":" are not un-escaped, they are returned as \x3a" Bug
reported by Stephane Corthesy.
* Error Values
** Map ASSUAN/GpgSM ERR error values in a better way than is done now. !!
** Verify (and document) if Read_Error, Write_Error, Pipe_Error set errno.
* Tests
** Write a fake gpg-agent so that we can supply known passphrases to
gpgsm and setup the configuration files to use the agent. Without
this we are testing a currently running gpg-agent which is not a
clever idea. !
** t-data
*** Test gpgme_data_release_and_get_mem.
*** Test gpgme_data_rewind for invalid types.
*** Test gpgme_data_read's readable feature.
* Debug
** Handle malloc and vasprintf errors. But decide first if they should be
ignored (and logged with 255?!), or really be assertions. !
* Build suite
** Make sure everything is cleaned correctly (esp. test area).
* Architecture support
** (nothing currently)
Bugs reported by Stephane Corthesy:
> BTW, here's another bug: it it not possible to retrieve fingerprints
> for subkeys
> In GpgmeRecipients, would it be possible to provide a function which
> would return the validity assigned to a name contained in the
> GpgmeRecipients instance?
> passphrase callback. If I use the same GpgmeContext as the one which
> is currently asking for a passphrase, my app crashes: the r_hd in
> the
> callback has become invalid; if I use a brand new one, the callback
> is called recursively, when I ask to enumerate keys.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,221 @@
2002-05-03 Werner Koch <wk@gnupg.org>
* assuan-pipe-connect.c (assuan_pipe_connect2): New to extend
assuan_pipe_connect with some flags. Implemented a bitbucket for
stderr.
2002-04-26 Werner Koch <wk@gnupg.org>
* Makefile.am: Create libtool libraries
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.
***********************************************************
* Please note that Assuan is maintained as part of GnuPG. *
* You may find it source-copied in other packages. *
***********************************************************
Copyright 2001, 2002 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.

View File

@ -0,0 +1,49 @@
# Assuan Makefile for test purposes
# Copyright (C) 2001 Free Software Foundation, Inc.
#
# This file is part of GnuPG.
#
# GnuPG 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.
#
# GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
#libassuan_a_LDFLAGS =
libassuan_la_SOURCES = \
assuan.h \
assuan-defs.h \
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-errors.c : assuan.h
$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c

View File

@ -0,0 +1 @@
Please don't modify it here but in the copy which comes with GnuPG.

View File

@ -0,0 +1,441 @@
/* assuan-buffer.c - read and send data
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include "assuan-defs.h"
#ifdef HAVE_JNLIB_LOGGING
#include "../jnlib/logging.h"
#endif
static const char *
my_log_prefix (void)
{
#ifdef HAVE_JNLIB_LOGGING
return log_get_prefix (NULL);
#else
return "";
#endif
}
static int
writen ( int fd, const char *buffer, size_t length )
{
while (length)
{
#ifdef USE_GNU_PTH
int nwritten = pth_write (fd, buffer, length);
#else
int nwritten = write (fd, buffer, length);
#endif
if (nwritten < 0)
{
if (errno == EINTR)
continue;
return -1; /* write error */
}
length -= nwritten;
buffer += nwritten;
}
return 0; /* okay */
}
/* read an entire line */
static int
readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
{
size_t nleft = buflen;
char *p;
*eof = 0;
*r_nread = 0;
while (nleft > 0)
{
#ifdef USE_GNU_PTH
int n = pth_read (fd, buf, nleft);
#else
int n = read (fd, buf, nleft);
#endif
if (n < 0)
{
if (errno == EINTR)
continue;
return -1; /* read error */
}
else if (!n)
{
*eof = 1;
break; /* allow incomplete lines */
}
p = buf;
nleft -= n;
buf += n;
*r_nread += n;
for (; n && *p != '\n'; n--, p++)
;
if (n)
break; /* at least one full line available - that's enough for now */
}
return 0;
}
int
_assuan_read_line (ASSUAN_CONTEXT ctx)
{
char *line = ctx->inbound.line;
int n, nread, atticlen;
int rc;
if (ctx->inbound.eof)
return -1;
atticlen = ctx->inbound.attic.linelen;
if (atticlen)
{
memcpy (line, ctx->inbound.attic.line, atticlen);
ctx->inbound.attic.linelen = 0;
for (n=0; n < atticlen && line[n] != '\n'; n++)
;
if (n < atticlen)
{
rc = 0; /* found another line in the attic */
nread = atticlen;
atticlen = 0;
}
else
{ /* read the rest */
assert (atticlen < LINELENGTH);
rc = readline (ctx->inbound.fd, line + atticlen,
LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
}
}
else
rc = readline (ctx->inbound.fd, line, LINELENGTH,
&nread, &ctx->inbound.eof);
if (rc)
{
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
my_log_prefix (), ctx, strerror (errno));
return ASSUAN_Read_Error;
}
if (!nread)
{
assert (ctx->inbound.eof);
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n", my_log_prefix (),ctx);
return -1;
}
ctx->inbound.attic.pending = 0;
nread += atticlen;
for (n=0; n < nread; n++)
{
if (line[n] == '\n')
{
if (n+1 < nread)
{
char *s, *d;
int i;
n++;
/* we have to copy the rest because the handlers are
allowed to modify the passed buffer */
for (d=ctx->inbound.attic.line, s=line+n, i=nread-n; i; i--)
{
if (*s=='\n')
ctx->inbound.attic.pending = 1;
*d++ = *s++;
}
ctx->inbound.attic.linelen = nread-n;
n--;
}
if (n && line[n-1] == '\r')
n--;
line[n] = 0;
ctx->inbound.linelen = n;
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] <- ", my_log_prefix (), ctx);
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;
}
}
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", my_log_prefix (), ctx);
*line = 0;
ctx->inbound.linelen = 0;
return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
}
/* Read the next line from the client or server and return a pointer
to a buffer with holding that line. linelen returns the length of
the line. This buffer is valid until another read operation is
done on this buffer. The caller is allowed to modify this buffer.
He should only use the buffer if the function returns without an
error.
Returns: 0 on success or an assuan error code
See also: assuan_pending_line().
*/
AssuanError
assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
{
AssuanError err;
if (!ctx)
return ASSUAN_Invalid_Value;
err = _assuan_read_line (ctx);
*line = ctx->inbound.line;
*linelen = ctx->inbound.linelen;
return err;
}
/* Return true when a full line is pending for a read, without the need
for actual IO */
int
assuan_pending_line (ASSUAN_CONTEXT ctx)
{
return ctx && ctx->inbound.attic.pending;
}
AssuanError
assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
{
int rc;
if (!ctx)
return ASSUAN_Invalid_Value;
/* fixme: we should do some kind of line buffering */
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
_assuan_log_print_buffer (ctx->log_fp,
line, strlen (line));
putc ('\n', ctx->log_fp);
}
rc = writen (ctx->outbound.fd, line, strlen(line));
if (rc)
rc = ASSUAN_Write_Error;
if (!rc)
{
rc = writen (ctx->outbound.fd, "\n", 1);
if (rc)
rc = ASSUAN_Write_Error;
}
return rc;
}
/* Write out the data in buffer as datalines with line wrapping and
percent escaping. This fucntion is used for GNU's custom streams */
int
_assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
{
ASSUAN_CONTEXT ctx = cookie;
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)
{
/* insert data line header */
if (!linelen)
{
*line++ = 'D';
*line++ = ' ';
linelen += 2;
}
/* copy data, keep some 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--;
}
if (linelen >= LINELENGTH-2-2)
{
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
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 (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
{
ctx->outbound.data.error = ASSUAN_Write_Error;
return 0;
}
line = ctx->outbound.data.line;
linelen = 0;
}
}
ctx->outbound.data.linelen = linelen;
return 0;
}
/* Write out any buffered data
This fucntion is used for GNU's custom streams */
int
_assuan_cookie_write_flush (void *cookie)
{
ASSUAN_CONTEXT ctx = cookie;
char *line;
size_t linelen;
if (ctx->outbound.data.error)
return 0;
line = ctx->outbound.data.line;
linelen = ctx->outbound.data.linelen;
line += linelen;
if (linelen)
{
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
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 (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
{
ctx->outbound.data.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 INQUIRE response. However, when assuan_transact() is used, this
* function takes care of sending END itself.
*
* Return value: 0 on success or an error code
**/
AssuanError
assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
{
if (!ctx)
return ASSUAN_Invalid_Value;
if (!buffer && length)
return 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;
}

View File

@ -0,0 +1,225 @@
/* assuan-client.c - client functions
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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))
AssuanError
_assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
{
char *line;
int linelen;
AssuanError 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_Invalid_Response;
return rc;
}
/**
* assuan_transact:
* @ctx: The Assuan context
* @command: Coimmand line to be send to 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.
**/
AssuanError
assuan_transact (ASSUAN_CONTEXT ctx,
const char *command,
AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
void *inquire_cb_arg,
AssuanError (*status_cb)(void*, const char *),
void *status_cb_arg)
{
int rc, okay, off;
unsigned char *line;
int linelen;
rc = assuan_write_line (ctx, command);
if (rc)
return rc;
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 < 100)
rc = ASSUAN_Server_Fault;
}
else if (okay == 2)
{
if (!data_cb)
rc = ASSUAN_No_Data_Callback;
else
{
unsigned 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_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_No_Data_Callback;
else
{
rc = data_cb (data_cb_arg, NULL, 0);
if (!rc)
goto again;
}
}
return rc;
}

View File

@ -0,0 +1,54 @@
/* assuan-connect.c - Establish a connection (client)
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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>
#include <sys/wait.h>
#include "assuan-defs.h"
/* Disconnect and release the context CTX. */
void
assuan_disconnect (ASSUAN_CONTEXT ctx)
{
if (ctx)
{
assuan_write_line (ctx, "BYE");
ctx->finish_handler (ctx);
ctx->deinit_handler (ctx);
ctx->deinit_handler = NULL;
_assuan_release_context (ctx);
}
}
pid_t
assuan_get_pid (ASSUAN_CONTEXT ctx)
{
return ctx ? ctx->pid : -1;
}

View File

@ -0,0 +1,139 @@
/* assuan-defs.c - Internal definitions to Assuan
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef ASSUAN_DEFS_H
#define ASSUAN_DEFS_H
#include <sys/types.h>
#include "assuan.h"
#define LINELENGTH ASSUAN_LINELENGTH
struct cmdtbl_s {
const char *name;
int cmd_id;
int (*handler)(ASSUAN_CONTEXT, char *line);
};
struct assuan_context_s {
AssuanError err_no;
const char *err_str;
int os_errno; /* last system error number used with certain error codes*/
int confidential;
int is_server; /* set if this is context belongs to a server */
int in_inquire;
char *hello_line;
char *okay_line; /* see assan_set_okay_line() */
void *user_pointer; /* for assuan_[gs]et_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; /* In pipe mode, the pid of the child server process.
In socket mode, the pid of the server */
int listen_fd; /* The fd we are listening on (used by socket servers) */
pid_t client_pid; /* for a socket server the PID of the client or -1
if not available */
void (*deinit_handler)(ASSUAN_CONTEXT);
int (*accept_handler)(ASSUAN_CONTEXT);
int (*finish_handler)(ASSUAN_CONTEXT);
struct cmdtbl_s *cmdtbl;
size_t cmdtbl_used; /* used entries */
size_t cmdtbl_size; /* allocated size of table */
void (*bye_notify_fnc)(ASSUAN_CONTEXT);
void (*reset_notify_fnc)(ASSUAN_CONTEXT);
void (*cancel_notify_fnc)(ASSUAN_CONTEXT);
int (*option_handler_fnc)(ASSUAN_CONTEXT,const char*, const char*);
void (*input_notify_fnc)(ASSUAN_CONTEXT, const char *);
void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *);
int input_fd; /* set by INPUT command */
int output_fd; /* set by OUTPUT command */
};
/*-- assuan-pipe-server.c --*/
int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
void _assuan_release_context (ASSUAN_CONTEXT ctx);
/*-- assuan-handler.c --*/
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
/*-- assuan-buffer.c --*/
int _assuan_read_line (ASSUAN_CONTEXT ctx);
int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size);
int _assuan_cookie_write_flush (void *cookie);
/*-- assuan-client.c --*/
AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
/*-- 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_ ## e, (t))
void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length);
void _assuan_log_sanitized_string (const char *string);
#endif /*ASSUAN_DEFS_H*/

View File

@ -0,0 +1,688 @@
/* assuan-handler.c - dispatch commands
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "assuan-defs.h"
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
#define digitp(a) ((a) >= '0' && (a) <= '9')
static int
dummy_handler (ASSUAN_CONTEXT ctx, char *line)
{
return set_error (ctx, Server_Fault, "no handler registered");
}
static int
std_handler_nop (ASSUAN_CONTEXT ctx, char *line)
{
return 0; /* okay */
}
static int
std_handler_cancel (ASSUAN_CONTEXT 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 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 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 ctx, char *line)
{
return set_error (ctx, Not_Implemented, NULL);
}
static int
std_handler_reset (ASSUAN_CONTEXT ctx, char *line)
{
if (ctx->reset_notify_fnc)
ctx->reset_notify_fnc (ctx);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
return 0;
}
static int
std_handler_end (ASSUAN_CONTEXT ctx, char *line)
{
return set_error (ctx, Not_Implemented, NULL);
}
static int
parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd)
{
char *endp;
if (strncmp (line, "FD=", 3))
return set_error (ctx, Syntax_Error, "FD=<n> expected");
line += 3;
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;
}
/* Format is INPUT FD=<n> */
static int
std_handler_input (ASSUAN_CONTEXT ctx, char *line)
{
int rc, fd;
rc = parse_cmd_input_output (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 ctx, char *line)
{
int rc, fd;
rc = parse_cmd_input_output (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 assuciate strings
and handlers with cmd_ids */
static struct {
const char *name;
int cmd_id;
int (*handler)(ASSUAN_CONTEXT, char *line);
int always; /* always initialize this command */
} std_cmd_table[] = {
{ "NOP", ASSUAN_CMD_NOP, std_handler_nop, 1 },
{ "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 },
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
{ "BYE", ASSUAN_CMD_BYE, std_handler_bye, 1 },
{ "AUTH", ASSUAN_CMD_AUTH, std_handler_auth, 1 },
{ "RESET", ASSUAN_CMD_RESET, std_handler_reset, 1 },
{ "END", ASSUAN_CMD_END, std_handler_end, 1 },
{ "INPUT", ASSUAN_CMD_INPUT, std_handler_input },
{ "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output },
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
{ NULL }
};
/**
* assuan_register_command:
* @ctx: the server context
* @cmd_id: An ID value for the command
* @cmd_name: A string with the command name
* @handler: The handler function to be called
*
* Register a handler to be used for a given command.
*
* The @cmd_name must be %NULL or an empty string for all @cmd_ids
* below %ASSUAN_CMD_USER because predefined values are used.
*
* Return value:
**/
int
assuan_register_command (ASSUAN_CONTEXT ctx,
int cmd_id, const char *cmd_name,
int (*handler)(ASSUAN_CONTEXT, char *))
{
int i;
if (cmd_name && !*cmd_name)
cmd_name = NULL;
if (cmd_id < ASSUAN_CMD_USER)
{
if (cmd_name)
return ASSUAN_Invalid_Value; /* must be NULL for these values*/
for (i=0; std_cmd_table[i].name; i++)
{
if (std_cmd_table[i].cmd_id == cmd_id)
{
cmd_name = std_cmd_table[i].name;
if (!handler)
handler = std_cmd_table[i].handler;
break;
}
}
if (!std_cmd_table[i].name)
return ASSUAN_Invalid_Value; /* not a pre-registered one */
}
if (!handler)
handler = dummy_handler;
if (!cmd_name)
return ASSUAN_Invalid_Value;
/* fprintf (stderr, "DBG-assuan: registering %d as `%s'\n", cmd_id, cmd_name); */
if (!ctx->cmdtbl)
{
ctx->cmdtbl_size = 50;
ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl);
if (!ctx->cmdtbl)
return 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_Out_Of_Core;
ctx->cmdtbl = x;
ctx->cmdtbl_size += 50;
}
ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name;
ctx->cmdtbl[ctx->cmdtbl_used].cmd_id = cmd_id;
ctx->cmdtbl[ctx->cmdtbl_used].handler = handler;
ctx->cmdtbl_used++;
return 0;
}
int
assuan_register_bye_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
{
if (!ctx)
return ASSUAN_Invalid_Value;
ctx->bye_notify_fnc = fnc;
return 0;
}
int
assuan_register_reset_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
{
if (!ctx)
return ASSUAN_Invalid_Value;
ctx->reset_notify_fnc = fnc;
return 0;
}
int
assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
{
if (!ctx)
return ASSUAN_Invalid_Value;
ctx->cancel_notify_fnc = fnc;
return 0;
}
int
assuan_register_option_handler (ASSUAN_CONTEXT ctx,
int (*fnc)(ASSUAN_CONTEXT,
const char*, const char*))
{
if (!ctx)
return ASSUAN_Invalid_Value;
ctx->option_handler_fnc = fnc;
return 0;
}
int
assuan_register_input_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *))
{
if (!ctx)
return ASSUAN_Invalid_Value;
ctx->input_notify_fnc = fnc;
return 0;
}
int
assuan_register_output_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *))
{
if (!ctx)
return ASSUAN_Invalid_Value;
ctx->output_notify_fnc = fnc;
return 0;
}
/* Helper to register the standards commands */
int
_assuan_register_std_commands (ASSUAN_CONTEXT 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].cmd_id,
NULL, 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 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, all the
handler with the argument line and return the error */
static int
dispatch_command (ASSUAN_CONTEXT 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, Invalid_Command, "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 ctx)
{
int rc;
if (ctx->in_inquire)
return 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 (rc == -1)
{ /* No error checking because the peer may have already disconnect */
assuan_write_line (ctx, "OK closing connection");
ctx->finish_handler (ctx);
}
else
{
char errline[256];
if (rc < 100)
sprintf (errline, "ERR %d server fault (%.50s)",
ASSUAN_Server_Fault, assuan_strerror (rc));
else
{
const char *text = ctx->err_no == rc? ctx->err_str:NULL;
sprintf (errline, "ERR %d %.50s%s%.100s",
rc, assuan_strerror (rc), text? " - ":"", text?text:"");
}
rc = assuan_write_line (ctx, errline);
}
ctx->confidential = 0;
if (ctx->okay_line)
{
xfree (ctx->okay_line);
ctx->okay_line = NULL;
}
return rc;
}
/**
* assuan_process:
* @ctx: assuan context
*
* This fucntion 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 ctx)
{
int rc;
do {
rc = process_request (ctx);
} while (!rc);
if (rc == -1)
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 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 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;
}
/* 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 ctx)
{
cookie_io_functions_t cookie_fnc;
if (ctx->outbound.data.fp)
return ctx->outbound.data.fp;
cookie_fnc.read = NULL;
cookie_fnc.write = _assuan_cookie_write_data;
cookie_fnc.seek = NULL;
cookie_fnc.close = _assuan_cookie_write_flush;
ctx->outbound.data.fp = fopencookie (ctx, "wb", cookie_fnc);
ctx->outbound.data.error = 0;
return ctx->outbound.data.fp;
}
/* Set the text used for the next OK reponse. This string is
automatically reset to NULL after the next command. */
AssuanError
assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line)
{
if (!ctx)
return 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_Out_Of_Core;
strcpy (buf, "OK ");
strcpy (buf+3, line);
xfree (ctx->okay_line);
ctx->okay_line = buf;
}
return 0;
}
void
assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
{
char buffer[256];
char *helpbuf;
size_t n;
if ( !ctx || !keyword)
return;
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);
}
assuan_write_line (ctx, buffer);
}
else if ( (helpbuf = xtrymalloc (n)) )
{
strcpy (helpbuf, "S ");
strcat (helpbuf, keyword);
if (*text)
{
strcat (helpbuf, " ");
strcat (helpbuf, text);
}
assuan_write_line (ctx, helpbuf);
xfree (helpbuf);
}
}

View File

@ -0,0 +1,239 @@
/* assuan-inquire.c - handle inquire stuff
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
**/
AssuanError
assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
char **r_buffer, size_t *r_length, size_t maxlen)
{
AssuanError rc;
struct membuf mb;
char cmdbuf[100];
unsigned char *line, *p;
int linelen;
int nodataexpected;
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
return ASSUAN_Invalid_Value;
nodataexpected = !r_buffer && !r_length && !maxlen;
if (!nodataexpected && (!r_buffer || !r_length))
return ASSUAN_Invalid_Value;
if (!ctx->is_server)
return ASSUAN_Not_A_Server;
if (ctx->in_inquire)
return 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, "INQUIRE "), keyword);
rc = assuan_write_line (ctx, cmdbuf);
if (rc)
goto leave;
for (;;)
{
do
{
rc = _assuan_read_line (ctx);
if (rc)
goto leave;
line = 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_Canceled;
goto leave;
}
if (line[0] != 'D' || line[1] != ' ' || nodataexpected)
{
rc = 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_Too_Much_Data;
goto leave;
}
}
if (!nodataexpected)
{
*r_buffer = get_membuf (&mb, r_length);
if (!*r_buffer)
rc = ASSUAN_Out_Of_Core;
}
leave:
if (!nodataexpected)
free_membuf (&mb);
ctx->in_inquire = 0;
return rc;
}

View File

@ -0,0 +1,132 @@
/* assuan-listen.c - Wait for a connection (server)
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "assuan-defs.h"
AssuanError
assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
{
if (!ctx)
return 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_Out_Of_Core;
strcpy (buf, "OK ");
strcpy (buf+3, line);
xfree (ctx->hello_line);
ctx->hello_line = buf;
}
return 0;
}
/**
* assuan_accept:
* @ctx: context
*
* Cancel any existing connectiion 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.
**/
AssuanError
assuan_accept (ASSUAN_CONTEXT ctx)
{
int rc;
if (!ctx)
return 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 */
rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
: "OK Your orders please");
if (rc)
return rc;
if (ctx->pipe_mode)
ctx->pipe_mode = 2;
return 0;
}
int
assuan_get_input_fd (ASSUAN_CONTEXT ctx)
{
return ctx? ctx->input_fd : -1;
}
int
assuan_get_output_fd (ASSUAN_CONTEXT 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 */
AssuanError
assuan_close_input_fd (ASSUAN_CONTEXT ctx)
{
if (!ctx || ctx->input_fd == -1)
return ASSUAN_Invalid_Value;
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 */
AssuanError
assuan_close_output_fd (ASSUAN_CONTEXT ctx)
{
if (!ctx || ctx->output_fd == -1)
return ASSUAN_Invalid_Value;
close (ctx->output_fd);
ctx->output_fd = -1;
return 0;
}

View File

@ -0,0 +1,298 @@
/* assuan-pipe-connect.c - Establish a pipe connection (client)
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "assuan-defs.h"
#ifdef _POSIX_OPEN_MAX
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
#else
#define MAX_OPEN_FDS 20
#endif
#ifdef HAVE_JNLIB_LOGGING
#include "../jnlib/logging.h"
#define LOGERROR1(a,b) log_error ((a), (b))
#else
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
#endif
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 */
}
static int
do_finish (ASSUAN_CONTEXT ctx)
{
if (ctx->inbound.fd != -1)
{
close (ctx->inbound.fd);
ctx->inbound.fd = -1;
}
if (ctx->outbound.fd != -1)
{
close (ctx->outbound.fd);
ctx->outbound.fd = -1;
}
if (ctx->pid != -1)
{
waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */
ctx->pid = -1;
}
return 0;
}
static void
do_deinit (ASSUAN_CONTEXT ctx)
{
do_finish (ctx);
}
/* 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. */
AssuanError
assuan_pipe_connect2 (ASSUAN_CONTEXT *ctx, const char *name,
char *const argv[], int *fd_child_list,
unsigned int connect_flags)
{
static int fixed_signals = 0;
AssuanError err;
int rp[2];
int wp[2];
if (!ctx || !name || !argv || !argv[0])
return ASSUAN_Invalid_Value;
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 */
}
if (pipe (rp) < 0)
return ASSUAN_General_Error;
if (pipe (wp) < 0)
{
close (rp[0]);
close (rp[1]);
return 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;
(*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_General_Error;
}
if ((*ctx)->pid == 0)
{
int i, n;
char errbuf[512];
#ifdef HAVE_JNLIB_LOGGING
int log_fd = log_get_fd ();
#endif
/* close all files which will not be duped but keep stderr
and log_stream for now */
n = sysconf (_SC_OPEN_MAX);
if (n < 0)
n = MAX_OPEN_FDS;
for (i=0; i < n; i++)
{
int *fdp = fd_child_list;
if (fdp)
{
while (*fdp != -1 && *fdp != i)
fdp++;
}
if (!(fdp && *fdp != -1)
&& i != fileno (stderr)
#ifdef HAVE_JNLIB_LOGGING
&& i != log_fd
#endif
&& i != rp[1] && i != wp[0])
close(i);
}
errno = 0;
/* Dup handles and to stdin/stdout and exec */
if (rp[1] != STDOUT_FILENO)
{
if (dup2 (rp[1], STDOUT_FILENO) == -1)
{
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
_exit (4);
}
close (rp[1]);
}
if (wp[0] != STDIN_FILENO)
{
if (dup2 (wp[0], STDIN_FILENO) == -1)
{
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
_exit (4);
}
close (wp[0]);
}
if ((connect_flags & 1))
{ /* dup stderr to /dev/null so that the application output
won't get clobbered with output from the backend */
int fdzero = open ("/dev/null", O_WRONLY);
if (fdzero == -1)
{
LOGERROR1 ("can't open `/dev/null': %s\n", strerror (errno));
_exit (4);
}
if (dup2 (fdzero, 2) == -1)
{
LOGERROR1 ("dup2(dev/null, 2) failed: %s\n", strerror (errno));
_exit (4);
}
close (fdzero);
}
execv (name, 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_Problem_Starting_Server, name, strerror (errno));
errbuf[sizeof(errbuf)-1] = 0;
writen (1, errbuf, strlen (errbuf));
_exit (4);
}
close (rp[1]);
close (wp[0]);
/* initial handshake */
{
int okay, off;
err = _assuan_read_from_server (*ctx, &okay, &off);
if (err)
{
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
}
else if (okay != 1)
{
LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line);
err = ASSUAN_Connect_Failed;
}
}
if (err)
{
assuan_disconnect (*ctx);
*ctx = NULL;
}
return err;
}
AssuanError
assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
int *fd_child_list)
{
return assuan_pipe_connect2 (ctx, name, argv, fd_child_list, 0);
}

View File

@ -0,0 +1,124 @@
/* assuan-pipe-server.c - Assuan server working over a pipe
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include "assuan-defs.h"
static void
deinit_pipe_server (ASSUAN_CONTEXT ctx)
{
/* nothing to do for this simple server */
}
static int
accept_connection (ASSUAN_CONTEXT ctx)
{
/* This is a NOP for a pipe server */
return 0;
}
static int
finish_connection (ASSUAN_CONTEXT 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 wau we don't need extra dummy functions */
int
_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
{
ASSUAN_CONTEXT ctx;
int rc;
*r_ctx = NULL;
ctx = xtrycalloc (1, sizeof *ctx);
if (!ctx)
return ASSUAN_Out_Of_Core;
ctx->input_fd = -1;
ctx->output_fd = -1;
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
ctx->listen_fd = -1;
ctx->client_pid = (pid_t)-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;
}
int
assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
{
int rc;
rc = _assuan_new_context (r_ctx);
if (!rc)
{
ASSUAN_CONTEXT ctx = *r_ctx;
ctx->is_server = 1;
ctx->inbound.fd = filedes[0];
ctx->outbound.fd = filedes[1];
ctx->pipe_mode = 1;
}
return rc;
}
void
_assuan_release_context (ASSUAN_CONTEXT ctx)
{
if (ctx)
{
xfree (ctx->hello_line);
xfree (ctx->okay_line);
xfree (ctx);
}
}
void
assuan_deinit_server (ASSUAN_CONTEXT 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);
}
}

View File

@ -0,0 +1,150 @@
/* assuan-socket-connect.c - Assuan socket based client
* Copyright (C) 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "assuan-defs.h"
#ifdef HAVE_JNLIB_LOGGING
#include "../jnlib/logging.h"
#define LOGERROR(a) log_error ((a))
#define LOGERROR1(a,b) log_error ((a), (b))
#define LOGERROR2(a,b,c) log_error ((a), (b), (c))
#define LOGERRORX(a) log_printf ((a))
#else
#define LOGERROR(a) fprintf (stderr, (a))
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
#define LOGERROR2(a,b,c) fprintf (stderr, (a), (b), (c))
#define LOGERRORX(a) fputs ((a), stderr)
#endif
static int
do_finish (ASSUAN_CONTEXT ctx)
{
if (ctx->inbound.fd != -1)
{
close (ctx->inbound.fd);
}
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
return 0;
}
static void
do_deinit (ASSUAN_CONTEXT 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
becode handy in future. */
AssuanError
assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
const char *name, pid_t server_pid)
{
AssuanError err;
ASSUAN_CONTEXT ctx;
int fd;
struct sockaddr_un srvr_addr;
size_t len;
if (!r_ctx || !name)
return ASSUAN_Invalid_Value;
*r_ctx = NULL;
/* we require that the name starts with a slash, so that we can
alter reuse this function for other socket types */
if (*name != '/')
return ASSUAN_Invalid_Value;
if (strlen (name)+1 >= sizeof srvr_addr.sun_path)
return ASSUAN_Invalid_Value;
err = _assuan_new_context (&ctx);
if (err)
return err;
ctx->pid = server_pid; /* save it in case we need it later */
ctx->deinit_handler = do_deinit;
ctx->finish_handler = do_finish;
fd = socket (AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
{
LOGERROR1 ("can't create socket: %s\n", strerror (errno));
_assuan_release_context (ctx);
return ASSUAN_General_Error;
}
memset (&srvr_addr, 0, sizeof srvr_addr );
srvr_addr.sun_family = AF_UNIX;
strcpy (srvr_addr.sun_path, name);
len = (offsetof (struct sockaddr_un, sun_path)
+ strlen (srvr_addr.sun_path) + 1);
if (connect (fd, (struct sockaddr*)&srvr_addr, len) == -1)
{
LOGERROR2 ("can't connect to `%s': %s\n", name, strerror (errno));
_assuan_release_context (ctx);
close (fd );
return ASSUAN_Connect_Failed;
}
ctx->inbound.fd = fd;
ctx->outbound.fd = fd;
/* initial handshake */
{
int okay, off;
err = _assuan_read_from_server (ctx, &okay, &off);
if (err)
{
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
}
else if (okay != 1)
{
LOGERROR ("can't connect server: `");
_assuan_log_sanitized_string (ctx->inbound.line);
LOGERRORX ("'\n");
err = ASSUAN_Connect_Failed;
}
}
if (err)
{
assuan_disconnect (ctx);
}
else
*r_ctx = ctx;
return 0;
}

View File

@ -0,0 +1,139 @@
/* assuan-socket-server.c - Assuan socket based server
* Copyright (C) 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include "assuan-defs.h"
static int
accept_connection (ASSUAN_CONTEXT ctx)
{
int fd;
struct sockaddr_un clnt_addr;
size_t len = sizeof clnt_addr;
ctx->client_pid = (pid_t)-1;
#ifdef USE_GNU_PTH
fd = pth_accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
#else
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
#endif
if (fd == -1)
{
ctx->os_errno = errno;
return ASSUAN_Accept_Failed;
}
#ifdef HAVE_SO_PEERCRED
{
struct ucred cr;
int cl = sizeof cr;
if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) )
ctx->client_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
finish_connection (ASSUAN_CONTEXT ctx)
{
if (ctx->inbound.fd != -1)
{
close (ctx->inbound.fd);
}
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
return 0;
}
static void
deinit_socket_server (ASSUAN_CONTEXT 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 *r_ctx, int listen_fd)
{
ASSUAN_CONTEXT ctx;
int rc;
*r_ctx = NULL;
ctx = xtrycalloc (1, sizeof *ctx);
if (!ctx)
return ASSUAN_Out_Of_Core;
ctx->is_server = 1;
ctx->input_fd = -1;
ctx->output_fd = -1;
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
ctx->listen_fd = listen_fd;
ctx->deinit_handler = deinit_socket_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;
}

View File

@ -0,0 +1,196 @@
/* assuan-util.c - Utility functions for Assuan
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "assuan-defs.h"
#ifdef HAVE_JNLIB_LOGGING
#include "../jnlib/logging.h"
#endif
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 = _assuan_malloc (n*m);
if (p)
memset (p, 0, n* m);
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 ctx, int err, const char *text)
{
ctx->err_no = err;
ctx->err_str = text;
return err;
}
void
assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer)
{
if (ctx)
ctx->user_pointer = pointer;
}
void *
assuan_get_pointer (ASSUAN_CONTEXT ctx)
{
return ctx? ctx->user_pointer : NULL;
}
void
assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp)
{
if (ctx)
{
if (ctx->log_fp)
fflush (ctx->log_fp);
ctx->log_fp = fp;
}
}
void
assuan_begin_confidential (ASSUAN_CONTEXT ctx)
{
if (ctx)
{
ctx->confidential = 1;
}
}
void
assuan_end_confidential (ASSUAN_CONTEXT ctx)
{
if (ctx)
{
ctx->confidential = 0;
}
}
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 (*s < ' ' || (*s >= 0x7f && *s <= 0xa0))
break;
}
s = buffer;
if (!n && *s != '[')
fwrite (buffer, length, 1, fp);
else
{
putc ('[', fp);
for (n=0; n < length; n++, s++)
fprintf (fp, " %02x", *s);
putc (' ', fp);
putc (']', fp);
}
}
/* print a user supplied string after filtering out potential bad
characters*/
void
_assuan_log_sanitized_string (const char *string)
{
const unsigned char *s = string;
#ifdef HAVE_JNLIB_LOGGING
FILE *fp = log_get_stream ();
#else
FILE *fp = stderr;
#endif
for (; *s; s++)
{
if (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
{
putc ('\\', fp);
if (*s == '\n')
putc ('n', fp);
else if (*s == '\r')
putc ('r', fp);
else if (*s == '\f')
putc ('f', fp);
else if (*s == '\v')
putc ('v', fp);
else if (*s == '\b')
putc ('b', fp);
else if (!*s)
putc ('0', fp);
else
fprintf (fp, "x%02x", *s );
}
else
putc (*s, fp);
}
}

View File

@ -0,0 +1,234 @@
/* assuan.c - Definitions for the Assuna protocol
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef ASSUAN_H
#define ASSUAN_H
#include <stdio.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#if 0
}
#endif
#endif
typedef enum {
ASSUAN_No_Error = 0,
ASSUAN_General_Error = 1,
ASSUAN_Out_Of_Core = 2,
ASSUAN_Invalid_Value = 3,
ASSUAN_Timeout = 4,
ASSUAN_Read_Error = 5,
ASSUAN_Write_Error = 6,
ASSUAN_Problem_Starting_Server = 7,
ASSUAN_Not_A_Server = 8,
ASSUAN_Not_A_Client = 9,
ASSUAN_Nested_Commands = 10,
ASSUAN_Invalid_Response = 11,
ASSUAN_No_Data_Callback = 12,
ASSUAN_No_Inquire_Callback = 13,
ASSUAN_Connect_Failed = 14,
ASSUAN_Accept_Failed = 15,
/* error codes above 99 are meant as status codes */
ASSUAN_Not_Implemented = 100,
ASSUAN_Server_Fault = 101,
ASSUAN_Invalid_Command = 102,
ASSUAN_Unknown_Command = 103,
ASSUAN_Syntax_Error = 104,
ASSUAN_Parameter_Error = 105,
ASSUAN_Parameter_Conflict = 106,
ASSUAN_Line_Too_Long = 107,
ASSUAN_Line_Not_Terminated = 108,
ASSUAN_No_Input = 109,
ASSUAN_No_Output = 110,
ASSUAN_Canceled = 111,
ASSUAN_Unsupported_Algorithm = 112,
ASSUAN_Server_Resource_Problem = 113,
ASSUAN_Server_IO_Error = 114,
ASSUAN_Server_Bug = 115,
ASSUAN_No_Data_Available = 116,
ASSUAN_Invalid_Data = 117,
ASSUAN_Unexpected_Command = 118,
ASSUAN_Too_Much_Data = 119,
ASSUAN_Inquire_Unknown = 120,
ASSUAN_Inquire_Error = 121,
ASSUAN_Invalid_Option = 122,
ASSUAN_Invalid_Index = 123,
ASSUAN_Unexpected_Status = 124,
ASSUAN_Unexpected_Data = 125,
ASSUAN_Invalid_Status = 126,
ASSUAN_Not_Confirmed = 128,
ASSUAN_Bad_Certificate = 201,
ASSUAN_Bad_Certificate_Path = 202,
ASSUAN_Missing_Certificate = 203,
ASSUAN_Bad_Signature = 204,
ASSUAN_No_Agent = 205,
ASSUAN_Agent_Error = 206,
ASSUAN_No_Public_Key = 207,
ASSUAN_No_Secret_Key = 208,
ASSUAN_Invalid_Name = 209,
ASSUAN_Cert_Revoked = 301,
ASSUAN_No_CRL_For_Cert = 302,
ASSUAN_CRL_Too_Old = 303,
ASSUAN_Not_Trusted = 304,
ASSUAN_Card_Error = 401,
ASSUAN_Invalid_Card = 402,
ASSUAN_No_PKCS15_App = 403,
ASSUAN_Card_Not_Present = 404,
ASSUAN_Invalid_Id = 405
} AssuanError;
/* This is a list of pre-registered ASSUAN commands */
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;
#define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */
struct assuan_context_s;
typedef struct assuan_context_s *ASSUAN_CONTEXT;
/*-- assuan-handler.c --*/
int assuan_register_command (ASSUAN_CONTEXT ctx,
int cmd_id, const char *cmd_string,
int (*handler)(ASSUAN_CONTEXT, char *));
int assuan_register_bye_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT));
int assuan_register_reset_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT));
int assuan_register_cancel_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT));
int assuan_register_input_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *));
int assuan_register_output_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *));
int assuan_register_option_handler (ASSUAN_CONTEXT ctx,
int (*fnc)(ASSUAN_CONTEXT,
const char*, const char*));
int assuan_process (ASSUAN_CONTEXT ctx);
int assuan_process_next (ASSUAN_CONTEXT ctx);
int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
int *fdarray, int fdarraysize);
FILE *assuan_get_data_fp (ASSUAN_CONTEXT ctx);
AssuanError assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line);
void assuan_write_status (ASSUAN_CONTEXT ctx,
const char *keyword, const char *text);
/*-- assuan-listen.c --*/
AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line);
AssuanError assuan_accept (ASSUAN_CONTEXT ctx);
int assuan_get_input_fd (ASSUAN_CONTEXT ctx);
int assuan_get_output_fd (ASSUAN_CONTEXT ctx);
AssuanError assuan_close_input_fd (ASSUAN_CONTEXT ctx);
AssuanError assuan_close_output_fd (ASSUAN_CONTEXT ctx);
/*-- assuan-pipe-server.c --*/
int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]);
void assuan_deinit_server (ASSUAN_CONTEXT ctx);
/*-- assuan-socket-server.c --*/
int assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd);
/*-- assuan-pipe-connect.c --*/
AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
char *const argv[], int *fd_child_list);
AssuanError assuan_pipe_connect2 (ASSUAN_CONTEXT *ctx, const char *name,
char *const argv[], int *fd_child_list,
unsigned int connect_flags);
/*-- assuan-socket-connect.c --*/
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
pid_t server_pid);
/*-- assuan-connect.c --*/
void assuan_disconnect (ASSUAN_CONTEXT ctx);
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
/*-- assuan-client.c --*/
AssuanError
assuan_transact (ASSUAN_CONTEXT ctx,
const char *command,
AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
void *inquire_cb_arg,
AssuanError (*status_cb)(void*, const char *),
void *status_cb_arg);
/*-- assuan-inquire.c --*/
AssuanError assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
char **r_buffer, size_t *r_length, size_t maxlen);
/*-- assuan-buffer.c --*/
AssuanError assuan_read_line (ASSUAN_CONTEXT ctx,
char **line, size_t *linelen);
int assuan_pending_line (ASSUAN_CONTEXT ctx);
AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line );
AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
const void *buffer, size_t length);
/*-- 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 ctx, FILE *fp);
int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text);
void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer);
void *assuan_get_pointer (ASSUAN_CONTEXT ctx);
void assuan_begin_confidential (ASSUAN_CONTEXT ctx);
void assuan_end_confidential (ASSUAN_CONTEXT ctx);
/*-- assuan-errors.c (built) --*/
const char *assuan_strerror (AssuanError err);
#ifdef __cplusplus
}
#endif
#endif /*ASSUAN_H*/

View File

@ -0,0 +1,71 @@
#!/bin/sh
# mkerrors - Extract error strings from assuan.h
# and create C source for assuan_strerror
# Copyright (C) 2001 Free Software Foundation, Inc.
#
# This file is part of GnuPG.
#
# GnuPG 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.
#
# GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
cat <<EOF
/* Generated automatically by mkerrors */
/* Do not edit! */
#include <stdio.h>
#include "assuan.h"
/**
* 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 (AssuanError err)
{
const char *s;
static char buf[25];
switch (err)
{
EOF
awk '
/ASSUAN_No_Error/ { okay=1 }
!okay {next}
/}/ { exit 0 }
/ASSUAN_[A-Za-z_]*/ { print_code($1) }
function print_code( s )
{
printf " case %s: s=\"", s ;
gsub(/_/, " ", s );
printf "%s\"; break;\n", tolower(substr(s,8));
}
'
cat <<EOF
default: sprintf (buf, "ec=%d", err ); s=buf; break;
}
return s;
}
EOF

149
tags/gpgme-0-3-7/autogen.sh Executable file
View File

@ -0,0 +1,149 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
# It is only needed for the CVS version.
PGM=GPGME
lib_config_files=""
autoconf_vers=2.52
automake_vers=1.5
aclocal_vers=1.5
libtool_vers=1.4
DIE=no
if test "$1" = "--build-w32"; then
shift
target=i386--mingw32
if [ ! -f ./config.guess ]; then
echo "./config.guess not found" >&2
exit 1
fi
host=`./config.guess`
if ! mingw32 --version >/dev/null; then
echo "We need at least version 0.3 of MingW32/CPD" >&2
exit 1
fi
if [ -f config.h ]; then
if grep HAVE_DOSISH_SYSTEM config.h | grep undef >/dev/null; then
echo "Pease run a 'make distclean' first" >&2
exit 1
fi
fi
crossinstalldir=`mingw32 --install-dir`
crossbindir=`mingw32 --get-bindir 2>/dev/null` \
|| crossbindir="$crossinstalldir/bin"
crossdatadir=`mingw32 --get-datadir 2>/dev/null` \
|| crossdatadir="$crossinstalldir/share"
crosslibdir=`mingw32 --get-libdir 2>/dev/null` \
|| crosslibdir="$crossinstalldir/i386--mingw32/lib"
crossincdir=`mingw32 --get-includedir 2>/dev/null` \
|| crossincdir="$crossinstalldir/i386--mingw32/include"
CC=`mingw32 --get-path gcc`
CPP=`mingw32 --get-path cpp`
AR=`mingw32 --get-path ar`
RANLIB=`mingw32 --get-path ranlib`
export CC CPP AR RANLIB
disable_foo_tests=""
if [ -n "$lib_config_files" ]; then
for i in $lib_config_files; do
j=`echo $i | tr '[a-z-]' '[A-Z_]'`
eval "$j=${crossbindir}/$i"
export $j
disable_foo_tests="$disable_foo_tests --disable-`echo $i| \
sed 's,-config$,,'`-test"
if [ ! -f "${crossbindir}/$i" ]; then
echo "$i not installed for MingW32" >&2
DIE=yes
fi
done
fi
[ $DIE = yes ] && exit 1
./configure --host=${host} --target=${target} ${disable_foo_tests} \
--bindir=${crossbindir} --libdir=${crosslibdir} \
--datadir=${crossdatadir} --includedir=${crossincdir} \
--enable-maintainer-mode $*
exit $?
fi
if (autoconf --version) < /dev/null > /dev/null 2>&1 ; then
if (autoconf --version | awk 'NR==1 { if( $3 >= '$autoconf_vers') \
exit 1; exit 0; }');
then
echo "**Error**: "\`autoconf\'" is too old."
echo ' (version ' $autoconf_vers ' or newer is required)'
DIE="yes"
fi
else
echo
echo "**Error**: You must have "\`autoconf\'" installed to compile $PGM."
echo ' (version ' $autoconf_vers ' or newer is required)'
DIE="yes"
fi
if (automake --version) < /dev/null > /dev/null 2>&1 ; then
if (automake --version | awk 'NR==1 { if( $4 >= '$automake_vers') \
exit 1; exit 0; }');
then
echo "**Error**: "\`automake\'" is too old."
echo ' (version ' $automake_vers ' or newer is required)'
DIE="yes"
fi
if (aclocal --version) < /dev/null > /dev/null 2>&1; then
if (aclocal --version | awk 'NR==1 { if( $4 >= '$aclocal_vers' ) \
exit 1; exit 0; }' );
then
echo "**Error**: "\`aclocal\'" is too old."
echo ' (version ' $aclocal_vers ' or newer is required)'
DIE="yes"
fi
else
echo
echo "**Error**: Missing "\`aclocal\'". The version of "\`automake\'
echo " installed doesn't appear recent enough."
DIE="yes"
fi
else
echo
echo "**Error**: You must have "\`automake\'" installed to compile $PGM."
echo ' (version ' $automake_vers ' or newer is required)'
DIE="yes"
fi
if (libtool --version) < /dev/null > /dev/null 2>&1 ; then
if (libtool --version | awk 'NR==1 { if( $4 >= '$libtool_vers') \
exit 1; exit 0; }');
then
echo "**Error**: "\`libtool\'" is too old."
echo ' (version ' $libtool_vers ' or newer is required)'
DIE="yes"
fi
else
echo
echo "**Error**: You must have "\`libtool\'" installed to compile $PGM."
echo ' (version ' $libtool_vers ' or newer is required)'
DIE="yes"
fi
if test "$DIE" = "yes"; then
exit 1
fi
echo "Running libtoolize... Ignore non-fatal messages."
echo "no" | libtoolize
echo "Running aclocal..."
aclocal
echo "Running autoheader..."
autoheader
echo "Running automake --gnu -a ..."
automake --gnu -a
echo "Running autoconf..."
autoconf

View File

@ -0,0 +1,30 @@
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
## Process this file with automake to produce Makefile.in
bin_PROGRAMS = gpgme
INCLUDES = -I$(top_srcdir)/jnlib
LDADD = -L ../jnlib -ljnlib
gpgme_SOURCES = main.c main.h

View File

@ -0,0 +1,20 @@
/* gpgme - Bonbobo component to access GnuPG
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/

View File

@ -0,0 +1,20 @@
/* main.c - Bonbobo component to access GnuPG
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/

View File

@ -0,0 +1,42 @@
/* main.h - GPGME Bonobo component
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef MAIN_H
#define MAIN_H
struct {
int verbose;
int quiet;
unsigned int debug;
char *homedir;
} opt;
#endif /* MAIN_H */

View File

@ -0,0 +1,15 @@
2001-07-30 Werner Koch <wk@gnupg.org>
Encryption basically works.
Copyright 2001 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.

View File

@ -0,0 +1,49 @@
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
## Process this file with automake to produce Makefile.in
# Because there is no free IDL compiler for OLE, we have to distribute
# a binary typelibrary. To generate a new one, copy the idl file to a
# system with an install MIDL and run the command
# midl /nocpp gpgcom.idl
# Sorry, there is no other way yet.
EXTRA_DIST = gpgcom.idl gpgcom.tlb gpgcom.rc vbtest.html vbtest.vbs README
# No need to install this because we are cross-compiling anyway.
noinst_PROGRAMS = gpgcom tgpgcom
INCLUDES = -I$(top_srcdir)/jnlib
LDADD = ../gpgme/libgpgme.la -L ../jnlib -ljnlib -lole32 -loleaut32
gpgcom_LDADD = gpgcom_res.o $(LDADD)
gpgcom_SOURCES = gpgcom.c main.h \
debug.c utf8.c \
igpgme.h igpgme.c
tgpgcom_SOURCES = tgpgcom.c\
debug.c \
igpgme.h
#regtlb_SOURCES = regtlb.c
#guidgen_SOURCES = guidgen.c
gpgcom_res.o: gpgcom.rc
mingw32 windres $< gpgcom_res.o

View File

@ -0,0 +1,72 @@
How to install and use the Gpgcom Windows Component
===================================================
2001-07-31
Installation should be pretty easy:
-----------------------------------
* Get and install the latest GnuPG binary for windows
(ftp://ftp.gnupg.org/gcrypt/binary/gnupg-w32-1.0.6.zip)
* Check that you have an untampered version of this package by
comparing an MD5SUM against the one on the webpage or by checking
the signature of the package using "gpg --verify". See the
webpacge for details.
* Because you are reading this file, you probably have already
unpacked it distribution using a unzip utility :-). You should
find these files:
README - This file
gpgcom.exe - The Gpgcom server
vbtest.html - A Test webpage
vbtest.vbs - A VB script to be used with the cscript utility
* If you are updating Gpgcom, run the old Gpgcom like this:
c:\gnupg\gpgcom -UnregServer
(Replace c:\gnupg with the actually used path)
* Copy the file gpgcom.exe to a some location. C:\gnupg seems to be
a good choice.
* Register the component using this command:
c:\gnupg\gpgcom -RegServer
* Ready
Testing the installation:
-------------------------
* Make sure that you have a working GnuPG (gpg.exe) and that at least
one key is installed.
* Edit the vbtest.vbs script and replace "alice" in the line
gpg.AddRecipient "alice"
with a keyID or user name you have in your key ring.
* Run the test script:
cscript vbtest.vbs
and you should see a valid MIME message with the encrypted text.
Using Gpgcom
------------
Gpgcom currently support only encryption but will be extended to the
full range of operations GnuPG provides. The 2 examples should goive
yopu a hint on how to use it. We suggest that you always set armor to
true, so that the returned text is a string. If you don't use armor,
the "ciphertext" property will return an array with the binary
message.

View File

@ -0,0 +1,40 @@
/* debug.c - COM+ debug helpers
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ole2.h>
const char *
debugstr_guid (const GUID *id)
{
static char str[100];
if (!id)
return "(null)";
sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
id->Data1, id->Data2, id->Data3,
id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
return str;
}

View File

@ -0,0 +1,598 @@
/*
* Copyright 1999 Marcus Meissner
*/
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "winbase.h"
#include "winnls.h"
#include "mmsystem.h"
#include "winerror.h"
#include "debugtools.h"
#include "initguid.h"
#include "vfw.h"
DEFAULT_DEBUG_CHANNEL(avifile);
static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj);
static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface);
static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface);
static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size);
static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam);
static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi);
static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size);
static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size);
static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface);
static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam);
struct ICOM_VTABLE(IAVIFile) iavift = {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IAVIFile_fnQueryInterface,
IAVIFile_fnAddRef,
IAVIFile_fnRelease,
IAVIFile_fnInfo,
IAVIFile_fnGetStream,
IAVIFile_fnCreateStream,
IAVIFile_fnWriteData,
IAVIFile_fnReadData,
IAVIFile_fnEndRecord,
IAVIFile_fnDeleteStream
};
static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj);
static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface);
static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface);
static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2);
static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size);
static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags);
static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize);
static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize);
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread);
static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten);
static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples);
static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread);
static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size);
static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen);
struct ICOM_VTABLE(IAVIStream) iavist = {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IAVIStream_fnQueryInterface,
IAVIStream_fnAddRef,
IAVIStream_fnRelease,
IAVIStream_fnCreate,
IAVIStream_fnInfo,
IAVIStream_fnFindSample,
IAVIStream_fnReadFormat,
IAVIStream_fnSetFormat,
IAVIStream_fnRead,
IAVIStream_fnWrite,
IAVIStream_fnDelete,
IAVIStream_fnReadData,
IAVIStream_fnWriteData,
IAVIStream_fnSetInfo
};
typedef struct IAVIStreamImpl {
/* IUnknown stuff */
ICOM_VFIELD(IAVIStream);
DWORD ref;
/* IAVIStream stuff */
LPVOID lpInputFormat;
DWORD inputformatsize;
BOOL iscompressing;
DWORD curframe;
/* Compressor stuff */
HIC hic;
LPVOID lpCompressFormat;
ICINFO icinfo;
DWORD compbufsize;
LPVOID compbuffer;
DWORD decompbufsize;
LPVOID decompbuffer;
LPVOID decompformat;
AVICOMPRESSOPTIONS aco;
LPVOID lpPrev; /* pointer to decompressed frame later */
LPVOID lpPrevFormat; /* pointer to decompressed info later */
} IAVIStreamImpl;
/***********************************************************************
* AVIFileInit
*/
void WINAPI
AVIFileInit(void) {
FIXME("(),stub!\n");
}
typedef struct IAVIFileImpl {
/* IUnknown stuff */
ICOM_VFIELD(IAVIFile);
DWORD ref;
/* IAVIFile stuff... */
} IAVIFileImpl;
static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) {
ICOM_THIS(IAVIFileImpl,iface);
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
!memcmp(&IID_IAVIFile,refiid,sizeof(IID_IAVIFile))
) {
*obj = iface;
return S_OK;
}
return OLE_E_ENUM_NOMORE;
}
static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) {
ICOM_THIS(IAVIFileImpl,iface);
FIXME("(%p)->AddRef()\n",iface);
return ++(This->ref);
}
static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) {
ICOM_THIS(IAVIFileImpl,iface);
FIXME("(%p)->Release()\n",iface);
if (!--(This->ref)) {
HeapFree(GetProcessHeap(),0,iface);
return 0;
}
return This->ref;
}
static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size) {
FIXME("(%p)->Info(%p,%ld)\n",iface,afi,size);
/* FIXME: fill out struct? */
return E_FAIL;
}
static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
FIXME("(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam);
/* FIXME: create interface etc. */
return E_FAIL;
}
static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
ICOM_THIS(IAVIStreamImpl,iface);
char fcc[5];
IAVIStreamImpl *istream;
FIXME("(%p,%p,%p)\n",This,avis,asi);
istream = (IAVIStreamImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIStreamImpl));
istream->ref = 1;
ICOM_VTBL(istream) = &iavist;
fcc[4]='\0';
memcpy(fcc,(char*)&(asi->fccType),4);
FIXME("\tfccType '%s'\n",fcc);
memcpy(fcc,(char*)&(asi->fccHandler),4);
FIXME("\tfccHandler '%s'\n",fcc);
FIXME("\tdwFlags 0x%08lx\n",asi->dwFlags);
FIXME("\tdwCaps 0x%08lx\n",asi->dwCaps);
FIXME("\tname '%s'\n",debugstr_w(asi->szName));
istream->curframe = 0;
*avis = (PAVISTREAM)istream;
return S_OK;
}
static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size) {
FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,ckid,lpData,size);
/* FIXME: write data to file */
return E_FAIL;
}
static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size) {
FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,ckid,lpData,size);
/* FIXME: read at most size bytes from file */
return E_FAIL;
}
static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface) {
FIXME("(%p)->EndRecord()\n",iface);
/* FIXME: end record? */
return E_FAIL;
}
static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam) {
FIXME("(%p)->DeleteStream(0x%08lx,%ld)\n",iface,fccType,lParam);
/* FIXME: delete stream? */
return E_FAIL;
}
/***********************************************************************
* AVIFileOpenA
*/
HRESULT WINAPI AVIFileOpenA(
PAVIFILE * ppfile,LPCSTR szFile,UINT uMode,LPCLSID lpHandler
) {
IAVIFileImpl *iavi;
FIXME("(%p,%s,0x%08lx,%s),stub!\n",ppfile,szFile,(DWORD)uMode,debugstr_guid(lpHandler));
iavi = (IAVIFileImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIFileImpl));
iavi->ref = 1;
ICOM_VTBL(iavi) = &iavift;
*ppfile = (LPVOID)iavi;
return S_OK;
}
static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) {
ICOM_THIS(IAVIStreamImpl,iface);
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
!memcmp(&IID_IAVIStream,refiid,sizeof(IID_IAVIStream))
) {
*obj = This;
return S_OK;
}
/* can return IGetFrame interface too */
return OLE_E_ENUM_NOMORE;
}
static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) {
ICOM_THIS(IAVIStreamImpl,iface);
FIXME("(%p)->AddRef()\n",iface);
return ++(This->ref);
}
static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) {
ICOM_THIS(IAVIStreamImpl,iface);
FIXME("(%p)->Release()\n",iface);
if (!--(This->ref)) {
HeapFree(GetProcessHeap(),0,This);
return 0;
}
return This->ref;
}
static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2) {
FIXME("(%p)->Create(0x%08lx,0x%08lx)\n",iface,lParam1,lParam2);
return E_FAIL;
}
static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size) {
FIXME("(%p)->Info(%p,%ld)\n",iface,psi,size);
return E_FAIL;
}
static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags) {
FIXME("(%p)->FindSample(%ld,0x%08lx)\n",iface,pos,flags);
return E_FAIL;
}
static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) {
FIXME("(%p)->ReadFormat(%ld,%p,%p)\n",iface,pos,format,formatsize);
return E_FAIL;
}
/***********************************************************************
* IAVIStream::SetFormat
*/
static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) {
IAVIStreamImpl *as = (IAVIStreamImpl*)iface;
FIXME("(%p)->SetFormat(%ld,%p,%ld)\n",iface,pos,format,formatsize);
if (as->lpInputFormat) HeapFree(GetProcessHeap(),0,as->lpInputFormat);
as->inputformatsize = formatsize;
as->lpInputFormat = HeapAlloc(GetProcessHeap(),0,formatsize);
memcpy(as->lpInputFormat,format,formatsize);
if (as->iscompressing) {
int xsize;
/* Set up the Compressor part */
xsize = ICCompressGetFormatSize(as->hic,as->lpInputFormat);
as->lpCompressFormat = HeapAlloc(GetProcessHeap(),0,xsize);
ICCompressGetFormat(as->hic,as->lpInputFormat,as->lpCompressFormat);
ICCompressBegin(as->hic,as->lpInputFormat,as->lpCompressFormat);
as->compbufsize = ICCompressGetSize(as->hic,as->lpInputFormat,as->lpCompressFormat);
as->compbuffer = HeapAlloc(GetProcessHeap(),0,as->compbufsize);
/* Set up the Decompressor part (for prev frames?) */
xsize=ICDecompressGetFormatSize(as->hic,as->lpCompressFormat);
as->decompformat = HeapAlloc(GetProcessHeap(),0,xsize);
ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
as->decompbufsize=((LPBITMAPINFOHEADER)as->decompbuffer)->biSizeImage;
as->decompbuffer = HeapReAlloc(GetProcessHeap(),0,as->decompbuffer,as->decompbufsize);
memset(as->decompbuffer,0xff,as->decompbufsize);
assert(HeapValidate(GetProcessHeap(),0,NULL));
ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
ICDecompressBegin(as->hic,as->lpCompressFormat,as->decompformat);
as->lpPrev = as->lpPrevFormat = NULL;
}
return S_OK;
}
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
FIXME("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",iface,start,samples,buffer,buffersize,bytesread,samplesread);
return E_FAIL;
}
static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
IAVIStreamImpl *as = (IAVIStreamImpl*)iface;
DWORD ckid,xflags;
FIXME("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
ICCompress(
as->hic,flags,
as->lpCompressFormat,
as->compbuffer,
as->lpInputFormat,buffer,
&ckid,&xflags,
as->curframe,0xffffff/*framesize*/,as->aco.dwQuality,
as->lpPrevFormat,as->lpPrev
);
ICDecompress(
as->hic,
flags, /* FIXME: check */
as->lpCompressFormat,
as->compbuffer,
as->decompformat,
as->decompbuffer
);
/* We now have a prev format for the next compress ... */
as->lpPrevFormat = as->decompformat;
as->lpPrev = as->decompbuffer;
return S_OK;
}
static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) {
FIXME("(%p)->Delete(%ld,%ld)\n",iface,start,samples);
return E_FAIL;
}
static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) {
FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,fcc,lp,lpread);
return E_FAIL;
}
static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) {
FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,fcc,lp,size);
return E_FAIL;
}
static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) {
FIXME("(%p)->SetInfo(%p,%ld)\n",iface,info,infolen);
return E_FAIL;
}
/***********************************************************************
* AVIFileCreateStreamA
*/
HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE iface,PAVISTREAM *ppavi,AVISTREAMINFOA * psi) {
AVISTREAMINFOW psiw;
/* Only the szName at the end is different */
memcpy(&psiw,psi,sizeof(*psi)-sizeof(psi->szName));
MultiByteToWideChar( CP_ACP, 0, psi->szName, -1,
psiw.szName, sizeof(psiw.szName) / sizeof(WCHAR) );
return IAVIFile_CreateStream(iface,ppavi,&psiw);
}
/***********************************************************************
* AVIFileCreateStreamW
*/
HRESULT WINAPI AVIFileCreateStreamW(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
return IAVIFile_CreateStream(iface,avis,asi);
}
/***********************************************************************
* AVIFileGetStream
*/
HRESULT WINAPI AVIFileGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
return IAVIFile_GetStream(iface,avis,fccType,lParam);
}
/***********************************************************************
* AVIFileInfoA
*/
HRESULT WINAPI AVIFileInfoA(PAVIFILE iface,LPAVIFILEINFOA afi,LONG size) {
AVIFILEINFOW afiw;
HRESULT hres;
if (size < sizeof(AVIFILEINFOA))
return AVIERR_BADSIZE;
hres = IAVIFile_Info(iface,&afiw,sizeof(afiw));
memcpy(afi,&afiw,sizeof(*afi)-sizeof(afi->szFileType));
WideCharToMultiByte( CP_ACP, 0, afiw.szFileType, -1,
afi->szFileType, sizeof(afi->szFileType), NULL, NULL );
afi->szFileType[sizeof(afi->szFileType)-1] = 0;
return hres;
}
/***********************************************************************
* AVIStreamInfoW
*/
HRESULT WINAPI AVIStreamInfoW(PAVISTREAM iface,AVISTREAMINFOW *asi,LONG
size) {
return IAVIFile_Info(iface,asi,size);
}
/***********************************************************************
* AVIStreamInfoA
*/
HRESULT WINAPI AVIStreamInfoA(PAVISTREAM iface,AVISTREAMINFOA *asi,LONG
size) {
AVISTREAMINFOW asiw;
HRESULT hres;
if (size<sizeof(AVISTREAMINFOA))
return AVIERR_BADSIZE;
hres = IAVIFile_Info(iface,&asiw,sizeof(asiw));
memcpy(asi,&asiw,sizeof(asiw)-sizeof(asiw.szName));
WideCharToMultiByte( CP_ACP, 0, asiw.szName, -1,
asi->szName, sizeof(asi->szName), NULL, NULL );
asi->szName[sizeof(asi->szName)-1] = 0;
return hres;
}
/***********************************************************************
* AVIFileInfoW
*/
HRESULT WINAPI AVIFileInfoW(PAVIFILE iface,LPAVIFILEINFOW afi,LONG size) {
return IAVIFile_Info(iface,afi,size);
}
/***********************************************************************
* AVIMakeCompressedStream
*/
HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *aco,CLSID *pclsidHandler) {
char fcc[5];
IAVIStreamImpl *as;
FIXME("(%p,%p,%p,%p)\n",ppsCompressed,ppsSource,aco,pclsidHandler);
fcc[4]='\0';
memcpy(fcc,&(aco->fccType),4);
FIXME("\tfccType: '%s'\n",fcc);
memcpy(fcc,&(aco->fccHandler),4);
FIXME("\tfccHandler: '%s'\n",fcc);
FIXME("\tdwFlags: 0x%08lx\n",aco->dwFlags);
/* we just create a duplicate for now */
IAVIStream_AddRef(ppsSource);
*ppsCompressed = ppsSource;
as = (IAVIStreamImpl*)ppsSource;
/* this is where the fun begins. Open a compressor and prepare it. */
as->hic = ICOpen(aco->fccType,aco->fccHandler,ICMODE_COMPRESS);
/* May happen. for instance if the codec is not able to compress */
if (!as->hic)
return AVIERR_UNSUPPORTED;
ICGetInfo(as->hic,&(as->icinfo),sizeof(ICINFO));
FIXME("Opened compressor: '%s' '%s'\n",debugstr_w(as->icinfo.szName),debugstr_w(as->icinfo.szDescription));
as->iscompressing = TRUE;
memcpy(&(as->aco),aco,sizeof(*aco));
if (as->icinfo.dwFlags & VIDCF_COMPRESSFRAMES) {
ICCOMPRESSFRAMES icf;
/* now what to fill in there ... Hmm */
memset(&icf,0,sizeof(icf));
icf.lDataRate = aco->dwBytesPerSecond;
icf.lQuality = aco->dwQuality;
icf.lKeyRate = aco->dwKeyFrameEvery;
icf.GetData = (void *)0xdead4242;
icf.PutData = (void *)0xdead4243;
ICSendMessage(as->hic,ICM_COMPRESS_FRAMES_INFO,(LPARAM)&icf,sizeof(icf));
}
return S_OK;
}
/***********************************************************************
* AVIStreamSetFormat
*/
HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG formatsize) {
return IAVIStream_SetFormat(iface,pos,format,formatsize);
}
/***********************************************************************
* AVIStreamReadFormat
*/
HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG *formatsize) {
return IAVIStream_ReadFormat(iface,pos,format,formatsize);
}
/***********************************************************************
* AVIStreamWrite(
*/
HRESULT WINAPI AVIStreamWrite(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
return IAVIStream_Write(iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
}
/***********************************************************************
* AVIStreamRead
*/
HRESULT WINAPI AVIStreamRead(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
return IAVIStream_Read(iface,start,samples,buffer,buffersize,bytesread,samplesread);
}
/***********************************************************************
* AVIStreamWriteData
*/
HRESULT WINAPI AVIStreamWriteData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG size) {
return IAVIStream_WriteData(iface,fcc,lp,size);
}
/***********************************************************************
* AVIStreamReadData
*/
HRESULT WINAPI AVIStreamReadData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG *lpread) {
return IAVIStream_ReadData(iface,fcc,lp,lpread);
}
/***********************************************************************
* AVIStreamStart
*/
LONG WINAPI AVIStreamStart(PAVISTREAM iface) {
AVISTREAMINFOW si;
IAVIStream_Info(iface,&si,sizeof(si));
return si.dwStart;
}
/***********************************************************************
* AVIStreamLength
*/
LONG WINAPI AVIStreamLength(PAVISTREAM iface) {
AVISTREAMINFOW si;
HRESULT ret;
ret = IAVIStream_Info(iface,&si,sizeof(si));
if (ret) /* error */
return 1;
return si.dwLength;
}
/***********************************************************************
* AVIStreamRelease
*/
ULONG WINAPI AVIStreamRelease(PAVISTREAM iface) {
return IAVIStream_Release(iface);
}
/***********************************************************************
* AVIStreamGetFrameOpen
*/
PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM iface,LPBITMAPINFOHEADER bmi) {
FIXME("(%p)->(%p),stub!\n",iface,bmi);
return NULL;
}
/***********************************************************************
* AVIStreamGetFrame
*/
LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg,LONG pos) {
return IGetFrame_GetFrame(pg,pos);
}
/***********************************************************************
* AVIStreamGetFrameClose
*/
HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg) {
if (pg) IGetFrame_Release(pg);
return 0;
}
/***********************************************************************
* AVIFileRelease
*/
ULONG WINAPI AVIFileRelease(PAVIFILE iface) {
return IAVIFile_Release(iface);
}
/***********************************************************************
* AVIFileExit
*/
void WINAPI AVIFileExit(void) {
FIXME("(), stub.\n");
}

View File

@ -0,0 +1,545 @@
/* gpgcom.c - COM+ component to access GnuPG
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#include <windows.h>
#include <ole2.h>
#include "argparse.h"
#include "main.h"
#include "igpgme.h"
static void register_server (void);
static void unregister_server (void);
static void enter_complus (void);
enum cmd_and_opt_values { aNull = 0,
oQuiet = 'q',
oVerbose = 'v',
oNoVerbose = 500,
oOptions,
oDebug,
oDebugAll,
oNoGreeting,
oNoOptions,
oHomedir,
oGPGBinary,
oRegServer,
oUnregServer,
oEmbedding,
aTest };
static ARGPARSE_OPTS opts[] = {
{ 301, NULL, 0, N_("@Options:\n ") },
{ oVerbose, "verbose", 0, N_("verbose") },
{ oQuiet, "quiet", 0, N_("be somewhat more quiet") },
{ oOptions, "options" , 2, N_("read options from file")},
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
{ oGPGBinary, "gpg-program", 2 , "" },
{ oRegServer, "RegServer" , 0, "" },
{ oUnregServer, "UnregServer" , 0, "" },
{ oEmbedding, "Embedding" , 0, "" },
{0} };
static const char *
my_strusage( int level )
{
const char *p;
switch( level ) {
case 11: p = "gpgcom";
break;
case 13: p = VERSION; break;
/*case 17: p = PRINTABLE_OS_NAME; break;*/
case 19: p =
_("Please report bugs to <gpgme-bugs@gnupg.org>.\n");
break;
case 1:
case 40: p =
_("Usage: gpgcom [options] (-h for help)");
break;
case 41: p =
_("Syntax: gpgcom [options]\n"
"GnuPG COM+ component\n");
break;
default: p = NULL;
}
return p;
}
int
main (int argc, char **argv )
{
ARGPARSE_ARGS pargs;
int orig_argc;
char **orig_argv;
FILE *configfp = NULL;
char *configname = NULL;
unsigned configlineno;
int parse_debug = 0;
int default_config =1;
int greeting = 0;
int nogreeting = 0;
int action = 0;
set_strusage( my_strusage );
/*log_set_name ("gpa"); not yet implemented in logging.c */
opt.homedir = getenv("GNUPGHOME");
if( !opt.homedir || !*opt.homedir ) {
#ifdef HAVE_DRIVE_LETTERS
opt.homedir = "c:/gnupg";
#else
opt.homedir = "~/.gnupg";
#endif
}
/* check whether we have a config file on the commandline */
orig_argc = argc;
orig_argv = argv;
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */
while( arg_parse( &pargs, opts) ) {
if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
parse_debug++;
else if( pargs.r_opt == oOptions ) {
/* yes there is one, so we do not try the default one, but
* read the option file when it is encountered at the commandline
*/
default_config = 0;
}
else if( pargs.r_opt == oNoOptions )
default_config = 0; /* --no-options */
else if( pargs.r_opt == oHomedir )
opt.homedir = pargs.r.ret_str;
}
if( default_config )
configname = make_filename(opt.homedir, "gpgme.conf", NULL );
argc = orig_argc;
argv = orig_argv;
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1 | (1<<5); /* do not remove the args, allow one dash */
next_pass:
if( configname ) {
configlineno = 0;
configfp = fopen( configname, "r" );
if( !configfp ) {
if( default_config ) {
if( parse_debug )
log_info(_("NOTE: no default option file `%s'\n"),
configname );
}
else {
log_error(_("option file `%s': %s\n"),
configname, strerror(errno) );
exit(2);
}
free(configname); configname = NULL;
}
if( parse_debug && configname )
log_info(_("reading options from `%s'\n"), configname );
default_config = 0;
}
while( optfile_parse( configfp, configname, &configlineno,
&pargs, opts) ) {
switch( pargs.r_opt ) {
case oQuiet: opt.quiet = 1; break;
case oVerbose: opt.verbose++; break;
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
case oDebugAll: opt.debug = ~0; break;
case oOptions:
/* config files may not be nested (silently ignore them) */
if( !configfp ) {
free(configname);
configname = xstrdup(pargs.r.ret_str);
goto next_pass;
}
break;
case oNoGreeting: nogreeting = 1; break;
case oNoVerbose: opt.verbose = 0; break;
case oNoOptions: break; /* no-options */
case oHomedir: opt.homedir = pargs.r.ret_str; break;
case oGPGBinary: break;
case oRegServer: action = 1; break;
case oUnregServer: action = 2; break;
case oEmbedding: action = 3; break;
default : pargs.err = configfp? 1:2; break;
}
}
if( configfp ) {
fclose( configfp );
configfp = NULL;
free(configname); configname = NULL;
goto next_pass;
}
free( configname ); configname = NULL;
if( log_get_errorcount(0) )
exit(2);
if( nogreeting )
greeting = 0;
if( greeting ) {
fprintf(stderr, "%s %s; %s\n",
strusage(11), strusage(13), strusage(14) );
fprintf(stderr, "%s\n", strusage(15) );
}
#ifdef IS_DEVELOPMENT_VERSION
log_info("NOTE: this is a development version!\n");
#endif
if ( action == 1 )
register_server ();
else if (action == 2 )
unregister_server ();
else if (action == 3 )
enter_complus ();
else {
fprintf (stderr, "This is a COM+ component with no user interface.\n"
"gpgme --help will give you a list of options\n" );
exit (1);
}
return 0;
}
static void
register_progid ( const char *name )
{
HKEY hk = 0;
char buf[500];
/* Create a ProgID entry to point to the ClassID */
sprintf (buf, "%.400s", name);
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
sprintf (buf, "g10 Code's GnuPG made easy COMponent" );
if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, 0)) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
sprintf (buf, "%.400s\\CLSID", name);
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
sprintf (buf, "%.100s", debugstr_guid (&CLSID_Gpgme) );
if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
hk = 0;
}
static void
register_typelib (void)
{
ITypeLib *pTypeLib;
HRESULT hr;
char name[500];
wchar_t *wname;
size_t n;
if ( !GetModuleFileNameA (0, name, sizeof (name)-10) ) {
fprintf (stderr,"GetModuleFileName() failed: %d\n",
(int)GetLastError());
exit (1);
}
n = mbstowcs (NULL, name, strlen(name)+1);
wname = xmalloc ((n+1)*sizeof *wname);
mbstowcs (wname, name, strlen (name)+1);
hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
if (hr)
fprintf (stderr, "CoInitializeEx() failed: hr=%lu\n", hr);
hr = LoadTypeLibEx (wname, REGKIND_REGISTER, &pTypeLib);
if (hr)
fprintf (stderr, "LoadTypeLibEx() failed: hr=%lx\n", hr);
ITypeLib_Release (pTypeLib);
CoUninitialize ();
free (wname);
}
static void
unregister_typelib (void)
{
UnRegisterTypeLib (&TLBID_Gpgcom, 1, 0, LANG_NEUTRAL, SYS_WIN32);
}
static void
register_server ()
{
HKEY hk = 0;
char buf[500];
register_typelib ();
/* Create a key for the CLSID */
sprintf (buf, "CLSID\\%.100s", debugstr_guid (&CLSID_Gpgme) );
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
/* Store our class name as default value */
strcpy (buf, "Gpgme");
if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
/* Set the application ID */
sprintf (buf, "%.100s", debugstr_guid (&APPID_Gpgcom) );
if (RegSetValueExA (hk, "AppID", 0, REG_SZ, buf, strlen (buf))) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
hk = 0;
/* Create the LocalServer32 subkey under the CLSID key */
sprintf (buf, "CLSID\\%.100s\\LocalServer32",
debugstr_guid (&CLSID_Gpgme) );
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
/* retrieve the module name and add it under the key */
if ( !GetModuleFileNameA (0, buf, sizeof (buf)-10) ) {
fprintf (stderr,"GetModuleFileName() failed\n");
exit (1);
}
if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
hk = 0;
/* Create the ProgID subkey under the CLSID key */
sprintf (buf, "CLSID\\%.100s\\ProgID",
debugstr_guid (&CLSID_Gpgme) );
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
if (RegSetValueExA (hk, 0, 0, REG_SZ, "Gpgcom.Gpgme.1", 0)) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
hk = 0;
/* Create the VersionIndependentProgID subkey under the CLSID key */
sprintf (buf, "CLSID\\%.100s\\VersionIndependentProgID",
debugstr_guid (&CLSID_Gpgme) );
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
if (RegSetValueExA (hk, 0, 0, REG_SZ, "Gpgcom.Gpgme", 0)) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
hk = 0;
/* Create a key to store AppID info */
sprintf (buf, "AppID\\%.100s", debugstr_guid (&APPID_Gpgcom) );
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
/* Store the name as default value */
strcpy (buf, "Gpgcom");
if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
hk = 0;
register_progid ("Gpgcom.Gpgme");
register_progid ("Gpgcom.Gpgme.1");
/* Create a convenience cross reference to the AppID */
sprintf (buf, "AppID\\gpgcom.exe");
if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) {
fprintf (stderr,"RegCreateKey(`%s') failed\n", buf);
exit (1);
}
sprintf (buf, "%.100s", debugstr_guid (&APPID_Gpgcom) );
if (RegSetValueExA (hk, "AppID", 0, REG_SZ, buf, strlen (buf))) {
fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf);
exit (1);
}
if (RegCloseKey (hk)) {
fprintf (stderr,"RegCloseKey() failed\n");
exit (1);
}
hk = 0;
fprintf (stderr,"*** Component registered\n");
}
static void
unregister_server ()
{
char buf[500];
unregister_typelib ();
sprintf (buf, "CLSID\\%.100s\\LocalServer32",
debugstr_guid (&CLSID_Gpgme) );
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "CLSID\\%.100s\\ProgID", debugstr_guid (&CLSID_Gpgme) );
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "CLSID\\%.100s", debugstr_guid (&CLSID_Gpgme) );
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "Gpgcom.Gpgme.1\\CLSID");
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "Gpgcom.Gpgme.1");
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "Gpgcom.Gpgme\\CLSID");
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "Gpgcom.Gpgme");
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "AppID\\%.100s", debugstr_guid (&APPID_Gpgcom) );
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
sprintf (buf, "AppID\\gpgcom.exe" );
if (RegDeleteKey (HKEY_CLASSES_ROOT, buf))
fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf);
fprintf (stderr,"*** component unregistered\n");
}
static void
enter_complus ()
{
HANDLE running;
DWORD reg;
IClassFactory *factory;
CLSID clsid;
HRESULT hr;
fprintf (stderr,"*** enter enter_complus()\n");
CoInitializeEx (NULL, COINIT_MULTITHREADED);
running = CreateEvent (NULL, FALSE, FALSE, NULL );
fprintf (stderr,"*** CoInitialize() done; event=%lx\n", (unsigned long)running );
igpgme_register_exit_event (running);
factory = igpgme_factory_new ( &clsid );
fprintf (stderr,"*** igpgme_factory_new() done; got=%p\n", factory );
hr = CoRegisterClassObject (&clsid, (IUnknown*)factory,
CLSCTX_LOCAL_SERVER,
REGCLS_SUSPENDED|REGCLS_MULTIPLEUSE, &reg );
if (hr) {
fprintf (stderr, "CoRegisterClassObject() failed: hr=%lx\n", hr);
exit (1);
}
hr = CoResumeClassObjects ();
if (hr)
fprintf (stderr, "CoRegisterClassObject() failed: hr=%lx\n", hr);
fprintf (stderr,"*** class object registered; waiting\n" );
WaitForSingleObject ( running, INFINITE );
fprintf (stderr,"*** shutting down\n" );
igpgme_register_exit_event (NULL);
CloseHandle (running);
CoRevokeClassObject ( reg );
fprintf (stderr,"*** class object revoked\n" );
igpgme_factory_release (factory);
fprintf (stderr,"*** factory released\n" );
CoUninitialize ();
fprintf (stderr,"*** leave enter_complus()\n" );
}

View File

@ -0,0 +1,62 @@
/* ignupg.idl - Interface definition for the COM+ class GnuPG
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
import "unknwn.idl";
import "oaidl.idl";
[ object, uuid(3811fd50-7f72-11d5-8c9e-0080ad190cd5), dual]
interface IGpgme : IDispatch
{
HRESULT GetVersion([out] BSTR *retval);
HRESULT GetEngineInfo([out] BSTR *retval);
HRESULT Cancel(void);
[propput] HRESULT Armor([in] BOOL flag);
[propget] HRESULT Armor([out, retval] BOOL *retval);
[propput] HRESULT Textmode([in] BOOL flag);
[propget] HRESULT Textmode([out, retval] BOOL *retval);
[propput] HRESULT Plaintext([in] VARIANT val);
[propget] HRESULT Plaintext([out, retval] VARIANT *retval);
[propput] HRESULT Ciphertext([in] VARIANT val);
[propget] HRESULT Ciphertext([out,retval] VARIANT *retval);
HRESULT ClearRecipients(void);
HRESULT AddRecipient([in] BSTR name,
[in, optional, defaultvalue(-1)] signed short trust);
HRESULT ResetSignKeys(void);
HRESULT AddSignKey([in] BSTR name);
HRESULT Encrypt(void);
HRESULT Sign([in,optional,defaultvalue(0)] signed short signmode);
HRESULT SignEncrypt([in,optional,defaultvalue(0)] signed short signmode);
};
[ uuid(3811fd48-7f72-11d5-8c9e-0080ad190cd5),
helpstring("g10Code.gpgcom, type library"),
version(1.0) ]
library GpgcomLib
{
[ uuid(3811fd40-7f72-11d5-8c9e-0080ad190cd5) ]
coclass Gpgcom
{
[default] interface IGpgme;
}
};

View File

@ -0,0 +1,22 @@
/* gpgcom.rc - Resource file for gpgcom
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
1 TYPELIB "gpgcom.tlb"

Binary file not shown.

View File

@ -0,0 +1,130 @@
/* guidgen.c - Tool to create GUIDs
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#include <windows.h>
#include "obj_base.h"
#include "argparse.h"
enum cmd_and_opt_values { aNull = 0,
oVerbose = 'v',
aTest };
static ARGPARSE_OPTS opts[] = {
{ 301, NULL, 0, "@Options:\n " },
{ oVerbose, "verbose", 0, "verbose" },
{0} };
static struct {
int verbose;
} opt;
static void create_guid (void);
static const char *
my_strusage( int level )
{
const char *p;
switch( level ) {
case 11: p = "guidgen";
break;
case 13: p = VERSION; break;
/*case 17: p = PRINTABLE_OS_NAME; break;*/
case 19: p =
"Please report bugs to <gpgme-bugs@gnupg.org>.\n";
break;
case 1:
case 40: p =
"Usage: guidgen [options] (-h for help)";
break;
case 41: p =
"Syntax: guidgen [options]\n"
"Generate GUIDs\n";
break;
default: p = NULL;
}
return p;
}
int
main (int argc, char **argv )
{
ARGPARSE_ARGS pargs;
set_strusage( my_strusage );
/*log_set_name ("gpa"); not yet implemented in logging.c */
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 0;
while( arg_parse( &pargs, opts) ) {
switch( pargs.r_opt ) {
case oVerbose: opt.verbose++; break;
default : pargs.err = 2; break;
}
}
if (!argc)
create_guid();
else {
int n;
for (n = atoi (argv[0]); n > 0; n-- )
create_guid ();
}
return 0;
}
static void
create_guid ()
{
GUID guid, *id;
id = &guid;
if ( CoCreateGuid (id) ) {
fprintf (stderr,"failed to create GUID\n");
exit (1);
}
printf( "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
id->Data1, id->Data2, id->Data3,
id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
}

View File

@ -0,0 +1,859 @@
/* igpgme.c - COM+ class IGpgme
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#include <windows.h>
#include "../gpgme/gpgme.h"
/* FIXME: Put them into an extra header */
void *_gpgme_malloc (size_t n );
void *_gpgme_calloc (size_t n, size_t m );
void *_gpgme_realloc (void *p, size_t n);
char *_gpgme_strdup (const char *p);
void _gpgme_free ( void *a );
#define INITGUID
#include "igpgme.h"
/*
* Declare the interface implementation structures
*/
typedef struct IGpgmeImpl IGpgmeImpl;
typedef struct IClassFactoryImpl IClassFactoryImpl;
static HANDLE my_exit_event;
struct IGpgmeImpl {
/* IUnknown required stuff */
ICOM_VFIELD (IGpgme);
DWORD ref;
/* Delegation to IDispatch */
struct {
IUnknown *disp;
ITypeInfo *tinfo;
} std_disp;
/* Our stuff */
GpgmeCtx mainctx;
GpgmeData plaintext;
int plaintext_given_as_bstr;
GpgmeData ciphertext;
int ciphertext_is_armored;
GpgmeRecipients rset;
};
struct IClassFactoryImpl {
/* IUnknown fields */
ICOM_VFIELD(IClassFactory);
DWORD ref;
};
/**********************************************************
************** helper functions ************************
*********************************************************/
static HRESULT
map_gpgme_error (GpgmeError err)
{
HRESULT hr;
if (!err)
return 0;
if ( err < 0 || err > 0x1000 ) {
fprintf (stderr,"*** GpgmeError `%s' mapped to GPGME_General_Error\n",
gpgme_strerror (err) );
err = GPGME_General_Error;
}
hr = MAKE_HRESULT (SEVERITY_ERROR, FACILITY_ITF, 0x1000 + err);
fprintf (stderr,"*** GpgmeError `%s' mapped to %lx\n",
gpgme_strerror (err), (unsigned long)hr );
return hr;
}
/**********************************************************
************** IGpgme Implementation *******************
*********************************************************/
static HRESULT WINAPI
m_IGpgme_QueryInterface (IGpgme *iface, REFIID refiid, LPVOID *obj)
{
ICOM_THIS (IGpgmeImpl,iface);
/*fprintf (stderr,"*** m_IGpgme_QueryInterface(%p,%s)",
This, debugstr_guid(refiid));*/
if ( IsEqualGUID (&IID_IUnknown, refiid)
|| IsEqualGUID (&IID_IGpgme, refiid) ) {
*obj = This;
IGpgme_AddRef (iface);
fprintf (stderr," -> got %p\n", *obj);
return 0;
}
else if ( IsEqualGUID (&IID_IDispatch, refiid) ) {
HRESULT hr = IDispatch_QueryInterface (This->std_disp.disp,
refiid, obj);
/*fprintf (stderr," -> delegated, hr=%lx, got %p\n",
hr, hr? NULL: *obj);*/
return hr;
}
/*fprintf (stderr," -> none\n");*/
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI
m_IGpgme_AddRef (IGpgme *iface)
{
ICOM_THIS (IGpgmeImpl,iface);
return ++This->ref;
}
static ULONG WINAPI
m_IGpgme_Release (IGpgme *iface)
{
ICOM_THIS (IGpgmeImpl,iface);
if (--This->ref)
return This->ref;
gpgme_release (This->mainctx); This->mainctx = NULL;
gpgme_data_release (This->plaintext); This->plaintext = NULL;
gpgme_data_release (This->ciphertext); This->ciphertext = NULL;
gpgme_recipients_release (This->rset); This->rset = NULL;
if (This->std_disp.disp)
IDispatch_Release (This->std_disp.disp);
if (This->std_disp.tinfo)
ITypeInfo_Release (This->std_disp.tinfo);
HeapFree(GetProcessHeap(),0,iface);
{
ULONG count = CoReleaseServerProcess ();
if (!count && my_exit_event)
SetEvent (my_exit_event);
}
return 0;
}
static HRESULT WINAPI
m_stub_IDispatch_GetTypeInfoCount (IGpgme *iface, unsigned int *pctinfo)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_stub_IDispatch_GetTypeInfo (IGpgme *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_stub_IDispatch_GetIDsOfNames (IGpgme *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames,
LCID lcid, DISPID *rgDispId)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_stub_IDispatch_Invoke (IGpgme *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExepInfo, UINT *puArgErr)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_IGpgme_GetVersion (IGpgme *iface, BSTR *retvat)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_IGpgme_GetEngineInfo (IGpgme *iface, BSTR *retval)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_IGpgme_Cancel (IGpgme *iface)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_IGpgme_SetArmor (IGpgme *iface, BOOL yes)
{
ICOM_THIS (IGpgmeImpl,iface);
gpgme_set_armor (This->mainctx, yes);
return 0;
}
static HRESULT WINAPI
m_IGpgme_GetArmor (IGpgme *iface, BOOL *retval)
{
ICOM_THIS (IGpgmeImpl,iface);
*retval = gpgme_get_armor (This->mainctx);
return 0;
}
static HRESULT WINAPI
m_IGpgme_SetTextmode (IGpgme *iface, BOOL yes)
{
ICOM_THIS (IGpgmeImpl,iface);
gpgme_set_textmode (This->mainctx, yes);
return 0;
}
static HRESULT WINAPI
m_IGpgme_GetTextmode (IGpgme *iface, BOOL *retval)
{
ICOM_THIS (IGpgmeImpl,iface);
*retval = gpgme_get_textmode (This->mainctx);
return 0;
}
/*
* Put the data from VAL into a a Gpgme data object, which is passed by
* reference. Valid types of the Variant are: BSTR, SAFEARRAY of BYTE and
* SAFEARRAY of VARIANTS of signed or unsigned integers.
*/
static HRESULT WINAPI
set_data_from_variant (GpgmeData *data, VARIANT val, int *given_as_bstr)
{
GpgmeError err = 0;
HRESULT hr;
unsigned char *buf;
SAFEARRAY *array;
size_t len;
int i;
if ( val.vt == VT_BSTR) {
len = bstrtoutf8 (val.u.bstrVal, NULL, 0);
buf = _gpgme_malloc (len);
if (!buf)
return E_OUTOFMEMORY;
if (bstrtoutf8 (val.u.bstrVal, buf, len) < 0) {
fprintf (stderr,"problem with bstrtoutf8\n");
_gpgme_free (buf);
return E_FAIL;
}
#if 0
fprintf (stderr,"Got a BSTR (utf8):");
for (i=0; i < len; i++)
fprintf (stderr, " %0X", buf[i] );
putc ('\n', stderr);
#endif
gpgme_data_release (*data); *data = NULL;
err = gpgme_data_new_from_mem (data, buf, len, 0 /*no need to copy*/ );
if (!err && given_as_bstr)
*given_as_bstr = 1;
}
else if ( val.vt == (VT_ARRAY|VT_UI1)) {
array = val.u.parray;
/*fprintf (stderr,"Got an ARRAY of bytes:");*/
hr = SafeArrayAccessData (array, (void**)&buf);
if (hr) {
fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr);
return hr;
}
len = array->rgsabound[0].cElements;
/*for (i=0; i < len; i++)
fprintf (stderr, " %0X", buf[i] );
putc ('\n', stderr);*/
gpgme_data_release (*data); *data = NULL;
err = gpgme_data_new_from_mem (data, buf, len, 1 );
SafeArrayUnaccessData (array);
if (given_as_bstr)
*given_as_bstr = 0;
}
else if ( val.vt == (VT_ARRAY|VT_VARIANT)) {
VARIANT *vp;
array = val.u.parray;
/*fprintf (stderr,"Got an ARRAY of VARIANTS:");*/
hr = SafeArrayAccessData (array, (void**)&vp);
if (hr) {
fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr);
return hr;
}
len = array->rgsabound[0].cElements;
/* allocate the array using the gpgme allocator so that we can
* later use a new without the copy set*/
buf = _gpgme_malloc (len);
if (!buf) {
SafeArrayUnaccessData (array);
return E_OUTOFMEMORY;
}
/* coerce all array elements into rawtext */
for (i=0; i < len; i++) {
switch (vp[i].vt) {
case VT_I1: buf[i] = (BYTE)vp[i].u.cVal; break;
case VT_I2: buf[i] = ((UINT)vp[i].u.iVal) & 0xff; break;
case VT_I4: buf[i] = ((ULONG)vp[i].u.lVal) & 0xff; break;
case VT_INT: buf[i] = ((UINT)vp[i].u.intVal) & 0xff; break;
case VT_UI1: buf[i] = vp[i].u.bVal; break;
case VT_UI2: buf[i] = vp[i].u.uiVal & 0xff; break;
case VT_UI4: buf[i] = vp[i].u.ulVal & 0xff; break;
case VT_UINT: buf[i] = vp[i].u.uintVal & 0xff; break;
default:
fprintf (stderr, "Invalid value in array as pos %d\n", i);
_gpgme_free (buf);
SafeArrayUnaccessData (array);
return E_INVALIDARG;
}
}
/*for (i=0; i < len; i++)
fprintf (stderr, " %0X", buf[i] );
putc ('\n', stderr);*/
gpgme_data_release (*data); *data = NULL;
err = gpgme_data_new_from_mem (data, buf, len, 0);
SafeArrayUnaccessData (array);
if (given_as_bstr)
*given_as_bstr = 0;
}
else {
fprintf (stderr, "Got a variant type = %d (0x%x)\n",
(int)val.vt, (int)val.vt );
return E_INVALIDARG; /* not a safearray of bytes */
}
return map_gpgme_error (err);
}
static HRESULT WINAPI
set_data_to_variant (GpgmeData data, VARIANT *retval, int use_bstr)
{
GpgmeError err;
HRESULT hr;
SAFEARRAY *array;
char *p;
size_t nread, len;
int i;
/* Get some info on the data */
err = gpgme_data_rewind (data);
if (err ) {
fprintf (stderr, "*** gpgme_data_rewind failed: %d\n", err);
return map_gpgme_error (err);
}
err = gpgme_data_read (data, NULL, 0, &nread);
if (err && err != GPGME_EOF ) {
fprintf (stderr, "*** gpgme_data_read [length] failed: %d\n", err);
return map_gpgme_error (err);
}
len = nread; /*(eof returns a length of 0)*/
/*fprintf (stderr,"*** %d bytes are availabe\n", (int)len);*/
/* convert it to the target data type */
if (use_bstr) {
BSTR bs;
unsigned char *helpbuf;
/* It is easier to allocate some helper storage */
helpbuf = _gpgme_malloc (len);
if (!helpbuf)
return E_OUTOFMEMORY;
err = gpgme_data_read (data, helpbuf, len, &nread);
if (err ) {
_gpgme_free (helpbuf);
fprintf (stderr, "*** gpgme_data_read [data] failed: %d\n", err);
return map_gpgme_error (err);
}
bs = SysAllocStringLen (NULL, len+1);
if (!bs) {
_gpgme_free (helpbuf);
return E_OUTOFMEMORY;
}
for (i=0, p=helpbuf; i < len; i++, p++)
bs[i] = *p;
bs[i] = 0;
_gpgme_free (helpbuf);
/* Ready */
VariantInit (retval);
retval->vt = VT_BSTR;
retval->u.bstrVal = bs;
}
#if 0
else if (use_byte_array) {
array = SafeArrayCreateVector (VT_UI1, 0, len);
if (!array)
return E_OUTOFMEMORY;
p = NULL;
hr = SafeArrayAccessData (array, (void**)&p);
if (hr) {
fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr);
SafeArrayDestroyData (array);
SafeArrayDestroy (array);
return hr;
}
if (len) {
err = gpgme_data_read (data, p, len, &nread);
if (err ) {
SafeArrayUnaccessData (array);
SafeArrayDestroyData (array);
SafeArrayDestroy (array);
fprintf (stderr, "*** gpgme_data_read [data] failed: %d\n",
err);
return map_gpgme_error (err);
}
}
SafeArrayUnaccessData (array);
/* pass the data to the caller */
VariantInit (retval);
retval->vt = (VT_ARRAY|VT_UI1);
retval->u.parray = array;
}
#endif
else { /* Create an array of variants of bytes */
VARIANT *v;
unsigned char *helpbuf;
/* It is easier to allocate some helper storage */
helpbuf = _gpgme_malloc (len);
if (!helpbuf)
return E_OUTOFMEMORY;
err = gpgme_data_read (data, helpbuf, len, &nread);
if (err ) {
_gpgme_free (helpbuf);
fprintf (stderr, "*** gpgme_data_read [data] failed: %d\n", err);
return map_gpgme_error (err);
}
/* The create the array */
array = SafeArrayCreateVector (VT_VARIANT, 0, len);
if (!array) {
_gpgme_free (helpbuf);
return E_OUTOFMEMORY;
}
v = NULL;
hr = SafeArrayAccessData (array, (void**)&v);
if (hr) {
fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr);
_gpgme_free (helpbuf);
SafeArrayDestroyData (array);
SafeArrayDestroy (array);
return hr;
}
for (p=helpbuf; len; len--, v++) {
VariantInit (v);
v->vt = VT_UI1;
v->u.bVal = *p;
}
SafeArrayUnaccessData (array);
_gpgme_free (helpbuf);
/* pass the data to the caller */
VariantInit (retval);
retval->vt = (VT_ARRAY|VT_VARIANT);
retval->u.parray = array;
}
return 0;
}
static HRESULT WINAPI
m_IGpgme_SetPlaintext (IGpgme *iface, VARIANT val)
{
ICOM_THIS (IGpgmeImpl,iface);
return set_data_from_variant (&This->plaintext, val,
&This->plaintext_given_as_bstr);
}
static HRESULT WINAPI
m_IGpgme_GetPlaintext (IGpgme *iface, VARIANT *retval)
{
ICOM_THIS (IGpgmeImpl,iface);
/*fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p)\n", This );*/
return set_data_to_variant (This->plaintext, retval,
This->plaintext_given_as_bstr);
}
static HRESULT WINAPI
m_IGpgme_SetCiphertext (IGpgme *iface, VARIANT val)
{
ICOM_THIS (IGpgmeImpl,iface);
return set_data_from_variant (&This->ciphertext, val, NULL);
}
static HRESULT WINAPI
m_IGpgme_GetCiphertext (IGpgme *iface, VARIANT *retval)
{
ICOM_THIS (IGpgmeImpl,iface);
return set_data_to_variant (This->ciphertext, retval,
This->ciphertext_is_armored);
}
static HRESULT WINAPI
m_IGpgme_ClearRecipients (IGpgme *iface)
{
ICOM_THIS (IGpgmeImpl,iface);
gpgme_recipients_release (This->rset); This->rset = NULL;
return 0;
}
static HRESULT WINAPI
m_IGpgme_AddRecipient (IGpgme *iface, BSTR name, signed short int trust)
{
GpgmeError err;
int n;
char *p;
ICOM_THIS (IGpgmeImpl,iface);
/*fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p, %d)\n",
This, (int)trust);*/
if (!This->rset) {
err = gpgme_recipients_new (&This->rset);
if (err)
return map_gpgme_error (err);
}
n = bstrtoutf8 (name, NULL, 0);
p = HeapAlloc (GetProcessHeap(), 0, n );
if (!p) {
fprintf (stderr,"HeapAlloc failed: ec=%d\n", (int)GetLastError () );
return E_OUTOFMEMORY;
}
if (bstrtoutf8 (name, p, n) < 0) {
fprintf (stderr,"problem with bstrtoutf8\n");
HeapFree (GetProcessHeap(), 0, p);
return E_FAIL;
}
err = gpgme_recipients_add_name (This->rset, p);
HeapFree (GetProcessHeap(), 0, p);
return map_gpgme_error (err);
}
static HRESULT WINAPI
m_IGpgme_ResetSignKeys (IGpgme *iface)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_IGpgme_AddSignKey (IGpgme *iface, BSTR name)
{
return E_NOTIMPL;
}
static HRESULT WINAPI
m_IGpgme_Encrypt (IGpgme *iface)
{
GpgmeError err;
ICOM_THIS (IGpgmeImpl,iface);
gpgme_data_release (This->ciphertext);
err = gpgme_data_new (&This->ciphertext);
if (err)
return map_gpgme_error (err);
This->ciphertext_is_armored = gpgme_get_armor (This->mainctx);
err = gpgme_op_encrypt (This->mainctx, This->rset,
This->plaintext, This->ciphertext);
#if 0
if (!err ) {
char buf[100];
size_t nread;
err = gpgme_data_rewind ( This->ciphertext );
if (err )
fprintf (stderr, "*** gpgme_data_rewind failed: %d\n", err);
while ( !(err = gpgme_data_read ( This->ciphertext,
buf, 100, &nread )) ) {
fwrite ( buf, nread, 1, stderr );
}
if (err != GPGME_EOF)
fprintf (stderr, "*** gpgme_data_read failed: %d\n", err);
err = 0;
}
#endif
return map_gpgme_error (err);
}
static HRESULT WINAPI
m_IGpgme_Sign (IGpgme *iface, short int signmode)
{
ICOM_THIS (IGpgmeImpl,iface);
fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p)\n", This );
return E_NOTIMPL;
}
static HRESULT WINAPI
m_IGpgme_SignEncrypt (IGpgme *iface, short int signmode)
{
ICOM_THIS (IGpgmeImpl,iface);
fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p)\n", This );
return E_NOTIMPL;
}
#if 0
static HRESULT WINAPI
m_IGpgme_GetSigStatus(GpgmeCtx c, int idx,
GpgmeSigStat *r_stat, time_t *r_created );
{
return 0;
}
static HRESULT WINAPI
m_IGpgme_GetSigKey (GpgmeCtx c, int idx, GpgmeKey *r_key);
{
return 0;
}
static HRESULT WINAPI
m_IGpgme_GetNotation(IGpgme *c, BSTR *retval)
{
return 0;
}
#endif
static ICOM_VTABLE(IGpgme) igpgme_vtbl =
{
/* IUnknown methods */
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
m_IGpgme_QueryInterface,
m_IGpgme_AddRef,
m_IGpgme_Release,
/* IDispatch methods */
m_stub_IDispatch_GetTypeInfoCount,
m_stub_IDispatch_GetTypeInfo,
m_stub_IDispatch_GetIDsOfNames,
m_stub_IDispatch_Invoke,
/* Our methods */
m_IGpgme_GetVersion,
m_IGpgme_GetEngineInfo,
m_IGpgme_Cancel,
m_IGpgme_SetArmor,
m_IGpgme_GetArmor,
m_IGpgme_SetTextmode,
m_IGpgme_GetTextmode,
m_IGpgme_SetPlaintext,
m_IGpgme_GetPlaintext,
m_IGpgme_SetCiphertext,
m_IGpgme_GetCiphertext,
m_IGpgme_ClearRecipients,
m_IGpgme_AddRecipient,
m_IGpgme_ResetSignKeys,
m_IGpgme_AddSignKey,
m_IGpgme_Encrypt,
m_IGpgme_Sign,
m_IGpgme_SignEncrypt
};
/***************************************************************
****************** Gpgme Factory ****************************
***************************************************************/
static HRESULT WINAPI
m_GpgmeFactory_QueryInterface (IClassFactory *iface,
REFIID refiid, LPVOID *obj)
{
ICOM_THIS (IClassFactoryImpl,iface);
/*fprintf (stderr,"*** m_GpgmeFactory_QueryInterface(%p,%s)",
This, debugstr_guid(refiid));*/
if ( IsEqualGUID (&IID_IUnknown, refiid)
|| IsEqualGUID (&IID_IClassFactory, refiid) ) {
*obj = This;
/*fprintf (stderr," -> got %p\n", obj);*/
return 0;
}
*obj = NULL;
/*fprintf (stderr," -> none\n");*/
return E_NOINTERFACE;
}
static ULONG WINAPI
m_GpgmeFactory_AddRef (IClassFactory *iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
return ++(This->ref);
}
static ULONG WINAPI
m_GpgmeFactory_Release (IClassFactory *iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
return --(This->ref);
}
static HRESULT WINAPI
m_GpgmeFactory_CreateInstance (IClassFactory *iface, IUnknown *outer,
REFIID refiid, LPVOID *r_obj )
{
/*ICOM_THIS(IClassFactoryImpl,iface);*/
fprintf (stderr,"*** m_GpgmeFactory_CreateInstance(%s)",
debugstr_guid(refiid) );
if ( IsEqualGUID (&IID_IUnknown, refiid)
|| IsEqualGUID (&IID_IGpgme, refiid) ) {
IGpgmeImpl *obj;
GpgmeCtx ctx;
GpgmeError err;
err = gpgme_new (&ctx);
if (err) {
fprintf (stderr," -> gpgme_new failed: %s\n", gpgme_strerror (err));
return E_OUTOFMEMORY;
}
obj = HeapAlloc (GetProcessHeap(), 0, sizeof *obj );
if ( !obj) {
fprintf (stderr," -> out of core\n");
gpgme_release (ctx);
return E_OUTOFMEMORY;
}
memset (obj, 0, sizeof *obj);
ICOM_VTBL(obj) = &igpgme_vtbl;
obj->ref = 1;
obj->mainctx = ctx;
{ /* Fixme: need to release some stuff on error */
HRESULT hr;
ITypeLib *pTypeLib;
hr = LoadRegTypeLib (&TLBID_Gpgcom, 1, 0, LANG_NEUTRAL, &pTypeLib);
if (hr) {
fprintf (stderr," -> LoadRegTypeLib failed: %lx\n", hr);
return hr;
}
hr = ITypeLib_GetTypeInfoOfGuid (pTypeLib, &IID_IGpgme,
&obj->std_disp.tinfo);
ITypeLib_Release (pTypeLib);
if (hr) {
fprintf (stderr," -> GetTypeInfoOfGuid failed: %lx\n", hr);
return hr;
}
hr = CreateStdDispatch ((IUnknown*)obj, obj, obj->std_disp.tinfo,
&obj->std_disp.disp);
if (hr) {
fprintf (stderr," -> CreateStdDispatch failed: %lx\n", hr);
return hr;
}
}
CoAddRefServerProcess ();
*r_obj = obj;
fprintf (stderr," -> created %p\n", obj );
return 0;
}
fprintf (stderr," -> no interface\n" );
*r_obj = NULL;
return E_NOINTERFACE;
}
static HRESULT WINAPI
m_GpgmeFactory_LockServer (IClassFactory *iface, BOOL dolock )
{
if (dolock) {
CoAddRefServerProcess ();
}
else {
ULONG count = CoReleaseServerProcess ();
if (!count && my_exit_event)
SetEvent (my_exit_event);
}
return 0;
}
static ICOM_VTABLE(IClassFactory) igpgme_factory_vtbl = {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
m_GpgmeFactory_QueryInterface,
m_GpgmeFactory_AddRef,
m_GpgmeFactory_Release,
m_GpgmeFactory_CreateInstance,
m_GpgmeFactory_LockServer
};
static IClassFactoryImpl igpgme_CF = {&igpgme_factory_vtbl, 1 };
void
igpgme_register_exit_event (HANDLE ev)
{
my_exit_event = ev;
}
IClassFactory *
igpgme_factory_new ( CLSID *r_clsid )
{
*r_clsid = CLSID_Gpgme;
IClassFactory_AddRef((IClassFactory*)&igpgme_CF);
return (IClassFactory*)&igpgme_CF;
}
void
igpgme_factory_release ( IClassFactory *factory )
{
/* it's static - nothing to do */
}

View File

@ -0,0 +1,163 @@
/* igpgme.h - COM+ class IGpgme
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef IGPGME_H
#define IGPGME_H 1
#include <ole2.h>
DEFINE_GUID(CLSID_Gpgme, 0x3811fd40, 0x7f72, 0x11d5,
0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5);
#if 0
DEFINE_GUID(CLSID_GpgmeData, 0x3811fd41, 0x7f72, 0x11d5,
0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5);
DEFINE_GUID(CLSID_GpgmeKey, 0x3811fd42, 0x7f72, 0x11d5,
0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5);
DEFINE_GUID(CLSID_GpgmeRSet, 0x3811fd43, 0x7f72, 0x11d5,
0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5);
#endif
DEFINE_GUID(TLBID_Gpgcom, 0x3811fd48, 0x7f72, 0x11d5,
0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5);
DEFINE_GUID(APPID_Gpgcom, 0x3811fd4f, 0x7f72, 0x11d5,
0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5);
DEFINE_GUID(IID_IGpgme, 0x3811fd50, 0x7f72, 0x11d5,
0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5);
typedef struct IGpgme IGpgme;
void igpgme_register_exit_event (HANDLE ev);
IClassFactory *igpgme_factory_new( CLSID *r_clsid );
void igpgme_factory_release ( IClassFactory *factory );
/********************************************
***** The IGpgme interface *****************
********************************************/
#define ICOM_INTERFACE IGpgme
#define IGpgme_METHODS \
ICOM_METHOD1(HRESULT,GetVersion, BSTR*,) \
ICOM_METHOD1(HRESULT,GetEngineInfo, BSTR*,) \
ICOM_METHOD(HRESULT,Cancel) \
ICOM_METHOD1(HRESULT,SetArmor,BOOL,) \
ICOM_METHOD1(HRESULT,GetArmor,BOOL*,) \
ICOM_METHOD1(HRESULT,SetTextmode,BOOL,) \
ICOM_METHOD1(HRESULT,GetTextmode,BOOL*,) \
ICOM_METHOD1(HRESULT,SetPlaintext,VARIANT,) \
ICOM_METHOD1(HRESULT,GetPlaintext,VARIANT*,) \
ICOM_METHOD1(HRESULT,SetCiphertext,VARIANT,) \
ICOM_METHOD1(HRESULT,GetCiphertext,VARIANT*,) \
ICOM_METHOD(HRESULT,ClearRecipients) \
ICOM_METHOD2(HRESULT,AddRecipient,BSTR,,signed short int,) \
ICOM_METHOD(HRESULT,ResetSignKeys) \
ICOM_METHOD1(HRESULT,AddSignKey,BSTR,) \
ICOM_METHOD(HRESULT,Encrypt) \
ICOM_METHOD1(HRESULT,Sign,signed short int,) \
ICOM_METHOD1(HRESULT,SignEncrypt,signed short int,)
#if 0
ICOM_METHOD1(HRESULT,SetKeylistMode,)
ICOM_METHOD1(HRESULT,SetPassphraseCB,)
ICOM_METHOD1(HRESULT,SetProgressCB,)
ICOM_METHOD1(HRESULT,SignersClear,)
ICOM_METHOD1(HRESULT,SignersAdd,)
ICOM_METHOD1(HRESULT,SignersEnum,)
ICOM_METHOD1(HRESULT,GetSigStatus,)
ICOM_METHOD1(HRESULT,GetNotation,)
#endif
#define IGpgme_IMETHODS \
IDispatch_IMETHODS \
IGpgme_METHODS
ICOM_DEFINE(IGpgme,IDispatch)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IGpgme_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IGpgme_AddRef(p) ICOM_CALL (AddRef,p)
#define IGpgme_Release(p) ICOM_CALL (Release,p)
/*** IGpgme methods ***/
#define IGpgme_GetVersion(p,r) ICOM_CALL1(GetVersion,p,r)
#define IGpgme_GetEngineInfo(p,r) ICOM_CALL1(GetEngineInfo,p,r)
#define IGpgme_Cancel(p,a) ICOM_CALL1(Cancel,p,a)
#define IGpgme_SetArmor(p,a) ICOM_CALL1(SetArmor,p,a)
#define IGpgme_GetArmor(p,a) ICOM_CALL1(GetArmor,p,a)
#define IGpgme_SetTextmode(p,a) ICOM_CALL1(SetTextmode,p,a)
#define IGpgme_GetTextmode(p,a) ICOM_CALL1(GetTextmode,p,a)
#define IGpgme_SetPlaintext(p,a) ICOM_CALL1(SetPlaintext,p,a)
#define IGpgme_GetPlaintext(p,a) ICOM_CALL1(GetPlaintext,p,a)
#define IGpgme_SetCiphertext(p,a) ICOM_CALL1(SetCiphertext,p,a)
#define IGpgme_GetCiphertext(p,a) ICOM_CALL1(GetCiphertext,p,a)
#define IGpgme_ClearRecipients(p) ICOM_CALL (ClearRecipients,p)
#define IGpgme_AddRecipient(p,a,b) ICOM_CALL2(AddRecipient,p,a,b)
#define IGpgme_ResetSignKeys(p) ICOM_CALL (ResetSignKeys,p)
#define IGpgme_AddSignKey(p,a) ICOM_CALL (AddSignKey,p,a)
#define IGpgme_Encrypt(p) ICOM_CALL (Encrypt,p)
#define IGpgme_Sign(p,a) ICOM_CALL (Sign,p,a)
#define IGpgme_SignEncrypt(p,a) ICOM_CALL (SignEncrypt,p,a)
#if 0
#define IGpgme_SetKeylistMode(p,a) ICOM_CALL1(SetKeylistMode,p,a)
#define IGpgme_SetPassphraseCB(p,a) ICOM_CALL1(SetPassphraseCB,p,a)
#define IGpgme_SetProgressCB(p,a) ICOM_CALL1(SetProgressCB,p,a)
#define IGpgme_SignersClear(p,a) ICOM_CALL1(SignersClear,p,a)
#define IGpgme_SignersAdd(p,a) ICOM_CALL1(SignersAdd,p,a)
#define IGpgme_SignersEnum(p,a) ICOM_CALL1(SignersEnum,p,a)
#define IGpgme_GetSigStatus(p,a) ICOM_CALL1(GetSigStatus,p,a)
#define IGpgme_GetSigKey(p,a) ICOM_CALL1(GetSigKey,p,a)
#define IGpgme_GetNotation(p,a) ICOM_CALL1(GetNotation,p,a)
#endif
#if 0
/********************************************
***** The IGpgmeKey interface **************
********************************************/
#define ICOM_INTERFACE IGpgmeKey
#define IGpgmeKey_METHODS \
ICOM_METHOD1(HRESULT,GetVersion, BSTR,) \
ICOM_METHOD1(HRESULT,GetEngineInfo, BSTR,)
#define IGpgmeKey_IMETHODS \
IUnknown_IMETHODS \
IGpgmeKey_METHODS
ICOM_DEFINE(IGpgmeKey,IUnknown)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IGpgmeKey_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IGpgmeKey_AddRef(p) ICOM_CALL (AddRef,p)
#define IGpgmeKey_Release(p) ICOM_CALL (Release,p)
/*** IGpgmeKey methods ***/
#define IGpgmeKey_GetVersion(p,r) ICOM_CALL1(GetVersion,p,r)
#define IGpgmeKey_GetEngineInfo(p,r) ICOM_CALL1(GetEngineInfo,p,r)
#endif
#endif /*IGPGME_H*/

View File

@ -0,0 +1,49 @@
/* main.h - GPGME COM+ component
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef COMPLUS_MAIN_H
#define COMPLUS_MAIN_H
#include "xmalloc.h"
#include "stringhelp.h"
#include "logging.h"
#define _(a) (a)
#define N_(a) (a)
struct {
int verbose;
int quiet;
unsigned int debug;
char *homedir;
} opt;
#endif /* COMPLUS_MAIN_H */

View File

@ -0,0 +1,70 @@
/* regtlb.c - Register a type library
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#include <windows.h>
#include "xmalloc.h"
#include "oleauto.h"
int
main (int argc, char **argv)
{
ITypeLib *pTypeLib;
wchar_t *fname;
HRESULT hr;
size_t n;
if ( argc != 2 ) {
fprintf (stderr,"usage: regtlb foo.tlb\n");
return 1;
}
n = mbstowcs (NULL, argv[1], strlen(argv[1])+1);
fprintf (stderr, "need %d bytes\n", (int)n);
fname = xmalloc ((n+1)*sizeof *fname);
mbstowcs (fname, argv[1], strlen (argv[1])+1);
hr = CoInitializeEx (NULL, COINIT_MULTITHREADED);
if (hr)
fprintf (stderr, "CoInitializeEx() failed: hr=%lu\n", hr);
hr = LoadTypeLibEx (fname, REGKIND_REGISTER, &pTypeLib);
if (hr)
fprintf (stderr, "LoadTypeLibEx() failed: hr=%lx\n", hr);
ITypeLib_Release (pTypeLib);
CoUninitialize ();
return 0;
}

View File

@ -0,0 +1,157 @@
/* tgpgcom.c - Test the IGpgme classes
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#include <windows.h>
#define INITGUID
#include "igpgme.h"
int
main (int argc, char **argv)
{
IUnknown *pUnknown = NULL;
IGpgme *pGpgme;
HRESULT hr;
BSTR bs;
hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
if (hr)
fprintf (stderr, "CoInitializeEx() failed: hr=%lu\n", hr);
fprintf (stderr, "system initialized\n");
hr = CoCreateInstance (&CLSID_Gpgme, NULL, CLSCTX_LOCAL_SERVER,
&IID_IUnknown, (void**)&pUnknown );
if (hr)
fprintf (stderr, "CoCreateInstance() failed: hr=%lx\n", hr);
if (!pUnknown)
exit (1);
fprintf (stderr,"got object %p - querying %s\n",
pUnknown, debugstr_guid(&IID_IGpgme));
hr = IGpgme_QueryInterface (pUnknown, &IID_IGpgme, (void**)&pGpgme);
if (hr) {
fprintf (stderr, "QueryInterface() failed: hr=%lx\n", hr);
goto leave;
}
fprintf (stderr, "got interface %p\n", pGpgme);
hr = IGpgme_SetArmor (pGpgme, 1);
fprintf (stderr, "SetArmor returned %lx\n", hr);
hr = IGpgme_SetTextmode (pGpgme, 0);
fprintf (stderr, "SetTextmode returned %lx\n", hr);
hr = IGpgme_ClearRecipients (pGpgme);
fprintf (stderr, "ClearRecipients returned %lx\n", hr);
bs = SysAllocString (L"alice");
if (!bs)
fprintf (stderr, "SysAllocString failed: ec=%d\n", (int)GetLastError());
else {
int i;
for (i=-4; i < 12; i++ )
fprintf (stderr," %02X", ((unsigned char*)bs)[i] );
putc ('\n', stderr);
}
hr = IGpgme_AddRecipient (pGpgme, bs, -1);
fprintf (stderr, "AddRecipients returned %lx\n", hr);
{
SAFEARRAY *sa;
VARIANT v;
char *p;
sa = SafeArrayCreateVector (VT_UI1, 0, 20);
if (!sa) {
fprintf (stderr, "SafeArrayCreateVector failed\n");
goto leave;
}
hr = SafeArrayAccessData (sa, (void**)&p);
if (hr) {
fprintf (stderr,"SafeArrayAccessData failed: hr=%lx\n", hr);
goto leave;
}
memcpy (p, "=> Omnis enim res <=", 20 );
SafeArrayUnaccessData (sa);
VariantInit (&v);
v.vt = (VT_ARRAY|VT_UI1);
v.u.parray = sa;
hr = IGpgme_SetPlaintext (pGpgme, v );
fprintf (stderr, "SetPlaintext returned %lx\n", hr);
SafeArrayDestroyData (sa);
SafeArrayDestroy (sa);
VariantClear (&v);
}
hr = IGpgme_Encrypt (pGpgme);
fprintf (stderr, "Encrypt returned %lx\n", hr);
{
VARIANT v;
hr = IGpgme_GetCiphertext (pGpgme, &v);
fprintf (stderr, "GetCiphertext returned %lx\n", hr);
if (!hr) {
if (v.vt != (VT_ARRAY|VT_UI1))
fprintf (stderr, "Invalid array typed returned\n");
else {
unsigned char *p;
hr = SafeArrayAccessData (v.u.parray, (void**)&p);
if (hr)
fprintf (stderr,"*** SafeArrayAccessData failed: %lx\n", hr);
else {
size_t arraysize = v.u.parray->rgsabound[0].cElements;
fprintf (stderr,"*** got %d bytes\n", (int)arraysize);
for (;arraysize; arraysize--, p++ )
putc (*p, stderr);
SafeArrayUnaccessData (v.u.parray);
}
}
}
}
IGpgme_Release (pGpgme);
leave:
CoUninitialize ();
fprintf (stderr, "system uninitialized\n");
return 0;
}

View File

@ -0,0 +1,236 @@
/*
* UTF-8 support routines
*
* Copyright 2000 Alexandre Julliard
*
* Taken from WINE, so the usual WINE copyright applies:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <ole2.h>
/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
static const char utf8_length[128] =
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80-0x8f */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90-0x9f */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0-0xaf */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb0-0xbf */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xc0-0xcf */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xd0-0xdf */
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 0xe0-0xef */
3,3,3,3,3,3,3,3,4,4,4,4,5,5,0,0 /* 0xf0-0xff */
};
/* first byte mask depending on UTF-8 sequence length */
static const unsigned char utf8_mask[6] = { 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
/* minimum Unicode value depending on UTF-8 sequence length */
static const unsigned int utf8_minval[6] = { 0x0, 0x80, 0x800, 0x10000, 0x200000, 0x4000000 };
/* query necessary dst length for src string */
inline static int get_length_wcs_utf8( const WCHAR *src, unsigned int srclen )
{
int len;
for (len = 0; srclen; srclen--, src++, len++)
{
if (*src >= 0x80)
{
len++;
if (*src >= 0x800) len++;
}
}
return len;
}
/* wide char to UTF-8 string conversion */
/* return -1 on dst buffer overflow */
int utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen )
{
char *orig_dst = dst;
if (!dstlen) return get_length_wcs_utf8( src, srclen );
for (; srclen; srclen--, src++)
{
WCHAR ch = *src;
if (ch < 0x80) /* 0x00-0x7f: 1 byte */
{
if (!dstlen--) return -1; /* overflow */
*dst++ = ch;
continue;
}
if (ch < 0x800) /* 0x80-0x7ff: 2 bytes */
{
if ((dstlen -= 2) < 0) return -1; /* overflow */
dst[1] = 0x80 | (ch & 0x3f);
ch >>= 6;
dst[0] = 0xc0 | ch;
dst += 2;
continue;
}
/* 0x800-0xffff: 3 bytes */
if ((dstlen -= 3) < 0) return -1; /* overflow */
dst[2] = 0x80 | (ch & 0x3f);
ch >>= 6;
dst[1] = 0x80 | (ch & 0x3f);
ch >>= 6;
dst[0] = 0xe0 | ch;
dst += 3;
}
return dst - orig_dst;
}
/* query necessary dst length for src string */
inline static int get_length_mbs_utf8( const unsigned char *src, int srclen )
{
int ret;
const unsigned char *srcend = src + srclen;
for (ret = 0; src < srcend; ret++)
{
unsigned char ch = *src++;
if (ch < 0xc0) continue;
switch(utf8_length[ch-0x80])
{
case 5:
if (src >= srcend) return ret; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) continue;
src++;
case 4:
if (src >= srcend) return ret; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) continue;
src++;
case 3:
if (src >= srcend) return ret; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) continue;
src++;
case 2:
if (src >= srcend) return ret; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) continue;
src++;
case 1:
if (src >= srcend) return ret; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) continue;
src++;
}
}
return ret;
}
/* UTF-8 to wide char string conversion */
/* return -1 on dst buffer overflow, -2 on invalid input char */
int utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen )
{
int len, count;
unsigned int res;
const char *srcend = src + srclen;
if (!dstlen) return get_length_mbs_utf8( src, srclen );
for (count = dstlen; count && (src < srcend); count--, dst++)
{
unsigned char ch = *src++;
if (ch < 0x80) /* special fast case for 7-bit ASCII */
{
*dst = ch;
continue;
}
len = utf8_length[ch-0x80];
res = ch & utf8_mask[len];
switch(len)
{
case 5:
if (src >= srcend) goto done; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) goto bad;
res = (res << 6) | ch;
src++;
case 4:
if (src >= srcend) goto done; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) goto bad;
res = (res << 6) | ch;
src++;
case 3:
if (src >= srcend) goto done; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) goto bad;
res = (res << 6) | ch;
src++;
case 2:
if (src >= srcend) goto done; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) goto bad;
res = (res << 6) | ch;
src++;
case 1:
if (src >= srcend) goto done; /* ignore partial char */
if ((ch = *src ^ 0x80) >= 0x40) goto bad;
res = (res << 6) | ch;
src++;
if (res < utf8_minval[len]) goto bad;
if (res >= 0x10000) goto bad; /* FIXME: maybe we should do surrogates here */
*dst = res;
continue;
}
bad:
if (flags & MB_ERR_INVALID_CHARS) return -2; /* bad char */
*dst = (WCHAR)'?';
}
if (src < srcend) return -1; /* overflow */
done:
return dstlen - count;
}
int
bstrtoutf8 ( BSTR src, char *dst, size_t dstlen )
{
size_t srclen, needed;
int n;
srclen = src? SysStringLen (src): 0;
needed = srclen? (utf8_wcstombs (src, srclen, NULL, 0) + 1) : 1;
if (!dst || !dstlen)
return needed;
if (dstlen < needed)
return -1;
if (srclen) {
n = utf8_wcstombs (src, srclen, dst, dstlen);
if (n < 0)
return -1;
}
else
n = 0;
dst[n] = 0;
return n;
}

View File

@ -0,0 +1,47 @@
<html>
<head><title>g10 code - GPGCOM test</title>
<object id="gpg"
classid="CLSID:3811fd40-7f72-11d5-8c9e-0080ad190cd5">
</object>
<script language="VBScript">
Sub encrypt_text
On error resume next
Dim TheForm, plain
set TheForm = Document.forms ("MyForm")
gpg.armor = True
gpg.plaintext = TheForm.clear.value
gpg.ClearRecipients
gpg.AddRecipient TheForm.recp.value
Err.Clear
gpg.Encrypt
if Err <> 0 then
TheForm.encoded.value = "Error: " & CStr(Err.Number)
else
TheForm.encoded.value = gpg.ciphertext
end if
end sub
</script>
</head>
<body>
<h1>Silly Gpgcom test page</h1>
<form id="MyForm">
<textarea name="clear" rows = 3 cols=40>Please enter the text here</textarea>
<p>
Encrypt for <input name="recp" value="alice">
<input type="button" name="MyAction" value="Encrypt"
language="VBScript" onclick="encrypt_text()">
<p>
<textarea name="encoded" rows=10 cols=75></textarea>
</form>
<p>
</body>
</html>

View File

@ -0,0 +1,39 @@
' Demo script to generate a RFC2015 compliant message using Gpgcom
Dim gpg, body, crlf
crlf = chr(10) & chr(13)
' Create out Gpgcom object
set gpg = CreateObject("Gpgcom.Gpgme")
' We must use the ASCII armor and switch to textmode
gpg.armor = true
gpg.textmode = true
' Set the secret message
gpg.plaintext = "This is the secret message." 'or: InputBox('Enter message:")
' Set the Recipient. You may also use a keyID or an fingerprint
gpg.AddRecipient "alice"
' And encrypt the stuff
gpg.encrypt
' Build the MIME message
body = "Content-Type: multipart/encrypted; boundary="
body = body & Chr(34) & "=-=-=-=" & Chr(34) & crlf & " protocol=" & Chr(34)
body = body & "application/pgp-encrypted" & Chr(34) & crlf & crlf
body = body & "--=-=-=-=" & crlf
body = body & "Content-Type: application/pgp-encrypted" & crlf & crlf
body = body & "Version: 1" & crlf & crlf
body = body & "--=-=-=-=" & crlf
body = body & "Content-Type: application/octet-stream" & crlf & crlf
body = body & gpg.ciphertext
body = body & "--=-=-=-=--" & crlf
' And display it
Print body
' output function for the windows scripting host
sub Print(x)
WScript.Echo x
end sub

View File

@ -0,0 +1,277 @@
# configure.in for GPGME
# Copyright (C) 2000 Werner Koch (dd9jn)
# Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
# (Process this file with autoconf to produce a configure script.)
# 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)
#
AC_INIT(gpgme, 0.3.7, [gnupg-devel@gnupg.org])
LIBGPGME_LT_CURRENT=8
LIBGPGME_LT_AGE=2
LIBGPGME_LT_REVISION=1
NEED_GPG_VERSION=1.0.7
NEED_GPGSM_VERSION=0.3.7
##############################################
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
AH_VERBATIM([_GNU_SOURCE],
[/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif])
AH_VERBATIM([_REENTRANT],
[/* To allow the use of GPGME in multithreaded programs we have to use
special features from the library.
IMPORTANT: gpgme is not yet fully reentrant and you should use it
only from one thread. */
#ifndef _REENTRANT
# define _REENTRANT 1
#endif])
AC_PROG_CC
AC_SUBST(LIBGPGME_LT_CURRENT)
AC_SUBST(LIBGPGME_LT_AGE)
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.])
AC_SUBST(PACKAGE)
AC_SUBST(VERSION)
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
dnl Don't default to build static libs.
dnl AC_DISABLE_STATIC
AC_PROG_LIBTOOL
GPG_DEFAULT=no
GPGSM_DEFAULT=no
component_system=None
case "${target}" 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'
GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe'
#component_system='COM+'
;;
*)
AC_CHECK_PTH(1.2.0,,,no,have_pth=yes)
if test "$have_pth" = yes; then
AC_DEFINE(HAVE_PTH, ,[Define if we have Pth.])
CFLAGS="$CFLAGS $PTH_CFLAGS"
fi
AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes)
if test "$have_pthread" = yes; then
AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.])
fi
dnl # XXX: Probably use exec-prefix here?
dnl GPG_DEFAULT='/usr/bin/gpg'
dnl GPGSM_DEFAULT='/usr/bin/gpgsm'
;;
esac
AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = "yes")
AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes")
AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes")
dnl
dnl Checks for libraries.
dnl
dnl FIXME: check whether Bonobo is installed
dnl
dnl Checks for header files.
dnl
dnl
dnl Checks for typedefs and structures.
dnl
GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF)
GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF)
GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF)
GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF)
GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF)
dnl We should not use them in this software;
dnl However jnlib/types.h needs them - so we take the easy way.
AC_CHECK_SIZEOF(unsigned short)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
dnl
dnl Checks for compiler features.
dnl
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
fi
dnl
dnl Checks for library functions.
dnl
dnl These are needed by libjnlib
AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp)
# asprintf() is at least used in assuan
AC_REPLACE_FUNCS(vasprintf)
# Note: fopencokie is only a dummy stub and not used.
# However some code in assuan/ links against it.
AC_REPLACE_FUNCS(fopencookie)
dnl We use jnlib, so tell other modules about it
AC_DEFINE(HAVE_JNLIB_LOGGING, 1,
[Defined if jnlib style logging fucntions are available.])
dnl
dnl Checks for system services
dnl
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(RUN_GPGSM_TESTS,
[test "$cross_compiling" != "yes" && test -n "$GPGSM" && test -r "$GPGSM"])
dnl FIXME: Only build if supported.
AM_CONDITIONAL(BUILD_ASSUAN, test "$GPGSM" != "no")
AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
AM_CONDITIONAL(BUILD_BONOBO, test "$component_system" = "Bonobo")
GPGMEPLUG=no
AC_ARG_ENABLE(gpgmeplug,
AC_HELP_STRING([--enable-gpgmeplug], [build GPGME Crypt Plug-In]),
GPGMEPLUG=$enableval)
AM_CONDITIONAL(BUILD_GPGMEPLUG, test "$GPGMEPLUG" = "yes")
dnl Make the version number in gpgme/gpgme.h the same as the one here.
dnl (this is easier than to have a *.in file just for one substitution)
GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION)
dnl Substitution used for gpgme-config
GPGME_LIBS="-L${libdir} -lgpgme"
GPGME_CFLAGS=""
AC_SUBST(GPGME_LIBS)
AC_SUBST(GPGME_CFLAGS)
dnl
dnl Create config files
dnl
AC_CONFIG_FILES(Makefile assuan/Makefile jnlib/Makefile gpgme/Makefile
tests/Makefile tests/gpg/Makefile tests/gpgsm/Makefile
doc/Makefile
bonobo/Makefile complus/Makefile gpgmeplug/Makefile)
AC_CONFIG_FILES(gpgme/gpgme-config, chmod +x gpgme/gpgme-config)
AC_OUTPUT
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
GPGME CryptPlug: $GPGMEPLUG
"

View File

@ -0,0 +1,185 @@
2002-06-04 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Document new autodetection.
2002-06-04 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (DISTCLEANFILES): New variable.
2002-05-26 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi: Some typographical correctons throughout.
2002-05-09 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Using Automake): New section.
2002-05-09 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Escape { and }.
2002-05-09 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Overview): Replace note about thread-safeness.
(Multi Threading): New section.
2002-05-03 Werner Koch <wk@gnupg.org>
* gpgme.texi (Manipulating Data Buffers): Changed some data types
to void*.
(Protocol Selection): Added gpgme_get_protocol.
(Verify): Updated to include the new attribute fucntions and
status codes.
2002-04-27 Werner Koch <wk@gnupg.org>
* gpgme.texi (Manipulating Data Buffers): New type GpgmeDataEncoding.
2002-04-23 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Passphrase Callback): Document that either return
argument can be NULL.
(Progress Meter Callback): Likewise.
2002-04-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Passphrase Callback): Fix small typo. Document the
new function gpgme_get_passphrase_cb.
(Progress Meter Callback): Document the new function
gpgme_get_progress_cb.
2002-04-16 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Creating a Signature): Fix function name. Reported
by Wichert Ackerman <wichert@debian.org>.
2002-03-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (direntry): End index entry with a full stop.
Patch submitted by Jose Carlos Garcia Sogo <jsogo@debian.org>.
2002-03-17 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Detailed Results): Fix syntax error in last change.
2002-03-08 Werner Koch <wk@gnupg.org>
* gpgme.texi (Detailed Results): Import does also return info.
2002-03-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Document symmetric
encryption.
2002-03-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Error Strings): Add example.
* gpgme.texi (Listing Keys): Likewise.
2002-03-03 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Information About Keys): Document GPGME_ATTR_EXPIRE.
2002-03-03 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Verify): Document verification of normal and
cleartext signatures.
2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start.
2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Document
GPGME_Invalid_Recipients.
(Error Values): Likewise.
2002-02-26 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Document
gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start.
2002-02-25 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Creating a Signature): Add a note about
certificates to include.
(Included Certificates): New section.
2002-02-09 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Detailed Results): Remove literal tags.
(Generating Keys): Update documentation.
* gpgme.texi (Generating Keys): Fix syntax error.
2002-02-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Waiting For Completion): Adjust doc to changes in
the code.
2002-02-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Listing Mode): Update documentation.
2002-01-31 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Generating Keys): Document error at creation
failure.
2002-01-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Deleting Keys): Document new error values.
2002-01-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Importing Keys): Add reference to gpgme_get_op_info.
2002-01-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi: Some spell checking.
2002-01-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi: Add all the gpgme_op_*_start functions.
Fill the concept index with many, many entries.
2002-01-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Run Control): New section.
(Verify): Docuent gpgme_get_notation.
(More Information): New section describing gpgme_get_op_info.
2002-01-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Passphrase callback): Change GpgmePassphraseCb's
R_HD type from void* to void**.
2002-01-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Creating data buffers): Change
gpgme_data_new_from_filepart's LENGTH type from off_t to size_t.
2002-01-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Generating keys): New subsection.
(Exporting keys): Likewise.
(Importing keys): Likewise.
(Deleting keys): Likewise.
2002-01-16 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi: g10Code -> g10 Code
* gpgme.texi (Top): Complete detailmenu.
* gpgme.texi: Convert embarassing cruft to the real thing.
2002-01-16 Marcus Brinkmann <marcus@g10code.de>
* ChangeLog: New file.
* gpgme.texi: Likewise.
* gpl.texi: Likewise.
* fdl.texi: Likewise.
* Makefile.am (info_TEXINFOS): New variable.
(gpgme_TEXINFOS): Likewise.

View File

@ -0,0 +1,27 @@
# doc - Automake template
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
## Process this file with automake to produce Makefile.in
EXTRA_DIST = gdoc
DISTCLEANFILES = gpgme.tmp
info_TEXINFOS = gpgme.texi
gpgme_TEXINFOS = gpl.texi fdl.texi

View File

@ -0,0 +1,402 @@
@node Free Documentation License
@appendix GNU Free Documentation License
@cindex FDL, GNU Free Documentation License
@center Version 1.1, March 2000
@display
Copyright @copyright{} 2000 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display
@enumerate 0
@item
PREAMBLE
The purpose of this License is to make a manual, textbook, or other
written document @dfn{free} in the sense of freedom: to assure everyone
the effective freedom to copy and redistribute it, with or without
modifying it, either commercially or noncommercially. Secondarily,
this License preserves for the author and publisher a way to get
credit for their work, while not being considered responsible for
modifications made by others.
This License is a kind of ``copyleft'', which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does. But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book. We recommend this License
principally for works whose purpose is instruction or reference.
@item
APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work that contains a
notice placed by the copyright holder saying it can be distributed
under the terms of this License. The ``Document'', below, refers to any
such manual or work. Any member of the public is a licensee, and is
addressed as ``you''.
A ``Modified Version'' of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A ``Secondary Section'' is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject. (For example, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
mathematics.) The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
The ``Invariant Sections'' are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License.
The ``Cover Texts'' are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License.
A ``Transparent'' copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, whose contents can be viewed and edited directly and
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters. A copy made in an otherwise Transparent file
format whose markup has been designed to thwart or discourage
subsequent modification by readers is not Transparent. A copy that is
not ``Transparent'' is called ``Opaque''.
Examples of suitable formats for Transparent copies include plain
@sc{ascii} without markup, Texinfo input format, La@TeX{} input format,
@acronym{SGML} or @acronym{XML} using a publicly available
@acronym{DTD}, and standard-conforming simple @acronym{HTML} designed
for human modification. Opaque formats include PostScript,
@acronym{PDF}, proprietary formats that can be read and edited only by
proprietary word processors, @acronym{SGML} or @acronym{XML} for which
the @acronym{DTD} and/or processing tools are not generally available,
and the machine-generated @acronym{HTML} produced by some word
processors for output purposes only.
The ``Title Page'' means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
formats which do not have any title page as such, ``Title Page'' means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.
@item
VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License. You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute. However, you may accept
compensation in exchange for copies. If you distribute a large enough
number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and
you may publicly display copies.
@item
COPYING IN QUANTITY
If you publish printed copies of the Document numbering more than 100,
and the Document's license notice requires Cover Texts, you must enclose
the copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
you as the publisher of these copies. The front cover must present
the full title with all words of the title equally prominent and
visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.
If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a publicly-accessible computer-network location containing a complete
Transparent copy of the Document, free of added material, which the
general network-using public has access to download anonymously at no
charge using public-standard network protocols. If you use the latter
option, you must take reasonably prudent steps, when you begin
distribution of Opaque copies in quantity, to ensure that this
Transparent copy will remain thus accessible at the stated location
until at least one year after the last time you distribute an Opaque
copy (directly or through your agents or retailers) of that edition to
the public.
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give
them a chance to provide you with an updated version of the Document.
@item
MODIFICATIONS
You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it. In addition, you must do these things in the Modified Version:
@enumerate A
@item
Use in the Title Page (and on the covers, if any) a title distinct
from that of the Document, and from those of previous versions
(which should, if there were any, be listed in the History section
of the Document). You may use the same title as a previous version
if the original publisher of that version gives permission.
@item
List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has less than five).
@item
State on the Title page the name of the publisher of the
Modified Version, as the publisher.
@item
Preserve all the copyright notices of the Document.
@item
Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
@item
Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
@item
Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
@item
Include an unaltered copy of this License.
@item
Preserve the section entitled ``History'', and its title, and add to
it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section entitled ``History'' in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
@item
Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
it was based on. These may be placed in the ``History'' section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
@item
In any section entitled ``Acknowledgments'' or ``Dedications'',
preserve the section's title, and preserve in the section all the
substance and tone of each of the contributor acknowledgments
and/or dedications given therein.
@item
Preserve all the Invariant Sections of the Document,
unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
@item
Delete any section entitled ``Endorsements''. Such a section
may not be included in the Modified Version.
@item
Do not retitle any existing section as ``Endorsements''
or to conflict in title with any Invariant Section.
@end enumerate
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.
You may add a section entitled ``Endorsements'', provided it contains
nothing but endorsements of your Modified Version by various
parties---for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version. Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.
@item
COMBINING DOCUMENTS
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections entitled ``History''
in the various original documents, forming one section entitled
``History''; likewise combine any sections entitled ``Acknowledgments'',
and any sections entitled ``Dedications''. You must delete all sections
entitled ``Endorsements.''
@item
COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this
License in the various documents with a single copy that is included in
the collection, provided that you follow the rules of this License for
verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute
it individually under this License, provided you insert a copy of this
License into the extracted document, and follow this License in all
other respects regarding verbatim copying of that document.
@item
AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, does not as a whole count as a Modified Version
of the Document, provided no compilation copyright is claimed for the
compilation. Such a compilation is called an ``aggregate'', and this
License does not apply to the other self-contained works thus compiled
with the Document, on account of their being thus compiled, if they
are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one quarter
of the entire aggregate, the Document's Cover Texts may be placed on
covers that surround only the Document within the aggregate.
Otherwise they must appear on covers around the whole aggregate.
@item
TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License provided that you also include the
original English version of this License. In case of a disagreement
between the translation and the original English version of this
License, the original English version will prevail.
@item
TERMINATION
You may not copy, modify, sublicense, or distribute the Document except
as expressly provided for under this License. Any other attempt to
copy, modify, sublicense or distribute the Document is void, and will
automatically terminate your rights under this License. However,
parties who have received copies, or rights, from you under this
License will not have their licenses terminated so long as such
parties remain in full compliance.
@item
FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions
of the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
@uref{http://www.gnu.org/copyleft/}.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License ``or any later version'' applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation.
@end enumerate
@page
@appendixsubsec ADDENDUM: How to use this License for your documents
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and
license notices just after the title page:
@smallexample
@group
Copyright (C) @var{year} @var{your name}.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with the Invariant Sections being @var{list their titles}, with the
Front-Cover Texts being @var{list}, and with the Back-Cover Texts being @var{list}.
A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
@end group
@end smallexample
If you have no Invariant Sections, write ``with no Invariant Sections''
instead of saying which ones are invariant. If you have no
Front-Cover Texts, write ``no Front-Cover Texts'' instead of
``Front-Cover Texts being @var{list}''; likewise for Back-Cover Texts.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License,
to permit their use in free software.
@c Local Variables:
@c ispell-local-pdict: "ispell-dict"
@c End:

681
tags/gpgme-0-3-7/doc/gdoc Executable file
View File

@ -0,0 +1,681 @@
#!/usr/bin/perl
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
## hacked to allow -tex option --nmav ##
## ##
## This software falls under the GNU Public License. Please read ##
## the COPYING file for more information ##
#
# This will read a 'c' file and scan for embedded comments in the
# style of gnome comments (+minor extensions - see below).
#
# Note: This only supports 'c'.
# usage:
# gdoc [ -docbook | -html | -text | -man ]
# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
#
# Set output format using one of -docbook -html -text or -man. Default is man.
#
# -function funcname
# If set, then only generate documentation for the given function(s). All
# other functions are ignored.
#
# c files - list of 'c' files to process
#
# All output goes to stdout, with errors to stderr.
#
# format of comments.
# In the following table, (...)? signifies optional structure.
# (...)* signifies 0 or more structure elements
# /**
# * function_name(:)? (- short description)?
# (* @parameterx: (description of parameter x)?)*
# (* a blank line)?
# * (Description:)? (Description of function)?
# * (section header: (section description)? )*
# (*)?*/
#
# So .. the trivial example would be:
#
# /**
# * my_function
# **/
#
# If the Description: header tag is ommitted, then there must be a blank line
# after the last parameter specification.
# e.g.
# /**
# * my_function - does my stuff
# * @my_arg: its mine damnit
# *
# * Does my stuff explained.
# */
#
# or, could also use:
# /**
# * my_function - does my stuff
# * @my_arg: its mine damnit
# * Description: Does my stuff explained.
# */
# etc.
#
# All descriptions can be multiline, apart from the short function description.
#
# All descriptive text is further processed, scanning for the following special
# patterns, which are highlighted appropriately.
#
# 'funcname()' - function
# '$ENVVAR' - environmental variable
# '&struct_name' - name of a structure
# '@parameter' - name of a parameter
# '%CONST' - name of a constant.
# match expressions used to find embedded type information
$type_constant = "\\\%(\\w+)";
#$type_func = "(\\w+\\(\\))";
$type_func = "(\\(w||\\\\)+\\(\\))";
$type_param = "\\\@(\\w+)";
$type_struct = "\\\&(\\w+)";
$type_env = "(\\\$\\w+)";
# Output conversion substitutions.
# One for each output format
# these work fairly well
%highlights_html = ( $type_constant, "<i>\$1</i>",
$type_func, "<b>\$1</b>",
$type_struct, "<i>\$1</i>",
$type_param, "<tt><b>\$1</b></tt>" );
$blankline_html = "<p>";
%highlights_tex = ( $type_constant, "{\\\\it \$1}",
$type_func, "{\\\\bf \$1}",
$type_struct, "{\\\\it \$1}",
$type_param, "{\\\\bf \$1}" );
$blankline_tex = "\\par";
# sgml, docbook format
%highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
$type_func, "<function>\$1</function>",
$type_struct, "<structname>\$1</structname>",
$type_env, "<envar>\$1</envar>",
$type_param, "<parameter>\$1</parameter>" );
$blankline_sgml = "</para><para>\n";
# these are pretty rough
%highlights_man = ( $type_constant, "\\n.I \\\"\$1\\\"\\n",
$type_func, "\\n.B \\\"\$1\\\"\\n",
$type_struct, "\\n.I \\\"\$1\\\"\\n",
$type_param."([\.\, ]*)\n?", "\\n.I \\\"\$1\$2\\\"\\n" );
$blankline_man = "";
# text-mode
%highlights_text = ( $type_constant, "\$1",
$type_func, "\$1",
$type_struct, "\$1",
$type_param, "\$1" );
$blankline_text = "";
sub usage {
print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex ]\n";
print " [ -function funcname [ -function funcname ...] ]\n";
print " c source file(s) > outputfile\n";
exit 1;
}
# read arguments
if ($#ARGV==-1) {
usage();
}
$verbose = 0;
$output_mode = "man";
%highlights = %highlights_man;
$blankline = $blankline_man;
$modulename = "API Documentation";
$function_only = 0;
while ($ARGV[0] =~ m/^-(.*)/) {
$cmd = shift @ARGV;
if ($cmd eq "-html") {
$output_mode = "html";
%highlights = %highlights_html;
$blankline = $blankline_html;
} elsif ($cmd eq "-man") {
$output_mode = "man";
%highlights = %highlights_man;
$blankline = $blankline_man;
} elsif ($cmd eq "-tex") {
$output_mode = "tex";
%highlights = %highlights_tex;
$blankline = $blankline_tex;
} elsif ($cmd eq "-text") {
$output_mode = "text";
%highlights = %highlights_text;
$blankline = $blankline_text;
} elsif ($cmd eq "-docbook") {
$output_mode = "sgml";
%highlights = %highlights_sgml;
$blankline = $blankline_sgml;
} elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document
$modulename = shift @ARGV;
} elsif ($cmd eq "-function") { # to only output specific functions
$function_only = 1;
$function = shift @ARGV;
$function_table{$function} = 1;
} elsif ($cmd eq "-v") {
$verbose = 1;
} elsif (($cmd eq "-h") || ($cmd eq "--help")) {
usage();
}
}
# generate a sequence of code that will splice in highlighting information
# using the s// operator.
$dohighlight = "";
foreach $pattern (keys %highlights) {
# print "scanning pattern $pattern ($highlights{$pattern})\n";
$dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
}
##
# dumps section contents to arrays/hashes intended for that purpose.
#
sub dump_section {
my $name = shift @_;
my $contents = join "\n", @_;
if ($name =~ m/$type_constant/) {
$name = $1;
# print STDERR "constant section '$1' = '$contents'\n";
$constants{$name} = $contents;
} elsif ($name =~ m/$type_param/) {
# print STDERR "parameter def '$1' = '$contents'\n";
$name = $1;
$parameters{$name} = $contents;
} else {
# print STDERR "other section '$name' = '$contents'\n";
$sections{$name} = $contents;
push @sectionlist, $name;
}
}
##
# output function
#
# parameters, a hash.
# function => "function name"
# parameterlist => @list of parameters
# parameters => %parameter descriptions
# sectionlist => @list of sections
# sections => %descriont descriptions
#
sub output_highlight {
my $contents = join "\n", @_;
my $line;
eval $dohighlight;
foreach $line (split "\n", $contents) {
if ($line eq ""){
print $lineprefix, $blankline;
} else {
print $lineprefix, $line;
}
print "\n";
}
}
# output in html
sub output_html {
my %args = %{$_[0]};
my ($parameter, $section);
my $count;
print "\n\n<a name=\"". $args{'function'} . "\">&nbsp</a><h2>Function</h2>\n";
print "<i>".$args{'functiontype'}."</i>\n";
print "<b>".$args{'function'}."</b>\n";
print "(";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ", ";
}
}
print ")\n";
print "<h3>Arguments</h3>\n";
print "<dl>\n";
foreach $parameter (@{$args{'parameterlist'}}) {
print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
print "<dd>";
output_highlight($args{'parameters'}{$parameter});
}
print "</dl>\n";
foreach $section (@{$args{'sectionlist'}}) {
print "<h3>$section</h3>\n";
print "<ul>\n";
output_highlight($args{'sections'}{$section});
print "</ul>\n";
}
print "<hr>\n";
}
# output in tex
sub output_tex {
my %args = %{$_[0]};
my ($parameter, $section);
my $count;
my $func = $args{'function'};
my $param;
my $param2;
my $sec;
my $check;
my $type;
$func =~ s/_/\\_/g;
print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\n";
$type = $args{'functiontype'};
$type =~ s/_/\\_/g;
print "{\\it ".$type."}\n";
print "{\\bf ".$func."}\n";
print "(\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
$param = $args{'parametertypes'}{$parameter};
$param2 = $parameter;
$param =~ s/_/\\_/g;
$param2 =~ s/_/\\_/g;
print "{\\it ".$param."} {\\bf ".$param2."}\n";
if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ", ";
}
}
print ")\n";
print "\n{\\large{Arguments}}\n";
print "\\begin{itemize}\n";
$check=0;
foreach $parameter (@{$args{'parameterlist'}}) {
$param = $args{'parametertypes'}{$parameter};
$param =~ s/_/\\_/g;
$param2 = $parameter;
$param2 =~ s/_/\\_/g;
$check = 1;
print "\\item {\\it ".$param."} {\\bf ".$param2."}\n";
print "\n";
output_highlight($param{$parameter});
}
if ($check==0) {
print "\\item void\n";
}
print "\\end{itemize}\n";
foreach $section (@{$args{'sectionlist'}}) {
print "\n\\par{\\large{$section}}\\par\n";
print "\\begin{rmfamily}\n";
$sec = $args{'sections'}{$section};
$sec =~ s/_/\\_/g;
$sec =~ s/&/\\&/g;
output_highlight($sec);
print "\\end{rmfamily}\n";
}
print "\n";
}
# output in sgml DocBook
sub output_sgml {
my %args = %{$_[0]};
my ($parameter, $section);
my $count;
my $id;
$id = $args{'module'}."-".$args{'function'};
$id =~ s/[^A-Za-z0-9]/-/g;
print "<refentry>\n";
print "<refmeta>\n";
print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
print "</refmeta>\n";
print "<refnamediv>\n";
print " <refname>".$args{'function'}."</refname>\n";
print " <refpurpose>\n";
print " ".$args{'purpose'}."\n";
print " </refpurpose>\n";
print "</refnamediv>\n";
print "<refsynopsisdiv>\n";
print " <title>Synopsis</title>\n";
print " <funcsynopsis>\n";
print " <funcdef>".$args{'functiontype'}." ";
print "<function>".$args{'function'}." ";
print "</function></funcdef>\n";
# print "<refsect1>\n";
# print " <title>Synopsis</title>\n";
# print " <funcsynopsis>\n";
# print " <funcdef>".$args{'functiontype'}." ";
# print "<function>".$args{'function'}." ";
# print "</function></funcdef>\n";
$count = 0;
if ($#{$args{'parameterlist'}} >= 0) {
foreach $parameter (@{$args{'parameterlist'}}) {
print " <paramdef>".$args{'parametertypes'}{$parameter};
print " <parameter>$parameter</parameter></paramdef>\n";
}
} else {
print " <void>\n";
}
print " </funcsynopsis>\n";
print "</refsynopsisdiv>\n";
# print "</refsect1>\n";
# print parameters
print "<refsect1>\n <title>Arguments</title>\n";
# print "<para>\nArguments\n";
if ($#{$args{'parameterlist'}} >= 0) {
print " <variablelist>\n";
foreach $parameter (@{$args{'parameterlist'}}) {
print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n";
print " <listitem>\n <para>\n";
$lineprefix=" ";
output_highlight($args{'parameters'}{$parameter});
print " </para>\n </listitem>\n </varlistentry>\n";
}
print " </variablelist>\n";
} else {
print " <para>\n None\n </para>\n";
}
print "</refsect1>\n";
# print out each section
$lineprefix=" ";
foreach $section (@{$args{'sectionlist'}}) {
print "<refsect1>\n <title>$section</title>\n <para>\n";
# print "<para>\n$section\n";
if ($section =~ m/EXAMPLE/i) {
print "<example><para>\n";
}
output_highlight($args{'sections'}{$section});
# print "</para>";
if ($section =~ m/EXAMPLE/i) {
print "</para></example>\n";
}
print " </para>\n</refsect1>\n";
}
print "\n\n";
}
##
# output in man
sub output_man {
my %args = %{$_[0]};
my ($parameter, $section);
my $count;
print ".TH \"$args{'module'}\" \"$args{'function'}\" \"25 May 1998\" \"API Manual\" GNOME\n";
print ".SH Function\n";
print ".I \"".$args{'functiontype'}."\"\n";
print ".B \"".$args{'function'}."\"\n";
print "(\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
print ".I \"".$args{'parametertypes'}{$parameter}."\"\n.B \"".$parameter."\"\n";
if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ",\n";
}
}
print ")\n";
print ".SH Arguments\n";
foreach $parameter (@{$args{'parameterlist'}}) {
print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\" 12\n";
output_highlight($args{'parameters'}{$parameter});
}
foreach $section (@{$args{'sectionlist'}}) {
print ".SH \"$section\"\n";
output_highlight($args{'sections'}{$section});
}
}
##
# output in text
sub output_text {
my %args = %{$_[0]};
my ($parameter, $section);
print "Function = ".$args{'function'}."\n";
print " return type: ".$args{'functiontype'}."\n\n";
foreach $parameter (@{$args{'parameterlist'}}) {
print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n";
print " -> ".$args{'parameters'}{$parameter}."\n";
}
foreach $section (@{$args{'sectionlist'}}) {
print " $section:\n";
print " -> ";
output_highlight($args{'sections'}{$section});
}
}
##
# generic output function - calls the right one based
# on current output mode.
sub output_function {
# output_html(@_);
eval "output_".$output_mode."(\@_);";
}
##
# takes a function prototype and spits out all the details
# stored in the global arrays/hsahes.
sub dump_function {
my $prototype = shift @_;
if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
$prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
$prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
$prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
$prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/) {
$return_type = $1;
$function_name = $2;
$args = $3;
# print STDERR "ARGS = '$args'\n";
foreach $arg (split ',', $args) {
# strip leading/trailing spaces
$arg =~ s/^\s*//;
$arg =~ s/\s*$//;
# print STDERR "SCAN ARG: '$arg'\n";
@args = split('\s', $arg);
# print STDERR " -> @args\n";
$param = pop @args;
# print STDERR " -> @args\n";
if ($param =~ m/^(\*+)(.*)/) {
$param = $2;
push @args, $1;
}
$type = join " ", @args;
if ($parameters{$param} eq "") {
$parameters{$param} = "-- undescribed --";
print STDERR "Warning($lineno): Function parameter '$param' not described in '$function_name'\n";
}
push @parameterlist, $param;
$parametertypes{$param} = $type;
# print STDERR "param = '$param', type = '$type'\n";
}
} else {
print STDERR "Error($lineno): cannot understand prototype: '$prototype'\n";
return;
}
if ($function_only==0 || defined($function_table{$function_name})) {
output_function({'function' => $function_name,
'module' => $modulename,
'functiontype' => $return_type,
'parameterlist' => \@parameterlist,
'parameters' => \%parameters,
'parametertypes' => \%parametertypes,
'sectionlist' => \@sectionlist,
'sections' => \%sections,
'purpose' => $function_purpose
});
}
}
######################################################################
# main
# states
# 0 - normal code
# 1 - looking for function name
# 2 - scanning field start.
# 3 - scanning prototype.
$state = 0;
$section = "";
$doc_special = "\@\%\$\&";
$doc_start = "^/\\*\\*\$";
$doc_end = "\\*/";
$doc_com = "\\s*\\*\\s*";
$doc_func = $doc_com."(\\w+):?";
$doc_sect = $doc_com."([".$doc_special."]?[\\w ]+):(.*)";
$doc_content = $doc_com."(.*)";
%constants = ();
%parameters = ();
@parameterlist = ();
%sections = ();
@sectionlist = ();
$contents = "";
$section_default = "Description"; # default section
$section = $section_default;
$lineno = 0;
foreach $file (@ARGV) {
if (!open(IN,"<$file")) {
print STDERR "Error: Cannot open file $file\n";
next;
}
while (<IN>) {
$lineno++;
if ($state == 0) {
if (/$doc_start/o) {
$state = 1; # next line is always the function name
}
} elsif ($state == 1) { # this line is the function name (always)
if (/$doc_func/o) {
$function = $1;
$state = 2;
if (/-(.*)/) {
$function_purpose = $1;
} else {
$function_purpose = "";
}
if ($verbose) {
print STDERR "Info($lineno): Scanning doc for $function\n";
}
} else {
print STDERR "WARN($lineno): Cannot understand $_ on line $lineno",
" - I thought it was a doc line\n";
$state = 0;
}
} elsif ($state == 2) { # look for head: lines, and include content
if (/$doc_sect/o) {
$newsection = $1;
$newcontents = $2;
if ($contents ne "") {
dump_section($section, $contents);
$section = $section_default;
}
$contents = $newcontents;
if ($contents ne "") {
$contents .= "\n";
}
$section = $newsection;
} elsif (/$doc_end/) {
if ($contents ne "") {
dump_section($section, $contents);
$section = $section_default;
$contents = "";
}
# print STDERR "end of doc comment, looking for prototype\n";
$prototype = "";
$state = 3;
} elsif (/$doc_content/) {
# miguel-style comment kludge, look for blank lines after
# @parameter line to signify start of description
if ($1 eq "" && $section =~ m/^@/) {
dump_section($section, $contents);
$section = $section_default;
$contents = "";
} else {
$contents .= $1."\n";
}
} else {
# i dont know - bad line? ignore.
print STDERR "WARNING($lineno): bad line: $_";
}
} elsif ($state == 3) { # scanning for function { (end of prototype)
if (m#\s*/\*\s+MACDOC\s*#io) {
# do nothing
}
elsif (/([^\{]*)/) {
$prototype .= $1;
}
if (/\{/) {
$prototype =~ s@/\*.*?\*/@@gos; # strip comments.
$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
$prototype =~ s@^ +@@gos; # strip leading spaces
dump_function($prototype);
$function = "";
%constants = ();
%parameters = ();
%parametertypes = ();
@parameterlist = ();
%sections = ();
@sectionlist = ();
$prototype = "";
$state = 0;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,397 @@
@node Copying
@appendix GNU GENERAL PUBLIC LICENSE
@cindex GPL, GNU General Public License
@center Version 2, June 1991
@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display
@appendixsubsec Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software---to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
@iftex
@appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end ifinfo
@enumerate
@item
This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The ``Program'', below,
refers to any such program or work, and a ``work based on the Program''
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term ``modification''.) Each licensee is addressed as ``you''.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
@item
You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
@item
You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
@enumerate a
@item
You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
@item
You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
@item
If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
@end enumerate
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
@item
You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
@enumerate a
@item
Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
@item
Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
@item
Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
@end enumerate
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
@item
You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
@item
You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
@item
Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
@item
If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
@item
If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
@item
The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and ``any
later version'', you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
@item
If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo
@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
@item
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
@end enumerate
@iftex
@heading END OF TERMS AND CONDITIONS
@end iftex
@ifinfo
@center END OF TERMS AND CONDITIONS
@end ifinfo
@page
@unnumberedsec How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the ``copyright'' line and a pointer to where the full notice is found.
@smallexample
@var{one line to give the program's name and an idea of what it does.}
Copyright (C) 19@var{yy} @var{name of author}
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.,
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
@end smallexample
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'. This is free software, and you are welcome
to redistribute it under certain conditions; type `show c'
for details.
@end smallexample
The hypothetical commands @samp{show w} and @samp{show c} should show
the appropriate parts of the General Public License. Of course, the
commands you use may be called something other than @samp{show w} and
@samp{show c}; they could even be mouse-clicks or menu items---whatever
suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a ``copyright disclaimer'' for the program, if
necessary. Here is a sample; alter the names:
@smallexample
@group
Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written
by James Hacker.
@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end group
@end smallexample
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,90 @@
%%comments:
Copyright (C) 2001 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the file COPYING.
%%name: GPGME
%%short-description: GnuPG Made Easy
%%full-description: GPGME is a library designed to make access to
GnuPG easier for applications. It provides a High-Level Crypto API
for encryption, decryption, signing, signature verification and key
management. Currently it uses GnuPG and GpgSM as its backends to
support OpenPGP and the Cryptographic Message Syntax.
%%category: security, libraries
%%license: GPL
%%license verified by:
%%license verified on:
%%maintainer: g10 Code GmbH <gpgme@g10code.com>
%%updated: 2001-12-19
%%keywords: encryption, public key, digital signature, GnuPG
%%interface:
%%programs:
%%GNU: no
%%web-page: http://www.gnupg.org/gpgme.html
%%support: paid extension/consulting from http://www.g10code.com
%%doc: English programmer reference in Texinfo, Postscript, HTML included
%%developers: Werner Koch <wk@gnupg.org>.
%%contributors:
%%sponsors:
%%source: ftp://ftp.gnupg.org/gcrypt/alpha/gpgme/
%%debian:
%%redhat:
%%repository: See http://www.gnupg.org/cvs-access.html
%%related:
%%source-language: C
%%supported-languages: C, C++
%%use-requirements: GnuPG 1.0.6, GpgSM 0.0.0
%%build-prerequisites:
%%weak-prerequisites:
%%source-prerequisites:
%%version: 0.3.0 released on 2001-12-19
%%announce-list: announce@gnupg.org announce-request@gnupg.org
%%announce-news:
%%help-list:
%%help-news:
%%dev-list: gnupg-devel@gnupg.org gnupg-devel-request@gnupg.org
%%dev-news:
%%bug-list:
%%bug-database:
%%entry written by: Werner Koch <wk@gnupg.org>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
# Copyright (C) 2000 Werner Koch (dd9jn)
# Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
## Process this file with automake to produce Makefile.in
EXTRA_DIST = gpgme-config.in gpgme.m4 mkerrors mkstatus
BUILT_SOURCES = errors.c status-table.h
MOSTLYCLEANFILES = errors.c status-table.h
bin_SCRIPTS = gpgme-config
m4datadir = $(datadir)/aclocal
m4data_DATA = gpgme.m4
include_HEADERS = gpgme.h
lib_LTLIBRARIES = libgpgme.la
libgpgme_la_LDFLAGS = -version-info \
@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@
if BUILD_ASSUAN
AM_CPPFLAGS = -I$(top_srcdir)/assuan
libgpgme_la_LIBADD = ../assuan/libassuan.la ../jnlib/libjnlib.la
endif
if HAVE_PTHREAD
ath_components_pthread = ath-pthread.c
else
ath_components_pthread =
endif
if HAVE_PTH
ath_components_pth = ath-pth.c
else
ath_components_pth =
endif
ath_components = ath.h ath.c ${ath_components_pthread} ${ath_components_pth}
if HAVE_DOSISH_SYSTEM
system_components = w32-util.c w32-sema.c w32-io.c
else
system_components = ${ath_components} posix-util.c posix-sema.c posix-io.c
endif
libgpgme_la_SOURCES = \
gpgme.h types.h \
util.h util.c \
context.h ops.h \
data.c recipient.c signers.c \
wait.c wait.h \
encrypt.c \
encrypt-sign.c \
decrypt.c \
decrypt-verify.c \
verify.c \
sign.c \
passphrase.c \
progress.c \
key.c key.h \
keylist.c \
trustlist.c \
import.c \
export.c \
genkey.c \
delete.c \
rungpg.c rungpg.h status-table.h \
engine-gpgsm.c engine-gpgsm.h \
engine.c engine.h \
sema.h io.h \
${system_components} \
debug.c debug.h \
gpgme.c version.c errors.c
errors.c : gpgme.h
$(srcdir)/mkerrors < $(srcdir)/gpgme.h > errors.c
status-table.h : rungpg.h
$(srcdir)/mkstatus < $(srcdir)/rungpg.h > status-table.h

View File

@ -0,0 +1,117 @@
/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <malloc.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
/* 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
};
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;
}

View File

@ -0,0 +1,100 @@
/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <malloc.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 */
};
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;
}

View File

@ -0,0 +1,141 @@
/* ath.c - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "ath.h"
static struct ath_ops *ath_ops;
void
ath_init (void)
{
#ifdef HAVE_PTHREAD
if (!ath_ops)
ath_ops = ath_pthread_available ();
#endif
#ifdef HAVE_PTH
if (!ath_ops)
ath_ops = ath_pth_available ();
#endif
#ifdef HAVE_ATH_DUMMY
if (!ath_ops)
ath_ops = ath_dummy_available ();
#endif
}
int
ath_mutex_init (ath_mutex_t *lock)
{
if (!ath_ops)
return 0;
return ath_ops->mutex_init (lock, 0);
}
int
ath_mutex_destroy (ath_mutex_t *lock)
{
int err;
if (!ath_ops)
return 0;
err = ath_ops->mutex_init (lock, 1);
if (!err)
err = ath_ops->mutex_destroy (*lock);
return err;
}
int
ath_mutex_lock (ath_mutex_t *lock)
{
int err;
if (!ath_ops)
return 0;
err = ath_ops->mutex_init (lock, 1);
if (!err)
err = ath_ops->mutex_lock (*lock);
return err;
}
int
ath_mutex_unlock (ath_mutex_t *lock)
{
int err;
if (!ath_ops)
return 0;
err = ath_ops->mutex_init (lock, 1);
if (!err)
err = ath_ops->mutex_unlock (*lock);
return err;
}
ssize_t
ath_read (int fd, void *buf, size_t nbytes)
{
if (ath_ops && ath_ops->read)
return ath_ops->read (fd, buf, nbytes);
else
return read (fd, buf, nbytes);
}
ssize_t
ath_write (int fd, const void *buf, size_t nbytes)
{
if (ath_ops && ath_ops->write)
return ath_ops->write (fd, buf, nbytes);
else
return write (fd, buf, nbytes);
}
ssize_t
ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout)
{
if (ath_ops && ath_ops->select)
return ath_ops->select (nfd, rset, wset, eset, timeout);
else
return select (nfd, rset, wset, eset, timeout);
}
ssize_t
ath_waitpid (pid_t pid, int *status, int options)
{
if (ath_ops && ath_ops->waitpid)
return ath_ops->waitpid (pid, status, options);
else
return waitpid (pid, status, options);
}

View File

@ -0,0 +1,97 @@
/* ath.h - interfaces 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef ATH_H
#define ATH_H
#include <sys/types.h>
/* 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_init ATH_PREFIX(ath_init)
#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_mutex_pthread_available \
ATH_PREFIX(ath_mutex_pthread_available)
#define ath_mutex_pth_available \
ATH_PREFIX(ath_mutex_pth_available)
#define ath_mutex_dummy_available \
ATH_PREFIX(ath_mutex_dummy_available)
#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_mutex_pthread_available \
ATH_PREFIX(ath_mutex_pthread_available)
#define ath_mutex_pthr_available \
ATH_PREFIX(ath_mutex_pthr_available)
#define ath_mutex_dummy_available \
ATH_PREFIX(ath_mutex_dummy_available)
#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);
struct ath_ops
{
int (*mutex_init) (void **priv, int just_check);
int (*mutex_destroy) (void *priv);
int (*mutex_lock) (void *priv);
int (*mutex_unlock) (void *priv);
ssize_t (*read) (int fd, void *buf, size_t nbytes);
ssize_t (*write) (int fd, const void *buf, size_t nbytes);
ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout);
ssize_t (*waitpid) (pid_t pid, int *status, int options);
};
/* Initialize the any-thread package. */
void ath_init (void);
/* Used by ath_pkg_init. */
struct ath_ops *ath_pthread_available (void);
struct ath_ops *ath_pth_available (void);
struct ath_ops *ath_dummy_available (void);
#endif /* ATH_H */

View File

@ -0,0 +1,152 @@
/* context.h
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef CONTEXT_H
#define CONTEXT_H
#include "gpgme.h"
#include "types.h"
#include "engine.h"
struct key_queue_item_s {
struct key_queue_item_s *next;
GpgmeKey key;
};
struct trust_queue_item_s {
struct trust_queue_item_s *next;
GpgmeTrustItem item;
};
/* Currently we need it at several places, so we put the definition
* into this header file */
struct gpgme_context_s
{
int initialized;
/* A gpg request is still pending. */
int pending;
int use_cms;
/* At some points we need to remember an error which we can't report
immediately. */
GpgmeError error;
/* Cancel operation requested. */
int cancel;
/* The running engine process. */
EngineObject engine;
/* Level of verbosity to use. */
int verbosity;
int use_armor;
int use_textmode;
int keylist_mode;
int include_certs;
/* The number of keys in signers. */
int signers_len;
/* Size of the following array. */
int signers_size;
GpgmeKey *signers;
struct
{
VerifyResult verify;
DecryptResult decrypt;
SignResult sign;
EncryptResult encrypt;
PassphraseResult passphrase;
ImportResult import;
DeleteResult delete;
GenKeyResult genkey;
} result;
/* Last signature notation. */
GpgmeData notation;
/* Last operation info. */
GpgmeData op_info;
/* Used by keylist.c. */
GpgmeKey tmp_key;
/* Something new is available. */
volatile int key_cond;
struct key_queue_item_s *key_queue;
struct trust_queue_item_s *trust_queue;
GpgmePassphraseCb passphrase_cb;
void *passphrase_cb_value;
GpgmeProgressCb progress_cb;
void *progress_cb_value;
GpgmeData help_data_1;
};
struct gpgme_data_s {
size_t len;
const char *data;
GpgmeDataType type;
GpgmeDataMode mode;
GpgmeDataEncoding encoding;
int (*read_cb)( void *, char *, size_t, size_t *);
void *read_cb_value;
int read_cb_eof;
size_t readpos;
size_t writepos;
size_t private_len;
char *private_buffer;
};
struct user_id_s {
struct user_id_s *next;
unsigned int revoked:1;
unsigned int invalid:1;
GpgmeValidity validity;
const char *name_part; /* all 3 point into strings behind name */
const char *email_part; /* or to read-only strings */
const char *comment_part;
char name[1];
};
struct gpgme_recipients_s {
struct user_id_s *list;
int checked; /* wether the recipients are all valid */
};
#define fail_on_pending_request(c) \
do { \
if (!(c)) return GPGME_Invalid_Value; \
if ((c)->pending) return GPGME_Busy; \
} while (0)
#define wait_on_request_or_fail(c) \
do { \
if (!(c)) return GPGME_Invalid_Value;\
if (!(c)->pending) return GPGME_No_Request; \
gpgme_wait ((c), 1); \
} while (0)
#endif /* CONTEXT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,209 @@
/* debug.c - helpful output in desperate situations
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#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 (*(byte *) p); p++)
;
/* Move characters. */
for (mark = NULL; (*string = *p); string++, p++)
if (isspace (*(byte *) 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)
{
const char *e = getenv ("GPGME_DEBUG");
const char *s1, *s2;;
initialized = 1;
errfp = stderr;
if (e)
{
debug_level = atoi (e);
s1 = strchr (e, ':');
if (s1)
{
#ifndef HAVE_DOSISH_SYSTEM
if (getuid () == geteuid ())
{
#endif
char *p;
FILE *fp;
s1++;
if (!(s2 = strchr (s1, ':')))
s2 = s1 + strlen (s1);
p = xtrymalloc (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;
}
xfree (p);
}
#ifndef HAVE_DOSISH_SYSTEM
}
#endif
}
}
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;
}

View File

@ -0,0 +1,110 @@
/* debug.h - interface to debugging functions
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef DEBUG_H
#define DEBUG_H
/* 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))
#elsif 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, __FILE__, XSTRINGIFY (__LINE__))
#define DEBUG1(fmt,a) \
_gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__), (a))
#define DEBUG2(fmt,a,b) \
_gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__), (a), (b))
#define DEBUG3(fmt,a,b,c) \
_gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__), (a), (b), \
(c))
#define DEBUG4(fmt,a,b,c,d) \
_gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__), (a), (b), \
(c), (d))
#define DEBUG5(fmt,a,b,c,d,e) \
_gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__), (a), (b), \
(c), (d), (e))
#define DEBUG_BEGIN(hlp,lvl,fmt) \
_gpgme_debug_begin (&(hlp), lvl, "%s:%s: " fmt, __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 */

View File

@ -0,0 +1,80 @@
/* decrypt-verify.c - decrypt and verify functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
static void
decrypt_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
_gpgme_decrypt_status_handler (ctx, code, args);
_gpgme_verify_status_handler (ctx, code, args);
}
GpgmeError
gpgme_op_decrypt_verify_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
{
return _gpgme_decrypt_start (ctx, ciph, plain,
decrypt_verify_status_handler);
}
/**
* gpgme_op_decrypt_verify:
* @ctx: The context
* @in: ciphertext input
* @out: plaintext output
*
* This function decrypts @in to @out and performs a signature check.
* Other parameters are take from the context @c.
* The function does wait for the result.
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_decrypt_verify (GpgmeCtx ctx,
GpgmeData in, GpgmeData out,
GpgmeSigStat *r_stat)
{
GpgmeError err;
gpgme_data_release (ctx->notation);
ctx->notation = NULL;
*r_stat = GPGME_SIG_STAT_NONE;
err = gpgme_op_decrypt_verify_start (ctx, in, out);
if (!err)
{
gpgme_wait (ctx, &err, 1);
if (!err)
*r_stat = _gpgme_intersect_stati (ctx->result.verify);
}
return err;
}

View File

@ -0,0 +1,165 @@
/* decrypt.c - decrypt functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct decrypt_result_s
{
int okay;
int failed;
};
void
_gpgme_release_decrypt_result (DecryptResult result)
{
if (!result)
return;
xfree (result);
}
void
_gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
_gpgme_passphrase_status_handler (ctx, code, args);
if (ctx->error)
return;
test_and_allocate_result (ctx, decrypt);
switch (code)
{
case STATUS_EOF:
if (ctx->result.decrypt->failed)
ctx->error = mk_error (Decryption_Failed);
else if (!ctx->result.decrypt->okay)
ctx->error = mk_error (No_Data);
break;
case STATUS_DECRYPTION_OKAY:
ctx->result.decrypt->okay = 1;
break;
case STATUS_DECRYPTION_FAILED:
ctx->result.decrypt->failed = 1;
break;
default:
/* Ignore all other codes. */
break;
}
}
GpgmeError
_gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
void *status_handler)
{
GpgmeError err = 0;
fail_on_pending_request (ctx);
ctx->pending = 1;
_gpgme_release_result (ctx);
/* Create a process object. */
_gpgme_engine_release (ctx->engine);
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
/* Check the supplied data. */
if (!ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE)
{
err = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT);
if (gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE)
{
err = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (plain, GPGME_DATA_MODE_IN);
err = _gpgme_passphrase_start (ctx);
if (err)
goto leave;
_gpgme_engine_set_status_handler (ctx->engine, status_handler, ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
err = _gpgme_engine_op_decrypt (ctx->engine, ciph, plain);
if (!err) /* And kick off the process. */
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
GpgmeError
gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
{
return _gpgme_decrypt_start (ctx, ciph, plain,
_gpgme_decrypt_status_handler);
}
/**
* gpgme_op_decrypt:
* @ctx: The context
* @in: ciphertext input
* @out: plaintext output
*
* This function decrypts @in to @out.
* Other parameters are take from the context @ctx.
* The function does wait for the result.
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out)
{
GpgmeError err = gpgme_op_decrypt_start (ctx, in, out);
if (!err)
gpgme_wait (ctx, &err, 1);
return err;
}

View File

@ -0,0 +1,157 @@
/* delete.c - delete a key
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
#include "key.h"
enum delete_problem
{
DELETE_No_Problem = 0,
DELETE_No_Such_Key = 1,
DELETE_Must_Delete_Secret_Key = 2
};
struct delete_result_s
{
enum delete_problem problem;
};
void
_gpgme_release_delete_result (DeleteResult result)
{
if (!result)
return;
xfree (result);
}
static void
delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
if (ctx->error)
return;
test_and_allocate_result (ctx, delete);
switch (code)
{
case STATUS_EOF:
switch (ctx->result.delete->problem)
{
case DELETE_No_Problem:
break;
case DELETE_No_Such_Key:
ctx->error = mk_error(Invalid_Key);
break;
case DELETE_Must_Delete_Secret_Key:
ctx->error = mk_error(Conflict);
break;
default:
ctx->error = mk_error(General_Error);
break;
}
break;
case STATUS_DELETE_PROBLEM:
ctx->result.delete->problem = atoi (args);
break;
default:
/* Ignore all other codes. */
break;
}
}
GpgmeError
gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
{
GpgmeError err = 0;
fail_on_pending_request (ctx);
ctx->pending = 1;
if (!key)
{
err = mk_error (Invalid_Value);
goto leave;
}
if (ctx->engine)
{
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
_gpgme_release_result (ctx);
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
_gpgme_engine_set_status_handler (ctx->engine, delete_status_handler, ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
err = _gpgme_engine_op_delete (ctx->engine, key, allow_secret);
if (!err)
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_delete:
* @c: Context
* @key: A Key Object
* @allow_secret: Allow secret key delete
*
* Delete the give @key from the key database. To delete a secret
* along with the public key, @allow_secret must be true.
*
* Return value: 0 on success or an error code.
**/
GpgmeError
gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
{
GpgmeError err = gpgme_op_delete_start (ctx, key, allow_secret);
if (!err)
gpgme_wait (ctx, &err, 1);
return err;
}

View File

@ -0,0 +1,150 @@
/* encrypt-sign.c - encrypt and verify functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
static void
encrypt_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
char *encrypt_info = 0;
int encrypt_info_len;
_gpgme_encrypt_status_handler (ctx, code, args);
if (code == STATUS_EOF)
{
encrypt_info = gpgme_data_release_and_get_mem (ctx->op_info,
&encrypt_info_len);
ctx->op_info = NULL;
}
_gpgme_sign_status_handler (ctx, code, args);
if (code == STATUS_EOF && encrypt_info)
_gpgme_data_append (ctx->op_info, encrypt_info, encrypt_info_len);
}
GpgmeError
gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
GpgmeData plain, GpgmeData cipher)
{
int err = 0;
fail_on_pending_request (ctx);
ctx->pending = 1;
_gpgme_release_result (ctx);
/* Do some checks. */
if (!gpgme_recipients_count (recp))
{
/* FIXME: In this case we should do symmetric encryption. */
err = mk_error (No_Recipients);
goto leave;
}
/* Create an engine object. */
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
err = _gpgme_passphrase_start (ctx);
if (err)
goto leave;
_gpgme_engine_set_status_handler (ctx->engine,
encrypt_sign_status_handler, ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
/* Check the supplied data */
if (gpgme_data_get_type (plain) == GPGME_DATA_TYPE_NONE)
{
err = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (plain, GPGME_DATA_MODE_OUT);
if (!cipher || gpgme_data_get_type (cipher) != GPGME_DATA_TYPE_NONE)
{
err = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (cipher, GPGME_DATA_MODE_IN);
err = _gpgme_engine_op_encrypt_sign (ctx->engine, recp, plain, cipher,
ctx->use_armor, ctx /* FIXME */);
if (!err) /* And kick off the process. */
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_encrypt_sign:
* @ctx: The context
* @recp: The set of recipients
* @plain: plaintext input
* @cipher: signed ciphertext
*
* This function encrypts @plain for all recipients in recp, signs it,
* and returns the ciphertext in @out. The function does wait for the
* result.
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_encrypt_sign (GpgmeCtx ctx, GpgmeRecipients recp,
GpgmeData plain, GpgmeData cipher)
{
GpgmeError err = gpgme_op_encrypt_sign_start (ctx, recp, plain, cipher);
if (!err)
{
gpgme_wait (ctx, &err, 1);
/* Old gpg versions don't return status info for invalid
recipients, so we simply check whether we got any output at
all, and if not we assume that we don't have valid
recipients. */
if (!ctx->error && gpgme_data_get_type (cipher) == GPGME_DATA_TYPE_NONE)
ctx->error = mk_error (No_Recipients);
err = ctx->error;
}
return err;
}

View File

@ -0,0 +1,249 @@
/* encrypt.c - encrypt functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
#define SKIP_TOKEN_OR_RETURN(a) do { \
while (*(a) && *(a) != ' ') (a)++; \
while (*(a) == ' ') (a)++; \
if (!*(a)) \
return; /* oops */ \
} while (0)
struct encrypt_result_s
{
int no_valid_recipients;
int invalid_recipients;
GpgmeData xmlinfo;
};
void
_gpgme_release_encrypt_result (EncryptResult result)
{
if (!result)
return;
gpgme_data_release (result->xmlinfo);
xfree (result);
}
/*
* Parse the args and save the information
* in an XML structure.
* With args of NULL the xml structure is closed.
*/
static void
append_xml_encinfo (GpgmeData *rdh, char *args)
{
GpgmeData dh;
char helpbuf[100];
if (!*rdh)
{
if (gpgme_data_new (rdh))
return; /* FIXME: We are ignoring out-of-core. */
dh = *rdh;
_gpgme_data_append_string (dh, "<GnupgOperationInfo>\n");
}
else
{
dh = *rdh;
_gpgme_data_append_string (dh, " </encryption>\n");
}
if (!args)
{
/* Just close the XML containter. */
_gpgme_data_append_string (dh, "</GnupgOperationInfo>\n");
return;
}
_gpgme_data_append_string (dh, " <encryption>\n"
" <error>\n"
" <invalidRecipient/>\n");
sprintf (helpbuf, " <reason>%d</reason>\n", atoi (args));
_gpgme_data_append_string (dh, helpbuf);
SKIP_TOKEN_OR_RETURN (args);
_gpgme_data_append_string (dh, " <name>");
_gpgme_data_append_percentstring_for_xml (dh, args);
_gpgme_data_append_string (dh, "</name>\n"
" </error>\n");
}
void
_gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
if (ctx->error)
return;
test_and_allocate_result (ctx, encrypt);
switch (code)
{
case STATUS_EOF:
if (ctx->result.encrypt->xmlinfo)
{
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, NULL);
_gpgme_set_op_info (ctx, ctx->result.encrypt->xmlinfo);
ctx->result.encrypt->xmlinfo = NULL;
}
if (ctx->result.encrypt->no_valid_recipients)
ctx->error = mk_error (No_Recipients);
else if (ctx->result.encrypt->invalid_recipients)
ctx->error = mk_error (Invalid_Recipients);
break;
case STATUS_INV_RECP:
ctx->result.encrypt->invalid_recipients++;
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, args);
break;
case STATUS_NO_RECP:
ctx->result.encrypt->no_valid_recipients = 1;
break;
default:
break;
}
}
void
_gpgme_encrypt_sym_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
_gpgme_passphrase_status_handler (ctx, code, args);
}
GpgmeError
gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
GpgmeData ciph)
{
int err = 0;
int symmetric = 0;
fail_on_pending_request (ctx);
ctx->pending = 1;
_gpgme_release_result (ctx);
/* Do some checks. */
if (!recp)
symmetric = 1;
else if (!gpgme_recipients_count (recp))
{
err = mk_error (No_Recipients);
goto leave;
}
/* Create an engine object. */
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
if (symmetric)
{
err = _gpgme_passphrase_start (ctx);
if (err)
goto leave;
}
_gpgme_engine_set_status_handler (ctx->engine,
symmetric
? _gpgme_encrypt_sym_status_handler
: _gpgme_encrypt_status_handler,
ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
/* Check the supplied data */
if (gpgme_data_get_type (plain) == GPGME_DATA_TYPE_NONE)
{
err = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (plain, GPGME_DATA_MODE_OUT);
if (!ciph || gpgme_data_get_type (ciph) != GPGME_DATA_TYPE_NONE)
{
err = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (ciph, GPGME_DATA_MODE_IN);
err = _gpgme_engine_op_encrypt (ctx->engine, recp, plain, ciph, ctx->use_armor);
if (!err) /* And kick off the process. */
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_encrypt:
* @c: The context
* @recp: A set of recipients
* @in: plaintext input
* @out: ciphertext output
*
* This function encrypts @in to @out for all recipients from
* @recp. Other parameters are take from the context @c.
* The function does wait for the result.
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_encrypt (GpgmeCtx ctx, GpgmeRecipients recp,
GpgmeData plain, GpgmeData cipher)
{
int err = gpgme_op_encrypt_start (ctx, recp, plain, cipher);
if (!err)
{
gpgme_wait (ctx, &err, 1);
/* Old gpg versions don't return status info for invalid
recipients, so we simply check whether we got any output at
all, and if not we assume that we don't have valid
recipients. */
if (!ctx->error && gpgme_data_get_type (cipher) == GPGME_DATA_TYPE_NONE)
ctx->error = mk_error (No_Recipients);
err = ctx->error;
}
return err;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
/* engine-gpgsm.h - GPGME GpgSM engine calling functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef ENGINE_GPGSM_H
#define ENGINE_GPGSM_H
#include "types.h"
#include "rungpg.h" /* FIXME statusHandler */
const char *_gpgme_gpgsm_get_version (void);
GpgmeError _gpgme_gpgsm_check_version (void);
GpgmeError _gpgme_gpgsm_new (GpgsmObject *r_gpg);
void _gpgme_gpgsm_release (GpgsmObject gpg);
void _gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm,
GpgStatusHandler fnc, void *fnc_value);
void _gpgme_gpgsm_set_colon_line_handler (GpgsmObject gpgsm,
GpgColonLineHandler fnc, void *fnc_value) ;
GpgmeError _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph,
GpgmeData plain);
GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key,
int allow_secret);
GpgmeError _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph,
int use_armor);
GpgmeError _gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp,
GpgmeData keydata, int use_armor);
GpgmeError _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data,
int use_armor, GpgmeData pubkey,
GpgmeData seckey);
GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata);
GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
int secret_only, int keylist_mode);
GpgmeError _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm,
const char *pattern[],
int secret_only, int reserved,
int keylist_mode);
GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in,
GpgmeData out,
GpgmeSigMode mode, int use_armor,
int use_textmode, int include_certs,
GpgmeCtx ctx /* FIXME */);
GpgmeError _gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern);
GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig,
GpgmeData text);
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
#endif /* ENGINE_GPGSM_H */

View File

@ -0,0 +1,650 @@
/* engine.c
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <time.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include "gpgme.h"
#include "util.h"
#include "sema.h"
#include "io.h"
#include "engine.h"
#include "rungpg.h"
#include "engine-gpgsm.h"
struct engine_object_s
{
GpgmeProtocol protocol;
const char *path;
const char *version;
union
{
GpgObject gpg;
GpgsmObject gpgsm;
} engine;
};
struct reap_s
{
struct reap_s *next;
int pid;
time_t entered;
int term_send;
};
static struct reap_s *reap_list;
DEFINE_STATIC_LOCK (reap_list_lock);
/* Get the path of the engine for PROTOCOL. */
const char *
_gpgme_engine_get_path (GpgmeProtocol proto)
{
switch (proto)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_get_gpg_path ();
case GPGME_PROTOCOL_CMS:
return _gpgme_get_gpgsm_path ();
default:
return NULL;
}
}
/* Get the version number of the engine for PROTOCOL. */
const char *
_gpgme_engine_get_version (GpgmeProtocol proto)
{
switch (proto)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_get_version ();
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_get_version ();
default:
return NULL;
}
}
GpgmeError
gpgme_engine_check_version (GpgmeProtocol proto)
{
switch (proto)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_check_version ();
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_check_version ();
default:
return mk_error (Invalid_Value);
}
}
const char *
_gpgme_engine_get_info (GpgmeProtocol proto)
{
static const char fmt[] = " <engine>\n"
" <protocol>%s</protocol>\n"
" <version>%s</version>\n"
" <path>%s</path>\n"
" </engine>\n";
static const char *const strproto[3] = { "OpenPGP", "CMS", NULL };
static const char *engine_info[3]; /* FIXME: MAX_PROTO + 1*/
DEFINE_STATIC_LOCK (engine_info_lock);
if (proto > 2 /* FIXME MAX_PROTO */ || !strproto[proto])
return NULL;
LOCK (engine_info_lock);
if (!engine_info[proto])
{
const char *path = _gpgme_engine_get_path (proto);
const char *version = _gpgme_engine_get_version (proto);
if (path && version)
{
char *info = xtrymalloc (strlen (fmt) + strlen (strproto[proto])
+ strlen (path) + strlen (version) + 1);
if (!info)
info = " <engine>\n"
" <error>Out of core</error>\n"
" </engine>";
else
sprintf (info, fmt, strproto[proto], version, path);
engine_info[proto] = info;
}
}
UNLOCK (engine_info_lock);
return engine_info[proto];
}
GpgmeError
_gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine)
{
EngineObject engine;
GpgmeError err = 0;
engine = xtrycalloc (1, sizeof *engine);
if (!engine)
{
err = mk_error (Out_Of_Core);
goto leave;
}
engine->protocol = proto;
switch (proto)
{
case GPGME_PROTOCOL_OpenPGP:
err =_gpgme_gpg_new (&engine->engine.gpg);
break;
case GPGME_PROTOCOL_CMS:
err = _gpgme_gpgsm_new (&engine->engine.gpgsm);
if (err)
goto leave;
break;
default:
err = mk_error (Invalid_Value);
}
if (err)
goto leave;
engine->path = _gpgme_engine_get_path (proto);
engine->version = _gpgme_engine_get_version (proto);
if (!engine->path || !engine->version)
{
err = mk_error (Invalid_Engine);
goto leave;
}
leave:
if (err)
_gpgme_engine_release (engine);
else
*r_engine = engine;
return err;
}
void
_gpgme_engine_release (EngineObject engine)
{
if (!engine)
return;
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
_gpgme_gpg_release (engine->engine.gpg);
break;
case GPGME_PROTOCOL_CMS:
_gpgme_gpgsm_release (engine->engine.gpgsm);
break;
default:
break;
}
xfree (engine);
}
void
_gpgme_engine_set_verbosity (EngineObject engine, int verbosity)
{
if (!engine)
return;
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
while (verbosity-- > 0)
_gpgme_gpg_add_arg (engine->engine.gpg, "--verbose");
break;
case GPGME_PROTOCOL_CMS:
/* FIXME */
break;
default:
break;
}
}
void
_gpgme_engine_set_status_handler (EngineObject engine,
GpgStatusHandler fnc, void *fnc_value)
{
if (!engine)
return;
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
_gpgme_gpg_set_status_handler (engine->engine.gpg, fnc, fnc_value);
break;
case GPGME_PROTOCOL_CMS:
_gpgme_gpgsm_set_status_handler (engine->engine.gpgsm, fnc, fnc_value);
break;
default:
break;
}
}
GpgmeError
_gpgme_engine_set_command_handler (EngineObject engine,
GpgCommandHandler fnc, void *fnc_value)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_set_command_handler (engine->engine.gpg, fnc, fnc_value);
case GPGME_PROTOCOL_CMS:
/* FIXME */
break;
default:
break;
}
return 0;
}
GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine,
GpgColonLineHandler fnc,
void *fnc_value)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_set_colon_line_handler (engine->engine.gpg,
fnc, fnc_value);
case GPGME_PROTOCOL_CMS:
_gpgme_gpgsm_set_colon_line_handler (engine->engine.gpgsm,
fnc, fnc_value);
break;
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph, GpgmeData plain)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_decrypt (engine->engine.gpg, ciph, plain);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_decrypt (engine->engine.gpgsm, ciph, plain);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_delete (engine->engine.gpg, key, allow_secret);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_delete (engine->engine.gpgsm, key, allow_secret);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph, int use_armor)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_encrypt (engine->engine.gpg, recp, plain, ciph,
use_armor);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_encrypt (engine->engine.gpgsm, recp, plain, ciph,
use_armor);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_encrypt_sign (EngineObject engine, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph, int use_armor,
GpgmeCtx ctx /* FIXME */)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_encrypt_sign (engine->engine.gpg, recp, plain, ciph,
use_armor, ctx);
case GPGME_PROTOCOL_CMS:
return mk_error (Not_Implemented);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp,
GpgmeData keydata, int use_armor)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_export (engine->engine.gpg, recp, keydata,
use_armor);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_export (engine->engine.gpgsm, recp, keydata,
use_armor);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data,
int use_armor, GpgmeData pubkey, GpgmeData seckey)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_genkey (engine->engine.gpg, help_data, use_armor,
pubkey, seckey);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_genkey (engine->engine.gpgsm, help_data, use_armor,
pubkey, seckey);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_import (EngineObject engine, GpgmeData keydata)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_import (engine->engine.gpg, keydata);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_import (engine->engine.gpgsm, keydata);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
int secret_only, int keylist_mode)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_keylist (engine->engine.gpg, pattern, secret_only,
keylist_mode);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_keylist (engine->engine.gpgsm, pattern, secret_only,
keylist_mode);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_keylist_ext (EngineObject engine, const char *pattern[],
int secret_only, int reserved, int keylist_mode)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_keylist_ext (engine->engine.gpg, pattern,
secret_only, reserved, keylist_mode);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_keylist_ext (engine->engine.gpgsm, pattern,
secret_only, reserved, keylist_mode);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor,
int use_textmode, int include_certs,
GpgmeCtx ctx /* FIXME */)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_sign (engine->engine.gpg, in, out, mode, use_armor,
use_textmode, ctx);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_sign (engine->engine.gpgsm, in, out, mode,
use_armor, use_textmode, include_certs, ctx);
break;
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_trustlist (EngineObject engine, const char *pattern)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_trustlist (engine->engine.gpg, pattern);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_trustlist (engine->engine.gpgsm, pattern);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, GpgmeData text)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_op_verify (engine->engine.gpg, sig, text);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_op_verify (engine->engine.gpgsm, sig, text);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_start (EngineObject engine, void *opaque)
{
if (!engine)
return mk_error (Invalid_Value);
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_spawn (engine->engine.gpg, opaque);
case GPGME_PROTOCOL_CMS:
return _gpgme_gpgsm_start (engine->engine.gpgsm, opaque);
default:
break;
}
return 0;
}
void
_gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid)
{
/* Reuse the memory, so that we don't need to allocate another
memory block and to handle errors. */
struct reap_s *child = buf;
assert (buflen >= sizeof *child);
memset (child, 0, sizeof *child);
child->pid = pid;
child->entered = time (NULL);
LOCK (reap_list_lock);
child->next = reap_list;
reap_list = child;
UNLOCK (reap_list_lock);
}
static void
do_reaping (void)
{
struct reap_s *r, *rlast;
static time_t last_check;
time_t cur_time = time (NULL);
/* A race does not matter here. */
if (!last_check)
last_check = time (NULL);
if (last_check >= cur_time)
return; /* We check only every second. */
/* Fixme: it would be nice if to have a TRYLOCK here. */
LOCK (reap_list_lock);
for (r = reap_list, rlast = NULL; r; rlast = r, r = r ? r->next : NULL)
{
int dummy1, dummy2;
if (_gpgme_io_waitpid (r->pid, 0, &dummy1, &dummy2))
{
/* The process has terminated - remove it from the queue. */
void *p = r;
if (!rlast)
{
reap_list = r->next;
r = reap_list;
}
else
{
rlast->next = r->next;
r = rlast;
}
xfree (p);
}
else if (!r->term_send)
{
if (r->entered + 1 >= cur_time)
{
_gpgme_io_kill (r->pid, 0);
r->term_send = 1;
r->entered = cur_time;
}
}
else
{
/* Give it 5 second before we are going to send the killer. */
if (r->entered + 5 >= cur_time)
{
_gpgme_io_kill (r->pid, 1);
r->entered = cur_time; /* Just in case we have to repeat it. */
}
}
}
UNLOCK (reap_list_lock);
}
void
_gpgme_engine_housecleaning (void)
{
do_reaping ();
}

View File

@ -0,0 +1,82 @@
/* engine.h - GPGME engine calling functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef ENGINE_H
#define ENGINE_H
#include "types.h"
#include "rungpg.h"
const char *_gpgme_engine_get_path (GpgmeProtocol proto);
const char *_gpgme_engine_get_version (GpgmeProtocol proto);
const char * _gpgme_engine_get_info (GpgmeProtocol proto);
GpgmeError _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine);
void _gpgme_engine_release (EngineObject engine);
void _gpgme_engine_set_status_handler (EngineObject engine,
GpgStatusHandler fnc, void *fnc_value);
GpgmeError _gpgme_engine_set_command_handler (EngineObject engine,
GpgCommandHandler fnc,
void *fnc_value);
GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject gpg,
GpgColonLineHandler fnc,
void *fnc_value);
void _gpgme_engine_set_verbosity (EngineObject engine, int verbosity);
GpgmeError _gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph,
GpgmeData plain);
GpgmeError _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key,
int allow_secret);
GpgmeError _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph,
int use_armor);
GpgmeError _gpgme_engine_op_encrypt_sign (EngineObject engine,
GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph,
int use_armor,
GpgmeCtx ctx /* FIXME */);
GpgmeError _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp,
GpgmeData keydata, int use_armor);
GpgmeError _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data,
int use_armor, GpgmeData pubkey,
GpgmeData seckey);
GpgmeError _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata);
GpgmeError _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
int secret_only,
int keylist_mode);
GpgmeError _gpgme_engine_op_keylist_ext (EngineObject engine,
const char *pattern[],
int secret_only,
int reserved,
int keylist_mode);
GpgmeError _gpgme_engine_op_sign (EngineObject engine, GpgmeData in,
GpgmeData out, GpgmeSigMode mode,
int use_armor, int use_textmode,
int include_certs,
GpgmeCtx ctx /* FIXME */);
GpgmeError _gpgme_engine_op_trustlist (EngineObject engine,
const char *pattern);
GpgmeError _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig,
GpgmeData text);
GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque);
void _gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid);
void _gpgme_engine_housecleaning (void);
#endif /* ENGINE_H */

View File

@ -0,0 +1,107 @@
/* export.c - encrypt functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
static void
export_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
if (ctx->error)
return;
DEBUG2 ("export_status: code=%d args=`%s'\n", code, args);
/* FIXME: Need to do more */
}
GpgmeError
gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
{
GpgmeError err = 0;
fail_on_pending_request (ctx);
ctx->pending = 1;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
_gpgme_release_result (ctx);
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
if (!keydata || gpgme_data_get_type (keydata) != GPGME_DATA_TYPE_NONE)
{
err = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (keydata, GPGME_DATA_MODE_IN);
_gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
err = _gpgme_engine_op_export (ctx->engine, recp, keydata, ctx->use_armor);
if (!err)
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_export:
* @c: the context
* @recp: a list of recipients or NULL
* @keydata: Returns the keys
*
* This function can be used to extract public keys from the GnuPG key
* database either in armored (by using gpgme_set_armor()) or in plain
* binary form. The function expects a list of user IDs in @recp for
* whom the public keys are to be exported.
*
* Return value: 0 for success or an error code
**/
GpgmeError
gpgme_op_export (GpgmeCtx ctx, GpgmeRecipients recipients, GpgmeData keydata)
{
GpgmeError err = gpgme_op_export_start (ctx, recipients, keydata);
if (!err)
gpgme_wait (ctx, &err, 1);
return err;
}

View File

@ -0,0 +1,37 @@
/* fopencookie.c - Dummy glibc replacement
* Copyright (C) 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <errno.h>
#include "util.h"
FILE *
fopencookie (void *cookie, const char *opentype,
cookie_io_functions_t funclist)
{
errno = ENOSYS;
return NULL;
}

View File

@ -0,0 +1,224 @@
/* genkey.c - key generation
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct genkey_result_s
{
int created_primary : 1;
int created_sub : 1;
};
void
_gpgme_release_genkey_result (GenKeyResult result)
{
if (!result)
return;
xfree (result);
}
static void
genkey_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
_gpgme_progress_status_handler (ctx, code, args);
if (ctx->error)
return;
test_and_allocate_result (ctx, genkey);
switch (code)
{
case STATUS_KEY_CREATED:
if (args && *args)
{
if (*args == 'B' || *args == 'P')
ctx->result.genkey->created_primary = 1;
if (*args == 'B' || *args == 'S')
ctx->result.genkey->created_sub = 1;
}
break;
case STATUS_EOF:
/* FIXME: Should return some more useful error value. */
if (!ctx->result.genkey->created_primary
&& !ctx->result.genkey->created_sub)
ctx->error = mk_error (General_Error);
break;
default:
break;
}
}
/**
* gpgme_op_genkey:
* @c: the context
* @parms: XML string with the key parameters
* @pubkey: Returns the public key
* @seckey: Returns the secret key
*
* Generate a new key and store the key in the default keyrings if
* both @pubkey and @seckey are NULL. If @pubkey and @seckey are
* given, the newly created key will be returned in these data
* objects. This function just starts the gheneration and does not
* wait for completion.
*
* Here is an example on how @parms should be formatted; for deatils
* see the file doc/DETAILS from the GnuPG distribution.
*
* <literal>
* <![CDATA[
* <GnupgKeyParms format="internal">
* Key-Type: DSA
* Key-Length: 1024
* Subkey-Type: ELG-E
* Subkey-Length: 1024
* Name-Real: Joe Tester
* Name-Comment: with stupid passphrase
* Name-Email: joe@foo.bar
* Expire-Date: 0
* Passphrase: abc
* </GnupgKeyParms>
* ]]>
* </literal>
*
* Strings should be given in UTF-8 encoding. The format we support
* for now is only "internal". The content of the
* &lt;GnupgKeyParms&gt; container is passed verbatim to GnuPG.
* Control statements are not allowed.
*
* Return value: 0 for success or an error code
**/
GpgmeError
gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms,
GpgmeData pubkey, GpgmeData seckey)
{
int err = 0;
const char *s, *s2, *sx;
fail_on_pending_request (ctx);
ctx->pending = 1;
gpgme_data_release (ctx->help_data_1);
ctx->help_data_1 = NULL;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
if (!pubkey && !seckey)
; /* okay: Add key to the keyrings */
else if (pubkey && gpgme_data_get_type (pubkey) != GPGME_DATA_TYPE_NONE)
{
err = mk_error (Invalid_Value);
goto leave;
}
else if (seckey && gpgme_data_get_type (seckey) != GPGME_DATA_TYPE_NONE)
{
err = mk_error (Invalid_Value);
goto leave;
}
if (pubkey)
/* FIXME: Need some more things here. */
_gpgme_data_set_mode (pubkey, GPGME_DATA_MODE_IN);
if (seckey)
/* FIXME: Need some more things here. */
_gpgme_data_set_mode (seckey, GPGME_DATA_MODE_IN);
if ((parms = strstr (parms, "<GnupgKeyParms "))
&& (s = strchr (parms, '>'))
&& (sx = strstr (parms, "format=\"internal\""))
&& sx < s
&& (s2 = strstr (s+1, "</GnupgKeyParms>")))
{
/* FIXME: Check that there are no control statements inside. */
s++; /* Skip '>'. */
while (*s == '\n')
s++;
err = gpgme_data_new_from_mem (&ctx->help_data_1, s, s2-s, 1);
}
else
err = mk_error (Invalid_Value);
if (err)
goto leave;
_gpgme_data_set_mode (ctx->help_data_1, GPGME_DATA_MODE_OUT);
_gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
err = _gpgme_engine_op_genkey (ctx->engine, ctx->help_data_1, ctx->use_armor,
pubkey, seckey);
if (!err)
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_genkey:
* @c: the context
* @parms: XML string with the key parameters
* @pubkey: Returns the public key
* @seckey: Returns the secret key
*
* Generate a new key and store the key in the default keyrings if both
* @pubkey and @seckey are NULL. If @pubkey and @seckey are given, the newly
* created key will be returned in these data objects.
* See gpgme_op_genkey_start() for a description of @parms.
*
* Return value: 0 for success or an error code
**/
GpgmeError
gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
GpgmeData pubkey, GpgmeData seckey)
{
GpgmeError err = gpgme_op_genkey_start (ctx, parms, pubkey, seckey);
if (!err)
gpgme_wait (ctx, &err, 1);
return err;
}

View File

@ -0,0 +1,93 @@
#!/bin/sh
prefix=@prefix@
exec_prefix=@exec_prefix@
exec_prefix_set=no
gpgme_libs="@GPGME_LIBS@"
gpgme_cflags="@GPGME_CFLAGS@"
usage()
{
cat <<EOF
Usage: gpgme-config [OPTIONS]
Options:
[--prefix[=DIR]]
[--exec-prefix[=DIR]]
[--version]
[--libs]
[--cflags]
EOF
exit $1
}
if test $# -eq 0; then
usage 1 1>&2
fi
while test $# -gt 0; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case $1 in
--prefix=*)
prefix=$optarg
if test $exec_prefix_set = no ; then
exec_prefix=$optarg
fi
;;
--prefix)
echo_prefix=yes
;;
--exec-prefix=*)
exec_prefix=$optarg
exec_prefix_set=yes
;;
--exec-prefix)
echo_exec_prefix=yes
;;
--version)
echo "@VERSION@"
exit 0
;;
--cflags)
echo_cflags=yes
;;
--libs)
echo_libs=yes
;;
*)
usage 1 1>&2
;;
esac
shift
done
if test "$echo_prefix" = "yes"; then
echo $prefix
fi
if test "$echo_exec_prefix" = "yes"; then
echo $exec_prefix
fi
if test "$echo_cflags" = "yes"; then
if test "@includedir@" != "/usr/include" ; then
includes="-I@includedir@"
for i in $gpgme_cflags ; do
if test "$i" = "-I@includedir@" ; then
includes=""
fi
done
fi
echo $includes $gpgme_cflags
fi
if test "$echo_libs" = "yes"; then
echo ${gpgme_libs}
fi

View File

@ -0,0 +1,493 @@
/* gpgme.c - GnuPG Made Easy
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
/**
* gpgme_new:
* @r_ctx: Returns the new context
*
* Create a new context to be used with most of the other GPGME
* functions. Use gpgme_release_context() to release all resources
*
* Return value: An error code
**/
GpgmeError
gpgme_new (GpgmeCtx *r_ctx)
{
GpgmeCtx ctx;
if (!r_ctx)
return mk_error (Invalid_Value);
*r_ctx = 0;
ctx = xtrycalloc (1, sizeof *ctx);
if (!ctx)
return mk_error (Out_Of_Core);
ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
ctx->verbosity = 1;
ctx->include_certs = 1;
*r_ctx = ctx;
return 0;
}
/**
* gpgme_release:
* @c: Context to be released.
*
* Release all resources associated with the given context.
**/
void
gpgme_release (GpgmeCtx ctx)
{
if (!ctx)
return;
_gpgme_engine_release (ctx->engine);
_gpgme_release_result (ctx);
gpgme_key_release (ctx->tmp_key);
gpgme_data_release (ctx->help_data_1);
gpgme_data_release (ctx->notation);
gpgme_signers_clear (ctx);
if (ctx->signers)
xfree (ctx->signers);
/* FIXME: Release the key_queue. */
xfree (ctx);
}
void
_gpgme_release_result (GpgmeCtx ctx)
{
_gpgme_release_verify_result (ctx->result.verify);
_gpgme_release_decrypt_result (ctx->result.decrypt);
_gpgme_release_sign_result (ctx->result.sign);
_gpgme_release_encrypt_result (ctx->result.encrypt);
_gpgme_release_passphrase_result (ctx->result.passphrase);
_gpgme_release_import_result (ctx->result.import);
_gpgme_release_delete_result (ctx->result.delete);
_gpgme_release_genkey_result (ctx->result.genkey);
memset (&ctx->result, 0, sizeof (ctx->result));
_gpgme_set_op_info (ctx, NULL);
ctx->error = 0;
}
/**
* gpgme_cancel:
* @c: the context
*
* Cancel the current operation. It is not guaranteed that it will work for
* all kinds of operations. It is especially useful in a passphrase callback
* to stop the system from asking another time for the passphrase.
**/
void
gpgme_cancel (GpgmeCtx ctx)
{
return_if_fail (ctx);
ctx->cancel = 1;
}
/**
* gpgme_get_notation:
* @c: the context
*
* If there is notation data available from the last signature check,
* this function may be used to return this notation data as a string.
* The string is an XML represantaton of that data embedded in a
* %&lt;notation&gt; container.
*
* Return value: An XML string or NULL if no notation data is available.
**/
char *
gpgme_get_notation (GpgmeCtx ctx)
{
if (!ctx->notation)
return NULL;
return _gpgme_data_get_as_string (ctx->notation);
}
/**
* gpgme_get_op_info:
* @c: the context
* @reserved:
*
* Return information about the last operation. The caller has to
* free the string. NULL is returned if there is not previous
* operation available or the operation has not yet finished.
*
* Here is a sample information we return:
* <literal>
* <![CDATA[
* <GnupgOperationInfo>
* <signature>
* <detached/> <!-- or cleartext or standard -->
* <algo>17</algo>
* <hashalgo>2</hashalgo>
* <micalg>pgp-sha1</micalg>
* <sigclass>01</sigclass>
* <created>9222222</created>
* <fpr>121212121212121212</fpr>
* </signature>
* </GnupgOperationInfo>
* ]]>
* </literal>
* Return value: NULL for no info available or an XML string
**/
char *
gpgme_get_op_info (GpgmeCtx ctx, int reserved)
{
if (!ctx || reserved)
return NULL; /* Invalid value. */
return _gpgme_data_get_as_string (ctx->op_info);
}
/*
* Store the data object with the operation info in the
* context. Caller should not use that object anymore.
*/
void
_gpgme_set_op_info (GpgmeCtx ctx, GpgmeData info)
{
assert (ctx);
gpgme_data_release (ctx->op_info);
ctx->op_info = NULL;
if (info)
ctx->op_info = info;
}
GpgmeError
gpgme_set_protocol (GpgmeCtx ctx, GpgmeProtocol protocol)
{
if (!ctx)
return mk_error (Invalid_Value);
switch (protocol)
{
case GPGME_PROTOCOL_OpenPGP:
ctx->use_cms = 0;
break;
case GPGME_PROTOCOL_CMS:
ctx->use_cms = 1;
break;
case GPGME_PROTOCOL_AUTO:
return mk_error (Not_Implemented);
default:
return mk_error (Invalid_Value);
}
return 0;
}
GpgmeProtocol
gpgme_get_protocol (GpgmeCtx ctx)
{
if (!ctx)
return 0; /* well, this is OpenPGP */
if (ctx->use_cms)
return GPGME_PROTOCOL_CMS;
return GPGME_PROTOCOL_OpenPGP;
}
/**
* gpgme_set_armor:
* @ctx: the context
* @yes: boolean value to set or clear that flag
*
* Enable or disable the use of an ascii armor for all output.
**/
void
gpgme_set_armor (GpgmeCtx ctx, int yes)
{
if (!ctx)
return;
ctx->use_armor = yes;
}
/**
* gpgme_get_armor:
* @ctx: the context
*
* Return the state of the armor flag which can be changed using
* gpgme_set_armor().
*
* Return value: Boolean whether armor mode is to be used.
**/
int
gpgme_get_armor (GpgmeCtx ctx)
{
return ctx && ctx->use_armor;
}
/**
* gpgme_set_textmode:
* @ctx: the context
* @yes: boolean flag whether textmode should be enabled
*
* 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 (GpgmeCtx ctx, int yes)
{
if (!ctx)
return;
ctx->use_textmode = yes;
}
/**
* gpgme_get_textmode:
* @ctx: the context
*
* Return the state of the textmode flag which can be changed using
* gpgme_set_textmode().
*
* Return value: Boolean whether textmode is to be used.
**/
int
gpgme_get_textmode (GpgmeCtx ctx)
{
return ctx && ctx->use_textmode;
}
/**
* gpgme_set_include_certs:
* @ctx: the context
*
* Set the number of certifications to include in an S/MIME message.
* The default is 1 (only the cert of the sender). -1 means all certs,
* and -2 means all certs except the root cert.
*
* Return value: Boolean whether textmode is to be used.
**/
void
gpgme_set_include_certs (GpgmeCtx ctx, int nr_of_certs)
{
if (nr_of_certs < -2)
ctx->include_certs = -2;
else
ctx->include_certs = nr_of_certs;
}
/**
* gpgme_get_include_certs:
* @ctx: the context
*
* Get the number of certifications to include in an S/MIME message.
*
* Return value: Boolean whether textmode is to be used.
**/
int
gpgme_get_include_certs (GpgmeCtx ctx)
{
return ctx->include_certs;
}
/**
* gpgme_set_keylist_mode:
* @ctx: the context
* @mode: listing mode
*
* 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.
*
* Return value: GPGME_Invalid_Value if ctx is not a context or mode
* not a valid mode.
**/
GpgmeError
gpgme_set_keylist_mode (GpgmeCtx ctx, int mode)
{
if (!ctx)
return mk_error (Invalid_Value);
if (!((mode & GPGME_KEYLIST_MODE_LOCAL)
|| (mode & GPGME_KEYLIST_MODE_EXTERN)))
return mk_error (Invalid_Value);
ctx->keylist_mode = mode;
return 0;
}
/**
* gpgme_get_keylist_mode:
* @ctx: the context
*
* This function ch the default behaviour of the keylisting functions.
* Defines values for @mode are: %0 = normal, %1 = fast listing without
* information about key validity.
*
* Return value: 0 if ctx is not a valid context, or the current mode.
* Note that 0 is never a valid mode.
**/
int
gpgme_get_keylist_mode (GpgmeCtx ctx)
{
if (!ctx)
return 0;
return ctx->keylist_mode;
}
/**
* gpgme_set_passphrase_cb:
* @ctx: the context
* @cb: A callback function
* @cb_value: The value passed to the callback function
*
* This function sets a callback function to be used to pass a passphrase
* to gpg. The preferred way to handle this is by using the gpg-agent, but
* because that beast is not ready for real use, you can use this passphrase
* thing.
*
* The callback function is defined as:
* <literal>
* typedef const char *(*GpgmePassphraseCb)(void*cb_value,
* const char *desc,
* void **r_hd);
* </literal>
* and called whenever gpgme needs a passphrase. DESC will have a nice
* text, to be used to prompt for the passphrase and R_HD is just a parameter
* to be used by the callback it self. Because the callback returns a const
* string, the callback might want to know when it can release resources
* assocated with that returned string; gpgme helps here by calling this
* passphrase callback with an DESC of %NULL as soon as it does not need
* the returned string anymore. The callback function might then choose
* to release resources depending on R_HD.
*
**/
void
gpgme_set_passphrase_cb (GpgmeCtx ctx, GpgmePassphraseCb cb, void *cb_value)
{
if (ctx)
{
ctx->passphrase_cb = cb;
ctx->passphrase_cb_value = cb_value;
}
}
/**
* gpgme_get_passphrase_cb:
* @ctx: the context
* @r_cb: The current callback function
* @r_cb_value: The current value passed to the callback function
*
* This function returns the callback function to be used to pass a passphrase
* to the crypto engine.
**/
void
gpgme_get_passphrase_cb (GpgmeCtx ctx, GpgmePassphraseCb *r_cb, void **r_cb_value)
{
if (ctx)
{
if (r_cb)
*r_cb = ctx->passphrase_cb;
if (r_cb_value)
*r_cb_value = ctx->passphrase_cb_value;
}
else
{
if (r_cb)
*r_cb = NULL;
if (r_cb_value)
*r_cb_value = NULL;
}
}
/**
* gpgme_set_progress_cb:
* @ctx: the context
* @cb: A callback function
* @cb_value: The value passed to the callback function
*
* This function sets a callback function to be used as a progress indicator.
*
* The callback function is defined as:
* <literal>
* typedef void (*GpgmeProgressCb) (void *cb_value,
* const char *what, int type,
* int curretn, int total);
* </literal>
* For details on the progress events, see the entry for the PROGRESS
* status in the file doc/DETAILS of the GnuPG distribution.
**/
void
gpgme_set_progress_cb (GpgmeCtx ctx, GpgmeProgressCb cb, void *cb_value)
{
if (ctx)
{
ctx->progress_cb = cb;
ctx->progress_cb_value = cb_value;
}
}
/**
* gpgme_get_progress_cb:
* @ctx: the context
* @r_cb: The current callback function
* @r_cb_value: The current value passed to the callback function
*
* This function returns the callback function to be used as a progress indicator.
**/
void
gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *r_cb, void **r_cb_value)
{
if (ctx)
{
if (r_cb)
*r_cb = ctx->progress_cb;
if (r_cb_value)
*r_cb_value = ctx->progress_cb_value;
}
else
{
if (r_cb)
*r_cb = NULL;
if (r_cb_value)
*r_cb_value = NULL;
}
}

View File

@ -0,0 +1,601 @@
/* gpgme.h - GnuPG Made Easy
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef GPGME_H
#define GPGME_H
#include <stdio.h> /* For FILE *. */
#ifdef _MSC_VER
typedef long off_t;
#else
# include <sys/types.h>
#endif
#ifdef __cplusplus
extern "C" {
#if 0 /* just to make Emacs auto-indent happy */
}
#endif
#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 "0.3.7-cvs"
/* The 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_s;
typedef struct gpgme_context_s *GpgmeCtx;
/* The data object used by GPGME to exchange arbitrary data. */
struct gpgme_data_s;
typedef struct gpgme_data_s *GpgmeData;
/* A list of recipients to be used in an encryption operation. */
struct gpgme_recipients_s;
typedef struct gpgme_recipients_s *GpgmeRecipients;
/* A key from the keyring. */
struct gpgme_key_s;
typedef struct gpgme_key_s *GpgmeKey;
/* A trust item. */
struct gpgme_trust_item_s;
typedef struct gpgme_trust_item_s *GpgmeTrustItem;
/* The error numbers used by GPGME. */
typedef enum
{
GPGME_EOF = -1,
GPGME_No_Error = 0,
GPGME_General_Error = 1,
GPGME_Out_Of_Core = 2,
GPGME_Invalid_Value = 3,
GPGME_Busy = 4,
GPGME_No_Request = 5,
GPGME_Exec_Error = 6,
GPGME_Too_Many_Procs = 7,
GPGME_Pipe_Error = 8,
GPGME_No_Recipients = 9,
GPGME_No_Data = 10,
GPGME_Conflict = 11,
GPGME_Not_Implemented = 12,
GPGME_Read_Error = 13,
GPGME_Write_Error = 14,
GPGME_Invalid_Type = 15,
GPGME_Invalid_Mode = 16,
GPGME_File_Error = 17, /* errno is set in this case. */
GPGME_Decryption_Failed = 18,
GPGME_No_Passphrase = 19,
GPGME_Canceled = 20,
GPGME_Invalid_Key = 21,
GPGME_Invalid_Engine = 22,
GPGME_Invalid_Recipients = 23
}
GpgmeError;
/* The possible types of GpgmeData objects. */
typedef enum
{
GPGME_DATA_TYPE_NONE = 0,
GPGME_DATA_TYPE_MEM = 1,
GPGME_DATA_TYPE_FD = 2,
GPGME_DATA_TYPE_FILE = 3,
GPGME_DATA_TYPE_CB = 4
}
GpgmeDataType;
/* The possible encoding mode of GpgmeData objects. */
typedef enum
{
GPGME_DATA_ENCODING_NONE = 0, /* i.e. not specified */
GPGME_DATA_ENCODING_BINARY = 1,
GPGME_DATA_ENCODING_BASE64 = 2,
GPGME_DATA_ENCODING_ARMOR = 3 /* Either PEM or OpenPGP Armor */
}
GpgmeDataEncoding;
/* The possible signature stati. */
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
}
GpgmeSigStat;
/* The available signature modes. */
typedef enum
{
GPGME_SIG_MODE_NORMAL = 0,
GPGME_SIG_MODE_DETACH = 1,
GPGME_SIG_MODE_CLEAR = 2
}
GpgmeSigMode;
/* The available key and signature attributes. */
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
}
GpgmeAttr;
/* 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
}
GpgmeValidity;
/* The available protocols. */
typedef enum
{
GPGME_PROTOCOL_OpenPGP = 0, /* The default mode. */
GPGME_PROTOCOL_CMS = 1,
GPGME_PROTOCOL_AUTO = 2
}
GpgmeProtocol;
/* The available keylist mode flags. */
#define GPGME_KEYLIST_MODE_LOCAL 1
#define GPGME_KEYLIST_MODE_EXTERN 2
/* Types for callback functions. */
/* Request a passphrase from the user. */
typedef const char *(*GpgmePassphraseCb) (void *hook, const char *desc,
void **r_hd);
/* Inform the user about progress made. */
typedef void (*GpgmeProgressCb) (void *opaque, const char *what,
int type, int current, int total);
/* Context management functions. */
/* Create a new context and return it in CTX. */
GpgmeError gpgme_new (GpgmeCtx *ctx);
/* Release the context CTX. */
void gpgme_release (GpgmeCtx ctx);
/* Retrieve more info about performed signature check. */
char *gpgme_get_notation (GpgmeCtx ctx);
/* Set the protocol to be used by CTX to PROTO. */
GpgmeError gpgme_set_protocol (GpgmeCtx ctx, GpgmeProtocol proto);
/* Get the protocol used with CTX */
GpgmeProtocol gpgme_get_protocol (GpgmeCtx ctx);
/* If YES is non-zero, enable armor mode in CTX, disable it otherwise. */
void gpgme_set_armor (GpgmeCtx ctx, int yes);
/* Return non-zero if armor mode is set in CTX. */
int gpgme_get_armor (GpgmeCtx ctx);
/* If YES is non-zero, enable text mode in CTX, disable it otherwise. */
void gpgme_set_textmode (GpgmeCtx ctx, int yes);
/* Return non-zero if text mode is set in CTX. */
int gpgme_get_textmode (GpgmeCtx ctx);
/* Include up to NR_OF_CERTS certificates in an S/MIME message. */
void gpgme_set_include_certs (GpgmeCtx ctx, int nr_of_certs);
/* Return the number of certs to include in an S/MIME message. */
int gpgme_get_include_certs (GpgmeCtx ctx);
/* Set keylist mode in CTX to MODE. */
GpgmeError gpgme_set_keylist_mode (GpgmeCtx ctx, int mode);
/* Get keylist mode in CTX. */
int gpgme_get_keylist_mode (GpgmeCtx 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 (GpgmeCtx ctx,
GpgmePassphraseCb 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 (GpgmeCtx ctx, GpgmePassphraseCb *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 (GpgmeCtx c, GpgmeProgressCb 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 (GpgmeCtx ctx, GpgmeProgressCb *cb,
void **hook_value);
/* Delete all signers from CTX. */
void gpgme_signers_clear (GpgmeCtx ctx);
/* Add KEY to list of signers in CTX. */
GpgmeError gpgme_signers_add (GpgmeCtx ctx, const GpgmeKey key);
/* Return the SEQth signer's key in CTX. */
GpgmeKey gpgme_signers_enum (const GpgmeCtx 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. */
const char *gpgme_get_sig_status (GpgmeCtx ctx, int idx,
GpgmeSigStat *r_stat, time_t *r_created);
/* 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. RESERVED must be passed as 0. */
unsigned long gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx,
GpgmeAttr what, int reserved);
const char *gpgme_get_sig_string_attr (GpgmeCtx c, int idx,
GpgmeAttr what, int reserved);
/* Get the key used to create signature IDX in CTX and return it in
R_KEY. */
GpgmeError gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key);
/* Return a string with more info about the last crypto operating in CTX.
RESERVED should be zero. The user has to free the string. */
char *gpgme_get_op_info (GpgmeCtx ctx, int reserved);
/* Run control. */
/* Cancel a pending operation in CTX. */
void gpgme_cancel (GpgmeCtx ctx);
/* Process the pending operation and, if HANG is non-zero, wait for
the pending operation to finish. */
GpgmeCtx gpgme_wait (GpgmeCtx ctx, GpgmeError *status, int hang);
/* Functions to handle recipients. */
/* Create a new recipients set and return it in R_RSET. */
GpgmeError gpgme_recipients_new (GpgmeRecipients *r_rset);
/* Release the recipients set RSET. */
void gpgme_recipients_release (GpgmeRecipients rset);
/* Add NAME to the recipients set RSET. */
GpgmeError gpgme_recipients_add_name (GpgmeRecipients rset, const char *name);
/* Add NAME with validity AL to the recipients set RSET. */
GpgmeError gpgme_recipients_add_name_with_validity (GpgmeRecipients rset,
const char *name,
GpgmeValidity val);
/* Return the number of recipients in RSET. */
unsigned int gpgme_recipients_count (const GpgmeRecipients rset);
/* Create a new enumeration handle for the recipients set RSET and
return it in ITER. */
GpgmeError gpgme_recipients_enum_open (const GpgmeRecipients rset,
void **iter);
/* Return the next recipient from the recipient set RSET in the
enumerator ITER. */
const char *gpgme_recipients_enum_read (const GpgmeRecipients rset,
void **iter);
/* Destroy the enumerator ITER for the recipient set RSET. */
GpgmeError gpgme_recipients_enum_close (const GpgmeRecipients rset,
void **iter);
/* Functions to handle data objects. */
/* Create a new data buffer and return it in R_DH. */
GpgmeError gpgme_data_new (GpgmeData *r_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. */
GpgmeError gpgme_data_new_from_mem (GpgmeData *r_dh,
const char *buffer, size_t size,
int copy);
/* Create a new data buffer which retrieves the data from the callback
function READ_CB. */
GpgmeError gpgme_data_new_with_read_cb (GpgmeData *r_dh,
int (*read_cb) (void*,char *,size_t,size_t*),
void *read_cb_value);
/* Create a new data buffer filled with the content of file FNAME.
COPY must be non-zero (delayed reads are not supported yet). */
GpgmeError gpgme_data_new_from_file (GpgmeData *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). */
GpgmeError gpgme_data_new_from_filepart (GpgmeData *r_dh,
const char *fname, FILE *fp,
off_t offset, size_t length);
/* Destroy the data buffer DH. */
void gpgme_data_release (GpgmeData dh);
/* Destroy the data buffer DH and return a pointer to its content.
The memory has be to released with free by the user. It's size is
returned in R_LEN. */
char *gpgme_data_release_and_get_mem (GpgmeData dh, size_t *r_len);
/* Return the type of the data buffer DH. */
GpgmeDataType gpgme_data_get_type (GpgmeData dh);
/* Return the encoding attribute of the data buffer DH */
GpgmeDataEncoding gpgme_data_get_encoding (GpgmeData dh);
/* Set the encoding attribute of data buffer DH to ENC */
GpgmeError gpgme_data_set_encoding (GpgmeData dh, GpgmeDataEncoding enc);
/* Reset the read pointer in DH. */
GpgmeError gpgme_data_rewind (GpgmeData dh);
/* Read LENGTH bytes from the data object DH and store them in the
memory starting at BUFFER. The number of bytes actually read is
returned in NREAD. */
GpgmeError gpgme_data_read (GpgmeData dh, void *buffer,
size_t length, size_t *nread);
/* Write LENGTH bytes starting from BUFFER into the data object DH. */
GpgmeError gpgme_data_write (GpgmeData dh, const void *buffer, size_t length);
/* Key and trust functions. */
/* Acquire a reference to KEY. */
void gpgme_key_ref (GpgmeKey key);
/* Release a reference to KEY. If this was the last one the key is
destroyed. */
void gpgme_key_unref (GpgmeKey key);
void gpgme_key_release (GpgmeKey key);
/* Get the data from key KEY in a XML string, which has to be released
with free by the user. */
char *gpgme_key_get_as_xml (GpgmeKey key);
/* Return the value of the attribute WHAT of KEY, which has to be
representable by a string. IDX specifies a running index if the
attribute appears more than once in the key. */
const char *gpgme_key_get_string_attr (GpgmeKey key, GpgmeAttr what,
const void *reserved, int idx);
/* Return the value of the attribute WHAT of KEY, which has to be
representable by an unsigned integer. IDX specifies a running
index if the attribute appears more than once in the key. */
unsigned long gpgme_key_get_ulong_attr (GpgmeKey key, GpgmeAttr what,
const void *reserved, int idx);
/* Release the trust item ITEM. */
void gpgme_trust_item_release (GpgmeTrustItem item);
/* Return the value of the attribute WHAT of ITEM, which has to be
representable by a string. IDX specifies a running index if the
attribute appears more than once in the key. */
const char *gpgme_trust_item_get_string_attr (GpgmeTrustItem item,
GpgmeAttr what,
const void *reserved, int idx);
/* 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 (GpgmeTrustItem item, GpgmeAttr what,
const void *reserved, int idx);
/* Crypto operation function. */
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
store the resulting ciphertext in CIPHER. */
GpgmeError gpgme_op_encrypt_start (GpgmeCtx ctx,
GpgmeRecipients recp,
GpgmeData plain, GpgmeData cipher);
GpgmeError gpgme_op_encrypt (GpgmeCtx ctx,
GpgmeRecipients recp,
GpgmeData plain, GpgmeData 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. */
GpgmeError gpgme_op_encrypt_sign_start (GpgmeCtx ctx,
GpgmeRecipients recp,
GpgmeData plain, GpgmeData cipher);
GpgmeError gpgme_op_encrypt_sign (GpgmeCtx ctx,
GpgmeRecipients recp,
GpgmeData plain, GpgmeData cipher);
/* Decrypt ciphertext CIPHER within CTX and store the resulting
plaintext in PLAIN. */
GpgmeError gpgme_op_decrypt_start (GpgmeCtx ctx,
GpgmeData cipher, GpgmeData plain);
GpgmeError gpgme_op_decrypt (GpgmeCtx ctx,
GpgmeData cipher, GpgmeData plain);
/* Decrypt ciphertext CIPHER and make a signature verification within
CTX and store the resulting plaintext in PLAIN. */
GpgmeError gpgme_op_decrypt_verify_start (GpgmeCtx ctx,
GpgmeData cipher, GpgmeData plain);
GpgmeError gpgme_op_decrypt_verify (GpgmeCtx ctx,
GpgmeData cipher, GpgmeData plain,
GpgmeSigStat *r_status);
/* Sign the plaintext PLAIN and store the signature in SIG. Only
detached signatures are supported for now. */
GpgmeError gpgme_op_sign_start (GpgmeCtx ctx,
GpgmeData plain, GpgmeData sig,
GpgmeSigMode mode);
GpgmeError gpgme_op_sign (GpgmeCtx ctx,
GpgmeData plain, GpgmeData sig,
GpgmeSigMode mode);
/* Verify within CTX that SIG is a valid signature for TEXT. */
GpgmeError gpgme_op_verify_start (GpgmeCtx ctx,
GpgmeData sig, GpgmeData text);
GpgmeError gpgme_op_verify (GpgmeCtx ctx,
GpgmeData sig, GpgmeData text,
GpgmeSigStat *r_status);
/* Import the key in KEYDATA into the keyring. */
GpgmeError gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata);
GpgmeError gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata);
/* Export the keys listed in RECP into KEYDATA. */
GpgmeError gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp,
GpgmeData keydata);
GpgmeError gpgme_op_export (GpgmeCtx ctx, GpgmeRecipients recp,
GpgmeData keydata);
/* 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. */
GpgmeError gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms,
GpgmeData pubkey, GpgmeData seckey);
GpgmeError gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
GpgmeData pubkey, GpgmeData seckey);
/* Delete KEY from the keyring. If ALLOW_SECRET is non-zero, secret
keys are also deleted. */
GpgmeError gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key,
int allow_secret);
GpgmeError gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key,
int allow_secret);
/* Key management functions */
/* Start a keylist operation within CTX, searching for keys which
match PATTERN. If SECRET_ONLY is true, only secret keys are
returned. */
GpgmeError gpgme_op_keylist_start (GpgmeCtx ctx,
const char *pattern, int secret_only);
GpgmeError gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
int secret_only, int reserved);
/* Return the next key from the keylist in R_KEY. */
GpgmeError gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key);
/* Terminate a pending keylist operation within CTX. */
GpgmeError gpgme_op_keylist_end (GpgmeCtx ctx);
/* Start a trustlist operation within CTX, searching for trust items
which match PATTERN. */
GpgmeError gpgme_op_trustlist_start (GpgmeCtx ctx,
const char *pattern, int max_level);
/* Return the next trust item from the trustlist in R_ITEM. */
GpgmeError gpgme_op_trustlist_next (GpgmeCtx ctx, GpgmeTrustItem *r_item);
/* Terminate a pending trustlist operation within CTX. */
GpgmeError gpgme_op_trustlist_end (GpgmeCtx ctx);
/* Various functions. */
/* Check that the library fulfills the version requirement. */
const char *gpgme_check_version (const char *req_version);
/* Check that the backend engine is available. DEPRECATED. */
GpgmeError gpgme_check_engine (void);
/* Retrieve information about the backend engines. */
const char *gpgme_get_engine_info (void);
/* Return a string describing ERR. */
const char *gpgme_strerror (GpgmeError err);
/* Register an idle function. */
typedef void (*GpgmeIdleFunc)(void);
GpgmeIdleFunc gpgme_register_idle (GpgmeIdleFunc idle);
/* Engine support functions. */
/* Verify that the engine implementing PROTO is installed and
available. */
GpgmeError gpgme_engine_check_version (GpgmeProtocol proto);
#ifdef __cplusplus
}
#endif
#endif /* GPGME_H */

View File

@ -0,0 +1,170 @@
dnl Autoconf macros for libgpgme
dnl $Id$
# Configure paths for GPGME
# Shamelessly stolen from the one of XDELTA by Owen Taylor
# Werner Koch 2000-11-17
dnl AM_PATH_GPGME([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for gpgme, and define GPGME_CFLAGS and GPGME_LIBS
dnl
AC_DEFUN(AM_PATH_GPGME,
[dnl
dnl Get the cflags and libraries from the gpgme-config script
dnl
AC_ARG_WITH(gpgme-prefix,
[ --with-gpgme-prefix=PFX Prefix where gpgme is installed (optional)],
gpgme_config_prefix="$withval", gpgme_config_prefix="")
AC_ARG_ENABLE(gpgmetest,
[ --disable-gpgmetest Do not try to compile and run a test gpgme program],
, enable_gpgmetest=yes)
if test x$gpgme_config_prefix != x ; then
gpgme_config_args="$gpgme_config_args --prefix=$gpgme_config_prefix"
if test x${GPGME_CONFIG+set} != xset ; then
GPGME_CONFIG=$gpgme_config_prefix/bin/gpgme-config
fi
fi
AC_PATH_PROG(GPGME_CONFIG, gpgme-config, no)
min_gpgme_version=ifelse([$1], ,1.0.0,$1)
AC_MSG_CHECKING(for GPGME - version >= $min_gpgme_version)
no_gpgme=""
if test "$GPGME_CONFIG" = "no" ; then
no_gpgme=yes
else
GPGME_CFLAGS=`$GPGME_CONFIG $gpgme_config_args --cflags`
GPGME_LIBS=`$GPGME_CONFIG $gpgme_config_args --libs`
gpgme_config_version=`$GPGME_CONFIG $gpgme_config_args --version`
if test "x$enable_gpgmetest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GPGME_CFLAGS"
LIBS="$LIBS $GPGME_LIBS"
dnl
dnl Now check if the installed gpgme is sufficiently new. Also sanity
dnl checks the results of gpgme-config to some extent
dnl
rm -f conf.gpgmetest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gpgme.h>
int
main ()
{
system ("touch conf.gpgmetest");
if( strcmp( gpgme_check_version(NULL), "$gpgme_config_version" ) )
{
printf("\n"
"*** 'gpgme-config --version' returned %s, but GPGME (%s) was found!\n",
"$gpgme_config_version", gpgme_check_version(NULL) );
printf(
"*** If gpgme-config was correct, then it is best to remove the old\n"
"*** version of GPGME. You may also be able to fix the error\n"
"*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"
"*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"
"*** required on your system.\n"
"*** If gpgme-config was wrong, set the environment variable GPGME_CONFIG\n"
"*** to point to the correct copy of gpgme-config, \n"
"*** and remove the file config.cache before re-running configure\n"
);
}
else if ( strcmp(gpgme_check_version(NULL), GPGME_VERSION ) )
{
printf("\n*** GPGME header file (version %s) does not match\n",
GPGME_VERSION);
printf("*** library (version %s)\n", gpgme_check_version(NULL) );
}
else
{
if ( gpgme_check_version( "$min_gpgme_version" ) )
return 0;
printf("no\n"
"*** An old version of GPGME (%s) was found.\n", gpgme_check_version(NULL) );
printf(
"*** You need a version of GPGME newer than %s.\n", "$min_gpgme_version" );
printf(
"*** The latest version of GPGME is always available at\n"
"*** ftp://ftp.gnupg.org/pub/gcrypt/alpha/gpgme/\n"
"*** \n"
"*** If you have already installed a sufficiently new version, this error\n"
"*** probably means that the wrong copy of the gpgme-config shell script is\n"
"*** being found. The easiest way to fix this is to remove the old version\n"
"*** of GPGME, but you can also set the GPGME_CONFIG environment to point to\n"
"*** the correct copy of gpgme-config. (In this case, you will have to\n"
"*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"
"*** so that the correct libraries are found at run-time).\n"
);
}
return 1;
}
],, no_gpgme=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_gpgme" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
if test -f conf.gpgmetest ; then
:
else
AC_MSG_RESULT(no)
fi
if test "$GPGME_CONFIG" = "no" ; then
echo "*** The gpgme-config script installed by GPGME could not be found"
echo "*** If GPGME was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the GPGME_CONFIG environment variable to the"
echo "*** full path to gpgme-config."
else
if test -f conf.gpgmetest ; then
:
else
echo "*** Could not run gpgme test program, checking why..."
CFLAGS="$CFLAGS $GPGME_CFLAGS"
LIBS="$LIBS $GPGME_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gpgme.h>
], [ gpgme_check_version(NULL); return 0 ],
[
echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding GPGME or finding the wrong"
echo "*** version of GPGME. If it is not finding GPGME, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if"
echo "*** that is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it,"
echo "*** although you may also be able to get things to work by"
echo "*** modifying LD_LIBRARY_PATH"
echo "***"
],
[
echo "*** The test program failed to compile or link. See the file config.log"
echo "*** for the exact error that occured. This usually means GPGME was"
echo "*** incorrectly installed or that you have moved GPGME since it was"
echo "*** installed. In the latter case, you may want to edit the"
echo "*** gpgme-config script: $GPGME_CONFIG"
])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
GPGME_CFLAGS=""
GPGME_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(GPGME_CFLAGS)
AC_SUBST(GPGME_LIBS)
rm -f conf.gpgmetest
])

View File

@ -0,0 +1,223 @@
/* import.c - encrypt functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct import_result_s
{
GpgmeData xmlinfo;
};
void
_gpgme_release_import_result (ImportResult result)
{
if (!result)
return;
gpgme_data_release (result->xmlinfo);
xfree (result);
}
/* Parse the args and append the information to the XML structure in
the data buffer. With args of NULL the xml structure is
closed. */
static void
append_xml_impinfo (GpgmeData *rdh, GpgStatusCode code, char *args)
{
#define MAX_IMPORTED_FIELDS 14
static const char *const imported_fields[MAX_IMPORTED_FIELDS]
= { "keyid", "username", 0 };
static const char *const import_res_fields[MAX_IMPORTED_FIELDS]
= { "count", "no_user_id", "imported", "imported_rsa",
"unchanged", "n_uids", "n_subk", "n_sigs", "s_sigsn_revoc",
"sec_read", "sec_imported", "sec_dups", "skipped_new", 0 };
const char *field[MAX_IMPORTED_FIELDS];
const char *const *field_name = 0;
GpgmeData dh;
int i;
/* Verify that we can use the args. */
if (code != STATUS_EOF)
{
if (!args)
return;
if (code == STATUS_IMPORTED)
field_name = imported_fields;
else if (code == STATUS_IMPORT_RES)
field_name = import_res_fields;
else
return;
for (i = 0; field_name[i]; i++)
{
field[i] = args;
if (field_name[i + 1])
{
args = strchr (args, ' ');
if (!args)
return; /* Invalid line. */
*args++ = '\0';
}
}
}
/* Initialize the data buffer if necessary. */
if (!*rdh)
{
if (gpgme_data_new (rdh))
return; /* FIXME: We are ignoring out-of-core. */
dh = *rdh;
_gpgme_data_append_string (dh, "<GnupgOperationInfo>\n");
}
else
dh = *rdh;
if (code == STATUS_EOF)
{
/* Just close the XML containter. */
_gpgme_data_append_string (dh, "</GnupgOperationInfo>\n");
}
else
{
if (code == STATUS_IMPORTED)
_gpgme_data_append_string (dh, " <import>\n");
else if (code == STATUS_IMPORT_RES)
_gpgme_data_append_string (dh, " <importResult>\n");
for (i = 0; field_name[i]; i++)
{
_gpgme_data_append_string (dh, " <");
_gpgme_data_append_string (dh, field_name[i]);
_gpgme_data_append_string (dh, ">");
_gpgme_data_append_string (dh, field[i]);
_gpgme_data_append_string (dh, "</");
_gpgme_data_append_string (dh, field_name[i]);
_gpgme_data_append_string (dh, ">\n");
}
if (code == STATUS_IMPORTED)
_gpgme_data_append_string (dh, " </import>\n");
else if (code == STATUS_IMPORT_RES)
_gpgme_data_append_string (dh, " </importResult>\n");
}
}
static void
import_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
if (ctx->error)
return;
test_and_allocate_result (ctx, import);
switch (code)
{
case STATUS_EOF:
if (ctx->result.import->xmlinfo)
{
append_xml_impinfo (&ctx->result.import->xmlinfo, code, NULL);
_gpgme_set_op_info (ctx, ctx->result.import->xmlinfo);
ctx->result.import->xmlinfo = NULL;
}
/* XXX Calculate error value. */
break;
case STATUS_IMPORTED:
case STATUS_IMPORT_RES:
append_xml_impinfo (&ctx->result.import->xmlinfo, code, args);
break;
default:
break;
}
}
GpgmeError
gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata)
{
int err = 0;
fail_on_pending_request (ctx);
ctx->pending = 1;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
/* Check the supplied data */
if (gpgme_data_get_type (keydata) == GPGME_DATA_TYPE_NONE)
{
err = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (keydata, GPGME_DATA_MODE_OUT);
_gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
_gpgme_engine_op_import (ctx->engine, keydata);
if (!err)
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_import:
* @c: Context
* @keydata: Data object
*
* Import all key material from @keydata into the key database.
*
* Return value: o on success or an error code.
**/
GpgmeError
gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata)
{
GpgmeError err = gpgme_op_import_start (ctx, keydata);
if (!err)
gpgme_wait (ctx, &err, 1);
return err;
}

View File

@ -0,0 +1,71 @@
/* io.h - I/O functions
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef IO_H
#define IO_H
#include "types.h"
struct spawn_fd_item_s {
int fd;
int dup_to;
};
struct io_select_fd_s {
int fd;
int is_closed;
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 */
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 );
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);
#endif /* IO_H */

1118
tags/gpgme-0-3-7/gpgme/key.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,86 @@
/* key.h
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef KEY_H
#define KEY_H
#include <time.h>
#include "types.h"
#include "context.h"
struct subkey_s {
struct subkey_s *next;
unsigned int secret:1;
struct {
unsigned int revoked:1 ;
unsigned int expired:1 ;
unsigned int disabled:1 ;
unsigned int invalid:1 ;
unsigned int can_encrypt:1;
unsigned int can_sign:1;
unsigned int can_certify:1;
} flags;
unsigned int key_algo;
unsigned int key_len;
char keyid[16+1];
char *fingerprint; /* malloced hex digits */
time_t timestamp; /* -1 for invalid, 0 for not available */
time_t expires_at; /* 0 for does not expires */
};
struct gpgme_key_s {
struct {
unsigned int revoked:1 ;
unsigned int expired:1 ;
unsigned int disabled:1 ;
unsigned int invalid:1 ;
unsigned int can_encrypt:1;
unsigned int can_sign:1;
unsigned int can_certify:1;
} gloflags;
unsigned int ref_count;
unsigned int secret:1;
unsigned int x509:1;
char *issuer_serial; /* malloced string used only with X.509 */
char *issuer_name; /* ditto */
char *chain_id; /* ditto */
GpgmeValidity otrust; /* only used with OpenPGP */
struct subkey_s keys;
struct user_id_s *uids;
};
void _gpgme_key_cache_init (void);
void _gpgme_key_cache_add (GpgmeKey key);
GpgmeKey _gpgme_key_cache_get (const char *fpr);
struct subkey_s *_gpgme_key_add_subkey (GpgmeKey key);
struct subkey_s *_gpgme_key_add_secret_subkey (GpgmeKey key);
GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s );
#endif /* KEY_H */

View File

@ -0,0 +1,683 @@
/* keylist.c - key listing
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
#include "key.h"
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
static void finish_key ( GpgmeCtx ctx );
static void
keylist_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
if (ctx->error)
return;
switch (code)
{
case STATUS_EOF:
finish_key (ctx);
break;
default:
/* Ignore all other codes. */
break;
}
}
static time_t
parse_timestamp (char *p)
{
if (!*p)
return 0;
return (time_t)strtoul (p, NULL, 10);
}
static void
set_mainkey_trust_info (GpgmeKey key, const char *s)
{
/* Look at letters and stop at the first digit. */
for (; *s && !my_isdigit (*s); s++)
{
switch (*s)
{
case 'e': key->keys.flags.expired = 1; break;
case 'r': key->keys.flags.revoked = 1; break;
case 'd': key->keys.flags.disabled = 1; break;
case 'i': key->keys.flags.invalid = 1; break;
}
}
}
static void
set_userid_flags (GpgmeKey key, const char *s)
{
/* Look at letters and stop at the first digit. */
for (; *s && !my_isdigit (*s); s++)
{
switch (*s)
{
case 'r': key->uids->revoked = 1; break;
case 'i': key->uids->invalid = 1; break;
case 'n': key->uids->validity = GPGME_VALIDITY_NEVER; break;
case 'm': key->uids->validity = GPGME_VALIDITY_MARGINAL; break;
case 'f': key->uids->validity = GPGME_VALIDITY_FULL; break;
case 'u': key->uids->validity = GPGME_VALIDITY_ULTIMATE; break;
}
}
}
static void
set_subkey_trust_info (struct subkey_s *k, const char *s)
{
/* Look at letters and stop at the first digit. */
for (; *s && !my_isdigit (*s); s++)
{
switch (*s)
{
case 'e': k->flags.expired = 1; break;
case 'r': k->flags.revoked = 1; break;
case 'd': k->flags.disabled = 1; break;
case 'i': k->flags.invalid = 1; break;
}
}
}
static void
set_mainkey_capability (GpgmeKey key, const char *s)
{
for (; *s ; s++)
{
switch (*s)
{
case 'e': key->keys.flags.can_encrypt = 1; break;
case 's': key->keys.flags.can_sign = 1; break;
case 'c': key->keys.flags.can_certify = 1; break;
case 'E': key->gloflags.can_encrypt = 1; break;
case 'S': key->gloflags.can_sign = 1; break;
case 'C': key->gloflags.can_certify = 1; break;
}
}
}
static void
set_subkey_capability ( struct subkey_s *k, const char *s)
{
for (; *s; s++)
{
switch (*s)
{
case 'e': k->flags.can_encrypt = 1; break;
case 's': k->flags.can_sign = 1; break;
case 'c': k->flags.can_certify = 1; break;
}
}
}
static void
set_ownertrust (GpgmeKey key, const char *s)
{
/* Look at letters and stop at the first digit. */
for (; *s && !my_isdigit (*s); s++)
{
switch (*s)
{
case 'n': key->otrust = GPGME_VALIDITY_NEVER; break;
case 'm': key->otrust = GPGME_VALIDITY_MARGINAL; break;
case 'f': key->otrust = GPGME_VALIDITY_FULL; break;
case 'u': key->otrust = GPGME_VALIDITY_ULTIMATE; break;
default : key->otrust = GPGME_VALIDITY_UNKNOWN; break;
}
}
}
/* Note: We are allowed to modify LINE. */
static void
keylist_colon_handler (GpgmeCtx ctx, char *line)
{
char *p, *pend;
int field = 0;
enum
{
RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_SSB, RT_SEC,
RT_CRT, RT_CRS
}
rectype = RT_NONE;
GpgmeKey key = ctx->tmp_key;
int i;
const char *trust_info = NULL;
struct subkey_s *sk = NULL;
if (ctx->error)
return;
if (!line)
{
/* EOF */
finish_key (ctx);
return;
}
for (p = line; p; p = pend)
{
field++;
pend = strchr (p, ':');
if (pend)
*pend++ = 0;
if (field == 1)
{
if (!strcmp (p, "sig"))
rectype = RT_SIG;
else if (!strcmp (p, "uid") && key)
{
rectype = RT_UID;
key = ctx->tmp_key;
}
else if (!strcmp (p, "sub") && key)
{
/* Start a new subkey. */
rectype = RT_SUB;
if (!(sk = _gpgme_key_add_subkey (key)))
{
ctx->error = mk_error (Out_Of_Core);
return;
}
}
else if (!strcmp (p, "ssb") && key)
{
/* Start a new secret subkey. */
rectype = RT_SSB;
if (!(sk = _gpgme_key_add_secret_subkey (key)))
{
ctx->error = mk_error (Out_Of_Core);
return;
}
}
else if (!strcmp (p, "pub"))
{
/* Start a new keyblock. */
if (_gpgme_key_new (&key))
{
ctx->error = mk_error (Out_Of_Core); /* the only kind of error we can get*/
return;
}
rectype = RT_PUB;
finish_key (ctx);
assert (!ctx->tmp_key);
ctx->tmp_key = key;
}
else if (!strcmp (p, "sec"))
{
/* Start a new keyblock, */
if (_gpgme_key_new_secret (&key))
{
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
return;
}
rectype = RT_SEC;
finish_key (ctx);
assert (!ctx->tmp_key);
ctx->tmp_key = key;
}
else if (!strcmp (p, "crt"))
{
/* Start a new certificate. */
if (_gpgme_key_new (&key))
{
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
return;
}
key->x509 = 1;
rectype = RT_CRT;
finish_key (ctx);
assert (!ctx->tmp_key);
ctx->tmp_key = key;
}
else if (!strcmp (p, "crs"))
{
/* Start a new certificate. */
if (_gpgme_key_new_secret (&key))
{
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
return;
}
key->x509 = 1;
rectype = RT_CRS;
finish_key (ctx);
assert (!ctx->tmp_key);
ctx->tmp_key = key;
}
else if (!strcmp (p, "fpr") && key)
rectype = RT_FPR;
else
rectype = RT_NONE;
}
else if (rectype == RT_PUB || rectype == RT_SEC
|| rectype == RT_CRT || rectype == RT_CRS)
{
switch (field)
{
case 2: /* trust info */
trust_info = p;
set_mainkey_trust_info (key, trust_info);
break;
case 3: /* key length */
i = atoi (p);
if (i > 1) /* ignore invalid values */
key->keys.key_len = i;
break;
case 4: /* pubkey algo */
i = atoi (p);
if (i > 1 && i < 128)
key->keys.key_algo = i;
break;
case 5: /* long keyid */
if (strlen (p) == DIM(key->keys.keyid) - 1)
strcpy (key->keys.keyid, p);
break;
case 6: /* timestamp (seconds) */
key->keys.timestamp = parse_timestamp (p);
break;
case 7: /* expiration time (seconds) */
key->keys.expires_at = parse_timestamp (p);
break;
case 8: /* X.509 serial number */
if (rectype == RT_CRT)
{
key->issuer_serial = xtrystrdup (p);
if (!key->issuer_serial)
ctx->error = mk_error (Out_Of_Core);
}
break;
case 9: /* ownertrust */
set_ownertrust (key, p);
break;
case 10: /* not used for gpg due to --fixed-list-mode option
but gpgsm stores the issuer name */
if (rectype == RT_CRT)
{
key->issuer_name = xtrystrdup (p);
if (!key->issuer_name)
ctx->error = mk_error (Out_Of_Core);
}
break;
case 11: /* signature class */
break;
case 12: /* capabilities */
set_mainkey_capability (key, p);
break;
case 13:
pend = NULL; /* we can stop here */
break;
}
}
else if ((rectype == RT_SUB || rectype== RT_SSB) && sk)
{
switch (field)
{
case 2: /* trust info */
set_subkey_trust_info (sk, p);
break;
case 3: /* key length */
i = atoi (p);
if (i > 1) /* ignore invalid values */
sk->key_len = i;
break;
case 4: /* pubkey algo */
i = atoi (p);
if (i > 1 && i < 128)
sk->key_algo = i;
break;
case 5: /* long keyid */
if (strlen (p) == DIM(sk->keyid) - 1)
strcpy (sk->keyid, p);
break;
case 6: /* timestamp (seconds) */
sk->timestamp = parse_timestamp (p);
break;
case 7: /* expiration time (seconds) */
break;
case 8: /* reserved (LID) */
break;
case 9: /* ownertrust */
break;
case 10:/* user ID n/a for a subkey */
break;
case 11: /* signature class */
break;
case 12: /* capability */
set_subkey_capability (sk, p);
break;
case 13:
pend = NULL; /* we can stop here */
break;
}
}
else if (rectype == RT_UID)
{
switch (field)
{
case 2: /* trust info */
trust_info = p; /*save for later */
break;
case 10: /* user ID */
if (_gpgme_key_append_name (key, p))
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
else
{
if (trust_info)
set_userid_flags (key, trust_info);
}
pend = NULL; /* we can stop here */
break;
}
}
else if (rectype == RT_FPR)
{
switch (field)
{
case 10: /* fingerprint (take only the first one)*/
if (!key->keys.fingerprint && *p)
{
key->keys.fingerprint = xtrystrdup (p);
if (!key->keys.fingerprint)
ctx->error = mk_error (Out_Of_Core);
}
break;
case 13: /* gpgsm chain ID (take only the first one)*/
if (!key->chain_id && *p)
{
key->chain_id = xtrystrdup (p);
if (!key->chain_id)
ctx->error = mk_error (Out_Of_Core);
}
pend = NULL; /* that is all we want */
break;
}
}
}
}
/*
* We have read an entire key into ctx->tmp_key and should now finish
* it. It is assumed that this releases ctx->tmp_key.
*/
static void
finish_key (GpgmeCtx ctx)
{
GpgmeKey key = ctx->tmp_key;
struct key_queue_item_s *q, *q2;
if (key)
{
ctx->tmp_key = NULL;
_gpgme_key_cache_add (key);
q = xtrymalloc (sizeof *q);
if (!q)
{
gpgme_key_release (key);
ctx->error = mk_error (Out_Of_Core);
return;
}
q->key = key;
q->next = NULL;
/* FIXME: Lock queue. Use a tail pointer? */
if (!(q2 = ctx->key_queue))
ctx->key_queue = q;
else
{
for (; q2->next; q2 = q2->next)
;
q2->next = q;
}
ctx->key_cond = 1;
/* FIXME: Unlock queue. */
}
}
/**
* gpgme_op_keylist_start:
* @c: context
* @pattern: a GnuPG user ID or NULL for all
* @secret_only: List only keys where the secret part is available
*
* Note that this function also cancels a pending key listing
* operaton. To actually retrieve the key, use
* gpgme_op_keylist_next().
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
{
GpgmeError err = 0;
if (!ctx)
return mk_error (Invalid_Value);
ctx->pending = 1;
_gpgme_release_result (ctx);
if (ctx->engine)
{
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
gpgme_key_release (ctx->tmp_key);
ctx->tmp_key = NULL;
/* Fixme: Release key_queue. */
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
_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)
goto leave;
/* We don't want to use the verbose mode as this will also print
the key signatures which is in most cases not needed and furthermore we
just ignore those lines - This should speed up things */
_gpgme_engine_set_verbosity (ctx->engine, 0);
err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only, ctx->keylist_mode);
if (!err) /* And kick off the process. */
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_keylist_ext_start:
* @c: context
* @pattern: a NULL terminated array of search patterns
* @secret_only: List only keys where the secret part is available
* @reserved: Should be 0.
*
* Note that this function also cancels a pending key listing
* operaton. To actually retrieve the key, use
* gpgme_op_keylist_next().
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
int secret_only, int reserved)
{
GpgmeError err = 0;
if (!ctx)
return mk_error (Invalid_Value);
ctx->pending = 1;
_gpgme_release_result (ctx);
if (ctx->engine)
{
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
gpgme_key_release (ctx->tmp_key);
ctx->tmp_key = NULL;
/* Fixme: Release key_queue. */
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
if (err)
goto leave;
_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)
goto leave;
/* We don't want to use the verbose mode as this will also print
the key signatures which is in most cases not needed and furthermore we
just ignore those lines - This should speed up things */
_gpgme_engine_set_verbosity (ctx->engine, 0);
err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
reserved, ctx->keylist_mode);
if (!err) /* And kick off the process. */
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_keylist_next:
* @c: Context
* @r_key: Returned key object
*
* Return the next key from the key listing started with
* gpgme_op_keylist_start(). The caller must free the key using
* gpgme_key_release(). If the last key has already been returned the
* last time the function was called, %GPGME_EOF is returned and the
* operation is finished.
*
* Return value: 0 on success, %GPGME_EOF or another error code.
**/
GpgmeError
gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key)
{
struct key_queue_item_s *queue_item;
if (!r_key)
return mk_error (Invalid_Value);
*r_key = NULL;
if (!ctx)
return mk_error (Invalid_Value);
if (!ctx->pending)
return mk_error (No_Request);
if (ctx->error)
return ctx->error;
if (!ctx->key_queue)
{
_gpgme_wait_on_condition (ctx, 1, &ctx->key_cond);
if (ctx->error)
return ctx->error;
if (!ctx->key_cond)
{
ctx->pending = 0;
return mk_error (EOF);
}
ctx->key_cond = 0;
assert (ctx->key_queue);
}
queue_item = ctx->key_queue;
ctx->key_queue = queue_item->next;
if (!ctx->key_queue)
ctx->key_cond = 0;
*r_key = queue_item->key;
xfree (queue_item);
return 0;
}
/**
* gpgme_op_keylist_end:
* @c: Context
*
* Ends the keylist operation and allows to use the context for some
* other operation next.
**/
GpgmeError
gpgme_op_keylist_end (GpgmeCtx ctx)
{
if (!ctx)
return mk_error (Invalid_Value);
if (!ctx->pending)
return mk_error (No_Request);
if (ctx->error)
return ctx->error;
ctx->pending = 0;
return 0;
}

84
tags/gpgme-0-3-7/gpgme/mkerrors Executable file
View File

@ -0,0 +1,84 @@
#!/bin/sh
# mkerrors - Extract error strings from gpgme.h
# and create C source for gpgme_strerror
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
cat <<EOF
/* Generated automatically by mkerrors */
/* Do not edit! */
#include <stdio.h>
#include "gpgme.h"
/**
* gpgme_strerror:
* @err: Error code
*
* This function returns a textual representaion of the given
* errocode. If this is an unknown value, a string with the value
* is returned (which is hold in a static buffer).
*
* Return value: String with the error description.
**/
const char *
gpgme_strerror (GpgmeError err)
{
const char *s;
static char buf[25];
switch (err) {
EOF
awk '
/GPGME_No_Error/ { okay=1 }
!okay {next}
/}/ { exit 0 }
/GPGME_[A-Za-z_]*/ { print_code($1) }
function print_code( s )
{
printf " case %s: s=\"", s ;
gsub(/_/, " ", s );
printf "%s\"; break;\n", substr(s,7);
}
'
cat <<EOF
default: sprintf (buf, "ec=%d", err ); s=buf; break;
}
return s;
}
EOF

61
tags/gpgme-0-3-7/gpgme/mkstatus Executable file
View File

@ -0,0 +1,61 @@
#!/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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
GpgStatusCode code;
};
static struct status_table_s status_table[] =
{
EOF
awk '
/STATUS_ENTER/ { okay=1 }
!okay {next}
/}/ { exit 0 }
/STATUS_[A-Za-z_]*/ { printf " { \"%s\", %s },\n", substr($1,8), $1 }
' | sort
cat <<EOF
{NULL, 0}
};
EOF

View File

@ -0,0 +1,137 @@
/* ops.h - internal operations stuff
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef OPS_H
#define OPS_H
#include "types.h"
#include "rungpg.h"
/* Support macros. */
#define test_and_allocate_result(ctx,field) \
do \
{ \
if (!ctx->result.field) \
{ \
ctx->result.field = xtrycalloc (1, sizeof *ctx->result.field); \
if (!ctx->result.field) \
{ \
ctx->error = mk_error (Out_Of_Core); \
return; \
} \
} \
} \
while (0)
/*-- gpgme.c --*/
void _gpgme_release_result ( GpgmeCtx c );
void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info);
/*-- wait.c --*/
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
int hang, volatile int *cond );
void _gpgme_freeze_fd ( int fd );
void _gpgme_thaw_fd ( int fd );
/*-- recipient.c --*/
int _gpgme_recipients_all_valid ( const GpgmeRecipients rset );
/*-- data.c --*/
char * _gpgme_data_release_and_return_string ( GpgmeData dh );
GpgmeDataMode _gpgme_data_get_mode ( GpgmeData dh );
void _gpgme_data_set_mode ( GpgmeData dh, GpgmeDataMode mode );
char * _gpgme_data_get_as_string ( GpgmeData dh );
GpgmeError _gpgme_data_append ( GpgmeData dh,
const char *buffer, size_t length );
GpgmeError _gpgme_data_append_string ( GpgmeData dh, const char *s );
GpgmeError _gpgme_data_append_string_for_xml ( GpgmeData dh,
const char *s);
GpgmeError _gpgme_data_append_for_xml ( GpgmeData dh,
const char *buffer,
size_t len );
GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh,
const char *string );
GpgmeError _gpgme_data_unread (GpgmeData dh,
const char *buffer, size_t length );
int _gpgme_data_inbound_handler (void *opaque, int pid, int fd);
int _gpgme_data_outbound_handler (void *opaque, int pid, int fd);
/*-- key.c --*/
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
/*-- verify.c --*/
void _gpgme_release_verify_result (VerifyResult result);
GpgmeSigStat _gpgme_intersect_stati (VerifyResult result);
void _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code,
char *args);
/*-- decrypt.c --*/
void _gpgme_release_decrypt_result (DecryptResult result);
void _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
char *args);
GpgmeError _gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
void *status_handler);
GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
/*-- sign.c --*/
void _gpgme_release_sign_result ( SignResult res );
void _gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code,
char *args);
/*-- encrypt.c --*/
void _gpgme_release_encrypt_result ( EncryptResult res );
void _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
char *args);
/*-- passphrase.c --*/
void _gpgme_release_passphrase_result (PassphraseResult result);
void _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code,
char *args);
GpgmeError _gpgme_passphrase_start (GpgmeCtx ctx);
/*-- progress.c --*/
void _gpgme_progress_status_handler (GpgmeCtx ctx, GpgStatusCode code,
char *args);
/*-- import.c --*/
void _gpgme_release_import_result (ImportResult res);
/*-- delete.c --*/
void _gpgme_release_delete_result (DeleteResult res);
/*-- genkey.c --*/
void _gpgme_release_genkey_result (GenKeyResult res);
/*-- version.c --*/
const char *_gpgme_compare_versions (const char *my_version,
const char *req_version);
char *_gpgme_get_program_version (const char *const path);
#endif /* OPS_H */

View File

@ -0,0 +1,175 @@
/* passphrase.c - passphrase functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct passphrase_result_s
{
int no_passphrase;
void *last_pw_handle;
char *userid_hint;
char *passphrase_info;
int bad_passphrase;
};
void
_gpgme_release_passphrase_result (PassphraseResult result)
{
if (!result)
return;
xfree (result->passphrase_info);
xfree (result->userid_hint);
xfree (result);
}
void
_gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
if (ctx->error)
return;
test_and_allocate_result (ctx, passphrase);
switch (code)
{
case STATUS_USERID_HINT:
xfree (ctx->result.passphrase->userid_hint);
if (!(ctx->result.passphrase->userid_hint = xtrystrdup (args)))
ctx->error = mk_error (Out_Of_Core);
break;
case STATUS_BAD_PASSPHRASE:
ctx->result.passphrase->bad_passphrase++;
break;
case STATUS_GOOD_PASSPHRASE:
ctx->result.passphrase->bad_passphrase = 0;
break;
case STATUS_NEED_PASSPHRASE:
case STATUS_NEED_PASSPHRASE_SYM:
xfree (ctx->result.passphrase->passphrase_info);
ctx->result.passphrase->passphrase_info = xtrystrdup (args);
if (!ctx->result.passphrase->passphrase_info)
ctx->error = mk_error (Out_Of_Core);
break;
case STATUS_MISSING_PASSPHRASE:
DEBUG0 ("missing passphrase - stop\n");;
ctx->result.passphrase->no_passphrase = 1;
break;
case STATUS_EOF:
if (ctx->result.passphrase->no_passphrase
|| ctx->result.passphrase->bad_passphrase)
ctx->error = mk_error (No_Passphrase);
break;
default:
/* Ignore all other codes. */
break;
}
}
static const char *
command_handler (void *opaque, GpgStatusCode code, const char *key)
{
GpgmeCtx ctx = opaque;
if (!ctx->result.passphrase)
{
ctx->result.passphrase = xtrycalloc (1, sizeof *ctx->result.passphrase);
if (!ctx->result.passphrase)
{
ctx->error = mk_error (Out_Of_Core);
return NULL;
}
}
if (!code)
{
/* We have been called for cleanup. */
if (ctx->passphrase_cb)
{
/* Fixme: Take the key in account. */
ctx->passphrase_cb (ctx->passphrase_cb_value, NULL,
&ctx->result.passphrase->last_pw_handle);
}
return NULL;
}
if (!key || !ctx->passphrase_cb)
return NULL;
if (code == STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter"))
{
const char *userid_hint = ctx->result.passphrase->userid_hint;
const char *passphrase_info = ctx->result.passphrase->passphrase_info;
int bad_passphrase = ctx->result.passphrase->bad_passphrase;
char *buf;
const char *s;
ctx->result.passphrase->bad_passphrase = 0;
if (!userid_hint)
userid_hint = "[User ID hint missing]";
if (!passphrase_info)
passphrase_info = "[passphrase info missing]";
buf = xtrymalloc (20 + strlen (userid_hint)
+ strlen (passphrase_info) + 3);
if (!buf)
{
ctx->error = mk_error (Out_Of_Core);
return NULL;
}
sprintf (buf, "%s\n%s\n%s",
bad_passphrase ? "TRY_AGAIN":"ENTER",
userid_hint, passphrase_info);
s = ctx->passphrase_cb (ctx->passphrase_cb_value,
buf, &ctx->result.passphrase->last_pw_handle);
xfree (buf);
return s;
}
return NULL;
}
GpgmeError
_gpgme_passphrase_start (GpgmeCtx ctx)
{
GpgmeError err = 0;
if (ctx->passphrase_cb)
err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, ctx);
return err;
}

View File

@ -0,0 +1,381 @@
/* posix-io.c - Posix I/O functions
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "io.h"
#include "sema.h"
#include "ath.h"
static struct
{
void (*handler) (int,void*);
void *value;
} notify_table[256];
int
_gpgme_io_read (int fd, void *buffer, size_t count)
{
int nread;
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 );
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;
}
int
_gpgme_io_write (int fd, const void *buffer, size_t count)
{
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);
DEBUG2 ("fd %d: wrote %d bytes\n", fd, (int) nwritten);
return nwritten;
}
int
_gpgme_io_pipe (int filedes[2], int inherit_idx)
{
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);
if (err < 0)
{
close (filedes[0]);
close (filedes[1]);
}
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 < 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 >= 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);
}
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)
{
static int fixed_signals;
DEFINE_STATIC_LOCK (fixed_signals_lock);
pid_t pid;
int i;
LOCK (fixed_signals_lock);
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;
}
UNLOCK (fixed_signals_lock);
pid = fork ();
if (pid == -1)
return -1;
if (!pid)
{
/* 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. */
/* .dup_to is not used in the parent list. */
for (i=0; fd_parent_list[i].fd != -1; i++)
close (fd_parent_list[i].fd);
return (int) pid;
}
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;
}
int
_gpgme_io_kill (int pid, int hard)
{
return kill (pid, hard ? SIGKILL : SIGTERM);
}
/*
* 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)
{
fd_set readfds;
fd_set writefds;
int any, i, 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;
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)
{
DEBUG1 ("_gpgme_io_select failed: %s\n", strerror (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;
}

View File

@ -0,0 +1,71 @@
/* posix-sema.c
* Copyright (C) 2001 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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"
static void
sema_fatal (const char *text)
{
fprintf (stderr, "sema.c: %s\n", text);
abort ();
}
void
_gpgme_sema_subsystem_init ()
{
/* FIXME: we should check that there is only one thread running */
_gpgme_ath_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;
}

View File

@ -0,0 +1,50 @@
/* posix-util.c - Utility functions for Posix
* Copyright (C) 2001 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
}

View File

@ -0,0 +1,80 @@
/* progress.c - status handler for progress status
* Copyright (C) 2000 Werner Koch (dd9jn)
* Copyright (C) 2001, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "context.h"
void
_gpgme_progress_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
{
char *p;
char *args_cpy;
int type = 0;
int current = 0;
int total = 0;
if (code != STATUS_PROGRESS || !*args || !ctx->progress_cb)
return;
args_cpy = xtrystrdup (args);
if (!args_cpy)
{
ctx->error = mk_error (Out_Of_Core);
return;
}
p = strchr (args_cpy, ' ');
if (p)
{
*p++ = 0;
if (*p)
{
type = *(byte *)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);
xfree (args_cpy);
}

View File

@ -0,0 +1,240 @@
/* recipient.c - mainatin recipient sets
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "rungpg.h"
/**
* gpgme_recipients_new:
* @r_rset: Returns the new object.
*
* Create a new uninitialized Reciepient set Object.
*
* Return value: 0 on success or an error code.
**/
GpgmeError
gpgme_recipients_new (GpgmeRecipients *r_rset)
{
GpgmeRecipients rset;
rset = xtrycalloc ( 1, sizeof *rset );
if (!rset)
return mk_error (Out_Of_Core);
*r_rset = rset;
return 0;
}
/**
* gpgme_recipients_release:
* @rset: Recipient Set object
*
* Free the given object.
**/
void
gpgme_recipients_release ( GpgmeRecipients rset )
{
if (rset) {
struct user_id_s *u, *u2;
for (u = rset->list; u; u = u2) {
u2 = u->next;
xfree(u);
}
}
xfree ( rset );
}
/**
* gpgme_recipients_add_name:
* @rset: Recipient Set object
* @name: user name or keyID
*
* Add a name to the recipient Set.
*
* Return value: 0 on success or an error code
**/
GpgmeError
gpgme_recipients_add_name (GpgmeRecipients rset, const char *name )
{
return gpgme_recipients_add_name_with_validity (
rset, name, GPGME_VALIDITY_UNKNOWN
);
}
/**
* gpgme_recipients_add_name_with_validity:
* @rset: Recipient Set object
* @name: user name or keyID
* @val: Validity value
*
* Same as gpgme_recipients_add_name() but with explictly given key
* validity. Use one of the constants
* %GPGME_VALIDITY_UNKNOWN, %GPGME_VALIDITY_UNDEFINED,
* %GPGME_VALIDITY_NEVER, %GPGME_VALIDITY_MARGINAL,
* %GPGME_VALIDITY_FULL, %GPGME_VALIDITY_ULTIMATE5
* for the validity. %GPGME_VALIDITY_UNKNOWN is implicitly used by
* gpgme_recipients_add_name().
*
* Return value: o on success or an error value.
**/
GpgmeError
gpgme_recipients_add_name_with_validity (GpgmeRecipients rset,
const char *name,
GpgmeValidity val )
{
struct user_id_s *r;
if (!name || !rset )
return mk_error (Invalid_Value);
r = xtrymalloc ( sizeof *r + strlen (name) );
if (!r)
return mk_error (Out_Of_Core);
r->validity = val;
r->name_part = "";
r->email_part = "";
r->comment_part = "";
strcpy (r->name, name );
r->next = rset->list;
rset->list = r;
return 0;
}
/**
* gpgme_recipients_count:
* @rset: Recipient Set object
*
* Return value: The number of recipients in the set.
**/
unsigned int
gpgme_recipients_count ( const GpgmeRecipients rset )
{
struct user_id_s *r;
unsigned int count = 0;
if ( rset ) {
for (r=rset->list ; r; r = r->next )
count++;
}
return count;
}
/**
* gpgme_recipients_enum_open:
* @rset: Recipient Set object
* @ctx: Enumerator
*
* Start an enumeration on the Recipient Set object. The caller must pass
* the address of a void pointer which is used as the enumerator object.
*
* Return value: 0 on success or an error code.
*
* See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close().
**/
GpgmeError
gpgme_recipients_enum_open ( const GpgmeRecipients rset, void **ctx )
{
if (!rset || !ctx)
return mk_error (Invalid_Value);
*ctx = rset->list;
return 0;
}
/**
* gpgme_recipients_enum_read:
* @rset: Recipient Set object
* @ctx: Enumerator
*
* Return the name of the next user name from the given recipient
* set. This name is valid as along as the @rset is valid and until
* the next call to this function.
*
* Return value: name or NULL for no more names.
*
* See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close().
**/
const char *
gpgme_recipients_enum_read ( const GpgmeRecipients rset, void **ctx )
{
struct user_id_s *r;
if (!rset || !ctx)
return NULL; /* oops */
r = *ctx;
if ( r ) {
const char *s = r->name;
r = r->next;
*ctx = r;
return s;
}
return NULL;
}
/**
* gpgme_recipients_enum_close:
* @rset: Recipient Set object
* @ctx: Enumerator
*
* Release the enumerator @rset for this object.
*
* Return value: 0 on success or %GPGME_Invalid_Value;
*
* See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close().
**/
GpgmeError
gpgme_recipients_enum_close ( const GpgmeRecipients rset, void **ctx )
{
if (!rset || !ctx)
return mk_error (Invalid_Value);
*ctx = NULL;
return 0;
}
int
_gpgme_recipients_all_valid ( const GpgmeRecipients rset )
{
struct user_id_s *r;
assert (rset);
for (r=rset->list ; r; r = r->next ) {
if (r->validity != GPGME_VALIDITY_FULL
&& r->validity != GPGME_VALIDITY_ULTIMATE )
return 0; /*no*/
}
return 1; /*yes*/
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
/* rungpg.h - gpg calling functions
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef RUNGPG_H
#define RUNGPG_H
#include "types.h"
typedef enum {
STATUS_EOF ,
/* mkstatus starts here */
STATUS_ENTER ,
STATUS_LEAVE ,
STATUS_ABORT ,
STATUS_GOODSIG ,
STATUS_BADSIG ,
STATUS_ERRSIG ,
STATUS_BADARMOR ,
STATUS_RSA_OR_IDEA ,
STATUS_KEYEXPIRED ,
STATUS_KEYREVOKED ,
STATUS_TRUST_UNDEFINED ,
STATUS_TRUST_NEVER ,
STATUS_TRUST_MARGINAL ,
STATUS_TRUST_FULLY ,
STATUS_TRUST_ULTIMATE ,
STATUS_SHM_INFO ,
STATUS_SHM_GET ,
STATUS_SHM_GET_BOOL ,
STATUS_SHM_GET_HIDDEN ,
STATUS_NEED_PASSPHRASE ,
STATUS_VALIDSIG ,
STATUS_SIG_ID ,
STATUS_ENC_TO ,
STATUS_NODATA ,
STATUS_BAD_PASSPHRASE ,
STATUS_NO_PUBKEY ,
STATUS_NO_SECKEY ,
STATUS_NEED_PASSPHRASE_SYM,
STATUS_DECRYPTION_FAILED ,
STATUS_DECRYPTION_OKAY ,
STATUS_MISSING_PASSPHRASE ,
STATUS_GOOD_PASSPHRASE ,
STATUS_GOODMDC ,
STATUS_BADMDC ,
STATUS_ERRMDC ,
STATUS_IMPORTED ,
STATUS_IMPORT_RES ,
STATUS_FILE_START ,
STATUS_FILE_DONE ,
STATUS_FILE_ERROR ,
STATUS_BEGIN_DECRYPTION ,
STATUS_END_DECRYPTION ,
STATUS_BEGIN_ENCRYPTION ,
STATUS_END_ENCRYPTION ,
STATUS_DELETE_PROBLEM ,
STATUS_GET_BOOL ,
STATUS_GET_LINE ,
STATUS_GET_HIDDEN ,
STATUS_GOT_IT ,
STATUS_PROGRESS ,
STATUS_SIG_CREATED ,
STATUS_SESSION_KEY ,
STATUS_NOTATION_NAME ,
STATUS_NOTATION_DATA ,
STATUS_POLICY_URL ,
STATUS_BEGIN_STREAM ,
STATUS_END_STREAM ,
STATUS_KEY_CREATED ,
STATUS_USERID_HINT ,
STATUS_UNEXPECTED ,
STATUS_INV_RECP ,
STATUS_NO_RECP ,
STATUS_ALREADY_SIGNED ,
STATUS_SIGEXPIRED ,
STATUS_EXPSIG ,
STATUS_EXPKEYSIG
} GpgStatusCode;
typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args );
typedef void (*GpgColonLineHandler)( GpgmeCtx, char *line );
typedef const char *(*GpgCommandHandler)(void*, GpgStatusCode code,
const char *keyword);
const char *_gpgme_gpg_get_version (void);
GpgmeError _gpgme_gpg_check_version (void);
GpgmeError _gpgme_gpg_new ( GpgObject *r_gpg );
void _gpgme_gpg_release ( GpgObject gpg );
void _gpgme_gpg_housecleaning (void);
void _gpgme_gpg_enable_pipemode ( GpgObject gpg );
GpgmeError _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg );
GpgmeError _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to );
GpgmeError _gpgme_gpg_add_pm_data ( GpgObject gpg, GpgmeData data, int what );
void _gpgme_gpg_set_status_handler ( GpgObject gpg,
GpgStatusHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_simple_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_command_handler ( GpgObject gpg,
GpgCommandHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_op_decrypt (GpgObject gpg, GpgmeData ciph,
GpgmeData plain);
GpgmeError _gpgme_gpg_op_delete (GpgObject gpg, GpgmeKey key, int allow_secret);
GpgmeError _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph,
int use_armor);
GpgmeError _gpgme_gpg_op_encrypt_sign (GpgObject gpg, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph,
int use_armor, GpgmeCtx ctx);
GpgmeError _gpgme_gpg_op_export (GpgObject gpg, GpgmeRecipients recp,
GpgmeData keydata, int use_armor);
GpgmeError _gpgme_gpg_op_genkey (GpgObject gpg, GpgmeData help_data,
int use_armor, GpgmeData pubkey,
GpgmeData seckey);
GpgmeError _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata);
GpgmeError _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern,
int secret_only, int keylist_mode);
GpgmeError _gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[],
int secret_only, int reserved,
int keylist_mode);
GpgmeError _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor,
int use_textmode, GpgmeCtx ctx /* FIXME */);
GpgmeError _gpgme_gpg_op_trustlist (GpgObject gpg, const char *pattern);
GpgmeError _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text);
GpgmeError _gpgme_gpg_spawn (GpgObject gpg, void *opaque);
#endif /* RUNGPG_H */

Some files were not shown because too many files have changed in this diff Show More