[Midnightbsd-cvs] src: lib/libmport: Latest developement version.
ctriv at midnightbsd.org
ctriv at midnightbsd.org
Thu Nov 22 03:00:32 EST 2007
Log Message:
-----------
Latest developement version. Nearing completion of package installation.
Modified Files:
--------------
src/lib/libmport:
Makefile (r1.2 -> r1.3)
create_pkg.c (r1.6 -> r1.7)
db_schema.c (r1.3 -> r1.4)
error.c (r1.4 -> r1.5)
mport.h (r1.4 -> r1.5)
util.c (r1.6 -> r1.7)
Added Files:
-----------
src/lib/libmport:
db_stub.c (r1.1)
db_util.c (r1.1)
inst_init.c (r1.1)
install_pkg.c (r1.1)
-------------- next part --------------
--- /dev/null
+++ lib/libmport/db_stub.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2007 Chris Reinhardt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $MidnightBSD: src/lib/libmport/db_stub.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $
+ */
+
+
+
+#include <sqlite3.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mport.h"
+
+__MBSDID("$MidnightBSD: src/lib/libmport/db_stub.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $");
+
+int mport_attach_stub_db(sqlite3 *db, const char *dir)
+{
+ char *file;
+ asprintf(&file, "%s/%s", dir, MPORT_STUB_DB_FILE);
+
+ if (mport_db_do(db, "ATTACH %s AS stub", file) != MPORT_OK) {
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+ }
+
+ free(file);
+
+ return MPORT_OK;
+}
+
+int mport_get_meta_from_db(sqlite3 *db, mportPackageMeta **ref)
+{
+ mportPackageMeta *pack = *ref;
+ sqlite3_stmt *stmt;
+ const char *tmp = 0;
+
+ pack = mport_new_packagemeta();
+
+ if (pack == NULL)
+ return MPORT_ERR_NO_MEM;
+
+ if (sqlite3_prepare_v2(db, "SELECT (pkg, version, origin, lang, prefix) FROM stub.package", -1, &stmt, &tmp) != SQLITE_OK)
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+
+ if (sqlite3_step(stmt) != SQLITE_DONE)
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+
+ /* Copy pkg to pack->name */
+ if ((tmp = sqlite3_column_text(stmt, 0)) == NULL)
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+
+ if ((pack->name = strdup(tmp)) == NULL)
+ return MPORT_ERR_NO_MEM;
+
+ /* Copy version to pack->version */
+ if ((tmp = sqlite3_column_text(stmt, 1)) == NULL)
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+
+ if ((pack->version = strdup(tmp)) == NULL)
+ return MPORT_ERR_NO_MEM;
+
+ /* Copy origin to pack->origin */
+ if ((tmp = sqlite3_column_text(stmt, 2)) == NULL)
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+
+ if ((pack->origin = strdup(tmp)) == NULL)
+ return MPORT_ERR_NO_MEM;
+
+ /* Copy lang to pack->lang */
+ if ((tmp = sqlite3_column_text(stmt, 4)) == NULL)
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+
+ if ((pack->lang = strdup(tmp)) == NULL)
+ return MPORT_ERR_NO_MEM;
+
+ /* Copy prefix to pack->prefix */
+ if ((tmp = sqlite3_column_text(stmt, 5)) == NULL)
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+
+ if ((pack->prefix = strdup(tmp)) == NULL)
+ return MPORT_ERR_NO_MEM;
+
+ sqlite3_finalize(stmt);
+
+ return MPORT_OK;
+}
+
--- /dev/null
+++ lib/libmport/inst_init.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2007 Chris Reinhardt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $MidnightBSD: src/lib/libmport/inst_init.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $
+ */
+
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <sqlite3.h>
+#include "mport.h"
+
+__MBSDID("$MidnightBSD: src/lib/libmport/inst_init.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $");
+
+
+static int create_master_db(sqlite3 **);
+
+/* set up the master database, and related instance infrastructure. */
+int mport_inst_init(sqlite3 **db)
+{
+ if (mkdir(MPORT_INST_DIR, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) {
+ if (errno != EEXIST)
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ return create_master_db(db);
+}
+
+
+static int create_master_db(sqlite3 **db)
+{
+ if (sqlite3_open(MPORT_MASTER_DB_FILE, db) != 0) {
+ sqlite3_close(*db);
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(*db));
+ }
+
+ /* create tables */
+ return mport_generate_master_schema(*db);
+}
Index: util.c
===================================================================
RCS file: /home/cvs/src/lib/libmport/util.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -L lib/libmport/util.c -L lib/libmport/util.c -u -r1.6 -r1.7
--- lib/libmport/util.c
+++ lib/libmport/util.c
@@ -34,6 +34,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <libgen.h>
#include "mport.h"
__MBSDID("$MidnightBSD$");
@@ -96,7 +97,7 @@
return (lstat(file, &st) == 0);
}
-
+
/* mport_xsystem(char *fmt, ...)
*
@@ -175,4 +176,73 @@
*vec = NULL;
}
+/*
+ * mport_run_plist_exec(fmt, cwd, last_file)
+ *
+ * handles a @exec or a @unexec directive in a plist. This function
+ * does the substitions and then runs the command.
+ *
+ * Substitutions:
+ * %F The last filename extracted (last_file argument)
+ * %D The current working directory (cwd)
+ * %B Return the directory part ("dirname") of %D/%F
+ * %f Return the filename part of ("basename") %D/%F
+ */
+int mport_run_plist_exec(const char *fmt, const char *cwd, const char *last_file)
+{
+ size_t l;
+ size_t max = FILENAME_MAX * 2;
+ char cmnd[max];
+ char *pos = cmnd;
+ char *name;
+
+ while (*fmt && max > 0) {
+ if (*fmt == '%') {
+ fmt++;
+ switch (*fmt) {
+ case 'F':
+ strlcpy(pos, last_file, max);
+ l = strlen(last_file);
+ pos += l;
+ max -= l;
+ break;
+ case 'D':
+ strlcpy(pos, cwd, max);
+ l = strlen(cwd);
+ pos += l;
+ max -= l;
+ break;
+ case 'B':
+ name = dirname(last_file);
+ strlcpy(pos, name, max);
+ l = strlen(name);
+ pos += l;
+ max -= l;
+ break;
+ case 'f':
+ name = basename(last_file);
+ strlcpy(pos, name, max);
+ l = strlen(name);
+ pos += l;
+ pos -= l;
+ break;
+ default:
+ *pos = *fmt;
+ max--;
+ pos++;
+ }
+ fmt++;
+ } else {
+ *pos = *fmt;
+ pos++;
+ fmt++;
+ max--;
+ }
+ }
+
+ *pos = '\0';
+
+ /* cmnd now hold the expaded command, now execute it*/
+ return mport_xsystem(cmnd);
+}
Index: error.c
===================================================================
RCS file: /home/cvs/src/lib/libmport/error.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L lib/libmport/error.c -L lib/libmport/error.c -u -r1.4 -r1.5
--- lib/libmport/error.c
+++ lib/libmport/error.c
@@ -45,6 +45,8 @@
"Malformed packing list.",
"SQLite error.",
"File not found."
+ "System call failed.",
+ "libarchive error."
};
Index: create_pkg.c
===================================================================
RCS file: /home/cvs/src/lib/libmport/create_pkg.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -L lib/libmport/create_pkg.c -L lib/libmport/create_pkg.c -u -r1.6 -r1.7
--- lib/libmport/create_pkg.c
+++ lib/libmport/create_pkg.c
@@ -43,11 +43,10 @@
#include <md5.h>
#include <archive.h>
#include <archive_entry.h>
-#include <mport.h>
+#include "mport.h"
__MBSDID("$MidnightBSD$");
-#define PACKAGE_DB_FILENAME "+CONTENTS.db"
static int create_package_db(sqlite3 **);
static int create_plist(sqlite3 *, mportPlist *, mportPackageMeta *);
@@ -58,15 +57,16 @@
static int archive_files(mportPlist *, mportPackageMeta *);
static int clean_up(const char *);
+
int mport_create_pkg(mportPlist *plist, mportPackageMeta *pack)
{
- /* create a temp dir to hold our meta files. */
- char dirtmpl[] = "/tmp/mport.XXXXXXXX";
- char *tmpdir = mkdtemp(dirtmpl);
int ret;
sqlite3 *db;
-
+
+ char dirtmpl[] = "/tmp/mport.XXXXXXXX";
+ char *tmpdir = mkdtemp(dirtmpl);
+
if (tmpdir == NULL) {
SET_ERROR(MPORT_ERR_FILEIO, strerror(errno));
goto CLEANUP;
@@ -104,7 +104,7 @@
static int create_package_db(sqlite3 **db)
{
- if (sqlite3_open(PACKAGE_DB_FILENAME, db) != 0) {
+ if (sqlite3_open(MPORT_STUB_DB_FILE, db) != SQLITE_OK) {
sqlite3_close(*db);
RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(*db));
}
@@ -337,7 +337,7 @@
*/
#define COPY_PKG_METAFILE(field, tofile) \
if (pack->field != NULL && mport_file_exists(pack->field)) { \
- if ((ret = mport_copy_file(pack->field, #tofile)) != MPORT_OK) { \
+ if ((ret = mport_copy_file(pack->field, tofile)) != MPORT_OK) { \
return ret; \
} \
} \
@@ -346,11 +346,11 @@
static int copy_metafiles(mportPackageMeta *pack)
{
int ret;
-
- COPY_PKG_METAFILE(mtree, +MTREE);
- COPY_PKG_METAFILE(pkginstall, +INSTALL);
- COPY_PKG_METAFILE(pkgdeinstall, +DEINSTALL);
- COPY_PKG_METAFILE(pkgmessage, +MESSAGE);
+
+ COPY_PKG_METAFILE(mtree, MPORT_MTREE_FILE);
+ COPY_PKG_METAFILE(pkginstall, MPORT_INSTALL_FILE);
+ COPY_PKG_METAFILE(pkgdeinstall, MPORT_DEINSTALL_FILE);
+ COPY_PKG_METAFILE(pkgmessage, MPORT_MESSAGE_FILE);
return ret;
}
--- /dev/null
+++ lib/libmport/db_util.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2007 Chris Reinhardt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $MidnightBSD: src/lib/libmport/db_util.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "mport.h"
+
+__MBSDID("$MidnightBSD: src/lib/libmport/db_util.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $");
+
+/* mport_db_do(sqlite3 *db, const char *sql, ...)
+ *
+ * A wrapper for doing executing a single sql query. Takes a sqlite3 struct
+ * pointer, a format string and a list of args. See the documentation for
+ * sqlite3_vmprintf() for format information.
+ */
+int mport_db_do(sqlite3 *db, const char *fmt, ...)
+{
+ va_list args;
+ char *sql;
+
+ va_start(args, fmt);
+
+ if ((sql = sqlite3_vmprintf(fmt, args)) == NULL) {
+ return MPORT_ERR_NO_MEM;
+ }
+
+ if (sqlite3_exec(db, sql, 0, 0, 0) != SQLITE_OK) {
+ sqlite3_free(sql);
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+ }
+
+ sqlite3_free(sql);
+
+ return MPORT_OK;
+}
+
+
+
+
Index: db_schema.c
===================================================================
RCS file: /home/cvs/src/lib/libmport/db_schema.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L lib/libmport/db_schema.c -L lib/libmport/db_schema.c -u -r1.3 -r1.4
--- lib/libmport/db_schema.c
+++ lib/libmport/db_schema.c
@@ -36,20 +36,36 @@
static int run_sql(sqlite3 *db, const char *sql);
+#define RUN_SQL(db, sql) \
+ if (run_sql(db, sql) != SQLITE_OK) \
+ RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db))
+
+
int mport_generate_stub_schema(sqlite3 *db)
{
- if (run_sql(db, "CREATE TABLE assets (pkg text not NULL, type int NOT NULL, data text, checksum text)") != SQLITE_OK)
- RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
- if (run_sql(db, "CREATE TABLE package (pkg text NOT NULL, version text NOT NULL, origin text NOT NULL, lang text, options text, date int NOT NULL, prefix text NOT NULL)") != SQLITE_OK)
- RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
- if (run_sql(db, "CREATE TABLE conflicts (pkg text NOT NULL, conflict_pkg text NOT NULL, conflict_version text NOT NULL)") != SQLITE_OK)
- RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
- if (run_sql(db, "CREATE TABLE depends (pkg text NOT NULL, depend_pkgname text NOT NULL, depend_pkgversion text NOT NULL, depend_port text NOT NULL)") != SQLITE_OK)
- RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+ RUN_SQL(db, "CREATE TABLE assets (pkg text not NULL, type int NOT NULL, data text, checksum text)");
+ RUN_SQL(db, "CREATE TABLE package (pkg text NOT NULL, version text NOT NULL, origin text NOT NULL, lang text, options text, date int NOT NULL, prefix text NOT NULL)");
+ RUN_SQL(db, "CREATE TABLE conflicts (pkg text NOT NULL, conflict_pkg text NOT NULL, conflict_version text NOT NULL)");
+ RUN_SQL(db, "CREATE TABLE depends (pkg text NOT NULL, depend_pkgname text NOT NULL, depend_pkgversion text NOT NULL, depend_port text NOT NULL)");
return MPORT_OK;
}
+int mport_generate_master_schema(sqlite3 *db)
+{
+ RUN_SQL(db, "CREATE TABLE IF NOT EXISTS packages (pkg text NOT NULL, version text NOT NULL, origin text NOT NULL, prefix text NOT NULL, lang text, options text, date int)");
+ RUN_SQL(db, "CREATE UNIQUE INDEX IF NOT EXISTS packages_pkg ON packages (pkg)");
+ RUN_SQL(db, "CREATE INDEX IF NOT EXISTS packages_origin ON packages (origin)");
+ RUN_SQL(db, "CREATE TABLE IF NOT EXISTS depends (pkg text NOT NULL, depend_pkgname text NOT NULL, depend_pkgversion text NOT NULL, depend_port text NOT NULL)");
+ RUN_SQL(db, "CREATE INDEX IF NOT EXISTS depends_pkg ON depends (pkg)");
+ RUN_SQL(db, "CREATE INDEX IF NOT EXISTS depends_dependpkgname ON depends (depend_pkgname)");
+ RUN_SQL(db, "CREATE TABLE IF NOT EXISTS assets (pkg text NOT NULL, type int NOT NULL, data text, checksum text)");
+ RUN_SQL(db, "CREATE INDEX IF NOT EXISTS assets_pkg ON assets (pkg)");
+ RUN_SQL(db, "CREATE INDEX IF NOT EXISTS assets_data ON assets (data)");
+
+ return MPORT_OK;
+}
+
static int run_sql(sqlite3 *db, const char *sql)
{
char *error = 0;
--- /dev/null
+++ lib/libmport/install_pkg.c
@@ -0,0 +1,283 @@
+/*-
+ * Copyright (c) 2007 Chris Reinhardt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $MidnightBSD: src/lib/libmport/install_pkg.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $
+ */
+
+
+
+#include "mport.h"
+#include <sys/cdefs.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <archive.h>
+#include <archive_entry.h>
+
+__MBSDID("$MidnightBSD: src/lib/libmport/install_pkg.c,v 1.1 2007/11/22 08:00:32 ctriv Exp $");
+
+static int do_pre_install(sqlite3 *, mportPackageMeta *, const char *);
+static int do_actual_install(struct archive *, struct archive_entry *, sqlite3 *, mportPackageMeta *, const char *);
+static int do_post_install(sqlite3 *, mportPackageMeta *, const char *);
+static int run_pkg_install(const char *, mportPackageMeta *, const char *);
+static int run_mtree(const char *, mportPackageMeta *);
+static int clean_up(const char *);
+static int rollback(void);
+
+int mport_install_pkg(const char *filename, const char *prefix)
+{
+ /*
+ * The general strategy here is to extract the meta-files into a tempdir, but
+ * extract the real files inplace. There's huge IO overhead with having a stagging
+ * area.
+ */
+ struct archive *a = archive_read_new();
+ struct archive_entry *entry;
+ char filepath[FILENAME_MAX];
+ const char *file;
+ sqlite3 *db;
+ mportPackageMeta *pack;
+ int ret = MPORT_OK;
+
+ /* initialize our local mport instance */
+ if ((ret = mport_inst_init(&db)) != MPORT_OK)
+ return ret;
+
+ /* extract the meta-files into the a temp dir */
+ char dirtmpl[] = "/tmp/mport.XXXXXXXX";
+ char *tmpdir = mkdtemp(dirtmpl);
+
+ if (tmpdir == NULL)
+ RETURN_ERROR(MPORT_ERR_FILEIO, strerror(errno));
+
+ archive_read_support_compression_bzip2(a);
+ archive_read_support_format_tar(a);
+
+ if (archive_read_open_filename(a, filename, 10240) != ARCHIVE_OK)
+ RETURN_ERROR(MPORT_ERR_ARCHIVE, archive_error_string(a));
+
+ while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ file = archive_entry_pathname(entry);
+
+ if (*file == '+') {
+ snprintf(filepath, FILENAME_MAX, "%s/%s", tmpdir, file);
+ archive_entry_set_pathname(entry, filepath);
+ archive_read_extract(a, entry, ARCHIVE_EXTRACT_OWNER|ARCHIVE_EXTRACT_PERM);
+ } else {
+ break;
+ }
+ }
+
+ /* Attach the stub db */
+ if ((ret = mport_attach_stub_db(db, tmpdir)) != MPORT_OK)
+ return ret;
+
+ /* get the meta object from the stub database */
+ if ((ret = mport_get_meta_from_db(db, &pack)) != MPORT_OK)
+ return ret;
+
+ if (prefix != NULL)
+ pack->prefix = (char *)prefix;
+
+ /* check if this is installed already, depends, and conflicts */
+// if ((ret = mport_check_preconditions(db, pack)) != MPORT_OK)
+// return ret;
+
+ /* Run mtree. Run pkg-install. Etc... */
+ if ((ret = do_pre_install(db, pack, tmpdir)) != MPORT_OK)
+ return ret;
+
+ if ((ret = do_actual_install(a, entry, db, pack, tmpdir)) != MPORT_OK)
+ return ret;
+
+ archive_read_finish(a);
+
+ if ((ret = do_post_install(db, pack, tmpdir)) != MPORT_OK)
+ return ret;
+
+ if ((ret = clean_up(tmpdir)) != MPORT_OK)
+ return ret;
+
+ return ret;
+}
+
+/* This does everything that has to happen before we start installing files.
+ * We run mtree, pkg-install PRE-INSTALL, etc...
+ */
+static int do_pre_install(sqlite3 *db, mportPackageMeta *pack, const char *tmpdir)
+{
+ int ret = MPORT_OK;
+
+ /* run mtree */
+ if ((ret = run_mtree(tmpdir, pack)) != MPORT_OK)
+ return ret;
+
+ /* run pkg-install PRE-INSTALL */
+ if ((ret = run_pkg_install(tmpdir, pack, "PRE-INSTALL")) != MPORT_OK)
+ return ret;
+
+ return ret;
+}
+
+
+static int do_actual_install(
+ struct archive *a,
+ struct archive_entry *entry,
+ sqlite3 *db,
+ mportPackageMeta *pack,
+ const char *tmpdir
+ )
+{
+ const char *err;
+ int ret;
+ mportPlistEntryType type;
+ char *data, *cwd;
+ char file[FILENAME_MAX];
+ sqlite3_stmt *assets;
+
+ if (mport_db_do(db, "START TRANSACTION") != MPORT_OK)
+ goto ERROR;
+
+ /* Insert the package meta row into the packages table - XXX Does not honor pack->prefix! */
+ if (mport_db_do(db, "INSERT INTO packages (pkg, version, origin, prefix, lang, options) SELECT (pkg, version, origin, prefix, lang, options) FROM stub.package") != MPORT_OK)
+ goto ERROR;
+ /* Insert the assets into the master table */
+ if (mport_db_do(db, "INSERT INTO assets (pkg, type, data, checksum) SELECT (pkg,type,data,checksum) FROM stub.assets") != MPORT_OK)
+ goto ERROR;
+ /* Insert the depends into the master table */
+ if (mport_db_do(db, "INSERT INTO depends (pkg, depend_pkgname, depend_pkgversion, depend_port) SELECT (pkg, depend_pkgname, depend_pkgversion, depend_port) FROM stub.depends") != MPORT_OK)
+ goto ERROR;
+
+ if ((ret = sqlite3_prepare_v2(db, "SELECT type,data FROM stub.assets", -1, &assets, &err)) != SQLITE_OK) {
+ mport_set_err(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
+ goto ERROR;
+ }
+
+ cwd = pack->prefix;
+
+ while ((ret = sqlite3_step(assets)) == SQLITE_ROW) {
+ type = (mportPlistEntryType)sqlite3_column_int(assets, 0);
+ data = (char *)sqlite3_column_text(assets, 1);
+
+ switch (type) {
+ case PLIST_CWD:
+ if (data == NULL) {
+ cwd = pack->prefix;
+ } else {
+ cwd = data;
+ }
+ break;
+ case PLIST_EXEC:
+ if ((ret = mport_run_plist_exec(data, cwd, file)) != MPORT_OK)
+ goto ERROR;
+ break;
+ case PLIST_FILE:
+ /* Our logic here is a bit backwards, because the first real file
+ * in the archive was read in the loop in mport_install_pkg. we
+ * use the current entry and then update it. */
+ if (entry == NULL) {
+ mport_set_err(MPORT_ERR_INTERNAL, "Plist to arhive mismatch!");
+ goto ERROR;
+ }
+ snprintf(file, FILENAME_MAX, "%s/%s", cwd, data);
+ archive_entry_set_pathname(entry, file);
+ if ((ret = archive_read_extract(a, entry, ARCHIVE_EXTRACT_OWNER|ARCHIVE_EXTRACT_PERM)) != ARCHIVE_OK) {
+ mport_set_err(MPORT_ERR_ARCHIVE, archive_error_string(a));
+ goto ERROR;
+ }
+ /* we only look for fatal, because EOF is only an error if we come
+ back around. */
+ if (archive_read_next_header(a, &entry) == ARCHIVE_FATAL) {
+ mport_set_err(MPORT_ERR_ARCHIVE, archive_error_string(a));
+ goto ERROR;
+ }
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+
+ sqlite3_finalize(assets);
+
+ if (mport_db_do(db, "COMMIT TRANSACTION") != MPORT_OK)
+ goto ERROR;
+
+ return MPORT_OK;
+
+ ERROR:
+ rollback();
+ return ret;
+}
+
+static int do_post_install(sqlite3 *db, mportPackageMeta *pack, const char *tmpdir)
+{
+ return run_pkg_install(tmpdir, pack, "POST-INSTALL");
+}
+
+
+static int run_mtree(const char *tmpdir, mportPackageMeta *pack)
+{
+ char file[FILENAME_MAX];
+ int ret;
+
+ snprintf(file, FILENAME_MAX, "%s/%s", tmpdir, MPORT_MTREE_FILE);
+
+ if (mport_file_exists(file)) {
+ if ((ret = mport_xsystem("%s -U -f %s -d -e -p %s >/dev/null", MPORT_MTREE_BIN, file, pack->prefix)) != 0)
+ return mport_set_errx(MPORT_ERR_SYSCALL_FAILED, "%s returned non-zero: %i", MPORT_MTREE_BIN, ret);
+ }
+
+ return MPORT_OK;
+}
+
+static int run_pkg_install(const char *tmpdir, mportPackageMeta *pack, const char *mode)
+{
+ char file[FILENAME_MAX];
+ int ret;
+
+ snprintf(file, FILENAME_MAX, "%s/%s", tmpdir, MPORT_INSTALL_FILE);
+ if (mport_file_exists(file)) {
+ if ((ret = mport_xsystem("PKG_PREFIX=%s %s %s %s", pack->prefix, MPORT_SH_BIN, file, mode)) != 0)
+ return mport_set_errx(MPORT_ERR_SYSCALL_FAILED, "%s %s returned non-zero: %i" MPORT_INSTALL_FILE, mode, ret);
+ }
+
+ return MPORT_OK;
+}
+
+
+static int clean_up(const char *tmpdir)
+{
+ // return mport_rmtree(tmpdir);
+ return MPORT_OK;
+}
+
+
+static int rollback()
+{
+ fprintf(stderr, "Rollback called!\n");
+ return 0;
+}
+
Index: mport.h
===================================================================
RCS file: /home/cvs/src/lib/libmport/mport.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -L lib/libmport/mport.h -L lib/libmport/mport.h -u -r1.4 -r1.5
--- lib/libmport/mport.h
+++ lib/libmport/mport.h
@@ -91,17 +91,32 @@
mportPackageMeta * mport_new_packagemeta(void);
void mport_free_packagemeta(mportPackageMeta *);
+
/* Package creation */
int mport_create_pkg(mportPlist *, mportPackageMeta *);
+
+/* Package installation */
+int mport_install_pkg(const char *, const char *);
+
+
#include <sqlite3.h>
/* schema */
-int mport_generate_plist_schema(sqlite3 *);
+int mport_generate_master_schema(sqlite3 *);
int mport_generate_stub_schema(sqlite3 *);
-/* Errors */
+/* Various database convience functions */
+int mport_attach_stub_db(sqlite3 *, const char *);
+int mport_get_meta_from_db(sqlite3 *, mportPackageMeta **);
+int mport_db_do(sqlite3 *, const char *, ...);
+
+
+/* instance init */
+int mport_inst_init(sqlite3 **);
+
+/* Errors */
int mport_err_code(void);
char * mport_err_string(void);
@@ -116,16 +131,34 @@
#define MPORT_ERR_FILE_NOT_FOUND 5
#define MPORT_ERR_SYSCALL_FAILED 6
#define MPORT_ERR_ARCHIVE 7
+#define MPORT_ERR_INTERNAL 8
#define RETURN_ERROR(code, msg) return mport_set_errx((code), "Error at %s:(%d): %s", __FILE__, __LINE__, (msg))
#define SET_ERROR(code,msg) mport_set_errx((code), "Error at %s:(%d): %s", __FILE__, __LINE__, (msg))
-/* Utils */
+/* Utils */
int mport_copy_file(const char *, const char *);
int mport_rmtree(const char *);
int mport_file_exists(const char *);
int mport_xsystem(const char *, ...);
void mport_parselist(char *, char ***);
+int mport_run_plist_exec(const char *, const char *, const char *);
+
+/* Meta files */
+#define MPORT_STUB_DB_FILE "+CONTENTS.db"
+#define MPORT_MTREE_FILE "+MTREE"
+#define MPORT_INSTALL_FILE "+INSTALL"
+#define MPORT_DEINSTALL_FILE "+DEINSTALL"
+#define MPORT_MESSAGE_FILE "+MESSAGE"
+
+
+/* Instance files */
+#define MPORT_INST_DIR "/var/db/mport"
+#define MPORT_MASTER_DB_FILE "/var/db/mport/master.db"
+
+/* Binaries we use */
+#define MPORT_MTREE_BIN "/usr/sbin/mtree"
+#define MPORT_SH_BIN "/bin/sh"
-#endif
+#endif /* ! defined _MPORT_H */
Index: Makefile
===================================================================
RCS file: /home/cvs/src/lib/libmport/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -L lib/libmport/Makefile -L lib/libmport/Makefile -u -r1.2 -r1.3
--- lib/libmport/Makefile
+++ lib/libmport/Makefile
@@ -1,7 +1,7 @@
-# $FreeBSD: src/usr.sbin/pkg_install/lib/Makefile,v 1.18 2004/10/24 15:33:07 ru Exp $
+# $MidnightBSD$
LIB= mport
-SRCS= plist.c create_pkg.c db_schema.c util.c error.c
+SRCS= plist.c create_pkg.c db_schema.c db_stub.c db_util.c util.c error.c install_pkg.c inst_init.c
INCS= mport.h
More information about the Midnightbsd-cvs
mailing list