[svn] assuan - r201 - in trunk: . doc m4 src tests

svn author wk cvs at cvs.gnupg.org
Thu Sep 14 13:17:34 CEST 2006


Author: wk
Date: 2006-09-14 13:17:33 +0200 (Thu, 14 Sep 2006)
New Revision: 201

Added:
   trunk/m4/Makefile.am
   trunk/m4/onceonly.m4
   trunk/m4/socklen.m4
   trunk/m4/sys_socket_h.m4
Removed:
   trunk/m4/ChangeLog
Modified:
   trunk/AUTHORS
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/NEWS
   trunk/TODO
   trunk/configure.ac
   trunk/doc/assuan.texi
   trunk/src/ChangeLog
   trunk/src/assuan-buffer.c
   trunk/src/assuan-client.c
   trunk/src/assuan-connect.c
   trunk/src/assuan-defs.h
   trunk/src/assuan-io.c
   trunk/src/assuan-pipe-connect.c
   trunk/src/assuan-pipe-server.c
   trunk/src/assuan-socket-server.c
   trunk/src/assuan.h
   trunk/tests/fdpassing.c
Log:
Preparing a new release


Modified: trunk/AUTHORS
===================================================================
--- trunk/AUTHORS	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/AUTHORS	2006-09-14 11:17:33 UTC (rev 201)
@@ -13,6 +13,8 @@
 Marcus Brinkmann  <marcus at g10code.de>
  - Bug fixes.
 
+g10 Code GmbH   <info at g10code.com> 
+ - all work indicated by mail addresses in ChangeLogs
 
 
 Libassuan was orginally part of NewPG, a temporary fork of GnuPG, and

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/ChangeLog	2006-09-14 11:17:33 UTC (rev 201)
@@ -1,3 +1,11 @@
+2006-09-14  Werner Koch  <wk at g10code.com>
+
+	Released 0.9.0.
+
+	* configure.ac: Check for S_PEERCRED.  Include check for socklen_t.
+	* m4/sys_socket_h.m4, m4/onceonly.m4, m4/socklen.m4: New.
+	* m4/Makefile.am: New.
+
 2006-09-05  Werner Koch  <wk at g10code.com>
 
 	* configure.ac (AH_BOTTOM): Define _ASSUAN_IN_LIBASSUAN.

Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/Makefile.am	2006-09-14 11:17:33 UTC (rev 201)
@@ -4,5 +4,9 @@
 
 EXTRA_DIST = config.rpath  config.rpath autogen.sh README.SVN
 
-SUBDIRS = src doc tests
+SUBDIRS = m4 src doc tests
 
+
+dist-hook:
+	echo "$(VERSION)" > $(distdir)/VERSION
+

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/NEWS	2006-09-14 11:17:33 UTC (rev 201)
@@ -1,5 +1,5 @@
-Noteworthy changes in version 0.9.0
--------------------------------------------------
+Noteworthy changes in version 0.9.0 (2006-09-14)
+------------------------------------------------
 
  * Internal cleanups to make inclusion of the code into libraries
    easier.
@@ -17,12 +17,14 @@
    printing of the full data, a new environment variable
    ASSUAN_FULL_LOGGING may be set to any value.
 
- * Removed the assuan_domain functions. 
+ * Removed the assuan_domain_* functions. 
 
- * New functions assuan_pipe_connect_ext and assuan_socket_connext_ext
+ * New functions assuan_pipe_connect_ext and assuan_socket_connect_ext
    to allow connections on a socketpair and to pass descriptors.
 
+ * New function assuan_get_peercred.
 
+
 Noteworthy changes in version 0.6.10 (2005-06-20)
 -------------------------------------------------
 

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/TODO	2006-09-14 11:17:33 UTC (rev 201)
@@ -1,6 +1,5 @@
                                                            -*- outline -*-
-* waitpid is used instead of pth_waitpid as well as some  other
-  functions.
+* Check that we have Pth-ed all blocking fucntions.
 * When turning libassuan into a shared library, provide a general
   version as well as a Pth-enabled one.
 * Need API documentation.
@@ -10,6 +9,3 @@
   for unknown inquiries, albeit dirmngr itself would handle the
   returns for assuan_inquire gracefully.  We need to check all
   applications whether it is safe to change this.
-* Do a configure test for SO_PEERCRED.
-  We already use HAVE_SO_PEERCRED buty it never gets defined.
-* Replace assuan_pipe_connect2 by  assuan_pipe_connect.
\ No newline at end of file

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/configure.ac	2006-09-14 11:17:33 UTC (rev 201)
@@ -1,29 +1,31 @@
 # configure.ac - for libassuan
-#       Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc,
+# Copyright (C) 2001, 2002, 2003, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+# This file is part of Assuan.
+#
+# Assuan is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Assuan is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+# MA 02110-1301, USA 
 
 # Process this file with autoconf to produce a configure script.
+
 AC_PREREQ(2.59)
 min_automake_version="1.9.3"
 
 # Version number: Remember to change it immediately *after* a release.
 #                 Add a "-cvs" prefix for non-released code.
-AC_INIT(libassuan, 0.9.0-cvs, gnupg-devel at gnupg.org)
+AC_INIT(libassuan, 0.9.0, gnupg-devel at gnupg.org)
 # Note, that this is not yet available as a shared library.
 
 PACKAGE=$PACKAGE_NAME
@@ -132,6 +134,9 @@
 AC_TYPE_SIGNAL
 AC_DECL_SYS_SIGLIST
 
