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-2026 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.6.2
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 
310  //Process command line
311  error = shellServerProcessCommandLine(session, session->buffer);
312  }
313 
314  //Check status code
315  if(!error)
316  {
317  //Display shell prompt
318  error = sshWriteChannel(channel, session->prompt,
319  osStrlen(session->prompt), NULL, 0);
320  }
321 
322  //Flush the receive buffer and wait for the next command line
323  session->bufferLen = 0;
324  session->bufferPos = 0;
325  }
326  else
327  {
328  //Insert character at current position
329  error = shellServerInsertChar(session, c);
330  }
331  }
332  else if(error == ERROR_TIMEOUT)
333  {
334  //Wait for the next character
335  error = NO_ERROR;
336  }
337  else
338  {
339  //A communication error has occurred
340  }
341 
342  //Return status code
343  return error;
344 }
345 
346 
347 /**
348  * @brief Insert character at current position
349  * @param[in] session Handle referencing an shell session
350  * @param[in] c Character to be inserted
351  * @return Error code
352  **/
353 
355 {
356  error_t error;
357  uint_t cursorPos;
358  char_t buffer[16];
359 
360  //Initialize status code
361  error = NO_ERROR;
362 
363  //Limit the length of the command line
364  if(session->bufferLen < (SHELL_SERVER_BUFFER_SIZE - 1))
365  {
366  //Check the position where the character is to be inserted
367  if(session->bufferPos < session->bufferLen)
368  {
369  //Make room for the character
370  osMemmove(session->buffer + session->bufferPos + 1,
371  session->buffer + session->bufferPos,
372  session->bufferLen - session->bufferPos);
373  }
374 
375  //Insert character at current position
376  session->buffer[session->bufferPos] = c;
377 
378  //Update the length of the command line
379  session->bufferLen++;
380  session->bufferPos++;
381 
382  //Determine the current position of the cursor
383  cursorPos = session->promptLen + session->bufferPos;
384 
385  //Echo back the character to the client
386  buffer[0] = c;
387  buffer[1] = '\0';
388 
389  if((cursorPos % session->termWidth) == 0)
390  {
391  osStrcat(buffer, "\r\n");
392  }
393 
394  if(session->bufferPos < session->bufferLen)
395  {
397  }
398 
399  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
400  NULL, 0);
401 
402  //Check the position where the character is to be inserted
403  if(session->bufferPos < session->bufferLen)
404  {
405  //Check status code
406  if(!error)
407  {
408  error = sshWriteChannel(session->channel,
409  session->buffer + session->bufferPos,
410  session->bufferLen - session->bufferPos, NULL, 0);
411  }
412 
413  //Check status code
414  if(!error)
415  {
417 
418  error = sshWriteChannel(session->channel, buffer,
419  osStrlen(buffer), NULL, 0);
420  }
421  }
422  }
423 
424  //Return status code
425  return error;
426 }
427 
428 
429 /**
430  * @brief Process backspace key
431  * @param[in] session Handle referencing an shell session
432  * @return Error code
433  **/
434 
436 {
437  error_t error;
438  uint_t cursorPos;
439  char_t buffer[16];
440 
441  //Initialize status code
442  error = NO_ERROR;
443 
444  //Check the length of the command line
445  if(session->bufferPos > 0)
446  {
447  //Determine the current position of the cursor
448  cursorPos = session->promptLen + session->bufferPos;
449 
450  //Moving left at the edge of the screen wraps to the previous line
451  if((cursorPos % session->termWidth) == 0)
452  {
454  (uint_t) (session->termWidth - 1));
455  }
456  else
457  {
458  osStrcpy(buffer, VT100_BACKSPACE);
459  }
460 
461  //Check the position where the character is to be deleted
462  if(session->bufferPos < session->bufferLen)
463  {
465 
466  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
467  NULL, 0);
468 
469  //Check status code
470  if(!error)
471  {
472  error = sshWriteChannel(session->channel,
473  session->buffer + session->bufferPos,
474  session->bufferLen - session->bufferPos, NULL, 0);
475  }
476 
477  //Check status code
478  if(!error)
479  {
480  osStrcpy(buffer, " " VT100_RESTORE_CURSOR_POS);
481 
482  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
483  NULL, 0);
484  }
485 
486  //Delete character at current position
487  osMemmove(session->buffer + session->bufferPos - 1,
488  session->buffer + session->bufferPos,
489  session->bufferLen - session->bufferPos);
490  }
491  else
492  {
494 
495  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
496  NULL, 0);
497  }
498 
499  //Update the length of the command line
500  session->bufferLen--;
501  session->bufferPos--;
502  }
503 
504  //Return status code
505  return error;
506 }
507 
508 
509 /**
510  * @brief Process delete key
511  * @param[in] session Handle referencing an shell session
512  * @return Error code
513  **/
514 
516 {
517  error_t error;
518  char_t buffer[16];
519 
520  //Initialize status code
521  error = NO_ERROR;
522 
523  //Check the position where the character is to be deleted
524  if(session->bufferPos < session->bufferLen)
525  {
526  //Save cursor position
528 
529  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
530  NULL, 0);
531 
532  //Check status code
533  if(!error)
534  {
535  error = sshWriteChannel(session->channel,
536  session->buffer + session->bufferPos + 1,
537  session->bufferLen - session->bufferPos - 1, NULL, 0);
538  }
539 
540  //Check status code
541  if(!error)
542  {
543  osStrcpy(buffer, " " VT100_RESTORE_CURSOR_POS);
544 
545  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
546  NULL, 0);
547  }
548 
549  //Delete character at current position
550  osMemmove(session->buffer + session->bufferPos,
551  session->buffer + session->bufferPos + 1,
552  session->bufferLen - session->bufferPos);
553 
554  //Update the length of the command line
555  session->bufferLen--;
556  }
557 
558  //Return status code
559  return error;
560 }
561 
562 
563 /**
564  * @brief Process left key
565  * @param[in] session Handle referencing an shell session
566  * @return Error code
567  **/
568 
570 {
571  error_t error;
572  uint_t cursorPos;
573  char_t buffer[16];
574 
575  //Initialize status code
576  error = NO_ERROR;
577 
578  //Check the length of the command line
579  if(session->bufferPos > 0)
580  {
581  //Determine the current position of the cursor
582  cursorPos = session->promptLen + session->bufferPos;
583 
584  //Moving left at the edge of the screen wraps to the previous line
585  if((cursorPos % session->termWidth) == 0)
586  {
588  (uint_t) (session->termWidth - 1));
589  }
590  else
591  {
592  osStrcpy(buffer, VT100_BACKSPACE);
593  }
594 
595  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
596  NULL, 0);
597 
598  //Update current position
599  session->bufferPos--;
600  }
601 
602  //Return status code
603  return error;
604 }
605 
606 
607 /**
608  * @brief Process right key
609  * @param[in] session Handle referencing an shell session
610  * @return Error code
611  **/
612 
614 {
615  error_t error;
616  uint_t cursorPos;
617  char_t buffer[16];
618 
619  //Initialize status code
620  error = NO_ERROR;
621 
622  //Check current position
623  if(session->bufferPos < session->bufferLen)
624  {
625  //Determine the current position of the cursor
626  cursorPos = session->promptLen + session->bufferPos;
627 
628  //Moving right at the edge of the screen wraps to the next line
629  if((cursorPos % session->termWidth) == (session->termWidth - 1))
630  {
631  osStrcpy(buffer, "\r\n");
632  }
633  else
634  {
636  }
637 
638  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
639  NULL, 0);
640 
641  //Update current position
642  session->bufferPos++;
643  }
644 
645  //Return status code
646  return error;
647 }
648 
649 
650 /**
651  * @brief Process up key
652  * @param[in] session Handle referencing an shell session
653  * @return Error code
654  **/
655 
657 {
658 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
659  error_t error;
660  size_t n;
661  const char_t *p;
662 
663  //Retrieve the previous command line from history
664  error = shellServerGetPrevCommandLine(session, &p, &n);
665 
666  //Any entry found in history?
667  if(!error)
668  {
669  //Restore command line
670  error = shellRestoreCommandLine(session, p, n);
671  }
672  else
673  {
674  //The command history is empty
675  error = NO_ERROR;
676  }
677 
678  //Return status code
679  return error;
680 #else
681  //Ignore up key
682  return NO_ERROR;
683 #endif
684 }
685 
686 
687 /**
688  * @brief Process down key
689  * @param[in] session Handle referencing an shell session
690  * @return Error code
691  **/
692 
694 {
695 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
696  error_t error;
697  size_t n;
698  const char_t *p;
699 
700  //Retrieve the next command line from history
701  error = shellServerGetNextCommandLine(session, &p, &n);
702 
703  //Any entry found in history?
704  if(!error)
705  {
706  //Restore command line
707  error = shellRestoreCommandLine(session, p, n);
708  }
709  else
710  {
711  //The command history is empty
712  error = NO_ERROR;
713  }
714 
715  //Return status code
716  return error;
717 #else
718  //Ignore down key
719  return NO_ERROR;
720 #endif
721 }
722 
723 
724 /**
725  * @brief Process page up key
726  * @param[in] session Handle referencing an shell session
727  * @return Error code
728  **/
729 
731 {
732 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
733  error_t error;
734  size_t n;
735  const char_t *p;
736 
737  //Retrieve the first command line from history
738  error = shellServerGetFirstCommandLine(session, &p, &n);
739 
740  //Any entry found in history?
741  if(!error)
742  {
743  //Restore command line
744  error = shellRestoreCommandLine(session, p, n);
745  }
746  else
747  {
748  //The command history is empty
749  error = NO_ERROR;
750  }
751 
752  //Return status code
753  return error;
754 #else
755  //Ignore page up key
756  return NO_ERROR;
757 #endif
758 }
759 
760 
761 /**
762  * @brief Process page down key
763  * @param[in] session Handle referencing an shell session
764  * @return Error code
765  **/
766 
768 {
769 #if (SHELL_SERVER_HISTORY_SUPPORT == ENABLED)
770  error_t error;
771  size_t n;
772  const char_t *p;
773 
774  //Retrieve the last command line from history
775  error = shellServerGetLastCommandLine(session, &p, &n);
776 
777  //Any entry found in history?
778  if(!error)
779  {
780  //Restore command line
781  error = shellRestoreCommandLine(session, p, n);
782  }
783  else
784  {
785  //The command history is empty
786  error = NO_ERROR;
787  }
788 
789  //Return status code
790  return error;
791 #else
792  //Ignore page down key
793  return NO_ERROR;
794 #endif
795 }
796 
797 
798 /**
799  * @brief Clear command line
800  * @param[in] session Handle referencing an shell session
801  * @return error code
802  **/
803 
805 {
806  error_t error;
807  uint_t y;
808  uint_t cursorPos;
809  char_t buffer[32];
810  size_t n;
811 
812  //Determine the current position of the cursor
813  cursorPos = session->promptLen + session->bufferPos;
814  y = cursorPos / session->termWidth;
815 
816  //Flush buffer
817  session->bufferLen = 0;
818  session->bufferPos = 0;
819 
820  //Clear command line
821  n = osSprintf(buffer, "\r");
822 
823  if(y > 0)
824  {
825  n += osSprintf(buffer + n, VT100_MOVE_CURSOR_UP_N, y);
826  }
827 
828  n += osSprintf(buffer + n, VT100_CLEAR_SCREEN_DOWN);
829 
830  error = sshWriteChannel(session->channel, buffer, osStrlen(buffer),
831  NULL, 0);
832 
833  //Check status code
834  if(!error)
835  {
836  //Display shell prompt
837  error = sshWriteChannel(session->channel, session->prompt,
838  session->promptLen, NULL, 0);
839  }
840 
841  //Return status code
842  return error;
843 }
844 
845 
846 /**
847  * @brief Restore command line
848  * @param[in] session Handle referencing an shell session
849  * @param[in] commandLine Pointer to the command line
850  * @param[in] length Length of the command line
851  * @return error code
852  **/
853 
855  const char_t *commandLine, size_t length)
856 {
857  error_t error;
858  uint_t cursorPos;
859 
860  //Clear entire line
861  error = shellClearCommandLine(session);
862 
863  //Check status code
864  if(!error)
865  {
866  //Restore command line
867  osMemcpy(session->buffer, commandLine, length);
868  session->bufferLen = length;
869  session->bufferPos = length;
870 
871  //Display command line
872  error = sshWriteChannel(session->channel, session->buffer,
873  session->bufferLen, NULL, 0);
874  }
875 
876  //Check status code
877  if(!error)
878  {
879  //Determine the current position of the cursor
880  cursorPos = session->promptLen + session->bufferLen;
881 
882  //Wrap to the next line if necessary
883  if((cursorPos % session->termWidth) == 0)
884  {
885  error = sshWriteChannel(session->channel, " \r", 2, NULL, 0);
886  }
887  }
888 
889  //Return status code
890  return error;
891 }
892 
893 #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:174
#define osStrlen(s)
Definition: os_port.h:168
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:2206
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:144
#define VT100_MOVE_CURSOR_DOWN_N
error_t
Error codes.
Definition: error.h:43
#define osSprintf(dest,...)
Definition: os_port.h:234
#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:2077
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:375
#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:55
#define osStrcat(s1, s2)
Definition: os_port.h:222
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:204
error_t shellServerProcessWindowResize(ShellServerSession *session)
Process window resize event.
unsigned int uint_t
Definition: compiler_port.h:57
Secure Shell (SSH)
error_t shellServerProcessBackspaceKey(ShellServerSession *session)
Process backspace key.
#define VT100_RESTORE_CURSOR_POS
#define osStrcpy(s1, s2)
Definition: os_port.h:210
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:150
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:900
#define VT100_MOVE_CURSOR_RIGHT_N
#define VT100_BACKSPACE
#define VT100_SAVE_CURSOR_POS