diff --git a/doc/xml/release/2024/2.54.xml b/doc/xml/release/2024/2.54.xml
index 621f3327f..84b08669d 100644
--- a/doc/xml/release/2024/2.54.xml
+++ b/doc/xml/release/2024/2.54.xml
@@ -104,6 +104,17 @@
Remove limitation on reading files in parallel during restore.
+
+
+
+
+
+
+
+
+
+ Improve SFTP error messages.
+
diff --git a/src/storage/sftp/storage.c b/src/storage/sftp/storage.c
index 9b162409d..3eadb97ff 100644
--- a/src/storage/sftp/storage.c
+++ b/src/storage/sftp/storage.c
@@ -92,6 +92,113 @@ storageSftpKnownHostKeyType(const int hostKeyType)
FUNCTION_TEST_RETURN(INT, result);
}
+/***********************************************************************************************************************************
+Return error message based on error code
+***********************************************************************************************************************************/
+static const char *
+libssh2SftpErrorMsg(const uint64_t error)
+{
+ FUNCTION_TEST_BEGIN();
+ FUNCTION_TEST_PARAM(UINT64, error);
+ FUNCTION_TEST_END();
+
+ const char *result;
+
+ // SFTP error status codes (returned by libssh2_sftp_last_error()
+ switch (error)
+ {
+ case LIBSSH2_FX_EOF:
+ result = "eof";
+ break;
+
+ case LIBSSH2_FX_NO_SUCH_FILE:
+ result = "no such file";
+ break;
+
+ case LIBSSH2_FX_PERMISSION_DENIED:
+ result = "permission denied";
+ break;
+
+ case LIBSSH2_FX_FAILURE:
+ result = "failure";
+ break;
+
+ case LIBSSH2_FX_BAD_MESSAGE:
+ result = "bad message";
+ break;
+
+ case LIBSSH2_FX_NO_CONNECTION:
+ result = "no connection";
+ break;
+
+ case LIBSSH2_FX_CONNECTION_LOST:
+ result = "connection lost";
+ break;
+
+ case LIBSSH2_FX_OP_UNSUPPORTED:
+ result = "operation unsupported";
+ break;
+
+ case LIBSSH2_FX_INVALID_HANDLE:
+ result = "invalid handle";
+ break;
+
+ case LIBSSH2_FX_NO_SUCH_PATH:
+ result = "no such path";
+ break;
+
+ case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+ result = "file already exists";
+ break;
+
+ case LIBSSH2_FX_WRITE_PROTECT:
+ result = "write protect";
+ break;
+
+ case LIBSSH2_FX_NO_MEDIA:
+ result = "no media";
+ break;
+
+ case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+ result = "no space on filesystem";
+ break;
+
+ case LIBSSH2_FX_QUOTA_EXCEEDED:
+ result = "quota exceeded";
+ break;
+
+ case LIBSSH2_FX_UNKNOWN_PRINCIPAL:
+ result = "unknown principal";
+ break;
+
+ case LIBSSH2_FX_LOCK_CONFLICT:
+ result = "lock conflict";
+ break;
+
+ case LIBSSH2_FX_DIR_NOT_EMPTY:
+ result = "directory not empty";
+ break;
+
+ case LIBSSH2_FX_NOT_A_DIRECTORY:
+ result = "not a directory";
+ break;
+
+ case LIBSSH2_FX_INVALID_FILENAME:
+ result = "invalid filename";
+ break;
+
+ case LIBSSH2_FX_LINK_LOOP:
+ result = "link loop";
+ break;
+
+ default:
+ result = "unknown error";
+ break;
+ }
+
+ FUNCTION_TEST_RETURN_CONST(STRINGZ, result);
+}
+
/***********************************************************************************************************************************
Return a match failed message based on known host check failure type
***********************************************************************************************************************************/
@@ -301,7 +408,8 @@ storageSftpLibSsh2SessionFreeResource(THIS_VOID)
THROW_FMT(
ServiceError, "failed to shutdown sftpSession: libssh2 errno [%d]%s", rc,
rc == LIBSSH2_ERROR_SFTP_PROTOCOL ?
- strZ(strNewFmt(": sftp errno [%lu]", libssh2_sftp_last_error(this->sftpSession))) : "");
+ strZ(strNewFmt(": sftp errno [%lu] %s", libssh2_sftp_last_error(this->sftpSession),
+ libssh2SftpErrorMsg(libssh2_sftp_last_error(this->sftpSession)))) : "");
else
THROW_FMT(
ServiceError, "timeout shutting down sftpSession: libssh2 errno [%d]", rc);
@@ -363,7 +471,8 @@ storageSftpEvalLibSsh2Error(
THROWP_FMT(
errorType, "%s%s%s%s", message != NULL ? zNewFmt("%s%s", strZ(message), ssh2Errno == 0 ? "" : ": ") : "",
ssh2Errno == 0 ? "" : zNewFmt("libssh2 error [%d]", ssh2Errno),
- ssh2Errno == LIBSSH2_ERROR_SFTP_PROTOCOL ? zNewFmt(": sftp error [%" PRIu64 "]", sftpErrno) : "",
+ ssh2Errno == LIBSSH2_ERROR_SFTP_PROTOCOL ?
+ zNewFmt(": sftp error [%" PRIu64 "] %s", sftpErrno, libssh2SftpErrorMsg(sftpErrno)) : "",
hint != NULL ? zNewFmt("\n%s", strZ(hint)) : "");
FUNCTION_TEST_NO_RETURN();
@@ -1011,8 +1120,8 @@ storageSftpPathRemove(THIS_VOID, const String *const path, const bool recurse, c
else
{
THROW_FMT(
- PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE " libssh sftp [%" PRIu64 "]", strZ(file),
- sftpErrno);
+ PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE " libssh sftp [%" PRIu64 "] %s", strZ(file),
+ sftpErrno, libssh2SftpErrorMsg(sftpErrno));
}
}
else
@@ -1046,7 +1155,11 @@ storageSftpPathRemove(THIS_VOID, const String *const path, const bool recurse, c
const uint64_t sftpErrno = libssh2_sftp_last_error(this->sftpSession);
if (sftpErrno != LIBSSH2_FX_NO_SUCH_FILE)
- THROW_FMT(PathRemoveError, STORAGE_ERROR_PATH_REMOVE " sftp error [%" PRIu64 "]", strZ(path), sftpErrno);
+ {
+ THROW_FMT(
+ PathRemoveError, STORAGE_ERROR_PATH_REMOVE " sftp error [%" PRIu64 "] %s", strZ(path), sftpErrno,
+ libssh2SftpErrorMsg(sftpErrno));
+ }
// Path does not exist
result = false;
diff --git a/test/define.yaml b/test/define.yaml
index 0684f151e..19d929a1b 100644
--- a/test/define.yaml
+++ b/test/define.yaml
@@ -626,7 +626,7 @@ unit:
# ----------------------------------------------------------------------------------------------------------------------------
- name: sftp
- total: 19
+ total: 20
harness:
name: libSsh2
integration: false
diff --git a/test/src/module/storage/sftpTest.c b/test/src/module/storage/sftpTest.c
index 3243b6f72..f739b8a70 100644
--- a/test/src/module/storage/sftpTest.c
+++ b/test/src/module/storage/sftpTest.c
@@ -2158,10 +2158,12 @@ testRun(void)
TEST_ERROR_FMT(
storageExistsP(storageTest, fileNoPerm),
- FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
+ FileOpenError,
+ STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm));
TEST_ERROR_FMT(
storagePathExistsP(storageTest, fileNoPerm),
- FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
+ FileOpenError,
+ STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("file and path");
@@ -2230,7 +2232,8 @@ testRun(void)
TEST_ERROR_FMT(
storageInfoP(storageTest, fileNoPerm),
- FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
+ FileOpenError,
+ STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -2566,7 +2569,7 @@ testRun(void)
// libssh2_sftp_symlink_ex fail link destination followLink false
TEST_ERROR_FMT(
storageInfoP(storageTest, linkName, .followLink = false), FileReadError,
- "unable to get destination for link '" TEST_PATH "/testlink': libssh2 error [-31]: sftp error [21]");
+ "unable to get destination for link '" TEST_PATH "/testlink': libssh2 error [-31]: sftp error [21] link loop");
// --------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("info - pipe");
@@ -2774,12 +2777,12 @@ testRun(void)
TEST_ERROR_FMT(
storageNewItrP(storageTest, pathNoPerm, .errorOnMissing = true), PathOpenError,
- STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3]", strZ(pathNoPerm));
+ STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm));
// Should still error even when ignore missing
TEST_ERROR_FMT(
storageNewItrP(storageTest, pathNoPerm), PathOpenError,
- STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3]", strZ(pathNoPerm));
+ STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("helper function - storageSftpListEntry()");
@@ -3740,12 +3743,12 @@ testRun(void)
TEST_ERROR_FMT(
storageListP(storageTest, pathNoPerm, .errorOnMissing = true), PathOpenError,
- STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3]", strZ(pathNoPerm));
+ STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm));
// Should still error even when ignore missing
TEST_ERROR_FMT(
storageListP(storageTest, pathNoPerm), PathOpenError,
- STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3]", strZ(pathNoPerm));
+ STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathNoPerm));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -4125,7 +4128,7 @@ testRun(void)
TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("sub3/sub4"), .noParentCreate = true), PathCreateError,
- "sftp error unable to create path '" TEST_PATH "/sub3/sub4': libssh2 error [-31]: sftp error [2]");
+ "sftp error unable to create path '" TEST_PATH "/sub3/sub4': libssh2 error [-31]: sftp error [2] no such file");
TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub3/sub4")), "create sub3/sub4");
// LIBSSH2_ERROR_EAGAIN timeout fail
@@ -4184,7 +4187,7 @@ testRun(void)
TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "timeout success");
TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("subfail"), .noParentCreate = true), PathCreateError,
- "sftp error unable to create path '" TEST_PATH "/subfail': libssh2 error [-31]: sftp error [3]");
+ "sftp error unable to create path '" TEST_PATH "/subfail': libssh2 error [-31]: sftp error [3] permission denied");
TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "do not throw error on already exists");
TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("subfail"), .errorOnExists = true), PathCreateError,
@@ -4391,11 +4394,11 @@ testRun(void)
// Mimic creation of pathRemove2 mode 700
TEST_ERROR_FMT(
- storagePathRemoveP(storageTest, pathRemove2), PathRemoveError, STORAGE_ERROR_PATH_REMOVE " sftp error [3]",
- strZ(pathRemove2));
+ storagePathRemoveP(storageTest, pathRemove2), PathRemoveError,
+ STORAGE_ERROR_PATH_REMOVE " sftp error [3] permission denied", strZ(pathRemove2));
TEST_ERROR_FMT(
storagePathRemoveP(storageTest, pathRemove2, .recurse = true), PathOpenError,
- STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3]", strZ(pathRemove2));
+ STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathRemove2));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("path remove - subpath permission denied");
@@ -4403,7 +4406,7 @@ testRun(void)
// Mimic chmod 777 pathRemove1
TEST_ERROR_FMT(
storagePathRemoveP(storageTest, pathRemove2, .recurse = true), PathOpenError,
- STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3]", strZ(pathRemove2));
+ STORAGE_ERROR_LIST_INFO ": libssh2 error [-31]: sftp error [3] permission denied", strZ(pathRemove2));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("path remove - file in subpath, permission denied");
@@ -4412,9 +4415,8 @@ testRun(void)
// Mimic "sudo chmod 755 %s && sudo touch %s && sudo chmod 777 %s", strZ(pathRemove2), strZ(fileRemove), strZ(fileRemove));
TEST_ERROR_FMT(
- storagePathRemoveP(
- storageTest, pathRemove1, .recurse = true), PathRemoveError, STORAGE_ERROR_PATH_REMOVE " sftp error [3]",
- strZ(pathRemove2));
+ storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError,
+ STORAGE_ERROR_PATH_REMOVE " sftp error [3] permission denied", strZ(pathRemove2));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("path remove - path with subpath and file removed");
@@ -4426,17 +4428,15 @@ testRun(void)
TEST_TITLE("path remove - path with subpath ssh fail on unlink");
TEST_ERROR_FMT(
- storagePathRemoveP(
- storageTest, pathRemove1, .recurse = true), PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE " libssh ssh [-7]",
- strZ(pathRemove2));
+ storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError,
+ STORAGE_ERROR_PATH_REMOVE_FILE " libssh ssh [-7]", strZ(pathRemove2));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("path remove - other than LIBSSH2_FX_FAILURE/LIBSSH2_FX_PERMISSION_DENIED");
TEST_ERROR_FMT(
- storagePathRemoveP(
- storageTest, pathRemove1, .recurse = true), PathRemoveError, STORAGE_ERROR_PATH_REMOVE_FILE " libssh sftp [7]",
- strZ(pathRemove2));
+ storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError,
+ STORAGE_ERROR_PATH_REMOVE_FILE " libssh sftp [7] connection lost", strZ(pathRemove2));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -4958,7 +4958,7 @@ testRun(void)
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true, .noCreatePath = false), "new write file");
TEST_ERROR_FMT(
ioWriteOpen(storageWriteIo(file)), FileOpenError,
- STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
+ STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -5270,7 +5270,8 @@ testRun(void)
TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd");
TEST_ERROR_FMT(
ioWriteClose(storageWriteIo(file)), FileCloseError,
- "unable to move '%s' to '%s': libssh2 error [-31]: sftp error [7]", strZ(fileNameTmp), strZ(fileName));
+ "unable to move '%s' to '%s': libssh2 error [-31]: sftp error [7] connection lost", strZ(fileNameTmp),
+ strZ(fileName));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -5681,7 +5682,7 @@ testRun(void)
{.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING},
{.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"" TEST_PATH "/test.empty\"]",
.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
- {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK},
+ {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = 99},
HRNLIBSSH2_MACRO_SHUTDOWN()
});
@@ -5698,7 +5699,7 @@ testRun(void)
TEST_ERROR(
storagePutP(storageNewWriteP(storageTest, emptyFile), NULL), FileRemoveError,
- "unable to remove existing '" TEST_PATH "/test.empty': libssh2 error [-31]: sftp error [0]");
+ "unable to remove existing '" TEST_PATH "/test.empty': libssh2 error [-31]: sftp error [99] unknown error");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -6360,7 +6361,7 @@ testRun(void)
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true);
TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError,
- "unable to remove '/missing': libssh2 error [-31]: sftp error [2]");
+ "unable to remove '/missing': libssh2 error [-31]: sftp error [2] no such file");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -6390,7 +6391,7 @@ testRun(void)
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true);
TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing")), FileRemoveError,
- "unable to remove '/missing': libssh2 error [-31]: sftp error [7]");
+ "unable to remove '/missing': libssh2 error [-31]: sftp error [7] connection lost");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -6559,7 +6560,7 @@ testRun(void)
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen sftp error");
TEST_ERROR_FMT(
ioWriteOpen(storageWriteIo(file)), FileOpenError,
- STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3]", strZ(fileName));
+ STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileName));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -6659,7 +6660,7 @@ testRun(void)
TEST_ERROR_FMT(
ioReadOpen(storageReadIo(file)),
FileOpenError,
- STORAGE_ERROR_READ_OPEN ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
+ STORAGE_ERROR_READ_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileNoPerm));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("file missing");
@@ -6902,7 +6903,8 @@ testRun(void)
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true), "new write file");
TEST_ERROR_FMT(
ioWriteOpen(storageWriteIo(file)),
- FileOpenError, STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
+ FileOpenError, STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-31]: sftp error [3] permission denied",
+ strZ(fileNoPerm));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -7663,6 +7665,7 @@ testRun(void)
HRNLIBSSH2_MACRO_STARTUP(),
{.function = HRNLIBSSH2_SFTP_SHUTDOWN, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST},
+ {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_CONNECTION_LOST},
{.function = NULL},
});
@@ -7682,7 +7685,7 @@ testRun(void)
TEST_ASSIGN(storageSftp, storageDriver(storageTest), "assign storage");
TEST_ERROR_FMT(
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))), ServiceError,
- "failed to shutdown sftpSession: libssh2 errno [-31]: sftp errno [7]");
+ "failed to shutdown sftpSession: libssh2 errno [-31]: sftp errno [7] connection lost");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("storageSftpLibSsh2SessionFreeResource() sftp shutdown failure EAGAIN");
@@ -7859,19 +7862,46 @@ testRun(void)
LIBSSH2_ERROR_SFTP_PROTOCOL, 16, &FileRemoveError,
strNewFmt("unable to move '%s' to '%s'", "BOGUS", "NOT BOGUS"), STRDEF("HINT")),
FileRemoveError,
- "unable to move 'BOGUS' to 'NOT BOGUS': libssh2 error [-31]: sftp error [16]\n"
+ "unable to move 'BOGUS' to 'NOT BOGUS': libssh2 error [-31]: sftp error [16] unknown principal\n"
"HINT");
TEST_ERROR_FMT(
storageSftpEvalLibSsh2Error(
LIBSSH2_ERROR_SFTP_PROTOCOL, 16, &FileRemoveError,
strNewFmt("unable to move '%s' to '%s'", "BOGUS", "NOT BOGUS"), NULL),
- FileRemoveError,
- "unable to move 'BOGUS' to 'NOT BOGUS': libssh2 error [-31]: sftp error [16]");
+ FileRemoveError, "unable to move 'BOGUS' to 'NOT BOGUS': libssh2 error [-31]: sftp error [16] unknown principal");
TEST_ERROR_FMT(
- storageSftpEvalLibSsh2Error(
- LIBSSH2_ERROR_SFTP_PROTOCOL, 16, &FileRemoveError, NULL, NULL),
- FileRemoveError,
- "libssh2 error [-31]: sftp error [16]");
+ storageSftpEvalLibSsh2Error(LIBSSH2_ERROR_SFTP_PROTOCOL, 16, &FileRemoveError, NULL, NULL),
+ FileRemoveError, "libssh2 error [-31]: sftp error [16] unknown principal");
+#else
+ TEST_LOG(PROJECT_NAME " not built with sftp support");
+#endif // HAVE_LIBSSH2
+ }
+
+ // *****************************************************************************************************************************
+ if (testBegin("libssh2SftpErrorMsg()"))
+ {
+#ifdef HAVE_LIBSSH2
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("libssh2SftpErrorMsg()");
+
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_EOF), "eof", "LIBSSH2_FX_EOF");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_FAILURE), "failure", "LIBSSH2_FX_FAILURE");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_BAD_MESSAGE), "bad message", "LIBSSH2_FX_BAD_MESSAGE");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_NO_CONNECTION), "no connection", "LIBSSH2_FX_NO_CONNECTION");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_OP_UNSUPPORTED), "operation unsupported", "LIBSSH2_FX_OP_UNSUPPORTED");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_INVALID_HANDLE), "invalid handle", "LIBSSH2_FX_INVALID_HANDLE");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_NO_SUCH_PATH), "no such path", "LIBSSH2_FX_NO_SUCH_PATH");
+ TEST_RESULT_Z(
+ libssh2SftpErrorMsg(LIBSSH2_FX_FILE_ALREADY_EXISTS), "file already exists", "LIBSSH2_FX_FILE_ALREADY_EXISTS");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_WRITE_PROTECT), "write protect", "LIBSSH2_FX_WRITE_PROTECT");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_NO_MEDIA), "no media", "LIBSSH2_FX_NO_MEDIA");
+ TEST_RESULT_Z(
+ libssh2SftpErrorMsg(LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM), "no space on filesystem", "LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_QUOTA_EXCEEDED), "quota exceeded", "LIBSSH2_FX_QUOTA_EXCEEDED");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_LOCK_CONFLICT), "lock conflict", "LIBSSH2_FX_LOCK_CONFLICT");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_DIR_NOT_EMPTY), "directory not empty", "LIBSSH2_FX_DIR_NOT_EMPTY");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_NOT_A_DIRECTORY), "not a directory", "LIBSSH2_FX_NOT_A_DIRECTORY");
+ TEST_RESULT_Z(libssh2SftpErrorMsg(LIBSSH2_FX_INVALID_FILENAME), "invalid filename", "LIBSSH2_FX_INVALID_FILENAME");
#else
TEST_LOG(PROJECT_NAME " not built with sftp support");
#endif // HAVE_LIBSSH2