nutools/legacy/sysinc/system_caps

440 lines
16 KiB
Bash

# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
##@require base
# system_caps: Déterminer les capacités du syteme sur lequel nous tournons. Ces
# scripts sont prévus pour adapter un système non Linux pour qu'il fonctionne a
# peu près comme Linux. Les fonctions de base qui doivent être adaptées le sont
# en fonction du système sur lequel on tourne. Il suffit d'inclure ce fichier
# pour bénéficier des nouvelles fonctionnalités
# note: sous Linux, ces scripts sont essentiellement un no-op
__SYSTEM_CAPS_COMPUTED__=
if [ -z "$__MAKE_SYSTEM_CAPS__" -a -z "$__FORCE_COMPUTE_SYSTEM_CAPS__" -a -f "@@dest@@/legacy/system_caps" ]; then
source "@@dest@@/legacy/system_caps"
fi
unset __FORCE_COMPUTE_SYSTEM_CAPS__
if [ -z "$__SYSTEM_CAPS_COMPUTED__" ]; then
if [ -n "$__MAKE_SYSTEM_CAPS__" ]; then
>"$__MAKE_SYSTEM_CAPS__"
fi
function __define_and_eval__() {
if [ -n "$__MAKE_SYSTEM_CAPS__" ]; then
echo "$1" >>"$__MAKE_SYSTEM_CAPS__"
fi
eval "$1"
}
function __verify_system__() {
# Vérifier que le système est supporté
local OENC="$UTF8"
local system
for system in Linux SunOS Darwin Cygwin Mingw unsupported; do
[ "$system" = "$SYSTEM_NAME" ] && break
[ "$system" = "unsupported" ] && die "$SYSTEM_NAME: Système non supporté"
done
}
__verify_system__; unset -f __verify_system__
function __get_which_caps__() {
[ "$SYSTEM_NAME" = "Linux" ] && return
# Obtenir les capacités de which: certaines implémentations affichent "no x
# in ..." sur stdout au lieu de l'afficher sur stderr
local OENC="$UTF8"
local tmpout="$TMPDIR/which_test.$$.out"
local tmperr="$TMPDIR/which_test.$$.err"
which __une_appli_qui_existe_pas__ >"$tmpout" 2>"$tmperr"
if [ -s "$tmpout" ]; then
__legacy_which__=1 # legacy
elif [ -s "$tmperr" ]; then
: # cas normal
else
__legacy_which__=2 # MacOSX 10.5
fi
/bin/rm -f "$tmpout"
/bin/rm -f "$tmperr"
if [ "$__legacy_which__" == 1 ]; then
local grep="${grep:-`which grep 2>&1`}"
if [ -x "$grep" ]; then
__define_and_eval__ 'function progexists() { test -n "$1" -a -z "$(which "$1" 2>&1 | '"$grep"' "^no $1")"; }'
else
die "grep est requis pour l'implémentation de progexists() sur ce système"
fi
elif [ "$__legacy_which__" == 2 ]; then
__define_and_eval__ 'function progexists() { which "$1" >&/dev/null; }'
fi
}
__get_which_caps__; unset -f __get_which_caps__
function __set_prog_func__() {
# Tester la présence d'un programme sur le système en cours, et si
# le programme doit être accedé avec un chemin absolu, créer une
# fonction du nom de ce programme qui pourra être utilisée pour
# appeler ce programme.
# $1 == nom de la fonction a créer. Il s'agit géneralement du nom du
# programme, mais ce n'est pas une obligation.
# $2 == nom à afficher si le programme n'est pas trouvé. Le message
# affiché sera de la forme "Ce script requière $2....". Si cette
# valeur est non vide, le programme *doit exister* sinon le script
# se termine. Si la valeur est "-", alors il s'agit de $1.
# $3..$n == chemins dans lesquels il faut chercher le programme. Si
# la valeur est "-", on teste si le programme est disponible dans le
# path.
local OENC="$UTF8"
local prog="$1"; shift
local req="$1"; shift
if [ -z "$prog" ]; then
die "USAGE: __set_prog_func__ prog_func req? path [paths...]"
fi
if [ -n "${!prog}" ]; then
# Si une variable de ce nom est deja definie, on assume qu'il
# s'agit du chemin vers le programme
__define_and_eval__ 'function '"$prog"'() { '"${!prog}"' "$@"; }'
return 0
fi
local found=
while [ -n "$1" ]; do
local path="$1"; shift
if [ "$path" = "--legacy" ]; then
# Declarer que les programmes qui suivent sont "legacy"
__define_and_eval__ 'export __legacy_'"$prog"'__=1'
continue
fi
if [ "${path#/}" = "$path" ] && progexists "$path"; then
# Si on donne un nom de programme, et que ce programme se
# trouve dans le path, l'adopter avec son chemin absolu
if [ "$path" != "$prog" ]; then
path="$(type -p "$path")"
__define_and_eval__ 'function '"$prog"'() { "'"$path"'" "$@"; }'
fi
found=1
break
fi
if [ "$path" = "-" ] && progexists "$prog"; then
# pas la peine de creer une fonction, la commande existe
# deja avec ce nom-la dans le path
found=1
break
fi
if [ -d "$path" ]; then path="$path/$prog"; fi
if [ -d "$path" ]; then continue; fi
if [ -x "$path" ]; then
__define_and_eval__ 'function '"$prog"'() { "'"$path"'" "$@"; }'
found=1
break
fi
done
if [ -z "$found" -a -n "$req" ]; then
if [ "$req" = "-" ]; then req="$prog"; fi
die "Ce script requière $req
Si ce programme est installé, faites
export $prog=/path/to/$prog
et relancez ce script"
fi
test -n "$found"
}
function __get_tools_path_and_caps__() {
[ "$SYSTEM_NAME" = "Linux" ] && return
# Obtenir l'emplacement d'outils standards, tels que:
# cp, awk, grep, diff, tar, ps, date
local system
# cp
for system in SunOS Darwin; do
[ "$SYSTEM_NAME" = "$system" ] && __define_and_eval__ 'export __legacy_cp__=1'
done
[ -n "$__legacy_cp__" ] && __define_and_eval__ 'function cp_a() { /bin/cp -pR "$@"; }'
# awk
if [ "$SYSTEM_NAME" = "SunOS" ]; then
__set_prog_func__ awk "gawk or nawk" \
gawk \
/usr/sfw/bin/gawk \
/opt/sfw/bin/gawk \
--legacy nawk \
/usr/bin/nawk
elif [ "$SYSTEM_NAME" = "Darwin" ]; then
# note: gensub() n'est supporté que sur gnuawk
# si __legacy_awk__ est défini, on sait que cette fonction n'est pas
# disponible
__set_prog_func__ awk "gawk or nawk" \
gawk \
/sw/bin/gawk \
/sw/bin/awk \
--legacy /usr/bin/awk
fi
# grep
if [ "$SYSTEM_NAME" = "SunOS" ]; then
__set_prog_func__ grep - \
ggrep \
/usr/sfw/bin/ggrep \
/opt/sfw/bin/ggrep \
--legacy /usr/bin/grep
fi
if [ -n "$__legacy_grep__" ]; then
__define_and_eval__ 'function quietgrep() { grep "$@" >&/dev/null; }'
fi
# diff
if [ "$SYSTEM_NAME" = "SunOS" ]; then
__set_prog_func__ diff - \
gdiff \
/usr/sfw/bin/gdiff \
/opt/sfw/bin/gdiff \
--legacy /usr/bin/diff
fi
if [ -n "$__legacy_diff__" ]; then
__define_and_eval__ 'function quietdiff() { diff "$@" >&/dev/null; }'
fi
# tar
if [ "$SYSTEM_NAME" = "SunOS" ]; then
__set_prog_func__ tar - \
gtar \
/usr/sfw/bin/gtar \
/opt/sfw/bin/gtar \
--legacy /usr/bin/tar
elif [ "$SYSTEM_NAME" = "Darwin" ]; then
__set_prog_func__ tar - \
gnutar gtar \
/sw/bin/gtar \
--legacy /usr/bin/tar
fi
# ps
if [ "$SYSTEM_NAME" = "SunOS" ]; then
__set_prog_func__ ps - \
/usr/ucb/ps \
--legacy /usr/bin/ps
__set_prog_func__ legacyps - \
/usr/bin/ps
__define_and_eval__ 'function is_running() { test -n "$(legacyps -o pid -p "$1" | grep -v PID)"; }'
fi
if [ -n "$__legacy_ps__" ]; then
__define_and_eval__ 'function ps_all() { ps -ef; }'
fi
# sleep
if [ "$SYSTEM_NAME" = "SunOS" -o "$SYSTEM_NAME" = "Darwin" ]; then
__define_and_eval__ 'function little_sleep() { n=1000; while [ $n -gt 0 ]; do n=$(($n - 1)); done; }'
fi
# date
if [ "$SYSTEM_NAME" = "SunOS" ]; then
__set_prog_func__ date - \
gdate \
/usr/sfw/bin/gdate \
/opt/sfw/bin/gdate \
--legacy /usr/bin/date
elif [ "$SYSTEM_NAME" = "Darwin" ]; then
__set_prog_func__ date - \
--legacy /bin/date
fi
# readlink
if ! progexists readlink; then
__define_and_eval__ 'function readlink() { if [ -L "$1" ]; then /bin/ls -ld "$1" | awk '"'"'{print $11'"'"'}; fi; }'
fi
# mktemp
if ! progexists mktemp; then
__define_and_eval__ 'function mktemp() { make_tempfile "$@"; }'
fi
# curl/wget (pour dumpurl)
if ! progexists curl; then
if [ "$SYSTEM_NAME" = "SunOS" ]; then
if __set_prog_func__ curl "" /usr/local/bin/curl; then
__define_and_eval__ 'export __curl_EXISTS__=1'
fi
fi
fi
if ! progexists wget; then
if [ "$SYSTEM_NAME" = "SunOS" ]; then
if __set_prog_func__ wget "" /usr/sfw/bin/wget /opt/sfw/bin/wget; then
__define_and_eval__ 'export __wget_EXISTS__=1'
fi
fi
fi
# is_root
if [ "$SYSTEM_NAME" = "SunOS" ]; then
__define_and_eval__ 'function is_root() { id | quietgrep "uid=0"; }'
elif [ "$SYSTEM_NAME" = "Cygwin" -o "$SYSTEM_NAME" = "Mingw" ]; then
# on assume que sur ces systèmes, l'utilisateur est maitre à bord.
__define_and_eval__ 'function is_root() { true; }'
fi
# sedi
if [ "$SYSTEM_NAME" = "Darwin" ]; then
__define_and_eval__ 'function __1sedi() {
local script="$1" input="$2"
if sed -i.bak "$script" "$input"; then
/bin/rm -f "$input.bak"
fi
}
function sedi() {
local script="$1" input
shift
for input in "$@"; do
__1sedi "$script" "$input"
done
}'
elif [ "$SYSTEM_NAME" = "SunOS" ]; then
__define_and_eval__ 'function __1sedi() {
local script="$1" input="$2"
if sed "$script" "$input" >"$input.out.$$"; then
chmod "$(/bin/ls -l "$input" | awk '\''function oct(mod) {
value = 0
if (substr(mod, 1, 1) == "r") value = value + 4
if (substr(mod, 2, 1) == "w") value = value + 2
if (substr(mod, 3, 1) == "x") value = value + 1
return value
}
{
print oct(substr($1, 2, 3)) oct(substr($1, 5, 3)) oct(substr($1, 8, 3))
}'\'')" "$input.out.$$"
/bin/mv -f "$input.out.$$" "$input"
fi
}
function sedi() {
local script="$1" input
shift
for input in "$@"; do
__1sedi "$script" "$input"
done
}'
fi
# parse_date
if [ "$SYSTEM_NAME" = "Darwin" ]; then
function __pd_isleap() {
# tester si l'année $1 est bissextile
[ $(($1 % 4)) -eq 0 -a \( $(($1 % 100)) -ne 0 -o $(($1 % 400)) -eq 0 \) ]
}
function __pd_fix_month() {
# soit $1 le nom d'une variable contenant une année, et $2 le nom d'une
# variable contenant un mois, normaliser les valeurs de ces variables, en
# ajustant si nécessaire les valeurs.
local __pdfm_y="${!1}" __pdfm_m="${!2}"
let __pdfm_m=$__pdfm_m-1
while [ $__pdfm_m -gt 11 ]; do
let __pdfm_m=$__pdfm_m-12
let __pdfm_y=$__pdfm_y+1
done
while [ $__pdfm_m -lt 0 ]; do
let __pdfm_m=$__pdfm_m+12
let __pdfm_y=$__pdfm_y-1
done
let __pdfm_m=$__pdfm_m+1
eval "$1=$__pdfm_y; $2=$__pdfm_m"
}
__PD_MONTHDAYS=(0 31 28 31 30 31 30 31 31 30 31 30 31)
function __pd_monthdays() {
# calculer le nombre de jours du mois $2 de l'année $1
local y="$1" m="$2" mds
__pd_fix_month y m
mds="${__PD_MONTHDAYS[$m]}"
[ "$m" -eq 2 ] && __pd_isleap "$y" && let mds=$mds+1
echo $mds
}
function __pd_fix_day() {
# soit $1 le nom d'une variable contenant une année, $2 le nom d'une
# variable contenant un mois et $3 le nom d'une variable contenant un jour,
# normaliser les valeurs de ces variables, en ajustant si nécessaire les
# valeurs. cette fonction assume que la valeur de $2 est déjà corrigée avec
# __pd_fix_month
local __pdfd_y="${!1}" __pdfd_m="${!2}" __pdfd_d="${!3}" __pdfd_mds
let __pdfd_d=$__pdfd_d-1
let __pdfd_mds=$(__pd_monthdays $__pdfd_y $__pdfd_m)
while [ $__pdfd_d -gt $(($__pdfd_mds-1)) ]; do
let __pdfd_d=$__pdfd_d-$__pdfd_mds
let __pdfd_m=$__pdfd_m+1
__pd_fix_month __pdfd_y __pdfd_m
let __pdfd_mds=$(__pd_monthdays $__pdfd_y $__pdfd_m)
done
while [ $__pdfd_d -lt 0 ]; do
let __pdfd_m=$__pdfd_m-1
__pd_fix_month __pdfd_y __pdfd_m
let __pdfd_d=$__pdfd_d-$(__pd_monthdays $__pdfd_y $__pdfd_m)
done
let __pdfd_d=$__pdfd_d+1
eval "$1=$__pdfd_y; $2=$__pdfd_m; $3=$__pdfd_d"
}
function __pd_fix_date() {
# soit $1 le nom d'une variable contenant une année, $2 le nom d'une
# variable contenant un mois et $3 le nom d'une variable contenant un jour,
# normaliser les valeurs de ces variables, en ajustant si nécessaire les
# valeurs.
local __pdf_y="${!1}" __pdf_m="${!2}" __pdf_d="${!3}"
}
function parse_date() {
local value="$1" type="${2:-date}"
local d m y
# date courante
eval "$(date +%d/%m/%Y | awk -F/ '{
print "d=" $1 "; m=" $2 "; y=" $3
}')"
if [ "${value#+}" != "$value" ]; then
# ajouter $1 jours
d="$(($d+${value#+}))"
else
# parser une nouvelle date, en complétant avec les informations de la
# date du jour
eval "$(<<<"$value" awk -F/ "BEGIN {
dn=$dn; mn=$mn; yn=$yn
}"'
{
d = $1 + 0; if (d < 1) d = dn + 0;
m = $2 + 0; if (m < 1) m = mn + 0;
if ($3 == "") y = yn + 0;
else { y = $3 + 0; if (y < 100) y = y + 2000; }
print "d=" d "; m=" m "; y=" y
}')"
fi
# ensuite corriger les champs si nécessaire
__pd_fix_month y m
__pd_fix_day y m d
# enfin formater la date selon les volontés de l'utilisateur
case "$type" in
d|date)
awk "BEGIN { d=$d; m=$m; y=$y; "'printf "%02i/%02i/%04i\n", d, m, y }'
;;
l|ldap)
awk "BEGIN { d=$d; m=$m; y=$y; "'printf "%04i%02i%02i000000+0400\n", y, m, d }'
;;
esac
}
fi
}
__get_tools_path_and_caps__
unset -f __set_prog_func__ __get_tools_path_and_caps__
__define_and_eval__ "__SYSTEM_CAPS_COMPUTED__=1"
unset -f __define_and_eval__
fi