Skip to content

Commit b02d455

Browse files
committed
Add lcd and lls commands
1 parent 5272cc4 commit b02d455

File tree

2 files changed

+214
-3
lines changed

2 files changed

+214
-3
lines changed

examples/sftpclient/sftpclient.c

Lines changed: 138 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ static void ShowCommands(void)
358358
printf("\tcd <string> change directory\n");
359359
printf("\tchmod <mode> <path> change mode\n");
360360
printf("\tget <remote file> <local file> pulls file(s) from server\n");
361+
printf("\tlcd <path> change local directory\n");
362+
printf("\tlls list local directory\n");
361363
printf("\tls list current directory\n");
362364
printf("\tmkdir <dir name> creates new directory on server\n");
363365
printf("\tput <local file> <remote file> push file(s) to server\n");
@@ -731,6 +733,30 @@ static int doCmds(func_args* args)
731733
continue;
732734
}
733735

736+
/* lcd must be checked before cd so that WSTRNSTR
737+
* does not match "cd" inside "lcd" */
738+
#ifndef WOLFSSH_FATFS /* WCHDIR not yet defined for FatFS */
739+
if ((pt = WSTRNSTR(msg, "lcd", MAX_CMD_SZ)) != NULL) {
740+
int sz;
741+
742+
pt += sizeof("lcd");
743+
sz = (int)WSTRLEN(pt);
744+
745+
if (sz > 0 && pt[sz - 1] == '\n') {
746+
pt[sz - 1] = '\0';
747+
}
748+
749+
if (WCHDIR(ssh->fs, pt) != 0) {
750+
if (SFTP_FPUTS(args,
751+
"Error changing local directory\n") < 0) {
752+
err_msg("fputs error");
753+
return -1;
754+
}
755+
}
756+
continue;
757+
}
758+
#endif /* !WOLFSSH_FATFS */
759+
734760
if ((pt = WSTRNSTR(msg, "cd", MAX_CMD_SZ)) != NULL) {
735761
WS_SFTP_FILEATRB atrb;
736762
int sz;
@@ -1071,6 +1097,114 @@ static int doCmds(func_args* args)
10711097

10721098
}
10731099

1100+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
1101+
/* lls must be checked before ls so that WSTRNSTR
1102+
* does not match "ls" inside "lls" */
1103+
if (WSTRNSTR(msg, "lls", MAX_CMD_SZ) != NULL) {
1104+
char cwd[WOLFSSH_MAX_FILENAME];
1105+
int llsErr = 0;
1106+
1107+
#ifdef WOLFSSH_ZEPHYR
1108+
WSTRNCPY(cwd, CONFIG_WOLFSSH_SFTP_DEFAULT_DIR,
1109+
sizeof(cwd));
1110+
#else
1111+
if (WGETCWD(ssh->fs, cwd, sizeof(cwd)) == NULL) {
1112+
if (SFTP_FPUTS(args,
1113+
"Error getting local directory\n") < 0) {
1114+
err_msg("fputs error");
1115+
return -1;
1116+
}
1117+
continue;
1118+
}
1119+
#endif
1120+
1121+
#ifdef USE_WINDOWS_API
1122+
{
1123+
WDIR findHandle;
1124+
char name[MAX_PATH];
1125+
char fileName[MAX_PATH];
1126+
1127+
WSTRNCPY(name, cwd, MAX_PATH);
1128+
WSTRNCAT(name, "\\*", MAX_PATH);
1129+
findHandle = (HANDLE)WS_FindFirstFileA(name,
1130+
fileName, sizeof(fileName), NULL, NULL);
1131+
if (findHandle == INVALID_HANDLE_VALUE) {
1132+
if (SFTP_FPUTS(args,
1133+
"Error opening local directory\n") < 0) {
1134+
err_msg("fputs error");
1135+
return -1;
1136+
}
1137+
continue;
1138+
}
1139+
1140+
do {
1141+
if (SFTP_FPUTS(args, fileName) < 0 ||
1142+
SFTP_FPUTS(args, "\n") < 0) {
1143+
err_msg("fputs error");
1144+
llsErr = 1;
1145+
break;
1146+
}
1147+
} while (WS_FindNextFileA(findHandle,
1148+
fileName, sizeof(fileName)));
1149+
FindClose(findHandle);
1150+
}
1151+
#elif defined(WOLFSSH_ZEPHYR)
1152+
{
1153+
WDIR dir;
1154+
struct fs_dirent dp;
1155+
1156+
if (WOPENDIR(ssh->fs, NULL, &dir, cwd) != 0) {
1157+
if (SFTP_FPUTS(args,
1158+
"Error opening local directory\n") < 0) {
1159+
err_msg("fputs error");
1160+
return -1;
1161+
}
1162+
continue;
1163+
}
1164+
1165+
while (fs_readdir(&dir, &dp) == 0 &&
1166+
dp.name[0] != '\0') {
1167+
if (SFTP_FPUTS(args, dp.name) < 0 ||
1168+
SFTP_FPUTS(args, "\n") < 0) {
1169+
err_msg("fputs error");
1170+
llsErr = 1;
1171+
break;
1172+
}
1173+
}
1174+
WCLOSEDIR(ssh->fs, &dir);
1175+
}
1176+
#else
1177+
{
1178+
WDIR dir;
1179+
struct dirent* dp;
1180+
1181+
if (WOPENDIR(ssh->fs, NULL, &dir, cwd) != 0) {
1182+
if (SFTP_FPUTS(args,
1183+
"Error opening local directory\n") < 0) {
1184+
err_msg("fputs error");
1185+
return -1;
1186+
}
1187+
continue;
1188+
}
1189+
1190+
while ((dp = WREADDIR(ssh->fs, &dir)) != NULL) {
1191+
if (SFTP_FPUTS(args, dp->d_name) < 0 ||
1192+
SFTP_FPUTS(args, "\n") < 0) {
1193+
err_msg("fputs error");
1194+
llsErr = 1;
1195+
break;
1196+
}
1197+
}
1198+
WCLOSEDIR(ssh->fs, &dir);
1199+
}
1200+
#endif
1201+
if (llsErr) {
1202+
return -1;
1203+
}
1204+
continue;
1205+
}
1206+
#endif /* !NO_WOLFSSH_DIR && !WOLFSSH_FATFS */
1207+
10741208
if (WSTRNSTR(msg, "ls", MAX_CMD_SZ) != NULL) {
10751209
WS_SFTPNAME* tmp;
10761210
WS_SFTPNAME* current;
@@ -1503,8 +1637,9 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
15031637
int err;
15041638
ret = wolfSSH_shutdown(ssh);
15051639

1506-
/* peer hung up, stop trying to shutdown */
1507-
if (ret == WS_SOCKET_ERROR_E) {
1640+
/* peer hung up or channel already closed, stop trying */
1641+
if (ret == WS_SOCKET_ERROR_E || ret == WS_ERROR ||
1642+
ret == WS_CHANNEL_CLOSED) {
15081643
ret = 0;
15091644
}
15101645

@@ -1525,7 +1660,7 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
15251660
}
15261661

15271662
/* peer hung up, stop shutdown */
1528-
if (ret == WS_SOCKET_ERROR_E) {
1663+
if (ret == WS_SOCKET_ERROR_E || ret == WS_ERROR) {
15291664
ret = 0;
15301665
break;
15311666
}

tests/sftp.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,67 @@ static int checkLsSize(void)
136136
sizeof(inBuf)) == NULL) ? 1 : 0;
137137
}
138138

