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