Viewing file: slapt.h (20.46 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* * Copyright (C) 2003,2004,2005 Jason Woodward <woodwardj at jaos dot 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 * 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 Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <getopt.h> #include <curl/curl.h> #include <curl/types.h> #include <curl/easy.h> #include <regex.h> #include <errno.h> #include <sys/stat.h> #include <sys/types.h> #include <dirent.h> #include <ctype.h> #include <openssl/evp.h> #include <libintl.h> #include <locale.h> #include <sys/statvfs.h> #include <sys/mman.h> #include <zlib.h> #include <utime.h>
enum slapt_action { USAGE = 0, UPDATE, INSTALL, REMOVE, SHOW, SEARCH, UPGRADE, LIST, INSTALLED, CLEAN, SHOWVERSION, AUTOCLEAN, AVAILABLE, INSTALL_DISK_SET };
#define SLAPT_UPDATE_OPT 'u' #define SLAPT_UPGRADE_OPT 'g' #define SLAPT_INSTALL_OPT 'i' #define SLAPT_INSTALL_DISK_SET_OPT 'D' #define SLAPT_REMOVE_OPT 'r' #define SLAPT_SHOW_OPT 's' #define SLAPT_SEARCH_OPT 'e' #define SLAPT_LIST_OPT 't' #define SLAPT_INSTALLED_OPT 'd' #define SLAPT_CLEAN_OPT 'c' #define SLAPT_DOWNLOAD_ONLY_OPT 'o' #define SLAPT_SIMULATE_OPT 'm' #define SLAPT_VERSION_OPT 'v' #define SLAPT_NO_PROMPT_OPT 'b' #define SLAPT_PROMPT_OPT 'y' #define SLAPT_REINSTALL_OPT 'n' #define SLAPT_IGNORE_EXCLUDES_OPT 'x' #define SLAPT_NO_MD5_OPT '5' #define SLAPT_DIST_UPGRADE_OPT 'h' #define SLAPT_HELP_OPT 'l' #define SLAPT_IGNORE_DEP_OPT 'p' #define SLAPT_NO_DEP_OPT 'q' #define SLAPT_PRINT_URIS_OPT 'P' #define SLAPT_SHOW_STATS_OPT 'S' #define SLAPT_CONFIG_OPT 'C' #define SLAPT_AUTOCLEAN_OPT 'a' #define SLAPT_OBSOLETE_OPT 'O' #define SLAPT_AVAILABLE_OPT 'A' #define SLAPT_RETRY_OPT 'R' #define SLAPT_NO_UPGRADE_OPT 'N'
#define SLAPT_DEBUG 0 #define SLAPT_DO_NOT_UNLINK_BAD_FILES 1
#define SLAPT_MAX_REGEX_PARTS 10 #define SLAPT_SLACK_BASE_SET_REGEX "^./slackware/a$"
typedef enum { #if !defined(FALSE) && !defined(TRUE) SLAPT_FALSE = 0, SLAPT_TRUE #else SLAPT_FALSE = FALSE, SLAPT_TRUE = TRUE #endif } SLAPT_BOOL_T;
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_init_regex(const char *regex_string); void slapt_execute_regex(slapt_regex_t *regex_t,const char *string); void slapt_free_regex(slapt_regex_t *regex_t); void slapt_create_dir_structure(const char *dir_name); /* generate an md5sum of filehandle */ void slapt_gen_md5_sum_of_file(FILE *f,char *result_sum);
/* Ask the user to answer yes or no. * return 1 on yes, 0 on no, else -1. */ int slapt_ask_yes_no(const char *format, ...); char *slapt_str_replace_chr(const char *string,const char find, const char replace); __inline void *slapt_malloc(size_t s); __inline void *slapt_calloc(size_t n,size_t s);
#define SOURCE_TOKEN "SOURCE=" #define WORKINGDIR_TOKEN "WORKINGDIR=" #define WORKINGDIR_TOKEN_LEN 256 #define EXCLUDE_TOKEN "EXCLUDE="
struct slapt_exclude_list { char **excludes; unsigned int count; };
struct slapt_source_list { char **url; unsigned int count; };
typedef struct { char working_dir[WORKINGDIR_TOKEN_LEN]; struct slapt_source_list *sources; struct slapt_exclude_list *exclude_list; int(*progress_cb)(void *,double,double,double,double); SLAPT_BOOL_T download_only; SLAPT_BOOL_T dist_upgrade; SLAPT_BOOL_T simulate; SLAPT_BOOL_T no_prompt; SLAPT_BOOL_T prompt; SLAPT_BOOL_T re_install; SLAPT_BOOL_T ignore_excludes; SLAPT_BOOL_T no_md5_check; SLAPT_BOOL_T ignore_dep; SLAPT_BOOL_T disable_dep_check; SLAPT_BOOL_T print_uris; SLAPT_BOOL_T dl_stats; SLAPT_BOOL_T remove_obsolete; SLAPT_BOOL_T no_upgrade; unsigned int retry; } slapt_rc_config;
/* read the configuration from file_name returns (rc_config *) or NULL */ slapt_rc_config *slapt_read_rc_config(const char *file_name);
/* check that working_dir exists or make it if permissions allow */ void slapt_working_dir_init(const slapt_rc_config *global_config);
/* free rc_config structure */ void slapt_free_rc_config(slapt_rc_config *global_config);
/* add an exclude expression to the exclude list. commonly called with global_config->exclude_list */ void slapt_add_exclude(struct slapt_exclude_list *list,const char *e); void slapt_remove_exclude(struct slapt_exclude_list *list,const char *e);
/* add or remove a package source url to the source list. commonly called with global_config->source_list */ void slapt_add_source(struct slapt_source_list *list,const char *s); void slapt_remove_source (struct slapt_source_list *list, const char *s);
#define SLAPT_PKG_PARSE_REGEX "(.*{1,})\\-(.*[\\-].*[\\-].*).t[gbl]z[ ]{0,}$" #define SLAPT_PKG_NAMEVER "(.*{1,})\\-(.*[\\-].*[\\-].*)" #define SLAPT_PKG_VER "(.*)[\\-](.*)[\\-](.*)" #define SLAPT_PKG_NAME_PATTERN "^PACKAGE NAME:[ ]{1,}(.*{1,})\\-(.*[\\-].*[\\-].*)(.t[gbl]z)[ ]{0,}$" #define SLAPT_PKG_MIRROR_PATTERN "^PACKAGE MIRROR:[ ]+(.*)$" #define SLAPT_PKG_LOCATION_PATTERN "^PACKAGE LOCATION:[ ]+(.*)$" #define SLAPT_PKG_SIZEC_PATTERN "^PACKAGE SIZE [(]+compressed[)]{1,}:[ ]{1,}([0-9]{1,}) K$" #define SLAPT_PKG_SIZEU_PATTERN "^PACKAGE SIZE [(]+uncompressed[)]{1,}:[ ]{1,}([0-9]{1,}) K$" #define SLAPT_PKG_LOG_SIZEC_PATTERN "^COMPRESSED PACKAGE SIZE:[ ]{1,}([0-9]{1,}) K$" #define SLAPT_PKG_LOG_SIZEU_PATTERN "^UNCOMPRESSED PACKAGE SIZE:[ ]{1,}([0-9]{1,}) K$" #define SLAPT_PKG_LOG_DIR "/var/log/packages" #define SLAPT_ROOT_ENV_NAME "ROOT" #define SLAPT_ROOT_ENV_LEN 255 #define SLAPT_PKG_LOG_PATTERN "^(.*{1,})\\-(.*[\\-].*[\\-].*)" #define SLAPT_MD5SUM_REGEX "([a-zA-Z0-9]{1,})[ ]{1,}([a-zA-Z0-9\\/._\\-]{1,})\\/(.*{1,})\\-(.*[\\-].*[\\-].*).t[gbl]z$" #define SLAPT_REQUIRED_REGEX "^[ ]{0,}([a-zA-Z0-9\\+_\\-]+)[ ]{0,}([\\<\\=\\>]+){0,}[ ]{0,}([a-zA-Z0-9\\.\\_\\-]+){0,}[ ]{0,}$" #define SLAPT_MD5_STR_LEN 34 #define SLAPT_MD5_CHECKSUM_FAILED -100 #define SLAPT_PKG_LIST "PACKAGES.TXT" #define SLAPT_PKG_LIST_GZ "PACKAGES.TXT.gz" #define SLAPT_PKG_LIST_L "package_data" #define SLAPT_PATCHES_LIST "patches/PACKAGES.TXT" #define SLAPT_PATCHES_LIST_GZ "patches/PACKAGES.TXT.gz" #define SLAPT_CHANGELOG_FILE "ChangeLog.txt" #define SLAPT_CHANGELOG_FILE_GZ "ChangeLog.txt.gz" #define SLAPT_PATCHDIR "patches/" #define SLAPT_REMOVE_CMD "/sbin/removepkg " #define SLAPT_INSTALL_CMD "/sbin/installpkg " #define SLAPT_UPGRADE_CMD "/sbin/upgradepkg --reinstall " #define SLAPT_CHECKSUM_FILE "CHECKSUMS.md5" #define SLAPT_CHECKSUM_FILE_GZ "CHECKSUMS.md5.gz" #define SLAPT_HEAD_FILE_EXT ".head" #define SLAPT_MAX_MMAP_SIZE 1024 #define SLAPT_MAX_ZLIB_BUFFER 1024
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; unsigned int size_c; unsigned int size_u; } slapt_pkg_info_t;
struct slapt_pkg_list { slapt_pkg_info_t **pkgs; unsigned int pkg_count; SLAPT_BOOL_T free_pkgs; };
typedef struct { slapt_pkg_info_t *installed; slapt_pkg_info_t *upgrade; } slapt_pkg_upgrade_t;
struct slapt_pkg_upgrade_list { slapt_pkg_upgrade_t **pkgs; unsigned int pkg_count; };
struct slapt_pkg_version_parts { char **parts; unsigned int count; };
typedef struct { char *pkg; char *error; } slapt_pkg_err_t;
struct slapt_pkg_err_list { slapt_pkg_err_t **errs; unsigned int err_count; };
/* returns an empty package structure */ __inline slapt_pkg_info_t *slapt_init_pkg(void); /* frees the package structure */ void slapt_free_pkg(slapt_pkg_info_t *pkg);
/* create an empty package list */ struct slapt_pkg_list *slapt_init_pkg_list(void); /* add a package to a package list */ void slapt_add_pkg_to_pkg_list(struct slapt_pkg_list *list, slapt_pkg_info_t *pkg); /* free package list */ void slapt_free_pkg_list(struct slapt_pkg_list *);
/* update the local package cache */ int slapt_update_pkg_cache(const slapt_rc_config *global_config); /* write pkg data to disk */ void slapt_write_pkg_data(const char *source_url,FILE *d_file, struct slapt_pkg_list *pkgs); /* parse the PACKAGES.TXT file */ struct slapt_pkg_list *slapt_parse_packages_txt(FILE *); /* return a list of available packages must be already chdir'd to rc_config->working_dir. Otherwise, open a filehandle to the package data and pass it to slapt_parse_packages_txt(); */ struct slapt_pkg_list *slapt_get_available_pkgs(void); /* retrieve list of installed pkgs */ struct slapt_pkg_list *slapt_get_installed_pkgs(void);
/* retrieve the newest package from package list */ slapt_pkg_info_t *slapt_get_newest_pkg(struct slapt_pkg_list *,const char *); /* get the exact package */ slapt_pkg_info_t *slapt_get_exact_pkg(struct slapt_pkg_list *list, const char *name, const char *version); /* lookup package by details */ slapt_pkg_info_t *slapt_get_pkg_by_details(struct slapt_pkg_list *list, const char *name, const char *version, const char *location); /* search package list with pattern */ struct slapt_pkg_list *slapt_search_pkg_list(struct slapt_pkg_list *list, const char *pattern);
/* install package by calling installpkg returns 0 on success, -1 on error */ int slapt_install_pkg(const slapt_rc_config *,slapt_pkg_info_t *); /* upgrade package by calling upgradepkg returns 0 on success, -1 on error */ int slapt_upgrade_pkg(const slapt_rc_config *global_config, slapt_pkg_info_t *pkg); /* remove package by calling removepkg returns 0 on success, -1 on error */ int slapt_remove_pkg(const slapt_rc_config *,slapt_pkg_info_t *);
/* get a list of obsolete packages */ struct slapt_pkg_list * slapt_get_obsolete_pkgs ( const slapt_rc_config *global_config, struct slapt_pkg_list *avail_pkgs, struct slapt_pkg_list *installed_pkgs);
/* generate a short description, returns (char *) on success or NULL on error caller responsible for freeing the returned data */ char *slapt_gen_short_pkg_description(slapt_pkg_info_t *); /* generate the filename from the url caller responsible for freeing the returned data */ char *slapt_gen_filename_from_url(const char *url,const char *file); /* generate the package file name caller responsible for freeing the returned data */ char *slapt_gen_pkg_file_name(const slapt_rc_config *global_config, slapt_pkg_info_t *pkg); /* generate the head cache filename caller responsible for freeing the returned data */ char *slapt_gen_head_cache_filename(const char *filename_from_url); /* generate the download url for a package caller responsible for freeing the returned data */ char *slapt_gen_pkg_url(slapt_pkg_info_t *pkg); /* exclude pkg based on pkg name returns 1 if package is present in the exclude list, 0 if not present */ int slapt_is_excluded(const slapt_rc_config *,slapt_pkg_info_t *); /* package is already downloaded and cached, md5sum if applicable is ok returns 0 if download is cached, -1 if not */ int slapt_verify_downloaded_pkg(const slapt_rc_config *global_config, slapt_pkg_info_t *pkg); /* fill in the md5sum of the package */ void slapt_get_md5sums(struct slapt_pkg_list *pkgs, FILE *checksum_file); /* find out the pkg file size (post download) */ size_t slapt_get_pkg_file_size(const slapt_rc_config *global_config, slapt_pkg_info_t *pkg);
/* compare package versions returns just like strcmp, > 0 if a is greater than b < 0 if a is less than b 0 if a and b are equal */ int slapt_cmp_pkg_versions(const char *a, const char *b); #define slapt_cmp_pkgs(x,y) slapt_cmp_pkg_versions(x->version,y->version)
/* resolve dependencies returns 0 on success, -1 on error setting conflict_err and missing_err (usually called with transaction->conflict_err and transaction->missing_err) */ int slapt_get_pkg_dependencies(const slapt_rc_config *global_config, struct slapt_pkg_list *avail_pkgs, struct slapt_pkg_list *installed_pkgs, slapt_pkg_info_t *pkg, struct slapt_pkg_list *deps, struct slapt_pkg_err_list *conflict_err, struct slapt_pkg_err_list *missing_err); /* return list of package conflicts */ struct slapt_pkg_list *slapt_get_pkg_conflicts(struct slapt_pkg_list *avail_pkgs, struct slapt_pkg_list *installed_pkgs, slapt_pkg_info_t *pkg); /* return list of packages required by */ struct slapt_pkg_list *slapt_is_required_by(const slapt_rc_config *global_config, struct slapt_pkg_list *avail, slapt_pkg_info_t *pkg);
/* empty packages from cache dir */ void slapt_clean_pkg_dir(const char *dir_name); /* clean out old outdated packages in the cache that are no longer available in the current source lists (ie are not downloadable) */ void slapt_purge_old_cached_pkgs(const slapt_rc_config *global_config, const char *dir_name, struct slapt_pkg_list *avail_pkgs);
/* make a copy of a package (needs to be freed with free_pkg) */ slapt_pkg_info_t *slapt_copy_pkg(slapt_pkg_info_t *dst,slapt_pkg_info_t *src);
/* package error handling api to handle errors within core functions */ struct slapt_pkg_err_list *slapt_init_pkg_err_list(void); void slapt_add_pkg_err_to_list(struct slapt_pkg_err_list *l, const char *pkg,const char *err); int slapt_search_pkg_err_list(struct slapt_pkg_err_list *l, const char *pkg, const char *err); void slapt_free_pkg_err_list(struct slapt_pkg_err_list *l);
/* download the PACKAGES.TXT and CHECKSUMS.md5 files */ struct slapt_pkg_list *slapt_get_pkg_source_packages (const slapt_rc_config *global_config, const char *url); struct slapt_pkg_list *slapt_get_pkg_source_patches (const slapt_rc_config *global_config, const char *url); FILE *slapt_get_pkg_source_checksums (const slapt_rc_config *global_config, const char *url); int slapt_get_pkg_source_changelog (const slapt_rc_config *global_config, const char *url);
/* clean package name from package description */ void slapt_clean_description (char *description, const char *name);
/* retrieve the packages changelog entry, if any. Returns NULL otherwise */ char *slapt_get_pkg_changelog(const slapt_pkg_info_t *pkg);
char *slapt_stringify_pkg(const slapt_pkg_info_t *pkg);
/* retrieves the head data for the url, returns (char *) or NULL on error */ char *slapt_head_request(const char *url);
/* this fills FILE with data from url, used for PACKAGES.TXT and CHECKSUMS returns 0 on success, on error -1 or CURLE_HTTP_RANGE_ERROR */ int slapt_get_mirror_data_from_source(FILE *fh, const slapt_rc_config *global_config, const char *base_url, const char *filename);
/* download pkg, calls download_data returns 0 on success, on error -1 or CURLE_HTTP_RANGE_ERROR */ int slapt_download_pkg(const slapt_rc_config *global_config, slapt_pkg_info_t *pkg);
/* this is the default progress callback if global_config->progress_cb == NULL */ int slapt_progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
/* do a head request on the mirror data to find out if it's new returns (char *) or NULL */ char *slapt_head_mirror_data(const char *wurl,const char *file); /* clear head cache storage file */ void slapt_clear_head_cache(const char *cache_filename); /* cache the head request */ void slapt_write_head_cache(const char *cache, const char *cache_filename); /* read the cached head request returns (char *) or NULL */ char *slapt_read_head_cache(const char *cache_filename);
/* this defines the max length of the transaction summary lines, hopefully someday this will be replaced with a more dynamic solution. */ #define MAX_LINE_LEN 80
struct slapt_suggests { char **pkgs; unsigned int count; };
typedef struct { union { slapt_pkg_info_t *i; slapt_pkg_upgrade_t *u; } pkg; unsigned int type; /* this is enum slapt_action defined in main.h */ } slapt_queue_i;
typedef struct { slapt_queue_i **pkgs; unsigned int count; } slapt_queue_t;
typedef struct { struct slapt_pkg_list *install_pkgs; struct slapt_pkg_upgrade_list *upgrade_pkgs; struct slapt_pkg_list *remove_pkgs; struct slapt_pkg_list *exclude_pkgs; struct slapt_suggests *suggests; struct slapt_pkg_err_list *conflict_err; struct slapt_pkg_err_list *missing_err; slapt_queue_t *queue; } slapt_transaction_t;
/* fill in transaction structure with defaults */ slapt_transaction_t *slapt_init_transaction(void); /* download and install/remove/upgrade packages as defined in the transaction returns 0 on success */ int slapt_handle_transaction(const slapt_rc_config *,slapt_transaction_t *);
/* add package for installation to transaction */ void slapt_add_install_to_transaction(slapt_transaction_t *, slapt_pkg_info_t *pkg); /* add package for removal to transaction */ void slapt_add_remove_to_transaction(slapt_transaction_t *, slapt_pkg_info_t *pkg); /* add package to upgrade to transaction */ void slapt_add_upgrade_to_transaction(slapt_transaction_t *, slapt_pkg_info_t *installed_pkg, slapt_pkg_info_t *upgrade_pkg); /* add package to exclude to transaction */ void slapt_add_exclude_to_transaction(slapt_transaction_t *, slapt_pkg_info_t *pkg); /* remove package from transaction, returns modified transaction */ slapt_transaction_t *slapt_remove_from_transaction(slapt_transaction_t *tran, slapt_pkg_info_t *pkg);
/* search transaction by package name. returns 1 if found, 0 otherwise */ int slapt_search_transaction(slapt_transaction_t *,char *pkg_name); /* search transaction by package attributes returns 1 if found, 0 otherwise */ int slapt_search_transaction_by_pkg(slapt_transaction_t *tran, slapt_pkg_info_t *pkg); /* searches the upgrade list of the transaction for the present of the package returns 1 if found, 0 if not found */ int slapt_search_upgrade_transaction(slapt_transaction_t *tran, slapt_pkg_info_t *pkg);
/* add dependencies for package to transaction, returns -1 on error, 0 otherwise */ int slapt_add_deps_to_trans(const slapt_rc_config *global_config, slapt_transaction_t *tran, struct slapt_pkg_list *avail_pkgs, struct slapt_pkg_list *installed_pkgs, slapt_pkg_info_t *pkg);
/* check to see if a package has a conflict already present in the transaction returns conflicted package or NULL if none */ slapt_pkg_info_t *slapt_is_conflicted(slapt_transaction_t *tran, struct slapt_pkg_list *avail_pkgs, struct slapt_pkg_list *installed_pkgs, slapt_pkg_info_t *pkg);
/* generate a list of suggestions based on the current packages in the transaction */ void slapt_generate_suggestions(slapt_transaction_t *tran);
/* free the transaction structure and it's members */ void slapt_free_transaction(slapt_transaction_t *);
|