Deleted Added
full compact
index.subr (250410) index.subr (250538)
1if [ ! "$_PACKAGES_INDEX_SUBR" ]; then _PACKAGES_INDEX_SUBR=1
2#
3# Copyright (c) 2013 Devin Teske
4# All Rights Reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
1if [ ! "$_PACKAGES_INDEX_SUBR" ]; then _PACKAGES_INDEX_SUBR=1
2#
3# Copyright (c) 2013 Devin Teske
4# All Rights Reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/usr.sbin/bsdconfig/share/packages/index.subr 250410 2013-05-09 16:09:39Z dteske $
27# $FreeBSD: head/usr.sbin/bsdconfig/share/packages/index.subr 250538 2013-05-12 00:46:18Z dteske $
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." packages/index.subr
34f_include $BSDCFG_SHARE/device.subr
35f_include $BSDCFG_SHARE/media/common.subr
36f_include $BSDCFG_SHARE/strings.subr
37
38BSDCFG_LIBE="/usr/libexec/bsdconfig"
39f_include_lang $BSDCFG_LIBE/include/messages.subr
40
41############################################################ GLOBALS
42
43PACKAGE_INDEX=
44_INDEX_INITTED=
45
46############################################################ FUNCTIONS
47
48# f_index_initialize $path [$var_to_set]
49#
50# Read and initialize the global index. $path is to be relative to the chosen
51# media (not necessarily the filesystem; e.g. FTP) -- this is usually going to
52# be `packages/INDEX'. Returns success unless media cannot be initialized for
53# any reason (e.g. user cancels media selection dialog) or an error occurs. The
54# index is sorted before being loaded into $var_to_set.
55#
56# NOTE: The index is processed with f_index_read() [below] after being loaded.
57#
58f_index_initialize()
59{
60 local __path="$1" __var_to_set="${2:-PACKAGE_INDEX}"
61
62 [ "$_INDEX_INITTED" ] && return $SUCCESS
63 [ "$__path" ] || return $FAILURE
64
65 # Got any media?
66 f_media_verify || return $FAILURE
67
68 # Does it move when you kick it?
69 f_device_init media || return $FAILURE
70
71 f_show_info "$msg_attempting_to_fetch_file_from_selected_media" \
72 "$__path"
73 eval "$__var_to_set"='$( f_device_get media "$__path" | sort )'
74 if [ $? -ne $SUCCESS ]; then
75 f_show_msg "$msg_unable_to_get_file_from_selected_media" \
76 "$__path"
77 f_device_shutdown media
78 return $FAILURE
79 fi
80
81 f_show_info "$msg_located_index_now_reading_package_data_from_it"
82 if ! f_index_read "$__var_to_set"; then
83 f_show_msg "$msg_io_or_format_error_on_index_file" "$__path"
84 return $FAILURE
85 fi
86
87 _INDEX_INITTED=1
88 return $SUCCESS
89}
90
91# f_index_read [$var_to_get]
92#
93# Process the INDEX file (contents contained in $var_to_get) and...
94#
95# 1. create a list ($CATEGORY_MENU_LIST) of categories with package counts
96# 2. For convenience, create $_npkgs holding the total number of all packages
97# 3. extract associative categories for each package into $_categories_$varpkg
98# 4. extract runtime dependencies for each package into $_rundeps_$varpkg
99# 5. extract a [sorted] list of categories into $PACKAGE_CATEGORIES
100# 6. create $_npkgs_$varcat holding the total number of packages in category
101#
102# NOTE: $varpkg is the product of f_str2varname $package varpkg
103# NOTE: $package is the name as it appears in the INDEX (no archive suffix)
104# NOTE: We only show categories for which there are at least one package.
105# NOTE: $varcat is the product of f_str2varname $category varcat
106#
107f_index_read()
108{
109 local var_to_get="${1:-PACKAGE_INDEX}"
110
111 # Export variables required by awk(1) below
112 export msg_no_description_provided
113 export msg_all msg_all_desc
114 export VALID_VARNAME_CHARS
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." packages/index.subr
34f_include $BSDCFG_SHARE/device.subr
35f_include $BSDCFG_SHARE/media/common.subr
36f_include $BSDCFG_SHARE/strings.subr
37
38BSDCFG_LIBE="/usr/libexec/bsdconfig"
39f_include_lang $BSDCFG_LIBE/include/messages.subr
40
41############################################################ GLOBALS
42
43PACKAGE_INDEX=
44_INDEX_INITTED=
45
46############################################################ FUNCTIONS
47
48# f_index_initialize $path [$var_to_set]
49#
50# Read and initialize the global index. $path is to be relative to the chosen
51# media (not necessarily the filesystem; e.g. FTP) -- this is usually going to
52# be `packages/INDEX'. Returns success unless media cannot be initialized for
53# any reason (e.g. user cancels media selection dialog) or an error occurs. The
54# index is sorted before being loaded into $var_to_set.
55#
56# NOTE: The index is processed with f_index_read() [below] after being loaded.
57#
58f_index_initialize()
59{
60 local __path="$1" __var_to_set="${2:-PACKAGE_INDEX}"
61
62 [ "$_INDEX_INITTED" ] && return $SUCCESS
63 [ "$__path" ] || return $FAILURE
64
65 # Got any media?
66 f_media_verify || return $FAILURE
67
68 # Does it move when you kick it?
69 f_device_init media || return $FAILURE
70
71 f_show_info "$msg_attempting_to_fetch_file_from_selected_media" \
72 "$__path"
73 eval "$__var_to_set"='$( f_device_get media "$__path" | sort )'
74 if [ $? -ne $SUCCESS ]; then
75 f_show_msg "$msg_unable_to_get_file_from_selected_media" \
76 "$__path"
77 f_device_shutdown media
78 return $FAILURE
79 fi
80
81 f_show_info "$msg_located_index_now_reading_package_data_from_it"
82 if ! f_index_read "$__var_to_set"; then
83 f_show_msg "$msg_io_or_format_error_on_index_file" "$__path"
84 return $FAILURE
85 fi
86
87 _INDEX_INITTED=1
88 return $SUCCESS
89}
90
91# f_index_read [$var_to_get]
92#
93# Process the INDEX file (contents contained in $var_to_get) and...
94#
95# 1. create a list ($CATEGORY_MENU_LIST) of categories with package counts
96# 2. For convenience, create $_npkgs holding the total number of all packages
97# 3. extract associative categories for each package into $_categories_$varpkg
98# 4. extract runtime dependencies for each package into $_rundeps_$varpkg
99# 5. extract a [sorted] list of categories into $PACKAGE_CATEGORIES
100# 6. create $_npkgs_$varcat holding the total number of packages in category
101#
102# NOTE: $varpkg is the product of f_str2varname $package varpkg
103# NOTE: $package is the name as it appears in the INDEX (no archive suffix)
104# NOTE: We only show categories for which there are at least one package.
105# NOTE: $varcat is the product of f_str2varname $category varcat
106#
107f_index_read()
108{
109 local var_to_get="${1:-PACKAGE_INDEX}"
110
111 # Export variables required by awk(1) below
112 export msg_no_description_provided
113 export msg_all msg_all_desc
114 export VALID_VARNAME_CHARS
115 export msg_packages
115
116 eval "$( debug= f_getvar "$var_to_get" | awk -F'|' '
117 function asorti(src, dest)
118 {
119 # Copy src indices to dest and calculate array length
120 nitems = 0; for (i in src) dest[++nitems] = i
121
122 # Sort the array of indices (dest) using insertion sort method
123 for (i = 1; i <= nitems; k = i++)
124 {
125 idx = dest[i]
126 while ((k > 0) && (dest[k] > idx))
127 {
128 dest[k+1] = dest[k]
129 k--
130 }
131 dest[k+1] = idx
132 }
133
134 return nitems
135 }
136 function print_category(category, npkgs, desc)
137 {
138 cat = category
139 # Accent the category if the first page has been
140 # cached (also acting as a visitation indicator)
141 if ( ENVIRON["_index_page_" varcat "_1"] )
142 cat = cat "*"
116
117 eval "$( debug= f_getvar "$var_to_get" | awk -F'|' '
118 function asorti(src, dest)
119 {
120 # Copy src indices to dest and calculate array length
121 nitems = 0; for (i in src) dest[++nitems] = i
122
123 # Sort the array of indices (dest) using insertion sort method
124 for (i = 1; i <= nitems; k = i++)
125 {
126 idx = dest[i]
127 while ((k > 0) && (dest[k] > idx))
128 {
129 dest[k+1] = dest[k]
130 k--
131 }
132 dest[k+1] = idx
133 }
134
135 return nitems
136 }
137 function print_category(category, npkgs, desc)
138 {
139 cat = category
140 # Accent the category if the first page has been
141 # cached (also acting as a visitation indicator)
142 if ( ENVIRON["_index_page_" varcat "_1"] )
143 cat = cat "*"
143 printf "'\''%s'\'' '\''%s packages'\'' '\''%s'\''\n",
144 printf "'\''%s'\'' '\''%s " packages "'\'' '\''%s'\''\n",
144 cat, npkgs, desc
145 }
146 BEGIN {
147 valid_chars = ENVIRON["VALID_VARNAME_CHARS"]
148 default_desc = ENVIRON["msg_no_description_provided"]
145 cat, npkgs, desc
146 }
147 BEGIN {
148 valid_chars = ENVIRON["VALID_VARNAME_CHARS"]
149 default_desc = ENVIRON["msg_no_description_provided"]
150 packages = ENVIRON["msg_packages"]
149 tpkgs = 0
150 prefix = ""
151 }
152 {
153 tpkgs++
154 varpkg = $1
155 gsub("[^" valid_chars "]", "_", varpkg)
156 print "_categories_" varpkg "=\"" $7 "\""
157 split($7, pkg_categories, /[[:space:]]+/)
158 for (pkg_category in pkg_categories)
159 categories[pkg_categories[pkg_category]]++
160 print "_rundeps_" varpkg "=\"" $9 "\""
161 }
162 END {
163 print "_npkgs=" tpkgs # For convenience, total package count
164
165 n = asorti(categories, categories_sorted)
166
167 # Produce package counts for each category
168 for (i = 1; i <= n; i++)
169 {
170 cat = varcat = categories_sorted[i]
171 npkgs = categories[cat]
172 gsub("[^" valid_chars "]", "_", varcat)
173 print "_npkgs_" varcat "=\"" npkgs "\""
174 }
175
176 # Create menu list and generate list of categories at same time
177 print "CATEGORY_MENU_LIST=\""
178 print_category(ENVIRON["msg_all"], tpkgs,
179 ENVIRON["msg_all_desc"])
180 category_list = ""
181 for (i = 1; i <= n; i++)
182 {
183 cat = varcat = categories_sorted[i]
184 npkgs = categories[cat]
185 cur_prefix = tolower(substr(cat, 1, 1))
186 if ( prefix != cur_prefix )
187 prefix = cur_prefix
188 else
189 cat = " " cat
190 gsub("[^" valid_chars "]", "_", varcat)
191 desc = ENVIRON["_category_" varcat]
192 if ( ! desc ) desc = default_desc
193 print_category(cat, npkgs, desc)
194 category_list = category_list " " cat
195 }
196 print "\""
197
198 # Produce the list of categories (calculated in above block)
199 sub(/^ /, "", category_list)
200 print "PACKAGE_CATEGORIES=\"" category_list "\""
201
202 }' )" # End-Quote
203}
204
205# f_index_extract_pages $var_to_get $var_basename $pagesize [$category]
206#
207# Extracts the package INDEX into a series of sequential variables
208# corresponding to "pages" containing up to $pagesize packages. The package
209# INDEX data must be contained in the variable $var_to_get. The extracted pages
210# are stored in variables ${var_basename}_# -- where "#" is a the page number.
211# If $category is set, only packages for that category are extracted.
212# Otherwise, if $category is "All", missing, or NULL, all packages are
213# extracted and no filtering is done.
214#
215f_index_extract_pages()
216{
217 local var_to_get="$1" var_basename="$2" pagesize="$3"
218 local category="$4" # Optional
219
220 eval "$(
221 debug= f_getvar "$var_to_get" | awk -F'|' \
222 -v cat="$category" \
223 -v pagesize="$pagesize" \
151 tpkgs = 0
152 prefix = ""
153 }
154 {
155 tpkgs++
156 varpkg = $1
157 gsub("[^" valid_chars "]", "_", varpkg)
158 print "_categories_" varpkg "=\"" $7 "\""
159 split($7, pkg_categories, /[[:space:]]+/)
160 for (pkg_category in pkg_categories)
161 categories[pkg_categories[pkg_category]]++
162 print "_rundeps_" varpkg "=\"" $9 "\""
163 }
164 END {
165 print "_npkgs=" tpkgs # For convenience, total package count
166
167 n = asorti(categories, categories_sorted)
168
169 # Produce package counts for each category
170 for (i = 1; i <= n; i++)
171 {
172 cat = varcat = categories_sorted[i]
173 npkgs = categories[cat]
174 gsub("[^" valid_chars "]", "_", varcat)
175 print "_npkgs_" varcat "=\"" npkgs "\""
176 }
177
178 # Create menu list and generate list of categories at same time
179 print "CATEGORY_MENU_LIST=\""
180 print_category(ENVIRON["msg_all"], tpkgs,
181 ENVIRON["msg_all_desc"])
182 category_list = ""
183 for (i = 1; i <= n; i++)
184 {
185 cat = varcat = categories_sorted[i]
186 npkgs = categories[cat]
187 cur_prefix = tolower(substr(cat, 1, 1))
188 if ( prefix != cur_prefix )
189 prefix = cur_prefix
190 else
191 cat = " " cat
192 gsub("[^" valid_chars "]", "_", varcat)
193 desc = ENVIRON["_category_" varcat]
194 if ( ! desc ) desc = default_desc
195 print_category(cat, npkgs, desc)
196 category_list = category_list " " cat
197 }
198 print "\""
199
200 # Produce the list of categories (calculated in above block)
201 sub(/^ /, "", category_list)
202 print "PACKAGE_CATEGORIES=\"" category_list "\""
203
204 }' )" # End-Quote
205}
206
207# f_index_extract_pages $var_to_get $var_basename $pagesize [$category]
208#
209# Extracts the package INDEX into a series of sequential variables
210# corresponding to "pages" containing up to $pagesize packages. The package
211# INDEX data must be contained in the variable $var_to_get. The extracted pages
212# are stored in variables ${var_basename}_# -- where "#" is a the page number.
213# If $category is set, only packages for that category are extracted.
214# Otherwise, if $category is "All", missing, or NULL, all packages are
215# extracted and no filtering is done.
216#
217f_index_extract_pages()
218{
219 local var_to_get="$1" var_basename="$2" pagesize="$3"
220 local category="$4" # Optional
221
222 eval "$(
223 debug= f_getvar "$var_to_get" | awk -F'|' \
224 -v cat="$category" \
225 -v pagesize="$pagesize" \
224 -v var_basename="$var_basename" '
226 -v var_basename="$var_basename" \
227 -v i18n_all="$msg_all" '
225 BEGIN { n = page = 0 }
226 /'\''/{ gsub(/'\''/, "'\''\\'\'\''") }
227 {
228 BEGIN { n = page = 0 }
229 /'\''/{ gsub(/'\''/, "'\''\\'\'\''") }
230 {
228 if ( cat !~ /(^$|^All$)/ && $7 !~ \
231 if ( cat !~ "(^$|^" i18n_all "$)" && $7 !~ \
229 "(^|[[:space:]])" cat "([[:space:]]|$)" ) next
230 starting_new_page = (n++ == (pagesize * page))
231 if ( starting_new_page )
232 printf "%s%s", ( n > 1 ? "'\''\n" : "" ),
233 var_basename "_" ++page "='\''"
234 printf "%s%s", ( starting_new_page ? "" : "\n" ), $0
235 }
236 END { if ( n > 0 ) print "'\''" }'
237 )"
238}
239
240############################################################ MAIN
241
242f_dprintf "%s: Successfully loaded." packages/index.subr
243
244fi # ! $_PACKAGES_INDEX_SUBR
232 "(^|[[:space:]])" cat "([[:space:]]|$)" ) next
233 starting_new_page = (n++ == (pagesize * page))
234 if ( starting_new_page )
235 printf "%s%s", ( n > 1 ? "'\''\n" : "" ),
236 var_basename "_" ++page "='\''"
237 printf "%s%s", ( starting_new_page ? "" : "\n" ), $0
238 }
239 END { if ( n > 0 ) print "'\''" }'
240 )"
241}
242
243############################################################ MAIN
244
245f_dprintf "%s: Successfully loaded." packages/index.subr
246
247fi # ! $_PACKAGES_INDEX_SUBR