/**
 * File:
 *   routines.ycp
 *
 * Module:
 *   Configuration of nfs server
 *
 * Summary:
 *   Network NFS routines
 *
 * Authors:
 *   Jan Holesovsky <kendy@suse.cz>
 *   Dan Vesely <dan@suse.cz>
 *   Martin Vidner <mvidner@suse.cz>
 *
 * $Id: routines.ycp 20767 2005-01-14 16:52:43Z jsuchome $
 *
 * Network NFS routines
 *
 */

{
    textdomain "nfs_server";
    import "Popup";
    import "Report";

    /**
     * Split the allowed host specification
     * @param hosts	"hosts(opts)"
     * @return		["hosts", "opts"]
     */
    define list<string> AllowedToHostsOpts(string hosts) ``{
	integer  brpos = findfirstof(hosts, "(");
	string opts = "";
	if (brpos != nil) {
	    opts = substring(hosts, brpos+1);
	    hosts = substring(hosts, 0, brpos);

	    brpos = findfirstof(opts, ")");
	    if (brpos != nil)
		opts = substring(opts, 0, brpos);
	}
	return [ hosts, opts ];
    }

    /**
     * @param allowed	a list of allowed host specifications
     * @return		a ui table list of items
     * @example AllowedTableItems (["*.local.domain(ro)", "@trusted(rw)"])
     */
    define list<term> AllowedTableItems(list<string> allowed) ``{
	integer count = 0;
	return maplist(string str, allowed, ``{
	    list<string> sp = AllowedToHostsOpts(str);
	    term it = `item(`id(count), sp[0]:"" + " ", sp[1]:"" + " ");

	    count = count+1;
	    return it;
	});
    }

    /**
     * Find entry in exports according to the mountpoint
     * @param exports	list of exports
     * @param mp	mount point
     * @return		a list of allowed host specifications or nil if not found
     */
    define list<string> FindAllowed(list<map> exports, string mp) ``{
	list<map> flt = filter(map ent, exports, ``{
	    return ent["mountpoint"]:"" == mp;
	});
	if (flt == nil || size(flt) == 0)
	    return nil;

	return (list<string>) (flt[0, "allowed"]:nil);
    }

    /**
     * @param exports	list of exports
     * @return		a ui table list of mountpoints, id'ed by themselves
     */
    define list<term> ExportsItems(list<map> exports) ``{
	return maplist(map entry, exports, ``{
	    string str = entry["mountpoint"]:"";
	    return `item(`id(str), str+" ");
	});
    }

    /**
     * @param exports	list of exports
     * @return		a SelectionBox for the mountpoints, `id(`exportsbox)
     */
    define term ExportsSelBox(list<map> exports) ``{
	return `SelectionBox(`id(`exportsbox), `opt(`notify),
			     // selection box label
			     _("Dire&ctories"), ExportsItems(exports));
    }

    /**
     * Check for the validity of client specification:
     * fewer than 70 chars, no blanks.
     * If invalid, a message is displayed.
     * @param name	options
     * @return		whether valid
     */
    define boolean CheckNoSpaces(string name) ``{
	if (size(name) < 70 &&
	    findfirstof(name, " \t") == nil)
	    return true;
	else
	    // error popup message
	    Report::Message(sformat(_("You entered a wrong wild card or options string.
It must be shorter than 70 characters and it
must not contain spaces.
")));
	return false;
    }

    /**
     * Check for the validity of export options:
     * [A-Za-z0-9=/.,_-]*
     * If invalid, a message is displayed.
     * @param options	spaces and parentheses already removed
     * @return		whether valid
     */
    define boolean CheckExportOptions (string options) ``{
	if (regexpmatch (options, "[^A-Za-z0-9=/.,_-]"))
	{
	    // error popup message
	    Report::Error (_("Incorrect option format:
Only letters, digits and the characters =/.,_- are allowed."));
	    return false;
	}
	return true;
    }

    /**
     * Check for the validity of export options: only those listed in
     * exports(5) are accepted.
     * Unused - to allow not only nfs-utils but also nfs-server.
     * If invalid, a message is displayed.
     * @param options	spaces and parentheses already removed
     * @return		whether valid
     */
    define boolean CheckExportOptions_strict (string options) ``{
	list<string> o1 = ["secure", "insecure", "rw", "ro", "sync", "async",
		   "no_wdelay", "wdelay", "nohide", "hide",
		   "no_subtree_check", "subtree_check",
		   "insecure_locks", "secure_locks", "no_auth_nlm", "auth_nlm",
		   "root_squash", "no_root_squash",
		   "all_squash", "no_all_squash"];
	list<string> o_value = ["anonuid", "anongid"];
	list<string> opts = splitstring (options, ",");

	boolean ret = true;
	opts = filter (string e, opts, ``(!contains (o1, e)));
	foreach (string e, opts, ``{
	    list<string> opt = splitstring (e, "=");
	    if (!contains (o_value, opt[0]:""))
	    {
		// error popup message
		Popup::Error (sformat (_("Unknown option: '%1'"), e));
		ret = false;
	    }
	    else if (size (opt) != 2 ||
		     !regexpmatch (opt[1]:"", "[0-9]+"))
	    {
		// error popup message
		Popup::Error (sformat (_("Wrong option format: '%1'"), e));
		ret = false;
	    }
	});
	return ret;
    }

    /**
     * Replaces 'allowed' list in exports (for specified mountpoint)
     * @param exports		exports list
     * @param mountpoint	mount point
     * @param allowed		new allowed host list for that mout point
     * @return			modified exports list
     */
    define list<map<string,any> > ReplaceInExports(list<map<string,any> > exports, string mountpoint, list<string> allowed) ``{
	return maplist(map<string,any> entry, exports, ``{
	    if (entry["mountpoint"]:"" == mountpoint)
		entry = add(entry, "allowed", allowed);
	    return entry;
	});
    }

}
