mirror of
				https://gitlab.archlinux.org/pacman/pacman.git
				synced 2025-11-04 01:14:41 +01:00 
			
		
		
		
	Compare commits
	
		
			10 Commits
		
	
	
		
			morganamil
			...
			allan/alte
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7175062526 | ||
| 
						 | 
					7ceee8805b | ||
| 
						 | 
					d21fb58da3 | ||
| 
						 | 
					5352367022 | ||
| 
						 | 
					5287cc7251 | ||
| 
						 | 
					fed522775d | ||
| 
						 | 
					b0a2fd75b2 | ||
| 
						 | 
					806ccd90ed | ||
| 
						 | 
					b242f5f24c | ||
| 
						 | 
					529e208f39 | 
@@ -27,7 +27,7 @@ arch:
 | 
			
		||||
arch-debug:
 | 
			
		||||
  extends: .arch-test
 | 
			
		||||
  script:
 | 
			
		||||
    - meson --buildtype=debug build
 | 
			
		||||
    - meson --buildtype=debug --werror build
 | 
			
		||||
    - ninja -C build
 | 
			
		||||
    - fakechroot meson test -C build
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,250 +0,0 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
 | 
			
		||||
# SPDX-License-Identifier: Unlicense
 | 
			
		||||
#
 | 
			
		||||
# Based on the template file provided by the 'YCM-Generator' project authored by
 | 
			
		||||
# Reuben D'Netto.
 | 
			
		||||
# Jiahui Xie has re-reformatted and expanded the original script in accordance
 | 
			
		||||
# to the requirements of the PEP 8 style guide and 'systemd' project,
 | 
			
		||||
# respectively.
 | 
			
		||||
#
 | 
			
		||||
# The original license is preserved as it is.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# This is free and unencumbered software released into the public domain.
 | 
			
		||||
#
 | 
			
		||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
 | 
			
		||||
# distribute this software, either in source code form or as a compiled
 | 
			
		||||
# binary, for any purpose, commercial or non-commercial, and by any
 | 
			
		||||
# means.
 | 
			
		||||
#
 | 
			
		||||
# In jurisdictions that recognize copyright laws, the author or authors
 | 
			
		||||
# of this software dedicate any and all copyright interest in the
 | 
			
		||||
# software to the public domain. We make this dedication for the benefit
 | 
			
		||||
# of the public at large and to the detriment of our heirs and
 | 
			
		||||
# successors. We intend this dedication to be an overt act of
 | 
			
		||||
# relinquishment in perpetuity of all present and future rights to this
 | 
			
		||||
# software under copyright law.
 | 
			
		||||
#
 | 
			
		||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
			
		||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
			
		||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
			
		||||
# OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#
 | 
			
		||||
# For more information, please refer to <http://unlicense.org/>
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
YouCompleteMe configuration file tailored to support the 'meson' build system
 | 
			
		||||
used by the 'systemd' project.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import glob
 | 
			
		||||
import os
 | 
			
		||||
import ycm_core
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SOURCE_EXTENSIONS = (".C", ".cpp", ".cxx", ".cc", ".c", ".m", ".mm")
 | 
			
		||||
HEADER_EXTENSIONS = (".H", ".h", ".hxx", ".hpp", ".hh")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def DirectoryOfThisScript():
 | 
			
		||||
    """
 | 
			
		||||
    Return the absolute path of the parent directory containing this
 | 
			
		||||
    script.
 | 
			
		||||
    """
 | 
			
		||||
    return os.path.dirname(os.path.abspath(__file__))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def GuessBuildDirectory():
 | 
			
		||||
    """
 | 
			
		||||
    Guess the build directory using the following heuristics:
 | 
			
		||||
 | 
			
		||||
    1. Returns the current directory of this script plus 'build'
 | 
			
		||||
    subdirectory in absolute path if this subdirectory exists.
 | 
			
		||||
 | 
			
		||||
    2. Otherwise, probes whether there exists any directory
 | 
			
		||||
    containing '.ninja_log' file two levels above the current directory;
 | 
			
		||||
    returns this single directory only if there is one candidate.
 | 
			
		||||
    """
 | 
			
		||||
    result = os.path.join(DirectoryOfThisScript(), "build")
 | 
			
		||||
 | 
			
		||||
    if os.path.exists(result):
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    result = glob.glob(os.path.join(DirectoryOfThisScript(),
 | 
			
		||||
                                    "..", "..", "*", ".ninja_log"))
 | 
			
		||||
 | 
			
		||||
    if not result:
 | 
			
		||||
        return ""
 | 
			
		||||
 | 
			
		||||
    if 1 != len(result):
 | 
			
		||||
        return ""
 | 
			
		||||
 | 
			
		||||
    return os.path.split(result[0])[0]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def TraverseByDepth(root, include_extensions):
 | 
			
		||||
    """
 | 
			
		||||
    Return a set of child directories of the 'root' containing file
 | 
			
		||||
    extensions specified in 'include_extensions'.
 | 
			
		||||
 | 
			
		||||
    NOTE:
 | 
			
		||||
        1. The 'root' directory itself is excluded from the result set.
 | 
			
		||||
        2. No subdirectories would be excluded if 'include_extensions' is left
 | 
			
		||||
           to 'None'.
 | 
			
		||||
        3. Each entry in 'include_extensions' must begin with string '.'.
 | 
			
		||||
    """
 | 
			
		||||
    is_root = True
 | 
			
		||||
    result = set()
 | 
			
		||||
    # Perform a depth first top down traverse of the given directory tree.
 | 
			
		||||
    for root_dir, subdirs, file_list in os.walk(root):
 | 
			
		||||
        if not is_root:
 | 
			
		||||
            # print("Relative Root: ", root_dir)
 | 
			
		||||
            # print(subdirs)
 | 
			
		||||
            if include_extensions:
 | 
			
		||||
                get_ext = os.path.splitext
 | 
			
		||||
                subdir_extensions = {
 | 
			
		||||
                    get_ext(f)[-1] for f in file_list if get_ext(f)[-1]
 | 
			
		||||
                }
 | 
			
		||||
                if subdir_extensions & include_extensions:
 | 
			
		||||
                    result.add(root_dir)
 | 
			
		||||
            else:
 | 
			
		||||
                result.add(root_dir)
 | 
			
		||||
        else:
 | 
			
		||||
            is_root = False
 | 
			
		||||
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_project_src_dir = os.path.join(DirectoryOfThisScript(), "src")
 | 
			
		||||
_include_dirs_set = TraverseByDepth(_project_src_dir, frozenset({".h"}))
 | 
			
		||||
