diff options
author | joerg <joerg> | 2007-08-03 13:15:58 +0000 |
---|---|---|
committer | joerg <joerg> | 2007-08-03 13:15:58 +0000 |
commit | b6d7b2e349ccd459e8ed86007a574cbb80bcab58 (patch) | |
tree | 0fbc0fcc5d1e9cfb578db0369d55c2e5ccdd25bd /pkgtools/pkg_install | |
parent | ca80cc4f417a75d325664e5446a13bacf180d4ab (diff) | |
download | pkgsrc-b6d7b2e349ccd459e8ed86007a574cbb80bcab58.tar.gz |
- only build pkg_admin, pkg_create and pkg_info for --enable-bootstrap
- for pkg_create, split-off the package creation from the plist
processing. package creation is disabled for --enable-bootstrap
- change package creation to use libarchive
- add two options (-u and -g) to override file system ownership
- pkg_create now creates files in the tarball with correct owner/group
based on -u/-g or @owner/@group
- add a function to compute the +CONTENTS file in memory
Bump version to 20070802.
Review of a slightly older version by jlam@
Diffstat (limited to 'pkgtools/pkg_install')
-rw-r--r-- | pkgtools/pkg_install/Makefile | 55 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/Makefile.in | 8 | ||||
-rwxr-xr-x | pkgtools/pkg_install/files/configure | 19 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/configure.ac | 6 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/Makefile.in | 19 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/build.c | 387 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/create.h | 28 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/main.c | 39 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/perform.c | 283 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/pkg_create.1 | 14 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/pkg_create.cat1 | 16 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/pl.c | 30 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/create/util.c | 147 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/lib.h | 3 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/plist.c | 79 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/version.h | 4 |
16 files changed, 842 insertions, 295 deletions
diff --git a/pkgtools/pkg_install/Makefile b/pkgtools/pkg_install/Makefile index 181c169c5f2..151280d475c 100644 --- a/pkgtools/pkg_install/Makefile +++ b/pkgtools/pkg_install/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.136 2007/07/29 17:39:31 seb Exp $ +# $NetBSD: Makefile,v 1.137 2007/08/03 13:15:58 joerg Exp $ # Notes to package maintainers: # @@ -86,8 +86,61 @@ SUBST_MESSAGE.paths= Fixing paths in scripts. SUBST_FILES.paths= audit-packages/Makefile.in SUBST_SED.paths= -e 's,_gzcat_,${GZCAT},g' +.include "../../archivers/bzip2/builtin.mk" +.include "../../archivers/libarchive/builtin.mk" +.include "../../devel/zlib/builtin.mk" + +USE_BUILTIN.bzip2= no +USE_BUILTIN.zlib= no + +.if empty(USE_BUILTIN.bzip2:M[yY][eE][sS]) || \ + empty(USE_BUILTIN.zlib:M[yY][eE][sS]) +USE_BUILTIN.libarchive= no +.endif + +FILESDIR.bzip2?= ${.CURDIR}/../../archivers/bzip2/files +FILESDIR.libarchive?= ${.CURDIR}/../../archivers/libarchive/files +FILESDIR.zlib?= ${.CURDIR}/../../devel/zlib/files + +.if empty(USE_BUILTIN.bzip2:M[yY][eE][sS]) +CPPFLAGS+= -I${WRKDIR}/bzip2 +LDFLAGS+= -L${WRKDIR}/bzip2 +.endif +.if empty(USE_BUILTIN.zlib:M[yY][eE][sS]) +CPPFLAGS+= -I${WRKDIR}/zlib +LDFLAGS+= -L${WRKDIR}/zlib +.endif +.if empty(USE_BUILTIN.libarchive:M[yY][eE][sS]) +CPPFLAGS+= -I${WRKDIR}/libarchive/libarchive +LDFLAGS+= -L${WRKDIR}/libarchive/.libs +.endif + do-extract: @${CP} -R ${FILESDIR} ${WRKSRC} +.if empty(USE_BUILTIN.bzip2:M[yY][eE][sS]) + @${CP} -R ${FILESDIR.bzip2} ${WRKDIR}/bzip2 +.endif +.if empty(USE_BUILTIN.zlib:M[yY][eE][sS]) + @${CP} -R ${FILESDIR.zlib} ${WRKDIR}/zlib +.endif +.if empty(USE_BUILTIN.libarchive:M[yY][eE][sS]) + @${CP} -R ${FILESDIR.libarchive} ${WRKDIR}/libarchive +.endif + +pre-configure: +.if empty(USE_BUILTIN.bzip2:M[yY][eE][sS]) + cd ${WRKDIR}/bzip2 && ${BUILD_MAKE_CMD} libbz2.a +.endif +.if empty(USE_BUILTIN.zlib:M[yY][eE][sS]) + cd ${WRKDIR}/zlib && ${BUILD_MAKE_CMD} libz.a +.endif +.if empty(USE_BUILTIN.libarchive:M[yY][eE][sS]) + cd ${WRKDIR}/libarchive && \ + ${SETENV} ${_CONFIGURE_SCRIPT_ENV} \ + ${CONFIG_SHELL} ${CONFIG_SHELL_FLAGS} \ + ./configure --disable-shared --disable-bsdtar + cd ${WRKDIR}/libarchive && ${BUILD_MAKE_CMD} +.endif # XXX Reverse the order that update does things since # XXX we need pkg_delete built before we can deinstall. diff --git a/pkgtools/pkg_install/files/Makefile.in b/pkgtools/pkg_install/files/Makefile.in index 95eb89191b5..ed1f2264c75 100644 --- a/pkgtools/pkg_install/files/Makefile.in +++ b/pkgtools/pkg_install/files/Makefile.in @@ -1,6 +1,12 @@ -# $NetBSD: Makefile.in,v 1.7 2007/07/14 20:17:06 adrianp Exp $ +# $NetBSD: Makefile.in,v 1.8 2007/08/03 13:15:58 joerg Exp $ +BOOTSTRAP= @bootstrap@ + +.if empty(BOOTSTRAP) SUBDIRS= lib add admin create delete info view audit-packages +.else +SUBDIRS= lib admin create info +.endif all: @for dir in $(SUBDIRS); do \ diff --git a/pkgtools/pkg_install/files/configure b/pkgtools/pkg_install/files/configure index 38d79e6df37..024d1495f57 100755 --- a/pkgtools/pkg_install/files/configure +++ b/pkgtools/pkg_install/files/configure @@ -695,6 +695,7 @@ pkgdbdir ftp tar pax +bootstrap CPP EGREP LIBOBJS @@ -1280,6 +1281,11 @@ if test -n "$ac_init_help"; then esac cat <<\_ACEOF +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-bootstrap build minimal version of pkg_install + Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) @@ -3592,6 +3598,16 @@ fi +# Check whether --enable-bootstrap was given. +if test "${enable_bootstrap+set}" = set; then + enableval=$enable_bootstrap; bootstrap=yes +else + bootstrap= +fi + + + + { echo "$as_me:$LINENO: checking for __db185_open in -ldb" >&5 echo $ECHO_N "checking for __db185_open in -ldb... $ECHO_C" >&6; } @@ -7498,13 +7514,14 @@ pkgdbdir!$pkgdbdir$ac_delim ftp!$ftp$ac_delim tar!$tar$ac_delim pax!$pax$ac_delim +bootstrap!$bootstrap$ac_delim CPP!$CPP$ac_delim EGREP!$EGREP$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 84; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 85; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/pkgtools/pkg_install/files/configure.ac b/pkgtools/pkg_install/files/configure.ac index 609bebb0027..e66c08dfa70 100644 --- a/pkgtools/pkg_install/files/configure.ac +++ b/pkgtools/pkg_install/files/configure.ac @@ -61,6 +61,12 @@ AC_ARG_WITH(pax, [ pax='$(prefix)/bin/pax' ]) AC_SUBST(pax) +AC_ARG_ENABLE([bootstrap], + [AS_HELP_STRING([--enable-bootstrap], [build minimal version of pkg_install])], + [bootstrap=yes], [bootstrap=]) + +AC_SUBST(bootstrap) + dnl Checks for libraries. AC_CHECK_LIB(db, __db185_open, , AC_SEARCH_LIBS(dbopen, [db db1])) AC_SEARCH_LIBS(tgetent, [termcap termlib curses ncurses]) diff --git a/pkgtools/pkg_install/files/create/Makefile.in b/pkgtools/pkg_install/files/create/Makefile.in index dc8d3c0332d..d4864efd9bc 100644 --- a/pkgtools/pkg_install/files/create/Makefile.in +++ b/pkgtools/pkg_install/files/create/Makefile.in @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.in,v 1.13 2007/07/16 09:57:58 joerg Exp $ +# $NetBSD: Makefile.in,v 1.14 2007/08/03 13:15:59 joerg Exp $ srcdir= @srcdir@ @@ -10,14 +10,11 @@ mandir= @mandir@ man1dir= $(mandir)/man1 cat1dir= $(mandir)/cat1 -tar= @tar@ -pax= @pax@ +BOOTSTRAP= @bootstrap@ CC= @CC@ CCLD= $(CC) -LIBS= -linstall @LIBS@ -CPPFLAGS= @CPPFLAGS@ -I. -I$(srcdir) -I../lib -DEFS= @DEFS@ -DTAR_CMD=\"$(tar)\" -DPAX_CMD=\"$(pax)\" +DEFS= @DEFS@ CFLAGS= @CFLAGS@ LDFLAGS= @LDFLAGS@ -L../lib @@ -25,7 +22,15 @@ INSTALL= @INSTALL@ PROG= pkg_create -OBJS= main.o perform.o pl.o +.if empty(BOOTSTRAP) +LIBS= -linstall -larchive -lbz2 -lz @LIBS@ +CPPFLAGS= @CPPFLAGS@ -I. -I$(srcdir) -I../lib +OBJS= main.o perform.o pl.o util.o build.o +.else +LIBS= -linstall @LIBS@ +CPPFLAGS= @CPPFLAGS@ -I. -I$(srcdir) -I../lib -DBOOTSTRAP +OBJS= main.o perform.o pl.o util.o +.endif all: $(PROG) diff --git a/pkgtools/pkg_install/files/create/build.c b/pkgtools/pkg_install/files/create/build.c new file mode 100644 index 00000000000..2efd597da04 --- /dev/null +++ b/pkgtools/pkg_install/files/create/build.c @@ -0,0 +1,387 @@ +/* $NetBSD: build.c,v 1.1 2007/08/03 13:15:59 joerg Exp $ */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include <nbcompat.h> +#if HAVE_SYS_CDEFS_H +#include <sys/cdefs.h> +#endif +#ifndef lint +#if 0 +static const char *rcsid = "from FreeBSD Id: perform.c,v 1.38 1997/10/13 15:03:51 jkh Exp"; +#else +__RCSID("$NetBSD: build.c,v 1.1 2007/08/03 13:15:59 joerg Exp $"); +#endif +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * 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. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the main body of the create module. + * + */ + +#include "lib.h" +#include "create.h" + +#if HAVE_ERR_H +#include <err.h> +#endif +#if HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <pwd.h> +#include <grp.h> + +#include <archive.h> +#include <archive_entry.h> + +static struct memory_file *contents_file; +static struct memory_file *comment_file; +static struct memory_file *desc_file; +static struct memory_file *install_file; +static struct memory_file *deinstall_file; +static struct memory_file *display_file; +static struct memory_file *build_version_file; +static struct memory_file *build_info_file; +static struct memory_file *size_pkg_file; +static struct memory_file *size_all_file; +static struct memory_file *preserve_file; +static struct memory_file *views_file; + +static void +write_meta_file(struct memory_file *file, struct archive *archive) +{ + struct archive_entry *entry; + + entry = archive_entry_new(); + archive_entry_set_pathname(entry, file->name); + archive_entry_copy_stat(entry, &file->st); + + archive_entry_set_uname(entry, file->owner); + archive_entry_set_gname(entry, file->group); + + if (archive_write_header(archive, entry)) + errx(2, "cannot write to archive: %s", archive_error_string(archive)); + + archive_write_data(archive, file->data, file->len); + + archive_entry_free(entry); +} + +LIST_HEAD(hardlink_list, hardlinked_entry); +struct hardlink_list written_hardlinks; + +struct hardlinked_entry { + LIST_ENTRY(hardlinked_entry) link; + const char *existing_name; + nlink_t remaining_links; + dev_t existing_device; + ino_t existing_ino; +}; + +static void +write_normal_file(const char *name, struct archive *archive, const char *owner, const char *group) +{ + char buf[16384]; + off_t len; + ssize_t buf_len; + struct hardlinked_entry *older_link; + struct archive_entry *entry; + struct stat st; + int fd; + + if (lstat(name, &st) == -1) + err(2, "lstat failed for file %s", name); + + entry = archive_entry_new(); + archive_entry_set_pathname(entry, name); + + if (!S_ISDIR(st.st_mode) && st.st_nlink > 1) { + LIST_FOREACH(older_link, &written_hardlinks, link) { + if (st.st_dev == older_link->existing_device && + st.st_ino == older_link->existing_ino) { + archive_entry_copy_hardlink(entry, + older_link->existing_name); + if (archive_write_header(archive, entry)) { + errx(2, "cannot write to archive: %s", + archive_error_string(archive)); + } + + if (--older_link->remaining_links > 0) + return; + LIST_REMOVE(older_link, link); + free(older_link); + return; + } + } + /* Not yet linked */ + if ((older_link = malloc(sizeof(*older_link))) == NULL) + err(2, "malloc failed"); + older_link->existing_name = name; + older_link->remaining_links = st.st_nlink - 1; + older_link->existing_device = st.st_dev; + older_link->existing_ino = st.st_ino; + LIST_INSERT_HEAD(&written_hardlinks, older_link, link); + } + + archive_entry_copy_stat(entry, &st); + + if (owner != NULL) { + uid_t uid; + + archive_entry_set_uname(entry, owner); + if (uid_from_user(owner, &uid) == -1) + errx(2, "user %s unknown", owner); + archive_entry_set_uid(entry, uid); + } else { + archive_entry_set_uname(entry, user_from_uid(st.st_uid, 1)); + } + + if (group != NULL) { + gid_t gid; + + archive_entry_set_gname(entry, group); + if (gid_from_group(group, &gid) == -1) + errx(2, "group %s unknown", group); + archive_entry_set_gid(entry, gid); + } else { + archive_entry_set_gname(entry, group_from_gid(st.st_gid, 1)); + } + + switch (st.st_mode & S_IFMT) { + case S_IFLNK: + buf_len = readlink(name, buf, sizeof buf); + if (buf_len < 0) + err(2, "cannot read symlink %s", name); + buf[buf_len] = '\0'; + archive_entry_set_symlink(entry, buf); + + if (archive_write_header(archive, entry)) + errx(2, "cannot write to archive: %s", archive_error_string(archive)); + + break; + + case S_IFREG: + fd = open(name, O_RDONLY); + if (fd == -1) + errx(2, "cannot open data file %s: %s", name, archive_error_string(archive)); + + len = st.st_size; + + if (archive_write_header(archive, entry)) + errx(2, "cannot write to archive: %s", archive_error_string(archive)); + + while (len > 0) { + if (len > sizeof(buf)) + buf_len = sizeof(buf); + else + buf_len = (ssize_t)len; + if ((buf_len = read(fd, buf, buf_len)) <= 0) + break; + archive_write_data(archive, buf, (size_t)buf_len); + len -= buf_len; + } + + close(fd); + break; + + default: + errx(2, "PLIST entry neither symlink nor directory: %s", name); + } + + archive_entry_free(entry); +} + +static void +make_dist(const char *pkg, const char *suffix, const package_t *plist) +{ + char *archive_name; + const char *owner, *group; + const plist_t *p; + struct archive *archive; + char *initial_cwd; + + archive = archive_write_new(); + archive_write_set_format_pax_restricted(archive); + + if (strcmp(suffix, "tbz") == 0 || strcmp(suffix, "tar.bz2") == 0) + archive_write_set_compression_bzip2(archive); + else if (strcmp(suffix, "tgz") == 0 || strcmp(suffix, "tar.gz") == 0) + archive_write_set_compression_gzip(archive); + else + archive_write_set_compression_none(archive); + + if (asprintf(&archive_name, "%s.%s", pkg, suffix) == -1) + err(2, "cannot compute output name"); + + if (archive_write_open_file(archive, archive_name)) + errx(2, "cannot create archive: %s", archive_error_string(archive)); + + free(archive_name); + + owner = DefaultOwner; + group = DefaultGroup; + + write_meta_file(contents_file, archive); + write_meta_file(comment_file, archive); + write_meta_file(desc_file, archive); + + if (Install) + write_meta_file(install_file, archive); + if (DeInstall) + write_meta_file(deinstall_file, archive); + if (Display) + write_meta_file(display_file, archive); + if (BuildVersion) + write_meta_file(build_version_file, archive); + if (BuildInfo) + write_meta_file(build_info_file, archive); + if (SizePkg) + write_meta_file(size_pkg_file, archive); + if (SizeAll) + write_meta_file(size_all_file, archive); + if (Preserve) + write_meta_file(preserve_file, archive); + if (create_views) + write_meta_file(views_file, archive); + + initial_cwd = getcwd(NULL, 0); + + for (p = plist->head; p; p = p->next) { + if (p->type == PLIST_FILE) { + write_normal_file(p->name, archive, owner, group); + } else if (p->type == PLIST_CWD || p->type == PLIST_SRC) { + + /* XXX let PLIST_SRC override PLIST_CWD */ + if (p->type == PLIST_CWD && p->next != NULL && + p->next->type == PLIST_SRC) { + continue; + } + chdir(p->name); + } else if (p->type == PLIST_IGNORE) { + p = p->next; + } else if (p->type == PLIST_CHOWN) { + if (p->name != NULL) + owner = p->name; + else + owner = DefaultOwner; + } else if (p->type == PLIST_CHGRP) { + if (p->name != NULL) + group = p->name; + else + group = DefaultGroup; + } + } + chdir(initial_cwd); + free(initial_cwd); + + if (archive_write_close(archive)) + errx(2, "cannot finish archive: %s", archive_error_string(archive)); + archive_write_finish(archive); +} + +static struct memory_file * +load_and_add(package_t *plist, const char *input_name, + const char *target_name, mode_t perm) +{ + struct memory_file *file; + + file = load_memory_file(input_name, target_name, DefaultOwner, + DefaultGroup, perm); + add_plist(plist, PLIST_IGNORE, NULL); + add_plist(plist, PLIST_FILE, target_name); + + return file; +} + +static struct memory_file * +make_and_add(package_t *plist, const char *target_name, + char *content, mode_t perm) +{ + struct memory_file *file; + + file = make_memory_file(target_name, content, strlen(content), + DefaultOwner, DefaultGroup, perm); + add_plist(plist, PLIST_IGNORE, NULL); + add_plist(plist, PLIST_FILE, target_name); + + return file; +} + +int +pkg_build(const char *pkg, const char *full_pkg, const char *suffix, + package_t *plist) +{ + char *plist_buf; + size_t plist_len; + + /* Now put the release specific items in */ + add_plist(plist, PLIST_CWD, "."); + comment_file = make_and_add(plist, COMMENT_FNAME, Comment, 0444); + desc_file = make_and_add(plist, DESC_FNAME, Desc, 0444); + + if (Install) { + install_file = load_and_add(plist, Install, INSTALL_FNAME, + 0555); + } + if (DeInstall) { + deinstall_file = load_and_add(plist, DeInstall, + DEINSTALL_FNAME, 0555); + } + if (Display) { + display_file = load_and_add(plist, Display, + DISPLAY_FNAME, 0444); + add_plist(plist, PLIST_DISPLAY, DISPLAY_FNAME); + } + if (BuildVersion) { + build_version_file = load_and_add(plist, BuildVersion, + BUILD_VERSION_FNAME, 0444); + } + if (BuildInfo) { + build_info_file = load_and_add(plist, BuildInfo, + BUILD_INFO_FNAME, 0444); + } + if (SizePkg) { + size_pkg_file = load_and_add(plist, SizePkg, + SIZE_PKG_FNAME, 0444); + } + if (SizeAll) { + size_all_file = load_and_add(plist, SizeAll, + SIZE_ALL_FNAME, 0444); + } + if (Preserve) { + preserve_file = load_and_add(plist, Preserve, + PRESERVE_FNAME, 0444); + } + if (create_views) + views_file = make_and_add(plist, VIEWS_FNAME, "", 0444); + + /* Finally, write out the packing list */ + stringify_plist(plist, &plist_buf, &plist_len, realprefix); + contents_file = make_memory_file(CONTENTS_FNAME, plist_buf, plist_len, + DefaultOwner, DefaultGroup, 0644); + + /* And stick it into a tar ball */ + make_dist(pkg, suffix, plist); + + return TRUE; /* Success */ +} diff --git a/pkgtools/pkg_install/files/create/create.h b/pkgtools/pkg_install/files/create/create.h index f7c6b835f98..c3fe149ae3c 100644 --- a/pkgtools/pkg_install/files/create/create.h +++ b/pkgtools/pkg_install/files/create/create.h @@ -1,4 +1,4 @@ -/* $NetBSD: create.h,v 1.8 2007/07/30 07:25:10 joerg Exp $ */ +/* $NetBSD: create.h,v 1.9 2007/08/03 13:15:59 joerg Exp $ */ /* from FreeBSD Id: create.h,v 1.13 1997/10/08 07:46:19 charnier Exp */ @@ -25,6 +25,17 @@ #ifndef _INST_CREATE_H_INCLUDE #define _INST_CREATE_H_INCLUDE +struct memory_file { + struct stat st; + const char *name; + const char *owner; + const char *group; + mode_t mode; + + char *data; + size_t len; +}; + extern char *Prefix; extern char *Comment; extern char *Desc; @@ -42,6 +53,8 @@ extern char *SizeAll; extern char *Preserve; extern char *SrcDir; extern char *realprefix; +extern char *DefaultOwner; +extern char *DefaultGroup; extern char PlayPen[]; extern size_t PlayPenSize; extern int PlistOnly; @@ -50,9 +63,18 @@ extern int ReorderDirs; extern int update_pkgdb; extern int create_views; -void check_list(char *, package_t *, const char *); +void check_list(package_t *, const char *); void copy_plist(char *, package_t *); -int pkg_perform(const char *); +struct memory_file + *load_memory_file(const char *, const char *, + const char *, const char *, mode_t); +struct memory_file + *make_memory_file(const char *, void *, size_t, + const char *, const char *, mode_t); +void free_memory_file(struct memory_file *); + +int pkg_perform(const char *); +int pkg_build(const char *, const char *, const char *, package_t *plist); #endif /* _INST_CREATE_H_INCLUDE */ diff --git a/pkgtools/pkg_install/files/create/main.c b/pkgtools/pkg_install/files/create/main.c index d2b61665b0a..f5d69fe59f3 100644 --- a/pkgtools/pkg_install/files/create/main.c +++ b/pkgtools/pkg_install/files/create/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.10 2007/07/30 07:25:11 joerg Exp $ */ +/* $NetBSD: main.c,v 1.11 2007/08/03 13:15:59 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -11,7 +11,7 @@ #if 0 static const char *rcsid = "from FreeBSD Id: main.c,v 1.17 1997/10/08 07:46:23 charnier Exp"; #else -__RCSID("$NetBSD: main.c,v 1.10 2007/07/30 07:25:11 joerg Exp $"); +__RCSID("$NetBSD: main.c,v 1.11 2007/08/03 13:15:59 joerg Exp $"); #endif #endif @@ -32,7 +32,7 @@ __RCSID("$NetBSD: main.c,v 1.10 2007/07/30 07:25:11 joerg Exp $"); #include "lib.h" #include "create.h" -static const char Options[] = "B:C:D:EFI:K:L:OP:RS:T:UVb:c:d:f:i:k:ln:p:r:s:t:v"; +static const char Options[] = "B:C:D:EFI:K:L:OP:RS:T:UVb:c:d:f:g:i:k:ln:p:r:s:u:v"; char *Prefix = NULL; char *Comment = NULL; @@ -50,6 +50,8 @@ char *SizePkg = NULL; char *SizeAll = NULL; char *Preserve = NULL; char *SrcDir = NULL; +char *DefaultOwner = NULL; +char *DefaultGroup = NULL; char *realprefix = NULL; char PlayPen[MaxPathSize]; size_t PlayPenSize = sizeof(PlayPen); @@ -68,12 +70,18 @@ usage(void) " [-C cpkgs] [-D displayfile] [-I realprefix] [-i iscript]\n" " [-K pkg_dbdir] [-k dscript] [-L SrcDir]\n" " [-n preserve-file] [-P dpkgs] [-p prefix] [-r rscript]\n" - " [-S size-all-file] [-s size-pkg-file] [-t template]\n" - " [-T buildpkgs] -c comment -d description -f packlist\n" + " [-S size-all-file] [-s size-pkg-file]\n" + " [-T buildpkgs] [-u owner] [-g group]\n" + " -c comment -d description -f packlist\n" " pkg-name\n"); exit(1); } +void +cleanup(int in_signal) +{ +} + int main(int argc, char **argv) { @@ -130,6 +138,10 @@ main(int argc, char **argv) Desc = optarg; break; + case 'g': + DefaultGroup = optarg; + break; + case 'i': Install = optarg; break; @@ -150,8 +162,8 @@ main(int argc, char **argv) SrcDir = optarg; break; - case 't': - strlcpy(PlayPen, optarg, sizeof(PlayPen)); + case 'u': + DefaultOwner = optarg; break; case 'D': @@ -204,10 +216,13 @@ main(int argc, char **argv) usage(); } - if (!pkg_perform(*argv)) { - if (Verbose) - warnx("package creation failed"); - return 1; - } else + if (pkg_perform(*argv)) return 0; + if (Verbose) { + if (PlistOnly) + warnx("package registration failed"); + else + warnx("package creation failed"); + } + return 1; } diff --git a/pkgtools/pkg_install/files/create/perform.c b/pkgtools/pkg_install/files/create/perform.c index f083ffb959f..90b1a8e25e2 100644 --- a/pkgtools/pkg_install/files/create/perform.c +++ b/pkgtools/pkg_install/files/create/perform.c @@ -1,4 +1,4 @@ -/* $NetBSD: perform.c,v 1.14 2007/07/30 07:25:11 joerg Exp $ */ +/* $NetBSD: perform.c,v 1.15 2007/08/03 13:15:59 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -11,7 +11,7 @@ #if 0 static const char *rcsid = "from FreeBSD Id: perform.c,v 1.38 1997/10/13 15:03:51 jkh Exp"; #else -__RCSID("$NetBSD: perform.c,v 1.14 2007/07/30 07:25:11 joerg Exp $"); +__RCSID("$NetBSD: perform.c,v 1.15 2007/08/03 13:15:59 joerg Exp $"); #endif #endif @@ -41,9 +41,6 @@ __RCSID("$NetBSD: perform.c,v 1.14 2007/07/30 07:25:11 joerg Exp $"); #if HAVE_ERR_H #include <err.h> #endif -#if HAVE_SIGNAL_H -#include <signal.h> -#endif #if HAVE_SYS_WAIT_H #include <sys/wait.h> #endif @@ -51,160 +48,42 @@ __RCSID("$NetBSD: perform.c,v 1.14 2007/07/30 07:25:11 joerg Exp $"); #include <unistd.h> #endif -static char *Home; -void cleanup_callback(void); - -static void -make_dist(const char *home, const char *pkg, const char *suffix, const package_t *plist) -{ - char tball[MaxPathSize]; - const plist_t *p; - int ret; - char *args[50]; /* Much more than enough. */ - int nargs = 1; - FILE *totar; - pipe_to_system_t *to_pipe; - - if ((args[0] = (char *)strrchr(TAR_CMD, '/')) == NULL) - args[0] = TAR_CMD; - else - args[0]++; - - if (*pkg == '/') - (void) snprintf(tball, sizeof(tball), "%s.%s", pkg, suffix); - else - (void) snprintf(tball, sizeof(tball), "%s/%s.%s", home, pkg, suffix); - - args[nargs++] = "-c"; - args[nargs++] = "-f"; - args[nargs++] = tball; - if (strstr(suffix, "bz")) { - args[nargs++] = "--use-compress-program"; - args[nargs++] = "bzip2"; - } else if (strchr(suffix, 'z'))/* Compress/gzip? */ - args[nargs++] = "-z"; - args[nargs++] = "-T"; /* Take filenames from file instead of args. */ - args[nargs++] = "-"; /* Use stdin for the file. */ - args[nargs] = NULL; - - to_pipe = pipe_to_system_begin(TAR_CMD, args, cleanup_callback); - totar = to_pipe->fp; - - fprintf(totar, "%s\n", CONTENTS_FNAME); - fprintf(totar, "%s\n", COMMENT_FNAME); - fprintf(totar, "%s\n", DESC_FNAME); - - if (Install) { - fprintf(totar, "%s\n", INSTALL_FNAME); - } - if (DeInstall) { - fprintf(totar, "%s\n", DEINSTALL_FNAME); - } - if (Display) { - fprintf(totar, "%s\n", DISPLAY_FNAME); - } - if (BuildVersion) { - (void) fprintf(totar, "%s\n", BUILD_VERSION_FNAME); - } - if (BuildInfo) { - (void) fprintf(totar, "%s\n", BUILD_INFO_FNAME); - } - if (SizePkg) { - (void) fprintf(totar, "%s\n", SIZE_PKG_FNAME); - } - if (SizeAll) { - (void) fprintf(totar, "%s\n", SIZE_ALL_FNAME); - } - if (Preserve) { - (void) fprintf(totar, "%s\n", PRESERVE_FNAME); - } - if (create_views) { - (void) fprintf(totar, "%s\n", VIEWS_FNAME); - } - - for (p = plist->head; p; p = p->next) { - if (p->type == PLIST_FILE) { - fprintf(totar, "%s\n", p->name); - } else if (p->type == PLIST_CWD || p->type == PLIST_SRC) { - - /* XXX let PLIST_SRC override PLIST_CWD */ - if (p->type == PLIST_CWD && p->next != NULL && - p->next->type == PLIST_SRC) { - continue; - } - - fprintf(totar, "-C\n%s\n", p->name); - } else if (p->type == PLIST_IGNORE) { - p = p->next; - } - } - - ret = pipe_to_system_end(to_pipe); - /* assume either signal or bad exit is enough for us */ - if (ret) { - cleanup(0); - errx(2, "%s command failed with code %d", TAR_CMD, ret); - } -} - static void sanity_check(void) { - if (!Comment) { - cleanup(0); + if (!Comment) errx(2, "required package comment string is missing (-c comment)"); - } - if (!Desc) { - cleanup(0); + if (!Desc) errx(2, "required package description string is missing (-d desc)"); - } - if (!Contents) { - cleanup(0); + if (!Contents) errx(2, "required package contents list is missing (-f [-]file)"); - } -} - -/* - * Clean up callback for pipe_to_system() - */ -void -cleanup_callback(void) -{ - cleanup(0); -} - -/* - * Clean up those things that would otherwise hang around - */ -void -cleanup(int sig) -{ - static int alreadyCleaning; - void (*oldint) (int); - void (*oldhup) (int); - oldint = signal(SIGINT, SIG_IGN); - oldhup = signal(SIGHUP, SIG_IGN); - - if (!alreadyCleaning) { - alreadyCleaning = 1; - if (sig) - printf("Signal %d received, cleaning up.\n", sig); - leave_playpen(Home); - if (sig) - exit(1); - } - signal(SIGINT, oldint); - signal(SIGHUP, oldhup); } int pkg_perform(const char *pkg) { char *cp; - FILE *pkg_in, *fp; + FILE *pkg_in; package_t plist; - char *suffix; /* What we tack on to the end of the finished package */ - char installed[MaxPathSize]; + char installed[MaxPathSize]; + const char *full_pkg, *suffix; + char *allocated_pkg; + int retval; + + /* Break the package name into base and desired suffix (if any) */ + if ((cp = strrchr(pkg, '.')) != NULL) { + if ((allocated_pkg = malloc(cp - pkg + 1)) == NULL) + err(2, "malloc failed"); + memcpy(allocated_pkg, pkg, cp - pkg); + allocated_pkg[cp - pkg] = '\0'; + suffix = cp + 1; + full_pkg = pkg; + pkg = allocated_pkg; + } else { + allocated_pkg = NULL; + full_pkg = pkg; + suffix = "tgz"; + } /* Preliminary setup */ sanity_check(); @@ -216,20 +95,11 @@ pkg_perform(const char *pkg) pkg_in = stdin; else { pkg_in = fopen(Contents, "r"); - if (!pkg_in) { - cleanup(0); + if (!pkg_in) errx(2, "unable to open contents file '%s' for input", Contents); - } } plist.head = plist.tail = NULL; - /* Break the package name into base and desired suffix (if any) */ - if ((cp = strrchr(pkg, '.')) != NULL) { - suffix = cp + 1; - *cp = '\0'; - } else - suffix = "tgz"; - /* If a SrcDir override is set, add it now */ if (SrcDir) { if (Verbose && !PlistOnly) @@ -312,102 +182,31 @@ pkg_perform(const char *pkg) add_plist_top(&plist, PLIST_NAME, basename_of(pkg)); } + /* Make first "real contents" pass over it */ + check_list(&plist, basename_of(pkg)); + /* * We're just here for to dump out a revised plist for the FreeBSD ports * hack. It's not a real create in progress. */ if (PlistOnly) { - check_list(Home, &plist, basename_of(pkg)); write_plist(&plist, stdout, realprefix); - exit(0); - } - - /* Make a directory to stomp around in */ - Home = make_playpen(PlayPen, PlayPenSize, 0); - signal(SIGINT, cleanup); - signal(SIGHUP, cleanup); - - /* Make first "real contents" pass over it */ - check_list(Home, &plist, basename_of(pkg)); - (void) umask(DEF_UMASK);/* make sure gen'ed directories, files - * don't have group or other write bits. */ - - /* Now put the release specific items in */ - add_plist(&plist, PLIST_CWD, "."); - write_file(COMMENT_FNAME, Comment); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, COMMENT_FNAME); - write_file(DESC_FNAME, Desc); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, DESC_FNAME); - - if (Install) { - copy_file(Home, Install, INSTALL_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, INSTALL_FNAME); - } - if (DeInstall) { - copy_file(Home, DeInstall, DEINSTALL_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME); - } - if (Display) { - copy_file(Home, Display, DISPLAY_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, DISPLAY_FNAME); - add_plist(&plist, PLIST_DISPLAY, DISPLAY_FNAME); - } - if (BuildVersion) { - copy_file(Home, BuildVersion, BUILD_VERSION_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, BUILD_VERSION_FNAME); - } - if (BuildInfo) { - copy_file(Home, BuildInfo, BUILD_INFO_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, BUILD_INFO_FNAME); - } - if (SizePkg) { - copy_file(Home, SizePkg, SIZE_PKG_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, SIZE_PKG_FNAME); - } - if (SizeAll) { - copy_file(Home, SizeAll, SIZE_ALL_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, SIZE_ALL_FNAME); - } - if (Preserve) { - copy_file(Home, Preserve, PRESERVE_FNAME); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, PRESERVE_FNAME); - } - if (create_views) { - write_file(VIEWS_FNAME, ""); - add_plist(&plist, PLIST_IGNORE, NULL); - add_plist(&plist, PLIST_FILE, VIEWS_FNAME); - } - - /* Finally, write out the packing list */ - fp = fopen(CONTENTS_FNAME, "w"); - if (!fp) { - cleanup(0); - errx(2, "can't open file %s for writing", CONTENTS_FNAME); - } - write_plist(&plist, fp, realprefix); - if (fclose(fp)) { - cleanup(0); - errx(2, "error while closing %s", CONTENTS_FNAME); + retval = TRUE; + } else { +#ifdef BOOTSTRAP + warnx("Package building is not supported in bootstrap mode"); + retval = FALSE; +#else + retval = pkg_build(pkg, full_pkg, suffix, &plist); +#endif } - /* And stick it into a tar ball */ - make_dist(Home, pkg, suffix, &plist); - /* Cleanup */ free(Comment); free(Desc); free_plist(&plist); - leave_playpen(Home); - - return TRUE; /* Success */ + + free(allocated_pkg); + + return retval; } diff --git a/pkgtools/pkg_install/files/create/pkg_create.1 b/pkgtools/pkg_install/files/create/pkg_create.1 index c9a6516f63e..b47efba200b 100644 --- a/pkgtools/pkg_install/files/create/pkg_create.1 +++ b/pkgtools/pkg_install/files/create/pkg_create.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: pkg_create.1,v 1.10 2007/07/25 15:01:46 joerg Exp $ +.\" $NetBSD: pkg_create.1,v 1.11 2007/08/03 13:15:59 joerg Exp $ .\" .\" FreeBSD install - a package for the installation and maintenance .\" of non-core utilities. @@ -44,6 +44,8 @@ .Ek .Bk -words .Op Fl D Ar displayfile +.Bk -words +.Op Fl g Ar group .Ek .Bk -words .Op Fl I Ar realprefix @@ -82,6 +84,8 @@ .Op Fl t Ar template .Ek .Bk -words +.Op Fl u Ar owner +.Bk -words .Fl c Ar comment .Ek .Bk -words @@ -166,6 +170,10 @@ if is a .Cm - (dash). +.It Fl g Ar group +Make +.Ar group +the default group ownership instead of extracting it from the file system. .It Fl I Ar realprefix Provide the real prefix, as opposed to the staging prefix, for use in staged installations of packages. @@ -283,6 +291,10 @@ characters for to fill in with a unique ID. .It Fl U Do not update the package file database with any file information. +.It Fl u Ar owner +Make +.Ar owner +the default owner instead of extracting it from the file system. .It Fl V Print version number and exit. .It Fl v diff --git a/pkgtools/pkg_install/files/create/pkg_create.cat1 b/pkgtools/pkg_install/files/create/pkg_create.cat1 index 1bc5e4a31d2..420134c15f7 100644 --- a/pkgtools/pkg_install/files/create/pkg_create.cat1 +++ b/pkgtools/pkg_install/files/create/pkg_create.cat1 @@ -5,11 +5,11 @@ NNAAMMEE SSYYNNOOPPSSIISS ppkkgg__ccrreeaattee [--EEllOORRUUVVvv] [--BB _b_u_i_l_d_-_i_n_f_o_-_f_i_l_e] [--bb _b_u_i_l_d_-_v_e_r_s_i_o_n_-_f_i_l_e] - [--CC _c_p_k_g_s] [--DD _d_i_s_p_l_a_y_f_i_l_e] [--II _r_e_a_l_p_r_e_f_i_x] [--ii _i_s_c_r_i_p_t] - [--KK _p_k_g___d_b_d_i_r] [--kk _d_s_c_r_i_p_t] [--LL _S_r_c_D_i_r] [--mm _m_t_r_e_e_f_i_l_e] + [--CC _c_p_k_g_s] [--DD _d_i_s_p_l_a_y_f_i_l_e] [--gg _g_r_o_u_p] [--II _r_e_a_l_p_r_e_f_i_x] + [--ii _i_s_c_r_i_p_t] [--KK _p_k_g___d_b_d_i_r] [--kk _d_s_c_r_i_p_t] [--LL _S_r_c_D_i_r] [--nn _p_r_e_s_e_r_v_e_-_f_i_l_e] [--PP _d_p_k_g_s] [--TT _b_u_i_l_d_p_k_g_s] [--pp _p_r_e_f_i_x] - [--SS _s_i_z_e_-_a_l_l_-_f_i_l_e] [--ss _s_i_z_e_-_p_k_g_-_f_i_l_e] [--tt _t_e_m_p_l_a_t_e] --cc _c_o_m_m_e_n_t - --dd _d_e_s_c_r_i_p_t_i_o_n --ff _p_a_c_k_l_i_s_t _p_k_g_-_n_a_m_e + [--SS _s_i_z_e_-_a_l_l_-_f_i_l_e] [--ss _s_i_z_e_-_p_k_g_-_f_i_l_e] [--tt _t_e_m_p_l_a_t_e] [--uu _o_w_n_e_r] + --cc _c_o_m_m_e_n_t --dd _d_e_s_c_r_i_p_t_i_o_n --ff _p_a_c_k_l_i_s_t _p_k_g_-_n_a_m_e DDEESSCCRRIIPPTTIIOONN The ppkkgg__ccrreeaattee command is used to create packages that will subsequently @@ -65,6 +65,10 @@ OOPPTTIIOONNSS Fetch (packing list) for package from the file _p_a_c_k_l_i_s_t or ssttddiinn if _p_a_c_k_l_i_s_t is a -- (dash). + --gg _g_r_o_u_p + Make _g_r_o_u_p the default group ownership instead of extracting it + from the file system. + --II _r_e_a_l_p_r_e_f_i_x Provide the real prefix, as opposed to the staging prefix, for use in staged installations of packages. @@ -151,6 +155,10 @@ OOPPTTIIOONNSS --UU Do not update the package file database with any file informa- tion. + --uu _o_w_n_e_r + Make _o_w_n_e_r the default owner instead of extracting it from the + file system. + --VV Print version number and exit. --vv Turn on verbose output. diff --git a/pkgtools/pkg_install/files/create/pl.c b/pkgtools/pkg_install/files/create/pl.c index 55446c2bf15..02886dabe99 100644 --- a/pkgtools/pkg_install/files/create/pl.c +++ b/pkgtools/pkg_install/files/create/pl.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl.c,v 1.9 2004/12/29 12:16:56 agc Exp $ */ +/* $NetBSD: pl.c,v 1.10 2007/08/03 13:15:59 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -11,7 +11,7 @@ #if 0 static const char *rcsid = "from FreeBSD Id: pl.c,v 1.11 1997/10/08 07:46:35 charnier Exp"; #else -__RCSID("$NetBSD: pl.c,v 1.9 2004/12/29 12:16:56 agc Exp $"); +__RCSID("$NetBSD: pl.c,v 1.10 2007/08/03 13:15:59 joerg Exp $"); #endif #endif @@ -118,7 +118,7 @@ reorder(package_t *pkg, int dirc) * Check a list for files that require preconversion */ void -check_list(char *home, package_t *pkg, const char *PkgName) +check_list(package_t *pkg, const char *PkgName) { struct stat st; plist_t *tmp; @@ -126,16 +126,14 @@ check_list(char *home, package_t *pkg, const char *PkgName) char buf[ChecksumHeaderLen + LegibleChecksumLen]; char target[MaxPathSize + SymlinkHeaderLen]; char name[MaxPathSize]; - char *cwd = home; + char *cwd = NULL; char *srcdir = NULL; int dirc; int cc; /* Open Package Database for writing */ - if (update_pkgdb && !pkgdb_open(ReadWrite)) { - cleanup(0); + if (update_pkgdb && !pkgdb_open(ReadWrite)) err(EXIT_FAILURE, "can't open pkgdb"); - } for (dirc = 0, p = pkg->head; p; p = p->next) { switch (p->type) { @@ -158,6 +156,8 @@ check_list(char *home, package_t *pkg, const char *PkgName) * but as they are present before pkg_create * starts, it's ok to do this somewhere here */ + if (cwd == NULL) + errx(2, "file without preceding @cwd found"); if (update_pkgdb) { char *s, t[MaxPathSize]; @@ -181,17 +181,11 @@ check_list(char *home, package_t *pkg, const char *PkgName) } } - if (cwd == home) { - /* no @cwd yet */ - (void) snprintf(name, sizeof(name), "%s/%s", srcdir ? srcdir : cwd, p->name); - } else { - /* after @cwd */ - /* prepend DESTDIR if set? - HF */ - (void) snprintf(name, sizeof(name), "%s%s%s", - cwd, - (strcmp(cwd, "/") == 0) ? "" : "/", - p->name); - } + /* prepend DESTDIR if set? - HF */ + (void) snprintf(name, sizeof(name), "%s%s%s", + cwd, + (strcmp(cwd, "/") == 0) ? "" : "/", + p->name); if (lstat(name, &st) < 0) { warnx("can't stat `%s'", name); continue; diff --git a/pkgtools/pkg_install/files/create/util.c b/pkgtools/pkg_install/files/create/util.c new file mode 100644 index 00000000000..1588e9be59e --- /dev/null +++ b/pkgtools/pkg_install/files/create/util.c @@ -0,0 +1,147 @@ +/*- + * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>. + * 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <nbcompat.h> + +#include <sys/stat.h> +#include <err.h> +#include <pwd.h> +#include <grp.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "lib.h" +#include "create.h" + +static void +update_ids(struct memory_file *file) +{ + if (file->owner != NULL) { + uid_t uid; + + if (uid_from_user(file->owner, &uid) == -1) + errx(2, "user %s unknown", file->owner); + file->st.st_uid = uid; + } else { + file->owner = user_from_uid(file->st.st_uid, 1); + } + + if (file->group != NULL) { + gid_t gid; + + if (gid_from_group(file->group, &gid) == -1) + errx(2, "group %s unknown", file->group); + file->group = file->group; + file->st.st_gid = gid; + } else { + file->group = group_from_gid(file->st.st_gid, 1); + } +} + +struct memory_file * +make_memory_file(const char *archive_name, void *data, size_t len, + const char *owner, const char *group, mode_t mode) +{ + struct memory_file *file; + + if ((file = malloc(sizeof(*file))) == NULL) + err(2, "malloc failed"); + + file->name = archive_name; + file->owner = owner; + file->group = group; + + file->data = data; + file->len = len; + + memset(&file->st, 0, sizeof(file->st)); + + file->st.st_atime = file->st.st_ctime = file->st.st_mtime = time(NULL); + + file->st.st_nlink = 1; + file->st.st_size = len; + file->st.st_mode = mode | S_IFREG; + + update_ids(file); + + return file; +} + +struct memory_file * +load_memory_file(const char *disk_name, + const char *archive_name, const char *owner, const char *group, + mode_t mode) +{ + struct memory_file *file; + int fd; + + if ((file = malloc(sizeof(*file))) == NULL) + err(2, "malloc failed"); + + file->name = archive_name; + file->owner = owner; + file->group = group; + file->mode = mode; + + fd = open(disk_name, O_RDONLY); + if (fd == -1) + err(2, "cannot open file %s", disk_name); + if (fstat(fd, &file->st) == -1) + err(2, "cannot stat file %s", disk_name); + + update_ids(file); + + if (file->st.st_size > SSIZE_MAX || + (file->data = malloc(file->st.st_size)) == NULL) + errx(2, "cannot allocate memory for file %s", disk_name); + + if (read(fd, file->data, file->st.st_size) != file->st.st_size) + err(2, "cannot read file into memory %s", disk_name); + + file->len = file->st.st_size; + + close(fd); + + return file; +} + +void +free_memory_file(struct memory_file *file) +{ + if (file != NULL) { + free(file->data); + free(file); + } +} diff --git a/pkgtools/pkg_install/files/lib/lib.h b/pkgtools/pkg_install/files/lib/lib.h index fe69ccb8c6f..da5a56ad26f 100644 --- a/pkgtools/pkg_install/files/lib/lib.h +++ b/pkgtools/pkg_install/files/lib/lib.h @@ -1,4 +1,4 @@ -/* $NetBSD: lib.h,v 1.29 2007/07/30 07:16:21 joerg Exp $ */ +/* $NetBSD: lib.h,v 1.30 2007/08/03 13:16:00 joerg Exp $ */ /* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */ @@ -383,6 +383,7 @@ void add_plist(package_t *, pl_ent_t, const char *); void add_plist_top(package_t *, pl_ent_t, const char *); void delete_plist(package_t *, Boolean, pl_ent_t, char *); void write_plist(package_t *, FILE *, char *); +void stringify_plist(package_t *, char **, size_t *, char *); void read_plist(package_t *, FILE *); int plist_cmd(unsigned char *, char **); int delete_package(Boolean, Boolean, package_t *, Boolean); diff --git a/pkgtools/pkg_install/files/lib/plist.c b/pkgtools/pkg_install/files/lib/plist.c index 7470fdb773b..234e350ef36 100644 --- a/pkgtools/pkg_install/files/lib/plist.c +++ b/pkgtools/pkg_install/files/lib/plist.c @@ -1,4 +1,4 @@ -/* $NetBSD: plist.c,v 1.15 2006/11/03 09:35:14 joerg Exp $ */ +/* $NetBSD: plist.c,v 1.16 2007/08/03 13:16:00 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -11,7 +11,7 @@ #if 0 static const char *rcsid = "from FreeBSD Id: plist.c,v 1.24 1997/10/08 07:48:15 charnier Exp"; #else -__RCSID("$NetBSD: plist.c,v 1.15 2006/11/03 09:35:14 joerg Exp $"); +__RCSID("$NetBSD: plist.c,v 1.16 2007/08/03 13:16:00 joerg Exp $"); #endif #endif @@ -330,6 +330,81 @@ write_plist(package_t *pkg, FILE * fp, char *realprefix) } /* + * Like write_plist, but compute memory string. + */ +void +stringify_plist(package_t *pkg, char **real_buf, size_t *real_len, char *realprefix) +{ + plist_t *p; + const cmd_t *cmdp; + char *buf; + size_t len; + int item_len; + + /* Pass One: compute output size only. */ + len = 0; + + for (p = pkg->head; p; p = p->next) { + if (p->type == PLIST_FILE) { + len += strlen(p->name) + 1; + continue; + } + for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) { + } + if (cmdp->c_type == FAIL) + continue; + if (cmdp->c_argc == 0) + len += 1 + strlen(cmdp->c_s) + 1; + else if (cmdp->c_subst && realprefix) + len += 1 + strlen(cmdp->c_s) + 1 + strlen(realprefix) + 1; + else + len += 1 + strlen(cmdp->c_s) + 1 + strlen(p->name ? p->name : "") + 1; + } + + /* Pass Two: build actual string. */ + if ((buf = malloc(len + 1)) == NULL) + err(2, "malloc failed"); + *real_buf = buf; + *real_len = len; + ++len; + +#define UPDATE_LEN \ +do { \ + if (item_len < 0 || item_len > len) \ + errx(2, "Size computation failed, aborted."); \ + buf += item_len; \ + len -= item_len; \ +} while (0) + + for (p = pkg->head; p; p = p->next) { + if (p->type == PLIST_FILE) { + /* Fast-track files - these are the most common */ + item_len = snprintf(buf, len, "%s\n", p->name); + UPDATE_LEN; + continue; + } + for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) { + } + if (cmdp->c_type == FAIL) { + warnx("Unknown PLIST command type %d (%s)", p->type, p->name); + } else if (cmdp->c_argc == 0) { + item_len = snprintf(buf, len, "%c%s\n", CMD_CHAR, cmdp->c_s); + UPDATE_LEN; + } else if (cmdp->c_subst && realprefix) { + item_len = snprintf(buf, len, "%c%s %s\n", CMD_CHAR, cmdp->c_s, realprefix); + UPDATE_LEN; + } else { + item_len = snprintf(buf, len, "%c%s %s\n", CMD_CHAR, cmdp->c_s, + (p->name) ? p->name : ""); + UPDATE_LEN; + } + } + + if (len != 1) + errx(2, "Size computation failed, aborted."); +} + +/* * Delete the results of a package installation. * * This is here rather than in the pkg_delete code because pkg_add needs to diff --git a/pkgtools/pkg_install/files/lib/version.h b/pkgtools/pkg_install/files/lib/version.h index d1691b86c47..f6b0874fc81 100644 --- a/pkgtools/pkg_install/files/lib/version.h +++ b/pkgtools/pkg_install/files/lib/version.h @@ -1,4 +1,4 @@ -/* $NetBSD: version.h,v 1.70 2007/07/30 08:09:15 joerg Exp $ */ +/* $NetBSD: version.h,v 1.71 2007/08/03 13:16:00 joerg Exp $ */ /* * Copyright (c) 2001 Thomas Klausner. All rights reserved. @@ -33,6 +33,6 @@ #ifndef _INST_LIB_VERSION_H_ #define _INST_LIB_VERSION_H_ -#define PKGTOOLS_VERSION "20070730" +#define PKGTOOLS_VERSION "20070802" #endif /* _INST_LIB_VERSION_H_ */ |