Magellan Linux

Diff of /trunk/installer-simple/bin/installer.sh.in

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2882 by niro, Fri Jul 31 09:39:45 2015 UTC revision 2948 by niro, Mon Jun 13 15:03:52 2016 UTC
# Line 40  do Line 40  do
40   fi   fi
41  done  done
42    
43    # fetch cmdline
44    for argv in $*
45    do
46     case $1 in
47     --liveroot) shift; cmdliveroot="$1" ;;
48     --imageroot) shift; cmdimageroot="$1" ;;
49     --installroot) shift; cmdinstallroot="$1" ;;
50     --filesystem) shift; cmdformatfilesystem="$1" ;;
51     --help)
52     echo "$0 options:"
53     echo " --liveroot [path]     - override default liveroot"
54     echo " --imageroot [path]    - override default imageroot"
55     echo " --installroot [path]  - override default installroot"
56     echo " --filesystem [fstype] - override default filesystem used to format the disk"
57     exit 0 ;;
58     esac
59     shift
60    done
61    
62  ### System/Config Version  ### System/Config Version
63  VERSION="%VERSIONTAG%"  VERSION="%VERSIONTAG%"
64  TITLE="${DEFAULT_TITLE} - ${VERSION}"  TITLE="${DEFAULT_TITLE} - ${VERSION}"
65    
66    # initialize global variables so they are exportable
67  # some sane defaults  # some sane defaults
68  LIVEROOT="${DEFAULT_LIVEROOT}"  INSTALL_METHOD=""
69  IMAGEROOT="${DEFAULT_IMAGEROOT}"  if [[ -n ${cmdliveroot} ]]
70  INSTALLROOT="${DEFAULT_INSTALLROOT}"  then
71     LIVEROOT="${cmdliveroot}"
72    else
73     LIVEROOT="${DEFAULT_LIVEROOT}"
74    fi
75    if [[ -n ${cmdimageroot} ]]
76    then
77     IMAGEROOT="${cmdimageroot}"
78    else
79     IMAGEROOT="${DEFAULT_IMAGEROOT}"
80    fi
81    if [[ -n ${cmdinstallroot} ]]
82    then
83     INSTALLROOT="${cmdinstallroot}"
84    else
85     INSTALLROOT="${DEFAULT_INSTALLROOT}"
86    fi
87  KERNELPKG="${DEFAULT_KERNELPKG}"  KERNELPKG="${DEFAULT_KERNELPKG}"
88  KERNELOPTS="${DEFAULT_KERNELOPTS}"  KERNELOPTS="${DEFAULT_KERNELOPTS}"
89  GRUBLEGACYOPTS=""  GRUBLEGACYOPTS=""
# Line 55  GRUB2OPTS="" Line 91  GRUB2OPTS=""
91  FDISKPARTIONBELOW256MB=0  FDISKPARTIONBELOW256MB=0
92  SPECIALDEVICE=""  SPECIALDEVICE=""
93  FORMFACTOR="${DEFAULT_FORMFACTOR}"  FORMFACTOR="${DEFAULT_FORMFACTOR}"
94  FORMAT_FILESYSTEM="${DEFAULT_FILESYSTEM}"  if [[ -n ${cmdformatfilesystem} ]]
95    then
96     FORMAT_FILESYSTEM="${cmdformatfilesystem}"
97    else
98     FORMAT_FILESYSTEM="${DEFAULT_FILESYSTEM}"
99    fi
100    FLASHDISK=0
101    
102  # TOTALLINES=linecount of ${CDIMAGENAME}-tarball -1 !  # TOTALLINES=linecount of ${CDIMAGENAME}-tarball -1 !
103  # -> now in images.conf  # -> now in images.conf
# Line 81  trap_exit() Line 123  trap_exit()
123   is_mounted --location "${INSTALLROOT}/sys" && umount ${INSTALLROOT}/sys   is_mounted --location "${INSTALLROOT}/sys" && umount ${INSTALLROOT}/sys
124   is_mounted --location "${INSTALLROOT}/boot" && umount ${INSTALLROOT}/boot   is_mounted --location "${INSTALLROOT}/boot" && umount ${INSTALLROOT}/boot
125   is_mounted --location "${INSTALLROOT}" && umount ${INSTALLROOT}   is_mounted --location "${INSTALLROOT}" && umount ${INSTALLROOT}
126     [[ -n ${SWAPHDD} ]] && swapoff ${SWAPHDD}
127    
128   echo $"Installation aborted."   echo $"Installation aborted."
129   exit 1   exit 1
# Line 99  install_meter() Line 142  install_meter()
142   return 0   return 0
143  }  }
144    
 install_mount_rootfs()  
 {  
  local opts  
   
  if [[ -n ${SWAPHDD} ]]  
  then  
  swapon ${SWAPHDD} || die  
  fi  
  if [[ -n ${ROOTHDD} ]]  
  then  
  mount -t ${FORMAT_FILESYSTEM_ROOTHDD} ${ROOTHDD} ${INSTALL_ROOT} || die  
  fi  
  if [[ -n ${BOOTHDD} ]]  
  then  
  install -d ${INSTALL_ROOT}/boot || die  
  mount -t ${FORMAT_FILESYSTEM_BOOTHDD} ${BOOTHDD} ${INSTALL_ROOT}/boot || die  
  fi  
   
  cd ${INSTALL_ROOT} || die  
 }  
   
   
