#!/bin/ash

#echo "Sucht zur Installierung freien Platz auf der Festplatte oder  Partitionen die abgeschnitten werden können"
echo " 1. Freien Platz finden oder grsste bestehende Partition kleiner machen"



# Aufruf durch  init 

#                                                                  (c) 2007 werner@copaya.yi.org  

#ls / 


STATUS=-3                                    #   -2  kein Platz da    -1 Platz da, Part. ist zu machen     1 Partition fertig

# 0. Neu zu machende Partition
SIZEMIN=200000          #  in Sektoren
read TST SIZE REST < installinfo      # Uebergabe von aussen 

echo "SIZE: " $SIZE  " SIZEMIN " $SIZEMIN
test $(($SIZE - $SIZEMIN)) -gt 0 ;   if test $? -ne 0 ;  then SIZE=$SIZEMIN ; fi ;
echo " *** Neue Partition Bloecke:  "  $SIZE   $SIZEMIN      


# 1. Partitionstafel erhalten
#         Format von parted:  Nr, Anfg, Ende, Groesse, primary/extended, typ/filesystem, ifbootflag

/sbin/parted -ls > parts0                     #/sbin/parted /dev/hda unit s  print  ;   /sbin/parted /dev/hda mkpart p ext3 0 1G   

echo " vorhandene Partitionen: "
cat parts0
grep -e "/dev/sda" parts0
#/sbin/parted /dev/sda print 
if test $? -eq 0  ;  then NACH0=/dev/sda ; fi ;
grep -e "/dev/hda" parts0
#/sbin/parted /dev/hda print 
if test $? -eq 0  ;  then NACH0=/dev/hda ; fi ;
echo " Device benutzen: "  $NACH0
/sbin/parted -s $NACH0  unit s print 



#echo "Part.Tafel von " $NACH0 
#/sbin/parted -s $NACH0 unit s  print 
/sbin/parted -s $NACH0 unit s  print > parts0 
grep -e "Disk" parts0 > scr
sed 's/s/ /g'  scr > tmp0
read A1 A2 A3 DISKSIZE REST < tmp0     # size in Sektoren
#echo "Harddisk Groesse: "   $DISKSIZE 

grep "primary" parts0 > parts          # parts enthaelt nur Partitionen 1-4 
grep "extended" parts0 >> parts


# 2. Feststellen ob/wo grösster freier Platz auf Platte vh

echo " *** groesste freie Luecke auf Platte " $NACH0 " suchen :    *** "
sort -n -k 2 parts > parts0        #  Nach phys. Reihenfolge auf Platte geordnet, nicht nach Nr.  
#echo "Partitionen nach Reihenfolge auf Platte sortiert: "
cat parts0
sed 's/s/ /g'  parts0 > partitions
#echo " Nach Loeschen des Textes:"
#cat tmp0
A1=0 ; A2=0 ; A3=0 ; A4=0 ; X1=1 ; X2=1 ; X3=1 ; X4=1 ; Y1=1 ; Y2=1 ; Y3=1 ; Y4=1
( read A1  X1  Y1  REST  ;  read A2  X2  Y2  REST  ;    read A3  X3  Y3  REST  ;  read A4  X4  Y4  REST  ;  
echo $A1 $X1 $Y1 $A2 $X2 $Y2 $A3 $X3 $Y3 $A4 $X4 $Y4 > tmp00 ) < partitions
read A1 X1 Y1 A2 X2 Y2 A3 X3 Y3 A4 X4 Y4 REST < tmp00

echo "Disk-Size: "  $DISKSIZE 
echo "Partitionen Nr/Anfg/Ende"  $A1 " " $X1 " " $Y1  "  ;  " $A2 " " $X2 " " $Y2 
echo "Partitionen Nr/Anfg/Ende"  $A3 " " $X3 " " $Y3  "  ;  " $A4 " " $X4 " " $Y4  

