libpkg(3) FreeBSD Library Functions Manual libpkg(3) NAME libpkg -- functions for managing binary packages LIBRARY library ``libpkg'' SYNOPSIS #include int pkg_delete_file_commit(struct pkg *); int pkg_delete_file(struct pkg *, const char *filename); const char * pkg_file_directory(struct pkg *, const char *filename); const char * pkg_first_file(struct pkg *); void pkg_free(struct pkg *); int pkg_is_metafile(struct pkg *, const char *filename); const char * pkg_next_file(struct pkg *); int pkg_register_metafile(struct pkg *, const char *filename, const char *text); int pkg_undelete_file(struct pkg *, const char *filename); int pkg_verify(struct pkg *); struct pkg * pkgdb_create_pkg(struct pkgdb *, const char *plist); struct pkgdb * pkgdb_default(void); struct pkgdb * pkgdb_delete_package(void); const char * pkgdb_first_pkg(struct pkgdb *); void pkgdb_free(struct pkgdb *); struct pkg * pkgdb_get_pkg(struct pkgdb *, const char *name); struct pkg * pkgdb_get_pkg_with_file(struct pkgdb *, const char *filename); const char * pkgdb_next_pkg(struct pkgdb *); struct pkgrepo * pkgrepo_default(void); struct pkgrepo * pkgrepo_dir(const char *path); void pkgrepo_free(struct pkgrepo *); struct pkgrepo * pkgrepo_ftp(const char *site, const char *path); FILE * pkgrepo_open(struct pkgrepo *, const char *package_name); OVERVIEW The libpkg library provides a set of APIs for locating package archives and managing installed packages. There are several fundamental concepts: package archive A ``package archive'' is a file (generally a tar.gz or tar.bz2 file) that contains information about a package. package A ``package'' is a collection of files on disk (for example, the files comprising an installed application) together with ``package metadata'' required to install/remove and otherwise manage those files as a unit. package object A package object is a handle for an installed package. You obtain a package object from the package database. Changes made to the package object affect the installed package on disk. For example, if you remove a file from the package object, that causes the corresponding file to be deleted from disk. package database A collection of information about installed packages. In partic- ular, you can ask the package database for a list of all installed packages or the name of a package containing a particu- lar file. package repository A place where package files are stored. This could be a direc- tory, a CD-ROM, or a remote FTP site. Some package repositories can provide information about package dependencies. Part of the goal is to remove the need for applications that deal with packages to know anything about the internal details of these systems. For example, the package database may be implemented as a collection of files stored in directories, as a Berkeley DB database file, or as a col- lection of tables in a relational database. Similarly, a package reposi- tory may be a remote FTP site, a CDROM, or a network directory. BASIC OPERATIONS There are several important high-level operations that can be performed on packages. The goal of this library is to provide the underlying machinery needed to support these actions. The key actions include: Installing a package To install a package, you must obtain a file handle from the package repository, interpret that file handle as a package ar- chive, obtain a package object from the package database, and copy the contents of the archive into the package. Deleting a package This requires obtaining a package object from the database, deleting the contents of the package, and finally deleting the object itself. Creating a package This requires creating a package object that describes a set of files on disk. Creating a package archive This requires that we already have a package object; we create the archive and add all of the on-disk files to that archive. (Note: unlike libarchive operation, this involves first register- ing all of the package contents with the archive, then creating the archive as a single step.) DESCRIPTION An installed package is represented by a struct pkg, which can be obtained from a package database. XXX More Details XXX EXAMPLES XXX Usage scenario: To install a package, ask for the default package repos- itory with pkgrepo_default(), then ask the repository for the named pack- age. It returns a FILE * that you pass to libarchive to unpack. The first item in the archive is the +CONTENTS packing list. Extract that into memory. Ask for the default package database using pkgdb_default(), and ask it to create a new package based on the contents of the packing list. You then continue extracting files from the archive. If the file- name starts with "+", then this file is meta-information that you regis- ter with the package. Otherwise, you ask the package what directory this file goes into, extract the file to that directory. Once all files have been extracted, you ask the package to verify itself (check that all files are where they should be; this also gives the package a chance to update permissions/owners that may have been stored in the packing list instead of the archive and to record/verify timestamps/sizes/checksums for each file). Do a final "commit" on the package and you're done. The above is complicated slightly if there are dependencies. Ideally, the package repository would be able to provide dependency information so that required packages could be installed first. For FTP repos, this requires downloading and caching the INDEX file, which probably won't be supported in the first draft of this library. Of course, arbitrary directories don't support this, so we can't depend on it in general any- way. When the package is created in the package database, the installer will have to ask the package for a list of dependencies. For each depen- dency, ask the package database if that dependency is already installed. If not, recursively install it from the repository. There are non-triv- ial complications with rollback: the installer needs to keep a list of all "in-progress" package installations so that, in the event of a fatal error, it can rollback the entire installation. CONFLICT HANDLING A key point about conflicts: packages do not conflict; files conflict. For example, it often makes perfect sense to have two versions of a library package installed, even though the documentation or programming header files may conflict. In practice, this means that conflict detec- tion and management needs to happen very early in the installation process. When the prototype package is first created, we need to ask the package for a list of files and see if any of those files already exist. For each file that does exist, we ask the package database for the pack- age containing that file. Once we've collected a list of all packages that conflict, we can give the user an option of o Remove the old package entirely. o Remove the conflicting file from the old package and from disk. o Skip the new file (remove it from the new package). o Skip the new package. Some kind of two-phase commit features would be really helpful here. In particular, "delete file" should probably rename the file on disk and mark the file as deleted. A later "commit" operation on the package would then actually delete the renamed file; conversely a "rollback" or "restore" operation would rename the file back. Use case: The package database and/or package APIs should handle a num- ber of high-level tasks, such as: deleting an entire package, renaming a package, generating a complete list of dependent packages, verifying the on-disk package, identifying the package containing a particular file, XXX other suggestions? XXX Future Directions: A key design goal here is to keep the interfaces generic so that the underlying implementations can be improved over time. In particular, I would like to see a configurable pkgrepo implementation that reads a configuration file with a list of available repositories (e.g., distribution CD-ROMs, FTP sites, etc) and then passes any requests along to each of them. Applications that simply ask for pkgrepo_default will always get a suitable default that varies depending on environment variables, etc. Similarly, the package database implementation can be easily changed to utilize a true database file without having to alter any of the programs that utilize the pkgdb API. RETURN VALUES XXX ENVIRONMENT XXX Several environment variables affect what pkgrepo or pkgdb object is returned by pkgrepo_default() or pkgdb_default(). SEE ALSO XXX HISTORY XXX AUTHORS XXX BUGS Most of this library has yet to be written. I'm working on it. FreeBSD 6.0 January 20, 2004 FreeBSD 6.0