ACC SHELL

Path : /usr/share/YaST2/modules/
File Upload :
Current File : //usr/share/YaST2/modules/Host.ycp

/**
 * File:	modules/Host.ycp
 * Package:	Network configuration
 * Summary:	Hosts data (/etc/hosts)
 * Authors:	Michal Svec <msvec@suse.cz>
 *
 * $Id: Host.ycp 61734 2010-04-16 13:15:42Z kmachalkova $
 */

{

module "Host";
textdomain "network";

import "DNS";
import "Hostname";
import "NetworkInterfaces";
import "String";
import "Summary";

include "network/routines.ycp";

/**
 * All hosts
 * See hosts(5)
 * keys: IPs, (But #35671 suggests that repeating IPs is valid)
 * values: names, the first one is the canonical one
 */
global map<string, list<string> > hosts = $[];

/**
 * Data was modified?
 */
global boolean modified = false;

/**
 * All hosts read at the start
 */
map<string,any> hosts_init = $[];

/**
 * "hosts" file location
 */
string hosts_file = "/etc/hosts";

/**
 * Only write configuration
 */
global boolean write_only = false;

boolean initialized = false;

global boolean NeedDummyIP() {
   return DNS::write_hostname;
}

global void EnsureHostnameResolvable() {
    string local_ip = "127.0.0.2";
    if ( NeedDummyIP() ) {
	y2milestone("Dummy 127.0.0.2 IP will be added");
	//Add 127.0.0.2 entry to /etc/hosts,if product default says so
	//or user requests it otherwise some desktop apps may hang,
	//being unable to resolve hostname (bnc#304632)

	string fqhostname = Hostname::MergeFQ( DNS::hostname, DNS::domain);
	hosts[ local_ip ] = [ fqhostname + " " + DNS::hostname ];
    }
    else {
	// Do not add it if product default says no
	// and remove 127.0.02 entry if it exists
	if( haskey( hosts, local_ip) ) {
	    hosts[ local_ip] = [];
	}
    }
    modified = true;
}

/**
 * Read hosts settings
 * @return true if success
 */
global define boolean Read() {

    if(initialized == true) 
	return true;

    /* read /etc/hosts */
    if(SCR::Read(.target.size, hosts_file) > 0) {
	list<string> hostlist = SCR::Dir(.etc.hosts);
	hosts = listmap(string host, hostlist, {
	    list <string> names = (list <string>) SCR::Read(topath(sformat(".etc.hosts.\"%1\"", host)));
	    if (names != [])
	        return $[ host: names ];
	});
    }

    /* save hosts to check for changes later */
    hosts_init = hosts;

    y2debug("hosts=%1", hosts);
    initialized = true;
    return true;
}

/**
 * Write hosts settings and apply changes
 * @return true if success
 */
global define boolean Write() {

    y2milestone("Writing hosts configuration");

    if(!modified) {
       y2milestone("No changes to Host -> nothing to write");
       return true;
    }

    /* Check if there is anything to do */
    if(hosts_init == hosts) {
	y2milestone("Hosts not modified");
	return true;
    }

    list <string> steps = [
	_("Update /etc/hosts"),
    ];

    string caption = _("Saving Hostname Configuration");
    integer sl = 500; //sleep for longer time, so that progress does not disappear right afterwards

    Progress::New(caption, " ", size(steps), steps, [], "");

    ProgressNextStage(_("Updating /etc/hosts ..."));

    /* Create if not exists, otherwise backup */
    if(SCR::Read(.target.size, hosts_file) < 0)
	SCR::Write(.target.string, hosts_file, "");
    else
	SCR::Execute(.target.bash, "/bin/cp "+hosts_file+" "+hosts_file+".YaST2save");

    any ret = false;
    if(hosts == $[] || hosts == nil)
	/* Workaround bug [#4476] */
	ret = SCR::Write(.target.string, hosts_file, "");
    else {
	/* Update the hosts config */
	y2milestone("hosts=%1", hosts);
	maplist(string ho, list<string> names, (map<string,list<string> >)hosts, {
	    y2milestone("%1 (%2:%3)", ho, names, hosts_init[ho]:nil);
	    SCR::Write(add(.etc.hosts, ho), names);
	});
	ret = true;
    }

    SCR::Write(.etc.hosts, nil);
    sleep(sl);
    Progress::NextStage();
    return ret == true;
}

/**
 * Get all the Hosts configuration from a map.
 * When called by hosts_auto (preparing autoinstallation data)
 * the map may be empty.
 * @param settings autoinstallation settings
 * @return true if success
 */
global define boolean Import(map settings) {
    modified = true;

    hosts = eval(settings["hosts"]:$[]);

    //convert from old format to the new one
    //use ::1 entry as a reference
    if (size(hosts["::1"]:[]) > 1) {
	foreach(string ip, list<string> hn, hosts, {
	    hosts[ip] = [mergestring(hn," ")];
	});
    }
    return true;
}

/**
 * Dump the Hosts settings to a map, for autoinstallation use.
 * @return autoinstallation settings
 */
global define map Export() {
    if (size(hosts)>0)
    {
	//Filter out IPs with empty hostname (so that valid autoyast
        //profile is created)(#335120)
	hosts = filter ( string ip, list <string> names, hosts,{
	    return (names != []);
	});
        return $[
            "hosts": eval(hosts),
        ];
    } else {
        return $[];
    }
}

/**
 * Return "system" predefined hosts (should be present all the time)
 * @return list of system hosts
 */
global define list GetSystemHosts() {
    return [
	"127.0.0.1",
	"::1", "fe00::0", "ff00::0", "ff02::1", "ff02::2", "ff02::3"
    ];
}

/**
 * Update hosts according to the current hostname
 * (only one hostname, assigned to all IPs)
 * @param hostname current hostname
 * @param domain current domain name
 * @param iplist localhost IP addresses
 * @return true if success
 */
global define boolean Update(string oldhn, string newhn, list<string> iplist) {

    list<string> ips = filter(string ip, iplist, {
	return ip != "127.0.0.1";
    });

    y2milestone("Hosts: %1", hosts);
    y2milestone("Updating /etc/hosts: %1 -> %2: %3", oldhn, newhn, ips);
    modified = true;

    string nick = Hostname::SplitFQ(newhn)[0]:"";
    string oldnick = Hostname::SplitFQ(oldhn)[0]:"";

    /* Remove old hostname from hosts */
//    list oldhnlist = [];
    foreach (string ip, list<string> hs, hosts, {
	list <list <string> > wrk = maplist(string s, hs, {
	    return splitstring(s," ");
	});
	wrk = filter (list <string> lst, wrk, {
	    return (!contains(lst, oldhn));
        });

        hosts[ip] = maplist(list <string> lst, wrk, {
	    return mergestring(lst, " ");
        });
    });

    /* Resurect the rest of oldhnlist without old hostname */
    // FIXME: maybe

    /* Add localhost if missing */
    if(!haskey(hosts, "127.0.0.1")) {
	hosts["127.0.0.1"] = ["localhost"];
    }

    
    /* Add hostname/ip for all ips */
    boolean nickadded = false;
    maplist(string ip, ips, {

	/* Only add if not present yet */
	//		if(haskey(hosts, ip)) return;
	/* Omit some IP addresses */
	if(ip == "" || ip == nil || ip == "127.0.0.1" ) return;

	string name =  newhn ;
	/* Add nick for the first one */
	if(!nickadded && name != "")  {
	    nickadded = true;
	    name = newhn + " " +  nick;
	}

	hosts[ip] = add(hosts[ip]:[],name);

    });

    y2milestone("Hosts: %1", hosts);

    return true;
}

/**
 * Create summary
 * @return summary text
 */
global define string Summary() {

	string summary = "";
	if(hosts == $[] )
	    return Summary::NotConfigured();

	summary = Summary::OpenList(summary);
	foreach(string k, list<string> v, (map<string,list<string> >)hosts, {
	    if(!contains(Host::GetSystemHosts(), k)) {
		foreach(string hn, v, {
		    summary = Summary::AddListItem(summary, k + " - " + hn );
		});
	    }
	});
	summary = Summary::CloseList(summary);
	return summary;
}

/**
 * Function which returns if the settings were modified
 * @return boolean  settings were modified
 */
global define boolean GetModified () {
    return modified;
}
/**
 * Function sets internal variable, which indicates, that any
 * settings were modified, to "true"
 */
global define void SetModified () {
    modified = true;
}
/* EOF */
}

ACC SHELL 2018