ports/79398: New port: archivers/unmakeself, and make bsd.port.mk use it
Jean-Yves Lefort
jylefort at brutele.be
Thu Mar 31 14:20:05 UTC 2005
>Number: 79398
>Category: ports
>Synopsis: New port: archivers/unmakeself, and make bsd.port.mk use it
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Mar 31 14:20:04 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Jean-Yves Lefort
>Release: FreeBSD 5.3-RELEASE-p6 i386
>Organization:
>Environment:
System: FreeBSD jsite.lefort.net 5.3-RELEASE-p6 FreeBSD 5.3-RELEASE-p6 #0: Tue Mar 29 00:14:29 CEST 2005 jylefort at jsite.lefort.net:/usr/obj/usr/src/sys/JSITE i386
>Description:
Here's a port for extracting Makeself archives. They are the .run or
.sh self-extracting shell scripts most commercial games ship as.
Several ports (mostly games) use Makeself archives as distfiles. With
the provided bsd.port.mk patch, they can now define USE_MAKESELF=yes
instead of manually specifying EXTRACT_SUFX and do-extract.
>How-To-Repeat:
>Fix:
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# unmakeself
# unmakeself/files
# unmakeself/files/unmakeself.c
# unmakeself/pkg-descr
# unmakeself/Makefile
#
echo c - unmakeself
mkdir -p unmakeself > /dev/null 2>&1
echo c - unmakeself/files
mkdir -p unmakeself/files > /dev/null 2>&1
echo x - unmakeself/files/unmakeself.c
sed 's/^X//' >unmakeself/files/unmakeself.c << 'END-of-unmakeself/files/unmakeself.c'
X/*
X * unmakeself - extracts Makeself archives
X *
X * Copyright (C) 2005 Jean-Yves Lefort
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors
X * may be used to endorse or promote products derived from this software
X * without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
X * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
X * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
X * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
X * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
X * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
X * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
X * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
X * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
X * POSSIBILITY OF SUCH DAMAGE.
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <locale.h>
X#include <string.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/uio.h>
X#include <unistd.h>
X#include <getopt.h>
X#include <archive.h>
X
Xstatic char *self = NULL; /* program name */
Xstatic int extract_flags = ARCHIVE_EXTRACT_TIME; /* bsdtar default */
X
Xstatic void unmakeself_print_help (void);
Xstatic void unmakeself_print_version (void);
Xstatic void unmakeself_extract (const char *filename);
X
Xint
Xmain (int argc, char **argv)
X{
X const struct option options[] = {
X { "help", no_argument, NULL, '?' },
X { "version", no_argument, NULL, 'v' },
X { "keep-old-files", no_argument, NULL, 'k' },
X { "modification-time", no_argument, NULL, 'm' },
X { "no-same-owner", no_argument, NULL, 'o' },
X { "preserve-permissions", no_argument, NULL, 'p' },
X { "unlink", no_argument, NULL, 'U' },
X { "unlink-first", no_argument, NULL, 'U' },
X { NULL, 0, NULL, 0 }
X };
X int c;
X
X self = argc > 0 ? strdup(argv[0]) : "unmakeself";
X setlocale(LC_ALL, "");
X
X if (geteuid() == 0) /* bsdtar does this */
X extract_flags |= ARCHIVE_EXTRACT_OWNER;
X
X while ((c = getopt_long(argc, argv, "?vkmpUx", options, NULL)) != -1)
X switch (c)
X {
X case '?':
X unmakeself_print_help();
X exit(0);
X break;
X
X case 'v':
X unmakeself_print_version();
X exit(0);
X break;
X
X case 'k': /* GNU tar, bsdtar */
X extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE;
X break;
X
X case 'm': /* SUSv2, bsdtar */
X extract_flags &= ~ARCHIVE_EXTRACT_TIME;
X break;
X
X case 'o': /* bsdtar */
X extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
X break;
X
X case 'p': /* GNU tar, star, bsdtar */
X extract_flags |= ARCHIVE_EXTRACT_PERM;
X extract_flags |= ARCHIVE_EXTRACT_ACL;
X extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
X break;
X
X case 'U': /* GNU tar, bsdtar */
X extract_flags |= ARCHIVE_EXTRACT_UNLINK;
X break;
X
X default:
X abort();
X }
X
X argc -= optind;
X argv += optind;
X
X if (argc != 1)
X {
X fprintf(stderr, "%s: a file to extract must be specified\n", self);
X exit(1);
X }
X
X unmakeself_extract(argv[0]);
X
X /* on some systems, the return value of main() is ignored */
X exit(0);
X
X return 0;
X}
X
Xstatic void
Xunmakeself_print_help (void)
X{
X printf("Synopsis:\n");
X printf(" %s {-? | -v}\n", self);
X printf(" %s [-kmopU] FILE\n", self);
X}
X
Xstatic void
Xunmakeself_print_version (void)
X{
X printf("unmakeself version 0.99\n");
X printf("Copyright (C) 2005 Jean-Yves Lefort\n");
X}
X
Xstatic void
Xunmakeself_extract (const char *filename)
X{
X int fd;
X char buf[4096];
X int pos = 0;
X int last_newline = -1;
X int offset = -1;
X int done = 0;
X ssize_t len;
X
X fd = open(filename, O_RDONLY);
X if (fd < 0)
X {
X fprintf(stderr, "%s: unable to open %s: %s\n", self, filename, strerror(errno));
X exit(1);
X }
X
X /*
X * We find the start offset of the archive inside the shell script
X * by locating the first non-printable character following a
X * newline. The archive starts immediately after that newline.
X */
X while (! done && (len = read(fd, buf, sizeof(buf))) > 0)
X {
X int i;
X
X for (i = 0; i < len; i++, pos++)
X if (buf[i] == '\n')
X last_newline = pos;
X else if (buf[i] != '\t' && (buf[i] < 32 || buf[i] > 126))
X {
X if (last_newline != -1)
X offset = last_newline + 1;
X
X done = 1;
X break;
X }
X }
X
X if (offset != -1) /* offset found, extract using libarchive */
X {
X struct archive *archive;
X struct archive_entry *entry;
X int status;
X
X if (lseek(fd, offset, SEEK_SET) < 0)
X {
X fprintf(stderr, "%s: unable to seek into %s: %s\n", self, filename, strerror(errno));
X exit(1);
X }
X
X archive = archive_read_new();
X
X if (archive_read_support_compression_all(archive) != ARCHIVE_OK)
X fprintf(stderr, "%s: warning: unable to support all compression formats: %s\n", self, archive_error_string(archive));
X if (archive_read_support_format_all(archive) != ARCHIVE_OK)
X fprintf(stderr, "%s: warning: unable to support all archive formats: %s\n", self, archive_error_string(archive));
X
X /* same block size as DEFAULT_BYTES_PER_BLOCK in bsdtar.h */
X if (archive_read_open_fd(archive, fd, 20 * 512) != ARCHIVE_OK)
X {
X fprintf(stderr, "%s: unable to open %s with libarchive: %s\n", self, filename, archive_error_string(archive));
X exit(1);
X }
X
X while ((status = archive_read_next_header(archive, &entry)) == ARCHIVE_OK)
X if (archive_read_extract(archive, entry, extract_flags) != ARCHIVE_OK)
X {
X fprintf(stderr, "%s: unable to extract %s: %s\n", self, filename, archive_error_string(archive));
X exit(1);
X }
X
X if (status != ARCHIVE_EOF)
X {
X fprintf(stderr, "%s: unable to read next header of %s: %s\n", self, filename, archive_error_string(archive));
X exit(1);
X }
X
X if (archive_read_close(archive) != ARCHIVE_OK)
X {
X fprintf(stderr, "%s: unable to close %s with libarchive: %s\n", self, filename, archive_error_string(archive));
X exit(1);
X }
X
X archive_read_finish(archive);
X }
X else
X {
X if (len >= 0) /* EOF, or couldn't find start offset */
X {
X fprintf(stderr, "%s: %s is not a valid Makeself archive\n", self, filename);
X exit(1);
X }
X else /* read error */
X {
X fprintf(stderr, "%s: unable to read %s: %s\n", self, filename, strerror(errno));
X exit(1);
X }
X }
X
X if (close(fd) < 0)
X {
X fprintf(stderr, "%s: unable to close %s: %s\n", self, filename, strerror(errno));
X exit(1);
X }
X}
END-of-unmakeself/files/unmakeself.c
echo x - unmakeself/pkg-descr
sed 's/^X//' >unmakeself/pkg-descr << 'END-of-unmakeself/pkg-descr'
Xunmakeself is a program for extracting Makeself archives without
Xhaving to run the self-extracting shell script.
X
X- Jean-Yves Lefort
Xjylefort at brutele.be
END-of-unmakeself/pkg-descr
echo x - unmakeself/Makefile
sed 's/^X//' >unmakeself/Makefile << 'END-of-unmakeself/Makefile'
X# New ports collection makefile for: unmakeself
X# Date created: 31 Mar 2005
X# Whom: Jean-Yves Lefort <jylefort at brutele.be>
X#
X# $FreeBSD$
X#
X
XPORTNAME= unmakeself
XPORTVERSION= 0.99
XCATEGORIES= archivers
XDISTFILES=
X
XMAINTAINER= jylefort at brutele.be
XCOMMENT= Extract Makeself archives
X
XLDFLAGS= -larchive -lbz2 -lz
XUSE_GETOPT_LONG= yes
XNO_WRKSUBDIR= yes
X
XPLIST_FILES= bin/unmakeself
X
X.include <bsd.port.pre.mk>
X
X.if ${OSVERSION} < 502103
XBUILD_DEPENDS+= ${LOCALBASE}/lib/libarchive.a:${PORTSDIR}/archivers/libarchive
XCPPFLAGS+= -I${LOCALBASE}/include
XLDFLAGS+= -L${LOCALBASE}/lib
X.endif
X
Xdo-build:
X ${CC} ${CFLAGS} ${CPPFLAGS} -o ${WRKSRC}/unmakeself \
X ${FILESDIR}/unmakeself.c ${LDFLAGS}
X
Xdo-install:
X ${MKDIR} ${PREFIX}/bin
X ${INSTALL_PROGRAM} ${WRKSRC}/unmakeself ${PREFIX}/bin
X
X.include <bsd.port.post.mk>
END-of-unmakeself/Makefile
exit
--- bsd.port.mk.orig Fri Mar 18 09:45:37 2005
+++ bsd.port.mk Thu Mar 31 14:01:21 2005
@@ -92,7 +92,7 @@
# EXTRACT_SUFX - Suffix for archive names
# You never have to set both DISTFILES and EXTRACT_SUFX.
# Default: .tar.bz2 if USE_BZIP2 is set, .zip if USE_ZIP is
-# set, .tar.gz otherwise).
+# set, .run if USE_MAKESELF is set, .tar.gz otherwise).
# MASTER_SITES - Primary location(s) for distribution files if not found
# locally. See bsd.sites.mk for common choices for
# MASTER_SITES.
@@ -216,6 +216,8 @@
# compression.
# USE_ZIP - If set, this port distfile uses zip, not tar w/[bg]zip
# for compression.
+# USE_MAKESELF - If set, this port distfile uses makeself, not tar w/[bg]zip
+# for compression.
# USE_GCC - If set, this port requires this version of gcc, either in
# the system or installed from a port.
# USE_GMAKE - If set, this port uses gmake.
@@ -701,7 +703,8 @@
# For extract:
#
# EXTRACT_CMD - Command for extracting archive: "bzip2" if USE_BZIP2
-# is set, "unzip" if USE_ZIP is set, "gzip" otherwise.
+# is set, "unzip" if USE_ZIP is set, "unmakeself" if
+# USE_MAKESELF if set, "gzip" otherwise.
# EXTRACT_BEFORE_ARGS
# - Arguments to ${EXTRACT_CMD} before filename.
# Default: "-dc"
@@ -989,6 +992,7 @@
UNZIP_CMD?= ${LOCALBASE}/bin/unzip
ZIPDEPENDS= yes
.endif
+UNMAKESELF_CMD?= ${LOCALBASE}/bin/unmakeself
WHICH?= /usr/bin/which
XARGS?= /usr/bin/xargs
YACC?= /usr/bin/yacc
@@ -1176,6 +1180,8 @@
EXTRACT_SUFX?= .tar.bz2
.elif defined(USE_ZIP)
EXTRACT_SUFX?= .zip
+.elif defined(USE_MAKESELF)
+EXTRACT_SUFX?= .run
.else
EXTRACT_SUFX?= .tar.gz
.endif
@@ -1433,6 +1439,9 @@
.if defined(USE_ZIP) && defined(ZIPDEPENDS)
EXTRACT_DEPENDS+= unzip:${PORTSDIR}/archivers/unzip
.endif
+.if defined(USE_MAKESELF)
+EXTRACT_DEPENDS+= unmakeself:${PORTSDIR}/archivers/unmakeself
+.endif
.if defined(USE_GMAKE)
BUILD_DEPENDS+= gmake:${PORTSDIR}/devel/gmake
CONFIGURE_ENV+= MAKE=${GMAKE}
@@ -1943,6 +1952,10 @@
EXTRACT_CMD?= ${UNZIP_CMD}
EXTRACT_BEFORE_ARGS?= -qo
EXTRACT_AFTER_ARGS?= -d ${WRKDIR}
+.elif defined(USE_MAKESELF)
+EXTRACT_CMD?= ${UNMAKESELF_CMD}
+EXTRACT_BEFORE_ARGS?=
+EXTRACT_AFTER_ARGS?=
.else
EXTRACT_BEFORE_ARGS?= -dc
EXTRACT_AFTER_ARGS?= | ${TAR} -xf -
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list