+gl_TYPE_SOCKLEN_T
+
+
 # Checks for library functions.
 
 AC_CHECK_FUNCS(flockfile funlockfile)
@@ -161,8 +166,31 @@
 AC_CHECK_HEADERS(unistd.h)
 AC_REPLACE_FUNCS(setenv)
 
+
+#
+# Check for the getsockopt SO_PEERCRED
+#
+AC_MSG_CHECKING(for SO_PEERCRED)
+AC_CACHE_VAL(assuan_cv_sys_so_peercred,
+      [AC_TRY_COMPILE([#include <sys/socket.h>], 
+         [struct ucred cr; 
+          int cl = sizeof cr;
+          getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);],
+          assuan_cv_sys_so_peercred=yes,
+          assuan_cv_sys_so_peercred=no)
+       ])
+AC_MSG_RESULT($assuan_cv_sys_so_peercred) 
+if test $assuan_cv_sys_so_peercred = yes; then
+  AC_DEFINE(HAVE_SO_PEERCRED, 1,
+            [Defined if SO_PEERCRED is supported (Linux specific)])
+fi
+
+
+
+
 # Create the config files.
 AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([m4/Makefile])
 AC_CONFIG_FILES([src/Makefile])
 AC_CONFIG_FILES([doc/Makefile])
 AC_CONFIG_FILES([tests/Makefile])

Modified: trunk/doc/assuan.texi
===================================================================
--- trunk/doc/assuan.texi	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/doc/assuan.texi	2006-09-14 11:17:33 UTC (rev 201)
@@ -558,6 +558,7 @@
 @menu
 * Data Types::                  Data types used by @sc{libassuan}.
 * Initializing the library::    How to initialize the library.
+* Reading and Writing::         How to communicate with the peer.
 @end menu
 
 
@@ -566,16 +567,17 @@
 @section Data Types used by the library
 
 @sc{libassuan} uses a context approach to keep state.  The following
-data type is used all over the palce:
+data type is used all over the place:
 
 @deftp {Data type} assuan_context_t
 The @code{assuan_context_t} type is a pointer to an object mainted
-internally by the library.  Certain assuan fucntions allocate such a
+internally by the library.  Certain Assuan functions allocate such a
 context and return it to the caller using this data type. Other
 functions take this data type to access the state created by these
 functions.
 @end deftp
 
+ at noindent
 For compatibility with older versions of @sc{libassuan} a data
 type for error return values exists:
 
@@ -605,6 +607,7 @@
 set @code{errno} whenever an error has occured.
 @end deftypefun
 
+ at noindent
 To integrate assuan logging and diagnostics into your own logging
 system, you may use the following two functions:
 
@@ -618,7 +621,7 @@
 setup a proper default.
 @end deftypefun
 
- at deftypefun void assuan_set_assuan_log_prefix (const char *@var{text})
+ at deftypefun void assuan_set_assuan_log_prefix (@w{const char *@var{text}})
 Set the prefix to be used at the start of a line emitted by assuan
 on the log stream to @var{text}.  The default is the empty string. 
 @end deftypefun
@@ -638,15 +641,114 @@
 @end smallexample
 @end deftypefun
 
+ at node Reading and Writing
+ at section How to communicate with the peer
+
+What would be a IPC library without the ability to read and write data?
+Not very useful.  Libassuan has high level functions to take care of of
+the more boring stuff but eventully actually data needs to be written.
+
+ at noindent
+The basic read and write functions are:
+
+ at deftypefun assuan_error_t assuan_read_line (@w{assuan_context_t @var{ctx}}, @w{char **@var{line}}, @w{size_t *@var{linelen}})
+
+Read the next line from the client or server and store a pointer to the
+buffer holding that line at the address @var{line}.  The valid length of
+the lines is stored at the address of @var{linelen}. This buffer is
+valid until the next read operation on the same context @var{ctx}.  You
+may modify the contet of this buffer.  The buffer is invalid (i.e. must
+not be used) if an error is returned.  This function returns @code{0} on
+success or an error code.
+ at end deftypefun
+
+ at deftypefun assuan_error_t assuan_write_line (@w{assuan_context_t @var{ctx}}, @w{const char *@var{line}})
+
+Write the string @var{line} to the other end.  This string needs to be a
+proper formatted Assuan protocol line and should not include a linefeed.
+Sending linefeed or Nul characters is not possible and not alowed by the
+assuan protocol.  This fucntion shall not be used for sendind data (D)
+lines.  This function returns @code{0} on success or an error code.
+ at end deftypefun
+
+ at noindent 
+To actually send bulk data lines a specialized function is available:
+
+ at deftypefun assuan_error_t assuan_send_data (@w{assuan_context_t @var{ctx}}, @w{const void *@var{buffer}}, @w{size_t @var{length}})
+
+This function is used by a server or a client to send
+ at var{length} bytes of bulk data in @var{buffer} to the other end.
+The data will be escaped as required by the Assuan protocol and
+may get buffered until a line is full.  To force sending the data out
+ at var{buffer} may be passed as @code{NULL} and @var{length} be @code{0}.
+
+When used by a client this flush operation does also send the
+terminating @code{END} command to terminate the response on an
+``INQUIRE'' response.  Note, that the fucntion @code{assuan_transact}
+takes care of sending this @code{END} itself.
+
+ at noindent
+This function returns @code{0} on success or an error code.
+ at end deftypefun
+
+
+
+
 @c 
 @c     C L I E N T   C O D E
 @c
 @node Client code
 @chapter How to develop an Assuan client
 
