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
);
77 /* add to the end of linked list */
78 for (p
= &service
->connections
; *p
; p
= &(*p
)->next
);
81 service
->max_connections
--;
86 int remove_connection(service_t
*service
, connection_t
*connection
)
88 connection_t
**p
= &service
->connections
;
94 if (c
->fd
== connection
->fd
)
96 service
->connection_closed(c
);
98 command_done(c
->cmd_ctx
);
100 /* delete connection */
104 service
->max_connections
++;
108 /* redirect p to next list pointer */
115 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
)
118 int so_reuseaddr_option
= 1;
120 c
= malloc(sizeof(service_t
));
122 c
->name
= strdup(name
);
125 c
->max_connections
= max_connections
;
127 c
->connections
= NULL
;
128 c
->new_connection
= new_connection_handler
;
129 c
->input
= input_handler
;
130 c
->connection_closed
= connection_closed_handler
;
134 if ((c
->fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
136 ERROR("error creating socket: %s", strerror(errno
));
140 setsockopt(c
->fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
142 socket_nonblock(c
->fd
);
144 memset(&c
->sin
, 0, sizeof(c
->sin
));
145 c
->sin
.sin_family
= AF_INET
;
146 c
->sin
.sin_addr
.s_addr
= INADDR_ANY
;
147 c
->sin
.sin_port
= htons(port
);
149 if (bind(c
->fd
, (struct sockaddr
*)&c
->sin
, sizeof(c
->sin
)) == -1)
151 ERROR("couldn't bind to socket: %s", strerror(errno
));
155 if (listen(c
->fd
, 1) == -1)
157 ERROR("couldn't listen on socket: %s", strerror(errno
));
161 /* add to the end of linked list */
162 for (p
= &services
; *p
; p
= &(*p
)->next
);
168 int remove_service(unsigned short port
)
170 service_t
**p
= &services
;
189 /* redirect p to next list pointer */
196 int remove_services()
198 service_t
*c
= services
;
203 service_t
*next
= c
->next
;
214 /* remember the last service for unlinking */
223 int server_loop(command_context_t
*command_context
)
227 /* used in select() */
232 /* used in accept() */
236 if (signal(SIGPIPE
, SIG_IGN
) == SIG_ERR
)
237 ERROR("couldn't set SIGPIPE to SIG_IGN");
240 /* do regular tasks after at most 10ms */
244 while(!shutdown_openocd
)
246 /* monitor sockets for acitvity */
250 /* add service and connection fds to read_fds */
251 for (service
= services
; service
; service
= service
->next
)
253 if (service
->fd
!= -1)
255 /* listen for new connections */
256 FD_SET(service
->fd
, &read_fds
);
258 if (service
->fd
> fd_max
)
259 fd_max
= service
->fd
;
262 if (service
->connections
)
266 for (c
= service
->connections
; c
; c
= c
->next
)
268 /* check for activity on the connection */
269 FD_SET(c
->fd
, &read_fds
);
277 /* add STDIN to read_fds */
278 FD_SET(fileno(stdin
), &read_fds
);
281 retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
);
287 errno
= WSAGetLastError();
289 if (errno
== WSAEINTR
)
293 ERROR("error during select: %s", strerror(errno
));
304 ERROR("error during select: %s", strerror(errno
));
310 target_call_timer_callbacks();
314 /* do regular tasks after at most 100ms */
317 FD_ZERO(&read_fds
); /* eCos leaves read_fds unchanged in this case! */
320 for (service
= services
; service
; service
= service
->next
)
322 /* handle new connections on listeners */
323 if ((service
->fd
!= -1)
324 && (FD_ISSET(service
->fd
, &read_fds
)))
326 if (service
->max_connections
> 0)
328 add_connection(service
, command_context
);
332 struct sockaddr_in sin
;
333 unsigned int address_size
= sizeof(sin
);
335 tmp_fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
336 close_socket(tmp_fd
);
337 INFO("rejected '%s' connection, no more connections allowed", service
->name
);
341 /* handle activity on connections */
342 if (service
->connections
)
346 for (c
= service
->connections
; c
;)
348 if ((FD_ISSET(c
->fd
, &read_fds
)) || c
->input_pending
)
350 if (service
->input(c
) != ERROR_OK
)
352 connection_t
*next
= c
->next
;
353 remove_connection(service
, c
);
354 INFO("dropped '%s' connection", service
->name
);
365 if (FD_ISSET(fileno(stdin
), &read_fds
))
367 if (getc(stdin
) == 'x')
369 shutdown_openocd
= 1;
374 while (PeekMessage(&msg
,NULL
,0,0,PM_REMOVE
))
376 if (msg
.message
== WM_QUIT
)
377 shutdown_openocd
= 1;
386 BOOL WINAPI
ControlHandler(DWORD dwCtrlType
)
388 shutdown_openocd
= 1;
392 void sig_handler(int sig
) {
393 shutdown_openocd
= 1;
400 WORD wVersionRequested
;
403 wVersionRequested
= MAKEWORD( 2, 2 );
405 if (WSAStartup(wVersionRequested
, &wsaData
) != 0)
407 ERROR("Failed to Open Winsock");
411 SetConsoleCtrlHandler( ControlHandler
, TRUE
);
413 signal(SIGINT
, sig_handler
);
414 signal(SIGTERM
, sig_handler
);
415 signal(SIGBREAK
, sig_handler
);
416 signal(SIGABRT
, sig_handler
);
429 SetConsoleCtrlHandler( ControlHandler
, FALSE
);
435 int server_register_commands(command_context_t
*context
)
437 register_command(context
, NULL
, "shutdown", handle_shutdown_command
,
438 COMMAND_ANY
, "shut the server down");
443 /* tell the server we want to shut down */
444 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
446 shutdown_openocd
= 1;
448 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)