Add a symbolic link to the lfs-uefi-20170207.txt hint
[linux_from_scratch_hints.git] / ATTACHMENTS / pkg_unionfs / manager
blob205eccf281a4e0ad05215f036a8b03f00b9581b3
1 #!/bin/sh
3 # The "pkg_dir" variable points to the directory containing the packages.
4 # This path must be absolute.
5 pkg_dir="/pkgs"
7 # The "target_dir" variable points to the directory where the target
8 # directories are located. This path must be absolute.
9 target_dir="/"
12 command="${1}"
13 pkg_name="${2}"
14 pkg_version="${3}"
16 # Unfortunately, bash does not support map or dictionary data structures.
17 # The goal of map_dir is to simulate this data structure. Given a source
18 # directory, it will map it to a target directory.
20 # Input: ${1} - the path of the source directory; the path cannot be absolute
21 # but must be relative to the package's directory.
22 # Result: the target directory if the source directory has a target, otherwise
23 # an empty string.
24 function map_dir ()
26 dir_entries ()
28 # target-point source-dir
29 echo "${target_dir}/bin bin"
30 echo "${target_dir}/bin jre/bin"
31 echo "${target_dir}/bin usr/bin"
32 echo "${target_dir}/bin usr/local/bin"
34 echo "${target_dir}/sbin sbin"
35 echo "${target_dir}/sbin usr/sbin"
36 echo "${target_dir}/sbin usr/local/sbin"
38 echo "${target_dir}/lib lib"
39 echo "${target_dir}/lib jre/lib"
40 echo "${target_dir}/lib usr/lib"
41 echo "${target_dir}/lib usr/local/lib"
42 echo "${target_dir}/lib lib64"
43 echo "${target_dir}/lib usr/lib64"
44 echo "${target_dir}/lib usr/local/lib64"
46 echo "${target_dir}/usr/include include"
47 echo "${target_dir}/usr/include usr/include"
48 echo "${target_dir}/usr/include usr/local/include"
50 echo "${target_dir}/usr/share share"
51 echo "${target_dir}/usr/share usr/share"
52 echo "${target_dir}/usr/share usr/local/share"
54 echo "${target_dir}/usr/man man"
55 echo "${target_dir}/usr/man usr/man"
56 echo "${target_dir}/usr/man usr/share/man"
57 echo "${target_dir}/usr/man usr/local/share/man"
59 echo "${target_dir}/etc etc"
60 echo "${target_dir}/var var"
63 ( dir_entries ) | while read mount_point source_dir; do
64 if [ "${source_dir}" == "${1}" ]; then
65 echo "${mount_point}"
66 exit 0
68 done
69 echo
72 function print_usage()
74 echo "Usage: ${0} <command> <parameters>"
75 echo "Commands:"
76 echo " list"
77 echo " list all packages"
78 echo " list package-name"
79 echo " list versions of specified package"
80 echo " load package-name [package-version]"
81 echo " load a package"
82 echo " unload package-name"
83 echo " unload a package"
84 echo " test package-name [package-version]"
85 echo " dump mount points of a package"
88 # Find all the sub-directories in a package directory. The prefix of ./ is
89 # stripped off from all sub-directory paths returned by find.
90 # Input: ${1} - the package name
91 # ${2} - the package version
92 # Result: all of the sub-directories
93 function find_dirs()
95 dir="${pkg_dir}/${1}/${2}/"
96 cd ${dir}
97 find . -maxdepth 3 -mindepth 1 -type d | sed 's/\.\///'
100 # Checks the variable ${pkg_name} to see if the package name exists.
101 # It prints messages to standard error if the package is not found.
102 # Input: ${pkg_name} - the name of the package.
103 # Result: 0 if the package directory is found, 1 if not.
104 function check_pkg_name()
106 if [ "${pkg_name}" == "" ]; then
107 echo "No package was specified" >&2
108 exit 1
109 elif [ ! -d "${pkg_dir}/${pkg_name}" ]; then
110 echo "Package \`${pkg_name}' does not exist" >&2
111 potential_pkg_names=""
112 for potential_pkg_name in `${0} list`; do
113 matches=`echo ${potential_pkg_name} | grep ${pkg_name}`
114 if [ ! "${matches}" == "" ]; then
115 potential_pkg_names="${matches} ${potential_pkg_names}"
117 done
118 if [ ! "${potential_pkg_names}" == "" ]; then
119 echo "Possible packages are: ${potential_pkg_names}" >&2
121 exit 1
122 else
123 exit 0
127 # Checks the package version in order to determine if it is valid.
128 # If ${pkg_version} is empty, the default package version is used instead.
129 # Input: ${pkg_version} - the package version to check
130 # Result: the package version to use. This can be different from the supplied
131 # ${pkg_version} if it is an empty string.
132 function check_pkg_version()
134 if [ "${pkg_version}" == "" ]; then
135 cd "${pkg_dir}/${pkg_name}"
136 for version in `ls -r`; do pkg_version=${version}; done
137 if [ "${pkg_version}" == "" ]; then
138 echo "No package versions are available for package \`${pkg_name}'" >&2
139 exit 1
140 else
141 echo "No package version was specified for \`${pkg_name}'; defaulting to \`${pkg_version}'" >&2
143 else
144 if [ ! -d "${pkg_dir}/${pkg_name}/${pkg_version}" ]; then
145 echo "Version \`${pkg_version}' does not exist for package \`${pkg_name}'" >&2
146 echo -n "Available versions are: " >&2
147 ${0} list ${pkg_name} >&2
148 exit 1
151 echo "${pkg_version}"
152 exit 0
155 # Performs a supplied function on each directory returned by map_dir.
156 # On each directory returned, the function will be called with the parameters:
157 # ${1} set to the absolute path to the source directory, and ${2} set to
158 # the path to the target directory.
159 # Input: ${1} - the function name to execute
160 # ${2} - the package name
161 # ${3} - the package version
162 # Result: 0 if the supplied function succeeded for each directory, 1 otherwise.
163 function for_each_mapped_dir ()
165 for dir in `( find_dirs ${2} ${3} )`; do
166 dest=`( map_dir ${dir} )`
167 if [ "${dest}" != "" ]; then
168 ( "${1}" "${pkg_dir}/${2}/${3}/${dir}" "${dest}" )
169 if [ ! $? -eq 0 ]; then exit 1; fi
171 done
174 case "${command}" in
175 list)
176 if [ "${pkg_name}" == "" ]; then
177 cd ${pkg_dir}
178 for pkg_name in *; do
179 if [ -d ${pkg_dir}/${pkg_name} ]; then
180 echo -n "${pkg_name} "
181 cd ${pkg_name}
182 for version in *; do
183 echo -n "${version} "
184 done
185 echo
186 cd ..
188 done
189 echo
190 else
191 ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
192 cd ${pkg_dir}/${pkg_name}
193 for version in *; do
194 echo -n "${version} "
195 done
196 echo
199 load)
200 ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
201 pkg_version=`( check_pkg_version )`; if [ ! $? -eq 0 ]; then exit 1; fi
202 do_load ()
204 mount -n -t unionfs -o "remount,add=:${1}=rw" none "${2}"
206 ( for_each_mapped_dir "do_load" ${pkg_name} ${pkg_version} )
207 exit ${?}
209 unload)
210 ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
211 pkg_version=`( check_pkg_version )`; if [ ! $? -eq 0 ]; then exit 1; fi
212 do_unload ()
214 mount -n -t unionfs -o "remount,del=${1}" none "${2}"
216 ( for_each_mapped_dir "do_unload" ${pkg_name} ${pkg_version} )
217 exit ${?}
219 test)
220 ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
221 pkg_version=`( check_pkg_version )`; if [ ! $? -eq 0 ]; then exit 1; fi
222 do_test ()
224 echo ${2} \<== ${1}
226 ( for_each_mapped_dir "do_test" ${pkg_name} ${pkg_version} )
227 exit $?
230 if [ ! "${command}" == "" ]; then
231 echo "Command \`${command}' not understood"
233 ( print_usage )
234 exit 1
236 esac