139+
static int checkCdNonexistent(void)
140+
{
141+
if (WSTRNSTR(inBuf, "Error changing directory",
142+
sizeof(inBuf)) == NULL) {
143+
fprintf(stderr,
144+
"cd: expected error not found in %s\n", inBuf);
145+
return 1;
146+
}
147+
return 0;
148+
}
149+
150+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
151+
static int checkLlsHasConfigureAc(void)
152+
{
153+
if (WSTRNSTR(inBuf, "configure.ac",
154+
sizeof(inBuf)) == NULL) {
155+
fprintf(stderr,
156+
"lls: configure.ac not found in %s\n", inBuf);
157+
return 1;
158+
}
159+
return 0;
160+
}
161+
#endif /* !NO_WOLFSSH_DIR && !WOLFSSH_FATFS */
162+
163+
static int checkLcdNonexistent(void)
164+
{
165+
if (WSTRNSTR(inBuf, "Error changing local directory",
166+
sizeof(inBuf)) == NULL) {
167+
fprintf(stderr,
168+
"lcd: expected error not found in %s\n", inBuf);
169+
return 1;
170+
}
171+
return 0;
172+
}
173+
174+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
175+
/* after lcd into keys/, lls should show key files */
176+
static int checkLlsInKeys(void)
177+
{
178+
if (WSTRNSTR(inBuf, ".pem", sizeof(inBuf)) == NULL &&
179+
WSTRNSTR(inBuf, ".der", sizeof(inBuf)) == NULL) {
180+
fprintf(stderr,
181+
"lls: expected key files not found in %s\n", inBuf);
182+
return 1;
183+
}
184+
return 0;
185+
}
186+
187+
/* after lcd back to .., lls should show project root files */
188+
static int checkLlsBackToRoot(void)
189+
{
190+
if (WSTRNSTR(inBuf, "configure.ac",
191+
sizeof(inBuf)) == NULL) {
192+
fprintf(stderr,
193+
"lls: configure.ac not found after lcd ..\n");
194+
return 1;
195+
}
196+
return 0;
197+
}
198+
#endif /* !NO_WOLFSSH_DIR && !WOLFSSH_FATFS */
199+
139200
static const SftpTestCmd cmds[] = {
140201
/* If a prior run was interrupted, files and directories
141202
* created during the test may still exist in the working
@@ -176,6 +237,21 @@ static const SftpTestCmd cmds[] = {
176237
{ "chmod 600 test-get-2", NULL },
177238
{ "rm test-get-2", NULL },
178239
{ "ls -s", checkLsSize },
240+
{ "cd /nonexistent_path_xyz", checkCdNonexistent },
241+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
242+
{ "lls", checkLlsHasConfigureAc },
243+
#endif
244+
{ "lcd /nonexistent_path_xyz", checkLcdNonexistent },
245+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS) \
246+
&& !defined(WOLFSSH_ZEPHYR)
247+
/* lcd into a subdirectory, verify with lls, then return.
248+
* Skipped on Zephyr: lls always lists the default dir
249+
* (no WGETCWD) and the keys/ tree is not on the RAM fs. */
250+
{ "lcd keys", NULL },
251+
{ "lls", checkLlsInKeys },
252+
{ "lcd ..", NULL },
253+
{ "lls", checkLlsBackToRoot },
254+
#endif
179255
/* empty arg tests: must not underflow on pt[sz-1] */
180256
{ "mkdir", NULL },
181257
{ "cd", NULL },

0 commit comments

Comments
 (0)