2 # ==============================================================================
3 # portsreinstall library script
4 # - Wrappers for hiding version differences in the Ports/Packages system -
5 # Copyright (C) 2013-2014 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
9 # ============= Variables =============
10 PKGSYS_USE_PKGNG=yes # no: legacy pkg_* tools, yes: the new generation package (pkgng)
11 PKGSYS_CMD_PKG_INFO='pkg info' # Corresponding command for pkg_info
12 PKGSYS_CMD_PKG_CREATE='pkg create' # Corresponding command for pkg_create
13 PKGSYS_CMD_PKG_DELETE='pkg delete' # Corresponding command for pkg_delete
14 PKGSYS_CMD_PKG_ADD='pkg add' # Corresponding command for pkg_add
15 PKGSYS_AVR_REFETCH_TIMES_PER_SITE=1 # Average number (integer) of retrials for retrieving package or distfiles per mirror site
16 PKGSYS_AVR_REFETCH_TIMES_FOR_CHKSUMERR=2 # Number (integer) of retrials for check sum error in retrieving a package
18 # ============= Check implementation of the ports tree =============
19 pkgsys_chk_ports_tree_implementation ()
22 if [ ! -d "${PORTSDIR}" ]
24 message_echo "ERROR: Ports directory ${PORTSDIR} is not found." >&2
27 if [ ! -e "${PORTSDIR}/Makefile" -o ! -e "${PORTSDIR}/Mk/bsd.port.mk" ]
29 message_echo "ERROR: Ports tree ${PORTSDIR} is missing, broken or incompatible." >&2
34 # ============= System defined value for the ports/packages =============
39 tmp_work=${TMPDIR}/pkgsys_sysvar:work
42 make -C "$tmp_work" -f "${PORTSDIR}/Mk/bsd.port.mk" -V "$var" 2> /dev/null
45 # ============= Get the file name of package check sum file =============
46 pkgsys_pkgchksum_file ()
51 # ============= Check whether a port is indispensable for the standard function of the ports/packages system =============
55 ports-mgmt/pkg|ports-mgmt/dialog4ports)
61 # ============= Check whether a port is indispensable for package operations =============
62 pkgsys_is_necessary_pkgtool ()
64 [ x"$WITH_PKGNG" = x'yes' -a "x$1" = x'ports-mgmt/pkg' ]
67 # ============= Check whether the dialog for selecting port options is dialog4ports =============
68 pkgsys_is_dialog4ports_used ()
70 [ -n "`pkgsys_sysvar DIALOG4PORTS`" ]
73 # ============= Get the number of mirror sites for legacy packages =============
74 pkgsys_num_mirrorsites ()
78 echo "$siteroots" | tr '|' '\n' | wc -l
81 # ============= Get a URL one of mirror sites =============
82 pkgsys_url_from_mirrors ()
84 local siteroots subdir nsites id_site site platform version
87 nsites=`pkgsys_num_mirrorsites "$siteroots"`
88 id_site=`(set +e; random -e $nsites; echo $?)`
89 site=`echo "$siteroots" | tr '|' '\n' | sed -n $((${id_site}+1))p`
91 version=`uname -r | cut -d - -f 1,2 | tr [:upper:] [:lower:]`
93 printf "$subdir\n" "$platform" "$version"
96 # ============= Fetch a file from one of mirror sites =============
97 pkgsys_fetch_from_mirrors ()
99 local siteroots subdir filename dst tmp_work fetch itrial origdir url
104 tmp_work=${TMPDIR}/pkgsys_fetch_from_mirrors:work
107 fetch=`pkgsys_sysvar FETCH_CMD`
108 itrial=$((`pkgsys_num_mirrorsites "$siteroots"`*$PKGSYS_AVR_REFETCH_TIMES_PER_SITE))
111 while [ $itrial -ge 1 ]
113 url=`pkgsys_url_from_mirrors "$siteroots" "$subdir"`$filename
114 message_echo "INFO: Fetching from $url:"
115 $fetch "$url"&& break
117 itrial=$(($itrial-1))
120 [ -e "$tmp_work/$filename" ] || return
121 mv "$tmp_work/$filename" "$dst"
124 # ============= Get the package check sums file ready =============
125 pkgsys_ready_checksum_file ()
128 tmp_savedpath=${TMPDIR}/pkgsys_ready_checksum_file:savedpath
129 rm -f "$tmp_savedpath"
130 chksumfile=`pkgsys_pkgchksum_file`
131 if [ ! -e "${DBDIR}/checksum/$chksumfile" ]
133 [ -d "${DBDIR}/checksum" ] || mkdir "${DBDIR}/checksum"
134 if ! pkgsys_fetch_from_mirrors "${PACKAGECHECKSUMROOTS}" "${PACKAGECHECKSUMDIR}" \
135 "$chksumfile" "${DBDIR}/checksum"
137 message_echo "WARNING: No check sum file is available." >&2
141 echo "${DBDIR}/checksum/$chksumfile" > $tmp_savedpath
144 # ============= Get the location of a check sums file fetched by pkgsys_ready_checksum_file =============
145 pkgsys_ready_checksum_file__fetched_file ()
147 cat "${TMPDIR}/pkgsys_ready_checksum_file:savedpath"
150 # ============= Fetch a legacy package from one of remote sites =============
151 pkgsys_fetch_legacy_remote ()
153 local pkg tmp_work tmp_pkgpath pkg_regexp checksumpath validMD5 fetchedMD5 needs_fetch itrial
155 tmp_work=${TMPDIR}/pkgsys_fetch_legacy_remote:work
156 tmp_pkgpath=${TMPDIR}/pkgsys_fetch_legacy_remote:pkgpath
159 pkg_regexp=`str_escape_regexp "$pkg"`
160 pkgsys_ready_checksum_file || return
161 checksumpath=`pkgsys_ready_checksum_file__fetched_file`
162 validMD5=`grep -m 1 -E -e "^MD5[[:space:]]*\($pkg_regexp\.tbz\)[[:space:]]*=" "$checksumpath" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
163 if [ -z "$validMD5" ]
165 message_echo "WARNING: No check sum for $pkg.tbz." >&2
169 [ -d "${PKGREPOSITORY}" ] || mkdir -p "${PKGREPOSITORY}"
170 if [ -e "${PKGREPOSITORY}/$pkg.tbz" ]
172 if [ -e "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" ]
174 fetchedMD5=`md5 "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
175 [ "x$fetchedMD5" = "x$validMD5" ] || rm "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz"
177 if [ -e "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" ]
179 ln -f "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz" "${PKGREPOSITORY}/$pkg.tbz"
181 fetchedMD5=`md5 "${PKGREPOSITORY}/$pkg.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
182 if [ "x$fetchedMD5" = "x$validMD5" ]
186 mv "${PKGREPOSITORY}/$pkg.tbz" "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz"
190 if [ $needs_fetch = yes ]
192 itrial=$PKGSYS_AVR_REFETCH_TIMES_FOR_CHKSUMERR
193 while [ $itrial -ge 1 ]
195 if pkgsys_fetch_from_mirrors "${PACKAGEROOTS}" "${PACKAGEDIR}" \
196 "$pkg.tbz" "$tmp_work"
198 fetchedMD5=`md5 "$tmp_work/$pkg.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
199 [ "x$fetchedMD5" = "x$validMD5" ] && break
200 message_echo "WARNING: Check sum mismatches for $pkg.tbz." >&2
202 itrial=$(($itrial-1))
204 [ $itrial -ge 1 ] || return
205 mv "$tmp_work/$pkg.tbz" "${PKGREPOSITORY}"
207 echo "${PKGREPOSITORY}/$pkg.tbz" > $tmp_pkgpath
210 # ============= Get the location of a package fetched by pkgsys_fetch_legacy_remote =============
211 pkgsys_fetch_legacy_remote__fetched_pkg ()
213 cat "${TMPDIR}/pkgsys_fetch_legacy_remote:pkgpath"
216 # ============= Check whether the dependency of a legacy package is the latest =============
217 pkg_is_dependency_of_a_legacypkg_latest ()
219 local pkgarc tmp_extract tmp_contents tmp_origin tmp_pkg pkg nlines iline origin_req pkg_req pkg_new
221 tmp_extract=${TMPDIR}/pkgng:pkg_is_dependency_of_a_legacypkg_latest:extract
222 tmp_contents=${TMPDIR}/pkgng:pkg_is_dependency_of_a_legacypkg_latest:contents
223 tmp_origin=${TMPDIR}/pkgng:pkg_is_dependency_of_a_legacypkg_latest:origin
224 tmp_pkg=${TMPDIR}/pkgng:pkg_is_dependency_of_a_legacypkg_latest:pkg
225 pkg=`pkgsys_pkgarc_to_pkgname "$pkgarc"`
226 [ -e "$pkgarc" ] || return
227 rm -rf "$tmp_extract"
229 tar xf "$pkgarc" -C "$tmp_extract" +CONTENTS
230 grep -e '^@pkgdep[[:space:]]' -e '^@comment[[:space:]]*DEPORIGIN:' "$tmp_extract/+CONTENTS" \
231 | sed 's/^@pkgdep[[:space:]]*//;s/^@comment[[:space:]]*DEPORIGIN://' > $tmp_contents
232 nlines=`wc -l < $tmp_contents`
234 while [ $iline -le $nlines ]
236 origin_req=`sed -n ${iline}p "$tmp_contents"`
237 pkg_req=`sed -n $(($iline+1))p "$tmp_contents"`
239 pkg_new=`cat "${DBDIR}/requires/$origin_req/new_version" 2> /dev/null` || :
240 if [ -z "$pkg_new" -o "$pkg_new" != "$pkg_req" ]
242 message_echo "WARNING: Requirements of remote package $pkg are not the latest." >&2
249 # ============= Check whether legacy package tools are available =============
250 pkgsys_is_legacy_tool_available ()
255 # ============= Define wrapper commands for hiding the differences between pkg_* tools and pkgng =============
256 pkgsys_def_pkgtools ()
258 if [ "${DBDIR}/WITH_PKGNG" -nt /etc/make.conf -o \( -e "${DBDIR}/WITH_PKGNG" -a ! -e /etc/make.conf \) ]
260 PKGSYS_USE_PKGNG=`cat "${DBDIR}/WITH_PKGNG"`
262 PKGSYS_USE_PKGNG=`pkgsys_sysvar WITH_PKGNG | tr '[:upper:]' '[:lower:]'`
263 if [ -d "${DBDIR}" ] && misc_is_superuser_privilege
265 echo "$PKGSYS_USE_PKGNG" > ${DBDIR}/WITH_PKGNG.tmp
266 mv "${DBDIR}/WITH_PKGNG.tmp" "${DBDIR}/WITH_PKGNG"
269 if [ "x$PKGSYS_USE_PKGNG" = xyes ]
271 export WITH_PKGNG=yes
272 PKGSYS_CMD_PKG_INFO='pkg info'
273 PKGSYS_CMD_PKG_CREATE='pkg create'
274 PKGSYS_CMD_PKG_DELETE='pkg delete'
275 PKGSYS_CMD_PKG_ADD='pkg add'
276 pkg_is_tool_available ()
278 if [ -x /usr/sbin/pkg ]
280 pkg -N 2> /dev/null && return
281 env ASSUME_ALWAYS_YES=yes pkg bootstrap -f
282 pkg_is_tool_available
284 which -s pkg && return
289 pkg info -qa 2> /dev/null
293 pkg info -qoa 2> /dev/null
297 # pkg info -qox "$@" 2> /dev/null
301 pkg info -qox "$@" 2> /dev/null
305 pkg info -qO "$@" 2> /dev/null
309 pkg info -qo "$@" 2> /dev/null
313 pkg info -qd "$@" 2> /dev/null
317 pkg info -e "$@" 2> /dev/null
321 pkg info -eO "$1" 2> /dev/null
325 pkg info -Eg "$@" 2> /dev/null
329 pkg info -qr "$@" 2> /dev/null
333 pkg info -Ex "$@" 2> /dev/null
337 pkg info -ql "$@" 2> /dev/null
341 local pkg tmp_stdout tmp_stderr
343 tmp_stdout=${TMPDIR}/pkgng:pkg_check_sanity:stdout
344 tmp_stderr=${TMPDIR}/pkgng:pkg_check_sanity:stderr
345 pkg check -s "$pkg" > $tmp_stdout 2> $tmp_stderr || :
346 grep '^[^:]*: checksum mismatch for ' "$tmp_stderr" | sed 's/^[^:]*: checksum mismatch for //' || :
347 if grep -q '^pkg: .*: No such file or directory$' "$tmp_stderr"
349 pkg info -ql "$pkg" | while read filepath
351 [ -e "$filepath" ] || echo "$filepath"
360 pkg which -q "$filepath" 2> /dev/null
362 pkg_info_gen_pkg_origin_table ()
364 pkg query -g '%n-%v\t%o' \* 2> /dev/null > ${DBDIR}/installed_ports:pkg_vs_origin.tbl
373 pkg info -e "$@" || return 0 # Countermeasure for a bug found for pkg-1.3.4 (at least not until 1.2.7_4)
378 local pkgarc tmp_extract prefix prefix_parent pkg
380 tmp_extract=${TMPDIR}/pkgng:pkg_add_tools:extract
381 rm -rf "$tmp_extract"
383 tar xf "$pkgarc" -C "$tmp_extract"
384 prefix=`grep -m 1 '^prefix: ' "$tmp_extract/+MANIFEST" | sed 's/^prefix: *//'`
385 prefix_parent=`dirname "$prefix"`
386 cp -Rp "$tmp_extract/$prefix" "$prefix_parent"/
387 pkg=`pkgsys_pkgarc_to_pkgname "$pkgarc"`
388 message_echo "INFO: Contents of $pkg are temporarily installed by simple copy."
389 if env ASSUME_ALWAYS_YES=YES pkg add "$pkgarc"
391 message_echo "INFO: $pkg is successfully registered."
393 message_echo "WARNING: Failed to register $pkg, but the process is continued." >&2
398 local pkgarc pkg pkg_tool pkg_gen
403 pkg=`basename "$pkgarc"`
404 if expr "$pkg" : '^pkg-[0-9][0-9]*\..*' > /dev/null
408 pkg_gen="$pkg_gen $pkgarc"
411 [ -n "$pkg_tool" ] && pkg_add_tools "$pkg_tool"
412 [ -n "$pkg_gen" ] && env ASSUME_ALWAYS_YES=YES pkg add $pkg_gen
418 pkg_inst_remote_fetch ()
420 local pkg mode pkgarc
423 tmp_extract=${TMPDIR}/pkgng:pkg_inst_remote:extract
424 pkg fetch -yU "$pkg" || return
425 pkgarc=`pkgsys_pkgname_to_pkgarc "${PKGNG_PKG_CACHEDIR}/All" "$pkg"` || return
426 [ "x$mode" = xnodepschk ] && return
427 rm -rf "$tmp_extract"
429 tar xf "$pkgarc" -C "$tmp_extract" +MANIFEST
430 sed -E '1,/^deps:/d;/^[^[:space:]]/,$d;s/^[[:space:]]*([^:]+):[[:space:]]*\{origin:[[:space:]]*([^,]+),[[:space:]]*version:[[:space:]]*([^}]+)\}/\2\\\1-\3/' "$tmp_extract/+MANIFEST" \
431 | tr '\\' '\t' | while read origin_req pkg_req
433 pkg_new=`cat "${DBDIR}/requires/$origin_req/new_version" 2> /dev/null` || :
434 if [ -z "$pkg_new" -o "$pkg_new" != "$pkg_req" ]
436 message_echo "WARNING: Requirements of remote package $pkg are not latest." >&2
444 local pkg mode pkgarc
447 pkg_inst_remote_fetch "$pkg" "$mode" || return
448 pkgarc=`pkgsys_pkgname_to_pkgarc "${PKGNG_PKG_CACHEDIR}/All" "$pkg"` || return
449 env ASSUME_ALWAYS_YES=YES pkg add "$pkgarc"
451 pkg_inst_remote_wild_fetch ()
453 local pkg mode pkgarc
456 if pkg_is_tool_available
458 pkg_inst_remote "$pkg" "$mode" && return
460 pkgsys_is_legacy_tool_available || return
461 message_echo "INFO: Trying to use a legacy package and convert it to pkgng."
462 pkgsys_fetch_legacy_remote "$pkg" || return
463 pkgarc=`pkgsys_fetch_legacy_remote__fetched_pkg`
464 [ "x$mode" = xnodepschk ] && return
465 pkg_is_dependency_of_a_legacypkg_latest "$pkgarc"
467 pkg_inst_remote_wild ()
469 local pkg mode pkgarc
472 pkg_inst_remote_wild_fetch "$pkg" "$mode" || return
473 pkgarc=`pkgsys_fetch_legacy_remote__fetched_pkg`
474 pkg_add -ifF "$pkgarc" || return
475 message_echo "INFO: Trying to convert the installed legacy package to pkgng."
477 message_echo "INFO: Checking whether the conversion is successful."
483 # Deafult configuration for pkg(1)
484 PKGNG_PACKAGESITE='http://pkg.freebsd.org/${ABI}/latest'
485 PKGNG_SRV_MIRRORS=YES
486 PKGNG_PKG_DBDIR=/var/db/pkg
487 PKGNG_PKG_CACHEDIR=/var/cache/pkg
488 PKGNG_PORTSDIR=/usr/ports
489 PKGNG_PUBKEY=/etc/ssl/pkg.conf
490 PKGNG_HANDLE_RC_SCRIPTS=NO
491 PKGNG_PKG_MULTIREPOS=NO
492 PKGNG_ASSUME_ALWAYS_YES=NO
496 PKGNG_PORTAUDIT_SITE='http=//portaudit.FreeBSD.org/auditfile.tbz'
497 # Load configuration for pkg(1)
498 pkg_conf=`pkg query %Fp pkg 2> /dev/null | grep '/etc/pkg\.conf\.sample$' | sed 's/\.sample$//'` || :
499 [ -n "$pkg_conf" ] || pkg_conf=${MYPREFIX}/etc/pkg.conf
500 grep -v -e '^[[:space:]]*#' -e '^[[:space:]]*$' "$pkg_conf" 2> /dev/null \
501 | grep -e '^[[:space:]]*[A-Z0-9_]*[[:space:]]*:[[:space:]]*.*' \
504 var=`expr "$srcline" : '^[[:space:]]*\([A-Z0-9_]*\)[[:space:]]*:.*'` || :
505 val=`expr "$srcline" : '^[[:space:]]*[A-Z0-9_]*[[:space:]]*:[[:space:]]*\(.*\)'` || :
506 eval PKGNG_$var=\$val
507 misc_get_all_vardefs | grep -E "^PKGNG_$var="
508 done > ${TMPDIR}/pkgsys_def_pkgtools:pkg.conf.sh
509 . "${TMPDIR}/pkgsys_def_pkgtools:pkg.conf.sh"
513 local packagepath checksumpath pkgname is_successful
514 packagepath=`pkgsys_get_backup_pkg ports-mgmt/pkg` && \
515 pkg_add_tools "$packagepath" && return
516 pkg_is_tool_available && return
517 message_echo "WARNING: WITH_PKGNG is set, but pkgng is still missing. It is installed now." >&2
518 pkgsys_ready_checksum_file || return
519 message_echo "INFO: Installing pkgng by legacy package tool."
520 checksumpath=`pkgsys_ready_checksum_file__fetched_file`
521 pkgname=`sed 's/^MD5[[:space:]]*(//;s/\.tbz)[[:space:]]*=[^=]*$//' "$checksumpath" \
522 | grep -m 1 -E -e "^pkg-[0-9]"` || :
523 [ -n "$pkgname" ] && pkg_inst_remote_wild "$pkgname" nodepschk && return
524 message_echo "INFO: Failed by package, so installing pkgng by port."
525 grep -v '^[[:space:]]*WITH_PKGNG=' /etc/make.conf > ${TMPDIR}/make.conf
526 echo WITHOUT_PKGNG=yes >> ${TMPDIR}/make.conf
531 message_echo "INFO: Attempting deinstallation of ports-mgmt/pkg to make sure."
532 env __MAKE_CONF="${TMPDIR}/make.conf" make -C "${PORTSDIR}/ports-mgmt/pkg" deinstall || :
533 message_echo "INFO: Attempting (re)installation by ports-mgmt/pkg."
534 env __MAKE_CONF="${TMPDIR}/make.conf" make -C "${PORTSDIR}/ports-mgmt/pkg" reinstall clean
537 pkg_is_tool_available
540 if ! pkg_rescue_tools
542 message_echo "WARNING: Pkgng is still missing, but continuing for the time being." >&2
545 elif ! pkgsys_is_legacy_tool_available
547 message_echo "ERROR: Pkgng is disabled although the legacy packages tools are unavailable. Resolve the problem manually." >&2
552 PKGSYS_CMD_PKG_INFO='pkg_info'
553 PKGSYS_CMD_PKG_CREATE='pkg_create'
554 PKGSYS_CMD_PKG_DELETE='pkg_delete'
555 PKGSYS_CMD_PKG_ADD='pkg_add'
556 pkg_is_tool_available ()
558 pkgsys_is_legacy_tool_available
562 pkg_info -Ea 2> /dev/null
566 pkg_info -qoa 2> /dev/null
570 # pkg_info -qox "$@" 2> /dev/null
574 pkg_info -qoX "$@" 2> /dev/null
578 pkg_info -qO "$@" 2> /dev/null
582 pkg_info -qo "$@" 2> /dev/null
586 pkg_info -qr "$@" | grep '^@pkgdep ' | sed 's/^@pkgdep[[:space:]]*//' 2> /dev/null
590 pkg_info -e "$@" 2> /dev/null
594 [ `pkg_info -qO "$1" 2> /dev/null | wc -l` -gt 0 ]
598 pkg_info -E "$@" 2> /dev/null
602 pkg_info -qR "$@" | grep -v '^$' 2> /dev/null
606 pkg_info -Ex "$@" 2> /dev/null
610 pkg_info -qL "$@" 2> /dev/null
614 local pkg tmp_stdout tmp_stderr
616 tmp_stdout=${TMPDIR}/pkgng:pkg_check_sanity:stdout
617 tmp_stderr=${TMPDIR}/pkgng:pkg_check_sanity:stderr
618 pkg_info -qg "$pkg" > $tmp_stdout 2> $tmp_stderr || :
619 grep ' fails the original MD5 checksum$' "$tmp_stdout" | sed 's/ fails the original MD5 checksum$//' || :
620 grep "^pkg_info: .* doesn't exist$" "$tmp_stderr" | sed -E "s/^pkg_info: (.*) doesn't exist$/\1/" || :
626 pkg_info -qW "$filepath" 2> /dev/null
628 pkg_info_gen_pkg_origin_table ()
630 pkg_info -aE 2> /dev/null | while read pkg
632 origin=`pkg_info -qo "$pkg" 2> /dev/null`
633 printf '%s\t%s\n' "$pkg" "$origin"
634 done > ${DBDIR}/installed_ports:pkg_vs_origin.tbl
652 pkg_inst_remote_fetch ()
654 local pkg mode pkgarc
657 pkgsys_fetch_legacy_remote "$pkg" || return
658 pkgarc=`pkgsys_fetch_legacy_remote__fetched_pkg`
659 [ "x$mode" = xnodepschk ] && return
660 pkg_is_dependency_of_a_legacypkg_latest "$pkgarc"
664 local pkg mode pkgarc
667 pkg_inst_remote_fetch "$pkg" "$mode" || return
668 pkgarc=`pkgsys_fetch_legacy_remote__fetched_pkg`
669 pkg_add "$pkgarc" || return
671 pkg_inst_remote_wild_fetch ()
673 pkg_inst_remote_fetch "$1" "$2"
675 pkg_inst_remote_wild ()
677 pkg_inst_remote "$1" "$2"
679 pkg_loadconf () { :; }
680 pkg_rescue_tools () { :; }
684 # ============= Check existence of initially or currently installed package for an origin =============
685 pkgsys_pkg_info_eO ()
687 local origin origin_regexp
689 origin_regexp=`str_escape_regexp "$origin"`
690 cut -f 2 "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
691 | grep -q -E "^$origin_regexp$" && return
692 pkg_info_eO "$origin"
695 # ============= Get the name of an initially installed package for an origin =============
696 pkgsys_pkg_info_qO_init ()
698 local origin tmppkg origin_regexp npkgs
700 tmppkg=${TMPDIR}/pkgsys_pkg_info_qO_init::pkg
701 origin_regexp=`str_escape_regexp "$origin"`
702 sed -n -E "/[[:space:]]$origin_regexp$/p" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
703 | cut -f 1 > $tmppkg || :
704 npkgs=`wc -l < $tmppkg`
709 pkg_info_qO "$origin"
713 # ============= Get the package name of this utility =============
714 pkgsys_get_my_current_pkg ()
716 pkg_info_Ex "${APPNAME}-[0-9].*"
719 # ============= Get the origin of this utility =============
720 pkgsys_get_my_origin ()
722 pkg_info_qo "`pkgsys_get_my_current_pkg`"
725 # ============= Get the origin of an initially installed package by ambiguous matching =============
726 pkgsys_init_pkg_orig_by_ambiguous_matching ()
728 local pkg origin tmporigin ambsuffix len_pkg pkg_regexp norigins
730 origin=`pkg_info_qo "$pkg" || :`
731 [ -n "$origin" ] && { echo "$origin"; return; }
732 tmporigin=${TMPDIR}/pkgsys_init_pkg_orig_by_ambiguous_matching::origin
735 len_pkg=`echo -n "$pkg" | wc -c`
736 if [ $len_pkg -gt 0 ]
740 pkg_regexp=`str_escape_regexp "$pkg"`$ambsuffix
741 grep -E "^${pkg_regexp}[[:space:]]" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
742 | cut -f 2 > $tmporigin
743 norigins=`wc -l < $tmporigin`
744 [ $norigins -gt 0 ] && break
745 ambsuffix='[a-zA-Z0-9.,_+-]*'
746 len_pkg=$(($len_pkg-1))
747 [ $len_pkg -gt 0 ] || break
748 pkg=`echo -n "$pkg" | head -c $len_pkg`
751 [ $norigins -eq 1 ] || return
755 # ============= A part of message indicating tools for showing concerned issues in UPDATING =============
756 pkgsys_show_pkg_updating_commands ()
758 if [ "x$PKGSYS_USE_PKGNG" = xyes ]
760 if which -s pkg_updating
762 echo 'pkg-updating(8) or pkg_updating(1)'
764 echo 'pkg-updating(8)'
766 elif which -s pkg_updating
768 echo 'pkg_updating(1)'
772 # ============= Evaluation of ports globs =============
773 pkgsys_eval_ports_glob ()
775 local pkglist origlist
776 pkglist=${DBDIR}/pkgsys_eval_ports_glob:pkg.lst
777 origlist=${DBDIR}/pkgsys_eval_ports_glob:origin.lst
778 if [ ! -r "$pkglist" ]
780 if touch "$pkglist" 2>/dev/null
784 pkglist=${TMPDIR}/pkgsys_eval_ports_glob:pkg.lst
787 if [ ! -r "$origlist" ]
789 if touch "$origlist" 2>/dev/null
793 origlist=${TMPDIR}/pkgsys_eval_ports_glob:origin.lst
797 || cut -d \| -f 1 "${PORTS_INDEX_DB}" > $pkglist
799 || cut -d \| -f 2 "${PORTS_INDEX_DB}" \
800 | sed -E "s/^`str_escape_regexp "${PORTSDIR}"`\///" > $origlist
805 expr "x$glob" : '^x-' > /dev/null 2>&1 && continue
806 glob_regexp=`str_convert_portsglob_to_regexp_pattern "$glob"`
807 if expr "$glob" : '.*/' > /dev/null 2>&1
809 grep -E "$glob_regexp" "$origlist" 2>&1 || :
812 cut -f 2 "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null
813 } | grep -E "$glob_regexp" 2>&1 || :
815 if expr "$glob" : '^[a-z][a-zA-Z0-9_.+-]*[a-zA-Z0-9_.+]$' > /dev/null 2>&1 && \
816 [ `expr "$glob" : '.*-[0-9]' 2>&1` -eq 0 ]
818 glob_regexp2=`expr "$glob_regexp" : '\(.*\)\$$' 2>&1`'-[0-9]'
820 glob_regexp2=$glob_regexp
822 grep -n -E "$glob_regexp2" "$pkglist" 2>&1 | cut -d : -f 1 \
825 sed -n ${index}p "$origlist"
827 glob_regexp2=`expr "$glob_regexp" : '\(.*\)\$$' 2>&1`'[[:space:]]'
828 sed -n -E "/$glob_regexp2/p" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
830 pkg_info_qoX "$glob_regexp" || :
835 # ============= Create a back-up package archive =============
836 pkgsys_create_backup_pkg ()
838 local pkgname dstdir origin backup_pkg_old pkgname_ptn backup_pkg dbpath pkgpath origin_regexp
841 rm -rf "${TMPDIR}"/package.tmp
842 mkdir "${TMPDIR}"/package.tmp
843 origin=`pkg_info_qo "$pkgname"`
844 if backup_pkg_old=`pkgsys_get_backup_pkg "$origin"` \
845 [ "$backup_pkg_old" -nt "${DBDIR}/requires/$origin/installed_timestamp" ]
847 echo "$backup_pkg_old"
850 if ( cd "${TMPDIR}"/package.tmp && pkg_create_b "$pkgname" > /dev/null )
852 pkgname_ptn=`str_escape_regexp "$pkgname"`
853 backup_pkg=`ls "${TMPDIR}"/package.tmp | \
854 grep -m 1 -E "^${pkgname_ptn}\.(txz|tbz|tgz|tar)$"` || :
856 if [ -z "$backup_pkg" ]
858 message_echo "WARNING: Failed to create backup package for $pkgname." >&2
861 dbpath=${DBDIR}/requires/$origin
862 [ -d "$dbpath" ] || dbpath=${DBDIR}/initial/$origin
863 pkg_info_qL > $dbpath/previously_installed_files
864 [ -d "$dstdir" ] || mkdir -p "$dstdir"
865 mv "${TMPDIR}/package.tmp/$backup_pkg" "$dstdir"
866 pkgpath=$dstdir/$backup_pkg
867 origin_regexp=`str_escape_regexp "$origin"`
868 cat "${DBDIR}/backup_pkgarcs.lst" 2> /dev/null | \
869 while read origin_cur pkgpath_cur
871 [ "$pkgpath_cur" = "$pkgpath" ] && continue
872 if [ "$origin_cur" = "$origin" ]
876 printf '%s\t%s\n' "$origin_cur" "$pkgpath_cur"
878 done > ${DBDIR}/backup_pkgarcs.lst.tmp
879 printf '%s\t%s\n' "$origin" "$pkgpath" >> ${DBDIR}/backup_pkgarcs.lst.tmp
880 mv "${DBDIR}/backup_pkgarcs.lst.tmp" "${DBDIR}/backup_pkgarcs.lst"
884 # ============= Delete a back-up package archive for a port origin =============
885 pkgsys_delete_backup_pkg ()
887 local origin origin_regexp
889 origin_regexp=`str_escape_regexp "$origin"`
890 grep -E "^${origin_regexp}[[:space:]]" "${DBDIR}/backup_pkgarcs.lst" 2> /dev/null \
891 | cut -f 2 | while read pkgpath_cur
895 grep -v -E "^${origin_regexp}[[:space:]]" "${DBDIR}/backup_pkgarcs.lst" \
896 2> /dev/null > ${DBDIR}/backup_pkgarcs.lst.tmp || :
897 mv "${DBDIR}/backup_pkgarcs.lst.tmp" "${DBDIR}/backup_pkgarcs.lst"
900 # ============= Get an existing package archive path for a port origin =============
901 pkgsys_get_backup_pkg ()
903 local origin tmpnewest origin_regexp
905 tmpnewest=${TMPDIR}/pkgsys_get_backup_pkg::newest
906 origin_regexp=`str_escape_regexp "$origin"`
908 grep -E "^${origin_regexp}[[:space:]]" "${DBDIR}/backup_pkgarcs.lst" 2> /dev/null \
909 | cut -f 2 | while read pkgpath
911 pkgpath_newest=`cat "$tmpnewest" 2> /dev/null` || :
912 [ -e "$pkgpath" ] || continue
913 [ -z "$pkgpath_newest" -o "$pkgpath" -nt "$pkgpath_newest" ] || continue
914 echo "$pkgpath" > $tmpnewest
916 cat "$tmpnewest" 2> /dev/null
919 # ============= Get a file list to be restored by the current backup package for a port origin =============
920 pkgsys_get_restored_files_by_backup_pkg ()
924 dbpath=${DBDIR}/requires/$origin
925 [ -d "$dbpath" ] || dbpath=${DBDIR}/initial/$origin
926 cat "$dbpath/previously_installed_files" 2> /dev/null || :
929 # ============= Get a package name from a package archive file name =============
930 pkgsys_pkgarc_to_pkgname ()
934 basename "$pkgfile_path" | sed -E 's/\.(txz|tbz|tgz|tar)$//'
937 # ============= Get the file name of an existing package archive for a package name =============
938 pkgsys_pkgname_to_pkgarc ()
940 local pkgdir pkgname pkgname_ptn pkgnode
943 [ -n "$pkgname" ] || return 1
944 [ -d "$pkgdir" ] || return 1
945 if [ "x$PKGSYS_USE_PKGNG" = xyes ]
947 pkgname_ptn=`str_escape_regexp "$pkgname"`
948 pkgnode=`ls "$pkgdir" 2> /dev/null | grep -m 1 -E "^${pkgname_ptn}\.(txz|tbz|tgz|tar)$"` || :
949 elif [ -e "$pkgdir/$pkgname.tbz" ]
953 [ -n "$pkgnode" ] || return 1
954 echo "$pkgdir/$pkgnode"
957 # ============= Get port origins matching a glob pattern even if nonexistent =============
958 pkgsys_eval_ports_glob_even_if_nonexistent ()
963 pkgsys_eval_ports_glob "$glob_pattern" 2> /dev/null || :
964 echo "$glob_pattern" | grep '^[a-z][a-z]*/[a-zA-Z0-9_.+-][a-zA-Z0-9_.+-]*$' || :
965 } | grep -v -e '^$' | sort -u
968 # ============= Evaluate glob patterns and add/remove non-existing/existing ones of them to/from a file =============
969 pkgsys_register_evaluated_globs ()
971 local mode listpath dirpath tmp_evaluated
975 dirpath=`dirname "$listpath"`
976 tmp_evaluated=${TMPDIR}/pkgsys_register_evaluated_globs:pkgsys_eval_ports_glob
977 echo "$@" | sed -E 's/[ :]+/\
978 /g' | grep -v '^$' | sort -u | while read glob
980 pkgsys_eval_ports_glob "$glob" > $tmp_evaluated
981 [ `wc -l < $tmp_evaluated` -ge 1 ] || \
983 message_echo "WARNING: No matching ports/package glob [$glob]." >&2
987 done | while read origin
989 [ -d "$dirpath" ] || mkdir -p "$dirpath"
991 remove) fileedit_rm_a_line "$origin" "$listpath";;
992 add) fileedit_add_a_line_if_new "$origin" "$listpath";;
997 # ============= Evaluate glob patterns for installed packages =============
998 pkgsys_eval_installed_pkgs_globs ()
1001 tmp_evaluated=${TMPDIR}/pkgsys_eval_installed_pkgs_globs:origins
1002 rm -f "$tmp_evaluated"
1003 pkgsys_register_evaluated_globs add "$tmp_evaluated" "$@"
1004 [ -e "$tmp_evaluated" ] || return 0
1007 pkgsys_pkg_info_eO "$origin" || echo "$origin"
1008 done < $tmp_evaluated
1011 # ============= Get glob patterns of conflicting packages of a port =============
1012 pkgsys_get_conflicting_pkgs_patterns ()
1014 local mode origin conflicts
1017 conflicts=`database_query_get_makevar_val "$origin" CONFLICTS`
1020 conflicts=$conflicts' '`database_query_get_makevar_val "$origin" CONFLICTS_BUILD`
1023 conflicts=$conflicts' '`database_query_get_makevar_val "$origin" CONFLICTS_INSTALL`
1026 echo "$conflicts" | tr ' ' '\n' | grep -v '^$' || :
1029 # ============= Get conflicting installed packages of a port =============
1030 pkgsys_get_conflicting_installed_pkgs ()
1032 local mode origin tmp_conflicts
1035 tmp_conflicts=${TMPDIR}/pkgsys_get_conflicting_installed_pkgs::conflicts
1036 pkg_info_Eg `pkgsys_get_conflicting_pkgs_patterns "$mode" "$origin"` > $tmp_conflicts || :
1037 cat "$tmp_conflicts"
1038 [ `wc -l < $tmp_conflicts` -gt 0 ]
1041 # ============= Check whether a package conflicts with a port =============
1042 pkgsys_chk_conflict_by_a_pkg ()
1044 local mode origin pkg tmp_conflicts_ptn
1048 tmp_conflicts_ptn=${TMPDIR}/pkgsys_chk_conflict_by_a_pkg::conflicts_ptn
1049 pkgsys_get_conflicting_pkgs_patterns "$mode" "$origin" \
1050 | str_convert_glob_to_regexp_pattern > $tmp_conflicts_ptn
1051 echo "$pkg" | grep -q -E -f "$tmp_conflicts_ptn"
1054 # ============= Check whether installed files are lost or broken for a package =============
1055 pkgsys_sanitychk_pkgcontents ()
1057 local pkg var_is_reinstall_encouraged _is_reinstall_encouraged tmp_sanity nlines iline src filename icol filename_esc pkg_owner origin
1059 var_is_reinstall_encouraged=$2
1060 tmp_sanity=${TMPDIR}/pkgsys_sanitychk_pkgcontents:sanity
1061 pkg_check_sanity "$pkg" > $tmp_sanity || :
1062 eval "$var_is_reinstall_encouraged=no"
1063 [ `wc -l < $tmp_sanity` -eq 0 ] && return
1064 nlines=`wc -l < $tmp_sanity`
1066 _is_reinstall_encouraged=no
1067 while [ $iline -le $nlines ]
1069 filename=`sed -n ${iline}p "$tmp_sanity"`
1071 if [ ! -e "$filename" ]
1073 _is_reinstall_encouraged=yes
1076 if expr "$filename" : '.*/include/.*' > /dev/null
1078 _is_reinstall_encouraged=yes
1081 filename_esc=`str_escape_regexp "$filename"`
1082 if file "$filename" | sed -E "s/^$filename_esc:[[:space:]]//" | grep -q '^ELF '
1084 _is_reinstall_encouraged=yes
1087 pkg_owner=`pkg_which "$filename"`
1088 if [ "$pkg" != "$pkg_owner" ]
1090 _is_reinstall_encouraged=yes
1094 eval "$var_is_reinstall_encouraged=\$_is_reinstall_encouraged"
1095 origin=`pkg_info_qo "$pkg"`
1096 if [ $opt_batch_mode = no ]
1098 message_echo "[$pkg ($origin)]"
1099 sed 's/^/ /' "$tmp_sanity"
1102 pkg_replace=`str_escape_replaceval "$pkg"`
1103 origin_replace=`str_escape_replaceval "$origin"`
1104 sed "s/^/$pkg_replace\\\\$origin_replace\\\\$_is_reinstall_encouraged\\\\/" "$tmp_sanity" | tr '\\' '\t'