This commit was manufactured by cvs2svn to create tag 'gpgme-0-4-6'.

This commit is contained in:
Repo Admin 2004-04-06 14:41:28 +00:00
parent 5e4a336374
commit 34b5868cf7
193 changed files with 71464 additions and 0 deletions

28
tags/gpgme-0-4-6/AUTHORS Normal file
View File

@ -0,0 +1,28 @@
Package: gpgme
Maintainer: Marcus Brinkmann <marcus@g10code.com>
Bug reports: bug-gpgme@gnupg.org
Security related bug reports: security@gnupg.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.
Wojciech Polak <polak@lodz.pdi.net>
- gpgme.spec
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.

340
tags/gpgme-0-4-6/COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 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.
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.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. 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.
1. 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.
2. 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:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) 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.
c) 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.)
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.
3. 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:
a) 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,
b) 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,
c) 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.)
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.
4. 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.
5. 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.
6. 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.
7. 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.
8. 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.
9. 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.
10. 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.
NO WARRANTY
11. 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.
12. 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 OF TERMS AND CONDITIONS
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <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
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:
Gnomovision version 69, Copyright (C) year 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.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `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:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
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.

483
tags/gpgme-0-4-6/ChangeLog Normal file
View File

@ -0,0 +1,483 @@
2004-04-06 Werner Koch <wk@gnupg.org>
Released 0.4.6.
* config.guess, config.sub, ltmain.sh: Updated to those from
libtools 1.5.4.
2004-03-07 Marcus Brinkmann <marcus@g10code.de>
Released 0.4.5.
* configure.ac (NEED_GPGSM_VERSION): Bump up to 1.9.6.
* Makefile.am (EXTRA_DIST): Remove autogen.sh and README.CVS.
2004-02-18 Werner Koch <wk@gnupg.org>
* configure.ac: Make the check for funopen fail with just a
warning.
2004-02-11 Werner Koch <wk@gnupg.org>
* autogen.sh (check_version): Removed bashism and simplified.
2004-02-10 Werner Koch <wk@gnupg.org>
* configure.ac: Fixed funopen test change.
2004-02-06 Moritz Schulte <mo@g10code.com>
* configure.ac: Fix funopen replacement mechanism.
2004-01-31 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Add invocation of AC_SYS_LARGEFILE, AC_TYPE_OFF_T
and AC_FUNC_FSEEKO.
2004-01-12 Werner Koch <wk@gnupg.org>
Released 0.4.4.
* configure.ac: Bumbed LT_Revision; now at C12/A1/R1.
(NEED_GPGSM_VERSION): Set to 1.9.3.
(min_automake_version): Added.
* README.CVS: New.
* Makefile.am (EXTRA_DIST): Added README.CVS.
* autogen.sh: Updated.
2003-11-19 Werner Koch <wk@gnupg.org>
* acinclude.m4: Add AM_PATH_GPG_ERROR.
* configure.ac: Check for timegm. Made warning messages more
prominent.
2003-10-06 Marcus Brinkmann <marcus@g10code.de>
Released 0.4.3.
* configure.ac (LIBGPGME_LT_CURRENT, LIBGPGME_LT_AGE): Bump up by 1.
(LIBGPGME_LT_REVISION): Set to 0.
2003-09-13 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Require libgpg-error 0.5.
* acinclude.m4: Remove libtool cruft, add jm_GLIBC21.
* configure.ac: Add check for getenv_r, and call jm_GLIBC21.
Define HAVE_THREAD_SAFE_GETENV if appropriate.
2003-09-03 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Remove GPGME_CONFIG_LIBS and GPGME_CONFIG_CFLAGS.
2003-09-02 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Move invocation of AC_CANONICAL_HOST up to
suppress warning by autoconf.
2003-08-30 Robert Schiele <rschiele@uni-mannheim.de>
* gpgme.spec.in: %{_infodir}/dir is not packaged,
remove to prevent checking failure.
2003-08-18 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: If building Assuan, check for funopen and
fopencookie, and make isascii, putc_unlocked and memrchr
replacement functions.
(AM_PATH_GPG_ERROR): Require 0.3.
2003-07-31 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AC_INIT): Bump version to 0.4.3.
2003-07-30 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (LIBGPGME_LT_REVISION): Bump up to 1.
Released 0.4.2.
2003-07-08 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Complain if libgpg-error is not found.
2003-06-22 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AC_INIT): Bump version to 0.4.2.
2003-06-06 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (LIBGPGME_LT_CURRENT): Bump up to 11.
* configure.ac: Use AM_PATH_GPG_ERROR.
* configure.ac: Check for libgpg-error. Define
GPG_ERR_SOURCE_DEFAULT.
2003-05-26 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (NEED_GPG_VERSION): Bump up to 1.2.2.
2003-05-18 Marcus Brinkmann <marcus@g10code.de>
In all files, replace the Gpgme* type names with the new gpgme_*
type names.
2003-02-01 Marcus Brinkmann <marcus@g10code.de>
* assuan/: Update files to 2002-11-10 version of assuan.
2003-01-29 Marcus Brinkmann <marcus@g10code.de>
* bonobo/gpgme.c, bonobo/main.c, bonobo/main.h, bonobo/Makefile,
bonobo/Makefile.am, bonobo/Makefile.in: Dead files removed.
* configure.ac: Remove automake conditional BUILD_BONOBO
(AC_CONFIG_FILES): Remove bonobo/Makefile.
* Makefile.am (bonobo): Remove variable.
(SUBDIRS): Remove ${bonobo}.
* configure.ac: Remove all uses of GNUPG_CHECK_TYPEDEF, for byte,
ushort, ulong, u16 and u32.
* acinclude.m4 (GNUPG_CHECK_TYPEDEF): Remove macro.
2002-12-24 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: New conditional HAVE_LD_VERSION_SCRIPT.
Call AC_CANONICAL_HOST, use host instead target.
2002-12-23 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Bump up to 0.4.1.
Released 0.4.0.
2002-12-23 Marcus Brinkmann <marcus@g10code.de>
* autogen.sh (automake_vers): Require 1.7 (really 1.7.1) for the
conditional source distribution bug fix.
2002-12-08 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (LIBGPGME_LT_CURRENT): Increase by one.
(LIBGPGME_LT_AGE, LIBGPGME_LT_REVISION): Set to 0.
2002-11-28 Marcus Brinkmann <marcus@g10code.de>
* NEWS: Add note about moving "gpgmeplug" to the "cryptplug"
package.
* README: Remove instructions related to "gpgmeplug".
* configure.ac: Remove enable option "gpgmeplug" and automake
conditional BUILD_GPGMEPLUG, as well as the status info about it.
(GPGMEPLUG): Remove variable.
* Makefile.am (gpgmeplug): Remove variable.
(SUBDIRS): Remove ${gpgmeplug}.
* cryptplug.h, gpgme-openpgp.c, gpgmeplug.dox, gpgme-smime.c,
Makefile.am, gpgmeplug.c, ChangeLog: Files removed.
2002-11-22 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Disable GPGSM for all dosish systems.
2002-10-12 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Add automake conditional HAVE_GPGSM.
2002-10-08 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AC_INIT): Bump version up to 0.4.0.
(NEED_GPG_VERSION): Bump up to 1.2.0.
(NEED_GPGSM_VERSION): Bump up to 0.9.0.
* README: Update version numbers.
* NEWS: Start entry for 0.4.0.
2002-09-20 Werner Koch <wk@gnupg.org>
Released 0.3.11.
* configure.ac: Bump up LIBGPGME_LT_REVISION.
* configure.ac (AC_CHECK_HEADERS): Check for sys/select.h.
2002-09-04 Marcus Brinkmann <marcus@g10code.de>
* autogen.sh (autoconf_vers): Bump up to 2.53 to get the @&t@
quadrigraph. Always cutting the edge!
2002-09-02 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Create and substitute LTLIBOBJS.
2002-09-02 Marcus Brinkmann <marcus@g10code.de>
Released 0.3.10.
* NEWS: Update for 0.3.9 release.
* configure.ac: Bump up LIBGPGME_LT_REVISION.
2002-08-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.spec.in: Changed user name in Wojciech Polak's email
address from ghostface to polak per request by himself.
2002-08-28 Werner Koch <wk@gnupg.org>
* acinclude.m4 (GNUPG_CHECK_VA_COPY): New.
* configure.ac: Use it.
2002-08-23 Werner Koch <wk@gnupg.org>
* configure.ac (GPGME_CONFIG_CFLAGS): Renamed from GPGME_CFLAGS
and removed the libpath because it is set by the config script.
2002-08-21 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Bump version number to 0.3.10.
* NEWS: Add template for development version.
2002-08-21 Marcus Brinkmann <marcus@g10code.de>
Released 0.3.9.
* NEWS: Update for 0.3.9 release.
* Makefile.am (EXTRA_DIST): Add gpgme.spec.in.
2002-08-21 Marcus Brinkmann <marcus@g10code.de>
* jnlib/argparse.c, jnlib/argparse.h, jnlib/ChangeLog,
jnlib/dotlock.c, jnlib/dotlock.h, jnlib/libjnlib-config.h,
jnlib/logging.c, jnlib/logging.h,jnlib/Makefile.am,
jnlib/mischelp.h, jnlib/README, jnlib/stringhelp.c,
jnlib/stringhelp.h, jnlib/strlist.c, jnlib/strlist.h,
jnlib/types.h, jnlib/xmalloc.c, jnlib/xmalloc.h: Remove files.
2002-08-21 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (SUBDIRS): Remove jnlib.
* configure.ac: Don't check for unsigned short or unsigned long.
Don't check for memicmp, strlwr, strtoul, memmove, stricmp.
Make stpcpy a replaced function.
Don't define HAVE_JNLIB_LOGGING.
Don't generate jnlib/Makefile.
2002-07-02 Werner Koch <wk@gnupg.org>
* configure.ac: Bumbed version number to 0.3.9; add a comment on
when to change it.
* gpgme.spec.in: New. Contributed by Wojciech Polak.
* Makefile.am (dist-hook): New.
* AUTHORS: Added Wojciech and bug reporting addresses.
2002-06-25 Werner Koch <wk@gnupg.org>
Released 0.3.8.
* configure.ac: Bumbed LT version to 9/3/0.
(NEED_GPGSM_VERSION): Need 0.3.8 due to fixed export command.
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, 2003, 2004 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.

229
tags/gpgme-0-4-6/INSTALL Normal file
View File

@ -0,0 +1,229 @@
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
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, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
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 you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' 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. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
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 support 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' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
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 machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
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.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--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.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -0,0 +1,50 @@
# 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 = README-alpha gpgme.spec.in
if BUILD_ASSUAN
assuan = assuan
else
assuan =
endif
if BUILD_COMPLUS
complus = complus
else
complus =
endif
if RUN_GPG_TESTS
tests = tests
else
tests =
endif
SUBDIRS = ${assuan} gpgme ${tests} doc ${complus}
# Fix the version of the spec file and create a file named VERSION
# to be used for patch's Prereq: feature.
dist-hook:
@set -e; \
sed -e 's/@pkg_version@/$(VERSION)/g' \
$(top_srcdir)/gpgme.spec.in > $(distdir)/gpgme.spec
echo "$(VERSION)" > $(distdir)/VERSION

955
tags/gpgme-0-4-6/NEWS Normal file
View File

@ -0,0 +1,955 @@
Noteworthy changes in version 0.4.6 (2004-04-06)
------------------------------------------------
* Bug fixes
Noteworthy changes in version 0.4.5 (2004-03-07)
------------------------------------------------
* GPGME is now compiled with LFS (large file support) by default.
This means that _all_ programs using GPGME must be compiled with
LFS support enabled by default. You can do this easily with
autoconf, by using the AC_SYS_LARGEFILE macro. Or you can do this
without autoconf by defining the preprocessor symbol
_FILE_OFFSET_BITS to 64 (by passing the -D_FILE_OFFSET_BITS=64 to
the C compiler command line, or by defining this preprocessor
symbol before including any system header files). For more
details, read the section on LFS in the manual.
Up to now, it was undocumented that GPGME was not using LFS.
But the public interfaces use off_t, and file descriptors are
exchanged between the application and GPGME. This was an oversight,
and bound to cause troubles in the future.
Writing GPGME as a dual mode library that seamlessly supports LFS
while keeping backwards compatibility is possible, but does not
solve the problem: Many applications already expect GPGME to have
LFS (they are compiled with off_t being a 64bit value). This is true
in particular for the popular Gtk+ and Qt programs.
So, although this is an ABI (but not an API) break, we will not
change the library version to reflect that. Because the interfaces
affected are probably not used yet in any GPGME 0.4 based
application, we don't expect any real failures from this change.
In fact, applications already using LFS will have some subtle bugs
fixed.
However, if you encounter an application using GPGME 0.4.x that
does _not_ use LFS by default (off_t is a 32bit value), _and_
uses at least one of the functions gpgme_data_seek,
gpgme_data_new_from_filepart, or a gpgme_data_seek_cb_t with
gpgme_data_new_from_cbs, then indeed this library will be ABI
incompatible with the program. As said above, we don't believe
such a program exists. If we are in error, then you have two
options: As a quick hack, you can configure GPGME with the
--disable-largefile option. This will revert the change, and GPGME
will not use LFS. However, GPGME will be incompatible with
programs that expect GPGME to use LFS. All applications are
required to use LFS when using GPGME, so this is only good as a
temporary local work-around.
The other option is to change the versioning of the library and
recompile all applications. We have reserved a special version of
the library for that, so you can do that without expecting a
version clash in the future. Furthermore, everyone who does this
will agree on the version to use (this is important for
distribution makers). Read the comment in configure.ac (before
LIBGPGME_LT_AGE) if you want to do this. Please don't do this
blindly: As stated above, we think it is unlikely this measure is
needed. Still, it is there if necessary. If in doubt, contact us
and we will give our advise for your specific situation.
* New key listing mode GPGME_KEYLIST_MODE_VALIDATE for validation of
the listed keys.
* New interface gpgme_cancel() that can be used to cancel
asynchronous operations.
* Interface changes relative to the 0.4.4 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_data_seek_cb_t CHANGED: off_t is now a largefile type.
gpgme_data_seek CHANGED: off_t is now a largefile type.
gpgme_data_new_from_filepart CHANGED: off_t is now a largefile type.
GPGME_KEYLIST_MODE_VALIDATE NEW
gpgme_cancel NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.4.4 (2004-01-12)
------------------------------------------------
* The member "class" in gpgme_key_sig_t and gpgme_new_signature_t has
been renamed to "sig_class", to avoid clash with C++ compilers. In
the C API, the old name "class" has been preserved for backwards
compatibility, but is deprecated.
* Interface changes relative to the 0.4.3 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_key_sig_t CHANGED: class deprecated, use new sig_class.
gpgme_new_signature_t CHANGED: class deprecated, use new sig_class.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.4.3 (2003-10-06)
------------------------------------------------
* libgpgme should not be used for threaded programs anymore. This
never worked reliably in all cases, because you had to
be careful about the linking order and libtool wouldn't do that for
you automatically. Instead, now you have to link against
libgpgme-pthread for applications using pthread and libgpgme-pth for
applications using GNU Pth.
The old code for automagically detecting the thread library is
still part of libgpgme, but it is DEPRECATED.
* There are new automake macros AM_PATH_GPGME_PTH and
AM_PATH_GPGME_PTHREAD, which support checking for thread-enabled
versions of GPGME. They define GPGME_PTH_CFLAGS, GPGME_PTH_LIBS,
GPGME_PTHREAD_CFLAGS and GPGME_PTHREAD_LIBS respectively. These
variables of course also include the configuration for the thread
package itself. Alternatively, use libtool.
* gpgme_strerror_r as a thread safe variant of gpgme_strerror was
added.
* gpgme-config doesn't support setting the prefix or exec prefix
anymore. I don't think it ever worked correctly, and it seems to
be pointless.
* gpgme_get_key fails with GPG_ERR_AMBIGUOUS_NAME if the key ID
provided was not unique, instead returning the first matching key.
* gpgme_key_t and gpgme_subkey_t have a new field, can_authenticate,
that indicates if the key can be used for authentication.
* gpgme_signature_t's status field is now correctly set to an error
with error code GPG_ERR_NO_PUBKEY if public key is not found.
* gpgme_new_signature_t's class field is now an unsigned int, rather
than an unsigned long (the old class field is preserved for
backwards compatibility).
* A new function gpgme_set_locale() is provided to allow configuring
the locale for the crypto backend. This is necessary for text
terminals so that programs like the pinentry can be started with
the right locale settings for the terminal the application is running
on, in case the terminal has different settings than the system
default (for example, if it is a remote terminal). You are highly
recommended to call the following functions directly after
gpgme_check_version:
#include <locale.h>
setlocale (LC_ALL, "");
gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
GPGME can not do this for you, as setlocale is not thread safe, and
there is no alternative.
* The signal action for SIGPIPE is now set to SIG_IGN by
gpgme_check_version, instead the first time a crypto engine is
started (which is not well defined).
* In the output of gpgme_hash_algo_name, change RMD160 to RIPEMD160,
TIGER to TIGER192, CRC32-RFC1510 to CRC32RFC1510, and CRC24-RFC2440
to CRC24RFC2440. For now, these strings can be used as the MIC
parameter for PGP/MIME (if appropriately modified).
* Interface changes relative to the 0.4.2 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_strerror_t NEW
gpgme_get_key CHANGED: Fails correctly if key ID not unique.
gpgme_key_t EXTENDED: New field can_authenticate.
gpgme_subkey_t EXTENDED: New field can_authenticate.
gpgme_new_signature_t CHANGED: New type for class field.
gpgme_set_locale NEW
gpgme_hash_algo_name CHANGED: Slight adjustment of algo names.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.4.2 (2003-07-30)
------------------------------------------------
* Allow gpg-error to be in non-standard place when linking the test suite.
* Configure will fail now if gpg-error can not be found.
* Fixed initialized memory backed data objects for writing, which
caused the test program to crash (but only on Mac OS, surprisingly).
* Eliminate use of C99 constructs.
* Small improvements to the manual.
Noteworthy changes in version 0.4.1 (2003-06-06)
------------------------------------------------
This is the release that 0.4.0 should have been. There are many
interface changes, please see below for the details. The changes are
sometimes the result of new functionality, but more often express a
paradigm shift. Others are an overdue cleanup to get GPGME in line
with the GNU coding standards and to make the interface more
self-consistent. Here is an overview on the changes:
All types have been renamed to conform to the GNU coding standards,
most of the time by keeping the whole name in lowercase and inserting
underscores between words.
All operations consistently only accept input parameters in their
invocation function, and return only an error code directly. Further
information about the result of the operation has to be retrieved
afterwards by calling one of the result functions. This unifies the
synchronous and the asynchronous interface.
The error values have been completely replaced by a more
sophisticated model that allows GPGME to transparently and accurately
report all errors from the other GnuPG components, irregardless of
process boundaries. This is achieved by using the library
libgpg-errors, which is shared by all GnuPG components. This library
is now required for GPGME.
The results of all operations are now provided by pointers to C
structs rather than by XML structs or in other ways.
Objects which used to be opaque (for example a key) are now pointers
to accessible structs, so no accessor functions are necessary.
Backward compatibility is provided where it was possible without too
much effort and did not collide with the overall sanitization effort.
However, this is only for ease of transition. NO DEPRECATED FUNCTION
OR DATA TYPE IS CONSIDERED A PART OF THE API OR ABI AND WILL BE
DROPPED IN THE FUTURE WITHOUT CHANGING THE SONAME OF THE LIBRARY.
Recommendations how to replace deprecated or removed functionality
can be found within the description of each change.
What follows are all changes to the interface and behaviour of GPGME
in detail.
* If gpgme.h is included in sources compiled by GCC 3.1 or later,
deprecated attributes will warn about use of obsolete functions and
type definitions. You can suppress these warnings by passing
-Wno-deprecated-declarations to the gcc command.
* The following types have been renamed. The old types are still
available as aliases, but they are deprecated now:
Old name: New name:
GpgmeCtx gpgme_ctx_t
GpgmeData gpgme_data_t
GpgmeError gpgme_error_t
GpgmeDataEncoding gpgme_data_encoding_t
GpgmeSigStat gpgme_sig_stat_t
GpgmeSigMode gpgme_sig_mode_t
GpgmeAttr gpgme_attr_t
GpgmeValidity gpgme_validity_t
GpgmeProtocol gpgme_protocol_t
GpgmeKey gpgme_key_t
GpgmePassphraseCb gpgme_passphrase_cb_t
GpgmeProgressCb gpgme_progress_cb_t
GpgmeIOCb gpgme_io_cb_t
GpgmeRegisterIOCb gpgme_register_io_cb_t
GpgmeRemoveIOCb gpgme_remove_io_cb_t
GpgmeEventIO gpgme_event_io_t
GpgmeEventIOCb gpgme_event_io_cb_t
GpgmeIOCbs gpgme_io_cbs
GpgmeDataReadCb gpgme_data_read_cb_t
GpgmeDataWriteCb gpgme_data_write_cb_t
GpgmeDataSeekCb gpgme_data_seek_cb_t
GpgmeDataReleaseCb gpgme_data_release_cb_t
GpgmeDataCbs gpgme_data_cbs_t
GpgmeTrustItem gpgme_trust_item_t
GpgmeStatusCode gpgme_status_code_t
* gpgme_error_t is now identical to gpg_error_t, the error type
provided by libgpg-error. More about using libgpg-error with GPGME
can be found in the manual. All error symbols have been removed!
* All functions and types in libgpg-error have been wrapped in GPGME.
The new types are gpgme_err_code_t and gpgme_err_source_t. The new
functions are gpgme_err_code, gpgme_err_source, gpgme_error,
gpgme_err_make, gpgme_error_from_errno, gpgme_err_make_from_errno,
gpgme_err_code_from_errno, gpgme_err_code_to_errno,
gpgme_strsource.
* GPGME_ATTR_IS_SECRET is not anymore representable as a string.
* GnuPG 1.2.2 is required. The progress callback is now also invoked
for encrypt, sign, encrypt-sign, decrypt, verify, and
decrypt-verify operations. For verify operations on detached
signatures, the progress callback is invoked for both the detached
signature and the plaintext message, though.
* gpgme_passphrase_cb_t has been changed to not provide a complete
description, but the UID hint, passphrase info and a flag
indicating if this is a repeated attempt individually, so the user
can compose his own description from this information.
The passphrase is not returned as a C string, but must be written
to a file descriptor directly. This allows for secure passphrase
entries.
The return type has been changed to gpgme_error_t value. This
allowed to remove the gpgme_cancel function; just return
the error code GPG_ERR_CANCELED in the passphrase callback directly.
* gpgme_edit_cb_t has been changed to take a file descriptor argument.
The user is expected to write the response to the file descriptor,
followed by a newline.
* The recipients interface has been removed. Instead, you use
NULL-terminated lists of keys for specifying the recipients of an
encryption operation. Use the new encryption flag
GPGME_ENCRYPT_ALWAYS_TRUST if you want to override the validity of
the keys (but note that in general this is not a good idea).
This change has been made to the prototypes of gpgme_op_encrypt,
gpgme_op_encrypt_start, gpgme_op_encrypt_sign and
gpgme_op_encrypt_sign_start.
The export interface has been changed to use pattern strings like
the keylist interface. Thus, new functions gpgme_op_export_ext and
gpgme_op_export_ext_start have been added as well. Now the
prototypes of gpgme_op_export_start and gpgme_op_export finally
make sense.
* gpgme_op_verify and gpgme_op_decrypt_verify don't return a status
summary anymore. Use gpgme_get_sig_status to retrieve the individual
stati.
* gpgme_io_cb_t changed from a void function to a function returning
a gpgme_error_t value. However, it will always return 0, so you
can safely ignore the return value.
* A new I/O callback event GPGME_EVENT_START has been added. The new
requirement is that you must wait until this event until you are
allowed to call the I/O callback handlers previously registered for
this context operation. Calling I/O callback functions for this
context operation before the start event happened is unsafe because
it can lead to race conditions in a multi-threaded environment.
* The idle function feature has been removed. It was not precisely
defined in a multi-threaded environment and is obsoleted by the
user I/O callback functions. If you still need a simple way to
call something while waiting on one or multiple asynchronous
operations to complete, don't set the HANG flag in gpgme_wait (note
that this will return to your program more often than the idle
function did).
* gpgme_wait can return NULL even if hang is true, if an error
occurs. In that case *status contains the error code.
* gpgme_get_engine_info was radically changed. Instead an XML
string, an info structure of the new type gpgme_engine_info_t is
returned. This makes it easier and more robust to evaluate the
information in an application.
* The new function gpgme_get_protocol_name can be used to convert a
gpgme_protocol_t value into a string.
* The status of a context operation is not checked anymore. Starting
a new operation will silently cancel the previous one. Calling a
function that requires you to have started an operation before without
doing so is undefined.
* The FPR argument to gpgme_op_genkey was removed. Instead, use the
gpgme_op_genkey_result function to retrieve a gpgme_genkey_result_t
pointer to a structure which contains the fingerprint. This also
works with gpgme_op_genkey_start. The structure also provides
other information about the generated keys.
So, instead:
char *fpr;
err = gpgme_op_genkey (ctx, NULL, NULL, &fpr);
if (!err && fpr)
printf ("%s\n", fpr);
you should now do:
gpgme_genkey_result_t result;
err = gpgme_op_genkey (ctx, NULL, NULL);
if (!err)
{
result = gpgme_op_genkey_result (ctx);
if (result->fpr)
printf ("%s\n", result->fpr);
}
* The new gpgme_op_import_result function provides detailed
information about the result of an import operation in
gpgme_import_result_t and gpgme_import_status_t objects.
Thus, the gpgme_op_import_ext variant is deprecated.
* The new gpgme_op_sign_result function provides detailed information
about the result of a signing operation in gpgme_sign_result_t,
gpgme_invalid_key_t and gpgme_new_signature_t objects.
* The new gpgme_op_encrypt_result function provides detailed
information about the result of an encryption operation in
a GpgmeEncryptResult object.
* The new gpgme_op_decrypt_result function provides detailed
information about the result of a decryption operation in
a GpgmeDecryptResult object.
* The new gpgme_op_verify_result function provides detailed
information about the result of an verify operation in
a GpgmeVerifyResult object. Because of this, the GPGME_SIG_STAT_*
values, gpgme_get_sig_status, gpgme_get_sig_ulong_attr,
gpgme_get_sig_string_attr and gpgme_get_sig_key are now deprecated,
and gpgme_get_notation is removed.
* GpgmeTrustItem objects have now directly accessible data, so the
gpgme_trust_item_get_string_attr and gpgme_trust_item_get_ulong_attr
accessor functions are deprecated. Also, reference counting is
available through gpgme_trust_item_ref and gpgme_trust_item_unref
(the gpgme_trust_item_release alias for the latter is deprecated).
* Keys are not cached internally anymore, so the force_update argument
to gpgme_get_key has been removed.
* GpgmeKey objects have now directly accessible data so the
gpgme_key_get_string_attr, gpgme_key_get_ulong_attr,
gpgme_key_sig_get_string_attr and gpgme_key_sig_get_ulong_attr
functions are deprecated. Also, gpgme_key_release is now
deprecated. The gpgme_key_get_as_xml function has been dropped.
* Because all interfaces using attributes are deprecated, the
GpgmeAttr data type is also deprecated.
* The new gpgme_op_keylist_result function provides detailed
information about the result of a key listing operation in
a GpgmeKeyListResult object.
* Now that each function comes with its own result retrieval
interface, the generic gpgme_get_op_info interface is not useful
anymore and dropped.
* The type and mode of data objects is not available anymore.
* Interface changes relative to the 0.4.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GpgmeCtx DEPRECATED: Use gpgme_ctx_t.
GpgmeData DEPRECATED: Use gpgme_data_t.
GpgmeError DEPRECATED: Use gpgme_error_t.
GpgmeDataEncoding DEPRECATED: Use gpgme_data_encoding_t.
GpgmeSigStat DEPRECATED: Use gpgme_sig_stat_t.
GpgmeSigMode DEPRECATED: Use gpgme_sig_mode_t.
GpgmeAttr DEPRECATED: Use gpgme_attr_t.
GpgmeValidity DEPRECATED: Use gpgme_validity_t.
GpgmeProtocol DEPRECATED: Use gpgme_protocol_t.
GpgmeKey DEPRECATED: Use gpgme_key_t.
GpgmePassphraseCb DEPRECATED: Use gpgme_passphrase_cb_t.
GpgmeProgressCb DEPRECATED: Use gpgme_progress_cb_t.
GpgmeIOCb DEPRECATED: Use gpgme_io_cb_t.
GpgmeRegisterIOCb DEPRECATED: Use gpgme_register_io_cb_t.
GpgmeRemoveIOCb DEPRECATED: Use gpgme_remove_io_cb_t.
GpgmeEventIO DEPRECATED: Use gpgme_event_io_t.
GpgmeEventIOCb DEPRECATED: Use gpgme_event_io_cb_t.
GpgmeIOCbs DEPRECATED: Use gpgme_io_cbs.
GpgmeDataReadCb DEPRECATED: Use gpgme_data_read_cb_t.
GpgmeDataWriteCb DEPRECATED: Use gpgme_data_write_cb_t.
GpgmeDataSeekCb DEPRECATED: Use gpgme_data_seek_cb_t.
GpgmeDataReleaseCb DEPRECATED: Use gpgme_data_release_cb_t.
GpgmeDataCbs DEPRECATED: Use gpgme_data_cbs_t.
GpgmeTrustItem DEPRECATED: Use gpgme_trust_item_t.
GpgmeStatusCode DEPRECATED: Use gpgme_status_code_t.
gpgme_ctx_t NEW
gpgme_data_t NEW
gpgme_recipients_t NEW
gpgme_error_t NEW
gpgme_data_encoding_t NEW
gpgme_sig_stat_t NEW
gpgme_sig_mode_t NEW
gpgme_attr_t NEW
gpgme_validity_t NEW
gpgme_protocol_t NEW
gpgme_key_t NEW
gpgme_passphrase_cb_t NEW
gpgme_progress_cb_t NEW
gpgme_io_cb_t NEW
gpgme_register_io_cb_t NEW
gpgme_remove_io_cb_t NEW
gpgme_event_io_t NEW
gpgme_event_io_cb_t NEW
gpgme_io_cbs NEW
gpgme_data_read_cb_t NEW
gpgme_data_write_cb_t NEW
gpgme_data_seek_cb_t NEW
gpgme_data_release_cb_t NEW
gpgme_data_cbs_t NEW
gpgme_trust_item_t NEW
gpgme_status_code_t NEW
GPGME_{some error code} REMOVED! Use GPG_ERR_* from libgpg-error.
gpgme_err_code_t NEW
gpgme_err_source_t NEW
gpgme_err_code NEW
gpgme_err_source NEW
gpgme_error NEW
gpgme_err_make NEW
gpgme_error_from_errno NEW
gpgme_err_make_from_errno NEW
gpgme_err_code_from_errno NEW
gpgme_err_code_to_errno NEW
gpgme_strsource NEW
gpgme_io_cb_t CHANGED: Return type from void to GpgmeError.
gpgme_event_io_t CHANGED: New event type (all numbers changed).
gpgme_passphrase_cb_t CHANGED: Desc decomposed, write directly to FD.
gpgme_edit_cb_t CHANGED: Write directly to FD.
gpgme_key_get_string_attr CHANGED: Don't handle GPGME_ATTR_IS_SECRET.
gpgme_op_verify CHANGED: Drop R_STAT argument.
gpgme_op_decrypt_verify CHANGED: Drop R_STAT argument.
gpgme_wait CHANGED: Can return NULL even if hang is true.
GpgmeIdleFunc REMOVED
gpgme_register_idle REMOVED
GpgmeRecipients REMOVED
gpgme_recipients_new REMOVED
gpgme_recipients_release REMOVED
gpgme_recipients_add_name REMOVED
gpgme_recipients_add_name_with_validity REMOVED
gpgme_recipients_count REMOVED
gpgme_recipients_enum_open REMOVED
gpgme_recipients_enum_read REMOVED
gpgme_recipients_enum_close REMOVED
gpgme_encrypt_flags_t NEW
GPGME_ENCRYPT_ALWAYS_TRUST NEW
gpgme_op_encrypt CHANGED: Recipients passed as gpgme_key_t[].
gpgme_op_encrypt_start CHANGED: Recipients passed as gpgme_key_t[].
gpgme_op_encrypt_sign CHANGED: Recipients passed as gpgme_key_t[].
gpgme_op_encrypt_sign_start CHANGED: Recipients passed as gpgme_key_t[].
gpgme_op_export_start CHANGED: User IDs passed as patterns.
gpgme_op_export CHANGED: User IDs passed as patterns.
gpgme_op_export_ext_start NEW
gpgme_op_export_ext NEW
gpgme_keylist_mode_t NEW
gpgme_sigsum_t NEW
gpgme_engine_info_t NEW
gpgme_get_engine_info CHANGED: Return info structure instead XML.
gpgme_get_protocol_name NEW
gpgme_cancel REMOVED: Return error in callback directly.
gpgme_op_genkey CHANGED: FPR argument dropped.
gpgme_op_genkey_result NEW
gpgme_genkey_result_t NEW
gpgme_op_import_ext DEPRECATED: Use gpgme_op_import_result.
gpgme_op_import_result NEW
gpgme_import_status_t NEW
gpgme_import_result_t NEW
gpgme_pubkey_algo_t NEW
gpgme_hash_algo_t NEW
gpgme_invalid_key_t NEW
gpgme_new_signature_t NEW
gpgme_sign_result_t NEW
gpgme_op_sign_result NEW
gpgme_pubkey_algo_name NEW
gpgme_hash_algo_name NEW
gpgme_encrypt_result_t NEW
gpgme_op_encrypt_result NEW
gpgme_decrypt_result_t NEW
gpgme_op_decrypt_result NEW
gpgme_verify_result_t NEW
gpgme_op_verify_result NEW
gpgme_get_notation REMOVED: Access verify result directly instead.
gpgme_get_sig_key DEPRECATED: Use gpgme_get_key with fingerprint.
gpgme_get_sig_ulong_attr DEPRECATED: Use verify result directly.
gpgme_get_sig_string_attr DEPRECATED: Use verify result directly.
GPGME_SIG_STAT_* DEPRECATED: Use error value in sig status.
gpgme_get_sig_status DEPRECATED: Use verify result directly.
gpgme_trust_item_t CHANGED: Now has user accessible data members.
gpgme_trust_item_ref NEW
gpgme_trust_item_unref NEW
gpgme_trust_item_release DEPRECATED: Use gpgme_trust_item_unref.
gpgme_trust_item_get_string_attr DEPRECATED
gpgme_trust_item_get_ulong_attr DEPRECATED
gpgme_get_key CHANGED: Removed force_update argument.
gpgme_sub_key_t NEW
gpgme_key_sig_t NEW
gpgme_user_id_t NEW
gpgme_key_t CHANGED: Now has user accessible data members.
gpgme_key_get_string_attr DEPRECATED
gpgme_key_get_ulong_attr DEPRECATED
gpgme_key_sig_get_string_attr DEPRECATED
gpgme_key_sig_get_ulong_attr DEPRECATED
gpgme_key_get_as_xml REMOVED
gpgme_key_list_result_t NEW
gpgme_op_keylist_result NEW
gpgme_get_op_info REMOVED
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.4.0 (2002-12-23)
------------------------------------------------
* Key generation returns the fingerprint of the generated key.
* New convenience function gpgme_get_key.
* Supports signatures of user IDs in keys via the new
GPGME_KEYLIST_MODE_SIGS keylist mode and the
gpgme_key_sig_get_string_attr and gpgme_key_sig_get_ulong_attr
interfaces. The XML info about a key also includes the signatures
if available.
* New data object interface, which is more flexible and transparent.
* Interface changes relative to the 0.3.9 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GpgmeDataReadCb NEW
GpgmeDataWriteCb NEW
GpgmeDataSeekCb NEW
GpgmeDataReleaseCb NEW
GpgmeDataCbs NEW
gpgme_data_read CHANGED: Match read() closely.
gpgme_data_write CHANGED: Match write() closely.
gpgme_data_seek NEW
gpgme_data_new_from_fd NEW
gpgme_data_new_from_stream NEW
gpgme_data_new_from_cbs NEW
gpgme_data_rewind DEPRECATED: Replaced by gpgme_data_seek().
gpgme_data_new_from_read_cb DEPRECATED: Replaced by gpgme_data_from_cbs().
gpgme_data_get_type REMOVED: No replacement.
gpgme_op_verify CHANGED: Take different data objects for
signed text and plain text.
gpgme_op_verify_start CHANGED: See gpgme_op_verify.
gpgme_check_engine REMOVED: Deprecated since 0.3.0.
gpgme_op_genkey CHANGED: New parameter FPR.
GPGME_KEYLIST_MODE_SIGS NEW
gpgme_key_sig_get_string_attr NEW
gpgme_key_sig_get_ulong_attr NEW
gpgme_get_key NEW
GPGME_ATTR_SIG_CLASS NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.15 (2003-02-18)
-------------------------------------------------
* The progress status is sent via the progress callbacks in
gpgme_op_edit.
* Bug fix for signing operations with explicit signer settings for
the CMS protocol.
Noteworthy changes in version 0.3.14 (2002-12-04)
-------------------------------------------------
* GPGME-Plug is now in its own package "cryptplug".
* Workaround for a setlocale problem. Fixed a segv related to not
correctly as closed marked file descriptors.
Noteworthy changes in version 0.3.13 (2002-11-20)
-------------------------------------------------
* Release due to changes in gpgmeplug.
Noteworthy changes in version 0.3.12 (2002-10-15)
-------------------------------------------------
* Fixed some bux with key listings.
* The development has been branched to clean up some API issues.
This 0.3 series will be kept for compatibility reasons; so do don't
expect new features.
Noteworthy changes in version 0.3.11 (2002-09-20)
-------------------------------------------------
* Bug fixes.
Noteworthy changes in version 0.3.10 (2002-09-02)
-------------------------------------------------
* Setting the signing keys for the CMS protocol does now work.
* The signers setting is honoured by gpgme_op_edit.
Noteworthy changes in version 0.3.9 (2002-08-21)
------------------------------------------------
* A spec file for creating RPMs has been added.
* An experimental interface to GnuPG's --edit-key functionality is
introduced, see gpgme_op_edit.
* The new gpgme_import_ext function provides a convenient access to
the number of processed keys.
* Interface changes relative to the 0.3.8 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GpgmeStatusCode NEW
GpgmeEditCb NEW
gpgme_op_edit_start NEW
gpgme_op_edit NEW
gpgme_op_import_ext NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.8 (2002-06-25)
------------------------------------------------
* It is possible to use an outside event loop for the I/O to the
crypto engine by setting the I/O callbacks with gpgme_set_io_cbs.
* Interface changes relative to the 0.3.6 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GpgmeIOCb NEW
GpgmeRegisterIOCb NEW
GpgmeRemoveIOCb NEW
GpgmeEventIO NEW
GpgmeEventIOCb NEW
struct GpgmeIOCbs NEW
gpgme_set_io_cbs NEW
gpgme_get_io_cbs NEW
GPGME_ATTR_ERRTOK NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 output 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, 2003, 2004 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.

33
tags/gpgme-0-4-6/README Normal file
View File

@ -0,0 +1,33 @@
GPGME - GnuPG Made Easy
---------------------------
!!!! THIS IS WORK IN PROGRESS !!!
If you want to hack on it, start with one of the `tests/gpg/t-foo'
programs.
To build GPGME, you need to install libgpg-error. You need at least
libgpg-error 0.5.
For support of the OpenPGP protocol (default), you need the latest CVS
version of GnuPG 1.2, see `http://www.gnupg.org/cvs-access.html'.
You need at least GnuPG 1.2.2.
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 1.9.6.
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.
For building the CVS version please see the file README.CVS
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 !!!!

View File

@ -0,0 +1,51 @@
If you are building from CVS, run the script
./autogen.sh
first, to make sure that you have all the necessary maintainer tools
are installed and to build the actual configuration files. Then run
./configure --enable-maintainer-mode
followed by the usual make.
If autogen.sh complains about insufficient versions of the required
tools, or the tools are not installed, you may use environment
variables to override the default tool names:
AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake
package. For example
AUTOMAKE_SUFFIX="-1.7" ./autogen.sh
uses "automake-1.7" and "aclocal-1.7.
AUTOMAKE_PREFIX is used as a prefix for all tools from the automake
page and may be combined with AUTOMAKE_SUFFIX. e.g.:
AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh
uses "automake" and "aclocal" in the /usr/foo/bin
directory.
AUTOCONF_SUFFIX is used as a suffix for all tools from the automake
package
AUTOCONF_PREFIX is used as a prefix for all tools from the automake
package
GETTEXT_SUFFIX is used as a suffix for all tools from the gettext
package
GETTEXT_PREFIX is used as a prefix for all tools from the gettext
package
It is also possible to use the variable name AUTOMAKE, AUTOCONF,
ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name
of the programs to run. It is however better to use the suffix and
prefix forms as described above because that does not require
knowledge about the actual tools used by autgen.sh.
Please don't use autopoint, libtoolize or autoreconf unless you are
the current maintainer and want to update the standard configuration
files. All those files should be in the CVS and only updated manually
if the maintainer decides that newer versions are required. The
maintainer should also make sure that the required version of automake
et al. are properly indicated at the top of configure.ac and take care
to copy the files and not merely use symlinks.

24
tags/gpgme-0-4-6/THANKS Normal file
View File

@ -0,0 +1,24 @@
Adriaan de Groot adridg@cs.kun.nl
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
Miguel Coca mcoca@gnu.org
Stéphane Corthésy stephane@sente.ch
Timo Schulz twoaday@freakmail.de
Tommy Reynolds reynolds@redhat.com
Copyright 2001, 2002, 2004 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.

155
tags/gpgme-0-4-6/TODO Normal file
View File

@ -0,0 +1,155 @@
Hey Emacs, this is -*- outline -*- mode!
* Before release:
** Some gpg tests fail with gpg 1.3.4-cvs (gpg/t-keylist-sig)
The test is currently disabled there and in gpg/t-import.
** Add notation data to key signatures.
* ABI's to break:
** I/O and User Data could be made extensible. But this can be done
without breaking the ABI hopefully.
** Compatibility interfaces that can be removed in future versions:
*** ath compatibility modules.
*** gpgme_data_new_from_filepart
*** gpgme_data_new_from_file
*** gpgme_data_new_with_read_cb
*** gpgme_data_rewind
*** gpgme_op_import_ext
*** gpgme_get_sig_key
*** gpgme_get_sig_ulong_attr
*** gpgme_get_sig_string_attr
*** GPGME_SIG_STAT_*
*** gpgme_get_sig_status
*** gpgme_trust_item_release
*** gpgme_trust_item_get_string_attr
*** gpgme_trust_item_get_ulong_attr
*** gpgme_attr_t
*** All Gpgme* typedefs.
* Thread support:
** When GNU Pth supports sendmsg/recvmsg, wrap them properly.
** Without timegm (3) support our ISO time parser is not thread safe.
There is a configure time warning, though.
* New features:
** notification system
We need a simple notification system, probably a simple callback
with a string and some optional arguments. This is for example
required to notify an application of a changed smartcard, The
application can then do whatever is required. There are other
usages too. This notfication system should be independent of any
contextes of course.
** --learn-code support
This might be integrated with import. we still need to work out how
to learn a card when gpg and gpgsm have support for smartcards.
** How to terminate a pending operation? Something like gpgme_op_reset,
but where are you allowed to call it (think callback handlers).
Then gpgme_op_*list_end can go. Update: The only place where this
can go is returning errors from callback handlers, and a function
to be called for example from the user event loop code. The user
must observe the threading rules! A blocking thread can not be
cancelled.
** Might need a stat() for data objects and use it for length param to gpg.
** Allow to export secret keys.
** Implement support for photo ids.
** New features requested by our dear users, but rejected or left for
later consideration:
*** Selecting the key ring, setting the version or comment in output.
Rejected because the naive implementation is engine specific, the
configuration is part of the engine's configuration or readily
worked around in a different way
*** Selecting the symmetric cipher.
*** Exchanging keys with key servers.
** Allow selection of subkeys
** Allow to return time stamps in ISO format
This allows us to handle years later than 2037 properly. With the
time_t interface they are all mapped to 2037-12-31
* Documentation
** Document validity and trust issues.
* Engines
** Do not create/destroy engines, but create engine and then reset it.
Internally the reset operation still spawns a new engine process,
but this can be replaced with a reset later. Also, be very sure to
release everything properly at a reset and at an error. Think hard
about where to guarantee what (ie, what happens if start fails, are
the fds unregistered immediately - i think so?)
** Optimize the case where a data object has an underlying fd we can pass
directly to the engine. This will be automatic with socket I/O and
descriptor passing.
** 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).
* Operations
** If an operation failed, make sure that the result functions don't return
corrupt partial information. !!!
NOTE: The EOF status handler is not called in this case !!!
** If no passphrase cb is installed, status handler is not run even if
password is required by crypto engine. !!
** Verify must not fail on NODATA premature if auto-key-retrieval failed.
It should not fail silently if it knows there is an error. !!!
** All operations: Better error reporting. !!
** Export status handler need much more work. !!!
** Import should return a useful error when one happened.
*** Import does not take notice of NODATA status report.
*** When GPGSM does issue IMPORT_OK status reports, make sure to check for
them in tests/gpgs m/t-import.c.
** Verify can include info about version/algo/class, but currently
this is only available for gpg, not gpgsm.
** Return ENC_TO output in verify result. Again, this is not available
for gpgsm.
** Genkey should return something more useful than General_Error.
** Decrypt:
On Fri, Jun 27, 2003 at 06:28:23PM +0200, Heiko Abraham wrote:
> I have a cipher text and I use 'gpgme_op_decrypt_verify(..)'
> for decrypt and get the plaintext. But also I wish a list
> of all reciepient, that can also decrypt this file.
>
> If I store the file and check it with 'gpg --list-packets ${filename}'
> then I will become also a recipient-list.
> It this also possible with gpgme?
Currently not, but it is easy to add this to GPGME 0.4.1. At least the key
ID and a user ID hint is available from gpg (of course key IDs are not
necessarily unique!). I will put it on the TODO list.
** If possible, use --file-setsize to set the file size for proper progress
callback handling. Write data interface for file size.
** Optimize the file descriptor list, so the number of open fds is
always known easily.
** Encryption: It should be verified that the behaviour for partially untrusted
recipients is correct.
** When GPG issues INV_something for invalid signers, catch them.
* Error Values
** Map ASSUAN/GpgSM ERR error values in a better way than is done now. !!
** Some error values should identify the source more correctly (mostly error
values derived from status messages).
* 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_seek for invalid types.
** t-keylist
Write a test for ext_keylist.
* 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).
** Configure test for gpg and gpgsm version (as a warning).
* Error checking
** engine-gpgsm, with-validation
Add error checking some time after releasing a new gpgsm.

View File

@ -0,0 +1,560 @@
dnl Macros to configure gpgme
dnl GNUPG_FIX_HDR_VERSION(FILE, NAME)
dnl Make the version number in gcrypt/gcrypt.h the same as the one here.
dnl (this is easier than to have a .in file just for one substitution)
dnl We must use a temp file in the current directory because make distcheck
dnl install all sourcefiles RO.
dnl (wk 2001-12-18)
AC_DEFUN(GNUPG_FIX_HDR_VERSION,
[ sed "s/^#define $2 \".*/#define $2 \"$VERSION\"/" $srcdir/$1 > fixhdr.tmp
if cmp -s $srcdir/$1 fixhdr.tmp 2>/dev/null; then
rm -f fixhdr.tmp
else
rm -f $srcdir/$1
if mv fixhdr.tmp $srcdir/$1 ; then
:
else
AC_MSG_ERROR([[
***
*** Failed to fix the version string macro $2 in $1.
*** The old file has been saved as fixhdr.tmp
***]])
fi
AC_MSG_WARN([fixed the $2 macro in $1])
fi
])
dnl ##
dnl ## GNU Pth - The GNU Portable Threads
dnl ## Copyright (c) 1999-2002 Ralf S. Engelschall <rse@engelschall.com>
dnl ##
dnl ## This file is part of GNU Pth, a non-preemptive thread scheduling
dnl ## library which can be found at http://www.gnu.org/software/pth/.
dnl ##
dnl ## This library is free software; you can redistribute it and/or
dnl ## modify it under the terms of the GNU Lesser General Public
dnl ## License as published by the Free Software Foundation; either
dnl ## version 2.1 of the License, or (at your option) any later version.
dnl ##
dnl ## This library is distributed in the hope that it will be useful,
dnl ## but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl ## Lesser General Public License for more details.
dnl ##
dnl ## You should have received a copy of the GNU Lesser General Public
dnl ## License along with this library; if not, write to the Free Software
dnl ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
dnl ## USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
dnl ##
dnl ## pth.m4: Autoconf macro for locating GNU Pth from within
dnl ## configure.in of third-party software packages
dnl ##
dnl ##
dnl ## Synopsis:
dnl ## AC_CHECK_PTH([MIN-VERSION [, # minimum Pth version, e.g. 1.2.0
dnl ## DEFAULT-WITH-PTH [, # default value for --with-pth option
dnl ## DEFAULT-WITH-PTH-TEST [,# default value for --with-pth-test option
dnl ## EXTEND-VARS [, # whether CFLAGS/LDFLAGS/etc are extended
dnl ## ACTION-IF-FOUND [, # action to perform if Pth was found
dnl ## ACTION-IF-NOT-FOUND # action to perform if Pth was not found
dnl ## ]]]]]])
dnl ## Examples:
dnl ## AC_CHECK_PTH(1.2.0)
dnl ## AC_CHECK_PTH(1.2.0,,,no,CFLAGS="$CFLAGS -DHAVE_PTH $PTH_CFLAGS")
dnl ## AC_CHECK_PTH(1.2.0,yes,yes,yes,CFLAGS="$CFLAGS -DHAVE_PTH")
dnl ##
dnl
dnl # auxilliary macros
AC_DEFUN(_AC_PTH_ERROR, [dnl
AC_MSG_RESULT([*FAILED*])
dnl define(_ac_pth_line,dnl
dnl "+------------------------------------------------------------------------+")
dnl echo " _ac_pth_line" 1>&2
cat <<EOT | sed -e 's/^[[ ]]*/ | /' -e 's/>>/ /' 1>&2
$1
EOT
dnl echo " _ac_pth_line" 1>&2
dnl undefine(_ac_pth_line)
exit 1
])
AC_DEFUN(_AC_PTH_VERBOSE, [dnl
if test ".$verbose" = .yes; then
AC_MSG_RESULT([ $1])
fi
])
dnl # the user macro
AC_DEFUN(AC_CHECK_PTH, [dnl
dnl
dnl # prerequisites
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_CPP])dnl
dnl
PTH_CPPFLAGS=''
PTH_CFLAGS=''
PTH_LDFLAGS=''
PTH_LIBS=''
AC_SUBST(PTH_CPPFLAGS)
AC_SUBST(PTH_CFLAGS)
AC_SUBST(PTH_LDFLAGS)
AC_SUBST(PTH_LIBS)
dnl # command line options
AC_MSG_CHECKING(for GNU Pth)
_AC_PTH_VERBOSE([])
AC_ARG_WITH(pth,dnl
[ --with-pth[=ARG] Build with GNU Pth Library (default=]ifelse([$2],,yes,$2)[)],dnl
,dnl
with_pth="ifelse([$2],,yes,$2)"
)dnl
AC_ARG_WITH(pth-test,dnl
[ --with-pth-test Perform GNU Pth Sanity Test (default=]ifelse([$3],,yes,$3)[)],dnl
,dnl
with_pth_test="ifelse([$3],,yes,$3)"
)dnl
_AC_PTH_VERBOSE([+ Command Line Options:])
_AC_PTH_VERBOSE([ o --with-pth=$with_pth])
_AC_PTH_VERBOSE([ o --with-pth-test=$with_pth_test])
dnl
dnl # configuration
if test ".$with_pth" != .no; then
_pth_subdir=no
_pth_subdir_opts=''
case "$with_pth" in
subdir:* )
_pth_subdir=yes
changequote(, )dnl
_pth_subdir_opts=`echo $with_pth | sed -e 's/^subdir:[^ ]*[ ]*//'`
with_pth=`echo $with_pth | sed -e 's/^subdir:\([^ ]*\).*$/\1/'`
changequote([, ])dnl
;;
esac
_pth_version=""
_pth_location=""
_pth_type=""
_pth_cppflags=""
_pth_cflags=""
_pth_ldflags=""
_pth_libs=""
if test ".$with_pth" = .yes; then
# via config script in $PATH
changequote(, )dnl
_pth_version=`(pth-config --version) 2>/dev/null |\
sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'`
changequote([, ])dnl
if test ".$_pth_version" != .; then
_pth_location=`pth-config --prefix`
_pth_type='installed'
_pth_cppflags=`pth-config --cflags`
_pth_cflags=`pth-config --cflags`
_pth_ldflags=`pth-config --ldflags`
_pth_libs=`pth-config --libs`
fi
elif test -d "$with_pth"; then
with_pth=`echo $with_pth | sed -e 's;/*$;;'`
_pth_found=no
# via locally included source tree
if test ".$_pth_subdir" = .yes; then
_pth_location="$with_pth"
_pth_type='local'
_pth_cppflags="-I$with_pth"
_pth_cflags="-I$with_pth"
if test -f "$with_pth/ltconfig"; then
_pth_ldflags="-L$with_pth/.libs"
else
_pth_ldflags="-L$with_pth"
fi
_pth_libs="-lpth"
changequote(, )dnl
_pth_version=`grep '^const char PTH_Hello' $with_pth/pth_vers.c |\
sed -e 's;^.*Version[ ]*\([0-9]*\.[0-9]*[.ab][0-9]*\)[ ].*$;\1;'`
changequote([, ])dnl
_pth_found=yes
ac_configure_args="$ac_configure_args --enable-subdir $_pth_subdir_opts"
with_pth_test=no
fi
# via config script under a specified directory
# (a standard installation, but not a source tree)
if test ".$_pth_found" = .no; then
for _dir in $with_pth/bin $with_pth; do
if test -f "$_dir/pth-config"; then
test -f "$_dir/pth-config.in" && continue # pth-config in source tree!
changequote(, )dnl
_pth_version=`($_dir/pth-config --version) 2>/dev/null |\
sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'`
changequote([, ])dnl
if test ".$_pth_version" != .; then
_pth_location=`$_dir/pth-config --prefix`
_pth_type="installed"
_pth_cppflags=`$_dir/pth-config --cflags`
_pth_cflags=`$_dir/pth-config --cflags`
_pth_ldflags=`$_dir/pth-config --ldflags`
_pth_libs=`$_dir/pth-config --libs`
_pth_found=yes
break
fi
fi
done
fi
# in any subarea under a specified directory
# (either a special installation or a Pth source tree)
if test ".$_pth_found" = .no; then
changequote(, )dnl
_pth_found=0
for _file in x `find $with_pth -name "pth.h" -type f -print`; do
test .$_file = .x && continue
_dir=`echo $_file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'`
_pth_version=`($_dir/pth-config --version) 2>/dev/null |\
sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'`
if test ".$_pth_version" = .; then
_pth_version=`grep '^#define PTH_VERSION_STR' $_file |\
sed -e 's;^#define[ ]*PTH_VERSION_STR[ ]*"\([0-9]*\.[0-9]*[.ab][0-9]*\)[ ].*$;\1;'`
fi
_pth_cppflags="-I$_dir"
_pth_cflags="-I$_dir"
_pth_found=`expr $_pth_found + 1`
done
for _file in x `find $with_pth -name "libpth.[aso]" -type f -print`; do
test .$_file = .x && continue
_dir=`echo $_file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'`
_pth_ldflags="-L$_dir"
_pth_libs="-lpth"
_pth_found=`expr $_pth_found + 1`
done
changequote([, ])dnl
if test ".$_pth_found" = .2; then
_pth_location="$with_pth"
_pth_type="uninstalled"
else
_pth_version=''
fi
fi
fi
_AC_PTH_VERBOSE([+ Determined Location:])
_AC_PTH_VERBOSE([ o path: $_pth_location])
_AC_PTH_VERBOSE([ o type: $_pth_type])
if test ".$_pth_version" = .; then
with_pth=no
else
dnl if test ".$with_pth" != .yes; then
dnl _AC_PTH_ERROR([dnl
dnl Unable to locate GNU Pth under $with_pth.
dnl Please specify the correct path to either a GNU Pth installation tree
dnl (use --with-pth=DIR if you used --prefix=DIR for installing GNU Pth in
dnl the past) or to a GNU Pth source tree (use --with-pth=DIR if DIR is a
dnl path to a pth-X.Y.Z/ directory; but make sure the package is already
dnl built, i.e., the "configure; make" step was already performed there).])
dnl else
dnl _AC_PTH_ERROR([dnl
dnl Unable to locate GNU Pth in any system-wide location (see \$PATH).
dnl Please specify the correct path to either a GNU Pth installation tree
dnl (use --with-pth=DIR if you used --prefix=DIR for installing GNU Pth in
dnl the past) or to a GNU Pth source tree (use --with-pth=DIR if DIR is a
dnl path to a pth-X.Y.Z/ directory; but make sure the package is already
dnl built, i.e., the "configure; make" step was already performed there).])
dnl fi
dnl fi
dnl #
dnl # Check whether the found version is sufficiently new
dnl #
_req_version="ifelse([$1],,1.0.0,$1)"
for _var in _pth_version _req_version; do
eval "_val=\"\$${_var}\""
_major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'`
_minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'`
_rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'`
_micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'`
case $_rtype in
"a" ) _rtype=0 ;;
"b" ) _rtype=1 ;;
"." ) _rtype=2 ;;
esac
_hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
"major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
eval "${_var}_hex=\"\$_hex\""
done
_AC_PTH_VERBOSE([+ Determined Versions:])
_AC_PTH_VERBOSE([ o existing: $_pth_version -> 0x$_pth_version_hex])
_AC_PTH_VERBOSE([ o required: $_req_version -> 0x$_req_version_hex])
_ok=0
if test ".$_pth_version_hex" != .; then
if test ".$_req_version_hex" != .; then
if test $_pth_version_hex -ge $_req_version_hex; then
_ok=1
fi
fi
fi
if test ".$_ok" = .0; then
_AC_PTH_ERROR([dnl
Found Pth version $_pth_version, but required at least version $_req_version.
Upgrade Pth under $_pth_location to $_req_version or higher first, please.])
fi
dnl #
dnl # Perform Pth Sanity Compile Check
dnl #
if test ".$with_pth_test" = .yes; then
_ac_save_CPPFLAGS="$CPPFLAGS"
_ac_save_CFLAGS="$CFLAGS"
_ac_save_LDFLAGS="$LDFLAGS"
_ac_save_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $_pth_cppflags"
CFLAGS="$CFLAGS $_pth_cflags"
LDFLAGS="$LDFLAGS $_pth_ldflags"
LIBS="$LIBS $_pth_libs"
_AC_PTH_VERBOSE([+ Test Build Environment:])
_AC_PTH_VERBOSE([ o CPPFLAGS=\"$CPPFLAGS\"])
_AC_PTH_VERBOSE([ o CFLAGS=\"$CFLAGS\"])
_AC_PTH_VERBOSE([ o LDFLAGS=\"$LDFLAGS\"])
_AC_PTH_VERBOSE([ o LIBS=\"$LIBS\"])
cross_compile=no
define(_code1, [dnl
#include <stdio.h>
#include <pth.h>
])
define(_code2, [dnl
int main(int argc, char *argv[])
{
FILE *fp;
if (!(fp = fopen("conftestval", "w")))
exit(1);
fprintf(fp, "hmm");
fclose(fp);
pth_init();
pth_kill();
if (!(fp = fopen("conftestval", "w")))
exit(1);
fprintf(fp, "yes");
fclose(fp);
exit(0);
}
])
_AC_PTH_VERBOSE([+ Performing Sanity Checks:])
_AC_PTH_VERBOSE([ o pre-processor test])
AC_TRY_CPP(_code1, _ok=yes, _ok=no)
if test ".$_ok" != .yes; then
_AC_PTH_ERROR([dnl
Found GNU Pth $_pth_version under $_pth_location, but
was unable to perform a sanity pre-processor check. This means
the GNU Pth header pth.h was not found.
We used the following build environment:
>> CPP="$CPP"
>> CPPFLAGS="$CPPFLAGS"
See config.log for possibly more details.])
fi
_AC_PTH_VERBOSE([ o link check])
AC_TRY_LINK(_code1, _code2, _ok=yes, _ok=no)
if test ".$_ok" != .yes; then
_AC_PTH_ERROR([dnl
Found GNU Pth $_pth_version under $_pth_location, but
was unable to perform a sanity linker check. This means
the GNU Pth library libpth.a was not found.
We used the following build environment:
>> CC="$CC"
>> CFLAGS="$CFLAGS"
>> LDFLAGS="$LDFLAGS"
>> LIBS="$LIBS"
See config.log for possibly more details.])
fi
_AC_PTH_VERBOSE([ o run-time check])
AC_TRY_RUN(_code1 _code2, _ok=`cat conftestval`, _ok=no, _ok=no)
if test ".$_ok" != .yes; then
if test ".$_ok" = .no; then
_AC_PTH_ERROR([dnl
Found GNU Pth $_pth_version under $_pth_location, but
was unable to perform a sanity execution check. This usually
means that the GNU Pth shared library libpth.so is present
but \$LD_LIBRARY_PATH is incomplete to execute a Pth test.
In this case either disable this test via --without-pth-test,
or extend \$LD_LIBRARY_PATH, or build GNU Pth as a static
library only via its --disable-shared Autoconf option.
We used the following build environment:
>> CC="$CC"
>> CFLAGS="$CFLAGS"
>> LDFLAGS="$LDFLAGS"
>> LIBS="$LIBS"
See config.log for possibly more details.])
else
_AC_PTH_ERROR([dnl
Found GNU Pth $_pth_version under $_pth_location, but
was unable to perform a sanity run-time check. This usually
means that the GNU Pth library failed to work and possibly
caused a core dump in the test program. In this case it
is strongly recommended that you re-install GNU Pth and this
time make sure that it really passes its "make test" procedure.
We used the following build environment:
>> CC="$CC"
>> CFLAGS="$CFLAGS"
>> LDFLAGS="$LDFLAGS"
>> LIBS="$LIBS"
See config.log for possibly more details.])
fi
fi
_extendvars="ifelse([$4],,yes,$4)"
if test ".$_extendvars" != .yes; then
CPPFLAGS="$_ac_save_CPPFLAGS"
CFLAGS="$_ac_save_CFLAGS"
LDFLAGS="$_ac_save_LDFLAGS"
LIBS="$_ac_save_LIBS"
fi
else
_extendvars="ifelse([$4],,yes,$4)"
if test ".$_extendvars" = .yes; then
if test ".$_pth_subdir" = .yes; then
CPPFLAGS="$CPPFLAGS $_pth_cppflags"
CFLAGS="$CFLAGS $_pth_cflags"
LDFLAGS="$LDFLAGS $_pth_ldflags"
LIBS="$LIBS $_pth_libs"
fi
fi
fi
PTH_CPPFLAGS="$_pth_cppflags"
PTH_CFLAGS="$_pth_cflags"
PTH_LDFLAGS="$_pth_ldflags"
PTH_LIBS="$_pth_libs"
AC_SUBST(PTH_CPPFLAGS)
AC_SUBST(PTH_CFLAGS)
AC_SUBST(PTH_LDFLAGS)
AC_SUBST(PTH_LIBS)
_AC_PTH_VERBOSE([+ Final Results:])
_AC_PTH_VERBOSE([ o PTH_CPPFLAGS=\"$PTH_CPPFLAGS\"])
_AC_PTH_VERBOSE([ o PTH_CFLAGS=\"$PTH_CFLAGS\"])
_AC_PTH_VERBOSE([ o PTH_LDFLAGS=\"$PTH_LDFLAGS\"])
_AC_PTH_VERBOSE([ o PTH_LIBS=\"$PTH_LIBS\"])
fi
fi
if test ".$with_pth" != .no; then
AC_MSG_RESULT([version $_pth_version, $_pth_type under $_pth_location])
ifelse([$5], , :, [$5])
else
AC_MSG_RESULT([no])
ifelse([$6], , :, [$6])
fi
])
dnl GNUPG_CHECK_VA_COPY()
dnl Do some check on how to implement va_copy.
dnl May define MUST_COPY_VA_BY_VAL.
dnl Actual test code taken from glib-1.1.
AC_DEFUN(GNUPG_CHECK_VA_COPY,
[ AC_MSG_CHECKING(whether va_lists must be copied by value)
AC_CACHE_VAL(gnupg_cv_must_copy_va_byval,[
gnupg_cv_must_copy_va_byval=no
AC_TRY_RUN([
#include <stdarg.h>
void f (int i, ...)
{
va_list args1, args2;
va_start (args1, i);
args2 = args1;
if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
exit (1);
va_end (args1);
va_end (args2);
}
int main()
{
f (0, 42);
return 0;
}
],gnupg_cv_must_copy_va_byval=yes)
])
if test "$gnupg_cv_must_copy_va_byval" = yes; then
AC_DEFINE(MUST_COPY_VA_BYVAL,1,[used to implement the va_copy macro])
fi
AC_MSG_RESULT($gnupg_cv_must_copy_va_byval)
])
# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40)
dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
dnl Public License, this file may be distributed as part of a program
dnl that contains a configuration script generated by Autoconf, under
dnl the same distribution terms as the rest of that program.
# Test for the GNU C Library, version 2.1 or newer.
# From Bruno Haible.
AC_DEFUN([jm_GLIBC21],
[
AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer,
ac_cv_gnu_library_2_1,
[AC_EGREP_CPP([Lucky GNU user],
[
#include <features.h>
#ifdef __GNU_LIBRARY__
#if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
Lucky GNU user
#endif
#endif
],
ac_cv_gnu_library_2_1=yes,
ac_cv_gnu_library_2_1=no)
]
)
AC_SUBST(GLIBC21)
GLIBC21="$ac_cv_gnu_library_2_1"
]
)
dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS
dnl
dnl taken from libgpg-error 0.6
dnl
AC_DEFUN(AM_PATH_GPG_ERROR,
[ AC_ARG_WITH(gpg-error-prefix,
AC_HELP_STRING([--with-gpg-error-prefix=PFX],
[prefix where GPG Error is installed (optional)]),
gpg_error_config_prefix="$withval", gpg_error_config_prefix="")
if test x$gpg_error_config_prefix != x ; then
if test x${GPG_ERROR_CONFIG+set} != xset ; then
GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config
fi
fi
AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no)
min_gpg_error_version=ifelse([$1], ,0.0,$1)
AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version)
ok=no
if test "$GPG_ERROR_CONFIG" != "no" ; then
req_major=`echo $min_gpg_error_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
req_minor=`echo $min_gpg_error_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
gpg_error_config_version=`$GPG_ERROR_CONFIG $gpg_error_config_args --version`
major=`echo $gpg_error_config_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
minor=`echo $gpg_error_config_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
if test "$major" -gt "$req_major"; then
ok=yes
else
if test "$major" -eq "$req_major"; then
if test "$minor" -ge "$req_minor"; then
ok=yes
fi
fi
fi
fi
if test $ok = yes; then
GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags`
GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs`
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
GPG_ERROR_CFLAGS=""
GPG_ERROR_LIBS=""
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
AC_SUBST(GPG_ERROR_CFLAGS)
AC_SUBST(GPG_ERROR_LIBS)
])

View File

@ -0,0 +1,493 @@
2004-02-18 Werner Koch <wk@gnupg.org>
* assuan-handler.c (assuan_get_data_fp): Fail with ENOSYS if we
can't implement this.
2004-02-13 Werner Koch <wk@gnupg.org>
* assuan-domain-connect.c: Removed the unneeded alloca.h
2003-08-13 Werner Koch <wk@gnupg.org>
* assuan-inquire.c (assuan_inquire): Increase length of cmdbuf to
the Assuan limit.
2003-06-24 Werner Koch <wk@gnupg.org>
* mkerrors: Kludge to print libgpg-error values in an easier
readable way.
2003-04-29 Werner Koch <wk@gnupg.org>
* libassuan.m4: New. Based on libgrypt.m4.
* Makefile.am (m4data_DATA): New.
* assuan.h (AssuanCommand): Removed.
* assuan-handler.c: Remove the cmd_id element,
(assuan_register_command): Likewise. Note that semantics changed.
(_assuan_register_std_commands): Adjusted.
2003-02-22 Neal H. Walfield <neal@g10code.de>
* Makefile.am (bin_SCRIPTS): Renamed from bin_PROGRAMS.
2003-02-18 Neal H. Walfield <neal@g10code.de>
* Makefile.am (libassuan_a_LIBADD): New variable.
* funopen.c: Move from ../common.
* isascii.c: Likewise.
* memrchr.c: Likewise.
* putc_unlocked.c: Likewise.
2003-02-18 Neal H. Walfield <neal@g10code.de>
* assuan-handler.c (_IO_cookie_io_functions_t): Remove.
(cookie_io_functions_t): Remove.
(fopencookie): Remove prototype.
(assuan_get_data_fp): Use funopen, not fopencookie.
2003-02-18 Neal H. Walfield <neal@g10code.de>
* libassuan-config.in: New file.
* Makefile.am (bin_PROGRAMS): New variable.
2003-02-17 Neal H. Walfield <neal@g10code.de>
* .cvsignore: New file.
2003-02-17 Neal H. Walfield <neal@g10code.de>
* Makefile.am (lib_LIBRARIES): Use this instead of . . .
(noinst_LIBRARIES): . . . this.
(include_HEADERS): New variable.
(libassuan_a_SOURCES): Remove assuan.h, add assuan-logging.c.
* assuan.h (assuan_set_assuan_log_stream): New prototype.
(assuan_get_assuan_log_stream): Likewise.
(assuan_get_assuan_log_prefix): Likewise.
* assuan-logging.c: New file.
* assuan-buffer.c [HAVE_JNLIB_LOGGIN]: Do not include
"../jnlib/logging.h".
(my_log_prefix): Remove function.
(_assuan_read_line): Use assuan_get_assuan_log_prefix in lieu of
my_log_prefix.
(assuan_write_line): Likewise.
(_assuan_cookie_write_data): Likewise.
(_assuan_cookie_write_flush): Likewise.
* assuan-domain-connect.c (LOGERROR, LOGERROR1, LOGERROR2,
LOGERRORX): Remove.
(LOG): New macro.
(domain_reader): Use it.
(domain_writer): Likewise.
(domain_sendfd): Likewise.
(domain_receivefd): Likewise.
(_assuan_domain_init): Likewise.
(assuan_domain_connect): Likewise.
* assuan-pipe-connect.c [HAVE_JNLIB_LOGGIN]: Do not include
"../jnlib/logging.h".
(LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove.
(LOG): New macro.
(assuan_pipe_connect): Use it.
* assuan-socket-connect.c [HAVE_JNLIB_LOGGIN]: Do not include
"../jnlib/logging.h".
(LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove.
(LOG): New macro.
(assuan_socket_connect): Use it.
(socket_reader): Remove dead code.
(socket_writer): Likewise.
* assuan-util.c [HAVE_JNLIB_LOGGIN]: Do not include
"../jnlib/logging.h".
(_assuan_log_sanitized_string): Use assuan_get_assuan_log_stream,
not jnlib.
2002-11-24 Neal H. Walfield <neal@g10code.de>
* assuan.h (assuan_command_parse_fd): New prototype.
* assuan-handler.c (assuan_command_parse_fd): Rename from
parse_cmd_input_output. Export.
(std_handler_input): Update to use assuan_command_parse_fd.
(std_handler_output): Likewise.
2002-11-24 Neal H. Walfield <neal@g10code.de>
* assuan.h (assuan_sendfd): New prototype.
(assuan_receivefd): New prototype.
* assuan-buffer.c (assuan_sendfd): New function.
(assuan_receivefd): New function.
* assuan-handler.c (parse_cmd_input_output): Recognize incoming
file descriptors and act appropriately.
* assuan-defs.h (struct assuan_io): Add fields sendfd and
receivefd.
(struct assuan_context_s): Add fields pendingfds and
pendingfdscount.
* assuan-pipe-server.c (_assuan_new_context): Update IO to reflect
new features.
* assuan-domain-connect.c (do_deinit): Cleanup any unreceived file
descriptors.
(domain_reader): Receive file descriptors.
(domain_sendfd): New function.
(domain_receivefd): New function.
(_assuan_domain_init): Update initialization code to reflect new
features.
2002-11-24 Neal H. Walfield <neal@g10code.de>
* assuan-domain-connect.c (do_finish): Remove.
(_assuan_domain_init): Use default handlers where possible.
Add an assert and update comments.
* assuan-domain-server.c (accept_connection): Remove.
(assuan_init_domain_server): Use default handlers where possible.
Put the server in pipe mode: it can only be used by a single
client.
2002-11-24 Neal H. Walfield <neal@g10code.de>
* assuan.h: Add prototype for assuan_domain_connect and
assuan_init_domain_server.
* assuan-defs.h: Include <unistd.h>.
Add prototype for _assuan_domain_init.
* assuan-domain-connect.c: New file.
* assuan-domain-server.c: New file.
* Makefile.am (libassuan_a_SOURCES): Add assuan-domain-connect.c
and assuan-domain-server.c
2002-11-23 Neal H. Walfield <neal@g10code.de>
* Makefile.am (libassuan_a_SOURCES): Add assuan-io.c.
* assuan-io.c: Restore.
(_assuan_simple_read): Rename from _assuan_read.
(_assuan_simple_write): Rename from _assuan_write.
* assuan-defs.h (_assuan_simple_read): New prototype.
(_assuan_simple_write): Likewise.
* assuan-pipe-server.c (pipe_reader): Remove.
(pipe_writer): Remove.
(_assuan_new_context): Initialize IO is with _assuan_simple_read
and _assuan_simple_write.
* assuan-socket-connect.c (socket_reader): Remove.
(socket_writer): Remove.
(assuan_socket_connect): Initialize IO is with _assuan_simple_read
and _assuan_simple_write.
* assuan-socket-server.c (io): New local variable.
(assuan_init_socket_server): Initialize CTX->io.
(assuan_init_connected_socket_server): Likewise.
2002-11-23 Neal H. Walfield <neal@g10code.de>
* assuan-buffer.c (readline): Use memrchr.
(_assuan_read_line): Rewritten to use the string functions.
2002-11-20 Neal H. Walfield <neal@g10code.de>
* assuan-socket-connect.c (assuan_socket_connect): Pass PF_LOCAL
to socket(), not AF_UNIX: it expects a PF_* macro and the former
is more portable.
(assuan_socket_connect): Use AF_LOCAL, not AF_UNIX which is more
POSIXy.
2002-11-20 Neal H. Walfield <neal@g10code.de>
* assuan-defs.h (struct assuan_io): New structure.
(struct assuan_context_s): New field, io.
(_assuan_read): Depreciated.
(_assuan_write): Likewise.
* assuan-pipe-server.c: Include <unistd.h>.
(pipe_reader): New function.
(pipe_writer): Likewise.
(_assuan_new_context.IO): New local static. Set to pipe_reader
and pipe_writer. Use it to initialize new context.
* assuan-socket-connect.c (socket_reader): New function.
(socket_writer): New function.
(assuan_socket_connect.IO): New local static. Set to socket_reader
and socket_writer. Use it to initialize new context.
* assuan-buffer.c (writen): Take an ASSUAN_CONTEXT rather than a
file descriptor. Do not use _assuan_write but the write method
in the supplied context.
(readline): Likewise for _assuan_read.
(assuan_write_line): When calling writen, pass CTX; not the file
descriptor directly.
(_assuan_cookie_write_data): Likewise.
(_assuan_cookie_write_flush): Likewise.
(_assuan_read_line): Likewise for readline.
* Makefile.am (libassuan_a_SOURCES): Remove assuan-io.c.
* assuan-io.c: Removed.
2002-11-10 Werner Koch <wk@gnupg.org>
* assuan-pipe-connect.c (assuan_pipe_connect): Changed the order
of the dups to handle cases where we have already used fd 2 for
other things.
2002-10-31 Neal H. Walfield <neal@g10code.de>
* assuan-util.c: Include <ctype.h>.
(_assuan_log_print_buffer): Elide the magic numbers preferring the
standard isfoo functions. Use putc_unlocked where possible.
(_assuan_log_sanitized_string): Rewrite to use putc_unlocked and
the isfoo functions.
2002-09-05 Neal H. Walfield <neal@g10code.de>
* assuan-defs.h (_assuan_read_wrapper): Depreciated.
* assuan-util.c (_assuan_read_wrapper): Removed.
* assuan-defs.h (_assuan_write_wrapper): Depreciated.
* assuan-util.c (_assuan_write_wrapper): Removed.
* assuan.h (assuan_set_io_fun): Depreciated.
* assuan-util.c (assuan_set_io_fun): Removed.
* assuan-defs.h (_assuan_read): New function.
(_assuan_write): Likewise.
* assuan-io.c: New file.
* assuan-buffer.c (writen): Use _assuan_write rather than doing
the work here.
(readline): Likewise for _assuan_read.
* Makefile.am (libassuan_a_SOURCES): Add assuan-io.c.
2002-08-16 Werner Koch <wk@gnupg.org>
* assuan.h: Renamed Bad_Certificate_Path to Bad_Certificate_Chain.
2002-07-30 Werner Koch <wk@gnupg.org>
Changed the license from GPL to LGPL.
2002-07-23 Werner Koch <wk@gnupg.org>
* assuan-handler.c (_IO_cookie_io_functions_t): Define it here if
it does not exists.
2002-06-27 Werner Koch <wk@gnupg.org>
* assuan-pipe-connect.c (assuan_pipe_connect): No special handling
for the log_fd and stderr. Connect stderr to /dev/null if it
should not be retained.
2002-06-26 Werner Koch <wk@gnupg.org>
* assuan-buffer.c (assuan_write_line): Make sure we never
accidently print an extra LF.
2002-05-23 Werner Koch <wk@gnupg.org>
* assuan-util.c (assuan_set_io_func): New.
* assuan-buffer.c (writen, readline): Use the new functions
instead of pth.
* assuan-socket-server.c (accept_connection): Don't use the
pth_accept - using the assuan included accept code would be a bad
idea within Pth so we don't need a replacement function.
2002-05-22 Werner Koch <wk@gnupg.org>
* assuan-socket-server.c (assuan_init_connected_socket_server): New.
(accept_connection): Factored most code out to..
(accept_connection_bottom): .. new function.
2002-04-04 Werner Koch <wk@gnupg.org>
* assuan-buffer.c (my_log_prefix): New. Use it for all i/o debug
output.
2002-03-06 Werner Koch <wk@gnupg.org>
* assuan-client.c (_assuan_read_from_server): Detect END.
(assuan_transact): Pass it to the data callback.
2002-02-27 Werner Koch <wk@gnupg.org>
* assuan-client.c (assuan_transact): Add 2 more arguments to
support status lines. Passing NULL yields the old behaviour.
* assuan-handler.c (process_request): Flush data lines send
without using the data fp.
2002-02-14 Werner Koch <wk@gnupg.org>
* assuan-inquire.c (assuan_inquire): Check for a cancel command
and return ASSUAN_Canceled. Allow for non-data inquiry.
* assuan.h: Add a few token specific error codes.
2002-02-13 Werner Koch <wk@gnupg.org>
* assuan-defs.h (assuan_context_s): New var CLIENT_PID.
* assuan-pipe-server.c (_assuan_new_context): set default value.
* assuan-socket-server.c (accept_connection): get the actual pid.
2002-02-12 Werner Koch <wk@gnupg.org>
* assuan-buffer.c (writen,readline) [USE_GNU_PT]: Use pth_read/write.
* assuan-socket-server.c (accept_connection) [USE_GNU_PTH]: Ditto.
2002-02-01 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (MOSTLYCLEANFILES): New variable.
2002-01-23 Werner Koch <wk@gnupg.org>
* assuan-socket-connect.c (LOGERRORX): and removed typo.
2002-01-22 Marcus Brinkmann <marcus@g10code.de>
* assuan-socket-connect.c (LOGERRORX): Reverse arguments to fputs.
2002-01-21 Werner Koch <wk@gnupg.org>
* assuan-connect.c: Move all except assuan_get_pid to...
* assuan-pipe-connect.c: this.
(assuan_pipe_disconnect): Removed.
(do_finish, do_deinit): New
(assuan_pipe_connect): and set them into the context.
* assuan-socket-connect.c: New.
* assuan-util.c (_assuan_log_sanitized_string): New.
* assuan-pipe-server.c (assuan_init_pipe_server): Factored most
code out to ...
(_assuan_new_context): new func.
(_assuan_release_context): New
* assuan-connect.c (assuan_pipe_connect): Use the new functions.
2002-01-20 Werner Koch <wk@gnupg.org>
* assuan.h: Added Invalid Option error code.
* assuan-handler.c (std_handler_option): New.
(std_cmd_tbl): Add OPTION as standard command.
(assuan_register_option_handler): New.
(dispatch_command): Use case insensitive matching as a fallback.
(my_strcasecmp): New.
2002-01-19 Werner Koch <wk@gnupg.org>
* assuan-buffer.c (_assuan_read_line): Add output logging.
(assuan_write_line): Ditto.
(_assuan_cookie_write_data): Ditto.
(_assuan_cookie_write_flush): Ditto.
* assuan-util.c (_assuan_log_print_buffer): New.
(assuan_set_log_stream): New.
(assuan_begin_confidential): New.
(assuan_end_confidential): New.
* assuan-defs.h: Add a few handler variables.
* assuan-pipe-server.c (assuan_deinit_pipe_server): Removed.
(deinit_pipe_server): New.
(assuan_deinit_server): New. Changed all callers to use this.
* assuan-listen.c (assuan_accept): Use the accept handler.
* assuan-handler.c (process_request): Use the close Handler.
* assuan-socket-server.c: New.
2002-01-14 Werner Koch <wk@gnupg.org>
* assuan-client.c (_assuan_read_from_server): Skip spaces after
the keyword.
2002-01-03 Werner Koch <wk@gnupg.org>
* assuan-handler.c (assuan_set_okay_line): New.
(process_request): And use it here.
2002-01-02 Werner Koch <wk@gnupg.org>
* assuan-inquire.c (init_membuf,put_membuf,get_membuf): Apply a
hidden 0 behind the buffer so that the buffer can be used as a
string in certain contexts.
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
* assuan-connect.c (assuan_pipe_connect): New argument
FD_CHILD_LIST. Don't close those fds.
* assuan.h: Likewise for prototype.
2001-12-14 Werner Koch <wk@gnupg.org>
* assuan-listen.c (assuan_close_input_fd): New.
(assuan_close_output_fd): New.
* assuan-handler.c (std_handler_reset): Always close them after a
reset command.
(std_handler_bye): Likewise.
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
* assuan-buffer.c (_assuan_read_line): New variable ATTICLEN, use
it to save the length of the attic line.
Rediddle the code a bit to make it more clear what happens.
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
* assuan-defs.h (LINELENGTH): Define as ASSUAN_LINELENGTH.
assuan.h: Define ASSUAN_LINELENGTH.
2001-12-13 Marcus Brinkmann <marcus@g10code.de>
* assuan-buffer.c (assuan_read_line): Fix order of execution to
get correct return values.
2001-12-13 Werner Koch <wk@gnupg.org>
* assuan-handler.c (assuan_get_active_fds): Fixed silly bug,
pretty obvious that nobody ever tested this function.
2001-12-12 Werner Koch <wk@gnupg.org>
* assuan-connect.c (assuan_pipe_connect): Implemented the inital
handshake.
* assuan-client.c (read_from_server): Renamed to
(_assuan_read_from_server): this and made external.
* assuan-listen.c (assuan_set_hello_line): New.
(assuan_accept): Use a custom hello line is available.
* assuan-buffer.c (assuan_read_line): New.
(assuan_pending_line): New.
(_assuan_write_line): Renamed to ..
(assuan_write_line): this, made public and changed all callers.
2001-12-04 Werner Koch <wk@gnupg.org>
* assuan-connect.c (assuan_pipe_connect): Add more error reporting.
* assuan-client.c: New.
* assuan-inquire.c: New.
* assuan-handler.c (process_request): Check for nested invocations.
2001-11-27 Werner Koch <wk@gnupg.org>
* assuan-handler.c (assuan_register_input_notify): New.
(assuan_register_output_notify): New.
2001-11-26 Werner Koch <wk@gnupg.org>
* assuan.h: Added more status codes.
2001-11-25 Werner Koch <wk@gnupg.org>
* assuan-handler.c (assuan_register_bye_notify)
(assuan_register_reset_notify)
(assuan_register_cancel_notify): New and call them from the
standard handlers.
(assuan_process): Moved bulk of function to ..
(process_request): .. new.
(assuan_process_next): One shot version of above.
(assuan_get_active_fds): New.
2001-11-24 Werner Koch <wk@gnupg.org>
* assuan-connect.c (assuan_get_pid): New.
* assuan-buffer.c (_assuan_read_line): Deal with reads of more
than a line.
* assuan-defs.h: Add space in the context for this.
Copyright 2001, 2002 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,53 @@
# Assuan Makefile
# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
#
# This file is part of Assuan.
#
# Assuan is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Assuan is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 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
AM_CPPFLAGS = -D_ASSUAN_IN_GPGME_BUILD_ASSUAN
#libassuan_la_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-io.c \
assuan-domain-connect.c \
assuan-domain-server.c \
assuan-logging.c
assuan-errors.c : assuan.h
$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c

View File

@ -0,0 +1,25 @@
This is a modified copy of the libassuan library. Don't modify it,
but instead modify the original Assuan library and merge the changes
back into this copy.
The changes to the original libassuan, that have to preserved when
updating this directory, are:
* Makefile.am
** Build the library with libtool as a convenience library, which can
be linked into the shared library GPGME.
** Do not install the library or the header file.
** Define -D_ASSUAN_IN_GPGME_BUILD_ASSUAN to wrap some POSIX functions
with ATH replacements.
* assuan.h
** Define _ASSUAN_IN_GPGME to enable GPGME specific code.
** Put all exported Assuan functions in the _gpgme namespace.
** Also wrap all system functions that are wrapped by GNU Pth to
_gpgme wrappers.
* assuan-io.c
** Don't try to support GNU Pth here.
* assuan-pipe-connect.c
** Do not install SIGPIPE signal handler here.

View File

@ -0,0 +1,448 @@
/* assuan-buffer.c - read and send data
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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>
#include "assuan-defs.h"
static int
writen (ASSUAN_CONTEXT ctx, const char *buffer, size_t length)
{
while (length)
{
ssize_t nwritten = ctx->io->write (ctx, buffer, length);
if (nwritten < 0)
{
if (errno == EINTR)
continue;
return -1; /* write error */
}
length -= nwritten;
buffer += nwritten;
}
return 0; /* okay */
}
/* Read an entire line. */
static int
readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen,
int *r_nread, int *eof)
{
size_t nleft = buflen;
char *p;
*eof = 0;
*r_nread = 0;
while (nleft > 0)
{
ssize_t n = ctx->io->read (ctx, buf, nleft);
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;
p = memrchr (p, '\n', n);
if (p)
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 nread, atticlen;
int rc;
char *endp = 0;
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;
endp = memchr (line, '\n', atticlen);
if (endp)
/* Found another line in the attic. */
{
rc = 0;
nread = atticlen;
atticlen = 0;
}
else
/* There is pending data but not a full line. */
{
assert (atticlen < LINELENGTH);
rc = readline (ctx, line + atticlen,
LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
}
}
else
/* No pending data. */
rc = readline (ctx, line, LINELENGTH,
&nread, &ctx->inbound.eof);
if (rc)
{
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
assuan_get_assuan_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",
assuan_get_assuan_log_prefix (), ctx);
return -1;
}
ctx->inbound.attic.pending = 0;
nread += atticlen;
if (! endp)
endp = memchr (line, '\n', nread);
if (endp)
{
int n = endp - line + 1;
if (n < nread)
/* LINE contains more than one line. We copy it to the attic
now as handlers are allowed to modify the passed
buffer. */
{
int len = nread - n;
memcpy (ctx->inbound.attic.line, endp + 1, len);
ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0;
ctx->inbound.attic.linelen = len;
}
if (endp != line && endp[-1] == '\r')
endp --;
*endp = 0;
ctx->inbound.linelen = endp - line;
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] <- ",
assuan_get_assuan_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;
}
else
{
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n",
assuan_get_assuan_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
in *LINE to a buffer holding the line. LINELEN is the length of
*LINE. The buffer is valid until the next read operation on it.
The caller may modify the buffer. The buffer is invalid (i.e. must
not be used) if an error is returned.
Returns 0 on success or an assuan error code.
See also: assuan_pending_line().
*/
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 if a full line is buffered (i.e. an entire line may be
read without any I/O). */
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;
size_t len;
const char *s;
if (!ctx)
return ASSUAN_Invalid_Value;
/* Make sure that we never take a LF from the user - this might
violate the protocol. */
s = strchr (line, '\n');
len = s? (s-line) : strlen (line);
/* fixme: we should do some kind of line buffering. */
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] -> ",
assuan_get_assuan_log_prefix (), ctx);
if (s)
fputs ("[supplied line contained a LF]", ctx->log_fp);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
_assuan_log_print_buffer (ctx->log_fp, line, len);
putc ('\n', ctx->log_fp);
}
rc = writen (ctx, line, len);
if (rc)
rc = ASSUAN_Write_Error;
if (!rc)
{
rc = writen (ctx, "\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] -> ",
assuan_get_assuan_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, 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] -> ",
assuan_get_assuan_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, 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;
}
AssuanError
assuan_sendfd (ASSUAN_CONTEXT ctx, int fd)
{
if (! ctx->io->sendfd)
return set_error (ctx, Not_Implemented,
"server does not support sending and receiving "
"of file descriptors");
return ctx->io->sendfd (ctx, fd);
}
AssuanError
assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd)
{
if (! ctx->io->receivefd)
return set_error (ctx, Not_Implemented,
"server does not support sending and receiving "
"of file descriptors");
return ctx->io->receivefd (ctx, fd);
}

View File

@ -0,0 +1,225 @@
/* assuan-client.c - client functions
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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, 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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,194 @@
/* assuan-defs.c - Internal definitions to Assuan
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef ASSUAN_DEFS_H
#define ASSUAN_DEFS_H
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "assuan.h"
#define LINELENGTH ASSUAN_LINELENGTH
struct cmdtbl_s
{
const char *name;
int (*handler)(ASSUAN_CONTEXT, char *line);
};
struct assuan_io
{
/* Routine to read from input_fd. */
ssize_t (*read) (ASSUAN_CONTEXT, void *, size_t);
/* Routine to write to output_fd. */
ssize_t (*write) (ASSUAN_CONTEXT, const void *, size_t);
/* Send a file descriptor. */
AssuanError (*sendfd) (ASSUAN_CONTEXT, int);
/* Receive a file descriptor. */
AssuanError (*receivefd) (ASSUAN_CONTEXT, int *);
};
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) */
int connected_fd; /* helper */
pid_t client_pid; /* for a socket server the PID of the client or -1
if not available */
/* Used for Unix domain sockets. */
struct sockaddr_un myaddr;
struct sockaddr_un serveraddr;
/* When reading from datagram sockets, we must read an entire
message at a time. This means that we have to do our own
buffering to be able to get the semantics of read. */
void *domainbuffer;
/* Offset of start of buffer. */
int domainbufferoffset;
/* Bytes buffered. */
int domainbuffersize;
/* Memory allocated. */
int domainbufferallocated;
int *pendingfds;
int pendingfdscount;
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 */
/* io routines. */
struct assuan_io *io;
};
/*-- assuan-pipe-server.c --*/
int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
void _assuan_release_context (ASSUAN_CONTEXT ctx);
/*-- assuan-domain-connect.c --*/
/* Make a connection to the Unix domain socket NAME and return a new
Assuan context in CTX. SERVER_PID is currently not used but may
become handy in the future. */
AssuanError _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
int rendezvousfd,
pid_t peer);
/*-- 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);
/*-- assuan-io.c --*/
ssize_t _assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size);
ssize_t _assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer,
size_t size);
#ifdef HAVE_FOPENCOOKIE
/* We have to implement funopen in terms of glibc's fopencookie. */
FILE *funopen(const void *cookie, cookie_read_function_t *readfn,
cookie_write_function_t *writefn,
cookie_seek_function_t *seekfn,
cookie_close_function_t *closefn);
#endif /*HAVE_FOPENCOOKIE*/
#endif /*ASSUAN_DEFS_H*/

