OSDN Git Service

The HISTORY description about the adaption to the specification change to disallow...
[portsreinstall/current.git] / lib / libpkgsys.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - Wrappers for hiding version differences in the Ports/Packages system -
5 # Copyright (C) 2013-2022 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
8
9 # ============= Variables =============
10 PKGSYS_USE_PKGNG=yes    # no: legacy pkg_* tools, yes: the new generation package (pkgng)
11 PKGSYS_CMD_PKG_DELETE='pkg delete'      # Corresponding command for pkg_delete
12 PKGSYS_AVR_REFETCH_TIMES_PER_SITE=1     # Average number (integer) of retrials for retrieving package or distfiles per mirror site
13 PKGSYS_AVR_REFETCH_TIMES_FOR_CHKSUMERR=2        #  Number (integer) of retrials for check sum error in retrieving a package
14
15 # ============= Get the time stamp of the ports tree =============
16 pkgsys_get_timestamp_portstree ()
17 {
18         stat -t %s -f %m "${PORTS_INDEX_DB}" 2> /dev/null || :
19 }
20
21 # ============= Update the ports tree =============
22 pkgsys_update_portstree ()
23 {
24                 if [ -e "$PORTSNAP_WORKDIR/INDEX" ]
25                 then
26                         mode=update
27                 else
28                         mode=extract
29                 fi
30                 if [ $opt_batch_mode = no ]
31                 then
32                         stdout=/dev/stdout
33                 else
34                         stdout=/dev/null
35                 fi
36                 portsnap fetch $mode > $stdout
37 }
38
39 # ============= Check implementation of the ports tree =============
40 pkgsys_chk_ports_tree_implementation ()
41 {
42         fs_fix_unionfs_image_if_hidden "${PORTSDIR}/Mk/bsd.port.mk" || :
43         fs_fix_unionfs_image_if_hidden "${PORTSDIR}/Makefile" || :
44         if [ ! -d "${PORTSDIR}" ]
45         then
46                 message_echo "ERROR: Ports directory ${PORTSDIR} is not found." >&2
47                 exit 1
48         fi
49         if [ ! -e "${PORTSDIR}/Makefile" -o ! -e "${PORTSDIR}/Mk/bsd.port.mk" ]
50         then
51                 message_echo "ERROR: Ports tree ${PORTSDIR} is missing, broken or incompatible." >&2
52                 exit 1
53         fi
54 }
55
56 # ============= System defined value for the ports/packages =============
57 pkgsys_sysvar ()
58 {
59         local var tmp_work
60         var=$1
61         tmp_work=${TMPDIR}/pkgsys_sysvar__work
62         rm -rf "$tmp_work"
63         mkdir "$tmp_work"
64         fs_fix_unionfs_image_if_hidden "${PORTSDIR}/Mk/bsd.port.mk"
65         make -C "$tmp_work" -f "${PORTSDIR}/Mk/bsd.port.mk" -V "$var" 2> /dev/null
66 }
67
68 # ============= Get the file name of package check sum file =============
69 pkgsys_pkgchksum_file ()
70 {
71         echo CHECKSUM.MD5
72 }
73
74 # ============= Get the origin of the currently used pkg(8) =============
75 # NOTE: Assumed to be unflavored.
76 pkgsys_portsmgmt_pkg ()
77 {
78         local origin_unflavored
79         if [ ! -e "${DBDIR}/PKG_ORIGIN" ]
80         then
81                 origin_unflavored=`pkgsys_sysvar PKG_ORIGIN` || :
82                 [ -n "$origin_unflavored" -a -d "${PORTSDIR}/$origin_unflavored" ] || origin_unflavored=ports-mgmt/pkg
83                 echo "$origin_unflavored" > ${DBDIR}/PKG_ORIGIN
84         fi
85         cat "${DBDIR}/PKG_ORIGIN"
86 }
87
88 # ============= Get the origin of the currently used dialog4ports(1) =============
89 # NOTE: Assumed to be unflavored.
90 pkgsys_portsmgmt_dialog4ports ()
91 {
92         local origin_unflavored
93         if [ ! -e "${DBDIR}/DIALOGPORT" ]
94         then
95                 origin_unflavored=`pkgsys_sysvar DIALOGPORT` || :
96                 [ -n "$origin_unflavored" -a -d "${PORTSDIR}/$origin_unflavored" ] || origin_unflavored=ports-mgmt/dialog4ports
97                 echo "$origin_unflavored" > ${DBDIR}/DIALOGPORT
98         fi
99         cat "${DBDIR}/DIALOGPORT"
100 }
101
102 # ============= Check whether a port is indispensable for the standard function of the ports/packages system =============
103 pkgsys_is_pkgtool ()
104 {
105         local origin origin_unflavored
106         origin=$1
107         origin_unflavored=`echo "$origin" | sed 's/@.*$//'`
108         case $origin_unflavored in
109         ports-mgmt/pkg | ports-mgmt/pkg-devel | ports-mgmt/dialog4ports | ports-mgmt/dialog4ports-static )
110                 ;;
111         *)      return 1
112                 ;;
113         esac
114 }
115
116 # ============= Check whether a port is indispensable for package operations =============
117 pkgsys_is_necessary_pkgtool ()
118 {
119         local origin origin_unflavored
120         origin=$1
121         origin_unflavored=`echo "$origin" | sed 's/@.*$//'`
122         [ x"$WITH_PKGNG" = x'yes' -a \( x"$origin_unflavored" = x'ports-mgmt/pkg' -o x"$origin_unflavored" = x'ports-mgmt/pkg-devel' \) ]
123 }
124
125 # ============= Get the extended regular expression pattern of ports for pkg(8) =============
126 pkgsys_pkgtools_ports_filter_regexp ()
127 {
128         echo '^ports-mgmt/(pkg|pkg-devel|pkg@.*|pkg-devel@.*)$'
129 }
130
131 # ============= Get the extended regular expression pattern of package names for pkg(8) =============
132 pkgsys_pkgtools_pkgs_filter_regexp ()
133 {
134         echo '^(pkg|pkg-devel)-[0-9]\.'
135 }
136
137 # ============= Check whether the dialog for selecting port options is dialog4ports =============
138 pkgsys_is_dialog4ports_used ()
139 {
140         [ -n "`pkgsys_sysvar DIALOG4PORTS`" ]
141 }
142
143 # ============= Get the number of mirror sites for legacy packages =============
144 pkgsys_num_mirrorsites ()
145 {
146         local siteroots
147         siteroots=$1
148         echo "$siteroots" | tr '|' '\n' | wc -l
149 }
150
151 # ============= Get a URL one of mirror sites =============
152 pkgsys_url_from_mirrors ()
153 {
154         local siteroots subdir nsites id_site site platform version
155         siteroots=$1
156         subdir=$2
157         nsites=`pkgsys_num_mirrorsites "$siteroots"`
158         id_site=`(set +e; random -e $nsites; echo $?)`
159         site=`echo "$siteroots" | tr '|' '\n' | sed -n $((${id_site}+1))p`
160         platform=`uname -p`
161         version=`uname -r | cut -d - -f 1,2 | tr [:upper:] [:lower:]`
162         echo -n "$site"
163         printf "$subdir\n" "$platform" "$version"
164 }
165
166 # ============= Fetch a file from one of mirror sites =============
167 pkgsys_fetch_from_mirrors ()
168 {
169         local siteroots subdir filename dst tmp_work fetch itrial origdir url
170         siteroots=$1
171         subdir=$2
172         filename=$3
173         dst=$4
174         tmp_work=${TMPDIR}/pkgsys_fetch_from_mirrors:work
175         rm -rf "$tmp_work"
176         mkdir "$tmp_work"
177         fetch=`pkgsys_sysvar FETCH_CMD`
178         itrial=$((`pkgsys_num_mirrorsites "$siteroots"`*$PKGSYS_AVR_REFETCH_TIMES_PER_SITE))
179         origdir=`pwd`
180         cd "$tmp_work"
181         while [ $itrial -ge 1 ]
182         do
183                 url=`pkgsys_url_from_mirrors "$siteroots" "$subdir"`$filename
184                 message_echo "INFO: Fetching from $url:"
185                 $fetch "$url"&& break
186                 rm -f "$filename"
187                 itrial=$(($itrial-1))
188         done
189         cd "$origdir"
190         [ -e "$tmp_work/$filename" ] || return
191         mv "$tmp_work/$filename" "$dst"
192 }
193
194 # ============= Get the package check sums file ready =============
195 pkgsys_ready_checksum_file ()
196 {
197         local chksumfile
198         tmp_savedpath=${TMPDIR}/pkgsys_ready_checksum_file:savedpath
199         rm -f "$tmp_savedpath"
200         chksumfile=`pkgsys_pkgchksum_file`
201         if [ ! -e "${DBDIR}/checksum/$chksumfile" ]
202         then
203                 [ -d "${DBDIR}/checksum" ] || mkdir "${DBDIR}/checksum"
204                 if ! pkgsys_fetch_from_mirrors "${PACKAGECHECKSUMROOTS}" "${PACKAGECHECKSUMDIR}" \
205                         "$chksumfile" "${DBDIR}/checksum"
206                 then
207                         message_echo "WARNING: No check sum file is available." >&2
208                         return 1
209                 fi
210         fi
211         echo "${DBDIR}/checksum/$chksumfile" > $tmp_savedpath
212 }
213
214 # ============= Get the location of a check sums file fetched by pkgsys_ready_checksum_file =============
215 pkgsys_ready_checksum_file__fetched_file ()
216 {
217         cat "${TMPDIR}/pkgsys_ready_checksum_file:savedpath"
218 }
219
220 # ============= Fetch a legacy package from one of remote sites =============
221 pkgsys_fetch_legacy_remote ()
222 {
223         local pkg tmp_work tmp_pkgpath pkg_regexp checksumpath validMD5 fetchedMD5 needs_fetch itrial
224         pkg=$1
225         tmp_work=${TMPDIR}/pkgsys_fetch_legacy_remote:work
226         tmp_pkgpath=${TMPDIR}/pkgsys_fetch_legacy_remote:pkgpath
227         rm -rf "$tmp_work"
228         mkdir "$tmp_work"
229         pkg_regexp=`str_escape_regexp "$pkg"`
230         pkgsys_ready_checksum_file || return
231         checksumpath=`pkgsys_ready_checksum_file__fetched_file`
232         validMD5=`env LANG=C grep -m 1 -E -e "^MD5[[:space:]]*\($pkg_regexp\.tbz\)[[:space:]]*=" "$checksumpath" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
233         if [ -z "$validMD5" ]
234         then
235                 message_echo "WARNING: No check sum for $pkg.tbz." >&2
236                 return 1
237         fi
238         needs_fetch=yes
239         mkdir -p "${PKGREPOSITORY}"
240         if [ -e "${PKGREPOSITORY}/$pkg.tbz" ]
241         then
242                 if [ -e "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" ]
243                 then
244                         fetchedMD5=`md5 "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
245                         [ "x$fetchedMD5" = "x$validMD5" ] || rm "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz"
246                 fi
247                 if [ -e "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" ]
248                 then
249                         ln -f "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz" "${PKGREPOSITORY}/$pkg.tbz"
250                 else
251                         fetchedMD5=`md5 "${PKGREPOSITORY}/$pkg.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
252                         if [ "x$fetchedMD5" = "x$validMD5" ]
253                         then
254                                 needs_fetch=no
255                         else
256                                 mv "${PKGREPOSITORY}/$pkg.tbz" "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz"
257                         fi
258                 fi
259         fi
260         if [ $needs_fetch = yes ]
261         then
262                 itrial=$PKGSYS_AVR_REFETCH_TIMES_FOR_CHKSUMERR
263                 while [ $itrial -ge 1 ]
264                 do
265                         if pkgsys_fetch_from_mirrors "${PACKAGEROOTS}" "${PACKAGEDIR}" \
266                                 "$pkg.tbz" "$tmp_work"
267                         then
268                                 fetchedMD5=`md5 "$tmp_work/$pkg.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
269                                 [ "x$fetchedMD5" = "x$validMD5" ] && break
270                                 message_echo "WARNING: Check sum mismatches for $pkg.tbz." >&2
271                         fi
272                         itrial=$(($itrial-1))
273                 done
274                 [ $itrial -ge 1 ] || return
275                 mv "$tmp_work/$pkg.tbz" "${PKGREPOSITORY}"
276         fi
277         echo "${PKGREPOSITORY}/$pkg.tbz" > $tmp_pkgpath
278 }
279
280 # ============= Get the location of a package fetched by pkgsys_fetch_legacy_remote =============
281 pkgsys_fetch_legacy_remote__fetched_pkg ()
282 {
283         cat "${TMPDIR}/pkgsys_fetch_legacy_remote:pkgpath"
284 }
285
286 # ============= Check whether the dependency of a legacy package is the latest =============
287 pkgsys_is_dependency_of_a_legacypkg_latest ()
288 {
289         local pkgarc tmp_extract tmp_contents tmp_origin tmp_pkg pkg nlines iline origin_req pkg_req pkg_new
290         pkgarc=$1
291         tmp_extract=${TMPDIR}/pkgng:pkgsys_is_dependency_of_a_legacypkg_latest:extract
292         tmp_contents=${TMPDIR}/pkgng:pkgsys_is_dependency_of_a_legacypkg_latest:contents
293         tmp_origin=${TMPDIR}/pkgng:pkgsys_is_dependency_of_a_legacypkg_latest:origin
294         tmp_pkg=${TMPDIR}/pkgng:pkgsys_is_dependency_of_a_legacypkg_latest:pkg
295         pkg=`pkgsys_pkgarc_to_pkgname "$pkgarc"`
296         [ -e "$pkgarc" ] || return
297         rm -rf "$tmp_extract"
298         mkdir "$tmp_extract"
299         tar xf "$pkgarc" -C "$tmp_extract" +CONTENTS
300         env LANG=C grep -e '^@pkgdep[[:space:]]' -e '^@comment[[:space:]]*DEPORIGIN:' "$tmp_extract/+CONTENTS" \
301                 | sed 's/^@pkgdep[[:space:]]*//;s/^@comment[[:space:]]*DEPORIGIN://' > $tmp_contents
302         nlines=`wc -l < $tmp_contents`
303         iline=1
304         while [ $iline -le $nlines ]
305         do
306                 origin_req=`sed -n ${iline}p "$tmp_contents"`
307                 pkg_req=`sed -n $(($iline+1))p "$tmp_contents"`
308                 iline=$(($iline+2))
309                 pkg_new=`cat "${DBDIR}/requires/$origin_req/new_version" 2> /dev/null` || :
310                 if [ -z "$pkg_new" -o "$pkg_new" != "$pkg_req" ]
311                 then
312                         message_echo "WARNING: Requirements of remote package $pkg are not the latest." >&2
313                         return 1
314                 fi
315         done
316         :
317 }
318
319 # ============= Check whether legacy package tools are available =============
320 pkgsys_is_legacy_tool_available ()
321 {
322         which -s pkg_info
323 }
324
325 # ============= Load portsnap.conf(5) for important directories  =============
326 pkgsys_load_portsnap_conf ()
327 {
328         if which -s portsnap
329         then
330                 PORTSNAP_WORKDIR=`sed -n '/^[[:space:]]*WORKDIR[[:space:]]*=[[:space:]]*\([^[:space:]#]*\)/s//\1/p' /etc/portsnap.conf || :`
331                 PORTSNAP_WORKDIR=${PORTSNAP_WORKDIR:-/var/db/portsnap}
332                 PORTSNAP_PORTSDIR=`sed -n '/^[[:space:]]*PORTSDIR[[:space:]]*=[[:space:]]*\([^[:space:]#]*\)/s//\1/p' /etc/portsnap.conf || :`
333                 PORTSNAP_PORTSDIR=${PORTSNAP_PORTSDIR:-/usr/ports}
334         else
335                 PORTSNAP_WORKDIR=
336                 PORTSNAP_PORTSDIR=
337         fi
338 }
339
340 # ============= Define wrapper commands for hiding the differences between pkg_* tools and pkgng =============
341 pkgsys_def_pkgtools ()
342 {
343         if [ "${DBDIR}/WITH_PKGNG" -nt /etc/make.conf -o \( -e "${DBDIR}/WITH_PKGNG" -a ! -e /etc/make.conf \) ]
344         then
345                 PKGSYS_USE_PKGNG=`cat "${DBDIR}/WITH_PKGNG"`
346         else
347                 PKGSYS_USE_PKGNG=`pkgsys_sysvar WITH_PKG | tr '[:upper:]' '[:lower:]'`
348                 [ -n "$PKGSYS_USE_PKGNG" ] || PKGSYS_USE_PKGNG=`pkgsys_sysvar WITH_PKGNG | tr '[:upper:]' '[:lower:]'`
349                 if [ -d "${DBDIR}" ] && misc_is_superuser_privilege
350                 then
351                         echo "$PKGSYS_USE_PKGNG" > ${DBDIR}/WITH_PKGNG.tmp
352                         mv "${DBDIR}/WITH_PKGNG.tmp" "${DBDIR}/WITH_PKGNG"
353                 fi
354         fi
355         if [ "x$PKGSYS_USE_PKGNG" = xyes ]
356         then
357                 export WITH_PKG=yes
358                 export WITH_PKGNG=yes
359                 PKGSYS_CMD_PKG_DELETE='pkg delete'
360                 pkg_is_tool_ready ()
361                 {
362                         TMPDIR=/dev/null ASSUME_ALWAYS_YES=yes  PACKAGESITE=file:///nonexistent \
363                                 pkg info -x 'pkg(-devel)?$' >/dev/null 2>&1
364                 }
365                 pkg_is_tool_available ()
366                 {
367                         local dev_out dev_err
368                         if [ -x /usr/sbin/pkg ]
369                         then
370                                 dev_out=/dev/stdout
371                                 dev_err=/dev/stderr
372                                 if [ $opt_batch_mode = yes ]
373                                 then
374                                         dev_out=/dev/null
375                                         dev_err=/dev/null
376                                 fi
377                                 pkg_is_tool_ready && return
378                                 env ASSUME_ALWAYS_YES=yes pkg bootstrap -f > $dev_out 2> $dev_err
379                                 pkg_is_tool_ready
380                         else
381                                 which -s pkg
382                         fi
383                 }
384                 pkg_info_Ea ()
385                 {
386                         pkg info -qa 2> /dev/null
387                 }
388 #               pkg_info_qoa ()
389 #               {
390 #                       pkg info -qoa 2> /dev/null
391 #               }
392 #               pkg_info_qox ()
393 #               {
394 #                       pkg info -qox "$@" 2> /dev/null
395 #               }
396 #               pkg_info_qoX ()
397 #               {
398 #                       pkg info -qox "$@" 2> /dev/null
399 #               }
400                 pkg_info_qO ()
401                 {
402                         pkg info -qO "$@" 2> /dev/null
403                 }
404                 pkg_info_qo ()
405                 {
406                         pkg info -qo "$@" 2> /dev/null
407                 }
408                 pkg_info_qr ()
409                 {
410                         pkg info -qd "$@" 2> /dev/null
411                 }
412                 pkg_info_e ()
413                 {
414                         pkg info -qe "$@" 2> /dev/null
415                 }
416                 pkg_info_eO ()
417                 {
418                         pkg info -qeO "$@" 2> /dev/null
419                 }
420                 pkg_info_Eg ()
421                 {
422                         pkg info -Eg "$@" 2> /dev/null
423                 }
424                 pkg_info_qR ()
425                 {
426                         pkg info -qr "$@" 2> /dev/null
427                 }
428                 pkg_info_Ex ()
429                 {
430                         pkg info -Ex "$@" 2> /dev/null
431                 }
432                 pkg_info_qL ()
433                 {
434                         pkg info -ql "$@" 2> /dev/null
435                 }
436                 pkg_info_qs ()
437                 {
438                         # Return the total storage space occupied by the installed files in bytes
439                         pkg info -qs "$@" 2> /dev/null | sed 's/KiB$/*1024/;s/MiB$/*1024^2/;s/GiB$/*1024^3/;s/B$//' | tr '\n' + | sed 's/+$//' | bc -l
440                 }
441                 pkg_info_flavors ()
442                 # For an unflavored pattern, all matching flavors are returned.
443                 {
444                         local glob_unflavored
445                         glob_unflavored=$1
446                         pkg query -g '%At\t%Av' "$glob_unflavored" 2> /dev/null | env LANG=C grep -E '^flavor[[:space:]]' | cut -f 2
447                 }
448                 pkg_info_flavored_origins ()
449                 # For an unflavored pattern, all matching flavors are returned.
450                 {
451                         local glob_unflavored origin_unflavored
452                         glob_unflavored=$1
453                         origin_unflavored=`pkg_info_qo "$glob_unflavored" 2> /dev/null || :`
454                         flavors=`pkg_info_flavors "$glob_unflavored" 2> /dev/null || :`
455                         if [ -z "$flavors" ]
456                         then
457                                 echo "$origin_unflavored"
458                         else
459                                 for flavor in $flavors
460                                 do
461                                         echo "$origin_unflavored@$flavor"
462                                 done
463                         fi
464                 }
465                 pkg_info_all_flavored_origins ()
466                 {
467                         local tmp_flavored tmp_flavored_ptn
468                         tmp_flavored_ptn=${TMPDIR}/pkg_info_all_flavored_origins:flavored_ptn
469                         pkg query '%o\t%At\t%Av' 2> /dev/null | env LANG=C grep -E '^[^[:space:]]+[[:space:]]flavor[[:space:]]' | cut -f 1,3 | tr '\t' @ | sed 's/@$//'
470                         pkg query '%n\t%At' 2> /dev/null | env LANG=C grep -E '^[^[:space:]]+[[:space:]]flavor$' | cut -f 1 > $tmp_flavored_ptn
471                         pkg query '%n\t%o' 2> /dev/null | env LANG=C grep -vFx -f "$tmp_flavored_ptn" | cut -f 2
472                 }
473                 pkg_check_sanity ()
474                 {
475                         local pkg tmp_stdout tmp_stderr
476                         pkg=$1
477                         tmp_stdout=${TMPDIR}/pkgng:pkg_check_sanity:stdout
478                         tmp_stderr=${TMPDIR}/pkgng:pkg_check_sanity:stderr
479                         pkg check -s "$pkg" > $tmp_stdout 2> $tmp_stderr || :
480                         {
481                                 env LANG=C grep '^[^:]*: checksum mismatch for ' "$tmp_stderr" | sed 's/^[^:]*: checksum mismatch for //' || :
482                                 env LANG=C grep '^[^:]*: missing file ' "$tmp_stderr" | sed 's/^[^:]*: missing file //' || :
483                                 if env LANG=C grep -q '^pkg: .*: No such file or directory$' "$tmp_stderr"      # For the old specification of pkg(8)
484                                 then
485                                         pkg info -ql "$pkg" 2> /dev/null | while read filepath
486                                         do
487                                                 [ -e "$filepath" ] || echo "$filepath"
488                                         done
489                                 fi
490                         } | sort -u || :
491                 }
492                 pkg_which ()
493                 {
494                         local filepath
495                         filepath=$1
496                         pkg which -q "$filepath" 2> /dev/null
497                 }
498                 pkg_info_gen_pkg_origin_table ()
499                 {
500                         local pkgname origin
501                         #       pkg query -g '%n-%v\t%o' \* 2> /dev/null > ${DBDIR}/installed_ports:pkg_vs_origin.tbl
502                         for pkgname in `pkg info -qa 2> /dev/null`
503                         do
504                                 for origin in `pkg_info_flavored_origins "$pkgname"`
505                                 do
506                                         printf '%s\t%s\n' "$pkgname" "$origin"
507                                 done
508                         done
509                 }
510                 pkg_create_b ()
511                 {
512                         pkg create "$@"
513                 }
514                 pkg_delete_f ()
515                 {
516                         local opt_del opt_quit dev_out dev_err
517                         opt_del=
518                         [ $opt_no_exec_inst_script = yes ] && opt_del='-D'
519                         opt_quit=
520                         dev_out=/dev/stdout
521                         dev_err=/dev/stderr
522                         if [ $opt_batch_mode = yes ]
523                         then
524                                 opt_quit='-q'
525                                 dev_out=/dev/null
526                                 dev_err=/dev/null
527                         fi
528                         pkg delete -fqy $opt_del "$@" > $dev_out 2> $dev_err || :
529                         pkg_is_tool_ready || return 0   # If pkg(8) is deinstalled successfully
530                         pkg info -e $opt_quit "$@" > /dev/null 2>&1 || return 0
531                         pkg delete -fy $opt_del "$@" > $dev_out 2> $dev_err     # Countermeasure for a bug found for pkg-1.3.4 (at least not until 1.2.7_4)
532                 }
533                 pkg_add_tools ()
534                 {
535                         local pkgarc tmp_extract prefix prefix_parent pkg opt_quit dev_out dev_err
536                         pkgarc=$1
537                         tmp_extract=${TMPDIR}/pkgng:pkg_add_tools:extract
538                         opt_quit=
539                         dev_out=/dev/stdout
540                         dev_err=/dev/stderr
541                         if [ $opt_batch_mode = yes ]
542                         then
543                                 opt_quit='-q'
544                                 dev_out=/dev/null
545                                 dev_err=/dev/null
546                         fi
547                         rm -rf "$tmp_extract"
548                         mkdir "$tmp_extract"
549                         tar xf "$pkgarc" -C "$tmp_extract" > $dev_out 2> $dev_err
550                         pkg=`pkgsys_pkgarc_to_pkgname "$pkgarc"`
551                         if env ASSUME_ALWAYS_YES=YES $tmp_extract/usr/local/sbin/pkg-static add $opt_quit "$pkgarc" > $dev_out 2> $dev_err
552                         then
553                                 message_echo "INFO: $pkg is successfully registered."
554                         else
555                                 message_echo "WARNING: Failed to register $pkg, but the process is continued." >&2
556                                 return 1
557                         fi
558                 }
559                 pkg_add_f_common ()
560                 {
561                         local option pkgarc pkg pkg_tool pkg_gen opt_add opt_quit dev_out dev_err
562                         option=$1
563                         shift || :
564                         pkg_tool=
565                         pkg_gen=
566                         for pkgarc in "$@"
567                         do
568                                 pkg=`basename "$pkgarc"`
569                                 if expr "$pkg" : '^pkg-[0-9][0-9]*\..*' > /dev/null
570                                 then
571                                         pkg_tool=$pkgarc
572                                 else
573                                         pkg_gen="$pkg_gen $pkgarc"
574                                 fi
575                         done
576                         [ -n "$pkg_tool" ] && pkg_add_tools "$pkg_tool"
577                         if [ -n "$pkg_gen" ]
578                         then
579                                 rm -rf "${TMPDIR}/pkg_add_f"
580                                 mkdir -p "${TMPDIR}/pkg_add_f"
581                                 opt_add=
582                                 [ $opt_no_exec_inst_script = yes ] && opt_add='-I'
583                                 opt_quit=
584                                 dev_out=/dev/stdout
585                                 dev_err=/dev/stderr
586                                 if [ $opt_batch_mode = yes ]
587                                 then
588                                         opt_quit='-q'
589                                         dev_out=/dev/null
590                                         dev_err=/dev/null
591                                 fi
592                                 ( cd "${TMPDIR}/pkg_add_f" && ln -s $pkg_gen && env ASSUME_ALWAYS_YES=YES pkg add -M $option $opt_quit $opt_add * > $dev_out 2> $dev_err )
593                         fi
594                 }
595                 pkg_add_f ()
596                 {
597                         pkg_add_f_common '' "$@"
598                 }
599                 pkg_add_fF ()
600                 {
601                         pkg_add_f_common '-f' "$@"
602                 }
603                 pkg_inst_verify_pkg ()
604                 {
605                         local pkg pkgarc
606                         pkg=$1
607                         pkgarc=`pkgsys_pkgname_to_pkgarc "${PKGNG_PKG_CACHEDIR}" "$pkg"` || return
608                         tar tf "$pkgarc" > /dev/null 2>&1
609                 }
610                 pkg_inst_remote_fetch ()
611                 {
612                         local pkg opt_quit
613                         pkg=$1
614                         opt_quit=
615                         [ $opt_batch_mode = yes ] && opt_quit='-q'
616                         pkg fetch -yU $opt_quit "$pkg"
617                 }
618                 pkg_inst_remote_verify_fetch ()
619                 {
620                         local pkg
621                         pkg=$1
622                         pkg_inst_verify_pkg "$pkg" && return
623                         pkg_inst_remote_fetch "$pkg" && pkg_inst_verify_pkg "$pkg"
624                 }
625                 pkg_inst_remote ()
626                 {
627                         local pkg pkgarc opt_add opt_quit dev_out dev_err
628                         pkg=$1
629                         pkg_inst_remote_verify_fetch "$pkg" || return
630                         pkgarc=`pkgsys_pkgname_to_pkgarc "${PKGNG_PKG_CACHEDIR}" "$pkg"` || return
631                         rm -rf "${TMPDIR}/pkg_inst_remote"
632                         mkdir -p "${TMPDIR}/pkg_inst_remote"
633                         opt_add=
634                         [ $opt_no_exec_inst_script = yes ] && opt_add='-I'
635                         opt_quit=
636                         dev_out=/dev/stdout
637                         dev_err=/dev/stderr
638                         if [ $opt_batch_mode = yes ]
639                         then
640                                 opt_quit='-q'
641                                 dev_out=/dev/null
642                                 dev_err=/dev/null
643                         fi
644                         ( cd "${TMPDIR}/pkg_inst_remote" && ln -s "$pkgarc" && env ASSUME_ALWAYS_YES=YES pkg add -fM $opt_quit $opt_add * > $dev_out 2> $dev_err )
645                 }
646                 pkg_inst_wild_verify_pkg ()
647                 {
648                         local pkg pkgarc
649                         pkg=$1
650                         pkgarc=`pkgsys_pkgname_to_pkgarc "${PKGNG_PKG_CACHEDIR}" "$pkg"` || return
651                         pkgsys_is_dependency_of_a_legacypkg_latest "$pkgarc"
652                 }
653                 pkg_inst_remote_wild_fetch ()
654                 {
655                         local pkg
656                         pkg=$1
657                         if pkg_is_tool_available
658                         then
659                                 pkg_inst_remote "$pkg" && return
660                         fi
661                         pkgsys_is_legacy_tool_available || return
662                         message_echo "INFO: Trying to use a legacy package and convert it to pkgng."
663                         pkgsys_fetch_legacy_remote "$pkg"
664                 }
665                 pkg_inst_remote_wild_verify_fetch ()
666                 {
667                         local pkg
668                         pkg=$1
669                         pkg_inst_wild_verify_pkg "$pkg" && return
670                         pkg_inst_remote_wild_fetch "$pkg" && pkg_inst_wild_verify_pkg "$pkg"
671                 }
672                 pkg_inst_remote_wild ()
673                 {
674                         local pkg pkgarc opt_add dev_out dev_err
675                         pkg=$1
676                         if pkg_inst_remote_wild_verify_fetch "$pkg"
677                         then
678                                 pkgarc=`pkgsys_fetch_legacy_remote__fetched_pkg`
679                                 rm -rf "${TMPDIR}/pkg_inst_remote_wild"
680                                 mkdir -p "${TMPDIR}/pkg_inst_remote_wild"
681                                 opt_add=
682                                 [ $opt_no_exec_inst_script = yes ] && opt_add='-I'
683                                 dev_out=/dev/stdout
684                                 dev_err=/dev/stderr
685                                 if [ $opt_batch_mode = yes ]
686                                 then
687                                         dev_out=/dev/null
688                                         dev_err=/dev/null
689                                 fi
690                                 ( cd "${TMPDIR}/pkg_inst_remote_wild" && ln -s "$pkgarc" && pkg_add -ifF $opt_add * > $dev_out 2> $dev_err) || return
691                                 message_echo "INFO: Trying to convert the installed legacy package to pkgng."
692                                 pkg2ng > $dev_out 2> $dev_err || :
693                                 message_echo "INFO: Checking whether the conversion is successful."
694                                 pkg info -qe "$pkg" 2> /dev/null
695                         fi
696                 }
697                 pkg_get_remote_repository_version ()
698                 {
699                         local origin origin_unflavored pkg
700                         origin=$1
701                         origin_unflavored=`expr "$origin" : '\([^@]*\)'` || return
702                         [ -n "$origin_unflavored" ] || return
703                         pkg fetch -qyU "$origin_unflavored" || return
704                         pkg=`pkg rquery -U %n-%v "$origin_unflavored"` || return
705                         echo "$pkg"
706                 }
707                 pkg_get_pkgs_timestamps ()
708                 {
709                         pkg query '%n-%v\tng-epoch:%t' "$@" 2> /dev/null
710                 }
711                 pkg_get_pkg_timestamp ()
712                 {
713                         local pkg
714                         pkg=$1
715                         pkg query '%t' "$pkg" 2> /dev/null
716                 }
717                 pkg_loadconf ()
718                 {
719                         local pkg_conf
720                         # Deafult configuration for pkg(1)
721                         PKGNG_PACKAGESITE='http://pkg.freebsd.org/${ABI}/latest'
722                         PKGNG_SRV_MIRRORS=YES
723                         PKGNG_PKG_DBDIR=/var/db/pkg
724                         PKGNG_PKG_CACHEDIR=/var/cache/pkg
725                         PKGNG_PORTSDIR=/usr/ports
726                         PKGNG_PUBKEY=/etc/ssl/pkg.conf
727                         PKGNG_HANDLE_RC_SCRIPTS=NO
728                         PKGNG_PKG_MULTIREPOS=NO
729                         PKGNG_ASSUME_ALWAYS_YES=NO
730                         PKGNG_SYSLOG=YES
731                         PKGNG_SHLIBS=NO
732                         PKGNG_AUTODEPS=NO
733                         PKGNG_PORTAUDIT_SITE='http=//portaudit.FreeBSD.org/auditfile.tbz'
734                         # Load configuration for pkg(1)
735                         pkg_conf=`pkg query %Fp pkg 2> /dev/null | env LANG=C grep '/etc/pkg\.conf\.sample$' | sed 's/\.sample$//'` || :
736                         [ -n "$pkg_conf" ] || pkg_conf=${MYPREFIX}/etc/pkg.conf
737                         env LANG=C grep -v -e '^[[:space:]]*#' -e '^[[:space:]]*$' "$pkg_conf" 2> /dev/null \
738                                 | env LANG=C grep -e '^[[:space:]]*[A-Z0-9_]*[[:space:]]*:[[:space:]]*.*' \
739                                 | while read srcline
740                         do
741                                 var=`expr "$srcline" : '^[[:space:]]*\([A-Z0-9_]*\)[[:space:]]*:.*'` || :
742                                 val=`expr "$srcline" : '^[[:space:]]*[A-Z0-9_]*[[:space:]]*:[[:space:]]*\(.*\)'` || :
743                                 eval PKGNG_$var=\$val
744                                 misc_get_all_vardefs | env LANG=C grep "^PKGNG_$var="
745                         done > ${TMPDIR}/pkgsys_def_pkgtools:pkg.conf.sh
746                         . "${TMPDIR}/pkgsys_def_pkgtools:pkg.conf.sh"
747                 }
748                 pkg_rescue_tools ()
749                 {
750                         local origin_portsmgmt packagepath checksumpath pkgname is_successful dev_out dev_err
751                         origin_portsmgmt=`pkgsys_portsmgmt_pkg`
752                         pkg_is_tool_ready && return
753                         packagepath=`pkgsys_get_backup_pkg "$origin_portsmgmt"` && \
754                                 pkg_add_tools "$packagepath" && return
755                         pkg_is_tool_available && return
756                         message_echo "WARNING: WITH_PKG or WITH_PKGNG is set, but pkgng is still missing. It is installed now." >&2
757                         pkgsys_ready_checksum_file || return
758                         message_echo "INFO: Installing pkgng by legacy package tool."
759                         checksumpath=`pkgsys_ready_checksum_file__fetched_file`
760                         pkgname=`sed 's/^MD5[[:space:]]*(//;s/\.tbz)[[:space:]]*=[^=]*$//' "$checksumpath" \
761                                 | env LANG=C grep -m 1 '^pkg-[0-9]'` || :
762                         [ -n "$pkgname" ] && pkg_inst_remote_wild "$pkgname" && return
763                         message_echo "INFO: Failed by package, so installing pkgng by port."
764                         env LANG=C grep -Ev '^[[:space:]]*(WITH_PKG|WITH_PKGNG)=' /etc/make.conf > ${TMPDIR}/make.conf 2> /dev/null || :
765                         echo WITHOUT_PKG=yes >> ${TMPDIR}/make.conf
766                         echo WITHOUT_PKGNG=yes >> ${TMPDIR}/make.conf
767                         dev_out=/dev/stdout
768                         dev_err=/dev/stderr
769                         if [ $opt_batch_mode = yes ]
770                         then
771                                 dev_out=/dev/null
772                                 dev_err=/dev/null
773                         fi
774                         ( set -e
775                                 unset WITH_PKG
776                                 unset WITH_PKGNG
777                                 unset WITHOUT_PKG
778                                 unset WITHOUT_PKGNG
779                                 message_echo "INFO: Attempting deinstallation of pkg(8) to make sure."
780                                 portsmgmt_port_path=`pkgsys_get_portpath_from_origin "$origin_portsmgmt"`
781                                 fs_fix_unionfs_image_if_hidden "${TMPDIR}/make.conf"
782                                 env __MAKE_CONF="${TMPDIR}/make.conf" make -C "$portsmgmt_port_path" deinstall > $dev_out 2> $dev_err || :
783                                 message_echo "INFO: Attempting (re)installation by pkg(8)."
784                                 env __MAKE_CONF="${TMPDIR}/make.conf" make -C "$portsmgmt_port_path" reinstall clean > $dev_out 2> $dev_err
785                         ) && {
786                                 pkg2ng > $dev_out 2> $dev_err || :
787                                 pkg_is_tool_available
788                         }
789                 }
790                 pkg_update_pkgrepository ()
791                 {
792                         local opts
793                         pkg_rescue_tools || return 0
794                         if [ $opt_batch_mode = no ]
795                         then
796                                 opts=
797                         else
798                                 opts='-q'
799                         fi
800                         pkg update $opts
801                 }
802                 if ! pkg_rescue_tools
803                 then
804                         message_echo "WARNING: Pkgng is still missing, but continuing for the time being." >&2
805                 fi
806                 pkg_loadconf
807         elif ! pkgsys_is_legacy_tool_available
808         then
809                 message_echo "ERROR: Pkgng is disabled although the legacy packages tools are unavailable. Resolve the problem manually." >&2
810                 exit 1
811         else
812                 unset WITH_PKG
813                 unset WITH_PKGNG
814                 PKGSYS_USE_PKGNG=no
815                 PKGSYS_CMD_PKG_DELETE='pkg_delete'
816                 pkg_is_tool_ready ()
817                 {
818                         pkgsys_is_legacy_tool_available
819                 }
820                 pkg_is_tool_available ()
821                 {
822                         pkgsys_is_legacy_tool_available
823                 }
824                 pkg_info_Ea ()
825                 {
826                         pkg_info -Ea 2> /dev/null
827                 }
828 #               pkg_info_qoa ()
829 #               {
830 #                       pkg_info -qoa 2> /dev/null
831 #               }
832 #               pkg_info_qox ()
833 #               {
834 #                       pkg_info -qox "$@" 2> /dev/null
835 #               }
836 #               pkg_info_qoX ()
837 #               {
838 #                       pkg_info -qoX "$@" 2> /dev/null
839 #               }
840                 pkg_info_qO ()
841                 {
842                         pkg_info -qO "$@" 2> /dev/null
843                 }
844                 pkg_info_qo ()
845                 {
846                         pkg_info -qo "$@" 2> /dev/null
847                 }
848                 pkg_info_qr ()
849                 {
850                         pkg_info -qr "$@" 2> /dev/null | sed -n 's/^@pkgdep[[:space:]]*//p'
851                 }
852                 pkg_info_e ()
853                 {
854                         pkg_info -qe "$@" 2> /dev/null
855                 }
856                 pkg_info_eO ()
857                 {
858                         [ `pkg_info -qO "$@" 2> /dev/null | wc -l` -gt 0 ]
859                 }
860                 pkg_info_Eg ()
861                 {
862                         pkg_info -E "$@" 2> /dev/null
863                 }
864                 pkg_info_qR ()
865                 {
866                         pkg_info -qR "$@" 2> /dev/null | env LANG=C grep -v '^$'
867                 }
868                 pkg_info_Ex ()
869                 {
870                         pkg_info -Ex "$@" 2> /dev/null
871                 }
872                 pkg_info_qL ()
873                 {
874                         pkg_info -qL "$@" 2> /dev/null
875                 }
876                 pkg_info_qs ()
877                 {
878                         # Return the total storage space occupied by the installed files in bytes
879                         pkg_info -qs "$@" 2> /dev/null | sed 's/[^0-9]*/*1024/' | tr '\n' + | sed 's/+$//' | bc -l
880                 }
881                 pkg_info_flavors ()
882                 {
883                         pkg_info -qe "$@" 2> /dev/null && echo
884                         :
885                 }
886                 pkg_info_flavored_origins ()
887                 {
888                         local glob_unflavored tmp_stdout
889                         glob_unflavored=$1
890                         pkg_info_qo "$glob_unflavored" 2> /dev/null
891                 }
892                 pkg_info_all_flavored_origins ()
893                 {
894                         pkg_info_qoa 2> /dev/null
895                 }
896                 pkg_check_sanity ()
897                 {
898                         local pkg tmp_stdout tmp_stderr
899                         pkg=$1
900                         tmp_stdout=${TMPDIR}/pkgng:pkg_check_sanity:stdout
901                         tmp_stderr=${TMPDIR}/pkgng:pkg_check_sanity:stderr
902                         pkg_info -qg "$pkg" > $tmp_stdout 2> $tmp_stderr || :
903                         sed -n 's/ fails the original MD5 checksum$//p' "$tmp_stdout" 2> /dev/null || :
904                         sed -nE "s/^pkg_info: (.*) doesn't exist$/\1/p" "$tmp_stderr" 2> /dev/null || :
905                 }
906                 pkg_which ()
907                 {
908                         local filepath
909                         filepath=$1
910                         pkg_info -qW "$filepath" 2> /dev/null
911                 }
912                 pkg_info_gen_pkg_origin_table ()
913                 {
914                         pkg_info -aE 2> /dev/null | while read pkg
915                         do
916                                 origin=`pkg_info -qo "$pkg" 2> /dev/null`
917                                 printf '%s\t%s\n' "$pkg" "$origin"
918                         done
919                 }
920                 pkg_create_b ()
921                 {
922                         local dev_out dev_err
923                         dev_out=/dev/stdout
924                         dev_err=/dev/stderr
925                         if [ $opt_batch_mode = yes ]
926                         then
927                                 dev_out=/dev/null
928                                 dev_err=/dev/null
929                         fi
930                         pkg_create -b "$@" > $dev_out 2> $dev_err
931                 }
932                 pkg_delete_f ()
933                 {
934                         local opt_del dev_out dev_err
935                         opt_del=
936                         [ $opt_no_exec_inst_script = yes ] && opt_del='-D'
937                         dev_out=/dev/stdout
938                         dev_err=/dev/stderr
939                         if [ $opt_batch_mode = yes ]
940                         then
941                                 dev_out=/dev/null
942                                 dev_err=/dev/null
943                         fi
944                         pkg_delete -f $opt_del "$@" > $dev_out 2> $dev_err
945                 }
946                 pkg_add_f ()
947                 {
948                         local opt_add dev_out dev_err
949                         rm -rf "${TMPDIR}/pkg_add_f"
950                         mkdir -p "${TMPDIR}/pkg_add_f"
951                         ln -s "$@" "${TMPDIR}/pkg_add_f"
952                         opt_add=
953                         [ $opt_no_exec_inst_script = yes ] && opt_add='-I'
954                         dev_out=/dev/stdout
955                         dev_err=/dev/stderr
956                         if [ $opt_batch_mode = yes ]
957                         then
958                                 dev_out=/dev/null
959                                 dev_err=/dev/null
960                         fi
961                         ( cd "${TMPDIR}/pkg_add_f" && pkg_add -if $opt_add * > $dev_out 2> $dev_err )
962                 }
963                 pkg_add_fF ()
964                 {
965                         local opt_add dev_out dev_err
966                         rm -rf "${TMPDIR}/pkg_add_f"
967                         mkdir -p "${TMPDIR}/pkg_add_f"
968                         ln -s "$@" "${TMPDIR}/pkg_add_f"
969                         opt_add=
970                         [ $opt_no_exec_inst_script = yes ] && opt_add='-I'
971                         dev_out=/dev/stdout
972                         dev_err=/dev/stderr
973                         if [ $opt_batch_mode = yes ]
974                         then
975                                 dev_out=/dev/null
976                                 dev_err=/dev/null
977                         fi
978                         ( cd "${TMPDIR}/pkg_add_f" && pkg_add -ifF $opt_add * > $dev_out 2> $dev_err )
979                 }
980                 pkg_inst_verify_pkg ()
981                 {
982                         local pkg pkgarc
983                         pkg=$1
984                         pkgarc=`pkgsys_fetch_legacy_remote__fetched_pkg` || return
985                         pkgsys_is_dependency_of_a_legacypkg_latest "$pkgarc"
986                 }
987                 pkg_inst_remote_fetch ()
988                 {
989                         local pkg
990                         pkg=$1
991                         pkgsys_fetch_legacy_remote "$pkg"
992                 }
993                 pkg_inst_remote_verify_fetch ()
994                 {
995                         local pkg
996                         pkg=$1
997                         pkg_inst_verify_pkg "$pkg" && return
998                         pkg_inst_remote_fetch "$pkg" && pkg_inst_verify_pkg "$pkg"
999                 }
1000                 pkg_inst_remote ()
1001                 {
1002                         local pkg pkgarc opt_add dev_out dev_err
1003                         pkg=$1
1004                         if pkg_inst_remote_verify_fetch "$pkg"
1005                         then
1006                                 pkgarc=`pkgsys_fetch_legacy_remote__fetched_pkg`
1007                                 rm -rf "${TMPDIR}/pkg_inst_remote"
1008                                 mkdir -p "${TMPDIR}/pkg_inst_remote"
1009                                 ln -s "$@" "${TMPDIR}/pkg_add_f"
1010                                 opt_add=
1011                                 [ $opt_no_exec_inst_script = yes ] && opt_add='-I'
1012                                 dev_out=/dev/stdout
1013                                 dev_err=/dev/stderr
1014                                 if [ $opt_batch_mode = yes ]
1015                                 then
1016                                         dev_out=/dev/null
1017                                         dev_err=/dev/null
1018                                 fi
1019                                 ( cd "${TMPDIR}/pkg_inst_remote" && ls -s "$pkgarc" && pkg_add -ifF $opt_add * > $dev_out 2> $dev_err )
1020                         fi
1021                 }
1022                 pkg_inst_wild_verify_pkg ()
1023                 {
1024                         pkg_inst_verify_pkg "$@"
1025                 }
1026                 pkg_inst_remote_wild_fetch ()
1027                 {
1028                         pkg_inst_remote_fetch "$@"
1029                 }
1030                 pkg_inst_remote_wild_verify_fetch ()
1031                 {
1032                         pkg_inst_remote_verify_fetch "$@"
1033                 }
1034                 pkg_inst_remote_wild ()
1035                 {
1036                         pkg_inst_remote "$@"
1037                 }
1038                 pkg_get_remote_repository_version ()
1039                 {
1040                         local origin checksumpath version_regexp pkgbase_regexp pkg
1041                         origin=$1
1042                         pkgsys_ready_checksum_file > /dev/null || return
1043                         checksumpath=`pkgsys_ready_checksum_file__fetched_file`
1044                         version_regexp=`database_build_make "$origin" -V PORTVERSION | str_escape_regexp_filter`
1045                         pkgbase_regexp=`database_build_get_new_pkgname "$origin" | sed -E "s/$version_regexp$//" | str_escape_regexp_filter`
1046                         pkg=`sed -nE "s/^MD5[[:space:]]*\(($pkgbase_regexp.*)\.tbz\)[[:space:]]*=.*/\1/p" "$checksumpath" | head -n 1`
1047                         echo "$pkg"
1048                 }
1049                 pkg_get_pkgs_timestamps ()
1050                 {
1051                         stat -t %s -f $'legacy:%m\t%N' ${PKG_DBDIR} 2> /dev/null || :
1052                 }
1053                 pkg_get_pkg_timestamp ()
1054                 {
1055                         local pkg portdb
1056                         pkg=$1
1057                         portdb=`echo "$pkg" | sed 's/-[0-9].*//'`
1058                         stat -t %s -f %m "${PKG_DBDIR}/$portdb" 2> /dev/null || :
1059                 }
1060                 pkg_loadconf () { :; }
1061                 pkg_rescue_tools () { :; }
1062                 pkg_update_pkgrepository () { :; }
1063         fi
1064 }
1065
1066 # ============= Get the unflavored part of a flavored origin =============
1067 pkgsys_get_unflavored_origin ()
1068 {
1069         local origin origin_unflavored
1070         origin=$1
1071         origin_unflavored=`echo "$origin" | sed 's/@.*$//'`
1072         echo "$origin_unflavored"
1073 }
1074
1075 # ============= Get the port path from a flavored origin =============
1076 pkgsys_get_portpath_from_origin ()
1077 {
1078         local origin origin_unflavored
1079         origin=$1
1080         origin_unflavored=`pkgsys_get_unflavored_origin "$origin"`
1081         echo "${PORTSDIR}/$origin_unflavored"
1082 }
1083
1084 # ============= Get the flavor from a flavored origin =============
1085 pkgsys_get_flavor_from_origin ()
1086 {
1087         local origin flavor
1088         origin=$1
1089         flavor=`echo "$origin" | sed -E 's/^[^@]*@?//'`
1090         echo "$flavor"
1091 }
1092
1093 # ============= Compose a flavored origin name =============
1094 pkgsys_compose_flavored_origin ()
1095 {
1096         local origin flavor
1097         origin=$1
1098         flavor=$2
1099         origin_unflavored=`pkgsys_get_unflavored_origin "$origin"`
1100         [ -z "$flavor" ] || flavor=@$flavor
1101         echo "$origin_unflavored$flavor"
1102 }
1103
1104 # ============= Check existence of a port for a flavored origin =============
1105 pkgsys_exists_port ()
1106 {
1107         local origin port_path
1108         origin=$1
1109         port_path=`pkgsys_get_portpath_from_origin "$origin"`
1110         [ -d "$port_path" ]
1111 }
1112
1113 # ============= Get the installed package name from a flavored origin =============
1114 pkgsys_get_installed_pkg_from_origin ()
1115 {
1116         local origin origin_unflavored flavor_origin flavor_pkg
1117         origin=$1
1118         origin_unflavored=`pkgsys_get_unflavored_origin "$origin"`
1119         flavor_origin=`pkgsys_get_flavor_from_origin "$origin"`
1120         if [ -n "$flavor_origin" ]
1121         then
1122                 for pkgname in `pkg_info_qO "$origin_unflavored" 2> /dev/null`
1123                 do
1124                         for flavor_pkg in `pkg_info_flavors "$pkgname"`
1125                         do
1126                                 if [ "x$flavor_origin" = "x$flavor_pkg" ]
1127                                 then
1128                                         echo "$pkgname"
1129                                         return
1130                                 fi
1131                         done
1132                 done
1133         else
1134                 pkg_info_qO "$origin_unflavored" 2> /dev/null
1135         fi
1136         :
1137 }
1138
1139 # ============= Get the installed package name from glob patterns =============
1140 pkgsys_get_installed_pkg_from_glob ()
1141 {
1142         local glob regexp
1143         for glob in "$@"
1144         do
1145                 [ -z "$glob" ] && continue
1146                 if regexp=`expr "$glob" : ':\(.*\)'`
1147                 then
1148                         pkg_info_Ex "$regexp"
1149                 else
1150                         pkg_info_Eg "$glob"
1151                 fi
1152         done | sort -u
1153 }
1154
1155 # ============= Check existence of an installed package for a flavored origin =============
1156 pkgsys_exists_from_orig ()
1157 {
1158         local origin origin_unflavored flavor_origin flavor_pkg
1159         origin=$1
1160         origin_unflavored=`pkgsys_get_unflavored_origin "$origin"`
1161         pkg_info_eO "$origin_unflavored" 2> /dev/null || return
1162         flavor_origin=`pkgsys_get_flavor_from_origin "$origin"`
1163         for flavor_pkg in `pkg_info_flavors "$origin_unflavored"`
1164         do
1165                 [ "x$flavor_origin" = "x$flavor_pkg" ] && return
1166         done
1167         false
1168 }
1169
1170 # ============= Generate the package names vs origins table at the initial state =============
1171 pkgsys_gen_init_pkg_origin_table ()
1172 {
1173         [ -e "${DBDIR}/installed_ports:pkg_vs_origin.tbl" ] && return
1174         pkg_info_gen_pkg_origin_table > ${DBDIR}/installed_ports:pkg_vs_origin.tbl.tmp || :
1175         mv "${DBDIR}/installed_ports:pkg_vs_origin.tbl.tmp" "${DBDIR}/installed_ports:pkg_vs_origin.tbl"
1176 }
1177
1178 # ============= Check existence of initially or currently installed package for a flavored origin =============
1179 pkgsys_exists_or_existed_from_orig ()
1180 {
1181         local origin
1182         origin=$1
1183         cut -f 2 "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
1184                 | env LANG=C grep -q -Fx "$origin" || pkgsys_exists_from_orig "$origin"
1185 }
1186
1187 # ============= Get the name of an initially installed package for a flavored origin =============
1188 pkgsys_get_init_pkg_from_orig ()
1189 {
1190         local origin tmppkg origin_regexp npkgs origin_unflavored flavor_origin flavor_pkg
1191         origin=$1
1192         tmppkg=${TMPDIR}/pkgsys_get_init_pkg_from_orig::pkg
1193         origin_regexp=`str_escape_regexp "$origin"`
1194         sed -n -E "/[[:space:]]$origin_regexp$/p" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
1195                 | cut -f 1 > $tmppkg || :
1196         npkgs=`wc -l < $tmppkg`
1197         if [ $npkgs -gt 0 ]
1198         then
1199                 cat "$tmppkg"
1200         else
1201                 origin_unflavored=`pkgsys_get_unflavored_origin "$origin"`
1202                 flavor_origin=`pkgsys_get_flavor_from_origin "$origin"`
1203                 for pkgname in `pkg_info_qO "$origin_unflavored" 2> /dev/null`
1204                 do
1205                         for flavor_pkg in `pkg_info_flavors "$pkgname"`
1206                         do
1207                                 if [ "x$flavor_origin" = "x$flavor_pkg" ]
1208                                 then
1209                                         echo "$pkgname"
1210                                         return
1211                                 fi
1212                         done
1213                 done
1214         fi
1215         :
1216 }
1217
1218 # ============= Get the package name of this utility =============
1219 pkgsys_get_my_current_pkg ()
1220 {
1221         pkg_info_Ex "${PROGRAM}-[0-9].*"
1222 }
1223
1224 # ============= Get the flavored origin of this utility =============
1225 pkgsys_get_my_origin ()
1226 {
1227         local pkgname
1228         for pkgname in `pkgsys_get_my_current_pkg`
1229         do
1230                 pkg_info_flavored_origins "$pkgname"
1231         done
1232 }
1233
1234 # ============= Get the flavored origin of an initially installed package by ambiguous matching =============
1235 pkgsys_init_pkg_orig_by_ambiguous_matching ()
1236 {
1237         local pkg origin tmporigin ambsuffix len_pkg pkg_regexp norigins
1238         pkg=$1
1239         tmporigin=${TMPDIR}/pkgsys_init_pkg_orig_by_ambiguous_matching::origin
1240         pkg_info_flavored_origins "$pkg" > $tmporigin
1241         [ `wc -l < $tmporigin` -gt 0 ] && { cat "$tmporigin"; return; }
1242         ambsuffix=
1243         norigins=0
1244         len_pkg=`echo -n "$pkg" | wc -c`
1245         if [ $len_pkg -gt 0 ]
1246         then
1247                 while :
1248                 do
1249                         pkg_regexp=`str_escape_regexp "$pkg"`$ambsuffix
1250                         env LANG=C grep -E "^${pkg_regexp}[[:space:]]" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
1251                                 | cut -f 2 > $tmporigin
1252                         norigins=`wc -l < $tmporigin`
1253                         [ $norigins -gt 0 ] && break
1254                         ambsuffix='[a-zA-Z0-9.,_+-]*'
1255                         len_pkg=$(($len_pkg-1))
1256                         [ $len_pkg -gt 0 ] || break
1257                         pkg=`echo -n "$pkg" | head -c $len_pkg`
1258                 done
1259         fi
1260         [ $norigins -eq 1 ] || return
1261         cat "$tmporigin"
1262 }
1263
1264 # ============= A part of message indicating tools for showing concerned issues in UPDATING =============
1265 pkgsys_show_pkg_updating_commands ()
1266 {
1267         if [ "x$PKGSYS_USE_PKGNG" = xyes ]
1268         then
1269                 if which -s pkg_updating
1270                 then
1271                         echo 'pkg-updating(8) or pkg_updating(1)'
1272                 else
1273                         echo 'pkg-updating(8)'
1274                 fi
1275         elif which -s pkg_updating
1276         then
1277                 echo 'pkg_updating(1)'
1278         fi
1279 }
1280
1281 # ============= Evaluation of flavored ports globs =============
1282 pkgsys_eval_ports_glob ()
1283 {
1284         local pkglist unflavored_origlist tmp_flavors
1285         pkglist=${DBDIR}/pkgsys_eval_ports_glob:pkg.lst
1286         unflavored_origlist=${DBDIR}/pkgsys_eval_ports_glob:origin_unflavored.lst
1287         tmp_flavors=${TMPDIR}/pkgsys_eval_ports_glob:flavors
1288         # Test the access privilege as the superuser or not
1289         if [ ! -r "$pkglist" ]
1290         then
1291                 if touch "$pkglist" 2>/dev/null
1292                 then
1293                         rm "$pkglist"
1294                 else
1295                         pkglist=${TMPDIR}/pkgsys_eval_ports_glob:pkg.lst
1296                 fi
1297         fi
1298         if [ ! -r "$unflavored_origlist" ]
1299         then
1300                 if touch "$unflavored_origlist" 2>/dev/null
1301                 then
1302                         rm "$unflavored_origlist"
1303                 else
1304                         unflavored_origlist=${TMPDIR}/pkgsys_eval_ports_glob:origin.lst
1305                 fi
1306         fi
1307         # Preparation of customized databases
1308         [ -f "$pkglist" ] \
1309                 || cut -d \| -f 1 "${PORTS_INDEX_DB}" > $pkglist
1310         [ -f "$unflavored_origlist" ] \
1311                 || cut -d \| -f 2 "${PORTS_INDEX_DB}" \
1312                 | sed -E "s/^`str_escape_regexp "${PORTSDIR}"`\///" > $unflavored_origlist
1313         # Evaluation
1314         while [ $# -gt 0 ]
1315         do
1316                 glob=$1
1317                 shift
1318                 expr "x$glob" : '^x-' > /dev/null 2>&1 && continue
1319                 glob_regexp=`str_convert_portsglob_to_regexp_pattern "$glob"`
1320                 if expr "$glob" : '.*/' > /dev/null 2>&1
1321                 then
1322                         if expr "$glob" : '.*@' > /dev/null 2>&1
1323                         then
1324                                 glob_regexp_unflavored=`expr "$glob_regexp" : '\([^@]*\)' || :`$
1325                                 glob_regexp_flavor=^`expr "$glob_regexp" : '[^@]*@\([^@]*\)' || :`
1326                                         
1327                                 env LANG=C grep -E "$glob_regexp_unflavored" "$unflavored_origlist" 2>&1 | while read origin_unflavored
1328                                 do
1329                                         fs_fix_unionfs_image_if_hidden "${PORTSDIR}/$origin_unflavored"
1330                                         make -C "${PORTSDIR}/$origin_unflavored" -V FLAVORS 2> /dev/null | \
1331                                                 tr '[:space:]' '\n' | env LANG=C grep -v '^$' | env LANG=C grep -E "$glob_regexp_flavor" | sed -E "s|^|$origin_unflavored@|"
1332                                 done
1333                                 {
1334                                         pkg_info_all_flavored_origins
1335                                         cut -f 2 "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null
1336                                 } | env LANG=C grep -E "$glob_regexp" 2>&1 || :
1337                         else
1338                                 env LANG=C grep -E "$glob_regexp" "$unflavored_origlist" 2>&1 | while read origin_unflavored
1339                                 do
1340                                         origin_unflavored_rpl=`str_escape_replaceval "$origin_unflavored"`
1341                                         fs_fix_unionfs_image_if_hidden "${PORTSDIR}/$origin_unflavored"
1342                                         make -C "${PORTSDIR}/$origin_unflavored" -V FLAVORS 2> /dev/null | \
1343                                                 tr '[:space:]' '\n' | env LANG=C grep -v '^$' > $tmp_flavors || :
1344                                         if [ `wc -l < $tmp_flavors` -gt 0 ]
1345                                         then
1346                                                 sed -E "s|^|$origin_unflavored_rpl@|" "$tmp_flavors"
1347                                         else
1348                                                 echo "$origin_unflavored"
1349                                         fi
1350                                 done
1351                         fi
1352                         glob_regexp_allflavors=`echo "$glob_regexp" | sed 's/$$/@.*$/'`
1353                         {
1354                                 pkg_info_all_flavored_origins
1355                                 cut -f 2 "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null
1356                         } | env LANG=C grep -E -e "$glob_regexp" -e "$glob_regexp_allflavors" 2>&1 || :
1357                 else
1358                         if expr "$glob" : '[a-z][a-zA-Z0-9_.+-]*[a-zA-Z0-9_.+]$' > /dev/null 2>&1 && \
1359                                 [ `expr "$glob" : '.*-[0-9]' 2>&1` -eq 0 ]
1360                         then
1361                                 glob_regexp2=`expr "$glob_regexp" : '\(.*\)\$$' 2>&1 || :`'-[0-9]'
1362                         else
1363                                 glob_regexp2=$glob_regexp
1364                         fi
1365                         env LANG=C grep -n -E "$glob_regexp2" "$pkglist" 2>&1 | cut -d : -f 1 \
1366                                 | while read index
1367                         do
1368                                 sed -n ${index}p "$unflavored_origlist"
1369                         done | while read origin_unflavored
1370                         do
1371                                 origin_unflavored_rpl=`str_escape_replaceval "$origin_unflavored"`
1372                                 fs_fix_unionfs_image_if_hidden "${PORTSDIR}/$origin_unflavored"
1373                                 make -C "${PORTSDIR}/$origin_unflavored" -V FLAVORS 2> /dev/null | \
1374                                         tr '[:space:]' '\n' | env LANG=C grep -v '^$' > $tmp_flavors || :
1375                                 [ `wc -l < $tmp_flavors` -gt 0 ] || echo > $tmp_flavors
1376                                 sed -E "s/^/$origin_unflavored_rpl /" "$tmp_flavors"
1377                         done | while read origin_unflavored flavor
1378                         do
1379                                 if [ -n "$flavor" ]
1380                                 then
1381                                         if make -C "${PORTSDIR}/$origin_unflavored" package-name FLAVOR=$flavor 2> /dev/null | \
1382                                         env LANG=C grep -qE "$glob_regexp2"
1383                                         then
1384                                                 echo "$origin_unflavored@$flavor"
1385                                         fi
1386                                 else
1387                                         if make -C "${PORTSDIR}/$origin_unflavored" package-name 2> /dev/null | \
1388                                         env LANG=C grep -qE "$glob_regexp2"
1389                                         then
1390                                                 echo "$origin_unflavored"
1391                                         fi
1392                                 fi
1393                         done || :
1394                         glob_regexp2=`echo "$glob_regexp" | sed -E 's/\$*$//' 2>&1 || :`'[[:space:]]'
1395                         env LANG=C grep -E "$glob_regexp2" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
1396                                 | cut -f 2 || :
1397                         for pkgname in `pkg_info_Ex "$glob_regexp"`
1398                         do
1399                                 pkg_info_flavored_origins "$pkgname"
1400                         done
1401                 fi
1402         done | sort -u
1403 }
1404
1405 # ============= Create a back-up package archive =============
1406 pkgsys_create_backup_pkg ()
1407 {
1408         local pkgname dstdir origin backup_pkg_old pkgname_ptn backup_pkg dbpath pkgpath
1409         pkgname=$1
1410         dstdir=$2
1411         rm -rf "${TMPDIR}"/package.tmp
1412         mkdir "${TMPDIR}"/package.tmp
1413         for origin in `pkg_info_flavored_origins "$pkgname"`
1414         do
1415                 if backup_pkg_old=`pkgsys_get_backup_pkg "$origin"` && \
1416                         [ ! -e "${DBDIR}/requires/$origin/installed_timestamp" -o \
1417                                 "$backup_pkg_old" -nt "${DBDIR}/requires/$origin/installed_timestamp" ]
1418                 then
1419                         echo "$backup_pkg_old"
1420                         return
1421                 fi
1422                 if ( cd "${TMPDIR}"/package.tmp && pkg_create_b "$pkgname" > /dev/null )
1423                 then
1424                         pkgname_ptn=`str_escape_regexp "$pkgname"`
1425                         backup_pkg=`ls "${TMPDIR}"/package.tmp | \
1426                                 env LANG=C grep -m 1 -E "^${pkgname_ptn}\.(txz|tbz|tgz|tar|pkg)$"` || :
1427                 fi
1428                 if [ -z "$backup_pkg" ]
1429                 then
1430                         message_echo "WARNING: Failed to create backup package for $pkgname." >&2
1431                         return 1
1432                 fi
1433                 dbpath=${DBDIR}/backup/$origin
1434                 mkdir -p "$dbpath"
1435                 pkg_info_qL "$pkgname" > $dbpath/previously_installed_files
1436                 mkdir -p "$dstdir"
1437                 mv "${TMPDIR}/package.tmp/$backup_pkg" "$dstdir"
1438                 pkgpath=$dstdir/$backup_pkg
1439                 cat "${DBDIR}/backup_pkgarcs.lst" 2> /dev/null | \
1440                         while read origin_cur pkgpath_cur
1441                         do
1442                                 [ "$pkgpath_cur" = "$pkgpath" ] && continue
1443                                 if [ "$origin_cur" = "$origin" ]
1444                                 then
1445                                         rm -f "$pkgpath_cur"
1446                                 else
1447                                         printf '%s\t%s\n' "$origin_cur" "$pkgpath_cur"
1448                                 fi
1449                         done > ${DBDIR}/backup_pkgarcs.lst.tmp
1450                 printf '%s\t%s\n' "$origin" "$pkgpath" >> ${DBDIR}/backup_pkgarcs.lst.tmp
1451                 mv "${DBDIR}/backup_pkgarcs.lst.tmp" "${DBDIR}/backup_pkgarcs.lst"
1452                 echo "$pkgpath"
1453         done
1454 }
1455
1456 # ============= Delete a back-up package archive for a flavored port origin =============
1457 pkgsys_delete_backup_pkg ()
1458 {
1459         local origin origin_regexp
1460         origin=$1
1461         origin_regexp=`str_escape_regexp "$origin"`
1462         env LANG=C grep -E "^${origin_regexp}[[:space:]]" "${DBDIR}/backup_pkgarcs.lst" 2> /dev/null \
1463                 | cut -f 2 | while read pkgpath_cur
1464                 do
1465                         rm -f "$pkgpath_cur"
1466                 done
1467         env LANG=C grep -v -E "^${origin_regexp}[[:space:]]" "${DBDIR}/backup_pkgarcs.lst" \
1468                 2> /dev/null > ${DBDIR}/backup_pkgarcs.lst.tmp || :
1469         mv "${DBDIR}/backup_pkgarcs.lst.tmp" "${DBDIR}/backup_pkgarcs.lst"
1470 }
1471
1472 # ============= Get an existing package archive path for a flavored port origin =============
1473 pkgsys_get_backup_pkg ()
1474 {
1475         local origin tmpnewest origin_regexp
1476         origin=$1
1477         tmpnewest=${TMPDIR}/pkgsys_get_backup_pkg::newest
1478         origin_regexp=`str_escape_regexp "$origin"`
1479         rm -f "$tmpnewest"
1480         env LANG=C grep -E "^${origin_regexp}[[:space:]]" "${DBDIR}/backup_pkgarcs.lst" 2> /dev/null \
1481                 | cut -f 2 | while read pkgpath
1482         do
1483                 pkgpath_newest=`cat "$tmpnewest" 2> /dev/null` || :
1484                 [ -e "$pkgpath" ] || continue
1485                 [ -z "$pkgpath_newest" -o "$pkgpath" -nt "$pkgpath_newest" ] || continue
1486                 echo "$pkgpath" > $tmpnewest
1487         done
1488         cat "$tmpnewest" 2> /dev/null
1489 }
1490
1491 # ============= Get a file list to be restored by the current backup package for a flavored port origin =============
1492 pkgsys_get_restored_files_by_backup_pkg ()
1493 {
1494         local origin
1495         origin=$1
1496         cat "${DBDIR}/backup/$origin/previously_installed_files" 2> /dev/null || :
1497 }
1498
1499 # ============= Check whether any file match restored files by the current backup package for a flavored port origin =============
1500 pkgsys_chk_match_to_restored_files_by_backup_pkg ()
1501 {
1502         local origin filelist dbfile
1503         origin=$1
1504         filelist=$2
1505         dbfile=${DBDIR}/backup/$origin/previously_installed_files
1506         env LANG=C grep -qFx -f "$filelist" "$dbfile" 2> /dev/null
1507 }
1508
1509 # ============= Get a package name from a package archive file name =============
1510 pkgsys_pkgarc_to_pkgname ()
1511 {
1512         local pkgfile_path
1513         pkgfile_path=$1
1514         basename "$pkgfile_path" | sed -E 's/\.(txz|tbz|tgz|tar|pkg)$//'
1515 }
1516
1517 # ============= Get the file name of an existing package archive for a package name =============
1518 pkgsys_pkgname_to_pkgarc ()
1519 {
1520         local pkgdir pkgname pkgname_ptn pkgnode
1521         pkgdir=$1
1522         pkgname=$2
1523         [ -n "$pkgname" ] || return 1
1524         [ -d "$pkgdir" ] || return 1
1525         if [ "x$PKGSYS_USE_PKGNG" = xyes ]
1526         then
1527                 pkgname_ptn=`str_escape_regexp "$pkgname"`
1528                 pkgnode=`ls "$pkgdir" 2> /dev/null | env LANG=C grep -m 1 -E "^${pkgname_ptn}\.(txz|tbz|tgz|tar|pkg)$"` || :
1529         elif [ -e "$pkgdir/$pkgname.tbz" ]
1530         then
1531                 pkgnode=$pkgname.tbz
1532         fi
1533         [ -n "$pkgnode" ] || return 1
1534         echo "$pkgdir/$pkgnode"
1535 }
1536
1537 # ============= Get flavored port origins matching a glob pattern even if nonexistent =============
1538 pkgsys_eval_ports_glob_even_if_nonexistent ()
1539 {
1540         local glob_pattern
1541         glob_pattern=$1
1542         {
1543                 pkgsys_eval_ports_glob "$glob_pattern" 2> /dev/null || :
1544                 echo "$glob_pattern" | env LANG=C grep -E '^[a-z]+/([a-zA-Z0-9_.+-]+|[a-zA-Z0-9_.+-]+@[a-zA-Z0-9_.+-]+)$' || :
1545         } | env LANG=C grep -v -e '^$' | sort -u
1546 }
1547
1548 # ============= Evaluate glob patterns and add/remove non-existing/existing ones of them to/from a file =============
1549 pkgsys_register_evaluated_globs ()
1550 {
1551         local mode listpath dirpath tmp_evaluated
1552         mode=$1
1553         listpath=$2
1554         shift 2
1555         dirpath=`dirname "$listpath"`
1556         tmp_evaluated=${TMPDIR}/pkgsys_register_evaluated_globs:pkgsys_eval_ports_glob
1557         echo "$@" | sed -E 's/[ :]+/\
1558 /g' | env LANG=C grep -v '^$' | sort -u | while read -r glob
1559         do
1560                 pkgsys_eval_ports_glob "$glob" > $tmp_evaluated
1561                 [ `wc -l < $tmp_evaluated` -ge 1 ] || \
1562                 {
1563                         message_echo "WARNING: No matching ports/package glob [$glob]." >&2
1564                         continue
1565                 }
1566                 cat "$tmp_evaluated"
1567         done | while read origin
1568         do
1569                 mkdir -p "$dirpath"
1570                 case $mode in
1571                 remove )        fileedit_rm_a_line "$origin" "$listpath"
1572                         ;;
1573                 add )   fileedit_add_a_line_if_new "$origin" "$listpath"
1574                         ;;
1575                 esac
1576         done
1577 }
1578
1579 # ============= Evaluate glob patterns for installed packages =============
1580 pkgsys_eval_installed_pkgs_globs ()
1581 {
1582         local tmp_evaluated
1583         tmp_evaluated=${TMPDIR}/pkgsys_eval_installed_pkgs_globs:origins
1584         rm -f "$tmp_evaluated"
1585         pkgsys_register_evaluated_globs add "$tmp_evaluated" "$@"
1586         [ -e "$tmp_evaluated" ] || return 0
1587         while read origin
1588         do
1589                 pkgsys_exists_or_existed_from_orig "$origin" || echo "$origin"
1590         done < $tmp_evaluated
1591 }
1592
1593 # ============= Get glob patterns of conflicting packages of a port =============
1594 pkgsys_get_conflicting_pkgs_patterns ()
1595 {
1596         local mode origin conflicts conflicts_makevar conflicts_config
1597         mode=$1
1598         origin=$2
1599         conflicts=`database_query_get_makevar_val "$origin" CONFLICTS`
1600         case $mode in
1601         build )
1602                 conflicts_makevar=`database_query_get_makevar_val "$origin" CONFLICTS_BUILD`
1603                 conflicts_config=`database_query_get_config_val "$origin" BUILDCONFLICT`
1604                 ;;
1605         install )
1606                 conflicts_makevar=`database_query_get_makevar_val "$origin" CONFLICTS_INSTALL`
1607                 conflicts_config=`database_query_get_config_val "$origin" INSTCONFLICT`
1608                 ;;
1609         *)
1610                 conflicts_makevar=
1611                 conflicts_config=
1612                 ;;
1613         esac
1614         echo "$conflicts $conflicts_makevar $conflicts_config" | tr ' ' '\n' | env LANG=C grep -v '^$' | sort -u
1615 }       
1616
1617 # ============= Get conflicting installed packages of a port =============
1618 pkgsys_get_conflicting_installed_pkgs ()
1619 {
1620         local mode origin tmp_conflicts
1621         mode=$1
1622         origin=$2
1623         tmp_conflicts=${TMPDIR}/pkgsys_get_conflicting_installed_pkgs::conflicts
1624         pkgsys_get_conflicting_pkgs_patterns "$mode" "$origin" | while read pkg_pattern
1625         do
1626                 pkgsys_get_installed_pkg_from_glob "$pkg_pattern" || :
1627         done > $tmp_conflicts
1628         cat "$tmp_conflicts"
1629         [ `wc -l < $tmp_conflicts` -gt 0 ]
1630 }       
1631
1632 # ============= Check whether a package conflicts with a port =============
1633 pkgsys_chk_conflict_by_a_pkg ()
1634 {
1635         local mode origin pkg tmp_conflicts_ptn
1636         mode=$1
1637         origin=$2
1638         pkg=$3
1639         tmp_conflicts_ptn=${TMPDIR}/pkgsys_chk_conflict_by_a_pkg::conflicts_ptn
1640         pkgsys_get_conflicting_pkgs_patterns "$mode" "$origin" \
1641                 | str_convert_glob_to_regexp_pattern > $tmp_conflicts_ptn
1642         echo "$pkg" | env LANG=C grep -q -E -f "$tmp_conflicts_ptn"
1643 }       
1644
1645 # ============= Check whether installed files are lost or broken for a package =============
1646 pkgsys_sanitychk_pkgcontents ()
1647 {
1648         local pkg var_is_reinstall_encouraged _is_reinstall_encouraged tmp_sanity nlines iline src filename icol filename_esc pkg_owner origin
1649         pkg=$1
1650         var_is_reinstall_encouraged=$2
1651         tmp_sanity=${TMPDIR}/pkgsys_sanitychk_pkgcontents:sanity
1652         pkg_check_sanity "$pkg" > $tmp_sanity || :
1653         eval "$var_is_reinstall_encouraged=no"
1654         [ `wc -l < $tmp_sanity` -eq 0 ] && return
1655         nlines=`wc -l < $tmp_sanity`
1656         iline=1
1657         _is_reinstall_encouraged=no
1658         while [ $iline -le $nlines ]
1659         do
1660                 filename=`sed -n ${iline}p "$tmp_sanity"`
1661                 iline=$(($iline+1))
1662                 if [ ! -e "$filename" ]
1663                 then
1664                         _is_reinstall_encouraged=yes
1665                         break
1666                 fi
1667                 if expr "$filename" : '.*/include/.*' > /dev/null
1668                 then
1669                         _is_reinstall_encouraged=yes
1670                         break
1671                 fi
1672                 filename_esc=`str_escape_regexp "$filename"`
1673                 if file "$filename" | sed -E "s/^$filename_esc:[[:space:]]//" | env LANG=C grep -q '^ELF '
1674                 then
1675                         _is_reinstall_encouraged=yes
1676                         break
1677                 fi
1678                 pkg_owner=`pkg_which "$filename"`
1679                 if [ "$pkg" != "$pkg_owner" ]
1680                 then
1681                         _is_reinstall_encouraged=yes
1682                         break
1683                 fi
1684         done
1685         eval "$var_is_reinstall_encouraged=\$_is_reinstall_encouraged"
1686         for origin in `pkg_info_flavored_origins "$pkg"`
1687         do
1688                 if [ $opt_batch_mode = no ]
1689                 then
1690                         message_echo "[$pkg ($origin)]"
1691                         sed 's/^/  /' "$tmp_sanity"
1692                         message_echo
1693                 else
1694                         pkg_replace=`str_escape_replaceval "$pkg"`
1695                         origin_replace=`str_escape_replaceval "$origin"`
1696                         sed "s/^/$pkg_replace\\\\$origin_replace\\\\$_is_reinstall_encouraged\\\\/" "$tmp_sanity" | tr '\\' '\t'
1697                 fi
1698         done
1699         return 1
1700 }
1701
1702 # ============= Check whether the port options database is once saved =============
1703 pkgsys_exists_saved_port_options_timestamps ()
1704 {
1705         [ -d "${DBDIR}/ls_dbdir" ]
1706 }
1707
1708 # ============= Get the current all timestamp information of port options =============
1709 pkgsys_get_current_port_options_timestamp ()
1710 {
1711         local portdb_needle_regexp
1712         portdb_needle_regexp=`str_escape_regexp "$1"`
1713         {
1714                 ls -lD %Y%m%d:%H%M%S "${PORT_DBDIR}" | if [ -n "$portdb_needle_regexp" ]
1715                 then
1716                         env LANG=C grep -E "[[:space:]]$portdb_needle_regexp$" || :
1717                 else
1718                         cat
1719                 fi
1720         } 2> /dev/null | cut -w -f 6,7 | while read datetime portdb
1721         do
1722                 [ -d "${PORT_DBDIR}/$portdb" ] || continue
1723                 if [ -e "${PORT_DBDIR}/$portdb/options" ]
1724                 then
1725                         datetime=`ls -lD %Y%m%d:%H%M%S "${PORT_DBDIR}/$portdb/options" 2> /dev/null | cut -w -f 6`
1726                 fi
1727                 printf '%s\t%s\n' "$portdb" "$datetime"
1728         done
1729 }
1730
1731 # ============= Get the saved all timestamp information of port options =============
1732 pkgsys_get_saved_port_options_timestamps_all ()
1733 {
1734         mkdir -p "${DBDIR}/ls_dbdir"
1735         cat "${DBDIR}/ls_dbdir/"*.log 2> /dev/null || :
1736 }
1737
1738 # ============= Convert a list of port origins to port options timestamp log names =============
1739 pkgsys_conv_portorigin_to_port_option_timestamp_logname ()
1740 {
1741         sed 's|/|_|'
1742 }
1743
1744 # ============= Get the file name of the port options database of a port =============
1745 pkgsys_get_port_option_database ()
1746 {
1747         local origin
1748         origin=$1
1749         if pkgsys_is_dialog4ports_used
1750         then
1751                 echo "$origin" | sed 's|/|_|;s/@.*//'
1752         else
1753                 database_build_make "$origin" -V UNIQUENAME
1754         fi
1755 }
1756
1757 # ============= Save the timestamp information of port options of a port =============
1758 pkgsys_save_port_option_timestamp ()
1759 {
1760         local origin portoptlog portoptdb
1761         origin=$1
1762         portoptlog=`echo "$origin" | pkgsys_conv_portorigin_to_port_option_timestamp_logname`
1763         portoptdb=`pkgsys_get_port_option_database "$origin"`
1764         mkdir -p "${DBDIR}/ls_dbdir"
1765         pkgsys_get_current_port_options_timestamp "$portoptdb" > ${DBDIR}/ls_dbdir/$portoptlog.log 2> /dev/null || :
1766 }
1767
1768 # ============= Get changed port options from the saved point =============
1769 pkgsys_get_changed_port_options ()
1770 {
1771         local saved_log current_log tmp_log
1772         saved_log=$1
1773         current_log=$2
1774         tmp_log=${TMPDIR}/pkgsys_get_changed_port_options.log
1775         {
1776                 env LANG=C grep -vxF -f "$current_log" "$saved_log" || :
1777                 env LANG=C grep -vxF -f "$saved_log" "$current_log" || :
1778         } | cut -w -f 1 | env LANG=C grep -v '^$' | sort -u > $tmp_log
1779         if pkgsys_is_dialog4ports_used
1780         then
1781                 env LANG=C grep '_' "$tmp_log" || :
1782         else
1783                 cat "$tmp_log"
1784         fi
1785 }
1786
1787 # ============= Convert a list of port options database names to port globs =============
1788 pkgsys_conv_portoptiondbs_to_globs ()
1789 {
1790         if pkgsys_is_dialog4ports_used
1791         then
1792                 sed 's|_|/|'
1793         else
1794                 cat
1795         fi
1796 }
1797
1798 # ============= Register nonexistent port options databases =============
1799 pkgsys_register_list_nonexistent_portopriondb ()
1800 {
1801         local dbpath
1802         dbpath=${DBDIR}/ls_dbdir/%NONEXISTENT%.log
1803         mkdir -p "${DBDIR}/ls_dbdir"
1804         cat > $dbpath.new
1805         touch  "$dbpath"
1806         sort -u "$dbpath.new" "$dbpath" > $dbpath.tmp
1807         mv "$dbpath.tmp" "$dbpath"
1808 }
1809
1810 # ============= Order a list of installed packages by storage space occupied by the installed files =============
1811 pkgsys_order_pkgs_by_size ()
1812 {
1813         while read pkg
1814         do
1815                 size=`pkg_info_qs "$pkg" || :`
1816                 [ -n "$size" ] && echo "$size"$'\t'"$pkg"
1817         done | sort -g | cut -f 2
1818 }