summaryrefslogtreecommitdiffstats
path: root/g10/ringedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/ringedit.c')
-rw-r--r--g10/ringedit.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/g10/ringedit.c b/g10/ringedit.c
index d12afa6dc..e7ffdbfa8 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -77,6 +77,7 @@ typedef struct resource_table_struct RESTBL;
#define MAX_RESOURCES 10
static RESTBL resource_table[MAX_RESOURCES];
+static const char *keyring_lock;
static int search( PACKET *pkt, KBPOS *kbpos, int secret );
@@ -116,6 +117,15 @@ fatal_gdbm_error( const char *string )
#endif /* HAVE_LIBGDBM */
+static void
+cleanup( void )
+{
+ if( keyring_lock ) {
+ release_dotlock( keyring_lock );
+ keyring_lock = NULL;
+ }
+}
+
/****************************************************************
****************** public functions ****************************
****************************************************************/
@@ -152,6 +162,7 @@ enum_keyblock_resources( int *sequence, int secret )
int
add_keyblock_resource( const char *url, int force, int secret )
{
+ static int initialized = 0;
static int any_secret, any_public;
const char *resname = url;
IOBUF iobuf = NULL;
@@ -160,6 +171,11 @@ add_keyblock_resource( const char *url, int force, int secret )
int rc = 0;
enum resource_type rt = rt_UNKNOWN;
+ if( !initialized ) {
+ initialized = 1;
+ atexit( cleanup );
+ }
+
/* Do we have an URL?
* gnupg-gdbm:filename := this is a GDBM resource
* gnupg-ring:filename := this is a plain keyring
@@ -843,7 +859,7 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
*
* A string "GnuPG user db", a \n.
* user ids of one key, delimited by \t,
- * a # or ^ followed by a 20 byte fingerprint, followed by an \n
+ * a # or ^ followed by a 20 byte fingerprint, followed by an \n
* The literal characters =, \n, \t, #, ^ must be replaced by a equal sign
* and their hex value.
*
@@ -1224,6 +1240,11 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
if( kbpos->fp )
BUG(); /* not allowed with such a handle */
+ if( !keyring_lock );
+ keyring_lock = make_dotlock( rentry->fname, -1 );
+ if( !keyring_lock )
+ log_fatal("can't lock '%s'\n", rentry->fname );
+
/* open the source file */
fp = iobuf_fopen( rentry->fname, "rb" );
if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */
@@ -1233,6 +1254,10 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
newfp = iobuf_create( rentry->fname );
if( !newfp ) {
log_error(_("%s: can't create: %s\n"), rentry->fname, strerror(errno));
+ if( !opt.lock_once ) {
+ release_dotlock( keyring_lock );
+ keyring_lock = NULL;
+ }
return G10ERR_OPEN_FILE;
}
else
@@ -1244,16 +1269,28 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) );
iobuf_cancel(newfp);
+ if( !opt.lock_once ) {
+ release_dotlock( keyring_lock );
+ keyring_lock = NULL;
+ }
return G10ERR_WRITE_FILE;
}
}
if( iobuf_close(newfp) ) {
log_error("%s: close failed: %s\n", rentry->fname, strerror(errno));
+ if( !opt.lock_once ) {
+ release_dotlock( keyring_lock );
+ keyring_lock = NULL;
+ }
return G10ERR_CLOSE_FILE;
}
if( chmod( rentry->fname, S_IRUSR | S_IWUSR ) ) {
log_error("%s: chmod failed: %s\n",
rentry->fname, strerror(errno) );
+ if( !opt.lock_once ) {
+ release_dotlock( keyring_lock );
+ keyring_lock = NULL;
+ }
return G10ERR_WRITE_FILE;
}
return 0;
@@ -1418,6 +1455,10 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
}
leave:
+ if( !opt.lock_once ) {
+ release_dotlock( keyring_lock );
+ keyring_lock = NULL;
+ }
m_free(bakfname);
m_free(tmpfname);
return rc;