323 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			323 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
## Gestion du fichier crontab
 | 
						|
##@cooked nocomments
 | 
						|
##@require base
 | 
						|
uprovide crontab
 | 
						|
urequire base
 | 
						|
 | 
						|
# Ajouter la ligne $1 au crontab de l'utilisateur $2
 | 
						|
# Le code de retour est 123 si la ligne est déjà présente
 | 
						|
function add_to_crontab() {
 | 
						|
    local -a crontab=(crontab ${2:+-u "$2"})
 | 
						|
    local current="$("${crontab[@]}" -l 2>/dev/null)"
 | 
						|
    local tmpfile
 | 
						|
    ac_set_tmpfile tmpfile
 | 
						|
    if [ -n "$current" ]; then
 | 
						|
        echo "$current" >"$tmpfile"
 | 
						|
    fi
 | 
						|
    local NL=$'\n'
 | 
						|
    if quietgrep -xF "$1$NL#$1" "$tmpfile"; then
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
        return 123
 | 
						|
    else
 | 
						|
        echo "$1" >>"$tmpfile"
 | 
						|
        "${crontab[@]}" "$tmpfile"
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
    fi
 | 
						|
}
 | 
						|
# Supprimer la ligne $1 du crontab de l'utilisateur $2
 | 
						|
# Le code de retour est 123 si la ligne a déjà été supprimée
 | 
						|
function remove_from_crontab() {
 | 
						|
    local -a crontab=(crontab ${2:+-u "$2"})
 | 
						|
    local current="$("${crontab[@]}" -l 2>/dev/null)"
 | 
						|
    local tmpfile
 | 
						|
    ac_set_tmpfile tmpfile
 | 
						|
    if [ -n "$current" ]; then
 | 
						|
        echo "$current" >"$tmpfile"
 | 
						|
    fi
 | 
						|
    local NL=$'\n'
 | 
						|
    if ! quietgrep -xF "$1$NL#$1" "$tmpfile"; then
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
        return 123
 | 
						|
    else
 | 
						|
        grep -vxF "$1$NL#$1" "$tmpfile" | "${crontab[@]}" -
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
    fi
 | 
						|
}
 | 
						|
# Désactiver la ligne $1 du crontab de l'utilisateur $2 en mettant '#' devant. Si
 | 
						|
# la ligne n'existe pas, elle est ajoutée mais commentée.
 | 
						|
# Le code de retour est 123 si la ligne est déjà désactivée
 | 
						|
function disable_in_crontab() {
 | 
						|
    local -a crontab=(crontab ${2:+-u "$2"})
 | 
						|
    local current="$("${crontab[@]}" -l 2>/dev/null)"
 | 
						|
    local tmpfile
 | 
						|
    ac_set_tmpfile tmpfile
 | 
						|
    if [ -n "$current" ]; then
 | 
						|
        echo "$current" >"$tmpfile"
 | 
						|
    fi
 | 
						|
    local NL=$'\n'
 | 
						|
    if ! quietgrep -xF "$1$NL#$1" "$tmpfile"; then
 | 
						|
        echo "#$1" >>"$tmpfile"
 | 
						|
        "${crontab[@]}" "$tmpfile"
 | 
						|
    elif quietgrep -xF "#$1" "$tmpfile"; then
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
        return 123
 | 
						|
    else
 | 
						|
        <"$tmpfile" awkrun line="$1" '$0 == line { $0 = "#" $0 } { print }' | "${crontab[@]}" -
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
    fi
 | 
						|
}
 | 
						|
# Activer la ligne $1 du crontab de l'utilisateur $2 en enlevant '#' devant. Si
 | 
						|
# la ligne n'existe pas, elle est ajoutée.
 | 
						|
# Le code de retour est 123 si la ligne est déjà activée
 | 
						|