#  Zu jeder Partition J den vorigen J-1 und den folgenden J Zwischenraum bestimmen:
#echo " Bestimmung der freien Stellen auf der Platte: "
EINS=1 
Y0=0
ZA0=$(($Y0+$EINS)) ; ZE0=$DISKSIZE ; Z0=$(($DISKSIZE-$Y0))
test $A1 -gt 0 ; if test $? -eq 0 ;  then ZE0=$(($X1-$EINS)) ; Z0=$(($X1-$Y0-$EINS)) ; ZA1=$(($Y1+$EINS)) ; ZE1=$DISKSIZE ; Z1=$(($DISKSIZE-$Y1)) ; fi ;
echo " Luecke vor P.1: " $ZA0 $ZE0 $Z0   "    Groesse soll: "  $(($ZE0-$ZA0+$EINS)) 
test $A2 -gt 0 ; if test $? -eq 0 ;  then ZE1=$(($X2-$EINS)) ; Z1=$(($X2-$Y1-$EINS)) ; ZA2=$(($Y2+$EINS)) ; ZE2=$DISKSIZE ; Z2=$(($DISKSIZE-$Y2)) ; fi ;
echo " Luecke nach P.1: " $ZA1 $ZE1 $Z1  "    Groesse soll: "  $(($ZE1-$ZA1+$EINS)) 
test $A3 -gt 0 ; if test $? -eq 0 ;  then ZE2=$(($X3-$EINS)) ; Z2=$(($X3-$Y2-$EINS)) ; ZA3=$(($Y3+$EINS)) ; ZE3=$DISKSIZE ; Z3=$(($DISKSIZE-$Y3)) ; fi ;
echo " Luecke nach P.2: " $ZA2 $ZE2 $Z2  "    Groesse soll: "  $(($ZE2-$ZA2+$EINS))
test $A4 -gt 0 ; if test $? -eq 0 ;  then ZE3=$(($X4-$EINS)) ; Z3=$(($X4-$Y3-$EINS)) ; ZA4=$(($Y4+$EINS)) ; ZE4=$DISKSIZE ; Z4=$(($DISKSIZE-$Y4)) ; fi ;
echo " Luecke nach P.3: " $ZA3 $ZE3 $Z3  "    Groesse soll: "  $(($ZE3-$ZA3+$EINS))
echo " Luecke nach P.4: " $ZA4 $ZE4 $Z4  "    Groesse soll: "  $(($ZE4-$ZA4+$EINS))
echo " " > tmp2
echo  $Z0  "   "  $ZA0 "   " $ZE0      >> tmp2
echo  $Z1  "   "  $ZA1 "   " $ZE1  >> tmp2  
echo  $Z2  "   "  $ZA2 "   " $ZE2   >> tmp2
echo  $Z3  "   "  $ZA3 "   " $ZE3    >> tmp2
echo  $Z4  "   "  $ZA4 "   " $ZE4   >> tmp2   
echo "  Zwischenrume auf der Platte:  " 
echo $Z0 " ab " $ZA0  " ; " $Z1 " ab " $ZA1 " ; " $Z2 " ab " $ZA2 " ; "  $Z3 " ab " $ZA3 " ; "  $Z4 " ab " $ZA4   
#echo "Zw. unsortiert:"  ; cat  tmp2  
sort  -o tmp1 -r  -n  -k 1   tmp2           # Auf tmp1 sind jetzt die ZWISCHENRAEUME / FREIE BEREICHE nach Groesse sortieret
#echo "Zw. sortiert:" ; cat tmp1
read ZZ XX YY  REST < tmp1                    # Groesse, Anfang, Ende des groessten freien Platzes 
#ZZ=$(($YY-$XX+1))
echo " *** ::: Groesster freier Platz auf der HD:  Gr/von/bis  " $ZZ  "   "  $XX  "    "  $YY  