View File

@ -0,0 +1,472 @@
/* assuan-domain-connect.c - Assuan unix domain socket based client
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include "assuan-defs.h"
#define LOG(format, args...) \
fprintf (assuan_get_assuan_log_stream (), \
assuan_get_assuan_log_prefix (), \
"%s" format , ## args)
static void
do_deinit (ASSUAN_CONTEXT ctx)
{
if (ctx->inbound.fd != -1)
close (ctx->inbound.fd);
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
if (ctx->domainbuffer)
{
assert (ctx->domainbufferallocated);
free (ctx->domainbuffer);
}
if (ctx->pendingfds)
{
int i;
assert (ctx->pendingfdscount > 0);
for (i = 0; i < ctx->pendingfdscount; i ++)
close (ctx->pendingfds[i]);
free (ctx->pendingfds);
}
unlink (ctx->myaddr.sun_path);
}
/* Read from the socket server. */
static ssize_t
domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
{
int len = ctx->domainbuffersize;
start:
if (len == 0)
/* No data is buffered. */
{
struct msghdr msg;
struct iovec iovec;
struct sockaddr_un sender;
struct
{
struct cmsghdr hdr;
int fd;
}
cmsg;
memset (&msg, 0, sizeof (msg));
for (;;)
{
msg.msg_name = &sender;
msg.msg_namelen = sizeof (struct sockaddr_un);
msg.msg_iov = &iovec;
msg.msg_iovlen = 1;
iovec.iov_base = ctx->domainbuffer;
iovec.iov_len = ctx->domainbufferallocated;
msg.msg_control = &cmsg;
msg.msg_controllen = sizeof cmsg;
/* Peek first: if the buffer we have is too small then it
will be truncated. */
len = recvmsg (ctx->inbound.fd, &msg, MSG_PEEK);
if (len < 0)
{
printf ("domain_reader: %m\n");
return -1;
}
if (strcmp (ctx->serveraddr.sun_path,
((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
{
/* XXX: Arg. Not from whom we expected! What do we
want to do? Should we just ignore it? Either way,
we still need to consume the message. */
break;
}
if (msg.msg_flags & MSG_TRUNC)
/* Enlarge the buffer and try again. */
{
int size = ctx->domainbufferallocated;
void *tmp;
if (size == 0)
size = 4 * 1024;
else
size *= 2;
tmp = malloc (size);
if (! tmp)
return -1;
free (ctx->domainbuffer);
ctx->domainbuffer = tmp;
ctx->domainbufferallocated = size;
}
else
/* We have enough space! */
break;
}
/* Now we have to actually consume it (remember, we only
peeked). */
msg.msg_name = &sender;
msg.msg_namelen = sizeof (struct sockaddr_un);
msg.msg_iov = &iovec;
msg.msg_iovlen = 1;
iovec.iov_base = ctx->domainbuffer;
iovec.iov_len = ctx->domainbufferallocated;
msg.msg_control = &cmsg;
msg.msg_controllen = sizeof cmsg;
if (strcmp (ctx->serveraddr.sun_path,
((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
{
/* XXX: Arg. Not from whom we expected! What do we want to
do? Should we just ignore it? We shall do the latter
for the moment. */
LOG ("Not setup to receive messages from: `%s'.",
((struct sockaddr_un *) msg.msg_name)->sun_path);
goto start;
}
len = recvmsg (ctx->inbound.fd, &msg, 0);
if (len < 0)
{
LOG ("domain_reader: %s\n", strerror (errno));
return -1;
}
ctx->domainbuffersize = len;
ctx->domainbufferoffset = 0;
if (sizeof (cmsg) == msg.msg_controllen)
/* We received a file descriptor. */
{
void *tmp;
tmp = realloc (ctx->pendingfds,
sizeof (int) * (ctx->pendingfdscount + 1));
if (! tmp)
{
LOG ("domain_reader: %s\n", strerror (errno));
return -1;
}
ctx->pendingfds = tmp;
ctx->pendingfds[ctx->pendingfdscount++]
= *(int *) CMSG_DATA (&cmsg.hdr);
LOG ("Received file descriptor %d from peer.\n",
ctx->pendingfds[ctx->pendingfdscount - 1]);
}
if (len == 0)
goto start;
}
/* Return some data to the user. */
if (len > buflen)
/* We have more than the user requested. */
len = buflen;
memcpy (buf, ctx->domainbuffer + ctx->domainbufferoffset, len);
ctx->domainbuffersize -= len;
assert (ctx->domainbuffersize >= 0);
ctx->domainbufferoffset += len;
assert (ctx->domainbufferoffset <= ctx->domainbufferallocated);
return len;
}
/* Write to the domain server. */
static ssize_t
domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen)
{
struct msghdr msg;
struct iovec iovec;
ssize_t len;
memset (&msg, 0, sizeof (msg));
msg.msg_name = &ctx->serveraddr;
msg.msg_namelen = offsetof (struct sockaddr_un, sun_path)
+ strlen (ctx->serveraddr.sun_path) + 1;
msg.msg_iovlen = 1;
msg.msg_iov = &iovec;
iovec.iov_base = (void *) buf;
iovec.iov_len = buflen;
msg.msg_control = 0;
msg.msg_controllen = 0;
len = sendmsg (ctx->outbound.fd, &msg, 0);
if (len < 0)
LOG ("domain_writer: %s\n", strerror (errno));
return len;
}
static AssuanError
domain_sendfd (ASSUAN_CONTEXT ctx, int fd)
{
struct msghdr msg;
struct
{
struct cmsghdr hdr;
int fd;
}
cmsg;
int len;
memset (&msg, 0, sizeof (msg));
msg.msg_name = &ctx->serveraddr;
msg.msg_namelen = offsetof (struct sockaddr_un, sun_path)
+ strlen (ctx->serveraddr.sun_path) + 1;
msg.msg_iovlen = 0;
msg.msg_iov = 0;
cmsg.hdr.cmsg_level = SOL_SOCKET;
cmsg.hdr.cmsg_type = SCM_RIGHTS;
cmsg.hdr.cmsg_len = sizeof (cmsg);
msg.msg_control = &cmsg;
msg.msg_controllen = sizeof (cmsg);
*(int *) CMSG_DATA (&cmsg.hdr) = fd;
len = sendmsg (ctx->outbound.fd, &msg, 0);
if (len < 0)
{
LOG ("domain_sendfd: %s\n", strerror (errno));
return ASSUAN_General_Error;
}
else
return 0;
}
static AssuanError
domain_receivefd (ASSUAN_CONTEXT ctx, int *fd)
{
if (ctx->pendingfds == 0)
{
LOG ("No pending file descriptors!\n");
return ASSUAN_General_Error;
}
*fd = ctx->pendingfds[0];
if (-- ctx->pendingfdscount == 0)
{
free (ctx->pendingfds);
ctx->pendingfds = 0;
}
else
/* Fix the array. */
{
memmove (ctx->pendingfds, ctx->pendingfds + 1,
ctx->pendingfdscount * sizeof (int));
ctx->pendingfds = realloc (ctx->pendingfds,
ctx->pendingfdscount * sizeof (int));
}
return 0;
}
/* Make a connection to the Unix domain socket NAME and return a new
Assuan context in CTX. SERVER_PID is currently not used but may
become handy in the future. */
AssuanError
_assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer)
{
static struct assuan_io io = { domain_reader, domain_writer,
domain_sendfd, domain_receivefd };
AssuanError err;
ASSUAN_CONTEXT ctx;
int fd;
size_t len;
int tries;
if (!r_ctx)
return ASSUAN_Invalid_Value;
*r_ctx = NULL;
err = _assuan_new_context (&ctx);
if (err)
return err;
/* Save it in case we need it later. */
ctx->pid = peer;
/* Override the default (NOP) handlers. */
ctx->deinit_handler = do_deinit;
/* Setup the socket. */
fd = socket (PF_LOCAL, SOCK_DGRAM, 0);
if (fd == -1)
{
LOG ("can't create socket: %s\n", strerror (errno));
_assuan_release_context (ctx);
return ASSUAN_General_Error;
}
ctx->inbound.fd = fd;
ctx->outbound.fd = fd;
/* And the io buffers. */
ctx->io = &io;
ctx->domainbuffer = 0;
ctx->domainbufferoffset = 0;
ctx->domainbuffersize = 0;
ctx->domainbufferallocated = 0;
ctx->pendingfds = 0;
ctx->pendingfdscount = 0;
/* Get usable name and bind to it. */
for (tries = 0; tries < TMP_MAX; tries ++)
{
char *p;
char buf[L_tmpnam];
/* XXX: L_tmpnam must be shorter than sizeof (sun_path)! */
assert (L_tmpnam < sizeof (ctx->myaddr.sun_path));
p = tmpnam (buf);
if (! p)
{
LOG ("cannot determine an appropriate temporary file "
"name. DOS in progress?\n");
_assuan_release_context (ctx);
close (fd);
return ASSUAN_General_Error;
}
memset (&ctx->myaddr, 0, sizeof ctx->myaddr);
ctx->myaddr.sun_family = AF_LOCAL;
len = strlen (buf) + 1;
memcpy (ctx->myaddr.sun_path, buf, len);
len += offsetof (struct sockaddr_un, sun_path);
err = bind (fd, (struct sockaddr *) &ctx->myaddr, len);
if (! err)
break;
}
if (err)
{
LOG ("can't bind to `%s': %s\n", ctx->myaddr.sun_path,
strerror (errno));
_assuan_release_context (ctx);
close (fd);
return ASSUAN_Connect_Failed;
}
/* Rendezvous with our peer. */
{
FILE *fp;
char *p;
fp = fdopen (rendezvousfd, "w+");
if (! fp)
{
LOG ("can't open rendezvous port: %s\n", strerror (errno));
return ASSUAN_Connect_Failed;
}
/* Send our address. */
fprintf (fp, "%s\n", ctx->myaddr.sun_path);
fflush (fp);
/* And receive our peer's. */
memset (&ctx->serveraddr, 0, sizeof ctx->serveraddr);
for (p = ctx->serveraddr.sun_path;
p < (ctx->serveraddr.sun_path
+ sizeof ctx->serveraddr.sun_path - 1);
p ++)
{
*p = fgetc (fp);
if (*p == '\n')
break;
}
*p = '\0';
fclose (fp);
ctx->serveraddr.sun_family = AF_LOCAL;
}
*r_ctx = ctx;
return 0;
}
AssuanError
assuan_domain_connect (ASSUAN_CONTEXT * r_ctx, int rendezvousfd, pid_t peer)
{
AssuanError aerr;
int okay, off;
aerr = _assuan_domain_init (r_ctx, rendezvousfd, peer);
if (aerr)
return aerr;
/* Initial handshake. */
aerr = _assuan_read_from_server (*r_ctx, &okay, &off);
if (aerr)
LOG ("can't connect to server: %s\n", assuan_strerror (aerr));
else if (okay != 1)
{
LOG ("can't connect to server: `");
_assuan_log_sanitized_string ((*r_ctx)->inbound.line);
fprintf (assuan_get_assuan_log_stream (), "'\n");
aerr = ASSUAN_Connect_Failed;
}
if (aerr)
assuan_disconnect (*r_ctx);
return aerr;
}

View File

@ -0,0 +1,46 @@
/* assuan-socket-server.c - Assuan socket based server
* Copyright (C) 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <unistd.h>
#include "assuan-defs.h"
/* Initialize a server. */
AssuanError
assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
int rendezvousfd,
pid_t peer)
{
AssuanError err;
err = _assuan_domain_init (r_ctx, rendezvousfd, peer);
if (err)
return err;
(*r_ctx)->is_server = 1;
/* A domain server can only be used once. */
(*r_ctx)->pipe_mode = 1;
return 0;
}

View File

@ -0,0 +1,690 @@
/* assuan-handler.c - dispatch commands
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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 my_strcasecmp (const char *a, const char *b);
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);
}
AssuanError
assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd)
{
char *endp;
if (strncmp (line, "FD", 2) != 0 || (line[2] != '=' && line[2] != '\0'))
return set_error (ctx, Syntax_Error, "FD[=<n>] expected");
line += 2;
if (*line == '=')
{
line ++;
if (!digitp (*line))
return set_error (ctx, Syntax_Error, "number required");
*rfd = strtoul (line, &endp, 10);
/* remove that argument so that a notify handler won't see it */
memset (line, ' ', endp? (endp-line):strlen(line));
if (*rfd == ctx->inbound.fd)
return set_error (ctx, Parameter_Conflict, "fd same as inbound fd");
if (*rfd == ctx->outbound.fd)
return set_error (ctx, Parameter_Conflict, "fd same as outbound fd");
return 0;
}
else
/* Our peer has sent the file descriptor. */
return assuan_receivefd (ctx, rfd);
}
/* Format is INPUT FD=<n> */
static int
std_handler_input (ASSUAN_CONTEXT ctx, char *line)
{
int rc, fd;
rc = assuan_command_parse_fd (ctx, line, &fd);
if (rc)
return rc;
ctx->input_fd = fd;
if (ctx->input_notify_fnc)
ctx->input_notify_fnc (ctx, line);
return 0;
}
/* Format is OUTPUT FD=<n> */
static int
std_handler_output (ASSUAN_CONTEXT ctx, char *line)
{
int rc, fd;
rc = assuan_command_parse_fd (ctx, line, &fd);
if (rc)
return rc;
ctx->output_fd = fd;
if (ctx->output_notify_fnc)
ctx->output_notify_fnc (ctx, line);
return 0;
}
/* This is a table with the standard commands and handler for them.
The table is used to initialize a new context and associate strings
with default handlers */
static struct {
const char *name;
int (*handler)(ASSUAN_CONTEXT, char *line);
int always; /* always initialize this command */
} std_cmd_table[] = {
{ "NOP", std_handler_nop, 1 },
{ "CANCEL", std_handler_cancel, 1 },
{ "OPTION", std_handler_option, 1 },
{ "BYE", std_handler_bye, 1 },
{ "AUTH", std_handler_auth, 1 },
{ "RESET", std_handler_reset, 1 },
{ "END", std_handler_end, 1 },
{ "INPUT", std_handler_input },
{ "OUTPUT", std_handler_output },
{ "OPTION", std_handler_option, 1 },
{ NULL }
};
/**
* assuan_register_command:
* @ctx: the server context
* @cmd_name: A string with the command name
* @handler: The handler function to be called or NULL to use a default
* handler.
*
* Register a handler to be used for a given command. Note that
* several default handlers are already regsitered with a new context.
* This function however allows to override them.
*
* Return value: 0 on success or an error code
**/
int
assuan_register_command (ASSUAN_CONTEXT ctx,
const char *cmd_name,
int (*handler)(ASSUAN_CONTEXT, char *))
{
int i;
const char *s;
if (cmd_name && !*cmd_name)
cmd_name = NULL;
if (!cmd_name)
return ASSUAN_Invalid_Value;
if (!handler)
{ /* find a default handler. */
for (i=0; (s=std_cmd_table[i].name) && strcmp (cmd_name, s); i++)
;
if (!s)
{ /* Try again but case insensitive. */
for (i=0; (s=std_cmd_table[i].name)
&& my_strcasecmp (cmd_name, s); i++)
;
}
if (s)
handler = std_cmd_table[i].handler;
if (!handler)
handler = dummy_handler; /* Last resort is the dummy handler. */
}
if (!ctx->cmdtbl)
{
ctx->cmdtbl_size = 50;
ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl);
if (!ctx->cmdtbl)
return ASSUAN_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].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].name, NULL);
if (rc)
return rc;
}
}
return 0;
}
/* Process the special data lines. The "D " has already been removed
from the line. As all handlers this function may modify the line. */
static int
handle_data_line (ASSUAN_CONTEXT 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)
{
#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN)
if (ctx->outbound.data.fp)
return ctx->outbound.data.fp;
ctx->outbound.data.fp = funopen (ctx, 0,
_assuan_cookie_write_data,
0, _assuan_cookie_write_flush);
ctx->outbound.data.error = 0;
return ctx->outbound.data.fp;
#else
errno = ENOSYS;
return NULL;
#endif
}
/* Set the text used for the next OK reponse. This string is
automatically reset to NULL after the next command. */
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,240 @@
/* assuan-inquire.c - handle inquire stuff
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */
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,58 @@
/* assuan-io.c - Wraps the read and write functions.
* Copyright (C) 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "assuan-defs.h"
#include <sys/types.h>
#include <unistd.h>
#ifdef _ASSUAN_IN_GPGME
ssize_t
_assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size)
{
return read (ctx->inbound.fd, buffer, size);
}
ssize_t
_assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer, size_t size)
{
return write (ctx->outbound.fd, buffer, size);
}
#else
extern ssize_t pth_read (int fd, void *buffer, size_t size);
extern ssize_t pth_write (int fd, const void *buffer, size_t size);
#pragma weak pth_read
#pragma weak pth_write
ssize_t
_assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size)
{
return (pth_read ? pth_read : read) (ctx->inbound.fd, buffer, size);
}
ssize_t
_assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer, size_t size)
{
return (pth_write ? pth_write : write) (ctx->outbound.fd, buffer, size);
}
#endif

View File

@ -0,0 +1,132 @@
/* assuan-listen.c - Wait for a connection (server)
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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 connection and wait for a connection from a
* client. The initial handshake is performed which may include an
* initial authentication or encryption negotiation.
*
* Return value: 0 on success or an error if the connection could for
* some reason not be established.
**/
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,42 @@
/* assuan-logging.c - Default logging function.
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "assuan-defs.h"
#include <stdio.h>
static FILE *_assuan_log;
void
assuan_set_assuan_log_stream (FILE *fp)
{
_assuan_log = fp;
}
FILE *
assuan_get_assuan_log_stream (void)
{
return _assuan_log ? _assuan_log : stderr;
}
const char *
assuan_get_assuan_log_prefix (void)
{
return "";
}

View File

@ -0,0 +1,285 @@
/* assuan-pipe-connect.c - Establish a pipe connection (client)
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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 <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "assuan-defs.h"
#ifdef _POSIX_OPEN_MAX
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
#else
#define MAX_OPEN_FDS 20
#endif
#define LOG(format, args...) \
fprintf (assuan_get_assuan_log_stream (), \
assuan_get_assuan_log_prefix (), \
"%s" format , ## args)
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_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
int *fd_child_list)
{
#ifndef _ASSUAN_IN_GPGME
static int fixed_signals = 0;
#endif
AssuanError err;
int rp[2];
int wp[2];
if (!ctx || !name || !argv || !argv[0])
return ASSUAN_Invalid_Value;
#ifndef _ASSUAN_IN_GPGME
if (!fixed_signals)
{
struct sigaction act;
sigaction (SIGPIPE, NULL, &act);
if (act.sa_handler == SIG_DFL)
{
act.sa_handler = SIG_IGN;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
sigaction (SIGPIPE, &act, NULL);
}
fixed_signals = 1;
/* FIXME: This is not MT safe */
}
#endif
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];
int *fdp;
/* Dup handles to stdin/stdout. */
if (rp[1] != STDOUT_FILENO)
{
if (dup2 (rp[1], STDOUT_FILENO) == -1)
{
LOG ("dup2 failed in child: %s\n", strerror (errno));
_exit (4);
}
}
if (wp[0] != STDIN_FILENO)
{
if (dup2 (wp[0], STDIN_FILENO) == -1)
{
LOG ("dup2 failed in child: %s\n", strerror (errno));
_exit (4);
}
}
/* Dup stderr to /dev/null unless it is in the list of FDs to be
passed to the child. */
fdp = fd_child_list;
if (fdp)
{
for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++)
;
}
if (!fdp || *fdp == -1)
{
int fd = open ("/dev/null", O_WRONLY);
if (fd == -1)
{
LOG ("can't open `/dev/null': %s\n", strerror (errno));
_exit (4);
}
if (dup2 (fd, STDERR_FILENO) == -1)
{
LOG ("dup2(dev/null, 2) failed: %s\n", strerror (errno));
_exit (4);
}
}
/* Close all files which will not be duped and are not in the
fd_child_list. */
n = sysconf (_SC_OPEN_MAX);
if (n < 0)
n = MAX_OPEN_FDS;
for (i=0; i < n; i++)
{
if ( i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO)
continue;
fdp = fd_child_list;
if (fdp)
{
while (*fdp != -1 && *fdp != i)
fdp++;
}
if (!(fdp && *fdp != -1))
close(i);
}
errno = 0;
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)
LOG ("can't connect server: %s\n", assuan_strerror (err));
else if (okay != 1)
{
LOG ("can't connect server: `%s'\n", (*ctx)->inbound.line);
err = ASSUAN_Connect_Failed;
}
}
if (err)
{
assuan_disconnect (*ctx);
*ctx = NULL;
}
return err;
}

