source: rtems-libbsd/rtemsbsd/telnetd/telnetd-service.c @ 65c65bb

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 65c65bb was 65c65bb, checked in by Chris Johns <chrisj@…>, on 07/01/16 at 05:49:52

Add telnetd as service to rc.conf.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26/*
27 * Telnet service. To use add to rc.conf:
28 *
29 * telnetd_enable="YES"
30 * telnet_options="-p 21 -s 32768 -P 8 -L"
31 *
32 * The options defaults are show. The options are:
33 *
34 *  -C conns      : Maximum connections (ptys).
35 *  -P priority   : Telnet thread priority (RTEMS Classis API).
36 *  -L            : Login using /etc/passwd
37 */
38
39#include <errno.h>
40#include <stddef.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44
45#define __need_getopt_newlib
46#include <getopt.h>
47
48#include <rtems/telnetd.h>
49#include <machine/rtems-bsd-rc-conf-services.h>
50
51/*
52 * Stack size. Use RTEMS_BSD_CONFIG_TELNETD_STACK_SIZE.
53 */
54extern int rtems_telnetd_stack_size;
55__weak_reference(_rtems_telnetd_stack_size, rtems_telnetd_stack_size);
56int _rtems_telnetd_stack_size;
57
58/*
59 * Condefs always defines this variable.
60 */
61extern int rtems_telnetd_maximum_ptys;
62
63/*
64 * By default no login.
65 */
66static bool telnet_login;
67
68static void
69hydra_telnetd_command(char* device, void* arg)
70{
71  rtems_shell_login_check_t login = NULL;
72  rtems_shell_env_t         shell_env;
73
74  if (telnet_login)
75    login = rtems_shell_login_check;
76
77  rtems_shell_dup_current_env(&shell_env);
78
79  shell_env.devname       = device;
80  shell_env.taskname      = "TELn";
81  shell_env.exit_shell    = false;
82  shell_env.forever       = 0;
83  shell_env.echo          = 0;
84  shell_env.input         = NULL;
85  shell_env.output        = NULL;
86  shell_env.output_append = 0;
87  shell_env.wake_on_end   = 0;
88  shell_env.login_check   = login;
89
90  rtems_shell_main_loop (&shell_env);
91}
92
93static int
94telnetd_service(rtems_bsd_rc_conf* rc_conf)
95{
96  rtems_telnetd_config_table config = {
97    .priority = 100,                  /* Telnet task priority */
98    .stack_size = 32 * 1024,          /* Stack size */
99    .command = hydra_telnetd_command, /* The telnetd command, runs the shell. */
100  };
101  rtems_bsd_rc_conf_argc_argv* aa;
102  int                          conns = 0;
103  int                          r;
104
105  if (rtems_telnetd_stack_size != 0)
106    config.stack_size = rtems_telnetd_stack_size;
107
108  aa = rtems_bsd_rc_conf_argc_argv_create();
109  if (aa == NULL)
110    return -1;
111
112  r = rtems_bsd_rc_conf_find(rc_conf, "telnetd_enable", aa);
113  if (r == 0) {
114    rtems_status_code sc;
115    bool              verbose = false;
116    if (aa->argc == 2 && strcasecmp("YES", aa->argv[1]) == 0) {
117      r = rtems_bsd_rc_conf_find(rc_conf, "telnetd_options", aa);
118      if (r == 0) {
119        struct getopt_data data;
120        char*              end;
121
122        memset(&data, 0, sizeof(data));
123
124        while (true) {
125          int c;
126
127          c = getopt_r(aa->argc, aa->argv, "C:P:Lv", &data);
128          if (c == -1)
129            break;
130
131          switch (c) {
132          case 'C':
133            conns = strtoul(data.optarg, &end, 10);
134            if (conns == 0 || *end != '\0') {
135              fprintf(stderr, "error: telnet: invalid connections countt\n");
136            }
137            else {
138              rtems_telnetd_maximum_ptys = conns;
139            }
140            break;
141          case 'P':
142            config.priority = strtoul(data.optarg, &end, 10);
143            if (config.priority == 0 || *end != '\0') {
144              fprintf(stderr, "error: telnetd: invalid priority\n");
145              config.priority = 100;
146            }
147            break;
148          case 'L':
149            telnet_login = true;
150            break;
151          case 'v':
152            verbose = true;
153            break;
154          case '?':
155          default:
156            fprintf(stderr, "error: telnetd: unknown option: %s\n", data.optarg);
157            break;
158          }
159        }
160      }
161      if (verbose) {
162        printf("telnetd: conns:%lu pri:%lu login:%s\n",
163               rtems_telnetd_maximum_ptys, config.priority,
164               telnet_login == NULL ? "no" : "yes");
165      }
166      sc = rtems_telnetd_start(&config);
167      if (sc != RTEMS_SUCCESSFUL)
168        fprintf(stderr, "error: telnetd: %s\n", rtems_status_text(sc));
169    }
170  }
171
172  return 0;
173}
174
175void
176rc_conf_telnetd_init(void* arg)
177{
178  int r;
179  r = rtems_bsd_rc_conf_service_add("telnetd",
180                                    "after:network;before:ftpd;",
181                                    telnetd_service);
182  if (r < 0)
183    fprintf(stderr, "error: telnetd service add failed: %s\n", strerror(errno));
184}
Note: See TracBrowser for help on using the repository browser.