echo " *** kleinste  Nr. Part suchen die noch nicht benutzt ist:   *** "
# Falls alle 4 benutzt, wird hchste Part-Nr die nicht extended ist und nicht verkleinert wird, desaktiviert aber nicht gelscht   
sort -o tmp1  -n -k 1 partitions         # Auf tmp1 sind jetzt die PARTITIONEN nach Index / Nr.  geordnet  
echo "Partitionen nach Index/Part-Nr  geordnet:"  ; cat tmp1
(read A1 X1 Y1 Z1 ART1 SY1 REST ; read A2 X2 Y2 Z2 ART2 SY2 REST ;  read A3 X3 Y3 Z3  ART3 SY3 REST ;  read A4 X4 Y4 Z4 ART4 SY4 REST 
SY1=fs$SY1 ; SY2=fs$SY2 ; SY3=fs$SY3 ; SY4=fs$SY4            #  da extended keinen Wert haben, gaebe Probleme bei naechstem Lesen
echo $A1 $ART1 $SY1 $A2 $ART2 $SY2 $A3 $ART3 $SY3 $A4 $ART4 $SY4 > tmp00 ) < tmp1
read A1 ART1 SY1 A2 ART2 SY2 A3 ART3 SY3 A4 ART4 SY4 REST < tmp00
#echo "A1 ART1 A2 ART2 A3 ART3 A4 ART4 :" $A1 $ART1 $A2 $ART2 $A3 $ART3 $A4 $ART4 
EXTNR=5 ; NACHNR=1  ; WINDOWS=0              #  5 falls 1,2,3,4 schon da
echo " Part.4: "  $A4  " Art4: " $ART4  " Sy4: "  $SY4 
test $(($A1)) -gt 0 ; if test $? -eq 0 ; then   test $A1 = 1 ; if test $? -eq 0 ; then NACHNR=2 ; fi ;      
test $ART1 = "extended" ; if test $? -eq 0 ; then EXTNR=$A1 ; fi 
test $SY1 = "boot" ; if test $? -eq 0 ; then SY1=ntf ; fi  ; test $SY1 = "ntf" ; if test $? -eq 0 ; then WINDOWS=$A1  ; fi ;   fi ; 
test $(($A2)) -gt 0 ; if test $? -eq 0 ; then   test $A2 = 2 ; if test $? -eq 0 ; then NACHNR=3 ; fi ;      
test $ART2 = "extended" ; if test $? -eq 0 ; then EXTNR=$A2 ; fi 
test $SY2 = "boot" ; if test $? -eq 0 ; then SY2=ntf  ;  fi ; test $SY1 = "ntf" ; if test $? -eq 0 ; then WINDOWS=$A1  ; fi ;   fi ; 
test $(($A3)) -gt 0 ; if test $? -eq 0 ; then   test $A3 = 3 ; if test $? -eq 0 ; then NACHNR=4 ; fi ;      
test $ART3 = "extended" ; if test $? -eq 0 ; then EXTNR=$A3 ; fi 
test $SY3 = "boot" ; if test $? -eq 0 ; then SY3=ntf  ; fi ; test $SY1 = "ntf" ; if test $? -eq 0 ; then WINDOWS=$A1  ; fi ;   fi ; 
test $(($A4)) -gt 0 ; if test $? -eq 0 ; then   test $A4 = 4 ; if test $? -eq 0 ; then NACHNR=5 ; fi ;      
test $ART4 = "extended" ; if test $? -eq 0 ; then EXTNR=$A4 ; fi 
test $SY4 = "boot" ; if test $? -eq 0 ; then SY4=ntf  ; fi ; test $SY1 = "ntf" ; if test $? -eq 0 ; then WINDOWS=$A1  ; fi ;   fi ; 
if test $WINDOWS -ne 0 ; then  WINDOWS=$A1 ; fi ;       # WINDOWS ist kleinste Nr. der schon dagewesener Partitionen
echo " *** Nr. NACH: " $NACHNR  " Nr. extended: "  $EXTNR  "  Nr. Part. dagewesenes System: "  $WINDOWS " *** "  
echo $A1 $ART1 $SY1 $A2 $ART2 $SY2 $A3 $ART3 $SY3 $A4 $ART4 $SY4


# 3. Testen ob freier Platz ausreicht, sonst eine Partition kleiner machen