function enable_in_crontab() {
 | 
						|
    local -a crontab=(crontab ${2:+-u "$2"})
 | 
						|
    local current="$("${crontab[@]}" -l 2>/dev/null)"
 | 
						|
    local tmpfile
 | 
						|
    ac_set_tmpfile tmpfile
 | 
						|
    if [ -n "$current" ]; then
 | 
						|
        echo "$current" >"$tmpfile"
 | 
						|
    fi
 | 
						|
    local NL=$'\n'
 | 
						|
    if ! quietgrep -xF "$1$NL#$1" "$tmpfile"; then
 | 
						|
        echo "$1" >>"$tmpfile"
 | 
						|
        "${crontab[@]}" "$tmpfile"
 | 
						|
    elif quietgrep -xF "$1" "$tmpfile"; then
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
        return 123
 | 
						|
    else
 | 
						|
        <"$tmpfile" awkrun line="$1" '$0 == "#" line { sub(/^#/, "") } { print }' | "${crontab[@]}" -
 | 
						|
        ac_clean "$tmpfile"
 | 
						|
    fi
 | 
						|
}
 | 
						|
# Afficher la spécification crontab correspondant à l'heure courante
 | 
						|
function ctnow() {
 | 
						|
    date +"%-M %-H %-d %-m %u"
 | 
						|
}
 | 
						|
__CTRESOLVE_CTNOW=""
 | 
						|
# Analyser STDIN qui contient des lignes au format crontab, et afficher des
 | 
						|
# commandes pour les lignes correspondant à la date courante.
 | 
						|
# Les commandes sont de la forme "export var=value" pour la définition d'une
 | 
						|
# variable, "__ctexec 'cmd'" pour exécuter la commande correspondante ou
 | 
						|
# "__cterror 'msg'" en cas d'erreur de syntaxe sur une ligne. Il faut bien
 | 
						|
# entendu définir les function __ctexec et __cterror.
 | 
						|
# Cette fonction s'utilise de cette manière:
 | 
						|
#     function __ctexec() { eval "$*"; }
 | 
						|
#     function __cterror() { die "$*"; }
 | 
						|
#     eval "$(ctresolve <crontab)"
 | 
						|
