r1: [svn-inject] Installing original source of amavisd-cn
[amavisd-cn.git] / src / functions.sh
1 #####
2 ##
3 ## first, some generic functions
4 ##
5
6 # find first free uid/gid in range
7 # find_id passwd 100 999
8 find_id() {
9   local db first last ids
10   db=$1
11   first=$2
12   last=$3
13   ids=$(getent $db | awk -F: "\$3 >= $first && \$3 <= $last {print \$3}")
14   for i in $(seq $first $last)
15   do
16     if ! echo $ids |grep -q $i; then
17       echo $i
18       return 0
19     fi
20   done
21   return 1
22 }
23
24 #
25 # Update uid for user from reserved system range (0-99) to dynamic system
26 # range (100-999).  Optionally update ownerships of given directories.
27 # $0 user [directory ...]
28 #
29 check_and_update_ugid() {
30   local user newgid newuid
31   user=$1
32   if [ "$(getent passwd $user | awk -F: '$3 >= 100 {print "ok"; exit 0}')" ]; then
33     return 0
34   fi
35   shift
36   newgid=$(find_id group 100 999)
37   newuid=$(find_id passwd 100 999)
38   # other directories/files
39   chown -R $newuid:$newgid $* 2>/dev/null || true
40   groupmod -g $newgid $user
41   usermod -u $newuid -g $newgid $user
42   cp_echo "CN: Fixed $user user uid/gid."
43 }
44
45 wait_for_fds () {
46   # wait until process shows some I/O readiness :)
47   [ "$DEBIAN_SCRIPT_DEBUG" ] && set -vx
48   local name IFSOLD num sleep maxtry script user psname pidfile fdname
49   name="$1"
50   [ -z "$name" ] && return 1
51   IFSOLD="$IFS"
52   IFS=" " # tab
53   read name script user psname pidfile num fdname <<-EOPTS
54         $(echo "$options" | sed 's/             */      /g' | grep ^$name)
55         EOPTS
56   IFS="$IFSOLD"
57   num=${num:-4}
58   sleep=${sleep:-1}
59   maxtry=${maxtry:-10}
60   if [ -n "$pidfile" ]; then
61     pidfile=/var/run/$pidfile
62     findpid="[ -f $pidfile ] && cat $pidfile || true"
63   else
64     findpid="pgrep -u $user -f \"$psname\" -P 1 | head -1"
65   fi
66
67   # loop the loop the loop
68   try=1
69   while /bin/true
70   do
71     sleep $sleep                           # 1st, give it a chance to run
72     pid=`eval $findpid`                    # 2nd: find it
73     [ -z "$pid" ]           && return 1    # not running at all
74     count=`ls -1 /proc/$pid/fd 2> /dev/null| wc -l`    # 3rd: count all it's worth
75     [ "$count" -ge "$num" ] && ls -l /proc/$pid/fd | grep -q $fdname \
76                             && return      # success -- release
77     try=$(($try+1))
78     [ "0$try" -ge "0$maxtry" ] && return 1 # no luck this time
79   done
80 }
81
82 failed() {
83   if [ -n "$failed" ]; then
84     failed="$failed, $1"
85   else
86     failed="$1"
87   fi
88 }
89
90 check_and_add_alias () {
91   if ! grep -q "^$1:" $ALIASES; then
92     echo "$1: $2" >> $ALIASES
93     # both postfix and sendmail use newaliases
94     newaliases > /dev/null
95   fi
96 }
97
98 noisy_backup() {
99   cp_backup_conffile "$1"
100   cp_echo "CN: Current configuration saved in /var/backups/`basename $1`.bak"
101 }
102
103 # if fqdn is name.dom3.dom2.dom1.hr, check if this host is MX for
104 # either dom3.dom2.dom1.hr, dom2.dom1.hr or dom1.hr and dump highest level
105 # domain on stdout
106 get_domain() {
107   local domains d
108   RET=$host
109   if ! echo $host | grep -q '\.'; then
110     return
111   fi
112   if [ ! -x /usr/bin/host ]; then
113     cp_echo "CN: no host command... \$mydomain value might be unoptimal."
114     return
115   fi
116   domains=$(hostname -f | awk -F'\.' '
117     {
118       for (i=2; i<NF; i++) { 
119         for (j=i; j<NF; j++) {
120           printf "%s", $(j)"."
121         };
122         print $NF
123       }
124     }'    )
125   for d in $domains
126   do
127     mxes=$(host -t mx $d)
128     # handle output of both /usr/bin/host providers
129     mxes=$(echo "$mxes"|\
130            awk '/mail is handled by/ || /MX/ {print $NF}'|sed s/\.$//)
131     if echo "$mxes" |egrep -q "^$host$"; then
132       RET="$d"
133     fi
134   done
135 }
136
137 # XXX TODO implement per paragraph conditional munging some day
138 in_paragraph() {
139   return 1
140 }
141   
142 commented_in_paragraph() {
143   local s
144   s="$1"
145   shift
146   s=`echo $s|sed 's/^/[[:blank:]]*#[[:blank:]]/'`
147   set -- "$s" "$@"
148   in_paragraph "$@"
149 }
150
151 uncommented_in_paragraph() {
152   local s
153   s="$1"
154   shift
155   s=`echo $s|sed 's/^/[[:blank:]]*/'`
156   set -- "$s" "$@"
157   in_paragraph "$@"
158 }
159
160 catpatch() {
161   cat "$postdiff" | sed "s,amavisd\.conf[a-z.-]*\t,$1\t,"
162 }
163
164 #####
165 ##
166 ## amavisd-cn specific functions bloated enough to be moved here
167 ##
168
169 conf_from_template() {
170   cp /dev/null $ACONF
171   sed -e "s/_CN_DOMAIN_/$domain/g; s/_CN_HOST_/$host/g" $ACONFTMPL >> $ACONF
172   restart_daemon=1
173   changed_config=1
174 }