-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 NotDashEscaped: You need GnuPG to verify this message This is a patch file to create version 1.1.0 from 1.0.3. Please check the signature of this patch file: zcat somepath/gpgme-1.0.3-1.1.0.diff.gz | gpg --verify Change to directory gpgme-1.0.3 (or however you renamed it) and give this command: zcat somepath/gpgme-1.0.3-1.1.0.diff.gz | patch -p1 It is a good idea to rename your current directory to gpgme-1.1.0 now. diff -urpNP gpgme-1.0.3/VERSION gpgme-1.1.0/VERSION --- gpgme-1.0.3/VERSION 2005-06-20 19:35:41.000000000 +0000 +++ gpgme-1.1.0/VERSION 2005-10-01 21:15:18.000000000 +0000 @@ -1 +1 @@ -1.0.3 +1.1.0 diff -urpNP gpgme-1.0.3/ChangeLog gpgme-1.1.0/ChangeLog --- gpgme-1.0.3/ChangeLog 2005-06-20 19:15:21.000000000 +0000 +++ gpgme-1.1.0/ChangeLog 2005-10-01 21:13:02.000000000 +0000 @@ -1,13 +1,53 @@ -2005-06-20 Marcus Brinkmann +2005-10-01 Marcus Brinkmann + + Released 1.1.0. + + * configure.ac (LIBGPGME_LT_CURRENT, LIBGPGME_LT_AGE): Bump for + release. + (LIBGPGME_LT_REVISION): Reset to 0 for release. + +2005-09-12 Marcus Brinkmann + + * configure.ac (HAVE_PTH): Don't add $PTH_CFLAGS to $CFLAGS here. + +2005-08-26 Werner Koch + + * configure.ac (SEPCONSTANTS): New to define DIRSEP_C et al. + +2005-08-19 Werner Koch + + * configure.ac [W32]: Create values for versioninfo.rc and list + substuture versioninfo.rc. + * configure.ac: Define ENABLE_GPGSM. + +2005-08-08 Werner Koch + + * configure.ac (stpcpy): Changed from replace to test. + +2005-03-24 Marcus Brinkmann + + * configure.ac (AH_BOTTOM): Removed. + +2005-03-09 Werner Koch + + * acinclude.m4 (GNUPG_CHECK_VA_COPY): Assume no when cross-compiling. + + * Makefile.am (EXTRA_DIST): Include autogen.sh + + * autogen.sh: Added the usual code to build for W32 (--build-w32). + + * configure.ac: Fixed the mingw32 host string, removed OS/2 stuff. + (HAVE_DRIVE_LETTERS): Removed. + (HAVE_W32_SYSTEM): Added. + (AC_GNU_SOURCE): New to replace the identical AH_VERBATIM. + (AH_BOTTOM): Added. - * configure.ac: Update the version information for the release. - 2004-12-28 Werner Koch Released 1.0.2. - * Makefile.am (AUTOMAKE_OPTIONS): Build bzip 2 version - (ACLOCAL_AMFLAGS): Add -I m4 + * Makefile.am (AUTOMAKE_OPTIONS): Build bzip 2 version. + (ACLOCAL_AMFLAGS): Add -I m4. * configure.ac: Require automake 1.9.3 and autoconf 2.59. * acinclude.m4: Changed quoting for automake 1.9. * README: Use SHA1 instead of MD5. @@ -568,7 +608,7 @@ * autogen.sh: Added option --build-w32. - Copyright 2001, 2002, 2003, 2004 g10 Code GmbH + Copyright 2001, 2002, 2003, 2004, 2005 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff -urpNP gpgme-1.0.3/INSTALL gpgme-1.1.0/INSTALL --- gpgme-1.0.3/INSTALL 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/INSTALL 2005-09-08 14:42:33.000000000 +0000 @@ -1,16 +1,13 @@ -Installation Instructions -************************* +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free -Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives + 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. + These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -70,9 +67,9 @@ The simplest way to compile this package 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. + 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 @@ -85,7 +82,7 @@ is an example: Compiling For Multiple Architectures ==================================== -You can compile the package for more than one kind of computer at the + 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 @@ -102,19 +99,19 @@ for another architecture. Installation Names ================== -By default, `make install' will install the package's files in + 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=PREFIX'. +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=PREFIX', the package will -use PREFIX as the prefix for installing programs and libraries. +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=DIR' to specify different values for particular +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. @@ -125,7 +122,7 @@ option `--program-prefix=PREFIX' or `--p Optional Features ================= -Some packages pay attention to `--enable-FEATURE' options to + 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 @@ -140,11 +137,11 @@ you can use the `configure' options `--x 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 + 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: @@ -170,9 +167,9 @@ 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'. + 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. @@ -181,7 +178,7 @@ A warning: not all `configure' scripts l Defining Variables ================== -Variables not defined in a site shell script can be set in the + 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 @@ -195,7 +192,8 @@ overridden in the site shell script). `configure' Invocation ====================== -`configure' recognizes the following options to control how it operates. + `configure' recognizes the following options to control how it +operates. `--help' `-h' diff -urpNP gpgme-1.0.3/Makefile.am gpgme-1.1.0/Makefile.am --- gpgme-1.0.3/Makefile.am 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/Makefile.am 2005-09-08 14:42:33.000000000 +0000 @@ -1,6 +1,6 @@ # Makefile.am - Top level Makefile for GPGME. # Copyright (C) 2000 Werner Koch (dd9jn) -# Copyright (C) 2001, 2002, 2004 g10 Code GmbH +# Copyright (C) 2001, 2002, 2004, 2005 g10 Code GmbH # # This file is part of GPGME. # @@ -23,7 +23,7 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = dist-bzip2 -EXTRA_DIST = gpgme.spec.in +EXTRA_DIST = gpgme.spec.in autogen.sh if BUILD_ASSUAN assuan = assuan diff -urpNP gpgme-1.0.3/Makefile.in gpgme-1.1.0/Makefile.in --- gpgme-1.0.3/Makefile.in 2005-06-20 19:35:25.000000000 +0000 +++ gpgme-1.1.0/Makefile.in 2005-10-01 21:13:48.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -16,7 +16,7 @@ # Makefile.am - Top level Makefile for GPGME. # Copyright (C) 2000 Werner Koch (dd9jn) -# Copyright (C) 2001, 2002, 2004 g10 Code GmbH +# Copyright (C) 2001, 2002, 2004, 2005 g10 Code GmbH # # This file is part of GPGME. # @@ -108,6 +108,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -120,6 +122,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -148,6 +151,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -186,12 +191,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ @@ -231,7 +239,7 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = dist-bzip2 -EXTRA_DIST = gpgme.spec.in +EXTRA_DIST = gpgme.spec.in autogen.sh @BUILD_ASSUAN_FALSE@assuan = @BUILD_ASSUAN_TRUE@assuan = assuan @BUILD_COMPLUS_FALSE@complus = diff -urpNP gpgme-1.0.3/NEWS gpgme-1.1.0/NEWS --- gpgme-1.0.3/NEWS 2005-06-20 19:16:42.000000000 +0000 +++ gpgme-1.1.0/NEWS 2005-10-01 21:13:02.000000000 +0000 @@ -1,3 +1,69 @@ +Noteworthy changes in version 1.1.0 (2005-10-01) +------------------------------------------------ + + * You can now configure the backend engine file name and home + directory to be used, as default and per context. + + * Information about the recipients of an encrypted text is now + available at decryption time. + + * New status GPGME_STATUS_PLAINTEXT. This is analyzed by the decrypt + and verify handlers, the information about the plaintext filename, + if available is made available in the new field file_name of the + respective result structure. + + * The code for "automagically detecting the thread library" has been + removed from libgpgme. It is deprecated since version 0.4.3. + Since then, you had to link against libgpgme-pthread for + applications using pthread and libgpgme-pth for applications using + GNU Pth. + + The code was removed because it caused compilation problems on + systems where the pthread.h header from GNU Pth is available in + addition to the system header (FreeBSD 6 and later for example). + + * "./autogen.sh --build-w32" does now build gpgme.dll. + + * [W32] The environment variable GPGME_DEBUG now uses a semicolon as + delimiter. The standard install directory is used when locating + gpg or gpgsm before finally falling back to the hardwired name. + + * There is a new flag for keys and subkeys, is_qualified, which + indicates if a key can be used for qualified signatures according + to local government regulations. + + * You can associate a filename with a data object using the new + function gpgme_data_set_file_name(). This filename will be stored + in the output when encrypting or signing the data and will be + returned when decrypting or verifying the output data. + + * You can now set notation data at signature creation with the new + function gpgme_sig_notation_add(). + + * Interface changes relative to the 1.0.3 release: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +gpgme_set_engine_info NEW +gpgme_ctx_get_engine_info NEW +gpgme_ctx_set_engine_info NEW +gpgme_recipient_t NEW +gpgme_decrypt_result_t EXTENDED: New field recipients. +gpgme_verify_result_t EXTENDED: New fields pubkey_algo, hash_algo. +gpgme_decrypt_result_t EXTENDED: New field plaintext_filename. +gpgme_verify_result_t EXTENDED: New field plaintext_filename. +GPGME_STATUS_PLAINTEXT NEW +gpgme_key_t EXTENDED: New field is_qualified. +gpgme_subkey_t EXTENDED: New field is_qualified. +gpgme_data_get_file_name NEW +gpgme_data_set_file_name NEW +gpgme_sig_notation_flags_t NEW +GPGME_SIG_NOTATION_HUMAN_READABLE NEW +GPGME_SIG_NOTATAION_CRITICAL NEW +gpgme_sig_notation_clear NEW +gpgme_sig_notation_add NEW +gpgme_sig_notation_get NEW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Noteworthy changes in version 1.0.3 (2005-06-20) ------------------------------------------------ diff -urpNP gpgme-1.0.3/TODO gpgme-1.1.0/TODO --- gpgme-1.0.3/TODO 2005-05-28 19:37:54.000000000 +0000 +++ gpgme-1.1.0/TODO 2005-10-01 20:33:52.000000000 +0000 @@ -6,12 +6,13 @@ Hey Emacs, this is -*- outline -*- mode! ** Add notation data to key signatures. * ABI's to break: +** gpgme_edit_cb_t: Add "processed" return argument + (see edit.c::command_handler). ** I/O and User Data could be made extensible. But this can be done without breaking the ABI hopefully. * All enums that should be enums need to have a maximum value to ensure a certain minimum width for extensibility. ** 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 @@ -35,6 +36,8 @@ Hey Emacs, this is -*- outline -*- mode! There is a configure time warning, though. * New features: +** Extended notation support. When gpg supports arbitrary binary + notation data, provide a user interface for that. ** notification system We need a simple notification system, probably a simple callback with a string and some optional arguments. This is for example @@ -46,20 +49,22 @@ Hey Emacs, this is -*- outline -*- mode! 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. ** 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. +** 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 ** New features requested by our dear users, but rejected or left for later consideration: +*** Allow to export secret keys. + Rejected because this is conceptually flawed. Secret keys on a + smart card can not be exported, for example. *** 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. @@ -97,19 +102,6 @@ Hey Emacs, this is -*- outline -*- mode! ** 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 @@ -150,7 +142,7 @@ Hey Emacs, this is -*- outline -*- mode! Add error checking some time after releasing a new gpgsm. -Copyright 2004 g10 Code GmbH +Copyright 2004, 2005 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff -urpNP gpgme-1.0.3/acinclude.m4 gpgme-1.1.0/acinclude.m4 diff -urpNP gpgme-1.0.3/acinclude.m4 gpgme-1.1.0/acinclude.m4 --- gpgme-1.0.3/acinclude.m4 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/acinclude.m4 2005-09-08 14:42:33.000000000 +0000 @@ -50,8 +50,11 @@ dnl Actual test code taken from glib-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([ + if test "$cross_compiling" = yes; then + gnupg_cv_must_copy_va_byval=no + else + gnupg_cv_must_copy_va_byval=no + AC_TRY_RUN([ #include void f (int i, ...) { @@ -69,10 +72,15 @@ AC_DEFUN([GNUPG_CHECK_VA_COPY], f (0, 42); return 0; } - ],gnupg_cv_must_copy_va_byval=yes) + ],gnupg_cv_must_copy_va_byval=yes) + fi ]) 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) + if test "$cross_compiling" = yes; then + AC_MSG_RESULT(assuming $gnupg_cv_must_copy_va_byval) + else + AC_MSG_RESULT($gnupg_cv_must_copy_va_byval) + fi ]) diff -urpNP gpgme-1.0.3/aclocal.m4 gpgme-1.1.0/aclocal.m4 --- gpgme-1.0.3/aclocal.m4 2005-06-20 19:35:20.000000000 +0000 +++ gpgme-1.1.0/aclocal.m4 2005-10-01 21:13:38.000000000 +0000 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.9.5 -*- Autoconf -*- +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005 Free Software Foundation, Inc. @@ -28,7 +28,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.5])]) + [AM_AUTOMAKE_VERSION([1.9.6])]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- diff -urpNP gpgme-1.0.3/assuan/ChangeLog gpgme-1.1.0/assuan/ChangeLog --- gpgme-1.0.3/assuan/ChangeLog 2005-03-24 08:25:32.000000000 +0000 +++ gpgme-1.1.0/assuan/ChangeLog 2005-10-01 20:14:48.000000000 +0000 @@ -1,3 +1,70 @@ +2005-10-01 Marcus Brinkmann + + * assuan.h (assuan_pipe_connect, assuan_pipe_connect2): Make type + of ARGV parameter const in prototype. + * assuan-pipe-connect.c (assuan_pipe_connect, + assuan_pipe_connect2): Likewise in declaration. + (assuan_pipe_connect2): Add braindead cast to make execv happy. + + * assuan-client.c (assuan_transact): Change LINE, S and D from + unsigned char * to char * to silence gcc warning. + * assuan-util.c (_assuan_log_sanitized_string): Add explicit cast + to silence gcc warning. + * assuan-inquire.c (assuan_inquire): Likewise. + +2005-08-19 Werner Koch + + * funopen.c, assuan-socket.c: Copied from libassuan CVS. + * assuan-pipe-connect.c (assuan_pipe_connect2): Add missing + declaration of PID. + +2005-08-09 Werner Koch + + * README.1st: Adjusted to cope with changes done in upstream Assuan. + + Merged changes for W32 support from libassuan. + + * assuan.h [_ASSUAN_EXT_SYM_PREFIX]: New. + * assuan-io.c [_ASSUAN_NO_PTH]: New. + * assuan-pipe-connect.c (fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: New. + (assuan_pipe_connect2) [_ASSUAN_USE_DOUBLE_FORK]: Use double fork. + (fix_signals) [_ASSUAN_USE_DOUBLE_FORK]: Do not wait.. + * assuan-logging.c, assuan-io.c: Include config.h + Replaced all usages of _WIN32 by the new HAVE_W32_SYSTEM because + there is nothing winning in this API. + * assuan-pipe-connect.c (assuan_pipe_connect2) [_WIN32]: Return + error Not Imlemented. + * assuan-logging.c (_assuan_w32_strerror): New. + * assuan-defs.h (w32_strerror): new. + * assuan-pipe-connect.c (assuan_pipe_connect2, fix_signals): + Factored signal code out to new function. + (build_w32_commandline, create_inheritable_pipe): New. Taken + from gnupg 1.9. + (assuan_pipe_connect2) [W32]: Implemented for W32. + * assuan-pipe-server.c (assuan_init_pipe_server) [W32]: Map file + descriptors using _get_osfhandle. + * assuan-socket-connect.c (assuan_socket_connect) [W32]: Allow for + a drive letter in the path. + * assuan-client.c (assuan_transact): Handle empty and comment + commands correctly. + * assuan-util.c (_assuan_calloc): Avoid integer overflow. + * assuan-util.c (assuan_set_flag, assuan_get_flag): New. + * assuan-defs.h (struct assuan_context_s): New field flags. + * assuan.h (assuan_flag_t): New with one flag value + ASSUAN_NO_WAITPID for now. + * assuan-pipe-connect.c (do_finish): Take care of the no_waitpid + flag. + * mkerrors: Include config.h into assuan-errors.c. This is + required so that assuan.h knows about the W32 macro. + +2005-08-09 Timo Schulz (ported from libassuan by wk) + + * assuan-io.c (_assuan_simple_read, _assuan_simple_write): W32 + support. + * assuan-socket.c (_assuan_close): New. + (_assuan_sock_new): New. + (_assuan_sock_bind): New. + 2005-03-22 Werner Koch * assuan-defs.h (struct assuan_io): Renamed elements READ and diff -urpNP gpgme-1.0.3/assuan/Makefile.am gpgme-1.1.0/assuan/Makefile.am --- gpgme-1.0.3/assuan/Makefile.am 2003-08-20 20:20:45.000000000 +0000 +++ gpgme-1.1.0/assuan/Makefile.am 2005-09-08 14:42:30.000000000 +0000 @@ -44,6 +44,8 @@ libassuan_la_SOURCES = \ assuan-socket-server.c \ assuan-pipe-connect.c \ assuan-socket-connect.c \ + assuan-socket.c \ + funopen.c \ assuan-io.c \ assuan-domain-connect.c \ assuan-domain-server.c \ diff -urpNP gpgme-1.0.3/assuan/Makefile.in gpgme-1.1.0/assuan/Makefile.in --- gpgme-1.0.3/assuan/Makefile.in 2005-06-20 19:35:23.000000000 +0000 +++ gpgme-1.1.0/assuan/Makefile.in 2005-10-01 21:13:44.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -33,8 +33,6 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -SOURCES = $(libassuan_la_SOURCES) - srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -75,7 +73,8 @@ am_libassuan_la_OBJECTS = assuan-util.lo assuan-buffer.lo assuan-handler.lo assuan-inquire.lo \ assuan-listen.lo assuan-connect.lo assuan-client.lo \ assuan-pipe-server.lo assuan-socket-server.lo \ - assuan-pipe-connect.lo assuan-socket-connect.lo assuan-io.lo \ + assuan-pipe-connect.lo assuan-socket-connect.lo \ + assuan-socket.lo funopen.lo assuan-io.lo \ assuan-domain-connect.lo assuan-domain-server.lo \ assuan-logging.lo libassuan_la_OBJECTS = $(am_libassuan_la_OBJECTS) @@ -108,6 +107,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -120,6 +121,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -148,6 +150,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -186,12 +190,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ @@ -252,6 +259,8 @@ libassuan_la_SOURCES = \ assuan-socket-server.c \ assuan-pipe-connect.c \ assuan-socket-connect.c \ + assuan-socket.c \ + funopen.c \ assuan-io.c \ assuan-domain-connect.c \ assuan-domain-server.c \ @@ -324,7 +333,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assuan-pipe-server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assuan-socket-connect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assuan-socket-server.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assuan-socket.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assuan-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/funopen.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ diff -urpNP gpgme-1.0.3/assuan/assuan-buffer.c gpgme-1.1.0/assuan/assuan-buffer.c --- gpgme-1.0.3/assuan/assuan-buffer.c 2005-03-24 08:25:32.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-buffer.c 2005-09-08 14:42:30.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-buffer.c - read and send data - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -25,6 +25,9 @@ #include #include #include +#ifdef HAVE_W32_SYSTEM +#include +#endif #include "assuan-defs.h" static int @@ -49,12 +52,12 @@ writen (ASSUAN_CONTEXT ctx, const char * /* Read an entire line. */ static int readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen, - int *r_nread, int *eof) + int *r_nread, int *r_eof) { size_t nleft = buflen; char *p; - *eof = 0; + *r_eof = 0; *r_nread = 0; while (nleft > 0) { @@ -68,7 +71,7 @@ readline (ASSUAN_CONTEXT ctx, char *buf, } else if (!n) { - *eof = 1; + *r_eof = 1; break; /* allow incomplete lines */ } p = buf; @@ -125,16 +128,18 @@ _assuan_read_line (ASSUAN_CONTEXT ctx) if (rc) { if (ctx->log_fp) - fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n", - assuan_get_assuan_log_prefix (), ctx, strerror (errno)); + fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Error: %s]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), 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); + fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [EOF]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); return -1; } @@ -165,8 +170,9 @@ _assuan_read_line (ASSUAN_CONTEXT ctx) ctx->inbound.linelen = endp - line; if (ctx->log_fp) { - fprintf (ctx->log_fp, "%s[%p] <- ", - assuan_get_assuan_log_prefix (), ctx); + fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); if (ctx->confidential) fputs ("[Confidential data not shown]", ctx->log_fp); else @@ -180,8 +186,9 @@ _assuan_read_line (ASSUAN_CONTEXT ctx) else { if (ctx->log_fp) - fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", - assuan_get_assuan_log_prefix (), ctx); + fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Invalid line]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); *line = 0; ctx->inbound.linelen = 0; return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated @@ -199,10 +206,10 @@ _assuan_read_line (ASSUAN_CONTEXT ctx) Returns 0 on success or an assuan error code. See also: assuan_pending_line(). */ -AssuanError +assuan_error_t assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen) { - AssuanError err; + assuan_error_t err; if (!ctx) return ASSUAN_Invalid_Value; @@ -223,31 +230,33 @@ assuan_pending_line (ASSUAN_CONTEXT ctx) } -AssuanError -assuan_write_line (ASSUAN_CONTEXT ctx, const char *line) +assuan_error_t +_assuan_write_line (assuan_context_t ctx, const char *prefix, + const char *line, size_t len) { - int rc; - size_t len; - const char *s; + int rc = 0; + size_t prefixlen = prefix? strlen (prefix):0; - 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); - - if (len > LINELENGTH - 2) - return ASSUAN_Line_Too_Long; + /* Make sure that the line is short enough. */ + if (len + prefixlen + 2 > ASSUAN_LINELENGTH) + { + if (ctx->log_fp) + fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> " + "[supplied line too long -truncated]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); + if (prefixlen > 5) + prefixlen = 5; + if (len > ASSUAN_LINELENGTH - prefixlen - 2) + len = ASSUAN_LINELENGTH - prefixlen - 2 - 1; + } - /* fixme: we should do some kind of line buffering. */ + /* 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); + fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); if (ctx->confidential) fputs ("[Confidential data not shown]", ctx->log_fp); else @@ -255,27 +264,60 @@ assuan_write_line (ASSUAN_CONTEXT ctx, c putc ('\n', ctx->log_fp); } - rc = writen (ctx, line, len); - if (rc) - rc = ASSUAN_Write_Error; + if (prefixlen) + { + rc = writen (ctx, prefix, prefixlen); + if (rc) + rc = ASSUAN_Write_Error; + } if (!rc) { - rc = writen (ctx, "\n", 1); + 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; } +assuan_error_t +assuan_write_line (ASSUAN_CONTEXT ctx, const char *line) +{ + 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); + + if (ctx->log_fp && s) + fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> " + "[supplied line contained a LF -truncated]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); + + return _assuan_write_line (ctx, NULL, line, len); +} + + /* Write out the data in buffer as datalines with line wrapping and - percent escaping. This fucntion is used for GNU's custom streams */ + percent escaping. This function is used for GNU's custom streams */ int -_assuan_cookie_write_data (void *cookie, const char *buffer, size_t size) +_assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size) { ASSUAN_CONTEXT ctx = cookie; + size_t size = orig_size; char *line; size_t linelen; @@ -317,8 +359,9 @@ _assuan_cookie_write_data (void *cookie, { if (ctx->log_fp) { - fprintf (ctx->log_fp, "%s[%p] -> ", - assuan_get_assuan_log_prefix (), ctx); + fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); if (ctx->confidential) fputs ("[Confidential data not shown]", ctx->log_fp); @@ -341,12 +384,12 @@ _assuan_cookie_write_data (void *cookie, } ctx->outbound.data.linelen = linelen; - return 0; + return (int)orig_size; } /* Write out any buffered data - This fucntion is used for GNU's custom streams */ + This function is used for GNU's custom streams */ int _assuan_cookie_write_flush (void *cookie) { @@ -364,8 +407,9 @@ _assuan_cookie_write_flush (void *cookie { if (ctx->log_fp) { - fprintf (ctx->log_fp, "%s[%p] -> ", - assuan_get_assuan_log_prefix (), ctx); + fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx); if (ctx->confidential) fputs ("[Confidential data not shown]", ctx->log_fp); else @@ -404,7 +448,7 @@ _assuan_cookie_write_flush (void *cookie * Return value: 0 on success or an error code **/ -AssuanError +assuan_error_t assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length) { if (!ctx) @@ -430,7 +474,7 @@ assuan_send_data (ASSUAN_CONTEXT ctx, co return 0; } -AssuanError +assuan_error_t assuan_sendfd (ASSUAN_CONTEXT ctx, int fd) { if (! ctx->io->sendfd) @@ -440,7 +484,7 @@ assuan_sendfd (ASSUAN_CONTEXT ctx, int f return ctx->io->sendfd (ctx, fd); } -AssuanError +assuan_error_t assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd) { if (! ctx->io->receivefd) diff -urpNP gpgme-1.0.3/assuan/assuan-client.c gpgme-1.1.0/assuan/assuan-client.c --- gpgme-1.0.3/assuan/assuan-client.c 2003-02-01 18:52:56.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-client.c 2005-10-01 20:14:48.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-client.c - client functions - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -32,12 +32,12 @@ #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) -AssuanError +assuan_error_t _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off) { char *line; int linelen; - AssuanError rc; + assuan_error_t rc; *okay = 0; *off = 0; @@ -126,24 +126,27 @@ _assuan_read_from_server (ASSUAN_CONTEXT * the one one returned by the server in error lines or from the * callback functions. **/ -AssuanError +assuan_error_t assuan_transact (ASSUAN_CONTEXT ctx, const char *command, - AssuanError (*data_cb)(void *, const void *, size_t), + assuan_error_t (*data_cb)(void *, const void *, size_t), void *data_cb_arg, - AssuanError (*inquire_cb)(void*, const char *), + assuan_error_t (*inquire_cb)(void*, const char *), void *inquire_cb_arg, - AssuanError (*status_cb)(void*, const char *), + assuan_error_t (*status_cb)(void*, const char *), void *status_cb_arg) { int rc, okay, off; - unsigned char *line; + char *line; int linelen; rc = assuan_write_line (ctx, command); if (rc) return rc; + if (*command == '#' || !*command) + return 0; /* Don't expect a response for a comment line. */ + again: rc = _assuan_read_from_server (ctx, &okay, &off); if (rc) @@ -164,7 +167,7 @@ assuan_transact (ASSUAN_CONTEXT ctx, rc = ASSUAN_No_Data_Callback; else { - unsigned char *s, *d; + char *s, *d; for (s=d=line; linelen; linelen--) { diff -urpNP gpgme-1.0.3/assuan/assuan-connect.c gpgme-1.1.0/assuan/assuan-connect.c --- gpgme-1.0.3/assuan/assuan-connect.c 2004-12-21 08:43:02.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-connect.c 2005-09-08 14:42:30.000000000 +0000 @@ -29,21 +29,19 @@ #include #include #include +#ifndef HAVE_W32_SYSTEM #include +#endif #include "assuan-defs.h" /* Disconnect and release the context CTX. */ void -assuan_disconnect (ASSUAN_CONTEXT ctx) +assuan_disconnect (assuan_context_t ctx) { if (ctx) { -#if 0 - /* This may not work if the pipe is full and the other end is - blocked. */ assuan_write_line (ctx, "BYE"); -#endif ctx->finish_handler (ctx); ctx->deinit_handler (ctx); ctx->deinit_handler = NULL; @@ -51,8 +49,10 @@ assuan_disconnect (ASSUAN_CONTEXT ctx) } } +/* Return the PID of the peer or -1 if not known. */ pid_t -assuan_get_pid (ASSUAN_CONTEXT ctx) +assuan_get_pid (assuan_context_t ctx) { - return ctx ? ctx->pid : -1; + return (ctx && ctx->pid)? ctx->pid : -1; } + diff -urpNP gpgme-1.0.3/assuan/assuan-defs.h gpgme-1.1.0/assuan/assuan-defs.h --- gpgme-1.0.3/assuan/assuan-defs.h 2005-03-24 08:25:32.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-defs.h 2005-09-08 14:42:30.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-defs.c - Internal definitions to Assuan - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -22,12 +22,44 @@ #define ASSUAN_DEFS_H #include +#ifndef HAVE_W32_SYSTEM #include #include +#else +#include +#endif #include #include "assuan.h" +#ifndef HAVE_W32_SYSTEM +#define DIRSEP_C '/' +#else +#define DIRSEP_C '\\' +#endif + +#ifdef HAVE_W32_SYSTEM +#define AF_LOCAL AF_UNIX +/* We need to prefix the structure with a sockaddr_in header so we can + use it later for sendto and recvfrom. */ +struct sockaddr_un +{ + short sun_family; + unsigned short sun_port; + struct in_addr sun_addr; + char sun_path[108-2-4]; /* Path name. */ +}; + +/* Not needed anymore because the current mingw32 defines this in + sys/types.h */ +/* typedef int ssize_t; */ + +/* Missing W32 functions */ +int putc_unlocked (int c, FILE *stream); +void * memrchr (const void *block, int c, size_t size); +char * stpcpy (char *dest, const char *src); +#endif + #define LINELENGTH ASSUAN_LINELENGTH struct cmdtbl_s @@ -43,24 +75,31 @@ struct assuan_io /* Routine to write to output_fd. */ ssize_t (*writefnc) (ASSUAN_CONTEXT, const void *, size_t); /* Send a file descriptor. */ - AssuanError (*sendfd) (ASSUAN_CONTEXT, int); + assuan_error_t (*sendfd) (ASSUAN_CONTEXT, int); /* Receive a file descriptor. */ - AssuanError (*receivefd) (ASSUAN_CONTEXT, int *); + assuan_error_t (*receivefd) (ASSUAN_CONTEXT, int *); }; struct assuan_context_s { - AssuanError err_no; + assuan_error_t err_no; const char *err_str; - int os_errno; /* last system error number used with certain error codes*/ + int os_errno; /* Last system error number used with certain + error codes. */ + + /* Context specific flags (cf. assuan_flag_t). */ + struct + { + unsigned int no_waitpid:1; /* See ASSUAN_NO_WAITPID. */ + } flags; int confidential; - int is_server; /* set if this is context belongs to a server */ + int 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() */ + char *okay_line; /* See assuan_set_okay_line() */ - void *user_pointer; /* for assuan_[gs]et_pointer () */ + void *user_pointer; /* For assuan_get_pointer and assuan-set_pointer (). */ FILE *log_fp; @@ -90,13 +129,10 @@ struct assuan_context_s 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 */ + pid_t pid; /* The the pid of the peer. */ 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; @@ -145,7 +181,7 @@ void _assuan_release_context (ASSUAN_CON /* 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, +assuan_error_t _assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer); @@ -156,9 +192,11 @@ int _assuan_register_std_commands (ASSUA 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_error_t _assuan_write_line (assuan_context_t ctx, const char *prefix, + const char *line, size_t len); /*-- assuan-client.c --*/ -AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off); +assuan_error_t _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off); /*-- assuan-util.c --*/ @@ -177,17 +215,40 @@ void _assuan_free (void *p); void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length); void _assuan_log_sanitized_string (const char *string); +#ifdef HAVE_W32_SYSTEM +const char *_assuan_w32_strerror (int ec); +#define w32_strerror(e) _assuan_w32_strerror ((e)) +#endif /*HAVE_W32_SYSTEM*/ + + +/*-- assuan-logging.c --*/ +void _assuan_set_default_log_stream (FILE *fp); + +void _assuan_log_printf (const char *format, ...) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) + __attribute__ ((format (printf,1,2))) +#endif + ; + /*-- 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); +/*-- assuan-socket.c --*/ +int _assuan_close (int fd); +int _assuan_sock_new (int domain, int type, int proto); +int _assuan_sock_bind (int sockfd, struct sockaddr *addr, int addrlen); +int _assuan_sock_connect (int sockfd, struct sockaddr *addr, int addrlen); + #ifdef HAVE_FOPENCOOKIE /* We have to implement funopen in terms of glibc's fopencookie. */ -FILE *funopen(const void *cookie, cookie_read_function_t *readfn, - cookie_write_function_t *writefn, - cookie_seek_function_t *seekfn, - cookie_close_function_t *closefn); +FILE *_assuan_funopen(void *cookie, + cookie_read_function_t *readfn, + cookie_write_function_t *writefn, + cookie_seek_function_t *seekfn, + cookie_close_function_t *closefn); +#define funopen(a,r,w,s,c) _assuan_funopen ((a), (r), (w), (s), (c)) #endif /*HAVE_FOPENCOOKIE*/ #endif /*ASSUAN_DEFS_H*/ diff -urpNP gpgme-1.0.3/assuan/assuan-domain-connect.c gpgme-1.1.0/assuan/assuan-domain-connect.c --- gpgme-1.0.3/assuan/assuan-domain-connect.c 2004-06-23 14:11:46.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-domain-connect.c 2005-09-08 14:42:30.000000000 +0000 @@ -27,8 +27,12 @@ #include #include #include +#ifndef HAVE_W32_SYSTEM #include #include +#else +#include +#endif #if HAVE_SYS_UIO_H #include #endif @@ -39,17 +43,23 @@ #include "assuan-defs.h" -#define LOG(format, args...) \ - fprintf (assuan_get_assuan_log_stream (), \ - assuan_get_assuan_log_prefix (), \ - "%s" format , ## args) +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +# ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +# endif +#endif static void -do_deinit (ASSUAN_CONTEXT ctx) +do_deinit (assuan_context_t ctx) { if (ctx->inbound.fd != -1) - close (ctx->inbound.fd); + _assuan_close (ctx->inbound.fd); ctx->inbound.fd = -1; ctx->outbound.fd = -1; @@ -65,7 +75,7 @@ do_deinit (ASSUAN_CONTEXT ctx) assert (ctx->pendingfdscount > 0); for (i = 0; i < ctx->pendingfdscount; i ++) - close (ctx->pendingfds[i]); + _assuan_close (ctx->pendingfds[i]); free (ctx->pendingfds); } @@ -76,10 +86,11 @@ do_deinit (ASSUAN_CONTEXT ctx) /* Read from the socket server. */ static ssize_t -domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen) +domain_reader (assuan_context_t ctx, void *buf, size_t buflen) { int len = ctx->domainbuffersize; +#ifndef HAVE_W32_SYSTEM start: if (len == 0) /* No data is buffered. */ @@ -166,15 +177,15 @@ domain_reader (ASSUAN_CONTEXT ctx, void /* 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); + _assuan_log_printf ("not setup to receive messages from `%s'\n", + ((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)); + _assuan_log_printf ("domain_reader: %s\n", strerror (errno)); return -1; } @@ -190,7 +201,7 @@ domain_reader (ASSUAN_CONTEXT ctx, void sizeof (int) * (ctx->pendingfdscount + 1)); if (! tmp) { - LOG ("domain_reader: %s\n", strerror (errno)); + _assuan_log_printf ("domain_reader: %s\n", strerror (errno)); return -1; } @@ -198,13 +209,16 @@ domain_reader (ASSUAN_CONTEXT ctx, void ctx->pendingfds[ctx->pendingfdscount++] = *(int *) CMSG_DATA (&cmsg.hdr); - LOG ("Received file descriptor %d from peer.\n", + _assuan_log_printf ("received file descriptor %d from peer\n", ctx->pendingfds[ctx->pendingfdscount - 1]); } if (len == 0) goto start; } +#else + len = recvfrom (ctx->inbound.fd, buf, buflen, 0, NULL, NULL); +#endif /* Return some data to the user. */ @@ -223,8 +237,9 @@ domain_reader (ASSUAN_CONTEXT ctx, void /* Write to the domain server. */ static ssize_t -domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen) +domain_writer (assuan_context_t ctx, const void *buf, size_t buflen) { +#ifndef HAVE_W32_SYSTEM struct msghdr msg; struct iovec iovec; ssize_t len; @@ -244,14 +259,21 @@ domain_writer (ASSUAN_CONTEXT ctx, const len = sendmsg (ctx->outbound.fd, &msg, 0); if (len < 0) - LOG ("domain_writer: %s\n", strerror (errno)); - + _assuan_log_printf ("domain_writer: %s\n", strerror (errno)); +#else + int len; + + len = sendto (ctx->outbound.fd, buf, buflen, 0, + (struct sockaddr *)&ctx->serveraddr, + sizeof (struct sockaddr_in)); +#endif return len; } -static AssuanError -domain_sendfd (ASSUAN_CONTEXT ctx, int fd) +static assuan_error_t +domain_sendfd (assuan_context_t ctx, int fd) { +#ifndef HAVE_W32_SYSTEM struct msghdr msg; struct { @@ -282,19 +304,23 @@ domain_sendfd (ASSUAN_CONTEXT ctx, int f len = sendmsg (ctx->outbound.fd, &msg, 0); if (len < 0) { - LOG ("domain_sendfd: %s\n", strerror (errno)); + _assuan_log_printf ("domain_sendfd: %s\n", strerror (errno)); return ASSUAN_General_Error; } else return 0; +#else + return 0; +#endif } -static AssuanError -domain_receivefd (ASSUAN_CONTEXT ctx, int *fd) +static assuan_error_t +domain_receivefd (assuan_context_t ctx, int *fd) { +#ifndef HAVE_W32_SYSTEM if (ctx->pendingfds == 0) { - LOG ("No pending file descriptors!\n"); + _assuan_log_printf ("no pending file descriptors!\n"); return ASSUAN_General_Error; } @@ -312,7 +338,7 @@ domain_receivefd (ASSUAN_CONTEXT ctx, in ctx->pendingfds = realloc (ctx->pendingfds, ctx->pendingfdscount * sizeof (int)); } - +#endif return 0; } @@ -321,14 +347,14 @@ domain_receivefd (ASSUAN_CONTEXT ctx, in /* 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_error_t +_assuan_domain_init (assuan_context_t *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; + assuan_error_t err; + assuan_context_t ctx; int fd; size_t len; int tries; @@ -349,17 +375,17 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_c /* Setup the socket. */ - fd = socket (PF_LOCAL, SOCK_DGRAM, 0); + fd = _assuan_sock_new (PF_LOCAL, SOCK_DGRAM, 0); if (fd == -1) { - LOG ("can't create socket: %s\n", strerror (errno)); + _assuan_log_printf ("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; @@ -380,13 +406,14 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_c /* XXX: L_tmpnam must be shorter than sizeof (sun_path)! */ assert (L_tmpnam < sizeof (ctx->myaddr.sun_path)); + /* XXX: W32 tmpnam is broken */ p = tmpnam (buf); if (! p) { - LOG ("cannot determine an appropriate temporary file " - "name. DOS in progress?\n"); + _assuan_log_printf ("cannot determine an appropriate temporary file " + "name. DoS in progress?\n"); _assuan_release_context (ctx); - close (fd); + _assuan_close (fd); return ASSUAN_General_Error; } @@ -396,17 +423,17 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_c memcpy (ctx->myaddr.sun_path, buf, len); len += offsetof (struct sockaddr_un, sun_path); - err = bind (fd, (struct sockaddr *) &ctx->myaddr, len); + err = _assuan_sock_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_log_printf ("can't bind to `%s': %s\n", ctx->myaddr.sun_path, + strerror (errno)); _assuan_release_context (ctx); - close (fd); + _assuan_close (fd); return ASSUAN_Connect_Failed; } @@ -418,7 +445,7 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_c fp = fdopen (rendezvousfd, "w+"); if (! fp) { - LOG ("can't open rendezvous port: %s\n", strerror (errno)); + _assuan_log_printf ("can't open rendezvous port: %s\n", strerror (errno)); return ASSUAN_Connect_Failed; } @@ -447,10 +474,10 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_c return 0; } -AssuanError -assuan_domain_connect (ASSUAN_CONTEXT * r_ctx, int rendezvousfd, pid_t peer) +assuan_error_t +assuan_domain_connect (assuan_context_t * r_ctx, int rendezvousfd, pid_t peer) { - AssuanError aerr; + assuan_error_t aerr; int okay, off; aerr = _assuan_domain_init (r_ctx, rendezvousfd, peer); @@ -460,10 +487,11 @@ assuan_domain_connect (ASSUAN_CONTEXT * /* Initial handshake. */ aerr = _assuan_read_from_server (*r_ctx, &okay, &off); if (aerr) - LOG ("can't connect to server: %s\n", assuan_strerror (aerr)); + _assuan_log_printf ("can't connect to server: %s\n", + assuan_strerror (aerr)); else if (okay != 1) { - LOG ("can't connect to server: `"); + _assuan_log_printf ("can't connect to server: `"); _assuan_log_sanitized_string ((*r_ctx)->inbound.line); fprintf (assuan_get_assuan_log_stream (), "'\n"); aerr = ASSUAN_Connect_Failed; diff -urpNP gpgme-1.0.3/assuan/assuan-domain-server.c gpgme-1.1.0/assuan/assuan-domain-server.c --- gpgme-1.0.3/assuan/assuan-domain-server.c 2003-08-18 19:17:07.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-domain-server.c 2005-09-08 14:42:30.000000000 +0000 @@ -27,12 +27,12 @@ #include "assuan-defs.h" /* Initialize a server. */ -AssuanError +assuan_error_t assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer) { - AssuanError err; + assuan_error_t err; err = _assuan_domain_init (r_ctx, rendezvousfd, peer); if (err) diff -urpNP gpgme-1.0.3/assuan/assuan-errors.c gpgme-1.1.0/assuan/assuan-errors.c --- gpgme-1.0.3/assuan/assuan-errors.c 2005-06-20 19:35:39.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-errors.c 2005-10-01 21:15:12.000000000 +0000 @@ -1,6 +1,10 @@ /* Generated automatically by mkerrors */ /* Do not edit! */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include "assuan.h" @@ -65,6 +69,7 @@ assuan_strerror (AssuanError err) case ASSUAN_Unexpected_Status: s="unexpected status"; break; case ASSUAN_Unexpected_Data: s="unexpected data"; break; case ASSUAN_Invalid_Status: s="invalid status"; break; + case ASSUAN_Locale_Problem: s="locale problem"; break; case ASSUAN_Not_Confirmed: s="not confirmed"; break; case ASSUAN_Bad_Certificate: s="bad certificate"; break; case ASSUAN_Bad_Certificate_Chain: s="bad certificate chain"; break; @@ -84,6 +89,8 @@ assuan_strerror (AssuanError err) case ASSUAN_No_PKCS15_App: s="no pkcs15 app"; break; case ASSUAN_Card_Not_Present: s="card not present"; break; case ASSUAN_Invalid_Id: s="invalid id"; break; + case ASSUAN_USER_ERROR_FIRST: s="user error first"; break; + case ASSUAN_USER_ERROR_LAST: s="user error last"; break; default: { unsigned int source, code; diff -urpNP gpgme-1.0.3/assuan/assuan-handler.c gpgme-1.1.0/assuan/assuan-handler.c --- gpgme-1.0.3/assuan/assuan-handler.c 2004-06-23 13:52:17.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-handler.c 2005-09-08 14:42:30.000000000 +0000 @@ -135,7 +135,7 @@ std_handler_end (ASSUAN_CONTEXT ctx, cha return set_error (ctx, Not_Implemented, NULL); } -AssuanError +assuan_error_t assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd) { char *endp; @@ -391,7 +391,7 @@ my_strcasecmp (const char *a, const char } /* Parse the line, break out the command, find it in the command - table, remove leading and white spaces from the arguments, all the + table, remove leading and white spaces from the arguments, call the handler with the argument line and return the error */ static int dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen) @@ -484,7 +484,7 @@ process_request (ASSUAN_CONTEXT ctx) } else { - char errline[256]; + char errline[300]; if (rc < 100) sprintf (errline, "ERR %d server fault (%.50s)", @@ -493,8 +493,40 @@ process_request (ASSUAN_CONTEXT ctx) { 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:""); +#if defined(__GNUC__) && defined(__ELF__) + /* If we have weak symbol support we try to use the error + strings from libgpg-error without creating a dependency. + They are used for debugging purposes only, so there is no + problem if they are not available. We need to make sure + that we are using elf because only this guarantees that + weak symbol support is available in case GNU ld is not + used. */ + unsigned int source, code; + + int gpg_strerror_r (unsigned int err, char *buf, size_t buflen) + __attribute__ ((weak)); + + const char *gpg_strsource (unsigned int err) + __attribute__ ((weak)); + + source = ((rc >> 24) & 0xff); + code = (rc & 0x00ffffff); + if (source && gpg_strsource && gpg_strerror_r) + { + /* Assume this is an libgpg-error. */ + char ebuf[50]; + + gpg_strerror_r (rc, ebuf, sizeof ebuf ); + sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s", + rc, + ebuf, + gpg_strsource (rc), + text? " - ":"", text?text:""); + } + else +#endif /* __GNUC__ && __ELF__ */ + sprintf (errline, "ERR %d %.50s%s%.100s", + rc, assuan_strerror (rc), text? " - ":"", text?text:""); } rc = assuan_write_line (ctx, errline); } @@ -512,7 +544,7 @@ process_request (ASSUAN_CONTEXT ctx) * assuan_process: * @ctx: assuan context * - * This fucntion is used to handle the assuan protocol after a + * This function is used to handle the assuan protocol after a * connection has been established using assuan_accept(). This is the * main protocol handler. * @@ -625,7 +657,7 @@ assuan_get_data_fp (ASSUAN_CONTEXT ctx) /* Set the text used for the next OK reponse. This string is automatically reset to NULL after the next command. */ -AssuanError +assuan_error_t assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line) { if (!ctx) @@ -652,15 +684,16 @@ assuan_set_okay_line (ASSUAN_CONTEXT ctx -void +assuan_error_t assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text) { char buffer[256]; char *helpbuf; size_t n; + assuan_error_t ae; if ( !ctx || !keyword) - return; + return ASSUAN_Invalid_Value; if (!text) text = ""; @@ -674,7 +707,7 @@ assuan_write_status (ASSUAN_CONTEXT ctx, strcat (buffer, " "); strcat (buffer, text); } - assuan_write_line (ctx, buffer); + ae = assuan_write_line (ctx, buffer); } else if ( (helpbuf = xtrymalloc (n)) ) { @@ -685,7 +718,10 @@ assuan_write_status (ASSUAN_CONTEXT ctx, strcat (helpbuf, " "); strcat (helpbuf, text); } - assuan_write_line (ctx, helpbuf); + ae = assuan_write_line (ctx, helpbuf); xfree (helpbuf); } + else + ae = 0; + return ae; } diff -urpNP gpgme-1.0.3/assuan/assuan-inquire.c gpgme-1.1.0/assuan/assuan-inquire.c --- gpgme-1.0.3/assuan/assuan-inquire.c 2003-08-18 19:17:07.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-inquire.c 2005-10-01 20:14:48.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-inquire.c - handle inquire stuff - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -134,11 +134,11 @@ free_membuf (struct membuf *mb) * * 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) +assuan_error_t +assuan_inquire (assuan_context_t ctx, const char *keyword, + unsigned char **r_buffer, size_t *r_length, size_t maxlen) { - AssuanError rc; + assuan_error_t rc; struct membuf mb; char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */ unsigned char *line, *p; @@ -173,7 +173,7 @@ assuan_inquire (ASSUAN_CONTEXT ctx, cons rc = _assuan_read_line (ctx); if (rc) goto leave; - line = ctx->inbound.line; + line = (unsigned char *) ctx->inbound.line; linelen = ctx->inbound.linelen; } while (*line == '#' || !linelen); diff -urpNP gpgme-1.0.3/assuan/assuan-io.c gpgme-1.1.0/assuan/assuan-io.c --- gpgme-1.0.3/assuan/assuan-io.c 2003-08-20 20:20:45.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-io.c 2005-09-08 14:42:30.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-io.c - Wraps the read and write functions. - * Copyright (C) 2002 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -18,41 +18,53 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include "assuan-defs.h" #include #include +#ifdef HAVE_W32_SYSTEM +#include +#endif -#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 - +#ifndef _ASSUAN_NO_PTH 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); +#ifndef HAVE_W32_SYSTEM #pragma weak pth_read #pragma weak pth_write +#endif +#endif /*!_ASSUAN_NO_PTH*/ ssize_t -_assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size) +_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) { +#ifdef _ASSUAN_NO_PTH + return read (ctx->inbound.fd, buffer, size); +#else +# ifndef HAVE_W32_SYSTEM return (pth_read ? pth_read : read) (ctx->inbound.fd, buffer, size); +# else + return pth_read ? pth_read (ctx->inbound.fd, buffer, size) + : recv (ctx->inbound.fd, buffer, size, 0); +# endif +# endif } ssize_t -_assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer, size_t size) +_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) { +#ifdef _ASSUAN_NO_PTH + return write (ctx->outbound.fd, buffer, size); +#else +# ifndef HAVE_W32_SYSTEM return (pth_write ? pth_write : write) (ctx->outbound.fd, buffer, size); -} - +# else + return pth_write ? pth_write (ctx->outbound.fd, buffer, size) + : send (ctx->outbound.fd, buffer, size, 0); +# endif #endif +} diff -urpNP gpgme-1.0.3/assuan/assuan-listen.c gpgme-1.1.0/assuan/assuan-listen.c --- gpgme-1.0.3/assuan/assuan-listen.c 2003-08-18 19:17:07.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-listen.c 2005-09-08 14:42:30.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-listen.c - Wait for a connection (server) - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -26,8 +26,8 @@ #include "assuan-defs.h" -AssuanError -assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line) +assuan_error_t +assuan_set_hello_line (assuan_context_t ctx, const char *line) { if (!ctx) return ASSUAN_Invalid_Value; @@ -41,8 +41,13 @@ assuan_set_hello_line (ASSUAN_CONTEXT ct char *buf = xtrymalloc (3+strlen(line)+1); if (!buf) return ASSUAN_Out_Of_Core; - strcpy (buf, "OK "); - strcpy (buf+3, line); + if (strchr (line, '\n')) + strcpy (buf, line); + else + { + strcpy (buf, "OK "); + strcpy (buf+3, line); + } xfree (ctx->hello_line); ctx->hello_line = buf; } @@ -61,10 +66,11 @@ assuan_set_hello_line (ASSUAN_CONTEXT ct * Return value: 0 on success or an error if the connection could for * some reason not be established. **/ -AssuanError -assuan_accept (ASSUAN_CONTEXT ctx) +assuan_error_t +assuan_accept (assuan_context_t ctx) { int rc; + const char *p, *pend; if (!ctx) return ASSUAN_Invalid_Value; @@ -77,9 +83,26 @@ assuan_accept (ASSUAN_CONTEXT ctx) if (rc) return rc; - /* send the hello */ - rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line - : "OK Your orders please"); + /* Send the hello. */ + p = ctx->hello_line; + if (p && (pend = strchr (p, '\n'))) + { /* This is a multi line hello. Send all but the last line as + comments. */ + do + { + rc = _assuan_write_line (ctx, "# ", p, pend - p); + if (rc) + return rc; + p = pend + 1; + pend = strchr (p, '\n'); + } + while (pend); + rc = _assuan_write_line (ctx, "OK ", p, strlen (p)); + } + else if (p) + rc = assuan_write_line (ctx, p); + else + rc = assuan_write_line (ctx, "OK Pleased to meet you"); if (rc) return rc; @@ -92,14 +115,14 @@ assuan_accept (ASSUAN_CONTEXT ctx) int -assuan_get_input_fd (ASSUAN_CONTEXT ctx) +assuan_get_input_fd (assuan_context_t ctx) { return ctx? ctx->input_fd : -1; } int -assuan_get_output_fd (ASSUAN_CONTEXT ctx) +assuan_get_output_fd (assuan_context_t ctx) { return ctx? ctx->output_fd : -1; } @@ -107,25 +130,25 @@ assuan_get_output_fd (ASSUAN_CONTEXT ctx /* 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) +assuan_error_t +assuan_close_input_fd (assuan_context_t ctx) { if (!ctx || ctx->input_fd == -1) return ASSUAN_Invalid_Value; - close (ctx->input_fd); + _assuan_close (ctx->input_fd); ctx->input_fd = -1; return 0; } /* Close the fd descriptor set by the command OUTPUT FD=n. We handle this fd inside assuan so that we can do some initial checks */ -AssuanError -assuan_close_output_fd (ASSUAN_CONTEXT ctx) +assuan_error_t +assuan_close_output_fd (assuan_context_t ctx) { if (!ctx || ctx->output_fd == -1) return ASSUAN_Invalid_Value; - close (ctx->output_fd); + _assuan_close (ctx->output_fd); ctx->output_fd = -1; return 0; } diff -urpNP gpgme-1.0.3/assuan/assuan-logging.c gpgme-1.1.0/assuan/assuan-logging.c --- gpgme-1.0.3/assuan/assuan-logging.c 2003-08-18 19:17:07.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-logging.c 2005-09-08 14:42:30.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-logging.c - Default logging function. - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -18,12 +18,29 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include "assuan-defs.h" +#ifdef HAVE_CONFIG_H +#include +#endif #include +#include +#include +#ifdef HAVE_W32_SYSTEM +#include +#endif /*HAVE_W32_SYSTEM*/ + +#include "assuan-defs.h" +static char prefix_buffer[80]; static FILE *_assuan_log; void +_assuan_set_default_log_stream (FILE *fp) +{ + if (!_assuan_log) + _assuan_log = fp; +} + +void assuan_set_assuan_log_stream (FILE *fp) { _assuan_log = fp; @@ -35,8 +52,61 @@ assuan_get_assuan_log_stream (void) return _assuan_log ? _assuan_log : stderr; } + +/* Set the prefix to be used for logging to TEXT or + resets it to the default if TEXT is NULL. */ +void +assuan_set_assuan_log_prefix (const char *text) +{ + if (text) + { + strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1); + prefix_buffer[sizeof (prefix_buffer)-1] = 0; + } + else + *prefix_buffer = 0; +} + const char * assuan_get_assuan_log_prefix (void) { - return ""; + return prefix_buffer; +} + + +void +_assuan_log_printf (const char *format, ...) +{ + va_list arg_ptr; + FILE *fp; + const char *prf; + + fp = assuan_get_assuan_log_stream (); + prf = assuan_get_assuan_log_prefix (); + if (*prf) + { + fputs (prf, fp); + fputs (": ", fp); + } + + va_start (arg_ptr, format); + vfprintf (fp, format, arg_ptr ); + va_end (arg_ptr); +} + + + +#ifdef HAVE_W32_SYSTEM +const char * +_assuan_w32_strerror (int ec) +{ + static char strerr[256]; + + if (ec == -1) + ec = (int)GetLastError (); + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + strerr, sizeof (strerr)-1, NULL); + return strerr; } +#endif /*HAVE_W32_SYSTEM*/ diff -urpNP gpgme-1.0.3/assuan/assuan-pipe-connect.c gpgme-1.1.0/assuan/assuan-pipe-connect.c --- gpgme-1.0.3/assuan/assuan-pipe-connect.c 2004-12-21 08:42:35.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-pipe-connect.c 2005-10-01 20:14:48.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-pipe-connect.c - Establish a pipe connection (client) - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -30,7 +30,11 @@ #include #include #include +#ifndef HAVE_W32_SYSTEM #include +#else +#include +#endif #include "assuan-defs.h" @@ -40,11 +44,47 @@ #define MAX_OPEN_FDS 20 #endif -#define LOG(format, args...) \ - fprintf (assuan_get_assuan_log_stream (), \ - assuan_get_assuan_log_prefix (), \ - "%s" format , ## args) +#ifdef HAVE_W32_SYSTEM +/* We assume that a HANDLE can be represented by an int which should + be true for all i386 systems (HANDLE is defined as void *) and + these are the only systems for which Windows is available. Further + we assume that -1 denotes an invalid handle. */ +#define fd_to_handle(a) ((HANDLE)(a)) +#define handle_to_fd(a) ((int)(a)) +#define pid_to_handle(a) ((HANDLE)(a)) +#define handle_to_pid(a) ((int)(a)) +#endif /*HAVE_W32_SYSTEM*/ + + +/* This should be called to make sure that SIGPIPE gets ignored. */ +static void +fix_signals (void) +{ +#ifndef _ASSUAN_NO_FIXED_SIGNALS +#ifndef HAVE_DOSISH_SYSTEM /* No SIGPIPE for these systems. */ + static int fixed_signals; + if (!fixed_signals) + { + struct sigaction act; + + sigaction (SIGPIPE, NULL, &act); + if (act.sa_handler == SIG_DFL) + { + act.sa_handler = SIG_IGN; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + sigaction (SIGPIPE, &act, NULL); + } + fixed_signals = 1; + /* FIXME: This is not MT safe */ + } +#endif /*HAVE_DOSISH_SYSTEM*/ +#endif /*!_ASSUAN_NO_FIXED_SIGNALS*/ +} + + +#ifndef HAVE_W32_SYSTEM static int writen (int fd, const char *buffer, size_t length) { @@ -63,75 +103,328 @@ writen (int fd, const char *buffer, size } return 0; /* okay */ } - +#endif static int -do_finish (ASSUAN_CONTEXT ctx) +do_finish (assuan_context_t ctx) { if (ctx->inbound.fd != -1) { - close (ctx->inbound.fd); + _assuan_close (ctx->inbound.fd); ctx->inbound.fd = -1; } if (ctx->outbound.fd != -1) { - close (ctx->outbound.fd); + _assuan_close (ctx->outbound.fd); ctx->outbound.fd = -1; } - if (ctx->pid != -1) + if (ctx->pid != -1 && ctx->pid) { -#if 0 - /* This is already done by the double fork. */ - waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */ +#ifndef HAVE_W32_SYSTEM +#ifndef _ASSUAN_USE_DOUBLE_FORK + if (!ctx->flags.no_waitpid) + waitpid (ctx->pid, NULL, 0); ctx->pid = -1; #endif +#endif /*!HAVE_W32_SYSTEM*/ } return 0; } static void -do_deinit (ASSUAN_CONTEXT ctx) +do_deinit (assuan_context_t ctx) { do_finish (ctx); } +#ifdef HAVE_W32_SYSTEM +/* Build a command line for use with W32's CreateProcess. On success + CMDLINE gets the address of a newly allocated string. */ +static int +build_w32_commandline (char * const *argv, char **cmdline) +{ + int i, n; + const char *s; + char *buf, *p; + + *cmdline = NULL; + n = 0; + for (i=0; (s=argv[i]); i++) + { + n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ + for (; *s; s++) + if (*s == '\"') + n++; /* Need to double inner quotes. */ + } + n++; + + buf = p = xtrymalloc (n); + if (!buf) + return -1; + + for (i=0; argv[i]; i++) + { + if (i) + p = stpcpy (p, " "); + if (!*argv[i]) /* Empty string. */ + p = stpcpy (p, "\"\""); + else if (strpbrk (argv[i], " \t\n\v\f\"")) + { + p = stpcpy (p, "\""); + for (s=argv[i]; *s; s++) + { + *p++ = *s; + if (*s == '\"') + *p++ = *s; + } + *p++ = '\"'; + *p = 0; + } + else + p = stpcpy (p, argv[i]); + } + + *cmdline= buf; + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +/* Create pipe where one end end is inheritable. */ +static int +create_inheritable_pipe (int filedes[2], int for_write) +{ + HANDLE r, w, h; + SECURITY_ATTRIBUTES sec_attr; + + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + if (!CreatePipe (&r, &w, &sec_attr, 0)) + { + _assuan_log_printf ("CreatePipe failed: %s\n", w32_strerror (-1)); + return -1; + } + + if (!DuplicateHandle (GetCurrentProcess(), for_write? r : w, + GetCurrentProcess(), &h, 0, + TRUE, DUPLICATE_SAME_ACCESS )) + { + _assuan_log_printf ("DuplicateHandle failed: %s\n", w32_strerror (-1)); + CloseHandle (r); + CloseHandle (w); + return -1; + } + if (for_write) + { + CloseHandle (r); + r = h; + } + else + { + CloseHandle (w); + w = h; + } + + filedes[0] = handle_to_fd (r); + filedes[1] = handle_to_fd (w); + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + /* 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) + descriptors not to close in the child. ATFORK is called in the + child right after the fork; ATFORKVALUE is passed as the first + argument and 0 is passed as the second argument. The ATFORK + function should only act if the second value is 0. */ +assuan_error_t +assuan_pipe_connect2 (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue) { -#ifndef _ASSUAN_IN_GPGME - static int fixed_signals = 0; -#endif - AssuanError err; +#ifdef HAVE_W32_SYSTEM + assuan_error_t err; int rp[2]; int wp[2]; + char mypidstr[50]; + char *cmdline; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* Returns process handle. */ + 0, /* Returns primary thread handle. */ + 0, /* Returns pid. */ + 0 /* Returns tid. */ + }; + STARTUPINFO si; + int fd, *fdp; + HANDLE nullfd = INVALID_HANDLE_VALUE; if (!ctx || !name || !argv || !argv[0]) return ASSUAN_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); + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); + + /* Build the command line. */ + if (build_w32_commandline (argv, &cmdline)) + return ASSUAN_Out_Of_Core; + + /* Create thew two pipes. */ + if (create_inheritable_pipe (rp, 0)) + { + xfree (cmdline); + return ASSUAN_General_Error; + } + + if (create_inheritable_pipe (wp, 1)) + { + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + xfree (cmdline); + return ASSUAN_General_Error; + } + + + err = _assuan_new_context (ctx); + if (err) + { + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + CloseHandle (fd_to_handle (wp[1])); + xfree (cmdline); + return ASSUAN_General_Error; + } + + (*ctx)->pipe_mode = 1; + (*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */ + (*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */ + (*ctx)->deinit_handler = do_deinit; + (*ctx)->finish_handler = do_finish; + + + /* fixme: Actually we should set the "_assuan_pipe_connect_pid" env + variable. However this requires us to write a full environment + handler, because the strings are expected in sorted order. The + suggestion given in the MS Reference Library, to save the old + value, changeit, create proces and restore it, is not thread + safe. */ + + /* Start the process. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = fd_to_handle (wp[0]); + si.hStdOutput = fd_to_handle (rp[1]); + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fd = fileno (stderr); + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != fd; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + nullfd = CreateFile ("nul", GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + if (nullfd == INVALID_HANDLE_VALUE) + { + _assuan_log_printf ("can't open `nul': %s\n", w32_strerror (-1)); + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + CloseHandle (fd_to_handle (wp[1])); + xfree (cmdline); + _assuan_release_context (*ctx); + return -1; } - fixed_signals = 1; - /* FIXME: This is not MT safe */ + si.hStdError = nullfd; } -#endif + else + si.hStdError = fd_to_handle (_get_osfhandle (fd)); + + + /* Note: We inherit all handles flagged as inheritable. This seems + to be a security flaw but there seems to be no way of selecting + handles to inherit. */ + /* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */ + /* name, cmdline); */ + if (!CreateProcess (name, /* Program to start. */ + cmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED), /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + _assuan_log_printf ("CreateProcess failed: %s\n", w32_strerror (-1)); + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + CloseHandle (fd_to_handle (wp[1])); + if (nullfd != INVALID_HANDLE_VALUE) + CloseHandle (nullfd); + xfree (cmdline); + _assuan_release_context (*ctx); + return ASSUAN_General_Error; + } + xfree (cmdline); + cmdline = NULL; + if (nullfd != INVALID_HANDLE_VALUE) + { + CloseHandle (nullfd); + nullfd = INVALID_HANDLE_VALUE; + } + + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (wp[0])); + + /* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */ + /* " dwProcessID=%d dwThreadId=%d\n", */ + /* pi.hProcess, pi.hThread, */ + /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + ResumeThread (pi.hThread); + CloseHandle (pi.hThread); + (*ctx)->pid = 0; /* We don't use the PID. */ + CloseHandle (pi.hProcess); /* We don't need to wait for the process. */ + +#else /*!HAVE_W32_SYSTEM*/ + assuan_error_t err; + int rp[2]; + int wp[2]; + char mypidstr[50]; + + if (!ctx || !name || !argv || !argv[0]) + return ASSUAN_Invalid_Value; + + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); if (pipe (rp) < 0) return ASSUAN_General_Error; @@ -158,8 +451,8 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx (*ctx)->deinit_handler = do_deinit; (*ctx)->finish_handler = do_finish; - /* FIXME: Use _gpgme_io_spawn. The PID stored here is actually - soon useless. */ + /* FIXME: For GPGME we should better use _gpgme_io_spawn. The PID + stored here is actually soon useless. */ (*ctx)->pid = fork (); if ((*ctx)->pid < 0) { @@ -173,111 +466,133 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx if ((*ctx)->pid == 0) { - /* Intermediate child to prevent zombie processes. */ +#ifdef _ASSUAN_USE_DOUBLE_FORK pid_t pid; if ((pid = fork ()) == 0) +#endif { - /* Child. */ - - 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); - } /* End child. */ + int i, n; + char errbuf[512]; + int *fdp; + + if (atfork) + atfork (atforkvalue, 0); + + /* Dup handles to stdin/stdout. */ + if (rp[1] != STDOUT_FILENO) + { + if (dup2 (rp[1], STDOUT_FILENO) == -1) + { + _assuan_log_printf ("dup2 failed in child: %s\n", + strerror (errno)); + _exit (4); + } + } + if (wp[0] != STDIN_FILENO) + { + if (dup2 (wp[0], STDIN_FILENO) == -1) + { + _assuan_log_printf ("dup2 failed in child: %s\n", + strerror (errno)); + _exit (4); + } + } + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + int fd = open ("/dev/null", O_WRONLY); + if (fd == -1) + { + _assuan_log_printf ("can't open `/dev/null': %s\n", + strerror (errno)); + _exit (4); + } + if (dup2 (fd, STDERR_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null, 2) failed: %s\n", + strerror (errno)); + _exit (4); + } + } + + + /* Close all files which will not be duped and are not in the + fd_child_list. */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) + { + if ( i == STDIN_FILENO || i == STDOUT_FILENO + || i == STDERR_FILENO) + continue; + fdp = fd_child_list; + if (fdp) + { + while (*fdp != -1 && *fdp != i) + fdp++; + } + + if (!(fdp && *fdp != -1)) + close(i); + } + errno = 0; + + /* We store our parents pid in the environment so that the + execed assuan server is able to read the actual pid of the + client. The server can't use getppid becuase it might have + been double forked before the assuan server has been + initialized. */ + setenv ("_assuan_pipe_connect_pid", mypidstr, 1); + + execv (name, (char *const *) argv); + /* oops - use the pipe to tell the parent about it */ + snprintf (errbuf, sizeof(errbuf)-1, + "ERR %d can't exec `%s': %.50s\n", + ASSUAN_Problem_Starting_Server, name, strerror (errno)); + errbuf[sizeof(errbuf)-1] = 0; + writen (1, errbuf, strlen (errbuf)); + _exit (4); + } +#ifdef _ASSUAN_USE_DOUBLE_FORK if (pid == -1) _exit (1); else _exit (0); +#endif } +#ifdef _ASSUAN_USE_DOUBLE_FORK waitpid ((*ctx)->pid, NULL, 0); (*ctx)->pid = -1; +#endif close (rp[1]); close (wp[0]); +#endif /*!HAVE_W32_SYSTEM*/ + /* 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)); + _assuan_log_printf ("can't connect server: %s\n", + assuan_strerror (err)); else if (okay != 1) { - LOG ("can't connect server: `%s'\n", (*ctx)->inbound.line); + _assuan_log_printf ("can't connect server: `%s'\n", + (*ctx)->inbound.line); err = ASSUAN_Connect_Failed; } } @@ -292,15 +607,13 @@ assuan_pipe_connect (ASSUAN_CONTEXT *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. */ +assuan_error_t +assuan_pipe_connect (assuan_context_t *ctx, const char *name, + const char *const argv[], int *fd_child_list) +{ + return assuan_pipe_connect2 (ctx, name, argv, fd_child_list, NULL, NULL); +} diff -urpNP gpgme-1.0.3/assuan/assuan-pipe-server.c gpgme-1.1.0/assuan/assuan-pipe-server.c --- gpgme-1.0.3/assuan/assuan-pipe-server.c 2003-08-18 19:17:07.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-pipe-server.c 2005-09-08 14:42:30.000000000 +0000 @@ -22,9 +22,14 @@ #include #include #include +#ifdef HAVE_W32_SYSTEM +#include +#include +#endif #include "assuan-defs.h" + static void deinit_pipe_server (ASSUAN_CONTEXT ctx) { @@ -69,7 +74,6 @@ _assuan_new_context (ASSUAN_CONTEXT *r_c 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; @@ -84,7 +88,6 @@ _assuan_new_context (ASSUAN_CONTEXT *r_c } - int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]) { @@ -94,11 +97,30 @@ assuan_init_pipe_server (ASSUAN_CONTEXT if (!rc) { ASSUAN_CONTEXT ctx = *r_ctx; + const char *s; + unsigned long ul; ctx->is_server = 1; - ctx->inbound.fd = filedes[0]; +#ifdef HAVE_W32_SYSTEM + /* MS Windows has so many different types of handle that one + needs to tranlsate them at many place forth and back. Also + make sure that the fiel descriptos are in binary mode. */ + setmode (filedes[0], O_BINARY); + setmode (filedes[1], O_BINARY); + ctx->inbound.fd = _get_osfhandle (filedes[0]); + ctx->outbound.fd = _get_osfhandle (filedes[1]); +#else + ctx->inbound.fd = filedes[0]; ctx->outbound.fd = filedes[1]; +#endif ctx->pipe_mode = 1; + + s = getenv ("_assuan_pipe_connect_pid"); + if (s && (ul=strtoul (s, NULL, 10)) && ul) + ctx->pid = (pid_t)ul; + else + ctx->pid = (pid_t)-1; + } return rc; } diff -urpNP gpgme-1.0.3/assuan/assuan-socket-connect.c gpgme-1.1.0/assuan/assuan-socket-connect.c --- gpgme-1.0.3/assuan/assuan-socket-connect.c 2004-04-19 14:24:57.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-socket-connect.c 2005-09-08 14:42:30.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-socket-connect.c - Assuan socket based client - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -22,25 +22,43 @@ #include #include #include +#include #include +#include #include +#ifndef HAVE_W32_SYSTEM #include #include -#include +#else +#include +#endif #include "assuan-defs.h" -#define LOG(format, args...) \ - fprintf (assuan_get_assuan_log_stream (), \ - assuan_get_assuan_log_prefix (), \ - "%s" format , ## args) +/* Hacks for Slowaris. */ +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + +#ifndef SUN_LEN +# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + + strlen ((ptr)->sun_path)) +#endif + static int do_finish (ASSUAN_CONTEXT ctx) { if (ctx->inbound.fd != -1) { - close (ctx->inbound.fd); + _assuan_close (ctx->inbound.fd); } ctx->inbound.fd = -1; ctx->outbound.fd = -1; @@ -55,56 +73,64 @@ do_deinit (ASSUAN_CONTEXT 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_error_t 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_error_t err; ASSUAN_CONTEXT ctx; int fd; struct sockaddr_un srvr_addr; size_t len; + const char *s; 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 != '/') + /* We require that the name starts with a slash, so that we can + alter reuse this function for other socket types. To make things + easier we allow an optional dirver prefix. */ + s = name; + if (*s && s[1] == ':') + s += 2; + if (*s != DIRSEP_C && *s != '/') return ASSUAN_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); + + fd = _assuan_sock_new (PF_LOCAL, SOCK_STREAM, 0); if (fd == -1) { - LOG ("can't create socket: %s\n", strerror (errno)); + _assuan_log_printf ("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)); + strncpy (srvr_addr.sun_path, name, sizeof (srvr_addr.sun_path) - 1); + srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0; + len = SUN_LEN (&srvr_addr); + - if (connect (fd, (struct sockaddr *) &srvr_addr, len) == -1) + if (_assuan_sock_connect (fd, (struct sockaddr *) &srvr_addr, len) == -1) { - LOG ("can't connect to `%s': %s\n", name, strerror (errno)); + _assuan_log_printf ("can't connect to `%s': %s\n", + name, strerror (errno)); _assuan_release_context (ctx); - close (fd); + _assuan_close (fd); return ASSUAN_Connect_Failed; } @@ -118,10 +144,11 @@ assuan_socket_connect (ASSUAN_CONTEXT *r err = _assuan_read_from_server (ctx, &okay, &off); if (err) - LOG ("can't connect to server: %s\n", assuan_strerror (err)); + _assuan_log_printf ("can't connect to server: %s\n", + assuan_strerror (err)); else if (okay != 1) { - LOG ("can't connect to server: `"); + /*LOG ("can't connect to server: `");*/ _assuan_log_sanitized_string (ctx->inbound.line); fprintf (assuan_get_assuan_log_stream (), "'\n"); err = ASSUAN_Connect_Failed; diff -urpNP gpgme-1.0.3/assuan/assuan-socket-server.c gpgme-1.1.0/assuan/assuan-socket-server.c --- gpgme-1.0.3/assuan/assuan-socket-server.c 2004-04-19 14:24:57.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-socket-server.c 2005-09-08 14:42:30.000000000 +0000 @@ -22,26 +22,32 @@ #include #include #include +#include #include +#ifndef HAVE_W32_SYSTEM #include #include -#include +#else +#include +#endif #include "assuan-defs.h" static int -accept_connection_bottom (ASSUAN_CONTEXT ctx) +accept_connection_bottom (assuan_context_t ctx) { int fd = ctx->connected_fd; - ctx->client_pid = (pid_t)-1; #ifdef HAVE_SO_PEERCRED { + /* This overrides any already set PID if the function returns a + valid one. */ struct ucred cr; int cl = sizeof cr; - if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) ) - ctx->client_pid = cr.pid; + if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) + && cr.pid != (pid_t)-1 && cr.pid ) + ctx->pid = cr.pid; } #endif @@ -62,13 +68,12 @@ accept_connection_bottom (ASSUAN_CONTEXT static int -accept_connection (ASSUAN_CONTEXT ctx) +accept_connection (assuan_context_t 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) { @@ -81,11 +86,11 @@ accept_connection (ASSUAN_CONTEXT ctx) } static int -finish_connection (ASSUAN_CONTEXT ctx) +finish_connection (assuan_context_t ctx) { if (ctx->inbound.fd != -1) { - close (ctx->inbound.fd); + _assuan_close (ctx->inbound.fd); } ctx->inbound.fd = -1; ctx->outbound.fd = -1; @@ -94,7 +99,7 @@ finish_connection (ASSUAN_CONTEXT ctx) static void -deinit_socket_server (ASSUAN_CONTEXT ctx) +deinit_socket_server (assuan_context_t ctx) { finish_connection (ctx); } @@ -105,9 +110,9 @@ static struct assuan_io io = { _assuan_s /* 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_init_socket_server (assuan_context_t *r_ctx, int listen_fd) { - ASSUAN_CONTEXT ctx; + assuan_context_t ctx; int rc; *r_ctx = NULL; @@ -139,9 +144,9 @@ assuan_init_socket_server (ASSUAN_CONTEX /* Initialize a server using the already accepted socket FD. */ int -assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd) +assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd) { - ASSUAN_CONTEXT ctx; + assuan_context_t ctx; int rc; *r_ctx = NULL; diff -urpNP gpgme-1.0.3/assuan/assuan-socket.c gpgme-1.1.0/assuan/assuan-socket.c --- gpgme-1.0.3/assuan/assuan-socket.c 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-socket.c 2005-09-08 14:42:30.000000000 +0000 @@ -0,0 +1,134 @@ +/* assuan-socket.c + * Copyright (C) 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#include +#include +#ifdef HAVE_W32_SYSTEM +#include +#include +#else +#include +#include +#endif +#include "assuan-defs.h" + +int +_assuan_close (int fd) +{ +#ifndef HAVE_W32_SYSTEM + return close (fd); +#else + int rc = closesocket (fd); + if (rc && WSAGetLastError () == WSAENOTSOCK) + rc = close (fd); + return rc; +#endif +} + + +int +_assuan_sock_new (int domain, int type, int proto) +{ +#ifndef HAVE_W32_SYSTEM + return socket (domain, type, proto); +#else + if (domain == AF_UNIX || domain == AF_LOCAL) + domain = AF_INET; + return socket (domain, type, proto); +#endif +} + + +int +_assuan_sock_connect (int sockfd, struct sockaddr * addr, int addrlen) +{ +#ifndef HAVE_W32_SYSTEM + return connect (sockfd, addr, addrlen); +#else + struct sockaddr_in myaddr; + struct sockaddr_un * unaddr; + FILE * fp; + int port = 0; + + unaddr = (struct sockaddr_un *)addr; + fp = fopen (unaddr->sun_path, "rb"); + if (!fp) + return -1; + fscanf (fp, "%d", &port); + fclose (fp); + /* XXX: set errno in this case */ + if (port < 0 || port > 65535) + return -1; + + myaddr.sin_family = AF_INET; + myaddr.sin_port = port; + myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + /* we need this later. */ + unaddr->sun_family = myaddr.sin_family; + unaddr->sun_port = myaddr.sin_port; + unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; + + return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr); +#endif +} + + +int +_assuan_sock_bind (int sockfd, struct sockaddr * addr, int addrlen) +{ +#ifndef HAVE_W32_SYSTEM + return bind (sockfd, addr, addrlen); +#else + if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX) + { + struct sockaddr_in myaddr; + struct sockaddr_un * unaddr; + FILE * fp; + int len = sizeof myaddr; + int rc; + + myaddr.sin_port = 0; + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + rc = bind (sockfd, (struct sockaddr *)&myaddr, len); + if (rc) + return rc; + rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len); + if (rc) + return rc; + unaddr = (struct sockaddr_un *)addr; + fp = fopen (unaddr->sun_path, "wb"); + if (!fp) + return -1; + fprintf (fp, "%d", myaddr.sin_port); + fclose (fp); + + /* we need this later. */ + unaddr->sun_family = myaddr.sin_family; + unaddr->sun_port = myaddr.sin_port; + unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; + + return 0; + } + return bind (sockfd, addr, addrlen); +#endif +} + diff -urpNP gpgme-1.0.3/assuan/assuan-util.c gpgme-1.1.0/assuan/assuan-util.c --- gpgme-1.0.3/assuan/assuan-util.c 2003-08-18 19:17:07.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan-util.c 2005-10-01 20:14:48.000000000 +0000 @@ -1,5 +1,5 @@ /* assuan-util.c - Utility functions for Assuan - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -23,6 +23,7 @@ #include #include #include +#include #include "assuan-defs.h" @@ -55,9 +56,19 @@ _assuan_realloc (void *a, size_t n) void * _assuan_calloc (size_t n, size_t m) { - void *p = _assuan_malloc (n*m); + void *p; + size_t nbytes; + + nbytes = n * m; + if (m && nbytes / m != n) + { + errno = ENOMEM; + return NULL; + } + + p = _assuan_malloc (nbytes); if (p) - memset (p, 0, n* m); + memset (p, 0, nbytes); return p; } @@ -73,7 +84,7 @@ _assuan_free (void *p) 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) +assuan_set_error (assuan_context_t ctx, int err, const char *text) { ctx->err_no = err; ctx->err_str = text; @@ -81,33 +92,34 @@ assuan_set_error (ASSUAN_CONTEXT ctx, in } void -assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer) +assuan_set_pointer (assuan_context_t ctx, void *pointer) { if (ctx) ctx->user_pointer = pointer; } void * -assuan_get_pointer (ASSUAN_CONTEXT ctx) +assuan_get_pointer (assuan_context_t ctx) { return ctx? ctx->user_pointer : NULL; } void -assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp) +assuan_set_log_stream (assuan_context_t ctx, FILE *fp) { if (ctx) { if (ctx->log_fp) fflush (ctx->log_fp); ctx->log_fp = fp; + _assuan_set_default_log_stream (fp); } } void -assuan_begin_confidential (ASSUAN_CONTEXT ctx) +assuan_begin_confidential (assuan_context_t ctx) { if (ctx) { @@ -116,7 +128,7 @@ assuan_begin_confidential (ASSUAN_CONTEX } void -assuan_end_confidential (ASSUAN_CONTEXT ctx) +assuan_end_confidential (assuan_context_t ctx) { if (ctx) { @@ -124,6 +136,36 @@ assuan_end_confidential (ASSUAN_CONTEXT } } + + +/* For context CTX, set the flag FLAG to VALUE. Values for flags + are usually 1 or 0 but certain flags might allow for other values; + see the description of the type assuan_flag_t for details. */ +void +assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value) +{ + if (!ctx) + return; + switch (flag) + { + case ASSUAN_NO_WAITPID: ctx->flags.no_waitpid = value; break; + } +} + +/* Return the VALUE of FLAG in context CTX. */ +int +assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag) +{ + if (!ctx) + return 0; + switch (flag) + { + case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid; + } + return 0; +} + + /* Dump a possibly binary string (used for debugging). Distinguish ascii text from binary and print it accordingly. */ void @@ -133,7 +175,7 @@ _assuan_log_print_buffer (FILE *fp, cons int n; for (n=length,s=buffer; n; n--, s++) - if (!isascii (*s) || iscntrl (*s) || !isprint (*s)) + if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80)) break; s = buffer; @@ -160,7 +202,7 @@ _assuan_log_print_buffer (FILE *fp, cons void _assuan_log_sanitized_string (const char *string) { - const unsigned char *s = string; + const unsigned char *s = (const unsigned char *) string; FILE *fp = assuan_get_assuan_log_stream (); if (! *s) @@ -197,7 +239,7 @@ _assuan_log_sanitized_string (const char break; default: - if (isascii (*s) && isprint (*s)) + if ((isascii (*s) && isprint (*s)) || (*s >= 0x80)) putc_unlocked (*s, fp); else { @@ -217,3 +259,4 @@ _assuan_log_sanitized_string (const char funlockfile (fp); #endif } + diff -urpNP gpgme-1.0.3/assuan/assuan.h gpgme-1.1.0/assuan/assuan.h --- gpgme-1.0.3/assuan/assuan.h 2003-08-20 20:20:45.000000000 +0000 +++ gpgme-1.1.0/assuan/assuan.h 2005-10-01 20:14:48.000000000 +0000 @@ -1,5 +1,5 @@ -/* assuan.c - Definitions for the Assuan protocol - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +/* assuan.c - Definitions for the Assuan IPC library + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -25,22 +25,48 @@ #include #include -#include -#define _ASSUAN_IN_GPGME -#ifdef _ASSUAN_IN_GPGME +/* To use this file with libraries the following macros are often + useful: + + #define _ASSUAN_EXT_SYM_PREFIX _foo_ + + This prefixes all external symbols with "_foo_". + + #define _ASSUAN_NO_PTH + + This avoids inclusion of special GNU Pth hacks. + + #define _ASSUAN_NO_FIXED_SIGNALS + + This disables changing of certain signal handler; i.e. SIGPIPE. + + #define _ASSUAN_USE_DOUBLE_FORK + + Use a double fork approach when connecting to a server through a pipe. + */ +/**** Begin GPGME specific modifications. ******/ #define _ASSUAN_EXT_SYM_PREFIX _gpgme_ +#define _ASSUAN_NO_PTH +#define _ASSUAN_NO_FIXED_SIGNALS +#define _ASSUAN_USE_DOUBLE_FORK #ifdef _ASSUAN_IN_GPGME_BUILD_ASSUAN int _gpgme_io_read (int fd, void *buffer, size_t count); int _gpgme_io_write (int fd, const void *buffer, size_t count); -ssize_t _gpgme_ath_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); +#ifdef HAVE_W32_SYSTEM +int _gpgme_ath_accept (int s, void *addr, int *length_ptr); +#else /*!HAVE_W32_SYSTEM*/ +struct sockaddr; +struct msghdr; +ssize_t _gpgme_ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout); int _gpgme_ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr); int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length); int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags); int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags); +#endif /*!HAVE_W32_SYSTEM*/ #define read _gpgme_io_read #define write _gpgme_io_write @@ -50,8 +76,9 @@ int _gpgme_ath_recvmsg (int s, struct ms #define connect _gpgme_ath_connect #define sendmsg _gpgme_ath_sendmsg #define recvmsg _gpgme_ath_recvmsg -#endif -#endif +#endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/ +/**** End GPGME specific modifications. ******/ + #ifdef _ASSUAN_EXT_SYM_PREFIX #define _ASSUAN_PREFIX1(x,y) x ## y @@ -116,6 +143,8 @@ int _gpgme_ath_recvmsg (int s, struct ms _ASSUAN_PREFIX(assuan_get_assuan_log_stream) #define assuan_get_assuan_log_prefix \ _ASSUAN_PREFIX(assuan_get_assuan_log_prefix) +#define assuan_set_flag _ASSUAN_PREFIX(assuan_set_flag) +#define assuan_get_flag _ASSUAN_PREFIX(assuan_get_flag) /* And now the internal functions, argh... */ #define _assuan_read_line _ASSUAN_PREFIX(_assuan_read_line) @@ -138,14 +167,27 @@ int _gpgme_ath_recvmsg (int s, struct ms #define _assuan_log_print_buffer _ASSUAN_PREFIX(_assuan_log_print_buffer) #define _assuan_log_sanitized_string \ _ASSUAN_PREFIX(_assuan_log_sanitized_string) +#define _assuan_log_printf _ASSUAN_PREFIX(_assuan_log_printf) +#define _assuan_set_default_log_stream \ + _ASSUAN_PREFIX(_assuan_set_default_log_stream) +#define _assuan_w32_strerror _ASSUAN_PREFIX(_assuan_w32_strerror) +#define _assuan_write_line _ASSUAN_PREFIX(_assuan_write_line) +#define _assuan_close _ASSUAN_PREFIX(_assuan_close) +#define _assuan_sock_new _ASSUAN_PREFIX(_assuan_sock_new) +#define _assuan_sock_bind _ASSUAN_PREFIX(_assuan_sock_bind) +#define _assuan_sock_connect _ASSUAN_PREFIX(_assuan_sock_connect) + +#endif /*_ASSUAN_EXT_SYM_PREFIX*/ -#endif #ifdef __cplusplus extern "C" { +#if 0 +} #endif - +#endif + typedef enum { @@ -166,7 +208,7 @@ typedef enum ASSUAN_Connect_Failed = 14, ASSUAN_Accept_Failed = 15, - /* error codes above 99 are meant as status codes */ + /* Error codes above 99 are meant as status codes */ ASSUAN_Not_Implemented = 100, ASSUAN_Server_Fault = 101, ASSUAN_Invalid_Command = 102, @@ -194,9 +236,10 @@ typedef enum ASSUAN_Unexpected_Status = 124, ASSUAN_Unexpected_Data = 125, ASSUAN_Invalid_Status = 126, - + ASSUAN_Locale_Problem = 127, ASSUAN_Not_Confirmed = 128, + /* Warning: Don't use the rror codes, below they are deprecated. */ ASSUAN_Bad_Certificate = 201, ASSUAN_Bad_Certificate_Chain = 202, ASSUAN_Missing_Certificate = 203, @@ -216,11 +259,20 @@ typedef enum ASSUAN_Invalid_Card = 402, ASSUAN_No_PKCS15_App = 403, ASSUAN_Card_Not_Present = 404, - ASSUAN_Invalid_Id = 405 + ASSUAN_Invalid_Id = 405, -} AssuanError; + /* Error codes in the range 1000 to 9999 may be used by applications + at their own discretion. */ + ASSUAN_USER_ERROR_FIRST = 1000, + ASSUAN_USER_ERROR_LAST = 9999 + +} assuan_error_t; + +typedef assuan_error_t AssuanError; /* Deprecated. */ /* This is a list of pre-registered ASSUAN commands */ +/* NOTE, these command IDs are now deprectated and solely exists for + compatibility reasons. */ typedef enum { ASSUAN_CMD_NOP = 0, @@ -237,72 +289,92 @@ typedef enum ASSUAN_CMD_USER = 256 /* Other commands should be used with this offset*/ } AssuanCommand; + +/* Definitions of flags for assuan_set_flag(). */ +typedef enum + { + /* When using a pipe server, by default Assuan will wait for the + forked process to die in assuan_disconnect. In certain cases + this is not desirable. By setting this flag, the waitpid will + be skipped and the caller is responsible to cleanup a forked + process. */ + ASSUAN_NO_WAITPID = 1 + } +assuan_flag_t; + #define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */ struct assuan_context_s; +typedef struct assuan_context_s *assuan_context_t; typedef struct assuan_context_s *ASSUAN_CONTEXT; /*-- assuan-handler.c --*/ -int assuan_register_command (ASSUAN_CONTEXT ctx, +int assuan_register_command (assuan_context_t 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 (*handler)(assuan_context_t, char *)); +int assuan_register_bye_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_reset_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_cancel_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_input_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)); +int assuan_register_output_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)); -int assuan_register_option_handler (ASSUAN_CONTEXT ctx, - int (*fnc)(ASSUAN_CONTEXT, +int assuan_register_option_handler (assuan_context_t ctx, + int (*fnc)(assuan_context_t, 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 assuan_process (assuan_context_t ctx); +int assuan_process_next (assuan_context_t ctx); +int assuan_get_active_fds (assuan_context_t ctx, int what, int *fdarray, int fdarraysize); -FILE *assuan_get_data_fp (ASSUAN_CONTEXT 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); +FILE *assuan_get_data_fp (assuan_context_t ctx); +assuan_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line); +assuan_error_t assuan_write_status (assuan_context_t ctx, + const char *keyword, const char *text); /* Negotiate a file descriptor. If LINE contains "FD=N", returns N assuming a local file descriptor. If LINE contains "FD" reads a file descriptor via CTX and stores it in *RDF (the CTX must be capable of passing file descriptors). */ -AssuanError assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, +assuan_error_t assuan_command_parse_fd (assuan_context_t 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_error_t assuan_set_hello_line (assuan_context_t ctx, const char *line); +assuan_error_t assuan_accept (assuan_context_t ctx); +int assuan_get_input_fd (assuan_context_t ctx); +int assuan_get_output_fd (assuan_context_t ctx); +assuan_error_t assuan_close_input_fd (assuan_context_t ctx); +assuan_error_t assuan_close_output_fd (assuan_context_t ctx); /*-- assuan-pipe-server.c --*/ -int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]); -void assuan_deinit_server (ASSUAN_CONTEXT ctx); +int assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]); +void assuan_deinit_server (assuan_context_t ctx); /*-- assuan-socket-server.c --*/ -int assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd); -int assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd); +int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd); +int assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd); /*-- assuan-pipe-connect.c --*/ -AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, - char *const argv[], int *fd_child_list); +assuan_error_t assuan_pipe_connect (assuan_context_t *ctx, const char *name, + const char *const argv[], + int *fd_child_list); +assuan_error_t assuan_pipe_connect2 (assuan_context_t *ctx, const char *name, + const char *const argv[], + int *fd_child_list, + void (*atfork) (void*, int), + void *atforkvalue); /*-- assuan-socket-connect.c --*/ -AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name, - pid_t server_pid); +assuan_error_t assuan_socket_connect (assuan_context_t *ctx, const char *name, + pid_t server_pid); /*-- assuan-domain-connect.c --*/ @@ -310,7 +382,7 @@ AssuanError assuan_socket_connect (ASSUA 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, +assuan_error_t assuan_domain_connect (assuan_context_t *r_ctx, int rendezvousfd, pid_t server); @@ -319,74 +391,93 @@ AssuanError assuan_domain_connect (ASSUA /* 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, +assuan_error_t assuan_init_domain_server (assuan_context_t *r_ctx, int rendezvousfd, pid_t client); /*-- assuan-connect.c --*/ -void assuan_disconnect (ASSUAN_CONTEXT ctx); -pid_t assuan_get_pid (ASSUAN_CONTEXT ctx); +void assuan_disconnect (assuan_context_t ctx); +pid_t assuan_get_pid (assuan_context_t ctx); /*-- assuan-client.c --*/ -AssuanError -assuan_transact (ASSUAN_CONTEXT ctx, +assuan_error_t +assuan_transact (assuan_context_t ctx, const char *command, - AssuanError (*data_cb)(void *, const void *, size_t), + assuan_error_t (*data_cb)(void *, const void *, size_t), void *data_cb_arg, - AssuanError (*inquire_cb)(void*, const char *), + assuan_error_t (*inquire_cb)(void*, const char *), void *inquire_cb_arg, - AssuanError (*status_cb)(void*, const char *), + assuan_error_t (*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_error_t assuan_inquire (assuan_context_t ctx, const char *keyword, + unsigned char **r_buffer, size_t *r_length, + size_t maxlen); /*-- assuan-buffer.c --*/ -AssuanError assuan_read_line (ASSUAN_CONTEXT ctx, +assuan_error_t assuan_read_line (assuan_context_t 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, +int assuan_pending_line (assuan_context_t ctx); +assuan_error_t assuan_write_line (assuan_context_t ctx, const char *line ); +assuan_error_t assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length); /* The file descriptor must be pending before assuan_receivefd is 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_error_t assuan_sendfd (assuan_context_t ctx, int fd); +assuan_error_t assuan_receivefd (assuan_context_t ctx, int *fd); /*-- assuan-util.c --*/ void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), void *(*new_realloc_func)(void *p, size_t n), void (*new_free_func)(void*) ); -void assuan_set_log_stream (ASSUAN_CONTEXT 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_set_log_stream (assuan_context_t ctx, FILE *fp); +int assuan_set_error (assuan_context_t ctx, int err, const char *text); +void assuan_set_pointer (assuan_context_t ctx, void *pointer); +void *assuan_get_pointer (assuan_context_t ctx); + +void assuan_begin_confidential (assuan_context_t ctx); +void assuan_end_confidential (assuan_context_t ctx); + +/* For context CTX, set the flag FLAG to VALUE. Values for flags + are usually 1 or 0 but certain flags might allow for other values; + see the description of the type assuan_flag_t for details. */ +void assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value); + +/* Return the VALUE of FLAG in context CTX. */ +int assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag); -void assuan_begin_confidential (ASSUAN_CONTEXT ctx); -void assuan_end_confidential (ASSUAN_CONTEXT ctx); /*-- assuan-errors.c (built) --*/ -const char *assuan_strerror (AssuanError err); +const char *assuan_strerror (assuan_error_t err); /*-- assuan-logging.c --*/ -/* Set the stream to which assuan should log. By default, this is - stderr. */ +/* Set the stream to which assuan should log message not associated + with a context. By default, this is stderr. The default value + will be changed when the first log stream is associated with a + context. Note, that this function is not thread-safe and should + in general be used right at startup. */ extern void assuan_set_assuan_log_stream (FILE *fp); -/* Return the stream which is currently being using for logging. */ +/* Return the stream which is currently being using for global 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); +/* Set the prefix to be used at the start of a line emitted by assuan + on the log stream. The default is the empty string. Note, that + this function is not thread-safe and should in general be used + right at startup. */ +void assuan_set_assuan_log_prefix (const char *text); + +/* Return a prefix to be used at the start of a line emitted by assuan + on the log stream. The default implementation returns the empty + string, i.e. "" */ +const char *assuan_get_assuan_log_prefix (void); #ifdef __cplusplus } diff -urpNP gpgme-1.0.3/assuan/funopen.c gpgme-1.1.0/assuan/funopen.c --- gpgme-1.0.3/assuan/funopen.c 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/assuan/funopen.c 2005-09-08 14:42:30.000000000 +0000 @@ -0,0 +1,63 @@ +/* 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 +#endif + +#include + + +/* Replacement for the *BSD function: + + FILE *funopen (void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), + int (*closefn)(void *)); + + The functions to provide my either be NULL if not required or + similar to the unistd function with the exception of using the + cookie instead of the fiel descripor. +*/ + + +#ifdef HAVE_FOPENCOOKIE +FILE * +_assuan_funopen(void *cookie, + cookie_read_function_t *readfn, + cookie_write_function_t *writefn, + cookie_seek_function_t *seekfn, + cookie_close_function_t *closefn) +{ + cookie_io_functions_t io = { NULL }; + + io.read = readfn; + io.write = writefn; + io.seek = seekfn; + io.close = closefn; + + return fopencookie (cookie, + readfn ? ( writefn ? "rw" : "r" ) + : ( writefn ? "w" : ""), io); +} +#else +#error No known way to implement funopen. +#endif diff -urpNP gpgme-1.0.3/assuan/mkerrors gpgme-1.1.0/assuan/mkerrors --- gpgme-1.0.3/assuan/mkerrors 2003-08-18 19:17:07.000000000 +0000 +++ gpgme-1.1.0/assuan/mkerrors 2005-09-08 14:42:30.000000000 +0000 @@ -23,6 +23,10 @@ cat < +#endif + #include #include "assuan.h" diff -urpNP gpgme-1.0.3/autogen.sh gpgme-1.1.0/autogen.sh --- gpgme-1.0.3/autogen.sh 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/autogen.sh 2005-09-08 14:42:33.000000000 +0000 @@ -0,0 +1,156 @@ +#! /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 +} + + +DIE=no + +# Used to cross-compile for Windows. +if test "$1" = "--build-w32"; then + tmp=`dirname $0` + tsdir=`cd "$tmp"; pwd` + shift + if [ ! -f $tsdir/config.guess ]; then + echo "$tsdir/config.guess not found" >&2 + exit 1 + fi + build=`$tsdir/config.guess` + + [ -z "$w32root" ] && w32root="$HOME/w32root" + echo "Using $w32root as standard install directory" >&2 + + # See whether we have the Debian cross compiler package or the + # old mingw32/cpd system + if i586-mingw32msvc-gcc --version >/dev/null 2>&1 ; then + host=i586-mingw32msvc + crossbindir=/usr/$host/bin + else + host=i386--mingw32 + if ! mingw32 --version >/dev/null; then + echo "We need at least version 0.3 of MingW32/CPD" >&2 + exit 1 + fi + crossbindir=`mingw32 --install-dir`/bin + # Old autoconf version required us to setup the environment + # with the proper tool names. + CC=`mingw32 --get-path gcc` + CPP=`mingw32 --get-path cpp` + AR=`mingw32 --get-path ar` + RANLIB=`mingw32 --get-path ranlib` + export CC CPP AR RANLIB + fi + + if [ -f "$tsdir/config.log" ]; then + if ! head $tsdir/config.log | grep "$host" >/dev/null; then + echo "Pease run a 'make distclean' first" >&2 + exit 1 + fi + fi + + ./configure --enable-maintainer-mode --prefix=${w32root} \ + --host=i586-mingw32msvc --build=${build} \ + --with-gpg-error-prefix=${w32root} \ + --disable-shared --without-gpgsm + + exit $? +fi + + + + + +# 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 <. # # This program is free software; you can redistribute it and/or modify @@ -25,118 +24,76 @@ scriptversion=2004-10-12.08 # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. - -Report bugs to . -EOF - exit 0 - ;; - -v | --v*) - echo "compile $scriptversion" - exit 0 - ;; -esac +# Usage: +# compile PROGRAM [ARGS]... +# `-o FOO.o' is removed from the args passed to the actual compile. + +prog=$1 +shift ofile= cfile= -eat= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift +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 "$@" + # 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/'` +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 +lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 + 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 +trap "rmdir $lockdir; exit 1" 1 2 15 # Run the compile. -"$@" -ret=$? +"$prog" $args +status=$? if test -f "$cofile"; then - mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - mv "${cofile}bj" "$ofile" + mv "$cofile" "$ofile" fi -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: +rmdir $lockdir +exit $status diff -urpNP gpgme-1.0.3/complus/Makefile.in gpgme-1.1.0/complus/Makefile.in --- gpgme-1.0.3/complus/Makefile.in 2005-06-20 19:35:24.000000000 +0000 +++ gpgme-1.1.0/complus/Makefile.in 2005-10-01 21:13:45.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -33,8 +33,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -SOURCES = $(gpgcom_SOURCES) $(tgpgcom_SOURCES) - srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -110,6 +108,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -122,6 +122,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -150,6 +151,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -188,12 +191,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ diff -urpNP gpgme-1.0.3/complus/gpgcom.c gpgme-1.1.0/complus/gpgcom.c --- gpgme-1.0.3/complus/gpgcom.c 2001-07-31 09:44:22.000000000 +0000 +++ gpgme-1.1.0/complus/gpgcom.c 2005-09-08 14:42:29.000000000 +0000 @@ -123,7 +123,7 @@ main (int argc, char **argv ) opt.homedir = getenv("GNUPGHOME"); if( !opt.homedir || !*opt.homedir ) { - #ifdef HAVE_DRIVE_LETTERS + #ifdef HAVE_DOSISH_SYSTEM opt.homedir = "c:/gnupg"; #else opt.homedir = "~/.gnupg"; diff -urpNP gpgme-1.0.3/config.guess gpgme-1.1.0/config.guess --- gpgme-1.0.3/config.guess 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/config.guess 2005-09-08 14:42:33.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -timestamp='2004-08-13' +timestamp='2004-01-05' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -53,7 +53,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO @@ -197,21 +197,15 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; - amd64:OpenBSD:*:*) - echo x86_64-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - cats:OpenBSD:*:*) - echo arm-unknown-openbsd${UNAME_RELEASE} + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - luna88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; @@ -227,33 +221,28 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; + pegasos:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; sgi:OpenBSD:*:*) - echo mips64-unknown-openbsd${UNAME_RELEASE} + echo mipseb-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit 0 ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit 0 ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit 0 ;; alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) + if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac + fi # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU @@ -291,12 +280,14 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac - # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? @@ -414,9 +405,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; @@ -752,7 +740,7 @@ EOF echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` @@ -775,7 +763,21 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + # GNU/KFreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin @@ -827,9 +829,6 @@ EOF ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; @@ -1070,9 +1069,9 @@ EOF M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit 0 ;; - M68*:*:R3V[5678]*:*) + M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` @@ -1170,10 +1169,9 @@ EOF echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in + case `uname -p` in *86) UNAME_PROCESSOR=i686 ;; - unknown) UNAME_PROCESSOR=powerpc ;; + powerpc) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit 0 ;; @@ -1232,16 +1230,9 @@ EOF SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit 0 ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + *:DRAGONFLY:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly${UNAME_RELEASE} exit 0 ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms && exit 0 ;; - I*) echo ia64-dec-vms && exit 0 ;; - V*) echo vax-dec-vms && exit 0 ;; - esac esac #echo '(No uname command or uname output not recognized.)' 1>&2 diff -urpNP gpgme-1.0.3/config.h.in gpgme-1.1.0/config.h.in --- gpgme-1.0.3/config.h.in 2005-06-20 19:35:39.000000000 +0000 +++ gpgme-1.1.0/config.h.in 2005-10-01 21:13:41.000000000 +0000 @@ -1,5 +1,8 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* Whether GPGSM support is enabled */ +#undef ENABLE_GPGSM + /* Path to the GPGSM binary. */ #undef GPGSM_PATH @@ -12,13 +15,10 @@ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H -/* Defined if the filesystem uses driver letters. */ +/* Defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2) + with special properties like no file modes */ #undef HAVE_DOSISH_SYSTEM -/* Defined if we run on some of the PCDOS like systems (DOS, Windoze, OS/2) - with special properties like no file modes. */ -#undef HAVE_DRIVE_LETTERS - /* Define to 1 if you have the `fopencookie' function. */ #undef HAVE_FOPENCOOKIE @@ -94,6 +94,9 @@ /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF +/* Defined if we run on a W32 API based system */ +#undef HAVE_W32_SYSTEM + /* used to implement the va_copy macro */ #undef MUST_COPY_VA_BYVAL @@ -121,6 +124,27 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION + +/* Separators as used in file names and $PATH. Please note that the + string version must not contain more than one character because + the using code assumes strlen()==1 */ +#ifdef HAVE_DOSISH_SYSTEM +#define DIRSEP_C '\\\\' +#define EXTSEP_C '.' +#define DIRSEP_S "\\\\" +#define EXTSEP_S "." +#define PATHSEP_C ';' +#define PATHSEP_S ";" +#else +#define DIRSEP_C '/' +#define EXTSEP_C '.' +#define DIRSEP_S "/" +#define EXTSEP_S "." +#define PATHSEP_C ':' +#define PATHSEP_S ":" +#endif + + /* The size of a `unsigned int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_INT @@ -135,7 +159,7 @@ /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE -# define _GNU_SOURCE +# undef _GNU_SOURCE #endif /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ diff -urpNP gpgme-1.0.3/config.sub gpgme-1.1.0/config.sub --- gpgme-1.0.3/config.sub 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/config.sub 2005-09-08 14:42:33.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -timestamp='2004-06-24' +timestamp='2004-01-05' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -70,7 +70,7 @@ Report bugs and patches to &5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by gpgme $as_me 1.0.3, which was +It was created by gpgme $as_me 1.1.0, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1525,10 +1524,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # (Interfaces added: AGE++) # (Interfaces removed/changed: AGE=0) # -LIBGPGME_LT_CURRENT=15 -# Subtract 2 from the AGE value if you want to make the LFS transition an +LIBGPGME_LT_CURRENT=16 +# 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=4 +LIBGPGME_LT_AGE=5 LIBGPGME_LT_REVISION=0 # If the API is changed in an incompatible way: increment the next counter. @@ -1539,7 +1538,6 @@ NEED_GPGSM_VERSION=1.9.6 ############################################## - PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION @@ -2062,7 +2060,11 @@ host_os=`echo $ac_cv_host | sed 's/^\([^ +# Enable GNU extensions on systems that have them. +cat >>confdefs.h <<\_ACEOF +#define _GNU_SOURCE 1 +_ACEOF @@ -3167,6 +3169,166 @@ else fi +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_DLLTOOL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + echo "$as_me:$LINENO: result: $DLLTOOL" >&5 +echo "${ECHO_T}$DLLTOOL" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_DLLTOOL" && ac_cv_prog_ac_ct_DLLTOOL=":" +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + echo "$as_me:$LINENO: result: $ac_ct_DLLTOOL" >&5 +echo "${ECHO_T}$ac_ct_DLLTOOL" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + DLLTOOL=$ac_ct_DLLTOOL +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. +set dummy ${ac_tool_prefix}windres; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_WINDRES+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$WINDRES"; then + ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_WINDRES="${ac_tool_prefix}windres" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +WINDRES=$ac_cv_prog_WINDRES +if test -n "$WINDRES"; then + echo "$as_me:$LINENO: result: $WINDRES" >&5 +echo "${ECHO_T}$WINDRES" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_WINDRES"; then + ac_ct_WINDRES=$WINDRES + # Extract the first word of "windres", so it can be a program name with args. +set dummy windres; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_WINDRES+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_WINDRES"; then + ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_WINDRES="windres" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_WINDRES" && ac_cv_prog_ac_ct_WINDRES=":" +fi +fi +ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES +if test -n "$ac_ct_WINDRES"; then + echo "$as_me:$LINENO: result: $ac_ct_WINDRES" >&5 +echo "${ECHO_T}$ac_ct_WINDRES" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + WINDRES=$ac_ct_WINDRES +else + WINDRES="$ac_cv_prog_WINDRES" +fi + @@ -3743,7 +3905,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 3746 "configure"' > conftest.$ac_ext + echo '#line 3908 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -5307,7 +5469,7 @@ fi # Provide some information about the compiler. -echo "$as_me:5310:" \ +echo "$as_me:5472:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -6343,11 +6505,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6346: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6508: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6350: \$? = $ac_status" >&5 + echo "$as_me:6512: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -6576,11 +6738,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6579: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6741: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6583: \$? = $ac_status" >&5 + echo "$as_me:6745: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -6636,11 +6798,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6639: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6801: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:6643: \$? = $ac_status" >&5 + echo "$as_me:6805: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8812,7 +8974,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:11256: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:11098: \$? = $ac_status" >&5 + echo "$as_me:11260: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -11151,11 +11313,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:11154: $lt_compile\"" >&5) + (eval echo "\"\$as_me:11316: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:11158: \$? = $ac_status" >&5 + echo "$as_me:11320: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12508,7 +12670,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:13598: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:13440: \$? = $ac_status" >&5 + echo "$as_me:13602: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -13493,11 +13655,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13496: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13658: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:13500: \$? = $ac_status" >&5 + echo "$as_me:13662: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -15530,11 +15692,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15533: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15695: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15537: \$? = $ac_status" >&5 + echo "$as_me:15699: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -15763,11 +15925,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15766: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15928: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15770: \$? = $ac_status" >&5 + echo "$as_me:15932: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -15823,11 +15985,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15826: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15988: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15830: \$? = $ac_status" >&5 + echo "$as_me:15992: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17999,7 +18161,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <>confdefs.h <<\_ACEOF -#define HAVE_DRIVE_LETTERS -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_DOSISH_SYSTEM -_ACEOF - have_dosish_system=yes + have_w32_system=yes GPG_DEFAULT='c:\\gnupg\\gpg.exe' # XXX Assuan is not supported in this configuration. #GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe' @@ -19723,7 +19876,6 @@ cat >>confdefs.h <<\_ACEOF #define HAVE_PTH _ACEOF - CFLAGS="$CFLAGS $PTH_CFLAGS" fi echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6 @@ -19806,8 +19958,16 @@ _ACEOF ;; esac +if test "$have_dosish_system" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOSISH_SYSTEM 1 +_ACEOF + +fi + -if test "$have_dosish_system" = "yes"; then +if test "$have_dosish_system" = yes; then HAVE_DOSISH_SYSTEM_TRUE= HAVE_DOSISH_SYSTEM_FALSE='#' else @@ -19816,6 +19976,26 @@ else fi +if test "$have_w32_system" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_W32_SYSTEM 1 +_ACEOF + +fi + + +if test "$have_w32_system" = yes; then + HAVE_W32_SYSTEM_TRUE= + HAVE_W32_SYSTEM_FALSE='#' +else + HAVE_W32_SYSTEM_TRUE='#' + HAVE_W32_SYSTEM_FALSE= +fi + + + + if test "$have_pth" = "yes"; then HAVE_PTH_TRUE= @@ -21098,21 +21278,11 @@ if test `eval echo '${'$as_ac_var'}'` = #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF -else - case $LIBOBJS in - "$ac_func.$ac_objext" | \ - *" $ac_func.$ac_objext" | \ - "$ac_func.$ac_objext "* | \ - *" $ac_func.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; -esac - fi done - for ac_func in vasprintf do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -21230,8 +21400,11 @@ echo $ECHO_N "checking whether va_lists echo $ECHO_N "(cached) $ECHO_C" >&6 else - gnupg_cv_must_copy_va_byval=no if test "$cross_compiling" = yes; then + gnupg_cv_must_copy_va_byval=no + else + gnupg_cv_must_copy_va_byval=no + if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling See \`config.log' for more details." >&5 echo "$as_me: error: cannot run test program while cross compiling @@ -21284,6 +21457,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi + fi fi @@ -21294,8 +21468,13 @@ cat >>confdefs.h <<\_ACEOF _ACEOF fi - echo "$as_me:$LINENO: result: $gnupg_cv_must_copy_va_byval" >&5 + if test "$cross_compiling" = yes; then + echo "$as_me:$LINENO: result: assuming $gnupg_cv_must_copy_va_byval" >&5 +echo "${ECHO_T}assuming $gnupg_cv_must_copy_va_byval" >&6 + else + echo "$as_me:$LINENO: result: $gnupg_cv_must_copy_va_byval" >&5 echo "${ECHO_T}$gnupg_cv_must_copy_va_byval" >&6 + fi fi @@ -22054,6 +22233,10 @@ cat >>confdefs.h <<_ACEOF _ACEOF +cat >>confdefs.h <<\_ACEOF +#define ENABLE_GPGSM 1 +_ACEOF + fi @@ -22065,6 +22248,8 @@ else HAVE_GPGSM_FALSE= fi + + GPGSM_VERSION=unknown ok=maybe if test -z "$GPGSM" -o "x$GPGSM" = "xno"; then @@ -22903,6 +23088,24 @@ echo "$as_me: WARNING: fixed the GPGME_V fi +# Generate values for the DLL version info +if test "$have_w32_system" = yes; then + BUILD_TIMESTAMP=`date --iso-8601=minutes` + BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` + case "$VERSION" in + *-cvs) BUILD_FILEVERSION="${BUILD_FILEVERSION}0" ;; + *-rc*) BUILD_FILEVERSION="${BUILD_FILEVERSION}1" ;; + *) BUILD_FILEVERSION="${BUILD_FILEVERSION}2" ;; + esac +fi + + + +# Add a few constants to help porting to W32 + + + + # Substitution used for gpgme-config GPGME_CONFIG_LIBS="-lgpgme" GPGME_CONFIG_CFLAGS="" @@ -22918,7 +23121,7 @@ LTLIBOBJS=`echo "$LIBOBJS" | # # Create config files - ac_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="$ac_config_files Makefile assuan/Makefile gpgme/Makefile tests/Makefile tests/gpg/Makefile tests/gpgsm/Makefile doc/Makefile complus/Makefile gpgme/versioninfo.rc" ac_config_files="$ac_config_files gpgme/gpgme-config" @@ -23055,6 +23258,13 @@ echo "$as_me: error: conditional \"HAVE_ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${HAVE_W32_SYSTEM_TRUE}" && test -z "${HAVE_W32_SYSTEM_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"HAVE_W32_SYSTEM\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"HAVE_W32_SYSTEM\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${HAVE_PTH_TRUE}" && test -z "${HAVE_PTH_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"HAVE_PTH\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -23375,7 +23585,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by gpgme $as_me 1.0.3, which was +This file was extended by gpgme $as_me 1.1.0, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -23438,7 +23648,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -gpgme config.status 1.0.3 +gpgme config.status 1.1.0 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -23556,6 +23766,7 @@ do "tests/gpgsm/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/gpgsm/Makefile" ;; "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "complus/Makefile" ) CONFIG_FILES="$CONFIG_FILES complus/Makefile" ;; + "gpgme/versioninfo.rc" ) CONFIG_FILES="$CONFIG_FILES gpgme/versioninfo.rc" ;; "gpgme/gpgme-config" ) CONFIG_FILES="$CONFIG_FILES gpgme/gpgme-config" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; @@ -23693,6 +23904,10 @@ s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@DLLTOOL@,$DLLTOOL,;t t +s,@ac_ct_DLLTOOL@,$ac_ct_DLLTOOL,;t t +s,@WINDRES@,$WINDRES,;t t +s,@ac_ct_WINDRES@,$ac_ct_WINDRES,;t t s,@LIBGPGME_LT_CURRENT@,$LIBGPGME_LT_CURRENT,;t t s,@LIBGPGME_LT_AGE@,$LIBGPGME_LT_AGE,;t t s,@LIBGPGME_LT_REVISION@,$LIBGPGME_LT_REVISION,;t t @@ -23723,6 +23938,8 @@ s,@PTH_LDFLAGS@,$PTH_LDFLAGS,;t t s,@PTH_LIBS@,$PTH_LIBS,;t t s,@HAVE_DOSISH_SYSTEM_TRUE@,$HAVE_DOSISH_SYSTEM_TRUE,;t t s,@HAVE_DOSISH_SYSTEM_FALSE@,$HAVE_DOSISH_SYSTEM_FALSE,;t t +s,@HAVE_W32_SYSTEM_TRUE@,$HAVE_W32_SYSTEM_TRUE,;t t +s,@HAVE_W32_SYSTEM_FALSE@,$HAVE_W32_SYSTEM_FALSE,;t t s,@HAVE_PTH_TRUE@,$HAVE_PTH_TRUE,;t t s,@HAVE_PTH_FALSE@,$HAVE_PTH_FALSE,;t t s,@HAVE_PTHREAD_TRUE@,$HAVE_PTHREAD_TRUE,;t t @@ -23745,6 +23962,8 @@ s,@BUILD_ASSUAN_TRUE@,$BUILD_ASSUAN_TRUE s,@BUILD_ASSUAN_FALSE@,$BUILD_ASSUAN_FALSE,;t t s,@BUILD_COMPLUS_TRUE@,$BUILD_COMPLUS_TRUE,;t t s,@BUILD_COMPLUS_FALSE@,$BUILD_COMPLUS_FALSE,;t t +s,@BUILD_TIMESTAMP@,$BUILD_TIMESTAMP,;t t +s,@BUILD_FILEVERSION@,$BUILD_FILEVERSION,;t t s,@GPGME_CONFIG_API_VERSION@,$GPGME_CONFIG_API_VERSION,;t t s,@GPGME_CONFIG_LIBS@,$GPGME_CONFIG_LIBS,;t t s,@GPGME_CONFIG_CFLAGS@,$GPGME_CONFIG_CFLAGS,;t t diff -urpNP gpgme-1.0.3/configure.ac gpgme-1.1.0/configure.ac --- gpgme-1.0.3/configure.ac 2005-06-20 19:35:19.000000000 +0000 +++ gpgme-1.1.0/configure.ac 2005-10-01 21:13:02.000000000 +0000 @@ -24,17 +24,17 @@ AC_PREREQ(2.59) min_automake_version="1.9.3" # Version number: Remember to change it immediately *after* a release. -AC_INIT(gpgme, 1.0.3, [bug-gpgme@gnupg.org]) +AC_INIT(gpgme, 1.1.0, [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=15 -# Subtract 2 from the AGE value if you want to make the LFS transition an +LIBGPGME_LT_CURRENT=16 +# 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=4 +LIBGPGME_LT_AGE=5 LIBGPGME_LT_REVISION=0 # If the API is changed in an incompatible way: increment the next counter. @@ -43,8 +43,7 @@ GPGME_CONFIG_API_VERSION=1 NEED_GPG_VERSION=1.2.2 NEED_GPGSM_VERSION=1.9.6 ############################################## -AC_PREREQ(2.52) -AC_REVISION($Revision: 1.93.2.5 $) + PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION @@ -57,11 +56,8 @@ 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]) +# Enable GNU extensions on systems that have them. +AC_GNU_SOURCE AH_VERBATIM([_REENTRANT], [/* To allow the use of GPGME in multithreaded programs we have to use @@ -72,8 +68,9 @@ AH_VERBATIM([_REENTRANT], # define _REENTRANT 1 #endif]) - AC_PROG_CC +AC_CHECK_TOOL(DLLTOOL, dlltool, :) +AC_CHECK_TOOL(WINDRES, windres, :) AC_SUBST(LIBGPGME_LT_CURRENT) @@ -109,17 +106,13 @@ AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, t GPG_DEFAULT=no GPGSM_DEFAULT=no component_system=None +have_dosish_system=no +have_w32_system=no case "${host}" in - *-*-mingw32* | i?86-emx-os2 | i?86-*-os2*emx | i?86-*-msdosdjgpp* ) + *-mingw32*) # 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 + have_w32_system=yes GPG_DEFAULT='c:\\gnupg\\gpg.exe' # XXX Assuan is not supported in this configuration. #GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe' @@ -129,7 +122,6 @@ case "${host}" in 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 @@ -141,7 +133,21 @@ case "${host}" in # GPGSM_DEFAULT='/usr/bin/gpgsm' ;; esac -AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = "yes") + +if test "$have_dosish_system" = yes; then + AC_DEFINE(HAVE_DOSISH_SYSTEM,1, + [Defined if we run on some of the PCDOS like systems + (DOS, Windoze. OS/2) with special properties like + no file modes]) +fi +AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = yes) + +if test "$have_w32_system" = yes; then + AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system]) +fi +AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) + + AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes") AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes") @@ -164,7 +170,7 @@ fi # Checks for library functions. AC_FUNC_FSEEKO -AC_REPLACE_FUNCS(stpcpy) +AC_CHECK_FUNCS(stpcpy) AC_REPLACE_FUNCS(vasprintf) if test "$ac_cv_func_vasprintf" != yes; then @@ -337,9 +343,11 @@ if test "$GPGSM" = no; then fi else AC_DEFINE_UNQUOTED(GPGSM_PATH, "$GPGSM", [Path to the GPGSM binary.]) - AC_SUBST(GPGSM) + AC_DEFINE(ENABLE_GPGSM,1,[Whether GPGSM support is enabled]) fi AM_CONDITIONAL(HAVE_GPGSM, test "$GPGSM" != "no") + + dnl Check for GPGSM version requirement. GPGSM_VERSION=unknown ok=maybe @@ -434,6 +442,45 @@ AM_CONDITIONAL(BUILD_COMPLUS, test "$com # (this is easier than to have a *.in file just for one substitution) GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION) +# Generate values for the DLL version info +if test "$have_w32_system" = yes; then + BUILD_TIMESTAMP=`date --iso-8601=minutes` + changequote(,)dnl + BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` + changequote([,])dnl + case "$VERSION" in + *-cvs) BUILD_FILEVERSION="${BUILD_FILEVERSION}0" ;; + *-rc*) BUILD_FILEVERSION="${BUILD_FILEVERSION}1" ;; + *) BUILD_FILEVERSION="${BUILD_FILEVERSION}2" ;; + esac +fi +AC_SUBST(BUILD_TIMESTAMP) +AC_SUBST(BUILD_FILEVERSION) + +# Add a few constants to help porting to W32 +AH_VERBATIM([SEPCONSTANTS], +[ +/* Separators as used in file names and $PATH. Please note that the + string version must not contain more than one character because + the using code assumes strlen()==1 */ +#ifdef HAVE_DOSISH_SYSTEM +#define DIRSEP_C '\\\\' +#define EXTSEP_C '.' +#define DIRSEP_S "\\\\" +#define EXTSEP_S "." +#define PATHSEP_C ';' +#define PATHSEP_S ";" +#else +#define DIRSEP_C '/' +#define EXTSEP_C '.' +#define DIRSEP_S "/" +#define EXTSEP_S "." +#define PATHSEP_C ':' +#define PATHSEP_S ":" +#endif +]) + + # Substitution used for gpgme-config GPGME_CONFIG_LIBS="-lgpgme" GPGME_CONFIG_CFLAGS="" @@ -451,7 +498,8 @@ AC_SUBST(LTLIBOBJS) AC_CONFIG_FILES(Makefile assuan/Makefile gpgme/Makefile tests/Makefile tests/gpg/Makefile tests/gpgsm/Makefile - doc/Makefile complus/Makefile) + doc/Makefile complus/Makefile + gpgme/versioninfo.rc) AC_CONFIG_FILES(gpgme/gpgme-config, chmod +x gpgme/gpgme-config) AC_OUTPUT diff -urpNP gpgme-1.0.3/depcomp gpgme-1.1.0/depcomp --- gpgme-1.0.3/depcomp 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/depcomp 2005-09-08 14:42:33.000000000 +0000 @@ -1,9 +1,7 @@ #! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2004-05-31.23 -# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. +# 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 @@ -27,45 +25,22 @@ scriptversion=2004-05-31.23 # Originally written by Alexandre Oliva . -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit 0 - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit 0 - ;; -esac - 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 -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" @@ -197,25 +172,19 @@ sgi) aix) # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, 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. - # Version 6 uses the directory in both cases. - stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + # 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 -f "$tmpdepfile"; then : - else - stripped=`echo "$stripped" | sed 's,^.*/,,'` - tmpdepfile="$stripped.u" - fi + stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" @@ -223,7 +192,6 @@ aix) fi if test -f "$tmpdepfile"; then - outname="$stripped.o" # 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:'. @@ -287,40 +255,31 @@ tru64) base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then - # Dependencies are output in .lo.d with libtool 1.4. - # With libtool 1.5 they are output both in $dir.libs/$base.o.d - # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the - # latter, because the former will be cleaned when $dir.libs is - # erased. tmpdepfile1="$dir.libs/$base.lo.d" - tmpdepfile2="$dir$base.o.d" - tmpdepfile3="$dir.libs/$base.d" + tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" - tmpdepfile3="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" - elif test -f "$tmpdepfile2"; then - tmpdepfile="$tmpdepfile2" else - tmpdepfile="$tmpdepfile3" + tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$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 @@ -333,7 +292,7 @@ tru64) dashmstdout) # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. + # always write the proprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. @@ -429,7 +388,7 @@ makedepend) cpp) # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. + # always write the proprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. @@ -471,7 +430,7 @@ cpp) msvisualcpp) # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o, + # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " @@ -511,12 +470,3 @@ none) esac exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff -urpNP gpgme-1.0.3/doc/ChangeLog gpgme-1.1.0/doc/ChangeLog --- gpgme-1.0.3/doc/ChangeLog 2005-05-28 19:53:14.000000000 +0000 +++ gpgme-1.1.0/doc/ChangeLog 2005-10-01 02:06:08.000000000 +0000 @@ -1,3 +1,30 @@ +2005-10-01 Marcus Brinkmann + + * gpgme.texi (Signature Notation Data): New section. + (Verify): Added more about the notation data structure. + +2005-09-30 Marcus Brinkmann + + * gpgme.texi (Data Buffer I/O Operations, Data Buffer Meta-Data): + New subsections. + + * gpgme.texi: Replace plaintext_filename with file_name. + + * gpgme.texi (Key Management): Document is_qualified. + +2005-07-27 Marcus Brinkmann + + * gpgme.texi (Decrypt): Add plaintext_filename to + gpgme_decrypt_result_t. + (Verify): Likewise for gpgme_verify_result_t. + +2005-06-03 Marcus Brinkmann + + * gpgme.texi (Verify): Add information about new fields in + gpgme_signature_t. + + * gpgme.texi (Decrypt): Add gpgme_recipient_t. + 2005-05-28 Marcus Brinkmann * gpgme.texi (Key Listing Mode): Fix return type of @@ -9,6 +36,11 @@ * gpgme.texi (Included Certificates): Document GPGME_INCLUDE_CERTS_DEFAULT. +2005-01-12 Marcus Brinkmann + + * gpgme.texi (Engine Configuration): New section. + (Crypto Engine): New subsection. + 2004-12-07 Marcus Brinkmann * lesser.texi (Library Copying): Change from @appendixsec to diff -urpNP gpgme-1.0.3/doc/Makefile.in gpgme-1.1.0/doc/Makefile.in --- gpgme-1.0.3/doc/Makefile.in 2005-06-20 19:35:24.000000000 +0000 +++ gpgme-1.1.0/doc/Makefile.in 2005-10-01 21:13:45.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -97,6 +97,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -109,6 +111,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -137,6 +140,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -175,12 +180,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ @@ -268,9 +276,11 @@ distclean-libtool: restore=: && backupdir="$(am__leading_dot)am$$$$" && \ am__cwd=`pwd` && cd $(srcdir) && \ rm -rf $$backupdir && mkdir $$backupdir && \ - for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ - if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ - done; \ + if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ + for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ + if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ + done; \ + else :; fi && \ cd "$$am__cwd"; \ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $@ $<; \ @@ -331,6 +341,7 @@ mostlyclean-vti: maintainer-clean-vti: @MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi .dvi.ps: + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ $(DVIPS) -o $@ $< uninstall-info-am: diff -urpNP gpgme-1.0.3/doc/gpgme.texi gpgme-1.1.0/doc/gpgme.texi --- gpgme-1.0.3/doc/gpgme.texi 2005-05-28 19:53:28.000000000 +0000 +++ gpgme-1.1.0/doc/gpgme.texi 2005-10-01 02:06:08.000000000 +0000 @@ -125,6 +125,7 @@ Protocols and Engines * Engine Version Check:: Verifying the engine version. * Engine Information:: Obtaining more information about the engines. +* Engine Configuration:: Changing the engine configuration. * OpenPGP:: Support for the OpenPGP protocol. * Cryptographic Message Syntax:: Support for the CMS. @@ -152,6 +153,11 @@ Creating Data Buffers * File Based Data Buffers:: Creating file based data buffers. * Callback Based Data Buffers:: Creating callback based data buffers. +Manipulating Data Buffers + +* Data Buffer I/O Operations:: I/O operations on data buffers. +* Data Buffer Meta-Data:: Meta-data manipulation of data buffers. + Contexts * Creating Contexts:: Creating new @acronym{GPGME} contexts. @@ -165,6 +171,7 @@ Contexts Context Attributes * Protocol Selection:: Selecting the protocol used by a context. +* Crypto Engine:: Configuring the crypto engine. * ASCII Armor:: Requesting @acronym{ASCII} armored output. * Text Mode:: Choosing canonical text mode. * Included Certificates:: Including a number of certificates. @@ -202,6 +209,7 @@ Sign * Selecting Signers:: How to choose the keys to sign with. * Creating a Signature:: How to create a signature. +* Signature Notation Data:: How to add notation data to a signature. Encrypt @@ -745,6 +753,7 @@ allocated string describing the protocol @menu * Engine Version Check:: Verifying the engine version. * Engine Information:: Obtaining more information about the engines. +* Engine Configuration:: Changing the engine configuration. * OpenPGP:: Support for the OpenPGP protocol. * Cryptographic Message Syntax:: Support for the CMS. @end menu @@ -789,6 +798,11 @@ This is a string holding the file name o engine. Currently, it is never @code{NULL}, but using @code{NULL} is reserved for future use, so always check before you use it. +@item const char *home_dir +This is a string holding the directory name of the crypto engine's +configuration directory. If it is @code{NULL}, then the default +directory is used. + @item const char *version This is a string containing the version number of the crypto engine. It might be @code{NULL} if the version number can not be determined, @@ -803,10 +817,10 @@ reserved for future use, so always check @end table @end deftp -@deftypefun gpgme_error_t gpgme_get_engine_info (gpgme_engine_info_t *info) +@deftypefun gpgme_error_t gpgme_get_engine_info (@w{gpgme_engine_info_t *@var{info}}) The function @code{gpgme_get_engine_info} returns a linked list of engine info structures in @var{info}. Each info structure describes -one configured backend. +the defaults of one configured backend. The memory for the info structures is allocated the first time this function is invoked, and must not be freed by the caller. @@ -850,6 +864,37 @@ if (gpgme_err_code (err) == GPG_ERR_INV_ @end example +@node Engine Configuration +@section Engine Configuration +@cindex engine, configuration of +@cindex configuration of crypto backend + +You can change the configuration of a backend engine, and thus change +the executable program and configuration directory to be used. You +can make these changes the default or set them for some contexts +individually. + +@deftypefun gpgme_error_t gpgme_set_engine_info (@w{gpgme_protocol_t @var{proto}}, @w{const char *@var{file_name}}, @w{const char *@var{home_dir}}) +The function @code{gpgme_set_engine_info} changes the default +configuration of the crypto engine implementing the protocol +@var{proto}. + +@var{file_name} is the file name of the executable program +implementing this protocol, and @var{home_dir} is the directory name +of the configuration directory for this crypto engine. If +@var{home_dir} is @code{NULL}, the engine's default will be used. + +The new defaults are not applied to already created GPGME contexts. + +This function returns the error code @code{GPG_ERR_NO_ERROR} if +successful, or an eror code on failure. +@end deftypefun + +The functions @code{gpgme_ctx_get_engine_info} and +@code{gpgme_ctx_set_engine_info} can be used to change the engine +configuration per context. @xref{Crypto Engine}. + + @node OpenPGP @section OpenPGP @cindex OpenPGP @@ -1677,7 +1722,24 @@ be returned to the user, the function wi @node Manipulating Data Buffers @section Manipulating Data Buffers -@cindex data buffere, manipulation +@cindex data buffer, manipulation + +Data buffers contain data and meta-data. The following operations can +be used to manipulate both. + + +@menu +* Data Buffer I/O Operations:: I/O operations on data buffers. +* Data Buffer Meta-Data:: Meta-data manipulation of data buffers. +@end menu + + +@node Data Buffer I/O Operations +@subsection Data Buffer I/O Operations +@cindex data buffer, I/O operations +@cindex data buffer, read +@cindex data buffer, write +@cindex data buffer, seek @deftypefun ssize_t gpgme_data_read (@w{gpgme_data_t @var{dh}}, @w{void *@var{buffer}}, @w{size_t @var{length}}) The function @code{gpgme_data_read} reads up to @var{length} bytes @@ -1744,9 +1806,39 @@ The function @code{gpgme_data_rewind} is @end example @end deftypefun -@c -@c gpgme_data_encoding_t -@c + + + +@node Data Buffer Meta-Data +@subsection Data Buffer Meta-Data +@cindex data buffer, meta-data +@cindex data buffer, file name +@cindex data buffer, encoding + +@deftypefun char *gpgme_data_get_file_name (@w{gpgme_data_t @var{dh}}) +The function @code{gpgme_data_get_file_name} returns a pointer to a +string containing the file name associated with the data object. The +file name will be stored in the output when encrypting or signing the +data and will be returned to the user when decrypting or verifying the +output data. + +If no error occurs, the string containing the file name is returned. +Otherwise, @code{NULL} will be returned. +@end deftypefun + + +@deftypefun gpgme_error_t gpgme_data_set_file_name (@w{gpgme_data_t @var{dh}}, @w{const char *@var{file_name}}) +The function @code{gpgme_data_set_file_name} sets the file name +associated with the data object. The file name will be stored in the +output when encrypting or signing the data and will be returned to the +user when decrypting or verifying the output data. + +The function returns the error code @code{GPG_ERR_INV_VALUE} if +@var{dh} is not a valid pointer and @code{GPG_ERR_ENOMEM} if not +enough memory is available. +@end deftypefun + + @deftp {Data type} {enum gpgme_data_encoding_t} @tindex gpgme_data_encoding_t The @code{gpgme_data_encoding_t} type specifies the encoding of a @@ -1847,6 +1939,7 @@ The function @code{gpgme_release} destro @menu * Protocol Selection:: Selecting the protocol used by a context. +* Crypto Engine:: Configuring the crypto engine. * ASCII Armor:: Requesting @acronym{ASCII} armored output. * Text Mode:: Choosing canonical text mode. * Included Certificates:: Including a number of certificates. @@ -1882,6 +1975,50 @@ The function @code{gpgme_get_protocol} r use with the context @var{ctx}. @end deftypefun + +@node Crypto Engine +@subsection Crypto Engine +@cindex context, configuring engine +@cindex engine, configuration per context + +The following functions can be used to set and retrieve the +configuration of the crypto engines of a specific context. The +default can also be retrieved without any particular context. +@xref{Engine Information}. The default can also be changed globally. +@xref{Engine Configuration}. + +@deftypefun gpgme_engine_info_t gpgme_ctx_get_engine_info (@w{gpgme_ctx_t @var{ctx}}) +The function @code{gpgme_ctx_get_engine_info} returns a linked list of +engine info structures. Each info structure describes the +configuration of one configured backend, as used by the context +@var{ctx}. + +The result is valid until the next invocation of +@code{gpgme_ctx_set_engine_info} for this particular context. + +This function can not fail. +@end deftypefun + +@deftypefun gpgme_error_t gpgme_ctx_set_engine_info (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_protocol_t @var{proto}}, @w{const char *@var{file_name}}, @w{const char *@var{home_dir}}) +The function @code{gpgme_ctx_set_engine_info} changes the +configuration of the crypto engine implementing the protocol +@var{proto} for the context @var{ctx}. + +@var{file_name} is the file name of the executable program +implementing this protocol, and @var{home_dir} is the directory name +of the configuration directory for this crypto engine. If +@var{home_dir} is @code{NULL}, the engine's default will be used. + +Currently this function must be used before starting the first crypto +operation. It is unspecified if and when the changes will take effect +if the function is called after starting the first operation on the +context @var{ctx}. + +This function returns the error code @code{GPG_ERR_NO_ERROR} if +successful, or an eror code on failure. +@end deftypefun + + @c FIXME: Unfortunately, using @acronym here breaks texi2dvi. @node ASCII Armor @subsection @acronym{ASCII} Armor @@ -2229,6 +2366,10 @@ This is true if the subkey can be used t @item unsigned int can_authenticate : 1 This is true if the subkey can be used for authentication. +@item unsigned int is_qualified : 1 +This is true if the subkey can be used for qualified signatures +according to local government regulations. + @item unsigned int secret : 1 This is true if the subkey is a secret key. @@ -2397,6 +2538,10 @@ key certificates. This is true if the key (ie one of its subkeys) can be used for authentication. +@item unsigned int is_qualified : 1 +This is true if the key can be used for qualified signatures according +to local government regulations. + @item unsigned int secret : 1 This is true if the key is a secret key. @@ -3538,9 +3683,38 @@ operation could be started successfully, if @var{cipher} or @var{plain} is not a valid pointer. @end deftypefun +@deftp {Data type} {gpgme_recipient_t} +This is a pointer to a structure used to store information about the +recipient of an encrypted text which is decrypted in a +@code{gpgme_op_decrypt} operation. This information (except for the +status field) is even available before the operation finished +successfully, for example in a passphrase callback. The structure +contains the following members: + +@table @code +@item gpgme_recipient_t next +This is a pointer to the next recipient structure in the linked list, +or @code{NULL} if this is the last element. + +@item gpgme_pubkey_algo_t +The public key algorithm used in the encryption. + +@item unsigned int wrong_key_usage : 1 +This is true if the key was not used according to its policy. + +@item char *keyid +This is the key ID of the key (in hexadecimal digits) used as +recipient. + +@item gpgme_error_t status +This is an error number with the error code GPG_ERR_NO_SECKEY if the +secret key for this recipient is not available, and 0 otherwise. +@end table +@end deftp + @deftp {Data type} {gpgme_decrypt_result_t} This is a pointer to a structure used to store the result of a -@code{gpgme_op_decrypt} operation. After successfully encrypting +@code{gpgme_op_decrypt} operation. After successfully decrypting data, you can retrieve the pointer to the result with @code{gpgme_op_decrypt_result}. The structure contains the following members: @@ -3552,6 +3726,13 @@ algorithm that is not supported. @item unsigned int wrong_key_usage : 1 This is true if the key was not used according to its policy. + +@item gpgme_recipient_t recipient +This is a linked list of recipients to which this message was encrypted. + +@item char *file_name +This is the filename of the original plaintext message file if it is +known, otherwise this is a null pointer. @end table @end deftp @@ -3573,6 +3754,8 @@ the context. @cindex signature, verification @cindex cryptographic operation, verification @cindex cryptographic operation, signature check +@cindex signature notation data +@cindex notation data @deftypefun gpgme_error_t gpgme_op_verify (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_data_t @var{sig}}, @w{gpgme_data_t @var{signed_text}}, @w{gpgme_data_t @var{plain}}) The function @code{gpgme_op_verify} verifies that the signature in the @@ -3621,9 +3804,45 @@ linked list, or @code{NULL} if this is t The name of the notation field. If this is @code{NULL}, then the member @code{value} will contain a policy URL. +@item int name_len +The length of the @code{name} field. For strings the length is +counted without the trailing binary zero. + @item char *value The value of the notation field. If @code{name} is @code{NULL}, then this is a policy URL. + +@item int value_len +The length of the @code{value} field. For strings the length is +counted without the trailing binary zero. + +@item gpgme_sig_notation_flags_t flags +The accumulated flags field. This field contains the flags associated +with the notation data in an accumulated form which can be used as an +argument to the function @code{gpgme_sig_notation_add}. The value +@code{flags} is a bitwise-or combination of one or multiple of the +following bit values: + +@table @code +@item GPGME_SIG_NOTATION_HUMAN_READABLE +The @code{GPGME_SIG_NOTATION_HUMAN_READABLE} symbol specifies that the +notation data is in human readable form + +@item GPGME_SIG_NOTATION_CRITICAL +The @code{GPGME_SIG_NOTATION_CRITICAL} symbol specifies that the +notation data is critical. + +@end table + +@item unsigned int human_readable : 1 +This is true if the @code{GPGME_SIG_NOTATION_HUMAN_READABLE} flag is +set and false otherwise. This flag is only valid for notation data, +not for policy URLs. + +@item unsigned int critical : 1 +This is true if the @code{GPGME_SIG_NOTATION_CRITICAL} flag is set and +false otherwise. This flag is valid for notation data and policy URLs. + @end table @end deftp @@ -3745,6 +3964,11 @@ The validity of the signature. @item gpgme_error_t validity_reason If a signature is not valid, this provides a reason why. +@item gpgme_pubkey_algo_t +The public key algorithm used to create this signature. + +@item gpgme_hash_algo_t +The hash algorithm used to create this signature. @end table @end deftp @@ -3759,6 +3983,10 @@ a @code{NULL} pointer. The structure co @item gpgme_signature_t signatures A linked list with information about all signatures for which a verification was attempted. + +@item char *file_name +This is the filename of the original plaintext message file if it is +known, otherwise this is a null pointer. @end table @end deftp @@ -4069,6 +4297,7 @@ set is changed). @menu * Selecting Signers:: How to choose the keys to sign with. * Creating a Signature:: How to create a signature. +* Signature Notation Data:: How to add notation data to a signature. @end menu @@ -4217,6 +4446,58 @@ context. @end deftypefun +@node Signature Notation Data +@subsubsection Signature Notation Data +@cindex notation data +@cindex signature notation data +@cindex policy URL + +Using the following functions, you can attach arbitrary notation data +to a signature. This information is then available to the user when +the signature is verified. + +@deftypefun void gpgme_sig_notation_clear (@w{gpgme_ctx_t @var{ctx}}) +The function @code{gpgme_sig_notation_clear} removes the notation data +from the context @var{ctx}. Subsequent signing operations from this +context will not include any notation data. + +Every context starts with an empty notation data list. +@end deftypefun + +@deftypefun gpgme_error_t gpgme_sig_notation_add (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{name}}, @w{const char *@var{value}}, @w{gpgme_sig_notation_flags_t @var{flags}}) +The function @code{gpgme_sig_notation_add} adds the notation data with +the name @var{name} and the value @var{value} to the context +@var{ctx}. + +Subsequent signing operations will include this notation data, as well +as any other notation data that was added since the creation of the +context or the last @code{gpgme_sig_notation_clear} operation. + +The arguments @var{name} and @var{value} must be @code{NUL}-terminated +strings in human-readable form. The flag +@code{GPGME_SIG_NOTATION_HUMAN_READABLE} is implied +(non-human-readable notation data is currently not supported). The +strings must be in UTF-8 encoding. + +If @var{name} is @code{NULL}, then @var{value} should be a policy URL. + +The function @code{gpgme_sig_notation_add} returns the error code +@code{GPG_ERR_NO_ERROR} if the notation data could be added +successfully, @code{GPG_ERR_INV_VALUE} if @var{ctx} is not a valid +pointer, or if @var{name}, @var{value} and @var{flags} are an invalid +combination. The function also passes through any errors that are +reported by the crypto engine support routines. +@end deftypefun + +@deftypefun gpgme_sig_notation_t gpgme_sig_notation_get (@w{const gpgme_ctx_t @var{ctx}}) +The function @code{gpgme_sig_notation_get} returns the linked list of +notation data structures that are contained in the context @var{ctx}. + +If @var{ctx} is not a valid pointer, or there is no notation data +added for this context, @code{NULL} is returned. +@end deftypefun + + @node Encrypt @subsection Encrypt @cindex encryption diff -urpNP gpgme-1.0.3/doc/mdate-sh gpgme-1.1.0/doc/mdate-sh --- gpgme-1.0.3/doc/mdate-sh 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/doc/mdate-sh 2005-09-08 14:42:33.000000000 +0000 @@ -1,8 +1,5 @@ #!/bin/sh # Get modification time of a file or directory and pretty-print it. - -scriptversion=2003-11-09.00 - # Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc. # written by Ulrich Drepper , June 1995 # @@ -25,31 +22,6 @@ scriptversion=2003-11-09.00 # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case $1 in - '') - echo "$0: No file. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: mdate-sh [--help] [--version] FILE - -Pretty-print the modification time of FILE. - -Report bugs to . -EOF - exit 0 - ;; - -v | --v*) - echo "mdate-sh $scriptversion" - exit 0 - ;; -esac - # Prevent date giving response in another language. LANG=C export LANG @@ -159,12 +131,3 @@ esac # The result. echo $day $month $year - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff -urpNP gpgme-1.0.3/doc/stamp-vti gpgme-1.1.0/doc/stamp-vti --- gpgme-1.0.3/doc/stamp-vti 2005-06-20 19:35:41.000000000 +0000 +++ gpgme-1.1.0/doc/stamp-vti 2005-10-01 21:15:18.000000000 +0000 @@ -1,4 +1,4 @@ -@set UPDATED 28 May 2005 -@set UPDATED-MONTH May 2005 -@set EDITION 1.0.3 -@set VERSION 1.0.3 +@set UPDATED 1 October 2005 +@set UPDATED-MONTH October 2005 +@set EDITION 1.1.0 +@set VERSION 1.1.0 diff -urpNP gpgme-1.0.3/doc/texinfo.tex gpgme-1.1.0/doc/texinfo.tex --- gpgme-1.0.3/doc/texinfo.tex 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/doc/texinfo.tex 2005-09-08 14:42:33.000000000 +0000 @@ -3,11 +3,10 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2004-10-31.06} +\def\texinfoversion{2003-05-04.08} % % Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, -% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software -% Foundation, Inc. +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. % % This texinfo.tex file is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License as @@ -24,16 +23,21 @@ % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % -% As a special exception, when this file is read by TeX when processing -% a Texinfo source document, you may use the result without -% restriction. (This has been our intent since Texinfo was invented.) +% In other words, you are welcome to use, share and improve this program. +% You are forbidden to forbid anyone else to use, share and improve +% what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: -% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or +% ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex +% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://tug.org/tex/texinfo.tex -% (and all CTAN mirrors, see http://www.ctan.org). -% The texinfo.tex in any given distribution could well be out +% (and all CTAN mirrors, see http://www.ctan.org), +% and /home/gd/gnu/doc/texinfo.tex on the GNU machines. +% +% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. +% +% The texinfo.tex in any given Texinfo distribution could well be out % of date, so if that's what you're using, please check. % % Send bug reports to bug-texinfo@gnu.org. Please include including a @@ -55,9 +59,6 @@ % It is possible to adapt texinfo.tex for other languages, to some % extent. You can get the existing language-specific files from the % full Texinfo distribution. -% -% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. - \message{Loading texinfo [version \texinfoversion]:} @@ -84,13 +85,10 @@ \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! -\let\ptexfootnote=\footnote \let\ptexgtr=> \let\ptexhat=^ \let\ptexi=\i \let\ptexindent=\indent -\let\ptexnoindent=\noindent -\let\ptexinsert=\insert \let\ptexlbrace=\{ \let\ptexless=< \let\ptexplus=+ @@ -103,15 +101,6 @@ % starts a new line in the output. \newlinechar = `^^J -% Use TeX 3.0's \inputlineno to get the line number, for better error -% messages, but if we're using an old version of TeX, don't do anything. -% -\ifx\inputlineno\thisisundefined - \let\linenumber = \empty % Pre-3.0. -\else - \def\linenumber{l.\the\inputlineno:\space} -\fi - % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi @@ -150,81 +139,43 @@ \ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi \ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi +\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi % In some macros, we cannot use the `\? notation---the left quote is % in some cases the escape char. \chardef\colonChar = `\: \chardef\commaChar = `\, \chardef\dotChar = `\. +\chardef\equalChar = `\= \chardef\exclamChar= `\! \chardef\questChar = `\? \chardef\semiChar = `\; -\chardef\underChar = `\_ - \chardef\spaceChar = `\ % -\chardef\spacecat = 10 -\def\spaceisspace{\catcode\spaceChar=\spacecat} +\chardef\underChar = `\_ % Ignore a token. % \def\gobble#1{} -% The following is used inside several \edef's. -\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} +% True if #1 is the empty string, i.e., called like `\ifempty{}'. +% +\def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% +\def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% % Hyphenation fixes. -\hyphenation{ - Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script - ap-pen-dix bit-map bit-maps - data-base data-bases eshell fall-ing half-way long-est man-u-script - man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm - par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces - spell-ing spell-ings - stand-alone strong-est time-stamp time-stamps which-ever white-space - wide-spread wrap-around -} +\hyphenation{ap-pen-dix} +\hyphenation{eshell} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{time-stamp} +\hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen\bindingoffset \newdimen\normaloffset \newdimen\pagewidth \newdimen\pageheight -% For a final copy, take out the rectangles -% that mark overfull boxes (in case you have decided -% that the text looks ok even though it passes the margin). -% -\def\finalout{\overfullrule=0pt} - -% @| inserts a changebar to the left of the current line. It should -% surround any changed text. This approach does *not* work if the -% change spans more than two lines of output. To handle that, we would -% have adopt a much more difficult approach (putting marks into the main -% vertical list for the beginning and end of each change). -% -\def\|{% - % \vadjust can only be used in horizontal mode. - \leavevmode - % - % Append this vertical mode material after the current line in the output. - \vadjust{% - % We want to insert a rule with the height and depth of the current - % leading; that is exactly what \strutbox is supposed to record. - \vskip-\baselineskip - % - % \vadjust-items are inserted at the left edge of the type. So - % the \llap here moves out into the left-hand margin. - \llap{% - % - % For a thicker or thinner bar, change the `1pt'. - \vrule height\baselineskip width1pt - % - % This is the space between the bar and the text. - \hskip 12pt - }% - }% -} - % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. We also make @@ -249,7 +200,7 @@ \tracingassigns1 \fi \tracingcommands3 % 3 gives us more in etex - \errorcontextlines16 + \errorcontextlines\maxdimen }% % add check for \lastpenalty to plain's definitions. If the last thing @@ -307,7 +258,7 @@ % the page break happens to be in the middle of an example. \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. - \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi % \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize @@ -388,162 +339,132 @@ % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % -\def\parsearg{\parseargusing{}} -\def\parseargusing#1#2{% - \def\next{#2}% +\def\parsearg#1{% + \let\next = #1% \begingroup \obeylines - \spaceisspace - #1% - \parseargline\empty% Insert the \empty token, see \finishparsearg below. + \futurelet\temp\parseargx } +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. +\def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} + +% Remove a single space (as the delimiter token to the macro call). +{\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. - \argremovecomment #1\comment\ArgTerm% + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% }% } -% First remove any @comment, then any @c comment. -\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} -\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} -% Each occurence of `\^^M' or `\^^M' is replaced by a single space. -% -% \argremovec might leave us with trailing space, e.g., +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo -% This space token undergoes the same procedure and is eventually removed -% by \finishparsearg. +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. % -\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} -\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} -\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% - \def\temp{#3}% - \ifx\temp\empty - % We cannot use \next here, as it holds the macro to run; - % thus we reuse \temp. - \let\temp\finishparsearg - \else - \let\temp\argcheckspaces - \fi - % Put the space token in: - \temp#1 #3\ArgTerm +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup } -% If a _delimited_ argument is enclosed in braces, they get stripped; so -% to get _exactly_ the rest of the line, we had to prevent such situation. -% We prepended an \empty token at the very beginning and we expand it now, -% just before passing the control to \next. -% (Similarily, we have to think about #3 of \argcheckspacesY above: it is -% either the null string, or it ends with \^^M---thus there is no danger -% that a pair of braces would be stripped. +% Change the active space to expand to nothing. % -% But first, we have to remove the trailing space token. -% -\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}} +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup -% \parseargdef\foo{...} -% is roughly equivalent to -% \def\foo{\parsearg\Xfoo} -% \def\Xfoo#1{...} -% -% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my -% favourite TeX trick. --kasal, 16nov03 -\def\parseargdef#1{% - \expandafter \doparseargdef \csname\string#1\endcsname #1% -} -\def\doparseargdef#1#2{% - \def#2{\parsearg#1}% - \def#1##1% -} +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} -% Several utility definitions with active space: -{ - \obeyspaces - \gdef\obeyedspace{ } +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment; press RETURN to continue} +\endgroup\fi} % This is not perfect, but it should reduce lossage - % Make each space character in the input produce a normal interword - % space in the output. Don't allow a line break at this space, as this - % is used only in environments like @example, where each line of input - % should produce a line of output anyway. - % - \gdef\sepspaces{\obeyspaces\let =\tie} - - % If an index command is used in an @example environment, any spaces - % therein should become regular spaces in the raw index file, not the - % expansion of \tie (\leavevmode \penalty \@M \ ). - \gdef\unsepspaces{\let =\space} -} +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Press RETURN to continue.} +\outer\def\begin{\parsearg\beginxxx} -\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} -% Define the framework for environments in texinfo.tex. It's used like this: -% -% \envdef\foo{...} -% \def\Efoo{...} +% @end foo executes the definition of \Efoo. % -% It's the responsibility of \envdef to insert \begingroup before the -% actual body; @end closes the group after calling \Efoo. \envdef also -% defines \thisenv, so the current environment is known; @end checks -% whether the environment name matches. The \checkenv macro can also be -% used to check whether the current environment is the one expected. -% -% Non-false conditionals (@iftex, @ifset) don't fit into this, so they -% are not treated as enviroments; they don't open a group. (The -% implementation of @end takes care not to call \endgroup in this -% special case.) - - -% At runtime, environments start with this: -\def\startenvironment#1{\begingroup\def\thisenv{#1}} -% initialize -\let\thisenv\empty - -% ... but they get defined via ``\envdef\foo{...}'': -\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} -\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} - -% Check whether we're in the right environment: -\def\checkenv#1{% - \def\temp{#1}% - \ifx\thisenv\temp +\def\end{\parsearg\endxxx} +\def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi \else - \badenverr + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname \fi } -% Evironment mismatch, #1 expected: -\def\badenverr{% +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% \errhelp = \EMsimple - \errmessage{This command can appear only \inenvironment\temp, - not \inenvironment\thisenv}% -} -\def\inenvironment#1{% - \ifx#1\empty - out of any environment% - \else - in environment \expandafter\string#1% - \fi + \errmessage{This `@end #1' doesn't have a matching `@#1'}% } -% @end foo executes the definition of \Efoo. -% But first, it executes a specialized version of \checkenv +% Define the control sequence \E#1 to give an unmatched @end error. % -\parseargdef\end{% - \if 1\csname iscond.#1\endcsname - \else - % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03 - \expandafter\checkenv\csname#1\endcsname - \csname E#1\endcsname - \endgroup - \fi +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } -\newhelp\EMsimple{Press RETURN to continue.} - %% Simple single-character @ commands @@ -575,9 +496,6 @@ !gdef!rbraceatcmd[@}]% !endgroup -% @comma{} to avoid , parsing problems. -\let\comma = , - % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. \let\, = \c @@ -587,12 +505,10 @@ \let\ubaraccent = \b \let\udotaccent = \d -% Other special characters: @questiondown @exclamdown @ordf @ordm +% Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} -\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} -\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} % Dotless i and dotless j, used for accents. \def\imacro{i} @@ -605,25 +521,6 @@ \fi\fi } -% The \TeX{} logo, as in plain, but resetting the spacing so that a -% period following counts as ending a sentence. (Idea found in latex.) -% -\edef\TeX{\TeX \spacefactor=1000 } - -% @LaTeX{} logo. Not quite the same results as the definition in -% latex.ltx, since we use a different font for the raised A; it's most -% convenient for us to use an explicitly smaller font, rather than using -% the \scriptstyle font (since we don't reset \scriptstyle and -% \scriptscriptstyle). -% -\def\LaTeX{% - L\kern-.36em - {\setbox0=\hbox{T}% - \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}% - \kern-.15em - \TeX -} - % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and @@ -677,14 +574,59 @@ \newbox\groupbox \def\vfilllimit{0.7} % -\envdef\group{% - \ifnum\catcode`\^^M=\active \else +\def\group{\begingroup + \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi - \startsavinginserts + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \pageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\pageheight + \page + \fi + \fi + \copy\groupbox + \endgroup % End the \group. + }% % \setbox\groupbox = \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after @@ -694,32 +636,6 @@ \comment } % -% The \vtop produces a box with normal height and large depth; thus, TeX puts -% \baselineskip glue before it, and (when the next line of text is done) -% \lineskip glue after it. Thus, space below is not quite equal to space -% above. But it's pretty close. -\def\Egroup{% - % To get correct interline space between the last line of the group - % and the first line afterwards, we have to propagate \prevdepth. - \endgraf % Not \par, as it may have been set to \lisppar. - \global\dimen1 = \prevdepth - \egroup % End the \vtop. - % \dimen0 is the vertical size of the group's box. - \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox - % \dimen2 is how much space is left on the page (more or less). - \dimen2 = \pageheight \advance\dimen2 by -\pagetotal - % if the group doesn't fit on the current page, and it's a big big - % group, force a page break. - \ifdim \dimen0 > \dimen2 - \ifdim \pagetotal < \vfilllimit\pageheight - \page - \fi - \fi - \box\groupbox - \prevdepth = \dimen1 - \checkinserts -} -% % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % @@ -732,8 +648,10 @@ where each line of input produces a line \newdimen\mil \mil=0.001in +\def\need{\parsearg\needx} + % Old definition--didn't work. -%\parseargdef\need{\par % +%\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% @@ -741,7 +659,7 @@ where each line of input produces a line %\prevdepth=-1000pt %}} -\parseargdef\need{% +\def\needx#1{% % Ensure vertical mode, so we don't make a big box in the middle of a % paragraph. \par @@ -780,10 +698,35 @@ where each line of input produces a line \fi } -% @br forces paragraph break (and is undocumented). +% @br forces paragraph break \let\br = \par +% @dots{} output an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in a typewriter +% font as three actual period characters. +% +\def\dots{% + \leavevmode + \hbox to 1.5em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \leavevmode + \hbox to 2em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% + \spacefactor=3000 +} + % @page forces the start of a new page. % \def\page{\par\vfill\supereject} @@ -796,11 +739,13 @@ where each line of input produces a line \newskip\exdentamount % This defn is used inside fill environments such as @defun. -\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. -\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount - \leftline{\hskip\leftskip{\rm#1}}}} +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current % paragraph. For more general purposes, use the \margin insertion @@ -852,19 +797,8 @@ where each line of input produces a line } % @include file insert text of that file as input. -% -\def\include{\parseargusing\filenamecatcodes\includezzz} -\def\includezzz#1{% - \pushthisfilestack - \def\thisfile{#1}% - {% - \makevalueexpandable - \def\temp{\input #1 }% - \expandafter - }\temp - \popthisfilestack -} -\def\filenamecatcodes{% +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other @@ -873,50 +807,33 @@ where each line of input produces a line \catcode`<=\other \catcode`>=\other \catcode`+=\other - \catcode`-=\other -} - -\def\pushthisfilestack{% - \expandafter\pushthisfilestackX\popthisfilestack\StackTerm -} -\def\pushthisfilestackX{% - \expandafter\pushthisfilestackY\thisfile\StackTerm -} -\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% - \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% -} - -\def\popthisfilestack{\errthisfilestackempty} -\def\errthisfilestackempty{\errmessage{Internal error: - the stack of filenames is empty.}} + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \let\value=\expandablevalue + \input\thisfile +\endgroup} \def\thisfile{} % @center line % outputs that line, centered. % -\parseargdef\center{% - \ifhmode - \let\next\centerH - \else - \let\next\centerV - \fi - \next{\hfil \ignorespaces#1\unskip \hfil}% -} -\def\centerH#1{% - {% - \hfil\break - \advance\hsize by -\leftskip - \advance\hsize by -\rightskip - \line{#1}% - \break - }% -} -\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}} +\def\center{\parsearg\docenter} +\def\docenter#1{{% + \ifhmode \hfil\break \fi + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{\hfil \ignorespaces#1\unskip \hfil}% + \ifhmode \break \fi +}} % @sp n outputs n lines of vertical space -\parseargdef\sp{\vskip #1\baselineskip} +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment @@ -937,7 +854,8 @@ where each line of input produces a line \def\asisword{asis} % no translation, these are keywords \def\noneword{none} % -\parseargdef\paragraphindent{% +\def\paragraphindent{\parsearg\doparagraphindent} +\def\doparagraphindent#1{% \def\temp{#1}% \ifx\temp\asisword \else @@ -954,7 +872,8 @@ where each line of input produces a line % We'll use ems for NCHARS like @paragraphindent. % It seems @exampleindent asis isn't necessary, but % I preserve it to make it similar to @paragraphindent. -\parseargdef\exampleindent{% +\def\exampleindent{\parsearg\doexampleindent} +\def\doexampleindent#1{% \def\temp{#1}% \ifx\temp\asisword \else @@ -968,18 +887,21 @@ where each line of input produces a line % @firstparagraphindent WORD % If WORD is `none', then suppress indentation of the first paragraph -% after a section heading. If WORD is `insert', then do indent at such +% after a section heading. If WORD is `insert', then do indentat such % paragraphs. % % The paragraph indentation is suppressed or not by calling -% \suppressfirstparagraphindent, which the sectioning commands do. -% We switch the definition of this back and forth according to WORD. -% By default, we suppress indentation. +% \suppressfirstparagraphindent, which the sectioning commands do. We +% switch the definition of this back and forth according to WORD. By +% default, we suppress indentation. % \def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\newdimen\currentparindent +% \def\insertword{insert} % -\parseargdef\firstparagraphindent{% +\def\firstparagraphindent{\parsearg\dofirstparagraphindent} +\def\dofirstparagraphindent#1{% \def\temp{#1}% \ifx\temp\noneword \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent @@ -999,24 +921,15 @@ where each line of input produces a line % \gdef\dosuppressfirstparagraphindent{% \gdef\indent{% - \restorefirstparagraphindent - \indent - }% - \gdef\noindent{% - \restorefirstparagraphindent - \noindent + \global\let\indent=\ptexindent + \global\everypar = {}% }% \global\everypar = {% - \kern -\parindent - \restorefirstparagraphindent + \kern-\parindent + \global\let\indent=\ptexindent + \global\everypar = {}% }% -} - -\gdef\restorefirstparagraphindent{% - \global \let \indent = \ptexindent - \global \let \noindent = \ptexnoindent - \global \everypar = {}% -} +}% % @asis just yields its argument. Used with @table, for example. @@ -1024,18 +937,23 @@ where each line of input produces a line \def\asis#1{#1} % @math outputs its argument in math mode. +% We don't use $'s directly in the definition of \math because we need +% to set catcodes according to plain TeX first, to allow for subscripts, +% superscripts, special math chars, etc. +% +\let\implicitmath = $%$ font-lock fix % % One complication: _ usually means subscripts, but it could also mean % an actual _ character, as in @math{@var{some_variable} + 1}. So make -% _ active, and distinguish by seeing if the current family is \slfam, -% which is what @var uses. -{ - \catcode\underChar = \active - \gdef\mathunderscore{% - \catcode\underChar=\active - \def_{\ifnum\fam=\slfam \_\else\sb\fi}% - } -} +% _ within @math be active (mathcode "8000), and distinguish by seeing +% if the current family is \slfam, which is what @var uses. +% +{\catcode\underChar = \active +\gdef\mathunderscore{% + \catcode\underChar=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% +}} +% % Another complication: we want \\ (and @\) to output a \ character. % FYI, plain.tex uses \\ as a temporary control sequence (why?), but % this is not advertised and we don't care. Texinfo does not @@ -1046,16 +964,15 @@ where each line of input produces a line % \def\math{% \tex - \mathunderscore + \mathcode`\_="8000 \mathunderscore \let\\ = \mathbackslash \mathactive - $\finishmath -} -\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + \implicitmath\finishmath} +\def\finishmath#1{#1\implicitmath\Etex} % Some active characters (such as <) are spaced differently in math. -% We have to reset their definitions in case the @math was an argument -% to a command which sets the catcodes (such as @item or @section). +% We have to reset their definitions in case the @math was an +% argument to a command which set the catcodes (such as @item or @section). % { \catcode`^ = \active @@ -1071,33 +988,8 @@ where each line of input produces a line } % @bullet and @minus need the same treatment as @math, just above. -\def\bullet{$\ptexbullet$} -\def\minus{$-$} - -% @dots{} outputs an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in a typewriter -% font as three actual period characters. -% -\def\dots{% - \leavevmode - \hbox to 1.5em{% - \hskip 0pt plus 0.25fil - .\hfil.\hfil.% - \hskip 0pt plus 0.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \dots - \spacefactor=3000 -} - -% @comma{} is so commas can be inserted into text without messing up -% Texinfo's parsing. -% -\let\comma = , +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} % @refill is a no-op. \let\refill=\relax @@ -1113,20 +1005,20 @@ where each line of input produces a line % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% - \fixbackslash % Turn off hack to swallow `\input texinfo'. \iflinks - \tryauxfile - % Open the new aux file. TeX will close it automatically at exit. - \immediate\openout\auxfile=\jobname.aux + \readauxfile \fi % \openindices needs to do some work in any case. \openindices - \let\setfilename=\comment % Ignore extra @setfilename cmds. + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. + % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf - \ifeof 1 \else \input texinfo.cnf \fi - \closein 1 + \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi + \closein1 + \temp % \comment % Ignore the actual filename. } @@ -1162,23 +1054,17 @@ where each line of input produces a line \newif\ifpdf \newif\ifpdfmakepagedest -% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 -% can be set). So we test for \relax and 0 as well as \undefined, -% borrowed from ifpdf.sty. \ifx\pdfoutput\undefined + \pdffalse + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\linkcolor = \relax + \let\pdfmakeoutlines = \relax \else - \ifx\pdfoutput\relax - \else - \ifcase\pdfoutput - \else - \pdftrue - \fi - \fi -\fi -% -\ifpdf + \pdftrue + \pdfoutput = 1 \input pdfcolor - \pdfcatalog{/PageMode /UseOutlines}% \def\dopdfimage#1#2#3{% \def\imagewidth{#2}% \def\imageheight{#3}% @@ -1199,13 +1085,7 @@ where each line of input produces a line \ifnum\pdftexversion < 14 \else \pdfrefximage \pdflastximage \fi} - \def\pdfmkdest#1{{% - % We have to set dummies so commands such as @code in a section title - % aren't expanded. - \atdummies - \normalturnoffactive - \pdfdest name{#1} xyz% - }} + \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} \def\pdfmkpgn#1{#1} \let\linkcolor = \Blue % was Cyan, but that seems light? \def\endlink{\Black\pdfendlink} @@ -1214,94 +1094,48 @@ where each line of input produces a line \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \else \csname#1\endcsname \fi} \def\advancenumber#1{\tempnum=\expnumber{#1}\relax - \advance\tempnum by 1 + \advance\tempnum by1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} - % - % #1 is the section text. #2 is the pdf expression for the number - % of subentries (or empty, for subsubsections). #3 is the node - % text, which might be empty if this toc entry had no - % corresponding node. #4 is the page number. - % - \def\dopdfoutline#1#2#3#4{% - % Generate a link to the node text if that exists; else, use the - % page number. We could generate a destination for the section - % text in the case where a section has no node, but it doesn't - % seem worthwhile, since most documents are normally structured. - \def\pdfoutlinedest{#3}% - \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi - % - \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}% - } - % - \def\pdfmakeoutlines{% - \begingroup + \def\pdfmakeoutlines{{% + \openin 1 \jobname.toc + \ifeof 1\else\begingroup + \closein 1 % Thanh's hack / proper braces in bookmarks \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace % - % Read toc silently, to get counts of subentries for \pdfoutline. - \def\numchapentry##1##2##3##4{% - \def\thischapnum{##2}% - \let\thissecnum\empty - \let\thissubsecnum\empty - }% - \def\numsecentry##1##2##3##4{% - \advancenumber{chap\thischapnum}% - \def\thissecnum{##2}% - \let\thissubsecnum\empty - }% - \def\numsubsecentry##1##2##3##4{% - \advancenumber{sec\thissecnum}% - \def\thissubsecnum{##2}% - }% - \def\numsubsubsecentry##1##2##3##4{% - \advancenumber{subsec\thissubsecnum}% - }% - \let\thischapnum\empty - \let\thissecnum\empty - \let\thissubsecnum\empty - % - % use \def rather than \let here because we redefine \chapentry et - % al. a second time, below. - \def\appentry{\numchapentry}% - \def\appsecentry{\numsecentry}% - \def\appsubsecentry{\numsubsecentry}% - \def\appsubsubsecentry{\numsubsubsecentry}% - \def\unnchapentry{\numchapentry}% - \def\unnsecentry{\numsecentry}% - \def\unnsubsecentry{\numsubsecentry}% - \def\unnsubsubsecentry{\numsubsubsecentry}% + \def\chapentry ##1##2##3{} + \def\secentry ##1##2##3##4{\advancenumber{chap##2}} + \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} + \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} + \let\appendixentry = \chapentry + \let\unnumbchapentry = \chapentry + \let\unnumbsecentry = \secentry + \let\unnumbsubsecentry = \subsecentry + \let\unnumbsubsubsecentry = \subsubsecentry \input \jobname.toc + \def\chapentry ##1##2##3{% + \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} + \def\secentry ##1##2##3##4{% + \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} + \def\subsecentry ##1##2##3##4##5{% + \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} + \def\subsubsecentry ##1##2##3##4##5##6{% + \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} + \let\appendixentry = \chapentry + \let\unnumbchapentry = \chapentry + \let\unnumbsecentry = \secentry + \let\unnumbsubsecentry = \subsecentry + \let\unnumbsubsubsecentry = \subsubsecentry % - % Read toc second time, this time actually producing the outlines. - % The `-' means take the \expnumber as the absolute number of - % subentries, which we calculated on our first read of the .toc above. - % - % We use the node names as the destinations. - \def\numchapentry##1##2##3##4{% - \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% - \def\numsecentry##1##2##3##4{% - \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% - \def\numsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% - \def\numsubsubsecentry##1##2##3##4{% count is always zero - \dopdfoutline{##1}{}{##3}{##4}}% - % - % PDF outlines are displayed using system fonts, instead of - % document fonts. Therefore we cannot use special characters, - % since the encoding is unknown. For example, the eogonek from - % Latin 2 (0xea) gets translated to a | character. Info from - % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % Make special characters normal for writing to the pdf file. % - % xx to do this right, we have to translate 8-bit characters to - % their "best" equivalent, based on the @documentencoding. Right - % now, I guess we'll just let the pdf reader have its way. \indexnofonts + \let\tt=\relax \turnoffactive \input \jobname.toc - \endgroup - } - % + \endgroup\fi + }} \def\makelinks #1,{% \def\params{#1}\def\E{END}% \ifx\params\E @@ -1332,6 +1166,7 @@ where each line of input produces a line \def\ppn#1{\pgn=#1\gobble} \def\ppnn{\pgn=\first} \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces @@ -1349,17 +1184,18 @@ where each line of input produces a line \def\pdfurl#1{% \begingroup \normalturnoffactive\def\@{@}% - \makevalueexpandable + \let\value=\expandablevalue \leavevmode\Red \startlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + % #1 \endgroup} \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} \def\maketoks{% - \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \expandafter\poptoks\the\toksA|ENDTOKS| \ifx\first0\adn0 \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 @@ -1379,44 +1215,20 @@ where each line of input produces a line \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} \linkcolor #1\endlink} \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} -\else - \let\pdfmkdest = \gobble - \let\pdfurl = \gobble - \let\endlink = \relax - \let\linkcolor = \relax - \let\pdfmakeoutlines = \relax -\fi % \ifx\pdfoutput +\fi % \ifx\pdfoutput \message{fonts,} - -% Change the current font style to #1, remembering it in \curfontstyle. -% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in -% italics, not bold italics. -% -\def\setfontstyle#1{% - \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. - \csname ten#1\endcsname % change the current font -} - -% Select #1 fonts with the current style. -% -\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} - -\def\rm{\fam=0 \setfontstyle{rm}} -\def\it{\fam=\itfam \setfontstyle{it}} -\def\sl{\fam=\slfam \setfontstyle{sl}} -\def\bf{\fam=\bffam \setfontstyle{bf}} -\def\tt{\fam=\ttfam \setfontstyle{tt}} +% Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. -% So we set up a \sf. +% So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam -\def\sf{\fam=\sffam \setfontstyle{sf}} +\def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. -% We don't need math for this font style. -\def\ttsl{\setfontstyle{ttsl}} +% We don't need math for this one. +\def\ttsl{\tenttsl} % Default leading. \newdimen\textleading \textleading = 13.2pt @@ -1467,7 +1279,6 @@ where each line of input produces a line \def\scshape{csc} \def\scbshape{csc} -% Text fonts (11.2pt, magstep1). \newcount\mainmagstep \ifx\bigger\relax % not really supported. @@ -1479,6 +1290,10 @@ where each line of input produces a line \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi +% Instead of cmb10, you may want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10 +% (in Bob's opinion). \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} @@ -1488,11 +1303,10 @@ where each line of input produces a line \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep -% A few fonts for @defun names and args. -\setfont\defbf\bfshape{10}{\magstep1} +% A few fonts for @defun, etc. +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} -\setfont\defttsl\ttslshape{10}{\magstep1} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices, footnotes, small examples (9pt). \setfont\smallrm\rmshape{9}{1000} @@ -1518,7 +1332,7 @@ where each line of input produces a line \font\smalleri=cmmi8 \font\smallersy=cmsy8 -% Fonts for title page (20.4pt): +% Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} @@ -1564,21 +1378,11 @@ where each line of input produces a line \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm -\setfont\ssecsc\scbshape{10}{1315} +\setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 - -% Reduced fonts for @acro in text (10pt). -\setfont\reducedrm\rmshape{10}{1000} -\setfont\reducedtt\ttshape{10}{1000} -\setfont\reducedbf\bfshape{10}{1000} -\setfont\reducedit\itshape{10}{1000} -\setfont\reducedsl\slshape{10}{1000} -\setfont\reducedsf\sfshape{10}{1000} -\setfont\reducedsc\scshape{10}{1000} -\setfont\reducedttsl\ttslshape{10}{1000} -\font\reducedi=cmmi10 -\font\reducedsy=cmsy10 +% The smallcaps and symbol fonts should actually be scaled \magstep1.5, +% but that is not a standard magnification. % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since @@ -1593,72 +1397,50 @@ where each line of input produces a line } % The font-changing commands redefine the meanings of \tenSTYLE, instead -% of just \STYLE. We do this because \STYLE needs to also set the -% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire -% \tenSTYLE to set the current font. -% -% Each font-changing command also sets the names \lsize (one size lower) -% and \lllsize (three sizes lower). These relative commands are used in -% the LaTeX logo and acronyms. -% -% This all needs generalizing, badly. -% +% of just \STYLE. We do this so that font changes will continue to work +% in math mode, where it is the current \fam that is relevant in most +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc - \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy - \let\tenttsl=\textttsl - \def\lsize{reduced}\def\lllsize{smaller}% + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts \setleading{\textleading}} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl - \def\lsize{chap}\def\lllsize{subsec}% \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl - \def\lsize{sec}\def\lllsize{text}% \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc - \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy - \let\tenttsl=\secttsl - \def\lsize{subsec}\def\lllsize{reduced}% + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc - \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy - \let\tenttsl=\ssecttsl - \def\lsize{text}\def\lllsize{small}% + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts \setleading{15pt}} -\let\subsubsecfonts = \subsecfonts -\def\reducedfonts{% - \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl - \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc - \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy - \let\tenttsl=\reducedttsl - \def\lsize{small}\def\lllsize{smaller}% - \resetmathfonts \setleading{10.5pt}} +\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \def\smallfonts{% \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy \let\tenttsl=\smallttsl - \def\lsize{smaller}\def\lllsize{smaller}% \resetmathfonts \setleading{10.5pt}} \def\smallerfonts{% \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy \let\tenttsl=\smallerttsl - \def\lsize{smaller}\def\lllsize{smaller}% \resetmathfonts \setleading{9.5pt}} % Set the fonts to use with the @small... environments. @@ -1667,7 +1449,7 @@ where each line of input produces a line % About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample % can fit this many characters: % 8.5x11=86 smallbook=72 a4=90 a5=69 -% If we use \scriptfonts (8pt), then we can fit this many characters: +% If we use \smallerfonts (8pt), then we can fit this many characters: % 8.5x11=90+ smallbook=80 a4=90+ a5=77 % For me, subjectively, the few extra characters that fit aren't worth % the additional smallness of 8pt. So I'm making the default 9pt. @@ -1675,13 +1457,14 @@ where each line of input produces a line % By the way, for comparison, here's what fits with @example (10pt): % 8.5x11=71 smallbook=60 a4=75 a5=58 % -% I wish the USA used A4 paper. +% I wish we used A4 paper on this side of the Atlantic. +% % --karl, 24jan03. % Set up the default fonts, so we can use them for creating boxes. % -\textfonts \rm +\textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} @@ -1692,7 +1475,7 @@ where each line of input produces a line % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} -\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12 +\setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} \setfont\shortconttt\ttshape{12}{1000} @@ -1706,19 +1489,11 @@ where each line of input produces a line \def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} -% like \smartslanted except unconditionally uses \ttsl. -% @var is set to this for defun arguments. -\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx} - -% like \smartslanted except unconditionally use \sl. We never want -% ttsl for book titles, do we? -\def\cite#1{{\sl #1}\futurelet\next\smartitalicx} - \let\i=\smartitalic -\let\slanted=\smartslanted \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic +\let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b @@ -1745,6 +1520,7 @@ where each line of input produces a line {\tt \rawbackslash \frenchspacing #1}% \null } +\let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\keyrm\rmshape{8}{1000} \font\keysy=cmsy9 @@ -1785,7 +1561,7 @@ where each line of input produces a line \null } -% We *must* turn on hyphenation at `-' and `_' in @code. +% We *must* turn on hyphenation at `-' and `_' in \code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. @@ -1803,6 +1579,10 @@ where each line of input produces a line \catcode`\_=\active \let_\codeunder \codex } + % + % If we end up with any active - characters when handling the index, + % just treat them as a normal -. + \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} @@ -1826,7 +1606,8 @@ where each line of input produces a line % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). -\parseargdef\kbdinputstyle{% +\def\kbdinputstyle{\parsearg\kbdinputstylexxx} +\def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% @@ -1852,8 +1633,8 @@ where each line of input produces a line \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} -% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. -\let\indicateurl=\code +% For @url, @env, @command quotes seem unnecessary, so use \code. +\let\url=\code \let\env=\code \let\command=\code @@ -1885,10 +1666,6 @@ where each line of input produces a line \endlink \endgroup} -% @url synonym for @uref, since that's how everyone uses it. -% -\let\url=\uref - % rms does not like angle brackets --karl, 17may97. % So now @email is just like @uref, unless we are pdf. % @@ -1930,53 +1707,22 @@ where each line of input produces a line \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font -% @acronym for "FBI", "NATO", and the like. -% We print this one point size smaller, since it's intended for -% all-uppercase. -% -\def\acronym#1{\doacronym #1,,\finish} -\def\doacronym#1,#2,#3\finish{% - {\selectfonts\lsize #1}% - \def\temp{#2}% - \ifx\temp\empty \else - \space ({\unsepspaces \ignorespaces \temp \unskip})% - \fi -} - -% @abbr for "Comput. J." and the like. -% No font change, but don't do end-of-sentence spacing. -% -\def\abbr#1{\doabbr #1,,\finish} -\def\doabbr#1,#2,#3\finish{% - {\frenchspacing #1}% - \def\temp{#2}% - \ifx\temp\empty \else - \space ({\unsepspaces \ignorespaces \temp \unskip})% - \fi -} +% @acronym downcases the argument and prints in smallcaps. +\def\acronym#1{{\smallcaps \lowercase{#1}}} -% @pounds{} is a sterling sign, which Knuth put in the CM italic font. -% +% @pounds{} is a sterling sign. \def\pounds{{\it\$}} -% @registeredsymbol - R in a circle. The font for the R should really -% be smaller yet, but lllsize is the best we can do for now. +% @registeredsymbol - R in a circle. For now, only works in text size; +% we'd have to redo the font mechanism to change the \scriptstyle and +% \scriptscriptstyle font sizes to make it look right in headings. % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% - $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% - \hfil\crcr\Orb}}% + $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% }$% } -% Laurent Siebenmann reports \Orb undefined with: -% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 -% so we'll define it if necessary. -% -\ifx\Orb\undefined -\def\Orb{\mathhexbox20D} -\fi - \message{page headings,} @@ -1995,103 +1741,87 @@ where each line of input produces a line \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue -\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} -\envdef\titlepage{% - % Open one extra group, as we want to close it in the middle of \Etitlepage. - \begingroup - \parindent=0pt \textfonts - % Leave some space at the very top of the page. - \vglue\titlepagetopglue - % No rule at page bottom unless we print one at the top with @title. - \finishedtitlepagetrue - % - % Most title ``pages'' are actually two pages long, with space - % at the top of the second. We don't want the ragged left on the second. - \let\oldpage = \page - \def\page{% +\def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines + \let\tt=\authortt}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefonts\rm ##1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% \iffinishedtitlepage\else - \finishtitlepage + \finishtitlepage \fi + \oldpage \let\page = \oldpage - \page - \null - }% + \hbox{}}% +% \def\page{\oldpage \hbox{}} } \def\Etitlepage{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - % It is important to do the page break before ending the group, - % because the headline and footline are only empty inside the group. - % If we use the new definition of \page, we always get a blank page - % after the title page, which we certainly don't want. - \oldpage - \endgroup - % - % Need this before the \...aftertitlepage checks so that if they are - % in effect the toc pages will come out with page numbers. - \HEADINGSon - % - % If they want short, they certainly want long too. - \ifsetshortcontentsaftertitlepage - \shortcontents - \contents - \global\let\shortcontents = \relax - \global\let\contents = \relax - \fi - % - \ifsetcontentsaftertitlepage - \contents - \global\let\contents = \relax - \global\let\shortcontents = \relax - \fi + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi } \def\finishtitlepage{% - \vskip4pt \hrule height 2pt width \hsize - \vskip\titlepagebottomglue - \finishedtitlepagetrue -} - -%%% Macros to be used within @titlepage: - -\let\subtitlerm=\tenrm -\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} - -\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines - \let\tt=\authortt} - -\parseargdef\title{% - \checkenv\titlepage - \leftline{\titlefonts\rm #1} - % print a rule at the page bottom also. - \finishedtitlepagefalse - \vskip4pt \hrule height 4pt width \hsize \vskip4pt -} - -\parseargdef\subtitle{% - \checkenv\titlepage - {\subtitlefont \rightline{#1}}% -} - -% @author should come last, but may come many times. -% It can also be used inside @quotation. -% -\parseargdef\author{% - \def\temp{\quotation}% - \ifx\thisenv\temp - \def\quotationauthor{#1}% printed in \Equotation. - \else - \checkenv\titlepage - \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi - {\authorfont \leftline{#1}}% - \fi + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue } - %%% Set up page headings and footings. \let\thispage=\folio @@ -2101,7 +1831,7 @@ where each line of input produces a line \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages -% Now make TeX use those variables +% Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline @@ -2115,27 +1845,32 @@ where each line of input produces a line % @evenfooting @thisfile|| % @oddfooting ||@thisfile - \def\evenheading{\parsearg\evenheadingxxx} -\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} -\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} -\def\oddheading{\parsearg\oddheadingxxx} -\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} -\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} -\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% +\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% -\def\evenfooting{\parsearg\evenfootingxxx} -\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} -\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} -\def\oddfooting{\parsearg\oddfootingxxx} -\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} -\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume @@ -2144,8 +1879,9 @@ where each line of input produces a line \global\advance\vsize by -\baselineskip } -\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} - +\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} +% +}% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. @@ -2159,7 +1895,7 @@ where each line of input produces a line \def\headings #1 {\csname HEADINGS#1\endcsname} -\def\HEADINGSoff{% +\def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff @@ -2168,7 +1904,7 @@ where each line of input produces a line % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. -\def\HEADINGSdouble{% +\def\HEADINGSdouble{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} @@ -2180,7 +1916,7 @@ where each line of input produces a line % For single-sided printing, chapter title goes across top left of page, % page number on top right. -\def\HEADINGSsingle{% +\def\HEADINGSsingle{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} @@ -2227,11 +1963,12 @@ where each line of input produces a line % @settitle line... specifies the title of the document, for headings. % It generates no output of its own. \def\thistitle{\putwordNoTitle} -\def\settitle{\parsearg{\gdef\thistitle}} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} -% Tables -- @table, @ftable, @vtable, @item(x). +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in @@ -2243,7 +1980,7 @@ where each line of input produces a line % used internally for \itemindent minus \itemmargin \newdimen\itemmax -% Note @table, @ftable, and @vtable define @item, @itemx, etc., with +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). @@ -2255,10 +1992,22 @@ where each line of input produces a line \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent - \setbox0=\hbox{\itemindicate{#1}}% + \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % @@ -2282,13 +2031,17 @@ where each line of input produces a line % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % - % Stop a page break at the \parskip glue coming up. However, if - % what follows is an environment such as @example, there will be no - % \parskip glue; then the negative vskip we just inserted would - % cause the example and the item to crash together. So we use this - % bizarre value of 10001 as a signal to \aboveenvbreak to insert - % \parskip glue after all. Section titles are handled this way also. - % + % Stop a page break at the \parskip glue coming up. (Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue.) However, if what follows is an environment + % such as @example, there will be no \parskip glue; then + % the negative vskip we just would cause the example and the item to + % crash together. So we use this bizarre value of 10001 as a signal + % to \aboveenvbreak to insert \parskip glue after all. + % (Possibly there are other commands that could be followed by + % @example which need the same treatment, but not section titles; or + % maybe section titles are the only special case and they should be + % penalty 10001...) \penalty 10001 \endgroup \itemxneedsnegativevskipfalse @@ -2308,72 +2061,81 @@ where each line of input produces a line \fi } -\def\item{\errmessage{@item while not in a list environment}} -\def\itemx{\errmessage{@itemx while not in a list environment}} +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +% Contains a kludge to get @end[description] to work. +\def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. -\envdef\table{% - \let\itemindex\gobble - \tablecheck{table}% -} -\envdef\ftable{% - \def\itemindex ##1{\doind {fn}{\code{##1}}}% - \tablecheck{ftable}% -} -\envdef\vtable{% - \def\itemindex ##1{\doind {vr}{\code{##1}}}% - \tablecheck{vtable}% -} -\def\tablecheck#1{% - \ifnum \the\catcode`\^^M=\active - \endgroup - \errmessage{This command won't work in this context; perhaps the problem is - that we are \inenvironment\thisenv}% - \def\next{\doignore{#1}}% - \else - \let\next\tablex - \fi - \next -} -\def\tablex#1{% - \def\itemindicate{#1}% - \parsearg\tabley +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley +\def\Eftable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Necessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\exdentamount=\tableindent +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\afterenvbreak\endgroup}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % } -\def\tabley#1{% - {% - \makevalueexpandable - \edef\temp{\noexpand\tablez #1\space\space\space}% - \expandafter - }\temp \endtablez -} -\def\tablez #1 #2 #3 #4\endtablez{% - \aboveenvbreak - \ifnum 0#1>0 \advance \leftskip by #1\mil \fi - \ifnum 0#2>0 \tableindent=#2\mil \fi - \ifnum 0#3>0 \advance \rightskip by #3\mil \fi - \itemmax=\tableindent - \advance \itemmax by -\itemmargin - \advance \leftskip by \tableindent - \exdentamount=\tableindent - \parindent = 0pt - \parskip = \smallskipamount - \ifdim \parskip=0pt \parskip=2pt \fi - \let\item = \internalBitem - \let\itemx = \internalBitemx -} -\def\Etable{\endgraf\afterenvbreak} -\let\Eftable\Etable -\let\Evtable\Etable -\let\Eitemize\Etable -\let\Eenumerate\Etable % This is the counter used by @enumerate, which is really @itemize \newcount \itemno -\envdef\itemize{\parsearg\doitemize} +\def\itemize{\parsearg\itemizezzz} -\def\doitemize#1{% +\def\itemizezzz #1{% + \begingroup % ended by the @end itemize + \itemizey {#1}{\Eitemize} +} + +\def\itemizey#1#2{% \aboveenvbreak \itemmax=\itemindent \advance\itemmax by -\itemmargin @@ -2382,33 +2144,13 @@ where each line of input produces a line \parindent=0pt \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi + \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% % @itemize with no arg is equivalent to @itemize @bullet. \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi \let\item=\itemizeitem } -% Definition of @item while inside @itemize and @enumerate. -% -\def\itemizeitem{% - \advance\itemno by 1 % for enumerations - {\let\par=\endgraf \smallbreak}% reasonable place to break - {% - % If the document has an @itemize directly after a section title, a - % \nobreak will be last on the list, and \sectionheading will have - % done a \vskip-\parskip. In that case, we don't want to zero - % parskip, or the item text will crash with the heading. On the - % other hand, when there is normal text preceding the item (as there - % usually is), we do want to zero parskip, or there would be too much - % space. In that case, we won't have a \nobreak before. At least - % that's the theory. - \ifnum\lastpenalty<10000 \parskip=0in \fi - \noindent - \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% - \vadjust{\penalty 1200}}% not good to break after first line of item. - \flushcr -} - % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % @@ -2418,8 +2160,11 @@ where each line of input produces a line % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % -\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +\def\enumerate{\parsearg\enumeratezzz} +\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi @@ -2490,13 +2235,13 @@ where each line of input produces a line }% } -% Call \doitemize, adding a period to the first argument and supplying the +% Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 - \doitemize{#1.}\flushcr + \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg @@ -2507,6 +2252,16 @@ where each line of input produces a line \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{In hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 1200}}% +\flushcr} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 @@ -2533,14 +2288,24 @@ where each line of input produces a line % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. -% @item, @tab do not need to be on their own lines, but it will not hurt -% if they are. +% @item, @tab, @multitable or @end multitable do not need to be on their +% own lines, but it will not hurt if they are. % Sample multitable: @@ -2584,12 +2349,13 @@ where each line of input produces a line \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent -% #1 is the @columnfraction, usually a decimal number like .5, but might -% be just 1. We just use it, whatever it is. -% -\def\pickupwholefraction#1 {% +% #1 is the part of the @columnfraction before the decimal point, which +% is presumably either 0 or the empty string (but we don't check, we +% just throw it away). #2 is the decimal part, which we use as the +% percent of \hsize for this column. +\def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 - \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% \setuptable } @@ -2622,33 +2388,18 @@ where each line of input produces a line \go } -% multitable-only commands. -% -% @headitem starts a heading row, which we typeset in bold. -% Assignments have to be global since we are inside the implicit group -% of an alignment entry. Note that \everycr resets \everytab. -\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}% -% -% A \tab used to include \hskip1sp. But then the space in a template -% line is not enough. That is bad. So let's go back to just `&' until -% we encounter the problem it was intended to solve again. -% --karl, nathan@acm.org, 20apr99. -\def\tab{\checkenv\multitable &\the\everytab}% - % @multitable ... @end multitable definitions: % -\newtoks\everytab % insert after every tab. -% -\envdef\multitable{% +\def\multitable{\parsearg\dotable} +\def\dotable#1{\bgroup \vskip\parskip - \startsavinginserts - % - % @item within a multitable starts a normal row. - % We use \def instead of \let so that if one of the multitable entries - % contains an @itemize, we don't choke on the \item (seen as \crcr aka - % \endtemplate) expanding \doitemize. - \def\item{\crcr}% - % + \let\item=\crcrwithfootnotes + % A \tab used to include \hskip1sp. But then the space in a template + % line is not enough. That is bad. So let's go back to just & until + % we encounter the problem it was intended to solve again. --karl, + % nathan@acm.org, 20apr99. + \let\tab=&% + \let\startfootins=\startsavedfootnote \tolerance=9500 \hbadness=9500 \setmultitablespacing @@ -2656,93 +2407,85 @@ where each line of input produces a line \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 - % - \everycr = {% - \noalign{% - \global\everytab={}% - \global\colcount=0 % Reset the column counter. - % Check for saved footnotes, etc. - \checkinserts - % Keeps underfull box messages off when table breaks over pages. - %\filbreak - % Maybe so, but it also creates really weird page breaks when the - % table breaks over pages. Wouldn't \vfil be better? Wait until the - % problem manifests itself, so it can be fixed for real --karl. - }% + \def\Emultitable{% + \global\setpercentfalse + \crcrwithfootnotes\crcr + \egroup\egroup }% % - \parsearg\domultitable -} -\def\domultitable#1{% % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. + \everycr{\noalign{% + % + % \filbreak%% keeps underfull box messages off when table breaks over pages. + % Maybe so, but it also creates really weird page breaks when the table + % breaks over pages. Wouldn't \vfil be better? Wait until the problem + % manifests itself, so it can be fixed for real --karl. + \global\colcount=0\relax}}% + % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. - \halign\bgroup &% - \global\advance\colcount by 1 - \multistrut - \vtop{% - % Use the current \colcount to find the correct column width: - \hsize=\expandafter\csname col\the\colcount\endcsname - % - % In order to keep entries from bumping into each other - % we will add a \leftskip of \multitablecolspace to all columns after - % the first one. - % - % If a template has been used, we will add \multitablecolspace - % to the width of each template entry. - % - % If the user has set preamble in terms of percent of \hsize we will - % use that dimension as the width of the column, and the \leftskip - % will keep entries from bumping into each other. Table will start at - % left margin and final column will justify at right margin. - % - % Make sure we don't inherit \rightskip from the outer environment. - \rightskip=0pt - \ifnum\colcount=1 - % The first column will be indented with the surrounding text. - \advance\hsize by\leftskip - \else - \ifsetpercent \else - % If user has not set preamble in terms of percent of \hsize - % we will advance \hsize by \multitablecolspace. - \advance\hsize by \multitablecolspace - \fi - % In either case we will make \leftskip=\multitablecolspace: - \leftskip=\multitablecolspace - \fi - % Ignoring space at the beginning and end avoids an occasional spurious - % blank line, when TeX decides to break the line at the space before the - % box from the multistrut, so the strut ends up on a line by itself. - % For example: - % @multitable @columnfractions .11 .89 - % @item @code{#} - % @tab Legal holiday which is valid in major parts of the whole country. - % Is automatically provided with highlighting sequences respectively - % marking characters. - \noindent\ignorespaces##\unskip\multistrut - }\cr -} -\def\Emultitable{% - \crcr - \egroup % end the \halign - \global\setpercentfalse -} - -\def\setmultitablespacing{% - \def\multistrut{\strut}% just use the standard line spacing + \halign\bgroup&\global\advance\colcount by 1\relax + \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname % - % Compute \multitablelinespace (if not defined by user) for use in - % \multitableparskip calculation. We used define \multistrut based on - % this, but (ironically) that caused the spacing to be off. - % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. \ifdim\multitablelinespace=0pt \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 -\fi +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\let\multistrut = \strut +\else +%% FIXME: what is \box0 supposed to be? +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi %% Test to see if parskip is larger than space between lines of %% table. If not, do nothing. %% If so, set to same dimension as multitablelinespace. @@ -2757,33 +2500,163 @@ where each line of input produces a line %% than skip between lines in the table. \fi} +% In case a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is +% finished. Otherwise, the insertion is lost, it never migrates to the +% main vertical list. --kasal, 22jan03. +% +\newbox\savedfootnotes +% +% \dotable \let's \startfootins to this, so that \dofootnote will call +% it instead of starting the insertion right away. +\def\startsavedfootnote{% + \global\setbox\savedfootnotes = \vbox\bgroup + \unvbox\savedfootnotes +} +\def\crcrwithfootnotes{% + \crcr + \ifvoid\savedfootnotes \else + \noalign{\insert\footins{\box\savedfootnotes}}% + \fi +} \message{conditionals,} - -% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, -% @ifnotxml always succeed. They currently do nothing; we don't -% attempt to check whether the conditionals are properly nested. But we -% have to remember that they are conditionals, so that @end doesn't -% attempt to close an environment group. -% -\def\makecond#1{% - \expandafter\let\csname #1\endcsname = \relax - \expandafter\let\csname iscond.#1\endcsname = 1 -} -\makecond{iftex} -\makecond{ifnotdocbook} -\makecond{ifnothtml} -\makecond{ifnotinfo} -\makecond{ifnotplaintext} -\makecond{ifnotxml} +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% + \let\chapter=\relax + \let\unnumbered=\relax + \let\top=\relax + \let\unnumberedsec=\relax + \let\unnumberedsection=\relax + \let\unnumberedsubsec=\relax + \let\unnumberedsubsection=\relax + \let\unnumberedsubsubsec=\relax + \let\unnumberedsubsubsection=\relax + \let\section=\relax + \let\subsec=\relax + \let\subsubsec=\relax + \let\subsection=\relax + \let\subsubsection=\relax + \let\appendix=\relax + \let\appendixsec=\relax + \let\appendixsection=\relax + \let\appendixsubsec=\relax + \let\appendixsubsection=\relax + \let\appendixsubsubsec=\relax + \let\appendixsubsubsection=\relax + \let\contents=\relax + \let\smallbook=\relax + \let\titlepage=\relax +} + +% Used in nested conditionals, where we have to parse the Texinfo source +% and so want to turn off most commands, in case they are used +% incorrectly. +% +% We use \empty instead of \relax for the @def... commands, so that \end +% doesn't throw an error. For instance: +% @ignore +% @deffn ... +% @end deffn +% @end ignore +% +% The @end deffn is going to get expanded, because we're trying to allow +% nested conditionals. But we don't want to expand the actual @deffn, +% since it might be syntactically correct and intended to be ignored. +% Since \end checks for \relax, using \empty does not cause an error. +% +\def\ignoremorecommands{% + \let\defcodeindex = \relax + \let\defcv = \empty + \let\defcvx = \empty + \let\Edefcv = \empty + \let\deffn = \empty + \let\deffnx = \empty + \let\Edeffn = \empty + \let\defindex = \relax + \let\defivar = \empty + \let\defivarx = \empty + \let\Edefivar = \empty + \let\defmac = \empty + \let\defmacx = \empty + \let\Edefmac = \empty + \let\defmethod = \empty + \let\defmethodx = \empty + \let\Edefmethod = \empty + \let\defop = \empty + \let\defopx = \empty + \let\Edefop = \empty + \let\defopt = \empty + \let\defoptx = \empty + \let\Edefopt = \empty + \let\defspec = \empty + \let\defspecx = \empty + \let\Edefspec = \empty + \let\deftp = \empty + \let\deftpx = \empty + \let\Edeftp = \empty + \let\deftypefn = \empty + \let\deftypefnx = \empty + \let\Edeftypefn = \empty + \let\deftypefun = \empty + \let\deftypefunx = \empty + \let\Edeftypefun = \empty + \let\deftypeivar = \empty + \let\deftypeivarx = \empty + \let\Edeftypeivar = \empty + \let\deftypemethod = \empty + \let\deftypemethodx = \empty + \let\Edeftypemethod = \empty + \let\deftypeop = \empty + \let\deftypeopx = \empty + \let\Edeftypeop = \empty + \let\deftypevar = \empty + \let\deftypevarx = \empty + \let\Edeftypevar = \empty + \let\deftypevr = \empty + \let\deftypevrx = \empty + \let\Edeftypevr = \empty + \let\defun = \empty + \let\defunx = \empty + \let\Edefun = \empty + \let\defvar = \empty + \let\defvarx = \empty + \let\Edefvar = \empty + \let\defvr = \empty + \let\defvrx = \empty + \let\Edefvr = \empty + \let\clear = \relax + \let\down = \relax + \let\evenfooting = \relax + \let\evenheading = \relax + \let\everyfooting = \relax + \let\everyheading = \relax + \let\headings = \relax + \let\include = \relax + \let\item = \relax + \let\lowersections = \relax + \let\oddfooting = \relax + \let\oddheading = \relax + \let\printindex = \relax + \let\pxref = \relax + \let\raisesections = \relax + \let\ref = \relax + \let\set = \relax + \let\setchapternewpage = \relax + \let\setchapterstyle = \relax + \let\settitle = \relax + \let\up = \relax + \let\verbatiminclude = \relax + \let\xref = \relax +} % Ignore @ignore, @ifhtml, @ifinfo, and the like. % \def\direntry{\doignore{direntry}} +\def\documentdescriptionword{documentdescription} \def\documentdescription{\doignore{documentdescription}} -\def\docbook{\doignore{docbook}} \def\html{\doignore{html}} -\def\ifdocbook{\doignore{ifdocbook}} \def\ifhtml{\doignore{ifhtml}} \def\ifinfo{\doignore{ifinfo}} \def\ifnottex{\doignore{ifnottex}} @@ -2793,133 +2666,198 @@ where each line of input produces a line \def\menu{\doignore{menu}} \def\xml{\doignore{xml}} -% Ignore text until a line `@end #1', keeping track of nested conditionals. -% -% A count to remember the depth of nesting. -\newcount\doignorecount +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory = \comment +% Ignore text until a line `@end #1'. +% \def\doignore#1{\begingroup - % Scan in ``verbatim'' mode: - \catcode`\@ = \other - \catcode`\{ = \other - \catcode`\} = \other - % - % Make sure that spaces turn into tokens that match what \doignoretext wants. - \spaceisspace + % Don't complain about control sequences we have declared \outer. + \ignoresections % - % Count number of #1's that we've seen. - \doignorecount = 0 + % Define a command to swallow text until we reach `@end #1'. + % This @ is a catcode 12 token (that is the normal catcode of @ in + % this texinfo.tex file). We change the catcode of @ below to match. + \long\def\doignoretext##1@end #1{\enddoignore}% % - % Swallow text until we reach the matching `@end #1'. - \dodoignore{#1}% -} - -{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. - \obeylines % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode\spaceChar = 10 % - \gdef\dodoignore#1{% - % #1 contains the command name as a string, e.g., `ifinfo'. + % Ignore braces, too, so mismatched braces don't cause trouble. + \catcode`\{ = 9 + \catcode`\} = 9 + % + % We must not have @c interpreted as a control sequence. + \catcode`\@ = 12 + % + \def\ignoreword{#1}% + \ifx\ignoreword\documentdescriptionword + % The c kludge breaks documentdescription, since + % `documentdescription' contains a `c'. Means not everything will + % be ignored inside @documentdescription, but oh well... + \else + % Make the letter c a comment character so that the rest of the line + % will be ignored. This way, the document can have (for example) + % @c @end ifinfo + % and the @end ifinfo will be properly ignored. + % (We've just changed @ to catcode 12.) + \catcode`\c = 14 + \fi + % + % And now expand the command defined above. + \doignoretext +} + +% What we do to finish off ignored text. +% +\def\enddoignore{\endgroup\ignorespaces}% + +\newif\ifwarnedobs\warnedobsfalse +\def\obstexwarn{% + \ifwarnedobs\relax\else + % We need to warn folks that they may have trouble with TeX 3.0. + % This uses \immediate\write16 rather than \message to get newlines. + \immediate\write16{} + \immediate\write16{WARNING: for users of Unix TeX 3.0!} + \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} + \immediate\write16{If you are running another version of TeX, relax.} + \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} + \immediate\write16{ Then upgrade your TeX installation if you can.} + \immediate\write16{ (See ftp://ftp.gnu.org/non-gnu/TeX.README.)} + \immediate\write16{If you are stuck with version 3.0, run the} + \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} + \immediate\write16{ to use a workaround.} + \immediate\write16{} + \global\warnedobstrue + \fi +} + +% **In TeX 3.0, setting text in \nullfont hangs tex. For a +% workaround (which requires the file ``dummy.tfm'' to be installed), +% uncomment the following line: +%%%%%\font\nullfont=dummy\let\obstexwarn=\relax + +% Ignore text, except that we keep track of conditional commands for +% purposes of nesting, up to an `@end #1' command. +% +\def\nestedignore#1{% + \obstexwarn + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the chance of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because some sites + % might not have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + % + \nullfont + \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont + \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont + \let\tensf=\nullfont + % Similarly for index fonts. + \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont + \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont + \let\smallsf=\nullfont + % Similarly for smallexample fonts. + \let\smallerrm=\nullfont \let\smallerit=\nullfont \let\smallersl=\nullfont + \let\smallerbf=\nullfont \let\smallertt=\nullfont \let\smallersc=\nullfont + \let\smallersf=\nullfont % - % Define a command to find the next `@end #1', which must be on a line - % by itself. - \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}% - % And this command to find another #1 command, at the beginning of a - % line. (Otherwise, we would consider a line `@c @ifset', for - % example, to count as an @ifset for nesting.) - \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% - % - % And now expand that command. - \obeylines % - \doignoretext ^^M% - }% -} - -\def\doignoreyyy#1{% - \def\temp{#1}% - \ifx\temp\empty % Nothing found. - \let\next\doignoretextzzz - \else % Found a nested condition, ... - \advance\doignorecount by 1 - \let\next\doignoretextyyy % ..., look for another. - % If we're here, #1 ends with ^^M\ifinfo (for example). - \fi - \next #1% the token \_STOP_ is present just after this macro. -} - -% We have to swallow the remaining "\_STOP_". -% -\def\doignoretextzzz#1{% - \ifnum\doignorecount = 0 % We have just found the outermost @end. - \let\next\enddoignore - \else % Still inside a nested condition. - \advance\doignorecount by -1 - \let\next\doignoretext % Look for the next @end. - \fi - \next + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 + % + % Do not execute instructions in @tex. + \def\tex{\doignore{tex}}% + % Do not execute macro definitions. + % `c' is a comment character, so the word `macro' will get cut off. + \def\macro{\doignore{ma}}% } -% Finish off ignored text. -\def\enddoignore{\endgroup\ignorespaces} - - % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we -% didn't need it. -% We rely on the fact that \parsearg sets \catcode`\ =10. +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. % -\parseargdef\set{\setyyy#1 \endsetyyy} +\def\set{\begingroup\catcode` =10 + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \parsearg\setxxx} +\def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% - {% - \makevalueexpandable - \def\temp{#2}% - \edef\next{\gdef\makecsname{SET#1}}% - \ifx\temp\empty - \next{}% - \else - \setzzz#2\endsetzzz - \fi - }% + \def\temp{#2}% + \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi + \endgroup } -% Remove the trailing space \setxxx inserted. -\def\setzzz#1 \endsetzzz{\next{#1}} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % -\parseargdef\clear{% - {% - \makevalueexpandable - \global\expandafter\let\csname SET#1\endcsname=\relax - }% -} +\def\clear{\parsearg\clearxxx} +\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. -\def\value{\begingroup\makevalueexpandable\valuexxx} -\def\valuexxx#1{\expandablevalue{#1}\endgroup} { - \catcode`\- = \active \catcode`\_ = \active + \catcode`\_ = \active % - \gdef\makevalueexpandable{% - \let\value = \expandablevalue - % We don't want these characters active, ... + % We might end up with active _ or - characters in the argument if + % we're called from @code, as @code{@value{foo-bar_}}. So \let any + % such active characters to their normal equivalents. + \gdef\value{\begingroup \catcode`\-=\other \catcode`\_=\other - % ..., but we might end up with active ones in the argument if - % we're called from @code, as @code{@value{foo-bar_}}, though. - % So \let them to their normal equivalents. - \let-\realdash \let_\normalunderscore - } + \indexbreaks \let_\normalunderscore + \valuexxx} } +\def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's -% properly in indexes (we call \makevalueexpandable in \indexdummies). -% The command has to be fully expandable (if the variable is set), since -% the result winds up in the index file. This means that if the -% variable's value contains other Texinfo commands, it's almost certain -% it will fail (although perhaps we could fix that with sufficient work -% to do a one-level expansion on the result, instead of complete). +% properly in indexes (we \let\value to this in \indexdummies). Ones +% whose names contain - or _ still won't work, but we can't do anything +% about that. The command has to be fully expandable (if the variable +% is set), since the result winds up in the index file. This means that +% if the variable's value contains other Texinfo commands, it's almost +% certain it will fail (although perhaps we could fix that with +% sufficient work to do a one-level expansion on the result, instead of +% complete). % \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax @@ -2933,36 +2871,55 @@ where each line of input produces a line % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % -% To get special treatment of `@end ifset,' call \makeond and the redefine. -% -\makecond{ifset} -\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} -\def\doifset#1#2{% - {% - \makevalueexpandable - \let\next=\empty - \expandafter\ifx\csname SET#2\endcsname\relax - #1% If not set, redefine \next. - \fi - \expandafter - }\next +\def\ifset{\parsearg\doifset} +\def\doifset#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \let\next=\ifsetfail + \else + \let\next=\ifsetsucceed + \fi + \next } -\def\ifsetfail{\doignore{ifset}} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\nestedignore{ifset}} +\defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % -% The `\else' inside the `\doifset' parameter is a trick to reuse the -% above code: if the variable is not set, do nothing, if it is set, -% then redefine \next to \ifclearfail. -% -\makecond{ifclear} -\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} -\def\ifclearfail{\doignore{ifclear}} - -% @dircategory CATEGORY -- specify a category of the dir file -% which this file should belong to. Ignore this in TeX. -\let\dircategory=\comment +\def\ifclear{\parsearg\doifclear} +\def\doifclear#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \let\next=\ifclearsucceed + \else + \let\next=\ifclearfail + \fi + \next +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\nestedignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we +% read the text following, through the first @end iftex (etc.). Make +% `@end iftex' (etc.) valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\def\ifnothtml{\conditionalsucceed{ifnothtml}} +\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} +\def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} +\defineunmatchedend{iftex} +\defineunmatchedend{ifnothtml} +\defineunmatchedend{ifnotinfo} +\defineunmatchedend{ifnotplaintext} + +% True conditional. Since \set globally defines its variables, we can +% just start and end a group (to keep the @end definition undefined at +% the outer level). +% +\def\conditionalsucceed#1{\begingroup + \expandafter\def\csname E#1\endcsname{\endgroup}% +} % @defininfoenclose. \let\definfoenclose=\comment @@ -3087,7 +3044,6 @@ where each line of input produces a line \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% }% - \let\definedummyaccent\definedummyletter % % Do the redefinitions. \commondummies @@ -3110,7 +3066,6 @@ where each line of input produces a line \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{@##1}% }% - \let\definedummyaccent\definedummyletter % % Do the redefinitions. \commondummies @@ -3123,11 +3078,26 @@ where each line of input produces a line % \normalturnoffactive % - \commondummiesnofonts - % + % Control letters and accents. \definedummyletter{_}% + \definedummyletter{,}% + \definedummyletter{"}% + \definedummyletter{`}% + \definedummyletter{'}% + \definedummyletter{^}% + \definedummyletter{~}% + \definedummyletter{=}% + \definedummyword{u}% + \definedummyword{v}% + \definedummyword{H}% + \definedummyword{dotaccent}% + \definedummyword{ringaccent}% + \definedummyword{tieaccent}% + \definedummyword{ubaraccent}% + \definedummyword{udotaccent}% + \definedummyword{dotless}% % - % Non-English letters. + % Other non-English letters. \definedummyword{AA}% \definedummyword{AE}% \definedummyword{L}% @@ -3139,10 +3109,6 @@ where each line of input produces a line \definedummyword{oe}% \definedummyword{o}% \definedummyword{ss}% - \definedummyword{exclamdown}% - \definedummyword{questiondown}% - \definedummyword{ordf}% - \definedummyword{ordm}% % % Although these internal commands shouldn't show up, sometimes they do. \definedummyword{bf}% @@ -3154,14 +3120,37 @@ where each line of input produces a line \definedummyword{tclose}% \definedummyword{tt}% % - \definedummyword{LaTeX}% + % Texinfo font commands. + \definedummyword{b}% + \definedummyword{i}% + \definedummyword{r}% + \definedummyword{sc}% + \definedummyword{t}% + % \definedummyword{TeX}% + \definedummyword{acronym}% + \definedummyword{cite}% + \definedummyword{code}% + \definedummyword{command}% + \definedummyword{dfn}% + \definedummyword{dots}% + \definedummyword{emph}% + \definedummyword{env}% + \definedummyword{file}% + \definedummyword{kbd}% + \definedummyword{key}% + \definedummyword{math}% + \definedummyword{option}% + \definedummyword{samp}% + \definedummyword{strong}% + \definedummyword{uref}% + \definedummyword{url}% + \definedummyword{var}% + \definedummyword{w}% % % Assorted special characters. \definedummyword{bullet}% - \definedummyword{comma}% \definedummyword{copyright}% - \definedummyword{registeredsymbol}% \definedummyword{dots}% \definedummyword{enddots}% \definedummyword{equiv}% @@ -3173,9 +3162,10 @@ where each line of input produces a line \definedummyword{print}% \definedummyword{result}% % - % Handle some cases of @value -- where it does not contain any + % Handle some cases of @value -- where the variable name does not + % contain - or _, and the value does not contain any % (non-fully-expandable) commands. - \makevalueexpandable + \let\value = \expandablevalue % % Normal spaces, not active ones. \unsepspaces @@ -3184,97 +3174,45 @@ where each line of input produces a line \turnoffmacros } -% \commondummiesnofonts: common to \commondummies and \indexnofonts. -% -% Better have this without active chars. -{ - \catcode`\~=\other - \gdef\commondummiesnofonts{% - % Control letters and accents. - \definedummyletter{!}% - \definedummyaccent{"}% - \definedummyaccent{'}% - \definedummyletter{*}% - \definedummyaccent{,}% - \definedummyletter{.}% - \definedummyletter{/}% - \definedummyletter{:}% - \definedummyaccent{=}% - \definedummyletter{?}% - \definedummyaccent{^}% - \definedummyaccent{`}% - \definedummyaccent{~}% - \definedummyword{u}% - \definedummyword{v}% - \definedummyword{H}% - \definedummyword{dotaccent}% - \definedummyword{ringaccent}% - \definedummyword{tieaccent}% - \definedummyword{ubaraccent}% - \definedummyword{udotaccent}% - \definedummyword{dotless}% - % - % Texinfo font commands. - \definedummyword{b}% - \definedummyword{i}% - \definedummyword{r}% - \definedummyword{sc}% - \definedummyword{t}% - % - % Commands that take arguments. - \definedummyword{acronym}% - \definedummyword{cite}% - \definedummyword{code}% - \definedummyword{command}% - \definedummyword{dfn}% - \definedummyword{emph}% - \definedummyword{env}% - \definedummyword{file}% - \definedummyword{kbd}% - \definedummyword{key}% - \definedummyword{math}% - \definedummyword{option}% - \definedummyword{samp}% - \definedummyword{strong}% - \definedummyword{tie}% - \definedummyword{uref}% - \definedummyword{url}% - \definedummyword{var}% - \definedummyword{verb}% - \definedummyword{w}% - } -} +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + % \indexnofonts is used when outputting the strings to sort the index % by, and when constructing control sequence names. It eliminates all % control sequences and just writes whatever the best ASCII sort string % would be for a given command (usually its argument). % +\def\indexdummytex{TeX} +\def\indexdummydots{...} +% \def\indexnofonts{% - % Accent commands should become @asis. - \def\definedummyaccent##1{% - \expandafter\let\csname ##1\endcsname\asis - }% - % We can just ignore other control letters. - \def\definedummyletter##1{% - \expandafter\def\csname ##1\endcsname{}% - }% - % Hopefully, all control words can become @asis. - \let\definedummyword\definedummyaccent - % - \commondummiesnofonts - % - % Don't no-op \tt, since it isn't a user-level command - % and is used in the definitions of the active chars like <, >, |, etc. - % Likewise with the other plain tex font commands. - %\let\tt=\asis - % \def\ { }% \def\@{@}% % how to handle braces? \def\_{\normalunderscore}% % - % Non-English letters. + \let\,=\asis + \let\"=\asis + \let\`=\asis + \let\'=\asis + \let\^=\asis + \let\~=\asis + \let\==\asis + \let\u=\asis + \let\v=\asis + \let\H=\asis + \let\dotaccent=\asis + \let\ringaccent=\asis + \let\tieaccent=\asis + \let\ubaraccent=\asis + \let\udotaccent=\asis + \let\dotless=\asis + % + % Other non-English letters. \def\AA{AA}% \def\AE{AE}% \def\L{L}% @@ -3288,169 +3226,130 @@ where each line of input produces a line \def\ss{ss}% \def\exclamdown{!}% \def\questiondown{?}% - \def\ordf{a}% - \def\ordm{o}% - % - \def\LaTeX{LaTeX}% - \def\TeX{TeX}% % - % Assorted special characters. - % (The following {} will end up in the sort string, but that's ok.) - \def\bullet{bullet}% - \def\comma{,}% - \def\copyright{copyright}% - \def\registeredsymbol{R}% - \def\dots{...}% - \def\enddots{...}% - \def\equiv{==}% - \def\error{error}% - \def\expansion{==>}% - \def\minus{-}% - \def\pounds{pounds}% - \def\point{.}% - \def\print{-|}% - \def\result{=>}% + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis % - % Don't write macro names. - \emptyusermacros + % Texinfo font commands. + \let\b=\asis + \let\i=\asis + \let\r=\asis + \let\sc=\asis + \let\t=\asis + % + \let\TeX=\indexdummytex + \let\acronym=\asis + \let\cite=\asis + \let\code=\asis + \let\command=\asis + \let\dfn=\asis + \let\dots=\indexdummydots + \let\emph=\asis + \let\env=\asis + \let\file=\asis + \let\kbd=\asis + \let\key=\asis + \let\math=\asis + \let\option=\asis + \let\samp=\asis + \let\strong=\asis + \let\uref=\asis + \let\url=\asis + \let\var=\asis + \let\w=\asis } \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? +% For \ifx comparisons. +\def\emptymacro{\empty} + % Most index entries go through here, but \dosubind is the general case. -% #1 is the index name, #2 is the entry text. -\def\doind#1#2{\dosubind{#1}{#2}{}} +% +\def\doind#1#2{\dosubind{#1}{#2}\empty} % Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- -% empty if called from \doind, as we usually are (the main exception -% is with most defuns, which call us directly). +% \empty if called from \doind, as we usually are. The main exception +% is with defuns, which call us directly. % \def\dosubind#1#2#3{% - \iflinks - {% - % Store the main index entry text (including the third arg). - \toks0 = {#2}% - % If third arg is present, precede it with a space. - \def\thirdarg{#3}% - \ifx\thirdarg\empty \else - \toks0 = \expandafter{\the\toks0 \space #3}% - \fi - % - \edef\writeto{\csname#1indfile\endcsname}% - % - \ifvmode - \dosubindsanitize - \else - \dosubindwrite - \fi - }% - \fi -} - -% Write the entry in \toks0 to the index file: -% -\def\dosubindwrite{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else - \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi - % - % Remember, we are within a group. - \indexdummies % Must do this here, since \bf, etc expand at this stage - \escapechar=`\\ - \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now - % so it will be output as is; and it will print as backslash. - % - % Process the index entry with all font commands turned off, to - % get the string to sort by. - {\indexnofonts - \edef\temp{\the\toks0}% need full expansion - \xdef\indexsorttmp{\temp}% - }% - % - % Set up the complete index entry, with both the sort key and - % the original text, including any font commands. We write - % three arguments to \entry to the .?? file (four in the - % subentry case), texindex reduces to two when writing the .??s - % sorted result. - \edef\temp{% - \write\writeto{% - \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% + {% + \count255=\lastpenalty + {% + \indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\ + {% + \let\folio = 0% We will expand all macros now EXCEPT \folio. + \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + % The main index entry text. + \toks0 = {#2}% + % + % If third arg is present, precede it with space in sort key. + \def\thirdarg{#3}% + \ifx\thirdarg\emptymacro \else + % If the third (subentry) arg is present, add it to the index + % line to write. + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + % Process the index entry with all font commands turned off, to + % get the string to sort by. + {\indexnofonts + \edef\temp{\the\toks0}% need full expansion + \xdef\indexsorttmp{\temp}% + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\csname#1indfile\endcsname{% + \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% + }% + % + % If a skip is the last thing on the list now, preserve it + % by backing up by \lastskip, doing the \write, then inserting + % the skip again. Otherwise, the whatsit generated by the + % \write will make \lastskip zero. The result is that sequences + % like this: + % @end defun + % @tindex whatever + % @defun ... + % will have extra space inserted, because the \medbreak in the + % start of the @defun won't see the skip inserted by the @end of + % the previous defun. + % + % But don't do any of this if we're not in vertical mode. We + % don't want to do a \vskip and prematurely end a paragraph. + % + % Avoid page breaks due to these extra skips, too. + % + \iflinks + \ifvmode + \skip0 = \lastskip + \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi + \fi + % + \temp % do the write + % + \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi + \fi + }% + }% + \penalty\count255 }% - \temp -} - -% Take care of unwanted page breaks: -% -% If a skip is the last thing on the list now, preserve it -% by backing up by \lastskip, doing the \write, then inserting -% the skip again. Otherwise, the whatsit generated by the -% \write will make \lastskip zero. The result is that sequences -% like this: -% @end defun -% @tindex whatever -% @defun ... -% will have extra space inserted, because the \medbreak in the -% start of the @defun won't see the skip inserted by the @end of -% the previous defun. -% -% But don't do any of this if we're not in vertical mode. We -% don't want to do a \vskip and prematurely end a paragraph. -% -% Avoid page breaks due to these extra skips, too. -% -% But wait, there is a catch there: -% We'll have to check whether \lastskip is zero skip. \ifdim is not -% sufficient for this purpose, as it ignores stretch and shrink parts -% of the skip. The only way seems to be to check the textual -% representation of the skip. -% -% The following is almost like \def\zeroskipmacro{0.0pt} except that -% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). -% -\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} -% -% ..., ready, GO: -% -\def\dosubindsanitize{% - % \lastskip and \lastpenalty cannot both be nonzero simultaneously. - \skip0 = \lastskip - \edef\lastskipmacro{\the\lastskip}% - \count255 = \lastpenalty - % - % If \lastskip is nonzero, that means the last item was a - % skip. And since a skip is discardable, that means this - % -\skip0 glue we're inserting is preceded by a - % non-discardable item, therefore it is not a potential - % breakpoint, therefore no \nobreak needed. - \ifx\lastskipmacro\zeroskipmacro - \else - \vskip-\skip0 - \fi - % - \dosubindwrite - % - \ifx\lastskipmacro\zeroskipmacro - % If \lastskip was zero, perhaps the last item was a penalty, and - % perhaps it was >=10000, e.g., a \nobreak. In that case, we want - % to re-insert the same penalty (values >10000 are used for various - % signals); since we just inserted a non-discardable item, any - % following glue (such as a \parskip) would be a breakpoint. For example: - % - % @deffn deffn-whatever - % @vindex index-whatever - % Description. - % would allow a break between the index-whatever whatsit - % and the "Description." paragraph. - \ifnum\count255>9999 \penalty\count255 \fi - \else - % On the other hand, if we had a nonzero \lastskip, - % this make-up glue would be preceded by a non-discardable item - % (the whatsit from the \write), so we must insert a \nobreak. - \nobreak\vskip\skip0 - \fi } % The index entry written in the file actually looks like @@ -3488,12 +3387,14 @@ where each line of input produces a line % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % -\parseargdef\printindex{\begingroup +\def\printindex{\parsearg\doprintindex} +\def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \smallfonts \rm \tolerance = 9500 \everypar = {}% don't want the \kern\-parindent from indentation suppression. + \indexbreaks % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains @@ -3520,7 +3421,7 @@ where each line of input produces a line % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. - \def\indexbackslash{\backslashcurfont}% + \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns @@ -3542,10 +3443,7 @@ where each line of input produces a line \removelastskip % % We like breaks before the index initials, so insert a bonus. - \nobreak - \vskip 0pt plus 3\baselineskip - \penalty 0 - \vskip 0pt plus -3\baselineskip + \penalty -300 % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column @@ -3555,100 +3453,80 @@ where each line of input produces a line % No shrink because it confuses \balancecolumns. \vskip 1.67\baselineskip plus .5\baselineskip \leftline{\secbf #1}% + \vskip .33\baselineskip plus .1\baselineskip + % % Do our best not to break after the initial. \nobreak - \vskip .33\baselineskip plus .1\baselineskip }} -% \entry typesets a paragraph consisting of the text (#1), dot leaders, and -% then page number (#2) flushed to the right margin. It is used for index -% and table of contents entries. The paragraph is indented by \leftskip. -% -% A straightforward implementation would start like this: -% \def\entry#1#2{... -% But this frozes the catcodes in the argument, and can cause problems to -% @code, which sets - active. This problem was fixed by a kludge--- -% ``-'' was active throughout whole index, but this isn't really right. -% -% The right solution is to prevent \entry from swallowing the whole text. -% --kasal, 21nov03 -\def\entry{% - \begingroup - % - % Start a new paragraph if necessary, so our assignments below can't - % affect previous text. - \par - % - % Do not fill out the last line with white space. - \parfillskip = 0in - % - % No extra space above this paragraph. - \parskip = 0in - % - % Do not prefer a separate line ending with a hyphen to fewer lines. - \finalhyphendemerits = 0 - % - % \hangindent is only relevant when the entry text and page number - % don't both fit on one line. In that case, bob suggests starting the - % dots pretty far over on the line. Unfortunately, a large - % indentation looks wrong when the entry text itself is broken across - % lines. So we use a small indentation and put up with long leaders. - % - % \hangafter is reset to 1 (which is the value we want) at the start - % of each paragraph, so we need not do anything with that. - \hangindent = 2em - % - % When the entry text needs to be broken, just fill out the first line - % with blank space. - \rightskip = 0pt plus1fil - % - % A bit of stretch before each entry for the benefit of balancing - % columns. - \vskip 0pt plus1pt - % - % Swallow the left brace of the text (first parameter): - \afterassignment\doentry - \let\temp = -} -\def\doentry{% - \bgroup % Instead of the swallowed brace. - \noindent - \aftergroup\finishentry - % And now comes the text of the entry. -} -\def\finishentry#1{% - % #1 is the page number. - % - % The following is kludged to not output a line of dots in the index if - % there are no page numbers. The next person who breaks this will be - % cursed by a Unix daemon. - \def\tempa{{\rm }}% - \def\tempb{#1}% - \edef\tempc{\tempa}% - \edef\tempd{\tempb}% - \ifx\tempc\tempd - \ % +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry#1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing columns. + \vskip 0pt plus1pt + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else - % - % If we must, put the page number on a line of its own, and fill out - % this line with blank space. (The \hfil is overwhelmed with the - % fill leaders glue in \indexdotfill if the page number does fit.) - \hfil\penalty50 - \null\nobreak\indexdotfill % Have leaders before the page number. - % - % The `\ ' here is removed by the implicit \unskip that TeX does as - % part of (the primitive) \par. Without it, a spurious underfull - % \hbox ensues. - \ifpdf - \pdfgettoks#1.% - \ \the\toksA - \else - \ #1% - \fi + \ #2% The page number ends the paragraph. \fi - \par - \endgroup -} + \fi% + \par +\endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders @@ -3817,12 +3695,6 @@ where each line of input produces a line \message{sectioning,} % Chapters, sections, etc. -% \unnumberedno is an oxymoron, of course. But we count the unnumbered -% sections so that we can refer to them unambiguously in the pdf -% outlines by their "section number". We avoid collisions with chapter -% numbers by starting them at 10000. (If a document ever has 10000 -% chapters, we're in trouble anyway, I'm sure.) -\newcount\unnumberedno \unnumberedno = 10000 \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 @@ -3830,12 +3702,9 @@ where each line of input produces a line % This counter is funny since it counts through charcodes of letters A, B, ... \newcount\appendixno \appendixno = `\@ -% % \def\appendixletter{\char\the\appendixno} -% We do the following ugly conditional instead of the above simple -% construct for the sake of pdftex, which needs the actual +% We do the following for the sake of pdftex, which needs the actual % letter in the expansion, not just typeset. -% \def\appendixletter{% \ifnum\appendixno=`A A% \else\ifnum\appendixno=`B B% @@ -3873,12 +3742,11 @@ where each line of input produces a line % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise. -% However, they are not reliable, because we don't use marks. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level -\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count +\newcount\secbase\secbase=0 % @raise/lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} @@ -3888,142 +3756,121 @@ where each line of input produces a line \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name -% we only have subsub. -\chardef\maxseclevel = 3 -% -% A numbered section within an unnumbered changes to unnumbered too. -% To achive this, remember the "biggest" unnum. sec. we are currently in: -\chardef\unmlevel = \maxseclevel -% -% Trace whether the current chapter is an appendix or not: -% \chapheadtype is "N" or "A", unnumbered chapters are ignored. -\def\chapheadtype{N} - -% Choose a heading macro -% #1 is heading type -% #2 is heading level -% #3 is text for heading -\def\genhead#1#2#3{% - % Compute the abs. sec. level: - \absseclevel=#2 - \advance\absseclevel by \secbase - % Make sure \absseclevel doesn't fall outside the range: - \ifnum \absseclevel < 0 - \absseclevel = 0 +% Choose a numbered-heading macro +% #1 is heading level if unmodified by @raisesections or @lowersections +% #2 is text for heading +\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \chapterzzz{#2} +\or + \seczzz{#2} +\or + \numberedsubseczzz{#2} +\or + \numberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \chapterzzz{#2} \else - \ifnum \absseclevel > 3 - \absseclevel = 3 - \fi + \numberedsubsubseczzz{#2} \fi - % The heading type: - \def\headtype{#1}% - \if \headtype U% - \ifnum \absseclevel < \unmlevel - \chardef\unmlevel = \absseclevel - \fi +\fi +\suppressfirstparagraphindent +} + +% like \numhead, but chooses appendix heading levels +\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \appendixzzz{#2} +\or + \appendixsectionzzz{#2} +\or + \appendixsubseczzz{#2} +\or + \appendixsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \appendixzzz{#2} \else - % Check for appendix sections: - \ifnum \absseclevel = 0 - \edef\chapheadtype{\headtype}% - \else - \if \headtype A\if \chapheadtype N% - \errmessage{@appendix... within a non-appendix chapter}% - \fi\fi - \fi - % Check for numbered within unnumbered: - \ifnum \absseclevel > \unmlevel - \def\headtype{U}% - \else - \chardef\unmlevel = 3 - \fi + \appendixsubsubseczzz{#2} \fi - % Now print the heading: - \if \headtype U% - \ifcase\absseclevel - \unnumberedzzz{#3}% - \or \unnumberedseczzz{#3}% - \or \unnumberedsubseczzz{#3}% - \or \unnumberedsubsubseczzz{#3}% - \fi +\fi +\suppressfirstparagraphindent +} + +% like \numhead, but chooses numberless heading levels +\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \unnumberedzzz{#2} +\or + \unnumberedseczzz{#2} +\or + \unnumberedsubseczzz{#2} +\or + \unnumberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \unnumberedzzz{#2} \else - \if \headtype A% - \ifcase\absseclevel - \appendixzzz{#3}% - \or \appendixsectionzzz{#3}% - \or \appendixsubseczzz{#3}% - \or \appendixsubsubseczzz{#3}% - \fi - \else - \ifcase\absseclevel - \chapterzzz{#3}% - \or \seczzz{#3}% - \or \numberedsubseczzz{#3}% - \or \numberedsubsubseczzz{#3}% - \fi - \fi + \unnumberedsubsubseczzz{#2} \fi - \suppressfirstparagraphindent +\fi +\suppressfirstparagraphindent } -% an interface: -\def\numhead{\genhead N} -\def\apphead{\genhead A} -\def\unnmhead{\genhead U} - -% @chapter, @appendix, @unnumbered. Increment top-level counter, reset -% all lower-level sectioning counters to zero. -% -% Also set \chaplevelprefix, which we prepend to @float sequence numbers -% (e.g., figures), q.v. By default (before any chapter), that is empty. -\let\chaplevelprefix = \empty -% -\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz -\def\chapterzzz#1{% - % section resetting is \global in case the chapter is in a group, such - % as an @include file. - \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 - \global\advance\chapno by 1 - % - % Used for \float. - \gdef\chaplevelprefix{\the\chapno.}% - \resetallfloatnos - % - \message{\putwordChapter\space \the\chapno}% - % - % Write the actual heading. - \chapmacro{#1}{Ynumbered}{\the\chapno}% - % - % So @section and the like are numbered underneath this chapter. +% @chapter, @appendix, @unnumbered. +\def\thischaptername{No Chapter Title} +\outer\def\chapter{\parsearg\chapteryyy} +\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz #1{% + \secno=0 \subsecno=0 \subsubsecno=0 + \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% + \chapmacro {#1}{\the\chapno}% + \gdef\thissection{#1}% + \gdef\thischaptername{#1}% + % We don't substitute the actual chapter name into \thischapter + % because we don't want its macros evaluated now. + \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% + \writetocentry{chap}{#1}{{\the\chapno}} + \donoderef \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } -\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz -\def\appendixzzz#1{% - \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 - \global\advance\appendixno by 1 - \gdef\chaplevelprefix{\appendixletter.}% - \resetallfloatnos - % - \def\appendixnum{\putwordAppendix\space \appendixletter}% - \message{\appendixnum}% - % - \chapmacro{#1}{Yappendix}{\appendixletter}% - % +% we use \chapno to avoid indenting back +\def\appendixbox#1{% + \setbox0 = \hbox{\putwordAppendix{} \the\chapno}% + \hbox to \wd0{#1\hss}} + +\outer\def\appendix{\parsearg\appendixyyy} +\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz #1{% + \secno=0 \subsecno=0 \subsubsecno=0 + \global\advance \appendixno by 1 + \message{\putwordAppendix\space \appendixletter}% + \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}% + \gdef\thissection{#1}% + \gdef\thischaptername{#1}% + \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% + \writetocentry{appendix}{#1}{{\appendixletter}} + \appendixnoderef \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } -\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz -\def\unnumberedzzz#1{% - \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 - \global\advance\unnumberedno by 1 - % - % Since an unnumbered has no number, no prefix for figures. - \global\let\chaplevelprefix = \empty - \resetallfloatnos +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} + +% @top is like @unnumbered. +\outer\def\top{\parsearg\unnumberedyyy} + +\outer\def\unnumbered{\parsearg\unnumberedyyy} +\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz #1{% + \secno=0 \subsecno=0 \subsubsecno=0 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX @@ -4036,98 +3883,134 @@ where each line of input produces a line % \the to achieve this: TeX expands \the only once, % simply yielding the contents of . (We also do this for % the toc entries.) - \toks0 = {#1}% - \message{(\the\toks0)}% - % - \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + \toks0 = {#1}\message{(\the\toks0)}% % + \unnumbchapmacro {#1}% + \gdef\thischapter{#1}\gdef\thissection{#1}% + \writetocentry{unnumbchap}{#1}{{\the\chapno}} + \unnumbnoderef \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } -% @centerchap is like @unnumbered, but the heading is centered. -\outer\parseargdef\centerchap{% - % Well, we could do the following in a group, but that would break - % an assumption that \chapmacro is called at the outermost level. - % Thus we are safer this way: --kasal, 24feb04 - \let\centerparametersmaybe = \centerparameters - \unnmhead0{#1}% - \let\centerparametersmaybe = \relax +% Sections. +\outer\def\numberedsec{\parsearg\secyyy} +\def\secyyy #1{\numhead1{#1}} % normally calls seczzz +\def\seczzz #1{% + \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % + \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% + \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}} + \donoderef + \nobreak } -% @top is like @unnumbered. -\let\top\unnumbered +\outer\def\appendixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsec{\parsearg\appendixsecyyy} +\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz #1{% + \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % + \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% + \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}} + \appendixnoderef + \nobreak +} -% Sections. -\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz -\def\seczzz#1{% - \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 - \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% -} - -\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz -\def\appendixsectionzzz#1{% - \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 - \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% -} -\let\appendixsec\appendixsection - -\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz -\def\unnumberedseczzz#1{% - \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 - \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} +\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz #1{% + \plainsecheading {#1}\gdef\thissection{#1}% + \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}} + \unnumbnoderef + \nobreak } % Subsections. -\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz -\def\numberedsubseczzz#1{% - \global\subsubsecno=0 \global\advance\subsecno by 1 - \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% -} - -\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz -\def\appendixsubseczzz#1{% - \global\subsubsecno=0 \global\advance\subsecno by 1 - \sectionheading{#1}{subsec}{Yappendix}% - {\appendixletter.\the\secno.\the\subsecno}% -} - -\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz -\def\unnumberedsubseczzz#1{% - \global\subsubsecno=0 \global\advance\subsecno by 1 - \sectionheading{#1}{subsec}{Ynothing}% - {\the\unnumberedno.\the\secno.\the\subsecno}% +\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} +\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz #1{% + \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % + \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% + \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} + \donoderef + \nobreak +} + +\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} +\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz #1{% + \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % + \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% + \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}} + \appendixnoderef + \nobreak +} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} +\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz #1{% + \plainsubsecheading {#1}\gdef\thissection{#1}% + \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} + \unnumbnoderef + \nobreak } % Subsubsections. -\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz -\def\numberedsubsubseczzz#1{% - \global\advance\subsubsecno by 1 - \sectionheading{#1}{subsubsec}{Ynumbered}% - {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% -} - -\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz -\def\appendixsubsubseczzz#1{% - \global\advance\subsubsecno by 1 - \sectionheading{#1}{subsubsec}{Yappendix}% - {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% -} - -\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz -\def\unnumberedsubsubseczzz#1{% - \global\advance\subsubsecno by 1 - \sectionheading{#1}{subsubsec}{Ynothing}% - {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} +\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz #1{% + \gdef\thissection{#1}\global\advance \subsubsecno by 1 % + \subsubsecheading {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% + \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} + \donoderef + \nobreak +} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} +\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz #1{% + \gdef\thissection{#1}\global\advance \subsubsecno by 1 % + \subsubsecheading {#1} + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% + \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}} + \appendixnoderef + \nobreak +} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} +\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz #1{% + \plainsubsubsecheading {#1}\gdef\thissection{#1}% + \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} + \unnumbnoderef + \nobreak } +% These are variants which are not "outer", so they can appear in @ifinfo. +% Actually, they should now be obsolete; ordinary section commands should work. +\def\infotop{\parsearg\unnumberedzzz} +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. -\let\section = \numberedsec -\let\subsection = \numberedsubsec -\let\subsubsection = \numberedsubsubsec +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading @@ -4140,27 +4023,23 @@ where each line of input produces a line % if justification is not attempted. Hence \raggedright. -\def\majorheading{% +\def\majorheading{\parsearg\majorheadingzzz} +\def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% - \parsearg\chapheadingzzz -} + {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} -\def\chapheading{\chapbreak \parsearg\chapheadingzzz} -\def\chapheadingzzz#1{% +\def\chapheading{\parsearg\chapheadingzzz} +\def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright - \rm #1\hfill}}% - \bigskip \par\penalty 200\relax - \suppressfirstparagraphindent -} + \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. -\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} - \suppressfirstparagraphindent} -\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} - \suppressfirstparagraphindent} -\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} - \suppressfirstparagraphindent} +\def\heading{\parsearg\plainsecheading} +\def\subheading{\parsearg\plainsubsecheading} +\def\subsubheading{\parsearg\plainsubsubsecheading} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), @@ -4169,6 +4048,8 @@ where each line of input produces a line %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) @@ -4191,7 +4072,7 @@ where each line of input produces a line \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} -\def\CHAPPAGodd{% +\def\CHAPPAGodd{ \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage @@ -4199,193 +4080,116 @@ where each line of input produces a line \CHAPPAGon -% Chapter opening. -% -% #1 is the text, #2 is the section type (Ynumbered, Ynothing, -% Yappendix, Yomitfromtoc), #3 the chapter number. -% -% To test against our argument. -\def\Ynothingkeyword{Ynothing} -\def\Yomitfromtockeyword{Yomitfromtoc} -\def\Yappendixkeyword{Yappendix} -% -\def\chapmacro#1#2#3{% +\def\CHAPFplain{ +\global\let\chapmacro=\chfplain +\global\let\unnumbchapmacro=\unnchfplain +\global\let\centerchapmacro=\centerchfplain} + +% Plain chapter opening. +% #1 is the text, #2 the chapter number or empty if unnumbered. +\def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm - % - % Have to define \thissection before calling \donoderef, because the - % xref code eventually uses it. On the other hand, it has to be called - % after \pchapsepmacro, or the headline will change too soon. - \gdef\thissection{#1}% - \gdef\thischaptername{#1}% - % - % Only insert the separating space if we have a chapter/appendix - % number, and don't print the unnumbered ``number''. - \def\temptype{#2}% - \ifx\temptype\Ynothingkeyword - \setbox0 = \hbox{}% - \def\toctype{unnchap}% - \def\thischapter{#1}% - \else\ifx\temptype\Yomitfromtockeyword - \setbox0 = \hbox{}% contents like unnumbered, but no toc entry - \def\toctype{omit}% - \xdef\thischapter{}% - \else\ifx\temptype\Yappendixkeyword - \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% - \def\toctype{app}% - % We don't substitute the actual chapter name into \thischapter - % because we don't want its macros evaluated now. And we don't - % use \thissection because that changes with each section. - % - \xdef\thischapter{\putwordAppendix{} \appendixletter: - \noexpand\thischaptername}% - \else - \setbox0 = \hbox{#3\enspace}% - \def\toctype{numchap}% - \xdef\thischapter{\putwordChapter{} \the\chapno: - \noexpand\thischaptername}% - \fi\fi\fi - % - % Write the toc entry for this chapter. Must come before the - % \donoderef, because we include the current node name in the toc - % entry, and \donoderef resets it to empty. - \writetocentry{\toctype}{#1}{#3}% - % - % For pdftex, we have to write out the node definition (aka, make - % the pdfdest) after any page break, but before the actual text has - % been typeset. If the destination for the pdf outline is after the - % text, then jumping from the outline may wind up with the text not - % being visible, for instance under high magnification. - \donoderef{#2}% - % - % Typeset the actual heading. + \def\chapnum{#2}% + \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent=\wd0 \centerparametersmaybe + \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } +% Plain opening for unnumbered. +\def\unnchfplain#1{\chfplain{#1}{}} + % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax -\def\centerparameters{% - \advance\rightskip by 3\rightskip - \leftskip = \rightskip - \parfillskip = 0pt -} +\def\centerchfplain#1{{% + \def\centerparametersmaybe{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + }% + \chfplain{#1}{}% +}} +\CHAPFplain % The default -% I don't think this chapter style is supported any more, so I'm not -% updating it with the new noderef stuff. We'll see. --karl, 11aug03. -% -\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} -% \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\nobreak } + \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } + \def\centerchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } -\def\CHAPFopen{% - \global\let\chapmacro=\chfopen - \global\let\centerchapmacro=\centerchfopen} +\def\CHAPFopen{ +\global\let\chapmacro=\chfopen +\global\let\unnumbchapmacro=\unnchfopen +\global\let\centerchapmacro=\centerchfopen} -% Section titles. These macros combine the section number parts and -% call the generic \sectionheading to do the printing. -% + +% Section titles. \newskip\secheadingskip -\def\secheadingbreak{\dobreak \secheadingskip{-1000}} +\def\secheadingbreak{\dobreak \secheadingskip {-1000}} +\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} +\def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. -\newskip\subsecheadingskip -\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} +\newskip \subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} +\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} +\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. -\def\subsubsecheadingskip{\subsecheadingskip} -\def\subsubsecheadingbreak{\subsecheadingbreak} +\let\subsubsecheadingskip = \subsecheadingskip +\let\subsubsecheadingbreak = \subsecheadingbreak +\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} +\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} -% Print any size, any type, section title. -% -% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is -% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the -% section number. +% Print any size section title. % -\def\sectionheading#1#2#3#4{% +% #1 is the section type (sec/subsec/subsubsec), #2 is the section +% number (maybe empty), #3 the text. +\def\sectionheading#1#2#3{% + {% + \expandafter\advance\csname #1headingskip\endcsname by \parskip + \csname #1headingbreak\endcsname + }% {% % Switch to the right set of fonts. - \csname #2fonts\endcsname \rm - % - % Insert space above the heading. - \csname #2headingbreak\endcsname + \csname #1fonts\endcsname \rm % - % Only insert the space after the number if we have a section number. - \def\sectionlevel{#2}% - \def\temptype{#3}% - % - \ifx\temptype\Ynothingkeyword - \setbox0 = \hbox{}% - \def\toctype{unn}% - \gdef\thissection{#1}% - \else\ifx\temptype\Yomitfromtockeyword - % for @headings -- no section number, don't include in toc, - % and don't redefine \thissection. - \setbox0 = \hbox{}% - \def\toctype{omit}% - \let\sectionlevel=\empty - \else\ifx\temptype\Yappendixkeyword - \setbox0 = \hbox{#4\enspace}% - \def\toctype{app}% - \gdef\thissection{#1}% - \else - \setbox0 = \hbox{#4\enspace}% - \def\toctype{num}% - \gdef\thissection{#1}% - \fi\fi\fi - % - % Write the toc entry (before \donoderef). See comments in \chfplain. - \writetocentry{\toctype\sectionlevel}{#1}{#4}% - % - % Write the node reference (= pdf destination for pdftex). - % Again, see comments in \chfplain. - \donoderef{#3}% + % Only insert the separating space if we have a section number. + \def\secnum{#2}% + \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % - % Output the actual section heading. \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent=\wd0 % zero if no section number - \unhbox0 #1}% + \hangindent = \wd0 % zero if no section number + \unhbox0 #3}% }% - % Add extra space after the heading -- half of whatever came above it. - % Don't allow stretch, though. - \kern .5 \csname #2headingskip\endcsname - % - % Do not let the kern be a potential breakpoint, as it would be if it - % was followed by glue. + % Add extra space after the heading -- either a line space or a + % paragraph space, whichever is more. (Some people like to set + % \parskip to large values for some reason.) Don't allow stretch, though. + \nobreak + \ifdim\parskip>\normalbaselineskip + \kern\parskip + \else + \kern\normalbaselineskip + \fi \nobreak - % - % We'll almost certainly start a paragraph next, so don't let that - % glue accumulate. (Not a breakpoint because it's preceded by a - % discardable item.) - \vskip-\parskip - % - % This is purely so the last item on the list is a known \penalty > - % 10000. This is so \startdefun can avoid allowing breakpoints after - % section headings. Otherwise, it would insert a valid breakpoint between: - % - % @section sec-whatever - % @deffn def-whatever - \penalty 10001 } @@ -4394,152 +4198,119 @@ where each line of input produces a line \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. -% Called from @chapter, etc. -% -% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} -% We append the current node name (if any) and page number as additional -% arguments for the \{chap,sec,...}entry macros which will eventually -% read this. The node name is used in the pdf outlines as the -% destination to jump to. +% Called from @chapter, etc. We supply {\folio} at the end of the +% argument, which will end up as the last argument to the \...entry macro. % +% Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}} % We open the .toc file for writing here instead of at @setfilename (or % any other fixed time) so that @contents can be anywhere in the document. -% But if #1 is `omit', then we don't do anything. This is used for the -% table of contents chapter openings themselves. % \newif\iftocfileopened -\def\omitkeyword{omit}% -% \def\writetocentry#1#2#3{% - \edef\writetoctype{#1}% - \ifx\writetoctype\omitkeyword \else - \iftocfileopened\else - \immediate\openout\tocfile = \jobname.toc - \global\tocfileopenedtrue - \fi - % - \iflinks - \toks0 = {#2}% - \toks2 = \expandafter{\lastnode}% - \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}% - {\the\toks2}{\noexpand\folio}}}% - \temp - \fi + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + \toks0 = {#2}% + \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}% + \temp \fi % - % Tell \shipout to create a pdf destination on each page, if we're - % writing pdf. These are used in the table of contents. We can't - % just write one on every page because the title pages are numbered - % 1 and 2 (the page numbers aren't printed), and so are the first - % two pages of the document. Thus, we'd have two destinations named - % `1', and two named `2'. - \ifpdf \global\pdfmakepagedesttrue \fi + % Tell \shipout to create a page destination if we're doing pdf, which + % will be the target of the links in the table of contents. We can't + % just do it on every page because the title pages are numbered 1 and + % 2 (the page numbers aren't printed), and so are the first two pages + % of the document. Thus, we'd have two destinations named `1', and + % two named `2'. + \ifpdf \pdfmakepagedesttrue \fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 -% Prepare to read what we've written to \tocfile. +% Finish up the main text and prepare to read what we've written +% to \tocfile. % \def\startcontents#1{% - % If @setchapternewpage on, and @headings double, the contents should - % start on an odd page, unlike chapters. Thus, we maintain - % \contentsalignmacro in parallel with \pagealignmacro. - % From: Torbjorn Granlund - \contentsalignmacro - \immediate\closeout\tocfile - % - % Don't need to put `Contents' or `Short Contents' in the headline. - % It is abundantly clear what they are. - \def\thischapter{}% - \chapmacro{#1}{Yomitfromtoc}{}% - % - \savepageno = \pageno - \begingroup % Set up to handle contents files properly. - \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 - % We can't do this, because then an actual ^ in a section - % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. - %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi - \raggedbottom % Worry more about breakpoints than the bottom. - \advance\hsize by -\contentsrightmargin % Don't use the full line length. - % - % Roman numerals for page numbers. - \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \unnumbchapmacro{#1}\def\thischapter{}% + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + % We can't do this, because then an actual ^ in a section + % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. + %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi } % Normal (long) toc. \def\contents{% - \startcontents{\putwordTOC}% - \openin 1 \jobname.toc - \ifeof 1 \else - \input \jobname.toc - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \ifeof 1 \else - \pdfmakeoutlines - \fi - \closein 1 - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno + \startcontents{\putwordTOC}% + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \pdfmakeoutlines + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno } % And just the chapters. \def\summarycontents{% - \startcontents{\putwordShortTOC}% - % - \let\numchapentry = \shortchapentry - \let\appentry = \shortchapentry - \let\unnchapentry = \shortunnchapentry - % We want a true roman here for the page numbers. - \secfonts - \let\rm=\shortcontrm \let\bf=\shortcontbf - \let\sl=\shortcontsl \let\tt=\shortconttt - \rm - \hyphenpenalty = 10000 - \advance\baselineskip by 1pt % Open it up a little. - \def\numsecentry##1##2##3##4{} - \let\appsecentry = \numsecentry - \let\unnsecentry = \numsecentry - \let\numsubsecentry = \numsecentry - \let\appsubsecentry = \numsecentry - \let\unnsubsecentry = \numsecentry - \let\numsubsubsecentry = \numsecentry - \let\appsubsubsecentry = \numsecentry - \let\unnsubsubsecentry = \numsecentry - \openin 1 \jobname.toc - \ifeof 1 \else - \input \jobname.toc - \fi - \closein 1 - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno + \startcontents{\putwordShortTOC}% + % + \let\chapentry = \shortchapentry + \let\appendixentry = \shortappendixentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\subsecentry ##1##2##3##4##5{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \let\unnumbsecentry = \secentry + \let\unnumbsubsecentry = \subsecentry + \let\unnumbsubsubsecentry = \subsubsecentry + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno } \let\shortcontents = \summarycontents -% Typeset the label for a chapter or appendix for the short contents. -% The arg is, e.g., `A' for an appendix, or `3' for a chapter. -% -\def\shortchaplabel#1{% - % This space should be enough, since a single number is .5em, and the - % widest letter (M) is 1em, at least in the Computer Modern fonts. - % But use \hss just in case. - % (This space doesn't include the extra space that gets added after - % the label; that gets put in by \shortchapentry above.) - % - % We'd like to right-justify chapter numbers, but that looks strange - % with appendix letters. And right-justifying numbers and - % left-justifying letters looks strange when there is less than 10 - % chapters. Have to read the whole toc once to know how many chapters - % there are before deciding ... - \hbox to 1em{#1\hss}% -} +\ifpdf + \pdfcatalog{/PageMode /UseOutlines}% +\fi % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. @@ -4547,46 +4318,58 @@ where each line of input produces a line % The arguments in between are the chapter number, section number, ... % Chapters, in the main contents. -\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} +\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. -\def\shortchapentry#1#2#3#4{% - \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +\def\shortchapentry#1#2#3{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% } % Appendices, in the main contents. -% Need the word Appendix, and a fixed-size box. +\def\appendixentry#1#2#3{% + \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}} % -\def\appendixbox#1{% - % We use M since it's probably the widest letter. - \setbox0 = \hbox{\putwordAppendix{} M}% - \hbox to \wd0{\putwordAppendix{} #1\hss}} +% Appendices, in the short toc. +\let\shortappendixentry = \shortchapentry + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter. +% We could simplify the code here by writing out an \appendixentry +% command in the toc file for appendices, instead of using \chapentry +% for both, but it doesn't seem worth it. % -\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} +\newdimen\shortappendixwidth +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + \dimen0 = 1em + \hbox to \dimen0{#1\hss}% +} % Unnumbered chapters. -\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} -\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} +\def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}} +\def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}} % Sections. -\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} -\let\appsecentry=\numsecentry -\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} +\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} +\def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}} % Subsections. -\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} -\let\appsubsecentry=\numsubsecentry -\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} +\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} +\def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}} % And subsubsections. -\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} -\let\appsubsubsecentry=\numsubsubsecentry -\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} +\def\subsubsecentry#1#2#3#4#5#6{% + \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} +\def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}} % This parameter controls the indentation of the various levels. -% Same as \defaultparindent. -\newdimen\tocindent \tocindent = 15pt +\newdimen\tocindent \tocindent = 3pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. @@ -4617,8 +4400,17 @@ where each line of input produces a line \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} -% We use the same \entry macro as for the index entries. -\let\tocentry = \entry +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +\def\tocentry#1#2{\begingroup + \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks + % Do not use \turnoffactive in these arguments. Since the toc is + % typeset in cmr, characters such as _ would come out wrong; we + % have to do the usual translation tricks. + \entry{#1}{#2}% +\endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} @@ -4628,8 +4420,8 @@ where each line of input produces a line \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} -\def\subsecentryfonts{\textfonts} -\def\subsubsecentryfonts{\textfonts} +\let\subsecentryfonts = \textfonts +\let\subsubsecentryfonts = \textfonts \message{environments,} @@ -4656,10 +4448,10 @@ where each line of input produces a line % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} % -\setbox\errorbox=\hbox to \dimen0{\hfil +\global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. - \vbox{% + \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. @@ -4673,13 +4465,14 @@ where each line of input produces a line % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. -\envdef\tex{% +\def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie \catcode `\%=14 \catcode `\+=\other \catcode `\"=\other + \catcode `\==\other \catcode `\|=\other \catcode `\<=\other \catcode `\>=\other @@ -4695,7 +4488,6 @@ where each line of input produces a line \let\!=\ptexexclam \let\i=\ptexi \let\indent=\ptexindent - \let\noindent=\ptexnoindent \let\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace @@ -4706,11 +4498,10 @@ where each line of input produces a line \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% -} -% There is no need to define \Etex. +\let\Etex=\endgroup} % Define @lisp ... @end lisp. -% @lisp environment forms a group so it can rebind things, +% @lisp does a \begingroup so it can rebind things, % including the definition of @end lisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. @@ -4721,6 +4512,19 @@ where each line of input produces a line % have any width. \def\lisppar{\null\endgraf} +% Make each space character in the input produce a normal interword +% space in the output. Don't allow a line break at this space, as this +% is used only in environments like @example, where each line of input +% should produce a line of output anyway. +% +{\obeyspaces % +\gdef\sepspaces{\obeyspaces\let =\tie}} + +% Define \obeyedspace to be our active space, whatever it is. This is +% for use in \parsearg. +{\sepspaces% +\global\let\obeyedspace= } + % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt @@ -4730,8 +4534,7 @@ where each line of input produces a line % start of the next paragraph will insert \parskip. % \def\aboveenvbreak{{% - % =10000 instead of <10000 because of a special case in \itemzzz and - % \sectionheading, q.v. + % =10000 instead of <10000 because of a special case in \itemzzz, q.v. \ifnum \lastpenalty=10000 \else \advance\envskipamount by \parskip \endgraf @@ -4739,7 +4542,7 @@ where each line of input produces a line \removelastskip % it's not a good place to break if the last penalty was \nobreak % or better ... - \ifnum\lastpenalty<10000 \penalty-50 \fi + \ifnum\lastpenalty>10000 \else \penalty-50 \fi \vskip\envskipamount \fi \fi @@ -4771,52 +4574,52 @@ where each line of input produces a line % \newskip\lskip\newskip\rskip -\envdef\cartouche{% - \ifhmode\par\fi % can't be in the midst of a paragraph. - \startsavinginserts - \lskip=\leftskip \rskip=\rightskip - \leftskip=0pt\rightskip=0pt % we want these *outside*. - \cartinner=\hsize \advance\cartinner by-\lskip - \advance\cartinner by-\rskip - \cartouter=\hsize - \advance\cartouter by 18.4pt % allow for 3pt kerns on either - % side, and for 6pt waste from - % each corner char, and rule thickness - \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip - % Flag to tell @lisp, etc., not to narrow margin. - \let\nonarrowing=\comment - \vbox\bgroup - \baselineskip=0pt\parskip=0pt\lineskip=0pt - \carttop - \hbox\bgroup - \hskip\lskip - \vrule\kern3pt - \vbox\bgroup - \kern3pt - \hsize=\cartinner - \baselineskip=\normbskip - \lineskip=\normlskip - \parskip=\normpskip - \vskip -\parskip - \comment % For explanation, see the end of \def\group. -} +\def\cartouche{% +\par % can't be in the midst of a paragraph. +\begingroup + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt %we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either +% side, and for 6pt waste from +% each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \hsize=\cartinner + \kern3pt + \begingroup + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip \def\Ecartouche{% - \ifhmode\par\fi - \kern3pt - \egroup - \kern3pt\vrule - \hskip\rskip - \egroup - \cartbot - \egroup - \checkinserts -} + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup +\endgroup +}} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak + \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \let\par = \lisppar % don't ignore blank lines @@ -4829,99 +4632,103 @@ where each line of input produces a line \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax \fi - \let\exdent=\nofillexdent } -% If you want all examples etc. small: @set dispenvsize small. -% If you want even small examples the full size: @set dispenvsize nosmall. -% This affects the following displayed environments: -% @example, @display, @format, @lisp +% Define the \E... control sequence only if we are inside the particular +% environment, so the error checking in \end will work. % -\def\smallword{small} -\def\nosmallword{nosmall} -\let\SETdispenvsize\relax -\def\setnormaldispenv{% - \ifx\SETdispenvsize\smallword - \smallexamplefonts \rm - \fi -} -\def\setsmalldispenv{% - \ifx\SETdispenvsize\nosmallword - \else - \smallexamplefonts \rm - \fi -} +% To end an @example-like environment, we first end the paragraph (via +% \afterenvbreak's vertical glue), and then the group. That way we keep +% the zero \parskip that the environments set -- \parskip glue will be +% inserted at the beginning of the next paragraph in the document, after +% the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup} -% We often define two environments, @foo and @smallfoo. -% Let's do it by one command: -\def\makedispenv #1#2{ - \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2} - \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2} - \expandafter\let\csname E#1\endcsname \afterenvbreak - \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +% @lisp: indented, narrowed, typewriter font. +\def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return } -% Define two synonyms: -\def\maketwodispenvs #1#2#3{ - \makedispenv{#1}{#3} - \makedispenv{#2}{#3} -} +% @example: Same as @lisp. +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} -% @lisp: indented, narrowed, typewriter font; @example: same as @lisp. -% % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. -% -\maketwodispenvs {lisp}{example}{% - \nonfillstart - \tt - \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return +\def\smalllisp{\begingroup + \def\Esmalllisp{\nonfillfinish\endgroup}% + \def\Esmallexample{\nonfillfinish\endgroup}% + \smallexamplefonts + \lisp } +\let\smallexample = \smalllisp + -% @display/@smalldisplay: same as @lisp except keep current font. +% @display: same as @lisp except keep current font. % -\makedispenv {display}{% +\def\display{\begingroup \nonfillstart + \let\Edisplay = \nonfillfinish \gobble } - -% @format/@smallformat: same as @display except don't narrow margins. % -\makedispenv{format}{% - \let\nonarrowing = t% - \nonfillstart - \gobble +% @smalldisplay: @display plus smaller fonts. +% +\def\smalldisplay{\begingroup + \def\Esmalldisplay{\nonfillfinish\endgroup}% + \smallexamplefonts \rm + \display } -% @flushleft: same as @format, but doesn't obey \SETdispenvsize. -\envdef\flushleft{% - \let\nonarrowing = t% +% @format: same as @display except don't narrow margins. +% +\def\format{\begingroup + \let\nonarrowing = t \nonfillstart + \let\Eformat = \nonfillfinish \gobble } -\let\Eflushleft = \afterenvbreak +% +% @smallformat: @format plus smaller fonts. +% +\def\smallformat{\begingroup + \def\Esmallformat{\nonfillfinish\endgroup}% + \smallexamplefonts \rm + \format +} + +% @flushleft (same as @format). +% +\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % -\envdef\flushright{% - \let\nonarrowing = t% +\def\flushright{\begingroup + \let\nonarrowing = t \nonfillstart + \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } -\let\Eflushright = \afterenvbreak % @quotation does normal linebreaking (hence we can't use \nonfillstart) -% and narrows the margins. We keep \parskip nonzero in general, since -% we're doing normal filling. So, when using \aboveenvbreak and -% \afterenvbreak, temporarily make \parskip 0. +% and narrows the margins. % -\envdef\quotation{% +\def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax @@ -4930,27 +4737,6 @@ where each line of input produces a line \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi - \parsearg\quotationlabel -} - -% We have retained a nonzero parskip for the environment, since we're -% doing normal filling. -% -\def\Equotation{% - \par - \ifx\quotationauthor\undefined\else - % indent a bit. - \leftline{\kern 2\leftskip \sl ---\quotationauthor}% - \fi - {\parskip=0pt \afterenvbreak}% -} - -% If we're given an argument, typeset it in bold with a colon after. -\def\quotationlabel#1{% - \def\temp{#1}% - \ifx\temp\empty \else - {\bf #1: }% - \fi } @@ -4972,7 +4758,7 @@ where each line of input produces a line % % [Knuth] p. 380 \def\uncatcodespecials{% - \def\do##1{\catcode`##1=\other}\dospecials} + \def\do##1{\catcode`##1=12}\dospecials} % % [Knuth] pp. 380,381,391 % Disable Spanish ligatures ?` and !` of \tt font @@ -5020,8 +4806,6 @@ where each line of input produces a line } \endgroup \def\setupverbatim{% - \nonfillstart - \advance\leftskip by -\defbodyindent % Easiest (and conventionally used) font for verbatim \tt \def\par{\leavevmode\egroup\box0\endgraf}% @@ -5043,7 +4827,7 @@ where each line of input produces a line % % [Knuth] p. 382; only eat outer {} \begingroup - \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12 \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] \endgroup % @@ -5060,6 +4844,13 @@ where each line of input produces a line % we need not redefine '\', '{' and '}'. % % Inspired by LaTeX's verbatim command set [latex.ltx] +%% Include LaTeX hack for completeness -- never know +%% \begingroup +%% \catcode`|=0 \catcode`[=1 +%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active +%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ +%% #1|endgroup|def|Everbatim[]|end[verbatim]] +%% |endgroup % \begingroup \catcode`\ =\active @@ -5067,32 +4858,54 @@ where each line of input produces a line % ignore everything up to the first ^^M, that's the newline at the end % of the @verbatim input line itself. Otherwise we get an extra blank % line in the output. - \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% - % We really want {...\end verbatim} in the body of the macro, but - % without the active space; thus we have to use \xdef and \gobble. + \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% \endgroup % -\envdef\verbatim{% - \setupverbatim\doverbatim +\def\verbatim{% + \def\Everbatim{\nonfillfinish\endgroup}% + \begingroup + \nonfillstart + \advance\leftskip by -\defbodyindent + \begingroup\setupverbatim\doverbatim } -\let\Everbatim = \afterenvbreak - % @verbatiminclude FILE - insert text of file in verbatim environment. % -\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +% Allow normal characters that we make active in the argument (a file name). +\def\verbatiminclude{% + \begingroup + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \parsearg\doverbatiminclude +} +\def\setupverbatiminclude{% + \begingroup + \nonfillstart + \advance\leftskip by -\defbodyindent + \begingroup\setupverbatim +} % \def\doverbatiminclude#1{% - {% - \makevalueexpandable - \setupverbatim - \input #1 - \afterenvbreak - }% + % Restore active chars for included file. + \endgroup + \begingroup + \let\value=\expandablevalue + \def\thisfile{#1}% + \expandafter\expandafter\setupverbatiminclude\input\thisfile + \endgroup + \nonfillfinish + \endgroup } % @copying ... @end copying. -% Save the text away for @insertcopying later. +% Save the text away for @insertcopying later. Many commands won't be +% allowed in this context, but that's ok. % % We save the uninterpreted tokens, rather than creating a box. % Saving the text in a box would be much easier, but then all the @@ -5101,392 +4914,670 @@ where each line of input produces a line % file; b) letting users define the frontmatter in as flexible order as % possible is very desirable. % -\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} -\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} -% -\def\insertcopying{% - \begingroup - \parindent = 0pt % paragraph indentation looks wrong on title page - \scanexp\copyingtext - \endgroup +\def\copying{\begingroup + % Define a command to swallow text until we reach `@end copying'. + % \ is the escape char in this texinfo.tex file, so it is the + % delimiter for the command; @ will be the escape char when we read + % it, but that doesn't matter. + \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% + % + % We must preserve ^^M's in the input file; see \insertcopying below. + \catcode`\^^M = \active + \docopying +} + +% What we do to finish off the copying text. +% +\def\enddocopying{\endgroup\ignorespaces} + +% @insertcopying. Here we must play games with ^^M's. On the one hand, +% we need them to delimit commands such as `@end quotation', so they +% must be active. On the other hand, we certainly don't want every +% end-of-line to be a \par, as would happen with the normal active +% definition of ^^M. On the third hand, two ^^M's in a row should still +% generate a \par. +% +% Our approach is to make ^^M insert a space and a penalty1 normally; +% then it can also check if \lastpenalty=1. If it does, then manually +% do \par. +% +% This messes up the normal definitions of @c[omment], so we redefine +% it. Similarly for @ignore. (These commands are used in the gcc +% manual for man page generation.) +% +% Seems pretty fragile, most line-oriented commands will presumably +% fail, but for the limited use of getting the copying text (which +% should be quite simple) inserted, we can hope it's ok. +% +{\catcode`\^^M=\active % +\gdef\insertcopying{\begingroup % + \parindent = 0pt % looks wrong on title page + \def^^M{% + \ifnum \lastpenalty=1 % + \par % + \else % + \space \penalty 1 % + \fi % + }% + % + % Fix @c[omment] for catcode 13 ^^M's. + \def\c##1^^M{\ignorespaces}% + \let\comment = \c % + % + % Don't bother jumping through all the hoops that \doignore does, it + % would be very hard since the catcodes are already set. + \long\def\ignore##1\end ignore{\ignorespaces}% + % + \copyingtext % +\endgroup}% } \message{defuns,} % @defun etc. +% Allow user to change definition object font (\df) internally +\def\setdeffont#1 {\csname DEF#1\endcsname} + \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deflastargmargin \deflastargmargin=18pt -% Start the processing of @deffn: -\def\startdefun{% - \ifnum\lastpenalty<10000 - \medbreak +\newcount\parencount + +% We want ()&[] to print specially on the defun line. +% +\def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\&=\active + \catcode`\[=\active \catcode`\]=\active +} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested + \global\advance\parencount by 1 +} +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } +\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } +\let\ampnr = \& +\def\lbrb{{\bf\char`\[}} +\def\rbrb{{\bf\char`\]}} + +% Active &'s sneak into the index arguments, so make sure it's defined. +{ + \catcode`& = \active + \global\let& = \ampnr +} + +% \defname, which formats the name of the @def (not the args). +% #1 is the function name. +% #2 is the type of definition, such as "Function". +% +\def\defname#1#2{% + % How we'll output the type name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \ifempty{#2}% + \def\defnametype{}% \else - % If there are two @def commands in a row, we'll have a \nobreak, - % which is there to keep the function description together with its - % header. But if there's nothing but headers, we need to allow a - % break somewhere. Check specifically for penalty 10002, inserted - % by \defargscommonending, instead of 10000, since the sectioning - % commands also insert a nobreak penalty, and we don't want to allow - % a break between a section heading and a defun. - % - \ifnum\lastpenalty=10002 \penalty2000 \fi - % - % Similarly, after a section heading, do not allow a break. - % But do insert the glue. - \medskip % preceded by discardable penalty, so not a breakpoint + \def\defnametype{[\rm #2]}% \fi % + % Get the values of \leftskip and \rightskip as they were outside the @def... + \dimen2=\leftskip + \advance\dimen2 by -\defbodyindent + % + % Figure out values for the paragraph shape. + \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% + \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line + \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations + \parshape 2 0in \dimen0 \defargsindent \dimen1 + % + % Output arg 2 ("Function" or some such) but stuck inside a box of + % width 0 so it does not interfere with linebreaking. + \noindent + % + {% Adjust \hsize to exclude the ambient margins, + % so that \rightline will obey them. + \advance \hsize by -\dimen2 + \dimen3 = 0pt % was -1.25pc + \rlap{\rightline{\defnametype\kern\dimen3}}% + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \advance\leftskip by -\defbodyindent + \exdentamount=\defbodyindent + {\df #1}\enskip % output function name + % \defunargs will be called next to output the arguments, if any. +} + +% Common pieces to start any @def... +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence (which our caller defines). +% #3 is the control sequence to process the header, such as \defunheader. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we want to allow a + % break after all. Check for penalty 10002 (inserted by + % \defargscommonending) instead of 10000, since the sectioning + % commands insert a \penalty10000, and we don't want to allow a break + % between a section heading and a defun. + \ifnum\lastpenalty=10002 \penalty0 \fi + \medbreak + % + % Define the \E... end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + % \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent } -\def\dodefunx#1{% - % First, check whether we are in the right environment: - \checkenv#1% - % - % As above, allow line break if we have multiple x headers in a row. - % It's not a great place, though. - \ifnum\lastpenalty=10002 \penalty3000 \fi +% Common part of the \...x definitions. +% +\def\defxbodycommon{% + % As with \parsebodycommon above, allow line break if we have multiple + % x headers in a row. It's not a great place, though. + \ifnum\lastpenalty=10000 \penalty1000 \fi % - % And now, it's time to reuse the body of the original defun: - \expandafter\gobbledefun#1% + \begingroup\obeylines } -\def\gobbledefun#1\startdefun{} -% \printdefunline \deffnheader{text} +% Process body of @defun, @deffn, @defmac, etc. % -\def\printdefunline#1#2{% - \begingroup - % call \deffnheader: - #1#2 \endheader - % common ending: - \interlinepenalty = 10000 - \advance\rightskip by 0pt plus 1fil - \endgraf - \nobreak\vskip -\parskip - \penalty 10002 % signal to \startdefun and \dodefunx - % Some of the @defun-type tags do not enable magic parentheses, - % rendering the following check redundant. But we don't optimize. - \checkparencounts - \endgroup +\def\defparsebody#1#2#3{% + \parsebodycommon{#1}{#2}{#3}% + \def#2{\defxbodycommon \activeparens \spacesplit#3}% + \catcode\equalChar=\active + \begingroup\obeylines\activeparens + \spacesplit#3% } -\def\Edefun{\endgraf\medbreak} - -% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; -% the only thing remainnig is to define \deffnheader. +% #1, #2, #3 are the common arguments (see \parsebodycommon above). +% #4, delimited by the space, is the class name. % -\def\makedefun#1{% - \expandafter\let\csname E#1\endcsname = \Edefun - \edef\temp{\noexpand\domakedefun - \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% - \temp +\def\defmethparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% + \begingroup\obeylines\activeparens + % The \empty here prevents misinterpretation of a construct such as + % @deffn {whatever} {Enharmonic comma} + % See comments at \deftpparsebody, although in our case we don't have + % to remove the \empty afterwards, since it is empty. + \spacesplit{#3{#4}}\empty } -% \domakedefun \deffn \deffnx \deffnheader +% Used for @deftypemethod and @deftypeivar. +% #1, #2, #3 are the common arguments (see \defparsebody). +% #4, delimited by a space, is the class name. +% #5 is the method's return type. % -% Define \deffn and \deffnx, without parameters. -% \deffnheader has to be defined explicitly. +\def\deftypemethparsebody#1#2#3#4 #5 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% + \begingroup\obeylines\activeparens + \spacesplit{#3{#4}{#5}}% +} + +% Used for @deftypeop. The change from \deftypemethparsebody is an +% extra argument at the beginning which is the `category', instead of it +% being the hardwired string `Method' or `Instance Variable'. We have +% to account for this both in the \...x definition and in parsing the +% input at hand. Thus also need a control sequence (passed as #5) for +% the \E... definition to assign the category name to. % -\def\domakedefun#1#2#3{% - \envdef#1{% - \startdefun - \parseargusing\activeparens{\printdefunline#3}% - }% - \def#2{\dodefunx#1}% - \def#3% +\def\deftypeopparsebody#1#2#3#4#5 #6 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 ##3 {\def#4{##1}% + \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% + \begingroup\obeylines\activeparens + \spacesplit{#3{#5}{#6}}% } -%%% Untyped functions: +% For @defop. +\def\defopparsebody #1#2#3#4#5 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 {\def#4{##1}% + \defxbodycommon \activeparens \spacesplit{#3{##2}}}% + \begingroup\obeylines\activeparens + \spacesplit{#3{#5}}% +} -% @deffn category name args -\makedefun{deffn}{\deffngeneral{}} +% These parsing functions are similar to the preceding ones +% except that they do not make parens into active characters. +% These are used for "variables" since they have no arguments. +% +\def\defvarparsebody #1#2#3{% + \parsebodycommon{#1}{#2}{#3}% + \def#2{\defxbodycommon \spacesplit#3}% + \catcode\equalChar=\active + \begingroup\obeylines + \spacesplit#3% +} -% @deffn category class name args -\makedefun{defop}#1 {\defopon{#1\ \putwordon}} +% @defopvar. +\def\defopvarparsebody #1#2#3#4#5 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 {\def#4{##1}% + \defxbodycommon \spacesplit{#3{##2}}}% + \begingroup\obeylines + \spacesplit{#3{#5}}% +} -% \defopon {category on}class name args -\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% + \begingroup\obeylines + \spacesplit{#3{#4}}% +} -% \deffngeneral {subind}category name args +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody % -\def\deffngeneral#1#2 #3 #4\endheader{% - % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. - \dosubind{fn}{\code{#3}}{#1}% - \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% + \begingroup\obeylines + \spacesplit{\parsetpheaderline{#3{#4}}}\empty } -%%% Typed functions: +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does. +% +\def\removeemptybraces\empty#1\relax{#1} + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + #1{\removeemptybraces#2\relax}{#3}% +}% -% @deftypefn category type name args -\makedefun{deftypefn}{\deftypefngeneral{}} +% Split up #2 (the rest of the input line) at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. +% +{\obeylines % + \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% + \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% + \ifx\relax #3% + #1{#2}{}% + \else % + #1{#2}{#3#4}% + \fi}% +} -% @deftypeop category class type name args -\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} +% Define @defun. -% \deftypeopon {category on}class type name args -\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } +% This is called to end the arguments processing for all the @def... commands. +% +\def\defargscommonending{% + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil + \endgraf + \nobreak\vskip -\parskip + \penalty 10002 % signal to \parsebodycommon. +} -% \deftypefngeneral {subind}category type name args +% This expands the args and terminates the paragraph they comprise. % -\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% - \dosubind{fn}{\code{#4}}{#1}% - \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +\def\defunargs#1{\functionparens \sl +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Set the font temporarily and use \font in case \setfont made \tensl a macro. +{\tensl\hyphenchar\font=0}% +#1% +{\tensl\hyphenchar\font=45}% +\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% + \defargscommonending } -%%% Typed variables: +\def\deftypefunargs #1{% +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars + \defargscommonending +} -% @deftypevr category type var args -\makedefun{deftypevr}{\deftypecvgeneral{}} +% Do complete processing of one @defun or @defunx line already parsed. -% @deftypecv category class type var args -\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} +% @deffn Command forward-char nchars -% \deftypecvof {category of}class type var args -\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} -% \deftypecvgeneral {subind}category type var args -% -\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% - \dosubind{vr}{\code{#4}}{#1}% - \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody } -%%% Untyped variables: +% @defun == @deffn Function -% @defvr category var args -\makedefun{defvr}#1 {\deftypevrheader{#1} {} } +\def\defun{\defparsebody\Edefun\defunx\defunheader} -% @defcv category class var args -\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDeffunc}% +\defunargs {#2}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody +} + +% @deftypefun int foobar (int @var{foo}, float @var{bar}) -% \defcvof {category of}class var args -\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } +\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} -%%% Type: -% @deftp category name args -\makedefun{deftp}#1 #2 #3\endheader{% - \doind{tp}{\code{#2}}% - \defname{#1}{}{#2}\defunargs{#3\unskip}% +% #1 is the data type. #2 is the name and args. +\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} +% #1 is the data type, #2 the name, #3 the args. +\def\deftypefunheaderx #1#2 #3\relax{% +\doind {fn}{\code{#2}}% Make entry in function index +\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% +\deftypefunargs {#3}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody } -% Remaining @defun-like shortcuts: -\makedefun{defun}{\deffnheader{\putwordDeffunc} } -\makedefun{defmac}{\deffnheader{\putwordDefmac} } -\makedefun{defspec}{\deffnheader{\putwordDefspec} } -\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } -\makedefun{defvar}{\defvrheader{\putwordDefvar} } -\makedefun{defopt}{\defvrheader{\putwordDefopt} } -\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } -\makedefun{defmethod}{\defopon\putwordMethodon} -\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} -\makedefun{defivar}{\defcvof\putwordInstanceVariableof} -\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} +% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) -% \defname, which formats the name of the @def (not the args). -% #1 is the category, such as "Function". -% #2 is the return type, if any. -% #3 is the function name. -% -% We are followed by (but not passed) the arguments, if any. -% -\def\defname#1#2#3{% - % Get the values of \leftskip and \rightskip as they were outside the @def... - \advance\leftskip by -\defbodyindent - % - % How we'll format the type name. Putting it in brackets helps - % distinguish it from the body text that may end up on the next line - % just below it. - \def\temp{#1}% - \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} - % - % Figure out line sizes for the paragraph shape. - % The first line needs space for \box0; but if \rightskip is nonzero, - % we need only space for the part of \box0 which exceeds it: - \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip - % The continuations: - \dimen2=\hsize \advance\dimen2 by -\defargsindent - % (plain.tex says that \dimen1 should be used only as global.) - \parshape 2 0in \dimen0 \defargsindent \dimen2 - % - % Put the type name to the right margin. - \noindent - \hbox to 0pt{% - \hfil\box0 \kern-\hsize - % \hsize has to be shortened this way: - \kern\leftskip - % Intentionally do not respect \rightskip, since we need the space. - }% - % - % Allow all lines to be underfull without complaint: - \tolerance=10000 \hbadness=10000 - \exdentamount=\defbodyindent - {% - % defun fonts. We use typewriter by default (used to be bold) because: - % . we're printing identifiers, they should be in tt in principle. - % . in languages with many accents, such as Czech or French, it's - % common to leave accents off identifiers. The result looks ok in - % tt, but exceedingly strange in rm. - % . we don't want -- and --- to be treated as ligatures. - % . this still does not fix the ?` and !` ligatures, but so far no - % one has made identifiers using them :). - \df \tt - \def\temp{#2}% return value type - \ifx\temp\empty\else \tclose{\temp} \fi - #3% output function name - }% - {\rm\enskip}% hskip 0.5 em of \tenrm - % - \boldbrax - % arguments will be output next, if any. -} +\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} -% Print arguments in slanted roman (not ttsl), inconsistently with using -% tt for the name. This is because literal text is sometimes needed in -% the argument list (groff manual), and ttsl and tt are not very -% distinguishable. Prevent hyphenation at `-' chars. -% -\def\defunargs#1{% - % use sl by default (not ttsl), - % tt for the names. - \df \sl \hyphenchar\font=0 - % - % On the other hand, if an argument has two dashes (for instance), we - % want a way to get ttsl. Let's try @var for that. - \let\var=\ttslanted - #1% - \sl\hyphenchar\font=45 -} +% \defheaderxcond#1\relax$.$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} -% We want ()&[] to print specially on the defun line. -% -\def\activeparens{% - \catcode`\(=\active \catcode`\)=\active - \catcode`\[=\active \catcode`\]=\active - \catcode`\&=\active +% #1 is the classification. #2 is the data type. #3 is the name and args. +\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} +% #1 is the classification, #2 the data type, #3 the name, #4 the args. +\def\deftypefnheaderx #1#2#3 #4\relax{% +\doind {fn}{\code{#3}}% Make entry in function index +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$.$#3}{#1}% +\deftypefunargs {#4}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody } -% Make control sequences which act like normal parenthesis chars. -\let\lparen = ( \let\rparen = ) +% @defmac == @deffn Macro -% Be sure that we always have a definition for `(', etc. For example, -% if the fn name has parens in it, \boldbrax will not be in effect yet, -% so TeX would otherwise complain about undefined control sequence. -{ - \activeparens - \global\let(=\lparen \global\let)=\rparen - \global\let[=\lbrack \global\let]=\rbrack - \global\let& = \& +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} - \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} - \gdef\magicamp{\let&=\amprm} +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefmac}% +\defunargs {#2}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody } -\newcount\parencount +% @defspec == @deffn Special Form -% If we encounter &foo, then turn on ()-hacking afterwards -\newif\ifampseen -\def\amprm#1 {\ampseentrue{\bf\ }} +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} -\def\parenfont{% - \ifampseen - % At the first level, print parens in roman, - % otherwise use the default font. - \ifnum \parencount=1 \rm \fi - \else - % The \sf parens (in \boldbrax) actually are a little bolder than - % the contained text. This is especially needed for [ and ] . - \sf - \fi +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefspec}% +\defunargs {#2}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody } -\def\infirstlevel#1{% - \ifampseen - \ifnum\parencount=1 - #1% - \fi - \fi + +% @defop CATEGORY CLASS OPERATION ARG... +% +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} +% +\def\defopheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry + \begingroup + \defname{#2}{\defoptype\ \putwordon\ #1}% + \defunargs{#3}% + \endgroup } -\def\bfafterword#1 {#1 \bf} -\def\opnr{% - \global\advance\parencount by 1 - {\parenfont(}% - \infirstlevel \bfafterword +% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... +% +\def\deftypeop #1 {\def\deftypeopcategory{#1}% + \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader + \deftypeopcategory} +% +% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. +\def\deftypeopheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$.$#3} + {\deftypeopcategory\ \putwordon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup } -\def\clnr{% - {\parenfont)}% - \infirstlevel \sl - \global\advance\parencount by -1 + +% @deftypemethod CLASS TYPE METHOD ARG... +% +\def\deftypemethod{% + \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} +% +% #1 is the class name, #2 the data type, #3 the method name, #4 the args. +\def\deftypemethodheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup } -\newcount\brackcount -\def\lbrb{% - \global\advance\brackcount by 1 - {\bf[}% +% @deftypeivar CLASS TYPE VARNAME +% +\def\deftypeivar{% + \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} +% +% #1 is the class name, #2 the data type, #3 the variable name. +\def\deftypeivarheader#1#2#3{% + \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index + \begingroup + \defname{\defheaderxcond#2\relax$.$#3} + {\putwordInstanceVariableof\ \code{#1}}% + \defvarargs{#3}% + \endgroup } -\def\rbrb{% - {\bf]}% - \global\advance\brackcount by -1 + +% @defmethod == @defop Method +% +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} +% +% #1 is the class name, #2 the method name, #3 the args. +\def\defmethodheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{#2}{\putwordMethodon\ \code{#1}}% + \defunargs{#3}% + \endgroup } -\def\checkparencounts{% - \ifnum\parencount=0 \else \badparencount \fi - \ifnum\brackcount=0 \else \badbrackcount \fi +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + +\def\defcvarheader #1#2#3{% + \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry + \begingroup + \defname{#2}{\defcvtype\ \putwordof\ #1}% + \defvarargs{#3}% + \endgroup } -\def\badparencount{% - \errmessage{Unbalanced parentheses in @def}% - \global\parencount=0 + +% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME +% +\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} +% +\def\defivarheader#1#2#3{% + \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index + \begingroup + \defname{#2}{\putwordInstanceVariableof\ #1}% + \defvarargs{#3}% + \endgroup } -\def\badbrackcount{% - \errmessage{Unbalanced square braces in @def}% - \global\brackcount=0 + +% @defvar +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% + \defargscommonending } +% @defvr Counter foo-count -\message{macros,} -% @macro. +\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} -% To do this right we need a feature of e-TeX, \scantokens, -% which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\undefined - \newwrite\macscribble - \def\scantokens#1{% - \toks0={#1}% - \immediate\openout\macscribble=\jobname.tmp - \immediate\write\macscribble{\the\toks0}% - \immediate\closeout\macscribble - \input \jobname.tmp - } -\fi +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} -\def\scanmacro#1{% - \begingroup - \newlinechar`\^^M - \let\xeatspaces\eatspaces - % Undo catcode changes of \startcontents and \doprintindex - % When called from @insertcopying or (short)caption, we need active - % backslash to get it printed correctly. Previously, we had - % \catcode`\\=\other instead. We'll see whether a problem appears - % with macro expansion. --kasal, 19aug04 - \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ - % ... and \example - \spaceisspace - % - % Append \endinput to make sure that TeX does not see the ending newline. - % - % I've verified that it is necessary both for e-TeX and for ordinary TeX - % --kasal, 29nov03 - \scantokens{#1\endinput}% - \endgroup +% @defvar == @defvr Variable + +\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefvar}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefopt}% +\defvarargs {#2}\endgroup % } -\def\scanexp#1{% - \edef\temp{\noexpand\scanmacro{#1}}% - \temp +% @deftypevar int foobar + +\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + +% #1 is the data type. #2 is the name, perhaps followed by text that +% is actually part of the data type, which should not be put into the index. +\def\deftypevarheader #1#2{% +\dovarind#2 \relax% Make entry in variables index +\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% + \defargscommonending +\endgroup} +\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} + +% @deftypevr {Global Flag} int enable + +\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + +\def\deftypevrheader #1#2#3{\dovarind#3 \relax% +\begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} + \defargscommonending +\endgroup} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% These definitions are used if you use @defunx (etc.) +% anywhere other than immediately after a @defun or @defunx. +% +\def\defcvx#1 {\errmessage{@defcvx in invalid context}} +\def\deffnx#1 {\errmessage{@deffnx in invalid context}} +\def\defivarx#1 {\errmessage{@defivarx in invalid context}} +\def\defmacx#1 {\errmessage{@defmacx in invalid context}} +\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} +\def\defopx#1 {\errmessage{@defopx in invalid context}} +\def\defspecx#1 {\errmessage{@defspecx in invalid context}} +\def\deftpx#1 {\errmessage{@deftpx in invalid context}} +\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} +\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} +\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} +\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} +\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} +\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} +\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} +\def\defunx#1 {\errmessage{@defunx in invalid context}} +\def\defvarx#1 {\errmessage{@defvarx in invalid context}} +\def\defvrx#1 {\errmessage{@defvrx in invalid context}} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\undefined + \newwrite\macscribble + \def\scanmacro#1{% + \begingroup \newlinechar`\^^M + % Undo catcode changes of \startcontents and \doprintindex + \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ + % Append \endinput to make sure that TeX does not see the ending newline. + \toks0={#1\endinput}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \let\xeatspaces\eatspaces + \input \jobname.tmp + \endgroup } +\else +\def\scanmacro#1{% +\begingroup \newlinechar`\^^M +% Undo catcode changes of \startcontents and \doprintindex +\catcode`\@=0 \catcode`\\=\other \escapechar=`\@ +\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} +\fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name @@ -5495,15 +5586,13 @@ where each line of input produces a line % \do\macro1\do\macro2... % Utility routines. -% This does \let #1 = #2, with \csnames; that is, -% \let \csname#1\endcsname = \csname#2\endcsname -% (except of course we have to play expansion games). -% +% Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% - \expandafter\let - \csname#1\expandafter\endcsname - \csname#2\endcsname -} +\expandafter\expandafter +\expandafter\let +\expandafter\expandafter +\csname#1\endcsname +\csname#2\endcsname} % Trim leading and trailing spaces off a string. % Concepts from aro-bend problem 15 (see CTAN). @@ -5530,36 +5619,30 @@ where each line of input produces a line % done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. -\def\scanctxt{% - \catcode`\"=\other - \catcode`\+=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\@=\other +\def\macrobodyctxt{% + \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other - \catcode`\~=\other -} - -\def\scanargctxt{% - \scanctxt - \catcode`\\=\other - \catcode`\^^M=\other -} - -\def\macrobodyctxt{% - \scanctxt + \catcode`\<=\other + \catcode`\>=\other + \catcode`\+=\other \catcode`\{=\other \catcode`\}=\other + \catcode`\@=\other \catcode`\^^M=\other - \usembodybackslash -} + \usembodybackslash} \def\macroargctxt{% - \scanctxt - \catcode`\\=\other -} + \catcode`\~=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\+=\other + \catcode`\@=\other + \catcode`\\=\other} % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N @@ -5600,7 +5683,8 @@ where each line of input produces a line \else \expandafter\parsemacbody \fi} -\parseargdef\unmacro{% +\def\unmacro{\parsearg\dounmacro} +\def\dounmacro#1{% \if1\csname ismacro.#1\endcsname \global\cslet{#1}{macsave.#1}% \global\expandafter\let \csname ismacro.#1\endcsname=0% @@ -5741,41 +5825,25 @@ where each line of input produces a line \expandafter\parsearg \fi \next} -% We want to disable all macros during \shipout so that they are not +% We mant to disable all macros during \shipout so that they are not % expanded by \write. \def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% \edef\next{\macrolist}\expandafter\endgroup\next} -% For \indexnofonts, we need to get rid of all macros, leaving only the -% arguments (if present). Of course this is not nearly correct, but it -% is the best we can do for now. makeinfo does not expand macros in the -% argument to @deffn, which ends up writing an index entry, and texindex -% isn't prepared for an index sort entry that starts with \. -% -% Since macro invocations are followed by braces, we can just redefine them -% to take a single TeX argument. The case of a macro invocation that -% goes to end-of-line is not handled. -% -\def\emptyusermacros{\begingroup - \def\do##1{\let\noexpand##1=\noexpand\asis}% - \edef\next{\macrolist}\expandafter\endgroup\next} - % @alias. % We need some trickery to remove the optional spaces around the equal % sign. Just make them active and then expand them all to nothing. -\def\alias{\parseargusing\obeyspaces\aliasxxx} +\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} -\def\aliasyyy #1=#2\relax{% - {% - \expandafter\let\obeyedspace=\empty - \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% - }% - \next -} +\def\aliasyyy #1=#2\relax{\ignoreactivespaces +\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% + \expandafter\noexpand\csname#2\endcsname}% +\expandafter\endgroup\next} \message{cross references,} +% @xref etc. \newwrite\auxfile @@ -5787,70 +5855,64 @@ where each line of input produces a line \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} -% @node's only job in TeX is to define \lastnode, which is used in -% cross-references. The @node line might or might not have commas, and -% might or might not have spaces before the first comma, like: -% @node foo , bar , ... -% We don't want such trailing spaces in the node name. -% -\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} -% -% also remove a trailing comma, in case of something like this: -% @node Help-Cross, , , Cross-refs -\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} -\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} - +% @node's job is to define \lastnode. +\def\node{\ENVcheck\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx #1,\finishnodeparse} +\def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} \let\nwnode=\node -\let\lastnode=\empty +\let\lastnode=\relax -% Write a cross-reference definition for the current node. #1 is the -% type (Ynumbered, Yappendix, Ynothing). -% -\def\donoderef#1{% - \ifx\lastnode\empty\else - \setref{\lastnode}{#1}% - \global\let\lastnode=\empty +% The sectioning commands (@chapter, etc.) call these. +\def\donoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Ysectionnumberandtype}% + \global\let\lastnode=\relax + \fi +} +\def\unnumbnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% + \global\let\lastnode=\relax + \fi +} +\def\appendixnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Yappendixletterandtype}% + \global\let\lastnode=\relax \fi } + % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister -% -\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} -\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} -\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} +\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} % \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an -% anchor), which consists of three parts: -% 1) NAME-title - the current sectioning name taken from \thissection, -% or the anchor name. -% 2) NAME-snt - section number and type, passed as the SNT arg, or -% empty for anchors. -% 3) NAME-pg - the page number. -% -% This is called from \donoderef, \anchor, and \dofloat. In the case of -% floats, there is an additional part, which is not written here: -% 4) NAME-lof - the text as it should appear in a @listoffloats. +% anchor), namely NAME-title (the corresponding @chapter/etc. name), +% NAME-pg (the page number), and NAME-snt (section number and type). +% Called from \foonoderef. +% +% We have to set \indexdummies so commands such as @code in a section +% title aren't expanded. It would be nicer not to expand the titles in +% the first place, but there's so many layers that that is hard to do. +% +% Likewise, use \turnoffactive so that punctuation chars such as underscore +% and backslash work in node names. % -\def\setref#1#2{% +\def\setref#1#2{{% + \atdummies \pdfmkdest{#1}% - \iflinks - {% - \atdummies % preserve commands, but don't expand them - \turnoffactive - \otherbackslash - \edef\writexrdef##1##2{% - \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef - ##1}{##2}}% these are parameters of \writexrdef - }% - \toks0 = \expandafter{\thissection}% - \immediate \writexrdef{title}{\the\toks0 }% - \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. - \writexrdef{pg}{\folio}% will be written later, during \shipout - }% - \fi -} + % + \turnoffactive + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{#2}% +}} % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed @@ -5863,33 +5925,38 @@ where each line of input produces a line \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces \def\printedmanual{\ignorespaces #5}% - \def\printedrefname{\ignorespaces #3}% - \setbox1=\hbox{\printedmanual\unskip}% - \setbox0=\hbox{\printedrefname\unskip}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. - \def\printedrefname{\ignorespaces #1}% + \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. - \def\printedrefname{\ignorespaces #1}% + \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. - \def\printedrefname{\refx{#1-title}{}}% + \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. - \def\printedrefname{\ignorespaces #1}% + \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % - % Make link in pdf output. + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. \ifpdf \leavevmode \getfilename{#4}% @@ -5899,86 +5966,64 @@ where each line of input produces a line goto file{\the\filename.pdf} name{#1}% \else \startlink attr{/Border [0 0 0]}% - goto name{\pdfmkpgn{#1}}% + goto name{#1}% \fi }% \linkcolor \fi % - % Float references are printed completely differently: "Figure 1.2" - % instead of "[somenode], p.3". We distinguish them by the - % LABEL-title being set to a magic string. - {% - % Have to otherify everything special to allow the \csname to - % include an _ in the xref name, etc. - \indexnofonts - \turnoffactive - \otherbackslash - \expandafter\global\expandafter\let\expandafter\Xthisreftitle - \csname XR#1-title\endcsname - }% - \iffloat\Xthisreftitle - % If the user specified the print name (third arg) to the ref, - % print it instead of our usual "Figure 1.2". - \ifdim\wd0 = 0pt - \refx{#1-snt}% - \else - \printedrefname - \fi - % - % if the user also gave the printed manual name (fifth arg), append - % "in MANUALNAME". - \ifdim \wd1 > 0pt - \space \putwordin{} \cite{\printedmanual}% - \fi + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% \else - % node/anchor (non-float) references. + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive \otherbackslash + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via a macro. + \xrefprintnodename\printednodename % - % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not - % insert empty discretionaries after hyphens, which means that it will - % not find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, this - % is a loss. Therefore, we give the text of the node name again, so it - % is as if TeX is seeing it for the first time. - \ifdim \wd1 > 0pt - \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}% - \else - % _ (for example) has to be the character _ for the purposes of the - % control sequence corresponding to the node, but it has to expand - % into the usual \leavevmode...\vrule stuff for purposes of - % printing. So we \turnoffactive for the \refx-snt, back on for the - % printing, back off for the \refx-pg. - {\turnoffactive \otherbackslash - % Only output a following space if the -snt ref is nonempty; for - % @unnumbered and @anchor, it won't be. - \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% - \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi - }% - % output the `[mynode]' via a macro so it can be overridden. - \xrefprintnodename\printedrefname - % - % But we always want a comma and a space: - ,\space - % - % output the `page 3'. - \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% - \fi + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% \fi \endlink \endgroup} % This macro is called from \xrefX for the `[nodename]' part of xref % output. It's a separate macro only so it can be changed more easily, -% since square brackets don't work well in some documents. Particularly +% since not square brackets don't work in some documents. Particularly % one that Bob is working on :). % \def\xrefprintnodename#1{[#1]} -% Things referred to by \setref. +% \dosetq is called from \setref to do the actual \write (\iflinks). +% +\def\dosetq#1#2{% + {\let\folio=0% + \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% + \iflinks \next \fi + }% +} + +% \internalsetq{foo}{page} expands into +% CHARACTERS @xrdef{foo}{...expansion of \page...} +\def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq. % +\def\Ypagenumber{\folio} +\def\Ytitle{\thissection} \def\Ynothing{} -\def\Yomitfromtoc{} -\def\Ynumbered{% +\def\Ysectionnumberandtype{% \ifnum\secno=0 \putwordChapter@tie \the\chapno \else \ifnum\subsecno=0 @@ -5989,7 +6034,8 @@ where each line of input produces a line \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno \fi\fi\fi } -\def\Yappendix{% + +\def\Yappendixletterandtype{% \ifnum\secno=0 \putwordAppendix@tie @char\the\appendixno{}% \else \ifnum\subsecno=0 @@ -6002,6 +6048,15 @@ where each line of input produces a line \fi\fi\fi } +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. +\else + \def\linenumber{\the\inputlineno:\space} +\fi + % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. % @@ -6010,7 +6065,7 @@ where each line of input produces a line \indexnofonts \otherbackslash \expandafter\global\expandafter\let\expandafter\thisrefX - \csname XR#1\endcsname + \csname X#1\endcsname }% \ifx\thisrefX\relax % If not defined, say something at least. @@ -6032,44 +6087,11 @@ where each line of input produces a line #2% Output the suffix in any case. } -% This is the macro invoked by entries in the aux file. Usually it's -% just a \def (we prepend XR to the control sequence name to avoid -% collisions). But if this is a float type, we have more work to do. -% -\def\xrdef#1#2{% - \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value. - % - % Was that xref control sequence that we just defined for a float? - \expandafter\iffloat\csname XR#1\endcsname - % it was a float, and we have the (safe) float type in \iffloattype. - \expandafter\let\expandafter\floatlist - \csname floatlist\iffloattype\endcsname - % - % Is this the first time we've seen this float type? - \expandafter\ifx\floatlist\relax - \toks0 = {\do}% yes, so just \do - \else - % had it before, so preserve previous elements in list. - \toks0 = \expandafter{\floatlist\do}% - \fi - % - % Remember this xref in the control sequence \floatlistFLOATTYPE, - % for later use in \listoffloats. - \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}% - \fi -} - -% Read the last existing aux file, if any. No error if none exists. +% This is the macro invoked by entries in the aux file. % -\def\tryauxfile{% - \openin 1 \jobname.aux - \ifeof 1 \else - \readauxfile - \global\havexrefstrue - \fi - \closein 1 -} +\def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} +% Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \catcode`\^^@=\other \catcode`\^^A=\other @@ -6128,16 +6150,7 @@ where each line of input produces a line \catcode`\%=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % - % This is to support \ in node names and titles, since the \ - % characters end up in a \csname. It's easier than - % leaving it active and making its active definition an actual \ - % character. What I don't understand is why it works in the *value* - % of the xrdef. Seems like it should be a catcode12 \, and that - % should not typeset properly. But it works, so I'm moving on for - % now. --karl, 15jan04. - \catcode`\\=\other - % - % Make the characters 128-255 be printing characters. + % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% @@ -6147,17 +6160,31 @@ where each line of input produces a line }% }% % - % @ is our escape character in .aux files, and we need braces. + % Turn off \ as an escape so we do not lose on + % entries which were dumped with control sequences in their names. + % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ + % Reference to such entries still does not work the way one would wish, + % but at least they do not bomb out when the aux file is read in. + \catcode`\\=\other + % + % @ is our escape character in .aux files. \catcode`\{=1 \catcode`\}=2 \catcode`\@=0 % - \input \jobname.aux + \openin 1 \jobname.aux + \ifeof 1 \else + \closein 1 + \input \jobname.aux + \global\havexrefstrue + \global\warnedobstrue + \fi + % Open the new aux file. TeX will close it automatically at exit. + \openout\auxfile=\jobname.aux \endgroup} -\message{insertions,} -% including footnotes. +% Footnotes. \newcount \footnoteno @@ -6171,12 +6198,13 @@ where each line of input produces a line % @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment +\let\ptexfootnote=\footnote + {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \let\indent=\ptexindent - \let\noindent=\ptexnoindent \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % @@ -6194,12 +6222,17 @@ where each line of input produces a line % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % -% Oh yes, they do; otherwise, @ifset (and anything else that uses -% \parseargline) fails inside footnotes because the tokens are fixed when +% Oh yes, they do; otherwise, @ifset and anything else that uses +% \parseargline fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % +% The start of the footnote looks usually like this: +\gdef\startfootins{\insert\footins\bgroup} +% +% ... but this macro is redefined inside @multitable. +% \gdef\dofootnote{% - \insert\footins\bgroup + \startfootins % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. @@ -6235,66 +6268,40 @@ where each line of input produces a line } }%end \catcode `\@=11 -% In case a @footnote appears in a vbox, save the footnote text and create -% the real \insert just after the vbox finished. Otherwise, the insertion -% would be lost. -% Similarily, if a @footnote appears inside an alignment, save the footnote -% text to a box and make the \insert when a row of the table is finished. -% And the same can be done for other insert classes. --kasal, 16nov03. - -% Replace the \insert primitive by a cheating macro. -% Deeper inside, just make sure that the saved insertions are not spilled -% out prematurely. -% -\def\startsavinginserts{% - \ifx \insert\ptexinsert - \let\insert\saveinsert - \else - \let\checkinserts\relax - \fi -} - -% This \insert replacement works for both \insert\footins{foo} and -% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). % -\def\saveinsert#1{% - \edef\next{\noexpand\savetobox \makeSAVEname#1}% - \afterassignment\next - % swallow the left brace - \let\temp = -} -\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} -\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} - -\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} - -\def\placesaveins#1{% - \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname - {\box#1}% -} - -% eat @SAVE -- beware, all of them have catcode \other: -{ - \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) - \gdef\gobblesave @SAVE{} -} - -% initialization: -\def\newsaveins #1{% - \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% - \next -} -\def\newsaveinsX #1{% - \csname newbox\endcsname #1% - \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts - \checksaveins #1}% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% } -% initialize: -\let\checkinserts\empty -\newsaveins\footins -\newsaveins\margin - +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. @@ -6304,12 +6311,12 @@ where each line of input produces a line % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else + \closein 1 % Do not bother showing banner with epsf.tex v2.7k (available in % doc/epsf.tex and on ctan). \def\epsfannounce{\toks0 = }% \input epsf.tex \fi -\closein 1 % % We will only complain once about lack of epsf.tex. \newif\ifwarnednoepsf @@ -6365,269 +6372,6 @@ where each line of input produces a line \endgroup} -% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, -% etc. We don't actually implement floating yet, we always include the -% float "here". But it seemed the best name for the future. -% -\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} - -% There may be a space before second and/or third parameter; delete it. -\def\eatcommaspace#1, {#1,} - -% #1 is the optional FLOATTYPE, the text label for this float, typically -% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, -% this float will not be numbered and cannot be referred to. -% -% #2 is the optional xref label. Also must be present for the float to -% be referable. -% -% #3 is the optional positioning argument; for now, it is ignored. It -% will somehow specify the positions allowed to float to (here, top, bottom). -% -% We keep a separate counter for each FLOATTYPE, which we reset at each -% chapter-level command. -\let\resetallfloatnos=\empty -% -\def\dofloat#1,#2,#3,#4\finish{% - \let\thiscaption=\empty - \let\thisshortcaption=\empty - % - % don't lose footnotes inside @float. - % - % BEWARE: when the floats start float, we have to issue warning whenever an - % insert appears inside a float which could possibly float. --kasal, 26may04 - % - \startsavinginserts - % - % We can't be used inside a paragraph. - \par - % - \vtop\bgroup - \def\floattype{#1}% - \def\floatlabel{#2}% - \def\floatloc{#3}% we do nothing with this yet. - % - \ifx\floattype\empty - \let\safefloattype=\empty - \else - {% - % the floattype might have accents or other special characters, - % but we need to use it in a control sequence name. - \indexnofonts - \turnoffactive - \xdef\safefloattype{\floattype}% - }% - \fi - % - % If label is given but no type, we handle that as the empty type. - \ifx\floatlabel\empty \else - % We want each FLOATTYPE to be numbered separately (Figure 1, - % Table 1, Figure 2, ...). (And if no label, no number.) - % - \expandafter\getfloatno\csname\safefloattype floatno\endcsname - \global\advance\floatno by 1 - % - {% - % This magic value for \thissection is output by \setref as the - % XREFLABEL-title value. \xrefX uses it to distinguish float - % labels (which have a completely different output format) from - % node and anchor labels. And \xrdef uses it to construct the - % lists of floats. - % - \edef\thissection{\floatmagic=\safefloattype}% - \setref{\floatlabel}{Yfloat}% - }% - \fi - % - % start with \parskip glue, I guess. - \vskip\parskip - % - % Don't suppress indentation if a float happens to start a section. - \restorefirstparagraphindent -} - -% we have these possibilities: -% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap -% @float Foo,lbl & no caption: Foo 1.1 -% @float Foo & @caption{Cap}: Foo: Cap -% @float Foo & no caption: Foo -% @float ,lbl & Caption{Cap}: 1.1: Cap -% @float ,lbl & no caption: 1.1 -% @float & @caption{Cap}: Cap -% @float & no caption: -% -\def\Efloat{% - \let\floatident = \empty - % - % In all cases, if we have a float type, it comes first. - \ifx\floattype\empty \else \def\floatident{\floattype}\fi - % - % If we have an xref label, the number comes next. - \ifx\floatlabel\empty \else - \ifx\floattype\empty \else % if also had float type, need tie first. - \appendtomacro\floatident{\tie}% - \fi - % the number. - \appendtomacro\floatident{\chaplevelprefix\the\floatno}% - \fi - % - % Start the printed caption with what we've constructed in - % \floatident, but keep it separate; we need \floatident again. - \let\captionline = \floatident - % - \ifx\thiscaption\empty \else - \ifx\floatident\empty \else - \appendtomacro\captionline{: }% had ident, so need a colon between - \fi - % - % caption text. - \appendtomacro\captionline{\scanexp\thiscaption}% - \fi - % - % If we have anything to print, print it, with space before. - % Eventually this needs to become an \insert. - \ifx\captionline\empty \else - \vskip.5\parskip - \captionline - % - % Space below caption. - \vskip\parskip - \fi - % - % If have an xref label, write the list of floats info. Do this - % after the caption, to avoid chance of it being a breakpoint. - \ifx\floatlabel\empty \else - % Write the text that goes in the lof to the aux file as - % \floatlabel-lof. Besides \floatident, we include the short - % caption if specified, else the full caption if specified, else nothing. - {% - \atdummies \turnoffactive \otherbackslash - % since we read the caption text in the macro world, where ^^M - % is turned into a normal character, we have to scan it back, so - % we don't write the literal three characters "^^M" into the aux file. - \scanexp{% - \xdef\noexpand\gtemp{% - \ifx\thisshortcaption\empty - \thiscaption - \else - \thisshortcaption - \fi - }% - }% - \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident - \ifx\gtemp\empty \else : \gtemp \fi}}% - }% - \fi - \egroup % end of \vtop - % - % place the captured inserts - % - % BEWARE: when the floats start float, we have to issue warning whenever an - % insert appears inside a float which could possibly float. --kasal, 26may04 - % - \checkinserts -} - -% Append the tokens #2 to the definition of macro #1, not expanding either. -% -\def\appendtomacro#1#2{% - \expandafter\def\expandafter#1\expandafter{#1#2}% -} - -% @caption, @shortcaption -% -\def\caption{\docaption\thiscaption} -\def\shortcaption{\docaption\thisshortcaption} -\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} -\def\defcaption#1#2{\egroup \def#1{#2}} - -% The parameter is the control sequence identifying the counter we are -% going to use. Create it if it doesn't exist and assign it to \floatno. -\def\getfloatno#1{% - \ifx#1\relax - % Haven't seen this figure type before. - \csname newcount\endcsname #1% - % - % Remember to reset this floatno at the next chap. - \expandafter\gdef\expandafter\resetallfloatnos - \expandafter{\resetallfloatnos #1=0 }% - \fi - \let\floatno#1% -} - -% \setref calls this to get the XREFLABEL-snt value. We want an @xref -% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we -% first read the @float command. -% -\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% - -% Magic string used for the XREFLABEL-title value, so \xrefX can -% distinguish floats from other xref types. -\def\floatmagic{!!float!!} - -% #1 is the control sequence we are passed; we expand into a conditional -% which is true if #1 represents a float ref. That is, the magic -% \thissection value which we \setref above. -% -\def\iffloat#1{\expandafter\doiffloat#1==\finish} -% -% #1 is (maybe) the \floatmagic string. If so, #2 will be the -% (safe) float type for this float. We set \iffloattype to #2. -% -\def\doiffloat#1=#2=#3\finish{% - \def\temp{#1}% - \def\iffloattype{#2}% - \ifx\temp\floatmagic -} - -% @listoffloats FLOATTYPE - print a list of floats like a table of contents. -% -\parseargdef\listoffloats{% - \def\floattype{#1}% floattype - {% - % the floattype might have accents or other special characters, - % but we need to use it in a control sequence name. - \indexnofonts - \turnoffactive - \xdef\safefloattype{\floattype}% - }% - % - % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. - \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax - \ifhavexrefs - % if the user said @listoffloats foo but never @float foo. - \message{\linenumber No `\safefloattype' floats to list.}% - \fi - \else - \begingroup - \leftskip=\tocindent % indent these entries like a toc - \let\do=\listoffloatsdo - \csname floatlist\safefloattype\endcsname - \endgroup - \fi -} - -% This is called on each entry in a list of floats. We're passed the -% xref label, in the form LABEL-title, which is how we save it in the -% aux file. We strip off the -title and look up \XRLABEL-lof, which -% has the text we're supposed to typeset here. -% -% Figures without xref labels will not be included in the list (since -% they won't appear in the aux file). -% -\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} -\def\listoffloatsdoentry#1-title\finish{{% - % Can't fully expand XR#1-lof because it can contain anything. Just - % pass the control sequence. On the other hand, XR#1-pg is just the - % page number, and we want to fully expand that so we can get a link - % in pdf output. - \toksA = \expandafter{\csname XR#1-lof\endcsname}% - % - % use the same \entry macro we use to generate the TOC and index. - \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% - \writeentry -}} - \message{localization,} % and i18n. @@ -6636,17 +6380,19 @@ where each line of input produces a line % properly. Single argument is the language abbreviation. % It would be nice if we could set up a hyphenation file here. % -\parseargdef\documentlanguage{% +\def\documentlanguage{\parsearg\dodocumentlanguage} +\def\dodocumentlanguage#1{% \tex % read txi-??.tex file in plain TeX. - % Read the file if it exists. - \openin 1 txi-#1.tex - \ifeof 1 - \errhelp = \nolanghelp - \errmessage{Cannot read language file txi-#1.tex}% - \else - \input txi-#1.tex - \fi - \closein 1 + % Read the file if it exists. + \openin 1 txi-#1.tex + \ifeof1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \let\temp = \relax + \else + \def\temp{\input txi-#1.tex }% + \fi + \temp \endgroup } \newhelp\nolanghelp{The given language definition file cannot be found or @@ -6829,7 +6575,8 @@ should work if nowhere else does.} % Perhaps we should allow setting the margins, \topskip, \parskip, % and/or leading, also. Or perhaps we should compute them somehow. % -\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +\def\pagesizes{\parsearg\pagesizesxxx} +\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} \def\pagesizesyyy#1,#2,#3\finish{{% \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi \globaldefs = 1 @@ -6876,8 +6623,8 @@ should work if nowhere else does.} \def\normalplus{+} \def\normaldollar{$}%$ font-lock fix -% This macro is used to make a character print one way in \tt -% (where it can probably be output as-is), and another way in other fonts, +% This macro is used to make a character print one way in ttfont +% where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print @@ -6925,6 +6672,13 @@ should work if nowhere else does.} \catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix +% Set up an active definition for =, but don't enable it most of the time. +{\catcode`\==\active +\global\def={{\tt \char 61}}} + +\catcode`+=\active +\catcode`\_=\active + % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. @@ -6933,16 +6687,15 @@ should work if nowhere else does.} \catcode`\@=0 -% \backslashcurfont outputs one backslash character in current font, +% \rawbackslashxx outputs one backslash character in current font, % as in \char`\\. -\global\chardef\backslashcurfont=`\\ -\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work +\global\chardef\rawbackslashxx=`\\ -% \rawbackslash defines an active \ to do \backslashcurfont. +% \rawbackslash defines an active \ to do \rawbackslashxx. % \otherbackslash defines an active \ to be a literal `\' character with % catcode other. {\catcode`\\=\active - @gdef@rawbackslash{@let\=@backslashcurfont} + @gdef@rawbackslash{@let\=@rawbackslashxx} @gdef@otherbackslash{@let\=@realbackslash} } @@ -6950,7 +6703,7 @@ should work if nowhere else does.} {\catcode`\\=\other @gdef@realbackslash{\}} % \normalbackslash outputs one backslash in fixed width font. -\def\normalbackslash{{\tt\backslashcurfont}} +\def\normalbackslash{{\tt\rawbackslashxx}} \catcode`\\=\active @@ -6967,7 +6720,6 @@ should work if nowhere else does.} @let>=@normalgreater @let+=@normalplus @let$=@normaldollar %$ font-lock fix - @unsepspaces } % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of @@ -7007,6 +6759,10 @@ should work if nowhere else does.} @catcode`@# = @other @catcode`@% = @other +@c Set initial fonts. +@textfonts +@rm + @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) @@ -7015,9 +6771,3 @@ should work if nowhere else does.} @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @c End: - -@c vim:sw=2: - -@ignore - arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 -@end ignore diff -urpNP gpgme-1.0.3/doc/version.texi gpgme-1.1.0/doc/version.texi --- gpgme-1.0.3/doc/version.texi 2005-06-20 19:35:41.000000000 +0000 +++ gpgme-1.1.0/doc/version.texi 2005-10-01 21:15:18.000000000 +0000 @@ -1,4 +1,4 @@ -@set UPDATED 28 May 2005 -@set UPDATED-MONTH May 2005 -@set EDITION 1.0.3 -@set VERSION 1.0.3 +@set UPDATED 1 October 2005 +@set UPDATED-MONTH October 2005 +@set EDITION 1.1.0 +@set VERSION 1.1.0 diff -urpNP gpgme-1.0.3/gpgme/ChangeLog gpgme-1.1.0/gpgme/ChangeLog --- gpgme-1.0.3/gpgme/ChangeLog 2005-06-20 17:53:28.000000000 +0000 +++ gpgme-1.1.0/gpgme/ChangeLog 2005-10-01 20:14:48.000000000 +0000 @@ -1,9 +1,195 @@ +2005-10-01 Marcus Brinkmann + + * engine.h (_gpgme_set_engine_info): Add prototype. + * engine-backend.h (struct engine_ops): Change return type of + get_file_name() to const char * to silence gcc warning. + * engine.c (engine_get_file_name): Change return type to const + char * to silence gcc warning. + (gpgme_get_engine_info): Use transitional variable to go from + const char * to char * to silence gcc warning. + (_gpgme_set_engine_info): Likewise. + * engine-gpgsm.c (struct engine_gpgsm): Change type of LINE to + char * to silence gcc warning. + (gpgsm_new): Make ARGV a pointer to const char. + (status_handler): Change type of SRC, END, DST, ALINE and NEWLINE + to char * to silence gcc warning. + + * gpgme.def: Add gpgme_data_set_file_name, + gpgme_data_get_file_name, gpgme_sig_notation_clear, + gpgme_sig_notation_add and gpgme_sig_notation_get. + * libgpgme.vers: Add gpgme_sig_notation_clear, + gpgme_sig_notation_add and gpgme_sig_notation_get. + * Makefile.am (libgpgme_real_la_SOURCES): Add sig-notation.c. + * context.h (struct gpgme_context): New field sig_notations. + * gpgme.h (struct _gpgme_sig_notation): New member value_len and + critical. + (GPGME_SIG_NOTATION_CRITICAL): New symbol. + (gpgme_sig_notation_flags_t): New type. + (gpgme_sig_notation_add, gpgme_sig_notation_clear, + gpgme_sig_notation_get): New prototypes. + * ops.h (_gpgme_sig_notation_create, _gpgme_sig_notation_free): + New prototypes. + * sig-notation.c (_gpgme_sig_notation_free): New file. + * verify.c (parse_notation): Use support functions. + (release_op_data): Likewise. + * rungpg.c (append_args_from_sig_notations): New function. + (gpg_encrypt_sign, gpg_sign): Call it. + +2005-09-30 Marcus Brinkmann + + * data.h (struct gpgme_data): New member file_name. + * data.c (gpgme_data_set_filename): New function. + (_gpgme_data_release): Free DH->filename if necessary. + (gpgme_data_get_filename): New function. + * rungpg.c (gpg_encrypt): Set filename option. + (gpg_encrypt_sign): Likewise. + (gpg_sign): Likewise. + * libgpgme.vers (GPGME_1.1): Add gpgme_data_set_file_name and + gpgme_data_get_file_name. + + * decrpyt.c, verify.c, gpgme.h: Replace plaintext_filename with + file_name. + +2005-09-29 Marcus Brinkmann + + * gpgme.h (struct _gpgme_key): Add field is_qualified. + (struct _gpgme_subkey): Likewise. + * keylist.c (set_subkey_capability, set_mainkey_capability): Set + field is_qualified. + +2005-09-23 Werner Koch + + * w32-io.c (_gpgme_io_pipe): Removed use of environment variable + again. + (create_reader, create_writer): Set thread priority higher. + +2005-09-19 Werner Koch + + * w32-io.c (_gpgme_io_pipe): New environment variable to change + the size of the pipe buffer. + +2005-09-13 Werner Koch + + * ath.c: Changes to make it work under W32. + +2005-09-12 Marcus Brinkmann + + * Makefile.am (libgpgme_la_SOURCES): Set to ath.h and ath.c. + (ath_pth_src, ath_pthread_src): Removed. + (w32_o_files): Replace ath-compat.o with ath.o. + (libgpgme_pth_la_CFLAGS): New variable. + * ath-compat.c, ath-pthread-compat.c, ath-pth-compat.c: Removed. + * ath.h (ath_pthread_available, ath_pth_available): Removed. + (ath_init) [!_ATH_EXT_SYM_PREFIX]: Do not define macro. + (struct ath_ops, ath_init) [_ATH_COMPAT]: Removed. + (_ATH_COMPAT): Macro removed. + * posix-sema.c (_gpgme_sema_subsystem_init): Do not call + _gpgme_ath_init. + +2005-09-12 Marcus Brinkmann + + * keylist.c (release_op_data): Do not free opd->tmp_uid. + +2005-09-07 Werner Koch + + * w32-io.c (build_commandline): Quote argv[0]. + +2005-08-26 Marcus Brinkmann + + * rungpg.c (command_handler): Use _gpgme_io_write instead of write. + + * edit.c (command_handler): Do not depend on PROCESSED being + available. + + * engine.h (engine_command_handler_t): Add new argument processed. + * ops.h (_gpgme_passphrase_command_handler_internal): Rename + prototype to ... + (_gpgme_passphrase_command_handler): ... this one. + * passphrase.c (_gpgme_passphrase_command_handler_internal): + Rename to ... + (_gpgme_passphrase_command_handler): ... this one. + * edit.c (command_handler): Add new argument processed. Remove + local variable with the same name. Always return processed as + true. + * rungpg.c (command_handler): Send a newline character if the + handler did not. + +2005-08-26 Werner Koch + + * w32-util.c (read_w32_registry_string): Updated from code used by + GnuPG. This allows for expanding strings and features the + implicit fallback key. + (w32_shgetfolderpath, find_program_at_standard_place): New. + (_gpgme_get_gpg_path, _gpgme_get_gpgsm_path): With no registry + entry, locate the programs at the standard place. + (dlopen, dlsym, dlclose): New, so that we can keep on using what + we are accustomed to. + + * debug.c (debug_init): Use PATHSEP_C so that under W32 a + semicolon is used which allows us to create files with drive + letters. + + * w32-io.c (_gpgme_io_read, _gpgme_io_write): Print content in + debug mode too. + +2005-08-19 Werner Koch + + * gpgme.def: New. + * versioninfo.rc.in: New. + * Makefile.am: Addes support for building a W32 DLL. + + * ttyname_r.c (ttyname_r) [W32]: Return error. + * ath-compat.c [W32]: select and co are not yet supported; return + error. + * data-stream.c (stream_seek): Use ftell if ftello is not available. + +2005-08-08 Werner Koch + + * util.h (stpcpy): Renamed to .. + (_gpgme_stpcpy): .. this and made inline. This avoids duplicate + definitions when linking statically. + * stpcpy.c: Removed. + +2005-07-27 Marcus Brinkmann + + * gpgme.h (gpgme_status_code_t): Add GPGME_STATUS_PLAINTEXT. + (struct _gpgme_op_decrypt_result): New member plaintext_filename. + (struct _gpgme_op_verify_result): Likewise. + * ops.h (_gpgme_parse_plaintext): Add prototype. + * op-support.c (_gpgme_parse_plaintext): New function. + * decrypt.c (release_op_data): Release + OPD->result.plaintext_filename. + (_gpgme_decrypt_status_handler): Handle GPGME_STATUS_PLAINTEXT. + * verify.c (release_op_data): Release + OPD->result.plaintext_filename. + (_gpgme_verify_status_handler): Handle GPGME_STATUS_PLAINTEXT. + +2005-07-26 Marcus Brinkmann + + * keylist.c (gpgme_get_key): Allow key IDs. + 2005-06-20 Marcus Brinkmann * gpgme.m4: Only call GPGME_CONFIG if found. 2005-06-03 Marcus Brinkmann + * gpgme.h (struct _gpgme_signature): New members pubkey_algo and + hash_algo. + * verify.c (parse_valid_sig): Parse pubkey and hash algo numbers. + (parse_new_sig): Parse pubkey, hash algo and timestamp for ERRSIG. + + (_gpgme_decrypt_status_handler): Fix last change. + + * gpgme.h (struct _gpgme_recipient): New structure. + (gpgme_recipient_t): New type. + (struct _gpgme_op_decrypt_result): Add member recipients. + * decrypt.c (op_data_t): New member last_recipient_p. + (_gpgme_op_decrypt_init_result): Initialize last_recipient_p. + (parse_enc_to): New function. + (_gpgme_decrypt_status_handler): Handle status ENC_TO and + NO_SECKEY. + * wait-global.c (gpgme_wait): Break out of the fd processing loop after an error. Reported by Igor Belyi . @@ -18,12 +204,16 @@ 2005-06-02 Werner Koch - * gpgme.h: Add GPGME_STATUS_NEED_PASSPHRASE_PIN. * passphrase.c (_gpgme_passphrase_status_handler): Take care of GPGME_STATUS_NEED_PASSPHRASE_PIN. (_gpgme_passphrase_command_handler_internal): Also act on the key "passphrase.pin.ask". + * gpgme.h: Added status codes GPGME_STATUS_SIG_SUBPACKET, + GPGME_STATUS_NEED_PASSPHRASE_PIN, GPGME_STATUS_SC_OP_FAILURE, + GPGME_STATUS_SC_OP_SUCCESS, GPGME_STATUS_CARDCTRL, + GPGME_STATUS_BACKUP_KEY_CREATED. + 2005-05-28 Marcus Brinkmann * data-user.c: Include . @@ -67,6 +257,52 @@ should not hang, set *status to 0 and return NULL. Reported by Igor Belyi . +2005-03-24 Marcus Brinkmann + + * data.h (EOPNOTSUPP) [_WIN32]: Remove definition. + * data.c (EOPNOTSUPP) [HAVE_W32_SYSTEM]: Remove definition. + (gpgme_data_read, gpgme_data_write, gpgme_data_seek): Return + ENOSYS instead EOPNOTSUPP. + * data-compat.c (EOPNOTSUPP) [HAVE_W32_SYSTEM]: Remove definition. + (gpgme_error_to_errno): Map GPG_ERR_NOT_SUPPORTED + to ENOSYS. + +2005-03-24 Marcus Brinkmann + + * io.h: Rename to ... + * priv-io.h: ... this. + * Makefile.am (libgpgme_real_la_SOURCES): Change io.h to priv-io.h. + * data.c, engine-gpgsm.c, posix-io.c, rungpg.c, version.c, + w32-io.c, wait-private.c, wait-global.c, wait-user.c, wait.c: + Change all includes of "io.h" to "priv-io.h" + +2005-03-09 Werner Koch + + * w32-util.c (_gpgme_get_gpg_path, _gpgme_get_gpgsm_path): Do not + cast away type checks. + + * io.h [W32]: Do not include stdio.h. If it is needed do it at + the right place. + + * data.h [W32]: Removed kludge for EOPNOTSUP. + * data.c, data-compat.c [W32]: Explicitly test for it here. + + Replaced use of _WIN32 by HAVE_W32_SYSTEM except for public header + files. + +2005-03-07 Timo Schulz + + * gpgme.h: [_WIN32] Removed ssize_t typedef. + * ath.h: [_WIN32] Added some (dummy) types. + * io.h: [_WIN32] include stdio.h. + * data.h: [_WIN32] Define EOPNOTSUPP. + * w32-io.c [_WIN32] (_gpgme_io_subsystem_init): New. + * gpgme.c [_WIN32] (gpgme_set_locale): Disabled. + +2004-12-12 Marcus Brinkmann + + * engine.c (_gpgme_set_engine_info): Fix assertion. + 2004-12-11 Marcus Brinkmann * util.h [HAVE_CONFIG_H && HAVE_TTYNAME_R] (ttyname_r): Define @@ -98,6 +334,60 @@ wait.c, wait-global.c, wait.h, wait-private.c, wait-user.c: Change license to LGPL. +2004-12-07 Marcus Brinkmann + + * libgpgme.vers (GPGME_1.1): New version. + * engine-backend.h (struct engine_ops): Add argument FILE_NAME to + member get_version(). Add arguments FILE_NAME and HOME_DIR to + member new(). Change return type of get_file_name and get_version + to char *. + * engine-gpgsm.c (gpgsm_get_version): Change return type to char + pointer. Do not cache result. + (gpgsm_new): Add file_name and home_dir argument, and use them + instead of the defaults, if set. + * rungpg.c (struct engine_gpg): New member file_name. + (gpg_get_version): Change return type to char pointer, and do not + cache result. + (gpg_release): Free gpg->file_name. + (gpg_new): Take new arguments file_name and home_dir. Set the + --homedir argument if HOME_DIR is not NULL. Set gpg->file_name. + (start): Use gpg->file_name instead _gpgme_get_gpg_path, if set. + * engine.h (_gpgme_engine_info_copy, _gpgme_engine_info_release): + New prototypes. + (_gpgme_engine_new): Change first argument to gpgme_engine_info_t + info. + * engine.c: Include . + (gpgme_get_engine_info): Set *INFO within the lock. Move + ENGINE_INFO and ENGINE_INFO_LOCK to .... + (engine_info, engine_info_lock): ... here. New static variables. + (engine_get_version): Add file_name argument to + get_version invocation. Change return type to char pointer. + (gpgme_engine_check_version): Rewritten to free() the return value + of engine_get_version after using it. + (_gpgme_engine_info_release): New function. + (gpgme_get_engine_info): Rewritten. + (_gpgme_engine_info_copy): New function. + (_gpgme_set_engine_info): New function. + (gpgme_set_engine_info): New function. + (_gpgme_engine_new): Change first argument to gpgme_engine_info_t + info, and use that. + * gpgme.h (struct _gpgme_engine_info): Change type of file_name + and version to char * (remove the const). New member home_dir. + (gpgme_set_engine_info, gpgme_ctx_get_engine_info, + gpgme_ctx_set_engine_info): New prototypes. + * context.h (struct gpgme_context): New member engine_info. + * gpgme.c (gpgme_new): Allocate CTX->engine_info. + (gpgme_release): Deallocate CTX->engine_info. + (gpgme_ctx_get_engine_info, gpgme_ctx_set_engine_info): New + functions. + * op-support.c (_gpgme_op_reset): Look for correct engine info and + pass it to _gpgme_engine_new. + * version.c (gpgme_check_version): Adjust to + _gpgme_compare_versions returning an int. + (_gpgme_compare_versions): Return an int value, not a const char + pointer. + * ops.h (_gpgme_compare_versions): Same for prototype. + 2004-10-03 Marcus Brinkmann * verify.c (parse_trust): If no reason is provided, set diff -urpNP gpgme-1.0.3/gpgme/Makefile.am gpgme-1.1.0/gpgme/Makefile.am --- gpgme-1.0.3/gpgme/Makefile.am 2004-12-07 20:41:21.000000000 +0000 +++ gpgme-1.1.0/gpgme/Makefile.am 2005-10-01 02:06:07.000000000 +0000 @@ -1,5 +1,5 @@ # Copyright (C) 2000 Werner Koch (dd9jn) -# Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH +# Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH # # This file is part of GPGME. # @@ -19,7 +19,8 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = gpgme-config.in gpgme.m4 mkstatus libgpgme.vers +EXTRA_DIST = gpgme-config.in gpgme.m4 mkstatus libgpgme.vers \ + versioninfo.rc.in gpgme.def BUILT_SOURCES = status-table.h MOSTLYCLEANFILES = status-table.h bin_SCRIPTS = gpgme-config @@ -71,7 +72,7 @@ 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 \ + signers.c sig-notation.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 \ @@ -79,21 +80,10 @@ libgpgme_real_la_SOURCES = \ 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) \ + $(gpgsm_components) sema.h priv-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_la_SOURCES = ath.h ath.c libgpgme_pthread_la_SOURCES = ath.h ath-pthread.c libgpgme_pth_la_SOURCES = ath.h ath-pth.c @@ -113,6 +103,7 @@ libgpgme_pthread_la_DEPENDENCIES = libgp libgpgme_pthread_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \ -lpthread @GPG_ERROR_LIBS@ +libgpgme_pth_la_CFLAGS = $(AM_CFLAGS) @PTH_CFLAGS@ libgpgme_pth_la_CPPFLAGS = $(AM_CPPFLAGS) @PTH_CPPFLAGS@ libgpgme_pth_la_LDFLAGS = @PTH_LDFLAGS@ \ $(libgpgme_version_script_cmd) -version-info \ @@ -124,3 +115,34 @@ libgpgme_pth_la_LIBADD = libgpgme-real.l status-table.h : gpgme.h $(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h + +# Special code to build a DLL. The current libtool (1.5.6) is not +# able to do this properly; we better use gcc's built in magic. +if HAVE_W32_SYSTEM + +w32_o_files = ath.o conversion.o data-compat.o data-fd.o \ + data-mem.o data-stream.o data-user.o data.o debug.o \ + decrypt-verify.o decrypt.o delete.o edit.o encrypt-sign.o \ + encrypt.o engine-gpgsm.o engine.o error.o export.o genkey.o \ + get-env.o gpgme.o import.o key.o keylist.o memrchr.o \ + op-support.o passphrase.o progress.o putc_unlocked.o \ + rungpg.o sign.o signers.o trust-item.o trustlist.o \ + ttyname_r.o vasprintf.o verify.o version.o \ + w32-io.o w32-sema.o w32-util.o \ + wait-global.o wait-private.o wait-user.o wait.o + +all-local: gpgme.dll gpgme.dll.a + +install-exec-hook: + cp gpgme.dll gpgme.dll.a $(DESTDIR)$(libdir)/ + $(STRIP) $(DESTDIR)$(libdir)/gpgme.dll + +gpgme.dll gpgme.dll.a: gpgme.def $(w32_o_files) versioninfo.o + $(CC) -shared -o gpgme.dll gpgme.def $(w32_o_files) \ + versioninfo.o @GPG_ERROR_LIBS@ -Wl,--out-implib,gpgme.dll.a + + +.rc.o: + $(WINDRES) `test -f '$<' || echo '$(srcdir)/'`$< $@ + +endif diff -urpNP gpgme-1.0.3/gpgme/Makefile.in gpgme-1.1.0/gpgme/Makefile.in --- gpgme-1.0.3/gpgme/Makefile.in 2005-06-20 19:35:24.000000000 +0000 +++ gpgme-1.1.0/gpgme/Makefile.in 2005-10-01 21:13:45.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -15,7 +15,7 @@ @SET_MAKE@ # Copyright (C) 2000 Werner Koch (dd9jn) -# Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH +# Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH # # This file is part of GPGME. # @@ -36,8 +36,6 @@ -SOURCES = $(libgpgme_pth_la_SOURCES) $(libgpgme_pthread_la_SOURCES) $(libgpgme_real_la_SOURCES) $(libgpgme_la_SOURCES) - srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -62,9 +60,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = gpgme DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/gpgme-config.in ChangeLog \ - funopen.c isascii.c memrchr.c putc_unlocked.c stpcpy.c \ - ttyname_r.c vasprintf.c + $(srcdir)/Makefile.in $(srcdir)/gpgme-config.in \ + $(srcdir)/versioninfo.rc.in ChangeLog funopen.c isascii.c \ + memrchr.c putc_unlocked.c ttyname_r.c vasprintf.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/glibc21.m4 \ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \ @@ -74,7 +72,7 @@ am__configure_deps = $(am__aclocal_m4_de $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = gpgme-config +CONFIG_CLEAN_FILES = versioninfo.rc gpgme-config am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -96,14 +94,14 @@ libgpgme_real_la_LIBADD = am__libgpgme_real_la_SOURCES_DIST = 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 \ + sig-notation.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 engine-gpgsm.c sema.h io.h ath.h posix-util.c \ - posix-sema.c posix-io.c w32-util.c w32-sema.c w32-io.c debug.c \ - debug.h gpgme.c version.c error.c + status-table.h engine-gpgsm.c sema.h priv-io.h ath.h \ + posix-util.c posix-sema.c posix-io.c w32-util.c w32-sema.c \ + w32-io.c debug.c debug.h gpgme.c version.c error.c @HAVE_GPGSM_TRUE@am__objects_1 = engine-gpgsm.lo @HAVE_DOSISH_SYSTEM_FALSE@am__objects_2 = posix-util.lo posix-sema.lo \ @HAVE_DOSISH_SYSTEM_FALSE@ posix-io.lo @@ -111,20 +109,15 @@ am__libgpgme_real_la_SOURCES_DIST = gpgm @HAVE_DOSISH_SYSTEM_TRUE@ w32-io.lo am_libgpgme_real_la_OBJECTS = conversion.lo get-env.lo data.lo \ data-fd.lo data-stream.lo data-mem.lo data-user.lo \ - data-compat.lo signers.lo wait.lo wait-global.lo \ - wait-private.lo wait-user.lo op-support.lo encrypt.lo \ - encrypt-sign.lo decrypt.lo decrypt-verify.lo verify.lo sign.lo \ - passphrase.lo progress.lo key.lo keylist.lo trust-item.lo \ - trustlist.lo import.lo export.lo genkey.lo delete.lo edit.lo \ - engine.lo rungpg.lo $(am__objects_1) $(am__objects_2) debug.lo \ - gpgme.lo version.lo error.lo + data-compat.lo signers.lo sig-notation.lo wait.lo \ + wait-global.lo wait-private.lo wait-user.lo op-support.lo \ + encrypt.lo encrypt-sign.lo decrypt.lo decrypt-verify.lo \ + verify.lo sign.lo passphrase.lo progress.lo key.lo keylist.lo \ + trust-item.lo trustlist.lo import.lo export.lo genkey.lo \ + delete.lo edit.lo engine.lo rungpg.lo $(am__objects_1) \ + $(am__objects_2) debug.lo gpgme.lo version.lo error.lo libgpgme_real_la_OBJECTS = $(am_libgpgme_real_la_OBJECTS) -am__libgpgme_la_SOURCES_DIST = ath.h ath-compat.c ath-pth-compat.c \ - ath-pthread-compat.c -@HAVE_PTH_TRUE@am__objects_3 = ath-pth-compat.lo -@HAVE_PTHREAD_TRUE@am__objects_4 = ath-pthread-compat.lo -am_libgpgme_la_OBJECTS = ath-compat.lo $(am__objects_3) \ - $(am__objects_4) +am_libgpgme_la_OBJECTS = ath.lo libgpgme_la_OBJECTS = $(am_libgpgme_la_OBJECTS) binSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(bin_SCRIPTS) @@ -143,8 +136,7 @@ SOURCES = $(libgpgme_pth_la_SOURCES) $(l $(libgpgme_real_la_SOURCES) $(libgpgme_la_SOURCES) DIST_SOURCES = $(libgpgme_pth_la_SOURCES) \ $(libgpgme_pthread_la_SOURCES) \ - $(am__libgpgme_real_la_SOURCES_DIST) \ - $(am__libgpgme_la_SOURCES_DIST) + $(am__libgpgme_real_la_SOURCES_DIST) $(libgpgme_la_SOURCES) m4dataDATA_INSTALL = $(INSTALL_DATA) DATA = $(m4data_DATA) includeHEADERS_INSTALL = $(INSTALL_HEADER) @@ -165,6 +157,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -177,6 +171,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -205,6 +200,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -243,12 +240,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ @@ -286,7 +286,9 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -EXTRA_DIST = gpgme-config.in gpgme.m4 mkstatus libgpgme.vers +EXTRA_DIST = gpgme-config.in gpgme.m4 mkstatus libgpgme.vers \ + versioninfo.rc.in gpgme.def + BUILT_SOURCES = status-table.h MOSTLYCLEANFILES = status-table.h bin_SCRIPTS = gpgme-config @@ -313,7 +315,7 @@ 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 \ + signers.c sig-notation.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 \ @@ -321,16 +323,10 @@ libgpgme_real_la_SOURCES = \ 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) \ + $(gpgsm_components) sema.h priv-io.h $(system_components) \ debug.c debug.h gpgme.c version.c error.c -@HAVE_PTH_FALSE@ath_pth_src = - -# libgpgme_la_SOURCES = ath.h ath.c -@HAVE_PTH_TRUE@ath_pth_src = ath-pth-compat.c -@HAVE_PTHREAD_FALSE@ath_pthread_src = -@HAVE_PTHREAD_TRUE@ath_pthread_src = ath-pthread-compat.c -libgpgme_la_SOURCES = ath.h ath-compat.c $(ath_pth_src) $(ath_pthread_src) +libgpgme_la_SOURCES = ath.h ath.c 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@ @@ -352,6 +348,7 @@ libgpgme_pthread_la_DEPENDENCIES = libgp libgpgme_pthread_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \ -lpthread @GPG_ERROR_LIBS@ +libgpgme_pth_la_CFLAGS = $(AM_CFLAGS) @PTH_CFLAGS@ libgpgme_pth_la_CPPFLAGS = $(AM_CPPFLAGS) @PTH_CPPFLAGS@ libgpgme_pth_la_LDFLAGS = @PTH_LDFLAGS@ \ $(libgpgme_version_script_cmd) -version-info \ @@ -363,11 +360,25 @@ libgpgme_pth_la_DEPENDENCIES = libgpgme- libgpgme_pth_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \ @PTH_LIBS@ @GPG_ERROR_LIBS@ + +# Special code to build a DLL. The current libtool (1.5.6) is not +# able to do this properly; we better use gcc's built in magic. +@HAVE_W32_SYSTEM_TRUE@w32_o_files = ath.o conversion.o data-compat.o data-fd.o \ +@HAVE_W32_SYSTEM_TRUE@ data-mem.o data-stream.o data-user.o data.o debug.o \ +@HAVE_W32_SYSTEM_TRUE@ decrypt-verify.o decrypt.o delete.o edit.o encrypt-sign.o \ +@HAVE_W32_SYSTEM_TRUE@ encrypt.o engine-gpgsm.o engine.o error.o export.o genkey.o \ +@HAVE_W32_SYSTEM_TRUE@ get-env.o gpgme.o import.o key.o keylist.o memrchr.o \ +@HAVE_W32_SYSTEM_TRUE@ op-support.o passphrase.o progress.o putc_unlocked.o \ +@HAVE_W32_SYSTEM_TRUE@ rungpg.o sign.o signers.o trust-item.o trustlist.o \ +@HAVE_W32_SYSTEM_TRUE@ ttyname_r.o vasprintf.o verify.o version.o \ +@HAVE_W32_SYSTEM_TRUE@ w32-io.o w32-sema.o w32-util.o \ +@HAVE_W32_SYSTEM_TRUE@ wait-global.o wait-private.o wait-user.o wait.o + all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj +.SUFFIXES: .c .lo .o .obj .rc $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -397,6 +408,8 @@ $(top_srcdir)/configure: @MAINTAINER_MOD cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +versioninfo.rc: $(top_builddir)/config.status $(srcdir)/versioninfo.rc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ gpgme-config: $(top_builddir)/config.status $(srcdir)/gpgme-config.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @@ -473,13 +486,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/isascii.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memrchr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/putc_unlocked.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/stpcpy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ttyname_r.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/vasprintf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath-compat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath-pth-compat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath-pthread-compat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath-pthread.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conversion.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-compat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-fd.Plo@am__quote@ @@ -512,6 +522,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/progress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rungpg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig-notation.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sign.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trust-item.Plo@am__quote@ @@ -548,11 +559,11 @@ distclean-compile: @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libgpgme_pth_la-ath-pth.lo: ath-pth.c -@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgpgme_pth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgpgme_pth_la-ath-pth.lo -MD -MP -MF "$(DEPDIR)/libgpgme_pth_la-ath-pth.Tpo" -c -o libgpgme_pth_la-ath-pth.lo `test -f 'ath-pth.c' || echo '$(srcdir)/'`ath-pth.c; \ +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgpgme_pth_la_CPPFLAGS) $(CPPFLAGS) $(libgpgme_pth_la_CFLAGS) $(CFLAGS) -MT libgpgme_pth_la-ath-pth.lo -MD -MP -MF "$(DEPDIR)/libgpgme_pth_la-ath-pth.Tpo" -c -o libgpgme_pth_la-ath-pth.lo `test -f 'ath-pth.c' || echo '$(srcdir)/'`ath-pth.c; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgpgme_pth_la-ath-pth.Tpo" "$(DEPDIR)/libgpgme_pth_la-ath-pth.Plo"; else rm -f "$(DEPDIR)/libgpgme_pth_la-ath-pth.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ath-pth.c' object='libgpgme_pth_la-ath-pth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgpgme_pth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgpgme_pth_la-ath-pth.lo `test -f 'ath-pth.c' || echo '$(srcdir)/'`ath-pth.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgpgme_pth_la_CPPFLAGS) $(CPPFLAGS) $(libgpgme_pth_la_CFLAGS) $(CFLAGS) -c -o libgpgme_pth_la-ath-pth.lo `test -f 'ath-pth.c' || echo '$(srcdir)/'`ath-pth.c mostlyclean-libtool: -rm -f *.lo @@ -676,7 +687,9 @@ distdir: $(DISTFILES) check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) $(HEADERS) +@HAVE_W32_SYSTEM_FALSE@all-local: +all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) $(HEADERS) \ + all-local installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ @@ -708,6 +721,7 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +@HAVE_W32_SYSTEM_FALSE@install-exec-hook: clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ @@ -732,6 +746,8 @@ info-am: install-data-am: install-includeHEADERS install-m4dataDATA install-exec-am: install-binSCRIPTS install-libLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-info: install-info-am @@ -761,25 +777,38 @@ uninstall-am: uninstall-binSCRIPTS unins uninstall-info-am uninstall-libLTLIBRARIES \ uninstall-m4dataDATA -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ - ctags distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-binSCRIPTS \ - install-data install-data-am install-exec install-exec-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-m4dataDATA install-man \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-binSCRIPTS uninstall-includeHEADERS \ - uninstall-info-am uninstall-libLTLIBRARIES \ - uninstall-m4dataDATA +.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binSCRIPTS install-data install-data-am install-exec \ + install-exec-am install-exec-hook install-includeHEADERS \ + install-info install-info-am install-libLTLIBRARIES \ + install-m4dataDATA install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binSCRIPTS \ + uninstall-includeHEADERS uninstall-info-am \ + uninstall-libLTLIBRARIES uninstall-m4dataDATA status-table.h : gpgme.h $(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h + +@HAVE_W32_SYSTEM_TRUE@all-local: gpgme.dll gpgme.dll.a + +@HAVE_W32_SYSTEM_TRUE@install-exec-hook: +@HAVE_W32_SYSTEM_TRUE@ cp gpgme.dll gpgme.dll.a $(DESTDIR)$(libdir)/ +@HAVE_W32_SYSTEM_TRUE@ $(STRIP) $(DESTDIR)$(libdir)/gpgme.dll + +@HAVE_W32_SYSTEM_TRUE@gpgme.dll gpgme.dll.a: gpgme.def $(w32_o_files) versioninfo.o +@HAVE_W32_SYSTEM_TRUE@ $(CC) -shared -o gpgme.dll gpgme.def $(w32_o_files) \ +@HAVE_W32_SYSTEM_TRUE@ versioninfo.o @GPG_ERROR_LIBS@ -Wl,--out-implib,gpgme.dll.a + +@HAVE_W32_SYSTEM_TRUE@.rc.o: +@HAVE_W32_SYSTEM_TRUE@ $(WINDRES) `test -f '$<' || echo '$(srcdir)/'`$< $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -urpNP gpgme-1.0.3/gpgme/ath-compat.c gpgme-1.1.0/gpgme/ath-compat.c --- gpgme-1.0.3/gpgme/ath-compat.c 2004-12-07 20:55:54.000000000 +0000 +++ gpgme-1.1.0/gpgme/ath-compat.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,185 +0,0 @@ -/* ath.c - self-adapting thread-safeness library - Copyright (C) 2002, 2004 g10 Code GmbH - - This file is part of GPGME. - - GPGME is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - GPGME is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#ifdef HAVE_SYS_SELECT_H -# include -#else -# include -#endif -#include -#ifndef _WIN32 -#include -#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); -} diff -urpNP gpgme-1.0.3/gpgme/ath-pth-compat.c gpgme-1.1.0/gpgme/ath-pth-compat.c --- gpgme-1.0.3/gpgme/ath-pth-compat.c 2004-12-07 20:55:22.000000000 +0000 +++ gpgme-1.1.0/gpgme/ath-pth-compat.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -/* ath-pth.c - Pth module for self-adapting thread-safeness library - Copyright (C) 2002, 2004 g10 Code GmbH - - This file is part of GPGME. - - GPGME is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - GPGME is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#include -#include -#include - -#include "ath.h" - -#pragma weak pth_mutex_init -#pragma weak pth_mutex_acquire -#pragma weak pth_mutex_release -#pragma weak pth_read -#pragma weak pth_write -#pragma weak pth_select -#pragma weak pth_waitpid -#pragma weak pth_accept -#pragma weak pth_connect - -/* The lock we take while checking for lazy lock initialization. */ -static pth_mutex_t check_init_lock = PTH_MUTEX_INIT; - -/* Initialize the mutex *PRIV. If JUST_CHECK is true, only do this if - it is not already initialized. */ -static int -mutex_pth_init (void **priv, int just_check) -{ - int err = 0; - - if (just_check) - pth_mutex_acquire (&check_init_lock, 0, NULL); - if (!*priv || !just_check) - { - pth_mutex_t *lock = malloc (sizeof (pth_mutex_t)); - if (!lock) - err = ENOMEM; - if (!err) - { - err = pth_mutex_init (lock); - if (err == FALSE) - err = errno; - else - err = 0; - - if (err) - free (lock); - else - *priv = lock; - } - } - if (just_check) - pth_mutex_release (&check_init_lock); - return err; -} - - -static int -mutex_pth_destroy (void *priv) -{ - free (priv); - return 0; -} - - -static int -mutex_pth_lock (void *priv) -{ - int ret = pth_mutex_acquire ((pth_mutex_t *) priv, 0, NULL); - return ret == FALSE ? errno : 0; -} - - -static int -mutex_pth_unlock (void *priv) -{ - int ret = pth_mutex_release ((pth_mutex_t *) priv); - return ret == FALSE ? errno : 0; -} - - -static struct ath_ops ath_pth_ops = - { - mutex_pth_init, - mutex_pth_destroy, - mutex_pth_lock, - mutex_pth_unlock, - pth_read, - pth_write, - pth_select, - pth_waitpid, - pth_accept, - pth_connect, - NULL, /* FIXME: When GNU PTh has sendmsg. */ - NULL /* FIXME: When GNU PTh has recvmsg. */ - }; - - -struct ath_ops * -ath_pth_available (void) -{ - if (pth_mutex_init && pth_mutex_acquire && pth_mutex_release - && pth_read && pth_write && pth_select && pth_waitpid) - return &ath_pth_ops; - else - return 0; -} diff -urpNP gpgme-1.0.3/gpgme/ath-pthread-compat.c gpgme-1.1.0/gpgme/ath-pthread-compat.c --- gpgme-1.0.3/gpgme/ath-pthread-compat.c 2004-12-07 20:54:58.000000000 +0000 +++ gpgme-1.1.0/gpgme/ath-pthread-compat.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/* ath-pthread.c - pthread module for self-adapting thread-safeness library - Copyright (C) 2002, 2004 g10 Code GmbH - - This file is part of GPGME. - - GPGME is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - GPGME is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#include -#include -#include - -#include "ath.h" - -/* Need to include pthread_create in our check, as the GNU C library - has the pthread_mutex_* functions in their public interface. */ -#pragma weak pthread_create -#pragma weak pthread_mutex_init -#pragma weak pthread_mutex_destroy -#pragma weak pthread_mutex_lock -#pragma weak pthread_mutex_unlock - -/* The lock we take while checking for lazy lock initialization. */ -static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER; - -/* Initialize the mutex *PRIV. If JUST_CHECK is true, only do this if - it is not already initialized. */ -static int -mutex_pthread_init (void **priv, int just_check) -{ - int err = 0; - - if (just_check) - pthread_mutex_lock (&check_init_lock); - if (!*priv || !just_check) - { - pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t)); - if (!lock) - err = ENOMEM; - if (!err) - { - err = pthread_mutex_init (lock, NULL); - if (err) - free (lock); - else - *priv = lock; - } - } - if (just_check) - pthread_mutex_unlock (&check_init_lock); - return err; -} - - -static int -mutex_pthread_destroy (void *priv) -{ - int err = pthread_mutex_destroy ((pthread_mutex_t *) priv); - free (priv); - return err; -} - - -static struct ath_ops ath_pthread_ops = - { - mutex_pthread_init, - mutex_pthread_destroy, - (int (*) (void *)) pthread_mutex_lock, - (int (*) (void *)) pthread_mutex_unlock, - NULL, /* read */ - NULL, /* write */ - NULL, /* select */ - NULL, /* waitpid */ - NULL, /* accept */ - NULL, /* connect */ - NULL, /* sendmsg */ - NULL /* recvmsg */ - }; - - -struct ath_ops * -ath_pthread_available (void) -{ - /* Need to include pthread_create in our check, as the GNU C library - has the pthread_mutex_* functions in their public interface. */ - if (pthread_create - && pthread_mutex_init && pthread_mutex_destroy - && pthread_mutex_lock && pthread_mutex_unlock) - return &ath_pthread_ops; - else - return 0; -} diff -urpNP gpgme-1.0.3/gpgme/ath.c gpgme-1.1.0/gpgme/ath.c --- gpgme-1.0.3/gpgme/ath.c 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/gpgme/ath.c 2005-09-25 19:26:35.000000000 +0000 @@ -0,0 +1,169 @@ +/* ath.c - Thread-safeness library. + Copyright (C) 2002, 2003, 2004 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#ifdef HAVE_SYS_SELECT_H +# include +#else +# include +#endif +#include +#ifndef HAVE_W32_SYSTEM +#include +#endif + +#include "ath.h" + + +#define MUTEX_UNLOCKED ((ath_mutex_t) 0) +#define MUTEX_LOCKED ((ath_mutex_t) 1) +#define MUTEX_DESTROYED ((ath_mutex_t) 2) + + +int +ath_mutex_init (ath_mutex_t *lock) +{ +#ifndef NDEBUG + *lock = MUTEX_UNLOCKED; +#endif + return 0; +} + + +int +ath_mutex_destroy (ath_mutex_t *lock) +{ +#ifndef NDEBUG + assert (*lock == MUTEX_UNLOCKED); + + *lock = MUTEX_DESTROYED; +#endif + return 0; +} + + +int +ath_mutex_lock (ath_mutex_t *lock) +{ +#ifndef NDEBUG + assert (*lock == MUTEX_UNLOCKED); + + *lock = MUTEX_LOCKED; +#endif + return 0; +} + + +int +ath_mutex_unlock (ath_mutex_t *lock) +{ +#ifndef NDEBUG + assert (*lock == MUTEX_LOCKED); + + *lock = MUTEX_UNLOCKED; +#endif + return 0; +} + + +ssize_t +ath_read (int fd, void *buf, size_t nbytes) +{ + return read (fd, buf, nbytes); +} + + +ssize_t +ath_write (int fd, const void *buf, size_t nbytes) +{ + return write (fd, buf, nbytes); +} + + +ssize_t +ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout) +{ +#ifdef HAVE_W32_SYSTEM + return -1; /* Not supported. */ +#else + return select (nfd, rset, wset, eset, timeout); +#endif +} + + +ssize_t +ath_waitpid (pid_t pid, int *status, int options) +{ +#ifdef HAVE_W32_SYSTEM + return -1; /* Not supported. */ +#else + return waitpid (pid, status, options); +#endif +} + + +int +ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr) +{ +#ifdef HAVE_W32_SYSTEM + return -1; /* Not supported. */ +#else + return accept (s, addr, length_ptr); +#endif +} + + +int +ath_connect (int s, const struct sockaddr *addr, socklen_t length) +{ +#ifdef HAVE_W32_SYSTEM + return -1; /* Not supported. */ +#else + return connect (s, addr, length); +#endif +} + + +int +ath_sendmsg (int s, const struct msghdr *msg, int flags) +{ +#ifdef HAVE_W32_SYSTEM + return -1; /* Not supported. */ +#else + return sendmsg (s, msg, flags); +#endif +} + + +int +ath_recvmsg (int s, struct msghdr *msg, int flags) +{ +#ifdef HAVE_W32_SYSTEM + return -1; /* Not supported. */ +#else + return recvmsg (s, msg, flags); +#endif +} diff -urpNP gpgme-1.0.3/gpgme/ath.h gpgme-1.1.0/gpgme/ath.h --- gpgme-1.0.3/gpgme/ath.h 2004-12-07 20:55:34.000000000 +0000 +++ gpgme-1.1.0/gpgme/ath.h 2005-09-12 18:49:10.000000000 +0000 @@ -21,13 +21,25 @@ #ifndef ATH_H #define ATH_H -#ifdef HAVE_SYS_SELECT_H -# include -#else -# include -#endif -#include -#include +#ifdef HAVE_W32_SYSTEM + /* fixme: Check how we did it in libgcrypt. */ + struct msghdr { int dummy; }; + typedef int socklen_t; +# include +# include + +#else /*!HAVE_W32_SYSTEM*/ + +# ifdef HAVE_SYS_SELECT_H +# include +# else +# include +# endif +# include +# include + +#endif /*!HAVE_W32_SYSTEM*/ + /* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols @@ -74,34 +86,4 @@ int ath_connect (int s, const struct soc 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 */ diff -urpNP gpgme-1.0.3/gpgme/context.h gpgme-1.1.0/gpgme/context.h --- gpgme-1.0.3/gpgme/context.h 2004-12-07 20:54:36.000000000 +0000 +++ gpgme-1.1.0/gpgme/context.h 2005-10-01 02:06:07.000000000 +0000 @@ -1,6 +1,6 @@ /* context.h - Definitions for a GPGME context. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -63,6 +63,9 @@ typedef struct ctx_op_data *ctx_op_data_ be performed (sequentially). */ struct gpgme_context { + /* The engine info for this context. */ + gpgme_engine_info_t engine_info; + /* The protocol used by this context. */ gpgme_protocol_t protocol; @@ -88,6 +91,9 @@ struct gpgme_context unsigned int signers_size; gpgme_key_t *signers; + /* The signature notations for this context. */ + gpgme_sig_notation_t sig_notations; + /* The locale for the pinentry. */ char *lc_ctype; char *lc_messages; diff -urpNP gpgme-1.0.3/gpgme/data-compat.c gpgme-1.1.0/gpgme/data-compat.c --- gpgme-1.0.3/gpgme/data-compat.c 2004-12-07 20:54:19.000000000 +0000 +++ gpgme-1.1.0/gpgme/data-compat.c 2005-09-08 14:42:31.000000000 +0000 @@ -140,7 +140,7 @@ gpgme_error_to_errno (gpgme_error_t err) errno = EINVAL; return -1; case GPG_ERR_NOT_SUPPORTED: - errno = EOPNOTSUPP; + errno = ENOSYS; return -1; default: /* FIXME: Yeah, well. */ diff -urpNP gpgme-1.0.3/gpgme/data-stream.c gpgme-1.1.0/gpgme/data-stream.c --- gpgme-1.0.3/gpgme/data-stream.c 2004-12-07 20:53:50.000000000 +0000 +++ gpgme-1.1.0/gpgme/data-stream.c 2005-09-08 14:42:31.000000000 +0000 @@ -63,7 +63,11 @@ stream_seek (gpgme_data_t dh, off_t offs if (err) return -1; +#ifdef HAVE_FSEEKO return ftello (dh->data.stream); +#else + return ftell (dh->data.stream); +#endif } diff -urpNP gpgme-1.0.3/gpgme/data-user.c gpgme-1.1.0/gpgme/data-user.c --- gpgme-1.0.3/gpgme/data-user.c 2005-06-20 19:14:13.000000000 +0000 +++ gpgme-1.1.0/gpgme/data-user.c 2005-09-08 14:42:31.000000000 +0000 @@ -1,5 +1,5 @@ /* data-user.c - A user callback based data object. - Copyright (C) 2002, 2004, 2005 g10 Code GmbH + Copyright (C) 2002, 2004 g10 Code GmbH This file is part of GPGME. diff -urpNP gpgme-1.0.3/gpgme/data.c gpgme-1.1.0/gpgme/data.c --- gpgme-1.0.3/gpgme/data.c 2004-12-07 20:54:23.000000000 +0000 +++ gpgme-1.1.0/gpgme/data.c 2005-09-30 13:50:05.000000000 +0000 @@ -1,5 +1,5 @@ /* data.c - An abstraction for data objects. - Copyright (C) 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2002, 2003, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -31,7 +31,7 @@ #include "data.h" #include "util.h" #include "ops.h" -#include "io.h" +#include "priv-io.h" gpgme_error_t @@ -57,8 +57,12 @@ _gpgme_data_new (gpgme_data_t *r_dh, str void _gpgme_data_release (gpgme_data_t dh) { - if (dh) - free (dh); + if (!dh) + return; + + if (dh->file_name) + free (dh->file_name); + free (dh); } @@ -75,7 +79,7 @@ gpgme_data_read (gpgme_data_t dh, void * } if (!dh->cbs->read) { - errno = EOPNOTSUPP; + errno = ENOSYS; return -1; } return (*dh->cbs->read) (dh, buffer, size); @@ -95,7 +99,7 @@ gpgme_data_write (gpgme_data_t dh, const } if (!dh->cbs->write) { - errno = EOPNOTSUPP; + errno = ENOSYS; return -1; } return (*dh->cbs->write) (dh, buffer, size); @@ -115,7 +119,7 @@ gpgme_data_seek (gpgme_data_t dh, off_t } if (!dh->cbs->seek) { - errno = EOPNOTSUPP; + errno = ENOSYS; return -1; } @@ -167,6 +171,36 @@ gpgme_data_set_encoding (gpgme_data_t dh return 0; } + +/* Set the file name associated with the data object with handle DH to + FILE_NAME. */ +gpgme_error_t +gpgme_data_set_file_name (gpgme_data_t dh, const char *file_name) +{ + if (!dh) + return gpg_error (GPG_ERR_INV_VALUE); + + if (dh->file_name) + free (dh->file_name); + + dh->file_name = strdup (file_name); + if (!dh->file_name) + return gpg_error_from_errno (errno); + + return 0; +} + +/* Get the file name associated with the data object with handle DH, + or NULL if there is none. */ +char * +gpgme_data_get_file_name (gpgme_data_t dh) +{ + if (!dh) + return NULL; + + return dh->file_name; +} + /* Functions to support the wait interface. */ diff -urpNP gpgme-1.0.3/gpgme/data.h gpgme-1.1.0/gpgme/data.h --- gpgme-1.0.3/gpgme/data.h 2004-12-07 20:53:56.000000000 +0000 +++ gpgme-1.1.0/gpgme/data.h 2005-10-01 02:06:07.000000000 +0000 @@ -1,5 +1,5 @@ /* data.h - Internal data object abstraction interface. - Copyright (C) 2002, 2004 g10 Code GmbH + Copyright (C) 2002, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -77,6 +77,9 @@ struct gpgme_data char pending[BUFFER_SIZE]; int pending_len; + /* File name of the data object. */ + char *file_name; + union { /* For gpgme_data_new_from_fd. */ diff -urpNP gpgme-1.0.3/gpgme/debug.c gpgme-1.1.0/gpgme/debug.c --- gpgme-1.0.3/gpgme/debug.c 2004-12-07 20:53:35.000000000 +0000 +++ gpgme-1.1.0/gpgme/debug.c 2005-09-08 14:42:31.000000000 +0000 @@ -101,7 +101,7 @@ debug_init (void) if (e) { debug_level = atoi (e); - s1 = strchr (e, ':'); + s1 = strchr (e, PATHSEP_C); if (s1) { #ifndef HAVE_DOSISH_SYSTEM @@ -112,7 +112,7 @@ debug_init (void) FILE *fp; s1++; - if (!(s2 = strchr (s1, ':'))) + if (!(s2 = strchr (s1, PATHSEP_C))) s2 = s1 + strlen (s1); p = malloc (s2 - s1 + 1); if (p) diff -urpNP gpgme-1.0.3/gpgme/decrypt.c gpgme-1.1.0/gpgme/decrypt.c --- gpgme-1.0.3/gpgme/decrypt.c 2004-12-07 20:53:05.000000000 +0000 +++ gpgme-1.1.0/gpgme/decrypt.c 2005-09-30 13:50:05.000000000 +0000 @@ -38,6 +38,11 @@ typedef struct int okay; int failed; + + /* A pointer to the next pointer of the last recipient in the list. + This makes appending new invalid signers painless while + preserving the order. */ + gpgme_recipient_t *last_recipient_p; } *op_data_t; @@ -48,6 +53,9 @@ release_op_data (void *hook) if (opd->result.unsupported_algorithm) free (opd->result.unsupported_algorithm); + + if (opd->result.file_name) + free (opd->result.file_name); } @@ -67,6 +75,60 @@ gpgme_op_decrypt_result (gpgme_ctx_t ctx } +static gpgme_error_t +parse_enc_to (char *args, gpgme_recipient_t *recp) +{ + gpgme_recipient_t rec; + char *tail; + int i; + + rec = malloc (sizeof (*rec)); + if (!rec) + return gpg_error_from_errno (errno); + + rec->next = NULL; + rec->keyid = rec->_keyid; + rec->status = 0; + + for (i = 0; i < sizeof (rec->_keyid) - 1; i++) + { + if (args[i] == '\0' || args[i] == ' ') + break; + + rec->_keyid[i] = args[i]; + } + rec->_keyid[i] = '\0'; + + args = &args[i]; + if (*args != '\0' && *args != ' ') + { + free (rec); + return gpg_error (GPG_ERR_INV_ENGINE); + } + + while (*args == ' ') + args++; + + if (*args) + { + errno = 0; + rec->pubkey_algo = strtol (args, &tail, 0); + if (errno || args == tail || *tail != ' ') + { + /* The crypto backend does not behave. */ + free (rec); + return gpg_error (GPG_ERR_INV_ENGINE); + } + } + + /* FIXME: The key length is always 0 right now, so no need to parse + it. */ + + *recp = rec; + return 0; +} + + gpgme_error_t _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args) @@ -151,7 +213,39 @@ _gpgme_decrypt_status_handler (void *pri } } break; - + + case GPGME_STATUS_ENC_TO: + err = parse_enc_to (args, opd->last_recipient_p); + if (err) + return err; + + opd->last_recipient_p = &(*opd->last_recipient_p)->next; + break; + + case GPGME_STATUS_NO_SECKEY: + { + gpgme_recipient_t rec = opd->result.recipients; + + while (rec) + { + if (!strcmp (rec->keyid, args)) + { + rec->status = gpg_error (GPG_ERR_NO_SECKEY); + break; + } + rec = rec->next; + } + /* FIXME: Is this ok? */ + if (!rec) + return gpg_error (GPG_ERR_INV_ENGINE); + } + break; + + case GPGME_STATUS_PLAINTEXT: + err = _gpgme_parse_plaintext (args, &opd->result.file_name); + if (err) + return err; + default: break; } @@ -175,11 +269,18 @@ decrypt_status_handler (void *priv, gpgm gpgme_error_t _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx) { + gpgme_error_t err; void *hook; op_data_t opd; - return _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, - sizeof (*opd), release_op_data); + err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, + sizeof (*opd), release_op_data); + opd = hook; + if (err) + return err; + + opd->last_recipient_p = &opd->result.recipients; + return 0; } diff -urpNP gpgme-1.0.3/gpgme/edit.c gpgme-1.1.0/gpgme/edit.c --- gpgme-1.0.3/gpgme/edit.c 2004-12-07 20:52:42.000000000 +0000 +++ gpgme-1.1.0/gpgme/edit.c 2005-09-08 14:42:31.000000000 +0000 @@ -63,7 +63,7 @@ edit_status_handler (void *priv, gpgme_s static gpgme_error_t command_handler (void *priv, gpgme_status_code_t status, const char *args, - int fd) + int fd, int *processed_r) { gpgme_ctx_t ctx = (gpgme_ctx_t) priv; gpgme_error_t err; @@ -71,8 +71,8 @@ command_handler (void *priv, gpgme_statu if (ctx->passphrase_cb) { - err = _gpgme_passphrase_command_handler_internal (ctx, status, args, - fd, &processed); + err = _gpgme_passphrase_command_handler (ctx, status, args, + fd, &processed); if (err) return err; } @@ -87,8 +87,15 @@ command_handler (void *priv, gpgme_statu if (err) return err; + /* FIXME: We expect the user to handle _all_ status codes. + Later, we may fix the callback interface to allow the user + indicate if it processed the status code or not. */ + *processed_r = 1; + return (*opd->fnc) (opd->fnc_value, status, args, fd); } + + *processed_r = processed; return 0; } diff -urpNP gpgme-1.0.3/gpgme/engine-backend.h gpgme-1.1.0/gpgme/engine-backend.h --- gpgme-1.0.3/gpgme/engine-backend.h 2004-12-07 20:52:27.000000000 +0000 +++ gpgme-1.1.0/gpgme/engine-backend.h 2005-10-01 20:14:48.000000000 +0000 @@ -31,10 +31,21 @@ struct engine_ops { /* Static functions. */ + + /* Return the default file name for the binary of this engine. */ const char *(*get_file_name) (void); - const char *(*get_version) (void); + + /* Returns a malloced string containing the version of the engine + with the given binary file name (or the default if FILE_NAME is + NULL. */ + char *(*get_version) (const char *file_name); + + /* Returns a statically allocated string containing the required + version. */ const char *(*get_req_version) (void); + gpgme_error_t (*new) (void **r_engine, + const char *file_name, const char *home_dir, const char *lc_ctype, const char *lc_messages); /* Member functions. */ diff -urpNP gpgme-1.0.3/gpgme/engine-gpgsm.c gpgme-1.1.0/gpgme/engine-gpgsm.c --- gpgme-1.0.3/gpgme/engine-gpgsm.c 2005-05-28 19:37:54.000000000 +0000 +++ gpgme-1.1.0/gpgme/engine-gpgsm.c 2005-10-01 20:14:48.000000000 +0000 @@ -23,6 +23,8 @@ #include #endif +#ifndef HAVE_W32_SYSTEM + #include #include #include @@ -36,7 +38,7 @@ #include "util.h" #include "ops.h" #include "wait.h" -#include "io.h" +#include "priv-io.h" #include "sema.h" #include "assuan.h" @@ -83,7 +85,7 @@ struct engine_gpgsm void *fnc_value; struct { - unsigned char *line; + char *line; int linesize; int linelen; } attic; @@ -96,18 +98,11 @@ struct engine_gpgsm typedef struct engine_gpgsm *engine_gpgsm_t; -static const char * -gpgsm_get_version (void) +static char * +gpgsm_get_version (const char *file_name) { - static const char *gpgsm_version; - DEFINE_STATIC_LOCK (gpgsm_version_lock); - - LOCK (gpgsm_version_lock); - if (!gpgsm_version) - gpgsm_version = _gpgme_get_program_version (_gpgme_get_gpgsm_path ()); - UNLOCK (gpgsm_version_lock); - - return gpgsm_version; + return _gpgme_get_program_version (file_name ? file_name + : _gpgme_get_gpgsm_path ()); } @@ -320,11 +315,13 @@ gpgsm_release (void *engine) static gpgme_error_t -gpgsm_new (void **engine, const char *lc_ctype, const char *lc_messages) +gpgsm_new (void **engine, const char *file_name, const char *home_dir, + const char *lc_ctype, const char *lc_messages) { gpgme_error_t err = 0; engine_gpgsm_t gpgsm; - char *argv[3]; + const char *argv[5]; + int argc; int fds[2]; int child_fds[4]; char *dft_display = NULL; @@ -396,12 +393,19 @@ gpgsm_new (void **engine, const char *lc child_fds[2] = gpgsm->message_fd_server; child_fds[3] = -1; - argv[0] = "gpgsm"; - argv[1] = "--server"; - argv[2] = NULL; + argc = 0; + argv[argc++] = "gpgsm"; + if (home_dir) + { + argv[argc++] = "--homedir"; + argv[argc++] = home_dir; + } + argv[argc++] = "--server"; + argv[argc++] = NULL; err = assuan_pipe_connect (&gpgsm->assuan_ctx, - _gpgme_get_gpgsm_path (), argv, child_fds); + file_name ? file_name : _gpgme_get_gpgsm_path (), + argv, child_fds); /* FIXME: Check error. */ /* We need to know the fd used by assuan for reads. We do this by @@ -745,17 +749,16 @@ status_handler (void *opaque, int fd) /* FIXME We can't use this for binary data because we assume this is a string. For the current usage of colon output it is correct. */ - unsigned char *src = line + 2; - unsigned char *end = line + linelen; - unsigned char *dst; - unsigned char **aline = &gpgsm->colon.attic.line; + char *src = line + 2; + char *end = line + linelen; + char *dst; + char **aline = &gpgsm->colon.attic.line; int *alinelen = &gpgsm->colon.attic.linelen; if (gpgsm->colon.attic.linesize < *alinelen + linelen + 1) { - unsigned char *newline = realloc (*aline, - *alinelen + linelen + 1); + char *newline = realloc (*aline, *alinelen + linelen + 1); if (!newline) err = gpg_error_from_errno (errno); else @@ -774,7 +777,7 @@ status_handler (void *opaque, int fd) { /* Handle escaped characters. */ ++src; - *dst = (unsigned char) _gpgme_hextobyte (src); + *dst = _gpgme_hextobyte (src); (*alinelen)++; src += 2; } @@ -1602,3 +1605,5 @@ struct engine_ops _gpgme_engine_ops_gpgs gpgsm_io_event, gpgsm_cancel }; + +#endif /*!HAVE_W32_SYSTEM*/ diff -urpNP gpgme-1.0.3/gpgme/engine.c gpgme-1.1.0/gpgme/engine.c --- gpgme-1.0.3/gpgme/engine.c 2004-12-07 20:52:18.000000000 +0000 +++ gpgme-1.1.0/gpgme/engine.c 2005-10-01 20:14:48.000000000 +0000 @@ -25,6 +25,7 @@ #include #include #include +#include #include "gpgme.h" #include "util.h" @@ -52,6 +53,11 @@ static struct engine_ops *engine_ops[] = #endif }; + +/* The engine info. */ +static gpgme_engine_info_t engine_info; +DEFINE_STATIC_LOCK (engine_info_lock); + /* Get the file name of the engine for PROTOCOL. */ static const char * @@ -67,15 +73,16 @@ engine_get_file_name (gpgme_protocol_t p } -/* Get the version number of the engine for PROTOCOL. */ -static const char * -engine_get_version (gpgme_protocol_t proto) +/* Get a malloced string containing the version number of the engine + for PROTOCOL. */ +static char * +engine_get_version (gpgme_protocol_t proto, const char *file_name) { if (proto > DIM (engine_ops)) return NULL; if (engine_ops[proto] && engine_ops[proto]->get_version) - return (*engine_ops[proto]->get_version) (); + return (*engine_ops[proto]->get_version) (file_name); else return NULL; } @@ -99,21 +106,45 @@ engine_get_req_version (gpgme_protocol_t 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); + int result; + char *engine_version = engine_get_version (proto, NULL); + + result = _gpgme_compare_versions (engine_version, + engine_get_req_version (proto)); + if (engine_version) + free (engine_version); + + return result ? 0 : gpg_error (GPG_ERR_INV_ENGINE); +} + + +/* Release the engine info INFO. */ +void +_gpgme_engine_info_release (gpgme_engine_info_t info) +{ + while (info) + { + gpgme_engine_info_t next_info = info->next; + + assert (info->file_name); + free (info->file_name); + if (info->home_dir) + free (info->home_dir); + if (info->version) + free (info->version); + free (info); + info = next_info; + } } /* Get the information about the configured and installed engines. A pointer to the first engine in the statically allocated linked list - is returned in *INFO. If an error occurs, it is returned. */ + is returned in *INFO. If an error occurs, it is returned. The + returned data is valid until the next gpgme_set_engine_info. */ gpgme_error_t gpgme_get_engine_info (gpgme_engine_info_t *info) { - static gpgme_engine_info_t engine_info; - DEFINE_STATIC_LOCK (engine_info_lock); - LOCK (engine_info_lock); if (!engine_info) { @@ -124,70 +155,239 @@ gpgme_get_engine_info (gpgme_engine_info for (proto = 0; proto < DIM (proto_list); proto++) { - const char *file_name = engine_get_file_name (proto_list[proto]); + const char *ofile_name = engine_get_file_name (proto_list[proto]); + char *file_name; - if (!file_name) + if (!ofile_name) continue; + file_name = strdup (ofile_name); + *lastp = malloc (sizeof (*engine_info)); - if (!*lastp) + if (!*lastp || !file_name) { int saved_errno = errno; - while (engine_info) - { - gpgme_engine_info_t next_info = engine_info->next; - free (engine_info); - engine_info = next_info; - } + _gpgme_engine_info_release (engine_info); + engine_info = NULL; + + if (file_name) + free (file_name); + UNLOCK (engine_info_lock); return gpg_error_from_errno (saved_errno); } (*lastp)->protocol = proto_list[proto]; (*lastp)->file_name = file_name; - (*lastp)->version = engine_get_version (proto_list[proto]); + (*lastp)->home_dir = NULL; + (*lastp)->version = engine_get_version (proto_list[proto], NULL); (*lastp)->req_version = engine_get_req_version (proto_list[proto]); (*lastp)->next = NULL; lastp = &(*lastp)->next; } } - UNLOCK (engine_info_lock); + *info = engine_info; + UNLOCK (engine_info_lock); return 0; } - + +/* Get a deep copy of the engine info and return it in INFO. */ gpgme_error_t -_gpgme_engine_new (gpgme_protocol_t proto, engine_t *r_engine, - const char *lc_ctype, const char *lc_messages) +_gpgme_engine_info_copy (gpgme_engine_info_t *r_info) { - engine_t engine; + gpgme_error_t err = 0; + gpgme_engine_info_t info; + gpgme_engine_info_t new_info; + gpgme_engine_info_t *lastp; + + LOCK (engine_info_lock); + info = engine_info; + if (!info) + { + /* Make sure it is initialized. */ + UNLOCK (engine_info_lock); + err = gpgme_get_engine_info (&info); + if (err) + return err; + + LOCK (engine_info_lock); + } + + new_info = NULL; + lastp = &new_info; + + while (info) + { + char *file_name; + char *home_dir; + char *version; + + assert (info->file_name); + file_name = strdup (info->file_name); + + if (info->home_dir) + { + home_dir = strdup (info->home_dir); + if (!home_dir) + err = gpg_error_from_errno (errno); + } + else + home_dir = NULL; + + if (info->version) + { + version = strdup (info->version); + if (!version) + err = gpg_error_from_errno (errno); + } + else + version = NULL; + + *lastp = malloc (sizeof (*engine_info)); + if (!*lastp || !file_name || err) + { + int saved_errno = errno; + + _gpgme_engine_info_release (new_info); + + if (file_name) + free (file_name); + if (home_dir) + free (home_dir); + if (version) + free (version); + + UNLOCK (engine_info_lock); + return gpg_error_from_errno (saved_errno); + } - const char *file_name; - const char *version; + (*lastp)->protocol = info->protocol; + (*lastp)->file_name = file_name; + (*lastp)->home_dir = home_dir; + (*lastp)->version = version; + (*lastp)->req_version = info->req_version; + (*lastp)->next = NULL; + lastp = &(*lastp)->next; + info = info->next; + } + + *r_info = new_info; + UNLOCK (engine_info_lock); + return 0; +} + + +/* Set the engine info for the info list INFO, protocol PROTO, to the + file name FILE_NAME and the home directory HOME_DIR. */ +gpgme_error_t +_gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto, + const char *file_name, const char *home_dir) +{ + char *new_file_name; + char *new_home_dir; + + /* FIXME: Use some PROTO_MAX definition. */ if (proto > DIM (engine_ops)) return gpg_error (GPG_ERR_INV_VALUE); - if (!engine_ops[proto]) + while (info && info->protocol != proto) + info = info->next; + + if (!info) return gpg_error (GPG_ERR_INV_ENGINE); - file_name = engine_get_file_name (proto); - version = engine_get_version (proto); - if (!file_name || !version) + /* Prepare new members. */ + if (file_name) + new_file_name = strdup (file_name); + else + { + const char *ofile_name = engine_get_file_name (proto); + assert (ofile_name); + new_file_name = strdup (ofile_name); + } + if (!new_file_name) + return gpg_error_from_errno (errno); + + if (home_dir) + { + new_home_dir = strdup (home_dir); + if (!new_home_dir) + { + free (new_file_name); + return gpg_error_from_errno (errno); + } + } + else + new_home_dir = NULL; + + /* Remove the old members. */ + assert (info->file_name); + free (info->file_name); + if (info->home_dir) + free (info->home_dir); + if (info->version) + free (info->version); + + /* Install the new members. */ + info->file_name = new_file_name; + info->home_dir = new_home_dir; + info->version = engine_get_version (proto, file_name); + + return 0; +} + + +/* Set the default engine info for the protocol PROTO to the file name + FILE_NAME and the home directory HOME_DIR. */ +gpgme_error_t +gpgme_set_engine_info (gpgme_protocol_t proto, + const char *file_name, const char *home_dir) +{ + gpgme_error_t err; + gpgme_engine_info_t info; + + LOCK (engine_info_lock); + info = engine_info; + if (!info) + { + /* Make sure it is initialized. */ + UNLOCK (engine_info_lock); + err = gpgme_get_engine_info (&info); + if (err) + return err; + + LOCK (engine_info_lock); + } + + err = _gpgme_set_engine_info (info, proto, file_name, home_dir); + UNLOCK (engine_info_lock); + return err; +} + + +gpgme_error_t +_gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine, + const char *lc_ctype, const char *lc_messages) +{ + engine_t engine; + + if (!info->file_name || !info->version) return gpg_error (GPG_ERR_INV_ENGINE); engine = calloc (1, sizeof *engine); if (!engine) return gpg_error_from_errno (errno); - engine->ops = engine_ops[proto]; - if (engine_ops[proto]->new) + engine->ops = engine_ops[info->protocol]; + if (engine->ops->new) { - gpgme_error_t err = (*engine_ops[proto]->new) (&engine->engine, - lc_ctype, - lc_messages); + gpgme_error_t err = (*engine->ops->new) (&engine->engine, + info->file_name, info->home_dir, + lc_ctype, lc_messages); if (err) { free (engine); diff -urpNP gpgme-1.0.3/gpgme/engine.h gpgme-1.1.0/gpgme/engine.h --- gpgme-1.0.3/gpgme/engine.h 2004-12-07 20:51:53.000000000 +0000 +++ gpgme-1.1.0/gpgme/engine.h 2005-10-01 20:14:48.000000000 +0000 @@ -34,9 +34,23 @@ typedef gpgme_error_t (*engine_colon_lin typedef gpgme_error_t (*engine_command_handler_t) (void *priv, gpgme_status_code_t code, const char *keyword, - int fd); + int fd, int *processed); -gpgme_error_t _gpgme_engine_new (gpgme_protocol_t proto, +/* Get a deep copy of the engine info and return it in INFO. */ +gpgme_error_t _gpgme_engine_info_copy (gpgme_engine_info_t *r_info); + +/* Release the engine info INFO. */ +void _gpgme_engine_info_release (gpgme_engine_info_t info); + +/* Set the engine info for the info list INFO, protocol PROTO, to the + file name FILE_NAME and the home directory HOME_DIR. */ +gpgme_error_t _gpgme_set_engine_info (gpgme_engine_info_t info, + gpgme_protocol_t praoto, + const char *file_name, + const char *home_dir); + + +gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine, const char *lc_ctype, const char *lc_messages); diff -urpNP gpgme-1.0.3/gpgme/gpgme.c gpgme-1.1.0/gpgme/gpgme.c --- gpgme-1.0.3/gpgme/gpgme.c 2005-06-20 19:14:19.000000000 +0000 +++ gpgme-1.1.0/gpgme/gpgme.c 2005-10-01 02:06:07.000000000 +0000 @@ -1,6 +1,6 @@ /* gpgme.c - GnuPG Made Easy. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH This file is part of GPGME. @@ -51,6 +51,14 @@ gpgme_new (gpgme_ctx_t *r_ctx) ctx = calloc (1, sizeof *ctx); if (!ctx) return gpg_error_from_errno (errno); + + _gpgme_engine_info_copy (&ctx->engine_info); + if (!ctx->engine_info) + { + free (ctx); + return gpg_error_from_errno (errno); + } + ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL; ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT; ctx->protocol = GPGME_PROTOCOL_OpenPGP; @@ -63,6 +71,7 @@ gpgme_new (gpgme_ctx_t *r_ctx) if (!ctx->lc_ctype) { UNLOCK (def_lc_lock); + _gpgme_engine_info_release (ctx->engine_info); free (ctx); return gpg_error_from_errno (errno); } @@ -78,6 +87,7 @@ gpgme_new (gpgme_ctx_t *r_ctx) UNLOCK (def_lc_lock); if (ctx->lc_ctype) free (ctx->lc_ctype); + _gpgme_engine_info_release (ctx->engine_info); free (ctx); return gpg_error_from_errno (errno); } @@ -121,6 +131,7 @@ gpgme_release (gpgme_ctx_t ctx) free (ctx->lc_ctype); if (ctx->lc_messages) free (ctx->lc_messages); + _gpgme_engine_info_release (ctx->engine_info); free (ctx); } @@ -335,6 +346,7 @@ gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value) { +#ifndef HAVE_W32_SYSTEM int failed = 0; char *new_lc_ctype; char *new_lc_messages; @@ -389,9 +401,99 @@ gpgme_set_locale (gpgme_ctx_t ctx, int c if (!ctx) UNLOCK (def_lc_lock); +#endif /*!HAVE_W32_SYSTEM*/ + + return 0; +} + + +/* Get the information about the configured engines. A pointer to the + first engine in the statically allocated linked list is returned. + The returned data is valid until the next gpgme_ctx_set_engine_info. */ +gpgme_engine_info_t +gpgme_ctx_get_engine_info (gpgme_ctx_t ctx) +{ + return ctx->engine_info; +} + + +/* Set the engine info for the context CTX, protocol PROTO, to the + file name FILE_NAME and the home directory HOME_DIR. */ +gpgme_error_t +gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto, + const char *file_name, const char *home_dir) +{ + /* FIXME: Make sure to reset the context if we are running in daemon + mode. */ + return _gpgme_set_engine_info (ctx->engine_info, proto, + file_name, home_dir); +} + + +/* Clear all notation data from the context. */ +void +gpgme_sig_notation_clear (gpgme_ctx_t ctx) +{ + gpgme_sig_notation_t notation; + + if (!ctx) + return; + + notation = ctx->sig_notations; + while (notation) + { + gpgme_sig_notation_t next_notation = notation->next; + _gpgme_sig_notation_free (notation); + notation = next_notation; + } +} + + +/* Add the human-readable notation data with name NAME and value VALUE + to the context CTX, using the flags FLAGS. If NAME is NULL, then + VALUE should be a policy URL. The flag + GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation + data, and false for policy URLs. */ +gpgme_error_t +gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name, + const char *value, gpgme_sig_notation_flags_t flags) +{ + gpgme_error_t err; + gpgme_sig_notation_t notation; + gpgme_sig_notation_t *lastp; + + if (!ctx) + gpg_error (GPG_ERR_INV_VALUE); + + if (name) + flags |= GPGME_SIG_NOTATION_HUMAN_READABLE; + else + flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE; + + err = _gpgme_sig_notation_create (¬ation, name, name ? strlen (name) : 0, + value, value ? strlen (value) : 0, flags); + if (err) + return err; + + lastp = &ctx->sig_notations; + while (*lastp) + lastp = &(*lastp)->next; + + *lastp = notation; return 0; } + +/* Get the sig notations for this context. */ +gpgme_sig_notation_t +gpgme_sig_notation_get (gpgme_ctx_t ctx) +{ + if (!ctx) + return NULL; + + return ctx->sig_notations; +} + const char * gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo) diff -urpNP gpgme-1.0.3/gpgme/gpgme.def gpgme-1.1.0/gpgme/gpgme.def --- gpgme-1.0.3/gpgme/gpgme.def 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/gpgme/gpgme.def 2005-10-01 02:06:07.000000000 +0000 @@ -0,0 +1,155 @@ +; gpgme.def - List of symbols to export. +; Copyright (C) 2005 g10 Code GmbH +; +; This file is part of GPGME. +; +; GPGME is free software; you can redistribute it and/or modify +; it under the terms of the GNU Lesser general Public License as +; published by the Free Software Foundation; either version 2.1 of +; the License, or (at your option) any later version. +; +; GPGME is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU Lesser General Public License for more details. +; +; You should have received a copy of the GNU Lesser General Public +; License along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + + +EXPORTS + gpgme_check_version @1 + gpgme_get_engine_info @2 + gpgme_engine_check_version @3 + + gpgme_err_code_from_errno @4 + gpgme_err_code_to_errno @5 + gpgme_err_make_from_errno @6 + gpgme_error_from_errno @7 + gpgme_strerror @8 + gpgme_strerror_r @9 + gpgme_strsource @10 + + gpgme_data_get_encoding @11 + gpgme_data_new @12 + gpgme_data_new_from_cbs @13 + gpgme_data_new_from_fd @14 + gpgme_data_new_from_file @15 + gpgme_data_new_from_filepart @16 + gpgme_data_new_from_mem @17 + gpgme_data_new_from_stream @18 + gpgme_data_read @19 + gpgme_data_release @20 + gpgme_data_release_and_get_mem @21 + gpgme_data_seek @22 + gpgme_data_set_encoding @23 + gpgme_data_write @24 + + gpgme_get_protocol_name @25 + gpgme_hash_algo_name @26 + gpgme_pubkey_algo_name @27 + + gpgme_new @28 + gpgme_get_armor @29 + gpgme_get_include_certs @30 + gpgme_get_io_cbs @31 + gpgme_get_keylist_mode @32 + gpgme_get_passphrase_cb @33 + gpgme_get_progress_cb @34 + gpgme_get_protocol @35 + gpgme_get_textmode @36 + gpgme_release @37 + gpgme_set_armor @38 + gpgme_set_include_certs @39 + gpgme_set_io_cbs @40 + gpgme_set_keylist_mode @41 + gpgme_set_locale @42 + gpgme_set_passphrase_cb @43 + gpgme_set_progress_cb @44 + gpgme_set_protocol @45 + gpgme_set_textmode @46 + gpgme_signers_add @47 + gpgme_signers_clear @48 + gpgme_signers_enum @49 + + gpgme_key_ref @50 + gpgme_key_unref @51 + gpgme_key_release @52 + + gpgme_trust_item_ref @53 + gpgme_trust_item_unref @54 + + gpgme_cancel @55 + gpgme_op_card_edit @56 + gpgme_op_card_edit_start @57 + gpgme_op_decrypt @58 + gpgme_op_decrypt_result @59 + gpgme_op_decrypt_start @60 + gpgme_op_decrypt_verify @61 + gpgme_op_decrypt_verify_start @62 + gpgme_op_delete @63 + gpgme_op_delete_start @64 + gpgme_op_edit @65 + gpgme_op_edit_start @66 + gpgme_op_encrypt @67 + gpgme_op_encrypt_result @68 + gpgme_op_encrypt_sign @69 + gpgme_op_encrypt_sign_start @70 + gpgme_op_encrypt_start @71 + gpgme_op_export @72 + gpgme_op_export_ext @73 + gpgme_op_export_ext_start @74 + gpgme_op_export_start @75 + gpgme_op_genkey @76 + gpgme_op_genkey_result @77 + gpgme_op_genkey_start @78 + gpgme_get_key @79 + gpgme_op_import @80 + gpgme_op_import_result @81 + gpgme_op_import_start @82 + gpgme_op_keylist_end @83 + gpgme_op_keylist_ext_start @84 + gpgme_op_keylist_next @85 + gpgme_op_keylist_result @86 + gpgme_op_keylist_start @87 + gpgme_op_sign @88 + gpgme_op_sign_result @89 + gpgme_op_sign_start @90 + gpgme_op_trustlist_end @91 + gpgme_op_trustlist_next @92 + gpgme_op_trustlist_start @93 + gpgme_op_verify @94 + gpgme_op_verify_result @95 + gpgme_op_verify_start @96 + gpgme_wait @97 + + gpgme_data_new_with_read_cb @98 + gpgme_data_rewind @99 + gpgme_get_sig_status @100 + gpgme_get_sig_string_attr @101 + gpgme_get_sig_ulong_attr @102 + gpgme_get_sig_key @103 + gpgme_key_get_string_attr @104 + gpgme_key_get_ulong_attr @105 + gpgme_key_sig_get_string_attr @106 + gpgme_key_sig_get_ulong_attr @107 + gpgme_op_import_ext @108 + gpgme_trust_item_get_int_attr @109 + gpgme_trust_item_get_string_attr @110 + gpgme_trust_item_release @111 + + gpgme_set_engine_info @112 + + gpgme_ctx_get_engine_info @113 + gpgme_ctx_set_engine_info @114 + + gpgme_data_set_file_name @115 + gpgme_data_get_file_name @116 + + gpgme_sig_notation_clear @117 + gpgme_sig_notation_add @118 + gpgme_sig_notation_get @119 + +; END + diff -urpNP gpgme-1.0.3/gpgme/gpgme.h gpgme-1.1.0/gpgme/gpgme.h --- gpgme-1.0.3/gpgme/gpgme.h 2005-06-20 19:19:04.000000000 +0000 +++ gpgme-1.1.0/gpgme/gpgme.h 2005-10-01 21:13:02.000000000 +0000 @@ -38,9 +38,6 @@ typedef long ssize_t; #else # include -#ifdef _WIN32 -typedef long ssize_t; -#endif #endif #ifdef __cplusplus @@ -75,7 +72,8 @@ extern "C" { AM_PATH_GPGME macro) check that this header matches the installed library. Warning: Do not edit the next line. configure will do that for you! */ -#define GPGME_VERSION "1.0.3" +#define GPGME_VERSION "1.1.0" + /* Some opaque data types used by GPGME. */ @@ -315,6 +313,46 @@ gpgme_protocol_t; typedef unsigned int gpgme_keylist_mode_t; +/* Signature notations. */ + +/* The available signature notation flags. */ +#define GPGME_SIG_NOTATION_HUMAN_READABLE 1 +#define GPGME_SIG_NOTATION_CRITICAL 2 + +typedef unsigned int gpgme_sig_notation_flags_t; + +struct _gpgme_sig_notation +{ + struct _gpgme_sig_notation *next; + + /* If NAME is a null pointer, then VALUE contains a policy URL + rather than a notation. */ + char *name; + + /* The value of the notation data. */ + char *value; + + /* The length of the name of the notation data. */ + int name_len; + + /* The length of the value of the notation data. */ + int value_len; + + /* The accumulated flags. */ + gpgme_sig_notation_flags_t flags; + + /* Notation data is human-readable. */ + unsigned int human_readable : 1; + + /* Notation data is critical. */ + unsigned int critical : 1; + + /* Internal to GPGME, do not use. */ + int _unused : 30; +}; +typedef struct _gpgme_sig_notation *gpgme_sig_notation_t; + + /* The possible stati for the edit operation. */ typedef enum { @@ -400,7 +438,14 @@ typedef enum GPGME_STATUS_ERROR, GPGME_STATUS_NEWSIG, GPGME_STATUS_REVKEYSIG, - GPGME_STATUS_NEED_PASSPHRASE_PIN + GPGME_STATUS_SIG_SUBPACKET, + GPGME_STATUS_NEED_PASSPHRASE_PIN, + GPGME_STATUS_SC_OP_FAILURE, + GPGME_STATUS_SC_OP_SUCCESS, + GPGME_STATUS_CARDCTRL, + GPGME_STATUS_BACKUP_KEY_CREATED, + + GPGME_STATUS_PLAINTEXT } gpgme_status_code_t; @@ -414,13 +459,16 @@ struct _gpgme_engine_info gpgme_protocol_t protocol; /* The file name of the engine binary. */ - const char *file_name; - + char *file_name; + /* The version string of the installed engine. */ - const char *version; + char *version; /* The minimum version required for GPGME. */ const char *req_version; + + /* The home directory used, or NULL if default. */ + char *home_dir; }; typedef struct _gpgme_engine_info *gpgme_engine_info_t; @@ -457,8 +505,11 @@ struct _gpgme_subkey /* True if subkey can be used for authentication. */ unsigned int can_authenticate : 1; + /* True if subkey is qualified for signatures according to German law. */ + unsigned int is_qualified : 1; + /* Internal to GPGME, do not use. */ - unsigned int _unused : 23; + unsigned int _unused : 22; /* Public key algorithm supported by this subkey. */ gpgme_pubkey_algo_t pubkey_algo; @@ -618,8 +669,11 @@ struct _gpgme_key /* True if key can be used for authentication. */ unsigned int can_authenticate : 1; + /* True if subkey is qualified for signatures according to German law. */ + unsigned int is_qualified : 1; + /* Internal to GPGME, do not use. */ - unsigned int _unused : 23; + unsigned int _unused : 22; /* This is the protocol supported by this key. */ gpgme_protocol_t protocol; @@ -746,6 +800,19 @@ void gpgme_get_progress_cb (gpgme_ctx_t locale if CTX is a null pointer. */ gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value); + +/* Get the information about the configured engines. A pointer to the + first engine in the statically allocated linked list is returned. + The returned data is valid until the next gpgme_ctx_set_engine_info. */ +gpgme_engine_info_t gpgme_ctx_get_engine_info (gpgme_ctx_t ctx); + +/* Set the engine info for the context CTX, protocol PROTO, to the + file name FILE_NAME and the home directory HOME_DIR. */ +gpgme_error_t gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, + gpgme_protocol_t proto, + const char *file_name, + const char *home_dir); + /* Return a statically allocated string with the name of the public key algorithm ALGO, or NULL if that name is not known. */ @@ -792,6 +859,22 @@ gpgme_error_t gpgme_get_sig_key (gpgme_c _GPGME_DEPRECATED; +/* Clear all notation data from the context. */ +void gpgme_sig_notation_clear (gpgme_ctx_t ctx); + +/* Add the human-readable notation data with name NAME and value VALUE + to the context CTX, using the flags FLAGS. If NAME is NULL, then + VALUE should be a policy URL. The flag + GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation + data, and false for policy URLs. */ +gpgme_error_t gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name, + const char *value, + gpgme_sig_notation_flags_t flags); + +/* Get the sig notations for this context. */ +gpgme_sig_notation_t gpgme_sig_notation_get (gpgme_ctx_t ctx); + + /* Run control. */ /* The type of an I/O callback function. */ @@ -925,6 +1008,14 @@ gpgme_data_encoding_t gpgme_data_get_enc gpgme_error_t gpgme_data_set_encoding (gpgme_data_t dh, gpgme_data_encoding_t enc); +/* Get the filename associated with the data object with handle DH, or + NULL if there is none. */ +char *gpgme_data_get_file_name (gpgme_data_t dh); + +/* Set the filename associated with the data object with handle DH to + FILE_NAME. */ +gpgme_error_t gpgme_data_set_file_name (gpgme_data_t dh, + const char *file_name); /* Create a new data buffer which retrieves the data from the callback @@ -1061,6 +1152,25 @@ gpgme_error_t gpgme_op_encrypt_sign (gpg /* Decryption. */ + +struct _gpgme_recipient +{ + struct _gpgme_recipient *next; + + /* The key ID of key for which the text was encrypted. */ + char *keyid; + + /* Internal to GPGME, do not use. */ + char _keyid[16 + 1]; + + /* The public key algorithm of the recipient key. */ + gpgme_pubkey_algo_t pubkey_algo; + + /* The status of the recipient. */ + gpgme_error_t status; +}; +typedef struct _gpgme_recipient *gpgme_recipient_t; + struct _gpgme_op_decrypt_result { char *unsupported_algorithm; @@ -1070,6 +1180,12 @@ struct _gpgme_op_decrypt_result /* Internal to GPGME, do not use. */ int _unused : 31; + + gpgme_recipient_t recipients; + + /* The original file name of the plaintext message, if + available. */ + char *file_name; }; typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t; @@ -1149,16 +1265,6 @@ gpgme_error_t gpgme_op_sign (gpgme_ctx_t /* Verify. */ -struct _gpgme_sig_notation -{ - struct _gpgme_sig_notation *next; - - /* If NAME is a null pointer, then VALUE contains a policy URL - rather than a notation. */ - char *name; - char *value; -}; -typedef struct _gpgme_sig_notation *gpgme_sig_notation_t; /* Flags used for the SUMMARY field in a gpgme_signature_t. */ typedef enum @@ -1207,12 +1313,22 @@ struct _gpgme_signature gpgme_validity_t validity; gpgme_error_t validity_reason; + + /* The public key algorithm used to create the signature. */ + gpgme_pubkey_algo_t pubkey_algo; + + /* The hash algorithm used to create the signature. */ + gpgme_hash_algo_t hash_algo; }; typedef struct _gpgme_signature *gpgme_signature_t; struct _gpgme_op_verify_result { gpgme_signature_t signatures; + + /* The original file name of the plaintext message, if + available. */ + char *file_name; }; typedef struct _gpgme_op_verify_result *gpgme_verify_result_t; @@ -1506,9 +1622,18 @@ int gpgme_trust_item_get_int_attr (gpgme /* Check that the library fulfills the version requirement. */ const char *gpgme_check_version (const char *req_version); -/* Retrieve information about the backend engines. */ +/* Get the information about the configured and installed engines. A + pointer to the first engine in the statically allocated linked list + is returned in *INFO. If an error occurs, it is returned. The + returned data is valid until the next gpgme_set_engine_info. */ gpgme_error_t gpgme_get_engine_info (gpgme_engine_info_t *engine_info); +/* Set the default engine info for the protocol PROTO to the file name + FILE_NAME and the home directory HOME_DIR. */ +gpgme_error_t gpgme_set_engine_info (gpgme_protocol_t proto, + const char *file_name, + const char *home_dir); + /* Engine support functions. */ diff -urpNP gpgme-1.0.3/gpgme/gpgme.m4 gpgme-1.1.0/gpgme/gpgme.m4 --- gpgme-1.0.3/gpgme/gpgme.m4 2005-06-20 19:13:12.000000000 +0000 +++ gpgme-1.1.0/gpgme/gpgme.m4 2005-09-08 14:42:31.000000000 +0000 @@ -1,5 +1,5 @@ # gpgme.m4 - autoconf macro to detect GPGME. -# Copyright (C) 2002, 2003, 2004, 2005 g10 Code GmbH +# Copyright (C) 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 diff -urpNP gpgme-1.0.3/gpgme/io.h gpgme-1.1.0/gpgme/io.h --- gpgme-1.0.3/gpgme/io.h 2004-12-07 20:47:00.000000000 +0000 +++ gpgme-1.1.0/gpgme/io.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* io.h - Interface to the I/O functions. - Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH - - This file is part of GPGME. - - GPGME is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - GPGME is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef IO_H -#define IO_H - -/* A single file descriptor passed to spawn. For child fds, dup_to - specifies the fd it should become in the child. */ -struct spawn_fd_item_s -{ - int fd; - int dup_to; -}; - -struct io_select_fd_s -{ - int fd; - int for_read; - int for_write; - int signaled; - int frozen; - void *opaque; -}; - -/* These function are either defined in posix-io.c or w32-io.c. */ -void _gpgme_io_subsystem_init (void); -int _gpgme_io_read (int fd, void *buffer, size_t count); -int _gpgme_io_write (int fd, const void *buffer, size_t count); -int _gpgme_io_pipe (int filedes[2], int inherit_idx); -int _gpgme_io_close (int fd); -int _gpgme_io_set_close_notify (int fd, void (*handler) (int, void *), - void *value); -int _gpgme_io_set_nonblocking (int fd); - -/* Spawn the executable PATH with ARGV as arguments, after forking - close all fds in FD_PARENT_LIST in the parent and close or dup all - fds in FD_CHILD_LIST in the child. */ -int _gpgme_io_spawn (const char *path, char **argv, - struct spawn_fd_item_s *fd_child_list, - struct spawn_fd_item_s *fd_parent_list); -int _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal); -int _gpgme_io_kill (int pid, int hard); -int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock); - -#endif /* IO_H */ - - - diff -urpNP gpgme-1.0.3/gpgme/keylist.c gpgme-1.1.0/gpgme/keylist.c --- gpgme-1.0.3/gpgme/keylist.c 2004-12-07 20:42:12.000000000 +0000 +++ gpgme-1.1.0/gpgme/keylist.c 2005-09-29 17:29:14.000000000 +0000 @@ -48,6 +48,7 @@ typedef struct struct _gpgme_op_keylist_result result; gpgme_key_t tmp_key; + /* This points to the last uid in tmp_key. */ gpgme_user_id_t tmp_uid; /* Something new is available. */ int key_cond; @@ -63,8 +64,9 @@ release_op_data (void *hook) if (opd->tmp_key) gpgme_key_unref (opd->tmp_key); - if (opd->tmp_uid) - free (opd->tmp_uid); + /* opd->tmp_uid is actually part of opd->tmp_key, so we do not need + to release it here. */ + while (key) { struct key_queue_item_s *next = key->next; @@ -244,6 +246,10 @@ set_subkey_capability (gpgme_subkey_t su subkey->can_authenticate = 1; break; + case 'q': + subkey->is_qualified = 1; + break; + case 'd': subkey->disabled = 1; break; @@ -292,6 +298,11 @@ set_mainkey_capability (gpgme_key_t key, case 'A': key->can_authenticate = 1; break; + + case 'q': + case 'Q': + key->is_qualified = 1; + break; } src++; } @@ -842,7 +853,7 @@ gpgme_get_key (gpgme_ctx_t ctx, const ch if (!ctx || !r_key || !fpr) return gpg_error (GPG_ERR_INV_VALUE); - if (strlen (fpr) < 16) /* We have at least a key ID. */ + if (strlen (fpr) < 8) /* We have at least a key ID. */ return gpg_error (GPG_ERR_INV_VALUE); /* FIXME: We use our own context because we have to avoid the user's diff -urpNP gpgme-1.0.3/gpgme/libgpgme.vers gpgme-1.1.0/gpgme/libgpgme.vers --- gpgme-1.0.3/gpgme/libgpgme.vers 2004-12-07 20:41:44.000000000 +0000 +++ gpgme-1.1.0/gpgme/libgpgme.vers 2005-10-01 02:06:07.000000000 +0000 @@ -1,5 +1,5 @@ # libgpgme.vers - List of symbols to export. -# Copyright (C) 2002, 2004 g10 Code GmbH +# Copyright (C) 2002, 2004, 2005 g10 Code GmbH # # This file is part of GPGME. # @@ -17,6 +17,25 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +#------------------------------------------------------- +# Please remember to add new functions also to gpgme.def +#------------------------------------------------------- + +GPGME_1.1 { + global: + gpgme_set_engine_info; + + gpgme_ctx_get_engine_info; + gpgme_ctx_set_engine_info; + + gpgme_data_set_file_name; + gpgme_data_get_file_name; + + gpgme_sig_notation_clear; + gpgme_sig_notation_add; + gpgme_sig_notation_get; +}; + GPGME_1.0 { global: diff -urpNP gpgme-1.0.3/gpgme/op-support.c gpgme-1.1.0/gpgme/op-support.c --- gpgme-1.0.3/gpgme/op-support.c 2004-12-07 20:30:31.000000000 +0000 +++ gpgme-1.1.0/gpgme/op-support.c 2005-09-08 14:42:31.000000000 +0000 @@ -67,17 +67,26 @@ gpgme_error_t _gpgme_op_reset (gpgme_ctx_t ctx, int type) { gpgme_error_t err = 0; + gpgme_engine_info_t info; struct gpgme_io_cbs io_cbs; + info = ctx->engine_info; + while (info && info->protocol != ctx->protocol) + info = info->next; + + if (!info) + return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL); + _gpgme_release_result (ctx); - /* Create an engine object. */ - if (ctx->engine) + if (ctx->engine) { _gpgme_engine_release (ctx->engine); ctx->engine = NULL; } - err = _gpgme_engine_new (ctx->protocol, &ctx->engine, + + /* Create an engine object. */ + err = _gpgme_engine_new (info, &ctx->engine, ctx->lc_ctype, ctx->lc_messages); if (err) return err; @@ -114,6 +123,8 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int ty } +/* Parse the INV_RECP status line in ARGS and return the result in + KEY. */ gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key) { @@ -200,3 +211,47 @@ _gpgme_parse_inv_recp (char *args, gpgme *key = inv_key; return 0; } + + +/* Parse the PLAINTEXT status line in ARGS and return the result in + FILENAMEP. */ +gpgme_error_t +_gpgme_parse_plaintext (char *args, char **filenamep) +{ + char *tail; + + while (*args == ' ') + args++; + if (*args == '\0') + return 0; + + /* First argument is file type. */ + while (*args != ' ' && *args != '\0') + args++; + while (*args == ' ') + args++; + if (*args == '\0') + return 0; + + /* Second argument is the timestamp. */ + while (*args != ' ' && *args != '\0') + args++; + while (*args == ' ') + args++; + if (*args == '\0') + return 0; + + tail = args; + while (*tail != ' ' && *tail != '\0') + tail++; + *tail = '\0'; + if (filenamep && *args != '\0') + { + char *filename = strdup (args); + if (!filename) + return gpg_error_from_errno (errno); + + *filenamep = filename; + } + return 0; +} diff -urpNP gpgme-1.0.3/gpgme/ops.h gpgme-1.1.0/gpgme/ops.h --- gpgme-1.0.3/gpgme/ops.h 2004-12-07 20:30:36.000000000 +0000 +++ gpgme-1.1.0/gpgme/ops.h 2005-10-01 02:06:07.000000000 +0000 @@ -1,6 +1,6 @@ /* ops.h - Internal operation support. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -54,6 +54,11 @@ gpgme_error_t _gpgme_op_reset (gpgme_ctx KEY. */ gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key); +/* Parse the PLAINTEXT status line in ARGS and return the result in + FILENAMEP. */ +gpgme_error_t _gpgme_parse_plaintext (char *args, char **filenamep); + + /* From verify.c. */ gpgme_error_t _gpgme_op_verify_init_result (gpgme_ctx_t ctx); @@ -99,9 +104,6 @@ gpgme_error_t _gpgme_passphrase_status_h char *args); gpgme_error_t _gpgme_passphrase_command_handler (void *opaque, gpgme_status_code_t code, - const char *key, int fd); -gpgme_error_t _gpgme_passphrase_command_handler_internal (void *opaque, - gpgme_status_code_t code, const char *key, int fd, int *processed); @@ -136,9 +138,26 @@ void _gpgme_op_trustlist_event_cb (void void *type_data); -/*-- version.c --*/ -const char *_gpgme_compare_versions (const char *my_version, - const char *req_version); +/* From version.c. */ + +/* Return true if MY_VERSION is at least REQ_VERSION, and false + otherwise. */ +int _gpgme_compare_versions (const char *my_version, + const char *req_version); char *_gpgme_get_program_version (const char *const path); + +/* From sig-notation.c. */ + +/* Create a new, empty signature notation data object. */ +gpgme_error_t _gpgme_sig_notation_create (gpgme_sig_notation_t *notationp, + const char *name, int name_len, + const char *value, int value_len, + gpgme_sig_notation_flags_t flags); + +/* Free the signature notation object and all associated resources. + The object must already be removed from any linked list as the next + pointer is ignored. */ +void _gpgme_sig_notation_free (gpgme_sig_notation_t notation); + #endif /* OPS_H */ diff -urpNP gpgme-1.0.3/gpgme/passphrase.c gpgme-1.1.0/gpgme/passphrase.c --- gpgme-1.0.3/gpgme/passphrase.c 2005-06-20 19:14:02.000000000 +0000 +++ gpgme-1.1.0/gpgme/passphrase.c 2005-09-08 14:42:31.000000000 +0000 @@ -116,10 +116,8 @@ _gpgme_passphrase_status_handler (void * gpgme_error_t -_gpgme_passphrase_command_handler_internal (void *priv, - gpgme_status_code_t code, - const char *key, int fd, - int *processed) +_gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code, + const char *key, int fd, int *processed) { gpgme_ctx_t ctx = (gpgme_ctx_t) priv; gpgme_error_t err; @@ -153,12 +151,3 @@ _gpgme_passphrase_command_handler_intern return 0; } - - -gpgme_error_t -_gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code, - const char *key, int fd) -{ - return _gpgme_passphrase_command_handler_internal (priv, code, key, fd, - NULL); -} diff -urpNP gpgme-1.0.3/gpgme/posix-io.c gpgme-1.1.0/gpgme/posix-io.c --- gpgme-1.0.3/gpgme/posix-io.c 2004-12-07 20:30:21.000000000 +0000 +++ gpgme-1.1.0/gpgme/posix-io.c 2005-09-08 14:42:31.000000000 +0000 @@ -1,6 +1,6 @@ /* posix-io.c - Posix I/O functions Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2004 g10 Code GmbH + Copyright (C) 2001, 2002, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -35,7 +35,7 @@ #include #include "util.h" -#include "io.h" +#include "priv-io.h" #include "sema.h" #include "ath.h" #include "debug.h" diff -urpNP gpgme-1.0.3/gpgme/posix-sema.c gpgme-1.1.0/gpgme/posix-sema.c --- gpgme-1.0.3/gpgme/posix-sema.c 2004-12-07 20:30:13.000000000 +0000 +++ gpgme-1.1.0/gpgme/posix-sema.c 2005-09-12 18:49:10.000000000 +0000 @@ -40,8 +40,6 @@ void _gpgme_sema_subsystem_init () { - /* FIXME: we should check that there is only one thread running */ - _gpgme_ath_init (); } void diff -urpNP gpgme-1.0.3/gpgme/priv-io.h gpgme-1.1.0/gpgme/priv-io.h --- gpgme-1.0.3/gpgme/priv-io.h 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/gpgme/priv-io.h 2005-09-08 14:42:31.000000000 +0000 @@ -0,0 +1,67 @@ +/* priv-io.h - Interface to the private I/O functions. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef IO_H +#define IO_H + + +/* A single file descriptor passed to spawn. For child fds, dup_to + specifies the fd it should become in the child. */ +struct spawn_fd_item_s +{ + int fd; + int dup_to; +}; + +struct io_select_fd_s +{ + int fd; + int for_read; + int for_write; + int signaled; + int frozen; + void *opaque; +}; + +/* These function are either defined in posix-io.c or w32-io.c. */ +void _gpgme_io_subsystem_init (void); +int _gpgme_io_read (int fd, void *buffer, size_t count); +int _gpgme_io_write (int fd, const void *buffer, size_t count); +int _gpgme_io_pipe (int filedes[2], int inherit_idx); +int _gpgme_io_close (int fd); +int _gpgme_io_set_close_notify (int fd, void (*handler) (int, void *), + void *value); +int _gpgme_io_set_nonblocking (int fd); + +/* Spawn the executable PATH with ARGV as arguments, after forking + close all fds in FD_PARENT_LIST in the parent and close or dup all + fds in FD_CHILD_LIST in the child. */ +int _gpgme_io_spawn (const char *path, char **argv, + struct spawn_fd_item_s *fd_child_list, + struct spawn_fd_item_s *fd_parent_list); +int _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal); +int _gpgme_io_kill (int pid, int hard); +int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock); + +#endif /* IO_H */ + + + diff -urpNP gpgme-1.0.3/gpgme/rungpg.c gpgme-1.1.0/gpgme/rungpg.c --- gpgme-1.0.3/gpgme/rungpg.c 2004-12-07 20:27:26.000000000 +0000 +++ gpgme-1.1.0/gpgme/rungpg.c 2005-10-01 02:06:07.000000000 +0000 @@ -1,6 +1,6 @@ /* rungpg.c - Gpg Engine. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -33,7 +33,7 @@ #include "ops.h" #include "wait.h" #include "context.h" /*temp hack until we have GpmeData methods to do I/O */ -#include "io.h" +#include "priv-io.h" #include "sema.h" #include "debug.h" @@ -67,6 +67,8 @@ struct fd_data_map_s struct engine_gpg { + char *file_name; + struct arg_and_data_s *arglist; struct arg_and_data_s **argtail; @@ -225,17 +227,11 @@ add_data (engine_gpg_t gpg, gpgme_data_t } -static const char * -gpg_get_version (void) +static char * +gpg_get_version (const char *file_name) { - static const char *gpg_version; - DEFINE_STATIC_LOCK (gpg_version_lock); - - LOCK (gpg_version_lock); - if (!gpg_version) - gpg_version = _gpgme_get_program_version (_gpgme_get_gpg_path ()); - UNLOCK (gpg_version_lock); - return gpg_version; + return _gpgme_get_program_version (file_name ? file_name + : _gpgme_get_gpg_path ()); } @@ -314,6 +310,9 @@ gpg_release (void *engine) gpg_cancel (engine); + if (gpg->file_name) + free (gpg->file_name); + while (gpg->arglist) { struct arg_and_data_s *next = gpg->arglist->next; @@ -337,7 +336,8 @@ gpg_release (void *engine) static gpgme_error_t -gpg_new (void **engine, const char *lc_ctype, const char *lc_messages) +gpg_new (void **engine, const char *file_name, const char *home_dir, + const char *lc_ctype, const char *lc_messages) { engine_gpg_t gpg; gpgme_error_t rc = 0; @@ -346,6 +346,16 @@ gpg_new (void **engine, const char *lc_c if (!gpg) return gpg_error_from_errno (errno); + if (file_name) + { + gpg->file_name = strdup (file_name); + if (!gpg->file_name) + { + rc = gpg_error_from_errno (errno); + goto leave; + } + } + gpg->argtail = &gpg->arglist; gpg->status.fd[0] = -1; gpg->status.fd[1] = -1; @@ -381,6 +391,16 @@ gpg_new (void **engine, const char *lc_c goto leave; } gpg->status.eof = 0; + + if (home_dir) + { + rc = add_arg (gpg, "--homedir"); + if (!rc) + rc = add_arg (gpg, home_dir); + if (rc) + goto leave; + } + rc = add_arg (gpg, "--status-fd"); if (rc) goto leave; @@ -458,15 +478,21 @@ command_handler (void *opaque, int fd) { gpgme_error_t err; engine_gpg_t gpg = (engine_gpg_t) opaque; + int processed = 0; assert (gpg->cmd.used); assert (gpg->cmd.code); assert (gpg->cmd.fnc); - err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd); + err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd, + &processed); if (err) return err; + /* We always need to send at least a newline character. */ + if (!processed) + _gpgme_io_write (fd, "\n", 1); + gpg->cmd.code = 0; /* And sleep again until read_status will wake us up again. */ /* XXX We must check if there are any more fds active after removing @@ -1044,7 +1070,7 @@ start (engine_gpg_t gpg) if (!gpg) return gpg_error (GPG_ERR_INV_VALUE); - if (! _gpgme_get_gpg_path ()) + if (!gpg->file_name && !_gpgme_get_gpg_path ()) return gpg_error (GPG_ERR_INV_ENGINE); rc = build_argv (gpg); @@ -1102,7 +1128,8 @@ start (engine_gpg_t gpg) fd_parent_list[n].fd = -1; fd_parent_list[n].dup_to = -1; - status = _gpgme_io_spawn (_gpgme_get_gpg_path (), + status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name : + _gpgme_get_gpg_path (), gpg->argv, fd_child_list, fd_parent_list); saved_errno = errno; free (fd_child_list); @@ -1229,6 +1256,91 @@ append_args_from_signers (engine_gpg_t g static gpgme_error_t +append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */) +{ + gpgme_error_t err = 0; + gpgme_sig_notation_t notation; + + notation = gpgme_sig_notation_get (ctx); + + while (!err && notation) + { + if (notation->name + && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE)) + err = gpg_error (GPG_ERR_INV_VALUE); + else if (notation->name) + { + char *arg; + + /* Maximum space needed is one byte for the "critical" flag, + the name, one byte for '=', the value, and a terminating + '\0'. */ + + arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1); + if (!arg) + err = gpg_error_from_errno (errno); + + if (!err) + { + char *argp = arg; + + if (notation->critical) + *(argp++) = '!'; + + memcpy (argp, notation->name, notation->name_len); + argp += notation->name_len; + + *(argp++) = '='; + + /* We know that notation->name is '\0' terminated. */ + strcpy (argp, notation->value); + } + + if (!err) + err = add_arg (gpg, "--sig-notation"); + if (!err) + err = add_arg (gpg, arg); + + if (arg) + free (arg); + } + else + { + /* This is a policy URL. */ + + char *value; + + if (notation->critical) + { + value = malloc (1 + notation->value_len + 1); + if (!value) + err = gpg_error_from_errno (errno); + else + { + value[0] = '!'; + /* We know that notation->value is '\0' terminated. */ + strcpy (&value[1], notation->value); + } + } + else + value = notation->value; + + if (!err) + err = add_arg (gpg, "--sig-policy-url"); + if (!err) + err = add_arg (gpg, value); + + if (value != notation->value) + free (value); + } + + notation = notation->next; + } + return err; +} + + +static gpgme_error_t gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */) { @@ -1312,6 +1424,13 @@ gpg_encrypt (void *engine, gpgme_key_t r err = add_arg (gpg, "-"); if (!err) err = add_data (gpg, ciph, 1, 1); + if (gpgme_data_get_file_name (plain)) + { + if (!err) + err = add_arg (gpg, "--set-filename"); + if (!err) + err = add_arg (gpg, gpgme_data_get_file_name (plain)); + } if (!err) err = add_arg (gpg, "--"); if (!err) @@ -1349,6 +1468,8 @@ gpg_encrypt_sign (void *engine, gpgme_ke if (!err) err = append_args_from_signers (gpg, ctx); + if (!err) + err = append_args_from_sig_notations (gpg, ctx); /* Tell the gpg object about the data. */ if (!err) @@ -1357,6 +1478,13 @@ gpg_encrypt_sign (void *engine, gpgme_ke err = add_arg (gpg, "-"); if (!err) err = add_data (gpg, ciph, 1, 1); + if (gpgme_data_get_file_name (plain)) + { + if (!err) + err = add_arg (gpg, "--set-filename"); + if (!err) + err = add_arg (gpg, gpgme_data_get_file_name (plain)); + } if (!err) err = add_arg (gpg, "--"); if (!err) @@ -1567,6 +1695,16 @@ gpg_sign (void *engine, gpgme_data_t in, if (!err) err = append_args_from_signers (gpg, ctx); + if (!err) + err = append_args_from_sig_notations (gpg, ctx); + + if (gpgme_data_get_file_name (in)) + { + if (!err) + err = add_arg (gpg, "--set-filename"); + if (!err) + err = add_arg (gpg, gpgme_data_get_file_name (in)); + } /* Tell the gpg object about the data. */ if (!err) diff -urpNP gpgme-1.0.3/gpgme/sig-notation.c gpgme-1.1.0/gpgme/sig-notation.c --- gpgme-1.0.3/gpgme/sig-notation.c 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/gpgme/sig-notation.c 2005-10-01 02:06:07.000000000 +0000 @@ -0,0 +1,123 @@ +/* sig-notation.c - Signature notation data support. + Copyright (C) 2005 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#if HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include + +#include "gpgme.h" +#include "util.h" +#include "context.h" +#include "ops.h" + + +/* Free the signature notation object and all associated resources. + The object must already be removed from any linked list as the next + pointer is ignored. */ +void +_gpgme_sig_notation_free (gpgme_sig_notation_t notation) +{ + if (notation->name) + free (notation->name); + + if (notation->value) + free (notation->value); + + free (notation); +} + + +/* Set the flags of NOTATION to FLAGS. */ +static void +sig_notation_set_flags (gpgme_sig_notation_t notation, + gpgme_sig_notation_flags_t flags) +{ + /* We copy the flags into individual bits to make them easier + accessible individually for the user. */ + notation->human_readable = flags & GPGME_SIG_NOTATION_HUMAN_READABLE ? 1 : 0; + notation->critical = flags & GPGME_SIG_NOTATION_CRITICAL ? 1 : 0; + + notation->flags = flags; +} + + +/* Create a new, empty signature notation data object. */ +gpgme_error_t +_gpgme_sig_notation_create (gpgme_sig_notation_t *notationp, + const char *name, int name_len, + const char *value, int value_len, + gpgme_sig_notation_flags_t flags) +{ + gpgme_error_t err = 0; + gpgme_sig_notation_t notation; + + /* Currently, we require all notations to be human-readable. */ + if (name && !(flags & GPGME_SIG_NOTATION_HUMAN_READABLE)) + return gpg_error (GPG_ERR_INV_VALUE); + + notation = calloc (1, sizeof (*notation)); + if (!notation) + return gpg_error_from_errno (errno); + + if (name_len) + { + /* We add a trailing '\0' for stringification in the good + case. */ + notation->name = malloc (name_len + 1); + if (!notation->name) + { + err = gpg_error_from_errno (errno); + goto err; + } + + memcpy (notation->name, name, name_len); + notation->name[name_len] = '\0'; + notation->name_len = name_len; + } + + if (value_len) + { + /* We add a trailing '\0' for stringification in the good + case. */ + notation->value = malloc (value_len + 1); + if (!notation->value) + { + err = gpg_error_from_errno (errno); + goto err; + } + + memcpy (notation->value, value, value_len); + notation->value[value_len] = '\0'; + notation->value_len = value_len; + } + + sig_notation_set_flags (notation, flags); + + *notationp = notation; + return 0; + + err: + _gpgme_sig_notation_free (notation); + return err; +} diff -urpNP gpgme-1.0.3/gpgme/status-table.h gpgme-1.1.0/gpgme/status-table.h --- gpgme-1.0.3/gpgme/status-table.h 2005-06-20 19:35:40.000000000 +0000 +++ gpgme-1.1.0/gpgme/status-table.h 2005-10-01 21:15:17.000000000 +0000 @@ -10,6 +10,7 @@ static struct status_table_s status_tabl { { "ABORT", GPGME_STATUS_ABORT }, { "ALREADY_SIGNED", GPGME_STATUS_ALREADY_SIGNED }, + { "BACKUP_KEY_CREATED", GPGME_STATUS_BACKUP_KEY_CREATED }, { "BADARMOR", GPGME_STATUS_BADARMOR }, { "BADMDC", GPGME_STATUS_BADMDC }, { "BADSIG", GPGME_STATUS_BADSIG }, @@ -17,6 +18,7 @@ static struct status_table_s status_tabl { "BEGIN_DECRYPTION", GPGME_STATUS_BEGIN_DECRYPTION }, { "BEGIN_ENCRYPTION", GPGME_STATUS_BEGIN_ENCRYPTION }, { "BEGIN_STREAM", GPGME_STATUS_BEGIN_STREAM }, + { "CARDCTRL", GPGME_STATUS_CARDCTRL }, { "DECRYPTION_FAILED", GPGME_STATUS_DECRYPTION_FAILED }, { "DECRYPTION_OKAY", GPGME_STATUS_DECRYPTION_OKAY }, { "DELETE_PROBLEM", GPGME_STATUS_DELETE_PROBLEM }, @@ -60,10 +62,13 @@ static struct status_table_s status_tabl { "NO_PUBKEY", GPGME_STATUS_NO_PUBKEY }, { "NO_RECP", GPGME_STATUS_NO_RECP }, { "NO_SECKEY", GPGME_STATUS_NO_SECKEY }, + { "PLAINTEXT", GPGME_STATUS_PLAINTEXT }, { "POLICY_URL", GPGME_STATUS_POLICY_URL }, { "PROGRESS", GPGME_STATUS_PROGRESS }, { "REVKEYSIG", GPGME_STATUS_REVKEYSIG }, { "RSA_OR_IDEA", GPGME_STATUS_RSA_OR_IDEA }, + { "SC_OP_FAILURE", GPGME_STATUS_SC_OP_FAILURE }, + { "SC_OP_SUCCESS", GPGME_STATUS_SC_OP_SUCCESS }, { "SESSION_KEY", GPGME_STATUS_SESSION_KEY }, { "SHM_GET", GPGME_STATUS_SHM_GET }, { "SHM_GET_BOOL", GPGME_STATUS_SHM_GET_BOOL }, @@ -72,6 +77,7 @@ static struct status_table_s status_tabl { "SIGEXPIRED", GPGME_STATUS_SIGEXPIRED }, { "SIG_CREATED", GPGME_STATUS_SIG_CREATED }, { "SIG_ID", GPGME_STATUS_SIG_ID }, + { "SIG_SUBPACKET", GPGME_STATUS_SIG_SUBPACKET }, { "TRUNCATED", GPGME_STATUS_TRUNCATED }, { "TRUST_FULLY", GPGME_STATUS_TRUST_FULLY }, { "TRUST_MARGINAL", GPGME_STATUS_TRUST_MARGINAL }, diff -urpNP gpgme-1.0.3/gpgme/stpcpy.c gpgme-1.1.0/gpgme/stpcpy.c --- gpgme-1.0.3/gpgme/stpcpy.c 2004-12-07 20:26:44.000000000 +0000 +++ gpgme-1.1.0/gpgme/stpcpy.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* Copyright (C) 1992, 1995, 1997, 2002, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#undef __stpcpy -#undef stpcpy - -#ifndef weak_alias -# define __stpcpy stpcpy -#endif - -/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ -char * -__stpcpy (dest, src) - char *dest; - const char *src; -{ - register char *d = dest; - register const char *s = src; - - do - *d++ = *s; - while (*s++ != '\0'); - - return d - 1; -} -#ifdef libc_hidden_def -libc_hidden_def (__stpcpy) -#endif -#ifdef weak_alias -weak_alias (__stpcpy, stpcpy) -#endif -#ifdef libc_hidden_builtin_def -libc_hidden_builtin_def (stpcpy) -#endif diff -urpNP gpgme-1.0.3/gpgme/ttyname_r.c gpgme-1.1.0/gpgme/ttyname_r.c --- gpgme-1.0.3/gpgme/ttyname_r.c 2004-12-11 15:48:43.000000000 +0000 +++ gpgme-1.1.0/gpgme/ttyname_r.c 2005-09-08 14:42:31.000000000 +0000 @@ -32,6 +32,9 @@ int ttyname_r (int fd, char *buf, size_t buflen) { +#if HAVE_W32_SYSTEM + errno = ENOTTY; /* The best error code I have under mingw. */ +#else char *tty; tty = ttyname (fd); @@ -41,4 +44,5 @@ ttyname_r (int fd, char *buf, size_t buf strncpy (buf, tty, buflen); buf[buflen - 1] = '\0'; return (strlen (tty) >= buflen) ? ERANGE : 0; +#endif } diff -urpNP gpgme-1.0.3/gpgme/util.h gpgme-1.1.0/gpgme/util.h --- gpgme-1.0.3/gpgme/util.h 2005-06-20 19:15:13.000000000 +0000 +++ gpgme-1.1.0/gpgme/util.h 2005-09-08 14:42:31.000000000 +0000 @@ -1,6 +1,6 @@ /* util.h Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -35,9 +35,18 @@ const char *_gpgme_get_gpgsm_path (void) /*-- replacement functions in .c --*/ #ifdef HAVE_CONFIG_H + #ifndef HAVE_STPCPY -char *stpcpy (char *a, const char *b); -#endif +static _GPGME_INLINE char * +_gpgme_stpcpy (char *a, const char *b) +{ + while (*b) + *a++ = *b++; + *a = 0; + return a; +} +#define stpcpy(a,b) _gpgme_stpcpy ((a), (b)) +#endif /*!HAVE_STPCPY*/ #if !HAVE_VASPRINTF #include diff -urpNP gpgme-1.0.3/gpgme/verify.c gpgme-1.1.0/gpgme/verify.c --- gpgme-1.0.3/gpgme/verify.c 2005-06-20 19:14:49.000000000 +0000 +++ gpgme-1.1.0/gpgme/verify.c 2005-10-01 02:06:07.000000000 +0000 @@ -58,10 +58,7 @@ release_op_data (void *hook) { gpgme_sig_notation_t next_nota = notation->next; - if (notation->name) - free (notation->name); - if (notation->value) - free (notation->value); + _gpgme_sig_notation_free (notation); notation = next_nota; } @@ -70,6 +67,9 @@ release_op_data (void *hook) free (sig); sig = next; } + + if (opd->result.file_name) + free (opd->result.file_name); } @@ -203,6 +203,7 @@ parse_new_sig (op_data_t opd, gpgme_stat { gpgme_signature_t sig; char *end = strchr (args, ' '); + char *tail; if (end) { @@ -248,39 +249,70 @@ parse_new_sig (op_data_t opd, gpgme_stat break; case GPGME_STATUS_ERRSIG: - if (end) + /* Parse the pubkey algo. */ + if (!end) + goto parse_err_sig_fail; + errno = 0; + sig->pubkey_algo = strtol (end, &tail, 0); + if (errno || end == tail || *tail != ' ') + goto parse_err_sig_fail; + end = tail; + while (*end == ' ') + end++; + + /* Parse the hash algo. */ + if (!*end) + goto parse_err_sig_fail; + errno = 0; + sig->hash_algo = strtol (end, &tail, 0); + if (errno || end == tail || *tail != ' ') + goto parse_err_sig_fail; + end = tail; + while (*end == ' ') + end++; + + /* Skip the sig class. */ + end = strchr (end, ' '); + if (!end) + goto parse_err_sig_fail; + while (*end == ' ') + end++; + + /* Parse the timestamp. */ + sig->timestamp = _gpgme_parse_timestamp (end, &tail); + if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' ')) + return gpg_error (GPG_ERR_INV_ENGINE); + end = tail; + while (*end == ' ') + end++; + + /* Parse the return code. */ + if (end[0] && (!end[1] || end[1] == ' ')) { - int i = 0; - /* The return code is the 6th argument, if it is 9, the - problem is a missing key. */ - while (end && i < 4) + switch (end[0]) { - end = strchr (end, ' '); - if (end) - end++; - i++; - } - if (end && end[0] && (!end[1] || end[1] == ' ')) - { - switch (end[0]) - { - case '4': - sig->status = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - break; - - case '9': - sig->status = gpg_error (GPG_ERR_NO_PUBKEY); - break; - - default: - sig->status = gpg_error (GPG_ERR_GENERAL); - } + case '4': + sig->status = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + break; + + case '9': + sig->status = gpg_error (GPG_ERR_NO_PUBKEY); + break; + + default: + sig->status = gpg_error (GPG_ERR_GENERAL); } } else - sig->status = gpg_error (GPG_ERR_GENERAL); - break; + goto parse_err_sig_fail; + goto parse_err_sig_ok; + + parse_err_sig_fail: + sig->status = gpg_error (GPG_ERR_GENERAL); + parse_err_sig_ok: + break; + default: return gpg_error (GPG_ERR_GENERAL); } @@ -299,7 +331,6 @@ static gpgme_error_t parse_valid_sig (gpgme_signature_t sig, char *args) { char *end = strchr (args, ' '); - if (end) { *end = '\0'; @@ -316,6 +347,7 @@ parse_valid_sig (gpgme_signature_t sig, if (!sig->fpr) return gpg_error_from_errno (errno); + /* Skip the creation date. */ end = strchr (end, ' '); if (end) { @@ -329,6 +361,43 @@ parse_valid_sig (gpgme_signature_t sig, sig->exp_timestamp = _gpgme_parse_timestamp (end, &tail); if (sig->exp_timestamp == -1 || end == tail || (*tail && *tail != ' ')) return gpg_error (GPG_ERR_INV_ENGINE); + end = tail; + + while (*end == ' ') + end++; + /* Skip the signature version. */ + end = strchr (end, ' '); + if (end) + { + while (*end == ' ') + end++; + + /* Skip the reserved field. */ + end = strchr (end, ' '); + if (end) + { + /* Parse the pubkey algo. */ + errno = 0; + sig->pubkey_algo = strtol (end, &tail, 0); + if (errno || end == tail || *tail != ' ') + return gpg_error (GPG_ERR_INV_ENGINE); + end = tail; + + while (*end == ' ') + end++; + + if (*end) + { + /* Parse the hash algo. */ + + errno = 0; + sig->hash_algo = strtol (end, &tail, 0); + if (errno || end == tail || *tail != ' ') + return gpg_error (GPG_ERR_INV_ENGINE); + end = tail; + } + } + } } return 0; } @@ -359,51 +428,39 @@ parse_notation (gpgme_signature_t sig, g previous one. The crypto backend misbehaves. */ return gpg_error (GPG_ERR_INV_ENGINE); - notation = malloc (sizeof (*sig)); - if (!notation) - return gpg_error_from_errno (errno); - notation->next = NULL; + err = _gpgme_sig_notation_create (¬ation, NULL, 0, NULL, 0, 0); + if (err) + return err; if (code == GPGME_STATUS_NOTATION_NAME) { - int len = strlen (args) + 1; - - notation->name = malloc (len); - if (!notation->name) - { - int saved_errno = errno; - free (notation); - return gpg_error_from_errno (saved_errno); - } - err = _gpgme_decode_percent_string (args, ¬ation->name, len); + err = _gpgme_decode_percent_string (args, ¬ation->name, 0); if (err) { - free (notation->name); - free (notation); + _gpgme_sig_notation_free (notation); return err; } - notation->value = NULL; + notation->name_len = strlen (notation->name); + + /* FIXME: For now we fake the human-readable flag. The + critical flag can not be reported as it is not + provided. */ + notation->flags = GPGME_SIG_NOTATION_HUMAN_READABLE; + notation->human_readable = 1; } else { - int len = strlen (args) + 1; + /* This is a policy URL. */ - notation->name = NULL; - notation->value = malloc (len); - if (!notation->value) - { - int saved_errno = errno; - free (notation); - return gpg_error_from_errno (saved_errno); - } - err = _gpgme_decode_percent_string (args, ¬ation->value, len); + err = _gpgme_decode_percent_string (args, ¬ation->value, 0); if (err) { - free (notation->value); - free (notation); + _gpgme_sig_notation_free (notation); return err; } + + notation->value_len = strlen (notation->value); } *lastp = notation; } @@ -443,6 +500,8 @@ parse_notation (gpgme_signature_t sig, g err = _gpgme_decode_percent_string (args, &dest, len); if (err) return err; + + notation->value_len += strlen (dest); } else return gpg_error (GPG_ERR_INV_ENGINE); @@ -626,6 +685,11 @@ _gpgme_verify_status_handler (void *priv opd->only_newsig_seen = 0; break; + case GPGME_STATUS_PLAINTEXT: + err = _gpgme_parse_plaintext (args, &opd->result.file_name); + if (err) + return err; + default: break; } diff -urpNP gpgme-1.0.3/gpgme/version.c gpgme-1.1.0/gpgme/version.c --- gpgme-1.0.3/gpgme/version.c 2004-12-07 20:19:39.000000000 +0000 +++ gpgme-1.1.0/gpgme/version.c 2005-09-08 14:42:31.000000000 +0000 @@ -1,6 +1,6 @@ /* version.c - Version check routines. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH This file is part of GPGME. @@ -27,7 +27,7 @@ #include #include "gpgme.h" -#include "io.h" +#include "priv-io.h" /* For _gpgme_sema_subsystem_init (). */ #include "sema.h" @@ -104,7 +104,9 @@ parse_version_string (const char *str, i } -const char * +/* Return true if MY_VERSION is at least REQ_VERSION, and false + otherwise. */ +int _gpgme_compare_versions (const char *my_version, const char *rq_version) { @@ -113,17 +115,17 @@ _gpgme_compare_versions (const char *my_ const char *my_plvl, *rq_plvl; if (!rq_version) - return my_version; + return 1; if (!my_version) - return NULL; + return 0; my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro); if (!my_plvl) - return NULL; + return 0; rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro); if (!rq_plvl) - return NULL; + return 0; if (my_major > rq_major || (my_major == rq_major && my_minor > rq_minor) @@ -131,9 +133,9 @@ _gpgme_compare_versions (const char *my_ && my_micro > rq_micro) || (my_major == rq_major && my_minor == rq_minor && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0)) - return my_version; + return 1; - return NULL; + return 0; } @@ -150,7 +152,7 @@ const char * gpgme_check_version (const char *req_version) { do_subsystem_inits (); - return _gpgme_compare_versions (VERSION, req_version); + return _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL; } diff -urpNP gpgme-1.0.3/gpgme/versioninfo.rc.in gpgme-1.1.0/gpgme/versioninfo.rc.in --- gpgme-1.0.3/gpgme/versioninfo.rc.in 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/gpgme/versioninfo.rc.in 2005-09-08 14:42:31.000000000 +0000 @@ -0,0 +1,52 @@ +/* versioninfo.rc.in - for gpgme + * Copyright (C) 2005 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This 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. + */ + +/* This file is processed by configure to create versioninfo.rc */ + +#line __LINE__ "versioninfo.rc.in" + +#include + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @BUILD_FILEVERSION@ + PRODUCTVERSION @BUILD_FILEVERSION@ + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License.\0" + VALUE "CompanyName", "g10 Code GmbH\0" + VALUE "FileDescription", "GPGME - GnuPG Made Easy\0" + VALUE "FileVersion", "@VERSION@\0" + VALUE "InternalName", "gpgme\0" + VALUE "LegalCopyright", "Copyright © 2005 g10 Code GmbH\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "gpgme.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "GPGME\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0" + END + END +END + diff -urpNP gpgme-1.0.3/gpgme/w32-io.c gpgme-1.1.0/gpgme/w32-io.c --- gpgme-1.0.3/gpgme/w32-io.c 2005-06-20 19:14:27.000000000 +0000 +++ gpgme-1.1.0/gpgme/w32-io.c 2005-09-25 19:26:35.000000000 +0000 @@ -1,6 +1,6 @@ /* w32-io.c - W32 API I/O functions. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH This file is part of GPGME. @@ -36,8 +36,8 @@ #include "util.h" #include "sema.h" -#include "io.h" - +#include "priv-io.h" +#include "debug.h" /* We assume that a HANDLE can be represented by an int which should be true for all i386 systems (HANDLE is defined as void *) and @@ -51,6 +51,7 @@ #define READBUF_SIZE 4096 #define WRITEBUF_SIZE 4096 +#define PIPEBUF_SIZE 4096 #define MAX_READERS 20 #define MAX_WRITERS 20 @@ -261,6 +262,12 @@ create_reader (HANDLE fd) free (c); return NULL; } + else { + /* We set the priority of the thread higher because we know that + it only runs for a short time. This greatly helps to increase + the performance of the I/O. */ + SetThreadPriority (c->thread_hd, THREAD_PRIORITY_HIGHEST); + } return c; } @@ -395,12 +402,11 @@ _gpgme_io_read ( int fd, void *buffer, s UNLOCK (c->mutex); DEBUG2 ("fd %d: got %d bytes\n", fd, nread ); + if (nread > 0) + _gpgme_debug (2, "fd %d: got `%.*s'\n", fd, nread, buffer); return nread; } - - - /* * The writer does use a simple buffering strategy so that we are * informed about write errors as soon as possible (i.e. with the the @@ -514,6 +520,12 @@ create_writer (HANDLE fd) free (c); return NULL; } + else { + /* We set the priority of the thread higher because we know that + it only runs for a short time. This greatly helps to increase + the performance of the I/O. */ + SetThreadPriority (c->thread_hd, THREAD_PRIORITY_HIGHEST); + } return c; } @@ -600,6 +612,7 @@ _gpgme_io_write ( int fd, const void *bu struct writer_context_s *c = find_writer (fd,1); DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int)count ); + _gpgme_debug (2, "fd %d: write `%.*s'\n", fd, (int) count, buffer); if ( !c ) { DEBUG0 ( "no writer thread\n"); return -1; @@ -646,9 +659,9 @@ _gpgme_io_pipe ( int filedes[2], int inh sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; - if (!CreatePipe ( &r, &w, &sec_attr, 0)) + if (!CreatePipe ( &r, &w, &sec_attr, PIPEBUF_SIZE)) return -1; - /* make one end inheritable */ + /* Make one end inheritable. */ if ( inherit_idx == 0 ) { HANDLE h; if (!DuplicateHandle( GetCurrentProcess(), r, @@ -762,27 +775,36 @@ _gpgme_io_set_nonblocking ( int fd ) static char * build_commandline ( char **argv ) { - int i, n = 0; - char *buf, *p; - - /* FIXME: we have to quote some things because under Windows the - * program parses the commandline and does some unquoting */ - for (i=0; argv[i]; i++) - n += strlen (argv[i]) + 2 + 1; /* 2 extra bytes for possible quoting */ - buf = p = malloc (n); - if ( !buf ) - return NULL; - *buf = 0; - if ( argv[0] ) + int i, n = 0; + char *buf, *p; + + /* FIXME: we have to quote some things because under Windows the + * program parses the commandline and does some unquoting. For now + * we only do very basic quoting to the first argument because this + * one often contains a space (e.g. C:\\Program Files\GNU\GnuPG\gpg.exe) + * and we would produce an invalid line in that case. */ + for (i=0; argv[i]; i++) + n += strlen (argv[i]) + 2 + 1; /* 2 extra bytes for possible quoting */ + buf = p = malloc (n); + if ( !buf ) + return NULL; + *buf = 0; + if ( argv[0] ) + { + if (strpbrk (argv[0], " \t")) + p = stpcpy (stpcpy (stpcpy (p, "\""), argv[0]), "\""); + else p = stpcpy (p, argv[0]); - for (i = 1; argv[i]; i++) { - if (!*argv[i]) + for (i = 1; argv[i]; i++) + { + if (!*argv[i]) p = stpcpy (p, " \"\""); - else + else p = stpcpy (stpcpy (p, " "), argv[i]); + } } - - return buf; + + return buf; } @@ -891,13 +913,13 @@ _gpgme_io_spawn ( const char *path, char return -1; } - /* close the /dev/nul handle if used */ + /* Close the /dev/nul handle if used. */ if (hnul != INVALID_HANDLE_VALUE ) { if ( !CloseHandle ( hnul ) ) DEBUG1 ("CloseHandle(hnul) failed: ec=%d\n", (int)GetLastError()); } - /* Close the other ends of the pipes */ + /* Close the other ends of the pipes. */ for (i = 0; fd_parent_list[i].fd != -1; i++) _gpgme_io_close (fd_parent_list[i].fd); @@ -1064,7 +1086,7 @@ _gpgme_io_select ( struct io_select_fd_s */ any = 0; for (i=code - WAIT_OBJECT_0; i < nwait; i++ ) { - if (WaitForSingleObject ( waitbuf[i], NULL ) == WAIT_OBJECT_0) { + if (WaitForSingleObject (waitbuf[i], 0) == WAIT_OBJECT_0) { assert (waitidx[i] >=0 && waitidx[i] < nfds); fds[waitidx[i]].signaled = 1; any = 1; @@ -1116,3 +1138,11 @@ _gpgme_io_select ( struct io_select_fd_s return count; } + +void +_gpgme_io_subsystem_init (void) +{ + +} + + diff -urpNP gpgme-1.0.3/gpgme/w32-sema.c gpgme-1.1.0/gpgme/w32-sema.c --- gpgme-1.0.3/gpgme/w32-sema.c 2004-12-07 20:19:25.000000000 +0000 +++ gpgme-1.1.0/gpgme/w32-sema.c 2005-09-08 14:42:31.000000000 +0000 @@ -36,6 +36,7 @@ #include "util.h" #include "sema.h" +#include "debug.h" static void sema_fatal (const char *text) diff -urpNP gpgme-1.0.3/gpgme/w32-util.c gpgme-1.1.0/gpgme/w32-util.c --- gpgme-1.0.3/gpgme/w32-util.c 2004-12-07 20:19:15.000000000 +0000 +++ gpgme-1.1.0/gpgme/w32-util.c 2005-09-08 14:42:31.000000000 +0000 @@ -33,65 +33,196 @@ #include #include #include +#include #include #include "util.h" #include "sema.h" +#include "debug.h" DEFINE_STATIC_LOCK (get_path_lock); -/* Return a string from the Win32 Registry or NULL in case of error. - Caller must release the return value. A NULL for root is an alias - for HKEY_CURRENT_USER. */ + +#define RTLD_LAZY 0 + +static __inline__ void * +dlopen (const char * name, int flag) +{ + void * hd = LoadLibrary (name); + return hd; +} + +static __inline__ void * +dlsym (void * hd, const char * sym) +{ + if (hd && sym) + { + void * fnc = GetProcAddress (hd, sym); + if (!fnc) + return NULL; + return fnc; + } + return NULL; +} + +static __inline__ int +dlclose (void * hd) +{ + if (hd) + { + FreeLibrary (hd); + return 0; + } + return -1; +} + + +/* Return a string from the W32 Registry or NULL in case of error. + Caller must release the return value. A NULL for root is an alias + for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */ static char * read_w32_registry_string (const char *root, const char *dir, const char *name) { HKEY root_key, key_handle; - DWORD n1, nbytes; + DWORD n1, nbytes, type; char *result = NULL; - - if (!root) + + if ( !root ) root_key = HKEY_CURRENT_USER; - else if (!strcmp (root, "HKEY_CLASSES_ROOT")) + else if ( !strcmp( root, "HKEY_CLASSES_ROOT" ) ) root_key = HKEY_CLASSES_ROOT; - else if (!strcmp (root, "HKEY_CURRENT_USER")) + else if ( !strcmp( root, "HKEY_CURRENT_USER" ) ) root_key = HKEY_CURRENT_USER; - else if (!strcmp (root, "HKEY_LOCAL_MACHINE")) + else if ( !strcmp( root, "HKEY_LOCAL_MACHINE" ) ) root_key = HKEY_LOCAL_MACHINE; - else if (!strcmp (root, "HKEY_USERS")) + else if ( !strcmp( root, "HKEY_USERS" ) ) root_key = HKEY_USERS; - else if (!strcmp (root, "HKEY_PERFORMANCE_DATA")) + else if ( !strcmp( root, "HKEY_PERFORMANCE_DATA" ) ) root_key = HKEY_PERFORMANCE_DATA; - else if (!strcmp (root, "HKEY_CURRENT_CONFIG")) + else if ( !strcmp( root, "HKEY_CURRENT_CONFIG" ) ) root_key = HKEY_CURRENT_CONFIG; else return NULL; - - if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle)) - return NULL; /* No need for a RegClose, so return directly. */ + + if ( RegOpenKeyEx ( root_key, dir, 0, KEY_READ, &key_handle ) ) + { + if (root) + return NULL; /* no need for a RegClose, so return direct */ + /* It seems to be common practise to fall back to HKLM. */ + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) + return NULL; /* still no need for a RegClose, so return direct */ + } nbytes = 1; - if (RegQueryValueEx (key_handle, name, 0, NULL, NULL, &nbytes)) - goto leave; - n1 = nbytes + 1; - result = malloc (n1); - if (!result) + if ( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) + { + if (root) + goto leave; + /* Try to fallback to HKLM also vor a missing value. */ + RegCloseKey (key_handle); + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) + return NULL; /* Nope. */ + if (RegQueryValueEx ( key_handle, name, 0, NULL, NULL, &nbytes)) + goto leave; + } + result = malloc ( (n1=nbytes+1) ); + if ( !result ) goto leave; - if (RegQueryValueEx (key_handle, name, 0, NULL, result, &n1)) + if ( RegQueryValueEx ( key_handle, name, 0, &type, result, &n1 ) ) { - free (result); - result = NULL; + free(result); result = NULL; goto leave; } - result[nbytes] = 0; /* Make sure it is really a string. */ + result[nbytes] = 0; /* Make sure it is really a string. */ + if (type == REG_EXPAND_SZ && strchr (result, '%')) + { + char *tmp; + + n1 += 1000; + tmp = malloc (n1+1); + if (!tmp) + goto leave; + nbytes = ExpandEnvironmentStrings (result, tmp, n1); + if (nbytes && nbytes > n1) + { + free (tmp); + n1 = nbytes; + tmp = malloc (n1 + 1); + if (!tmp) + goto leave; + nbytes = ExpandEnvironmentStrings (result, tmp, n1); + if (nbytes && nbytes > n1) { + free (tmp); /* Oops - truncated, better don't expand at all. */ + goto leave; + } + tmp[nbytes] = 0; + free (result); + result = tmp; + } + else if (nbytes) /* Okay, reduce the length. */ + { + tmp[nbytes] = 0; + free (result); + result = malloc (strlen (tmp)+1); + if (!result) + result = tmp; + else + { + strcpy (result, tmp); + free (tmp); + } + } + else /* Error - don't expand. */ + { + free (tmp); + } + } leave: - RegCloseKey (key_handle); + RegCloseKey( key_handle ); return result; } -static const char * +/* This is a helper function to load and run a Windows function from + either of one DLLs. */ +static HRESULT +w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e) +{ + static int initialized; + static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR); + + if (!initialized) + { + static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL }; + void *handle; + int i; + + initialized = 1; + + for (i=0, handle = NULL; !handle && dllnames[i]; i++) + { + handle = dlopen (dllnames[i], RTLD_LAZY); + if (handle) + { + func = dlsym (handle, "SHGetFolderPathA"); + if (!func) + { + dlclose (handle); + handle = NULL; + } + } + } + } + + if (func) + return func (a,b,c,d,e); + else + return -1; +} + + +static char * find_program_in_registry (const char *name) { char *program = NULL; @@ -112,6 +243,29 @@ find_program_in_registry (const char *na } +static char * +find_program_at_standard_place (const char *name) +{ + char path[MAX_PATH]; + char *result = NULL; + + if (w32_shgetfolderpath (NULL, CSIDL_PROGRAM_FILES, NULL, 0, path) >= 0) + { + result = malloc (strlen (path) + 1 + strlen (name) + 1); + if (result) + { + strcpy (stpcpy (stpcpy (result, path), "\\"), name); + if (access (result, F_OK)) + { + free (result); + result = NULL; + } + } + } + return result; +} + + const char * _gpgme_get_gpg_path (void) { @@ -120,6 +274,8 @@ _gpgme_get_gpg_path (void) LOCK (get_path_lock); if (!gpg_program) gpg_program = find_program_in_registry ("gpgProgram"); + if (!gpg_program) + gpg_program = find_program_at_standard_place ("GNU\\GnuPG\\gpg.exe"); #ifdef GPG_PATH if (!gpg_program) gpg_program = GPG_PATH; @@ -136,6 +292,8 @@ _gpgme_get_gpgsm_path (void) LOCK (get_path_lock); if (!gpgsm_program) gpgsm_program = find_program_in_registry ("gpgsmProgram"); + if (!gpgsm_program) + gpgsm_program = find_program_at_standard_place ("GNU\\GnuPG\\gpgsm.exe"); #ifdef GPGSM_PATH if (!gpgsm_program) gpgsm_program = GPGSM_PATH; diff -urpNP gpgme-1.0.3/gpgme/wait-global.c gpgme-1.1.0/gpgme/wait-global.c --- gpgme-1.0.3/gpgme/wait-global.c 2005-06-02 23:02:42.000000000 +0000 +++ gpgme-1.1.0/gpgme/wait-global.c 2005-09-08 14:42:31.000000000 +0000 @@ -32,7 +32,7 @@ #include "util.h" #include "context.h" #include "wait.h" -#include "io.h" +#include "priv-io.h" /* The global event loop is used for all asynchronous operations (except key listing) for which no user I/O callbacks are specified. diff -urpNP gpgme-1.0.3/gpgme/wait-private.c gpgme-1.1.0/gpgme/wait-private.c --- gpgme-1.0.3/gpgme/wait-private.c 2005-06-20 19:13:47.000000000 +0000 +++ gpgme-1.1.0/gpgme/wait-private.c 2005-09-08 14:42:31.000000000 +0000 @@ -29,7 +29,7 @@ #include "context.h" #include "wait.h" #include "ops.h" -#include "io.h" +#include "priv-io.h" #include "util.h" diff -urpNP gpgme-1.0.3/gpgme/wait-user.c gpgme-1.1.0/gpgme/wait-user.c --- gpgme-1.0.3/gpgme/wait-user.c 2005-06-20 19:13:41.000000000 +0000 +++ gpgme-1.1.0/gpgme/wait-user.c 2005-09-08 14:42:31.000000000 +0000 @@ -26,7 +26,7 @@ #include "gpgme.h" #include "context.h" -#include "io.h" +#include "priv-io.h" #include "wait.h" diff -urpNP gpgme-1.0.3/gpgme/wait.c gpgme-1.1.0/gpgme/wait.c --- gpgme-1.0.3/gpgme/wait.c 2005-06-20 19:13:32.000000000 +0000 +++ gpgme-1.1.0/gpgme/wait.c 2005-09-08 14:42:31.000000000 +0000 @@ -33,7 +33,7 @@ #include "ops.h" #include "wait.h" #include "sema.h" -#include "io.h" +#include "priv-io.h" #include "engine.h" #include "debug.h" diff -urpNP gpgme-1.0.3/gpgme/wait.h gpgme-1.1.0/gpgme/wait.h --- gpgme-1.0.3/gpgme/wait.h 2005-06-20 19:13:26.000000000 +0000 +++ gpgme-1.1.0/gpgme/wait.h 2005-09-08 14:42:31.000000000 +0000 @@ -1,6 +1,6 @@ /* wait.h - Definitions for the wait queue interface. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH This file is part of GPGME. diff -urpNP gpgme-1.0.3/gpgme.spec gpgme-1.1.0/gpgme.spec --- gpgme-1.0.3/gpgme.spec 2005-06-20 19:35:41.000000000 +0000 +++ gpgme-1.1.0/gpgme.spec 2005-10-01 21:15:18.000000000 +0000 @@ -1,7 +1,7 @@ # This is a template. The dist target uses it to create the real file. Summary: GPGME - GnuPG Made Easy Name: gpgme -Version: 1.0.3 +Version: 1.1.0 Release: 1 URL: http://www.gnupg.org/gpgme.html Source: ftp://ftp.gnupg.org/gcrypt/alpha/gpgme/%{name}-%{version}.tar.gz diff -urpNP gpgme-1.0.3/install-sh gpgme-1.1.0/install-sh --- gpgme-1.0.3/install-sh 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/install-sh 2005-09-08 14:42:33.000000000 +0000 @@ -1,8 +1,7 @@ #!/bin/sh +# # install - install a program, script, or datafile - -scriptversion=2004-10-22.00 - +# # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. @@ -42,11 +41,13 @@ scriptversion=2004-10-22.00 # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. + # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" + # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" @@ -58,266 +59,236 @@ stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" +transformbasename="" +transform_arg="" +instcmd="$mvprog" chmodcmd="$chmodprog 0755" -chowncmd= -chgrpcmd= -stripcmd= +chowncmd="" +chgrpcmd="" +stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" -src= -dst= -dir_arg= -dstarg= -no_target_directory= - -usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: --c (ignored) --d create directories instead of installing files. --g GROUP $chgrpprog installed files to GROUP. --m MODE $chmodprog installed files to MODE. --o USER $chownprog installed files to USER. --s $stripprog installed files. --t DIRECTORY install into DIRECTORY. --T report an error if DSTFILE is a directory. ---help display this help and exit. ---version display version info and exit. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG -" - -while test -n "$1"; do - case $1 in - -c) shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - --help) echo "$usage"; exit 0;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -s) stripcmd=$stripprog - shift - continue;; +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done - -t) dstarg=$2 - shift - shift - continue;; +if [ x"$src" = x ] +then + echo "$0: no input file specified" >&2 + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d "$dst" ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" ] || [ -d "$src" ] + then + : + else + echo "$0: $src does not exist" >&2 + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "$0: no destination specified" >&2 + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d "$dst" ] + then + dst=$dst/`basename "$src"` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-$defaultIFS}" + +oIFS=$IFS +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS=$oIFS - -T) no_target_directory=true +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp=$pathcomp$1 shift - continue;; - --version) echo "$0 $scriptversion"; exit 0;; + if [ ! -d "$pathcomp" ] ; + then + $mkdirprog "$pathcomp" + else + : + fi - *) # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - test -n "$dir_arg$dstarg" && break - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dstarg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dstarg" - shift # fnord - fi - shift # arg - dstarg=$arg - done - break;; - esac + pathcomp=$pathcomp/ done - -if test -z "$1"; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 fi -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src ;; - esac - - if test -n "$dir_arg"; then - dst=$src - src= - - if test -d "$dst"; then - mkdircmd=: - chmodcmd= - else - mkdircmd=$mkdirprog - fi - else - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dstarg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dstarg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst ;; - esac +if [ x"$dir_arg" != x ] +then + $doit $instcmd "$dst" && - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dstarg: Is a directory" >&2 - exit 1 - fi - dst=$dst/`basename "$src"` - fi - fi - - # This sed command emulates the dirname command. - dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` - - # Make sure that the destination directory exists. - - # Skip lots of stat calls in the usual case. - if test ! -d "$dstdir"; then - defaultIFS=' - ' - IFS="${IFS-$defaultIFS}" - - oIFS=$IFS - # Some sh's can't handle IFS=/ for some reason. - IFS='%' - set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` - shift - IFS=$oIFS - - pathcomp= - - while test $# -ne 0 ; do - pathcomp=$pathcomp$1 - shift - if test ! -d "$pathcomp"; then - $mkdirprog "$pathcomp" - # mkdir can fail with a `File exist' error in case several - # install-sh are creating the directory concurrently. This - # is OK. - test -d "$pathcomp" || exit - fi - pathcomp=$pathcomp/ - done - fi - - if test -n "$dir_arg"; then - $doit $mkdircmd "$dst" \ - && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ - && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ - && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } - - else - dstfile=`basename "$dst"` - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - trap '(exit $?); exit' 1 2 13 15 - - # Copy the file name to the temp name. - $doit $cpprog "$src" "$dsttmp" && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ - && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ - && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && - - # Now rename the file to the real destination. - { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ - || { - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - if test -f "$dstdir/$dstfile"; then - $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ - || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ - || { - echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 - (exit 1); exit - } - else - : - fi - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" - } - } - fi || { (exit 1); exit; } -done + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename "$dst"` + else + : + fi + +# Make a couple of temp file names in the proper directory. + + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + +# Trap to clean up temp files at exit. + + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + +# Move or copy the file name to the temp name + + $doit $instcmd "$src" "$dsttmp" && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && + +# Now remove or move aside any old file at destination location. We try this +# two ways since rm can't unlink itself on some systems and the destination +# file might be busy for other reasons. In this case, the final cleanup +# might fail but the new file should still install successfully. + +{ + if [ -f "$dstdir/$dstfile" ] + then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || + $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || + { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi +} && + +# Now rename the file to the real destination. + + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + +fi && # The final little trick to "correctly" pass the exit status to the exit trap. + { - (exit 0); exit + (exit 0); exit } - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff -urpNP gpgme-1.0.3/ltmain.sh gpgme-1.1.0/ltmain.sh --- gpgme-1.0.3/ltmain.sh 2004-04-06 14:41:28.000000000 +0000 +++ gpgme-1.1.0/ltmain.sh 2005-09-08 14:42:33.000000000 +0000 @@ -44,7 +44,7 @@ EXIT_FAILURE=1 PROGRAM=ltmain.sh PACKAGE=libtool VERSION=1.5.4 -TIMESTAMP=" (1.1220.2.90 2004/04/03 14:10:19) Debian$Rev: 203 $" +TIMESTAMP=" (1.1220.2.90 2004/04/03 14:10:19) Debian$Rev: 931 $" # Check that we have a working $echo. diff -urpNP gpgme-1.0.3/m4/libtool.m4 gpgme-1.1.0/m4/libtool.m4 --- gpgme-1.0.3/m4/libtool.m4 2004-04-06 14:21:43.000000000 +0000 +++ gpgme-1.1.0/m4/libtool.m4 2005-09-08 14:42:29.000000000 +0000 @@ -23,7 +23,7 @@ ## the same distribution terms that you use for the rest of that program. # serial 47 AC_PROG_LIBTOOL -# Debian $Rev: 203 $ +# Debian $Rev: 928 $ # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) diff -urpNP gpgme-1.0.3/missing gpgme-1.1.0/missing --- gpgme-1.0.3/missing 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/missing 2005-09-08 14:42:33.000000000 +0000 @@ -1,10 +1,6 @@ #! /bin/sh # Common stub for a few missing GNU programs while installing. - -scriptversion=2004-09-07.08 - -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -42,24 +38,18 @@ else configure_ac=configure.in fi -msg="missing on your system" - case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in -h|--h|--he|--hel|--help) echo "\ @@ -84,15 +74,11 @@ Supported PROGRAM values: lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] - -Send bug reports to ." - exit 0 + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit 0 + echo "missing 0.4 - GNU automake" ;; -*) @@ -101,44 +87,14 @@ Send bug reports to &2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) + aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 fi - ;; -esac -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case "$1" in - aclocal*) echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." @@ -146,8 +102,13 @@ WARNING: \`$1' is $msg. You should only ;; autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." @@ -155,8 +116,13 @@ WARNING: \`$1' is $msg. You should only ;; autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." @@ -174,8 +140,13 @@ WARNING: \`$1' is $msg. You should only ;; automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." @@ -185,11 +156,16 @@ WARNING: \`$1' is $msg. You should only ;; autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU + You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` @@ -209,7 +185,7 @@ WARNING: \`$1' is needed, but is $msg. bison|yacc) echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." @@ -239,7 +215,7 @@ WARNING: \`$1' $msg. You should only ne lex|flex) echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." @@ -261,8 +237,13 @@ WARNING: \`$1' is $msg. You should only ;; help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." @@ -281,8 +262,13 @@ WARNING: \`$1' is $msg. You should only ;; makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if +WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, @@ -298,6 +284,10 @@ WARNING: \`$1' is $msg. You should only tar) shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error @@ -333,10 +323,10 @@ WARNING: I can't seem to be able to run *) echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing + it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 @@ -344,10 +334,3 @@ WARNING: \`$1' is needed, and is $msg. esac exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff -urpNP gpgme-1.0.3/mkinstalldirs gpgme-1.1.0/mkinstalldirs --- gpgme-1.0.3/mkinstalldirs 2005-01-12 10:04:54.000000000 +0000 +++ gpgme-1.1.0/mkinstalldirs 2005-09-08 14:42:33.000000000 +0000 @@ -1,32 +1,20 @@ #! /bin/sh # mkinstalldirs --- make directory hierarchy - -scriptversion=2004-02-15.20 - -# Original author: Noah Friedman +# Author: Noah Friedman # Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to or send patches to -# . +# Public domain errstatus=0 dirmode="" usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to ." +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help - echo "$usage" + echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg @@ -35,10 +23,6 @@ while test $# -gt 0 ; do dirmode=$1 shift ;; - --version) - echo "$0 $scriptversion" - exit 0 - ;; --) # stop option processing shift break @@ -66,37 +50,17 @@ case $# in 0) exit 0 ;; esac -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version fi ;; *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done fi ;; esac @@ -120,17 +84,17 @@ do mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then - errstatus=$lasterr + errstatus=$lasterr else - if test ! -z "$dirmode"; then + if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" - lasterr="" - chmod "$dirmode" "$pathcomp" || lasterr=$? + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi fi fi @@ -143,8 +107,5 @@ exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" # End: +# mkinstalldirs ends here diff -urpNP gpgme-1.0.3/tests/ChangeLog gpgme-1.1.0/tests/ChangeLog --- gpgme-1.0.3/tests/ChangeLog 2005-06-02 23:02:42.000000000 +0000 +++ gpgme-1.1.0/tests/ChangeLog 2005-10-01 20:14:48.000000000 +0000 @@ -1,3 +1,31 @@ +2005-10-01 Marcus Brinkmann + + * gpg/Makefile.am (EXTRA_DIST): Remove gpg.conf. + (DISTCLEANFILES): Add gpg.conf. + (all-local): Add gpg.conf. + (./gpg.conf): New target. + * gpg/gpg.conf: Remove file. + + * gpg/Makefile.am (EXTRA_DIST): Add gpg.conf. + + * gpg/Makefile.am (TESTS): Add t-sig-notation. + * gpg/t-sig-notation.c (check_result): New file. + * gpg/t-verify.c (check_result): Also check the length of the + notation data. + * gpg/gpg.conf: New file. + +2005-09-30 Marcus Brinkmann + + * gpg/Makefile.am (TESTS): Add t-filename. + * gpg/t-filename.c: New file. + +2005-09-23 Werner Koch + + * gpg/t-support.h (init_gpgme) [W32]: Don't use LC_MESSAGES. + + * gpg/t-encrypt-large.c: New test. + * gpg/Makefile.am (TESTS): Add t-encrypt-large. + 2005-06-03 Marcus Brinkmann * gpg/Makefile.am (TESTS): Add t-wait. diff -urpNP gpgme-1.0.3/tests/Makefile.in gpgme-1.1.0/tests/Makefile.in --- gpgme-1.0.3/tests/Makefile.in 2005-06-20 19:35:24.000000000 +0000 +++ gpgme-1.1.0/tests/Makefile.in 2005-10-01 21:13:46.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -34,8 +34,6 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -SOURCES = t-data.c t-engine-info.c t-version.c - srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -122,6 +120,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -134,6 +134,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -162,6 +163,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -200,12 +203,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ diff -urpNP gpgme-1.0.3/tests/gpg/Makefile.am gpgme-1.1.0/tests/gpg/Makefile.am --- gpgme-1.0.3/tests/gpg/Makefile.am 2005-06-02 23:02:42.000000000 +0000 +++ gpgme-1.1.0/tests/gpg/Makefile.am 2005-10-01 20:14:48.000000000 +0000 @@ -26,12 +26,13 @@ TESTS_ENVIRONMENT = GNUPGHOME=. GPG_AGEN # The keylist tests must come after the import and the edit test. noinst_HEADERS = t-support.h TESTS = t-encrypt t-encrypt-sym t-encrypt-sign t-sign t-signers \ - t-decrypt t-verify t-decrypt-verify \ + t-decrypt t-verify t-decrypt-verify t-sig-notation \ t-export t-import t-trustlist t-eventloop t-edit \ - t-keylist t-keylist-sig t-thread1 t-wait + t-keylist t-keylist-sig t-thread1 t-wait t-encrypt-large \ + t-file-name CLEANFILES = secring.gpg pubring.gpg trustdb.gpg -DISTCLEANFILES = pubring.gpg~ random_seed +DISTCLEANFILES = pubring.gpg~ random_seed gpg.conf EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \ geheim.txt pubkey-1.asc seckey-1.asc @@ -48,11 +49,16 @@ noinst_PROGRAMS = $(TESTS) t-genkey clean-local: $(srcdir)/mkdemodirs --clean -all-local: ./pubring.gpg +all-local: ./pubring.gpg ./gpg.conf ./pubring.gpg: $(srcdir)/pubdemo.asc ./Alpha/Secret.gpg $(GPG) --homedir . --import $(srcdir)/pubdemo.asc - $(GPG) --homedir . --allow-secret-key-import --import Alpha/Secret.gpg Zulu/Secret.gpg + $(GPG) --homedir . --allow-secret-key-import \ + --import Alpha/Secret.gpg Zulu/Secret.gpg ./Alpha/Secret.gpg: secdemo.asc srcdir=$(srcdir) $(srcdir)/mkdemodirs + +./gpg.conf: +# This is required for t-sig-notations. + echo no-force-v3-sigs > ./gpg.conf diff -urpNP gpgme-1.0.3/tests/gpg/Makefile.in gpgme-1.1.0/tests/gpg/Makefile.in --- gpgme-1.0.3/tests/gpg/Makefile.in 2005-06-20 19:35:25.000000000 +0000 +++ gpgme-1.1.0/tests/gpg/Makefile.in 2005-10-01 21:13:46.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -34,8 +34,6 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -SOURCES = t-decrypt.c t-decrypt-verify.c t-edit.c t-encrypt.c t-encrypt-sign.c t-encrypt-sym.c t-eventloop.c t-export.c t-genkey.c t-import.c t-keylist.c t-keylist-sig.c t-sign.c t-signers.c t-thread1.c t-trustlist.c t-verify.c t-wait.c - srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -75,9 +73,10 @@ CONFIG_CLEAN_FILES = am__EXEEXT_1 = t-encrypt$(EXEEXT) t-encrypt-sym$(EXEEXT) \ t-encrypt-sign$(EXEEXT) t-sign$(EXEEXT) t-signers$(EXEEXT) \ t-decrypt$(EXEEXT) t-verify$(EXEEXT) t-decrypt-verify$(EXEEXT) \ - t-export$(EXEEXT) t-import$(EXEEXT) t-trustlist$(EXEEXT) \ - t-eventloop$(EXEEXT) t-edit$(EXEEXT) t-keylist$(EXEEXT) \ - t-keylist-sig$(EXEEXT) t-thread1$(EXEEXT) t-wait$(EXEEXT) + t-sig-notation$(EXEEXT) t-export$(EXEEXT) t-import$(EXEEXT) \ + t-trustlist$(EXEEXT) t-eventloop$(EXEEXT) t-edit$(EXEEXT) \ + t-keylist$(EXEEXT) t-keylist-sig$(EXEEXT) t-thread1$(EXEEXT) \ + t-wait$(EXEEXT) t-encrypt-large$(EXEEXT) t-file-name$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) t_decrypt_SOURCES = t-decrypt.c t_decrypt_OBJECTS = t-decrypt.$(OBJEXT) @@ -95,6 +94,10 @@ t_encrypt_SOURCES = t-encrypt.c t_encrypt_OBJECTS = t-encrypt.$(OBJEXT) t_encrypt_LDADD = $(LDADD) t_encrypt_DEPENDENCIES = ../../gpgme/libgpgme.la +t_encrypt_large_SOURCES = t-encrypt-large.c +t_encrypt_large_OBJECTS = t-encrypt-large.$(OBJEXT) +t_encrypt_large_LDADD = $(LDADD) +t_encrypt_large_DEPENDENCIES = ../../gpgme/libgpgme.la t_encrypt_sign_SOURCES = t-encrypt-sign.c t_encrypt_sign_OBJECTS = t-encrypt-sign.$(OBJEXT) t_encrypt_sign_LDADD = $(LDADD) @@ -111,6 +114,10 @@ t_export_SOURCES = t-export.c t_export_OBJECTS = t-export.$(OBJEXT) t_export_LDADD = $(LDADD) t_export_DEPENDENCIES = ../../gpgme/libgpgme.la +t_file_name_SOURCES = t-file-name.c +t_file_name_OBJECTS = t-file-name.$(OBJEXT) +t_file_name_LDADD = $(LDADD) +t_file_name_DEPENDENCIES = ../../gpgme/libgpgme.la t_genkey_SOURCES = t-genkey.c t_genkey_OBJECTS = t-genkey.$(OBJEXT) t_genkey_LDADD = $(LDADD) @@ -127,6 +134,10 @@ t_keylist_sig_SOURCES = t-keylist-sig.c t_keylist_sig_OBJECTS = t-keylist-sig.$(OBJEXT) t_keylist_sig_LDADD = $(LDADD) t_keylist_sig_DEPENDENCIES = ../../gpgme/libgpgme.la +t_sig_notation_SOURCES = t-sig-notation.c +t_sig_notation_OBJECTS = t-sig-notation.$(OBJEXT) +t_sig_notation_LDADD = $(LDADD) +t_sig_notation_DEPENDENCIES = ../../gpgme/libgpgme.la t_sign_SOURCES = t-sign.c t_sign_OBJECTS = t-sign.$(OBJEXT) t_sign_LDADD = $(LDADD) @@ -162,12 +173,14 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = t-decrypt.c t-decrypt-verify.c t-edit.c t-encrypt.c \ - t-encrypt-sign.c t-encrypt-sym.c t-eventloop.c t-export.c \ - t-genkey.c t-import.c t-keylist.c t-keylist-sig.c t-sign.c \ + t-encrypt-large.c t-encrypt-sign.c t-encrypt-sym.c \ + t-eventloop.c t-export.c t-file-name.c t-genkey.c t-import.c \ + t-keylist.c t-keylist-sig.c t-sig-notation.c t-sign.c \ t-signers.c t-thread1.c t-trustlist.c t-verify.c t-wait.c DIST_SOURCES = t-decrypt.c t-decrypt-verify.c t-edit.c t-encrypt.c \ - t-encrypt-sign.c t-encrypt-sym.c t-eventloop.c t-export.c \ - t-genkey.c t-import.c t-keylist.c t-keylist-sig.c t-sign.c \ + t-encrypt-large.c t-encrypt-sign.c t-encrypt-sym.c \ + t-eventloop.c t-export.c t-file-name.c t-genkey.c t-import.c \ + t-keylist.c t-keylist-sig.c t-sig-notation.c t-sign.c \ t-signers.c t-thread1.c t-trustlist.c t-verify.c t-wait.c HEADERS = $(noinst_HEADERS) ETAGS = etags @@ -186,6 +199,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -198,6 +213,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -226,6 +242,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -264,12 +282,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ @@ -312,12 +333,13 @@ TESTS_ENVIRONMENT = GNUPGHOME=. GPG_AGEN # The keylist tests must come after the import and the edit test. noinst_HEADERS = t-support.h TESTS = t-encrypt t-encrypt-sym t-encrypt-sign t-sign t-signers \ - t-decrypt t-verify t-decrypt-verify \ + t-decrypt t-verify t-decrypt-verify t-sig-notation \ t-export t-import t-trustlist t-eventloop t-edit \ - t-keylist t-keylist-sig t-thread1 t-wait + t-keylist t-keylist-sig t-thread1 t-wait t-encrypt-large \ + t-file-name CLEANFILES = secring.gpg pubring.gpg trustdb.gpg -DISTCLEANFILES = pubring.gpg~ random_seed +DISTCLEANFILES = pubring.gpg~ random_seed gpg.conf EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \ geheim.txt pubkey-1.asc seckey-1.asc @@ -377,6 +399,9 @@ t-edit$(EXEEXT): $(t_edit_OBJECTS) $(t_e t-encrypt$(EXEEXT): $(t_encrypt_OBJECTS) $(t_encrypt_DEPENDENCIES) @rm -f t-encrypt$(EXEEXT) $(LINK) $(t_encrypt_LDFLAGS) $(t_encrypt_OBJECTS) $(t_encrypt_LDADD) $(LIBS) +t-encrypt-large$(EXEEXT): $(t_encrypt_large_OBJECTS) $(t_encrypt_large_DEPENDENCIES) + @rm -f t-encrypt-large$(EXEEXT) + $(LINK) $(t_encrypt_large_LDFLAGS) $(t_encrypt_large_OBJECTS) $(t_encrypt_large_LDADD) $(LIBS) t-encrypt-sign$(EXEEXT): $(t_encrypt_sign_OBJECTS) $(t_encrypt_sign_DEPENDENCIES) @rm -f t-encrypt-sign$(EXEEXT) $(LINK) $(t_encrypt_sign_LDFLAGS) $(t_encrypt_sign_OBJECTS) $(t_encrypt_sign_LDADD) $(LIBS) @@ -389,6 +414,9 @@ t-eventloop$(EXEEXT): $(t_eventloop_OBJE t-export$(EXEEXT): $(t_export_OBJECTS) $(t_export_DEPENDENCIES) @rm -f t-export$(EXEEXT) $(LINK) $(t_export_LDFLAGS) $(t_export_OBJECTS) $(t_export_LDADD) $(LIBS) +t-file-name$(EXEEXT): $(t_file_name_OBJECTS) $(t_file_name_DEPENDENCIES) + @rm -f t-file-name$(EXEEXT) + $(LINK) $(t_file_name_LDFLAGS) $(t_file_name_OBJECTS) $(t_file_name_LDADD) $(LIBS) t-genkey$(EXEEXT): $(t_genkey_OBJECTS) $(t_genkey_DEPENDENCIES) @rm -f t-genkey$(EXEEXT) $(LINK) $(t_genkey_LDFLAGS) $(t_genkey_OBJECTS) $(t_genkey_LDADD) $(LIBS) @@ -401,6 +429,9 @@ t-keylist$(EXEEXT): $(t_keylist_OBJECTS) t-keylist-sig$(EXEEXT): $(t_keylist_sig_OBJECTS) $(t_keylist_sig_DEPENDENCIES) @rm -f t-keylist-sig$(EXEEXT) $(LINK) $(t_keylist_sig_LDFLAGS) $(t_keylist_sig_OBJECTS) $(t_keylist_sig_LDADD) $(LIBS) +t-sig-notation$(EXEEXT): $(t_sig_notation_OBJECTS) $(t_sig_notation_DEPENDENCIES) + @rm -f t-sig-notation$(EXEEXT) + $(LINK) $(t_sig_notation_LDFLAGS) $(t_sig_notation_OBJECTS) $(t_sig_notation_LDADD) $(LIBS) t-sign$(EXEEXT): $(t_sign_OBJECTS) $(t_sign_DEPENDENCIES) @rm -f t-sign$(EXEEXT) $(LINK) $(t_sign_LDFLAGS) $(t_sign_OBJECTS) $(t_sign_LDADD) $(LIBS) @@ -429,15 +460,18 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-decrypt-verify.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-decrypt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-edit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-encrypt-large.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-encrypt-sign.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-encrypt-sym.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-encrypt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-eventloop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-export.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-file-name.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-genkey.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-import.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-keylist-sig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-keylist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-sig-notation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-sign.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-signers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-thread1.Po@am__quote@ @@ -722,14 +756,19 @@ uninstall-am: uninstall-info-am clean-local: $(srcdir)/mkdemodirs --clean -all-local: ./pubring.gpg +all-local: ./pubring.gpg ./gpg.conf ./pubring.gpg: $(srcdir)/pubdemo.asc ./Alpha/Secret.gpg $(GPG) --homedir . --import $(srcdir)/pubdemo.asc - $(GPG) --homedir . --allow-secret-key-import --import Alpha/Secret.gpg Zulu/Secret.gpg + $(GPG) --homedir . --allow-secret-key-import \ + --import Alpha/Secret.gpg Zulu/Secret.gpg ./Alpha/Secret.gpg: secdemo.asc srcdir=$(srcdir) $(srcdir)/mkdemodirs + +./gpg.conf: +# This is required for t-sig-notations. + echo no-force-v3-sigs > ./gpg.conf # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -urpNP gpgme-1.0.3/tests/gpg/t-encrypt-large.c gpgme-1.1.0/tests/gpg/t-encrypt-large.c --- gpgme-1.0.3/tests/gpg/t-encrypt-large.c 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/tests/gpg/t-encrypt-large.c 2005-09-25 19:26:35.000000000 +0000 @@ -0,0 +1,143 @@ +/* t-encrypt-large.c - Regression test for large amounts of data. + Copyright (C) 2005 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "t-support.h" + + +struct cb_parms +{ + size_t bytes_to_send; + size_t bytes_received; +}; + + + +/* The read callback used by GPGME to read data. */ +static ssize_t +read_cb (void *handle, void *buffer, size_t size) +{ + struct cb_parms *parms = handle; + char *p = buffer; + + for (; size && parms->bytes_to_send; size--, parms->bytes_to_send--) + *p++ = rand (); + + return (p - (char*)buffer); +} + +/* The write callback used by GPGME to write data. */ +static ssize_t +write_cb (void *handle, const void *buffer, size_t size) +{ + struct cb_parms *parms = handle; + + parms->bytes_received += size; + + return size; +} + + +static void +progress_cb (void *opaque, const char *what, int type, int current, int total) +{ + /* This is just a dummy. */ +} + + + + + +int +main (int argc, char *argv[]) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + struct gpgme_data_cbs cbs; + gpgme_data_t in, out; + gpgme_key_t key[3] = { NULL, NULL, NULL }; + gpgme_encrypt_result_t result; + size_t nbytes; + struct cb_parms parms; + + if (argc > 1) + nbytes = atoi (argv[1]); + else + nbytes = 100000; + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + memset (&cbs, 0, sizeof cbs); + cbs.read = read_cb; + cbs.write = write_cb; + memset (&parms, 0, sizeof parms); + parms.bytes_to_send = nbytes; + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_armor (ctx, 0); + + /* Install a progress handler to enforce a bit of more work to the + gpgme i/o system. */ + gpgme_set_progress_cb (ctx, progress_cb, NULL); + + err = gpgme_data_new_from_cbs (&in, &cbs, &parms); + fail_if_err (err); + + err = gpgme_data_new_from_cbs (&out, &cbs, &parms); + fail_if_err (err); + + err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734", + &key[0], 0); + fail_if_err (err); + err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", + &key[1], 0); + fail_if_err (err); + + err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); + fail_if_err (err); + result = gpgme_op_encrypt_result (ctx); + if (result->invalid_recipients) + { + fprintf (stderr, "Invalid recipient encountered: %s\n", + result->invalid_recipients->fpr); + exit (1); + } + printf ("plaintext=%u bytes, ciphertext=%u bytes\n", + (unsigned int)nbytes, (unsigned int)parms.bytes_received); + + gpgme_key_unref (key[0]); + gpgme_key_unref (key[1]); + gpgme_data_release (in); + gpgme_data_release (out); + gpgme_release (ctx); + return 0; +} diff -urpNP gpgme-1.0.3/tests/gpg/t-file-name.c gpgme-1.1.0/tests/gpg/t-file-name.c --- gpgme-1.0.3/tests/gpg/t-file-name.c 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/tests/gpg/t-file-name.c 2005-09-30 13:50:05.000000000 +0000 @@ -0,0 +1,99 @@ +/* t-file-name.c - Regression test. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "t-support.h" + +#define TESTNAME "abcde12345" + + +int +main (int argc, char *argv[]) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t in, out; + gpgme_key_t key[2] = { NULL, NULL }; + gpgme_decrypt_result_t result; + char *agent_info; + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_armor (ctx, 1); + + agent_info = getenv("GPG_AGENT_INFO"); + if (!(agent_info && strchr (agent_info, ':'))) + gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL); + + err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0); + fail_if_err (err); + + err = gpgme_data_set_file_name (in, TESTNAME); + fail_if_err (err); + + err = gpgme_data_new (&out); + fail_if_err (err); + + err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734", + &key[0], 0); + fail_if_err (err); + + err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); + fail_if_err (err); + + gpgme_data_release (in); + err = gpgme_data_new (&in); + fail_if_err (err); + + err = gpgme_data_seek (out, 0, SEEK_SET); + fail_if_err (err); + + err = gpgme_op_decrypt (ctx, out, in); + fail_if_err (err); + result = gpgme_op_decrypt_result (ctx); + + if (strcmp (TESTNAME, result->file_name)) + { + fprintf (stderr, "%s:%i: Unexpected result file name: %s\n", + __FILE__, __LINE__, + result->file_name ? "(null)" : result->file_name); + exit (1); + } + + gpgme_key_unref (key[0]); + gpgme_data_release (in); + gpgme_data_release (out); + gpgme_release (ctx); + return 0; +} diff -urpNP gpgme-1.0.3/tests/gpg/t-sig-notation.c gpgme-1.1.0/tests/gpg/t-sig-notation.c --- gpgme-1.0.3/tests/gpg/t-sig-notation.c 1970-01-01 00:00:00.000000000 +0000 +++ gpgme-1.1.0/tests/gpg/t-sig-notation.c 2005-10-01 02:06:08.000000000 +0000 @@ -0,0 +1,166 @@ +/* t-sig-notation.c - Regression test. + Copyright (C) 2005 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "t-support.h" + + +static struct { + const char *name; + const char *value; + gpgme_sig_notation_flags_t flags; + int seen; +} expected_notations[] = { + { "laughing@me", + "Just Squeeze Me", + GPGME_SIG_NOTATION_HUMAN_READABLE }, + { "leave@home", + "Right Now", + GPGME_SIG_NOTATION_HUMAN_READABLE | GPGME_SIG_NOTATION_CRITICAL }, + { NULL, + "http://www.gnu.org/policy/", + 0 } +}; + +static void +check_result (gpgme_verify_result_t result) +{ + int i; + gpgme_sig_notation_t r; + + gpgme_signature_t sig; + + sig = result->signatures; + if (!sig || sig->next) + { + fprintf (stderr, "%s:%i: Unexpected number of signatures\n", + __FILE__, __LINE__); + exit (1); + } + + for (i=0; i < DIM(expected_notations); i++ ) + expected_notations[i].seen = 0; + + for (r = result->signatures->notations; r; r = r->next) + { + int any = 0; + for (i=0; i < DIM(expected_notations); i++) + { + if ( ((r->name && expected_notations[i].name + && !strcmp (r->name, expected_notations[i].name) + && r->name_len + == strlen (expected_notations[i].name)) + || (!r->name && !expected_notations[i].name + && r->name_len == 0)) + && r->value + && !strcmp (r->value, expected_notations[i].value) + && r->value_len == strlen (expected_notations[i].value) + && r->flags + == (expected_notations[i].flags & ~GPGME_SIG_NOTATION_CRITICAL) + && r->human_readable + == !!(r->flags & GPGME_SIG_NOTATION_HUMAN_READABLE) + && r->critical == 0) + { + expected_notations[i].seen++; + any++; + } + } + if (!any) + { + fprintf (stderr, "%s:%i: Unexpected notation data\n", + __FILE__, __LINE__); + exit (1); + } + } + for (i=0; i < DIM(expected_notations); i++ ) + { + if (expected_notations[i].seen != 1) + { + fprintf (stderr, "%s:%i: Missing or duplicate notation data\n", + __FILE__, __LINE__); + exit (1); + } + } +} + + +int +main (int argc, char *argv[]) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t in, out; + gpgme_verify_result_t result; + char *agent_info; + int i; + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + err = gpgme_new (&ctx); + fail_if_err (err); + + agent_info = getenv ("GPG_AGENT_INFO"); + if (!(agent_info && strchr (agent_info, ':'))) + gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL); + + err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0); + fail_if_err (err); + err = gpgme_data_new (&out); + fail_if_err (err); + + for (i = 0; i < sizeof (expected_notations) / sizeof (expected_notations[0]); + i++) + { + err = gpgme_sig_notation_add (ctx, expected_notations[i].name, + expected_notations[i].value, + expected_notations[i].flags); + fail_if_err (err); + } + + err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL); + fail_if_err (err); + + gpgme_data_release (in); + err = gpgme_data_new (&in); + fail_if_err (err); + + gpgme_data_seek (out, 0, SEEK_SET); + + err = gpgme_op_verify (ctx, out, NULL, in); + fail_if_err (err); + result = gpgme_op_verify_result (ctx); + check_result (result); + + gpgme_data_release (in); + gpgme_data_release (out); + gpgme_release (ctx); + return 0; +} diff -urpNP gpgme-1.0.3/tests/gpg/t-support.h gpgme-1.1.0/tests/gpg/t-support.h --- gpgme-1.0.3/tests/gpg/t-support.h 2004-12-07 20:04:41.000000000 +0000 +++ gpgme-1.1.0/tests/gpg/t-support.h 2005-09-25 19:26:35.000000000 +0000 @@ -96,7 +96,9 @@ init_gpgme (gpgme_protocol_t proto) gpgme_check_version (NULL); setlocale (LC_ALL, ""); gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); +#ifndef HAVE_W32_SYSTEM gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); +#endif err = gpgme_engine_check_version (proto); fail_if_err (err); diff -urpNP gpgme-1.0.3/tests/gpg/t-verify.c gpgme-1.1.0/tests/gpg/t-verify.c --- gpgme-1.0.3/tests/gpg/t-verify.c 2004-12-07 20:03:25.000000000 +0000 +++ gpgme-1.1.0/tests/gpg/t-verify.c 2005-10-01 02:06:08.000000000 +0000 @@ -136,10 +136,14 @@ check_result (gpgme_verify_result_t resu for (i=0; i < DIM(expected_notations); i++) { if ( ((r->name && expected_notations[i].name - && !strcmp (r->name, expected_notations[i].name)) - || (!r->name && !expected_notations[i].name)) + && !strcmp (r->name, expected_notations[i].name) + && r->name_len + == strlen (expected_notations[i].name)) + || (!r->name && !expected_notations[i].name + && r->name_len == 0)) && r->value - && !strcmp (r->value, expected_notations[i].value)) + && !strcmp (r->value, expected_notations[i].value) + && r->value_len == strlen (expected_notations[i].value)) { expected_notations[i].seen++; any++; diff -urpNP gpgme-1.0.3/tests/gpgsm/Makefile.in gpgme-1.1.0/tests/gpgsm/Makefile.in --- gpgme-1.0.3/tests/gpgsm/Makefile.in 2005-06-20 19:35:25.000000000 +0000 +++ gpgme-1.1.0/tests/gpgsm/Makefile.in 2005-10-01 21:13:47.000000000 +0000 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -34,8 +34,6 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -SOURCES = t-decrypt.c t-encrypt.c t-export.c t-genkey.c t-import.c t-keylist.c t-sign.c t-verify.c - srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -140,6 +138,8 @@ BUILD_ASSUAN_FALSE = @BUILD_ASSUAN_FALSE BUILD_ASSUAN_TRUE = @BUILD_ASSUAN_TRUE@ BUILD_COMPLUS_FALSE = @BUILD_COMPLUS_FALSE@ BUILD_COMPLUS_TRUE = @BUILD_COMPLUS_TRUE@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -152,6 +152,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -180,6 +181,8 @@ HAVE_PTHREAD_FALSE = @HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE = @HAVE_PTHREAD_TRUE@ HAVE_PTH_FALSE = @HAVE_PTH_FALSE@ HAVE_PTH_TRUE = @HAVE_PTH_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -218,12 +221,15 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WINDRES = @WINDRES@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ ac_ct_F77 = @ac_ct_F77@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ +ac_ct_WINDRES = @ac_ct_WINDRES@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFDPwAkwKTLuYeXhWkRApiDAJ47okpswx6F79MV+RS0sf+IlZzWVwCZAQmM 9G0f6F3hPLb00XpeKXYdp8o= =Bk1z -----END PGP SIGNATURE-----