1
1
#include "server.h"
2
2
3
+ #define TTYD_VERSION "1.0.0"
4
+
3
5
volatile bool force_exit = false;
4
6
struct lws_context * context ;
5
7
struct tty_server * server ;
@@ -32,58 +34,70 @@ static const struct option options[] = {
32
34
{"ssl-key" , required_argument , NULL , 'K' },
33
35
{"ssl-ca" , required_argument , NULL , 'A' },
34
36
{"debug" , required_argument , NULL , 'd' },
37
+ {"version" , no_argument , NULL , 'v' },
35
38
{"help" , no_argument , NULL , 'h' },
36
39
{NULL , 0 , 0 , 0 }
37
40
};
38
41
static const char * opt_string = "p:i:c:u:g:s:r:aSC:K:A:d:vh" ;
39
42
40
43
void print_help () {
41
44
fprintf (stderr , "ttyd is a tool for sharing terminal over the web\n\n"
42
- "USAGE: ttyd [options] <command> [<arguments...>]\n\n"
43
- "OPTIONS:\n"
44
- "\t--port, -p Port to listen (default: 7681)\n"
45
- "\t--interface, -i Network interface to bind\n"
46
- "\t--credential, -c Credential for Basic Authentication (format: username:password)\n"
47
- "\t--uid, -u User id to run with\n"
48
- "\t--gid, -g Group id to run with\n"
49
- "\t--signal, -s Signal to send to the command when exit it (default: SIGHUP)\n"
50
- "\t--reconnect, -r Time to reconnect for the client in seconds (default: 10)\n"
51
- "\t--ssl, -S Enable ssl\n"
52
- "\t--ssl-cert, -C Ssl certificate file path\n"
53
- "\t--ssl-key, -K Ssl key file path\n"
54
- "\t--ssl-ca, -A Ssl ca file path\n"
55
- "\t--debug, -d Set log level (0-9, default: 7)\n"
56
- "\t--help, -h Print this text and exit\n"
45
+ "USAGE:\n"
46
+ " ttyd [options] <command> [<arguments...>]\n\n"
47
+ "VERSION:\n"
48
+ " %s\n\n"
49
+ "OPTIONS:\n"
50
+ " --port, -p Port to listen (default: 7681)\n"
51
+ " --interface, -i Network interface to bind\n"
52
+ " --credential, -c Credential for Basic Authentication (format: username:password)\n"
53
+ " --uid, -u User id to run with\n"
54
+ " --gid, -g Group id to run with\n"
55
+ " --signal, -s Signal to send to the command when exit it (default: SIGHUP)\n"
56
+ " --reconnect, -r Time to reconnect for the client in seconds (default: 10)\n"
57
+ " --ssl, -S Enable ssl\n"
58
+ " --ssl-cert, -C Ssl certificate file path\n"
59
+ " --ssl-key, -K Ssl key file path\n"
60
+ " --ssl-ca, -A Ssl ca file path\n"
61
+ " --debug, -d Set log level (0-9, default: 7)\n"
62
+ " --version, -v Print the version and exit\n"
63
+ " --help, -h Print this text and exit\n" ,
64
+ TTYD_VERSION
57
65
);
58
66
}
59
67
60
68
struct tty_server *
61
- tty_server_new (int argc , char * * argv ) {
69
+ tty_server_new (int argc , char * * argv , int start ) {
62
70
struct tty_server * ts ;
63
71
size_t cmd_len = 0 ;
64
72
65
73
ts = t_malloc (sizeof (struct tty_server ));
74
+
75
+ memset (ts , 0 , sizeof (struct tty_server ));
66
76
LIST_INIT (& ts -> clients );
67
77
ts -> client_count = 0 ;
68
- ts -> credential = NULL ;
69
78
ts -> reconnect = 10 ;
70
79
ts -> sig_code = SIGHUP ;
71
80
ts -> sig_name = strdup ("SIGHUP" );
72
- ts -> argv = t_malloc (sizeof (char * ) * (argc + 1 ));
73
- for (int i = 0 ; i < argc ; i ++ ) {
74
- ts -> argv [i ] = strdup (argv [i ]);
81
+ if (start == argc )
82
+ return ts ;
83
+
84
+ int cmd_argc = argc - start ;
85
+ char * * cmd_argv = & argv [start ];
86
+ ts -> argv = t_malloc (sizeof (char * ) * (cmd_argc + 1 ));
87
+ for (int i = 0 ; i < cmd_argc ; i ++ ) {
88
+ ts -> argv [i ] = strdup (cmd_argv [i ]);
75
89
cmd_len += strlen (ts -> argv [i ]);
76
- if (i != argc - 1 ) {
90
+ if (i != cmd_argc - 1 ) {
77
91
cmd_len ++ ; // for space
78
92
}
79
93
}
80
- ts -> argv [argc ] = NULL ;
94
+ ts -> argv [cmd_argc ] = NULL ;
81
95
82
96
ts -> command = t_malloc (cmd_len );
83
97
char * ptr = ts -> command ;
84
- for (int i = 0 ; i < argc ; i ++ ) {
98
+ for (int i = 0 ; i < cmd_argc ; i ++ ) {
85
99
ptr = stpcpy (ptr , ts -> argv [i ]);
86
- if (i != argc - 1 ) {
100
+ if (i != cmd_argc - 1 ) {
87
101
sprintf (ptr ++ , "%c" , ' ' );
88
102
}
89
103
}
@@ -118,7 +132,7 @@ calc_command_start(int argc, char **argv) {
118
132
while (getopt_long (argc_copy , argv_copy , opt_string , options , NULL ) != -1 )
119
133
;
120
134
121
- int start = -1 ;
135
+ int start = argc ;
122
136
if (optind < argc ) {
123
137
char * command = argv_copy [optind ];
124
138
for (int i = 0 ; i < argc ; i ++ ) {
@@ -144,17 +158,13 @@ calc_command_start(int argc, char **argv) {
144
158
145
159
int
146
160
main (int argc , char * * argv ) {
147
- if (argc == 1 || strcmp ( argv [ 1 ], "-h" ) == 0 || strcmp ( argv [ 1 ], "--help" ) == 0 ) {
161
+ if (argc == 1 ) {
148
162
print_help ();
149
- exit ( 0 ) ;
163
+ return 0 ;
150
164
}
151
- // parse command line
165
+
152
166
int start = calc_command_start (argc , argv );
153
- if (start < 0 ) {
154
- fprintf (stderr , "ttyd: missing start command\n" );
155
- exit (1 );
156
- }
157
- server = tty_server_new (argc - start , & argv [start ]);
167
+ server = tty_server_new (argc , argv , start );
158
168
159
169
struct lws_context_creation_info info ;
160
170
memset (& info , 0 , sizeof (info ));
@@ -184,11 +194,18 @@ main(int argc, char **argv) {
184
194
case 'h' :
185
195
print_help ();
186
196
return 0 ;
197
+ case 'v' :
198
+ printf ("ttyd version %s\n" , TTYD_VERSION );
199
+ return 0 ;
187
200
case 'd' :
188
201
debug_level = atoi (optarg );
189
202
break ;
190
203
case 'p' :
191
204
info .port = atoi (optarg );
205
+ if (info .port < 0 ) {
206
+ fprintf (stderr , "ttyd: invalid port: %s\n" , optarg );
207
+ return -1 ;
208
+ }
192
209
break ;
193
210
case 'i' :
194
211
strncpy (iface , optarg , sizeof (iface ));
@@ -220,6 +237,10 @@ main(int argc, char **argv) {
220
237
break ;
221
238
case 'r' :
222
239
server -> reconnect = atoi (optarg );
240
+ if (server -> reconnect <= 0 ) {
241
+ fprintf (stderr , "ttyd: invalid reconnect: %s\n" , optarg );
242
+ return -1 ;
243
+ }
223
244
break ;
224
245
case 'S' :
225
246
ssl = true;
@@ -240,10 +261,15 @@ main(int argc, char **argv) {
240
261
break ;
241
262
default :
242
263
print_help ();
243
- exit ( 1 ) ;
264
+ return -1 ;
244
265
}
245
266
}
246
267
268
+ if (server -> command == NULL || strlen (server -> command ) == 0 ) {
269
+ fprintf (stderr , "ttyd: missing start command\n" );
270
+ return -1 ;
271
+ }
272
+
247
273
lws_set_log_level (debug_level , NULL );
248
274
249
275
if (strlen (iface ) > 0 )
@@ -276,7 +302,7 @@ main(int argc, char **argv) {
276
302
context = lws_create_context (& info );
277
303
if (context == NULL ) {
278
304
lwsl_err ("libwebsockets init failed\n" );
279
- return - 1 ;
305
+ return 1 ;
280
306
}
281
307
282
308
lwsl_notice ("TTY configuration:\n" );
0 commit comments