-foo
 
 
+
+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_error_t assuan_pipe_connect_ext (assuan_context_t *ctx, 
+                                        const char *name,
+                                        const char *const argv[],
+                                        int *fd_child_list,
+                                        void (*atfork) (void *, int),
+                                        void *atforkvalue,
+                                        unsigned int flags);
+
+assuan_error_t assuan_socket_connect (assuan_context_t *ctx, 
+                                      const char *name,
+                                      pid_t server_pid);
+assuan_error_t assuan_socket_connect_ext (assuan_context_t *ctx,
+                                          const char *name,
+                                          pid_t server_pid,
+                                          unsigned int flags);
+
+void assuan_disconnect (assuan_context_t ctx);
+
+assuan_error_t 
+assuan_transact (assuan_context_t ctx,
+                 const char *command,
+                 int (*data_cb)(void *, const void *, size_t),
+                 void *data_cb_arg,
+                 int (*inquire_cb)(void*, const char *),
+                 void *inquire_cb_arg,
+                 int (*status_cb)(void*, const char *),
+                 void *status_cb_arg);
+
+
+/* The file descriptor must be pending before assuan_receivefd is
+   called.  This means that assuan_sendfd should be called *before* the
+   trigger is sent (normally via assuan_write_line ("INPUT FD")).  */
+assuan_error_t assuan_sendfd (assuan_context_t ctx, int fd);
+assuan_error_t assuan_receivefd (assuan_context_t ctx, int *fd);
+
+
 @c 
 @c     S E R V E R   C O D E
 @c
@@ -654,16 +756,138 @@
 @chapter How to develop an Assuan server
 
 bar
+int assuan_register_command (assuan_context_t ctx,
+                             const char *cmd_string,
+                             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_t ctx,
+                                    int (*fnc)(assuan_context_t,
+                                               const char*, const char*));
+
+int assuan_process (assuan_context_t ctx);
+int assuan_process_next (assuan_context_t ctx);
+
+FILE *assuan_get_data_fp (assuan_context_t ctx);
+assuan_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line);
+assuan_error_t assuan_write_status (assuan_context_t ctx,
+                                    const char *keyword, const char *text);
+
+/* Negotiate a file descriptor.  If LINE contains "FD=N", returns N
+   assuming a local file descriptor.  If LINE contains "FD" reads a
+   file descriptor via CTX and stores it in *RDF (the CTX must be
+   capable of passing file descriptors).  */
+assuan_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line,
+                                        int *rfd);
+
+assuan_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);
+
+int assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]);
+void assuan_deinit_server (assuan_context_t ctx);
+
+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);
+int assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
+                                   unsigned int flags);
+
+assuan_error_t assuan_inquire (assuan_context_t ctx, const char *keyword,
+                               unsigned char **r_buffer, size_t *r_length,
+                               size_t maxlen);
+
+
+
 @c
 @c     U T I L I T I E S
 @c
 @node Utilities
 @chapter Utility functions
 
-baz
 