145  mount_rootfs()  mount_rootfs()
146  {  {
147   local retval   local retval
# Line 136  mount_rootfs() Line 157  mount_rootfs()
157   then   then
158   echo $"${INSTALLROOT} already mounted" >&2   echo $"${INSTALLROOT} already mounted" >&2
159   else   else
160   mount "${ROOTHDD}" "${INSTALLROOT}" || dialog_die $"Could not mount rootfs - drive '${ROOTHDD}' -> '${INSTALLROOT}'"   mount -t "${FORMAT_FILESYSTEM_ROOTHDD}" "${ROOTHDD}" "${INSTALLROOT}" || dialog_die $"Could not mount rootfs - drive '${ROOTHDD}' -> '${INSTALLROOT}'"
161   fi   fi
162   fi   fi
163    
# Line 148  mount_rootfs() Line 169  mount_rootfs()
169   then   then
170   echo $"${INSTALLROOT}/boot already mounted" >&2   echo $"${INSTALLROOT}/boot already mounted" >&2
171   else   else
172   mount "${BOOTHDD}" "${INSTALLROOT}"/boot || dialog_die $"Could not mount bootfs - drive '${BOOTHDD}' -> '${INSTALLROOT}/boot'"   mount -t "${FORMAT_FILESYSTEM_BOOTHDD}" "${BOOTHDD}" "${INSTALLROOT}"/boot || dialog_die $"Could not mount bootfs - drive '${BOOTHDD}' -> '${INSTALLROOT}/boot'"
173   fi   fi
174   fi   fi
175  }  }
# Line 172  install_do_reboot() Line 193  install_do_reboot()
193  run_hardware_detection()  run_hardware_detection()
194  {  {
195   local hwinfo   local hwinfo
   
196   hwinfo="$(hwinfo --bios --storage --pci --gfxcard --sys)"   hwinfo="$(hwinfo --bios --storage --pci --gfxcard --sys)"
197    
198   # check for special devices/clients:   # check for special devices/clients:
# Line 180  run_hardware_detection() Line 200  run_hardware_detection()
200   local removable=0   local removable=0
201   if [[ ! -z $(echo "${hwinfo}" | grep -i zotac) ]]   if [[ ! -z $(echo "${hwinfo}" | grep -i zotac) ]]
202   then   then
203   #for i in /sys/block/[hs]d*/removable   for i in /sys/block/[hs]d*/removable
204   #do   do
205   # if [[ $(< ${i}) = 1 ]]   if [[ $(< ${i}) = 1 ]]
206   # then   then
207   # removable=1   removable=1
208   # fi   # we assume that all removable disks are flash disks on a zotac
209   #done   export FLASHDISK=1
210     fi
211     done
212   # smartcard = udevadm info -n /dev/sda -a | grep -i 'configuration.*card'   # smartcard = udevadm info -n /dev/sda -a | grep -i 'configuration.*card'
213    
214   # only add this for grub legacy, grub2 detect these settings on its own   # only add this for grub legacy, grub2 detect these settings on its own
# Line 218  run_hardware_detection() Line 240  run_hardware_detection()
240   export GRUBLEGACYOPTS=""   export GRUBLEGACYOPTS=""
241   fi   fi
242    
243     # check for i845 Chipsets and enable KMS and use 915 drm driver later in initrd
244     if [[ ! -z $(echo "${hwinfo}" | grep -i i845) ]]
245     then
246     export SPECIALDEVICE="i845"
247     # unset default video=1024x768 opt or the drm driver breaks
248     export KERNELOPTS="quiet"
249     export GRUBLEGACYOPTS=""
250     # enable full kms support
251     export GRUB2GFXPAYLOAD="keep"
252     fi
253    
254     # check for radeon gfxcards
255     if [[ ! -z $(echo "${hwinfo}" | grep -i radeon) ]]
256     then
257     # enable full kms support
258     export GRUB2GFXPAYLOAD="keep"
259     fi
260    
261     # requires nomsi to prevent massive IRQ error spam
262     # see: http://ubuntuforums.org/showthread.php?t=1234983
263     if [[ ! -z $(echo "${hwinfo}" | grep -i 'P5VD2-X') ]] || [[ ! -z $(echo "${hwinfo}" | grep -i 'VT8237') ]] || [[ ! -z $(echo "${hwinfo}" | grep -i 'VX700') ]]
264     then
265     export SPECIALDEVICE="nomsi"
266     export KERNELOPTS="${KERNELOPTS} pci=nomsi,noaer"
267     fi
268    
269   # check for special devices/clients:   # check for special devices/clients:
270   # check for laptops and activate cpufreq scaling   # check for laptops and activate cpufreq scaling
271   if [[ $(echo "${hwinfo}" | grep 'Formfactor:' | sed 's:.*Formfactor\:\ \"\(.*\)\":\1:') = laptop ]]   if [[ $(echo "${hwinfo}" | grep 'Formfactor:' | sed 's:.*Formfactor\:\ \"\(.*\)\":\1:') = laptop ]]
# Line 242  run_hardware_detection_disks() Line 290  run_hardware_detection_disks()
290   export ALL_CDROMS="$(get_hwinfo cdrom)"   export ALL_CDROMS="$(get_hwinfo cdrom)"
291  }  }
292    
293    auto_partition_clear_disk()
294    {
295     if [ -e ${HDD} ]
296     then
297     dd if=/dev/zero of=${HDD} count=1 &> /dev/null || dialog_die
298     else
299     echo "clear disk: device ${HDD} does not exist" >&2
300     fi
301    }
302    
303    auto_partition_command()
304    {
305     if [ -e ${HDD} ]
306     then
307     fdisk ${HDD} &> /dev/null << EOF
308    $(echo "${PARTITION_OPTS}")
309    EOF
310     else
311     echo "partition command: device ${HDD} does not exist" >&2
312     fi
313    }
314    
315  setup_hdd_partitions()  setup_hdd_partitions()
316  {  {
317   case "${INSTALL_METHOD}" in   local partition_number
318   auto)   local partition_type
319   BOOTHDD=""   local partition_start_sector
320   SWAPHDD=""   local partition_size
  ROOTHDD="${HDD}1"  
  ;;  
  normal)  
  BOOTHDD="${HDD}1"  
  SWAPHDD="${HDD}2"  
  ROOTHDD="${HDD}3"  
  ;;  
  esac  
