summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--src/apk_package.h14
-rw-r--r--src/database.c23
-rw-r--r--src/package.c126
4 files changed, 99 insertions, 65 deletions
diff --git a/TODO b/TODO
index cac06a4..9ee75c7 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,3 @@
-- New style scripts
- Internal gunzip (via lib) to speed up stuff, and avoid threads
- mmap() if possible for reading
diff --git a/src/apk_package.h b/src/apk_package.h
index c3649fd..68e63e1 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -18,12 +18,14 @@
struct apk_database;
struct apk_name;
-#define APK_SCRIPT_PRE_INSTALL 0
-#define APK_SCRIPT_POST_INSTALL 1
-#define APK_SCRIPT_PRE_DEINSTALL 2
-#define APK_SCRIPT_POST_DEINSTALL 3
-#define APK_SCRIPT_PRE_UPGRADE 4
-#define APK_SCRIPT_POST_UPGRADE 5
+#define APK_SCRIPT_INVALID -1
+#define APK_SCRIPT_GENERIC 0
+#define APK_SCRIPT_PRE_INSTALL 1
+#define APK_SCRIPT_POST_INSTALL 2
+#define APK_SCRIPT_PRE_DEINSTALL 3
+#define APK_SCRIPT_POST_DEINSTALL 4
+#define APK_SCRIPT_PRE_UPGRADE 5
+#define APK_SCRIPT_POST_UPGRADE 6
struct apk_script {
struct hlist_node script_list;
diff --git a/src/database.c b/src/database.c
index 168df04..6b32255 100644
--- a/src/database.c
+++ b/src/database.c
@@ -673,12 +673,16 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae,
struct apk_db_dir *dir;
struct apk_db_file *file;
const char *p;
- int r = 0, type;
+ int r = 0, type = APK_SCRIPT_INVALID;
- if (strcmp(ae->name, ".PKGINFO") == 0)
- return 0;
-
- if (strncmp(ae->name, "var/db/apk/", 11) == 0) {
+ /* Package metainfo and script processing */
+ if (ae->name[0] == '.') {
+ /* APK 2.0 format */
+ if (strcmp(ae->name, ".INSTALL") != 0)
+ return 0;
+ type = APK_SCRIPT_GENERIC;
+ } else if (strncmp(ae->name, "var/db/apk/", 11) == 0) {
+ /* APK 1.0 format */
p = &ae->name[11];
if (strncmp(p, pkg->name->name, strlen(pkg->name->name)) != 0)
return 0;
@@ -688,13 +692,17 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae,
p += strlen(pkg->version) + 1;
type = apk_script_type(p);
- if (type < 0)
+ if (type != APK_SCRIPT_INVALID)
return 0;
+ }
+ /* Handle script */
+ if (type != APK_SCRIPT_INVALID) {
ae->size -= apk_pkg_add_script(pkg, ae->read_fd,
type, ae->size);
- if (type == ctx->script) {
+ if (type == APK_SCRIPT_GENERIC ||
+ type == ctx->script) {
r = apk_pkg_run_script(pkg, db->root_fd, type);
if (r != 0)
apk_error("%s-%s: Failed to execute pre-install/upgrade script",
@@ -704,6 +712,7 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae,
return r;
}
+ /* Installable entry */
if (ctx->file_pkg_node == NULL)
ctx->file_pkg_node = hlist_tail_ptr(&pkg->owned_files);
diff --git a/src/package.c b/src/package.c
index bc517ad..1cbf203 100644
--- a/src/package.c
+++ b/src/package.c
@@ -49,15 +49,15 @@ int apk_pkg_parse_name(apk_blob_t apkname,
return 0;
}
-static char *trim(apk_blob_t str)
+static apk_blob_t trim(apk_blob_t str)
{
if (str.ptr == NULL || str.len < 1)
- return NULL;
+ return str;
if (str.ptr[str.len-2] == '\n')
- str.ptr[str.len-2] = 0;
+ return APK_BLOB_PTR_LEN(str.ptr, str.len-1);
- return str.ptr;
+ return str;
}
static void parse_depend(struct apk_database *db,
@@ -154,6 +154,15 @@ static const char *script_types[] = {
[APK_SCRIPT_POST_UPGRADE] = "post-upgrade",
};
+static const char *script_types2[] = {
+ [APK_SCRIPT_PRE_INSTALL] = "pre_install",
+ [APK_SCRIPT_POST_INSTALL] = "post_install",
+ [APK_SCRIPT_PRE_DEINSTALL] = "pre_deinstall",
+ [APK_SCRIPT_POST_DEINSTALL] = "post_deinstall",
+ [APK_SCRIPT_PRE_UPGRADE] = "pre_upgrade",
+ [APK_SCRIPT_POST_UPGRADE] = "post_upgrade",
+};
+
int apk_script_type(const char *name)
{
int i;
@@ -247,59 +256,69 @@ static int read_info_line(void *ctx, apk_blob_t line)
static int read_info_entry(struct apk_archive_entry *ae, void *ctx)
{
+ static struct {
+ const char *str;
+ char field;
+ } fields[] = {
+ { "DESC", 'T' },
+ { "WW", 'U' },
+ { "LICENSE", 'L' },
+ { "DEPEND", 'D' },
+ };
struct read_info_ctx *ri = (struct read_info_ctx *) ctx;
struct apk_database *db = ri->db;
struct apk_package *pkg = ri->pkg;
const int bsize = 4 * 1024;
apk_blob_t name, version;
char *slash, *str;
+ int i;
- if (strcmp(ae->name, ".PKGINFO") == 0) {
- apk_blob_t blob = apk_archive_entry_read(ae);
- apk_blob_for_each_segment(blob, "\n", read_info_line, ctx);
- free(blob.ptr);
- return 0;
- }
-
- if (strncmp(ae->name, "var/db/apk/", 11) != 0) {
- pkg->installed_size += (ae->size + bsize - 1) & ~(bsize - 1);
- return 0;
- }
-
- if (!S_ISREG(ae->mode))
- return 0;
-
- slash = strchr(&ae->name[11], '/');
- if (slash == NULL)
- return 0;
+ /* Meta info and scripts */
+ if (ae->name[0] == '.') {
+ /* APK 2.0 format */
+ if (strcmp(ae->name, ".PKGINFO") == 0) {
+ apk_blob_t blob = apk_archive_entry_read(ae);
+ apk_blob_for_each_segment(blob, "\n", read_info_line, ctx);
+ free(blob.ptr);
+ /* FIXME: all done after checking if .INSTALL exists */
+ return 0;
+ }
+ } else if (strncmp(ae->name, "var/db/apk/", 11) == 0) {
+ /* APK 1.0 format */
+ if (!S_ISREG(ae->mode))
+ return 0;
- if (apk_pkg_parse_name(APK_BLOB_PTR_PTR(&ae->name[11], slash-1),
- &name, &version) < 0)
- return -1;
+ slash = strchr(&ae->name[11], '/');
+ if (slash == NULL)
+ return 0;
- if (pkg->name == NULL) {
- str = apk_blob_cstr(name);
- pkg->name = apk_db_get_name(db, str);
- free(str);
- }
- if (pkg->version == NULL)
- pkg->version = apk_blob_cstr(version);
+ if (apk_pkg_parse_name(APK_BLOB_PTR_PTR(&ae->name[11], slash-1),
+ &name, &version) < 0)
+ return -1;
- if (strcmp(slash, "/DEPEND") == 0) {
- apk_blob_t blob = apk_archive_entry_read(ae);
- if (blob.ptr) {
- apk_deps_parse(db, &pkg->depends, blob);
- free(blob.ptr);
+ if (pkg->name == NULL) {
+ str = apk_blob_cstr(name);
+ pkg->name = apk_db_get_name(db, str);
+ free(str);
+ }
+ if (pkg->version == NULL)
+ pkg->version = apk_blob_cstr(version);
+
+ for (i = 0; i < ARRAY_SIZE(fields); i++) {
+ if (strcmp(fields[i].str, slash+1) == 0) {
+ apk_blob_t blob = apk_archive_entry_read(ae);
+ add_info(ri->db, ri->pkg, fields[i].field,
+ trim(blob));
+ free(blob.ptr);
+ break;
+ }
}
- } else if (strcmp(slash, "/DESC") == 0) {
- pkg->description = trim(apk_archive_entry_read(ae));
- } else if (strcmp(slash, "/WWW") == 0) {
- pkg->url = trim(apk_archive_entry_read(ae));
- } else if (strcmp(slash, "/LICENSE") == 0) {
- pkg->license = trim(apk_archive_entry_read(ae));
- } else if (apk_script_type(slash+1) == APK_SCRIPT_POST_INSTALL ||
- apk_script_type(slash+1) == APK_SCRIPT_PRE_INSTALL)
- ri->has_install = 1;
+ if (apk_script_type(slash+1) == APK_SCRIPT_POST_INSTALL ||
+ apk_script_type(slash+1) == APK_SCRIPT_PRE_INSTALL)
+ ri->has_install = 1;
+ } else {
+ pkg->installed_size += (ae->size + bsize - 1) & ~(bsize - 1);
+ }
return 0;
}
@@ -420,13 +439,14 @@ int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
fchdir(root_fd);
hlist_for_each_entry(script, c, &pkg->scripts, script_list) {
- if (script->type != type)
+ if (script->type != type &&
+ script->type != APK_SCRIPT_GENERIC)
continue;
snprintf(fn, sizeof(fn),
"tmp/%s-%s.%s",
pkg->name->name, pkg->version,
- script_types[script->type]);
+ script_types[type]);
fd = creat(fn, 0777);
if (fd < 0)
return fd;
@@ -441,13 +461,17 @@ int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
if (pid == 0) {
if (chroot(".") < 0) {
apk_error("chroot: %s", strerror(errno));
- } else
- execle(fn, script_types[script->type],
+ } else if (script->type == APK_SCRIPT_GENERIC) {
+ execle(fn, "INSTALL", script_types2[type],
+ pkg->version, "", NULL, environment);
+ } else {
+ execle(fn, script_types[type],
pkg->version, "", NULL, environment);
+ }
exit(1);
}
waitpid(pid, &status, 0);
- //unlink(fn);
+ unlink(fn);
if (WIFEXITED(status))
return WEXITSTATUS(status);
return -1;