[Midnightbsd-cvs] src: lib/libmport: First working code for archive creation.
ctriv at midnightbsd.org
ctriv at midnightbsd.org
Mon Sep 24 02:01:46 EDT 2007
Log Message:
-----------
First working code for archive creation. Many features still missing, but
it kinda works :).
Modified Files:
--------------
src/lib/libmport:
Makefile (r1.1 -> r1.2)
create_pkg.c (r1.1 -> r1.2)
error.c (r1.1 -> r1.2)
util.c (r1.1 -> r1.2)
Added Files:
-----------
src/lib/libmport:
mport.h (r1.1)
-------------- next part --------------
Index: util.c
===================================================================
RCS file: /home/cvs/src/lib/libmport/util.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -Llib/libmport/util.c -Llib/libmport/util.c -u -r1.1 -r1.2
--- lib/libmport/util.c
+++ lib/libmport/util.c
@@ -27,9 +27,13 @@
*/
-
-#include <sqlite3.h>
+#include <errno.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "mport.h"
__MBSDID("$MidnightBSD$");
@@ -59,3 +63,42 @@
free(pack->req_script);
free(pack);
}
+
+
+int mport_copy_file(const char *fromname, const char *toname)
+{
+ int to;
+ int from;
+ int len;
+ char buf[8192];
+
+
+ if ((from = open(fromname, O_RDONLY)) == -1) {
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ if ((to = open(toname, O_WRONLY | O_CREAT)) == -1) {
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ len = read(from, buf, sizeof(buf));
+
+ while (len > 0) {
+ write(to, buf, len);
+ len = read(from, buf, sizeof(buf));
+ }
+
+ close(from);
+ close(to);
+
+ return MPORT_OK;
+}
+
+int mport_file_exists(const char *file)
+{
+ struct stat st;
+
+ return (lstat(file, &st) == 0);
+}
+
+
Index: error.c
===================================================================
RCS file: /home/cvs/src/lib/libmport/error.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -Llib/libmport/error.c -Llib/libmport/error.c -u -r1.1 -r1.2
--- lib/libmport/error.c
+++ lib/libmport/error.c
@@ -30,6 +30,7 @@
#include "mport.h"
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
__MBSDID("$MidnightBSD$");
@@ -78,3 +79,15 @@
return code;
}
+int mport_set_errx(int code, const char *fmt, ...)
+{
+ va_list args;
+ char *err;
+
+ va_start(args, fmt);
+ if (vasprintf(&err, fmt, args) == -1) {
+ fprintf(stderr, "fatal error: mport_set_errx can't format the string.\n");
+ exit(255);
+ }
+ return mport_set_err(code, err);
+}
--- /dev/null
+++ lib/libmport/mport.h
@@ -0,0 +1,128 @@
+/* $MidnightBSD: src/lib/libmport/mport.h,v 1.1 2007/09/24 06:01:46 ctriv Exp $
+ *
+ * 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.
+ *
+ */
+
+#ifndef _MPORT_H_
+#define _MPORT_H_
+
+
+#include <sys/cdefs.h>
+__MBSDID("$MidnightBSD: src/lib/libmport/mport.h,v 1.1 2007/09/24 06:01:46 ctriv Exp $");
+
+
+
+/* plist stuff */
+
+#include <sys/queue.h>
+#include <stdio.h>
+
+
+/* For now this is just the FreeBSD list, this will change soon. */
+enum _PlistEntryType {
+ PLIST_INVALID, PLIST_FILE, PLIST_CWD, PLIST_CHMOD, PLIST_CHOWN, PLIST_CHGRP,
+ PLIST_COMMENT, PLIST_IGNORE, PLIST_NAME, PLIST_EXEC, PLIST_UNEXEC,
+ PLIST_SRC, PLIST_DISPLY, PLIST_PKGDEP, PLIST_CONFLICTS, PLIST_MTREE,
+ PLIST_DIRRM, PLIST_DIRRMTRY, PLIST_IGNORE_INST, PLIST_OPTION, PLIST_ORIGIN,
+ PLIST_DEPORIGIN, PLIST_NOINST, PLIST_DISPLAY
+};
+
+typedef enum _PlistEntryType mportPlistEntryType;
+
+struct _PlistEntry {
+ mportPlistEntryType type;
+ char *data;
+ STAILQ_ENTRY(_PlistEntry) next;
+};
+
+STAILQ_HEAD(_Plist, _PlistEntry);
+
+typedef struct _Plist mportPlist;
+typedef struct _PlistEntry mportPlistEntry;
+
+mportPlist* mport_new_plist(void);
+void mport_free_plist(mportPlist *);
+int mport_parse_plist_file(FILE *, mportPlist *);
+
+/* Package Meta-data structure */
+
+typedef struct {
+ char *pkg_filename;
+ char *name;
+ char *version;
+ char *lang;
+ char *options;
+ char *comment;
+ char *sourcedir;
+ char *desc;
+ char *prefix;
+ char **depends;
+ char *mtree;
+ char *origin;
+ char **conflicts;
+ char *pkginstall;
+ char *pkgdeinstall;
+ char *pkgmessage;
+ char *req_script;
+} mportPackageMeta;
+
+mportPackageMeta * mport_new_packagemeta(void);
+void mport_free_packagemeta(mportPackageMeta *);
+
+/* Package creation */
+int mport_create_pkg(mportPlist *, mportPackageMeta *);
+
+#include <sqlite3.h>
+
+/* schema */
+void mport_generate_plist_schema(sqlite3 *);
+void mport_generate_package_schema(sqlite3 *);
+
+/* Errors */
+
+int mport_err_code(void);
+char * mport_err_string(void);
+
+int mport_set_err(int, const char *);
+int mport_set_errx(int , const char *, ...);
+
+#define MPORT_OK 0
+#define MPORT_ERR_NO_MEM 1
+#define MPORT_ERR_FILEIO 2
+#define MPORT_ERR_MALFORMED_PLIST 3
+#define MPORT_ERR_SQLITE 4
+#define MPORT_ERR_FILE_NOT_FOUND 5
+#define MPORT_ERR_SYSCALL_FAILED 6
+#define MPORT_ERR_ARCHIVE 7
+
+#define RETURN_ERROR(code, msg) return mport_set_errx((code), "Error at %s:(%d): %s", __FILE__, __LINE__, (msg))
+
+/* Utils */
+
+int mport_copy_file(const char *, const char *);
+int mport_file_exists(const char *);
+
+#endif
Index: create_pkg.c
===================================================================
RCS file: /home/cvs/src/lib/libmport/create_pkg.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -Llib/libmport/create_pkg.c -Llib/libmport/create_pkg.c -u -r1.1 -r1.2
--- lib/libmport/create_pkg.c
+++ lib/libmport/create_pkg.c
@@ -30,6 +30,10 @@
#include <sys/cdefs.h>
#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -37,7 +41,9 @@
#include <sqlite3.h>
#include <errno.h>
#include <md5.h>
-#include "mport.h"
+#include <archive.h>
+#include <archive_entry.h>
+#include <mport.h>
__MBSDID("$MidnightBSD$");
@@ -46,7 +52,8 @@
static int create_package_db(sqlite3 **);
static int create_plist(sqlite3 *, mportPlist *, mportPackageMeta *);
static int create_meta(sqlite3 *, mportPackageMeta *);
-static int tar_files(mportPlist *, mportPackageMeta *);
+static int copy_metafiles(mportPackageMeta *);
+static int archive_files(mportPlist *, mportPackageMeta *);
static int clean_up(const char *);
int mport_create_pkg(mportPlist *plist, mportPackageMeta *pack)
@@ -76,7 +83,10 @@
if (sqlite3_close(db) != SQLITE_OK)
RETURN_ERROR(MPORT_ERR_SQLITE, sqlite3_errmsg(db));
- if ((ret = tar_files(plist, pack)) != MPORT_OK)
+ if ((ret = copy_metafiles(pack)) != MPORT_OK)
+ return ret;
+
+ if ((ret = archive_files(plist, pack)) != MPORT_OK)
return ret;
if ((ret = clean_up(tmpdir)) != MPORT_OK)
@@ -204,9 +214,129 @@
return MPORT_OK;
}
-static int tar_files(mportPlist *plist, mportPackageMeta *pack)
+/* this is just to save a lot of typing. It will only work in the
+ copy_metafiles() function.
+ */
+#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) { \
+ return ret; \
+ } \
+ } \
+
+
+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);
+
+ return ret;
+}
+
+
+static int archive_files(mportPlist *plist, mportPackageMeta *pack)
{
+ struct archive *a;
+ struct archive_entry *entry;
+ struct stat st;
+ DIR *dir;
+ struct dirent *diren;
+ mportPlistEntry *e;
+ char filename[FILENAME_MAX];
+ char buff[8192];
+ char *cwd;
+ int len;
+ int fd;
+
+ cwd = pack->prefix;
+
+ a = archive_write_new();
+ archive_write_set_compression_bzip2(a);
+ archive_write_set_format_pax(a);
+
+ if (archive_write_open_filename(a, pack->pkg_filename) != ARCHIVE_OK) {
+ RETURN_ERROR(MPORT_ERR_ARCHIVE, archive_error_string(a));
+ }
+
+ /* First step - add the files in the tmpdir to the archive. */
+ if ((dir = opendir(".")) == NULL) {
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ while ((diren = readdir(dir)) != NULL) {
+ if (strcmp(diren->d_name, ".") == 0 || strcmp(diren->d_name, "..") == 0)
+ continue;
+
+ if (lstat(diren->d_name, &st) != 0) {
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ entry = archive_entry_new();
+ archive_entry_copy_stat(entry, &st);
+ archive_entry_set_pathname(entry, diren->d_name);
+ archive_write_header(a, entry);
+ if ((fd = open(diren->d_name, O_RDONLY)) == -1) {
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ len = read(fd, buff, sizeof(buff));
+ while (len > 0) {
+ archive_write_data(a, buff, len);
+ len = read(fd, buff, sizeof(buff));
+ }
+
+ archive_entry_free(entry);
+ close(fd);
+ }
+
+ closedir(dir);
+
+ /* second step - all the files in the plist */
+ STAILQ_FOREACH(e, plist, next) {
+ if (e->type == PLIST_CWD) {
+ if (e->data == NULL) {
+ cwd = pack->prefix;
+ } else {
+ cwd = e->data;
+ }
+ }
+
+ if (e->type != PLIST_FILE) {
+ continue;
+ }
+
+ snprintf(filename, FILENAME_MAX, "%s/%s/%s", pack->sourcedir, cwd, e->data);
+
+ fprintf(stderr, "statting: %s\n", filename);
+
+ if (lstat(filename, &st) != 0) {
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ entry = archive_entry_new();
+ archive_entry_copy_stat(entry, &st);
+ archive_entry_set_pathname(entry, e->data);
+ archive_write_header(a, entry);
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ RETURN_ERROR(MPORT_ERR_SYSCALL_FAILED, strerror(errno));
+ }
+
+ len = read(fd, buff, sizeof(buff));
+ while (len > 0) {
+ archive_write_data(a, buff, len);
+ len = read(fd, buff, sizeof(buff));
+ }
+
+ archive_entry_free(entry);
+ close(fd);
+ }
+
+ archive_write_finish(a);
}
static int clean_up(const char *tmpdir)
Index: Makefile
===================================================================
RCS file: /home/cvs/src/lib/libmport/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -Llib/libmport/Makefile -Llib/libmport/Makefile -u -r1.1 -r1.2
--- lib/libmport/Makefile
+++ lib/libmport/Makefile
@@ -3,6 +3,10 @@
LIB= mport
SRCS= plist.c create_pkg.c db_schema.c util.c error.c
+INCS= mport.h
+
+
+CFLAGS+= -I${.CURDIR}
WARNS?= 3
WFORMAT?= 1
SHLIB_MAJOR= 1
More information about the Midnightbsd-cvs
mailing list