Skip to content

Commit aab9d58

Browse files
committed
Add lcd and lls commands
1 parent 3075b72 commit aab9d58

2 files changed

Lines changed: 204 additions & 6 deletions

File tree

examples/sftpclient/sftpclient.c

Lines changed: 134 additions & 0 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;

tests/sftp.c

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,29 @@ static const char* cmds[] = {
6161
#endif
6262
"rm configure.ac",
6363
"cd ../",
64+
"pwd",
6465
"ls",
6566
"rename test-get test-get-2",
6667
"rmdir a",
6768
"ls",
6869
"chmod 600 test-get-2",
6970
"rm test-get-2",
7071
"ls -s",
72+
"cd /nonexistent_path_xyz",
73+
"cd",
74+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
75+
"lls",
76+
#endif
77+
#ifdef USE_WINDOWS_API
78+
"lcd C:\\Windows",
79+
#else
80+
"lcd /tmp",
81+
#endif
82+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
83+
"lls",
84+
#endif
85+
"lcd /nonexistent_path_xyz",
86+
"lcd",
7187
"exit"
7288
};
7389
static int commandIdx = 0;
@@ -129,14 +145,62 @@ static int Expected(int command)
129145
return 0;
130146
}
131147

132-
case 10:
133-
return (WSTRNSTR(inBuf, "test-get", sizeof(inBuf)) == NULL);
148+
case 10: /* pwd after cd ../ */
149+
for (i = 0; i < (int)sizeof(inBuf); i++) {
150+
if (inBuf[i] == '\n') {
151+
inBuf[i] = '\0';
152+
break;
153+
}
154+
}
155+
if (WSTRLEN(inBuf) >= 2 &&
156+
inBuf[WSTRLEN(inBuf) - 1] == 'a' &&
157+
inBuf[WSTRLEN(inBuf) - 2] == '/') {
158+
printf("pwd still in /a after cd ../: %s\n", inBuf);
159+
return -1;
160+
}
161+
break;
162+
163+
case 11: /* ls after cd ../ */
164+
return (WSTRNSTR(inBuf, "test-get",
165+
sizeof(inBuf)) == NULL);
166+
167+
case 14: /* ls after rmdir */
168+
return (WSTRNSTR(inBuf, "test-get-2",
169+
sizeof(inBuf)) == NULL);
134170

135-
case 13:
136-
return (WSTRNSTR(inBuf, "test-get-2", sizeof(inBuf)) == NULL);
171+
case 17: /* ls -s */
172+
return (WSTRNSTR(inBuf, "size in bytes",
173+
sizeof(inBuf)) == NULL);
137174

138-
case 16:
139-
return (WSTRNSTR(inBuf, "size in bytes", sizeof(inBuf)) == NULL);
175+
case 18: /* cd to nonexistent path */
176+
if (WSTRNSTR(inBuf, "Error changing directory",
177+
sizeof(inBuf)) == NULL) {
178+
fprintf(stderr,
179+
"cd: expected error not found in %s\n", inBuf);
180+
return 1;
181+
}
182+
return 0;
183+
184+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
185+
case 20: /* lls from working directory */
186+
if (WSTRNSTR(inBuf, "configure.ac",
187+
sizeof(inBuf)) == NULL) {
188+
fprintf(stderr,
189+
"lls: configure.ac not found in %s\n", inBuf);
190+
return 1;
191+
}
192+
return 0;
193+
194+
case 23: /* lcd to nonexistent path */
195+
case 24: /* lcd with empty path */
196+
if (WSTRNSTR(inBuf, "Error changing local directory",
197+
sizeof(inBuf)) == NULL) {
198+
fprintf(stderr,
199+
"lcd: expected error not found in %s\n", inBuf);
200+
return 1;
201+
}
202+
return 0;
203+
#endif /* !NO_WOLFSSH_DIR && !WOLFSSH_FATFS */
140204

141205
default:
142206
break;

0 commit comments

Comments
 (0)