1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
|
# $NetBSD: dirs,v 1.4 2008/01/04 21:50:27 heinz Exp $
#
# Generate a +DIRS script that reference counts directories that are
# required for the proper functioning of the package.
#
case "${STAGE},$1" in
UNPACK,|UNPACK,+DIRS)
${CAT} > ./+DIRS << 'EOF'
#!@SH@
#
# +DIRS - reference-counted directory management script
#
# Usage: ./+DIRS ADD|REMOVE|PERMS [metadatadir]
# ./+DIRS CHECK-ADD|CHECK-REMOVE|CHECK-PERMS [metadatadir]
#
# This script supports two actions, ADD and REMOVE, that will add or
# remove the directories needed by the package associated with
# <metadatadir>. The CHECK-ADD action will check whether any directories
# needed by the package are missing, and print an informative message
# noting those directories. The CHECK-REMOVE action will check whether
# any directories needed by the package still exist, and print an
# informative message noting those directories. The CHECK-ADD and
# CHECK-REMOVE actions return non-zero if they detect either missing
# or existing directories, respectively. The PERMS action will correct
# any ownership or permission discrepancies between the existing
# directories and the data in this script, and the CHECK-PERMS action
# will check whether any directories have the wrong ownership or
# permission and print an informative message noting those directories.
# The CHECK-PERMS action will return non-zero if it detects directories
# with wrong ownership or permissions.
#
# Lines starting with "# DIR: " are data read by this script that
# name the directories that this package requires to exist to function
# correctly, e.g.
#
# # DIR: /etc/foo m
# # DIR: /var/log/foo/tmp mo 0700 foo-user foo-group
# # DIR: share/foo-plugins fm
#
# For each DIR entry, if the directory path is relative, then it is taken
# to be relative to ${PKG_PREFIX}.
#
# The second field in each DIR entry is a set of flags with the following
# meanings:
#
# f ignore ${PKG_CONFIG}
# m create (make) the directory when ADDing
# o directory is owned by the package
#
AWK="@AWK@"
CAT="@CAT@"
CHGRP="@CHGRP@"
CHMOD="@CHMOD@"
CHOWN="@CHOWN@"
ECHO="@ECHO@"
GREP="@GREP@"
LS="@LS@"
MKDIR="@MKDIR@"
MV="@MV@"
PWD_CMD="@PWD_CMD@"
RM="@RM@"
RMDIR="@RMDIR@"
SED="@SED@"
SORT="@SORT@"
TEST="@TEST@"
TRUE="@TRUE@"
SELF=$0
ACTION=$1
CURDIR=`${PWD_CMD}`
PKG_METADATA_DIR="${2-${CURDIR}}"
: ${PKGNAME=${PKG_METADATA_DIR##*/}}
: ${PKG_DBDIR=${PKG_METADATA_DIR%/*}}
: ${PKG_REFCOUNT_DBDIR=${PKG_DBDIR}.refcount}
: ${PKG_PREFIX=@PREFIX@}
PKG_REFCOUNT_DIRS_DBDIR="${PKG_REFCOUNT_DBDIR}/dirs"
case "${PKG_CONFIG:-@PKG_CONFIG@}" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
_PKG_CONFIG=yes
;;
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
_PKG_CONFIG=no
;;
esac
case "${PKG_CONFIG_PERMS:-@PKG_CONFIG_PERMS@}" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
_PKG_CONFIG_PERMS=yes
;;
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
_PKG_CONFIG_PERMS=no
;;
esac
exitcode=0
case $ACTION in
ADD)
${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -u |
while read dir d_flags d_mode d_user d_group; do
case $dir in
"") continue ;;
[!/]*) dir="${PKG_PREFIX}/$dir" ;;
esac
case $d_flags in
*m*) ;;
*) continue ;;
esac
shadow_dir="${PKG_REFCOUNT_DIRS_DBDIR}$dir"
perms="$shadow_dir/+PERMISSIONS"
preexist="$shadow_dir/+PREEXISTING"
token="$shadow_dir/${PKGNAME}"
if ${TEST} ! -d "$shadow_dir"; then
${MKDIR} $shadow_dir
${TEST} ! -d "$dir" ||
${ECHO} "${PKGNAME}" > $preexist
fi
if ${TEST} -f "$token" && \
${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then
:
else
${ECHO} "${PKG_METADATA_DIR}" >> $token
fi
case $d_mode$d_user$d_group in
"") ;;
*) ${ECHO} "$d_user $d_group $d_mode" > $perms ;;
esac
case $d_flags:$_PKG_CONFIG in
*f*:*|*:yes)
${MKDIR} $dir
case $d_user in
"") ;;
*) ${CHOWN} $d_user $dir ;;
esac
case $d_group in
"") ;;
*) ${CHGRP} $d_group $dir ;;
esac
case $d_mode in
"") ;;
*) ${CHMOD} $d_mode $dir ;;
esac
;;
esac
done
;;
REMOVE)
${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -ru |
while read dir d_flags d_mode d_user d_group; do
case $dir in
"") continue ;;
[!/]*) dir="${PKG_PREFIX}/$dir" ;;
esac
case $d_flags in
*m*) ;;
*) continue ;;
esac
shadow_dir="${PKG_REFCOUNT_DIRS_DBDIR}$dir"
perms="$shadow_dir/+PERMISSIONS"
preexist="$shadow_dir/+PREEXISTING"
token="$shadow_dir/${PKGNAME}"
tokentmp="$token.tmp.$$"
if ${TEST} -f "$token" && \
${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then
${CAT} "$token" | ${GREP} -v "^${PKG_METADATA_DIR}$" > $tokentmp
case `${CAT} $tokentmp | ${SED} -n "$="` in
"")
${TEST} -f "$preexist" ||
{ case $d_flags:$_PKG_CONFIG in
*f*:*|*:yes)
${RMDIR} -p $dir 2>/dev/null || ${TRUE};
;;
esac; }
${RM} -f $perms $preexist $token $token.tmp.*
${RMDIR} -p $shadow_dir 2>/dev/null || ${TRUE}
;;
*)
${MV} -f $tokentmp $token
;;
esac
fi
done
;;
PERMS)
${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -u |
while read dir d_flags d_mode d_user d_group; do
case $_PKG_CONFIG:$_PKG_CONFIG_PERMS in
yes:yes) ;;
*) continue ;;
esac
case $dir in
"") continue ;;
[!/]*) dir="${PKG_PREFIX}/$dir" ;;
esac
case $d_user in
"") ;;
*) ${CHOWN} $d_user $dir ;;
esac
case $d_group in
"") ;;
*) ${CHGRP} $d_group $dir ;;
esac
case $d_mode in
"") ;;
*) ${CHMOD} $d_mode $dir ;;
esac
done
;;
CHECK-ADD)
${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -u |
{ while read dir d_flags d_mode d_user d_group; do
case $dir in
"") continue ;;
[!/]*) dir="${PKG_PREFIX}/$dir" ;;
esac
${TEST} ! -d "$dir" || continue
case $d_flags in
*m*) ;;
*) continue ;;
esac
case "$printed_header" in
yes) ;;
*) printed_header=yes
${ECHO} "==========================================================================="
${ECHO} "The following directories should be created for ${PKGNAME}:"
${ECHO} ""
;;
esac
case $d_user:$d_group:$d_mode in
[!:]*:[!:]*:[!:]*)
${ECHO} " $dir (m=$d_mode, o=$d_user, g=$d_group)"
;;
*)
${ECHO} " $dir"
;;
esac
done
case "$printed_header" in
yes) ${ECHO} ""
${ECHO} "==========================================================================="
exit 1
;;
esac; }
${TEST} $? -eq 0 || exitcode=1
;;
CHECK-REMOVE)
${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -ru |
{ while read dir d_flags d_mode d_user d_group; do
case $dir in
"") continue ;;
[!/]*) dir="${PKG_PREFIX}/$dir" ;;
esac
${TEST} -d "$dir" || continue
case $d_flags in
*o*) ;;
*) continue ;;
esac
shadow_dir="${PKG_REFCOUNT_DIRS_DBDIR}$dir"
${TEST} ! -d "$shadow_dir" || continue # refcount isn't zero
case "$printed_header" in
yes) ;;
*) printed_header=yes
${ECHO} "==========================================================================="
${ECHO} "The following directories are no longer being used by ${PKGNAME},"
${ECHO} "and they can be removed if no other packages are using them:"
${ECHO} ""
;;
esac
${ECHO} " $dir"
done
case "$printed_header" in
yes) ${ECHO} ""
${ECHO} "==========================================================================="
exit 1
;;
esac; }
${TEST} $? -eq 0 || exitcode=1
;;
CHECK-PERMS)
tmpdir="./.pkginstall.$$"
${MKDIR} -p $tmpdir 2>/dev/null || exit 1
${CHMOD} 0700 $tmpdir
${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -ru |
{ while read dir d_flags d_mode d_user d_group; do
case $dir in
"") continue ;;
[!/]*) dir="${PKG_PREFIX}/$dir" ;;
esac
${TEST} -d "$dir" || continue
case $d_user:$d_group:$d_mode in
::) continue ;;
esac
perms=`${LS} -ld $dir | ${AWK} '{ print $1":"$3":"$4 }'`
testpath="$tmpdir/dir_perms"
${MKDIR} -p $testpath
${CHMOD} $d_mode $testpath 2>/dev/null
longmode=`${LS} -ld $testpath | ${AWK} '{ print $1 }'`
case $d_mode:$d_user:$d_group in
:[!:]*:)
case "$perms" in
*:$d_user:*) continue ;;
esac
;;
:[!:]*:[!:]*)
case "$perms" in
*:$d_user:$d_group) continue ;;
esac
;;
[!:]*::)
case "$perms" in
$longmode:*:*) continue ;;
esac
;;
[!:]*:[!:]*:)
case "$perms" in
$longmode:$d_user:*) continue ;;
esac
;;
[!:]*:[!:]*:[!:]*)
case "$perms" in
$longmode:$d_user:$d_group) continue ;;
esac
;;
esac
case "$printed_header" in
yes) ;;
*) printed_header=yes
${ECHO} "==========================================================================="
${ECHO} "The following directories are used by ${PKGNAME} and"
${ECHO} "have the wrong ownership and/or permissions:"
${ECHO} ""
;;
esac
case $d_mode:$d_user:$d_group in
[!:]*::)
${ECHO} " $dir (m=$d_mode)"
;;
[!:]*:[!:]*:)
${ECHO} " $dir (m=$d_mode, o=$d_user)"
;;
[!:]*:[!:]*:[!:]*)
${ECHO} " $dir (m=$d_mode, o=$d_user, g=$d_group)"
;;
esac
done
case "$printed_header" in
yes) ${ECHO} ""
${ECHO} "==========================================================================="
exit 1
;;
esac; }
${TEST} $? -eq 0 || exitcode=1
${RM} -fr $tmpdir
;;
*)
${ECHO} "Usage: ./+DIRS ADD|REMOVE|PERMS [metadatadir]"
${ECHO} " ./+DIRS CHECK-ADD|CHECK-REMOVE|CHECK-PERMS [metadatadir]"
;;
esac
exit $exitcode
EOF
${SED} -n "/^\# DIR: /p" ${SELF} >> ./+DIRS
${CHMOD} +x ./+DIRS
;;
esac
|