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