View File

@ -0,0 +1,129 @@
/* assuan-pipe-server.c - Assuan server working over a pipe
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.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 way we don't need extra dummy functions */
int
_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
{
static struct assuan_io io = { _assuan_simple_read,
_assuan_simple_write,
0, 0 };
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->io = &io;
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,137 @@
/* assuan-socket-connect.c - Assuan socket based client
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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"
#define LOG(format, args...) \
fprintf (assuan_get_assuan_log_stream (), \
assuan_get_assuan_log_prefix (), \
"%s" format , ## args)
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
become handy in the future. */
AssuanError
assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
const char *name, pid_t server_pid)
{
static struct assuan_io io = { _assuan_simple_read,
_assuan_simple_write };
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 (PF_LOCAL, SOCK_STREAM, 0);
if (fd == -1)
{
LOG ("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_LOCAL;
len = strlen (srvr_addr.sun_path) + 1;
memcpy (srvr_addr.sun_path, name, len);
len += (offsetof (struct sockaddr_un, sun_path));
if (connect (fd, (struct sockaddr *) &srvr_addr, len) == -1)
{
LOG ("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;
ctx->io = &io;
/* initial handshake */
{
int okay, off;
err = _assuan_read_from_server (ctx, &okay, &off);
if (err)
LOG ("can't connect to server: %s\n", assuan_strerror (err));
else if (okay != 1)
{
LOG ("can't connect to server: `");
_assuan_log_sanitized_string (ctx->inbound.line);
fprintf (assuan_get_assuan_log_stream (), "'\n");
err = ASSUAN_Connect_Failed;
}
}
if (err)
{
assuan_disconnect (ctx);
}
else
*r_ctx = ctx;
return 0;
}

View File

@ -0,0 +1,174 @@
/* assuan-socket-server.c - Assuan socket based server
* Copyright (C) 2002 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 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>
#include "assuan-defs.h"
static int
accept_connection_bottom (ASSUAN_CONTEXT ctx)
{
int fd = ctx->connected_fd;
ctx->client_pid = (pid_t)-1;
#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
accept_connection (ASSUAN_CONTEXT ctx)
{
int fd;
struct sockaddr_un clnt_addr;
size_t len = sizeof clnt_addr;
ctx->client_pid = (pid_t)-1;
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
if (fd == -1)
{
ctx->os_errno = errno;
return ASSUAN_Accept_Failed;
}
ctx->connected_fd = fd;
return accept_connection_bottom (ctx);
}
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);
}
static struct assuan_io io = { _assuan_simple_read,
_assuan_simple_write };
/* 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->connected_fd = -1;
ctx->deinit_handler = deinit_socket_server;
ctx->accept_handler = accept_connection;
ctx->finish_handler = finish_connection;
ctx->io = &io;
rc = _assuan_register_std_commands (ctx);
if (rc)
xfree (ctx);
else
*r_ctx = ctx;
return rc;
}
/* Initialize a server using the already accepted socket FD. */
int
assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int 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->pipe_mode = 1; /* we want a second accept to indicate EOF */
ctx->input_fd = -1;
ctx->output_fd = -1;
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
ctx->io = &io;
ctx->listen_fd = -1;
ctx->connected_fd = fd;
ctx->deinit_handler = deinit_socket_server;
ctx->accept_handler = accept_connection_bottom;
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,219 @@
/* assuan-util.c - Utility functions for Assuan
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "assuan-defs.h"
static void *(*alloc_func)(size_t n) = malloc;
static void *(*realloc_func)(void *p, size_t n) = realloc;
static void (*free_func)(void*) = free;
void
assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
void *(*new_realloc_func)(void *p, size_t n),
void (*new_free_func)(void*) )
{
alloc_func = new_alloc_func;
realloc_func = new_realloc_func;
free_func = new_free_func;
}
void *
_assuan_malloc (size_t n)
{
return alloc_func (n);
}
void *
_assuan_realloc (void *a, size_t n)
{
return realloc_func (a, n);
}
void *
_assuan_calloc (size_t n, size_t m)
{
void *p = _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;
}
}
/* Dump a possibly binary string (used for debugging). Distinguish
ascii text from binary and print it accordingly. */
void
_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
{
const unsigned char *s;
int n;
for (n=length,s=buffer; n; n--, s++)
if (!isascii (*s) || iscntrl (*s) || !isprint (*s))
break;
s = buffer;
if (!n && *s != '[')
fwrite (buffer, length, 1, fp);
else
{
#ifdef HAVE_FLOCKFILE
flockfile (fp);
#endif
putc_unlocked ('[', fp);
for (n=0; n < length; n++, s++)
fprintf (fp, " %02x", *s);
putc_unlocked (' ', fp);
putc_unlocked (']', fp);
#ifdef HAVE_FUNLOCKFILE
funlockfile (fp);
#endif
}
}
/* Log a user supplied string. Escapes non-printable before
printing. */
void
_assuan_log_sanitized_string (const char *string)
{
const unsigned char *s = string;
FILE *fp = assuan_get_assuan_log_stream ();
if (! *s)
return;
#ifdef HAVE_FLOCKFILE
flockfile (fp);
#endif
for (; *s; s++)
{
int c = 0;
switch (*s)
{
case '\r':
c = 'r';
break;
case '\n':
c = 'n';
break;
case '\f':
c = 'f';
break;
case '\v':
c = 'v';
break;
case '\b':
c = 'b';
break;
default:
if (isascii (*s) && isprint (*s))
putc_unlocked (*s, fp);
else
{
putc_unlocked ('\\', fp);
fprintf (fp, "x%02x", *s);
}
}
if (c)
{
putc_unlocked ('\\', fp);
putc_unlocked (c, fp);
}
}
#ifdef HAVE_FUNLOCKFILE
funlockfile (fp);
#endif
}

View File

@ -0,0 +1,394 @@
/* assuan.c - Definitions for the Assuan protocol
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
* Assuan is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Assuan is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef ASSUAN_H
#define ASSUAN_H
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#define _ASSUAN_IN_GPGME
#ifdef _ASSUAN_IN_GPGME
#define _ASSUAN_EXT_SYM_PREFIX _gpgme_
#ifdef _ASSUAN_IN_GPGME_BUILD_ASSUAN
int _gpgme_io_read (int fd, void *buffer, size_t count);
int _gpgme_io_write (int fd, const void *buffer, size_t count);
ssize_t _gpgme_ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout);
ssize_t _gpgme_ath_waitpid (pid_t pid, int *status, int options);
int _gpgme_ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length);
int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags);
int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
#define read _gpgme_io_read
#define write _gpgme_io_write
#define waitpid _gpgme_ath_waitpid
#define select _gpgme_ath_select
#define accept _gpgme_ath_accept
#define connect _gpgme_ath_connect
#define sendmsg _gpgme_ath_sendmsg
#define recvmsg _gpgme_ath_recvmsg
#endif
#endif
#ifdef _ASSUAN_EXT_SYM_PREFIX
#define _ASSUAN_PREFIX1(x,y) x ## y
#define _ASSUAN_PREFIX2(x,y) _ASSUAN_PREFIX1(x,y)
#define _ASSUAN_PREFIX(x) _ASSUAN_PREFIX2(_ASSUAN_EXT_SYM_PREFIX,x)
#define assuan_ _ASSUAN_PREFIX(assuan_)
#define assuan_register_command _ASSUAN_PREFIX(assuan_register_command)
#define assuan_register_bye_notify _ASSUAN_PREFIX(assuan_register_bye_notify)
#define assuan_register_reset_notify \
_ASSUAN_PREFIX(assuan_register_reset_notify)
#define assuan_register_cancel_notify \
_ASSUAN_PREFIX(assuan_register_cancel_notify)
#define assuan_register_input_notify \
_ASSUAN_PREFIX(assuan_register_input_notify)
#define assuan_register_output_notify \
_ASSUAN_PREFIX(assuan_register_output_notify)
#define assuan_register_option_handler \
_ASSUAN_PREFIX(assuan_register_option_handler)
#define assuan_process _ASSUAN_PREFIX(assuan_process)
#define assuan_process_next _ASSUAN_PREFIX(assuan_process_next)
#define assuan_get_active_fds _ASSUAN_PREFIX(assuan_get_active_fds)
#define assuan_get_data_fp _ASSUAN_PREFIX(assuan_get_data_fp)
#define assuan_set_okay_line _ASSUAN_PREFIX(assuan_set_okay_line)
#define assuan_write_status _ASSUAN_PREFIX(assuan_write_status)
#define assuan_command_parse_fd _ASSUAN_PREFIX(assuan_command_parse_fd)
#define assuan_set_hello_line _ASSUAN_PREFIX(assuan_set_hello_line)
#define assuan_accept _ASSUAN_PREFIX(assuan_accept)
#define assuan_get_input_fd _ASSUAN_PREFIX(assuan_get_input_fd)
#define assuan_get_output_fd _ASSUAN_PREFIX(assuan_get_output_fd)
#define assuan_close_input_fd _ASSUAN_PREFIX(assuan_close_input_fd)
#define assuan_close_output_fd _ASSUAN_PREFIX(assuan_close_output_fd)
#define assuan_init_pipe_server _ASSUAN_PREFIX(assuan_init_pipe_server)
#define assuan_deinit_server _ASSUAN_PREFIX(assuan_deinit_server)
#define assuan_init_socket_server _ASSUAN_PREFIX(assuan_init_socket_server)
#define assuan_init_connected_socket_server \
_ASSUAN_PREFIX(assuan_init_connected_socket_server)
#define assuan_pipe_connect _ASSUAN_PREFIX(assuan_pipe_connect)
#define assuan_socket_connect _ASSUAN_PREFIX(assuan_socket_connect)
#define assuan_domain_connect _ASSUAN_PREFIX(assuan_domain_connect)
#define assuan_init_domain_server _ASSUAN_PREFIX(assuan_init_domain_server)
#define assuan_disconnect _ASSUAN_PREFIX(assuan_disconnect)
#define assuan_get_pid _ASSUAN_PREFIX(assuan_get_pid)
#define assuan_transact _ASSUAN_PREFIX(assuan_transact)
#define assuan_inquire _ASSUAN_PREFIX(assuan_inquire)
#define assuan_read_line _ASSUAN_PREFIX(assuan_read_line)
#define assuan_pending_line _ASSUAN_PREFIX(assuan_pending_line)
#define assuan_write_line _ASSUAN_PREFIX(assuan_write_line)
#define assuan_send_data _ASSUAN_PREFIX(assuan_send_data)
#define assuan_sendfd _ASSUAN_PREFIX(assuan_sendfd)
#define assuan_receivefd _ASSUAN_PREFIX(assuan_receivefd)
#define assuan_set_malloc_hooks _ASSUAN_PREFIX(assuan_set_malloc_hooks)
#define assuan_set_log_stream _ASSUAN_PREFIX(assuan_set_log_stream)
#define assuan_set_error _ASSUAN_PREFIX(assuan_set_error)
#define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer)
#define assuan_get_pointer _ASSUAN_PREFIX(assuan_get_pointer)
#define assuan_begin_confidential _ASSUAN_PREFIX(assuan_begin_confidential)
#define assuan_end_confidential _ASSUAN_PREFIX(assuan_end_confidential)
#define assuan_strerror _ASSUAN_PREFIX(assuan_strerror)
#define assuan_set_assuan_log_stream \
_ASSUAN_PREFIX(assuan_set_assuan_log_stream)
#define assuan_get_assuan_log_stream \
_ASSUAN_PREFIX(assuan_get_assuan_log_stream)
#define assuan_get_assuan_log_prefix \
_ASSUAN_PREFIX(assuan_get_assuan_log_prefix)
/* And now the internal functions, argh... */
#define _assuan_read_line _ASSUAN_PREFIX(_assuan_read_line)
#define _assuan_cookie_write_data _ASSUAN_PREFIX(_assuan_cookie_write_data)
#define _assuan_cookie_write_flush _ASSUAN_PREFIX(_assuan_cookie_write_flush)
#define _assuan_read_from_server _ASSUAN_PREFIX(_assuan_read_from_server)
#define _assuan_domain_init _ASSUAN_PREFIX(_assuan_domain_init)
#define _assuan_register_std_commands \
_ASSUAN_PREFIX(_assuan_register_std_commands)
#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read)
#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write)
#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read)
#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write)
#define _assuan_new_context _ASSUAN_PREFIX(_assuan_new_context)
#define _assuan_release_context _ASSUAN_PREFIX(_assuan_release_context)
#define _assuan_malloc _ASSUAN_PREFIX(_assuan_malloc)
#define _assuan_realloc _ASSUAN_PREFIX(_assuan_realloc)
#define _assuan_calloc _ASSUAN_PREFIX(_assuan_calloc)
#define _assuan_free _ASSUAN_PREFIX(_assuan_free)
#define _assuan_log_print_buffer _ASSUAN_PREFIX(_assuan_log_print_buffer)
#define _assuan_log_sanitized_string \
_ASSUAN_PREFIX(_assuan_log_sanitized_string)
#endif
#ifdef __cplusplus
extern "C"
{
#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_Chain = 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,
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);
/* Negotiate a file descriptor. If LINE contains "FD=N", returns N
assuming a local file descriptor. If LINE contains "FD" reads a
file descriptor via CTX and stores it in *RDF (the CTX must be
capable of passing file descriptors). */
AssuanError assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line,
int *rfd);
/*-- 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);
int assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd);
/*-- assuan-pipe-connect.c --*/
AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
char *const argv[], int *fd_child_list);
/*-- assuan-socket-connect.c --*/
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
pid_t server_pid);
/*-- assuan-domain-connect.c --*/
/* Connect to a Unix domain socket server. RENDEZVOUSFD is
bidirectional file descriptor (normally returned via socketpair)
which the client can use to rendezvous with the server. SERVER s
the server's pid. */
AssuanError assuan_domain_connect (ASSUAN_CONTEXT *r_ctx,
int rendezvousfd,
pid_t server);
/*-- assuan-domain-server.c --*/
/* RENDEZVOUSFD is a bidirectional file descriptor (normally returned
via socketpair) that the domain server can use to rendezvous with
the client. CLIENT is the client's pid. */
AssuanError assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
int rendezvousfd,
pid_t client);
/*-- 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);
/* The file descriptor must be pending before assuan_receivefd is
call. This means that assuan_sendfd should be called *before* the
trigger is sent (normally via assuan_send_data ("I sent you a
descriptor")). */
AssuanError assuan_sendfd (ASSUAN_CONTEXT ctx, int fd);
AssuanError assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd);
/*-- assuan-util.c --*/
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
void *(*new_realloc_func)(void *p, size_t n),
void (*new_free_func)(void*) );
void assuan_set_log_stream (ASSUAN_CONTEXT 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);
/*-- assuan-logging.c --*/
/* Set the stream to which assuan should log. By default, this is
stderr. */
extern void assuan_set_assuan_log_stream (FILE *fp);
/* Return the stream which is currently being using for logging. */
extern FILE *assuan_get_assuan_log_stream (void);
/* User defined call back. Return a prefix to be used at the start of
a line emitted by assuan on the log stream. The default
implementation returns the empty string, i.e. "" */
extern const char *assuan_get_assuan_log_prefix (void);
#ifdef __cplusplus
}
#endif
#endif /* ASSUAN_H */

