Initial import from FreeBSD RELENG_4:
[games.git] / release / picobsd / build / picobsd
1 #!/bin/sh -
2 #
3 # $FreeBSD: src/release/picobsd/build/picobsd,v 1.1.2.28 2002/12/02 22:33:50 luigi Exp $
4 #
5 # The new PicoBSD build script. Invoked as
6 #
7 # picobsd [options] floppy_type site_name
8 #
9 # Where floppy_type is a directory where the picobsd config info
10 # is held, and ${floppy_type}/floppy.tree.${site_name} contains
11 # optional site-specific configuration.
12 #
13 # For Options, see the bottom of the file where the processing is
14 # done. The picobsd(8) manpage might be of some help, but code and docs
15 # tend to lose sync over time...
16 #
17 # This script depends on the following files:
18 #
19 # in ${PICO_TREE} :
20 #   Makefile.conf       Makefile used to build the kernel
21 #   config              shell variables, sourced here.
22 #   mfs.mtree           mtree config file
23 #
24 #   floppy.tree/        files which go on the floppy
25 #   mfs_tree/           files which go onto the mfs
26 #
27 # in ${MY_TREE} :
28 #   PICOBSD             kernel config file
29 #   config              shell variables, sourced here.
30 #   crunch.conf         crunchgen configuration
31 #   floppy.tree.exclude files from floppy.tree/ which we do not need here.
32 #   floppy.tree/        local additions to the floppy.tree
33 #   floppy.tree.${site}/ same as above, site specific.
34
35 #
36 #--- The main entry point is at the end.
37 #
38
39 # There are two set of initialization. The first one (set_defaults)
40 # is done on entry to the script, and is used to set default values
41 # for all variables which do not depend on floppy type and source tree.
42 #
43 # The second set is done after command line parsing, e.g.
44 # to resolve dependencies on the source tree.
45 #
46 # Naming:
47 # + variables that control operation (e.g. verbosity) and are generally
48 #   set from the command line have o_ ("option") as a name prefix
49 #
50 # + variables which contain pathnames and values that should not change
51 #   have c_ ("constant") as a name prefix
52 #
53 # + variables exported to Makefiles and subshells are CAPITAL
54 #
55 # + variables local to the script are lowercase, possibly with
56 #   an l_ ("local") prefix
57
58 # SRC points to your FreeBSD source tree.
59 # l_usrtree points to the /usr subdir for the source tree.
60 #     Normally /usr or ${SRC}/../usr
61 # l_objtree points to the obj tree. Normally ${l_usrtree}/obj-pico
62 # PICO_TREE is where standard picobsd stuff resides.
63 #     Normally ${SRC}/release/picobsd
64 # You can set SRC with --src <directory>
65 # It is not recommended to override the other variables.
66
67 # MY_TREE (set later) is where this floppy type resides.
68 # BUILDDIR is the build directory
69
70 # set some default values for variables.
71 # needs to be done as the first thing in the script.
72
73 # log something on stdout if verbose.
74 o_verbose=0     # this needs to be here!
75 log() {
76     if [ ${o_verbose} -gt 0 ] ; then
77         printf "\n*** %s\n" "$*"
78         if [ ${o_verbose}  -gt 1 ] ; then
79             read -p "=== Press enter to continue" foo
80         fi
81     fi
82 }
83
84 logverbose() {
85     printf "\n*** %s\n" "$*"
86     read -p "=== Press enter to continue" foo
87 }
88
89 set_defaults() {
90     # no way to use logging in this function, variable not set yet.
91
92     # EDITOR is the editor you use
93     # fd_size  floppy size in KB (default to 1440). You can use 1480,
94     #   1720, 2880, etc. but beware that only 1440 and 1480 will boot
95     #   from 1.44M floppy drives (1480 will not work on vmware).
96     EDITOR=${EDITOR:-vi}
97     fd_size=${fd_size:-1440}
98
99     o_all_in_mfs="yes"          # put all files in mfs so you can boot and run
100                                 # the image via diskless boot.
101     o_clean=""                  # do not clean
102     o_interactive=""            # default is interactive
103     o_verbose=0                 # verbose level, 0 is silent
104     o_tarv=""                   # tar verbose flag, "" or "v"
105     o_init_src=""               # non "" if we need to init libs and includes.
106     o_makeopts=${MAKEOPTS:--s}  # make options, be silent by default
107     o_no_devfs=yes              # we do not want devfs
108     o_do_modules=""             # do not build modules
109
110     SRC="/usr/src"              # default location for sources
111     c_startdir=`pwd`    # directory where we start
112                         # used to lookup config and create BUILDDIR
113
114     c_boot1=/boot/boot1 # boot blocks (in case you want custom ones)
115     c_boot2=/boot/boot2
116
117     c_reply=${c_reply:-`mktemp "/tmp/reply.XXXXXXXXXX"`}
118                         # file where User replies will be put
119     c_mnt=`mktemp -d "/tmp/picobsd.XXXXXXXXXX"`
120                         # mountpoint used to build memory filesystems
121     c_fs=fs.PICOBSD     # filename used for the memory filesystem
122     c_img=picobsd.bin   # filename used for the picobsd image
123
124     # select the right memory disk name
125     case `uname -r` in
126         5.*)
127             l_vn="md"
128             l_makedev="${SRC}/etc/MAKEDEV"
129             ;;
130         *)
131             l_vn="vn"
132             l_makedev="/dev/MAKEDEV"
133     esac
134     # Find a suitable vnode
135     l_vnum=`mount | awk "/${l_vn}/ { num++ } END { printf \"%d\", num }"`
136     l_vndev=${l_vn}${l_vnum}
137
138     set -e
139
140     trap fail 2
141     #trap fail 3
142     #trap fail 6
143     trap fail 15
144     free_vnode                  # cleanup old vnodes
145 }
146
147 create_includes_and_libraries2() {
148     log "create_includes_and_libraries2() for ${SRC}"
149     MAKEOBJDIRPREFIX=${l_objtree}
150     export MAKEOBJDIRPREFIX
151     ( cd ${SRC};
152     make -DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R -DPICOBSD buildworld
153     )
154 }
155
156 create_includes_and_libraries() {
157     log "create_includes_and_libraries() for ${SRC}"
158     # Optionally creates include directory and libraries.
159     mkdir -p ${l_usrtree}/include               # the include directory...
160     mkdir -p ${l_usrtree}/share/misc    # a few things go here
161     mkdir -p ${l_usrtree}/lib           # libraries
162     mkdir -p ${l_usrtree}/sbin          # some binaries
163     (cd ${SRC}; INCOWN=`id -un`  BINOWN=`id -un` DESTDIR=${l_usrtree}/.. \
164                 make -m ${SRC}/share/mk includes ) || fail $? includes
165     # Pick up the correct headers for libraries.
166     CFLAGS="-nostdinc -I${l_usrtree}/include" ; export CFLAGS
167
168     (cd ${SRC}
169         # $e is the invocation of make with correct environment
170         e="MAKEOBJDIRPREFIX=${l_objtree}/picobsd/libraries \
171             INCOWN=`id -un` BINOWN=`id -un` DESTDIR=${l_usrtree}/.. \
172             make -m ${SRC}/share/mk \
173                 -DNOHTML -DNOINFO -DNOMAN -DNOSHARE -DNOFSCHG "
174         log "do a 'make obj' in a few places."
175         # This is very version-specific... The following works for 5.0
176         for i in lib secure/lib gnu/lib usr.sbin/pcvt/keycap \
177                 gnu/usr.bin/perl usr.bin/lex usr.sbin/config ; do
178             (cd ${i}; eval $e obj)
179         done
180         log "now make the static libraries"
181         eval $e -DNOPROFILE -DNOPIC libraries
182         (cd ${SRC}/usr.sbin/config
183         eval $e         # build binary
184         eval $e install # install it
185         )
186     ) || fail $? "libraries"
187     log "Libraries done"
188 }
189
190 # set_type <type> looks in user or system directories for the floppy type
191 # specified as first argument, and sets variables according to the config.
192 # file. Also sets MY_TREE and BUILDDIR and SITE
193
194 set_type() {
195     local a
196
197     log "set_type()"
198     THETYPE=$1
199     SITE=$2
200     a=$1
201     for i in ${c_startdir}/${a} ${PICO_TREE}/${a} ; do
202         log "set_type: checking $i"
203         if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ] ; then
204             set -- `cat $i/PICOBSD | \
205             awk '/^#PicoBSD/ {print $2, $3, $4, $5, $6}'`
206             if [ "$1" != "" ]; then
207                 MFS_SIZE=$1 ; init_name=$2
208                 mfs_inodes=$3 ; fd_inodes=$4
209                 name=`(cd $i ; pwd) `
210                 name=`basename $name`
211                 MY_TREE=$i
212                 BUILDDIR=${c_startdir}/build_dir-${name}
213                 log "Matching file $name in $i"
214                 return ;
215             fi
216         fi
217     done
218     echo "Type $a NOT FOUND"
219 }
220
221 clean_tree() {
222     log "clean_tree()"
223     if [ "${name}" = "" ] ; then
224         echo "---> Wrong floppy type"
225         exit 3
226     fi
227     rm -rf ${BUILDDIR}
228 }
229
230 # free as much as possible from the vnode
231 free_vnode() {
232     log "free_vnode() ${l_vndev} "
233     umount ${c_mnt}    2> /dev/null || true
234     umount /dev/${l_vndev}       2> /dev/null || true
235     if [ "${l_vn}" = "vn" ] ; then
236         vnconfig -u ${l_vndev} 2> /dev/null || true
237     else
238         mdconfig -d -u ${l_vnum} 2> /dev/null || true
239     fi
240 }
241
242 # prepare a message to be printed in the dialog menus.
243 set_msgs() {            # OK
244     log "set_msgs()"
245
246     MSG1="Type: ${THETYPE} name $name"
247
248     MSG="PicoBSD build -- Current parameters:\n\n\t1.  ${MSG1}\n\
249 \t2.  MFS size: ${MFS_SIZE} kB\n\
250 \t3.  Site-info: ${SITE}\n\t4.  Full-path: ${MY_TREE}\n"
251 }
252
253
254 # Main build procedure.
255 build_image() {
256     log "build_image() <${name}>"
257     [ "${name}" != "" ] || fail $? bad_type
258     clear
259     set_msgs
260     printf "${MSG}---> We'll use the sources living in ${SRC}\n\n"
261
262     # read config variables from a global and then a type-specific file
263     # basically STAND_LINKS and MY_DEVS, but can also override other
264     # variables.
265     # 
266     . ${PICO_TREE}/build/config
267     if [ -f ${MY_TREE}/config ] ; then
268         . ${MY_TREE}/config
269     fi
270
271     # location of the object directory
272     PICO_OBJ=${l_objtree}/picobsd/${THETYPE}
273     log "PICO_OBJ is ${PICO_OBJ}"
274
275     if [ ${OSVERSION} -ge 500035 ] ; then
276         MAKEOBJDIRPREFIX=${l_objtree}
277         export MAKEOBJDIRPREFIX
278         log `cd ${SRC}; make -f Makefile.inc1 -V WMAKEENV`
279         eval export `cd ${SRC}; make -f Makefile.inc1 -V WMAKEENV`
280     fi
281     # create build directory and subtree
282     mkdir -p ${BUILDDIR}/crunch
283     # remove any old stuff
284     rm -f ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs}
285     # invoke commands to build a kernel
286     do_kernel
287     # fill a subdirectory with things that go into the floppy
288     # (mostly /etc and similar stuff)
289     populate_floppy_fs
290     # populate it and produce a file with the MFS image
291     populate_mfs_tree           # things which go into mfs
292     # create, mount and fill a filesystem with floppy image
293     fill_floppy_image # copies everything into the floppy
294 }
295
296 build_package() {
297     local z msg
298
299     log "build_package()"
300     touch build.status
301     echo "##############################################" >>build.status
302     echo "## `date` ">>build.status
303     echo "##############################################" >>build.status
304     for z in bridge dial router net isp ; do
305         set_type ${z}
306         echo "---------------------------------------------">>build.status
307         echo "Building TYPE=${z}, SIZE=${MFS_SIZE}" >>build.status
308         msg="(ok)"      # error message
309         build_image || msg="** FAILED! **"
310         echo "  ${msg}">>build.status
311         # where do i put things ?
312         # clean_tree
313     done
314     exit 0
315 }
316
317 # Set build parameters interactively
318
319 main_dialog() {
320   local ans i l
321
322   log "main_dialog()"
323   while [ true ] ; do
324     set_msgs
325     rm ${c_reply}
326     dialog --menu "PicoBSD build menu -- (29 sep 2001)" 19 70 12 \
327         N "--> READY, build it <---" \
328         T "${MSG1}" \
329         K "edit Kernel config file" \
330         E "Edit crunch.conf file" \
331         S "MFS Size: ${MFS_SIZE}kB" \
332         I "Init type: ${init_name}" \
333         F "Floppy size: ${fd_size}kB" \
334         M "MFS bytes per inode: ${mfs_inodes}" \
335         U "UFS bytes per inode: ${fd_inodes}" \
336         $ "Site-info: ${SITE}" \
337         Q "Quit" \
338         2> ${c_reply}
339     ans=`cat ${c_reply}`
340     rm ${c_reply}
341     case ${ans} in
342     T)
343         l=""
344         for i in ${c_startdir} ${c_startdir}/* ${PICO_TREE}/* ; do
345             if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ]; then
346                 l="$l `basename $i` `basename $i`"
347             fi
348         done
349         log $l
350         { dialog --menu "Setup the type of configuration" 12 70 5 $l \
351                 2> ${c_reply} && set_type "`cat ${c_reply}`" ${SITE} ; } || true
352         ;;
353     I)
354         { dialog --menu "Choose your init(8) program" \
355         10 70 2 init "Standard init (requires getty)" \
356         oinit "small init from TinyWare" 2> ${c_reply} \
357                 && init_name=`cat ${c_reply}` ; } || true
358         ;;
359
360     K) ${EDITOR} ${MY_TREE}/PICOBSD ;;
361
362     E) ${EDITOR} ${MY_TREE}/crunch.conf ;;
363
364     S)
365         { dialog --title "MFS Size setup" --inputbox \
366 "MFS size depends on what you need to put on the MFS image. Typically \
367 ranges between 820kB (for very small bridge/router images) to \
368 as much as 2500kB kB for a densely packed image. \
369 Keep in mind that this memory is \
370 totally lost to other programs. Usually you want to keep \
371 this as small as possible. " 10 70 2> ${c_reply} \
372         && MFS_SIZE=`cat ${c_reply}` ; } || true
373         ;;
374
375     \$)
376         { dialog --title "Site info setup" --inputbox \
377         "Please enter the full path to the directory \
378         containing site-specific setup. \
379         This directory tree must contain files that replace \
380         standard ones in floppy.tree/ and mfs.tree/ . " \
381         10 70 2> ${c_reply} && SITE=`cat ${c_reply}` ; } || true
382         ;;
383
384     F)
385         { dialog --menu "Set floppy size" 15 70 4 \
386             1440 "1.44MB" 1720 "1.72MB" 2880 "2.88MB" 4096 "4MB" \
387                  2> ${c_reply} && fd_size=`cat ${c_reply}` ; } || true
388         ;;
389
390     M)
391         { dialog --title "MFS bytes per inode:" --inputbox \
392         "Enter MFS bytes per inode (typically 4096..65536). \
393         A larger value means fewer inodes but more space on MFS" \
394         10 70 2> ${c_reply} && mfs_inodes=`cat ${c_reply}`  ; } || true
395         ;;
396
397     U)
398         { dialog --title "Floppy bytes per inode:" --inputbox \
399         "Enter floppy bytes per inode (typically 3072..65536). \
400         A larger value means fewer inodes but more space on the floppy." \
401         10 70 2> ${c_reply} && fd_inodes=`cat ${c_reply}` ; } || true
402         ;;
403
404     N) break 2
405         ;;
406
407     Q) exit 0 ;;
408
409     *) echo "\aUnknown option \"${ans}\". Try again."
410         sleep 2
411         clear
412         ;;
413     esac
414   done
415 }
416
417 # Call the build procedure
418 # Install image
419 do_install() {
420     log "do_install()"
421
422     if [ "${o_interactive}" = "NO" ] ; then
423         echo "+++ Build completed +++"
424         cat .build.reply
425         return
426     fi
427     dialog --title "Build ${THETYPE} completed" --inputbox \
428 "\nThe build process was completed successfuly.\n\
429 `cat .build.reply` \n\n\
430 Now we are going to install the image on the floppy.\n\
431 Please insert a blank floppy in /dev/fd0.\\n
432 WARNING: the contents of the floppy will be permanently erased!\n\
433 \n\
434 Your options:\n\
435         * ^C or [Cancel] to abort,\n\
436         * Enter to install ${c_img},\n\
437 " 20 80 2> ${c_reply}
438     if [ "$?" = "0" ]; then
439         echo "Writing ${c_img}..."
440         dd if=${BUILDDIR}/${c_img} of=/dev/fd0.${fd_size}
441     else
442         echo "Ok, the image is in ${c_img}"
443     fi
444     echo "Done."
445 }
446
447
448 #-------------------------------------------------------------------
449
450 # invoke the Makefile to compile the kernel.
451 do_kernel() {           # OK
452     log "do_kernel() Preparing kernel \"$name\" in $MY_TREE"
453     (cd $MY_TREE; export name SRC BUILDDIR # used in this makefile ;
454         # export CONFIG
455         if [ "${o_do_modules}" = "yes" ] ; then
456                 MODULES=""
457                 export MODULES
458         fi
459         make -m ${SRC}/share/mk -v -f ${PICO_TREE}/build/Makefile.conf ) || \
460         fail $? missing_kernel
461 }
462
463 # Populate the variable part of the floppy filesystem. Must be done before
464 # the MFS because its content might need to be copied there as well.
465 #
466 # This involves fetching files from three subtrees, in this order:
467 #
468 #  1. a standard one, from which type-specific files are excluded;
469 #  2. a type-specific one;
470 #  3. a site-specific one.
471 #
472 # Files are first copied to a local tree and then compressed.
473
474 populate_floppy_fs() {          # OK
475     local dst excl srcdir
476
477     log "populate_floppy_fs()"
478     dst=${BUILDDIR}/floppy.tree
479     log "pwd=`pwd` Populating floppy filesystem..."
480
481     # clean relics from old compilations.
482     rm -rf ${dst} || true
483     mkdir ${dst}
484
485     excl=${MY_TREE}/floppy.tree.exclude
486     if [ -f ${excl} ] ; then
487         excl="--exclude-from ${excl}"
488         log "Files excluded from generic tree: `echo;cat ${excl}`"
489     else
490         excl=""
491     fi
492     (cd ${PICO_TREE}/floppy.tree ; tar -cf - --exclude CVS ${excl} . ) | \
493                 (cd ${dst} ; tar x${o_tarv}f - )
494     log "Copied from generic floppy-tree `echo; ls -laR ${dst}`"
495
496     srcdir=${MY_TREE}/floppy.tree
497     if [ -d ${srcdir} ] ; then
498         log "update with type-specific files:"
499         (cd ${srcdir} ; tar -cf - --exclude CVS . ) | \
500             (cd ${dst} ; tar x${o_tarv}f - )
501         log "Copied from type floppy-tree `echo; ls -laR ${dst}`"
502     else
503         log "No type-specific floppy-tree"
504     fi
505     if [ -d ${srcdir}.${SITE} ] ; then
506         log "Update with site-specific (${SITE}) files:"
507         (cd ${srcdir}.${SITE} ; tar -cf - --exclude CVS . ) | \
508             (cd ${dst} ; tar x${o_tarv}f - )
509         log "Copied from site floppy-tree `echo; ls -laR ${dst}`"
510     else
511         log "No site-specific floppy-tree"
512     fi
513
514     # gzip returns an error if it fails to compress some file
515     (cd $dst ; gzip -9 etc/*
516             log "Compressed files in etc/ `echo; ls -l etc`"
517     ) || true
518 }
519
520 create_mfs() {          # OK
521     log "create_mfs() Preparing MFS filesystem..."
522
523     free_vnode
524
525     # zero-fill the MFS image
526     init_fs_image ${BUILDDIR}/${c_fs} ${MFS_SIZE}
527
528     log "Labeling MFS image"
529     # Disklabel "auto" behaves strangely for sizes < 1024K. Basically
530     # it fails to install a label on the system. On the other hand,
531     # if you provide a specific disk type, the boot code is not
532     # installed so you have more space on the disk...
533     # For small image sizes, use std disktypes
534     if [ ${MFS_SIZE} -lt 1024 ] ; then
535         disklabel -rw ${l_vndev} fd${MFS_SIZE} || fail $? mfs_disklabel
536     else
537         disklabel -rw ${l_vndev} auto || fail $? mfs_disklabel
538     fi
539     newfs -i ${mfs_inodes} -m 0 -o space -f 512 -b 4096 \
540         /dev/${l_vndev}c > /dev/null
541     mount /dev/${l_vndev}c ${c_mnt} || fail $? no_mount
542     log "`df /dev/${l_vndev}c`"
543 }
544
545 # Populate the memory filesystem with binaries and non-variable
546 # configuration files.
547 # First do an mtree pass, then create directory links and device entries,
548 # then run crunchgen etc. to build the binary and create links.
549 # Then copy the specific/generic mfs_tree.
550 # Finally, if required, make a copy of the floppy.tree onto /fd
551
552 populate_mfs_tree() {
553     local a dst
554
555     log "populate_mfs_tree()"
556     early_mfs_mount=0
557     if [ "${early_mfs_mount}" = "1" ] ; then
558         create_mfs
559         dst=${c_mnt}
560     else
561         dst=${BUILDDIR}/mfs.tree
562         # clean relics from old compilations.
563         rm -rf ${dst} || true
564         mkdir ${dst}
565     fi
566
567     log "pwd=`pwd`, Populating MFS tree..."
568
569     # use type-specific mfs.mtree, default to generic one.
570     a=${MY_TREE}/mfs.mtree
571     [ -f ${a} ] || a=${PICO_TREE}/build/mfs.mtree
572     log "Running mtree using $a..."
573     mtree -deU -f $a -p ${dst} > /dev/null || fail $? mtree
574
575     # XXX create links
576     for i in ${STAND_LINKS}; do
577         ln -s /stand ${dst}/$i
578     done
579     ln -s /dev/null ${dst}/var/run/log
580     ln -s /etc/termcap ${dst}/usr/share/misc/termcap
581
582
583     (
584     cd ${BUILDDIR}/crunch
585     log "Making and installing crunch1 from `pwd` src ${SRC}..."
586     a=${BUILDDIR}/crunch1.conf
587     ( export BUILDDIR SRC MY_TREE PICO_OBJ ;
588         make -m ${SRC}/share/mk \
589                 -v -f ${PICO_TREE}/build/Makefile.conf ${BUILDDIR}/crunch.mk )
590     log "Libs are ${LIBS} "
591     export SRC # used by crunch.mk
592     # export LIBS CFLAGS
593     log "Now make -f crunch.mk"
594     make -m ${SRC}/share/mk ${o_makeopts} -f ${BUILDDIR}/crunch.mk
595     strip --remove-section=.note --remove-section=.comment crunch1
596     mv crunch1 ${dst}/stand/crunch
597     chmod 555 ${dst}/stand/crunch
598     log "Making links for binaries..."
599     for i in `crunchgen -l $a` ; do
600         ln ${dst}/stand/crunch ${dst}/stand/${i};
601     done
602     # rm $a # do not remove!
603     ) || fail $? crunch
604
605     if [ -f ${dst}/stand/sshd ] ; then
606         log "Setting up host key for sshd:"
607         if [ -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key.gz ] ; then
608             log "Using existing host key"
609         else
610             log "Generating new host key" 
611             ssh-keygen -t rsa1 -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key \
612                  -N "" -C "root@picobsd"
613             gzip -9 ${BUILDDIR}/floppy.tree/etc/ssh_host_key* || true
614         fi
615     fi
616
617     log "Copy generic and site-specific MFS tree..."
618     for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do
619         if [ -d ${MFS_TREE} ] ; then
620             log "Copy ${MFS_TREE} ..."
621             (cd ${MFS_TREE} ; tar -cf - --exclude CVS . ) | \
622                     (cd ${dst} ; tar x${o_tarv}f - )
623         fi
624     done
625
626     if [ "${o_all_in_mfs}" = "yes" ]; then
627         log "Copy generic floppy_tree into MFS..."
628         cp -Rp ${BUILDDIR}/floppy.tree/* ${dst}/fd
629     fi
630
631     [ "`id -u`" = "0" ] || cat <<__EOF
632
633 ### -------------------------------------------------------------------
634 ###
635 ### WARNING: You are not running with root permissions, so the next
636 ### stages are likely to fail because they call commands such as
637 ### chown, {vn|md}config, mount/umount which need adequate rights.
638 ###
639 ### The results of the compilation so far is in directory
640 ###  ${BUILDDIR}
641 ### which has the following content:
642
643 `ls -l ${BUILDDIR}`
644
645 ###
646 ### -------------------------------------------------------------------
647
648 __EOF
649
650     if [ "${o_no_devfs}" != "" ] ; then
651         # create device entries using MAKEDEV
652         (cd ${dst}/dev
653         ln -s ${l_makedev} ; chmod 555 MAKEDEV
654         ./MAKEDEV ${MY_DEVS}
655         rm MAKEDEV
656         )
657     fi
658     log "Fixing permissions"
659     (cd ${dst}; chown -R root . )
660
661     if [ -n "${import_files}" ] ; then
662         log "importing ${import_files} into mfs"
663         # We do it in a chroot environment on the target so
664         # symlinks are followed correctly.
665         cp `which tar` ${dst}/my_copy_of_tar
666         (cd ${l_usrtree}/.. ; tar cf - ${import_files} ) | \
667             (chroot ${dst} /my_copy_of_tar xf - )
668         rm ${dst}/my_copy_of_tar
669     fi
670
671     if [ "${early_mfs_mount}" != "1" ] ; then
672         create_mfs
673         log "Copy mfs tree into file"
674         (cd ${dst} ; tar cf - . ) | ( cd ${c_mnt} ; tar xf - )
675     fi
676     # now umount and fsck the filesystem.
677     log "Status of mfs image"
678     df -ik ${c_mnt}
679     umount ${c_mnt}
680     fsck -p /dev/${l_vndev}c
681     free_vnode
682 }
683
684 final_cleanup() {
685     log "final_cleanup()"
686     free_vnode
687     rm -rf ${c_mnt} ${c_reply} 2> /dev/null || true
688     rm -f ${c_reply}
689 }
690
691 # fail errno errcode
692 # This function is used to trap errors and print msgs
693 #
694 fail() {
695     local errno errocode where
696
697     errno=$1
698     errcode=$2
699     where=$3
700     echo "---> fail: Error <${errno}> error code <${errcode}> in <${where}>"
701     case ${errcode} in
702     no_vnconfig)
703         echo "Error in vnconfig on /dev/${l_vndev}..."
704         echo "Either you are not running as root or your running kernel"
705         echo "does not have the ${l_vn}(4) device."
706         ;;
707     mfs_disklabel)
708         echo "Error while labeling ${c_fs} size ${MFS_SIZE}"
709         ;;
710     no_mount)
711         echo "Error while mounting ${c_fs} (/dev/${l_vndev}c) on ${c_mnt}"
712         ;;
713     mtree)
714         echo "Error while making hierarchy in ${c_mnt}"
715         ;;
716     crunch)
717         echo "Error while building ${name}."
718         ;;
719     floppy_disklabel)
720         echo "Error while doing disklabel on of floppy.img size $fd_size"
721         ;;
722     missing_kernel)
723         echo "Error: you must build PICOBSD${suffix} kernel first"
724         ;;
725     includes)
726         echo "Error: failed while making includes"
727         ;;
728     libraries)
729         echo "Error: failed while making libraries"
730         ;;
731     bad_type)
732         echo "Error: unknown floppy type ${name}"
733         ;;
734     no_space)
735         echo "Error: no space left on device (${where})"
736         ;;
737     no_mfs)
738         echo "Error: while writing MFS into the kernel."
739         ;;
740     "")
741         echo "User break"
742         errcode="userbreak"
743         ;;
744     *)
745         echo "unknown error, maybe user break: $errno $errcode"
746         ;;
747     esac
748     echo "---> Aborting $0"
749     # try to cleanup the vnode.
750     final_cleanup
751     exit 2
752 }
753
754 #
755 # Create a zero-filled disk image with a boot sector, and vnconfig it.
756 #
757
758 init_fs_image() { # filename size_in_kbytes
759     local imgname imgsize
760
761     log "init_fs_image() $1 $2"
762     imgname=$1 ; imgsize=$2
763     dd if=/dev/zero of=${imgname} count=${imgsize} bs=1k 2> /dev/null
764     dd if=${c_boot1}  of=${imgname} conv=notrunc 2> /dev/null
765
766     if [ "${l_vn}" = "vn" ] ; then
767         vnconfig -c -s labels ${l_vndev} ${imgname} || fail $? no_vnconfig
768     else
769         mdconfig -a -t vnode -u ${l_vnum} -f ${imgname} || fail $? no_vnconfig
770     fi
771 }
772
773
774 fill_floppy_image() {
775     local blocks sectors dst
776
777     log "fill_floppy_image()"
778     dst=${c_mnt}        # where to create the image
779
780     log "Preparing ${fd_size}kB floppy filesystem..."
781
782     # correct block and number of sectors according to size.
783     blocks=${fd_size}; sectors=18
784     if [ "${blocks}" = "1720" ]; then
785         blocks=1722 ; sectors=21
786     elif [ "${blocks}" = "1480" ]; then
787         blocks=1476 ;
788     fi
789
790     init_fs_image ${BUILDDIR}/${c_img} ${blocks}
791
792     log "Labeling floppy image"
793     b2=${BUILDDIR}/boot2 # modified boot2
794     cp ${c_boot2} ${b2}
795     chmod 0644 ${b2}
796     set `strings -at d ${b2} | grep "/boot/loader"`
797     echo -e "/kernel\0\0\0\0\0" | dd of=${b2} obs=$1 oseek=1 conv=notrunc
798     chmod 0444 ${b2}
799
800     # create a disklabel ...
801     disklabel -Brw -b ${c_boot1} -s ${b2} ${l_vndev} auto || \
802         fail $?  floppy_disklabel
803
804     # and copy partition c: into partition a: using some sed magic
805     disklabel ${l_vndev} | sed -e '/  c:/{p;s/c:/a:/;}' | \
806         disklabel -R ${l_vndev} /dev/stdin
807
808     log "Newfs floppy image"
809     newfs -i ${fd_inodes} -m 0 -o space -f 512 -b 4096 \
810              /dev/${l_vndev}a > /dev/null
811
812     log "Mounting floppy image"
813     mount /dev/${l_vndev}a ${dst}
814
815     (
816     cd ${BUILDDIR}
817     # $1 takes the offset of the MFS filesystem
818     set `strings -at d kernel | grep "MFS Filesystem goes here"`
819     mfs_ofs=$(($1 + 8192))
820     log "Preload kernel with file ${c_fs} at ${mfs_ofs}"
821     dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \
822         oseek=1 conv=notrunc
823     log "Compress with kgzip and copy to floppy image"
824     kgzip -o kernel.gz kernel
825     cp -p kernel.gz ${dst}/kernel || fail $? no_space "copying kernel"
826
827     log "now transfer floppy tree if needed"
828     # now transfer the floppy tree. If it is already in mfs, dont bother.
829     if [ "${o_all_in_mfs}" != "yes" ] ; then
830         cp -Rp floppy.tree/* ${dst} || \
831                 fail $? no_space "copying floppy tree"
832     fi
833     )
834     (log "Fixing permissions"; cd ${dst}; chown -R root *)
835     # rm -rf ${BUILDDIR}/floppy.tree || true # cleanup
836
837     df -ik ${dst} | colrm 70 > .build.reply
838     free_vnode
839     rm -rf ${dst}
840     rm ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs}
841 }
842
843 # This function creates variables which depend on the source tree in use:
844 # SRC, l_usrtree, l_objtree
845 # Optionally creates libraries, includes and the like (for cross compiles,
846 # needs to be done once).
847
848 set_build_parameters() {
849     log "set_build_parameters() SRC is ${SRC}"
850     if [ "${SRC}" = "/usr/src" ] ; then
851         l_usrtree=${USR:-/usr}
852     else
853         l_usrtree=${USR:-${SRC}/../usr}
854     fi
855     l_objtree=${l_usrtree}/obj-pico
856     PICO_TREE=${PICO_TREE:-${SRC}/release/picobsd}
857     set `grep "#define[\t ]__FreeBSD_version" ${SRC}/sys/sys/param.h`
858     OSVERSION=$3
859     log "OSVERSION is ${OSVERSION}"
860     if [ "${o_init_src}" != "" ] ; then
861         if [ ${OSVERSION} -lt 500035 ] ; then
862             create_includes_and_libraries
863         else
864             create_includes_and_libraries2
865         fi
866     fi
867     if [ ${OSVERSION} -lt 500035 ] ; then
868         # Create the right LIBS and CFLAGS for further builds.
869         # and build the config program
870         LIBS="-L${l_usrtree}/lib"
871         CFLAGS="-nostdinc -I${l_usrtree}/include"
872         export LIBS CFLAGS
873         CONFIG=${l_usrtree}/sbin/config
874         export CONFIG
875     fi
876 }
877
878 #-------------------------------------------------------------------
879 # Main entry of the script. Initialize variables, parse command line
880 # arguments.
881
882 set_defaults
883 while [ true ]; do
884     case $1 in
885     --src)      # set the source path instead of /usr/src
886         SRC=`(cd $2; pwd)`
887         shift
888         ;;
889     --init)
890         o_init_src="YES"
891         ;;
892
893     --floppy_size)
894         fd_size=$2
895         shift
896         ;;
897
898     --all_in_mfs)
899         o_all_in_mfs="yes"
900         ;;
901
902     --no_all_in_mfs)
903         o_all_in_mfs=""
904         ;;
905
906     --modules)  # also build kernel modules
907         o_do_modules="yes"
908         ;;
909     -n)
910         o_interactive="NO"
911         ;;
912
913     -clear|-clean|-c) # clean
914         o_clean="YES"
915         o_interactive="NO"
916         ;;
917
918     -v) # need -v -v to wait for user input
919         o_verbose=$((${o_verbose}+1))   # verbose level
920         o_tarv="v"                      # tar verbose flag
921         o_makeopts="-d l" # be verbose
922         ;;
923     *)
924         break ;
925         ;;
926
927     esac
928     shift
929 done
930 set_build_parameters    # things that depend on ${SRC}
931 set_type $1 $2          # type and site, respectively
932
933 # If $1="package", it creates a neat set of floppies
934
935 if [ "$1" = "package" ] ; then
936     build_package
937 fi
938 if [ "${o_interactive}" != "NO" ] ; then
939     main_dialog
940 fi
941 if [ "${o_clean}" = "YES" ] ; then
942     clean_tree
943 else
944     build_image
945     do_install
946 fi
947 final_cleanup
948 exit 0