#echo " max. Zwischenraum auf Disk: "  $ZZ "  Groesse der zu machenden Partition:  "  $SIZE   "  Zylinder"
if test $ZZ -lt $SIZE  ;   then   STATUS="-2"  ; fi ;  #  echo " vhd. Partition kleiner machen:  "  ;  
if test $ZZ -ge $SIZE  ;   then   STATUS="-1"  ; fi ;  # echo " *** Platz reicht um neue Partition zu machen *** " ;  


echo " STATUS, -2 falls Part. kleiner zu machen, -1 falls Platz vhd:  "    $STATUS


if test $STATUS = "-2"  ;  then  
# 4.1  Disk voll, erst eine Partition kleiner machen

sort -o parts -r -n -k 4  partitions    # PARTIONEN nach Groesse sortiert      Achtung um s bereinigt

cat parts > parts0             # nachfolgendes Sortieren nach Art abgeschaltet, gibt Probleme:   strikt nach Groesse sortieren
#grep "ntf" parts > parts0             # Prioritt für ggf. zu verkleinernde Partitionen wenn Platz gebraucht wird
#grep "fat" parts >> parts0
#grep "ext4" parts >> parts0         # nicht ext da dies fuer extended partitions
#grep "ext3" parts >> parts0
#grep "ext2" parts >> parts0
#grep "reiser" parts >> parts0
#grep "boot" parts >> parts0         # da parted bld ist, achtung falls filesys definiert kommt diese Zeile doppelt
#grep "lba" parts >> parts0          # extended Partitions
####sort -o tmp0 -r  -k 5  parts0          # extended nachrangig primary
cat parts0 > tmp0                          # momentan abgeschaltet da sonst Probleme wenn ausser der extended eine zu kleine primaere vhd
#cat  parts >> tmp0                 #  Vorsorge falls nichts gefunden wurde: nochmal parts anhaengen.   parts, parts0 unveraendert     


#echo " Kandidaten fuer verkleinernde Partitionen, Reihenfolge: " ; cat tmp0

read KLEINERNR S1 S2  SIZE0 KLEINERART KLEINERFS REST < tmp0   
echo " Kandidat der zu verkleinernden Partition: " $KLEINERNR $S1 $S2 $SIZE0 $KLEINERART $KLEINERFS $REST
echo " *** Ob kleinerzumachende Partition / deren Groesse definiert: " $(($SIZE0))  "  Benoetigt / neue Part.: "  $SIZE
#test $(($SIZE0)) -gt 0  ;  if test $? -ne 0 ; then   read KLEINERNR S1 S2  SIZE0 KLEINERART KLEINERFS REST < parts ; fi ;   
#Ganz sicherheitshalber mehrere Abfragen nebeneinander, jede führt zur Vorgabe der KLEINER-Partition:
test $(($KLEINERNR)) -gt 0  ;  if test $? -ne 0 ; then  KLEINERNR=$A1 ; S1=$X1 ; S2=$Y1 ; SIZE0=$Z1 ; KLEINERART=$ART1 ; KLEINERFS=$SY1  ; fi ;   
test $(($SIZE0)) -gt 0  ;  if test $? -ne 0 ; then  KLEINERNR=$A1 ; S1=$X1 ; S2=$Y1 ; SIZE0=$Z1 ; KLEINERART=$ART1 ; KLEINERFS=$SY1  ; fi ;   
test $(($S2)) -gt 0  ;  if test $? -ne 0 ; then  KLEINERNR=$A1 ; S1=$X1 ; S2=$Y1 ; SIZE0=$Z1 ; KLEINERART=$ART1 ; KLEINERFS=$SY1  ; fi ;   


KLEINER=$NACH0$KLEINERNR
echo " Partition verkleinern: "  $KLEINER  "    "  $KLEINERNR  "  Sektor Anfg, Ende,  Bloecke: "  $S1 "  " $S2 "  " $SIZE0
echo " Part-Art: "  $KLEINERART  "Filesystem:  "  $KLEINERFS

# Neuer freier Platz von XX bis YY
YY=$S2
EINS=1
XX=$(($YY-$SIZE))
S2=$(($XX-$EINS))