View File

@ -0,0 +1,82 @@
#!/bin/sh
# mkerrors - Extract error strings from assuan.h
# and create C source for assuan_strerror
# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
#
# This file is part of Assuan.
#
# Assuan is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Assuan is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 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[50];
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:
{
unsigned int source, code;
source = ((err >> 24) & 0xff);
code = (err & 0x00ffffff);
if (source) /* Assume this is an libgpg-error. */
sprintf (buf, "ec=%u.%u", source, code );
else
sprintf (buf, "ec=%d", err );
s=buf; break;
}
}
return s;
}
EOF

100
tags/gpgme-0-4-6/autogen.sh Executable file
View File

@ -0,0 +1,100 @@
#! /bin/sh
# Run this to generate all the initial makefiles, etc.
#
# Copyright (C) 2003 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 program 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.
configure_ac="configure.ac"
cvtver () {
awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}'
}
check_version () {
if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then
return 0
fi
echo "**Error**: "\`$1\'" not installed or too old." >&2
echo ' Version '$3' or newer is required.' >&2
[ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2
DIE="yes"
return 1
}
# Grep the required versions from configure.ac
autoconf_vers=`sed -n '/^AC_PREREQ(/ {
s/^.*(\(.*\))/\1/p
q
}' ${configure_ac}`
autoconf_vers_num=`echo "$autoconf_vers" | cvtver`
automake_vers=`sed -n '/^min_automake_version=/ {
s/^.*="\(.*\)"/\1/p
q
}' ${configure_ac}`
automake_vers_num=`echo "$automake_vers" | cvtver`
#gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
#s/^.*(\(.*\))/\1/p
#q
#}' ${configure_ac}`
#gettext_vers_num=`echo "$gettext_vers" | cvtver`
if [ -z "$autoconf_vers" -o -z "$automake_vers" ]
then
echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2
exit 1
fi
# Allow to override the default tool names
AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
#GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
#MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
DIE=no
if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then
check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf
fi
if check_version $AUTOMAKE $automake_vers_num $automake_vers; then
check_version $ACLOCAL $automake_vers_num $autoconf_vers automake
fi
#if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
# check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
#fi
if test "$DIE" = "yes"; then
cat <<EOF
Note that you may use alternative versions of the tools by setting
the corresponding environment variables; see README.CVS for details.
EOF
exit 1
fi
echo "Running aclocal -I m4 ..."
$ACLOCAL -I m4
echo "Running autoheader..."
$AUTOHEADER
echo "Running automake --gnu ..."
$AUTOMAKE --gnu;
echo "Running autoconf..."
$AUTOCONF
echo "You may now run \"./configure --enable-maintainer-mode && make\"."

