home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd2.bin / suse / inst-sys / lib / YaST2 / clients / inst_custom_part.ycp < prev    next >
Encoding:
Text File  |  2000-03-30  |  123.0 KB  |  3,066 lines

  1. /*
  2.  *************************************************************
  3.  *
  4.  *     YaST2      SuSE Labs                        -o)
  5.  *     --------------------                        /\\
  6.  *                                                _\_v
  7.  *           www.suse.de / www.suse.com
  8.  * ----------------------------------------------------------
  9.  *
  10.  * Author:        Michael Hager <mike@suse.de>
  11.  *
  12.  * Description:   Partitioner for experts.
  13.  *
  14.  *
  15.  * Purpose:
  16.  *                      -Determing possible partitions.
  17.  *                      -Ask the user which partition to use.
  18.  *                      -Check the input and return error-messages.
  19.  *                      -Writing user_settings with the selected partitions.
  20.  *
  21.  * user_settings:       used:   targets
  22.  *                      used:   architecture
  23.  *
  24.  * external function:   get_partition_info: get a list of current partitions
  25.  *                      check4partitions:   read the disk-information 
  26.  *
  27.  *************************************************************
  28.  
  29.  $Id: inst_custom_part.ycp,v 1.46.4.3 2000/03/27 15:29:21 kkaempf Exp $
  30.  
  31.  
  32. HINTS: Always use
  33.          lookup( part, "delete", false)
  34.          lookup( part, "create", false)
  35.        instead of
  36.          lookup( part, "delete")
  37.          lookup( part, "create")
  38.        cause delete, create are not always set to false
  39.  
  40. */
  41. {
  42.   // fall through to next step if target_is NOT custom
  43.  
  44.   if (lookup(user_settings, "target_is", "CUSTOM") != "CUSTOM")
  45.         return `auto;
  46.  
  47.   symbol fdisk_type = `intel;   // At the moment this partitioner is for intel only
  48.   string architecture = lookup( user_settings, "architecture", default_architecture);
  49.  
  50.   UI(``{  define FsIdToString( integer fs_id )
  51.   ``{
  52.           if ( fs_id == 0xa7) return( " NeXTSTEP      ");
  53.           if ( fs_id == 0xb7) return( " BSDI fs       ");
  54.           if ( fs_id == 0xb8) return( " BSDI swap     ");
  55.           if ( fs_id == 0xc1) return( " DRDOS/sec     ");
  56.           if ( fs_id == 0xc4) return( " DRDOS/sec     ");
  57.           if ( fs_id == 0xc6) return( " DRDOS/sec     ");
  58.           if ( fs_id == 0xc7) return( " Syrinx        ");
  59.           if ( fs_id == 0xdb) return( " CP/M / CTOS   ");
  60.           if ( fs_id == 0xe1) return( " DOS access    ");
  61.           if ( fs_id == 0xe3) return( " DOS R/O       ");
  62.           if ( fs_id == 0xe4) return( " SpeedStor     ");
  63.           if ( fs_id == 0xeb) return( " BeOS fs       ");
  64.           if ( fs_id == 0xf1) return( " SpeedStor     ");
  65.           if ( fs_id == 0xf4) return( " SpeedStor     ");
  66.           if ( fs_id == 0xf2) return( " DOS secondary ");
  67.           if ( fs_id == 0xfd) return( " Linux raid    ");
  68.           if ( fs_id == 0xfe) return( " LANstep       ");
  69.           if ( fs_id == 0xff) return( " BBT           ");
  70.           if ( fs_id == 0x0) return( " empty          ");
  71.           if ( fs_id == 0x1) return( " FAT12         ");
  72.           if ( fs_id == 0x2) return( " XENIX root    ");
  73.           if ( fs_id == 0x3) return( " XENIX usr     ");
  74.           if ( fs_id == 0x4) return( " FAT16 <32M    ");
  75.       // description for the partition typ in the patition table
  76.           if ( fs_id == 0x5) return( _("Extended"));
  77.           if ( fs_id == 0x6) return( " FAT16         ");
  78.           if ( fs_id == 0x7) return( " HPFS/NTFS     ");
  79.           if ( fs_id == 0x8) return( " AIX           ");
  80.           if ( fs_id == 0x9) return( " AIX boot      ");
  81.           if ( fs_id == 0xa) return( " OS/2 boot manager");
  82.           if ( fs_id == 0xb) return( " Win95 FAT32   ");
  83.           if ( fs_id == 0xc) return( " Win95 FAT32   ");
  84.           if ( fs_id == 0xe) return( " Win95 FAT16   ");
  85.           if ( fs_id == 0xf) return( " Win95 Erw. LBA");
  86.           if ( fs_id == 0x10) return( " OPUS          ");
  87.           if ( fs_id == 0x11) return( " Verst. FAT12  ");
  88.           if ( fs_id == 0x12) return( " Compaq diag");
  89.           if ( fs_id == 0x14) return( " Verst. FAT16  ");
  90.           if ( fs_id == 0x16) return( " Verst. FAT16  ");
  91.           if ( fs_id == 0x17) return( " Verst. HPFS/NTFS");
  92.           if ( fs_id == 0x18) return( " AST Windows   ");
  93.           if ( fs_id == 0x1b) return( " Verst. Win95  ");
  94.           if ( fs_id == 0x1c) return( " Verst. Win95  ");
  95.           if ( fs_id == 0x1e) return( " Verst. Win95  ");
  96.           if ( fs_id == 0x24) return( " NEC DOS       ");
  97.           if ( fs_id == 0x3c) return( " PartitionMagic");
  98.           if ( fs_id == 0x40) return( " Venix 80286   ");
  99.           if ( fs_id == 0x41) return( " PPC PReP Boot ");
  100.           if ( fs_id == 0x42) return( " SFS           ");
  101.           if ( fs_id == 0x4d) return( " QNX4.x        ");
  102.           if ( fs_id == 0x4e) return( " QNX4.x 2nd par");
  103.           if ( fs_id == 0x4f) return( " QNX4.x 3rd par");
  104.           if ( fs_id == 0x50) return( " OnTrack DM    ");
  105.           if ( fs_id == 0x51) return( " OnTrack DM6 Au");
  106.           if ( fs_id == 0x52) return( " CP/M          ");
  107.           if ( fs_id == 0x53) return( " OnTrack DM6 Au");
  108.           if ( fs_id == 0x54) return( " OnTrackDM6    ");
  109.           if ( fs_id == 0x55) return( " EZ-Drive      ");
  110.           if ( fs_id == 0x56) return( " Golden Bow    ");
  111.           if ( fs_id == 0x5c) return( " Priam Edisk   ");
  112.           if ( fs_id == 0x61) return( " SpeedStor     ");
  113.           if ( fs_id == 0x63) return( " GNU HURD / Sys");
  114.           if ( fs_id == 0x64) return( " Novell Netware");
  115.           if ( fs_id == 0x65) return( " Novell Netware");
  116.           if ( fs_id == 0x70) return( " DiskSecure    ");
  117.           if ( fs_id == 0x75) return( " PC/IX         ");
  118.           if ( fs_id == 0x80) return( " Old Minix     ");
  119.           if ( fs_id == 0x81) return( " Minix         ");
  120.           if ( fs_id == 0x82) return( " Linux Swap    ");
  121.           if ( fs_id == 0x83) return( " Linux ");
  122.           if ( fs_id == 0x84) return( " OS/2 verst.   ");
  123.           if ( fs_id == 0x85) return( " Linux ext.");
  124.           if ( fs_id == 0x86) return( " NTFS volume se");
  125.           if ( fs_id == 0x87) return( " NTFS volume se");
  126.           if ( fs_id == 0x93) return( " Amoeba        ");
  127.           if ( fs_id == 0x94) return( " Amoeba BBT    ");
  128.           if ( fs_id == 0xa0) return( " IBM Thinkpad  ");
  129.           if ( fs_id == 0xa5) return( " BSD/386       ");
  130.           return( "unknown" );
  131. }; });
  132.  
  133.  
  134.  
  135.     /*---------------------------------------------------------------------
  136.      * Convert a hard disk device name like "/dev/hda" into a SCR path
  137.      * that can be used to query SCR about technical data (.disk.hda).
  138.      *
  139.      * Return value: device as SCR path
  140.      *----------------------------------------------------------------------
  141.      */
  142.  
  143.     define DevNameToScrPath ( string dev_name )
  144.     ``{
  145.           if ( substring ( dev_name, 0, 5 ) == "/dev/" )
  146.           {
  147.               dev_name = substring ( dev_name, 5 );
  148.           }
  149.  
  150.           return ( .disk + topath ( "." + dev_name ) );
  151.         };
  152.  
  153.  
  154.  
  155.     /*---------------------------------------------------------------------
  156.      * Check if the numer is in the format [+]<number>[kKmMgGtT]
  157.      *
  158.      * Returns true or false
  159.      *----------------------------------------------------------------------
  160.      */
  161.  
  162.     UI(``{
  163.      define IsNumber( string input )
  164.      ``{
  165.            integer n = 0;
  166.            while (n < size(input))
  167.            {
  168.               string erg = filterchars(substring(input, n,1), "0123456789");
  169.               _debug( erg);
  170.  
  171.               if (size(erg) != 1)
  172.               {
  173.                _debug(n);
  174.                return(false);
  175.               }
  176.               n = n + 1;
  177.            }
  178.  
  179.            return(true);
  180.         };
  181.     });
  182.  
  183.     /*---------------------------------------------------------------------
  184.      * I386:
  185.      * Check if the patition-id is an extended -id
  186.      *
  187.      * Returns true or false
  188.      *----------------------------------------------------------------------
  189.      */
  190.  
  191.      define IsExtended( integer number )
  192.      ``{
  193.            // Standrd-Erw         Linux-Erweiterte    Win95-Erweitert
  194.            if ( (number == 5) || (number == 133) || (number == 5) )
  195.            {
  196.                _debug( "IS__EXTENDE YES");
  197.                return(true);
  198.            }
  199.            else
  200.            {
  201.                _debug( "IS__EXTENDE NO");
  202.                return(false);
  203.            }
  204.         };
  205.  
  206.     /*---------------------------------------------------------------------
  207.      * Check if the numer is in the format [+]<number>[kKmMgGtT]
  208.      *
  209.      * Returns true or false
  210.      *----------------------------------------------------------------------
  211.      */
  212.  
  213.      define IsNumber( string input )
  214.      ``{
  215.            integer n = 0;
  216.            while (n < size(input))
  217.            {
  218.               string erg = filterchars(substring(input, n,1), "0123456789");
  219.               _debug( erg);
  220.  
  221.               if (size(erg) != 1)
  222.               {
  223.                _debug(n);
  224.                return(false);
  225.               }
  226.               n = n + 1;
  227.            }
  228.  
  229.            return(true);
  230.         };
  231.  
  232.     /*---------------------------------------------------------------------
  233.      * Check if the numer is in the format [+]<number>[kKmMgGtT]
  234.      *
  235.      * Returns true or false
  236.      *----------------------------------------------------------------------
  237.      */
  238.      UI(``{
  239.      define IsCylNumber( string input )
  240.      ``{
  241.            if (substring( input, 0, 1) == "+")
  242.            {
  243.                input = substring( input, 1);
  244.            }
  245.  
  246.            if ( !IsNumber(input))
  247.            {
  248.                // check whether the last char is in "gGtTkKmMº
  249.                string last_char = substring( input, size(input)-1, 1);
  250.  
  251.                string erg = filterchars(last_char, "kKmMgGtT");
  252.  
  253.                if (size(erg) != 1)
  254.                {
  255.                    // the last isn't in "kKmMgGtT"
  256.                    return( false );
  257.                }
  258.                else
  259.                {
  260.                    // the last is in "kKmMgGtT" check whether the rest is a number
  261.                    return( IsNumber( substring(input, 0, size(input)-1)));
  262.                }
  263.            }
  264.            else
  265.            {
  266.                return( true );
  267.            }
  268.      };
  269.      });
  270.  
  271.  
  272.      /*---------------------------------------------------------------------
  273.      * Parse the end_partition String
  274.      * Input:
  275.      *  - start_cylinder,
  276.      *  - end of partition in
  277.      *    valid is [+]<number>[kKmMgGtT]
  278.      *    insert a valid string! consistency must be already checked
  279.      * - size of a cylinder in byte
  280.      *
  281.      * Returns (endcylinder -startcylinder +1) as integer
  282.      *----------------------------------------------------------------------
  283.      */
  284.  
  285.      UI(``{
  286.      define ToEndRegion(string start_cyl, string end_part, integer cyl_size )
  287.            ``{
  288.            boolean is_add = false;
  289.            string input   = end_part;
  290.  
  291.            if (substring( input, 0, 1) == "+")
  292.            {
  293.                input = substring( input, 1);
  294.                is_add = true;
  295.  
  296.            }
  297.  
  298.  
  299.            if ( !IsNumber(input))
  300.            {
  301.                is_add = true;  //  44k is the same as +44k
  302.  
  303.                // take last char
  304.                string last_char = substring( input, size(input)-1, 1);
  305.                integer base     = tointeger(substring( input, 0, size(input)-1 ));
  306.  
  307.                if ( last_char == "k" || last_char == "K" )
  308.                {
  309.                    return( (base*1024)/cyl_size +1 );
  310.                }
  311.                if ( last_char == "m" || last_char == "M" )
  312.                {
  313.                    return( (base*1048576)/cyl_size +1 );
  314.                }
  315.                if ( last_char == "g" || last_char == "G" )
  316.                {
  317.                    return( (base*1073741824)/cyl_size +1 );
  318.                }
  319.                if ( last_char == "t" || last_char == "T" )
  320.                {
  321.                    return( (base*(1099511627776/cyl_size) +1 ));
  322.                }
  323.  
  324.                y2log( .error, "Error in parsing end_cylinder" );
  325.                return( base );
  326.            }
  327.            else
  328.            {
  329.                if (is_add)
  330.                {
  331.                    return( tointeger(input) );
  332.                }
  333.                else
  334.                {
  335.                    return( tointeger(input)-tointeger(start_cyl)+1 );
  336.                }
  337.            }
  338.      };
  339.      });
  340.  
  341.  
  342.     /*---------------------------------------------------------------------
  343.      * Convert <number-of-bytes> to XXX.X MB or XXX.X GB or XXX.X TB
  344.      *
  345.      * Return value: string
  346.      *----------------------------------------------------------------------
  347.      */
  348.     define ByteToHumanString ( integer number )
  349.     ``{
  350.           // column description, if disk space is not known
  351.           if ( number == 0 ) return( _("unknown") );
  352.  
  353.           if ( number < 1073741824 )
  354.           {
  355.               // < 1 GB
  356.               integer MB    = number / 1048576;
  357.               integer hunKB = (number - (MB * 1048576)) / 102400;
  358.               if ( hunKB >= 10 )
  359.               {
  360.                 hunKB = 0;
  361.                 MB = MB+1;
  362.               }
  363.               return( sformat( "%1.%2 MB", MB,hunKB ));
  364.           }
  365.  
  366.           else if ( number < 1099511627776 )
  367.           {
  368.               // < 1 TB
  369.               integer GB    = number / 1073741824;
  370.               integer hunMB = (number - (GB * 1073741824)) /  104857600;
  371.               if ( hunMB >= 10 )
  372.               {
  373.                 hunMB = 0;
  374.                 GB = GB+1;
  375.               }
  376.               return( sformat( "%1.%2 GB", GB,hunMB ));
  377.           }
  378.           else
  379.           {
  380.               // >= 1 TB
  381.               integer TB    = number / 1099511627776;
  382.               integer hunGB = (number - (TB * 1099511627776)) / 107374182400;
  383.               if ( hunGB >= 10 )
  384.               {
  385.                 hunGB = 0;
  386.                 TB = TB+1;
  387.               }
  388.               return( sformat( "%1.%2 TB", TB,hunGB ));
  389.           }
  390.     };
  391.  
  392.  
  393.     /*---------------------------------------------------------------------
  394.      * tests which Partition types on a disk can be created
  395.      * for Intel-I386!
  396.      *
  397.      * Input: map disk    // (the map out of the targets map)
  398.      *        string dev  // /dev/hda
  399.      *
  400.      *  Return value: [ <primary_poss>, <extended_poss>, <logical_poss> ]
  401.      *  boolean primary_poss;   // Is a primary partition possible
  402.      *  boolean extended_poss;  // Is a extended partition possible
  403.      *  boolean logical_poss;   // Is a logical partition possible
  404.      *----------------------------------------------------------------------
  405.      * DESCRIPTION
  406.      *
  407.      * primary_part_is_possible  = false; // can I create a primary part ?
  408.      * extended_part_is_possible = false; // can I create a extended part ?
  409.      * logial_part_is_possible  = false; // ...
  410.      *
  411.      *
  412.      *   if (one of the partitions <disk>1 <disk>2 <disk>3 <disk>4
  413.      *       is not used )
  414.      *   {
  415.      *      primary_part_is_possible = true;
  416.      *   }
  417.      *
  418.      *   if  primary_part_is_possible && (no extended partition exists)
  419.      *   {
  420.      *     extended_part_is_possible = true;
  421.      *   }
  422.      *
  423.      *   if (extended partition already exists) && (extended partition has
  424.      *                                       space left)
  425.      *      && (not more than 15 logical parts already exist)
  426.      *   {
  427.      *     logial_part_is_possible = true;
  428.      *   }
  429.      *
  430.      *
  431.      *   At the same time is not possible, that both "logial_part_is_possible"
  432.      *   and "extended_part_is_possible" are true
  433.      *   so we have 6 possible situations
  434.      *
  435.      *   to show this we use
  436.      *   "P" for primary_part_is_possible
  437.      *   "E" for extended_part_is_possible
  438.      *   "L" for logial_part_is_possible
  439.      *
  440.      *   "p" for primary_part_is_possible  == false
  441.      *   "e" for extended_part_is_possible == false
  442.      *   "l" for logial_part_is_possible  == false
  443.      *
  444.      *
  445.      *   PE  : I can create a primary or exended part.
  446.      *   PL  : Extended part. exist. I can create a primary or a logical
  447.      *   Pel : only a priary is possible, when the extended part. has no space left
  448.      *
  449.      *   pE  : Not possible, if "E" is possible always "P" is possible too.
  450.      *   pL  : only a logical is possible, if together 4 primary and extended
  451.      *  partitions are already created
  452.      *   pel : no partitions are possible
  453.      *
  454.      *----------------------------------------------------------------------
  455.      */
  456.  
  457.     define CheckCreatePossibilities( string dev, map disk )
  458.     ``{
  459.             string type = substring(dev, 5, 2);
  460.  
  461.             boolean extended_exists      = false;
  462.  
  463.         symbol no_logical_cause     = `no_ext;
  464.         symbol no_primary_cause     = `dev_full;
  465.         symbol no_extended_cause    = `dev_full;
  466.  
  467.             boolean     primary_is_possible  = false;
  468.             boolean     extended_is_possible = false;
  469.             boolean     logical_is_possible  = false;
  470.  
  471.             list primary_list  = filter( `part, lookup( disk, "partitions"),
  472.                                           ``( (lookup( part, "type") == `primary)  && (!lookup( part, "delete", false) )));
  473.             list extended_list = filter( `part, lookup( disk, "partitions"),
  474.                                           ``( (lookup( part, "type") == `extended) && (!lookup( part, "delete", false) )));
  475.             list logical_list  = filter( `part, lookup( disk, "partitions"),
  476.                                           ``( (lookup( part, "type") == `logical)  && (!lookup( part, "delete", false) )));
  477.  
  478.           if (  (size(extended_list) + size(primary_list)) <= 3 )
  479.           {
  480.               primary_is_possible = true;
  481.           }
  482.  
  483.           if ( primary_is_possible && (size(extended_list) == 0) )
  484.           {
  485.               extended_is_possible = true;
  486.           }
  487.  
  488.           if ( size(extended_list) > 0 )            // "== 1" should also work, but ">" for safety
  489.           {
  490.          no_extended_cause = `already; 
  491.          extended_exists = true;
  492.           }
  493.  
  494.           if ( extended_exists )
  495.           {
  496.              no_logical_cause = `no_extsp;
  497.  
  498.               // test if extended partition has space left == a slot exists
  499.               boolean slot_exist = false;
  500.  
  501.               // Start-End of the extended partition
  502.  
  503.               integer start_ext_cyl = select( lookup( select( extended_list, 0 ), "region" ), 0);
  504.               integer end_ext_cyl   = select( lookup( select( extended_list, 0 ), "region" ), 1) + start_ext_cyl -1;
  505.  
  506.  
  507.               // logical_cyl_list = [ <start_cyl.firstLogPart> , <end_cyl.firstLogPart> , <start.nextLogPart> ,....., <end.lastLogPart>]
  508.               //
  509.               // example:  input: hda5:region [255,100] hda6:region[355,100] hda7[455,100]
  510.               //           is al list generatated: logical_cyl_list = [255,354,355,454,455,555]
  511.               //
  512.               list logical_cyl_list = sort(flatten(maplist( `part, logical_list, ``([select(lookup(part, "region"), 0),
  513.                                                    select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ]))));
  514.  
  515.               // Look for a slot in the list of cylinders
  516.               integer  n          = 0;
  517.  
  518.               if (size(logical_cyl_list) == 0 )
  519.               {
  520.                   // no logical partitions exist
  521.                   slot_exist = true;
  522.               }
  523.               else
  524.               {
  525.                   repeat
  526.                       {
  527.                           if ( n == 0 )
  528.                           {
  529.                               // first
  530.                               if ( select( logical_cyl_list, 0 ) != start_ext_cyl ) slot_exist = true;
  531.                           }
  532.                           else if ( n == (size(logical_cyl_list)/2))
  533.                           {
  534.                               // last
  535.                               if ( select( logical_cyl_list, size(logical_cyl_list)-1 ) != end_ext_cyl ) slot_exist = true;
  536.                           }
  537.                           else
  538.                           {
  539.                               //check if between logical partition n-1 and n is a slot
  540.                               if ( (select( logical_cyl_list, 2*n-1 )+1) !=  (select( logical_cyl_list, 2*n )  )) slot_exist = true;
  541.                           }
  542.  
  543.                           n = n+1;
  544.                       } until ( n == ( (size(logical_cyl_list)/2 +1)) || slot_exist );
  545.               }
  546.  
  547.               if (slot_exist)
  548.               {
  549.            no_logical_cause     = `to_many;
  550.  
  551.                   if  ( type == "hd" )                                        // EIDE supports 64 partitions
  552.                   {
  553.                       if (size(logical_cyl_list)/2 < 60 ) logical_is_possible = true;
  554.                   }
  555.                   if  ( type == "sd" )                                        // SCSI supports 16 partitions
  556.                   {
  557.                       if (size(logical_cyl_list)/2 < 12 ) logical_is_possible = true;
  558.                   }
  559.                   else
  560.                   {
  561.                       logical_is_possible = true;
  562.                   }
  563.               }
  564.           }
  565.  
  566.           return( [primary_is_possible, extended_is_possible, logical_is_possible, no_primary_cause, no_extended_cause, no_logical_cause ]);
  567.     };
  568.  
  569.  
  570.     /*---------------------------------------------------------------------
  571.      * Find bigest slot
  572.      * return [start, end] or nil
  573.      *---------------------------------------------------------------------
  574.      */
  575.  
  576.     define GetSlot( string dev, map disk )
  577.     ``{
  578.             string type = substring(dev, 5, 2);
  579.             list global_list  = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") != `logical) && !lookup( part, "delete", false) ));
  580.  
  581.             list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0),
  582.                                             select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ]))));
  583.  
  584.             // Look for a slot in the list of cylinders
  585.             integer  n          = 0;
  586.             integer start_cyl   = 0;
  587.             integer end_cyl     = lookup( disk, "cyl_count" )-1;
  588.  
  589.             integer sl_start   = 0;
  590.             integer sl_end     = 0;
  591.             integer curr_start = 0;
  592.             integer curr_end   = 0;
  593.  
  594.             boolean slot_exist = false;
  595.  
  596.  
  597.           if (size(global_cyl_list) == 0 )
  598.           {
  599.               // no partition exist
  600.               return( [start_cyl, end_cyl]);
  601.           }
  602.           else
  603.           {
  604.               repeat
  605.                   {
  606.                       if ( n == 0 )
  607.                       {
  608.                           // first
  609.                           curr_start  =  start_cyl-1;
  610.                           curr_end    =  select( global_cyl_list, 0 );
  611.                       }
  612.                       else if ( n == (size(global_cyl_list)/2))
  613.                       {
  614.                           // last
  615.                           curr_start = select( global_cyl_list, size(global_cyl_list)-1);
  616.                           curr_end   = end_cyl+1;
  617.                       }
  618.                       else
  619.                       {
  620.                           //check if between global partition n-1 and n is a slot
  621.                           curr_start = select( global_cyl_list, 2*n-1 );
  622.                           curr_end   = select( global_cyl_list, 2*n );
  623.                       }
  624.  
  625.                       if ( curr_start+1 != curr_end )
  626.                       {
  627.                           slot_exist = true;
  628.  
  629.                           _debug( "A Slot at: ",  curr_start, curr_end );
  630.  
  631.                           if (  (curr_end - curr_start -2) >= (sl_end - sl_start) )
  632.                           {
  633.                               sl_start = curr_start+1;
  634.                               sl_end   = curr_end-1;
  635.                           }
  636.                       }
  637.                       _debug("SLOT-", slot_exist, curr_start, curr_end, n );
  638.  
  639.                       n = n+1;
  640.                   } until ( n == ( (size(global_cyl_list)/2 +1)));
  641.           }
  642.  
  643.           if (slot_exist)
  644.           {
  645.               return( [sl_start, sl_end] );
  646.           }
  647.           else
  648.           {
  649.               return(nil);
  650.           }
  651.     };
  652.  
  653.     /*---------------------------------------------------------------------
  654.      * test primary and extended slot
  655.      * return [start, end] or nil
  656.      * Input: start_cyl of the tested slot, /dev/hda1,  diskmap
  657.      * return [max-end_cyl] or "nil" if its no valid start_cyl
  658.      * todo: GetSlo TestSlot should be one function
  659.      *---------------------------------------------------------------------
  660.      */
  661.  
  662.     UI(``{
  663.     define TestSlot( integer slot_start_cyl, string dev, map disk )
  664.     ``{
  665.             string type = substring(dev, 5, 2);
  666.             list global_list  = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") != `logical) && !lookup( part, "delete", false) ));
  667.  
  668.             list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0),
  669.                                             select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ]))));
  670.  
  671.             // Look for a slot in the list of cylinders
  672.             integer  n          = 0;
  673.             integer start_cyl   = 0;
  674.             integer end_cyl     = lookup( disk, "cyl_count" )-1;
  675.  
  676.             integer sl_start   = 0;
  677.             integer sl_end     = 0;
  678.             integer curr_start = 0;
  679.             integer curr_end   = 0;
  680.  
  681.             boolean slot_exist = false;
  682.  
  683.  
  684.           if (size(global_cyl_list) == 0 )
  685.           {
  686.               _debug( "Testing Slot : disk empty");
  687.               if ( start_cyl <= slot_start_cyl  && slot_start_cyl <= end_cyl )   return( end_cyl );
  688.           }
  689.           else
  690.           {
  691.               repeat
  692.                   {
  693.                       if ( n == 0 )
  694.                       {
  695.                           // first
  696.                           curr_start  =  start_cyl-1;
  697.                           curr_end    =  select( global_cyl_list, 0 );
  698.                       }
  699.                       else if ( n == (size(global_cyl_list)/2))
  700.                       {
  701.                           // last
  702.                           curr_start = select( global_cyl_list, size(global_cyl_list)-1);
  703.                           curr_end   = end_cyl+1;
  704.                       }
  705.                       else
  706.                       {
  707.                           //check if between global partition n-1 and n is a slot
  708.                           curr_start = select( global_cyl_list, 2*n-1 );
  709.                           curr_end   = select( global_cyl_list, 2*n );
  710.                       }
  711.  
  712.                       _debug( "Testing Slot < x < ", curr_start, curr_end );
  713.                       if ( curr_start < slot_start_cyl && slot_start_cyl < curr_end )
  714.                       {
  715.  
  716.                           // If the slot was found ...
  717.                           _debug( "X Slot at: ",  curr_start, curr_end );
  718.                           //////////////////
  719.                           return( curr_end-1 );
  720.                           //////////////////
  721.                       }
  722.                       _debug("SLOT-", slot_exist, curr_start, curr_end, n );
  723.  
  724.                       n = n+1;
  725.                   } until ( n == ( (size(global_cyl_list)/2 +1)));
  726.           }
  727.  
  728.           return(nil);
  729.     };
  730.     });
  731.  
  732.  
  733.  
  734.     /*---------------------------------------------------------------------
  735.      * Find bigest slot for logical
  736.      * return [start, end] or nil
  737.     /*---------------------------------------------------------------------
  738.      */
  739.  
  740.     define GetLogicalSlot( string dev, map disk )
  741.     ``{
  742.        
  743.             string type = substring(dev, 5, 2);
  744.  
  745.             list     global_list   = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `logical) && !lookup( part, "delete", false) ));
  746.             map|void extended      = find( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `extended)  && !lookup( part, "delete", false) ));
  747.  
  748.         //////////////////////////////////
  749.         if (extended == nil ) return(nil);
  750.         //////////////////////////////////
  751.         
  752.             list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0),
  753.                                             select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ]))));
  754.  
  755.             // Look for a slot in the list of cylinders
  756.             integer  n          = 0;
  757.             integer start_cyl   = tointeger( select(lookup( extended, "region"),0) );
  758.             integer end_cyl     = start_cyl + tointeger(select(lookup( extended, "region"), 1)) -1;
  759.  
  760.             integer sl_start   = 0;
  761.             integer sl_end     = 0;
  762.             integer curr_start = 0;
  763.             integer curr_end   = 0;
  764.  
  765.             boolean slot_exist = false;
  766.  
  767.  
  768.           if (size(global_cyl_list) == 0 )
  769.           {
  770.               // no partition exist
  771.               return( [start_cyl, end_cyl]);
  772.           }
  773.           else
  774.           {
  775.               repeat
  776.                   {
  777.                       if ( n == 0 )
  778.                       {
  779.                           // first
  780.                           curr_start  =  start_cyl-1;
  781.                           curr_end    =  select( global_cyl_list, 0 );
  782.                       }
  783.                       else if ( n == (size(global_cyl_list)/2))
  784.                       {
  785.                           // last
  786.                           curr_start = select( global_cyl_list, size(global_cyl_list)-1);
  787.                           curr_end   = end_cyl+1;
  788.                       }
  789.                       else
  790.                       {
  791.                           //check if between global partition n-1 and n is a slot
  792.                           curr_start = select( global_cyl_list, 2*n-1 );
  793.                           curr_end   = select( global_cyl_list, 2*n );
  794.                       }
  795.  
  796.                       if ( curr_start+1 != curr_end )
  797.                       {
  798.                           slot_exist = true;
  799.  
  800.                           _debug( "A Slot at: ",  curr_start, curr_end );
  801.  
  802.                           if (  (curr_end - curr_start -2) >= (sl_end - sl_start) )
  803.                           {
  804.                               sl_start = curr_start+1;
  805.                               sl_end   = curr_end-1;
  806.                           }
  807.                       }
  808.                       _debug("SLOT-", slot_exist, curr_start, curr_end, n );
  809.  
  810.                       n = n+1;
  811.                   } until ( n == ( (size(global_cyl_list)/2 +1)));
  812.           }
  813.  
  814.           if (slot_exist)
  815.           {
  816.               return( [sl_start, sl_end] );
  817.           }
  818.           else
  819.           {
  820.               return(nil);
  821.           }
  822.     };
  823.  
  824.  
  825.     /*---------------------------------------------------------------------
  826.      * Check slot for logical partition
  827.      * Input: start_cyl of the tested slot, /dev/hda5,  diskmap, in edit_mode or create_mode
  828.      *
  829.      * return [max-end_cyl] or nil if its no valisd start_cyl
  830.      *
  831.      * todo: GetLogicalSlot TestLogicalSlot should be one function
  832.      *---------------------------------------------------------------------
  833.      */
  834.  
  835.     UI(``{
  836.     define TestLogicalSlot( integer slot_start_cyl, string dev, map disk)
  837.     ``{
  838.             string type = substring(dev, 5, 2);
  839.  
  840.             list global_list  = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `logical) && !lookup( part, "delete", false) ));
  841.             map extended      = find( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `extended)  && !lookup( part, "delete", false) ));
  842.  
  843.             list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0),
  844.                                             select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ]))));
  845.  
  846.             // Look for the slot in the list of cylinders
  847.             integer  n          = 0;
  848.             integer start_cyl   = tointeger( select(lookup( extended, "region"),0) );
  849.             integer end_cyl     = start_cyl + tointeger(select(lookup( extended, "region"), 1)) -1 ;
  850.  
  851.             integer sl_start   = 0;
  852.             integer sl_end     = 0;
  853.             integer curr_start = 0;
  854.             integer curr_end   = 0;
  855.  
  856.             boolean slot_exist = false;
  857.  
  858.  
  859.           if (size(global_cyl_list) == 0 )
  860.           {
  861.               if ( start_cyl <= slot_start_cyl  && slot_start_cyl <= end_cyl )   return( end_cyl );
  862.           }
  863.           else
  864.           {
  865.               repeat
  866.                   {
  867.                       if ( n == 0 )
  868.                       {
  869.                           // first
  870.                           curr_start  =  start_cyl-1;
  871.                           curr_end    =  select( global_cyl_list, 0 );
  872.                       }
  873.                       else if ( n == (size(global_cyl_list)/2))
  874.                       {
  875.                           // last
  876.                           curr_start = select( global_cyl_list, size(global_cyl_list)-1);
  877.                           curr_end   = end_cyl+1;
  878.                       }
  879.                       else
  880.                       {
  881.                           //check if between global partition n-1 and n is a slot
  882.                           curr_start = select( global_cyl_list, 2*n-1 );
  883.                           curr_end   = select( global_cyl_list, 2*n );
  884.                       }
  885.  
  886.                       _debug( "Testing Slot < x < ", curr_start, curr_end );
  887.  
  888.                       if ( curr_start < slot_start_cyl && slot_start_cyl < curr_end )
  889.                       {
  890.  
  891.                           // If the slot was found ...
  892.                           _debug( "X Slot at: ",  curr_start, curr_end );
  893.                           //////////////////
  894.                           return( curr_end -1);
  895.                           //////////////////
  896.                       }
  897.                       _debug("SLOT-", slot_exist, curr_start, curr_end, n );
  898.  
  899.                       n = n+1;
  900.                   } until ( n == ( (size(global_cyl_list)/2 +1)));
  901.           }
  902.  
  903.           return(nil);
  904.     };
  905.     });
  906.  
  907.  
  908.     /*---------------------------------------------------------------------
  909.      * Fill the selection box with ID 'selbox_id' inside widget tree
  910.      * 'widget' with disk and partition info from 'all_disks'.
  911.      *
  912.      *  Return value:
  913.      * term contents = `VBox(`Label("Today's menu in the kanteen"),
  914.      *                        `Table(`header("Device", "Start", "End", "Size", "F", "Type", "Mount"),
  915.      *                               [
  916.      *                                `item(`id(1), "/dev/hda",      "1",  "1115", "8.5 GB",   " ", "Seagate ST 48012", " "),
  917.      *                                `item(`id(2), "  /dev/hda1",   "1",  "65",   "509.8 MB", " ", "FAT16", " "),
  918.      *                                `item(`id(3), "  /dev/hda2",   "66", "150",  "666.7 MB", " ", "NTFS", " "),
  919.      *                                `item(`id(4), "  /dev/hda3",   "301","1024", "5.5 GB",   " ", "Extended", " "),
  920.      *                                `item(`id(5), "    /dev/hda5", "301","302",  "7.8 MB",   "F", "Linux ", "/boot")
  921.      *                               ] )) ;
  922.      *----------------------------------------------------------------------
  923.      */
  924.  
  925.     define FillPartitionList ( map targets )
  926.     ``{
  927.              list    table_input = [];
  928.              //boolean log_mode = true;          // more logging info in main dialog!!
  929.              boolean log_mode = false;
  930.  
  931.             foreach ( `disk_dev_name, `disk, targets,
  932.                       ``{
  933.  
  934.                             integer cyl_count  = lookup ( disk, "cyl_count", 0  );
  935.                             integer cyl_size   = lookup ( disk, "cyl_size",  1000000    );
  936.                             string  vendor     = lookup ( disk, "vendor",    "" );
  937.                             string  model      = lookup ( disk, "model",     "" );
  938.  
  939.                 if ( (model != "") && (vendor != "") )  vendor = vendor + "-" + model;
  940.                 else                     vendor = vendor +       model;
  941.  
  942.                 // entry in column "Type" for a unknown disk
  943.                 if ( vendor == "" ) vendor = sformat( UI(_("DISK %1")) , substring( disk_dev_name, 5 )); 
  944.                 
  945.                             // Insert line for the entire disk into selection box widget
  946.                             term a = `item(`id(disk_dev_name), disk_dev_name, 0, cyl_count-1,
  947.                        ByteToHumanString(cyl_count * cyl_size), " ", vendor, "" );
  948.                             table_input = add( table_input, a );
  949.  
  950.                             list        partitions      = lookup ( disk, "partitions"    );
  951.  
  952.                             foreach ( `partition, partitions,
  953.                                       ``{
  954.                                             if ( !lookup ( partition, "delete", false ) || log_mode )
  955.                                             {
  956.                                                 string id = "";
  957.                                                 if  ( lookup ( partition, "nr") < 10 )
  958.                                                 {
  959.                                                     id = sformat( "0%2.%1", disk_dev_name, lookup ( partition, "nr"));
  960.                                                 }
  961.                                                 else
  962.                                                 {
  963.                                                     id = sformat( "%2.%1", disk_dev_name, lookup ( partition, "nr"));
  964.                                                 }
  965.                                                string   part_dev_name   = sformat( "%1%2", disk_dev_name, lookup ( partition, "nr"));
  966.                                                integer  start_cyl       = select ( lookup ( partition, "region"), 0 );
  967.                                                integer  nb_cyl          = select ( lookup ( partition, "region"), 1 );
  968.                                                symbol   type            = lookup ( partition, "type"            );
  969.                                                boolean  format          = lookup ( partition, "format",  false );
  970.                                                symbol   used_fs         = lookup ( partition, "used_fs", `unknown );
  971.                                                string   mount_point     = lookup ( partition, "mount",   ""       );
  972.                                                string   filesystem_name = "";
  973.                            if (lookup ( partition, "type") == `pdisk) {
  974.                            filesystem_name = lookup ( partition, "fstype", "?");
  975.                            } else {
  976.                            filesystem_name = UI(`FsIdToString( lookup ( partition, "fsid" )));
  977.                            }
  978.  
  979.                            if ( format && (used_fs == `ext2) ) filesystem_name = filesystem_name + " (Ext2)  ";
  980.                            if ( format && (used_fs == `reiser)) filesystem_name = filesystem_name + " (ReiserFS)  ";
  981.                             
  982.                                                string   format_flag      = "";
  983.                                                if ( format ) format_flag = "F";
  984.  
  985.                                                if ( log_mode )
  986.                                                {
  987.                            string       ori_str = "";
  988.                                                    void|boolean del = lookup ( partition, "delete" );
  989.                                                    void|boolean cre = lookup ( partition, "create" );
  990.                                                    void|integer ori = lookup ( partition, "ori_nr" );
  991.                                                    if ( del == nil )   format_flag = format_flag + " dn";
  992.                                                    if ( del == true )  format_flag = format_flag + " dT";
  993.                                                    if ( del == false ) format_flag = format_flag + " dF";
  994.                                                    if ( cre == nil )   format_flag = format_flag + " cn";
  995.                                                    if ( cre == true )  format_flag = format_flag + " cT";
  996.                                                    if ( cre == false ) format_flag = format_flag + " cF";
  997.                            if ( ori != nil )   ori_str = sformat( " o%1 ", ori );
  998.                            if ( ori == nil )   ori_str = " o- ";
  999.                            format_flag = format_flag + ori_str;
  1000.                                                }
  1001.  
  1002.                                                integer bytes_of_part =  ( nb_cyl ) * cyl_size;
  1003.  
  1004.                                                // Insert line for this partition into selection box widget
  1005.                                                term a = `item(`id(id), part_dev_name, start_cyl, start_cyl + nb_cyl - 1, ByteToHumanString(bytes_of_part),
  1006.                                                               format_flag, filesystem_name, mount_point );
  1007.                                                table_input = add( table_input, a );
  1008.                                             }
  1009.                                             else
  1010.                                             {
  1011.                                                 // as deted marked
  1012.                                                 // _debug( "ddddddddddddd----");
  1013.                                             }
  1014.                                       }
  1015.                                   );
  1016.                         }
  1017.                     );
  1018.             return sort( `lineA, `lineB, table_input, ``(
  1019.             {
  1020.                 return( select(lineA, 1) <= select(lineB, 1 ));
  1021.             }));
  1022.           };
  1023.  
  1024.     /*---------------------------------------------------------------------
  1025.      * Initialize Partitiontable:
  1026.      *
  1027.      * - all really existing partition get a ori_nr
  1028.      *   We need this number, when a logical partition is deleted and
  1029.      *   other logical partition change their number
  1030.      *
  1031.      * - delete pseudo partitions with `free from target_partitioner
  1032.      *
  1033.      * - mark swap-partition with pseudo Mountpoint swap
  1034.      *----------------------------------------------------------------------
  1035.      */
  1036.  
  1037.     define InitTargets ( map targets )
  1038.     ``{
  1039.             foreach( `disk_dev_name, `disk, targets,
  1040.             ``{
  1041.                 // only really existing!
  1042.                 list    partitions      = lookup ( disk, "partitions");
  1043.  
  1044.           partitions = filter(  `partition, partitions, ``(  lookup(partition, "type", `free) != `free ) );
  1045.         
  1046.                   partitions = maplist( `partition, partitions, ``(
  1047.                   {
  1048.               map result  = partition;
  1049.               if ( lookup(partition, "fsid",  131) == 130 )
  1050.               {
  1051.               result = add( result, "mount", "swap");
  1052.               }
  1053.               
  1054.               if ( lookup(partition, "ori_nr") == nil ) 
  1055.                       {
  1056.                           result =  add( result, "ori_nr", lookup(partition, "nr"));
  1057.                       }
  1058.  
  1059.               _debug( "WW", result);
  1060.  
  1061.               return ( result );
  1062.               
  1063.                   }));
  1064.  
  1065.                 disk = add( disk, "partitions", partitions );
  1066.                 targets = add( targets, disk_dev_name, disk );
  1067.  
  1068.              });
  1069.             return targets;
  1070.     };
  1071.  
  1072.  
  1073.     
  1074.     /*---------------------------------------------------------------------
  1075.      * Checks if the mountpoint is valid
  1076.      * - /proc /mnt /lost+found contain /var/adm/mount are not allowd
  1077.      * - double entries are not allowed ( mountpoints with no / and "" are always allowed )
  1078.      * 
  1079.      *----------------------------------------------------------------------
  1080.      */
  1081.     
  1082.     UI(``{
  1083.     define check_mount_point( map targetMap, string mount )
  1084.     ``{
  1085.  
  1086.     boolean allowed = true;
  1087.  
  1088.     if ( mount != ""  && mount != "swap"  )
  1089.     {
  1090.         
  1091.         foreach( `disk, `diskinfo, targetMap, ``{
  1092.         list part_info = lookup( diskinfo, "partitions" );
  1093.         foreach( `part, part_info, ``{
  1094.  
  1095.             if ( lookup( part, "delete", false) == false )
  1096.             {
  1097.             // all valid partitions
  1098.             if ( lookup( part, "mount", "") == mount )   allowed = false;
  1099.             }
  1100.         });
  1101.         });
  1102.  
  1103.     
  1104.         if ( allowed == false )
  1105.         {
  1106.         DisplayMessage(_("The mount point is already in use, please choose another moint point"));
  1107.         }
  1108.         else
  1109.         {
  1110.         if ( contains([ "/proc", "/dev", "/mnt", "var/adm/mnt", "/lost+found" ], mount) )
  1111.         {
  1112.              allowed = false;
  1113.              DisplayMessage(_("You cannot use one of the following mountpoints:
  1114. /proc, /dev, /mnt, var/adm/mnt, /lost+found"));
  1115.         }
  1116.         else if ( substring( mount, 0, 1 ) != "/"  )
  1117.          {
  1118.              allowed = false;
  1119.              DisplayMessage(_("Your mountpoint must start with a \"/\" "));
  1120.         }
  1121.         }
  1122.     }
  1123.     else
  1124.     {
  1125.         allowed = true;
  1126.     }
  1127.  
  1128.     return( allowed );
  1129.     
  1130.     }; });
  1131.  
  1132.  
  1133.     
  1134.     /*---------------------------------------------------------------------
  1135.      * Display "Create a partition Dialog"
  1136.      *
  1137.      * Input:
  1138.      * string title,
  1139.      * boolean format,
  1140.      * integer filesystem_id,
  1141.      * string start_cyl,
  1142.      * string end_part,
  1143.      * string mount_point,
  1144.      * symbol type,
  1145.      * string dev,
  1146.      * map disk,         CAUTION: in Edit-Mode, the edited partion, must not be in this map!!
  1147.      * integer cyl_size  cylinder size
  1148.      * targetMap         CAUTION: in Edit-Mode, the edited partion, must not be in this map!
  1149.      *
  1150.      * return: nil bei cancel
  1151.      *         [fsid,format,mount,start_cyl,end_cyl, used_fs]
  1152.      *----------------------------------------------------------------------
  1153.      */
  1154.  
  1155.     UI(``{
  1156.           define EditOrCreatePartDlg(string title, boolean format, integer filesystem_id,
  1157.                               string start_cyl, string end_part, string mount_point, symbol type, string dev,
  1158.                                map disk, integer cyl_size, symbol used_fs, map targetList ) ``{
  1159.               // helptext for popup create partition line 1 of 6
  1160.               string helptextCR = _("<p>First, please choose the type of the new partiton and whether this partition should be formatted or not.</p>" );
  1161.               // helptext for popup create partition line 2 of 6
  1162.               helptextCR = helptextCR + _("<p>Then you must enter the mount point ( /, /boot, /usr, /var ... )</p>" );
  1163.               // helptext for popup create partition line 3 of 6
  1164.               helptextCR = helptextCR + _("Now you can enter the location of the new partition on your hard disk. ");
  1165.               // helptext for popup create partition line 4 of 6
  1166.               helptextCR = helptextCR + _("<p>Please enter the starting cylinder number of the partition.");
  1167.               // helptext for popup create partition line 5 of 6
  1168.               helptextCR = helptextCR + _("After that you can either specify an ending cylinder number or an offset from the first cylinder (e.g +66).");
  1169.               // helptext for popup create partition line 6 of 6
  1170.               helptextCR = helptextCR + _("It is also possible to specify the size of the partition directly (e.g. +100M or +20000K))</p>");
  1171.  
  1172.               OpenDialog( `opt(`decorated ), `VBox(`Heading(title),
  1173.                         `Label(""),
  1174.                         `HBox(
  1175.                               /// left side
  1176.                               `RichText( helptextCR ),
  1177.                               /// right side
  1178.                               `VBox(
  1179.                                     // popup create partition: Framedescription Typ of Filesystem
  1180.                                     `Frame ( _("Type"),
  1181.                                              `RadioButtonGroup(`id(`fs),
  1182.                                    `VBox(
  1183.                                      // popup create partition: Typ of Filesystem: Linux native
  1184.                                      `Left(`RadioButton(`id(`reiser),`opt(`notify),
  1185.                                             // popup create partition: here you choose the type of the
  1186.                                             // filesystem/ Data with  ReiserFS/  Data with Ext2 or / Swap
  1187.                                             _("Data with &ReiserFS"),  (filesystem_id == 131) && (used_fs == `reiser)  )),
  1188.                                      `Left(`RadioButton(`id(`ext2),`opt(`notify),
  1189.                                             // popup create partition: here you choose the type of the filesystem/
  1190.                                             // Data with  ReiserFS/  Data with Ext2 or / Swap
  1191.                                             _("Data with &Ext2"),  (filesystem_id == 131) && (used_fs == `ext2 ))),
  1192.                                      // popup create partition: Typ of Filesystem: Linux Swap
  1193.                                      `Left(`RadioButton(`id(`swap),`opt(`notify),
  1194.                                             _("&Swap") , (filesystem_id == 130)) )
  1195.                                      )
  1196.                                    )
  1197.                                              ),
  1198.                                     `Label(""),
  1199.  
  1200.                                     // popup create partition: Framedescription "Format partition or not"
  1201.                                     `Frame ( substring(_("2:Format"),2),
  1202.                                              `RadioButtonGroup(`id(`format),
  1203.                                                          `VBox(
  1204.                                                                // popup create partition: Dont format partition
  1205.                                                                `Left(`RadioButton(`id(false),_("Do ¬ format"), !format  )),
  1206.                                                                // popup create partition: Format partition (Vocative)
  1207.                                                                `Left(`RadioButton(`id(true), _("&Format"), format ))
  1208.                                                                )
  1209.                                                          )
  1210.                                              ),
  1211.                                     `Label(""),
  1212.                                     // popup create partition: Framedescription Choose Mountpoint
  1213.                                     `Frame ( _("Mount Point"),
  1214.                                     // popup create partition: Description Inputfield
  1215.                                              `TextEntry(`id(`mount_point), _("&Mount Point:"))
  1216.                                              ),
  1217.                                     `Label(""),
  1218.                                     // popup create partition: Framedescription Start/Endcylinder
  1219.                                     `Frame ( _("Size"),
  1220.                                              `VBox(
  1221.                                                    // popup create partition: Description Inputfield
  1222.                                                    `TextEntry(`id(`start_cyl), _("S&tart cylinder:")),
  1223.                                                    // popup create partition: Description Inputfield +9M means add 9 MB
  1224.                                                    `TextEntry(`id(`end_part), _("E&nd: ( 9 or +9M or +9G )"))
  1225.                                                    )
  1226.                                              )
  1227.                                     ),
  1228.                                     `Label(" ")
  1229.                               ),
  1230.                         `Label(""),
  1231.                         `HBox(
  1232.                               // popup create partition:
  1233.                               `PushButton(`id(`ok), `opt(`default),    _("&OK")),
  1234.                               // popup create partition:
  1235.                               `PushButton(`id(`cancel), _("&Cancel"))
  1236.                               )
  1237.                         )
  1238.                   );
  1239.           
  1240.     string  user_mount_point = "";
  1241.     ChangeWidget(`id(`start_cyl), `Value, start_cyl);
  1242.     ChangeWidget(`id(`end_part),  `Value, end_part);
  1243.     SetFocus(`id(`start_cyl));
  1244.  
  1245.     // if the user choose swap mount, mount swap should be displayed
  1246.     if (filesystem_id == 130)    {
  1247.         ChangeWidget(`id(`mount_point), `Value,   "swap");
  1248.         mount_point = "swap";
  1249.         ChangeWidget(`id(`mount_point), `Enabled, false );
  1250.     user_mount_point = "";
  1251.     }
  1252.     else
  1253.     {
  1254.         ChangeWidget(`id(`mount_point), `Value, mount_point);
  1255.         ChangeWidget(`id(`mount_point), `Enabled, true );
  1256.     user_mount_point = mount_point;
  1257.     }
  1258.  
  1259.  
  1260.     boolean input_is_ok     = false;
  1261.     map     return_value    = $[];
  1262.     symbol  doit_int        = `ok;
  1263.     symbol  doit            = `cancel;
  1264.  
  1265.     repeat
  1266.           {
  1267.               //-------------------------------
  1268.               // Check the User input / change popup ...
  1269.               //-------------------------------
  1270.               doit_int = UserInput();
  1271.  
  1272.               if       (doit_int == `cancel) doit = `cancel;
  1273.               else  if (doit_int == `ok)     doit = `ok;
  1274.               else                           doit = `retry;
  1275.  
  1276.  
  1277.               if ( doit != `cancel )
  1278.               {
  1279.                   return_value = $[];
  1280.  
  1281.           //------------------------------------------------------------
  1282.           // Read the format-type and y/n
  1283.           
  1284.                   symbol format_id = QueryWidget(`id(`fs),            `CurrentButton);
  1285.           
  1286.           if ( format_id != `swap )   return_value = add( return_value, "fsid", 131 );
  1287.           if ( format_id == `swap )   return_value = add( return_value, "fsid", 130 );
  1288.           if ( format_id == `ext2 )   return_value = add( return_value, "used_fs", `ext2 );
  1289.           if ( format_id == `reiser ) return_value = add( return_value, "used_fs", `reiser );
  1290.           
  1291.           return_value = add( return_value, "format",       QueryWidget(`id(`format),        `CurrentButton)) ;
  1292.                   return_value = add( return_value, "mount",        QueryWidget(`id(`mount_point),   `Value)) ;
  1293.                   return_value = add( return_value, "start_cyl",    QueryWidget(`id(`start_cyl),     `Value)) ;
  1294.                   return_value = add( return_value, "end_part",     QueryWidget(`id(`end_part),      `Value)) ;
  1295.  
  1296.                   //////////////////////////////////////////////////////////////
  1297.                   // if the user choose swap no mount_poit should be displayed ..
  1298.  
  1299.                   if (QueryWidget(`id(`fs), `CurrentButton) == `swap)
  1300.                   {
  1301.                       mount_point = "swap";
  1302.                       ChangeWidget(`id(`mount_point), `Value,   "swap");
  1303.                       ChangeWidget(`id(`mount_point), `Enabled, false );
  1304.                   }
  1305.                   else
  1306.                   {
  1307.               mount_point = QueryWidget(`id(`mount_point),   `Value);
  1308.                       if (mount_point != "swap" ) user_mount_point = mount_point;   // notice last user_input
  1309.                       if (mount_point == "swap" ) mount_point = user_mount_point;   // set last user_input
  1310.                       ChangeWidget(`id(`mount_point), `Value, mount_point);
  1311.                       ChangeWidget(`id(`mount_point), `Enabled, true );
  1312.                   }
  1313.  
  1314.           
  1315.                   if ( doit == `ok )
  1316.           {
  1317.               //////////////////////////////////////////////////////////////
  1318.               // Check if the user input for start und end cyl are valid
  1319.  
  1320.               list ret = TestStartEndCyl( lookup(return_value, "start_cyl"),
  1321.                           lookup(return_value, "end_part"),  dev, disk, type, cyl_size );
  1322.  
  1323.               if (select( ret, 0) == `error )  input_is_ok = false;
  1324.               if (select( ret, 0) == `ok )     input_is_ok = true;
  1325.               if (select( ret, 0) == `max )
  1326.               {
  1327.               input_is_ok = true;
  1328.               return_value = add( return_value, "end_part", select( ret, 1));
  1329.               }
  1330.  
  1331.           
  1332.               //////////////////////////////////////////////////////////////
  1333.               // Check if the user has a reiserfs with  not enough space
  1334.               if ( input_is_ok && (format_id == `reiser) )
  1335.               {
  1336.               integer part_size = ( tointeger(select( ret, 1)) - tointeger(lookup(return_value, "start_cyl")) +1 ) * cyl_size;
  1337.  
  1338.               _debug( "UUUUUUUUUUU", part_size );
  1339.               if ( part_size < 60000000 )
  1340.               {
  1341.                   DisplayMessage(_("Your partition is too small, to use ReiserFS!
  1342. ReiserFS is a journaling filesystem, and the storage
  1343. of the journal needs already about 30 MB space.
  1344. So please use ReiserFS only with bigger partitions."));
  1345.                   input_is_ok = false;
  1346.               }
  1347.               }
  1348.  
  1349.               //////////////////////////////////////////////////////////////
  1350.               // Check if the user input for mount point are valid
  1351.  
  1352.               if (  input_is_ok  )
  1353.               {
  1354.               string user_input_mount = lookup(return_value, "mount", "");
  1355.               input_is_ok = check_mount_point( targetList, user_input_mount);
  1356.               }
  1357.           }
  1358.  
  1359.               }
  1360.           } until ( (doit == `ok && input_is_ok)  ||  doit == `cancel );
  1361.  
  1362.     CloseDialog();
  1363.  
  1364.     if ( doit == `cancel )
  1365.     {
  1366.           return( nil );
  1367.     }
  1368.     else
  1369.     {
  1370.           return( return_value );
  1371.     }
  1372. }; });
  1373.  
  1374.  
  1375.  
  1376.     /*--------------------------------------------------------------------------------------------
  1377.      *
  1378.      *    Now check start an endcylinder
  1379.      *    caution: there is no differenc in edit and create cause the partion, which is to edited,
  1380.      *    is not in the disk map!
  1381.      *
  1382.      *    Check:
  1383.      *    A. Is start_cyl ist a number?  no-> try again
  1384.      *    B. is start_cyl valid ( can the partition start there?) no -> try again
  1385.      *          (when this is tested, the maximal possible end cylinder is computed, too)
  1386.      *    C.    Now we check the syntax of the endCylinder
  1387.      *    D.    If the syntax is valid, the requested end cylinder is checked
  1388.      *    E.  If it is not valid, the user gets a popup and the maximal possible end cylinder is set
  1389.      *
  1390.      *    returns  [<symbol>, <value>]
  1391.      *
  1392.      *             [`ok,  <effektive end cyl>]
  1393.      *             [`max, <max-value as str> ]   // case E
  1394.      *             [`error, 0]
  1395.      *---------------------------------------------------------------------------------------------
  1396.      */
  1397.  
  1398.  
  1399.    UI(``{
  1400.    define TestStartEndCyl( string str_start_cyl, string str_end_part, string dev, map disk, symbol type, integer cyl_size )
  1401.    ``{
  1402.  
  1403.       void|integer max_end_cyl   = 0;
  1404.       string       max_end_str   = "";
  1405.       symbol       input         = `ok;
  1406.       integer      int_start_cyl = tointeger(str_start_cyl);
  1407.       integer      int_end_cyl   = 0;
  1408.  
  1409.       ////////////////////////////////// STEP A ////////////////////////////////////////////////
  1410.       if (!IsNumber( str_start_cyl ))
  1411.       {
  1412.           input = `error;
  1413.           DisplayMessage(_("Wrong input for the start of the partition, \nyou must must enter the start cylinder (e.g. 77)."));
  1414.       }
  1415.       else
  1416.       {
  1417.           ////////////////////////////// STEP B ////////////////////////////////////////////////
  1418.  
  1419.           integer      int_start_cyl = tointeger(str_start_cyl);
  1420.  
  1421.           if ( type == `logical )         max_end_cyl = TestLogicalSlot( int_start_cyl, dev, disk );
  1422.           else                            max_end_cyl = TestSlot(        int_start_cyl, dev, disk );  // primary && extended
  1423.           if ( max_end_cyl == nil )
  1424.           {
  1425.               DisplayMessage(_("The start cylinder is not valid. Please check again"));
  1426.               input = `error;
  1427.           }
  1428.  
  1429.           if ( input == `ok )
  1430.           {
  1431.               ////////////////////////// STEP C ////////////////////////////////////////////////
  1432.               if (!IsCylNumber(str_end_part))
  1433.               {
  1434.                   input = `error;
  1435.                   DisplayMessage(_("Wrong input for the end of the partition.\n
  1436. st enter the endcylinder (e.g. 77) or an offset (e.g.+122)
  1437. specify the size of the partition directly (e.g. +100M or +1GB )"));
  1438.               }
  1439.               else
  1440.               {
  1441.                   ////////////////////// STEP D ////////////////////////////////////////////////
  1442.  
  1443.                   int_end_cyl = int_start_cyl + ToEndRegion( str_start_cyl, str_end_part, cyl_size ) -1;
  1444.  
  1445.                   if ( int_end_cyl > max_end_cyl || int_end_cyl < int_start_cyl)
  1446.                   {
  1447.                            ////////////////// STEP E ////////////////////////////////////////////////
  1448.  
  1449.                       DisplayMessage(_("CAUTION: The value of the end cylinder was not valid. \nYaST2 had inserted the maximum \npossible value"));
  1450.                       max_end_str = sformat("%1", max_end_cyl);
  1451.                       input = `max;
  1452.                   }
  1453.               }
  1454.           }
  1455.       }
  1456.       // END Check
  1457.  
  1458.       if ( input == `ok )  return( [`ok,  int_end_cyl ]);
  1459.       if ( input == `max ) return( [`max, max_end_str ]);
  1460.  
  1461.       // if  ( input == `error )
  1462.       return( [`error, 0]);
  1463.  
  1464.    };
  1465.    });
  1466.  
  1467.  
  1468.  
  1469.  
  1470.     /*---------------------------------------------------------------------
  1471.      * Display "Create a extended partition Dialog"
  1472.      *
  1473.      * return: nil bei cancel
  1474.      *         [fsid,format,mount,start_cyl,end_cyl] bei ok
  1475.      *
  1476.      *----------------------------------------------------------------------
  1477.      */
  1478.  
  1479.  
  1480.     UI(``{
  1481.           define CreateEditExtendedPartDlg(string title, boolean format, integer filesystem_id,
  1482.                               string start_cyl, string end_part, string mount_point, symbol type, string dev,
  1483.                                map disk, integer cyl_size, boolean edit  )  ``{
  1484.                   // helptext for popup create extended  partition line
  1485.               string helptextCR = _("<p>Please enter the starting cylinder number of the partition.
  1486. After that you can either specify an ending cylinder number or an offset from the first cylinder (e.g +66).
  1487. It is also possible to specify the size of the partition directly (e.g. +2G or +100M or +20000K)</p>");
  1488.  
  1489.               OpenDialog( `opt(`decorated ),  `VBox(`Heading(title),
  1490.                         `Label(""),
  1491.                         `HBox(
  1492.                               /// left side
  1493.                               `RichText( helptextCR ),
  1494.                               /// right side
  1495.                               // popup create partition: Framedescription Start/Endcylinder
  1496.                                     `Frame ( _("Size"),
  1497.                                              `VBox(
  1498.                                                    // popup create partition: Description Inputfield
  1499.                                                    `TextEntry(`id(`start_cyl), _("S&tart cylinder:")),
  1500.                                                    // popup create partition: Description Inputfield +9M means add 9 MB
  1501.                                                    `TextEntry(`id(`end_part), _("E&nd: ( 9 or +9M or +9G )"))
  1502.                                                    )
  1503.                                              )
  1504.                               ),
  1505.                         `Label(""),
  1506.                         `HBox(
  1507.                               // popup create partition:
  1508.                               `PushButton(`id(`ok), `opt(`default),    _("&OK")),
  1509.                               // popup create partition:
  1510.                               `PushButton(`id(`cancel), _("&Cancel"))
  1511.                               )
  1512.                         )
  1513.                   );
  1514.  
  1515.     ChangeWidget(`id(`start_cyl),   `Value, start_cyl);
  1516.     ChangeWidget(`id(`end_part),    `Value, end_part);
  1517.     SetFocus(`id(`start_cyl));
  1518.  
  1519.     boolean input_is_ok     = false;
  1520.     map     return_value    = $[];
  1521.     symbol  doit            = `cancel;
  1522.  
  1523.     repeat
  1524.           {
  1525.               //-------------------------------
  1526.               // Check the User input
  1527.               //-------------------------------
  1528.               doit = UserInput();
  1529.  
  1530.           if ( doit != `cancel )
  1531.           {
  1532.  
  1533.           return_value = $[];
  1534.  
  1535.           return_value = add( return_value, "fsid",         filesystem_id);
  1536.           return_value = add( return_value, "format",       format);
  1537.           return_value = add( return_value, "mount",        mount_point);
  1538.  
  1539.           return_value = add( return_value, "start_cyl",    QueryWidget(`id(`start_cyl),     `Value)) ;
  1540.           return_value = add( return_value, "end_part",     QueryWidget(`id(`end_part),      `Value)) ;
  1541.  
  1542.           input_is_ok = true;
  1543.  
  1544.           //////////////////////////////////////////////////////////////
  1545.           // Check if the user input for start und end cyl are valid
  1546.  
  1547.           list ret = TestStartEndCyl( lookup(return_value, "start_cyl"),
  1548.                           lookup(return_value, "end_part"),  dev, disk, type, cyl_size );
  1549.  
  1550.           if (select( ret, 0) == `error )  input_is_ok = false;
  1551.           if (select( ret, 0) == `ok )     input_is_ok = true;
  1552.           if (select( ret, 0) == `max )
  1553.           {
  1554.               input_is_ok = true;
  1555.               return_value = add( return_value, "end_part", select( ret, 1));
  1556.           }
  1557.  
  1558.               }
  1559.  
  1560.           } until (input_is_ok || doit == `cancel);
  1561.  
  1562.  
  1563.     //------------------------------------------------------------------------------------
  1564.     // Check if the start end cylinder are changed: PopUp // todo change logical cylinders
  1565.     //------------------------------------------------------------------------------------
  1566.  
  1567.     if ( doit != `cancel
  1568.      && (   lookup(return_value, "start_cyl") >  start_cyl
  1569.          || lookup(return_value, "end_part")  != end_part ))
  1570.     {
  1571.     DisplayMessage(_("Caution: You have changed the start/end cylinders.
  1572. Please make sure that all logical partitions \nfit into this new extended partition."));    
  1573.     }
  1574.      
  1575.     CloseDialog();
  1576.  
  1577.     if ( doit == `cancel )
  1578.     {
  1579.           return( nil );
  1580.     }
  1581.     else
  1582.     {
  1583.           return( return_value );
  1584.     }
  1585. }; });
  1586.  
  1587.  
  1588.  
  1589.     /*---------------------------------------------------------------------
  1590.      * EditDialog for a already existing Partitions
  1591.      *---------------------------------------------------------------------
  1592.      * targetMap  CAUTION: in Edit-Mode, the edited partion, must not be in this map!
  1593.      */
  1594.  
  1595.     UI(``{
  1596.  
  1597.              define ExistingPartitionDlg(string title, boolean format, integer filesystem_id,
  1598.                               string start_cyl, string end_part, string mount_point, map disk,
  1599.                      map targetList, symbol used_fs, integer cyl_size, boolean pdisk_disk ) ``{
  1600.  
  1601.                  // helptext for popup edit already existing partition line 1 of 3
  1602.                  string helptextCR = _("<p>For an already existing partition you can only change the mount point and format.</p>" );
  1603.                  // helptext line 2 of 3
  1604.                  helptextCR = helptextCR + _("<p>If you want to change the type or the start/end cylinder, you must delete this partition and then create a new one with the new parameters. All data in this partition will be LOST!</p>" );
  1605.  
  1606.                  OpenDialog( `opt(`decorated ),  `VBox(`Heading(title),
  1607.                         `Label(""),
  1608.                         `HBox(
  1609.                               /// left side
  1610.                               `HWeight( 66, `RichText( helptextCR )),
  1611.                               /// right side
  1612.                               `HWeight( 33, `VBox(
  1613.                                       `Top( `HBox(
  1614.                                            // popup edit existing partition: Description
  1615.                                                   `Left(`Label( _("Type of filesystem: ")
  1616.                                            // popup edit existing partition: Description
  1617.                                                                 +  _("\nStart cylinder:")
  1618.                                           // popup edit existing partition: Description
  1619.                                            +  _("\nEnd cylinder:  ") )),
  1620.                                           `Left(`Label( FsIdToString( filesystem_id )
  1621.                                                   + "\n " + start_cyl
  1622.                                                   + "\n " + end_part ))
  1623.                                           )),
  1624.                                        // popup edit existing partition: Description to  edit Mount Point
  1625.                                       `Top(`TextEntry(`id(`mount_point), _("&Mount Point:"))),
  1626.                                       // popup edit existing partition:  Framedescription to Format the disk y/n
  1627.                                       `Top(`Frame ( substring(_("2:Format"),2),
  1628.                                        `RadioButtonGroup(`id(`format),
  1629.                                                          `VBox(
  1630.                                                                 // popup edit existing partition: Selection "Do not format"
  1631.                                                                `Left(`RadioButton(`id(`unknown), _("Do ¬ format"), !format  )),
  1632.                                                                // popup edit existing partition: Selection "Format"
  1633.                                                                `Left(`RadioButton(`id(`reiser),  _("Format with &ReiserFS"),
  1634.                                           (format &&  (filesystem_id == 131) && (used_fs == `reiser)) )),
  1635.                                                                // popup edit existing partition: Selection "Format"
  1636.                                                                `Left(`RadioButton(`id(`ext2),    _("Format with &Ext2"),
  1637.                                           (format &&  (filesystem_id == 131) && (used_fs == `ext2)) )),
  1638.                                                                `Left(`RadioButton(`id(`swap),    _("Format &Swap"),
  1639.                                           (format &&  (filesystem_id == 130)) ))
  1640.                                                                )
  1641.                                                          )
  1642.                                                     )
  1643.                                            )
  1644.                                     ))
  1645.                               ),
  1646.                         `Label(""),
  1647.                         `HBox(
  1648.                               // popup edit existing partition: OK
  1649.                               `PushButton(`id(`ok), `opt(`default), _("&OK")),
  1650.                               // popup edit existing partition: Cancel
  1651.                               `PushButton(`id(`cancel), _("&Cancel"))
  1652.                               )
  1653.                         )
  1654.                   );
  1655.  
  1656.  
  1657.      // if the user choose swap ..
  1658.     if (filesystem_id == 130)    {
  1659.         ChangeWidget(`id(`mount_point), `Value,   "swap");
  1660.         ChangeWidget(`id(`reiser),      `Enabled, false );
  1661.         ChangeWidget(`id(`ext2),        `Enabled, false );
  1662.     }
  1663.     else
  1664.     {
  1665.         ChangeWidget(`id(`mount_point), `Value, mount_point);
  1666.         ChangeWidget(`id(`swap),        `Enabled, false );
  1667.     }
  1668.  
  1669.     if (filesystem_id != 130 && filesystem_id != 131)
  1670.     {
  1671.     ChangeWidget(`id(`unknown), `Enabled, false );
  1672.     ChangeWidget(`id(`reiser),  `Enabled, false );
  1673.     ChangeWidget(`id(`ext2),    `Enabled, false );
  1674.     ChangeWidget(`id(`swap),    `Enabled, false );
  1675.     }
  1676.  
  1677.     if ( pdisk_disk == true )
  1678.     {
  1679.      ChangeWidget(`id(`unknown), `Enabled, false );
  1680.      ChangeWidget(`id(`reiser),  `Enabled, false );
  1681.      ChangeWidget(`id(`ext2),    `Enabled, false );
  1682.      ChangeWidget(`id(`swap),    `Enabled, false );
  1683.     }
  1684.  
  1685.     boolean input_is_ok     = false;
  1686.     map     return_value    = $[];
  1687.     symbol  doit            = `cancel;
  1688.  
  1689.     repeat
  1690.           {
  1691.               //-------------------------------
  1692.               // Check the User input
  1693.               //-------------------------------
  1694.               doit = UserInput();
  1695.  
  1696.           if ( doit != `cancel )
  1697.           {
  1698.           input_is_ok = true;
  1699.           return_value = $[];
  1700.  
  1701.           return_value = add( return_value, "fsid",         filesystem_id) ;
  1702.           return_value = add( return_value, "used_fs",      QueryWidget(`id(`format), `CurrentButton)) ;
  1703.           return_value = add( return_value, "mount",        QueryWidget(`id(`mount_point),   `Value)) ;
  1704.           return_value = add( return_value, "start_cyl",    start_cyl) ;
  1705.           return_value = add( return_value, "end_part",     end_part) ;
  1706.           
  1707.           if ( QueryWidget(`id(`format), `CurrentButton) == `unknown )
  1708.           {
  1709.               return_value = add( return_value, "format", false );
  1710.           }
  1711.           else
  1712.           {
  1713.               return_value = add( return_value, "format", true );
  1714.           }
  1715.           
  1716.           if ( QueryWidget(`id(`format), `CurrentButton) == `swap )
  1717.           {
  1718.               // todo: should be `swap, but I have now not the time to test this
  1719.               // this should be removes after the release
  1720.               return_value = add( return_value, "used_fs",         `unknown );
  1721.           }
  1722.  
  1723.           //////////////////////////////////////////////////////////////
  1724.           // Check if the user has a reiserfs with  not enough space
  1725.           if ( input_is_ok && ( lookup(return_value, "used_fs") == `reiser) )
  1726.           {
  1727.               integer part_size = (tointeger(end_part) - tointeger(start_cyl) +1)  * cyl_size;
  1728.               
  1729.               _debug( "UUUUUUUUUUU", part_size );
  1730.               if ( part_size < 60000000 )
  1731.               {
  1732.               DisplayMessage( _("Your partition is too small, to use ReiserFS!
  1733. ReiserFS is a journaling filesystem, and the storage
  1734. of the journal needs already about 30 MB space.
  1735. So please use ReiserFS only with bigger partitions." ));
  1736.               input_is_ok = false;
  1737.               }
  1738.           }
  1739.  
  1740.           if ( input_is_ok )
  1741.           {
  1742.               if (filesystem_id == 130)
  1743.               {
  1744.               //////////////////////////////////////////////////////////////
  1745.               // Check swap mount point
  1746.               string user_input_mount = lookup(return_value, "mount", "");
  1747.               
  1748.               if ( (user_input_mount != "") && (user_input_mount != "swap") )
  1749.               {
  1750.                   DisplayMessage( _("\
  1751. You have entered an invalid mountpoint. For a swap partition, only
  1752. two mountpoints are permitted.
  1753.  - If you leave this field empty, the swap partition will NOT be used.
  1754.  - The entry \"swap\" means, that the swap partition will be used."));
  1755.                   input_is_ok = false;
  1756.               }
  1757.               }
  1758.               else
  1759.               {
  1760.               //////////////////////////////////////////////////////////////
  1761.               // Check if the user input formount point are valid
  1762.    
  1763.               string user_input_mount = lookup(return_value, "mount", "");
  1764.    
  1765.               input_is_ok = check_mount_point( targetList, user_input_mount);
  1766.               }
  1767.           }
  1768.           }
  1769.  
  1770.           } until (input_is_ok || doit == `cancel);
  1771.  
  1772.     CloseDialog();
  1773.  
  1774.     if ( doit == `cancel )
  1775.     {
  1776.           return( nil );
  1777.     }
  1778.     else
  1779.     {
  1780.           return( return_value );
  1781.     }
  1782. }; });
  1783.  
  1784.     /*---------------------------------------------------------------------
  1785.      * Dialog choose disk
  1786.      * return /dev/xxx  or nil if cancel
  1787.      *---------------------------------------------------------------------
  1788.      */
  1789.  
  1790.     UI(``{
  1791.               define ChooseDisk( map targetMap )
  1792.               ``{
  1793.                   // Header Choose disk dialog
  1794.                   term diskgroup  = `VBox();
  1795.                   list disks      = [];
  1796.                   integer       n = 0;
  1797.  
  1798.                   foreach ( `dev, `disk, targetMap, ``{ diskgroup = add ( diskgroup, `Left( `RadioButton( `id( dev ), dev, n == 0 ) ) ); n = n + 1; } );
  1799.                   foreach ( `dev, `disk, targetMap, ``{ disks     = add ( disks,  dev ); } );
  1800.  
  1801.                   if (size(disks) != 1 )
  1802.                   {
  1803.                       OpenDialog( `opt(`decorated),  `VBox(`Heading(_("On which disk do you want to create the partition?") ),
  1804.                                         `Label(""),
  1805.                                         `RadioButtonGroup( `id(`choosedisk), diskgroup ),
  1806.                                         `Label(""),
  1807.                                         `HBox(
  1808.                                               // popup edit existing partition: OK
  1809.                                               `PushButton(`id(`ok), `opt(`default), _("&OK")),
  1810.                                               // popup edit existing partition: Cancel
  1811.                                               `PushButton(`id(`cancel), _("&Cancel"))
  1812.                                               )
  1813.                                         )
  1814.                                   );
  1815.                       any ret = UserInput();
  1816.  
  1817.                       if (ret == `cancel)
  1818.                       {
  1819.                           CloseDialog();
  1820.                           return(nil);
  1821.                       }
  1822.                       else
  1823.                       {
  1824.                           ret     = QueryWidget(`id(`choosedisk), `CurrentButton);
  1825.                           CloseDialog();
  1826.                           return(ret);
  1827.                       }
  1828.                   }
  1829.                   else
  1830.                   {
  1831.                       // if there is only one disk: no
  1832.                       return( select( disks, 0 ) );
  1833.                   }
  1834.               }; });
  1835.  
  1836.  
  1837.  
  1838.     /*---------------------------------------------------------------------
  1839.      * Dialog choose primary extended or logical Partition
  1840.      * Input "PL", "PE" or "PEL"
  1841.      * return `primary or `logical or `extended or `none
  1842.      *---------------------------------------------------------------------
  1843.      */
  1844.  
  1845.     UI(``{
  1846.                   define ChoosePart( string usage )
  1847.                   ``{
  1848.                       term PL = `VBox(
  1849.                                       `Left( `RadioButton( `id(`primary ), _("&Primary partition"), true )),
  1850.                                       `Left( `RadioButton( `id(`logical ), _("&Logical partition"), false ))
  1851.                                       );
  1852.                       term PE = `VBox(
  1853.                                       `Left( `RadioButton( `id(`primary ), _("&Primary partition"), true )),
  1854.                                       `Left( `RadioButton( `id(`extended ), _("&Extended partition"), false ))
  1855.                                       );
  1856.                       term PEL = `VBox(
  1857.                                       `Left( `RadioButton( `id(`primary ), _("&Primary partition"), true )),
  1858.                                       `Left( `RadioButton( `id(`logical ), _("&Logical partition"), false )),
  1859.                                       `Left( `RadioButton( `id(`extended ), _("&Extended partition"), false ))
  1860.                                       );
  1861.  
  1862.                       term                 current = PEL;        // default
  1863.                       if ( usage == "PL" ) current = PL;
  1864.                       if ( usage == "PE" ) current = PE;
  1865.  
  1866.  
  1867.                           OpenDialog( `opt(`decorated ),  `VBox(`Heading(_("Which type of partition do you want to create?") ),
  1868.                                             `Label(""),
  1869.                                             `RadioButtonGroup( `id(`choosePL), current ),
  1870.                                             `Label(""),
  1871.                                             `HBox(
  1872.                                                   // popup edit existing partition: OK
  1873.                                                   `PushButton(`id(`ok),  `opt(`default), _("&OK")),
  1874.                                                   // popup edit existing partition: Cancel
  1875.                                                   `PushButton(`id(`cancel), _("&Cancel"))
  1876.                                                   )
  1877.                                             )
  1878.                                       );
  1879.                           any ret = UserInput();
  1880.  
  1881.                           if (ret == `cancel)
  1882.                           {
  1883.                               CloseDialog();
  1884.                               return(`none);
  1885.                           }
  1886.                           else
  1887.                           {
  1888.                               ret     = QueryWidget(`id(`choosePL), `CurrentButton);
  1889.                               CloseDialog();
  1890.                               return(ret);
  1891.                           }
  1892.                 }; });
  1893.  
  1894.     
  1895.  
  1896.     /*---------------------------------------------------------------------
  1897.      * Make a proposal for a Mountpoint
  1898.      *---------------------------------------------------------------------
  1899.      */
  1900.     
  1901.     define GetMountPointProposal( map targetMap )
  1902.     ``{
  1903.     list base = [ "/", "/usr", "/boot", "/var", "/opt", "/home" ];
  1904.  
  1905.  
  1906.     list free_list = filter( `point, base,
  1907.     ``{
  1908.         boolean found = false;
  1909.     
  1910.         foreach( `dev, `disk, targetMap,
  1911.          ``{
  1912.                    map|void parti = find( `part, lookup( disk, "partitions"), ``( lookup( part, "mount", "") == point &&
  1913.                                               lookup( part, "delete", false) == false ));
  1914.                if ( parti != nil )   found = true;
  1915.         });
  1916.  
  1917.         if (found)  return( false );
  1918.         return( true );
  1919.     });
  1920.  
  1921.     _debug( free_list );
  1922.  
  1923.     if ( size( free_list ) == 0 )
  1924.     {
  1925.         return( "/work" );
  1926.     }
  1927.     else
  1928.     {
  1929.         return( select( free_list, 0 ));
  1930.     }
  1931.                  
  1932.     };        
  1933.     /*---------------------------------------------------------------------
  1934.      * Make a output string for "you can not create a partition, because: "
  1935.      *---------------------------------------------------------------------
  1936.      */
  1937.  
  1938.  
  1939.     define FormatCauseLine( symbol cause )
  1940.     ``{
  1941.      if ( cause == `no_ext )   return( UI(_("No extended partition exists.") ));
  1942.      if ( cause == `dev_full ) return( UI(_("There exists already four primary/extended partitions.") ));
  1943.      if ( cause == `no_extsp ) return( UI(_("No space left in the extended partition.") ));
  1944.      if ( cause == `to_many )  return( UI(_("Too many logical drives already exist .") ));
  1945.      if ( cause == `no_space ) return( UI(_("No space remaining") ));
  1946.      if ( cause == `already )  return( UI(_("An extended partition already exists")));
  1947.      return( "---" );
  1948.     };
  1949.      
  1950.  
  1951.     /*---------------------------------------------------------------------
  1952.      * Make a output string for "you can not create a partition, because: "
  1953.      *---------------------------------------------------------------------
  1954.      */
  1955.  
  1956.     define FormatYouCannotCause( boolean primary_is_possible,  
  1957.                  boolean extended_is_possible, 
  1958.                  boolean logical_is_possible,  
  1959.                  symbol  no_primary_cause,     
  1960.                  symbol  no_extended_cause,
  1961.                  symbol  no_logical_cause      )     
  1962.     ``{
  1963.        string pri_line = "";
  1964.        string ext_line = "";
  1965.        string log_line = "";
  1966.  
  1967.  
  1968.        if ( primary_is_possible )      pri_line = UI(_("Primary partition creation: Is possible\n"));
  1969.                                       // example "No primary partition: No space left
  1970.        else                              pri_line = UI(_("No primary partition:  ")) +   FormatCauseLine( no_primary_cause ) + "\n";
  1971.        
  1972.        if ( logical_is_possible )     log_line = UI(_("Logical  partition creation: Is possible\n")); 
  1973.                                           // example "No logical partition: No space left
  1974.        else                             log_line = UI(_("No logical- partition:  ")) +   FormatCauseLine( no_logical_cause ) +"\n" ;
  1975.        
  1976.        if ( extended_is_possible )      ext_line = UI(_("Extendend partition creation: Is possible\n"));
  1977.                                          // example "No extended partition: No space left 
  1978.        else                             ext_line = UI(_("No extended partition: ")) +   FormatCauseLine( no_extended_cause ) +"\n";
  1979.  
  1980.        return ( pri_line + ext_line + log_line );
  1981.     };
  1982.     
  1983.     
  1984.  
  1985.     /*---------------------------------------------------------------------
  1986.      * Checks the generated partion table.  (adds whole_disk - flags to the table)
  1987.      *---------------------------------------------------------------------
  1988.      * Checkpoints:
  1989.      * - popup if unformated mounted partitions exist
  1990.      * - checks if yast can take a whole disk
  1991.      *   all partitions have a fsid have of the type 130 131 5 // all fsid 131 partitions are mounted
  1992.      *
  1993.      * todo: move the following test to this function
  1994.      * - checks if / mountpoint is set
  1995.      * - check if the boot partition ends in < 1024 cylinder (/or/boot)
  1996.      * - checks thart the boot  partition is not a reiserfs (/or/boot)
  1997.      * - check that all reiser Filesystems are bigger than 60MB
  1998.      */
  1999.       
  2000.       define check_created_partiton_table( map targetMap )
  2001.        ``{
  2002.       boolean partition_mounted_but_not_formated = false;
  2003.       boolean have_swap = false;
  2004.  
  2005.       foreach( `disk, `diskinfo, targetMap, ``{  
  2006.  
  2007.           list part_info     = lookup( diskinfo, "partitions" );
  2008.           boolean whole_disk = true;
  2009.  
  2010.           foreach( `part, part_info, ``{
  2011.  
  2012.           if ( lookup( part, "delete", false) == false )
  2013.           {
  2014.               // All valid partitions ...
  2015.               integer fsid       =  lookup( part, "fsid", 0);
  2016.               boolean is_mounted = (lookup( part, "mount", "") != "");
  2017.           
  2018.               if ( (lookup( part, "mount", "" ) == "swap" ) &&  (fsid == 130) )
  2019.               {
  2020.               have_swap = true;
  2021.               }
  2022.  
  2023.               //    | NOT
  2024.               //    v 
  2025.               if (  ! (( (fsid == 130) || (fsid == 5) ) && ((fsid == 131) && is_mounted) ) )
  2026.               {
  2027.               whole_disk = false;
  2028.               }
  2029.               
  2030.               if ( fsid == 131
  2031.                && lookup( part, "mount", nil )   != nil
  2032.                && substring( lookup( part, "mount"), 0, 1 ) == "/"
  2033.                &&            lookup( part, "format", false  ) == false )
  2034.               {
  2035.               partition_mounted_but_not_formated = true;
  2036.               }
  2037.           }
  2038.           });
  2039.            
  2040.           diskinfo  = add( diskinfo, "whole_disk", whole_disk );
  2041.           targetMap = add( targetMap, disk, diskinfo );
  2042.       } );
  2043.  
  2044.       if ( !have_swap )
  2045.       {
  2046.           UI(`DisplayMessage( _("\
  2047. You have not created and activated a swap partition. There is nothing wrong with that,
  2048. but in common it is highly recommended to create an activate a swap partition.
  2049. Created swap partitions are listed in the main window with the type \"Linux Swap\".
  2050. An activated swap partition have a mountpoint \"swap\"")) );          
  2051.       }
  2052.       
  2053.       if ( partition_mounted_but_not_formated )
  2054.       {
  2055.           UI(`DisplayMessage(_("\
  2056. You have a mounted partition, which will not be formatted. There is nothing wrong with that,
  2057. but notice that YaST2 is now not able to determine the free space exactly.
  2058. YaST2 treats this partitions like an empty partitions, because it does not know how
  2059. many space will be overwritten. So be sure, not to install to much packages.")));
  2060.       }
  2061.  
  2062.       return( targetMap );
  2063.       };          
  2064.  
  2065.  
  2066.       
  2067.     /*---------------------------------------------------------------------
  2068.      * At the moment with a pdisk-formated disk you cannot
  2069.      * create partitions
  2070.      *------------------------------------
  2071.      * in: current disk, `warn_nor | `warn_delete | `warn_create
  2072.      * out true | false
  2073.      *---------------------------------------------------------------------
  2074.      */
  2075.  
  2076.       define check_pdisk( map curr_disk, symbol warn )
  2077.     ``{
  2078.           if (filter (`pentry, lookup( curr_disk, "partitions", []),
  2079.               ``(lookup (pentry, "type", `empty) == `pdisk))
  2080.           != [] )
  2081.           {
  2082.           // This disk has an non-fdisk partition scheme 
  2083.           // only mount-point
  2084.           if ( warn == `warn_delete )
  2085.           {
  2086.               UI (`DisplayMessage (_("\
  2087. Caution: This disk has pdisk partitions
  2088.  
  2089. There is nothing wrong with that, but at the moment YaST2 cannot
  2090. delete those partitions. It can only mount pdisk partitions.
  2091. To delete pdisk partitions, switch to a virtual console and
  2092. delete those partitions manually.")));
  2093.           }
  2094.           else  if ( warn == `warn_create )
  2095.           {
  2096.               UI (`DisplayMessage (_("\
  2097. Caution: This disk has pdisk partitions
  2098.  
  2099. There is nothing wrong with that, but at the moment YaST2 cannot
  2100. create those partitions. It can only mount pdisk partitions.
  2101. To create new pdisk partitions, switch to a virtual console and
  2102. create those partitions manually.
  2103.  
  2104. The other way is to use an empty disk, without any partitions.
  2105. Then YaST2 can also create and delete partitions.")));
  2106.           }
  2107.           else  if ( warn == `warn_create )
  2108.           {
  2109.               // dont warn
  2110.           }
  2111.           
  2112.           return true;
  2113.           }
  2114.           else
  2115.           {
  2116.           return false;
  2117.           }
  2118.       };
  2119.  
  2120.       
  2121.     /////////////////////////////////////////////////////////////////////////////////////////////////////
  2122.     // MAIN:
  2123.     /////////////////////////////////////////////////////////////////////////////////////////////////////
  2124.  
  2125.     // boolean test_mode   = true;
  2126.     boolean test_mode     = false;
  2127.     map     targetMap     = $[];
  2128.     any     ret           = nil;
  2129.  
  2130.     map     testtargetMap = $[
  2131.               "/dev/sda":$[
  2132.                "bus":"SCSI",
  2133.                "name":"1. SCSI, 8.54 GB, /dev/sda, IBM-DNES-309170W",
  2134.                "cyl_count":1114,
  2135.                   "cyl_size":8224768,
  2136.                "vendor":"",
  2137.            "model": "DNES-309170-X",
  2138.                "partitions":[
  2139.                  $["delete":false, "fsid":130, "fstype":"Linux swap", "mount":"swap", "nr":4, "ori_nr":4, "region":[280, 129], "type":`primary],
  2140.                  $["delete":true,  "fsid":130, "fstype":"Linux swap",   "mount":"swap", "nr":4, "ori_nr":4, "region":[194, 65], "type":`logical],
  2141.                  $["fsid":11,
  2142.                                 "fstype":"Windows",
  2143.                                 "nr":1,
  2144.                                 "region":[1, 254],
  2145.                                 "type":`primary],
  2146.                  $["fsid":130,
  2147.                                 "fstype":"Linux swap",
  2148.                                 "nr":2,
  2149.                                 "region":[255, 16],
  2150.                                 "type":`primary],
  2151.                  $["fsid":130,
  2152.                                 "fstype":"Linux swap",
  2153.                                 "nr":2,
  2154.                                 "region":[255, 16],
  2155.                                 "type":`pdisk],
  2156.                  $["delete":true,
  2157.                  "fsid":131,
  2158.                                 "fstype":"Linux native",
  2159.                                 "nr":2,
  2160.                                 "region":[271, 844],
  2161.                                 "type":`primary]
  2162.                                ]
  2163.                            ],
  2164.               "/dev/sdb":$[
  2165.                "bus":"SCSI",
  2166.                "name":"1. SCSI, 8.54 GB, /dev/sda, IBM-DNES-309170W",
  2167.                "cyl_count":11141,
  2168.                "cyl_size":8224768,
  2169.                "vendor":"IBM DNES-309170-XEW",
  2170.                "partitions":[
  2171.                  $["fsid":131,
  2172.                                 "fstype":"Linux native",
  2173.                                 "nr":1,
  2174.                                 "format":true,
  2175.                                 "region":[1, 254],
  2176.                                 "type":`primary],
  2177.                  $["fsid":5,
  2178.                                 "fstype":"Extended",
  2179.                                 "nr":4,
  2180.                                 "region":[272, 1000],
  2181.                                 "type":`extended],
  2182.                                $["fsid":11,
  2183.                                 "fstype":"Windows",
  2184.                       "nr":2,
  2185.                                 "region":[255, 16],
  2186.                                 "type":`primary],
  2187.                                $["fsid":130,
  2188.                                 "fstype":"Linux swap",
  2189.                                 "nr":5,
  2190.                                 "region":[272, 100],
  2191.                                 "type":`logical],
  2192.                                $["fsid":130,
  2193.                                 "fstype":"Linux",
  2194.                                 "nr":6,
  2195.                                 "region":[372, 100],
  2196.                                 "type":`logical],
  2197.                                $["fsid":131,
  2198.                                 "fstype":"Linux",
  2199.                                 "nr":7,
  2200.                                 "region":[472, 300],
  2201.                                 "type":`logical],                                                
  2202.                                $["fsid":131,
  2203.                                 "fstype":"Linux native",
  2204.                                 "nr":3,
  2205.                                 "region":[1273, 9869],
  2206.                                 "type":`primary]
  2207.                ]]];
  2208.  
  2209.  
  2210.     if (!test_mode)
  2211.     {
  2212.           targetMap = lookup ( user_settings, "targets", $[] );
  2213.     }
  2214.     else
  2215.     {
  2216.           targetMap = testtargetMap;
  2217.  
  2218.           _debug( "TTTTTTT-TESTMODE ___________________-", targetMap );
  2219.           _debug( "TTTTTTT-TESTMODE ___________________-", targetMap );
  2220.           _debug( "TTTTTTT-TESTMODE ___________________-", targetMap );
  2221.           _debug( "TTTTTTT-TESTMODE ___________________-", targetMap );
  2222.     }
  2223.  
  2224.     targetMap = InitTargets( targetMap );
  2225.  
  2226.     list table_list = [];
  2227.  
  2228.     if (test_mode)
  2229.     {
  2230.           table_list = FillPartitionList(  targetMap );
  2231.           // table_list = [
  2232.           //                              `item(`id(1), "/dev/hda",      "1",  "1115", "8.5 GB",   " ", "Seagate ST 48012", " "),
  2233.           //                              `item(`id(2), "/dev/hda1",   "1",  "65",   "509.8 MB", " ", "FAT16", " "),
  2234.           //                              `item(`id(3), "/dev/hda2",   "66", "150",  "666.7 MB", " ", "NTFS", " "),
  2235.           //                              `item(`id(4), "/dev/hda3",   "301","1024", "5.5 GB",   " ", "Extended", " "),
  2236.           //                              `item(`id(5), "/dev/hda5", "301","302",  "7.8 MB",   "F", "Linux ", "/boot")
  2237.           // ];
  2238.     }
  2239.     else
  2240.     {
  2241.           table_list = FillPartitionList(  targetMap );
  2242.     }
  2243.  
  2244.     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2245.     ///                                                     MAIN DIALOG
  2246.     
  2247.     term contents = `VBox(`Label(""),
  2248.                             // for the translators:  the spaces in the column descriptions are needed for the correct column width example "     Size   "
  2249.                             `Table(`id(`table),`header(_("Device"),
  2250.                                // Column header: minimum = 5 characters   fill with space if needed
  2251.                                                        `Right(_("Start")),
  2252.                                // Column header: minimum = 4 characters   fill with space if needed
  2253.                                `Right(_("End ")),
  2254.                                // Column header: centered / minimum = 11 characters /  fill with space if needed 
  2255.                                `Right(_("     Size   ")),
  2256.                                // Column header: centered / minimum = 3 characters /  fill with space if needed 
  2257.                                                        `Right(_(" F ")),
  2258.                                // Column header  
  2259.                                _("Type"),
  2260.                                // Column header: centered / minimum = 7 characters /  fill with space if needed
  2261.                                _(" Mount ")), table_list
  2262.                                    ),
  2263.                             // main dialog: Button Create partition
  2264.                             `HBox( `PushButton(`id(`create), _("&Create") ),
  2265.                                    // main dialog: Button Delete partition
  2266.                                    `PushButton(`id(`delete), _("&Delete") ),
  2267.                                    // main dialog: Button Edit partition
  2268.                                    `PushButton(`id(`edit),   _("&Edit") ),
  2269.                                    // main dialog: Button Reset current changes and then read partition table
  2270.                                    `PushButton(`id(`reread), _("&Reset and Re-Read") )
  2271.                                    )
  2272.                             ) ;
  2273.  
  2274.     string help_text = "";
  2275.  
  2276.     // helptext expert partitioning. 1 of 16
  2277.     help_text =  UI(_("<p> Partition your hard disk(s).. </p>"));
  2278.  
  2279.     // helptext expert partitioning. 2 of 16
  2280.     help_text = help_text + UI(_("<p>
  2281. This is intended for <b>experts</b>.
  2282. If you are not familiar with the concepts of hard disk <b>partitions</b>
  2283. and how to use them, you might want to go back and select <b>automatic</b>
  2284. partitioning.
  2285. </p>"));
  2286.     // helptext expert partitioning. 3 of 16
  2287.     help_text = help_text + UI(_("<p>
  2288. Please note that <b>nothing will be written to your hard disk</b>
  2289. until you confirm the entire installation in the last installation dialog.
  2290. Until that point, you can safely abort the installation.
  2291. </p>"));
  2292.     // helptext expert partitioning. 4 of 16
  2293.     help_text = help_text + UI(_("<p>
  2294. The table to the right shows the current partitions of all of your hard disks.
  2295. </p>"));
  2296.  
  2297.     // helptext expert partitioning. 5 of 16
  2298.     help_text = help_text + UI(_("<p><b>Hard disks</b> are designated like this </p>
  2299. <tt>/dev/hda </tt>1st EIDE disk
  2300. <tt>/dev/hdb </tt>2nd EIDE disk
  2301. <tt>/dev/hdc </tt>3rd EIDE disk
  2302. <p>etc.</p>
  2303. <p>- or - </p>
  2304. <tt>/dev/sda </tt>1st SCSI disk
  2305. <tt>/dev/sdb </tt>2nd SCSI disk
  2306. <tt>/dev/sdc </tt>3rd SCSI disk"));
  2307.     // helptext expert partitioning. 6 of 16
  2308.     help_text = help_text + UI(_("<p>etc.</p>
  2309. <p>
  2310. This notation always refers to the entire disk.
  2311. </p>"));
  2312.     // helptext expert partitioning. 7 of 16
  2313.     help_text = help_text + UI(_("<p>
  2314. <b>Partitions</b> are designated like this:
  2315. </p>"));
  2316.     // helptext expert partitioning. 8 of 16
  2317.     help_text = help_text + UI(_("<p><tt>/dev/hda1 </tt>1st primary partition on the 1st EIDE disk.</p>
  2318. <p><tt>/dev/hda2 </tt>2nd primary partition on the 1st EIDE disk.</p>
  2319. <p>...</p>
  2320. <p><tt>/dev/hda5 </tt>1st logical partition within the extended partition on
  2321. the first EIDE disk. <b>Note:</b> this is always #5, even if there are less than four
  2322. primary partitions.</p>"));
  2323.     // helptext expert partitioning. 9 of 16
  2324.     help_text = help_text + UI(_("<p><tt>/dev/hda6 </tt>2nd logical partition</p>
  2325. <p>...</p>
  2326. <p><tt>/dev/sda1 </tt>etc. accordingly for SCSI.</p>"));
  2327.     // helptext expert partitioning. 10 of 16
  2328.     help_text = help_text + UI(_("<p>
  2329. On the i386 platform (i.e. normal PCs), there can be no more than four
  2330. <b>primary partitions</b> on any hard disk (since the respective table in the
  2331. master boot record can hold no more than four entries).
  2332. </p>"));
  2333.     // helptext expert partitioning. 11 of 16
  2334.     help_text = help_text + UI(_("<p>
  2335. Please note that most PCs have a <b>BIOS</b> limitation that restricts bootable
  2336. partitions to cylinders <b>1024</b> and below.
  2337. </p>"));
  2338.     // helptext expert partitioning. 12 of 16
  2339.     help_text = help_text + UI(_("<p>
  2340. In order to be able to boot from a partition, make sure it ends below this
  2341. cylinder 1024 boundary. Create a separate partition and mount it as
  2342. <b>/boot</b>, if necessary. A partition consisting of one single cylinder
  2343. (at least 2 MB) is usually sufficient for that.
  2344. </p>"));
  2345.     // helptext expert partitioning. 13 of 16
  2346.     help_text = help_text + UI(_("<p>
  2347. One of the four primary partitions may be an <b>extended partition</b>.
  2348. This extended partition can contain one or more <b>logical partitions</b>.
  2349. </p>"));
  2350.     // helptext expert partitioning. 14 of 16
  2351.     help_text = help_text + UI(_("<p>
  2352. The extended partition itself cannot hold any data.
  2353. In order to use it, you must create logical partitions within it.
  2354. Those logical partitions may contain any kind of Linux partition (Linux
  2355. file systems or Linux swap partition) as well as partitions for other
  2356. operating systems.
  2357. </p>"));
  2358.     // helptext expert partitioning. 15 of 16
  2359.     help_text = help_text + UI(_("<p>
  2360. In connection with advanced boot managers such as <b>LILO</b>, you can even
  2361. boot your computer from a logical partition.
  2362. </p>"));
  2363.     // helptext expert partitioning. 16 of 16
  2364.     help_text = help_text + UI(_("<p>
  2365. Please note that the extended partition will <b>overlap</b> with the logical
  2366. partitions: For an extended partition from cylinder 200 to 500, logical
  2367. partitions could range from (say) 200 to 250, 251 to 400 and 401 to 500.
  2368. </p>"));
  2369.     help_text = help_text + "<p>-----------<\p><\p>V.44<\p>";
  2370.  
  2371.     // Main dialog: Header
  2372.      UI(`SetWizardContents(_("Expert Partitioner"), contents, help_text, Args(0), Args(1)));
  2373.  
  2374.    string spaces  = "                                  ";
  2375.    string spaces2 = "                              ";
  2376.    string spaces3 = "                           ";
  2377.    string spaces4 = "                        ";
  2378.    string spaces5 = "                     ";
  2379.    string spaces6 = "                 ";
  2380.    string spaces7 = "              ";
  2381.    string spaces8 = "           ";
  2382.    string spaces9 = "        ";
  2383.    string spaces10 = "    ";
  2384.    string spaces11 = "  ";
  2385.    string spaces12 = " ";
  2386.    string spaces13 = "";
  2387.  
  2388.    
  2389.    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  2390.    ////  Loop for User Input ....
  2391.    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  2392.  
  2393.    
  2394.    repeat
  2395.    {
  2396.          table_list = FillPartitionList(  targetMap );
  2397.          UI( `ChangeWidget(`id(`table), `Items,  table_list));
  2398.  
  2399.         ret= UI(`UserInput());
  2400.  
  2401.         ////////////////////////////////////////////////////////////////////////////////////////////////////////
  2402.         ////  CREATE
  2403.         ////////////////////////////////////////////////////////////////////////////////////////////////////////
  2404.  
  2405.  
  2406.  
  2407.     
  2408.         if (ret == `create)
  2409.         {
  2410.             any curr_diskdev    = UI(`ChooseDisk( targetMap ));
  2411.         
  2412.         symbol  create_type = `none;
  2413.         map     curr_disk   = lookup(targetMap, curr_diskdev);
  2414.         boolean pdisk_disk  = false;
  2415.  
  2416.         ///////////////////////////////////////////////////////
  2417.         // At the moment with a pdisk-formated disk you cannot
  2418.         // create partitions: check it ...
  2419.         
  2420.             if (curr_diskdev != nil)  // check cancel-button
  2421.             {
  2422.         pdisk_disk = check_pdisk( curr_disk, `warn_create );
  2423.         }
  2424.  
  2425.         
  2426.         ///////////////////////////////////////////////////////
  2427.         // If we have a no pdisk-disk and we have a current disk
  2428.         // lets start ....
  2429.         
  2430.         if (curr_diskdev != nil && !pdisk_disk )  
  2431.             {
  2432.                 list possibilities = CheckCreatePossibilities( curr_diskdev, curr_disk );
  2433.  
  2434.                 boolean primary_is_possible  = select( possibilities, 0);
  2435.                 boolean extended_is_possible = select( possibilities, 1);
  2436.                 boolean logical_is_possible  = select( possibilities, 2);
  2437.         
  2438.         symbol  no_primary_cause     = select( possibilities, 3);
  2439.         symbol  no_extended_cause    = select( possibilities, 4);
  2440.         symbol  no_logical_cause     = select( possibilities, 5);
  2441.  
  2442.                 list|void log_slot = [];
  2443.                 list|void p_e_slot = [];
  2444.  
  2445.                 //////////////////////////////////////////////////////////
  2446.                 // Test if there is space left on the device
  2447.         log_slot = GetLogicalSlot(curr_diskdev, curr_disk);
  2448.         p_e_slot = GetSlot(curr_diskdev, curr_disk);
  2449.  
  2450.                 if (log_slot == nil && logical_is_possible ) no_logical_cause     = `no_space;
  2451.                 if (p_e_slot == nil && primary_is_possible ) no_primary_cause     = `no_space;
  2452.                 if (p_e_slot == nil && extended_is_possible) no_extended_cause    = `no_space;
  2453.         
  2454.                 if (log_slot == nil) logical_is_possible  = false;
  2455.                 if (p_e_slot == nil) primary_is_possible  = false;
  2456.                 if (p_e_slot == nil) extended_is_possible = false;
  2457.         
  2458.         
  2459.         
  2460.                 /*----------------------------------------------------------------------
  2461.                 *   At the same time is not possible, that both "logial_part_is_possible"
  2462.                 *   and "extended_part_is_possible" are true
  2463.                 *   so we have 6 possible situations
  2464.                 *
  2465.                 *   to show this we use
  2466.                 *   "P" for primary_part_is_possible
  2467.                 *   "E" for extended_part_is_possible
  2468.                 *   "L" for logial_part_is_possible
  2469.                 *
  2470.                 *   "p" for primary_part_is_possible  == false
  2471.                 *   "e" for extended_part_is_possible == false
  2472.                 *   "l" for logial_part_is_possible  == false
  2473.                 *
  2474.                 *
  2475.                 *   PE  : I can create a primary or exended part.
  2476.                 *   PL  : Extended part. exist. I can create a primary or a logical
  2477.                 *   Pel : only a priary is possible, when the extended part. has no space left
  2478.                 *
  2479.                 *   pE  : Not possible, if "E" is possible always "P" is possible too.
  2480.                 *   pL  : only a logical is possible, if together 4 primary and extended
  2481.                 *          partitions are already created
  2482.                 *   pel : no partitions are possible
  2483.                 *--------------------------------------------------------------------------*/
  2484.  
  2485.                 if ( !primary_is_possible  && !extended_is_possible && !logical_is_possible )
  2486.                 {
  2487.            
  2488.                     // ------pel--------
  2489.                     string text = sformat( UI(_("It is not possible, to create a partition on %1\n\n%2")), curr_diskdev,
  2490.                        FormatYouCannotCause( primary_is_possible,  extended_is_possible,   logical_is_possible,
  2491.                                  no_primary_cause,     no_extended_cause,      no_logical_cause  ));
  2492.                     UI(`DisplayMessage(text));
  2493.                 }
  2494.                 else if ( !primary_is_possible  && logical_is_possible )
  2495.                 {
  2496.                     //------pL----------
  2497.                     create_type = `logical;
  2498.                 }
  2499.                 else if ( !primary_is_possible  && extended_is_possible )
  2500.                 {
  2501.                     //------pE----------
  2502.                     create_type = `extended;
  2503.  
  2504.                 }
  2505.                 else if ( primary_is_possible  && !extended_is_possible && !logical_is_possible )
  2506.                 {
  2507.                     //------Pel----------
  2508.                     create_type = `primary;
  2509.                 }
  2510.                 else if ( primary_is_possible  && extended_is_possible )
  2511.                 {
  2512.                     //------PE----------
  2513.                     create_type = UI(`ChoosePart("PE"));   // curr_diskdev
  2514.                 }
  2515.                 else if ( primary_is_possible  && logical_is_possible )
  2516.                 {
  2517.                     //------PL----------
  2518.                     create_type = UI(`ChoosePart("PL"));     // popup
  2519.                 }
  2520.                 else
  2521.                 {
  2522.                     y2log( .error, "Error partition check" );
  2523.                     create_type = UI(`ChoosePart("PEL"));   // popup
  2524.                     _debug( possibilities );
  2525.                 }
  2526.  
  2527.                 if ( create_type != `none )
  2528.                 {
  2529.                     list    partitions = lookup( curr_disk, "partitions");
  2530.                     integer curr_nr    = 0;
  2531.                     list    base       = [];
  2532.             list    slot       = [];
  2533.  
  2534.                     // search for the first possible dev nr
  2535.                     if ( create_type == `primary || create_type == `extended || create_type == `logical )
  2536.                     {
  2537.                         if ( create_type == `primary || create_type == `extended)
  2538.                         {
  2539.                             base = [1,2,3,4];
  2540.                 slot = p_e_slot;
  2541.                         }
  2542.                         else  // logical
  2543.                         {
  2544.                             base = [5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
  2545.                                     40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64];
  2546.                 slot = log_slot;
  2547.                         }
  2548.  
  2549.                         //----------------------------------------------------------
  2550.                         // dev_nb List of numbers of  extende an primary partitions
  2551.                         // result: list of all free primaty|extended partition numbers
  2552.  
  2553.  
  2554.                         list dev_nb = maplist( `part, filter( `pa, partitions, ``(lookup( pa, "delete", false) == false)), ``(lookup( part, "nr") ));
  2555.                         list result = filter( `base_nr, base, ``( find(`nr, dev_nb, ``(nr == base_nr)) == nil));
  2556.  
  2557.                         curr_nr = select( sort( result ), 0 );
  2558.                     }
  2559.  
  2560.  
  2561.                     //---------------------------------------------------------------------------------------
  2562.                     // Present the Create-Popups ...
  2563.                     //---------------------------------------------------------------------------------------
  2564.  
  2565.                     string titleC = "";
  2566.                     // Popup Create Partition: Description of partition %1 and %3 are many spaces,  %2 is for example "/dev/hda3"
  2567.                     if ( create_type == `primary )  titleC =  sformat( UI(_("%1 Create a primary partition on %2 %3")), spaces, curr_diskdev, spaces );
  2568.                     // Popup Create Partition: Description of partition %1 and %3 are many spaces,  %2 is for example "/dev/hda3"
  2569.                     if ( create_type == `extended ) titleC =  sformat( UI(_("%1 Create a extended partition on %2 %3")), spaces11, curr_diskdev, spaces11 );
  2570.                     // Popup Create Partition: Description of partition %1 and %3 are many spaces,  %2 is for example "/dev/hda3"
  2571.                     if ( create_type == `logical )  titleC =  sformat( UI(_("%1 Create a logical partition on %2 %3")), spaces, curr_diskdev, spaces );
  2572.  
  2573.                     map|void  new_val = nil;
  2574.  
  2575.  
  2576.                     string start_cyl_str = sformat( "%1", select( slot, 0));
  2577.                     string end_cyl_str   = sformat( "%1", select( slot, 1));
  2578.  
  2579.                     if ( create_type == `extended )
  2580.                     {
  2581.                         new_val = UI(`CreateEditExtendedPartDlg(titleC,
  2582.                                 true,
  2583.                                 5,
  2584.                                 start_cyl_str,
  2585.                                 end_cyl_str, "",
  2586.                                 create_type,
  2587.                                 curr_diskdev,
  2588.                                 curr_disk,
  2589.                                 lookup( curr_disk, "cyl_size", 1000000),
  2590.                                 false ));
  2591.                     }
  2592.                     else
  2593.                     {
  2594.                         new_val = UI(`EditOrCreatePartDlg(titleC,
  2595.                               true,
  2596.                               131,
  2597.                               start_cyl_str,
  2598.                               end_cyl_str,
  2599.                               GetMountPointProposal(targetMap),
  2600.                               create_type,
  2601.                               curr_diskdev,
  2602.                               curr_disk,
  2603.                               lookup( curr_disk, "cyl_size", 1000000),
  2604.                               `ext2,
  2605.                               targetMap ));
  2606.                     }
  2607.  
  2608.                     if ( new_val != nil )
  2609.                     {
  2610.                         // $["fsid":131, "fstype":"Linux native", "nr":1, "region":[0, 255], "type":`primary],
  2611.                         map new_part = $[];
  2612.  
  2613.                         new_part = add( new_part, "create", true );
  2614.                         new_part = add( new_part, "nr",     curr_nr );
  2615.                         new_part = add( new_part, "type",   create_type );
  2616.                         new_part = add( new_part, "fsid",     lookup( new_val, "fsid") );
  2617.                         new_part = add( new_part, "format",   lookup( new_val, "format") );
  2618.                         new_part = add( new_part, "mount",    lookup( new_val, "mount") );
  2619.                         new_part = add( new_part, "used_fs",  lookup( new_val, "used_fs", `unknown));
  2620.  
  2621.                         list region = add( [],       tointeger( lookup( new_val, "start_cyl")));
  2622.                         region  = add( region, UI(`ToEndRegion( lookup( new_val, "start_cyl"),
  2623.                                 lookup( new_val, "end_part"),
  2624.                                 lookup( curr_disk, "cyl_size", 1000000))));
  2625.  
  2626.                         new_part   = add( new_part, "region", region );
  2627.                         partitions = add( partitions, new_part );
  2628.                         curr_disk  = add( curr_disk, "partitions", partitions );
  2629.  
  2630.                         targetMap = add( targetMap, curr_diskdev, curr_disk );
  2631.                     }
  2632.                 }
  2633.             }
  2634.         }
  2635.  
  2636.       ////////////////////////////////////////////////////////////////////////////////////////////////////////
  2637.       ////  EDIT
  2638.       ////////////////////////////////////////////////////////////////////////////////////////////////////////
  2639.  
  2640.         if (ret == `edit)
  2641.         {
  2642.           any w_id = UI( `QueryWidget(`id(`table), `CurrentItem) );
  2643.  
  2644.           // notify a line is selected
  2645.           if ( w_id != nil )
  2646.           {
  2647.  
  2648.             string id = UI( `QueryWidget(`id(`table), `CurrentItem) );
  2649.  
  2650.             // the user is not allowed to select a disk, he must select a partition
  2651.             if ( substring( id, 2, 1) != "." )
  2652.             {
  2653.         // %1 is a disk device, example: You have selected the disk /dev/hda, but can only edit a partition like /dev/hda11, /dev/hda2, 
  2654.                 UI(`DisplayMessage(sformat(UI(_("\n You have selected the disk %1, but can \n  only edit a partition like %11, %12, ... \n")), id )));
  2655.             }
  2656.             else
  2657.             {
  2658.                 // parse "id" of the seklected line:
  2659.                 string dev         = substring( id, 3 );
  2660.                 integer number     = tointeger( substring( id , 0, 2));
  2661.  
  2662.                 // read the data of the selected partition from the db (user_settings.targets)
  2663.                 string devStr      = sformat("%1%2", dev, number );
  2664.                 map curr_disk      = lookup( targetMap, dev );
  2665.  
  2666.         // check if it is a pdisk disk, then editing is restricted
  2667.         boolean pdisk_disk = check_pdisk( curr_disk, `warn_not );
  2668.  
  2669.                 map  curr_part                  = find  ( `c_part, lookup( curr_disk, "partitions"), ``(lookup(c_part, "nr")==number
  2670.                                                     && (lookup(c_part, "delete", false) == false) ));
  2671.                 list partitions_without_current = filter( `c_part, lookup( curr_disk, "partitions"), ``(!(lookup(c_part, "nr")==number
  2672.                                                     && (lookup(c_part, "delete", false) == false) )));
  2673.                 map disk_without_current   = add( curr_disk, "partitions", partitions_without_current);
  2674.                 map target_without_current = add( targetMap, dev, disk_without_current );
  2675.  
  2676.                 string start_cyl = sformat( "%1", select(lookup(curr_part, "region"), 0));
  2677.                 string end_cyl   = sformat( "%1", select(lookup(curr_part, "region"), 0) +
  2678.                                                   select(lookup(curr_part, "region"), 1) -1 );
  2679.  
  2680.  
  2681.                 boolean input_is_ok = false;
  2682.  
  2683.                 integer fs            = 130;
  2684.                 boolean format        = false;
  2685.                 string  mount_point   = "";
  2686.                 string  erg_start_cyl = "";
  2687.                 string  end_part      = "";
  2688.  
  2689.                 map | void  new_val = $[];              // new values as map
  2690.  
  2691.                 //////////////////////////////////////
  2692.                 // There are three different Editors:
  2693.                 // - "normal"
  2694.                 // - extended
  2695.                 // - already existing
  2696.  
  2697.                 if ( IsExtended( lookup(curr_part, "fsid") ))
  2698.                 {
  2699.             if ( lookup(curr_part, "create", false) == true )
  2700.             {
  2701.             ////////////////////////////////////////////////////////////////
  2702.             // header of the Dialog Create a partition (Please don t use
  2703.             // a shorter translation, In doubt fill with Blanks left and right)
  2704.             string title = UI(spaces10)+UI(_("Edit an extended partition "))+ UI(devStr)+ UI(spaces10);
  2705.             new_val = UI(`CreateEditExtendedPartDlg( title,
  2706.                                  lookup(curr_part, "format", false),
  2707.                                  lookup(curr_part, "fsid", 130),
  2708.                                  start_cyl,
  2709.                                  end_cyl,
  2710.                                  lookup(curr_part, "mount", ""),
  2711.                                  lookup(curr_part, "type"),
  2712.                                  devStr,
  2713.                                  disk_without_current,
  2714.                                  lookup( curr_disk, "cyl_size", 1000000),
  2715.                                  true
  2716.                                  ));
  2717.             }
  2718.             else
  2719.             {
  2720.             UI(`DisplayMessage( _("An already existing extended partition cannot be changed!
  2721. You must delete this partition and then create a new one with the new parameters.
  2722. All data in this partition will be LOST!" )));
  2723.             new_val = nil;
  2724.             }
  2725.                 }
  2726.                 else if ( !lookup(curr_part, "create", false) )
  2727.                 {
  2728.             ///////////////////////////////////////////////////////////////////////////////////////
  2729.                     // header of the Dialog Create a partition (Please don t use a shorter
  2730.             // translation, In doubt fill with Blanks left and right)
  2731.                     string title = UI(spaces8)+UI(_("Edit an already existing partition "))+ UI(devStr)+ UI(spaces8);
  2732.  
  2733.                     new_val =  UI(`ExistingPartitionDlg(title,
  2734.                             lookup(curr_part, "format", false),
  2735.                             lookup(curr_part, "fsid", 130),
  2736.                             start_cyl,
  2737.                             end_cyl,
  2738.                             lookup(curr_part, "mount", ""),
  2739.                             disk_without_current,
  2740.                             target_without_current,
  2741.                             lookup( curr_part, "used_fs", `unknown),
  2742.                             lookup( curr_disk, "cyl_size", 1000000),
  2743.                             pdisk_disk
  2744.                             ));
  2745.                 }
  2746.                 else
  2747.                 {
  2748.             ///////////////////////////////////////////////////////////////////////////////////////
  2749.                     // header of the Dialog Create a partition (Please don t use a
  2750.             // shorter translation, In doubt fill with Blanks left and right)
  2751.                     string title = UI(spaces2)+UI(_("Edit a partition"))+ UI(devStr)+ UI(spaces2);
  2752.  
  2753.                     new_val = UI(`EditOrCreatePartDlg(title, lookup(curr_part, "format", false),lookup(curr_part, "fsid", 130),
  2754.                               start_cyl, end_cyl,
  2755.                               lookup(curr_part, "mount", ""),
  2756.                               lookup(curr_part, "type"),
  2757.                               devStr, disk_without_current,
  2758.                               lookup( curr_disk, "cyl_size", 1000000),
  2759.                               lookup( curr_part, "used_fs", `unknown),
  2760.                               target_without_current
  2761.                               ));
  2762.  
  2763.                 }
  2764.  
  2765.                 if ( new_val != nil )   // not canceld
  2766.                 {
  2767.                     curr_part = add( curr_part, "fsid",    lookup( new_val, "fsid") );
  2768.                     curr_part = add( curr_part, "format",  lookup( new_val, "format") );
  2769.                     curr_part = add( curr_part, "mount",   lookup( new_val, "mount") );
  2770.                     curr_part = add( curr_part, "used_fs", lookup( new_val, "used_fs", `unknown));
  2771.  
  2772.                     list region = add( [],      tointeger( lookup( new_val, "start_cyl")));
  2773.                     region = add( region, UI(`ToEndRegion( lookup( new_val, "start_cyl"),
  2774.                                lookup( new_val, "end_part"),
  2775.                                lookup( curr_disk, "cyl_size", 1000000))));
  2776.  
  2777.                     curr_part = add( curr_part, "region", region );
  2778.  
  2779.                     list r_part = filter( `c_part, lookup( curr_disk, "partitions"),
  2780.                                           ``(lookup(c_part, "nr")!=number || (lookup(c_part, "delete", false) == true)));
  2781.                     r_part    = add( r_part,    curr_part );
  2782.                     curr_disk = add( curr_disk, "partitions", r_part );
  2783.                     targetMap = add( targetMap, dev, curr_disk );
  2784.                 }
  2785.             }
  2786.           }
  2787.           else
  2788.           {
  2789.               // No line is selcted:
  2790.               UI(`DisplayMessage(_("To edit a partition, you have to select one in main dialog") ));
  2791.           }
  2792.         }
  2793.  
  2794.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  2795.         // DELETE
  2796.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  2797.  
  2798.         if (ret == `delete)
  2799.         {
  2800.              string id = UI( `QueryWidget(`id(`table), `CurrentItem) );
  2801.  
  2802.          
  2803.             // the user is not allowed to select a disk, he must select a partition
  2804.             if ( substring( id, 2, 1) != "." )
  2805.             {
  2806.                 UI(`DisplayMessage(sformat(UI(_("\n You have selected the disk %1, but can \n  only delete a partition like %11, %12, ... \n")), id )));
  2807.  
  2808.             }
  2809.             else
  2810.             {
  2811.                 //////////////////////////////////////////////////////////////////////////////
  2812.                 // delete algorithm:
  2813.                 // if you find newly created (but until now not realy written) partition
  2814.                 //    (sign: "create = true"): delete it
  2815.                 // else there must be already existing partition: mark it with "delete = true"
  2816.                 //
  2817.  
  2818.                 string  dev       = substring( id, 3 );
  2819.                 integer number    = tointeger( substring( id , 0, 2));
  2820.                 map     curr_disk = lookup(    targetMap, dev );
  2821.  
  2822.         ///////////////////////////////////////////////////////
  2823.         // At the moment with a pdisk-formated disk you cannot
  2824.         // create/delete partitions: check it ...
  2825.         
  2826.         boolean pdisk_disk = check_pdisk( curr_disk, `warn_delete );
  2827.  
  2828.         if ( !pdisk_disk )
  2829.         {
  2830.             list curr_partitions = lookup( curr_disk, "partitions");
  2831.             map curr_part = find( `parti, curr_partitions, ``( (lookup(parti,"nr") == number) && (lookup( parti,"delete",false) == false)));
  2832.  
  2833.  
  2834.             if ( fdisk_type == `intel )
  2835.             {
  2836.             // if it is an extended partition -> delete all logical!
  2837.             // -----------
  2838.             // remove all partition with a "nr" >= 5  i.e. all logical
  2839.             // we dont need to mark already existing part. with delete,
  2840.             // because fdisk deletes the logical automaticly
  2841.             // also, when a deleted extended is newly created cause the delete operation
  2842.             // is done!
  2843.  
  2844.  
  2845.             if ( lookup( curr_part, "type") == `extended )
  2846.             {
  2847.                 curr_partitions = filter( `parti, curr_partitions, ``(lookup(parti,"nr")< 5));
  2848.             }
  2849.             }
  2850.  
  2851.  
  2852.             map|void part_created = find( `parti, curr_partitions, ``( (lookup(parti,"nr") == number) && (lookup( parti,"create",false ) == true)));
  2853.  
  2854.             if ( part_created == nil )
  2855.             {
  2856.             // No newly created found...
  2857.             // Mark already existant with "delete"
  2858.             curr_partitions =  maplist( `parti, curr_partitions, ``(
  2859.             {
  2860.                 if ( lookup( parti, "nr" ) == number )
  2861.                 {
  2862.                 return( add( add( parti, "delete", true ), "nr", lookup( parti, "ori_nr") ));
  2863.                 }
  2864.                 else
  2865.                 {
  2866.                 return( parti );
  2867.                 }
  2868.             }));
  2869.             }
  2870.             else
  2871.             {
  2872.             // delete newly created partition
  2873.             curr_partitions = filter( `parti, curr_partitions,
  2874.                           ``(  !  ((lookup( parti, "nr" ) == number) && (lookup( parti, "create", false ) == true))  ));
  2875.             }
  2876.  
  2877.             ///////////////////////////////////////////////
  2878.             // If you delete a logical partition you must decrease the number of every logical partition,
  2879.             // that has a higher number than the deleted
  2880.             // start: sda1 sda2 sda5 sda6 sda7 sda8 sda9 sda10
  2881.             // delete sda7
  2882.             // you must sda8 -> sda7   sda9 -> sda8     sda10 -> sda9
  2883.             // end with: sda1 sda2 sda5 sda6 sda7 sda8 sda9
  2884.  
  2885.             if ( lookup( curr_part, "type" )  == `logical )
  2886.             {
  2887.             curr_partitions = maplist( `parti, curr_partitions , ``(
  2888.             {
  2889.                 // only the valid ones
  2890.                 if ( (lookup( parti,"delete",false) == false) &&  (lookup( parti, "nr") > number) )
  2891.                 {
  2892.                 return( add( parti, "nr",  lookup( parti, "nr")-1  ));
  2893.                 }
  2894.                 else
  2895.                 {
  2896.                 return( parti );
  2897.                 }
  2898.             }));
  2899.             }
  2900.  
  2901.             curr_disk = add(  curr_disk, "partitions",  curr_partitions );
  2902.  
  2903.             targetMap = add( targetMap, dev, curr_disk );
  2904.         }
  2905.             }
  2906.  
  2907.             ////////////////////////////////////////////////////////////////////////////////////////////////////
  2908.             ////////////////////////////////////////////////////////////////////////////////////////////////////
  2909.         }
  2910.  
  2911.  
  2912.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  2913.         // REREAD
  2914.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  2915.  
  2916.         if (ret == `reread)
  2917.         {
  2918.        any ret2 = UI(`YesOrNo(_("Do you really want to reread the partiton table?\nAll current changes will be lost!"),
  2919.                   _("&Yes"), _("&No") ) ); 
  2920.  
  2921.             if (ret2 == true)
  2922.             {
  2923.                 foreach( `dev, `disk, targetMap,
  2924.                 ``{
  2925.                     _debug( "reread dev", dev);
  2926.                     path diskpath   = topath ("." + substring (dev, 5));
  2927.                     list partitions = check4partitions (diskpath, architecture);
  2928.  
  2929.                     disk = add (disk, "partitions", partitions);
  2930.  
  2931.                     // add constructed target map to list of all targets
  2932.  
  2933.                     targetMap = add (targetMap, dev, disk);
  2934.                     targetMap = InitTargets( targetMap );
  2935.  
  2936.                 });
  2937.             }
  2938.         }
  2939.  
  2940.     
  2941.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  2942.         // End of Actions, Now check the returncode
  2943.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  2944.     
  2945.         if (ret == `next || ret == `back)
  2946.         {
  2947.         _debug ("WHOLLLLLLE", targetMap );
  2948.         
  2949.         if ( ret == `next )
  2950.             {
  2951.         targetMap = check_created_partiton_table( targetMap );
  2952.         _debug ("WHOLLLLLLE", targetMap );
  2953.         }
  2954.         
  2955.         // write partition information
  2956.         user_settings = add(user_settings, "targets", targetMap );
  2957.         
  2958.         // force re-evaluation of lilo settings in inst_lilo_info later
  2959.         user_settings = add (user_settings, "lilo", "" );
  2960.         user_settings = add (user_settings, "lilo_device", "" );
  2961.         
  2962.              if ( ret != `back )
  2963.              {
  2964.                 if (ret == `apply) return `again;
  2965.                 // checking targetMap
  2966.                 if (ret == `next)
  2967.                 {
  2968.                     boolean swap_found = false;
  2969.                     boolean boot_found = false;
  2970.                     boolean root_found = false;
  2971.             integer boot_end = 0;
  2972.             integer root_end = 0;
  2973.             symbol  root_fs  = `unknown;
  2974.             symbol  boot_fs  = `unknown;
  2975.             
  2976.                     list avail_part = get_partition_info( targetMap, false );
  2977.  
  2978.                     foreach ( `part, avail_part, ``{
  2979.                         if ( lookup( part, "name" ) == "/" )
  2980.                         {
  2981.                             root_found = true;
  2982.                 root_end   =  select(lookup( part, "region"), 0) + select(lookup( part, "region"), 1) -1;
  2983.                 root_fs    =         lookup( part, "used_fs", `unknown );
  2984.                         }
  2985.                         else if ( lookup( part, "name" ) == "/boot" )
  2986.                         {
  2987.                             boot_found = true;
  2988.                 boot_end   =  select(lookup( part, "region"), 0) + select(lookup( part, "region"), 1) -1;
  2989.                 boot_fs    =         lookup( part, "used_fs", `unknown );
  2990.                         }
  2991.  
  2992.                     } );
  2993.  
  2994.             if ( !root_found )
  2995.                     {
  2996.                         UI(`DisplayMessage(_("\
  2997. YaST2 needs at least one partition to install SuSE Linux:\n\
  2998. the root \"/\" partition.\n\
  2999. Please create the requested mountpoint." ))); 
  3000.  
  3001.                         return `again;
  3002.                     }
  3003.             
  3004.             if ( boot_found )
  3005.             {  
  3006.                         if ( boot_end >= 1024 )
  3007.             {
  3008.                 any ret = UI(`YesOrNo(_("\
  3009. Warning: With the current selection your SuSE Linux
  3010. installation will not be directly bootable. 
  3011. Your boot partition has a end cylinder over 1024.
  3012. \nDo you want to change this?"),  _("&Yes"), _("&No") ) );
  3013.                 
  3014.                 if (ret == true) return `again;
  3015.                 return `next;
  3016.             }
  3017.  
  3018.             if ( boot_fs == `reiser )
  3019.             {
  3020.                 UI(`DisplayMessage(_("\
  3021. In the current version, LILO cannot per default boot a boot-partition with Reiser
  3022. Filesystem. Please choose Ext2 as the filesystem for the with /boot
  3023. mounted partition" )));
  3024.                 return `again; 
  3025.             }
  3026.             }
  3027.             else
  3028.             {
  3029.             if ( root_fs == `reiser )
  3030.             {
  3031.                 UI(`DisplayMessage(_("\
  3032. In the current version, LILO cannot per default boot partition with ReiserFS.
  3033. Please choose Ext2 as the filesystem for your root partition
  3034. or create a small boot-partition (10MB) with Ext2, and mount it as /boot" )));
  3035.                 return `again; 
  3036.             }
  3037.  
  3038.                         // no boot but root
  3039.             if ( root_end >= 1024 )
  3040.             {
  3041.                 any ret = UI(`YesOrNo(_("\
  3042. Warning: With the current selection your SuSE Linux
  3043. installation will not be directly bootable. 
  3044. Your boot partition root has a end cylinder over 1024.
  3045. \nDo you want to change this?"),  _("&Yes"), _("&No") ) );
  3046.                 
  3047.                 if (ret == true) return `again;
  3048.                 return `next;
  3049.             }
  3050.             }
  3051.                 }
  3052.             }
  3053.  
  3054.             if ( ret != `back )
  3055.             {
  3056.                 if (ret == `apply) return `again;
  3057.             }
  3058.         }
  3059.  
  3060.   } until (ret == `next || ret == `back || ret == `cancel);
  3061.  
  3062.   return ret;
  3063.  
  3064.  
  3065. }
  3066.