blob: 6651097e0089a68039525dd5553600a5fdc1d17a [file] [log] [blame]
Neels Hofmeyrfaa49e22019-01-31 09:06:53 +01001/* Test implementation for VTY transcript testing. */
2/*
3 * (C) 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
4 *
5 * All Rights Reserved
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 *
9 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#define _GNU_SOURCE
27#include <getopt.h>
28#include <signal.h>
29#include <limits.h>
30#include <string.h>
31
32#include <osmocom/core/application.h>
33
34#include <osmocom/vty/command.h>
35#include <osmocom/vty/misc.h>
36#include <osmocom/vty/telnet_interface.h>
37
38#include <stdlib.h>
39
40#include "config.h"
41
42void *root_ctx = NULL;
43
44static void print_help()
45{
46 printf( "options:\n"
47 " -h --help this text\n"
48 " -d --debug MASK Enable debugging (e.g. -d DRSL:DOML:DLAPDM)\n"
49 " -D --daemonize For the process into a background daemon\n"
50 " -c --config-file Specify the filename of the config file\n"
51 " -s --disable-color Don't use colors in stderr log output\n"
52 " -T --timestamp Prefix every log line with a timestamp\n"
53 " -V --version Print version information and exit\n"
54 " -e --log-level Set a global log-level\n"
55 );
56}
57
58static struct {
59 const char *config_file;
60 int daemonize;
61} cmdline_config = {};
62
63static void handle_options(int argc, char **argv)
64{
65 while (1) {
66 int option_idx = 0, c;
67 static const struct option long_options[] = {
68 { "help", 0, 0, 'h' },
69 { "debug", 1, 0, 'd' },
70 { "daemonize", 0, 0, 'D' },
71 { "config-file", 1, 0, 'c' },
72 { "disable-color", 0, 0, 's' },
73 { "timestamp", 0, 0, 'T' },
74 { "version", 0, 0, 'V' },
75 { "log-level", 1, 0, 'e' },
76 {}
77 };
78
79 c = getopt_long(argc, argv, "hc:d:Dc:sTVe:",
80 long_options, &option_idx);
81 if (c == -1)
82 break;
83
84 switch (c) {
85 case 'h':
86 print_help();
87 exit(0);
88 case 's':
89 log_set_use_color(osmo_stderr_target, 0);
90 break;
91 case 'd':
92 log_parse_category_mask(osmo_stderr_target, optarg);
93 break;
94 case 'D':
95 cmdline_config.daemonize = 1;
96 break;
97 case 'c':
98 cmdline_config.config_file = optarg;
99 break;
100 case 'T':
101 log_set_print_timestamp(osmo_stderr_target, 1);
102 break;
103 case 'e':
104 log_set_log_level(osmo_stderr_target, atoi(optarg));
105 break;
106 case 'V':
107 print_version(1);
108 exit(0);
109 break;
110 default:
111 /* catch unknown options *as well as* missing arguments. */
112 fprintf(stderr, "Error in command line options. Exiting.\n");
113 exit(-1);
114 }
115 }
116}
117
118static int quit = 0;
119
120static void signal_handler(int signal)
121{
122 fprintf(stdout, "signal %u received\n", signal);
123
124 switch (signal) {
125 case SIGINT:
126 case SIGTERM:
127 quit++;
128 break;
129 case SIGABRT:
130 osmo_generate_backtrace();
131 /* in case of abort, we want to obtain a talloc report
132 * and then return to the caller, who will abort the process */
133 case SIGUSR1:
134 talloc_report(tall_vty_ctx, stderr);
135 talloc_report_full(root_ctx, stderr);
136 break;
137 case SIGUSR2:
138 talloc_report_full(tall_vty_ctx, stderr);
139 break;
140 default:
141 break;
142 }
143}
144
145static struct vty_app_info vty_info = {
146 .name = "vty_transcript_test",
147 .version = PACKAGE_VERSION,
148};
149
150static const struct log_info_cat default_categories[] = {};
151
152const struct log_info log_info = {
153 .cat = default_categories,
154 .num_cat = ARRAY_SIZE(default_categories),
155};
156
Pau Espin Pedrol14aadd52019-06-12 18:34:34 +0200157DEFUN(single0, single0_cmd,
158 "single0 [one]",
159 "single0 test command\n" "1\n")
160{
161 vty_out(vty, "ok argc=%d%s%s%s", argc, argc ? " " : "", argc ? argv[0] : "", VTY_NEWLINE);
162 return CMD_SUCCESS;
163}
164
Neels Hofmeyrfaa49e22019-01-31 09:06:53 +0100165DEFUN(multi0, multi0_cmd,
166 "multi0 (one|two|three)",
167 "multi0 test command\n" "1\n2\n3\n")
168{
169 vty_out(vty, "ok argc=%d%s%s%s", argc, argc ? " " : "", argc ? argv[0] : "", VTY_NEWLINE);
170 return CMD_SUCCESS;
171}
172
173DEFUN(multi1, multi1_cmd,
174 "multi1 ([one]|[two]|[three])",
175 "multi1 test command\n" "1\n2\n3\n")
176{
177 vty_out(vty, "ok argc=%d%s%s%s", argc, argc ? " " : "", argc ? argv[0] : "", VTY_NEWLINE);
178 return CMD_SUCCESS;
179}
180
Neels Hofmeyrb55f4d22019-01-31 08:13:31 +0100181DEFUN(multi2, multi2_cmd,
182 "multi2 [(one|two|three)]",
183 "multi2 test command\n" "1\n2\n3\n")
184{
185 vty_out(vty, "ok argc=%d%s%s%s", argc, argc ? " " : "", argc ? argv[0] : "", VTY_NEWLINE);
186 return CMD_SUCCESS;
187}
188
Neels Hofmeyrfaa49e22019-01-31 09:06:53 +0100189static void init_vty_cmds()
190{
Pau Espin Pedrol14aadd52019-06-12 18:34:34 +0200191 install_element_ve(&single0_cmd);
Neels Hofmeyrfaa49e22019-01-31 09:06:53 +0100192 install_element_ve(&multi0_cmd);
193 install_element_ve(&multi1_cmd);
Neels Hofmeyrb55f4d22019-01-31 08:13:31 +0100194 install_element_ve(&multi2_cmd);
Neels Hofmeyrfaa49e22019-01-31 09:06:53 +0100195}
196
197int main(int argc, char **argv)
198{
199 int rc;
200
201 root_ctx = talloc_named_const(NULL, 0, "vty_transcript_test");
202
203 vty_info.tall_ctx = root_ctx;
204 vty_init(&vty_info);
205 osmo_talloc_vty_add_cmds();
206 init_vty_cmds();
207
208 osmo_init_logging2(root_ctx, &log_info);
209
210 handle_options(argc, argv);
211
212 if (cmdline_config.config_file) {
213 rc = vty_read_config_file(cmdline_config.config_file, NULL);
214 if (rc < 0) {
215 fprintf(stderr, "Failed to parse the config file: '%s'\n", cmdline_config.config_file);
216 return 1;
217 }
218 }
219
220 rc = telnet_init_dynif(root_ctx, NULL, vty_get_bind_addr(), 42042);
221 if (rc < 0)
222 return 2;
223
224 signal(SIGINT, &signal_handler);
225 signal(SIGTERM, &signal_handler);
226 signal(SIGABRT, &signal_handler);
227 signal(SIGUSR1, &signal_handler);
228 signal(SIGUSR2, &signal_handler);
229 osmo_init_ignore_signals();
230
231 if (cmdline_config.daemonize) {
232 rc = osmo_daemonize();
233 if (rc < 0) {
234 perror("Error during daemonize");
235 return 6;
236 }
237 }
238
239 while (!quit) {
240 log_reset_context();
241 osmo_select_main(0);
242 }
243
244 talloc_free(root_ctx);
245 talloc_free(tall_vty_ctx);
246
247 return 0;
248}