flags = [
 | 
			
		||||
    "-x",
 | 
			
		||||
    "c"
 | 
			
		||||
    # The following flags are partially redundant due to the existence of
 | 
			
		||||
    # 'compile_commands.json'.
 | 
			
		||||
    #    '-Wall',
 | 
			
		||||
    #    '-Wextra',
 | 
			
		||||
    #    '-Wfloat-equal',
 | 
			
		||||
    #    '-Wpointer-arith',
 | 
			
		||||
    #    '-Wshadow',
 | 
			
		||||
    #    '-std=gnu99',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
for include_dir in _include_dirs_set:
 | 
			
		||||
    flags.append("-I" + include_dir)
 | 
			
		||||
 | 
			
		||||
# Set this to the absolute path to the folder (NOT the file!) containing the
 | 
			
		||||
# compile_commands.json file to use that instead of 'flags'. See here for
 | 
			
		||||
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
 | 
			
		||||
#
 | 
			
		||||
# You can get CMake to generate this file for you by adding:
 | 
			
		||||
#   set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
 | 
			
		||||
# to your CMakeLists.txt file.
 | 
			
		||||
#
 | 
			
		||||
# Most projects will NOT need to set this to anything; you can just change the
 | 
			
		||||
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
 | 
			
		||||
compilation_database_folder = GuessBuildDirectory()
 | 
			
		||||
 | 
			
		||||
if os.path.exists(compilation_database_folder):
 | 
			
		||||
    database = ycm_core.CompilationDatabase(compilation_database_folder)
 | 
			
		||||
else:
 | 
			
		||||
    database = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
 | 
			
		||||
    """
 | 
			
		||||
    Iterate through 'flags' and replace the relative paths prefixed by
 | 
			
		||||
    '-isystem', '-I', '-iquote', '--sysroot=' with absolute paths
 | 
			
		||||
    start with 'working_directory'.
 | 
			
		||||
    """
 | 
			
		||||
    if not working_directory:
 | 
			
		||||
        return list(flags)
 | 
			
		||||
    new_flags = []
 | 
			
		||||
    make_next_absolute = False
 | 
			
		||||
    path_flags = ["-isystem", "-I", "-iquote", "--sysroot="]
 | 
			
		||||
    for flag in flags:
 | 
			
		||||
        new_flag = flag
 | 
			
		||||
 | 
			
		||||
        if make_next_absolute:
 | 
			
		||||
            make_next_absolute = False
 | 
			
		||||
            if not flag.startswith("/"):
 | 
			
		||||
                new_flag = os.path.join(working_directory, flag)
 | 
			
		||||
 | 
			
		||||
        for path_flag in path_flags:
 | 
			
		||||
            if flag == path_flag:
 | 
			
		||||
                make_next_absolute = True
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
            if flag.startswith(path_flag):
 | 
			
		||||
                path = flag[len(path_flag):]
 | 
			
		||||
                new_flag = path_flag + os.path.join(working_directory, path)
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
        if new_flag:
 | 
			
		||||
            new_flags.append(new_flag)
 | 
			
		||||
    return new_flags
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def IsHeaderFile(filename):
 | 
			
		||||
    """
 | 
			
		||||
    Check whether 'filename' is considered as a header file.
 | 
			
		||||
    """
 | 
			
		||||
    extension = os.path.splitext(filename)[1]
 | 
			
		||||
    return extension in HEADER_EXTENSIONS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def GetCompilationInfoForFile(filename):
 | 
			
		||||
    """
 | 
			
		||||
    Helper function to look up compilation info of 'filename' in the 'database'.
 | 
			
		||||
    """
 | 
			
		||||
    # The compilation_commands.json file generated by CMake does not have
 | 
			
		||||
    # entries for header files. So we do our best by asking the db for flags for
 | 
			
		||||
    # a corresponding source file, if any. If one exists, the flags for that
 | 
			
		||||
    # file should be good enough.
 | 
			
		||||
    if not database:
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    if IsHeaderFile(filename):
 | 
			
		||||
        basename = os.path.splitext(filename)[0]
 | 
			
		||||
        for extension in SOURCE_EXTENSIONS:
 | 
			
		||||
            replacement_file = basename + extension
 | 
			
		||||
            if os.path.exists(replacement_file):
 | 
			
		||||
                compilation_info = \
 | 
			
		||||
                    database.GetCompilationInfoForFile(replacement_file)
 | 
			
		||||
                if compilation_info.compiler_flags_:
 | 
			
		||||
                    return compilation_info
 | 
			
		||||
        return None
 | 
			
		||||
    return database.GetCompilationInfoForFile(filename)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def FlagsForFile(filename, **kwargs):
 | 
			
		||||
    """
 | 
			
		||||
    Callback function to be invoked by YouCompleteMe in order to get the
 | 
			
		||||
    information necessary to compile 'filename'.
 | 
			
		||||
 | 
			
		||||
    It returns a dictionary with a single element 'flags'. This element is a
 | 
			
		||||
    list of compiler flags to pass to libclang for the file 'filename'.
 | 
			
		||||
    """
 | 
			
		||||
    if database:
 | 
			
		||||
        # Bear in mind that compilation_info.compiler_flags_ does NOT return a
 | 
			
		||||
        # python list, but a "list-like" StringVec object
 | 
			
		||||
        compilation_info = GetCompilationInfoForFile(filename)
 | 
			
		||||
        if not compilation_info:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        final_flags = MakeRelativePathsInFlagsAbsolute(
 | 
			
		||||
            compilation_info.compiler_flags_,
 | 
			
		||||
            compilation_info.compiler_working_dir_)
 | 
			
		||||
 | 
			
		||||
    else:
 | 
			
		||||
        relative_to = DirectoryOfThisScript()
 | 
			
		||||
        final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to)
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        "flags": final_flags,
 | 
			
		||||
        "do_cache": True
 | 
			
		||||
    }
 | 
			
		||||
@@ -402,8 +402,8 @@ All options and directives for the split packages default to the global values
 | 
			
		||||
given in the PKGBUILD. Nevertheless, the following ones can be overridden within
 | 
			
		||||
each split package's packaging function:
 | 
			
		||||
`pkgdesc`, `arch`, `url`, `license`, `groups`, `depends`, `optdepends`,
 | 
			
		||||
`provides`, `conflicts`, `replaces`, `backup`, `options`, `install`, and
 | 
			
		||||
`changelog`.
 | 
			
		||||
`provides`, `conflicts`, `replaces`, `backup`, `options`, `install`,
 | 
			
		||||
`changelog` and `alternative`.
 | 
			
		||||
 | 
			
		||||
Note that makepkg does not consider split package `depends` when checking
 | 
			
		||||
if dependencies are installed before package building and with `--syncdeps`.
 | 
			
		||||
 
 | 
			
		||||
@@ -210,11 +210,6 @@ 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
 | 
			
		||||
@@ -261,12 +256,6 @@ 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
 | 
			
		||||
@@ -280,9 +269,6 @@ 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
 | 
			
		||||
@@ -378,9 +364,6 @@ 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]]
 | 
			
		||||
------------------------------------
 | 
			
		||||
@@ -389,6 +372,11 @@ 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
 | 
			
		||||
@@ -480,13 +468,6 @@ 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 -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'
 | 
			
		||||
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'
 | 
			
		||||
          'rsync::/usr/bin/rsync --no-motd -z %u %o'
 | 
			
		||||
          'scp::/usr/bin/scp -C %u %o')
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -431,22 +431,8 @@ 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,11 +101,6 @@ 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.
 | 
			
		||||
@@ -163,9 +158,6 @@ 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 */
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
@@ -1289,12 +1281,6 @@ 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
 | 
			
		||||
@@ -1458,42 +1444,6 @@ 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 */
 | 
			
		||||
/** @} */
 | 
			
		||||
@@ -2436,12 +2386,6 @@ 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
 | 
			
		||||
