commit 7f0603995e577b87a87cc5be70991b07e1065346
parent 4bb2cc57335f2ca3bab66e248982d8e6d743c24b
Author: sin <sin@2f30.org>
Date: Fri, 20 Jun 2014 17:20:51 +0100
Rework installation interfaces
Diffstat:
M | db.c | | | 216 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
M | db.h | | | 5 | +++-- |
M | installpkg.c | | | 19 | +++++-------------- |
3 files changed, 106 insertions(+), 134 deletions(-)
diff --git a/db.c b/db.c
@@ -101,39 +101,17 @@ db_free(struct db *db)
return 0;
}
-/* Update the db entry on disk for package `file' */
+/* Update the db entry on disk for package `pkg' */
int
-db_add(struct db *db, const char *file)
+db_add(struct db *db, struct pkg *pkg)
{
- char pkgpath[PATH_MAX];
char path[PATH_MAX];
- char tmp[PATH_MAX];
char *name, *version;
+ struct pkgentry *pe;
FILE *fp;
- struct archive *ar;
- struct archive_entry *entry;
- int r;
-
- if (!realpath(file, pkgpath)) {
- weprintf("realpath %s:", file);
- return -1;
- }
-
- ar = archive_read_new();
-
- archive_read_support_filter_gzip(ar);
- archive_read_support_filter_bzip2(ar);
- archive_read_support_filter_xz(ar);
- archive_read_support_format_tar(ar);
-
- if (archive_read_open_filename(ar, pkgpath, ARCHIVEBUFSIZ) < 0) {
- weprintf("archive_read_open_filename %s: %s\n", pkgpath,
- archive_error_string(ar));
- return -1;
- }
- parse_name(pkgpath, &name);
- parse_version(pkgpath, &version);
+ parse_name(pkg->path, &name);
+ parse_version(pkg->path, &version);
estrlcpy(path, db->path, sizeof(path));
estrlcat(path, "/", sizeof(path));
estrlcat(path, name, sizeof(path));
@@ -141,40 +119,21 @@ db_add(struct db *db, const char *file)
estrlcat(path, "#", sizeof(path));
estrlcat(path, version, sizeof(path));
}
+ free(name);
+ free(version);
if (!(fp = fopen(path, "w"))) {
weprintf("fopen %s:", path);
- free(name);
- free(version);
return -1;
}
- while (1) {
- r = archive_read_next_header(ar, &entry);
- if (r == ARCHIVE_EOF)
- break;
- if (r != ARCHIVE_OK) {
- weprintf("archive_read_next_header: %s\n",
- archive_error_string(ar));
- free(name);
- free(version);
- return -1;
- }
-
- estrlcpy(tmp, db->prefix, sizeof(tmp));
- estrlcat(tmp, "/", sizeof(tmp));
- estrlcat(tmp, archive_entry_pathname(entry),
- sizeof(tmp));
-
+ for (pe = pkg->head; pe; pe = pe->next) {
if (vflag == 1)
- printf("installed %s\n", tmp);
- fputs(archive_entry_pathname(entry), fp);
+ printf("installed %s\n", pe->path);
+ fputs(pe->path, fp);
fputc('\n', fp);
}
- free(name);
- free(version);
-
if (vflag == 1)
printf("adding %s\n", path);
fflush(fp);
@@ -182,8 +141,6 @@ db_add(struct db *db, const char *file)
weprintf("fsync %s:", path);
fclose(fp);
- archive_read_free(ar);
-
return 0;
}
@@ -262,69 +219,6 @@ db_links(struct db *db, const char *path)
return links;
}
-/* Check if the contents of package `file'
- * collide with corresponding entries in the filesystem */
-int
-db_collisions(struct db *db, const char *file)
-{
- char pkgpath[PATH_MAX];
- char path[PATH_MAX];
- char resolvedpath[PATH_MAX];
- struct archive *ar;
- struct archive_entry *entry;
- struct stat sb;
- int ok = 0, r;
-
- if (!realpath(file, pkgpath)) {
- weprintf("realpath %s:", file);
- return -1;
- }
-
- ar = archive_read_new();
-
- archive_read_support_filter_gzip(ar);
- archive_read_support_filter_bzip2(ar);
- archive_read_support_filter_xz(ar);
- archive_read_support_format_tar(ar);
-
- if (archive_read_open_filename(ar, pkgpath, ARCHIVEBUFSIZ) < 0) {
- weprintf("archive_read_open_filename %s: %s\n", pkgpath,
- archive_error_string(ar));
- return -1;
- }
-
- while (1) {
- r = archive_read_next_header(ar, &entry);
- if (r == ARCHIVE_EOF)
- break;
- if (r != ARCHIVE_OK) {
- weprintf("archive_read_next_header: %s\n",
- archive_error_string(ar));
- return -1;
- }
- estrlcpy(path, db->prefix, sizeof(path));
- estrlcat(path, "/", sizeof(path));
- estrlcat(path, archive_entry_pathname(entry), sizeof(path));
- if (access(path, F_OK) == 0) {
- if (stat(path, &sb) < 0) {
- weprintf("lstat %s:", archive_entry_pathname(entry));
- return -1;
- }
- if (S_ISDIR(sb.st_mode) == 0) {
- if (realpath(path, resolvedpath))
- weprintf("%s exists\n", resolvedpath);
- else
- weprintf("%s exists\n", path);
- ok = -1;
- }
- }
- }
-
- archive_read_free(ar);
-
- return ok;
-}
-
/* Load the package contents for the given `filename' */
struct pkg *
pkg_load(struct db *db, const char *filename)
@@ -354,8 +248,6 @@ pkg_load(struct db *db, const char *filename)
}
pkg = pkg_new(path, name, version);
- if (!pkg)
- return NULL;
if (!(fp = fopen(pkg->path, "r"))) {
weprintf("fopen %s:", pkg->path);
@@ -394,6 +286,65 @@ pkg_load(struct db *db, const char *filename)
return pkg;
}
+struct pkg *
+pkg_load_file(struct db *db, const char *filename)
+{
+ char path[PATH_MAX];
+ char *name, *version;
+ struct pkg *pkg;
+ struct pkgentry *pe;
+ struct archive *ar;
+ struct archive_entry *entry;
+ int r;
+
+ if (!realpath(filename, path)) {
+ weprintf("realpath %s:", filename);
+ return NULL;
+ }
+
+ parse_name(path, &name);
+ parse_version(path, &version);
+ pkg = pkg_new(path, name, version);
+ free(name);
+ free(version);
+
+ ar = archive_read_new();
+
+ archive_read_support_filter_gzip(ar);
+ archive_read_support_filter_bzip2(ar);
+ archive_read_support_filter_xz(ar);
+ archive_read_support_format_tar(ar);
+
+ if (archive_read_open_filename(ar, pkg->path, ARCHIVEBUFSIZ) < 0) {
+ weprintf("archive_read_open_filename %s: %s\n", pkg->path,
+ archive_error_string(ar));
+ pkg_free(pkg);
+ return NULL;
+ }
+
+ while (1) {
+ r = archive_read_next_header(ar, &entry);
+ if (r == ARCHIVE_EOF)
+ break;
+ if (r != ARCHIVE_OK) {
+ weprintf("archive_read_next_header: %s\n",
+ archive_error_string(ar));
+ pkg_free(pkg);
+ return NULL;
+ }
+ pe = emalloc(sizeof(*pe));
+ estrlcpy(pe->path, db->prefix, sizeof(pe->path));
+ estrlcat(pe->path, "/", sizeof(pe->path));
+ estrlcat(pe->path, archive_entry_pathname(entry), sizeof(pe->path));
+ pe->next = pkg->head;
+ pkg->head = pe;
+ }
+
+ archive_read_free(ar);
+
+ return pkg;
+}
+
/* Install the package `file' to disk */
int
pkg_install(struct db *db, const char *file)
@@ -540,6 +491,35 @@ pkg_remove(struct db *db, struct pkg *pkg)
return 0;
}
+/* Check if the contents of package `pkg'
+ * collide with corresponding entries in the filesystem */
+int
+pkg_collisions(struct pkg *pkg)
+{
+ char resolvedpath[PATH_MAX];
+ struct pkgentry *pe;
+ struct stat sb;
+ int ok = 0;
+
+ for (pe = pkg->head; pe; pe = pe->next) {
+ if (access(pe->path, F_OK) == 0) {
+ if (stat(pe->path, &sb) < 0) {
+ weprintf("lstat %s:", pe->path);
+ return -1;
+ }
+ if (S_ISDIR(sb.st_mode) == 0) {
+ if (realpath(pe->path, resolvedpath))
+ weprintf("%s exists\n", resolvedpath);
+ else
+ weprintf("%s exists\n", pe->path);
+ ok = -1;
+ }
+ }
+ }
+
+ return ok;
+}
+
/* Create a new package instance */
struct pkg *
pkg_new(const char *path, const char *name, const char *version)
diff --git a/db.h b/db.h
@@ -30,16 +30,17 @@ extern int vflag;
struct db *db_new(const char *);
int db_free(struct db *);
-int db_add(struct db *, const char *);
+int db_add(struct db *, struct pkg *);
int db_rm(struct pkg *);
int db_load(struct db *);
+struct pkg *pkg_load_file(struct db *, const char *);
int db_walk(struct db *, int (*)(struct db *, struct pkg *, void *), void *);
int db_links(struct db *, const char *);
-int db_collisions(struct db *, const char *);
struct pkg *pkg_load(struct db *, const char *);
int pkg_install(struct db *, const char *);
int pkg_remove(struct db *, struct pkg *);
+int pkg_collisions(struct pkg *);
struct pkg *pkg_new(const char *, const char *, const char *);
void pkg_free(struct pkg *);
diff --git a/installpkg.c b/installpkg.c
@@ -5,8 +5,6 @@
#include "db.h"
#include "util.h"
-static int collisions_cb(struct db *, struct pkg *, void *);
-
static void
usage(void)
{
@@ -22,6 +20,7 @@ int
main(int argc, char *argv[])
{
struct db *db;
+ struct pkg *pkg;
char path[PATH_MAX];
char *prefix = "/";
int i, r;
@@ -59,15 +58,16 @@ main(int argc, char *argv[])
}
if (vflag == 1)
printf("installing %s\n", path);
+ pkg = pkg_load_file(db, path);
if (fflag == 0) {
- r = db_walk(db, collisions_cb, path);
- if (r < 0) {
+ if (pkg_collisions(pkg) < 0) {
db_free(db);
printf("not installed %s\n", path);
exit(EXIT_FAILURE);
}
}
- db_add(db, path);
+ db_add(db, pkg);
+ /* TODO: fix pkg_install() to work with struct pkg */
pkg_install(db, path);
printf("installed %s\n", path);
}
@@ -76,12 +76,3 @@ main(int argc, char *argv[])
return EXIT_SUCCESS;
}
-
-static int
-collisions_cb(struct db *db, struct pkg *pkg, void *file)
-{
- (void) pkg;
- if (db_collisions(db, file) < 0)
- return -1;
- return 0;
-}