Magellan Linux

Annotation of /alx-src/trunk/alxinstall-ng/bin/alxinstall-ng.sh.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 258 - (hide annotations) (download) (as text)
Mon Apr 18 19:01:41 2005 UTC (19 years ago) by niro
Original Path: alx-src/branches/unlabeled-1.1.1/alxinstall-ng/bin/alxinstall-ng.sh
File MIME type: application/x-sh
File size: 15657 byte(s)
iimport

1 niro 258 #!/bin/sh
2     #
3     # $Header: /home/cvsd/alx-cvs/alx-src/alxinstall-ng/bin/alxinstall-ng.sh,v 1.1.1.1 2005-04-18 19:01:41 niro Exp $
4     #
5     # AutoSta_LX Installation Script
6     # version: 0.8b
7     #
8     # Niels Rogalla <niro@magellan-linux.de>
9     # <rogalla@augusta-bochum.de>
10     #
11     #
12     # Install Navigation Gui
13     #
14    
15     #source /etc/alx_version
16     #source /opt/alx-config/version
17    
18     #source /etc/alx-config/config.rc
19    
20     #images: (get ${CDIMAGENAME})
21     source /mnt/cdrom/system/images.conf
22    
23     #Includes
24     source /usr/lib/alxinstall-ng/functions/findhdd.sh > /dev/null
25     ### bugfix ###############################
26     cdromdev="`echo $cdromdev|sed -e 's/ //'`"
27     ########################################
28    
29     ### System/Config Version
30     VERSION="0.1"
31     TITLE="alxinstall-ng - ${VERSION}"
32    
33     #CONFIGS_TEMPLATE="/opt/alx-config/configs"
34    
35     CDPATH="/mnt/cdrom"
36     INSTALLPATH="/mnt/magellan"
37    
38     ### WICHTIG: anzahl lines in der autosta_lx.tar.gz -1
39     CURRENTLINE=0
40     #TOTALLINES=11072 # -> now in images.conf
41    
42    
43     #################################################
44     # DIALOG BOXEN #
45     #################################################
46    
47     die() {
48     #clear
49     #echo -e "\nhuch, da ist ein script gestorben -> $?\n"
50     #read
51     #exit 0
52     ERROR=$1
53     RETVAL=$?
54     dialog_install_failure
55     exit 1
56     }
57    
58     dialog_warning() {
59     dialog \
60     --backtitle "$TITLE" \
61     --colors \
62     --defaultno \
63     --yesno "\Z1 !!! Achtung !!! \Zn\n\n\
64     Diese Festplatte wird unwiederruflich geloescht werden.\n\n\
65     Soll ich wirklich fortfahren ?" 10 70
66     RES=$?
67     if [ "$RES" == "1" ]
68     then
69     clear
70     echo "Der Vorgang wurde abgebrochen."
71     exit 1
72     fi
73     }
74    
75     dialog_setup_hdd_info(){
76     local SHDD="`echo $HDD|sed -e 's/\/dev\///'`"
77    
78     dialog \
79     --colors \
80     --title "[ Festplatten Partitionierung ]" \
81     --backtitle "$TITLE" \
82     --ok-label "Weiter" \
83     --msgbox "\nBitte legen Sie 3 Partitionen an.\n\n\
84     [ \Z3${SHDD}1\Zn ] Typ: \Z3Linux\Zn mit ca. 50MB\n\
85     [ \Z3${SHDD}2\Zn ] Typ: \Z3Linux Swap\Zn mit ca. 256MB\n\
86     [ \Z3${SHDD}3\Zn ] Typ: \Z3Linux \Zn mit dem Rest (min. 256MB)\n\n\
87     Bitte ${SHDD}1 als \Z3bootable\Zn markieren." 12 81
88     }
89    
90     dialog_setup_hdd_menu() {
91    
92     I=`dialog \
93     --backtitle "$TITLE" \
94     --title "[ Festplatten Partitionierung ]" \
95     --cancel-label "Abbrechen" \
96     --ok-label "Weiter" \
97     --stdout \
98     --menu "\nWaehlen Sie zwischen Manuell und Automatisch" 14 70 5 \
99     "1" "Manuell" \
100     "2" "Automatisch"`
101     RES=$?
102     if [ "$RES" == "1" ];then
103     return 1
104     fi
105     if [ "$RES" == "0" ];then
106     case "$I" in
107     "1")
108     dialog_setup_hdd_found_manuell
109     ;;
110     "2")
111     dialog_warning
112     setup_hdd_partitions_silent
113     ;;
114     esac
115     fi
116     }
117    
118     dialog_setup_hdd_found_manuell() {
119     if [ ! -z "$installdevs" ]
120     then
121     installdevs=""
122     fi
123    
124     echo "dialog \\" > /tmp/hddtmp.sh
125     echo "--backtitle \"$TITLE\" \\" >> /tmp/hddtmp.sh
126     echo "--ok-label \"Weiter\" \\" >> /tmp/hddtmp.sh
127     echo "--stdout \\" >> /tmp/hddtmp.sh
128     echo "--colors \\" >> /tmp/hddtmp.sh
129     echo "--msgbox \"Gefundene Hardware:\n\n \\" >> /tmp/hddtmp.sh
130     echo " Festplatten:\n \\" >> /tmp/hddtmp.sh
131    
132     if [ ! -z "$scsidisks" ]
133     then
134     for I in $scsidisks
135     do
136     if [ "$I" != "$cdromdev" ]
137     then
138     echo " \\Z7SCSI: \\Z3$I\\Zn\n \\" >> /tmp/hddtmp.sh
139     installdevs="$installdevs $I"
140     fi
141     done
142     fi
143    
144     if [ ! -z "$idedisks" ]
145     then
146     for I in $idedisks
147     do
148     if [ "$I" != "$cdromdev" ]
149     then
150     echo " \\Z7IDE: \\Z3$I\\Zn\n \\" >> /tmp/hddtmp.sh
151     installdevs="$installdevs $I"
152     fi
153     done
154     fi
155    
156     if [ ! -z "$cdromdev" ]
157     then
158     echo " \n \\" >> /tmp/hddtmp.sh
159     echo " \\Z7andere Laufwerke:\n \\" >> /tmp/hddtmp.sh
160     echo " CDROM: \\Z3$cdromdev\\Zn\n \\" >> /tmp/hddtmp.sh
161     fi
162     echo " \" 13 70" >> /tmp/hddtmp.sh
163     chmod a+x /tmp/hddtmp.sh
164     /tmp/hddtmp.sh
165     }
166    
167     dialog_setup_hdd_partitions_manuell() {
168     if [ -z "$installdevs" ]
169     then
170     dialog \
171     --backtitle "$TITLE" \
172     --ok-label "Beenden" \
173     --msgbox "Kein geeignetes Laufwerk gefunden.\nDie Installation ist fehlgeschlagen." 6 70
174     exit 1
175     else
176    
177     echo "dialog \\" > /tmp/hddtmp.sh
178     echo "--backtitle \"$TITLE\" \\" >> /tmp/hddtmp.sh
179     echo "--ok-label \"Weiter\" \\" >> /tmp/hddtmp.sh
180     echo "--cancel-label \"Beenden\" \\" >> /tmp/hddtmp.sh
181     echo "--stdout \\" >> /tmp/hddtmp.sh
182     echo "--menu \"Installations Laufwerk auswaehlen:\" 10 70 3 \\" >> /tmp/hddtmp.sh
183    
184     for I in $installdevs
185     do
186     echo "\"$I\" \"\" \\" >> /tmp/hddtmp.sh
187     done
188     echo -e "\n" >> /tmp/hddtmp.sh
189    
190     chmod a+x /tmp/hddtmp.sh
191     HDD="`/tmp/hddtmp.sh`"
192     RES=$?
193     if [ "$RES" == "1" ]
194     then
195     return 1
196     fi
197     if [ "$RES" == "0" ]
198     then
199     dialog_setup_hdd_info
200     setup_hdd_partitions_manuell
201     fi
202     fi
203     }
204    
205     dialog_setup_hdd_partitions_silent() {
206     dialog \
207     --backtitle "$TITLE" \
208     --infobox "Erstelle Partitionen ..." 3 70
209     }
210    
211     dialog_setup_hdd_format() {
212     dialog \
213     --backtitle "$TITLE" \
214     --infobox "Erstelle Datei-Systeme ..." 3 70
215     }
216    
217     dialog_install_settings() {
218     dialog \
219     --backtitle "$TITLE" \
220     --infobox "Speichere System-Einstellungen ..." 3 70
221     }
222    
223     dialog_install_system_image() {
224     dialog \
225     --backtitle "$TITLE" \
226     --gauge "Kopiere System-Image ..." 6 80
227     }
228    
229     dialog_install_meter() {
230     while [ "${CURRENTLINE}" != "${TOTALLINES}" ] ; do
231     CURRENTLINE=`grep --count . /tmp/install.log`
232     PERCENT=`expr ${CURRENTLINE} \* 100 / ${TOTALLINES}`
233     echo ${PERCENT}
234     sleep 1
235     done
236     rm -f /tmp/install.log
237     return 0
238     }
239    
240    
241     dialog_install_bootsector() {
242     dialog \
243     --backtitle "$TITLE" \
244     --infobox "Schreibe den Bootsektor ..." 3 70
245     }
246    
247     dialog_install_alxconfig() {
248     dialog \
249     --backtitle "$TITLE" \
250     --infobox "Installiere die ALX Setup-Tools ..." 3 70
251     }
252    
253     dialog_install_kernel_image() {
254     dialog \
255     --backtitle "$TITLE" \
256     --infobox "Installiere den System-Kernel ..." 3 70
257    
258     }
259    
260     dialog_install_hotfixes() {
261     dialog \
262     --backtitle "$TITLE" \
263     --infobox "Installiere Hotfixes ..." 3 70
264    
265     }
266    
267     dialog_install_successful() {
268     dialog \
269     --backtitle "$TITLE" \
270     --colors \
271     --msgbox "Die Installation war \Z2erfolgreich\Zn." 5 81
272     }
273    
274     dialog_install_failure() {
275     dialog \
276     --backtitle "$TITLE" \
277     --colors \
278     --msgbox "Die Installation ist \Z1Fehlgeschlagen\Zn.\n\n\
279     Fehler bei $ERROR, RetVal: $RETVAL \
280     " 10 81
281     }
282    
283     dialog_install_method() {
284    
285     METHOD=`dialog \
286     --backtitle "$TITLE" \
287     --cancel-label "Abbrechen" \
288     --ok-label "Weiter" \
289     --stdout \
290     --menu "Konfiguration" 14 70 5 \
291     "1" "Normale Installation" \
292     "2" "Silent Installation"`
293     RES=$?
294     if [ "$RES" == "1" ];then
295     return 1
296     fi
297     if [ "$RES" == "0" ];then
298     case "$METHOD" in
299     "1")
300     run_install_normal
301     ;;
302     "2")
303     dialog_warning
304     run_install_silent
305     ;;
306     esac
307     fi
308     }
309    
310     dialog_main() {
311     METHOD=0
312    
313     while [ $METHOD -le 2 ]
314     do
315     METHOD=`dialog \
316     --backtitle "$TITLE" \
317     --no-cancel \
318     --ok-label "Weiter" \
319     --stdout \
320     --menu "Konfiguration" 14 70 5 \
321     "1" "AutoSta_LX installieren" \
322     "2" "Uebersicht gefundener Laufwerke" \
323     "3" "Beenden und neustarten" \
324     "4" "Beenden ohne neustarten" `
325     RES=$?
326     if [ "$RES" == "1" ];then
327     exit 1
328     fi
329     if [ "$RES" == "0" ];then
330     case "$METHOD" in
331     "1")
332     #only for now later it will be used again
333     #with 6.1-r2 only one install method available
334     #dialog_install_method
335     run_install_normal
336     ;;
337     "2") dialog_setup_hdd_found_manuell
338     ;;
339     "3") install_do_reboot
340     ;;
341     esac
342     fi
343     done
344     }
345    
346     #################################################
347     # Install Komandos #
348     #################################################
349     setup_hdd_partitions_manuell() {
350     BOOTHDD="${HDD}1"
351     SWAPHDD="${HDD}2"
352     ROOTHDD="${HDD}3"
353    
354     ## hdds partitionieren manuell
355     cfdisk $HDD || die
356     }
357    
358     setup_hdd_partitions_silent() {
359     ## hdds löschen
360     dd if=/dev/zero of=$HDD bs=1024k count=1 || die
361     ## hdds partitionieren silent
362     fdisk $HDD < $CONFIGS_TEMPLATE/fdisksettings #1> /dev/null 3> /dev/null || die
363    
364     read
365     }
366    
367     setup_hdd_format() {
368     mkswap $SWAPHDD || die
369     mke2fs -j -q $BOOTHDD || die
370     mke2fs -j -q $ROOTHDD || die
371     }
372    
373     install_mount_rootfs() {
374     swapon $SWAPHDD || die
375     mount $ROOTHDD $INSTALLPATH || die
376     install -d $INSTALLPATH/boot || die
377     mount $BOOTHDD $INSTALLPATH/boot || die
378     cd $INSTALLPATH || die
379     }
380    
381     install_system_image() {
382     #tar xvzpf $CDPATH/system/autosta_lx.tar.gz
383     tar xvjpf ${CDPATH}/system/${CDIMAGENAME} -C ${INSTALLPATH}
384     }
385    
386    
387     install_kernel_image() {
388     declare -i CPUTYPE=`cat /proc/cpuinfo |grep "cpu family"|cut -d ' ' -f3`
389    
390     if [ $CPUTYPE -le 5 ];then
391     #echo -e "\033[1;6m\033[36m""i386 Architektur gefunden.""\033[0m"
392     #echo -e "Installiere i386 Kernel..."
393    
394     lastdir="`pwd`"
395    
396     mkdir -p $INSTALLPATH/INSTALL/kernel || die
397     cd $INSTALLPATH/INSTALL/kernel || die
398     tar xzpf $CDPATH/kernels/kernel-i386.tar.gz || die
399     source $INSTALLPATH/INSTALL/kernel/kernelversion || die
400    
401     cp -aRf $INSTALLPATH/INSTALL/kernel/$KRNLIB $INSTALLPATH/lib/modules || die
402     cp -aRf $INSTALLPATH/INSTALL/kernel/$KRNIMG $INSTALLPATH/boot || die
403     cp -aRf $INSTALLPATH/INSTALL/kernel/$KRNINITRD $INSTALLPATH/boot || die
404     cp -aRf $INSTALLPATH/INSTALL/kernel/kernelversion $INSTALLPATH/boot || die
405    
406     cd $lastdir || die
407    
408     elif [ $CPUTYPE -ge 6 ];then
409     #echo -e "\033[1;6m\033[36m""i686 Architektur gefunden.""\033[0m"
410     #echo -e "Installiere i686 Kernel..."
411    
412     lastdir="`pwd`"
413    
414     mkdir -p $INSTALLPATH/INSTALL/kernel || die
415     cd $INSTALLPATH/INSTALL/kernel || die
416     tar xzpf $CDPATH/kernels/kernel-i686.tar.gz || die
417     source $INSTALLPATH/INSTALL/kernel/kernelversion || die
418    
419     cp -aRf $INSTALLPATH/INSTALL/kernel/$KRNLIB $INSTALLPATH/lib/modules || die
420     cp -aRf $INSTALLPATH/INSTALL/kernel/$KRNIMG $INSTALLPATH/boot || die
421     cp -aRf $INSTALLPATH/INSTALL/kernel/$KRNINITRD $INSTALLPATH/boot || die
422     cp -aRf $INSTALLPATH/INSTALL/kernel/kernelversion $INSTALLPATH/boot || die
423    
424     cd $lastdir || die
425     fi
426     }
427    
428     install_bootsector() {
429     ### grubconf schreiben
430     source $INSTALLPATH/INSTALL/kernel/kernelversion
431    
432     if [ -z $KRNVER ]
433     then
434     KRNVER="AutoSta_LX"
435     fi
436    
437     if [ -z $KRNIMG ]
438     then
439     KRNIMG="bzImage"
440     fi
441    
442     if [ -z $KRNINITRD ]
443     then
444     KRNINITRD="initrd"
445     fi
446    
447     echo -e "default 0" > $INSTALLPATH/boot/grub/grub.conf || die
448     echo -e "timeout 03" >> $INSTALLPATH/boot/grub/grub.conf ||die
449     #no support for splash image in 6.1-r2
450     #echo -e "splashimage=(hd0,0)/boot/grub/splash.xpm.gz" >> $INSTALLPATH/boot/grub/grub.conf || die
451     echo -e "\ntitle=${KRNVER}" >> $INSTALLPATH/boot/grub/grub.conf || die
452     echo -e "root (hd0,0)" >> $INSTALLPATH/boot/grub/grub.conf || die
453    
454     #s3 cards don't support this
455     #echo -e "kernel (hd0,0)/boot/${KRNIMG} root=$ROOTHDD vga=0x317 video:vesa:ywrap,mtrr splash=silent quiet" >> $INSTALLPATH/boot/grub/grub.conf || die
456     #that's more safer:
457     echo -e "kernel (hd0,0)/boot/${KRNIMG} root=$ROOTHDD quiet" >> $INSTALLPATH/boot/grub/grub.conf || die
458    
459     #not needed without bootsplash support
460     #echo -e "initrd=/boot/${KRNINITRD}" >> $INSTALLPATH/boot/grub/grub.conf || die
461    
462     ### bootsector schreiben
463     #grub --no-floppy < $CONFIGS_TEMPLATE/grubsettings || die
464     /sbin/grub --no-floppy --batch << "EOF" 1> /dev/null 2> /dev/null || die
465     root (hd0,0)
466     setup (hd0)
467     quit
468     EOF
469     }
470    
471     install_bootsector_chroot() {
472     ### grubconf schreiben
473     #source $INSTALLPATH/INSTALL/kernel/kernelversion
474     source $INSTALLPATH/boot/kernelversion
475    
476     #for alx only
477     if [ -e ${INSTALLPATH}/etc/alx_version ]
478     then
479     OLD_ALXVER="${ALXVER}"
480     source ${INSTALLPATH}/etc/alx_version
481     KRNVER="ALX-${ALXVER}"
482     ALXVER="${OLD_ALXVER}"
483     fi
484    
485     if [ -z "$KRNVER" ]
486     then
487     KRNVER="AutoSta_LX"
488     fi
489    
490     if [ -z "$KRNIMG" ]
491     then
492     KRNIMG="bzImage"
493     fi
494    
495     if [ -z "$KRNINITRD" ]
496     then
497     KRNINITRD="initrd"
498     fi
499    
500     echo -e "default 0" > $INSTALLPATH/boot/grub/grub.conf || die
501     echo -e "timeout 03" >> $INSTALLPATH/boot/grub/grub.conf ||die
502    
503     #no support for splash image in 6.1-r2
504     #echo -e "splashimage=(hd0,0)/boot/grub/splash.xpm.gz" >> $INSTALLPATH/boot/grub/grub.conf || die
505    
506     echo -e "\ntitle=${KRNVER}" >> $INSTALLPATH/boot/grub/grub.conf || die
507     echo -e "root (hd0,0)" >> $INSTALLPATH/boot/grub/grub.conf || die
508    
509     #s3 cards don't support this
510     #echo -e "kernel (hd0,0)/boot/${KRNIMG} root=$ROOTHDD vga=0x317 video:vesa:ywrap,mtrr splash=silent quiet" >> $INSTALLPATH/boot/grub/grub.conf || die
511     #that's more safer:
512     echo -e "kernel (hd0,0)/boot/${KRNIMG} root=$ROOTHDD quiet" >> $INSTALLPATH/boot/grub/grub.conf || die
513    
514     #not needed without bootsplash support
515     #echo -e "initrd=/boot/${KRNINITRD}" >> $INSTALLPATH/boot/grub/grub.conf || die
516    
517    
518     ### bootsector schreiben chrooted schreiben (gentoo)
519     if [ -f $INSTALLPATH/sbin/grub ]
520     then
521     cat > $INSTALLPATH/root/.bashrc << CHROOTEOF
522     /sbin/grub --no-floppy --batch << "EOF" 1> /dev/null 2> /dev/null
523     root (hd0,0)
524     setup (hd0)
525     quit
526     EOF
527     exit
528     CHROOTEOF
529     fi
530    
531     ### bootsector schreiben chrooted schreiben (lfs/magellan)
532     if [ -f $INSTALLPATH/usr/sbin/grub ]
533     then
534     cat > $INSTALLPATH/root/.bashrc << CHROOTEOF
535     /usr/sbin/grub --no-floppy --batch << "EOF" 1> /dev/null 2> /dev/null
536     root (hd0,0)
537     setup (hd0)
538     quit
539     EOF
540     exit
541     CHROOTEOF
542     fi
543    
544     ##enters chroot
545     mount -t proc proc $INSTALLPATH/proc
546     chroot $INSTALLPATH /bin/bash
547     umount $INSTALLPATH/proc
548     rm $INSTALLPATH/root/.bashrc
549     }
550    
551     install_alxconfig(){
552     lastdir="`pwd`"
553    
554     mkdir -p $INSTALLPATH/opt/alx-config || die
555     cd $INSTALLPATH/opt/alx-config || die
556     tar xzpf $CDPATH/alx-config/alx-config.tar.gz || die
557     chmod a+x $INSTALLPATH/opt/alx-config/Configurator/config_functions.sh || die
558     chmod a+x $INSTALLPATH/opt/alx-config/Configurator/config_menu.sh || die
559     ln -sf /opt/alx-config/Configurator/config_menu.sh $INSTALLPATH/bin/ALXConfig || die
560    
561     cd $lastdir || die
562     }
563    
564    
565     install_system_settings(){
566     ### schreibe fstab
567     echo -e "$BOOTHDD\t/\text3\tnoatime,noauto\t1 1" > $INSTALLPATH/etc/fstab || die
568     echo -e "$ROOTHDD\t/\text3\tnoatime\t0 0" >> $INSTALLPATH/etc/fstab || die
569     echo -e "$SWAPHDD\tswap\tswap\tpri=1\t0 0" >> $INSTALLPATH/etc/fstab || die
570     echo -e "none\t/proc\tproc\tdefaults\t0 0" >> $INSTALLPATH/etc/fstab || die
571    
572     #deprecated
573     #echo -e "devpts\t/dev/pts\tdevpts\tgid=4,mode=620\t0 0" >> $INSTALLPATH/etc/fstab || die
574    
575     echo -e "none\t/dev/shm\ttmpfs\tdefaults\t0 0" >> $INSTALLPATH/etc/fstab || die
576     echo -e "none\t/proc/bus/usb\tusbfs\tdefaults\t0 0" >> $INSTALLPATH/etc/fstab || die
577     }
578    
579     install_hotfixes(){
580     if [ -f $CDPATH/hotfixes/hotfixes.sh ]
581     then
582     dialog_hotfixes
583     sleep1
584     $CDPATH/hotfixes/hotfixes.sh
585     fi
586     }
587    
588     install_umount_rootfs() {
589     cd /
590     umount $INSTALLPATH/boot || die
591     umount $INSTALLPATH || die
592     swapoff $SWAPHDD || die
593     }
594    
595     install_do_reboot() {
596    
597     #only for now later it will be used again
598     #with 6.1-r2 these options are not available
599     #cd /
600     #umount $CDPATH
601     #eject
602     #clear
603    
604     reboot
605     }
606    
607     #################################################
608     # Install Ablauf Scripte #
609     #################################################
610    
611     run_install_normal() {
612     #only for now later it will be used again
613     #with 6.1-r2 only one install method available
614     #dialog_setup_hdd_menu
615     dialog_setup_hdd_found_manuell
616    
617     dialog_setup_hdd_partitions_manuell
618     dialog_setup_hdd_format
619     setup_hdd_format > /dev/null
620     install_mount_rootfs
621     (install_system_image > /tmp/install.log) 2> /tmp/install_errors.log | dialog_install_meter | dialog_install_system_image
622    
623     #only for now later it will be used again
624     #with 6.1-r2 variable kernels are not available
625     #dialog_install_kernel_image
626     #install_kernel_image
627    
628     dialog_install_bootsector
629     install_bootsector_chroot
630    
631     #only for now later it will be used again
632     #with 6.1-r2 highest version of alx-config is already included
633     #dialog_install_alxconfig
634     #sleep 1
635     #install_alxconfig
636    
637     dialog_install_settings
638     sleep 1
639     install_system_settings
640     install_hotfixes
641     install_umount_rootfs
642     dialog_install_successful
643     }
644    
645     run_install_silent() {
646     echo "starting silent install ..."
647     sleep 1
648     }
649    
650     run_install_unattended() {
651     echo "starting unattended install ..."
652     sleep 1
653     }
654    
655     if [ "$1" == "unattended" ]
656     then
657     run_install_unattended
658     else
659     dialog_main
660     fi
661    
662     exit 0