+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);
+
+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;
+
+
+
+/* Return the VALUE of FLAG in context CTX. */ 
+int  assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag);
+
+
+const char *assuan_strerror (assuan_error_t err);
+
+
+ at deftypefun pid_t assuan_get_pid (@w{assuan_context_t @var{ctx}})
+
+This function returns the pid of the connected connected peer.  If that
+pid is not known @code{-1} is returned.  Note that it is not always
+possible to learn the pid of the other process. For a pipe based server
+the client knows it instantly and a mechnism is in palce to let the
+server learn it.  For socket based servers the pid is only available on
+systems providing the ``SO_PEERCRED'' socket option @footnote{to our
+knowledge only the Linux kernel has this feature}.
+ at end deftypefun
+
+
+ at deftypefun assuan_error_t assuan_get_peercred (@w{assuan_context_t @var{ctx}}, @w{pid_t *@var{pid}}, @w{uid_t *@var{uid}}, @w{gid_t *@var{pid}})
+
+Return user credentials of the peer. This will work only on certain
+systems and only when connected over a socket.  If you are not
+interested in some of the values, pass @code{NULL} instead of the
+address of an appropriate variable.  @var{pid}, @var{uid} and @var{gid}
+are only set if the function succeeds and returns with @code{0}.
+
+As of now only the server is able to retrieve this information.  Note,
+that for getting the pid of the peer @code{assuan_get_pid} is usually
+better suited.
+ at end deftypefun
+
+
+int assuan_get_active_fds (assuan_context_t ctx, int what,
+                           int *fdarray, int fdarraysize);
+
+int assuan_pending_line (assuan_context_t ctx);
+
+/* Return the stream which is currently being using for global logging.  */
+FILE *assuan_get_assuan_log_stream (void);
+
+/* 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);
+
+
 @c ---------------------------------------------------------------------
 @c Legal BS
 @c ---------------------------------------------------------------------

Deleted: trunk/m4/ChangeLog

Added: trunk/m4/Makefile.am
===================================================================
--- trunk/m4/Makefile.am	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/m4/Makefile.am	2006-09-14 11:17:33 UTC (rev 201)
@@ -0,0 +1 @@
+EXTRA_DIST = socklen.m4 sys_socket_h.m4 onceonly.m4

Added: trunk/m4/onceonly.m4
===================================================================
--- trunk/m4/onceonly.m4	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/m4/onceonly.m4	2006-09-14 11:17:33 UTC (rev 201)
@@ -0,0 +1,66 @@
+# onceonly.m4 serial 4 (gettext-0.15)
+dnl Copyright (C) 2002-2003, 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This file defines some "once only" variants of standard autoconf macros.
+dnl   AC_CHECK_HEADERS_ONCE         like  AC_CHECK_HEADERS
+dnl   AC_CHECK_FUNCS_ONCE           like  AC_CHECK_FUNCS
+dnl   AC_CHECK_DECLS_ONCE           like  AC_CHECK_DECLS
+dnl   AC_REQUIRE([AC_HEADER_STDC])  like  AC_HEADER_STDC
+dnl The advantage is that the check for each of the headers/functions/decls
+dnl will be put only once into the 'configure' file. It keeps the size of
+dnl the 'configure' file down, and avoids redundant output when 'configure'
+dnl is run.
+dnl The drawback is that the checks cannot be conditionalized. If you write
+dnl   if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi
+dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to
+dnl empty, and the check will be inserted before the body of the AC_DEFUNed
+dnl function.
+
+dnl This file is only needed in autoconf <= 2.59.  Newer versions of autoconf
+dnl have this macro built-in.  But about AC_CHECK_DECLS_ONCE: note that in
+dnl autoconf >= 2.60 the symbol separator is a comma, whereas here it is
+dnl whitespace.
+
+dnl Autoconf version 2.57 or newer is recommended.
+AC_PREREQ(2.54)
+
+# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of
+# AC_CHECK_HEADERS(HEADER1 HEADER2 ...).
+AC_DEFUN([AC_CHECK_HEADERS_ONCE], [
+  :
+  AC_FOREACH([gl_HEADER_NAME], [$1], [
+    AC_DEFUN([gl_CHECK_HEADER_]m4_quote(translit(m4_defn([gl_HEADER_NAME]),
+                                                 [-./], [___])), [
+      AC_CHECK_HEADERS(gl_HEADER_NAME)
+    ])
+    AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME,
+                                                   [-./], [___])))
+  ])
+])
+
+# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of
+# AC_CHECK_FUNCS(FUNC1 FUNC2 ...).
+AC_DEFUN([AC_CHECK_FUNCS_ONCE], [
+  :
+  AC_FOREACH([gl_FUNC_NAME], [$1], [
+    AC_DEFUN([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]), [
+      AC_CHECK_FUNCS(m4_defn([gl_FUNC_NAME]))
+    ])
+    AC_REQUIRE([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]))
+  ])
+])
+
+# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of
+# AC_CHECK_DECLS(DECL1, DECL2, ...).
+AC_DEFUN([AC_CHECK_DECLS_ONCE], [
+  :
+  AC_FOREACH([gl_DECL_NAME], [$1], [
+    AC_DEFUN([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]), [
+      AC_CHECK_DECLS(m4_defn([gl_DECL_NAME]))
+    ])
+    AC_REQUIRE([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]))
+  ])
+])

Added: trunk/m4/socklen.m4
===================================================================
--- trunk/m4/socklen.m4	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/m4/socklen.m4	2006-09-14 11:17:33 UTC (rev 201)
@@ -0,0 +1,52 @@
+# socklen.m4 serial 4
+dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Albert Chin, Windows fixes from Simon Josefsson.
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc.  So we
+dnl have to test to find something that will work.
+
+dnl On mingw32, socklen_t is in ws2tcpip.h ('int'), so we try to find
+dnl it there first.  That file is included by gnulib's socket_.h, which
+dnl all users of this module should include.  Cygwin must not include
+dnl ws2tcpip.h.
+AC_DEFUN([gl_TYPE_SOCKLEN_T],
+  [AC_REQUIRE([gl_HEADER_SYS_SOCKET])dnl
+   AC_CHECK_TYPE([socklen_t], ,
+     [AC_MSG_CHECKING([for socklen_t equivalent])
+      AC_CACHE_VAL([gl_cv_gl_cv_socklen_t_equiv],
+	[# Systems have either "struct sockaddr *" or
+	 # "void *" as the second argument to getpeername
+	 gl_cv_socklen_t_equiv=
+	 for arg2 in "struct sockaddr" void; do
+	   for t in int size_t "unsigned int" "long int" "unsigned long int"; do
+	     AC_TRY_COMPILE(
+	       [#include <sys/types.h>
+		#include <sys/socket.h>
+
+		int getpeername (int, $arg2 *, $t *);],
+	       [$t len;
+		getpeername (0, 0, &len);],
+	       [gl_cv_socklen_t_equiv="$t"])
+	     test "$gl_cv_socklen_t_equiv" != "" && break
+	   done
+	   test "$gl_cv_socklen_t_equiv" != "" && break
+	 done
+      ])
+      if test "$gl_cv_socklen_t_equiv" = ""; then
+	AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+      fi
+      AC_MSG_RESULT([$gl_cv_socklen_t_equiv])
+      AC_DEFINE_UNQUOTED([socklen_t], [$gl_cv_socklen_t_equiv],
+	[type to use in place of socklen_t if not defined])],
+     [#include <sys/types.h>
+      #if HAVE_SYS_SOCKET_H
+      # include <sys/socket.h>
+      #elif HAVE_WS2TCPIP_H
+      # include <ws2tcpip.h>
+      #endif])])

Added: trunk/m4/sys_socket_h.m4
===================================================================
--- trunk/m4/sys_socket_h.m4	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/m4/sys_socket_h.m4	2006-09-14 11:17:33 UTC (rev 201)
@@ -0,0 +1,23 @@
+# sys_socket_h.m4 serial 2
+dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson.
+
+AC_DEFUN([gl_HEADER_SYS_SOCKET],
+[
+  AC_CHECK_HEADERS_ONCE([sys/socket.h])
+  if test $ac_cv_header_sys_socket_h = yes; then
+    SYS_SOCKET_H=''
+  else
+    dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make
+    dnl the check for those headers unconditional; yet cygwin reports
+    dnl that the headers are present but cannot be compiled (since on
+    dnl cygwin, all socket information should come from sys/socket.h).
+    AC_CHECK_HEADERS([winsock2.h ws2tcpip.h])
+    SYS_SOCKET_H='sys/socket.h'
+  fi
+  AC_SUBST(SYS_SOCKET_H)
+])

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/ChangeLog	2006-09-14 11:17:33 UTC (rev 201)
@@ -1,3 +1,15 @@
+2006-09-14  Werner Koch  <wk at g10code.com>
+
+	* assuan-io.c (_assuan_waitpid): New.  Changed all waitpid calls
+	to this.
+
+	* assuan.h (_ASSUAN_DEPRECATED): New internal macro.
+	(assuan_pipe_connect2): Declare deprecated.
+	(assuan_init_connected_socket_server): Declare deprecated.
+
+	* assuan-connect.c (assuan_get_peercred): New.
+	* assuan-socket-server.c (accept_connection_bottom): Save uid and gid.
+
 2006-09-13  Werner Koch  <wk at g10code.com>
 
 	* assuan-client.c (assuan_transact): Need to map the error code.

Modified: trunk/src/assuan-buffer.c
===================================================================
--- trunk/src/assuan-buffer.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-buffer.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -35,7 +35,7 @@
 /* Extended version of write(2) to guarantee that all bytes are
    written.  Returns 0 on success or -1 and ERRNO on failure. */
 static int
