ACC SHELL

Path : /usr/share/YaST2/include/autoinstall/
File Upload :
Current File : //usr/share/YaST2/include/autoinstall/io.ycp

/**
 * File:	include/autoinstall/io.ycp
 * Package:	Autoinstallation Configuration System
 * Summary:	I/O
 * Authors:	Anas Nashif<nashif@suse.de>
 *
 * $Id: io.ycp 61227 2010-03-10 12:47:14Z ug $
 */
{
    textdomain "autoinst";
    import "URL";
    import "FTP";
    import "Installation";
    import "HTTP";
    import "StorageDevices";
    import "TFTP";
        import "AutoinstConfig";

    string GET_error = "";

    /**
     * Basename
     * @param string path
     * @return string  basename
     */
    define string basename (string filePath)
        ``{
        list pathComponents = splitstring(filePath, "/");
        string ret = pathComponents[size(pathComponents) -1 ]: "";
        return ( ret );
    }


    /**
     * Get directory name
     * @param string path
     * @return  string dirname
     */
    define string dirname (string filePath)
        ``{
           list pathComponents = splitstring(filePath, "/");
           string last = pathComponents[size(pathComponents) -1]:"";
           string ret = substring(filePath, 0 , size(filePath) - size(last));
           return (ret);
    }


    /**
     * Get control files from different sources
     * @return boolean true on success
     */
    define boolean Get(string Scheme,
                              string Host,
                              string Path,
                              string Localfile)
        ``{
        GET_error = "";
        boolean ok = false;
        map res = $[];
        map toks =  AutoinstConfig::urltok;
        toks["scheme"] = Scheme;
        toks["host"]   = Host;
        if (regexpsub(Path, "(.*)//(.*)", "\\1\/\\2")!= nil)
        {
            Path = regexpsub(Path, "(.*)//(.*)", "\\1\/\\2");
        }
        toks["path"]   = Path;
        string full_url = URL::Build(toks);

        string tmp_dir = (string)WFM::Read(.local.tmpdir, []);
        string mount_point = tmp_dir + "/tmp_mount";
        WFM::Execute(.local.mkdir, mount_point );

        if ( Scheme == "http" || Scheme == "https" )
        {
            HTTP::easySSL( true );
            res = HTTP::Get(full_url, Localfile);
            if (res["code"]:0 == 200)
            {
                GET_error = "";
                return (true);
            }
            else
            {
                y2error("Can't find URL: %1", full_url);
                // autoyast tried to read a file but had no success.
                GET_error = sformat(_("Cannot find URL '%1' via protocol HTTP(S). Server returned code %2."),full_url,res["code"]:0);
                return (false);
            }
        }
        if ( Scheme == "ftp" )
        {
            res = FTP::Get(full_url, Localfile);
            if ( ( res["code"]:-1 >= 200 && res["code"]:-1 < 300 ) && SCR::Read(.target.size, Localfile) > 0 )
            {
                GET_error = "";
                return (true);
            }
            else
            {
                y2error("Can't find URL: %1", full_url);
                // autoyast tried to read a file but had no success.
                GET_error = sformat(_("Cannot find URL '%1' via protocol FTP. Server returned code %2."),full_url,res["code"]:0);
                return (false);
            }
        }
        else if (Scheme == "file")
        {
            string file = sformat("%1/%2", Installation::sourcedir, Path); // FIXME: I have doubts this will ever work. Too early.
            if (SCR::Read(.target.size, file) > 0 )
            {
                string cpcmd = sformat("cp %1 %2", file, Localfile);
                y2milestone("Copy profile: %1", cpcmd);
                SCR::Execute(.target.bash, cpcmd);
            }
            else
            {
                GET_error = GET_error + sformat(_("Reading file on %1/%2 failed.\n"), Installation::sourcedir, Path);
                string cpcmd = sformat("cp %1 %2", Path , Localfile);
                y2milestone("Copy profile: %1", cpcmd);
                SCR::Execute(.target.bash, cpcmd);
            }

            if (SCR::Read(.target.size, Localfile) > 0 )
            {
                GET_error = "";
                ok = true;
            } else {
                GET_error = GET_error + sformat(_("Reading file on %1 failed.\n"), Path);
                y2milestone("Trying to find file on installation media: %1", Installation::boot ());
                if (Installation::boot () == "cd") {
                    string cdrom = (string)SCR::Read (.etc.install_inf.Cdrom);
                    string cdrom_device = "/dev/"+cdrom;
                    string already_mounted = "grep "+cdrom_device+" /proc/mounts ;";
                    map am = (map) SCR::Execute (.target.bash_output, already_mounted);

                    if (am["exit"]:-1 == 0 && size (am["stdout"]:"") > 0) {
                        y2warning ("%1 is already mounted, trying to bind mount...", cdrom_device);
                        string cmd = "mount -v --bind `grep "+cdrom_device+" /proc/mounts |cut -f 2 -d \\ ` "+mount_point+";";
                        map am1 = (map) SCR::Execute (.target.bash_output, cmd);
                        if (am1["exit"]:-1 == 0) {
                            ok=true;
                        } else {
                            y2warning ("can't bind mount %1 failing...", cdrom_device);
                            ok = false;
                        }

                    } else {
                        if (!(boolean)WFM::Execute(.local.mount, [cdrom_device, mount_point, Installation::mountlog] )) {
                            // autoyast tried to mount the CD but had no success.
                            GET_error = GET_error + sformat(_("Mounting %1 failed."), cdrom );
                            y2warning("Mount failed");
                            ok=false;
                        } else {
                            ok=true;
                        }
                    }
                    if (ok) {
                        string cpcmd = sformat("cp " + mount_point + "/%1 %2", Path , Localfile);
                        y2milestone("Copy profile: %1", cpcmd);
                        SCR::Execute(.target.bash, cpcmd);
                        WFM::Execute(.local.umount, mount_point);
                        if (SCR::Read(.target.size, Localfile) > 0 ) {
                            GET_error = "";
                            return (true);
                        }
                    }
                }
                // autoyast tried to read a file but had no success.
                GET_error = GET_error + sformat(_("Reading a file on CD failed. Path: %1/%2."),mount_point,Path);
                ok = false;
            }
        }
        else if (Scheme == "nfs")  // NFS
        {
            if (Installation::boot () != "nfs")
            {
                y2milestone("Starting portmap: %1", SCR::Execute (.target.bash, "/sbin/portmap") );
            }

            if( !(boolean)SCR::Execute(.target.mount, [ Host + ":" + dirname(Path), mount_point ], "-o nolock" ) &&
                !(boolean)SCR::Execute(.target.mount, [ Host + ":" + dirname(Path), mount_point ], "-t nfs4" ) )
            {
                y2warning("Mount failed");
                // autoyast tried to mount a NFS directory which failed
                GET_error = sformat(_("Mounting %1 failed."), Host + ":" + dirname(Path) );
                return (false);
            }

            string copyCmd = "/bin/cp " + mount_point + "/" + basename(Path) +
                " " + Localfile;
            y2milestone("Copy Command: %1", copyCmd);
            if (WFM::Execute (.local.bash, copyCmd ) == 0)
            {
                GET_error = "";
                ok = true;
            }
            else
            {
                // autoyast tried to copy a file via NFS which failed
                GET_error = sformat(_("Remote file %1 cannot be retrieved"),  mount_point + "/"+ basename(Path) );
                y2error("remote file %1 can't be retrieved",  mount_point + "/"
                        + basename(Path));

            }

            WFM::Execute(.local.umount, mount_point);

        }
        else if (Scheme == "cifs")  // CIFS
        {
            if (!(boolean)SCR::Execute(.target.mount,
                        [ "//" + Host + dirname(Path), mount_point ], "-t cifs -o guest,ro" ))
            {
                y2warning("Mount failed");
                // autoyast tried to mount a NFS directory which failed
                GET_error = sformat(_("Mounting %1 failed."), "//" + Host + dirname(Path) );
                return (false);
            }

            string copyCmd = "/bin/cp " + mount_point + "/" + basename(Path) +
                " " + Localfile;
            y2milestone("Copy Command: %1", copyCmd);
            if (WFM::Execute (.local.bash, copyCmd ) == 0)
            {
                GET_error = "";
                ok = true;
            }
            else
            {
                // autoyast tried to copy a file via NFS which failed
                GET_error = sformat(_("Remote file %1 cannot be retrieved"),  mount_point + "/"+ basename(Path) );
                y2error("remote file %1 can't be retrieved",  mount_point + "/"
                        + basename(Path));

            }

            WFM::Execute(.local.umount, mount_point);

        }
        else if (Scheme == "floppy")
        {
            if (StorageDevices::FloppyReady())
            {
                WFM::Execute(.local.mount, [StorageDevices::FloppyDevice(), mount_point]);

                if (WFM::Execute (.local.bash, "/bin/cp " + mount_point + "/" + Path + " " + Localfile) != 0)
                {
                    y2error("file  %1 can't be retrieved", mount_point + "/" + Path );
                }
                else
                {
                    GET_error = "";
                    ok = true;
                }
                SCR::Execute(.target.umount, mount_point);
            }
        }
        else if (Scheme == "device" || Scheme == "usb" ) // Device or USB
        {
            if ( Path != "")
            {
                list<string> deviceList = [];
                if( Host == "" ) {
                    list<map> disks =  (Scheme == "device") ? (list<map>)SCR::Read(.probe.disk) : (list<map>)SCR::Read(.probe.usb);
                    foreach( map m, disks, ``{
                        if( Scheme == "usb" &&
                            m["bus"]:"USB" != "SCSI" )
                            continue;
                        if( haskey( m, "dev_name") ) {
                            integer i = 0;
                            string dev = m["dev_name"]:"";
                            deviceList = add( deviceList, substring( dev, 5 ) ); // not uncommon for USB sticks to have no partition
                            do {
                                i = i + 1;
                                dev = m["dev_name"]:"" + sformat("%1",i);
                                if( SCR::Read(.target.lstat, dev) != $[] )
                                    deviceList = add( deviceList, substring( dev, 5 ) );
                            } while( SCR::Read(.target.lstat, dev) != $[] || i < 5 );
                        }
                    });
                    y2milestone("devices to look on: %1", deviceList);
                } else {
                    /*
                      sometimes we have devices like /dev/cciss/c1d0p5
                      those "nested" devices will be catched here
                      as long as we find a directory where we expect a device,
                      we cut down the Path and enhance the Host (device name)
                    */
                    while( SCR::Read( .target.dir, "/dev/"+Host ) != nil ) {
                        y2milestone("nested device found");
                        list<string> l = splitstring( Path, "/" );
                        Host = Host + "/" + l[0]:"";
                        l = remove(l,0);
                        Path = mergestring(l,"/");
                        y2milestone("Host=%1 Path=%2",Host,Path);
                    }
                    // catching nested devices done
                    deviceList = [ Host ];
                }
                foreach( string Host, deviceList, ``{
                    y2milestone("looking for profile on %1", Host);
                    string mounts = (string)(SCR::Read (.target.string, "/proc/mounts"));
                    list<string> mount_list = splitstring( mounts, "\n" );
                    boolean already_mounted = false;
                    foreach( string m, mount_list, ``{
                        list<string>  entries = splitstring( m, " " );
                        if( entries[0]:"" == "/dev/"+Host ) {
                            already_mounted = true;
                            mount_point = entries[1]:"";
                            break;
                        }
                    });
                    y2milestone("already mounted=%1 mountpoint=%2",already_mounted,mount_point);
                    if( ! already_mounted &&
                        !(boolean)WFM::Execute(.local.mount, [sformat("/dev/%1", Host),
                                        mount_point]) ) {
                        y2milestone("%1 is not mounted and mount failed", sformat("/dev/%1", Host));
                        GET_error = sformat(_("%1 is not mounted and mount failed"), sformat("/dev/%1", Host));
                        continue;
                    }

                    if (WFM::Execute (.local.bash, "/bin/cp " + mount_point +  "/" + Path + " " + Localfile) != 0 )
                    {
                        // autoyast tried to copy a file but that file can't be found
                        GET_error = sformat(_("File %1 cannot be found"),mount_point + Path);
                        y2milestone("file %1 can't be found",  mount_point + Path);
                    }
                    else
                    {
                        GET_error = "";
                        ok = true;
                        y2milestone("found");
                    }
                    if( ! already_mounted )
                        WFM::Execute(.local.umount, mount_point);
                    if( ok == true )
                        break;
                });
            }
        }
        else if (Scheme == "tftp") // Device
        {
            if (TFTP::Get( Host,  Path, Localfile ))
            {
                GET_error = "";
                ok = true;
            }
            else
            {
                GET_error = sformat(_("Cannot find URL '%1' via protocol TFTP."),Host+":"+Path);
                y2error("file %1 can't be found", Path );
            }
        }
        else
        {
            // the user wanted autoyast to fetch it's profile via an unknown protocol
            GET_error = sformat(_("Unknown protocol %1."),Scheme);
            y2error("Protocol not supported");
            ok = false;
        }
        return ( ok );
    }


    /**
     * Get a file froma  given URL
     */
    boolean GetURL(string url, string target)
    {
        AutoinstConfig::urltok=URL::Parse(url);
        map toks = AutoinstConfig::urltok;
        return Get(toks["scheme"]:"", toks["host"]:"", toks["path"]:"", target);
    }

}

ACC SHELL 2018