diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index f167c96db..546af81a0 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -2266,7 +2266,7 @@ create_private_keys_directory (const char *home) struct stat statbuf; fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL); - if (stat (fname, &statbuf) && errno == ENOENT) + if (gnupg_stat (fname, &statbuf) && errno == ENOENT) { if (gnupg_mkdir (fname, "-rwx")) log_error (_("can't create directory '%s': %s\n"), @@ -2305,7 +2305,7 @@ create_directories (void) char *home; home = make_filename (gnupg_homedir (), NULL); - if ( stat (home, &statbuf) ) + if (gnupg_stat (home, &statbuf)) { if (errno == ENOENT) { @@ -2390,7 +2390,7 @@ handle_tick (void) /* Check whether the homedir is still available. */ if (!shutdown_pending && (!have_homedir_inotify || !reliable_homedir_inotify) - && stat (gnupg_homedir (), &statbuf) && errno == ENOENT) + && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT) { shutdown_pending = 1; log_info ("homedir has been removed - shutting down\n"); diff --git a/common/mkdir_p.c b/common/mkdir_p.c index c26cfee01..6fb98c370 100644 --- a/common/mkdir_p.c +++ b/common/mkdir_p.c @@ -78,7 +78,7 @@ gnupg_amkdir_p (const char **directory_components) /* log_debug ("%s: stat(%s)\n", __func__, dirs[i]); */ - if (!stat (dirs[i], &s)) + if (!gnupg_stat (dirs[i], &s)) { if ( ! S_ISDIR (s.st_mode)) { diff --git a/common/sysutils.c b/common/sysutils.c index bfb5d7dd8..f8c3a5857 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -1078,6 +1078,49 @@ gnupg_access (const char *name, int mode) #endif } + +/* A wrapper around stat to handle Unicode file names under Windows. */ +#ifdef HAVE_STAT +int +gnupg_stat (const char *name, struct stat *statbuf) +{ +# ifdef HAVE_W32_SYSTEM + if (any8bitchar (name)) + { + wchar_t *wname; + struct _stat32 st32; + int ret; + + wname = utf8_to_wchar (name); + if (!wname) + return -1; + ret = _wstat (wname, &st32); + xfree (wname); + if (!ret) + { + statbuf->st_dev = st32.st_dev; + statbuf->st_ino = st32.st_ino; + statbuf->st_mode = st32.st_mode; + statbuf->st_nlink = st32.st_nlink; + statbuf->st_uid = st32.st_uid; + statbuf->st_gid = st32.st_gid; + statbuf->st_rdev = st32.st_rdev; + statbuf->st_size = st32.st_size; + statbuf->st_atime = st32.st_atime; + statbuf->st_mtime = st32.st_mtime; + statbuf->st_ctime = st32.st_ctime; + } + return ret; + } + else + return stat (name, statbuf); +# else + return stat (name, statbuf); +# endif +} +#endif /*HAVE_STAT*/ + + /* A wrapper around open to handle Unicode file names under Windows. */ int gnupg_open (const char *name, int flags, unsigned int mode) diff --git a/common/sysutils.h b/common/sysutils.h index d088fe29f..eee4cf5b6 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -46,6 +46,9 @@ typedef int gnupg_fd_t; #define FD2INT(h) (h) #endif +#ifdef HAVE_STAT +# include +#endif void trap_unaligned (void); int disable_core_dumps (void); @@ -74,6 +77,9 @@ int gnupg_setenv (const char *name, const char *value, int overwrite); int gnupg_unsetenv (const char *name); char *gnupg_getcwd (void); gpg_err_code_t gnupg_access (const char *name, int mode); +#ifdef HAVE_STAT +int gnupg_stat (const char *name, struct stat *statbuf); +#endif /*HAVE_STAT*/ int gnupg_open (const char *name, int flags, unsigned int mode); gpg_error_t gnupg_chuid (const char *user, int silent); char *gnupg_get_socket_name (int fd); diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 54caf4136..88b07cd7a 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -271,7 +271,7 @@ cleanup_cache_dir (int force) if (force) okay = 1; else - okay = (!stat (cdbname, &sbuf) && S_ISREG (sbuf.st_mode)); + okay = (!gnupg_stat (cdbname, &sbuf) && S_ISREG (sbuf.st_mode)); if (okay) { diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index a7b0cc051..838ab9487 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -2024,7 +2024,7 @@ handle_tick (void) /* Check whether the homedir is still available. */ if (!shutdown_pending - && stat (gnupg_homedir (), &statbuf) && errno == ENOENT) + && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT) { shutdown_pending = 1; log_info ("homedir has been removed - shutting down\n"); diff --git a/g10/gpg.c b/g10/gpg.c index 1b1d18969..c5c6f87ad 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1574,7 +1574,7 @@ check_permissions (const char *path, int item) } /* It's okay if the file or directory doesn't exist */ - if(stat(tmppath,&statbuf)!=0) + if (gnupg_stat (tmppath,&statbuf)) { ret=0; goto end; @@ -1585,7 +1585,7 @@ check_permissions (const char *path, int item) I'm stopping at one level down. */ dir=make_dirname(tmppath); - if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode)) + if (gnupg_stat (dir,&dirbuf) || !S_ISDIR (dirbuf.st_mode)) { /* Weird error */ ret=1; diff --git a/g10/keyring.c b/g10/keyring.c index f9ac83615..e044cab1a 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1368,7 +1368,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname) statbuf.st_mode=S_IRUSR | S_IWUSR; - if (!stat (bakfname, &statbuf) && !chmod (fname, statbuf.st_mode)) + if (!gnupg_stat (bakfname, &statbuf) && !chmod (fname, statbuf.st_mode)) ; else log_error ("WARNING: unable to restore permissions to '%s': %s", diff --git a/g10/misc.c b/g10/misc.c index 6d3b047e8..111a916e8 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -103,7 +103,7 @@ register_secured_file (const char *fname) struct secured_file_item *sf; /* Note that we stop immediately if something goes wrong here. */ - if (stat (fname, &buf)) + if (gnupg_stat (fname, &buf)) log_fatal (_("fstat of '%s' failed in %s: %s\n"), fname, "register_secured_file", strerror (errno)); /* log_debug ("registering '%s' i=%lu.%lu\n", fname, */ @@ -132,7 +132,7 @@ unregister_secured_file (const char *fname) struct stat buf; struct secured_file_item *sf, *sfprev; - if (stat (fname, &buf)) + if (gnupg_stat (fname, &buf)) { log_error (_("fstat of '%s' failed in %s: %s\n"), fname, "unregister_secured_file", strerror (errno)); @@ -206,7 +206,7 @@ is_secured_filename (const char *fname) /* Note that we print out a error here and claim that a file is secure if something went wrong. */ - if (stat (fname, &buf)) + if (gnupg_stat (fname, &buf)) { if (errno == ENOENT || errno == EPERM || errno == EACCES) return 0; diff --git a/g10/openfile.c b/g10/openfile.c index 424fd9114..be186bd81 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -411,7 +411,7 @@ get_openpgp_revocdir (const char *home) struct stat statbuf; fname = make_filename (home, GNUPG_OPENPGP_REVOC_DIR, NULL); - if (stat (fname, &statbuf) && errno == ENOENT) + if (gnupg_stat (fname, &statbuf) && errno == ENOENT) { if (gnupg_mkdir (fname, "-rwx")) log_error (_("can't create directory '%s': %s\n"), diff --git a/g10/tdbio.c b/g10/tdbio.c index 193f80dc2..f49f4435e 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -681,7 +681,7 @@ tdbio_set_dbname (ctrl_t ctrl, const char *new_dbname, * trustdb.gpg. This check is not required in theory, but it helps * in practice avoiding costly operations of preparing and taking * the lock. */ - if (!stat (fname, &statbuf) && statbuf.st_size > 0) + if (!gnupg_stat (fname, &statbuf) && statbuf.st_size > 0) { /* OK, we have the valid trustdb.gpg already. */ return 0; @@ -722,7 +722,7 @@ tdbio_set_dbname (ctrl_t ctrl, const char *new_dbname, take_write_lock (); if (gnupg_access (fname, R_OK) - || stat (fname, &statbuf) + || gnupg_stat (fname, &statbuf) || statbuf.st_size == 0) { estream_t fp; diff --git a/g10/tofu.c b/g10/tofu.c index 2eda1ff30..f49083844 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -197,7 +197,7 @@ begin_transaction (ctrl_t ctrl, int only_batch) /* Check if another process wants to run. (We just ignore any * stat failure. A waiter might have to wait a bit longer, but * otherwise there should be no impact.) */ - if (stat (dbs->want_lock_file, &statbuf) == 0 + if (gnupg_stat (dbs->want_lock_file, &statbuf) == 0 && statbuf.st_ctime != dbs->want_lock_file_ctime) { end_transaction (ctrl, 2); @@ -237,7 +237,7 @@ begin_transaction (ctrl_t ctrl, int only_batch) dbs->in_batch_transaction = 1; dbs->batch_update_started = gnupg_get_time (); - if (stat (dbs->want_lock_file, &statbuf) == 0) + if (gnupg_stat (dbs->want_lock_file, &statbuf) == 0) dbs->want_lock_file_ctime = statbuf.st_ctime; } diff --git a/g13/backend.c b/g13/backend.c index 71cd6ffc1..a0a26752c 100644 --- a/g13/backend.c +++ b/g13/backend.c @@ -139,7 +139,7 @@ be_take_lock_for_create (ctrl_t ctrl, const char *fname, dotlock_t *r_lock) } /* Check again that the file does not exist. */ - err = stat (fname, &sb)? 0 : gpg_error (GPG_ERR_EEXIST); + err = gnupg_stat (fname, &sb)? 0 : gpg_error (GPG_ERR_EEXIST); leave: if (!err) diff --git a/g13/create.c b/g13/create.c index d773dfa81..bc31f4e32 100644 --- a/g13/create.c +++ b/g13/create.c @@ -250,7 +250,7 @@ g13_create_container (ctrl_t ctrl, const char *filename) { struct stat sb; - if (!stat (detachedname, &sb)) + if (!gnupg_stat (detachedname, &sb)) { err = gpg_error (GPG_ERR_EEXIST); goto leave; diff --git a/g13/mount.c b/g13/mount.c index bee47fbd5..45b60806c 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -121,7 +121,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) { struct stat sb; - if (stat (filename, &sb)) + if (gnupg_stat (filename, &sb)) { err = gpg_error_from_syserror (); goto leave; diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c index 09c4d967b..4320ac394 100644 --- a/g13/sh-dmcrypt.c +++ b/g13/sh-dmcrypt.c @@ -94,7 +94,7 @@ check_blockdev (const char *devname, int expect_busy) char **fields = NULL; int lno, count; - if (stat (devname, &sb)) + if (gnupg_stat (devname, &sb)) { err = gpg_error_from_syserror (); log_error ("error stating '%s': %s\n", devname, gpg_strerror (err)); diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index 5acac97a5..753a2601a 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -1178,7 +1178,7 @@ create_public_keys_directory (const char *home) struct stat statbuf; fname = make_filename (home, GNUPG_PUBLIC_KEYS_DIR, NULL); - if (stat (fname, &statbuf) && errno == ENOENT) + if (gnupg_stat (fname, &statbuf) && errno == ENOENT) { if (gnupg_mkdir (fname, "-rwxr-x")) log_error (_("can't create directory '%s': %s\n"), @@ -1207,7 +1207,7 @@ create_directories (void) char *home; home = make_filename (gnupg_homedir (), NULL); - if (stat (home, &statbuf)) + if (gnupg_stat (home, &statbuf)) { if (errno == ENOENT) { @@ -1273,7 +1273,7 @@ handle_tick (void) /* Check whether the homedir is still available. */ if (!shutdown_pending && (!have_homedir_inotify || !reliable_homedir_inotify) - && stat (gnupg_homedir (), &statbuf) && errno == ENOENT) + && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT) { shutdown_pending = 1; log_info ("homedir has been removed - shutting down\n"); diff --git a/tools/gpg-pair-tool.c b/tools/gpg-pair-tool.c index 25fa074c8..4a9a6f56c 100644 --- a/tools/gpg-pair-tool.c +++ b/tools/gpg-pair-tool.c @@ -636,7 +636,7 @@ get_pairing_statedir (void) return fname; fname = make_filename (gnupg_homedir (), GNUPG_CACHE_DIR, NULL); - if (stat (fname, &statbuf) && errno == ENOENT) + if (gnupg_stat (fname, &statbuf) && errno == ENOENT) { if (gnupg_mkdir (fname, "-rwx")) { @@ -651,7 +651,7 @@ get_pairing_statedir (void) tmpstr = make_filename (fname, PAIRING_STATE_DIR, NULL); xfree (fname); fname = tmpstr; - if (stat (fname, &statbuf) && errno == ENOENT) + if (gnupg_stat (fname, &statbuf) && errno == ENOENT) { if (gnupg_mkdir (fname, "-rwx")) { diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index b5a1753bf..9997e853f 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -313,7 +313,7 @@ main (int argc, char **argv) { struct stat sb; - if (stat (opt.directory, &sb)) + if (gnupg_stat (opt.directory, &sb)) { err = gpg_error_from_syserror (); log_error ("error accessing directory '%s': %s\n", diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index 32cd46530..0cfe47fba 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -337,7 +337,7 @@ main (int argc, char **argv) { struct stat sb; - if (stat (opt.directory, &sb)) + if (gnupg_stat (opt.directory, &sb)) { err = gpg_error_from_syserror (); log_error ("error accessing directory '%s': %s\n", @@ -1645,7 +1645,7 @@ get_domain_list (strlist_t *r_list) goto leave; } - if (stat (fname, &sb)) + if (gnupg_stat (fname, &sb)) { err = gpg_error_from_syserror (); log_error ("error accessing '%s': %s\n", fname, gpg_strerror (err)); @@ -1723,7 +1723,7 @@ expire_one_domain (const char *top_dirname, const char *domain) log_info ("garbage file '%s' ignored\n", fname); continue; } - if (stat (fname, &sb)) + if (gnupg_stat (fname, &sb)) { err = gpg_error_from_syserror (); log_error ("error accessing '%s': %s\n", fname, gpg_strerror (err)); diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index 0311a465b..d13b1dc7e 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -42,7 +42,7 @@ #include "gpgtar.h" #ifndef HAVE_LSTAT -#define lstat(a,b) stat ((a), (b)) +#define lstat(a,b) gnupg_stat ((a), (b)) #endif diff --git a/tools/wks-util.c b/tools/wks-util.c index 621be7920..7afe6c1aa 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -843,13 +843,13 @@ wks_compute_hu_fname (char **r_fname, const char *addrspec) /* Try to create missing directories below opt.directory. */ fname = make_filename_try (opt.directory, domain, NULL); - if (fname && stat (fname, &sb) + if (fname && gnupg_stat (fname, &sb) && gpg_err_code_from_syserror () == GPG_ERR_ENOENT) if (!gnupg_mkdir (fname, "-rwxr--r--") && opt.verbose) log_info ("directory '%s' created\n", fname); xfree (fname); fname = make_filename_try (opt.directory, domain, "hu", NULL); - if (fname && stat (fname, &sb) + if (fname && gnupg_stat (fname, &sb) && gpg_err_code_from_syserror () == GPG_ERR_ENOENT) if (!gnupg_mkdir (fname, "-rwxr--r--") && opt.verbose) log_info ("directory '%s' created\n", fname);