From cvs at cvs.gnupg.org Mon May 3 13:10:50 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 03 May 2010 13:10:50 +0200 Subject: [svn] GnuPG - r5324 - in branches/STABLE-BRANCH-2-0: agent common scd Message-ID: Author: wk Date: 2010-05-03 13:10:49 +0200 (Mon, 03 May 2010) New Revision: 5324 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/call-scd.c branches/STABLE-BRANCH-2-0/agent/gpg-agent.c branches/STABLE-BRANCH-2-0/common/ChangeLog branches/STABLE-BRANCH-2-0/common/asshelp.c branches/STABLE-BRANCH-2-0/scd/ChangeLog branches/STABLE-BRANCH-2-0/scd/apdu.c branches/STABLE-BRANCH-2-0/scd/apdu.h branches/STABLE-BRANCH-2-0/scd/command.c branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c Log: Collected changes Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324) @@ -1,3 +1,12 @@ +2010-05-03 Werner Koch + + * gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME + too early. + +2010-03-17 Werner Koch + + * call-scd.c (unlock_scd): Send a BYE under certain conditions. + 2010-02-19 Werner Koch * call-pinentry.c (start_pinentry): Remove a translation prefix. Modified: branches/STABLE-BRANCH-2-0/common/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324) @@ -1,3 +1,8 @@ +2010-03-17 Werner Koch + + * asshelp.c (start_new_gpg_agent) [W32]: Use a named mutex to + avoid starting two agents. + 2010-03-12 Werner Koch * status.h (STATUS_ENTER): New. Modified: branches/STABLE-BRANCH-2-0/scd/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/scd/ChangeLog 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/scd/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324) @@ -1,3 +1,14 @@ +2010-03-17 Werner Koch + + * command.c (open_card): Return GPG_ERR_NOT_OPERATIONAL if no + card services are available. + (get_reader_slot): Detect no services status. + (cmd_serialno): No reset if there are no services. + (scd_command_handler): Stop scdaemon in that case. + * apdu.c (pcsc_no_service): New. + (open_pcsc_reader_direct): Set it. + (apdu_open_reader): Add arg R_NO_SERVICE. + 2010-02-11 Marcus Brinkmann From trunk 2009-09-23, 2009-10-16, 2009-11-02, 2009-11-04, 2009-11-05, Modified: branches/STABLE-BRANCH-2-0/agent/call-scd.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/call-scd.c 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/agent/call-scd.c 2010-05-03 11:10:49 UTC (rev 5324) @@ -176,6 +176,17 @@ static int unlock_scd (ctrl_t ctrl, int rc) { + if (gpg_err_code (rc) == GPG_ERR_NOT_OPERATIONAL + && gpg_err_source (rc) == GPG_ERR_SOURCE_SCD) + { + /* If the SCdaemon returned this error, it detected a major + problem, like no reader connected. To finish this we need to + stop the connection. This simulates an explicit killing of + the SCdaemon. */ + assuan_transact (primary_scd_ctx, "BYE", + NULL, NULL, NULL, NULL, NULL, NULL); + } + if (ctrl->scd_local->locked != 1) { log_error ("unlock_scd: invalid lock count (%d)\n", Modified: branches/STABLE-BRANCH-2-0/agent/gpg-agent.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-03 11:10:49 UTC (rev 5324) @@ -2101,7 +2101,6 @@ check_own_socket_running++; rc = assuan_new (&ctx); - xfree (sockname); if (rc) { log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); @@ -2137,6 +2136,7 @@ xfree (buffer); leave: + xfree (sockname); if (ctx) assuan_release (ctx); if (rc) Modified: branches/STABLE-BRANCH-2-0/common/asshelp.c =================================================================== --- branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-05-03 11:10:49 UTC (rev 5324) @@ -231,25 +231,68 @@ and thus there is no need for the GPG_AGENT_INFO envvar. This is possible as we don't have a real unix domain socket but use a plain file and thus there is no - need to care about non-local file systems. */ + need to care about non-local file systems. We use a + named mutex to interlock the spawning. There is just + one problem with that: If gpg-agent needs more than 3 + seconds to come up and listen on the socket we might + still spawn another agent. However this is no serious + problem because an agent detects this and handles it. + Thus the mutex merely helps to save resources in the + most common cases. */ const char *argv[3]; + HANDLE mutex; + int waitrc; argv[0] = "--daemon"; argv[1] = "--use-standard-socket"; argv[2] = NULL; - rc = gnupg_spawn_process_detached (agent_program, argv, NULL); - if (rc) - log_debug ("failed to start agent `%s': %s\n", - agent_program, gpg_strerror (rc)); + mutex = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel"); + if (!mutex) + { + log_error ("failed to create the spawn_agent mutex: %s\n", + w32_strerror (-1)); + rc = gpg_error (GPG_ERR_GENERAL); + } + else if ((waitrc = WaitForSingleObject (mutex, 5000)) + == WAIT_OBJECT_0) + { + rc = assuan_socket_connect (&ctx, sockname, 0); + if (rc) + { + /* Still not available. */ + rc = gnupg_spawn_process_detached (agent_program, + argv, NULL); + if (rc) + log_debug ("failed to start agent `%s': %s\n", + agent_program, gpg_strerror (rc)); + else + { + /* Give the agent some time to prepare itself. */ + gnupg_sleep (3); + /* Now try again to connect the agent. */ + rc = assuan_socket_connect (&ctx, sockname, 0); + } + } + if (!ReleaseMutex (mutex)) + log_error ("failed to release the spawn_agent mutex: %s\n", + w32_strerror (-1)); + } + else if (waitrc == WAIT_TIMEOUT) + { + log_info ("error waiting for the spawn_agent mutex: timeout\n"); + rc = gpg_error (GPG_ERR_GENERAL); + } else { - /* Give the agent some time to prepare itself. */ - gnupg_sleep (3); - /* Now try again to connect the agent. */ - rc = assuan_socket_connect (ctx, sockname, 0, 0); + log_debug ("error waiting for the spawn_agent mutex: " + "(code=%d) %s\n", waitrc, w32_strerror (-1)); + rc = gpg_error (GPG_ERR_GENERAL); } - } + + if (mutex) + CloseHandle (mutex); + } #else /*!HAVE_W32_SYSTEM*/ { const char *pgmname; Modified: branches/STABLE-BRANCH-2-0/scd/apdu.c =================================================================== --- branches/STABLE-BRANCH-2-0/scd/apdu.c 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/scd/apdu.c 2010-05-03 11:10:49 UTC (rev 5324) @@ -287,7 +287,10 @@ long (* DLSTDCALL pcsc_set_timeout) (unsigned long context, unsigned long timeout); +/* Flag set if PC/SC returned the no-service error. */ +static int pcsc_no_service; + /* Prototypes. */ static int pcsc_get_status (int slot, unsigned int *status); static int reset_pcsc_reader (int slot); @@ -1487,8 +1490,11 @@ log_error ("pcsc_establish_context failed: %s (0x%lx)\n", pcsc_error_string (err), err); reader_table[slot].used = 0; + if (err == 0x8010001d) + pcsc_no_service = 1; return -1; } + pcsc_no_service = 0; err = pcsc_list_readers (reader_table[slot].pcsc.context, NULL, NULL, &nreader); @@ -2321,14 +2327,18 @@ error. If PORTSTR is NULL we default to a suitable port (for ctAPI: the first USB reader. For PC/SC the first listed reader). */ int -apdu_open_reader (const char *portstr) +apdu_open_reader (const char *portstr, int *r_no_service) { static int pcsc_api_loaded, ct_api_loaded; + int slot; + if (r_no_service) + *r_no_service = 0; + #ifdef HAVE_LIBUSB if (!opt.disable_ccid) { - int slot, i; + int i; const char *s; slot = open_ccid_reader (portstr); @@ -2458,7 +2468,11 @@ pcsc_api_loaded = 1; } - return open_pcsc_reader (portstr); + slot = open_pcsc_reader (portstr); + if (slot == -1 && r_no_service && pcsc_no_service) + *r_no_service = 1; + + return slot; } Modified: branches/STABLE-BRANCH-2-0/scd/apdu.h =================================================================== --- branches/STABLE-BRANCH-2-0/scd/apdu.h 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/scd/apdu.h 2010-05-03 11:10:49 UTC (rev 5324) @@ -80,8 +80,8 @@ #define APDU_CARD_ACTIVE (4) /* Card is active. */ -/* Note , that apdu_open_reader returns no status word but -1 on error. */ -int apdu_open_reader (const char *portstr); +/* Note, that apdu_open_reader returns no status word but -1 on error. */ +int apdu_open_reader (const char *portstr, int *r_no_service); int apdu_open_remote_reader (const char *portstr, const unsigned char *cookie, size_t length, int (*readfnc) (void *opaque, Modified: branches/STABLE-BRANCH-2-0/scd/command.c =================================================================== --- branches/STABLE-BRANCH-2-0/scd/command.c 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/scd/command.c 2010-05-03 11:10:49 UTC (rev 5324) @@ -70,6 +70,10 @@ && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot) +/* Flag indicating that the reader has been disabled. */ +static int reader_disabled; + + /* This structure is used to keep track of open readers (slots). */ struct slot_status_s { @@ -394,7 +398,15 @@ /* Try to open the reader. */ if (ss->slot == -1) - ss->slot = apdu_open_reader (opt.reader_port); + { + int no_service_flag; + ss->slot = apdu_open_reader (opt.reader_port, &no_service_flag); + if (no_service_flag) + { + log_info ("no card services - disabling scdaemon\n"); + reader_disabled = 1; + } + } /* Return the slot_table index. */ return 0; @@ -409,6 +421,9 @@ gpg_error_t err; int slot; + if (reader_disabled) + return gpg_error (GPG_ERR_NOT_OPERATIONAL); + /* If we ever got a card not present error code, return that. Only the SERIALNO command and a reset are able to clear from that state. */ @@ -441,7 +456,7 @@ slot = get_reader_slot (); ctrl->reader_slot = slot; if (slot == -1) - err = gpg_error (GPG_ERR_CARD); + err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD); else { /* Fixme: We should move the apdu_connect call to @@ -495,7 +510,7 @@ time_t stamp; /* Clear the remove flag so that the open_card is able to reread it. */ - if (ctrl->server_local->card_removed) + if (!reader_disabled && ctrl->server_local->card_removed) { if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); @@ -1995,7 +2010,7 @@ BUG (); sl->next_session = ctrl->server_local->next_session; } - stopme = ctrl->server_local->stopme; + stopme = ctrl->server_local->stopme || reader_disabled; xfree (ctrl->server_local); ctrl->server_local = NULL; Modified: branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c =================================================================== --- branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c 2010-04-27 14:11:41 UTC (rev 5323) +++ branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c 2010-05-03 11:10:49 UTC (rev 5324) @@ -139,7 +139,7 @@ if (argc != 1) usage (1); - slot = apdu_open_reader (reader_port); + slot = apdu_open_reader (reader_port, NULL); if (slot == -1) exit (1); if (apdu_connect (slot)) From cvs at cvs.gnupg.org Mon May 3 17:23:10 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 03 May 2010 17:23:10 +0200 Subject: [svn] GnuPG - r5325 - in trunk: . agent common doc Message-ID: Author: wk Date: 2010-05-03 17:23:10 +0200 (Mon, 03 May 2010) New Revision: 5325 Modified: trunk/ChangeLog trunk/agent/ChangeLog trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/asshelp.c trunk/common/exechelp-posix.c trunk/configure.ac trunk/doc/gpg-agent.texi Log: auto start the agent if --use-standard-socket is in use. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325) @@ -1,3 +1,8 @@ +2010-04-30 Werner Koch + + * configure.ac: Add option --enable-standard-socket. + (USE_STANDARD_SOCKET): ac_define it. + 2010-04-14 Werner Koch * Makefile.am (keyserver) [W32CE]: Do not build for now. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/agent/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325) @@ -1,3 +1,12 @@ +2010-05-03 Werner Koch + + * gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME + too early. + +2010-04-30 Werner Koch + + * gpg-agent.c (main): Add command --use-standard-socket-p. + 2010-04-26 Werner Koch * gpg-agent.c (create_server_socket) [W32]: Also check for EEXIST. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/common/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325) @@ -1,3 +1,13 @@ +2010-05-03 Werner Koch + + * asshelp.c (lock_agent_spawning, unlock_agent_spawning): New. + (start_new_gpg_agent): Test for configured standard socket and + try to fire up the agent in this case. + + * exechelp-posix.c (gnupg_wait_process): Do not log a message if + EXITCODE is given. + (gnupg_spawn_process_detached): Do not reuse PID for the second fork. + 2010-04-26 Werner Koch * utf8conv.c (load_libiconv) [W32CE]: No libiconv warning Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/agent/gpg-agent.c 2010-05-03 15:23:10 UTC (rev 5325) @@ -62,6 +62,7 @@ oNoVerbose = 500, aGPGConfList, aGPGConfTest, + aUseStandardSocketP, oOptions, oDebug, oDebugAll, @@ -98,6 +99,7 @@ oEnablePassphraseHistory, oUseStandardSocket, oNoUseStandardSocket, + oStandardSocketP, oFakedSystemTime, oIgnoreCacheForSigning, @@ -116,6 +118,7 @@ { aGPGConfList, "gpgconf-list", 256, "@" }, { aGPGConfTest, "gpgconf-test", 256, "@" }, + { aUseStandardSocketP, "use-standard-socket-p", 256, "@" }, { 301, NULL, 0, N_("@Options:\n ") }, @@ -748,6 +751,7 @@ { case aGPGConfList: gpgconf_list = 1; break; case aGPGConfTest: gpgconf_list = 2; break; + case aUseStandardSocketP: gpgconf_list = 3; break; case oBatch: opt.batch=1; break; case oDebugWait: debug_wait = pargs.r.ret_int; break; @@ -858,9 +862,11 @@ log_debug ("... okay\n"); } - if (gpgconf_list == 2) + if (gpgconf_list == 3) + agent_exit (!use_standard_socket); + else if (gpgconf_list == 2) agent_exit (0); - if (gpgconf_list) + else if (gpgconf_list) { char *filename; char *filename_esc; @@ -2097,7 +2103,6 @@ check_own_socket_running++; rc = assuan_new (&ctx); - xfree (sockname); if (rc) { log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); @@ -2133,6 +2138,7 @@ xfree (buffer); leave: + xfree (sockname); if (ctx) assuan_release (ctx); if (rc) @@ -2153,7 +2159,7 @@ /* Check whether we are still listening on our own socket. In case another gpg-agent process started after us has taken ownership of - our socket, we woul linger around without any real taks. Thus we + our socket, we woulf linger around without any real task. Thus we better check once in a while whether we are really needed. */ static void check_own_socket (void) Modified: trunk/common/asshelp.c =================================================================== --- trunk/common/asshelp.c 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/common/asshelp.c 2010-05-03 15:23:10 UTC (rev 5325) @@ -1,5 +1,5 @@ /* asshelp.c - Helper functions for Assuan - * Copyright (C) 2002, 2004, 2007, 2009 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2007, 2009, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -35,7 +35,14 @@ #include "status.h" #include "asshelp.h" +/* The type we use for lock_agent_spawning. */ +#ifdef HAVE_W32_SYSTEM +# define lock_agent_t HANDLE +#else +# define lock_agent_t dotlock_t +#endif + /* A bitfield that specifies the assuan categories to log. This is identical to the default log handler of libassuan. We need to do it ourselves because we use a custom log handler and want to use @@ -209,6 +216,77 @@ } +/* Lock the agent spawning process. The caller needs to provide the + address of a variable to store the lock information. */ +static gpg_error_t +lock_agent_spawning (lock_agent_t *lock, const char *homedir) +{ +#ifdef HAVE_W32_SYSTEM + int waitrc; + + (void)homedir; /* Not required. */ + + *lock = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel"); + if (!*lock) + { + log_error ("failed to create the spawn_agent mutex: %s\n", + w32_strerror (-1)); + return gpg_error (GPG_ERR_GENERAL); + } + + waitrc = WaitForSingleObject (*lock, 5000); + if (waitrc == WAIT_OBJECT_0) + return 0; + + if (waitrc == WAIT_TIMEOUT) + log_info ("error waiting for the spawn_agent mutex: timeout\n"); + else + log_info ("error waiting for the spawn_agent mutex: " + "(code=%d) %s\n", waitrc, w32_strerror (-1)); + return gpg_error (GPG_ERR_GENERAL); +#else /*!HAVE_W32_SYSTEM*/ + char *fname; + + *lock = NULL; + + fname = make_filename (homedir, "gnupg_spawn_agent_sentinel", NULL); + if (!fname) + return gpg_error_from_syserror (); + + *lock = create_dotlock (fname); + xfree (fname); + if (!*lock) + return gpg_error_from_syserror (); + + /* FIXME: We should use a timeout of 5000 here - however + make_dotlock does not yet support values other than -1 and 0. */ + if (make_dotlock (*lock, -1)) + return gpg_error_from_syserror (); + + return 0; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Unlock the spawning process. */ +static void +unlock_agent_spawning (lock_agent_t *lock) +{ + if (*lock) + { +#ifdef HAVE_W32_SYSTEM + if (!ReleaseMutex (*lock)) + log_error ("failed to release the spawn_agent mutex: %s\n", + w32_strerror (-1)); + CloseHandle (*lock); +#else /*!HAVE_W32_SYSTEM*/ + destroy_dotlock (*lock); +#endif /*!HAVE_W32_SYSTEM*/ + *lock = NULL; + } +} + + /* Try to connect to the agent via socket or fork it off and work by pipes. Handle the server's initial greeting. Returns a new assuan context at R_CTX or an error code. */ @@ -228,17 +306,17 @@ of the pipe based server for the lifetime of the process. */ static int force_pipe_server = 0; - gpg_error_t rc = 0; + gpg_error_t err = 0; char *infostr, *p; assuan_context_t ctx; *r_ctx = NULL; - rc = assuan_new (&ctx); - if (rc) + err = assuan_new (&ctx); + if (err) { - log_error ("error allocating assuan context: %s\n", gpg_strerror (rc)); - return rc; + log_error ("error allocating assuan context: %s\n", gpg_strerror (err)); + return err; } restart: @@ -246,13 +324,16 @@ if (!infostr || !*infostr) { char *sockname; + const char *argv[3]; + pid_t pid; + int excode; /* First check whether we can connect at the standard socket. */ sockname = make_filename (homedir, "S.gpg-agent", NULL); - rc = assuan_socket_connect (ctx, sockname, 0, 0); + err = assuan_socket_connect (ctx, sockname, 0, 0); - if (rc) + if (err) { /* With no success start a new server. */ if (verbose) @@ -275,59 +356,86 @@ if (!agent_program || !*agent_program) agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); -#ifdef HAVE_W32_SYSTEM - { - /* Under Windows we start the server in daemon mode. This - is because the default is to use the standard socket - and thus there is no need for the GPG_AGENT_INFO - envvar. This is possible as we don't have a real unix - domain socket but use a plain file and thus there is no - need to care about non-local file systems. */ - const char *argv[3]; + argv[0] = "--use-standard-socket-p"; + argv[1] = NULL; + err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid); + if (err) + log_debug ("starting `%s' for testing failed: %s\n", + agent_program, gpg_strerror (err)); + else if ((err = gnupg_wait_process (agent_program, pid, &excode))) + { + if (excode == -1) + log_debug ("running `%s' for testing failed: %s\n", + agent_program, gpg_strerror (err)); + } - argv[0] = "--daemon"; - argv[1] = "--use-standard-socket"; - argv[2] = NULL; + if (!err && !excode) + { + /* If the agent has been configured for use with a + standard socket, an environment variable is not + required and thus we we can savely start the agent + here. */ + lock_agent_t lock; - rc = gnupg_spawn_process_detached (agent_program, argv, NULL); - if (rc) - log_debug ("failed to start agent `%s': %s\n", - agent_program, gpg_strerror (rc)); - else - { - /* Give the agent some time to prepare itself. */ - gnupg_sleep (3); - /* Now try again to connect the agent. */ - rc = assuan_socket_connect (ctx, sockname, 0, 0); - } - } -#else /*!HAVE_W32_SYSTEM*/ - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; + argv[0] = "--daemon"; + argv[1] = "--use-standard-socket"; + argv[2] = NULL; - if ( !(pgmname = strrchr (agent_program, '/'))) - pgmname = agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); - no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); - no_close_list[i] = -1; - - /* Connect to the agent and perform initial handshaking. */ - rc = assuan_pipe_connect (ctx, agent_program, argv, - no_close_list, NULL, NULL, 0); - } -#endif /*!HAVE_W32_SYSTEM*/ + if (!(err = lock_agent_spawning (&lock, homedir)) + && assuan_socket_connect (ctx, sockname, 0, 0)) + { + err = gnupg_spawn_process_detached (agent_program, argv,NULL); + if (err) + log_error ("failed to start agent `%s': %s\n", + agent_program, gpg_strerror (err)); + else + { + int i; + + if (verbose) + log_info (_("waiting %d seconds for the agent " + "to come up\n"), 5); + for (i=0; i < 5; i++) + { + gnupg_sleep (1); + err = assuan_socket_connect (ctx, sockname, 0, 0); + if (!err) + break; + } + } + } + + unlock_agent_spawning (&lock); + } + else + { + /* If using the standard socket is not the default we + start the agent as a pipe server which gives us most + of the required features except for passphrase + caching etc. */ + const char *pgmname; + int no_close_list[3]; + int i; + + if ( !(pgmname = strrchr (agent_program, '/'))) + pgmname = agent_program; + else + pgmname++; + + argv[0] = pgmname; + argv[1] = "--server"; + argv[2] = NULL; + + i=0; + if (log_get_fd () != -1) + no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); + no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); + no_close_list[i] = -1; + + /* Connect to the agent and perform initial handshaking. */ + err = assuan_pipe_connect (ctx, agent_program, argv, + no_close_list, NULL, NULL, 0); + } } xfree (sockname); } @@ -358,9 +466,9 @@ goto restart; } - rc = assuan_socket_connect (ctx, infostr, pid, 0); + err = assuan_socket_connect (ctx, infostr, pid, 0); xfree (infostr); - if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED) + if (gpg_err_code (err) == GPG_ERR_ASS_CONNECT_FAILED) { log_info (_("can't connect to the agent - trying fall back\n")); force_pipe_server = 1; @@ -368,9 +476,9 @@ } } - if (rc) + if (err) { - log_error ("can't connect to the agent: %s\n", gpg_strerror (rc)); + log_error ("can't connect to the agent: %s\n", gpg_strerror (err)); assuan_release (ctx); return gpg_error (GPG_ERR_NO_AGENT); } @@ -378,16 +486,16 @@ if (debug) log_debug ("connection to agent established\n"); - rc = assuan_transact (ctx, "RESET", + err = assuan_transact (ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (!rc) - rc = send_pinentry_environment (ctx, errsource, + if (!err) + err = send_pinentry_environment (ctx, errsource, opt_lc_ctype, opt_lc_messages, session_env); - if (rc) + if (err) { assuan_release (ctx); - return rc; + return err; } *r_ctx = ctx; Modified: trunk/common/exechelp-posix.c =================================================================== --- trunk/common/exechelp-posix.c 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/common/exechelp-posix.c 2010-05-03 15:23:10 UTC (rev 5325) @@ -410,7 +410,8 @@ diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL for any failures of the spawned program or other error codes. If EXITCODE is not NULL the exit code of the process is stored at this - address or -1 if it could not be retrieved. */ + address or -1 if it could not be retrieved and no error message is + logged. */ gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode) { @@ -443,9 +444,10 @@ } else if (WIFEXITED (status) && WEXITSTATUS (status)) { - log_error (_("error running `%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); - if (exitcode) + if (!exitcode) + log_error (_("error running `%s': exit status %d\n"), pgmname, + WEXITSTATUS (status)); + else *exitcode = WEXITSTATUS (status); ec = GPG_ERR_GENERAL; } @@ -497,13 +499,16 @@ } if (!pid) { + pid_t pid2; + gcry_control (GCRYCTL_TERM_SECMEM); if (setsid() == -1 || chdir ("/")) _exit (1); - pid = fork (); /* Double fork to let init takes over the new child. */ - if (pid == (pid_t)(-1)) + + pid2 = fork (); /* Double fork to let init take over the new child. */ + if (pid2 == (pid_t)(-1)) _exit (1); - if (pid) + if (pid2) _exit (0); /* Let the parent exit immediately. */ if (envp) Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/configure.ac 2010-05-03 15:23:10 UTC (rev 5325) @@ -79,6 +79,7 @@ use_exec=yes disable_keyserver_path=no use_ccid_driver=yes +use_standard_socket=no GNUPG_BUILD_PROGRAM(gpg, yes) GNUPG_BUILD_PROGRAM(gpgsm, yes) @@ -266,17 +267,17 @@ [enable email keyserver interface only]), try_mailto=$enableval, try_mailto=no) AC_MSG_RESULT($try_mailto) - fi + fi - AC_MSG_CHECKING([whether keyserver exec-path is enabled]) - AC_ARG_ENABLE(keyserver-path, + AC_MSG_CHECKING([whether keyserver exec-path is enabled]) + AC_ARG_ENABLE(keyserver-path, AC_HELP_STRING([--disable-keyserver-path], [disable the exec-path option for keyserver helpers]), [if test "$enableval" = no ; then disable_keyserver_path=yes fi],enableval=yes) - AC_MSG_RESULT($enableval) - fi + AC_MSG_RESULT($enableval) +fi # @@ -625,6 +626,30 @@ [Defined to disable exec-path for keyserver helpers]) fi +# +# Allows enabling the use of a standard socket by default This is +# gpg-agent's option --[no-]use-standard-socket. For Windows we force +# the use of this. +# +AC_MSG_CHECKING([whether to use a standard socket by default]) +AC_ARG_ENABLE(standard-socket, + AC_HELP_STRING([--enable-standard-socket], + [use a standard socket for the agent by default]), + use_standard_socket=$enableval) +tmp="" +if test "$use_standard_socket" != yes; then + if test "$have_w32_system" = yes; then + use_standard_socket=yes + tmp=" (forced)" + fi +fi +AC_MSG_RESULT($use_standard_socket$tmp) +if test "$use_standard_socket" = yes; then + AC_DEFINE(USE_STANDARD_SOCKET,1, + [Use the standard socket for the agent by default]) +fi + + # (These need to go after AC_PROG_CC so that $EXEEXT is defined) AC_DEFINE_UNQUOTED(EXEEXT,"$EXEEXT",[The executable file extension, if any]) Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2010-05-03 11:10:49 UTC (rev 5324) +++ trunk/doc/gpg-agent.texi 2010-05-03 15:23:10 UTC (rev 5325) @@ -435,9 +435,12 @@ environment variable @var{GPG_AGENT_INFO} and then fall back to this socket. This option may not be used if the home directory is mounted as a remote file system. Note, that @option{--use-standard-socket} is the -default on Windows systems. +default on Windows systems. The default may be changed at build time. +It is possible to test at runtime whether the agent has been configured +for use with the standard socket by issuing the command + at command{gpg-agent --use-standard-socket-p} which returns success if the +standard socket option has been enabled. - @item --display @var{string} @itemx --ttyname @var{string} @itemx --ttytype @var{string} From cvs at cvs.gnupg.org Tue May 4 11:56:43 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 04 May 2010 11:56:43 +0200 Subject: [svn] GnuPG - r5326 - in branches/STABLE-BRANCH-2-0: . agent common doc Message-ID: Author: wk Date: 2010-05-04 11:56:42 +0200 (Tue, 04 May 2010) New Revision: 5326 Modified: branches/STABLE-BRANCH-2-0/ChangeLog branches/STABLE-BRANCH-2-0/NEWS branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/gpg-agent.c branches/STABLE-BRANCH-2-0/common/ChangeLog branches/STABLE-BRANCH-2-0/common/asshelp.c branches/STABLE-BRANCH-2-0/common/exechelp.c branches/STABLE-BRANCH-2-0/configure.ac branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi Log: Start the agent on demand if option --enable-standard socket has been enabled. Modified: branches/STABLE-BRANCH-2-0/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/ChangeLog 2010-05-04 09:56:42 UTC (rev 5326) @@ -1,3 +1,7 @@ +2010-05-04 Werner Koch + + * configure.ac: Add option --enable-standard-socket. + 2010-03-09 Werner Koch Release 2.0.15. Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-04 09:56:42 UTC (rev 5326) @@ -1,3 +1,7 @@ +2010-05-04 Werner Koch + + * gpg-agent.c (main): Add command --use-standard-socket-p. + 2010-05-03 Werner Koch * gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME Modified: branches/STABLE-BRANCH-2-0/common/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-05-04 09:56:42 UTC (rev 5326) @@ -1,3 +1,13 @@ +2010-05-03 Werner Koch + + * asshelp.c (lock_agent_spawning, unlock_agent_spawning): New. + (start_new_gpg_agent): Test for configured standard socket and + try to fire up the agent in this case. + + * exechelp.c (gnupg_spawn_process_detached): Do not reuse PID for + the second fork. + (gnupg_wait_process): Do not log a message if EXITCODE is given. + 2010-03-17 Werner Koch * asshelp.c (start_new_gpg_agent) [W32]: Use a named mutex to Modified: branches/STABLE-BRANCH-2-0/NEWS =================================================================== --- branches/STABLE-BRANCH-2-0/NEWS 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/NEWS 2010-05-04 09:56:42 UTC (rev 5326) @@ -1,7 +1,15 @@ Noteworthy changes in version 2.0.16 (unreleased) ------------------------------------------------- + * If the agent's --use-standard-socket option is active, all tools + try to start and daemonize the agent on the fly. In the past this + was only supported on W32; on non-W32 systems the new configure + option --use-standard-socket may now be used to use this feature by + default. + * Minor bug fixes. + + Noteworthy changes in version 2.0.15 (2010-03-09) ------------------------------------------------- Modified: branches/STABLE-BRANCH-2-0/agent/gpg-agent.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-04 09:56:42 UTC (rev 5326) @@ -1,6 +1,6 @@ /* gpg-agent.c - The GnuPG Agent * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2007, 2009 Free Software Foundation, Inc. + * 2006, 2007, 2009, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -60,6 +60,7 @@ oNoVerbose = 500, aGPGConfList, aGPGConfTest, + aUseStandardSocketP, oOptions, oDebug, oDebugAll, @@ -114,6 +115,7 @@ { aGPGConfList, "gpgconf-list", 256, "@" }, { aGPGConfTest, "gpgconf-test", 256, "@" }, + { aUseStandardSocketP, "use-standard-socket-p", 256, "@" }, { 301, NULL, 0, N_("@Options:\n ") }, @@ -628,7 +630,7 @@ /* Set default options. */ parse_rereadable_options (NULL, 0); /* Reset them to default values. */ -#ifdef HAVE_W32_SYSTEM +#ifdef USE_STANDARD_SOCKET use_standard_socket = 1; /* Under Windows we always use a standard socket. */ #endif @@ -748,6 +750,7 @@ { case aGPGConfList: gpgconf_list = 1; break; case aGPGConfTest: gpgconf_list = 2; break; + case aUseStandardSocketP: gpgconf_list = 3; break; case oBatch: opt.batch=1; break; case oDebugWait: debug_wait = pargs.r.ret_int; break; @@ -858,6 +861,8 @@ log_debug ("... okay\n"); } + if (gpgconf_list == 3) + agent_exit (!use_standard_socket); if (gpgconf_list == 2) agent_exit (0); if (gpgconf_list) Modified: branches/STABLE-BRANCH-2-0/common/asshelp.c =================================================================== --- branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-05-04 09:56:42 UTC (rev 5326) @@ -1,5 +1,5 @@ /* asshelp.c - Helper functions for Assuan - * Copyright (C) 2002, 2004, 2007, 2009 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2007, 2009, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -27,6 +27,7 @@ #include #endif +#define JNLIB_NEED_LOG_LOGV #include "i18n.h" #include "util.h" #include "exechelp.h" @@ -34,6 +35,14 @@ #include "status.h" #include "asshelp.h" +/* The type we use for lock_agent_spawning. */ +#ifdef HAVE_W32_SYSTEM +# define lock_agent_t HANDLE +#else +# define lock_agent_t DOTLOCK +#endif + + static gpg_error_t send_one_option (assuan_context_t ctx, gpg_err_source_t errsource, const char *name, const char *value, int use_putenv) @@ -70,7 +79,9 @@ { gpg_error_t err = 0; +#if defined(HAVE_SETLOCALE) char *old_lc = NULL; +#endif char *dft_lc = NULL; const char *dft_ttyname; int iterator; @@ -158,6 +169,77 @@ } +/* Lock the agent spawning process. The caller needs to provide the + address of a variable to store the lock information. */ +static gpg_error_t +lock_agent_spawning (lock_agent_t *lock, const char *homedir) +{ +#ifdef HAVE_W32_SYSTEM + int waitrc; + + (void)homedir; /* Not required. */ + + *lock = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel"); + if (!*lock) + { + log_error ("failed to create the spawn_agent mutex: %s\n", + w32_strerror (-1)); + return gpg_error (GPG_ERR_GENERAL); + } + + waitrc = WaitForSingleObject (*lock, 5000); + if (waitrc == WAIT_OBJECT_0) + return 0; + + if (waitrc == WAIT_TIMEOUT) + log_info ("error waiting for the spawn_agent mutex: timeout\n"); + else + log_info ("error waiting for the spawn_agent mutex: " + "(code=%d) %s\n", waitrc, w32_strerror (-1)); + return gpg_error (GPG_ERR_GENERAL); +#else /*!HAVE_W32_SYSTEM*/ + char *fname; + + *lock = NULL; + + fname = make_filename (homedir, "gnupg_spawn_agent_sentinel", NULL); + if (!fname) + return gpg_error_from_syserror (); + + *lock = create_dotlock (fname); + xfree (fname); + if (!*lock) + return gpg_error_from_syserror (); + + /* FIXME: We should use a timeout of 5000 here - however + make_dotlock does not yet support values other than -1 and 0. */ + if (make_dotlock (*lock, -1)) + return gpg_error_from_syserror (); + + return 0; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Unlock the spawning process. */ +static void +unlock_agent_spawning (lock_agent_t *lock) +{ + if (*lock) + { +#ifdef HAVE_W32_SYSTEM + if (!ReleaseMutex (*lock)) + log_error ("failed to release the spawn_agent mutex: %s\n", + w32_strerror (-1)); + CloseHandle (*lock); +#else /*!HAVE_W32_SYSTEM*/ + destroy_dotlock (*lock); +#endif /*!HAVE_W32_SYSTEM*/ + *lock = NULL; + } +} + + /* Try to connect to the agent via socket or fork it off and work by pipes. Handle the server's initial greeting. Returns a new assuan context at R_CTX or an error code. */ @@ -177,17 +259,17 @@ of the pipe based server for the lifetime of the process. */ static int force_pipe_server = 0; - gpg_error_t rc = 0; + gpg_error_t err = 0; char *infostr, *p; assuan_context_t ctx; *r_ctx = NULL; - rc = assuan_new (&ctx); - if (rc) + err = assuan_new (&ctx); + if (err) { - log_error ("error allocating assuan context: %s\n", gpg_strerror (rc)); - return rc; + log_error ("error allocating assuan context: %s\n", gpg_strerror (err)); + return err; } restart: @@ -195,13 +277,16 @@ if (!infostr || !*infostr) { char *sockname; + const char *argv[3]; + pid_t pid; + int excode; /* First check whether we can connect at the standard socket. */ sockname = make_filename (homedir, "S.gpg-agent", NULL); - rc = assuan_socket_connect (ctx, sockname, 0, 0); + err = assuan_socket_connect (ctx, sockname, 0, 0); - if (rc) + if (err) { /* With no success start a new server. */ if (verbose) @@ -224,102 +309,86 @@ if (!agent_program || !*agent_program) agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); -#ifdef HAVE_W32_SYSTEM - { - /* Under Windows we start the server in daemon mode. This - is because the default is to use the standard socket - and thus there is no need for the GPG_AGENT_INFO - envvar. This is possible as we don't have a real unix - domain socket but use a plain file and thus there is no - need to care about non-local file systems. We use a - named mutex to interlock the spawning. There is just - one problem with that: If gpg-agent needs more than 3 - seconds to come up and listen on the socket we might - still spawn another agent. However this is no serious - problem because an agent detects this and handles it. - Thus the mutex merely helps to save resources in the - most common cases. */ - const char *argv[3]; - HANDLE mutex; - int waitrc; + argv[0] = "--use-standard-socket-p"; + argv[1] = NULL; + err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid); + if (err) + log_debug ("starting `%s' for testing failed: %s\n", + agent_program, gpg_strerror (err)); + else if ((err = gnupg_wait_process (agent_program, pid, &excode))) + { + if (excode == -1) + log_debug ("running `%s' for testing failed: %s\n", + agent_program, gpg_strerror (err)); + } - argv[0] = "--daemon"; - argv[1] = "--use-standard-socket"; - argv[2] = NULL; + if (!err && !excode) + { + /* If the agent has been configured for use with a + standard socket, an environment variable is not + required and thus we we can savely start the agent + here. */ + lock_agent_t lock; - mutex = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel"); - if (!mutex) - { - log_error ("failed to create the spawn_agent mutex: %s\n", - w32_strerror (-1)); - rc = gpg_error (GPG_ERR_GENERAL); - } - else if ((waitrc = WaitForSingleObject (mutex, 5000)) - == WAIT_OBJECT_0) - { - rc = assuan_socket_connect (&ctx, sockname, 0); - if (rc) - { - /* Still not available. */ - rc = gnupg_spawn_process_detached (agent_program, - argv, NULL); - if (rc) - log_debug ("failed to start agent `%s': %s\n", - agent_program, gpg_strerror (rc)); - else - { - /* Give the agent some time to prepare itself. */ - gnupg_sleep (3); - /* Now try again to connect the agent. */ - rc = assuan_socket_connect (&ctx, sockname, 0); - } - } - if (!ReleaseMutex (mutex)) - log_error ("failed to release the spawn_agent mutex: %s\n", - w32_strerror (-1)); - } - else if (waitrc == WAIT_TIMEOUT) - { - log_info ("error waiting for the spawn_agent mutex: timeout\n"); - rc = gpg_error (GPG_ERR_GENERAL); - } - else - { - log_debug ("error waiting for the spawn_agent mutex: " - "(code=%d) %s\n", waitrc, w32_strerror (-1)); - rc = gpg_error (GPG_ERR_GENERAL); - } - - if (mutex) - CloseHandle (mutex); - } -#else /*!HAVE_W32_SYSTEM*/ - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; + argv[0] = "--daemon"; + argv[1] = "--use-standard-socket"; + argv[2] = NULL; - if ( !(pgmname = strrchr (agent_program, '/'))) - pgmname = agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); - no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); - no_close_list[i] = -1; - - /* Connect to the agent and perform initial handshaking. */ - rc = assuan_pipe_connect (ctx, agent_program, argv, - no_close_list, NULL, NULL, 0); - } -#endif /*!HAVE_W32_SYSTEM*/ + if (!(err = lock_agent_spawning (&lock, homedir)) + && assuan_socket_connect (ctx, sockname, 0, 0)) + { + err = gnupg_spawn_process_detached (agent_program, argv,NULL); + if (err) + log_error ("failed to start agent `%s': %s\n", + agent_program, gpg_strerror (err)); + else + { + int i; + + if (verbose) + log_info (_("waiting %d seconds for the agent " + "to come up\n"), 5); + for (i=0; i < 5; i++) + { + gnupg_sleep (1); + err = assuan_socket_connect (ctx, sockname, 0, 0); + if (!err) + break; + } + } + } + + unlock_agent_spawning (&lock); + } + else + { + /* If using the standard socket is not the default we + start the agent as a pipe server which gives us most + of the required features except for passphrase + caching etc. */ + const char *pgmname; + int no_close_list[3]; + int i; + + if ( !(pgmname = strrchr (agent_program, '/'))) + pgmname = agent_program; + else + pgmname++; + + argv[0] = pgmname; + argv[1] = "--server"; + argv[2] = NULL; + + i=0; + if (log_get_fd () != -1) + no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); + no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); + no_close_list[i] = -1; + + /* Connect to the agent and perform initial handshaking. */ + err = assuan_pipe_connect (ctx, agent_program, argv, + no_close_list, NULL, NULL, 0); + } } xfree (sockname); } @@ -350,9 +419,9 @@ goto restart; } - rc = assuan_socket_connect (ctx, infostr, pid, 0); + err = assuan_socket_connect (ctx, infostr, pid, 0); xfree (infostr); - if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED) + if (gpg_err_code (err) == GPG_ERR_ASS_CONNECT_FAILED) { log_info (_("can't connect to the agent - trying fall back\n")); force_pipe_server = 1; @@ -360,9 +429,9 @@ } } - if (rc) + if (err) { - log_error ("can't connect to the agent: %s\n", gpg_strerror (rc)); + log_error ("can't connect to the agent: %s\n", gpg_strerror (err)); assuan_release (ctx); return gpg_error (GPG_ERR_NO_AGENT); } @@ -370,16 +439,16 @@ if (debug) log_debug ("connection to agent established\n"); - rc = assuan_transact (ctx, "RESET", + err = assuan_transact (ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (!rc) - rc = send_pinentry_environment (ctx, errsource, + if (!err) + err = send_pinentry_environment (ctx, errsource, opt_lc_ctype, opt_lc_messages, session_env); - if (rc) + if (err) { assuan_release (ctx); - return rc; + return err; } *r_ctx = ctx; Modified: branches/STABLE-BRANCH-2-0/common/exechelp.c =================================================================== --- branches/STABLE-BRANCH-2-0/common/exechelp.c 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/common/exechelp.c 2010-05-04 09:56:42 UTC (rev 5326) @@ -872,9 +872,11 @@ } else if (WIFEXITED (status) && WEXITSTATUS (status)) { - log_error (_("error running `%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); - if (exitcode) + + if (!exitcode) + log_error (_("error running `%s': exit status %d\n"), pgmname, + WEXITSTATUS (status)); + else *exitcode = WEXITSTATUS (status); ec = GPG_ERR_GENERAL; } @@ -1002,13 +1004,15 @@ } if (!pid) { + pid_t pid2; + gcry_control (GCRYCTL_TERM_SECMEM); if (setsid() == -1 || chdir ("/")) _exit (1); - pid = fork (); /* Double fork to let init takes over the new child. */ - if (pid == (pid_t)(-1)) + pid2 = fork (); /* Double fork to let init takes over the new child. */ + if (pid2 == (pid_t)(-1)) _exit (1); - if (pid) + if (pid2) _exit (0); /* Let the parent exit immediately. */ if (envp) Modified: branches/STABLE-BRANCH-2-0/configure.ac =================================================================== --- branches/STABLE-BRANCH-2-0/configure.ac 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/configure.ac 2010-05-04 09:56:42 UTC (rev 5326) @@ -75,6 +75,7 @@ use_exec=yes disable_keyserver_path=no use_ccid_driver=yes +use_standard_socket=no GNUPG_BUILD_PROGRAM(gpg, yes) GNUPG_BUILD_PROGRAM(gpgsm, yes) @@ -251,17 +252,17 @@ [enable email keyserver interface only]), try_mailto=$enableval, try_mailto=no) AC_MSG_RESULT($try_mailto) - fi + fi - AC_MSG_CHECKING([whether keyserver exec-path is enabled]) - AC_ARG_ENABLE(keyserver-path, + AC_MSG_CHECKING([whether keyserver exec-path is enabled]) + AC_ARG_ENABLE(keyserver-path, AC_HELP_STRING([--disable-keyserver-path], - [disable the exec-path option for keyserver helpers]), - [if test "$enableval" = no ; then - disable_keyserver_path=yes - fi],enableval=yes) - AC_MSG_RESULT($enableval) - fi + [disable the exec-path option for keyserver helpers]), + [if test "$enableval" = no ; then + disable_keyserver_path=yes + fi],enableval=yes) + AC_MSG_RESULT($enableval) +fi # @@ -586,6 +587,30 @@ [Defined to disable exec-path for keyserver helpers]) fi +# +# Allows enabling the use of a standard socket by default This is +# gpg-agent's option --[no-]use-standard-socket. For Windows we force +# the use of this. +# +AC_MSG_CHECKING([whether to use a standard socket by default]) +AC_ARG_ENABLE(standard-socket, + AC_HELP_STRING([--enable-standard-socket], + [use a standard socket for the agent by default]), + use_standard_socket=$enableval) +tmp="" +if test "$use_standard_socket" != yes; then + if test "$have_w32_system" = yes; then + use_standard_socket=yes + tmp=" (forced)" + fi +fi +AC_MSG_RESULT($use_standard_socket$tmp) +if test "$use_standard_socket" = yes; then + AC_DEFINE(USE_STANDARD_SOCKET,1, + [Use a standard socket for the agent by default]) +fi + + # (These need to go after AC_PROG_CC so that $EXEEXT is defined) AC_DEFINE_UNQUOTED(EXEEXT,"$EXEEXT",[The executable file extension, if any]) Modified: branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi =================================================================== --- branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi 2010-05-03 15:23:10 UTC (rev 5325) +++ branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi 2010-05-04 09:56:42 UTC (rev 5326) @@ -435,7 +435,11 @@ environment variable @var{GPG_AGENT_INFO} and then fall back to this socket. This option may not be used if the home directory is mounted as a remote file system. Note, that @option{--use-standard-socket} is the -default on Windows systems. +default on Windows systems. The default may be changed at build time. +It is possible to test at runtime whether the agent has been configured +for use with the standard socket by issuing the command + at command{gpg-agent --use-standard-socket-p} which returns success if the +standard socket option has been enabled. @item --display @var{string} From cvs at cvs.gnupg.org Tue May 4 17:21:48 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 04 May 2010 17:21:48 +0200 Subject: [svn] GnuPG - r5327 - in trunk: . agent common Message-ID: Author: wk Date: 2010-05-04 17:21:47 +0200 (Tue, 04 May 2010) New Revision: 5327 Modified: trunk/NEWS trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/estream.c trunk/common/exechelp-w32ce.c trunk/configure.ac Log: Auto starting the agent does now work on CE. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-05-04 09:56:42 UTC (rev 5326) +++ trunk/common/ChangeLog 2010-05-04 15:21:47 UTC (rev 5327) @@ -1,3 +1,15 @@ +2010-05-04 Werner Koch + + * estream.c (_es_get_std_stream): Re-use registered standard fds. + (IS_INVALID_FD, ESTREAM_SYS_YIELD): New. + (es_func_fd_read, es_func_fd_write, es_func_fd_seek) + (es_func_fd_destroy): Implement a dummy stream. + + * exechelp-w32ce.c (build_w32_commandline): Add args FD0_ISNULL + and FD1_ISNULL. Remove arg PGMNAME. Change callers. + (gnupg_spawn_process_detached): Implement. + (gnupg_spawn_process_fd): Implement one special case for now. + 2010-05-03 Werner Koch * asshelp.c (lock_agent_spawning, unlock_agent_spawning): New. @@ -18,7 +30,7 @@ 2010-04-20 Werner Koch * estream.c (es_deinit): New. - (es_init_do): Intll atexit handler to flush all streams. + (es_init_do): Install atexit handler to flush all streams. * Makefile.am (common_sources): Add gettime.h. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-05-04 09:56:42 UTC (rev 5326) +++ trunk/NEWS 2010-05-04 15:21:47 UTC (rev 5327) @@ -23,7 +23,13 @@ * Support for Windows CE. + * If the agent's --use-standard-socket option is active, all tools + try to start and daemonize the agent on the fly. In the past this + was only supported on W32; on non-W32 systems the new configure + option --use-standard-socket may now be used to use this feature by + default. + Noteworthy changes in version 2.0.13 (2009-09-04) ------------------------------------------------- Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2010-05-04 09:56:42 UTC (rev 5326) +++ trunk/agent/gpg-agent.c 2010-05-04 15:21:47 UTC (rev 5327) @@ -99,7 +99,6 @@ oEnablePassphraseHistory, oUseStandardSocket, oNoUseStandardSocket, - oStandardSocketP, oFakedSystemTime, oIgnoreCacheForSigning, @@ -631,9 +630,8 @@ /* Set default options. */ parse_rereadable_options (NULL, 0); /* Reset them to default values. */ -#ifdef HAVE_W32_SYSTEM - use_standard_socket = 1; /* Under Windows we always use a standard - socket. */ +#ifdef USE_STANDARD_SOCKET + use_standard_socket = 1; #endif shell = getenv ("SHELL"); @@ -863,7 +861,11 @@ } if (gpgconf_list == 3) - agent_exit (!use_standard_socket); + { + if (use_standard_socket && !opt.quiet) + log_info ("configured to use the standard socket\n"); + agent_exit (!use_standard_socket); + } else if (gpgconf_list == 2) agent_exit (0); else if (gpgconf_list) Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2010-05-04 09:56:42 UTC (rev 5326) +++ trunk/common/estream.c 2010-05-04 15:21:47 UTC (rev 5327) @@ -125,7 +125,13 @@ # define _set_errno(a) do { errno = (a); } while (0) #endif +#ifdef HAVE_W32_SYSTEM +# define IS_INVALID_FD(a) ((void*)(a) == (void*)(-1)) +#else +# define IS_INVALID_FD(a) ((a) == -1) +#endif + /* Generally used types. */ typedef void *(*func_realloc_t) (void *mem, size_t size); @@ -184,9 +190,11 @@ #ifdef HAVE_PTH # define ESTREAM_SYS_READ es_pth_read # define ESTREAM_SYS_WRITE es_pth_write +# define ESTREAM_SYS_YIELD() pth_yield (NULL) #else # define ESTREAM_SYS_READ read # define ESTREAM_SYS_WRITE write +# define ESTREAM_SYS_YIELD() do { } while (0) #endif /* Misc definitions. */ @@ -777,25 +785,40 @@ { estream_cookie_fd_t file_cookie = cookie; ssize_t bytes_read; + + if (IS_INVALID_FD (file_cookie->fd)) + { + ESTREAM_SYS_YIELD (); + bytes_read = 0; + } + else + { + do + bytes_read = ESTREAM_SYS_READ (file_cookie->fd, buffer, size); + while (bytes_read == -1 && errno == EINTR); + } - do - bytes_read = ESTREAM_SYS_READ (file_cookie->fd, buffer, size); - while (bytes_read == -1 && errno == EINTR); - return bytes_read; } /* Write function for fd objects. */ static ssize_t es_func_fd_write (void *cookie, const void *buffer, size_t size) - { estream_cookie_fd_t file_cookie = cookie; ssize_t bytes_written; - do - bytes_written = ESTREAM_SYS_WRITE (file_cookie->fd, buffer, size); - while (bytes_written == -1 && errno == EINTR); + if (IS_INVALID_FD (file_cookie->fd)) + { + ESTREAM_SYS_YIELD (); + bytes_written = size; /* Yeah: Success writing to the bit bucket. */ + } + else + { + do + bytes_written = ESTREAM_SYS_WRITE (file_cookie->fd, buffer, size); + while (bytes_written == -1 && errno == EINTR); + } return bytes_written; } @@ -808,13 +831,21 @@ off_t offset_new; int err; - offset_new = lseek (file_cookie->fd, *offset, whence); - if (offset_new == -1) - err = -1; + if (IS_INVALID_FD (file_cookie->fd)) + { + _set_errno (ESPIPE); + err = -1; + } else { - *offset = offset_new; - err = 0; + offset_new = lseek (file_cookie->fd, *offset, whence); + if (offset_new == -1) + err = -1; + else + { + *offset = offset_new; + err = 0; + } } return err; @@ -829,7 +860,10 @@ if (fd_cookie) { - err = fd_cookie->no_close? 0 : close (fd_cookie->fd); + if (IS_INVALID_FD (fd_cookie->fd)) + err = 0; + else + err = fd_cookie->no_close? 0 : close (fd_cookie->fd); mem_free (fd_cookie); } else @@ -2405,19 +2439,21 @@ stream = do_fdopen (custom_std_fds[1], "a", 1, 1); else if (custom_std_fds_valid[2]) stream = do_fdopen (custom_std_fds[1], "a", 1, 1); - } - if (!stream) - { - /* Standard stream not yet created - do it now. */ - if (!fd) - stream = do_fpopen (stdin, "r", 1, 1); - else if (fd == 1) - stream = do_fpopen (stdout, "a", 1, 1); - else - stream = do_fpopen (stderr, "a", 1, 1); - - if (!stream) /* Fallback: Create a bit bucket. */ + + if (!stream) { + /* Second try is to use the standard C streams. */ + if (!fd) + stream = do_fpopen (stdin, "r", 1, 1); + else if (fd == 1) + stream = do_fpopen (stdout, "a", 1, 1); + else + stream = do_fpopen (stderr, "a", 1, 1); + } + + if (!stream) + { + /* Last try: Create a bit bucket. */ stream = do_fpopen (NULL, fd? "a":"r", 0, 1); if (!stream) { @@ -2426,6 +2462,7 @@ abort(); } } + stream->intern->is_stdstream = 1; stream->intern->stdstream_fd = fd; if (fd == 2) Modified: trunk/common/exechelp-w32ce.c =================================================================== --- trunk/common/exechelp-w32ce.c 2010-05-04 09:56:42 UTC (rev 5326) +++ trunk/common/exechelp-w32ce.c 2010-05-04 15:21:47 UTC (rev 5327) @@ -334,8 +334,10 @@ /* 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 (const char *pgmname, const char * const *argv, - int fd0, int fd1, int fd2, int fd2_isnull, +build_w32_commandline (const char * const *argv, + int fd0, int fd0_isnull, + int fd1, int fd1_isnull, + int fd2, int fd2_isnull, char **cmdline) { int i, n; @@ -347,12 +349,18 @@ *p = 0; if (fd0) { - snprintf (p, 25, "-&S0=%d ", fd0); + if (fd0_isnull) + strcpy (p, "-&S0=null "); + else + snprintf (p, 25, "-&S0=%d ", fd0); p += strlen (p); } if (fd1) { - snprintf (p, 25, "-&S1=%d ", fd1); + if (fd1_isnull) + strcpy (p, "-&S1=null "); + else + snprintf (p, 25, "-&S1=%d ", fd1); p += strlen (p); } if (fd2) @@ -366,7 +374,6 @@ *cmdline = NULL; n = strlen (fdbuf); - n += strlen (pgmname) + 1 + 2; /* (1 space, 2 quoting) */ for (i=0; (s = argv[i]); i++) { n += strlen (s) + 1 + 2; /* (1 space, 2 quoting) */ @@ -381,7 +388,6 @@ return -1; p = stpcpy (p, fdbuf); - p = copy_quoted (p, pgmname); for (i = 0; argv[i]; i++) { *p++ = ' '; @@ -540,8 +546,11 @@ } /* Build the command line. */ - err = build_w32_commandline (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], - 0, &cmdline); + err = build_w32_commandline (argv, + inpipe[0], 0, + outpipe[1], 0, + errpipe[1], 0, + &cmdline); if (err) { CloseHandle (fd_to_handle (errpipe[0])); @@ -601,68 +610,42 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], int infd, int outfd, int errfd, pid_t *pid) { - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -#if 0 gpg_error_t err; - PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; - STARTUPINFO si; + PROCESS_INFORMATION pi = {NULL}; char *cmdline; - int i; - HANDLE stdhd[3]; /* Setup return values. */ *pid = (pid_t)(-1); + if (infd != -1 || outfd != -1 || errfd != -1) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + /* Build the command line. */ - err = build_w32_commandline (pgmname, argv, &cmdline); + err = build_w32_commandline (argv, -1, 1, -1, 1, -1, 1, &cmdline); if (err) return err; - /* si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; */ - /* stdhd[0] = infd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE; */ - /* stdhd[1] = outfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; */ - /* stdhd[2] = errfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; */ - /* si.hStdInput = infd == -1? stdhd[0] : (void*)_get_osfhandle (infd); */ - /* si.hStdOutput = outfd == -1? stdhd[1] : (void*)_get_osfhandle (outfd); */ - /* si.hStdError = errfd == -1? stdhd[2] : (void*)_get_osfhandle (errfd); */ - -/* log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */ - if (!CreateProcess (pgmname, /* Program to start. */ - cmdline, /* Command line arguments. */ - NULL, /* Process security attributes. */ - NULL, /* Thread security attributes. */ - FALSE, /* Inherit handles. */ - CREATE_SUSPENDED, - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - NULL, /* Startup information. */ - &pi /* Returns process information. */ - )) + log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); + if (!create_process (pgmname, cmdline, &pi)) { - log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); - err = gpg_error (GPG_ERR_GENERAL); + log_error ("CreateProcess(fd) failed: %s\n", w32_strerror (-1)); + xfree (cmdline); + return gpg_error (GPG_ERR_GENERAL); } - else - err = 0; xfree (cmdline); - for (i=0; i < 3; i++) - if (stdhd[i] != INVALID_HANDLE_VALUE) - CloseHandle (stdhd[i]); - if (err) - return err; + cmdline = NULL; -/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ -/* " dwProcessID=%d dwThreadId=%d\n", */ -/* pi.hProcess, pi.hThread, */ -/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - + log_debug ("CreateProcess(fd) ready: hProcess=%p hThread=%p" + " dwProcessID=%d dwThreadId=%d\n", + pi.hProcess, pi.hThread, + (int) pi.dwProcessId, (int) pi.dwThreadId); + /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); CloseHandle (pi.hThread); *pid = handle_to_pid (pi.hProcess); return 0; -#endif } /* Wait for the process identified by PID to terminate. PGMNAME should @@ -743,42 +726,20 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], const char *envp[] ) { - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -#if 0 gpg_error_t err; - PROCESS_INFORMATION pi = - { - NULL, /* Returns process handle. */ - 0, /* Returns primary thread handle. */ - 0, /* Returns pid. */ - 0 /* Returns tid. */ - }; - STARTUPINFO si; char *cmdline; + PROCESS_INFORMATION pi = {NULL }; (void)envp; - - if (access (pgmname, X_OK)) - return gpg_error_from_syserror (); - + /* Build the command line. */ - err = build_w32_commandline (pgmname, argv, &cmdline); + err = build_w32_commandline (argv, -1, 1, -1, 1, -1, 1, &cmdline); if (err) return err; -/* log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", */ -/* pgmname, cmdline); */ - if (!CreateProcess (pgmname, /* Program to start. */ - cmdline, /* Command line arguments. */ - NULL, /* Process security attributes. */ - NULL, /* Thread security attributes. */ - FALSE, /* Inherit handles. */ - 0, /* Creation flags. */ - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - NULL, /* Startup information. */ - &pi /* Returns process information. */ - )) + /* Note: There is no detached flag under CE. */ + log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); + if (!create_process (pgmname, cmdline, &pi)) { log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1)); xfree (cmdline); @@ -787,17 +748,19 @@ xfree (cmdline); cmdline = NULL; -/* log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" */ -/* " dwProcessID=%d dwThreadId=%d\n", */ -/* pi.hProcess, pi.hThread, */ -/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - + log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" + " dwProcessID=%d dwThreadId=%d\n", + pi.hProcess, pi.hThread, + (int) pi.dwProcessId, (int) pi.dwThreadId); + + /* Process has been created suspended; resume it now. */ + ResumeThread (pi.hThread); CloseHandle (pi.hThread); return 0; -#endif } + /* Kill a process; that is send an appropriate signal to the process. gnupg_wait_process must be called to actually remove the process from the system. An invalid PID is ignored. */ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-05-04 09:56:42 UTC (rev 5326) +++ trunk/configure.ac 2010-05-04 15:21:47 UTC (rev 5327) @@ -1584,12 +1584,13 @@ Smartcard: $build_scdaemon $build_scdaemon_extra G13: $build_g13 - Protect tool: $show_gnupg_protect_tool_pgm Default agent: $show_gnupg_agent_pgm Default pinentry: $show_gnupg_pinentry_pgm Default scdaemon: $show_gnupg_scdaemon_pgm Default dirmngr: $show_gnupg_dirmngr_pgm + + Use standard socket: $use_standard_socket " if test x"$use_regex" != xyes ; then echo " From cvs at cvs.gnupg.org Thu May 6 14:29:31 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 06 May 2010 14:29:31 +0200 Subject: [svn] ksba - r317 - in trunk: . src Message-ID: Author: wk Date: 2010-05-06 14:29:31 +0200 (Thu, 06 May 2010) New Revision: 317 Added: trunk/src/gen-help.c trunk/src/gen-help.h Modified: trunk/NEWS trunk/configure.ac trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/asn1-func.c trunk/src/asn1-func.h trunk/src/asn1-gentables.c trunk/src/asn1-parse.y trunk/src/util.h Log: Make it build from SVN even when cross compiling Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/src/ChangeLog 2010-05-06 12:29:31 UTC (rev 317) @@ -1,3 +1,22 @@ +2010-05-06 Werner Koch + + * gen-help.c, gen-help.h: New. + * Makefile.am: Build asn1-gentables and ber-dump also when cross + compiling. + (asn1_gentables_SOURCES, asn1_gentables_LDADD) + (asn1_gentables_CFLAGS): Remove. + (asn1-gentables): New rule. + (asn1-parse.c): Add gen-help.h as dependency. + (EXTRA_DIST): Add gen-help.c and gen-help.h. + * asn1-parse.y [BUILD_GENTOOLS]: Include gen-help.h instead of + util.h and ksba.h. + (ksba_asn_parse_file): Use gpg_error_from_syserror. + * asn1-func.c [BUILD_GENTOOLS]: Include gen-help.h instead of + util.h and ksba.h. + (resolve_identifier): Avoid the alloca. + * asn1-gentables.c: Include gen-help instead of util.h and ksba.h. + (sort_string_table): Remove useless printing of the string table. + 2010-01-22 Werner Koch * util.c (ksba_calloc): Use gpg_er_set_errno. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/NEWS 2010-05-06 12:29:31 UTC (rev 317) @@ -3,7 +3,9 @@ * Support for WindowsCE. + * Builds cleaning from SVN even when cross-compiling. + Noteworthy changes in version 1.0.7 (2009-07-03) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/configure.ac 2010-05-06 12:29:31 UTC (rev 317) @@ -100,7 +100,19 @@ AC_PROG_YACC AC_C_INLINE +# We need to compile and run a program on the build machine. +# The AC_PROG_CC_FOR_BUILD macro in the AC archive is broken for +# autoconf 2.57. +AC_MSG_CHECKING(for cc for build) +if test "$cross_compiling" = "yes"; then + CC_FOR_BUILD="${CC_FOR_BUILD-cc}" +else + CC_FOR_BUILD="${CC_FOR_BUILD-$CC}" +fi +AC_MSG_RESULT($CC_FOR_BUILD) +AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler]) + # This is handy for debugging so the compiler doesn't rearrange # things and eliminate variables. AC_ARG_ENABLE(optimization, @@ -371,11 +383,3 @@ Platform: $host " -if test x$cross_compiling != xno; then -echo "Hint: If you encounter make problems like - \"No rule to make target 'asn1-tables.c'\" -you should first do a native build without installing -the software, then a \"make distclean\" and then -run the cross compilation again. -" -fi Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/src/Makefile.am 2010-05-06 12:29:31 UTC (rev 317) @@ -20,20 +20,21 @@ asn1_modules = tmttv2.asn cms.asn +buildtool_src = asn1-gentables.c gen-help.c gen-help.h EXTRA_DIST = ksba-config.in $(asn1_modules) ksba.m4 libksba.vers libksba.def \ - asn1-parse.c asn1-tables.c + asn1-parse.c asn1-tables.c $(buildtool_src) BUILT_SOURCES = asn1-parse.c asn1-tables.c bin_SCRIPTS = ksba-config include_HEADERS = ksba.h lib_LTLIBRARIES = libksba.la +noinst_PROGRAMS = ber-dump -if ! CROSS_COMPILING -noinst_PROGRAMS = asn1-gentables ber-dump -endif - m4datadir = $(datadir)/aclocal m4data_DATA = ksba.m4 +CLEANFILES = asn1-gentables +DISTCLEANFILES = asn1-tables.c + AM_CPPFLAGS = -I$(top_builddir)/gl -I$(top_srcdir)/gl AM_CFLAGS = $(GPG_ERROR_CFLAGS) @@ -106,27 +107,25 @@ sexp-parse.h \ asn1-tables.c -asn1_gentables_SOURCES = asn1-gentables.c asn1-parse.c asn1-func.c oid.c util.c -asn1_gentables_LDADD = $(GPG_ERROR_LIBS) ../gl/libgnu.la -# Note that we need to use per-target flags to force renaming of the -# object files to avoid clashes with libtool. -asn1_gentables_CFLAGS = $(AM_CFLAGS) - ber_dump_SOURCES = ber-dump.c \ ber-decoder.c ber-help.c reader.c writer.c asn1-parse.c \ asn1-func.c oid.c util.c ber_dump_LDADD = $(GPG_ERROR_LIBS) ../gl/libgnu.la ber_dump_CFLAGS = $(AM_CFLAGS) -asn1-parse.c : asn1-func.h +asn1-parse.c : asn1-func.h gen-help.h -if ! CROSS_COMPILING -asn1-tables.c : $(asn1_modules) - $(MAKE) $(AM_MAKEFLAGS) asn1-gentables +asn1-gentables: asn1-gentables.c asn1-parse.c asn1-func.c gen-help.c gen-help.h + $(CC_FOR_BUILD) -I$(srcdir) -DBUILD_GENTOOLS -o $@ \ + $(srcdir)/asn1-gentables.c \ + `test -f 'asn1-parse.c' || echo '$(srcdir)/'`asn1-parse.c \ + $(srcdir)/asn1-func.c \ + $(srcdir)/gen-help.c + +asn1-tables.c : $(asn1_modules) asn1-gentables @set -e; list=""; \ for file in $(asn1_modules); do list="$$list $(srcdir)/$$file";done;\ ./asn1-gentables $$list > asn1-tables.c -endif install-data-local: install-def-file Modified: trunk/src/asn1-func.c =================================================================== --- trunk/src/asn1-func.c 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/src/asn1-func.c 2010-05-06 12:29:31 UTC (rev 317) @@ -1,6 +1,6 @@ -/* asn1-func.c - Manage ASN.1 definitions +/* asn1-func.c - Fucntions for the ASN.1 data structures. * Copyright (C) 2000, 2001 Fabio Fiorina - * Copyright (C) 2001 Free Software Foundation, Inc. + * Copyright (C) 2001, 2010 Free Software Foundation, Inc. * * This file is part of GNUTLS. * @@ -18,22 +18,27 @@ * along with this program; if not, see . */ +#ifndef BUILD_GENTOOLS #include +#endif + #include #include #include #include #include -#include +#ifdef BUILD_GENTOOLS +# include "gen-help.h" +#else +# include "util.h" +# include "ksba.h" +#endif -#include "util.h" -#include "ksba.h" #include "asn1-func.h" -static AsnNode -resolve_identifier (AsnNode root, AsnNode node, int nestlevel); +static AsnNode resolve_identifier (AsnNode root, AsnNode node, int nestlevel); static AsnNode @@ -1051,8 +1056,10 @@ static AsnNode resolve_identifier (AsnNode root, AsnNode node, int nestlevel) { + char buf_space[50]; char *buf; AsnNode n; + size_t bufsize; if (nestlevel > 20) return NULL; @@ -1060,13 +1067,24 @@ return_null_if_fail (root); return_null_if_fail (node->valuetype == VALTYPE_CSTR); - buf = alloca (strlen(root->name)+strlen(node->value.v_cstr)+2); - return_null_if_fail (buf); + bufsize = strlen (root->name) + strlen (node->value.v_cstr) + 2; + if (bufsize <= sizeof buf_space) + buf = buf_space; + else + { + buf = xtrymalloc (bufsize); + return_null_if_fail (buf); + } strcpy (stpcpy (stpcpy (buf, root->name), "."), node->value.v_cstr); n = _ksba_asn_find_node (root, buf); - /* we do just a simple indirection */ + + /* We do just a simple indirection. */ if (n && n->type == TYPE_IDENTIFIER) n = resolve_identifier (root, n, nestlevel+1); + + if (buf != buf_space) + xfree (buf); + return n; } @@ -1270,8 +1288,3 @@ } return NULL; } - - - - - Modified: trunk/src/asn1-func.h =================================================================== --- trunk/src/asn1-func.h 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/src/asn1-func.h 2010-05-06 12:29:31 UTC (rev 317) @@ -124,10 +124,11 @@ unsigned long v_ulong; }; -/******************************************************/ -/* Structure definition used for the node of the tree */ -/* that rappresent an ASN.1 DEFINITION. */ -/******************************************************/ + +/* + * Structure definition used for the node of the tree that represents + * an ASN.1 DEFINITION. + */ #ifndef HAVE_TYPEDEFD_ASNNODE typedef struct asn_node_struct *AsnNode; typedef struct asn_node_struct *asn_node_t; @@ -167,10 +168,11 @@ } static_asn; +/*-- asn1-parse.y --*/ +void _ksba_asn_release_nodes (AsnNode node); -/***************************************/ -/* Functions used by ASN.1 parser */ -/***************************************/ + +/*-- asn1-func.c --*/ void _ksba_asn_set_value (AsnNode node, enum asn_value_type vtype, const void *value, size_t len); void _ksba_asn_set_name (AsnNode node, const char *name); @@ -186,11 +188,6 @@ AsnNode _ksba_asn_expand_tree (AsnNode parse_tree, const char *name); AsnNode _ksba_asn_insert_copy (AsnNode node); -/*-- asn1-parse.y --*/ -void _ksba_asn_release_nodes (AsnNode node); - - -/*-- asn1-func.c --*/ int _ksba_asn_is_primitive (node_type_t type); AsnNode _ksba_asn_new_node (node_type_t type); void _ksba_asn_node_dump (AsnNode p, FILE *fp); @@ -204,8 +201,8 @@ int _ksba_asn_delete_structure (AsnNode root); /*-- asn2-func.c --*/ +/*(functions are all declared in ksba.h)*/ - /*-- asn1-tables.c (generated) --*/ const static_asn *_ksba_asn_lookup_table (const char *name, const char **stringtbl); Modified: trunk/src/asn1-gentables.c =================================================================== --- trunk/src/asn1-gentables.c 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/src/asn1-gentables.c 2010-05-06 12:29:31 UTC (rev 317) @@ -17,16 +17,13 @@ * along with this program; if not, see . */ -#include #include #include #include #include #include -#include "util.h" - -#include "ksba.h" +#include "gen-help.h" #include "asn1-func.h" #define PGMNAME "asn1-gentables" @@ -134,8 +131,8 @@ for (i=0; i < arraylen; i++) insert_string (array[i]->name); xfree (array); - for (item = string_table,arraylen = 0; item; item = item->next) - fprintf (stderr, " `%s'\n", item->name); + /* for (item = string_table,arraylen = 0; item; item = item->next) */ + /* fprintf (stderr, " `%s'\n", item->name); */ } Modified: trunk/src/asn1-parse.y =================================================================== --- trunk/src/asn1-parse.y 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/src/asn1-parse.y 2010-05-06 12:29:31 UTC (rev 317) @@ -1,6 +1,6 @@ -/* +/* asn1-parse.y - ASN.1 grammar * Copyright (C) 2000,2001 Fabio Fiorina - * Copyright (C) 2001 Free Software Foundation, Inc. + * Copyright (C) 2001, 2010 Free Software Foundation, Inc. * * This file is part of GNUTLS. * @@ -28,7 +28,9 @@ %{ -#include +#ifndef BUILD_GENTOOLS +# include +#endif #include #include #include @@ -36,8 +38,13 @@ #include #include -#include "util.h" -#include "ksba.h" +#ifdef BUILD_GENTOOLS +# include "gen-help.h" +#else +# include "util.h" +# include "ksba.h" +#endif + #include "asn1-parse.h" #include "asn1-func.h" @@ -992,7 +999,7 @@ parsectl.fp = file_name? fopen (file_name, "r") : NULL; if ( !parsectl.fp ) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); parsectl.lineno = 0; parsectl.debug = debug; @@ -1039,7 +1046,7 @@ void _ksba_asn_release_nodes (AsnNode node) { - /* FIXME: it does not work yet becuase the allocation function in + /* FIXME: it does not work yet because the allocation function in asn1-func.c does not link all nodes together */ release_all_nodes (node); } Added: trunk/src/gen-help.c =================================================================== --- trunk/src/gen-help.c (rev 0) +++ trunk/src/gen-help.c 2010-05-06 12:29:31 UTC (rev 317) @@ -0,0 +1,111 @@ +/* gen-help.c - Helper functions used by build time tools + * Copyright (C) 2010 g10 Code GmbH + * + * This file is part of KSBA. + * + * KSBA 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 Fountion; either version 3 of the License, or + * (at your option) any later version. + * + * KSBA is distributed in the hope that 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, see . + */ + +/* No config.h - this file needs to build as plain ISO-C. */ +#include +#include +#include + +#include "gen-help.h" + + +static void +out_of_core(void) +{ + fputs ("\nfatal: out of memory\n", stderr); + exit (2); +} + + + +/* Implementation of the common xfoo() memory allocation functions */ +void * +xmalloc (size_t n ) +{ + void *p = malloc (n); + if (!p) + out_of_core (); + return p; +} + +void * +xcalloc (size_t n, size_t m) +{ + void *p = calloc (n, m); + if (!p) + out_of_core (); + return p; +} + +void * +xrealloc (void *mem, size_t n) +{ + void *p = realloc (mem, n); + if (!p) + out_of_core (); + return p; +} + + +char * +xstrdup (const char *str) +{ + char *p = strdup (str); + if (!p) + out_of_core (); + return p; +} + +void +xfree (void *a) +{ + if (a) + free (a); +} + + +/* Our version of stpcpy to avoid conflicts with already availabale + implementations. */ +char * +gen_help_stpcpy (char *a, const char *b) +{ + while (*b) + *a++ = *b++; + *a = 0; + + return a; +} + + +/* Simple replacement function to avoid the need for a build libgpg-error */ +const char * +gpg_strerror (int err) +{ + switch (err) + { + case 0: return "Success"; + case GPG_ERR_GENERAL: return "General error"; + case GPG_ERR_SYNTAX: return "Syntax error"; + case GPG_ERR_INV_VALUE: return "Invalid value"; + case GPG_ERR_BUG: return "Bug"; + case GPG_ERR_ELEMENT_NOT_FOUND: return "Not found"; + case GPG_ERR_IDENTIFIER_NOT_FOUND: return "Identifier not found"; + default: return "Unknown error"; + } +} Added: trunk/src/gen-help.h =================================================================== --- trunk/src/gen-help.h (rev 0) +++ trunk/src/gen-help.h 2010-05-06 12:29:31 UTC (rev 317) @@ -0,0 +1,96 @@ +/* gen-help.c - Helper functions used by build time tools + * Copyright (C) 2010 g10 Code GmbH + * + * This file is part of KSBA. + * + * KSBA 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 Fountion; either version 3 of the License, or + * (at your option) any later version. + * + * KSBA is distributed in the hope that 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, see . + */ + +/* This header has definitions used by programs which are only run on + the build platform as part of the build process. They need to be + plain ISO C and don't make use of any information gathered from the + configure run. */ + +#ifndef GEN_HELP_H +#define GEN_HELP_H + +#ifndef BUILD_GENTOOLS +#error file may only be used for build time tools +#endif + + +void *xmalloc (size_t n); +void *xcalloc (size_t n, size_t m); +void *xrealloc (void *mem, size_t n); +char *xstrdup (const char *str); +void xfree (void *a); +#define xtrymalloc(a) malloc ((a)) + +char *gen_help_stpcpy (char *a, const char *b); +#define stpcpy(a, b) gen_help_stpcpy ((a), (b)) + + + + +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) +#ifndef STR +# define STR(v) #v +#endif +#ifndef STR2 +# define STR2(v) STR(v) +#endif + +#define return_if_fail(expr) do { \ + if (!(expr)) { \ + fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ + __FILE__, __LINE__, #expr ); \ + return; \ + } } while (0) +#define return_null_if_fail(expr) do { \ + if (!(expr)) { \ + fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ + __FILE__, __LINE__, #expr ); \ + return NULL; \ + } } while (0) +#define return_val_if_fail(expr,val) do { \ + if (!(expr)) { \ + fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ + __FILE__, __LINE__, #expr ); \ + return (val); \ + } } while (0) +#define never_reached() do { \ + fprintf (stderr, "%s:%d: oops; should never get here\n", \ + __FILE__, __LINE__ ); \ + } while (0) + + +/* Replacement for gpg_error.h stuff. */ +#define GPG_ERR_GENERAL 1 +#define GPG_ERR_SYNTAX 29 +#define GPG_ERR_INV_VALUE 55 +#define GPG_ERR_BUG 59 +#define GPG_ERR_ELEMENT_NOT_FOUND 136 +#define GPG_ERR_IDENTIFIER_NOT_FOUND 137 + +#define gpg_error(a) (a) +#define gpg_error_from_syserror() (GPG_ERR_GENERAL); +const char *gpg_strerror (int err); + +/* Duplicated type definitions from ksba.h. */ +typedef struct ksba_asn_tree_s *ksba_asn_tree_t; + + +#endif /*GEN_HELP_H*/ + Modified: trunk/src/util.h =================================================================== --- trunk/src/util.h 2010-04-14 14:33:14 UTC (rev 316) +++ trunk/src/util.h 2010-05-06 12:29:31 UTC (rev 317) @@ -20,6 +20,11 @@ #ifndef UTIL_H #define UTIL_H +#ifdef BUILD_GENTOOLS +#error file may not be be used for build time tools +#endif + + #include "visibility.h" From cvs at cvs.gnupg.org Thu May 6 15:40:29 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 06 May 2010 15:40:29 +0200 Subject: [svn] gpgme - r1461 - in trunk: . src Message-ID: Author: marcus Date: 2010-05-06 15:39:55 +0200 (Thu, 06 May 2010) New Revision: 1461 Modified: trunk/ChangeLog trunk/README trunk/configure.ac trunk/src/assuan-support.c trunk/src/conversion.c trunk/src/data-compat.c trunk/src/data-mem.c trunk/src/data-user.c trunk/src/data.c trunk/src/debug.c trunk/src/decrypt.c trunk/src/delete.c trunk/src/engine-gpgsm.c trunk/src/gpgme-tool.c trunk/src/import.c trunk/src/op-support.c trunk/src/setenv.c trunk/src/sign.c trunk/src/verify.c trunk/src/w32-io.c trunk/src/w32-util.c Log: 2010-05-06 Marcus Brinkmann * configure.ac: Require libgpg-error 1.8. src/ 2010-05-06 Marcus Brinkmann * sign.c, data-user.c, conversion.c, debug.c, verify.c, data.c, decrypt.c, delete.c, assuan-support.c, import.c, engine-gpgsm.c, data-mem.c, op-support.c, w32-io.c, w32-util.c, data-compat.c: Use gpg_error_from_syserror instead gpg_error_from_errno, and use gpg_err_set_errno to set error number. * setenv.c: Include and define __set_errno to use gpg_err_set_errno. * gpgme-tool.c (ARGP_ERR_UNKNOWN): Define to EDEADLOCK (which is mapped in Windows CE) instead of E2BIG (which is not). (gt_import_keys): Initialize err. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/ChangeLog 2010-05-06 13:39:55 UTC (rev 1461) @@ -1,3 +1,7 @@ +2010-05-06 Marcus Brinkmann + + * configure.ac: Require libgpg-error 1.8. + 2010-03-15 Werner Koch * configure.ac (emacs_local_vars_begin) Modified: trunk/README =================================================================== --- trunk/README 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/README 2010-05-06 13:39:55 UTC (rev 1461) @@ -41,7 +41,7 @@ Don't skip it - this is an important step! To build GPGME, you need to install libgpg-error. You need at least -libgpg-error 0.5. +libgpg-error 1.8. For support of the OpenPGP protocol (default), you should use the latest version of GnuPG 1.2 or 1.4, available at: Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/configure.ac 2010-05-06 13:39:55 UTC (rev 1461) @@ -283,7 +283,7 @@ fi # Checking for libgpg-error. -AM_PATH_GPG_ERROR(1.4,, AC_MSG_ERROR([libgpg-error was not found])) +AM_PATH_GPG_ERROR(1.8,, AC_MSG_ERROR([libgpg-error was not found])) AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME, [The default error source for GPGME.]) Modified: trunk/src/assuan-support.c =================================================================== --- trunk/src/assuan-support.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/assuan-support.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -77,7 +77,7 @@ int flags) { #ifdef HAVE_W32_SYSTEM - errno = ENOSYS; + gpg_err_set_errno (ENOSYS); return -1; #else return _gpgme_io_recvmsg (fd, msg, flags); @@ -91,7 +91,7 @@ int flags) { #ifdef HAVE_W32_SYSTEM - errno = ENOSYS; + gpg_err_set_errno (ENOSYS); return -1; #else return _gpgme_io_sendmsg (fd, msg, flags); @@ -118,7 +118,7 @@ if (! name) { - errno = ENOSYS; + gpg_err_set_errno (ENOSYS); return -1; } @@ -203,7 +203,7 @@ int protocol, assuan_fd_t filedes[2]) { #ifdef HAVE_W32_SYSTEM - errno = ENOSYS; + gpg_err_set_errno (ENOSYS); return -1; #else /* FIXME: Debug output missing. */ Modified: trunk/src/conversion.c =================================================================== --- trunk/src/conversion.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/conversion.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -93,7 +93,7 @@ string. */ dest = malloc (strlen (src) + 1); if (!dest) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); *destp = dest; } @@ -198,7 +198,7 @@ string. */ dest = malloc (strlen (src) + 1); if (!dest) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); *destp = dest; } @@ -291,7 +291,7 @@ string. */ dest = malloc (destlen); if (!dest) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); *destp = dest; } Modified: trunk/src/data-compat.c =================================================================== --- trunk/src/data-compat.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/data-compat.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -158,7 +158,7 @@ TRACE3 (DEBUG_DATA, "gpgme:gpgme_error_to_errno", 0, "mapping %s <%s> to: %s", gpgme_strerror (err), gpgme_strsource (err), strerror (res)); - errno = res; + gpg_err_set_errno (res); return res ? -1 : 0; } @@ -188,7 +188,7 @@ if (whence != SEEK_SET || offset) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return TRACE_SYSRES (-1); } err = (*dh->data.old_user.cb) (dh->data.old_user.handle, NULL, 0, NULL); Modified: trunk/src/data-mem.c =================================================================== --- trunk/src/data-mem.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/data-mem.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -115,7 +115,7 @@ case SEEK_SET: if (offset < 0 || offset > dh->data.mem.length) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return -1; } dh->data.mem.offset = offset; @@ -124,7 +124,7 @@ if ((offset > 0 && dh->data.mem.length - dh->data.mem.offset < offset) || (offset < 0 && dh->data.mem.offset < -offset)) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return -1; } dh->data.mem.offset += offset; @@ -132,13 +132,13 @@ case SEEK_END: if (offset > 0 || -offset > dh->data.mem.length) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return -1; } dh->data.mem.offset = dh->data.mem.length - offset; break; default: - errno = EINVAL; + gpg_err_set_errno (EINVAL); return -1; } return dh->data.mem.offset; Modified: trunk/src/data-user.c =================================================================== --- trunk/src/data-user.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/data-user.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -34,7 +34,7 @@ { if (!dh->data.user.cbs->read) { - errno = EBADF; + gpg_err_set_errno (EBADF); return -1; } @@ -47,7 +47,7 @@ { if (!dh->data.user.cbs->write) { - errno = EBADF; + gpg_err_set_errno (EBADF); return -1; } @@ -60,7 +60,7 @@ { if (!dh->data.user.cbs->seek) { - errno = EBADF; + gpg_err_set_errno (EBADF); return -1; } Modified: trunk/src/data.c =================================================================== --- trunk/src/data.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/data.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -46,7 +46,7 @@ *r_dh = NULL; dh = calloc (1, sizeof (*dh)); if (!dh) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); dh->cbs = cbs; @@ -79,12 +79,12 @@ if (!dh) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return TRACE_SYSRES (-1); } if (!dh->cbs->read) { - errno = ENOSYS; + gpg_err_set_errno (ENOSYS); return TRACE_SYSRES (-1); } do @@ -107,12 +107,12 @@ if (!dh) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return TRACE_SYSRES (-1); } if (!dh->cbs->write) { - errno = ENOSYS; + gpg_err_set_errno (ENOSYS); return TRACE_SYSRES (-1); } do @@ -134,12 +134,12 @@ if (!dh) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return TRACE_SYSRES (-1); } if (!dh->cbs->seek) { - errno = ENOSYS; + gpg_err_set_errno (ENOSYS); return TRACE_SYSRES (-1); } @@ -216,7 +216,7 @@ { dh->file_name = strdup (file_name); if (!dh->file_name) - return TRACE_ERR (gpg_error_from_errno (errno)); + return TRACE_ERR (gpg_error_from_syserror ()); } else dh->file_name = 0; @@ -257,7 +257,7 @@ buflen = _gpgme_io_read (fd, buffer, BUFFER_SIZE); if (buflen < 0) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); if (buflen == 0) { _gpgme_io_close (fd); @@ -268,7 +268,7 @@ { ssize_t amt = gpgme_data_write (dh, bufp, buflen); if (amt == 0 || (amt < 0 && errno != EINTR)) - return TRACE_ERR (gpg_error_from_errno (errno)); + return TRACE_ERR (gpg_error_from_syserror ()); bufp += amt; buflen -= amt; } @@ -290,7 +290,7 @@ { ssize_t amt = gpgme_data_read (dh, dh->pending, BUFFER_SIZE); if (amt < 0) - return TRACE_ERR (gpg_error_from_errno (errno)); + return TRACE_ERR (gpg_error_from_syserror ()); if (amt == 0) { _gpgme_io_close (fd); @@ -314,7 +314,7 @@ } if (nwritten <= 0) - return TRACE_ERR (gpg_error_from_errno (errno)); + return TRACE_ERR (gpg_error_from_syserror ()); if (nwritten < dh->pending_len) memmove (dh->pending, dh->pending + nwritten, dh->pending_len - nwritten); Modified: trunk/src/debug.c =================================================================== --- trunk/src/debug.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/debug.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -231,7 +231,7 @@ UNLOCK (debug_lock); fflush (errfp); - errno = saved_errno; + gpg_err_set_errno (saved_errno); } Modified: trunk/src/decrypt.c =================================================================== --- trunk/src/decrypt.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/decrypt.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -126,7 +126,7 @@ rec = malloc (sizeof (*rec)); if (!rec) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); rec->next = NULL; rec->keyid = rec->_keyid; @@ -153,7 +153,7 @@ if (*args) { - errno = 0; + gpg_err_set_errno (0); rec->pubkey_algo = strtol (args, &tail, 0); if (errno || args == tail || *tail != ' ') { @@ -239,7 +239,7 @@ { opd->result.unsupported_algorithm = strdup (args); if (!opd->result.unsupported_algorithm) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); } } } Modified: trunk/src/delete.c =================================================================== --- trunk/src/delete.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/delete.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -45,7 +45,7 @@ long problem; char *tail; - errno = 0; + gpg_err_set_errno (0); problem = strtol (args, &tail, 0); if (errno || (*tail && *tail != ' ')) return gpg_error (GPG_ERR_INV_ENGINE); Modified: trunk/src/engine-gpgsm.c =================================================================== --- trunk/src/engine-gpgsm.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/engine-gpgsm.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -247,7 +247,7 @@ gpgsm = calloc (1, sizeof *gpgsm); if (!gpgsm) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); gpgsm->status_cb.fd = -1; gpgsm->status_cb.dir = 1; @@ -288,7 +288,7 @@ #if !USE_DESCRIPTOR_PASSING if (_gpgme_io_pipe (fds, 0) < 0) { - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); goto leave; } gpgsm->input_cb.fd = fds[1]; @@ -296,7 +296,7 @@ if (_gpgme_io_pipe (fds, 1) < 0) { - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); goto leave; } gpgsm->output_cb.fd = fds[0]; @@ -304,7 +304,7 @@ if (_gpgme_io_pipe (fds, 0) < 0) { - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); goto leave; } gpgsm->message_cb.fd = fds[1]; @@ -372,7 +372,7 @@ if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) { free (dft_display); - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); goto leave; } free (dft_display); @@ -398,7 +398,7 @@ { if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); goto leave; } err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, @@ -415,7 +415,7 @@ if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) { free (dft_ttytype); - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); goto leave; } free (dft_ttytype); @@ -524,7 +524,7 @@ return 0; if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); else { err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, @@ -660,7 +660,7 @@ int fds[2]; if (_gpgme_io_pipe (fds, dir) < 0) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); iocb_data->fd = dir ? fds[0] : fds[1]; iocb_data->server_fd = dir ? fds[1] : fds[0]; @@ -832,7 +832,7 @@ { char *newline = realloc (*aline, *alinelen + linelen + 1); if (!newline) - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); else { *aline = newline; @@ -917,7 +917,7 @@ if (!nwritten || (nwritten < 0 && errno != EINTR) || nwritten > linelen) { - err = gpg_error_from_errno (errno); + err = gpg_error_from_syserror (); break; } src += nwritten; @@ -1115,7 +1115,7 @@ line = malloc (length); if (!line) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); strcpy (line, "DELKEYS "); linep = &line[8]; @@ -1172,7 +1172,7 @@ linelen = 10 + 40 + 1; /* "RECIPIENT " + guess + '\0'. */ line = malloc (10 + 40 + 1); if (!line) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); strcpy (line, "RECIPIENT "); for (i =0; !err && recp[i]; i++) { @@ -1278,7 +1278,7 @@ cmd = malloc (7 + strlen (pattern) + 1); if (!cmd) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); strcpy (cmd, "EXPORT "); strcpy (&cmd[7], pattern); @@ -1335,7 +1335,7 @@ } line = malloc (length); if (!line) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); strcpy (line, "EXPORT "); linep = &line[7]; @@ -1552,7 +1552,7 @@ /* Always send list-mode option because RESET does not reset it. */ if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL); free (line); if (err) @@ -1580,7 +1580,7 @@ /* Length is "LISTSECRETKEYS " + p + '\0'. */ line = malloc (15 + strlen (pattern) + 1); if (!line) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); if (secret_only) { strcpy (line, "LISTSECRETKEYS "); @@ -1626,7 +1626,7 @@ /* Always send list-mode option because RESET does not reset it. */ if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL); free (line); if (err) @@ -1663,7 +1663,7 @@ } line = malloc (length); if (!line) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); if (secret_only) { strcpy (line, "LISTSECRETKEYS "); @@ -1749,7 +1749,7 @@ requested. */ if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, assuan_cmd, NULL, NULL); free (assuan_cmd); Modified: trunk/src/gpgme-tool.c =================================================================== --- trunk/src/gpgme-tool.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/gpgme-tool.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -107,7 +107,7 @@ void *pstate; }; -#define ARGP_ERR_UNKNOWN E2BIG +#define ARGP_ERR_UNKNOWN EDEADLOCK #define ARGP_KEY_ARG 0 #define ARGP_KEY_ARGS 0x1000006 #define ARGP_KEY_END 0x1000001 @@ -1651,7 +1651,7 @@ gpg_error_t gt_import_keys (gpgme_tool_t gt, char *fpr[]) { - gpg_error_t err; + gpg_error_t err = 0; int cnt; int idx; gpgme_key_t *keys; Modified: trunk/src/import.c =================================================================== --- trunk/src/import.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/import.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -121,10 +121,10 @@ import = malloc (sizeof (*import)); if (!import) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); import->next = NULL; - errno = 0; + gpg_err_set_errno (0); nr = strtol (args, &tail, 0); if (errno || args == tail || *tail != ' ') { @@ -189,7 +189,7 @@ { char *tail; - errno = 0; + gpg_err_set_errno (0); #define PARSE_NEXT(x) \ (x) = strtol (args, &tail, 0); \ Modified: trunk/src/op-support.c =================================================================== --- trunk/src/op-support.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/op-support.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -182,7 +182,7 @@ if (!inv_key) return gpg_error_from_errno (errno); inv_key->next = NULL; - errno = 0; + gpg_err_set_errno (0); reason = strtol (args, &tail, 0); if (errno || args == tail || (*tail && *tail != ' ')) { @@ -299,7 +299,7 @@ { char *filename = strdup (args); if (!filename) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); *filenamep = filename; } Modified: trunk/src/setenv.c =================================================================== --- trunk/src/setenv.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/setenv.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -20,6 +20,9 @@ # include #endif +#include +#define __set_errno(ev) (gpg_err_set_errno (ev)) + #if HAVE_ASSUAN_H /* Fixme: Why do we need to include the assuan header and why the internal ones? */ @@ -29,12 +32,6 @@ #define __builtin_expect(cond,val) (cond) #include -#if !_LIBC -# if !defined errno && !defined HAVE_ERRNO_DECL -extern int errno; -# endif -# define __set_errno(ev) ((errno) = (ev)) -#endif #if _LIBC || HAVE_STDLIB_H # include Modified: trunk/src/sign.c =================================================================== --- trunk/src/sign.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/sign.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -149,7 +149,7 @@ sig = malloc (sizeof (*sig)); if (!sig) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); sig->next = NULL; switch (*args) @@ -179,7 +179,7 @@ return gpg_error (GPG_ERR_INV_ENGINE); } - errno = 0; + gpg_err_set_errno (0); sig->pubkey_algo = strtol (args, &tail, 0); if (errno || args == tail || *tail != ' ') { Modified: trunk/src/verify.c =================================================================== --- trunk/src/verify.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/verify.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -227,7 +227,7 @@ { sig = calloc (1, sizeof (*sig)); if (!sig) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); if (!opd->result.signatures) opd->result.signatures = sig; if (opd->current_sig) @@ -293,7 +293,7 @@ /* Parse the pubkey algo. */ if (!end) goto parse_err_sig_fail; - errno = 0; + gpg_err_set_errno (0); sig->pubkey_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') goto parse_err_sig_fail; @@ -304,7 +304,7 @@ /* Parse the hash algo. */ if (!*end) goto parse_err_sig_fail; - errno = 0; + gpg_err_set_errno (0); sig->hash_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') goto parse_err_sig_fail; @@ -362,7 +362,7 @@ { sig->fpr = strdup (args); if (!sig->fpr) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); } return 0; } @@ -386,7 +386,7 @@ free (sig->fpr); sig->fpr = strdup (args); if (!sig->fpr) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); /* Skip the creation date. */ end = strchr (end, ' '); @@ -418,7 +418,7 @@ if (end) { /* Parse the pubkey algo. */ - errno = 0; + gpg_err_set_errno (0); sig->pubkey_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') return gpg_error (GPG_ERR_INV_ENGINE); @@ -431,7 +431,7 @@ { /* Parse the hash algo. */ - errno = 0; + gpg_err_set_errno (0); sig->hash_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') return gpg_error (GPG_ERR_INV_ENGINE); @@ -526,14 +526,14 @@ { dest = notation->value = malloc (len); if (!dest) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); } else { int cur_len = strlen (notation->value); dest = realloc (notation->value, len + strlen (notation->value)); if (!dest) - return gpg_error_from_errno (errno); + return gpg_error_from_syserror (); notation->value = dest; dest += cur_len; } Modified: trunk/src/w32-io.c =================================================================== --- trunk/src/w32-io.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/w32-io.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -166,7 +166,7 @@ TRACE1 (DEBUG_SYSIO, "gpgme:set_synchronize", hd, "DuplicateHandle failed: ec=%d", (int) GetLastError ()); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return INVALID_HANDLE_VALUE; } @@ -492,7 +492,7 @@ ctx = find_reader (fd, 1); if (!ctx) { - errno = EBADF; + gpg_err_set_errno (EBADF); return TRACE_SYSRES (-1); } if (ctx->eof_shortcut) @@ -520,7 +520,7 @@ TRACE_LOG ("EOF but ctx->eof flag not set"); return 0; } - errno = ctx->error_code; + gpg_err_set_errno (ctx->error_code); return TRACE_SYSRES (-1); } @@ -538,7 +538,7 @@ TRACE_LOG1 ("ResetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } } @@ -548,7 +548,7 @@ ctx->have_space_ev, (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } UNLOCK (ctx->mutex); @@ -837,7 +837,7 @@ TRACE_LOG1 ("ResetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } UNLOCK (ctx->mutex); @@ -851,9 +851,9 @@ { UNLOCK (ctx->mutex); if (ctx->error_code == ERROR_NO_DATA) - errno = EPIPE; + gpg_err_set_errno (EPIPE); else - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } @@ -873,7 +873,7 @@ TRACE_LOG1 ("ResetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } if (!SetEvent (ctx->have_data)) @@ -881,7 +881,7 @@ TRACE_LOG1 ("SetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } UNLOCK (ctx->mutex); @@ -908,7 +908,7 @@ { TRACE_LOG1 ("CreatePipe failed: ec=%d", (int) GetLastError ()); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } @@ -926,7 +926,7 @@ CloseHandle (rh); CloseHandle (wh); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } CloseHandle (rh); @@ -940,7 +940,7 @@ CloseHandle (rh); CloseHandle (wh); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } } @@ -957,7 +957,7 @@ CloseHandle (rh); CloseHandle (wh); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } CloseHandle (wh); @@ -971,7 +971,7 @@ CloseHandle (rh); CloseHandle (wh); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } } @@ -992,7 +992,7 @@ if (fd == -1) { - errno = EBADF; + gpg_err_set_errno (EBADF); return TRACE_SYSRES (-1); } @@ -1019,7 +1019,7 @@ { TRACE_LOG1 ("CloseHandle failed: ec=%d", (int) GetLastError ()); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } @@ -1048,7 +1048,7 @@ if (i == DIM (notify_table)) { UNLOCK (notify_table_lock); - errno = EINVAL; + gpg_err_set_errno (EINVAL); return TRACE_SYSRES (-1); } notify_table[i].fd = fd; @@ -1215,7 +1215,7 @@ DeleteFile (tmp_name); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } @@ -1245,7 +1245,7 @@ DeleteFile (tmp_name); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } /* Return the child name of this handle. */ @@ -1380,7 +1380,7 @@ TRACE_END (dbg_help, "oops ]"); TRACE_LOG ("Too many objects for WFMO!"); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } waitidx[nwait] = i; @@ -1403,7 +1403,7 @@ TRACE_END (dbg_help, "oops ]"); TRACE_LOG ("Too many objects for WFMO!"); /* FIXME: Should translate the error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } waitidx[nwait] = i; @@ -1492,7 +1492,7 @@ if (count < 0) { /* FIXME: Should determine a proper error code. */ - errno = EIO; + gpg_err_set_errno (EIO); } return TRACE_SYSRES (count); @@ -1533,7 +1533,7 @@ { TRACE_LOG1 ("DuplicateHandle failed: ec=%d\n", (int) GetLastError ()); /* FIXME: Translate error code. */ - errno = EIO; + gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } @@ -1627,7 +1627,7 @@ res = socket (domain, type, proto); if (res == INVALID_SOCKET) { - errno = wsa2errno (WSAGetLastError ()); + gpg_err_set_errno (wsa2errno (WSAGetLastError ())); return TRACE_SYSRES (-1); } @@ -1648,7 +1648,7 @@ res = connect (fd, addr, addrlen); if (res) { - errno = wsa2errno (WSAGetLastError ()); + gpg_err_set_errno (wsa2errno (WSAGetLastError ())); return TRACE_SYSRES (-1); } Modified: trunk/src/w32-util.c =================================================================== --- trunk/src/w32-util.c 2010-04-19 16:59:23 UTC (rev 1460) +++ trunk/src/w32-util.c 2010-05-06 13:39:55 UTC (rev 1461) @@ -524,7 +524,7 @@ len = strlen (tmpl); if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX")) { - errno = EINVAL; + gpg_err_set_errno (EINVAL); return -1; } @@ -561,7 +561,7 @@ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd >= 0) { - errno = save_errno; + gpg_err_set_errno (save_errno); return fd; } else if (errno != EEXIST) @@ -569,7 +569,7 @@ } /* We got out of the loop because we ran out of combinations to try. */ - errno = EEXIST; + gpg_err_set_errno (EEXIST); return -1; } From cvs at cvs.gnupg.org Thu May 6 16:49:44 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 06 May 2010 16:49:44 +0200 Subject: [svn] gpgme - r1462 - in trunk: . m4 src Message-ID: Author: marcus Date: 2010-05-06 16:49:43 +0200 (Thu, 06 May 2010) New Revision: 1462 Modified: trunk/ChangeLog trunk/configure.ac trunk/ltmain.sh trunk/m4/libtool.m4 trunk/src/ChangeLog Log: 2010-05-06 Marcus Brinkmann * configure.ac: Detect Windows CE. (HAVE_W32CE_SYSTEM): New symbol and automake conditional. * ltmain.sh, m4/libtool.m4: Patch so that it works for Windows CE. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-05-06 13:39:55 UTC (rev 1461) +++ trunk/ChangeLog 2010-05-06 14:49:43 UTC (rev 1462) @@ -1,5 +1,9 @@ 2010-05-06 Marcus Brinkmann + * configure.ac: Detect Windows CE. + (HAVE_W32CE_SYSTEM): New symbol and automake conditional. + * ltmain.sh, m4/libtool.m4: Patch so that it works for Windows CE. + * configure.ac: Require libgpg-error 1.8. 2010-03-15 Werner Koch Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-06 13:39:55 UTC (rev 1461) +++ trunk/src/ChangeLog 2010-05-06 14:49:43 UTC (rev 1462) @@ -1,3 +1,16 @@ +2010-05-06 Marcus Brinkmann + + * sign.c, data-user.c, conversion.c, debug.c, verify.c, data.c, + decrypt.c, delete.c, assuan-support.c, import.c, engine-gpgsm.c, + data-mem.c, op-support.c, w32-io.c, w32-util.c, data-compat.c: Use + gpg_error_from_syserror instead gpg_error_from_errno, and use + gpg_err_set_errno to set error number. + * setenv.c: Include and define __set_errno to use + gpg_err_set_errno. + * gpgme-tool.c (ARGP_ERR_UNKNOWN): Define to EDEADLOCK (which is + mapped in Windows CE) instead of E2BIG (which is not). + (gt_import_keys): Initialize err. + 2010-04-19 Marcus Brinkmann * assuan-support.c (my_spawn): Cast to avoid warning. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-05-06 13:39:55 UTC (rev 1461) +++ trunk/configure.ac 2010-05-06 14:49:43 UTC (rev 1462) @@ -128,7 +128,12 @@ build_w32_glib=no build_w32_qt=no case "${host}" in - *-mingw32*) + *-mingw32ce*) + have_w32ce_system=yes + ;; +esac +case "${host}" in + *-mingw32ce*|*-mingw32*) # special stuff for Windoze NT have_dosish_system=yes have_w32_system=yes @@ -185,6 +190,10 @@ 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) +if test "$have_w32ce_system" = yes; then + AC_DEFINE(HAVE_W32CE_SYSTEM,1, [Defined if we run on a W32 CE API based system]) +fi +AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes) AM_CONDITIONAL(BUILD_W32_GLIB, test "$build_w32_glib" = yes) AM_CONDITIONAL(BUILD_W32_QT, test "$build_w32_qt" = yes) Modified: trunk/ltmain.sh =================================================================== --- trunk/ltmain.sh 2010-05-06 13:39:55 UTC (rev 1461) +++ trunk/ltmain.sh 2010-05-06 14:49:43 UTC (rev 1462) @@ -65,7 +65,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.2.6 Debian-2.2.6a-4 +# $progname: (GNU libtool) 2.2.6 Debian-2.2.6a-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # @@ -73,7 +73,7 @@ PROGRAM=ltmain.sh PACKAGE=libtool -VERSION="2.2.6 Debian-2.2.6a-4" +VERSION="2.2.6 Debian-2.2.6a-1ubuntu1" TIMESTAMP="" package_revision=1.3012 @@ -5347,19 +5347,19 @@ # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_duplicate_deps ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done continue fi # $pass = conv @@ -5896,7 +5896,6 @@ if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do - path= case $deplib in -L*) path="$deplib" ;; *.la) @@ -7681,15 +7680,15 @@ wrappers_required=yes case $host in + *cegcc | *mingw32ce*) + # Disable wrappers for cegcc/mingw32ce, we are cross compiling anyway. + wrappers_required=no + ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; - *cegcc) - # Disable wrappers for cegcc, we are cross compiling anyway. - wrappers_required=no - ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no Modified: trunk/m4/libtool.m4 =================================================================== --- trunk/m4/libtool.m4 2010-05-06 13:39:55 UTC (rev 1461) +++ trunk/m4/libtool.m4 2010-05-06 14:49:43 UTC (rev 1462) @@ -3007,6 +3007,17 @@ lt_cv_file_magic_cmd='func_win32_libid' ;; + +mingw32ce*) + # Windows CE is often used with non-x86 platforms and thus the below + # mingw and cegcc checks don't work. It would be possible to + # support other architectures in these checks. However x86 is pretty + # hard coded and changing this would require quite some tests on all + # the platforms to be sure not to break something. Thus we take the + # easy way out and don't check at all. + lt_cv_deplibs_check_method=pass_all + ;; + mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', @@ -4261,9 +4272,6 @@ openbsd*) with_gnu_ld=no ;; - linux* | k*bsd*-gnu) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes From cvs at cvs.gnupg.org Thu May 6 16:49:55 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 06 May 2010 16:49:55 +0200 Subject: [svn] gpg-error - r240 - in trunk: . po Message-ID: Author: wk Date: 2010-05-06 16:49:55 +0200 (Thu, 06 May 2010) New Revision: 240 Added: trunk/po/nl.po Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/po/ChangeLog trunk/po/LINGUAS trunk/po/de.po trunk/po/vi.po Log: prepare a release Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-04-14 14:32:07 UTC (rev 239) +++ trunk/ChangeLog 2010-05-06 14:49:55 UTC (rev 240) @@ -1,3 +1,9 @@ +2010-05-06 Werner Koch + + Release 1.8. + + * configure.ac: Set LT version to C6/A6/R0. + 2010-04-14 Werner Koch * src/init.c (_gpg_w32ce_get_errno): Add native error mapping. @@ -590,7 +596,7 @@ 2004-03-09 Marcus Brinkmann * libgpg-error.spec.in (%files): Add gpg-error. Submitted by - Albrecht Dre? . + Albrecht Dre?? . * src/mkerrcodes.c (main): Fix type of argv. Return something. Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2010-04-14 14:32:07 UTC (rev 239) +++ trunk/po/ChangeLog 2010-05-06 14:49:55 UTC (rev 240) @@ -1,3 +1,11 @@ +2010-05-06 Freek de Kruijf (wk) + + * nl.po: New. + +2010-05-06 Clytie Siddall (wk) + + * vi.po: Update + 2009-08-20 Werner Koch * LINGUAS: Add zh_CN, cs and it. @@ -3,11 +11,11 @@ * cs.po: New. * it.po: New. - + 2009-08-20 Daniel Nylander (wk) * sv.po: Update 2009-08-20 Aron Xu (wk) - + * zh_CN.po: New. @@ -54,7 +62,7 @@ 2006-09-08 Werner Koch - * pl.po: Updated. + * pl.po: Updated. 2006-03-14 gettextize @@ -111,9 +119,9 @@ * remove-potcdate.sin: New file, from gettext-0.11.5. * Rules-quot: New file, from gettext-0.11.5. - - Copyright 2003 g10 Code GmbH + Copyright 2003, 2010 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. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-04-14 14:32:07 UTC (rev 239) +++ trunk/NEWS 2010-05-06 14:49:55 UTC (rev 240) @@ -1,7 +1,7 @@ -Noteworthy changes in version 1.8 +Noteworthy changes in version 1.8 (2010-05-06) ---------------------------------------------- - * Preliminary support for WindowsCE. + * Support for WindowsCE. * New option --list for gpg-error. @@ -279,7 +279,7 @@ * Initial release. - Copyright 2003, 2004, 2005 g10 Code GmbH + Copyright 2003, 2004, 2005, 2010 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 Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-04-14 14:32:07 UTC (rev 239) +++ trunk/configure.ac 2010-05-06 14:49:55 UTC (rev 240) @@ -1,5 +1,5 @@ # configure.ac for libgpg-error -# Copyright (C) 2003, 2004, 2006 g10 Code GmbH +# Copyright (C) 2003, 2004, 2006, 2010 g10 Code GmbH # # This file is part of libgpg-error. # @@ -13,9 +13,8 @@ # 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . # (Process this file with autoconf to produce a configure script.) # The following lines are used by ./autogen.sh. @@ -26,7 +25,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [1.8]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -39,8 +38,8 @@ # (Interfaces added: AGE++) # (Interfaces removed: AGE=0) # Note that added error codes don't constitute an interface change. -LIBGPG_ERROR_LT_CURRENT=5 -LIBGPG_ERROR_LT_AGE=5 +LIBGPG_ERROR_LT_CURRENT=6 +LIBGPG_ERROR_LT_AGE=6 LIBGPG_ERROR_LT_REVISION=0 AC_SUBST(LIBGPG_ERROR_LT_CURRENT) AC_SUBST(LIBGPG_ERROR_LT_AGE) Modified: trunk/po/LINGUAS =================================================================== --- trunk/po/LINGUAS 2010-04-14 14:32:07 UTC (rev 239) +++ trunk/po/LINGUAS 2010-05-06 14:49:55 UTC (rev 240) @@ -3,6 +3,7 @@ de fr it +nl pl ro sv Modified: trunk/po/de.po [not shown] Modified: trunk/po/vi.po [not shown] From cvs at cvs.gnupg.org Thu May 6 17:01:19 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 06 May 2010 17:01:19 +0200 Subject: [svn] gpg-error - r241 - tags Message-ID: Author: wk Date: 2010-05-06 17:01:18 +0200 (Thu, 06 May 2010) New Revision: 241 Added: tags/libgpg-error-1.8/ Log: Release tag From cvs at cvs.gnupg.org Thu May 6 17:02:04 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 06 May 2010 17:02:04 +0200 Subject: [svn] gpg-error - r242 - trunk Message-ID: Author: wk Date: 2010-05-06 17:02:04 +0200 (Thu, 06 May 2010) New Revision: 242 Modified: trunk/NEWS trunk/configure.ac Log: post release updates Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-05-06 15:01:18 UTC (rev 241) +++ trunk/NEWS 2010-05-06 15:02:04 UTC (rev 242) @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.9 +---------------------------------------------- + + Noteworthy changes in version 1.8 (2010-05-06) ---------------------------------------------- Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-05-06 15:01:18 UTC (rev 241) +++ trunk/configure.ac 2010-05-06 15:02:04 UTC (rev 242) @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.8]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.9]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) From cvs at cvs.gnupg.org Thu May 6 17:16:57 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 06 May 2010 17:16:57 +0200 Subject: [svn] gpgme - r1463 - trunk/src Message-ID: Author: marcus Date: 2010-05-06 17:16:57 +0200 (Thu, 06 May 2010) New Revision: 1463 Modified: trunk/src/ChangeLog trunk/src/w32-glib-io.c trunk/src/w32-io.c trunk/src/w32-qt-io.cpp trunk/src/w32-sema.c trunk/src/w32-util.c Log: 2010-05-06 Marcus Brinkmann * w32-glib-io.c, w32-io.c, w32-qt-io.cpp, w32-sema.c, w32-util.c: Do not include . Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-06 14:49:43 UTC (rev 1462) +++ trunk/src/ChangeLog 2010-05-06 15:16:57 UTC (rev 1463) @@ -1,5 +1,8 @@ 2010-05-06 Marcus Brinkmann + * w32-glib-io.c, w32-io.c, w32-qt-io.cpp, w32-sema.c, w32-util.c: + Do not include . + * sign.c, data-user.c, conversion.c, debug.c, verify.c, data.c, decrypt.c, delete.c, assuan-support.c, import.c, engine-gpgsm.c, data-mem.c, op-support.c, w32-io.c, w32-util.c, data-compat.c: Use Modified: trunk/src/w32-glib-io.c =================================================================== --- trunk/src/w32-glib-io.c 2010-05-06 14:49:43 UTC (rev 1462) +++ trunk/src/w32-glib-io.c 2010-05-06 15:16:57 UTC (rev 1463) @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include Modified: trunk/src/w32-io.c =================================================================== --- trunk/src/w32-io.c 2010-05-06 14:49:43 UTC (rev 1462) +++ trunk/src/w32-io.c 2010-05-06 15:16:57 UTC (rev 1463) @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include Modified: trunk/src/w32-qt-io.cpp =================================================================== --- trunk/src/w32-qt-io.cpp 2010-05-06 14:49:43 UTC (rev 1462) +++ trunk/src/w32-qt-io.cpp 2010-05-06 15:16:57 UTC (rev 1463) @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include Modified: trunk/src/w32-sema.c =================================================================== --- trunk/src/w32-sema.c 2010-05-06 14:49:43 UTC (rev 1462) +++ trunk/src/w32-sema.c 2010-05-06 15:16:57 UTC (rev 1463) @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include Modified: trunk/src/w32-util.c =================================================================== --- trunk/src/w32-util.c 2010-05-06 14:49:43 UTC (rev 1462) +++ trunk/src/w32-util.c 2010-05-06 15:16:57 UTC (rev 1463) @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include From cvs at cvs.gnupg.org Fri May 7 10:51:08 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 07 May 2010 10:51:08 +0200 Subject: [svn] pinentry - r230 - in trunk: . gtk+-2 Message-ID: Author: wk Date: 2010-05-07 10:51:07 +0200 (Fri, 07 May 2010) New Revision: 230 Modified: trunk/ChangeLog trunk/THANKS trunk/gtk+-2/pinentry-gtk-2.c Log: MapNotify fix Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-04-26 17:37:27 UTC (rev 229) +++ trunk/ChangeLog 2010-05-07 08:51:07 UTC (rev 230) @@ -1,3 +1,9 @@ +2010-05-03 Werner Koch + + * gtk+-2/pinentry-gtk-2.c (create_window): Use + visibility-notify-event instead of map-event. Suggested by Ed + Marten. + 2010-04-26 Werner Koch * gtk+-2/pinentry-gtk-2.c (grab_failed): New. Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2010-04-26 17:37:27 UTC (rev 229) +++ trunk/THANKS 2010-05-07 08:51:07 UTC (rev 230) @@ -4,3 +4,4 @@ Michael Nottebrock michaelnottebrock at gmx.net Peter Eisentraut peter_e at gmx.net Tobias Koenig tokoe at kde.org +Ed Marten edman007x at mac com Modified: trunk/gtk+-2/pinentry-gtk-2.c =================================================================== --- trunk/gtk+-2/pinentry-gtk-2.c 2010-04-26 17:37:27 UTC (rev 229) +++ trunk/gtk+-2/pinentry-gtk-2.c 2010-05-07 08:51:07 UTC (rev 230) @@ -309,8 +309,15 @@ g_signal_connect (G_OBJECT (win), "realize", G_CALLBACK (make_transient), NULL); + /* We need to grab the keyboard when its visible! not when its + mapped (there is a difference) */ + g_object_set (G_OBJECT(win), "events", + GDK_VISIBILITY_NOTIFY_MASK | GDK_STRUCTURE_MASK, NULL); + g_signal_connect (G_OBJECT (win), - pinentry->grab ? "map-event" : "focus-in-event", + pinentry->grab + ? "visibility-notify-event" + : "focus-in-event", G_CALLBACK (grab_keyboard), NULL); g_signal_connect (G_OBJECT (win), pinentry->grab ? "unmap-event" : "focus-out-event", From cvs at cvs.gnupg.org Fri May 7 12:36:24 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 07 May 2010 12:36:24 +0200 Subject: [svn] GnuPG - r5328 - branches/STABLE-BRANCH-2-0/g10 Message-ID: Author: wk Date: 2010-05-07 12:36:24 +0200 (Fri, 07 May 2010) New Revision: 5328 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog branches/STABLE-BRANCH-2-0/g10/import.c Log: Re-indent code and use test macros for betetr readability Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-04 15:21:47 UTC (rev 5327) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-07 10:36:24 UTC (rev 5328) @@ -1,3 +1,8 @@ +2010-05-07 Werner Koch + + * import.c (chk_self_sigs): Re-indent and slighly re-arrange code. + Use test macros for the sig class. + 2010-03-12 Werner Koch * plaintext.c (setup_plaintext_name): Do not encode pipe like Modified: branches/STABLE-BRANCH-2-0/g10/import.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/import.c 2010-05-04 15:21:47 UTC (rev 5327) +++ branches/STABLE-BRANCH-2-0/g10/import.c 2010-05-07 10:36:24 UTC (rev 5328) @@ -1348,8 +1348,8 @@ } -/**************** - * loop over the keyblock and check all self signatures. +/* + * Loop over the keyblock and check all self signatures. * Mark all user-ids with a self-signature by setting flag bit 0. * Mark all user-ids with an invalid self-signature by setting bit 1. * This works also for subkeys, here the subkey is marked. Invalid or @@ -1361,171 +1361,179 @@ chk_self_sigs( const char *fname, KBNODE keyblock, PKT_public_key *pk, u32 *keyid, int *non_self ) { - KBNODE n,knode=NULL; - PKT_signature *sig; - int rc; - u32 bsdate=0,rsdate=0; - KBNODE bsnode=NULL,rsnode=NULL; + KBNODE n, knode = NULL; + PKT_signature *sig; + int rc; + u32 bsdate=0,rsdate=0; + KBNODE bsnode = NULL, rsnode = NULL; + + (void)fname; + (void)pk; - (void)fname; - (void)pk; - - for( n=keyblock; (n = find_next_kbnode(n, 0)); ) { - if(n->pkt->pkttype==PKT_PUBLIC_SUBKEY) + for (n=keyblock; (n = find_next_kbnode (n, 0)); ) + { + if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) { - knode=n; - bsdate=0; - rsdate=0; - bsnode=NULL; - rsnode=NULL; + knode = n; + bsdate = 0; + rsdate = 0; + bsnode = NULL; + rsnode = NULL; continue; } - else if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - sig = n->pkt->pkt.signature; - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { - /* This just caches the sigs for later use. That way we - import a fully-cached key which speeds things up. */ - if(!opt.no_sig_cache) - check_key_signature(keyblock,n,NULL); + if ( n->pkt->pkttype != PKT_SIGNATURE ) + continue; + + sig = n->pkt->pkt.signature; + if ( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] ) + { + *non_self = 1; + continue; + } - if( IS_UID_SIG(sig) || IS_UID_REV(sig) ) - { - KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); - if( !unode ) - { - log_error( _("key %s: no user ID for signature\n"), - keystr(keyid)); - return -1; /* the complete keyblock is invalid */ - } + /* This just caches the sigs for later use. That way we + import a fully-cached key which speeds things up. */ + if (!opt.no_sig_cache) + check_key_signature (keyblock, n, NULL); + + if ( IS_UID_SIG(sig) || IS_UID_REV(sig) ) + { + KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); + if ( !unode ) + { + log_error( _("key %s: no user ID for signature\n"), + keystr(keyid)); + return -1; /* The complete keyblock is invalid. */ + } + + /* If it hasn't been marked valid yet, keep trying. */ + if (!(unode->flag&1)) + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if ( opt.verbose ) + { + char *p = utf8_to_native + (unode->pkt->pkt.user_id->name, + strlen (unode->pkt->pkt.user_id->name),0); + log_info (gpg_err_code(rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key " + "algorithm on user ID \"%s\"\n"): + _("key %s: invalid self-signature " + "on user ID \"%s\"\n"), + keystr (keyid),p); + xfree (p); + } + } + else + unode->flag |= 1; /* Mark that signature checked. */ + } + } + else if ( IS_SUBKEY_SIG (sig) ) + { + /* Note that this works based solely on the timestamps like + the rest of gpg. If the standard gets revocation + targets, this may need to be revised. */ - /* If it hasn't been marked valid yet, keep trying */ - if(!(unode->flag&1)) { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if( opt.verbose ) - { - char *p=utf8_to_native(unode->pkt->pkt.user_id->name, - strlen(unode->pkt->pkt.user_id->name),0); - log_info( rc == G10ERR_PUBKEY_ALGO ? - _("key %s: unsupported public key " - "algorithm on user ID \"%s\"\n"): - _("key %s: invalid self-signature " - "on user ID \"%s\"\n"), - keystr(keyid),p); - xfree(p); - } - } - else - unode->flag |= 1; /* mark that signature checked */ - } - } - else if( sig->sig_class == 0x18 ) { - /* Note that this works based solely on the timestamps - like the rest of gpg. If the standard gets - revocation targets, this may need to be revised. */ - - if( !knode ) - { - if(opt.verbose) - log_info( _("key %s: no subkey for key binding\n"), - keystr(keyid)); - n->flag |= 4; /* delete this */ - } - else - { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if(opt.verbose) - log_info(rc == G10ERR_PUBKEY_ALGO ? - _("key %s: unsupported public key" - " algorithm\n"): - _("key %s: invalid subkey binding\n"), - keystr(keyid)); - n->flag|=4; - } - else - { - /* It's valid, so is it newer? */ - if(sig->timestamp>=bsdate) { - knode->flag |= 1; /* the subkey is valid */ - if(bsnode) - { - bsnode->flag|=4; /* Delete the last binding - sig since this one is - newer */ - if(opt.verbose) - log_info(_("key %s: removed multiple subkey" - " binding\n"),keystr(keyid)); - } - - bsnode=n; - bsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - else if( sig->sig_class == 0x28 ) { - /* We don't actually mark the subkey as revoked right - now, so just check that the revocation sig is the - most recent valid one. Note that we don't care if - the binding sig is newer than the revocation sig. - See the comment in getkey.c:merge_selfsigs_subkey for - more */ - if( !knode ) - { - if(opt.verbose) - log_info( _("key %s: no subkey for key revocation\n"), - keystr(keyid)); - n->flag |= 4; /* delete this */ - } - else - { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if(opt.verbose) - log_info(rc == G10ERR_PUBKEY_ALGO ? - _("key %s: unsupported public" - " key algorithm\n"): - _("key %s: invalid subkey revocation\n"), - keystr(keyid)); - n->flag|=4; - } - else - { - /* It's valid, so is it newer? */ - if(sig->timestamp>=rsdate) - { - if(rsnode) - { - rsnode->flag|=4; /* Delete the last revocation - sig since this one is - newer */ - if(opt.verbose) - log_info(_("key %s: removed multiple subkey" - " revocation\n"),keystr(keyid)); - } - - rsnode=n; - rsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - } - else - *non_self=1; + if ( !knode ) + { + if (opt.verbose) + log_info (_("key %s: no subkey for key binding\n"), + keystr (keyid)); + n->flag |= 4; /* delete this */ + } + else + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if (opt.verbose) + log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key" + " algorithm\n"): + _("key %s: invalid subkey binding\n"), + keystr (keyid)); + n->flag |= 4; + } + else + { + /* It's valid, so is it newer? */ + if (sig->timestamp >= bsdate) + { + knode->flag |= 1; /* The subkey is valid. */ + if (bsnode) + { + /* Delete the last binding sig since this + one is newer */ + bsnode->flag |= 4; + if (opt.verbose) + log_info (_("key %s: removed multiple subkey" + " binding\n"),keystr(keyid)); + } + + bsnode = n; + bsdate = sig->timestamp; + } + else + n->flag |= 4; /* older */ + } + } + } + else if ( IS_SUBKEY_REV (sig) ) + { + /* We don't actually mark the subkey as revoked right now, + so just check that the revocation sig is the most recent + valid one. Note that we don't care if the binding sig is + newer than the revocation sig. See the comment in + getkey.c:merge_selfsigs_subkey for more. */ + if ( !knode ) + { + if (opt.verbose) + log_info (_("key %s: no subkey for key revocation\n"), + keystr(keyid)); + n->flag |= 4; /* delete this */ + } + else + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if(opt.verbose) + log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public" + " key algorithm\n"): + _("key %s: invalid subkey revocation\n"), + keystr(keyid)); + n->flag |= 4; + } + else + { + /* It's valid, so is it newer? */ + if (sig->timestamp >= rsdate) + { + if (rsnode) + { + /* Delete the last revocation sig since + this one is newer. */ + rsnode->flag |= 4; + if (opt.verbose) + log_info (_("key %s: removed multiple subkey" + " revocation\n"),keystr(keyid)); + } + + rsnode = n; + rsdate = sig->timestamp; + } + else + n->flag |= 4; /* older */ + } + } + } } - return 0; + return 0; } /**************** From cvs at cvs.gnupg.org Fri May 7 13:15:26 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 07 May 2010 13:15:26 +0200 Subject: [svn] GnuPG - r5329 - branches/STABLE-BRANCH-2-0/g10 Message-ID: Author: wk Date: 2010-05-07 13:15:26 +0200 (Fri, 07 May 2010) New Revision: 5329 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog branches/STABLE-BRANCH-2-0/g10/import.c Log: Fix for bug 1223 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-07 10:36:24 UTC (rev 5328) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-07 11:15:26 UTC (rev 5329) @@ -1,5 +1,8 @@ 2010-05-07 Werner Koch + * import.c (chk_self_sigs): Check direct key signatures. Fixes + bug#1223. + * import.c (chk_self_sigs): Re-indent and slighly re-arrange code. Use test macros for the sig class. Modified: branches/STABLE-BRANCH-2-0/g10/import.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/import.c 2010-05-07 10:36:24 UTC (rev 5328) +++ branches/STABLE-BRANCH-2-0/g10/import.c 2010-05-07 11:15:26 UTC (rev 5329) @@ -1431,6 +1431,19 @@ unode->flag |= 1; /* Mark that signature checked. */ } } + else if (IS_KEY_SIG (sig)) + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if (opt.verbose) + log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key algorithm\n"): + _("key %s: invalid direct key signature\n"), + keystr (keyid)); + n->flag |= 4; + } + } else if ( IS_SUBKEY_SIG (sig) ) { /* Note that this works based solely on the timestamps like From cvs at cvs.gnupg.org Fri May 7 14:17:19 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 07 May 2010 14:17:19 +0200 Subject: [svn] GnuPG - r5330 - branches/STABLE-BRANCH-2-0/g10 Message-ID: Author: wk Date: 2010-05-07 14:17:18 +0200 (Fri, 07 May 2010) New Revision: 5330 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog branches/STABLE-BRANCH-2-0/g10/import.c Log: Take care of already existing bogus 0x1f signatures. Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-07 11:15:26 UTC (rev 5329) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-07 12:17:18 UTC (rev 5330) @@ -2,6 +2,8 @@ * import.c (chk_self_sigs): Check direct key signatures. Fixes bug#1223. + (fix_bad_direct_key_sigs): New. + (import_one): Use it here. * import.c (chk_self_sigs): Re-indent and slighly re-arrange code. Use test macros for the sig class. Modified: branches/STABLE-BRANCH-2-0/g10/import.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/import.c 2010-05-07 11:15:26 UTC (rev 5329) +++ branches/STABLE-BRANCH-2-0/g10/import.c 2010-05-07 12:17:18 UTC (rev 5330) @@ -520,6 +520,46 @@ } +/* Versions of GnuPG before 1.4.11 and 2.0.16 allowed to import bogus + direct key signatures. A side effect of this was that a later + import of the same good direct key signatures was not possible + because the cmp_signature check in merge_blocks considered them + equal. Although direct key signatures are now checked during + import, there might still be bogus signatures sitting in a keyring. + We need to detect and delete them before doing a merge. This + fucntion returns the number of removed sigs. */ +static int +fix_bad_direct_key_sigs (KBNODE keyblock, u32 *keyid) +{ + gpg_error_t err; + KBNODE node; + int count = 0; + + for (node = keyblock->next; node; node=node->next) + { + if (node->pkt->pkttype == PKT_USER_ID) + break; + if (node->pkt->pkttype == PKT_SIGNATURE + && IS_KEY_SIG (node->pkt->pkt.signature)) + { + err = check_key_signature (keyblock, node, NULL); + if (err && gpg_err_code (err) != GPG_ERR_PUBKEY_ALGO ) + { + /* If we don't know the error, we can't decide; this is + not a problem because cmp_signature can't compare the + signature either. */ + log_info ("key %s: invalid direct key signature removed\n", + keystr (keyid)); + delete_kbnode (node); + count++; + } + } + } + + return count; +} + + static void print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason) { @@ -886,10 +926,15 @@ goto leave; } + /* Make sure the original direct key sigs are all sane. */ + n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid); + if (n_sigs_cleaned) + commit_kbnode (&keyblock_orig); + /* and try to merge the block */ clear_kbnode_flags( keyblock_orig ); clear_kbnode_flags( keyblock ); - n_uids = n_sigs = n_subk = n_sigs_cleaned = n_uids_cleaned = 0; + n_uids = n_sigs = n_subk = n_uids_cleaned = 0; rc = merge_blocks( fname, keyblock_orig, keyblock, keyid, &n_uids, &n_sigs, &n_subk ); if( rc ) From cvs at cvs.gnupg.org Fri May 7 14:32:07 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 07 May 2010 14:32:07 +0200 Subject: [svn] GnuPG - r5331 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2010-05-07 14:32:06 +0200 (Fri, 07 May 2010) New Revision: 5331 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/import.c Log: Fix for bug 1223 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-05-07 12:17:18 UTC (rev 5330) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-05-07 12:32:06 UTC (rev 5331) @@ -1,3 +1,10 @@ +2010-05-07 Werner Koch + + * import.c (chk_self_sigs): Check direct key signatures. Fixes + bug#1223. + (fix_bad_direct_key_sigs): New. + (import_one): Call it. + 2010-03-26 David Shaw * plaintext.c (handle_plaintext): Make sure that the stdout flush Modified: branches/STABLE-BRANCH-1-4/g10/import.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/import.c 2010-05-07 12:17:18 UTC (rev 5330) +++ branches/STABLE-BRANCH-1-4/g10/import.c 2010-05-07 12:32:06 UTC (rev 5331) @@ -516,6 +516,46 @@ } +/* Versions of GnuPG before 1.4.11 and 2.0.16 allowed to import bogus + direct key signatures. A side effect of this was that a later + import of the same good direct key signatures was not possible + because the cmp_signature check in merge_blocks considered them + equal. Although direct key signatures are now checked during + import, there might still be bogus signatures sitting in a keyring. + We need to detect and delete them before doing a merge. This + fucntion returns the number of removed sigs. */ +static int +fix_bad_direct_key_sigs (KBNODE keyblock, u32 *keyid) +{ + int rc; + int count = 0; + KBNODE node; + + for (node = keyblock->next; node; node=node->next) + { + if (node->pkt->pkttype == PKT_USER_ID) + break; + if (node->pkt->pkttype == PKT_SIGNATURE + && IS_KEY_SIG (node->pkt->pkt.signature)) + { + rc = check_key_signature (keyblock, node, NULL); + if (rc && rc != G10ERR_PUBKEY_ALGO ) + { + /* If we don't know the error, we can't decide; this is + not a problem because cmp_signature can't compare the + signature either. */ + log_info ("key %s: invalid direct key signature removed\n", + keystr (keyid)); + delete_kbnode (node); + count++; + } + } + } + + return count; +} + + static void print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason) { @@ -876,10 +916,15 @@ goto leave; } + /* Make sure the original direct key sigs are all sane. */ + n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid); + if (n_sigs_cleaned) + commit_kbnode (&keyblock_orig); + /* and try to merge the block */ clear_kbnode_flags( keyblock_orig ); clear_kbnode_flags( keyblock ); - n_uids = n_sigs = n_subk = n_sigs_cleaned = n_uids_cleaned = 0; + n_uids = n_sigs = n_subk = n_uids_cleaned = 0; rc = merge_blocks( fname, keyblock_orig, keyblock, keyid, &n_uids, &n_sigs, &n_subk ); if( rc ) @@ -1397,6 +1442,19 @@ unode->flag |= 1; /* mark that signature checked */ } } + else if (IS_KEY_SIG (sig)) + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if (opt.verbose) + log_info (rc == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key algorithm\n"): + _("key %s: invalid direct key signature\n"), + keystr (keyid)); + n->flag |= 4; + } + } else if( sig->sig_class == 0x18 ) { /* Note that this works based solely on the timestamps like the rest of gpg. If the standard gets From cvs at cvs.gnupg.org Fri May 7 15:13:56 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 07 May 2010 15:13:56 +0200 Subject: [svn] GnuPG - r5332 - in trunk: g10 tests/openpgp Message-ID: Author: wk Date: 2010-05-07 15:13:56 +0200 (Fri, 07 May 2010) New Revision: 5332 Added: trunk/tests/openpgp/bug1223-bogus.asc trunk/tests/openpgp/bug1223-good.asc Modified: trunk/g10/ChangeLog trunk/g10/import.c trunk/tests/openpgp/ChangeLog trunk/tests/openpgp/Makefile.am trunk/tests/openpgp/import.test Log: Fix for bug 1223 Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2010-05-07 12:32:06 UTC (rev 5331) +++ trunk/g10/ChangeLog 2010-05-07 13:13:56 UTC (rev 5332) @@ -1,3 +1,11 @@ +2010-05-07 Werner Koch + + * import.c (fix_bad_direct_key_sigs): New. + (import_one): Call it. + (chk_self_sigs): Re-indent, slighly re-arrange code, use test + macros for the sig class. Check direct key signatures. Fixes + bug#1223. + 2010-04-27 Werner Koch * passphrase.c (gpg_format_keydesc): New. Modified: trunk/tests/openpgp/ChangeLog =================================================================== --- trunk/tests/openpgp/ChangeLog 2010-05-07 12:32:06 UTC (rev 5331) +++ trunk/tests/openpgp/ChangeLog 2010-05-07 13:13:56 UTC (rev 5332) @@ -1,3 +1,8 @@ +2010-05-07 Werner Koch + + * import.test: Add test case for bug#1223. + * bug1223-good.asc, bug1223-bogus.asc: New. + 2009-12-21 Werner Koch * Makefile.am (required_pgms): New. Modified: trunk/g10/import.c =================================================================== --- trunk/g10/import.c 2010-05-07 12:32:06 UTC (rev 5331) +++ trunk/g10/import.c 2010-05-07 13:13:56 UTC (rev 5332) @@ -521,6 +521,46 @@ } +/* Versions of GnuPG before 1.4.11 and 2.0.16 allowed to import bogus + direct key signatures. A side effect of this was that a later + import of the same good direct key signatures was not possible + because the cmp_signature check in merge_blocks considered them + equal. Although direct key signatures are now checked during + import, there might still be bogus signatures sitting in a keyring. + We need to detect and delete them before doing a merge. This + fucntion returns the number of removed sigs. */ +static int +fix_bad_direct_key_sigs (kbnode_t keyblock, u32 *keyid) +{ + gpg_error_t err; + kbnode_t node; + int count = 0; + + for (node = keyblock->next; node; node=node->next) + { + if (node->pkt->pkttype == PKT_USER_ID) + break; + if (node->pkt->pkttype == PKT_SIGNATURE + && IS_KEY_SIG (node->pkt->pkt.signature)) + { + err = check_key_signature (keyblock, node, NULL); + if (err && gpg_err_code (err) != GPG_ERR_PUBKEY_ALGO ) + { + /* If we don't know the error, we can't decide; this is + not a problem because cmp_signature can't compare the + signature either. */ + log_info ("key %s: invalid direct key signature removed\n", + keystr (keyid)); + delete_kbnode (node); + count++; + } + } + } + + return count; +} + + static void print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason) { @@ -887,10 +927,15 @@ goto leave; } + /* Make sure the original direct key sigs are all sane. */ + n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid); + if (n_sigs_cleaned) + commit_kbnode (&keyblock_orig); + /* and try to merge the block */ clear_kbnode_flags( keyblock_orig ); clear_kbnode_flags( keyblock ); - n_uids = n_sigs = n_subk = n_sigs_cleaned = n_uids_cleaned = 0; + n_uids = n_sigs = n_subk = n_uids_cleaned = 0; rc = merge_blocks( fname, keyblock_orig, keyblock, keyid, &n_uids, &n_sigs, &n_subk ); if( rc ) @@ -1354,8 +1399,8 @@ } -/**************** - * loop over the keyblock and check all self signatures. +/* + * Loop over the keyblock and check all self signatures. * Mark all user-ids with a self-signature by setting flag bit 0. * Mark all user-ids with an invalid self-signature by setting bit 1. * This works also for subkeys, here the subkey is marked. Invalid or @@ -1364,176 +1409,198 @@ * in this keyblock. */ static int -chk_self_sigs( const char *fname, KBNODE keyblock, +chk_self_sigs (const char *fname, kbnode_t keyblock, PKT_public_key *pk, u32 *keyid, int *non_self ) { - KBNODE n,knode=NULL; - PKT_signature *sig; - int rc; - u32 bsdate=0,rsdate=0; - KBNODE bsnode=NULL,rsnode=NULL; + kbnode_t n, knode = NULL; + PKT_signature *sig; + int rc; + u32 bsdate=0, rsdate=0; + kbnode_t bsnode = NULL, rsnode = NULL; + + (void)fname; + (void)pk; - (void)fname; - (void)pk; - - for( n=keyblock; (n = find_next_kbnode(n, 0)); ) { - if(n->pkt->pkttype==PKT_PUBLIC_SUBKEY) + for (n=keyblock; (n = find_next_kbnode (n, 0)); ) + { + if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) { - knode=n; - bsdate=0; - rsdate=0; - bsnode=NULL; - rsnode=NULL; + knode = n; + bsdate = 0; + rsdate = 0; + bsnode = NULL; + rsnode = NULL; continue; } - else if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - sig = n->pkt->pkt.signature; - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { - /* This just caches the sigs for later use. That way we - import a fully-cached key which speeds things up. */ - if(!opt.no_sig_cache) - check_key_signature(keyblock,n,NULL); + if ( n->pkt->pkttype != PKT_SIGNATURE ) + continue; + + sig = n->pkt->pkt.signature; + if ( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] ) + { + *non_self = 1; + continue; + } - if( IS_UID_SIG(sig) || IS_UID_REV(sig) ) - { - KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); - if( !unode ) - { - log_error( _("key %s: no user ID for signature\n"), - keystr(keyid)); - return -1; /* the complete keyblock is invalid */ - } + /* This just caches the sigs for later use. That way we + import a fully-cached key which speeds things up. */ + if (!opt.no_sig_cache) + check_key_signature (keyblock, n, NULL); + + if ( IS_UID_SIG(sig) || IS_UID_REV(sig) ) + { + KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); + if ( !unode ) + { + log_error( _("key %s: no user ID for signature\n"), + keystr(keyid)); + return -1; /* The complete keyblock is invalid. */ + } + + /* If it hasn't been marked valid yet, keep trying. */ + if (!(unode->flag&1)) + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if ( opt.verbose ) + { + char *p = utf8_to_native + (unode->pkt->pkt.user_id->name, + strlen (unode->pkt->pkt.user_id->name),0); + log_info (gpg_err_code(rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key " + "algorithm on user ID \"%s\"\n"): + _("key %s: invalid self-signature " + "on user ID \"%s\"\n"), + keystr (keyid),p); + xfree (p); + } + } + else + unode->flag |= 1; /* Mark that signature checked. */ + } + } + else if (IS_KEY_SIG (sig)) + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if (opt.verbose) + log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key algorithm\n"): + _("key %s: invalid direct key signature\n"), + keystr (keyid)); + n->flag |= 4; + } + } + else if ( IS_SUBKEY_SIG (sig) ) + { + /* Note that this works based solely on the timestamps like + the rest of gpg. If the standard gets revocation + targets, this may need to be revised. */ - /* If it hasn't been marked valid yet, keep trying */ - if(!(unode->flag&1)) { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if( opt.verbose ) - { - char *p=utf8_to_native(unode->pkt->pkt.user_id->name, - strlen(unode->pkt->pkt.user_id->name),0); - log_info( rc == G10ERR_PUBKEY_ALGO ? - _("key %s: unsupported public key " - "algorithm on user ID \"%s\"\n"): - _("key %s: invalid self-signature " - "on user ID \"%s\"\n"), - keystr(keyid),p); - xfree(p); - } - } - else - unode->flag |= 1; /* mark that signature checked */ - } - } - else if( sig->sig_class == 0x18 ) { - /* Note that this works based solely on the timestamps - like the rest of gpg. If the standard gets - revocation targets, this may need to be revised. */ - - if( !knode ) - { - if(opt.verbose) - log_info( _("key %s: no subkey for key binding\n"), - keystr(keyid)); - n->flag |= 4; /* delete this */ - } - else - { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if(opt.verbose) - log_info(rc == G10ERR_PUBKEY_ALGO ? - _("key %s: unsupported public key" - " algorithm\n"): - _("key %s: invalid subkey binding\n"), - keystr(keyid)); - n->flag|=4; - } - else - { - /* It's valid, so is it newer? */ - if(sig->timestamp>=bsdate) { - knode->flag |= 1; /* the subkey is valid */ - if(bsnode) - { - bsnode->flag|=4; /* Delete the last binding - sig since this one is - newer */ - if(opt.verbose) - log_info(_("key %s: removed multiple subkey" - " binding\n"),keystr(keyid)); - } - - bsnode=n; - bsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - else if( sig->sig_class == 0x28 ) { - /* We don't actually mark the subkey as revoked right - now, so just check that the revocation sig is the - most recent valid one. Note that we don't care if - the binding sig is newer than the revocation sig. - See the comment in getkey.c:merge_selfsigs_subkey for - more */ - if( !knode ) - { - if(opt.verbose) - log_info( _("key %s: no subkey for key revocation\n"), - keystr(keyid)); - n->flag |= 4; /* delete this */ - } - else - { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if(opt.verbose) - log_info(rc == G10ERR_PUBKEY_ALGO ? - _("key %s: unsupported public" - " key algorithm\n"): - _("key %s: invalid subkey revocation\n"), - keystr(keyid)); - n->flag|=4; - } - else - { - /* It's valid, so is it newer? */ - if(sig->timestamp>=rsdate) - { - if(rsnode) - { - rsnode->flag|=4; /* Delete the last revocation - sig since this one is - newer */ - if(opt.verbose) - log_info(_("key %s: removed multiple subkey" - " revocation\n"),keystr(keyid)); - } - - rsnode=n; - rsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - } - else - *non_self=1; + if ( !knode ) + { + if (opt.verbose) + log_info (_("key %s: no subkey for key binding\n"), + keystr (keyid)); + n->flag |= 4; /* delete this */ + } + else + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if (opt.verbose) + log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key" + " algorithm\n"): + _("key %s: invalid subkey binding\n"), + keystr (keyid)); + n->flag |= 4; + } + else + { + /* It's valid, so is it newer? */ + if (sig->timestamp >= bsdate) + { + knode->flag |= 1; /* The subkey is valid. */ + if (bsnode) + { + /* Delete the last binding sig since this + one is newer */ + bsnode->flag |= 4; + if (opt.verbose) + log_info (_("key %s: removed multiple subkey" + " binding\n"),keystr(keyid)); + } + + bsnode = n; + bsdate = sig->timestamp; + } + else + n->flag |= 4; /* older */ + } + } + } + else if ( IS_SUBKEY_REV (sig) ) + { + /* We don't actually mark the subkey as revoked right now, + so just check that the revocation sig is the most recent + valid one. Note that we don't care if the binding sig is + newer than the revocation sig. See the comment in + getkey.c:merge_selfsigs_subkey for more. */ + if ( !knode ) + { + if (opt.verbose) + log_info (_("key %s: no subkey for key revocation\n"), + keystr(keyid)); + n->flag |= 4; /* delete this */ + } + else + { + rc = check_key_signature (keyblock, n, NULL); + if ( rc ) + { + if(opt.verbose) + log_info (gpg_err_code (rc) == G10ERR_PUBKEY_ALGO ? + _("key %s: unsupported public" + " key algorithm\n"): + _("key %s: invalid subkey revocation\n"), + keystr(keyid)); + n->flag |= 4; + } + else + { + /* It's valid, so is it newer? */ + if (sig->timestamp >= rsdate) + { + if (rsnode) + { + /* Delete the last revocation sig since + this one is newer. */ + rsnode->flag |= 4; + if (opt.verbose) + log_info (_("key %s: removed multiple subkey" + " revocation\n"),keystr(keyid)); + } + + rsnode = n; + rsdate = sig->timestamp; + } + else + n->flag |= 4; /* older */ + } + } + } } - return 0; + return 0; } + /**************** * delete all parts which are invalid and those signatures whose * public key algorithm is not available in this implemenation; Modified: trunk/tests/openpgp/Makefile.am =================================================================== --- trunk/tests/openpgp/Makefile.am 2010-05-07 12:32:06 UTC (rev 5331) +++ trunk/tests/openpgp/Makefile.am 2010-05-07 13:13:56 UTC (rev 5332) @@ -40,7 +40,8 @@ TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \ plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \ pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc \ - gpg.conf.tmpl bug537-test.data.asc bug894-test.asc + gpg.conf.tmpl bug537-test.data.asc bug894-test.asc \ + bug1223-good.asc bug1223-bogus.asc DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large Added: trunk/tests/openpgp/bug1223-bogus.asc =================================================================== --- trunk/tests/openpgp/bug1223-bogus.asc (rev 0) +++ trunk/tests/openpgp/bug1223-bogus.asc 2010-05-07 13:13:56 UTC (rev 5332) @@ -0,0 +1,21 @@ +Bogus test key for bug 1223 (Designated revoker sigs are not properly merged) +Thanks to Daniel Kahn Gillmor for providing the test keys. + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.10 (GNU/Linux) + +mI0ES+OoSQEEAJUZ/+fC6DXN2X7Wxl4Huud/+i2qP1hcq+Qnbr7hVCKEnn0edYl+ +6xfsKmAMBjl+qTZxPSDSx4r3ciMiIbnvXFtlBAQmji86kqoR6fm9s8BN7LTq7+2/ +c2FHVF67D7zES7WgHc4i7CfiZnwXgkLvi5b1jBt+MTAOrFhdobxoy6/XABEBAAGI +twQfAQIAIQUCS+OsRRcMgAEAAAAAAAAAAAAAAAAAAAAAAAAAAQIHAAAKCRA0t9EL +wQjoOrRXBACBqhigTcj8pJY14AkjV+ZzUbm55kJRDPdU7NQ1PSvczm7HZaL3b8Lr +Psa5c5+caVLjsGWkQycQl7lUIGU84KoUfwACQKVVLkqJz8LkL54lLcwkG70+1NH5 +xoSNcHHVbYtqDLNeCOq5jEIoXuz44wiWVEfF+/B115PvgwZ63pjH1rRGVGVzdCBL +ZXkgRGVtb25zdHJhdGluZyBSZXZva2VyIFRyb3VibGUgKERPIE5PVCBVU0UpIDx0 +ZXN0QGV4YW1wbGUubmV0Poi+BBMBAgAoBQJL46hJAhsDBQkACTqABgsJCAcDAgYV +CAIJCgsEFgIDAQIeAQIXgAAKCRA0t9ELwQjoOgLpA/9/si2QYmietY9a6VlAmMri +mhZeqo6zyn8zrO9RGU7+8jmeb5nVnXw1YmZcw2fiJgI9+tTMkTfomyR6k0EDvcEu +2Mg3USkVnJfrrkPjSL9EajW6VpOUNxlox3ZT1oyEo3OOnVF1gC1reWYfy7Ns9zIB +1leLXbMr86zYdCoXp0Xu4g== +=YV5g +-----END PGP PUBLIC KEY BLOCK----- Added: trunk/tests/openpgp/bug1223-good.asc =================================================================== --- trunk/tests/openpgp/bug1223-good.asc (rev 0) +++ trunk/tests/openpgp/bug1223-good.asc 2010-05-07 13:13:56 UTC (rev 5332) @@ -0,0 +1,20 @@ +Good test key for bug 1223 (Designated revoker sigs are not properly merged) + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.10 (GNU/Linux) + +mI0ES+OoSQEEAJUZ/+fC6DXN2X7Wxl4Huud/+i2qP1hcq+Qnbr7hVCKEnn0edYl+ +6xfsKmAMBjl+qTZxPSDSx4r3ciMiIbnvXFtlBAQmji86kqoR6fm9s8BN7LTq7+2/ +c2FHVF67D7zES7WgHc4i7CfiZnwXgkLvi5b1jBt+MTAOrFhdobxoy6/XABEBAAGI +twQfAQIAIQUCS+OsRRcMgAEO5b6XkoLYC591QPHM0u2U0hc56QIHAAAKCRA0t9EL +wQjoOrRXBACBqhigTcj8pJY14AkjV+ZzUbm55kJRDPdU7NQ1PSvczm7HZaL3b8Lr +Psa5c5+caVLjsGWkQycQl7lUIGU84KoUfwACQKVVLkqJz8LkL54lLcwkG70+1NH5 +xoSNcHHVbYtqDLNeCOq5jEIoXuz44wiWVEfF+/B115PvgwZ63pjH1rRGVGVzdCBL +ZXkgRGVtb25zdHJhdGluZyBSZXZva2VyIFRyb3VibGUgKERPIE5PVCBVU0UpIDx0 +ZXN0QGV4YW1wbGUubmV0Poi+BBMBAgAoBQJL46hJAhsDBQkACTqABgsJCAcDAgYV +CAIJCgsEFgIDAQIeAQIXgAAKCRA0t9ELwQjoOgLpA/9/si2QYmietY9a6VlAmMri +mhZeqo6zyn8zrO9RGU7+8jmeb5nVnXw1YmZcw2fiJgI9+tTMkTfomyR6k0EDvcEu +2Mg3USkVnJfrrkPjSL9EajW6VpOUNxlox3ZT1oyEo3OOnVF1gC1reWYfy7Ns9zIB +1leLXbMr86zYdCoXp0Xu4g== +=xsEd +-----END PGP PUBLIC KEY BLOCK----- Modified: trunk/tests/openpgp/import.test =================================================================== --- trunk/tests/openpgp/import.test 2010-05-07 12:32:06 UTC (rev 5331) +++ trunk/tests/openpgp/import.test 2010-05-07 13:13:56 UTC (rev 5332) @@ -18,9 +18,24 @@ fi +boguskey=$srcdir/bug1223-bogus.asc +goodkey=$srcdir/bug1223-good.asc +keyid=0xC108E83A +info "Checking bug 1223: designated revoker sigs are not properly merged." +$GPG --delete-key --batch --yes $keyid 2>/dev/null || true +$GPG --import $boguskey || true +$GPG --import $goodkey || true +if $GPG --list-keys --with-colons $keyid \ + | grep '^rvk:.*:0EE5BE979282D80B9F7540F1CCD2ED94D21739E9:' >/dev/null; then + : +else + error "$goodkey: import failed (bug 1223)" +fi + + From cvs at cvs.gnupg.org Fri May 7 19:26:10 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 07 May 2010 19:26:10 +0200 Subject: [svn] pinentry - r231 - in trunk: . gtk+-2 Message-ID: Author: wk Date: 2010-05-07 19:26:10 +0200 (Fri, 07 May 2010) New Revision: 231 Modified: trunk/ChangeLog trunk/NEWS trunk/gtk+-2/pinentry-gtk-2.c Log: Fix bug#1162. This finally allows me to use the pinentry on my kfreebsd laptop without fearing it pops up below other windows and grabs the keyboard. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-05-07 08:51:07 UTC (rev 230) +++ trunk/ChangeLog 2010-05-07 17:26:10 UTC (rev 231) @@ -1,3 +1,8 @@ +2010-05-07 Werner Koch + + * gtk+-2/pinentry-gtk-2.c (create_window): Keep the window above + and make sure it has the focus. Fixes bug#1162. + 2010-05-03 Werner Koch * gtk+-2/pinentry-gtk-2.c (create_window): Use Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-05-07 08:51:07 UTC (rev 230) +++ trunk/NEWS 2010-05-07 17:26:10 UTC (rev 231) @@ -3,7 +3,10 @@ * The W32 pinentry now supports WindowsCE. + * The GTK pinentry now always sticks to the top and properly grabs + the keyboard. + Noteworthy changes in version 0.8.0 (2010-03-03) ------------------------------------------------ Modified: trunk/gtk+-2/pinentry-gtk-2.c =================================================================== --- trunk/gtk+-2/pinentry-gtk-2.c 2010-05-07 08:51:07 UTC (rev 230) +++ trunk/gtk+-2/pinentry-gtk-2.c 2010-05-07 17:26:10 UTC (rev 231) @@ -510,9 +510,10 @@ } gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER); + gtk_window_set_keep_above (GTK_WINDOW (win), TRUE); + gtk_widget_show_all (win); + gtk_window_present (GTK_WINDOW (win)); /* Make sure it has the focus. */ - gtk_widget_show_all(win); - return win; } From cvs at cvs.gnupg.org Sat May 8 01:22:39 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Sat, 08 May 2010 01:22:39 +0200 Subject: [svn] gpgme - r1467 - in trunk: . m4 Message-ID: Author: wk Date: 2010-05-08 01:22:38 +0200 (Sat, 08 May 2010) New Revision: 1467 Modified: trunk/ChangeLog trunk/configure.ac trunk/m4/ChangeLog trunk/m4/libassuan.m4 Log: Better detection of a missing libassuan Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-05-07 02:14:04 UTC (rev 1466) +++ trunk/ChangeLog 2010-05-07 23:22:38 UTC (rev 1467) @@ -1,3 +1,7 @@ +2010-05-07 Werner Koch + + * configure.ac: Change checks to always require libassuan. + 2010-05-07 Marcus Brinkmann * autogen.sh: Update the thing. Modified: trunk/m4/ChangeLog =================================================================== --- trunk/m4/ChangeLog 2010-05-07 02:14:04 UTC (rev 1466) +++ trunk/m4/ChangeLog 2010-05-07 23:22:38 UTC (rev 1467) @@ -1,3 +1,7 @@ +2010-05-07 Werner Koch + + * libassuan.m4: Update from libassuan svn. + 2009-11-10 Marcus Brinkmann * libassuan.m4: Fix LIBASSUAN_VERSION. @@ -23,7 +27,7 @@ * pth.m4: Disable _ac_pth_line, and don't fail if Pth is not found. - + * glibc21.m4: New file. * gpg-error.m4: New file. * pth.m4: New file. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-05-07 02:14:04 UTC (rev 1466) +++ trunk/configure.ac 2010-05-07 23:22:38 UTC (rev 1467) @@ -58,7 +58,10 @@ GPGME_CONFIG_API_VERSION=1 ############################################## +NEED_LIBASSUAN_API=2 +NEED_LIBASSUAN_VERSION=2.0.0 + BUILD_REVISION=svn_revision PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION @@ -298,10 +301,13 @@ [The default error source for GPGME.]) # And for libassuan. -NEED_LIBASSUAN_VERSION=1.1.0 have_libassuan=no -AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_VERSION", +AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", have_libassuan=yes, have_libassuan=no) +if test "$have_libassuan" = "yes"; then + AC_DEFINE_UNQUOTED(GPGME_LIBASSUAN_VERSION, "$libassuan_version", + [version of the libassuan library]) +fi AM_CONDITIONAL(HAVE_ASSUAN, test "$have_libassuan" = "yes") if test "$have_libassuan" = "yes"; then AC_DEFINE(ENABLE_ASSUAN,1,[Whether Assuan support is enabled]) @@ -551,16 +557,7 @@ run_gpgsm_test=$enableval) AM_CONDITIONAL(RUN_GPGSM_TESTS, test "$run_gpgsm_test" = "yes") -# Require libassuan if GPGSM is here. -require_libassuan=no -if test "$GPGSM" != "no"; then - require_libassuan=yes -fi -if test "$G13" != "no"; then - require_libassuan=yes -fi - NO_OVERRIDE=no AC_ARG_WITH(gpgconf, AC_HELP_STRING([--with-gpgconf=PATH], @@ -799,6 +796,7 @@ #include ]) +use_descriptor_passing=no AC_ARG_ENABLE(fd-passing, AC_HELP_STRING([--enable-fd-passing], [use FD passing if supported]), use_descriptor_passing=$enableval) @@ -889,14 +887,14 @@ # Last check. die=no -if test "$require_libassuan" = "no"; then +if test "$have_libassuan" = "no"; then die=yes AC_MSG_NOTICE([[ *** *** You need libassuan to build this program with GPGSM support. *** This library is for example available at -*** ftp://ftp.gnupg.org/pub/gcrypt/alpha/libassuan/ -*** (at least version $NEED_LIBASSUAN_VERSION is required). +*** ftp://ftp.gnupg.org/gcrypt/libassuan/ +*** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required). ***]]) fi @@ -925,25 +923,25 @@ AC_OUTPUT echo " - GPGME v${VERSION} has been configured as follows: + GPGME v${VERSION} has been configured as follows: - GnuPG path: $GPG + GnuPG path: $GPG GnuPG version: $GPG_VERSION, min. $NEED_GPG_VERSION - GpgSM path: $GPGSM + GpgSM path: $GPGSM GpgSM version: $GPGSM_VERSION, min. $NEED_GPGSM_VERSION - GpgConf path: $GPGCONF + GpgConf path: $GPGCONF GpgConf version: $GPGCONF_VERSION, min. $NEED_GPGCONF_VERSION - G13 path: $G13 + G13 path: $G13 G13 version: $G13_VERSION, min. $NEED_G13_VERSION - Assuan version: $LIBASSUAN_VERSION + Assuan version: $libassuan_version, min. $NEED_LIBASSUAN_VERSION - UI Server: $uiserver + UI Server: $uiserver FD Passing: $use_descriptor_passing - GPGME Pthread: $have_pthread - GPGME Pth: $have_pth + GPGME Pthread: $have_pthread + GPGME Pth: $have_pth " Modified: trunk/m4/libassuan.m4 =================================================================== --- trunk/m4/libassuan.m4 2010-05-07 02:14:04 UTC (rev 1466) +++ trunk/m4/libassuan.m4 2010-05-07 23:22:38 UTC (rev 1467) @@ -9,71 +9,125 @@ dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -dnl AM_PATH_LIBASSUAN([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libassuan and define LIBASSUAN_CFLAGS and LIBASSUAN_LIBS dnl -AC_DEFUN([AM_PATH_LIBASSUAN], +dnl Common code used for libassuan detection [internal] +dnl Returns ok set to yes or no. +dnl +AC_DEFUN([_AM_PATH_LIBASSUAN_COMMON], [ AC_ARG_WITH(libassuan-prefix, - AC_HELP_STRING([--with-libassuan-prefix=PFX], - [prefix where LIBASSUAN is installed (optional)]), + AC_HELP_STRING([--with-libassuan-prefix=PFX], + [prefix where LIBASSUAN is installed (optional)]), libassuan_config_prefix="$withval", libassuan_config_prefix="") if test x$libassuan_config_prefix != x ; then - libassuan_config_args="$libassuan_config_args --prefix=$libassuan_config_prefix" - if test x${LIBASSUAN_CONFIG+set} != xset ; then - LIBASSUAN_CONFIG=$libassuan_config_prefix/bin/libassuan-config - fi + libassuan_config_args="$libassuan_config_args --prefix=$libassuan_config_prefix" + if test x${LIBASSUAN_CONFIG+set} != xset ; then + LIBASSUAN_CONFIG=$libassuan_config_prefix/bin/libassuan-config + fi fi + AC_PATH_PROG(LIBASSUAN_CONFIG, libassuan-config, no) - AC_PATH_PROG(LIBASSUAN_CONFIG, libassuan-config, no) - min_libassuan_version=ifelse([$1], ,0.0.1,$1) - AC_MSG_CHECKING(for LIBASSUAN - version >= $min_libassuan_version) + tmp=ifelse([$1], ,1:0.9.2,$1) + if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then + req_libassuan_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` + min_libassuan_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + else + req_libassuan_api=0 + min_libassuan_version="$tmp" + fi + + if test "$LIBASSUAN_CONFIG" != "no" ; then + libassuan_version=`$LIBASSUAN_CONFIG --version` + fi + libassuan_version_major=`echo $libassuan_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + libassuan_version_minor=`echo $libassuan_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + libassuan_version_micro=`echo $libassuan_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + + AC_MSG_CHECKING(for LIBASSUAN ifelse([$2], ,,[$2 ])- version >= $min_libassuan_version) ok=no if test "$LIBASSUAN_CONFIG" != "no" ; then + ifelse([$2], ,,[if `$LIBASSUAN_CONFIG --thread=$2 2> /dev/null` ; then]) req_major=`echo $min_libassuan_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` req_minor=`echo $min_libassuan_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` req_micro=`echo $min_libassuan_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libassuan_config_version=`$LIBASSUAN_CONFIG $libassuan_config_args --version` - major=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then + if test "$libassuan_version_major" -gt "$req_major"; then ok=yes else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then + if test "$libassuan_version_major" -eq "$req_major"; then + if test "$libassuan_version_minor" -gt "$req_minor"; then ok=yes else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then + if test "$libassuan_version_minor" -eq "$req_minor"; then + if test "$libassuan_version_micro" -ge "$req_micro"; then ok=yes fi fi fi fi fi + ifelse([$2], ,,[fi]) fi + if test $ok = yes; then + AC_MSG_RESULT([yes ($libassuan_version)]) + else + AC_MSG_RESULT(no) + fi + + if test $ok = yes; then + if test "$req_libassuan_api" -gt 0 ; then + tmp=`$LIBASSUAN_CONFIG --api-version 2>/dev/null || echo 0` + if test "$tmp" -gt 0 ; then + AC_MSG_CHECKING([LIBASSUAN ifelse([$2], ,,[$2 ])API version]) + if test "$req_libassuan_api" -eq "$tmp" ; then + AC_MSG_RESULT(okay) + else + ok=no + AC_MSG_RESULT([does not match. want=$req_libassuan_api got=$tmp.]) + fi + fi + fi + fi + +]) + +dnl AM_CHECK_LIBASSUAN([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test whether libassuan has at least MINIMUM-VERSION. This is +dnl used to test for features only available in newer versions. +dnl +AC_DEFUN([AM_CHECK_LIBASSUAN], +[ _AM_PATH_LIBASSUAN_COMMON($1) + if test $ok = yes; then + ifelse([$2], , :, [$2]) + else + ifelse([$3], , :, [$3]) + fi +]) + + + + +dnl AM_PATH_LIBASSUAN([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libassuan and define LIBASSUAN_CFLAGS and LIBASSUAN_LIBS +dnl +AC_DEFUN([AM_PATH_LIBASSUAN], +[ _AM_PATH_LIBASSUAN_COMMON($1) + if test $ok = yes; then LIBASSUAN_CFLAGS=`$LIBASSUAN_CONFIG $libassuan_config_args --cflags` LIBASSUAN_LIBS=`$LIBASSUAN_CONFIG $libassuan_config_args --libs` - LIBASSUAN_VERSION="$libassuan_config_version" - AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) else LIBASSUAN_CFLAGS="" LIBASSUAN_LIBS="" - LIBASSUAN_VERSION="" - AC_MSG_RESULT(no) ifelse([$3], , :, [$3]) fi AC_SUBST(LIBASSUAN_CFLAGS) AC_SUBST(LIBASSUAN_LIBS) - AC_SUBST(LIBASSUAN_VERSION) ]) From cvs at cvs.gnupg.org Tue May 11 19:01:41 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 11 May 2010 19:01:41 +0200 Subject: [svn] gpgme - r1468 - trunk/src Message-ID: Author: marcus Date: 2010-05-11 19:01:40 +0200 (Tue, 11 May 2010) New Revision: 1468 Modified: trunk/src/ChangeLog trunk/src/gpgme.h.in Log: 2010-05-11 Marcus Brinkmann * gpgme.h.in: Use _WIN32 instead of _MSC_VER. Include time.h for time_t. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-07 23:22:38 UTC (rev 1467) +++ trunk/src/ChangeLog 2010-05-11 17:01:40 UTC (rev 1468) @@ -1,3 +1,8 @@ +2010-05-11 Marcus Brinkmann + + * gpgme.h.in: Use _WIN32 instead of _MSC_VER. Include time.h for + time_t. + 2010-05-07 Marcus Brinkmann * engine-g13.c, gpgme.c, engine-gpgsm.c, engine-gpg.c, Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2010-05-07 23:22:38 UTC (rev 1467) +++ trunk/src/gpgme.h.in 2010-05-11 17:01:40 UTC (rev 1468) @@ -34,13 +34,15 @@ /* Include stdio.h for the FILE type definition. */ #include -#ifdef _MSC_VER +#ifdef _WIN32 typedef long off_t; typedef long ssize_t; #else # include #endif +#include + #include #ifdef __cplusplus From cvs at cvs.gnupg.org Tue May 11 19:20:46 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 11 May 2010 19:20:46 +0200 Subject: [svn] gpgme - r1469 - trunk/src Message-ID: Author: marcus Date: 2010-05-11 19:20:45 +0200 (Tue, 11 May 2010) New Revision: 1469 Modified: trunk/src/ChangeLog trunk/src/w32-util.c Log: 2010-05-11 Marcus Brinkmann * w32-util.c: Include ath.h (HAVE_ALLOW_SET_FOREGROUND_WINDOW) [!HAVE_W32CE_SYSTEM]: Define it. (RTLD_LAZY, dlopen, dlsym, dlclose) [!HAVE_ALLOW_SET_FORGROUND_WINDOW]: Don't define anymore. (_gpgme_allow_set_foreground_window) [!HAVE_ALLOW_SET_FOREGROUND_WINDOW]: Make it a stub. (read_w32_registry_string): Use FooA variants of Windows functions instead of Foo (which dispatches depending on UNICODE). [!HAVE_W32CE_SYSTEM]: Don't check environment. (w32_shgetfolderpath): Remove. (find_program_at_standard_place): Call SHGetSpecialFolderPath (which is available on all Windows systems and also Windows CE). (mkstemp): Use ath_self instead of getpid. (_gpgme_mkstemp): Use GetTempPathA instead of GetTempPath. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-11 17:01:40 UTC (rev 1468) +++ trunk/src/ChangeLog 2010-05-11 17:20:45 UTC (rev 1469) @@ -1,5 +1,22 @@ 2010-05-11 Marcus Brinkmann + * w32-util.c: Include ath.h + (HAVE_ALLOW_SET_FOREGROUND_WINDOW) [!HAVE_W32CE_SYSTEM]: Define + it. + (RTLD_LAZY, dlopen, dlsym, + dlclose) [!HAVE_ALLOW_SET_FORGROUND_WINDOW]: Don't define anymore. + (_gpgme_allow_set_foreground_window) [!HAVE_ALLOW_SET_FOREGROUND_WINDOW]: + Make it a stub. + (read_w32_registry_string): Use FooA variants of Windows functions + instead of Foo (which dispatches depending on UNICODE). + [!HAVE_W32CE_SYSTEM]: Don't check environment. + (w32_shgetfolderpath): Remove. + (find_program_at_standard_place): Call + SHGetSpecialFolderPath (which is available on all Windows systems + and also Windows CE). + (mkstemp): Use ath_self instead of getpid. + (_gpgme_mkstemp): Use GetTempPathA instead of GetTempPath. + * gpgme.h.in: Use _WIN32 instead of _MSC_VER. Include time.h for time_t. Modified: trunk/src/w32-util.c =================================================================== --- trunk/src/w32-util.c 2010-05-11 17:01:40 UTC (rev 1468) +++ trunk/src/w32-util.c 2010-05-11 17:20:45 UTC (rev 1469) @@ -38,13 +38,22 @@ #include #include +#include "ath.h" #include "util.h" #include "sema.h" #include "debug.h" + +#ifndef HAVE_W32CE_SYSTEM +#define HAVE_ALLOW_SET_FOREGROUND_WINDOW 1 +#endif + + DEFINE_STATIC_LOCK (get_path_lock); +#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW + #define RTLD_LAZY 0 static __inline__ void * @@ -77,8 +86,54 @@ } return -1; } +#endif /* HAVE_ALLOW_SET_FOREGROUND_WINDOW */ +void +_gpgme_allow_set_foreground_window (pid_t pid) +{ +#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW + static int initialized; + static BOOL (WINAPI * func)(DWORD); + void *handle; + + if (!initialized) + { + /* Available since W2000; thus we dynload it. */ + initialized = 1; + handle = dlopen ("user32.dll", RTLD_LAZY); + if (handle) + { + func = dlsym (handle, "AllowSetForegroundWindow"); + if (!func) + { + dlclose (handle); + handle = NULL; + } + } + } + + if (!pid || pid == (pid_t)(-1)) + { + TRACE1 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0, + "no action for pid %d", (int)pid); + } + else if (func) + { + int rc = func (pid); + TRACE2 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0, + "called for pid %d; result=%d", (int)pid, rc); + + } + else + { + TRACE0 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0, + "function not available"); + } +#endif /* HAVE_ALLOW_SET_FOREGROUND_WINDOW */ +} + + /* 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. */ @@ -89,59 +144,64 @@ 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 ) ) + if (RegOpenKeyExA (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) ) + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) return NULL; /* still no need for a RegClose, so return direct */ } nbytes = 1; - if ( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) + if (RegQueryValueExA (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) ) + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) return NULL; /* Nope. */ - if (RegQueryValueEx ( key_handle, name, 0, NULL, NULL, &nbytes)) + if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) goto leave; } - result = malloc ( (n1=nbytes+1) ); - if ( !result ) + n1 = nbytes + 1; + result = malloc (n1); + if (!result) goto leave; - if ( RegQueryValueEx ( key_handle, name, 0, &type, result, &n1 ) ) + if (RegQueryValueExA (key_handle, name, 0, &type, (LPBYTE) result, &n1)) { - free(result); result = NULL; + free (result); + result = NULL; goto leave; } result[nbytes] = 0; /* Make sure it is really a string. */ + +#ifndef HAVE_W32CE_SYSTEM + /* Windows CE does not have an environment. */ if (type == REG_EXPAND_SZ && strchr (result, '%')) { char *tmp; n1 += 1000; - tmp = malloc (n1+1); + tmp = malloc (n1 + 1); if (!tmp) goto leave; nbytes = ExpandEnvironmentStrings (result, tmp, n1); @@ -179,51 +239,14 @@ free (tmp); } } +#endif leave: - RegCloseKey( key_handle ); + RegCloseKey (key_handle); return result; } -/* This is a helper function to load and run a Windows function from - either of one DLLs. */ -static HRESULT -w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e) -{ - static int initialized; - static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR); - - if (!initialized) - { - static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL }; - void *handle; - int i; - - initialized = 1; - - for (i=0, handle = NULL; !handle && dllnames[i]; i++) - { - handle = dlopen (dllnames[i], RTLD_LAZY); - if (handle) - { - func = dlsym (handle, "SHGetFolderPathA"); - if (!func) - { - dlclose (handle); - handle = NULL; - } - } - } - } - - if (func) - return func (a,b,c,d,e); - else - return -1; -} - - #if 0 static char * find_program_in_registry (const char *name) @@ -285,7 +308,8 @@ char path[MAX_PATH]; char *result = NULL; - if (w32_shgetfolderpath (NULL, CSIDL_PROGRAM_FILES, NULL, 0, path) >= 0) + /* See http://wiki.tcl.tk/17492 for details on compatibility. */ + if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0)) { result = malloc (strlen (path) + 1 + strlen (name) + 1); if (result) @@ -383,7 +407,7 @@ _gpgme_get_uiserver_socket_path (void) { static char *socket_path; - char *homedir; + const char *homedir; const char name[] = "S.uiserver"; if (socket_path) @@ -432,51 +456,6 @@ return 1; } - -void -_gpgme_allow_set_foreground_window (pid_t pid) -{ - static int initialized; - static BOOL (WINAPI * func)(DWORD); - void *handle; - - if (!initialized) - { - /* Available since W2000; thus we dynload it. */ - initialized = 1; - handle = dlopen ("user32.dll", RTLD_LAZY); - if (handle) - { - func = dlsym (handle, "AllowSetForegroundWindow"); - if (!func) - { - dlclose (handle); - handle = NULL; - } - } - } - - if (!pid || pid == (pid_t)(-1)) - { - TRACE1 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0, - "no action for pid %d", (int)pid); - } - else if (func) - { - int rc = func (pid); - TRACE2 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0, - "called for pid %d; result=%d", (int)pid, rc); - - } - else - { - TRACE0 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0, - "function not available"); - } - -} - - /* mkstemp extracted from libc/sysdeps/posix/tempname.c. Copyright (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc. @@ -538,7 +517,7 @@ random_time_bits = (((uint64_t)ft.dwHighDateTime << 32) | (uint64_t)ft.dwLowDateTime); } - value += random_time_bits ^ getpid (); + value += random_time_bits ^ ath_self (); for (count = 0; count < attempts; value += 7777, ++count) { @@ -583,7 +562,7 @@ *fd = -1; *name = NULL; - err = GetTempPath (MAX_PATH + 1, tmp); + err = GetTempPathA (MAX_PATH + 1, tmp); if (err == 0 || err > MAX_PATH + 1) strcpy (tmp,"c:\\windows\\temp"); else From cvs at cvs.gnupg.org Tue May 11 19:52:01 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 11 May 2010 19:52:01 +0200 Subject: [svn] GnuPG - r5333 - in branches/STABLE-BRANCH-2-0: . agent doc tests tests/openpgp Message-ID: Author: wk Date: 2010-05-11 19:52:00 +0200 (Tue, 11 May 2010) New Revision: 5333 Modified: branches/STABLE-BRANCH-2-0/NEWS branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/agent.h branches/STABLE-BRANCH-2-0/agent/command.c branches/STABLE-BRANCH-2-0/agent/gpg-agent.c branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi branches/STABLE-BRANCH-2-0/tests/Makefile.am branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog branches/STABLE-BRANCH-2-0/tests/openpgp/Makefile.am branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc branches/STABLE-BRANCH-2-0/tests/openpgp/genkey1024.test Log: Allow to run the test without a running agent. Add new gpg-agent commands. Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-11 17:52:00 UTC (rev 5333) @@ -1,3 +1,12 @@ +2010-05-11 Werner Koch + + * agent.h (opt): Add field USE_STANDARD_SOCKET. + * gpg-agent.c (use_standard_socket): Remove. Use new option instead. + + * command.c (cmd_killagent, cmd_reloadagent): Provide command also + for non-W32 platforms. + (cmd_getinfo): New subcommands std_session_env and std_startup_env. + 2010-05-04 Werner Koch * gpg-agent.c (main): Add command --use-standard-socket-p. Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog 2010-05-11 17:52:00 UTC (rev 5333) @@ -1,3 +1,13 @@ +2010-05-11 Werner Koch + + * genkey1024.test: Use GPG macro. + + * gpg-agent.conf.tmpl: New. + * defs.inc: Create gpg-agent.conf + (GNUPGHOME): Set and export. + (GPG_AGENT_INFO): Unset + * Makefile.am (CLEANFILES): Add S.gpg-agent + 2009-12-21 Werner Koch * Makefile.am (required_pgms): New. Modified: branches/STABLE-BRANCH-2-0/NEWS =================================================================== --- branches/STABLE-BRANCH-2-0/NEWS 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/NEWS 2010-05-11 17:52:00 UTC (rev 5333) @@ -7,6 +7,9 @@ option --use-standard-socket may now be used to use this feature by default. + * The gpg-agent commands KILLAGENT and RELOADAGENT are now available + on all platforms. + * Minor bug fixes. Modified: branches/STABLE-BRANCH-2-0/agent/agent.h =================================================================== --- branches/STABLE-BRANCH-2-0/agent/agent.h 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/agent/agent.h 2010-05-11 17:52:00 UTC (rev 5333) @@ -61,6 +61,8 @@ char *startup_lc_ctype; char *startup_lc_messages; + /* True if we are listening on the standard socket. */ + int use_standard_socket; const char *pinentry_program; /* Filename of the program to start as pinentry. */ Modified: branches/STABLE-BRANCH-2-0/agent/command.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/command.c 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/agent/command.c 2010-05-11 17:52:00 UTC (rev 5333) @@ -59,10 +59,8 @@ char *keydesc; /* Allocated description for the next key operation. */ int pause_io_logging; /* Used to suppress I/O logging during a command */ -#ifdef HAVE_W32_SYSTEM int stopme; /* If set to true the agent will be terminated after the end of this session. */ -#endif int allow_pinentry_notify; /* Set if pinentry notifications should be done. */ }; @@ -1590,18 +1588,20 @@ -#ifdef HAVE_W32_SYSTEM static const char hlp_killagent[] = "KILLAGENT\n" "\n" - "Under Windows we start the agent on the fly. Thus it also make\n" - "sense to allow a client to stop the agent."; + "If the agent has been started using a standard socket\n" + "we allow a client to stop the agent."; static gpg_error_t cmd_killagent (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); (void)line; + + if (!opt.use_standard_socket) + return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket"); ctrl->server_local->stopme = 1; return gpg_error (GPG_ERR_EOF); @@ -1611,8 +1611,8 @@ static const char hlp_reloadagent[] = "RELOADAGENT\n" "\n" - "As signals are inconvenient under Windows, we provide this command\n" - "to allow reloading of the configuration."; + "This command is an alternative to SIGHUP\n" + "to reload the configuration."; static gpg_error_t cmd_reloadagent (assuan_context_t ctx, char *line) { @@ -1622,7 +1622,6 @@ agent_sighup_action (); return 0; } -#endif /*HAVE_W32_SYSTEM*/ @@ -1637,11 +1636,14 @@ " socket_name - Return the name of the socket.\n" " ssh_socket_name - Return the name of the ssh socket.\n" " scd_running - Return OK if the SCdaemon is already running.\n" + " std_session_env - List the standard session environment.\n" + " std_startup_env - List the standard startup environment.\n" " cmd_has_option\n" " - Returns OK if the command CMD implements the option OPT."; static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); int rc = 0; if (!strcmp (line, "version")) @@ -1685,6 +1687,34 @@ snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ()); rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); } + else if (!strcmp (line, "std_session_env") + || !strcmp (line, "std_startup_env")) + { + int iterator; + const char *name, *value; + char *string; + + iterator = 0; + while ((name = session_env_list_stdenvnames (&iterator, NULL))) + { + value = session_env_getenv_or_default + (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL); + if (value) + { + string = xtryasprintf ("%s=%s", name, value); + if (!string) + rc = gpg_error_from_syserror (); + else + { + rc = assuan_send_data (ctx, string, strlen (string)+1); + if (!rc) + rc = assuan_send_data (ctx, NULL, 0); + } + if (rc) + break; + } + } + } else if (!strncmp (line, "cmd_has_option", 14) && (line[14] == ' ' || line[14] == '\t' || !line[14])) { @@ -1881,10 +1911,8 @@ { "GETVAL", cmd_getval, hlp_getval }, { "PUTVAL", cmd_putval, hlp_putval }, { "UPDATESTARTUPTTY", cmd_updatestartuptty, hlp_updatestartuptty }, -#ifdef HAVE_W32_SYSTEM { "KILLAGENT", cmd_killagent, hlp_killagent }, { "RELOADAGENT", cmd_reloadagent,hlp_reloadagent }, -#endif { "GETINFO", cmd_getinfo, hlp_getinfo }, { NULL } }; @@ -1991,10 +2019,8 @@ /* Cleanup. */ assuan_release (ctx); -#ifdef HAVE_W32_SYSTEM if (ctrl->server_local->stopme) agent_exit (0); -#endif xfree (ctrl->server_local); ctrl->server_local = NULL; } Modified: branches/STABLE-BRANCH-2-0/agent/gpg-agent.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-11 17:52:00 UTC (rev 5333) @@ -217,9 +217,6 @@ /* Counter for the currently running own socket checks. */ static int check_own_socket_running; -/* True if we are listening on the standard socket. */ -static int use_standard_socket; - /* It is possible that we are currently running under setuid permissions */ static int maybe_setuid = 1; @@ -631,8 +628,8 @@ /* Set default options. */ parse_rereadable_options (NULL, 0); /* Reset them to default values. */ #ifdef USE_STANDARD_SOCKET - use_standard_socket = 1; /* Under Windows we always use a standard - socket. */ + opt.use_standard_socket = 1; /* Under Windows we always use a standard + socket. */ #endif shell = getenv ("SHELL"); @@ -783,8 +780,8 @@ case oXauthority: default_xauthority = xstrdup (pargs.r.ret_str); break; - case oUseStandardSocket: use_standard_socket = 1; break; - case oNoUseStandardSocket: use_standard_socket = 0; break; + case oUseStandardSocket: opt.use_standard_socket = 1; break; + case oNoUseStandardSocket: opt.use_standard_socket = 0; break; case oFakedSystemTime: { @@ -862,7 +859,7 @@ } if (gpgconf_list == 3) - agent_exit (!use_standard_socket); + agent_exit (!opt.use_standard_socket); if (gpgconf_list == 2) agent_exit (0); if (gpgconf_list) @@ -1437,7 +1434,7 @@ { char *name, *p; - if (use_standard_socket) + if (opt.use_standard_socket) name = make_filename (opt.homedir, standard_name, NULL); else { @@ -1500,7 +1497,7 @@ strcpy (serv_addr->sun_path, name); len = SUN_LEN (serv_addr); rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len); - if (use_standard_socket && rc == -1 && errno == EADDRINUSE) + if (opt.use_standard_socket && rc == -1 && errno == EADDRINUSE) { /* Check whether a gpg-agent is already running on the standard socket. We do this test only if this is not the ssh socket. @@ -1533,7 +1530,7 @@ gpg_strerror (gpg_error_from_errno (errno))); assuan_sock_close (fd); - if (use_standard_socket) + if (opt.use_standard_socket) *name = 0; /* Inhibit removal of the socket by cleanup(). */ agent_exit (2); } @@ -2170,7 +2167,7 @@ char *sockname; pth_attr_t tattr; - if (!use_standard_socket) + if (!opt.use_standard_socket) return; /* This check makes only sense in standard socket mode. */ if (check_own_socket_running || shutdown_pending) Modified: branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi =================================================================== --- branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/doc/gpg-agent.texi 2010-05-11 17:52:00 UTC (rev 5333) @@ -433,8 +433,9 @@ a random socket below a temporary directory. Tools connecting to @command{gpg-agent} should first try to connect to the socket given in environment variable @var{GPG_AGENT_INFO} and then fall back to this -socket. This option may not be used if the home directory is mounted as -a remote file system. Note, that @option{--use-standard-socket} is the +socket. This option may not be used if the home directory is mounted on +a remote file system which does not support special files like fifos or +sockets. Note, that @option{--use-standard-socket} is the default on Windows systems. The default may be changed at build time. It is possible to test at runtime whether the agent has been configured for use with the standard socket by issuing the command Modified: branches/STABLE-BRANCH-2-0/tests/Makefile.am =================================================================== --- branches/STABLE-BRANCH-2-0/tests/Makefile.am 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/tests/Makefile.am 2010-05-11 17:52:00 UTC (rev 5333) @@ -30,7 +30,7 @@ GPGSM = ../sm/gpgsm # Note that we need to use /bin/pwd so that we don't get into trouble -# if the shell used for inittests would uses an internal version of +# if the shell used for inittests would use an internal version of # pwd which handles symlinks differently. TESTS_ENVIRONMENT = GNUPGHOME=`/bin/pwd` GPG_AGENT_INFO= LC_ALL=C \ GPGSM=$(GPGSM) $(srcdir)/runtest Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/Makefile.am =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/Makefile.am 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/Makefile.am 2010-05-11 17:52:00 UTC (rev 5333) @@ -40,15 +40,19 @@ TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \ plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \ pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc \ - gpg.conf.tmpl bug537-test.data.asc bug894-test.asc + gpg.conf.tmpl gpg-agent.conf.tmpl \ + bug537-test.data.asc bug894-test.asc DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large EXTRA_DIST = defs.inc $(TESTS) $(TEST_FILES) \ mkdemodirs signdemokey + +# Note that removing S.gpg-agent forces a running gpg-agent to +# terminate after some time. CLEANFILES = prepared.stamp x y yy z out err $(DATA_FILES) \ plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \ - *.test.log gpg_dearmor gpg.conf \ + *.test.log gpg_dearmor gpg.conf gpg-agent.conf S.gpg-agent \ pubring.gpg secring.gpg pubring.pkr secring.skr DISTCLEANFILES = pubring.gpg~ random_seed Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc 2010-05-11 17:52:00 UTC (rev 5333) @@ -161,15 +161,27 @@ [ -z "$srcdir" ] && fatal "not called from make" -# Make sure we have a valid option files even with VPATH builds. -if [ -f ./gpg.conf ]; then - : -elif [ -f $srcdir/gpg.conf.tmpl ]; then - cat $srcdir/gpg.conf.tmpl >gpg.conf -fi +# Make sure we have a valid option file even with VPATH builds. +for f in gpg.conf gpg-agent.conf; do + if [ -f ./$f ]; then + : + elif [ -f $srcdir/$f.tmpl ]; then + cat $srcdir/$f.tmpl >$f + fi +done -GPG="../../g10/gpg2 --no-permission-warning --homedir . " +# Always work in the current directory +GNUPGHOME=`pwd` +export GNUPGHOME +# We do not use an external info variable for gpg-agent because we use +# a standard socket in the home directory. This way gpg-agent will be +# started as soon as needed. It is terminated indirectly using a +# Makefile rule. +GPG_AGENT_INFO= + +GPG="../../g10/gpg2 --no-permission-warning " + exec 5>&2 2>${pgmname}.log : Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/genkey1024.test =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/genkey1024.test 2010-05-07 13:13:56 UTC (rev 5332) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/genkey1024.test 2010-05-11 17:52:00 UTC (rev 5333) @@ -10,7 +10,7 @@ . $srcdir/defs.inc || exit 3 -../../g10/gpg2 --quiet --batch --debug-quick-random --homedir . --gen-key < Author: wk Date: 2010-05-11 20:00:12 +0200 (Tue, 11 May 2010) New Revision: 5334 Added: branches/STABLE-BRANCH-2-0/tests/openpgp/gpg-agent.conf.tmpl Log: Add file From cvs at cvs.gnupg.org Tue May 11 20:00:31 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 11 May 2010 20:00:31 +0200 Subject: [svn] GnuPG - r5335 - in trunk: agent doc tests/openpgp Message-ID: Author: wk Date: 2010-05-11 20:00:31 +0200 (Tue, 11 May 2010) New Revision: 5335 Added: trunk/tests/openpgp/gpg-agent.conf.tmpl Modified: trunk/agent/ChangeLog trunk/agent/agent.h trunk/agent/command.c trunk/agent/gpg-agent.c trunk/doc/gpg-agent.texi trunk/tests/openpgp/ChangeLog trunk/tests/openpgp/Makefile.am trunk/tests/openpgp/defs.inc trunk/tests/openpgp/genkey1024.test Log: Update tests. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/agent/ChangeLog 2010-05-11 18:00:31 UTC (rev 5335) @@ -1,3 +1,12 @@ +2010-05-11 Werner Koch + + * agent.h (opt): Add field USE_STANDARD_SOCKET. + * gpg-agent.c (use_standard_socket): Remove. Use new option instead. + + * command.c (cmd_killagent, cmd_reloadagent): Provide command also + for non-W32 platforms. + (cmd_getinfo): New subcommands std_session_env and std_startup_env. + 2010-05-03 Werner Koch * gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME Modified: trunk/tests/openpgp/ChangeLog =================================================================== --- trunk/tests/openpgp/ChangeLog 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/tests/openpgp/ChangeLog 2010-05-11 18:00:31 UTC (rev 5335) @@ -1,3 +1,13 @@ +2010-05-11 Werner Koch + + * genkey1024.test: Use GPG macro. + + * gpg-agent.conf.tmpl: New. + * defs.inc: Create gpg-agent.conf + (GNUPGHOME): Set and export. + (GPG_AGENT_INFO): Unset. + * Makefile.am (CLEANFILES): Add S.gpg-agent + 2010-05-07 Werner Koch * import.test: Add test case for bug#1223. @@ -48,7 +58,7 @@ we support. This is safer than the previous setup which could hide that some ciphers weren't being tested. Plus, this automatically tests any new ciphers libgcrypt supports. - (all_hash_algos): New. + (all_hash_algos): New. * sigs.test: Use it here, and also test with >=160 bit hashes for DSA2. * conventional.test, encrypt.test, encrypt-dsa.test, Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/agent/agent.h 2010-05-11 18:00:31 UTC (rev 5335) @@ -55,6 +55,9 @@ int batch; /* Batch mode */ const char *homedir; /* Configuration directory name */ + /* True if we are listening on the standard socket. */ + int use_standard_socket; + /* Environment setting gathered at program start or changed using the Assuan command UPDATESTARTUPTTY. */ session_env_t startup_env; Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/agent/command.c 2010-05-11 18:00:31 UTC (rev 5335) @@ -59,10 +59,8 @@ char *keydesc; /* Allocated description for the next key operation. */ int pause_io_logging; /* Used to suppress I/O logging during a command */ -#ifdef HAVE_W32_SYSTEM int stopme; /* If set to true the agent will be terminated after the end of this session. */ -#endif int allow_pinentry_notify; /* Set if pinentry notifications should be done. */ }; @@ -1591,18 +1589,20 @@ -#ifdef HAVE_W32_SYSTEM static const char hlp_killagent[] = "KILLAGENT\n" "\n" - "Under Windows we start the agent on the fly. Thus it also make\n" - "sense to allow a client to stop the agent."; + "If the agent has been started using a standard socket\n" + "we allow a client to stop the agent."; static gpg_error_t cmd_killagent (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); (void)line; + + if (!opt.use_standard_socket) + return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket"); ctrl->server_local->stopme = 1; return gpg_error (GPG_ERR_EOF); @@ -1612,8 +1612,8 @@ static const char hlp_reloadagent[] = "RELOADAGENT\n" "\n" - "As signals are inconvenient under Windows, we provide this command\n" - "to allow reloading of the configuration."; + "This command is an alternative to SIGHUP\n" + "to reload the configuration."; static gpg_error_t cmd_reloadagent (assuan_context_t ctx, char *line) { @@ -1623,7 +1623,6 @@ agent_sighup_action (); return 0; } -#endif /*HAVE_W32_SYSTEM*/ @@ -1639,11 +1638,14 @@ " ssh_socket_name - Return the name of the ssh socket.\n" " scd_running - Return OK if the SCdaemon is already running.\n" " s2k_count - Return the calibrated S2K count.\n" + " std_session_env - List the standard session environment.\n" + " std_startup_env - List the standard startup environment.\n" " cmd_has_option\n" " - Returns OK if the command CMD implements the option OPT."; static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); int rc = 0; if (!strcmp (line, "version")) @@ -1687,6 +1689,34 @@ snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ()); rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); } + else if (!strcmp (line, "std_session_env") + || !strcmp (line, "std_startup_env")) + { + int iterator; + const char *name, *value; + char *string; + + iterator = 0; + while ((name = session_env_list_stdenvnames (&iterator, NULL))) + { + value = session_env_getenv_or_default + (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL); + if (value) + { + string = xtryasprintf ("%s=%s", name, value); + if (!string) + rc = gpg_error_from_syserror (); + else + { + rc = assuan_send_data (ctx, string, strlen (string)+1); + if (!rc) + rc = assuan_send_data (ctx, NULL, 0); + } + if (rc) + break; + } + } + } else if (!strncmp (line, "cmd_has_option", 14) && (line[14] == ' ' || line[14] == '\t' || !line[14])) { @@ -1883,10 +1913,8 @@ { "GETVAL", cmd_getval, hlp_getval }, { "PUTVAL", cmd_putval, hlp_putval }, { "UPDATESTARTUPTTY", cmd_updatestartuptty, hlp_updatestartuptty }, -#ifdef HAVE_W32_SYSTEM { "KILLAGENT", cmd_killagent, hlp_killagent }, { "RELOADAGENT", cmd_reloadagent,hlp_reloadagent }, -#endif { "GETINFO", cmd_getinfo, hlp_getinfo }, { NULL } }; @@ -1993,10 +2021,8 @@ /* Cleanup. */ assuan_release (ctx); -#ifdef HAVE_W32_SYSTEM if (ctrl->server_local->stopme) agent_exit (0); -#endif xfree (ctrl->server_local); ctrl->server_local = NULL; } Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/agent/gpg-agent.c 2010-05-11 18:00:31 UTC (rev 5335) @@ -219,9 +219,6 @@ /* Counter for the currently running own socket checks. */ static int check_own_socket_running; -/* True if we are listening on the standard socket. */ -static int use_standard_socket; - /* It is possible that we are currently running under setuid permissions */ static int maybe_setuid = 1; @@ -631,7 +628,7 @@ /* Set default options. */ parse_rereadable_options (NULL, 0); /* Reset them to default values. */ #ifdef USE_STANDARD_SOCKET - use_standard_socket = 1; + opt.use_standard_socket = 1; #endif shell = getenv ("SHELL"); @@ -782,8 +779,8 @@ case oXauthority: default_xauthority = xstrdup (pargs.r.ret_str); break; - case oUseStandardSocket: use_standard_socket = 1; break; - case oNoUseStandardSocket: use_standard_socket = 0; break; + case oUseStandardSocket: opt.use_standard_socket = 1; break; + case oNoUseStandardSocket: opt.use_standard_socket = 0; break; case oFakedSystemTime: { @@ -862,9 +859,9 @@ if (gpgconf_list == 3) { - if (use_standard_socket && !opt.quiet) + if (opt.use_standard_socket && !opt.quiet) log_info ("configured to use the standard socket\n"); - agent_exit (!use_standard_socket); + agent_exit (!opt.use_standard_socket); } else if (gpgconf_list == 2) agent_exit (0); @@ -1438,7 +1435,7 @@ { char *name, *p; - if (use_standard_socket) + if (opt.use_standard_socket) name = make_filename (opt.homedir, standard_name, NULL); else { @@ -1504,7 +1501,7 @@ /* Our error code mapping on W32CE returns EEXIST thus we also test for this. */ - if (use_standard_socket && rc == -1 + if (opt.use_standard_socket && rc == -1 && (errno == EADDRINUSE #ifdef HAVE_W32_SYSTEM || errno == EEXIST @@ -1542,7 +1539,7 @@ gpg_strerror (gpg_error_from_errno (errno))); assuan_sock_close (fd); - if (use_standard_socket) + if (opt.use_standard_socket) *name = 0; /* Inhibit removal of the socket by cleanup(). */ agent_exit (2); } @@ -2169,7 +2166,7 @@ char *sockname; pth_attr_t tattr; - if (!use_standard_socket) + if (!opt.use_standard_socket) return; /* This check makes only sense in standard socket mode. */ if (check_own_socket_running || shutdown_pending) Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/doc/gpg-agent.texi 2010-05-11 18:00:31 UTC (rev 5335) @@ -433,13 +433,14 @@ a random socket below a temporary directory. Tools connecting to @command{gpg-agent} should first try to connect to the socket given in environment variable @var{GPG_AGENT_INFO} and then fall back to this -socket. This option may not be used if the home directory is mounted as -a remote file system. Note, that @option{--use-standard-socket} is the -default on Windows systems. The default may be changed at build time. -It is possible to test at runtime whether the agent has been configured -for use with the standard socket by issuing the command - at command{gpg-agent --use-standard-socket-p} which returns success if the -standard socket option has been enabled. +socket. This option may not be used if the home directory is mounted on +a remote file system which does not support special files like fifos or +sockets. Note, that @option{--use-standard-socket} is the default on +Windows systems. The default may be changed at build time. It is +possible to test at runtime whether the agent has been configured for +use with the standard socket by issuing the command @command{gpg-agent +--use-standard-socket-p} which returns success if the standard socket +option has been enabled. @item --display @var{string} @itemx --ttyname @var{string} Modified: trunk/tests/openpgp/Makefile.am =================================================================== --- trunk/tests/openpgp/Makefile.am 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/tests/openpgp/Makefile.am 2010-05-11 18:00:31 UTC (rev 5335) @@ -40,16 +40,20 @@ TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \ plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \ pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc \ - gpg.conf.tmpl bug537-test.data.asc bug894-test.asc \ + gpg.conf.tmpl gpg-agent.conf.tmpl \ + bug537-test.data.asc bug894-test.asc \ bug1223-good.asc bug1223-bogus.asc DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large EXTRA_DIST = defs.inc $(TESTS) $(TEST_FILES) \ mkdemodirs signdemokey + +# Note that removing S.gpg-agent forces a running gpg-agent to +# terminate after some time. CLEANFILES = prepared.stamp x y yy z out err $(DATA_FILES) \ plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \ - *.test.log gpg_dearmor gpg.conf \ + *.test.log gpg_dearmor gpg.conf gpg-agent.conf S.gpg-agent \ pubring.gpg secring.gpg pubring.pkr secring.skr DISTCLEANFILES = pubring.gpg~ random_seed Modified: trunk/tests/openpgp/defs.inc =================================================================== --- trunk/tests/openpgp/defs.inc 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/tests/openpgp/defs.inc 2010-05-11 18:00:31 UTC (rev 5335) @@ -162,14 +162,26 @@ [ -z "$srcdir" ] && fatal "not called from make" # Make sure we have a valid option files even with VPATH builds. -if [ -f ./gpg.conf ]; then - : -elif [ -f $srcdir/gpg.conf.tmpl ]; then - cat $srcdir/gpg.conf.tmpl >gpg.conf -fi +for f in gpg.conf gpg-agent.conf; do + if [ -f ./$f ]; then + : + elif [ -f $srcdir/$f.tmpl ]; then + cat $srcdir/$f.tmpl >$f + fi +done -GPG="../../g10/gpg2 --no-permission-warning --homedir . " +# Always work in the current directory +GNUPGHOME=`pwd` +export GNUPGHOME +# We do not use an external info variable for gpg-agent because we use +# a standard socket in the home directory. This way gpg-agent will be +# started as soon as needed. It is terminated indirectly using a +# Makefile rule. +GPG_AGENT_INFO= + +GPG="../../g10/gpg2 --no-permission-warning " + exec 5>&2 2>${pgmname}.log : Modified: trunk/tests/openpgp/genkey1024.test =================================================================== --- trunk/tests/openpgp/genkey1024.test 2010-05-11 18:00:12 UTC (rev 5334) +++ trunk/tests/openpgp/genkey1024.test 2010-05-11 18:00:31 UTC (rev 5335) @@ -10,7 +10,7 @@ . $srcdir/defs.inc || exit 3 -../../g10/gpg2 --quiet --batch --debug-quick-random --homedir . --gen-key < Author: wk Date: 2010-05-12 11:49:28 +0200 (Wed, 12 May 2010) New Revision: 5336 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/gpg-agent.c branches/STABLE-BRANCH-2-0/tests/Makefile.am branches/STABLE-BRANCH-2-0/tests/inittests branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog branches/STABLE-BRANCH-2-0/tests/openpgp/Makefile.am branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc branches/STABLE-BRANCH-2-0/tests/openpgp/gpg-agent.conf.tmpl Log: Changed test system again to allow building on an NFS mount Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-11 18:00:31 UTC (rev 5335) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-12 09:49:28 UTC (rev 5336) @@ -1,3 +1,7 @@ +2010-05-12 Werner Koch + + * gpg-agent.c (handle_tick): Do not print die message with option -q. + 2010-05-11 Werner Koch * agent.h (opt): Add field USE_STANDARD_SOCKET. Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog 2010-05-11 18:00:31 UTC (rev 5335) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog 2010-05-12 09:49:28 UTC (rev 5336) @@ -1,3 +1,12 @@ +2010-05-12 Werner Koch + + * Makefile.am (TESTS_ENVIRONMENT): New. Start all scripts udner + the control of the gpg-agent. + (prepared.stamp): Create gpg-agent.conf. + * defs.inc: Do not create gpg-agent.conf + (GNUPGHOME): Check that it is set properly. + (GPG_AGENT_INFO): Do not change. + 2010-05-11 Werner Koch * genkey1024.test: Use GPG macro. Modified: branches/STABLE-BRANCH-2-0/agent/gpg-agent.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-11 18:00:31 UTC (rev 5335) +++ branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-12 09:49:28 UTC (rev 5336) @@ -1660,8 +1660,11 @@ if (kill (parent_pid, 0)) { shutdown_pending = 2; - log_info ("parent process died - shutting down\n"); - log_info ("%s %s stopped\n", strusage(11), strusage(13) ); + if (!opt.quiet) + { + log_info ("parent process died - shutting down\n"); + log_info ("%s %s stopped\n", strusage(11), strusage(13) ); + } cleanup (); agent_exit (0); } Modified: branches/STABLE-BRANCH-2-0/tests/Makefile.am =================================================================== --- branches/STABLE-BRANCH-2-0/tests/Makefile.am 2010-05-11 18:00:31 UTC (rev 5335) +++ branches/STABLE-BRANCH-2-0/tests/Makefile.am 2010-05-12 09:49:28 UTC (rev 5336) @@ -46,9 +46,9 @@ samplekeys/cert_g10code_test1.pem \ samplekeys/cert_g10code_theo1.pem -# We used to run $(testscripts) here but tehse asschk scripts ares not +# We used to run $(testscripts) here but these asschk scripts are not # completely reliable in all enviromnets and thus we better disable -# them. The tests are anyway way to minimal. We will eventually +# them. The tests are anyway way too minimal. We will eventually # write new tests based on gpg-connect-agent which has a full fledged # script language and thus makes it far easier to write tests than to # use the low--level asschk stuff. Modified: branches/STABLE-BRANCH-2-0/tests/inittests =================================================================== --- branches/STABLE-BRANCH-2-0/tests/inittests 2010-05-11 18:00:31 UTC (rev 5335) +++ branches/STABLE-BRANCH-2-0/tests/inittests 2010-05-12 09:49:28 UTC (rev 5336) @@ -73,7 +73,7 @@ done # Create the configuration scripts -# Note, die to an expired test certificate, we need to use +# Note, due to an expired test certificate, we need to use # the faked system time option. cat > gpgsm.conf < gpg-agent.conf echo timestamp >./prepared.stamp + # We need to depend on a couple of programs so that the tests don't # start before all programs are built. ./gpg_dearmor: $(required_pgms) Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc 2010-05-11 18:00:31 UTC (rev 5335) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/defs.inc 2010-05-12 09:49:28 UTC (rev 5336) @@ -1,6 +1,6 @@ # Definitions for the OpenPGP test scripts -*- sh -*- # Copyright 1998,1999,2000,2001,2002,2003,2004,2005,2006, -# 2007 Free Software Foundation, Inc. +# 2007, 2010 Free Software Foundation, Inc. # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. This file is @@ -162,7 +162,7 @@ [ -z "$srcdir" ] && fatal "not called from make" # Make sure we have a valid option file even with VPATH builds. -for f in gpg.conf gpg-agent.conf; do +for f in gpg.conf ; do if [ -f ./$f ]; then : elif [ -f $srcdir/$f.tmpl ]; then @@ -170,19 +170,24 @@ fi done -# Always work in the current directory -GNUPGHOME=`pwd` -export GNUPGHOME +# Always work in the current directory. We set GNUPGHOME only if it +# has not been set already. Usually it is set through the Makefile's +# TESTS_ENVIRONMENT macro. +if [ -z "$GNUPGHOME" ]; then + GNUPGHOME=`pwd` + export GNUPGHOME +elif [ "$GNUPGHOME" != `pwd` ]; then + echo "$pgmname: GNUPGHOME not set to the cwd" $* >&2 + exit 1 +fi -# We do not use an external info variable for gpg-agent because we use -# a standard socket in the home directory. This way gpg-agent will be -# started as soon as needed. It is terminated indirectly using a -# Makefile rule. -GPG_AGENT_INFO= GPG="../../g10/gpg2 --no-permission-warning " -exec 5>&2 2>${pgmname}.log +echo "Test: $pgmname" > ${pgmname}.log +echo "GNUPGHOME=$GNUPGHOME" >> ${pgmname}.log +echo "GPG_AGENT_INFO=$GPG_AGENT_INFO" >> ${pgmname}.log +exec 5>&2 2>>${pgmname}.log : # end Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/gpg-agent.conf.tmpl =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/gpg-agent.conf.tmpl 2010-05-11 18:00:31 UTC (rev 5335) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/gpg-agent.conf.tmpl 2010-05-12 09:49:28 UTC (rev 5336) @@ -1,2 +1,2 @@ -use-standard-socket +no-use-standard-socket From cvs at cvs.gnupg.org Wed May 12 12:35:17 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 12:35:17 +0200 Subject: [svn] GnuPG - r5337 - branches/STABLE-BRANCH-2-0/po Message-ID: Author: wk Date: 2010-05-12 12:35:16 +0200 (Wed, 12 May 2010) New Revision: 5337 Modified: branches/STABLE-BRANCH-2-0/po/ChangeLog branches/STABLE-BRANCH-2-0/po/zh_TW.po Log: Update Modified: branches/STABLE-BRANCH-2-0/po/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/po/ChangeLog 2010-05-12 09:49:28 UTC (rev 5336) +++ branches/STABLE-BRANCH-2-0/po/ChangeLog 2010-05-12 10:35:16 UTC (rev 5337) @@ -1,3 +1,7 @@ +2010-05-12 Jedi (wk) + + * zh_TW.po: Update (dated 2010-03-10). + 2010-02-17 Werner Koch * de.po: Replace "Unterschrift" by "Signatur". Modified: branches/STABLE-BRANCH-2-0/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Wed May 12 12:35:59 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 12:35:59 +0200 Subject: [svn] GnuPG - r5338 - branches/STABLE-BRANCH-2-0/sm Message-ID: Author: wk Date: 2010-05-12 12:35:58 +0200 (Wed, 12 May 2010) New Revision: 5338 Modified: branches/STABLE-BRANCH-2-0/sm/ChangeLog branches/STABLE-BRANCH-2-0/sm/Makefile.am Log: Include NETLIBS Modified: branches/STABLE-BRANCH-2-0/sm/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/sm/ChangeLog 2010-05-12 10:35:16 UTC (rev 5337) +++ branches/STABLE-BRANCH-2-0/sm/ChangeLog 2010-05-12 10:35:58 UTC (rev 5338) @@ -1,3 +1,8 @@ +2010-05-12 Werner Koch + + * Makefile.am (gpgsm_LDADD): Include NETLIBS which is required for + Solaris. + 2010-03-12 Werner Koch * server.c (cmd_passwd): New. From trunk. Modified: branches/STABLE-BRANCH-2-0/sm/Makefile.am =================================================================== --- branches/STABLE-BRANCH-2-0/sm/Makefile.am 2010-05-12 10:35:16 UTC (rev 5337) +++ branches/STABLE-BRANCH-2-0/sm/Makefile.am 2010-05-12 10:35:58 UTC (rev 5338) @@ -55,7 +55,7 @@ common_libs = $(libcommon) ../kbx/libkeybox.a ../jnlib/libjnlib.a \ ../gl/libgnu.a -gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a \ +gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a $(NETLIBS) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ $(GPG_ERROR_LIBS) $(LIBREADLINE) $(LIBINTL) $(ZLIBS) $(LIBICONV) From cvs at cvs.gnupg.org Wed May 12 12:53:03 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 12:53:03 +0200 Subject: [svn] GnuPG - r5339 - branches/STABLE-BRANCH-2-0/g10 Message-ID: Author: wk Date: 2010-05-12 12:53:02 +0200 (Wed, 12 May 2010) New Revision: 5339 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog branches/STABLE-BRANCH-2-0/g10/plaintext.c Log: Fix bug 1207 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-12 10:35:58 UTC (rev 5338) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-12 10:53:02 UTC (rev 5339) @@ -1,3 +1,8 @@ +2010-05-12 Werner Koch + + * plaintext.c (handle_plaintext): Check return code of fflush. + Fixes bug#1207. + 2010-05-07 Werner Koch * import.c (chk_self_sigs): Check direct key signatures. Fixes Modified: branches/STABLE-BRANCH-2-0/g10/plaintext.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/plaintext.c 2010-05-12 10:35:58 UTC (rev 5338) +++ branches/STABLE-BRANCH-2-0/g10/plaintext.c 2010-05-12 10:53:02 UTC (rev 5339) @@ -402,7 +402,15 @@ /* Make sure that stdout gets flushed after the plaintext has been handled. This is for extra security as we do a flush anyway before checking the signature. */ - fflush (stdout); + if (fflush (stdout)) + { + /* We need to check the return code to detect errors like disk + full for short plaintexts. See bug#1207. Checking return + values is a good idea in any case. */ + if (!rc) + rc = gpg_error_from_syserror (); + log_error ("error flushing `%s': %s\n", "[stdout]", strerror (errno) ); + } if( fp && fp != stdout ) fclose (fp); From cvs at cvs.gnupg.org Wed May 12 13:03:28 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 13:03:28 +0200 Subject: [svn] GnuPG - r5340 - branches/STABLE-BRANCH-2-0/agent Message-ID: Author: wk Date: 2010-05-12 13:03:28 +0200 (Wed, 12 May 2010) New Revision: 5340 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/preset-passphrase.c Log: Fix bug#1198 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-12 10:53:02 UTC (rev 5339) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-12 11:03:28 UTC (rev 5340) @@ -1,5 +1,8 @@ 2010-05-12 Werner Koch + * preset-passphrase.c (forget_passphrase): Actually implement + this. Fixes bug#1198. + * gpg-agent.c (handle_tick): Do not print die message with option -q. 2010-05-11 Werner Koch Modified: branches/STABLE-BRANCH-2-0/agent/preset-passphrase.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/preset-passphrase.c 2010-05-12 10:53:02 UTC (rev 5339) +++ branches/STABLE-BRANCH-2-0/agent/preset-passphrase.c 2010-05-12 11:03:28 UTC (rev 5340) @@ -189,11 +189,15 @@ rc = asprintf (&line, "CLEAR_PASSPHRASE %s\n", keygrip); if (rc < 0) + rc = gpg_error_from_syserror (); + else + rc = map_spwq_error (simple_query (line)); + if (rc) { - log_error ("clearing passphrase failed: %s\n", - gpg_strerror (gpg_error_from_syserror ())); + log_error ("clearing passphrase failed: %s\n", gpg_strerror (rc)); return; } + xfree (line); } From cvs at cvs.gnupg.org Wed May 12 18:06:40 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 18:06:40 +0200 Subject: [svn] GnuPG - r5341 - in branches/STABLE-BRANCH-1-4: . checks g10 tools util Message-ID: Author: wk Date: 2010-05-12 18:06:38 +0200 (Wed, 12 May 2010) New Revision: 5341 Modified: branches/STABLE-BRANCH-1-4/NEWS branches/STABLE-BRANCH-1-4/checks/ChangeLog branches/STABLE-BRANCH-1-4/checks/armor.test branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/armor.c branches/STABLE-BRANCH-1-4/tools/ChangeLog branches/STABLE-BRANCH-1-4/util/iobuf.c Log: Fix bug 1179 Modified: branches/STABLE-BRANCH-1-4/checks/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/checks/ChangeLog 2010-05-12 11:03:28 UTC (rev 5340) +++ branches/STABLE-BRANCH-1-4/checks/ChangeLog 2010-05-12 16:06:38 UTC (rev 5341) @@ -1,3 +1,7 @@ +2010-05-12 Werner Koch + + * armor.test: Extend to test bug 1179. + 2007-12-14 Werner Koch * Makefile.am (./gpg_dearmor): Revert last change. The actual fix Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-05-12 11:03:28 UTC (rev 5340) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-05-12 16:06:38 UTC (rev 5341) @@ -1,3 +1,7 @@ +2010-05-12 Werner Koch + + * armor.c (radix64_read): Change fix 2006-04-08 to fix bug#1179. + 2010-05-07 Werner Koch * import.c (chk_self_sigs): Check direct key signatures. Fixes Modified: branches/STABLE-BRANCH-1-4/tools/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/tools/ChangeLog 2010-05-12 11:03:28 UTC (rev 5340) +++ branches/STABLE-BRANCH-1-4/tools/ChangeLog 2010-05-12 16:06:38 UTC (rev 5341) @@ -1,3 +1,7 @@ +2010-05-12 Werner Koch + + * mk-tdata.c (main): Add option --seq. + 2007-10-23 Werner Koch Switched entire package to GPLv3+. Modified: branches/STABLE-BRANCH-1-4/NEWS =================================================================== --- branches/STABLE-BRANCH-1-4/NEWS 2010-05-12 11:03:28 UTC (rev 5340) +++ branches/STABLE-BRANCH-1-4/NEWS 2010-05-12 16:06:38 UTC (rev 5341) @@ -1,6 +1,7 @@ Noteworthy changes in version 1.4.11 ------------------------------------------------- + * Bug fixes. Noteworthy changes in version 1.4.10 (2009-09-02) ------------------------------------------------- Modified: branches/STABLE-BRANCH-1-4/checks/armor.test =================================================================== --- branches/STABLE-BRANCH-1-4/checks/armor.test 2010-05-12 11:03:28 UTC (rev 5340) +++ branches/STABLE-BRANCH-1-4/checks/armor.test 2010-05-12 16:06:38 UTC (rev 5341) @@ -177,5 +177,578 @@ $GPG --import x || error "the $i bug is back in town" +nopad_armored_msg='-----BEGIN PGP MESSAGE----- +Version: GnuPG v1.4.11-svn5139 (GNU/Linux) +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 +jnOKMUrdbDkbYM+ojXZ18/4WPKtaxf6lTLrh3m5CJ1V8slRJp0Jes74aDQf/OXqo +QgqVrI2wnl1klGwn06bhVaymdk0hMkxAfeHBGZIQ4BMMZ3aLuVWjAcBH/HP1tVQ4 +IG7MHRnm81yVNgA6yAuZZIPQwxDWVko7rRm/DnsJcpKfL0nZHoF+bJ6q4Rd6Dey1 +S96L4PDmXseFkVZOH/7dNWyKuvSA/MmthkN14lWJiYJebaXb7oZG3XDC70o7bG6Y +mtGOrOwVthFereg1Ii98ZA4nKgqeu2paMju/t03hQXHY5iqyV9ax0A3B0rdivz4U +VbqCcO7pGNb/Ki3gGc3hfVw9YXnR7E+tra19eE7UM7o+YlunKF1Q5dJaLKY1z3L9 +3UAJmXG/sZcLqrDn9zHfb/YxqbyIkM7VIU2kKztWCCNiNKgLQsIoVzK4sbS2LVDI +grmvZg+Q7EkwxZ1FXeBGJmsiyjKYPU3PI8ZBU1MXjwTjtnQRuBSxh+Ok9glPeE+1 +rUDdlVoogUGgPAvLV3BM43E/Q5VE+X04KvPNKINvvS1nZpGKyyy1MayOfstc7Hsw +W/RgllTEd7VW5jgZKg7YyA8r8cUjMqE7zewrq6MtkoFk6ZVslWxfoADBW3ivwdwe +I4XwNboOgBx77qxf95aHRRdqWZa0JF8zvK5BH6EpBI29hlJU4leax696ACA7QIIM +Rpc+ulkvHsNxsUlrUut9AXoob0MqDJRmZvU4gSVivHjvKLEIlymJw4pLbMWhcrNa +v94TExP21Fy/zYcWiZT2nCX6qZVXTcUcQGIrBTWDbR8bxKll4FNo/2zmelyFmeXt +iH+Zp2EwFAUELsrxx9plNd5WceyU9VnZoeucNFd2QFl7lV9KL8AlQaaMdsYOt27m +8j7iNBID4HtCYM0xLwE/5uqVQPxX6qzPPZc66MSRIi8ZHZPFvVilFVzFyZSrq5Lo +ojQQmAycQGOzx7dwx7vi9SeTrBRY2PK3WVurcLiRxM+2u9vjlxigwimpnK3VU1dh +GDoPghB3O34bfiV5GndcnPDLJxsSGWz2z2WiyCFgCkVp3shHUN5c2PLWDIOf/Ejz +LzNJXFKjO6/6ZGpMmGf6bZCa9MBnvXMNic9/k0lmtbgj8SS+2//gko1EDa/Gpaqo +J2xgEuHLvp9KQABWt9VRI+tNUJQCS/Jq10ZiT1TzhczyJEqbtVDOo0l5A5sMV0PO +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 +=3akT +-----END PGP MESSAGE----- +' + +alpha_seckey='-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1.4.8 (GNU/Linux) + +lQHhBDbjjp4RBAC2ZbFDX0wmJI8yLDYQdIiZeAuHLmfyHsqXaLGUMZtWiAvn/hNp +ctwahmzKm5oXinHUvUkLOQ0s8rOlu15nhw4azc30rTP1LsIkn5zORNnFdgYC6RKy +hOeim/63+/yGtdnTm49lVfaCqwsEmBCEkXaeWDGq+ie1b89J89T6n/JquwCgoQkj +VeVGG+B/SzJ6+yifdHWQVkcD/RXDyLXX4+WHGP2aet51XlKojWGwsZmc9LPPYhwU +/RcUO7ce1QQb0XFlUVFBhY0JQpM/ty/kNi+aGWFzigbQ+HAWZkUvA8+VIAVneN+p ++SHhGIyLTXKpAYTq46AwvllZ5Cpvf02Cp/+W1aVyA0qnBWMyeIxXmR9HOi6lxxn5 +cjajA/9VZufOXWqCXkBvz4Oy3Q5FbjQQ0/+ty8rDn8OTaiPi41FyUnEi6LO+qyBS +09FjnZj++PkcRcXW99SNxmEJRY7MuNHt5wIvEH2jNEOJ9lszzZFBDbuwsjXHK35+ +lPbGEy69xCP26iEafysKKbRXJhE1C+tk8SnK+Gm62sivmK/5av4CAwKcF1Qep+Pf +ssOqtJhr+klruUBf55onBJi4vkk0gK3m32p/05YB2bbMURGz8R4JxUZfUxjdDk73 +LaNYRbQpQWxwaGEgVGVzdCAoZGVtbyBrZXkpIDxhbHBoYUBleGFtcGxlLm5ldD6I +VQQTEQIAFQUCNuOOngMLCgMDFQMCAxYCAQIXgAAKCRAtcnzHaGl3NDl4AJ4rouHB ++LpCkNi5C59jHEa1kbANzACgmddtrNSj1yPyTCwUwRghPUomECS0EEFsaWNlIChk +ZW1vIGtleSmIVQQTEQIAFQUCNuO2qwMLCgMDFQMCAxYCAQIXgAAKCRAtcnzHaGl3 +NCeMAJ9MeUVrago5Jc6PdwdeN5OMwby37QCghW65cZTQlD1bBlIq/QM8bz9AN4G0 +J0FsZmEgVGVzdCAoZGVtbyBrZXkpIDxhbGZhQGV4YW1wbGUubmV0PohVBBMRAgAV +BQI247hYAwsKAwMVAwIDFgIBAheAAAoJEC1yfMdoaXc0t8IAoJPwa6j+Vm5Vi3Nv +uo8JZri4PJ/DAJ9dqbmaJdB8FdJnHfGh1rXK3y/Jcp0BuAQ2448PEAQAnI3XH1f0 +uyN9fZnw72zsHMw706g7EW29nD4UDQG4OzRZViSrUa5n39eI7QrfTO+1meVvs0y8 +F/PvFst5jH68rPLnGSrXz4sTl1T4cop1FBkquvCAKwPLy0lE7jjtCyItOSwIOo8x +oTfY4JEEXmcqsbm+KHv9yYSF/YK4Cf7bIzcAAwcD/Rnl5jKxoucDA96pD2829TKs +LFQSau+Xiy8bvOSSDdlyABsOkNBSaeKO3eAQEKgDM7dzjVNTnAlpQ0EQ8Y9Z8pxO +WYEQYlaMrnRBC4DZ2IadzEhLlIOz5BVp/jfhrr8oVVBwKZXsrz9PZLz+e4Yn+siU +Uvlei9boD9L2ZgSOHakP/gIDApwXVB6n49+yw6e5k2VJBGTFDkQbxpgi4oslePpT +7Tc2qjAke4zO8JHkgKSokEgnMpMz412q9otFX/3qC5MpPG5P8f4r00Kfy9Am/thk +ri01WTIUqF8L/VZXJxLKVoRAabSXudG0eavfah14fN5/+Bw5i8vSHhc/xmQEKTya +2X8Nt1F5zMrE1LAGVVCL9i/DUygnJYOZzAd1Ct0RJ4kFj7lOBICF2IWWiEYEGBEC +AAYFAjbjjw8ACgkQLXJ8x2hpdzQgqQCgn81AaW8W/lyVwMh/UBeMuVMUb24An2uz +wg7Md81a5RI3F2FG8747t9gX +=VM1e +-----END PGP PRIVATE KEY BLOCK----- +' + +# Bug 1179 solved 2010-05-12: +# It occured for messages of a multiple of the iobuf block size where +# the last line had no pad character. Due to premature poppng of thea +# rmor filter gpg swalled the CRC line and passed the '-----END...' +# line on to the decryption layer. + +i=alpha_seckey +info "importing: $i" +eval "(IFS=; echo \"\$$i\")" >x +$GPG --import x || true + +i=nopad_armored_msg +info "checking: $i" +eval "(IFS=; echo \"\$$i\")" >x +if echo "abc" | $GPG --passphrase-fd 0 -o - x > /dev/null ; then + : +else + error "bug#1179 is back in town" +fi Modified: branches/STABLE-BRANCH-1-4/g10/armor.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/armor.c 2010-05-12 11:03:28 UTC (rev 5340) +++ branches/STABLE-BRANCH-1-4/g10/armor.c 2010-05-12 16:06:38 UTC (rev 5341) @@ -775,14 +775,14 @@ if( !maxlen ) afx->truncated++; if( !afx->buffer_len ) - break; /* eof */ + break; /* eof */ continue; } again: if( c == '\n' || c == ' ' || c == '\r' || c == '\t' ) continue; - else if( c == '=' ) { /* pad character: stop */ + else if( c == '=' ) { /* Pad character: stop or CRC sum starts. */ /* some mailers leave quoted-printable encoded characters * so we try to workaround this */ if( afx->buffer_pos+2 < afx->buffer_len ) { @@ -801,8 +801,9 @@ goto again; } } - else if(n==0) - onlypad=1; + + if (!n) + onlypad = 1; if( idx == 1 ) buf[n++] = val; Modified: branches/STABLE-BRANCH-1-4/util/iobuf.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/iobuf.c 2010-05-12 11:03:28 UTC (rev 5340) +++ branches/STABLE-BRANCH-1-4/util/iobuf.c 2010-05-12 16:06:38 UTC (rev 5341) @@ -44,7 +44,7 @@ /* The size of the internal buffers. NOTE: If you change this value you MUST also adjust the regression - test "armored_key_8192" in armor.test! */ + test "armored_key_8192" and "nopad_armored_msg" in armor.test! */ #define IOBUF_BUFFER_SIZE 8192 From cvs at cvs.gnupg.org Wed May 12 18:18:50 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 18:18:50 +0200 Subject: [svn] GnuPG - r5342 - in branches/STABLE-BRANCH-2-0: g10 tests/openpgp Message-ID: Author: wk Date: 2010-05-12 18:18:49 +0200 (Wed, 12 May 2010) New Revision: 5342 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog branches/STABLE-BRANCH-2-0/g10/armor.c branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog branches/STABLE-BRANCH-2-0/tests/openpgp/armor.test Log: Fix bug#1179 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-12 16:06:38 UTC (rev 5341) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-05-12 16:18:49 UTC (rev 5342) @@ -1,5 +1,7 @@ 2010-05-12 Werner Koch + * armor.c (radix64_read): Change fix 2006-04-28 to fix bug#1179. + * plaintext.c (handle_plaintext): Check return code of fflush. Fixes bug#1207. Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog 2010-05-12 16:06:38 UTC (rev 5341) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/ChangeLog 2010-05-12 16:18:49 UTC (rev 5342) @@ -1,5 +1,7 @@ 2010-05-12 Werner Koch + * armor.test: Add test for bug#1179. + * Makefile.am (TESTS_ENVIRONMENT): New. Start all scripts udner the control of the gpg-agent. (prepared.stamp): Create gpg-agent.conf. Modified: branches/STABLE-BRANCH-2-0/g10/armor.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/armor.c 2010-05-12 16:06:38 UTC (rev 5341) +++ branches/STABLE-BRANCH-2-0/g10/armor.c 2010-05-12 16:18:49 UTC (rev 5342) @@ -1,4 +1,4 @@ -/* armor.c - Armor flter +/* armor.c - Armor filter * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, * 2007 Free Software Foundation, Inc. * @@ -797,9 +797,10 @@ goto again; } } - else if(n==0) - onlypad=1; + if (!n) + onlypad = 1; + if( idx == 1 ) buf[n++] = val; checkcrc++; Modified: branches/STABLE-BRANCH-2-0/tests/openpgp/armor.test =================================================================== --- branches/STABLE-BRANCH-2-0/tests/openpgp/armor.test 2010-05-12 16:06:38 UTC (rev 5341) +++ branches/STABLE-BRANCH-2-0/tests/openpgp/armor.test 2010-05-12 16:18:49 UTC (rev 5342) @@ -185,4 +185,580 @@ +nopad_armored_msg='-----BEGIN PGP MESSAGE----- +Version: GnuPG v1.4.11-svn5139 (GNU/Linux) +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 +jnOKMUrdbDkbYM+ojXZ18/4WPKtaxf6lTLrh3m5CJ1V8slRJp0Jes74aDQf/OXqo +QgqVrI2wnl1klGwn06bhVaymdk0hMkxAfeHBGZIQ4BMMZ3aLuVWjAcBH/HP1tVQ4 +IG7MHRnm81yVNgA6yAuZZIPQwxDWVko7rRm/DnsJcpKfL0nZHoF+bJ6q4Rd6Dey1 +S96L4PDmXseFkVZOH/7dNWyKuvSA/MmthkN14lWJiYJebaXb7oZG3XDC70o7bG6Y +mtGOrOwVthFereg1Ii98ZA4nKgqeu2paMju/t03hQXHY5iqyV9ax0A3B0rdivz4U +VbqCcO7pGNb/Ki3gGc3hfVw9YXnR7E+tra19eE7UM7o+YlunKF1Q5dJaLKY1z3L9 +3UAJmXG/sZcLqrDn9zHfb/YxqbyIkM7VIU2kKztWCCNiNKgLQsIoVzK4sbS2LVDI +grmvZg+Q7EkwxZ1FXeBGJmsiyjKYPU3PI8ZBU1MXjwTjtnQRuBSxh+Ok9glPeE+1 +rUDdlVoogUGgPAvLV3BM43E/Q5VE+X04KvPNKINvvS1nZpGKyyy1MayOfstc7Hsw +W/RgllTEd7VW5jgZKg7YyA8r8cUjMqE7zewrq6MtkoFk6ZVslWxfoADBW3ivwdwe +I4XwNboOgBx77qxf95aHRRdqWZa0JF8zvK5BH6EpBI29hlJU4leax696ACA7QIIM +Rpc+ulkvHsNxsUlrUut9AXoob0MqDJRmZvU4gSVivHjvKLEIlymJw4pLbMWhcrNa +v94TExP21Fy/zYcWiZT2nCX6qZVXTcUcQGIrBTWDbR8bxKll4FNo/2zmelyFmeXt +iH+Zp2EwFAUELsrxx9plNd5WceyU9VnZoeucNFd2QFl7lV9KL8AlQaaMdsYOt27m +8j7iNBID4HtCYM0xLwE/5uqVQPxX6qzPPZc66MSRIi8ZHZPFvVilFVzFyZSrq5Lo +ojQQmAycQGOzx7dwx7vi9SeTrBRY2PK3WVurcLiRxM+2u9vjlxigwimpnK3VU1dh +GDoPghB3O34bfiV5GndcnPDLJxsSGWz2z2WiyCFgCkVp3shHUN5c2PLWDIOf/Ejz +LzNJXFKjO6/6ZGpMmGf6bZCa9MBnvXMNic9/k0lmtbgj8SS+2//gko1EDa/Gpaqo +J2xgEuHLvp9KQABWt9VRI+tNUJQCS/Jq10ZiT1TzhczyJEqbtVDOo0l5A5sMV0PO +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 +=3akT +-----END PGP MESSAGE----- + +' + +alpha_seckey='-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1.4.8 (GNU/Linux) + +lQHhBDbjjp4RBAC2ZbFDX0wmJI8yLDYQdIiZeAuHLmfyHsqXaLGUMZtWiAvn/hNp +ctwahmzKm5oXinHUvUkLOQ0s8rOlu15nhw4azc30rTP1LsIkn5zORNnFdgYC6RKy +hOeim/63+/yGtdnTm49lVfaCqwsEmBCEkXaeWDGq+ie1b89J89T6n/JquwCgoQkj +VeVGG+B/SzJ6+yifdHWQVkcD/RXDyLXX4+WHGP2aet51XlKojWGwsZmc9LPPYhwU +/RcUO7ce1QQb0XFlUVFBhY0JQpM/ty/kNi+aGWFzigbQ+HAWZkUvA8+VIAVneN+p ++SHhGIyLTXKpAYTq46AwvllZ5Cpvf02Cp/+W1aVyA0qnBWMyeIxXmR9HOi6lxxn5 +cjajA/9VZufOXWqCXkBvz4Oy3Q5FbjQQ0/+ty8rDn8OTaiPi41FyUnEi6LO+qyBS +09FjnZj++PkcRcXW99SNxmEJRY7MuNHt5wIvEH2jNEOJ9lszzZFBDbuwsjXHK35+ +lPbGEy69xCP26iEafysKKbRXJhE1C+tk8SnK+Gm62sivmK/5av4CAwKcF1Qep+Pf +ssOqtJhr+klruUBf55onBJi4vkk0gK3m32p/05YB2bbMURGz8R4JxUZfUxjdDk73 +LaNYRbQpQWxwaGEgVGVzdCAoZGVtbyBrZXkpIDxhbHBoYUBleGFtcGxlLm5ldD6I +VQQTEQIAFQUCNuOOngMLCgMDFQMCAxYCAQIXgAAKCRAtcnzHaGl3NDl4AJ4rouHB ++LpCkNi5C59jHEa1kbANzACgmddtrNSj1yPyTCwUwRghPUomECS0EEFsaWNlIChk +ZW1vIGtleSmIVQQTEQIAFQUCNuO2qwMLCgMDFQMCAxYCAQIXgAAKCRAtcnzHaGl3 +NCeMAJ9MeUVrago5Jc6PdwdeN5OMwby37QCghW65cZTQlD1bBlIq/QM8bz9AN4G0 +J0FsZmEgVGVzdCAoZGVtbyBrZXkpIDxhbGZhQGV4YW1wbGUubmV0PohVBBMRAgAV +BQI247hYAwsKAwMVAwIDFgIBAheAAAoJEC1yfMdoaXc0t8IAoJPwa6j+Vm5Vi3Nv +uo8JZri4PJ/DAJ9dqbmaJdB8FdJnHfGh1rXK3y/Jcp0BuAQ2448PEAQAnI3XH1f0 +uyN9fZnw72zsHMw706g7EW29nD4UDQG4OzRZViSrUa5n39eI7QrfTO+1meVvs0y8 +F/PvFst5jH68rPLnGSrXz4sTl1T4cop1FBkquvCAKwPLy0lE7jjtCyItOSwIOo8x +oTfY4JEEXmcqsbm+KHv9yYSF/YK4Cf7bIzcAAwcD/Rnl5jKxoucDA96pD2829TKs +LFQSau+Xiy8bvOSSDdlyABsOkNBSaeKO3eAQEKgDM7dzjVNTnAlpQ0EQ8Y9Z8pxO +WYEQYlaMrnRBC4DZ2IadzEhLlIOz5BVp/jfhrr8oVVBwKZXsrz9PZLz+e4Yn+siU +Uvlei9boD9L2ZgSOHakP/gIDApwXVB6n49+yw6e5k2VJBGTFDkQbxpgi4oslePpT +7Tc2qjAke4zO8JHkgKSokEgnMpMz412q9otFX/3qC5MpPG5P8f4r00Kfy9Am/thk +ri01WTIUqF8L/VZXJxLKVoRAabSXudG0eavfah14fN5/+Bw5i8vSHhc/xmQEKTya +2X8Nt1F5zMrE1LAGVVCL9i/DUygnJYOZzAd1Ct0RJ4kFj7lOBICF2IWWiEYEGBEC +AAYFAjbjjw8ACgkQLXJ8x2hpdzQgqQCgn81AaW8W/lyVwMh/UBeMuVMUb24An2uz +wg7Md81a5RI3F2FG8747t9gX +=VM1e +-----END PGP PRIVATE KEY BLOCK----- +' + +# Bug 1179 solved 2010-05-12: +# It occured for messages of a multiple of the iobuf block size where +# the last line had no pad character. Due to premature poppng of thea +# rmor filter gpg swalled the CRC line and passed the '-----END...' +# line on to the decryption layer. + +i=alpha_seckey +info "importing: $i" +eval "(IFS=; echo \"\$$i\")" >x +$GPG --import x || true + +i=nopad_armored_msg +info "checking: $i" +eval "(IFS=; echo \"\$$i\")" >x +if echo "abc" | $GPG --passphrase-fd 0 -o - x > /dev/null ; then + : +else + error "bug#1179 is back in town" +fi + + From cvs at cvs.gnupg.org Wed May 12 18:55:39 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 12 May 2010 18:55:39 +0200 Subject: [svn] gpgme - r1470 - trunk/src Message-ID: Author: marcus Date: 2010-05-12 18:55:39 +0200 (Wed, 12 May 2010) New Revision: 1470 Modified: trunk/src/ChangeLog trunk/src/priv-io.h trunk/src/util.h Log: 2010-05-12 Marcus Brinkmann * priv-io.h: Include * util.h: Likewise. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-11 17:20:45 UTC (rev 1469) +++ trunk/src/ChangeLog 2010-05-12 16:55:39 UTC (rev 1470) @@ -1,3 +1,8 @@ +2010-05-12 Marcus Brinkmann + + * priv-io.h: Include + * util.h: Likewise. + 2010-05-11 Marcus Brinkmann * w32-util.c: Include ath.h Modified: trunk/src/priv-io.h =================================================================== --- trunk/src/priv-io.h 2010-05-11 17:20:45 UTC (rev 1469) +++ trunk/src/priv-io.h 2010-05-12 16:55:39 UTC (rev 1470) @@ -28,6 +28,10 @@ # include #endif +/* For pid_t. */ +#include + + /* A single file descriptor passed to spawn. For child fds, dup_to specifies the fd it should become in the child, but only 0, 1 and 2 are valid values (due to a limitation in the W32 code). As return Modified: trunk/src/util.h =================================================================== --- trunk/src/util.h 2010-05-11 17:20:45 UTC (rev 1469) +++ trunk/src/util.h 2010-05-12 16:55:39 UTC (rev 1470) @@ -22,6 +22,13 @@ #ifndef UTIL_H #define UTIL_H +#ifdef HAVE_W32CE_SYSTEM +#include "w32-ce.h" +#endif + +/* For pid_t. */ +#include + #include "gpgme.h" From cvs at cvs.gnupg.org Wed May 12 19:13:10 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 19:13:10 +0200 Subject: [svn] pinentry - r232 - in trunk: . gtk+-2 Message-ID: Author: wk Date: 2010-05-12 19:13:10 +0200 (Wed, 12 May 2010) New Revision: 232 Modified: trunk/ChangeLog trunk/gtk+-2/gtksecentry.h Log: Make -DSEAL safe. Fixes bug#1224 Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-05-07 17:26:10 UTC (rev 231) +++ trunk/ChangeLog 2010-05-12 17:13:10 UTC (rev 232) @@ -1,3 +1,9 @@ +2010-05-12 Guido G?nther (wk) + + * gtk+-2/gtksecentry.c: Make -DSEAL safe. + * gtk+-2/gseal-gtk-compat.h: New. + * gtk+-2/gtksecentry.h: Include new header. + 2010-05-07 Werner Koch * gtk+-2/pinentry-gtk-2.c (create_window): Keep the window above Modified: trunk/gtk+-2/gtksecentry.h =================================================================== --- trunk/gtk+-2/gtksecentry.h 2010-05-07 17:26:10 UTC (rev 231) +++ trunk/gtk+-2/gtksecentry.h 2010-05-12 17:13:10 UTC (rev 232) @@ -39,6 +39,7 @@ #include +#include "gseal-gtk-compat.h" #ifdef __cplusplus extern "C" { From cvs at cvs.gnupg.org Wed May 12 19:13:29 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 12 May 2010 19:13:29 +0200 Subject: [svn] pinentry - r233 - trunk/gtk+-2 Message-ID: Author: wk Date: 2010-05-12 19:13:29 +0200 (Wed, 12 May 2010) New Revision: 233 Added: trunk/gtk+-2/gseal-gtk-compat.h Log: Add required header From cvs at cvs.gnupg.org Wed May 12 19:21:37 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 12 May 2010 19:21:37 +0200 Subject: [svn] gpgme - r1471 - trunk/src Message-ID: Author: marcus Date: 2010-05-12 19:21:36 +0200 (Wed, 12 May 2010) New Revision: 1471 Added: trunk/src/w32-ce.c trunk/src/w32-ce.h Modified: trunk/src/ChangeLog trunk/src/Makefile.am Log: 2010-05-12 Marcus Brinkmann * Makefile.am (system_components): Remove custom cppflags from RCCOMPILE (because gpg-error adds -idirafter that makes RC bail. [HAVE_W32CE_SYSTEM]: Add w32-ce.h and w32-ce.c, clear libexec_PROGRAMS. * w32-ce.h, w32-ce.c: New files. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-12 16:55:39 UTC (rev 1470) +++ trunk/src/ChangeLog 2010-05-12 17:21:36 UTC (rev 1471) @@ -1,5 +1,11 @@ 2010-05-12 Marcus Brinkmann + * Makefile.am (system_components): Remove custom cppflags from + RCCOMPILE (because gpg-error adds -idirafter that makes RC bail. + [HAVE_W32CE_SYSTEM]: Add w32-ce.h and w32-ce.c, clear + libexec_PROGRAMS. + * w32-ce.h, w32-ce.c: New files. + * priv-io.h: Include * util.h: Likewise. Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2010-05-12 16:55:39 UTC (rev 1470) +++ trunk/src/Makefile.am 2010-05-12 17:21:36 UTC (rev 1471) @@ -68,6 +68,10 @@ system_components_not_extra = endif +if HAVE_W32CE_SYSTEM +system_components += w32-ce.h w32-ce.c +endif + if HAVE_GPGSM gpgsm_components = engine-gpgsm.c else @@ -155,14 +159,17 @@ AM_CFLAGS = @LIBASSUAN_CFLAGS@ @PTH_CFLAGS@ @GLIB_CFLAGS@ @QT4_CORE_CFLAGS@ if HAVE_W32_SYSTEM - # Windows provides us with an endless stream of Tough Love. To spawn # processes with a controlled set of inherited handles, we need a # wrapper process. +# Except on Windows CE. There nothing is inheritable anyway. +if HAVE_W32CE_SYSTEM +libexec_PROGRAMS = +else libexec_PROGRAMS = gpgme-w32spawn +endif -RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) +RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) SUFFIXES = .rc .lo Added: trunk/src/w32-ce.c =================================================================== --- trunk/src/w32-ce.c (rev 0) +++ trunk/src/w32-ce.c 2010-05-12 17:21:36 UTC (rev 1471) @@ -0,0 +1,405 @@ +/* w32-ce.h + Copyright (C) 2010 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 + +#include + +#include "w32-ce.h" + + +/* Return a malloced string encoded in UTF-8 from the wide char input + string STRING. Caller must free this value. Returns NULL and sets + ERRNO on failure. Calling this function with STRING set to NULL is + not defined. */ +char * +wchar_to_utf8 (const wchar_t *string) +{ + int n; + char *result; + + n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL); + if (n < 0) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + + result = malloc (n+1); + if (!result) + return NULL; + + n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL); + if (n < 0) + { + free (result); + gpg_err_set_errno (EINVAL); + result = NULL; + } + return result; +} + + +/* Return a malloced wide char string from an UTF-8 encoded input + string STRING. Caller must free this value. Returns NULL and sets + ERRNO on failure. Calling this function with STRING set to NULL is + not defined. */ +wchar_t * +utf8_to_wchar (const char *string) +{ + int n; + size_t nbytes; + wchar_t *result; + + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0); + if (n < 0) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + + nbytes = (size_t)(n+1) * sizeof(*result); + if (nbytes / sizeof(*result) != (n+1)) + { + gpg_err_set_errno (ENOMEM); + return NULL; + } + result = malloc (nbytes); + if (!result) + return NULL; + + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n); + if (n < 0) + { + free (result); + gpg_err_set_errno (EINVAL); + result = NULL; + } + return result; +} + + +#define MAX_ENV 30 + +char *environ[MAX_ENV + 1]; + +char * +getenv (const char *name) +{ + static char *past_result; + char **envp; + + if (past_result) + { + free (past_result); + past_result = NULL; + } + +#if 0 + if (! strcmp (name, "DBUS_VERBOSE")) + return past_result = get_verbose_setting (); + else if (! strcmp (name, "HOMEPATH")) + return past_result = find_my_documents_folder (); + else if (! strcmp (name, "DBUS_DATADIR")) + return past_result = find_inst_subdir ("share"); +#endif + + for (envp = environ; *envp != 0; envp++) + { + const char *varp = name; + char *ep = *envp; + + while (*varp == *ep && *varp != '\0') + { + ++ep; + ++varp; + }; + + if (*varp == '\0' && *ep == '=') + return ep + 1; + } + + return NULL; +} + + +void +GetSystemTimeAsFileTime (LPFILETIME ftp) +{ + SYSTEMTIME st; + GetSystemTime (&st); + SystemTimeToFileTime (&st, ftp); +} + + +BOOL +DeleteFileA (LPCSTR lpFileName) +{ + wchar_t *filename; + BOOL result; + int err; + + filename = utf8_to_wchar (lpFileName); + if (!filename) + return FALSE; + + result = DeleteFileW (filename); + + err = GetLastError (); + free (filename); + SetLastError (err); + return result; +} + + +BOOL +CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine, + LPSECURITY_ATTRIBUTES psaProcess, + LPSECURITY_ATTRIBUTES psaThread, BOOL fInheritHandles, + DWORD fdwCreate, PVOID pvEnvironment, LPCSTR pszCurDir, + LPSTARTUPINFOA psiStartInfo, + LPPROCESS_INFORMATION pProcInfo) +{ + wchar_t *image_name = NULL; + wchar_t *cmd_line = NULL; + BOOL result; + int err; + + assert (psaProcess == NULL); + assert (psaThread == NULL); + assert (fInheritHandles == FALSE); + assert (pvEnvironment == NULL); + assert (pszCurDir == NULL); + /* psiStartInfo is generally not NULL. */ + + if (pszImageName) + { + image_name = utf8_to_wchar (pszImageName); + if (!image_name) + return 0; + } + if (pszCmdLine) + { + cmd_line = utf8_to_wchar (pszCmdLine); + if (!cmd_line) + { + if (image_name) + free (image_name); + return 0; + } + } + + result = CreateProcessW (image_name, cmd_line, NULL, NULL, FALSE, + fdwCreate, NULL, NULL, NULL, pProcInfo); + + err = GetLastError (); + free (image_name); + free (cmd_line); + SetLastError (err); + return result; +} + + +LONG +RegOpenKeyExA (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, + REGSAM samDesired, PHKEY phkResult) +{ + wchar_t *subkey; + LONG result; + int err; + + if (lpSubKey) + { + subkey = utf8_to_wchar (lpSubKey); + if (!subkey) + return 0; + } + else + subkey = NULL; + + result = RegOpenKeyEx (hKey, subkey, ulOptions, samDesired, phkResult); + + err = GetLastError (); + free (subkey); + SetLastError (err); + return result; +} + + +LONG +RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, + LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) +{ + wchar_t *name; + LONG err; + BYTE *data; + DWORD data_len; + DWORD type; + + if (lpValueName) + { + name = utf8_to_wchar (lpValueName); + if (!name) + return GetLastError (); + } + else + name = NULL; + + data_len = 0; + err = RegQueryValueExW (hKey, name, lpReserved, lpType, NULL, &data_len); + if (err || !lpcbData) + { + free (name); + return err; + } + + data = malloc (data_len + sizeof (wchar_t)); + if (!data) + { + free (name); + return ERROR_NOT_ENOUGH_MEMORY; + } + + err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len); + if (lpType) + *lpType = type; + free (name); + /* If err is ERROR_MORE_DATA, there probably was a race condition. + We can punt this to the caller just as well. */ + if (err) + return err; + + /* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they + are not needed in this module. */ + if (type == REG_SZ) + { + char *data_c; + int data_c_len; + + /* This is valid since we allocated one more above. */ + data[data_len] = '\0'; + data[data_len + 1] = '\0'; + + data_c = wchar_to_utf8 ((wchar_t*) data); + if (!data_c) + return GetLastError(); + + data_c_len = strlen (data_c) + 1; + assert (data_c_len <= data_len + sizeof (wchar_t)); + memcpy (data, data_c, data_c_len); + data_len = data_c_len; + free (data_c); + } + + /* DATA and DATA_LEN now contain the result. */ + if (lpData) + { + if (data_len > *lpcbData) + err = ERROR_MORE_DATA; + else + memcpy (lpData, data, data_len); + } + *lpcbData = data_len; + return err; +} + + +DWORD +GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer) +{ + wchar_t dummy[1]; + DWORD len; + + len = GetTempPathW (0, dummy); + if (len == 0) + return 0; + + assert (len <= MAX_PATH); + + /* Better be safe than sorry. MSDN doesn't say if len is with or + without terminating 0. */ + len++; + + { + wchar_t *buffer_w; + DWORD len_w; + char *buffer_c; + DWORD len_c; + + buffer_w = malloc (sizeof (wchar_t) * len); + if (! buffer_w) + return 0; + + len_w = GetTempPathW (len, buffer_w); + /* Give up if we still can't get at it. */ + if (len_w == 0 || len_w >= len) + { + free (buffer_w); + return 0; + } + + /* Better be really safe. */ + buffer_w[len_w] = '\0'; + + buffer_c = wchar_to_utf8 (buffer_w); + free (buffer_w); + if (! buffer_c) + return 0; + + /* strlen is correct (not _mbstrlen), because we want storage and + not string length. */ + len_c = strlen (buffer_c) + 1; + if (len_c > nBufferLength) + return len_c; + + strcpy (lpBuffer, buffer_c); + free (buffer_c); + return len_c - 1; + } +} + + +BOOL +SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder, + BOOL fCreate) +{ + wchar_t path[MAX_PATH]; + char *path_c; + BOOL result; + + path[0] = (wchar_t) 0; + result = SHGetSpecialFolderPathW (hwndOwner, path, nFolder, fCreate); + /* Note: May return false even if succeeds. */ + + path[MAX_PATH - 1] = (wchar_t) 0; + path_c = wchar_to_utf8 (path); + if (! path_c) + return 0; + + strncpy (lpszPath, path_c, MAX_PATH); + free (path_c); + lpszPath[MAX_PATH - 1] = '\0'; + return result; +} Added: trunk/src/w32-ce.h =================================================================== --- trunk/src/w32-ce.h (rev 0) +++ trunk/src/w32-ce.h 2010-05-12 17:21:36 UTC (rev 1471) @@ -0,0 +1,70 @@ +/* w32-ce.h + Copyright (C) 2010 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 GPGME_W32_CE_H +#define GPGME_W32_CE_H + +#include +#include + +/* For getaddrinfo. */ +#define _MSV_VER 0x401 +#include + + +/* shlobj.h declares these only for _WIN32_IE that we don't want to define. + In any case, with mingw32ce we only get a SHGetSpecialFolderPath. */ +#define SHGetSpecialFolderPathW SHGetSpecialFolderPath +BOOL WINAPI SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL); +BOOL WINAPI SHGetSpecialFolderPathW(HWND,LPWSTR,int,BOOL); + + +#define getenv _gpgme_wince_getenv +char *getenv (const char *name); + +#include +#define isatty(fd) 0 + + +/* Windows CE is missing some Windows functions that we want. */ + +#define GetSystemTimeAsFileTime _gpgme_wince_GetSystemTimeAsFileTime +void GetSystemTimeAsFileTime (LPFILETIME ftp); + +#define DeleteFileA _gpgme_wince_DeleteFileA +BOOL DeleteFileA(LPCSTR); + +#define CreateProcessA _gpgme_wince_CreateProcessA +BOOL CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION); + +#define RegOpenKeyExA _gpgme_wince_RegOpenKeyExA +LONG RegOpenKeyExA(HKEY,LPCSTR,DWORD,REGSAM,PHKEY); + +#define RegQueryValueExA _gpgme_wince_RegQueryValueExA +LONG WINAPI RegQueryValueExA(HKEY,LPCSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); + +#define GetTempPathA _gpgme_wince_GetTempPathA +DWORD GetTempPathA(DWORD,LPSTR); + +#define SHGetSpecialFolderPathA _gpgme_wince_SHGetSpecialFolderPathA +BOOL SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL); + + +#endif /* GPGME_W32_CE_H */ From cvs at cvs.gnupg.org Wed May 12 19:40:09 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 12 May 2010 19:40:09 +0200 Subject: [svn] gpgme - r1472 - in trunk: . src Message-ID: Author: marcus Date: 2010-05-12 19:40:08 +0200 (Wed, 12 May 2010) New Revision: 1472 Modified: trunk/ChangeLog trunk/configure.ac trunk/src/ChangeLog trunk/src/gpgme-tool.c Log: 2010-05-12 Marcus Brinkmann * configure.ac: Check for setlocale. src/ 2010-05-12 Marcus Brinkmann * gpgme-tool.c (main): Protect call to setlocale with HAVE_SETLOCALE. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-05-12 17:21:36 UTC (rev 1471) +++ trunk/ChangeLog 2010-05-12 17:40:08 UTC (rev 1472) @@ -1,3 +1,7 @@ +2010-05-12 Marcus Brinkmann + + * configure.ac: Check for setlocale. + 2010-05-07 Werner Koch * configure.ac: Change checks to always require libassuan. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-12 17:21:36 UTC (rev 1471) +++ trunk/src/ChangeLog 2010-05-12 17:40:08 UTC (rev 1472) @@ -1,5 +1,8 @@ 2010-05-12 Marcus Brinkmann + * gpgme-tool.c (main): Protect call to setlocale with + HAVE_SETLOCALE. + * Makefile.am (system_components): Remove custom cppflags from RCCOMPILE (because gpg-error adds -idirafter that makes RC bail. [HAVE_W32CE_SYSTEM]: Add w32-ce.h and w32-ce.c, clear Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-05-12 17:21:36 UTC (rev 1471) +++ trunk/configure.ac 2010-05-12 17:40:08 UTC (rev 1472) @@ -295,6 +295,8 @@ ***]) fi +AC_CHECK_FUNCS(setlocale) + # Checking for libgpg-error. AM_PATH_GPG_ERROR(1.8,, AC_MSG_ERROR([libgpg-error was not found])) AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME, Modified: trunk/src/gpgme-tool.c =================================================================== --- trunk/src/gpgme-tool.c 2010-05-12 17:21:36 UTC (rev 1471) +++ trunk/src/gpgme-tool.c 2010-05-12 17:40:08 UTC (rev 1472) @@ -2908,7 +2908,9 @@ struct args args; struct gpgme_tool gt; +#ifdef HAVE_SETLOCALE setlocale (LC_ALL, ""); +#endif gpgme_check_version (NULL); #ifdef LC_CTYPE gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); From cvs at cvs.gnupg.org Wed May 12 20:20:36 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 12 May 2010 20:20:36 +0200 Subject: [svn] gpgme - r1473 - trunk/src Message-ID: Author: marcus Date: 2010-05-12 20:20:36 +0200 (Wed, 12 May 2010) New Revision: 1473 Modified: trunk/src/ChangeLog trunk/src/conversion.c Log: 2010-05-12 Marcus Brinkmann * conversion.c (_gpgme_timegm) [HAVE_W32_SYSTEM]: New static function. (_gpgme_parse_timestamp) [HAVE_W32_SYSTEM]: Use it. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-05-12 17:40:08 UTC (rev 1472) +++ trunk/src/ChangeLog 2010-05-12 18:20:36 UTC (rev 1473) @@ -1,5 +1,9 @@ 2010-05-12 Marcus Brinkmann + * conversion.c (_gpgme_timegm) [HAVE_W32_SYSTEM]: New static + function. + (_gpgme_parse_timestamp) [HAVE_W32_SYSTEM]: Use it. + * gpgme-tool.c (main): Protect call to setlocale with HAVE_SETLOCALE. Modified: trunk/src/conversion.c =================================================================== --- trunk/src/conversion.c 2010-05-12 17:40:08 UTC (rev 1472) +++ trunk/src/conversion.c 2010-05-12 18:20:36 UTC (rev 1473) @@ -315,6 +315,39 @@ } +#ifdef HAVE_W32_SYSTEM +static time_t +_gpgme_timegm (struct tm *tm) +{ + /* This one is thread safe. */ + SYSTEMTIME st; + FILETIME ft; + unsigned long long cnsecs; + + st.wYear = tm->tm_year + 1900; + st.wMonth = tm->tm_mon + 1; + st.wDay = tm->tm_mday; + st.wHour = tm->tm_hour; + st.wMinute = tm->tm_min; + st.wSecond = tm->tm_sec; + st.wMilliseconds = 0; /* Not available. */ + st.wDayOfWeek = 0; /* Ignored. */ + + /* System time is UTC thus the conversion is pretty easy. */ + if (!SystemTimeToFileTime (&st, &ft)) + { + gpg_err_set_errno (EINVAL); + return (time_t)(-1); + } + + cnsecs = (((unsigned long long)ft.dwHighDateTime << 32) + | ft.dwLowDateTime); + cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01. */ + return (time_t)(cnsecs / 10000000ULL); +} +#endif + + /* Parse the string TIMESTAMP into a time_t. The string may either be seconds since Epoch or in the ISO 8601 format like "20390815T143012". Returns 0 for an empty string or seconds since @@ -354,6 +387,9 @@ if (endp) *endp = (char*)(timestamp + 15); +#ifdef HAVE_W32_SYSTEM + return _gpgme_timegm (&buf); +#else #ifdef HAVE_TIMEGM return timegm (&buf); #else @@ -368,6 +404,7 @@ return tim; } #endif /* !HAVE_TIMEGM */ +#endif /* !HAVE_W32_SYSTEM */ } else return (time_t)strtoul (timestamp, endp, 10); From cvs at cvs.gnupg.org Sun May 30 14:06:38 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Sun, 30 May 2010 14:06:38 +0200 Subject: [svn] GnuPG - r5343 - trunk/common Message-ID: Author: wk Date: 2010-05-30 14:06:38 +0200 (Sun, 30 May 2010) New Revision: 5343 Modified: trunk/common/ChangeLog trunk/common/argparse.c trunk/common/argparse.h trunk/common/init.c Log: Print --version etc via estream Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-05-12 16:18:49 UTC (rev 5342) +++ trunk/common/ChangeLog 2010-05-30 12:06:38 UTC (rev 5343) @@ -1,3 +1,12 @@ +2010-05-30 Werner Koch + + * init.c (writestring_via_estream): New. + (init_common_subsystems): Register with argparse. + + * argparse.c (argparse_register_outfnc): New. + (writestrings, flushstrings): New. Use them instead of stdout or + stderr based functions. + 2010-05-04 Werner Koch * estream.c (_es_get_std_stream): Re-use registered standard fds. Modified: trunk/common/argparse.c =================================================================== --- trunk/common/argparse.c 2010-05-12 16:18:49 UTC (rev 5342) +++ trunk/common/argparse.c 2010-05-30 12:06:38 UTC (rev 5343) @@ -26,6 +26,7 @@ #include #include #include +#include #include "libjnlib-config.h" #include "mischelp.h" @@ -144,13 +145,65 @@ }; static const char *(*strusage_handler)( int ) = NULL; +static int (*custom_outfnc) (int, const char *); static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s); static void show_help(ARGPARSE_OPTS *opts, unsigned flags); static void show_version(void); +static int writestrings (int is_error, const char *string, ...) +#if __GNUC__ >= 4 + __attribute__ ((sentinel(0))) +#endif + ; +void +argparse_register_outfnc (int (*fnc)(int, const char *)) +{ + custom_outfnc = fnc; +} + + +/* Write STRING and all following const char * arguments either to + stdout or, if IS_ERROR is set, to stderr. The list of strings must + be terminated by a NULL. */ +static int +writestrings (int is_error, const char *string, ...) +{ + va_list arg_ptr; + const char *s; + int count = 0; + + if (string) + { + s = string; + va_start (arg_ptr, string); + do + { + if (custom_outfnc) + custom_outfnc (is_error? 2:1, s); + else + fputs (s, is_error? stderr : stdout); + count += strlen (s); + } + while ((s = va_arg (arg_ptr, const char *))); + va_end (arg_ptr); + } + return count; +} + + static void +flushstrings (int is_error) +{ + if (custom_outfnc) + custom_outfnc (is_error? 2:1, NULL); + else + fflush (is_error? stderr : stdout); +} + + +static void initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) { if( !(arg->flags & (1<<15)) ) @@ -630,7 +683,7 @@ } else if ( i < 0 && !strcmp( "warranty", s+2)) { - puts ( strusage (16) ); + writestrings (0, strusage (16), "\n", NULL); exit (0); } else if ( i < 0 && !strcmp( "dump-options", s+2) ) @@ -638,9 +691,10 @@ for (i=0; opts[i].short_opt; i++ ) { if ( opts[i].long_opt ) - printf ("--%s\n", opts[i].long_opt); + writestrings (0, "--", opts[i].long_opt, "\n", NULL); } - fputs ("--dump-options\n--help\n--version\n--warranty\n", stdout); + writestrings (0, "--dump-options\n--help\n--version\n--warranty\n", + NULL); exit (0); } @@ -875,11 +929,12 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags) { const char *s; + char tmp[2]; show_version (); - putchar ('\n'); + writestrings (0, "\n", NULL); s = strusage(41); - puts (s); + writestrings (0, s, "\n", NULL); if ( opts[0].description ) { /* Auto format the option description. */ @@ -897,7 +952,7 @@ /* Example: " -v, --verbose Viele Sachen ausgeben" */ indent += 10; if ( *opts[0].description != '@' ) - puts ("Options:"); + writestrings (0, "Options:", "\n", NULL); for (i=0; opts[i].short_opt; i++ ) { s = _( opts[i].description ); @@ -910,61 +965,76 @@ if ( *s == '\n' ) { if( s[1] ) - putchar('\n'); + writestrings (0, "\n", NULL); } else - putchar(*s); - } - putchar('\n'); + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } + } + writestrings (0, "\n", NULL); continue; } j = 3; if ( opts[i].short_opt < 256 ) { - printf (" -%c", opts[i].short_opt); + tmp[0] = opts[i].short_opt; + tmp[1] = 0; + writestrings (0, " -", tmp, NULL ); if ( !opts[i].long_opt ) { if (s && *s == '|' ) { - putchar (' '); j++; + writestrings (0, " ", NULL); j++; for (s++ ; *s && *s != '|'; s++, j++ ) - putchar (*s); + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } if ( *s ) s++; } } } else - fputs(" ", stdout); + writestrings (0, " ", NULL); if ( opts[i].long_opt ) { - j += printf ("%c --%s", opts[i].short_opt < 256?',':' ', - opts[i].long_opt ); + tmp[0] = opts[i].short_opt < 256?',':' '; + tmp[1] = 0; + j += writestrings (0, tmp, " --", opts[i].long_opt, NULL); if (s && *s == '|' ) { if ( *++s != '=' ) { - putchar(' '); + writestrings (0, " ", NULL); j++; } for ( ; *s && *s != '|'; s++, j++ ) - putchar(*s); + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } if ( *s ) s++; } - fputs (" ", stdout); + writestrings (0, " ", NULL); j += 3; } for (;j < indent; j++ ) - putchar(' '); + writestrings (0, " ", NULL); if ( s ) { if ( *s && j > indent ) { - putchar('\n'); + writestrings (0, "\n", NULL); for (j=0;j < indent; j++ ) - putchar (' '); + writestrings (0, " ", NULL); } for (; *s; s++ ) { @@ -972,44 +1042,58 @@ { if ( s[1] ) { - putchar ('\n'); + writestrings (0, "\n", NULL); for (j=0; j < indent; j++ ) - putchar (' '); + writestrings (0, " ", NULL); } } else - putchar (*s); + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } } } - putchar ('\n'); + writestrings (0, "\n", NULL); } if ( (flags & ARGPARSE_FLAG_ONEDASH) ) - puts ("\n(A single dash may be used instead of the double ones)"); + writestrings (0, "\n(A single dash may be used " + "instead of the double ones)\n", NULL); } if ( (s=strusage(19)) ) { /* bug reports to ... */ char *s2; - putchar('\n'); + writestrings (0, "\n", NULL); s2 = strstr (s, "@EMAIL@"); if (s2) { if (s2-s) - fwrite (s, s2-s, 1, stdout); + { + const char *s3; + + for (s3=s; s3 < s2; s3++) + { + tmp[0] = *s3; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } + } #ifdef PACKAGE_BUGREPORT - fputs (PACKAGE_BUGREPORT, stdout); + writestrings (0, PACKAGE_BUGREPORT, NULL); #else - fputs ("bug at example.org", stdout); + writestrings (0, "bug at example.org", NULL); #endif s2 += 7; if (*s2) - fputs (s2, stdout); + writestrings (0, s2, NULL); } else - fputs(s, stdout); + writestrings (0, s, NULL); } - fflush(stdout); + flushstrings (0); exit(0); } @@ -1020,31 +1104,31 @@ int i; /* Version line. */ - fputs (strusage (11), stdout); + writestrings (0, strusage (11), NULL); if ((s=strusage (12))) - printf (" (%s)", s ); - printf (" %s\n", strusage (13) ); + writestrings (0, " (", s, ")", NULL); + writestrings (0, " ", strusage (13), "\n", NULL); /* Additional version lines. */ for (i=20; i < 30; i++) if ((s=strusage (i))) - printf ("%s\n", s ); + writestrings (0, s, "\n", NULL); /* Copyright string. */ - if( (s=strusage (14)) ) - printf("%s\n", s ); + if ((s=strusage (14))) + writestrings (0, s, "\n", NULL); /* Licence string. */ if( (s=strusage (10)) ) - printf("%s\n", s ); + writestrings (0, s, "\n", NULL); /* Copying conditions. */ if ( (s=strusage(15)) ) - fputs (s, stdout); + writestrings (0, s, NULL); /* Thanks. */ if ((s=strusage(18))) - fputs (s, stdout); + writestrings (0, s, NULL); /* Additional program info. */ for (i=30; i < 40; i++ ) if ( (s=strusage (i)) ) - fputs (s, stdout); - fflush (stdout); + writestrings (0, s, NULL); + flushstrings (0); } @@ -1055,20 +1139,21 @@ if (!level) { - fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), strusage (14)); - fflush (stderr); + writestrings (1, strusage(11), " ", strusage(13), "; ", + strusage (14), "\n", NULL); + flushstrings (1); } else if (level == 1) { p = strusage (40); - fputs (p, stderr); + writestrings (1, p, NULL); if (*p && p[strlen(p)] != '\n') - putc ('\n', stderr); + writestrings (1, "\n", NULL); exit (2); } else if (level == 2) { - puts (strusage(41)); + writestrings (0, strusage(41), "\n", NULL); exit (0); } } Modified: trunk/common/argparse.h =================================================================== --- trunk/common/argparse.h 2010-05-12 16:18:49 UTC (rev 5342) +++ trunk/common/argparse.h 2010-05-30 12:06:38 UTC (rev 5343) @@ -179,5 +179,6 @@ void usage( int level ); const char *strusage( int level ); void set_strusage( const char *(*f)( int ) ); +void argparse_register_outfnc (int (*fnc)(int, const char *)); #endif /*LIBJNLIB_ARGPARSE_H*/ Modified: trunk/common/init.c =================================================================== --- trunk/common/init.c 2010-05-12 16:18:49 UTC (rev 5342) +++ trunk/common/init.c 2010-05-30 12:06:38 UTC (rev 5343) @@ -49,6 +49,23 @@ #endif /*HAVE_W32CE_SYSTEM*/ +/* If STRING is not NULL write string to es_stdout or es_stderr. MODE + must be 1 or 2. If STRING is NULL flush the respective stream. */ +static int +writestring_via_estream (int mode, const char *string) +{ + if (mode == 1 || mode == 2) + { + if (string) + return es_fputs (string, mode == 1? es_stdout : es_stderr); + else + return es_fflush (mode == 1? es_stdout : es_stderr); + } + else + return -1; +} + + /* This function is to be used early at program startup to make sure that some subsystems are initialized. This is in particular important for W32 to initialize the sockets so that our socket @@ -100,6 +117,10 @@ (void)argcp; (void)argvp; #endif + + /* --version et al shall use estream as well. */ + argparse_register_outfnc (writestring_via_estream); + }