[pacman-dev] [PATCH 1/3] add _alpm_access() wrapper
This is a wrapper function for access() which logs some debug information and eases handling in case of split directory and filename. Signed-off-by: Florian Pritz <bluewind@xinu.at> --- lib/libalpm/util.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/libalpm/util.h | 1 + 2 files changed, 50 insertions(+), 0 deletions(-) diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index cd7f19c..332f917 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -917,6 +917,55 @@ long _alpm_parsedate(const char *line) return atol(line); } +/** + * Wrapper around access() which takes a dir and file argument + * separately and generates an appropriate error message. + * If dir is NULL file will be treated as the whole path. + * @param handle an alpm handle + * @param dir directory path ending with and slash + * @param file filename + * @param amode access mode as describe in access() + * @return int value returned by access() + */ + +int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode) +{ + char *check_path = NULL; + size_t len = 0; + int ret = 0; + + if (dir == NULL) { + len = strlen(file) + 1; + CALLOC(check_path, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + snprintf(check_path, len, "%s", file); + } else { + len = strlen(dir) + strlen(file) + 1; + CALLOC(check_path, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + snprintf(check_path, len, "%s%s", dir, file); + } + + ret = access(check_path, amode); + + if(ret != 0) { + switch(amode) { + case R_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" is not readable: %s\n"), check_path, strerror(errno)); + break; + case W_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" is not writeable: %s\n"), check_path, strerror(errno)); + break; + case X_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" is not executable: %s\n"), check_path, strerror(errno)); + break; + case F_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" does not exist: %s\n"), check_path, strerror(errno)); + break; + } + } + free(check_path); + return ret; +} + #ifndef HAVE_STRNDUP /* A quick and dirty implementation derived from glibc */ static size_t strnlen(const char *s, size_t max) diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 450dac9..015ed5a 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -115,6 +115,7 @@ unsigned long _alpm_hash_sdbm(const char *str); long _alpm_parsedate(const char *line); int _alpm_raw_cmp(const char *first, const char *second); int _alpm_raw_ncmp(const char *first, const char *second, size_t max); +int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode); #ifndef HAVE_STRSEP char *strsep(char **, const char *); -- 1.7.6
If we can't read the keyring, gpgme will output confusing debug information and fail to verify the signature, so we should log some debug information. Signed-off-by: Florian Pritz <bluewind@xinu.at> --- lib/libalpm/signing.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index cfa9a02..b08416f 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -118,6 +118,12 @@ static int init_gpgme(alpm_handle_t *handle) sigdir = alpm_option_get_gpgdir(handle); + if (_alpm_access(handle, sigdir, "pubring.gpg", R_OK) + || _alpm_access(handle, sigdir, "trustdb.gpg", R_OK)) { + handle->pm_errno = ALPM_ERR_NOT_A_FILE; + _alpm_log(handle, ALPM_LOG_DEBUG, "Signature verification will fail!\n"); + } + /* calling gpgme_check_version() returns the current version and runs * some internal library setup code */ version = gpgme_check_version(NULL); -- 1.7.6
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- lib/libalpm/remove.c | 2 +- lib/libalpm/signing.c | 4 ++-- lib/libalpm/trans.c | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 9b8517c..03aaeca 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -205,7 +205,7 @@ static int can_remove_file(alpm_handle_t *handle, const alpm_file_t *file, } /* If we fail write permissions due to a read-only filesystem, abort. * Assume all other possible failures are covered somewhere else */ - if(access(filepath, W_OK) == -1) { + if(_alpm_access(handle, NULL, filepath, W_OK) == -1) { if(errno != EACCES && errno != ETXTBSY && access(filepath, F_OK) == 0) { /* only return failure if the file ACTUALLY exists and we can't write to * it - ignore "chmod -w" simple permission failures */ diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index b08416f..26226dc 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -225,7 +225,7 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, unsigned char *decoded_sigdata = NULL; FILE *file = NULL, *sigfile = NULL; - if(!path || access(path, R_OK) != 0) { + if(!path || _alpm_access(handle, NULL, path, R_OK) != 0) { RET_ERR(handle, ALPM_ERR_NOT_A_FILE, -1); } @@ -239,7 +239,7 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, CALLOC(sigpath, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); snprintf(sigpath, len, "%s.sig", path); - if(!access(sigpath, R_OK) == 0) { + if(!_alpm_access(handle, NULL, sigpath, R_OK) == 0) { /* sigcount is 0 */ } } diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 6cea9b7..1bab830 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -288,8 +288,7 @@ int _alpm_runscriptlet(alpm_handle_t *handle, const char *installfn, int clean_tmpdir = 0; int retval = 0; - if(access(installfn, R_OK)) { - /* not found */ + if(_alpm_access(handle, NULL, installfn, R_OK) != 0) { _alpm_log(handle, ALPM_LOG_DEBUG, "scriptlet '%s' not found\n", installfn); return 0; } -- 1.7.6
This is a wrapper function for access() which logs some debug information and eases handling in case of split directory and filename.
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- lib/libalpm/util.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/libalpm/util.h | 1 + 2 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index cd7f19c..332f917 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -917,6 +917,55 @@ long _alpm_parsedate(const char *line) return atol(line); }
+/** + * Wrapper around access() which takes a dir and file argument + * separately and generates an appropriate error message. + * If dir is NULL file will be treated as the whole path. + * @param handle an alpm handle + * @param dir directory path ending with and slash + * @param file filename + * @param amode access mode as describe in access() "described" + * @return int value returned by access() + */ + +int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode) +{ + char *check_path = NULL; + size_t len = 0; + int ret = 0; + + if (dir == NULL) { + len = strlen(file) + 1; + CALLOC(check_path, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + snprintf(check_path, len, "%s", file); This adds a bit of unnecessry string copying (and could use STRDUP() instead). However, I'd suggest simply dropping the whole first part of
On Wed, Jul 6, 2011 at 12:34 PM, Florian Pritz <bluewind@xinu.at> wrote: this block and doing something like this: if(dir) { char *check_path; (no need at all to set it to null, you are allocing memory right away) /* next block */; ret = access(check_path, amode); free(check_path); } else { dir = ""; ret = access(file, amode); } + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" is not readable: %s\n"), check_path, strerror(errno)); can then become + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s%s\" is not readable: %s\n"), dir, file, strerror(errno));
+ } else { + len = strlen(dir) + strlen(file) + 1; + CALLOC(check_path, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + snprintf(check_path, len, "%s%s", dir, file); + } + + ret = access(check_path, amode); + + if(ret != 0) { + switch(amode) { + case R_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" is not readable: %s\n"), check_path, strerror(errno)); + break; + case W_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" is not writeable: %s\n"), check_path, strerror(errno)); writable? + break; + case X_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" is not executable: %s\n"), check_path, strerror(errno)); + break; + case F_OK: + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s\" does not exist: %s\n"), check_path, strerror(errno)); + break; + } A switch looks good, but it prevents calls such as access(file, R_OK | X_OK) which is valid. Do we care? You could just do four consecutive if(amode & R_OK) { log() } statements. (Except apparently F_OK is defined to 0, so the F_OK check needs to be equality, see /usr/include/unistd.h).
+ } + free(check_path); + return ret; +} + #ifndef HAVE_STRNDUP /* A quick and dirty implementation derived from glibc */ static size_t strnlen(const char *s, size_t max) diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 450dac9..015ed5a 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -115,6 +115,7 @@ unsigned long _alpm_hash_sdbm(const char *str); long _alpm_parsedate(const char *line); int _alpm_raw_cmp(const char *first, const char *second); int _alpm_raw_ncmp(const char *first, const char *second, size_t max); +int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode);
#ifndef HAVE_STRSEP char *strsep(char **, const char *); -- 1.7.6
This is a wrapper function for access() which logs some debug information and eases handling in case of split directory and filename. Signed-off-by: Florian Pritz <bluewind@xinu.at> --- lib/libalpm/util.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ lib/libalpm/util.h | 1 + 2 files changed, 48 insertions(+), 0 deletions(-) diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index cd7f19c..a69a137 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -917,6 +917,53 @@ long _alpm_parsedate(const char *line) return atol(line); } +/** + * Wrapper around access() which takes a dir and file argument + * separately and generates an appropriate error message. + * If dir is NULL file will be treated as the whole path. + * @param handle an alpm handle + * @param dir directory path ending with and slash + * @param file filename + * @param amode access mode as described in access() + * @return int value returned by access() + */ + +int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode) +{ + size_t len = 0; + int ret = 0; + + if (dir) { + char *check_path; + + len = strlen(dir) + strlen(file) + 1; + CALLOC(check_path, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + snprintf(check_path, len, "%s%s", dir, file); + + ret = access(check_path, amode); + free(check_path); + } else { + dir = ""; + ret = access(file, amode); + } + + if(ret != 0) { + if (amode & R_OK) { + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s%s\" is not readable: %s\n"), dir, file, strerror(errno)); + } + if (amode & W_OK) { + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s%s\" is not writable: %s\n"), dir, file, strerror(errno)); + } + if (amode & X_OK) { + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s%s\" is not executable: %s\n"), dir, file, strerror(errno)); + } + if (amode == F_OK) { + _alpm_log(handle, ALPM_LOG_DEBUG, _("\"%s%s\" does not exist: %s\n"), dir, file, strerror(errno)); + } + } + return ret; +} + #ifndef HAVE_STRNDUP /* A quick and dirty implementation derived from glibc */ static size_t strnlen(const char *s, size_t max) diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 450dac9..015ed5a 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -115,6 +115,7 @@ unsigned long _alpm_hash_sdbm(const char *str); long _alpm_parsedate(const char *line); int _alpm_raw_cmp(const char *first, const char *second); int _alpm_raw_ncmp(const char *first, const char *second, size_t max); +int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode); #ifndef HAVE_STRSEP char *strsep(char **, const char *); -- 1.7.6
participants (2)
-
Dan McGee
-
Florian Pritz