                           FreeBSD "s nulya"

  Jens Schweikhardt

   <schweikh@FreeBSD.org>

   Copyright (c) 2002,2003,2004 Jens Schweikhardt

   $FreeBSD:
   doc/ru_RU.KOI8-R/articles/fbsd-from-scratch/article.sgml,v 1.4
   2005/06/14 06:38:08 andy Exp $

   FreeBSD `eto zaregistrirovannaya torgovaya marka FreeBSD
   Foundation.

   Adobe, Acrobat, Acrobat Reader i PostScript `eto ili
   zaregistrirovannye torgovye marki ili torgovye marki Adobe Systems
   Incorporated v Soedinennyh SHtatah i/ili drugih stranah.

   Mnogie iz oboznachenij, ispol'zuemye proizvoditelyami i prodavcami
   dlya oboznacheniya svoih produktov, zayavlyayutsya v kachestve
   torgovyh marok. Kogda takie oboznacheniya poyavlyayutsya v `etom
   dokumente, i Proektu FreeBSD izvestno o torgovoj marke, k
   oboznacheniyu dobavlyaetsya znak ''(TM)'' ili ''(R)''.

     --------------------------------------------------------------

     V `etoj stat'e opisyvaetsya moi po polnost'yu
     avtomatizirovannaya ustanovka prednastroennoj kompiliruemoj iz
     ishodnyh tekstov, vklyuchaya kompilyaciyu vseh vashih lyubimyh
     portov i prednastroennoj tak, chto ona sootvetstvuet vashim
     predstavleniyam o nastoyaschej sisteme. Esli vy polagaete, chto
     koncepciya make world yavlyaetsya prekrasnym podhodom, to
     FreeBSD From Scratch rasshiryaet `eto ponyatie do make evenmore.

     --------------------------------------------------------------

1. Vvedenie

   Vy kogda-libo obnovlyali vashu sistemu pri pomoschi make world?
   Suschestvuet odna problema, voznikayuschaya pri nalichii vsego
   lish' odnoj sistemy na diske. Esli vypolnenie celi installworld
   preryvaetsya na seredine, u vas ostaiotsya nerabotosposobnaya
   sistema, kotoraya mozhet dazhe ne zagruzhat'sya. Libo cel'
   installworld otrabatyvaet normal'no, a novoe yadro ne
   zagruzhaetsya. Togda nastupaet moment dlya poiska Fixit CD i
   rezervnyh kopij, kotorye vy delali polgoda nazad.

   YA ispoveduyu podhod ''sotrite dannye na diskah pri obnovlenii
   sistem''. Udalenie diskov, i dazhe razdelov, obespechivaet vam to,
   chto nigde ne ostaiotsya nikakih chastej starogo, to, o chiom ne
   zabotyatsya bol'shee chislo procedur obnovleniya. Odnako ochistka
   razdelov oznachaet, chto vam nuzhno
   perekompilirovat'/pereustanovit' vse vashi porty i pakadzhi, a
   takzhe prodelat' vse tonkie procedury nastrojki. Esli vy dumaete,
   chto `eta zadacha tozhe dolzhna byt' avtomatizirovana, to chitajte
   dal'she.

     --------------------------------------------------------------

2. Pochemu mne (ne) nuzhna FreeBSD From Scratch?

   `Eto zakonomernyj vopros. U nas imeetsya utilita sysinstall i
   horosho izuchennyj sposob kompilyacii yadra i pol'zovatel'skih
   prilozhenij.

   Problema s utilitoj sysinstall zaklyuchaetsya v tom, chto ona
   neskol'ko ogranichena v tom, chto, kuda i kak mozhet
   ustanavlivat'.

     * Obychno ona ispol'zovalas' dlya ustanovki uzhe
       otkompilirovannyh distributivnyh naborov i pakadzhej s
       nekotorogo nositelya (CD, DVD, FTP). Ona ne mozhet
       ustanavlivat' rezul'tat vypolneniya make buildworld.

     * Ona ne mozhet ustanavlivat' vtoruyu sistemu v nekotoryj
       katalog uzhe rabotayuschej sistemy.

     * Ona ne mozhet vypolnyat' ustanovku v razdely Vinum.

     * Ona ne mozhet stroit' porty, a lish' ustanavlivat' uzhe
       otkompilirovannye pakadzhi.

     * Sozdanie skriptov ili vypolnenie nestandartnyh dejstvij posle
       ustanovki zatrudneno.

     * I poslednim, no odnim iz samyh vazhnyh faktorov, yavlyaetsya
       poluoficial'noe prekraschenie dal'nejshej podderzhki
       sysinstall.

   Horosho izvestnyj sposob polnogo postroeniya i ustanovki sistemy,
   opisannyj v Rukovodstve, po umolchaniyu zameschaet
   suschestvuyuschuyu sistemu. Pri `etom sohranyayutsya tol'ko moduli
   i yadro. Sistemnye binarnye fajly, fajly ob"yavlenij funkcij i
   mnozhestvo drugih fajlov perezapisyvayutsya; uzhe nenuzhnye fajly
   ostayutsya i mogut prepodnosit' syurprizy. Esli po kakoj-libo
   prichine obnovlenie zavershilos' neudachno, byvaet trudno i dazhe
   nevozmozhno vernut' sistemu v ishodnoe sostoyanie.

   FreeBSD From Scratch reshaet vse `eti problemy. Eio strategiya
   prosta: ispol'zovanie rabotayuschej sistemy dlya ustanovki novoj v
   pustoe derevo katalogov, pri `etom novye razdely montiruyutsya v
   sootvetstvuyuschie mesta `etogo dereva. Mnogie konfiguracionnye
   fajly mogut byt' skopirovany v sootvetstvuyuschee mesto, a
   mergemaster(8) smozhet pozabotit'sya o teh, chto skopirovat' ne
   udalos'. Tonkaya nastrojka novoj sistemy mozhet byt' vypolnena v
   staroj, vplot' do momenta, kogda vy smozhete vypolnit' chroot v
   novuyu sistemu. Drugimi slovami, my prohodim cherez tri `etapa,
   pri `etom kazhdyj shag predstavlyaet soboj libo zapusk skripta,
   libo vyzov komandy make:

    1. stage_1.sh: Sozdanie novoj zagruzhaemoj sistemy v pustom
       kataloge i ob"edinenie libo kopirovanie maksimal'no bol'shego
       kolichestva neobhodimyh fajlov. Zatem zagruzka novoj sistemy.

    2. stage_2.sh: Ustanovka trebuemyh portov.

    3. stage_3.mk: Vypolnenie posleduyuschej nastrojki programmnogo
       obespecheniya, ustanovlennogo na predyduschem `etape.

   Posle togo, kak vy vospol'zuetes' FreeBSD From Scratch dlya
   postroeniya vtoroj sistemy i v techenie neskol'kih nedel'
   ubedites', chto ona rabotaet udovletvoritel'no, mozhete zatem
   ispol'zovat' eio povtorno dlya pereustanovki ishodnoj sistemy. S
   `etogo momenta, kak tol'ko vy pochuvstvuete neobhodimost'
   obnovleniya, to prosto vyberite razdely, kotorye hotite udalit' i
   vypolnit' pereustanovku.

   Mozhet byt', vy slyshali i dazhe probovali ispol'zovat' sistemu
   Linux From Scratch, ili LFS dlya kratkosti. LFS takzhe
   opredelyaet, kak postroit' i ustanovit' sistemu s nulya na pustoj
   razdel pri pomoschi rabotayuschej sistemy. LFS delaet upor na
   vyyasnenie roli kazhdogo komponenta sistemy (takih, kak yadro,
   kompilyator, ustrojstva, komandnyj processor, baza dannyh
   terminal'nyh ustrojstv i tak dalee) i detalej ustanovki kazhdogo
   komponenta. FreeBSD From Scratch ne opuskaetsya do takogo urovnya
   detalizacii. Moej cel'yu yavlyaetsya provedenie avtomatizirovannoj
   i polnoj ustanovki, a ne opisanie vseh krovavyh podrobnostej
   polnogo perepostroeniya sistemy. V sluchae, esli vy hotite
   izuchit' FreeBSD do takogo urovnya, nachnite s prosmotra
   /usr/src/Makefile i sledujte dejstviyam, kotorye vypolnyaet make
   buildworld.

   V podhode, kotoryj primenyaetsya v FreeBSD From Scratch, imeyutsya
   svoi otricatel'nye storony, kotorye vy dolzhny imet' v vidu.

     * Pri kompilyacii portov na vtorom `etape sistemu nel'zya
       ispol'zovat' v obychnom rezhime. Esli vy imeete delo s
       serverom, rabotayuschim v rezhime promyshlennoj `ekspluatacii,
       vy dolzhny byt' gotovy k prostoyu, k kotoromu privodit
       vypolnenie vtorogo `etapa. Porty, postroennye pri pomoschi
       stage_2.conf.default nizhe, trebuyut primerno 4 chasa dlya
       postroeniya na sisteme AMD1800+ so SCSI-diskami, imeyuschimi
       skorost' vrascheniya 10krpm i 1 Gbajtom OZU. Esli vy
       predpochitaete ustanavlivat' pakety, a ne porty, to vy mozhete
       suschestvenno sokratit' vremya prostoya, primerno na 10 minut.

     --------------------------------------------------------------

