aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog12
-rw-r--r--g10/g10.c3
-rw-r--r--g10/options.h1
-rw-r--r--g10/options.skel6
-rw-r--r--g10/ringedit.c43
-rw-r--r--g10/tdbio.c38
6 files changed, 101 insertions, 2 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 20c5abdb9..455451cbd 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,15 @@
+Fri Nov 27 21:37:41 CET 1998 Werner Koch <[email protected]>
+
+ * g10.c: New option --lock-once
+ * tdbio.c (open_db): Add an atexit
+ (cleanup): New.
+ (tdbio_sync): Add locking.
+ (tdbio_end_transaction): Ditto.
+ (put_record_into_cache): Ditto.
+ * ringedit.c (keyring_copy): Ditto.
+ (cleanup): New.
+ (add_keyblock_resource): Add an atexit.
+
Fri Nov 27 15:30:24 CET 1998 Werner Koch <[email protected]>
* armor.c (find_header): Another fix for clearsigs.
diff --git a/g10/g10.c b/g10/g10.c
index a0ba4e1ef..815d61041 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -147,6 +147,7 @@ enum cmd_and_opt_values { aNull = 0,
oS2KCipher,
oCharset,
oNotDashEscaped,
+ oLockOnce,
aTest };
@@ -295,6 +296,7 @@ static ARGPARSE_OPTS opts[] = {
{ oSetFilename, "set-filename", 2, "@" },
{ oComment, "comment", 2, "@" },
{ oNotDashEscaped, "not-dash-escaped", 0, "@" },
+ { oLockOnce, "lock-once", 0, "@" },
{0} };
@@ -768,6 +770,7 @@ main( int argc, char **argv )
pargs.r.ret_str);
break;
case oNotDashEscaped: opt.not_dash_escaped = 1; break;
+ case oLockOnce: opt.lock_once = 1; break;
default : pargs.err = configfp? 1:2; break;
}
diff --git a/g10/options.h b/g10/options.h
index 538b175d7..a8164f89d 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -65,6 +65,7 @@ struct {
int s2k_digest_algo;
int s2k_cipher_algo;
int not_dash_escaped;
+ int lock_once;
} opt;
diff --git a/g10/options.skel b/g10/options.skel
index 3ce6e5aa8..9fe89b1fb 100644
--- a/g10/options.skel
+++ b/g10/options.skel
@@ -46,3 +46,9 @@ compress-algo 1
# everytime you use --mynames, it will be expanded to the options
# in the above defintion. The name of the alias may not be abbreviated.
+# lock tthe file only once for the lifetime of a process.
+# if you do not define this, the lock will be obtained and released
+# every time it is needed - normally this is not needed.
+lock-once
+
+
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;
diff --git a/g10/tdbio.c b/g10/tdbio.c
index bac8a3364..5d1864c3d 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -77,6 +77,7 @@ struct cmp_sdir_struct {
static char *db_name;
+static const char *lockname;
static int db_fd = -1;
static int in_transaction;
@@ -235,6 +236,10 @@ put_record_into_cache( ulong recno, const char *data )
int n = dirty_count / 5; /* discard some dirty entries */
if( !n )
n = 1;
+ if( !lockname )
+ lockname = make_dotlock( db_name, -1 );
+ if( !lockname )
+ log_fatal("can't get a lock - giving up\n");
for( unused = NULL, r = cache_list; r; r = r->next ) {
if( r->flags.used && r->flags.dirty ) {
int rc = write_cache_item( r );
@@ -248,6 +253,10 @@ put_record_into_cache( ulong recno, const char *data )
break;
}
}
+ if( !opt.lock_once ) {
+ release_dotlock( lockname );
+ lockname=NULL;
+ }
assert( unused );
r = unused;
r->flags.used = 1;
@@ -276,6 +285,7 @@ int
tdbio_sync()
{
CACHE_CTRL r;
+ int did_lock = 0;
if( in_transaction )
log_bug("tdbio: syncing while in transaction\n");
@@ -283,6 +293,12 @@ tdbio_sync()
if( !cache_is_dirty )
return 0;
+ if( !lockname ) {
+ lockname = make_dotlock( db_name, -1 );
+ did_lock = 1;
+ if( !lockname )
+ log_fatal("can't get a lock - giving up\n");
+ }
for( r = cache_list; r; r = r->next ) {
if( r->flags.used && r->flags.dirty ) {
int rc = write_cache_item( r );
@@ -291,6 +307,10 @@ tdbio_sync()
}
}
cache_is_dirty = 0;
+ if( did_lock && !opt.lock_once ) {
+ release_dotlock( lockname );
+ lockname=NULL;
+ }
return 0;
}
@@ -324,10 +344,18 @@ tdbio_end_transaction()
if( !in_transaction )
log_bug("tdbio: no active transaction\n");
+ if( !lockname )
+ lockname = make_dotlock( db_name, -1 );
+ if( !lockname )
+ log_fatal("can't get a lock - giving up\n");
block_all_signals();
in_transaction = 0;
rc = tdbio_sync();
unblock_all_signals();
+ if( !opt.lock_once ) {
+ release_dotlock( lockname );
+ lockname=NULL;
+ }
return rc;
}
@@ -452,6 +480,14 @@ tdbio_get_dbname()
}
+static void
+cleanup(void)
+{
+ if( lockname ) {
+ release_dotlock(lockname);
+ lockname = NULL;
+ }
+}
static void
open_db()
@@ -468,7 +504,7 @@ open_db()
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
log_fatal( _("%s: invalid trust-db\n"), db_name );
- /* fixme: check ->locked and other stuff */
+ atexit( cleanup );
}