libslapt(3)

NAME
libslapt - slapt-get library

SYNOPSIS
#define _GNU_SOURCE
#include <slapt.h>
/* initialize slapt_config_t */
slapt_config_t *slapt_config_t_init(void);
/* parse config file for sources, excludes, and working_dir*/
slapt_config_t *config = slapt_config_t_read("/etc/slapt-get/slapt-getrc");
/* get a list of installed packages */
slapt_vector_t *installed = slapt_get_installed_pkgs();
/* parse the package data, normally using config->working_dir */
FILE *data_f = fopen("/var/cache/slapt-get/package_data","r");
slapt_vector_t *available = slapt_parse_packages_txt(data_f);
/* search for a package in a list via regex */
slapt_vector_t *results = slapt_search_pkg_list(installed,"[0-9]frg");
slapt_pkg_t_free_list(results);
/* look for a specific package */
slapt_pkg_t *pkg = slapt_get_exact_pkg(available,
                                            "slapt-get",
                                            "0.9.10c-i386-1");
if (!slapt_is_excluded(config,pkg)) {
  const char *error = slapt_download_pkg(config,pkg);
  if (error == NULL) {
    if (slapt_install_pkg(config,pkg) != 0) {
      fprintf(stderr,"error installing %s\n"pkg->name);
    }
    if (slapt_upgrade_pkg(config,pkg) != 0) {
      fprintf(stderr,"error upgrading %s\n"pkg->name);
    }
    if (slapt_remove_pkg(config,pkg) != 0) {
      fprintf(stderr,"error removing %s\n"pkg->name);
    }
  }
}
slapt_pkg_t_free(pkg);
if (slapt_pkg_t_cmp(pkg_a,pkg_b) = 0) {
  fprintf(stderr,"%s is equal to %s\n",pkg_a->version,pkg_b->version);
} elsif (slapt_pkg_t_cmp(pkg_a,pkg_b) < 0) {
  fprintf(stderr,"%s is less than %s\n",pkg_a->version,pkg_b->version);
} elsif (slapt_pkg_t_cmp(pkg_a,pkg_b) > 0) {
  fprintf(stderr,"%s is greater than %s\n",pkg_a->version,pkg_b->version);
}
slapt_pkg_t_free_list(available);
slapt_pkg_t_free_list(installed);
slapt_config_t_free(config);

DESCRIPTION
This is a short overview on how to use libslapt with your C programs.

CONFIGURATION

slapt-get stores the configuration information in a slapt_config_t object.  The configuration is parsed from the slapt-getrc which includes SOURCE, EXCLUDE, and WORKINGDIR directives.  Various runtime configuration options are also stored within the slapt_rc_config object.
      typedef struct {
        char working_dir[WORKINGDIR_TOKEN_LEN];
        slapt_vector_t *sources;
        slapt_vector_t *exclude_list;
        int (*progress_cb) (void *,off_t,off_t,off_t,off_t);
        bool download_only;
        bool dist_upgrade;
        bool simulate;
        bool no_prompt;
        bool re_install;
        bool ignore_excludes;
        bool no_md5_check;
        bool ignore_dep;
        bool disable_dep_check;
        bool print_uris;
        bool dl_stats;
        bool remove_obsolete;
        bool no_upgrade;
        uint32_t retry;
      } slapt_config_t;

The slapt_config_t is created with the slapt_config_t_read() function by passing in the file location of the configuration to parse, or by calling slapt_config_t_init() to return an empty, initialized slapt_rc_config.

    slapt_config_t *slapt_config_t_read(const char *file_name);

    slapt_config_t *slapt_config_t_init(void);

and is freed by a call to the slapt_config_t_free() function.

    void slapt_config_t_free(slapt_config_t *global_config);

The slapt-getrc configuration can be written back out with slapt_config_t_write.

    int slapt_config_t_write(const slapt_config_t *global_config, const char *location);

The progress callback is a function that is called while data is being downloaded.  It is in the format of int slapt_progress_callback(void *clientp, off_t dltotal, off_t dlnow, off_t ultotal, off_t ulnow);

Package sources are represented by the slapt_source_t type.  They are created, destroyed, and interacted with using the following functions:

      typedef struct {
        char *url;
        slapt_priority_t priority;
        bool disabled;
      } slapt_source_t;

    slapt_source_t *slapt_source_t_init(const char *s);
    void slapt_source_t_free(slapt_source_t *src);

