/pliant/fullpliant/install.pli
 
 1  abstract 
 2    [This module will install a ready to operate FullPliant system.] 
 3   
 4  module "/pliant/language/context.pli" 
 5  module "/pliant/language/stream.pli" 
 6  module "/pliant/admin/file.pli" 
 7  module "/pliant/admin/execute.pli" 
 8  module "/pliant/admin/shell.pli" 
 9  module "/pliant/linux/kernel/module.pli" 
 10  module "/pliant/linux/kernel/device.pli" 
 11  module "/pliant/linux/storage/partition.pli" 
 12  module "/pliant/linux/storage/raid.pli" 
 13  module "/pliant/linux/storage/filesystem.pli" 
 14  module "/pliant/linux/storage/cdrom.pli" 
 15  module "/pliant/linux/kernel/library.pli" 
 16   
 17  module "/pliant/protocol/http/site.pli" 
 18  module "/pliant/protocol/dns/name.pli" 
 19  module "/pliant/util/crypto/rsa.pli" 
 20   
 21  module "/pliant/fullpliant/user.pli" 
 22   
 23  module "/pliant/language/stream/filesystembase.pli" 
 24  module "/pliant/language/stream/multi.pli" 
 25   
 26  module "kernel.pli" 
 27  module "debian.pli" 
 28  module "embedded/install.pli" 
 29  submodule "computer.pli" 
 30   
 31   
 32  public 
 33    constant fullpliant_source_path "file:/fullpliant/unix/src/" 
 34    constant fullpliant_binary_path "file:/fullpliant/unix/bin/" 
 35   
 36   
 37 
 
 38   
 39   
 40  function grub_copy path 
 41    arg Str path 
 42    file_tree_copy "file:/usr/share/grub/i386-pc/" path+"boot/grub/" 
 43    file_tree_copy "file:/usr/lib/grub/i386-pc/" path+"boot/grub/" 
 44    file_tree_copy "file:/lib/grub/i386-pc/" path+"boot/grub/" 
 45    file_tree_copy "file:/boot/grub/" path+"boot/grub/" 
 46   
 47   
 48  function grub_install root_path grub_boot_drive grub_boot_partition -> status 
 49    arg Str root_path grub_boot_drive grub_boot_partition ; arg Status status 
 50    var Str temp := file_temporary 
 51    (var Stream kbd) open temp out+safe 
 52    kbd writeline "root ("+grub_boot_partition+")" 
 53    var Str stage1 := "stage1" # shunt (grub_boot_drive parse "fd" any) "stage1" "stage1_lba" 
 54    var Str stage2 := "stage2" 
 55    kbd writeline "install /boot/grub/"+stage1+" ("+grub_boot_drive+") /boot/grub/"+stage2+" p" 
 56    kbd writeline "quit" 
 57    kbd close 
 58    var Int err := execute "grub --batch" input temp # quiet 
 59    file_delete temp 
 60    status := shunt err=0 success failure 
 61   
 62   
 63  function grub_configure c root_path grub_boot_drive grub_boot_partition kernel_root kernel_options grub_options 
 64    arg Data:Computer c ; arg Str root_path grub_boot_drive grub_boot_partition ; arg Str kernel_root kernel_options grub_options 
 65    (var Stream menu) open root_path+"boot/grub/menu.lst" out+safe+mkdir 
 66    menu writeline "timeout 2" 
 67    menu writeline "title FullPliant" 
 68    menu writeline "root ("+grub_boot_partition+")" 
 69    if (file_query root_path+"boot/initrd.img" standard)=success 
 70      menu writeline "kernel /boot/kernel root=/dev/ram0"+(shunt kernel_options<>"" " " "")+kernel_options 
 71      menu writeline "initrd /boot/initrd.img" 
 72    else 
 73      menu writeline "kernel /boot/kernel root="+file_os_name:kernel_root+(shunt kernel_options<>"" " " "")+kernel_options 
 74    each c:env:"partition" filter keyof:p<>"root" 
 75      if p:"os"<>"" and (p:"device" parse any (var Int i)) 
 76        menu writeline "title "+keyof:p 
 77        menu writeline "rootnoverify (hd0,"+(string i-1)+")" 
 78        menu writeline "makeactive" 
 79        menu writeline "chainloader +1" 
 80    menu close 
 81   
 82   
 83  function lilo_install c root_path lilo_boot_device kernel_root kernel_options lilo_options -> status 
 84    arg Data:Computer c ; arg Str root_path lilo_boot_device kernel_root kernel_options lilo_options ; arg Status status 
 85    (var Stream s) open root_path+"boot/lilo.conf" out+safe 
 86    if s=failure 
 87      console "Failed to create lilo configuration file" eol 
 88      return failure 
 89    writeline "ignore-table" 
 90    writeline "boot="+file_os_name:lilo_boot_device 
 91    writeline "delay=50" 
 92    writeline "lock" 
 93    writeline "read-only" 
 94    writeline "image=/boot/kernel" 
 95    writeline "  label=fullpliant" 
 96    if (file_query root_path+"boot/initrd.img" standard)=success 
 97      writeline "  initrd=/boot/initrd.img" 
 98      writeline "  root=/dev/ram0" 
 99    else 
 100      writeline "  root="+file_os_name:kernel_root 
 101    writeline "  append=[dq]"+kernel_options+"[dq]" 
 102    if c:env:"partition":"root":"video_bios_mode"<>"" 
 103      writeline "  vga="+c:env:"partition":"root":"video_bios_mode" 
 104    eif c:env:"hardware":"video":"bios_mode"<>"" 
 105      writeline "  vga="+c:env:"hardware":"video":"bios_mode" 
 106    if (file_query root_path+"boot/recover" standard)=defined 
 107      writeline "image=/boot/recover" 
 108      writeline "  label=recover" 
 109      writeline "  root="+file_os_name:kernel_root 
 110      writeline "  append=[dq]"+kernel_options+"[dq]" 
 111      if c:env:"partition":"root":"video_bios_mode"<>"" 
 112        writeline "  vga="+c:env:"partition":"root":"video_bios_mode" 
 113      eif c:env:"hardware":"video":"bios_mode"<>"" 
 114        writeline "  vga="+c:env:"hardware":"video":"bios_mode" 
 115    if (file_query root_path+"boot/once" standard)=defined 
 116      writeline "image=/boot/once" 
 117      writeline "  label=once" 
 118      writeline "  root="+file_os_name:kernel_root 
 119      writeline "  append=[dq]"+kernel_options+"[dq]" 
 120      if c:env:"partition":"root":"video_bios_mode"<>"" 
 121        writeline "  vga="+c:env:"partition":"root":"video_bios_mode" 
 122      eif c:env:"hardware":"video":"bios_mode"<>"" 
 123        writeline "  vga="+c:env:"hardware":"video":"bios_mode" 
 124    each c:env:"partition" filter keyof:p<>"root" 
 125      if p:"kernel"<>"" 
 126        if (filesystem_mount p:"device" "file:/mnt/"+keyof:p+"/" "nocheck")=failure 
 127          console "Failed to mount " p:"device" " partition" eol 
 128        writeline "image=/mnt/"+keyof:p+"/boot/"+p:"kernel" 
 129        writeline "  label="+keyof:p 
 130        writeline "  root="+(file_os_name p:"device") 
 131        writeline "  append=[dq]"+p:"kernel_options"+"[dq]" 
 132        if p:"video_bios_mode"<>"" 
 133          writeline "  vga="+p:"video_bios_mode" 
 134        eif c:env:"hardware":"video":"bios_mode"<>"" 
 135          writeline "  vga="+c:env:"hardware":"video":"bios_mode" 
 136      eif p:"os"<>"" 
 137        (var Stream disk) open p:"device" in+safe 
 138        var Str sector := repeat 512 " " 
 139        disk raw_read sector:characters sector:len 
 140        disk close 
 141        if sector:1FEh=character:55h and sector:1FFh=character:0AAh 
 142          writeline "other="+(file_os_name p:"device") 
 143          writeline "  label="+keyof:p 
 144          writeline "  optional" 
 145    if (file_query root_path+"boot/memtest86.bin" standard)=success 
 146      writeline "image=/boot/memtest86.bin" 
 147      writeline "  label=memtest" 
 148    close 
 149    var Str flags := "" 
 150    var Str geometry := lilo_options option "geometry" Str 
 151    flags += (shunt geometry="chs" "" geometry="lba32" " -L" " -l") 
 152    var Int err := execute "lilo -C /boot/lilo.conf"+flags root root_path 
 153    if err<>and geometry="" 
 154      err := execute "lilo -C /boot/lilo.conf -L" root root_path 
 155      if err<>and geometry="" 
 156        err := execute "lilo -C /boot/lilo.conf" root root_path 
 157    # file_delete root_path+"boot/lilo.conf" 
 158    each c:env:"partition" 
 159      if p:"kernel"<>"" 
 160        filesystem_dismount "file:/mnt/"+keyof:p+"/" 
 161    status := shunt err=0 success failure 
 162    if status=success and (file_query root_path+"boot/once" standard)=defined 
 163      execute "lilo -C /boot/lilo.conf -R once" 
 164      file_delete "file:/boot/twice" 
 165      file_move "file:/boot/once" "file:/boot/twice" 
 166   
 167   
 168  function update_rights c root_path 
 169    arg Data:Computer c ; arg Str root_path 
 170    file_tree_rights root_path+"bin/" undefined undefined 8^2 0 0 0 
 171    file_tree_rights root_path+"pliant/binary/" undefined undefined 8^2 0 0 0 
 172    var Array:FileInfo files := file_list root_path+"pliant/binary/" standard 
 173    for (var Int i) files:size-1 
 174      if files:i:extension=".dump" 
 175        file_delete files:i:name 
 176   
 177   
 178  export grub_copy grub_install grub_configure lilo_install update_rights 
 179   
 180   
 181 
 
 182   
 183   
 184  function install_initrd c path loindex -> status 
 185    arg Data:Computer c ; arg Str path ; arg Int loindex ; arg ExtendedStatus status 
 186    kernel_make_device path+"dev/ram0" 
 187    var Str temp := file_temporary 
 188    (var Stream s) open temp out+safe 
 189    var Address buf := memory_zallocate 1024 null 
 190    for (var Int i) 0 1023 
 191      raw_write buf 1024 
 192    close 
 193    memory_free buf 
 194    partition_format temp "ext2" "standard" 
 195    kernel_load_module "loop" 
 196    kernel_make_device "device:/loop"+string:loindex 
 197    execute "losetup /dev/loop"+string:loindex+" "+file_os_name:temp 
 198    if (filesystem_mount "device:/loop"+string:loindex "file:/mnt/loop/" "")=failure 
 199      return failure:"Failed to mount initrd image (maybe loopback device is not supported by this kernel)" 
 200    if (file_copy fullpliant_binary_path+"linuxrc" "file:/mnt/loop/bin/init" extended)=failure 
 201      filesystem_dismount "file:/mnt/loop/" 
 202      return failure:"Failed to build /linuxrc" 
 203    kernel_make_device "file:/mnt/loop/dev/console" 
 204    kernel_make_device "file:/mnt/loop/dev/tty0" 
 205    for (var Int i) 0 3 
 206      kernel_make_device "file:/mnt/loop/dev/hd"+(character "a":number+i) 
 207    for (var Int i) 0 11 
 208      kernel_make_device "file:/mnt/loop/dev/sd"+(character "a":number+i) 
 209    file_tree_create "file:/mnt/loop/mnt/root/" 
 210    filesystem_dismount "file:/mnt/loop/" 
 211    execute "losetup -d /dev/loop"+string:loindex 
 212    file_copy temp "gzip:"+path+"boot/initrd.img" reduced 
 213    file_delete temp 
 214    file_tree_create path+"mnt/initrd/" 
 215    status := success 
 216   
 217   
 218 
 
 219   
 220   
 221  function copy_floppy src_name dest_name -> status 
 222    arg Str src_name dest_name ; arg Status status 
 223    (var Stream src) open src_name in+nocache+safe 
 224    if src=failure 
 225      return failure 
 226    (var Stream dest) open dest_name out+nocache+safe 
 227    var Address buffer := memory_zallocate 512 null 
 228    for (var Int i) 1 2880 
 229      src raw_read buffer 512 
 230      dest raw_write buffer 512 
 231    status := shunt src=success and dest=success success failure 
 232    src close ; dest close 
 233    if status=failure and not (dest_name parse "device:" any) 
 234      file_delete dest_name 
 235   
 236   
 237  function build_grub_floppy -> status 
 238    arg ExtendedStatus status 
 239    file_tree_create "file:/mnt/floppy/" 
 240    filesystem_dismount "file:/mnt/floppy/" 
 241    kernel_make_device "device:/fd0" 
 242    copy_floppy "device:/zero" "device:/fd0" 
 243    if (partition_format "device:/fd0" "ext2" "standard nocheck name [dq]FullPliant[dq]")=failure 
 244      return failure:"Failed to format partition (maybe there is no floppy in the drive)" 
 245    if (filesystem_mount "device:/fd0" "file:/mnt/floppy/" "")=failure 
 246      return failure:"Failed to mount floppy" 
 247    grub_copy "file:/mnt/floppy/" 
 248    if (grub_install "file:/mnt/floppy/" "fd0" "fd0")=failure 
 249      status := failure "Failed to install GRUB" 
 250    else 
 251      status := success 
 252    filesystem_dismount "file:/mnt/floppy/" 
 253    if status=success 
 254      if (copy_floppy "device:/fd0" "file:/fullpliant/unix/bin/floppy")=failure 
 255        status := failure "Failed to read the floppy" 
 256   
 257   
 258  function install_floppy c file kernel_root kernel_options -> status 
 259    arg Data:Computer c ; arg Str file kernel_root kernel_options ; arg ExtendedStatus status 
 260    kernel_load_module "floppy" 
 261    if (file_query "file:/fullpliant/unix/bin/floppy" standard)=undefined 
 262      status := build_grub_floppy 
 263      if status=failure 
 264        return 
 265    if (file_copy "file:/fullpliant/unix/bin/floppy" file)=failure 
 266      return failure:"No boot floppy image available" 
 267    file_tree_create "file:/mnt/floppy/" 
 268    filesystem_dismount "file:/mnt/floppy/" 
 269    if (file parse "device:" any) 
 270      if (filesystem_mount file "file:/mnt/floppy/" "")=failure 
 271        return failure:"Failed to mount boot floppy image" 
 272    else 
 273      kernel_load_module "loop" 
 274      kernel_make_device "device:/loop0" 
 275      execute "losetup /dev/loop0"+" "+file_os_name:file 
 276      if (filesystem_mount "device:/loop0" "file:/mnt/floppy/" "")=failure 
 277        return failure:"Failed to mount boot floppy image (maybe loopback device is not supported by this kernel)" 
 278    var Str kversion := c:env:"kernel":"constant":"linux_version" 
 279    var Str sign := c:env:"kernel":"constant":"signature" 
 280    file_tree_delete "file:/tmp/kernel/" 
 281    file_extract kernel_binary_path+"kernel-"+kversion+"-"+sign+".tgz" "file:/tmp/kernel/" 
 282    if (file_copy "file:/tmp/kernel/boot/kernel" "file:/mnt/floppy/boot/kernel")=failure 
 283      status := failure "The kernel image "+kversion+" "+sign+" is not available" 
 284    else 
 285      status := success 
 286    file_tree_delete "file:/tmp/kernel/" 
 287    status := install_initrd "file:/mnt/floppy/" 1 
 288    if status=failure 
 289      return 
 290    grub_configure "file:/mnt/floppy/" "fd0" "fd0" kernel_root kernel_options "" 
 291    filesystem_dismount "file:/mnt/floppy/" 
 292    if not (file parse "device:" any) 
 293      # execute file_os_name:"embedded:/sbin/losetup"+" -d "+file_os_name:"embedded:/dev/loop0" 
 294      execute "losetup -d /dev/loop0" 
 295   
 296   
 297  export build_grub_floppy install_floppy 
 298   
 299   
 300 
 
 301   
 302   
 303  method p disk -> d 
 304   arg DiskPartition p ; arg Str d 
 305   if ((reverse p:device) parse (var Int num) any:d) 
 306     := reverse d 
 307   else 
 308     := device 
 309   
 310  export '. disk' 
 311   
 312   
 313  function enumerate_partitions c partitions disks 
 314    arg Data:Computer c ; arg_rw Dictionary partitions disks 
 315    partitions := var Dictionary empty_dictionary 
 316    disks := var Dictionary empty_dictionary 
 317    each pa c:env:"partition" 
 318      var Pointer:DiskPartition :> partitions kmap pa:"device" DiskPartition 
 319      name := keyof pa 
 320      device := pa "device" 
 321      raid_devices := pa "raid_devices" 
 322      mountpoint := pa "mountpoint" 
 323      if (pa:"size_mb" parse (var Int mb)) 
 324        size := mb*2n^20 
 325      filesystem := shunt pa:"filesystem"<>"" pa:"filesystem" "ext2" 
 326      options := pa "options" 
 327      if pa:"disk_image"<>"" 
 328        options += " disk_image "+(string pa:"disk_image") 
 329      disks kmap p:disk Str := disk 
 330      var Str devices := raid_devices 
 331      while devices<>"" 
 332        if not (devices parse any:(var Str device) _ any:(var Str remain)) 
 333          device := devices ; remain := "" 
 334        var Str device := shunt (device search ":" -1)=(-1) "device:/"+device device 
 335        var Pointer:DiskPartition :> partitions kmap device DiskPartition 
 336        device := device 
 337        filesystem := "raid" 
 338        disks kmap p:disk Str := disk 
 339        devices := remain 
 340    disks remove "device:/md" null 
 341   
 342   
 343  function install_partition c name 
 344    arg Data:Computer c ; arg Str name 
 345    enumerate_partitions c (var Dictionary partitions) (var Dictionary disks) 
 346    each disks type Str 
 347      if d=name or name="" 
 348        (var Array:DiskPartition a) size := 0 
 349        for (var Int i) 1 16 
 350          each partitions type DiskPartition 
 351            if p:device=d+string:# p:disk=d 
 352              += p 
 353        if a:size>0 
 354          partition_create a 
 355   
 356   
 357  function install_format c name -> status 
 358    arg_rw Data:Computer c ; arg Str name ; arg Status status 
 359    enumerate_partitions c (var Dictionary partitions) (var Dictionary disks) 
 360    each partitions type DiskPartition 
 361      if name="" or name=p:name 
 362        if p:raid_devices<>"" 
 363          (var Raid raid) define p:device p:raid_devices p:options 
 364          raid initialize 
 365        status := partition_format p:device p:filesystem p:options+(shunt p:name<>"" " name "+(string p:name) "") 
 366   
 367   
 368  export enumerate_partitions install_partition install_format 
 369   
 370   
 371 
 
 372   
 373   
 374  function install_check_libraries binpath libpath -> status 
 375    arg Str binpath libpath ; arg ExtendedStatus status 
 376    status := success 
 377    var Array:FileInfo bins := file_list binpath standard+relative 
 378    for (var Int i) bins:size-1 
 379      var List:Str libs := file_libraries (file_os_name binpath+bins:i:name) 
 380      each lib libs 
 381        if (file_query libpath+lib standard)=undefined 
 382          console bins:i:name+" requires "+lib eol 
 383          status := failure bins:i:name+" requires "+lib 
 384    if status=failure 
 385      console status:message eol 
 386   
 387  export install_check_libraries 
 388   
 389   
 390 
 
 391   
 392   
 393  function install_tree c path options -> status 
 394    arg_rw Data:Computer c ; arg Str path options ; arg ExtendedStatus status 
 395    if not exists:c 
 396      return (failure "There is no "+keyof:c+" computer in the database.") 
 397   
 398    var Str distrib := c:env:"pliant":"system":"distribution" 
 399    if distrib<>"fullpliant" and not (options option "force") 
 400      return failure:"This script can only install a FullPliant system." 
 401   
 402    var Str medium := c:env:"pliant":"system":"medium" 
 403    var Str this_medium := this_computer:env:"pliant":"system":"medium" 
 404    var Bool static := c:env:"pliant":"fullpliant":"static"="true" 
 405    if not (c:env:"pliant":"pliant":"debugging_level" parse (var Int debugging_level)) 
 406      debugging_level := 1 
 407    pliant_multi_file_system mount "target:/" path pliant_default_file_system 
 408    var Str security := shunt distrib="fullpliant" "target:/pliant_security/" "target:/etc/pliant/" 
 409    var CBool keep_site_key := options option "keep_site_key" 
 410    var CBool generate_site_key := options option "generate_site_key" 
 411   
 412    if keep_site_key 
 413      console "Fetching the old site key" eol 
 414      file_tree_create "target:/" 
 415      file_extract "file:/fullpliant/archive/"+keyof:c+".tgz" "target:/" 
 416      var Str temp := file_temporary 
 417      file_copy security+"name_secret.pdb" temp   
 418    console "Cleaning the target tree " path eol 
 419    file_tree_delete path 
 420    file_tree_create path 
 421    if keep_site_key 
 422      file_copy temp security+"name_secret.pdb" 
 423      file_delete temp 
 424       
 425    if (options option "secret" Str)<>"" 
 426      file_copy (options option "secret" Str) security+"site_secret.pdb" 
 427   
 428    file_tree_create "target:/bin/" 
 429    file_tree_create "target:/dev/" 
 430    file_tree_create "target:/proc/" 
 431    file_tree_create "target:/tmp/" 
 432    if medium="nfs" or medium="cdrom" 
 433      file_tree_create "target:/mnt/target/" 
 434    file_tree_create security 
 435   
 436    console "Building devices" eol 
 437    kernel_make_device "target:/dev/console" 
 438    if (c:env:"kernel":"make":"CONFIG_BLK_DEV_IDE")="y" 
 439      for (var Int u) 0 3 
 440        kernel_make_device "target:/dev/hd"+(character "a":number+u) 
 441        for (var Int i) 1 4 
 442          kernel_make_device "target:/dev/hd"+(character "a":number+u)+string:i 
 443    if (c:env:"kernel":"make":"CONFIG_SCSI")="y"or (c:env:"kernel":"make":"CONFIG_SCSI")="m" 
 444      for (var Int i) 0 7 
 445        kernel_make_device "target:/dev/scd"+string:i 
 446      for (var Int u) 0 7 
 447        kernel_make_device "target:/dev/sd"+(character "a":number+u) 
 448        for (var Int i) 1 4 
 449          kernel_make_device "target:/dev/sd"+(character "a":number+u)+string:i 
 450    kernel_make_device "target:/dev/fdO" 
 451    if (c:env:"kernel":"make":"CONFIG_BLK_DEV_MD")="y" 
 452      for (var Int i) 0 15 
 453        kernel_make_device "target:/dev/md"+string:i 
 454    kernel_make_device "target:/dev/fd0" 
 455    kernel_make_device "target:/dev/null" 
 456    kernel_make_device "target:/dev/zero" 
 457    kernel_make_device "target:/dev/random" 
 458    kernel_make_device "target:/dev/rtc" 
 459    if medium="cdrom" 
 460      kernel_make_device "target:/dev/ram1" 
 461    if (c:env:"kernel":"make":"CONFIG_ISDN")="y" or(c:env:"kernel":"make":"CONFIG_ISDN")="m" 
 462      kernel_make_device "target:/dev/isdninfo" 
 463      kernel_make_device "target:/dev/isdnctrl" 
 464      for (var Int i) 0 15 
 465        kernel_make_device "target:/dev/ippp"+string:i 
 466        kernel_make_device "target:/dev/isdnctrl"+string:i 
 467   
 468    console "Resolving shared libraries dependencies" eol 
 469    var (Dictionary Str Str) dlls 
 470    (var DebianDistribution debian) bind c 
 471    (var Stream log) open "file:/tmp/packages.log" out+safe 
 472    (var Stream log2) open "file:/tmp/dll.log" out+safe 
 473    each c:env:"package" 
 474      var Str name := keyof p 
 475      if (debian unpack1 name p:"file" "file:/tmp/package/")=success 
 476        var Str list := file_temporary 
 477        if (execute "tar -zt -f "+file_os_name:"file:/tmp/package/data.tar.gz" output list)=0 
 478          (var Stream s) open list in+safe 
 479          while not s:atend 
 480            if (s:readline parse "." any:(var Str filename)) and (filename search "/lib/" -1)<>(-1) 
 481              var Str libpath := filename 0 (filename search_last "/" -1)+1 
 482              var Str libname := filename (filename search_last "/" -1)+filename:len 
 483              if libpath="/lib/" or libpath="/usr/lib/" 
 484                dlls insert libname string:name+" "+string:filename 
 485        else 
 486          console "Failed to list package " name eol 
 487          log writeline name+": failed to list" 
 488        file_delete list 
 489      else 
 490        console "Failed to unpack package " name eol 
 491        log writeline name+": failed to unpack" 
 492    each c:env:"package" 
 493      var Str name := keyof p 
 494      var CBool some := false 
 495      each p 
 496        if (keyof:parse "/" any) and (parse "/bin/" any) 
 497          some := true 
 498      if some 
 499        if (debian unpack1 name p:"file" "file:/tmp/package/")=success 
 500          file_tree_delete "file:/tmp/files/" 
 501          file_extract "file:/tmp/package/data.tar.gz" "file:/tmp/files/" 
 502          each p 
 503            if (keyof:parse "/" any) and (parse "/bin/" any) 
 504              var List:Str libraries := file_libraries (file_os_name "file:/tmp/files"+keyof:f) 
 505              each lib libraries 
 506                if exists:(dlls first lib) and ((dlls first lib) parse (var Str packname) (var Str filename)) 
 507                  log2 writeline f+" requires "+lib+" in "+packname 
 508                  "package" packname filename := "/lib/"+lib 
 509                else 
 510                  console "Failed to find package containing library " lib eol 
 511                  log writeline name+": find package containing library "+lib 
 512   
 513    console "Extracting Debian files" eol 
 514    each c:env:"package" 
 515      var Str name := keyof p 
 516      var CBool some := false 
 517      each p 
 518        if (keyof:parse "/" any) 
 519          some := true 
 520      if some 
 521        if (debian unpack1 name p:"file" "file:/tmp/package/")=success 
 522          file_tree_delete "file:/tmp/files/" 
 523          file_extract "file:/tmp/package/data.tar.gz" "file:/tmp/files/" 
 524          each p 
 525            if (keyof:parse "/" any) 
 526              var Str src := keyof f 
 527              var Str link := (file_query "file:/tmp/files"+src extended):link 
 528              if (link 0 1)="/" 
 529                src := "file:/tmp/files"+link 
 530              eif link<>"" 
 531                src := "file:/tmp/files"+(src 0 (src search_last "/" -1)+1)+link 
 532              else 
 533                src := "file:/tmp/files"+src 
 534              var Str dest := "target:"+f 
 535              if src:len>and (src src:len-1)="*" and dest:len>and (dest dest:len-1)="/" 
 536                var Int cut := (src search_last "/" 0)+1 
 537                var Str src_path := src cut 
 538                var Str src_base := src cut src:len-1-cut 
 539                var Array:FileInfo files := file_list src_path extended+relative 
 540                var Int count := 0 
 541                for (var Int i) files:size-1 
 542                  if (files:i:name src_base:len)=src_base 
 543                    count += 1 
 544                    if (file_copy src_path+files:i:name dest+files:i:name extended)=failure 
 545                      console "Failed to copy file " src_path+files:i:name " to " dest+files:i:name eol             
 546                      log writeline name+": "+src_path+files:i:name+" -> "+dest+files:i:name 
 547                if count=0 
 548                  console "There is no "+src+" file in package "+name eol 
 549                  log writeline name+": "+src 
 550              else 
 551                if (file_copy src dest extended)=failure 
 552                  console "Failed to copy file " keyof:" to " eol             
 553                  log writeline name+": "+keyof:f+" -> "+f 
 554                  var Array:FileInfo files := file_list "file:/tmp/files/" extended+recursive+relative 
 555                  for (var Int i) files:size-1 
 556                    log writeline "  "+files:i:name+" "+(string files:i:size)+(shunt files:i:is_link " ("+files:i:link+")" "") 
 557    # file_link "file:libdl.so.2" "target:/lib/libdl.so" 
 558    file_tree_delete "file:/tmp/files/" 
 559    file_tree_delete "file:/tmp/package/" 
 560   
 561    if static 
 562      if (file_query fullpliant_binary_path+"e2fsck" standard)=undefined 
 563        console "Building static e2fsck" eol 
 564        if not (c:env:"package":"e2fsprogs":"version" parse any:(var Str version) "-" any) 
 565          version := "1.18" 
 566        var Str ext2utils := "e2fsprogs-"+version 
 567        var Str local := fullpliant_source_path+ext2utils+".tar.gz" 
 568        var Str remote := "http://web.mit.edu/tytso/www/linux/dist/"+ext2utils+".tar.gz" 
 569        if (file_query local standard)=undefined 
 570          console "downloading " remote eol 
 571          if (file_copy remote local standard)=failure 
 572            return (failure "Failed to download ext2 utils source from "+remote) 
 573        file_tree_delete "file:/usr/src/"+ext2utils+"/" 
 574        file_extract local "file:/usr/src/" 
 575        console "  building e2fsck." eol 
 576        # we cannot redirect ./configure output to /dev/null since it would build buggy make files 
 577        shell "cd /usr/src/"+ext2utils+"/ ; ./configure --disable-shared ; make clean >/dev/null ; make >/dev/null 2>/dev/null" 
 578        if (file_copy "file:/usr/src/"+ext2utils+"/e2fsck/e2fsck" fullpliant_binary_path+"e2fsck" extended)=failure 
 579          return failure:"Failed to build e2fsck." 
 580        if (file_copy "file:/usr/src/"+ext2utils+"/misc/mke2fs" fullpliant_binary_path+"mke2fs" extended)=failure 
 581          return failure:"Failed to build mke2fs." 
 582        if (file_copy "file:/usr/src/"+ext2utils+"/misc/tune2fs" fullpliant_binary_path+"tune2fs" extended)=failure 
 583          return failure:"Failed to build mke2fs." 
 584      file_copy fullpliant_binary_path+"e2fsck" "target:/bin/e2fsck" extended 
 585      file_copy fullpliant_binary_path+"mke2fs" "target:/bin/mke2fs" extended 
 586      file_copy fullpliant_binary_path+"tune2fs" "target:/bin/tune2fs" extended 
 587    if c:env:"kernel":"make":"CONFIG_PCMCIA"="y" and c:env:"kernel":"constant":"pcmcia_version"="" 
 588      file_extract "file:/fullpliant/download/pcmcia.tgz" "target:/" 
 589    status := install_check_libraries "target:/bin/" "target:/lib/" 
 590    if status=failure 
 591      return 
 592   
 593    if not (options option "nokernel") 
 594      console "Building the custom Linux kernel" eol 
 595      status := kernel_compile c 
 596      if status=failure 
 597        return 
 598      var Str kversion := c:env:"kernel":"constant":"linux_version" 
 599      var Str sign := c:env:"kernel":"constant":"signature" 
 600      file_extract kernel_binary_path+"kernel-"+kversion+"-"+sign+".tgz" "target:/" 
 601      file_tree_delete "target:/sbin/" 
 602      file_tree_delete "target:/etc/" 
 603      file_tree_delete "target:/usr/" 
 604      file_tree_delete "target:/var/" 
 605      file_copy kernel_binary_path+"kernel-"+kversion+"-"+sign+".tgz" "target:/boot/modules.tgz" 
 606   
 607    console "Copying Pliant tree" eol 
 608    file_tree_copy "/pliant/" "target:/pliant/pliant/" extended+recursive 
 609    file_copy "/index.page" "target:/pliant/index.page" 
 610    var Str compiler := "gcc" 
 611    var Str include_options := "" 
 612    var Str compiler_options := "-O2 -m486 -mregparm=3 -mrtd -D_REGISTERS_" 
 613    var Str debug0_options := "-s -D_NOCHECK_ -fomit-frame-pointer -D_LISTING_" 
 614    var Str debug1_options := "-s -D_NOCHECK_ -D_LISTING_" 
 615    var Str debug2_options := "-s -D_CHECK_" 
 616    var Str debug_options := shunt debugging_level=debug0_options debugging_level=debug1_options debug2_options 
 617    var Str link_options := "-nostdlib" 
 618    var Str exe_options := pliant_root_path+"pliant/language/startup/start.s" 
 619    if false # not static 
 620      exe_options += " -ldl -D_SO2_" 
 621      if (file_query "file:/lib/libdl.so" standard)=undefined 
 622        file_link "file:/lib/libdl.so.2" "file:/lib/libdl.so" 
 623    var Str context_options := "-D_i386_ -D_LINUX_API_ -D_LINUX_ -D_GCC_" 
 624    if static 
 625      context_options += " -D_STATIC_" 
 626    var Str extra_options := "" 
 627    var Str detail := "-debug"+(string debugging_level)+"-static.exe" 
 628    if (file_query fullpliant_binary_path+"init" standard)=undefined 
 629      console "Compiling init executable" eol 
 630      file_tree_create fullpliant_binary_path 
 631      execute compiler+" "+compiler_options+" "+include_options+" "+debug_options+" "+link_options+" "+exe_options+" "+context_options+" "+extra_options+" -o "+(file_os_name fullpliant_binary_path+"init")+" "+file_os_name:"/pliant/fullpliant/init.c" 
 632      (var Stream t) open "file:/tmp/compile.log" out+safe 
 633      writeline compiler+" "+compiler_options+" "+include_options+" "+debug_options+" "+link_options+" "+exe_options+" "+context_options+" "+extra_options+" -o "+(file_os_name fullpliant_binary_path+"init")+" "+file_os_name:"/pliant/fullpliant/init.c" 
 634      close 
 635      file_configure fullpliant_binary_path+"init" "mode "+(string 7*8^2+5*8+5) 
 636    if (file_copy fullpliant_binary_path+"init" "target:/bin/init" extended)=failure 
 637      return failure:"Failed to build /bin/init" 
 638    if (file_query fullpliant_binary_path+"linuxrc" standard)=undefined 
 639      console "Compiling linuxrc executable" eol 
 640      file_tree_create fullpliant_binary_path 
 641      execute compiler+" "+compiler_options+" "+include_options+" "+debug_options+" "+link_options+" "+exe_options+" "+context_options+" "+extra_options+" -o "+(file_os_name fullpliant_binary_path+"linuxrc")+" "+file_os_name:"/pliant/fullpliant/linuxrc.c" 
 642      (var Stream t) open "file:/tmp/compile.log" out+safe 
 643      writeline compiler+" "+compiler_options+" "+include_options+" "+debug_options+" "+link_options+" "+exe_options+" "+context_options+" "+extra_options+" -o "+(file_os_name fullpliant_binary_path+"linuxrc")+" "+file_os_name:"/pliant/fullpliant/linuxrc.c" 
 644      close 
 645      file_configure fullpliant_binary_path+"linuxrc" "mode "+(string 7*8^2+5*8+5) 
 646    if static 
 647      file_tree_delete "target:/pliant/binary/" 
 648      file_tree_create "target:/pliant/binary/"  
 649      if (file_query fullpliant_binary_path+"pliant"+detail standard)=undefined 
 650        console "Compiling static Pliant executable" eol 
 651        file_tree_create fullpliant_binary_path 
 652        execute compiler+" "+compiler_options+" "+include_options+" "+debug_options+" "+link_options+" "+exe_options+" "+context_options+" "+extra_options+" -Dc_debugging_level="+string:debugging_level+" -o "+(file_os_name fullpliant_binary_path+"pliant"+detail)+" "+file_os_name:"/pliant/install/pliant.c" 
 653      file_copy fullpliant_binary_path+"pliant"+detail "target:/bin/pliant" extended 
 654    else 
 655      file_tree_copy "/binary/" "target:/pliant/binary/" extended 
 656      var Array:FileInfo files := file_list "target:/pliant/binary/" standard 
 657      for (var Int i) files:size-1 
 658        if files:i:extension=".dump" 
 659          file_delete files:i:name 
 660      file_link "/binary/pliant-debug"+string:debugging_level+".exe" "target:/bin/pliant" 
 661   
 662    if generate_site_key and (c:env:"pliant":"http":"site_key_bits" parse (var Int bits)) and not keep_site_key 
 663      console "Generating site " bits " bits RSA key" eol 
 664      if exists:(name_database:data:name keyof:c) 
 665        if not exists:(name_database:data:host keyof:c) 
 666          name_database:data:host create keyof:c 
 667          name_database:data:host:(keyof c) ip := name_database:data:name:(keyof c) ip 
 668        name_database:data:name delete keyof:c 
 669      site_database:data:site delete keyof:c 
 670      site_secret_database:data:site delete keyof:c 
 671      rsa_generate "target:"+keyof:bits "" 
 672   
 673    console "Building configuration files" eol 
 674    var (Link Database:Computer) target_db :> new Database:Computer 
 675    target_db load "target:/pliant_security/this_computer.pdb" 
 676    data_copy target_db:data 
 677    target_db store 
 678    data_store 
 679    file_copy "security:/computer.pdb" security+"computer.pdb" 
 680    file_copy "security:/name.pdb" security+"name.pdb" 
 681    file_copy "security:/site.pdb" security+"site.pdb" 
 682    file_copy "security:/user.pdb" security+"user.pdb" 
 683    var (Link Database:UserSecretDatabase) user_secret_db :> new Database:UserSecretDatabase 
 684    user_secret_db load "target:/pliant_security/user_secret.pdb" 
 685    each us user_secret_database:data:user 
 686      if us:password_md5<>"" 
 687        user_secret_db:data:user create keyof:us 
 688        user_secret_db:data:user:(keyof us) password_md5 := us password_md5 
 689    user_secret_db store 
 690    data_store 
 691    file_copy "security:/mail.pdb" security+"mail.pdb" 
 692    file_copy "security:/password_secret.pdb" security+"password_secret.pdb" 
 693    file_copy "security:/keyboard.pdb" security+"keyboard.pdb" 
 694   
 695    if medium="cdrom" 
 696      (var Stream s) open "target:/etc/mtab" out+mkdir+safe # get around a bug in raidtools and tune2fs 
 697      close 
 698    if medium="cdrom" or medium="usb" 
 699      file_copy "data:/pliant/fullpliant/pci_device_listing.txt" "target:/pliant_data/pliant/fullpliant/pci_device_listing.txt" 
 700      console "Building initrd image" eol 
 701      status := install_initrd "target:/" 0 
 702      if status=failure 
 703        return 
 704    if c:env:"pliant":"ui":"console"="true" 
 705      console "Copying ui extra files" eol 
 706      file_copy "security:/keyboard.pdb" security+"keyboard.pdb" 
 707      file_copy "security:/font.pdb" security+"font.pdb" 
 708      constant fontset "bitstreamvera" # "free" 
 709      file_tree_copy "file:/pliant_data/pliant/font/"+fontset+"/" "target:/pliant_data/pliant/font/"+fontset+"/" 
 710      kernel_make_device "target:/dev/tty0" 
 711      kernel_make_device "target:/dev/tty2" 
 712      # kernel_make_device "target:/dev/input/keyboard" 
 713      kernel_make_device "target:/dev/input/mice" 
 714      kernel_make_device "target:/dev/fb0" 
 715    each tb c:env:"tarball" 
 716      var Str tbfile := tb "file" 
 717      if tbfile<>"" 
 718        if (tbfile search "/" -1)=(-1) 
 719          tbfile := "file:/fullpliant/download/"+tbfile 
 720        var Str tbpath := tb "path" 
 721        if tbpath="" 
 722          tbpath := "target:/" 
 723        file_extract tbfile tbpath 
 724    pliant_multi_file_system dismount "target:/" 
 725    console "done." eol 
 726    status := success 
 727     
 728  export install_tree