diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 12 | ||||
-rw-r--r-- | g10/g10.c | 3 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/options.skel | 6 | ||||
-rw-r--r-- | g10/ringedit.c | 43 | ||||
-rw-r--r-- | g10/tdbio.c | 38 |
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. @@ -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 ); } |