In order to initialize the slapt_config_t->working_dir directory, slapt_working_dir_init() must be called.  It is a fatal error to call slapt_working_dir_init() with a directory that the current process does not have privileges to read, write, and execute.

    void slapt_working_dir_init(const slapt_config_t *global_config);

PACKAGES

slapt-get stores packages within slapt_pkg_t objects.

      typedef struct {
        char md5[SLAPT_MD5_STR_LEN];
        char *name;
        char *version;
        char *mirror;
        char *location;
        char *description;
        char *required;
        char *conflicts;
        char *suggests;
        char *file_ext;
        uint32_t size_c;
        uint32_t size_u;
        uint32_t priority;
        bool installed;
      } slapt_pkg_t;

The slapt_pkg_t object is created and freed with slapt_pkg_t_init() and slapt_pkg_t_free().  A slapt_pkg_t can also be copied with slapt_pkg_t_copy().

    slapt_pkg_t *slapt_pkg_t_init(void);
    void slapt_pkg_t_free(slapt_pkg_t *pkg);
    slapt_pkg_t *slapt_pkg_t_copy(slapt_pkg_t *dst,
                                     slapt_pkg_t *src);

Package lists are useful for grouping packages from the existing installed packages, packages available from external sources, a list of dependencies, and more.  Package lists are stored within a slapt_vector_t.

Package lists can be parsed from PACKAGES.TXT or similar formated files (such as the working_dir/package_data file used by slapt-get) with slapt_parse_packages_txt().  A package list of the currently installed packages is returned by slapt_get_installed_pkgs().  slapt_get_available_pkgs() is a frontend to slapt_parse_packages_txt() looking for a package_data file in the current directory.  All three of the following set free_pkgs to TRUE.

    slapt_vector_t *slapt_parse_packages_txt(FILE *);
    slapt_vector_t *slapt_get_available_pkgs(void);
    slapt_vector_t *slapt_get_installed_pkgs(void);

Finding a specific package in a package list is done through one of the following functions.  All return slapt_pkg_t, or NULL on error, except for slapt_search_pkg_list() which returns a list of packages as slapt_vector_t.

    slapt_pkg_t *slapt_get_newest_pkg(slapt_vector_t *,
                                           const char *);
    slapt_pkg_t *slapt_get_exact_pkg(slapt_vector_t *list,
                                          const char *name,
                                          const char *version);
    slapt_pkg_t *slapt_get_pkg_by_details(slapt_vector_t *list,
                                               const char *name,
                                               const char *version,
                                               const char *location);
    slapt_vector_t *slapt_search_pkg_list(slapt_vector_t *list,
                                                 const char *pattern);

Passing a package to installpkg, upgradepkg, and removepkg is done through the following functions.  All return 0 upon success, or non-zero on error.

    int slapt_install_pkg(const slapt_config_t *,slapt_pkg_t *);
    int slapt_upgrade_pkg(const slapt_config_t *global_config,
                          slapt_pkg_t *pkg);
    int slapt_remove_pkg(const slapt_config_t *,slapt_pkg_t *);

Comparing package versions is done with the slapt_pkg_t_cmp functions.  It calls slapt_pkg_t_cmp_versions() which returns just like strcmp, greater than 0 if a is greater than b, less than 0 if a is less than b, or 0 if a and b are equal.

    int slapt_pkg_t_cmp_versions(const char *a, const char *b);
    int slapt_pkg_t_cmp(slapt_pkg_t *a, slapt_pkg_t *b);

The following functions deal with determining package dependencies and conflicts and returning them within a package list.  Some require the use of a slapt_vector_t of slapt_pkg_err_t objects for reporting errors on which packages failed or were missing.  slapt_search_pkg_err_list() returns 0 if the package and error string combination does not already exist in the slapt_vector_t, or 1 if found.

      typedef struct {
        char *pkg;
        char *error;
      } slapt_pkg_err_t;

