OSDN Git Service

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