@@ -2485,12 +2429,6 @@ 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
 | 
			
		||||
@@ -2617,6 +2555,12 @@ alpm_filelist_t *alpm_pkg_get_files(alpm_pkg_t *pkg);
 | 
			
		||||
 */
 | 
			
		||||
alpm_list_t *alpm_pkg_get_backup(alpm_pkg_t *pkg);
 | 
			
		||||
 | 
			
		||||
/** Returns the list of alternatives provided by the package
 | 
			
		||||
 * @param pkg a pointer to package
 | 
			
		||||
 * @return a reference to a list of char* objects
 | 
			
		||||
 */
 | 
			
		||||
alpm_list_t *alpm_pkg_get_alternatives(alpm_pkg_t *pkg);
 | 
			
		||||
 | 
			
		||||
/** Returns the database containing pkg.
 | 
			
		||||
 * Returns a pointer to the alpm_db_t structure the package is
 | 
			
		||||
 * originating from, or NULL if the package was loaded from a file.
 | 
			
		||||
@@ -2669,15 +2613,6 @@ 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 */
 | 
			
		||||
/** @} */
 | 
			
		||||
@@ -2749,6 +2684,7 @@ int alpm_pkg_mtree_close(const alpm_pkg_t *pkg, struct archive *archive);
 | 
			
		||||
/* End of mtree accessors */
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* End of libalpm_packages */
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
@@ -2774,8 +2710,7 @@ 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,
 | 
			
		||||
	/** Don't keep backup files when installing packages. */
 | 
			
		||||
	ALPM_TRANS_FLAG_NOKEEP = (1 << 1),
 | 
			
		||||
	/* (1 << 1) flag can go here */
 | 
			
		||||
	/** Delete files even if they are tagged as backup. */
 | 
			
		||||
	ALPM_TRANS_FLAG_NOSAVE = (1 << 2),
 | 
			
		||||
	/** Ignore version numbers when checking dependencies. */
 | 
			
		||||
@@ -2827,16 +2762,6 @@ 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,12 +81,6 @@ 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);
 | 
			
		||||
@@ -201,6 +195,12 @@ static alpm_list_t *_cache_get_backup(alpm_pkg_t *pkg)
 | 
			
		||||
	return pkg->backup;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static alpm_list_t *_cache_get_alternatives(alpm_pkg_t *pkg)
 | 
			
		||||
{
 | 
			
		||||
	LAZY_LOAD(INFRQ_DESC);
 | 
			
		||||
	return pkg->alternatives;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Open a package changelog for reading. Similar to fopen in functionality,
 | 
			
		||||
 * except that the returned 'file stream' is from the database.
 | 
			
		||||
@@ -336,7 +336,6 @@ 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,
 | 
			
		||||
@@ -356,6 +355,7 @@ static const struct pkg_operations local_pkg_ops = {
 | 
			
		||||
	.get_replaces = _cache_get_replaces,
 | 
			
		||||
	.get_files = _cache_get_files,
 | 
			
		||||
	.get_backup = _cache_get_backup,
 | 
			
		||||
	.get_alternatives = _cache_get_alternatives,
 | 
			
		||||
 | 
			
		||||
	.changelog_open = _cache_changelog_open,
 | 
			
		||||
	.changelog_read = _cache_changelog_read,
 | 
			
		||||
@@ -759,8 +759,6 @@ 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) {
 | 
			
		||||
@@ -813,6 +811,8 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
 | 
			
		||||
				READ_AND_SPLITDEP(info->conflicts);
 | 
			
		||||
			} else if(strcmp(line, "%PROVIDES%") == 0) {
 | 
			
		||||
				READ_AND_SPLITDEP(info->provides);
 | 
			
		||||
			} else if(strcmp(line, "%ALTERNATIVES%") == 0) {
 | 
			
		||||
				READ_AND_STORE_ALL(info->alternatives);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
@@ -1049,9 +1049,13 @@ 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);
 | 
			
		||||
		if(info->alternatives) {
 | 
			
		||||
			fputs("%ALTERNATIVES%\n", fp);
 | 
			
		||||
			for(lp = info->alternatives; lp; lp = lp->next) {
 | 
			
		||||
				fputs(lp->data, fp);
 | 
			
		||||
				fputc('\n', fp);
 | 
			
		||||
			}
 | 
			
		||||
			fputc('\n', fp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
@@ -1172,31 +1176,6 @@ 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,
 | 
			
		||||
 
 | 
			
		||||
@@ -244,6 +244,8 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
 | 
			
		||||
				CALLOC(backup, 1, sizeof(alpm_backup_t), return -1);
 | 
			
		||||
				STRDUP(backup->name, ptr, FREE(backup); return -1);
 | 
			
		||||
				newpkg->backup = alpm_list_add(newpkg->backup, backup);
 | 
			
		||||
			} else if(strcmp(key, "alternative") == 0) {
 | 
			
		||||
				newpkg->alternatives = alpm_list_add(newpkg->alternatives, strdup(ptr));
 | 
			
		||||
			} else if(strcmp(key, "force") == 0) {
 | 
			
		||||
				/* deprecated, skip it */
 | 
			
		||||
			} else if(strcmp(key, "makepkgopt") == 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -566,7 +566,8 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0) {
 | 
			
		||||
	if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
 | 
			
		||||
			|| strcmp(filename, "files") == 0) {
 | 
			
		||||
		int ret;
 | 
			
		||||
		while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
 | 
			
		||||
			char *line = buf.line;
 | 
			
		||||
@@ -635,6 +636,36 @@ 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) {
 | 
			
		||||
@@ -685,152 +716,3 @@ 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,12 +212,6 @@ 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);
 | 
			
		||||
@@ -411,7 +405,6 @@ 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))) {
 | 
			
		||||
@@ -421,11 +414,6 @@ 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,13 +61,6 @@ 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,6 +427,9 @@ 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);
 | 
			
		||||