slapt_get_pkg_dependencies() fills a slapt_vector_t of dependencies for the specified package.  These dependencies are pulled from the available package list and the installed package lists.  Missing and conflict errors are placed in slapt_vector_t.  deps, conflict_err, and missing_err are initialized if NULL.  slapt_get_pkg_dependencies() returns 0 on success, or -1 on error.

    int slapt_get_pkg_dependencies(const slapt_config_t *global_config,
                                   slapt_vector_t *avail_pkgs,
                                   slapt_vector_t *installed_pkgs,
                                   slapt_pkg_t *pkg,
                                   slapt_vector_t *deps,
                                   slapt_vector_t *conflict_err,
                                   slapt_vector_t *missing_err);

slapt_get_pkg_conflicts() returns a slapt_vector_t of packages that conflict with the specified package.

    slapt_vector_t *
    slapt_get_pkg_conflicts(slapt_vector_t *avail_pkgs,
                            slapt_vector_t *installed_pkgs,
                            slapt_pkg_t *pkg);

slapt_is_required_by() returns a slapt_vector_t of packages that require the package specified.

    slapt_vector_t *
    slapt_is_required_by(const slapt_config_t *global_config,
                         slapt_vector_t *avail,
                         slapt_vector_t *installed_pkgs,
                         slapt_vector_t *pkgs_to_install,
                         slapt_vector_t *pkgs_to_remove,
                         slapt_pkg_t *pkg);

slapt_get_obsolete_pkgs() returns a slapt_vector_t of packages that are no longer available from the current package sources.

    slapt_vector_t *
      slapt_get_obsolete_pkgs ( const slapt_config_t *global_config,
                                slapt_vector_t *avail_pkgs,
                                slapt_vector_t *installed_pkgs);

slapt_is_excluded() returns 1 if package is present in the exclude list, 0 if not.

    int slapt_is_excluded(const slapt_config_t *,slapt_pkg_t *);

slapt_pkg_t_changelog() returns the package changelog entry, if any.  Otherwise returns NULL.  Assumes already chdir'd to the working directory.

    char *slapt_pkg_t_changelog(const slapt_pkg_t *pkg);

slapt_pkg_t_filelist() returns a string representing all of the files installed by the package.  This list is read from the package log file.

    char *slapt_pkg_t_filelist(const slapt_pkg_t *pkg);

slapt_pkg_t_string() returns a string representation of the package.

    char *slapt_pkg_t_string(const slapt_pkg_t *pkg);

slapt_gen_package_log_dir_name() returns a string location of the package log directory, accounting for the value of the ROOT environment variable, if set.

    char *slapt_gen_package_log_dir_name(void);

The working_dir, defined within the slapt_config_t object, caches the downloaded packages.  At various times it becomes necessary to purge the package cache.  slapt_clean_pkg_dir() unlinks all packages within the specified directory location.  slapt_purge_old_cached_pkgs() unlinks only packages that are not present in the current sources and thus are no longer downloadable.

    void slapt_clean_pkg_dir(const char *dir_name);
    void slapt_purge_old_cached_pkgs(const slapt_config_t *global_config,
                                     const char *dir_name,
                                     slapt_vector_t *avail_pkgs);

The slapt_pkg_t_clean_description() function is used to clean the package name from the package description.

    char *slapt_pkg_t_clean_description (const slapt_pkg_t *pkg);

DOWNLOADING

Downloading packages and the package data from various sources is handled with the following functions.  Functions with integer return types return non-zero on error.  slapt_update_pkg_cache() and slapt_get_available_pkgs() assume to be chdir'd to the working directory.

    int slapt_download_data(FILE *fh, const char *url, size_t bytes, long *filetime,
                      const slapt_config_t *global_config);
    int slapt_update_pkg_cache(const slapt_config_t *global_config);
    const char *slapt_download_pkg(const slapt_config_t *global_config,
                           slapt_pkg_t *pkg);
    slapt_code_t slapt_verify_downloaded_pkg(const slapt_config_t *global_config,
                                    slapt_pkg_t *pkg);

    const char *slapt_get_mirror_data_from_source(FILE *fh,
                                          const slapt_config_t *global_config,
                                          const char *base_url,
                                          const char *filename);
    char *slapt_head_request(const char *url);
    char *slapt_head_mirror_data(const char *wurl,const char *file);
    void slapt_clear_head_cache(const char *cache_filename);
    void slapt_write_head_cache(const char *cache, const char *cache_filename);
    char *slapt_read_head_cache(const char *cache_filename);

