mirror of
https://gitlab.archlinux.org/pacman/pacman.git
synced 2025-11-05 10:05:20 +01:00
Compare commits
31 Commits
morganamil
...
morganamil
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
219941734a | ||
|
|
fe055bec1f | ||
|
|
ee31b4c12e | ||
|
|
cde562bb4d | ||
|
|
15eb65c839 | ||
|
|
40f59fd6ac | ||
|
|
3c68d11f3c | ||
|
|
2200dd8797 | ||
|
|
c7c280115f | ||
|
|
564fd18c9a | ||
|
|
5c55ef2db5 | ||
|
|
de5fb9ae2f | ||
|
|
d4b4d315aa | ||
|
|
97d127588e | ||
|
|
c301327ad5 | ||
|
|
841236a1c9 | ||
|
|
6ce85053c5 | ||
|
|
e877472509 | ||
|
|
2b4c022925 | ||
|
|
689223f40d | ||
|
|
8d48332069 | ||
|
|
a61c500557 | ||
|
|
8fa9a69683 | ||
|
|
1340b5336e | ||
|
|
2b1ca6c298 | ||
|
|
ef05b4e31e | ||
|
|
c7c88f880a | ||
|
|
753083d241 | ||
|
|
36d3d8401c | ||
|
|
ddcceb9314 | ||
|
|
0c701af590 |
@@ -210,6 +210,11 @@ Transaction Options (apply to '-S', '-R' and '-U')
|
||||
dependencies are installed and there are no package conflicts in the
|
||||
system. Specify this option twice to skip all dependency checks.
|
||||
|
||||
*-n, \--nosave*::
|
||||
Instructs pacman to ignore file backup designations. Normally, when a
|
||||
file is removed from the system, the database is checked to see if the
|
||||
file should be renamed with a '.pacsave' extension.
|
||||
|
||||
*\--assume-installed* <package=version>::
|
||||
Add a virtual package "package" with version "version" to the transaction
|
||||
to satisfy dependencies. This allows to disable specific dependency checks
|
||||
@@ -235,9 +240,8 @@ Transaction Options (apply to '-S', '-R' and '-U')
|
||||
|
||||
*\--print-format* <format>::
|
||||
Specify a printf-like format to control the output of the '\--print'
|
||||
operation. The possible attributes are: "%a" for arch, "%n" for pkgname,
|
||||
"%v" for pkgver, "%l" for location, "%r" for repository, and "%s" for size.
|
||||
Implies '\--print'.
|
||||
operation. The possible attributes are: "%n" for pkgname, "%v" for pkgver,
|
||||
"%l" for location, "%r" for repository, and "%s" for size. Implies '\--print'.
|
||||
|
||||
|
||||
Upgrade Options (apply to '-S' and '-U')[[UO]]
|
||||
@@ -257,6 +261,12 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
|
||||
as explicitly installed so it will not be removed by the '\--recursive'
|
||||
remove operation.
|
||||
|
||||
*\--note*::
|
||||
Add an install note to packages. This will only apply to targets explicitly
|
||||
listed and not their dependencies. The note can be used to keep track of why
|
||||
a package was installed or any other info of note. The note can later be
|
||||
edited or removed with '\--D \--note' or '\--D \--rmnote' respectively.
|
||||
|
||||
*\--ignore* <package>::
|
||||
Directs pacman to ignore upgrades of package even if there is one
|
||||
available. Multiple packages can be specified by separating them
|
||||
@@ -270,6 +280,9 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
|
||||
*\--needed*::
|
||||
Do not reinstall the targets that are already up-to-date.
|
||||
|
||||
*\--nokeep*::
|
||||
Overwrite backup files when installing packages.
|
||||
|
||||
*\--overwrite* <glob>::
|
||||
Bypass file conflict checks and overwrite conflicting files. If the
|
||||
package that is about to be installed contains files that are already
|
||||
@@ -365,6 +378,9 @@ Query Options (apply to '-Q')[[QO]]
|
||||
replacements are not checked here. This option works best if the sync
|
||||
database is refreshed using '-Sy'.
|
||||
|
||||
*-w, \--backup*::
|
||||
List all modified backup files owened by a given package. Multiple packages can
|
||||
be specified on the command line. Pass twice to print all backup files.
|
||||
|
||||
Remove Options (apply to '-R')[[RO]]
|
||||
------------------------------------
|
||||
@@ -373,11 +389,6 @@ Remove Options (apply to '-R')[[RO]]
|
||||
or more target packages. This operation is recursive and must be used
|
||||
with care, since it can remove many potentially needed packages.
|
||||
|
||||
*-n, \--nosave*::
|
||||
Instructs pacman to ignore file backup designations. Normally, when a
|
||||
file is removed from the system, the database is checked to see if the
|
||||
file should be renamed with a '.pacsave' extension.
|
||||
|
||||
*-s, \--recursive*::
|
||||
Remove each target specified including all of their dependencies, provided
|
||||
that (A) they are not required by other packages; and (B) they were not
|
||||
@@ -469,6 +480,13 @@ Database Options (apply to '-D')[[QO]]
|
||||
package installed even when it was initially installed as a dependency
|
||||
of another package.
|
||||
|
||||
*\--note*::
|
||||
Add or edit a package's install note. The note can be used to keep track of why
|
||||
a package was installed or any other info of note.
|
||||
|
||||
*\--rmnote*::
|
||||
Remove a package's install note.
|
||||
|
||||
*-k, \--check*::
|
||||
Check the local package database is internally consistent. This will
|
||||
check all required files are present and that installed packages have
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
#
|
||||
#-- The download utilities that makepkg should use to acquire sources
|
||||
# Format: 'protocol::agent'
|
||||
DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u'
|
||||
'ftp::/usr/bin/curl -qgfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
|
||||
'http::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
'https::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
DLAGENTS=('file::/usr/bin/curl -gqC - -o %o %u'
|
||||
'ftp::/usr/bin/curl -gqfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
|
||||
'http::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
'https::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
'rsync::/usr/bin/rsync --no-motd -z %u %o'
|
||||
'scp::/usr/bin/scp -C %u %o')
|
||||
|
||||
|
||||
@@ -431,8 +431,22 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
|
||||
|
||||
ASSERT(trans != NULL, return -1);
|
||||
|
||||
|
||||
if(_alpm_db_get_pkgfromcache(db, newpkg->name)) {
|
||||
oldpkg = newpkg->oldpkg;
|
||||
}
|
||||
|
||||
/* set note on package only if it was explicitly added to transaction */
|
||||
if(trans->note && newpkg->reason == ALPM_PKG_REASON_EXPLICIT) {
|
||||
STRDUP(newpkg->note, trans->note,
|
||||
RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
} else if(oldpkg && oldpkg->note) {
|
||||
STRDUP(newpkg->note,oldpkg->note,
|
||||
RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
}
|
||||
|
||||
if(oldpkg) {
|
||||
/* see if this is an upgrade. if so, remove the old package first */
|
||||
if(_alpm_db_get_pkgfromcache(db, newpkg->name) && (oldpkg = newpkg->oldpkg)) {
|
||||
int cmp = _alpm_pkg_compare_versions(newpkg, oldpkg);
|
||||
if(cmp < 0) {
|
||||
log_msg = "downgrading";
|
||||
|
||||
@@ -101,6 +101,11 @@ typedef struct _alpm_handle_t alpm_handle_t;
|
||||
typedef struct _alpm_db_t alpm_db_t;
|
||||
|
||||
|
||||
/** A Database file iterator
|
||||
* @ingroup libalpm_databases
|
||||
*/
|
||||
typedef struct __alpm_db_files_t alpm_db_files_t;
|
||||
|
||||
/** A package.
|
||||
*
|
||||
* A package can be loaded from disk via \link alpm_pkg_load \endlink or retrieved from a database.
|
||||
@@ -158,6 +163,9 @@ typedef struct _alpm_backup_t {
|
||||
*/
|
||||
alpm_file_t *alpm_filelist_contains(alpm_filelist_t *filelist, const char *path);
|
||||
|
||||
/** Frees a file list */
|
||||
void alpm_filelist_free(alpm_filelist_t *files);
|
||||
|
||||
/* End of libalpm_files */
|
||||
/** @} */
|
||||
|
||||
@@ -1281,6 +1289,12 @@ int alpm_unregister_all_syncdbs(alpm_handle_t *handle);
|
||||
*/
|
||||
int alpm_db_unregister(alpm_db_t *db);
|
||||
|
||||
/** Get the handle of a package database.
|
||||
* @param db pointer to the package database
|
||||
* @return the alpm handle that the package database belongs to
|
||||
*/
|
||||
alpm_handle_t *alpm_db_get_handle(alpm_db_t *db);
|
||||
|
||||
/** Get the name of a package database.
|
||||
* @param db pointer to the package database
|
||||
* @return the name of the package database, NULL on error
|
||||
@@ -1444,6 +1458,42 @@ int alpm_db_get_usage(alpm_db_t *db, int *usage);
|
||||
/* End of usage accessors */
|
||||
/** @} */
|
||||
|
||||
/** @name File iterators
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Opens a handle to the db files iterator.
|
||||
* @param db the db files to iterate over
|
||||
* @return handle to the iterator
|
||||
*/
|
||||
alpm_db_files_t *alpm_db_files_open(alpm_db_t *db);
|
||||
|
||||
/** Goes to the next package.
|
||||
* @param files handle to the file iterator
|
||||
* @param pkgname stores the pkgname of the current package
|
||||
* @return 0 on success, 1 if end of iterator, -1 on error
|
||||
*/
|
||||
int alpm_db_files_next(alpm_db_files_t *files, char** pkgname);
|
||||
|
||||
/** Loads the files for a package into a file list.
|
||||
*
|
||||
* This extends the file list as needed, reusing the memory alloced.
|
||||
* You can reuse the same file list for calls to this function but
|
||||
* the list should be freed with \link alpm_filelist_free alpm_filelist_free \endlink
|
||||
* after use.
|
||||
* @param files handle to the file iterator
|
||||
* @param filelist the filelist to load files into
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int alpm_db_files_load(alpm_db_files_t *files, alpm_filelist_t *filelist);
|
||||
|
||||
/** Close the db file iterator
|
||||
* @param files handle to the file iterator
|
||||
*/
|
||||
void alpm_db_files_close(alpm_db_files_t *files);
|
||||
|
||||
/* End of file iterators */
|
||||
/** @} */
|
||||
|
||||
/* End of libalpm_databases */
|
||||
/** @} */
|
||||
@@ -2386,6 +2436,12 @@ int alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg);
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Gets the handle of a package
|
||||
* @param pkg a pointer to package
|
||||
* @return the alpm handle that the package belongs to
|
||||
*/
|
||||
alpm_handle_t *alpm_pkg_get_handle(alpm_pkg_t *pkg);
|
||||
|
||||
/** Gets the name of the file from which the package was loaded.
|
||||
* @param pkg a pointer to package
|
||||
* @return a reference to an internal string
|
||||
@@ -2429,6 +2485,12 @@ const char *alpm_pkg_get_desc(alpm_pkg_t *pkg);
|
||||
*/
|
||||
const char *alpm_pkg_get_url(alpm_pkg_t *pkg);
|
||||
|
||||
/** Returns the package note.
|
||||
* @param pkg a pointer to package
|
||||
* @return a reference to an internal string
|
||||
*/
|
||||
char *alpm_pkg_get_note(alpm_pkg_t *pkg);
|
||||
|
||||
/** Returns the build timestamp of the package.
|
||||
* @param pkg a pointer to package
|
||||
* @return the timestamp of the build time
|
||||
@@ -2607,6 +2669,15 @@ off_t alpm_pkg_download_size(alpm_pkg_t *newpkg);
|
||||
*/
|
||||
int alpm_pkg_set_reason(alpm_pkg_t *pkg, alpm_pkgreason_t reason);
|
||||
|
||||
/** Set install note for a package in the local database.
|
||||
* The provided package object must be from the local database or this method
|
||||
* will fail. The write to the local database is performed immediately.
|
||||
* @param pkg the package to edit
|
||||
* @param note the new install note, null to remove a note
|
||||
* @return 0 on success, -1 on error (pm_errno is set accordingly)
|
||||
*/
|
||||
int alpm_pkg_set_note(alpm_pkg_t *pkg, char *note);
|
||||
|
||||
|
||||
/* End of libalpm_pkg_t accessors */
|
||||
/** @} */
|
||||
@@ -2678,7 +2749,6 @@ int alpm_pkg_mtree_close(const alpm_pkg_t *pkg, struct archive *archive);
|
||||
/* End of mtree accessors */
|
||||
/** @} */
|
||||
|
||||
|
||||
/* End of libalpm_packages */
|
||||
/** @} */
|
||||
|
||||
@@ -2704,7 +2774,8 @@ int alpm_pkg_mtree_close(const alpm_pkg_t *pkg, struct archive *archive);
|
||||
typedef enum _alpm_transflag_t {
|
||||
/** Ignore dependency checks. */
|
||||
ALPM_TRANS_FLAG_NODEPS = 1,
|
||||
/* (1 << 1) flag can go here */
|
||||
/** Don't keep backup files when installing packages. */
|
||||
ALPM_TRANS_FLAG_NOKEEP = (1 << 1),
|
||||
/** Delete files even if they are tagged as backup. */
|
||||
ALPM_TRANS_FLAG_NOSAVE = (1 << 2),
|
||||
/** Ignore version numbers when checking dependencies. */
|
||||
@@ -2756,6 +2827,16 @@ alpm_list_t *alpm_trans_get_add(alpm_handle_t *handle);
|
||||
*/
|
||||
alpm_list_t *alpm_trans_get_remove(alpm_handle_t *handle);
|
||||
|
||||
/** Sets the install note for a transaction
|
||||
*
|
||||
* All target packages will gain the note, dependencies will not.
|
||||
*
|
||||
* @param handle the context handle
|
||||
* @note the the note, may not contain new lines
|
||||
* @return 0 on success, -1 on error (pm_errno is set accordingly)
|
||||
*/
|
||||
int alpm_trans_set_note(alpm_handle_t *handle, char *note);
|
||||
|
||||
/** Initialize the transaction.
|
||||
* @param handle the context handle
|
||||
* @param flags flags of the transaction (like nodeps, etc; see alpm_transflag_t)
|
||||
|
||||
@@ -81,6 +81,12 @@ static const char *_cache_get_url(alpm_pkg_t *pkg)
|
||||
return pkg->url;
|
||||
}
|
||||
|
||||
static char *_cache_get_note(alpm_pkg_t *pkg)
|
||||
{
|
||||
LAZY_LOAD(INFRQ_DESC);
|
||||
return pkg->note;
|
||||
}
|
||||
|
||||
static alpm_time_t _cache_get_builddate(alpm_pkg_t *pkg)
|
||||
{
|
||||
LAZY_LOAD(INFRQ_DESC);
|
||||
@@ -330,6 +336,7 @@ static const struct pkg_operations local_pkg_ops = {
|
||||
.get_base = _cache_get_base,
|
||||
.get_desc = _cache_get_desc,
|
||||
.get_url = _cache_get_url,
|
||||
.get_note = _cache_get_note,
|
||||
.get_builddate = _cache_get_builddate,
|
||||
.get_installdate = _cache_get_installdate,
|
||||
.get_packager = _cache_get_packager,
|
||||
@@ -752,6 +759,8 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
|
||||
READ_AND_STORE_ALL(info->groups);
|
||||
} else if(strcmp(line, "%URL%") == 0) {
|
||||
READ_AND_STORE(info->url);
|
||||
} else if(strcmp(line, "%NOTE%") == 0) {
|
||||
READ_AND_STORE(info->note);
|
||||
} else if(strcmp(line, "%LICENSE%") == 0) {
|
||||
READ_AND_STORE_ALL(info->licenses);
|
||||
} else if(strcmp(line, "%ARCH%") == 0) {
|
||||
@@ -1040,6 +1049,11 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, int inforeq)
|
||||
write_deps(fp, "%CONFLICTS%", info->conflicts);
|
||||
write_deps(fp, "%PROVIDES%", info->provides);
|
||||
|
||||
if(info->note) {
|
||||
fprintf(fp, "%%NOTE%%\n"
|
||||
"%s\n\n", info->note);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
@@ -1158,6 +1172,31 @@ int SYMEXPORT alpm_pkg_set_reason(alpm_pkg_t *pkg, alpm_pkgreason_t reason)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_pkg_set_note(alpm_pkg_t *pkg, char *note)
|
||||
{
|
||||
ASSERT(pkg != NULL, return -1);
|
||||
ASSERT(pkg->origin == ALPM_PKG_FROM_LOCALDB,
|
||||
RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
ASSERT(pkg->origin_data.db == pkg->handle->db_local,
|
||||
RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
|
||||
_alpm_log(pkg->handle, ALPM_LOG_DEBUG,
|
||||
"setting note for %s: %s\n", pkg->name, note);
|
||||
LAZY_LOAD(INFRQ_DESC);
|
||||
FREE(pkg->note);
|
||||
if(note) {
|
||||
ASSERT(!strchr(note, '\n'), RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
STRDUP(pkg->note, note,
|
||||
RET_ERR(pkg->handle, ALPM_ERR_MEMORY, -1));
|
||||
}
|
||||
/* write DESC */
|
||||
if(_alpm_local_db_write(pkg->handle->db_local, pkg, INFRQ_DESC)) {
|
||||
RET_ERR(pkg->handle, ALPM_ERR_DB_WRITE, -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct db_operations local_db_ops = {
|
||||
.validate = local_db_validate,
|
||||
.populate = local_db_populate,
|
||||
|
||||
@@ -566,8 +566,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|
||||
|| strcmp(filename, "files") == 0) {
|
||||
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0) {
|
||||
int ret;
|
||||
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
||||
char *line = buf.line;
|
||||
@@ -636,36 +635,6 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
READ_AND_SPLITDEP(pkg->conflicts);
|
||||
} else if(strcmp(line, "%PROVIDES%") == 0) {
|
||||
READ_AND_SPLITDEP(pkg->provides);
|
||||
} else if(strcmp(line, "%FILES%") == 0) {
|
||||
/* TODO: this could lazy load if there is future demand */
|
||||
size_t files_count = 0, files_size = 0;
|
||||
alpm_file_t *files = NULL;
|
||||
|
||||
while(1) {
|
||||
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) {
|
||||
goto error;
|
||||
}
|
||||
line = buf.line;
|
||||
if(_alpm_strip_newline(line, buf.real_line_size) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!_alpm_greedy_grow((void **)&files, &files_size,
|
||||
(files_count ? (files_count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) {
|
||||
goto error;
|
||||
}
|
||||
STRDUP(files[files_count].name, line, goto error);
|
||||
files_count++;
|
||||
}
|
||||
/* attempt to hand back any memory we don't need */
|
||||
if(files_count > 0) {
|
||||
REALLOC(files, sizeof(alpm_file_t) * files_count, (void)0);
|
||||
} else {
|
||||
FREE(files);
|
||||
}
|
||||
pkg->files.count = files_count;
|
||||
pkg->files.files = files;
|
||||
_alpm_filelist_sort(&pkg->files);
|
||||
}
|
||||
}
|
||||
if(ret != ARCHIVE_EOF) {
|
||||
@@ -716,3 +685,152 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
|
||||
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
|
||||
return db;
|
||||
}
|
||||
|
||||
static int load_files(struct archive *archive, alpm_filelist_t *filelist)
|
||||
{
|
||||
struct archive_read_buffer buf = {0};
|
||||
|
||||
/* 512K for a line length seems reasonable */
|
||||
buf.max_line_size = 512 * 1024;
|
||||
|
||||
_alpm_filelist_truncate(filelist);
|
||||
|
||||
int ret;
|
||||
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
||||
char *line = buf.line;
|
||||
if(_alpm_strip_newline(line, buf.real_line_size) == 0) {
|
||||
/* length of stripped line was zero */
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(line, "%FILES%") == 0) {
|
||||
size_t files_size = 0;
|
||||
|
||||
while(1) {
|
||||
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) {
|
||||
goto error;
|
||||
}
|
||||
line = buf.line;
|
||||
if(_alpm_strip_newline(line, buf.real_line_size) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!_alpm_greedy_grow((void **)&filelist->files, &files_size,
|
||||
(filelist->count ? (filelist->count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) {
|
||||
goto error;
|
||||
}
|
||||
STRDUP(filelist->files[filelist->count].name, line, goto error);
|
||||
filelist->count++;
|
||||
}
|
||||
_alpm_filelist_sort(filelist);
|
||||
}
|
||||
}
|
||||
if(ret != ARCHIVE_EOF) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
alpm_db_files_t SYMEXPORT *alpm_db_files_open(alpm_db_t *db)
|
||||
{
|
||||
const char *dbpath;
|
||||
int fd;
|
||||
struct stat buf;
|
||||
struct archive *archive;
|
||||
alpm_db_files_t *files = NULL;
|
||||
|
||||
ASSERT(db != NULL, return NULL);
|
||||
|
||||
dbpath = _alpm_db_path(db);
|
||||
if(!dbpath) {
|
||||
/* pm_errno set in _alpm_db_path() */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(db->status & DB_STATUS_INVALID || db->status & DB_STATUS_MISSING) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = _alpm_open_archive(db->handle, dbpath, &buf,
|
||||
&archive, ALPM_ERR_DB_OPEN);
|
||||
if(fd < 0) {
|
||||
db->status &= ~DB_STATUS_VALID;
|
||||
db->status |= DB_STATUS_INVALID;
|
||||
_alpm_archive_read_free(archive);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MALLOC(files, sizeof(alpm_db_files_t), RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
|
||||
files->archive = archive;
|
||||
files->fd = fd;
|
||||
files->db = db;
|
||||
return files;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_db_files_next(alpm_db_files_t *files, char** pkgname)
|
||||
{
|
||||
struct archive_entry *entry;
|
||||
const char *entryname;
|
||||
int archive_ret;
|
||||
char *filename;
|
||||
|
||||
ASSERT(files != NULL, return -1);
|
||||
ASSERT(pkgname != NULL, return -1);
|
||||
|
||||
while((archive_ret = archive_read_next_header(files->archive, &entry)) == ARCHIVE_OK) {
|
||||
mode_t mode = archive_entry_mode(entry);
|
||||
if(!S_ISDIR(mode)) {
|
||||
entryname = archive_entry_pathname(entry);
|
||||
if(entryname == NULL) {
|
||||
_alpm_log(files->db->handle, ALPM_LOG_DEBUG,
|
||||
"invalid archive entry provided to alpm_db_files_next, skipping\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(_alpm_splitname(entryname, pkgname, NULL, NULL) != 0) {
|
||||
_alpm_log(files->db->handle, ALPM_LOG_ERROR,
|
||||
_("invalid name for database entry '%s'\n"), entryname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
filename = strrchr(entryname, '/');
|
||||
filename++;
|
||||
|
||||
/* we only want to read the file list */
|
||||
if(filename && strcmp(filename, "files") == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(archive_ret != ARCHIVE_EOF) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_db_files_load(alpm_db_files_t *files, alpm_filelist_t *filelist)
|
||||
{
|
||||
ASSERT(files != NULL, return -1);
|
||||
ASSERT(filelist != NULL, return -1);
|
||||
|
||||
_alpm_filelist_truncate(filelist);
|
||||
if(load_files(files->archive, filelist) != 0) {
|
||||
_alpm_log(files->db->handle, ALPM_LOG_ERROR,
|
||||
_("could not parse package description file '%s' from db '%s'\n"),
|
||||
"files", files->db->treename);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SYMEXPORT alpm_db_files_close(alpm_db_files_t *files)
|
||||
{
|
||||
ASSERT(files != NULL, return);
|
||||
_alpm_archive_read_free(files->archive);
|
||||
close(files->fd);
|
||||
free(files);
|
||||
}
|
||||
|
||||
@@ -212,6 +212,12 @@ int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
|
||||
return ret;
|
||||
}
|
||||
|
||||
alpm_handle_t SYMEXPORT *alpm_db_get_handle(alpm_db_t *db)
|
||||
{
|
||||
ASSERT(db != NULL, return NULL);
|
||||
return db->handle;
|
||||
}
|
||||
|
||||
const char SYMEXPORT *alpm_db_get_name(const alpm_db_t *db)
|
||||
{
|
||||
ASSERT(db != NULL, return NULL);
|
||||
@@ -405,6 +411,7 @@ int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles,
|
||||
const char *matched = NULL;
|
||||
const char *name = pkg->name;
|
||||
const char *desc = alpm_pkg_get_desc(pkg);
|
||||
const char *note = alpm_pkg_get_note(pkg);
|
||||
|
||||
/* check name as regex AND as plain text */
|
||||
if(name && (regexec(®, name, 0, 0, 0) == 0 || strstr(name, targ))) {
|
||||
@@ -414,6 +421,11 @@ int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles,
|
||||
else if(desc && regexec(®, desc, 0, 0, 0) == 0) {
|
||||
matched = desc;
|
||||
}
|
||||
/* check note */
|
||||
else if(note && regexec(®, note, 0, 0, 0) == 0) {
|
||||
matched = note;
|
||||
}
|
||||
|
||||
/* TODO: should we be doing this, and should we print something
|
||||
* differently when we do match it since it isn't currently printed? */
|
||||
if(!matched) {
|
||||
|
||||
@@ -61,6 +61,13 @@ struct db_operations {
|
||||
void (*unregister) (alpm_db_t *);
|
||||
};
|
||||
|
||||
/* Database files iterator */
|
||||
struct __alpm_db_files_t {
|
||||
struct archive *archive;
|
||||
int fd;
|
||||
alpm_db_t *db;
|
||||
};
|
||||
|
||||
/* Database */
|
||||
struct _alpm_db_t {
|
||||
alpm_handle_t *handle;
|
||||
|
||||
@@ -427,9 +427,6 @@ static int curl_retry_next_server(CURLM *curlm, CURL *curl, struct dload_payload
|
||||
len = strlen(server) + strlen(payload->filepath) + 2;
|
||||
MALLOC(payload->fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
snprintf(payload->fileurl, len, "%s/%s", server, payload->filepath);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"%s: retrying from %s\n",
|
||||
payload->remote_name, payload->fileurl);
|
||||
|
||||
|
||||
fflush(payload->localf);
|
||||
|
||||
@@ -145,3 +145,17 @@ void _alpm_filelist_sort(alpm_filelist_t *filelist)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _alpm_filelist_truncate(alpm_filelist_t *files)
|
||||
{
|
||||
for(size_t i = 0; i < files->count; i++) {
|
||||
FREE(files->files[i].name);
|
||||
}
|
||||
files->count = 0;
|
||||
}
|
||||
|
||||
void SYMEXPORT alpm_filelist_free(alpm_filelist_t *files)
|
||||
{
|
||||
_alpm_filelist_truncate(files);
|
||||
free(files->files);
|
||||
}
|
||||
|
||||
@@ -28,5 +28,6 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
|
||||
alpm_filelist_t *filesB);
|
||||
|
||||
void _alpm_filelist_sort(alpm_filelist_t *filelist);
|
||||
void _alpm_filelist_truncate(alpm_filelist_t *filelist);
|
||||
|
||||
#endif /* ALPM_FILELIST_H */
|
||||
|
||||
@@ -57,7 +57,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg)
|
||||
ASSERT(pkg->origin == ALPM_PKG_FROM_SYNCDB,
|
||||
RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
|
||||
fpath = _alpm_filecache_find(pkg->handle, pkg->filename);
|
||||
fpath = _alpm_cache_find_pkg(pkg, 0);
|
||||
|
||||
retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_PKG_VALIDATION_MD5SUM);
|
||||
|
||||
@@ -78,6 +78,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg)
|
||||
static const char *_pkg_get_base(alpm_pkg_t *pkg) { return pkg->base; }
|
||||
static const char *_pkg_get_desc(alpm_pkg_t *pkg) { return pkg->desc; }
|
||||
static const char *_pkg_get_url(alpm_pkg_t *pkg) { return pkg->url; }
|
||||
static char *_pkg_get_note(alpm_pkg_t *pkg) { return pkg->note; }
|
||||
static alpm_time_t _pkg_get_builddate(alpm_pkg_t *pkg) { return pkg->builddate; }
|
||||
static alpm_time_t _pkg_get_installdate(alpm_pkg_t *pkg) { return pkg->installdate; }
|
||||
static const char *_pkg_get_packager(alpm_pkg_t *pkg) { return pkg->packager; }
|
||||
@@ -99,6 +100,7 @@ static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces;
|
||||
static alpm_filelist_t *_pkg_get_files(alpm_pkg_t *pkg) { return &(pkg->files); }
|
||||
static alpm_list_t *_pkg_get_backup(alpm_pkg_t *pkg) { return pkg->backup; }
|
||||
|
||||
|
||||
static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg)
|
||||
{
|
||||
return NULL;
|
||||
@@ -142,6 +144,7 @@ const struct pkg_operations default_pkg_ops = {
|
||||
.get_base = _pkg_get_base,
|
||||
.get_desc = _pkg_get_desc,
|
||||
.get_url = _pkg_get_url,
|
||||
.get_note = _pkg_get_note,
|
||||
.get_builddate = _pkg_get_builddate,
|
||||
.get_installdate = _pkg_get_installdate,
|
||||
.get_packager = _pkg_get_packager,
|
||||
@@ -191,6 +194,13 @@ const char SYMEXPORT *alpm_pkg_get_base(alpm_pkg_t *pkg)
|
||||
return pkg->ops->get_base(pkg);
|
||||
}
|
||||
|
||||
alpm_handle_t SYMEXPORT *alpm_pkg_get_handle(alpm_pkg_t *pkg)
|
||||
{
|
||||
ASSERT(pkg != NULL, return NULL);
|
||||
pkg->handle->pm_errno = ALPM_ERR_OK;
|
||||
return pkg->handle;
|
||||
}
|
||||
|
||||
const char SYMEXPORT *alpm_pkg_get_name(alpm_pkg_t *pkg)
|
||||
{
|
||||
ASSERT(pkg != NULL, return NULL);
|
||||
@@ -226,6 +236,13 @@ const char SYMEXPORT *alpm_pkg_get_url(alpm_pkg_t *pkg)
|
||||
return pkg->ops->get_url(pkg);
|
||||
}
|
||||
|
||||
char SYMEXPORT *alpm_pkg_get_note(alpm_pkg_t *pkg)
|
||||
{
|
||||
ASSERT(pkg != NULL, return NULL);
|
||||
pkg->handle->pm_errno = ALPM_ERR_OK;
|
||||
return pkg->ops->get_note(pkg);
|
||||
}
|
||||
|
||||
alpm_time_t SYMEXPORT alpm_pkg_get_builddate(alpm_pkg_t *pkg)
|
||||
{
|
||||
ASSERT(pkg != NULL, return -1);
|
||||
@@ -283,7 +300,7 @@ int SYMEXPORT alpm_pkg_get_sig(alpm_pkg_t *pkg, unsigned char **sig, size_t *sig
|
||||
alpm_errno_t err;
|
||||
int ret = -1;
|
||||
|
||||
pkgpath = _alpm_filecache_find(pkg->handle, pkg->filename);
|
||||
pkgpath = _alpm_cache_find_pkg(pkg, 0);
|
||||
if(!pkgpath) {
|
||||
GOTO_ERR(pkg->handle, ALPM_ERR_PKG_NOT_FOUND, cleanup);
|
||||
}
|
||||
@@ -610,6 +627,7 @@ int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr)
|
||||
STRDUP(newpkg->version, pkg->version, goto cleanup);
|
||||
STRDUP(newpkg->desc, pkg->desc, goto cleanup);
|
||||
STRDUP(newpkg->url, pkg->url, goto cleanup);
|
||||
STRDUP(newpkg->note, pkg->note, goto cleanup);
|
||||
newpkg->builddate = pkg->builddate;
|
||||
newpkg->installdate = pkg->installdate;
|
||||
STRDUP(newpkg->packager, pkg->packager, goto cleanup);
|
||||
@@ -683,6 +701,7 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
|
||||
FREE(pkg->version);
|
||||
FREE(pkg->desc);
|
||||
FREE(pkg->url);
|
||||
FREE(pkg->note);
|
||||
FREE(pkg->packager);
|
||||
FREE(pkg->md5sum);
|
||||
FREE(pkg->sha256sum);
|
||||
|
||||
@@ -46,6 +46,7 @@ struct pkg_operations {
|
||||
const char *(*get_base) (alpm_pkg_t *);
|
||||
const char *(*get_desc) (alpm_pkg_t *);
|
||||
const char *(*get_url) (alpm_pkg_t *);
|
||||
char *(*get_note) (alpm_pkg_t *);
|
||||
alpm_time_t (*get_builddate) (alpm_pkg_t *);
|
||||
alpm_time_t (*get_installdate) (alpm_pkg_t *);
|
||||
const char *(*get_packager) (alpm_pkg_t *);
|
||||
@@ -93,6 +94,7 @@ struct _alpm_pkg_t {
|
||||
char *version;
|
||||
char *desc;
|
||||
char *url;
|
||||
char *note;
|
||||
char *packager;
|
||||
char *md5sum;
|
||||
char *sha256sum;
|
||||
|
||||
@@ -575,7 +575,9 @@ static int should_skip_file(alpm_handle_t *handle,
|
||||
{
|
||||
return _alpm_fnmatch_patterns(handle->noupgrade, path) == 0
|
||||
|| alpm_list_find_str(handle->trans->skip_remove, path)
|
||||
|| (newpkg && _alpm_needbackup(path, newpkg)
|
||||
|| (!(handle->trans->flags & ALPM_TRANS_FLAG_NOKEEP)
|
||||
&& newpkg
|
||||
&& _alpm_needbackup(path, newpkg)
|
||||
&& alpm_filelist_contains(alpm_pkg_get_files(newpkg), path));
|
||||
}
|
||||
|
||||
|
||||
@@ -323,7 +323,7 @@ static int compute_download_size(alpm_pkg_t *newpkg)
|
||||
|
||||
ASSERT(newpkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
|
||||
fname = newpkg->filename;
|
||||
fpath = _alpm_filecache_find(handle, fname);
|
||||
fpath = _alpm_cache_find_pkg(newpkg, 0);
|
||||
|
||||
/* downloaded file exists, so there's nothing to grab */
|
||||
if(fpath) {
|
||||
@@ -333,7 +333,7 @@ static int compute_download_size(alpm_pkg_t *newpkg)
|
||||
|
||||
CALLOC(fnamepart, strlen(fname) + 6, sizeof(char), return -1);
|
||||
sprintf(fnamepart, "%s.part", fname);
|
||||
fpath = _alpm_filecache_find(handle, fnamepart);
|
||||
fpath = _alpm_cache_find_pkg(newpkg, 1);
|
||||
if(fpath) {
|
||||
struct stat st;
|
||||
if(stat(fpath, &st) == 0) {
|
||||
@@ -732,26 +732,18 @@ static int find_dl_candidates(alpm_handle_t *handle, alpm_list_t **files)
|
||||
handle->pm_errno = ALPM_ERR_SERVER_NONE;
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, "%s: %s\n",
|
||||
alpm_strerror(handle->pm_errno), repo->treename);
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASSERT(spkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
|
||||
|
||||
need_download = spkg->download_size != 0 || !_alpm_filecache_exists(handle, spkg->filename);
|
||||
need_download = spkg->download_size != 0 || !_alpm_cache_pkg_exists(spkg, 0);
|
||||
/* even if the package file in the cache we need to check for
|
||||
* accompanion *.sig file as well.
|
||||
* If *.sig is not cached then force download the package + its signature file.
|
||||
*/
|
||||
if(!need_download && (siglevel & ALPM_SIG_PACKAGE)) {
|
||||
char *sig_filename = NULL;
|
||||
int len = strlen(spkg->filename) + 5;
|
||||
|
||||
MALLOC(sig_filename, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
snprintf(sig_filename, len, "%s.sig", spkg->filename);
|
||||
|
||||
need_download = !_alpm_filecache_exists(handle, sig_filename);
|
||||
|
||||
FREE(sig_filename);
|
||||
need_download = !_alpm_cache_pkg_exists(spkg, 1);
|
||||
}
|
||||
|
||||
if(need_download) {
|
||||
@@ -990,7 +982,14 @@ static int check_validity(alpm_handle_t *handle,
|
||||
}
|
||||
|
||||
current_bytes += v.pkg->size;
|
||||
v.path = _alpm_filecache_find(handle, v.pkg->filename);
|
||||
v.path = _alpm_cache_find_pkg(v.pkg, 0);
|
||||
|
||||
if(!v.path) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("%s: could not find package in cache\n"), v.pkg->name);
|
||||
RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, -1);
|
||||
}
|
||||
|
||||
v.siglevel = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg));
|
||||
|
||||
if(_alpm_pkg_validate_internal(handle, v.path, v.pkg,
|
||||
@@ -1080,7 +1079,14 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
|
||||
}
|
||||
|
||||
current_bytes += spkg->size;
|
||||
filepath = _alpm_filecache_find(handle, spkg->filename);
|
||||
|
||||
filepath = _alpm_cache_find_pkg(spkg, 0);
|
||||
|
||||
if(!filepath) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("%s: could not find package in cache\n"), spkg->name);
|
||||
RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, -1);
|
||||
}
|
||||
|
||||
/* load the package file and replace pkgcache entry with it in the target list */
|
||||
/* TODO: alpm_pkg_get_db() will not work on this target anymore */
|
||||
|
||||
@@ -177,7 +177,8 @@ int SYMEXPORT alpm_trans_commit(alpm_handle_t *handle, alpm_list_t **data)
|
||||
ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1));
|
||||
ASSERT(trans->state == STATE_PREPARED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_PREPARED, -1));
|
||||
|
||||
ASSERT(!(trans->flags & ALPM_TRANS_FLAG_NOLOCK), RET_ERR(handle, ALPM_ERR_TRANS_NOT_LOCKED, -1));
|
||||
ASSERT(!(trans->flags & ALPM_TRANS_FLAG_NOLOCK && !(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY)),
|
||||
RET_ERR(handle, ALPM_ERR_TRANS_NOT_LOCKED, -1));
|
||||
|
||||
/* If there's nothing to do, return without complaining */
|
||||
if(trans->add == NULL && trans->remove == NULL) {
|
||||
@@ -298,6 +299,7 @@ void _alpm_trans_free(alpm_trans_t *trans)
|
||||
alpm_list_free(trans->add);
|
||||
alpm_list_free_inner(trans->remove, (alpm_list_fn_free)_alpm_pkg_free);
|
||||
alpm_list_free(trans->remove);
|
||||
FREE(trans->note);
|
||||
|
||||
FREELIST(trans->skip_remove);
|
||||
|
||||
@@ -450,3 +452,19 @@ alpm_list_t SYMEXPORT *alpm_trans_get_remove(alpm_handle_t *handle)
|
||||
|
||||
return handle->trans->remove;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_trans_set_note(alpm_handle_t *handle, char *note) {
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
ASSERT(handle->trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1));
|
||||
ASSERT(handle->trans->state == STATE_INITIALIZED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_INITIALIZED, -1));
|
||||
|
||||
if(handle->trans->note) {
|
||||
ASSERT(!strchr(handle->trans->note, '\n'), RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
free(handle->trans->note);
|
||||
handle->trans->note = NULL;
|
||||
}
|
||||
|
||||
STRDUP(handle->trans->note, note, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef enum _alpm_transstate_t {
|
||||
typedef struct _alpm_trans_t {
|
||||
/* bitfield of alpm_transflag_t flags */
|
||||
int flags;
|
||||
char *note;
|
||||
alpm_transstate_t state;
|
||||
alpm_list_t *unresolvable; /* list of (alpm_pkg_t *) */
|
||||
alpm_list_t *add; /* list of (alpm_pkg_t *) */
|
||||
|
||||
@@ -815,6 +815,37 @@ int _alpm_str_cmp(const void *s1, const void *s2)
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
char *_alpm_cache_find_pkg(alpm_pkg_t *pkg, int sig) {
|
||||
alpm_handle_t *handle = pkg->handle;
|
||||
struct stat buf;
|
||||
alpm_list_t *servers = pkg->origin_data.db->servers;
|
||||
char *retpath;
|
||||
char filepath[PATH_MAX];
|
||||
|
||||
for(alpm_list_t *j = servers; j; j = j->next) {
|
||||
char *server = j->data;
|
||||
|
||||
if(strncmp("file://", server, strlen("file://")) == 0) {
|
||||
int len = strlen(server) - strlen("file://") + 1 + strlen(pkg->filename) + 1;
|
||||
|
||||
if(sig) {
|
||||
len += strlen(".sig");
|
||||
snprintf(filepath, len, "%s/%s", server + strlen("file://"), pkg->filename);
|
||||
} else {
|
||||
snprintf(filepath, len, "%s/%s.sig", server + strlen("file://"), pkg->filename);
|
||||
}
|
||||
|
||||
if(stat(filepath, &buf) == 0 && S_ISREG(buf.st_mode)) {
|
||||
STRDUP(retpath, filepath, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "found pkg in repo cache: %s\n", retpath);
|
||||
return retpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _alpm_filecache_find(handle, pkg->filename);
|
||||
}
|
||||
|
||||
/** Find a filename in a registered alpm cachedir.
|
||||
* @param handle the context handle
|
||||
* @param filename name of file to find
|
||||
@@ -831,10 +862,17 @@ char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename)
|
||||
for(i = handle->cachedirs; i; i = i->next) {
|
||||
snprintf(path, PATH_MAX, "%s%s", (char *)i->data,
|
||||
filename);
|
||||
if(stat(path, &buf) == 0 && S_ISREG(buf.st_mode)) {
|
||||
retpath = strdup(path);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "found cached pkg: %s\n", retpath);
|
||||
return retpath;
|
||||
if(stat(path, &buf) == 0) {
|
||||
if(S_ISREG(buf.st_mode)) {
|
||||
retpath = strdup(path);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "found cached pkg: %s\n", retpath);
|
||||
return retpath;
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
"cached pkg '%s' is not a regular file: mode=%i\n", path, buf.st_mode);
|
||||
}
|
||||
} else if(errno != ENOENT) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, "could not open '%s'\n: %s", path, strerror(errno));
|
||||
}
|
||||
}
|
||||
/* package wasn't found in any cachedir */
|
||||
@@ -846,10 +884,10 @@ char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename)
|
||||
* @param filename name of file to find
|
||||
* @return 0 if the filename was not found, 1 otherwise
|
||||
*/
|
||||
int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename)
|
||||
int _alpm_cache_pkg_exists(alpm_pkg_t *pkg, int sig)
|
||||
{
|
||||
int res;
|
||||
char *fpath = _alpm_filecache_find(handle, filename);
|
||||
char *fpath = _alpm_cache_find_pkg(pkg, sig);
|
||||
res = (fpath != NULL);
|
||||
FREE(fpath);
|
||||
return res;
|
||||
|
||||
@@ -133,9 +133,10 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
|
||||
_alpm_cb_io in_cb, void *in_ctx);
|
||||
int _alpm_ldconfig(alpm_handle_t *handle);
|
||||
int _alpm_str_cmp(const void *s1, const void *s2);
|
||||
char *_alpm_cache_find_pkg(alpm_pkg_t *pkg, int sig);
|
||||
char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename);
|
||||
/* Checks whether a file exists in cache */
|
||||
int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename);
|
||||
int _alpm_cache_pkg_exists(alpm_pkg_t *pkg, int sig);
|
||||
const char *_alpm_filecache_setup(alpm_handle_t *handle);
|
||||
/* Unlike many uses of alpm_pkgvalidation_t, _alpm_test_checksum expects
|
||||
* an enum value rather than a bitfield. */
|
||||
|
||||
@@ -28,7 +28,7 @@ source "$LIBRARY/util/pkgbuild.sh"
|
||||
source "$LIBRARY/util/schema.sh"
|
||||
|
||||
lint_pkgbuild_functions+=('lint_variable')
|
||||
|
||||
lint_pkgbuild_functions+=('lint_array')
|
||||
|
||||
lint_variable() {
|
||||
local i a pkg out bad ret=0
|
||||
@@ -95,3 +95,21 @@ lint_variable() {
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
lint_array() {
|
||||
local i var ret=0
|
||||
|
||||
for i in ${pkgbuild_schema_arrays[@]}; do
|
||||
local l=()
|
||||
get_pkgbuild_all_split_attributes $i l
|
||||
|
||||
for var in "${l[@]}"; do
|
||||
if [[ -z $var ]]; then
|
||||
error "$(gettext "%s does not allow empty values.")" "$i"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@ config_t *config_new(void)
|
||||
return NULL;
|
||||
}
|
||||
/* defaults which may get overridden later */
|
||||
newconfig->op = PM_OP_MAIN;
|
||||
newconfig->op = 0;
|
||||
newconfig->curr_op = 0;
|
||||
newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING;
|
||||
newconfig->configfile = strdup(CONFFILE);
|
||||
if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) {
|
||||
@@ -131,6 +132,13 @@ config_t *config_new(void)
|
||||
return newconfig;
|
||||
}
|
||||
|
||||
void targets_free(targets_t *targets) {
|
||||
FREELIST(targets->targets);
|
||||
FREELIST(targets->sync);
|
||||
FREELIST(targets->upgrade);
|
||||
FREELIST(targets->remove);
|
||||
}
|
||||
|
||||
int config_free(config_t *oldconfig)
|
||||
{
|
||||
if(oldconfig == NULL) {
|
||||
@@ -155,6 +163,7 @@ int config_free(config_t *oldconfig)
|
||||
free(oldconfig->dbpath);
|
||||
free(oldconfig->logfile);
|
||||
free(oldconfig->gpgdir);
|
||||
free(oldconfig->note);
|
||||
FREELIST(oldconfig->hookdirs);
|
||||
FREELIST(oldconfig->cachedirs);
|
||||
free(oldconfig->xfercommand);
|
||||
|
||||
@@ -43,8 +43,17 @@ typedef struct __config_repo_t {
|
||||
int siglevel_mask;
|
||||
} config_repo_t;
|
||||
|
||||
|
||||
typedef struct __targets_t {
|
||||
alpm_list_t *targets;
|
||||
alpm_list_t *sync;
|
||||
alpm_list_t *upgrade;
|
||||
alpm_list_t *remove;
|
||||
} targets_t;
|
||||
|
||||
typedef struct __config_t {
|
||||
unsigned short op;
|
||||
unsigned short curr_op;
|
||||
unsigned short quiet;
|
||||
unsigned short verbose;
|
||||
unsigned short version;
|
||||
@@ -83,6 +92,7 @@ typedef struct __config_t {
|
||||
unsigned short op_q_upgrade;
|
||||
unsigned short op_q_check;
|
||||
unsigned short op_q_locality;
|
||||
unsigned short op_q_backup;
|
||||
|
||||
unsigned short op_s_clean;
|
||||
unsigned short op_s_downloadonly;
|
||||
@@ -99,6 +109,8 @@ typedef struct __config_t {
|
||||
unsigned int ask;
|
||||
/* Bitfield of alpm_transflag_t */
|
||||
int flags;
|
||||
char *note;
|
||||
int rmnote;
|
||||
/* Bitfields of alpm_siglevel_t */
|
||||
int siglevel;
|
||||
int localfilesiglevel;
|
||||
@@ -142,14 +154,15 @@ typedef struct __config_t {
|
||||
|
||||
/* Operations */
|
||||
enum {
|
||||
PM_OP_MAIN = 1,
|
||||
PM_OP_REMOVE,
|
||||
PM_OP_UPGRADE,
|
||||
PM_OP_QUERY,
|
||||
PM_OP_SYNC,
|
||||
PM_OP_DEPTEST,
|
||||
PM_OP_DATABASE,
|
||||
PM_OP_FILES
|
||||
PM_OP_INVALID = 1 << 0,
|
||||
PM_OP_REMOVE = 1 << 1,
|
||||
PM_OP_UPGRADE = 1 << 2,
|
||||
PM_OP_QUERY = 1 << 3,
|
||||
PM_OP_SYNC = 1 << 4,
|
||||
PM_OP_DEPTEST = 1 << 5,
|
||||
PM_OP_DATABASE = 1 << 6,
|
||||
PM_OP_FILES = 1 << 7,
|
||||
PM_OP_TRANS = PM_OP_SYNC | PM_OP_UPGRADE | PM_OP_REMOVE
|
||||
};
|
||||
|
||||
/* Long Operations */
|
||||
@@ -169,7 +182,10 @@ enum {
|
||||
OP_LOGFILE,
|
||||
OP_IGNOREGROUP,
|
||||
OP_NEEDED,
|
||||
OP_NOKEEP,
|
||||
OP_ASEXPLICIT,
|
||||
OP_NOTE,
|
||||
OP_RMNOTE,
|
||||
OP_ARCH,
|
||||
OP_PRINTFORMAT,
|
||||
OP_GPGDIR,
|
||||
@@ -180,6 +196,7 @@ enum {
|
||||
OP_DBPATH,
|
||||
OP_CASCADE,
|
||||
OP_CHANGELOG,
|
||||
OP_BACKUP,
|
||||
OP_CLEAN,
|
||||
OP_NODEPS,
|
||||
OP_DEPS,
|
||||
@@ -235,6 +252,9 @@ enum {
|
||||
/* global config variable */
|
||||
extern config_t *config;
|
||||
|
||||
|
||||
void targets_free(targets_t *targets);
|
||||
|
||||
void enable_colors(int colors);
|
||||
config_t *config_new(void);
|
||||
int config_free(config_t *oldconfig);
|
||||
|
||||
@@ -38,11 +38,12 @@
|
||||
*
|
||||
* @return 0 on success, 1 on failure
|
||||
*/
|
||||
static int change_install_reason(alpm_list_t *targets)
|
||||
static int change_pkg(alpm_list_t *targets)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
alpm_db_t *db_local;
|
||||
int ret = 0;
|
||||
int set_reason = 0;
|
||||
|
||||
alpm_pkgreason_t reason;
|
||||
|
||||
@@ -53,11 +54,10 @@ static int change_install_reason(alpm_list_t *targets)
|
||||
|
||||
if(config->flags & ALPM_TRANS_FLAG_ALLDEPS) { /* --asdeps */
|
||||
reason = ALPM_PKG_REASON_DEPEND;
|
||||
set_reason = 1;
|
||||
} else if(config->flags & ALPM_TRANS_FLAG_ALLEXPLICIT) { /* --asexplicit */
|
||||
reason = ALPM_PKG_REASON_EXPLICIT;
|
||||
} else {
|
||||
pm_printf(ALPM_LOG_ERROR, _("no install reason specified (use -h for help)\n"));
|
||||
return 1;
|
||||
set_reason = 1;
|
||||
}
|
||||
|
||||
/* Lock database */
|
||||
@@ -69,19 +69,46 @@ static int change_install_reason(alpm_list_t *targets)
|
||||
for(i = targets; i; i = alpm_list_next(i)) {
|
||||
char *pkgname = i->data;
|
||||
alpm_pkg_t *pkg = alpm_db_get_pkg(db_local, pkgname);
|
||||
if(!pkg || alpm_pkg_set_reason(pkg, reason)) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("could not set install reason for package %s (%s)\n"),
|
||||
pkgname, alpm_strerror(alpm_errno(config->handle)));
|
||||
|
||||
if(!pkg) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("package '%s' was not found"), pkgname);
|
||||
ret = 1;
|
||||
} else {
|
||||
if(!config->quiet) {
|
||||
if(reason == ALPM_PKG_REASON_DEPEND) {
|
||||
printf(_("%s: install reason has been set to 'installed as dependency'\n"), pkgname);
|
||||
} else {
|
||||
printf(_("%s: install reason has been set to 'explicitly installed'\n"), pkgname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(set_reason) {
|
||||
if(alpm_pkg_set_reason(pkg, reason)) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("could not set install reason for package %s (%s)\n"),
|
||||
pkgname, alpm_strerror(alpm_errno(config->handle)));
|
||||
ret = 1;
|
||||
} else {
|
||||
if(!config->quiet) {
|
||||
if(reason == ALPM_PKG_REASON_DEPEND) {
|
||||
printf(_("%s: install reason has been set to 'installed as dependency'\n"), pkgname);
|
||||
} else {
|
||||
printf(_("%s: install reason has been set to 'explicitly installed'\n"), pkgname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(config->rmnote) {
|
||||
if(alpm_pkg_set_note(pkg, NULL)) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("could not set install note for package %s (%s)\n"),
|
||||
pkgname, alpm_strerror(alpm_errno(config->handle)));
|
||||
ret = 1;
|
||||
} else if(!config->quiet) {
|
||||
printf(_("%s: note removed\n"), pkgname);
|
||||
}
|
||||
} else if(config->note) {
|
||||
if(alpm_pkg_set_note(pkg, config->note)) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("could not set install note for package %s (%s)\n"),
|
||||
pkgname, alpm_strerror(alpm_errno(config->handle)));
|
||||
ret = 1;
|
||||
} else if(!config->quiet) {
|
||||
printf(_("%s: note set\n"), pkgname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock database */
|
||||
@@ -296,8 +323,9 @@ int pacman_database(alpm_list_t *targets)
|
||||
}
|
||||
}
|
||||
|
||||
if(config->flags & (ALPM_TRANS_FLAG_ALLDEPS | ALPM_TRANS_FLAG_ALLEXPLICIT)) {
|
||||
ret = change_install_reason(targets);
|
||||
if(config->note || config->rmnote ||
|
||||
(config->flags & (ALPM_TRANS_FLAG_ALLDEPS | ALPM_TRANS_FLAG_ALLEXPLICIT))) {
|
||||
ret = change_pkg(targets);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -40,9 +40,8 @@ static void print_line_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg, char *fil
|
||||
fputs("\n", stdout);
|
||||
}
|
||||
|
||||
static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg)
|
||||
static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg, alpm_filelist_t *pkgfiles)
|
||||
{
|
||||
alpm_filelist_t *pkgfiles = alpm_pkg_get_files(pkg);
|
||||
for(size_t filenum = 0; filenum < pkgfiles->count; filenum++) {
|
||||
const alpm_file_t *file = pkgfiles->files + filenum;
|
||||
print_line_machinereadable(db, pkg, file->name);
|
||||
@@ -108,7 +107,9 @@ static void filetarget_free(struct filetarget *ftarg) {
|
||||
|
||||
static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
|
||||
int ret = 0;
|
||||
alpm_list_t *t, *filetargs = NULL;
|
||||
alpm_list_t *t, *s, *filetargs = NULL;
|
||||
alpm_filelist_t filelist = {0};
|
||||
char *pkgname = NULL;
|
||||
|
||||
for(t = targets; t; t = alpm_list_next(t)) {
|
||||
char *targ = t->data;
|
||||
@@ -144,43 +145,58 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for(t = filetargs; t; t = alpm_list_next(t)) {
|
||||
struct filetarget *ftarg = t->data;
|
||||
char *targ = ftarg->targ;
|
||||
regex_t *reg = &ftarg->reg;
|
||||
int exact_file = ftarg->exact_file;
|
||||
alpm_list_t *s;
|
||||
int found = 0;
|
||||
for(s = syncs; s; s = alpm_list_next(s)) {
|
||||
alpm_db_t *repo = s->data;
|
||||
int m;
|
||||
|
||||
for(s = syncs; s; s = alpm_list_next(s)) {
|
||||
alpm_list_t *p;
|
||||
alpm_db_t *repo = s->data;
|
||||
alpm_list_t *packages = alpm_db_get_pkgcache(repo);
|
||||
int m;
|
||||
alpm_db_files_t *files = alpm_db_files_open(repo);
|
||||
|
||||
for(p = packages; p; p = alpm_list_next(p)) {
|
||||
alpm_pkg_t *pkg = p->data;
|
||||
alpm_filelist_t *files = alpm_pkg_get_files(pkg);
|
||||
if(!files) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
int ok = alpm_db_files_next(files, &pkgname);
|
||||
if(ok == 1) {
|
||||
break;
|
||||
}
|
||||
if(ok != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(alpm_db_files_load(files, &filelist) != 0) {
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
alpm_pkg_t *pkg = alpm_db_get_pkg(repo, pkgname);
|
||||
|
||||
for(t = filetargs; t; t = alpm_list_next(t)) {
|
||||
struct filetarget *ftarg = t->data;
|
||||
char *targ = ftarg->targ;
|
||||
regex_t *reg = &ftarg->reg;
|
||||
int exact_file = ftarg->exact_file;
|
||||
int found = 0;
|
||||
alpm_list_t *match = NULL;
|
||||
|
||||
if(exact_file) {
|
||||
if (regex) {
|
||||
for(size_t f = 0; f < files->count; f++) {
|
||||
char *c = files->files[f].name;
|
||||
if(regex) {
|
||||
for(size_t f = 0; f < filelist.count; f++) {
|
||||
char *c = filelist.files[f].name;
|
||||
if(regexec(reg, c, 0, 0, 0) == 0) {
|
||||
match = alpm_list_add(match, files->files[f].name);
|
||||
match = alpm_list_add(match, filelist.files[f].name);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(alpm_filelist_contains(files, targ)) {
|
||||
if(alpm_filelist_contains(&filelist, targ)) {
|
||||
match = alpm_list_add(match, targ);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(size_t f = 0; f < files->count; f++) {
|
||||
char *c = strrchr(files->files[f].name, '/');
|
||||
for(size_t f = 0; f < filelist.count; f++) {
|
||||
char *c = strrchr(filelist.files[f].name, '/');
|
||||
if(c && *(c + 1)) {
|
||||
if(regex) {
|
||||
m = regexec(reg, (c + 1), 0, 0, 0);
|
||||
@@ -188,7 +204,7 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
|
||||
m = strcmp(c + 1, targ);
|
||||
}
|
||||
if(m == 0) {
|
||||
match = alpm_list_add(match, files->files[f].name);
|
||||
match = alpm_list_add(match, filelist.files[f].name);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
@@ -199,28 +215,33 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
|
||||
print_match(match, repo, pkg, exact_file);
|
||||
alpm_list_free(match);
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
ret = 1;
|
||||
}
|
||||
alpm_db_files_close(files);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
alpm_list_free_inner(filetargs, (alpm_list_fn_free) filetarget_free);
|
||||
alpm_list_free(filetargs);
|
||||
alpm_filelist_free(&filelist);
|
||||
|
||||
if(pkgname) {
|
||||
free(pkgname);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dump_file_list(alpm_pkg_t *pkg) {
|
||||
static void dump_file_list(alpm_pkg_t *pkg, alpm_filelist_t *pkgfiles) {
|
||||
const char *pkgname;
|
||||
alpm_filelist_t *pkgfiles;
|
||||
size_t i;
|
||||
|
||||
pkgname = alpm_pkg_get_name(pkg);
|
||||
pkgfiles = alpm_pkg_get_files(pkg);
|
||||
|
||||
for(i = 0; i < pkgfiles->count; i++) {
|
||||
const alpm_file_t *file = pkgfiles->files + i;
|
||||
@@ -239,73 +260,97 @@ static void dump_file_list(alpm_pkg_t *pkg) {
|
||||
static int files_list(alpm_list_t *syncs, alpm_list_t *targets) {
|
||||
alpm_list_t *i, *j;
|
||||
int ret = 0;
|
||||
size_t found = 0;
|
||||
alpm_filelist_t filelist = {0};
|
||||
char *pkgname = NULL;
|
||||
|
||||
if(targets != NULL) {
|
||||
for(i = targets; i; i = alpm_list_next(i)) {
|
||||
int found = 0;
|
||||
char *targ = i->data;
|
||||
char *repo = NULL;
|
||||
char *c = strchr(targ, '/');
|
||||
for(j = syncs; j; j = alpm_list_next(j)) {
|
||||
alpm_db_t *db = j->data;
|
||||
alpm_db_files_t *files = alpm_db_files_open(db);
|
||||
|
||||
if(c) {
|
||||
if(! *(c + 1)) {
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
_("invalid package: '%s'\n"), targ);
|
||||
ret += 1;
|
||||
if(!files) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
int ok = alpm_db_files_next(files, &pkgname);
|
||||
if(ok == 1) {
|
||||
break;
|
||||
}
|
||||
if(ok != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(targets != NULL) {
|
||||
int match = 0;
|
||||
for(i = targets; i; i = alpm_list_next(i)) {
|
||||
char *targ = i->data;
|
||||
char *c = strchr(targ, '/');
|
||||
char *repo = NULL;
|
||||
|
||||
if(c) {
|
||||
if(! *(c + 1)) {
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
_("invalid package: '%s'\n"), targ);
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
repo = strndup(targ, c - targ);
|
||||
targ = c + 1;
|
||||
}
|
||||
|
||||
if(repo) {
|
||||
if(strcmp(alpm_db_get_name(db), repo) != 0) {
|
||||
free(repo);
|
||||
continue;
|
||||
}
|
||||
free(repo);
|
||||
}
|
||||
|
||||
if(strcmp(pkgname, targ) == 0) {
|
||||
match = 1;
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!match) {
|
||||
continue;
|
||||
}
|
||||
|
||||
repo = strndup(targ, c - targ);
|
||||
targ = c + 1;
|
||||
}
|
||||
|
||||
for(j = syncs; j; j = alpm_list_next(j)) {
|
||||
alpm_pkg_t *pkg;
|
||||
alpm_db_t *db = j->data;
|
||||
|
||||
if(repo) {
|
||||
if(strcmp(alpm_db_get_name(db), repo) != 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(alpm_db_files_load(files, &filelist) != 0) {
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((pkg = alpm_db_get_pkg(db, targ)) != NULL) {
|
||||
found = 1;
|
||||
if(config->op_f_machinereadable) {
|
||||
dump_pkg_machinereadable(db, pkg);
|
||||
} else {
|
||||
dump_file_list(pkg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
alpm_pkg_t *pkg = alpm_db_get_pkg(db, pkgname);
|
||||
|
||||
if(config->op_f_machinereadable) {
|
||||
dump_pkg_machinereadable(db, pkg, &filelist);
|
||||
} else {
|
||||
dump_file_list(pkg, &filelist);
|
||||
}
|
||||
if(!found) {
|
||||
targ = i->data;
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
_("package '%s' was not found\n"), targ);
|
||||
ret += 1;
|
||||
}
|
||||
free(repo);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for(i = syncs; i; i = alpm_list_next(i)) {
|
||||
alpm_db_t *db = i->data;
|
||||
alpm_db_files_close(files);
|
||||
}
|
||||
|
||||
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
|
||||
alpm_pkg_t *pkg = j->data;
|
||||
if(config->op_f_machinereadable) {
|
||||
dump_pkg_machinereadable(db, pkg);
|
||||
} else {
|
||||
dump_file_list(pkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
alpm_filelist_free(&filelist);
|
||||
|
||||
if(found != alpm_list_count(targets)) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if(pkgname) {
|
||||
free(pkgname);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int pacman_files(alpm_list_t *targets)
|
||||
{
|
||||
alpm_list_t *files_dbs = NULL;
|
||||
|
||||
@@ -10,6 +10,7 @@ pacman_sources = files('''
|
||||
remove.c
|
||||
sighandler.h sighandler.c
|
||||
sync.c
|
||||
trans.c
|
||||
callback.h callback.c
|
||||
upgrade.c
|
||||
util.h util.c
|
||||
|
||||
@@ -70,6 +70,7 @@ enum {
|
||||
T_URL,
|
||||
T_VALIDATED_BY,
|
||||
T_VERSION,
|
||||
T_NOTE,
|
||||
/* the following is a sentinel and should remain in last position */
|
||||
_T_MAX
|
||||
};
|
||||
@@ -124,6 +125,7 @@ static void make_aligned_titles(void)
|
||||
buf[T_URL] = _("URL");
|
||||
buf[T_VALIDATED_BY] = _("Validated By");
|
||||
buf[T_VERSION] = _("Version");
|
||||
buf[T_NOTE] = _("Note");
|
||||
|
||||
for(i = 0; i < ARRAYSIZE(wbuf); i++) {
|
||||
wlen[i] = mbstowcs(wbuf[i], buf[i], strlen(buf[i]) + 1);
|
||||
@@ -301,6 +303,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
|
||||
if(from == ALPM_PKG_FROM_LOCALDB) {
|
||||
string_display(titles[T_INSTALL_DATE], idatestr, cols);
|
||||
string_display(titles[T_INSTALL_REASON], reason, cols);
|
||||
string_display(titles[T_NOTE], alpm_pkg_get_note(pkg), cols);
|
||||
}
|
||||
if(from == ALPM_PKG_FROM_FILE || from == ALPM_PKG_FROM_LOCALDB) {
|
||||
string_display(titles[T_INSTALL_SCRIPT],
|
||||
@@ -348,7 +351,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
|
||||
|
||||
/* Print additional package info if info flag passed more than once */
|
||||
if(from == ALPM_PKG_FROM_LOCALDB && extra) {
|
||||
dump_pkg_backups(pkg);
|
||||
dump_backup_status(pkg, cols);
|
||||
}
|
||||
|
||||
/* final newline to separate packages */
|
||||
@@ -359,6 +362,34 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
|
||||
alpm_list_free(validation);
|
||||
}
|
||||
|
||||
static int get_backup_file_changed(const char *root,
|
||||
const alpm_backup_t *backup)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
int ret = 0;
|
||||
|
||||
snprintf(path, PATH_MAX, "%s%s", root, backup->name);
|
||||
|
||||
/* if we find the file, calculate checksums, otherwise it is missing */
|
||||
if(access(path, R_OK) == 0) {
|
||||
char *md5sum = alpm_compute_md5sum(path);
|
||||
|
||||
if(md5sum == NULL) {
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
_("could not calculate checksums for %s\n"), path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if checksums don't match, file has been modified */
|
||||
ret = strcmp(md5sum, backup->hash) != 0;
|
||||
free(md5sum);
|
||||
} else if(errno != ENOENT) {
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
_("could not read %s: %s\n"), path, strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *get_backup_file_status(const char *root,
|
||||
const alpm_backup_t *backup)
|
||||
{
|
||||
@@ -379,21 +410,21 @@ static const char *get_backup_file_status(const char *root,
|
||||
|
||||
/* if checksums don't match, file has been modified */
|
||||
if(strcmp(md5sum, backup->hash) != 0) {
|
||||
ret = "MODIFIED";
|
||||
ret = "[modified]";
|
||||
} else {
|
||||
ret = "UNMODIFIED";
|
||||
ret = "[unmodified]";
|
||||
}
|
||||
free(md5sum);
|
||||
} else {
|
||||
switch(errno) {
|
||||
case EACCES:
|
||||
ret = "UNREADABLE";
|
||||
ret = "[unreadable]";
|
||||
break;
|
||||
case ENOENT:
|
||||
ret = "MISSING";
|
||||
ret = "[missing]";
|
||||
break;
|
||||
default:
|
||||
ret = "UNKNOWN";
|
||||
ret = "[unknown]";
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -401,27 +432,33 @@ static const char *get_backup_file_status(const char *root,
|
||||
|
||||
/* Display list of backup files and their modification states
|
||||
*/
|
||||
void dump_pkg_backups(alpm_pkg_t *pkg)
|
||||
void dump_backup_status(alpm_pkg_t *pkg, unsigned short cols)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
alpm_list_t *i, *text = NULL;
|
||||
const char *root = alpm_option_get_root(config->handle);
|
||||
printf("%s%s\n%s", config->colstr.title, titles[T_BACKUP_FILES],
|
||||
config->colstr.nocolor);
|
||||
if(alpm_pkg_get_backup(pkg)) {
|
||||
/* package has backup files, so print them */
|
||||
for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) {
|
||||
const alpm_backup_t *backup = i->data;
|
||||
const char *value;
|
||||
if(!backup->hash) {
|
||||
continue;
|
||||
}
|
||||
value = get_backup_file_status(root, backup);
|
||||
printf("%s\t%s%s\n", value, root, backup->name);
|
||||
/* package has backup files, so print them */
|
||||
for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) {
|
||||
const alpm_backup_t *backup = i->data;
|
||||
const char *value;
|
||||
char *line;
|
||||
size_t needed;
|
||||
if(!backup->hash) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* package had no backup files */
|
||||
printf(_("(none)\n"));
|
||||
value = get_backup_file_status(root, backup);
|
||||
needed = strlen(root) + strlen(backup->name) + 1 + strlen(value) + 1;
|
||||
line = malloc(needed);
|
||||
if(!line) {
|
||||
goto cleanup;
|
||||
}
|
||||
sprintf(line, "%s%s %s", root, backup->name, value);
|
||||
text = alpm_list_add(text, line);
|
||||
}
|
||||
|
||||
list_display_linebreak(titles[T_BACKUP_FILES], text, cols);
|
||||
|
||||
cleanup:
|
||||
FREELIST(text);
|
||||
}
|
||||
|
||||
/* List all files contained in a package
|
||||
@@ -450,6 +487,32 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet)
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void dump_pkg_backups(alpm_pkg_t *pkg, int quiet, int all)
|
||||
{
|
||||
const char *pkgname, *root;
|
||||
alpm_list_t *backups;
|
||||
alpm_list_t *i;
|
||||
|
||||
pkgname = alpm_pkg_get_name(pkg);
|
||||
backups = alpm_pkg_get_backup(pkg);
|
||||
root = alpm_option_get_root(config->handle);
|
||||
|
||||
for(i = backups; i; i = i->next) {
|
||||
alpm_backup_t *backup = i->data;
|
||||
|
||||
if(!all && backup->hash && !get_backup_file_changed(root, backup)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!quiet) {
|
||||
printf("%s%s%s ", config->colstr.title, pkgname, config->colstr.nocolor);
|
||||
}
|
||||
printf("%s%s\n", root, backup->name);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* Display the changelog of a package
|
||||
*/
|
||||
void dump_pkg_changelog(alpm_pkg_t *pkg)
|
||||
@@ -466,7 +529,11 @@ void dump_pkg_changelog(alpm_pkg_t *pkg)
|
||||
char buf[CLBUF_SIZE];
|
||||
size_t ret = 0;
|
||||
while((ret = alpm_pkg_changelog_read(buf, CLBUF_SIZE, pkg, fp))) {
|
||||
fwrite(buf, 1, ret, stdout);
|
||||
if(ret < CLBUF_SIZE) {
|
||||
/* if we hit the end of the file, we need to add a null terminator */
|
||||
*(buf + ret) = '\0';
|
||||
}
|
||||
fputs(buf, stdout);
|
||||
}
|
||||
alpm_pkg_changelog_close(pkg, fp);
|
||||
putchar('\n');
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
void dump_pkg_full(alpm_pkg_t *pkg, int extra);
|
||||
|
||||
void dump_pkg_backups(alpm_pkg_t *pkg);
|
||||
void dump_backup_status(alpm_pkg_t *pkg, unsigned short cols);
|
||||
void dump_pkg_backups(alpm_pkg_t *pkg, int quiet, int all);
|
||||
void dump_pkg_files(alpm_pkg_t *pkg, int quiet);
|
||||
void dump_pkg_changelog(alpm_pkg_t *pkg);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include "sighandler.h"
|
||||
|
||||
/* list of targets specified on command line */
|
||||
static alpm_list_t *pm_targets;
|
||||
static targets_t pm_targets;
|
||||
|
||||
/* Used to sort the options in --help */
|
||||
static int options_cmp(const void *p1, const void *p2)
|
||||
@@ -104,7 +104,7 @@ static void usage(int op, const char * const myname)
|
||||
char const *const str_opr = _("operation");
|
||||
|
||||
/* please limit your strings to 80 characters in width */
|
||||
if(op == PM_OP_MAIN) {
|
||||
if(!op) {
|
||||
printf("%s: %s <%s> [...]\n", str_usg, myname, str_opr);
|
||||
printf(_("operations:\n"));
|
||||
printf(" %s {-h --help}\n", myname);
|
||||
@@ -123,13 +123,11 @@ static void usage(int op, const char * const myname)
|
||||
printf("%s: %s {-R --remove} [%s] <%s>\n", str_usg, myname, str_opt, str_pkg);
|
||||
printf("%s:\n", str_opt);
|
||||
addlist(_(" -c, --cascade remove packages and all packages that depend on them\n"));
|
||||
addlist(_(" -n, --nosave remove configuration files\n"));
|
||||
addlist(_(" -s, --recursive remove unnecessary dependencies\n"
|
||||
" (-ss includes explicitly installed dependencies)\n"));
|
||||
addlist(_(" -u, --unneeded remove unneeded packages\n"));
|
||||
" (-ss includes explicitly installed dependencies)\n"));
|
||||
addlist(_(" --unneeded remove unneeded packages\n"));
|
||||
} else if(op == PM_OP_UPGRADE) {
|
||||
printf("%s: %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file);
|
||||
addlist(_(" --needed do not reinstall up to date packages\n"));
|
||||
printf("%s:\n", str_opt);
|
||||
} else if(op == PM_OP_QUERY) {
|
||||
printf("%s: %s {-Q --query} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
|
||||
@@ -150,6 +148,7 @@ static void usage(int op, const char * const myname)
|
||||
addlist(_(" -t, --unrequired list packages not (optionally) required by any\n"
|
||||
" package (-tt to ignore optdepends) [filter]\n"));
|
||||
addlist(_(" -u, --upgrades list outdated packages [filter]\n"));
|
||||
addlist(_(" -w, --backup list modified backup files of a package (-xx for all backup files)\n"));
|
||||
} else if(op == PM_OP_SYNC) {
|
||||
printf("%s: %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
|
||||
printf("%s:\n", str_opt);
|
||||
@@ -163,12 +162,13 @@ static void usage(int op, const char * const myname)
|
||||
addlist(_(" -u, --sysupgrade upgrade installed packages (-uu enables downgrades)\n"));
|
||||
addlist(_(" -y, --refresh download fresh package databases from the server\n"
|
||||
" (-yy to force a refresh even if up to date)\n"));
|
||||
addlist(_(" --needed do not reinstall up to date packages\n"));
|
||||
} else if(op == PM_OP_DATABASE) {
|
||||
printf("%s: %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg);
|
||||
printf("%s:\n", str_opt);
|
||||
addlist(_(" --asdeps mark packages as non-explicitly installed\n"));
|
||||
addlist(_(" --asexplicit mark packages as explicitly installed\n"));
|
||||
addlist(_(" --note <note> add or edit a packages install notes\n"));
|
||||
addlist(_(" --rmnote remove install note from packages\n"));
|
||||
addlist(_(" -k, --check test local database for validity (-kk for sync databases)\n"));
|
||||
addlist(_(" -q, --quiet suppress output of success messages\n"));
|
||||
} else if(op == PM_OP_DEPTEST) {
|
||||
@@ -185,29 +185,29 @@ static void usage(int op, const char * const myname)
|
||||
addlist(_(" --machinereadable\n"
|
||||
" produce machine-readable output\n"));
|
||||
}
|
||||
switch(op) {
|
||||
case PM_OP_SYNC:
|
||||
case PM_OP_UPGRADE:
|
||||
addlist(_(" -w, --downloadonly download packages but do not install/upgrade anything\n"));
|
||||
addlist(_(" --overwrite <glob>\n"
|
||||
" overwrite conflicting files (can be used more than once)\n"));
|
||||
addlist(_(" --asdeps install packages as non-explicitly installed\n"));
|
||||
addlist(_(" --asexplicit install packages as explicitly installed\n"));
|
||||
addlist(_(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n"));
|
||||
addlist(_(" --ignoregroup <grp>\n"
|
||||
" ignore a group upgrade (can be used more than once)\n"));
|
||||
__attribute__((fallthrough));
|
||||
case PM_OP_REMOVE:
|
||||
addlist(_(" -d, --nodeps skip dependency version checks (-dd to skip all checks)\n"));
|
||||
addlist(_(" --assume-installed <package=version>\n"
|
||||
" add a virtual package to satisfy dependencies\n"));
|
||||
addlist(_(" --dbonly only modify database entries, not package files\n"));
|
||||
addlist(_(" --noprogressbar do not show a progress bar when downloading files\n"));
|
||||
addlist(_(" --noscriptlet do not execute the install scriptlet if one exists\n"));
|
||||
addlist(_(" -p, --print print the targets instead of performing the operation\n"));
|
||||
addlist(_(" --print-format <string>\n"
|
||||
" specify how the targets should be printed\n"));
|
||||
break;
|
||||
if(op & (PM_OP_UPGRADE | PM_OP_SYNC)) {
|
||||
addlist(_(" --needed do not reinstall up to date packages\n"));
|
||||
addlist(_(" --nokeep overwrite backup files when installing packages\n"));
|
||||
addlist(_(" -w, --downloadonly download packages but do not install/upgrade anything\n"));
|
||||
addlist(_(" --overwrite <glob>\n"
|
||||
" overwrite conflicting files (can be used more than once)\n"));
|
||||
addlist(_(" --asdeps install packages as non-explicitly installed\n"));
|
||||
addlist(_(" --asexplicit install packages as explicitly installed\n"));
|
||||
addlist(_(" --note <note> add an install note to packages\n"));
|
||||
addlist(_(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n"));
|
||||
addlist(_(" --ignoregroup <grp>\n"
|
||||
" ignore a group upgrade (can be used more than once)\n"));
|
||||
}
|
||||
if(op & PM_OP_TRANS) {
|
||||
addlist(_(" -d, --nodeps skip dependency version checks (-dd to skip all checks)\n"));
|
||||
addlist(_(" --assume-installed <package=version>\n"
|
||||
" add a virtual package to satisfy dependencies\n"));
|
||||
addlist(_(" --dbonly only modify database entries, not package files\n"));
|
||||
addlist(_(" --noprogressbar do not show a progress bar when downloading files\n"));
|
||||
addlist(_(" --noscriptlet do not execute the install scriptlet if one exists\n"));
|
||||
addlist(_(" -p, --print print the targets instead of performing the operation\n"));
|
||||
addlist(_(" --print-format <string>\n"
|
||||
" specify how the targets should be printed\n"));
|
||||
}
|
||||
|
||||
addlist(_(" -b, --dbpath <path> set an alternate database location\n"));
|
||||
@@ -301,7 +301,7 @@ static void cleanup(int ret)
|
||||
}
|
||||
|
||||
/* free memory */
|
||||
FREELIST(pm_targets);
|
||||
targets_free(&pm_targets);
|
||||
console_cursor_show();
|
||||
exit(ret);
|
||||
}
|
||||
@@ -327,6 +327,24 @@ static int parsearg_util_addlist(alpm_list_t **list)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_op(int opt)
|
||||
{
|
||||
int trans = (config->op & PM_OP_TRANS) != 0;
|
||||
int setting_trans = (opt & PM_OP_TRANS) != 0;
|
||||
|
||||
/* we allow -SS so allow -QQ for sake of consistency */
|
||||
if(config->op == opt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!config->op || (trans && setting_trans)) {
|
||||
config->op |= opt;
|
||||
config->curr_op = opt;
|
||||
} else {
|
||||
config->op |= PM_OP_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper function for parsing operation from command-line arguments.
|
||||
* @param opt Keycode returned by getopt_long
|
||||
* @param dryrun If nonzero, application state is NOT changed
|
||||
@@ -338,25 +356,25 @@ static int parsearg_op(int opt, int dryrun)
|
||||
/* operations */
|
||||
case 'D':
|
||||
if(dryrun) break;
|
||||
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DATABASE); break;
|
||||
set_op(PM_OP_DATABASE); break;
|
||||
case 'F':
|
||||
if(dryrun) break;
|
||||
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_FILES); break;
|
||||
set_op(PM_OP_FILES); break;
|
||||
case 'Q':
|
||||
if(dryrun) break;
|
||||
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;
|
||||
set_op(PM_OP_QUERY); break;
|
||||
case 'R':
|
||||
if(dryrun) break;
|
||||
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break;
|
||||
set_op(PM_OP_REMOVE); break;
|
||||
case 'S':
|
||||
if(dryrun) break;
|
||||
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break;
|
||||
set_op(PM_OP_SYNC); break;
|
||||
case 'T':
|
||||
if(dryrun) break;
|
||||
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DEPTEST); break;
|
||||
set_op(PM_OP_DEPTEST); break;
|
||||
case 'U':
|
||||
if(dryrun) break;
|
||||
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_UPGRADE); break;
|
||||
set_op(PM_OP_UPGRADE); break;
|
||||
case 'V':
|
||||
if(dryrun) break;
|
||||
config->version = 1; break;
|
||||
@@ -369,6 +387,7 @@ static int parsearg_op(int opt, int dryrun)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Helper functions for parsing command-line arguments.
|
||||
* @param opt Keycode returned by getopt_long
|
||||
* @return 0 on success, 1 on failure
|
||||
@@ -481,6 +500,12 @@ static int parsearg_database(int opt)
|
||||
case OP_ASEXPLICIT:
|
||||
config->flags |= ALPM_TRANS_FLAG_ALLEXPLICIT;
|
||||
break;
|
||||
case OP_NOTE:
|
||||
config->note = strdup(optarg);
|
||||
break;
|
||||
case OP_RMNOTE:
|
||||
config->rmnote = 1;
|
||||
break;
|
||||
case OP_CHECK:
|
||||
case 'k':
|
||||
(config->op_q_check)++;
|
||||
@@ -501,7 +526,11 @@ static void checkargs_database(void)
|
||||
&& config->flags & ALPM_TRANS_FLAG_ALLEXPLICIT,
|
||||
"--asdeps", "--asexplicit");
|
||||
|
||||
invalid_opt(config->note && config->rmnote, "--note", "--rmnote");
|
||||
|
||||
if(config->op_q_check) {
|
||||
invalid_opt(config->note != NULL, "--note", "--check");
|
||||
invalid_opt(config->rmnote, "--rmnote", "--check");
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_ALLDEPS,
|
||||
"--asdeps", "--check");
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_ALLEXPLICIT,
|
||||
@@ -516,6 +545,10 @@ static int parsearg_query(int opt)
|
||||
case 'c':
|
||||
config->op_q_changelog = 1;
|
||||
break;
|
||||
case OP_BACKUP:
|
||||
case 'w':
|
||||
(config->op_q_backup)++;
|
||||
break;
|
||||
case OP_DEPS:
|
||||
case 'd':
|
||||
config->op_q_deps = 1;
|
||||
@@ -583,6 +616,7 @@ static void checkargs_query_display_opts(const char *opname) {
|
||||
invalid_opt(config->op_q_check, opname, "--check");
|
||||
invalid_opt(config->op_q_info, opname, "--info");
|
||||
invalid_opt(config->op_q_list, opname, "--list");
|
||||
invalid_opt(config->op_q_backup, opname, "--backup");
|
||||
}
|
||||
|
||||
static void checkargs_query_filter_opts(const char *opname) {
|
||||
@@ -619,62 +653,8 @@ static void checkargs_query(void)
|
||||
"--native", "--foreign");
|
||||
}
|
||||
|
||||
/* options common to -S -R -U */
|
||||
static int parsearg_trans(int opt)
|
||||
{
|
||||
switch(opt) {
|
||||
case OP_NODEPS:
|
||||
case 'd':
|
||||
if(config->flags & ALPM_TRANS_FLAG_NODEPVERSION) {
|
||||
config->flags |= ALPM_TRANS_FLAG_NODEPS;
|
||||
} else {
|
||||
config->flags |= ALPM_TRANS_FLAG_NODEPVERSION;
|
||||
}
|
||||
break;
|
||||
case OP_DBONLY:
|
||||
config->flags |= ALPM_TRANS_FLAG_DBONLY;
|
||||
config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
|
||||
config->flags |= ALPM_TRANS_FLAG_NOHOOKS;
|
||||
break;
|
||||
case OP_NOPROGRESSBAR:
|
||||
config->noprogressbar = 1;
|
||||
break;
|
||||
case OP_NOSCRIPTLET:
|
||||
config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
|
||||
break;
|
||||
case OP_PRINT:
|
||||
case 'p':
|
||||
config->print = 1;
|
||||
break;
|
||||
case OP_PRINTFORMAT:
|
||||
config->print = 1;
|
||||
free(config->print_format);
|
||||
config->print_format = strdup(optarg);
|
||||
break;
|
||||
case OP_ASSUMEINSTALLED:
|
||||
parsearg_util_addlist(&(config->assumeinstalled));
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void checkargs_trans(void)
|
||||
{
|
||||
if(config->print) {
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_DBONLY,
|
||||
"--print", "--dbonly");
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_NOSCRIPTLET,
|
||||
"--print", "--noscriptlet");
|
||||
}
|
||||
}
|
||||
|
||||
static int parsearg_remove(int opt)
|
||||
{
|
||||
if(parsearg_trans(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
switch(opt) {
|
||||
case OP_CASCADE:
|
||||
case 'c':
|
||||
@@ -693,7 +673,6 @@ static int parsearg_remove(int opt)
|
||||
}
|
||||
break;
|
||||
case OP_UNNEEDED:
|
||||
case 'u':
|
||||
config->flags |= ALPM_TRANS_FLAG_UNNEEDED;
|
||||
break;
|
||||
default:
|
||||
@@ -704,7 +683,6 @@ static int parsearg_remove(int opt)
|
||||
|
||||
static void checkargs_remove(void)
|
||||
{
|
||||
checkargs_trans();
|
||||
if(config->flags & ALPM_TRANS_FLAG_NOSAVE) {
|
||||
invalid_opt(config->print, "--nosave", "--print");
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_DBONLY,
|
||||
@@ -715,9 +693,6 @@ static void checkargs_remove(void)
|
||||
/* options common to -S -U */
|
||||
static int parsearg_upgrade(int opt)
|
||||
{
|
||||
if(parsearg_trans(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
switch(opt) {
|
||||
case OP_OVERWRITE_FILES:
|
||||
parsearg_util_addlist(&(config->overwrite_files));
|
||||
@@ -728,9 +703,15 @@ static int parsearg_upgrade(int opt)
|
||||
case OP_ASEXPLICIT:
|
||||
config->flags |= ALPM_TRANS_FLAG_ALLEXPLICIT;
|
||||
break;
|
||||
case OP_NOTE:
|
||||
config->note = strdup(optarg);
|
||||
break;
|
||||
case OP_NEEDED:
|
||||
config->flags |= ALPM_TRANS_FLAG_NEEDED;
|
||||
break;
|
||||
case OP_NOKEEP:
|
||||
config->flags |= ALPM_TRANS_FLAG_NOKEEP;
|
||||
break;
|
||||
case OP_IGNORE:
|
||||
parsearg_util_addlist(&(config->ignorepkg));
|
||||
break;
|
||||
@@ -742,6 +723,7 @@ static int parsearg_upgrade(int opt)
|
||||
config->op_s_downloadonly = 1;
|
||||
config->flags |= ALPM_TRANS_FLAG_DOWNLOADONLY;
|
||||
config->flags |= ALPM_TRANS_FLAG_NOCONFLICTS;
|
||||
config->flags |= ALPM_TRANS_FLAG_NOLOCK;
|
||||
break;
|
||||
default: return 1;
|
||||
}
|
||||
@@ -750,7 +732,6 @@ static int parsearg_upgrade(int opt)
|
||||
|
||||
static void checkargs_upgrade(void)
|
||||
{
|
||||
checkargs_trans();
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_ALLDEPS
|
||||
&& config->flags & ALPM_TRANS_FLAG_ALLEXPLICIT,
|
||||
"--asdeps", "--asexplicit");
|
||||
@@ -758,9 +739,6 @@ static void checkargs_upgrade(void)
|
||||
|
||||
static int parsearg_files(int opt)
|
||||
{
|
||||
if(parsearg_trans(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
switch(opt) {
|
||||
case OP_LIST:
|
||||
case 'l':
|
||||
@@ -799,6 +777,26 @@ static int parsearg_sync(int opt)
|
||||
if(parsearg_upgrade(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
switch(opt) {
|
||||
case OP_SYSUPGRADE:
|
||||
case 'u':
|
||||
(config->op_s_upgrade)++;
|
||||
break;
|
||||
case OP_REFRESH:
|
||||
case 'y':
|
||||
(config->op_s_sync)++;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parsearg_sync_only(int opt)
|
||||
{
|
||||
if(parsearg_sync(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
switch(opt) {
|
||||
case OP_CLEAN:
|
||||
case 'c':
|
||||
@@ -840,7 +838,12 @@ static int parsearg_sync(int opt)
|
||||
|
||||
static void checkargs_sync(void)
|
||||
{
|
||||
checkargs_upgrade();
|
||||
/* no conflicts currently */
|
||||
}
|
||||
|
||||
static void checkargs_sync_only(void)
|
||||
{
|
||||
checkargs_sync();
|
||||
if(config->op_s_clean) {
|
||||
invalid_opt(config->group, "--clean", "--groups");
|
||||
invalid_opt(config->op_s_info, "--clean", "--info");
|
||||
@@ -870,6 +873,89 @@ static void checkargs_sync(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* options common to -S -R -U */
|
||||
static int parsearg_trans(int opt)
|
||||
{
|
||||
if(config->op & (PM_OP_SYNC | PM_OP_UPGRADE) && parsearg_upgrade(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if(config->op & PM_OP_SYNC && parsearg_sync(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if(config->op & PM_OP_REMOVE && parsearg_remove(opt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
switch(opt) {
|
||||
case OP_NODEPS:
|
||||
case 'd':
|
||||
if(config->flags & ALPM_TRANS_FLAG_NODEPVERSION) {
|
||||
config->flags |= ALPM_TRANS_FLAG_NODEPS;
|
||||
} else {
|
||||
config->flags |= ALPM_TRANS_FLAG_NODEPVERSION;
|
||||
}
|
||||
break;
|
||||
case OP_DBONLY:
|
||||
config->flags |= ALPM_TRANS_FLAG_DBONLY;
|
||||
config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
|
||||
config->flags |= ALPM_TRANS_FLAG_NOHOOKS;
|
||||
break;
|
||||
case OP_NOPROGRESSBAR:
|
||||
config->noprogressbar = 1;
|
||||
break;
|
||||
case OP_NOSCRIPTLET:
|
||||
config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
|
||||
break;
|
||||
case OP_PRINT:
|
||||
case 'p':
|
||||
config->print = 1;
|
||||
break;
|
||||
case OP_PRINTFORMAT:
|
||||
config->print = 1;
|
||||
free(config->print_format);
|
||||
config->print_format = strdup(optarg);
|
||||
break;
|
||||
case OP_ASSUMEINSTALLED:
|
||||
parsearg_util_addlist(&(config->assumeinstalled));
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void checkargs_trans(void)
|
||||
{
|
||||
if(config->op & (PM_OP_SYNC | PM_OP_UPGRADE)) {
|
||||
checkargs_upgrade();
|
||||
}
|
||||
if(config->op & PM_OP_SYNC) {
|
||||
checkargs_sync();
|
||||
}
|
||||
if(config->op & PM_OP_REMOVE) {
|
||||
checkargs_remove();
|
||||
}
|
||||
|
||||
if(config->print) {
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_DBONLY,
|
||||
"--print", "--dbonly");
|
||||
invalid_opt(config->flags & ALPM_TRANS_FLAG_NOSCRIPTLET,
|
||||
"--print", "--noscriptlet");
|
||||
}
|
||||
}
|
||||
|
||||
static void add_target(char *targ)
|
||||
{
|
||||
if(config->curr_op & PM_OP_SYNC) {
|
||||
pm_targets.sync = alpm_list_add(pm_targets.sync, targ);
|
||||
} else if(config->curr_op & PM_OP_REMOVE) {
|
||||
pm_targets.remove = alpm_list_add(pm_targets.remove, targ);
|
||||
} else if(config->curr_op & PM_OP_UPGRADE) {
|
||||
pm_targets.upgrade = alpm_list_add(pm_targets.upgrade, targ);
|
||||
} else {
|
||||
pm_targets.targets = alpm_list_add(pm_targets.targets, targ);
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse command-line arguments for each operation.
|
||||
* @param argc argc
|
||||
* @param argv argv
|
||||
@@ -880,7 +966,7 @@ static int parseargs(int argc, char *argv[])
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
int result;
|
||||
const char *optstring = "DFQRSTUVb:cdefghiklmnopqr:stuvwxy";
|
||||
const char *optstring = "-DFQRSTUVb:cdefghiklmnopqr:stuvwxy";
|
||||
static const struct option opts[] =
|
||||
{
|
||||
{"database", no_argument, 0, 'D'},
|
||||
@@ -896,6 +982,7 @@ static int parseargs(int argc, char *argv[])
|
||||
{"dbpath", required_argument, 0, OP_DBPATH},
|
||||
{"cascade", no_argument, 0, OP_CASCADE},
|
||||
{"changelog", no_argument, 0, OP_CHANGELOG},
|
||||
{"backup", no_argument, 0, OP_BACKUP},
|
||||
{"clean", no_argument, 0, OP_CLEAN},
|
||||
{"nodeps", no_argument, 0, OP_NODEPS},
|
||||
{"deps", no_argument, 0, OP_DEPS},
|
||||
@@ -941,7 +1028,10 @@ static int parseargs(int argc, char *argv[])
|
||||
{"logfile", required_argument, 0, OP_LOGFILE},
|
||||
{"ignoregroup", required_argument, 0, OP_IGNOREGROUP},
|
||||
{"needed", no_argument, 0, OP_NEEDED},
|
||||
{"nokeep", no_argument, 0, OP_NOKEEP},
|
||||
{"asexplicit", no_argument, 0, OP_ASEXPLICIT},
|
||||
{"note", required_argument, 0, OP_NOTE},
|
||||
{"rmnote", no_argument, 0, OP_RMNOTE},
|
||||
{"arch", required_argument, 0, OP_ARCH},
|
||||
{"print-format", required_argument, 0, OP_PRINTFORMAT},
|
||||
{"gpgdir", required_argument, 0, OP_GPGDIR},
|
||||
@@ -955,6 +1045,11 @@ static int parseargs(int argc, char *argv[])
|
||||
while((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) {
|
||||
if(opt == 0) {
|
||||
continue;
|
||||
} else if(opt == 1) {
|
||||
char *targ = strdup(optarg);
|
||||
/* add the target to our target array */
|
||||
add_target(targ);
|
||||
continue;
|
||||
} else if(opt == '?') {
|
||||
/* unknown option, getopt printed an error */
|
||||
return 1;
|
||||
@@ -962,8 +1057,8 @@ static int parseargs(int argc, char *argv[])
|
||||
parsearg_op(opt, 0);
|
||||
}
|
||||
|
||||
if(config->op == 0) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("only one operation may be used at a time\n"));
|
||||
if(config->op & PM_OP_INVALID) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("these operations can not be used together\n"));
|
||||
return 1;
|
||||
}
|
||||
if(config->help) {
|
||||
@@ -978,7 +1073,7 @@ static int parseargs(int argc, char *argv[])
|
||||
/* parse all other options */
|
||||
optind = 1;
|
||||
while((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) {
|
||||
if(opt == 0) {
|
||||
if(opt == 0 || opt == 1) {
|
||||
continue;
|
||||
} else if(opt == '?') {
|
||||
/* this should have failed during first pass already */
|
||||
@@ -995,14 +1090,9 @@ static int parseargs(int argc, char *argv[])
|
||||
case PM_OP_QUERY:
|
||||
result = parsearg_query(opt);
|
||||
break;
|
||||
case PM_OP_REMOVE:
|
||||
result = parsearg_remove(opt);
|
||||
break;
|
||||
case PM_OP_SYNC:
|
||||
result = parsearg_sync(opt);
|
||||
break;
|
||||
case PM_OP_UPGRADE:
|
||||
result = parsearg_upgrade(opt);
|
||||
/* handle -Si -Sg etc if -S is the only trans op */
|
||||
result = parsearg_sync_only(opt);
|
||||
break;
|
||||
case PM_OP_FILES:
|
||||
result = parsearg_files(opt);
|
||||
@@ -1016,6 +1106,13 @@ static int parseargs(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
if(config->op & PM_OP_TRANS) {
|
||||
result = parsearg_trans(opt);
|
||||
}
|
||||
if(result == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* fall back to global options */
|
||||
result = parsearg_global(opt);
|
||||
if(result != 0) {
|
||||
@@ -1032,7 +1129,7 @@ static int parseargs(int argc, char *argv[])
|
||||
|
||||
while(optind < argc) {
|
||||
/* add the target to our target array */
|
||||
pm_targets = alpm_list_add(pm_targets, strdup(argv[optind]));
|
||||
add_target(strdup(argv[optind]));
|
||||
optind++;
|
||||
}
|
||||
|
||||
@@ -1044,7 +1141,7 @@ static int parseargs(int argc, char *argv[])
|
||||
/* no conflicting options */
|
||||
break;
|
||||
case PM_OP_SYNC:
|
||||
checkargs_sync();
|
||||
checkargs_sync_only();
|
||||
break;
|
||||
case PM_OP_QUERY:
|
||||
checkargs_query();
|
||||
@@ -1061,10 +1158,83 @@ static int parseargs(int argc, char *argv[])
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(config->op & PM_OP_TRANS) {
|
||||
checkargs_trans();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse_stdin(alpm_list_t **targets)
|
||||
{
|
||||
if(!isatty(fileno(stdin))) {
|
||||
int target_found = 0;
|
||||
char *vdata, *line = NULL;
|
||||
size_t line_size = 0;
|
||||
ssize_t nread;
|
||||
|
||||
/* remove the '-' from the list */
|
||||
*targets = alpm_list_remove_str(*targets, "-", &vdata);
|
||||
free(vdata);
|
||||
|
||||
while((nread = getline(&line, &line_size, stdin)) != -1) {
|
||||
if(line[nread - 1] == '\n') {
|
||||
/* remove trailing newline */
|
||||
line[nread - 1] = '\0';
|
||||
}
|
||||
if(line[0] == '\0') {
|
||||
/* skip empty lines */
|
||||
continue;
|
||||
}
|
||||
if(!alpm_list_append_strdup(targets, line)) {
|
||||
break;
|
||||
}
|
||||
target_found = 1;
|
||||
}
|
||||
free(line);
|
||||
|
||||
if(ferror(stdin)) {
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
_("failed to read arguments from stdin: (%s)\n"), strerror(errno));
|
||||
cleanup(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(!freopen(ctermid(NULL), "r", stdin)) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"),
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
if(!target_found) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("argument '-' specified with empty stdin\n"));
|
||||
cleanup(1);
|
||||
}
|
||||
} else {
|
||||
/* do not read stdin from terminal */
|
||||
pm_printf(ALPM_LOG_ERROR, _("argument '-' specified without input on stdin\n"));
|
||||
cleanup(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void parse_stdins(void)
|
||||
{
|
||||
alpm_list_t **lists[4] = {&pm_targets.targets, &pm_targets.sync, &pm_targets.upgrade, &pm_targets.remove};
|
||||
int replaced = 0;
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
alpm_list_t **list = lists[i];
|
||||
if(alpm_list_find_str(*list, "-")) {
|
||||
if(replaced) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("argument '-' can not be specified multiple times\n"));
|
||||
cleanup(1);
|
||||
}
|
||||
parse_stdin(list);
|
||||
replaced++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Print command line to logfile.
|
||||
* @param argc
|
||||
* @param argv
|
||||
@@ -1138,54 +1308,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* we support reading targets from stdin if a cmdline parameter is '-' */
|
||||
if(alpm_list_find_str(pm_targets, "-")) {
|
||||
if(!isatty(fileno(stdin))) {
|
||||
int target_found = 0;
|
||||
char *vdata, *line = NULL;
|
||||
size_t line_size = 0;
|
||||
ssize_t nread;
|
||||
|
||||
/* remove the '-' from the list */
|
||||
pm_targets = alpm_list_remove_str(pm_targets, "-", &vdata);
|
||||
free(vdata);
|
||||
|
||||
while((nread = getline(&line, &line_size, stdin)) != -1) {
|
||||
if(line[nread - 1] == '\n') {
|
||||
/* remove trailing newline */
|
||||
line[nread - 1] = '\0';
|
||||
}
|
||||
if(line[0] == '\0') {
|
||||
/* skip empty lines */
|
||||
continue;
|
||||
}
|
||||
if(!alpm_list_append_strdup(&pm_targets, line)) {
|
||||
break;
|
||||
}
|
||||
target_found = 1;
|
||||
}
|
||||
free(line);
|
||||
|
||||
if(ferror(stdin)) {
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
_("failed to read arguments from stdin: (%s)\n"), strerror(errno));
|
||||
cleanup(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(!freopen(ctermid(NULL), "r", stdin)) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"),
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
if(!target_found) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("argument '-' specified with empty stdin\n"));
|
||||
cleanup(1);
|
||||
}
|
||||
} else {
|
||||
/* do not read stdin from terminal */
|
||||
pm_printf(ALPM_LOG_ERROR, _("argument '-' specified without input on stdin\n"));
|
||||
cleanup(1);
|
||||
}
|
||||
}
|
||||
parse_stdins();
|
||||
|
||||
if(config->sysroot && (chroot(config->sysroot) != 0 || chdir("/") != 0)) {
|
||||
pm_printf(ALPM_LOG_ERROR,
|
||||
@@ -1233,7 +1356,10 @@ int main(int argc, char *argv[])
|
||||
printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle));
|
||||
printf("Log File : %s\n", alpm_option_get_logfile(config->handle));
|
||||
printf("GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle));
|
||||
list_display("Targets :", pm_targets, 0);
|
||||
list_display("Targets :", pm_targets.targets, 0);
|
||||
list_display("Sync :", pm_targets.sync, 0);
|
||||
list_display("Upgrade :", pm_targets.upgrade, 0);
|
||||
list_display("Remove :", pm_targets.remove, 0);
|
||||
}
|
||||
|
||||
/* Log command line */
|
||||
@@ -1242,31 +1368,26 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* start the requested operation */
|
||||
switch(config->op) {
|
||||
case PM_OP_DATABASE:
|
||||
ret = pacman_database(pm_targets);
|
||||
break;
|
||||
case PM_OP_REMOVE:
|
||||
ret = pacman_remove(pm_targets);
|
||||
break;
|
||||
case PM_OP_UPGRADE:
|
||||
ret = pacman_upgrade(pm_targets);
|
||||
break;
|
||||
case PM_OP_QUERY:
|
||||
ret = pacman_query(pm_targets);
|
||||
break;
|
||||
case PM_OP_SYNC:
|
||||
ret = pacman_sync(pm_targets);
|
||||
break;
|
||||
case PM_OP_DEPTEST:
|
||||
ret = pacman_deptest(pm_targets);
|
||||
break;
|
||||
case PM_OP_FILES:
|
||||
ret = pacman_files(pm_targets);
|
||||
break;
|
||||
default:
|
||||
pm_printf(ALPM_LOG_ERROR, _("no operation specified (use -h for help)\n"));
|
||||
ret = EXIT_FAILURE;
|
||||
if(config->op & PM_OP_TRANS) {
|
||||
ret = do_transaction(&pm_targets);
|
||||
} else {
|
||||
switch(config->op) {
|
||||
case PM_OP_DATABASE:
|
||||
ret = pacman_database(pm_targets.targets);
|
||||
break;
|
||||
case PM_OP_QUERY:
|
||||
ret = pacman_query(pm_targets.targets);
|
||||
break;
|
||||
case PM_OP_DEPTEST:
|
||||
ret = pacman_deptest(pm_targets.targets);
|
||||
break;
|
||||
case PM_OP_FILES:
|
||||
ret = pacman_files(pm_targets.targets);
|
||||
break;
|
||||
default:
|
||||
pm_printf(ALPM_LOG_ERROR, _("no operation specified (use -h for help)\n"));
|
||||
ret = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup(ret);
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <alpm_list.h>
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#define PACMAN_CALLER_PREFIX "PACMAN"
|
||||
|
||||
/* database.c */
|
||||
@@ -32,12 +34,14 @@ int pacman_deptest(alpm_list_t *targets);
|
||||
int pacman_files(alpm_list_t *files);
|
||||
/* query.c */
|
||||
int pacman_query(alpm_list_t *targets);
|
||||
/* remove.c */
|
||||
int pacman_remove(alpm_list_t *targets);
|
||||
/* sync.c */
|
||||
int pacman_sync(alpm_list_t *targets);
|
||||
int sync_prepare_execute(void);
|
||||
/* remove.c */
|
||||
int load_remove(alpm_list_t *targets);
|
||||
/* upgrade.c */
|
||||
int pacman_upgrade(alpm_list_t *targets);
|
||||
int load_upgrade(alpm_list_t *targets);
|
||||
/* trans.c */
|
||||
int do_transaction(targets_t *targets);
|
||||
|
||||
|
||||
#endif /* PM_PACMAN_H */
|
||||
|
||||
@@ -315,6 +315,9 @@ static int display(alpm_pkg_t *pkg)
|
||||
if(config->op_q_list) {
|
||||
dump_pkg_files(pkg, config->quiet);
|
||||
}
|
||||
if(config->op_q_backup) {
|
||||
dump_pkg_backups(pkg, config->quiet, config->op_q_backup != 1);
|
||||
}
|
||||
if(config->op_q_changelog) {
|
||||
dump_pkg_changelog(pkg);
|
||||
}
|
||||
@@ -325,13 +328,19 @@ static int display(alpm_pkg_t *pkg)
|
||||
ret = check_pkg_full(pkg);
|
||||
}
|
||||
}
|
||||
if(!config->op_q_info && !config->op_q_list
|
||||
&& !config->op_q_changelog && !config->op_q_check) {
|
||||
if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog
|
||||
&& !config->op_q_check && !config->op_q_backup) {
|
||||
if(!config->quiet) {
|
||||
const colstr_t *colstr = &config->colstr;
|
||||
char *note = alpm_pkg_get_note(pkg);
|
||||
|
||||
printf("%s%s %s%s%s", colstr->title, alpm_pkg_get_name(pkg),
|
||||
colstr->version, alpm_pkg_get_version(pkg), colstr->nocolor);
|
||||
|
||||
if(note) {
|
||||
printf(" (%s)", note);
|
||||
}
|
||||
|
||||
if(config->op_q_upgrade) {
|
||||
int usage;
|
||||
alpm_pkg_t *newpkg = alpm_sync_get_new_version(pkg, alpm_get_syncdbs(config->handle));
|
||||
@@ -431,7 +440,7 @@ int pacman_query(alpm_list_t *targets)
|
||||
db_local = alpm_get_localdb(config->handle);
|
||||
|
||||
/* operations on all packages in the local DB
|
||||
* valid: no-op (plain -Q), list, info, check
|
||||
* valid: no-op (plain -Q), list, info, check, backup
|
||||
* invalid: isfile, owns */
|
||||
if(targets == NULL) {
|
||||
if(config->op_q_isfile || config->op_q_owns) {
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -30,11 +29,6 @@
|
||||
#include "util.h"
|
||||
#include "conf.h"
|
||||
|
||||
static int fnmatch_cmp(const void *pattern, const void *string)
|
||||
{
|
||||
return fnmatch(pattern, string, 0);
|
||||
}
|
||||
|
||||
static int remove_target(const char *target)
|
||||
{
|
||||
alpm_pkg_t *pkg;
|
||||
@@ -69,28 +63,16 @@ static int remove_target(const char *target)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a specified list of packages.
|
||||
*
|
||||
* @param targets a list of packages (as strings) to remove from the system
|
||||
*
|
||||
* @return 0 on success, 1 on failure
|
||||
*/
|
||||
int pacman_remove(alpm_list_t *targets)
|
||||
int load_remove(alpm_list_t *targets)
|
||||
{
|
||||
int retval = 0;
|
||||
alpm_list_t *i, *data = NULL;
|
||||
alpm_list_t *i;
|
||||
|
||||
if(targets == NULL) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Step 0: create a new transaction */
|
||||
if(trans_init(config->flags, 0) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Step 1: add targets to the created transaction */
|
||||
for(i = targets; i; i = alpm_list_next(i)) {
|
||||
char *target = i->data;
|
||||
@@ -102,81 +84,6 @@ int pacman_remove(alpm_list_t *targets)
|
||||
}
|
||||
}
|
||||
|
||||
if(retval == 1) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Step 2: prepare the transaction based on its type, targets and flags */
|
||||
if(alpm_trans_prepare(config->handle, &data) == -1) {
|
||||
alpm_errno_t err = alpm_errno(config->handle);
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
|
||||
alpm_strerror(err));
|
||||
switch(err) {
|
||||
case ALPM_ERR_UNSATISFIED_DEPS:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
alpm_depmissing_t *miss = i->data;
|
||||
char *depstring = alpm_dep_compute_string(miss->depend);
|
||||
colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
|
||||
miss->causingpkg, depstring, miss->target);
|
||||
free(depstring);
|
||||
alpm_depmissing_free(miss);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
alpm_list_free(data);
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Search for holdpkg in target list */
|
||||
int holdpkg = 0;
|
||||
for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
|
||||
pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
|
||||
alpm_pkg_get_name(pkg));
|
||||
holdpkg = 1;
|
||||
}
|
||||
}
|
||||
if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Step 3: actually perform the removal */
|
||||
alpm_list_t *pkglist = alpm_trans_get_remove(config->handle);
|
||||
if(pkglist == NULL) {
|
||||
printf(_(" there is nothing to do\n"));
|
||||
goto cleanup; /* we are done */
|
||||
}
|
||||
|
||||
if(config->print) {
|
||||
print_packages(pkglist);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* print targets and ask user confirmation */
|
||||
display_targets();
|
||||
printf("\n");
|
||||
if(yesno(_("Do you want to remove these packages?")) == 0) {
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(alpm_trans_commit(config->handle, &data) == -1) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
|
||||
alpm_strerror(alpm_errno(config->handle)));
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
FREELIST(data);
|
||||
|
||||
/* Step 4: release transaction resources */
|
||||
cleanup:
|
||||
if(trans_release() == -1) {
|
||||
retval = 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "pacman.h"
|
||||
#include "util.h"
|
||||
#include "package.h"
|
||||
#include "callback.h"
|
||||
#include "conf.h"
|
||||
|
||||
static int unlink_verbose(const char *pathname, int ignore_missing)
|
||||
@@ -510,376 +509,6 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static alpm_db_t *get_db(const char *dbname)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
|
||||
alpm_db_t *db = i->data;
|
||||
if(strcmp(alpm_db_get_name(db), dbname) == 0) {
|
||||
return db;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int process_pkg(alpm_pkg_t *pkg)
|
||||
{
|
||||
int ret = alpm_add_pkg(config->handle, pkg);
|
||||
|
||||
if(ret == -1) {
|
||||
alpm_errno_t err = alpm_errno(config->handle);
|
||||
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), alpm_strerror(err));
|
||||
return 1;
|
||||
}
|
||||
config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int group_exists(alpm_list_t *dbs, const char *name)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
for(i = dbs; i; i = i->next) {
|
||||
alpm_db_t *db = i->data;
|
||||
|
||||
if(alpm_db_get_group(db, name)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_group(alpm_list_t *dbs, const char *group, int error)
|
||||
{
|
||||
int ret = 0;
|
||||
alpm_list_t *i;
|
||||
alpm_list_t *pkgs = alpm_find_group_pkgs(dbs, group);
|
||||
int count = alpm_list_count(pkgs);
|
||||
|
||||
if(!count) {
|
||||
if(group_exists(dbs, group)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), group);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(error) {
|
||||
/* we already know another target errored. there is no reason to prompt the
|
||||
* user here; we already validated the group name so just move on since we
|
||||
* won't actually be installing anything anyway. */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(config->print == 0) {
|
||||
char *array = malloc(count);
|
||||
int n = 0;
|
||||
const colstr_t *colstr = &config->colstr;
|
||||
colon_printf(_n("There is %d member in group %s%s%s:\n",
|
||||
"There are %d members in group %s%s%s:\n", count),
|
||||
count, colstr->groups, group, colstr->title);
|
||||
select_display(pkgs);
|
||||
if(!array) {
|
||||
ret = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
if(multiselect_question(array, count)) {
|
||||
ret = 1;
|
||||
free(array);
|
||||
goto cleanup;
|
||||
}
|
||||
for(i = pkgs, n = 0; i; i = alpm_list_next(i)) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
|
||||
if(array[n++] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(process_pkg(pkg) == 1) {
|
||||
ret = 1;
|
||||
free(array);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
free(array);
|
||||
} else {
|
||||
for(i = pkgs; i; i = alpm_list_next(i)) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
|
||||
if(process_pkg(pkg) == 1) {
|
||||
ret = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
alpm_list_free(pkgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int process_targname(alpm_list_t *dblist, const char *targname,
|
||||
int error)
|
||||
{
|
||||
alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
|
||||
|
||||
/* skip ignored packages when user says no */
|
||||
if(alpm_errno(config->handle) == ALPM_ERR_PKG_IGNORED) {
|
||||
pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), targname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pkg) {
|
||||
return process_pkg(pkg);
|
||||
}
|
||||
/* fallback on group */
|
||||
return process_group(dblist, targname, error);
|
||||
}
|
||||
|
||||
static int process_target(const char *target, int error)
|
||||
{
|
||||
/* process targets */
|
||||
char *targstring = strdup(target);
|
||||
char *targname = strchr(targstring, '/');
|
||||
int ret = 0;
|
||||
alpm_list_t *dblist;
|
||||
|
||||
if(targname && targname != targstring) {
|
||||
alpm_db_t *db;
|
||||
const char *dbname;
|
||||
int usage;
|
||||
|
||||
*targname = '\0';
|
||||
targname++;
|
||||
dbname = targstring;
|
||||
db = get_db(dbname);
|
||||
if(!db) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("database not found: %s\n"),
|
||||
dbname);
|
||||
ret = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* explicitly mark this repo as valid for installs since
|
||||
* a repo name was given with the target */
|
||||
alpm_db_get_usage(db, &usage);
|
||||
alpm_db_set_usage(db, usage|ALPM_DB_USAGE_INSTALL);
|
||||
|
||||
dblist = alpm_list_add(NULL, db);
|
||||
ret = process_targname(dblist, targname, error);
|
||||
alpm_list_free(dblist);
|
||||
|
||||
/* restore old usage so we don't possibly disturb later
|
||||
* targets */
|
||||
alpm_db_set_usage(db, usage);
|
||||
} else {
|
||||
targname = targstring;
|
||||
dblist = alpm_get_syncdbs(config->handle);
|
||||
ret = process_targname(dblist, targname, error);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(targstring);
|
||||
if(ret && access(target, R_OK) == 0) {
|
||||
pm_printf(ALPM_LOG_WARNING,
|
||||
_("'%s' is a file, did you mean %s instead of %s?\n"),
|
||||
target, "-U/--upgrade", "-S/--sync");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sync_trans(alpm_list_t *targets)
|
||||
{
|
||||
int retval = 0;
|
||||
alpm_list_t *i;
|
||||
|
||||
/* Step 1: create a new transaction... */
|
||||
if(trans_init(config->flags, 1) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* process targets */
|
||||
for(i = targets; i; i = alpm_list_next(i)) {
|
||||
const char *targ = i->data;
|
||||
if(process_target(targ, retval) == 1) {
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(retval) {
|
||||
trans_release();
|
||||
return retval;
|
||||
}
|
||||
|
||||
if(config->op_s_upgrade) {
|
||||
if(!config->print) {
|
||||
colon_printf(_("Starting full system upgrade...\n"));
|
||||
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
|
||||
"starting full system upgrade\n");
|
||||
}
|
||||
if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
|
||||
pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
|
||||
trans_release();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return sync_prepare_execute();
|
||||
}
|
||||
|
||||
static void print_broken_dep(alpm_depmissing_t *miss)
|
||||
{
|
||||
char *depstring = alpm_dep_compute_string(miss->depend);
|
||||
alpm_list_t *trans_add = alpm_trans_get_add(config->handle);
|
||||
alpm_pkg_t *pkg;
|
||||
if(miss->causingpkg == NULL) {
|
||||
/* package being installed/upgraded has unresolved dependency */
|
||||
colon_printf(_("unable to satisfy dependency '%s' required by %s\n"),
|
||||
depstring, miss->target);
|
||||
} else if((pkg = alpm_pkg_find(trans_add, miss->causingpkg))) {
|
||||
/* upgrading a package breaks a local dependency */
|
||||
colon_printf(_("installing %s (%s) breaks dependency '%s' required by %s\n"),
|
||||
miss->causingpkg, alpm_pkg_get_version(pkg), depstring, miss->target);
|
||||
} else {
|
||||
/* removing a package breaks a local dependency */
|
||||
colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
|
||||
miss->causingpkg, depstring, miss->target);
|
||||
}
|
||||
free(depstring);
|
||||
}
|
||||
|
||||
int sync_prepare_execute(void)
|
||||
{
|
||||
alpm_list_t *i, *packages, *data = NULL;
|
||||
int retval = 0;
|
||||
|
||||
/* Step 2: "compute" the transaction based on targets and flags */
|
||||
if(alpm_trans_prepare(config->handle, &data) == -1) {
|
||||
alpm_errno_t err = alpm_errno(config->handle);
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
|
||||
alpm_strerror(err));
|
||||
switch(err) {
|
||||
case ALPM_ERR_PKG_INVALID_ARCH:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
char *pkg = i->data;
|
||||
colon_printf(_("package %s does not have a valid architecture\n"), pkg);
|
||||
free(pkg);
|
||||
}
|
||||
break;
|
||||
case ALPM_ERR_UNSATISFIED_DEPS:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
print_broken_dep(i->data);
|
||||
alpm_depmissing_free(i->data);
|
||||
}
|
||||
break;
|
||||
case ALPM_ERR_CONFLICTING_DEPS:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
alpm_conflict_t *conflict = i->data;
|
||||
/* only print reason if it contains new information */
|
||||
if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
|
||||
colon_printf(_("%s and %s are in conflict\n"),
|
||||
conflict->package1, conflict->package2);
|
||||
} else {
|
||||
char *reason = alpm_dep_compute_string(conflict->reason);
|
||||
colon_printf(_("%s and %s are in conflict (%s)\n"),
|
||||
conflict->package1, conflict->package2, reason);
|
||||
free(reason);
|
||||
}
|
||||
alpm_conflict_free(conflict);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
packages = alpm_trans_get_add(config->handle);
|
||||
if(packages == NULL) {
|
||||
/* nothing to do: just exit without complaining */
|
||||
if(!config->print) {
|
||||
printf(_(" there is nothing to do\n"));
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Step 3: actually perform the operation */
|
||||
if(config->print) {
|
||||
print_packages(packages);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
display_targets();
|
||||
printf("\n");
|
||||
|
||||
int confirm;
|
||||
if(config->op_s_downloadonly) {
|
||||
confirm = yesno(_("Proceed with download?"));
|
||||
} else {
|
||||
confirm = yesno(_("Proceed with installation?"));
|
||||
}
|
||||
if(!confirm) {
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
multibar_move_completed_up(true);
|
||||
if(alpm_trans_commit(config->handle, &data) == -1) {
|
||||
alpm_errno_t err = alpm_errno(config->handle);
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
|
||||
alpm_strerror(err));
|
||||
switch(err) {
|
||||
case ALPM_ERR_FILE_CONFLICTS:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
alpm_fileconflict_t *conflict = i->data;
|
||||
switch(conflict->type) {
|
||||
case ALPM_FILECONFLICT_TARGET:
|
||||
printf(_("%s exists in both '%s' and '%s'\n"),
|
||||
conflict->file, conflict->target, conflict->ctarget);
|
||||
break;
|
||||
case ALPM_FILECONFLICT_FILESYSTEM:
|
||||
if(conflict->ctarget[0]) {
|
||||
printf(_("%s: %s exists in filesystem (owned by %s)\n"),
|
||||
conflict->target, conflict->file, conflict->ctarget);
|
||||
} else {
|
||||
printf(_("%s: %s exists in filesystem\n"),
|
||||
conflict->target, conflict->file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
alpm_fileconflict_free(conflict);
|
||||
}
|
||||
break;
|
||||
case ALPM_ERR_PKG_INVALID:
|
||||
case ALPM_ERR_PKG_INVALID_CHECKSUM:
|
||||
case ALPM_ERR_PKG_INVALID_SIG:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
char *filename = i->data;
|
||||
printf(_("%s is invalid or corrupted\n"), filename);
|
||||
free(filename);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* TODO: stderr? */
|
||||
printf(_("Errors occurred, no packages were upgraded.\n"));
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Step 4: release transaction resources */
|
||||
cleanup:
|
||||
alpm_list_free(data);
|
||||
if(trans_release() == -1) {
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int pacman_sync(alpm_list_t *targets)
|
||||
{
|
||||
alpm_list_t *sync_dbs = NULL;
|
||||
@@ -902,26 +531,8 @@ int pacman_sync(alpm_list_t *targets)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(check_syncdbs(1, 0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sync_dbs = alpm_get_syncdbs(config->handle);
|
||||
|
||||
if(config->op_s_sync) {
|
||||
/* grab a fresh package list */
|
||||
colon_printf(_("Synchronizing package databases...\n"));
|
||||
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
|
||||
"synchronizing package lists\n");
|
||||
if(!sync_syncdbs(config->op_s_sync, sync_dbs)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(check_syncdbs(1, 1)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* search for a package */
|
||||
if(config->op_s_search) {
|
||||
return sync_search(sync_dbs, targets);
|
||||
@@ -943,17 +554,9 @@ int pacman_sync(alpm_list_t *targets)
|
||||
}
|
||||
|
||||
if(targets == NULL) {
|
||||
if(config->op_s_upgrade) {
|
||||
/* proceed */
|
||||
} else if(config->op_s_sync) {
|
||||
return 0;
|
||||
} else {
|
||||
/* don't proceed here unless we have an operation that doesn't require a
|
||||
* target list */
|
||||
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
|
||||
return 1;
|
||||
}
|
||||
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return sync_trans(targets);
|
||||
return 0;
|
||||
}
|
||||
|
||||
478
src/pacman/trans.c
Normal file
478
src/pacman/trans.c
Normal file
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* upgrade.c
|
||||
*
|
||||
* Copyright (c) 2006-2021 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include <alpm.h>
|
||||
#include <alpm_list.h>
|
||||
|
||||
/* pacman */
|
||||
#include "pacman.h"
|
||||
#include "callback.h"
|
||||
#include "conf.h"
|
||||
#include "util.h"
|
||||
|
||||
static int fnmatch_cmp(const void *pattern, const void *string)
|
||||
{
|
||||
return fnmatch(pattern, string, 0);
|
||||
}
|
||||
|
||||
static void print_broken_dep(alpm_depmissing_t *miss)
|
||||
{
|
||||
char *depstring = alpm_dep_compute_string(miss->depend);
|
||||
alpm_list_t *trans_add = alpm_trans_get_add(config->handle);
|
||||
alpm_pkg_t *pkg;
|
||||
if(miss->causingpkg == NULL) {
|
||||
/* package being installed/upgraded has unresolved dependency */
|
||||
colon_printf(_("unable to satisfy dependency '%s' required by %s\n"),
|
||||
depstring, miss->target);
|
||||
} else if((pkg = alpm_pkg_find(trans_add, miss->causingpkg))) {
|
||||
/* upgrading a package breaks a local dependency */
|
||||
colon_printf(_("installing %s (%s) breaks dependency '%s' required by %s\n"),
|
||||
miss->causingpkg, alpm_pkg_get_version(pkg), depstring, miss->target);
|
||||
} else {
|
||||
/* removing a package breaks a local dependency */
|
||||
colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
|
||||
miss->causingpkg, depstring, miss->target);
|
||||
}
|
||||
free(depstring);
|
||||
}
|
||||
|
||||
static int sync_prepare_execute(void)
|
||||
{
|
||||
alpm_list_t *i, *packages, *remove_packages, *data = NULL;
|
||||
int retval = 0;
|
||||
|
||||
/* Step 2: "compute" the transaction based on targets and flags */
|
||||
if(alpm_trans_prepare(config->handle, &data) == -1) {
|
||||
alpm_errno_t err = alpm_errno(config->handle);
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
|
||||
alpm_strerror(err));
|
||||
switch(err) {
|
||||
case ALPM_ERR_PKG_INVALID_ARCH:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
char *pkg = i->data;
|
||||
colon_printf(_("package %s does not have a valid architecture\n"), pkg);
|
||||
free(pkg);
|
||||
}
|
||||
break;
|
||||
case ALPM_ERR_UNSATISFIED_DEPS:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
print_broken_dep(i->data);
|
||||
alpm_depmissing_free(i->data);
|
||||
}
|
||||
break;
|
||||
case ALPM_ERR_CONFLICTING_DEPS:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
alpm_conflict_t *conflict = i->data;
|
||||
/* only print reason if it contains new information */
|
||||
if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
|
||||
colon_printf(_("%s and %s are in conflict\n"),
|
||||
conflict->package1, conflict->package2);
|
||||
} else {
|
||||
char *reason = alpm_dep_compute_string(conflict->reason);
|
||||
colon_printf(_("%s and %s are in conflict (%s)\n"),
|
||||
conflict->package1, conflict->package2, reason);
|
||||
free(reason);
|
||||
}
|
||||
alpm_conflict_free(conflict);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
packages = alpm_trans_get_add(config->handle);
|
||||
remove_packages = alpm_trans_get_remove(config->handle);
|
||||
|
||||
if(packages == NULL && remove_packages == NULL) {
|
||||
/* nothing to do: just exit without complaining */
|
||||
if(!config->print) {
|
||||
printf(_(" there is nothing to do\n"));
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/* Search for holdpkg in target list */
|
||||
int holdpkg = 0;
|
||||
for(i = remove_packages; i; i = alpm_list_next(i)) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
|
||||
pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
|
||||
alpm_pkg_get_name(pkg));
|
||||
holdpkg = 1;
|
||||
}
|
||||
}
|
||||
if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Step 3: actually perform the operation */
|
||||
if(config->print) {
|
||||
print_packages(packages);
|
||||
print_packages(remove_packages);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
display_targets();
|
||||
printf("\n");
|
||||
|
||||
int confirm;
|
||||
if(config->op_s_downloadonly) {
|
||||
confirm = yesno(_("Proceed with download?"));
|
||||
} else {
|
||||
confirm = yesno(_("Proceed with installation?"));
|
||||
}
|
||||
if(!confirm) {
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
multibar_move_completed_up(true);
|
||||
if(alpm_trans_commit(config->handle, &data) == -1) {
|
||||
alpm_errno_t err = alpm_errno(config->handle);
|
||||
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
|
||||
alpm_strerror(err));
|
||||
switch(err) {
|
||||
case ALPM_ERR_FILE_CONFLICTS:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
alpm_fileconflict_t *conflict = i->data;
|
||||
switch(conflict->type) {
|
||||
case ALPM_FILECONFLICT_TARGET:
|
||||
printf(_("%s exists in both '%s' and '%s'\n"),
|
||||
conflict->file, conflict->target, conflict->ctarget);
|
||||
break;
|
||||
case ALPM_FILECONFLICT_FILESYSTEM:
|
||||
if(conflict->ctarget[0]) {
|
||||
printf(_("%s: %s exists in filesystem (owned by %s)\n"),
|
||||
conflict->target, conflict->file, conflict->ctarget);
|
||||
} else {
|
||||
printf(_("%s: %s exists in filesystem\n"),
|
||||
conflict->target, conflict->file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
alpm_fileconflict_free(conflict);
|
||||
}
|
||||
break;
|
||||
case ALPM_ERR_PKG_INVALID:
|
||||
case ALPM_ERR_PKG_INVALID_CHECKSUM:
|
||||
case ALPM_ERR_PKG_INVALID_SIG:
|
||||
for(i = data; i; i = alpm_list_next(i)) {
|
||||
char *filename = i->data;
|
||||
printf(_("%s is invalid or corrupted\n"), filename);
|
||||
free(filename);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* TODO: stderr? */
|
||||
printf(_("Errors occurred, no packages were upgraded.\n"));
|
||||
retval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Step 4: release transaction resources */
|
||||
cleanup:
|
||||
alpm_list_free(data);
|
||||
if(trans_release() == -1) {
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int group_exists(alpm_list_t *dbs, const char *name)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
for(i = dbs; i; i = i->next) {
|
||||
alpm_db_t *db = i->data;
|
||||
|
||||
if(alpm_db_get_group(db, name)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static alpm_db_t *get_db(const char *dbname)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
|
||||
alpm_db_t *db = i->data;
|
||||
if(strcmp(alpm_db_get_name(db), dbname) == 0) {
|
||||
return db;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int process_pkg(alpm_pkg_t *pkg)
|
||||
{
|
||||
int ret = alpm_add_pkg(config->handle, pkg);
|
||||
|
||||
if(ret == -1) {
|
||||
alpm_errno_t err = alpm_errno(config->handle);
|
||||
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), alpm_strerror(err));
|
||||
return 1;
|
||||
}
|
||||
config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_group(alpm_list_t *dbs, const char *group, int error)
|
||||
{
|
||||
int ret = 0;
|
||||
alpm_list_t *i;
|
||||
alpm_list_t *pkgs = alpm_find_group_pkgs(dbs, group);
|
||||
int count = alpm_list_count(pkgs);
|
||||
|
||||
if(!count) {
|
||||
if(group_exists(dbs, group)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), group);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(error) {
|
||||
/* we already know another target errored. there is no reason to prompt the
|
||||
* user here; we already validated the group name so just move on since we
|
||||
* won't actually be installing anything anyway. */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(config->print == 0) {
|
||||
char *array = malloc(count);
|
||||
int n = 0;
|
||||
const colstr_t *colstr = &config->colstr;
|
||||
colon_printf(_n("There is %d member in group %s%s%s:\n",
|
||||
"There are %d members in group %s%s%s:\n", count),
|
||||
count, colstr->groups, group, colstr->title);
|
||||
select_display(pkgs);
|
||||
if(!array) {
|
||||
ret = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
if(multiselect_question(array, count)) {
|
||||
ret = 1;
|
||||
free(array);
|
||||
goto cleanup;
|
||||
}
|
||||
for(i = pkgs, n = 0; i; i = alpm_list_next(i)) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
|
||||
if(array[n++] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(process_pkg(pkg) == 1) {
|
||||
ret = 1;
|
||||
free(array);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
free(array);
|
||||
} else {
|
||||
for(i = pkgs; i; i = alpm_list_next(i)) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
|
||||
if(process_pkg(pkg) == 1) {
|
||||
ret = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
alpm_list_free(pkgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int process_targname(alpm_list_t *dblist, const char *targname,
|
||||
int error)
|
||||
{
|
||||
alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
|
||||
|
||||
/* skip ignored packages when user says no */
|
||||
if(alpm_errno(config->handle) == ALPM_ERR_PKG_IGNORED) {
|
||||
pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), targname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pkg) {
|
||||
return process_pkg(pkg);
|
||||
}
|
||||
/* fallback on group */
|
||||
return process_group(dblist, targname, error);
|
||||
}
|
||||
|
||||
static int process_target(const char *target, int error)
|
||||
{
|
||||
/* process targets */
|
||||
char *targstring = strdup(target);
|
||||
char *targname = strchr(targstring, '/');
|
||||
int ret = 0;
|
||||
alpm_list_t *dblist;
|
||||
|
||||
if(targname && targname != targstring) {
|
||||
alpm_db_t *db;
|
||||
const char *dbname;
|
||||
int usage;
|
||||
|
||||
*targname = '\0';
|
||||
targname++;
|
||||
dbname = targstring;
|
||||
db = get_db(dbname);
|
||||
if(!db) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("database not found: %s\n"),
|
||||
dbname);
|
||||
ret = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* explicitly mark this repo as valid for installs since
|
||||
* a repo name was given with the target */
|
||||
alpm_db_get_usage(db, &usage);
|
||||
alpm_db_set_usage(db, usage|ALPM_DB_USAGE_INSTALL);
|
||||
|
||||
dblist = alpm_list_add(NULL, db);
|
||||
ret = process_targname(dblist, targname, error);
|
||||
alpm_list_free(dblist);
|
||||
|
||||
/* restore old usage so we don't possibly disturb later
|
||||
* targets */
|
||||
alpm_db_set_usage(db, usage);
|
||||
} else {
|
||||
targname = targstring;
|
||||
dblist = alpm_get_syncdbs(config->handle);
|
||||
ret = process_targname(dblist, targname, error);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(targstring);
|
||||
if(ret && access(target, R_OK) == 0) {
|
||||
pm_printf(ALPM_LOG_WARNING,
|
||||
_("'%s' is a file, did you mean %s instead of %s?\n"),
|
||||
target, "-U/--upgrade", "-S/--sync");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_sync(alpm_list_t *targets)
|
||||
{
|
||||
int retval = 0;
|
||||
alpm_list_t *i;
|
||||
|
||||
if(targets == NULL && !config->op_s_upgrade && !config->op_s_sync) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* process targets */
|
||||
for(i = targets; i; i = alpm_list_next(i)) {
|
||||
const char *targ = i->data;
|
||||
if(process_target(targ, retval) == 1) {
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int do_transaction(targets_t *targets) {
|
||||
int need_repos = (config->op & PM_OP_SYNC);
|
||||
alpm_list_t *sync_dbs;
|
||||
|
||||
if(targets->targets != NULL) {
|
||||
pm_printf(ALPM_LOG_ERROR, _("targets must come after operation\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(check_syncdbs(need_repos, 0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sync_dbs = alpm_get_syncdbs(config->handle);
|
||||
|
||||
if(config->op_s_sync) {
|
||||
/* grab a fresh package list */
|
||||
colon_printf(_("Synchronizing package databases...\n"));
|
||||
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
|
||||
"synchronizing package lists\n");
|
||||
if(!sync_syncdbs(config->op_s_sync, sync_dbs)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(check_syncdbs(need_repos, 1)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(config->op_s_clean || config->op_s_search || config->op_s_info
|
||||
|| config->op_q_list || config->group) {
|
||||
return pacman_sync(targets->sync);
|
||||
}
|
||||
|
||||
/* Step 1: create a new transaction... */
|
||||
if(trans_init(config->flags, 1) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(config->op & PM_OP_SYNC && load_sync(targets->sync)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if(config->op & PM_OP_REMOVE && load_remove(targets->remove)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if(config->op & PM_OP_UPGRADE && load_upgrade(targets->upgrade)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(config->op_s_upgrade) {
|
||||
if(!config->print) {
|
||||
colon_printf(_("Starting full system upgrade...\n"));
|
||||
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
|
||||
"starting full system upgrade\n");
|
||||
}
|
||||
if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
|
||||
pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
|
||||
trans_release();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return sync_prepare_execute();
|
||||
|
||||
cleanup:
|
||||
trans_release();
|
||||
return 1;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ static int load_packages(alpm_list_t *targets, int siglevel)
|
||||
*
|
||||
* @return 0 on success, 1 on failure
|
||||
*/
|
||||
int pacman_upgrade(alpm_list_t *targets)
|
||||
int load_upgrade(alpm_list_t *targets)
|
||||
{
|
||||
int retval = 0;
|
||||
alpm_list_t *remote_targets = NULL, *fetched_files = NULL;
|
||||
@@ -88,38 +88,16 @@ int pacman_upgrade(alpm_list_t *targets)
|
||||
|
||||
if(remote_targets) {
|
||||
retval = alpm_fetch_pkgurl(config->handle, remote_targets, &fetched_files);
|
||||
if(retval) {
|
||||
goto fail_free;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 1: create a new transaction */
|
||||
if(trans_init(config->flags, 1) == -1) {
|
||||
retval = 1;
|
||||
goto fail_free;
|
||||
}
|
||||
|
||||
printf(_("loading packages...\n"));
|
||||
retval |= load_packages(local_targets, alpm_option_get_local_file_siglevel(config->handle));
|
||||
retval |= load_packages(fetched_files, alpm_option_get_remote_file_siglevel(config->handle));
|
||||
|
||||
if(retval) {
|
||||
goto fail_release;
|
||||
}
|
||||
|
||||
alpm_list_free(remote_targets);
|
||||
alpm_list_free(local_targets);
|
||||
FREELIST(fetched_files);
|
||||
|
||||
/* now that targets are resolved, we can hand it all off to the sync code */
|
||||
return sync_prepare_execute();
|
||||
|
||||
fail_release:
|
||||
trans_release();
|
||||
fail_free:
|
||||
alpm_list_free(remote_targets);
|
||||
alpm_list_free(local_targets);
|
||||
FREELIST(fetched_files);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,15 @@ int trans_init(int flags, int check_valid)
|
||||
trans_init_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(config->note) {
|
||||
ret = alpm_trans_set_note(config->handle, config->note);
|
||||
if(ret == -1) {
|
||||
trans_init_error();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -106,16 +115,17 @@ int needs_root(void)
|
||||
if(config->sysroot) {
|
||||
return 1;
|
||||
}
|
||||
if(config->op & PM_OP_SYNC) {
|
||||
return (config->op_s_clean || config->op_s_sync ||
|
||||
(!config->group && !config->op_s_info && !config->op_q_list &&
|
||||
!config->op_s_search && !config->print));
|
||||
}
|
||||
if(config->op & PM_OP_TRANS) {
|
||||
return !config->print;
|
||||
}
|
||||
switch(config->op) {
|
||||
case PM_OP_DATABASE:
|
||||
return !config->op_q_check;
|
||||
case PM_OP_UPGRADE:
|
||||
case PM_OP_REMOVE:
|
||||
return !config->print;
|
||||
case PM_OP_SYNC:
|
||||
return (config->op_s_clean || config->op_s_sync ||
|
||||
(!config->group && !config->op_s_info && !config->op_q_list &&
|
||||
!config->op_s_search && !config->print));
|
||||
case PM_OP_FILES:
|
||||
return config->op_s_sync;
|
||||
default:
|
||||
@@ -1146,16 +1156,6 @@ void print_packages(const alpm_list_t *packages)
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
char *string = strdup(config->print_format);
|
||||
char *temp = string;
|
||||
/* %a : arch */
|
||||
if(strstr(temp, "%a")) {
|
||||
const char *arch = alpm_pkg_get_arch(pkg);
|
||||
if(arch == NULL) {
|
||||
arch = "";
|
||||
}
|
||||
string = strreplace(temp, "%a", arch);
|
||||
free(temp);
|
||||
temp = string;
|
||||
}
|
||||
/* %n : pkgname */
|
||||
if(strstr(temp, "%n")) {
|
||||
string = strreplace(temp, "%n", alpm_pkg_get_name(pkg));
|
||||
|
||||
@@ -9,6 +9,8 @@ pacman_tests = [
|
||||
'tests/config002.py',
|
||||
'tests/database001.py',
|
||||
'tests/database002.py',
|
||||
'tests/database003.py',
|
||||
'tests/database004.py',
|
||||
'tests/database010.py',
|
||||
'tests/database011.py',
|
||||
'tests/database012.py',
|
||||
@@ -174,6 +176,7 @@ pacman_tests = [
|
||||
'tests/symlink020.py',
|
||||
'tests/symlink021.py',
|
||||
'tests/sync-failover-404-with-body.py',
|
||||
'tests/sync-keep-note.py',
|
||||
'tests/sync-install-assumeinstalled.py',
|
||||
'tests/sync-nodepversion01.py',
|
||||
'tests/sync-nodepversion02.py',
|
||||
@@ -181,6 +184,7 @@ pacman_tests = [
|
||||
'tests/sync-nodepversion04.py',
|
||||
'tests/sync-nodepversion05.py',
|
||||
'tests/sync-nodepversion06.py',
|
||||
'tests/sync-note-targets-only.py',
|
||||
'tests/sync-sysupgrade-print-replaced-packages.py',
|
||||
'tests/sync-update-assumeinstalled.py',
|
||||
'tests/sync-update-package-removing-required-provides.py',
|
||||
|
||||
@@ -121,6 +121,8 @@ class pmdb(object):
|
||||
pkg.groups = _getsection(fd)
|
||||
elif line == "%URL%":
|
||||
pkg.url = fd.readline().strip("\n")
|
||||
elif line == "%NOTE%":
|
||||
pkg.note = fd.readline().strip("\n")
|
||||
elif line == "%LICENSE%":
|
||||
pkg.license = _getsection(fd)
|
||||
elif line == "%ARCH%":
|
||||
@@ -208,6 +210,7 @@ class pmdb(object):
|
||||
make_section(data, "INSTALLDATE", pkg.installdate)
|
||||
make_section(data, "SIZE", pkg.size)
|
||||
make_section(data, "REASON", pkg.reason)
|
||||
make_section(data, "NOTE", pkg.note)
|
||||
else:
|
||||
make_section(data, "FILENAME", pkg.filename())
|
||||
make_section(data, "REPLACES", pkg.replaces)
|
||||
|
||||
@@ -34,6 +34,7 @@ class pmpkg(object):
|
||||
self.desc = ""
|
||||
self.groups = []
|
||||
self.url = ""
|
||||
self.note = ""
|
||||
self.license = []
|
||||
self.arch = ""
|
||||
self.builddate = ""
|
||||
@@ -71,6 +72,7 @@ class pmpkg(object):
|
||||
s.append("url: %s" % self.url)
|
||||
s.append("files: %s" % " ".join(self.files))
|
||||
s.append("reason: %d" % self.reason)
|
||||
s.append("note: %s" % self.note)
|
||||
return "\n".join(s)
|
||||
|
||||
def fullname(self):
|
||||
|
||||
@@ -108,6 +108,9 @@ class pmrule(object):
|
||||
if f.startswith(value + "\t"):
|
||||
success = 1
|
||||
break;
|
||||
elif case == "NOTE":
|
||||
if newpkg.note != value:
|
||||
success = 0
|
||||
else:
|
||||
tap.diag("PKG rule '%s' not found" % case)
|
||||
success = -1
|
||||
|
||||
@@ -322,7 +322,7 @@ class pmtest(object):
|
||||
self.result["success"] += 1
|
||||
else:
|
||||
self.result["fail"] += 1
|
||||
tap.ok(success, i)
|
||||
tap.ok(success == 1, i)
|
||||
|
||||
def configfile(self):
|
||||
return os.path.join(self.root, util.PACCONF)
|
||||
|
||||
10
test/pacman/tests/database003.py
Normal file
10
test/pacman/tests/database003.py
Normal file
@@ -0,0 +1,10 @@
|
||||
self.description = "-D --note :D"
|
||||
|
||||
lp = pmpkg("pkg")
|
||||
self.addpkg2db("local", lp)
|
||||
|
||||
self.args = "-D pkg --note :D"
|
||||
|
||||
self.addrule("PACMAN_RETCODE=0")
|
||||
self.addrule("PKG_EXIST=pkg")
|
||||
self.addrule("PKG_NOTE=pkg|:D")
|
||||
11
test/pacman/tests/database004.py
Normal file
11
test/pacman/tests/database004.py
Normal file
@@ -0,0 +1,11 @@
|
||||
self.description = "-D --rmnote"
|
||||
|
||||
lp = pmpkg("pkg")
|
||||
lp.note = "D:"
|
||||
self.addpkg2db("local", lp)
|
||||
|
||||
self.args = "-D pkg --rmnote"
|
||||
|
||||
self.addrule("PACMAN_RETCODE=0")
|
||||
self.addrule("PKG_EXIST=pkg")
|
||||
self.addrule("PKG_NOTE=pkg|")
|
||||
@@ -10,9 +10,9 @@ lp3 = pmpkg("pkg3")
|
||||
lp3.depends = [ "pkg1" ]
|
||||
self.addpkg2db("local", lp3)
|
||||
|
||||
self.args = "-Ru pkg1 pkg2"
|
||||
self.args = "-R --unneeded pkg1 pkg2"
|
||||
|
||||
self.addrule("PACMAN_RETCODE=0")
|
||||
self.addrule("PKG_EXIST=pkg1")
|
||||
self.addrule("!PKG_EXIST=pkg2")
|
||||
self.addrule("PKG_EXIST=pkg3")
|
||||
self.addrule("PKG_EXIST=pkg3")
|
||||
|
||||
14
test/pacman/tests/sync-keep-note.py
Normal file
14
test/pacman/tests/sync-keep-note.py
Normal file
@@ -0,0 +1,14 @@
|
||||
self.description = "Sync a package keeping the existing note"
|
||||
|
||||
sp = pmpkg("pkg")
|
||||
self.addpkg2db("sync", sp)
|
||||
|
||||
lp = pmpkg("pkg")
|
||||
lp.note = "this is a note"
|
||||
self.addpkg2db("local", lp)
|
||||
|
||||
self.args = "-S pkg"
|
||||
|
||||
self.addrule("PACMAN_RETCODE=0")
|
||||
self.addrule("PKG_EXIST=pkg")
|
||||
self.addrule("PKG_NOTE=pkg|this is a note")
|
||||
30
test/pacman/tests/sync-note-targets-only.py
Normal file
30
test/pacman/tests/sync-note-targets-only.py
Normal file
@@ -0,0 +1,30 @@
|
||||
self.description = "Make sure note is only set for targets"
|
||||
|
||||
sp1 = pmpkg("pkg1", "1.0-2")
|
||||
sp1.depends = ["pkg2"]
|
||||
|
||||
sp2 = pmpkg("pkg2")
|
||||
|
||||
sp3 = pmpkg("pkg3")
|
||||
sp3.depends = ["pkg4"]
|
||||
|
||||
sp4 = pmpkg("pkg4")
|
||||
|
||||
for p in sp1, sp2, sp3, sp4:
|
||||
self.addpkg2db("sync", p)
|
||||
|
||||
lp1 = pmpkg("pkg1")
|
||||
self.addpkg2db("local", lp1)
|
||||
|
||||
self.args = "-S pkg1 pkg3 --note aaaa"
|
||||
|
||||
self.addrule("PACMAN_RETCODE=0")
|
||||
self.addrule("PKG_EXIST=pkg1")
|
||||
self.addrule("PKG_EXIST=pkg2")
|
||||
self.addrule("PKG_EXIST=pkg3")
|
||||
self.addrule("PKG_EXIST=pkg4")
|
||||
|
||||
self.addrule("PKG_NOTE=pkg1|aaaa")
|
||||
self.addrule("PKG_NOTE=pkg2|")
|
||||
self.addrule("PKG_NOTE=pkg3|aaaa")
|
||||
self.addrule("PKG_NOTE=pkg4|")
|
||||
Reference in New Issue
Block a user