diff options
Diffstat (limited to 'lib/libalpm/util.c')
-rw-r--r-- | lib/libalpm/util.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index be465afa..75f6042d 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -242,7 +242,8 @@ char *_alpm_strreplace(const char *str, const char *needle, const char *replace) int _alpm_lckmk() { int fd; - char *dir, *ptr; + pid_t pid; + char *dir, *ptr, *spid = NULL; const char *file = alpm_option_get_lockfile(); /* create the dir of the lockfile first */ @@ -256,7 +257,17 @@ int _alpm_lckmk() while((fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0000)) == -1 && errno == EINTR); - return(fd > 0 ? fd : -1); + if(fd > 0) { + pid = getpid(); + size_t len = snprintf(spid, 0, "%ld\n", (long)pid) + 1; + spid = malloc(len); + snprintf(spid, len, "%ld\n", (long)pid); + while(write(fd, (void *)spid, len) == -1 && errno == EINTR); + fsync(fd); + free(spid); + return(fd); + } + return(-1); } /* Remove a lock file */ @@ -277,19 +288,21 @@ int _alpm_lckrm() * @param archive the archive to unpack * @param prefix where to extract the files * @param fn a file within the archive to unpack or NULL for all + * @return 0 on success, 1 on failure */ int _alpm_unpack(const char *archive, const char *prefix, const char *fn) { - int ret = 1; + int ret = 0; mode_t oldmask; struct archive *_archive; struct archive_entry *entry; - char expath[PATH_MAX]; + char cwd[PATH_MAX]; + int restore_cwd = 0; ALPM_LOG_FUNC; if((_archive = archive_read_new()) == NULL) - RET_ERR(PM_ERR_LIBARCHIVE, -1); + RET_ERR(PM_ERR_LIBARCHIVE, 1); archive_read_support_compression_all(_archive); archive_read_support_format_all(_archive); @@ -298,10 +311,25 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn) ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { _alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), archive, archive_error_string(_archive)); - RET_ERR(PM_ERR_PKG_OPEN, -1); + RET_ERR(PM_ERR_PKG_OPEN, 1); } oldmask = umask(0022); + + /* save the cwd so we can restore it later */ + if(getcwd(cwd, PATH_MAX) == NULL) { + _alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); + } else { + restore_cwd = 1; + } + + /* just in case our cwd was removed in the upgrade operation */ + if(chdir(prefix) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), prefix, strerror(errno)); + ret = 1; + goto cleanup; + } + while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) { const struct stat *st; const char *entryname; /* the name of the file in the archive */ @@ -326,10 +354,6 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn) } /* Extract the archive entry. */ - ret = 0; - snprintf(expath, PATH_MAX, "%s/%s", prefix, entryname); - archive_entry_set_pathname(entry, expath); - int readret = archive_read_extract(_archive, entry, 0); if(readret == ARCHIVE_WARN) { /* operation succeeded but a non-critical error was encountered */ @@ -350,6 +374,9 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn) cleanup: umask(oldmask); archive_read_finish(_archive); + if(restore_cwd) { + chdir(cwd); + } return(ret); } @@ -539,7 +566,7 @@ int _alpm_lstat(const char *path, struct stat *buf) * @return the checksum on success, NULL on error * @addtogroup alpm_misc */ -char SYMEXPORT *alpm_get_md5sum(const char *filename) +char SYMEXPORT *alpm_compute_md5sum(const char *filename) { unsigned char output[16]; char *md5sum; @@ -573,7 +600,7 @@ int _alpm_test_md5sum(const char *filepath, const char *md5sum) char *md5sum2; int ret; - md5sum2 = alpm_get_md5sum(filepath); + md5sum2 = alpm_compute_md5sum(filepath); if(md5sum == NULL || md5sum2 == NULL) { ret = -1; |