The following functions download the PACKAGES.TXT, the patches/PACKAGES.TXT, CHECKSUMS.md5, and ChangeLog.txt.  Each sets the compressed option if a compressed version was available and retrieved.

    slapt_vector_t *
    slapt_get_pkg_source_packages (const slapt_config_t *global_config,
                                   const char *url, bool *compressed);
    slapt_vector_t *
    slapt_get_pkg_source_patches (const slapt_config_t *global_config,
                                  const char *url, bool *compressed);
    FILE *slapt_get_pkg_source_checksums (const slapt_config_t *global_config,
                                          const char *url, bool *compressed);
    int slapt_get_pkg_source_changelog (const slapt_config_t *global_config,
                                          const char *url, bool *compressed);

Progress callbacks make use of struct slapt_progress_data.

      struct slapt_progress_data
      {
        size_t bytes;
        time_t start;
      };

    struct slapt_progress_data *slapt_init_progress_data(void);
    void slapt_free_progress_data(struct slapt_progress_data *d);

TRANSACTIONS

Adding, removing, and upgrading packages can be wrapped in a slapt_transaction_t object.  This structure will make sure that all packages are worked on in the specific order, downloaded, and handed off to the appropriate pkgtools command via the slapt_transaction_t_run() function.

      enum slapt_action {
        USAGE = 0, UPDATE, INSTALL, REMOVE, SHOW, SEARCH, UPGRADE,
        LIST, INSTALLED, CLEAN, SHOWVERSION, AUTOCLEAN, AVAILABLE
      };

      typedef struct {
        union { slapt_pkg_t *i; slapt_pkg_upgrade_t *u; } pkg;
        enum slapt_action type;
      } slapt_queue_i;

      typedef struct {
        slapt_pkg_t *installed;
        slapt_pkg_t *upgrade;
        bool reinstall;
      } slapt_pkg_upgrade_t;

      typedef struct {
        slapt_vector_t *install_pkgs;
        slapt_vector_t *upgrade_pkgs;
        slapt_vector_t *remove_pkgs;
        slapt_vector_t *exclude_pkgs;
        slapt_vector_t *suggests;
        slapt_vector_t *conflict_err;
        slapt_vector_t *missing_err;
        slapt_vector_t *queue;
      } slapt_transaction_t;

    slapt_transaction_t *slapt_transaction_t_init(void);
    void slapt_transaction_t_free(slapt_transaction_t *);
    int slapt_transaction_t_run(const slapt_config_t *,slapt_transaction_t *);

    void slapt_transaction_t_add_install(slapt_transaction_t *,
                                          slapt_pkg_t *pkg);

    void slapt_transaction_t_add_remove(slapt_transaction_t *,
                                         slapt_pkg_t *pkg);

    void slapt_transaction_t_add_upgrade(slapt_transaction_t *,
                                          slapt_pkg_t *installed_pkg,
                                          slapt_pkg_t *upgrade_pkg);

    void slapt_transaction_t_add_reinstall(slapt_transaction_t *,
                                          slapt_pkg_t *installed_pkg,
                                          slapt_pkg_t *upgrade_pkg);

    void slapt_transaction_t_add_exclude(slapt_transaction_t *,
                                          slapt_pkg_t *pkg);

    slapt_transaction_t *slapt_transaction_t_remove(slapt_transaction_t *trxn,
                                                       slapt_pkg_t *pkg);

    int slapt_transaction_t_search(slapt_transaction_t *,char *pkg_name);
    int slapt_transaction_t_search_by_pkg(slapt_transaction_t *trxn,
                                        slapt_pkg_t *pkg);

    int slapt_transaction_t_search_upgrade(slapt_transaction_t *trxn,
                                         slapt_pkg_t *pkg);

    int slapt_transaction_t_add_dependencies(const slapt_config_t *global_config,
                                slapt_transaction_t *trxn,
                                slapt_vector_t *avail_pkgs,
                                slapt_vector_t *installed_pkgs,
                                slapt_pkg_t *pkg);

    slapt_pkg_t *slapt_transaction_t_find_conflicts(slapt_transaction_t *trxn,
                                          slapt_vector_t *avail_pkgs,
                                          slapt_vector_t *installed_pkgs,
                                          slapt_pkg_t *pkg);

    void slapt_transaction_t_suggestions(slapt_transaction_t *trxn);

GPG

Functionality for GPG verification of package sources.

