diff options
Diffstat (limited to '')
-rw-r--r-- | g10/ringedit.c | 91 |
1 files changed, 47 insertions, 44 deletions
diff --git a/g10/ringedit.c b/g10/ringedit.c index 4a97f78f8..d5ac6ac77 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -72,12 +72,13 @@ struct resource_table_struct { GDBM_FILE dbf; #endif enum resource_type rt; + DOTLOCK lockhd; + int is_locked; }; 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 ); @@ -117,15 +118,40 @@ fatal_gdbm_error( const char *string ) #endif /* HAVE_LIBGDBM */ + +/**************** + * Hmmm, how to avoid deadlock? They should not happen if everyone + * locks the key resources in the same order; but who knows. + * A solution is to use only one lock file in the gnupg homedir but + * what will happen with key resources which normally don't belong + * to the gpg homedir? + */ static void -cleanup( void ) +lock_rentry( RESTBL *rentry ) { - if( keyring_lock ) { - release_dotlock( keyring_lock ); - keyring_lock = NULL; + if( !rentry->lockhd ) { + rentry->lockhd = create_dotlock( rentry->fname ); + if( !rentry->lockhd ) + log_fatal("can't allocate lock for `%s'\n", rentry->fname ); + rentry->is_locked = 0; + } + if( !rentry->is_locked ) { + if( make_dotlock( rentry->lockhd, -1 ) ) + log_fatal("can't lock `%s'\n", rentry->fname ); + rentry->is_locked = 1; } } +static void +unlock_rentry( RESTBL *rentry ) +{ + if( opt.lock_once ) + return; + if( !release_dotlock( rentry->lockhd ) ) + rentry->is_locked = 0; +} + + /**************************************************************** ****************** public functions **************************** ****************************************************************/ @@ -162,7 +188,6 @@ 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; @@ -171,10 +196,6 @@ 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 @@ -190,7 +211,7 @@ add_keyblock_resource( const char *url, int force, int secret ) rt = rt_GDBM; resname += 11; } - #ifndef __MINGW32__ + #ifndef HAVE_DRIVE_LETTERS else if( strchr( resname, ':' ) ) { log_error("%s: invalid URL\n", url ); rc = G10ERR_GENERAL; @@ -264,7 +285,7 @@ add_keyblock_resource( const char *url, int force, int secret ) if( access(filename, F_OK) ) { if( strlen(filename) >= 7 && !strcmp(filename+strlen(filename)-7, "/.gnupg") ) { - #if __MINGW32__ + #ifdef HAVE_DOSISH_SYSTEM if( mkdir(filename) ) #else if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) ) @@ -298,10 +319,10 @@ add_keyblock_resource( const char *url, int force, int secret ) else log_info(_("%s: keyring created\n"), filename ); } - #if __MINGW32__ || 1 - /* must close it again */ + #if HAVE_DOSISH_SYSTEM || 1 iobuf_close( iobuf ); iobuf = NULL; + /* must close it again */ #endif break; @@ -1039,7 +1060,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname ) kbpos->rt = rt_RING; kbpos->valid = 0; - #if __MINGW32__ || 1 + #if HAVE_DOSISH_SYSTEM || 1 assert(!iobuf); iobuf = iobuf_open( fname ); if( !iobuf ) { @@ -1084,7 +1105,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname ) leave: free_packet(&pkt); set_packet_list_mode(save_mode); - #if __MINGW32__ || 1 + #if HAVE_DOSISH_SYSTEM || 1 iobuf_close(iobuf); #endif return rc; @@ -1276,10 +1297,7 @@ 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 ); + lock_rentry( rentry ); /* open the source file */ fp = iobuf_open( rentry->fname ); @@ -1290,10 +1308,7 @@ 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; - } + unlock_rentry( rentry ); return G10ERR_OPEN_FILE; } else @@ -1305,28 +1320,19 @@ 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; - } + unlock_rentry( rentry ); 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; - } + unlock_rentry( rentry ); 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; - } + unlock_rentry( rentry ); return G10ERR_WRITE_FILE; } return 0; @@ -1338,7 +1344,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) } /* create the new file */ - #ifdef __MINGW32__ + #ifdef USE_ONLY_8DOT3 /* Here is another Windoze bug?: * you cant rename("pubring.gpg.tmp", "pubring.gpg"); * but rename("pubring.gpg.tmp", "pubring.aaa"); @@ -1451,7 +1457,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) goto leave; } /* if the new file is a secring, restrict the permissions */ - #ifndef __MINGW32__ + #ifndef HAVE_DOSISH_SYSTEM if( rentry->secret ) { if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) { log_error("%s: chmod failed: %s\n", @@ -1464,7 +1470,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) /* rename and make backup file */ if( !rentry->secret ) { /* but not for secret keyrings */ - #ifdef __MINGW32__ + #ifdef HAVE_DOSISH_SYSTEM remove( bakfname ); #endif if( rename( rentry->fname, bakfname ) ) { @@ -1474,7 +1480,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) goto leave; } } - #ifdef __MINGW32__ + #ifdef HAVE_DOSISH_SYSTEM remove( rentry->fname ); #endif if( rename( tmpfname, rentry->fname ) ) { @@ -1492,10 +1498,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) } leave: - if( !opt.lock_once ) { - release_dotlock( keyring_lock ); - keyring_lock = NULL; - } + unlock_rentry( rentry ); m_free(bakfname); m_free(tmpfname); return rc; |