telnet-server 1.0.2-java

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: 1aa85e38d62df8e71c261548b56316fc9ce61a43182cabea836639dcb13732ab
4
+ data.tar.gz: 6b44b58a27cc8c596f2f681bfdb9ba2d9f4584c7d81f624708c88b2715078e2a
5
+ SHA512:
6
+ metadata.gz: 471724158c29c74810f0a867c5ad1a795724a6f022ec7b3f5371bc725618b946e2e13bdcec6245d783a497aeb7460f52ca1b5f4daabafa47942d8ae444d865ba
7
+ data.tar.gz: 507fa086485838d9a6b2404986b89d233d797f030d116cd548685ac3dc2301e613542b0466b21e1e50af36d6dd7d1f61c05d91e8a4423380c5bc746770dbf4f9
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Nels Nelson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # telnet-server-jruby
2
+
3
+ [![License](https://img.shields.io/badge/license-MIT--2.0-blue.svg?style=flat)][license]
4
+
5
+ This is a small telnet server for [JRuby].
6
+
7
+ It is based on the [Netty project]. Netty is written in java, but I wanted to write ruby.
8
+
9
+
10
+ ## Quick-start
11
+
12
+ Follow these instructions to get a telnet server echo program running.
13
+
14
+
15
+ ### Container
16
+
17
+ You may run the telnet server in a container.
18
+
19
+ ```sh
20
+ colima start
21
+ docker-compose up --detach
22
+ nc localhost 21
23
+ docker-compose down
24
+ ```
25
+
26
+
27
+ Building the image or running the container:
28
+
29
+ ```sh
30
+ docker build --squash --tag telnet-server-jruby .
31
+ docker run --detach --publish 21:21 --name telnet-server-jruby telnet-server-jruby
32
+ ```
33
+
34
+
35
+ ## Manually
36
+
37
+ Run directly with the required dependencies installed.
38
+
39
+ ### Install asdf
40
+
41
+ The [asdf] CLI tool used to manage multiple runtime versions.
42
+
43
+ ```sh
44
+ git clone https://github.com/asdf-vm/asdf.git "${HOME}/.asdf" --branch v0.8.1
45
+ pushd "${HOME}/.asdf"; git fetch origin; popd
46
+ source "${HOME}/.asdf/asdf.sh"; source "${HOME}/.asdf/completions/asdf.bash"
47
+ ```
48
+
49
+ ### Install required runtime software
50
+
51
+ Download and install the latest version of the [Java JDK].
52
+
53
+ ```sh
54
+ asdf plugin add java
55
+ asdf install java openjdk-17.0.2
56
+ ```
57
+
58
+
59
+ Download and install the latest version of [JRuby].
60
+
61
+ ```sh
62
+ asdf plugin add ruby
63
+ asdf plugin update --all
64
+ asdf list all ruby
65
+ asdf install
66
+ ```
67
+
68
+
69
+ Install the project dependencies.
70
+
71
+ ```sh
72
+ bundle install
73
+ ```
74
+
75
+
76
+ ## Run
77
+
78
+ The entrypoint for the web application service may now be invoked from a command line interface terminal shell.
79
+
80
+ ```sh
81
+ bundle exec ./telnet.rb &
82
+ nc localhost 21
83
+ ```
84
+
85
+
86
+ ## Build the gem
87
+
88
+ To clean the project, run unit tests, build the gem file, and verify that the built artifact works, execute:
89
+
90
+ ```sh
91
+ bundle exec rake
92
+ ```
93
+
94
+
95
+ ## Publish the gem
96
+
97
+ To publish the gem, execute:
98
+
99
+ ```sh
100
+ bundle exec rake publish
101
+ ```
102
+
103
+
104
+ ## Project file tree
105
+
106
+ Here is a bird's-eye view of the project layout.
107
+
108
+ ```sh
109
+ # date && tree
110
+ Wed Apr 6 23:05:28 CDT 2022
111
+ .
112
+ ├── Dockerfile
113
+ ├── Gemfile
114
+ ├── Gemfile.lock
115
+ ├── LICENSE
116
+ ├── README.md
117
+ ├── Rakefile
118
+ ├── docker-compose.yaml
119
+ ├── exe
120
+ │ └── telnet
121
+ ├── lib
122
+ │ ├── log.rb
123
+ │ ├── server
124
+ │ │ ├── mime_types.rb
125
+ │ │ └── server.rb
126
+ │ ├── telnet
127
+ │ │ ├── config.rb
128
+ │ │ ├── server.rb
129
+ │ │ └── version.rb
130
+ │ ├── telnet_client.rb
131
+ │ └── telnet_server.rb
132
+ ├── logs
133
+ │ └── server.log
134
+ ├── spec
135
+ │ ├── spec_helper.rb
136
+ │ ├── test_spec.rb
137
+ │ └── verify
138
+ │ └── verify_spec.rb
139
+ ├── telnet-server-jruby.gemspec
140
+ └── telnet.rb
141
+
142
+ 13 directories, 52 files
143
+ ```
144
+
145
+
146
+ ## CI linting
147
+
148
+ Use the GitLab CI Linting API to validate the syntax of a CI definition file.
149
+
150
+ ```sh
151
+ jq --null-input --arg yaml "$(<.gitlab/ci/gem.gitlab-ci.yml)" '.content=$yaml' | curl --silent --location https://gitlab.com/api/v4/ci/lint --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" --header "Content-Type: application/json" --data @- | jq --raw-output '.errors[0]'
152
+ ```
153
+
154
+
155
+ ## CI configuration
156
+
157
+ Generate a deploy key.
158
+
159
+ ```sh
160
+ ssh-keygen -t ed25519 -P '' -C deploy_key -f deploy_key_ed25519
161
+ ```
162
+
163
+ Use the GitLab Project-level Variables API to add the deploy key as a ssh private key variable.
164
+
165
+ ```sh
166
+ project_path="nelsnelson/$(basename $(pwd))"
167
+
168
+ # Test auth token validity
169
+ curl --silent --show-error --location "https://gitlab.com/api/v4/projects" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" | jq '.[0]["id"]'
170
+
171
+ project=$(curl --silent --show-error --location "https://gitlab.com/api/v4/search?scope=projects&search=${project_path}" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" | jq --arg project_path "${project_path}" '.[] | select(.path_with_namespace == $project_path)')
172
+
173
+ project_id=$(curl --silent --show-error --location "https://gitlab.com/api/v4/search?scope=projects&search=${project_path}" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" | jq --arg project_path "${project_path}" '.[] | select(.path_with_namespace == $project_path) | .id')
174
+
175
+ # Add the deploy_token as a CI variable:
176
+ curl --silent --show-error --location --request POST "https://gitlab.com/api/v4/projects/${project_id}/variables" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" --form "key=SSH_PRIVATE_KEY" --form "value=$(cat ./deploy_key_ed25519)" --form "protected=true" | jq
177
+ ```
178
+
179
+ Use the Deploy keys API to add a the public deploy key as a deploy key for the project.
180
+
181
+ ```sh
182
+ curl --silent --show-error --location --request POST "https://gitlab.com/api/v4/projects/${project_id}/deploy_keys" --header "PRIVATE-TOKEN: ${GITLAB_COM_API_PRIVATE_TOKEN}" --form "title=deploy_key" --form "key=$(cat ./deploy_key_ed25519.pub)" --form "can_push=true" | jq
183
+ ```
184
+
185
+ [license]: https://gitlab.com/nelsnelson/telnet-server-jruby/blob/master/LICENSE
186
+ [asdf]: https://asdf-vm.com/
187
+ [Netty project]: https://github.com/netty/netty
188
+ [Java JDK]: https://www.java.com/en/download/
189
+ [JRuby]: https://jruby.org/download
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # -*- mode: ruby -*-
5
+ # vi: set ft=ruby :
6
+
7
+ require 'rake'
8
+ require 'rake/clean'
9
+
10
+ PROJECT = File.basename(__dir__) unless defined?(PROJECT)
11
+
12
+ load "#{PROJECT}.gemspec"
13
+
14
+ CLEAN.add File.join('tmp', '**', '*'), 'tmp'
15
+ CLOBBER.add '*.gem', 'pkg'
16
+
17
+ task default: %i[package]
18
+
19
+ desc 'Run the rubocop linter'
20
+ task :lint do
21
+ system('bundle', 'exec', 'rubocop') or abort
22
+ end
23
+
24
+ desc 'Run the spec tests'
25
+ task :test do
26
+ system('bundle', 'exec', 'rspec', '--exclude-pattern', 'spec/verify/**/*_spec.rb') or abort
27
+ end
28
+ task test: :lint
29
+
30
+ desc 'Explode the gem'
31
+ task :explode do
32
+ system('jgem', 'install', '--no-document', '--install-dir=tmp', '*.gem')
33
+ end
34
+ task explode: :clean
35
+
36
+ desc 'Package the gem'
37
+ task :package do
38
+ system('jgem', 'build')
39
+ end
40
+ task package: %i[clean clobber test]
41
+
42
+ desc 'Verify the gem'
43
+ task :verify do
44
+ system('bundle', 'exec', 'rspec', 'spec/verify') or abort
45
+ end
46
+ task verify: :explode
47
+
48
+ desc 'Publish the gem'
49
+ task :publish do
50
+ system('jgem', 'push', latest_gem)
51
+ end
52
+ task publish: :verify
53
+
54
+ def latest_gem
55
+ `ls -t #{PROJECT}*.gem`.strip.split("\n").first
56
+ end
data/exe/telnet ADDED
@@ -0,0 +1,17 @@
1
+ #! /usr/bin/env jruby
2
+
3
+ # encoding: utf-8
4
+ # frozen_string_literal: false
5
+
6
+ # -*- mode: ruby -*-
7
+ # vi: set ft=ruby :
8
+
9
+ # =begin
10
+ #
11
+ # Copyright Nels Nelson 2016-2022 but freely usable (see license)
12
+ #
13
+ # =end
14
+
15
+ require_relative '../lib/telnet_server'
16
+
17
+ Object.new.extend(Telnet).main
data/lib/log.rb ADDED
@@ -0,0 +1,241 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # =begin
5
+
6
+ # Copyright Nels Nelson 2016-2019 but freely usable (see license)
7
+
8
+ # =end
9
+
10
+ require 'java'
11
+ require 'logger'
12
+
13
+ require 'log4j-2'
14
+
15
+ require 'fileutils'
16
+
17
+ # The Logging module
18
+ module Logging
19
+ module_function
20
+
21
+ # rubocop: disable Metrics/MethodLength
22
+ def config
23
+ @config ||= begin
24
+ lib_dir_path = File.expand_path(__dir__)
25
+ project_dir_path = File.expand_path(File.dirname(lib_dir_path))
26
+ logs_dir_path = File.expand_path(File.join(project_dir_path, 'logs'))
27
+ server_log_file = File.expand_path(File.join(logs_dir_path, 'server.log'))
28
+ {
29
+ level: :info,
30
+ name: 'telnet',
31
+ logs_dir_path: logs_dir_path,
32
+ server_log_file: server_log_file,
33
+ rolling_log_file_name_template: 'server-%d{yyyy-MM-dd}.log.gz',
34
+ logger_pattern_template: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
35
+ schedule: '0 0 0 * * ?',
36
+ size: '100M'
37
+ }
38
+ end
39
+ end
40
+ # rubocop: enable Metrics/MethodLength
41
+ end
42
+
43
+ # The LogInitialization module
44
+ module LogInitialization
45
+ module_function
46
+
47
+ def init
48
+ init_log_file
49
+ init_log4j if defined? Java
50
+ end
51
+
52
+ def init_log_file
53
+ FileUtils.mkdir_p(Logging.config[:logs_dir_path])
54
+ return if File.file?(Logging.config[:server_log_file])
55
+
56
+ File.write(Logging.config[:server_log_file], '')
57
+ end
58
+
59
+ # rubocop: disable Metrics/AbcSize
60
+ # rubocop: disable Metrics/MethodLength
61
+ def init_log4j(log_level = org.apache.logging.log4j.Level::INFO)
62
+ server_log_file = Logging.config[:server_log_file]
63
+ logs_dir_path = Logging.config[:logs_dir_path]
64
+ rolling_log_file_name_template = Logging.config[:rolling_log_file_name_template]
65
+ rolling_log_file_path = File.join(logs_dir_path, rolling_log_file_name_template)
66
+
67
+ java.lang::System.setProperty('log4j.shutdownHookEnabled', java.lang::Boolean.toString(false))
68
+ factory = org.apache.logging.log4j.core.config.builder.api::ConfigurationBuilderFactory
69
+ config = factory.newConfigurationBuilder()
70
+
71
+ if log_level.is_a?(Symbol)
72
+ log_level = org.apache.logging.log4j.Level.to_level(
73
+ log_level.to_s.upcase
74
+ )
75
+ end
76
+ config.setStatusLevel(log_level)
77
+ config.setConfigurationName(Logging.config['name'])
78
+
79
+ # Create a console appender
80
+ target = org.apache.logging.log4j.core.appender::ConsoleAppender::Target::SYSTEM_OUT
81
+ layout = config.newLayout('PatternLayout')
82
+ layout = layout.addAttribute('pattern', Logging.config[:logger_pattern_template])
83
+ appender = config.newAppender('stdout', 'CONSOLE')
84
+ appender = appender.addAttribute('target', target)
85
+ appender = appender.add(layout)
86
+ config.add(appender)
87
+
88
+ # Create a root logger
89
+ root_logger = config.newRootLogger(log_level)
90
+ root_logger = root_logger.add(config.newAppenderRef('stdout'))
91
+
92
+ # Create a rolling file appender
93
+ cron = config.newComponent('CronTriggeringPolicy')
94
+ cron = cron.addAttribute('schedule', Logging.config[:schedule])
95
+
96
+ size = config.newComponent('SizeBasedTriggeringPolicy')
97
+ size = size.addAttribute('size', Logging.config[:size])
98
+
99
+ policies = config.newComponent('Policies')
100
+ policies = policies.addComponent(cron)
101
+ policies = policies.addComponent(size)
102
+
103
+ appender = config.newAppender('rolling_file', 'RollingFile')
104
+ appender = appender.addAttribute('fileName', server_log_file)
105
+ appender = appender.addAttribute('filePattern', rolling_log_file_path)
106
+ appender = appender.add(layout)
107
+ appender = appender.addComponent(policies)
108
+ config.add(appender)
109
+
110
+ root_logger = root_logger.addAttribute('additivity', false)
111
+ root_logger = root_logger.add(config.newAppenderRef('rolling_file'))
112
+ config.add(root_logger)
113
+
114
+ logging_configuration = config.build()
115
+ ctx = org.apache.logging.log4j.core.config::Configurator.initialize(logging_configuration)
116
+ ctx.updateLoggers()
117
+ end
118
+ # rubocop: enable Metrics/AbcSize
119
+ # rubocop: enable Metrics/MethodLength
120
+ # def init_log4j
121
+ end
122
+ # module LogInitialization
123
+
124
+ ::LogInitialization.init
125
+
126
+ # The Apache log4j Logger class
127
+ # rubocop: disable Style/ClassAndModuleChildren
128
+ class org.apache.logging.log4j.core::Logger
129
+ alias log4j_error error
130
+ def error(error_or_message, error = nil)
131
+ return extract_backtrace(error_or_message) if error.nil?
132
+ log4j_error(generate_message(error_or_message, error))
133
+ extract_backtrace(error)
134
+ end
135
+
136
+ def generate_message(error_or_message, error)
137
+ error_message = "#{error_or_message}: #{error.class.name}"
138
+ error_message << ": #{error.message}" if error.respond_to?(:message)
139
+ error_message
140
+ end
141
+
142
+ def extract_backtrace(error, default_result = nil)
143
+ log4j_error(error)
144
+ if error.respond_to?(:backtrace)
145
+ error.backtrace.each { |trace| log4j_error(trace) unless trace.nil? }
146
+ elsif error.respond_to?(:getStackTrace)
147
+ error.getStackTrace().each { |trace| log4j_error(trace) unless trace.nil? }
148
+ else
149
+ default_result
150
+ end
151
+ end
152
+ end
153
+ # rubocop: enable Style/ClassAndModuleChildren
154
+
155
+ # The Logging module
156
+ module Logging
157
+ def init_logger(level = :all, logger_name = nil)
158
+ return init_java_logger(level, logger_name, caller[2]) if defined?(Java)
159
+ init_ruby_logger(level)
160
+ end
161
+
162
+ def init_ruby_logger(level)
163
+ logger_instance = Logger.new
164
+ logger_instance.level = Logging::Level.to_level(level.to_s.upcase)
165
+ logger_instance
166
+ end
167
+
168
+ # rubocop: disable Metrics/AbcSize
169
+ def init_java_logger(level, logger_name = nil, source_location = nil)
170
+ logger_name = get_formatted_logger_name(logger_name)
171
+ logger_name = source_location.split(/\//).last if logger_name.empty?
172
+ logger_instance = org.apache.logging.log4j.LogManager.getLogger(logger_name)
173
+ logger_instance.level = org.apache.logging.log4j.Level.to_level(level.to_s.upcase)
174
+ logger_instance
175
+ end
176
+ # rubocop: enable Metrics/AbcSize
177
+
178
+ def get_formatted_logger_name(logger_name = nil)
179
+ return logger_name.to_s[/\w+$/] unless logger_name.nil?
180
+ return name[/\w+$/] if is_a?(Class) || is_a?(Module)
181
+ self.class.name[/\w+$/]
182
+ end
183
+
184
+ def log(level = Logging.log_level, log_name = nil)
185
+ @log ||= init_logger(level, log_name)
186
+ end
187
+ alias logger log
188
+
189
+ module_function
190
+
191
+ # rubocop: disable Metrics/CyclomaticComplexity
192
+ # OFF: 0
193
+ # FATAL: 100
194
+ # ERROR: 200
195
+ # WARN: 300
196
+ # INFO: 400
197
+ # DEBUG: 500
198
+ # TRACE: 600
199
+ # ALL: 2147483647
200
+ # See: https://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/Level.html
201
+ def symbolize_numeric_log_level(level)
202
+ case level
203
+ when 5..Float::INFINITY then :off
204
+ when 4 then :fatal
205
+ when 3 then :error
206
+ when 2 then :warn
207
+ when 1 then :info
208
+ when 0 then :debug
209
+ when -1 then :trace
210
+ when -2..-Float::INFINITY then :all
211
+ end
212
+ end
213
+ # rubocop: enable Metrics/CyclomaticComplexity
214
+
215
+ def log_level=(log_level)
216
+ Logging.config[:level] = symbolize_numeric_log_level(log_level)
217
+ end
218
+
219
+ def log_level
220
+ Logging.config[:level]
221
+ end
222
+ end
223
+ # module Logging
224
+
225
+ # The Module class
226
+ class Module
227
+ # Universally include Logging
228
+ include ::Logging
229
+ end
230
+
231
+ # The Class class
232
+ class Class
233
+ # Universally include Logging
234
+ include ::Logging
235
+ end
236
+
237
+ # The Object class
238
+ class Object
239
+ # Universally include Logging
240
+ include ::Logging
241
+ end
@@ -0,0 +1,97 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # -*- mode: ruby -*-
5
+ # vi: set ft=ruby :
6
+
7
+ # =begin
8
+ #
9
+ # Copyright Nels Nelson 2016-2022 but freely usable (see license)
10
+ #
11
+ # =end
12
+
13
+ require 'optparse'
14
+
15
+ require_relative 'config'
16
+ require_relative 'version'
17
+
18
+ # The Telnet module
19
+ module Telnet
20
+ # The ArgumentsParser class
21
+ class ArgumentsParser
22
+ attr_reader :parser, :options
23
+
24
+ def initialize(option_parser = OptionParser.new)
25
+ @parser = option_parser
26
+ @options = ::Telnet.server_config.dup
27
+ @flags = %i[banner port idle_reading idle_writing log_requests log_level help version]
28
+ @flags.each { |method_name| method(method_name).call }
29
+ end
30
+
31
+ def banner
32
+ @parser.banner = "Usage: #{File.basename($PROGRAM_NAME)} [port] [options]"
33
+ @parser.separator ''
34
+ @parser.separator 'Options:'
35
+ end
36
+
37
+ def validated_port(val, integer_pattern = /^\d+$/)
38
+ raise "Invalid port: #{v}" unless integer_pattern.match?(val.to_s) && val.positive? && val < 65_536
39
+ val
40
+ end
41
+
42
+ def port
43
+ description = "Port on which to listen for connections; default: #{@options[:port]}"
44
+ @parser.on('-p', '--port=<port>', Integer, description) do |v|
45
+ @options[:port] = validated_port(v).to_i
46
+ end
47
+ end
48
+
49
+ def idle_reading
50
+ @parser.on('--idle-reading=seconds', 'Amount of time channel can idle without incoming data') do |v|
51
+ @options[:idle_reading] = v.to_i
52
+ end
53
+ end
54
+
55
+ def idle_writing
56
+ @parser.on('--idle-writing=seconds', 'Amount of time channel can idle without outgoing data') do |v|
57
+ @options[:idle_writing] = v.to_i
58
+ end
59
+ end
60
+
61
+ def log_requests
62
+ @parser.on('-r', '--log-requests', 'Include individual request info in log output') do
63
+ @options[:log_requests] = true
64
+ end
65
+ end
66
+
67
+ def log_level
68
+ @parser.on_tail('-v', '--verbose', 'Increase verbosity') do
69
+ @options[:log_level] ||= 1
70
+ @options[:log_level] -= 1
71
+ end
72
+ end
73
+
74
+ def help
75
+ @parser.on_tail('-?', '--help', 'Show this message') do
76
+ puts @parser
77
+ exit
78
+ end
79
+ end
80
+
81
+ def version
82
+ @parser.on_tail('--version', 'Show version') do
83
+ puts "#{File.basename($PROGRAM_NAME)} version #{::Telnet::VERSION}"
84
+ exit
85
+ end
86
+ end
87
+ end
88
+ # class ArgumentsParser
89
+
90
+ def parse_arguments(arguments_parser = ::Telnet::ArgumentsParser.new)
91
+ arguments_parser.parser.parse!(ARGV)
92
+ arguments_parser.options
93
+ rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption => e
94
+ abort e.message
95
+ end
96
+ end
97
+ # module Telnet
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # -*- mode: ruby -*-
5
+ # vi: set ft=ruby :
6
+
7
+ # =begin
8
+ #
9
+ # Copyright Nels Nelson 2016-2022 but freely usable (see license)
10
+ #
11
+ # =end
12
+
13
+ require 'netty'
14
+
15
+ require 'logger'
16
+
17
+ # The Telnet module
18
+ module Telnet
19
+ # rubocop: disable Metrics/MethodLength
20
+ def server_config
21
+ @server_config ||= {
22
+ host: '0.0.0.0',
23
+ port: 21,
24
+ ssl: false,
25
+ idle_reading: 5 * 60, # seconds
26
+ idle_writing: 30, # seconds
27
+ log_requests: false,
28
+ log_level: Logger::INFO,
29
+ quit_commands: %i[bye cease desist exit leave quit stop terminate],
30
+ prompt: '>',
31
+ max_frame_length: 8192,
32
+ delimiter: Java::io.netty.handler.codec.Delimiters.lineDelimiter
33
+ }
34
+ end
35
+ module_function :server_config
36
+ # rubocop: enable Metrics/MethodLength
37
+ end