From 3c16d2c5ecccd13fe8cf5acc613ca533089e00f4 Mon Sep 17 00:00:00 2001 From: ngn Date: Sun, 25 Aug 2024 14:30:50 +0300 Subject: [PATCH] update: better error handling for pool list loading --- include/ctx.h | 4 +- include/error.h | 4 + include/util.h | 5 +- locale/tr/LC_MESSAGES/libmp.po | 258 ++++++++++++++++++--------------- src/ctx/sync.c | 2 +- src/error.c | 4 + src/package/data.c | 25 +++- src/pool/list.c | 28 ++-- src/util.c | 12 +- 9 files changed, 194 insertions(+), 148 deletions(-) diff --git a/include/ctx.h b/include/ctx.h index acabb71..cce406a 100644 --- a/include/ctx.h +++ b/include/ctx.h @@ -93,8 +93,8 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta void *data); // installs/updates a single package bool lm_ctx_check( lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t callback, void *data); // checks a single package -size_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data); // syncs all the pools -void lm_ctx_ping(lm_ctx_t *ctx, lm_ctx_ping_callback_t callback, void *data); // pings all the pools +ssize_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data); // syncs all the pools +void lm_ctx_ping(lm_ctx_t *ctx, lm_ctx_ping_callback_t callback, void *data); // pings all the pools bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, __sighandler_t handler, lm_ctx_serve_callback_t callback, void *data); // serves all the pools diff --git a/include/error.h b/include/error.h index 57f0d03..97d950f 100644 --- a/include/error.h +++ b/include/error.h @@ -154,6 +154,10 @@ typedef enum lm_error { LM_ERR_PoolInfoUnknown = 152, LM_ERR_MPTPBadPath = 153, LM_ERR_UnknownThread = 154, + LM_ERR_PkgBadVersion = 155, + LM_ERR_PkgDataMissing = 156, + LM_ERR_PoolListDataFail = 157, + LM_ERR_PoolListAddFail = 158, } lm_error_t; typedef struct lm_error_desc { diff --git a/include/util.h b/include/util.h index cd8a109..e25956b 100644 --- a/include/util.h +++ b/include/util.h @@ -33,8 +33,9 @@ bool rmrf(char *p); int digits(int n); bool package_parse(char *package, char *name, char *version); -bool package_version_valid(char *name); -bool package_name_valid(char *name); +bool __package_field_valid(char *field); +#define package_version_valid(x) __package_field_valid(x) +#define package_name_valid(x) __package_field_valid(x) void pdebug(const char *func, const char *fmt, ...); void pdebug_binary(char *data, size_t len); diff --git a/locale/tr/LC_MESSAGES/libmp.po b/locale/tr/LC_MESSAGES/libmp.po index cdd68ff..9b74715 100644 --- a/locale/tr/LC_MESSAGES/libmp.po +++ b/locale/tr/LC_MESSAGES/libmp.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-08-22 08:38+0300\n" +"POT-Creation-Date: 2024-08-25 14:07+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -203,461 +203,481 @@ msgid "failed to open extracted pool list directory" msgstr "" #: src/error.c:76 -msgid "failed to read access the pool list file" +#, c-format +msgid "failed to load \"%s\" data: %s" msgstr "" #: src/error.c:77 -msgid "failed to read access the pool info file" +#, c-format +msgid "failed add \"%s\" to the pool list: %s" msgstr "" #: src/error.c:78 -msgid "failed to parse package data" +msgid "failed to read access the pool list file" msgstr "" #: src/error.c:79 +msgid "failed to read access the pool info file" +msgstr "" + +#: src/error.c:80 +msgid "failed to parse package data" +msgstr "" + +#: src/error.c:81 #, fuzzy msgid "package name is invalid" msgstr "URL hostname is too large" -#: src/error.c:80 +#: src/error.c:82 +#, fuzzy +msgid "package version is invalid" +msgstr "URL hostname is too large" + +#: src/error.c:83 +#, c-format +msgid "package data has missing field: %s" +msgstr "" + +#: src/error.c:84 msgid "data path is not set with in the ctx" msgstr "" -#: src/error.c:81 +#: src/error.c:85 msgid "temp path is not set with in the ctx" msgstr "" -#: src/error.c:82 +#: src/error.c:86 msgid "root path is not set with in the ctx" msgstr "" -#: src/error.c:83 +#: src/error.c:87 #, c-format msgid "failed to set the ctx temp director to %s: %s" msgstr "" -#: src/error.c:84 +#: src/error.c:88 #, c-format msgid "failed to set the ctx root directory to %s: %s" msgstr "" -#: src/error.c:85 +#: src/error.c:89 #, c-format msgid "failed to set the ctx data directory to %s: %s" msgstr "" -#: src/error.c:86 +#: src/error.c:90 msgid "pool did not respond ping with pong" msgstr "" -#: src/error.c:87 +#: src/error.c:91 msgid "package file and directory paths are empty" msgstr "" -#: src/error.c:88 +#: src/error.c:92 msgid "failed to to open target file for sending" msgstr "" -#: src/error.c:89 +#: src/error.c:93 msgid "failed to to delete target file for receiving" msgstr "" -#: src/error.c:90 +#: src/error.c:94 msgid "failed to to open target file for receiving" msgstr "" -#: src/error.c:91 +#: src/error.c:95 msgid "got a bad response code for receiving the target file" msgstr "" -#: src/error.c:92 +#: src/error.c:96 msgid "failed to write to the target file for receiving" msgstr "" -#: src/error.c:93 +#: src/error.c:97 #, fuzzy msgid "package not found" msgstr "URL hostname is too large" -#: src/error.c:94 +#: src/error.c:98 msgid "failed to access to the database file/directory" msgstr "" -#: src/error.c:95 +#: src/error.c:99 msgid "failed to open SQLite database" msgstr "" -#: src/error.c:96 +#: src/error.c:100 msgid "failed to create table in SQLite database" msgstr "" -#: src/error.c:97 +#: src/error.c:101 msgid "failed to prepare statement for SQLite database" msgstr "" -#: src/error.c:98 +#: src/error.c:102 msgid "failed to insert to the table in SQLite database" msgstr "" -#: src/error.c:99 +#: src/error.c:103 msgid "failed to select from the table in SQLite database" msgstr "" -#: src/error.c:100 +#: src/error.c:104 msgid "failed to delete from the table in SQLite database" msgstr "" -#: src/error.c:101 +#: src/error.c:105 msgid "failed to find entry in SQLite database" msgstr "" -#: src/error.c:102 +#: src/error.c:106 msgid "failed to init GPG for package verification" msgstr "" -#: src/error.c:103 +#: src/error.c:107 msgid "failed to import signature to GPG for package verification" msgstr "" -#: src/error.c:104 +#: src/error.c:108 msgid "failed to import archive to GPG for package verification" msgstr "" -#: src/error.c:105 +#: src/error.c:109 msgid "package signature verification failed with zero matches" msgstr "" -#: src/error.c:106 +#: src/error.c:110 msgid "package signature verification failed with zero results" msgstr "" -#: src/error.c:107 +#: src/error.c:111 msgid "pool file and directory paths are empty" msgstr "" -#: src/error.c:108 +#: src/error.c:112 msgid "pool is not avaliable for connection" msgstr "" -#: src/error.c:109 +#: src/error.c:113 msgid "pool URL is empty or invalid" msgstr "" -#: src/error.c:110 +#: src/error.c:114 msgid "pool directory path is not accessible" msgstr "" -#: src/error.c:111 +#: src/error.c:115 msgid "pool directory sub-paths are not accessible" msgstr "" -#: src/error.c:112 +#: src/error.c:116 msgid "file list not found for the package" msgstr "" -#: src/error.c:113 +#: src/error.c:117 #, c-format msgid "failed to rename the file list for the package: %s" msgstr "" -#: src/error.c:114 +#: src/error.c:118 #, c-format msgid "failed to open the package file list: %s" msgstr "" -#: src/error.c:115 +#: src/error.c:119 #, c-format msgid "failed to open the database directory: %s" msgstr "" -#: src/error.c:116 +#: src/error.c:120 #, c-format msgid "failed to remove package file list: %s" msgstr "" -#: src/error.c:117 +#: src/error.c:121 msgid "package keep list not found in the database" msgstr "" -#: src/error.c:118 +#: src/error.c:122 msgid "failed to open package keep list in the database" msgstr "" -#: src/error.c:119 +#: src/error.c:123 msgid "failed to access package keep list database directory" msgstr "" -#: src/error.c:120 +#: src/error.c:124 msgid "failed to remove package keep list from the database" msgstr "" -#: src/error.c:121 +#: src/error.c:125 #, c-format msgid "failed to find %s (dependency of %s)" msgstr "" -#: src/error.c:122 +#: src/error.c:126 #, c-format msgid "failed to download %s for installation: %s" msgstr "" -#: src/error.c:123 +#: src/error.c:127 #, fuzzy msgid "package is not downloaded" msgstr "URL hostname is too large" -#: src/error.c:124 src/error.c:125 +#: src/error.c:128 src/error.c:129 msgid "failed to remove downloaded package" msgstr "" -#: src/error.c:126 +#: src/error.c:130 msgid "failed to open the destination file" msgstr "" -#: src/error.c:127 +#: src/error.c:131 msgid "failed to open the source file" msgstr "" -#: src/error.c:128 src/error.c:129 +#: src/error.c:132 src/error.c:133 msgid "failed to write to the destination file" msgstr "" -#: src/error.c:130 +#: src/error.c:134 msgid "package does not have associated pool" msgstr "" -#: src/error.c:131 +#: src/error.c:135 msgid "failed to create specified temp directory" msgstr "" -#: src/error.c:132 +#: src/error.c:136 msgid "package archive does not contain required files" msgstr "" -#: src/error.c:133 +#: src/error.c:137 msgid "package data does not match with target package" msgstr "" -#: src/error.c:134 +#: src/error.c:138 #, c-format msgid "failed to update changes file for package: %s" msgstr "" -#: src/error.c:135 +#: src/error.c:139 msgid "failed to access package hashes file" msgstr "" -#: src/error.c:136 +#: src/error.c:140 msgid "failed to remove package changes file from the database" msgstr "" -#: src/error.c:137 +#: src/error.c:141 msgid "failed to stat target file for sending" msgstr "" -#: src/error.c:138 +#: src/error.c:142 msgid "failed to format target file size for sending" msgstr "" -#: src/error.c:139 +#: src/error.c:143 msgid "failed to read target file size for sending" msgstr "" -#: src/error.c:140 +#: src/error.c:144 msgid "failed to parse target file size for receiving" msgstr "" -#: src/error.c:141 +#: src/error.c:145 msgid "target file is not fully received" msgstr "" -#: src/error.c:142 +#: src/error.c:146 msgid "failed to stat for target extract archive" msgstr "" -#: src/error.c:143 +#: src/error.c:147 #, c-format msgid "failed to add package file (%s) to the database: %s" msgstr "" -#: src/error.c:144 +#: src/error.c:148 #, c-format msgid "failed to extract package files: %s" msgstr "" -#: src/error.c:145 +#: src/error.c:149 #, c-format msgid "failed to add package to the database: %s" msgstr "" -#: src/error.c:146 +#: src/error.c:150 #, fuzzy msgid "package is already installed" msgstr "URL hostname is too large" -#: src/error.c:147 +#: src/error.c:151 #, fuzzy msgid "package is not installed" msgstr "URL hostname is too large" -#: src/error.c:148 +#: src/error.c:152 #, c-format msgid "failed to remove package file (%s): %s" msgstr "" -#: src/error.c:149 +#: src/error.c:153 #, c-format msgid "failed to remove package from the database: %s" msgstr "" -#: src/error.c:150 +#: src/error.c:154 #, c-format msgid "failed to remove package files from the database: %s" msgstr "" -#: src/error.c:151 +#: src/error.c:155 #, c-format msgid "failed to remove changes file for package: %s" msgstr "" -#: src/error.c:152 +#: src/error.c:156 msgid "failed to get current directory for running install" msgstr "" -#: src/error.c:153 +#: src/error.c:157 msgid "failed change directory to root for running install" msgstr "" -#: src/error.c:154 +#: src/error.c:158 msgid "failed run install spawn command" msgstr "" -#: src/error.c:156 +#: src/error.c:160 msgid "failed to change directory to old directory after running install" msgstr "" -#: src/error.c:157 +#: src/error.c:161 msgid "install script returned a bad status code" msgstr "" -#: src/error.c:158 +#: src/error.c:162 #, c-format msgid "failed to run the package install script: %s" msgstr "" -#: src/error.c:159 +#: src/error.c:163 #, c-format msgid "failed to save the package install script: %s" msgstr "" -#: src/error.c:160 +#: src/error.c:164 #, c-format msgid "removing package breaks %s" msgstr "" -#: src/error.c:161 +#: src/error.c:165 #, fuzzy msgid "package is already up-to-date" msgstr "URL hostname is too large" -#: src/error.c:162 +#: src/error.c:166 msgid "failed to open file for hashing" msgstr "" -#: src/error.c:163 +#: src/error.c:167 msgid "failed create digest for hashing" msgstr "" -#: src/error.c:164 +#: src/error.c:168 #, c-format msgid "failed to get hash of %s: %s" msgstr "" -#: src/error.c:165 +#: src/error.c:169 #, c-format msgid "file hash does not match for %s" msgstr "" -#: src/error.c:166 +#: src/error.c:170 #, fuzzy msgid "pool info is not loaded" msgstr "URL hostname is too large" -#: src/error.c:167 +#: src/error.c:171 msgid "pool list is empty" msgstr "" -#: src/error.c:168 +#: src/error.c:172 msgid "package changes file not found in the database" msgstr "" -#: src/error.c:169 +#: src/error.c:173 msgid "failed to change mod of the changes file" msgstr "" -#: src/error.c:170 +#: src/error.c:174 msgid "failed to create install script save directory" msgstr "" -#: src/error.c:171 +#: src/error.c:175 msgid "directory does not have read permissions" msgstr "" -#: src/error.c:172 +#: src/error.c:176 msgid "specified path is not a directory" msgstr "" -#: src/error.c:173 +#: src/error.c:177 msgid "failed to create the specified directory" msgstr "" -#: src/error.c:174 +#: src/error.c:178 msgid "specified list extraction directory is not accessible" msgstr "" -#: src/error.c:175 +#: src/error.c:179 #, c-format msgid "file does not exist: %s" msgstr "" -#: src/error.c:176 +#: src/error.c:180 #, c-format msgid "file is a symbolic link: %s" msgstr "" -#: src/error.c:177 -msgid "failed to set the package archive" -msgstr "" - -#: src/error.c:178 -#, c-format -msgid "failed change directory: %s" -msgstr "" - -#: src/error.c:179 -msgid "failed to change directory to root during extraction" -msgstr "" - -#: src/error.c:180 -msgid "failed to change directory back from root during extraction" -msgstr "" - #: src/error.c:181 -#, c-format -msgid "failed to accept the MPTP connection: %s" +msgid "failed to set the package archive" msgstr "" #: src/error.c:182 #, c-format -msgid "failed to listen the MPTP socket: %s" +msgid "failed change directory: %s" msgstr "" #: src/error.c:183 +msgid "failed to change directory to root during extraction" +msgstr "" + +#: src/error.c:184 +msgid "failed to change directory back from root during extraction" +msgstr "" + +#: src/error.c:185 +#, c-format +msgid "failed to accept the MPTP connection: %s" +msgstr "" + +#: src/error.c:186 +#, c-format +msgid "failed to listen the MPTP socket: %s" +msgstr "" + +#: src/error.c:187 #, c-format msgid "pool name (%s) doesn't match with: %s" msgstr "" -#: src/error.c:184 +#: src/error.c:188 #, c-format msgid "unknown key in the configuration: %s" msgstr "" diff --git a/src/ctx/sync.c b/src/ctx/sync.c index ccf3c8e..06434c9 100644 --- a/src/ctx/sync.c +++ b/src/ctx/sync.c @@ -25,7 +25,7 @@ bool __lm_ctx_sync_callback(char *path, size_t current, size_t total, void *data return cbdata->callback(cbdata->ctx, cbdata->pool, cbdata->state, current, total, data); } -size_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data){ +ssize_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data){ if(NULL == ctx) { lm_error_set(LM_ERR_ArgNULL); return -1; diff --git a/src/error.c b/src/error.c index 9f152d7..9de5cde 100644 --- a/src/error.c +++ b/src/error.c @@ -73,10 +73,14 @@ void lm_error_set(lm_error_t code, ...) { {.code = LM_ERR_ArcNextHeaderFail, .desc = _("failed to read the next header of the archive") }, {.code = LM_ERR_GetCwdFail, .desc = _("failed to obtain current working directory") }, {.code = LM_ERR_PoolListDirFail, .desc = _("failed to open extracted pool list directory") }, + {.code = LM_ERR_PoolListDataFail, .desc = _("failed to load \"%s\" data: %s") }, + {.code = LM_ERR_PoolListAddFail, .desc = _("failed add \"%s\" to the pool list: %s") }, {.code = LM_ERR_PoolListCantRead, .desc = _("failed to read access the pool list file") }, {.code = LM_ERR_PoolInfoCantRead, .desc = _("failed to read access the pool info file") }, {.code = LM_ERR_PkgDataBad, .desc = _("failed to parse package data") }, {.code = LM_ERR_PkgBadName, .desc = _("package name is invalid") }, + {.code = LM_ERR_PkgBadVersion, .desc = _("package version is invalid") }, + {.code = LM_ERR_PkgDataMissing, .desc = _("package data has missing field: %s") }, {.code = LM_ERR_CtxDataNULL, .desc = _("data path is not set with in the ctx") }, {.code = LM_ERR_CtxTempNULL, .desc = _("temp path is not set with in the ctx") }, {.code = LM_ERR_CtxRootNULL, .desc = _("root path is not set with in the ctx") }, diff --git a/src/package/data.c b/src/package/data.c index 1f71e7b..7bf9060 100644 --- a/src/package/data.c +++ b/src/package/data.c @@ -12,8 +12,10 @@ int lm_package_data_handler(void *_data, const char *_section, const char *_key, lm_pkg_data_t *data = _data; if(NULL == data->name){ - if(!package_name_valid(section)) + if(!package_name_valid(section)){ + lm_error_set(LM_ERR_PkgBadName); return 0; + } data->name = strdup(section); } @@ -24,8 +26,10 @@ int lm_package_data_handler(void *_data, const char *_section, const char *_key, data->desc = strdup(value); else if(eq(key, PKG_DATA_VERSION)){ - if(!package_version_valid(value)) + if(!package_version_valid(value)){ + lm_error_set(LM_ERR_PkgBadVersion); return 0; + } data->version = strdup(value); } @@ -47,13 +51,26 @@ int lm_package_data_handler(void *_data, const char *_section, const char *_key, bool lm_package_data_load(lm_pkg_data_t *data, char *file){ lm_package_data_free(data); + lm_error_clear(); if (ini_parse(file, lm_package_data_handler, data) < 0) { lm_error_set(LM_ERR_PkgDataBad); return false; } - return true; + if(LM_ERR_NoError != lm_error()) + return false; + + if(NULL == data->name) + lm_error_set(LM_ERR_PkgDataMissing, "name"); + else if(NULL == data->desc) + lm_error_set(LM_ERR_PkgDataMissing, "desc"); + else if(NULL == data->version) + lm_error_set(LM_ERR_PkgDataMissing, "version"); + else if(0 == data->size) + lm_error_set(LM_ERR_PkgDataMissing, "size"); + + return LM_ERR_NoError == lm_error(); } void lm_package_data_free(lm_pkg_data_t *data){ @@ -62,5 +79,5 @@ void lm_package_data_free(lm_pkg_data_t *data){ free(data->version); lm_package_data_depend_free(data); lm_package_data_keep_free(data); - bzero(&data, sizeof(lm_pkg_data_t)); + bzero(data, sizeof(lm_pkg_data_t)); } diff --git a/src/pool/list.c b/src/pool/list.c index e031404..050f87c 100644 --- a/src/pool/list.c +++ b/src/pool/list.c @@ -15,7 +15,7 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){ lm_error_set(LM_ERR_ArgNULL); return false; } - + lm_pool_list_free(pool); if(lm_pool_path_is_empty(pool)){ @@ -52,7 +52,7 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){ lm_error_set(LM_ERR_PoolListDirFail); goto end; } - + while((ent = readdir(dirfd)) != NULL){ if(eq(ent->d_name, "..") || eq(ent->d_name, ".")) continue; @@ -60,21 +60,29 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){ ent_len = strlen(ent->d_name); char datap[ent_len+list_dir_len+10]; join_multiple(datap, dir, ent->d_name, "DATA"); - + lm_pkg_t *pkg = lm_package_new(); - + if(!lm_package_data_load(&pkg->data, datap)){ - pdebug(__func__, "(%s) failed to load new package from %s", pool->name, datap); + pdebug(__func__, "(%s) failed to load new package from %s: %s", pool->name, datap, lm_strerror()); + if(NULL != pkg->data.name){ + char *suberr = lm_strerror_dup(); + lm_error_set(LM_ERR_PoolListDataFail, pkg->data.name, suberr); + free(suberr); + } lm_package_free(pkg); - continue; + goto end; } if(!lm_pool_package_add(pool, pkg)){ - pdebug(__func__, "(%s) failed to add new package: %s", pool->name, pkg->data.name); + pdebug(__func__, "(%s) failed to add package %s: %s", pool->name, pkg->data.name, lm_strerror()); + char *suberr = lm_strerror_dup(); + lm_error_set(LM_ERR_PoolListAddFail, pkg->data.name, suberr); + free(suberr); lm_package_free(pkg); - continue; + goto end; } - + pdebug(__func__, "(%s) added new package: %s", pool->name, pkg->data.name); } @@ -127,7 +135,7 @@ bool lm_pool_list_download(lm_pool_t *pool, char *dir, lm_mptp_transfer_callback pdebug(__func__, "list file request failed for %s: %s", pool->name, lm_strerror()); goto end; } - + if(!lm_mptp_recvfile(sock, pool->list_file, callback, data)){ pdebug(__func__, "recvfile failed for %s: %s", pool->name, lm_strerror()); goto end; diff --git a/src/util.c b/src/util.c index 27b5d94..dcd04bf 100644 --- a/src/util.c +++ b/src/util.c @@ -282,16 +282,8 @@ bool mkdir_ifnot(char *path, int mode) { return !(mkdir(path, mode) < 0 && errno != EEXIST); } -bool package_name_valid(char *name) { - for (char *c = name; *c != 0; c++) { - if (!is_digit(*c) && !is_letter(*c) && *c != '-' && *c != '.') - return false; - } - return true; -} - -bool package_version_valid(char *version) { - for (char *c = version; *c != 0; c++) { +bool __package_field_valid(char *field) { + for (char *c = field; *c != 0; c++) { if (!is_digit(*c) && !is_letter(*c) && *c != '-' && *c != '+' && *c != '.') return false; }