home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / share / YaST2 / modules / SourceDialogs.ycp < prev    next >
Text File  |  2006-11-29  |  30KB  |  1,109 lines

  1. /**
  2.  * File:        SourceDialogs.ycp
  3.  *
  4.  * Authors:        Jiri Srain <jsrain@suse.cz>
  5.  *            Klaus Kaempf <kkaempf@suse.de>
  6.  *            Gabriele Strattner <gs@suse.de>
  7.  *            Stefan Schubert <schubi@suse.de>
  8.  *                      Cornelius Schumacher <cschum@suse.de>
  9.  *
  10.  * Purpose:
  11.  * Displays possibilities to install from NFS, CD or partion
  12.  *
  13.  * $Id: inst_source_dialogs.ycp 31607 2006-06-22 07:02:01Z jsuchome $
  14.  */
  15.  
  16. {
  17. textdomain "packager";
  18.  
  19. module "SourceDialogs";
  20.  
  21. import "Label";
  22. import "URL";
  23. import "Popup";
  24. import "CWM";
  25. import "SourceManager";
  26.  
  27. // common functions / data
  28.  
  29. /**
  30.  * URL to work with
  31.  */
  32. string _url = "";
  33.  
  34. /**
  35.  * Allow HTTPS for next source dialog?
  36.  */
  37. boolean _allow_https = true;
  38.  
  39. /**
  40.  * Help text suffix for some types of the medias
  41.  */
  42. string iso_help = _("<p>If the location is a file holding an ISO image
  43. of the media, set <b>ISO Image</b>.</p>");
  44.  
  45. /**
  46.  * Help text suffix for some types of the medias
  47.  */
  48. string multi_cd_help = _("<p>If the catalog is on multiple medias,
  49. set the location of the first media of the set.</p>");
  50.  
  51. /**
  52.  * Set the URL to work with
  53.  * @param url string URL to run the dialogs with
  54.  */
  55. global void SetURL (string url) {
  56.     _url = url;
  57. }
  58.  
  59. /**
  60.  * Return URL after the run of the dialog
  61.  * @return string the URL
  62.  */
  63. global string GetURL () {
  64.     return _url;
  65. }
  66.  
  67. /**
  68.  * Postprocess URL of an ISO image
  69.  * @param url string URL in the original form
  70.  * @return string postprocessed URL
  71.  */
  72. string PosprocessISOURL (string url) {
  73.     y2milestone ("Updating ISO URL %1", url);
  74.     integer last = findlastof (url, "/") + 1;
  75.     string onlydir = substring (url, 0, last);
  76.     url = "iso:/?iso=" + substring (url, last) + "&url=" + onlydir;
  77.     y2milestone ("Updated URL: %1", url);
  78.     return url;
  79. }
  80.  
  81. /**
  82.  * Check if URL is an ISO URL
  83.  * @param url string URL to check
  84.  * @return boolean true if URL is an ISO URL, false otherwise
  85.  */
  86. boolean IsISOURL (string url) {
  87.     boolean ret = substring (url, 0, 5) == "iso:/" &&
  88.     issubstring (url, "&url=");
  89.     y2milestone ("URL %1 is ISO: %2", url, ret);
  90.     return ret;
  91. }
  92.  
  93. /**
  94.  * Preprocess the ISO URL to be used in the dialogs
  95.  * @param url string URL to preprocess
  96.  * @return string preprocessed URL
  97.  */
  98. string PreprocessISOURL (string url) {
  99.     y2milestone ("Preprocessing ISO URL %1", url);
  100.     integer url_pt = search (url, "&url=");
  101.     string serverpart = substring (url, url_pt + 5);
  102.     string isopart = substring (url, 0, url_pt);
  103.     url = serverpart + substring (isopart, search (isopart, "iso=") + 4);
  104.     y2milestone ("Updated URL: %1", url);
  105.     return url;
  106. }
  107.  
  108. /**
  109.  * check if given path points to ISO file
  110.  * @param url string URL to check
  111.  * @return boolean true if URL is ISO image
  112.  */
  113. boolean PathIsISO (string url) {
  114.     if (size (url) < 4) return false;
  115.     return substring (url, size (url) - 4, 4) == ".iso";
  116. }
  117.  
  118. /**
  119.  * Add a slash to the part of url, if it is not already present
  120.  * @param urlpart string a part of the URL
  121.  * @return string urlpart with leading slash
  122.  */
  123. string Slashed (string urlpart) {
  124.     if ( substring( urlpart, 0, 1 ) == "/" )
  125.     return urlpart;
  126.     return "/" + urlpart;
  127. }
  128.  
  129. /**
  130.  * Remove leading and trailing (and inner) spaces from the host name
  131.  * @param host string original host name
  132.  * @return string host without leading and trailing spaces
  133.  */
  134. string NormalizeHost (string host) {
  135.     host = deletechars (host, " \t");
  136.     return host;
  137. }
  138.  
  139. /**
  140.  * Return an HBox with ok and cancel buttons for use by other dialogs.
  141.  * @return An HBox term for use in a CreateDialog call.
  142.  */
  143. term PopupButtons() {
  144.     return `HBox(
  145.     `PushButton( `id( `ok ), `opt( `default ), Label::OKButton() ),
  146.     `HStretch(),
  147.     `PushButton( `id( `cancel ), Label::CancelButton() )
  148.     );
  149. }
  150.  
  151. /**
  152.  * Get scheme of a URL, also for ISO URL get scheme of the access protocol
  153.  * @param url string URL to get scheme for
  154.  * @return string URL scheme
  155.  */
  156. string URLScheme (string url) {
  157.     string scheme = "";
  158.     if (IsISOURL (url))
  159.     {
  160.     string tmp_url = PreprocessISOURL (url);
  161.     map parsed = URL::Parse (tmp_url);
  162.     scheme = parsed["scheme"]:"";
  163.     }
  164.     else
  165.     {
  166.     map parsed = URL::Parse (url);
  167.     scheme = parsed["scheme"]:"";
  168.     }
  169.  
  170.     if (scheme == "" || scheme == nil)
  171.     scheme = "url";
  172.     y2milestone ("URL scheme for URL %1: %2", url, scheme);
  173.     return scheme;
  174. }
  175.  
  176. // raw URL editation widget
  177.  
  178. /**
  179.  * Init function of a widget
  180.  * @param key string widget key
  181.  */
  182. void PlainURLInit (string key) {
  183.     UI::ChangeWidget (`id (`url), `Value, _url);
  184.     UI::SetFocus (`url);
  185. }
  186.  
  187. /**
  188.  * Store function of a widget
  189.  * @param key string widget key
  190.  * @param event map which caused settings being stored
  191.  */
  192. void PlainURLStore (string key, map event) {
  193.     _url = (string)UI::QueryWidget (`id (`url), `Value);
  194. }
  195.  
  196. boolean PlainURLValidate (string key, map event) {
  197.     string url = (string)UI::QueryWidget (`id (`url), `Value);
  198.     if (url == "")
  199.     {
  200.     UI::SetFocus (`id (`url));
  201.     // popup message
  202.     Popup::Message (_("URL cannot be empty."));
  203.     return false;
  204.     }
  205.     return true;
  206. }
  207.  
  208. /**
  209.  * Get widget description map
  210.  * @return widget description map
  211.  */
  212. map<string,any> PlainURLWidget () {
  213.     return $[
  214.     "widget" : `custom,
  215.     "custom_widget" : `VBox (
  216.         // text entry
  217.         `TextEntry( `id( `url ), _("&URL") )
  218.     ),
  219.     "init" : PlainURLInit,
  220.     "store" : PlainURLStore,
  221.     "validate_type" : `function,
  222.     "validate_function" : PlainURLValidate,
  223.     // help text
  224.     "help" : _("<p><big><b>Catalog URL</b></big><br>
  225. Use <b>URL</b> to specify the URL of the catalog.<p>") + multi_cd_help,
  226.     ];
  227. }
  228.  
  229. // NFS editation widget
  230.  
  231. /**
  232.  * Init function of a widget
  233.  * @param key string widget key
  234.  */
  235. void NFSInit (string key) {
  236.     boolean iso = IsISOURL (_url);
  237.     if (iso)
  238.     _url = PreprocessISOURL (_url);
  239.     map parsed = URL::Parse (_url);
  240.     UI::ChangeWidget (`id (`server), `Value, parsed["host"]:"");
  241.     UI::ChangeWidget (`id (`dir), `Value, parsed["path"]:"");
  242.     UI::ChangeWidget (`id (`ch_iso), `Value, iso);
  243.     UI::SetFocus (`server);
  244. }
  245.  
  246. /**
  247.  * Store function of a widget
  248.  * @param key string widget key
  249.  * @param event map which caused settings being stored
  250.  */
  251. void NFSStore (string key, map event) {
  252.     map parsed = $[
  253.     "scheme" : "nfs",
  254.     "host" : NormalizeHost (
  255.         (string)UI::QueryWidget (`id (`server), `Value)),
  256.     "path" : (string)UI::QueryWidget (`id (`dir), `Value),
  257.     ];
  258.     _url = URL::Build (parsed);
  259.     boolean iso = (boolean)UI::QueryWidget (`id (`ch_iso), `Value);
  260.     if (iso)
  261.     _url = PosprocessISOURL (_url);
  262. }
  263.  
  264. /**
  265.  * Get widget description map
  266.  * @return widget description map
  267.  */
  268. map<string,any> NFSWidget () {
  269.     return $[
  270.     "widget" : `custom,
  271.     "custom_widget" : `VBox (
  272.         // text entry
  273.             `TextEntry (`id (`server), _("&Server Name")),
  274.         // text entry
  275.             `TextEntry (`id (`dir), _("&Path to Directory or ISO Image")),
  276.         // checkbox label
  277.         `Left (`CheckBox ( `id (`ch_iso), _("ISO Image")))
  278.     ),
  279.     "init" : NFSInit,
  280.     "store" : NFSStore,
  281.     // help text
  282.     "help" : _("<p><big><b>NFS Server</b></big><br>
  283. Use <b>Server Name</b> and <b>Path to Directory or ISO Image</b>
  284. to specify the NFS server host name and path on the server.<p>")
  285. + iso_help
  286. + multi_cd_help,
  287.     ];
  288. }
  289.  
  290. // CD/DVD source widget
  291.  
  292. /**
  293.  * Init function of a widget
  294.  * @param key string widget key
  295.  */
  296. void CDInit (string key) {
  297.     map parsed = URL::Parse (_url);
  298.     string scheme = parsed["scheme"]:"";
  299.     if (scheme == "dvd")
  300.     UI::ChangeWidget (`id (`cd), `Value, true);
  301.     else
  302.     UI::ChangeWidget (`id (`dvd), `Value, true);
  303.     UI::SetFocus (`cd);
  304. }
  305.  
  306. /**
  307.  * Store function of a widget
  308.  * @param key string widget key
  309.  * @param event map which caused settings being stored
  310.  */
  311. void CDStore (string key, map event) {
  312.     symbol device = (symbol)UI::QueryWidget (`id (`device), `CurrentButton);
  313.     if (device == `cd)
  314.     _url = "cd:///";
  315.     else
  316.     _url = "dvd:///";
  317. }
  318.  
  319. /**
  320.  * Get widget description map
  321.  * @return widget description map
  322.  */
  323. map<string,any> CDWidget () {
  324.     return $[
  325.     "widget" : `custom,
  326.     "custom_widget" : `RadioButtonGroup (`id (`device), `VBox (
  327.         // radio button
  328.         `Left (`RadioButton (`id (`cd), _("&CD-ROM"))),
  329.         // radio button
  330.         `Left (`RadioButton (`id (`dvd ), _("&DVD-ROM")))
  331.     )),
  332.     "init" : CDInit,
  333.     "store" : CDStore,
  334.     "help" : _("<p><big><b>CD or DVD Media</b></big><br>
  335. Set <b>CD-ROM</b> or <b>DVD-ROM</b> to specify the type of media.</p>"),
  336.     ];
  337. }
  338.  
  339. // File / Directory source widget
  340.  
  341. /**
  342.  * Init function of a widget
  343.  * @param key string widget key
  344.  */
  345. void DirInit (string key) {
  346.     boolean iso = IsISOURL (_url);
  347.     if (iso)
  348.     _url = PreprocessISOURL (_url);
  349.     map parsed = URL::Parse (_url);
  350.     UI::ChangeWidget (`id (`dir), `Value, parsed["path"]:"");
  351.     UI::SetFocus (`dir);
  352.  
  353. }
  354.  
  355. /**
  356.  * Store function of a widget
  357.  * @param key string widget key
  358.  * @param event map which caused settings being stored
  359.  */
  360. void DirStore (string key, map event) {
  361.     map parsed = $[
  362.     "scheme" : "dir",
  363.     "path" : (string)UI::QueryWidget (`id (`dir), `Value),
  364.     ];
  365.     _url = URL::Build (parsed);
  366.  
  367.     if (UI::WidgetExists(`id(`ch_iso)))
  368.     {
  369.     boolean iso = (boolean)UI::QueryWidget (`id (`ch_iso), `Value);
  370.     if (iso)
  371.         _url = PosprocessISOURL (_url);
  372.     }
  373. }
  374.  
  375. /**
  376.  * Handle function of a widget
  377.  * @param key string widget key
  378.  * @param event map which caused settings being stored
  379.  * @return always nil
  380.  */
  381. symbol DirHandle (string key, map event) {
  382.     boolean iso   = (UI::WidgetExists(`id(`ch_iso))) ?
  383.     (boolean)UI::QueryWidget (`id (`ch_iso), `Value)
  384.     : false;
  385.  
  386.     string dir = (string)UI::QueryWidget (`id (`dir), `Value);
  387.     string result = iso
  388.     // dialog caption
  389.     ?  UI::AskForExistingFile (dir, "*", _("ISO Image File"))
  390.     // dialog caption
  391.     : UI::AskForExistingDirectory (dir, _("Local Directory"));
  392.     if ( result != nil )
  393.     UI::ChangeWidget (`id (`dir), `Value, result);
  394.     return nil;
  395. }
  396.  
  397. /**
  398.  * Get widget description map
  399.  * @return widget description map
  400.  */
  401. map<string,any> DirWidget () {
  402.     return $[
  403.     "widget" : `custom,
  404.     "custom_widget" : `VBox(
  405.         `HBox(
  406.         // text entry
  407.                 `TextEntry (`id (`dir), _("&Path to Directory or ISO Image")),
  408.         `VBox (
  409.             `Label (""),
  410.             // push button
  411.             `PushButton (`id (`browse), _("&Browse..."))
  412.         )
  413.         ),
  414.         // checkbox label
  415.         `Left (`CheckBox (`id (`ch_iso), _("ISO Image")))
  416.     ),
  417.     "init" : DirInit,
  418.     "store" : DirStore,
  419.     "handle" : DirHandle,
  420.     "handle_events" : [ `browse ],
  421.     "help" : _("<p><big><b>Local Directory or ISO</b></big><br>
  422. Ise <b>Path to Directory or ISO Image</b> to specify the path to the
  423. directory or the file holding the ISO image of the installation media.</p>")
  424. + iso_help
  425. + multi_cd_help,
  426.     ];
  427.  
  428. }
  429.  
  430. /**
  431.  * Store function of a widget
  432.  * @param key string widget key
  433.  * @param event map which caused settings being stored
  434.  */
  435. void PlainDirStore (string key, map event) {
  436.     map parsed = $[
  437.     "scheme" : "pkg",
  438.     "path" : (string)UI::QueryWidget (`id (`dir), `Value),
  439.     ];
  440.     _url = URL::Build (parsed);
  441. }
  442. /**
  443.  * Get widget description map
  444.  * @return widget description map
  445.  */
  446. map<string,any> PlainDirWidget () {
  447.     return $[
  448.     "widget" : `custom,
  449.     "custom_widget" : `VBox(
  450.         `HBox(
  451.         // text entry
  452.                 `TextEntry (`id (`dir), _("&Path to Directory")),
  453.         `VBox (
  454.             `Label (""),
  455.             // push button
  456.             `PushButton (`id (`browse), _("&Browse..."))
  457.         )
  458.         )
  459.     ),
  460.     "init" : DirInit,
  461.     "store" : PlainDirStore,
  462.     "handle" : DirHandle,
  463.     "handle_events" : [ `browse ],
  464.     "help" : _("<p><big><b>Local Directory</b></big><br>
  465. Use <b>Path to Directory</b> to specify the path to the
  466. directory holding RPM packages.</p>")
  467.     ];
  468.  
  469. }
  470.  
  471. // HTTP(s)/FTP/SMB/CIFS source widget
  472.  
  473. /**
  474.  * Handle function of a widget
  475.  * @param key string widget key
  476.  * @param event map which caused settings being stored
  477.  * @return always nil
  478.  */
  479. symbol ServerHandle (string key, map event) {
  480.     y2debug("ServerHandle: %1, %2", key, event);
  481.     any id = event["ID"]:nil;
  482.     if (is (id, symbol)
  483.     && contains ([`http, `https, `ftp, `samba, `rb_type], (symbol)id))
  484.     {
  485.     symbol type = (symbol)UI::QueryWidget (`id (`rb_type), `CurrentButton);
  486.     string server = UI::WidgetExists (`id (`server))
  487.         ? (string)UI::QueryWidget (`id (`server), `Value)
  488.         : "";
  489.     string dir = UI::WidgetExists (`id (`dir))
  490.         ? (string)UI::QueryWidget (`id (`dir), `Value)
  491.         : "";
  492.     boolean anonymous = UI::WidgetExists (`id (`anonymous))
  493.         ? (boolean)UI::QueryWidget (`id (`anonymous), `Value)
  494.         : false;
  495.     string username = UI::WidgetExists (`id (`username))
  496.         ? (string)UI::QueryWidget (`id (`username), `Value)
  497.         : "";
  498.     string password = UI::WidgetExists (`id (`password))
  499.         ? (string)UI::QueryWidget (`id (`password), `Value)
  500.         : "";
  501.     term widget = `VBox (
  502.         // text entry
  503.         `TextEntry (`id (`server), _("Server &Name"), server),
  504.         type == `samba
  505.         // text entry
  506.         ? `TextEntry (`id (`share), _("&Share"))
  507.         : `Empty (),
  508.         type == `samba
  509.         ? `VBox (
  510.             `TextEntry (`id (`dir),
  511.             // text entry
  512.             _("&Path to Directory or ISO Image"), dir),
  513.  
  514.             // checkbox label
  515.             `Left (`CheckBox (`id (`ch_iso), _("ISO Image")))
  516.         )
  517.         // text entry
  518.         : `TextEntry( `id( `dir ), _("&Directory on Server"), dir),
  519.         `HBox (
  520.         `HSpacing (0.5),
  521.         // frame
  522.         `Frame (_("Au&thentication"), `VBox (
  523.             `Left (`CheckBox (`id (`anonymous), `opt (`notify),
  524.             // check box
  525.             _("&Anonymous"), anonymous)),
  526.             type == `samba
  527.             // text entry
  528.             ? `TextEntry (`id (`workgroup),
  529.                 _("Workgroup or Domain"))
  530.             : `Empty (),
  531.             // text entry
  532.             `TextEntry (`id (`username), _("&User Name"), username),
  533.             // password entry
  534.             `Password (`id (`password), _("&Password"), password)
  535.         )),
  536.         `HSpacing (0.5)
  537.         )
  538.     );
  539.     UI::ReplaceWidget (`id (`server_rp), widget);
  540.  
  541.     // update widget status
  542.     UI::ChangeWidget (`id (`username), `Enabled, !anonymous);
  543.     UI::ChangeWidget (`id (`password), `Enabled, !anonymous);
  544.     if (UI::WidgetExists (`id (`workgroup)))
  545.         UI::ChangeWidget (`id (`workgroup), `Enabled, !anonymous);
  546.  
  547.     return nil;
  548.     }
  549.     if (event["ID"]:nil == `anonymous)
  550.     {
  551.     boolean anonymous = (boolean)UI::QueryWidget (`id (`anonymous),
  552.         `Value);
  553.     UI::ChangeWidget (`id (`username), `Enabled, !anonymous);
  554.     UI::ChangeWidget (`id (`password), `Enabled, !anonymous);
  555.     if (UI::WidgetExists (`id (`workgroup)))
  556.         UI::ChangeWidget (`id (`workgroup), `Enabled, !anonymous);
  557.     return nil;
  558.     }
  559. }
  560.  
  561. /**
  562.  * Init function of a widget
  563.  * @param key string widget key
  564.  */
  565. void ServerInit (string key) {
  566.     term protocol_box = `HBox (
  567.     `HStretch (),
  568.     // radio button
  569.     `RadioButton (`id (`ftp),`opt (`notify), _("&FTP")),
  570.     `HStretch(),
  571.     // radio button
  572.     `RadioButton (`id (`http),`opt (`notify), _("H&TTP")),
  573.     `HStretch()
  574.     );
  575.     if (_allow_https)
  576.     {
  577.     protocol_box = add (protocol_box,
  578.         // radio button
  579.         `RadioButton (`id (`https), `opt (`notify), _("HTT&PS"))
  580.     );
  581.     protocol_box = add (protocol_box, `HStretch ());
  582.     }
  583.     protocol_box = add (protocol_box,
  584.     // radio button
  585.     `RadioButton (`id (`samba),`opt (`notify), _("&SMB/CIFS"))
  586.     );
  587.     protocol_box = add (protocol_box, `HStretch ());
  588.     protocol_box = `RadioButtonGroup (`id (`rb_type), `opt (`notify),
  589.     protocol_box);
  590.     UI::ReplaceWidget (`id (`rb_type_rp), protocol_box);
  591.  
  592.     boolean iso = IsISOURL (_url);
  593.     if (iso)
  594.     _url = PreprocessISOURL (_url);
  595.     map parsed = URL::Parse (_url);
  596.     symbol type = `ftp;
  597.     if ( parsed["scheme"]:"" == "http" )
  598.     type = `http;
  599.     else if ( parsed["scheme"]:"" == "https" )
  600.     type = `https;
  601.     else if ( parsed["scheme"]:"" == "smb" )
  602.     type = `samba;
  603.     UI::ChangeWidget (`id (`rb_type), `CurrentButton, type);
  604.     ServerHandle (key, $[ "ID" : `rb_type ]);
  605.  
  606.     UI::ChangeWidget (`id (`server), `Value, parsed["host"]:"");
  607.     string dir = parsed["path"]:"";
  608.     if (type == `samba)
  609.     {
  610.     UI::ChangeWidget (`id (`ch_iso), `Value, iso);
  611.     list sharepath = regexptokenize (dir, "^/*([^/]+)(/.*)?$");
  612.     string share = sharepath[0]:"";
  613.     dir = sharepath[1]:"";
  614.     if (dir == nil)
  615.         dir = "/";
  616.     string workgroup = "";
  617.     if (regexpmatch (dir, "^.*;workgroup=[^;]+$"))
  618.     {
  619.         workgroup = regexpsub (dir,
  620.         "^.*;workgroup=([^;]+)$", "\\1");
  621.         dir = regexpsub (dir, "^(.*);workgroup=[^;]+$", "\\1");
  622.     }
  623.     UI::ChangeWidget (`id (`workgroup), `Value, workgroup);
  624.     UI::ChangeWidget (`id (`share), `Value, share);
  625.     }
  626.     UI::ChangeWidget (`id (`dir), `Value, dir);
  627.     UI::ChangeWidget (`id (`username), `Value, parsed["user"]:"");
  628.     UI::ChangeWidget (`id (`password), `Value, parsed["pass"]:"");
  629.     boolean anonymous = ! (parsed["user"]:"" != "" || parsed["pass"]:"" != "");
  630.     y2milestone ("Anonymous: %1", anonymous);
  631.     UI::ChangeWidget (`id (`anonymous), `Value, anonymous);
  632.     if (anonymous)
  633.     {
  634.     UI::ChangeWidget (`id (`username), `Enabled, false);
  635.     UI::ChangeWidget (`id (`password), `Enabled, false);
  636.     if (UI::WidgetExists (`id (`workgroup)))
  637.         UI::ChangeWidget (`id (`workgroup), `Enabled, !anonymous);
  638.     }
  639. }
  640.  
  641. /**
  642.  * Store function of a widget
  643.  * @param key string widget key
  644.  * @param event map which caused settings being stored
  645.  */
  646. void ServerStore (string key, map event) {
  647.     y2debug("Server store: %1, %2", key, event);
  648.  
  649.     symbol type = (symbol) UI::QueryWidget( `id( `rb_type), `CurrentButton );
  650.     map parsed = $[];
  651.     if ( type == `ftp )
  652.     parsed["scheme"] = "ftp";
  653.     else if ( type == `http )
  654.     parsed["scheme"] = "http";
  655.     else if ( type == `https )
  656.     parsed["scheme"] = "https";
  657.     else if ( type == `samba )
  658.     parsed["scheme"] = "smb";
  659.  
  660.     boolean anonymous = (boolean)UI::QueryWidget (`id (`anonymous), `Value);
  661.     if ( !anonymous ) {
  662.     string user = (string)UI::QueryWidget (`id (`username), `Value);
  663.     string pass = (string)UI::QueryWidget (`id (`password ), `Value);
  664.     if (size (user) != 0)
  665.         parsed["user"] = user;
  666.     if (size (pass) != 0)
  667.         parsed["pass"] = pass;
  668.     }
  669.  
  670.     string host = NormalizeHost((string)UI::QueryWidget (`id (`server), `Value));
  671.     string directory = (string)UI::QueryWidget (`id (`dir), `Value);
  672.  
  673.     // is / in the host name?
  674.     integer pos = findfirstof(host, "/");
  675.     if (pos != nil)
  676.     {
  677.     // update the hostname and the directory,
  678.     // URL::Build return empty URL when the hostname is not valid
  679.     y2milestone("The hostname contains a path: %1", host);
  680.     string dir = substring(host, pos);
  681.  
  682.     if (substring(dir, size(dir) - 1, 1) != "/" && substring(directory, 0, 1) != "/")
  683.     {
  684.         dir = dir + "/";
  685.     }
  686.  
  687.     directory = dir + directory;
  688.     host = substring(host, 0, pos);
  689.  
  690.     y2milestone("Updated hostname: %1, directory: %2", host, directory);
  691.     }
  692.  
  693.     parsed["host"] = host;
  694.  
  695.     if (type == `samba)
  696.     {
  697.     string share = (string)UI::QueryWidget (`id (`share), `Value);
  698.     directory = Slashed (share) + Slashed (directory);
  699.     }
  700.     else if (type != `ftp)
  701.     // FTP needs to distinguish absolute and relative path
  702.     {
  703.     directory = Slashed (directory);
  704.     }
  705.     if (UI::WidgetExists (`id (`workgroup)))
  706.     {
  707.     string workgroup = (string)UI::QueryWidget (`id (`workgroup), `Value);
  708.     if (type == `samba && size (workgroup) > 0)
  709.         directory = directory + ";workgroup=" + workgroup;
  710.     }
  711.     parsed["path"] = directory;
  712.     y2milestone("Entered URL: %1", parsed);
  713.     _url = URL::Build (parsed);
  714.     y2milestone("URL::Build: %1", _url);
  715.     if (UI::WidgetExists (`id (`ch_iso)))
  716.     {
  717.     boolean iso = (boolean)UI::QueryWidget (`id (`ch_iso), `Value);
  718.     if (iso)
  719.         _url = PosprocessISOURL (_url);
  720.     }
  721. }
  722.  
  723.  
  724. /**
  725.  * Get widget description map
  726.  * @return widget description map
  727.  */
  728. map<string,any> ServerWidget () {
  729.     return $[
  730.     "widget" : `custom,
  731.     "custom_widget" : `VBox (
  732.         `HBox (
  733.         `HSpacing (0.5),
  734.         // frame
  735.         `Frame (_("P&rotocol"), `ReplacePoint (`id (`rb_type_rp),
  736.             `Empty ())
  737.         ),
  738.         `HSpacing( 0.5 )
  739.         ),
  740.         `ReplacePoint (`id (`server_rp), `Empty ())
  741.     ),
  742.     "init" : ServerInit,
  743.     "store" : ServerStore,
  744.     "handle" : ServerHandle,
  745.     "help" : _("<p><big><b>Server and Directory</b></big><br>
  746. Use <b>Server Name</b> and <b>Path to Directory or ISO Image</b>
  747. to specify the NFS server host name and path on the server.
  748. To enable authentication, uncheck <b>Anonymous</b> and specify the
  749. <b>User Name</b> and the <b>Password</b>.<p>
  750. <p>
  751. For SMB/CIFS source, specify <b>Share</b> name and <b>Path to Directory
  752. or ISO Image</b>. 
  753. If the location is a file holding an ISO image
  754. of the media, set <b>ISO Image</b>.</p>")
  755. + multi_cd_help,
  756.     ];
  757. }
  758.  
  759. /**
  760.  * Checks whether some network is available in the current moment,
  761.  * see the bug #170147 for more information.
  762.  */
  763. boolean IsAnyNetworkAvailable () {
  764.         boolean ret = false;
  765.         
  766.         string command = "TERM=dumb /sbin/ip -o address show | grep inet | grep -v scope.host";
  767.         y2milestone("Running %1", command);
  768.         map cmd_run = (map) SCR::Execute(.target.bash_output, command);
  769.         y2milestone("Command returned: %1", cmd_run);
  770.  
  771.         // command failed
  772.         if (cmd_run["exit"]:-1 != 0) {
  773.             // some errors were there, we don't know the status, rather return that it's available
  774.             // `grep` also returns non zero exit code when there is nothing to do...
  775.             if (cmd_run["stdout"]:"" != "") {
  776.                 y2error("Checking the network failed");
  777.                 ret = true;
  778.             }
  779.         // some devices are listed
  780.         } else if (cmd_run["stdout"]:"" != nil && cmd_run["stdout"]:"" != "") {
  781.             ret = true;
  782.         }
  783.         
  784.         return ret;    
  785. }
  786.  
  787.  
  788. term SelectRadioWidget () {
  789.     term contents = `HBox (`HStretch (), `VBox (
  790.     `RadioButtonGroup (`id (`type), `VBox (
  791.         `VStretch (),
  792.         // radio button
  793.         `Left (`RadioButton(`id(`slp),       _("&Scan Using SLP..."))),
  794.         // radio button
  795.         `Left (`RadioButton(`id(`ftp),       _("&FTP..."))),
  796.         // radio button
  797.         `Left (`RadioButton(`id(`http),      _("&HTTP..."))),
  798.         // radio button
  799.         `Left (`RadioButton(`id(`https),      _("HTT&PS..."))),
  800.         // radio button
  801.         `Left (`RadioButton(`id(`samba),     _("&SMB/CIFS"))),
  802.         // radio button
  803.         `Left (`RadioButton(`id(`nfs),       _("&NFS..."))),
  804.         // radio button
  805.         `Left (`RadioButton(`id(`cd),        _("&CD..."))),
  806.         // radio button
  807.         `Left (`RadioButton(`id(`dvd),       _("&DVD..."))),
  808.         // radio button
  809.         `Left (`RadioButton(`id(`local_dir), _("&Local Directory..."))),
  810.         // radio button
  811.         `Left (`RadioButton(`id(`pkg), _("&Package Directory..."))), // TODO: Proposal: move the functionality to "Local Directory", move ISO here
  812.         // radio button
  813.         `Left (`RadioButton (`id (`specify_url),_("Specify &URL..."))),
  814.         `VStretch ()
  815.     ))), `HStretch ()
  816.     );
  817.     if (! IsAnyNetworkAvailable()) {
  818.     y2milestone ("Network is not available, skipping all Network-related options...");
  819.  
  820.     contents = `HBox (`HStretch (), `VBox (
  821.         `RadioButtonGroup (`id (`type), `VBox (
  822.         `VStretch (),
  823.         // radio button
  824.         `Left (`RadioButton(`id(`cd),        _("&CD..."))),
  825.         // radio button
  826.         `Left (`RadioButton(`id(`dvd),       _("&DVD..."))),
  827.         // radio button
  828.         `Left (`RadioButton(`id(`local_dir), _("&Local Directory..."))),
  829.         // radio button
  830.         `Left (`RadioButton(`id(`pkg), _("&Package Directory..."))),
  831.         // radio button
  832.         `Left (`RadioButton (`id (`specify_url),_("Specify &URL..."))),
  833.         `VStretch ()
  834.         ))), `HStretch ()
  835.     );
  836.     } else {
  837.     y2milestone("Network is available, allowing Network-related options...");
  838.     }
  839.     return contents;
  840. }
  841.  
  842. string SelectWidgetHelp () {
  843.     // help text
  844.     string help_text = _("<p><big><b>Catalog Media</b></big><br>
  845. The software catalog can be located on CD, on a network server,
  846. or on the hard disk.</p>");
  847.  
  848.     // help, continued
  849.     help_text = help_text + _("<p>
  850. To add  <b>CD</b> or <b>DVD</b>,
  851. have the product CD set or the DVD available.</p>");
  852.  
  853.     // help, continued
  854.     help_text = help_text + _("<p>
  855. The product CDs can be copied to the hard disk.
  856. Insert the path where the first
  857. CD is located, for example, /data1/<b>CD1</b>.
  858. Only the base path is required if all CDs are copied
  859. into one directory.</p>
  860. ");
  861.  
  862.     // help, continued
  863.     help_text = help_text + _("<p>
  864. Network installation requires a working network connection.
  865. Specify the directory where the packages from
  866. the first CD are located, such as /data1/CD1.</p>
  867. ");
  868.     return help_text;
  869. }
  870.  
  871. boolean SelectValidate (string key, map event) {
  872.     symbol selected = (symbol)UI::QueryWidget (`id (`type), `CurrentButton);
  873.     if (selected == nil)
  874.     {
  875.     // error popup
  876.     Popup::Message (_("Select the media type."));
  877.     return false;
  878.     }
  879.     if (selected == `cd || selected == `dvd)
  880.     {
  881.     Pkg::SourceReleaseAll();
  882.     string msg = selected == `cd
  883.         ? _("Insert the add-on product CD")
  884.         : _("Insert the add-on product DVD");
  885.     if (! SourceManager::AskForCD (msg))
  886.         return false;
  887.     }
  888.     return true;
  889. }
  890.  
  891. symbol SelectHandle (string key, map event) {
  892.     if (! (event["ID"]:nil == `next || event["ID"]:nil == `ok))
  893.     return nil;
  894.     symbol selected = (symbol)UI::QueryWidget (`id (`type), `CurrentButton);
  895.     if (selected == nil)
  896.     return nil;
  897.     if (selected == `slp || selected == `cd || selected == `dvd)
  898.     return `finish;
  899. }
  900.  
  901. void SelectStore (string key, map event) {
  902.     _url = "";
  903.     symbol selected = (symbol)UI::QueryWidget (`id (`type), `CurrentButton);
  904.     if (contains ([`ftp, `http, `https, `samba, `nfs, `cd, `dvd,
  905.     `local_dir, `specify__url, `slp, `pkg], selected))
  906.     {
  907.     if ( selected == `ftp ) _url = "ftp://";
  908.     else if ( selected == `http ) _url = "http://";
  909.     else if ( selected == `https ) _url = "https://";
  910.     else if ( selected == `samba ) _url = "smb://";
  911.     else if ( selected == `nfs ) _url = "nfs://";
  912.     else if ( selected == `cd ) _url = "cd:///";
  913.     else if ( selected == `dvd ) _url = "dvd:///";
  914.     else if ( selected == `local_dir ) _url = "dir://";
  915.     else if ( selected == `pkg ) _url = "pkg://";    // hack for local PlainDir source
  916.     else if ( selected == `slp ) _url = "slp://";
  917.     }
  918. }
  919.  
  920. map<string,any> SelectWidget () {
  921.     return $[
  922.     "widget" : `func,
  923.     "widget_func" : SelectRadioWidget,
  924.     "help" : SelectWidgetHelp (),
  925.     "validate_type" : `function,
  926.     "validate_function" : SelectValidate,
  927.     "store" : SelectStore,
  928.     "handle" : SelectHandle,
  929.     ];
  930. }
  931.  
  932. // general data
  933.  
  934. /**
  935.  * Individual widgets
  936.  */
  937. map<string,map<string,any> > _widgets = $[];
  938.  
  939. /**
  940.  * Get individual widgets
  941.  * @return individual widgets
  942.  */
  943. map<string,map<string,any> > Widgets () {
  944.     if (size (_widgets) == 0)
  945.     _widgets = $[
  946.         "url" : PlainURLWidget (),
  947.         "nfs" : NFSWidget (),
  948.         "cd" : CDWidget (),
  949.         "dvd" : CDWidget (),
  950.         "dir" : DirWidget (),
  951.         "file" : DirWidget (),
  952.         "pkg" : PlainDirWidget(),
  953.         "http" : ServerWidget (),
  954.         "https" : ServerWidget (),
  955.         "ftp" : ServerWidget (),
  956.         "smb" : ServerWidget (),
  957.         "cifs" : ServerWidget (),
  958.         "select" : SelectWidget (),
  959.     ];
  960.     return _widgets;
  961. }
  962.  
  963. /**
  964.  * Captions for individual protocols
  965.  */
  966. map<string,string> _caption = $[
  967.     // label / dialog caption
  968.     "url" : _("Catalog URL"),
  969.     // label / dialog caption
  970.     "nfs" : _("NFS Server"),
  971.     // label / dialog caption
  972.     "cd" : _("CD or DVD Media"),
  973.     // label / dialog caption
  974.     "dvd" : _("CD or DVD Media"),
  975.     // label / dialog caption
  976.     "dir" : _("Local Directory or ISO"),
  977.     // label / dialog caption
  978.     "file" : _("Local Directory or ISO"),
  979.     // label / dialog caption
  980.     "pkg"  : _("Package Directory"),
  981.     // label / dialog caption
  982.     "http" : _("Server and Directory"),
  983.     // label / dialog caption
  984.     "https" : _("Server and Directory"),
  985.     // label / dialog caption
  986.     "ftp" : _("Server and Directory"),
  987.     // label / dialog caption
  988.     "smb" : _("Server and Directory"),
  989.     // label / dialog caption
  990.     "cifs" : _("Server and Directory"),
  991. ];
  992.  
  993. // general functions
  994.  
  995. /**
  996.  * Get contents of a popup for specified protocol
  997.  * @param proto string protocol to display popup for
  998.  * @return term popup contents
  999.  */
  1000. term PopupContents (string proto) {
  1001.     return `VBox (
  1002.     `HSpacing (50),
  1003.     // label
  1004.     `Label (_caption[proto]:""),
  1005.     proto,
  1006.     PopupButtons ()
  1007.     );
  1008. };
  1009.  
  1010. /**
  1011.  * URL editation popup with the HTTPS option
  1012.  * @param url string url URL to edit
  1013.  * @return string modified URL or empty string if canceled
  1014.  */
  1015. global string EditPopup (string url) {
  1016.     SetURL (url);
  1017.     string proto = URLScheme (url);
  1018.     y2milestone ("Displaying popup for protocol %1", proto);
  1019.  
  1020.     list<map<string,any> > w = CWM::CreateWidgets ([proto], Widgets ());
  1021.     term contents = PopupContents (proto);
  1022.     contents = CWM::PrepareDialog (contents, w);
  1023.     UI::OpenDialog (contents);
  1024.     symbol ret = CWM::Run (w, $[]);
  1025.     y2milestone ("Ret: %1", ret);
  1026.     UI::CloseDialog ();
  1027.     if (ret == `ok)
  1028.     return GetURL ();
  1029.     else
  1030.     return "";
  1031. }
  1032.  
  1033. /**
  1034.  * URL editation popup without the HTTPS option
  1035.  * @param url string url URL to edit
  1036.  * @return string modified URL or empty string if canceled
  1037.  */
  1038. global string EditPopupNoHTTPS (string url) {
  1039.     _allow_https = false;
  1040.     string ret = EditPopup (url);
  1041.     _allow_https = true;
  1042.     return ret;
  1043. }
  1044.  
  1045. /**
  1046.  * Sample implementation of URL selection dialog
  1047.  * @return symbol for wizard sequencer
  1048.  */
  1049. global symbol EditDialog () {
  1050.     string proto = URLScheme (_url);
  1051.     y2milestone ("Displaying dialog for protocol %1", proto);
  1052.     string caption = _caption[proto]:"";
  1053.  
  1054.     return CWM::ShowAndRun ($[
  1055.     "widget_names" : [proto],
  1056.     "widget_descr" : Widgets (),
  1057.     "contents" :  `HVCenter(`MinWidth( 65, proto ) ),
  1058.     "caption" : caption,
  1059.     "back_button" : Label::BackButton (),
  1060.     "next_button" : Label::NextButton (),
  1061.     "fallback_functions" : $[]
  1062.     ]);
  1063. }
  1064.  
  1065. /**
  1066.  * URL editation popup with the HTTPS option
  1067.  * @return string modified URL or empty string if canceled
  1068.  */
  1069. global string TypePopup () {
  1070.     list<map<string,any> > w = CWM::CreateWidgets (["select"], Widgets ());
  1071.     term contents = PopupContents ("select");
  1072.     contents = CWM::PrepareDialog (contents, w);
  1073.     UI::OpenDialog (contents);
  1074.     symbol ret = CWM::Run (w, $[]);
  1075.     y2milestone ("Ret: %1", ret);
  1076.     UI::CloseDialog ();
  1077.     return "";
  1078. /*
  1079.     if (ret == `ok)
  1080.     return GetURL ();
  1081.     else
  1082.     return "";
  1083. */
  1084. }
  1085.  
  1086. /**
  1087.  * Sample implementation of URL type selection dialog
  1088.  * @return symbol for wizard sequencer
  1089.  */
  1090. global symbol TypeDialog () {
  1091.     y2milestone ("Running source type dialog");
  1092.     // dialog caption
  1093.     string caption = _("Media Type");
  1094.     symbol ret = CWM::ShowAndRun ($[
  1095.     "widget_names" : ["select"],
  1096.     "widget_descr" : Widgets (),
  1097.     "contents" : `VBox ( "select" ),
  1098.     "caption" : caption,
  1099.     "back_button" : Label::BackButton (),
  1100.     "next_button" : Label::NextButton (),
  1101.     "fallback_functions" : $[]
  1102.     ]);
  1103.     y2milestone ("Type dialog returned %1", ret);
  1104.     return ret;
  1105. }
  1106.  
  1107. } // EOF
  1108.  
  1109.