Skip to content

Commit e1dca27

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

File tree

2 files changed

+199
-6
lines changed

2 files changed

+199
-6
lines changed

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: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,19 @@ 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+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
74+
"lls",
75+
#endif
76+
"lcd /nonexistent_path_xyz",
7177
"exit"
7278
};
7379
static int commandIdx = 0;
@@ -129,14 +135,67 @@ static int Expected(int command)
129135
return 0;
130136
}
131137

132-
case 10:
133-
return (WSTRNSTR(inBuf, "test-get", sizeof(inBuf)) == NULL);
138+
case 10: /* pwd after cd ../ */
139+
for (i = 0; i < (int)sizeof(inBuf); i++) {
140+
if (inBuf[i] == '\n') {
141+
inBuf[i] = '\0';
142+
break;
143+
}
144+
}
145+
if (WSTRLEN(inBuf) >= 2 &&
146+
inBuf[WSTRLEN(inBuf) - 1] == 'a' &&
147+
inBuf[WSTRLEN(inBuf) - 2] == '/') {
148+
printf("pwd still in /a after cd ../: %s\n", inBuf);
149+
return -1;
150+
}
151+
break;
152+
153+
case 11: /* ls after cd ../ */
154+
return (WSTRNSTR(inBuf, "test-get",
155+
sizeof(inBuf)) == NULL);
156+
157+
case 14: /* ls after rmdir */
158+
return (WSTRNSTR(inBuf, "test-get-2",
159+
sizeof(inBuf)) == NULL);
134160

135-
case 13:
136-
return (WSTRNSTR(inBuf, "test-get-2", sizeof(inBuf)) == NULL);
161+
case 17: /* ls -s */
162+
return (WSTRNSTR(inBuf, "size in bytes",
163+
sizeof(inBuf)) == NULL);
137164

138-
case 16:
139-
return (WSTRNSTR(inBuf, "size in bytes", sizeof(inBuf)) == NULL);
165+
case 18: /* cd to nonexistent path */
166+
if (WSTRNSTR(inBuf, "Error changing directory",
167+
sizeof(inBuf)) == NULL) {
168+
fprintf(stderr,
169+
"cd: expected error not found in %s\n", inBuf);
170+
return 1;
171+
}
172+
return 0;
173+
174+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
175+
case 19: /* lls from working directory */
176+
if (WSTRNSTR(inBuf, "configure.ac",
177+
sizeof(inBuf)) == NULL) {
178+
fprintf(stderr,
179+
"lls: configure.ac not found in %s\n", inBuf);
180+
return 1;
181+
}
182+
return 0;
183+
#endif /* !NO_WOLFSSH_DIR && !WOLFSSH_FATFS */
184+
185+
/* lcd error: index differs based on whether lls is
186+
* included (20 with lls, 19 without) */
187+
#if !defined(NO_WOLFSSH_DIR) && !defined(WOLFSSH_FATFS)
188+
case 20:
189+
#else
190+
case 19:
191+
#endif
192+
if (WSTRNSTR(inBuf, "Error changing local directory",
193+
sizeof(inBuf)) == NULL) {
194+
fprintf(stderr,
195+
"lcd: expected error not found in %s\n", inBuf);
196+
return 1;
197+
}
198+
return 0;
140199

141200
default:
142201
break;

0 commit comments

Comments
 (0)