updates and bugfixes
[zsh.git] / .zsh / functions / udh
1 # -*- mode:sh -*-
2
3 emulate -LR zsh
4 setopt extendedglob
5 setopt globdots
6 setopt numericglobsort
7
8 autoload -Uz relative
9 zmodload zsh/stat
10
11
12 local SPECBASE=${HOME}/.dotfiles
13 local CRONBASE=${HOME}/.crontabs
14 local startdir=$(pwd)
15 local STATEFILE=${HOME}/.config/mr/update
16
17 local linktarget entry file base dirn opt force diff now age max
18
19 if [ "$ZDOTDIR" = "" ]; then
20 echo "Sorry, need to run within a configured zsh environment"
21 return
22 fi
23 cd -q ${HOME}
24
25 while getopts "f" opt; do
26 case $opt in
27 (f)
28 force=1
29 ;;
30 (*)
31 return 1
32 ;;
33 esac
34 done
35 shift $(( OPTIND - 1 ))
36
37 if (( force )); then
38 mr update
39 else
40 if [[ ! -f ${STATEFILE} ]]; then
41 touch ${STATEFILE}
42 fi
43 age=$(zstat +ctime ${STATEFILE})
44 now=$(date +%s)
45 (( diff = now - age ))
46 (( max = 1 * 60 * 60 ))
47 if [[ $diff -gt $max ]]; then
48 mr update
49 else
50 echo "Too early retry"
51 return
52 fi
53 fi
54 touch ${STATEFILE}
55
56 # Now we check if we have something specific for this host, that we need
57 # to link into the homedir
58
59 typeset -a specdirs
60 specdirs=(
61 # "${SPECBASE}/net:$DOMAIN"
62 # "${SPECBASE}/host:$HOST"
63 # "${SPECBASE}/sys:$OSNAME"
64 # "${SPECBASE}/distri:$DISTRI"
65 # "${SPECBASE}/user:$USER"
66 # "${SPECBASE}/user:$SUDO_USER"
67 "${SPECBASE}/net:$DOMAIN/host:$HOST"
68 "${SPECBASE}/net:$DOMAIN/sys:$OSNAME"
69 "${SPECBASE}/net:$DOMAIN/distri:$DISTRI"
70 "${SPECBASE}/net:$DOMAIN/user:$USER"
71 "${SPECBASE}/net:$DOMAIN/user:$SUDO_USER"
72 "${SPECBASE}/net:$DOMAIN/host:$HOST/sys:$OSNAME"
73 "${SPECBASE}/net:$DOMAIN/host:$HOST/distri:$DISTRI"
74 "${SPECBASE}/net:$DOMAIN/host:$HOST/user:$USER"
75 "${SPECBASE}/net:$DOMAIN/host:$HOST/user:$SUDO_USER"
76 "${SPECBASE}/net:$DOMAIN/host:$HOST/sys:$OSNAME"
77 "${SPECBASE}/net:$DOMAIN/host:$HOST/sys:$OSNAME/distri:$DISTRI"
78 "${SPECBASE}/net:$DOMAIN/host:$HOST/sys:$OSNAME/user:$USER"
79 "${SPECBASE}/net:$DOMAIN/host:$HOST/sys:$OSNAME/user:$SUDO_USER"
80 "${SPECBASE}/host:$HOST/sys:$OSNAME"
81 "${SPECBASE}/host:$HOST/distri:$DISTRI"
82 "${SPECBASE}/host:$HOST/user:$USER"
83 "${SPECBASE}/host:$HOST/user:$SUDO_USER"
84 "${SPECBASE}/host:$HOST/sys:$OSNAME/distri:$DISTRI"
85 "${SPECBASE}/host:$HOST/sys:$OSNAME/user:$USER"
86 "${SPECBASE}/host:$HOST/sys:$OSNAME/user:$SUDO_USER"
87 )
88
89 typeset -a workdirs
90 for entry in $specdirs[@]; do
91 for file in ${entry}/**/*(N.); do
92 workdirs+=$file
93 done
94 done
95 typeset -U workdirs
96
97 # Now link stuff
98 echo "Checking host files..."
99 for entry in $workdirs[@]; do
100 base=${entry:t}
101 dirn=${entry:h}
102 dirn=${dirn//$SPECBASE/}
103 dirn=${dirn//net:$DOMAIN/}
104 dirn=${dirn//host:$HOST/}
105 dirn=${dirn//sys:$OSNAME/}
106 dirn=${dirn//distri:$DISTRI/}
107 dirn=${dirn//user:$USER/}
108 dirn=${dirn//user:$SUDO_USER/}
109
110 echo "... ${HOME}/${dirn}/${base}"
111
112 if [ -f "${HOME}/${dirn}/${base}" ] || [ -L "${HOME}/${dirn}/${base}" ]; then
113 linktarget=$(readlink -f "${HOME}/${dirn}/${base}")
114 if ! [[ $linktarget =~ .dotfiles ]] || [ -z "${linktarget}" ]; then
115 answer=N
116 echo "File exists. ${HOME}/${dirn}/${base} (is ${linktarget})"
117 vared -p 'Overwrite with symlink to ${entry}?: [y/N] ' answer
118 case ${answer} in
119 y|Y)
120 rm -f "${HOME}/${dirn}/${base}"
121 ;;
122 *)
123 echo "Not overwriting ${linktarget}"
124 continue
125 ;;
126 esac
127 fi
128 fi
129
130 linktarget=$(relative "${entry}" "${HOME}/${dirn}")
131 # The same can be done with ln - current sid or later versions.
132 # (as of 2013-16-03)
133 # if ln --help 2>/dev/null | grep -- --relative >/dev/null; then
134 # LNOPTS="-r"
135 # fi
136 if [[ -n ${dirn} ]]; then
137 mkdir -p "${HOME}/${dirn}"
138 if [[ ! -L ${HOME}/${dirn}/${base} ]]; then
139 echo "Linking ${entry} to ${HOME}/${dirn}/${base}"
140 /bin/ln -s "${linktarget}" "${HOME}/${dirn}"
141 fi
142 else
143 if [[ ! -L ${HOME}/${dirn}/${base} ]]; then
144 echo "Linking ${entry} to ${HOME}/${dirn}"
145 /bin/ln -s "${linktarget}" "${HOME}/${base}"
146 fi
147 fi
148 done
149
150 if [ -f "${CRONBASE}/${HOST}.${DOMAIN}" ]; then
151 if ! old=${${(z)"$(crontab -l | md5sum)"}[1]}; then
152 echo "crontab disabled for users"
153 return
154 fi
155 new=${${(z)$(md5sum "${CRONBASE}/${HOST}.${DOMAIN}" )}[1]}
156 if [ "${new}" != "${old}" ]; then
157 echo "Crontab changed, installing repository copy"
158 crontab "${CRONBASE}/${HOST}.${DOMAIN}"
159 fi
160 fi
161
162 cd -q ${startdir}