@@ -490,8 +493,8 @@ static int curl_check_finished_download(CURLM *curlm, CURLMsg *msg,
 | 
			
		||||
 | 
			
		||||
	curl_gethost(payload->fileurl, hostname, sizeof(hostname));
 | 
			
		||||
	curlerr = msg->data.result;
 | 
			
		||||
	_alpm_log(handle, ALPM_LOG_DEBUG, "%s: curl returned result %d from transfer\n",
 | 
			
		||||
			payload->remote_name, curlerr);
 | 
			
		||||
	_alpm_log(handle, ALPM_LOG_DEBUG, "%s: %s returned result %d from transfer\n",
 | 
			
		||||
			payload->remote_name, "curl", curlerr);
 | 
			
		||||
 | 
			
		||||
	/* was it a success? */
 | 
			
		||||
	switch(curlerr) {
 | 
			
		||||
 
 | 
			
		||||
@@ -145,17 +145,3 @@ 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,6 +28,5 @@ 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_cache_find_pkg(pkg, 0);
 | 
			
		||||
	fpath = _alpm_filecache_find(pkg->handle, pkg->filename);
 | 
			
		||||
 | 
			
		||||
	retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_PKG_VALIDATION_MD5SUM);
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +78,6 @@ 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,7 +98,7 @@ static alpm_list_t *_pkg_get_provides(alpm_pkg_t *pkg)   { return pkg->provides;
 | 
			
		||||
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 alpm_list_t *_pkg_get_alternatives(alpm_pkg_t *pkg) { return pkg->alternatives; }
 | 
			
		||||
 | 
			
		||||
static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg)
 | 
			
		||||
{
 | 
			
		||||
@@ -144,7 +143,6 @@ 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,
 | 
			
		||||
@@ -165,6 +163,7 @@ const struct pkg_operations default_pkg_ops = {
 | 
			
		||||
	.get_replaces    = _pkg_get_replaces,
 | 
			
		||||
	.get_files       = _pkg_get_files,
 | 
			
		||||
	.get_backup      = _pkg_get_backup,
 | 
			
		||||
	.get_alternatives = _pkg_get_alternatives,
 | 
			
		||||
 | 
			
		||||
	.changelog_open  = _pkg_changelog_open,
 | 
			
		||||
	.changelog_read  = _pkg_changelog_read,
 | 
			
		||||
@@ -194,13 +193,6 @@ 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);
 | 
			
		||||
@@ -236,13 +228,6 @@ 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);
 | 
			
		||||
@@ -300,7 +285,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_cache_find_pkg(pkg, 0);
 | 
			
		||||
		pkgpath = _alpm_filecache_find(pkg->handle, pkg->filename);
 | 
			
		||||
		if(!pkgpath) {
 | 
			
		||||
			GOTO_ERR(pkg->handle, ALPM_ERR_PKG_NOT_FOUND, cleanup);
 | 
			
		||||
		}
 | 
			
		||||
@@ -435,6 +420,13 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(alpm_pkg_t *pkg)
 | 
			
		||||
	return pkg->ops->get_backup(pkg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
alpm_list_t SYMEXPORT *alpm_pkg_get_alternatives(alpm_pkg_t *pkg)
 | 
			
		||||
{
 | 
			
		||||
	ASSERT(pkg != NULL, return NULL);
 | 
			
		||||
	pkg->handle->pm_errno = ALPM_ERR_OK;
 | 
			
		||||
	return pkg->ops->get_alternatives(pkg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg)
 | 
			
		||||
{
 | 
			
		||||
	/* Sanity checks */
 | 
			
		||||
@@ -627,7 +619,6 @@ 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);
 | 
			
		||||
@@ -650,6 +641,7 @@ int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr)
 | 
			
		||||
	newpkg->optdepends = list_depdup(pkg->optdepends);
 | 
			
		||||
	newpkg->conflicts  = list_depdup(pkg->conflicts);
 | 
			
		||||
	newpkg->provides   = list_depdup(pkg->provides);
 | 
			
		||||
	newpkg->alternatives = alpm_list_strdup(pkg->alternatives);
 | 
			
		||||
 | 
			
		||||
	if(pkg->files.count) {
 | 
			
		||||
		size_t filenum;
 | 
			
		||||
@@ -701,7 +693,6 @@ 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);
 | 
			
		||||
@@ -728,6 +719,7 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
 | 
			
		||||
	free_deplist(pkg->provides);
 | 
			
		||||
	alpm_list_free(pkg->removes);
 | 
			
		||||
	_alpm_pkg_free(pkg->oldpkg);
 | 
			
		||||
	FREELIST(pkg->alternatives);
 | 
			
		||||
 | 
			
		||||
	if(pkg->origin == ALPM_PKG_FROM_FILE) {
 | 
			
		||||
		FREE(pkg->origin_data.file);
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,6 @@ 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 *);
 | 
			
		||||
@@ -67,6 +66,7 @@ struct pkg_operations {
 | 
			
		||||
	alpm_list_t *(*get_replaces) (alpm_pkg_t *);
 | 
			
		||||
	alpm_filelist_t *(*get_files) (alpm_pkg_t *);
 | 
			
		||||
	alpm_list_t *(*get_backup) (alpm_pkg_t *);
 | 
			
		||||
	alpm_list_t *(*get_alternatives) (alpm_pkg_t *);
 | 
			
		||||
 | 
			
		||||
	void *(*changelog_open) (alpm_pkg_t *);
 | 
			
		||||
	size_t (*changelog_read) (void *, size_t, const alpm_pkg_t *, void *);
 | 
			
		||||
@@ -94,7 +94,6 @@ struct _alpm_pkg_t {
 | 
			
		||||
	char *version;
 | 
			
		||||
	char *desc;
 | 
			
		||||
	char *url;
 | 
			
		||||
	char *note;
 | 
			
		||||
	char *packager;
 | 
			
		||||
	char *md5sum;
 | 
			
		||||
	char *sha256sum;
 | 
			
		||||
@@ -122,6 +121,7 @@ struct _alpm_pkg_t {
 | 
			
		||||
	alpm_list_t *provides;
 | 
			
		||||
	alpm_list_t *removes; /* in transaction targets only */
 | 
			
		||||
	alpm_pkg_t *oldpkg; /* in transaction targets only */
 | 
			
		||||
	alpm_list_t *alternatives;
 | 
			
		||||
 | 
			
		||||
	const struct pkg_operations *ops;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -575,9 +575,7 @@ 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)
 | 
			
		||||
		|| (!(handle->trans->flags & ALPM_TRANS_FLAG_NOKEEP)
 | 
			
		||||
				&& newpkg
 | 
			
		||||
				&& _alpm_needbackup(path, newpkg)
 | 
			
		||||
		|| (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_cache_find_pkg(newpkg, 0);
 | 
			
		||||
	fpath = _alpm_filecache_find(handle, fname);
 | 
			
		||||
 | 
			
		||||
	/* 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_cache_find_pkg(newpkg, 1);
 | 
			
		||||
	fpath = _alpm_filecache_find(handle, fnamepart);
 | 
			
		||||
	if(fpath) {
 | 
			
		||||
		struct stat st;
 | 
			
		||||
		if(stat(fpath, &st) == 0) {
 | 
			
		||||
@@ -732,18 +732,26 @@ 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_cache_pkg_exists(spkg, 0);
 | 
			
		||||
			need_download = spkg->download_size != 0 || !_alpm_filecache_exists(handle, spkg->filename);
 | 
			
		||||
			/* 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)) {
 | 
			
		||||
				need_download = !_alpm_cache_pkg_exists(spkg, 1);
 | 
			
		||||
				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);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(need_download) {
 | 
			
		||||
@@ -982,14 +990,7 @@ static int check_validity(alpm_handle_t *handle,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		current_bytes += v.pkg->size;
 | 
			
		||||
		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.path = _alpm_filecache_find(handle, v.pkg->filename);
 | 
			
		||||
		v.siglevel = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg));
 | 
			
		||||
 | 
			
		||||
		if(_alpm_pkg_validate_internal(handle, v.path, v.pkg,
 | 
			
		||||
@@ -1079,14 +1080,7 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		current_bytes += spkg->size;
 | 
			
		||||
 | 
			
		||||
		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);
 | 
			
		||||
		}
 | 
			
		||||
		filepath = _alpm_filecache_find(handle, spkg->filename);
 | 
			
		||||
 | 
			
		||||
		/* 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,8 +177,7 @@ 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 && !(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY)),
 | 
			
		||||
			RET_ERR(handle, ALPM_ERR_TRANS_NOT_LOCKED, -1));
 | 
			
		||||
	ASSERT(!(trans->flags & ALPM_TRANS_FLAG_NOLOCK), 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) {
 | 
			
		||||
@@ -299,7 +298,6 @@ 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);
 | 
			
		||||
 | 
			
		||||
@@ -452,19 +450,3 @@ 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,7 +39,6 @@ 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,37 +815,6 @@ 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
 | 
			
		||||
@@ -862,17 +831,10 @@ 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) {
 | 
			
		||||
			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));
 | 
			
		||||
		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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	/* package wasn't found in any cachedir */
 | 
			
		||||
@@ -884,10 +846,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_cache_pkg_exists(alpm_pkg_t *pkg, int sig)
 | 
			
		||||
int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename)
 | 
			
		||||
{
 | 
			
		||||
	int res;
 | 
			
		||||
	char *fpath = _alpm_cache_find_pkg(pkg, sig);
 | 
			
		||||
	char *fpath = _alpm_filecache_find(handle, filename);
 | 
			
		||||
	res = (fpath != NULL);
 | 
			
		||||
	FREE(fpath);
 | 
			
		||||
	return res;
 | 
			
		||||
 
 | 
			
		||||
@@ -133,10 +133,9 @@ 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_cache_pkg_exists(alpm_pkg_t *pkg, int sig);
 | 
			
		||||
int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename);
 | 
			
		||||
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. */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								scripts/libmakepkg/lint_pkgbuild/alternative.sh.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								scripts/libmakepkg/lint_pkgbuild/alternative.sh.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
#   alternative.sh - Check the files associated with the 'alternative'
 | 
			
		||||
#   array exist.
 | 
			
		||||
#
 | 
			
		||||
#   Copyright (c) 2020 Pacman Development Team <pacman-dev@archlinux.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/>.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_ALTERNATIVE_SH" ]] && return
 | 
			
		||||
LIBMAKEPKG_LINT_PKGBUILD_ALTERNATIVE_SH=1
 | 
			
		||||
 | 
			
		||||
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
 | 
			
		||||
 | 
			
		||||
source "$LIBRARY/util/message.sh"
 | 
			
		||||
source "$LIBRARY/util/pkgbuild.sh"
 | 
			
		||||
source "$LIBRARY/lint_pkgbuild/util.sh"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
lint_pkgbuild_functions+=('lint_alternative')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
lint_alternative() {
 | 
			
		||||
	local ret=0
 | 
			
		||||
 | 
			
		||||
	check_files_exist 'alternative' "${alternative[@]/%/.alternative}" || ret=1
 | 
			
		||||
 | 
			
		||||
	return $ret
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
libmakepkg_module = 'lint_pkgbuild'
 | 
			
		||||
 | 
			
		||||
sources = [
 | 
			
		||||
  'alternative.sh.in',
 | 
			
		||||
  'arch.sh.in',
 | 
			
		||||
  'arch_specific.sh.in',
 | 
			
		||||
  'backup.sh.in',
 | 
			
		||||
 
 | 
			
		||||
@@ -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,21 +95,3 @@ 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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,8 +28,8 @@ source "$LIBRARY/util/util.sh"
 | 
			
		||||
 | 
			
		||||
known_hash_algos=({ck,md5,sha{1,224,256,384,512},b2})
 | 
			
		||||
 | 
			
		||||
pkgbuild_schema_arrays=(arch backup checkdepends conflicts depends groups
 | 
			
		||||
                        license makedepends noextract optdepends options
 | 
			
		||||
pkgbuild_schema_arrays=(alternative arch backup checkdepends conflicts depends
 | 
			
		||||
                        groups license makedepends noextract optdepends options
 | 
			
		||||
                        provides replaces source validpgpkeys
 | 
			
		||||
                        "${known_hash_algos[@]/%/sums}")
 | 
			
		||||
 | 
			
		||||
@@ -42,7 +42,7 @@ pkgbuild_schema_arch_arrays=(checkdepends conflicts depends makedepends
 | 
			
		||||
 | 
			
		||||
pkgbuild_schema_package_overrides=(pkgdesc arch url license groups depends
 | 
			
		||||
                                   optdepends provides conflicts replaces
 | 
			
		||||
                                   backup options install changelog)
 | 
			
		||||
                                   backup options install changelog alternative)
 | 
			
		||||
 | 
			
		||||
readonly -a known_hash_algos pkgbuild_schema_arrays \
 | 
			
		||||
	pkgbuild_schema_strings pkgbuild_schema_arch_arrays \
 | 
			
		||||
 
 | 
			
		||||
@@ -630,6 +630,7 @@ write_pkginfo() {
 | 
			
		||||
	write_kv_pair "optdepend"   "${optdepends[@]//+([[:space:]])/ }"
 | 
			
		||||
	write_kv_pair "makedepend"  "${makedepends[@]}"
 | 
			
		||||
	write_kv_pair "checkdepend" "${checkdepends[@]}"
 | 
			
		||||
	write_kv_pair "alternative" "${alternative[@]}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
write_buildinfo() {
 | 
			
		||||
@@ -710,6 +711,16 @@ create_package() {
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# check for alternative files
 | 
			
		||||
	for i in ${alternative[@]}; do
 | 
			
		||||
		msg2 "$(gettext "Adding %s file...")" "$i.alternative"
 | 
			
		||||
		if ! cp "$startdir/$i.alternative" ".ALTERNATIVE.$i"; then
 | 
			
		||||
			error "$(gettext "Failed to add %s file to package.")" "$i.alternative"
 | 
			
		||||
			exit $E_MISSING_FILE
 | 
			
		||||
		fi
 | 
			
		||||
		chmod 644 ".ALTERNATIVE.$i"
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# tar it up
 | 
			
		||||
	local fullver=$(get_full_version)
 | 
			
		||||
	local pkg_file="$PKGDEST/${pkgname}-${fullver}-${pkgarch}${PKGEXT}"
 | 
			
		||||
 
 | 
			
		||||
@@ -105,8 +105,7 @@ config_t *config_new(void)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	/* defaults which may get overridden later */
 | 
			
		||||
	newconfig->op = 0;
 | 
			
		||||
	newconfig->curr_op = 0;
 | 
			
		||||
	newconfig->op = PM_OP_MAIN;
 | 
			
		||||
	newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING;
 | 
			
		||||
	newconfig->configfile = strdup(CONFFILE);
 | 
			
		||||
	if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) {
 | 
			
		||||
@@ -132,13 +131,6 @@ 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) {
 | 
			
		||||
@@ -163,7 +155,6 @@ 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,17 +43,8 @@ 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;
 | 
			
		||||
@@ -92,7 +83,6 @@ 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;
 | 
			
		||||
@@ -109,8 +99,6 @@ 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;
 | 
			
		||||
@@ -154,15 +142,14 @@ typedef struct __config_t {
 | 
			
		||||
 | 
			
		||||
/* Operations */
 | 
			
		||||
enum {
 | 
			
		||||
	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
 | 
			
		||||
	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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Long Operations */
 | 
			
		||||
@@ -182,10 +169,7 @@ enum {
 | 
			
		||||
	OP_LOGFILE,
 | 
			
		||||
	OP_IGNOREGROUP,
 | 
			
		||||
	OP_NEEDED,
 | 
			
		||||
	OP_NOKEEP,
 | 
			
		||||
	OP_ASEXPLICIT,
 | 
			
		||||
	OP_NOTE,
 | 
			
		||||
	OP_RMNOTE,
 | 
			
		||||
	OP_ARCH,
 | 
			
		||||
	OP_PRINTFORMAT,
 | 
			
		||||
	OP_GPGDIR,
 | 
			
		||||
@@ -196,7 +180,6 @@ enum {
 | 
			
		||||
	OP_DBPATH,
 | 
			
		||||
	OP_CASCADE,
 | 
			
		||||
	OP_CHANGELOG,
 | 
			
		||||
	OP_BACKUP,
 | 
			
		||||
	OP_CLEAN,
 | 
			
		||||
	OP_NODEPS,
 | 
			
		||||
	OP_DEPS,
 | 
			
		||||
@@ -252,9 +235,6 @@ 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,12 +38,11 @@
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, 1 on failure
 | 
			
		||||
 */
 | 
			
		||||
static int change_pkg(alpm_list_t *targets)
 | 
			
		||||
static int change_install_reason(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	alpm_db_t *db_local;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	int set_reason = 0;
 | 
			
		||||
 | 
			
		||||
	alpm_pkgreason_t reason;
 | 
			
		||||
 | 
			
		||||
@@ -54,10 +53,11 @@ static int change_pkg(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;
 | 
			
		||||
		set_reason = 1;
 | 
			
		||||
	} else {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("no install reason specified (use -h for help)\n"));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Lock database */
 | 
			
		||||
@@ -69,46 +69,19 @@ static int change_pkg(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) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("package '%s' was not found"), 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)));
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			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);
 | 
			
		||||
					}
 | 
			
		||||
		} 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 */
 | 
			
		||||
@@ -323,9 +296,8 @@ int pacman_database(alpm_list_t *targets)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->note || config->rmnote ||
 | 
			
		||||
			(config->flags & (ALPM_TRANS_FLAG_ALLDEPS | ALPM_TRANS_FLAG_ALLEXPLICIT))) {
 | 
			
		||||
		ret = change_pkg(targets);
 | 
			
		||||
	if(config->flags & (ALPM_TRANS_FLAG_ALLDEPS | ALPM_TRANS_FLAG_ALLEXPLICIT)) {
 | 
			
		||||
		ret = change_install_reason(targets);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,9 @@ 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, alpm_filelist_t *pkgfiles)
 | 
			
		||||
static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg)
 | 
			
		||||
{
 | 
			
		||||
	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);
 | 
			
		||||
@@ -107,9 +108,7 @@ 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, *s,  *filetargs = NULL;
 | 
			
		||||
	alpm_filelist_t filelist = {0};
 | 
			
		||||
	char *pkgname = NULL;
 | 
			
		||||
	alpm_list_t *t, *filetargs = NULL;
 | 
			
		||||
 | 
			
		||||
	for(t = targets; t; t = alpm_list_next(t)) {
 | 
			
		||||
		char *targ = t->data;
 | 
			
		||||
@@ -145,58 +144,43 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for(s = syncs; s; s = alpm_list_next(s)) {
 | 
			
		||||
		alpm_db_t *repo = s->data;
 | 
			
		||||
		int m;
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
		alpm_db_files_t *files = alpm_db_files_open(repo);
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
		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;
 | 
			
		||||
			for(p = packages; p; p = alpm_list_next(p)) {
 | 
			
		||||
				alpm_pkg_t *pkg = p->data;
 | 
			
		||||
				alpm_filelist_t *files = alpm_pkg_get_files(pkg);
 | 
			
		||||
				alpm_list_t *match = NULL;
 | 
			
		||||
 | 
			
		||||
				if(exact_file) {
 | 
			
		||||
					if(regex) {
 | 
			
		||||
						for(size_t f = 0; f < filelist.count; f++) {
 | 
			
		||||
							char *c = filelist.files[f].name;
 | 
			
		||||
					if (regex) {
 | 
			
		||||
						for(size_t f = 0; f < files->count; f++) {
 | 
			
		||||
							char *c = files->files[f].name;
 | 
			
		||||
							if(regexec(reg, c, 0, 0, 0) == 0) {
 | 
			
		||||
								match = alpm_list_add(match, filelist.files[f].name);
 | 
			
		||||
								match = alpm_list_add(match, files->files[f].name);
 | 
			
		||||
								found = 1;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						if(alpm_filelist_contains(&filelist, targ)) {
 | 
			
		||||
						if(alpm_filelist_contains(files, targ)) {
 | 
			
		||||
							match = alpm_list_add(match, targ);
 | 
			
		||||
							found = 1;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					for(size_t f = 0; f < filelist.count; f++) {
 | 
			
		||||
						char *c = strrchr(filelist.files[f].name, '/');
 | 
			
		||||
					for(size_t f = 0; f < files->count; f++) {
 | 
			
		||||
						char *c = strrchr(files->files[f].name, '/');
 | 
			
		||||
						if(c && *(c + 1)) {
 | 
			
		||||
							if(regex) {
 | 
			
		||||
								m = regexec(reg, (c + 1), 0, 0, 0);
 | 
			
		||||
@@ -204,7 +188,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, filelist.files[f].name);
 | 
			
		||||
								match = alpm_list_add(match, files->files[f].name);
 | 
			
		||||
								found = 1;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
@@ -215,33 +199,28 @@ 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;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		alpm_db_files_close(files);
 | 
			
		||||
		if(!found) {
 | 
			
		||||
			ret = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
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, alpm_filelist_t *pkgfiles) {
 | 
			
		||||
static void dump_file_list(alpm_pkg_t *pkg) {
 | 
			
		||||
	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;
 | 
			
		||||
@@ -260,97 +239,73 @@ static void dump_file_list(alpm_pkg_t *pkg, alpm_filelist_t *pkgfiles) {
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
	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(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, '/');
 | 
			
		||||
 | 
			
		||||
		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) {
 | 
			
		||||
			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;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for(j = syncs; j; j = alpm_list_next(j)) {
 | 
			
		||||
				alpm_pkg_t *pkg;
 | 
			
		||||
				alpm_db_t *db = j->data;
 | 
			
		||||
 | 
			
		||||
			if(alpm_db_files_load(files, &filelist) != 0) {
 | 
			
		||||
				ret = 1;
 | 
			
		||||
				continue;
 | 
			
		||||
				if(repo) {
 | 
			
		||||
					if(strcmp(alpm_db_get_name(db), repo) != 0) {
 | 
			
		||||
						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;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
			free(repo);
 | 
			
		||||
		}
 | 
			
		||||
		alpm_db_files_close(files);
 | 
			
		||||
	}
 | 
			
		||||
	} else {
 | 
			
		||||
		for(i = syncs; i; i = alpm_list_next(i)) {
 | 
			
		||||
		alpm_db_t *db = i->data;
 | 
			
		||||
 | 
			
		||||
	alpm_filelist_free(&filelist);
 | 
			
		||||
 | 
			
		||||
	if(found != alpm_list_count(targets)) {
 | 
			
		||||
		ret = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(pkgname) {
 | 
			
		||||
		free(pkgname);
 | 
			
		||||
			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);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int pacman_files(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *files_dbs = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ pacman_sources = files('''
 | 
			
		||||
  remove.c
 | 
			
		||||
  sighandler.h sighandler.c
 | 
			
		||||
  sync.c
 | 
			
		||||
  trans.c
 | 
			
		||||
  callback.h callback.c
 | 
			
		||||
  upgrade.c
 | 
			
		||||
  util.h util.c
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,6 @@ enum {
 | 
			
		||||
	T_URL,
 | 
			
		||||
	T_VALIDATED_BY,
 | 
			
		||||
	T_VERSION,
 | 
			
		||||
	T_NOTE,
 | 
			
		||||
	/* the following is a sentinel and should remain in last position */
 | 
			
		||||
	_T_MAX
 | 
			
		||||
};
 | 
			
		||||
@@ -125,7 +124,6 @@ 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);
 | 
			
		||||
@@ -303,7 +301,6 @@ 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],
 | 
			
		||||
@@ -351,7 +348,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_backup_status(pkg, cols);
 | 
			
		||||
		dump_pkg_backups(pkg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* final newline to separate packages */
 | 
			
		||||
@@ -362,34 +359,6 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
@@ -410,21 +379,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;
 | 
			
		||||
@@ -432,33 +401,27 @@ static const char *get_backup_file_status(const char *root,
 | 
			
		||||
 | 
			
		||||
/* Display list of backup files and their modification states
 | 
			
		||||
 */
 | 
			
		||||
void dump_backup_status(alpm_pkg_t *pkg, unsigned short cols)
 | 
			
		||||
void dump_pkg_backups(alpm_pkg_t *pkg)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i, *text = NULL;
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	const char *root = alpm_option_get_root(config->handle);
 | 
			
		||||
	/* 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;
 | 
			
		||||
	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);
 | 
			
		||||
		}
 | 
			
		||||
		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);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* package had no backup files */
 | 
			
		||||
		printf(_("(none)\n"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_display_linebreak(titles[T_BACKUP_FILES], text, cols);
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
	FREELIST(text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* List all files contained in a package
 | 
			
		||||
@@ -487,32 +450,6 @@ 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)
 | 
			
		||||
@@ -529,11 +466,7 @@ 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))) {
 | 
			
		||||
			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);
 | 
			
		||||
			fwrite(buf, 1, ret, stdout);
 | 
			
		||||
		}
 | 
			
		||||
		alpm_pkg_changelog_close(pkg, fp);
 | 
			
		||||
		putchar('\n');
 | 
			
		||||
 
 | 
			
		||||
@@ -24,8 +24,7 @@
 | 
			
		||||
 | 
			
		||||
void dump_pkg_full(alpm_pkg_t *pkg, int extra);
 | 
			
		||||
 | 
			
		||||
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_backups(alpm_pkg_t *pkg);
 | 
			
		||||
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 targets_t pm_targets;
 | 
			
		||||
static alpm_list_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) {
 | 
			
		||||
	if(op == PM_OP_MAIN) {
 | 
			
		||||
		printf("%s:  %s <%s> [...]\n", str_usg, myname, str_opr);
 | 
			
		||||
		printf(_("operations:\n"));
 | 
			
		||||
		printf("    %s {-h --help}\n", myname);
 | 
			
		||||
@@ -123,11 +123,13 @@ 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(_("      --unneeded       remove unneeded packages\n"));
 | 
			
		||||
			          "                       (-ss includes explicitly installed dependencies)\n"));
 | 
			
		||||
			addlist(_("  -u, --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);
 | 
			
		||||
@@ -148,7 +150,6 @@ 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);
 | 
			
		||||
@@ -162,13 +163,12 @@ 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"));
 | 
			
		||||
		}
 | 
			
		||||
		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"));
 | 
			
		||||
		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;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		addlist(_("  -b, --dbpath <path>  set an alternate database location\n"));
 | 
			
		||||
@@ -301,7 +301,7 @@ static void cleanup(int ret)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* free memory */
 | 
			
		||||
	targets_free(&pm_targets);
 | 
			
		||||
	FREELIST(pm_targets);
 | 
			
		||||
	console_cursor_show();
 | 
			
		||||
	exit(ret);
 | 
			
		||||
}
 | 
			
		||||
@@ -327,24 +327,6 @@ 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
 | 
			
		||||
@@ -356,25 +338,25 @@ static int parsearg_op(int opt, int dryrun)
 | 
			
		||||
		/* operations */
 | 
			
		||||
		case 'D':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_DATABASE); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DATABASE); break;
 | 
			
		||||
		case 'F':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_FILES); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_FILES); break;
 | 
			
		||||
		case 'Q':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_QUERY); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;
 | 
			
		||||
		case 'R':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_REMOVE); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break;
 | 
			
		||||
		case 'S':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_SYNC); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break;
 | 
			
		||||
		case 'T':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_DEPTEST); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DEPTEST); break;
 | 
			
		||||
		case 'U':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_UPGRADE); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_UPGRADE); break;
 | 
			
		||||
		case 'V':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			config->version = 1; break;
 | 
			
		||||
@@ -387,7 +369,6 @@ 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
 | 
			
		||||
@@ -500,12 +481,6 @@ 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)++;
 | 
			
		||||
@@ -526,11 +501,7 @@ 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,
 | 
			
		||||
@@ -545,10 +516,6 @@ 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;
 | 
			
		||||
@@ -616,7 +583,6 @@ 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) {
 | 
			
		||||
@@ -653,8 +619,62 @@ 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':
 | 
			
		||||
@@ -673,6 +693,7 @@ static int parsearg_remove(int opt)
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_UNNEEDED:
 | 
			
		||||
		case 'u':
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_UNNEEDED;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
@@ -683,6 +704,7 @@ 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,
 | 
			
		||||
@@ -693,6 +715,9 @@ 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));
 | 
			
		||||
@@ -703,15 +728,9 @@ 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;
 | 
			
		||||
@@ -723,7 +742,6 @@ 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;
 | 
			
		||||
	}
 | 
			
		||||
@@ -732,6 +750,7 @@ 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");
 | 
			
		||||
@@ -739,6 +758,9 @@ 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':
 | 
			
		||||
@@ -777,26 +799,6 @@ 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':
 | 
			
		||||
@@ -838,12 +840,7 @@ static int parsearg_sync_only(int opt)
 | 
			
		||||
 | 
			
		||||
static void checkargs_sync(void)
 | 
			
		||||
{
 | 
			
		||||
	/* no conflicts currently */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void checkargs_sync_only(void)
 | 
			
		||||
{
 | 
			
		||||
	checkargs_sync();
 | 
			
		||||
	checkargs_upgrade();
 | 
			
		||||
	if(config->op_s_clean) {
 | 
			
		||||
		invalid_opt(config->group, "--clean", "--groups");
 | 
			
		||||
		invalid_opt(config->op_s_info, "--clean", "--info");
 | 
			
		||||
@@ -873,89 +870,6 @@ static void checkargs_sync_only(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
 | 
			
		||||
@@ -966,7 +880,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'},
 | 
			
		||||
@@ -982,7 +896,6 @@ 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},
 | 
			
		||||
@@ -1028,10 +941,7 @@ 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},
 | 
			
		||||
@@ -1045,11 +955,6 @@ 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;
 | 
			
		||||
@@ -1057,8 +962,8 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
		parsearg_op(opt, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->op & PM_OP_INVALID) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("these operations can not be used together\n"));
 | 
			
		||||
	if(config->op == 0) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("only one operation may be used at a time\n"));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->help) {
 | 
			
		||||
@@ -1073,7 +978,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 || opt == 1) {
 | 
			
		||||
		if(opt == 0) {
 | 
			
		||||
			continue;
 | 
			
		||||
		} else if(opt == '?') {
 | 
			
		||||
			/* this should have failed during first pass already */
 | 
			
		||||
@@ -1090,9 +995,14 @@ 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:
 | 
			
		||||
				/* handle -Si -Sg etc if -S is the only trans op */
 | 
			
		||||
				result = parsearg_sync_only(opt);
 | 
			
		||||
				result = parsearg_sync(opt);
 | 
			
		||||
				break;
 | 
			
		||||
			case PM_OP_UPGRADE:
 | 
			
		||||
				result = parsearg_upgrade(opt);
 | 
			
		||||
				break;
 | 
			
		||||
			case PM_OP_FILES:
 | 
			
		||||
				result = parsearg_files(opt);
 | 
			
		||||
@@ -1106,13 +1016,6 @@ 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) {
 | 
			
		||||
@@ -1129,7 +1032,7 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
	while(optind < argc) {
 | 
			
		||||
		/* add the target to our target array */
 | 
			
		||||
		add_target(strdup(argv[optind]));
 | 
			
		||||
		pm_targets = alpm_list_add(pm_targets, strdup(argv[optind]));
 | 
			
		||||
		optind++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1141,7 +1044,7 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
			/* no conflicting options */
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_SYNC:
 | 
			
		||||
			checkargs_sync_only();
 | 
			
		||||
			checkargs_sync();
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_QUERY:
 | 
			
		||||
			checkargs_query();
 | 
			
		||||
@@ -1158,83 +1061,10 @@ 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
 | 
			
		||||
@@ -1308,7 +1138,54 @@ int main(int argc, char *argv[])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* we support reading targets from stdin if a cmdline parameter is '-' */
 | 
			
		||||
	parse_stdins();
 | 
			
		||||
	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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->sysroot && (chroot(config->sysroot) != 0 || chdir("/") != 0)) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR,
 | 
			
		||||
@@ -1356,10 +1233,7 @@ 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.targets, 0);
 | 
			
		||||
		list_display("Sync      :", pm_targets.sync, 0);
 | 
			
		||||
		list_display("Upgrade   :", pm_targets.upgrade, 0);
 | 
			
		||||
		list_display("Remove    :", pm_targets.remove, 0);
 | 
			
		||||
		list_display("Targets   :", pm_targets, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Log command line */
 | 
			
		||||
@@ -1368,26 +1242,31 @@ int main(int argc, char *argv[])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* start the requested operation */
 | 
			
		||||
	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;
 | 
			
		||||
		}
 | 
			
		||||
	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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cleanup(ret);
 | 
			
		||||
 
 | 
			
		||||
@@ -22,8 +22,6 @@
 | 
			
		||||
 | 
			
		||||
#include <alpm_list.h>
 | 
			
		||||
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
#define PACMAN_CALLER_PREFIX "PACMAN"
 | 
			
		||||
 | 
			
		||||
/* database.c */
 | 
			
		||||
@@ -34,14 +32,12 @@ 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);
 | 
			
		||||
/* remove.c */
 | 
			
		||||
int load_remove(alpm_list_t *targets);
 | 
			
		||||
int sync_prepare_execute(void);
 | 
			
		||||
/* upgrade.c */
 | 
			
		||||
int load_upgrade(alpm_list_t *targets);
 | 
			
		||||
/* trans.c */
 | 
			
		||||
int do_transaction(targets_t *targets);
 | 
			
		||||
 | 
			
		||||
int pacman_upgrade(alpm_list_t *targets);
 | 
			
		||||
 | 
			
		||||
#endif /* PM_PACMAN_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -315,9 +315,6 @@ 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);
 | 
			
		||||
	}
 | 
			
		||||
@@ -328,19 +325,13 @@ 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 && !config->op_q_backup) {
 | 
			
		||||
	if(!config->op_q_info && !config->op_q_list
 | 
			
		||||
			&& !config->op_q_changelog && !config->op_q_check) {
 | 
			
		||||
		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));
 | 
			
		||||
@@ -440,7 +431,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, backup
 | 
			
		||||
	 * valid: no-op (plain -Q), list, info, check
 | 
			
		||||
	 * invalid: isfile, owns */
 | 
			
		||||
	if(targets == NULL) {
 | 
			
		||||
		if(config->op_q_isfile || config->op_q_owns) {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <fnmatch.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
@@ -29,6 +30,11 @@
 | 
			
		||||
#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;
 | 
			
		||||
@@ -63,16 +69,28 @@ static int remove_target(const char *target)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int load_remove(alpm_list_t *targets)
 | 
			
		||||
/**
 | 
			
		||||
 * @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 retval = 0;
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	alpm_list_t *i, *data = NULL;
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
@@ -84,6 +102,81 @@ int load_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,6 +35,7 @@
 | 
			
		||||
#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)
 | 
			
		||||
@@ -509,6 +510,376 @@ 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;
 | 
			
		||||
@@ -531,8 +902,26 @@ 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);
 | 
			
		||||
@@ -554,9 +943,17 @@ int pacman_sync(alpm_list_t *targets)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(targets == NULL) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
 | 
			
		||||
		return 1;
 | 
			
		||||
		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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return sync_trans(targets);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,478 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  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 load_upgrade(alpm_list_t *targets)
 | 
			
		||||
int pacman_upgrade(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	int retval = 0;
 | 
			
		||||
	alpm_list_t *remote_targets = NULL, *fetched_files = NULL;
 | 
			
		||||
@@ -88,16 +88,38 @@ int load_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,15 +72,6 @@ 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -115,17 +106,16 @@ 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:
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,6 @@ 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',
 | 
			
		||||
@@ -176,7 +174,6 @@ 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',
 | 
			
		||||
@@ -184,7 +181,6 @@ 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,8 +121,6 @@ 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%":
 | 
			
		||||
@@ -210,7 +208,6 @@ 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,7 +34,6 @@ class pmpkg(object):
 | 
			
		||||
        self.desc = ""
 | 
			
		||||
        self.groups = []
 | 
			
		||||
        self.url = ""
 | 
			
		||||
        self.note = ""
 | 
			
		||||
        self.license = []
 | 
			
		||||
        self.arch = ""
 | 
			
		||||
        self.builddate = ""
 | 
			
		||||
@@ -72,7 +71,6 @@ 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,9 +108,6 @@ 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 == 1, i)
 | 
			
		||||
            tap.ok(success, i)
 | 
			
		||||
 | 
			
		||||
    def configfile(self):
 | 
			
		||||
        return os.path.join(self.root, util.PACCONF)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
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")
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
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 = "-R --unneeded pkg1 pkg2"
 | 
			
		||||
self.args = "-Ru 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")
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
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")
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
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