plptools
Loading...
Searching...
No Matches
main.cc
Go to the documentation of this file.
1/*
2 * This file is part of plptools.
3 *
4 * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com>
5 * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com>
6 * Copyright (C) 2026 Jason Morley <hello@jbmorley.co.uk>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * along with this program; if not, see <https://www.gnu.org/licenses/>.
20 *
21 */
22#include "config.h"
23
24#include <string>
25#include <cstring>
26#include <iostream>
27
28#include <cli_utils.h>
29#include <bufferstore.h>
30#include <tcpsocket.h>
31#include <iowatch.h>
32#include <log.h>
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <signal.h>
37#include <errno.h>
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <pthread.h>
42#include <plpintl.h>
43#include <unistd.h>
44
45#include "ignore-value.h"
46
47#include "ncp_log.h"
48#include "ncp_session.h"
49#include "packet.h"
50
51#ifndef _GNU_SOURCE
52#define _GNU_SOURCE
53#endif
54#include <getopt.h>
55
56using namespace std;
57
58// Global session state specific to the `ncpd` process. This exists as a global solely for the purpose of accessing it
59// from the interrupt handlers.
61
62static void
64{
65 linf << _("Got SIGTERM") << endl;
67 signal(SIGTERM, term_handler);
68};
69
70static void
72{
73 linf << _("Got SIGINT") << endl;
75 signal(SIGINT, int_handler);
76};
77
78static void
80{
81 cout << _(
82 "Usage: ncpd [OPTIONS]...\n"
83 "\n"
84 "Supported options:\n"
85 "\n"
86 " -d, --dontfork Run in foreground, don't fork\n"
87 " -h, --help Display this text.\n"
88 " -V, --version Print version and exit.\n"
89 " -e, --autoexit Exit after device is disconnected.\n"
90 " -v, --verbose=LOGCLASS Enable logging of LOGCLASS events\n"
91 " Valid log classes are:\n"
92 " m - main program\n"
93 " nl - NCP protocol log\n"
94 " nd - NCP protocol data dump\n"
95 " ll - PLP protocol log\n"
96 " ld - PLP protocol data dump\n"
97 " pl - physical I/O log\n"
98 " ph - physical I/O handshake\n"
99 " pd - physical I/O data dump\n"
100 " all - All of the above\n"
101 " -s, --serial=DEV Use serial device DEV.\n"
102 " -b, --baudrate=RATE Set serial speed to BAUD.\n"
103 );
104 cout <<
105#if DSPEED > 0
106#define SPEEDSTR(x) #x
107 _(" Default: ") << DSPEED << ".\n";
108#else
109 _(" Default: Autocycle 115.2k, 57.6k 38.4k, 19.2k\n");
110#endif
111 cout << _(
112 " -p, --port=[HOST:]PORT Listen on host HOST, port PORT.\n"
113 " Default for HOST: 127.0.0.1\n"
114 " Default for PORT: "
115 ) << DPORT << "\n\n";
116}
117
118static void
120 cerr << _("Try `ncpd --help' for more information") << endl;
121}
122
123static struct option opts[] = {
124 {"dontfork", no_argument, 0, 'd'},
125 {"autoexit", no_argument, 0, 'e'},
126 {"help", no_argument, 0, 'h'},
127 {"version", no_argument, 0, 'V'},
128 {"verbose", required_argument, 0, 'v'},
129 {"port", required_argument, 0, 'p'},
130 {"serial", required_argument, 0, 's'},
131 {"baudrate", required_argument, 0, 'b'},
132 {NULL, 0, 0, 0 }
133};
134
135int
136main(int argc, char **argv)
137{
138 int pid;
139 bool dofork = true;
140
141 int sockNum = cli_utils::lookup_default_port();
142 int baudRate = DSPEED;
143 string host = "127.0.0.1";
144 const char *serialDevice = NULL;
145 unsigned short nverbose = 0;
146 bool autoexit = false;
147
151
152 while (1) {
153 int c = getopt_long(argc, argv, "hdeVb:s:p:v:", opts, NULL);
154 if (c == -1)
155 break;
156 switch (c) {
157 case '?':
158 usage();
159 return -1;
160 case 'V':
161 cout << _("ncpd Version ") << VERSION << endl;
162 return 0;
163 case 'h':
164 help();
165 return 0;
166 case 'v':
167 if (!strcmp(optarg, "nl"))
168 nverbose |= NCP_DEBUG_LOG;
169 if (!strcmp(optarg, "nd"))
170 nverbose |= NCP_DEBUG_DUMP;
171 if (!strcmp(optarg, "ll"))
172 nverbose |= LNK_DEBUG_LOG;
173 if (!strcmp(optarg, "ld"))
174 nverbose |= LNK_DEBUG_DUMP;
175 if (!strcmp(optarg, "pl"))
176 nverbose |= PKT_DEBUG_LOG;
177 if (!strcmp(optarg, "pd"))
178 nverbose |= PKT_DEBUG_DUMP;
179 if (!strcmp(optarg, "ph"))
180 nverbose |= PKT_DEBUG_HANDSHAKE;
181 if (!strcmp(optarg, "m"))
182 nverbose |= NCP_SESSION_LOG;
183 if (!strcmp(optarg, "all")) {
184 nverbose = NCP_DEBUG_LOG | NCP_DEBUG_DUMP |
188 }
189 break;
190 case 'd':
191 dofork = 0;
192 break;
193 case 'e':
194 autoexit = true;
195 break;
196 case 'b':
197 if (!strcmp(optarg, "auto"))
198 baudRate = -1;
199 else
200 baudRate = atoi(optarg);
201 break;
202 case 's':
203 serialDevice = optarg;
204 break;
205 case 'p':
206 if (!cli_utils::parse_port(optarg, &host, &sockNum)) {
207 cout << _("Invalid port definition.") << endl;
208 return 1;
209 }
210 break;
211 }
212 }
213 if (optind < argc) {
214 usage();
215 return -1;
216 }
217
218 if (serialDevice == NULL)
219 serialDevice = DDEV;
220
221 if (dofork)
222 pid = fork();
223 else
224 pid = 0;
225 switch (pid) {
226 case 0:
227 {
228 signal(SIGTERM, term_handler);
229 signal(SIGINT, int_handler);
230
231 // Configure the daemon process before starting up.
232 if (dofork) {
233 openlog("ncpd", LOG_CONS|LOG_PID, LOG_DAEMON);
234 dlog.useSyslog();
235 elog.useSyslog();
236 ilog.useSyslog();
237 setsid();
238 ignore_value(chdir("/"));
239 int devnull = open("/dev/null", O_RDWR, 0);
240 if (devnull != -1) {
241 dup2(devnull, STDIN_FILENO);
242 dup2(devnull, STDOUT_FILENO);
243 dup2(devnull, STDERR_FILENO);
244 if (devnull > 2) {
245 close(devnull);
246 }
247 }
248 }
249
250 // Once our process is fully set up, we can create and start the session.
251 sharedSession = new NCPSession(sockNum,
252 baudRate,
253 host,
254 serialDevice,
255 autoexit,
256 nverbose);
259 delete sharedSession;
260
261 break;
262 }
263 case -1:
264 lerr << "fork: " << strerror(errno) << endl;
265 break;
266 default:
267 exit(0);
268 }
269 linf << _("normal exit") << endl;
270 return 0;
271}
Responsible for orchestrating the high-level life cycle of a daemon-side NCP server and multiplexing ...
Definition: ncp_session.h:41
void cancel()
Mark the session as cancelled.
Definition: ncp_session.cc:229
void wait()
Wait for the session to terminate.
Definition: ncp_session.cc:245
int start()
Creates and manages all the threads necessary to run a full session for communicating with a Psion an...
Definition: ncp_session.cc:219
void useFileDescriptor()
Write logs to the file descriptor passed in the constructor.
Definition: log.h:77
void useSyslog()
Write logs using syslog.
Definition: log.h:69
bool parse_port(const std::string &arg, std::string *host, int *port)
Definition: cli_utils.cc:52
int lookup_default_port()
Definition: cli_utils.cc:43
Definition: doctest.h:522
logbuf dlog(LOG_DEBUG, STDOUT_FILENO)
Definition: ncp_log.cc:35
logbuf elog(LOG_ERR, STDERR_FILENO)
Definition: ncp_log.cc:36
logbuf ilog(LOG_INFO, STDOUT_FILENO)
Definition: ncp_log.cc:34
#define NCP_DEBUG_DUMP
Definition: ncp_log.h:30
#define PKT_DEBUG_HANDSHAKE
Definition: ncp_log.h:35
std::ostream lerr
#define LNK_DEBUG_LOG
Definition: ncp_log.h:31
#define PKT_DEBUG_DUMP
Definition: ncp_log.h:34
#define NCP_SESSION_LOG
Definition: ncp_log.h:36
#define PKT_DEBUG_LOG
Definition: ncp_log.h:33
#define LNK_DEBUG_DUMP
Definition: ncp_log.h:32
#define NCP_DEBUG_LOG
Definition: ncp_log.h:29
std::ostream linf
static void term_handler(int)
Definition: main.cc:63
static void int_handler(int)
Definition: main.cc:71
int main(int argc, char **argv)
Definition: main.cc:136
static void usage()
Definition: main.cc:119
static struct option opts[]
Definition: main.cc:123
static NCPSession * sharedSession
Definition: main.cc:60
static void help()
Definition: main.cc:79
#define _(String)
Definition: plpintl.h:35