Skip to content

Commit b71670f

Browse files
authored
Merge pull request wolfSSL#909 from padelsbach/lls-lcd-commands
Add lcd and lls commands
2 parents eb49029 + 453371f commit b71670f

File tree

2 files changed

+215
-3
lines changed

2 files changed

+215
-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: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,68 @@ 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+
&& !defined(WOLFSSH_ZEPHYR)
176+
/* after lcd into keys/, lls should show key files */
177+
static int checkLlsInKeys(void)
178+
{
179+
if (WSTRNSTR(inBuf, ".pem", sizeof(inBuf)) == NULL &&
180+
WSTRNSTR(inBuf, ".der", sizeof(inBuf)) == NULL) {
181+
fprintf(stderr,
182+
"lls: expected key files not found in %s\n", inBuf);
183+
return 1;
184+
}
185+
return 0;
186+
}
187+
188+
/* after lcd back to .., lls should show project root files */
189+
static int checkLlsBackToRoot(void)
190+
{
191+
if (WSTRNSTR(inBuf, "configure.ac",
192+
sizeof(inBuf)) == NULL) {
193+
fprintf(stderr,
194+
"lls: configure.ac not found after lcd ..\n");
195+
return 1;
196+
}
197+
return 0;
198+
}
199+
#endif /* !NO_WOLFSSH_DIR && !WOLFSSH_FATFS && !WOLFSSH_ZEPHYR */
200+
139201
static const SftpTestCmd cmds[] = {
140202
/* If a prior run was interrupted, files and directories
141203
* created during the test may still exist in the working
@@ -176,6 +238,21 @@ static const SftpTestCmd cmds[] = {
176238
{ "chmod 600 test-get-2", NULL },
177239
{ "rm test-get-2", NULL },
178240
{ "ls -s", checkLsSize },
241+
{ "cd /nonexistent_path_xyz", checkCdNonexistent },
242+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
243+
{ "lls", checkLlsHasConfigureAc },
244+
#endif
245+
{ "lcd /nonexistent_path_xyz", checkLcdNonexistent },
246+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS) \
247+
&& !defined(WOLFSSH_ZEPHYR)
248+
/* lcd into a subdirectory, verify with lls, then return.
249+
* Skipped on Zephyr: lls always lists the default dir
250+
* (no WGETCWD) and the keys/ tree is not on the RAM fs. */
251+
{ "lcd keys", NULL },
252+
{ "lls", checkLlsInKeys },
253+
{ "lcd ..", NULL },
254+
{ "lls", checkLlsBackToRoot },
255+
#endif
179256
/* empty arg tests: must not underflow on pt[sz-1] */
180257
{ "mkdir", NULL },
181258
{ "cd", NULL },

0 commit comments

Comments
 (0)