update Thu Oct 29 18:37:00 PDT 2009
[pkgsrc.git] / mk / pkginstall / usergroup
1 # $NetBSD: usergroup,v 1.3 2009/10/29 20:19:27 joerg Exp $
2 #
3 # Generate a +USERGROUP script that reference-counts users and groups
4 # that are required for the proper functioning of the package.
5 #
6 case "${STAGE},$1" in
7 UNPACK,|UNPACK,+USERGROUP)
8         ${CAT} > ./+USERGROUP << 'EOF'
9 #!@SH@
10 #
11 # +USERGROUP - users and groups management script
12 #
13 # Usage: ./+USERGROUP ADD|REMOVE [metadatadir]
14 #        ./+USERGROUP CHECK-ADD|CHECK-REMOVE [metadatadir]
15 #
16 # This script supports two actions, ADD and REMOVE, that will add or
17 # remove the users and groups needed by the package associated with
18 # <metadatadir>.  The CHECK-ADD action will check whether any users or
19 # groups needed by the package are missing, and print an informative
20 # message noting those users and groups.  The CHECK-REMOVE action will
21 # check whether any users and groups needed by the package still exist,
22 # and print an informative message noting those users and groups.  The
23 # CHECK-ADD and CHECK-REMOVE actions return non-zero if they detect
24 # either missing or existing users/groups, respectively.
25 #
26 # Lines starting with "# USER: " or "# GROUP: " are data read by this
27 # script that name the users and groups that this package requires to
28 # exist to function correctly, e.g.
29 #
30 #       # USER: foo:foogrp::The Foomister
31 #       # GROUP: foogrp
32 #
33 # The USER lines are of the form:
34 #
35 #       user:group[:[userid][:[descr][:[home][:shell]]]]
36 #
37 # Only the user and group are required; everything else is optional,
38 # but the colons must be in the right places when specifying optional
39 # bits.
40 #
41 # The GROUP lines are of the form:
42 #
43 #       group[:groupid]
44 #
45 # Only the group is required; the groupid is optional.
46 #
47 AWK="@AWK@"
48 CAT="@CAT@"
49 CHGRP="@CHGRP@"
50 CHMOD="@CHMOD@"
51 CHOWN="@CHOWN@"
52 ECHO="@ECHO@"
53 GREP="@GREP@"
54 LS="@LS@"
55 MKDIR="@MKDIR@"
56 MV="@MV@"
57 PWD_CMD="@PWD_CMD@"
58 RM="@RM@"
59 RMDIR="@RMDIR@"
60 SED="@SED@"
61 SORT="@SORT@"
62 TEST="@TEST@"
63 TRUE="@TRUE@"
64
65 SELF=$0
66 ACTION=$1
67
68 CURDIR=`${PWD_CMD}`
69 PKG_METADATA_DIR="${2-${CURDIR}}"
70 : ${PKGNAME=${PKG_METADATA_DIR##*/}}
71 : ${PKG_DBDIR=${PKG_METADATA_DIR%/*}}
72 : ${PKG_REFCOUNT_DBDIR=${PKG_DBDIR}.refcount}
73
74 PKG_REFCOUNT_USERS_DBDIR="${PKG_REFCOUNT_DBDIR}/users"
75 PKG_REFCOUNT_GROUPS_DBDIR="${PKG_REFCOUNT_DBDIR}/groups"
76
77 case "${PKG_CREATE_USERGROUP:-@PKG_CREATE_USERGROUP@}" in
78 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
79         _PKG_CREATE_USERGROUP=yes
80         ;;
81 [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
82         _PKG_CREATE_USERGROUP=no
83         ;;
84 esac
85
86 listwrap()
87 {
88         _length=$1
89         _buffer=
90         while read _line; do
91                 set -- $_line
92                 for _word; do
93                         case $_buffer in
94                         "")     _buffer="$_word" ;;
95                         *)      _buffer="$_buffer  $_word" ;;
96                         esac
97                         if ${TEST} ${#_buffer} -gt $_length; then
98                                 ${ECHO} "       $_buffer"
99                                 _buffer=
100                         fi
101                 done
102         done
103         case $_buffer in
104         "")     ;;
105         *)      ${ECHO} "       $_buffer" ;;
106         esac
107 }
108
109 # DO NOT CHANGE THE FOLLOWING LINE!
110 # platform-specific adduser/addgroup functions
111
112 exitcode=0
113 case $ACTION in
114 ADD)
115         ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u |
116         { while read line; do
117                 SAVEIFS="$IFS"; IFS=":"
118                 set -- $line
119                 group="$1"; groupid="$2"
120                 IFS="$SAVEIFS"
121                 case $group in
122                 "")     continue ;;
123                 esac
124                 shadow_dir="${PKG_REFCOUNT_GROUPS_DBDIR}/$group"
125                 preexist="$shadow_dir/+PREEXISTING"
126                 token="$shadow_dir/${PKGNAME}"
127                 if ${TEST} ! -d "$shadow_dir"; then
128                         ${MKDIR} $shadow_dir
129                         group_exists $group $groupid &&
130                                 ${ECHO} "${PKGNAME}" > $preexist
131                 fi
132                 if ${TEST} -f "$token" && \
133                    ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then
134                         :
135                 else
136                         ${ECHO} "${PKG_METADATA_DIR}" >> $token
137                 fi
138                 case ${_PKG_CREATE_USERGROUP} in
139                 yes)
140                         group_exists $group $groupid
141                         case $? in
142                         0)      ;;
143                         1)      addgroup "$group" "$groupid" ;;
144                         esac
145                         ;;
146                 esac
147         done; }
148         ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u |
149         { while read line; do
150                 SAVEIFS="$IFS"; IFS=":"
151                 set -- $line
152                 user="$1"; group="$2"; userid="$3"
153                 descr="$4"; home="$5" shell="$6"
154                 IFS="$SAVEIFS"
155                 case $user in
156                 "")     continue ;;
157                 esac
158                 case $group in
159                 "")     continue ;;
160                 esac
161                 shadow_dir="${PKG_REFCOUNT_USERS_DBDIR}/$user"
162                 preexist="$shadow_dir/+PREEXISTING"
163                 token="$shadow_dir/${PKGNAME}"
164                 if ${TEST} ! -d "$shadow_dir"; then
165                         ${MKDIR} $shadow_dir
166                         user_exists $user $userid &&
167                                 ${ECHO} "${PKGNAME}" > $preexist
168                 fi
169                 if ${TEST} -f "$token" && \
170                    ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then
171                         :
172                 else
173                         ${ECHO} "${PKG_METADATA_DIR}" >> $token
174                 fi
175                 case ${_PKG_CREATE_USERGROUP} in
176                 yes)
177                         group_exists $group || continue
178                         user_exists $user $userid
179                         case $? in
180                         0)      ;;
181                         1)      adduser "$user" "$group" "$userid"      \
182                                         "$descr" "$home" "$shell"
183                                 ;;
184                         esac
185                         ;;
186                 esac
187         done; }
188         ;;
189
190 REMOVE)
191         ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u |
192         { while read line; do
193                 SAVEIFS="$IFS"; IFS=":"
194                 set -- $line
195                 user="$1"; group="$2"; userid="$3"
196                 descr="$4"; home="$5" shell="$6"
197                 IFS="$SAVEIFS"
198                 case $user in
199                 "")     continue ;;
200                 esac
201                 shadow_dir="${PKG_REFCOUNT_USERS_DBDIR}/$user"
202                 preexist="$shadow_dir/+PREEXISTING"
203                 token="$shadow_dir/${PKGNAME}"
204                 tokentmp="$token.tmp.$$"
205                 if ${TEST} -f "$token" && \
206                    ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then
207                         ${CAT} "$token" | ${GREP} -v "^${PKG_METADATA_DIR}$" > $tokentmp
208                         case `${CAT} $tokentmp | ${SED} -n "$="` in
209                         "")
210                                 ${RM} -f $preexist $token $token.tmp.*
211                                 ${RMDIR} -p $shadow_dir 2>/dev/null || ${TRUE}
212                                 ;;
213                         *)
214                                 ${MV} -f $tokentmp $token
215                                 ;;
216                         esac
217                 fi
218         done; }
219         ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u |
220         { while read line; do
221                 SAVEIFS="$IFS"; IFS=":"
222                 set -- $line
223                 group="$1"; groupid="$2"
224                 IFS="$SAVEIFS"
225                 case $group in
226                 "")     continue ;;
227                 esac
228                 shadow_dir="${PKG_REFCOUNT_GROUPS_DBDIR}/$group"
229                 preexist="$shadow_dir/+PREEXISTING"
230                 token="$shadow_dir/${PKGNAME}"
231                 tokentmp="$token.tmp.$$"
232                 if ${TEST} -f "$token" && \
233                    ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then
234                         ${CAT} "$token" | ${GREP} -v "^${PKG_METADATA_DIR}$" > $tokentmp
235                         case `${CAT} $tokentmp | ${SED} -n "$="` in
236                         "")
237                                 ${RM} -f $preexist $token $token.tmp.*
238                                 ${RMDIR} -p $shadow_dir 2>/dev/null || ${TRUE}
239                                 ;;
240                         *)
241                                 ${MV} -f $tokentmp $token
242                                 ;;
243                         esac
244                 fi
245         done; }
246         ;;
247
248 CHECK-ADD)
249         ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u |
250         { while read line; do
251                 SAVEIFS="$IFS"; IFS=":"
252                 set -- $line
253                 group="$1"; groupid="$2"
254                 IFS="$SAVEIFS"
255                 case $group in
256                 "")     continue ;;
257                 *)      group_exists $group $groupid && continue ;;
258                 esac
259                 case "$printed_header" in
260                 yes)    ;;
261                 *)      printed_header=yes
262                         ${ECHO} "==========================================================================="
263                         ${ECHO} "The following groups need to be created for ${PKGNAME}:"
264                         ${ECHO} ""
265                         ;;
266                 esac
267                 case $groupid in
268                 "")     ${ECHO} "       $group" ;;
269                 *)      ${ECHO} "       $group (gid = $groupid)" ;;
270                 esac
271         done
272         case "$printed_header" in
273         yes)    ${ECHO} ""
274                 ${ECHO} "==========================================================================="
275                 exit 1
276                 ;;
277         esac; }
278         ${TEST} $? -eq 0 || exitcode=1
279         ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u |
280         { while read line; do
281                 SAVEIFS="$IFS"; IFS=":"
282                 set -- $line
283                 user="$1"; group="$2"; userid="$3"
284                 descr="$4"; home="$5" shell="$6"
285                 IFS="$SAVEIFS"
286                 case $user in
287                 "")     continue ;;
288                 *)      user_exists $user $userid && continue ;;
289                 esac
290                 case "$printed_header" in
291                 yes)    ;;
292                 *)      printed_header=yes
293                         ${ECHO} "==========================================================================="
294                         ${ECHO} "The following users need to be created for ${PKGNAME}:"
295                         ${ECHO} ""
296                         ;;
297                 esac
298                 : ${home:="@PKG_USER_HOME@"}
299                 : ${shell:="@PKG_USER_SHELL@"}
300                 case $userid in
301                 "")     ${ECHO} "       $user: $group, $home, $shell" ;;
302                 *)      ${ECHO} "       $user (uid = $userid): $group, $home, $shell" ;;
303                 esac
304         done
305         case "$printed_header" in
306         yes)    ${ECHO} ""
307                 ${ECHO} "==========================================================================="
308                 exit 1
309                 ;;
310         esac; }
311         ${TEST} $? -eq 0 || exitcode=1
312         ;;
313
314 CHECK-REMOVE)
315         ${SED} -n "/^\# USER: /{s/^\# USER: //;p;}" ${SELF} | ${SORT} -u |
316         { while read line; do
317                 SAVEIFS="$IFS"; IFS=":"
318                 set -- $line
319                 user="$1"; group="$2"; userid="$3"
320                 descr="$4"; home="$5" shell="$6"
321                 IFS="$SAVEIFS"
322                 case $user in
323                 "")     continue ;;
324                 *)      user_exists $user $userid || continue ;;
325                 esac
326                 shadow_dir="${PKG_REFCOUNT_USERS_DBDIR}/$user"
327                 ${TEST} ! -d "$shadow_dir" || continue  # refcount isn't zero
328                 existing_users="$existing_users $user"
329         done
330         case $existing_users in
331         "")     ;;
332         *)      ${ECHO} "==========================================================================="
333                 ${ECHO} "The following users are no longer being used by ${PKGNAME},"
334                 ${ECHO} "and they can be removed if no other software is using them:"
335                 ${ECHO} ""
336                 ${ECHO} "$existing_users" | listwrap 40
337                 ${ECHO} ""
338                 ${ECHO} "==========================================================================="
339                 exit 1
340                 ;;
341         esac; }
342         ${TEST} $? -eq 0 || exitcode=1
343         ${SED} -n "/^\# GROUP: /{s/^\# GROUP: //;p;}" ${SELF} | ${SORT} -u |
344         { while read line; do
345                 SAVEIFS="$IFS"; IFS=":"
346                 set -- $line
347                 group="$1"; groupid="$2"
348                 IFS="$SAVEIFS"
349                 case $group in
350                 "")     continue ;;
351                 *)      group_exists $group $groupid || continue ;;
352                 esac
353                 shadow_dir="${PKG_REFCOUNT_GROUPS_DBDIR}/$group"
354                 ${TEST} ! -d "$shadow_dir" || continue  # refcount isn't zero
355                 existing_groups="$existing_groups $group"
356         done
357         case $existing_groups in
358         "")     ;;
359         *)      ${ECHO} "==========================================================================="
360                 ${ECHO} "The following groups are no longer being used by ${PKGNAME},"
361                 ${ECHO} "and they can be removed if no other software is using them:"
362                 ${ECHO} ""
363                 ${ECHO} "$existing_groups" | listwrap 40
364                 ${ECHO} ""
365                 ${ECHO} "==========================================================================="
366                 exit 1
367                 ;;
368         esac; }
369         ${TEST} $? -eq 0 || exitcode=1
370         ;;
371
372 *)
373         ${ECHO} "Usage: ./+USERGROUP ADD|REMOVE [metadatadir]"
374         ${ECHO} "       ./+USERGROUP CHECK-ADD|CHECK-REMOVE [metadatadir]"
375         ;;
376 esac
377 exit $exitcode
378
379 EOF
380         ${SED} -n "/^\# GROUP: /p" ${SELF} >> ./+USERGROUP
381         ${SED} -n "/^\# USER: /p" ${SELF} >> ./+USERGROUP
382         ${CHMOD} +x ./+USERGROUP
383         ;;
384 esac
385