mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
Merge branch 'STABLE-BRANCH-2-4'
-- Fixed conflicts in NEWS g10/encrypt.c sm/encrypt.c sm/sign.c
This commit is contained in:
commit
2764ee309a
38 changed files with 1149 additions and 370 deletions
|
@ -256,6 +256,13 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
|||
if (! initialized)
|
||||
return 1;
|
||||
|
||||
/* Map the the generic ECC algo to ECDSA if requested. */
|
||||
if ((algo_flags & PK_ALGO_FLAG_ECC18)
|
||||
&& algo == GCRY_PK_ECC
|
||||
&& (use == PK_USE_VERIFICATION
|
||||
|| use == PK_USE_SIGNING))
|
||||
algo = GCRY_PK_ECDSA;
|
||||
|
||||
switch (compliance)
|
||||
{
|
||||
case CO_DE_VS:
|
||||
|
@ -280,7 +287,6 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
|||
default:
|
||||
log_assert (!"reached");
|
||||
}
|
||||
(void)algo_flags;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_DSA:
|
||||
|
@ -301,7 +307,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
|||
result = (use == PK_USE_DECRYPTION);
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_ECDH:
|
||||
case PUBKEY_ALGO_ECDH: /* Same value as GCRY_PK_ECC, i.e. 18 */
|
||||
case GCRY_PK_ECDH:
|
||||
if (use == PK_USE_DECRYPTION)
|
||||
result = 1;
|
||||
|
@ -549,6 +555,9 @@ gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
|
|||
int *result;
|
||||
int res;
|
||||
|
||||
/* #warning debug code ahead */
|
||||
/* return 1; */
|
||||
|
||||
result = get_compliance_cache (compliance, 1);
|
||||
|
||||
if (result && *result != -1)
|
||||
|
|
|
@ -50,6 +50,7 @@ enum pk_use_case
|
|||
|
||||
/* Flags to distinguish public key algorithm variants. */
|
||||
#define PK_ALGO_FLAG_RSAPSS 1 /* Use rsaPSS padding. */
|
||||
#define PK_ALGO_FLAG_ECC18 256 /* GCRY_PK_ECC is used in a generic way. */
|
||||
|
||||
|
||||
int gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
||||
|
|
322
common/dotlock.c
322
common/dotlock.c
|
@ -291,6 +291,7 @@
|
|||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <dirent.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -393,9 +394,18 @@ struct dotlock_handle
|
|||
unsigned int locked:1; /* Lock status. */
|
||||
unsigned int disable:1; /* If true, locking is disabled. */
|
||||
unsigned int use_o_excl:1; /* Use open (O_EXCL) for locking. */
|
||||
unsigned int by_parent:1; /* Parent does the locking. */
|
||||
unsigned int no_write:1; /* No write to the lockfile. */
|
||||
|
||||
int extra_fd; /* A place for the caller to store an FD. */
|
||||
|
||||
/* An optional info callback - see dotlock_set_info_cb. */
|
||||
int (*info_cb)(dotlock_t, void *,
|
||||
enum dotlock_reasons reason,
|
||||
const char *,...);
|
||||
void *info_cb_value;
|
||||
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
HANDLE lockhd; /* The W32 handle of the lock file. */
|
||||
#else /*!HAVE_DOSISH_SYSTEM */
|
||||
|
@ -545,8 +555,15 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd)
|
|||
if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
|
||||
{
|
||||
int e = errno;
|
||||
my_info_2 ("error opening lockfile '%s': %s\n",
|
||||
h->lockname, strerror(errno) );
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
my_info_2 ("error opening lockfile '%s': %s\n",
|
||||
h->lockname, strerror(errno) );
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"error opening lockfile '%s': %s\n",
|
||||
h->lockname, strerror (errno) );
|
||||
}
|
||||
if (buffer != buffer_space)
|
||||
xfree (buffer);
|
||||
my_set_errno (e); /* Need to return ERRNO here. */
|
||||
|
@ -564,6 +581,10 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd)
|
|||
{
|
||||
int e = errno;
|
||||
my_info_1 ("error reading lockfile '%s'\n", h->lockname );
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"error reading lockfile '%s': %s\n",
|
||||
h->lockname, strerror (errno) );
|
||||
close (fd);
|
||||
if (buffer != buffer_space)
|
||||
xfree (buffer);
|
||||
|
@ -583,6 +604,9 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd)
|
|||
if (nread < 11)
|
||||
{
|
||||
my_info_1 ("invalid size of lockfile '%s'\n", h->lockname);
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_INV_FILE,
|
||||
"invalid size of lockfile '%s'\n", h->lockname);
|
||||
if (buffer != buffer_space)
|
||||
xfree (buffer);
|
||||
my_set_errno (EINVAL);
|
||||
|
@ -594,6 +618,9 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd)
|
|||
|| !pid )
|
||||
{
|
||||
my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname);
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_INV_FILE,
|
||||
"invalid pid %d in lockfile '%s'\n", pid, h->lockname);
|
||||
if (buffer != buffer_space)
|
||||
xfree (buffer);
|
||||
my_set_errno (EINVAL);
|
||||
|
@ -655,6 +682,80 @@ use_hardlinks_p (const char *tname)
|
|||
|
||||
|
||||
#ifdef HAVE_POSIX_SYSTEM
|
||||
static int
|
||||
dotlock_get_process_id (dotlock_t h)
|
||||
{
|
||||
return h->by_parent? (int)getppid(): (int)getpid();
|
||||
}
|
||||
|
||||
static int
|
||||
dotlock_detect_tname (dotlock_t h)
|
||||
{
|
||||
struct stat sb;
|
||||
DIR *dir;
|
||||
char *dirname;
|
||||
char *basename;
|
||||
struct dirent *d;
|
||||
int r;
|
||||
|
||||
if (stat (h->lockname, &sb))
|
||||
return -1;
|
||||
|
||||
basename = make_basename (h->lockname, NULL);
|
||||
dirname = make_dirname (h->lockname);
|
||||
|
||||
dir = opendir (dirname);
|
||||
if (dir == NULL)
|
||||
{
|
||||
xfree (basename);
|
||||
xfree (dirname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((d = readdir (dir)))
|
||||
if (sb.st_ino == d->d_ino && strcmp (d->d_name, basename))
|
||||
break;
|
||||
|
||||
if (d)
|
||||
{
|
||||
int len = strlen (h->tname);
|
||||
int dlen = strlen (d->d_name);
|
||||
const char *tname_path;
|
||||
|
||||
if (dlen > len)
|
||||
{
|
||||
xfree (basename);
|
||||
xfree (dirname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy (stpcpy (stpcpy (h->tname, dirname), DIRSEP_S), d->d_name);
|
||||
h->use_o_excl = 0;
|
||||
tname_path = strchr (h->tname + strlen (dirname) + 2, '.');
|
||||
if (!tname_path)
|
||||
{
|
||||
xfree (basename);
|
||||
xfree (dirname);
|
||||
return -1;
|
||||
}
|
||||
h->nodename_off = tname_path - h->tname + 1;
|
||||
}
|
||||
else
|
||||
h->use_o_excl = 1;
|
||||
|
||||
r = closedir (dir);
|
||||
if (r)
|
||||
{
|
||||
xfree (basename);
|
||||
xfree (dirname);
|
||||
return r;
|
||||
}
|
||||
|
||||
xfree (basename);
|
||||
xfree (dirname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Locking core for Unix. It used a temporary file and the link
|
||||
system call to make locking an atomic operation. */
|
||||
static dotlock_t
|
||||
|
@ -667,8 +768,10 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||
int dirpartlen;
|
||||
struct utsname utsbuf;
|
||||
size_t tnamelen;
|
||||
int pid;
|
||||
|
||||
snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );
|
||||
pid = dotlock_get_process_id (h);
|
||||
snprintf (pidstr, sizeof pidstr, "%10d\n", pid);
|
||||
|
||||
/* Create a temporary file. */
|
||||
if ( uname ( &utsbuf ) )
|
||||
|
@ -702,10 +805,17 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||
}
|
||||
h->nodename_len = strlen (nodename);
|
||||
|
||||
if (h->no_write)
|
||||
{
|
||||
memset (h->tname, '_', tnamelen);
|
||||
h->tname[tnamelen] = 0;
|
||||
goto skip_write;
|
||||
}
|
||||
|
||||
snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h );
|
||||
h->nodename_off = strlen (h->tname);
|
||||
snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off,
|
||||
"%s.%d", nodename, (int)getpid ());
|
||||
"%s.%d", nodename, pid);
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -722,6 +832,10 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||
UNLOCK_all_lockfiles ();
|
||||
my_error_2 (_("failed to create temporary file '%s': %s\n"),
|
||||
h->tname, strerror (errno));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_WAITING,
|
||||
_("failed to create temporary file '%s': %s\n"),
|
||||
h->tname, strerror (errno));
|
||||
xfree (h->tname);
|
||||
xfree (h);
|
||||
my_set_errno (saveerrno);
|
||||
|
@ -755,11 +869,16 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||
int saveerrno = errno;
|
||||
my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n"
|
||||
, h->tname, strerror (saveerrno));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_CONFIG_TEST,
|
||||
"can't check whether hardlinks are supported for '%s': %s\n"
|
||||
, h->tname, strerror (saveerrno));
|
||||
my_set_errno (saveerrno);
|
||||
}
|
||||
goto write_failed;
|
||||
}
|
||||
|
||||
skip_write:
|
||||
h->lockname = xtrymalloc (strlen (file_to_lock) + 6 );
|
||||
if (!h->lockname)
|
||||
{
|
||||
|
@ -775,6 +894,20 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||
strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
|
||||
UNLOCK_all_lockfiles ();
|
||||
|
||||
if (h->no_write)
|
||||
{
|
||||
if (dotlock_detect_tname (h) < 0)
|
||||
{
|
||||
xfree (h->lockname);
|
||||
xfree (h->tname);
|
||||
xfree (h);
|
||||
my_set_errno (EACCES);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
h->locked = 1;
|
||||
}
|
||||
|
||||
return h;
|
||||
|
||||
write_failed:
|
||||
|
@ -783,6 +916,11 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||
all_lockfiles = h->next;
|
||||
UNLOCK_all_lockfiles ();
|
||||
my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
_("error writing to '%s': %s\n"),
|
||||
h->tname, strerror (errno));
|
||||
|
||||
if ( fd != -1 )
|
||||
close (fd);
|
||||
unlink (h->tname);
|
||||
|
@ -849,6 +987,10 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
|
|||
all_lockfiles = h->next;
|
||||
UNLOCK_all_lockfiles ();
|
||||
my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
_("can't create '%s': %s\n"),
|
||||
h->lockname, w32_strerror (-1));
|
||||
xfree (h->lockname);
|
||||
xfree (h);
|
||||
my_set_errno (saveerrno);
|
||||
|
@ -873,7 +1015,15 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
|
|||
POSIX systems a temporary file ".#lk.<hostname>.pid[.threadid] is
|
||||
used.
|
||||
|
||||
FLAGS must be 0.
|
||||
FLAGS may include DOTLOCK_PREPARE_CREATE bit, which only allocates
|
||||
the handle and requires a further call to dotlock_finish_create.
|
||||
This can be used to set a callback between these calls.
|
||||
|
||||
FLAGS may include DOTLOCK_LOCK_BY_PARENT bit, when it's the parent
|
||||
process controlling the lock. This is used by dotlock util.
|
||||
|
||||
FLAGS may include DOTLOCK_LOCKED bit, when it should not create the
|
||||
lockfile, but to unlock. This is used by dotlock util.
|
||||
|
||||
The function returns an new handle which needs to be released using
|
||||
destroy_dotlock but gets also released at the termination of the
|
||||
|
@ -885,8 +1035,13 @@ dotlock_create (const char *file_to_lock, unsigned int flags)
|
|||
{
|
||||
static int initialized;
|
||||
dotlock_t h;
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
int by_parent = 0;
|
||||
int no_write = 0;
|
||||
#endif
|
||||
|
||||
if ( !initialized )
|
||||
if ( !(flags & DOTLOCK_LOCK_BY_PARENT)
|
||||
&& !initialized )
|
||||
{
|
||||
atexit (dotlock_remove_lockfiles);
|
||||
initialized = 1;
|
||||
|
@ -895,7 +1050,15 @@ dotlock_create (const char *file_to_lock, unsigned int flags)
|
|||
if ( !file_to_lock )
|
||||
return NULL; /* Only initialization was requested. */
|
||||
|
||||
if (flags)
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
if ((flags & DOTLOCK_LOCK_BY_PARENT) || (flags & DOTLOCK_LOCKED))
|
||||
{
|
||||
by_parent = !!(flags & DOTLOCK_LOCK_BY_PARENT);
|
||||
no_write = !!(flags & DOTLOCK_LOCKED);
|
||||
flags &= ~(DOTLOCK_LOCK_BY_PARENT | DOTLOCK_LOCKED);
|
||||
}
|
||||
#endif
|
||||
if ((flags & ~DOTLOCK_PREPARE_CREATE))
|
||||
{
|
||||
my_set_errno (EINVAL);
|
||||
return NULL;
|
||||
|
@ -905,6 +1068,10 @@ dotlock_create (const char *file_to_lock, unsigned int flags)
|
|||
if (!h)
|
||||
return NULL;
|
||||
h->extra_fd = -1;
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
h->by_parent = by_parent;
|
||||
h->no_write = no_write;
|
||||
#endif
|
||||
|
||||
if (never_lock)
|
||||
{
|
||||
|
@ -916,6 +1083,24 @@ dotlock_create (const char *file_to_lock, unsigned int flags)
|
|||
return h;
|
||||
}
|
||||
|
||||
if ((flags & DOTLOCK_PREPARE_CREATE))
|
||||
return h;
|
||||
else
|
||||
return dotlock_finish_create (h, file_to_lock);
|
||||
}
|
||||
|
||||
|
||||
/* This function may be used along with dotlock_create (file_name,
|
||||
* DOTLOCK_PREPARE_CREATE) to finish the creation call. The given
|
||||
* filename shall be the same as passed to dotlock_create. On success
|
||||
* the same handle H is returned, on error NULL is returned and H is
|
||||
* released. */
|
||||
dotlock_t
|
||||
dotlock_finish_create (dotlock_t h, const char *file_to_lock)
|
||||
{
|
||||
if (!h || !file_to_lock)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
return dotlock_create_w32 (h, file_to_lock);
|
||||
#else /*!HAVE_DOSISH_SYSTEM */
|
||||
|
@ -942,6 +1127,24 @@ dotlock_get_fd (dotlock_t h)
|
|||
}
|
||||
|
||||
|
||||
/* Set a callback function for info diagnostics. The callback
|
||||
* function CB is called with the handle, the opaque value OPAQUE, a
|
||||
* reason code, and a format string with its arguments. The callback
|
||||
* shall return 0 to continue operation or true in which case the
|
||||
* current function will be terminated with an error. */
|
||||
void
|
||||
dotlock_set_info_cb (dotlock_t h,
|
||||
int (*cb)(dotlock_t, void *,
|
||||
enum dotlock_reasons reason,
|
||||
const char *,...),
|
||||
void *opaque)
|
||||
{
|
||||
h->info_cb = cb;
|
||||
h->info_cb_value = opaque;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_POSIX_SYSTEM
|
||||
/* Unix specific code of destroy_dotlock. */
|
||||
|
@ -952,7 +1155,6 @@ dotlock_destroy_unix (dotlock_t h)
|
|||
unlink (h->lockname);
|
||||
if (h->tname && !h->use_o_excl)
|
||||
unlink (h->tname);
|
||||
xfree (h->tname);
|
||||
}
|
||||
#endif /*HAVE_POSIX_SYSTEM*/
|
||||
|
||||
|
@ -998,15 +1200,28 @@ dotlock_destroy (dotlock_t h)
|
|||
UNLOCK_all_lockfiles ();
|
||||
|
||||
/* Then destroy the lock. */
|
||||
if (!h->disable)
|
||||
if (!h->disable
|
||||
&& (!h->by_parent || h->no_write))
|
||||
{
|
||||
/* NOTE: under the condition of (by_parent && !no_write),
|
||||
it doesn't come here. So, the lock file remains. */
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
dotlock_destroy_w32 (h);
|
||||
#else /* !HAVE_DOSISH_SYSTEM */
|
||||
dotlock_destroy_unix (h);
|
||||
#endif /* HAVE_DOSISH_SYSTEM */
|
||||
xfree (h->lockname);
|
||||
}
|
||||
|
||||
#ifdef HAVE_POSIX_SYSTEM
|
||||
/* When DOTLOCK_LOCK_BY_PARENT and lock fails,
|
||||
the temporary file created should be removed. */
|
||||
if (h->by_parent && !h->no_write && !h->locked)
|
||||
if (h->tname && !h->use_o_excl)
|
||||
unlink (h->tname);
|
||||
|
||||
xfree (h->tname);
|
||||
#endif
|
||||
xfree (h->lockname);
|
||||
xfree(h);
|
||||
}
|
||||
|
||||
|
@ -1061,6 +1276,7 @@ static int
|
|||
dotlock_take_unix (dotlock_t h, long timeout)
|
||||
{
|
||||
int wtime = 0;
|
||||
int timedout = 0;
|
||||
int sumtime = 0;
|
||||
int pid;
|
||||
int lastpid = -1;
|
||||
|
@ -1089,6 +1305,10 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
saveerrno = errno;
|
||||
my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n",
|
||||
h->lockname, strerror (saveerrno));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"lock not made: open(O_EXCL) of '%s' failed: %s\n",
|
||||
h->lockname, strerror (saveerrno));
|
||||
my_set_errno (saveerrno);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1096,7 +1316,8 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
{
|
||||
char pidstr[16];
|
||||
|
||||
snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid());
|
||||
snprintf (pidstr, sizeof pidstr, "%10d\n",
|
||||
dotlock_get_process_id (h));
|
||||
if (write (fd, pidstr, 11 ) == 11
|
||||
&& write (fd, h->tname + h->nodename_off,h->nodename_len)
|
||||
== h->nodename_len
|
||||
|
@ -1110,6 +1331,10 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
saveerrno = errno;
|
||||
my_error_2 ("lock not made: writing to '%s' failed: %s\n",
|
||||
h->lockname, strerror (errno));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"lock not made: writing to '%s' failed: %s\n",
|
||||
h->lockname, strerror (errno));
|
||||
close (fd);
|
||||
unlink (h->lockname);
|
||||
my_set_errno (saveerrno);
|
||||
|
@ -1128,6 +1353,10 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
saveerrno = errno;
|
||||
my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
|
||||
strerror (errno));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"lock not made: Oops: stat of tmp file failed: %s\n",
|
||||
strerror (errno));
|
||||
/* In theory this might be a severe error: It is possible
|
||||
that link succeeded but stat failed due to changed
|
||||
permissions. We can't do anything about it, though. */
|
||||
|
@ -1149,16 +1378,19 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
{
|
||||
saveerrno = errno;
|
||||
my_info_0 ("cannot read lockfile\n");
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"cannot read lockfile\n");
|
||||
my_set_errno (saveerrno);
|
||||
return -1;
|
||||
}
|
||||
my_info_0 ("lockfile disappeared\n");
|
||||
goto again;
|
||||
}
|
||||
else if ( (pid == getpid() && same_node)
|
||||
else if ( (pid == dotlock_get_process_id (h) && same_node && !h->by_parent)
|
||||
|| (same_node && kill (pid, 0) && errno == ESRCH) )
|
||||
/* Stale lockfile is detected. */
|
||||
{
|
||||
/* Stale lockfile is detected. */
|
||||
struct stat sb;
|
||||
|
||||
/* Check if it's unlocked during examining the lockfile. */
|
||||
|
@ -1201,6 +1433,9 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
unlink (h->lockname);
|
||||
my_info_1 (_("removing stale lockfile (created by %d)\n"), pid);
|
||||
close (fd);
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_STALE_REMOVED,
|
||||
_("removing stale lockfile (created by %d)\n"), pid);
|
||||
goto again;
|
||||
}
|
||||
|
||||
|
@ -1218,6 +1453,8 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
wtime = 0; /* Reset because owner chnaged. */
|
||||
|
||||
wtimereal = next_wait_interval (&wtime, &timeout);
|
||||
if (!timeout)
|
||||
timedout = 1; /* remember. */
|
||||
|
||||
sumtime += wtimereal;
|
||||
if (sumtime >= 1500)
|
||||
|
@ -1225,6 +1462,15 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
sumtime = 0;
|
||||
my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
|
||||
pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
|
||||
if (h->info_cb
|
||||
&& h->info_cb (h, h->info_cb_value, DOTLOCK_WAITING,
|
||||
_("waiting for lock (held by %d%s) %s...\n"),
|
||||
pid, maybe_dead,
|
||||
maybe_deadlock(h)? _("(deadlock?) "):""))
|
||||
{
|
||||
my_set_errno (ECANCELED);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tv.tv_sec = wtimereal / 1000;
|
||||
|
@ -1233,7 +1479,7 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||
goto again;
|
||||
}
|
||||
|
||||
my_set_errno (EACCES);
|
||||
my_set_errno (timedout? ETIMEDOUT : EACCES);
|
||||
return -1;
|
||||
}
|
||||
#endif /*HAVE_POSIX_SYSTEM*/
|
||||
|
@ -1246,6 +1492,7 @@ static int
|
|||
dotlock_take_w32 (dotlock_t h, long timeout)
|
||||
{
|
||||
int wtime = 0;
|
||||
int timedout = 0;
|
||||
int w32err;
|
||||
OVERLAPPED ovl;
|
||||
|
||||
|
@ -1264,7 +1511,11 @@ dotlock_take_w32 (dotlock_t h, long timeout)
|
|||
{
|
||||
my_error_2 (_("lock '%s' not made: %s\n"),
|
||||
h->lockname, w32_strerror (w32err));
|
||||
my_set_errno (map_w32_to_errno (w32err));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
_("lock '%s' not made: %s\n"),
|
||||
h->lockname, w32_strerror (w32err));
|
||||
_set_errno (map_w32_to_errno (w32err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1273,15 +1524,26 @@ dotlock_take_w32 (dotlock_t h, long timeout)
|
|||
int wtimereal;
|
||||
|
||||
wtimereal = next_wait_interval (&wtime, &timeout);
|
||||
if (!timeout)
|
||||
timedout = 1; /* remember. */
|
||||
|
||||
if (wtime >= 800)
|
||||
my_info_1 (_("waiting for lock %s...\n"), h->lockname);
|
||||
{
|
||||
my_info_1 (_("waiting for lock %s...\n"), h->lockname);
|
||||
if (h->info_cb
|
||||
&& h->info_cb (h, h->info_cb_value, DOTLOCK_WAITING,
|
||||
_("waiting for lock %s...\n"), h->lockname))
|
||||
{
|
||||
my_set_errno (ECANCELED);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep (wtimereal);
|
||||
goto again;
|
||||
}
|
||||
|
||||
my_set_errno (EACCES);
|
||||
my_set_errno (timedout? ETIMEDOUT : EACCES);
|
||||
return -1;
|
||||
}
|
||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||
|
@ -1328,12 +1590,18 @@ dotlock_release_unix (dotlock_t h)
|
|||
{
|
||||
saveerrno = errno;
|
||||
my_error_0 ("release_dotlock: lockfile error\n");
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"release_dotlock: lockfile error\n");
|
||||
my_set_errno (saveerrno);
|
||||
return -1;
|
||||
}
|
||||
if ( pid != getpid() || !same_node )
|
||||
if ( pid != dotlock_get_process_id (h) || !same_node )
|
||||
{
|
||||
my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid);
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_CONFLICT,
|
||||
"release_dotlock: not our lock (pid=%d)\n", pid);
|
||||
my_set_errno (EACCES);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1343,6 +1611,10 @@ dotlock_release_unix (dotlock_t h)
|
|||
saveerrno = errno;
|
||||
my_error_1 ("release_dotlock: error removing lockfile '%s'\n",
|
||||
h->lockname);
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"release_dotlock: error removing lockfile '%s'\n",
|
||||
h->lockname);
|
||||
my_set_errno (saveerrno);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1363,10 +1635,15 @@ dotlock_release_w32 (dotlock_t h)
|
|||
memset (&ovl, 0, sizeof ovl);
|
||||
if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
|
||||
{
|
||||
int saveerrno = map_w32_to_errno (GetLastError ());
|
||||
int ec = (int)GetLastError ();
|
||||
|
||||
my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n",
|
||||
h->lockname, w32_strerror (-1));
|
||||
my_set_errno (saveerrno);
|
||||
h->lockname, w32_strerror (ec));
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR,
|
||||
"release_dotlock: error removing lockfile '%s': %s\n",
|
||||
h->lockname, w32_strerror (ec));
|
||||
my_set_errno (map_w32_to_errno (ec));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1397,6 +1674,9 @@ dotlock_release (dotlock_t h)
|
|||
if ( !h->locked )
|
||||
{
|
||||
my_debug_1 ("Oops, '%s' is not locked\n", h->lockname);
|
||||
if (h->info_cb)
|
||||
h->info_cb (h, h->info_cb_value, DOTLOCK_NOT_LOCKED,
|
||||
"Oops, '%s' is not locked\n", h->lockname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,12 +97,35 @@ extern "C"
|
|||
struct dotlock_handle;
|
||||
typedef struct dotlock_handle *dotlock_t;
|
||||
|
||||
enum dotlock_reasons
|
||||
{
|
||||
DOTLOCK_CONFIG_TEST, /* Can't check system - function terminates. */
|
||||
DOTLOCK_FILE_ERROR, /* General file error - function terminates. */
|
||||
DOTLOCK_INV_FILE, /* Invalid file - function terminates. */
|
||||
DOTLOCK_CONFLICT, /* Something is wrong - function terminates. */
|
||||
DOTLOCK_NOT_LOCKED, /* Not locked - No action required. */
|
||||
DOTLOCK_STALE_REMOVED, /* Stale lock file was removed - retrying. */
|
||||
DOTLOCK_WAITING /* Waiting for the lock - may be terminated. */
|
||||
};
|
||||
|
||||
/* Flags for dotlock_create. */
|
||||
#define DOTLOCK_PREPARE_CREATE (1U << 5) /* Require dotlock_finish_create. */
|
||||
#define DOTLOCK_LOCK_BY_PARENT (1U << 6) /* Used by dotlock util. */
|
||||
#define DOTLOCK_LOCKED (1U << 7) /* Used by dotlock util. */
|
||||
|
||||
void dotlock_disable (void);
|
||||
dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags);
|
||||
dotlock_t dotlock_finish_create (dotlock_t h, const char *file_to_lock);
|
||||
void dotlock_set_fd (dotlock_t h, int fd);
|
||||
int dotlock_get_fd (dotlock_t h);
|
||||
void dotlock_set_info_cb (dotlock_t h,
|
||||
int (*cb)(dotlock_t, void *,
|
||||
enum dotlock_reasons reason,
|
||||
const char *,...),
|
||||
void *opaque);
|
||||
void dotlock_destroy (dotlock_t h);
|
||||
int dotlock_take (dotlock_t h, long timeout);
|
||||
int dotlock_is_locked (dotlock_t h);
|
||||
int dotlock_release (dotlock_t h);
|
||||
void dotlock_remove_lockfiles (void);
|
||||
|
||||
|
|
196
common/homedir.c
196
common/homedir.c
|
@ -77,6 +77,14 @@
|
|||
#endif
|
||||
|
||||
|
||||
/* Mode flags for unix_rootdir. */
|
||||
enum wantdir_values {
|
||||
WANTDIR_ROOT = 0,
|
||||
WANTDIR_SYSCONF,
|
||||
WANTDIR_SOCKET
|
||||
};
|
||||
|
||||
|
||||
/* The GnuPG homedir. This is only accessed by the functions
|
||||
* gnupg_homedir and gnupg_set_homedir. Malloced. */
|
||||
static char *the_gnupg_homedir;
|
||||
|
@ -491,11 +499,12 @@ w32_rootdir (void)
|
|||
* file system. If WANT_SYSCONFDIR is true the optional sysconfdir
|
||||
* entry is returned. */
|
||||
static const char *
|
||||
unix_rootdir (int want_sysconfdir)
|
||||
unix_rootdir (enum wantdir_values wantdir)
|
||||
{
|
||||
static int checked;
|
||||
static char *dir; /* for the rootdir */
|
||||
static char *sdir; /* for the sysconfdir */
|
||||
static char *s2dir; /* for the socketdir */
|
||||
|
||||
if (!checked)
|
||||
{
|
||||
|
@ -510,8 +519,10 @@ unix_rootdir (int want_sysconfdir)
|
|||
estream_t fp;
|
||||
char *rootdir;
|
||||
char *sysconfdir;
|
||||
char *socketdir;
|
||||
const char *name;
|
||||
int ignoreall = 0;
|
||||
int okay;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -602,45 +613,44 @@ unix_rootdir (int want_sysconfdir)
|
|||
linelen = 0;
|
||||
rootdir = NULL;
|
||||
sysconfdir = NULL;
|
||||
socketdir = NULL;
|
||||
while ((length = es_read_line (fp, &line, &linelen, NULL)) > 0)
|
||||
{
|
||||
static const char *names[] =
|
||||
{
|
||||
"rootdir",
|
||||
"sysconfdir",
|
||||
"socketdir",
|
||||
".enable"
|
||||
};
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
/* Strip NL and CR, if present. */
|
||||
while (length > 0
|
||||
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
|
||||
line[--length] = 0;
|
||||
trim_spaces (line);
|
||||
if (!strncmp (line, "rootdir=", 8))
|
||||
/* Find the stamement. */
|
||||
name = NULL;
|
||||
for (i=0; i < DIM (names); i++)
|
||||
{
|
||||
name = "rootdir";
|
||||
p = line + 8;
|
||||
n = strlen (names[i]);
|
||||
if (!strncmp (line, names[i], n))
|
||||
{
|
||||
while (line[n] == ' ' || line[n] == '\t')
|
||||
n++;
|
||||
if (line[n] == '=')
|
||||
{
|
||||
name = names[i];
|
||||
p = line + n + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strncmp (line, "rootdir =", 9)) /* (What a kludge) */
|
||||
{
|
||||
name = "rootdir";
|
||||
p = line + 9;
|
||||
}
|
||||
else if (!strncmp (line, "sysconfdir=", 11))
|
||||
{
|
||||
name = "sysconfdir";
|
||||
p = line + 11;
|
||||
}
|
||||
else if (!strncmp (line, "sysconfdir =", 12)) /* (What a kludge) */
|
||||
{
|
||||
name = "sysconfdir";
|
||||
p = line + 12;
|
||||
}
|
||||
else if (!strncmp (line, ".enable=", 8))
|
||||
{
|
||||
name = ".enable";
|
||||
p = line + 8;
|
||||
}
|
||||
else if (!strncmp (line, ".enable =", 9))
|
||||
{
|
||||
name = ".enable";
|
||||
p = line + 9;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
if (!name)
|
||||
continue; /* Statement not known. */
|
||||
|
||||
trim_spaces (p);
|
||||
p = substitute_envvars (p);
|
||||
if (!p)
|
||||
|
@ -665,6 +675,11 @@ unix_rootdir (int want_sysconfdir)
|
|||
xfree (sysconfdir);
|
||||
sysconfdir = p;
|
||||
}
|
||||
else if (!strcmp (name, "socketdir"))
|
||||
{
|
||||
xfree (socketdir);
|
||||
socketdir = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
xfree (rootdir);
|
||||
|
@ -680,6 +695,7 @@ unix_rootdir (int want_sysconfdir)
|
|||
xfree (line);
|
||||
xfree (rootdir);
|
||||
xfree (sysconfdir);
|
||||
xfree (socketdir);
|
||||
checked = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -687,29 +703,26 @@ unix_rootdir (int want_sysconfdir)
|
|||
xfree (buffer);
|
||||
xfree (line);
|
||||
|
||||
okay = 0;
|
||||
if (ignoreall)
|
||||
{
|
||||
xfree (rootdir);
|
||||
xfree (sysconfdir);
|
||||
sdir = dir = NULL;
|
||||
}
|
||||
;
|
||||
else if (!rootdir || !*rootdir || *rootdir != '/')
|
||||
{
|
||||
log_info ("invalid rootdir '%s' specified in gpgconf.ctl\n", rootdir);
|
||||
xfree (rootdir);
|
||||
xfree (sysconfdir);
|
||||
dir = NULL;
|
||||
}
|
||||
else if (sysconfdir && (!*sysconfdir || *sysconfdir != '/'))
|
||||
{
|
||||
log_info ("invalid sysconfdir '%s' specified in gpgconf.ctl\n",
|
||||
sysconfdir);
|
||||
xfree (rootdir);
|
||||
xfree (sysconfdir);
|
||||
dir = NULL;
|
||||
}
|
||||
else if (socketdir && (!*socketdir || *socketdir != '/'))
|
||||
{
|
||||
log_info ("invalid socketdir '%s' specified in gpgconf.ctl\n",
|
||||
socketdir);
|
||||
}
|
||||
else
|
||||
{
|
||||
okay = 1;
|
||||
while (*rootdir && rootdir[strlen (rootdir)-1] == '/')
|
||||
rootdir[strlen (rootdir)-1] = 0;
|
||||
dir = rootdir;
|
||||
|
@ -723,11 +736,34 @@ unix_rootdir (int want_sysconfdir)
|
|||
gpgrt_annotate_leaked_object (sdir);
|
||||
/* log_info ("want sysconfdir '%s'\n", sdir); */
|
||||
}
|
||||
if (socketdir)
|
||||
{
|
||||
while (*socketdir && socketdir[strlen (socketdir)-1] == '/')
|
||||
socketdir[strlen (socketdir)-1] = 0;
|
||||
s2dir = socketdir;
|
||||
gpgrt_annotate_leaked_object (s2dir);
|
||||
/* log_info ("want socketdir '%s'\n", s2dir); */
|
||||
}
|
||||
}
|
||||
|
||||
if (!okay)
|
||||
{
|
||||
xfree (rootdir);
|
||||
xfree (sysconfdir);
|
||||
xfree (socketdir);
|
||||
dir = sdir = s2dir = NULL;
|
||||
}
|
||||
checked = 1;
|
||||
}
|
||||
|
||||
return want_sysconfdir? sdir : dir;
|
||||
switch (wantdir)
|
||||
{
|
||||
case WANTDIR_ROOT: return dir;
|
||||
case WANTDIR_SYSCONF: return sdir;
|
||||
case WANTDIR_SOCKET: return s2dir;
|
||||
}
|
||||
|
||||
return NULL; /* Not reached. */
|
||||
}
|
||||
#endif /* Unix */
|
||||
|
||||
|
@ -1038,7 +1074,8 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
|
|||
};
|
||||
int i;
|
||||
struct stat sb;
|
||||
char prefix[19 + 1 + 20 + 6 + 1];
|
||||
char prefixbuffer[19 + 1 + 20 + 6 + 1];
|
||||
const char *prefix;
|
||||
const char *s;
|
||||
char *name = NULL;
|
||||
|
||||
|
@ -1053,35 +1090,42 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
|
|||
* as a background process with no (desktop) user logged in. Thus
|
||||
* we better don't do that. */
|
||||
|
||||
/* Check whether we have a /run/[gnupg/]user dir. */
|
||||
for (i=0; bases[i]; i++)
|
||||
prefix = unix_rootdir (WANTDIR_SOCKET);
|
||||
if (!prefix)
|
||||
{
|
||||
snprintf (prefix, sizeof prefix, "%s/user/%u",
|
||||
bases[i], (unsigned int)getuid ());
|
||||
if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
|
||||
break;
|
||||
}
|
||||
if (!bases[i])
|
||||
{
|
||||
*r_info |= 2; /* No /run/user directory. */
|
||||
goto leave;
|
||||
/* gpgconf.ctl does not specify a directory. Check whether we
|
||||
* have the usual /run/[gnupg/]user dir. */
|
||||
for (i=0; bases[i]; i++)
|
||||
{
|
||||
snprintf (prefixbuffer, sizeof prefixbuffer, "%s/user/%u",
|
||||
bases[i], (unsigned int)getuid ());
|
||||
prefix = prefixbuffer;
|
||||
if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode))
|
||||
break;
|
||||
}
|
||||
if (!bases[i])
|
||||
{
|
||||
*r_info |= 2; /* No /run/user directory. */
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (sb.st_uid != getuid ())
|
||||
{
|
||||
*r_info |= 4; /* Not owned by the user. */
|
||||
if (!skip_checks)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (strlen (prefix) + 7 >= sizeof prefixbuffer)
|
||||
{
|
||||
*r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */
|
||||
goto leave;
|
||||
}
|
||||
strcat (prefixbuffer, "/gnupg");
|
||||
}
|
||||
|
||||
if (sb.st_uid != getuid ())
|
||||
{
|
||||
*r_info |= 4; /* Not owned by the user. */
|
||||
if (!skip_checks)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (strlen (prefix) + 7 >= sizeof prefix)
|
||||
{
|
||||
*r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */
|
||||
goto leave;
|
||||
}
|
||||
strcat (prefix, "/gnupg");
|
||||
|
||||
/* Check whether the gnupg sub directory has proper permissions. */
|
||||
/* Check whether the gnupg sub directory (or the specified diretory)
|
||||
* has proper permissions. */
|
||||
if (stat (prefix, &sb))
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
|
@ -1241,7 +1285,7 @@ gnupg_sysconfdir (void)
|
|||
}
|
||||
return name;
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
const char *dir = unix_rootdir (1);
|
||||
const char *dir = unix_rootdir (WANTDIR_SYSCONF);
|
||||
if (dir)
|
||||
return dir;
|
||||
else
|
||||
|
@ -1270,7 +1314,7 @@ gnupg_bindir (void)
|
|||
else
|
||||
return rdir;
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
rdir = unix_rootdir (0);
|
||||
rdir = unix_rootdir (WANTDIR_ROOT);
|
||||
if (rdir)
|
||||
{
|
||||
if (!name)
|
||||
|
@ -1297,7 +1341,7 @@ gnupg_libexecdir (void)
|
|||
static char *name;
|
||||
const char *rdir;
|
||||
|
||||
rdir = unix_rootdir (0);
|
||||
rdir = unix_rootdir (WANTDIR_ROOT);
|
||||
if (rdir)
|
||||
{
|
||||
if (!name)
|
||||
|
@ -1327,7 +1371,7 @@ gnupg_libdir (void)
|
|||
#else /*!HAVE_W32_SYSTEM*/
|
||||
const char *rdir;
|
||||
|
||||
rdir = unix_rootdir (0);
|
||||
rdir = unix_rootdir (WANTDIR_ROOT);
|
||||
if (rdir)
|
||||
{
|
||||
if (!name)
|
||||
|
@ -1358,7 +1402,7 @@ gnupg_datadir (void)
|
|||
#else /*!HAVE_W32_SYSTEM*/
|
||||
const char *rdir;
|
||||
|
||||
rdir = unix_rootdir (0);
|
||||
rdir = unix_rootdir (WANTDIR_ROOT);
|
||||
if (rdir)
|
||||
{
|
||||
if (!name)
|
||||
|
@ -1390,7 +1434,7 @@ gnupg_localedir (void)
|
|||
#else /*!HAVE_W32_SYSTEM*/
|
||||
const char *rdir;
|
||||
|
||||
rdir = unix_rootdir (0);
|
||||
rdir = unix_rootdir (WANTDIR_ROOT);
|
||||
if (rdir)
|
||||
{
|
||||
if (!name)
|
||||
|
|
|
@ -48,6 +48,7 @@ struct name_value_container
|
|||
struct name_value_entry *first;
|
||||
struct name_value_entry *last;
|
||||
unsigned int private_key_mode:1;
|
||||
unsigned int modified:1;
|
||||
};
|
||||
|
||||
|
||||
|
@ -87,11 +88,15 @@ my_error (gpg_err_code_t ec)
|
|||
|
||||
/* Allocation and deallocation. */
|
||||
|
||||
/* Allocate a private key container structure. */
|
||||
/* Allocate a name value container structure. */
|
||||
nvc_t
|
||||
nvc_new (void)
|
||||
{
|
||||
return xtrycalloc (1, sizeof (struct name_value_container));
|
||||
nvc_t nvc;
|
||||
nvc = xtrycalloc (1, sizeof (struct name_value_container));
|
||||
if (nvc)
|
||||
nvc->modified = 1;
|
||||
return nvc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,6 +147,24 @@ nvc_release (nvc_t pk)
|
|||
xfree (pk);
|
||||
}
|
||||
|
||||
|
||||
/* Return the modified-flag of the container and clear it if CLEAR is
|
||||
* set. That flag is set for a new container and set with each
|
||||
* update. */
|
||||
int
|
||||
nvc_modified (nvc_t pk, int clear)
|
||||
{
|
||||
int modified;
|
||||
|
||||
if (!pk)
|
||||
return 0;
|
||||
modified = pk->modified;
|
||||
if (clear)
|
||||
pk->modified = 0;
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Dealing with names and values. */
|
||||
|
@ -427,6 +450,8 @@ _nvc_add (nvc_t pk, char *name, char *value, strlist_t raw_value,
|
|||
else
|
||||
pk->first = pk->last = e;
|
||||
|
||||
pk->modified = 1;
|
||||
|
||||
leave:
|
||||
if (err)
|
||||
{
|
||||
|
@ -476,36 +501,29 @@ nvc_set (nvc_t pk, const char *name, const char *value)
|
|||
|
||||
e = nvc_lookup (pk, name);
|
||||
if (e)
|
||||
{
|
||||
char *v;
|
||||
|
||||
v = xtrystrdup (value);
|
||||
if (v == NULL)
|
||||
return my_error_from_syserror ();
|
||||
|
||||
free_strlist_wipe (e->raw_value);
|
||||
e->raw_value = NULL;
|
||||
if (e->value)
|
||||
wipememory (e->value, strlen (e->value));
|
||||
xfree (e->value);
|
||||
e->value = v;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return nve_set (pk, e, value);
|
||||
else
|
||||
return nvc_add (pk, name, value);
|
||||
}
|
||||
|
||||
|
||||
/* Update entry E to VALUE. */
|
||||
/* Update entry E to VALUE. PK is optional; if given its modified
|
||||
* flag will be updated. */
|
||||
gpg_error_t
|
||||
nve_set (nve_t e, const char *value)
|
||||
nve_set (nvc_t pk, nve_t e, const char *value)
|
||||
{
|
||||
char *v;
|
||||
|
||||
if (!e)
|
||||
return GPG_ERR_INV_ARG;
|
||||
|
||||
if (e->value && value && !strcmp (e->value, value))
|
||||
{
|
||||
/* Setting same value - ignore this call and don't set the
|
||||
* modified flag (if PK is given). */
|
||||
return 0;
|
||||
}
|
||||
|
||||
v = xtrystrdup (value? value:"");
|
||||
if (!v)
|
||||
return my_error_from_syserror ();
|
||||
|
@ -516,6 +534,8 @@ nve_set (nve_t e, const char *value)
|
|||
wipememory (e->value, strlen (e->value));
|
||||
xfree (e->value);
|
||||
e->value = v;
|
||||
if (pk)
|
||||
pk->modified = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -536,6 +556,7 @@ nvc_delete (nvc_t pk, nve_t entry)
|
|||
pk->last = entry->prev;
|
||||
|
||||
nve_release (entry, pk->private_key_mode);
|
||||
pk->modified = 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,9 @@ nvc_t nvc_new_private_key (void);
|
|||
/* Release a name value container structure. */
|
||||
void nvc_release (nvc_t pk);
|
||||
|
||||
/* Return the modified flag and optionally clear it. */
|
||||
int nvc_modified (nvc_t pk, int clear);
|
||||
|
||||
/* Get the name. */
|
||||
char *nve_name (nve_t pke);
|
||||
|
||||
|
@ -92,8 +95,8 @@ gpg_error_t nvc_add (nvc_t pk, const char *name, const char *value);
|
|||
first entry is updated. */
|
||||
gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value);
|
||||
|
||||
/* Update entry E to VALUE. */
|
||||
gpg_error_t nve_set (nve_t e, const char *value);
|
||||
/* Update entry E to VALUE. PK is optional. */
|
||||
gpg_error_t nve_set (nvc_t pk, nve_t e, const char *value);
|
||||
|
||||
/* Delete the given entry from PK. */
|
||||
void nvc_delete (nvc_t pk, nve_t pke);
|
||||
|
|
|
@ -122,6 +122,9 @@ typedef enum
|
|||
SIGSUBPKT_ATTST_SIGS = 37, /* Attested Certifications. */
|
||||
SIGSUBPKT_KEY_BLOCK = 38, /* Entire key used. */
|
||||
|
||||
SIGSUBPKT_META_HASH = 40, /* Literal Data Meta Hash. */
|
||||
SIGSUBPKT_TRUST_ALIAS = 41, /* Trust Alias. */
|
||||
|
||||
SIGSUBPKT_FLAG_CRITICAL = 128
|
||||
}
|
||||
sigsubpkttype_t;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#ifdef HAVE_W32_SYSTEM
|
||||
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
|
||||
|
||||
|
||||
const char *
|
||||
w32_strerror (int ec)
|
||||
{
|
||||
|
@ -174,6 +175,11 @@ strconcat (const char *s1, ...)
|
|||
|
||||
#define PGM "t-dotlock"
|
||||
|
||||
static int opt_silent;
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
static volatile int ctrl_c_pending_flag;
|
||||
static void
|
||||
|
@ -217,6 +223,9 @@ inf (const char *format, ...)
|
|||
{
|
||||
va_list arg_ptr;
|
||||
|
||||
if (opt_silent)
|
||||
return;
|
||||
|
||||
va_start (arg_ptr, format);
|
||||
fprintf (stderr, PGM "[%lu]: ", (unsigned long)getpid ());
|
||||
vfprintf (stderr, format, arg_ptr);
|
||||
|
@ -225,15 +234,35 @@ inf (const char *format, ...)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
lock_info_cb (dotlock_t h, void *opaque, enum dotlock_reasons reason,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list arg_ptr;
|
||||
|
||||
va_start (arg_ptr, format);
|
||||
fprintf (stderr, PGM "[%lu]: info_cb: reason %d, ",
|
||||
(unsigned long)getpid (), (int)reason);
|
||||
vfprintf (stderr, format, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lock_and_unlock (const char *fname)
|
||||
{
|
||||
dotlock_t h;
|
||||
unsigned long usec;
|
||||
|
||||
h = dotlock_create (fname, 0);
|
||||
h = dotlock_create (fname, DOTLOCK_PREPARE_CREATE);
|
||||
if (!h)
|
||||
die ("error creating lock file for '%s': %s", fname, strerror (errno));
|
||||
dotlock_set_info_cb (h, lock_info_cb, NULL);
|
||||
h = dotlock_finish_create (h, fname);
|
||||
if (!h)
|
||||
die ("error finishing lock file creation for '%s': %s",
|
||||
fname, strerror (errno));
|
||||
inf ("lock created");
|
||||
|
||||
do
|
||||
|
@ -270,6 +299,11 @@ main (int argc, char **argv)
|
|||
ctrl_c_pending_flag = 1;
|
||||
argc--;
|
||||
}
|
||||
if (argc > 1 && !strcmp (argv[1], "--silent"))
|
||||
{
|
||||
opt_silent = 1;
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
fname = argv[argc-1];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue