/**
 * Module: 		FileSystems.ycp
 *
 * Authors:		Johannes Buchhold (jbuch@suse.de)
 *
 * Purpose:
 * These module contains the supported filesystems and their settings.
 *
 *
 * $Id: FileSystems.ycp 22850 2005-03-30 09:54:08Z fehr $
 */
{
  module "FileSystems";
  textdomain "storage";
  import "Arch";
  import "String";
  import "Partitions";
  import "Popup";
  import "Encoding";

  import "Mode";
  import "Stage";




  global list<string> system_m_points = [ "/", Partitions::BootMount(), "/usr",
                                          "/var", "/opt" ];
  global list<string> crypt_m_points = [ "/", Partitions::BootMount(), "/usr" ];
  global list<string> suggest_m_points = (list<string>)union( system_m_points,
                                        [ "/home", "/srv", "/tmp", "/local", ""] );
  global list<string> swap_m_points   = [ "swap", ""  ];

  global string nchars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

define list FstabOptionStrings = 
    [ "defaults", 
      "auto", "noauto",
      "atime", "noatime",
      "ro", "rw",
      "user", "nouser",
      "acl", "noacl",
      "user_xattr", "no_user_xattr",
      "data=journal", "data=ordered", "data=writeback",
      "dev", "nodev", 
      "exec", "noexec", 
      "suid", "nosuid", 
      "async", "sync", "dirsync",
      "procuid", 
      "barrier=none",
      "fs=floppyfss", "fs=cdfss",
      "users", "gid=users"
      ];

define list FstabOptionRegex = [ "pri=[0-9]\+", "iocharset=.\+", "utf8=\.*",
                                 "nls=.\+", "codepage=.\+", 
				 "gid=[0-9]\+", "umask=[0-7]\+",
				 "loop=.\+", "encryption=.\+" ];

define map FstabDefaultMap =
    $[ "pts":    $[ "spec":"devpts", "mount":"/dev/pts", "vfstype":"devpts",
		    "mntops":"mode=0620,gid=5", "freq":0, "passno":0 ],
       "proc":   $[ "spec":"proc", "mount":"/proc", "vfstype":"proc", 
                    "mntops":"defaults", "freq":0, "passno":0 ],
       "sys":    $[ "spec":"sysfs", "mount":"/sys", "vfstype":"sysfs", 
                    "mntops":"noauto", "freq":0, "passno":0 ],
       "swap":   $[ "spec":"", "mount":"swap", "vfstype":"swap", 
                    "mntops":"pri=42", "freq":0, "passno":0 ],
       "root":   $[ "spec":"", "mount":"", "vfstype":"auto", 
                    "mntops":"defaults", "freq":1, "passno":1 ],
       "dev":    $[ "spec":"", "mount":"", "vfstype":"auto", 
                    "mntops":"noauto,user", "freq":0, "passno":0 ],
       "nfs":    $[ "spec":"", "mount":"", "vfstype":"nfs", 
                    "mntops":"defaults", "freq":0, "passno":0 ],
       "usb":    $[ "spec":"usbfs", "mount":"/proc/bus/usb", "vfstype":"usbfs", 
                    "mntops":"noauto", "freq":0, "passno":0 ],
       "cdrom":  $[ "spec":"", "mount":"", "vfstype":"subfs", 
                    "mntops":"noauto,fs=cdfss,ro,procuid,nosuid,nodev,exec", 
		    "freq":0, "passno":0 ],
       "floppy": $[ "spec":"", "mount":"", "vfstype":"subfs", 
                    "mntops":"noauto,fs=floppyfss,procuid,nodev,nosuid,sync", 
		    "freq":0, "passno":0 ],
       "zip":    $[ "spec":"", "mount":"", "vfstype":"auto", 
                    "mntops":"noauto,user", "freq":0, "passno":0 ]
     ];

  /* All supported filesystems */
  map<symbol, boolean> support 	= $[
		   `reiser	: true,
		   `xfs		: true,
		   `ext2        : true,
		   `ext3        : true,
		   `jfs    	: false,
		   `fat16  	: true,
		   `fat32  	: true,
		   `xxefi  	: false,
		   `xbootdisk  	: false,
		   `xbootfat  	: false,
		   `xhibernate 	: true,
		   `raid       	: true,
		   `lvm        	: true
  ];

  map<symbol, map<string, any> > capabilities = $[
		   `reiser	: $[
		                     "extend":true,
				     "shrink":true,
		                     "mount_extend":true,
				     "uuid" : true,
				     "label_length" : 16,
				     "label" : true
				   ],
		   `xfs		: $[
		                     "extend":true,
		                     "mount_extend":true,
				     "label_length" : 12,
				     "set_label_mount" : true,
				     "uuid" : true,
				     "label" : true
				   ],
		   `ext2        : $[
		                     "extend":true,
		                     "shrink":true,
				     "uuid" : true,
				     "label_length" : 16,
				     "set_label_mount" : true,
				     "label" : true
				   ],
		   `ext3        : $[ "extend":true,
		                     "shrink":true,
				     "uuid" : true,
				     "label_length" : 16,
				     "set_label_mount" : true,
				     "label" : true
				   ],
		   `jfs    	: $[
				   ],
		   `fat16  	: $[ "shrink":true,
				     "parted" : true,
				   ],
		   `fat32  	: $[ "shrink":true,
				     "parted" : true,
				   ],
		   `ntfs  	: $[ "extend":true,
		                     "shrink":true
				   ],
		   `swap  	: $[ "extend":true,
		                     "shrink":true,
				   ],
		   `unknown  	: $[
				   ],
  ];



    /**
     * Return a map that contains the mount option for each used_fs (-t)
     * @return map
     */
  /*
    to mount_string
    global define used2typeMap()
    ``{
	return $[
		 `ext2   : "ext2",
		 `ext3   : "ext3",
		 `reiser : "reiserfs",
		 `xfs    : "xfs",
		 `jfs    : "jfs",
		 `fat16  : "vfat",
		 `fat32  : "vfat" ];
    };
  */

global define list<map<symbol, any> > GetGeneralFstabOptions()
    ``{
    list<map<symbol, any> > options =
	[ $[
	     // button text
	     `widget : `Left(`CheckBox(`id("opt_readonly"), _("Mount &read-only"), false)),
	     `query_key : "opt_readonly",
	     // help text, richtext format
	     `help_text : _("<p><b>Mount Read-Only:</b>
No writable access to the file system is possible. Default is false.</p>
"),
             `type : `boolean,
	     `str_opt : $[ 1 : "ro", "default" : "" ],
	     `str_scan : [[ "ro", 1 ], ["rw", 0 ]],
	   ],
	  $[
	     // button text
	     `widget : `Left(`CheckBox(`id("opt_noatime"), _("No &access time"), false)),
	     `query_key : "opt_noatime",
	     // help text, richtext format
	     `help_text : _("<p><b>No access time:</b>
Access times are not updated when a file is read. Default is false.</p>"),
             `type : `boolean,
	     `str_opt  : $[ 1 : "noatime", "default" : "" ],
	     `str_scan : [[ "noatime", 1 ], ["atime", 0 ]],
	   ],
	  $[
	     // button text
	     `widget : `Left(`CheckBox(`id("opt_user"), _("Mountable by &user"), false)),
	     `query_key : "opt_user",
	     // help text, richtext format
	     `help_text : _("<p><b>Mountable by User:</b>
The file system may be mounted by an ordinary user. Default is false.</p>
"),
             `type : `boolean,
	     `str_opt  : $[ 1 : "user", "default" : "" ],
	     `str_scan : [[ "nouser", 0 ], ["user", 1 ]],
	   ],
	  $[
	     // button text
	     `widget : `Left(`CheckBox(`id("opt_noauto"), `opt(`notify), _("Do Not Mount at System &Start-up"), false)),
	     `query_key : "opt_noauto",
	     // help text, richtext format
	     `help_text : _("<p><b>Not Mounted at System Start-up:</b>
The file system is not automatically mounted when the system starts.
An entry in /etc/fstab is created and the file system is mounted
with the appropriate options when the command <tt>mount &lt;mount point&gt;</tt>
(&lt;mount point&gt; is the directory to which the file system is mounted)
is given. Default is false.</p>
"),
             `type : `boolean,
	     `str_opt  : $[ 1 : "noauto", "default" : "" ],
	     `str_scan : [[ "noauto", 1 ], ["auto", 0 ]],
	   ]
	];
    return( options );
    };

global define list< map<symbol, any> > GetJournalFstabOptions()
    ``{
    list< map<symbol, any> > options =
	[ $[
	     `widget : `VBox( `ComboBox(`id("opt_journal"), `opt(`hstretch),
					// label text
					_("Data &Journaling Mode"),
					["journal", "ordered", "writeback"]),
			      `VSpacing(0.5)),
	     `default   : "ordered",
	     `query_key : "opt_journal",
	     `type : `text,
	     // help text, richtext format
	     `help_text : _("<p><b>Data Journaling Mode:</b>
Specifies  the  journaling  mode  for  file  data.
journal -- All data is committed into the  journal  prior  to  being
written into the main file system.
ordered -- All data is forced directly out to the main file system
prior to its  metadata  being committed to the journal.
writeback -- Data ordering is not preserved.</p>
"),
	     `str_opt : "data=%1",
	     `str_scan : "data=\(.*\)"
	   ]
	];
    return( options );
    };

global define list< map<symbol, any> > GetAclFstabOptions()
    ``{
    list< map<symbol, any> > options =
	[ $[
	     // button text
	     `widget : `Left(`CheckBox(`id("opt_acl"), _("&Access Control Lists (ACL)"), false)),
	     `query_key : "opt_acl",
	     // help text, richtext format
	     `help_text : _("<p><b>Access Control Lists (ACL):</b>
Enable access control lists on the file system.</p>
"),
             `type : `boolean,
	     `default : true,
	     `str_opt : $[ 0 : "noacl", "default" : "acl" ],
	     `str_scan : [[ "acl", 1 ], ["noacl", 0 ]],
	   ],
	  $[
	     // button text
	     `widget : `Left(`CheckBox(`id("opt_eua"), _("&Extended User Attributes"), false)),
	     `query_key : "opt_eua",
	     // help text, richtext format
	     `help_text : _("<p><b>Extended User Attributes:</b>
Allow extended user attributes on the file system.</p>
"),
             `type : `boolean,
	     `str_opt  : $[ 1 : "user_xattr", "default" : "" ],
	     `str_scan : [[ "user_xattr", 1 ], ["no_user_xattr", 0 ]],
	   ],
	];
    return( options );
    };

global define map<symbol, any> GetArbitraryOptionField()
    ``{
    map<symbol,any> opt = $[
	     // label text
	     `widget : `TextEntry(`id("opt_arbitrary"), _("Arbitrary option &value"), ""),
	     `query_key : "opt_arbitrary",
	     // help text, richtext format
	     `help_text : _("<p><b>Arbitrary Option Value:</b>
In this field, type any legal mount option allowed in the fourth field of /etc/fstab.
Mutiple options are separated by commas.</p>
"),
             `type : `text
	   ];
    return( opt );
    };

define map<symbol, map<symbol, any> > GetNormalFilesystems()``{

  list< map<symbol, any> > fat_fst_options =
      [
	$[
	   // label text
	   `widget : `ComboBox(`id("opt_iocharset"), `opt(`editable,`hstretch), _("Char&set for file names"),
	                       ["", "iso8859-1", "iso8859-15", "iso8859-2",
			        "iso8859-5", "iso8859-7", "iso8859-9", "utf8",
			        "koi8-r", "euc-jp", "sjis", "gb2312", "big5", "euc-kr" ]),
	   `query_key : "opt_iocharset",
	   `type : `text,
	     // help text, richtext format
	   `help_text : _("<p><b>Charset for File Names:</b>
Set the charset used for display of file names in Windows partitions.</p>
"),
	   `str_opt : "iocharset=%1",
	   `str_scan : "iocharset=\(.*\)"
	 ],
	$[
	   // label text
	   `widget : `ComboBox(`id("opt_codepage"), `opt(`editable,`hstretch), _("Code&page for short FAT names"),
	                       ["", "437", "852", "932", "936", "949", "950" ]),
	   `query_key : "opt_codepage",
	   `type : `text,
	     // help text, richtext format
	   `help_text : _("<p><b>Codepage for Short FAT Names:</b>
This codepage is used for converting to shortname characters on FAT file systems.</p>
"),
	   `str_opt : "codepage=%1",
	   `str_scan : "codepage=\(.*\)"
	 ]
      ];

  list< map<symbol, any> > fat32_options =
      [
       $[
	 // label text
	 `widget		: `ComboBox(`id("opt_number_of_fats"), `opt(`hstretch), _("Number of &FATs"), ["auto" , "1", "2"  ]),
	 `query_key	: "opt_number_of_fats",
	 `option_str	: "-f",
	     // help text, richtext format
	 `help_text	: _("<p><b>Number of FATs:</b>
Specify the number of file allocation tables in the file system. The default is 2.</p>")
       ],
	 $[
	 // label text
	   `widget	: `ComboBox(`id("opt_fat_size"), `opt(`hstretch), _("FAT &size"), ["auto",
											  `item(`id("12"), "12 bit"),
											  `item(`id("16"), "16 bit"),
											  `item(`id("32"), "32 bit") ]),
	   `query_key 	: "opt_fat_size",
	   `option_str	: "-F",
	     // help text, richtext format
	   `help_text	: _("<p><b>FAT size:</b>
Specifies the type of file allocation tables used (12,  16,  or  32-bit). If auto is specified, YaST2 will automatically select the value most suitable for the file system size.</p>
")
	 ],
	 $[
	 // label text
	   `widget 	: `TextEntry(`id("opt_root_dir_entries"), `opt(`hstretch), _("Root &dir entries"), "auto"),
	   `query_key 	: "opt_root_dir_entries",
	   `option_str	: "-r",
	   `between	: [ 112, -1],
	   `valid_chars : "0123456789",
	   // popup text
	   `error_text 	: _("The minimum size for \"Root dir entries\" is 112. Please try again."),
	     // help text, richtext format
	   `help_text	: _("<p><b>Root dir entries:</b>
Select the number of entries available in the root directory.</p>")
	 ]
  ];


  list< map<symbol, any> > reiserfs_options =   [
			     $[
			       // label text
			       `widget     	: `ComboBox(`id("opt_hash"), `opt(`hstretch), _("Hash &function"), ["auto", "r5", "tea" ,"rupasov" ]),
			       `query_key		: "opt_hash",
			       `option_str	: "--hash",
			       `option_blank    : true,
	     // help text, richtext format
			       `help_text		: _("<p><b>Hash function:</b>
This specifies the name of the hash function to use to sort the file names in directories.</p>")
			     ],
			       $[
			       // label text
				 `widget     	: `ComboBox(`id("opt_format"), `opt(`hstretch), _("FS &revision"), ["auto", "3.5", "3.6" ]),
				 `query_key		: "opt_format",
				 `option_str	: "--format",
			         `option_blank  : true,
	     // help text, richtext format
				 `help_text		: _("<p><b>FS revision:</b>
This option defines the reiserfs format revision to use. '3.5' is for backwards compatibility with kernels of the 2.2.x series. '3.6' is more recent, but can only be used with kernel versions greater than or equal to 2.4.</p>
")
			       ]
  ];


  list< map<symbol, any> > xfs_options	=  [
			      $[
			     // label text
				   `widget     	: `ComboBox(`id("opt_blocksize"), `opt(`hstretch), _("Block &size in bytes"), ["auto","512","1024", "2048","4096" /*,"8192", "16384","32768"*/ ]),
				   `query_key	: "opt_blocksize",
				   `option_str	: "-b size=",
	     // help text, richtext format
				   `help_text  	: _("<p><b>Block size:</b>
Specify the size of blocks in bytes. Valid block size values are 512, 1024, 2048, and 4096 bytes per block. If auto is selected, the standard block size of 4096 is used.</p>
")
				 ],
			      $[
			       // label text
				`widget   	: `ComboBox(`id("opt_bytes_per_inode"), `opt(`hstretch), _("&Inode Size"),["auto","256", "512", "1024", "2048"]),
				`query_key	: "opt_bytes_per_inode",
				`option_str  	: "-i size=",
	     // help text, richtext format
				`help_text  	: _("<p><b>Inode Size:</b>
This option specifies the inode size of the file system.</p>\n")
			      ],
			      $[
			       // label text
				`widget   	: `ComboBox(`id("opt_max_inode_space"), `opt(`hstretch), _("&Percentage of inode space"),["auto", "5", "10", "15", "20","25","30",
																	 "35", "40", "45", "50", "55", "60", "65",
																	 "70", "75", "80", "85", "90", "95",
																	 `item(`id("0"), "100") ]),
				`query_key	: "opt_max_inode_space",
				`option_str  	: "-i maxpct=",
	     // help text, richtext format
				`help_text  	: _("<p><b>Percentage of inode space:</b>
The option \"Percentage of inode space\" specifies the maximum percentage of space in the file system that can be allocated to inodes.</p>
")
			      ],
			      $[
			       // label text
				`widget   	: `ComboBox(`id("opt_inode_align"), `opt(`hstretch), _("Inode &aligned"),[ "auto", `item(`id("1"), "true"),
															 `item( `id("0"), "false")  ]),
				`query_key	: "opt_inode_align",
				`option_str  	: "-i align=",
	     // help text, richtext format
				`help_text  	: _("<p><b>Inode Aligned:</b>
The option \"Inode Aligned\" is used to specify whether inode allocation is or
is not aligned. The default is that inodes are aligned. Aligned inode access
is normally more efficient than unaligned access.</p>
")
			      ]
  ];


  list< map<symbol, any> > jfs_options = [
	    $[
	   // label text
	   `widget : `ComboBox(`id("opt_iocharset"), `opt(`editable,`hstretch), _("Char&set for file names"),
	                       ["", "iso8859-1", "iso8859-15", "iso8859-2",
			        "iso8859-5", "iso8859-7", "iso8859-9", "utf8",
			        "koi8-r", "euc-jp", "sjis", "gb2312", "big5", "euc-kr" ]),
	   `query_key : "opt_iocharset",
	   `type : `text,
	     // help text, richtext format
	   `help_text : _("<p><b>Charset for File Names:</b>
Set the charset used to display file names on the partition.</p>\n"),
	   `str_opt : "iocharset=%1",
	   `str_scan : "iocharset=\(.*\)"
	 ],
		      $[
		       // label text
			`widget 		: `TextEntry(`id("opt_log_size"), `opt(`hstretch),_("&Log size in megabytes"), "auto"),
			`query_key	: "opt_log_size",
			`option_str	: "-ls:",
			// no way to find out the max log size ????
			`between		: [ 0 , -1 ], //  -> -1 = infinite
			`valid_chars 	: "0123456789",
		       // popup text
			`error_text 	: _("The \"Log size\" value is incorrect.\nPlease enter a value greater than zero."),
			// xgettext: no-c-format
	     // help text, richtext format
			`help_text  	: _("<p><b>Log size</b>
Set the log size (in megabytes). If auto, the default is 40% of the aggregate size.</p>")
		      ],
		      $[
		       // label text
			`widget		: `CheckBox(`id("opt_blocks_utility"), _("Invoke Bad Blocks List &Utility"), false),
			`query_key	: "opt_blocks_utility",
			`option_str	: "-l"
		      ]
  ];

  list< map<symbol, any> > ext2_options  =  [
			       $[
				 // label text
				 `widget     	: `TextEntry(`id("opt_raid"), `opt(`hstretch), _("Stride &length in blocks"), "none" ),
				 `query_key	: "opt_raid",
				 `option_str	: "-Rstride=",
				 `valid_chars	: "0123456789",
				 `between		: [ 1, -1],
				 // popup text
				 `error_text	: _("The \"Stride length in blocks\" value is not possible.\nPlease select a value greater than 1."),
	     // help text, richtext format
				 `help_text	: _("<p><b>Stride Length in Blocks:</b>
Set RAID-related options for the file system. Currently, the only supported
argument is 'stride', which takes the number of blocks in a
RAID stripe as its argument.</p>
")
			       ],
				 $[
				 // label text
				   `widget     	: `ComboBox(`id("opt_blocksize"), `opt(`hstretch), _("Block &size in bytes"), ["auto","1024", "2048","4096" /*,"8192", "16384","32768"*/ ]),
				   `query_key	: "opt_blocksize",
				   `option_str	: "-b",
	     // help text, richtext format
				   `help_text  	: _("<p><b>Block size:</b>
Specify the size of blocks in bytes. Valid block size values are 1024, 2048, and 4096 bytes per block. If auto is selected, the block size is determined by the file system size and the expected use of the file system.</p>\n")
				 ],
				 $[
				   // label text
				   `widget   	: `ComboBox(`id("opt_inode_density"), `opt(`hstretch), _("Bytes per &inode"),["auto","1024", "2048","4096","8192", "16384","32768" ]),
				   `query_key	: "opt_inode_density",
				   `option_str 	: "-i",
	     // help text, richtext format
				   `help_text  	: _("<p><b>Bytes per inode:</b>
Specify the bytes to inode ratio. YaST2 creates an inode for every &lt;bytes-per-inode&gt; bytes of space on the disk. The larger the bytes-per-inode ratio, the fewer inodes will be created.
Generally, this value should not be smaller than the block size of the file system, since too many inodes will be created in this case.  It is not possible to expand the
number of inodes on a file system after its creation, so be sure to enter a reasonable value for this parameter.</p>
")
				 ],
				 $[
				   // label text
				   `widget   	: `TextEntry(`id("opt_reserved_blocks"), `opt(`hstretch), _("Percentage of blocks &reserved for root"), "auto" ),
				   `query_key	: "opt_reserved_blocks",
				   `option_str  : "-m",
				   //`default 	: 5,
				   `between	: [ 0 , 99 ], //  -> -1 = infinite
				   `str_length	: 2,
				   `valid_chars : "0123456789",
				   // popup text
				   `error_text  : _("The \"Percentage of blocks reserved for root\" value is incorrect.\nPlease use a value between 0 and 99."),
				   // xgettext: no-c-format
	     // help text, richtext format
				   `help_text  	: _("<p><b>Percentage of blocks reserved for root:</b> Specify the percentage of blocks reserved for the super user. This value defaults to 5%.</p>")
				 ]
      ];

  list< map<symbol, any> > ext3_only_options = [
      $[
      // label text
      `widget   	: `ComboBox(`id("opt_bytes_per_inode"), `opt(`hstretch), _("&Inode Size"),["default", "128", "256", "512", "1024"]),
      `query_key	: "opt_bytes_per_inode",
      `option_str  	: "-I",
       // help text, richtext format
      `help_text  	: _("<p><b>Inode Size:</b>
This option specifies the inode size of the file system.</p>\n")
      ]
  ];

  list< map<symbol, any> > ext3_options = (list< map<symbol, any> >)merge( ext2_options, ext3_only_options );

  list< map<symbol, any> > ext3_fst_options = [ ];
  list< map<symbol, any> > ext2_fst_options = [ ];
  list< map<symbol, any> > reiser_fst_options = [ ];


  map <symbol, map<symbol, any> > RealFileSystems  = $[
		      `ext2	: $[
				    `name 		: "Ext2",
				    `fsid 		: Partitions::fsid_native,
				    `supports_format 	: true,
				    `fsid_item 		: "0x83 Linux ",
				    `fstype 		: "Linux native" ,
				    `crypt 		: true ,
				    `mountpoints 	: suggest_m_points,
				    `mount_option	: "-t ext2",
				    `mount_string	: "ext2",
				    `makefstype		: "ext2",
				    `fst_options  	: ext2_fst_options,
				    `options  		: ext2_options,
		      ],
		      `fat32	: $[
				    `name 		: "FAT",
				    `fsid 		: 12,
				    `alt_fsid           : [ 12, 0x103 ],
				    `supports_format 	: true ,
				    `fsid_item 		: "0x0C Win95 FAT32 ",
				    `fstype 		: "Fat32",
				    `crypt 		: true ,
				    `mountpoints 	: suggest_m_points ,
				    `mount_option	: "-t vfat",
				    `mount_string	: "vfat",
				    `makefstype		: "fat32",
				    `needed_modules	: [ "fat", "vfat" ],
				    `fst_options  	: fat_fst_options,
				    `options 		: fat32_options

		      ],
		      `reiser 	: $[
				    `name 		: "Reiser",
				    `fsid 		: Partitions::fsid_native,
				    `supports_format 	: true ,
				    `fsid_item 		: "0x83 Linux " ,
				    `fstype 		: "Linux native",
				    `crypt 		: true,
				    `mountpoints 	: suggest_m_points,
				    `mount_option 	: "-t reiserfs",
				    `mount_string	: "reiserfs",
				    `needed_modules	: [ "reiserfs" ],
				    `makefstype		: "reiserfs",
				    `fst_options  	: reiser_fst_options,
				    `options 		: reiserfs_options
		      ],
		      `xfs 	: $[
				    `name 		: "XFS",
				    `fsid 		: Partitions::fsid_native,
				    `supports_format 	: true ,
				    `fsid_item 		: "0x83 Linux " ,
				    `fstype 		: "Linux native" ,
				    `crypt 		: true,
				    `mountpoints 	: suggest_m_points,
				    `mount_option 	: "-t xfs",
				    `mount_string	: "xfs",
				    `needed_modules	: [ "xfs" ],
				    `makefstype		: "xfs",
				    `options 		: xfs_options
		      ],
		      `jfs 	: $[
				    `name 		: "JFS",
				    `fsid 		: Partitions::fsid_native,
				    `supports_format 	: true ,
				    `fsid_item 		: "0x83 Linux " ,
				    `fstype 		: "Linux native" ,
				    `crypt		: true,
				    `mountpoints 	: suggest_m_points,
				    `mount_string	: "jfs",
				    `mount_option	: "-t jfs",
				    `needed_modules	: [ "jfs" ],
				    `makefstype		: "jfs",
				    `options      	: jfs_options
		      ],
		      `ext3 	: $[
				    `name 		: "Ext3",
				    `fsid 		: Partitions::fsid_native,
				    `supports_format 	: true ,
				    `fsid_item 		: "0x83 Linux " ,
				    `fstype 		: "Linux native" ,
				    `crypt		: true,
				    `mountpoints 	: suggest_m_points,
				    `mount_string	: "ext3",
				    `mount_option	: "-t ext3",
				    `needed_modules	: [ "jbd",  "ext3" ],
				    `makefstype		: "ext2", // format ext3 as ext2 !!!!!!!!!!!!!!!
				    `fst_options  	: ext3_fst_options,
				    `options      	: ext3_options
		      ],
		      `hfs 	: $[
				    `name 		: "MacHFS",
				    `fsid 		: Partitions::fsid_mac_hfs,
				    `supports_format 	: true,
				    `fsid_item 		: "0x102 Apple_HFS " ,
				    `fstype 		: "Apple_HFS " ,
				    `crypt		: false,
				    `mountpoints 	: [],
				    `mount_string	: "hfs",
				    `mount_option	: "-t hfs",
				    `needed_modules	: [ "hfs" ],
				    `makefstype		: "hfs",
				    `fst_options  	: [],
				    `options      	: []
		      ]
  ];

  return( RealFileSystems );
  };

  list< map<symbol, any> > swap_fst_options = [
    $[ `widget 	    : `TextEntry( `id("priority"), `opt(`hstretch),
				  // label text
                                  _("Swap &Priority"), "42" ),
       `query_key   : "priority",
       `between	    : [ 0, 32767],
       `valid_chars : "0123456789",
       // popup text
       `error_text  : _("Value must be between 0 and 32767. Try again."),
       `type : `text,
       `str_opt : "pri=%1",
       `str_scan : "pri=\(.*\)",
	 // help text, richtext format
       `help_text   : _("<p><b>Swap Priority:</b>
Enter the swap priority. Higher numbers mean higher priority.</p>
")
     ]];

  map<symbol, any> SwapFileSystems =
    $[ `swap :
	$[ `name 	    : "Swap" ,
	   `fsid 	    : Partitions::fsid_swap,
	   `supports_format : true ,
	   `fsid_item 	    : "0x82 Linux swap ",
	   `fstype 	    : "Linux swap",
	   `crypt 	    : false,
	   `fst_options     : swap_fst_options,
	   `mountpoints     : swap_m_points
	 ]
     ];


  map<symbol, map<symbol, any> > PseudoFileSystems = $[
			    `lvm	: $[
					    `name 		: "LVM",
					    `fsid 		: Partitions::fsid_lvm,
					    `supports_format 	: false,
					    `fsid_item 		: "0x8E Linux LVM "
			    ],
			    `raid	: $[
					    `name 		: "RAID",
					    `fsid 		: Partitions::fsid_raid,
					    `supports_format 	: false,
					    `fsid_item 		: "0xFD Linux RAID "
			    ],
			    `xbootdisk : $[
					   `name 		: "PPCBOOT",
					   `fsid 		: Partitions::fsid_prep_chrp_boot,
					   `supports_format 	: false,
					   `fsid_item 		: "0x41 PPC PReP Boot"
			    ],
			    `xbootfat  : $[
					   `name 		: "FATBOOT",
					   `fsid 		: Partitions::fsid_fat16,
					   `supports_format 	: false,
					   `fsid_item 		: "0x06 FAT16 Boot"
			    ],
			    `xhibernate : $[
					   `name 		: "Hibernate",
					   `fsid 		: Partitions::fsid_hibernation,
					   `supports_format 	: false,
					   `fsid_item 		: "0xA0 Hibernation"
					   ],
			    `xxefi      : $[
			                   `name                : "Efi Boot",
					   `fsid                : Partitions::fsid_gpt_boot,
					   `supports_format     : false,
					   `fsid_item           : "0x103 EFI Boot"
					   ]
  ];


  /**
   * Filesystem Definitions
   * @return map map with all supported filesystems
   */
global define map<symbol, map<symbol, any> > GetAllFileSystems(boolean add_swap, boolean add_pseudo )
    ``{ 
    map<symbol, map<symbol, any> > ret = filter( symbol fs_key, map<symbol,any> fs_map, GetNormalFilesystems(),
                      ``( support[fs_key]:false ));

    if( add_swap )
	{
	ret = (map<symbol, map<symbol, any> >)union( ret, SwapFileSystems );
	}
    if( add_pseudo )
	{
	ret = (map<symbol, map<symbol, any> >)union( ret, filter( symbol fs_key, any fs_map, PseudoFileSystems,
				  ``( support[fs_key]:false )));
	}
    return ret;
    }


global define list< map<symbol, any> > GetFstabOptWidgets( symbol fsys )
    ``{
    list< map<symbol, any> > ret = [];
    if( fsys != `swap )
	{
	map<symbol, map<symbol, any> > fs = GetAllFileSystems( true, false );
	ret = fs[fsys,`fst_options]:[];
	if( contains( [`ext3, `reiser], fsys ) )
	    {
	    ret = (list< map<symbol, any> >)union( ret, GetJournalFstabOptions() );
	    }
	if( contains( [`ext2, `ext3, `reiser], fsys ) )
	    {
	    ret = (list< map<symbol, any> >)union( ret, GetAclFstabOptions() );
	    }
	}
    else
	{
	ret = swap_fst_options;
	}
    y2milestone( "fsys %1", fsys );
    y2milestone( "ret %1", ret );
    return( ret );
    };




  /* FileS build fss map with all supported filesystems ( list support ) */
global define void FileSystems()
    ``{
    if( Arch::sparc64 () || Arch::sparc32 () )
	{
        support[`fat16] = false;
        support[`fat32] = false;
	}
    if( Arch::ppc () )
	{
	support[`fat16] = Arch::board_chrp ();
	support[`fat32] = Arch::board_chrp ();
	support[`xbootdisk] = true;
	support[`xbootfat] = Arch::board_chrp ();
	}
    if( Arch::s390 () )
	{
	support[`xfs] = false;
	support[`fat16] = false;
	support[`fat32] = false;
	}
    if( Arch::ia64 () )
	{
	support[`jfs] = false;
	support[`xxefi] = true;
	}
    if( Arch::alpha () )
	{
	support[`reiser] = false;
	}
    if( Arch::board_mac () )
	{
	support[`hfs] = true;
	}
    y2milestone( "support %1", support );
    }


  global define boolean IsSupported( symbol used_fs)``{
      return support[ used_fs ]:false;
  }

  global define map<symbol, any> GetFsMap( symbol used_fs )``{
      map<symbol, map<symbol, any> > allfs =  GetAllFileSystems( true, true  );
      return allfs[ used_fs]:$[];
  }

  global define string GetName( symbol used_fs, string default )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      string ret        = fsmap[`name]:"";
      if ( ret == "" && used_fs == `ntfs ) ret = "NTFS";
      if ( ret == "" ) ret = default;
      return ret;
  }

  global define integer GetFsid( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return fsmap[`fsid]:Partitions::fsid_native;
  }

  global define boolean GetSupportFormat( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return (boolean)(fsmap[`supports_format]:nil);
  }

  global define string GetFsidItem( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return fsmap[`fsid_item ]:"";
  }

  global define string GetFstype( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return fsmap[`fstype ]:"";
  }

  global define boolean GetCrypt( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return (boolean)(fsmap[`crypt ]:nil);
  }

  global define list GetPossibleMountPoints( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return fsmap[`mountpoints ]:[];
  }

  global define string GetMountOption( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return fsmap[`mount_option ]:"";
  }

  global define list GetOptions( symbol used_fs )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      return fsmap[`options ]:[];
  }


    /**
     * Return the mount option for each used_fs (-t)
     * @return string
     */
  global define string GetMountString(symbol used_fs, string default )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      string ret        = fsmap[`mount_string ]:"";
      if( size(ret)==0 )
	  {
	  if( used_fs == `fat32 || used_fs == `fat16 )
	      {
	      ret = "vfat";
	      }
	  else if( used_fs == `ntfs )
	      {
	      ret = "ntfs";
	      }
	  }
      if( ret == "" ) ret = default;
      y2milestone( "used_fs:%1 ret:%2", used_fs, ret );
      return ret;
  }

  global define list<string> GetNeededModules( symbol used_fs )``{
      list<string> ret = [];
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      if( used_fs==`ntfs && size(fsmap)==0 )
	{
	ret = ["ntfs"];
	}
      else
	{
	ret = fsmap[`needed_modules ]:[];
	}
      return ret;
  }

  global define string GetMakeFsType( symbol used_fs , string default )``{
      map<symbol,any> fsmap 	= GetFsMap( used_fs);
      string ret        = fsmap[`makefstype ]:"";
      if( ret == "" ) ret = default;
      return ret;
  }



  /**
     * Load the kernel module which is necessary to mount a partition with used_fs!
     * @param used_fs filesystem
     * @return boolean
     * old load_fs_module
     */
global define boolean LoadModule( symbol used_fs )
    ``{

    list<string> all_needed_modules = GetNeededModules( used_fs );
    y2milestone("all needed modules for %1: %2", used_fs, all_needed_modules );
    boolean load_success = true;

    SCR::UnmountAgent (.proc.modules);
    map loaded_modules = (map) SCR::Read(.proc.modules);
    y2milestone( "loaded_modules %1", loaded_modules );

    foreach( string modulename, all_needed_modules,
	``{
	if( modulename != "" &&  size (loaded_modules[modulename]:$[])==0 )
	    {
	    if( load_success )
		load_success = (boolean) SCR::Execute(.target.modprobe, modulename , "" );

	    y2milestone ("Loaded fs module %1 %2", modulename, load_success?"Ok":"Failed");
	    }
	});
    return load_success;
    };

global define boolean MountUuid( symbol fsys )
    ``{
    map<string,any> cap = capabilities[`unknown]:$[];
    cap = capabilities[fsys]:cap;
    boolean ret = cap["uuid"]:false;
    y2milestone( "MountUuid fsys:%1 ret:%2", fsys, ret );
    return( ret );
    }

global define boolean MountLabel( symbol fsys )
    ``{
    map<string,any> cap = capabilities[`unknown]:$[];
    cap = capabilities[fsys]:cap;
    boolean ret = cap["label"]:false;
    y2milestone( "MountLabel fsys:%1 ret:%2", fsys, ret );
    return( ret );
    }

global define boolean ChangeLabelMounted( symbol fsys )
    ``{
    map<string,any> cap = capabilities[`unknown]:$[];
    cap = capabilities[fsys]:cap;
    boolean ret = cap["set_label_mount"]:false;
    y2milestone( "ChangeLabelMounted fsys:%1 ret:%2", fsys, ret );
    return( ret );
    }

global define integer LabelLength( symbol fsys )
    ``{
    map<string,any> cap = capabilities[`unknown]:$[];
    cap = capabilities[fsys]:cap;
    integer ret = cap["label_legth"]:16;
    y2milestone( "LabelLength fsys:%1 ret:%2", fsys, ret );
    return( ret );
    }

global define map IsResizable( symbol fsys )
    ``{
    map<string,any> cap = capabilities[`unknown]:$[];
    cap = capabilities[fsys]:cap;
    map ret = $[];
    ret["extend"] = cap["extend"]:false;
    ret["shrink"] = cap["shrink"]:false;
    ret["mount_extend"] = cap["mount_extend"]:false;
    ret["mount_shrink"] = cap["mount_shrink"]:false;
    ret["parted"] = cap["parted"]:false;
    y2milestone( "IsResizable fsys:%1 ret:%2", fsys, ret );
    return( ret );
    };

  /*
   * DetectFs
   *---------------------------------------------------------------------
   * Detect the existing fs on the partition. Right now only ext2 and
   * reiserfs are detected.
   * arguments: <partition> for ex. "/dev/sda1"
   * returns:   Symbol for filesystem or `unknown
   *---------------------------------------------------------------------
   */
global define symbol DetectFs( string current_dev )
    ``{
    symbol  return_value = `unknown;
    string  testcall     = "";
    map bc        	 = $[];

    testcall  = sformat( "/bin/guessfstype %1 2>&1", current_dev );
    bc = (map) SCR::Execute (.target.bash_output, testcall, $[] );
    y2milestone( "cmd %1", testcall );
    y2milestone( "%1", bc );

    if (bc["exit"]:1 == 0)
	{
	string type = filter( string e, splitstring( bc["stdout"]:"", "\n" ),
			      ``(find(e,current_dev)==0) )[0]:"";
	integer pos = findlastof(type, " ");
	if (pos != nil)
	   {
	   type = substring (type, pos+1);
	}
	pos = findfirstof(type, " ,");
	if (pos != nil)
	{
	   type = substring (type, 0, pos);
	}
	y2milestone( "type %1", type );
	if( type == "ext2" )
	{
	  return_value = `ext2;
	  }
	else if( type == "ext3" )
	    {
	  return_value = `ext3;
	    }
	else if( type == "reiserfs" )
	    {
	  return_value = `reiser;
	    }
	else if( type == "jfs" )
	  {
	  return_value = `jfs;
	}
	else if( type == "xfs" )
	  {
	  return_value = `xfs;
    }
	else if( type == "vfat" || type == "fat" )
	  {
	  return_value = `fat32;
	  }
	else if( type == "ntfs" )
	  {
	  return_value = `ntfs;
	  }
	else if( type == "hfs" )
	  {
	  return_value = `hfs;
	  }
	else if( type == "swap" )
	  {
	  return_value = `swap;
	  }
	}
    y2milestone( "DetectFs %1: %2", current_dev, return_value );
    return( return_value );
    };

global define string GetLosetupCmd( map loop, string tmpf )
    ``{
    list noext = [ "twofish", "twofishSL92", "none" ];
    string encr = loop["encryption"]:"twofish";
    string cmd = sformat( "/sbin/losetup -e %1", encr );
    # XXX: This could be done better
    if ( encr == "twofishSL92" )
       {
       cmd = "rmmod twofish cryptoloop; modprobe loop_fish2; /sbin/losetup -e twofishSL92";
       }
    else if( encr == "twofish" )
       {
       cmd = "rmmod twofish cryptoloop; modprobe loop_fish2; /sbin/losetup -e twofish";
       }
    else 
       {
       cmd = "rmmod loop_fish2; modprobe twofish; modprobe cryptoloop; /sbin/losetup -e twofish256";
       }
    if( !contains( noext, encr ) && size(loop["phash"]:"")>0 )
        {
        cmd = cmd + " -H " + loop["phash"]:"";
        }
    if( !contains( noext, encr ) && size(loop["itercountk"]:"")>0 )
        {
        cmd = cmd + " -C " + loop["itercountk"]:"";
        }
    cmd = cmd + " " + loop["loop_dev"]:"" + " " + loop["partitionName"]:"" +
          " -p0 < " + tmpf;
    y2milestone( "GetLosetupCmd %1", cmd );
    return( cmd );
    }

global define string DetectLoopEncryption( map loop, string pwdfile )
    ``{
    list<string> try_order = [ "twofish", "twofishSL92", "twofish256" ];
    integer try = 0;
    string mp = sformat( "%1_mp", pwdfile );
    boolean ret = (boolean)SCR::Execute( .target.mkdir, mp, 0700 );
    y2milestone( "DetectLoopEncryption mkdir:%1 r:%2", mp, ret );
    string cmd = "";
    map r = $[];
    symbol fs = `unknown;
    do
	{
	fs = `unknown;
	cmd = sformat( "losetup -d %1", loop["loop_dev"]:"" );
	r = (map)SCR::Execute( .target.bash_output, cmd );
	y2milestone( "DetectLoopEncryption cmd:%1 r:%2", cmd, r );
	loop["encryption"] = try_order[try]:"twofish";
	cmd = GetLosetupCmd( loop, pwdfile );
	r = (map)SCR::Execute( .target.bash_output, cmd );
	y2milestone( "DetectLoopEncryption cmd:%1 r:%2", cmd, r );
	if( r["exit"]:1==0 )
	    fs = FileSystems::DetectFs( loop["loop_dev"]:"" );
	if( fs != `unknown )
	    {
	    cmd = sformat( "mount -oro %1 %2 %3", GetMountOption(fs), 
	                   loop["loop_dev"]:"", mp );
	    r = (map)SCR::Execute( .target.bash_output, cmd );
	    y2milestone( "DetectLoopEncryption cmd:%1 r:%2", cmd, r );
	    if( r["exit"]:1!=0 )
		fs = `unknown;
	    cmd = sformat( "umount %1", loop["loop_dev"]:"" );
	    r = (map)SCR::Execute( .target.bash_output, cmd );
	    y2milestone( "DetectLoopEncryption cmd:%1 r:%2", cmd, r );
	    }
	if( fs==`unknown )
	    try = try+1;
	}
    while( fs==`unknown && try<size(try_order) );
    cmd = sformat( "rmdir %1", mp );
    r = (map)SCR::Execute( .target.bash_output, cmd );
    y2milestone( "DetectLoopEncryption cmd:%1 r:%2", cmd, r );
    if( fs==`unknown )
	{
	cmd = sformat( "losetup -d %1", loop["loop_dev"]:"" );
	map r = (map)SCR::Execute( .target.bash_output, cmd );
	y2milestone( "DetectLoopEncryption cmd:%1 r:%2", cmd, r );
	}
    y2milestone( "DetectLoopEncryption ret:%1", try_order[try]:"" );
    return( try_order[try]:"" );
    }


global define map GetUuidVolume( string dev, symbol fs )
    ``{
    map ret = $[];
    string val = "";
    string cmd = "";
    string search = "";
    map cmd_ret = $[];
    integer pos = 0;
    if( fs == `ext2 || fs == `ext3 )
	{
	cmd = sformat( "/sbin/tune2fs -l %1", dev );
	y2debug( "executing cmd %1", cmd );
	cmd_ret = (map) SCR::Execute(.target.bash_output, cmd);
	val = cmd_ret["stdout"]:"";
	search = "UUID:";
	pos = find( val, search );
	if( pos != -1 )
	    {
	    val = substring( val, pos+size(search) );
	    pos = findfirstof( val, "\n" );
	    if( pos != nil )
		{
		val = substring( val, 0, pos );
		}
	    val = deletechars( val, " \n\t" );
	    if( size(val)>0 )
		{
		ret["uuid"] = val;
		}
	    }
	val = cmd_ret["stdout"]:"";
	search = "volume name:";
	pos = find( val, search );
	if( pos != -1 )
	    {
	    val = substring( val, pos+12 );
	    pos = findfirstof( val, "\n" );
	    if( pos != nil )
		{
		val = substring( val, 0, pos );
		}
	    val = deletechars( val, " \n\t" );
	    if( size(val)>0 && val != "<none>" )
		{
		ret["label"] = val;
		}
	    }
	}
    else if( fs == `reiser )
	{
	cmd = sformat( "/sbin/debugreiserfs %1 2>&1", dev );
	y2milestone( "executing cmd %1", cmd );
	cmd_ret = (map) SCR::Execute(.target.bash_output, cmd);
	y2milestone( "output %1", cmd_ret["stdout"]:"" );
	val = cmd_ret["stdout"]:"";
	search = "UUID:";
	pos = find( val, search );
	if( pos != -1 )
	    {
	    val = substring( val, pos+size(search) );
	    pos = findfirstof( val, "\n" );
	    if( pos != nil )
		{
		val = substring( val, 0, pos );
		}
	    val = deletechars( val, " \n\t" );
	    if( size(val)>0 )
		{
		ret["uuid"] = val;
		}
	    }
	val = cmd_ret["stdout"]:"";
	search = "LABEL:";
	pos = find( val, search );
	if( pos != -1 )
	    {
	    val = substring( val, pos+size(search) );
	    pos = findfirstof( val, "\n" );
	    if( pos != nil )
		{
		val = substring( val, 0, pos );
		}
	    val = deletechars( val, " \n\t" );
	    if( size(val)>0 )
		{
		ret["label"] = val;
		}
	    }
	}
    else if( fs == `xfs )
	{
	cmd = sformat( "/usr/sbin/xfs_admin -l -u %1", dev );
	y2debug( "executing cmd %1", cmd );
	cmd_ret = (map) SCR::Execute(.target.bash_output, cmd);
	val = cmd_ret["stdout"]:"";
	search = "uuid =";
	pos = find( val, search );
	if( pos != -1 )
	    {
	    val = substring( val, pos+size(search) );
	    pos = findfirstof( val, "\n" );
	    if( pos != nil )
		{
		val = substring( val, 0, pos );
		}
	    val = deletechars( val, " \n\t" );
	    if( size(val)>0 )
		{
		ret["uuid"] = val;
		}
	    }
	val = cmd_ret["stdout"]:"";
	search = "label =";
	pos = find( val, search );
	if( pos != -1 )
	    {
	    val = substring( val, pos+size(search) );
	    pos = findfirstof( val, "\n" );
	    if( pos != nil )
		{
		val = substring( val, 0, pos );
		}
	    val = deletechars( val, " \"\n\t" );
	    if( size(val)>0 )
		{
		ret["label"] = val;
		}
	    }
	}
    y2milestone( "GetUuidVolume dev:%1 fs:%2 ret:%3", dev, fs, ret );
    return( ret );
    }



global define map GetFsysInfos( map part )
    ``{
    string dev = part["device"]:"";
    y2milestone( "device:%1", dev );
    if( size(part["loop_dev"]:"")>0 )
      {
	dev = part["loop_dev"]:"";
	y2milestone( "device:%1", dev );
      }
    part["detected_fs"] = DetectFs( dev );
    if( part["detected_fs"]:`unknown != `unknown )
      {
	part["used_fs"] = part["detected_fs"]:`unknown;
      }
    if( part["detected_fs"]:`unknown != `unknown &&
        part["detected_fs"]:`unknown != `swap )
      {
	map info = GetUuidVolume( dev, part["detected_fs"]:`unknown );
	if( size(info["uuid"]:"")>0 )
      {
	    part["uuid"] = info["uuid"]:"";
      }
	if( size(info["label"]:"")>0 )
      {
	    part["label"] = info["label"]:"";
      }
      }
    y2milestone( "ret part:%1", part );
    return( part );
    }

global define symbol FsToSymbol( string type )
    ``{
    symbol return_value = `none;
	if( type == "ext2" )
	  {
	  return_value = `ext2;
	  }
	else if( type == "ext3" )
	  {
	  return_value = `ext3;
	  }
    else if( regexpmatch( type, "reiser.*" ) )
	  {
	  return_value = `reiser;
	  }
	else if( type == "jfs" )
	  {
	  return_value = `jfs;
	  }
	else if( type == "xfs" )
	  {
	  return_value = `xfs;
	  }
    else if( type == "vfat" || regexpmatch( type, "fat.*" ))
	  {
	  return_value = `fat32;
	  }
	else if( type == "ntfs" )
	  {
	  return_value = `ntfs;
	  }
	else if( type == "hfs" )
	  {
	  return_value = `hfs;
	  }
	else if( type == "swap" )
	  {
	  return_value = `swap;
	  }
    return( return_value );
    }

global define boolean SetVolumeLabel( string dev, map part )
    ``{
    boolean ret = false;
    string cmd = "";
    symbol fs = part["used_fs"]:`unknown;
    string label = part["label"]:"";
    y2milestone( "SetVolumeLabel dev:%1 fs:%2 label:%3", dev, fs, label );
    if( fs == `ext2 || fs == `ext3 )
	{
	cmd = sformat("/sbin/tune2fs -L \"%1\" %2", label, dev );
	}
    else if( fs == `xfs )
	{
	if( size(label)==0 )
	    label = "--";
	cmd = sformat("/usr/sbin/xfs_admin -L %1 %2", label, dev );
	}
    else if( fs == `reiser )
	{
	cmd = sformat("/sbin/reiserfstune -l \"%1\" %2", label, dev );
	}
    if( size(cmd)>0 )
	{
	y2milestone( "Excuting cmd:%1", cmd );
	ret = SCR::Execute(.target.bash, cmd ) == 0;
	// /sbin/reiserfstune always seems to return 1 even on success
	if( fs == `reiser )
	    ret = true;
	}
    y2milestone( "SetVolumeLabel ret:%1", ret );
    return( ret );
    };

global define void DoChangedFsDefaults( map part )
    ``{
    string cmd = "";
    symbol fs = part["used_fs"]:`unknown;
    string dev = part["device"]:"";
    if( haskey( part, "loop_dev" ))
	{
	dev = part["loop_dev"]:"";
	}
    if( fs == `ext3 )
	{
	y2milestone( "dev:%1 fs:%2", dev, fs );
	cmd = sformat("/sbin/tune2fs -c %1 -i %2 %3", 500, "2m", dev );
	y2milestone( "Excuting cmd:%1", cmd );
	SCR::Execute(.target.bash, cmd );
	}
    };

//////////////////////////////////////////////////////////////////////////
// mount partition and look how much free space is available
// size: size of partition
//////////////////////////////////////////////////////////////////////////

global define map GetFreeSpace( string device, integer testsize,
                                symbol used_fs, boolean verbose )
    ``{
    integer used = 0;
    integer free = 0;
    boolean win_disk = false;
    boolean mounted = false;
    string mount_point = (string) SCR::Read (.target.tmpdir) + "/gfs_mnt";

    if( !Stage::initial () )
	{
	map mounts = find( map e, Partitions::CurMounted(), 
	                   ``(e["spec"]:""==device ));
	y2milestone( "mounts %1", mounts );
        if( size(mounts["file"]:"")>0 )
	    {
	    mount_point = mounts["file"]:"";
	    mounted = true;
	    }
	}
    y2milestone( "GetFreeSpace mount_point %1 mounted %2 verbose %3", 
                 mount_point, mounted, verbose );

    if( !mounted )
	{
	SCR::Execute (.target.mkdir, mount_point, 0755);
	LoadModule( used_fs );
	}
    if ( Mode::test () )
	{
	integer wf =  tointeger(tofloat(testsize) * 0.6);
	integer wu =  tointeger(tofloat(testsize) * 0.4);
	integer ls =  tointeger(tofloat(testsize) * 0.5);
	return( $[ "free"  : wf, "used"    : wu,
		   "linux_size"  : ls, "new_size": (wu + wf - ls) ] );
	}

    if( !mounted )
	{
	string mount_type = GetMountString( used_fs, "");
	if (mount_type != "")
	    {
	    mount_type = "-r -t " + mount_type;
	    }

	// mount the partition to execute some checks
	//
	y2milestone( "mount %1 used_fs %2 type %3", device, used_fs, 
	             mount_type );
	boolean mount_ret = (boolean) SCR::Execute(.target.mount, [device, mount_point],
					 mount_type );

	if ( !mount_ret)
	    {
	    y2error( "Current device <%1> could not be mounted. Canceled", device );
	    return( $[] );	// abort installation
	    }
	else {
	    y2milestone( "Current device <%1> mounted on <%2>", device, 
			 mount_point );
        }
	}

    // get usage information for the partition via df
    //
    list<map> df_result = (list<map>) SCR::Read(.run.df);
    if( used_fs==`fat32 || used_fs==`fat16 || used_fs==`ntfs )
	{
	list chkf = ["boot.ini", "msdos.sys", "io.sys", "config.sys",
	             "MSDOS.SYS", "IO.SYS" ];
	integer num = 0;
	while( !win_disk && num<size(chkf) )
	    {
	    win_disk = SCR::Read( .target.size, 
	                          mount_point + "/" + chkf[num]:"XX" ) >= 0;
	    num = num+1;
	    }
	}

    if( !mounted )
	{
	SCR::Execute(.target.umount, mount_point);
	}

    y2debug( ".run.df: %1", df_result );

    // filter out headline and other invalid entries
    df_result = filter(map part, df_result, ``( part["spec"]:""==device ) );
    y2milestone( "df_result %1", df_result );

    // get the usage values
    //
    used = tointeger( df_result[0,"used"]:"-1" );
    free = tointeger( df_result[0,"free"]:"-1" );

    if( used != -1 && free != -1 )
	{
	used = used * 1024;	// Byte
	free = free * 1024;	// Byte
	y2milestone( ".run.df: used: <%1> free:<%2>", used, free );
	}
    else
	{
	free = 0;
	}

    integer df_free = free;
    if( used_fs == `ntfs )
	{
	string cmd = sformat("ntfsresize -f -i %1", device );
	y2milestone( "Executing cmd:%1", cmd );
	map bcall = (map) SCR::Execute( .target.bash_output, cmd, 
					$[ "LC_MESSAGES" :"POSIX"] );
	y2milestone( "Executing ret:%1", bcall );
	free = 0;
	if( bcall["exit"]:1 == 0 )
	    {
	    string line = find(string l, splitstring( bcall["stdout"]:"", "\n" ),
	                        ``( find(l, " might resize at ")>0 ));
	    y2milestone( "line %1", line );
	    if( line != nil )
		{
		line = substring( line, find(line, " at ")+4 );
		line = substring( line, 0, findfirstnotof( line, "0123456789" ));
		free = used + df_free - (tointeger( line ) + 1024*1024);
		y2milestone( "line \"%1\" free %2", line, free );
		}
	    }
	else if( verbose )
	    {
	    string tmp = _("Resize Not Possible:") + "\n\n";
	    tmp = tmp + bcall["stdout"]:"" + bcall["stderr"]:"";
	    Popup::Error( tmp );
	    }
	}

    integer linux_size = 0;
    integer min_linux_size = 0;
    integer add_free = df_free - free;

    if( free < 300000000 )
	{
	linux_size = 0;
	min_linux_size = 0;
	}
    else if( free < 600000000 )
	{
	linux_size = free;
	if( add_free < 75000000 )
	    {
	    linux_size = linux_size - 75000000 + add_free;
	    }
	min_linux_size = linux_size;
	}
    else if ( free < 1000000000 )
	{
	linux_size = free;
	if( add_free < 200000000 )
	    {
	    linux_size = linux_size - 200000000 + add_free;
	    }
	min_linux_size = 300000000;
	}
    else if ( free < 2000000000 )
	{
	linux_size = free;
	if( add_free < 300000000 )
	    {
	    linux_size = linux_size - 300000000 + add_free;
	    }
	min_linux_size = 500000000;
	}
    else if ( free < 3000000000 )
	{
	linux_size = free;
	if( add_free < 800000000 )
	    {
	    linux_size = linux_size - 800000000 + add_free;
	    }
	min_linux_size = 500000000;
	}
    else
	{
	linux_size = free;
	if( add_free < free/3 )
	    {
	    linux_size = linux_size - free/3 + add_free;
	    }
	min_linux_size = 500000000;
	}

    integer new_size = used + add_free + free - linux_size;

    map ret = $[ "free": (free>0?free:0),
		 "df_free" : df_free,
		 "used":used,
		 "win_disk":win_disk,
		 "linux_size":linux_size,
		 "max_win_size":used + free + add_free - min_linux_size,
		 "ntfs" : (used_fs == `ntfs),
		 "new_size":new_size ];
    y2milestone( "ret %1", ret );
    return( ret );
    };

global define boolean IsCryptMp( string mount, boolean prefix )
    ``{
    boolean ret = contains( crypt_m_points, mount );
    if( !ret && prefix )
	{
	list<string> mp = filter(string s, system_m_points, ``(s!="/") );
	foreach(string s, mp,
	    ``{
	    ret = ret || find( mount, s + "/" )==0;
	    });
	}
    y2milestone( "IsCryptMp mount:%1 prefix:%2 ret:%3", mount, prefix, ret );
    return( ret );
    };

global define boolean IsSystemMp( string mount, boolean prefix )
    ``{
    boolean ret = contains( system_m_points, mount );
    if( !ret && prefix )
	{
	list<string> mp = filter(string s, system_m_points, ``(s!="/") );
	foreach(string s, mp,
	    ``{
	    ret = ret || find( mount, s + "/" )==0;
	    });
	}
    y2milestone( "IsSystemMp mount:%1 prefix:%2 ret:%3", mount, prefix, ret );
    return( ret );
    };

global define string RemoveCryptOpts( string opt )
    ``{
    string ret = opt;
    ret = String::CutRegexMatch( ret, ",*loop[^,]*", true );
    ret = String::CutRegexMatch( ret, ",*encryption=[^,]*", true );
    ret = String::CutRegexMatch( ret, ",*phash=[^,]*", true );
    ret = String::CutRegexMatch( ret, ",*itercountk=[^,]*", true );
    if( size(ret)!=size(opt) )
	{
	ret = String::CutRegexMatch( ret, "^,", false );
	y2milestone( "in %1 ret %2", opt, ret );
	}
    return( ret );
    };

global define string DefaultFstabOptions( map part )
    ``{
    symbol fsys = part["used_fs"]:`none;
    string old = part["fstopt"]:"";
    string fst_default = "";
    if( part["format"]:false && contains( [`ext2, `ext3, `reiser], fsys ) )
	{
	fst_default = "acl,user_xattr";
	}
    y2milestone( "DefaultFstabOptions fsys %1 is %2", fsys, fst_default );
    return( fst_default );
    }

global define map CheckFstabOptions( string option_list )
    ``{
    boolean found = false;
    integer index = 0;
    y2milestone( "CheckFstabOptions option_list=%1", option_list );
    list<string> olist = splitstring( option_list, "," );
    list<string> known = [];
    list<string> unknown = [];
    foreach( string o, olist,
	``{
	if( contains( FstabOptionStrings, o ) )
	    {
	    known = add( known, o );
	    }
	else 
	    {
	    found = false;
	    index = 0;
	    while( !found && index<size(FstabOptionRegex) )
		{
		found = regexpmatch( o, FstabOptionRegex[index]:"" );
		index = index + 1;
		}
	    if( found )
		{
		known = add( known, o );
		}
	    else
		{
		unknown = add( unknown, o );
		}
	    }
	});
    map ret = $[  "all_known" : size(unknown)==0, 
                  "known_options" : mergestring( known, "," ),
                  "unknown_options" : mergestring( unknown, "," ) ];
    y2milestone( "CheckFstabOptions ret=%1", ret );
    return( ret );
    }

global define map GetFstabDefaultMap( string key )
    ``{
    return( FstabDefaultMap[key]:$[] );
    }

global define string GetFstabDefaultMntops( string key )
    ``{
    map m = GetFstabDefaultMap( key );
    return( m["mntops"]:"" );
    }

global define list GetFstabDefaultList( string key )
    ``{
    map m = GetFstabDefaultMap( key );
    return( [ m["spec"]:"", m["mount"]:"", m["vfstype"]:"", m["mntops"]:"",
              tostring(m["freq"]:0), tostring(m["passno"]:0) ] );
    }


}