3. Predvaritel'nye trebovaniya

   Dlya togo, chtoby vospol'zovat'sya podhodom FreeBSD From Scratch,
   vam nuzhno imet':

     * Rabotayuschuyu sistemu FreeBSD s ishodnymi tekstami i derevom
       portov.

     * Po krajnej mere odin neispol'zuemyj razdel, kuda budet
       ustanavlivat'sya novaya sistema.

     * Opyt raboty s mergemaster(8). Ili po krajnej mere otsutstvie
       straha ego ispol'zovat'.

     * Esli u vas net podklyucheniya ili slabyj kanal v Internet:
       distributivnye fajly dlya vashih lyubimyh portov.

     * Znanie osnov napisaniya skriptov na yazyke komandnogo
       processora Bourne, sh(1).

     * Nakonec, vy dolzhny umet' ukazyvat' zagruzchiku sistemy na
       zagruzku novoj sistemy, libo interaktivno, libo iz
       konfiguracionnogo fajla.

     --------------------------------------------------------------

4. `Etap pervyj: Ustanovka sistemy

   V pervom variante `etoj stat'i na pervom shage ispol'zovalsya
   edinstvennyj skript, v kotorom vsya nastrojka vypolnyalas' ego
   redaktirovaniem. Posle togo, kak pol'zovateli vyskazali svoi
   zamechaniya, ya reshil razdelit' kod i dannye na urovne skriptov.
   `Eto pozvolyaet imet' raznye nabory konfiguracionnyh dannyh dlya
   ustanovki razlichnyh sistem bez vneseniya izmenenij v skripty s
   kodom.

   Skript s kodom dlya pervogo `etapa nazyvaetsya stage_1.sh, i on
   zapuskaetsya s edinstvennym argumentom, naprimer

 # ./stage_1.sh default

   budet schityvat' svoyu konfiguraciyu iz fajla stage_1.conf.default
   i zapisyvat' protokol v fajl stage_1.log.default.

   Dalee privoditsya moj fajl stage_1.conf.default. Vam neobhodimo
   podpravit' ego v razlichnyh mestah dlya togo, chtoby on
   sootvetstvoval vashim predstavleniyam ob ''ideal'noj sisteme''. YA
   popytalsya podrobno prokommentirovat' te mesta, kotorye vy dolzhny
   ispravlyat'. Konfiguracionnyj skript dolzhen predostavlyat'
   chetyre funkcii dlya obolochki, create_file_systems,
   create_etc_fstab, copy_files i all_remaining_customization (v
   sluchae, esli `eto imeet smysl: imenno v takoj posledovatel'nosti
   oni budut vyzyvat'sya iz stage_1.sh).

   Sleduet vnimatel'no otnestis' k sleduyuschim momentam:

     * Razbienie razdelov.

       YA ne yavlyayus' storonnikom nalichiya odnogo bol'shogo
       razdela dlya vsej sistemy. Moi sistemy, kak pravilo, imeyut po
       krajnej mere po odnomu razdelu dlya /, /usr i /var s katalogom
       /tmp, obrazovannym simvolicheskoj ssylkoj v /var/tmp. Vdobavok
       ya ispol'zuyu fajlovye sistemy v rezhime sovmestnogo dostupa k
       /home (domashnie katalogi pol'zovatelej), /home/ncvs (kopiya
       CVS-hranilischa FreeBSD), /usr/ports (derevo portov), /src
       (razlichnye vygruzhennye iz hranilischa derev'ya ishodnyh
       tekstov) i /share (ostal'nye sovmestno ispol'zuemye dannye,
       rezervnye kopii kotoryh ne nuzhny, naprimer, spul servera
       telekonferencij).

     * Novye vozmozhnosti.

       `Eto to, chto vy hotite imet' srazu posle zagruzki novoj
       sistemy i dazhe do zapuska vtorogo `etapa. Prichina otkaza ot
       sozdaniya i perehoda v chroot-okruzhenie novoj sistemy vo
       vremya pervogo `etapa i prostoj ustanovki vseh moih lyubimyh
       portov zaklyuchaetsya v tom, chto teoreticheski i prakticheski
       suschestvuyut problemy nachal'noj zagruzki i celostnosti: na
       pervom `etape rabotaet vashe staroe yadro, odnako v
       chroot-okruzhenii soderzhatsya novye dvoichnye fajly programm
       i fajly ob"yavlenij. Esli novye programmy ispol'zuyut novyj
       sistemnyj vyzov, to oni budut zavershat'sya SIGSYS, Plohoj
       sistemnyj vyzov, tak kak staroe yadro ne podderzhivaet `etot
       novyj vyzov. YA nablyudal i drugie problemy pri popytke
       postroeniya porta lang/perl5.

   Pered tem, kak zapuskat' stage_1.sh, ubedites', chto vypolnili
   obychnye dejstviya pri podgotovke k make installworld
   installkernel, tipa:

     * otredaktirovali konfiguracionnyj fajl vashego yadra

     * uspeshno vypolnili make buildworld

     * uspeshno vypolnili make buildkernel KERNCONF=whatever

   Kogda vy zapuskaete stage_1.sh pervyj raz, i konfiguracionnyj
   fajl, skopirovannyj s rabotayuschej sistemy v novuyu, yavlyaetsya
   ustarevshim po sravneniyu s tem, chto nahoditsya v kataloge
   /usr/src, mergemaster budet zaprashivat' vas na otrabotku `etoj
   situacii. YA rekomenduyu perenosit' izmeneniya. Esli vam nadoelo
   otvechat' na zaprosy, vy mozhete prosto obnovit' fajly v vashej
   rabotayuschej sisteme za raz (Esli tol'ko `eto vam podhodit.
   Skoree vsego, vam ne nuzhno `eto delat', esli odna iz vashih
   sistem rabotaet pod upravleniem -STABLE, a drugaya s -CURRENT.
   Izmeneniya mogut okazat'sya nesovmestimymi). Posleduyuschie vyzovy
   utility mergemaster obnaruzhat, chto RCS-identifikatory versij
   sootvetstvuyut tem, chto nahodyatsya v /usr/src, i propustyat
   fajl.

   Skript stage_1.sh ostanovitsya na pervoj komande, kotoraya
   zavershitsya neudachno (vozvratit nenulevoj kod zaversheniya)
   iz-za set -e, tak chto vy ne propustite oshibki. On takzhe
   ostanovitsya, esli vy ispol'zuete otmenu znacheniya peremennoj
   okruzheniya, kak pravilo, iz-za opechatki. Vy dolzhny ispravit'
   vse oshibki v vashej versii stage_1.conf.default pered tem, kak
   prodolzhit' rabotu.

   V skripte stage_1.sh my vyzyvaem mergemaster. Dazhe esli nikakim
   fajlam ob"edinenie ne trebuetsya, on vyvedet soobschenie i v konce
   sdelaet zapros

 *** Comparison complete

 Do you wish to delete what is left of /var/tmp/temproot.stage1? [no] no

   Pozhalujsta, otvet'te no ili prosto nazhmite Enter. Prichina v
   tom, chto mergemaster ostavit neskol'ko fajlov nulevoj dliny v
   kataloge /var/tmp/temproot.stage1, kotorye pozzhe budut
   skopirovany v novuyu sistemu (esli ih zdes' uzhe net).

   Posle `etogo budet vydan spisok ustanovlennyh fajlov pri pomoschi
   utility postranichnogo vyvoda, po umolchaniyu `eto more(1), mozhet
   byt' less(1):

 *** You chose the automatic install option for files that did not
     exist on your system.  The following were installed for you:
       /newroot/etc/defaults/rc.conf
       ...
       /newroot/COPYRIGHT

 (END)

   Nazhmite q dlya togo, chtoby prekratit' prosmotr. Zatem vy budete
   proinformirovany o login.conf:

 *** You installed a login.conf file, so make sure that you run
     '/usr/bin/cap_mkdb /newroot/etc/login.conf'
     to rebuild your login.conf database

     Would you like to run it now? y or n [n]

   Otvet ne imeet znacheniya, tak kak my budem zapuskat' cap_mkdb(1)
   v lyubom sluchae.

   Vot avtorskij fajl stage_1.conf.default, kotoryj vy dolzhny potom
   modificirovat'. V kommentariyah daiotsya dostatochno informacii o
   tom, chto neobhodimo izmenit'.

     Vnimanie: Pozhalujsta, obratite na komandy newfs(8). Hotya vy ne
     mozhete sozdavat' novye fajlovye sistemy na smontirovannyh
     razdelah, skript uspeshno udalit vse nesmontirovannye razdely
     /dev/da0s1a, /dev/da0s1e i /dev/da2s1e. `Etogo mozhet okazat'sya
     dostatochnym, chtoby isportit' vam den', tak chto podprav'te
     imena ustrojstv.

 # This file: stage_1.conf.default, sourced by stage_1.sh.
 #
 # $Id: stage_1.conf.default,v 1.2 2004/01/03 13:55:06 toor Exp toor $
 # $FreeBSD: doc/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_1.conf.default,v 1.4 2008/12/03 21:59:51 schweikh Exp $

 # Root mount point where you create the new system. Because it is only
 # used as a mount point, no space will be used on that file system as all
 # files are of course written to the mounted file system(s).
 DESTDIR="/newroot"

 # Where your src tree is.
 SRC="/usr/src"

 # Where your obj is.
 MAKEOBJDIRPREFIX="/usr/obj"

 # Your kernel config name as from make buildkernel KERNCONF=...
 KERNCONF="HAL9000"

 # Your target architecture as used for make buildworld TARGET=...
 # If you did not specify a TARGET when building world, it defaulted
 # to the build architecture (run "uname -m" to find out if you are unsure).
 TARGET="i386"  # amd64 arm i386 ia64 mips pc98 powerpc sparc64 sun4v

 # Available time zones are those under /usr/share/zoneinfo.
 TIMEZONE="Europe/Berlin"


 #
 # The create_file_systems function must create the mountpoints under
 # DESTDIR, create the file systems, and then mount them under DESTDIR.
 #
 create_file_systems () {
   # The new root file system. Mandatory.
   # Change DEVICE names.
   DEVICE=/dev/daXYZs1a
   mkdir -m 755 -p ${DESTDIR}
   chown root:wheel ${DESTDIR}
   newfs -U ${DEVICE}
   mount -o noatime ${DEVICE} ${DESTDIR}

   # Additional file systems and initial mount points. Optional.
   DEVICE=/dev/daXYZs1e
   mkdir -m 755 -p ${DESTDIR}/var
   chown root:wheel ${DESTDIR}/var
   newfs -U ${DEVICE}
   mount -o noatime ${DEVICE} ${DESTDIR}/var

   DEVICE=/dev/daXYZs1e
   mkdir -m 755 -p ${DESTDIR}/usr
   chown root:wheel ${DESTDIR}/usr
   newfs -U ${DEVICE}
   mount -o noatime ${DEVICE} ${DESTDIR}/usr
 }

 #
 # The create_etc_fstab function must create an fstab matching the
 # file systems created in create_file_systems.
 #
 create_etc_fstab () {
   cat <<EOF >${DESTDIR}/etc/fstab
 # Device         Mountpoint          FStype    Options              Dump Pass#
 /dev/da0s1b      none                swap      sw                   0    0
 /dev/da1s1b      none                swap      sw                   0    0
 /dev/da2s2b      none                swap      sw                   0    0
 /dev/da3s2b      none                swap      sw                   0    0
 /dev/da0s1a      /                   ufs       rw,noatime           1    1
 /dev/da0s1e      /var                ufs       rw,noatime           1    1
 /dev/da2s1e      /usr                ufs       rw,noatime           1    1
 /dev/vinum/Share /share              ufs       rw,noatime           0    2
 /dev/vinum/home  /home               ufs       rw,noatime           0    2
 /dev/vinum/ncvs  /home/ncvs          ufs       rw,noatime           0    2
 /dev/vinum/ports /usr/ports          ufs       rw,noatime           0    2
 /dev/ad1s1a      /flash              ufs       rw,noatime           0    0
 /dev/ad0s1       /2k                 ntfs      ro,noauto            0    0
 /dev/ad0s6       /linux              ext2fs    ro,noauto            0    0
 #
 /dev/cd0         /cdrom              cd9660    ro,noauto            0    0
 /dev/cd1         /dvd                cd9660    ro,noauto            0    0
 proc             /proc               procfs    rw                   0    0
 linproc          /compat/linux/proc  linprocfs rw                   0    0
 EOF
   chmod 644 ${DESTDIR}/etc/fstab
   chown root:wheel ${DESTDIR}/etc/fstab
 }

 #
 # The copy_files function is used to copy files before mergemaster is run.
 #
 copy_files () {
   # Add or remove from this list at your discretion. Mostly mandatory.
   for f in \
     /.profile \
     /etc/devd.conf \
     /etc/devd.rules \
     /etc/exports \
     /etc/group \
     /etc/hosts \
     /etc/inetd.conf \
     /etc/ipfw.conf \
     /etc/make.conf \
     /etc/master.passwd \
     /etc/nsswitch.conf \
     /etc/ntp.conf \
     /etc/printcap \
     /etc/profile \
     /etc/rc.conf \
     /etc/resolv.conf \
     /etc/src.conf \
     /etc/sysctl.conf \
     /etc/ttys \
     /etc/mail/aliases \
     /etc/mail/aliases.db \
     /etc/mail/hal9000.mc \
     /etc/mail/service.switch \
     /etc/ssh/*key* \
     /etc/ssh/*_config \
     /etc/X11/xorg.conf \
     /var/cron/tabs/* \
     /root/.profile \
     /boot/*.bmp \
     /boot/loader.conf \
     /boot/device.hints ; do
     cp -p ${f} ${DESTDIR}${f}
   done
 }

 #
 # Everything else you want to tune in the new system.
 # NOTE: Do not install too many binaries here. With the old system running and
 # the new binaries and headers installed you are likely to run into bootstrap
 # problems. Ports should be compiled after you have booted in the new system.
 #
 all_remaining_customization () {
   # Without the compat symlink the linux_base files end up on the root fs:
   cd ${DESTDIR}
   mkdir -m 755 usr/compat; chown root:wheel usr/compat; ln -s usr/compat
   mkdir -m 755 usr/compat/linux;      chown root:wheel usr/compat/linux
   mkdir -m 555 usr/compat/linux/proc; chown root:wheel usr/compat/linux/proc
   mkdir -m 755 boot/grub;             chown root:wheel boot/grub
   mkdir -m 755 linux 2k;              chown root:wheel linux 2k
   mkdir -m 755 src;                   chown root:wheel src
   mkdir -m 755 share;                 chown root:wheel share
   mkdir -m 755 dvd cdrom flash;       chown root:wheel dvd cdrom flash
   mkdir -m 755 home;                  chown root:wheel home
   mkdir -m 755 usr/ports;             chown root:wheel usr/ports

   # Create the ntp and slip log files.
   touch ${DESTDIR}/var/log/ntp ${DESTDIR}/var/log/slip.log

   # Make /usr/src point to the right directory. Optional.
   # Note: some ports need part of the src tree, e.g. emulators/kqemu,
   # sysutils/lsof, sysutils/fusefs, ...
   cd ${DESTDIR}/usr
   if test "${SRC}" != /usr/src; then
     rmdir src; ln -s ${SRC}
   fi
   if test "${MAKEOBJDIRPREFIX}" != /usr/obj; then
     rmdir obj; ln -s ${MAKEOBJDIRPREFIX}
   fi

   # My personal preference is to symlink tmp -> var/tmp. Optional.
   cd ${DESTDIR}; rmdir tmp; ln -s var/tmp

   # Make spooldirs for the printers in my /etc/printcap.
   cd ${DESTDIR}/var/spool/output/lpd; mkdir -p as od ev te lp da
   touch ${DESTDIR}/var/log/lpd-errs

   # If you do not have /home on a shared partition, you may want to copy it:
   # mkdir -p ${DESTDIR}/home
   # cd /home; tar cf - . | (cd ${DESTDIR}/home; tar xpvf -)
 }

 # vim: tabstop=2:expandtab:shiftwidth=2:syntax=sh:
 # EOF $RCSfile: stage_1.conf.default,v $

   Sgruzite stage_1.conf.default.

   Pri rabote `etot skript ustanavlivaet sistemu, kotoraya pri
   zagruzke imeet:

     * Unasledovannye spiski pol'zovatelej i grupp.

     * Podklyuchenie k Internet po Ethernet i PPP s ispol'zovaniem
       mezhsetevogo `ekrana.

     * Pravil'nyj vremennoj poyas i NTP.

     * Drugie bolee melkie konfiguracionnye parametry, naprimer,
       /etc/ttys i inetd.

   Drugie funkcii gotovy k nastrojke, no ne budut rabotat', poka ne
   budet zavershion vtoroj `etap. Naprimer, my skopirovali fajly dlya
   nastrojki pechati i X11. Odnako dlya pechati, skoree vsego,
   neobhodimy prilozheniya, otsutstvuyuschie v bazovom komplekte
   sistemy. X11 ne budet rabotat', poka my ne otkompiliruem server,
   biblioteki i programmy.

     --------------------------------------------------------------

5. `Etap vtoroj: Ustanovka portov

     Zamechanie: Na `etom `etape vmesto kompilyacii portov vozmozhna
     takzhe ustanovka (uzhe otkompilirovannyh) pakadzhej. V `etom
     sluchae stage_2.sh budet predstavlyat' soboj ne bolee, chem
     perechen' komand pkg_add. YA nadeyus', chto vy sumeete napisat'
     takoj skript. Zdes' my sosredotochimsya na bolee gibkom i
     tradicionnom sposobe s ispol'zovaniem portov.

   Sleduyuschij skript stage_2.sh pokazyvaet, kak ya ustanavlivayu
   moi lyubimye porty. On mozhet byt' zapuschen lyuboe kolichestvo
   raz i budet propuskat' vse porty, kotorye uzhe ustanovleny. On
   podderzhivaet dryrun-parametr (-n) dlya tol'ko pokaza togo, chto
   budet vypolneno. Vy zapuskaete ego tochno takzhe, kak stage_1.sh,
   s tol'ko odnim argumentom, ukazyvayuschim na konfiguracionnyj
   fajl, k primeru

 # ./stage_2.sh default

   kotoryj budet schityvat' perechen' portov iz stage_2.conf.default.

   Spisok portov sostoit iz strochek s dvumya ili bol'shim
   kolichestvom slov, razdelionnyh probelami: kategoriya i port, za
   kotorymi opcional'no sleduet komanda ustanovki, kotoraya budet
   kompilirovat' i ustanavlivat' port (po umolchaniyu: make install
   BATCH=yes < /dev/null). Pustye stroki i stroki, nachinayuschiesya
   s simvola #, ignoriruyutsya. V bol'shinstve sluchaev v nih
   ukazyvaetsya tol'ko nazvanie kategorii i port. Odnako nekotorye
   porty mogut byt' tonko nastroeny pri pomoschi ukazaniya
   make-peremennyh, k primeru:

 www mozilla make WITHOUT_MAILNEWS=yes WITHOUT_CHATZILLA=yes install

   Na samom dele vy mozhete ukazat' nekotorye komandy obolochki, tak
   chto ne ogranicheny prostymi vyzovami make:

 java linux-sun-jdk13 yes | make install
 news inn-stable CONFIGURE_ARGS="--enable-uucp-rnews --enable-setgid-inews" make install

   Zamet'te, chto stroka dlya news/inn-stable yavlyaetsya primerom
   odnovremenno zadaniya peremennoj obolochki CONFIGURE_ARGS. Fajl
   Makefile porta budet ispol'zovat' `eto kak nachal'noe znachenie i
   opredelit nekotorye drugie neobhodimye argumenty. Raznica v
   zadanii make-peremennyh v komandnoj stroke po komande

 news inn-stable make CONFIGURE_ARGS="--enable-uucp-rnews --enable-setgid-inews" install

   zaklyuchaetsya v tom, chto v poslednem sluchae znachenie budet
   perenaznacheno, no ne rasshireno. Vybor nuzhnogo metoda zavisit ot
   konkretnogo porta.

   Ubedites' v tom, chto vashi porty ne ispol'zuyut interaktivnyj
   rezhim ustanovki, to est' ne dolzhny pytat'sya chitat' so
   standartnogo ustrojstva vvoda nichego krome togo, chto vy im
   podaiote na vhod. Esli `eto vsio zhe proishodit, to oni budut
   schityvat' posleduyuschie stroki iz vashego perechnya portov,
   opisyvaemogo v `etom dokumente, i budut rabotat' nekorrektno. Esli
   skript stage_2.sh neozhidanno propustil port ili prekratil rabotu,
   prichina mozhet byt' v `etom.

   Nizhe privoditsya stage_2.conf.default. Dlya kazhdogo
   ustanovlennogo im porta sozdaiotsya fajl protokola
   LOGDIR/category+port.

 # vim: syntax=sh
 # $Id: stage_2.conf.default,v 1.2 2004/03/06 12:50:30 toor Exp toor $
 # $FreeBSD: doc/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_2.conf.default,v 1.4 2008/12/03 21:59:51 schweikh Exp $
 ports-mgmt portaudit
 devel ccache
 shells zsh
 devel gettext
 archivers unzip
 archivers zip
 security sudo
 x11 xorg
 x11-servers xorg-server
 x11-fonts xorg-fonts-100dpi
 x11-fonts xorg-fonts-75dpi
 x11-fonts xorg-fonts-miscbitmaps
 x11-fonts xorg-fonts-truetype
 x11-fonts xorg-fonts-type1
 x11-fonts gnu-unifont make install && mkfontdir /usr/local/lib/X11/fonts/local
 x11-fonts urwfonts
 x11-fonts webfonts
 x11-toolkits open-motif
 x11-wm ctwm
 x11 wdm
 security openssh-askpass
 astro xplanet
 astro xephem
 editors vim
 print ghostscript8
 print psutils-a4
 print a2ps-a4
 print gv
 print transfig
 print teTeX
 print cups-base
 emulators linux_base-fc6
 print acroread8 yes accept | make install PAGER=ls
 java jdk16 echo true > files/license.sh; make install BATCH=yes < /dev/null
 www apache22
 www amaya
 www firefox3
 www checkbot
 www p5-HTML-Parser
 www validator
 www mplayer-plugin
 math p5-Math-Combinatorics
 math p5-Bit-Vector
 graphics evince
 graphics xfig
 graphics xv
 graphics gphoto2
 multimedia xawtv
 lang expect
 lang gawk
 lang python
 news tin
 net freebsd-uucp
 net cvsup-without-gui
 net rsync
 ftp wget
 textproc ispell
 german ispell-neu
 german ispell-alt
 textproc docproj
 sysutils samefile
 sysutils smartmontools
 sysutils pstree
 sysutils cdrtools
 sysutils dvd+rw-tools
 sysutils grub
 sysutils lsof
 devel subversion-freebsd
 devel bcc
 devel ddd
 devel gindent
 devel ctags
 devel ElectricFence
 devel strace
 devel perltidy
 mail procmail
 mail metamail
 mail mutt-devel
 ports-mgmt portupgrade
 news inn CONFIGURE_ARGS="--enable-uucp-rnews --enable-setgid-inews" make BATCH=yes install < /dev/null
 misc figlet-fonts
 security gpa
 mail spamoracle
 textproc rman
 multimedia mplayer
 multimedia mplayer-fonts
 multimedia acidrip
 multimedia ogle
 multimedia ogle-gui
 audio pacpl
 audio p5-CDDB_get
 audio cowbell
 shells bash
 editors openoffice.org-3-RC
 java eclipse
 java netbeans

   Sgruzite stage_2.conf.default.

     --------------------------------------------------------------

6. `Etap tretij

   Na vtorom `etape vy ustanovili vashi lyubimye porty. Nekotorye ih
   nih trebuyut nekotoroj nastrojki. Imenno dlya `etogo i
   prednaznachen tretij `etap, nastrojki. YA mog by integrirovat'
   `etu nastrojku v konec skripta stage_2.sh. Odnako ya dumayu, chto
   est' konceptual'noe razlichie mezhdu ustanovkoj porta i
   modifikaciej ego nachal'noj konfiguracii, i `eto trebuet
   otdel'nogo shaga.

   YA reshil realizovat' tretij `etap v vide fajla Makefile, potomu
   chto `eto pozvolyaet legko vybirat' to, chto vy hotite
   konfigurirovat', sleduyuschim prostym vyzovom:

 # make -f stage_3.mk target

   Kak i v sluchae s stage_2.sh, ubedites', chto fajl stage_3.mk
   posle zagruzki novoj sistemy est' v nalichii, pomestiv ego na
   sovmestno ispol'zuemyj razdel libo skopirovav ego kuda-nibud' v
   novuyu sistemu.

     --------------------------------------------------------------

7. Ogranicheniya

   Avtomatizirovannaya ustanovka porta mozhet okazat'sya zatrudnena,
   esli on yavlyaetsya interaktivnym i ne podderzhivaet komandu make
   BATCH=YES install. Dlya neskol'kih portov interaktivnost'
   oznachaet ne bolee, chem vvod yes v otvet na vopros o prinyatii
   nekotorogo licenzionnogo soglasheniya. Esli takoj vvod
   schityvaetsya so standartnogo ustrojstva vvoda, my prosto
   napravlyaem sootvetstvuyuschie otvety na vhod ustanovochnoj
   komandy (obychno make install; imenno tak ya rabotal s
   java/linux-sun-jdk14 v stage_2.conf.default).

   Takoj podhod, naprimer, ne rabotaet s editors/staroffice52,
   kotoryj trebuet raboty X11. Procedura ustanovki vklyuchaet
   dostatochno bol'shoe kolichestvo nazhatij myshi i nabor, tak chto
   ona ne mozhet byt' avtomatizirovana tak, kak drugie porty. Odnako
   dlya menya srabotal sleduyuschij tryuk: snachala ya sozdal pakadzh
   staroffice na staroj sisteme pri pomoschi komandy

 # cd /usr/ports/editors/staroffice52
 # make package
 ===>  Building package for staroffice-5.2_1
 Creating package /usr/ports/editors/staroffice52/staroffice-5.2_1.tbz
 Registering depends:.
 Creating bzip'd tar ball in '/usr/ports/editors/staroffice52/staroffice-5.2_1.tbz'

   i na vtorom `etape ya prosto ispol'zoval sleduyuschee:

 # pkg_add /usr/ports/editors/staroffice52/staroffice-5.2_1.tbz

   Vy dolzhny takzhe prinyat' vo vnimanie voprosy obnovleniya
   konfiguracionnyh fajlov. Voobsche govorya, vy ne znaete, kogda i
   smenilsya li voobsche format ili soderzhimoe konfiguracionnogo
   fajla. V fajl /etc/group mozhet byt' dobavlena novaya gruppa, ili
   v /etc/passwd mozhet dobavit'sya dopolnitel'noe pole. Vsio `eto
   uzhe proishodilo v proshlom. Prostoe kopirovanie konfiguracionnogo
   fajla iz staroj v novuyu sistemu mozhet v bol'shinstve sluchaev
   okazat'sya dostatochnym, no v `etih sluchayah `eto ne tak. Esli vy
   obnovlyaete sistemu kanonicheskim sposobom (putiom
   perezapisyvaniya staryh fajlov), vy dolzhny ispol'zovat' utilitu
   mergemaster dlya raboty s izmeneniyami, esli vy hotite `effektivno
   ob"edinit' vashu lokal'nye nastrojki s potencial'no novymi
   vozmozhnostyami. K sozhaleniyu, mergemaster rabotaet tol'ko s
   fajlami bazovogo komplekta sistemy, a ne s lyubymi fajlami,
   ustanavlivaemymi portami. Pohozhe, chto storonnee programmnoe
   obespechenie special'no proektiruetsya dlya togo, chtoby ya ne
   dremal, i menyaet konfiguracionnye fajly po dva raza v mesyac.
   Dlya obnaruzheniya takih skrytyh izmenenij, ya derzhu kopiyu
   izmenionnyh konfiguracionnyh fajlov tam zhe, gde i stage_3.mk i
   sravnivayu rezul'tat s pomosch'yu pravil make. Naprimer, dlya
   konfiguracionnogo fajla apacha, httpd.conf cel'yu budet
   config_apache.

 @if ! cmp -s /usr/local/etc/apache2/httpd.conf httpd.conf; then \
     echo "ATTENTION: the httpd.conf has changed. Please examine if"; \
     echo "the modifications are still correct. Here is the diff:"; \
     diff -u /usr/local/etc/apache2/httpd.conf httpd.conf; \
 fi

   Esli raznica mezhdu fajlami nesuschestvenna ya mogu vypolnit' cp
   /usr/local/etc/apache2/httpd.conf httpd.conf.

   YA ispol'zoval sistemu FreeBSD From Scratch neskol'ko raz dlya
   obnovleniya 5-CURRENT do 5-CURRENT, to est' ya nikogda ne pytalsya
   ustanovit' 5-CURRENT iz sistemy 4-STABLE i naoborot. Iz-za
   kolichestva izmenenij mezhdu relizami s raznymi starshimi nomerami
   ya ozhidayu, chto `etot process budet neskol'ko bolee slozhnym.
   Ispol'zovanie FreeBSD From Scratch dlya obnovleniya vnutri
   4-STABLE dolzhno prohodit' bezboleznenno (hotya ya eschio `etogo
   ne proboval delat'.) Pol'zovateli vetki 4-STABLE mogut imet' v
   vidu sleduyuschee:

     Zamechanie: Esli vy ne ispol'zuete fajlovuyu sistemu ustrojstv,
     devfs(5), to mozhete sozdat' ustrojstva dlya nekotorogo vashego
     oborudovaniya komandoj MAKEDEV(8) v processe
     all_remaining_customization.

     --------------------------------------------------------------

8. Fajly

   Vot tri fajla, kotorye vam nuzhny krome teh konfiguracionnyh, chto
   uzhe pokazany vyshe.

   `Eto skript stage_1.sh, kotoryj vy ne dolzhny modificirovat'.

 #!/bin/sh
 #
 # stage_1.sh - FreeBSD From Scratch, Stage 1: System Installation.
 #              Usage: ./stage_1.sh profile
 #              will read profile
 #              and write ./stage_1.log.profile
 #
 # Author:      Jens Schweikhardt
 # $Id: stage_1.sh,v 1.7 2004/01/03 13:50:41 toor Exp toor $
 # $FreeBSD: doc/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_1.sh,v 1.7 2008/12/11 19:48:21 schweikh Exp $

 PATH=/bin:/usr/bin:/sbin:/usr/sbin

 # Prerequisites:
 #
 # a) Successfully completed "make buildworld" and "make buildkernel"
 # b) Unused partitions (at least one for the root fs, probably more for
 #    the new /usr and /var, to your liking.)
 # c) A customized profile file.

 if test $# -ne 1; then
   echo "usage: stage_1.sh profile" 1>&2
   exit 1
 fi

 # ---------------------------------------------------------------------------- #
 # Step 1: Create an empty directory tree below $DESTDIR.
 # ---------------------------------------------------------------------------- #

 step_one () {
   create_file_systems
   # Now create all the other directories. Mandatory.
   cd ${SRC}/etc; make distrib-dirs DESTDIR=${DESTDIR} TARGET=${TARGET}
 }

 # ---------------------------------------------------------------------------- #
 # Step 2: Fill the empty /etc directory tree and put a few files in /.
 # ---------------------------------------------------------------------------- #

 step_two () {
   copy_files

   # Delete mergemaster's temproot, if any.
   TEMPROOT=/var/tmp/temproot.stage1
   if test -d ${TEMPROOT}; then
     chflags -R 0 ${TEMPROOT}
     rm -rf ${TEMPROOT}
   fi
   export MAKEDEVPATH="/bin:/sbin:/usr/bin"
   mergemaster -i -m ${SRC}/etc -t ${TEMPROOT} -D ${DESTDIR}
   cap_mkdb ${DESTDIR}/etc/login.conf
   pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd

   # Mergemaster does not create empty files, e.g. in /var/log. Do so now,
   # but do not clobber files that may have been copied with copy_files.
   cd ${TEMPROOT}
   find . -type f | sed 's,^\./,,' |
   while read f; do
     if test -r ${DESTDIR}/${f}; then
       echo "${DESTDIR}/${f} already exists; not copied"
     else
       echo "Creating empty ${DESTDIR}/${f}"
       cp -p ${f} ${DESTDIR}/${f}
     fi
   done
   chflags -R 0 ${TEMPROOT}
   rm -rf ${TEMPROOT}
 }

 # ---------------------------------------------------------------------------- #
 # Step 3: Install world.
 # ---------------------------------------------------------------------------- #

 step_three () {
   cd ${SRC}
   make installworld DESTDIR=${DESTDIR} TARGET=${TARGET}
 }

 # ---------------------------------------------------------------------------- #
 # Step 4: Install kernel and modules.
 # ---------------------------------------------------------------------------- #

 step_four () {
   cd ${SRC}
   # The loader.conf and device.hints are required by the installkernel target.
   # If you have not copied them in Step 2, cp them as shown in the next 2 lines.
   #   cp sys/boot/forth/loader.conf ${DESTDIR}/boot/defaults
   #   cp sys/${TARGET}/conf/GENERIC.hints ${DESTDIR}/boot/device.hints
   make installkernel DESTDIR=${DESTDIR} KERNCONF=${KERNCONF} TARGET=${TARGET}
 }

 # ---------------------------------------------------------------------------- #
 # Step 5: Install /etc/fstab and time zone info.
 # ---------------------------------------------------------------------------- #

 step_five () {
   create_etc_fstab

   # Setup time zone info; pretty much mandatory.
   cp ${DESTDIR}/usr/share/zoneinfo/${TIMEZONE} ${DESTDIR}/etc/localtime
   if test -r /etc/wall_cmos_clock; then
     cp -p /etc/wall_cmos_clock ${DESTDIR}/etc/wall_cmos_clock
   fi
 }

 # ---------------------------------------------------------------------------- #
 # Step 6: All remaining customization.
 # ---------------------------------------------------------------------------- #

 step_six () {
   all_remaining_customization
 }

 do_steps () {
   echo "PROFILE=${PROFILE}"
   echo "TARGET=${TARGET}"
   echo "DESTDIR=${DESTDIR}"
   echo "SRC=${SRC}"
   echo "KERNCONF=${KERNCONF}"
   echo "TIMEZONE=${TIMEZONE}"
   echo "TYPE=${TYPE}"
   echo "REVISION=${REVISION}"
   echo "BRANCH=${BRANCH}"
   echo "RELDATE=${RELDATE}"
   step_one
   step_two
   step_three
   step_four
   step_five
   step_six
 }

 # ---------------------------------------------------------------------------- #
 # The ball starts rolling here.
 # ---------------------------------------------------------------------------- #

 PROFILE="$1"
 set -x -e -u # Stop for any error or use of an undefined variable.
 . ${PROFILE}

 # Determine a few variables from the sources that were used to make the
 # world. The variables can be used to modify actions, e.g. depending on
 # the system's version. The __FreeBSD_version numbers
 # for RELDATE are documented in the Porter's Handbook,
 # doc/en_US.ISO8859-1/books/porters-handbook/freebsd-versions.html.
 # Scheme is:  <major><two digit minor><0 if release branch, otherwise 1>xx
 # The result will be something like
 #
 #   TYPE="FreeBSD"
 #   REVISION="8.0"
 #   BRANCH="RC"      { "CURRENT", "STABLE", "RELEASE" }
 #   RELDATE="800028"
 #
 eval $(awk '/^(TYPE|REVISION|BRANCH)=/' ${SRC}/sys/conf/newvers.sh)
 RELDATE=$(awk '/^[ \t]*#[ \t]*define[ \t][ \t]*__FreeBSD_version[ \t]/ {
                 print $3
               }' ${SRC}/sys/sys/param.h)

 echo "=> Logging to stage_1.${PROFILE}.log"
 do_steps 2>&1 | tee "stage_1.${PROFILE}.log"

 # vim: tabstop=2:expandtab:shiftwidth=2:
 # EOF $RCSfile: stage_1.sh,v $

   Sgruzite stage_1.sh.

   `Eto skript stage_2.sh. Vam mozhet ponadobit'sya izmenit'
   peremennye v samom nachale fajla.

 #!/bin/sh
 #
 # stage_2.sh - FreeBSD From Scratch, Stage 2: Ports Installation.
 #              Usage: ./stage_2.sh [-hnp] configname
 #
 # Author:      Jens Schweikhardt
 # $Id: stage_2.sh,v 1.5 2004/01/23 22:09:19 toor Exp toor $
 # $FreeBSD: doc/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_2.sh,v 1.5 2004/07/19 21:02:26 schweikh Exp $

 DBDIR="/var/db/pkg"
 PORTS="/usr/ports"
 : ${PACKAGES:=${PORTS}/packages}
 LOGDIR="/home/root/setup/ports.log"; mkdir -p ${LOGDIR}
 PKG_PATH="/cdrom/packages/All:/dvd/packages/All"
 PKG=

 MYNAME="$(basename $0)"
 usage () {
         exec >&2
         echo "usage: ${MYNAME} [-hnp] configname"
         echo ""
         echo "  Options:"
         echo "  -h    Print this help text."
         echo "  -n    Dryrun: just show what would be done."
         echo "  -p    Install a precompiled package if one can be found."
         echo ""
         echo "  The config file (stage_2.conf.configname) is a list of"
         echo "  ports to install with one entry per line. Each line"
         echo "  consists of two or three space separated fields:"
         echo "  category, port, and optionally a build command."
         echo ""
         exit 1
 }

 # Look for a package in these locations in sequence.
 # Returns as soon as the first is found. Result on stdout.
 #
 #   ${PORTS}/${CATEGORY}/${NAME}
 #   ${PACKAGES}/All
 #   ${PACKAGES}/${CATEGORY}
 #   ${PKG_PATH}
 #
 find_package () {
         echo "${PORTS}/${CATEGORY}/${NAME}:${PACKAGES}/All:${PACKAGES}/${CATEGORY}:${PKG_PATH}" |
         tr : '\n' |
         while read d; do
                 test -d "${d}" || continue
                 PKG=$(ls ${d}/${PKGNAME}.* 2>/dev/null)
                 test $? -eq 0 && echo "${PKG}" && return
         done
 }

 #
 # Parse command line arguments.
 #
 args=`getopt hnp $*`
 if test $? != 0; then
         usage
 fi
 set -- $args
 DRYRUN=
 CHKPKG=
 for i; do
         case "$i" in
         -n) DRYRUN="yes"; shift;;
         -p) CHKPKG="yes"; shift;;
         --) shift; break;;
         *) usage;;
         esac
 done
 if test $# -eq 1; then
         DATAFILE="$1"
 else
         usage
 fi

 #
 # Loop over the ports list.
 #
 while read CATEGORY NAME CMD; do
         case "${CATEGORY}" in
         \#*) continue;;
         '') continue;;
         esac
         DIR="${PORTS}/${CATEGORY}/${NAME}"
         if ! test -d "${DIR}"; then
                 echo "$DIR does not exist -- ignored"
                 continue
         fi
         cd ${DIR}
         PKGNAME=`make -V PKGNAME`
         if test -n "${CHKPKG}"; then
                 PKG=$(find_package)
         else
                 PKG=""
         fi
         if test -d "${DBDIR}/${PKGNAME}"; then
                 echo "${CATEGORY}/${NAME} already installed as ${PKGNAME}"
                 continue
         fi
         LOG="${LOGDIR}/${CATEGORY}+${NAME}"
         echo "===> Installing ${CATEGORY}/${NAME}; logging to ${LOG}"
         test -n "${CMD}" || CMD="make install BATCH=yes < /dev/null"
         if test -n "${DRYRUN}"; then
                 if test -n "${PKG}"; then
                         echo pkg_add -v ${PKG}
                 else
                         echo "${CMD}"
                 fi
                 continue
         fi
         date "++++ Started %v %T +++" > ${LOG}
         STARTED=$(date +%s)
         (
                 if test -n "${PKG}"; then
                         echo "Found package ${PKG}"
                         pkg_add -v ${PKG}
                 else
                         echo "CMD: ${CMD}"
                         make clean
                         eval "${CMD}"
                         make clean # Uncomment if diskspace is tight under ${PORTS}.
                 fi
         ) 2>&1 | tee -a ${LOG}
         FINISHED=$(date +%s)
         DURATION=$(dc -e "${FINISHED} ${STARTED} - p")
         date "++++ Finished %v %T after ${DURATION} secs +++" >> ${LOG}
 done < stage_2.conf.${DATAFILE}

 # vim: tabstop=4:
 # EOF $RCSfile: stage_2.sh,v $

   Sgruzite stage_2.sh.

   `Eto moj fajl stage_3.mk, kotoryj dast vam ideyu o tom, kak
   avtomatizirovat' vsyu povtornuyu konfiguraciyu.

 # stage_3.mk - FreeBSD From Scratch, Stage 3: Ports Post-Configuration.
 #              Usage: make -f stage_3.mk all     (configure everything)
 #                or   make -f stage_3.mk target  (just configure target)
 #
 # Author:      Jens Schweikhardt
 #
 # It is a good idea to make sure any target can be made more than
 # once without ill effect.
 #
 # $Id: stage_3.mk,v 1.8 2004/03/27 16:53:11 toor Exp toor $
 # $FreeBSD: doc/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_3.mk,v 1.5 2008/12/03 21:59:51 schweikh Exp $

 .POSIX:

 message:
         @echo "Please use one of the following targets:"
         @echo "config_apache"
         @echo "config_cups"
         @echo "config_firefox"
         @echo "config_inn"
         @echo "config_javaplugin"
         @echo "config_openoffice"
         @echo "config_sudo"
         @echo "config_TeX"
         @echo "config_tin"
         @echo "config_wdm"
         @echo "config_uucp"
         @echo "all -- all of the above"

 all: \
         config_apache \
         config_cups \
         config_firefox \
         config_inn \
         config_javaplugin \
         config_openoffice \
         config_sudo \
         config_TeX \
         config_tin \
         config_wdm \
         config_uucp

 APACHE = apache22
 config_apache:
         # 1. Modify httpd.conf.
         perl -pi \
         -e 's/^\s*ServerAdmin.*/ServerAdmin schweikh\@schweikhardt.net/;' \
         -e 's/^#?ServerName .*/ServerName hal9000.schweikhardt.net:80/;' \
         -e 's/^\s*Listen.*/Listen 127.0.0.1:80/;' \
         -e 's/^\s*Deny from all/    Allow from 127.0.0.1/i;' \
         -e 's,/usr/local/www/$(APACHE)/cgi-bin/,/home/opt/www/cgi-bin/,;' \
           /usr/local/etc/$(APACHE)/httpd.conf
         cp w3c-validator.conf /usr/local/etc/$(APACHE)/Includes
         # 2. Restore symlinks to web pages.
         cd /usr/local/www/$(APACHE)/data && \
         ln -fs /home/schweikh/prj/homepage schweikhardt.net && \
         ln -fs /home/opt/www/test .
         # 3. Restore W3C Validator config.
         mkdir -p /etc/w3c
         cp /usr/local/www/validator/htdocs/config/validator.conf.sample \
                 /etc/w3c/validator.conf
         perl -pi \
         -e 's/^Allow Private IPs.*/Allow Private IPs = yes/;' \
                 /etc/w3c/validator.conf
         # Test if the httpd.conf has changed.
         @if ! cmp -s /usr/local/etc/$(APACHE)/httpd.conf httpd.conf; then \
                 echo "ATTENTION: the httpd.conf has changed. Please examine if"; \
                 echo "the modifications are still correct. If so you can simply"; \
                 echo "cp /usr/local/etc/$(APACHE)/httpd.conf httpd.conf"; \
                 echo "to make this message go away. Here is the diff:"; \
                 diff -u /usr/local/etc/$(APACHE)/httpd.conf httpd.conf; \
         fi
         if test -f /var/run/httpd.pid; then \
                 /usr/local/etc/rc.d/$(APACHE) stop; \
                 /usr/local/etc/rc.d/$(APACHE) start; \
         else \
                 /usr/local/etc/rc.d/$(APACHE) start; \
         fi

 # The original ppd file is from http://www.cups.org/ppd.php?L63+I0+T+Q2300
 # = http://www.cups.org/ppd/hp/de/hpc2325s.ppd.gz
 config_cups:
         chmod 644 /usr/local/etc/cups/cupsd.conf
         cp printers.conf /usr/local/etc/cups/printers.conf
         cp LaserJet_2300d.ppd /usr/local/etc/cups/ppd/LaserJet_2300d.ppd

 config_firefox:
         # Make this group wheel writable to allow extensions being installed.
         chmod -R g+w /usr/local/lib/firefox3/chrome

 config_inn:
         pw usermod -n news -d /usr/local/news -s /bin/sh
         mkdir -p /share/news/spool/outgoing \
                  /share/news/spool/incoming \
                  /share/news/spool/articles \
                  /share/news/spool/overview \
                  /share/news/spool/tmp      \
                  /share/news/db
         chown -R news:news /share/news
         # Give the news system its initial configuration.
         cd /home/root/setup && \
         if test ! -f /share/news/db/active; then \
                 echo "installing /share/news/db/active"; \
                 install -C -o news -g news -m 664 active /share/news/db; \
         fi; \
         if test ! -f /share/news/db/newsgroups; then \
                 echo "installing /share/news/db/newsgroups"; \
                 install -C -o news -g news -m 664 newsgroups /share/news/db; \
         fi
         # Configure storage method.
         cd /home/root/setup &&    \
         printf "%s\n%s\n%s\n%s\n" \
                 "method tradspool {"  \
                 "  newsgroups: *"     \
                 "  class: 0"          \
                 "}"                   \
         >storage.conf &&          \
         install -C -o news -g news -m 664 storage.conf /usr/local/news/etc
         # Configure newsfeeds.
         printf "%s\n%s\n" \
                 "ME:*::"      \
                 "shuttle/news2.shuttle.de:!junk,!control:B32768/512,Tf,Wfb:" \
         >/usr/local/news/etc/newsfeeds
         # Configure inn.conf.
         perl -pi                                                        \
         -e 's/^#*\s*(organization:\s*).*/$$1"An Open Pod Bay Door"/;'   \
         -e 's/^#*\s*(pathhost:\s*).*/$$1hal9000.schweikhardt.net/;'     \
         -e 's/^#*\s*(server:).*/$$1 localhost/;'                        \
         -e 's/^#*\s*(domain:).*/$$1 schweikhardt.net/;'                 \
         -e 's/^#*\s*(fromhost:).*/$$1 schweikhardt.net/;'               \
         -e 's,^#*\s*(moderatormailer:).*,$$1 \%s\@moderators.isc.org,;' \
         -e 's,^#*\s*(pathdb:\s*).*,$$1/share/news/db,;'                 \
         -e 's,/usr/local/news/spool,/share/news/spool,;'                \
         /usr/local/news/etc/inn.conf
         # Create empty history, if none there.
         # See post-install in /usr/ports/news/inn-stable/Makefile.
         set -e; cd /share/news/db; \
         if test ! -f history; then \
                 touch history; \
                 chmod 644 history; \
                 chown news:news history; \
                 su -fm news -c "/usr/local/news/bin/makedbz -i"; \
                 for s in dir hash index; do \
                         mv history.n.$${s} history.$${s}; \
                 done; \
         fi
         # Configure send-uucp.
         echo shuttle:shuttle >/usr/local/news/etc/send-uucp.cf
         # Satisfy inncheck:
         set -e; cd /usr/local/news/etc; \
         chown news:news *; \
         chmod 640 control.ctl expire.ctl nntpsend.ctl readers.conf
         /usr/local/news/bin/inncheck
         # Test if the inn.conf has changed.
         @if ! cmp -s /usr/local/news/etc/inn.conf inn.conf; then \
                 echo "ATTENTION: the inn.conf has changed. Please examine if"; \
                 echo "the modifications are still correct. If so you can simply"; \
                 echo "cp /usr/local/news/etc/inn.conf inn.conf"; \
                 echo "to make this message go away. Here is the diff:"; \
                 diff -u /usr/local/news/etc/inn.conf inn.conf; \
         fi
         if ! test -f /usr/local/news/run/innd.pid; then \
                 /usr/local/etc/rc.d/innd start; \
         fi

 config_javaplugin:
         cd /usr/local/lib/firefox3/plugins && \
           ln -fs /usr/local/jdk1.6.0/jre/plugin/$$(uname -m)/ns7/libjavaplugin_oji.so

 config_openoffice:
         # Copy some truetype files so ooo can use them.
         find /usr/local/openoffice.org* -type d -name truetype \
                 -exec echo cp *.ttf {} \; -exec cp *.ttf {} \;

 config_sudo:
         if ! grep -q schweikh /usr/local/etc/sudoers; then \
                 echo 'schweikh ALL = (ALL) NOPASSWD: ALL' >> /usr/local/etc/sudoers; \
         fi
         chmod 440 /usr/local/etc/sudoers

 config_TeX:
         # textproc/docproj advises: to typeset the FreeBSD Handbook with JadeTeX,
         # change the following settings to the listed values:
         perl -pi                                      \
         -e 's/^% original texmf.cnf/% texmf.cnf/;'    \
         -e 's/^(hash_extra\s*=\s*).*/$${1}60000/;'    \
         -e 's/^(pool_size\s*=\s*).*/$${1}1000000/;'   \
         -e 's/^(max_strings\s*=\s*).*/$${1}70000/;'   \
         -e 's/^(save_size\s*=\s*).*/$${1}10000/;'     \
         /usr/local/share/texmf/web2c/texmf.cnf
         # Test if the texmf.cnf has changed.
         @if ! cmp -s /usr/local/share/texmf/web2c/texmf.cnf texmf.cnf; then \
                 echo "ATTENTION: the texmf.cnf has changed. Please examine if"; \
                 echo "the modifications are still correct. If so you can simply"; \
                 echo "cp /usr/local/share/texmf/web2c/texmf.cnf texmf.cnf"; \
                 echo "to make this message go away. Here is the diff:"; \
                 diff -u /usr/local/share/texmf/web2c/texmf.cnf texmf.cnf; \
         fi

 config_tin:
         # Point tin to our files.
         printf "%s\n%s\n%s\n"                          \
                 "activefile=/share/news/db/active"         \
                 "newsgroupsfile=/share/news/db/newsgroups" \
                 "spooldir=/share/news/spool/articles"      \
         >/usr/local/etc/tin.defaults

 config_wdm:
         cp daemon1-JS-1600x1200.jpg FreeBSD_small.png \
                 /usr/local/lib/X11/wdm/pixmaps
         perl -pi \
         -e 's,^(DisplayManager\*wdmBg:).*,\1 pixmap:/usr/local/lib/X11/wdm/pixmaps/daemon1-JS-1600x1200.jpg,;' \
         -e 's,^(DisplayManager\*wdmLogo:).*,\1 /usr/local/lib/X11/wdm/pixmaps/FreeBSD_small.png,;' \
         -e 's,^(DisplayManager\*wdmWm:).*,\1 ctwm:icewm:xfce4:tvtwm,;' \
                 /usr/local/lib/X11/wdm/wdm-config
         @if ! cmp -s /usr/local/lib/X11/wdm/wdm-config wdm-config; then \
                 echo "ATTENTION: the wdm-config has changed. Please examine if"; \
                 echo "the modifications are still correct. If so you can simply"; \
                 echo "cp /usr/local/lib/X11/wdm/wdm-config wdm-config"; \
                 echo "to make this message go away. Here is the diff:"; \
                 diff -u /usr/local/lib/X11/wdm/wdm-config wdm-config; \
         fi

 config_uucp:
         cd /etc/mail && make install SENDMAIL_MC=/etc/mail/hal9000.mc
         # Make the uucp user's shell the correct uucico, so su(1) works.
         chpass -s /usr/local/libexec/uucp/uucico uucp
         # UUCP expects to find /usr/bin/rnews.
         cd /usr/bin && ln -fs ../local/news/bin/rnews .
         # Actual UUCP configuration.
         echo nodename js2015           > /usr/local/etc/uucp/config
         echo shuttle js2015 `cat uucp` > /usr/local/etc/uucp/call
         printf 'port tcp\ntype tcp\n'  > /usr/local/etc/uucp/port
         printf "%s\n"                         \
                 "call-login    *"                 \
                 "call-password *"                 \
                 "time          any"               \
                 "system        shuttle"           \
                 "address       mail.s.shuttle.de" \
                 "commands      rmail rnews"       \
                 "port          tcp"               \
         >/usr/local/etc/uucp/sys
         cd /usr/local/etc/uucp && chown uucp:uucp * && chmod o-rwx *
         # Trigger uucico after booting.
         mkdir -p /usr/local/etc/rc.d
         cp uucp.sh /usr/local/etc/rc.d
         # Rebuild the aliases.db.
         cp aliases /etc/mail/aliases
         newaliases

 # vim: tabstop=4:
 # EOF $RCSfile: stage_3.mk,v $

   Sgruzite stage_3.mk.

     --------------------------------------------------------------

            `Etot, i drugie dokumenty, mogut byt' skachany s
                ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

  Po voprosam, svyazannym s FreeBSD, prochitajte dokumentaciyu prezhde
                 chem pisat' v <questions@FreeBSD.org>.
         Po voprosam, svyazannym s `etoj dokumentaciej, pishite
                           <doc@FreeBSD.org>.
  Po voprosam, svyazannym s russkim perevodom dokumentacii, pishite v
                    rassylku <frdp@FreeBSD.org.ua>.
  Informaciya po podpiske na `etu rassylku nahoditsya na sajte proekta
                               perevoda.