99
tags/gpgme-0-4-6/compile Executable file
View File

@ -0,0 +1,99 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
# Copyright 1999, 2000 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# 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, 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Usage:
# compile PROGRAM [ARGS]...
# `-o FOO.o' is removed from the args passed to the actual compile.
prog=$1
shift
ofile=
cfile=
args=
while test $# -gt 0; do
case "$1" in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we do something ugly here.
ofile=$2
shift
case "$ofile" in
*.o | *.obj)
;;
*)
args="$args -o $ofile"
ofile=
;;
esac
;;
*.c)
cfile=$1
args="$args $1"
;;
*)
args="$args $1"
;;
esac
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$prog" $args
fi
# Name of file we expect compiler to create.
cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir $lockdir > /dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir $lockdir; exit 1" 1 2 15
# Run the compile.
"$prog" $args
status=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
fi
rmdir $lockdir
exit $status

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

1432
tags/gpgme-0-4-6/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1537
tags/gpgme-0-4-6/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,337 @@
# configure.in for GPGME
# Copyright (C) 2000 Werner Koch (dd9jn)
# Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
#
# This file is part of GPGME.
#
# GPGME is free software; you can redistribute it and/or modify
# it under the terms of the GNU 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.)
AC_PREREQ(2.57)
min_automake_version="1.7.6"
# Version number: Remember to change it immediately *after* a release.
AC_INIT(gpgme, 0.4.6, [bug-gpgme@gnupg.org])
# LT Version numbers, remember to change them just *before* a release.
# (Code changed: REVISION++)
# (Interfaces added/removed/changed: CURRENT++, REVISION=0)
# (Interfaces added: AGE++)
# (Interfaces removed/changed: AGE=0)
#
LIBGPGME_LT_CURRENT=13
# Subtract 2 from this value if you want to make the LFS transition an
# ABI break. [Note to self: Remove this comment with the next regular break.]
LIBGPGME_LT_AGE=2
LIBGPGME_LT_REVISION=1
NEED_GPG_VERSION=1.2.2
NEED_GPGSM_VERSION=1.9.6
##############################################
AC_PREREQ(2.52)
AC_REVISION($Revision$)
PACKAGE=$PACKAGE_NAME
VERSION=$PACKAGE_VERSION
AC_CONFIG_SRCDIR(gpgme/gpgme.h)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
AM_MAINTAINER_MODE
AC_CANONICAL_HOST
AH_VERBATIM([_GNU_SOURCE],
[/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif])
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])
# Don't default to build static libs.
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
# For now we hardcode the use of version scripts. It would be better
# to write a test for this or even implement this within libtool.
have_ld_version_script=no
case "${host}" in
*-*-linux*)
have_ld_version_script=yes
;;
*-*-gnu*)
have_ld_version_script=yes
;;
esac
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
GPG_DEFAULT=no
GPGSM_DEFAULT=no
component_system=None
case "${host}" in
*-*-mingw32* | i?86-emx-os2 | i?86-*-os2*emx | i?86-*-msdosdjgpp* )
# special stuff for Windoze NT
# OS/2 with the EMX environment
# DOS with the DJGPP environment
AC_DEFINE(HAVE_DRIVE_LETTERS, ,
[Defined if we run on some of the PCDOS like systems (DOS,
Windoze, OS/2) with special properties like no file modes.])
AC_DEFINE(HAVE_DOSISH_SYSTEM, ,
[Defined if the filesystem uses driver letters.])
have_dosish_system=yes
GPG_DEFAULT='c:\\gnupg\\gpg.exe'
# XXX Assuan is not supported in this configuration.
#GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe'
#component_system='COM+'
;;
*)
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
# XXX: Probably use exec-prefix here?
# GPG_DEFAULT='/usr/bin/gpg'
# 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")
# Checks for header files.
AC_CHECK_HEADERS(sys/select.h)
# Type checks.
AC_CHECK_SIZEOF(unsigned int)
AC_SYS_LARGEFILE
AC_TYPE_OFF_T
# Checks for compiler features.
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
fi
# Checks for library functions.
AC_FUNC_FSEEKO
AC_REPLACE_FUNCS(stpcpy)
AC_REPLACE_FUNCS(vasprintf)
if test "$ac_cv_func_vasprintf" != yes; then
GNUPG_CHECK_VA_COPY
fi
# Try to find a thread-safe version of getenv().
have_thread_safe_getenv=no
jm_GLIBC21
if test $GLIBC21 = yes; then
have_thread_safe_getenv=yes
fi
if test $have_thread_safe_getenv = yes; then
AC_DEFINE(HAVE_THREAD_SAFE_GETENV, [1], [Define if getenv() is thread-safe])
fi
have_getenv_r=no
AC_CHECK_FUNCS(getenv_r, have_getenv_r=yes)
if test $have_getenv_r = no && test $have_thread_safe_getenv = no; then
AC_MSG_WARN([
***
*** getenv() is not thread-safe and getenv_r() does not exist
***])
fi
# For converting time strings to seconds since Epoch, we need the timegm
# function.
AC_CHECK_FUNCS(timegm)
if test "$ac_cv_func_timegm" != yes; then
AC_MSG_WARN([
***
*** timegm() not available - a non-thread-safe kludge will be used
*** and the TZ variable might be changed at runtime.
***])
fi
# Checking for libgpg-error.
AM_PATH_GPG_ERROR(0.5,, AC_MSG_ERROR([libgpg-error was not found]))
AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME,
[The default error source for GPGME.])
# Checks for system services
NO_OVERRIDE=no
AC_ARG_WITH(gpg,
AC_HELP_STRING([--with-gpg=PATH], [use GnuPG binary at PATH]),
GPG=$withval, NO_OVERRIDE=yes)
if test "$NO_OVERRIDE" = "yes" || test "$GPG" = "yes"; then
GPG=
NO_OVERRIDE=yes
if test "$cross_compiling" != "yes"; then
AC_PATH_PROG(GPG, gpg)
fi
if test -z "$GPG"; then
GPG="$GPG_DEFAULT"
fi
fi
if test "$GPG" = no; then
if test "$NO_OVERRIDE" = "yes"; then
if test "$cross_compiling" != "yes"; then
AC_MSG_WARN([
***
*** Could not find GnuPG, install GnuPG or use --with-gpg=PATH to enable it
***])
else
AC_MSG_ERROR([
***
*** Can not determine path to GnuPG when cross-compiling, use --with-gpg=PATH
***])
fi
fi
else
AC_DEFINE_UNQUOTED(GPG_PATH, "$GPG", [Path to the GnuPG binary.])
AC_SUBST(GPG)
fi
AM_CONDITIONAL(RUN_GPG_TESTS,
[test "$cross_compiling" != "yes" && test -n "$GPG" && test -r "$GPG"])
AC_SUBST(GPG_PATH)
NO_OVERRIDE=no
AC_ARG_WITH(gpgsm,
AC_HELP_STRING([--with-gpgsm=PATH], [use GpgSM binary at PATH]),
GPGSM=$withval, NO_OVERRIDE=yes)
if test "$NO_OVERRIDE" = "yes" || test "$GPGSM" = "yes"; then
GPGSM=
NO_OVERRIDE=yes
if test "$cross_compiling" != "yes"; then
AC_PATH_PROG(GPGSM, gpgsm)
fi
if test -z "$GPGSM"; then
GPGSM="$GPGSM_DEFAULT"
fi
fi
if test "$GPGSM" = no; then
if test "$NO_OVERRIDE" = "yes"; then
if test "$cross_compiling" != "yes"; then
AC_MSG_WARN([
***
*** Could not find GpgSM, install GpgSM or use --with-gpgsm=PATH to enable it
***])
else
AC_MSG_ERROR([
***
*** Can not determine path to GpgSM when cross-compiling, use --with-gpgsm=PATH
***])
fi
fi
else
AC_DEFINE_UNQUOTED(GPGSM_PATH, "$GPGSM", [Path to the GPGSM binary.])
AC_SUBST(GPGSM)
fi
AM_CONDITIONAL(HAVE_GPGSM, [test -n "$GPGSM" && test -r "$GPGSM"])
AM_CONDITIONAL(RUN_GPGSM_TESTS,
[test "$cross_compiling" != "yes" && test -n "$GPGSM" && test -r "$GPGSM"])
# FIXME: Only build if supported.
AM_CONDITIONAL(BUILD_ASSUAN, test "$GPGSM" != "no")
# The assuan code uses funopen but it will also build without it. So
# test for it. Frankly, this is not required in gpgme, but thats the
# way we handle it in libassuan.
AC_CHECK_FUNCS(funopen)
if test $ac_cv_func_funopen != yes; then
# No funopen but we can implement that in terms of fopencookie.
AC_CHECK_FUNCS(fopencookie)
if test $ac_cv_func_fopencookie = yes; then
AC_LIBOBJ([funopen])
else
AC_MSG_WARN([
***
*** No implementation of fopencookie or funopen available
***])
fi
fi
AC_REPLACE_FUNCS(isascii)
AC_REPLACE_FUNCS(putc_unlocked)
AC_REPLACE_FUNCS(memrchr)
AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
# Make the version number in gpgme/gpgme.h the same as the one here.
# (this is easier than to have a *.in file just for one substitution)
GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION)
# Substitution used for gpgme-config
GPGME_CONFIG_LIBS="-lgpgme"
GPGME_CONFIG_CFLAGS=""
AC_SUBST(GPGME_CONFIG_LIBS)
AC_SUBST(GPGME_CONFIG_CFLAGS)
# Frob'da Variables
LTLIBOBJS=`echo "$LIB@&t@OBJS" |
sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
AC_SUBST(LTLIBOBJS)
#
# Create config files
AC_CONFIG_FILES(Makefile assuan/Makefile gpgme/Makefile
tests/Makefile tests/gpg/Makefile tests/gpgsm/Makefile
doc/Makefile complus/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
"

472
tags/gpgme-0-4-6/depcomp Executable file
View File

@ -0,0 +1,472 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
# Copyright 1999, 2000 Free Software Foundation, Inc.
# 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, 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# `libtool' can also be set to `yes' or `no'.
if test -z "$depfile"; then
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
dir=`echo "$object" | sed 's,/.*$,/,'`
if test "$dir" = "$object"; then
dir=
fi
# FIXME: should be _deps on DOS.
depfile="$dir.deps/$base"
fi
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. This file always lives in the current directory.
# Also, the AIX compiler puts `$object:' at the start of each line;
# $object doesn't have directory information.
stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
outname="$stripped.o"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
else
tmpdepfile="$tmpdepfile2"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a space and a tab in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,602 @@
2004-03-29 Moritz Schulte <moritz@duesseldorf.ccc.de>
* gpgme.texi (Verify): Fix type of gpgme_op_verify_result.
* gpgme.texi (Key Listing Mode): Typo fix.
2004-03-23 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Library Version Check): Fix the instruction when to
set the locale.
2004-03-03 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (I/O Callback Example Qt): New section by Marc Mutz.
2004-02-24 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (cancellation): New section.
2004-02-17 Werner Koch <wk@gnupg.org>
* gpgme.texi (Key Listing Mode): Doc KEYLIST_MODE_VALIDATE.
2004-02-06 Moritz Schulte <mo@g10code.com>
* gpgme.texi: A couple of small fixes regarding the Largfile
Support section.
2004-02-01 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Largefile Support): New section.
2004-01-13 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Management): Fix exportable field.
2003-12-25 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Management): Rename member class in
gpgme_key_sig_t to sig_class.
(Creating a Signature): Likewise for gpgme_signature_t.
2003-12-23 Moritz Schulte <mo@g10code.com>
* gpgme.texi (Listing Keys): Minor clarification for
gpgme_get_key.
2003-10-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Signal Handling): New section.
2003-09-14 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Correct documentation on memory
synchronization requirement.
* gpgme.texi (Locale): New section.
(Multi Threading): Set locale in example.
2003-09-13 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Error Strings): Add gpgme_strerror_r.
2003-09-13 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Update documentation.
2003-09-03 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Header): We don't use the assuan namespace anymore.
Document new thread options.
2003-08-14 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Creating a Signature): Change type of member class
to unsigned int.
2003-08-04 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Verify): Get error code from SIG->status in the code
for gpgme_get_sig_status.
2003-07-31 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Management): Add can_authenticate flag.
* gpgme.texi (Listing Keys): Document GPG_ERR_AMBIGUOUS_NAME for
gpgme_get_key.
2003-07-29 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (EXTRA_DIST): Remove variable.
* gpgme.texi (Encrypting a Plaintext): Bad passphrase is only
possible with symmetric encryption, change the wording to reflect
that.
* gpgme.texi (Creating a Signature): Document
GPG_ERR_UNUSABLE_SECKEY.
* gpgme.texi (Encrypting a Plaintext): Mention encrypt and sign
operations in result function.
(Creating a Signature): Likewise.
2003-07-23 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Listing Mode): Remove word duplication.
(Listing Keys): Remove mentioning of force argument.
(Verify): Don't mention r_stat. Fix some typos.
(Decrypt and Verify): Correct info how to get the result. Don't
mention r_stat.
(Manipulating Data Buffers): Fix documentation of return value.
(Listing Keys): Update examples.
(Decrypt): Result might also be available when operation failed.
(Verify): Result might also be available when operation failed.
All spotted by Stéphane Corthésy.
2003-07-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Error Sources): Fix cut and paste error.
2003-07-09 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Management): Clarify difference between can_sign
and can_certify.
(Information About Keys): Likewise for GPGME_ATTR_CAN_SIGN and
GPGME_ATTR_CAN_CERTIFY.
2003-07-08 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Progress Meter Callback): Change return type of
gpgme_progress_cb_t to void.
2003-06-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi: Add 2003 to copyright notice.
* gpgme.texi (Header): Fix name space documentation on
libgpg-error.
2003-06-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Remove reference to
gpgme_recipients_t.
2003-06-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Crypto Operations): Rename gpgme_invalid_user_id_t
to gpgme_invalid_key_t.
2003-06-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi: Change error codes to GPG_ERR_* variants.
(Error Handling): Rewritten.
2003-05-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Exporting Keys): Change and document prototypes.
Add new gpgme_op_export_ext and gpgme_op_export_ext_start
variants.
(Selecting Recipients): Section removed.
(Encrypting a Plaintext): Change prototypes and document the
changes.
2003-05-28 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Exporting Keys): Change argument type from
gpgme_recipient_t to gpgme_user_id_t.
(Encrypting a Plaintext): Likewise.
(Selecting Recipients): Rewritten.
2003-05-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Protocol Selection): Do not use @acronym in @node
because that breaks texi2dvi.
* gpgme.texi (Passphrase Callback): Document new prototype.
2003-05-18 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Header): Remove Gpgme as namespace prefix. Add
_GPGME to namespace prefix.
* gpgme.texi (Multi Threading): Add note about link order.
2003-05-04 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Listing Keys): Document what happens if key is not
found.
* gpgme.texi (Importing Keys): Fix cut and paste error.
2003-04-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Remove reference to
gpgme_get_op_info.
(Detailed Results): Subsection removed.
* gpgme.texi (Key Listing Mode): Add GPGME_KEYLIST_MODE_SIGS.
(Manipulating Keys): Add obsoleteness note.
(Key Signatures): Likewise.
(Information About Keys): Likewise.
(Key Management): Add new data types GpgmeSubkey, GpgmeKeySig,
GpgmeUserID, and all the information about GpgmeKey.
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Listing Keys): Remove force_update argument from
gpgme_get_key.
* gpgme.texi (Trust Item Management): Add data members of
GpgmeTrustItem type.
(Information About Trust Items): Add note about obsoleteness.
(Manipulating Trust Items): Add gpgme_trust_item_ref and
gpgme_trust_item_unref.
2003-04-28 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Verify): Rewritten to take into account new and
deprecated functions and data types.
* gpgme.texi (Decrypt): Descript gpgme_op_decrypt_result and
GpgmeDecryptResult.
2003-04-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Add info about
GpgmeEncryptResult and gpgme_op_encrypt_result.
* gpgme.texi (Creating a Signature): Add info about
GpgmeNewSignature, GpgmeSignResult and gpgme_op_sign_result.
(Crypto Operations): Add GpgmeInvalidUserID.
(Algorithms): New chapter.
* gpgme.texi (Deleting Keys): Document
GPGME_Ambiguous_Specification.
(Error Values): Remove GPGME_Invalid_Type and GPGME_Invalid_Mode.
Add GPGME_Unknown_Reason, GPGME_Not_Found,
GPGME_Ambiguous_Specification, GPGME_Wrong_Key_Usage,
GPGME_Key_Revoked, GPGME_Key_Expired, GPGME_No_CRL_Known,
GPGME_CRL_Too_Old, GPGME_Policy_Mismatch, GPGME_No_Secret_Key,
GPGME_Key_Not_Trusted, GPGME_Issuer_Missing, GPGME_Chain_Too_Long,
GPGME_Unsupported_Algorithm, GPGME_Sig_Expired,
GPGME_Bad_Signature, GPGME_No_Public_Key.
2003-04-25 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Importing Keys): Change GPGME_IMPORT_PRIVATE to
GPGME_IMPORT_SECRET.
* gpgme.texi (Importing Keys): Remove note about gpgme_get_op_info.
(Detailed Results): Remove note about import.
* gpgme.texi (Importing Keys): Add documentation for
GpgmeImportStatus, GpgmeImportResult and gpgme_op_import_result.
* gpgme.texi (Generating Keys): Fix documentation of public and
secret arguments.
2003-04-24 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Generating Keys): Document changed gpgme_op_genkey
and new gpgme_op_genkey_result function. Document
GpgmeGenKeyResult data type.
* gpgme.texi (Error Values): Rename GPGME_No_Passphrase to
GPGME_Bad_Passphrase.
* gpgme.texi (Decrypt): Likewise.
(Decrypt and Verify): Likewise.
(Creating a Signature): Likewise.
(Encrypting a Plaintext): Likewise.
* gpgme.texi (Error Values): Rename GPGME_No_Recipients to
GPGME_No_UserID and GPGME_Invalid_Recipient to
GPGME_Invalid_UserID.
(Encrypting a Plaintext): Likewise.
* gpgme.texi (Error Values): Remove GPGME_Busy and GPGME_No_Request.
(Listing Keys): Likewise.
(Listing Trust Items): Likewise.
2003-02-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Cancelling an Operation): Removed.
(Passphrase Callback): Document new type for GpgmePassphraseCb.
2003-01-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Engine Information): Rename member part to
file_name.
* gpgme.texi (Protocols and Engines): Document
gpgme_get_protocol_name.
* gpgme.texi (Engine Information): Rewritten.
2003-01-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (I/O Callback Interface): Document new even
GPGME_EVENT_START.
(Waiting For Completion): Document new possible return values.
(I/O Callback Interface): Document return type of GpgmeIOCb.
2003-01-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Hooking Up Into Idle Time): Section removed.
2002-12-24 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Verify): Drop R_STAT argument in gpgme_op_verify.
* gpgme.texi (Decrypt and Verify): Likewise for
gpgme_op_decrypt_verify.
2002-12-23 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Information About Keys): Document that
GPGME_ATTR_IS_SECRET is not representable as a string anymore.
2002-12-22 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Key Signatures): New section.
(Listing Keys): Add gpgme_get_key.
2002-12-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Memory Based Data Buffers): New subsection.
(File Based Data Buffers): Likewise.
(Callback Based Data Buffers): Likewise.
(Manipulating Data Buffers): Update interfaces. Add
gpgme_data_seek.
* gpgme.texi (Engine Version Check): Remove gpgme_check_engine.
2002-11-21 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Verify): Document the new interface.
2002-11-19 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Generating Keys): Document new argument to
gpgme_op_genkey.
2002-11-05 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Verify): Fix prototype of gpgme_get_sig_key.
Reported by Miguel Coca <e970095@zipi.fi.upm.es>.
2002-08-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Selecting Signers): Fix reference count.
2002-08-21 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Header): Document name space.
2002-08-20 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Importing Keys): Document gpgme_op_import_ext.
* gpgme.texi (Importing Keys): Undocument EOF.
2002-08-14 Werner Koch <wk@gnupg.org>
* gpgme.texi (Information About Keys): Changed GPGME_ATTR_TYPE.
2002-07-25 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Deleting Keys): Say that secret keys might not be
deleted.
2002-07-25 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Information About Keys): Document (badly) the new
key attributes.
* gpgme.texi (Manipulating Data Buffers): Mention that backend
tries to detect encoding automatically.
2002-07-03 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Run Control): Update this section.
(Waiting For Completion): Likewise for this subsection.
(Cancelling an Operation): Likewise for this subsection.
(Using External Event Loops): New subsection with several
subsubsections.
2002-06-28 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Remove item about the need to
synchronize anything against gpgme_wait (except gpgme_wait
itself).
2002-06-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Information About Keys): Fix documentation for IDX.
(Information About Trust Items): Likewise.
2002-06-26 Werner Koch <wk@gnupg.org>
* gpgme.texi (Importing Keys): Document the return value -1 of
gpgme_op_import.
2002-06-20 Werner Koch <wk@gnupg.org>
* gpgme.texi (Verify): Explain the new whatidx variable.
2002-06-10 Werner Koch <wk@gnupg.org>
* gpgme.texi (Verify): Document attribute GPGME_ATTR_ERRTOK.
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.
Copyright 2002, 2003, 2004 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,25 @@
# 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
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:

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.

133
tags/gpgme-0-4-6/doc/mdate-sh Executable file
View File