-writen (ASSUAN_CONTEXT ctx, const char *buffer, size_t length)
+writen (assuan_context_t ctx, const char *buffer, size_t length)
 {
   while (length)
     {
@@ -57,7 +57,7 @@
    failure.  EOF is indictated by setting the integer at address
    R_EOF.  */
 static int
-readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen,
+readline (assuan_context_t ctx, char *buf, size_t buflen,
 	  int *r_nread, int *r_eof)
 {
   size_t nleft = buflen;
@@ -96,7 +96,7 @@
 
 /* Function returns an Assuan error. */
 int
-_assuan_read_line (ASSUAN_CONTEXT ctx)
+_assuan_read_line (assuan_context_t ctx)
 {
   char *line = ctx->inbound.line;
   int nread, atticlen;
@@ -216,7 +216,7 @@
    See also: assuan_pending_line().
 */
 assuan_error_t
-assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
+assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen)
 {
   assuan_error_t err;
 
@@ -233,7 +233,7 @@
 /* Return true if a full line is buffered (i.e. an entire line may be
    read without any I/O).  */
 int
-assuan_pending_line (ASSUAN_CONTEXT ctx)
+assuan_pending_line (assuan_context_t ctx)
 {
   return ctx && ctx->inbound.attic.pending;
 }
@@ -300,7 +300,7 @@
 
 
 assuan_error_t 
-assuan_write_line (ASSUAN_CONTEXT ctx, const char *line)
+assuan_write_line (assuan_context_t ctx, const char *line)
 {
   size_t len;
   const char *s;
@@ -329,7 +329,7 @@
 int
 _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
 {
-  ASSUAN_CONTEXT ctx = cookie;
+  assuan_context_t ctx = cookie;
   size_t size = orig_size;
   char *line;
   size_t linelen;
@@ -406,7 +406,7 @@
 int
 _assuan_cookie_write_flush (void *cookie)
 {
-  ASSUAN_CONTEXT ctx = cookie;
+  assuan_context_t ctx = cookie;
   char *line;
   size_t linelen;
 
@@ -462,7 +462,7 @@
  **/
 
 assuan_error_t
-assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
+assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
 {
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
@@ -488,7 +488,7 @@
 }
 
 assuan_error_t
-assuan_sendfd (ASSUAN_CONTEXT ctx, int fd)
+assuan_sendfd (assuan_context_t ctx, int fd)
 {
   if (! ctx->io->sendfd)
     return set_error (ctx, Not_Implemented,
@@ -498,7 +498,7 @@
 }
 
 assuan_error_t
-assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd)
+assuan_receivefd (assuan_context_t ctx, int *fd)
 {
   if (! ctx->io->receivefd)
     return set_error (ctx, Not_Implemented,

Modified: trunk/src/assuan-client.c
===================================================================
--- trunk/src/assuan-client.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-client.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -34,7 +34,7 @@
 
 
 assuan_error_t
-_assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
+_assuan_read_from_server (assuan_context_t ctx, int *okay, int *off)
 {
   char *line;
   int linelen;
@@ -130,7 +130,7 @@
  * will altter return an Assuan error (write erro in most cases).
  **/
 assuan_error_t
-assuan_transact (ASSUAN_CONTEXT ctx,
+assuan_transact (assuan_context_t ctx,
                  const char *command,
                  int (*data_cb)(void *, const void *, size_t),
                  void *data_cb_arg,

Modified: trunk/src/assuan-connect.c
===================================================================
--- trunk/src/assuan-connect.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-connect.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -50,10 +50,30 @@
     }
 }
 
-/* Return the PID of the peer or -1 if not known. */
+/* Return the PID of the peer or -1 if not known. This function works
+   in some situations where assuan_get_ucred fails. */
 pid_t
 assuan_get_pid (assuan_context_t ctx)
 {
   return (ctx && ctx->pid)? ctx->pid : -1;
 }
 
+
+/* Return user credentials. PID, UID and GID amy be gived as NULL if
+   you are not interested in this value.  For getting the pid of the
+   peer the assuan_get_pid is usually better suited. */
+assuan_error_t
+assuan_get_peercred (assuan_context_t ctx, pid_t *pid, uid_t *uid, gid_t *gid)
+{
+  if (!ctx)
+    return _assuan_error (ASSUAN_Invalid_Value);
+  if (!ctx->peercred.valid)
+    return _assuan_error (ASSUAN_General_Error);
+  if (pid)
+    *pid = ctx->peercred.pid;
+  if (uid)
+    *uid = ctx->peercred.uid;
+  if (gid)
+    *gid = ctx->peercred.gid;
+  return 0;
+}

Modified: trunk/src/assuan-defs.h
===================================================================
--- trunk/src/assuan-defs.h	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-defs.h	2006-09-14 11:17:33 UTC (rev 201)
@@ -67,7 +67,7 @@
 struct cmdtbl_s
 {
   const char *name;
-  int (*handler)(ASSUAN_CONTEXT, char *line);
+  int (*handler)(assuan_context_t, char *line);
 };
 
 
@@ -76,13 +76,13 @@
 struct assuan_io
 {
   /* Routine to read from input_fd.  */
-  ssize_t (*readfnc) (ASSUAN_CONTEXT, void *, size_t);
+  ssize_t (*readfnc) (assuan_context_t, void *, size_t);
   /* Routine to write to output_fd.  */
-  ssize_t (*writefnc) (ASSUAN_CONTEXT, const void *, size_t);
+  ssize_t (*writefnc) (assuan_context_t, const void *, size_t);
   /* Send a file descriptor.  */
-  assuan_error_t (*sendfd) (ASSUAN_CONTEXT, int);
+  assuan_error_t (*sendfd) (assuan_context_t, int);
   /* Receive a file descriptor.  */
-  assuan_error_t (*receivefd) (ASSUAN_CONTEXT, int *);
+  assuan_error_t (*receivefd) (assuan_context_t, int *);
 };
 
 
@@ -140,6 +140,12 @@
   int listen_fd;  /* The fd we are listening on (used by socket servers) */
   int connected_fd; /* helper */
 
+  struct {
+    int   valid;   /* Whether this structure has valid information. */
+    pid_t pid;     /* The pid of the peer. */
+    uid_t uid;     /* The uid of the peer. */
+    gid_t gid;     /* The gid of the peer. */
+  } peercred;
 
   /* Used for Unix domain sockets.  */
   struct sockaddr_un myaddr;
@@ -158,20 +164,20 @@
     int pendingfdscount;  /* Number of received descriptors. */
   } uds;
 
-  void (*deinit_handler)(ASSUAN_CONTEXT);
-  int (*accept_handler)(ASSUAN_CONTEXT);
-  int (*finish_handler)(ASSUAN_CONTEXT);
+  void (*deinit_handler)(assuan_context_t);
+  int (*accept_handler)(assuan_context_t);
+  int (*finish_handler)(assuan_context_t);
 
   struct cmdtbl_s *cmdtbl;
   size_t cmdtbl_used; /* used entries */
   size_t cmdtbl_size; /* allocated size of table */
 
-  void (*bye_notify_fnc)(ASSUAN_CONTEXT);
-  void (*reset_notify_fnc)(ASSUAN_CONTEXT);
-  void (*cancel_notify_fnc)(ASSUAN_CONTEXT);
-  int  (*option_handler_fnc)(ASSUAN_CONTEXT,const char*, const char*);
-  void (*input_notify_fnc)(ASSUAN_CONTEXT, const char *);
-  void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *);
+  void (*bye_notify_fnc)(assuan_context_t);
+  void (*reset_notify_fnc)(assuan_context_t);
+  void (*cancel_notify_fnc)(assuan_context_t);
+  int  (*option_handler_fnc)(assuan_context_t,const char*, const char*);
+  void (*input_notify_fnc)(assuan_context_t, const char *);
+  void (*output_notify_fnc)(assuan_context_t, const char *);
 
   int input_fd;   /* set by INPUT command */
   int output_fd;  /* set by OUTPUT command */
@@ -181,8 +187,8 @@
 };
 
 /*-- assuan-pipe-server.c --*/
-int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
-void _assuan_release_context (ASSUAN_CONTEXT ctx);
+int _assuan_new_context (assuan_context_t *r_ctx);
+void _assuan_release_context (assuan_context_t ctx);
 
 /*-- assuan-uds.c --*/
 void _assuan_uds_close_fds (assuan_context_t ctx);
@@ -191,17 +197,18 @@
 
 
 /*-- assuan-handler.c --*/
-int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
+int _assuan_register_std_commands (assuan_context_t ctx);
 
 /*-- assuan-buffer.c --*/
-int _assuan_read_line (ASSUAN_CONTEXT ctx);
+int _assuan_read_line (assuan_context_t ctx);
 int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size);
 int _assuan_cookie_write_flush (void *cookie);
 assuan_error_t _assuan_write_line (assuan_context_t ctx, const char *prefix,
                                    const char *line, size_t len);
 
 /*-- assuan-client.c --*/
-assuan_error_t _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
+assuan_error_t _assuan_read_from_server (assuan_context_t ctx,
+                                         int *okay, int *off);
 
 /*-- assuan-error.c --*/
 
@@ -254,8 +261,10 @@
 
 
 /*-- 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,
+pid_t _assuan_waitpid (pid_t pid, int *status, int options);
+
+ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size);
+ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer,
 			      size_t size);
 ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg);
 ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg);

Modified: trunk/src/assuan-io.c
===================================================================
--- trunk/src/assuan-io.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-io.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -25,13 +25,16 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/wait.h>
 #if HAVE_SYS_UIO_H
-#include <sys/uio.h>
+# include <sys/uio.h>
 #endif
 #include <unistd.h>
 #include <errno.h>
 #ifdef HAVE_W32_SYSTEM
-#include <windows.h>
+# include <windows.h>
+#else
+# include <sys/wait.h>
 #endif
 
 #include "assuan-defs.h"
@@ -46,12 +49,14 @@
 
 
 #ifndef _ASSUAN_NO_PTH
+extern pid_t   pth_waitpid (pid_t pid, int *status, int options);
 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);
 extern int     pth_fdmode (int, int);
 extern int     pth_select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
 
 #ifndef HAVE_W32_SYSTEM
+#pragma weak pth_waitpid
 #pragma weak pth_read
 #pragma weak pth_write
 #pragma weak pth_fdmode
@@ -84,6 +89,17 @@
 }
 #endif /*_ASSUAN_NO_PTH*/
 
+#ifndef HAVE_W32_SYSTEM
+pid_t 
+_assuan_waitpid (pid_t pid, int *status, int options)
+{
+#ifdef _ASSUAN_NO_PTH
+  return waitpid (pid, status, options);
+#else
+  return (pth_waitpid ? pth_waitpid : waitpid) (pid, status, options);
+#endif
+}
+#endif
 
 
 ssize_t
@@ -98,7 +114,7 @@
   return pth_read ? pth_read (ctx->inbound.fd, buffer, size)
                   : recv (ctx->inbound.fd, buffer, size, 0);
 # endif
-# endif
+#endif
 }
 
 ssize_t

Modified: trunk/src/assuan-pipe-connect.c
===================================================================
--- trunk/src/assuan-pipe-connect.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-pipe-connect.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -126,7 +126,7 @@
 #ifndef HAVE_W32_SYSTEM
 #ifndef _ASSUAN_USE_DOUBLE_FORK
       if (!ctx->flags.no_waitpid)
-        waitpid (ctx->pid, NULL, 0); 
+        _assuan_waitpid (ctx->pid, NULL, 0); 
       ctx->pid = -1;
 #endif
 #endif /*!HAVE_W32_SYSTEM*/
@@ -342,7 +342,7 @@
     }
 
 #ifdef _ASSUAN_USE_DOUBLE_FORK
-  waitpid ((*ctx)->pid, NULL, 0);
+  _assuan_waitpid ((*ctx)->pid, NULL, 0);
   (*ctx)->pid = -1;
 #endif
 
@@ -525,7 +525,7 @@
 
 
 #ifdef _ASSUAN_USE_DOUBLE_FORK
-  waitpid ((*ctx)->pid, NULL, 0);
+  _assuan_waitpid ((*ctx)->pid, NULL, 0);
   (*ctx)->pid = -1;
 #endif
 
@@ -824,13 +824,7 @@
 }
 
 
-/* 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.  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[],

Modified: trunk/src/assuan-pipe-server.c
===================================================================
--- trunk/src/assuan-pipe-server.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-pipe-server.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -34,20 +34,20 @@
 
 
 static void
-deinit_pipe_server (ASSUAN_CONTEXT ctx)
+deinit_pipe_server (assuan_context_t ctx)
 {
   /* nothing to do for this simple server */
 }
 
 static int
-accept_connection (ASSUAN_CONTEXT ctx)
+accept_connection (assuan_context_t ctx)
 {
   /* This is a NOP for a pipe server */
   return 0;
 }
 
 static int
-finish_connection (ASSUAN_CONTEXT ctx)
+finish_connection (assuan_context_t ctx)
 {
   /* This is a NOP for a pipe server */
   return 0;
@@ -56,13 +56,13 @@
 /* Create a new context.  Note that the handlers are set up for a pipe
    server/client - this way we don't need extra dummy functions */
 int
-_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
+_assuan_new_context (assuan_context_t *r_ctx)
 {
   static struct assuan_io io = { _assuan_simple_read,
 				 _assuan_simple_write,
 				 0, 0 };
 
-  ASSUAN_CONTEXT ctx;
+  assuan_context_t ctx;
   int rc;
 
   *r_ctx = NULL;
@@ -104,14 +104,14 @@
 
 
 int
-assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
+assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2])
 {
   int rc;
 
   rc = _assuan_new_context (r_ctx);
   if (!rc)
     {
-      ASSUAN_CONTEXT ctx = *r_ctx;
+      assuan_context_t ctx = *r_ctx;
       const char *s;
       unsigned long ul;
 
@@ -162,7 +162,7 @@
 
 
 void
-_assuan_release_context (ASSUAN_CONTEXT ctx)
+_assuan_release_context (assuan_context_t ctx)
 {
   if (ctx)
     {
@@ -173,7 +173,7 @@
 }
 
 void
-assuan_deinit_server (ASSUAN_CONTEXT ctx)
+assuan_deinit_server (assuan_context_t ctx)
 {
   if (ctx)
     {

Modified: trunk/src/assuan-socket-server.c
===================================================================
--- trunk/src/assuan-socket-server.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan-socket-server.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -43,16 +43,24 @@
 {
   int fd = ctx->connected_fd;
 
+  ctx->peercred.valid = 0;
 #ifdef HAVE_SO_PEERCRED
   {
-    /* This overrides any already set PID if the function returns a
-       valid one. */
     struct ucred cr; 
-    int cl = sizeof cr;
+    socklen_t cl = sizeof cr;
 
-    if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)
-         && cr.pid != (pid_t)-1 && cr.pid ) 
-      ctx->pid = cr.pid;
+    if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl))
+      {
+         ctx->peercred.pid = cr.pid;
+         ctx->peercred.uid = cr.uid;
+         ctx->peercred.gid = cr.gid;
+         ctx->peercred.valid = 1;
+
+         /* This overrides any already set PID if the function returns
+            a valid one. */
+         if (cr.pid != (pid_t)-1 && cr.pid) 
+           ctx->pid = cr.pid;
+      }
   }
 #endif
 
@@ -117,7 +125,8 @@
   return assuan_init_socket_server_ext (r_ctx, listen_fd, 0);
 }
 
-/* Initialize a server using the already accepted socket FD. */
+/* Initialize a server using the already accepted socket FD.  This
+   fucntion is deprecated. */
 int
 assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd)
 {

Modified: trunk/src/assuan.h
===================================================================
--- trunk/src/assuan.h	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/src/assuan.h	2006-09-14 11:17:33 UTC (rev 201)
@@ -99,6 +99,7 @@
 #define assuan_socket_connect_ext _ASSUAN_PREFIX(assuan_socket_connect_ext)
 #define assuan_disconnect _ASSUAN_PREFIX(assuan_disconnect)
 #define assuan_get_pid _ASSUAN_PREFIX(assuan_get_pid)
+#define assuan_get_peercred _ASSUAN_PREFIX(assuan_get_peercred)
 #define assuan_transact _ASSUAN_PREFIX(assuan_transact)
 #define assuan_inquire _ASSUAN_PREFIX(assuan_inquire)
 #define assuan_read_line _ASSUAN_PREFIX(assuan_read_line)
@@ -168,9 +169,25 @@
 #endif
 #endif
 
-#ifndef _ASSUAN_ONLY_GPG_ERRORS
+
+/* Check for compiler features.  */
+#if __GNUC__
+#define _ASSUAN_GCC_VERSION (__GNUC__ * 10000 \
+                            + __GNUC_MINOR__ * 100 \
+                            + __GNUC_PATCHLEVEL__)
+
+#if _ASSUAN_GCC_VERSION > 30100
+#define _ASSUAN_DEPRECATED  __attribute__ ((__deprecated__))
+#endif
+#endif
+#ifndef _ASSUAN_DEPRECATED
+#define _ASSUAN_DEPRECATED
+#endif
+
+
 /* Assuan error codes.  These are only used by old applications or
    those applications which won't make use of libgpg-error. */
+#ifndef _ASSUAN_ONLY_GPG_ERRORS
 typedef enum
 {
 #ifndef _ASSUAN_IN_LIBASSUAN
@@ -311,7 +328,7 @@
 struct assuan_context_s;
 typedef struct assuan_context_s *assuan_context_t;
 #ifndef _ASSUAN_ONLY_GPG_ERRORS
-typedef struct assuan_context_s *ASSUAN_CONTEXT;
+typedef struct assuan_context_s *ASSUAN_CONTEXT _ASSUAN_DEPRECATED;
 #endif /*_ASSUAN_ONLY_GPG_ERRORS*/
 
 /*-- assuan-handler.c --*/
@@ -366,7 +383,8 @@
 
 /*-- assuan-socket-server.c --*/
 int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd);
-int assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd);
+int assuan_init_connected_socket_server (assuan_context_t *r_ctx, 
+                                         int fd) _ASSUAN_DEPRECATED;
 int assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
                                    unsigned int flags);
 
