diff --git a/doc/xml/release.xml b/doc/xml/release.xml index 576f11fbb..540f2b156 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -29,6 +29,10 @@

Ignore SIGPIPE signals and check EPIPE result instead.

+ +

Make the C version of the info command conform to the Perl version.

+
+

Improve accuracy of strSizeFormat().

diff --git a/src/Makefile b/src/Makefile index 7e31e1b47..a2653451b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -62,6 +62,7 @@ SRCS = \ command/archive/get/get.c \ command/archive/push/push.c \ command/help/help.c \ + command/info/info.c \ command/command.c \ command/control/control.c \ common/debug.c \ @@ -115,6 +116,8 @@ SRCS = \ crypto/crypto.c \ info/info.c \ info/infoArchive.c \ + info/infoBackup.c \ + info/infoManifest.c \ info/infoPg.c \ perl/config.c \ perl/exec.c \ @@ -348,7 +351,7 @@ info/infoManifest.o: info/infoManifest.c common/error.auto.h common/error.h comm info/infoPg.o: info/infoPg.c common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/crypto.h crypto/hash.h info/info.h info/infoPg.h postgres/interface.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h $(CC) $(CFLAGS) -c info/infoPg.c -o info/infoPg.o -main.o: main.c command/archive/get/get.h command/archive/push/push.h command/command.h command/help/help.h common/debug.h common/error.auto.h common/error.h common/exit.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/interface.h version.h +main.o: main.c command/archive/get/get.h command/archive/push/push.h command/command.h command/help/help.h command/info/info.h common/debug.h common/error.auto.h common/error.h common/exit.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/interface.h version.h $(CC) $(CFLAGS) -c main.c -o main.o perl/config.o: perl/config.c common/debug.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h diff --git a/src/command/info/info.c b/src/command/info/info.c index 9911e8349..2aa407165 100644 --- a/src/command/info/info.c +++ b/src/command/info/info.c @@ -96,7 +96,7 @@ stanzaStatus(const int code, const String *message, Variant *stanzaInfo) /*********************************************************************************************************************************** Set the data for the archive section of the stanza for the database info from the backup.info file. ***********************************************************************************************************************************/ -void +static void archiveDbList(const String *stanza, const InfoPgData *pgData, VariantList *archiveSection, const InfoArchive *info, bool currentDb) { FUNCTION_TEST_BEGIN(); @@ -149,7 +149,7 @@ archiveDbList(const String *stanza, const InfoPgData *pgData, VariantList *archi } // Iterate through the directory list in the reverse so processing newest first. Cast comparison to an int for readability. - for (unsigned int idx = sizeWalDir - 1; (int)idx > 0; idx--) + for (unsigned int idx = sizeWalDir - 1; (int)idx >= 0; idx--) { // Get a list of all WAL in this WAL dir StringList *list = storageListP( @@ -189,15 +189,13 @@ archiveDbList(const String *stanza, const InfoPgData *pgData, VariantList *archi /*********************************************************************************************************************************** For each current backup in the backup.info file of the stanza, set the data for the backup section. ***********************************************************************************************************************************/ -void -backupList(const String *stanza, VariantList *backupSection, InfoBackup *info) +static void +backupList(VariantList *backupSection, InfoBackup *info) { FUNCTION_TEST_BEGIN(); - FUNCTION_TEST_PARAM(STRING, stanza); FUNCTION_TEST_PARAM(VARIANT, backupSection); FUNCTION_TEST_PARAM(INFO_BACKUP, info); - FUNCTION_TEST_ASSERT(stanza != NULL); FUNCTION_TEST_ASSERT(backupSection != NULL); FUNCTION_TEST_ASSERT(info != NULL); FUNCTION_TEST_END(); @@ -310,7 +308,7 @@ stanzaInfoList(const String *stanza, StringList *stanzaList) { // Attempt to load the backup info file info = infoBackupNew( - storageRepo(), strNewFmt("%s/%s/%s", STORAGE_REPO_BACKUP, strPtr(stanzaListName), INFO_BACKUP_FILE), false, + storageRepo(), strNewFmt(STORAGE_PATH_BACKUP "/%s/%s", strPtr(stanzaListName), INFO_BACKUP_FILE), false, cipherType(cfgOptionStr(cfgOptRepoCipherType)), cfgOptionStr(cfgOptRepoCipherPass)); } CATCH(FileMissingError) @@ -337,7 +335,7 @@ stanzaInfoList(const String *stanza, StringList *stanzaList) // If the backup.info file exists, get the database history information (newest to oldest) and corresponding archive if (info != NULL) { - for (unsigned int pgIdx = 0; pgIdx < infoPgDataTotal(infoBackupPg(info)); pgIdx++) + for (unsigned int pgIdx = infoPgDataTotal(infoBackupPg(info)) - 1; (int)pgIdx >= 0; pgIdx--) { InfoPgData pgData = infoPgData(infoBackupPg(info), pgIdx); Variant *pgInfo = varNewKv(); @@ -350,13 +348,13 @@ stanzaInfoList(const String *stanza, StringList *stanzaList) // Get the archive info for the DB from the archive.info file InfoArchive *info = infoArchiveNew( - storageRepo(), strNewFmt("%s/%s/%s", STORAGE_REPO_ARCHIVE, strPtr(stanzaListName), INFO_ARCHIVE_FILE), false, + storageRepo(), strNewFmt(STORAGE_PATH_ARCHIVE "/%s/%s", strPtr(stanzaListName), INFO_ARCHIVE_FILE), false, cipherType(cfgOptionStr(cfgOptRepoCipherType)), cfgOptionStr(cfgOptRepoCipherPass)); archiveDbList(stanzaListName, &pgData, archiveSection, info, (pgIdx == 0 ? true : false)); } // Get data for all existing backups for this stanza - backupList(stanzaListName, backupSection, info); + backupList(backupSection, info); } // Add the database history, backup and archive sections to the stanza info @@ -413,13 +411,13 @@ formatTextDb(const KeyValue *stanzaInfo, String *resultStr) VariantList *backupSection = kvGetList(stanzaInfo, varNewStr(STANZA_KEY_BACKUP_STR)); // For each database (working from oldest to newest) find the corresponding archive and backup info - for (unsigned int dbIdx = varLstSize(dbSection) - 1; (int)dbIdx >= 0; dbIdx--) + for (unsigned int dbIdx = 0; dbIdx < varLstSize(dbSection); dbIdx++) { KeyValue *pgInfo = varKv(varLstGet(dbSection, dbIdx)); uint64_t dbId = varUInt64(kvGet(pgInfo, varNewStr(DB_KEY_ID_STR))); // List is ordered so 0 is always the current DB index - if (dbIdx == 0) + if (dbIdx == varLstSize(dbSection) - 1) strCat(resultStr, "\n db (current)"); // Get the min/max archive information for the database @@ -515,7 +513,7 @@ formatTextDb(const KeyValue *stanzaInfo, String *resultStr) // If there is data to display, then display it. if (strSize(archiveResult) > 0 || strSize(backupResult) > 0) { - if (dbIdx != 0) + if (dbIdx != varLstSize(dbSection) - 1) strCat(resultStr, "\n db (prior)"); if (strSize(archiveResult) > 0) @@ -544,12 +542,12 @@ infoRender(void) const String *stanza = cfgOptionTest(cfgOptStanza) ? cfgOptionStr(cfgOptStanza) : NULL; // Get a list of stanzas in the backup directory. - StringList *stanzaList = storageListP(storageRepo(), strNew(STORAGE_REPO_BACKUP), .errorOnMissing = true); + StringList *stanzaList = storageListP(storageRepo(), STORAGE_PATH_BACKUP_STR, .errorOnMissing = false); VariantList *infoList = varLstNew(); String *resultStr = strNew(""); // If the backup storage exists, then search for and process any stanzas - if (strLstSize(stanzaList) > 0) + if (stanzaList != NULL && strLstSize(stanzaList) > 0) infoList = stanzaInfoList(stanza, stanzaList); // Format text output @@ -604,7 +602,7 @@ infoRender(void) } } else - resultStr = strNewFmt("No stanzas exist in %s\n", strPtr(storagePathNP(storageRepo(), NULL))); + resultStr = strNewFmt("No stanzas exist in %s.\n", strPtr(storagePathNP(storageRepo(), NULL))); } // Format json output else diff --git a/src/main.c b/src/main.c index 205b522b2..3fd3c4d36 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ Main #include "command/archive/get/get.h" #include "command/archive/push/push.h" #include "command/help/help.h" +#include "command/info/info.h" #include "command/command.h" #include "common/debug.h" #include "common/error.h" diff --git a/src/storage/helper.c b/src/storage/helper.c index db52960d6..52803969f 100644 --- a/src/storage/helper.c +++ b/src/storage/helper.c @@ -17,8 +17,8 @@ Storage path constants STRING_EXTERN(STORAGE_SPOOL_ARCHIVE_IN_STR, STORAGE_SPOOL_ARCHIVE_IN); STRING_EXTERN(STORAGE_SPOOL_ARCHIVE_OUT_STR, STORAGE_SPOOL_ARCHIVE_OUT); -#define STORAGE_PATH_ARCHIVE "archive" -#define STORAGE_PATH_BACKUP "backup" +STRING_EXTERN(STORAGE_PATH_ARCHIVE_STR, STORAGE_PATH_ARCHIVE); +STRING_EXTERN(STORAGE_PATH_BACKUP_STR, STORAGE_PATH_BACKUP); /*********************************************************************************************************************************** Local variables diff --git a/src/storage/helper.h b/src/storage/helper.h index 83cc0267b..75e31e931 100644 --- a/src/storage/helper.h +++ b/src/storage/helper.h @@ -17,6 +17,11 @@ Storage path constants #define STORAGE_REPO_ARCHIVE "" #define STORAGE_REPO_BACKUP "" +#define STORAGE_PATH_ARCHIVE "archive" + STRING_DECLARE(STORAGE_PATH_ARCHIVE_STR); +#define STORAGE_PATH_BACKUP "backup" + STRING_DECLARE(STORAGE_PATH_BACKUP_STR); + /*********************************************************************************************************************************** Repository storage types ***********************************************************************************************************************************/ diff --git a/test/src/module/command/infoTest.c b/test/src/module/command/infoTest.c index 3bf3c1404..9cc61cb54 100644 --- a/test/src/module/command/infoTest.c +++ b/test/src/module/command/infoTest.c @@ -32,22 +32,16 @@ testRun(void) strLstAddZ(argList, "--output=json"); harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); - // No repo path - //-------------------------------------------------------------------------------------------------------------------------- - TEST_ERROR_FMT( - infoRender(), PathOpenError, - "unable to open path '%s' for read: [2] No such file or directory", strPtr(backupPath)); - - storagePathCreateNP(storageLocalWrite(), archivePath); - storagePathCreateNP(storageLocalWrite(), backupPath); - // No stanzas have been created //-------------------------------------------------------------------------------------------------------------------------- TEST_RESULT_STR(strPtr(infoRender()), "[]\n", "json - repo but no stanzas"); harnessCfgLoad(strLstSize(argListText), strLstPtr(argListText)); TEST_RESULT_STR(strPtr(infoRender()), - strPtr(strNewFmt("No stanzas exist in %s\n", strPtr(storagePathNP(storageRepo(), NULL)))), "text - no stanzas"); + strPtr(strNewFmt("No stanzas exist in %s.\n", strPtr(storagePathNP(storageRepo(), NULL)))), "text - no stanzas"); + + storagePathCreateNP(storageLocalWrite(), archivePath); + storagePathCreateNP(storageLocalWrite(), backupPath); // Empty stanza //-------------------------------------------------------------------------------------------------------------------------- @@ -155,14 +149,14 @@ testRun(void) " \"cipher\" : \"none\",\n" " \"db\" : [\n" " {\n" - " \"id\" : 2,\n" - " \"system-id\" : 6569239123849665679,\n" - " \"version\" : \"9.4\"\n" - " },\n" - " {\n" " \"id\" : 1,\n" " \"system-id\" : 6569239123849665666,\n" " \"version\" : \"9.3\"\n" + " },\n" + " {\n" + " \"id\" : 2,\n" + " \"system-id\" : 6569239123849665679,\n" + " \"version\" : \"9.4\"\n" " }\n" " ],\n" " \"name\" : \"stanza1\",\n" @@ -249,19 +243,19 @@ testRun(void) " \"archive\" : [\n" " {\n" " \"database\" : {\n" - " \"id\" : 3\n" - " },\n" - " \"id\" : \"9.4-3\",\n" - " \"max\" : null,\n" - " \"min\" : null\n" - " },\n" - " {\n" - " \"database\" : {\n" " \"id\" : 1\n" " },\n" " \"id\" : \"9.4-1\",\n" " \"max\" : \"000000020000000000000003\",\n" " \"min\" : \"000000010000000000000002\"\n" + " },\n" + " {\n" + " \"database\" : {\n" + " \"id\" : 3\n" + " },\n" + " \"id\" : \"9.4-3\",\n" + " \"max\" : null,\n" + " \"min\" : null\n" " }\n" " ],\n" " \"backup\" : [\n" @@ -298,7 +292,7 @@ testRun(void) " \"cipher\" : \"none\",\n" " \"db\" : [\n" " {\n" - " \"id\" : 3,\n" + " \"id\" : 1,\n" " \"system-id\" : 6569239123849665679,\n" " \"version\" : \"9.4\"\n" " },\n" @@ -308,7 +302,7 @@ testRun(void) " \"version\" : \"9.3\"\n" " },\n" " {\n" - " \"id\" : 1,\n" + " \"id\" : 3,\n" " \"system-id\" : 6569239123849665679,\n" " \"version\" : \"9.4\"\n" " }\n" @@ -470,19 +464,19 @@ testRun(void) " \"archive\" : [\n" " {\n" " \"database\" : {\n" - " \"id\" : 2\n" - " },\n" - " \"id\" : \"9.5-2\",\n" - " \"max\" : null,\n" - " \"min\" : null\n" - " },\n" - " {\n" - " \"database\" : {\n" " \"id\" : 1\n" " },\n" " \"id\" : \"9.4-1\",\n" " \"max\" : \"000000020000000000000003\",\n" " \"min\" : \"000000010000000000000002\"\n" + " },\n" + " {\n" + " \"database\" : {\n" + " \"id\" : 2\n" + " },\n" + " \"id\" : \"9.5-2\",\n" + " \"max\" : null,\n" + " \"min\" : null\n" " }\n" " ],\n" " \"backup\" : [\n" @@ -582,14 +576,14 @@ testRun(void) " \"cipher\" : \"none\",\n" " \"db\" : [\n" " {\n" - " \"id\" : 2,\n" - " \"system-id\" : 6626363367545678089,\n" - " \"version\" : \"9.5\"\n" - " },\n" - " {\n" " \"id\" : 1,\n" " \"system-id\" : 6625592122879095702,\n" " \"version\" : \"9.4\"\n" + " },\n" + " {\n" + " \"id\" : 2,\n" + " \"system-id\" : 6626363367545678089,\n" + " \"version\" : \"9.5\"\n" " }\n" " ],\n" " \"name\" : \"stanza1\",\n" @@ -842,7 +836,7 @@ testRun(void) // Restore normal stdout dup2(stdoutSave, STDOUT_FILENO); - const char *generalHelp = strPtr(strNewFmt("No stanzas exist in %s\n", strPtr(repoPath))); + const char *generalHelp = strPtr(strNewFmt("No stanzas exist in %s.\n", strPtr(repoPath))); Storage *storage = storageDriverPosixInterface( storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));