@ -0,0 +1,133 @@
#!/bin/sh
# Get modification time of a file or directory and pretty-print it.
# Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
#
# 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, 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Prevent date giving response in another language.
LANG=C
export LANG
LC_ALL=C
export LC_ALL
LC_TIME=C
export LC_TIME
save_arg1="$1"
# Find out how to get the extended ls output of a file or directory.
if ls -L /dev/null 1>/dev/null 2>&1; then
ls_command='ls -L -l -d'
else
ls_command='ls -l -d'
fi
# A `ls -l' line looks as follows on OS/2.
# drwxrwx--- 0 Aug 11 2001 foo
# This differs from Unix, which adds ownership information.
# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
#
# To find the date, we split the line on spaces and iterate on words
# until we find a month. This cannot work with files whose owner is a
# user named `Jan', or `Feb', etc. However, it's unlikely that `/'
# will be owned by a user whose name is a month. So we first look at
# the extended ls output of the root directory to decide how many
# words should be skipped to get the date.
# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
set - x`$ls_command /`
# Find which argument is the month.
month=
command=
until test $month
do
shift
# Add another shift to the command.
command="$command shift;"
case $1 in
Jan) month=January; nummonth=1;;
Feb) month=February; nummonth=2;;
Mar) month=March; nummonth=3;;
Apr) month=April; nummonth=4;;
May) month=May; nummonth=5;;
Jun) month=June; nummonth=6;;
Jul) month=July; nummonth=7;;
Aug) month=August; nummonth=8;;
Sep) month=September; nummonth=9;;
Oct) month=October; nummonth=10;;
Nov) month=November; nummonth=11;;
Dec) month=December; nummonth=12;;
esac
done
# Get the extended ls output of the file or directory.
set - x`eval "$ls_command \"\$save_arg1\""`
# Remove all preceding arguments
eval $command
# Get the month. Next argument is day, followed by the year or time.
case $1 in
Jan) month=January; nummonth=1;;
Feb) month=February; nummonth=2;;
Mar) month=March; nummonth=3;;
Apr) month=April; nummonth=4;;
May) month=May; nummonth=5;;
Jun) month=June; nummonth=6;;
Jul) month=July; nummonth=7;;
Aug) month=August; nummonth=8;;
Sep) month=September; nummonth=9;;
Oct) month=October; nummonth=10;;
Nov) month=November; nummonth=11;;
Dec) month=December; nummonth=12;;
esac
day=$2
# Here we have to deal with the problem that the ls output gives either
# the time of day or the year.
case $3 in
*:*) set `date`; eval year=\$$#
case $2 in
Jan) nummonthtod=1;;
Feb) nummonthtod=2;;
Mar) nummonthtod=3;;
Apr) nummonthtod=4;;
May) nummonthtod=5;;
Jun) nummonthtod=6;;
Jul) nummonthtod=7;;
Aug) nummonthtod=8;;
Sep) nummonthtod=9;;
Oct) nummonthtod=10;;
Nov) nummonthtod=11;;
Dec) nummonthtod=12;;
esac
# For the first six month of the year the time notation can also
# be used for files modified in the last year.
if (expr $nummonth \> $nummonthtod) > /dev/null;
then
year=`expr $year - 1`
fi;;
*) year=$3;;
esac
# The result.
echo $day $month $year

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
# This is a template. The dist target uses it to create the real file.
Summary: GPGME - GnuPG Made Easy
Name: gpgme
Version: @pkg_version@
Release: 1
URL: http://www.gnupg.org/gpgme.html
Source: ftp://ftp.gnupg.org/gcrypt/alpha/gpgme/%{name}-%{version}.tar.gz
Group: Development/Libraries
Copyright: GPL
BuildRoot: %{_tmppath}/%{name}-%{version}
BuildRequires: make
Prereq: /sbin/ldconfig /sbin/install-info
Requires: gnupg
%description
GnuPG Made Easy (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.
%prep
%setup -q
%build
CFLAGS="$RPM_OPT_FLAGS"; export CFLAGS
./configure --prefix=/usr
make
%install
rm -fr $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT
make install prefix=$RPM_BUILD_ROOT/usr infodir=$RPM_BUILD_ROOT%{_infodir}
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
%clean
rm -fr $RPM_BUILD_ROOT
make distclean
%post
/sbin/ldconfig
/sbin/install-info %{_infodir}/gpgme.info.gz %{_infodir}/dir
%preun
if [ "$1" = 0 ]; then
/sbin/install-info --delete %{_infodir}/gpgme.info.gz %{_infodir}/dir
fi
%postun
/sbin/ldconfig
%files
%defattr(-,root,root)
%doc COPYING AUTHORS README INSTALL NEWS ChangeLog TODO THANKS
%attr(0755,root,root) %{_bindir}/gpgme-config
%attr(0755,root,root) %{_libdir}/*gpgme.so*
%attr(0755,root,root) %{_libdir}/*gpgme.la
%attr(0644,root,root) %{_libdir}/*gpgme.a
%{_includedir}/gpgme.h
%{_datadir}/aclocal/gpgme.m4
%{_infodir}/gpgme.info*
%changelog
* Sat Aug 30 2003 Robert Schiele <rschiele@uni-mannheim.de>
- %{_infodir}/dir is not packaged, remove to prevent checking failure
* Mon Jul 01 2002 Wojciech Polak <polak@lodz.pdi.net>
- initial specfile release for GPGME.
# EOF

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: 2002-07-25
%%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.7, GpgSM 0.3.8
%%build-prerequisites:
%%weak-prerequisites:
%%source-prerequisites:
%%version: 0.3.8 released on 2002-06-25
%%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,126 @@
# Copyright (C) 2000 Werner Koch (dd9jn)
# Copyright (C) 2001, 2002, 2003 g10 Code GmbH
#
# This file is part of GPGME.
#
# GPGME is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# GPGME is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 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 mkstatus libgpgme.vers
BUILT_SOURCES = status-table.h
MOSTLYCLEANFILES = status-table.h
bin_SCRIPTS = gpgme-config
m4datadir = $(datadir)/aclocal
m4data_DATA = gpgme.m4
include_HEADERS = gpgme.h
if HAVE_PTHREAD
ltlib_gpgme_pthread = libgpgme-pthread.la
else
ltlib_gpgme_pthread =
endif
if HAVE_PTH
ltlib_gpgme_pth = libgpgme-pth.la
else
ltlib_gpgme_pth =
endif
noinst_LTLIBRARIES = libgpgme-real.la
lib_LTLIBRARIES = libgpgme.la $(ltlib_gpgme_pthread) $(ltlib_gpgme_pth)
if HAVE_LD_VERSION_SCRIPT
libgpgme_version_script_cmd = -Wl,--version-script=$(srcdir)/libgpgme.vers
else
libgpgme_version_script_cmd =
endif
if BUILD_ASSUAN
assuan_cppflags = -I$(top_srcdir)/assuan
assuan_libobjs = ../assuan/libassuan.la
else
assuan_cppflags =
assuan_libobjs =
endif
if HAVE_DOSISH_SYSTEM
system_components = w32-util.c w32-sema.c w32-io.c
else
system_components = ath.h posix-util.c posix-sema.c posix-io.c
endif
if HAVE_GPGSM
gpgsm_components = engine-gpgsm.c
else
gpgsm_components =
endif
libgpgme_real_la_SOURCES = \
gpgme.h util.h conversion.c get-env.c context.h ops.h \
data.h data.c data-fd.c data-stream.c data-mem.c data-user.c \
data-compat.c \
signers.c \
wait.c wait-global.c wait-private.c wait-user.c wait.h \
op-support.c \
encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \
sign.c passphrase.c progress.c \
key.c keylist.c trust-item.c trustlist.c \
import.c export.c genkey.c delete.c edit.c \
engine.h engine-backend.h engine.c rungpg.c status-table.h \
$(gpgsm_components) sema.h io.h $(system_components) \
debug.c debug.h gpgme.c version.c error.c
# libgpgme_la_SOURCES = ath.h ath.c
if HAVE_PTH
ath_pth_src = ath-pth-compat.c
else
ath_pth_src =
endif
if HAVE_PTHREAD
ath_pthread_src = ath-pthread-compat.c
else
ath_pthread_src =
endif
libgpgme_la_SOURCES = ath.h ath-compat.c $(ath_pth_src) $(ath_pthread_src)
libgpgme_pthread_la_SOURCES = ath.h ath-pthread.c
libgpgme_pth_la_SOURCES = ath.h ath-pth.c
AM_CPPFLAGS = $(assuan_cppflags) @GPG_ERROR_CFLAGS@
libgpgme_la_LDFLAGS = $(libgpgme_version_script_cmd) -version-info \
@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@
libgpgme_la_DEPENDENCIES = libgpgme-real.la $(assuan_libobjs) \
@LTLIBOBJS@ $(srcdir)/libgpgme.vers
libgpgme_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \
@GPG_ERROR_LIBS@
libgpgme_pthread_la_LDFLAGS = $(libgpgme_version_script_cmd) -version-info \
@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@
libgpgme_pthread_la_DEPENDENCIES = libgpgme-real.la $(assuan_libobjs) \
@LTLIBOBJS@ $(srcdir)/libgpgme.vers
libgpgme_pthread_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \
-lpthread @GPG_ERROR_LIBS@
libgpgme_pth_la_CPPFLAGS = $(AM_CPPFLAGS) @PTH_CPPFLAGS@
libgpgme_pth_la_LDFLAGS = @PTH_LDFLAGS@ \
$(libgpgme_version_script_cmd) -version-info \
@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@
libgpgme_pth_la_DEPENDENCIES = libgpgme-real.la $(assuan_libobjs) \
@LTLIBOBJS@ $(srcdir)/libgpgme.vers
libgpgme_pth_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \
@PTH_LIBS@ @GPG_ERROR_LIBS@
status-table.h : gpgme.h
$(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h

View File

@ -0,0 +1,185 @@
/* 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>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#else
# include <sys/time.h>
#endif
#include <sys/types.h>
#ifndef _WIN32
#include <sys/wait.h>
#endif
#include "ath.h"
static struct ath_ops *ath_ops;
void
ath_init (void)
{
if (0)
;
#ifdef HAVE_PTHREAD
else if (!ath_ops)
ath_ops = ath_pthread_available ();
#endif
#ifdef HAVE_PTH
else if (!ath_ops)
ath_ops = ath_pth_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);
}
int
ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
{
if (ath_ops && ath_ops->accept)
return ath_ops->accept (s, addr, length_ptr);
else
return accept (s, addr, length_ptr);
}
int
ath_connect (int s, const struct sockaddr *addr, socklen_t length)
{
if (ath_ops && ath_ops->connect)
return ath_ops->connect (s, addr, length);
else
return connect (s, addr, length);
}
int
ath_sendmsg (int s, const struct msghdr *msg, int flags)
{
if (ath_ops && ath_ops->sendmsg)
return ath_ops->sendmsg (s, msg, flags);
else
return sendmsg (s, msg, flags);
}
int
ath_recvmsg (int s, struct msghdr *msg, int flags)
{
if (ath_ops && ath_ops->recvmsg)
return ath_ops->recvmsg (s, msg, flags);
else
return recvmsg (s, msg, flags);
}

View File

@ -0,0 +1,123 @@
/* ath-pth.c - Pth module for self-adapting thread-safeness library
* Copyright (C) 2002 g10 Code GmbH
*
* This file is part of GPGME.
*
* GPGME is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GPGME is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <stdlib.h>
#include <errno.h>
#include <pth.h>
#include "ath.h"
#pragma weak pth_mutex_init
#pragma weak pth_mutex_acquire
#pragma weak pth_mutex_release
#pragma weak pth_read
#pragma weak pth_write
#pragma weak pth_select
#pragma weak pth_waitpid
#pragma weak pth_accept
#pragma weak pth_connect
/* The lock we take while checking for lazy lock initialization. */
static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
/* Initialize the mutex *PRIV. If JUST_CHECK is true, only do this if
it is not already initialized. */
static int
mutex_pth_init (void **priv, int just_check)
{
int err = 0;
if (just_check)
pth_mutex_acquire (&check_init_lock, 0, NULL);
if (!*priv || !just_check)
{
pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
if (!lock)
err = ENOMEM;
if (!err)
{
err = pth_mutex_init (lock);
if (err == FALSE)
err = errno;
else
err = 0;
if (err)
free (lock);
else
*priv = lock;
}
}
if (just_check)
pth_mutex_release (&check_init_lock);
return err;
}
static int
mutex_pth_destroy (void *priv)
{
free (priv);
return 0;
}
static int
mutex_pth_lock (void *priv)
{
int ret = pth_mutex_acquire ((pth_mutex_t *) priv, 0, NULL);
return ret == FALSE ? errno : 0;
}
static int
mutex_pth_unlock (void *priv)
{
int ret = pth_mutex_release ((pth_mutex_t *) priv);
return ret == FALSE ? errno : 0;
}
static struct ath_ops ath_pth_ops =
{
mutex_pth_init,
mutex_pth_destroy,
mutex_pth_lock,
mutex_pth_unlock,
pth_read,
pth_write,
pth_select,
pth_waitpid,
pth_accept,
pth_connect,
NULL, /* FIXME: When GNU PTh has sendmsg. */
NULL /* FIXME: When GNU PTh has recvmsg. */
};
struct ath_ops *
ath_pth_available (void)
{
if (pth_mutex_init && pth_mutex_acquire && pth_mutex_release
&& pth_read && pth_write && pth_select && pth_waitpid)
return &ath_pth_ops;
else
return 0;
}

View File

@ -0,0 +1,177 @@
/* ath-pth.c - Pth module for self-adapting thread-safeness library
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include <pth.h>
#include "ath.h"
/* The lock we take while checking for lazy lock initialization. */
static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
/* Initialize the mutex *PRIV. If JUST_CHECK is true, only do this if
it is not already initialized. */
static int
mutex_pth_init (ath_mutex_t *priv, int just_check)
{
int err = 0;
if (just_check)
pth_mutex_acquire (&check_init_lock, 0, NULL);
if (!*priv || !just_check)
{
pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
if (!lock)
err = ENOMEM;
if (!err)
{
err = pth_mutex_init (lock);
if (err == FALSE)
err = errno;
else
err = 0;
if (err)
free (lock);
else
*priv = (ath_mutex_t) lock;
}
}
if (just_check)
pth_mutex_release (&check_init_lock);
return err;
}
void
ath_init (void)
{
/* Nothing to do. */
}
int
ath_mutex_init (ath_mutex_t *lock)
{
return mutex_pth_init (lock, 0);
}
int
ath_mutex_destroy (ath_mutex_t *lock)
{
int err = mutex_pth_init (lock, 1);
if (!err)
{
/* GNU Pth has no destructor function. */
free (*lock);
}
return err;
}
int
ath_mutex_lock (ath_mutex_t *lock)
{
int ret = mutex_pth_init (lock, 1);
if (ret)
return ret;
ret = pth_mutex_acquire ((pth_mutex_t *) *lock, 0, NULL);
return ret == FALSE ? errno : 0;
}
int
ath_mutex_unlock (ath_mutex_t *lock)
{
int ret = mutex_pth_init (lock, 1);
if (ret)
return ret;
ret = pth_mutex_release ((pth_mutex_t *) *lock);
return ret == FALSE ? errno : 0;
}
ssize_t
ath_read (int fd, void *buf, size_t nbytes)
{
return pth_read (fd, buf, nbytes);
}
ssize_t
ath_write (int fd, const void *buf, size_t nbytes)
{
return pth_write (fd, buf, nbytes);
}
ssize_t
ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout)
{
return pth_select (nfd, rset, wset, eset, timeout);
}
ssize_t
ath_waitpid (pid_t pid, int *status, int options)
{
return pth_waitpid (pid, status, options);
}
int
ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
{
return pth_accept (s, addr, length_ptr);
}
int
ath_connect (int s, const struct sockaddr *addr, socklen_t length)
{
return pth_connect (s, addr, length);
}
int
ath_sendmsg (int s, const struct msghdr *msg, int flags)
{
/* FIXME: GNU Pth is missing pth_sendmsg. */
return sendmsg (s, msg, flags);
}
int
ath_recvmsg (int s, struct msghdr *msg, int flags)
{
/* FIXME: GNU Pth is missing pth_recvmsg. */
return recvmsg (s, msg, flags);
}

View File

@ -0,0 +1,104 @@
/* ath-pthread.c - pthread module for self-adapting thread-safeness library
* Copyright (C) 2002 g10 Code GmbH
*
* This file is part of GPGME.
*
* GPGME is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GPGME is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include "ath.h"
/* Need to include pthread_create in our check, as the GNU C library
has the pthread_mutex_* functions in their public interface. */
#pragma weak pthread_create
#pragma weak pthread_mutex_init
#pragma weak pthread_mutex_destroy
#pragma weak pthread_mutex_lock
#pragma weak pthread_mutex_unlock
/* The lock we take while checking for lazy lock initialization. */
static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER;
/* Initialize the mutex *PRIV. If JUST_CHECK is true, only do this if
it is not already initialized. */
static int
mutex_pthread_init (void **priv, int just_check)
{
int err = 0;
if (just_check)
pthread_mutex_lock (&check_init_lock);
if (!*priv || !just_check)
{
pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
if (!lock)
err = ENOMEM;
if (!err)
{
err = pthread_mutex_init (lock, NULL);
if (err)
free (lock);
else
*priv = lock;
}
}
if (just_check)
pthread_mutex_unlock (&check_init_lock);
return err;
}
static int
mutex_pthread_destroy (void *priv)
{
int err = pthread_mutex_destroy ((pthread_mutex_t *) priv);
free (priv);
return err;
}
static struct ath_ops ath_pthread_ops =
{
mutex_pthread_init,
mutex_pthread_destroy,
(int (*) (void *)) pthread_mutex_lock,
(int (*) (void *)) pthread_mutex_unlock,
NULL, /* read */
NULL, /* write */
NULL, /* select */
NULL, /* waitpid */
NULL, /* accept */
NULL, /* connect */
NULL, /* sendmsg */
NULL /* recvmsg */
};
struct ath_ops *
ath_pthread_available (void)
{
/* Need to include pthread_create in our check, as the GNU C library
has the pthread_mutex_* functions in their public interface. */
if (pthread_create
&& pthread_mutex_init && pthread_mutex_destroy
&& pthread_mutex_lock && pthread_mutex_unlock)
return &ath_pthread_ops;
else
return 0;
}

View File

@ -0,0 +1,175 @@
/* ath-pthread.c - pthread module for self-adapting thread-safeness library
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#else
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include "ath.h"
/* The lock we take while checking for lazy lock initialization. */
static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER;
/* Initialize the mutex *PRIV. If JUST_CHECK is true, only do this if
it is not already initialized. */
static int
mutex_pthread_init (ath_mutex_t *priv, int just_check)
{
int err = 0;
if (just_check)
pthread_mutex_lock (&check_init_lock);
if (!*priv || !just_check)
{
pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
if (!lock)
err = ENOMEM;
if (!err)
{
err = pthread_mutex_init (lock, NULL);
if (err)
free (lock);
else
*priv = (ath_mutex_t) lock;
}
}
if (just_check)
pthread_mutex_unlock (&check_init_lock);
return err;
}
void
ath_init (void)
{
/* Nothing to do. */
}
int
ath_mutex_init (ath_mutex_t *lock)
{
return mutex_pthread_init (lock, 0);
}
int
ath_mutex_destroy (ath_mutex_t *lock)
{
int err = mutex_pthread_init (lock, 1);
if (!err)
{
err = pthread_mutex_destroy ((pthread_mutex_t *) *lock);
free (*lock);
}
return err;
}
int
ath_mutex_lock (ath_mutex_t *lock)
{
int ret = mutex_pthread_init (lock, 1);
if (ret)
return ret;
return pthread_mutex_lock ((pthread_mutex_t *) *lock);
}
int
ath_mutex_unlock (ath_mutex_t *lock)
{
int ret = mutex_pthread_init (lock, 1);
if (ret)
return ret;
return pthread_mutex_unlock ((pthread_mutex_t *) *lock);
}
ssize_t
ath_read (int fd, void *buf, size_t nbytes)
{
return read (fd, buf, nbytes);
}
ssize_t
ath_write (int fd, const void *buf, size_t nbytes)
{
return write (fd, buf, nbytes);
}
ssize_t
ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout)
{
return select (nfd, rset, wset, eset, timeout);
}
ssize_t
ath_waitpid (pid_t pid, int *status, int options)
{
return waitpid (pid, status, options);
}
int
ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
{
return accept (s, addr, length_ptr);
}
int
ath_connect (int s, const struct sockaddr *addr, socklen_t length)
{
return connect (s, addr, length);
}
int
ath_sendmsg (int s, const struct msghdr *msg, int flags)
{
return sendmsg (s, msg, flags);
}
int
ath_recvmsg (int s, struct msghdr *msg, int flags)
{
return recvmsg (s, msg, flags);
}

View File

@ -0,0 +1,142 @@
/* ath.c - Thread-safeness library.
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <unistd.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#else
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <sys/wait.h>
#include "ath.h"
#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
#define MUTEX_LOCKED ((ath_mutex_t) 1)
#define MUTEX_DESTROYED ((ath_mutex_t) 2)
int
ath_mutex_init (ath_mutex_t *lock)
{
#ifndef NDEBUG
*lock = MUTEX_UNLOCKED;
#endif
return 0;
}
int
ath_mutex_destroy (ath_mutex_t *lock)
{
#ifndef NDEBUG
assert (*lock == MUTEX_UNLOCKED);
*lock = MUTEX_DESTROYED;
#endif
return 0;
}
int
ath_mutex_lock (ath_mutex_t *lock)
{
#ifndef NDEBUG
assert (*lock == MUTEX_UNLOCKED);
*lock = MUTEX_LOCKED;
#endif
return 0;
}
int
ath_mutex_unlock (ath_mutex_t *lock)
{
#ifndef NDEBUG
assert (*lock == MUTEX_LOCKED);
*lock = MUTEX_UNLOCKED;
#endif
return 0;
}
ssize_t
ath_read (int fd, void *buf, size_t nbytes)
{
return read (fd, buf, nbytes);
}
ssize_t
ath_write (int fd, const void *buf, size_t nbytes)
{
return write (fd, buf, nbytes);
}
ssize_t
ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout)
{
return select (nfd, rset, wset, eset, timeout);
}
ssize_t
ath_waitpid (pid_t pid, int *status, int options)
{
return waitpid (pid, status, options);
}
int
ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
{
return accept (s, addr, length_ptr);
}
int
ath_connect (int s, const struct sockaddr *addr, socklen_t length)
{
return connect (s, addr, length);
}
int
ath_sendmsg (int s, const struct msghdr *msg, int flags)
{
return sendmsg (s, msg, flags);
}
int
ath_recvmsg (int s, struct msghdr *msg, int flags)
{
return recvmsg (s, msg, flags);
}

View File

@ -0,0 +1,106 @@
/* ath.h - Interfaces for thread-safeness library.
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef ATH_H
#define ATH_H
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#else
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <sys/socket.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_mutex_init _ATH_PREFIX(ath_mutex_init)
#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
#define ath_read _ATH_PREFIX(ath_read)
#define ath_write _ATH_PREFIX(ath_write)
#define ath_select _ATH_PREFIX(ath_select)
#define ath_waitpid _ATH_PREFIX(ath_waitpid)
#define ath_connect _ATH_PREFIX(ath_connect)
#define ath_accept _ATH_PREFIX(ath_accept)
#define ath_sendmsg _ATH_PREFIX(ath_sendmsg)
#define ath_recvmsg _ATH_PREFIX(ath_recvmsg)
#endif
typedef void *ath_mutex_t;
#define ATH_MUTEX_INITIALIZER 0;
/* Functions for mutual exclusion. */
int ath_mutex_init (ath_mutex_t *mutex);
int ath_mutex_destroy (ath_mutex_t *mutex);
int ath_mutex_lock (ath_mutex_t *mutex);
int ath_mutex_unlock (ath_mutex_t *mutex);
/* Replacement for the POSIX functions, which can be used to allow
other (user-level) threads to run. */
ssize_t ath_read (int fd, void *buf, size_t nbytes);
ssize_t ath_write (int fd, const void *buf, size_t nbytes);
ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout);
ssize_t ath_waitpid (pid_t pid, int *status, int options);
int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
int ath_connect (int s, const struct sockaddr *addr, socklen_t length);
int ath_sendmsg (int s, const struct msghdr *msg, int flags);
int ath_recvmsg (int s, struct msghdr *msg, int flags);
#define _ATH_COMPAT
#ifdef _ATH_COMPAT
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);
int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr);
int (*connect) (int s, const struct sockaddr *addr, socklen_t length);
int (*sendmsg) (int s, const struct msghdr *msg, int flags);
int (*recvmsg) (int s, struct msghdr *msg, int flags);
};
/* Initialize the any-thread package. */
#define ath_init _ATH_PREFIX(ath_init)
void ath_init (void);
/* Used by ath_pkg_init. */
#define ath_pthread_available _ATH_PREFIX(ath_pthread_available)
struct ath_ops *ath_pthread_available (void);
#define ath_pth_available _ATH_PREFIX(ath_pth_available)
struct ath_ops *ath_pth_available (void);
#endif
#endif /* ATH_H */

View File

@ -0,0 +1,111 @@
/* context.h - Definitions for a GPGME context.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef CONTEXT_H
#define CONTEXT_H
#include "gpgme.h"
#include "engine.h"
#include "wait.h"
/* Operations might require to remember arbitrary information and data
objects during invocations of the status handler. The
ctx_op_data structure provides a generic framework to hook in
such additional data. */
typedef enum
{
OPDATA_DECRYPT, OPDATA_SIGN, OPDATA_ENCRYPT, OPDATA_PASSPHRASE,
OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT,
OPDATA_VERIFY, OPDATA_TRUSTLIST
} ctx_op_data_id_t;
struct ctx_op_data
{
/* The next element in the linked list, or NULL if this is the last
element. */
struct ctx_op_data *next;
/* The type of the hook data, which can be used by a routine to
lookup the hook data. */
ctx_op_data_id_t type;
/* The function to release HOOK and all its associated resources.
Can be NULL if no special dealllocation routine is necessary. */
void (*cleanup) (void *hook);
/* The hook that points to the operation data. */
void *hook;
};
typedef struct ctx_op_data *ctx_op_data_t;
/* The context defines an environment in which crypto operations can
be performed (sequentially). */
struct gpgme_context
{
/* The protocol used by this context. */
gpgme_protocol_t protocol;
/* The running engine process. */
engine_t engine;
/* True if armor mode should be used. */
unsigned int use_armor : 1;
/* True if text mode should be used. */
unsigned int use_textmode : 1;
/* Flags for keylist mode. */
gpgme_keylist_mode_t keylist_mode;
/* Number of certs to be included. */
unsigned int include_certs;
/* The number of keys in signers. */
unsigned int signers_len;
/* Size of the following array. */
unsigned int signers_size;
gpgme_key_t *signers;
/* The locale for the pinentry. */
char *lc_ctype;
char *lc_messages;
/* The operation data hooked into the context. */
ctx_op_data_t op_data;
/* The user provided passphrase callback and its hook value. */
gpgme_passphrase_cb_t passphrase_cb;
void *passphrase_cb_value;
/* The user provided progress callback and its hook value. */
gpgme_progress_cb_t progress_cb;
void *progress_cb_value;
/* A list of file descriptors in active use by the current
operation. */
struct fd_table fdt;
struct gpgme_io_cbs io_cbs;
};
#endif /* CONTEXT_H */

View File

@ -0,0 +1,411 @@
/* conversion.c - String conversion helper functions.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include "gpgme.h"
#include "util.h"
#define atoi_1(p) (*(p) - '0' )
#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
/* Convert two hexadecimal digits from STR to the value they
represent. Returns -1 if one of the characters is not a
hexadecimal digit. */
int
_gpgme_hextobyte (const char *str)
{
int val = 0;
int i;
#define NROFHEXDIGITS 2
for (i = 0; i < NROFHEXDIGITS; i++)
{
if (*str >= '0' && *str <= '9')
val += *str - '0';
else if (*str >= 'A' && *str <= 'F')
val += 10 + *str - 'A';
else if (*str >= 'a' && *str <= 'f')
val += 10 + *str - 'a';
else
return -1;
if (i < NROFHEXDIGITS - 1)
val *= 16;
str++;
}
return val;
}
/* Decode the C formatted string SRC and store the result in the
buffer *DESTP which is LEN bytes long. If LEN is zero, then a
large enough buffer is allocated with malloc and *DESTP is set to
the result. Currently, LEN is only used to specify if allocation
is desired or not, the caller is expected to make sure that *DESTP
is large enough if LEN is not zero. */
gpgme_error_t
_gpgme_decode_c_string (const char *src, char **destp, size_t len)
{
char *dest;
/* Set up the destination buffer. */
if (len)
{
if (len < strlen (src) + 1)
return gpg_error (GPG_ERR_INTERNAL);
dest = *destp;
}
else
{
/* The converted string will never be larger than the original
string. */
dest = malloc (strlen (src) + 1);
if (!dest)
return gpg_error_from_errno (errno);
*destp = dest;
}
/* Convert the string. */
while (*src)
{
if (*src != '\\')
{
*(dest++) = *(src++);
continue;
}
switch (src[1])
{
#define DECODE_ONE(match,result) \
case match: \
src += 2; \
*(dest++) = result; \
break;
DECODE_ONE ('\'', '\'');
DECODE_ONE ('\"', '\"');
DECODE_ONE ('\?', '\?');
DECODE_ONE ('\\', '\\');
DECODE_ONE ('a', '\a');
DECODE_ONE ('b', '\b');
DECODE_ONE ('f', '\f');
DECODE_ONE ('n', '\n');
DECODE_ONE ('r', '\r');
DECODE_ONE ('t', '\t');
DECODE_ONE ('v', '\v');
case 'x':
{
int val = _gpgme_hextobyte (&src[2]);
if (val == -1)
{
/* Should not happen. */
*(dest++) = *(src++);
*(dest++) = *(src++);
if (*src)
*(dest++) = *(src++);
if (*src)
*(dest++) = *(src++);
}
else
{
if (!val)
{
/* A binary zero is not representable in a C
string. */
*(dest++) = '\\';
*(dest++) = '0';
}
else
*((unsigned char *) dest++) = val;
src += 4;
}
}
break;
default:
{
/* Should not happen. */
*(dest++) = *(src++);
*(dest++) = *(src++);
}
}
}
*(dest++) = 0;
return 0;
}
/* Decode the percent escaped string SRC and store the result in the
buffer *DESTP which is LEN bytes long. If LEN is zero, then a
large enough buffer is allocated with malloc and *DESTP is set to
the result. Currently, LEN is only used to specify if allocation
is desired or not, the caller is expected to make sure that *DESTP
is large enough if LEN is not zero. */
gpgme_error_t
_gpgme_decode_percent_string (const char *src, char **destp, size_t len)
{
char *dest;
/* Set up the destination buffer. */
if (len)
{
if (len < strlen (src) + 1)
return gpg_error (GPG_ERR_INTERNAL);
dest = *destp;
}
else
{
/* The converted string will never be larger than the original
string. */
dest = malloc (strlen (src) + 1);
if (!dest)
return gpg_error_from_errno (errno);
*destp = dest;
}
/* Convert the string. */
while (*src)
{
if (*src != '%')
{
*(dest++) = *(src++);
continue;
}
else
{
int val = _gpgme_hextobyte (&src[1]);
if (val == -1)
{
/* Should not happen. */
*(dest++) = *(src++);
if (*src)
*(dest++) = *(src++);
if (*src)
*(dest++) = *(src++);
}
else
{
if (!val)
{
/* A binary zero is not representable in a C
string. */
*(dest++) = '\\';
*(dest++) = '0';
}
else
*((unsigned char *) dest++) = val;
src += 3;
}
}
}
*(dest++) = 0;
return 0;
}
/* Parse the string TIMESTAMP into a time_t. The string may either be
seconds since Epoch or in the ISO 8601 format like
"20390815T143012". Returns 0 for an empty string or seconds since
Epoch. Leading spaces are skipped. If ENDP is not NULL, it will
point to the next non-parsed character in TIMESTRING. */
time_t
_gpgme_parse_timestamp (const char *timestamp, char **endp)
{
/* Need to skip leading spaces, because that is what strtoul does
but not our ISO 8601 checking code. */
while (*timestamp && *timestamp== ' ')
timestamp++;
if (!*timestamp)
return 0;
if (strlen (timestamp) >= 15 && timestamp[8] == 'T')
{
struct tm buf;
int year;
year = atoi_4 (timestamp);
if (year < 1900)
return (time_t)(-1);
/* Fixme: We would better use a configure test to see whether
mktime can handle dates beyond 2038. */
if (sizeof (time_t) <= 4 && year >= 2038)
return (time_t)2145914603; /* 2037-12-31 23:23:23 */
memset (&buf, 0, sizeof buf);
buf.tm_year = year - 1900;
buf.tm_mon = atoi_2 (timestamp+4) - 1;
buf.tm_mday = atoi_2 (timestamp+6);
buf.tm_hour = atoi_2 (timestamp+9);
buf.tm_min = atoi_2 (timestamp+11);
buf.tm_sec = atoi_2 (timestamp+13);
if (endp)
*endp = (char*)(timestamp + 15);
#ifdef HAVE_TIMEGM
return timegm (&buf);
#else
{
time_t tim;
putenv ("TZ=UTC");
tim = mktime (&buf);
#ifdef __GNUC__
#warning fixme: we must somehow reset TZ here. It is not threadsafe anyway.
#endif
return tim;
}
#endif /* !HAVE_TIMEGM */
}
else
return (time_t)strtoul (timestamp, endp, 10);
}
static struct
{
char *name;
gpgme_error_t err;
} gnupg_errors[] =
{
{ "EOF", GPG_ERR_EOF },
{ "No_Error", GPG_ERR_NO_ERROR },
{ "General_Error", GPG_ERR_GENERAL },
{ "Out_Of_Core", GPG_ERR_ENOMEM },
{ "Invalid_Value", GPG_ERR_INV_VALUE },
{ "IO_Error", GPG_ERR_GENERAL },
{ "Resource_Limit", GPG_ERR_RESOURCE_LIMIT },
{ "Internal_Error", GPG_ERR_INTERNAL },
{ "Bad_Certificate", GPG_ERR_BAD_CERT },
{ "Bad_Certificate_Chain", GPG_ERR_BAD_CERT_CHAIN},
{ "Missing_Certificate", GPG_ERR_MISSING_CERT },
{ "No_Data", GPG_ERR_NO_DATA },
{ "Bad_Signature", GPG_ERR_BAD_SIGNATURE },
{ "Not_Implemented", GPG_ERR_NOT_IMPLEMENTED },
{ "Conflict", GPG_ERR_CONFLICT },
{ "Bug", GPG_ERR_BUG },
{ "Read_Error", GPG_ERR_GENERAL },
{ "Write_Error", GPG_ERR_GENERAL },
{ "Invalid_Line", GPG_ERR_GENERAL },
{ "Incomplete_Line", GPG_ERR_INCOMPLETE_LINE },
{ "Invalid_Response", GPG_ERR_INV_RESPONSE },
{ "Agent_Error", GPG_ERR_AGENT },
{ "No_Public_Key", GPG_ERR_NO_PUBKEY },
{ "No_Secret_Key", GPG_ERR_NO_SECKEY },
{ "File_Open_Error", GPG_ERR_GENERAL },
{ "File_Create_Error", GPG_ERR_GENERAL },
{ "File_Error", GPG_ERR_GENERAL },
{ "Not_Supported", GPG_ERR_NOT_SUPPORTED },
{ "Invalid_Data", GPG_ERR_INV_DATA },
{ "Assuan_Server_Fault", GPG_ERR_ASSUAN_SERVER_FAULT },
{ "Assuan_Error", GPG_ERR_ASSUAN },
{ "Invalid_Session_Key", GPG_ERR_INV_SESSION_KEY },
{ "Invalid_Sexp", GPG_ERR_INV_SEXP },
{ "Unsupported_Algorithm", GPG_ERR_UNSUPPORTED_ALGORITHM },
{ "No_PIN_Entry", GPG_ERR_NO_PIN_ENTRY },
{ "PIN_Entry_Error", GPG_ERR_NO_PIN_ENTRY },
{ "Bad_PIN", GPG_ERR_BAD_PIN },
{ "Bad_Passphrase", GPG_ERR_BAD_PASSPHRASE },
{ "Invalid_Name", GPG_ERR_INV_NAME },
{ "Bad_Public_Key", GPG_ERR_BAD_PUBKEY },
{ "Bad_Secret_Key", GPG_ERR_BAD_SECKEY },
{ "Bad_Data", GPG_ERR_BAD_DATA },
{ "Invalid_Parameter", GPG_ERR_INV_PARAMETER },
{ "Tribute_to_D_A", GPG_ERR_TRIBUTE_TO_D_A },
{ "No_Dirmngr", GPG_ERR_NO_DIRMNGR },
{ "Dirmngr_Error", GPG_ERR_DIRMNGR },
{ "Certificate_Revoked", GPG_ERR_CERT_REVOKED },
{ "No_CRL_Known", GPG_ERR_NO_CRL_KNOWN },
{ "CRL_Too_Old", GPG_ERR_CRL_TOO_OLD },
{ "Line_Too_Long", GPG_ERR_LINE_TOO_LONG },
{ "Not_Trusted", GPG_ERR_NOT_TRUSTED },
{ "Canceled", GPG_ERR_CANCELED },
{ "Bad_CA_Certificate", GPG_ERR_BAD_CA_CERT },
{ "Certificate_Expired", GPG_ERR_CERT_EXPIRED },
{ "Certificate_Too_Young", GPG_ERR_CERT_TOO_YOUNG },
{ "Unsupported_Certificate", GPG_ERR_UNSUPPORTED_CERT },
{ "Unknown_Sexp", GPG_ERR_UNKNOWN_SEXP },
{ "Unsupported_Protection", GPG_ERR_UNSUPPORTED_PROTECTION },
{ "Corrupted_Protection", GPG_ERR_CORRUPTED_PROTECTION },
{ "Ambiguous_Name", GPG_ERR_AMBIGUOUS_NAME },
{ "Card_Error", GPG_ERR_CARD },
{ "Card_Reset", GPG_ERR_CARD_RESET },
{ "Card_Removed", GPG_ERR_CARD_REMOVED },
{ "Invalid_Card", GPG_ERR_INV_CARD },
{ "Card_Not_Present", GPG_ERR_CARD_NOT_PRESENT },
{ "No_PKCS15_App", GPG_ERR_NO_PKCS15_APP },
{ "Not_Confirmed", GPG_ERR_NOT_CONFIRMED },
{ "Configuration_Error", GPG_ERR_CONFIGURATION },
{ "No_Policy_Match", GPG_ERR_NO_POLICY_MATCH },
{ "Invalid_Index", GPG_ERR_INV_INDEX },
{ "Invalid_Id", GPG_ERR_INV_ID },
{ "No_Scdaemon", GPG_ERR_NO_SCDAEMON },
{ "Scdaemon_Error", GPG_ERR_SCDAEMON },
{ "Unsupported_Protocol", GPG_ERR_UNSUPPORTED_PROTOCOL },
{ "Bad_PIN_Method", GPG_ERR_BAD_PIN_METHOD },
{ "Card_Not_Initialized", GPG_ERR_CARD_NOT_INITIALIZED },
{ "Unsupported_Operation", GPG_ERR_UNSUPPORTED_OPERATION },
{ "Wrong_Key_Usage", GPG_ERR_WRONG_KEY_USAGE }
};
gpgme_error_t
_gpgme_map_gnupg_error (char *err)
{
unsigned int i;
/* Future version of GnuPG might return the error code directly, so
we first test for a a numerical value and use that verbatim.
Note that this numerical value might be followed by an
underschore and the textual representation of the error code. */
if (*err >= '0' && *err <= '9')
return strtoul (err, NULL, 10);
/* Well, this is a token, use the mapping table to get the error.
The drawback is that we won't receive an error source and have to
use GPG as source. */
for (i = 0; i < DIM (gnupg_errors); i++)
if (!strcmp (gnupg_errors[i].name, err))
return gpg_err_make (GPG_ERR_SOURCE_GPG, gnupg_errors[i].err);
return gpg_err_make (GPG_ERR_SOURCE_GPG, GPG_ERR_GENERAL);
}