@@ -380,7 +398,7 @@
                                      const char *const argv[],
 				     int *fd_child_list,
                                      void (*atfork) (void*, int),
-                                     void *atforkvalue);
+                                     void *atforkvalue) _ASSUAN_DEPRECATED;
 assuan_error_t assuan_pipe_connect_ext (assuan_context_t *ctx, 
                                         const char *name,
                                         const char *const argv[],
@@ -401,6 +419,8 @@
 /*-- assuan-connect.c --*/
 void assuan_disconnect (assuan_context_t ctx);
 pid_t assuan_get_pid (assuan_context_t ctx);
+assuan_error_t assuan_get_peercred (assuan_context_t ctx,
+                                    pid_t *pid, uid_t *uid, gid_t *gid);
 
 /*-- assuan-client.c --*/
 assuan_error_t 

Modified: trunk/tests/fdpassing.c
===================================================================
--- trunk/tests/fdpassing.c	2006-09-13 15:55:25 UTC (rev 200)
+++ trunk/tests/fdpassing.c	2006-09-14 11:17:33 UTC (rev 201)
@@ -124,6 +124,9 @@
             log_error ("assuan_accept failed: %s\n", assuan_strerror (rc));
           break;
         }
+      
+      log_info ("client connected.  Client's pid is %ld\n",
+                (long)assuan_get_pid (ctx));
 
       rc = assuan_process (ctx);
       if (rc)
@@ -151,9 +154,10 @@
   FILE *fp;
   int i;
 
-  log_info ("client started\n");
+  log_info ("client started. Servers's pid is %ld\n",
+            (long)assuan_get_pid (ctx));
 
-  for (i=0; i < 8; i++)
+  for (i=0; i < 6; i++)
     {
       fp = fopen ("/etc/motd", "r");
       if (!fp)




More information about the Gnupg-commits mailing list