function ctresolve() {
 | 
						|
    local -a ctnow
 | 
						|
    if [ -n "$__CTRESOLVE_CTNOW" ]; then
 | 
						|
        eval "ctnow=($__CTRESOLVE_CTNOW)"
 | 
						|
    else
 | 
						|
        eval "ctnow=($(ctnow))"
 | 
						|
    fi
 | 
						|
    filter_conf | awkrun -f ctnow[@] '
 | 
						|
function ctmatch_one(ctval, ref,              parts, part, i, j, start, end, step, ok) {
 | 
						|
  ok = 0
 | 
						|
  split(ctval, parts, /,/)
 | 
						|
  for(i = 1; i <= length(parts); i++) {
 | 
						|
    part = parts[i]
 | 
						|
    start = -1; end = -1; step = 1
 | 
						|
    # extraire /step
 | 
						|
    pos = index(part, "/")
 | 
						|
    if (pos != 0) { 
 | 
						|
      step = substr(part, pos + 1) + 0
 | 
						|
      part = substr(part, 1, pos - 1)
 | 
						|
    }
 | 
						|
    # traiter start-end
 | 
						|
    pos = index(part, "-")
 | 
						|
    if (pos != 0) {
 | 
						|
      start = substr(part, 1, pos - 1) + 0
 | 
						|
      end = substr(part, pos + 1) + 0
 | 
						|
    } else {
 | 
						|
      start = part + 0
 | 
						|
      end = start
 | 
						|
    }
 | 
						|
    # tester si ça matche
 | 
						|
    for (j = start; j <= end; j += step) {
 | 
						|
      if (j == ref) {
 | 
						|
        ok = 1
 | 
						|
        break
 | 
						|
      }
 | 
						|
    }
 | 
						|
    #print " step: is " ref " in [" start "-" end "/" step "] ? " (ok? "yes": "no") #DEBUG
 | 
						|
    if (ok) break
 | 
						|
  }
 | 
						|
  #print "final: is " ref " ~ " ctval " ? " (ok? "yes": "no") #DEBUG
 | 
						|
  return ok
 | 
						|
}
 | 
						|
function ctmatch_all(M, H, dom, mon, dow, refM, refH, refdom, refmon, refdow,               Mok, Hok, domok, monok, dowok) {
 | 
						|
    gsub(/\*/, "0-59", M)
 | 
						|
    Mok = ctmatch_one(M, refM)
 | 
						|
 | 
						|
    gsub(/\*/, "0-23", H)
 | 
						|
    Hok = ctmatch_one(H, refH)
 | 
						|
 | 
						|
    gsub(/\*/, "1-31", dom)
 | 
						|
    domok = ctmatch_one(dom, refdom)
 | 
						|
 | 
						|
    gsub(/\*/, "1-12", mon)
 | 
						|
    monok = ctmatch_one(mon, refmon)
 | 
						|
 | 
						|
    gsub(/\*/, "1-7", dow)
 | 
						|
    dowok = ctmatch_one(dow, refdow)
 | 
						|
 | 
						|
    return Mok && Hok && monok && (domok || dowok)
 | 
						|
}
 | 
						|
function print_cmd(cmd) {
 | 
						|
  print "__ctexec " quote_value(cmd)
 | 
						|
}
 | 
						|
 | 
						|
BEGIN {
 | 
						|
  refM = ctnow[1]; refH = ctnow[2]; refdom = ctnow[3]; refmon = ctnow[4]; refdow = ctnow[5]
 | 
						|
  ctref = refM " " refH " " refdom " " refmon " " refdow
 | 
						|
  print "## now: " ctref
 | 
						|
 | 
						|
  # est-on dans une série de ctline?
 | 
						|
  ctline_run = 0
 | 
						|
  # dans une série de ctline, il y a-t-il au moins un match?
 | 
						|
  ctline_run_one_match = 0
 | 
						|
  # faut-il afficher les commandes indentées?
 | 
						|
  match_indented = 0
 | 
						|
}
 | 
						|
 | 
						|
/^(export[ \t]+)?[a-zA-Z_][a-zA-Z0-9_]*[-+%#?]=/ {
 | 
						|
  ctline_run = 0; ctline_run_one_match = 0; match_indented = 0
 | 
						|
 | 
						|
  # manipulation de variables de type PATH
 | 
						|
  match($0, /^(export[ \t]+)?([a-zA-Z_][a-zA-Z0-9_]*)([-+%#?])=(.*)$/, parts)
 | 
						|
  name = parts[2]
 | 
						|
  type = parts[3]
 | 
						|
  value = parts[4]
 | 
						|
  if (type == "+" || type == "%") {
 | 
						|
    print "uaddpath " value " " name
 | 
						|
  } else if (type == "#") {
 | 
						|
    print "uinspath " value " " name
 | 
						|
  } else if (type == "-") {
 | 
						|
    print "udelpath " value " " name
 | 
						|
  } else if (type == "?") {
 | 
						|
    print "[ -n \"$" name "\" ] || " name "=" value
 | 
						|
  }
 | 
						|
  print "export " name
 | 
						|
  next
 | 
						|
}
 | 
						|
/^(export[ \t]+)?[a-zA-Z_][a-zA-Z0-9_]*=/ {
 | 
						|
  ctline_run = 0; ctline_run_one_match = 0; match_indented = 0
 | 
						|
 | 
						|
  # spécification de variable
 | 
						|
  sub(/^export[ \t]+/, "", $0)
 | 
						|
  print "export " $0
 | 
						|
  next
 | 
						|
}
 | 
						|
/^\$.+/ {
 | 
						|
  ctline_run = 0; ctline_run_one_match = 0; match_indented = 0
 | 
						|
 | 
						|
  # exécution de commande arbitraire
 | 
						|
  if ($0 ~ /^\$\{([ \t]*(#.*)?)?$/) {
 | 
						|
    # commande sur plusieurs lignes
 | 
						|
    getline
 | 
						|
    while ($0 !~ /^\$\}([ \t]*(#.*)?)?$/) {
 | 
						|
      print
 | 
						|
      if (getline <= 0) break
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    # commande sur une seule ligne
 | 
						|
    sub(/^\$/, "", $0)
 | 
						|
    print
 | 
						|
  }
 | 
						|
  next
 | 
						|
}
 | 
						|
 | 
						|
/^[ \t]*[-0-9/*,]+[ ]*[-0-9/*,]+[ ]*[-0-9/*,]+[ ]*[-0-9/*,]+[ ]*[-0-9/*,]+/ {
 | 
						|
  match_indented = 0
 | 
						|
 | 
						|
  M = $1; H = $2; dom = $3; mon = $4; dow = $5
 | 
						|
  ctline = M " " H " " dom " " mon " " dow
 | 
						|
 | 
						|
  sub(/^[ \t]*[^ ]+[ ]+[^ ]+[ ]+[^ ]+[ ]+[^ ]+[ ]+[^ ]+[ ]*/, "", $0)
 | 
						|
  cmd = $0
 | 
						|
 | 
						|
  match_cur = ctmatch_all(M, H, dom, mon, dow, refM, refH, refdom, refmon, refdow)
 | 
						|
  if (match_cur) print "## match: " ctline
 | 
						|
 | 
						|
  if (cmd == "") {
 | 
						|
    ctline_run = 1
 | 
						|
    if (match_cur) ctline_run_one_match = 1
 | 
						|
    if (ctline_run_one_match) match_indented = 1
 | 
						|
 | 
						|
  } else {
 | 
						|
    if (ctline_run && match_cur) ctline_run_one_match = 1
 | 
						|
    if (ctline_run && ctline_run_one_match) {
 | 
						|
      print_cmd(cmd)
 | 
						|
      match_indented = 1
 | 
						|
    }
 | 
						|
 | 
						|
    if (!ctline_run && match_cur) {
 | 
						|
      print_cmd(cmd)
 | 
						|
      match_indented = 1
 | 
						|
    }
 | 
						|
 | 
						|
    ctline_run = 0
 | 
						|
    ctline_run_one_match = 0
 | 
						|
  }
 | 
						|
 | 
						|
  next
 | 
						|
}
 | 
						|
/^[ \t]+/ {
 | 
						|
  ctline_run = 0; ctline_run_one_match = 0
 | 
						|
 | 
						|
  if (match_indented) {
 | 
						|
    sub(/^[ \t]+/, "", $0)
 | 
						|
    print_cmd($0)
 | 
						|
  }
 | 
						|
 | 
						|
  next
 | 
						|
}
 | 
						|
{
 | 
						|
  print "__cterror " quote_value("ligne de format incorrect: " $0)
 | 
						|
}
 | 
						|
'
 | 
						|
}
 | 
						|
 | 
						|
## Préfixes
 | 
						|
 | 
						|
function get_default_crontabdir_prefix() {
 | 
						|
    if check_sysinfos -s darwin; then
 | 
						|
        if check_sysinfos -d 10.6+; then
 | 
						|
            echo /var/at/tabs
 | 
						|
        else
 | 
						|
            echo /var/cron/tabs
 | 
						|
        fi
 | 
						|
    elif check_sysinfos -s linux; then
 | 
						|
        if check_sysinfos -d debianlike; then
 | 
						|
            echo /var/spool/cron/crontabs
 | 
						|
        elif check_sysinfos -d redhatlike; then
 | 
						|
            echo /var/spool/cron
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
__crontab_prefixes=
 | 
						|
function __compute_crontab_prefixes() {
 | 
						|
    [ -n "$__crontab_prefixes" ] && return
 | 
						|
    CRONTABDIR="${CRONTABDIR:-$(get_default_crontabdir_prefix)}"
 | 
						|
    __crontab_prefixes=1
 | 
						|
}
 | 
						|
 | 
						|
UTOOLS_PREFIXES=("${UTOOLS_PREFIXES[@]}" CRONTABDIR)
 | 
						|
 | 
						|
function compute_crontab_prefixes() {
 | 
						|
    __compute_crontab_prefixes
 | 
						|
}
 | 
						|
 | 
						|
function recompute_crontab_prefixes() {
 | 
						|
    __crontab_prefixes=
 | 
						|
    __compute_crontab_prefixes
 | 
						|
}
 | 
						|
 | 
						|
function get_CRONTABDIR_prefix() {
 | 
						|
    __compute_crontab_prefixes
 | 
						|
    echo "$CRONTABDIR"
 | 
						|
}
 |