mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-11 22:52:47 +01:00
Make dirmngr more battery friendly.
Similar to gpg-agent, dirmngr's wait timeouts are now synced to the full second. Increased ldap helper thread timeout to 2 seconds. Nuked some white spaces.
This commit is contained in:
parent
62842cc7fe
commit
2b81258b2b
@ -1,3 +1,11 @@
|
|||||||
|
2011-01-25 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* dirmngr.c (handle_connections): Rewrite loop to use pth-select
|
||||||
|
so to sync timeouts to the full second.
|
||||||
|
(pth_thread_id): New.
|
||||||
|
* ldap-wrapper.c (ldap_wrapper_thread): Sync to the full second.
|
||||||
|
Increate pth_wait timeout from 1 to 2 seconds.
|
||||||
|
|
||||||
2011-01-20 Werner Koch <wk@g10code.com>
|
2011-01-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* server.c (release_ctrl_keyservers): New.
|
* server.c (release_ctrl_keyservers): New.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* dirmngr.c - LDAP access
|
/* dirmngr.c - LDAP access
|
||||||
* Copyright (C) 2002 Klarälvdalens Datakonsult AB
|
* Copyright (C) 2002 Klarälvdalens Datakonsult AB
|
||||||
* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2010 g10 Code GmbH
|
* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2010, 2011 g10 Code GmbH
|
||||||
*
|
*
|
||||||
* This file is part of DirMngr.
|
* This file is part of DirMngr.
|
||||||
*
|
*
|
||||||
@ -47,7 +47,7 @@
|
|||||||
#define JNLIB_NEED_AFLOCAL
|
#define JNLIB_NEED_AFLOCAL
|
||||||
#include "dirmngr.h"
|
#include "dirmngr.h"
|
||||||
|
|
||||||
#include <assuan.h>
|
#include <assuan.h>
|
||||||
|
|
||||||
#include "certcache.h"
|
#include "certcache.h"
|
||||||
#include "crlcache.h"
|
#include "crlcache.h"
|
||||||
@ -74,7 +74,7 @@ enum cmd_and_opt_values {
|
|||||||
oSh = 's',
|
oSh = 's',
|
||||||
oVerbose = 'v',
|
oVerbose = 'v',
|
||||||
oNoVerbose = 500,
|
oNoVerbose = 500,
|
||||||
|
|
||||||
aServer,
|
aServer,
|
||||||
aDaemon,
|
aDaemon,
|
||||||
aService,
|
aService,
|
||||||
@ -128,7 +128,7 @@ enum cmd_and_opt_values {
|
|||||||
|
|
||||||
|
|
||||||
static ARGPARSE_OPTS opts[] = {
|
static ARGPARSE_OPTS opts[] = {
|
||||||
|
|
||||||
ARGPARSE_group (300, N_("@Commands:\n ")),
|
ARGPARSE_group (300, N_("@Commands:\n ")),
|
||||||
|
|
||||||
ARGPARSE_c (aServer, "server", N_("run in server mode (foreground)") ),
|
ARGPARSE_c (aServer, "server", N_("run in server mode (foreground)") ),
|
||||||
@ -185,13 +185,13 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
|
|
||||||
ARGPARSE_s_s (oOCSPResponder, "ocsp-responder",
|
ARGPARSE_s_s (oOCSPResponder, "ocsp-responder",
|
||||||
N_("|URL|use OCSP responder at URL")),
|
N_("|URL|use OCSP responder at URL")),
|
||||||
ARGPARSE_s_s (oOCSPSigner, "ocsp-signer",
|
ARGPARSE_s_s (oOCSPSigner, "ocsp-signer",
|
||||||
N_("|FPR|OCSP response signed by FPR")),
|
N_("|FPR|OCSP response signed by FPR")),
|
||||||
ARGPARSE_s_i (oOCSPMaxClockSkew, "ocsp-max-clock-skew", "@"),
|
ARGPARSE_s_i (oOCSPMaxClockSkew, "ocsp-max-clock-skew", "@"),
|
||||||
ARGPARSE_s_i (oOCSPMaxPeriod, "ocsp-max-period", "@"),
|
ARGPARSE_s_i (oOCSPMaxPeriod, "ocsp-max-period", "@"),
|
||||||
ARGPARSE_s_i (oOCSPCurrentPeriod, "ocsp-current-period", "@"),
|
ARGPARSE_s_i (oOCSPCurrentPeriod, "ocsp-current-period", "@"),
|
||||||
|
|
||||||
ARGPARSE_s_i (oMaxReplies, "max-replies",
|
ARGPARSE_s_i (oMaxReplies, "max-replies",
|
||||||
N_("|N|do not return more than N items in one query")),
|
N_("|N|do not return more than N items in one query")),
|
||||||
|
|
||||||
ARGPARSE_s_s (oSocketName, "socket-name", "@"), /* Only for debugging. */
|
ARGPARSE_s_s (oSocketName, "socket-name", "@"), /* Only for debugging. */
|
||||||
@ -201,7 +201,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
|
ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
|
||||||
ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
|
ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
|
||||||
ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
|
ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
|
||||||
ARGPARSE_s_s (oHomedir, "homedir", "@"),
|
ARGPARSE_s_s (oHomedir, "homedir", "@"),
|
||||||
ARGPARSE_s_s (oLDAPWrapperProgram, "ldap-wrapper-program", "@"),
|
ARGPARSE_s_s (oLDAPWrapperProgram, "ldap-wrapper-program", "@"),
|
||||||
ARGPARSE_s_s (oHTTPWrapperProgram, "http-wrapper-program", "@"),
|
ARGPARSE_s_s (oHTTPWrapperProgram, "http-wrapper-program", "@"),
|
||||||
ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy", "@"),
|
ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy", "@"),
|
||||||
@ -286,11 +286,18 @@ static int fixed_gcry_pth_init (void)
|
|||||||
return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0;
|
return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PTH_HAVE_PTH_THREAD_ID
|
||||||
|
static unsigned long pth_thread_id (void)
|
||||||
|
{
|
||||||
|
return (unsigned long)pth_self ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
my_strusage( int level )
|
my_strusage( int level )
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
switch ( level )
|
switch ( level )
|
||||||
{
|
{
|
||||||
case 11: p = "dirmngr (GnuPG)";
|
case 11: p = "dirmngr (GnuPG)";
|
||||||
break;
|
break;
|
||||||
@ -307,7 +314,7 @@ my_strusage( int level )
|
|||||||
case 41: p = _("Syntax: dirmngr [options] [command [args]]\n"
|
case 41: p = _("Syntax: dirmngr [options] [command [args]]\n"
|
||||||
"LDAP and OCSP access for GnuPG\n");
|
"LDAP and OCSP access for GnuPG\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: p = NULL;
|
default: p = NULL;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
@ -318,18 +325,18 @@ my_strusage( int level )
|
|||||||
implementation does only allow SHA-1 for hashing. This may be
|
implementation does only allow SHA-1 for hashing. This may be
|
||||||
extended by mapping the name, testing for algorithm availibility
|
extended by mapping the name, testing for algorithm availibility
|
||||||
and adjust the length checks accordingly. */
|
and adjust the length checks accordingly. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
my_ksba_hash_buffer (void *arg, const char *oid,
|
my_ksba_hash_buffer (void *arg, const char *oid,
|
||||||
const void *buffer, size_t length, size_t resultsize,
|
const void *buffer, size_t length, size_t resultsize,
|
||||||
unsigned char *result, size_t *resultlen)
|
unsigned char *result, size_t *resultlen)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|
||||||
if (oid && strcmp (oid, "1.3.14.3.2.26"))
|
if (oid && strcmp (oid, "1.3.14.3.2.26"))
|
||||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
if (resultsize < 20)
|
if (resultsize < 20)
|
||||||
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
|
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
|
||||||
gcry_md_hash_buffer (2, result, buffer, length);
|
gcry_md_hash_buffer (2, result, buffer, length);
|
||||||
*resultlen = 20;
|
*resultlen = 20;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -362,7 +369,7 @@ set_debug (void)
|
|||||||
/* Unless the "guru" string has been used we don't want to allow
|
/* Unless the "guru" string has been used we don't want to allow
|
||||||
hashing debugging. The rationale is that people tend to
|
hashing debugging. The rationale is that people tend to
|
||||||
select the highest debug value and would then clutter their
|
select the highest debug value and would then clutter their
|
||||||
disk with debug files which may reveal confidential data. */
|
disk with debug files which may reveal confidential data. */
|
||||||
if (numok)
|
if (numok)
|
||||||
opt.debug &= ~(DBG_HASHING_VALUE);
|
opt.debug &= ~(DBG_HASHING_VALUE);
|
||||||
}
|
}
|
||||||
@ -387,7 +394,7 @@ set_debug (void)
|
|||||||
if (opt.debug & DBG_CRYPTO_VALUE )
|
if (opt.debug & DBG_CRYPTO_VALUE )
|
||||||
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
|
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wrong_args (const char *text)
|
wrong_args (const char *text)
|
||||||
@ -422,10 +429,10 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
|||||||
opt.debug = 0;
|
opt.debug = 0;
|
||||||
opt.ldap_wrapper_program = NULL;
|
opt.ldap_wrapper_program = NULL;
|
||||||
opt.disable_http = 0;
|
opt.disable_http = 0;
|
||||||
opt.disable_ldap = 0;
|
opt.disable_ldap = 0;
|
||||||
opt.honor_http_proxy = 0;
|
opt.honor_http_proxy = 0;
|
||||||
opt.http_proxy = NULL;
|
opt.http_proxy = NULL;
|
||||||
opt.ldap_proxy = NULL;
|
opt.ldap_proxy = NULL;
|
||||||
opt.only_ldap_proxy = 0;
|
opt.only_ldap_proxy = 0;
|
||||||
opt.ignore_http_dp = 0;
|
opt.ignore_http_dp = 0;
|
||||||
opt.ignore_ldap_dp = 0;
|
opt.ignore_ldap_dp = 0;
|
||||||
@ -485,7 +492,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
|||||||
|
|
||||||
case oAllowOCSP: opt.allow_ocsp = 1; break;
|
case oAllowOCSP: opt.allow_ocsp = 1; break;
|
||||||
case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
|
case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
|
||||||
case oOCSPSigner:
|
case oOCSPSigner:
|
||||||
opt.ocsp_signer = parse_ocsp_signer (pargs->r.ret_str);
|
opt.ocsp_signer = parse_ocsp_signer (pargs->r.ret_str);
|
||||||
break;
|
break;
|
||||||
case oOCSPMaxClockSkew: opt.ocsp_max_clock_skew = pargs->r.ret_int; break;
|
case oOCSPMaxClockSkew: opt.ocsp_max_clock_skew = pargs->r.ret_int; break;
|
||||||
@ -521,13 +528,13 @@ w32_service_control (DWORD control, DWORD event_type, LPVOID event_data,
|
|||||||
case SERVICE_CONTROL_SHUTDOWN:
|
case SERVICE_CONTROL_SHUTDOWN:
|
||||||
/* For shutdown we will try to force termination. */
|
/* For shutdown we will try to force termination. */
|
||||||
service_status.dwCurrentState = SERVICE_STOP_PENDING;
|
service_status.dwCurrentState = SERVICE_STOP_PENDING;
|
||||||
SetServiceStatus (service_handle, &service_status);
|
SetServiceStatus (service_handle, &service_status);
|
||||||
shutdown_pending = 3;
|
shutdown_pending = 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_CONTROL_STOP:
|
case SERVICE_CONTROL_STOP:
|
||||||
service_status.dwCurrentState = SERVICE_STOP_PENDING;
|
service_status.dwCurrentState = SERVICE_STOP_PENDING;
|
||||||
SetServiceStatus (service_handle, &service_status);
|
SetServiceStatus (service_handle, &service_status);
|
||||||
shutdown_pending = 1;
|
shutdown_pending = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -600,12 +607,12 @@ main (int argc, char **argv)
|
|||||||
service_status.dwServiceSpecificExitCode = NO_ERROR;
|
service_status.dwServiceSpecificExitCode = NO_ERROR;
|
||||||
service_status.dwCheckPoint = 0;
|
service_status.dwCheckPoint = 0;
|
||||||
service_status.dwWaitHint = 10000; /* 10 seconds timeout. */
|
service_status.dwWaitHint = 10000; /* 10 seconds timeout. */
|
||||||
SetServiceStatus (service_handle, &service_status);
|
SetServiceStatus (service_handle, &service_status);
|
||||||
}
|
}
|
||||||
#endif /*USE_W32_SERVICE*/
|
#endif /*USE_W32_SERVICE*/
|
||||||
|
|
||||||
set_strusage (my_strusage);
|
set_strusage (my_strusage);
|
||||||
log_set_prefix ("dirmngr", 1|4);
|
log_set_prefix ("dirmngr", 1|4);
|
||||||
|
|
||||||
/* Make sure that our subsystems are ready. */
|
/* Make sure that our subsystems are ready. */
|
||||||
i18n_init ();
|
i18n_init ();
|
||||||
@ -621,7 +628,7 @@ main (int argc, char **argv)
|
|||||||
gpg_strerror (rc));
|
gpg_strerror (rc));
|
||||||
}
|
}
|
||||||
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
|
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
|
||||||
|
|
||||||
/* Check that the libraries are suitable. Do it here because
|
/* Check that the libraries are suitable. Do it here because
|
||||||
the option parsing may need services of the libraries. */
|
the option parsing may need services of the libraries. */
|
||||||
|
|
||||||
@ -664,9 +671,9 @@ main (int argc, char **argv)
|
|||||||
if (pth_key_setdata (my_tlskey_current_fd, NULL))
|
if (pth_key_setdata (my_tlskey_current_fd, NULL))
|
||||||
log_set_pid_suffix_cb (pid_suffix_callback);
|
log_set_pid_suffix_cb (pid_suffix_callback);
|
||||||
#endif /*!HAVE_W32_SYSTEM*/
|
#endif /*!HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
/* Reset rereadable options to default values. */
|
/* Reset rereadable options to default values. */
|
||||||
parse_rereadable_options (NULL, 0);
|
parse_rereadable_options (NULL, 0);
|
||||||
|
|
||||||
/* LDAP defaults. */
|
/* LDAP defaults. */
|
||||||
opt.add_new_ldapservers = 0;
|
opt.add_new_ldapservers = 0;
|
||||||
@ -732,7 +739,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
if (default_config)
|
if (default_config)
|
||||||
configname = make_filename (opt.homedir, "dirmngr.conf", NULL );
|
configname = make_filename (opt.homedir, "dirmngr.conf", NULL );
|
||||||
|
|
||||||
argc = orig_argc;
|
argc = orig_argc;
|
||||||
argv = orig_argv;
|
argv = orig_argv;
|
||||||
pargs.argc = &argc;
|
pargs.argc = &argc;
|
||||||
@ -757,7 +764,7 @@ main (int argc, char **argv)
|
|||||||
configname, strerror(errno) );
|
configname, strerror(errno) );
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
xfree (configname);
|
xfree (configname);
|
||||||
configname = NULL;
|
configname = NULL;
|
||||||
}
|
}
|
||||||
if (parse_debug && configname )
|
if (parse_debug && configname )
|
||||||
@ -771,13 +778,13 @@ main (int argc, char **argv)
|
|||||||
continue; /* Already handled */
|
continue; /* Already handled */
|
||||||
switch (pargs.r_opt)
|
switch (pargs.r_opt)
|
||||||
{
|
{
|
||||||
case aServer:
|
case aServer:
|
||||||
case aDaemon:
|
case aDaemon:
|
||||||
case aService:
|
case aService:
|
||||||
case aShutdown:
|
case aShutdown:
|
||||||
case aFlush:
|
case aFlush:
|
||||||
case aListCRLs:
|
case aListCRLs:
|
||||||
case aLoadCRL:
|
case aLoadCRL:
|
||||||
case aFetchCRL:
|
case aFetchCRL:
|
||||||
case aGPGConfList:
|
case aGPGConfList:
|
||||||
case aGPGConfTest:
|
case aGPGConfTest:
|
||||||
@ -812,8 +819,8 @@ main (int argc, char **argv)
|
|||||||
case oSh: csh_style = 0; break;
|
case oSh: csh_style = 0; break;
|
||||||
case oLDAPFile: ldapfile = pargs.r.ret_str; break;
|
case oLDAPFile: ldapfile = pargs.r.ret_str; break;
|
||||||
case oLDAPAddServers: opt.add_new_ldapservers = 1; break;
|
case oLDAPAddServers: opt.add_new_ldapservers = 1; break;
|
||||||
case oLDAPTimeout:
|
case oLDAPTimeout:
|
||||||
opt.ldaptimeout = pargs.r.ret_int;
|
opt.ldaptimeout = pargs.r.ret_int;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case oFakedSystemTime:
|
case oFakedSystemTime:
|
||||||
@ -860,12 +867,12 @@ main (int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!access ("/etc/dirmngr", F_OK) && !strncmp (opt.homedir, "/etc/", 5))
|
if (!access ("/etc/dirmngr", F_OK) && !strncmp (opt.homedir, "/etc/", 5))
|
||||||
log_info
|
log_info
|
||||||
("NOTE: DirMngr is now a proper part of GnuPG. The configuration and"
|
("NOTE: DirMngr is now a proper part of GnuPG. The configuration and"
|
||||||
" other directory names changed. Please check that no other version"
|
" other directory names changed. Please check that no other version"
|
||||||
" of dirmngr is still installed. To disable this warning, remove the"
|
" of dirmngr is still installed. To disable this warning, remove the"
|
||||||
" directory `/etc/dirmngr'.\n");
|
" directory `/etc/dirmngr'.\n");
|
||||||
|
|
||||||
if (gnupg_faked_time_p ())
|
if (gnupg_faked_time_p ())
|
||||||
{
|
{
|
||||||
gnupg_isotime_t tbuf;
|
gnupg_isotime_t tbuf;
|
||||||
@ -879,7 +886,7 @@ main (int argc, char **argv)
|
|||||||
set_debug ();
|
set_debug ();
|
||||||
|
|
||||||
/* Get LDAP server list from file. */
|
/* Get LDAP server list from file. */
|
||||||
if (!ldapfile)
|
if (!ldapfile)
|
||||||
{
|
{
|
||||||
ldapfile = make_filename (opt.homedir,
|
ldapfile = make_filename (opt.homedir,
|
||||||
opt.system_daemon?
|
opt.system_daemon?
|
||||||
@ -917,7 +924,7 @@ main (int argc, char **argv)
|
|||||||
log_set_file (logfile);
|
log_set_file (logfile);
|
||||||
log_set_prefix (NULL, 2|4);
|
log_set_prefix (NULL, 2|4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_wait)
|
if (debug_wait)
|
||||||
{
|
{
|
||||||
log_debug ("waiting for debugger - my pid is %u .....\n",
|
log_debug ("waiting for debugger - my pid is %u .....\n",
|
||||||
@ -941,7 +948,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
if (argc)
|
if (argc)
|
||||||
wrong_args ("--daemon");
|
wrong_args ("--daemon");
|
||||||
|
|
||||||
/* Now start with logging to a file if this is desired. */
|
/* Now start with logging to a file if this is desired. */
|
||||||
if (logfile)
|
if (logfile)
|
||||||
{
|
{
|
||||||
@ -959,12 +966,12 @@ main (int argc, char **argv)
|
|||||||
dirmngr_exit (1);
|
dirmngr_exit (1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path )
|
if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path )
|
||||||
{
|
{
|
||||||
log_error (_("name of socket too long\n"));
|
log_error (_("name of socket too long\n"));
|
||||||
dirmngr_exit (1);
|
dirmngr_exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
|
fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (fd == ASSUAN_INVALID_FD)
|
if (fd == ASSUAN_INVALID_FD)
|
||||||
{
|
{
|
||||||
@ -979,7 +986,7 @@ main (int argc, char **argv)
|
|||||||
len = SUN_LEN (&serv_addr);
|
len = SUN_LEN (&serv_addr);
|
||||||
|
|
||||||
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
|
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
|
||||||
if (rc == -1
|
if (rc == -1
|
||||||
&& (errno == EADDRINUSE
|
&& (errno == EADDRINUSE
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|| errno == EEXIST
|
|| errno == EEXIST
|
||||||
@ -990,7 +997,7 @@ main (int argc, char **argv)
|
|||||||
gnupg_remove (socket_name);
|
gnupg_remove (socket_name);
|
||||||
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
|
rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
|
||||||
}
|
}
|
||||||
if (rc != -1
|
if (rc != -1
|
||||||
&& (rc = assuan_sock_get_nonce ((struct sockaddr*) &serv_addr, len, &socket_nonce)))
|
&& (rc = assuan_sock_get_nonce ((struct sockaddr*) &serv_addr, len, &socket_nonce)))
|
||||||
log_error (_("error getting nonce for the socket\n"));
|
log_error (_("error getting nonce for the socket\n"));
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
@ -1001,7 +1008,7 @@ main (int argc, char **argv)
|
|||||||
dirmngr_exit (1);
|
dirmngr_exit (1);
|
||||||
}
|
}
|
||||||
cleanup_socket = 1;
|
cleanup_socket = 1;
|
||||||
|
|
||||||
if (listen (FD2INT (fd), 5) == -1)
|
if (listen (FD2INT (fd), 5) == -1)
|
||||||
{
|
{
|
||||||
log_error (_("listen() failed: %s\n"), strerror (errno));
|
log_error (_("listen() failed: %s\n"), strerror (errno));
|
||||||
@ -1022,22 +1029,22 @@ main (int argc, char **argv)
|
|||||||
es_printf ("set DIRMNGR_INFO=%s;%lu;1\n", socket_name, (ulong) pid);
|
es_printf ("set DIRMNGR_INFO=%s;%lu;1\n", socket_name, (ulong) pid);
|
||||||
#else
|
#else
|
||||||
pid = pth_fork ();
|
pid = pth_fork ();
|
||||||
if (pid == (pid_t)-1)
|
if (pid == (pid_t)-1)
|
||||||
{
|
{
|
||||||
log_fatal (_("error forking process: %s\n"), strerror (errno));
|
log_fatal (_("error forking process: %s\n"), strerror (errno));
|
||||||
dirmngr_exit (1);
|
dirmngr_exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid)
|
if (pid)
|
||||||
{ /* We are the parent */
|
{ /* We are the parent */
|
||||||
char *infostr;
|
char *infostr;
|
||||||
|
|
||||||
/* Don't let cleanup() remove the socket - the child is
|
/* Don't let cleanup() remove the socket - the child is
|
||||||
responsible for doing that. */
|
responsible for doing that. */
|
||||||
cleanup_socket = 0;
|
cleanup_socket = 0;
|
||||||
|
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
/* Create the info string: <name>:<pid>:<protocol_version> */
|
/* Create the info string: <name>:<pid>:<protocol_version> */
|
||||||
if (asprintf (&infostr, "DIRMNGR_INFO=%s:%lu:1",
|
if (asprintf (&infostr, "DIRMNGR_INFO=%s:%lu:1",
|
||||||
socket_name, (ulong)pid ) < 0)
|
socket_name, (ulong)pid ) < 0)
|
||||||
@ -1058,18 +1065,18 @@ main (int argc, char **argv)
|
|||||||
es_printf ( "%s; export DIRMNGR_INFO;\n", infostr);
|
es_printf ( "%s; export DIRMNGR_INFO;\n", infostr);
|
||||||
}
|
}
|
||||||
free (infostr);
|
free (infostr);
|
||||||
exit (0);
|
exit (0);
|
||||||
/*NEVER REACHED*/
|
/*NEVER REACHED*/
|
||||||
} /* end parent */
|
} /* end parent */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the child
|
This is the child
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Detach from tty and put process into a new session */
|
/* Detach from tty and put process into a new session */
|
||||||
if (!nodetach )
|
if (!nodetach )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned int oldflags;
|
unsigned int oldflags;
|
||||||
|
|
||||||
@ -1165,7 +1172,7 @@ main (int argc, char **argv)
|
|||||||
argv[0], gpg_strerror (rc));
|
argv[0], gpg_strerror (rc));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = crl_cache_insert (&ctrlbuf, argv[0], reader);
|
rc = crl_cache_insert (&ctrlbuf, argv[0], reader);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error (_("processing CRL from `%s' failed: %s\n"),
|
log_error (_("processing CRL from `%s' failed: %s\n"),
|
||||||
argv[0], gpg_strerror (rc));
|
argv[0], gpg_strerror (rc));
|
||||||
@ -1236,7 +1243,7 @@ main (int argc, char **argv)
|
|||||||
and having both of them is thus problematic. --no-detach is
|
and having both of them is thus problematic. --no-detach is
|
||||||
also only usable on the command line. --batch is unused. */
|
also only usable on the command line. --batch is unused. */
|
||||||
|
|
||||||
filename = make_filename (opt.homedir,
|
filename = make_filename (opt.homedir,
|
||||||
opt.system_daemon?
|
opt.system_daemon?
|
||||||
"ldapservers.conf":"dirmngr_ldapservers.conf",
|
"ldapservers.conf":"dirmngr_ldapservers.conf",
|
||||||
NULL);
|
NULL);
|
||||||
@ -1327,7 +1334,7 @@ cleanup (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dirmngr_exit (int rc)
|
dirmngr_exit (int rc)
|
||||||
{
|
{
|
||||||
cleanup ();
|
cleanup ();
|
||||||
@ -1345,7 +1352,7 @@ dirmngr_init_default_ctrl (ctrl_t ctrl)
|
|||||||
|
|
||||||
|
|
||||||
/* Create a list of LDAP servers from the file FILENAME. Returns the
|
/* Create a list of LDAP servers from the file FILENAME. Returns the
|
||||||
list or NULL in case of errors.
|
list or NULL in case of errors.
|
||||||
|
|
||||||
The format fo such a file is line oriented where empty lines and
|
The format fo such a file is line oriented where empty lines and
|
||||||
lines starting with a hash mark are ignored. All other lines are
|
lines starting with a hash mark are ignored. All other lines are
|
||||||
@ -1353,7 +1360,7 @@ dirmngr_init_default_ctrl (ctrl_t ctrl)
|
|||||||
|
|
||||||
1. field: Hostname
|
1. field: Hostname
|
||||||
2. field: Portnumber
|
2. field: Portnumber
|
||||||
3. field: Username
|
3. field: Username
|
||||||
4. field: Password
|
4. field: Password
|
||||||
5. field: Base DN
|
5. field: Base DN
|
||||||
|
|
||||||
@ -1406,8 +1413,8 @@ parse_ldapserver_file (const char* filename)
|
|||||||
*serverend = server;
|
*serverend = server;
|
||||||
serverend = &server->next;
|
serverend = &server->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (es_ferror (fp))
|
if (es_ferror (fp))
|
||||||
log_error (_("error reading `%s': %s\n"), filename, strerror (errno));
|
log_error (_("error reading `%s': %s\n"), filename, strerror (errno));
|
||||||
es_fclose (fp);
|
es_fclose (fp);
|
||||||
@ -1441,14 +1448,14 @@ parse_ocsp_signer (const char *string)
|
|||||||
item->hexfpr[j] = 0;
|
item->hexfpr[j] = 0;
|
||||||
if (j != 40 || !(spacep (string+i) || !string[i]))
|
if (j != 40 || !(spacep (string+i) || !string[i]))
|
||||||
{
|
{
|
||||||
log_error (_("%s:%u: invalid fingerprint detected\n"),
|
log_error (_("%s:%u: invalid fingerprint detected\n"),
|
||||||
"--ocsp-signer", 0);
|
"--ocsp-signer", 0);
|
||||||
xfree (item);
|
xfree (item);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Well, it is a filename. */
|
/* Well, it is a filename. */
|
||||||
if (*string == '/' || (*string == '~' && string[1] == '/'))
|
if (*string == '/' || (*string == '~' && string[1] == '/'))
|
||||||
fname = make_filename (string, NULL);
|
fname = make_filename (string, NULL);
|
||||||
@ -1503,7 +1510,7 @@ parse_ocsp_signer (const char *string)
|
|||||||
;
|
;
|
||||||
err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
|
err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
|
||||||
/* */: GPG_ERR_INCOMPLETE_LINE);
|
/* */: GPG_ERR_INCOMPLETE_LINE);
|
||||||
log_error (_("%s:%u: read error: %s\n"),
|
log_error (_("%s:%u: read error: %s\n"),
|
||||||
fname, lnr, gpg_strerror (err));
|
fname, lnr, gpg_strerror (err));
|
||||||
errflag = 1;
|
errflag = 1;
|
||||||
continue;
|
continue;
|
||||||
@ -1541,14 +1548,14 @@ parse_ocsp_signer (const char *string)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Stuff used in daemon mode.
|
Stuff used in daemon mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Reread parts of the configuration. Note, that this function is
|
/* Reread parts of the configuration. Note, that this function is
|
||||||
obviously not thread-safe and should only be called from the PTH
|
obviously not thread-safe and should only be called from the PTH
|
||||||
signal handler.
|
signal handler.
|
||||||
|
|
||||||
Fixme: Due to the way the argument parsing works, we create a
|
Fixme: Due to the way the argument parsing works, we create a
|
||||||
memory leak here for all string type arguments. There is currently
|
memory leak here for all string type arguments. There is currently
|
||||||
@ -1619,11 +1626,11 @@ handle_signal (int signo)
|
|||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
dirmngr_sighup_action ();
|
dirmngr_sighup_action ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
cert_cache_print_stats ();
|
cert_cache_print_stats ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGUSR2:
|
case SIGUSR2:
|
||||||
log_info (_("SIGUSR2 received - no action defined\n"));
|
log_info (_("SIGUSR2 received - no action defined\n"));
|
||||||
break;
|
break;
|
||||||
@ -1643,7 +1650,7 @@ handle_signal (int signo)
|
|||||||
dirmngr_exit (0);
|
dirmngr_exit (0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
log_info (_("SIGINT received - immediate shutdown\n"));
|
log_info (_("SIGINT received - immediate shutdown\n"));
|
||||||
log_info( "%s %s stopped\n", strusage(11), strusage(13));
|
log_info( "%s %s stopped\n", strusage(11), strusage(13));
|
||||||
@ -1681,12 +1688,12 @@ handle_tick (void)
|
|||||||
|
|
||||||
/* Check the nonce on a new connection. This is a NOP unless we we
|
/* Check the nonce on a new connection. This is a NOP unless we we
|
||||||
are using our Unix domain socket emulation under Windows. */
|
are using our Unix domain socket emulation under Windows. */
|
||||||
static int
|
static int
|
||||||
check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
|
check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
|
||||||
{
|
{
|
||||||
if (assuan_sock_check_nonce (fd, nonce))
|
if (assuan_sock_check_nonce (fd, nonce))
|
||||||
{
|
{
|
||||||
log_info (_("error reading nonce on fd %d: %s\n"),
|
log_info (_("error reading nonce on fd %d: %s\n"),
|
||||||
FD2INT (fd), strerror (errno));
|
FD2INT (fd), strerror (errno));
|
||||||
assuan_sock_close (fd);
|
assuan_sock_close (fd);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1701,13 +1708,16 @@ static void *
|
|||||||
start_connection_thread (void *arg)
|
start_connection_thread (void *arg)
|
||||||
{
|
{
|
||||||
union int_and_ptr_u argval;
|
union int_and_ptr_u argval;
|
||||||
assuan_fd_t fd;
|
gnupg_fd_t fd;
|
||||||
|
|
||||||
argval.aptr = arg;
|
argval.aptr = arg;
|
||||||
fd = argval.afd;
|
fd = argval.afd;
|
||||||
|
|
||||||
if (check_nonce (fd, &socket_nonce))
|
if (check_nonce (fd, &socket_nonce))
|
||||||
return NULL;
|
{
|
||||||
|
log_error ("handler 0x%lx nonce check FAILED\n", pth_thread_id ());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef HAVE_W32_SYSTEM
|
#ifndef HAVE_W32_SYSTEM
|
||||||
pth_key_setdata (my_tlskey_current_fd, argval.aptr);
|
pth_key_setdata (my_tlskey_current_fd, argval.aptr);
|
||||||
@ -1727,7 +1737,7 @@ start_connection_thread (void *arg)
|
|||||||
argval.afd = ASSUAN_INVALID_FD;
|
argval.afd = ASSUAN_INVALID_FD;
|
||||||
pth_key_setdata (my_tlskey_current_fd, argval.aptr);
|
pth_key_setdata (my_tlskey_current_fd, argval.aptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1738,11 +1748,13 @@ handle_connections (assuan_fd_t listen_fd)
|
|||||||
{
|
{
|
||||||
pth_attr_t tattr;
|
pth_attr_t tattr;
|
||||||
pth_event_t ev, time_ev;
|
pth_event_t ev, time_ev;
|
||||||
sigset_t sigs, oldsigs;
|
sigset_t sigs;
|
||||||
int signo;
|
int signo;
|
||||||
struct sockaddr_un paddr;
|
struct sockaddr_un paddr;
|
||||||
socklen_t plen = sizeof( paddr );
|
socklen_t plen = sizeof( paddr );
|
||||||
assuan_fd_t fd;
|
gnupg_fd_t fd;
|
||||||
|
int nfd, ret;
|
||||||
|
fd_set fdset, read_fdset;
|
||||||
|
|
||||||
tattr = pth_attr_new();
|
tattr = pth_attr_new();
|
||||||
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
|
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
|
||||||
@ -1750,46 +1762,89 @@ handle_connections (assuan_fd_t listen_fd)
|
|||||||
pth_attr_set (tattr, PTH_ATTR_NAME, "dirmngr");
|
pth_attr_set (tattr, PTH_ATTR_NAME, "dirmngr");
|
||||||
|
|
||||||
#ifndef HAVE_W32_SYSTEM /* FIXME */
|
#ifndef HAVE_W32_SYSTEM /* FIXME */
|
||||||
|
/* Make sure that the signals we are going to handle are not blocked
|
||||||
|
and create an event object for them. We also set the default
|
||||||
|
action to ignore because we use an Pth event to get notified
|
||||||
|
about signals. This avoids that the default action is taken in
|
||||||
|
case soemthing goes wrong within Pth. The problem might also be
|
||||||
|
a Pth bug. */
|
||||||
sigemptyset (&sigs );
|
sigemptyset (&sigs );
|
||||||
sigaddset (&sigs, SIGHUP);
|
{
|
||||||
sigaddset (&sigs, SIGUSR1);
|
static const int mysigs[] = { SIGHUP, SIGUSR1, SIGUSR2, SIGINT, SIGTERM };
|
||||||
sigaddset (&sigs, SIGUSR2);
|
struct sigaction sa;
|
||||||
sigaddset (&sigs, SIGINT);
|
int i;
|
||||||
sigaddset (&sigs, SIGTERM);
|
|
||||||
|
for (i=0; i < DIM (mysigs); i++)
|
||||||
|
{
|
||||||
|
sigemptyset (&sa.sa_mask);
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
sigaction (mysigs[i], &sa, NULL);
|
||||||
|
|
||||||
|
sigaddset (&sigs, mysigs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
|
||||||
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
|
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
|
||||||
#else
|
#else
|
||||||
|
/* Use a dummy event. */
|
||||||
sigs = 0;
|
sigs = 0;
|
||||||
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
|
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
|
||||||
#endif
|
#endif
|
||||||
time_ev = NULL;
|
time_ev = NULL;
|
||||||
|
|
||||||
|
/* Setup the fdset. It has only one member. This is because we use
|
||||||
|
pth_select instead of pth_accept to properly sync timeouts with
|
||||||
|
to full second. */
|
||||||
|
FD_ZERO (&fdset);
|
||||||
|
FD_SET (FD2INT (listen_fd), &fdset);
|
||||||
|
nfd = FD2INT (listen_fd);
|
||||||
|
|
||||||
|
/* Main loop. */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
/* Make sure that our signals are not blocked. */
|
||||||
|
pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
|
||||||
|
|
||||||
|
/* Shutdown test. */
|
||||||
if (shutdown_pending)
|
if (shutdown_pending)
|
||||||
{
|
{
|
||||||
if (!active_connections)
|
if (!active_connections)
|
||||||
break; /* ready */
|
break; /* ready */
|
||||||
|
|
||||||
/* Do not accept anymore connections but wait for existing
|
/* Do not accept new connections but keep on running the
|
||||||
connections to terminate. */
|
loop to cope with the timer events. */
|
||||||
signo = 0;
|
FD_ZERO (&fdset);
|
||||||
pth_wait (ev);
|
|
||||||
if (pth_event_occurred (ev) && signo)
|
|
||||||
handle_signal (signo);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a timeout event if needed. To help with power saving
|
||||||
|
we syncronize the ticks to the next full second. */
|
||||||
if (!time_ev)
|
if (!time_ev)
|
||||||
time_ev = pth_event (PTH_EVENT_TIME,
|
{
|
||||||
pth_timeout (TIMERTICK_INTERVAL, 0));
|
pth_time_t nexttick;
|
||||||
|
|
||||||
|
nexttick = pth_timeout (TIMERTICK_INTERVAL, 0);
|
||||||
|
if (nexttick.tv_usec > 10) /* Use a 10 usec threshhold. */
|
||||||
|
{
|
||||||
|
nexttick.tv_sec++;
|
||||||
|
nexttick.tv_usec = 0;
|
||||||
|
}
|
||||||
|
time_ev = pth_event (PTH_EVENT_TIME, nexttick);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take a copy of the fdset. */
|
||||||
|
read_fdset = fdset;
|
||||||
|
|
||||||
if (time_ev)
|
if (time_ev)
|
||||||
pth_event_concat (ev, time_ev, NULL);
|
pth_event_concat (ev, time_ev, NULL);
|
||||||
fd = (assuan_fd_t) pth_accept_ev (FD2INT (listen_fd), (struct sockaddr *)&paddr, &plen, ev);
|
|
||||||
|
ret = pth_select_ev (nfd+1, &read_fdset, NULL, NULL, NULL, ev);
|
||||||
|
|
||||||
if (time_ev)
|
if (time_ev)
|
||||||
pth_event_isolate (time_ev);
|
pth_event_isolate (time_ev);
|
||||||
|
|
||||||
if (fd == ASSUAN_INVALID_FD)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
if (pth_event_occurred (ev)
|
if (pth_event_occurred (ev)
|
||||||
|| (time_ev && pth_event_occurred (time_ev)) )
|
|| (time_ev && pth_event_occurred (time_ev)) )
|
||||||
@ -1804,7 +1859,8 @@ handle_connections (assuan_fd_t listen_fd)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
log_error (_("accept failed: %s - waiting 1s\n"), strerror (errno));
|
log_error (_("pth_select failed: %s - waiting 1s\n"),
|
||||||
|
strerror (errno));
|
||||||
pth_sleep (1);
|
pth_sleep (1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1825,25 +1881,38 @@ handle_connections (assuan_fd_t listen_fd)
|
|||||||
/* We now might create a new thread and because we don't want
|
/* We now might create a new thread and because we don't want
|
||||||
any signals (as we are handling them here) to be delivered to
|
any signals (as we are handling them here) to be delivered to
|
||||||
a new thread we need to block those signals. */
|
a new thread we need to block those signals. */
|
||||||
pth_sigmask (SIG_BLOCK, &sigs, &oldsigs);
|
pth_sigmask (SIG_BLOCK, &sigs, NULL);
|
||||||
|
|
||||||
/* Create thread to handle this connection. */
|
if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset))
|
||||||
{
|
{
|
||||||
union int_and_ptr_u argval;
|
plen = sizeof paddr;
|
||||||
|
fd = INT2FD (pth_accept (FD2INT(listen_fd),
|
||||||
|
(struct sockaddr *)&paddr, &plen));
|
||||||
|
if (fd == GNUPG_INVALID_FD)
|
||||||
|
{
|
||||||
|
log_error ("accept failed: %s\n", strerror (errno));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char threadname[50];
|
||||||
|
union int_and_ptr_u argval;
|
||||||
|
|
||||||
argval.afd = fd;
|
argval.afd = fd;
|
||||||
if (!pth_spawn (tattr, start_connection_thread, argval.aptr))
|
snprintf (threadname, sizeof threadname-1,
|
||||||
{
|
"conn fd=%d", FD2INT(fd));
|
||||||
log_error (_("error spawning connection handler: %s\n"),
|
threadname[sizeof threadname -1] = 0;
|
||||||
strerror (errno) );
|
pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
|
||||||
assuan_sock_close (fd);
|
if (!pth_spawn (tattr, start_connection_thread, argval.aptr))
|
||||||
}
|
{
|
||||||
}
|
log_error ("error spawning connection handler: %s\n",
|
||||||
|
strerror (errno) );
|
||||||
/* Restore the signal mask. */
|
assuan_sock_close (fd);
|
||||||
pth_sigmask (SIG_SETMASK, &oldsigs, NULL);
|
}
|
||||||
|
}
|
||||||
|
fd = GNUPG_INVALID_FD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pth_event_free (ev, PTH_FREE_ALL);
|
pth_event_free (ev, PTH_FREE_ALL);
|
||||||
if (time_ev)
|
if (time_ev)
|
||||||
pth_event_free (time_ev, PTH_FREE_ALL);
|
pth_event_free (time_ev, PTH_FREE_ALL);
|
||||||
|
@ -269,8 +269,17 @@ ldap_wrapper_thread (void *dummy)
|
|||||||
{
|
{
|
||||||
pth_event_t timeout_ev;
|
pth_event_t timeout_ev;
|
||||||
int any_action = 0;
|
int any_action = 0;
|
||||||
|
pth_time_t nexttick;
|
||||||
|
|
||||||
timeout_ev = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
|
/* We timeout the pth_wait every 2 seconds. To help with power
|
||||||
|
saving we syncronize the timeouts to the next full second. */
|
||||||
|
nexttick = pth_timeout (2, 0);
|
||||||
|
if (nexttick.tv_usec > 10) /* Use a 10 usec threshhold. */
|
||||||
|
{
|
||||||
|
nexttick.tv_sec++;
|
||||||
|
nexttick.tv_usec = 0;
|
||||||
|
}
|
||||||
|
timeout_ev = pth_event (PTH_EVENT_TIME, nexttick);
|
||||||
if (! timeout_ev)
|
if (! timeout_ev)
|
||||||
{
|
{
|
||||||
log_error (_("pth_event failed: %s\n"), strerror (errno));
|
log_error (_("pth_event failed: %s\n"), strerror (errno));
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
/^"POT-Creation-Date: .*"$/{
|
|
||||||
x
|
|
||||||
s/P/P/
|
|
||||||
ta
|
|
||||||
g
|
|
||||||
d
|
|
||||||
bb
|
|
||||||
:a
|
|
||||||
x
|
|
||||||
:b
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user