regpkg revision 1.13 1 1.1 agc #! /bin/sh
2 1.1 agc #
3 1.13 apb # $NetBSD: regpkg,v 1.13 2006/01/28 18:42:23 apb Exp $
4 1.1 agc #
5 1.1 agc # Copyright (c) 2003 Alistair G. Crooks. All rights reserved.
6 1.1 agc #
7 1.1 agc # Redistribution and use in source and binary forms, with or without
8 1.1 agc # modification, are permitted provided that the following conditions
9 1.1 agc # are met:
10 1.1 agc # 1. Redistributions of source code must retain the above copyright
11 1.1 agc # notice, this list of conditions and the following disclaimer.
12 1.1 agc # 2. Redistributions in binary form must reproduce the above copyright
13 1.1 agc # notice, this list of conditions and the following disclaimer in the
14 1.1 agc # documentation and/or other materials provided with the distribution.
15 1.1 agc # 3. All advertising materials mentioning features or use of this software
16 1.1 agc # must display the following acknowledgement:
17 1.1 agc # This product includes software developed by Alistair G. Crooks.
18 1.1 agc # for the NetBSD project.
19 1.1 agc # 4. The name of the author may not be used to endorse or promote
20 1.1 agc # products derived from this software without specific prior written
21 1.1 agc # permission.
22 1.1 agc #
23 1.1 agc # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
24 1.1 agc # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 1.1 agc # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 agc # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
27 1.1 agc # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 agc # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 1.1 agc # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 1.1 agc # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 1.1 agc # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 1.1 agc # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 1.1 agc # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 1.1 agc #
35 1.1 agc
36 1.9 apb # Usage: regpkg [options] set pkgname
37 1.9 apb #
38 1.9 apb # Registers a syspkg in the database directory,
39 1.9 apb # and optionally creates a binary package.
40 1.9 apb #
41 1.9 apb # Options:
42 1.9 apb # -q Quiet.
43 1.9 apb # -v Verbose.
44 1.9 apb # -f Force.
45 1.9 apb # -m Ignore errors from missing files.
46 1.9 apb # -u Update.
47 1.9 apb # -c Use cached information from ${BUILD_INFO_CACHE}.
48 1.9 apb # -d destdir Sets DESTDIR.
49 1.9 apb # -t binpkgdir Create a binary package (in *.tgz format) in the
50 1.9 apb # specified directory. Without this option, a binary
51 1.9 apb # package is not created.
52 1.9 apb # -M metalog Use the specified metalog file to override file
53 1.9 apb # or directory attributes when creating a binary package.
54 1.9 apb # -N etcdir Use the specified directory for passwd and group files.
55 1.9 apb #
56 1.9 apb # When -f is set: If the desired syspkg already exists, it is overwritten.
57 1.9 apb # When -u is set: If the desired syspkg already exists, it might be
58 1.9 apb # overwritten or left alone, depending on whether it's older
59 1.9 apb # or newer than the files that belong to the syspkg.
60 1.9 apb # When neither -u nor -f are set: It's an error for the desired syspkg
61 1.9 apb # to already exist.
62 1.1 agc
63 1.9 apb prog="${0##*/}"
64 1.9 apb toppid=$$
65 1.8 apb rundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/"
66 1.9 apb . "${rundir}/sets.subr"
67 1.9 apb
68 1.9 apb bomb()
69 1.9 apb {
70 1.9 apb #echo "${prog}: bomb: start, toppid=${toppid} \$\$=$$"
71 1.9 apb kill ${toppid} # in case we were invoked from a subshell
72 1.9 apb #echo "${prog}: bomb: killed ${toppid}"
73 1.9 apb exit 1
74 1.9 apb }
75 1.6 erh
76 1.9 apb # A literal newline
77 1.9 apb nl='
78 1.9 apb '
79 1.9 apb # A literal tab
80 1.9 apb tab=' '
81 1.9 apb
82 1.9 apb # Prefixes for error messages, warnings, and important informational
83 1.9 apb # messages.
84 1.9 apb ERROR="${prog}: ERROR: "
85 1.9 apb WARNING="${prog}: WARNING: "
86 1.9 apb NOTE="${prog}: NOTE: "
87 1.9 apb ERRWARN="${ERROR}" # may be changed by "-f" (force) command line flag
88 1.9 apb ERRWARNNOTE="${ERROR}" # may be changed by "-u" (update) command line flag
89 1.1 agc
90 1.9 apb #
91 1.9 apb # All temporary files will go in ${SCRATCH}, which will be deleted on
92 1.9 apb # exit.
93 1.9 apb #
94 1.9 apb SCRATCH="$( ${MKTEMP} -d "/var/tmp/${0##*/}.XXXXXX" )"
95 1.9 apb if [ $? -ne 0 -o \! -d "${SCRATCH}" ]; then
96 1.10 apb echo >&2 "${prog}: Could not create scratch directory."
97 1.9 apb bomb
98 1.1 agc fi
99 1.1 agc
100 1.9 apb #
101 1.9 apb # cleanup() always deletes the SCRATCH directory, and might also
102 1.9 apb # delete other files or directories.
103 1.9 apb #
104 1.9 apb es=0
105 1.9 apb cleanup_must_delete_binpkgfile=false
106 1.9 apb cleanup_must_delete_dbsubdir=false
107 1.9 apb cleanup ()
108 1.9 apb {
109 1.9 apb trap - 0
110 1.9 apb #echo "${prog}: cleanup start"
111 1.9 apb if ${cleanup_must_delete_binpkgfile:-false} && [ -e "${binpkgfile}" ]
112 1.9 apb then
113 1.9 apb echo >&2 "${prog}: deleting partially-created ${binpkgfile}"
114 1.9 apb rm -f "${binpkgfile}"
115 1.9 apb fi
116 1.9 apb if ${cleanup_must_delete_dbsubdir:-false} \
117 1.9 apb && [ -e "${SYSPKG_DB_SUBDIR}" ]
118 1.9 apb then
119 1.9 apb echo >&2 "${prog}: deleting partially-created ${SYSPKG_DB_SUBDIR}"
120 1.9 apb rm -rf "${SYSPKG_DB_SUBDIR}"
121 1.9 apb fi
122 1.9 apb rm -rf "${SCRATCH}"
123 1.9 apb #echo "${prog}: cleanup done, exit ${es}"
124 1.9 apb exit ${es}
125 1.9 apb }
126 1.9 apb trap 'es=128; cleanup' 1 2 3 13 15 # HUP INT QUIT PIPE TERM
127 1.9 apb trap 'es=$?; cleanup' 0 # EXIT
128 1.9 apb
129 1.9 apb #
130 1.9 apb # Parse command line args.
131 1.9 apb #
132 1.9 apb verbose=false
133 1.9 apb verbosity=0
134 1.9 apb quiet=false
135 1.9 apb force=false
136 1.9 apb update=false
137 1.9 apb allowmissing=false
138 1.9 apb DESTDIR="${DESTDIR}"
139 1.9 apb binpkgdir=""
140 1.9 apb metalog=""
141 1.9 apb etcdir=""
142 1.9 apb SYSPKG_DB_TOPDIR=""
143 1.9 apb pkgset=""
144 1.9 apb pkg=""
145 1.9 apb parse_args ()
146 1.9 apb {
147 1.9 apb while [ $# -gt 2 ]; do
148 1.9 apb case "$1" in
149 1.9 apb -q) quiet=true ; verbose=false ;;
150 1.9 apb -v) verbose=true ; quiet=false
151 1.9 apb verbosity=$(( ${verbosity} + 1 ))
152 1.9 apb ;;
153 1.9 apb -f) force=true ;;
154 1.9 apb -u) update=true ;;
155 1.9 apb -m) allowmissing=true ;;
156 1.9 apb -c) # The -c option is ignored. The BUILD_INFO_CACHE
157 1.9 apb # environment variable is used instead.
158 1.9 apb ;;
159 1.9 apb -d) DESTDIR="$2" ; shift ;;
160 1.9 apb -d*) DESTDIR="${1#-?}" ;;
161 1.9 apb -t) binpkgdir="$2" ; shift ;;
162 1.9 apb -t*) binpkgdir="${1#-?}" ;;
163 1.9 apb -M) metalog="$2" ; shift ;;
164 1.9 apb -M*) metalog="${1#-?}" ;;
165 1.9 apb -N) etcdir="$2" ; shift ;;
166 1.9 apb -N*) etcdir="${1#-?}" ;;
167 1.9 apb *) break ;;
168 1.9 apb esac
169 1.9 apb shift
170 1.9 apb done
171 1.9 apb if ${force}; then
172 1.9 apb ERRWARN="${WARNING}"
173 1.9 apb else
174 1.9 apb ERRWARN="${ERROR}"
175 1.9 apb fi
176 1.9 apb if ${update}; then
177 1.9 apb ERRWARNNOTE="${NOTE}"
178 1.9 apb else
179 1.9 apb ERRWARNNOTE="${ERRWARN}"
180 1.9 apb fi
181 1.9 apb DESTDIR="${DESTDIR%/}" # delete trailing "/" if any
182 1.9 apb if [ \! -n "${etcdir}" ]; then
183 1.9 apb etcdir="${DESTDIR}/etc"
184 1.9 apb fi
185 1.9 apb if [ -n "${binpkgdir}" -a \! -d "${binpkgdir}" ]; then
186 1.9 apb echo >&2 "${ERROR}binary pkg directory ${binpkgdir} does not exist"
187 1.9 apb bomb
188 1.9 apb fi
189 1.9 apb #
190 1.9 apb # SYSPKG_DB_TOPDIR is the top level directory for registering
191 1.9 apb # syspkgs. It defaults to ${DESTDIR}/var/db/syspkg, but can be
192 1.9 apb # overridden by environment variables SYSPKG_DBDIR or PKG_DBDIR.
193 1.9 apb #
194 1.9 apb # Note that this corresponds to the default value of PKG_DBDIR
195 1.9 apb # set in .../distrib/syspkg/mk/bsd.syspkg.mk.
196 1.9 apb #
197 1.9 apb SYSPKG_DB_TOPDIR="${SYSPKG_DBDIR:-${PKG_DBDIR:-${DESTDIR}/var/db/syspkg}}"
198 1.9 apb
199 1.9 apb if [ $# -ne 2 ]; then
200 1.9 apb echo "Usage: regpkg [options] set pkgname"
201 1.9 apb bomb
202 1.9 apb fi
203 1.9 apb
204 1.9 apb pkgset="$1"
205 1.9 apb pkg="$2"
206 1.9 apb }
207 1.1 agc
208 1.9 apb #
209 1.9 apb # make_PLIST() creates a skeleton PLIST from the pkgset description.
210 1.9 apb #
211 1.9 apb # The result is stored in the file ${PLIST}.
212 1.9 apb #
213 1.9 apb PLIST="${SCRATCH}/PLIST"
214 1.9 apb make_PLIST ()
215 1.9 apb {
216 1.9 apb if ${verbose} ; then
217 1.9 apb echo "Making PLIST for \"${pkg}\" package (part of ${pkgset} set)"
218 1.9 apb fi
219 1.9 apb prefix="${DESTDIR:-/}"
220 1.9 apb realprefix=/
221 1.9 apb ${HOST_SH} "${rundir}/makeplist" -p "${prefix}" -I "${realprefix}" \
222 1.9 apb "${pkgset}" "${pkg}" \
223 1.9 apb >"${PLIST}" 2>"${SCRATCH}/makeplist-errors"
224 1.9 apb if ${EGREP} -v '^DEBUG:' "${SCRATCH}/makeplist-errors" ; then
225 1.9 apb # "find" invoked from makeplist sometimes reports
226 1.9 apb # errors about missing files or directories, and
227 1.9 apb # makeplist ignores the errors. Catch them here.
228 1.9 apb echo >&2 "${ERROR}makeplist reported errors for ${pkg}:"
229 1.9 apb cat >&2 "${SCRATCH}/makeplist-errors"
230 1.9 apb echo >&2 "${ERROR}see above for errors from makeplist"
231 1.9 apb if ${allowmissing}; then
232 1.9 apb echo >&2 "${prog}: ${NOTE}: ignoring above errors, due to '-m' option."
233 1.9 apb else
234 1.9 apb ${force} || bomb
235 1.9 apb fi
236 1.9 apb fi
237 1.9 apb }
238 1.1 agc
239 1.9 apb #
240 1.9 apb # init_allfiles() converts the PLIST (which contains relative filenames)
241 1.9 apb # into a list of absolute filenames. Directories are excluded from the
242 1.9 apb # result.
243 1.9 apb #
244 1.9 apb # The result is stored in the variable ${allfiles}.
245 1.9 apb #
246 1.9 apb allfiles=''
247 1.9 apb init_allfiles ()
248 1.9 apb {
249 1.9 apb [ -f "${PLIST}" ] || make_PLIST
250 1.9 apb allfiles="$( ${AWK} '
251 1.9 apb BEGIN { destdir = "'"${DESTDIR%/}"'" }
252 1.9 apb /^@cwd/ { prefix = $2; next }
253 1.9 apb /^@dirrm/ { next }
254 1.9 apb { printf("%s%s%s\n", destdir, prefix, $0) }' "${PLIST}" )"
255 1.9 apb }
256 1.1 agc
257 1.9 apb #
258 1.9 apb # init_newestfile() finds the newest file (most recent mtime).
259 1.9 apb #
260 1.9 apb # The result is stored in the variable ${newestfile}.
261 1.9 apb #
262 1.9 apb newestfile=''
263 1.9 apb init_newestfile ()
264 1.9 apb {
265 1.9 apb [ -s "${allfiles}" ] || init_allfiles
266 1.9 apb # We assume no shell special characters in ${allfiles},
267 1.9 apb # and spaces only between file names, not inside file names.
268 1.9 apb # This should be safe, because it has no no user-specified parts.
269 1.9 apb newestfile="$( ${LS} -1dt ${allfiles} | ${SED} '1q' )"
270 1.9 apb }
271 1.1 agc
272 1.9 apb #
273 1.9 apb # Various ways of getting parts of the syspkg version number:
274 1.9 apb #
275 1.9 apb # get_osvers() - get the OS version number from osrelease.sh or $(uname -r),
276 1.9 apb # return it in ${osvers}, and set ${method}.
277 1.9 apb # get_tinyvers() - get the tiny version number from the "versions" file,
278 1.9 apb # and return it in ${tinyvers}. Does not set ${method}.
279 1.9 apb # get_newest_rcsid_date() - get the newest RCS date,
280 1.9 apb # and return it in ${newest}. Does not set ${method}.
281 1.9 apb # get_newest_mtime_date() - get the newest file modification date,
282 1.9 apb # and return it in ${newest}. Does not set ${method}.
283 1.9 apb # get_newest_date() - get date from rcsid or mtime, return it in ${newest},
284 1.9 apb # and set ${method}.
285 1.9 apb #
286 1.9 apb get_osvers ()
287 1.9 apb {
288 1.3 agc if [ -f ../../sys/conf/osrelease.sh ]; then
289 1.8 apb osvers="$(${HOST_SH} ../../sys/conf/osrelease.sh)"
290 1.4 dyoung method=osreleases
291 1.3 agc else
292 1.8 apb osvers="$(${UNAME} -r)"
293 1.3 agc method=uname
294 1.3 agc fi
295 1.9 apb #echo "${osvers}"
296 1.9 apb }
297 1.9 apb get_tinyvers ()
298 1.9 apb {
299 1.9 apb tinyvers="$( ${AWK} '$1 ~ '/"${pkg}"/' { print $2 }' \
300 1.9 apb "${rundir}/versions" )"
301 1.9 apb case "${tinyvers}" in
302 1.9 apb "") tinyvers=0
303 1.9 apb ;;
304 1.9 apb esac
305 1.9 apb #echo "${tinyvers}"
306 1.9 apb }
307 1.9 apb get_newest_rcsid_date()
308 1.9 apb {
309 1.9 apb [ -s "${allfiles}" ] || init_allfiles
310 1.9 apb
311 1.9 apb # Old RCS identifiers might have 2-digit years, so we match both
312 1.9 apb # YY/MM/DD and YYYY/MM/DD. We also try to deal with the Y10K
313 1.9 apb # problem by allowing >4 digit years.
314 1.9 apb newest=0
315 1.9 apb case "${allfiles}" in
316 1.3 agc "") ;;
317 1.9 apb *) newest="$( ${IDENT} ${allfiles} 2>/dev/null | ${AWK} '
318 1.3 agc BEGIN { last = 0 }
319 1.3 agc $2 == "crt0.c,v" { next }
320 1.9 apb NF == 8 && \
321 1.9 apb $4 ~ /^[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9]$/ \
322 1.9 apb { t = "19" $4; gsub("/", "", t);
323 1.9 apb if (t > last) last = t; }
324 1.9 apb NF == 8 && \
325 1.9 apb $4 ~ /^[0-9][0-9][0-9][0-9][0-9]*\/[0-9][0-9]\/[0-9][0-9]$/ \
326 1.9 apb { t = $4; gsub("/", "", t);
327 1.9 apb if (t > last) last = t; }
328 1.9 apb END { print last }' )"
329 1.3 agc method=ident
330 1.3 agc ;;
331 1.3 agc esac
332 1.9 apb #echo "${newest}"
333 1.9 apb }
334 1.9 apb get_newest_mtime_date ()
335 1.9 apb {
336 1.9 apb [ -s "${newestfile}" ] || init_newestfile
337 1.9 apb
338 1.9 apb # We could simplify the awk program to take advantage of the
339 1.9 apb # fact thet it should have exactly one line of input.
340 1.9 apb newest="$( ${ENV_CMD} TZ=UTC LOCALE=C ${LS} -lT "${newestfile}" \
341 1.9 apb | ${AWK} '
342 1.9 apb BEGIN { newest = 0 }
343 1.9 apb {
344 1.9 apb t = $9 "";
345 1.9 apb if ($6 == "Jan") t = t "01";
346 1.9 apb if ($6 == "Feb") t = t "02";
347 1.9 apb if ($6 == "Mar") t = t "03";
348 1.9 apb if ($6 == "Apr") t = t "04";
349 1.9 apb if ($6 == "May") t = t "05";
350 1.9 apb if ($6 == "Jun") t = t "06";
351 1.9 apb if ($6 == "Jul") t = t "07";
352 1.9 apb if ($6 == "Aug") t = t "08";
353 1.9 apb if ($6 == "Sep") t = t "09";
354 1.9 apb if ($6 == "Oct") t = t "10";
355 1.9 apb if ($6 == "Nov") t = t "11";
356 1.9 apb if ($6 == "Dec") t = t "12";
357 1.9 apb if ($7 < 10) t = t "0";
358 1.9 apb t = t $7;
359 1.9 apb #these next two lines add the 24h clock onto the date
360 1.9 apb #gsub(":", "", $8);
361 1.9 apb #t = sprintf("%s.%4.4s", t, $8);
362 1.9 apb if (t > newest) newest = t;
363 1.9 apb }
364 1.9 apb END { print newest }' )"
365 1.9 apb #echo "${newest}"
366 1.9 apb }
367 1.9 apb get_newest_date ()
368 1.9 apb {
369 1.9 apb get_newest_rcsid_date
370 1.9 apb case "${newest}" in
371 1.9 apb ""|0) get_newest_mtime_date
372 1.3 agc method=ls
373 1.3 agc ;;
374 1.9 apb *) method=rcsid
375 1.9 apb ;;
376 1.3 agc esac
377 1.9 apb #echo "${newest}"
378 1.9 apb }
379 1.9 apb
380 1.9 apb #
381 1.9 apb # choose_version_number() chooses the syspkg version number,
382 1.9 apb # by concatenating several components (OS version, syspkg "tiny"
383 1.9 apb # version and date). We end up with something like
384 1.9 apb # osvers="3.99.15", tinyvers="0", newest="20060104",
385 1.9 apb # and t="3.99.15.0.20060104".
386 1.9 apb #
387 1.9 apb # The result is stored in the variables ${t} and ${method}.
388 1.9 apb #
389 1.9 apb method=''
390 1.9 apb t=''
391 1.9 apb choose_version_number ()
392 1.9 apb {
393 1.9 apb get_osvers ; m1="${method}"
394 1.9 apb get_tinyvers # does not set ${method}
395 1.9 apb get_newest_date ; m2="${method}"
396 1.9 apb t="${osvers}.${tinyvers}.${newest}"
397 1.9 apb method="${m1}.${m2}"
398 1.9 apb
399 1.9 apb # print version number that we're using
400 1.9 apb if ${verbose}; then
401 1.9 apb echo "${pkg} - ${t} version using ${method} method"
402 1.9 apb fi
403 1.9 apb }
404 1.9 apb
405 1.9 apb #
406 1.13 apb # init_db_opts() sets the dbfile, dbtype and db_opts variables,
407 1.13 apb # used for accessing the pkgdb.byfile.db database.
408 1.13 apb #
409 1.13 apb init_db_opts ()
410 1.13 apb {
411 1.13 apb dbfile="${SYSPKG_DB_TOPDIR}/pkgdb.byfile.db"
412 1.13 apb dbtype="btree"
413 1.13 apb db_opts=''
414 1.13 apb : ${TARGET_ENDIANNESS:="$( arch_to_endian "${MACHINE_ARCH}" )"}
415 1.13 apb case "${TARGET_ENDIANNESS}" in
416 1.13 apb 4321) db_opts="${db_opts} -E B" # big-endian
417 1.13 apb ;;
418 1.13 apb 1234) db_opts="${db_opts} -E L" # little-endian
419 1.13 apb ;;
420 1.13 apb *)
421 1.13 apb echo >&2 "${WARNING}Unknown or unsupported target endianness"
422 1.13 apb echo >&2 "${NOTE}Using host endianness"
423 1.13 apb ;;
424 1.13 apb esac
425 1.13 apb if ${update} || ${force} ; then
426 1.13 apb # overwriting an existing entry is not an error
427 1.13 apb db_opts="${db_opts} -R"
428 1.13 apb fi
429 1.13 apb if [ ${verbosity} -lt 2 ]; then
430 1.13 apb # don't print all the keys added to the database
431 1.13 apb db_opts="${db_opts} -q"
432 1.13 apb fi
433 1.13 apb }
434 1.13 apb
435 1.13 apb #
436 1.9 apb # print_dir_exec_lines outputs an "@exec install" line for each
437 1.9 apb # directory in ${PLIST}
438 1.9 apb #
439 1.9 apb print_dir_exec_lines ()
440 1.9 apb {
441 1.9 apb local dir uname gname mode
442 1.9 apb local dot_slash_dir
443 1.9 apb local no_dot_dir
444 1.9 apb local word line
445 1.9 apb ${AWK} '/^@dirrm/ { print $2 }' <"${PLIST}" | \
446 1.9 apb ${SORT} | \
447 1.9 apb while read dir ; do
448 1.9 apb # Sanitise the name. ${dir} could be an absolute or
449 1.9 apb # relative name, with or without a leading "./".
450 1.9 apb # ${dot_slash_dir} always has a leading "./" (except when
451 1.9 apb # it's exactly equal to "."). ${no_dot_dir} never has a
452 1.9 apb # leading "." or "/" (except when it's exactly equal to
453 1.9 apb # ".").
454 1.9 apb case "${dir}" in
455 1.9 apb .|./|/) dot_slash_dir=. ;;
456 1.9 apb ./*) dot_slash_dir="${dir}" ;;
457 1.9 apb /*) dot_slash_dir=".${dir}" ;;
458 1.9 apb *) dot_slash_dir="./${dir}" ;;
459 1.9 apb esac
460 1.9 apb no_dot_dir="${dot_slash_dir#./}"
461 1.9 apb # Get the directory's owner, group, and mode
462 1.9 apb # from the live file system, or let it be overridden
463 1.9 apb # by the metalog.
464 1.9 apb eval "$( ${STAT} -f 'uname=%Su gname=%Sg mode=%#OLp' \
465 1.9 apb "${DESTDIR}/${dot_slash_dir}" )"
466 1.9 apb if [ -n "${metalog}" ]; then
467 1.9 apb line="$( echo "${dot_slash_dir}" | \
468 1.9 apb ${AWK} -f "${rundir}/join.awk" \
469 1.9 apb /dev/stdin "${metalog}" )"
470 1.9 apb for word in ${line} ; do
471 1.9 apb case "${word}" in
472 1.9 apb uname=*|gname=*|mode=*) eval "${word}" ;;
473 1.9 apb esac
474 1.9 apb done
475 1.9 apb fi
476 1.9 apb # XXX: Work around yet another pkg_add bug: @cwd lines
477 1.9 apb # do not actually cause the working directory to change,
478 1.9 apb # so file names in @exec lines need to be qualified by
479 1.9 apb # %D, which (in our case, since we know there's an
480 1.9 apb # "@cwd /" line) will be the dir name passed to
481 1.9 apb # "pkg_add -p PREFIX".
482 1.9 apb case "${no_dot_dir}" in
483 1.9 apb .) d="%D" ;;
484 1.9 apb *) d="%D/${no_dot_dir}" ;;
485 1.9 apb esac
486 1.9 apb cat <<EOF
487 1.9 apb @exec install -d -o ${uname} -g ${gname} -m ${mode} ${d}
488 1.9 apb EOF
489 1.9 apb done
490 1.9 apb }
491 1.2 jwise
492 1.9 apb #
493 1.9 apb # register_syspkg() registers the syspkg in ${SYSPKG_DB_TOPDIR}.
494 1.9 apb # This involves creating the subdirectory ${SYSPKG_DB_SUBDIR}
495 1.9 apb # and populating it with several files.
496 1.9 apb #
497 1.9 apb register_syspkg ()
498 1.9 apb {
499 1.9 apb cleanup_must_delete_dbsubdir=true
500 1.9 apb [ -n "${SYSPKG_DB_SUBDIR}" ] || bomb
501 1.9 apb mkdir -p "${SYSPKG_DB_SUBDIR}"
502 1.9 apb
503 1.9 apb #
504 1.9 apb # Guess what versions of other packages to depend on.
505 1.9 apb #
506 1.9 apb # If we are using the OS version as part of the pkg
507 1.9 apb # version, then depend on any version ">=${osvers}". For
508 1.9 apb # example, etc-sys-etc-1.6ZI.0.20040206 might depend on
509 1.9 apb # base-sys-root>=1.6ZI.
510 1.9 apb #
511 1.9 apb # Failing that, depend on any version "-[0-9]*".
512 1.9 apb #
513 1.9 apb # XXX: We could extend the format of the "deps" file to carry
514 1.9 apb # this sort of information, so we wouldn't have to guess.
515 1.9 apb #
516 1.9 apb case "${t}" in
517 1.9 apb ${osvers}.*) depversion=">=${osvers}" ;;
518 1.9 apb *) depversion="-[0-9]*" ;;
519 1.9 apb esac
520 1.9 apb
521 1.9 apb #
522 1.9 apb # Add the dependencies.
523 1.9 apb #
524 1.9 apb # We always add a "@pkgdep" line for each prerequisite package.
525 1.9 apb #
526 1.9 apb # If the prerequisite pkg is already registered (as it should be
527 1.9 apb # if our caller is doing things in the right order), then we put
528 1.9 apb # its exact version number in a "@blddep" line.
529 1.9 apb #
530 1.9 apb ${AWK} '$1 ~ '/"${pkg}"/' { print $2 }' "${rundir}/deps" | ${SORT} | \
531 1.9 apb while read depname ; do
532 1.9 apb # ${pkgdepglob} is a shell glob pattern that should match
533 1.9 apb # any version of a pkg. ${pkgdep} uses the special syntax
534 1.9 apb # for pkg dependencies, and is not usable as a shell
535 1.9 apb # glob pattern.
536 1.9 apb pkgdepglob="${depname}-[0-9]*"
537 1.9 apb pkgdep="${depname}${depversion}"
538 1.9 apb echo "@pkgdep ${pkgdep}"
539 1.9 apb blddep="$( cd "${SYSPKG_DB_TOPDIR}" && echo ${pkgdepglob} \
540 1.9 apb || bomb )"
541 1.9 apb case "${blddep}" in
542 1.9 apb *\*) # pkgdepglob did not match anything
543 1.9 apb echo >&2 "${WARNING}${pkg} depends on '${pkgdep}' but there is no matching syspkg in ${SYSPKG_DB_TOPDIR}"
544 1.9 apb ;;
545 1.9 apb *\ *) # pkgdepglob matched more than once.
546 1.9 apb echo >&2 "${ERRWARN}${pkg} depends on '${pkgdep}' but there are multiple matching syspkgs in ${SYSPKG_DB_TOPDIR}"
547 1.9 apb ${force} || bomb
548 1.9 apb # If ${force} is set, then assume that the last
549 1.9 apb # match is the most recent.
550 1.9 apb # XXX: This might be wrong, because of
551 1.9 apb # differences between lexical sorting and
552 1.9 apb # numeric sorting.
553 1.9 apb lastmatch="${blddep##* }"
554 1.9 apb echo "@blddep ${lastmatch}"
555 1.9 apb ;;
556 1.9 apb *) # exactly one match.
557 1.9 apb # XXX: We ignore the possibility that the
558 1.9 apb # version we found via ${pkgdepglob} might not
559 1.9 apb # satisfy ${pkgdep}. We could conceivably use
560 1.9 apb # "pkg_admin pmatch" to check, but that's not a
561 1.9 apb # host tool so we can't assume that it will be
562 1.9 apb # available.
563 1.9 apb echo "@blddep ${blddep}"
564 1.9 apb ;;
565 1.9 apb esac
566 1.9 apb done >>"${PLIST}"
567 1.9 apb
568 1.9 apb # create the comment (should be one line)
569 1.9 apb comment="$( ${AWK} '$1 ~ '/"${pkg}"/' \
570 1.9 apb { print substr($0, length($1) + 2) }' \
571 1.9 apb "${rundir}/comments" )"
572 1.9 apb case "${comment}" in
573 1.9 apb "") echo >&2 "${WARNING}no comment for \"${pkg}\" (using placeholder)"
574 1.9 apb comment="System package for ${pkg}"
575 1.9 apb ;;
576 1.9 apb *"${nl}"*)
577 1.9 apb echo >&2 "${ERRWARN}multi-line comment for \"${pkg}\""
578 1.9 apb ${force} || bomb
579 1.9 apb ;;
580 1.9 apb esac
581 1.9 apb echo "${comment}" > "${SYSPKG_DB_SUBDIR}/+COMMENT"
582 1.1 agc
583 1.9 apb # create the description (could be multiple lines)
584 1.9 apb descr="$( ${AWK} '$1 ~ '/"${pkg}"/' {
585 1.9 apb print substr($0, length($1) + 2) }' \
586 1.9 apb "${rundir}/descrs" )"
587 1.9 apb case "${descr}" in
588 1.9 apb "") echo >&2 "${WARNING}no description for \"${pkg}\" (re-using comment)" 2>&1
589 1.9 apb descr="${comment}"
590 1.9 apb ;;
591 1.9 apb esac
592 1.9 apb echo "${descr}" > "${SYSPKG_DB_SUBDIR}/+DESC"
593 1.9 apb ${PRINTF} "\nHomepage:\nhttp://www.NetBSD.org/\n" >> "${SYSPKG_DB_SUBDIR}/+DESC"
594 1.1 agc
595 1.9 apb # create the build information
596 1.9 apb if [ x"${BUILD_INFO_CACHE}" = x ]; then
597 1.9 apb {
598 1.9 apb # These variables describe the build
599 1.9 apb # environment, not the target.
600 1.9 apb echo "OPSYS=$(${UNAME} -s)"
601 1.9 apb echo "OS_VERSION=$(${UNAME} -r)"
602 1.9 apb ${MAKE} -f- all <<EOF
603 1.4 dyoung .include <bsd.own.mk>
604 1.4 dyoung all:
605 1.4 dyoung @echo OBJECT_FMT=${OBJECT_FMT}
606 1.4 dyoung @echo MACHINE_ARCH=${MACHINE_ARCH}
607 1.4 dyoung @echo MACHINE_GNU_ARCH=${MACHINE_GNU_ARCH}
608 1.4 dyoung EOF
609 1.9 apb # XXX: what's the point of reporting _PKGTOOLS_VER
610 1.9 apb # when we roll everything by hand without using
611 1.9 apb # the pkg tools?
612 1.9 apb echo "_PKGTOOLS_VER=$(${PKG_CREATE} -V)"
613 1.9 apb } > "${SYSPKG_DB_SUBDIR}/+BUILD_INFO"
614 1.9 apb else
615 1.9 apb cp "${BUILD_INFO_CACHE}" "${SYSPKG_DB_SUBDIR}/+BUILD_INFO"
616 1.9 apb fi
617 1.9 apb
618 1.9 apb # test for attributes
619 1.9 apb args=""
620 1.9 apb attrs="$( ${AWK} '$1 ~ '/"${pkg}"/' { \
621 1.9 apb print substr($0, length($1) + 2) }' \
622 1.9 apb "${rundir}/attrs" )"
623 1.9 apb for a in "${attrs}"; do
624 1.9 apb case "${attrs}" in
625 1.9 apb "") ;;
626 1.9 apb preserve)
627 1.9 apb echo "${pkg}-${t}" >"${SYSPKG_DB_SUBDIR}/+PRESERVE"
628 1.9 apb args="${args} -n ${SYSPKG_DB_SUBDIR}/+PRESERVE"
629 1.9 apb ;;
630 1.9 apb esac
631 1.9 apb done
632 1.9 apb
633 1.9 apb #
634 1.9 apb # Create ${SYSPKGSIR}/+CONTENTS from ${PLIST}, by adding an
635 1.9 apb # "@name" line and a lot of "@comment MD5:" lines.
636 1.9 apb #
637 1.9 apb {
638 1.13 apb rcsid='$NetBSD: regpkg,v 1.13 2006/01/28 18:42:23 apb Exp $'
639 1.9 apb utcdate="$( ${ENV_CMD} TZ=UTC LOCALE=C \
640 1.9 apb ${DATE} '+%Y-%m-%d %H:%M' )"
641 1.9 apb user="${USER:-root}"
642 1.9 apb host="$( ${HOSTNAME} )"
643 1.9 apb echo "@name ${pkg}-${t}"
644 1.9 apb echo "@comment Packaged at ${utcdate} UTC by ${user}@${host}"
645 1.9 apb echo "@comment Packaged using ${prog} ${rcsid}"
646 1.9 apb # XXX: "option extract-in-place" might help to get
647 1.9 apb # pkg_add to create directories.
648 1.9 apb # XXX: no, it doesn't work. Yet another pkg_add bug.
649 1.9 apb ## echo "@option extract-in-place"
650 1.9 apb # Move the @pkgdep and @blddep lines up, so that
651 1.9 apb # they are easy to see when people do "less
652 1.9 apb # ${DESTDIR}/var/db/syspkg/*/+CONTENTS".
653 1.9 apb ${EGREP} '^(@pkgdep|@blddep)' "${PLIST}" || true
654 1.9 apb # Now do the remainder of the file.
655 1.9 apb while read line ; do
656 1.9 apb case "${line}" in
657 1.9 apb @pkgdep*|@blddep*)
658 1.9 apb # already handled by grep above
659 1.9 apb ;;
660 1.9 apb @cwd*)
661 1.9 apb # There should be exactly one @cwd line.
662 1.9 apb # Just after it, add an "@exec mkdir"
663 1.9 apb # line for every directory. This is to
664 1.9 apb # work around a pkg-add bug (see
665 1.9 apb # <http://mail-index.NetBSD.org/tech-pkg/2003/12/11/0018.html>)
666 1.9 apb echo "${line}"
667 1.9 apb print_dir_exec_lines
668 1.9 apb ;;
669 1.9 apb @*)
670 1.9 apb # just pass through all other @foo lines
671 1.9 apb echo "${line}"
672 1.9 apb ;;
673 1.9 apb *)
674 1.9 apb # This should be a file name. Pass it
675 1.9 apb # through, and append "@comment MD5:".
676 1.9 apb # XXX why not SHA256 ?
677 1.9 apb echo "${line}"
678 1.9 apb file="${DESTDIR}${line}"
679 1.9 apb if [ -f "${file}" -a -r "${file}" ];
680 1.9 apb then
681 1.9 apb md5sum="$( ${CKSUM} -n -m "${file}" \
682 1.9 apb | ${AWK} '{print $1}'
683 1.9 apb )"
684 1.9 apb echo "@comment MD5:${md5sum}"
685 1.9 apb fi
686 1.9 apb ;;
687 1.9 apb esac
688 1.9 apb done <"${PLIST}"
689 1.9 apb } >"${SYSPKG_DB_SUBDIR}/+CONTENTS"
690 1.9 apb
691 1.9 apb #
692 1.9 apb # Update ${SYSPKG_DB_TOPDIR}/pkgdb.byfile.db.
693 1.9 apb #
694 1.9 apb {
695 1.13 apb init_db_opts # sets dbfile, dbtype, and db_opts
696 1.9 apb
697 1.9 apb # Transform ${PLIST} into a form to be used as keys in
698 1.9 apb # ${dbfile}. The results look like absolute paths,
699 1.9 apb # but they are really relative to ${DESTDIR}.
700 1.9 apb #
701 1.9 apb # "@dirrm ." -> "/"
702 1.9 apb # "@dirrm foo/bar" -> "/foo/bar"
703 1.9 apb # "@dirrm ./foo/bar" -> "/foo/bar"
704 1.9 apb # "foo/bar/baz" -> "/foo/bar/baz"
705 1.9 apb # "./foo/bar/baz" -> "/foo/bar/baz"
706 1.9 apb #
707 1.9 apb dblist="${SCRATCH}/dblist"
708 1.9 apb ${AWK} '/^@dirrm \.\// {gsub("^.", "", $2); print $2; next}
709 1.9 apb /^@dirrm \.$/ {print "/"; next}
710 1.9 apb /^@dirrm/ {print "/" $2; next}
711 1.9 apb /^@/ {next}
712 1.9 apb /^\.\// {gsub("^.", "", $0); print $0; next}
713 1.9 apb /./ {print "/" $0; next}' \
714 1.9 apb <"${PLIST}" >"${dblist}"
715 1.9 apb # Add all the path names to the database.
716 1.9 apb ${AWK} '{print $1 "\t" "'"${pkg}-${t}"'"}' <"${dblist}" \
717 1.9 apb | ${DB} -w ${db_opts} -F "${tab}" -f - "${dbtype}" "${dbfile}"
718 1.9 apb }
719 1.9 apb
720 1.9 apb if ${verbose} ; then
721 1.9 apb echo "Registered ${pkg}-${t} in ${SYSPKG_DB_TOPDIR}"
722 1.9 apb elif ! ${quiet} ; then
723 1.9 apb echo "Registered ${pkg}-${t}"
724 1.9 apb fi
725 1.9 apb
726 1.9 apb cleanup_must_delete_dbsubdir=false
727 1.9 apb }
728 1.9 apb
729 1.9 apb #
730 1.9 apb # create_syspkg_tgz() creates the *.tgz file for the package.
731 1.9 apb #
732 1.9 apb # The output file is ${binpkgdir}/${pkg}-${t}.tgz.
733 1.9 apb #
734 1.9 apb create_syspkg_tgz ()
735 1.9 apb {
736 1.9 apb #
737 1.9 apb # pkg_create does not understand metalog files, so we have to
738 1.9 apb # use pax directly.
739 1.9 apb #
740 1.9 apb # We create two specfiles: specfile_overhead describes the
741 1.9 apb # special files that are part of the package system's metadata
742 1.9 apb # (+CONTENTS, +COMMENT, +DESCR, and more); and specfile_payload
743 1.9 apb # describes the files and directories that we actually want as
744 1.9 apb # part of the package's payload.
745 1.9 apb #
746 1.9 apb # We then use the specfiles to create a compressed tarball that
747 1.9 apb # contains both the overhead files and the payload files.
748 1.9 apb #
749 1.9 apb # There's no trivial way to get a single pax run to do
750 1.9 apb # everything we want, so we run pax twice, with a different
751 1.9 apb # working directory and a different specfile each time.
752 1.9 apb #
753 1.9 apb # We could conceivably make clever use of pax's "-s" option to
754 1.9 apb # get what we want from a single pax run with a single (more
755 1.9 apb # complicated) specfile, but the extra trouble doesn't seem
756 1.9 apb # warranted.
757 1.9 apb #
758 1.9 apb cleanup_must_delete_binpkgfile=true
759 1.9 apb specfile_overhead="${SCRATCH}/spec_overhead"
760 1.9 apb specfile_payload="${SCRATCH}/spec_payload"
761 1.9 apb tarball_uncompressed="${SCRATCH}/tarball_uncompressed"
762 1.9 apb
763 1.9 apb # Create a specfile for all the overhead files (+CONTENTS and
764 1.9 apb # friends).
765 1.9 apb {
766 1.9 apb plusnames_first="${SCRATCH}/plusnames_first"
767 1.9 apb plusnames_rest="${SCRATCH}/plusnames_rest"
768 1.9 apb
769 1.9 apb # Ensure that the first few files are in the same order
770 1.9 apb # that "pkg_create" would have used, just in case anything
771 1.9 apb # depends on that. Other files in alphabetical order.
772 1.9 apb SHOULD_BE_FIRST="+CONTENTS +COMMENT +DESC"
773 1.9 apb (
774 1.9 apb cd "${SYSPKG_DB_SUBDIR}" || bomb
775 1.9 apb for file in ${SHOULD_BE_FIRST}; do
776 1.9 apb [ -e "./${file}" ] && echo "${file}"
777 1.9 apb done >"${plusnames_first}"
778 1.9 apb ${LS} -1 | ${FGREP} -v -f "${plusnames_first}" \
779 1.9 apb >"${plusnames_rest}" \
780 1.9 apb || true
781 1.9 apb )
782 1.9 apb
783 1.9 apb # Convert the file list to specfile format, and override the
784 1.9 apb # uid/gid/mode.
785 1.9 apb {
786 1.9 apb echo ". optional type=dir"
787 1.9 apb ${AWK} '{print "./" $0 " type=file uid=0 gid=0 mode=0444"
788 1.9 apb }' "${plusnames_first}" "${plusnames_rest}"
789 1.9 apb } >"${specfile_overhead}"
790 1.9 apb }
791 1.9 apb
792 1.9 apb # Create a specfile for the payload of the package.
793 1.9 apb {
794 1.9 apb spec1="${SCRATCH}/spec1"
795 1.9 apb spec2="${SCRATCH}/spec2"
796 1.9 apb
797 1.9 apb # Transform ${PLIST} into simple specfile format:
798 1.9 apb #
799 1.11 apb # "@dirrm ." -> ". type=dir"
800 1.11 apb # "@dirrm foo/bar" -> "./foo/bar type=dir"
801 1.11 apb # "@dirrm ./foo/bar" -> "./foo/bar type=dir"
802 1.9 apb # "foo/bar/baz" -> "./foo/bar/baz"
803 1.9 apb # "./foo/bar/baz" -> "./foo/bar/baz"
804 1.9 apb #
805 1.9 apb # Ignores @cwd lines. This should be safe, given how
806 1.9 apb # makeplist works.
807 1.11 apb ${AWK} '/^@dirrm \.\// {print $2 " type=dir" ; next}
808 1.11 apb /^@dirrm \.$/ {print ". type=dir"; next}
809 1.11 apb /^@dirrm/ {print "./" $2 " type=dir" ; next}
810 1.9 apb /^@/ {next}
811 1.9 apb /^\.\// {print $0; next}
812 1.9 apb /./ {print "./" $0; next}' \
813 1.9 apb <"${PLIST}" >"${spec1}"
814 1.9 apb
815 1.9 apb # If metalog was specified, attributes from metalog override
816 1.9 apb # attributes in the file system. We also fake up an
817 1.9 apb # entry for the ./etc/mtree/set.${pkgset} file.
818 1.9 apb {
819 1.9 apb if [ -n "${metalog}" ]; then
820 1.9 apb ${AWK} -f "${rundir}/join.awk" \
821 1.9 apb "${spec1}" "${metalog}"
822 1.9 apb ${AWK} -f "${rundir}/join.awk" \
823 1.9 apb "${spec1}" /dev/stdin <<EOF
824 1.9 apb ./etc/mtree/set.${pkgset} type=file mode=0444 uname=root gname=wheel
825 1.9 apb EOF
826 1.9 apb else
827 1.9 apb cat "${spec1}"
828 1.9 apb fi
829 1.9 apb } >"${spec2}"
830 1.9 apb
831 1.9 apb #
832 1.9 apb # If a file or directory to was mentioned explicitly
833 1.9 apb # in ${PLIST} but not mentioned in ${metalog}, then the
834 1.9 apb # file or directory will not be mentioned in ${spec2}.
835 1.9 apb # This is an error, and means that the metalog was
836 1.9 apb # not built correctly.
837 1.9 apb #
838 1.9 apb if [ -n "${metalog}" ]; then
839 1.9 apb names1="${SCRATCH}/names1"
840 1.9 apb names2="${SCRATCH}/names2"
841 1.9 apb ${AWK} '{print $1}' <"${spec1}" | ${SORT} >"${names1}"
842 1.9 apb ${AWK} '{print $1}' <"${spec2}" | ${SORT} >"${names2}"
843 1.9 apb if ${FGREP} -v -f "${names2}" "${spec1}" >/dev/null
844 1.9 apb then
845 1.9 apb cat >&2 <<EOM
846 1.9 apb ${ERRWARN}The metalog file (${metalog}) does not
847 1.9 apb contain entries for the following files or directories
848 1.9 apb which should be part of the ${pkg} syspkg:
849 1.9 apb EOM
850 1.9 apb ${FGREP} -v -f "${names2}" "${spec1}" >&2
851 1.9 apb ${force} || bomb
852 1.9 apb fi
853 1.9 apb if ${FGREP} -v -f "${names1}" "${spec2}" >/dev/null
854 1.9 apb then
855 1.9 apb cat >&2 <<EOM
856 1.9 apb ${ERRWARN}The following lines are in the metalog file
857 1.9 apb (${metalog}), and the corresponding files or directories
858 1.9 apb should be in the ${pkg} syspkg, but something is wrong:
859 1.9 apb EOM
860 1.9 apb ${FGREP} -v -f "${names1}" "${spec2}" >&2
861 1.9 apb bomb
862 1.9 apb fi
863 1.9 apb fi
864 1.9 apb
865 1.9 apb # Add lines (tagged "optional") for any implicit directories.
866 1.9 apb #
867 1.9 apb # For example, if we have a file ./foo/bar/baz, then we add
868 1.9 apb # "./foo/bar optional type=dir", "./foo optional type=dir",
869 1.9 apb # and ". optional type=dir", unless those directories were
870 1.9 apb # already mentioned explicitly.
871 1.9 apb #
872 1.9 apb ${AWK} -f "${rundir}/getdirs.awk" "${spec2}" \
873 1.9 apb | ${SORT} -u >"${specfile_payload}"
874 1.9 apb }
875 1.9 apb
876 1.9 apb # Use two pax invocations followed by gzip to create
877 1.9 apb # the tgz file.
878 1.9 apb #
879 1.9 apb # Remove any leading "./" from path names, because that
880 1.9 apb # could confuse tools that work with binary packages.
881 1.9 apb (
882 1.9 apb cd "${SYSPKG_DB_SUBDIR}" && \
883 1.9 apb ${PAX} -O -w -d -N"${etcdir}" -M '-s,^\./,,' \
884 1.9 apb -f "${tarball_uncompressed}" \
885 1.9 apb <"${specfile_overhead}" \
886 1.9 apb || bomb
887 1.9 apb )
888 1.9 apb (
889 1.9 apb cd "${DESTDIR:-/}" && \
890 1.9 apb ${PAX} -O -w -d -N"${etcdir}" -M '-s,^\./,,' \
891 1.9 apb -a -f "${tarball_uncompressed}" \
892 1.9 apb <"${specfile_payload}" \
893 1.9 apb || bomb
894 1.9 apb )
895 1.9 apb ${GZIP_CMD} -9 <"${tarball_uncompressed}" >"${binpkgfile}" || bomb
896 1.9 apb
897 1.9 apb # (Extra space is to make message line up with "Registered" message.)
898 1.9 apb if ${verbose} ; then
899 1.9 apb echo " Packaged ${binpkgfile}"
900 1.9 apb elif ! ${quiet} ; then
901 1.9 apb echo " Packaged ${binpkgfile##*/}"
902 1.9 apb fi
903 1.9 apb
904 1.9 apb cleanup_must_delete_binpkgfile=false
905 1.9 apb
906 1.9 apb }
907 1.9 apb
908 1.9 apb #
909 1.9 apb # do_register_syspkg() registers the syspkg if appropriate.
910 1.9 apb #
911 1.9 apb # If SYSPKG_DB_SUBDIR already exists, that might be an error, depending
912 1.9 apb # on ${force} and ${update} flags.
913 1.9 apb #
914 1.9 apb do_register_syspkg ()
915 1.9 apb {
916 1.9 apb # Check that necessary variables are defined
917 1.9 apb [ -n "${SYSPKG_DB_TOPDIR}" ] || bomb
918 1.9 apb [ -n "${SYSPKG_DB_SUBDIR}" ] || bomb
919 1.9 apb
920 1.9 apb # Create SYSPKG_DB_TOPDIR if necessary
921 1.9 apb [ -d "${SYSPKG_DB_TOPDIR}" ] || mkdir -p "${SYSPKG_DB_TOPDIR}" || bomb
922 1.9 apb
923 1.13 apb # A function to delete db entries referring to any version of ${pkg}
924 1.13 apb delete_old_db_entries ()
925 1.13 apb {
926 1.13 apb init_db_opts # sets dbfile, dbtype, and db_opts
927 1.13 apb dblist="${SCRATCH}/dblist"
928 1.13 apb ${DB} ${db_opts} -O "${tab}" "${dbtype}" "${dbfile}" \
929 1.13 apb | ${AWK} -F "${tab}" '$2 ~ /^'"${pkg}"'-[0-9]/ { print $1 }' \
930 1.13 apb >"${dblist}"
931 1.13 apb ${DB} -d ${db_opts} -f "${dblist}" "${dbtype}" "${dbfile}"
932 1.13 apb }
933 1.13 apb
934 1.13 apb # A function to delete any old version of ${pkg}
935 1.13 apb delete_old_pkg ()
936 1.9 apb {
937 1.13 apb pattern="${pkg}-[0-9]*"
938 1.13 apb matches="$( cd "${SYSPKG_DB_TOPDIR}" && echo ${pattern} \
939 1.13 apb || bomb )"
940 1.13 apb echo >&2 "${NOTE}deleting old pkg (${matches})"
941 1.9 apb cleanup_must_delete_dbsubdir=true
942 1.13 apb delete_old_db_entries
943 1.13 apb ( cd "${SYSPKG_DB_TOPDIR}" && rm -rf ${matches} )
944 1.9 apb }
945 1.9 apb
946 1.9 apb # Check whether another version of ${pkg} is already registered.
947 1.9 apb pattern="${pkg}-[0-9]*"
948 1.9 apb matches="$( cd "${SYSPKG_DB_TOPDIR}" && echo ${pattern} || bomb )"
949 1.9 apb case "${matches}" in
950 1.9 apb *\*) ;; # wildcard did not match anything
951 1.9 apb "${pkg}-${t}") ;; # exact match
952 1.13 apb *) echo >&2 "${ERRWARNNOTE}another version of ${pkg} is already registered"
953 1.13 apb ${verbose} && echo >&2 " in ${SYSPKG_DB_TOPDIR}"
954 1.13 apb ${verbose} && echo >&2 " (while registering ${pkg}-${t})"
955 1.13 apb ${force} || ${update} || bomb
956 1.13 apb delete_old_pkg
957 1.9 apb ;;
958 1.9 apb esac
959 1.9 apb
960 1.9 apb # Check whether the desired version of ${pkg} is already registered,
961 1.9 apb # and create it if appropriate.
962 1.9 apb if [ -d "${SYSPKG_DB_SUBDIR}" ]; then
963 1.9 apb echo >&2 "${ERRWARNNOTE}${pkg}-${t} is already registered"
964 1.9 apb ${verbose} && echo >&2 " in ${SYSPKG_DB_TOPDIR}"
965 1.9 apb if ${force}; then
966 1.13 apb delete_old_pkg
967 1.13 apb register_syspkg
968 1.9 apb elif ${update}; then
969 1.9 apb #
970 1.9 apb # If all files in SYSPKG_DB_SUBDIR are newer
971 1.9 apb # than all files in the pkg, then do nothing.
972 1.9 apb # Else delete and re-register the pkg.
973 1.9 apb #
974 1.9 apb [ -n "${newestfile}" ] || init_newestfile
975 1.9 apb if [ -n "${newestfile}" ]; then
976 1.9 apb case "$( ${FIND} "${SYSPKG_DB_SUBDIR}" -type f \
977 1.9 apb ! -newer "${newestfile}" -print )" \
978 1.9 apb in
979 1.9 apb "") ;;
980 1.13 apb *)
981 1.13 apb echo >&2 "${NOTE}some files are newer but pkg version is unchanged"
982 1.13 apb delete_old_pkg
983 1.13 apb register_syspkg
984 1.13 apb ;;
985 1.9 apb esac
986 1.9 apb
987 1.9 apb else
988 1.9 apb # No files in the pkg? (This could happen
989 1.9 apb # if a pkg contains only directories.)
990 1.13 apb # Do nothing (keep the already-registered pkg).
991 1.9 apb fi
992 1.9 apb else
993 1.9 apb bomb
994 1.9 apb fi
995 1.9 apb else
996 1.9 apb register_syspkg
997 1.9 apb fi
998 1.9 apb }
999 1.9 apb
1000 1.9 apb #
1001 1.9 apb # do_create_syspkg_tgz() creates the the binary pkg (*.tgz) if
1002 1.9 apb # appropriate.
1003 1.9 apb #
1004 1.9 apb # If binpkgfile already exists, that might be an error, depending on
1005 1.9 apb # ${force} and ${update} flags.
1006 1.9 apb #
1007 1.9 apb do_create_syspkg_tgz ()
1008 1.9 apb {
1009 1.9 apb [ -n "${binpkgfile}" ] || bomb
1010 1.9 apb
1011 1.9 apb delete_and_recreate ()
1012 1.9 apb {
1013 1.9 apb echo >&2 "${ERRWARNNOTE}deleting and re-creating ${pkg}-${t}.tgz"
1014 1.9 apb rm -f "${binpkgfile}"
1015 1.9 apb create_syspkg_tgz
1016 1.9 apb }
1017 1.9 apb
1018 1.9 apb # Check whether another version of ${pkg} already exists.
1019 1.9 apb pattern="${pkg}-[0-9]*"
1020 1.9 apb matches="$( cd "${binpkgdir}" && echo ${pattern} || bomb )"
1021 1.9 apb case "${matches}" in
1022 1.9 apb *\*) ;; # wildcard did not match anything
1023 1.9 apb "${pkg}-${t}.tgz") ;; # exact match
1024 1.13 apb *) echo >&2 "${ERRWARNNOTE}another version of ${pkg} binary pkg already exists"
1025 1.13 apb ${verbose} && echo >&2 " in ${binpkgdir}"
1026 1.13 apb ${verbose} && echo >&2 " (while creating ${pkg}-${t}.tgz)"
1027 1.13 apb # If neither force nor update, this is a fatal error.
1028 1.13 apb # If force but not update, then leave old .tgz in place.
1029 1.13 apb # If update, then delete the old .tgz.
1030 1.13 apb ${force} || ${update} || bomb
1031 1.13 apb if ${update}; then
1032 1.13 apb echo >&2 "${NOTE}deleting old binary pkg (${matches})"
1033 1.13 apb ( cd "${binpkgdir}" && rm -f ${matches} || bomb )
1034 1.13 apb fi
1035 1.9 apb ;;
1036 1.9 apb esac
1037 1.9 apb
1038 1.9 apb # Check whether the desired version of ${pkg} already exists,
1039 1.9 apb # and create it if appropriate.
1040 1.9 apb if [ -e "${binpkgfile}" ]; then
1041 1.9 apb echo >&2 "${ERRWARNNOTE}${pkg}-${t}.tgz already exists"
1042 1.9 apb ${verbose} && echo >&2 " in ${binpkgdir}"
1043 1.9 apb if ${force}; then
1044 1.9 apb delete_and_recreate
1045 1.9 apb elif ${update}; then
1046 1.9 apb #
1047 1.9 apb # If all files in SYSPKG_DB_SUBDIR are older
1048 1.9 apb # than ${binpkgfile}, then do nothing.
1049 1.9 apb # Else delete and re-create the tgz.
1050 1.9 apb #
1051 1.9 apb case "$( ${FIND} "${SYSPKG_DB_SUBDIR}" -type f \
1052 1.9 apb -newer "${binpkgfile}" -print )" \
1053 1.9 apb in
1054 1.9 apb "") ;;
1055 1.9 apb *) delete_and_recreate ;;
1056 1.9 apb esac
1057 1.9 apb else
1058 1.9 apb bomb
1059 1.9 apb fi
1060 1.9 apb else
1061 1.9 apb create_syspkg_tgz
1062 1.9 apb fi
1063 1.9 apb }
1064 1.9 apb
1065 1.9 apb ####################
1066 1.9 apb # begin main program
1067 1.9 apb
1068 1.9 apb parse_args ${1+"$@"}
1069 1.9 apb make_PLIST
1070 1.9 apb choose_version_number
1071 1.9 apb SYSPKG_DB_SUBDIR="${SYSPKG_DB_TOPDIR}/${pkg}-${t}"
1072 1.9 apb do_register_syspkg
1073 1.9 apb if [ -n "${binpkgdir}" ]; then
1074 1.9 apb binpkgfile="${binpkgdir}/${pkg}-${t}.tgz"
1075 1.9 apb do_create_syspkg_tgz
1076 1.5 dyoung fi
1077 1.1 agc
1078 1.9 apb exit 0
1079