View File

@ -0,0 +1,208 @@
/* data-compat.c - Compatibility interfaces for data objects.
Copyright (C) 2002, 2003, 2004 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <errno.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdlib.h>
#include "data.h"
#include "util.h"
/* Create a new data buffer filled with LENGTH bytes starting from
OFFSET within the file FNAME or stream STREAM (exactly one must be
non-zero). */
gpgme_error_t
gpgme_data_new_from_filepart (gpgme_data_t *dh, const char *fname,
FILE *stream, off_t offset, size_t length)
{
gpgme_error_t err;
char *buf = NULL;
int res;
if (stream && fname)
return gpg_error (GPG_ERR_INV_VALUE);
if (fname)
stream = fopen (fname, "rb");
if (!stream)
return gpg_error_from_errno (errno);
#ifdef HAVE_FSEEKO
res = fseeko (stream, offset, SEEK_SET);
#else
/* FIXME: Check for overflow, or at least bail at compilation. */
res = fseek (stream, offset, SEEK_SET);
#endif
if (res)
{
int saved_errno = errno;
if (fname)
fclose (stream);
return gpg_error_from_errno (saved_errno);
}
buf = malloc (length);
if (!buf)
{
int saved_errno = errno;
if (fname)
fclose (stream);
return gpg_error_from_errno (saved_errno);
}
while (fread (buf, length, 1, stream) < 1
&& ferror (stream) && errno == EINTR);
if (ferror (stream))
{
int saved_errno = errno;
if (buf)
free (buf);
if (fname)
fclose (stream);
return gpg_error_from_errno (saved_errno);
}
if (fname)
fclose (stream);
err = gpgme_data_new (dh);
if (err)
{
if (buf)
free (buf);
return err;
}
(*dh)->data.mem.buffer = buf;
(*dh)->data.mem.size = length;
(*dh)->data.mem.length = length;
return 0;
}
/* Create a new data buffer filled with the content of file FNAME.
COPY must be non-zero (delayed reads are not supported yet). */
gpgme_error_t
gpgme_data_new_from_file (gpgme_data_t *dh, const char *fname, int copy)
{
struct stat statbuf;
if (!fname || !copy)
return gpg_error (GPG_ERR_INV_VALUE);
if (stat (fname, &statbuf) < 0)
return gpg_error_from_errno (errno);
return gpgme_data_new_from_filepart (dh, fname, NULL, 0, statbuf.st_size);
}
static int
gpgme_error_to_errno (gpgme_error_t err)
{
int no = gpg_err_code_to_errno (err);
if (no)
{
errno = no;
return -1;
}
switch (gpg_err_code (err))
{
case GPG_ERR_EOF:
return 0;
case GPG_ERR_INV_VALUE:
errno = EINVAL;
return -1;
case GPG_ERR_NOT_SUPPORTED:
errno = EOPNOTSUPP;
return -1;
default:
/* FIXME: Yeah, well. */
errno = EINVAL;
return -1;
}
}
static ssize_t
old_user_read (gpgme_data_t dh, void *buffer, size_t size)
{
size_t amt;
gpgme_error_t err = (*dh->data.old_user.cb) (dh->data.old_user.handle,
buffer, size, &amt);
if (err)
return gpgme_error_to_errno (err);
return amt;
}
static off_t
old_user_seek (gpgme_data_t dh, off_t offset, int whence)
{
gpgme_error_t err;
if (whence != SEEK_SET || offset)
return EINVAL;
err = (*dh->data.old_user.cb) (dh->data.old_user.handle, NULL, 0, NULL);
if (err)
return gpgme_error_to_errno (err);
return 0;
}
static struct _gpgme_data_cbs old_user_cbs =
{
old_user_read,
NULL,
old_user_seek,
NULL
};
/* Create a new data buffer which retrieves the data from the callback
function READ_CB. */
gpgme_error_t
gpgme_data_new_with_read_cb (gpgme_data_t *dh,
int (*read_cb) (void *, char *, size_t, size_t *),
void *read_cb_value)
{
gpgme_error_t err = _gpgme_data_new (dh, &old_user_cbs);
if (err)
return err;
(*dh)->data.old_user.cb = read_cb;
(*dh)->data.old_user.handle = read_cb_value;
return 0;
}
gpgme_error_t
gpgme_data_rewind (gpgme_data_t dh)
{
return (gpgme_data_seek (dh, 0, SEEK_SET) == -1)
? gpg_error_from_errno (errno) : 0;
}

View File

@ -0,0 +1,69 @@
/* data-fd.c - A file descripor based data object.
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 GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <unistd.h>
#include <sys/types.h>
#include "data.h"
static ssize_t
fd_read (gpgme_data_t dh, void *buffer, size_t size)
{
return read (dh->data.fd, buffer, size);
}
static ssize_t
fd_write (gpgme_data_t dh, const void *buffer, size_t size)
{
return write (dh->data.fd, buffer, size);
}
static off_t
fd_seek (gpgme_data_t dh, off_t offset, int whence)
{
return lseek (dh->data.fd, offset, whence);
}
static struct _gpgme_data_cbs fd_cbs =
{
fd_read,
fd_write,
fd_seek,
NULL
};
gpgme_error_t
gpgme_data_new_from_fd (gpgme_data_t *dh, int fd)
{
gpgme_error_t err = _gpgme_data_new (dh, &fd_cbs);
if (err)
return err;
(*dh)->data.fd = fd;
return 0;
}

View File

@ -0,0 +1,223 @@
/* data-mem.c - A memory based data object.
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include "data.h"
#include "util.h"
static ssize_t
mem_read (gpgme_data_t dh, void *buffer, size_t size)
{
size_t amt = dh->data.mem.length - dh->data.mem.offset;
const char *src;
if (!amt)
return 0;
if (size < amt)
amt = size;
src = dh->data.mem.buffer ? dh->data.mem.buffer : dh->data.mem.orig_buffer;
memcpy (buffer, src + dh->data.mem.offset, amt);
dh->data.mem.offset += amt;
return amt;
}
static ssize_t
mem_write (gpgme_data_t dh, const void *buffer, size_t size)
{
size_t unused;
if (!dh->data.mem.buffer && dh->data.mem.orig_buffer)
{
size_t new_size = dh->data.mem.size;
char *new_buffer;
if (new_size < dh->data.mem.offset + size)
new_size = dh->data.mem.offset + size;
new_buffer = malloc (new_size);
if (!new_buffer)
return -1;
memcpy (new_buffer, dh->data.mem.orig_buffer, dh->data.mem.length);
dh->data.mem.buffer = new_buffer;
dh->data.mem.size = new_size;
}
unused = dh->data.mem.size - dh->data.mem.offset;
if (unused < size)
{
/* Allocate a large enough buffer with exponential backoff. */
#define INITIAL_ALLOC 512
size_t new_size = dh->data.mem.size
? (2 * dh->data.mem.size) : INITIAL_ALLOC;
char *new_buffer;
if (new_size < dh->data.mem.offset + size)
new_size = dh->data.mem.offset + size;
new_buffer = realloc (dh->data.mem.buffer, new_size);
if (!new_buffer && new_size > dh->data.mem.offset + size)
{
/* Maybe we were too greedy, try again. */
new_size = dh->data.mem.offset + size;
new_buffer = realloc (dh->data.mem.buffer, new_size);
}
if (!new_buffer)
return -1;
dh->data.mem.buffer = new_buffer;
dh->data.mem.size = new_size;
}
memcpy (dh->data.mem.buffer + dh->data.mem.offset, buffer, size);
dh->data.mem.offset += size;
if (dh->data.mem.length < dh->data.mem.offset)
dh->data.mem.length = dh->data.mem.offset;
return size;
}
static off_t
mem_seek (gpgme_data_t dh, off_t offset, int whence)
{
switch (whence)
{
case SEEK_SET:
if (offset < 0 || offset > dh->data.mem.length)
{
errno = EINVAL;
return -1;
}
dh->data.mem.offset = offset;
break;
case SEEK_CUR:
if ((offset > 0 && dh->data.mem.length - dh->data.mem.offset < offset)
|| (offset < 0 && dh->data.mem.offset < -offset))
{
errno = EINVAL;
return -1;
}
dh->data.mem.offset += offset;
break;
case SEEK_END:
if (offset > 0 || -offset > dh->data.mem.length)
{
errno = EINVAL;
return -1;
}
dh->data.mem.offset = dh->data.mem.length - offset;
break;
default:
errno = EINVAL;
return -1;
}
return dh->data.mem.offset;
}
static void
mem_release (gpgme_data_t dh)
{
if (dh->data.mem.buffer)
free (dh->data.mem.buffer);
}
static struct _gpgme_data_cbs mem_cbs =
{
mem_read,
mem_write,
mem_seek,
mem_release
};
gpgme_error_t
gpgme_data_new (gpgme_data_t *dh)
{
gpgme_error_t err = _gpgme_data_new (dh, &mem_cbs);
if (err)
return err;
return 0;
}
/* Create a new data buffer filled with SIZE bytes starting from
BUFFER. If COPY is zero, copying is delayed until necessary, and
the data is taken from the original location when needed. */
gpgme_error_t
gpgme_data_new_from_mem (gpgme_data_t *dh, const char *buffer,
size_t size, int copy)
{
gpgme_error_t err = _gpgme_data_new (dh, &mem_cbs);
if (err)
return err;
if (copy)
{
char *bufcpy = malloc (size);
if (!bufcpy)
_gpgme_data_release (*dh);
memcpy (bufcpy, buffer, size);
(*dh)->data.mem.buffer = bufcpy;
}
else
(*dh)->data.mem.orig_buffer = buffer;
(*dh)->data.mem.size = size;
(*dh)->data.mem.length = size;
return 0;
}
char *
gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
{
char *str = NULL;
if (!dh || dh->cbs != &mem_cbs)
return NULL;
str = dh->data.mem.buffer;
if (!str && dh->data.mem.orig_buffer)
{
str = malloc (dh->data.mem.length);
if (!str)
return NULL;
memcpy (str, dh->data.mem.orig_buffer, dh->data.mem.length);
}
if (r_len)
*r_len = dh->data.mem.length;
return str;
}

View File

@ -0,0 +1,80 @@
/* data-stream.c - A stream based data object.
Copyright (C) 2002, 2004 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include "data.h"
static ssize_t
stream_read (gpgme_data_t dh, void *buffer, size_t size)
{
size_t amt = fread (buffer, 1, size, dh->data.stream);
if (amt > 0)
return amt;
return ferror (dh->data.stream) ? -1 : 0;
}
static ssize_t
stream_write (gpgme_data_t dh, const void *buffer, size_t size)
{
size_t amt = fwrite (buffer, 1, size, dh->data.stream);
if (amt > 0)
return amt;
return ferror (dh->data.stream) ? -1 : 0;
}
static off_t
stream_seek (gpgme_data_t dh, off_t offset, int whence)
{
#ifdef HAVE_FSEEKO
return fseeko (dh->data.stream, offset, whence);
#else
/* FIXME: Check for overflow, or at least bail at compilation. */
return fseek (dh->data.stream, offset, whence);
#endif
}
static struct _gpgme_data_cbs stream_cbs =
{
stream_read,
stream_write,
stream_seek,
NULL
};
gpgme_error_t
gpgme_data_new_from_stream (gpgme_data_t *dh, FILE *stream)
{
gpgme_error_t err = _gpgme_data_new (dh, &stream_cbs);
if (err)
return err;
(*dh)->data.stream = stream;
return 0;
}

View File

@ -0,0 +1,76 @@
/* data-user.c - A user callback based data object.
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 GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include "data.h"
static ssize_t
user_read (gpgme_data_t dh, void *buffer, size_t size)
{
return (*dh->data.user.cbs->read) (dh->data.user.handle, buffer, size);
}
static ssize_t
user_write (gpgme_data_t dh, const void *buffer, size_t size)
{
return (*dh->data.user.cbs->write) (dh->data.user.handle, buffer, size);
}
static off_t
user_seek (gpgme_data_t dh, off_t offset, int whence)
{
return (*dh->data.user.cbs->seek) (dh->data.user.handle, offset, whence);
}
static void
user_release (gpgme_data_t dh)
{
(*dh->data.user.cbs->release) (dh->data.user.handle);
}
static struct _gpgme_data_cbs user_cbs =
{
user_read,
user_write,
user_seek,
user_release
};
gpgme_error_t
gpgme_data_new_from_cbs (gpgme_data_t *dh, gpgme_data_cbs_t cbs, void *handle)
{
gpgme_error_t err = _gpgme_data_new (dh, &user_cbs);
if (err)
return err;
(*dh)->data.user.cbs = cbs;
(*dh)->data.user.handle = handle;
return 0;
}

View File

@ -0,0 +1,222 @@
/* data.c - An abstraction for data objects.
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "gpgme.h"
#include "data.h"
#include "util.h"
#include "ops.h"
#include "io.h"
gpgme_error_t
_gpgme_data_new (gpgme_data_t *r_dh, struct _gpgme_data_cbs *cbs)
{
gpgme_data_t dh;
if (!r_dh)
return gpg_error (GPG_ERR_INV_VALUE);
*r_dh = NULL;
dh = calloc (1, sizeof (*dh));
if (!dh)
return gpg_error_from_errno (errno);
dh->cbs = cbs;
*r_dh = dh;
return 0;
}
void
_gpgme_data_release (gpgme_data_t dh)
{
if (dh)
free (dh);
}
/* Read up to SIZE bytes into buffer BUFFER from the data object with
the handle DH. Return the number of characters read, 0 on EOF and
-1 on error. If an error occurs, errno is set. */
ssize_t
gpgme_data_read (gpgme_data_t dh, void *buffer, size_t size)
{
if (!dh)
{
errno = EINVAL;
return -1;
}
if (!dh->cbs->read)
{
errno = EOPNOTSUPP;
return -1;
}
return (*dh->cbs->read) (dh, buffer, size);
}
/* Write up to SIZE bytes from buffer BUFFER to the data object with
the handle DH. Return the number of characters written, or -1 on
error. If an error occurs, errno is set. */
ssize_t
gpgme_data_write (gpgme_data_t dh, const void *buffer, size_t size)
{
if (!dh)
{
errno = EINVAL;
return -1;
}
if (!dh->cbs->write)
{
errno = EOPNOTSUPP;
return -1;
}
return (*dh->cbs->write) (dh, buffer, size);
}
/* Set the current position from where the next read or write starts
in the data object with the handle DH to OFFSET, relativ to
WHENCE. */
off_t
gpgme_data_seek (gpgme_data_t dh, off_t offset, int whence)
{
if (!dh)
{
errno = EINVAL;
return -1;
}
if (!dh->cbs->read)
{
errno = EOPNOTSUPP;
return -1;
}
return (*dh->cbs->seek) (dh, offset, whence);
}
/* Release the data object with the handle DH. */
void
gpgme_data_release (gpgme_data_t dh)
{
if (!dh)
return;
if (dh->cbs->release)
(*dh->cbs->release) (dh);
_gpgme_data_release (dh);
}
/* Get the current encoding meta information for the data object with
handle DH. */
gpgme_data_encoding_t
gpgme_data_get_encoding (gpgme_data_t dh)
{
return dh ? dh->encoding : GPGME_DATA_ENCODING_NONE;
}
/* Set the encoding meta information for the data object with handle
DH to ENC. */
gpgme_error_t
gpgme_data_set_encoding (gpgme_data_t dh, gpgme_data_encoding_t enc)
{
if (!dh)
return gpg_error (GPG_ERR_INV_VALUE);
if (enc < 0 || enc > GPGME_DATA_ENCODING_ARMOR)
return gpg_error (GPG_ERR_INV_VALUE);
dh->encoding = enc;
return 0;
}
/* Functions to support the wait interface. */
gpgme_error_t
_gpgme_data_inbound_handler (void *opaque, int fd)
{
gpgme_data_t dh = (gpgme_data_t) opaque;
char buffer[BUFFER_SIZE];
char *bufp = buffer;
ssize_t buflen;
buflen = read (fd, buffer, BUFFER_SIZE);
if (buflen < 0)
return gpg_error_from_errno (errno);
if (buflen == 0)
{
_gpgme_io_close (fd);
return 0;
}
do
{
ssize_t amt = gpgme_data_write (dh, bufp, buflen);
if (amt == 0 || (amt < 0 && errno != EINTR))
return gpg_error_from_errno (errno);
bufp += amt;
buflen -= amt;
}
while (buflen > 0);
return 0;
}
gpgme_error_t
_gpgme_data_outbound_handler (void *opaque, int fd)
{
gpgme_data_t dh = (gpgme_data_t) opaque;
ssize_t nwritten;
if (!dh->pending_len)
{
ssize_t amt = gpgme_data_read (dh, dh->pending, BUFFER_SIZE);
if (amt < 0)
return gpg_error_from_errno (errno);
if (amt == 0)
{
_gpgme_io_close (fd);
return 0;
}
dh->pending_len = amt;
}
nwritten = _gpgme_io_write (fd, dh->pending, dh->pending_len);
if (nwritten == -1 && errno == EAGAIN )
return 0;
if (nwritten <= 0)
return gpg_error_from_errno (errno);
if (nwritten < dh->pending_len)
memmove (dh->pending, dh->pending + nwritten, dh->pending_len - nwritten);
dh->pending_len -= nwritten;
return 0;
}

View File

@ -0,0 +1,120 @@
/* data.h - Internal data object abstraction interface.
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 GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef DATA_H
#define DATA_H
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <limits.h>
#include "gpgme.h"
/* Read up to SIZE bytes into buffer BUFFER from the data object with
the handle DH. Return the number of characters read, 0 on EOF and
-1 on error. If an error occurs, errno is set. */
typedef ssize_t (*gpgme_data_read_cb) (gpgme_data_t dh, void *buffer,
size_t size);
/* Write up to SIZE bytes from buffer BUFFER to the data object with
the handle DH. Return the number of characters written, or -1 on
error. If an error occurs, errno is set. */
typedef ssize_t (*gpgme_data_write_cb) (gpgme_data_t dh, const void *buffer,
size_t size);
/* Set the current position from where the next read or write starts
in the data object with the handle DH to OFFSET, relativ to
WHENCE. */
typedef off_t (*gpgme_data_seek_cb) (gpgme_data_t dh, off_t offset,
int whence);
/* Release the data object with the handle DH. */
typedef void (*gpgme_data_release_cb) (gpgme_data_t dh);
struct _gpgme_data_cbs
{
gpgme_data_read_cb read;
gpgme_data_write_cb write;
gpgme_data_seek_cb seek;
gpgme_data_release_cb release;
};
struct gpgme_data
{
struct _gpgme_data_cbs *cbs;
gpgme_data_encoding_t encoding;
#ifdef PIPE_BUF
#define BUFFER_SIZE PIPE_BUF
#else
#ifdef _POSIX_PIPE_BUF
#define BUFFER_SIZE _POSIX_PIPE_BUF
#else
#define BUFFER_SIZE 512
#endif
#endif
char pending[BUFFER_SIZE];
int pending_len;
union
{
/* For gpgme_data_new_from_fd. */
int fd;
/* For gpgme_data_new_from_stream. */
FILE *stream;
/* For gpgme_data_new_from_cbs. */
struct
{
gpgme_data_cbs_t cbs;
void *handle;
} user;
/* For gpgme_data_new_from_mem. */
struct
{
char *buffer;
const char *orig_buffer;
/* Allocated size of BUFFER. */
size_t size;
size_t length;
size_t offset;
} mem;
/* For gpgme_data_new_from_read_cb. */
struct
{
int (*cb) (void *, char *, size_t, size_t *);
void *handle;
} old_user;
} data;
};
gpgme_error_t _gpgme_data_new (gpgme_data_t *r_dh,
struct _gpgme_data_cbs *cbs);
void _gpgme_data_release (gpgme_data_t dh);
#endif /* DATA_H */

View File

