440 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			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
 |