#!/bin/bash
# Copyright (C) 2007-2010 Matias A. Fonzo, Santiago del Estero, AR
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Localización % Idioma:
TEXTDOMAINDIR=/usr/share/locale
TEXTDOMAIN=add
VERSION=3.3
# Funciones #
# Una función para mostrar mensajes normales:
msg() { local LC_ALL ; printf '%s\n' "$@"; }
# Una función para mensajes de advertencia:
warn() { local LC_ALL; printf '%b\n' "$@" >&2; }
usage() {
msg $"Installs one or more packages in your system." \
"" \
$"Usage: add [options] package_name.tlz ..." \
"" \
$"Options:" \
$" -h, --help Show this help and exit." \
$" -v, --version Show the version of the program." \
$" -f, --force Overwrite installed package." \
$" -w, --warn Warn about of the files and" \
$" directories that will be" \
$" installed or overwritten." \
""
}
version() {
msg "add $VERSION" \
"Copyright (C) 2007-2010 Matias A. Fonzo ." \
"License GPLv3+: GNU GPL version 3 or later:" \
"" \
"This is free software: you are free to change and redistribute it." \
"There is NO WARRANTY, to the extent permitted by law."
}
# Opciones:
while (( $# )); do
case "$1" in
-f|--force)
OPT=FORCE
shift
;;
-w|--warn)
OPT=WARN
shift
;;
-[h?]|--help)
usage
exit 0
;;
-[vV]|--version)
version
exit 0
;;
-*)
warn $"${0##*/}: Invalid option: $1"
exit 1
;;
*)
break;
esac
done
# Si no hay argumentos, llama a la función de ayuda:
(( $# == 0 )) && { usage ; exit 0; }
# Sale ante cualquier error:
set -e
# Advierte acerca de los directorios y archivos del
# paquete que serán instalados o sobreescritos:
if [[ $OPT = WARN ]]; then
while [[ -f $1 ]]; do
msg "" $"% Scanning $1 ..." ""
LC_ALL=C tar --use-compress-program=lzip -tvvf "$1" | awk '!/^drwx/'
msg ""
shift
done
exit 0;
fi
# Comprobamos la variable de entorno ROOT:
if [[ -n $ROOT && ! -d $ROOT ]]; then
warn $"${0##*/}: ROOT=${ROOT}: Invalid directory"
exit 1;
fi
umask 022
# Base de datos por defecto:
DB="${ROOT}/var/db"
# Nos aseguramos de que la parte de la base de datos exista:
for directory in \
pkg/pre-post \
pkg/post-install \
pkg/description
do
if [[ ! -d ${DB}/$directory ]]; then
mkdir -p "${DB}/$directory"
fi
done
# Más funciones #
# Una función para reflejar el nombre base:
_basename() { local name ; name=${1##*/} ; printf "${name%$2}"; }
# Una función que ejecuta los scripts de pre y post instalación:
exe_install() {
local fileName
fileName="$1"
if [[ -r ${ROOT}/install/$fileName ]]; then
msg $"| $fileName execution for $pkgname ..."
( cd $ROOT/
sh install/$fileName
install -m 0755 install/$fileName \
-D ${DB}/pkg/${fileName}/$pkgname && \
rm -f install/$fileName
)
fi
}
# Guardamos y exportamos la variable de entorno LC_ALL
# para que algunos comandos corran más rápido:
DLANG=$LANG
export LC_ALL=C
# Loop:
for package in "$@" ; do
if [[ -f $package ]]; then
pkgname=$(_basename $package .tlz)
# Comprueba la extensión del paquete:
if [[ ${package##*/} != ${pkgname}.tlz ]]; then
warn "${package}: Does not end in .tlz"
CODE=1
continue;
fi
# Si el paquete no está en la base de datos, lo instalamos:
if [[ ! -r ${DB}/pkg/$pkgname || $OPT = FORCE ]]; then
msg "" $"> Installing $pkgname ..." ""
# Chequea la integridad del paquete:
msg $"% Testing integrity ..." ""
tar --use-compress-program=lzip -tf $package > /dev/null
# Descomprime el tarball:
( cd $ROOT/
tar --use-compress-program=lzip -xvphlf -
) < $package > ${DB}/pkg/$pkgname
CODE=$?
if (( $CODE != 0 )); then
rm -f ${DB}/pkg/$pkgname
break;
fi
sed -i 's/^.\///;/^$/d' ${DB}/pkg/$pkgname # Limpia el registro.
else
warn $"${DB}/pkg/${pkgname}: Already installed"
CODE=3
continue;
fi
# Muestra la descripción en el lenguaje disponible, de acuerdo a la
# "locale" usada por el sistema, y a la variable de entorno $LANG:
if [[ -f ${ROOT}/description/${DLANG%_*} ]]; then
case "$DLANG" in
*.UTF-8*|*.utf8)
DISPLAYTOOL="fmt <(iconv --from-code=ISO8859-1 --to-code=UTF-8)"
DLANG=${DLANG%_*}
;;
??_??|*.ISO8859-1|*.iso88591|*.ISO-8859-1)
DISPLAYTOOL=fmt
DLANG=${DLANG%_*}
;;
*)
DISPLAYTOOL=fmt
DLANG=en;
esac
# Imprime el archivo de descripción:
( cd ${ROOT}/description
$DISPLAYTOOL $DLANG || exit 1;
# Movemos los archivos a la base de datos:
for file in *
do mv $file ${DB}/pkg/description/${pkgname}-$file
done
)
fi
# Ejecuta el script de pre-post instalación:
exe_install "pre-post"
# Ejecuta el script de post-instalación:
exe_install "post-install"
# Remueve los directorios de descripción e instalación:
rmdir ${ROOT}/{description,install} > /dev/null 2>&1 || true;
else
warn $"${0##*/}: ${package}: File not found or non-regular"
CODE=1
continue;
fi
done
exit $CODE