From ArchWiki

pacman TODO


  • fix --sysroot
  • limit package name/version (db name?)
  • fix callback api's

config/option parsing

  • error on unknown options
  • multi-value options provided on the command-line override rather than append to configuration values
  • use wordsplit to split multi-value configuration options that can contain spaces
  • use the last configured value for all single-value options (dbpath, root, logfile, etc)
  • do not split --ignore/--ignoregroup on ',' (commas are valid characters in package names and groups)

external downloader

The external callback-based downloader has several deficiencies compared to the internal downloader:

dynamic users


  • add package user information to PKGBUILD (/etc/passwd format?)
  • add users to .PKGINFO
  • create dynamic users with fakeuser during package()


  • if user exists on system, use system uid
  • if user does not exist and uid is unassigned, use package uid
    • attempt to add user to /etc/passwd
  • if user does not exist and uid is assigned, fallback to uid 0
  • need to use the user info from inside the root (chroot for file extraction?)

signal handling

  • restrict scope to trans_commit

libalpm API

  • remove ignorepkg support from functions that don't modify the transaction
    • move alpm_find_group_packages to frontend
  • allow searching arbitrary package lists rather than databases
  • report memory errors from alpm_list_* functions
  • stop resetting pm_errno everywhere

pacman ui reorganization

Some of pacman's options are organized by target (--query) while others are organized by action (--deptest). Organization by target results in a large number of unrelated operations being grouped together. Reorganizing operations by action will provide greater consistency, fewer invalid option combinations that must manually be checked for, and easier extensibility for things like combined add/remove transactions.

-X install/upgrade/remove
 --refresh, -y
 --sysupgrade, -u
 --print, -p
 --nodeps, -d
 --downloadonly, -w
-S search
 --local/--sync     (show both by default)
 --satisfies        (-T replacement)
--info, -I <pkgname>...
 --local/--sync     (show both by default)
 --short            --search style output
 --verbose          show extended information
 --files            list files owned by <package>
 --format           expac-style output
--check, -K [<pkgname>...]
 --recursive        perform checks on package [opt-]depends
 --files            basic file list verification (default)
 --depends          check for missing dependencies
 --opt-depends      check for missing optional dependencies
 --file-properties  check file properties against MTREE data
 --backup           include backup files in modification checks
--database, -D
--version, -V
--help, -h
--groups, -G        list groups
 --local/--sync     (show both by default)
-? clean cache (retire in favor of paccache?)

combined transactions



  • restrict package name characters
  • provide syntax to skip targets base ^nano
  • move max filename tests to alpm unit tests
  • sync db files immediately after extraction
  • unit/integration tests
  • store md5/sha256 in local db for comparison to sync db pkgs
  • allow checking user/group names with -Qkk (requires modifications to libarchive)
  • libalpm man pages
  • clarify "skipping duplicate target" messages
  • githooks
  • check that fs file type matches old package filelist for conflict checks
  • document doxygen format
  • consolidate similar messages
  • use -fvisibility=hidden for clang
  • peculiar run_chroot arg0 strcpy's
  • dependency tree
  • sync, remove, etc. call graphs
  • translation context
  • add targets to conflicts if they need to be removed first
  • look at
  • makepkg test suite
  • check all malloc's for success
  • SyncGroup
  • RefreshOnSync
  • UpgradeOnSync

Format Specifications


A package is an archive file readable by libarchive that contains metadata files and the actual package contents. All metadata files begin with a period (dot) and are located in the archive root:

  • .BUILDINFO (optional)
  • .MTREE (optional)
  • .INSTALL (optional)
  • .CHANGELOG (optional)

All other root dotfiles are reserved for use by libalpm. The package contents are similarly located directly in the package root. All file paths should be relative and not contain '.' or '..' anywhere. All intermediate directories must exist in the archive. Metadata files must come before package files. Package contents must be sorted according to the C locale. For example, a package file structure might look like:



