shell_server_pty.c
Go to the documentation of this file.
1 /**
2  * @file shell_server_pty.c
3  * @brief Pseudo-terminal emulation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSH Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SHELL_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ssh/ssh.h"
36 #include "shell/shell_server.h"
37 #include "shell/shell_server_pty.h"
39 #include "debug.h"
40 
41 //Check SSH stack configuration
42 #if (SHELL_SERVER_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Process window resize event
47  * @param[in] session Handle referencing an shell session
48  * @return Error code
49  **/
50 
52 {
53  error_t error;
54  uint_t x;
55  uint_t y;
56  uint_t cursorPos;
57  char_t buffer[32];
58  size_t n = 0;
59  size_t i;
60  uint32_t newTermWidth;
61  uint32_t newTermHeight;
62 
63  //Acknowledge window resize event
64  session->windowResize = FALSE;
65 
66  //Retrieve the new dimensions of the terminal
67  newTermWidth = session->newTermWidth;
68  newTermHeight = session->newTermHeight;
69 
70  //Check client's identification string
71  if(osStrstr(session->channel->connection->clientId, "Bitvise") != NULL ||
72  osStrstr(session->channel->connection->clientId, "PuTTY") != NULL ||
73  osStrstr(session->channel->connection->clientId, "SmartFTP") != NULL ||
74  osStrstr(session->channel->connection->clientId, "libssh2") != NULL)
75  {
76  //Determine the current position of the cursor
77  cursorPos = session->promptLen + session->bufferPos;
78  y = cursorPos / session->termWidth;
79 
80  //Clear command line
81  n += osSprintf(buffer + n, "\r");
82 
83  if(y > 0)
84  {
85  n += osSprintf(buffer + n, VT100_MOVE_CURSOR_UP_N, y);
86  }
87 
88  n += osSprintf(buffer + n, VT100_CLEAR_SCREEN_DOWN);
89 
90  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
91  NULL, 0);
92 
93  //Check status code
94  if(!error)
95  {
96  //Display shell prompt
97  error = sshWriteChannel(session->channel, session->prompt,
98  session->promptLen, NULL, 0);
99  }
100 
101  //Check status code
102  if(!error)
103  {
104  //Display command line
105  error = sshWriteChannel(session->channel, session->buffer,
106  session->bufferLen, NULL, 0);
107  }
108 
109  //Check status code
110  if(!error)
111  {
112  //Determine the current position of the cursor
113  cursorPos = session->promptLen + session->bufferLen;
114 
115  //Wrap to the next line if necessary
116  if((cursorPos % newTermWidth) == 0)
117  {
118  error = sshWriteChannel(session->channel, " \r", 2, NULL, 0);
119  }
120  }
121  }
122  else if(osStrstr(session->channel->connection->clientId, "TTSSH") != NULL)
123  {
124  //Clear screen
126 
127  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
128  NULL, 0);
129 
130  //Check status code
131  if(!error)
132  {
133  //Display shell prompt
134  error = sshWriteChannel(session->channel, session->prompt,
135  session->promptLen, NULL, 0);
136  }
137 
138  //Display command line
139  for(i = 0; i < session->bufferLen && !error; )
140  {
141  //Determine the current position of the cursor
142  cursorPos = session->promptLen + i;
143  n = cursorPos % newTermWidth;
144  n = newTermWidth - n;
145 
146  n = MIN(n, session->bufferLen - i);
147 
148  error = sshWriteChannel(session->channel, session->buffer + i, n,
149  NULL, 0);
150 
151  i += n;
152 
153  //Check status code
154  if(!error)
155  {
156  //Determine the current position of the cursor
157  cursorPos = session->promptLen + i;
158 
159  //Wrap to the next line if necessary
160  if((cursorPos % newTermWidth) == 0)
161  {
162  error = sshWriteChannel(session->channel, "\r\n", 2, NULL, 0);
163  }
164  }
165  }
166 
167  //Check status code
168  if(!error)
169  {
170  //Determine the current position of the cursor
171  cursorPos = session->promptLen + session->bufferPos;
172  x = cursorPos % newTermWidth;
173  y = cursorPos / newTermWidth;
174 
175  //Set cursor to home
176  n = osSprintf(buffer, VT100_HOME);
177 
178  //Move cursor to the desired position
179  if(y > 0)
180  {
181  n += osSprintf(buffer + n, VT100_MOVE_CURSOR_DOWN_N, y);
182  }
183 
184  if(x > 0)
185  {
186  n += osSprintf(buffer + n, VT100_MOVE_CURSOR_RIGHT_N, x);
187  }
188 
189  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
190  NULL, 0);
191  }
192  }
193  else
194  {
195  //Ignore window resize event
196  error = NO_ERROR;
197  }
198 
199  //Update the dimensions of the terminal
200  session->termWidth = newTermWidth;
201  session->termHeight = newTermHeight;
202 
203  //Return status code
204  return error;
205 }
206 
207 
208 /**
209  * @brief Process received character
210  * @param[in] session Handle referencing an shell session
211  * @return Error code
212  **/
213 
215 {
216  error_t error;
217  size_t n;
218  char_t c;
219  SshChannel *channel;
220 
221  //Retrieve SSH channel handle
222  channel = session->channel;
223 
224  //Read a single character
225  error = sshReadChannel(channel, &c, 1, &n, 0);
226 
227  //Check status code
228  if(error == NO_ERROR)
229  {
230  //Check character code
231  if(c == session->backspaceCode)
232  {
233  //Process backspace key
234  error = shellServerProcessBackspaceKey(session);
235  }
236  else if(c == session->deleteCode)
237  {
238  //Process delete key
239  error = shellServerProcessDeleteKey(session);
240  }
241  else if(session->escSeqLen > 0)
242  {
243  //Limit the length of the multibyte escape sequence
244  if(session->escSeqLen < SHELL_SERVER_MAX_ESC_SEQ_LEN)
245  {
246  session->escSeq[session->escSeqLen++] = c;
247  session->escSeq[session->escSeqLen] = '\0';
248  }
249 
250  //End of escape sequence?
251  if(isalpha(c) || c == '~')
252  {
253  //Decode multibyte escape sequence
254  if(osStrcmp(session->escSeq, VT100_DELETE) == 0)
255  {
256  error = shellServerProcessDeleteKey(session);
257  }
258  else if(osStrcmp(session->escSeq, VT100_MOVE_CURSOR_LEFT) == 0)
259  {
260  error = shellServerProcessLeftKey(session);
261  }
262  else if(osStrcmp(session->escSeq, VT100_MOVE_CURSOR_RIGHT) == 0)
263  {
264  error = shellServerProcessRightKey(session);
265  }
266  if(osStrcmp(session->escSeq, VT100_MOVE_CURSOR_UP) == 0)
267  {
268  error = shellServerProcessUpKey(session);
269  }
270  else if(osStrcmp(session->escSeq, VT100_MOVE_CURSOR_DOWN) == 0)
271  {
272  error = shellServerProcessDownKey(session);
273  }
274  if(osStrcmp(session->escSeq, VT100_PAGE_UP) == 0)
275  {
276  error = shellServerProcessPageUpKey(session);
277  }
278  else if(osStrcmp(session->escSeq, VT100_PAGE_DOWN) == 0)
279  {
280  error = shellServerProcessPageDownKey(session);
281  }
282  else
283  {
284  //Unknown escape sequence
285  }
286 
287  //Clear escape sequence
288  session->escSeqLen = 0;
289  }
290  }
291  else if(c == VT100_ESC_CODE)
292  {
293  //Escape sequences start with an escape character
294  session->escSeq[0] = c;
295  session->escSeqLen = 1;
296  }
297  else if(c == '\r')
298  {
299  //Send a CRLF sequence to the client
300  error = sshWriteChannel(channel, "\r\n", 2, NULL, 0);
301 
302  //Check status code
303  if(!error)
304  {
305  //Properly terminate the command line with a NULL character
306  session->buffer[session->bufferLen] = '\0';
307  //Add command line to history
308  shellServerAddCommandLine(session, session->buffer);
309  //Process command line
310  error = shellServerProcessCommandLine(session, session->buffer);
311  }
312 
313  //Check status code
314  if(!error)
315  {
316  //Display shell prompt
317  error = sshWriteChannel(channel, session->prompt,
318  osStrlen(session->prompt), NULL, 0);
319  }
320 
321  //Flush the receive buffer and wait for the next command line
322  session->bufferLen = 0;
323  session->bufferPos = 0;
324  }
325  else
326  {
327  //Insert character at current position
328  error = shellServerInsertChar(session, c);
329  }
330  }
331  else if(error == ERROR_TIMEOUT)
332  {
333  //Wait for the next character
334  error = NO_ERROR;
335  }
336  else
337  {
338  //A communication error has occurred
339  }
340 
341  //Return status code
342  return error;
343 }
344 
345 
346 /**
347  * @brief Insert character at current position
348  * @param[in] session Handle referencing an shell session
349  * @param[in] c Character to be inserted
350  * @return Error code
351  **/
352 
354 {
355  error_t error;
356  uint_t cursorPos;
357  char_t buffer[16];
358 
359  //Initialize status code
360  error = NO_ERROR;
361 
362  //Limit the length of the command line
363  if(session->bufferLen < (SHELL_SERVER_BUFFER_SIZE - 1))
364  {
365  //Check the position where the character is to be inserted
366  if(session->bufferPos < session->bufferLen)
367  {
368  //Make room for the character
369  osMemmove(session->buffer + session->bufferPos + 1,
370  session->buffer + session->bufferPos,
371  session->bufferLen - session->bufferPos);
372  }
373 
374  //Insert character at current position
375  session->buffer[session->bufferPos] = c;
376 
377  //Update the length of the command line
378  session->bufferLen++;
379  session->bufferPos++;
380 
381  //Determine the current position of the cursor
382  cursorPos = session->promptLen + session->bufferPos;
383 
384  //Echo back the character to the client
385  buffer[0] = c;
386  buffer[1] = '\0';
387 
388  if((cursorPos % session->termWidth) == 0)
389  {
390  osStrcat(buffer, "\r\n");
391  }
392 
393  if(session->bufferPos < session->bufferLen)
394  {
396  }
397 
398  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
399  NULL, 0);
400 
401  //Check the position where the character is to be inserted
402  if(session->bufferPos < session->bufferLen)
403  {
404  //Check status code
405  if(!error)
406  {
407  error = sshWriteChannel(session->channel,
408  session->buffer + session->bufferPos,
409  session->bufferLen - session->bufferPos, NULL, 0);
410  }
411 
412  //Check status code
413  if(!error)
414  {
416 
417  error = sshWriteChannel(session->channel, buffer,
418  osStrlen(buffer), NULL, 0);
419  }
420  }
421  }
422 
423  //Return status code
424  return error;
425 }
426 
427 
428 /**
429  * @brief Process backspace key
430  * @param[in] session Handle referencing an shell session
431  * @return Error code
432  **/
433 
435 {
436  error_t error;
437  uint_t cursorPos;
438  char_t buffer[16];
439 
440  //Initialize status code
441  error = NO_ERROR;
442 
443  //Check the length of the command line
444  if(session->bufferPos > 0)
445  {
446  //Determine the current position of the cursor
447  cursorPos = session->promptLen + session->bufferPos;
448 
449  //Moving left at the edge of the screen wraps to the previous line
450  if((cursorPos % session->termWidth) == 0)
451  {
453  (uint_t) (session->termWidth - 1));
454  }
455  else
456  {
457  osStrcpy(buffer, VT100_BACKSPACE);
458  }
459 
460  //Check the position where the character is to be deleted
461  if(session->bufferPos < session->bufferLen)
462  {
464 
465  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
466  NULL, 0);
467 
468  //Check status code
469  if(!error)
470  {
471  error = sshWriteChannel(session->channel,
472  session->buffer + session->bufferPos,
473  session->bufferLen - session->bufferPos, NULL, 0);
474  }
475 
476  //Check status code
477  if(!error)
478  {
479  osStrcpy(buffer, " " VT100_RESTORE_CURSOR_POS);
480 
481  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
482  NULL, 0);
483  }
484 
485  //Delete character at current position
486  osMemmove(session->buffer + session->bufferPos - 1,
487  session->buffer + session->bufferPos,
488  session->bufferLen - session->bufferPos);
489  }
490  else
491  {
493 
494  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
495  NULL, 0);
496  }
497 
498  //Update the length of the command line
499  session->bufferLen--;
500  session->bufferPos--;
501  }
502 
503  //Return status code
504  return error;
505 }
506 
507 
508 /**
509  * @brief Process delete key
510  * @param[in] session Handle referencing an shell session
511  * @return Error code
512  **/
513 
515 {
516  error_t error;
517  char_t buffer[16];
518 
519  //Initialize status code
520  error = NO_ERROR;
521 
522  //Check the position where the character is to be deleted
523  if(session->bufferPos < session->bufferLen)
524  {
525  //Save cursor position
527 
528  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
529  NULL, 0);
530 
531  //Check status code
532  if(!error)
533  {
534  error = sshWriteChannel(session->channel,
535  session->buffer + session->bufferPos + 1,
536  session->bufferLen - session->bufferPos - 1, NULL, 0);
537  }
538 
539  //Check status code
540  if(!error)
541  {
542  osStrcpy(buffer, " " VT100_RESTORE_CURSOR_POS);
543 
544  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
545  NULL, 0);
546  }
547 
548  //Delete character at current position
549  osMemmove(session->buffer + session->bufferPos,
550  session->buffer + session->bufferPos + 1,
551  session->bufferLen - session->bufferPos);
552 
553  //Update the length of the command line
554  session->bufferLen--;
555  }
556 
557  //Return status code
558  return error;
559 }
560 
561 
562 /**
563  * @brief Process left key
564  * @param[in] session Handle referencing an shell session
565  * @return Error code
566  **/
567 
569 {
570  error_t error;
571  uint_t cursorPos;
572  char_t buffer[16];
573 
574  //Initialize status code
575  error = NO_ERROR;
576 
577  //Check the length of the command line
578  if(session->bufferPos > 0)
579  {
580  //Determine the current position of the cursor
581  cursorPos = session->promptLen + session->bufferPos;
582 
583  //Moving left at the edge of the screen wraps to the previous line
584  if((cursorPos % session->termWidth) == 0)
585  {
587  (uint_t) (session->termWidth - 1));
588  }
589  else
590  {
591  osStrcpy(buffer, VT100_BACKSPACE);
592  }
593 
594  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
595  NULL, 0);
596 
597  //Update current position
598  session->bufferPos--;
599  }
600 
601  //Return status code
602  return error;
603 }
604 
605 
606 /**
607  * @brief Process right key
608  * @param[in] session Handle referencing an shell session
609  * @return Error code
610  **/
611 
613 {
614  error_t error;
615  uint_t cursorPos;
616  char_t buffer[16];
617 
618  //Initialize status code
619  error = NO_ERROR;
620 
621  //Check current position
622  if(session->bufferPos < session->bufferLen)
623  {
624  //Determine the current position of the cursor
625  cursorPos = session->promptLen + session->bufferPos;
626 
627  //Moving right at the edge of the screen wraps to the next line
628  if((cursorPos % session->termWidth) == (session->termWidth - 1))
629  {
630  osStrcpy(buffer, "\r\n");
631  }
632  else
633  {
635  }
636 
637  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
638  NULL, 0);
639 
640  //Update current position
641  session->bufferPos++;
642  }
643 
644  //Return status code
645  return error;
646 }
647 
648 
649 /**
650  * @brief Process up key
651  * @param[in] session Handle referencing an shell session
652  * @return Error code
653  **/
654 
656 {
657 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
658  error_t error;
659  size_t n;
660  const char_t *p;
661 
662  //Retrieve the previous command line from history
663  error = shellServerGetPrevCommandLine(session, &p, &n);
664 
665  //Any entry found in history?
666  if(!error)
667  {
668  //Restore command line
669  error = shellRestoreCommandLine(session, p, n);
670  }
671  else
672  {
673  //The command history is empty
674  error = NO_ERROR;
675  }
676 
677  //Return status code
678  return error;
679 #else
680  //Ignore up key
681  return NO_ERROR;
682 #endif
683 }
684 
685 
686 /**
687  * @brief Process down key
688  * @param[in] session Handle referencing an shell session
689  * @return Error code
690  **/
691 
693 {
694 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
695  error_t error;
696  size_t n;
697  const char_t *p;
698 
699  //Retrieve the next command line from history
700  error = shellServerGetNextCommandLine(session, &p, &n);
701 
702  //Any entry found in history?
703  if(!error)
704  {
705  //Restore command line
706  error = shellRestoreCommandLine(session, p, n);
707  }
708  else
709  {
710  //The command history is empty
711  error = NO_ERROR;
712  }
713 
714  //Return status code
715  return error;
716 #else
717  //Ignore down key
718  return NO_ERROR;
719 #endif
720 }
721 
722 
723 /**
724  * @brief Process page up key
725  * @param[in] session Handle referencing an shell session
726  * @return Error code
727  **/
728 
730 {
731 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
732  error_t error;
733  size_t n;
734  const char_t *p;
735 
736  //Retrieve the first command line from history
737  error = shellServerGetFirstCommandLine(session, &p, &n);
738 
739  //Any entry found in history?
740  if(!error)
741  {
742  //Restore command line
743  error = shellRestoreCommandLine(session, p, n);
744  }
745  else
746  {
747  //The command history is empty
748  error = NO_ERROR;
749  }
750 
751  //Return status code
752  return error;
753 #else
754  //Ignore page up key
755  return NO_ERROR;
756 #endif
757 }
758 
759 
760 /**
761  * @brief Process page down key
762  * @param[in] session Handle referencing an shell session
763  * @return Error code
764  **/
765 
767 {
768 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
769  error_t error;
770  size_t n;
771  const char_t *p;
772 
773  //Retrieve the last command line from history
774  error = shellServerGetLastCommandLine(session, &p, &n);
775 
776  //Any entry found in history?
777  if(!error)
778  {
779  //Restore command line
780  error = shellRestoreCommandLine(session, p, n);
781  }
782  else
783  {
784  //The command history is empty
785  error = NO_ERROR;
786  }
787 
788  //Return status code
789  return error;
790 #else
791  //Ignore page down key
792  return NO_ERROR;
793 #endif
794 }
795 
796 
797 /**
798  * @brief Clear command line
799  * @param[in] session Handle referencing an shell session
800  * @return error code
801  **/
802 
804 {
805  error_t error;
806  uint_t y;
807  uint_t cursorPos;
808  char_t buffer[32];
809  size_t n;
810 
811  //Determine the current position of the cursor
812  cursorPos = session->promptLen + session->bufferPos;
813  y = cursorPos / session->termWidth;
814 
815  //Flush buffer
816  session->bufferLen = 0;
817  session->bufferPos = 0;
818 
819  //Clear command line
820  n = osSprintf(buffer, "\r");
821 
822  if(y > 0)
823  {
824  n += osSprintf(buffer + n, VT100_MOVE_CURSOR_UP_N, y);
825  }
826 
827  n += osSprintf(buffer + n, VT100_CLEAR_SCREEN_DOWN);
828 
829  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
830  NULL, 0);
831 
832  //Check status code
833  if(!error)
834  {
835  //Display shell prompt
836  error = sshWriteChannel(session->channel, session->prompt,
837  session->promptLen, NULL, 0);
838  }
839 
840  //Return status code
841  return error;
842 }
843 
844 
845 /**
846  * @brief Restore command line
847  * @param[in] session Handle referencing an shell session
848  * @param[in] commandLine Pointer to the command line
849  * @param[in] length Length of the command line
850  * @return error code
851  **/
852 
854  const char_t *commandLine, size_t length)
855 {
856  error_t error;
857  uint_t cursorPos;
858 
859  //Clear entire line
860  error = shellClearCommandLine(session);
861 
862  //Check status code
863  if(!error)
864  {
865  //Restore command line
866  osMemcpy(session->buffer, commandLine, length);
867  session->bufferLen = length;
868  session->bufferPos = length;
869 
870  //Display command line
871  error = sshWriteChannel(session->channel, session->buffer,
872  session->bufferLen, NULL, 0);
873  }
874 
875  //Check status code
876  if(!error)
877  {
878  //Determine the current position of the cursor
879  cursorPos = session->promptLen + session->bufferLen;
880 
881  //Wrap to the next line if necessary
882  if((cursorPos % session->termWidth) == 0)
883  {
884  error = sshWriteChannel(session->channel, " \r", 2, NULL, 0);
885  }
886  }
887 
888  //Return status code
889  return error;
890 }
891 
892 #endif
error_t shellServerProcessDeleteKey(ShellServerSession *session)
Process delete key.
uint8_t p
Definition: ndp.h:300
uint8_t x
Definition: lldp_ext_med.h:211
error_t shellServerGetPrevCommandLine(ShellServerSession *session, const char_t **commandLine, size_t *length)
Extract previous command line from history.
#define VT100_MOVE_CURSOR_UP_N
#define VT100_PAGE_DOWN
#define osStrcmp(s1, s2)
Definition: os_port.h:171
#define osStrlen(s)
Definition: os_port.h:165
error_t shellServerProcessPageDownKey(ShellServerSession *session)
Process page down key.
#define VT100_CLEAR_ENTIRE_SCREEN
error_t shellServerGetLastCommandLine(ShellServerSession *session, const char_t **commandLine, size_t *length)
Extract last command line from history.
error_t shellClearCommandLine(ShellServerSession *session)
Clear command line.
error_t sshReadChannel(SshChannel *channel, void *data, size_t size, size_t *received, uint_t flags)
Receive data from the specified channel.
Definition: ssh.c:2180
error_t shellServerProcessPageUpKey(ShellServerSession *session)
Process page up key.
Helper functions for SSH secure shell server.
#define VT100_MOVE_CURSOR_UP
error_t shellServerProcessUpKey(ShellServerSession *session)
Process up key.
SSH secure shell server.
#define FALSE
Definition: os_port.h:46
Pseudo-terminal emulation.
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define VT100_MOVE_CURSOR_DOWN_N
error_t
Error codes.
Definition: error.h:43
#define osSprintf(dest,...)
Definition: os_port.h:231
#define SHELL_SERVER_BUFFER_SIZE
Definition: shell_server.h:72
#define VT100_MOVE_CURSOR_RIGHT
#define VT100_ESC_CODE
error_t sshWriteChannel(SshChannel *channel, const void *data, size_t length, size_t *written, uint_t flags)
Write data to the specified channel.
Definition: ssh.c:2051
error_t shellServerProcessRightKey(ShellServerSession *session)
Process right key.
#define SHELL_SERVER_MAX_ESC_SEQ_LEN
Definition: shell_server.h:113
uint8_t length
Definition: tcp.h:368
#define MIN(a, b)
Definition: os_port.h:63
error_t shellServerInsertChar(ShellServerSession *session, char_t c)
Insert character at current position.
#define VT100_MOVE_CURSOR_LEFT
@ ERROR_TIMEOUT
Definition: error.h:95
char char_t
Definition: compiler_port.h:48
#define osStrcat(s1, s2)
Definition: os_port.h:219
error_t shellServerProcessDownKey(ShellServerSession *session)
Process down key.
uint8_t n
#define ShellServerSession
Definition: shell_server.h:121
#define VT100_CLEAR_SCREEN_DOWN
void shellServerAddCommandLine(ShellServerSession *session, const char_t *commandLine)
Add command line to history.
#define VT100_HOME
#define VT100_PAGE_UP
error_t shellServerGetNextCommandLine(ShellServerSession *session, const char_t **commandLine, size_t *length)
Extract next command line from history.
#define VT100_MOVE_CURSOR_DOWN
error_t shellServerProcessLeftKey(ShellServerSession *session)
Process left key.
#define VT100_DELETE
#define osStrstr(s1, s2)
Definition: os_port.h:201
error_t shellServerProcessWindowResize(ShellServerSession *session)
Process window resize event.
unsigned int uint_t
Definition: compiler_port.h:50
Secure Shell (SSH)
error_t shellServerProcessBackspaceKey(ShellServerSession *session)
Process backspace key.
#define VT100_RESTORE_CURSOR_POS
#define osStrcpy(s1, s2)
Definition: os_port.h:207
error_t shellServerProcessChar(ShellServerSession *session)
Process received character.
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
error_t shellServerGetFirstCommandLine(ShellServerSession *session, const char_t **commandLine, size_t *length)
Extract first command line from history.
Debugging facilities.
#define osMemmove(dest, src, length)
Definition: os_port.h:147
error_t shellServerProcessCommandLine(ShellServerSession *session, char_t *commandLine)
Command line processing.
error_t shellRestoreCommandLine(ShellServerSession *session, const char_t *commandLine, size_t length)
Restore command line.
#define SshChannel
Definition: ssh.h:878
#define VT100_MOVE_CURSOR_RIGHT_N
#define VT100_BACKSPACE
#define VT100_SAVE_CURSOR_POS