/* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc * Copyright (C) 2009, 2011, 2012, 2014 J. Ali Harlow * * 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 * (at your option) 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 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _RAZOR_H_ #define _RAZOR_H_ #include #include /* GCC extensions */ #if defined(__GNUC__) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) #define RAZOR_MALLOC __attribute__((__malloc__)) #else #define RAZOR_MALLOC #endif #if __GNUC__ >= 4 #define RAZOR_NULL_TERMINATED __attribute__ ((__sentinel__)) #else #define RAZOR_NULL_TERMINATED #endif #endif /* __GNUC__ */ enum razor_section_type { RAZOR_SECTION_MAIN = 0x01, RAZOR_SECTION_DETAILS = 0x02, RAZOR_SECTION_FILES = 0x04, RAZOR_SECTION_ALL = 0x07 }; enum razor_stage_type { RAZOR_STAGE_SCRIPTS_PRE = 0x1, RAZOR_STAGE_FILES = 0x2, RAZOR_STAGE_SCRIPTS_POST = 0x4, RAZOR_STAGE_SCRIPTS = 0x5, RAZOR_STAGE_ALL = 0x7 }; enum razor_detail_type { RAZOR_DETAIL_LAST = 0, /* the sentinel */ RAZOR_DETAIL_NAME, RAZOR_DETAIL_VERSION, RAZOR_DETAIL_ARCH, RAZOR_DETAIL_SUMMARY, RAZOR_DETAIL_DESCRIPTION, RAZOR_DETAIL_URL, RAZOR_DETAIL_LICENSE, RAZOR_DETAIL_PREUNPROG, RAZOR_DETAIL_PREUN, RAZOR_DETAIL_POSTUNPROG, RAZOR_DETAIL_POSTUN, RAZOR_DETAIL_PREFIXES }; enum razor_property_flags { RAZOR_PROPERTY_LESS = 1 << 0, RAZOR_PROPERTY_GREATER = 1 << 1, RAZOR_PROPERTY_EQUAL = 1 << 2, RAZOR_PROPERTY_RELATION_MASK = RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL, RAZOR_PROPERTY_REQUIRES = 0 << 3, RAZOR_PROPERTY_PROVIDES = 1 << 3, RAZOR_PROPERTY_CONFLICTS = 2 << 3, RAZOR_PROPERTY_OBSOLETES = 3 << 3, RAZOR_PROPERTY_TYPE_MASK = 3 << 3, RAZOR_PROPERTY_PRE = 1 << 5, RAZOR_PROPERTY_POST = 1 << 6, RAZOR_PROPERTY_PREUN = 1 << 7, RAZOR_PROPERTY_POSTUN = 1 << 8, RAZOR_PROPERTY_SCRIPT_MASK = RAZOR_PROPERTY_PRE | RAZOR_PROPERTY_POST | RAZOR_PROPERTY_PREUN | RAZOR_PROPERTY_POSTUN }; enum razor_set_flags { /* * Create a private copy of the razor set such that changes made * to the underlying file are not visible in the razor set. * If this flag is not set then the caller must ensure that the * underlying file (if any) is not changed. */ RAZOR_SET_PRIVATE = 1 << 0, }; /** * SECTION:error * @title: Error reporting * @short_description: A system for reporting errors. * * This object represents an error condition. */ struct razor_error; struct razor_error *razor_error_new_str(int domain, int code, const char *object, const char *str); struct razor_error *razor_error_dup(struct razor_error *src, const char *summary); #define razor_set_error(error, domain, code, object, str) \ if (error) \ *(error) = razor_error_new_str(domain, code, object, str); \ else #define razor_propagate_error(dest, src, summary) \ if (dest) \ *(dest) = razor_error_dup(src, summary); \ else #define RAZOR_ERROR_DOMAIN(i1,i2,i3,c) \ (((i1)&0xff)<<24|((i2)&0xff)<<16|((i3)&0xff)<<8|(c)&0xff) #define RAZOR_GENERAL_ERROR RAZOR_ERROR_DOMAIN('R','z','r',0) #define RAZOR_POSIX_ERROR RAZOR_ERROR_DOMAIN('R','z','r',1) #define RAZOR_MSWIN_ERROR RAZOR_ERROR_DOMAIN('R','z','r',2) #define RAZOR_ZLIB_ERROR RAZOR_ERROR_DOMAIN('R','z','r',3) enum razor_general_error { RAZOR_GENERAL_ERROR_FAILED, RAZOR_GENERAL_ERROR_DATABASE_CORRUPTED, RAZOR_GENERAL_ERROR_DATABASE_INCOMPATIBLE, RAZOR_GENERAL_ERROR_DATABASE_EXISTS, RAZOR_GENERAL_ERROR_DATABASE_LOCKED, RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, }; int razor_error_get_domain(struct razor_error *error); int razor_error_get_code(struct razor_error *error); const char *razor_error_get_object(struct razor_error *error); const char *razor_error_get_primary_text(struct razor_error *error); const char *razor_error_get_secondary_text(struct razor_error *error); const char *razor_error_get_msg(struct razor_error *error); void razor_error_free(struct razor_error *error); /** * SECTION:atomic * @title: Atomic transactions * @short_description: File-based transactions that shouldn't half-succeed * * This is a helper object for issuing a sequence of file-based actions * that should either all succeed or all fail. * * Note that currently only Windows 7 has a native implementation and that * while the emulated fallback implementation attempts to rollback the * transaction if it fails, this is not guaranteed to succeed and that * the transaction is held in core (and thus vulnernable to program crashes, * power loss, etc.). This could (and should) be improved. * * Atomic transactions can be disabled via configure, in which case all * bets are off. **/ struct razor_atomic; struct razor_atomic *razor_atomic_open(const char *description); int razor_atomic_commit(struct razor_atomic *atomic); struct razor_error *razor_atomic_get_error(struct razor_atomic *atomic); const char *razor_atomic_get_error_msg(struct razor_atomic *atomic); void razor_atomic_destroy(struct razor_atomic *atomic); /** * razor_atomic_make_dirs * * Create all sub-directories leading up to path. We know root exists * and is a dir, root does not end in a '/', and path either has a * leading '/' or (on MS-Windows only) root is the empty string * and path starts with drive (eg., "c:/windows"). * Note: path itself is not created, only the directory in which it * (would) exist. * * Returns: non-zero on error. **/ int razor_atomic_make_dirs(struct razor_atomic *atomic, const char *root, const char *path); int razor_atomic_remove(struct razor_atomic *atomic, const char *path); int razor_atomic_rename_file(struct razor_atomic *atomic, const char *oldpath, const char *newpath); /** * razor_atomic_create_dir * * Create a directory, replacing any existing object at this path except * an existing directory (which is not counted as a error). * * Returns: non-zero on error. */ int razor_atomic_create_dir(struct razor_atomic *atomic, const char *dirname, mode_t mode); /** * razor_atomic_create_symlink * * Create a symbolic link, replacing any existing object at this path except * a non-empty directory. * * Note: This function will always fail on platforms that don't support * symbolic links. * * Returns: non-zero on error. */ int razor_atomic_create_symlink(struct razor_atomic *atomic, const char *target, const char *path); /** * razor_atomic_create_file * * Create a file, replacing any existing object at this path except * a non-empty directory. * * Returns: A handle to be passed to razor_atomic_write() and * razor_atomic_close() or a negative value on error. */ int razor_atomic_create_file(struct razor_atomic *atomic, const char *filename, mode_t mode); int razor_atomic_write(struct razor_atomic *atomic, int handle, const void *data, size_t size); int razor_atomic_close(struct razor_atomic *atomic, int handle); int razor_atomic_sync(struct razor_atomic *atomic, int handle); void razor_atomic_abort(struct razor_atomic *atomic, int domain, int code, const char *error_msg); void razor_atomic_propagate_error(struct razor_atomic *atomic, struct razor_error *error, const char *summary); int razor_atomic_in_error_state(struct razor_atomic *atomic); /** * SECTION:set * @title: Package Set * @short_description: Represents a set of packages and their metadata. * * This object represents a set of packages, their dependency * information, the file lists and a number of other details. **/ struct razor_set; struct razor_package; struct razor_property; #define RAZOR_HEADER_VERSION 2 /* Current version */ #define RAZOR_HEADER_VERSION_MIN 1 /* Minimum version we support */ /** * razor_set_create: * * Create a new #razor_set object. * * Returns: the new #razor_set object. **/ struct razor_set *razor_set_create_without_root(void); struct razor_set *razor_set_create(void); struct razor_set * razor_set_open(const char *filename, enum razor_set_flags flags, struct razor_error **error); uint32_t razor_set_get_header_version(struct razor_set *set); int razor_set_set_header_version(struct razor_set *set, uint32_t header_version); void razor_set_unref(struct razor_set *set); struct razor_set *razor_set_ref(struct razor_set *set); void razor_set_write_to_handle(struct razor_set *set, struct razor_atomic *atomic, int handle, uint32_t section_mask); int razor_set_write(struct razor_set *set, struct razor_atomic *atomic, const char *filename, uint32_t setions); int razor_set_bind_sections(struct razor_set *set, const char *filename, enum razor_set_flags flags, struct razor_error **error); struct razor_package * razor_set_get_package(struct razor_set *set, const char *package); void razor_package_get_details(struct razor_set *set, struct razor_package *package, ...); int razor_package_remove(struct razor_set *prev, struct razor_set *next, struct razor_atomic *atomic, struct razor_package *package, const char *root, int install_count, enum razor_stage_type stage); /** * SECTION:iterator * @title: Iterators * @short_description: Objects for traversing packages or properties. * * The razor iterator objects provides a way to iterate through a set * of packages or properties. **/ struct razor_package_iterator; /** * razor_package_iterator_create: * * Create a new #razor_package_iterator object. * * Returns: the new #razor_package_iterator object. **/ struct razor_package_iterator * razor_package_iterator_create(struct razor_set *set); /** * razor_package_iterator_create_for_property: * * Create a new #razor_package_iterator object for the packages that * own the given property. * * Returns: the new #razor_package_iterator object. **/ struct razor_package_iterator * razor_package_iterator_create_for_property(struct razor_set *set, struct razor_property *property); /** * razor_package_iterator_create_for_file: * * Create a new #razor_package_iterator object for the packages that * contain the given file name. * * Returns: the new #razor_package_iterator object. **/ struct razor_package_iterator * razor_package_iterator_create_for_file(struct razor_set *set, const char *filename); int razor_package_iterator_next(struct razor_package_iterator *pi, struct razor_package **package, ...); void razor_package_iterator_destroy(struct razor_package_iterator *pi); struct razor_package_query * razor_package_query_create(struct razor_set *set); void razor_package_query_add_package(struct razor_package_query *pq, struct razor_package *p); void razor_package_query_add_iterator(struct razor_package_query *pq, struct razor_package_iterator *pi); struct razor_package_iterator * razor_package_query_finish(struct razor_package_query *pq); struct razor_property_iterator; struct razor_property_iterator * razor_property_iterator_create(struct razor_set *set, struct razor_package *package); int razor_property_iterator_next(struct razor_property_iterator *pi, struct razor_property **property, const char **name, uint32_t *flags, const char **version); void razor_property_iterator_destroy(struct razor_property_iterator *pi); struct razor_file_iterator; struct razor_file_iterator * razor_file_iterator_create(struct razor_set *set, struct razor_package *package, int post_order); int razor_file_iterator_next(struct razor_file_iterator *fi, const char **name); void razor_file_iterator_destroy(struct razor_file_iterator *fi); void razor_set_list_files(struct razor_set *set, const char *prefix); void razor_set_list_package_files(struct razor_set *set, struct razor_package *package); enum razor_diff_action { RAZOR_DIFF_ACTION_ADD, RAZOR_DIFF_ACTION_REMOVE, }; typedef void (*razor_diff_callback_t)(enum razor_diff_action action, struct razor_package *package, const char *name, const char *version, const char *arch, void *data); void razor_set_diff(struct razor_set *set, struct razor_set *upstream, razor_diff_callback_t callback, void *data); struct razor_install_iterator; enum razor_install_action { RAZOR_INSTALL_ACTION_ADD, RAZOR_INSTALL_ACTION_REMOVE, RAZOR_INSTALL_ACTION_COMMIT }; struct razor_install_iterator * razor_set_create_install_iterator(struct razor_set *set, struct razor_set *next); int razor_install_iterator_next(struct razor_install_iterator *ii, struct razor_package **package, enum razor_install_action *action, int *count); /** * razor_install_iterator_commit_set * * Immediately after razor_install_iterator_next() returns * RAZOR_INSTALL_ACTION_COMMIT, this function will return the razor_set * which should be committed. * * Returns: a new #razor_set object. **/ struct razor_set * razor_install_iterator_commit_set(struct razor_install_iterator *ii); void razor_install_iterator_rewind(struct razor_install_iterator *ii); size_t razor_install_iterator_tell(struct razor_install_iterator *ii); size_t razor_install_iterator_seek(struct razor_install_iterator *ii, size_t pos); void razor_install_iterator_destroy(struct razor_install_iterator *ii); /** * SECTION:transaction * @title: Transaction * @short_description: Create a new package set by merging two or more sets. * * The razor transaction object provides a way to create a new package set * from packages from one or more other package sets. **/ struct razor_rpm; struct razor_transaction * razor_transaction_create(struct razor_set *system, struct razor_set *upstream); void razor_transaction_install_package(struct razor_transaction *transaction, struct razor_package *package); void razor_transaction_remove_package(struct razor_transaction *transaction, struct razor_package *package); void razor_transaction_update_package(struct razor_transaction *trans, struct razor_package *package); void razor_transaction_fixup_package(struct razor_transaction *trans, struct razor_package *package, struct razor_rpm *rpm); void razor_transaction_update_all(struct razor_transaction *transaction); int razor_transaction_resolve(struct razor_transaction *trans); typedef void (*razor_unsatisfied_callback_t)(const char *requirement, struct razor_package *package, const char *name, const char *version, const char *arch, void *data); int razor_transaction_unsatisfied(struct razor_transaction *trans, razor_unsatisfied_callback_t callback, void *data); int razor_transaction_describe(struct razor_transaction *trans); struct razor_set *razor_transaction_commit(struct razor_transaction *trans); void razor_transaction_destroy(struct razor_transaction *trans); /* Temporary helper for test suite. */ int razor_transaction_unsatisfied_property(struct razor_transaction *trans, const char *name, uint32_t flags, const char *version); /** * SECTION:rpm * @title: Razor RPM * @short_description: Operating on RPM files. * * Functions for open RPM files and extracting information and * installing or removing RPM files. **/ struct razor_relocations; struct razor_relocations *razor_relocations_create(void); void razor_relocations_add(struct razor_relocations *relocations, const char *oldpath, const char *newpath); void razor_relocations_set_rpm(struct razor_relocations *relocations, struct razor_rpm *rpm); const char *razor_relocations_apply(struct razor_relocations *relocations, const char *path); void razor_relocations_destroy(struct razor_relocations *relocations); struct razor_rpm *razor_rpm_open(const char *filename, struct razor_error **error); void razor_rpm_get_details(struct razor_rpm *rpm, ...); void razor_rpm_set_relocations(struct razor_rpm *rpm, struct razor_relocations *relocations); int razor_rpm_install(struct razor_rpm *rpm, struct razor_atomic *atomic, const char *root, int install_count, enum razor_stage_type stage); int razor_rpm_close(struct razor_rpm *rpm); /** * SECTION:importer * @title: Importer * @short_description: A mechanism for building #razor_set objects * * The %razor_importer is a helper object for building a razor set * from external sources, like yum metadata, the RPM database or RPM * files. * * The importer is a stateful object; it has the notion of a current * package, and the caller can provide meta data such as properties, * files and similiar for the package as it becomes available. Once a * package is fully described, the next pacakge can begin. When all * packages have been described to the importer, the importer will * create a new %razor_set with the specified packages. * * A typical use * of the importer will follow this template: * |[ * importer = razor_importer_create(); * * while ( /* more packages to import */; ) { * /* get name, version and arch of next package */ * razor_importer_begin_package(importer, name, version, arch); * razor_importer_add_details(importer, summary, description, url, license); * * while ( /* more properties to add */ ) * razor_importer_add_property(importer, name, flags, version); * * while ( /* [more files to add */ ) * razor_importer_add_file(importer, name); * * razor_importer_finish_package(importer); * } * * return razor_importer_finish(importer); * ]| **/ struct razor_importer; struct razor_importer *razor_importer_create(void); void razor_importer_destroy(struct razor_importer *importer); void razor_importer_begin_package(struct razor_importer *importer, const char *name, const char *version, const char *arch); void razor_importer_add_details(struct razor_importer *importer, const char *summary, const char *description, const char *url, const char *license); void razor_importer_add_script(struct razor_importer *importer, enum razor_property_flags script, const char *program, const char *body); void razor_importer_add_install_prefix(struct razor_importer *importer, const char *install_prefix); void razor_importer_add_property(struct razor_importer *importer, const char *name, uint32_t flags, const char *version); void razor_importer_add_file(struct razor_importer *importer, const char *name); void razor_importer_finish_package(struct razor_importer *importer); int razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm); struct razor_set *razor_importer_finish(struct razor_importer *importer); struct razor_set *razor_set_create_from_yum(void); struct razor_set *razor_set_create_from_rpmdb(void); /** * SECTION:root * @title: Root * @short_description: Functions for accessing an install root. * * The #razor_root object encapsulate access to and locking of a razor * install root. **/ struct razor_root; const char *razor_get_database_path(); void razor_set_database_path(const char *database_path); int razor_root_create(const char *root, struct razor_error **error); struct razor_root * razor_root_open(const char *root, struct razor_error **error); struct razor_set * razor_root_open_read_only(const char *root, struct razor_error **error); struct razor_set *razor_root_get_system_set(struct razor_root *root); int razor_root_close(struct razor_root *root); int razor_root_update(struct razor_root *root, struct razor_set *next, struct razor_atomic *atomic); /** * SECTION:misc * @title: Miscellaneous Functions * @short_description: Various helper functions * * Functions that doesn't fit anywhere else. **/ const char * razor_property_relation_to_string(struct razor_property *p); const char * razor_property_type_to_string(struct razor_property *p); void razor_build_evr(char *evr_buf, int size, const char *epoch, const char *version, const char *release); int razor_versioncmp(const char *s1, const char *s2); void razor_disable_root_name_checks(int disable); void razor_set_lua_loader(const char *modname, void (*loader)()); void (*razor_get_lua_loader(const char *modname))(); char *razor_concat(const char *s, ...) RAZOR_MALLOC RAZOR_NULL_TERMINATED; char *razor_path_add_root(const char *path, const char *root) RAZOR_MALLOC; const char *razor_system_arch(void); #endif /* _RAZOR_H_ */