The .PKGINFO file contains metadata about the package itself. It must be a plain INI-style text file. Lines must not contain any leading whitespace. Empty lines and lines beginning with '#' will be skipped. Key-value pairs must be separated by " = ".

String Fields

  • pkgname
  • pkgbase
  • pkgver
  • pkgdesc
  • url
  • packager
  • arch

String List Fields

  • group
  • license
  • depend
  • optdepend
  • makedepend
  • checkdepend
  • conflict
  • replaces
  • provides
  • backup

Numeric Fields

  • builddate
  • size



The .MTREE file is an optional file that describes file properties such as size, owner, group, etc. It allows pacman to check if files on a system have been modified after installation. It can be in any format readable by libarchive. Note: third-party tools may expect this to be in the same format generated by makepkg, which uses the following:

LANG=C bsdtar -czf .MTREE --format=mtree --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link'


The .INSTALL file defines functions to run before and/or after a package operation is performed. See PKGBUILD(5) for more information.


An optional file describing the changes between package versions. .CHANGELOG is intended solely for display directly to the user without any parsing or processing. It should be plain text, but the contents may be formatted in any way suitable for presentation to the user. See PKGBUILD(5) for more information.


pacman LIMITS


  • all pkginfo fields limited to 1024 (local_db_read)
    • sync_db_read handles 512 * 1024
    • parse_descfile limits to 512 * 1024 - length of field name
  • path length: 1024 (local_db_read)
    • limited to PATH_MAX - strlen(rootdir) elsewhere
  • no newlines in any package data
  • no dotfiles in base directory
  • no '/' in db names, package name, or package version
  • syncdb cannot be named 'local'
  • package name + package version limited to NAME_MAX
  • script output cannot contain NUL bytes
  • package name should not contain '=<>' (can't be used as a dependency)
  • package name should not contain ": " (can't be used as a dependency)
  • backup file paths limited to PATH_MAX - (len(hash) + 2)
  • db extension should not be .part
  • pkgver cannot contain '-', can lead to overlap in database entry names causing aborted transactions
  • front-ends may not set a global SIGPIPE - if a SIGPIPE handler is active when gpgme is initialized it will not ignore SIGPIPE


  • maximum file length: PATH_MAX
  • no whitespace in multivalue options


  • pkgname may not start with '-'
  • pkgname may not start with '.'
  • pkgname may only contain [:alnum:]+_.@-]
  • epoch must be a positive integer
  • pkgrel must be a positive decimal
  • arch may only contain [:alnum:]_
  • provides cannot contain '<>'
  • pkgver cannot contain ':-' (confuses epoch/pkgrel parsing)

Rejected Features

makepkg: shallow git clones

pacman: save warning messages until the end

makepkg: replace default checksums


  • replace manual signal restoration for hooks/scripts? posix_spawn has POSIX_SPAWN_SETSIGDEF but is an optional part of the spec
  • switch to dpkg-style packages? uncompressed outer archive with package info, compressed archive with package files. could massively speed up reading package meta info


  • specify reliable way to get alpm pid (get_ppid(), $ALPM_PID?)
  • provide way to get detailed package information
    • read from db? db may not be inside root; pass db file descriptor?
    • chroot into sysroot instead of rootdir?
    • need a way to get info for files provided directly to -U
    • request info from alpm process via api socket?
  • ipc for persistent hooks
  • track alpm proc lifetime for persistent hooks; pidfd_open/procfs/poll can be used but are not portable
  • prompt for user interaction; ipc being built for unprivileged downloads could be used for this
  • trigger PostTransaction hooks even when transaction doesn't complete
  • PostAction hooks? requires scanning hooks before/after every single action; fs caching may make this irrelevant
  • allow specifying scripts as executable files to run directly instead of through bash
    • how to determine if a script needs to run?
      • action-specific scripts? e.g.,
      • always run script if present?