echo " *** Zum Einrichten einer neuen Partition wird eine bestehende verkleinert *** "
echo "verkleinerte Partition: Platte, Name, Nr, Track von bis: " $NACH0 "  "  $KLEINER "  " $KLEINERNR  "    "  $S1  "   "  $S2  
echo " Danach freier Bereich von: " $XX "  bis: " $YY 
SIZEKLEINER=$(($S2-$S1)) ; SIZEKLEINER=$(($SIZEKLEINER / 2))k
echo " zu verkleinernden Partition / neue Groesse: "  $KLEINER "   " $SIZEKLEINER   "   in k ;   Filesystem: "  $KLEINERFS 

echo " *** Beginn Verkleinern von Dateisystem auf: " $KLEINER " *** "
echo " *** freigeben: "
umount $KLEINER  
echo " *** freigegeben, verkleinern: "
IFR=0
#/sbin/parted -s $NACH0 unit s resize $KLEINERNR $S1 $S2   # das funktioniert fast nie, daher:
test $KLEINERFS = fsext2 ; if test $? -eq 0 ; then resize2fs -f -p $KLEINER $SIZEKLEINER ; IFR=1 ; echo "EXT2"; fi ;      # geht nicht mit Sektoren
test $KLEINERFS = fsext3 ; if test $? -eq 0 ; then resize2fs -f -p $KLEINER $SIZEKLEINER ; IFR=1 ;echo "EXT3" ; fi ;    # geht nicht mit Sektoren
test $KLEINERFS = fsext4 ; if test $? -eq 0 ; then resize2fs -f -p $KLEINER $SIZEKLEINER ; IFR=1 ;echo "EXT4" ; fi ;      # geht nicht mit Sektoren
test $KLEINERFS = fsext4dev ; if test $? -eq 0 ; then resize2fs -f -p $KLEINER $SIZEKLEINER ; IFR=1 ;echo "EXT4DEV" ; fi ;      # geht nicht mit Sektoren
test $KLEINERFS = fsreiserf ; if test $? -eq 0 ; then resize_reiserfs -s  $SIZEKLEINER -f $KLEINER ; IFR=1 ;echo "REISERFS" ; fi ;
test $IFR = 0 ; if test $? -eq 0 ; then ntfsfix $KLEINER  ;  ntfsresize -f -s $SIZEKLEINER  $KLEINER ; IFR=1 ;echo "NTFS"; fi ;
sync
echo " *** Partition "  $KLEINER " loeschen, egal ob FS verkleinern erfolgreich oder nicht: "
/sbin/parted -s $NACH0 rm $KLEINERNR                       #  Partition hinten absbeln egal ob Filesystem verkleinert oder nicht
echo " *** "  $KLEINER " verkleinert neu machen :"
echo "          parted Aufruf mit File-System:  "  $KLEINERFS  " Bereich fuer KLEINER: "  $S1  $S2 
/sbin/parted -s $NACH0 unit s mkpart $KLEINERART  $S1 $S2 ; 
echo " *** "  $KLEINER  " neu gemacht.    Situation jetzt:  " 
/sbin/parted -s $NACH0  unit s print 
####STATUS="-1"    # da nachfolgendes ebenfalls durchlaufen
fi ;    

echo "Nach evtl. Platz machen:  status, Platte, nachnr, extendednr, kleinernr: "  $STATUS $NACH0  $NACHNR  $EXTNR  $KLEINERNR
echo "KLEINER: " $KLEINERNR  "kleiner, sizekleiner, syskleinernr"   $KLEINER    $SIZEKLEINER   $SYS$KLEINERNR


####if test $STATUS = "-1"  ;  then  
# 4.2 Nr.  NACHNR  der neuen Partition definitiv festlegen
 if test $NACHNR = 5 ; then
  NACHNR=4 ; if test $NACHNR = $EXTNR ; then NACHNR=3 ; fi ;
