Overwriting of bb files, apk_create (from old apk-tools), chdir changes,
other stuff.cute-signatures
parent
384c2f1d94
commit
219a1b2ee8
8
Makefile
8
Makefile
|
@ -7,7 +7,7 @@
|
|||
# under the terms of the GNU General Public License version 3 as published
|
||||
# by the Free Software Foundation. See http://www.gnu.org/ for details.
|
||||
|
||||
VERSION := 2.0-pre0
|
||||
VERSION := 2.0_pre0
|
||||
|
||||
SVN_REV := $(shell svn info 2> /dev/null | grep ^Revision | cut -d ' ' -f 2)
|
||||
ifneq ($(SVN_REV),)
|
||||
|
@ -20,7 +20,7 @@ CC=gcc
|
|||
INSTALL=install
|
||||
INSTALLDIR=$(INSTALL) -d
|
||||
|
||||
CFLAGS=-O2 -g -D_GNU_SOURCE -Werror -Wall -Wstrict-prototypes -std=gnu99 \
|
||||
CFLAGS=-g -D_GNU_SOURCE -Werror -Wall -Wstrict-prototypes -std=gnu99 \
|
||||
-DAPK_VERSION=\"$(FULL_VERSION)\"
|
||||
LDFLAGS=-g -nopie
|
||||
LIBS=-lpthread
|
||||
|
@ -31,12 +31,12 @@ LDFLAGS+=-static
|
|||
endif
|
||||
|
||||
DESTDIR=
|
||||
SBINDIR=/usr/sbin
|
||||
SBINDIR=/sbin
|
||||
CONFDIR=/etc/apk
|
||||
MANDIR=/usr/share/man
|
||||
DOCDIR=/usr/share/doc/apk
|
||||
|
||||
SUBDIRS=src
|
||||
SUBDIRS=src scripts
|
||||
|
||||
.PHONY: compile install clean all
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# Makefile - one file to rule them all, one file to bind them
|
||||
#
|
||||
# Copyright (C) 2007 Timo Teräs <timo.teras@iki.fi>
|
||||
# All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 3 as published
|
||||
# by the Free Software Foundation. See http://www.gnu.org/ for details.
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
|
||||
install::
|
||||
$(INSTALLDIR) $(DESTDIR)$(SBINDIR)
|
||||
$(INSTALL) apk_create $(DESTDIR)$(SBINDIR)
|
||||
$(INSTALLDIR) $(DESTDIR)/lib/apk
|
||||
$(INSTALL) libutil.sh $(DESTDIR)/lib/apk
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# apk_create - a utility for creating software packages.
|
||||
#
|
||||
# Copyright (c) 2005 Natanael Copa
|
||||
#
|
||||
# Distributed under GPL-2
|
||||
#
|
||||
|
||||
PROGRAM=apk_create
|
||||
|
||||
#load the libraries
|
||||
. "${APK_LIBS:=/lib/apk}/libutil.sh"
|
||||
#. "$APK_LIBS/libfetch.sh"
|
||||
#. "$APK_LIBS/libindex.sh"
|
||||
#. "$APK_LIBS/libdb.sh"
|
||||
#. "$APK_LIBS/libpkgf.sh"
|
||||
|
||||
# print usage and die
|
||||
usage() {
|
||||
echo "$PROGRAM $VERSION"
|
||||
echo "
|
||||
Usage: apk_create [hvS] [-a [+]arch] [-c [+]desc] [-i iscript] [-I piscript]
|
||||
[-k dscript] [-K pdscript] [-l [+]license] [-m metadir] [-o owners]
|
||||
[-p package] [-P [+]pkgs] [-s srcdir] [-u uscript] [-U puscript]
|
||||
[-x excludepattern] [-X excludefile ] [-w [+]uri] pkg-filename
|
||||
|
||||
Options:
|
||||
-a Read package architecture from arch or use the argument itself, if
|
||||
preceded with an '+'.
|
||||
-c Read package description from desc or use the argument itself, if
|
||||
preceded with an '+'.
|
||||
-f Use fakeroot when creating the package.
|
||||
-h Show help and exit.
|
||||
-i Use iscript as pre-install script.
|
||||
-I Use piscript as post-install script.
|
||||
-k Use dscript as deinstall script.
|
||||
-K Use pdscript as post-deinstall script.
|
||||
-l Read package license from license or use the argument itself, if
|
||||
preceded with an '+'.
|
||||
-m Use all metafiles found in metadir.
|
||||
-o Use file as OWNERS file.
|
||||
-p Use package as source in addition to or instead of source dir.
|
||||
-P Read space separated dependencies from pkgs or use the argument itself,
|
||||
if preceded with an '+'.
|
||||
-s Set source directory to srcdir.
|
||||
-S Strip ELF files with sstrip.
|
||||
-T Include files listed in includefile.
|
||||
-u Use uscript as pre-update script.
|
||||
-U Use puscript as post-upgrade script.
|
||||
-v Turn on verbose output.
|
||||
-w Read webpage URI from uri or use the argument itself. if preceded
|
||||
with an '+'.
|
||||
-x Exclude files matching excludepattern.
|
||||
-X Exclude files listed in excludefile.
|
||||
"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# if $1 start with a '+', strip the '+' and echo the reset
|
||||
# otherwise read contents from file $1
|
||||
get_arg_or_file() {
|
||||
local tmp
|
||||
# we can do this with awk
|
||||
# but we want it more readable...
|
||||
# echo "$1" | awk '
|
||||
# /^\+/ { print substr($0, 2)}
|
||||
# /^[^\+]/ { readline < $0 ; print}'
|
||||
if echo "$1" | grep '^+' > /dev/null; then
|
||||
echo "$1" | sed 's/^\+//'
|
||||
return 0
|
||||
fi
|
||||
cat "$1" || die "Could not read file '$1'"
|
||||
}
|
||||
|
||||
#parse args
|
||||
unset vflag
|
||||
|
||||
|
||||
while getopts "a:c:fhi:I:k:K:l:m:o:p:P:Ss:T:u:U:vX:x:w:" opt ; do
|
||||
case "$opt" in
|
||||
a) ARCH=`get_arg_or_file "$OPTARG"`;;
|
||||
h) usage;;
|
||||
c) DESC=`get_arg_or_file "$OPTARG"`;;
|
||||
i) PRE_INSTALL="$OPTARG";;
|
||||
I) POST_INSTALL="$OPTARG";;
|
||||
k) DSCRIPT="$OPTARG";;
|
||||
K) POST_DEINSTALL="$OPTARG";;
|
||||
l) LICENSE=`get_arg_or_file "$OPTARG"`;;
|
||||
m) METADIR="$OPTARG";;
|
||||
o) OWNERS="$OPTARG";;
|
||||
p) case "$OPTARG" in
|
||||
*.tar.bz) UNTAR="tar -zxf \"$OPTARG\"";;
|
||||
*.tar.bz2) UNTAR="tar -jxf \"$OPTARG\"";;
|
||||
*) die "Only .tar.gz and .tar.bz2 are supported";;
|
||||
esac;;
|
||||
P) DEPEND=`get_arg_or_file "$OPTARG"`;;
|
||||
s) SRCDIR="$OPTARG";;
|
||||
S) SSTRIP="-S";;
|
||||
T) INCLUDE_FROM="$INCLUDE_FROM --include-from=$OPTARG";;
|
||||
u) PRE_UPDATE="$OPTARG";;
|
||||
U) POST_UPDATE="$OPTARG";;
|
||||
v) VERBOSE="-v" ;;
|
||||
x) EXCLUDE="$EXCLUDE --exclude=$OPTARG";;
|
||||
X) EXCLUDE_FROM="$EXCLUDE_FROM --exclude-from=$OPTARG";;
|
||||
w) WWW=`get_arg_or_file "$OPTARG"`;;
|
||||
\?) usage;;
|
||||
esac
|
||||
done
|
||||
shift `expr $OPTIND - 1`
|
||||
|
||||
# if -s and -p is not specified, use current dir as default.
|
||||
[ -z "$SRCDIR$UNTAR" ] && SRCDIR="."
|
||||
|
||||
[ $# -ne 1 ] && usage
|
||||
|
||||
which rsync > /dev/null || die "This program depends on rsync."
|
||||
|
||||
if [ "`whoami`" != "root" ] ; then
|
||||
SUDO=sudo
|
||||
fi
|
||||
|
||||
# find absolute path to package
|
||||
case "$1" in
|
||||
/*) PKGVF="$1";;
|
||||
*) PKGVF="$PWD/$1";;
|
||||
esac
|
||||
|
||||
PV="`basename \"$PKGVF\" .apk`"
|
||||
echo "$PV" | grep -- '-[0-9].*' > /dev/null || die "Package name $PKGVF does not have any version."
|
||||
P="`echo $PV | sed 's/-[0-9].*//'`"
|
||||
V="`echo $PV | sed 's/^'$P'-//'`"
|
||||
|
||||
# clean temp dir
|
||||
tmp="$APK_TMPDIR/$PV"
|
||||
rm -rf "$tmp"
|
||||
|
||||
# copy files
|
||||
if [ "$UNTAR" ] ; then
|
||||
$UNTAR $INCLUDE_FROM $EXCLUDE $EXCLUDE_FROM -C "$tmp" || \
|
||||
die "Failed to unpack"
|
||||
fi
|
||||
|
||||
if [ "$SRCDIR" ] ; then
|
||||
rsync -ra $INCLUDE_FROM $EXCLUDE $EXCLUDE_FROM "$SRCDIR/." "$tmp" ||\
|
||||
die "Failed to copy files from '$SRCDIR/.' to '$tmp'".
|
||||
fi
|
||||
|
||||
# run sstrip
|
||||
[ "$SSTRIP" ] && find "$tmp" -type f \
|
||||
| xargs -n1 file \
|
||||
| grep ELF \
|
||||
| grep -v relocatable \
|
||||
| cut -d : -f 1 \
|
||||
| while read f ; do
|
||||
$SUDO sstrip "$f"
|
||||
done
|
||||
|
||||
# create meta data
|
||||
dbdir=`beautify_path "$tmp/$APK_DBDIR"`
|
||||
db="$dbdir/$PV"
|
||||
mkdir -p "$db"
|
||||
|
||||
if [ "$METADIR" ] ; then
|
||||
cp $METADIR/* "$db/" || die "Failed to copy files from '$METADIR'"
|
||||
fi
|
||||
[ "$ARCH" ] && echo "$ARCH" > "$db/ARCH"
|
||||
[ "$DEPEND" ] && echo "$DEPEND" > "$db/DEPEND"
|
||||
[ "$DESC" ] && echo "$DESC" > "$db/DESC"
|
||||
[ "$LICENSE" ] && echo "$LICENSE" > "$db/LICENSE"
|
||||
[ "$WWW" ] && echo "$WWW" > "$db/WWW"
|
||||
|
||||
[ "$PRE_INSTALL" ] && cp -a "$PRE_INSTALL" "$db/pre-install"
|
||||
[ "$POST_INSTALL" ] && cp -a "$POST_INSTALL" "$db/post-install"
|
||||
[ "$DSCRIPT" ] && cp -a "$DSCRIPT" "$db/pre-deinstall"
|
||||
[ "$POST_DEINSTALL" ] && cp -a "$POST_DEINSTALL" "$db/post-deinstall"
|
||||
[ "$PRE_UPDATE" ] && cp -a "$PRE_UPDATE" "$db/pre-update"
|
||||
[ "$POST_UPDATE" ] && cp -a "$POST_UPDATE" "$db/post-update"
|
||||
[ "$OWNERS" ] && cp -a "$OWNERS" "$db/OWNERS"
|
||||
|
||||
# check if var/db/apk contains more than it should
|
||||
[ `ls "$dbdir" | wc -l` -gt 1 ] && die "$APK_DBDIR should only contain the directory $PV."
|
||||
|
||||
# check if arch, desc, license and www info is there
|
||||
[ -f "$db/ARCH" ] || die "Architecture not set. Use -a."
|
||||
[ -f "$db/DESC" ] || die "Description not set. Use -c."
|
||||
[ -f "$db/LICENSE" ] || die "License not set. Use -l."
|
||||
[ -f "$db/WWW" ] || eecho "Warning: Homepage not set (use -w)."
|
||||
|
||||
# now, lets create the package
|
||||
cd "$tmp"
|
||||
tar --owner=root --group=root $VERBOSE -zcf "$PKGVF" *
|
||||
|
||||
# cleanup
|
||||
rm -rf "$tmp"
|
|
@ -0,0 +1,275 @@
|
|||
#!/bin/sh
|
||||
|
||||
# libutil.sh - Utility functions
|
||||
#
|
||||
# Copyright(c) 2005 Natanael Copa
|
||||
#
|
||||
# Distributed under GPL-2
|
||||
#
|
||||
|
||||
VERSION=0.13.1
|
||||
|
||||
# echo to stderr
|
||||
eecho() {
|
||||
echo $* >&2
|
||||
}
|
||||
|
||||
# echo to stderr and die
|
||||
die() {
|
||||
echo -n "$PROGRAM: " >&2
|
||||
eecho $*
|
||||
exit 1
|
||||
}
|
||||
|
||||
die_unless_force() {
|
||||
echo "$PROGRAM: $*" >&2
|
||||
[ -z "$FORCE" ] && exit 1
|
||||
}
|
||||
|
||||
# remove double / and ./ in pathnames
|
||||
beautify_path() {
|
||||
echo "$1" | sed 's:/^[^\.]\./::g; s:/\{2,\}:/:g; s:/\./:/:g'
|
||||
}
|
||||
|
||||
# check if parameter is an uri or not
|
||||
is_uri() {
|
||||
echo "$1" | grep "^[a-z][a-z0-9+]*:/" >/dev/null
|
||||
}
|
||||
|
||||
# check if parameter is an apk package (contains a / or .apk at the end)
|
||||
is_apk() {
|
||||
#echo "$1" | grep '/' >/dev/null && return 0
|
||||
[ -z "${1%%*/*}" ] && return 0
|
||||
|
||||
#echo "$1" | grep ".apk$" >/dev/null
|
||||
[ -z "${1%%*.apk}" ]
|
||||
}
|
||||
|
||||
# check if path start with a '/'
|
||||
is_absolute_path() {
|
||||
test -z "${1##/*}"
|
||||
}
|
||||
|
||||
# if path dont start with '/' then append $PWD
|
||||
get_absolute_path() {
|
||||
if is_absolute_path "$1" ; then
|
||||
echo "$1"
|
||||
else
|
||||
beautify_path "$PWD/$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# check if parameter has version number (i.e. if it is an pkgv or pkg)
|
||||
has_version() {
|
||||
echo "$1" | grep -- '-[0-9].*' >/dev/null
|
||||
}
|
||||
|
||||
# check if parameter has some kind of wildcard
|
||||
has_wildcard() {
|
||||
echo "$1" | grep "[\*\?\[]" >/dev/null
|
||||
}
|
||||
|
||||
# get the scheme for an uri (echo everything before the first ':')
|
||||
get_uri_scheme() {
|
||||
echo "$1" | cut -d : -f 1
|
||||
}
|
||||
|
||||
# remove version number from package name
|
||||
rm_ver() {
|
||||
echo "$1" | sed 's/\(.*\)-[0-9].*/\1/'
|
||||
}
|
||||
|
||||
# get version number from package name or file
|
||||
get_ver() {
|
||||
basename "$1" .apk | sed 's/.*-\([0-9].*\)/\1/'
|
||||
}
|
||||
|
||||
# initialize a temp directory
|
||||
# $1 contains the variable name for the directory
|
||||
# the directory will automatically be deleted upon exit
|
||||
init_tmpdir() {
|
||||
local omask=`umask`
|
||||
local __tmpd="$APK_TMPDIR/$PROGRAM-${$}-`date +%s`"
|
||||
umask 077 || die "umask"
|
||||
mkdir "$__tmpd" || exit 1
|
||||
trap "rm -fr \"$__tmpd\"; exit" 0
|
||||
umask $omask
|
||||
eval "$1=\"$__tmpd\""
|
||||
}
|
||||
|
||||
# remove files and empty dirs in specified list.
|
||||
# also remove APK_LBUFILES from default.tdb
|
||||
# environment:
|
||||
# ROOT: all files are relative this path
|
||||
# VERBOSE: echo filenames to stdout
|
||||
# DRYRUN: don't delete anything, just simulate
|
||||
my_rm() {
|
||||
rm "$1" 2>/dev/null || busybox rm "$1"
|
||||
}
|
||||
|
||||
list_uninstall() {
|
||||
local f p
|
||||
local root=${ROOT:-"/"}
|
||||
sort -r "$1" | while read f ; do
|
||||
p="`beautify_path \"$root/$f\"`"
|
||||
if [ "$DRYRUN" ] ; then
|
||||
[ "$VERBOSE" ] && echo "$p"
|
||||
else
|
||||
if [ -d "$p" ] ; then
|
||||
# try to remove dir, but ignore errors. It might
|
||||
if rmdir "$p" 2>/dev/null ; then
|
||||
[ "$VERBOSE" ] && echo "$p"
|
||||
[ "$2" ] && echo "$f" >> "$2"
|
||||
fi
|
||||
else
|
||||
my_rm "$p" && [ "$VERBOSE" ] && echo "$p"
|
||||
[ "$2" ] && echo "$f" >> "$2"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# list all lines that occur in first list but not second
|
||||
# the files cannot contain duplicate lines.
|
||||
list_subtract() {
|
||||
(
|
||||
# first we find all uniq lines
|
||||
cat "$1" "$2" | sort | uniq -u
|
||||
|
||||
# then we combine uniq lines with first file ...
|
||||
cat "$1"
|
||||
|
||||
# ...and find all duplicates. Those only exist in first file
|
||||
) | sort | uniq -d
|
||||
}
|
||||
|
||||
# insert an element first in APK_PATH if its not already there
|
||||
insert_apk_path() {
|
||||
if [ "$1" != "`echo "$APK_PATH" | cut -d\; -f1`" ] ; then
|
||||
[ "$APK_PATH" ] && APK_PATH=";$APK_PATH"
|
||||
APK_PATH="$1$APK_PATH"
|
||||
fi
|
||||
}
|
||||
|
||||
lbu_filter() {
|
||||
# Ok... I give up. shell is too slow. lets do it in awk.
|
||||
awk 'BEGIN {
|
||||
APK_LBUDIRS="'"$APK_LBUDIRS"'";
|
||||
numdirs = split(APK_LBUDIRS, lbudir, ":");
|
||||
#precalc lengths to save a few cpu cycles in loop
|
||||
for (i = 1; i <= numdirs; i++)
|
||||
len[i] = length(lbudir[i]);
|
||||
}
|
||||
|
||||
# main loop
|
||||
{
|
||||
for (i = 1; i <= numdirs; i++) {
|
||||
if (index($0, lbudir[i]) == 1 && (len[i] == length() || substr($0, len[i] + 1, 1) == "/")) {
|
||||
print $0;
|
||||
}
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
is_lbu_file() {
|
||||
# just run test
|
||||
[ "$(echo "$1" | lbu_filter)" ]
|
||||
}
|
||||
|
||||
# assign a value to a global var, either from environment or
|
||||
# from configuraion file
|
||||
# usage: get_var VARIBALE_NAME DEFAULT_VALUE
|
||||
get_var() {
|
||||
local var
|
||||
# first we check if the envvar is set
|
||||
eval "var=\$$1"
|
||||
if [ "$var" ] ; then
|
||||
echo "$var"
|
||||
elif [ -f ${APKTOOLS_CONF:="$ROOT/etc/apk.conf"} ] ; then
|
||||
# then we check the conf file
|
||||
var=`awk -F = '/^'$1'=/ { print $2 }' "$APKTOOLS_CONF"`
|
||||
if [ "$var" ] ; then
|
||||
echo "$var"
|
||||
else
|
||||
# else we use the default
|
||||
echo "$2"
|
||||
fi
|
||||
else
|
||||
# no conf file found use default
|
||||
echo "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
##########################################################
|
||||
# last_pkgf
|
||||
# find the latest package in a list, return 1 if not found
|
||||
last_pkgf() {
|
||||
local pkgf last status
|
||||
while read pkgf ; do
|
||||
apk_version -q -t "$pkgf" "$last"
|
||||
[ $? -eq 2 ] && last="$pkgf"
|
||||
done
|
||||
[ -z "$last" ] && return 1
|
||||
echo "$last"
|
||||
}
|
||||
|
||||
###########################################################
|
||||
# dump global variables
|
||||
dump_env() {
|
||||
echo "ROOT=$ROOT"
|
||||
echo "APKTOOLS_CONF=$APKTOOLS_CONF"
|
||||
echo "APK_PATH=$APK_PATH"
|
||||
echo "APK_DBDIR=$APK_DBDIR"
|
||||
echo "APK_TMPDIR=$APK_TMPDIR"
|
||||
echo "APK_FETCH=$APK_FETCH"
|
||||
echo "APK_DATA=$APK_DATA"
|
||||
echo "APK_DATALEVEL=$APK_DATALEVEL"
|
||||
echo "APK_LIBS=$APK_LIBS"
|
||||
echo "PACKAGES=$PACKAGES"
|
||||
|
||||
echo "APKDB=$APKDB"
|
||||
echo "APK_NOCOMPRESS=$APK_NOCOMPRESS"
|
||||
echo "REP_DIR=$REP_DIR"
|
||||
echo "REP_SCHEME=$REP_SCHEME"
|
||||
echo "CACHED_INDEX=$CACHED_INDEX"
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# init_globals sets up the global variables
|
||||
|
||||
APK_PREFIX_IN_PKG="`get_var APK_PREFIX_IN_PKG ''`"
|
||||
|
||||
ROOT="`get_var ROOT /`"
|
||||
echo "$ROOT" | grep -v "^/" > /dev/null && ROOT="$PWD/$ROOT"
|
||||
|
||||
APKTOOLS_CONF="`get_var APKTOOLS_CONF \"$(beautify_path /etc/apk/apk.conf)\"`"
|
||||
APK_PATH=`get_var APK_PATH ""`
|
||||
APK_DBDIR="`get_var APK_DBDIR \"$(beautify_path \"$ROOT/var/db/apk\")\"`"
|
||||
APK_DBDIR_IN_PKG="`get_var APK_DBDIR_IN_PKG ${APK_PREFIX_IN_PKG}var/db/apk`"
|
||||
APK_TMPDIR="`get_var \"APK_TMPDIR\" /tmp`"
|
||||
APK_ADD_TMP="`get_var \"APK_ADD_TMP\" \"$ROOT/usr/tmp\"`"
|
||||
APK_DATA="`get_var APK_DATA \"$(beautify_path \"$ROOT/var/lib/apk\")\"`"
|
||||
APK_KEEPCACHE="`get_var APK_KEEPCACHE no`"
|
||||
APK_LIBS="`get_var APK_LIBS /lib/apk`"
|
||||
PACKAGES="`get_var PACKAGES \"$(beautify_path \"$ROOT/var/cache/packages\")\"`"
|
||||
|
||||
APKDB="`beautify_path \"$APK_DBDIR\"`"
|
||||
APK_NOCOMPRESS=`get_var APK_NOCOMPRESS ""`
|
||||
|
||||
INDEX="INDEX.md5.gz"
|
||||
CACHED_INDEX="$APK_DATA/$INDEX"
|
||||
|
||||
APK_SUM=`get_var APK_SUM md5`
|
||||
APK_MKSUM=`get_var APK_MKSUM "${APK_SUM}sum"`
|
||||
APK_CHKSUM=`get_var APK_CHKSUM "${APK_SUM}sum -c"`
|
||||
|
||||
APK_DEFAULT_TDB=`get_var APK_DEFAULT_TDB "$APK_DATA/default.tdb"`
|
||||
SFIC=`which sfic 2>/dev/null`
|
||||
APK_GZSIGN_CERT=`get_var APK_GZSIGN_KEY /etc/apk/apk.crt`
|
||||
|
||||
# confdirs are a : spearate list of dirs relative $ROOT that are to be
|
||||
# considered for local backups.
|
||||
# for example: APK_LBUDIRS="etc:usr/local/etc"
|
||||
APK_LBUDIRS=`get_var APK_LBUDIRS 'etc'`
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -22,6 +23,7 @@
|
|||
const char *apk_root = "/";
|
||||
const char *apk_repository = NULL;
|
||||
int apk_quiet = 0;
|
||||
int apk_cwd_fd;
|
||||
|
||||
void apk_log(const char *prefix, const char *format, ...)
|
||||
{
|
||||
|
@ -78,6 +80,7 @@ int main(int argc, char **argv)
|
|||
int r;
|
||||
|
||||
umask(0);
|
||||
apk_cwd_fd = open(".", O_RDONLY);
|
||||
|
||||
prog = strrchr(argv[0], '/');
|
||||
if (prog == NULL)
|
||||
|
|
|
@ -44,9 +44,9 @@ typedef struct md5_ctx csum_ctx_t;
|
|||
#define csum_finish(ctx, buf) md5_finish(ctx, buf)
|
||||
#endif
|
||||
|
||||
extern int apk_quiet;
|
||||
extern int apk_cwd_fd, apk_quiet;
|
||||
|
||||
#define apk_error(args...) if (!apk_quiet) { apk_log("ERROR: ", args); }
|
||||
#define apk_error(args...) apk_log("ERROR: ", args);
|
||||
#define apk_warning(args...) if (!apk_quiet) { apk_log("WARNING: ", args); }
|
||||
#define apk_message(args...) if (!apk_quiet) { apk_log(NULL, args); }
|
||||
|
||||
|
@ -101,12 +101,18 @@ static inline int hlist_hashed(const struct hlist_node *n)
|
|||
static inline void __hlist_del(struct hlist_node *n, struct hlist_node **pprev)
|
||||
{
|
||||
*pprev = n->next;
|
||||
n->next = NULL;
|
||||
}
|
||||
|
||||
static inline void hlist_del(struct hlist_node *n, struct hlist_node **pprev)
|
||||
static inline void hlist_del(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
__hlist_del(n, pprev);
|
||||
n->next = LIST_POISON1;
|
||||
struct hlist_node **pp = &h->first;
|
||||
|
||||
while (*pp != NULL && *pp != LIST_END && *pp != n)
|
||||
pp = &(*pp)->next;
|
||||
|
||||
if (*pp == n)
|
||||
__hlist_del(n, pp);
|
||||
}
|
||||
|
||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||
|
@ -123,6 +129,16 @@ static inline void hlist_add_after(struct hlist_node *n, struct hlist_node **pre
|
|||
*prev = n;
|
||||
}
|
||||
|
||||
static inline struct hlist_node **hlist_tail_ptr(struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *n = h->first;
|
||||
if (n == NULL || n == LIST_END)
|
||||
return &h->first;
|
||||
while (n->next != NULL && n->next != LIST_END)
|
||||
n = n->next;
|
||||
return &n->next;
|
||||
}
|
||||
|
||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
||||
|
||||
#define hlist_for_each(pos, head) \
|
||||
|
|
|
@ -75,7 +75,7 @@ void apk_pkg_free(struct apk_package *pkg);
|
|||
int apk_pkg_get_state(struct apk_package *pkg);
|
||||
int apk_pkg_add_script(struct apk_package *pkg, int fd,
|
||||
unsigned int type, unsigned int size);
|
||||
int apk_pkg_run_script(struct apk_package *pkg, const char *root,
|
||||
int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
|
||||
unsigned int type);
|
||||
|
||||
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry);
|
||||
|
|
|
@ -183,10 +183,11 @@ static void apk_db_file_set_owner(struct apk_database *db,
|
|||
int create_dir,
|
||||
struct hlist_node **after)
|
||||
{
|
||||
if (file->owner != NULL)
|
||||
return;
|
||||
|
||||
if (file->owner != NULL) {
|
||||
hlist_del(&file->pkg_files_list, &file->owner->owned_files);
|
||||
} else {
|
||||
db->installed.stats.files++;
|
||||
}
|
||||
file->dir = apk_db_dir_ref(db, file->dir, create_dir);
|
||||
file->owner = owner;
|
||||
hlist_add_after(&file->pkg_files_list, after);
|
||||
|
@ -215,7 +216,7 @@ static struct apk_db_file *apk_db_file_get(struct apk_database *db,
|
|||
dir = apk_db_dir_get(db, bdir);
|
||||
if (ctx != NULL && dir != ctx->dircache) {
|
||||
ctx->dircache = dir;
|
||||
ctx->file_dir_node = &dir->files.first;
|
||||
ctx->file_dir_node = hlist_tail_ptr(&dir->files);
|
||||
}
|
||||
|
||||
hlist_for_each_entry(file, cur, &dir->files, dir_files_list) {
|
||||
|
@ -274,7 +275,7 @@ static int apk_db_read_fdb(struct apk_database *db, int fd)
|
|||
}
|
||||
dir = NULL;
|
||||
file_dir_node = NULL;
|
||||
file_pkg_node = &pkg->owned_files.first;
|
||||
file_pkg_node = hlist_tail_ptr(&pkg->owned_files);
|
||||
break;
|
||||
case 'D':
|
||||
if (pkg == NULL) {
|
||||
|
@ -282,7 +283,7 @@ static int apk_db_read_fdb(struct apk_database *db, int fd)
|
|||
return -1;
|
||||
}
|
||||
dir = apk_db_dir_get(db, l);
|
||||
file_dir_node = &dir->files.first;
|
||||
file_dir_node = hlist_tail_ptr(&dir->files);
|
||||
break;
|
||||
case 'F':
|
||||
if (dir == NULL) {
|
||||
|
@ -388,29 +389,23 @@ static int apk_db_read_scriptdb(struct apk_database *db, int fd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char *get_db_path(const char *root, const char *f)
|
||||
{
|
||||
static char fn[1024];
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/%s", root, f);
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
int apk_db_create(const char *root)
|
||||
{
|
||||
apk_blob_t deps = APK_BLOB_STR("busybox, alpine-baselayout, "
|
||||
"apk-tools, alpine-conf");
|
||||
"apk-tools, alpine-conf\n");
|
||||
int fd;
|
||||
|
||||
mkdir(get_db_path(root, "tmp"), 01777);
|
||||
mkdir(get_db_path(root, "dev"), 0755);
|
||||
mknod(get_db_path(root, "dev/null"), 0666, makedev(1, 3));
|
||||
mkdir(get_db_path(root, "var"), 0755);
|
||||
mkdir(get_db_path(root, "var/lib"), 0755);
|
||||
mkdir(get_db_path(root, "var/lib/apk"), 0755);
|
||||
fchdir(apk_cwd_fd);
|
||||
chdir(root);
|
||||
|
||||
fd = creat(get_db_path(root, "var/lib/apk/world"), 0600);
|
||||
mkdir("tmp", 01777);
|
||||
mkdir("dev", 0755);
|
||||
mknod("dev/null", 0666, makedev(1, 3));
|
||||
mkdir("var", 0755);
|
||||
mkdir("var/lib", 0755);
|
||||
mkdir("var/lib/apk", 0755);
|
||||
|
||||
fd = creat("var/lib/apk/world", 0600);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
write(fd, deps.ptr, deps.len);
|
||||
|
@ -436,7 +431,9 @@ static int apk_db_read_config(struct apk_database *db)
|
|||
* 5. files db
|
||||
* 6. script db
|
||||
*/
|
||||
fd = open(get_db_path(db->root, "var/lib/apk/world"), O_RDONLY);
|
||||
fchdir(db->root_fd);
|
||||
|
||||
fd = open("var/lib/apk/world", O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -447,13 +444,13 @@ static int apk_db_read_config(struct apk_database *db)
|
|||
APK_BLOB_PTR_LEN(buf, st.st_size));
|
||||
close(fd);
|
||||
|
||||
fd = open(get_db_path(db->root, "var/lib/apk/files"), O_RDONLY);
|
||||
fd = open("var/lib/apk/files", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
apk_db_read_fdb(db, fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
fd = open(get_db_path(db->root, "var/lib/apk/scripts"), O_RDONLY);
|
||||
fd = open("var/lib/apk/scripts", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
apk_db_read_scriptdb(db, fd);
|
||||
close(fd);
|
||||
|
@ -496,20 +493,22 @@ static int apk_db_write_config(struct apk_database *db)
|
|||
if (db->root == NULL)
|
||||
return 0;
|
||||
|
||||
fd = creat(get_db_path(db->root, "var/lib/apk/world"), 0600);
|
||||
fchdir(db->root_fd);
|
||||
|
||||
fd = creat("var/lib/apk/world", 0600);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
n = apk_deps_format(buf, sizeof(buf), db->world);
|
||||
write(fd, buf, n);
|
||||
close(fd);
|
||||
|
||||
fd = creat(get_db_path(db->root, "var/lib/apk/files"), 0600);
|
||||
fd = creat("var/lib/apk/files", 0600);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
apk_db_write_fdb(db, fd);
|
||||
close(fd);
|
||||
|
||||
fd = creat(get_db_path(db->root, "var/lib/apk/scripts"), 0600);
|
||||
fd = creat("var/lib/apk/scripts", 0600);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
apk_db_write_scriptdb(db, fd);
|
||||
|
@ -690,7 +689,7 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae,
|
|||
type, ae->size);
|
||||
|
||||
if (type == ctx->script) {
|
||||
r = apk_pkg_run_script(pkg, db->root, type);
|
||||
r = apk_pkg_run_script(pkg, db->root_fd, type);
|
||||
if (r != 0)
|
||||
apk_error("%s-%s: Failed to execute pre-install/upgrade script",
|
||||
pkg->name->name, pkg->version);
|
||||
|
@ -700,7 +699,7 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae,
|
|||
}
|
||||
|
||||
if (ctx->file_pkg_node == NULL)
|
||||
ctx->file_pkg_node = &pkg->owned_files.first;
|
||||
ctx->file_pkg_node = hlist_tail_ptr(&pkg->owned_files);
|
||||
|
||||
if (!S_ISDIR(ae->mode)) {
|
||||
file = apk_db_file_get(db, name, ctx);
|
||||
|
@ -708,7 +707,8 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae,
|
|||
return -1;
|
||||
|
||||
if (file->owner != NULL &&
|
||||
file->owner->name != pkg->name) {
|
||||
file->owner->name != pkg->name &&
|
||||
strcmp(file->owner->name->name, "busybox") != 0) {
|
||||
apk_error("%s: Trying to overwrite %s owned by %s.\n",
|
||||
pkg->name->name, ae->name,
|
||||
file->owner->name->name);
|
||||
|
@ -749,7 +749,7 @@ static void apk_db_purge_pkg(struct apk_database *db,
|
|||
unlink(fn);
|
||||
|
||||
apk_db_dir_unref(db, file->dir);
|
||||
hlist_del(c, &pkg->owned_files.first);
|
||||
__hlist_del(c, &pkg->owned_files.first);
|
||||
|
||||
db->installed.stats.files--;
|
||||
}
|
||||
|
@ -772,14 +772,14 @@ int apk_db_install_pkg(struct apk_database *db,
|
|||
/* Purge the old package if there */
|
||||
if (oldpkg != NULL) {
|
||||
if (newpkg == NULL) {
|
||||
r = apk_pkg_run_script(oldpkg, db->root,
|
||||
r = apk_pkg_run_script(oldpkg, db->root_fd,
|
||||
APK_SCRIPT_PRE_DEINSTALL);
|
||||
if (r != 0)
|
||||
return r;
|
||||
}
|
||||
apk_db_purge_pkg(db, oldpkg);
|
||||
if (newpkg == NULL) {
|
||||
apk_pkg_run_script(oldpkg, db->root,
|
||||
apk_pkg_run_script(oldpkg, db->root_fd,
|
||||
APK_SCRIPT_POST_DEINSTALL);
|
||||
return 0;
|
||||
}
|
||||
|
@ -820,7 +820,7 @@ int apk_db_install_pkg(struct apk_database *db,
|
|||
apk_warning("%s-%s: checksum does not match",
|
||||
newpkg->name->name, newpkg->version);
|
||||
|
||||
r = apk_pkg_run_script(newpkg, db->root,
|
||||
r = apk_pkg_run_script(newpkg, db->root_fd,
|
||||
(oldpkg == NULL) ?
|
||||
APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE);
|
||||
if (r != 0) {
|
||||
|
|
|
@ -320,15 +320,20 @@ int apk_pkg_add_script(struct apk_package *pkg, int fd,
|
|||
return r;
|
||||
}
|
||||
|
||||
int apk_pkg_run_script(struct apk_package *pkg, const char *root,
|
||||
int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
|
||||
unsigned int type)
|
||||
{
|
||||
static const char * const environment[] = {
|
||||
"PATH=/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
NULL
|
||||
};
|
||||
struct apk_script *script;
|
||||
struct hlist_node *c;
|
||||
int fd, status;
|
||||
pid_t pid;
|
||||
char fn[1024];
|
||||
|
||||
fchdir(root_fd);
|
||||
hlist_for_each_entry(script, c, &pkg->scripts, script_list) {
|
||||
if (script->type != type)
|
||||
continue;
|
||||
|
@ -349,14 +354,13 @@ int apk_pkg_run_script(struct apk_package *pkg, const char *root,
|
|||
if (pid == -1)
|
||||
return -1;
|
||||
if (pid == 0) {
|
||||
chroot(root);
|
||||
fn[2] = '.';
|
||||
execl(&fn[2], script_types[script->type],
|
||||
pkg->version, "", NULL);
|
||||
chroot(".");
|
||||
execle(fn, script_types[script->type],
|
||||
pkg->version, "", NULL, environment);
|
||||
exit(1);
|
||||
}
|
||||
waitpid(pid, &status, 0);
|
||||
unlink(fn);
|
||||
//unlink(fn);
|
||||
if (WIFEXITED(status))
|
||||
return WEXITSTATUS(status);
|
||||
return -1;
|
||||
|
|
Loading…
Reference in New Issue