ACC SHELL

Path : /usr/share/YaST2/include/network/
File Upload :
Current File : //usr/share/YaST2/include/network/complex.ycp

/**
 * File:	include/network/complex.ycp
 * Package:	Network configuration
 * Summary:	Summary and overview functions
 * Authors:	Michal Svec <msvec@suse.cz>
 *
 * $Id: complex.ycp 54679 2009-01-16 10:51:38Z mzugec $
 *
 */

{

textdomain "network";

import "NetHwDetection";
import "HTML";
import "NetworkInterfaces";
import "Popup";
import "String";
import "Summary";
import "NetworkService";

include "network/routines.ycp";
include "network/summary.ycp";

define string CheckEmptyName(string devtype, string hwname);
define string DeviceStatus(string devtype, string devnum, map devmap);
define string HardwareName(list<map> Hardware, string unq);


/**
 * Used for initializing the description variable (ifcfg[NAME])
 * The code is mostly moved from BuildSummaryDevs
 * Take the NAME field from ifcfg
 * If empty, identify the hardware and use its data
 */
define string BuildDescription (string devtype, string devnum, map devmap,
				list<map> Hardware) {
    string descr = devmap["NAME"]:"";
    if (descr != "") return descr;
    descr = HardwareName (Hardware, devnum);
    if (descr != "") return descr;
    descr = HardwareName (Hardware, devmap["UNIQUE"]:"");
    if (descr != "") return descr;
    descr = HardwareName (Hardware, devmap["dev_name"]:"");
    if (descr != "") return descr;
    descr = CheckEmptyName (devtype, descr);
    return descr;
}

// TODO move to HTML.ycp
define string Hyperlink (string href, string text) {
    return sformat ("<a href=\"%1\">%2</a>", href, text);
}

/**
 * Build textual summary
 * @param split split configured and unconfigured?
 * @param link  add a link to configure the device (only if !split)
 * @return [ configured, unconfigured ] if split, [ summary, links ] otherwise
 */
define list<any> BuildSummaryDevs(map<string,map> Devs, list<map> Hardware, boolean split, boolean link) {
    y2milestone("Devs=%1", NetworkInterfaces::ConcealSecrets (Devs));
    y2milestone("Hardware=%1", Hardware);
    y2debug("split=%1", split);

    list uniques = [];
    list uniques_old = [];
    list<string> configured = [];
    list<map> unconfigured = [];
    list<string> links = [];

    /* build a list of configured devices */
    maplist(string devtype, map devsmap, Devs, {
	maplist(string devname, map devmap, (map<string,map>)devsmap, {

	    /* main device summary */
	    string descr = BuildDescription (devtype, devname, devmap, Hardware);
	    string unq = devmap["UNIQUE"]:"";
	    string status = DeviceStatus(devtype, devname, devmap);
	    if (link)
	    {
		if (devtype == "wlan" &&
		    devmap["WIRELESS_AUTH_MODE"]:"" == "open" &&
		    devmap["WIRELESS_KEY_0"]:"" == "")
		{
		    string href = "lan--wifi-encryption-" + devname;
		    // interface summary: WiFi without encryption
		    string warning = HTML::Colorize (_("Warning: no encryption is used."), "red");
		    status = status + " " + warning + " " +
			// Hyperlink: Change the configuration of an interface
			Hyperlink (href, _("Change."));
		    links = add (links, href);
		}
	    }

	    configured = add(configured, Summary::Device(descr, status));
	    uniques = add(uniques, devname);
	    uniques_old = add(uniques_old, unq);

	    /* aliases summary */
	    map<string,map> aliasee = devmap["_aliases"]:$[];
	    if(aliasee != $[])
		maplist(string aid, map amap, aliasee, {
		    /* Table item */
		    // this is what used to be Virtual Interface
		    // (eth0:1)
		    descr = _("Additional Address");
		    status = DeviceStatus(devtype, devname /* FIXME: devname + sformat(":%1", aid)*/, amap);
		    configured = add(configured, Summary::Device(descr, status));
		});

	});
    });

    y2debug("uniques(%1)", uniques);
    y2debug("uniques_old(%1)", uniques_old);

    /* build a list of unconfigured devices */
integer id=0;
    maplist(map h, Hardware, {
	string unq = h["unique"]:"";

	string busid = "bus-" + h["bus"]:"" + "-" + h["busid"]:"";
	string mac = "id-" + h["mac"]:"";
	string hwtype = h["type"]:"";
	string hwname = CheckEmptyName(hwtype, h["name"]:"");
	y2debug("busid=%1, mac=%2", busid, mac);
	if(!contains(uniques, busid) && !contains(uniques, mac) && !contains(uniques_old, unq)) {
	    if(split && !contains(uniques_old, unq))
{
		h["id"]=id;
		unconfigured = add(unconfigured, h);
}
	    else
		configured = add(configured, Summary::Device(hwname, Summary::NotConfigured()));
	}
	id=id+1;
    });

    y2debug("configured=%1", configured);
    y2debug("unconfigured=%1", unconfigured);

    /* create a summary text */
    string summary = Summary::DevicesList(configured);
    /* if not split -> summary is finished */
    if(!split) return [ summary, links ];

    /* add headers */
    if(size(configured) > 0)
	/* Summary text */
	summary = Summary::AddHeader("", _("Already Configured Devices:")) + summary;
    else
	/* Summary text */
	summary = Summary::AddHeader("", _("Nothing is configured"));

    /* create a table of unconfigured devices */
    integer selected = unconfigured[0, "num"]:-1;
//    list devs = hwlist2items(unconfigured, selected);

    // FIXME OtherDevices(devs, type);

    /* Label for not detected devices */
//    devs = add(devs, `item(`id(`other), _("Other (not detected)"), size(devs) == 0));

    y2debug("summary=%1", summary);
//    y2debug("devs=%1", devs);

    return [ summary, unconfigured ];
//    return [ summary, devs ];
}

/**
 * Build textual summary
 * @param split split configured and unconfigured?
 * @param link  add a link to configure the device (only if !split)
 * @return [ configured, unconfigured ] if split, [ summary, links ] otherwise
 */
define list<any> BuildSummary(string devregex, list<map> Hardware, boolean split, boolean link) {
    map <string, map> Devs = NetworkInterfaces::FilterDevices (devregex);
    list <any> ret = BuildSummaryDevs (Devs, Hardware, split, link);
 return ret;
}

/**
 * Fill in sensible string if the name is empty
 * @param devtype device type
 * @param hwname device name
 * @return hwname if not empty, "Unknown device" otherwise
 */
define string CheckEmptyName(string devtype, string hwname) {
    if(hwname != nil && hwname != "") return hwname;

    map device_names = $[
	/* Device type label */
	"contr-pcmcia"	: _("PCMCIA ISDN Card"),
	/* Device type label */
	"contr-usb"	: _("USB ISDN Card"),
	/* Device type label */
	"eth-pcmcia"	: _("PCMCIA Ethernet Network Card"),
	/* Device type label */
	"eth-usb"	: _("USB Ethernet Network Card"),
	/* Device type label */
	"fddi-pcmcia"	: _("PCMCIA FDDI Network Card"),
	/* Device type label */
	"fddi-usb"	: _("USB FDDI Network Card"),
	/* Device type label */
	"ippp-pcmcia"	: _("PCMCIA ISDN Connection"),
	/* Device type label */
	"ippp-usb"	: _("USB ISDN Connection"),
	/* Device type label */
	"isdn-pcmcia"	: _("PCMCIA ISDN Connection"),
	/* Device type label */
	"isdn-usb"	: _("USB ISDN Connection"),
	/* Device type label */
	"modem-pcmcia"	: _("PCMCIA Modem"),
	/* Device type label */
	"modem-usb"	: _("USB Modem"),
	/* Device type label */
	"ppp-pcmcia"	: _("PCMCIA Modem"),
	/* Device type label */
	"ppp-usb"	: _("USB Modem"),
	/* Device type label */
	"tr-pcmcia"	: _("PCMCIA Token Ring Network Card"),
	/* Device type label */
	"tr-usb"	: _("USB Token Ring Network Card"),
	/* Device type label */
	"usb-usb"	: _("USB Network Device"),
	/* Device type label */
	"wlan-pcmcia"	: _("PCMCIA Wireless Network Card"),
	/* Device type label */
	"wlan-usb"	: _("USB Wireless Network Card"),
    ];

    if(haskey(device_names, devtype)) return device_names[devtype]:"";
	else {
		string descr =	NetworkInterfaces::GetDevTypeDescription(devtype, true);
		if (hasAnyValue(descr)) return descr;
	     }

    if(haskey(device_names, devtype + "-")) {
	y2warning("- device found: %1, %2", devtype, hwname);
	return device_names[devtype + "-"]:"";
    }

    y2error("Unknown type: %1", devtype);
    /* Device type label */
    return _("Unknown Network Device");
}

/**
 * Return a human readable hardware name for device with given id
 * @param Hardware hardware map
 * @param id id-..., bus-...-..., or unique
 * @return hardware name
 */
define string HardwareName(list<map> Hardware, string id) {
    string hwname = "";
    if(id != "")
    {
	foreach (map h, Hardware, {
	    list<string> have = [
		"id-" + h["mac"]:"",
		"bus-" + h["bus"]:"" + String::OptFormat("-%1", h["busid"]:""),
		h["udi"]:"",
		h["dev_name"]:"",
		];
	    y2debug ("what: %1, have: %2", id, have);
	    if (contains (have, id))
	    {
		hwname = h["name"]:"";
		break;
	    }
	});
    }
    y2milestone("hwname=%1", hwname);
    return hwname;
}

/**
 * Get aprovider name from the provider map
 * @param provider identifier
 * @return provider name
 * @example ProviderName("tonline") -> "T-Online"
 */
define string ProviderName(string provider) {
    import "Provider";

    if(provider == nil || provider == "")
	return "";

    Provider::Select(provider);
    string nam = Provider::Current["PROVIDER"]:provider;
    if(nam == nil || nam == "") return provider;
    return nam;
}

/**
 * Return the textual device status
 * @param devtype device type
 * @param devnum device number
 * @param devmap map with devices settings
 * @return text wth device status
 */
define string DeviceStatus(string devtype, string devname, map devmap) {
    /* Modem and DSL */
    if(devtype == "ppp" || devtype == "modem" || devtype == "dsl") {

	string nam = ProviderName(devmap["PROVIDER"]:"");

	if(nam == "" || nam == nil)
	    /* Modem status (%1 is device) */
	    return sformat(_("Configured as %1"), devname);
	else
	    /* Modem status (%1 is device, %2 is provider) */
	    return sformat(_("Configured as %1 with provider %2"), devname, nam);
    }
    /* ISDN card */
    else if(devtype == "isdn" || devtype == "contr") {
	/* ISDN device status (%1 is device) */
	return sformat(_("Configured as %1"), devname);
    }
    /* ISDN stuff */
    else if(devtype == "net") {

	string nam = ProviderName(devmap["PROVIDER"]:"");
	/* Connection protocol (syncppp|rawip) */
	string proto = devmap["PROTOCOL"]:"";

	/* ISDN status (%1 is device, %2 is provider, %3 protocol) */
	return sformat(_("Configured as %1 with provider %2 (protocol %3)"), devname, nam, proto);

	/* example: ISDN Connection to Arcor with syncppp on net0 */
	// return sformat(_("to %1 with %2 on %3"), provider, proto, dev);
    }
    /* Treat others as network cards */
    else {
	/*
	if(!regexpmatch(devtype, NetworkAllRegex))
	    y2error("Unknown type: %1", devtype);
	*/

	string proto = devmap["BOOTPROTO"]:"static";

	if(proto == "" || proto == "static" || proto == "none" || proto == nil) {
	    string addr = devmap["IPADDR"]:"";
	    string host = NetHwDetection::ResolveIP (addr);
	    string remip = devmap["REMOTE_IPADDR"]:"";
 	 if (proto == "none") return _("Configured without address (NONE)");
	  else if(!hasAnyValue(addr))
		/* Network card status */
		return HTML::Colorize (_("Warning: no encryption is used."), "red"); //sformat(_("Configured without an address"));
	    else if(remip == "" || remip == nil)
		/* Network card status (%1 is address) */
		return sformat(_("Configured with address %1"),
			       addr + String::OptParens (host));
	    else
		/* Network card status (%1 is address, %2 is address) */
		return sformat(_("Configured with address %1 (remote %2)"), addr, remip);
	}
	else
	    /* Network card status (%1 is protocol) */
	    return sformat(_("Configured with %1"), toupper(proto));

	// This is the old version of the above code, including the
	// configuration name. But the name is long and cryptic so wen
	// don't use it.
	/* FIXME: dropped interface name */
	if(proto == "" || proto == "static" || proto == "none" || proto == nil) {
	    string addr = devmap["IPADDR"]:"";
	    string remip = devmap["REMOTE_IPADDR"]:"";
	    if(addr == "" || addr == nil)
		/* Network card status (%1 is device) */
		return sformat(_("Configured as %1"), devname);
	    else if(remip == "" || remip == nil)
		/* Network card status (%1 is device, %2 is address) */
		return sformat(_("Configured as %1 with address %2"), devname, addr);
	    else
		/* Network card status (%1 is device, %2 is address, %3 is address) */
		return sformat(_("Configured as %1 with address %2 (remote %3)"), devname, addr, remip);
	}
	else
	    /* Network card status (%1 is device, %2 is protocol) */
	    return sformat(_("Configured as %1 with %2"), devname, toupper(proto));
    }
}

/**
 * Return the device protocol or IP address in case of static config
 * Or indicate that NetworkManager takes over.
 * @param devmap device map
 * @return textual device protocol
 */
define string DeviceProtocol(map devmap) {
    if (devmap["STARTMODE"]:"" == "managed")
    {
	// Abbreviation for "The interface is Managed by NetworkManager" 
	return _("Managed");
    }
    string ip = devmap["BOOTPROTO"]:"static";
    if(ip == nil || ip == "" || ip == "static")
	ip = devmap["IPADDR"]:"";
    else ip = toupper(ip);
    return ip;
}

/**
 * Return description used for device summary dialog
 * In case device is not connected "(not connected)" string
 * will be added.
 * Description also contains MAC address or BusID information.
 */

string getConnMacBusDescription(map v, list<map> Hardware){
 string descr = "";
	string conn="";
	string mac_dev="";
	foreach(map device, Hardware, {
	 if (v["UNIQUE"]:""==device["unique_key"]:"") {
			conn = HTML::Bold ( (device["link"]:false == true)?"":_("(not connected)") );
			if (size(device["mac"]:"")>0) mac_dev= HTML::Bold ("MAC : ") + device["mac"]:"" + "<br>";
			 else 
			   if (size(device["busid"]:"")>0) mac_dev= HTML::Bold ("BusID : ") + device["busid"]:"" + "<br>";
			}
	});
 descr = " " + conn + "<br>" + mac_dev;
 return descr;
}

/**
 * Create overview table contents
 * List of terms
 * `item (`id (id), ...)
 * @return table items
 */
define list BuildOverviewDevs(map<string,map> Devs, list<map> Hardware) {
    list overview = [];

    map startmode_descrs = $[
	// summary description of STARTMODE=auto
	"auto": _("Started automatically at boot"),
	// summary description of STARTMODE=hotplug
	"hotplug": _("Started automatically at boot"),
	// summary description of STARTMODE=ifplugd
	"ifplugd": _("Started automatically on cable connection"),
	// summary description of STARTMODE=managed
	"managed": _("Managed by NetworkManager"),
	// summary description of STARTMODE=off
	"off"	: _("Will not be started at all")
	];

    maplist(string type, map devmap, Devs, {
	maplist(string devname, map v, (map<string,map>)devmap, {
	    term item = nil;
	    string ip = DeviceProtocol(v);

	    string descr = BuildDescription (type, devname, v, Hardware);
	    string startmode_descr = startmode_descrs[v["STARTMODE"]:""]:_("Started manually");

	    /* Modem and DSL */
	    if(type == "ppp" || type == "modem" || type == "dsl")
	    {
		// create the rich text description
		string rich = HTML::Bold (descr) 
		    + "<br>" + HTML::List ( [
			sformat(_("Device Name: %1"), devname),
			sformat(_("Mode: %1"), v["PPPMODE"]:_("Unknown")),
			startmode_descr,
		    ]);
		item = `item(`id(devname), devname, NetworkInterfaces::GetDevTypeDescription(type, false), ProviderName(v["PROVIDER"]:""), rich);
	    }
	    /* ISDN stuff */
	    else if (type == "contr") {
		// FIXME: richtext
		string cname = v["NAME"]:"unknown";
		item = `item(`id(devname), devname, NetworkInterfaces::GetDevTypeDescription(type, false), cname /*, "active?", ip, "?", "?"*/);
	    }
	    /* ISDN stuff */
	    else if (type == "net") {
		// FIXME: richtext
		string cname = v["PROVIDER"]:"unknown";
		string rip   = v["PTPADDR"]:"none";
		string proto = v["PROTOCOL"]:"unknown";
		item = `item(`id(devname), devname, proto, cname, ip, rip);
	    }
	    /* Treat others as network cards */
	    else {
		/*
		if(!regexpmatch(type, NetworkAllRegex))
		    y2error("Unknown type: %1", type);
		*/
		
		list<string> bullets =  [
		    sformat(_("Device Name: %1"), devname),
		    startmode_descr,
		    ];
		if (v["STARTMODE"]:"" != "managed")
		{
                 if (ip != "NONE")
		  {
		    bullets = bullets + [
			ip == "DHCP" ? _("IP address assigned using DHCP") :
			sformat(_("IP address: %1, subnet mask %2")
				, ip, v["NETMASK"]:""),
			];
		  }

	// build aliases overview
	if (size(v["_aliases"]:$[])>0 && !NetworkService::IsManaged()){
	 foreach(string key,   map<string, any> desc, (map<string ,map<string, any> >) v["_aliases"]:$[], {
	 string parameters = sformat(_("IP address: %1, subnet mask %2"), desc["IPADDR"]:"", desc["NETMASK"]:"");
	 bullets = add(bullets, sformat("%1 (%2)", key, parameters) );
	 });
	}
		}

                // build the "Bond Slaves" entry of rich box
		if (type == "bond")
		{
			string slaves = "";
			foreach (string key, any value, (map<string, any>)v, {
				if ((value != nil) && (regexpmatch(key, "BONDING_SLAVE[0-9]")))
					slaves = slaves + ((slaves != "") ? ", " : "") + (string)value;
			});
			if (slaves != "")
				bullets = bullets + [_("Bond slaves")+ " : " + slaves];
		}

		string rich =  descr;
		rich = HTML::Bold ( rich ) + getConnMacBusDescription(v, Hardware) + HTML::List (bullets);
	integer hw_id=-1;
	boolean found=false;
	foreach(map device, Hardware, {
	 hw_id=hw_id+1;
	 if (v["UNIQUE"]:""==device["unique_key"]:"") { found=true; break; }
	 });

		item = `item(`id(devname), descr, ip, rich, (found) ? hw_id : -1);
	    }
	    overview = add(overview, item);


	});
    });

    y2debug("overview=%1", overview);
    return overview;
}