echo " schon 4 Part. vhd: vhd. Partition" $NACHNR " wird in fdisk ausgeschaltet, um Nr. fr neue Part. zu benutzen, "
echo " wird aber nicht gelscht und kann durch Eintippen ihrer Grenzen in fdisk wieder benutzt werden" 
    if test $NACHNR -eq $KLEINERNR ; then  NACHNR=$(($NACHNR-$EINS)) ; fi ;
  /sbin/parted -s $NACH0 rm $NACHNR
 fi ;
 NACH=$NACH0$NACHNR

echo "nach definitiver Nr. fuer neue Part.: status, Platte, nachnr, extnr, kleinernr: "  $STATUS  $NACH0 $NACHNR  $EXTNR  $KLEINERNR


# 4.3 Partition für die Installierung machen
XX=$(($XX+128)) ; YY=$(($YY-128))                   # sicherbeitshalber ...
echo " *** Platte / Partition machen:  NACH0 , NACHNR , NACH  " $NACH0 "  "  $NACHNR "   "  $NACH   " *** " 
echo " *** Groesse von/bis XX , YY : "  $XX  "   "  $YY  " , wurde sicherheitshalber um +/- 128 verkleinert "
# Partition NACHNR machen:
/sbin/parted -s $NACH0  unit s mkpart primary   $XX $YY 
echo "          parted Aufruf mit:  "  $NACH0  " Bereich fuer KLEINER: "  $XX  $YY 
sync
echo " *** "  $NACH  " neu gemacht.    Situation jetzt:  " 
/sbin/parted -s $NACH0  unit s print 
####fi ;


if test $STATUS = "-2"  ;  then  
echo " ******** testweise ******* als maximale Gewaehr: KLEINER loeschen, dann NACH nochmal machen lassen:  *********** "
#  Vorsicht falls man kleiner erst nach nach macht, ist die Nr. falsch
#  Einzige Lösung:  beide Partitionen löschen (NACHNR und KLEINERNR), und danach zuerst diejenige mit der kleineren Nr machen
/sbin/parted -s $NACH0 rm $KLEINERNR       
S100=$(($S1+256)) ; S200=$(($S1+1024)) ; /sbin/parted -s $NACH0 unit s mkpart $KLEINERART  $S100 $S200   # dummy wg Index   Hinterher reparieren
/sbin/parted -s $NACH0  unit s mkpart primary ext3  $XX $YY     # falls vorher erfolgreich gemacht, kein Problem
echo "          parted Aufruf mit:  "  $NACH0  " Bereich fuer KLEINER: "  $XX  $YY 
sync
echo " *** "  $NACH  " neu gemacht.    Situation jetzt:  " 
/sbin/parted -s $NACH0  unit s print 
echo " *** Versuch   KLEINER  wieder zu machen,  falls erfolgreich ist alles OK und dieses testweise unschaedlich "
/sbin/parted -s $NACH0 rm $KLEINERNR ;  /sbin/parted -s $NACH0 unit s mkpart $KLEINERART  $S1 $S2         
echo " ***   KLEINER   neu gemacht.    Situation jetzt:  " 
/sbin/parted -s $NACH0  unit s print 
echo " ************************ " 
fi ;

/sbin/parted -s $NACH0 set $NACHNR  boot on       # bootbar machen

# 4.4.  Hier ggf. nochmal Groesse ueberpruefen und wenn  wenn was nicht iO mit leicht geaenderten Bedingungen bzgl Groesse
#   o.ae. nach oben springen
#echo " *** INSTALL-DRIVE , DEVICE SOLLTEN JETZT DA SEIN:  "  $NACH0   "    "  $NACH  
#/sbin/parted -s $NACH  unit s  print
echo "Alle Partitionen: "
/sbin/parted -s $NACH0 unit s  print


# 5. Parameteruebergabe nach aussen
echo $TST " " $SIZE  "  "  $NACH0 "  " $NACH  "  " $VON "  "  $KLEINER " " $WINDOWS > installinfo 
echo "neue Partition: Platte,  Name, Nr, Track von bis:   " $NACH0 "  "  $NACH "  " $NACHNR  "    "  $XX  "   "  $YY  

sync 

STATUS="1" 

echo " *** Ende mkpart " 


