OSDN Git Service

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