/**
 * Create overview table contents
 * @return table items
 */
define list BuildOverview(string devregex, list<map> Hardware) {
    map <string, map> Devs = NetworkInterfaces::FilterDevices (devregex);
    return BuildOverviewDevs (Devs, Hardware);
}

/**
 * Convert the output of BuildSummary for inclusion in the unified device list.
 * Called by BuildUnconfigured and BuildUnconfiguredDevs.
 * @param sum output of BuildSumary
 * @param class netcard modem dsl, isdn too;
 * determines how to arrange output, yuck
 * @return [ $[id, table_descr, rich descr] ]
 */
define list<map<string,any> > BuildUnconfiguredCommon (list sum, string class) {
    // unconfigured devices
//    list<term> res = sum[1]:[`item(`id(`other))];
    // filter out the item for adding an unknown one
//    list res = filter (term card, sum, ``( card[0,0]:nil != `other ));
    // translators: this device has not been configured yet
    string nc = _("Not configured");
    return maplist( map<string,any> card, (list<map<string, any> >)sum, {
	// configured cards are identified by the string after ifcfg-,
	// unconfigured ones by "-%1" where %1 is the index in hardware list
	string id = sformat ("-%1", card["id"]:0);
	string name = card["name"]:"";
	list desc = [];
	switch(class){
	 case "netcard" : desc = [name, nc];
			break;
	 case "modem" :
	 case "dsl" : desc = [name, NetworkInterfaces::GetDevTypeDescription (class, false), nc];
			break;
	 case "isdn" : desc = [nc, NetworkInterfaces::GetDevTypeDescription (class, false), name];
			break;
	 default : y2warning (1, "invalid class %1", class);
	}
	string rich = HTML::Bold(name) + getConnMacBusDescription((map)card, (list<map>)sum) + _("<p>The device is not configured. Press <b>Edit</b> for configuration.</p>");
	return $[
	    "id":id,
	    "table_descr":desc,
	    "rich_descr": rich,
	 ];
	}
    );
}

/**
 * @param Devs configured devices
 * @param class netcard modem dsl, isdn too
 * @param Hardware the detected hardware
 * @return [ $[id, table_descr, rich descr] ]
 */
define list<map<string,any> > BuildUnconfiguredDevs (map<string,map> Devs, string class, list<map> Hardware) {
    boolean split = true;
    boolean proposal = false;
    list sum = BuildSummaryDevs (Devs, Hardware, split, proposal);
    return BuildUnconfiguredCommon (sum[size(sum)-1]:[], class);
}

/**
 * @param class netcard modem dsl. not isdn because it does not use
 * NetworkInterfaces (#103073)
 * @param Hardware the detected hardware
 * @return [ $[id, table_descr, rich descr] ]
 */
define list<map<string,any> > BuildUnconfigured (string class, list<map> Hardware) {
    boolean split = true;
    boolean proposal = false;
    list sum = BuildSummary (class, Hardware, split, proposal);
    return BuildUnconfiguredCommon (sum[size(sum)-1]:[], class);
}

/* EOF */
}

ACC SHELL 2018