Retrieve the signature file for CHECKSUMS.md5 (or the signature for CHECKSUMS.md5.gz).  Sets compressed depending on which was found.
    FILE *slapt_get_pkg_source_checksums_signature (const slapt_config_t *global_config,
                                                    const char *url,
                                                    bool *compressed);

Retrieve the GPG-KEY file from the package source, if available.  Returns NULL if not found.
    FILE *slapt_get_pkg_source_gpg_key(const slapt_config_t *global_config,
                                       const char *url,
                                       bool *compressed);

Add the GPG-Key to the local keyring. Returns one of the following: SLAPT_GPG_KEY_IMPORTED, SLAPT_GPG_KEY_NOT_IMPORTED, or SLAPT_GPG_KEY_UNCHANGED.
    slapt_code_t slapt_add_pkg_source_gpg_key (FILE *key);

Verify the signature is valid for the compressed or uncompressed checksum.  Returns one of the following: SLAPT_CHECKSUMS_VERIFIED, SLAPT_CHECKSUMS_MISSING_KEY, or SLAPT_CHECKSUMS_NOT_VERIFIED.
    slapt_code_t slapt_gpg_verify_checksums(FILE *checksums, FILE *signature);

MISCELLANEOUS

Miscellaneous functionality within libslapt.

      typedef struct {
        regmatch_t pmatch[SLAPT_MAX_REGEX_PARTS];
        regex_t regex;
        size_t nmatch;
        int reg_return;
      } slapt_regex_t;

    FILE *slapt_open_file(const char *file_name,const char *mode);
    slapt_regex_t *slapt_regex_t_init(const char *regex_string);
    void slapt_regex_t_execute(slapt_regex_t *regex_t,const char *string);
    void slapt_regex_t_free(slapt_regex_t *regex_t);
    void slapt_create_dir_structure(const char *dir_name);
    void slapt_gen_md5_sum_of_file(FILE *f,char *result_sum);
    int slapt_ask_yes_no(const char *format, ...);
    char *slapt_str_replace_chr(const char *string,const char find,
                                const char replace);
    void *slapt_malloc(size_t s);
    void *slapt_calloc(size_t n,size_t s);

      typedef enum {
        SLAPT_OK = 0,
        SLAPT_MD5_CHECKSUM_MISMATCH,
        SLAPT_MD5_CHECKSUM_MISSING,
        #ifdef SLAPT_HAS_GPGME
        SLAPT_GPG_KEY_IMPORTED,
        SLAPT_GPG_KEY_NOT_IMPORTED,
        SLAPT_GPG_KEY_UNCHANGED,
        SLAPT_CHECKSUMS_VERIFIED,
        SLAPT_CHECKSUMS_MISSING_KEY,
        SLAPT_CHECKSUMS_NOT_VERIFIED,
        #endif
        SLAPT_DOWNLOAD_INCOMPLETE
      } slapt_code_t;

    const char *slapt_strerror(slapt_code_t code);

      typedef enum {
          SLAPT_PRIORITY_DEFAULT = 0,
          SLAPT_PRIORITY_DEFAULT_PATCH,
          SLAPT_PRIORITY_PREFERRED,
          SLAPT_PRIORITY_PREFERRED_PATCH,
          SLAPT_PRIORITY_OFFICIAL,
          SLAPT_PRIORITY_OFFICIAL_PATCH,
          SLAPT_PRIORITY_CUSTOM,
          SLAPT_PRIORITY_CUSTOM_PATCH
      } slapt_priority_t;

    #define SLAPT_PRIORITY_DEFAULT_TOKEN DEFAULT
    #define SLAPT_PRIORITY_PREFERRED_TOKEN PREFERRED
    #define SLAPT_PRIORITY_OFFICIAL_TOKEN OFFICIAL
    #define SLAPT_PRIORITY_CUSTOM_TOKEN CUSTOM

    /* return human readable priority */
    const char *slapt_priority_to_str(slapt_priority_t priority);

    bool slapt_disk_space_check (const char *path,double space_needed);

LINKING WITH LIBSLAPT
You must link with -lslapt and with libcurl through the curl-config script. For example: `curl-config --libs` -lslapt. Optionally, gpgme may be linked into libslapt, which requires `gpgme-config --libs`.

SEE ALSO
libcurl(3) zlib(3)

AUTHOR
Jason Woodward <woodwardj@jaos.org>