#!/bin/bash # Copyright (C) 2007-2011 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.5 # 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-2011 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 # Chequeo de sanidad. # # Comprueba si el sistema de archivos # se encuentra en modo de sólo-lectura: if ! touch ${ROOT}/pkg-add$$ ; then warn $"The filesystem (on $ROOT) is in read-only mode." exit 1; fi rm -f ${ROOT}/pkg-add$$ # Base de datos por defecto: DB="${ROOT}/var/db" # Nos aseguramos de que las partes 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 # Comprueba la extensión del paquete: case "$package" in *.tlz) pkgname=$(_basename $package .tlz) ;; *) warn "${package}: Does not end in .tlz" CODE=1 continue; esac else warn $"${0##*/}: ${package}: File not found or non-regular" 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 \ --strip-components=1 --show-stored-names \ -xvphlf - ) < $package > ${DB}/pkg/$pkgname CODE=$? if (( $CODE != 0 )); then rm -f ${DB}/pkg/$pkgname break; fi 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: case "$DLANG" in *.UTF-8*|*.utf8) DLANG=${DLANG%_*} UTF8_OUTPUT=y ;; ??_??|*.ISO8859-1|*.iso88591|*.ISO-8859-1) DLANG=${DLANG%_*} ;; *) DLANG=en; esac # Imprime el archivo de descripción: if [[ -f ${ROOT}/description/${DLANG} ]]; then ( cd ${ROOT}/description if [[ $UTF8_OUTPUT ]]; then fmt <(iconv --from-code=ISO8859-1 --to-code=UTF-8 $DLANG) else fmt $DLANG fi # 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 || : done exit $CODE