sftp_common.c
Go to the documentation of this file.
1 /**
2  * @file sftp_common.c
3  * @brief Definitions common to SFTP client and server
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 CycloneTCP 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 SFTP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ssh/ssh.h"
36 #include "ssh/ssh_misc.h"
37 #include "sftp/sftp_common.h"
38 #include "debug.h"
39 
40 
41 /**
42  * @brief Format name structure
43  * @param[in] version Protocol version
44  * @param[in] name Pointer to the name structure
45  * @param[in] p Buffer where to format the name structure
46  * @param[out] written Total number of bytes that have been written
47  * @return Error code
48  **/
49 
51  uint8_t *p, size_t *written)
52 {
53  error_t error;
54  size_t n;
55 
56  //Total number of bytes that have been written
57  *written = 0;
58 
59  //Format the file name
60  error = sshFormatBinaryString(name->filename.value, name->filename.length,
61  p, &n);
62  //Any error to report?
63  if(error)
64  return error;
65 
66  //Point to the next field
67  p += n;
68  *written += n;
69 
70  //The long file name has been removed in version 4
71  if(version <= SFTP_VERSION_3)
72  {
73  //Format the long file name
74  error = sftpFormatLongFilename(&name->filename, &name->attributes,
75  (char_t *) p + 4, &n);
76  //Any error to report?
77  if(error)
78  return error;
79 
80  //The string is preceded by a uint32 containing its length
81  STORE32BE(n, p);
82 
83  //Point to the next field
84  p += sizeof(uint32_t) + n;
85  *written += sizeof(uint32_t) + n;
86  }
87 
88  //Format ATTRS compound data
89  error = sftpFormatAttributes(version, &name->attributes, p, &n);
90  //Any error to report?
91  if(error)
92  return error;
93 
94  //Total number of bytes that have been written
95  *written += n;
96 
97  //Successful processing
98  return NO_ERROR;
99 }
100 
101 
102 /**
103  * @brief Format long file name
104  * @param[in] filename File name
105  * @param[in] attributes File attributes
106  * @param[in] p Buffer where to format the long file name
107  * @param[out] written Total number of bytes that have been written
108  * @return Error code
109  **/
110 
112  const SftpFileAttrs *attributes, char_t *p, size_t *written)
113 {
114  size_t n;
115  time_t time;
116  time_t modified;
117 
118  //Abbreviated months
119  static const char_t months[13][4] =
120  {
121  " ",
122  "Jan",
123  "Feb",
124  "Mar",
125  "Apr",
126  "May",
127  "Jun",
128  "Jul",
129  "Aug",
130  "Sep",
131  "Oct",
132  "Nov",
133  "Dec"
134  };
135 
136  //Valid attributes?
137  if(attributes->flags != 0)
138  {
139  //Format links, owner, group and size fields
140  if(attributes->size <= (uint64_t) UINT32_MAX)
141  {
142  n = osSprintf(p, "---------- 1 owner group %10" PRIu32,
143  (uint32_t) attributes->size);
144  }
145  else
146  {
147  n = osSprintf(p, "---------- 1 owner group %10" PRIu64,
148  attributes->size);
149  }
150 
151  //Check whether the current entry is a directory
153  {
154  p[0] = 'd';
155  }
156 
157  //Check user permissions
158  if((attributes->permissions & SFTP_MODE_IRUSR) != 0)
159  {
160  p[1] = 'r';
161  }
162 
163  if((attributes->permissions & SFTP_MODE_IWUSR) != 0)
164  {
165  p[2] = 'w';
166  }
167 
168  if((attributes->permissions & SFTP_MODE_IXUSR) != 0)
169  {
170  p[3] = 'x';
171  }
172 
173  //Check group permissions
174  if((attributes->permissions & SFTP_MODE_IRGRP) != 0)
175  {
176  p[4] = 'r';
177  }
178 
179  if((attributes->permissions & SFTP_MODE_IWGRP) != 0)
180  {
181  p[5] = 'w';
182  }
183 
184  if((attributes->permissions & SFTP_MODE_IXGRP) != 0)
185  {
186  p[6] = 'x';
187  }
188 
189  //Check other (everyone) permissions
190  if((attributes->permissions & SFTP_MODE_IROTH) != 0)
191  {
192  p[7] = 'r';
193  }
194 
195  if((attributes->permissions & SFTP_MODE_IWOTH) != 0)
196  {
197  p[8] = 'w';
198  }
199 
200  if((attributes->permissions & SFTP_MODE_IXOTH) != 0)
201  {
202  p[9] = 'x';
203  }
204 
205  //Get current time
207  //Get modification time
208  modified = convertDateToUnixTime(&attributes->mtime);
209 
210  //Check whether the modification time is within the previous 180 days
211  if(time > modified && time < (modified + SFTP_180_DAYS))
212  {
213  //The format of the date/time field is Mmm dd hh:mm
214  n += osSprintf(p + n, " %s %02" PRIu8 " %02" PRIu8 ":%02" PRIu8,
215  months[MIN(attributes->mtime.month, 12)], attributes->mtime.day,
216  attributes->mtime.hours, attributes->mtime.minutes);
217  }
218  else
219  {
220  //The format of the date/time field is Mmm dd yyyy
221  n += osSprintf(p + n, " %s %02" PRIu8 " %04" PRIu16,
222  months[MIN(attributes->mtime.month, 12)], attributes->mtime.day,
223  attributes->mtime.year);
224  }
225 
226  //Append a space character
227  p[n++] = ' ';
228  }
229  else
230  {
231  //The file attributes are not valid
232  n = 0;
233  }
234 
235  //Copy file name
236  osMemcpy(p + n, filename->value, filename->length);
237 
238  //Total number of bytes that have been written
239  *written = n + filename->length;
240 
241  //Successful processing
242  return NO_ERROR;
243 }
244 
245 
246 /**
247  * @brief Format file attributes
248  * @param[in] version Protocol version
249  * @param[in] attributes File attributes
250  * @param[in] p Buffer where to format the attributes
251  * @param[out] written Total number of bytes that have been written
252  * @return Error code
253  **/
254 
256  const SftpFileAttrs *attributes, uint8_t *p, size_t *written)
257 {
258  time_t time;
259  uint32_t permissions;
260 
261  //Total number of bytes that have been written
262  *written = 0;
263 
264  //The flags specify which of the fields are present
265  STORE32BE(attributes->flags, p);
266 
267  //Point to the next field
268  p += sizeof(uint32_t);
269  *written += sizeof(uint32_t);
270 
271  //Version 4 splits the file type out of the permissions field and into
272  //its own field (which is always present)
273  if(version >= SFTP_VERSION_4)
274  {
275  //The 'type' field is encoded as a byte
276  p[0] = (uint8_t) attributes->type;
277 
278  //Point to the next field
279  p += sizeof(uint8_t);
280  *written += sizeof(uint8_t);
281  }
282 
283  //The 'size' field is optional
284  if((attributes->flags & SSH_FILEXFER_ATTR_SIZE) != 0)
285  {
286  //The size field specifies the size of the file in bytes
287  STORE64BE(attributes->size, p);
288 
289  //Point to the next field
290  p += sizeof(uint64_t);
291  *written += sizeof(uint64_t);
292  }
293 
294  //The 'uid' and 'gid' fields are optional
295  if((attributes->flags & SSH_FILEXFER_ATTR_UIDGID) != 0)
296  {
297  //The 'uid' field contains numeric Unix-like user identifier
298  STORE32BE(attributes->uid, p);
299 
300  //Point to the next field
301  p += sizeof(uint32_t);
302  *written += sizeof(uint32_t);
303 
304  //The 'gid' field contains numeric Unix-like group identifier
305  STORE32BE(attributes->gid, p);
306 
307  //Point to the next field
308  p += sizeof(uint32_t);
309  *written += sizeof(uint32_t);
310  }
311 
312  //The 'permissions' field is optional
313  if((attributes->flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0)
314  {
315  //The 'permissions' field contains a bit mask of file permissions
316  permissions = attributes->permissions & ~SFTP_MODE_IFMT;
317 
318  //Check SFTP protocol version
319  if(version <= SFTP_VERSION_3)
320  {
321  //Convert file type to permission bits
322  permissions |= sftpConvertFileTypeToPerm(attributes->type);
323  }
324 
325  //The 'permissions' field is encoded as a 32-bit integer
326  STORE32BE(permissions, p);
327 
328  //Point to the next field
329  p += sizeof(uint32_t);
330  *written += sizeof(uint32_t);
331  }
332 
333  //The 'atime' and 'mtime' fields are optional
334  if((attributes->flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0)
335  {
336  //The 'atime' field contain the access time of the file
338  //The time is represented as seconds from Jan 1, 1970 in UTC
339  STORE32BE(time, p);
340 
341  //Point to the next field
342  p += sizeof(uint32_t);
343  *written += sizeof(uint32_t);
344 
345  //The 'mtime' field contain the modification time of the file
347  //The time is represented as seconds from Jan 1, 1970 in UTC
348  STORE32BE(time, p);
349 
350  //Point to the next field
351  p += sizeof(uint32_t);
352  *written += sizeof(uint32_t);
353  }
354 
355  //Successful processing
356  return NO_ERROR;
357 }
358 
359 
360 /**
361  * @brief Parse name structure
362  * @param[in] version Protocol version
363  * @param[out] name Pointer to the name structure
364  * @param[in] data Input data stream
365  * @param[in] length Number of bytes available in the input stream
366  * @param[out] consumed Total number of bytes that have been consumed
367  * @return Error code
368  **/
369 
371  size_t length, size_t *consumed)
372 {
373  error_t error;
374  size_t n;
375  const uint8_t *p;
376 
377  //Clear name structure
378  osMemset(name, 0, sizeof(SftpName));
379 
380  //Point to the input data stream
381  p = data;
382 
383  //Decode the file name
384  error = sshParseString(p, length, &name->filename);
385  //Any error to report?
386  if(error)
387  return error;
388 
389  //Point to the next field
390  p += sizeof(uint32_t) + name->filename.length;
391  length -= sizeof(uint32_t) + name->filename.length;
392 
393  //The long file name has been removed in version 4
394  if(version <= SFTP_VERSION_3)
395  {
396  //Decode the long file name
397  error = sshParseString(p, length, &name->longname);
398  //Any error to report?
399  if(error)
400  return error;
401 
402  //Point to the next field
403  p += sizeof(uint32_t) + name->longname.length;
404  length -= sizeof(uint32_t) + name->longname.length;
405  }
406 
407  //Parse ATTRS compound data
408  error = sftpParseAttributes(version, &name->attributes, p, length, &n);
409  //Any error to report?
410  if(error)
411  return error;
412 
413  //Point to the next field
414  p += n;
415  length -= n;
416 
417  //Check SFTP protocol version
418  if(version <= SFTP_VERSION_3)
419  {
420  //Unknown file type?
421  if(name->attributes.type == SSH_FILEXFER_TYPE_UNKNOWN &&
422  name->longname.length > 0)
423  {
424  //Check file type
425  if(name->longname.value[0] == 'd')
426  {
427  name->attributes.type = SSH_FILEXFER_TYPE_DIRECTORY;
428  }
429  else
430  {
431  name->attributes.type = SSH_FILEXFER_TYPE_REGULAR;
432  }
433  }
434  }
435 
436  //Total number of bytes that have been consumed
437  *consumed = p - data;
438 
439  //Successful processing
440  return NO_ERROR;
441 }
442 
443 
444 /**
445  * @brief Parse file attributes
446  * @param[in] version Protocol version
447  * @param[out] attributes File attributes
448  * @param[in] data Pointer to ATTRS compound data
449  * @param[in] length Number of bytes available in the input stream
450  * @param[out] consumed Total number of bytes that have been consumed
451  * @return Error code
452  **/
453 
455  const uint8_t *data, size_t length, size_t *consumed)
456 {
457  error_t error;
458  time_t time;
459  uint32_t i;
460  uint32_t extendedCount;
461  SshString extendedType;
462  SshString extendedData;
463  const uint8_t *p;
464 
465  //Clear file attributes
466  osMemset(attributes, 0, sizeof(SftpFileAttrs));
467 
468  //Point to the first byte of the ATTRS compound data
469  p = data;
470 
471  //Malformed packet?
472  if(length < sizeof(uint32_t))
473  return ERROR_INVALID_PACKET;
474 
475  //The flags specify which of the fields are present
476  attributes->flags = LOAD32BE(p);
477 
478  //Point to the next field
479  p += sizeof(uint32_t);
480  length -= sizeof(uint32_t);
481 
482  //Version 4 splits the file type out of the permissions field and into
483  //its own field (which is always present)
484  if(version >= SFTP_VERSION_4)
485  {
486  //Malformed packet?
487  if(length < sizeof(uint8_t))
488  return ERROR_INVALID_PACKET;
489 
490  //The 'type' field is always present in version 4
491  attributes->type = (SftpFileType) p[0];
492 
493  //Point to the next field
494  p += sizeof(uint8_t);
495  length -= sizeof(uint8_t);
496  }
497  else
498  {
499  //The 'type' field is not present in version 3
501  }
502 
503  //Check if the 'size' field is present?
504  if((attributes->flags & SSH_FILEXFER_ATTR_SIZE) != 0)
505  {
506  //Malformed packet?
507  if(length < sizeof(uint64_t))
508  return ERROR_INVALID_PACKET;
509 
510  //The 'size' field specifies the size of the file in bytes
511  attributes->size = LOAD64BE(p);
512 
513  //Point to the next field
514  p += sizeof(uint64_t);
515  length -= sizeof(uint64_t);
516  }
517 
518  //Check if the 'uid' and 'gid' fields are present?
519  if((attributes->flags & SSH_FILEXFER_ATTR_UIDGID) != 0)
520  {
521  //Malformed packet?
522  if(length < sizeof(uint32_t))
523  return ERROR_INVALID_PACKET;
524 
525  //The 'uid' field contains numeric Unix-like user identifier
526  attributes->uid = LOAD32BE(p);
527 
528  //Point to the next field
529  p += sizeof(uint32_t);
530  length -= sizeof(uint32_t);
531 
532  //Malformed packet?
533  if(length < sizeof(uint32_t))
534  return ERROR_INVALID_PACKET;
535 
536  //The 'gid' field contains numeric Unix-like group identifier
537  attributes->gid = LOAD32BE(p);
538 
539  //Point to the next field
540  p += sizeof(uint32_t);
541  length -= sizeof(uint32_t);
542  }
543 
544  //Check if the 'permissions' field is present?
545  if((attributes->flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0)
546  {
547  //Malformed packet?
548  if(length < sizeof(uint32_t))
549  return ERROR_INVALID_PACKET;
550 
551  //The 'permissions' field contains a bit mask of file permissions
552  attributes->permissions = LOAD32BE(p);
553 
554  //Check SFTP protocol version
555  if(version <= SFTP_VERSION_3)
556  {
557  //Extract file type from permission bits
558  attributes->type = sftpConvertPermToFileType(attributes->permissions);
559  }
560 
561  //Point to the next field
562  p += sizeof(uint32_t);
563  length -= sizeof(uint32_t);
564  }
565 
566  //Check if the 'atime' and 'mtime' fields are present?
567  if((attributes->flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0)
568  {
569  //Malformed packet?
570  if(length < sizeof(uint32_t))
571  return ERROR_INVALID_PACKET;
572 
573  //The 'atime' field contain the access time of the file
574  time = LOAD32BE(p);
575  //The time is represented as seconds from Jan 1, 1970 in UTC
577 
578  //Point to the next field
579  p += sizeof(uint32_t);
580  length -= sizeof(uint32_t);
581 
582  //Malformed packet?
583  if(length < sizeof(uint32_t))
584  return ERROR_INVALID_PACKET;
585 
586  //The 'mtime' field contain the modification time of the file
587  time = LOAD32BE(p);
588  //The time is represented as seconds from Jan 1, 1970 in UTC
590 
591  //Point to the next field
592  p += sizeof(uint32_t);
593  length -= sizeof(uint32_t);
594  }
595 
596  //Check if the 'extended_count' field is present?
597  if((attributes->flags & SSH_FILEXFER_ATTR_EXTENDED) != 0)
598  {
599  //Malformed packet?
600  if(length < sizeof(uint32_t))
601  return ERROR_INVALID_PACKET;
602 
603  //Parse the 'extended_count' field
604  extendedCount = LOAD32BE(p);
605 
606  //Point to the next field
607  p += sizeof(uint32_t);
608  length -= sizeof(uint32_t);
609  }
610  else
611  {
612  //The 'extended_count' field is not present
613  extendedCount = 0;
614  }
615 
616  //The 'extended_count' field specifies the number of extended type/data
617  //pairs that follow
618  for(i = 0; i < extendedCount; i++)
619  {
620  //For each of the attributes, the 'extended_type' field should be a
621  //string of the format "name@domain"
622  error = sshParseString(p, length, &extendedType);
623  //Any error to report?
624  if(error)
625  return error;
626 
627  //Point to the next field
628  p += sizeof(uint32_t) + extendedType.length;
629  length -= sizeof(uint32_t) + extendedType.length;
630 
631  //The interpretation of 'extended_data' depends on the type
632  error = sshParseString(p, length, &extendedData);
633  //Any error to report?
634  if(error)
635  return error;
636 
637  //Point to the next field
638  p += sizeof(uint32_t) + extendedData.length;
639  length -= sizeof(uint32_t) + extendedData.length;
640  }
641 
642  //Total number of bytes that have been consumed
643  *consumed = p - data;
644 
645  //Successful processing
646  return NO_ERROR;
647 }
648 
649 
650 /**
651  * @brief Extract file type from permission bits
652  * @param[in] permissions Permission bits
653  * @return File type
654  **/
655 
657 {
659 
660  //Check permission bits
661  switch(permissions & SFTP_MODE_IFMT)
662  {
663  case SFTP_MODE_IFREG:
664  //The file is a regular file
666  break;
667  case SFTP_MODE_IFDIR:
668  //The file is a directory
670  break;
671  case SFTP_MODE_IFLNK:
672  //The file is a symbolic link
674  break;
675  case SFTP_MODE_IFSOCK:
676  //The file is a socket
678  break;
679  case SFTP_MODE_IFCHR:
680  //The file is a character special file
682  break;
683  case SFTP_MODE_IFBLK:
684  //The file is a block special file
686  break;
687  case SFTP_MODE_IFIFO:
688  //The file is a FIFO special file or a pipe
690  break;
691  default:
692  //The file type is unknown
694  break;
695  }
696 
697  //Return file type
698  return type;
699 }
700 
701 
702 /**
703  * @brief Convert file type to permission bits
704  * @param[in] type File type
705  * @return Permission bits
706  **/
707 
709 {
710  uint32_t permissions;
711 
712  //Check file type
713  switch(type)
714  {
716  //The file is a regular file
717  permissions = SFTP_MODE_IFREG;
718  break;
720  //The file is a directory
721  permissions = SFTP_MODE_IFDIR;
722  break;
724  //The file is a symbolic link
725  permissions = SFTP_MODE_IFLNK;
726  break;
728  //The file is a socket
729  permissions = SFTP_MODE_IFSOCK;
730  break;
732  //The file is a character special file
733  permissions = SFTP_MODE_IFCHR;
734  break;
736  //The file is a block special file
737  permissions = SFTP_MODE_IFBLK;
738  break;
740  //The file is a FIFO special file or a pipe
741  permissions = SFTP_MODE_IFIFO;
742  break;
743  default:
744  //The file type is unknown
745  permissions = 0;
746  break;
747  }
748 
749  //Return permission bits
750  return permissions;
751 }
#define SSH_FILEXFER_ATTR_EXTENDED
Definition: sftp_common.h:66
SftpFileType
File types.
Definition: sftp_common.h:188
#define SFTP_MODE_IXOTH
Definition: sftp_common.h:83
#define LOAD32BE(p)
Definition: cpu_endian.h:210
uint8_t p
Definition: ndp.h:300
@ SFTP_VERSION_4
Definition: sftp_common.h:123
time_t convertDateToUnixTime(const DateTime *date)
Convert date to Unix timestamp.
Definition: date_time.c:260
uint8_t data[]
Definition: ethernet.h:222
@ SSH_FILEXFER_TYPE_FIFO
Definition: sftp_common.h:198
error_t sftpFormatName(SftpVersion version, const SftpName *name, uint8_t *p, size_t *written)
Format name structure.
Definition: sftp_common.c:50
@ SFTP_VERSION_3
Definition: sftp_common.h:122
error_t sshParseString(const uint8_t *p, size_t length, SshString *string)
Parse a string.
Definition: ssh_misc.c:1152
uint8_t type
Definition: coap_common.h:176
uint8_t attributes[]
Definition: radius.h:88
void convertUnixTimeToDate(time_t t, DateTime *date)
Convert Unix timestamp to date.
Definition: date_time.c:198
char_t name[]
@ SSH_FILEXFER_TYPE_CHAR_DEVICE
Definition: sftp_common.h:196
size_t length
Definition: ssh_types.h:58
#define SFTP_MODE_IFCHR
Definition: sftp_common.h:100
uint8_t version
Definition: coap_common.h:177
#define SFTP_MODE_IFLNK
Definition: sftp_common.h:104
#define LOAD64BE(p)
Definition: cpu_endian.h:246
#define SFTP_MODE_IROTH
Definition: sftp_common.h:85
#define SSH_FILEXFER_ATTR_SIZE
Definition: sftp_common.h:50
error_t sshFormatBinaryString(const void *value, size_t valueLen, uint8_t *p, size_t *written)
Format a binary string.
Definition: ssh_misc.c:1415
@ SSH_FILEXFER_TYPE_REGULAR
Definition: sftp_common.h:190
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
#define SFTP_MODE_IWUSR
Definition: sftp_common.h:92
#define osSprintf(dest,...)
Definition: os_port.h:231
error_t sftpParseAttributes(SftpVersion version, SftpFileAttrs *attributes, const uint8_t *data, size_t length, size_t *consumed)
Parse file attributes.
Definition: sftp_common.c:454
error_t sftpParseName(SftpVersion version, SftpName *name, const uint8_t *data, size_t length, size_t *consumed)
Parse name structure.
Definition: sftp_common.c:370
error_t sftpFormatAttributes(SftpVersion version, const SftpFileAttrs *attributes, uint8_t *p, size_t *written)
Format file attributes.
Definition: sftp_common.c:255
#define SFTP_MODE_IFBLK
Definition: sftp_common.h:102
@ ERROR_INVALID_PACKET
Definition: error.h:140
char_t filename[]
Definition: tftp_common.h:93
@ SSH_FILEXFER_TYPE_UNKNOWN
Definition: sftp_common.h:194
uint8_t length
Definition: tcp.h:368
#define SFTP_MODE_IWGRP
Definition: sftp_common.h:88
#define MIN(a, b)
Definition: os_port.h:63
String.
Definition: ssh_types.h:56
#define SFTP_MODE_IXUSR
Definition: sftp_common.h:91
SftpFileType sftpConvertPermToFileType(uint32_t permissions)
Extract file type from permission bits.
Definition: sftp_common.c:656
#define SFTP_MODE_IRGRP
Definition: sftp_common.h:89
#define SSH_FILEXFER_ATTR_ACMODTIME
Definition: sftp_common.h:53
#define SFTP_MODE_IWOTH
Definition: sftp_common.h:84
char char_t
Definition: compiler_port.h:48
Name structure.
Definition: sftp_common.h:265
#define STORE64BE(a, p)
Definition: cpu_endian.h:322
@ SSH_FILEXFER_TYPE_SOCKET
Definition: sftp_common.h:195
uint32_t time
#define SFTP_MODE_IFREG
Definition: sftp_common.h:103
#define SFTP_MODE_IXGRP
Definition: sftp_common.h:87
uint8_t n
error_t sftpFormatLongFilename(const SshString *filename, const SftpFileAttrs *attributes, char_t *p, size_t *written)
Format long file name.
Definition: sftp_common.c:111
#define SFTP_180_DAYS
Definition: sftp_common.h:39
#define SFTP_MODE_IFSOCK
Definition: sftp_common.h:105
SSH helper functions.
#define SFTP_MODE_IRUSR
Definition: sftp_common.h:93
#define SSH_FILEXFER_ATTR_PERMISSIONS
Definition: sftp_common.h:52
@ SSH_FILEXFER_TYPE_DIRECTORY
Definition: sftp_common.h:191
#define SFTP_MODE_IFMT
Definition: sftp_common.h:98
Definitions common to SFTP client and server.
SftpVersion
SFTP protocol version.
Definition: sftp_common.h:118
@ SSH_FILEXFER_TYPE_BLOCK_DEVICE
Definition: sftp_common.h:197
uint32_t sftpConvertFileTypeToPerm(SftpFileType type)
Convert file type to permission bits.
Definition: sftp_common.c:708
@ SSH_FILEXFER_TYPE_SYMLINK
Definition: sftp_common.h:192
#define osMemset(p, value, length)
Definition: os_port.h:135
File attributes.
Definition: sftp_common.h:247
Secure Shell (SSH)
#define SFTP_MODE_IFIFO
Definition: sftp_common.h:99
__weak_func time_t getCurrentUnixTime(void)
Get current time.
Definition: date_time.c:180
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
@ NO_ERROR
Success.
Definition: error.h:44
#define SFTP_MODE_IFDIR
Definition: sftp_common.h:101
Debugging facilities.
#define SSH_FILEXFER_ATTR_UIDGID
Definition: sftp_common.h:51