vfs: check userland buffers before reading them.
[haiku.git] / build / scripts / build_haiku_image
blob28ab70959e49bd1c8a4adecceb3ca358169fc6f1
1 #!/bin/sh
2 set -o errexit
4 # The first argument is the shell script that initializes the variables:
5 # sourceDir
6 # outputDir
7 # tmpDir
8 # addBuildCompatibilityLibDir
9 # systemPackages - lists of the hpkg packages copied/updated
10 # repositories - all repository files
11 # downloadDir
12 # The following are only for image types:
13 # installDir
14 # isImage
15 # imagePath
16 # imageSize
17 # imageLabel
18 # resolvePackageDependencies
19 # noDownloads
20 # updateAllPackages
21 # updateOnly
22 # dontClearImage
23 # isVMwareImage
25 # addattr
26 # copyattr
27 # getPackageDependencies
28 # package
29 # rc
30 # rmAttrs
31 # unzip
32 # The following are only for image types:
33 # bfsShell
34 # fsShellCommand
35 # makebootable
36 # resattr
37 # vmdkimage
38 # The following is only for cd types:
39 # generate_attribute_stores
40 # isCD
42 if [ $# -gt 0 ]; then
43 . $1
44 shift
47 if [ ! $isCD ]; then
48 # If the haiku image path is a symlink resolve it now (makebootable needs the
49 # path of the actual device path under Linux).
50 normalizedImagePath=''
51 if readlink -f "$imagePath" > /dev/null 2>&1 ; then
52 normalizedImagePath=$(readlink -f "$imagePath")
53 elif realpath "$imagePath" > /dev/null 2>&1 ; then
54 normalizedImagePath=$(realpath "$imagePath")
55 elif greadlink -f "$imagePath" > /dev/null 2>&1 ; then
56 normalizedImagePath=$(greadlink -f "$imagePath")
58 if [ -n "$normalizedImagePath" ]; then
59 imagePath="$normalizedImagePath"
63 # this adds the build library dir to LD_LIBRARY_PATH
64 eval "$addBuildCompatibilityLibDir"
66 # map the shell commands
67 if [ $isCD ]; then
68 outputDir=$tmpDir/cdsource
70 sPrefix=
71 tPrefix="$outputDir/"
72 cd=cd
73 scd=:
74 cp="$copyattr -d"
75 copyAttrs="$copyattr"
76 ln=ln
77 mkdir=mkdir
78 rm=rm
79 elif [ $isImage ]; then
80 # If FIFOs are used for the communication with the FS shell, prepare them.
81 if $fsShellCommand --uses-fifos; then
82 fifoBasePath=/tmp/build_haiku_image-$$-fifo
83 toFSShellFifo=${fifoBasePath}-to-shell
84 fromFSShellFifo=${fifoBasePath}-from-shell
86 rm -f $toFSShellFifo $fromFSShellFifo
87 mkfifo $toFSShellFifo $fromFSShellFifo
89 # Open the FIFOs such that they are ready for the fsShellCommand. This
90 # also makes sure that they remain open until this script exits. When we
91 # exit while the FS shell is still running and waiting for commands,
92 # closing of our file descriptors will break the FIFOs and the FS shell
93 # will exit, too.
94 # Note: A bit of trickery is needed since opening one end blocks until
95 # someone opens the other end.
96 sleep 3<$fromFSShellFifo 1 &
97 exec 6>$fromFSShellFifo 3<$fromFSShellFifo
98 sleep 5<$toFSShellFifo 1 &
99 exec 4>$toFSShellFifo 5<$toFSShellFifo
101 # Remove the FIFO files again -- we have the open FDs, so they can
102 # still be used and this makes sure they won't hang around any further.
103 rm -f $toFSShellFifo $fromFSShellFifo
105 # Remap the fsShellCommand and bfsShell such that they don't inherit the
106 # wrong FDs. For both fsShellCommand and bfsShell FD 3 is the input from
107 # the respectively other program, FD 4 is the output to it.
108 actualFSShellCommand="$fsShellCommand"
109 actualBFSShell="$bfsShell"
111 fsShellCommandWrapper()
113 $actualFSShellCommand 5>&- 6>&- "$@"
116 bfsShellWrapper()
118 $actualBFSShell 3>&5 4<&6 "$@"
121 fsShellCommand=fsShellCommandWrapper
122 bfsShell=bfsShellWrapper
125 # set up the other commands
126 sPrefix=:
127 tPrefix=/myfs/
128 cd="$fsShellCommand cd"
129 scd="$fsShellCommand cd"
130 cp="$fsShellCommand cp -f"
131 copyAttrs="$fsShellCommand cp -a"
132 ln="$fsShellCommand ln"
133 mkdir="$fsShellCommand mkdir"
134 rm="$fsShellCommand rm"
135 mkindex="$fsShellCommand mkindex"
136 else
137 sPrefix=
138 # TODO: This should come from the environment.
139 tPrefix="$installDir/"
140 cd=cd
141 scd=:
142 cp="$copyattr -d"
143 copyAttrs="$copyattr"
144 ln=ln
145 mkdir=mkdir
146 rm=rm
147 mkindex=mkindex
151 is_in_list()
153 local element
154 for element in $2; do
155 if [ "$1" = "$element" ]; then
156 return 0
158 done
159 return 1
163 extractFile()
165 # extractFile <archive> <directory> <extractedSubDir>
166 archiveFile=$1
167 targetExtractedDir=$2
168 extractedSubDir=$3
170 extractDir=$tmpDir/extract
171 $rmAttrs -rf "$extractDir"
172 mkdir -p "$extractDir"
174 case "$archiveFile" in
175 *.zip)
176 echo "Extracting $archiveFile ..."
177 $unzip -q -d "$extractDir" "$archiveFile"
179 *.tgz|*.tar.gz)
180 echo "Extracting $archiveFile ..."
181 tar -C "$extractDir" -xf "$archiveFile"
183 *.hpkg)
184 echo "Extracting $archiveFile ..."
185 if [ -n "$extractedSubDir" ]; then
186 $package extract -C "$extractDir" "$archiveFile" \
187 "$extractedSubDir"
188 else
189 $package extract -C "$extractDir" "$archiveFile"
193 echo "Unhandled archive extension in build_haiku_image" \
194 "extractFile()"
195 exit 1
197 esac
199 if [ -f $extractDir/.OptionalPackageDescription ]; then
200 cat $extractDir/.OptionalPackageDescription >> $copyrightsFile
201 echo >> $copyrightsFile
202 rm $extractDir/.OptionalPackageDescription
205 $cp -r "${sPrefix}$extractDir/$extractedSubDir/." \
206 "${tPrefix}$targetExtractedDir"
208 $rmAttrs -rf "$extractDir"
212 downloadFile()
214 url=$1
215 path=$2
217 if [ ! -f "$path" ]; then
218 if [ "$noDownloads" = "1" ]; then
219 echo "ERROR: Would need to download $url, but HAIKU_NO_DOWNLOADS "
220 "is set!"
221 exit 1
223 wget -O "$path" "$url"
228 packageFileName()
230 $package info -f "%fileName%" "$1"
234 mkdir -p $tmpDir
235 copyrightsFile=$tmpDir/copyrights
236 $rmAttrs -f $copyrightsFile
238 if [ $isCD ]; then
239 # setup output dir
240 $rmAttrs -rf "$outputDir"
241 mkdir -p "$outputDir"
244 # create the image and mount it
245 if [ $isImage ]; then
246 echo
248 imageOffsetFlags=
249 if [ $isVMwareImage ]; then
250 imageOffsetFlags="--start-offset 65536"
253 if [ ! $updateOnly ]; then
254 echo "Creating image ..."
256 imageFlags="-i${imageSize}M"
257 if [ ! "$dontClearImage" ]; then
258 imageFlags="$imageFlags -c"
261 if [ $isVMwareImage ]; then
262 $vmdkimage -h 64k $imageFlags "$imagePath"
263 else
264 $createImage $imageFlags "$imagePath"
267 $bfsShell --initialize $imageOffsetFlags "$imagePath" \
268 "$imageLabel" "block_size 2048"
269 $makebootable $imageOffsetFlags "$imagePath"
272 $bfsShell -n $imageOffsetFlags "$imagePath" > /dev/null &
273 sleep 1
275 # Close FDs 5 and 6. Those represent the pipe ends that are used by the
276 # FS shell. Closing them in the shell process makes sure an unexpected death
277 # of the FS shell causes writing to/reading from the other ends to fail
278 # immediately.
279 exec 5>&- 6>&-
281 # bail out, if mounting fails
282 $cd .
286 # Clean out the old packages directory, if updating all packages.
287 if [ -n "$updateAllPackages" ]; then
288 echo "Removing old packages ..."
289 $rm -rf "${tPrefix}system/packages"
290 $mkdir -p "${tPrefix}system/packages"
294 echo "Populating image ..."
295 while [ $# -gt 0 ]; do
296 . $1
297 shift
298 done
301 # resolve package dependencies
302 if [ -n "$resolvePackageDependencies" ]; then
303 echo "Resolving package dependencies ..."
305 packageUrls=`$getPackageDependencies $repositories -- $systemPackages`
306 for packageUrl in $packageUrls; do
307 packageFileName=`basename $packageUrl`
308 packageFilePath="$downloadDir/$packageFileName"
309 downloadFile $packageUrl "$packageFilePath"
310 $cp "${sPrefix}$packageFilePath" "${tPrefix}system/packages"
311 systemPackages="$systemPackages $packageFilePath"
312 done
316 # install default settings for packages
317 for packageFile in $systemPackages; do
318 if $package list -p $packageFile | egrep '^settings/' > /dev/null; then
319 extractFile $packageFile system/settings settings
321 done
324 # add the concatenated copyrights as an attribute to AboutSystem
325 # TODO: That might not be necessary, when all third-party software everything
326 # is packaged. Though we might not package everything.
328 # if [ ! $updateOnly ]; then
329 # if [ -f $copyrightsFile ]; then
330 # copyrightAttrs=$tmpDir/copyrightAttrs
331 # $rmAttrs -f $copyrightAttrs
332 # touch $copyrightAttrs
333 # $addattr -f $copyrightsFile COPYRIGHTS $copyrightAttrs
334 # $copyAttrs ${sPrefix}$copyrightAttrs ${tPrefix}system/apps/AboutSystem
335 # fi
336 # fi
338 if [ $isCD ]; then
339 # generate the attribute stores
340 echo "Generating attribute stores ..."
341 $generate_attribute_stores "$tPrefix"
343 echo "Copying boot image ..."
344 $cp "$cdBootFloppy" "$outputDir"
346 if [ $(which mkisofs) ]; then
347 # build the iso image using mkisofs
348 echo "Building CD image (mkisofs)..."
349 mkisofs -uid 0 -gid 0 -b `basename $cdBootFloppy` -R -V "$cdLabel" -o "$cdImagePath" "$tPrefix"
350 elif [ $(which genisoimage) ]; then
351 # build the iso image using genisoimage
352 echo "Building CD image (genisoimage)..."
353 echo "WARNING: genisoimage fallback has known problems with long filenames!"
354 echo " Please install mkisofs before making production releases!"
355 genisoimage -r -iso-level 4 -b `basename $cdBootFloppy` -V "$cdLabel" -o "$cdImagePath" "$tPrefix"
356 else
357 echo "you need mkisofs (preferred) or genisoimage to create a CD image."
358 exit 1
361 # cleanup output dir
362 $rmAttrs -rf "$outputDir"
365 # unmount
366 if [ $isImage ]; then
367 echo "Unmounting ..."
368 $fsShellCommand sync
369 $fsShellCommand quit