[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