diff --git a/src/include/nfs/ui.ycp b/src/include/nfs/ui.ycp index 9499ae3..a332468 100644 --- a/src/include/nfs/ui.ycp +++ b/src/include/nfs/ui.ycp @@ -298,26 +298,10 @@ { if (hosts == nil) { - //newer, shinier, better rpcinfo from rpcbind (#450056) - string prog_name = "/sbin/rpcinfo"; - string delim = ""; - - //fallback from glibc (uses different field separators, grr :( ) - if( !FileUtils::Exists(prog_name) ) - { - prog_name = "/usr/sbin/rpcinfo"; - delim = "-d ' ' "; - } - // label message UI::OpenDialog(`Label(_("Scanning for hosts on this LAN..."))); - // #71064 - // this works also if ICMP broadcasts are ignored - string cmd = prog_name + " -b mountd 1 | cut " + delim + "-f 2 | sort -u"; - map out = (map) SCR::Execute (.target.bash_output, cmd); - hosts = filter (string s, splitstring (out["stdout"]:"", "\n"), ``( s != "")); + hosts = Nfs::ProbeServers(); UI::CloseDialog(); - } if( hosts == [] || hosts == nil ) { @@ -358,32 +342,9 @@ which probably blocks the network scanning."); sformat (_("Getting directory list for \"%1\"..."), server) )); - list dirs = []; - - // showmounts does not work for nfsv4 (#466454) - if (v4) - { - string tmpdir = Nfs::Mount(server, "/", nil, "ro", "nfs4"); - - // This is completely stupid way how to explore what can be mounted - // and I even don't know if it is correct. Maybe 'find tmpdir -xdev -type d' - // should be used instead. No clue :( - dirs = maplist( string dirent, (list ) SCR::Read(.target.dir, tmpdir), { - return "/" + dirent; - }); - dirs = prepend(dirs, "/"); - Nfs::Unmount( tmpdir ); - } - else - { - dirs = (list) SCR::Read (.net.showexports, server); - } - - if (dirs == nil) - { - dirs = ["internal error"]; - } + list dirs = Nfs::ProbeExports (server, v4); UI::CloseDialog (); + string dir = ChooseExport (dirs); if (dir != nil) { diff --git a/src/modules/Nfs.ycp b/src/modules/Nfs.ycp index 995820c..912e34c 100644 --- a/src/modules/Nfs.ycp +++ b/src/modules/Nfs.ycp @@ -21,7 +21,8 @@ textdomain "nfs"; - import "Mode";; + import "FileUtils"; + import "Mode"; import "Report"; import "Service"; import "Summary"; @@ -63,7 +64,7 @@ global list required_packages = [ "nfs-client" ]; /** - * eg.: [ $["spec": "moon:/cheese", file: "/mooncheese", "mntopts": "defaults"], ...] + * eg.: [ $["spec": "moon:/cheese", file: "/mooncheese", "mntops": "defaults"], ...] */ global list > nfs_entries = []; @@ -614,7 +615,64 @@ the NFS client configuration.\n")); } + /** + * Probe the LAN for NFS servers. + * Uses RPC broadcast to mountd. + * @return a list of hostnames + */ + global define list ProbeServers() { + //newer, shinier, better rpcinfo from rpcbind (#450056) + string prog_name = "/sbin/rpcinfo"; + string delim = ""; + + //fallback from glibc (uses different field separators, grr :( ) + if( !FileUtils::Exists(prog_name) ) + { + prog_name = "/usr/sbin/rpcinfo"; + delim = "-d ' ' "; + } + // #71064 + // this works also if ICMP broadcasts are ignored + string cmd = prog_name + " -b mountd 1 | cut " + delim + "-f 2 | sort -u"; + map out = (map) SCR::Execute (.target.bash_output, cmd); + list hosts = filter (string s, splitstring (out["stdout"]:"", "\n"), ``( s != "")); + return hosts; + } + /** + * Probe a server for its exports. + * @param server IP or hostname + * @param v4 Use NFSv4? + * @return a list of exported paths + */ + global list ProbeExports(string server, boolean v4) { + list dirs = []; + + // showmounts does not work for nfsv4 (#466454) + if (v4) + { + string tmpdir = Mount(server, "/", nil, "ro", "nfs4"); + + // This is completely stupid way how to explore what can be mounted + // and I even don't know if it is correct. Maybe 'find tmpdir -xdev -type d' + // should be used instead. No clue :( + dirs = maplist( string dirent, (list ) SCR::Read(.target.dir, tmpdir), { + return "/" + dirent; + }); + dirs = prepend(dirs, "/"); + Unmount( tmpdir ); + } + else + { + dirs = (list) SCR::Read (.net.showexports, server); + } + + if (dirs == nil) + { + dirs = ["internal error"]; + } + return dirs; + } }