keep-alive: drop link with log framework
[fw/openocd] / src / server / server.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2007-2010 Ã˜yvind Harboe                                 *
6  *   oyvind.harboe@zylin.com                                               *
7  *                                                                         *
8  *   Copyright (C) 2008 by Spencer Oliver                                  *
9  *   spen@spen-soft.co.uk                                                  *
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19  *   GNU General Public License for more details.                          *
20  *                                                                         *
21  *   You should have received a copy of the GNU General Public License     *
22  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
23  ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "server.h"
30 #include <helper/time_support.h>
31 #include <target/target.h>
32 #include <target/target_request.h>
33 #include <target/openrisc/jsp_server.h>
34 #include "openocd.h"
35 #include "tcl_server.h"
36 #include "telnet_server.h"
37
38 #include <signal.h>
39
40 #ifdef HAVE_NETDB_H
41 #include <netdb.h>
42 #endif
43
44 #ifndef _WIN32
45 #include <netinet/tcp.h>
46 #endif
47
48 static struct service *services;
49
50 enum shutdown_reason {
51         CONTINUE_MAIN_LOOP,                     /* stay in main event loop */
52         SHUTDOWN_REQUESTED,                     /* set by shutdown command; exit the event loop and quit the debugger */
53         SHUTDOWN_WITH_ERROR_CODE,       /* set by shutdown command; quit with non-zero return code */
54         SHUTDOWN_WITH_SIGNAL_CODE       /* set by sig_handler; exec shutdown then exit with signal as return code */
55 };
56 static enum shutdown_reason shutdown_openocd = CONTINUE_MAIN_LOOP;
57
58 /* store received signal to exit application by killing ourselves */
59 static int last_signal;
60
61 /* set the polling period to 100ms */
62 static int polling_period = 100;
63
64 /* address by name on which to listen for incoming TCP/IP connections */
65 static char *bindto_name;
66
67 static int add_connection(struct service *service, struct command_context *cmd_ctx)
68 {
69         socklen_t address_size;
70         struct connection *c, **p;
71         int retval;
72         int flag = 1;
73
74         c = malloc(sizeof(struct connection));
75         c->fd = -1;
76         c->fd_out = -1;
77         memset(&c->sin, 0, sizeof(c->sin));
78         c->cmd_ctx = copy_command_context(cmd_ctx);
79         c->service = service;
80         c->input_pending = false;
81         c->priv = NULL;
82         c->next = NULL;
83
84         if (service->type == CONNECTION_TCP) {
85                 address_size = sizeof(c->sin);
86
87                 c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
88                 c->fd_out = c->fd;
89
90                 /* This increases performance dramatically for e.g. GDB load which
91                  * does not have a sliding window protocol.
92                  *
93                  * Ignore errors from this fn as it probably just means less performance
94                  */
95                 setsockopt(c->fd,       /* socket affected */
96                         IPPROTO_TCP,                    /* set option at TCP level */
97                         TCP_NODELAY,                    /* name of option */
98                         (char *)&flag,                  /* the cast is historical cruft */
99                         sizeof(int));                   /* length of option value */
100
101                 LOG_INFO("accepting '%s' connection on tcp/%s", service->name, service->port);
102                 retval = service->new_connection(c);
103                 if (retval != ERROR_OK) {
104                         close_socket(c->fd);
105                         LOG_ERROR("attempted '%s' connection rejected", service->name);
106                         command_done(c->cmd_ctx);
107                         free(c);
108                         return retval;
109                 }
110         } else if (service->type == CONNECTION_STDINOUT) {
111                 c->fd = service->fd;
112                 c->fd_out = fileno(stdout);
113
114 #ifdef _WIN32
115                 /* we are using stdin/out so ignore ctrl-c under windoze */
116                 SetConsoleCtrlHandler(NULL, TRUE);
117 #endif
118
119                 /* do not check for new connections again on stdin */
120                 service->fd = -1;
121
122                 LOG_INFO("accepting '%s' connection from pipe", service->name);
123                 retval = service->new_connection(c);
124                 if (retval != ERROR_OK) {
125                         LOG_ERROR("attempted '%s' connection rejected", service->name);
126                         command_done(c->cmd_ctx);
127                         free(c);
128                         return retval;
129                 }
130         } else if (service->type == CONNECTION_PIPE) {
131                 c->fd = service->fd;
132                 /* do not check for new connections again on stdin */
133                 service->fd = -1;
134
135                 char *out_file = alloc_printf("%so", service->port);
136                 c->fd_out = open(out_file, O_WRONLY);
137                 free(out_file);
138                 if (c->fd_out == -1) {
139                         LOG_ERROR("could not open %s", service->port);
140                         command_done(c->cmd_ctx);
141                         free(c);
142                         return ERROR_FAIL;
143                 }
144
145                 LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port);
146                 retval = service->new_connection(c);
147                 if (retval != ERROR_OK) {
148                         LOG_ERROR("attempted '%s' connection rejected", service->name);
149                         command_done(c->cmd_ctx);
150                         free(c);
151                         return retval;
152                 }
153         }
154
155         /* add to the end of linked list */
156         for (p = &service->connections; *p; p = &(*p)->next)
157                 ;
158         *p = c;
159
160         if (service->max_connections != CONNECTION_LIMIT_UNLIMITED)
161                 service->max_connections--;
162
163         return ERROR_OK;
164 }
165
166 static int remove_connection(struct service *service, struct connection *connection)
167 {
168         struct connection **p = &service->connections;
169         struct connection *c;
170
171         /* find connection */
172         while ((c = *p)) {
173                 if (c->fd == connection->fd) {
174                         service->connection_closed(c);
175                         if (service->type == CONNECTION_TCP)
176                                 close_socket(c->fd);
177                         else if (service->type == CONNECTION_PIPE) {
178                                 /* The service will listen to the pipe again */
179                                 c->service->fd = c->fd;
180                         }
181
182                         command_done(c->cmd_ctx);
183
184                         /* delete connection */
185                         *p = c->next;
186                         free(c);
187
188                         if (service->max_connections != CONNECTION_LIMIT_UNLIMITED)
189                                 service->max_connections++;
190
191                         break;
192                 }
193
194                 /* redirect p to next list pointer */
195                 p = &(*p)->next;
196         }
197
198         return ERROR_OK;
199 }
200
201 static void free_service(struct service *c)
202 {
203         free(c->name);
204         free(c->port);
205         free(c);
206 }
207
208 int add_service(const struct service_driver *driver, const char *port,
209                 int max_connections, void *priv)
210 {
211         struct service *c, **p;
212         struct hostent *hp;
213         int so_reuseaddr_option = 1;
214
215         c = malloc(sizeof(struct service));
216
217         c->name = strdup(driver->name);
218         c->port = strdup(port);
219         c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
220         c->fd = -1;
221         c->connections = NULL;
222         c->new_connection_during_keep_alive = driver->new_connection_during_keep_alive_handler;
223         c->new_connection = driver->new_connection_handler;
224         c->input = driver->input_handler;
225         c->connection_closed = driver->connection_closed_handler;
226         c->keep_client_alive = driver->keep_client_alive_handler;
227         c->priv = priv;
228         c->next = NULL;
229         long portnumber;
230         if (strcmp(c->port, "pipe") == 0)
231                 c->type = CONNECTION_STDINOUT;
232         else {
233                 char *end;
234                 portnumber = strtol(c->port, &end, 0);
235                 if (!*end && (parse_long(c->port, &portnumber) == ERROR_OK)) {
236                         c->portnumber = portnumber;
237                         c->type = CONNECTION_TCP;
238                 } else
239                         c->type = CONNECTION_PIPE;
240         }
241
242         if (c->type == CONNECTION_TCP) {
243                 c->max_connections = max_connections;
244
245                 c->fd = socket(AF_INET, SOCK_STREAM, 0);
246                 if (c->fd == -1) {
247                         LOG_ERROR("error creating socket: %s", strerror(errno));
248                         free_service(c);
249                         return ERROR_FAIL;
250                 }
251
252                 setsockopt(c->fd,
253                         SOL_SOCKET,
254                         SO_REUSEADDR,
255                         (void *)&so_reuseaddr_option,
256                         sizeof(int));
257
258                 socket_nonblock(c->fd);
259
260                 memset(&c->sin, 0, sizeof(c->sin));
261                 c->sin.sin_family = AF_INET;
262
263                 if (!bindto_name)
264                         c->sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
265                 else {
266                         hp = gethostbyname(bindto_name);
267                         if (!hp) {
268                                 LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
269                                 close_socket(c->fd);
270                                 free_service(c);
271                                 return ERROR_FAIL;
272                         }
273                         memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
274                 }
275                 c->sin.sin_port = htons(c->portnumber);
276
277                 if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
278                         LOG_ERROR("couldn't bind %s to socket on port %d: %s", c->name, c->portnumber, strerror(errno));
279                         close_socket(c->fd);
280                         free_service(c);
281                         return ERROR_FAIL;
282                 }
283
284 #ifndef _WIN32
285                 int segsize = 65536;
286                 setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG,  &segsize, sizeof(int));
287 #endif
288                 int window_size = 128 * 1024;
289
290                 /* These setsockopt()s must happen before the listen() */
291
292                 setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
293                         (char *)&window_size, sizeof(window_size));
294                 setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
295                         (char *)&window_size, sizeof(window_size));
296
297                 if (listen(c->fd, 1) == -1) {
298                         LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
299                         close_socket(c->fd);
300                         free_service(c);
301                         return ERROR_FAIL;
302                 }
303
304                 struct sockaddr_in addr_in;
305                 addr_in.sin_port = 0;
306                 socklen_t addr_in_size = sizeof(addr_in);
307                 if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
308                         LOG_INFO("Listening on port %hu for %s connections",
309                                  ntohs(addr_in.sin_port), c->name);
310         } else if (c->type == CONNECTION_STDINOUT) {
311                 c->fd = fileno(stdin);
312
313 #ifdef _WIN32
314                 /* for win32 set stdin/stdout to binary mode */
315                 if (_setmode(_fileno(stdout), _O_BINARY) < 0)
316                         LOG_WARNING("cannot change stdout mode to binary");
317                 if (_setmode(_fileno(stdin), _O_BINARY) < 0)
318                         LOG_WARNING("cannot change stdin mode to binary");
319                 if (_setmode(_fileno(stderr), _O_BINARY) < 0)
320                         LOG_WARNING("cannot change stderr mode to binary");
321 #else
322                 socket_nonblock(c->fd);
323 #endif
324         } else if (c->type == CONNECTION_PIPE) {
325 #ifdef _WIN32
326                 /* we currently do not support named pipes under win32
327                  * so exit openocd for now */
328                 LOG_ERROR("Named pipes currently not supported under this os");
329                 free_service(c);
330                 return ERROR_FAIL;
331 #else
332                 /* Pipe we're reading from */
333                 c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
334                 if (c->fd == -1) {
335                         LOG_ERROR("could not open %s", c->port);
336                         free_service(c);
337                         return ERROR_FAIL;
338                 }
339 #endif
340         }
341
342         /* add to the end of linked list */
343         for (p = &services; *p; p = &(*p)->next)
344                 ;
345         *p = c;
346
347         return ERROR_OK;
348 }
349
350 static void remove_connections(struct service *service)
351 {
352         struct connection *connection;
353
354         connection = service->connections;
355
356         while (connection) {
357                 struct connection *tmp;
358
359                 tmp = connection->next;
360                 remove_connection(service, connection);
361                 connection = tmp;
362         }
363 }
364
365 int remove_service(const char *name, const char *port)
366 {
367         struct service *tmp;
368         struct service *prev;
369
370         prev = services;
371
372         for (tmp = services; tmp; prev = tmp, tmp = tmp->next) {
373                 if (!strcmp(tmp->name, name) && !strcmp(tmp->port, port)) {
374                         remove_connections(tmp);
375
376                         if (tmp == services)
377                                 services = tmp->next;
378                         else
379                                 prev->next = tmp->next;
380
381                         if (tmp->type != CONNECTION_STDINOUT)
382                                 close_socket(tmp->fd);
383
384                         free(tmp->priv);
385                         free_service(tmp);
386
387                         return ERROR_OK;
388                 }
389         }
390
391         return ERROR_OK;
392 }
393
394 static int remove_services(void)
395 {
396         struct service *c = services;
397
398         /* loop service */
399         while (c) {
400                 struct service *next = c->next;
401
402                 remove_connections(c);
403
404                 free(c->name);
405
406                 if (c->type == CONNECTION_PIPE) {
407                         if (c->fd != -1)
408                                 close(c->fd);
409                 }
410                 free(c->port);
411                 free(c->priv);
412                 /* delete service */
413                 free(c);
414
415                 /* remember the last service for unlinking */
416                 c = next;
417         }
418
419         services = NULL;
420
421         return ERROR_OK;
422 }
423
424 void server_keep_clients_alive(void)
425 {
426         for (struct service *s = services; s; s = s->next)
427                 if (s->keep_client_alive)
428                         for (struct connection *c = s->connections; c; c = c->next)
429                                 s->keep_client_alive(c);
430 }
431
432 int server_loop(struct command_context *command_context)
433 {
434         struct service *service;
435
436         bool poll_ok = true;
437
438         /* used in select() */
439         fd_set read_fds;
440         int fd_max;
441
442         /* used in accept() */
443         int retval;
444
445         int64_t next_event = timeval_ms() + polling_period;
446
447 #ifndef _WIN32
448         if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
449                 LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
450 #endif
451
452         while (shutdown_openocd == CONTINUE_MAIN_LOOP) {
453                 /* monitor sockets for activity */
454                 fd_max = 0;
455                 FD_ZERO(&read_fds);
456
457                 /* add service and connection fds to read_fds */
458                 for (service = services; service; service = service->next) {
459                         if (service->fd != -1) {
460                                 /* listen for new connections */
461                                 FD_SET(service->fd, &read_fds);
462
463                                 if (service->fd > fd_max)
464                                         fd_max = service->fd;
465                         }
466
467                         if (service->connections) {
468                                 struct connection *c;
469
470                                 for (c = service->connections; c; c = c->next) {
471                                         /* check for activity on the connection */
472                                         FD_SET(c->fd, &read_fds);
473                                         if (c->fd > fd_max)
474                                                 fd_max = c->fd;
475                                 }
476                         }
477                 }
478
479                 struct timeval tv;
480                 tv.tv_sec = 0;
481                 if (poll_ok) {
482                         /* we're just polling this iteration, this is faster on embedded
483                          * hosts */
484                         tv.tv_usec = 0;
485                         retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
486                 } else {
487                         /* Every 100ms, can be changed with "poll_period" command */
488                         int timeout_ms = next_event - timeval_ms();
489                         if (timeout_ms < 0)
490                                 timeout_ms = 0;
491                         else if (timeout_ms > polling_period)
492                                 timeout_ms = polling_period;
493                         tv.tv_usec = timeout_ms * 1000;
494                         /* Only while we're sleeping we'll let others run */
495                         retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
496                 }
497
498                 if (retval == -1) {
499 #ifdef _WIN32
500
501                         errno = WSAGetLastError();
502
503                         if (errno == WSAEINTR)
504                                 FD_ZERO(&read_fds);
505                         else {
506                                 LOG_ERROR("error during select: %s", strerror(errno));
507                                 return ERROR_FAIL;
508                         }
509 #else
510
511                         if (errno == EINTR)
512                                 FD_ZERO(&read_fds);
513                         else {
514                                 LOG_ERROR("error during select: %s", strerror(errno));
515                                 return ERROR_FAIL;
516                         }
517 #endif
518                 }
519
520                 if (retval == 0) {
521                         /* We only execute these callbacks when there was nothing to do or we timed
522                          *out */
523                         target_call_timer_callbacks_now();
524                         next_event = target_timer_next_event();
525                         process_jim_events(command_context);
526
527                         FD_ZERO(&read_fds);     /* eCos leaves read_fds unchanged in this case!  */
528
529                         /* We timed out/there was nothing to do, timeout rather than poll next time
530                          **/
531                         poll_ok = false;
532                 } else {
533                         /* There was something to do, next time we'll just poll */
534                         poll_ok = true;
535                 }
536
537                 /* This is a simple back-off algorithm where we immediately
538                  * re-poll if we did something this time around.
539                  *
540                  * This greatly improves performance of DCC.
541                  */
542                 poll_ok = poll_ok || target_got_message();
543
544                 for (service = services; service; service = service->next) {
545                         /* handle new connections on listeners */
546                         if ((service->fd != -1)
547                                 && (FD_ISSET(service->fd, &read_fds))) {
548                                 if (service->max_connections != 0)
549                                         add_connection(service, command_context);
550                                 else {
551                                         if (service->type == CONNECTION_TCP) {
552                                                 struct sockaddr_in sin;
553                                                 socklen_t address_size = sizeof(sin);
554                                                 int tmp_fd;
555                                                 tmp_fd = accept(service->fd,
556                                                                 (struct sockaddr *)&service->sin,
557                                                                 &address_size);
558                                                 close_socket(tmp_fd);
559                                         }
560                                         LOG_INFO(
561                                                 "rejected '%s' connection, no more connections allowed",
562                                                 service->name);
563                                 }
564                         }
565
566                         /* handle activity on connections */
567                         if (service->connections) {
568                                 struct connection *c;
569
570                                 for (c = service->connections; c; ) {
571                                         if ((c->fd >= 0 && FD_ISSET(c->fd, &read_fds)) || c->input_pending) {
572                                                 retval = service->input(c);
573                                                 if (retval != ERROR_OK) {
574                                                         struct connection *next = c->next;
575                                                         if (service->type == CONNECTION_PIPE ||
576                                                                         service->type == CONNECTION_STDINOUT) {
577                                                                 /* if connection uses a pipe then
578                                                                  * shutdown openocd on error */
579                                                                 shutdown_openocd = SHUTDOWN_REQUESTED;
580                                                         }
581                                                         remove_connection(service, c);
582                                                         LOG_INFO("dropped '%s' connection",
583                                                                 service->name);
584                                                         c = next;
585                                                         continue;
586                                                 }
587                                         }
588                                         c = c->next;
589                                 }
590                         }
591                 }
592
593 #ifdef _WIN32
594                 MSG msg;
595                 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
596                         if (msg.message == WM_QUIT)
597                                 shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
598                 }
599 #endif
600         }
601
602         /* when quit for signal or CTRL-C, run (eventually user implemented) "shutdown" */
603         if (shutdown_openocd == SHUTDOWN_WITH_SIGNAL_CODE)
604                 command_run_line(command_context, "shutdown");
605
606         return shutdown_openocd == SHUTDOWN_WITH_ERROR_CODE ? ERROR_FAIL : ERROR_OK;
607 }
608
609 static void sig_handler(int sig)
610 {
611         /* store only first signal that hits us */
612         if (shutdown_openocd == CONTINUE_MAIN_LOOP) {
613                 shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
614                 last_signal = sig;
615                 LOG_DEBUG("Terminating on Signal %d", sig);
616         } else
617                 LOG_DEBUG("Ignored extra Signal %d", sig);
618 }
619
620
621 #ifdef _WIN32
622 BOOL WINAPI control_handler(DWORD ctrl_type)
623 {
624         shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
625         return TRUE;
626 }
627 #else
628 static void sigkey_handler(int sig)
629 {
630         /* ignore keystroke generated signals if not in foreground process group */
631
632         if (tcgetpgrp(STDIN_FILENO) > 0)
633                 sig_handler(sig);
634         else
635                 LOG_DEBUG("Ignored Signal %d", sig);
636 }
637 #endif
638
639
640 int server_host_os_entry(void)
641 {
642         /* this currently only calls WSAStartup on native win32 systems
643          * before any socket operations are performed.
644          * This is an issue if you call init in your config script */
645
646 #ifdef _WIN32
647         WORD version_requested;
648         WSADATA wsadata;
649
650         version_requested = MAKEWORD(2, 2);
651
652         if (WSAStartup(version_requested, &wsadata) != 0) {
653                 LOG_ERROR("Failed to Open Winsock");
654                 return ERROR_FAIL;
655         }
656 #endif
657         return ERROR_OK;
658 }
659
660 int server_host_os_close(void)
661 {
662 #ifdef _WIN32
663         WSACleanup();
664 #endif
665         return ERROR_OK;
666 }
667
668 int server_preinit(void)
669 {
670 #ifdef _WIN32
671         /* register ctrl-c handler */
672         SetConsoleCtrlHandler(control_handler, TRUE);
673
674         signal(SIGBREAK, sig_handler);
675         signal(SIGINT, sig_handler);
676 #else
677         signal(SIGHUP, sig_handler);
678         signal(SIGPIPE, sig_handler);
679         signal(SIGQUIT, sigkey_handler);
680         signal(SIGINT, sigkey_handler);
681 #endif
682         signal(SIGTERM, sig_handler);
683         signal(SIGABRT, sig_handler);
684
685         return ERROR_OK;
686 }
687
688 int server_init(struct command_context *cmd_ctx)
689 {
690         int ret = tcl_init();
691
692         if (ret != ERROR_OK)
693                 return ret;
694
695         ret = telnet_init("Open On-Chip Debugger");
696
697         if (ret != ERROR_OK) {
698                 remove_services();
699                 return ret;
700         }
701
702         return ERROR_OK;
703 }
704
705 int server_quit(void)
706 {
707         remove_services();
708         target_quit();
709
710 #ifdef _WIN32
711         SetConsoleCtrlHandler(control_handler, FALSE);
712
713         return ERROR_OK;
714 #endif
715
716         /* return signal number so we can kill ourselves */
717         return last_signal;
718 }
719
720 void server_free(void)
721 {
722         tcl_service_free();
723         telnet_service_free();
724         jsp_service_free();
725
726         free(bindto_name);
727 }
728
729 void exit_on_signal(int sig)
730 {
731 #ifndef _WIN32
732         /* bring back default system handler and kill yourself */
733         signal(sig, SIG_DFL);
734         kill(getpid(), sig);
735 #endif
736 }
737
738 int connection_write(struct connection *connection, const void *data, int len)
739 {
740         if (len == 0) {
741                 /* successful no-op. Sockets and pipes behave differently here... */
742                 return 0;
743         }
744         if (connection->service->type == CONNECTION_TCP)
745                 return write_socket(connection->fd_out, data, len);
746         else
747                 return write(connection->fd_out, data, len);
748 }
749
750 int connection_read(struct connection *connection, void *data, int len)
751 {
752         if (connection->service->type == CONNECTION_TCP)
753                 return read_socket(connection->fd, data, len);
754         else
755                 return read(connection->fd, data, len);
756 }
757
758 /* tell the server we want to shut down */
759 COMMAND_HANDLER(handle_shutdown_command)
760 {
761         LOG_USER("shutdown command invoked");
762
763         shutdown_openocd = SHUTDOWN_REQUESTED;
764
765         if (CMD_ARGC == 1) {
766                 if (!strcmp(CMD_ARGV[0], "error")) {
767                         shutdown_openocd = SHUTDOWN_WITH_ERROR_CODE;
768                         return ERROR_FAIL;
769                 }
770         }
771
772         return ERROR_COMMAND_CLOSE_CONNECTION;
773 }
774
775 COMMAND_HANDLER(handle_poll_period_command)
776 {
777         if (CMD_ARGC == 0)
778                 LOG_WARNING("You need to set a period value");
779         else
780                 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], polling_period);
781
782         LOG_INFO("set servers polling period to %ums", polling_period);
783
784         return ERROR_OK;
785 }
786
787 COMMAND_HANDLER(handle_bindto_command)
788 {
789         switch (CMD_ARGC) {
790                 case 0:
791                         command_print(CMD, "bindto name: %s", bindto_name);
792                         break;
793                 case 1:
794                         free(bindto_name);
795                         bindto_name = strdup(CMD_ARGV[0]);
796                         break;
797                 default:
798                         return ERROR_COMMAND_SYNTAX_ERROR;
799         }
800         return ERROR_OK;
801 }
802
803 static const struct command_registration server_command_handlers[] = {
804         {
805                 .name = "shutdown",
806                 .handler = &handle_shutdown_command,
807                 .mode = COMMAND_ANY,
808                 .usage = "",
809                 .help = "shut the server down",
810         },
811         {
812                 .name = "poll_period",
813                 .handler = &handle_poll_period_command,
814                 .mode = COMMAND_ANY,
815                 .usage = "",
816                 .help = "set the servers polling period",
817         },
818         {
819                 .name = "bindto",
820                 .handler = &handle_bindto_command,
821                 .mode = COMMAND_CONFIG,
822                 .usage = "[name]",
823                 .help = "Specify address by name on which to listen for "
824                         "incoming TCP/IP connections",
825         },
826         COMMAND_REGISTRATION_DONE
827 };
828
829 int server_register_commands(struct command_context *cmd_ctx)
830 {
831         int retval = telnet_register_commands(cmd_ctx);
832         if (retval != ERROR_OK)
833                 return retval;
834
835         retval = tcl_register_commands(cmd_ctx);
836         if (retval != ERROR_OK)
837                 return retval;
838
839         retval = jsp_register_commands(cmd_ctx);
840         if (retval != ERROR_OK)
841                 return retval;
842
843         return register_commands(cmd_ctx, NULL, server_command_handlers);
844 }
845
846 COMMAND_HELPER(server_port_command, unsigned short *out)
847 {
848         switch (CMD_ARGC) {
849                 case 0:
850                         command_print(CMD, "%d", *out);
851                         break;
852                 case 1:
853                 {
854                         uint16_t port;
855                         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
856                         *out = port;
857                         break;
858                 }
859                 default:
860                         return ERROR_COMMAND_SYNTAX_ERROR;
861         }
862         return ERROR_OK;
863 }
864
865 COMMAND_HELPER(server_pipe_command, char **out)
866 {
867         switch (CMD_ARGC) {
868                 case 0:
869                         command_print(CMD, "%s", *out);
870                         break;
871                 case 1:
872                 {
873                         if (CMD_CTX->mode == COMMAND_EXEC) {
874                                 LOG_WARNING("unable to change server port after init");
875                                 return ERROR_COMMAND_ARGUMENT_INVALID;
876                         }
877                         free(*out);
878                         *out = strdup(CMD_ARGV[0]);
879                         break;
880                 }
881                 default:
882                         return ERROR_COMMAND_SYNTAX_ERROR;
883         }
884         return ERROR_OK;
885 }