@ -0,0 +1,220 @@
/* debug.c - helpful output in desperate situations
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <ctype.h>
#ifndef HAVE_DOSISH_SYSTEM
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#include <assert.h>
#include "util.h"
#include "sema.h"
/* Lock to serialize initialization of the debug output subsystem and
output of actual debug messages. */
DEFINE_STATIC_LOCK (debug_lock);
/* The amount of detail requested by the user, per environment
variable GPGME_DEBUG. */
static int debug_level;
/* The output stream for the debug messages. */
static FILE *errfp;
/* Remove leading and trailing white spaces. */
static char *
trim_spaces (char *str)
{
char *string, *p, *mark;
string = str;
/* Find first non space character. */
for (p = string; *p && isspace (*(unsigned char *) p); p++)
;
/* Move characters. */
for (mark = NULL; (*string = *p); string++, p++)
if (isspace (*(unsigned char *) p))
{
if (!mark)
mark = string;
}
else
mark = NULL;
if (mark)
*mark = '\0'; /* Remove trailing spaces. */
return str;
}
static void
debug_init (void)
{
static int initialized;
LOCK (debug_lock);
if (!initialized)
{
gpgme_error_t err;
char *e;
const char *s1, *s2;;
err = _gpgme_getenv ("GPGME_DEBUG", &e);
if (err)
{
UNLOCK (debug_lock);
return;
}
initialized = 1;
errfp = stderr;
if (e)
{
debug_level = atoi (e);
s1 = strchr (e, ':');
if (s1)
{
#ifndef HAVE_DOSISH_SYSTEM
if (getuid () == geteuid ())
{
#endif
char *p;
FILE *fp;
s1++;
if (!(s2 = strchr (s1, ':')))
s2 = s1 + strlen (s1);
p = malloc (s2 - s1 + 1);
if (p)
{
memcpy (p, s1, s2 - s1);
p[s2-s1] = 0;
trim_spaces (p);
fp = fopen (p,"a");
if (fp)
{
setvbuf (fp, NULL, _IOLBF, 0);
errfp = fp;
}
free (p);
}
#ifndef HAVE_DOSISH_SYSTEM
}
#endif
}
free (e);
}
if (debug_level > 0)
fprintf (errfp, "gpgme_debug: level=%d\n", debug_level);
}
UNLOCK (debug_lock);
}
/* Log the formatted string FORMAT at debug level LEVEL or higher. */
void
_gpgme_debug (int level, const char *format, ...)
{
va_list arg_ptr;
debug_init ();
if (debug_level < level)
return;
va_start (arg_ptr, format);
LOCK (debug_lock);
vfprintf (errfp, format, arg_ptr);
va_end (arg_ptr);
if(format && *format && format[strlen (format) - 1] != '\n')
putc ('\n', errfp);
UNLOCK (debug_lock);
fflush (errfp);
}
/* Start a new debug line in *LINE, logged at level LEVEL or higher,
and starting with the formatted string FORMAT. */
void
_gpgme_debug_begin (void **line, int level, const char *format, ...)
{
va_list arg_ptr;
debug_init ();
if (debug_level < level)
{
/* Disable logging of this line. */
*line = NULL;
return;
}
va_start (arg_ptr, format);
vasprintf ((char **) line, format, arg_ptr);
va_end (arg_ptr);
}
/* Add the formatted string FORMAT to the debug line *LINE. */
void
_gpgme_debug_add (void **line, const char *format, ...)
{
va_list arg_ptr;
char *toadd;
char *result;
if (!*line)
return;
va_start (arg_ptr, format);
vasprintf (&toadd, format, arg_ptr);
va_end (arg_ptr);
asprintf (&result, "%s%s", *(char **) line, toadd);
free (*line);
free (toadd);
*line = result;
}
/* Finish construction of *LINE and send it to the debug output
stream. */
void
_gpgme_debug_end (void **line)
{
if (!*line)
return;
/* The smallest possible level is 1, so force logging here by
using that. */
_gpgme_debug (1, "%s", *line);
free (*line);
*line = NULL;
}

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))
#elif 0
/* Only works in C99. */
#define DEBUG0(fmt) \
_gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__))
#define DEBUG(fmt, ...) \
_gpgme_debug (1, "%s:%s: " fmt, __FILE__, XSTRINGIFY (__LINE__), __VA_ARGS__)
#define DEBUG_BEGIN(hlp, lvl, fmt) \
_gpgme_debug_begin (&(hlp), lvl, "%s:%s: " fmt, __FILE__, \
XSTRINGIFY (__LINE__))
#define DEBUG_BEGINX(hlp, lvl, fmt, ...) \
_gpgme_debug_begin (&(hlp), lvl, "%s:%s: " fmt, __FILE__, \
XSTRINGIFY (__LINE__), __VA_ARGS__)
#define DEBUG_ADD0(hlp, fmt) \
_gpgme_debug_add (&(hlp), fmt)
#define DEBUG_ADD(hlp, fmt, ...) \
_gpgme_debug_add (&(hlp), fmt, __VA_ARGS__)
#define DEBUG_END(hlp, fmt) \
_gpgme_debug_add (&(hlp), fmt); \
_gpgme_debug_end (&(hlp))
#define DEBUG_ENDX(hlp, fmt, ...) \
_gpgme_debug_add (&(hlp), fmt, __VA_ARGS__); \
_gpgme_debug_end (&(hlp))
#else
/* This finally works everywhere, horror. */
#define DEBUG0(fmt) \
_gpgme_debug (1, "%s:%s: " fmt, __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,102 @@
/* decrypt-verify.c - Decrypt and verify function.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "gpgme.h"
#include "ops.h"
static gpgme_error_t
decrypt_verify_status_handler (void *priv, gpgme_status_code_t code,
char *args)
{
gpgme_error_t err;
err = _gpgme_progress_status_handler (priv, code, args);
if (!err)
err = _gpgme_decrypt_status_handler (priv, code, args);
if (!err)
err = _gpgme_verify_status_handler (priv, code, args);
return err;
}
static gpgme_error_t
decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
gpgme_data_t cipher, gpgme_data_t plain)
{
gpgme_error_t err;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
err = _gpgme_op_decrypt_init_result (ctx);
if (err)
return err;
err = _gpgme_op_verify_init_result (ctx);
if (err)
return err;
if (!cipher)
return gpg_error (GPG_ERR_NO_DATA);
if (!plain)
return gpg_error (GPG_ERR_INV_VALUE);
if (ctx->passphrase_cb)
{
err = _gpgme_engine_set_command_handler
(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
if (err)
return err;
}
_gpgme_engine_set_status_handler (ctx->engine,
decrypt_verify_status_handler, ctx);
return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain);
}
/* Decrypt ciphertext CIPHER and make a signature verification within
CTX and store the resulting plaintext in PLAIN. */
gpgme_error_t
gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
gpgme_data_t plain)
{
return decrypt_verify_start (ctx, 0, cipher, plain);
}
/* Decrypt ciphertext CIPHER and make a signature verification within
CTX and store the resulting plaintext in PLAIN. */
gpgme_error_t
gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
gpgme_data_t plain)
{
gpgme_error_t err = decrypt_verify_start (ctx, 1, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -0,0 +1,223 @@
/* decrypt.c - Decrypt function.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "gpgme.h"
#include "util.h"
#include "context.h"
#include "ops.h"
typedef struct
{
struct _gpgme_op_decrypt_result result;
int okay;
int failed;
} *op_data_t;
static void
release_op_data (void *hook)
{
op_data_t opd = (op_data_t) hook;
if (opd->result.unsupported_algorithm)
free (opd->result.unsupported_algorithm);
}
gpgme_decrypt_result_t
gpgme_op_decrypt_result (gpgme_ctx_t ctx)
{
void *hook;
op_data_t opd;
gpgme_error_t err;
err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
opd = hook;
if (err || !opd)
return NULL;
return &opd->result;
}
gpgme_error_t
_gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
char *args)
{
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
gpgme_error_t err;
void *hook;
op_data_t opd;
err = _gpgme_passphrase_status_handler (priv, code, args);
if (err)
return err;
err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
opd = hook;
if (err)
return err;
switch (code)
{
case GPGME_STATUS_EOF:
/* FIXME: These error values should probably be attributed to
the underlying crypto engine (as error source). */
if (opd->failed)
return gpg_error (GPG_ERR_DECRYPT_FAILED);
else if (!opd->okay)
return gpg_error (GPG_ERR_NO_DATA);
break;
case GPGME_STATUS_DECRYPTION_OKAY:
opd->okay = 1;
break;
case GPGME_STATUS_DECRYPTION_FAILED:
opd->failed = 1;
break;
case GPGME_STATUS_ERROR:
{
const char d_alg[] = "decrypt.algorithm";
const char u_alg[] = "Unsupported_Algorithm";
if (!strncmp (args, d_alg, sizeof (d_alg) - 1))
{
args += sizeof (d_alg);
while (*args == ' ')
args++;
if (!strncmp (args, u_alg, sizeof (u_alg) - 1))
{
char *end;
args += sizeof (u_alg);
while (*args == ' ')
args++;
end = strchr (args, ' ');
if (end)
*end = '\0';
if (!(*args == '?' && *(args + 1) == '\0'))
{
opd->result.unsupported_algorithm = strdup (args);
if (!opd->result.unsupported_algorithm)
return gpg_error_from_errno (errno);
}
}
}
}
break;
default:
break;
}
return 0;
}
static gpgme_error_t
decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
gpgme_error_t err;
err = _gpgme_progress_status_handler (priv, code, args);
if (!err)
err = _gpgme_decrypt_status_handler (priv, code, args);
return err;
}
gpgme_error_t
_gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
{
void *hook;
op_data_t opd;
return _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
sizeof (*opd), release_op_data);
}
static gpgme_error_t
decrypt_start (gpgme_ctx_t ctx, int synchronous,
gpgme_data_t cipher, gpgme_data_t plain)
{
gpgme_error_t err;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
err = _gpgme_op_decrypt_init_result (ctx);
if (err)
return err;
if (!cipher)
return gpg_error (GPG_ERR_NO_DATA);
if (!plain)
return gpg_error (GPG_ERR_INV_VALUE);
if (err)
return err;
if (ctx->passphrase_cb)
{
err = _gpgme_engine_set_command_handler
(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
if (err)
return err;
}
_gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain);
}
gpgme_error_t
gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
gpgme_data_t plain)
{
return decrypt_start (ctx, 0, cipher, plain);
}
/* Decrypt ciphertext CIPHER within CTX and store the resulting
plaintext in PLAIN. */
gpgme_error_t
gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
{
gpgme_error_t err = decrypt_start (ctx, 1, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -0,0 +1,108 @@
/* delete.c - Delete a key.
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include "gpgme.h"
#include "context.h"
#include "ops.h"
static gpgme_error_t
delete_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
if (code == GPGME_STATUS_DELETE_PROBLEM)
{
enum delete_problem
{
DELETE_No_Problem = 0,
DELETE_No_Such_Key = 1,
DELETE_Must_Delete_Secret_Key = 2,
DELETE_Ambiguous_Specification = 3
};
long problem;
char *tail;
errno = 0;
problem = strtol (args, &tail, 0);
if (errno || (*tail && *tail != ' '))
return gpg_error (GPG_ERR_INV_ENGINE);
switch (problem)
{
case DELETE_No_Problem:
break;
case DELETE_No_Such_Key:
return gpg_error (GPG_ERR_NO_PUBKEY);
case DELETE_Must_Delete_Secret_Key:
return gpg_error (GPG_ERR_CONFLICT);
case DELETE_Ambiguous_Specification:
return gpg_error (GPG_ERR_AMBIGUOUS_NAME);
default:
return gpg_error (GPG_ERR_GENERAL);
}
}
return 0;
}
static gpgme_error_t
delete_start (gpgme_ctx_t ctx, int synchronous, const gpgme_key_t key,
int allow_secret)
{
gpgme_error_t err;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
_gpgme_engine_set_status_handler (ctx->engine, delete_status_handler, ctx);
return _gpgme_engine_op_delete (ctx->engine, key, allow_secret);
}
/* Delete KEY from the keyring. If ALLOW_SECRET is non-zero, secret
keys are also deleted. */
gpgme_error_t
gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key,
int allow_secret)
{
return delete_start (ctx, 0, key, allow_secret);
}
/* Delete KEY from the keyring. If ALLOW_SECRET is non-zero, secret
keys are also deleted. */
gpgme_error_t
gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret)
{
gpgme_error_t err = delete_start (ctx, 1, key, allow_secret);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -0,0 +1,169 @@
/* edit.c - Key edit function.
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include "gpgme.h"
#include "context.h"
#include "ops.h"
typedef struct
{
/* The user callback function and its hook value. */
gpgme_edit_cb_t fnc;
void *fnc_value;
} *op_data_t;
static gpgme_error_t
edit_status_handler (void *priv, gpgme_status_code_t status, char *args)
{
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
gpgme_error_t err;
void *hook;
op_data_t opd;
err = _gpgme_passphrase_status_handler (priv, status, args);
if (err)
return err;
err = _gpgme_progress_status_handler (priv, status, args);
if (err)
return err;
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
opd = hook;
if (err)
return err;
return (*opd->fnc) (opd->fnc_value, status, args, -1);
}
static gpgme_error_t
command_handler (void *priv, gpgme_status_code_t status, const char *args,
int fd)
{
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
gpgme_error_t err;
int processed = 0;
if (ctx->passphrase_cb)
{
err = _gpgme_passphrase_command_handler_internal (ctx, status, args,
fd, &processed);
if (err)
return err;
}
if (!processed)
{
void *hook;
op_data_t opd;
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
opd = hook;
if (err)
return err;
return (*opd->fnc) (opd->fnc_value, status, args, fd);
}
return 0;
}
static gpgme_error_t
edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
{
gpgme_error_t err;
void *hook;
op_data_t opd;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
if (!fnc || !out)
return gpg_error (GPG_ERR_INV_VALUE);
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
opd = hook;
if (err)
return err;
opd->fnc = fnc;
opd->fnc_value = fnc_value;
err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
ctx, out);
if (err)
return err;
_gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
return _gpgme_engine_op_edit (ctx->engine, type, key, out, ctx);
}
gpgme_error_t
gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
{
return edit_start (ctx, 0, 0, key, fnc, fnc_value, out);
}
/* Edit the key KEY. Send status and command requests to FNC and
output of edit commands to OUT. */
gpgme_error_t
gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
{
gpgme_error_t err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}
gpgme_error_t
gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
gpgme_edit_cb_t fnc, void *fnc_value,
gpgme_data_t out)
{
return edit_start (ctx, 0, 1, key, fnc, fnc_value, out);
}
/* Edit the card for the key KEY. Send status and command requests to
FNC and output of edit commands to OUT. */
gpgme_error_t
gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
{
gpgme_error_t err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -0,0 +1,109 @@
/* encrypt-sign.c - encrypt and verify functions
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "gpgme.h"
#include "context.h"
#include "ops.h"
static gpgme_error_t
encrypt_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
gpgme_error_t err;
err = _gpgme_progress_status_handler (priv, code, args);
if (!err)
err = _gpgme_encrypt_status_handler (priv, code, args);
if (!err)
err = _gpgme_sign_status_handler (priv, code, args);
return err;
}
static gpgme_error_t
encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t cipher)
{
gpgme_error_t err;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
if (!plain)
return gpg_error (GPG_ERR_NO_DATA);
if (!cipher || !recp)
return gpg_error (GPG_ERR_INV_VALUE);
err = _gpgme_op_encrypt_init_result (ctx);
if (err)
return err;
err = _gpgme_op_sign_init_result (ctx);
if (err)
return err;
if (ctx->passphrase_cb)
{
err = _gpgme_engine_set_command_handler
(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
if (err)
return err;
}
_gpgme_engine_set_status_handler (ctx->engine,
encrypt_sign_status_handler, ctx);
return _gpgme_engine_op_encrypt_sign (ctx->engine, recp, flags, plain,
cipher, ctx->use_armor,
ctx /* FIXME */);
}
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
store the resulting ciphertext in CIPHER. Also sign the ciphertext
with the signers in CTX. */
gpgme_error_t
gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t cipher)
{
return encrypt_sign_start (ctx, 0, recp, flags, plain, cipher);
}
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
store the resulting ciphertext in CIPHER. Also sign the ciphertext
with the signers in CTX. */
gpgme_error_t
gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t cipher)
{
gpgme_error_t err = encrypt_sign_start (ctx, 1, recp, flags, plain, cipher);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -0,0 +1,221 @@
/* encrypt.c - Encrypt function.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "gpgme.h"
#include "context.h"
#include "ops.h"
typedef struct
{
struct _gpgme_op_encrypt_result result;
/* A pointer to the next pointer of the last invalid recipient in
the list. This makes appending new invalid recipients painless
while preserving the order. */
gpgme_invalid_key_t *lastp;
} *op_data_t;
static void
release_op_data (void *hook)
{
op_data_t opd = (op_data_t) hook;
gpgme_invalid_key_t invalid_recipient = opd->result.invalid_recipients;
while (invalid_recipient)
{
gpgme_invalid_key_t next = invalid_recipient->next;
if (invalid_recipient->fpr)
free (invalid_recipient->fpr);
invalid_recipient = next;
}
}
gpgme_encrypt_result_t
gpgme_op_encrypt_result (gpgme_ctx_t ctx)
{
void *hook;
op_data_t opd;
gpgme_error_t err;
err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
opd = hook;
if (err || !opd)
return NULL;
return &opd->result;
}
gpgme_error_t
_gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
char *args)
{
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
gpgme_error_t err;
void *hook;
op_data_t opd;
err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
opd = hook;
if (err)
return err;
switch (code)
{
case GPGME_STATUS_EOF:
if (opd->result.invalid_recipients)
return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
break;
case GPGME_STATUS_INV_RECP:
err = _gpgme_parse_inv_recp (args, opd->lastp);
if (err)
return err;
opd->lastp = &(*opd->lastp)->next;
break;
case GPGME_STATUS_NO_RECP:
/* Should not happen, because we require at least one recipient. */
return gpg_error (GPG_ERR_GENERAL);
default:
break;
}
return 0;
}
static gpgme_error_t
encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
gpgme_error_t err;
err = _gpgme_progress_status_handler (priv, code, args);
if (!err)
err = _gpgme_passphrase_status_handler (priv, code, args);
return err;
}
static gpgme_error_t
encrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
return _gpgme_progress_status_handler (priv, code, args)
|| _gpgme_encrypt_status_handler (priv, code, args);
}
gpgme_error_t
_gpgme_op_encrypt_init_result (gpgme_ctx_t ctx)
{
gpgme_error_t err;
void *hook;
op_data_t opd;
err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, sizeof (*opd),
release_op_data);
opd = hook;
if (err)
return err;
opd->lastp = &opd->result.invalid_recipients;
return 0;
}
static gpgme_error_t
encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t cipher)
{
gpgme_error_t err;
int symmetric = 0;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
err = _gpgme_op_encrypt_init_result (ctx);
if (err)
return err;
if (!recp)
symmetric = 1;
if (!plain)
return gpg_error (GPG_ERR_NO_DATA);
if (!cipher)
return gpg_error (GPG_ERR_INV_VALUE);
if (recp && ! *recp)
return gpg_error (GPG_ERR_INV_VALUE);
if (symmetric && ctx->passphrase_cb)
{
/* Symmetric encryption requires a passphrase. */
err = _gpgme_engine_set_command_handler
(ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
if (err)
return err;
}
_gpgme_engine_set_status_handler (ctx->engine,
symmetric
? encrypt_sym_status_handler
: encrypt_status_handler,
ctx);
return _gpgme_engine_op_encrypt (ctx->engine, recp, flags, plain, cipher,
ctx->use_armor);
}
gpgme_error_t
gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t cipher)
{
return encrypt_start (ctx, 0, recp, flags, plain, cipher);
}
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
store the resulting ciphertext in CIPHER. */
gpgme_error_t
gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t cipher)
{
gpgme_error_t err = encrypt_start (ctx, 1, recp, flags, plain, cipher);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -0,0 +1,97 @@
/* engine-backend.h - A crypto backend for the engine interface.
Copyright (C) 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef ENGINE_BACKEND_H
#define ENGINE_BACKEND_H
#include "engine.h"
/* FIXME: Correct check? */
#ifdef GPGSM_PATH
#define ENABLE_GPGSM 1
#endif
struct engine_ops
{
/* Static functions. */
const char *(*get_file_name) (void);
const char *(*get_version) (void);
const char *(*get_req_version) (void);
gpgme_error_t (*new) (void **r_engine,
const char *lc_ctype, const char *lc_messages);
/* Member functions. */
void (*release) (void *engine);
void (*set_status_handler) (void *engine, engine_status_handler_t fnc,
void *fnc_value);
gpgme_error_t (*set_command_handler) (void *engine,
engine_command_handler_t fnc,
void *fnc_value, gpgme_data_t data);
gpgme_error_t (*set_colon_line_handler) (void *engine,
engine_colon_line_handler_t fnc,
void *fnc_value);
gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph,
gpgme_data_t plain);
gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret);
gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t (*encrypt) (void *engine, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t ciph,
int use_armor);
gpgme_error_t (*encrypt_sign) (void *engine, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t ciph,
int use_armor, gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t (*export) (void *engine, const char *pattern,
unsigned int reserved, gpgme_data_t keydata,
int use_armor);
gpgme_error_t (*export_ext) (void *engine, const char *pattern[],
unsigned int reserved, gpgme_data_t keydata,
int use_armor);
gpgme_error_t (*genkey) (void *engine, gpgme_data_t help_data, int use_armor,
gpgme_data_t pubkey, gpgme_data_t seckey);
gpgme_error_t (*import) (void *engine, gpgme_data_t keydata);
gpgme_error_t (*keylist) (void *engine, const char *pattern,
int secret_only, gpgme_keylist_mode_t mode);
gpgme_error_t (*keylist_ext) (void *engine, const char *pattern[],
int secret_only, int reserved,
gpgme_keylist_mode_t mode);
gpgme_error_t (*sign) (void *engine, gpgme_data_t in, gpgme_data_t out,
gpgme_sig_mode_t mode, int use_armor,
int use_textmode,
int include_certs, gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t (*trustlist) (void *engine, const char *pattern);
gpgme_error_t (*verify) (void *engine, gpgme_data_t sig,
gpgme_data_t signed_text,
gpgme_data_t plaintext);
void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs);
void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data);
gpgme_error_t (*cancel) (void *engine);
};
extern struct engine_ops _gpgme_engine_ops_gpg; /* OpenPGP. */
#ifdef ENABLE_GPGSM
extern struct engine_ops _gpgme_engine_ops_gpgsm; /* CMS. */
#endif
#endif /* ENGINE_BACKEND_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,499 @@
/* engine.c - GPGME engine support.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 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 <errno.h>
#include "gpgme.h"
#include "util.h"
#include "sema.h"
#include "ops.h"
#include "engine.h"
#include "engine-backend.h"
struct engine
{
struct engine_ops *ops;
void *engine;
};
static struct engine_ops *engine_ops[] =
{
&_gpgme_engine_ops_gpg, /* OpenPGP. */
#ifdef ENABLE_GPGSM
&_gpgme_engine_ops_gpgsm /* CMS. */
#else
NULL
#endif
};
/* Get the file name of the engine for PROTOCOL. */
static const char *
engine_get_file_name (gpgme_protocol_t proto)
{
if (proto > DIM (engine_ops))
return NULL;
if (engine_ops[proto] && engine_ops[proto]->get_file_name)
return (*engine_ops[proto]->get_file_name) ();
else
return NULL;
}
/* Get the version number of the engine for PROTOCOL. */
static const char *
engine_get_version (gpgme_protocol_t proto)
{
if (proto > DIM (engine_ops))
return NULL;
if (engine_ops[proto] && engine_ops[proto]->get_version)
return (*engine_ops[proto]->get_version) ();
else
return NULL;
}
/* Get the required version number of the engine for PROTOCOL. */
static const char *
engine_get_req_version (gpgme_protocol_t proto)
{
if (proto > DIM (engine_ops))
return NULL;
if (engine_ops[proto] && engine_ops[proto]->get_req_version)
return (*engine_ops[proto]->get_req_version) ();
else
return NULL;
}
/* Verify the version requirement for the engine for PROTOCOL. */
gpgme_error_t
gpgme_engine_check_version (gpgme_protocol_t proto)
{
return _gpgme_compare_versions (engine_get_version (proto),
engine_get_req_version (proto))
? 0 : gpg_error (GPG_ERR_INV_ENGINE);
}
/* Get the information about the configured and installed engines. A
pointer to the first engine in the statically allocated linked list
is returned in *INFO. If an error occurs, it is returned. */
gpgme_error_t
gpgme_get_engine_info (gpgme_engine_info_t *info)
{
static gpgme_engine_info_t engine_info;
DEFINE_STATIC_LOCK (engine_info_lock);
LOCK (engine_info_lock);
if (!engine_info)
{
gpgme_engine_info_t *lastp = &engine_info;
gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
GPGME_PROTOCOL_CMS };
unsigned int proto;
for (proto = 0; proto < DIM (proto_list); proto++)
{
const char *file_name = engine_get_file_name (proto_list[proto]);
if (!file_name)
continue;
*lastp = malloc (sizeof (*engine_info));
if (!*lastp)
{
int saved_errno = errno;
while (engine_info)
{
gpgme_engine_info_t next_info = engine_info->next;
free (engine_info);
engine_info = next_info;
}
UNLOCK (engine_info_lock);
return gpg_error_from_errno (saved_errno);
}
(*lastp)->protocol = proto_list[proto];
(*lastp)->file_name = file_name;
(*lastp)->version = engine_get_version (proto_list[proto]);
(*lastp)->req_version = engine_get_req_version (proto_list[proto]);
(*lastp)->next = NULL;
lastp = &(*lastp)->next;
}
}
UNLOCK (engine_info_lock);
*info = engine_info;
return 0;
}
gpgme_error_t
_gpgme_engine_new (gpgme_protocol_t proto, engine_t *r_engine,
const char *lc_ctype, const char *lc_messages)
{
engine_t engine;
const char *file_name;
const char *version;
if (proto > DIM (engine_ops))
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine_ops[proto])
return gpg_error (GPG_ERR_INV_ENGINE);
file_name = engine_get_file_name (proto);
version = engine_get_version (proto);
if (!file_name || !version)
return gpg_error (GPG_ERR_INV_ENGINE);
engine = calloc (1, sizeof *engine);
if (!engine)
return gpg_error_from_errno (errno);
engine->ops = engine_ops[proto];
if (engine_ops[proto]->new)
{
gpgme_error_t err = (*engine_ops[proto]->new) (&engine->engine,
lc_ctype,
lc_messages);
if (err)
{
free (engine);
return err;
}
}
else
engine->engine = NULL;
*r_engine = engine;
return 0;
}
void
_gpgme_engine_release (engine_t engine)
{
if (!engine)
return;
if (engine->ops->release)
(*engine->ops->release) (engine->engine);
free (engine);
}
void
_gpgme_engine_set_status_handler (engine_t engine,
engine_status_handler_t fnc, void *fnc_value)
{
if (!engine)
return;
if (engine->ops->set_status_handler)
(*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
}
gpgme_error_t
_gpgme_engine_set_command_handler (engine_t engine,
engine_command_handler_t fnc,
void *fnc_value,
gpgme_data_t linked_data)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->set_command_handler)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->set_command_handler) (engine->engine,
fnc, fnc_value, linked_data);
}
gpgme_error_t
_gpgme_engine_set_colon_line_handler (engine_t engine,
engine_colon_line_handler_t fnc,
void *fnc_value)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->set_colon_line_handler)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->set_colon_line_handler) (engine->engine,
fnc, fnc_value);
}
gpgme_error_t
_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
gpgme_data_t plain)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->decrypt)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->decrypt) (engine->engine, ciph, plain);
}
gpgme_error_t
_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->delete)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->delete) (engine->engine, key, allow_secret);
}
gpgme_error_t
_gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->edit)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->edit) (engine->engine, type, key, out, ctx);
}
gpgme_error_t
_gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->encrypt)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
use_armor);
}
gpgme_error_t
_gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t ciph,
int use_armor, gpgme_ctx_t ctx /* FIXME */)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->encrypt_sign)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
plain, ciph, use_armor, ctx);
}
gpgme_error_t
_gpgme_engine_op_export (engine_t engine, const char *pattern,
unsigned int reserved, gpgme_data_t keydata,
int use_armor)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->export)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->export) (engine->engine, pattern, reserved,
keydata, use_armor);
}
gpgme_error_t
_gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
unsigned int reserved, gpgme_data_t keydata,
int use_armor)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->export_ext)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
keydata, use_armor);
}
gpgme_error_t
_gpgme_engine_op_genkey (engine_t engine, gpgme_data_t help_data,
int use_armor, gpgme_data_t pubkey,
gpgme_data_t seckey)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->genkey)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
pubkey, seckey);
}
gpgme_error_t
_gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->import)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->import) (engine->engine, keydata);
}
gpgme_error_t
_gpgme_engine_op_keylist (engine_t engine, const char *pattern,
int secret_only, gpgme_keylist_mode_t mode)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->keylist)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode);
}
gpgme_error_t
_gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
int secret_only, int reserved,
gpgme_keylist_mode_t mode)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->keylist_ext)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
reserved, mode);
}
gpgme_error_t
_gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
gpgme_sig_mode_t mode, int use_armor,
int use_textmode, int include_certs,
gpgme_ctx_t ctx /* FIXME */)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->sign)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
use_textmode, include_certs, ctx);
}
gpgme_error_t
_gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->trustlist)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->trustlist) (engine->engine, pattern);
}
gpgme_error_t
_gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
gpgme_data_t signed_text, gpgme_data_t plaintext)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->verify)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
}
void
_gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
{
if (!engine)
return;
(*engine->ops->set_io_cbs) (engine->engine, io_cbs);
}
void
_gpgme_engine_io_event (engine_t engine,
gpgme_event_io_t type, void *type_data)
{
if (!engine)
return;
(*engine->ops->io_event) (engine->engine, type, type_data);
}
gpgme_error_t
_gpgme_engine_cancel (engine_t engine)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->cancel)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->cancel) (engine->engine);
}

View File

@ -0,0 +1,115 @@
/* engine.h - GPGME engine interface.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef ENGINE_H
#define ENGINE_H
#include "gpgme.h"
struct engine;
typedef struct engine *engine_t;
typedef gpgme_error_t (*engine_status_handler_t) (void *priv,
gpgme_status_code_t code,
char *args);
typedef gpgme_error_t (*engine_colon_line_handler_t) (void *priv, char *line);
typedef gpgme_error_t (*engine_command_handler_t) (void *priv,
gpgme_status_code_t code,
const char *keyword,
int fd);
gpgme_error_t _gpgme_engine_new (gpgme_protocol_t proto,
engine_t *r_engine,
const char *lc_ctype,
const char *lc_messages);
void _gpgme_engine_release (engine_t engine);
void _gpgme_engine_set_status_handler (engine_t engine,
engine_status_handler_t fnc,
void *fnc_value);
gpgme_error_t _gpgme_engine_set_command_handler (engine_t engine,
engine_command_handler_t fnc,
void *fnc_value,
gpgme_data_t data);
gpgme_error_t
_gpgme_engine_set_colon_line_handler (engine_t engine,
engine_colon_line_handler_t fnc,
void *fnc_value);
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine,
gpgme_data_t ciph,
gpgme_data_t plain);
gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret);
gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,
gpgme_key_t key, gpgme_data_t out,
gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t _gpgme_engine_op_encrypt (engine_t engine,
gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain, gpgme_data_t ciph,
int use_armor);
gpgme_error_t _gpgme_engine_op_encrypt_sign (engine_t engine,
gpgme_key_t recp[],
gpgme_encrypt_flags_t flags,
gpgme_data_t plain,
gpgme_data_t ciph,
int use_armor,
gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t _gpgme_engine_op_export (engine_t engine, const char *pattern,
unsigned int reserved,
gpgme_data_t keydata, int use_armor);
gpgme_error_t _gpgme_engine_op_export_ext (engine_t engine,
const char *pattern[],
unsigned int reserved,
gpgme_data_t keydata,
int use_armor);
gpgme_error_t _gpgme_engine_op_genkey (engine_t engine,
gpgme_data_t help_data,
int use_armor, gpgme_data_t pubkey,
gpgme_data_t seckey);
gpgme_error_t _gpgme_engine_op_import (engine_t engine,
gpgme_data_t keydata);
gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,
const char *pattern,
int secret_only,
gpgme_keylist_mode_t mode);
gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine,
const char *pattern[],
int secret_only,
int reserved,
gpgme_keylist_mode_t mode);
gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in,
gpgme_data_t out, gpgme_sig_mode_t mode,
int use_armor, int use_textmode,
int include_certs,
gpgme_ctx_t ctx /* FIXME */);
gpgme_error_t _gpgme_engine_op_trustlist (engine_t engine,
const char *pattern);
gpgme_error_t _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
gpgme_data_t signed_text,
gpgme_data_t plaintext);
void _gpgme_engine_set_io_cbs (engine_t engine,
gpgme_io_cbs_t io_cbs);
void _gpgme_engine_io_event (engine_t engine,
gpgme_event_io_t type, void *type_data);
gpgme_error_t _gpgme_engine_cancel (engine_t engine);
#endif /* ENGINE_H */

View File

@ -0,0 +1,91 @@
/* error.c - Error handling for GPGME.
Copyright (C) 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <gpgme.h>
/* Return a pointer to a string containing a description of the error
code in the error value ERR. */
const char *
gpgme_strerror (gpgme_error_t err)
{
return gpg_strerror (err);
}
/* Return the error string for ERR in the user-supplied buffer BUF of
size BUFLEN. This function is, in contrast to gpg_strerror,
thread-safe if a thread-safe strerror_r() function is provided by
the system. If the function succeeds, 0 is returned and BUF
contains the string describing the error. If the buffer was not
large enough, ERANGE is returned and BUF contains as much of the
beginning of the error string as fits into the buffer. */
int
gpgme_strerror_r (gpg_error_t err, char *buf, size_t buflen)
{
return gpg_strerror_r (err, buf, buflen);
}
/* Return a pointer to a string containing a description of the error
source in the error value ERR. */
const char *
gpgme_strsource (gpgme_error_t err)
{
return gpg_strsource (err);
}
/* Retrieve the error code for the system error ERR. This returns
GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
this). */
gpgme_err_code_t
gpgme_err_code_from_errno (int err)
{
return gpg_err_code_from_errno (err);
}
/* Retrieve the system error for the error code CODE. This returns 0
if CODE is not a system error code. */
int
gpgme_err_code_to_errno (gpgme_err_code_t code)
{
return gpg_err_code_from_errno (code);
}
/* Return an error value with the error source SOURCE and the system
error ERR. */
gpgme_error_t
gpgme_err_make_from_errno (gpg_err_source_t source, int err)
{
return gpg_err_make_from_errno (source, err);
}
/* Return an error value with the system error ERR. */
gpgme_err_code_t
gpgme_error_from_errno (int err)
{
return gpgme_error (gpg_err_code_from_errno (err));
}

View File

@ -0,0 +1,116 @@
/* export.c - Export a key.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "gpgme.h"
#include "context.h"
#include "ops.h"
static gpgme_error_t
export_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
return 0;
}
static gpgme_error_t
export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
unsigned int reserved, gpgme_data_t keydata)
{
gpgme_error_t err;
if (!keydata)
return gpg_error (GPG_ERR_INV_VALUE);
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
_gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
return _gpgme_engine_op_export (ctx->engine, pattern, reserved, keydata,
ctx->use_armor);
}
/* Export the keys listed in RECP into KEYDATA. */
gpgme_error_t
gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern,
unsigned int reserved, gpgme_data_t keydata)
{
return export_start (ctx, 0, pattern, reserved, keydata);
}
/* Export the keys listed in RECP into KEYDATA. */
gpgme_error_t
gpgme_op_export (gpgme_ctx_t ctx, const char *pattern, unsigned int reserved,
gpgme_data_t keydata)
{
gpgme_error_t err = export_start (ctx, 1, pattern, reserved, keydata);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}
static gpgme_error_t
export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
unsigned int reserved, gpgme_data_t keydata)
{
gpgme_error_t err;
if (!keydata)
return gpg_error (GPG_ERR_INV_VALUE);
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
_gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
return _gpgme_engine_op_export_ext (ctx->engine, pattern, reserved, keydata,
ctx->use_armor);
}
/* Export the keys listed in RECP into KEYDATA. */
gpgme_error_t
gpgme_op_export_ext_start (gpgme_ctx_t ctx, const char *pattern[],
unsigned int reserved, gpgme_data_t keydata)
{
return export_ext_start (ctx, 0, pattern, reserved, keydata);
}
/* Export the keys listed in RECP into KEYDATA. */
gpgme_error_t
gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[],
unsigned int reserved, gpgme_data_t keydata)
{
gpgme_error_t err = export_ext_start (ctx, 1, pattern, reserved, keydata);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -0,0 +1,44 @@
/* funopen.c - Replacement for funopen.
* Copyright (C) 2003 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>
#ifdef HAVE_FOPENCOOKIE
FILE *
funopen(const void *cookie, cookie_read_function_t *readfn,
cookie_write_function_t *writefn,
cookie_seek_function_t *seekfn,
cookie_close_function_t *closefn)
{
cookie_io_functions_t io = { read: readfn, write: writefn,
seek: seekfn,
close: closefn };
return fopencookie ((void *) cookie,
readfn ? ( writefn ? "rw" : "r" )
: ( writefn ? "w" : ""), io);
}
#else
#error No known way to implement funopen.
#endif

View File

@ -0,0 +1,204 @@
/* genkey.c - Key generation.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
This file is part of GPGME.
GPGME is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GPGME is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "gpgme.h"
#include "context.h"
#include "ops.h"
typedef struct
{
struct _gpgme_op_genkey_result result;
/* The key parameters passed to the crypto engine. */
gpgme_data_t key_parameter;
} *op_data_t;
static void
release_op_data (void *hook)
{
op_data_t opd = (op_data_t) hook;
if (opd->result.fpr)
free (opd->result.fpr);
if (opd->key_parameter)
gpgme_data_release (opd->key_parameter);
}
gpgme_genkey_result_t
gpgme_op_genkey_result (gpgme_ctx_t ctx)
{
void *hook;
op_data_t opd;
gpgme_error_t err;
err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook, -1, NULL);
opd = hook;
if (err || !opd)
return NULL;
return &opd->result;
}
static gpgme_error_t
genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
gpgme_error_t err;
void *hook;
op_data_t opd;
/* Pipe the status code through the progress status handler. */
err = _gpgme_progress_status_handler (ctx, code, args);
if (err)
return err;
err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook, -1, NULL);
opd = hook;
if (err)
return err;
switch (code)
{
case GPGME_STATUS_KEY_CREATED:
if (args && *args)
{
if (*args == 'B' || *args == 'P')
opd->result.primary = 1;
if (*args == 'B' || *args == 'S')
opd->result.sub = 1;
if (args[1] == ' ')
{
if (opd->result.fpr)
free (opd->result.fpr);
opd->result.fpr = strdup (&args[2]);
if (!opd->result.fpr)
return gpg_error_from_errno (errno);
}
}
break;
case GPGME_STATUS_EOF:
/* FIXME: Should return some more useful error value. */
if (!opd->result.primary && !opd->result.sub)
return gpg_error (GPG_ERR_GENERAL);
break;
default:
break;
}
return 0;
}
static gpgme_error_t
get_key_parameter (const char *parms, gpgme_data_t *key_parameter)
{
const char *content;
const char *attrib;
const char *endtag;
/* Extract the key parameter from the XML structure. */
parms = strstr (parms, "<GnupgKeyParms ");
if (!parms)
return gpg_error (GPG_ERR_INV_VALUE);
content = strchr (parms, '>');
if (!content)
return gpg_error (GPG_ERR_INV_VALUE);
content++;
attrib = strstr (parms, "format=\"internal\"");
if (!attrib || attrib >= content)
return gpg_error (GPG_ERR_INV_VALUE);
endtag = strstr (content, "</GnupgKeyParms>");
/* FIXME: Check that there are no control statements inside. */
while (*content == '\n')
content++;
return gpgme_data_new_from_mem (key_parameter, content,
endtag - content, 1);
}
static gpgme_error_t
genkey_start (gpgme_ctx_t ctx, int synchronous, const char *parms,
gpgme_data_t pubkey, gpgme_data_t seckey)
{
gpgme_error_t err;
void *hook;
op_data_t opd;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,
sizeof (*opd), release_op_data);
opd = hook;
if (err)
return err;
err = get_key_parameter (parms, &opd->key_parameter);
if (err)
return err;
_gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
return _gpgme_engine_op_genkey (ctx->engine, opd->key_parameter,
ctx->use_armor, pubkey, seckey);
}
/* Generate a new keypair and add it to the keyring. PUBKEY and
SECKEY should be null for now. PARMS specifies what keys should be
generated. */
gpgme_error_t
gpgme_op_genkey_start (gpgme_ctx_t ctx, const char *parms,
gpgme_data_t pubkey, gpgme_data_t seckey)
{
return genkey_start (ctx, 0, parms, pubkey, seckey);
}
/* Generate a new keypair and add it to the keyring. PUBKEY and
SECKEY should be null for now. PARMS specifies what keys should be
generated. */
gpgme_error_t
gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms, gpgme_data_t pubkey,
gpgme_data_t seckey)
{
gpgme_error_t err;
err = genkey_start (ctx, 1, parms, pubkey, seckey);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

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