321    
322   # sanity check - should not happen   # sanity check - should not happen
323   if is_mounted --device "${ROOTHDD}"   if is_mounted --device "${ROOTHDD}"
# Line 286  setup_hdd_partitions() Line 348  setup_hdd_partitions()
348   fi   fi
349    
350   ## delete disk   ## delete disk
351   dd if=/dev/zero of=${HDD} count=1 &> /dev/null || dialog_die   auto_partition_clear_disk
352    
353   if [[ ${FDISKPARTIONBELOW256MB} = 1 ]]   # setup partition options
354     export PARTITION_OPTS
355    
356     if [[ -n ${BOOTHDD} ]]
357   then   then
358   ## setup one bootable partition   # create a boot disk with 50meg size - bootable
359   #1. n= new disk   partition_type="p"
360   #2. p= primary disk   partition_number="1"
361   #3. 1= first partition   if [[ ${FDISKPARTIONBELOW256MB} = 1 ]]
362   #4. 2= default sector start // small disk needs more space for grub2 mbr sector   then
363   #5. ''= defaul sector end   # 2= default sector start // small disk needs more space for grub2 mbr sector
364   #6. a= bootable flag   partition_start_sector="2"
365   #7. 1= boot flag for partition 1   else
366   #8. w= write/quit   # '' use default sector start
367   fdisk ${HDD} &> /dev/null << EOF   partition_start_sector=""
368  n   fi
369  p   # 50meg size
370  1   partition_size="+50M"
371  2  
372     # create a boot disk with 50meg size - bootable
373  a   # n= new disk
374  1   # p= primary disk
375  w   # w= write/quit
376  EOF   PARTITION_OPTS="n
377   else  ${partition_type}
378   ## setup one bootable partition  ${partition_number}
379   #1. n= new disk  ${partition_start_sector}
380   #2. p= primary disk  ${partition_size}
381   #3. 1= first partition  w"
382   #4. ''= default sector start   # create the disk
383   #5. ''= defaul sector end   auto_partition_command
384   #6. a= bootable flag  
385   #7. 1= boot flag for partition 1   # mark the disk bootable
386   #8. w= write/quit   PARTITION_OPTS="a
387   fdisk ${HDD} &> /dev/null << EOF  ${partition_number}
388  n  w"
389  p   auto_partition_command
390  1  
391     fi
392    
393  a   if [[ -n ${SWAPHDD} ]]
394  1   then
395  w   # p= primary disk
396  EOF   partition_type="p"
397     if [[ -n ${BOOTHDD} ]]
398     then
399     # boot disk exist, partition 2
400     partition_number="2"
401     else
402     # boot disk does not exist, partition 1
403     partition_number="1"
404     fi
405     if [[ ${FDISKPARTIONBELOW256MB} = 1 ]]
406     then
407     # fake sector 2 and fdisk finds the next free sector which must be selected with enter
408     partition_start_sector="2
409    "
410     else
411     # '' use default sector start
412     partition_start_sector=""
413     fi
414     partition_start_sector=""
415     # +2G disk size
416     partition_size="+2G"
417    
418     # create a swap disk with 2GB size
419     PARTITION_OPTS="n
420    ${partition_type}
421    ${partition_number}
422    ${partition_start_sector}
423    ${partition_size}
424    w"
425     # create the disk
426     auto_partition_command
427    
428     # mark disk as swap space
429     PARTITION_OPTS="
430    t"
431     if [[ ${partition_number} != 1 ]]
432     then
433     PARTITION_OPTS+="
434    ${partition_number}"
435     fi
436     PARTITION_OPTS+="
437    82
438    w"
439     auto_partition_command
440     fi
441    
442     if [[ -n ${ROOTHDD} ]]
443     then
444     # p= primary disk
445     partition_type="p"
446     if [[ -z ${BOOTHDD} ]] && [[ -z ${SWAPHDD} ]]
447     then
448     # boot and swap disk does not exist, partition 1
449     partition_number="1"
450     fi
451     if [[ -n ${BOOTHDD} ]] || [[ -n ${SWAPHDD} ]]
452     then
453     # boot or swap disk exist, partition 2
454     partition_number="2"
455     fi
456     if [[ -n ${BOOTHDD} ]] && [[ -n ${SWAPHDD} ]]
457     then
458     # boot and swap disk does exist, partition 3
459     partition_number="3"
460     fi
461     if [[ ${FDISKPARTIONBELOW256MB} = 1 ]]
462     then
463     if [[ -z ${BOOTHDD} ]]
464     then
465     # 2= default sector start // small disk needs more space for grub2 mbr sector
466     partition_start_sector="2"
467     else
468     # fake sector 2 and fdisk finds the next free sector which must be selected with enter
469     partition_start_sector="2
470    "
471     fi
472     else
473     # '' use default sector start
474     partition_start_sector=""
475     fi
476     # '' default sector end
477     partition_size=""
478    
479     # create system disk with remaining space
480     # w= write/quit
481     PARTITION_OPTS="n
482    ${partition_type}
483    ${partition_number}
484    ${partition_start_sector}
485    ${partition_size}
486    w"
487     # create the disk
488     auto_partition_command
489    
490     # no boot disk? then this is the boot disk
491     if [[ -z ${BOOTHDD} ]]
492     then
493     # mark the disk bootable
494     PARTITION_OPTS="a
495    ${partition_number}
496    w"
497     auto_partition_command
498     fi
499   fi   fi
500   else   else
501   cfdisk ${HDD} || dialog_die   cfdisk ${HDD} || dialog_die
# Line 337  EOF Line 504  EOF
504    
505  setup_hdd_format()  setup_hdd_format()
506  {  {
507     install -d /tmp
508     :> /tmp/format.log
509    
510   if [[ -n ${SWAPHDD} ]]   if [[ -n ${SWAPHDD} ]]
511   then   then
512   # sanity check - should not happen   # sanity check - should not happen
# Line 357  setup_hdd_format() Line 527  setup_hdd_format()
527   umount "${BOOTHDD}"   umount "${BOOTHDD}"
528   fi   fi
529    
530   mkfs."${FORMAT_FILESYSTEM}" -q "${BOOTHDD}" || dialog_die   mkfs."${FORMAT_FILESYSTEM_BOOTHDD}" "${BOOTHDD}" &>> /tmp/format.log || dialog_die
531   fi   fi
532    
533   if [[ -n ${ROOTHDD} ]]   if [[ -n ${ROOTHDD} ]]
# Line 369  setup_hdd_format() Line 539  setup_hdd_format()
539   umount "${ROOTHDD}"   umount "${ROOTHDD}"
540   fi   fi
541    
542   mkfs."${FORMAT_FILESYSTEM}" -q "${ROOTHDD}" || dialog_die   mkfs."${FORMAT_FILESYSTEM_ROOTHDD}" "${ROOTHDD}" &>> /tmp/format.log || dialog_die
543   fi   fi
544  }  }
545    
# Line 389  install_system_settings() Line 559  install_system_settings()
559   clearconfig   clearconfig
560   if [[ -n ${BOOTHDD} ]]   if [[ -n ${BOOTHDD} ]]
561   then   then
562   addconfig -e "UUID=$(get_uuid ${BOOTHDD})\t/\t${FORMAT_FILESYSTEM}\tnoatime\t1 1"   addconfig -e "UUID=$(get_uuid ${BOOTHDD})\t/\t${FORMAT_FILESYSTEM_BOOTHDD}\tnoatime\t1 1"
563   fi   fi
564   if [[ -n ${ROOTHDD} ]]   if [[ -n ${ROOTHDD} ]]
565   then   then
566   addconfig -e "UUID=$(get_uuid ${ROOTHDD})\t/\t${FORMAT_FILESYSTEM}\tnoatime\t0 0"   addconfig -e "UUID=$(get_uuid ${ROOTHDD})\t/\t${FORMAT_FILESYSTEM_ROOTHDD}\tnoatime\t0 0"
567   fi   fi
568   if [[ -n ${SWAPHDD} ]]   if [[ -n ${SWAPHDD} ]]
569   then   then
# Line 500  task_hardware_detection() Line 670  task_hardware_detection()
670   zotac*) message+=$"\n\Z2Zotac device detected.\Zn" ;;   zotac*) message+=$"\n\Z2Zotac device detected.\Zn" ;;
671   rangee) message+=$"\n\Z2Rangee device detected.\Zn" ;;   rangee) message+=$"\n\Z2Rangee device detected.\Zn" ;;
672   maxdata) message+=$"\n\Z2Maxdata device detected.\Zn" ;;   maxdata) message+=$"\n\Z2Maxdata device detected.\Zn" ;;
673     i845) message+=$"\n\Z2Intel i845 VGA device detected.\Zn" ;;
674     nomsi) message+=$"\n\Z2Mainboard with P5VD2-X/VT8237/VX700 chipset detected.\Zn"
675     message+=$"\n\Z2Disabling Message Signaled Interrupts (MSI) capability of the kernel.\Zn" ;;
676   *) message+=$"\n\ZnCommon device detected.\Zn" ;;   *) message+=$"\n\ZnCommon device detected.\Zn" ;;
677   esac   esac
678   if [[ ${FORMFACTOR} = laptop ]]   if [[ ${FORMFACTOR} = laptop ]]
679   then   then
680   message+=$"\n\ZnFormfactor Laptop, activating 'ondemand' powersaving mode.\Zn"   message+=$"\n\ZnFormfactor Laptop, activating 'ondemand' powersaving mode.\Zn"
681   fi   fi
682     if [[ ${FLASHDISK} = 1 ]]
683     then
684     message+=$"\n\ZnFlash memory detected.\Zn"
685     message+=$"\n\ZnF2FS will be used as default filesystem within the auto installation mode.\Zn"
686     fi
687    
688   messagebox -y 12 -h $"Detected hardware:" "${message}"   messagebox -y 12 -h $"Detected hardware:" "${message}"
689  }  }
690    
691    task_select_target_hdd()
692    {
693     if [[ -z ${ALL_DISKS} ]]
694     then
695     dialog_no_harddrive_found
696     exit 1
697     else
698     export HDD=$(dialog_select_target_harddrive)
699     fi
700    }
701    
702  task_setup_hdd_partitions()  task_setup_hdd_partitions()
703  {  {
  local i  
704   local retval   local retval
705    
706   if [[ -z ${ALL_DISKS} ]]   if [[ -z ${HDD} ]]
707   then   then
708   dialog_no_harddrive_found   dialog_no_harddrive_found
709   exit 1   exit 1
710   else   else
711   HDD=$(dialog_select_target_harddrive)   dialog_setup_hdd_info
712   retval=$?   setup_hdd_partitions
  [[ ${retval} -eq 1 ]] && return 1  
  if [[ ${retval} -eq 0 ]]  
  then  
  dialog_setup_hdd_info  
  setup_hdd_partitions  
  fi  
713   fi   fi
714  }  }
715    
# Line 558  run_install() Line 740  run_install()
740   local method="$1"   local method="$1"
741    
742   task_hardware_detection   task_hardware_detection
743     task_select_target_hdd
744    
745   case "${method}" in   case "${method}" in
746   auto)   auto)
747     if [[ ${FLASHDISK} = 1 ]]
748     then
749     export BOOTHDD="${HDD}1"
750     export SWAPHDD=""
751     export ROOTHDD="${HDD}2"
752     export FORMAT_FILESYSTEM_BOOTHDD="ext2"
753     export FORMAT_FILESYSTEM_ROOTHDD="f2fs"
754     else
755     # ext4 seems not to be compatible again
756     if [[ ${FORMAT_FILESYSTEM} = ext4 ]]
757     then
758     export BOOTHDD="${HDD}1"
759     export SWAPHDD=""
760     export ROOTHDD="${HDD}2"
761     export FORMAT_FILESYSTEM_BOOTHDD="ext2"
762     export FORMAT_FILESYSTEM_ROOTHDD="${FORMAT_FILESYSTEM}"
763     else
764     export BOOTHDD=""
765     export SWAPHDD=""
766     export ROOTHDD="${HDD}1"
767     export FORMAT_FILESYSTEM_BOOTHDD=""
768     export FORMAT_FILESYSTEM_ROOTHDD="${FORMAT_FILESYSTEM}"
769     fi
770     fi
771   export INSTALL_METHOD="${method}"   export INSTALL_METHOD="${method}"
772   ;;   ;;
773   normal)   normal)
774     export BOOTHDD="${HDD}1"
775     export SWAPHDD="${HDD}2"
776     export ROOTHDD="${HDD}3"
777     export FORMAT_FILESYSTEM_BOOTHDD="${FORMAT_FILESYSTEM}"
778     export FORMAT_FILESYSTEM_ROOTHDD="${FORMAT_FILESYSTEM}"
779     export INSTALL_METHOD="${method}"
780     ;;
781     single)
782     export BOOTHDD=""
783     export SWAPHDD=""
784     export ROOTHDD="${HDD}1"
785     export FORMAT_FILESYSTEM_BOOTHDD=""
786     export FORMAT_FILESYSTEM_ROOTHDD="${FORMAT_FILESYSTEM}"
787     export INSTALL_METHOD="${method}"
788     ;;
789     flash)
790     export BOOTHDD="${HDD}1"
791     export SWAPHDD=""
792     export ROOTHDD="${HDD}2"
793     export FORMAT_FILESYSTEM_BOOTHDD="ext2"
794     export FORMAT_FILESYSTEM_ROOTHDD="f2fs"
795   export INSTALL_METHOD="${method}"   export INSTALL_METHOD="${method}"
796   ;;   ;;
797   *)   *)

Legend:
Removed from v.2882  
changed lines
  Added in v.2948