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