### Makepkg: Build and Install Package Source: https://context7.com/archlinux/alpm/llms.txt Use `makepkg --syncdeps --install` to build a package from a PKGBUILD, synchronizing dependencies and then installing it. Other options control cleaning the workspace, forcing rebuilds, verifying sources, generating checksums, and skipping integrity checks. ```bash # Basic usage — build then install makepkg --syncdeps --install ``` ```bash # Clean workspace after build makepkg -c ``` ```bash # Force rebuild (overwrite existing package) makepkg -f ``` ```bash # Download sources and verify checksums only; do not build makepkg --verifysource ``` ```bash # Generate checksums to paste back into PKGBUILD makepkg -g >> PKGBUILD ``` ```bash # Skip all integrity/pgp checks (for local dev) makepkg --skipinteg ``` ```bash # Build with verbose compiler output (BUILDENV=(!distcc !ccache)) makepkg --nocheck # skip check() function ``` -------------------------------- ### Pacman: Install Packages Source: https://context7.com/archlinux/alpm/llms.txt Use `pacman -S` to install packages. You can install single packages, packages with version constraints, package groups, or specify a repository. ```bash pacman -S htop # install a single package ``` ```bash pacman -S "bash>=5.0" # install with version constraint ``` ```bash pacman -S gnome # install a package group (interactive selection) ``` ```bash pacman -S core/pacman # explicit repository qualifier ``` -------------------------------- ### Install Packages via ALPM Transaction Source: https://context7.com/archlinux/alpm/llms.txt Demonstrates the workflow for initializing, preparing, committing, and releasing a transaction to install a package. Includes basic event callback for transaction progress. ```c #include #include /* Minimal event callback */ static void event_cb(void *ctx, alpm_event_t *event) { (void)ctx; switch (event->type) { case ALPM_EVENT_TRANSACTION_START: printf("transaction started\n"); break; case ALPM_EVENT_PACKAGE_OPERATION_START: printf("operating on %s\n", alpm_pkg_get_name(event->package_operation.newpkg ? event->package_operation.newpkg : event->package_operation.oldpkg)); break; case ALPM_EVENT_TRANSACTION_DONE: printf("transaction done\n"); break; default: break; } } int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_option_set_eventcb(handle, event_cb, NULL); alpm_option_set_logfile(handle, "/var/log/pacman.log"); alpm_option_add_cachedir(handle, "/var/cache/pacman/pkg/"); alpm_option_add_architecture(handle, "x86_64"); /* Register sync db */ alpm_db_t *syncdb = alpm_register_syncdb(handle, "core", ALPM_SIG_USE_DEFAULT); alpm_db_add_server(syncdb, "https://mirror.example.com/archlinux/core/os/x86_64/"); /* Begin transaction — no special flags */ if (alpm_trans_init(handle, 0) != 0) { fprintf(stderr, "trans_init: %s\n", alpm_strerror(alpm_errno(handle))); alpm_release(handle); return 1; } /* Resolve "htop" from sync databases */ alpm_pkg_t *pkg = alpm_db_get_pkg(syncdb, "htop"); if (!pkg) { fprintf(stderr, "htop not found in core\n"); alpm_trans_release(handle); alpm_release(handle); return 1; } alpm_add_pkg(handle, pkg); /* Prepare (dependency check, conflict detection) */ alpm_list_t *data = NULL; if (alpm_trans_prepare(handle, &data) != 0) { fprintf(stderr, "prepare failed: %s\n", alpm_strerror(alpm_errno(handle))); /* data contains alpm_depmissing_t* on ALPM_ERR_UNSATISFIED_DEPS */ alpm_trans_release(handle); alpm_release(handle); return 1; } /* Commit (download + install) */ if (alpm_trans_commit(handle, &data) != 0) { fprintf(stderr, "commit failed: %s\n", alpm_strerror(alpm_errno(handle))); alpm_trans_release(handle); alpm_release(handle); return 1; } alpm_trans_release(handle); alpm_release(handle); return 0; } ``` -------------------------------- ### Pacman: Query Local Database Source: https://context7.com/archlinux/alpm/llms.txt Use `pacman -Q` to query the local package database. Options include listing all installed packages, getting detailed info, listing files, finding which package owns a file, and searching installed packages. ```bash pacman -Q # list all installed packages ``` ```bash pacman -Qi pacman # detailed info: description, deps, files, etc. ``` ```bash pacman -Ql pacman # list files owned by pacman ``` ```bash pacman -Qo /usr/bin/pacman # which package owns a file ``` ```bash pacman -Qs regex # search locally installed packages ``` -------------------------------- ### Pacman: Upgrade/Install Local Package Source: https://context7.com/archlinux/alpm/llms.txt Use `pacman -U` to upgrade or install a local package file, which can be a local path or a URL. ```bash pacman -U /path/to/pkg.tar.zst ``` ```bash pacman -U https://example.com/repo/pkg.tar.zst ``` -------------------------------- ### PKGBUILD Metadata and Dependencies Source: https://github.com/archlinux/alpm/pacman/blob/master/doc/PKGBUILD-example.txt Defines package metadata such as name, version, description, architecture, URL, license, and dependencies. Ensure all listed dependencies are installed before building. ```bash # Maintainer: Joe User pkgname=patch pkgver=2.7.1 pkgrel=1 pkgdesc="A utility to apply patch files to original sources" arch=('i686' 'x86_64') url="https://www.gnu.org/software/patch/patch.html" license=('GPL') groups=('base-devel') depends=('glibc') makedepends=('ed') optdepends=('ed: for "patch -e" functionality') source=("ftp://ftp.gnu.org/gnu/$pkgname/$pkgname-$pkgver.tar.xz"{,.sig}) sha256sums=('9124ba46db0abd873d0995c2ca880e81252676bb6c03e0a37dfc5f608a9b0ceb' 'SKIP') ``` -------------------------------- ### Package Function in PKGBUILD Source: https://github.com/archlinux/alpm/pacman/blob/master/doc/PKGBUILD-example.txt Defines how to install the compiled software into the package directory. The DESTDIR variable is crucial for staging the installation. ```bash package() { cd "$srcdir/$pkgname-$pkgver" make DESTDIR="$pkgdir/" install } ``` -------------------------------- ### PKGBUILD Example Source: https://context7.com/archlinux/alpm/llms.txt A `PKGBUILD` is a bash script defining package metadata and build steps. It includes mandatory fields like `pkgname`, `pkgver`, `pkgrel`, `arch`, and optional functions for `prepare`, `build`, `check`, and `package`. ```bash # /path/to/mypkg/PKGBUILD pkgname=myhello pkgver=1.2.3 pkgrel=1 epoch=0 pkgdesc="A minimal hello-world package" arch=('x86_64' 'aarch64') url="https://github.com/example/myhello" license=('MIT') depends=('glibc>=2.38') makedepends=('gcc' 'make') checkdepends=('cmocka') optdepends=('python: for the utility script') provides=('hello') conflicts=('other-hello') replaces=('old-hello<1.0') source=("https://github.com/example/myhello/archive/v${pkgver}.tar.gz" "myhello-fix-typo.patch") sha256sums=('abc123def456...' 'SKIP') validpgpkeys=('ABCDEF1234567890ABCDEF1234567890ABCDEF12') backup=('etc/myhello/myhello.conf') options=('strip' '!docs' '!libtool') # Optional: override pkgver from VCS checkout pkgver() { cd "$srcdir/myhello-${pkgver}" git describe --long --tags | sed 's/^v//;s/-\([0-9]*\)-g/r\1./' } prepare() { cd "$srcdir/myhello-${pkgver}" patch -p1 < "$srcdir/myhello-fix-typo.patch" } build() { cd "$srcdir/myhello-${pkgver}" ./configure --prefix=/usr --sysconfdir=/etc make } check() { cd "$srcdir/myhello-${pkgver}" make test } package() { cd "$srcdir/myhello-${pkgver}" make DESTDIR="$pkgdir" install install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" } ``` -------------------------------- ### Query Local Package Database Source: https://context7.com/archlinux/alpm/llms.txt Retrieves information about installed packages from the local database. Use `alpm_db_get_pkg` for direct lookups and `alpm_db_get_pkgcache` to iterate through all installed packages. ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_db_t *localdb = alpm_get_localdb(handle); /* Direct lookup */ alpm_pkg_t *pkg = alpm_db_get_pkg(localdb, "pacman"); if (pkg) { printf("% -20s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); printf(" installed size: %lld bytes\n", (long long)alpm_pkg_get_isize(pkg)); printf(" description: %s\n", alpm_pkg_get_desc(pkg)); printf(" architecture: %s\n", alpm_pkg_get_arch(pkg)); } /* Iterate all installed packages */ alpm_list_t *pkgcache = alpm_db_get_pkgcache(localdb); size_t count = 0; for (alpm_list_t *i = pkgcache; i; i = alpm_list_next(i)) { alpm_pkg_t *p = (alpm_pkg_t *)i->data; printf("% -30s %s\n", alpm_pkg_get_name(p), alpm_pkg_get_version(p)); count++; } printf("total installed: %zu\n", count); alpm_release(handle); return 0; } /* Sample output: pacman 7.0.0-1 installed size: 4194304 bytes description: A library-based package manager with dependency support architecture: x86_64 */ ``` -------------------------------- ### Query packages from the local database Source: https://context7.com/archlinux/alpm/llms.txt Demonstrates how to retrieve package information from the local pacman database. It shows direct package lookup by name and iterating through all installed packages. ```APIDOC ## Query packages from the local database ### Description This function retrieves the local package database and allows for direct lookup of a package by its name or iteration through all installed packages. ### Functions - `alpm_get_localdb(handle)`: Returns the local package database. - `alpm_db_get_pkg(localdb, name)`: Looks up a single package by name in O(1) time. - `alpm_db_get_pkgcache(localdb)`: Returns a list of all installed packages. ### Example Usage ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_db_t *localdb = alpm_get_localdb(handle); /* Direct lookup */ alpm_pkg_t *pkg = alpm_db_get_pkg(localdb, "pacman"); if (pkg) { printf("% -20s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); printf(" installed size: %lld bytes\n", (long long)alpm_pkg_get_isize(pkg)); printf(" description: %s\n", alpm_pkg_get_desc(pkg)); printf(" architecture: %s\n", alpm_pkg_get_arch(pkg)); } /* Iterate all installed packages */ alpm_list_t *pkgcache = alpm_db_get_pkgcache(localdb); size_t count = 0; for (alpm_list_t *i = pkgcache; i; i = alpm_list_next(i)) { alpm_pkg_t *p = (alpm_pkg_t *)i->data; printf("% -30s %s\n", alpm_pkg_get_name(p), alpm_pkg_get_version(p)); count++; } printf("total installed: %zu\n", count); alpm_release(handle); return 0; } /* Sample output: pacman 7.0.0-1 installed size: 4194304 bytes description: A library-based package manager with dependency support architecture: x86_64 */ ``` ``` -------------------------------- ### Perform System Upgrade with ALPM Source: https://context7.com/archlinux/alpm/llms.txt Scans installed packages and adds outdated ones to the transaction for upgrading. Configures progress callback and parallel downloads. ```c #include #include static void progress_cb(void *ctx, alpm_progress_t prog, const char *pkg, int percent, size_t howmany, size_t current) { (void)ctx; printf("\r[%%zu/%%zu] %%s %%d%% ", current, howmany, pkg, percent); fflush(stdout); } int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_option_set_progresscb(handle, progress_cb, NULL); alpm_option_set_parallel_downloads(handle, 5); /* download 5 pkgs at once */ alpm_db_t *core = alpm_register_syncdb(handle, "core", ALPM_SIG_USE_DEFAULT); alpm_db_t *extra = alpm_register_syncdb(handle, "extra", ALPM_SIG_USE_DEFAULT); alpm_db_add_server(core, "https://mirror.example.com/archlinux/core/os/x86_64/"); alpm_db_add_server(extra, "https://mirror.example.com/archlinux/extra/os/x86_64/"); alpm_trans_init(handle, 0); /* 1 = allow downgrade if remote version is lower */ if (alpm_sync_sysupgrade(handle, 0) != 0) { fprintf(stderr, "sysupgrade staging failed: %s\n", alpm_strerror(alpm_errno(handle))); alpm_trans_release(handle); alpm_release(handle); return 1; } alpm_list_t *add = alpm_trans_get_add(handle); printf("%zu package(s) to upgrade\n", alpm_list_count(add)); alpm_list_t *data = NULL; if (alpm_trans_prepare(handle, &data) == 0) alpm_trans_commit(handle, &data); alpm_trans_release(handle); alpm_release(handle); return 0; } ``` -------------------------------- ### Pacman: Database Operations Source: https://context7.com/archlinux/alpm/llms.txt Use `pacman -D` for database operations. It can mark packages as dependencies (`--asdeps`) or explicitly installed (`--asexplicit`). ```bash pacman -D --asdeps htop # mark as dependency ``` ```bash pacman -D --asexplicit htop # mark as explicitly installed ``` -------------------------------- ### Pacman.conf: Options and Repositories Source: https://context7.com/archlinux/alpm/llms.txt The `/etc/pacman.conf` file configures global pacman behavior and defines sync repositories. The `[options]` section sets libalpm parameters, while `[repo]` sections define sync databases. Common options include `RootDir`, `DBPath`, `CacheDir`, `LogFile`, `GPGDir`, `HookDir`, `HoldPkg`, `Architecture`, `ParallelDownloads`, `SigLevel`, `NoUpgrade`, `NoExtract`, `IgnorePkg`, `IgnoreGroup`, and `DownloadUser`. ```ini # /etc/pacman.conf [options] RootDir = / DBPath = /var/lib/pacman/ CacheDir = /var/cache/pacman/pkg/ LogFile = /var/log/pacman.log GPGDir = /etc/pacman.d/gnupg/ HookDir = /etc/pacman.d/hooks/ HoldPkg = pacman glibc Architecture = auto # Parallel downloads (libalpm 6.0+) ParallelDownloads = 5 # Signature verification SigLevel = Required DatabaseOptional # Never upgrade these files (leave as-is; new version saved as .pacnew) NoUpgrade = etc/passwd etc/group etc/shadow # Never extract these (silently skip) NoExtract = usr/share/locale/* # Ignore specific packages during sysupgrade IgnorePkg = linux linux-headers # Ignore an entire package group IgnoreGroup = kde-applications # Sandbox the download process under an unprivileged user DownloadUser = alpm # DisableSandboxFilesystem # uncomment to disable filesystem sandboxing ``` -------------------------------- ### System Upgrade (sysupgrade) Source: https://context7.com/archlinux/alpm/llms.txt Demonstrates how to use `alpm_sync_sysupgrade()` to scan for and stage outdated packages for an upgrade. It includes initialization, setting progress callbacks, registering synchronized databases, and committing the transaction. ```APIDOC ## System upgrade (sysupgrade) `alpm_sync_sysupgrade()` scans all installed packages and adds outdated ones to the active transaction. ```c #include #include static void progress_cb(void *ctx, alpm_progress_t prog, const char *pkg, int percent, size_t howmany, size_t current) { (void)ctx; printf("\r[%%zu/%%zu] %%s %%d%% ", current, howmany, pkg, percent); fflush(stdout); } int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_option_set_progresscb(handle, progress_cb, NULL); alpm_option_set_parallel_downloads(handle, 5); /* download 5 pkgs at once */ alpm_db_t *core = alpm_register_syncdb(handle, "core", ALPM_SIG_USE_DEFAULT); alpm_db_t *extra = alpm_register_syncdb(handle, "extra", ALPM_SIG_USE_DEFAULT); alpm_db_add_server(core, "https://mirror.example.com/archlinux/core/os/x86_64/"); alpm_db_add_server(extra, "https://mirror.example.com/archlinux/extra/os/x86_64/"); alpm_trans_init(handle, 0); /* 1 = allow downgrade if remote version is lower */ if (alpm_sync_sysupgrade(handle, 0) != 0) { fprintf(stderr, "sysupgrade staging failed: %s\n", alpm_strerror(alpm_errno(handle))); alpm_trans_release(handle); alpm_release(handle); return 1; } alpm_list_t *add = alpm_trans_get_add(handle); printf("%zu package(s) to upgrade\n", alpm_list_count(add)); alpm_list_t *data = NULL; if (alpm_trans_prepare(handle, &data) == 0) alpm_trans_commit(handle, &data); alpm_trans_release(handle); alpm_release(handle); return 0; } ``` ``` -------------------------------- ### Register Sync Databases and Set Mirrors Source: https://context7.com/archlinux/alpm/llms.txt Shows how to register a sync repository, add a mirror server, and update the local package databases. This includes setting the default signature level for databases. ```APIDOC ## Register sync databases and set mirrors `alpm_register_syncdb()` registers a named sync repository with a signature level. `alpm_db_add_server()` attaches a mirror URL. `alpm_db_update()` downloads the database files. ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } /* Set default signature level: databases must be signed */ alpm_option_set_default_siglevel(handle, ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL); /* Register the "core" repository */ alpm_db_t *db = alpm_register_syncdb(handle, "core", ALPM_SIG_USE_DEFAULT); if (!db) { fprintf(stderr, "failed to register db: %s\n", alpm_strerror(alpm_errno(handle))); alpm_release(handle); return 1; } /* Add a mirror */ alpm_db_add_server(db, "https://mirror.example.com/archlinux/core/os/x86_64/"); /* Force-refresh all registered sync databases */ alpm_list_t *dbs = alpm_get_syncdbs(handle); int ret = alpm_db_update(handle, dbs, 1 /*force*/); if (ret < 0) { fprintf(stderr, "db update failed: %s\n", alpm_strerror(alpm_errno(handle))); } else if (ret == 1) { printf("all databases are up to date\n"); } else { printf("databases refreshed\n"); } alpm_release(handle); return 0; } ``` ``` -------------------------------- ### Initialize and Release libalpm Handle Source: https://context7.com/archlinux/alpm/llms.txt Initializes the libalpm library context and releases it when done. Requires filesystem root and DB path. Always release the handle to clean up resources. ```c #include #include int main(void) { alpm_errno_t err = ALPM_ERR_OK; /* Initialize with filesystem root and DB path */ alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "failed to initialize alpm: %s\n", alpm_strerror(err)); return 1; } printf("libalpm version: %s\n", alpm_version()); printf("capabilities: 0x%x\n", alpm_capabilities()); /* Always release when done */ if (alpm_release(handle) != 0) { fprintf(stderr, "failed to release handle\n"); return 1; } return 0; } /* Expected output: libalpm version: 16.0.1 capabilities: 0x7 */ ``` -------------------------------- ### alpm_list_t Linked List Operations Source: https://context7.com/archlinux/alpm/llms.txt Provides an overview and examples of using `alpm_list_t` for managing collections of data, including adding, sorting, finding, and freeing list elements. ```APIDOC ## alpm_list_t Linked List ### Description A public doubly-linked list implementation used throughout libalpm for managing collections of items such as packages, dependencies, and strings. ### Core Functions - `alpm_list_add(list, data)`: Adds an element to the end of the list. - `alpm_list_add_sorted(list, data, cmp)`: Adds an element to a sorted list using a comparison function. - `alpm_list_find_str(list, str)`: Finds a string element in the list. - `alpm_list_count(list)`: Returns the number of elements in the list. - `alpm_list_next(item)`: Returns the next item in the list. - `alpm_list_free(list)`: Frees the list structure itself (does not free data). - `FREELIST(list)`: Macro to free the list and its data pointers. ### Example ```c #include #include #include #include static int strcmp_cb(const void *a, const void *b) { return strcmp((const char *)a, (const char *)b); } int main(void) { alpm_list_t *list = NULL; /* Build a list of strings */ list = alpm_list_add(list, strdup("pacman")); list = alpm_list_add(list, strdup("glibc")); list = alpm_list_add(list, strdup("bash")); printf("count: %zu\n", alpm_list_count(list)); /* 3 */ /* Sorted insert */ list = alpm_list_add_sorted(list, strdup("zsh"), strcmp_cb); /* Search */ char *found = alpm_list_find_str(list, "bash"); printf("found: %s\n", found ? found : "not found"); /* bash */ /* Iterate forwards and backwards */ for (alpm_list_t *i = list; i; i = alpm_list_next(i)) printf(" %s\n", (char *)i->data); /* Remove duplicates (after adding a dup) */ list = alpm_list_add(list, strdup("bash")); alpm_list_t *deduped = alpm_list_remove_dupes(list); printf("deduped count: %zu\n", alpm_list_count(deduped)); /* Free list AND its string contents */ FREELIST(list); alpm_list_free(deduped); /* data pointers already freed above */ return 0; } /* Output: count: 3 found: bash bash glibc pacman zsh deduped count: 4 */ ``` ``` -------------------------------- ### Initialize and Release Library Handle Source: https://context7.com/archlinux/alpm/llms.txt Demonstrates how to create and tear down the libalpm library context handle. The handle is required for all subsequent libalpm operations. ```APIDOC ## Initialize / release a library handle `alpm_initialize()` creates the library context handle, connects to the local package database, and writes the lockfile. Every other libalpm call requires the returned `alpm_handle_t *`. `alpm_release()` tears everything down cleanly. ```c #include #include int main(void) { alpm_errno_t err = ALPM_ERR_OK; /* Initialize with filesystem root and DB path */ alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "failed to initialize alpm: %s\n", alpm_strerror(err)); return 1; } printf("libalpm version: %s\n", alpm_version()); printf("capabilities: 0x%x\n", alpm_capabilities()); /* Always release when done */ if (alpm_release(handle) != 0) { fprintf(stderr, "failed to release handle\n"); return 1; } return 0; } /* Expected output: libalpm version: 16.0.1 capabilities: 0x7 */ ``` ``` -------------------------------- ### Register Sync Databases and Set Mirrors Source: https://context7.com/archlinux/alpm/llms.txt Registers a sync repository, adds a mirror URL, and updates the local database files. Ensures databases are signed using the default signature level. ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } /* Set default signature level: databases must be signed */ alpm_option_set_default_siglevel(handle, ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL); /* Register the "core" repository */ alpm_db_t *db = alpm_register_syncdb(handle, "core", ALPM_SIG_USE_DEFAULT); if (!db) { fprintf(stderr, "failed to register db: %s\n", alpm_strerror(alpm_errno(handle))); alpm_release(handle); return 1; } /* Add a mirror */ alpm_db_add_server(db, "https://mirror.example.com/archlinux/core/os/x86_64/"); /* Force-refresh all registered sync databases */ alpm_list_t *dbs = alpm_get_syncdbs(handle); int ret = alpm_db_update(handle, dbs, 1 /*force*/); if (ret < 0) { fprintf(stderr, "db update failed: %s\n", alpm_strerror(alpm_errno(handle))); } else if (ret == 1) { printf("all databases are up to date\n"); } else { printf("databases refreshed\n"); } alpm_release(handle); return 0; } ``` -------------------------------- ### Set Custom Callbacks for Logging, Download, and Questions Source: https://context7.com/archlinux/alpm/llms.txt Implement custom callbacks for logging, download progress, and answering questions using `alpm_option_set_*cb()` functions. These callbacks allow for custom handling of events during ALPM operations. ```c #include #include #include static void log_cb(void *ctx, alpm_loglevel_t level, const char *fmt, va_list args) { (void)ctx; if (level == ALPM_LOG_ERROR || level == ALPM_LOG_WARNING) { fprintf(stderr, level == ALPM_LOG_ERROR ? "[E] " : "[W] "); vfprintf(stderr, fmt, args); } } static void dl_cb(void *ctx, const char *filename, alpm_download_event_type_t type, void *data) { (void)ctx; if (type == ALPM_DOWNLOAD_PROGRESS) { alpm_download_event_progress_t *p = data; printf("\r %s: %lld / %lld bytes", filename, (long long)p->downloaded, (long long)p->total); fflush(stdout); } else if (type == ALPM_DOWNLOAD_COMPLETED) { printf("\n %s: done\n", filename); } } static void question_cb(void *ctx, alpm_question_t *q) { (void)ctx; /* Auto-answer: always say yes */ if (q->type == ALPM_QUESTION_REPLACE_PKG) q->replace.replace = 1; else if (q->type == ALPM_QUESTION_CONFLICT_PKG) q->conflict.remove = 1; else q->any.answer = 1; } int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) return 1; alpm_option_set_logcb(handle, log_cb, NULL); alpm_option_set_dlcb(handle, dl_cb, NULL); alpm_option_set_questioncb(handle, question_cb, NULL); alpm_option_set_parallel_downloads(handle, 4); alpm_logaction(handle, "myfrontend", "starting custom transaction\n"); alpm_release(handle); return 0; } ``` -------------------------------- ### Search Sync Database with Regex Source: https://context7.com/archlinux/alpm/llms.txt Searches a synchronized database for packages matching POSIX regular expressions. Requires registering a sync database and adding a server URL. ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_db_t *db = alpm_register_syncdb(handle, "extra", ALPM_SIG_USE_DEFAULT); alpm_db_add_server(db, "https://mirror.example.com/archlinux/extra/os/x86_64/"); /* Build needle list — each element is a regex */ alpm_list_t *needles = NULL; needles = alpm_list_add(needles, "^python-"); alpm_list_t *results = NULL; if (alpm_db_search(db, needles, &results) == 0) { for (alpm_list_t *i = results; i; i = alpm_list_next(i)) { alpm_pkg_t *p = (alpm_pkg_t *)i->data; printf("% -40s %s\n", alpm_pkg_get_name(p), alpm_pkg_get_version(p)); } alpm_list_free(results); } else { fprintf(stderr, "search error: %s\n", alpm_strerror(alpm_errno(handle))); } alpm_list_free(needles); alpm_release(handle); return 0; } ``` -------------------------------- ### Callback Handling for Logging, Download Progress, and Questions Source: https://context7.com/archlinux/alpm/llms.txt Shows how to set custom callback functions for logging, download progress, and interactive questions using `alpm_option_set_*cb()` functions. ```APIDOC ## Callback Functions ### Description Allows users to define custom behavior for logging messages, tracking download progress, and answering interactive questions during ALPM operations. ### Functions - `alpm_option_set_logcb(handle, log_cb, ctx)`: Sets a custom logging callback. - `alpm_option_set_dlcb(handle, dl_cb, ctx)`: Sets a custom download progress callback. - `alpm_option_set_questioncb(handle, question_cb, ctx)`: Sets a custom callback for handling user questions. ### Callback Signatures - **Log Callback:** `void log_cb(void *ctx, alpm_loglevel_t level, const char *fmt, va_list args)` - **Download Callback:** `void dl_cb(void *ctx, const char *filename, alpm_download_event_type_t type, void *data)` - **Question Callback:** `void question_cb(void *ctx, alpm_question_t *q)` ### Example ```c #include #include #include static void log_cb(void *ctx, alpm_loglevel_t level, const char *fmt, va_list args) { (void)ctx; if (level == ALPM_LOG_ERROR || level == ALPM_LOG_WARNING) { fprintf(stderr, level == ALPM_LOG_ERROR ? "[E] " : "[W] "); vfprintf(stderr, fmt, args); } } static void dl_cb(void *ctx, const char *filename, alpm_download_event_type_t type, void *data) { (void)ctx; if (type == ALPM_DOWNLOAD_PROGRESS) { alpm_download_event_progress_t *p = data; printf("\r %s: %lld / %lld bytes", filename, (long long)p->downloaded, (long long)p->total); fflush(stdout); } else if (type == ALPM_DOWNLOAD_COMPLETED) { printf("\n %s: done\n", filename); } } static void question_cb(void *ctx, alpm_question_t *q) { (void)ctx; /* Auto-answer: always say yes */ if (q->type == ALPM_QUESTION_REPLACE_PKG) q->replace.replace = 1; else if (q->type == ALPM_QUESTION_CONFLICT_PKG) q->conflict.remove = 1; else q->any.answer = 1; } int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) return 1; alpm_option_set_logcb(handle, log_cb, NULL); alpm_option_set_dlcb(handle, dl_cb, NULL); alpm_option_set_questioncb(handle, question_cb, NULL); alpm_option_set_parallel_downloads(handle, 4); alpm_logaction(handle, "myfrontend", "starting custom transaction\n"); alpm_release(handle); return 0; } ``` ``` -------------------------------- ### Load a package file from disk Source: https://context7.com/archlinux/alpm/llms.txt Details on how to load a package archive file directly from disk into an `alpm_pkg_t` structure, including options for full parsing and signature verification. ```APIDOC ## Load a package file from disk ### Description This function loads a package archive file (e.g., `.pkg.tar.*`) from the local filesystem into an `alpm_pkg_t` structure. The `full` parameter determines if the entire archive is parsed, which is necessary for accessing the file list. ### Function - `alpm_pkg_load(handle, path, full, siglevel, pkg)`: Loads the package from the specified `path`. `full` is a boolean indicating a full parse, `siglevel` specifies the signature verification level, and `pkg` is a pointer to store the loaded package structure. ### Parameters #### `path` (const char *) - The full path to the package archive file. #### `full` (int) - A non-zero value to perform a full parse of the archive, including the file list. Zero for a partial parse. #### `siglevel` (alpm_siglevel_t) - The signature verification level to use (e.g., `ALPM_SIG_USE_DEFAULT`). ### Example Usage ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_pkg_t *pkg = NULL; int ret = alpm_pkg_load(handle, "/var/cache/pacman/pkg/curl-8.5.0-1-x86_64.pkg.tar.zst", 1 /*full parse*/, ALPM_SIG_USE_DEFAULT, &pkg); if (ret != 0) { fprintf(stderr, "load error: %s\n", alpm_strerror(alpm_errno(handle))); alpm_release(handle); return 1; } printf("name: %s\n", alpm_pkg_get_name(pkg)); printf("version: %s\n", alpm_pkg_get_version(pkg)); printf("size: %lld bytes (compressed)\n", (long long)alpm_pkg_get_size(pkg)); printf("isize: %lld bytes (installed)\n", (long long)alpm_pkg_get_isize(pkg)); /* List files owned by the package */ alpm_filelist_t *fl = alpm_pkg_get_files(pkg); for (size_t i = 0; i < fl->count; i++) { printf(" %s\n", fl->files[i].name); } /* Check if a specific path is owned */ alpm_file_t *f = alpm_filelist_contains(fl, "usr/bin/curl"); if (f) printf("owns /usr/bin/curl (%lld bytes)\n", (long long)f->size); alpm_pkg_free(pkg); /* Only needed for file-loaded packages */ alpm_release(handle); return 0; } ``` ``` -------------------------------- ### Pacman: System Upgrade Source: https://context7.com/archlinux/alpm/llms.txt Use `pacman -Syu` to refresh package databases and upgrade all outdated packages. `pacman -Syuu` additionally allows downgrades. ```bash pacman -Syu # refresh databases AND upgrade ``` ```bash pacman -Syuu # allow downgrades ``` -------------------------------- ### Search a sync database with regex Source: https://context7.com/archlinux/alpm/llms.txt Explains how to search a synchronized package database using POSIX regular expressions to find matching packages. ```APIDOC ## Search a sync database with regex ### Description This function searches a specified synchronized package database using a list of POSIX regular expressions and returns all packages that match any of the provided patterns. ### Function - `alpm_db_search(db, needles, results)`: Searches the given database (`db`) for packages matching the regular expressions in `needles` and stores the results in `results`. ### Parameters #### `needles` (alpm_list_t *) - A list where each element is a POSIX regular expression string. ### Example Usage ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_db_t *db = alpm_register_syncdb(handle, "extra", ALPM_SIG_USE_DEFAULT); alpm_db_add_server(db, "https://mirror.example.com/archlinux/extra/os/x86_64/"); /* Build needle list — each element is a regex */ alpm_list_t *needles = NULL; needles = alpm_list_add(needles, "^python-"); alpm_list_t *results = NULL; if (alpm_db_search(db, needles, &results) == 0) { for (alpm_list_t *i = results; i; i = alpm_list_next(i)) { alpm_pkg_t *p = (alpm_pkg_t *)i->data; printf("% -40s %s\n", alpm_pkg_get_name(p), alpm_pkg_get_version(p)); } alpm_list_free(results); } else { fprintf(stderr, "search error: %s\n", alpm_strerror(alpm_errno(handle))); } alpm_list_free(needles); alpm_release(handle); return 0; } ``` ``` -------------------------------- ### Load Package File from Disk Source: https://context7.com/archlinux/alpm/llms.txt Loads a package archive (`.pkg.tar.*`) into an `alpm_pkg_t` structure. The `full` flag determines if the entire archive is parsed, which is necessary for retrieving the file list. ```c #include #include int main(void) { alpm_errno_t err; alpm_handle_t *handle = alpm_initialize("/", "/var/lib/pacman/", &err); if (!handle) { fprintf(stderr, "%s\n", alpm_strerror(err)); return 1; } alpm_pkg_t *pkg = NULL; int ret = alpm_pkg_load(handle, "/var/cache/pacman/pkg/curl-8.5.0-1-x86_64.pkg.tar.zst", 1 /*full parse*/, ALPM_SIG_USE_DEFAULT, &pkg); if (ret != 0) { fprintf(stderr, "load error: %s\n", alpm_strerror(alpm_errno(handle))); alpm_release(handle); return 1; } printf("name: %s\n", alpm_pkg_get_name(pkg)); printf("version: %s\n", alpm_pkg_get_version(pkg)); printf("size: %lld bytes (compressed)\n", (long long)alpm_pkg_get_size(pkg)); printf("isize: %lld bytes (installed)\n", (long long)alpm_pkg_get_isize(pkg)); /* List files owned by the package */ alpm_filelist_t *fl = alpm_pkg_get_files(pkg); for (size_t i = 0; i < fl->count; i++) { printf(" %s\n", fl->files[i].name); } /* Check if a specific path is owned */ alpm_file_t *f = alpm_filelist_contains(fl, "usr/bin/curl"); if (f) printf("owns /usr/bin/curl (%lld bytes)\n", (long long)f->size); alpm_pkg_free(pkg); /* Only needed for file-loaded packages */ alpm_release(handle); return 0; } ``` -------------------------------- ### Pacman: Files Database Source: https://context7.com/archlinux/alpm/llms.txt Use `pacman -F` to query the files database. It can show which package provides a path or list all files from a sync-db entry. ```bash pacman -F /usr/bin/curl # which package provides a path ``` ```bash pacman -Fl curl # list all files from the sync-db entry for curl ``` -------------------------------- ### Build Function in PKGBUILD Source: https://github.com/archlinux/alpm/pacman/blob/master/doc/PKGBUILD-example.txt Specifies the steps to configure and compile the source code. This function is executed during the package build process. ```bash build() { cd "$srcdir/$pkgname-$pkgver" ./configure --prefix=/usr make } ``` -------------------------------- ### Version Comparison Source: https://context7.com/archlinux/alpm/llms.txt Explains the `alpm_pkg_vercmp()` function for comparing Arch Linux version strings, which supports epoch, package release, and alphanumeric ordering. It also mentions the equivalent `vercmp` utility. ```APIDOC ## Version comparison — `alpm_pkg_vercmp()` / `vercmp` utility `alpm_pkg_vercmp()` compares two Arch version strings (supporting epoch, pkgrel, and alphanumeric ordering). The standalone `vercmp` binary wraps the same logic. ```c #include #include int main(void) { /* alpm_pkg_vercmp returns: 1 if a > b, 0 if equal, -1 if a < b */ printf("%d\n", alpm_pkg_vercmp("2.0-1", "1.9-2")); /* 1 (newer) */ printf("%d\n", alpm_pkg_vercmp("1.0", "1.0-1")); /* 0 (equal, pkgrel ignored) */ printf("%d\n", alpm_pkg_vercmp("1.0a", "1.0b")); /* -1 (older) */ printf("%d\n", alpm_pkg_vercmp("1:1.0", "2.5-1")); /* 1 (epoch overrides) */ return 0; } /* Equivalent shell invocations: $ vercmp 2.0-1 1.9-2 => 1 $ vercmp 1.0 1.0-1 => 0 $ vercmp 1.0a 1.0b => -1 $ vercmp 1:1.0 2.5-1 => 1 */ ``` ```