ip_in_range 0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d47e8fd962fb2d1255beaf5033a5c2a46bfb11a261b11e4424034b8827d8af9b
4
+ data.tar.gz: 5214a27f60c1a1dd87eb2be2d6e45374205272b10fa6ad4885eea2ccadb1bb8a
5
+ SHA512:
6
+ metadata.gz: 42804793ba4ade8ad7e6bd8144b08535b6e626ac0a0962e78829c72c8c12444cec92d95f30b0ecfe66c83f1109660476253898a0acfd7707a3834fce6556b04e
7
+ data.tar.gz: 90639f79f3dc5d8dc678c04a39b634e63aad140364e573780dace104b17782a160526efeb9eead32620b32d1d4129522eb21abdf115a8ee2bfe7428cb68f842b
data/bin/ip_in_range ADDED
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: UTF-8
3
+ =begin
4
+ /***************************************************************************
5
+ * ©2021-2021, Michael Uplawski <michael.uplawski@uplawski.eu> *
6
+ * *
7
+ * This program is free software; you can redistribute it and/or modify *
8
+ * it under the terms of the GNU General Public License as published by *
9
+ * the Free Software Foundation; either version 3 of the License, or *
10
+ * (at your option) any later version. *
11
+ * *
12
+ * This program is distributed in the hope that it will be useful, *
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
+ * GNU General Public License for more details. *
16
+ * *
17
+ * You should have received a copy of the GNU General Public License *
18
+ * along with this program; if not, write to the *
19
+ * Free Software Foundation, Inc., *
20
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21
+ ***************************************************************************/
22
+ =end
23
+ require_relative '../lib/ip_range'
24
+ require_relative '../lib/email'
25
+ require_relative '../lib/logging'
26
+ require_relative '../lib/file_checking'
27
+
28
+ self.extend(Logging)
29
+ log = init_logger(STDOUT)
30
+
31
+ def usage
32
+ usage = "\tUsage: " << $0 << ' first_in_range last_in_range ip_to_check'
33
+ usage << "\n\tExample: " << $0 << ' 192.168.1.100 192.168.1.255 192.168.10.100'
34
+ usage << "\n\t\t to verify Received-headers: cat mail | " << $0 << " first_in_range last_in_range"
35
+ usage << "\n\t\t or: cat mail | " << $0 << " <file>"
36
+ usage << "\n\t\t where \"file\" contains a list of ip-ranges."
37
+ end
38
+
39
+ # primitive as there is nothing to gain from more complexity
40
+ IPR = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
41
+
42
+ # 1) first last ip_to_check
43
+ if ARGV.length >= 3
44
+ ip_range = IPRange.new(ARGV)
45
+ exit ip_range.in_range?(ARGV[2]).to_s
46
+ # 2) first last (mail is piped-in)
47
+ elsif ARGV.length == 2
48
+ ip_range = IPRange.new(ARGV)
49
+ ARGV.clear
50
+ if(!STDIN.tty?)
51
+ mail = FMail.new(ARGF.read)
52
+ else
53
+ log.error('No data to compare from STDIN – aborting!')
54
+ exit false
55
+ end
56
+ ips = mail.received.collect{|r| r.scan(IPR)}
57
+ ips.flatten!
58
+ log.debug( 'ips: ' << ips.join(', '))
59
+ ips.each do |ip|
60
+ exit true if ip_range.in_range?(ip)
61
+ end
62
+ log.info('not in range')
63
+ exit false
64
+ # 3) a text-file with ip-ranges, mail is piped in
65
+ elsif ARGV.length == 1
66
+ list_file = ARGV[0]
67
+ ARGV.clear
68
+ if(!STDIN.tty?)
69
+ mail = FMail.new(ARGF.read)
70
+ else
71
+ log.error('No data waiting on STDIN – aborting!')
72
+ exit false
73
+ end
74
+ msg = File_Checking::file_check(list_file, [:file, :exist, :readable])
75
+ if msg
76
+ log.error( "File #{list_file} is unuseable: #{msg}. Aborting!" )
77
+ exit false
78
+ end
79
+ ranges = File.readlines(list_file)
80
+ ranges.each do |l|
81
+ log.debug( "line is " << l)
82
+ if(!l.strip.empty?)
83
+ begin
84
+ log.debug 'trying to extract an IP-range'
85
+ range = l.scan(IPR).flatten
86
+ log.debug('testing range ' << range.to_s)
87
+ rescue ArgumentError => msg
88
+ er = 'Cannot interpret IP-range ' << l
89
+ er << ': ' << msg
90
+ log.error(er)
91
+ rescue Exception => msg
92
+ log.error(msg)
93
+ else
94
+ log.debug( "range is " << range.to_s )
95
+ ip_range = IPRange.new(range)
96
+ log.debug( "testing ip_range " << ip_range.vrange.to_s )
97
+ ips = mail.received.collect{|r| r.scan(IPR)}
98
+ ips.flatten!
99
+ log.debug( 'ips: ' << ips.join(', ') )
100
+ ips.each do |ip|
101
+ isso = ip_range.in_range?(ip)
102
+ msg = 'ip ' << ip << (isso ? ' is ' : ' is not ' ) << 'in range: ' << l
103
+ if isso
104
+ log.info(msg)
105
+ else
106
+ log.debug(msg)
107
+ end
108
+ exit isso if isso
109
+ end
110
+ end
111
+ end
112
+ end
113
+ exit false
114
+ else
115
+ log.warn( "ERROR! Arguments missing" )
116
+ log.info( usage)
117
+ exit false
118
+ end
@@ -0,0 +1,19 @@
1
+ require_relative "lib/version"
2
+ require 'date'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.version = VERSION
6
+ s.name = File.basename(__FILE__, '.gemspec')
7
+ s.date = Date.today.strftime('%F')
8
+ s.summary = SUMMARY
9
+ s.description = "Verify that an IP is in a range"
10
+ s.authors = AUTHORS
11
+ s.email = EMAIL
12
+ s.files = %w~ip_in_range~.collect{|f| 'bin/' << f} + %w~log.conf ip_range.rb version.rb file_checking.rb logging.rb email.rb~.collect{|f| 'lib/' << f} + %w~ip_in_range.gemspec~.collect{|f|f} + %w~~.collect{|f| 'doc/' << f}
13
+ s.homepage = ''
14
+ #s.requirements = ''
15
+ #s.add_runtime_dependency ''
16
+ s.executables = 'ip_in_range'
17
+ s.license = 'GPL-3.0'
18
+ s.required_ruby_version = '>= 2.7'
19
+ end
data/lib/email.rb ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: UTF-8
3
+ =begin
4
+ /***************************************************************************
5
+ * ©2021-2021, Michael Uplawski <michael.uplawski@uplawski.eu> *
6
+ * *
7
+ * This program is free software; you can redistribute it and/or modify *
8
+ * it under the terms of the GNU General Public License as published by *
9
+ * the Free Software Foundation; either version 3 of the License, or *
10
+ * (at your option) any later version. *
11
+ * *
12
+ * This program is distributed in the hope that it will be useful, *
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
+ * GNU General Public License for more details. *
16
+ * *
17
+ * You should have received a copy of the GNU General Public License *
18
+ * along with this program; if not, write to the *
19
+ * Free Software Foundation, Inc., *
20
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21
+ ***************************************************************************/
22
+ =end
23
+
24
+ require_relative 'logging'
25
+ require 'mail'
26
+
27
+ class FMail
28
+ extend Logging
29
+ @@log = init_logger(STDOUT)
30
+
31
+ def initialize(mail_text)
32
+ @log = @@log
33
+ if !mail_text || mail_text.empty?
34
+ @log.error('No mail-text provided. Aborting!')
35
+ exit false
36
+ end
37
+ @mail_text = mail_text
38
+ # @log.debug('mail text is ' << @mail_text)
39
+ extr_received
40
+ end
41
+
42
+ attr_reader :received
43
+
44
+ private
45
+
46
+ def extr_received
47
+ begin
48
+ @mail = Mail::read_from_string(@mail_text)
49
+ rescue Exception => ex
50
+ @log.error("cannot analyze this mail: " << ex.message)
51
+ @log.error("Aborting!")
52
+ exit false;
53
+ end
54
+ headers = @mail.header_fields
55
+ @received = headers.filter{|h| h.name == 'Received'}.collect{|h| h.unparsed_value}
56
+ @log.debug("found received-headers: " << @received.to_s)
57
+ end
58
+
59
+ end
60
+
61
+ ############ TEST ##############
62
+ if __FILE__ == $0
63
+ ml = FMail.new(ARGF.read)
64
+ end
@@ -0,0 +1,119 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2011-2021 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
+ * *
6
+ * This program is free software; you can redistribute it and/or modify *
7
+ * it under the terms of the GNU General Public License as published by *
8
+ * the Free Software Foundation; either version 3 of the License, or *
9
+ * (at your option) any later version. *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
+ * GNU General Public License for more details. *
15
+ * *
16
+ * You should have received a copy of the GNU General Public License *
17
+ * along with this program; if not, write to the *
18
+ * Free Software Foundation, Inc., *
19
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
+ ***************************************************************************/
21
+ =end
22
+
23
+ require 'filemagic'
24
+
25
+ =begin
26
+ A module to facilitate frequently occuring checks on
27
+ file-system objects
28
+ =end
29
+ module File_Checking
30
+
31
+ @@text_messages = {
32
+ :exist? => "does not exist!",
33
+ :exist => "does not exist!",
34
+ :readable? => "is not readable!",
35
+ :readable => "is not readable!",
36
+ :executable? => "is not executable!",
37
+ :executable => "is not executable!",
38
+ :writable? => "is not writable!",
39
+ :writable => "is not writable!",
40
+ :directory? => "is not a directory!",
41
+ :directory => "is not a directory!",
42
+ :file? => "is not a file!",
43
+ :file => "is not a file!",
44
+ # different thing
45
+ :type => "is not of the sought file-type (not '%s', but '%s')!",
46
+ :mime => "does not have the sought mime-type (not '%s', but '%s')!",
47
+ }
48
+
49
+ # Checks if the file with the name from the first
50
+ # parameter has the properties, listed in the second.
51
+ # The messages parameter is an array of one or several
52
+ # of :exist?, :readable?, :writable?, :directory? or
53
+ # their string-representations, respectively.
54
+ # Returns nil in case of success, otherwise an
55
+ # informative message, describing the first negative
56
+ # test-result.
57
+ def file_check(file, *messages)
58
+ File_Checking.file_check(file, *messages)
59
+ end
60
+
61
+ # Checks if the file with the name from the first
62
+ # parameter has the properties, listed in the second.
63
+ # The messages parameter is an array of one or all
64
+ # of :exist?, :readable?, :writable?, :directory? or
65
+ # their string-representations, respectively.
66
+ # Returns nil in case of success, otherwise an
67
+ # informative message, describing the first negative
68
+ # test-result.
69
+ def self.file_check(file, *messages)
70
+ msg = nil
71
+ if(file && messages.respond_to?(:to_ary) && !messages.empty?)
72
+ messages.each do |k|
73
+ if( k != :mime && k != :type)
74
+ if(! k.to_s.end_with?('?'))
75
+ k = (k.to_s << '?').to_sym
76
+ end
77
+ @log.debug ('checking ' << k.to_s) if @log
78
+ if(msg == nil && File.respond_to?(k) && ! File.send(k, file.to_s))
79
+ msg = "#{file} #{@@text_messages[k.to_sym]}"
80
+ end
81
+ end
82
+ end
83
+ end
84
+ msg
85
+ end
86
+
87
+ def self.mime_check(file, mime_type)
88
+ fm = FileMagic.mime
89
+ fd = fm.fd(File.new(file) ).split(';')[0]
90
+ if fd != mime_type.strip
91
+ return file.dup << ' ' << (@@text_messages[:mime] %[mime_type, fd])
92
+ end
93
+ return nil
94
+ end
95
+
96
+ def self.magic_check(file, magic)
97
+ fm = FileMagic.fm
98
+ fd = fm.fd(File.new(file) ).split(';')[0]
99
+ if fd != magic.strip
100
+ return file.dup << ' ' << (@@text_messages[:type] %[magic, fd])
101
+ end
102
+ return nil
103
+ end
104
+
105
+ end # module
106
+
107
+ =begin
108
+ # example
109
+
110
+ include File_Checking
111
+ msg = file_check('some_file.txt', [:exist?, :readable?, 'writable'])
112
+ # same as
113
+ # msg = file_check('some_file.txt', [:exist, :readable, 'writable?'])
114
+
115
+ msg ||= magic_check('some_file.txt', [:type?], 'OpenDocument Text'
116
+ msg ||= mime_check('some_file.txt', [:mime?], 'application/vnd.oasis.opendocument.text'
117
+ puts msg if msg
118
+ =end
119
+ # E O F
data/lib/ip_range.rb ADDED
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: UTF-8
3
+ =begin
4
+ /***************************************************************************
5
+ * ©2021-2021, Michael Uplawski <michael.uplawski@uplawski.eu> *
6
+ * *
7
+ * This program is free software; you can redistribute it and/or modify *
8
+ * it under the terms of the GNU General Public License as published by *
9
+ * the Free Software Foundation; either version 3 of the License, or *
10
+ * (at your option) any later version. *
11
+ * *
12
+ * This program is distributed in the hope that it will be useful, *
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
+ * GNU General Public License for more details. *
16
+ * *
17
+ * You should have received a copy of the GNU General Public License *
18
+ * along with this program; if not, write to the *
19
+ * Free Software Foundation, Inc., *
20
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21
+ ***************************************************************************/
22
+ =end
23
+
24
+ require_relative 'logging'
25
+ class IPRange
26
+ extend Logging
27
+ @@log = init_logger(STDOUT)
28
+
29
+ private
30
+
31
+ # return ip as Integer
32
+ def ip_to_number(ip)
33
+ nibbles = ip.split('.')
34
+ nibbles = nibbles.collect {|n| n.to_i}
35
+ if nibbles.size == 4
36
+ ( (nibbles[0] * 256 + nibbles[1] ) * 256 + nibbles[2] ) * 256 + nibbles[3]
37
+ else
38
+ @log.error(ip.dup << " is not an IP-address!")
39
+ return nil
40
+ end
41
+ end
42
+
43
+ public
44
+
45
+ # check IP in range ?
46
+ def in_range?(cip)
47
+ (@first..@last) === ip_to_number(cip)
48
+ end
49
+
50
+ def irange()
51
+ [@first, @last]
52
+ end
53
+
54
+ # create an IP-range
55
+ def initialize(args)
56
+ @log = @@log
57
+ if args && args.length >= 2
58
+
59
+ #first IP
60
+ @first = ip_to_number args[0]
61
+ #last IP
62
+ @last = ip_to_number args[1]
63
+ if @last && @first && ( @last < @first )
64
+ @log.error('ERROR! Last IP is smaller than first. Aborting!')
65
+ exit false
66
+ end
67
+ @vrange = args[0,2]
68
+ end
69
+ end
70
+
71
+ attr_reader :vrange, :first, :last
72
+ end
73
+ ######### TEST #############
74
+ if __FILE__ == $0
75
+ rg = IPRange.new(['192.168.2.33', '192.168.255.150'])
76
+ puts rg.first
77
+ puts rg.last
78
+ puts rg.in_range? '192.168.1.35'
79
+ puts rg.in_range? '192.168.2.35'
80
+
81
+ puts rg.vrange.join(' - ')
82
+ puts rg.irange.join(' - ')
83
+ end
84
+
data/lib/log.conf ADDED
@@ -0,0 +1,56 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2013 - 2019 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
+ * *
6
+ * This program is free software; you can redistribute it and/or modify *
7
+ * it under the terms of the GNU General Public License as published by *
8
+ * the Free Software Foundation; either version 3 of the License, or *
9
+ * (at your option) any later version. *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
+ * GNU General Public License for more details. *
15
+ * *
16
+ * You should have received a copy of the GNU General Public License *
17
+ * along with this program; if not, write to the *
18
+ * Free Software Foundation, Inc., *
19
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
+ ***************************************************************************/
21
+
22
+ A simplified logger configuration. Set the level for each individual logger
23
+ below. Choose a different log-device or log-file if you like. Keep the
24
+ formatting intact. Do not change other sections of this file.
25
+ =end
26
+
27
+ # Do not touch from here ----->
28
+ require 'logger'
29
+
30
+ debug = Logger::DEBUG
31
+ info = Logger::INFO
32
+ error = Logger::ERROR
33
+ fatal = Logger::FATAL
34
+ warn = Logger::WARN
35
+ unknown = Logger::UNKNOWN
36
+ {
37
+ # <---------------- to here !
38
+
39
+ # Enter your settings here, but take into consideration that not all
40
+ # the named classes will really produce readable output. Well, you can
41
+ # always try... Either name just the log-level or make the log-level
42
+ # precede the output-device or output-file like in the examples.
43
+
44
+ # Example: naming a log-file
45
+ #
46
+ # :HtmlBuilder => [info, 'C:\temp\htmlbuilder.log'],
47
+ #
48
+ # :HtmlBuilder => [debug, '/tmp/htmlbuilder.log'],
49
+
50
+ :FMail => info,
51
+ :IPRange => info,
52
+ :TopLevel => debug,
53
+
54
+ # And ignore the remainder, too.
55
+ }
56
+ #eof
data/lib/logging.rb ADDED
@@ -0,0 +1,198 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2011-2019 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
+ * *
6
+ * This program is free software; you can redistribute it and/or modify *
7
+ * it under the terms of the GNU General Public License as published by *
8
+ * the Free Software Foundation; either version 3 of the License, or *
9
+ * (at your option) any later version. *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
+ * GNU General Public License for more details. *
15
+ * *
16
+ * You should have received a copy of the GNU General Public License *
17
+ * along with this program; if not, write to the *
18
+ * Free Software Foundation, Inc., *
19
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
+ ***************************************************************************/
21
+ =end
22
+ require 'logger'
23
+
24
+ =begin Creates a member @log and precede its output with the name of the class
25
+ of the object.
26
+ Example for a class-level logger:
27
+ # --------------------
28
+ class TClass
29
+ self.extend(Logging)
30
+ @@log = init_logger(STDOUT)
31
+ def test_log
32
+ @@log.info('class-level logger called from instance: ' << @@log.to_s)
33
+ @log = @@log
34
+ @log.info('AGAIN: class-level logger called from instance: ' << @log.to_s)
35
+ end
36
+ def self::test_log
37
+ @log.info('class-level logger called from class: ' << @log.to_s)
38
+ @@log.info('AGAIN: class-level logger called from class: ' << @@log.to_s)
39
+ end
40
+ end
41
+ #---------------------
42
+ Example for a object-level logger:
43
+ ATTN! This means 1 logger per object.
44
+ # --------------------
45
+ class TClass
46
+ include Logging
47
+ def initialize
48
+ init_logger(STDOUT, Logger::DEBUG)
49
+ end
50
+ def test_log
51
+ @log.debug('called test_log() ')
52
+ end
53
+ end
54
+ =end
55
+ module Logging
56
+
57
+ @@have_log = false
58
+ @@LOG_CONF = File.dirname(File.absolute_path(__FILE__)) << File::Separator << 'log.conf'
59
+
60
+ # Call this method in an instance-method (e.g. initialize() ) to define the
61
+ # object-level logger; i.e. an object-specific member @log.
62
+ # Call this method within the class-definition for a class-level logger; i.e.
63
+ # a member @log for class-level acces.
64
+ # The method returns the logger, so you can actually do what you want with it.
65
+ def init_logger(target = STDOUT, level = Logger::INFO)
66
+ # Prepare for a class-level logger. This is actually quite cool.
67
+
68
+ # ---> Ingeniuous code starts here
69
+ cn = (self.class == Class ? name : self.class.name)
70
+ # <--- Ingeniuous code ends here
71
+
72
+ # 11/2019
73
+ if (cn == 'Object')
74
+ cn = 'Top Level'
75
+ end
76
+
77
+ # allow to override the set log-levels with an
78
+ # external configuration (log.conf).
79
+ log_conf(cn)
80
+ # Or use the defaults as set here or elsewhere...
81
+
82
+ @level ||= level
83
+ @target ||= target
84
+
85
+ @log = Logger.new(@target)
86
+ @log.level = @level
87
+
88
+ @log.formatter = proc do |severity, datetime, progname, msg|
89
+ t = Time.now
90
+ "#{cn}: #{severity} #{t.hour}-#{t.min}-#{t.sec}: #{msg}\n"
91
+ end
92
+ if ! @@have_log
93
+ @log.debug cn.dup << ' reading logging-configuration from ' << @@LOG_CONF
94
+ @@have_log = true
95
+ @log.debug('level is ' << level.to_s)
96
+ end
97
+ return @log
98
+ end
99
+
100
+ # Set the log-target to an IO object.
101
+ def log_target=(target)
102
+ @target = target
103
+ @log = Logger.new(@@target)
104
+ @log.level = @level
105
+ end
106
+
107
+ # set the log-level
108
+ def log_level=(level)
109
+ @level = level
110
+ @log.level = @level
111
+ end
112
+
113
+ private
114
+
115
+ # Override or set the log-level and target-device, as set in a file 'log.conf'.
116
+ # I do not like the look of this, but it works just the way I want it to.
117
+ # "HEAVANS! Isn't there a standard way to do this in Ruby, for Christ's sake?", you say.
118
+ # Heck, I don't care. <= Read that again, I say.
119
+ def log_conf(cn = nil)
120
+ config = level = target = nil
121
+ # puts 'log-config is in ' << @@LOG_CONF
122
+ if(File::exist?(@@LOG_CONF) )
123
+ begin
124
+ conf = File.read(@@LOG_CONF)
125
+ config = instance_eval(conf)
126
+ rescue Exception => ex
127
+ STDERR.puts "WARNING! Cannot evaluate the logger-configuration!" << ' ' << ex.message
128
+ STDERR.puts "Default log-levels apply."
129
+ end
130
+ else
131
+ puts "Default log-levels apply."
132
+ end
133
+
134
+ if(config && config.respond_to?(:to_hash) )
135
+ config.default = nil
136
+ if cn
137
+ config = config[cn.to_sym]
138
+ else
139
+ config = config[self.class.name.to_sym]
140
+ end
141
+
142
+ if(config )
143
+ if(config.respond_to?(:to_ary) && config.size == 2)
144
+ @level, @target = config
145
+ @target.downcase!
146
+ logdir = File.dirname(@target)
147
+ [:exist?, :directory?, :writable?].each do |m|
148
+ msg = File.send(m, logdir)
149
+ if(msg)
150
+ STDERR.puts "WARNING! A logfile for '%s' cannot be written to %s (%s)!" %[self.class.name, logdir, msg]
151
+ @target = nil
152
+ end
153
+ end
154
+ else
155
+ @level = config
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ ######### test
163
+ if __FILE__ == $0
164
+ class TClass
165
+ # class level ---->
166
+ self.extend(Logging)
167
+ @@log = init_logger(STDOUT, Logger::INFO)
168
+ # <------
169
+ # object-level ---->
170
+ include Logging
171
+ # <---------
172
+
173
+ def test_log
174
+ @@log.info('class-level logger called from instance: ' << @@log.to_s)
175
+ #@log = @@log # works too
176
+ @log = TClass.class_eval{@log}
177
+ @log.info('AGAIN: class-level logger called from instance: ' << @log.to_s)
178
+ @log.debug("you won't see this on log-level INFO")
179
+
180
+ # object-level ---->
181
+ init_logger
182
+ # <-----------
183
+ @log.info("That's a different thing: " << @log.to_s << " - object-level logger!")
184
+
185
+ end
186
+ def self::test_log
187
+ @log.info('class-level logger called from class: ' << @log.to_s)
188
+ @@log.info('AGAIN: class-level logger called from class: ' << @log.to_s)
189
+ end
190
+ end
191
+
192
+ TClass.new.test_log # class-logger + 1st object-logger
193
+ TClass.new.test_log # same class-logger + 2nd object-logger
194
+
195
+ TClass::test_log # same class-logger
196
+ puts 'And just say it once clearly: THIS IS COOOL!!'
197
+ end
198
+ #EOF
data/lib/version.rb ADDED
@@ -0,0 +1,4 @@
1
+ VERSION = 0.6
2
+ SUMMARY="Handle exception raised by the mail-gem"
3
+ AUTHORS=["Michael Uplawski@uplawski.eu"]
4
+ EMAIL="michael.uplawski@uplawski.eu"
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ip_in_range
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.6'
5
+ platform: ruby
6
+ authors:
7
+ - Michael Uplawski@uplawski.eu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Verify that an IP is in a range
14
+ email: michael.uplawski@uplawski.eu
15
+ executables:
16
+ - ip_in_range
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/ip_in_range
21
+ - ip_in_range.gemspec
22
+ - lib/email.rb
23
+ - lib/file_checking.rb
24
+ - lib/ip_range.rb
25
+ - lib/log.conf
26
+ - lib/logging.rb
27
+ - lib/version.rb
28
+ homepage: ''
29
+ licenses:
30
+ - GPL-3.0
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '2.7'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.3.5
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Handle exception raised by the mail-gem
51
+ test_files: []