diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-08-12 19:17:46 +0300 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-08-12 19:17:46 +0300 |
commit | 36b5cee98b1e80a493d291e9bffa1ed120ed908a (patch) | |
tree | 88855947e73b5e0f0a0dda3bd138064c401ff441 /src/package.c | |
parent | dee6ffa492c2efee982dcd0b4724213317eceb37 (diff) | |
download | apk-tools-36b5cee98b1e80a493d291e9bffa1ed120ed908a.tar.gz apk-tools-36b5cee98b1e80a493d291e9bffa1ed120ed908a.tar.bz2 apk-tools-36b5cee98b1e80a493d291e9bffa1ed120ed908a.tar.xz apk-tools-36b5cee98b1e80a493d291e9bffa1ed120ed908a.zip |
db, pkg: separate structure for fields of installed packages
this makes the database package entry smaller, and we propbably
get more fields to installed_package later too. this cleans up
the way scripts are stored and is a preparation for supporting
triggers. some parsing for trigger meta-data. ref #45.
Diffstat (limited to 'src/package.c')
-rw-r--r-- | src/package.c | 189 |
1 files changed, 101 insertions, 88 deletions
diff --git a/src/package.c b/src/package.c index 33d6519..24faaaf 100644 --- a/src/package.c +++ b/src/package.c @@ -53,13 +53,52 @@ void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to) struct apk_package *apk_pkg_new(void) { - struct apk_package *pkg; + return calloc(1, sizeof(struct apk_package)); +} - pkg = calloc(1, sizeof(struct apk_package)); - if (pkg != NULL) - list_init(&pkg->installed_pkgs_list); +struct apk_installed_package *apk_pkg_install(struct apk_database *db, + struct apk_package *pkg) +{ + struct apk_installed_package *ipkg; + + if (pkg->ipkg != NULL) + return pkg->ipkg; + + pkg->ipkg = ipkg = calloc(1, sizeof(struct apk_installed_package)); + ipkg->pkg = pkg; + list_init(&ipkg->installed_pkgs_list); + + db->installed.stats.packages++; + list_add_tail(&ipkg->installed_pkgs_list, &db->installed.packages); + + return ipkg; +} + +void apk_pkg_uninstall(struct apk_database *db, struct apk_package *pkg) +{ + struct apk_installed_package *ipkg = pkg->ipkg; + int i; + + if (ipkg == NULL) + return; + + if (db != NULL) + db->installed.stats.packages--; - return pkg; + list_del(&ipkg->installed_pkgs_list); + + if (ipkg->triggers) { + list_del(&ipkg->trigger_pkgs_list); + for (i = 0; i < ipkg->triggers->num; i++) + free(ipkg->triggers->item[i]); + free(ipkg->triggers); + } + + for (i = 0; i < APK_SCRIPT_MAX; i++) + if (ipkg->script[i].ptr != NULL) + free(ipkg->script[i].ptr); + free(ipkg); + pkg->ipkg = NULL; } int apk_pkg_parse_name(apk_blob_t apkname, @@ -293,6 +332,7 @@ const char *apk_script_types[] = { [APK_SCRIPT_POST_DEINSTALL] = "post-deinstall", [APK_SCRIPT_PRE_UPGRADE] = "pre-upgrade", [APK_SCRIPT_POST_UPGRADE] = "post-upgrade", + [APK_SCRIPT_TRIGGER] = "trigger", }; int apk_script_type(const char *name) @@ -763,15 +803,10 @@ err: void apk_pkg_free(struct apk_package *pkg) { - struct apk_script *script; - struct hlist_node *c, *n; - if (pkg == NULL) return; - hlist_for_each_entry_safe(script, c, n, &pkg->scripts, script_list) - free(script); - + apk_pkg_uninstall(NULL, pkg); if (pkg->depends) free(pkg->depends); if (pkg->version) @@ -785,106 +820,84 @@ void apk_pkg_free(struct apk_package *pkg) free(pkg); } -int apk_pkg_get_state(struct apk_package *pkg) -{ - if (list_hashed(&pkg->installed_pkgs_list)) - return APK_PKG_INSTALLED; - return APK_PKG_NOT_INSTALLED; -} - -void apk_pkg_set_state(struct apk_database *db, struct apk_package *pkg, int state) -{ - switch (state) { - case APK_PKG_INSTALLED: - if (!list_hashed(&pkg->installed_pkgs_list)) { - db->installed.stats.packages++; - list_add_tail(&pkg->installed_pkgs_list, - &db->installed.packages); - } - break; - case APK_PKG_NOT_INSTALLED: - if (list_hashed(&pkg->installed_pkgs_list)) { - db->installed.stats.packages--; - list_del(&pkg->installed_pkgs_list); - } - break; - } -} - -int apk_pkg_add_script(struct apk_package *pkg, struct apk_istream *is, - unsigned int type, unsigned int size) +int apk_ipkg_add_script(struct apk_installed_package *ipkg, + struct apk_istream *is, + unsigned int type, unsigned int size) { - struct apk_script *script; + void *ptr; int r; - script = malloc(sizeof(struct apk_script) + size); - script->type = type; - script->size = size; - r = is->read(is, script->script, size); + if (type >= APK_SCRIPT_MAX) + return -1; + + ptr = malloc(size); + r = is->read(is, ptr, size); if (r < 0) { - free(script); + free(ptr); return r; } - hlist_add_head(&script->script_list, &pkg->scripts); - return r; + if (ipkg->script[type].ptr) + free(ipkg->script[type].ptr); + ipkg->script[type].ptr = ptr; + ipkg->script[type].len = size; + return 0; } -int apk_pkg_run_script(struct apk_package *pkg, int root_fd, - unsigned int type) +int apk_ipkg_run_script(struct apk_installed_package *ipkg, int root_fd, + unsigned int type, char **argv) { - static const char * const environment[] = { + static char * const environment[] = { "PATH=/usr/sbin:/usr/bin:/sbin:/bin", NULL }; - struct apk_script *script; - struct hlist_node *c; + struct apk_package *pkg = ipkg->pkg; + char fn[PATH_MAX]; int fd, status; pid_t pid; - char fn[PATH_MAX]; - hlist_for_each_entry(script, c, &pkg->scripts, script_list) { - if (script->type != type) - continue; + if (type >= APK_SCRIPT_MAX) + return -1; - /* Avoid /tmp as it can be mounted noexec */ - snprintf(fn, sizeof(fn), "var/cache/misc/%s-%s.%s", - pkg->name->name, pkg->version, - apk_script_types[type]); + if (ipkg->script[type].ptr == NULL) + return 0; + + argv[0] = (char *) apk_script_types[type]; + /* Avoid /tmp as it can be mounted noexec */ + snprintf(fn, sizeof(fn), "var/cache/misc/%s-%s.%s", + pkg->name->name, pkg->version, + apk_script_types[type]); + + fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755); + if (fd < 0) { + mkdirat(root_fd, "var/cache/misc", 0755); fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755); - if (fd < 0) { - mkdirat(root_fd, "var/cache/misc", 0755); - fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0755); - if (fd < 0) - return -errno; - } - write(fd, script->script, script->size); - close(fd); + if (fd < 0) + return -errno; + } + write(fd, ipkg->script[type].ptr, ipkg->script[type].len); + close(fd); - apk_message("Executing %s", &fn[15]); + apk_message("Executing %s", &fn[15]); - pid = fork(); - if (pid == -1) - return -1; - if (pid == 0) { - fchdir(root_fd); - if (chroot(".") < 0) { - apk_error("chroot: %s", strerror(errno)); - } else { - execle(fn, apk_script_types[type], - pkg->version, "", NULL, environment); - } - exit(1); - } - waitpid(pid, &status, 0); - unlinkat(root_fd, fn, 0); - if (WIFEXITED(status)) - return WEXITSTATUS(status); + pid = fork(); + if (pid == -1) return -1; + if (pid == 0) { + fchdir(root_fd); + if (chroot(".") < 0) { + apk_error("chroot: %s", strerror(errno)); + } else { + execve(fn, argv, environment); + } + exit(1); } - - return 0; + waitpid(pid, &status, 0); + unlinkat(root_fd, fn, 0); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + return -1; } static int parse_index_line(void *ctx, apk_blob_t line) |