1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
29 #include "telnet_server.h"
37 #include <sys/types.h>
41 service_t
*services
= NULL
;
43 /* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
44 static int shutdown_openocd
= 0;
45 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
47 int add_connection(service_t
*service
, command_context_t
*cmd_ctx
)
49 unsigned int address_size
;
53 c
= malloc(sizeof(connection_t
));
55 memset(&c
->sin
, 0, sizeof(c
->sin
));
56 c
->cmd_ctx
= copy_command_context(cmd_ctx
);
62 address_size
= sizeof(c
->sin
);
63 c
->fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
65 if ((retval
= service
->new_connection(c
)) == ERROR_OK
)
67 INFO("accepted '%s' connection from %i", service
->name
, c
->sin
.sin_port
);
72 INFO("attempted '%s' connection rejected", service
->name
);
76 if (service
->connections
)
78 for (p
= service
->connections
; p
&& p
->next
; p
= p
->next
);
84 service
->connections
= c
;
87 service
->max_connections
--;
92 int remove_connection(service_t
*service
, connection_t
*connection
)
94 connection_t
*c
= service
->connections
;
99 connection_t
*next
= c
->next
;
101 if (c
->fd
== connection
->fd
)
103 service
->connections
= next
;
104 service
->connection_closed(c
);
107 command_done(c
->cmd_ctx
);
109 /* delete connection */
112 service
->max_connections
++;
116 /* remember the last connection for unlinking */
123 int add_service(char *name
, enum connection_type type
, unsigned short port
, int max_connections
, new_connection_handler_t new_connection_handler
, input_handler_t input_handler
, connection_closed_handler_t connection_closed_handler
, void *priv
)
126 int so_reuseaddr_option
= 1;
128 c
= malloc(sizeof(service_t
));
130 c
->name
= strdup(name
);
133 c
->max_connections
= max_connections
;
135 c
->connections
= NULL
;
136 c
->new_connection
= new_connection_handler
;
137 c
->input
= input_handler
;
138 c
->connection_closed
= connection_closed_handler
;
142 if ((c
->fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
144 ERROR("error creating socket: %s", strerror(errno
));
148 setsockopt(c
->fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
150 socket_nonblock(c
->fd
);
152 memset(&c
->sin
, 0, sizeof(c
->sin
));
153 c
->sin
.sin_family
= AF_INET
;
154 c
->sin
.sin_addr
.s_addr
= INADDR_ANY
;
155 c
->sin
.sin_port
= htons(port
);
157 if (bind(c
->fd
, (struct sockaddr
*)&c
->sin
, sizeof(c
->sin
)) == -1)
159 ERROR("couldn't bind to socket: %s", strerror(errno
));
163 if (listen(c
->fd
, 1) == -1)
165 ERROR("couldn't listen on socket: %s", strerror(errno
));
171 for (p
= services
; p
&& p
->next
; p
= p
->next
);
183 int remove_service(unsigned short port
)
185 service_t
*c
= services
;
190 service_t
*next
= c
->next
;
204 /* remember the last service for unlinking */
211 int remove_services()
213 service_t
*c
= services
;
218 service_t
*next
= c
->next
;
229 /* remember the last service for unlinking */
238 int server_loop(command_context_t
*command_context
)
242 /* used in select() */
247 /* used in accept() */
251 if (signal(SIGPIPE
, SIG_IGN
) == SIG_ERR
)
252 ERROR("couldn't set SIGPIPE to SIG_IGN");
255 /* do regular tasks after at most 10ms */
259 while(!shutdown_openocd
)
261 /* monitor sockets for acitvity */
265 /* add service and connection fds to read_fds */
266 for (service
= services
; service
; service
= service
->next
)
268 if (service
->fd
!= -1)
270 /* listen for new connections */
271 FD_SET(service
->fd
, &read_fds
);
273 if (service
->fd
> fd_max
)
274 fd_max
= service
->fd
;
277 if (service
->connections
)
281 for (c
= service
->connections
; c
; c
= c
->next
)
283 /* check for activity on the connection */
284 FD_SET(c
->fd
, &read_fds
);
292 /* add STDIN to read_fds */
293 FD_SET(fileno(stdin
), &read_fds
);
296 if ((retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
)) == -1)
300 errno
= WSAGetLastError();
302 if (errno
== WSAEINTR
)
306 ERROR("error during select: %s", strerror(errno
));
315 ERROR("error during select: %s", strerror(errno
));
321 target_call_timer_callbacks();
325 /* do regular tasks after at most 100ms */
330 for (service
= services
; service
; service
= service
->next
)
332 /* handle new connections on listeners */
333 if ((service
->fd
!= -1)
334 && (FD_ISSET(service
->fd
, &read_fds
)))
336 if (service
->max_connections
> 0)
337 add_connection(service
, command_context
);
340 struct sockaddr_in sin
;
341 unsigned int address_size
= sizeof(sin
);
343 tmp_fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
344 close_socket(tmp_fd
);
345 INFO("rejected '%s' connection, no more connections allowed", service
->name
);
349 /* handle activity on connections */
350 if (service
->connections
)
354 for (c
= service
->connections
; c
;)
356 if ((FD_ISSET(c
->fd
, &read_fds
)) || c
->input_pending
)
358 if (service
->input(c
) != ERROR_OK
)
360 connection_t
*next
= c
->next
;
361 remove_connection(service
, c
);
362 INFO("dropped '%s' connection", service
->name
);
373 if (FD_ISSET(fileno(stdin
), &read_fds
))
375 if (getc(stdin
) == 'x')
377 shutdown_openocd
= 1;
382 while (PeekMessage(&msg
,NULL
,0,0,PM_REMOVE
))
384 if (msg
.message
== WM_QUIT
)
385 shutdown_openocd
= 1;
394 BOOL WINAPI
ControlHandler(DWORD dwCtrlType
)
396 shutdown_openocd
= 1;
400 void sig_handler(int sig
) {
401 shutdown_openocd
= 1;
408 WORD wVersionRequested
;
411 wVersionRequested
= MAKEWORD( 2, 2 );
413 if (WSAStartup(wVersionRequested
, &wsaData
) != 0)
415 ERROR("Failed to Open Winsock");
419 SetConsoleCtrlHandler( ControlHandler
, TRUE
);
421 signal(SIGINT
, sig_handler
);
422 signal(SIGTERM
, sig_handler
);
423 signal(SIGBREAK
, sig_handler
);
424 signal(SIGABRT
, sig_handler
);
437 SetConsoleCtrlHandler( ControlHandler
, FALSE
);
443 int server_register_commands(command_context_t
*context
)
445 register_command(context
, NULL
, "shutdown", handle_shutdown_command
,
446 COMMAND_ANY
, "shut the server down");
451 /* tell the server we want to shut down */
452 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
454 shutdown_openocd
= 1;
456 return ERROR_COMMAND_CLOSE_CONNECTION
;
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)