4 * This file is a part of the revinetd project
6 * Revinetd is copyright (c) 2003-2008 by Steven M. Gill
7 * and distributed under the GPL.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 #include "relay_agt.h"
32 static const char cvsid
[] = "$Id: revinetd.c,v 1.29 2008/08/28 03:24:59 necrotaur Exp, adapted by ThP $";
35 main(int argc
, char **argv
)
37 /* All variables are initialized to a known invalid value so that they
38 are not used un-initialized. To use them should trip tests or cause
40 static struct option long_options
[] = {
41 /* These options set a flag. */
42 {"help", no_argument
, 0, 'h'},
43 {"daemonize", no_argument
, 0, 'd'},
44 {"relay-agent", no_argument
, 0, 'r'},
45 {"server", no_argument
, 0, 's'},
46 {"listen-client", required_argument
, 0, 'c'},
47 {"listen-relay", required_argument
, 0, 'l'},
48 {"server-host", required_argument
, 0, 'b'},
49 {"target-host", required_argument
, 0, 't'},
50 {"verbose", no_argument
, 0, 'v'},
51 {"quiet", no_argument
, 0, 'q'},
52 {"keep-alive", required_argument
, 0, 'k'},
54 /* getopt_long stores the option index here. */
55 int c
, option_index
= 0;
58 printf("%s - v1.0.2_p5_20200612 - Copyright (c) 2003-2008 Steven M. Gill, et al (201x, 2020)\n", *argv
);
59 printf("%s is distributed under the terms of the GPL\n", *argv
);
60 printf("http://revinetd.sourceforge.net\n\n");
61 exec_name
= strdup(*argv
);
66 c
= getopt_long(argc
, argv
, "hdrsc:l:b:t:qvk:", long_options
,
69 /* Detect the end of the options. */
75 /* If this option set a flag, do nothing else now. */
76 if (long_options
[option_index
].flag
!= 0)
78 printf("option %s", long_options
[option_index
].name
);
80 printf(" with arg %s", optarg
);
86 conf
.verbosity
= VB_QUIET
;
90 if (conf
.server_flag
== FLAG_NONE
) {
91 conf
.server_flag
= FLAG_SERVER
;
93 fprintf(stderr
, "You can only set one mode, either Server or "
94 "Relay Agent, not both.\n\n");
100 if (conf
.server_flag
== FLAG_NONE
) {
101 conf
.server_flag
= FLAG_RELAY
;
103 fprintf(stderr
, "You can only set one mode, either Server or "
104 "Relay Agent, not both.\n\n");
110 if (conf
.server_flag
== FLAG_SERVER
) {
111 conf
.host
= strdup(optarg
);
112 conf
.port
= parse_host_str(conf
.host
);
114 fprintf(stderr
, "You must select Server mode to use -c or "
115 "--listen-client.\n\n");
121 if (conf
.server_flag
== FLAG_SERVER
) {
122 conf
.host2
= strdup(optarg
);
123 conf
.port2
= parse_host_str(conf
.host2
);
125 fprintf(stderr
, "You must select Server mode to use -l or "
126 "--listen-relay.\n\n");
132 if (conf
.server_flag
== FLAG_RELAY
) {
133 conf
.host
= strdup(optarg
);
134 conf
.port
= parse_host_str(conf
.host
);
136 fprintf(stderr
, "You must select Relay Agent mode to use -c "
137 "or --server-host.\n\n");
143 if (conf
.server_flag
== FLAG_RELAY
) {
144 conf
.host2
= strdup(optarg
);
145 conf
.port2
= parse_host_str(conf
.host2
);
147 fprintf(stderr
, "You must select Relay Agent mode to use -t "
148 "or --target-host.\n\n");
157 conf
.keepalive
= atoi(optarg
);
161 if (conf
.daemonize
== 0) {
162 //conf.verbosity = VB_VERBOSE;
168 conf
.verbosity
= VB_QUIET
;
178 /* Print any remaining command line arguments (not options). */
183 if (conf
.daemonize
== TRUE
) {
186 if (pid
> 0) { /* parent */
188 } else if (pid
< 0) { /* error */
194 close(0); close(1); close(2);
197 signal(SIGTERM
, clean_exit
);
198 signal(SIGINT
, clean_exit
);
199 signal(SIGQUIT
, clean_exit
);
200 signal(SIGHUP
, clean_exit
);
202 if (conf
.server_flag
== FLAG_SERVER
) {
203 if (conf
.port
>= 0 && conf
.port2
>= 0) {
204 server(conf
.host
, conf
.port
, conf
.host2
, conf
.port2
);
206 fprintf(stderr
, "Two ports, port1 (-l and --client-port) and "
207 "port2 (-L and --ra-port) must be "
211 } else if (conf
.server_flag
== FLAG_RELAY
) {
212 if (conf
.host
!= NULL
&& conf
.host2
!= NULL
) {
213 relay_agent(conf
.host
, conf
.port
, conf
.host2
, conf
.port2
);
215 fprintf(stderr
, "Both a server (-b and --server-host) and a "
216 "target (-t and --target-host)\nmust be "
231 fprintf(stderr
, "Usage: revinetd -s -c HOST1:PORT1 -l HOST2:PORT2 [-d]"
233 " revinetd -r -b HOST1:PORT1 -t "
234 "HOST2:PORT2 [-d] [-k seconds]\n"
236 "Global arguments:\n"
237 " -s --server\t\tRuns in server mode\n"
238 " -r --relay-agent\tRuns as the relay agent\n"
239 " -d --daemonize\tRuns as a daemon (implies -q)\n"
240 " -h --help\t\tPrints this message and exit\n"
241 " -q --quiet\t\tSurpress all messages\n"
242 " -v --verbose\t\tIncrease verbiosity\n"
244 "Server arguments:\n"
245 " -c HOST1:PORT1 --client-port=HOST1:PORT1\tListen for a client on IP and Port\n"
246 " -l HOST2:PORT2 --ra-port=HOST2:PORT2 \tListen for a relay agent on IP and Port\n"
247 "Relay agent arguments:\n"
248 " required arguments:\n"
249 " -b HOST1:PORT1 --server-host=HOST1:PORT1\tRevinetd server "
251 " -t HOST2:PORT2 --target-host=HOST2:PORT2\tThe target host "
253 " optional arguments:\n"
254 " -k seconds --keep-alive=seconds\tKeep-alive signal interval\n"
255 " \tdefaults to 180 seconds\n\n");
263 OpenSockets
*open_sock
;
265 /* Close all registered sockets. */
266 open_sock
= conf
.open_sock
;
267 while (open_sock
!= NULL
) {
268 if (shutdown(open_sock
->sock
, SHUT_RDWR
) == -1) {
271 close(open_sock
->sock
);
272 open_sock
= open_sock
->next
;
278 // Adapted to search for the colon from the right. (thpi)
280 parse_host_str(char *host_str
)
285 /* Skip any leading spaces. */
286 while (isspace(*host_str
)) { host_str
++; }
288 /* Loop through the line until we reach a ':'. Exit with errors if we
289 stumble on an illegal character. */
290 j
= strlen(host_str
)-1;
292 while (*(host_str
+ j
) != ':') {
293 if (isspace(*(host_str
+ j
))) {
294 *(host_str
+ j
) = '\0'; // remove the trailing padding
298 fprintf(stderr
, "Invalid hostname format.\n");
303 /* Insert a NUL byte at the position of the right-most ':' to delimitate the
304 hostname. And then skip ahead one byte. */
305 *(host_str
+ j
++) = '\0';
308 port
= (unsigned short)atoi(host_str
+ j
);
317 memset(&conf
, 0, sizeof(Conf
));
320 conf
.verbosity
= VB_NORMAL
;
321 conf
.keepalive
= 180L;