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

  1. /*
  2.  *
  3.  * Module:             lan.ycp
  4.  *
  5.  * Author:             Stepan Marek (marek@suse.cz)
  6.  *
  7.  * Purpose:
  8.  * - autodetect network cards and install kernel module for eth0 device
  9.  * - set static IP address or dynamic IP address via DHCP for eth0.
  10.  * - set hostname and configure DNS access.
  11.  * - initial values are read from previous done configuration.
  12.  * - compatibility with YaST1 configurations is preserved
  13.  * - configuration of other devices and network interfaces 
  14.  *   ([eth1, eth2...], [isdn0, isdn1...] ...) is preserved
  15.  * - create backup file with postfix .old
  16.  *
  17.  * Require: 
  18.  * - installed dhclient or dhcpd package for dynamic IP address setup
  19.  *
  20.  * Modify:
  21.  *   /etc/rc.config
  22.  *   /etc/modules.conf
  23.  *
  24.  * Create:
  25.  *   /etc/route.conf
  26.  *
  27.  * Run SuSEconfig to generate /etc/hosts, /etc/host.conf, /etc/resolv.conf
  28.  *
  29.  */
  30.  
  31. {
  32.     boolean has_pcmcia = SCR(`Read(.probe.has_pcmcia));
  33.     boolean card_is_pcmcia = false;
  34.  
  35.   // get full name of device from .probe device map
  36.   define name_of_device (map device) ``{
  37.     string sub_vendor = lookup (device, "sub_vendor", "");
  38.     string sub_device = lookup (device, "sub_device", "");
  39.     if ((sub_vendor != "") && (sub_device != ""))
  40.     return (sub_vendor + " " + sub_device);
  41.     else
  42.     return (lookup (device, "vendor", "") + " " + lookup (device, "device", ""));
  43.   };
  44.  
  45.   // Menuentry for the YaST2 menu
  46.   if (Args() == [ "get_menuentry" ]) 
  47.     return [ "lan", $[
  48.             `menuentry    : UI(_("Network/Base")),
  49.             `arguments    : [ ],
  50.             `widget       : `RichText(
  51.                           // 
  52.                           UI(_("Launch this module to configure network devices for local networks"))
  53.                              +
  54.                           UI(_("<p>You need to be logged in as <i>root</i> in order to do this.</p>"))),
  55.             `codefragment : nil ]
  56.     ];
  57.  
  58.  
  59.   UI(``{
  60.     
  61.     // The main dialog. Copied from installation.ycp.
  62.     OpenDialog(`opt(`defaultsize),
  63.            `VBox(`Image(`suseheader, "SuSE"),
  64.              `HBox(`HWeight(30, `RichText(`id(`help), "")),
  65.                `HWeight(70, `VBox(
  66.                           `Left(`Heading(`id(`title), _("YaST2\nInitializing ..."))),
  67.                           `HVCenter(`ReplacePoint(`id(`contents), `Empty())),
  68.                           `HBox(
  69.                             // back pushbutton: the user input is ignored and the last dialog is called
  70.                             `PushButton(`id(`back), `opt(`disabled), _("&Back")),
  71.                             `HStretch(),
  72.                             // next pushbutton: the user input is checked and the next dialog is called
  73.                             `PushButton(`id(`next), `opt(`disabled), _("&Next"))))))));
  74.       
  75.     
  76.     define SetContents(string title, term contents, string helptext,
  77.                boolean has_back, boolean has_next) ``{
  78.       ChangeWidget(`id(`next), `Enabled, has_next);
  79.       ChangeWidget(`id(`back), `Enabled, has_back);
  80.       ChangeWidget(`id(`help), `Value, helptext);
  81.       ChangeWidget(`id(`title), `Value, title);
  82.       ReplaceWidget(`id(`contents), contents);
  83.       // ControlWidget(TheWizardDialog(), `id(`next), `SetFocus());
  84.     };
  85.  
  86.     define DisplayMessage(string message, integer code, string stack) ``{
  87.       // ok pushbutton: confirm the dialog
  88.       term t = `VBox();
  89.       t = add(t, `Left(`Label(message)));
  90.       if (code != 0)
  91.     // optional warning dialog text
  92.     t = add(t, `Left(`Label(sformat(_("Error code %1"), code))));
  93.       if (stack != "") 
  94.     t = add(t, `Left(`Label(stack)));
  95.       OpenDialog(`opt(`decorated), add(t, `PushButton(_("&OK"))));
  96.       UserInput();
  97.       CloseDialog();
  98.     }; 
  99.   });
  100.  
  101.   SCR(``{
  102.  
  103.     /*
  104.      * AnyAgent for reading default gateway from /etc/route.conf
  105.      *
  106.      * return: the last 'default' ip address in ip4number format
  107.      * example: $["default":168427521]
  108.      *
  109.      */
  110.     MountAgent (
  111.         `anyagent (
  112.                ``Description (
  113.                       ``File ("/etc/route.conf"),// real file name
  114.                       "#\n",                    // Comment
  115.                       true,                    // read-only
  116.                       ``Tuple (
  117.                            Optional (Whitespace ()),
  118.                            Choice (
  119.                                ["default", 
  120.                                Sequence(
  121.                                     Whitespace (), 
  122.                                     `default (Ip4Number ()), 
  123.                                     Optional (String ("^\n")),
  124.                                     Continue ("\n")
  125.                                     )],
  126.                                [String("^\n"), 
  127.                                Continue ("\n")]
  128.                                )
  129.                            )
  130.                         
  131.                       )
  132.                ), 
  133.         .etc.routeconf.read
  134.         );
  135.     
  136.     /*
  137.      * AnyAgetnt for reading /etc/rc.config
  138.      *
  139.      * return: map of all variables
  140.      * example: $["FQHOSTNAME":"linux.suse.de", "YP_DOMAINNAME":"suse.de", "umask":"022"]
  141.      *
  142.      */
  143.     MountAgent (
  144.         `anyagent(
  145.               ``Description (
  146.                      ``File ("/etc/rc.config"), // real file name
  147.                      "#\n",                    // Comment
  148.                      true,                    // read-only
  149.                      ``Tuple (
  150.                           Optional (Whitespace ()),
  151.                           Name (String ("^\t =")),
  152.                           Optional (Whitespace ()),
  153.                           Separator ("="),
  154.                           Optional (Whitespace ()),
  155.                           Choice (
  156.                               ["\"", 
  157.                               Sequence (
  158.                                     Optional (Value (String ("^\"\n"))), 
  159.                                     Optional (String ("^\n")), 
  160.                                     Continue("\n"))],
  161.                               [Value (String ("^\n\t ")), 
  162.                               Sequence (
  163.                                     Optional (String ("^\n")), 
  164.                                     Continue ("\n"))],
  165.                               [Continue ("\n"), 
  166.                               Skip ()]
  167.                               )
  168.                           )
  169.                      
  170.                      )
  171.               ), 
  172.         .etc.rcconfig.read
  173.         );
  174.  
  175.     /*
  176.      * AnyAgent for reading /etc/modules.conf
  177.      *
  178.      * read: /etc/modules.conf
  179.      * return: list of all lines (including empty lines) as maps
  180.      * example:
  181.      *  [
  182.      *   $["comment":"# The first ethernet device"],
  183.      *   $[],
  184.      *   $["alias":["eth0", "ne"], "comment":"# NE2000 compatible network card"], 
  185.      *   $["options":["ne", "irq=5", "io=0x240"]]
  186.      *  ]
  187.      *
  188.      */
  189.     MountAgent (
  190.         `anyagent(
  191.               ``Description (
  192.                      ``File ("/etc/modules.conf"),
  193.                      // ``Run ("/sbin/modprobe -c"),
  194.                      "",
  195.                      true,
  196.                      ``List (
  197.                          Tuple (
  198.                             Choice (
  199.                                 [
  200.                                  "alias",
  201.                                  Sequence (Whitespace (),
  202.                                        `alias (
  203.                                            List (
  204.                                              String ("^\n\t #"),
  205.                                              Whitespace ()
  206.                                              )
  207.                                            )
  208.                                        )
  209.                                 ],
  210.                                 [
  211.                                  "options",
  212.                                  Sequence (
  213.                                        Whitespace (),
  214.                                        `options (
  215.                                              List (
  216.                                                String ("^\n\t #"),
  217.                                                Whitespace ()
  218.                                                )
  219.                                              )
  220.                                        )
  221.                                 ],
  222.                                 [
  223.                                  "",
  224.                                  Skip ()
  225.                                 ]
  226.                                 ),
  227.                             `comment (Optional(String("^\n")))
  228.                             ),                           
  229.                          "\n"
  230.                          )
  231.                      )
  232.               ),
  233.         .etc.modulesconf.read
  234.         );
  235.     
  236.     /*
  237.      * AnyAgent for creating unique temporary file in /tmp directory
  238.      *
  239.      * run: mktemp
  240.      * return: file name string of new created file or "" in case of some error
  241.      *
  242.      */
  243.     MountAgent (`anyagent(
  244.               ``Description (
  245.                      ``Run("/bin/mktemp -q /tmp/YaST2.XXXXXX; echo"),
  246.                      "",
  247.                      true,                     
  248.                      ``Or (String("^\n"), "")
  249.                      )
  250.               ), 
  251.         .run.mktemp
  252.         );
  253.  
  254.     /*
  255.      * AnyAgent for reading ip address, broadcast and netmask (as the ip4numbers)
  256.      * of running network interfaces from ifconfig output
  257.      *
  258.      * example:
  259.      * $[
  260.      *    "eth0":$["addr":168453207,  "bcast":168493055, "mask":4294901760], 
  261.      *    "lo":  $["addr":2130706433, "mask":4278190080]
  262.      *  ]
  263.      *
  264.      */
  265.     MountAgent (`anyagent(
  266.               ``Description (
  267.                      ``Run("/sbin/ifconfig"),
  268.                      "\n",
  269.                      true,
  270.                      ``Tuple (
  271.                           Choice (
  272.                               [
  273.                                Name (String ("^\t ")),
  274.                                String ("^\n")
  275.                               ],
  276.                               [
  277.                                Whitespace (),
  278.                                Choice (
  279.                                    [
  280.                                     "inet",
  281.                                     Value (
  282.                                        Tuple (
  283.                                           Optional (Whitespace ()),
  284.                                           Choice (
  285.                                               [
  286.                                                "addr:",
  287.                                                `addr (Ip4Number ())
  288.                                               ],
  289.                                               [
  290.                                                "Bcast:",
  291.                                                `bcast (Ip4Number ())
  292.                                               ],
  293.                                               [
  294.                                                "Mask:",
  295.                                                `mask (Ip4Number ())
  296.                                               ],
  297.                                               [
  298.                                                String ("^\n\t "),
  299.                                                Skip()
  300.                                               ]
  301.                                               ),
  302.                                           Continue (Whitespace ())
  303.                                           )
  304.                                        )
  305.                                    ],
  306.                                    [ 
  307.                                     String ("^\n"),
  308.                                     Skip ()
  309.                                    ]
  310.                                    )
  311.                               ]
  312.                               ),
  313.                           Continue ("\n")
  314.                           )
  315.                      )
  316.               ),
  317.         .run.ifconfig
  318.         );
  319.  
  320.  
  321.     /*
  322.      * AnyAgent for reading nslookup output. 
  323.      * Output must must be written to /tmp/nslookup.out file before reading
  324.      * After reading /tmp/nslookup.out should be removed
  325.      *
  326.      * return: name of dns server and name of host from dns
  327.      *
  328.      * example: 
  329.      *   $["name":"Phoenix.suse.de", "server":"Wotan.suse.de"]
  330.      *
  331.      * usage example:
  332.      *   Shell("/usr/bin/nslookup -timeout=1 10.10.0.8 > /tmp/nslookup.out");
  333.      *   map m = SCR(`Read(.tmp.nslookup));
  334.      *   Shell("/bin/rm -f /tmp/nslookup.out");
  335.      *
  336.      */
  337.     MountAgent (`anyagent(
  338.               ``Description (
  339.                      ``File("/tmp/nslookup.out"),
  340.                      "*\n",
  341.                      false,
  342.                      ``Tuple (
  343.                           Choice (
  344.                               [
  345.                                "Server:",
  346.                                Sequence (
  347.                                      Whitespace (), 
  348.                                      `server (Hostname ())
  349.                                      )
  350.                               ],
  351.                               [
  352.                                "Name:", 
  353.                                Sequence (
  354.                                      Whitespace (), 
  355.                                      `name (Hostname ())
  356.                                      )
  357.                               ],
  358.                               [
  359.                                String ("^\n"),
  360.                                Skip ()
  361.                               ],
  362.                               [
  363.                                "",
  364.                                Skip ()
  365.                               ]
  366.                               ),
  367.                           Continue ("\n")
  368.                           )
  369.                      )
  370.               ),
  371.         .tmp.nslookup
  372.         );
  373.  
  374.     /*
  375.      * AnyAgent for reading address from ping return
  376.      * Usually used for geting ips of responded computer on the local network 
  377.      *   from ping to broadcast address to check network connection of host.
  378.      *
  379.      * Output from ping must be saved to /tmp/ping.out before reading
  380.      * 
  381.      * usage example:
  382.      *   Shell("/bin/ping -w 1 -n 10.10.255.255 > /tmp/ping.out & /bin/sleep 2; /bin/kill $!");
  383.      *   list l = SCR(`Read(.tmp.ping));
  384.      *   Shell("/bin/rm -f /tmp/ping.out");
  385.      *
  386.      * return: list of ips (ip4number) of responded host (duplicities are preserved)
  387.      * 
  388.      * example:
  389.      *   [168427521, 168427522, 168427523]
  390.      */
  391.     MountAgent (`anyagent(
  392.               ``Description (
  393.                      ``File("/tmp/ping.out"),
  394.                      "",
  395.                      false,
  396.                       ``List (
  397.                           Choice (
  398.                              [Number (),
  399.                              Choice (
  400.                                  [" bytes from ",
  401.                                  Ip4Number ()],
  402.                                  ["",
  403.                                  Skip ()]
  404.                                  )
  405.                              ],
  406.                              ["",
  407.                              Skip ()]
  408.                              ),
  409.                           Sequence (Optional (String ("^\n")), "\n")
  410.                          )
  411.                      )
  412.               ),
  413.         .tmp.ping
  414.         );
  415.     
  416.   });
  417.  
  418.   /*
  419.    * Split long string by characters in separator string into list of strings
  420.    *
  421.    *   split("addr:127.0.0.1  Mask:255.0.0.0", ": .") ->
  422.    *   -> ["addr", "127", "0", "0", "1", "Mask", "255", "0", "0", "0"]
  423.    *
  424.    */
  425.   define split(string s, string sep) ``{
  426.  
  427.     list chars = [];
  428.       
  429.     integer|void  i = size(sep) - 1;
  430.       
  431.     while (i >= 0) {    
  432.       
  433.       chars = add(chars, substring(sep, i, 1));
  434.       
  435.       i = i - 1;
  436.       
  437.     }
  438.       
  439.     chars = add(chars, "");
  440.       
  441.     list l = [];
  442.       
  443.     string ch = "";
  444.       
  445.     i = findfirstnotof(s, sep);
  446.       
  447.     while (i != nil) {
  448.       
  449.       s = substring(s, i);
  450.       
  451.       i = 0;
  452.       
  453.       ch = substring(s, 0, 1);
  454.       
  455.       while (!contains(chars, ch)) {
  456.           
  457.     i = i + 1;
  458.           
  459.     ch = substring(s, i, 1);
  460.           
  461.       } 
  462.       
  463.       l = add (l, substring(s, 0, i));
  464.     
  465.       s = substring(s, i);
  466.       
  467.       i = findfirstnotof(s, sep);
  468.     }
  469.       
  470.     return l;
  471.  
  472.   };
  473.  
  474.   /*
  475.    * Join list into string with separator (complement to split)
  476.    *
  477.    */
  478.   define join(list l, string sep) ``{
  479.  
  480.     if (size(l) == 0) return "";
  481.  
  482.     string str = sformat("%1", select(l, 0));
  483.  
  484.     integer i = 1;
  485.  
  486.     while (i < size(l)) {
  487.       
  488.       string s = sformat("%1", select(l, i));
  489.  
  490.       if (s != "") 
  491.     str = str + sep + s;
  492.       
  493.       i = i + 1;
  494.  
  495.     }
  496.     
  497.     return str;
  498.     
  499.   };
  500.  
  501.   /*
  502.    * Convert ip address string into list of four integer
  503.    * Return [] in case of syntax error
  504.    *
  505.    * strtoaddr("127.0.0.0") -> [127, 0, 0, 0]
  506.    *
  507.    */
  508.   define strtoaddr(string str) ``{
  509.       
  510.     integer i = 0;
  511.     integer j = 4;
  512.     integer x = 0;
  513.     list ip = [];
  514.       
  515.     str =  str + ".";
  516.       
  517.     while (j > 0) {
  518.       
  519.       i = findfirstnotof (str, "1234567890");
  520.       
  521.       if ((substring (str, i, 1) == ".") && (i != 0)) {
  522.           
  523.     x = tointeger(str);
  524.           
  525.     if (x > 255) return [];
  526.           
  527.     ip = add(ip, x);
  528.           
  529.     str = substring (str, i + 1);
  530.           
  531.       } else {
  532.           
  533.     return [];
  534.           
  535.       }
  536.       
  537.       j = j - 1;
  538.     }
  539.       
  540.     if (size(str) > 0) return [];
  541.       
  542.     return ip;
  543.       
  544.   };
  545.  
  546.   /*
  547.    * Convert ip4number address into list of four interger values
  548.    *
  549.    * ip4toaddr(2130706432) -> [127, 0, 0, 0]
  550.    *
  551.    */
  552.   define ip4toaddr(integer|void ii) ``{
  553.  
  554.     if (ii == nil) return [];
  555.  
  556.     list ip = [];
  557.  
  558.     integer i = 0x1000000;
  559.       
  560.     while (i >= 1) {
  561.  
  562.       ip = add(ip, ii / i);
  563.       
  564.       ii = ii % i;
  565.  
  566.       i = i / 0x100;
  567.  
  568.     }
  569.  
  570.     return ip;
  571.  
  572.   };
  573.  
  574.   /*
  575.    * Convert list of four integers into ip address string 
  576.    *
  577.    * addrtostr([127, 0, 0, 0]) -> "127.0.0.0"
  578.    *
  579.    */
  580.   define addrtostr(any ip) ``{ 
  581.     if (ip == nil) return "";
  582.     if (ip == []) return "";
  583.     return sformat("%1.%2.%3.%4", select(ip, 0), select(ip, 1), select(ip, 2), select(ip, 3));
  584.   };
  585.  
  586.   /*
  587.    * Convert integer into list of eight boolean
  588.    *
  589.    */
  590.   define inttobyte(integer i) ``{
  591.       
  592.     if ((i < 0) || (i > 255)) return [0];
  593.       
  594.     list y = [];
  595.       
  596.     do {
  597.       
  598.       y = add(y, i%2 == 1);
  599.       i = i / 2;
  600.       
  601.     } while (i > 0);
  602.       
  603.     return y;
  604.   };
  605.  
  606.   /*
  607.    * Convert list of boolean to integer 
  608.    *
  609.    */
  610.   define bytetoint(list a) ``{
  611.       
  612.     integer i = size(a) - 1;
  613.     integer x = 0;
  614.       
  615.     while (i >= 0) {
  616.       x = x * 2;
  617.       if (select(a, i)) x = x + 1;
  618.       i = i - 1;
  619.     }
  620.       
  621.     return x;
  622.       
  623.   };
  624.  
  625.   /*
  626.    * Logical 'and' on boolean elements of lists
  627.    *
  628.    */
  629.   define and(list a, list b) ``{
  630.       
  631.     list c = [];
  632.     integer no = 0;
  633.     integer i = 0;
  634.       
  635.     if (size(a) < size(b)) no = size(a);
  636.     else no = size(b);
  637.       
  638.     while (i < no) {    
  639.       c = add (c, select (a, i) && select(b, i));
  640.       i = i + 1;
  641.     }
  642.       
  643.     return c;
  644.       
  645.   };
  646.  
  647.   /*
  648.    * Logical 'or' on boolean elements of lists
  649.    *
  650.    */  
  651.   define or(list a, list b) ``{
  652.       
  653.     list c = [];
  654.     integer no = 0;
  655.     integer i = size(a) - size(b);
  656.       
  657.     while (i < 0) {
  658.       a = add(a, false);
  659.       i = i + 1;
  660.     }
  661.       
  662.     while (i > 0) {
  663.       b = add(b, false);
  664.       i = i - 1;
  665.     }
  666.       
  667.     no = size(a);
  668.       
  669.     while (i < no) {
  670.       c = add (c, select (a, i) || select(b, i));
  671.       i = i + 1;
  672.     }
  673.       
  674.     return c;
  675.       
  676.   };
  677.   
  678.   /*
  679.    * Logical 'not' on eight boolean element of list
  680.    *
  681.    */
  682.   define not(list a) ``{
  683.       
  684.     list b = [];
  685.     integer no = size(a);
  686.     integer i = 8 - size(a);
  687.       
  688.     while (i > 0) {
  689.       a = add(a, false);
  690.       i = i - 1;
  691.     }
  692.       
  693.     i = 0;
  694.       
  695.     while (i < 8) {
  696.       b = add (b, ! select (a, i));
  697.       i = i + 1;
  698.     }
  699.       
  700.     return b;
  701.       
  702.   };
  703.   
  704.   /*
  705.    * Compute broadcast from ip and mask
  706.    *
  707.    */
  708.   define getbcast(list ip, list mask) ``{
  709.       
  710.     if (ip == []) return [];
  711.     if (mask == []) return [255, 255, 255, 255];   // the same as mask = [0, 0, 0, 0]
  712.  
  713.     integer i = 0;
  714.     list bcast = [];
  715.       
  716.     while (i < 4) {
  717.       bcast = add(
  718.           bcast, 
  719.           bytetoint(
  720.                 or(
  721.                    inttobyte(select(ip, i)),
  722.                    not(inttobyte(select(mask, i)))
  723.                    )
  724.                 )
  725.           );
  726.       i = i + 1;
  727.     }
  728.       
  729.     return bcast;
  730.   };
  731.   
  732.   /*
  733.    * Compute network address  from ip and mask
  734.    *
  735.    */
  736.   define getnet (list ip, list mask) ``{
  737.       
  738.     if (ip == []) return [];
  739.     if (mask == []) return ip;   // the same as mask = [0, 0, 0, 0]
  740.     
  741.     integer i = 0;
  742.     list net = [];
  743.  
  744.     while (i < 4) {
  745.       net = add(
  746.         net, 
  747.         bytetoint(
  748.               and(
  749.                   inttobyte(select(ip, i)),
  750.                   inttobyte(select(mask, i))
  751.                   )
  752.               )
  753.         );
  754.       i = i + 1;
  755.     }
  756.       
  757.     return net;
  758.   };
  759.  
  760.   /*
  761.    * Check syntax of hostname entry
  762.    *
  763.    */
  764.   define chkhost(string str) ``{
  765.     if (str == "") return false;
  766.     if (findfirstnotof(str, "_0123456789abcdefghijklmnopqrstuvwxyz-") != nil) return false;
  767.     return true;
  768.   };
  769.  
  770.   /*
  771.    * Check syntax of domain entry
  772.    *
  773.    */
  774.   define chkdomain(string str) ``{
  775.     if (str == "") return false;
  776.     if (findfirstnotof(str, "._0123456789abcdefghijklmnopqrstuvwxyz-") != nil) return false;
  777.     return true;
  778.   };   
  779.  
  780.   /*
  781.    * Parse options line from modules.conf to get module argument
  782.    * 
  783.    * "options ne irq=5 io=0x240" -> ["irq=5", "io=0x240"]
  784.    *
  785.    */
  786.   define getargs(string s) ``{
  787.     list result = [];
  788.     list l = split(s, "\n");
  789.     if (l != []) {
  790.       l = split(select(l, 0), " \t");
  791.       if (l != []) {
  792.     integer i = 0;
  793.     if (select(l, 0) == "options") i = 2;
  794.     while (i < size(l)) {
  795.       result = add(result, select(l, i));
  796.       i = i + 1;
  797.     }
  798.       }
  799.     }
  800.     return result;
  801.   };
  802.  
  803.   /*
  804.    * Try to load module if it is not already loaded
  805.    *
  806.    * If there are paramerets for loading modules in .probe, the parameters 
  807.    * are saved to the new temporary modules.conf used for modprobe.
  808.    * There are two ways to get the parameters, from "conf" or "args".
  809.    *
  810.    * variables: 
  811.    *   string mod_name - kernel module name string  (eg. "ne")
  812.    *   string mod_conf - modules.conf line          (eg. "options ne irq=5 io=0x240")
  813.    *   list   mod_args - parsed mod_conf            (eg. ["irq=5", "io=0x240"])
  814.    *
  815.    * args: line from SCR(`Read(.probe.byclass.network)
  816.    *
  817.    */
  818.   define ModuleProbe (map card) ``{
  819.       
  820.     map module = lookup (card, "module");
  821.  
  822.     mod_name         = lookup (module, "name");
  823.     mod_conf         = lookup (module, "conf", "");
  824.     mod_args         = [];
  825.  
  826.     boolean active   = lookup (module, "active", true);
  827.     boolean modprobe = lookup (module, "modprobe", true);
  828.  
  829.     string tmpfile = "/etc/modules.conf.tmp";
  830.     string param = mod_name;
  831.  
  832.     // fix bug in libhd for isapnp card
  833.     if (mod_conf == "(null)\n") mod_conf = "";
  834.     if (mod_args != "(null)\n") 
  835.       mod_args = split(lookup (module, "args", ""), " \t");
  836.  
  837.     // parse "conf" or "args"
  838.     if (mod_conf == "") {
  839.       if (mod_args != [])
  840.     mod_conf = sformat("options %1\t\t%2\n", mod_name, join(mod_args, " "));
  841.     } else {
  842.       mod_args = getargs(mod_conf);
  843.       if (substring(mod_conf, 0, 7) != "options") 
  844.     mod_conf = sformat("options %1 %2", mod_name, mod_conf);
  845.     }
  846.  
  847.     // save temporary modules.conf
  848.     if (mod_conf != "") {
  849.       
  850.       any a = SCR(`Read(.run.mktemp));
  851.       if ((a != nil) && (a != "")) tmpfile = a;
  852.       if (!WriteString(tmpfile, getmodulesconf() + "\n" + mod_conf)) {
  853.     // warning dialog message
  854.     UI(`DisplayMessage(_("Cannot create temporary file"), 0, tmpfile));
  855.     return false;
  856.       }
  857.  
  858.       param = param + " -C " + tmpfile;
  859.  
  860.     }
  861.  
  862.     // kernel module loading
  863.     if (active == false) {
  864.  
  865.       integer code = Shell("/sbin/modprobe -s " + param);
  866.  
  867.       if (code != 0) {
  868.     // warning dialog message
  869.     UI(`DisplayMessage(_("Device initialization failed"), 
  870.                code, 
  871.                // kernel module name in warning dialog
  872.                sformat(UI(_("Module name %1")), mod_name)));
  873.     return false;
  874.       }
  875.     
  876.       Shell("/sbin/modprobe -r " + param);
  877.     }
  878.           
  879.     Shell("/bin/rm -f " + tmpfile);
  880.  
  881.     return true;
  882.       
  883.   };
  884.  
  885.   /*
  886.    * The fist dialog - Network card autodetection
  887.    *
  888.    * Read network card from SCR(`Read(.probe.byclass.network)). 
  889.    * If there are more network cards the list with radio buttons 
  890.    * are displayed.
  891.    *
  892.    * variables:
  893.    *   integer card_id   - line number from .probe
  894.    *   string  card_name - card description name
  895.    *
  896.    */
  897.   define FindCard (any result) ``{
  898.  
  899.     // label for waiting while yast2 is checking hardware
  900.     string msg = UI(_("Looking for network cards on your system..."));
  901.  
  902.     // help text for autodetecting and network card selecting
  903.     // part 1 of 2
  904.     string helptext = UI(_("<p>YaST2 autodetects <b>network cards</b> installed in your system.</p>"));
  905.  
  906.     // part 2 of 2
  907.     helptext = helptext + UI(_("<p>
  908. If you have more than one network card, select which one you want to 
  909. configure. Click <b>next</b> button to continue with network configuration.
  910. </p>"));
  911.  
  912.     term con = `Label (msg);
  913.  
  914.     // main dialog label
  915.     UI(`SetContents (_("Network configuration"), con, helptext, false, false));
  916.       
  917.     list cards = [];
  918.     any a = SCR(`Read(.probe.byclass.network));    
  919.     if (a != nil) cards = a;
  920.  
  921.     // filter out unknowen devices
  922.     cards = filter(`c, cards, ``(lookup(c, "module") != nil));
  923.     if (size(cards) == 0) {
  924.       if (has_pcmcia) {
  925.       // result of autodetection
  926.     con = `Label (_("No built-in network card was detected. However a PCMCIA\ndevice was found which can be used with a PCMCIA network\ncard. Press 'Next' to continue configuration for PCMCIA\nnetwork. Pressing 'Back' will cancel network configuration."));
  927.       } else {
  928.     // result of autodetection
  929.     con = `Label (_("No network card was detected."));
  930.     //             `Bottom (`PushButton (`id (`manual), `opt(`disabled), _("Manual")))
  931.       }
  932.       
  933.       UI(`SetContents (_("Network configuration"), con, helptext, true, true));
  934.       UI(`UserInput ());
  935.       if (has_pcmcia) {
  936.     card_is_pcmcia = true;
  937.     return `next;
  938.       }
  939.       else
  940.     return `back;
  941.     }
  942.  
  943.     if (size(cards) == 1) {
  944.     
  945.       // result of autodetection
  946.       // only one network card was detected and will be configured
  947.       con = `Label (sformat(UI(_("The network card\n\n%1\n\nwill be configured for network access.")),
  948.                 name_of_device(select(cards, 0))));
  949.       UI(`SetContents (_("Network configuration"), con, helptext, true, true));
  950.       result = UI(`UserInput ());
  951.       if (result == `next) {
  952.     ModuleProbe(select(cards, id));
  953.     card_id = 0;
  954.     card_name = name_of_device(select(cards, id));
  955.       }
  956.  
  957.       return result;    
  958.  
  959.     }
  960.  
  961.     term t = `VBox();
  962.     integer i = 0;
  963.     integer id = card_id;
  964.  
  965.  
  966.     // compare module items from .probe with module parameters 
  967.     // from modules.conf to get which card is previousely used
  968.     if (id >= size(cards)) id = -1;
  969.  
  970.     while (i < size(cards)) {
  971.  
  972.       if (id < 0) {
  973.     map m = lookup(select(cards, i), "module", $[]);
  974.     if (mod_name == (lookup(m, "name", ""))) {
  975.       list l = [];
  976.       if (lookup(m, "conf") == nil)
  977.         if (lookup(m, "args") == nil)
  978.           l = [];
  979.         else
  980.           l = split(lookup(m, "args", ""), " \t\n");
  981.       else
  982.         l = getargs(lookup(m, "conf"));
  983.       if (sort(mod_args) == sort(l))
  984.         id = i;
  985.     }
  986.       }
  987.  
  988.       t = add (t, `Left(`RadioButton(`id(i), `opt(`notify), name_of_device(select(cards, i)), id == i)));
  989.       i = i + 1;
  990.     }
  991.  
  992.     con = `VBox (
  993.          // result of autodetection
  994.          // more network cards were detected and radio button group is displayed
  995.          `Label (_("Please choose the network card you want to configure")),
  996.          `HSquash (`RadioButtonGroup (`id(`rb), t))
  997.          );
  998.  
  999.     UI(`SetContents (_("Network configuration"), con, helptext, true, id >= 0));
  1000.  
  1001.  
  1002.     // one card must be selected
  1003.     do {
  1004.       
  1005.       result =  UI(`UserInput ());
  1006.       if (!is(result, integer)) break;
  1007.       if (UI(`QueryWidget(`id(`rb), `CurrentButton) != nil))
  1008.     UI(`ChangeWidget(`id(`next), `Enabled, true));
  1009.  
  1010.     } while (true);
  1011.     
  1012.     if (result == `next) {
  1013.       id = UI(`QueryWidget(`id(`rb), `CurrentButton));
  1014.       ModuleProbe(select(cards, id));
  1015.       card_id   = id;
  1016.       card_name = name_of_device(select(cards, id));
  1017.     }
  1018.     return result;
  1019.       
  1020.   };
  1021.  
  1022.   /*
  1023.    * Address setup dialog
  1024.    *
  1025.    * read and modify global variables:
  1026.    *
  1027.    *    boolean dhcp
  1028.    *    list    ip
  1029.    *    list    mask
  1030.    *    list    gateway
  1031.    *    string  ifconfig
  1032.    *    string  dhcommand
  1033.    *
  1034.    */
  1035.   define AddressSetup(any result) ``{
  1036.  
  1037.     //    if (result == `back) return result;
  1038.  
  1039.     string msg = "OK";
  1040.  
  1041.     // help text for ip address setup dialog
  1042.     // part 1 of 2
  1043.     string helptext = UI(_("<p>This dialog provides IP address configuration.</p>"));
  1044.  
  1045.     // help text for ip address setup dialog
  1046.     // part 2 of 2
  1047.     helptext = helptext + UI(_("<p>You can select dynamic address assignment
  1048. if you have a <b>DHCP server</b> running on your local network. You also
  1049. should select this if you do not have a static IP address assigned to you by your cable or DSL provider. Network addresses will then be obtained <b>automatically</b> from the server. Configuration will be <b>finished</b> by clicking the 
  1050. <b>next</b> button.</p>
  1051. <p>Otherwise, you must assign the network addresses <b>manually</b>. Enter
  1052. the IP address (e.g., 192.168.100.99) for your computer, the network mask
  1053. (usually 255.255.255.0) and, optionally, the default gateway IP address. The
  1054. name server setup dialog follows.</p>
  1055. "));
  1056.  
  1057.     helptext = helptext + UI(_("<p>Please contact your <b>network administrator</b> for more information about the network configuration.</p>"));
  1058.  
  1059.     boolean dhcptmp = dhcp;
  1060.  
  1061.     list iptmp    = ip;
  1062.     list masktmp  = mask;
  1063.     list gwtmp    = gateway;
  1064.     list nettmp   = [];
  1065.     list bcasttmp = [];
  1066.  
  1067.     string ipstr = "";
  1068.     string maskstr = "";
  1069.     string gwstr = "";
  1070.  
  1071.     if (ip != []) ipstr = addrtostr(ip);
  1072.     if (mask != []) maskstr = addrtostr(mask);
  1073.     if (gateway != []) gwstr = addrtostr(gateway);
  1074.  
  1075.     if ((ipstr == "") && (maskstr == "")) maskstr = "255.255.255.0";
  1076.  
  1077.     // label for radio button group (dynamic/static ip address setup method)
  1078.     term label = `Label (_("Choose the network address setup method"));
  1079.  
  1080.     // frame label
  1081.     term frame1 = `Frame (_("Dynamic address"),
  1082.               `Left (`RadioButton (`id(true),
  1083.                            `opt(`notify),
  1084.                            // radio button label
  1085.                            _("Automatic address setup (via DHCP)"),
  1086.                            dhcptmp == true))
  1087.               );
  1088.       
  1089.     // frame label
  1090.     term frame2 = `Frame (_("Static address"),
  1091.               `VBox (
  1092.                  // radio button label
  1093.                  `Left (`RadioButton (`id(false), `opt(`notify), _("Static address setup"), dhcptmp == false)),
  1094.                  `HSquash (
  1095.                        `VBox (
  1096.                           // text entry label for ip address
  1097.                           `TextEntry (`id(`ip), _("IP Address"), ipstr),
  1098.                           // text entry label for network mask
  1099.                           `TextEntry (`id(`mask), _("Subnet mask"), maskstr),
  1100.                           // text entry label
  1101.                           `TextEntry (`id(`gw), _("Default gateway"), gwstr)
  1102.                           )
  1103.                        )
  1104.                  )
  1105.  
  1106.               );
  1107.  
  1108.  
  1109.     term t = `RadioButtonGroup (`id(`rb),
  1110.                 `HSquash (
  1111.                       `VBox (
  1112.                          frame1,
  1113.                          frame2
  1114.                          )
  1115.                       )
  1116.                 );
  1117.  
  1118.     // main dialog label
  1119.     UI(`SetContents (_("Network address setup"), t, helptext, true, true));
  1120.     UI(`ChangeWidget(`id(`ip),   `Enabled, !dhcptmp));
  1121.     UI(`ChangeWidget(`id(`mask), `Enabled, !dhcptmp));
  1122.     UI(`ChangeWidget(`id(`gw),   `Enabled, !dhcptmp));
  1123.  
  1124.     // loop for values checking
  1125.  
  1126.     do {    
  1127.       
  1128.       result = UI(`UserInput ());
  1129.       while (is(result, boolean)) {
  1130.     UI(`ChangeWidget(`id(`ip),   `Enabled, !result));
  1131.     UI(`ChangeWidget(`id(`mask), `Enabled, !result));
  1132.     UI(`ChangeWidget(`id(`gw),   `Enabled, !result));
  1133.     result = UI(`UserInput ());
  1134.       }
  1135.       
  1136.       dhcptmp = UI(`QueryWidget(`id(`rb),   `CurrentButton));
  1137.       ipstr   = UI(`QueryWidget(`id(`ip),   `Value));
  1138.       maskstr = UI(`QueryWidget(`id(`mask), `Value));
  1139.       gwstr   = UI(`QueryWidget(`id(`gw),   `Value));
  1140.  
  1141.       iptmp   = strtoaddr(ipstr);
  1142.       masktmp = strtoaddr(maskstr);
  1143.       gwtmp   = strtoaddr(gwstr);
  1144.     
  1145.       msg = "OK";
  1146.  
  1147.       if (result == `next) {
  1148.  
  1149.     if (dhcptmp) {
  1150.           
  1151.       if (dhcommand == "" ) {
  1152.         // warning dialog message
  1153.         msg = UI(_("You need to install the dhclient or dhcpcd package for dynamic IP address 
  1154. setup."));
  1155.  
  1156.         dhcptmp = false;
  1157.         
  1158.         UI(`ChangeWidget(`id(`ip),   `Enabled, !dhcptmp));
  1159.         UI(`ChangeWidget(`id(`mask), `Enabled, !dhcptmp));
  1160.         UI(`ChangeWidget(`id(`gw),   `Enabled, !dhcptmp));
  1161.         UI(`ChangeWidget(`id(`rb), `CurrentButton, dhcptmp));
  1162.         UI(`PollInput());
  1163.  
  1164.       }
  1165.           
  1166.     } else {
  1167.       
  1168.       if ((iptmp != []) && (masktmp != [])) {
  1169.         
  1170.         nettmp   = getnet(iptmp, masktmp);
  1171.         bcasttmp = getbcast(iptmp, masktmp);
  1172.         
  1173.         if (gwtmp != [])
  1174.           if ((getnet(gwtmp, masktmp) != nettmp) || (gwtmp == nettmp) || (gwtmp == bcasttmp))
  1175.         // warning dialog message
  1176.         // gateway address must be accessible from subnet
  1177.         msg = UI(_("Default gateway address is out of range"));
  1178.         
  1179.         if ((iptmp == nettmp) || (iptmp == bcasttmp))
  1180.           // warning dialog message
  1181.           // ip address overlaps network or broadcast address
  1182.           msg = UI(_("IP Address is out of range"));
  1183.       }
  1184.       
  1185.       if ((gwstr != "") && (gwtmp == []))
  1186.         // warning dialog message
  1187.         msg = UI(_("The default gateway is not correct"));
  1188.       
  1189.       if (masktmp == [])
  1190.         msg = UI(_("The subnet mask is not correct"));
  1191.           
  1192.       if (iptmp == [])
  1193.         msg = UI(_("The IP address is not correct"));
  1194.     }
  1195.       }
  1196.  
  1197.       if (msg == "OK") break;
  1198.  
  1199.       UI(`DisplayMessage(msg, 0, ""));
  1200.  
  1201.     } while (true);
  1202.  
  1203.     if (result == `next) {
  1204.     
  1205.       dhcp = dhcptmp;
  1206.  
  1207.       if (dhcp) {
  1208.  
  1209.     ifconfig = "dhcpclient";
  1210.  
  1211.       } else {
  1212.  
  1213.     ifconfig = sformat("%1 broadcast %2 netmask %3", 
  1214.                addrtostr(iptmp), 
  1215.                addrtostr(bcasttmp), 
  1216.                addrtostr(masktmp));
  1217.     ip      = iptmp;
  1218.     mask    = masktmp;
  1219.     gateway = gwtmp;        
  1220.  
  1221.       }
  1222.  
  1223.     }
  1224.  
  1225.     return result;
  1226.  
  1227.   };
  1228.  
  1229.   /*
  1230.    * Check network address for conflict with other interfaces.
  1231.    * User can correct ip address and mask of your configuration
  1232.    * or disable conflicted devices.
  1233.    * 
  1234.    * use global variable
  1235.    *    map ifs - all configurated interfaces provided  by rc.config
  1236.    * 
  1237.    * set global variable
  1238.    *    list cdev - interfaces in conflict. 
  1239.    *                they should be deactivate by NETCONFIG(_PCMCIA) value 
  1240.    *
  1241.    */
  1242.   define CheckInterfaces(any result) ``{
  1243.  
  1244.     cdev = [];
  1245.  
  1246.     if (dhcp) return result;
  1247.     if (result != `next) return result;
  1248.     
  1249.     term con = `VBox(`Empty ());
  1250.     boolean active = false;
  1251.  
  1252.     maplist(`k, `v, ifs, ``{
  1253.       if ((lookup(v, "dev") != "eth0") && (lookup(v, "addr") != []))
  1254.     if ((getnet(ip, mask)              == getnet(lookup(v, "addr"), mask)) ||
  1255.         (getnet(ip, lookup(v, "mask")) == lookup(v, "net"))) {
  1256.  
  1257.       cdev = add(cdev, k);
  1258.       if (lookup(v, "active")) active = true;
  1259.       con = add(con, `Left(`HBox (`CheckBox (`id(k), `opt(`disabled), "", lookup(v, "active")),
  1260.                       `Label (sformat("%1 [%2/%3]",
  1261.                               lookup(v, "dev"),
  1262.                               addrtostr(lookup(v, "addr")),
  1263.                               addrtostr(lookup(v, "mask")))))));
  1264.     }
  1265.     });
  1266.  
  1267.     if (!active) return `next;
  1268.  
  1269.     // help text
  1270.     // address conflict setup dialog
  1271.     // part 1 of 3
  1272.     string helptext = UI(_("<p>
  1273. One or more previously configured devices (such as a second network card or
  1274. ISDN adapter) were found in your system. Some of them have been assigned a
  1275. network address range (IP address/network mask) which <b>conflicts</b>
  1276. with your new configuration. It is <b>not possible</b> to use more
  1277. devices with <b>overlapping</b> network address.
  1278. </p>
  1279. "));
  1280.     // help text
  1281.     // address conflict setup dialog
  1282.     // part 2 of 3
  1283.     helptext = helptext + UI(_("<p>
  1284. This dialog displays a list of all incorrectly configured devices. A checked
  1285. line in the list means that device is <b>active</b>.
  1286. <p>
  1287. "));
  1288.     // help text
  1289.     // address conflict setup dialog
  1290.     // part 3 of 3
  1291.     helptext = helptext + UI(_("<p>
  1292. You can select <b>next</b> and the incorrectly configured devices will be
  1293. <b>deactivated</b>
  1294. and <b>disabled</b>. You will not be able to use them but you can
  1295. reconfigure them later. Configuration will be <b>continued</b>.
  1296. </p>
  1297. <p>
  1298. Or you can select <b>back</b> to go back to the address setup dialog and
  1299. <b>replace</b> any required IP address and network masks.
  1300. </p>
  1301. "));
  1302.  
  1303.     con = `VBox (
  1304.          // main dialog label
  1305.          // list of already configured network interfaces 
  1306.          // ([eth1, eth2...], [isdn0, isdn1...] etc.) with
  1307.          // network address (ip/mask) which overlaps address 
  1308.          // defined by user
  1309.          `Label (_("Conflicting network devices")),
  1310.          `HSquash (con)
  1311.          );
  1312.  
  1313.     UI(`SetContents (_("Network configuration"), con, helptext, true, true));
  1314.  
  1315.     result = UI(`UserInput ());
  1316.  
  1317.     return result;
  1318.  
  1319.   };
  1320.  
  1321.  
  1322.   /*
  1323.    * DNS setup dialog
  1324.    *
  1325.    * read and modify global variables:
  1326.    *
  1327.    *    string host
  1328.    *    string domain
  1329.    *    list   nameserver
  1330.    *    list   searchlist
  1331.    *
  1332.    */
  1333.   define DNSSetup(any result) `` {
  1334.  
  1335.     if (dhcp) return result;
  1336.  
  1337.     string msg = "OK";
  1338.     // help text for dns setup
  1339.     // part 1 of 4
  1340.     string helptext = UI(_("<p>Insert the host name and domain name for your computer. Name server list and domain search list are optional.</p>
  1341. "));
  1342.  
  1343.     // help text for dns setup
  1344.     // part 2 of 4
  1345.     helptext = helptext + UI(_("<p>A name server is a computer which translates host names into IP 
  1346. addresses. This value must be entered as an <b>IP address</b> (e.g., 
  1347. 10.10.0.1), not as a host name.</p>
  1348. "));
  1349.  
  1350.     // help text for dns setup
  1351.     // part 3 of 4
  1352.     helptext = helptext + UI(_("<p>Search domain is the domain name where host name searching is started. 
  1353. The primary search domain is usually the same as the <b>domain name</b> of 
  1354. your computer (e.g., suse.de). There may be additional search domains (e.g., 
  1355. suse.com).</p>
  1356. "));
  1357.  
  1358.     // help text for dns setup
  1359.     // part 4 of 4
  1360.     helptext = helptext + UI(_("<p>Select the <b>next</b> button to <b>save</b> your changes and <b>finish</b> the network configuration."));
  1361.  
  1362.     // reading from global variables
  1363.     string hoststr   = host;
  1364.     string domainstr = domain;
  1365.  
  1366.     // domain search default dialog strings
  1367.     string s1 = "";
  1368.     string s2 = "";
  1369.     string s3 = "";
  1370.  
  1371.     // name server default dialog strings
  1372.     string nstr1 = "";
  1373.     string nstr2 = "";
  1374.     string nstr3 = "";
  1375.     
  1376.     // name server ip address
  1377.     list ns1 = [];
  1378.     list ns2 = [];
  1379.     list ns3 = [];
  1380.  
  1381.     integer i = size(nameserver);
  1382.  
  1383.     if (i > 0) nstr1 = addrtostr(select(nameserver, 0));
  1384.     if (i > 1) nstr2 = addrtostr(select(nameserver, 1));
  1385.     if (i > 2) nstr3 = addrtostr(select(nameserver, 2));
  1386.  
  1387.     i = size(searchlist);
  1388.  
  1389.     if (i > 0) s1 = select(searchlist, 0);
  1390.     if (i > 1) s2 = select(searchlist, 1);
  1391.     if (i > 2) s3 = select(searchlist, 2);
  1392.  
  1393.     term t = `HSquash (
  1394.                `VBox (
  1395.                   `HBox (
  1396.                      // text entry label
  1397.                      `TextEntry(`id(`host), _("Host name"), hoststr),
  1398.                      // text entry label
  1399.                      `TextEntry(`id(`domain), _("Domain name"), domainstr)
  1400.                      ),
  1401.                   `HBox(
  1402.                     `Frame (
  1403.                         // common label for more text entries
  1404.                         _("Name server list"),
  1405.                         `VBox (
  1406.                            `TextEntry (`id(`ns1), "", nstr1),
  1407.                            `TextEntry (`id(`ns2), "", nstr2),
  1408.                            `TextEntry (`id(`ns3), "", nstr3)
  1409.                            )
  1410.                         ),
  1411.                     `Frame (
  1412.                         // common label for more text entries
  1413.                         _("Domain search list"),
  1414.                         
  1415.                         `VBox (
  1416.                            `TextEntry (`id(`s1), "", s1),
  1417.                            `TextEntry (`id(`s2), "", s2),
  1418.                            `TextEntry (`id(`s3), "", s3)
  1419.                            )
  1420.                         )
  1421.                     )
  1422.                   ));
  1423.     
  1424.             
  1425.     // main dialog label
  1426.     UI(`SetContents (_("Name server configuration"), t, helptext, true, true));
  1427.  
  1428.     do {
  1429.     
  1430.       result = UI(`UserInput ());
  1431.  
  1432.       hoststr   = tolower(UI(`QueryWidget(`id(`host), `Value)));
  1433.       domainstr = tolower(UI(`QueryWidget(`id(`domain), `Value)));
  1434.  
  1435.       nstr1 = UI(`QueryWidget(`id(`ns1), `Value));
  1436.       nstr2 = UI(`QueryWidget(`id(`ns2), `Value));
  1437.       nstr3 = UI(`QueryWidget(`id(`ns3), `Value));
  1438.            
  1439.       ns1 = strtoaddr(UI(nstr1));
  1440.       ns2 = strtoaddr(UI(nstr2));
  1441.       ns3 = strtoaddr(UI(nstr3));
  1442.  
  1443.       s1 = tolower(UI(`QueryWidget(`id(`s1), `Value)));
  1444.       s2 = tolower(UI(`QueryWidget(`id(`s2), `Value)));
  1445.       s3 = tolower(UI(`QueryWidget(`id(`s3), `Value)));
  1446.  
  1447.       msg = "OK";
  1448.  
  1449.       if (result == `next) {
  1450.  
  1451.     if (!((s3 == "") || chkdomain(s3)))
  1452.       msg = UI(_("The tertiary search domain is not correct"));
  1453.       
  1454.     if (!((s2 == "") || chkdomain(s2)))
  1455.       msg = UI(_("The secondary search domain is not correct"));
  1456.  
  1457.     if (!((s1 == "") || chkdomain(s1)))
  1458.       msg = UI(_("The primary search domain is not correct"));
  1459.       
  1460.     if ((nstr3 != "") && (ns3 == []))
  1461.       msg = UI(_("The tertiary nameserver is not correct"));
  1462.  
  1463.     if ((nstr2 != "") && (ns2 == []))
  1464.       msg = UI(_("The secondary nameserver is not correct"));
  1465.             
  1466.     if ((nstr1 != "") && (ns1 == []))
  1467.       msg = UI(_("The primary nameserver is not correct"));
  1468.  
  1469.     if (!chkdomain(domainstr))
  1470.       msg = UI(_("The domain name is not correct"));
  1471.       
  1472.     if (!chkhost(hoststr))
  1473.       msg = UI(_("The host name is not correct"));
  1474.       }
  1475.  
  1476.       if (msg != "OK")
  1477.     UI(`DisplayMessage(msg, 0, ""));
  1478.     
  1479.     } while (msg != "OK");
  1480.  
  1481.     
  1482.     if (result == `next) {
  1483.     
  1484.       host = hoststr;
  1485.       domain = domainstr;
  1486.  
  1487.       nameserver = [];
  1488.       if (ns1 != []) nameserver = add(nameserver, ns1);
  1489.       if (ns2 != []) nameserver = add(nameserver, ns2);
  1490.       if (ns3 != []) nameserver = add(nameserver, ns3);
  1491.     
  1492.       searchlist = [];
  1493.       if (s1 != []) searchlist = add(searchlist, s1);
  1494.       if (s2 != []) searchlist = add(searchlist, s2);
  1495.       if (s3 != []) searchlist = add(searchlist, s3);
  1496.     
  1497.     }
  1498.  
  1499.     return result;
  1500.     
  1501.   };
  1502.  
  1503.   /*
  1504.    * Configuration testing
  1505.    *
  1506.    */  
  1507.   define TestConfig (string device) ``{
  1508.  
  1509.     Shell(sformat("/sbin/ifconfig %1 down", device));
  1510.  
  1511.     if (dhcp) {
  1512.     
  1513.       Shell(sformat("/sbin/ifconfig %1 0.0.0.0 up", device));
  1514.       Shell(sformat("/sbin/route add -host 255.255.255.255 dev %1", device));
  1515.       Shell(sformat("%1 %2", dhcommand, device));
  1516.  
  1517.     } else {
  1518.  
  1519.       Shell(sformat("/sbin/ifconfig %1 %2", device, ifconfig));
  1520.       if (gateway != [])
  1521.     Shell(sformat("/sbin/route add default gw %1", addrtostr(gateway)));
  1522.       
  1523.     }
  1524.  
  1525.     Shell(sformat("/sbin/ifconfig %1 down", device));
  1526.  
  1527.   };
  1528.  
  1529.   /*
  1530.    * Read configuration and fill up global variables
  1531.    *
  1532.    * global variables: dhcommand
  1533.    *
  1534.    * file: /etc/modules.conf
  1535.    * global variables: modulesconf
  1536.    *
  1537.    * file: /etc/rc.config
  1538.    * global variables: 
  1539.    *   list netconfig  - NETCONFIG value from rc.config (integers)
  1540.    *   list netconfig_pcmcia  - NETCONFIG_PCMCIA value from rc.config (integers)
  1541.    *   bolean dhcp     - DHCLIENT  value
  1542.    *   list ip         - IPADDR_ value (eg. [10,10,0,1])
  1543.    *   list mask       - netmask used by IFCONFIG_ value (eg. [255,255,255,0])
  1544.    *   list nameserver - NAMESERVER value (eg. [[10,10,0,1],[10,10,10,1]]
  1545.    *   list searchlist - SEARCHLIST value (eg. [["suse.de"],["suse.cz"]]) 
  1546.    *   map ifs         - NETCONFIG(_PCMCIA) and all IFCONFIG_ values
  1547.    *       eg. $[
  1548.    *             0:$["active":false, "addr":[10, 10, 0, 1], "bcast":[10, 10, 10, 255], "dev":"eth1", "mask":[255, 255, 255, 0], "net":[10, 10, 0, 0]], 
  1549.    *             1:$["active":true, "addr":[10, 10, 10, 1], "bcast":[10, 10, 10, 255], "dev":"isdn0", "mask":[255, 255, 255, 0], "net":[10, 10, 10, 0]], 
  1550.    *             2:$["active":false, "addr":[], "bcast":[], "dev":"eth0", "mask":[], "net":[]]
  1551.    *            ]
  1552.    *
  1553.    * file /etc/route.conf
  1554.    * global variables: 
  1555.    *   list gateway - (eg. [10,10,0,8])
  1556.    *
  1557.    * 
  1558.    */
  1559.   define ReadConfig () ``{
  1560.  
  1561.  
  1562.     mod_name = "";
  1563.     mod_name_old = "";
  1564.     mod_args = [];
  1565.  
  1566.     // reading from /etc/modules.conf
  1567.     any a = SCR(`Read(.etc.modulesconf.read));
  1568.     if (a != nil) modulesconf = a;
  1569.     
  1570.     maplist(`r, modulesconf, ``{
  1571.       list l = lookup(r, "alias", []);
  1572.       if (size(l) > 1)
  1573.     if (select(l, 0) == "eth0")
  1574.       mod_name = select(l, 1);
  1575.     });
  1576.     
  1577.     mod_name_old = mod_name;
  1578.     maplist(`r, modulesconf, ``{
  1579.       list l = lookup(r, "options", []);
  1580.       if (size(l) > 1)
  1581.     if (select(l, 0) == mod_name) {
  1582.       mod_args = [];
  1583.       integer i = 1;
  1584.       while (i < size(l)) {
  1585.         mod_args = add(mod_args, select(l, i));
  1586.         i = i + 1;
  1587.       }
  1588.     } 
  1589.       l = lookup(r, "alias", []);
  1590.       if (size(l) > 1)
  1591.     if ((select(l, 1) == mod_name) && (select(l, 0) != "eth0"))
  1592.       mod_name_old = "";
  1593.     });
  1594.  
  1595.     // packages checking
  1596.     if (Shell("rpm -q dhclient") == 0) dhcommand = "/sbin/dhclient";
  1597.     if (Shell("rpm -q dhcpcd")   == 0) dhcommand = "/sbin/dhcpcd";
  1598.  
  1599.     // reading from /etc/rc.config
  1600.     map rcconfig = $[];
  1601.     a = SCR(`Read(.etc.rcconfig.read));
  1602.     if (a != nil) rcconfig = a;
  1603.  
  1604.     netconfig = split(lookup(rcconfig, "NETCONFIG", ""), " _");
  1605.     netconfig = maplist(`s, netconfig, ``tointeger(s));
  1606.     if (has_pcmcia) {
  1607.     netconfig_pcmcia = split(lookup(rcconfig, "NETCONFIG_PCMCIA", ""), " _");
  1608.     netconfig_pcmcia = maplist(`s, netconfig_pcmcia, ``tointeger(s));
  1609.     }
  1610.  
  1611.     ifs = $[];
  1612.     netdev = -1;
  1613.     maplist(`k, `v, rcconfig, ``{
  1614.       if (substring(k, 0, 6) == "NETDEV") {
  1615.     integer i = 0;
  1616.     if (v != "") {
  1617.       
  1618.       i = tointeger(substring(k, 7));
  1619.       
  1620.       if (v == "eth0") netdev = i;
  1621.       
  1622.       map m = $["addr":[], "net":[], "mask":[], "bcast":[]];
  1623.  
  1624.       list l = split(lookup(rcconfig, sformat("IFCONFIG_%1", i), ""), " \t");
  1625.       integer sizel = size(l);
  1626.       
  1627.       if (sizel > 0) {
  1628.         
  1629.         list addr  = strtoaddr(select(l, 0));
  1630.         list mask  = [];
  1631.         list bcast = [];
  1632.  
  1633.         integer i = 1;
  1634.         while (i < sizel) {
  1635.           if (select(l, i) == "netmask") {
  1636.         i = i + 1;
  1637.         if (i < sizel) 
  1638.           mask = strtoaddr(select(l, i));
  1639.           } else {
  1640.         if (select(l, i) == "broadcast") {
  1641.           i = i + 1;
  1642.           if (i < sizel)
  1643.             bcast = strtoaddr(select(l, i));
  1644.         }
  1645.           }
  1646.           i = i + 1;
  1647.         }
  1648.         if ((addr != []) && (mask != [])) {
  1649.           if (bcast == []) bcast = getbcast(addr, mask);
  1650.           m = $["addr":addr, "net":getnet(addr, mask), "mask":mask, "bcast":bcast];
  1651.         }
  1652.       }
  1653.       m = add(m, "dev", v);
  1654.       if (card_is_pcmcia)
  1655.         m = add(m, "active", contains(netconfig_pcmcia, i));
  1656.       else
  1657.         m = add(m, "active", contains(netconfig, i));
  1658.       ifs = add(ifs, i, m);
  1659.     }
  1660.       }
  1661.     });
  1662.  
  1663.     if (netdev < 0) {
  1664.  
  1665.       netdev = 0;
  1666.       while (haskey(ifs, netdev))
  1667.     netdev =  netdev + 1;
  1668.       ifs = add(ifs, netdev, $["dev":"eth0", "active":false, "addr":[], "net":[], "mask":[], "bcast":[]]);
  1669.  
  1670.     } 
  1671.  
  1672.     ip    = lookup(lookup(ifs, netdev), "addr");
  1673.     mask  = lookup(lookup(ifs, netdev), "mask");
  1674.  
  1675.     dhcp = (ip == []) && (dhcommand != "");
  1676.     
  1677.     if (dhcp)
  1678.       ifconfig = "dhcpclient";
  1679.     else
  1680.       ifconfig = sformat("%1 broadcast %2 netmask %3", 
  1681.              addrtostr(ip), 
  1682.              addrtostr(lookup(lookup(ifs, netdev), "bcast")),
  1683.              addrtostr(mask));
  1684.     
  1685.     a = SCR(`Read(.etc.routeconf.read));
  1686.     if (a != nil) gateway = ip4toaddr(lookup(a, "default"));
  1687.  
  1688.     list l = split(lookup(rcconfig, "FQHOSTNAME", ""), ".");
  1689.     
  1690.     if (size(l) > 0) {
  1691.       host = select(l, 0);
  1692.       integer i = 1;
  1693.       while (i < size(l)) {
  1694.     string s = select(l, i);
  1695.     if (s != "") {
  1696.       if (domain != "") domain = domain + ".";
  1697.       domain = domain + s;
  1698.     }
  1699.     i = i + 1;
  1700.       }
  1701.     } else {
  1702.       // default FQHOSTNAME
  1703.       host = "linux";
  1704.       domain = "local";
  1705.     }
  1706.  
  1707.     l = split(lookup(rcconfig, "NAMESERVER", ""), " \t");
  1708.     nameserver = maplist(`s, l, ``strtoaddr(s));
  1709.     searchlist = split(lookup(rcconfig, "SEARCHLIST", "")," \t");
  1710.     
  1711.   };
  1712.   
  1713.   /*
  1714.    * Get host name from DNS
  1715.    *
  1716.    */
  1717.   define gethostbyaddr (list ip) ``{
  1718.     if (ip == []) return "";
  1719.     if (Shell("/usr/bin/nslookup -timeout=1 " + addrtostr(ip) + " > /tmp/nslookup.out") != 0) 
  1720.       return "";
  1721.     any a = SCR(`Read(.tmp.nslookup));
  1722.     if (a == nil) return "";
  1723.     return lookup(a, "name", "");
  1724.   };
  1725.  
  1726.   /*
  1727.    * Convert global list modulesconf to modules.conf format
  1728.    *
  1729.    */
  1730.   define getmodulesconf() ``{
  1731.     
  1732.     string s = "";
  1733.     any a = nil;
  1734.  
  1735.     foreach (`c, modulesconf, ``{
  1736.  
  1737.       if (is(c, map)) {
  1738.     
  1739.     if (c == $[]) s = s + "\n";
  1740.  
  1741.     a = lookup(c, "comment");
  1742.     if (a != nil) s = s + a + "\n";
  1743.           
  1744.     a = lookup(c, "alias");
  1745.     if (a != nil)
  1746.       s = s + sformat("alias %1\n", join(a, " "));
  1747.           
  1748.     a = lookup(c, "options");
  1749.     if (a != nil)
  1750.       s = s + sformat("options %1\n", join(a, " "));
  1751.           
  1752.       } else {
  1753.  
  1754.     s = s + c + "\n";
  1755.  
  1756.       }
  1757.     });
  1758.  
  1759.     a = substring(s, size(s) - 2);
  1760.     if (substring(a, 0, 1) != "\n") s = s + "\n";
  1761.     if (substring(a, 1, 1) != "\n") s = s + "\n";
  1762.  
  1763.     return s;
  1764.   };    
  1765.     
  1766.  
  1767.   /*
  1768.    * Save configuration
  1769.    *
  1770.    * modify /etc/modules.conf, /etc/rc.config
  1771.    *
  1772.    * create /etc/route.conf
  1773.    *
  1774.    * run SuSEconfig to generate /etc/hosts, /etc/host.conf, /etc/resolv.conf
  1775.    *
  1776.    */
  1777.   define SaveConfig () ``{
  1778.  
  1779.     string fqhostname = host + "." + domain;
  1780.     string nameserverstr = join(maplist(`v, nameserver, ``addrtostr(v)), " ");
  1781.     string searchstr = join(searchlist, " ");
  1782.     string dhcpstr = "";
  1783.     string ipstr = "";
  1784.     string gwstr = "";
  1785.  
  1786.  
  1787.     // Add interface to /etc/modules.conf
  1788.  
  1789.     UI(`SetContents (
  1790.              _("Network configuration"),
  1791.              // label for waiting while yast2 is writing
  1792.              `Label (sformat(UI(_("Saving file %1...")), modules_conf)),
  1793.              "", false, false
  1794.              )
  1795.        );
  1796.  
  1797.     modulesconf = filter(`r, modulesconf, ``{
  1798.       list l = lookup(r, "alias", []);
  1799.       if (l != [])
  1800.       if (select(l, 0) == "eth0") return false;
  1801.       l = lookup(r, "options", []);
  1802.       if (l != []) {
  1803.     string s = select(l, 0);
  1804.     if ((s == "eth0") ||
  1805.         (s == mod_name) || 
  1806.         (s == mod_name_old) || 
  1807.         (s == "")) 
  1808.       return false;
  1809.       }
  1810.       if (substring(lookup(r, "comment", ""), 0, 8) == "# YaST2:") return false;
  1811.       return true;
  1812.     });
  1813.  
  1814.     Shell(sformat("/bin/mv -f %1.old %2.old.o", modules_conf, modules_conf));
  1815.     Shell(sformat("/bin/mv -f %1 %2.old", modules_conf, modules_conf));
  1816.  
  1817.     string s = getmodulesconf() + sformat("# YaST2: %1\nalias %2 %3\n%4", card_name, "eth0", mod_name, mod_conf);
  1818.  
  1819.     if (!WriteString(modules_conf, s))
  1820.       // warning dialog message
  1821.       UI(`DisplayMessage(sformat(UI(_("Couldn't write values to %1")), modules_conf), 0, ""));
  1822.  
  1823.     Shell("/sbin/depmod -a -F /boot/System.map-`uname -r` `uname -r`");
  1824.  
  1825.     // rc.config saving
  1826.     UI(`SetContents (
  1827.              _("Network configuration"),
  1828.              `Label (sformat(UI(_("Saving file %1...")), rc_config)),
  1829.              "", false, false
  1830.              )
  1831.        );
  1832.  
  1833.     if (dhcp) {
  1834.       dhcpstr = "yes";
  1835.     } else {
  1836.       dhcpstr = "no";
  1837.       ipstr = addrtostr(ip);
  1838.       if (gateway != []) {
  1839.     gwstr = sformat("default %1\n", addrtostr(gateway));
  1840.       }
  1841.     }
  1842.  
  1843.     map m = $[
  1844.           "FQHOSTNAME": [fqhostname,    "The fully qualfied hostname of this computer. (e.g. \"linux.suse.de\")"],
  1845.           "SEARCHLIST": [searchstr,     "Domain searchlist that should be used in /etc/resolv.conf"],
  1846.           "NAMESERVER": [nameserverstr, "Space separated list of nameservers that should be used for /etc/resolv.conf"],
  1847.  
  1848.           "DHCLIENT": [dhcpstr, "Shall the dynamic host configuration (DHCP) client be started? (\"yes\" or \"no\")"],
  1849.  
  1850.           // "START_LOOPBACK":     ["yes", "Start loopback networking? (\"yes\" or \"no\")"],
  1851.           "CREATE_HOSTCONF":    ["yes", "Should SuSEconfig create and check the /etc/host.conf? (\"yes\" or \"no\")"],
  1852.           "CREATE_RESOLVCONF":  ["yes", "Shall SuSEconfig maintain /etc/resolv.conf (needed for DNS)? (\"yes\" or \"no\")"],
  1853.           "CHECK_ETC_HOSTS":    ["yes", "Should SuSEconfig do some checks and modifications in /etc/hosts? (\"yes\" or \"no\")"],
  1854.           "BEAUTIFY_ETC_HOSTS": ["yes", "Should SuSEconfig sort your /etc/hosts? (\"yes\" or \"no\")"]
  1855.     ];
  1856.  
  1857.     // filter out conflicted and undefined interfaces
  1858.     // move interface to start of NETCONFIG(_PCMCIA) to be started as first device
  1859.     if (card_is_pcmcia) {
  1860.     netconfig_pcmcia = union([netdev],
  1861.               filter(`v,
  1862.                  netconfig_pcmcia,
  1863.                  ``((haskey(ifs, v)) && (!contains(cdev, v)) && (v != netdev))));
  1864.  
  1865.     s = join(maplist(`v, netconfig_pcmcia, ``sformat("_%1", v)), " ");
  1866.  
  1867.     m = add(m, "NETCONFIG_PCMCIA",             [s,        "Number of network devices: \"_0\" for one, \"_0 _1 _2 _3\" for four card"]);
  1868.     }
  1869.     else {
  1870.     netconfig = union([netdev],
  1871.               filter(`v,
  1872.                  netconfig,
  1873.                  ``((haskey(ifs, v)) && (!contains(cdev, v)) && (v != netdev))));
  1874.  
  1875.     s = join(maplist(`v, netconfig, ``sformat("_%1", v)), " ");
  1876.  
  1877.     m = add(m, "NETCONFIG",                    [s,        "Number of network devices: \"_0\" for one, \"_0 _1 _2 _3\" for four card"]);
  1878.     }
  1879.  
  1880.     m = add(m, sformat("IPADDR_%1", netdev),   [ipstr,    "IP Address"]);
  1881.     m = add(m, sformat("NETDEV_%1", netdev),   ["eth0",   "Network device name (e.g. \"eth0\")"]);
  1882.     m = add(m, sformat("IFCONFIG_%1", netdev), [ifconfig, "ifconfig (eg. \"10.10.1.3 broadcast 10.10.1.31 netmask 255.255.255.224\", \"bootp\" or \"dhcpclient\""]);
  1883.  
  1884.     if (!SCR(`Write(.etc.rcconfig, m)))
  1885.       // warning dialog message
  1886.       UI(`DisplayMessage(sformat(UI(_("Couldn't write values to %1")), rc_config), 0, ""));
  1887.  
  1888.     // change ifs to hold consistence with rc.config
  1889.     maplist(`k, cdev, ``{
  1890.       ifs = add(ifs, k, add(lookup(ifs, k), "active", false));
  1891.     });
  1892.     ifs =  add(ifs, netdev, $[
  1893.                   "dev": "eth0",
  1894.                   "addr":ip,
  1895.                   "net":getnet(ip, mask),
  1896.                   "mask":mask,
  1897.                   "bcast":getbcast(ip, mask),
  1898.                   "active":true]);
  1899.       
  1900.     // route.conf saving
  1901.     UI(`SetContents (
  1902.              _("Network configuration"),
  1903.              // label for waiting while yast2 is writing
  1904.              `Label (sformat(UI(_("Saving file %1...")), route_conf)),
  1905.              "", false, false
  1906.              )
  1907.        );
  1908.     
  1909.     Shell(sformat("/bin/mv -f %1.old %2.old.o", route_conf, route_conf));
  1910.     Shell(sformat("/bin/cp -f %1 %2.old", route_conf, route_conf));
  1911.     Shell(sformat("/bin/mv -f %1.old %2.old.o", resolv_conf, resolv_conf));
  1912.     Shell(sformat("/bin/mv -f %1 %2.old", resolv_conf, resolv_conf));
  1913.  
  1914.  
  1915.     if (gwstr != "") {
  1916.       string s = "#
  1917. # /etc/route.conf
  1918. #
  1919. # In this file you can configure your static routing...
  1920. #
  1921. # This file is read by /sbin/init.d/route. 
  1922. #
  1923. #
  1924. # Destination             Dummy/Gateway   Netmask             Device
  1925. #
  1926. # Examples:
  1927. #
  1928. # Net devices
  1929. # 193.141.17.192          0.0.0.0         255.255.255.192     eth0
  1930. #
  1931. # Gateways
  1932. # default                 Riemann
  1933. # 0.0.0.0                 193.141.17.193
  1934. #
  1935. #
  1936. # Host behind Gateway
  1937. # 193.141.17.142          193.141.17.193  255.255.255.255
  1938. #
  1939. # Net behind a Gateway
  1940. # 193.141.17.145          193.141.17.193  255.255.255.0
  1941. #
  1942. # Multicast route for e.g. eth0. IP multicasting, forwarding and perhaps
  1943. # multicast routing in kernel should be enabled.   More information will
  1944. # be found in the NET-3-HOWTO.     Most people do NOT need this feature.
  1945. #
  1946. # 224.0.0.0       0.0.0.0      240.0.0.0   eth0
  1947. #
  1948. # ISDN (i4l)
  1949. # 192.168.0.1             0.0.0.0         255.255.255.255       ippp0
  1950. # default                 192.168.0.1
  1951.  
  1952. " + gwstr;
  1953.       if (!WriteString(route_conf, s))
  1954.     UI(`DisplayMessage(sformat(UI(_("Couldn't write values to %1")), route_conf), 0, ""));
  1955.     }
  1956.  
  1957.     UI(`SetContents (
  1958.              _("Network configuration"),
  1959.              // label for waiting while SuSEconfig is runing
  1960.              `Label (_("Running SuSEconfig...")),
  1961.              "", false, false
  1962.              )
  1963.        );
  1964.  
  1965.     if (Shell("/sbin/SuSEconfig -quick -nonewpackage") != 0)
  1966.       // warning dialog message
  1967.       UI(`DisplayMessage(_("Error while running SuSEconfig"), 0, ""));
  1968.  
  1969.     if (card_is_pcmcia) {
  1970.     if (Shell("/sbin/conf.d/SuSEconfig.pcmcia") != 0) {
  1971.         // warning dialog message
  1972.         UI(`DisplayMessage(_("Error while running SuSEconfig"), 0, ""));
  1973.     }
  1974.     }
  1975.     return `next;
  1976.     
  1977.   };
  1978.  
  1979.   /*
  1980.    * Stop networking, save new configuration and restart networking
  1981.    *
  1982.    */
  1983.   define Finish (any result) ``{
  1984.  
  1985.     //    if (result == `back) return result;
  1986.  
  1987.     integer code = 0;
  1988.  
  1989.     // label for waiting until network is not stopped
  1990.     string msg = UI(_("Stopping network..."));
  1991.  
  1992.     // help text for configuration finishing
  1993.     string helptext = UI(_("<p>\n
  1994. Network configuration is finished and the changes are saved.\n
  1995. The network is then restarted.\n
  1996. </p>
  1997. "));
  1998.  
  1999.     UI(`SetContents (_("Network configuration"), `Label(msg), "", false, false));
  2000.  
  2001.     list l = [];
  2002.     void|map m = $[];
  2003.       
  2004.     any a = SCR(`Read(.probe.byclass.network_interface.ethernet));
  2005.  
  2006.     if (a != nil) l = maplist(`c, a, ``lookup(c, "dev_name", ""));
  2007.  
  2008.     Shell("/sbin/init.d/route stop");     
  2009.  
  2010.     maplist(`c, l, ``{
  2011.       if (substring(c, 0, 3) == "eth")
  2012.     Shell("/sbin/ifconfig " + c + " down");
  2013.     });
  2014.     
  2015.     maplist(`i, cdev, ``{
  2016.       Shell("/sbin/ifconfig " + lookup(lookup(ifs, i, $[]), "dev", "") + " down");
  2017.     });
  2018.  
  2019.     // Shell("/sbin/init.d/network stop");
  2020.  
  2021.     Shell("/sbin/init.d/dhclient stop");
  2022.  
  2023.     maplist(`c, l, ``Shell("/sbin/modprobe -r " + c));
  2024.  
  2025.     SaveConfig();
  2026.  
  2027.     Shell("/bin/hostname " + host + "." + domain);
  2028.  
  2029.     if (dhcp) {
  2030.  
  2031.       Shell("/sbin/init.d/dhclient start");
  2032.  
  2033.       sleep(2000);
  2034.  
  2035.     } else {
  2036.       
  2037.       Shell("/sbin/init.d/network start");
  2038.  
  2039.       Shell("/sbin/init.d/route start");
  2040.      
  2041.     }
  2042.  
  2043.  
  2044.     // test networking
  2045.     // get address and broadcast for eth0 from /sbin/ifconfig and ping broadcast
  2046.  
  2047.     msg = "";
  2048.  
  2049.     m = SCR(`Read(.run.ifconfig));
  2050.  
  2051.     if (m != nil) {
  2052.  
  2053.       m = lookup(m, "eth0");
  2054.       
  2055.       if (m != nil) {
  2056.  
  2057.     // there are some problems with broadcast ping !!!
  2058.     // therefore it is temporary commented
  2059. //     Shell(sformat("/bin/ping -w 1 -n %1 > /tmp/ping.out & /bin/sleep 10; /bin/kill $!",
  2060. //               addrtostr(ip4toaddr(lookup(m, "bcast")))));
  2061. //     list|void l = SCR(`Read(.tmp.ping));
  2062. //     Shell("/bin/rm -f /tmp/ping.out");
  2063. //     if (l == nil) l = [];
  2064. //     l = filter(`c, l, ``(c != lookup(m, "addr")));
  2065. //     if (size(l) > 0)
  2066.     
  2067.     // configuration is done
  2068.     msg = UI(_("The network device is now configured and ready to use."));
  2069.  
  2070.       }
  2071.     }          
  2072.  
  2073.     if (msg == "")
  2074.       // configuration is finished, but network is not running
  2075.       msg = UI(_("Something is wrong! Network is not running.\nPlease check your hardware and try again.\n\nHint on PCMCIA: Perhaps your network card\nisn't plugged in."));
  2076.  
  2077.     UI(`SetContents (_("Network configuration"), `Label(msg), helptext, true, true));
  2078.  
  2079.     result = UI(`UserInput ());
  2080.       
  2081.     return result;
  2082.       
  2083.   };
  2084.  
  2085.  
  2086.   /*
  2087.    * Global variables definiton
  2088.    *
  2089.    */
  2090.  
  2091.   boolean dhcp = false;
  2092.  
  2093.   list netconfig = [];  // list of active interfaces, NETCONFIG value
  2094.   list netconfig_pcmcia = [];  // list of active interfaces, NETCONFIG_PCMCIA value
  2095.   integer netdev = -1; // interface number, index for NETDEV, IPADDR, IFCONFIG
  2096.   map ifs = $[];      // map of other than eth devices with static ip addreses
  2097.   list cdev = [];    // list of conflicted devices according to NETCONFIG and netdev
  2098.   
  2099.   list ip = [];
  2100.   list mask = [];
  2101.   list gateway = [];
  2102.  
  2103.   string host   = "";
  2104.   string domain = "";
  2105.  
  2106.   list nameserver = [];
  2107.   list searchlist = []; 
  2108.  
  2109.   string dhcommand = "";
  2110.   string ifconfig = "";
  2111.   
  2112.   string rc_config    = "/etc/rc.config";
  2113.   string modules_conf = "/etc/modules.conf";
  2114.   string route_conf   = "/etc/route.conf";
  2115.   string hosts        = "/etc/hosts";
  2116.   string host_conf    = "/etc/host.conf"; 
  2117.   string resolv_conf  = "/etc/resolv.conf";
  2118.  
  2119.   integer card_id  = -1;         // card number from .probe
  2120.   string card_name = "";        // card description name
  2121.   string dev_name  = "eth0";   // device name
  2122.   string mod_name = "";       // kernel module name
  2123.   string mod_conf = "";      // modules.conf entry
  2124.   list   mod_args = [];     // insmod arguments
  2125.   string mod_name_old = "";// default kernel module name
  2126.  
  2127.   list modulesconf = [];
  2128.  
  2129.   /*
  2130.    * Global variables initialization
  2131.    *
  2132.    */
  2133.  
  2134.   ReadConfig();
  2135.  
  2136.   /*
  2137.    * Main dialog cycle
  2138.    *
  2139.    */
  2140.  
  2141.   list dialog = [
  2142.          ``FindCard (result),
  2143.          ``AddressSetup (result),
  2144.          ``CheckInterfaces(result),
  2145.          ``DNSSetup (result),
  2146.          ``Finish (result)
  2147.   ];
  2148.   integer id = 0;
  2149.   any result = `next;
  2150.  
  2151.   while ((id >= 0) && (id < size (dialog))) {
  2152.     
  2153.     result = eval(select(dialog, id));
  2154.     
  2155.     if (result == `cancel)
  2156.       break;
  2157.     else if (result == `next)
  2158.       id = id + 1;
  2159.     else if (result == `back)
  2160.       id = id - 1;
  2161.  
  2162.   }
  2163.   
  2164.   return UI(`CloseDialog());
  2165.  
  2166. }
  2167.