diff options
-rwxr-xr-x | autoclean.sh | 13 | ||||
-rw-r--r-- | lib/libalpm/alpm.h | 1 | ||||
-rw-r--r-- | lib/libalpm/backup.c | 6 | ||||
-rw-r--r-- | lib/libalpm/backup.h | 2 | ||||
-rw-r--r-- | lib/libalpm/be_local.c | 3 | ||||
-rw-r--r-- | lib/libalpm/be_sync.c | 128 | ||||
-rw-r--r-- | lib/libalpm/conflict.c | 35 | ||||
-rw-r--r-- | lib/libalpm/db.c | 17 | ||||
-rw-r--r-- | lib/libalpm/diskspace.c | 8 | ||||
-rw-r--r-- | lib/libalpm/dload.c | 6 | ||||
-rw-r--r-- | lib/libalpm/package.c | 6 | ||||
-rw-r--r-- | lib/libalpm/remove.c | 8 | ||||
-rw-r--r-- | lib/libalpm/util.c | 82 | ||||
-rw-r--r-- | lib/libalpm/util.h | 3 | ||||
-rw-r--r-- | scripts/makepkg.sh.in | 64 | ||||
-rw-r--r-- | scripts/repo-add.sh.in | 10 | ||||
-rw-r--r-- | src/pacman/callback.c | 10 | ||||
-rw-r--r-- | src/pacman/sync.c | 4 | ||||
-rw-r--r-- | src/pacman/upgrade.c | 1 | ||||
-rw-r--r-- | src/pacman/util.c | 2 | ||||
-rw-r--r-- | src/util/pactree.c | 96 | ||||
-rw-r--r-- | src/util/testpkg.c | 2 | ||||
-rw-r--r-- | test/pacman/tests/fileconflict008.py | 21 | ||||
-rw-r--r-- | valgrind.supp | 22 |
24 files changed, 355 insertions, 195 deletions
diff --git a/autoclean.sh b/autoclean.sh index 71284ad2..8f45d561 100755 --- a/autoclean.sh +++ b/autoclean.sh @@ -26,12 +26,7 @@ rm -f test/pacman/*.pyc rm -f doc/html/*.html rm -f doc/man3/*.3 -rm -f po/{Makefile.in,Makefile} -rm -f po/POTFILES -rm -f po/stamp-po -rm -f po/*.gmo - -rm -f lib/libalpm/po/{Makefile.in,Makefile} -rm -f lib/libalpm/po/POTFILES -rm -f lib/libalpm/po/stamp-po -rm -f lib/libalpm/po/*.gmo +rm -f {lib/libalpm,scripts,src/pacman}/po/{Makefile.in,Makefile} +rm -f {lib/libalpm,scripts,src/pacman}/po/POTFILES +rm -f {lib/libalpm,scripts,src/pacman}/po/stamp-po +rm -f {lib/libalpm,scripts,src/pacman}/po/*.gmo diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 579b45f2..ac352131 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -695,7 +695,6 @@ alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg); int alpm_pkg_check_pgp_signature(pmpkg_t *pkg); int alpm_db_check_pgp_signature(pmdb_t *db); -int alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify); /* * Groups diff --git a/lib/libalpm/backup.c b/lib/libalpm/backup.c index 20fb8a80..dc0c5674 100644 --- a/lib/libalpm/backup.c +++ b/lib/libalpm/backup.c @@ -58,16 +58,16 @@ int _alpm_split_backup(const char *string, pmbackup_t **backup) /* Look for a filename in a pmpkg_t.backup list. If we find it, * then we return the full backup entry. */ -pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup) +pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup_list) { const alpm_list_t *lp; - if(file == NULL || backup == NULL) { + if(file == NULL || backup_list == NULL) { return NULL; } /* run through the backup list and parse out the hash for our file */ - for(lp = backup; lp; lp = lp->next) { + for(lp = backup_list; lp; lp = lp->next) { pmbackup_t *backup = lp->data; if(strcmp(file, backup->name) == 0) { diff --git a/lib/libalpm/backup.h b/lib/libalpm/backup.h index 2f632d4a..be8de97a 100644 --- a/lib/libalpm/backup.h +++ b/lib/libalpm/backup.h @@ -24,7 +24,7 @@ #include "alpm.h" int _alpm_split_backup(const char *string, pmbackup_t **backup); -pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup); +pmbackup_t *_alpm_needbackup(const char *file, const alpm_list_t *backup_list); void _alpm_backup_free(pmbackup_t *backup); pmbackup_t *_alpm_backup_dup(const pmbackup_t *backup); diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 96f04c51..50066883 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -439,7 +439,8 @@ static int local_db_populate(pmdb_t *db) RET_ERR(db->handle, PM_ERR_MEMORY, -1); } /* split the db entry name */ - if(_alpm_splitname(name, pkg) != 0) { + if(_alpm_splitname(name, &(pkg->name), &(pkg->version), + &(pkg->name_hash)) != 0) { _alpm_log(db->handle, PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), name); _alpm_pkg_free(pkg); diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index f51ab97a..2bf37dab 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -245,7 +245,61 @@ cleanup: /* Forward decl so I don't reorganize the whole file right now */ static int sync_db_read(pmdb_t *db, struct archive *archive, - struct archive_entry *entry, pmpkg_t *likely_pkg); + struct archive_entry *entry, pmpkg_t **likely_pkg); + +static pmpkg_t *load_pkg_for_entry(pmdb_t *db, const char *entryname, + const char **entry_filename, pmpkg_t *likely_pkg) +{ + char *pkgname = NULL, *pkgver = NULL; + unsigned long pkgname_hash; + pmpkg_t *pkg; + + /* get package and db file names */ + if(entry_filename) { + char *fname = strrchr(entryname, '/'); + if(fname) { + *entry_filename = fname + 1; + } else { + *entry_filename = NULL; + } + } + if(_alpm_splitname(entryname, &pkgname, &pkgver, &pkgname_hash) != 0) { + _alpm_log(db->handle, PM_LOG_ERROR, + _("invalid name for database entry '%s'\n"), entryname); + return NULL; + } + + if(likely_pkg && strcmp(likely_pkg->name, pkgname) == 0) { + pkg = likely_pkg; + } else { + pkg = _alpm_pkghash_find(db->pkgcache, pkgname); + } + if(pkg == NULL) { + pkg = _alpm_pkg_new(); + if(pkg == NULL) { + RET_ERR(db->handle, PM_ERR_MEMORY, NULL); + } + + pkg->name = pkgname; + pkg->version = pkgver; + pkg->name_hash = pkgname_hash; + + pkg->origin = PKG_FROM_SYNCDB; + pkg->origin_data.db = db; + pkg->ops = &default_pkg_ops; + pkg->handle = db->handle; + + /* add to the collection */ + _alpm_log(db->handle, PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", + pkg->name, db->treename); + db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); + } else { + free(pkgname); + free(pkgver); + } + + return pkg; +} /* * This is the data table used to generate the estimating function below. @@ -355,45 +409,10 @@ static int sync_db_populate(pmdb_t *db) st = archive_entry_stat(entry); if(S_ISDIR(st->st_mode)) { - const char *name; - - pkg = _alpm_pkg_new(); - if(pkg == NULL) { - archive_read_finish(archive); - RET_ERR(db->handle, PM_ERR_MEMORY, -1); - } - - name = archive_entry_pathname(entry); - - if(_alpm_splitname(name, pkg) != 0) { - _alpm_log(db->handle, PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), - name); - _alpm_pkg_free(pkg); - pkg = NULL; - continue; - } - - /* duplicated database entries are not allowed */ - if(_alpm_pkghash_find(db->pkgcache, pkg->name)) { - _alpm_log(db->handle, PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); - _alpm_pkg_free(pkg); - pkg = NULL; - continue; - } - - pkg->origin = PKG_FROM_SYNCDB; - pkg->origin_data.db = db; - pkg->ops = &default_pkg_ops; - pkg->handle = db->handle; - - /* add to the collection */ - _alpm_log(db->handle, PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", - pkg->name, db->treename); - db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); - count++; + continue; } else { /* we have desc, depends or deltas - parse it */ - if(sync_db_read(db, archive, entry, pkg) != 0) { + if(sync_db_read(db, archive, entry, &pkg) != 0) { _alpm_log(db->handle, PM_LOG_ERROR, _("could not parse package description file '%s' from db '%s'\n"), archive_entry_pathname(entry), db->treename); @@ -402,6 +421,8 @@ static int sync_db_populate(pmdb_t *db) } } + count = alpm_list_count(db->pkgcache->list); + if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } @@ -431,10 +452,9 @@ static int sync_db_populate(pmdb_t *db) } while(1) /* note the while(1) and not (0) */ static int sync_db_read(pmdb_t *db, struct archive *archive, - struct archive_entry *entry, pmpkg_t *likely_pkg) + struct archive_entry *entry, pmpkg_t **likely_pkg) { const char *entryname, *filename; - char *pkgname, *p, *q; pmpkg_t *pkg; struct archive_read_buffer buf; @@ -452,27 +472,12 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, /* 512K for a line length seems reasonable */ buf.max_line_size = 512 * 1024; - /* get package and db file names */ - STRDUP(pkgname, entryname, RET_ERR(db->handle, PM_ERR_MEMORY, -1)); - p = pkgname + strlen(pkgname); - for(q = --p; *q && *q != '/'; q--); - filename = q + 1; - for(p = --q; *p && *p != '-'; p--); - for(q = --p; *q && *q != '-'; q--); - *q = '\0'; - - /* package is already in db due to parsing of directory name */ - if(likely_pkg && strcmp(likely_pkg->name, pkgname) == 0) { - pkg = likely_pkg; - } else { - if(db->pkgcache == NULL) { - RET_ERR(db->handle, PM_ERR_MEMORY, -1); - } - pkg = _alpm_pkghash_find(db->pkgcache, pkgname); - } + pkg = load_pkg_for_entry(db, entryname, &filename, *likely_pkg); + if(pkg == NULL) { - _alpm_log(db->handle, PM_LOG_DEBUG, "package %s not found in %s sync database", - pkgname, db->treename); + _alpm_log(db->handle, PM_LOG_DEBUG, + "entry %s could not be loaded into %s sync database", + entryname, db->treename); return -1; } @@ -559,6 +564,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, if(ret != ARCHIVE_EOF) { goto error; } + *likely_pkg = pkg; } else if(strcmp(filename, "files") == 0) { /* currently do nothing with this file */ } else { @@ -566,12 +572,10 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, _alpm_log(db->handle, PM_LOG_DEBUG, "unknown database file: %s\n", filename); } - FREE(pkgname); return 0; error: _alpm_log(db->handle, PM_LOG_DEBUG, "error parsing database file: %s\n", filename); - FREE(pkgname); return -1; } diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 39f42bfe..94d82dd9 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -275,10 +275,10 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, return ret; } -/* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type (either - * PM_FILECONFLICT_TARGET or PM_FILECONFLICT_FILESYSTEM), a file string, and either - * two package names or one package name and NULL. This is a wrapper for former - * functionality that was done inline. +/* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type + * (either PM_FILECONFLICT_TARGET or PM_FILECONFLICT_FILESYSTEM), a file + * string, and either two package names or one package name and NULL. This is + * a wrapper for former functionality that was done inline. */ static alpm_list_t *add_fileconflict(pmhandle_t *handle, alpm_list_t *conflicts, pmfileconflicttype_t type, const char *filestr, @@ -440,7 +440,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, for(j = tmpfiles; j; j = j->next) { struct stat lsbuf; - const char *filestr = j->data; + const char *filestr = j->data, *relative_path; + /* have we acted on this conflict? */ + int resolved_conflict = 0; snprintf(path, PATH_MAX, "%s%s", handle->root, filestr); @@ -449,7 +451,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, continue; } - if(path[strlen(path)-1] == '/') { + if(path[strlen(path) - 1] == '/') { struct stat sbuf; if(S_ISDIR(lsbuf.st_mode)) { _alpm_log(handle, PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path); @@ -461,17 +463,22 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, "%s is a symlink to a dir, hopefully not a conflict\n", path); continue; } + /* if we made it to here, we want all subsequent path comparisons to + * not include the trailing slash. This allows things like file -> + * directory replacements. */ + path[strlen(path) - 1] = '\0'; } - _alpm_log(handle, PM_LOG_DEBUG, "checking possible conflict: %s\n", path); - int resolved_conflict = 0; /* have we acted on this conflict? */ + _alpm_log(handle, PM_LOG_DEBUG, "checking possible conflict: %s\n", path); + relative_path = path + strlen(handle->root); /* Check remove list (will we remove the conflicting local file?) */ for(k = remove; k && !resolved_conflict; k = k->next) { pmpkg_t *rempkg = k->data; - if(rempkg && alpm_list_find_str(alpm_pkg_get_files(rempkg), filestr)) { + if(alpm_list_find_str(alpm_pkg_get_files(rempkg), relative_path)) { _alpm_log(handle, PM_LOG_DEBUG, - "local file will be removed, not a conflict: %s\n", filestr); + "local file will be removed, not a conflict: %s\n", + relative_path); resolved_conflict = 1; } } @@ -492,7 +499,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, handle->trans->skip_remove = alpm_list_add(handle->trans->skip_remove, strdup(filestr)); _alpm_log(handle, PM_LOG_DEBUG, - "file changed packages, adding to remove skiplist: %s\n", filestr); + "file changed packages, adding to remove skiplist: %s\n", + filestr); resolved_conflict = 1; } } @@ -512,12 +520,13 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, if(!resolved_conflict && dbpkg) { char *rpath = calloc(PATH_MAX, sizeof(char)); + const char *relative_rpath; if(!realpath(path, rpath)) { free(rpath); continue; } - char *filestr = rpath + strlen(handle->root); - if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), filestr)) { + relative_rpath = rpath + strlen(handle->root); + if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), relative_rpath)) { resolved_conflict = 1; } free(rpath); diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index b20421a3..9f37f80b 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -211,23 +211,6 @@ int SYMEXPORT alpm_db_remove_server(pmdb_t *db, const char *url) return 1; } -/** Set the verify gpg signature option for a database. - * @param db database pointer - * @param verify enum pgp_verify_t - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ -int SYMEXPORT alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify) -{ - /* Sanity checks */ - ASSERT(db != NULL, return -1); - db->handle->pm_errno = 0; - - db->pgp_verify = verify; - _alpm_log(db->handle, PM_LOG_DEBUG, "adding VerifySig option to database '%s': %d\n", - db->treename, verify); - - return 0; -} /** Get the name of a package database. */ const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db) diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 079e683e..51aa47f2 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -262,7 +262,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) alpm_list_t *mount_points, *i; alpm_mountpoint_t *root_mp; size_t replaces = 0, current = 0, numtargs; - int abort = 0; + int error = 0; alpm_list_t *targ; pmtrans_t *trans = handle->trans; @@ -323,7 +323,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) if(data->used && data->read_only) { _alpm_log(handle, PM_LOG_ERROR, _("Partition %s is mounted read only\n"), data->mount_dir); - abort = 1; + error = 1; } else if(data->used & USED_INSTALL) { /* cushion is roughly min(5% capacity, 20MiB) */ long fivepc = ((long)data->fsp.f_blocks / 20) + 1; @@ -338,7 +338,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) _alpm_log(handle, PM_LOG_ERROR, _("Partition %s too full: %ld blocks needed, %ld blocks free\n"), data->mount_dir, data->max_blocks_needed + cushion, (unsigned long)data->fsp.f_bfree); - abort = 1; + error = 1; } } } @@ -349,7 +349,7 @@ int _alpm_check_diskspace(pmhandle_t *handle) } FREELIST(mount_points); - if(abort) { + if(error) { RET_ERR(handle, PM_ERR_DISK_SPACE, -1); } diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 33fb1cb8..c7903ff0 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -137,12 +137,12 @@ static int curl_gethost(const char *url, char *buffer) return 0; } -static int utimes_long(const char *path, long time) +static int utimes_long(const char *path, long seconds) { - if(time != -1) { + if(seconds != -1) { struct timeval tv[2]; memset(&tv, 0, sizeof(tv)); - tv[0].tv_sec = tv[1].tv_sec = time; + tv[0].tv_sec = tv[1].tv_sec = seconds; return utimes(path, tv); } return 0; diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index e99d5bd4..75ac94c7 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -379,9 +379,9 @@ static void find_requiredby(pmpkg_t *pkg, pmdb_t *db, alpm_list_t **reqs) for(i = _alpm_db_get_pkgcache(db); i; i = i->next) { pmpkg_t *cachepkg = i->data; - alpm_list_t *i; - for(i = alpm_pkg_get_depends(cachepkg); i; i = i->next) { - if(_alpm_depcmp(pkg, i->data)) { + alpm_list_t *j; + for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) { + if(_alpm_depcmp(pkg, j->data)) { const char *cachepkgname = cachepkg->name; if(alpm_list_find_str(*reqs, cachepkgname) == NULL) { *reqs = alpm_list_add(*reqs, strdup(cachepkgname)); diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index b6a4c715..134c6662 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -287,7 +287,7 @@ int _alpm_upgraderemove_package(pmhandle_t *handle, { alpm_list_t *skip_remove, *b; alpm_list_t *newfiles, *lp; - size_t filenum; + size_t filenum = 0; alpm_list_t *files = alpm_pkg_get_files(oldpkg); const char *pkgname = alpm_pkg_get_name(oldpkg); @@ -323,9 +323,9 @@ int _alpm_upgraderemove_package(pmhandle_t *handle, "not removing package '%s', can't remove all files\n", pkgname); RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1); } + filenum++; } - filenum = alpm_list_count(files); _alpm_log(handle, PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum); /* iterate through the list backwards, unlinking files */ @@ -391,7 +391,7 @@ int _alpm_remove_packages(pmhandle_t *handle) if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) { alpm_list_t *files = alpm_pkg_get_files(info); alpm_list_t *newfiles; - size_t filenum; + size_t filenum = 0; for(lp = files; lp; lp = lp->next) { if(!can_remove_file(handle, lp->data, NULL)) { @@ -399,9 +399,9 @@ int _alpm_remove_packages(pmhandle_t *handle) pkgname); RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1); } + filenum++; } - filenum = alpm_list_count(files); _alpm_log(handle, PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum); /* init progress bar */ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 4976703a..6fbe08ae 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -299,13 +299,13 @@ int _alpm_unpack(pmhandle_t *handle, const char *archive, const char *prefix, /* If specific files were requested, skip entries that don't match. */ if(list) { - char *prefix = strdup(entryname); + char *entry_prefix = strdup(entryname); char *p = strstr(prefix,"/"); if(p) { *(p+1) = '\0'; } - char *found = alpm_list_find_str(list, prefix); - free(prefix); + char *found = alpm_list_find_str(list, entry_prefix); + free(entry_prefix); if(!found) { if(archive_read_data_skip(_archive) != ARCHIVE_OK) { ret = 1; @@ -487,22 +487,22 @@ int _alpm_run_chroot(pmhandle_t *handle, const char *path, char *const argv[]) } else { /* this code runs for the parent only (wait on the child) */ int status; - FILE *pipe; + FILE *pipe_file; close(pipefd[1]); - pipe = fdopen(pipefd[0], "r"); - if(pipe == NULL) { + pipe_file = fdopen(pipefd[0], "r"); + if(pipe_file == NULL) { close(pipefd[0]); retval = 1; } else { - while(!feof(pipe)) { + while(!feof(pipe_file)) { char line[PATH_MAX]; - if(fgets(line, PATH_MAX, pipe) == NULL) + if(fgets(line, PATH_MAX, pipe_file) == NULL) break; alpm_logaction(handle, "%s", line); EVENT(handle->trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); } - fclose(pipe); + fclose(pipe_file); } while(waitpid(pid, &status, 0) == -1) { @@ -760,9 +760,8 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) &b->block_size, &offset); b->block_offset = b->block; - /* error or end of archive with no data read, cleanup */ - if(b->ret < ARCHIVE_OK || - (b->block_size == 0 && b->ret == ARCHIVE_EOF)) { + /* error, cleanup */ + if(b->ret < ARCHIVE_OK) { goto cleanup; } } @@ -779,19 +778,20 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) /* allocate our buffer, or ensure our existing one is big enough */ if(!b->line) { /* set the initial buffer to the read block_size */ - CALLOC(b->line, b->block_size + 1, sizeof(char), return ENOMEM); + CALLOC(b->line, b->block_size + 1, sizeof(char), b->ret = -ENOMEM; goto cleanup); b->line_size = b->block_size + 1; b->line_offset = b->line; } else { size_t needed = (size_t)((b->line_offset - b->line) + (i - b->block_offset) + 1); if(needed > b->max_line_size) { - return ERANGE; + b->ret = -ERANGE; + goto cleanup; } if(needed > b->line_size) { /* need to realloc + copy data to fit total length */ char *new; - CALLOC(new, needed, sizeof(char), return ENOMEM); + CALLOC(new, needed, sizeof(char), b->ret = -ENOMEM; goto cleanup); memcpy(new, b->line, b->line_size); b->line_size = needed; b->line_offset = new + (b->line_offset - b->line); @@ -813,6 +813,12 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) memcpy(b->line_offset, b->block_offset, len); b->line_offset += len; b->block_offset = i; + /* there was no new data, return what is left; saved ARCHIVE_EOF will be + * returned on next call */ + if(len == 0) { + b->line_offset[0] = '\0'; + return ARCHIVE_OK; + } } } @@ -825,46 +831,54 @@ cleanup: } } -int _alpm_splitname(const char *target, pmpkg_t *pkg) +int _alpm_splitname(const char *target, char **name, char **version, + unsigned long *name_hash) { /* the format of a db entry is as follows: * package-version-rel/ + * package-version-rel/desc (we ignore the filename portion) * package name can contain hyphens, so parse from the back- go back * two hyphens and we have split the version from the name. */ - const char *version, *end; + const char *pkgver, *end; - if(target == NULL || pkg == NULL) { + if(target == NULL) { return -1; } - end = target + strlen(target); - /* remove any trailing '/' */ - while(*(end - 1) == '/') { - --end; + /* remove anything trailing a '/' */ + end = strchr(target, '/'); + if(!end) { + end = target + strlen(target); } /* do the magic parsing- find the beginning of the version string * by doing two iterations of same loop to lop off two hyphens */ - for(version = end - 1; *version && *version != '-'; version--); - for(version = version - 1; *version && *version != '-'; version--); - if(*version != '-' || version == target) { + for(pkgver = end - 1; *pkgver && *pkgver != '-'; pkgver--); + for(pkgver = pkgver - 1; *pkgver && *pkgver != '-'; pkgver--); + if(*pkgver != '-' || pkgver == target) { return -1; } /* copy into fields and return */ - if(pkg->version) { - FREE(pkg->version); + if(version) { + if(*version) { + FREE(*version); + } + /* version actually points to the dash, so need to increment 1 and account + * for potential end character */ + STRNDUP(*version, pkgver + 1, end - pkgver - 1, return -1); } - /* version actually points to the dash, so need to increment 1 and account - * for potential end character */ - STRNDUP(pkg->version, version + 1, end - version - 1, return -1); - if(pkg->name) { - FREE(pkg->name); + if(name) { + if(*name) { + FREE(*name); + } + STRNDUP(*name, target, pkgver - target, return -1); + if(name_hash) { + *name_hash = _alpm_hash_sdbm(*name); + } } - STRNDUP(pkg->name, target, version - target, return -1); - pkg->name_hash = _alpm_hash_sdbm(pkg->name); return 0; } diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 778e20fe..c68b07ba 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -109,7 +109,8 @@ const char *_alpm_filecache_setup(pmhandle_t *handle); int _alpm_lstat(const char *path, struct stat *buf); int _alpm_test_md5sum(const char *filepath, const char *md5sum); int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b); -int _alpm_splitname(const char *target, pmpkg_t *pkg); +int _alpm_splitname(const char *target, char **name, char **version, + unsigned long *name_hash); unsigned long _alpm_hash_sdbm(const char *str); long _alpm_parsedate(const char *line); diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index d1cf175e..391e1752 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -518,7 +518,8 @@ download_sources() { local file=$(get_filepath "$netfile" || true) if [[ -n "$file" ]]; then msg2 "$(gettext "Found %s")" "${file##*/}" - ln -sf "$file" "$srcdir/" + rm -f "$srcdir/$file" + ln -s "$file" "$srcdir/" continue fi @@ -878,8 +879,8 @@ tidy_install() { # update symlinks to this manpage find ${MAN_DIRS[@]} -lname "$file" 2>/dev/null | while read link ; do - rm -f "$link" - ln -sf "${file}.gz" "${link}.gz" + rm -f "$link" "${link}.gz" + ln -s "${file}.gz" "${link}.gz" done # check file still exists (potentially already compressed due to hardlink) @@ -1187,9 +1188,13 @@ create_package() { create_signature "$pkg_file" if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then - ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}" + rm -f "${pkg_file/$PKGDEST/$startdir}" + ln -s "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}" ret=$? - [[ -f $pkg_file.sig ]] && ln -sf "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig" + if [[ -f $pkg_file.sig ]]; then + rm -f "${pkg_file/$PKGDEST/$startdir}.sig" + ln -s "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig" + fi fi if (( ret )); then @@ -1276,7 +1281,8 @@ create_srcpackage() { fi if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then - ln -sf "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}" + rm -f "${pkg_file/$SRCPKGDEST/$startdir}" + ln -s "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}" ret=$? fi @@ -1449,6 +1455,13 @@ check_software() { # check for needed software local ret=0 + # check for sudo if we will need it during makepkg execution + if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then + if ! type -p sudo >/dev/null; then + warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")" + fi + fi + # fakeroot - building as non-root user if [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then if ! type -p fakeroot >/dev/null; then @@ -1531,30 +1544,48 @@ devel_check() { # This will only be used on the first call to makepkg; subsequent # calls to makepkg via fakeroot will explicitly pass the version # number to avoid having to determine the version number twice. - # Also do a brief check to make sure we have the VCS tool available. + # Also do a check to make sure we have the VCS tool available. oldpkgver=$pkgver if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then - type -p darcs >/dev/null || return 0 + if ! type -p darcs >/dev/null; then + warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "darcs" "darcs" + return 0 + fi msg "$(gettext "Determining latest %s revision...")" 'darcs' newpkgver=$(date +%Y%m%d) elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then - type -p cvs >/dev/null || return 0 + if ! type -p cvs >/dev/null; then + warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "cvs" "cvs" + return 0 + fi msg "$(gettext "Determining latest %s revision...")" 'cvs' newpkgver=$(date +%Y%m%d) elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then - type -p git >/dev/null || return 0 + if ! type -p git >/dev/null; then + warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "git "git" + return 0 + fi msg "$(gettext "Determining latest %s revision...")" 'git' newpkgver=$(date +%Y%m%d) elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then - type -p svn >/dev/null || return 0 + if ! type -p svn >/dev/null; then + warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "svn" "svn" + return 0 + fi msg "$(gettext "Determining latest %s revision...")" 'svn' newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p') elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then - type -p bzr >/dev/null || return 0 + if ! type -p bzr >/dev/null; then + warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "bzr" bzr" + return 0 + fi msg "$(gettext "Determining latest %s revision...")" 'bzr' newpkgver=$(bzr revno ${_bzrtrunk}) elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then - type -p hg >/dev/null || return 0 + if ! type -p hg >/dev/null; then + warning "$(gettext "Cannot find the %s binary required to determine latest %s revision.")" "hg" "hg" + return 0 + fi msg "$(gettext "Determining latest %s revision...")" 'hg' if [[ -d ./src/$_hgrepo ]] ; then cd ./src/$_hgrepo @@ -1898,13 +1929,6 @@ else fi fi -# check for sudo if we will need it during makepkg execution -if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then - if ! type -p sudo >/dev/null; then - warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")" - fi -fi - unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides unset md5sums replaces depends conflicts backup source install changelog build unset makedepends optdepends options noextract diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index 1d78c472..81c54b81 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -641,12 +641,14 @@ if (( success )); then [[ -f $tmpdir/$filename.sig ]] && mv "$tmpdir/$filename.sig" "$REPO_DB_FILE.sig" dblink="${REPO_DB_FILE%.tar*}" target=${REPO_DB_FILE##*/} - ln -sf "$target" "$dblink" 2>/dev/null || \ - ln -f "$target" "$dblink" 2>/dev/null || \ + rm -f "$dblink" + ln -s "$target" "$dblink" 2>/dev/null || \ + ln "$target" "$dblink" 2>/dev/null || \ cp "$REPO_DB_FILE" "$dblink" if [[ -f "$target.sig" ]]; then - ln -sf "$target.sig" "$dblink.sig" 2>/dev/null || \ - ln -f "$target.sig" "$dblink.sig" 2>/dev/null || \ + rm -f "$dblink.sig" + ln -s "$target.sig" "$dblink.sig" 2>/dev/null || \ + ln "$target.sig" "$dblink.sig" 2>/dev/null || \ cp "$REPO_DB_FILE.sig" "$dblink.sig" fi else diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 66b14cdd..ffca8bec 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -623,14 +623,14 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) /* if padwid is < 0, we need to trim the string so padwid = 0 */ if(padwid < 0) { int i = filenamelen - 3; - wchar_t *p = wcfname; + wchar_t *wcp = wcfname; /* grab the max number of char columns we can fill */ - while(i > 0 && wcwidth(*p) < i) { - i -= wcwidth(*p); - p++; + while(i > 0 && wcwidth(*wcp) < i) { + i -= wcwidth(*wcp); + wcp++; } /* then add the ellipsis and fill out any extra padding */ - wcscpy(p, L"..."); + wcscpy(wcp, L"..."); padwid = i; } diff --git a/src/pacman/sync.c b/src/pacman/sync.c index f242c827..fa30b8da 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -443,7 +443,6 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets) if(targets) { for(i = targets; i; i = alpm_list_next(i)) { - pmdb_t *db = NULL; int foundpkg = 0; char target[512]; /* TODO is this enough space? */ @@ -452,6 +451,7 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets) strncpy(target, i->data, 512); pkgstr = strchr(target, '/'); if(pkgstr) { + pmdb_t *db = NULL; repo = target; *pkgstr = '\0'; ++pkgstr; @@ -767,7 +767,6 @@ static int sync_trans(alpm_list_t *targets) pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"), alpm_strerror(err)); switch(err) { - alpm_list_t *i; case PM_ERR_PKG_INVALID_ARCH: for(i = data; i; i = alpm_list_next(i)) { char *pkg = alpm_list_getdata(i); @@ -835,7 +834,6 @@ static int sync_trans(alpm_list_t *targets) pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"), alpm_strerror(err)); switch(err) { - alpm_list_t *i; case PM_ERR_FILE_CONFLICTS: for(i = data; i; i = alpm_list_next(i)) { pmfileconflict_t *conflict = alpm_list_getdata(i); diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c index 6587671b..c1f72f6d 100644 --- a/src/pacman/upgrade.c +++ b/src/pacman/upgrade.c @@ -166,7 +166,6 @@ int pacman_upgrade(alpm_list_t *targets) pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"), alpm_strerror(err)); switch(err) { - alpm_list_t *i; case PM_ERR_FILE_CONFLICTS: for(i = data; i; i = alpm_list_next(i)) { pmfileconflict_t *conflict = alpm_list_getdata(i); diff --git a/src/pacman/util.c b/src/pacman/util.c index 77a7e56c..75e67170 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -589,7 +589,7 @@ void list_display(const char *title, const alpm_list_t *list) printf("%s", str); cols += string_length(str); for(i = alpm_list_next(list); i; i = alpm_list_next(i)) { - const char *str = alpm_list_getdata(i); + str = alpm_list_getdata(i); int s = string_length(str); /* wrap only if we have enough usable column space */ if(maxcols > len && cols + s + 2 >= maxcols) { diff --git a/src/util/pactree.c b/src/util/pactree.c index 87bac6d1..5beaa5a7 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -26,6 +26,8 @@ #include <alpm.h> #include <alpm_list.h> +#define LINE_MAX 512 + /* output */ struct graph_style { const char *provides; @@ -85,8 +87,77 @@ int graphviz = 0; int max_depth = -1; int reverse = 0; int unique = 0; +int searchsyncs = 0; const char *dbpath = DBPATH; +static char *strtrim(char *str) +{ + char *pch = str; + + if(str == NULL || *str == '\0') { + /* string is empty, so we're done. */ + return str; + } + + while(isspace((unsigned char)*pch)) { + pch++; + } + if(pch != str) { + memmove(str, pch, (strlen(pch) + 1)); + } + + /* check if there wasn't anything but whitespace in the string. */ + if(*str == '\0') { + return str; + } + + pch = (str + (strlen(str) - 1)); + while(isspace((unsigned char)*pch)) { + pch--; + } + *++pch = '\0'; + + return str; +} + +static int register_syncs(void) { + FILE *fp; + char *ptr, *section = NULL; + char line[LINE_MAX]; + + fp = fopen(CONFFILE, "r"); + if(!fp) { + return 1; + } + + while(fgets(line, LINE_MAX, fp)) { + strtrim(line); + + if(line[0] == '#' || !strlen(line)) { + continue; + } + + if((ptr = strchr(line, '#'))) { + *ptr = '\0'; + strtrim(line); + } + + if(line[0] == '[' && line[strlen(line) - 1] == ']') { + free(section); + section = strndup(&line[1], strlen(line) - 2); + + if(section && strcmp(section, "options") != 0) { + alpm_db_register_sync(handle, section, PM_PGP_VERIFY_OPTIONAL); + } + } + } + + free(section); + fclose(fp); + + return 0; +} + static int parse_options(int argc, char *argv[]) { int opt, option_index = 0; @@ -100,11 +171,12 @@ static int parse_options(int argc, char *argv[]) {"help", no_argument, 0, 'h'}, {"linear", no_argument, 0, 'l'}, {"reverse", no_argument, 0, 'r'}, + {"sync", no_argument, 0, 'S'}, {"unique", no_argument, 0, 'u'}, {0, 0, 0, 0} }; - while((opt = getopt_long(argc, argv, "b:cd:ghlru", opts, &option_index))) { + while((opt = getopt_long(argc, argv, "b:cd:ghlrsu", opts, &option_index))) { if(opt < 0) { break; } @@ -133,6 +205,9 @@ static int parse_options(int argc, char *argv[]) case 'r': reverse = 1; break; + case 's': + searchsyncs = 1; + break; case 'u': unique = 1; style = &graph_linear; @@ -161,6 +236,7 @@ static void usage(void) " -g, --graph generate output for graphviz's dot\n" " -l, --linear enable linear output\n" " -r, --reverse show reverse dependencies\n" + " -s, --sync search sync DBs instead of local\n" " -u, --unique show dependencies with no duplicates (implies -l)\n\n" " -h, --help display this help message\n"); } @@ -324,7 +400,7 @@ static void walk_deps(alpm_list_t *dblist, pmpkg_t *pkg, int depth) int main(int argc, char *argv[]) { - int ret = 0; + int freelist = 0, ret = 0; enum _pmerrno_t err; const char *target_name; pmpkg_t *pkg; @@ -344,7 +420,17 @@ int main(int argc, char *argv[]) goto finish; } - dblist = alpm_list_add(dblist, alpm_option_get_localdb(handle)); + if(searchsyncs) { + if(register_syncs() != 0) { + fprintf(stderr, "error: failed to register sync DBs\n"); + ret = 1; + goto finish; + } + dblist = alpm_option_get_syncdbs(handle); + } else { + dblist = alpm_list_add(dblist, alpm_option_get_localdb(handle)); + freelist = 1; + } /* we only care about the first non option arg for walking */ target_name = argv[optind]; @@ -366,7 +452,9 @@ int main(int argc, char *argv[]) print_end(); - alpm_list_free(dblist); + if(freelist) { + alpm_list_free(dblist); + } finish: cleanup(); diff --git a/src/util/testpkg.c b/src/util/testpkg.c index c6f02e34..d4d058d8 100644 --- a/src/util/testpkg.c +++ b/src/util/testpkg.c @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) if(alpm_pkg_load(handle, argv[1], 1, PM_PGP_VERIFY_OPTIONAL, &pkg) == -1 || pkg == NULL) { - enum _pmerrno_t err = alpm_errno(handle); + err = alpm_errno(handle); switch(err) { case PM_ERR_PKG_OPEN: printf("Cannot open the given file.\n"); diff --git a/test/pacman/tests/fileconflict008.py b/test/pacman/tests/fileconflict008.py new file mode 100644 index 00000000..24ea8852 --- /dev/null +++ b/test/pacman/tests/fileconflict008.py @@ -0,0 +1,21 @@ +self.description = "Fileconflict file -> dir on package replacement (FS#24904)" + +lp = pmpkg("dummy") +lp.files = ["dir/filepath", + "dir/file"] +self.addpkg2db("local", lp) + +p1 = pmpkg("replace") +p1.provides = ["dummy"] +p1.replaces = ["dummy"] +p1.files = ["dir/filepath/", + "dir/filepath/file", + "dir/file", + "dir/file2"] +self.addpkg2db("sync", p1) + +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("!PKG_EXIST=dummy") +self.addrule("PKG_EXIST=replace") diff --git a/valgrind.supp b/valgrind.supp index 1d6952d8..58fdf1cb 100644 --- a/valgrind.supp +++ b/valgrind.supp @@ -56,3 +56,25 @@ fun:SSL_COMP_get_compression_methods fun:SSL_library_init } +{ + gpgme-static-get-engine-info + Memcheck:Leak + fun:malloc + ... + fun:gpgme_get_engine_info +} +{ + gpgme-static-set-engine-info + Memcheck:Leak + fun:malloc + ... + fun:_gpgme_set_engine_info + fun:gpgme_set_engine_info +} +{ + gpgme-static-set-locale + Memcheck:Leak + fun:malloc + fun:strdup + fun:gpgme_set_locale +} |