Skip to content

Commit 6019334

Browse files
Fix retry loop in doAutopilot
1 parent 0b37d43 commit 6019334

1 file changed

Lines changed: 49 additions & 11 deletions

File tree

examples/sftpclient/sftpclient.c

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,33 @@ static int doCmds(func_args* args)
12911291
}
12921292

12931293

1294+
/* Resolve the CWD via RealPath (passing "." to get the current directory)
1295+
* and append the relative remote path into fullpath. WS_REKEYING and
1296+
* WS_WINDOW_FULL are intentionally excluded from the retry condition below;
1297+
* they require a wolfSSH_worker call that the caller's outer loop provides. */
1298+
static int doBuildRemotePath(const char* remote, char* fullpath, word32 fullpathSz,
1299+
WS_SFTPNAME** nameOut)
1300+
{
1301+
int err;
1302+
1303+
if (remote == NULL || fullpath == NULL || fullpathSz == 0 || nameOut == NULL)
1304+
return WS_BAD_ARGUMENT;
1305+
do {
1306+
*nameOut = wolfSSH_SFTP_RealPath(ssh, (char*)".");
1307+
err = wolfSSH_get_error(ssh);
1308+
} while (err == WS_WANT_READ || err == WS_WANT_WRITE);
1309+
if (*nameOut == NULL)
1310+
return (err == WS_SUCCESS) ? WS_FATAL_ERROR : err;
1311+
if (snprintf(fullpath, fullpathSz, "%s/%s", (*nameOut)->fName, remote)
1312+
>= (int)fullpathSz) {
1313+
wolfSSH_SFTPNAME_list_free(*nameOut);
1314+
*nameOut = NULL;
1315+
return WS_FATAL_ERROR;
1316+
}
1317+
return WS_SUCCESS;
1318+
}
1319+
1320+
12941321
/* alternate main loop for the autopilot get/receive */
12951322
static int doAutopilot(int cmd, char* local, char* remote)
12961323
{
@@ -1319,22 +1346,33 @@ static int doAutopilot(int cmd, char* local, char* remote)
13191346
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
13201347
}
13211348
else {
1322-
do {
1323-
name = wolfSSH_SFTP_RealPath(ssh, fullpath);
1324-
err = wolfSSH_get_error(ssh);
1325-
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE) &&
1326-
ret != WS_SUCCESS);
1327-
1328-
snprintf(fullpath, sizeof(fullpath), "%s/%s",
1329-
name == NULL ? "." : name->fName,
1330-
remote);
1349+
err = doBuildRemotePath(remote, fullpath, sizeof(fullpath), &name);
1350+
if (err != WS_SUCCESS && err != WS_REKEYING && err != WS_WINDOW_FULL)
1351+
return WS_FATAL_ERROR;
13311352
}
13321353

13331354
do {
1334-
if (err == WS_REKEYING || err == WS_WINDOW_FULL) { /* handle rekeying state */
1355+
if (err == WS_REKEYING || err == WS_WINDOW_FULL) { /* handle rekeying and window-full state */
13351356
do {
13361357
ret = wolfSSH_worker(ssh, NULL);
1337-
} while (ret == WS_REKEYING);
1358+
} while (ret == WS_REKEYING || ret == WS_WINDOW_FULL ||
1359+
wolfSSH_get_error(ssh) == WS_REKEYING);
1360+
1361+
/* wolfSSH_worker returns WS_FATAL_ERROR when the socket
1362+
* would block (DoReceive -> GetInputData -> WS_WANT_READ),
1363+
* so check ssh->error rather than ret for blocking conditions. */
1364+
if (ret != WS_SUCCESS && ret != WS_CHAN_RXD &&
1365+
wolfSSH_get_error(ssh) != WS_WANT_READ &&
1366+
wolfSSH_get_error(ssh) != WS_WANT_WRITE)
1367+
break;
1368+
1369+
if (!remoteAbsPath && name == NULL) {
1370+
err = doBuildRemotePath(remote, fullpath, sizeof(fullpath), &name);
1371+
if (err != WS_SUCCESS) {
1372+
ret = WS_FATAL_ERROR;
1373+
continue; /* skip wolfSSH_get_error; outer loop retries on err from doBuildRemotePath */
1374+
}
1375+
}
13381376
}
13391377

13401378
if (cmd == AUTOPILOT_PUT) {

0 commit comments

Comments
 (0)