new: cleaning up functions, base implementation of install function

This commit is contained in:
ngn 2024-07-04 03:12:33 +03:00
parent 43cf7d26c8
commit 38b99eda79
25 changed files with 568 additions and 253 deletions

View File

@ -30,13 +30,8 @@ int main(int argc, char *argv[]) {
lm_ctx_pool_get_info(&ctx, true, true, NULL, NULL); lm_ctx_pool_get_info(&ctx, true, true, NULL, NULL);
lm_ctx_pool_get_list(&ctx, true, true, NULL, NULL); lm_ctx_pool_get_list(&ctx, true, true, NULL, NULL);
if (lm_ctx_package_get(&ctx, "which", NULL) == NULL) { if(!lm_ctx_install(&ctx, "which")){
printf("failed to get the package: %s (%d)\n", lm_strerror(), lm_error()); printf("failed to install the package: %s (%d)\n", lm_strerror(), lm_error());
goto end;
}
if (!lm_ctx_package_verify(&ctx, "which", NULL)) {
printf("failed to verify package: %s (%d)\n", lm_strerror(), lm_error());
goto end; goto end;
} }

View File

@ -3,7 +3,16 @@
#include "types.h" #include "types.h"
#include <stdbool.h> #include <stdbool.h>
typedef struct lm_ctx {
lm_pool_t *pools; // pool list
char *root; // root path for package installtion
char *temp; // temp path
char *data; // package database path
const char *version; // libmp version (read-only)
} lm_ctx_t;
typedef bool (*lm_ctx_pool_callback_t)(lm_ctx_t *ctx, lm_pool_t *pool, bool status, void *data); typedef bool (*lm_ctx_pool_callback_t)(lm_ctx_t *ctx, lm_pool_t *pool, bool status, void *data);
typedef bool (*lm_ctx_database_callback_t)(lm_ctx_t *ctx, lm_pkg_t *pkg, void *data);
void lm_ctx_init(lm_ctx_t *ctx); void lm_ctx_init(lm_ctx_t *ctx);
bool lm_ctx_set_data(lm_ctx_t *ctx, char *dir); bool lm_ctx_set_data(lm_ctx_t *ctx, char *dir);
@ -11,6 +20,12 @@ bool lm_ctx_set_root(lm_ctx_t *ctx, char *dir);
bool lm_ctx_set_temp(lm_ctx_t *ctx, char *dir); bool lm_ctx_set_temp(lm_ctx_t *ctx, char *dir);
void lm_ctx_free(lm_ctx_t *ctx); void lm_ctx_free(lm_ctx_t *ctx);
lm_pkg_t *lm_ctx_find(lm_ctx_t *ctx, char *name, char *version);
bool lm_ctx_install(lm_ctx_t *ctx, char *package);
bool lm_ctx_remove(lm_ctx_t *ctx, char *package);
bool lm_ctx_verify(lm_ctx_t *ctx, char *package);
bool lm_ctx_update(lm_ctx_t *ctx);
lm_pool_t *lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url); lm_pool_t *lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url);
bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name); bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name);
void lm_ctx_pool_clear(lm_ctx_t *ctx); void lm_ctx_pool_clear(lm_ctx_t *ctx);
@ -21,8 +36,11 @@ void lm_ctx_pool_get_info(
void lm_ctx_pool_get_list( void lm_ctx_pool_get_list(
lm_ctx_t *ctx, bool allow_update, bool force_update, lm_ctx_pool_callback_t callback, void *data); lm_ctx_t *ctx, bool allow_update, bool force_update, lm_ctx_pool_callback_t callback, void *data);
lm_pkg_t *lm_ctx_package_install(lm_ctx_t *ctx, char *name, char *version); bool lm_ctx_package_install(lm_ctx_t *ctx, lm_pkg_t *pkg);
lm_pkg_t *lm_ctx_package_get(lm_ctx_t *ctx, char *name, char *version); bool lm_ctx_package_remove(lm_ctx_t *ctx, lm_pkg_t *pkg);
bool lm_ctx_package_verify(lm_ctx_t *ctx, char *name, char *version); bool lm_ctx_package_verify(lm_ctx_t *ctx, lm_pkg_t *pkg);
lm_database_t *lm_ctx_database_new(lm_ctx_t *ctx); lm_database_t *lm_ctx_database_new(lm_ctx_t *ctx);
bool lm_ctx_database_is_installed(lm_ctx_t *ctx, lm_pkg_t *pkg, bool check_version);
bool lm_ctx_database_find(lm_ctx_t *ctx, lm_pkg_t *pkg, char *name);
bool lm_ctx_database_foreach(lm_ctx_t *ctx, lm_ctx_database_callback_t callback, void *data);

View File

@ -9,14 +9,16 @@ typedef enum lm_query_index {
QUERY_INSERT_PACKAGE = 1, QUERY_INSERT_PACKAGE = 1,
QUERY_SELECT_PACKAGE = 2, QUERY_SELECT_PACKAGE = 2,
QUERY_DELETE_PACKAGE = 3, QUERY_DELETE_PACKAGE = 3,
QUERY_ALL_PACKAGE = 4,
} lm_query_index_t; } lm_query_index_t;
extern char *queries[]; extern char *queries[];
typedef struct lm_database { typedef struct lm_database {
sqlite3_stmt *st;
sqlite3 *sql;
char *dir; char *dir;
lm_pkg_t *pkg; lm_pkg_t *pkg;
sqlite3 *sql;
} lm_database_t; } lm_database_t;
typedef bool (*lm_database_files_eachfunc_t)(lm_pkg_t *pkg, char *path, char *hash, void *data); typedef bool (*lm_database_files_eachfunc_t)(lm_pkg_t *pkg, char *path, char *hash, void *data);
@ -26,6 +28,7 @@ lm_database_t *lm_database_new(char *path);
void lm_database_free(lm_database_t *db); void lm_database_free(lm_database_t *db);
bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name); bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name);
bool lm_database_next(lm_database_t *db, lm_pkg_t *pkg);
bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg); bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg);
bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg); bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg);

View File

@ -91,6 +91,10 @@ typedef enum lm_error {
LM_ERR_DbKeepsDirFail = 86, LM_ERR_DbKeepsDirFail = 86,
LM_ERR_DbKeepsUnlinkFail = 87, LM_ERR_DbKeepsUnlinkFail = 87,
LM_ERR_DbSqlNotFound = 88, LM_ERR_DbSqlNotFound = 88,
LM_ERR_DependNotFound = 89,
LM_ERR_InstallDownloadFail = 90,
LM_ERR_PkgNotDownloaded = 91,
LM_ERR_PkgRemoveDownloadFail = 92,
} lm_error_t; } lm_error_t;
typedef struct lm_error_desc { typedef struct lm_error_desc {
@ -98,6 +102,7 @@ typedef struct lm_error_desc {
char *desc; char *desc;
} lm_error_desc_t; } lm_error_desc_t;
void lm_error_set(lm_error_t code); void lm_error_set(lm_error_t code, ...);
void lm_error_clear();
lm_error_t lm_error(); lm_error_t lm_error();
char *lm_strerror(); char *lm_strerror();

View File

@ -16,6 +16,7 @@ void lm_package_init(lm_pkg_t *pkg);
bool lm_package_data_load(lm_pkg_t *pkg, char *file); bool lm_package_data_load(lm_pkg_t *pkg, char *file);
void lm_package_data_free(lm_pkg_t *pkg); void lm_package_data_free(lm_pkg_t *pkg);
bool lm_package_downloaded(lm_pkg_t *pkg);
bool lm_package_depend_add(lm_pkg_t *pkg, char *depend); bool lm_package_depend_add(lm_pkg_t *pkg, char *depend);
size_t lm_package_depend_count(lm_pkg_t *pkg); size_t lm_package_depend_count(lm_pkg_t *pkg);
size_t lm_package_depend_strlen(lm_pkg_t *pkg); size_t lm_package_depend_strlen(lm_pkg_t *pkg);

View File

@ -21,19 +21,19 @@ void lm_pool_test(lm_pool_t *pool);
void lm_pool_free(lm_pool_t *pool); void lm_pool_free(lm_pool_t *pool);
lm_pkg_t *lm_pool_package_find(lm_pool_t *pool, char *name, char *version); lm_pkg_t *lm_pool_package_find(lm_pool_t *pool, char *name, char *version);
bool lm_pool_package_download(lm_pool_t *pool, lm_pkg_t *pkg);
bool lm_pool_package_add(lm_pool_t *pool, lm_pkg_t *pkg); bool lm_pool_package_add(lm_pool_t *pool, lm_pkg_t *pkg);
bool lm_pool_package_get(lm_pool_t *pool, lm_pkg_t *pkg);
bool lm_pool_path_set_dir(lm_pool_t *pool, char *dir); bool lm_pool_path_set_dir(lm_pool_t *pool, char *dir);
bool lm_pool_path_is_empty(lm_pool_t *pool); bool lm_pool_path_is_empty(lm_pool_t *pool);
void lm_pool_path_free(lm_pool_t *pool); void lm_pool_path_free(lm_pool_t *pool);
bool lm_pool_info_load(lm_pool_t *pool); bool lm_pool_info_load(lm_pool_t *pool);
bool lm_pool_info_get(lm_pool_t *pool); bool lm_pool_info_download(lm_pool_t *pool);
void lm_pool_info_free(lm_pool_t *pool); void lm_pool_info_free(lm_pool_t *pool);
bool lm_pool_list_load(lm_pool_t *pool); bool lm_pool_list_load(lm_pool_t *pool);
bool lm_pool_list_get(lm_pool_t *pool); bool lm_pool_list_download(lm_pool_t *pool);
void lm_pool_list_free(lm_pool_t *pool); void lm_pool_list_free(lm_pool_t *pool);
void lm_pool_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr); void lm_pool_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr);

View File

@ -16,6 +16,7 @@ typedef struct lm_pkg_path {
} lm_pkg_path_t; } lm_pkg_path_t;
typedef struct lm_pkg { typedef struct lm_pkg {
struct lm_pool *pool;
struct lm_pkg *next; struct lm_pkg *next;
lm_pkg_path_t paths; lm_pkg_path_t paths;
char *name; char *name;
@ -48,11 +49,3 @@ typedef struct lm_pool {
bool available; bool available;
char *name; char *name;
} lm_pool_t; } lm_pool_t;
typedef struct lm_ctx {
lm_pool_t *pools; // pool list
char *root; // root path for package installtion
char *temp; // temp path
char *data; // package database path
const char *version; // libmp version (read-only)
} lm_ctx_t;

View File

@ -34,3 +34,8 @@ void sockaddr_to_str(struct sockaddr *addr, char *str);
int join_multiple(char *res, const char *base, const char *pth, const char *pth2); int join_multiple(char *res, const char *base, const char *pth, const char *pth2);
int join(char *res, const char *base, const char *pth); int join(char *res, const char *base, const char *pth);
char *join_alloc(const char *base, const char *pth); char *join_alloc(const char *base, const char *pth);
bool pkglist_contains(lm_pkg_t *list, lm_pkg_t *pkg);
lm_pkg_t *pkglist_del(lm_pkg_t *list, lm_pkg_t *pkg);
lm_pkg_t *pkglist_add(lm_pkg_t *list, lm_pkg_t *pkg);
void pkglist_free(lm_pkg_t *list);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-03 03:40+0300\n" "POT-Creation-Date: 2024-07-04 03:04+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,370 +17,389 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: src/error.c:13 #: src/error.c:19
msgid "no error" msgid "no error"
msgstr "hata yok" msgstr "hata yok"
#: src/error.c:14 #: src/error.c:20
#, fuzzy #, fuzzy
msgid "URL contains an invalid character" msgid "URL contains an invalid character"
msgstr "URL contains an invalid char" msgstr "URL contains an invalid char"
#: src/error.c:15 #: src/error.c:21
msgid "URL does not have a valid protocol field" msgid "URL does not have a valid protocol field"
msgstr "URL does not have a valid protocol field" msgstr "URL does not have a valid protocol field"
#: src/error.c:16 #: src/error.c:22
msgid "URL is too large" msgid "URL is too large"
msgstr "URL is too large" msgstr "URL is too large"
#: src/error.c:17 #: src/error.c:23
msgid "URL hostname is too large" msgid "URL hostname is too large"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:18 #: src/error.c:24
msgid "URL path is too large" msgid "URL path is too large"
msgstr "URL path is too large" msgstr "URL path is too large"
#: src/error.c:19 #: src/error.c:25
msgid "URL does not have a valid hostname" msgid "URL does not have a valid hostname"
msgstr "URL does not have a valid hostname" msgstr "URL does not have a valid hostname"
#: src/error.c:20 #: src/error.c:26
#, fuzzy #, fuzzy
msgid "URL does not have a valid port number" msgid "URL does not have a valid port number"
msgstr "URL does not have a valid hostname" msgstr "URL does not have a valid hostname"
#: src/error.c:21 #: src/error.c:27
msgid "URL does not have a valid path" msgid "URL does not have a valid path"
msgstr "URL does not have a valid path" msgstr "URL does not have a valid path"
#: src/error.c:22 #: src/error.c:28
#, fuzzy #, fuzzy
msgid "hostname does not contain a valid port number" msgid "hostname does not contain a valid port number"
msgstr "URL does not contain a hostname with a valid port number" msgstr "URL does not contain a hostname with a valid port number"
#: src/error.c:23 #: src/error.c:29
#, fuzzy #, fuzzy
msgid "hostname is not valid" msgid "hostname is not valid"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:24 #: src/error.c:30
msgid "URL protocol port number is unknown" msgid "URL protocol port number is unknown"
msgstr "URL protocol port number is unknown" msgstr "URL protocol port number is unknown"
#: src/error.c:25 #: src/error.c:31
msgid "URL is incomplete" msgid "URL is incomplete"
msgstr "URL tamamlanmamış" msgstr "URL tamamlanmamış"
#: src/error.c:26 #: src/error.c:32
msgid "pool does not support the specified protocol" msgid "pool does not support the specified protocol"
msgstr "pool does not support the specified protocol" msgstr "pool does not support the specified protocol"
#: src/error.c:27 #: src/error.c:33
msgid "unsupported MPTP version" msgid "unsupported MPTP version"
msgstr "" msgstr ""
#: src/error.c:28 #: src/error.c:34
msgid "invalid MPTP request/response code" msgid "invalid MPTP request/response code"
msgstr "" msgstr ""
#: src/error.c:29 #: src/error.c:35
msgid "invalid MPTP URL" msgid "invalid MPTP URL"
msgstr "" msgstr ""
#: src/error.c:30 #: src/error.c:36
msgid "failed to resolve hostname for MPTP connection" msgid "failed to resolve hostname for MPTP connection"
msgstr "" msgstr ""
#: src/error.c:31 #: src/error.c:37
msgid "failed to create a MPTP socket" msgid "failed to create a MPTP socket"
msgstr "" msgstr ""
#: src/error.c:32 #: src/error.c:38
msgid "failed to connect to the MPTP host" msgid "failed to connect to the MPTP host"
msgstr "" msgstr ""
#: src/error.c:33 #: src/error.c:39
msgid "failed receive MPTP data from host" msgid "failed receive MPTP data from host"
msgstr "" msgstr ""
#: src/error.c:34 #: src/error.c:40
msgid "failed send MPTP data to host" msgid "failed send MPTP data to host"
msgstr "" msgstr ""
#: src/error.c:35 #: src/error.c:41
#, fuzzy #, fuzzy
msgid "MPTP data size is invalid" msgid "MPTP data size is invalid"
msgstr "URL path is too large" msgstr "URL path is too large"
#: src/error.c:36 #: src/error.c:42
#, fuzzy #, fuzzy
msgid "MPTP host size is invalid" msgid "MPTP host size is invalid"
msgstr "URL path is too large" msgstr "URL path is too large"
#: src/error.c:37 #: src/error.c:43
msgid "failed to set MPTP socket options" msgid "failed to set MPTP socket options"
msgstr "" msgstr ""
#: src/error.c:38 #: src/error.c:44
msgid "MPTP connection timed out" msgid "MPTP connection timed out"
msgstr "" msgstr ""
#: src/error.c:39 #: src/error.c:45
msgid "failed to bind MPTP socket" msgid "failed to bind MPTP socket"
msgstr "" msgstr ""
#: src/error.c:40 #: src/error.c:46
msgid "required argument is a NULL pointer or 0" msgid "required argument is a NULL pointer or 0"
msgstr "" msgstr ""
#: src/error.c:41 #: src/error.c:47
msgid "not a MPTP request" msgid "not a MPTP request"
msgstr "" msgstr ""
#: src/error.c:42 #: src/error.c:48
msgid "not a MPTP response" msgid "not a MPTP response"
msgstr "" msgstr ""
#: src/error.c:43 #: src/error.c:49
msgid "MPTP request last flag is not set" msgid "MPTP request last flag is not set"
msgstr "" msgstr ""
#: src/error.c:44 #: src/error.c:50
msgid "host port not specified" msgid "host port not specified"
msgstr "" msgstr ""
#: src/error.c:45 #: src/error.c:51
msgid "pool info is badly formatted or is not complete" msgid "pool info is badly formatted or is not complete"
msgstr "" msgstr ""
#: src/error.c:46 #: src/error.c:52
msgid "failed to write block from archive" msgid "failed to write block from archive"
msgstr "" msgstr ""
#: src/error.c:47 #: src/error.c:53
msgid "failed to read block from archive" msgid "failed to read block from archive"
msgstr "" msgstr ""
#: src/error.c:48 #: src/error.c:54
msgid "failed to open archive" msgid "failed to open archive"
msgstr "" msgstr ""
#: src/error.c:49 #: src/error.c:55
msgid "failed to write archive header" msgid "failed to write archive header"
msgstr "" msgstr ""
#: src/error.c:50 #: src/error.c:56
msgid "failed to finish writing the archive entry" msgid "failed to finish writing the archive entry"
msgstr "" msgstr ""
#: src/error.c:51 #: src/error.c:57
msgid "failed to create new archive reader/writer" msgid "failed to create new archive reader/writer"
msgstr "" msgstr ""
#: src/error.c:52 #: src/error.c:58
msgid "failed to resolve full path for archive file" msgid "failed to resolve full path for archive file"
msgstr "" msgstr ""
#: src/error.c:53 #: src/error.c:59
msgid "failed to read the next header of the archive" msgid "failed to read the next header of the archive"
msgstr "" msgstr ""
#: src/error.c:54 #: src/error.c:60
msgid "failed to obtain current working directory" msgid "failed to obtain current working directory"
msgstr "" msgstr ""
#: src/error.c:55 #: src/error.c:61
msgid "failed to open extracted pool list directory" msgid "failed to open extracted pool list directory"
msgstr "" msgstr ""
#: src/error.c:56 #: src/error.c:62
msgid "failed to read access the pool list file" msgid "failed to read access the pool list file"
msgstr "" msgstr ""
#: src/error.c:57 #: src/error.c:63
msgid "failed to read access the pool info file" msgid "failed to read access the pool info file"
msgstr "" msgstr ""
#: src/error.c:58 #: src/error.c:64
msgid "failed to parse package data" msgid "failed to parse package data"
msgstr "" msgstr ""
#: src/error.c:59 #: src/error.c:65
#, fuzzy #, fuzzy
msgid "package name is invalid" msgid "package name is invalid"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:60 #: src/error.c:66
msgid "data path is not set with in the ctx" msgid "data path is not set with in the ctx"
msgstr "" msgstr ""
#: src/error.c:61 #: src/error.c:67
msgid "specified temp path does not exist" msgid "specified temp path does not exist"
msgstr "" msgstr ""
#: src/error.c:62 #: src/error.c:68
msgid "specified temp path is not a directory" msgid "specified temp path is not a directory"
msgstr "" msgstr ""
#: src/error.c:63 #: src/error.c:69
msgid "specified temp directory does not have write access" msgid "specified temp directory does not have write access"
msgstr "" msgstr ""
#: src/error.c:64 #: src/error.c:70
msgid "specified root path does not exist" msgid "specified root path does not exist"
msgstr "" msgstr ""
#: src/error.c:65 #: src/error.c:71
msgid "specified root path is not a directory" msgid "specified root path is not a directory"
msgstr "" msgstr ""
#: src/error.c:66 #: src/error.c:72
msgid "specified root directory does not have write access" msgid "specified root directory does not have write access"
msgstr "" msgstr ""
#: src/error.c:67 #: src/error.c:73
msgid "specified data path does not exist" msgid "specified data path does not exist"
msgstr "" msgstr ""
#: src/error.c:68 #: src/error.c:74
msgid "specified data path is not a directory" msgid "specified data path is not a directory"
msgstr "" msgstr ""
#: src/error.c:69 #: src/error.c:75
msgid "failed to create specified data directory" msgid "failed to create specified data directory"
msgstr "" msgstr ""
#: src/error.c:70 #: src/error.c:76
msgid "pool did not respond ping with pong" msgid "pool did not respond ping with pong"
msgstr "" msgstr ""
#: src/error.c:71 #: src/error.c:77
msgid "package file and directory paths are empty" msgid "package file and directory paths are empty"
msgstr "" msgstr ""
#: src/error.c:72 #: src/error.c:78
msgid "failed to to open target file for sending" msgid "failed to to open target file for sending"
msgstr "" msgstr ""
#: src/error.c:73 #: src/error.c:79
msgid "failed to to delete target file for receiving" msgid "failed to to delete target file for receiving"
msgstr "" msgstr ""
#: src/error.c:74 #: src/error.c:80
msgid "failed to to open target file for receiving" msgid "failed to to open target file for receiving"
msgstr "" msgstr ""
#: src/error.c:75 #: src/error.c:81
msgid "got a bad response code for receiving the target file" msgid "got a bad response code for receiving the target file"
msgstr "" msgstr ""
#: src/error.c:76 #: src/error.c:82
msgid "failed to write to the target file for receiving" msgid "failed to write to the target file for receiving"
msgstr "" msgstr ""
#: src/error.c:77 #: src/error.c:83
#, fuzzy #, fuzzy
msgid "package not found" msgid "package not found"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:78 #: src/error.c:84
msgid "failed to access to the database file/directory" msgid "failed to access to the database file/directory"
msgstr "" msgstr ""
#: src/error.c:79 #: src/error.c:85
msgid "failed to open SQLite database" msgid "failed to open SQLite database"
msgstr "" msgstr ""
#: src/error.c:80 #: src/error.c:86
msgid "failed to create table in SQLite database" msgid "failed to create table in SQLite database"
msgstr "" msgstr ""
#: src/error.c:81 #: src/error.c:87
msgid "failed to prepare statement for SQLite database" msgid "failed to prepare statement for SQLite database"
msgstr "" msgstr ""
#: src/error.c:82 #: src/error.c:88
msgid "failed to insert to the table in SQLite database" msgid "failed to insert to the table in SQLite database"
msgstr "" msgstr ""
#: src/error.c:83 #: src/error.c:89
msgid "failed to find entry in SQLite database" msgid "failed to find entry in SQLite database"
msgstr "" msgstr ""
#: src/error.c:84 #: src/error.c:90
msgid "failed to init GPG for package verification" msgid "failed to init GPG for package verification"
msgstr "" msgstr ""
#: src/error.c:85 #: src/error.c:91
msgid "failed to import signature to GPG for package verification" msgid "failed to import signature to GPG for package verification"
msgstr "" msgstr ""
#: src/error.c:86 #: src/error.c:92
msgid "failed to import archive to GPG for package verification" msgid "failed to import archive to GPG for package verification"
msgstr "" msgstr ""
#: src/error.c:87 #: src/error.c:93
msgid "package signature verification failed with zero matches" msgid "package signature verification failed with zero matches"
msgstr "" msgstr ""
#: src/error.c:88 #: src/error.c:94
msgid "package signature verification failed with zero results" msgid "package signature verification failed with zero results"
msgstr "" msgstr ""
#: src/error.c:89 #: src/error.c:95
msgid "pool file and directory paths are empty" msgid "pool file and directory paths are empty"
msgstr "" msgstr ""
#: src/error.c:90 #: src/error.c:96
msgid "pool is not avaliable for connection" msgid "pool is not avaliable for connection"
msgstr "" msgstr ""
#: src/error.c:91 #: src/error.c:97
msgid "pool URL is empty or invalid" msgid "pool URL is empty or invalid"
msgstr "" msgstr ""
#: src/error.c:92 #: src/error.c:98
msgid "pool directory path is not accessible" msgid "pool directory path is not accessible"
msgstr "" msgstr ""
#: src/error.c:93 #: src/error.c:99
msgid "pool directory sub-paths are not accessible" msgid "pool directory sub-paths are not accessible"
msgstr "" msgstr ""
#: src/error.c:94 #: src/error.c:100
msgid "package file list not found in the database" msgid "package file list not found in the database"
msgstr "" msgstr ""
#: src/error.c:95 #: src/error.c:101
msgid "failed to open package file list in the database" msgid "failed to open package file list in the database"
msgstr "" msgstr ""
#: src/error.c:96 #: src/error.c:102
msgid "failed to access package file list database directory" msgid "failed to access package file list database directory"
msgstr "" msgstr ""
#: src/error.c:97 #: src/error.c:103
msgid "failed to remove package file list from the database" msgid "failed to remove package file list from the database"
msgstr "" msgstr ""
#: src/error.c:98 #: src/error.c:104
msgid "failed to write to the file list in the database" msgid "failed to write to the file list in the database"
msgstr "" msgstr ""
#: src/error.c:99 #: src/error.c:105
msgid "package keep list not found in the database" msgid "package keep list not found in the database"
msgstr "" msgstr ""
#: src/error.c:100 #: src/error.c:106
msgid "failed to open package keep list in the database" msgid "failed to open package keep list in the database"
msgstr "" msgstr ""
#: src/error.c:101 #: src/error.c:107
msgid "failed to access package keep list database directory" msgid "failed to access package keep list database directory"
msgstr "" msgstr ""
#: src/error.c:102 #: src/error.c:108
msgid "failed to remove package keep list from the database" msgid "failed to remove package keep list from the database"
msgstr "" msgstr ""
#: src/error.c:109
#, c-format
msgid "failed to find %s (dependency of %s)"
msgstr ""
#: src/error.c:110
#, c-format
msgid "failed to download %s for installation: %s"
msgstr ""
#: src/error.c:111
#, fuzzy
msgid "package is not downloaded"
msgstr "URL hostname is too large"
#: src/error.c:112
msgid "failed to remove downloaded package"
msgstr ""

View File

@ -14,6 +14,8 @@ void lm_ctx_init(lm_ctx_t *ctx) {
bzero(ctx, sizeof(lm_ctx_t)); bzero(ctx, sizeof(lm_ctx_t));
ctx->version = LM_VERSION; ctx->version = LM_VERSION;
lm_error_clear();
} }
bool lm_ctx_set_temp(lm_ctx_t *ctx, char *dir){ bool lm_ctx_set_temp(lm_ctx_t *ctx, char *dir){
@ -81,5 +83,7 @@ void lm_ctx_free(lm_ctx_t *ctx) {
free(ctx->data); free(ctx->data);
free(ctx->root); free(ctx->root);
free(ctx->temp); free(ctx->temp);
lm_error_clear();
return; return;
} }

View File

@ -1,4 +1,5 @@
#include "../../include/database.h" #include "../../include/database.h"
#include "../../include/error.h"
#include "../../include/util.h" #include "../../include/util.h"
#include "../../include/ctx.h" #include "../../include/ctx.h"
@ -9,3 +10,52 @@ lm_database_t *lm_ctx_database_new(lm_ctx_t *ctx){
join(dbpath, ctx->data, "db"); join(dbpath, ctx->data, "db");
return lm_database_new(dbpath); return lm_database_new(dbpath);
} }
bool lm_ctx_database_is_installed(lm_ctx_t *ctx, lm_pkg_t *pkg, bool check_version){
lm_database_t *db = lm_ctx_database_new(ctx);
lm_pkg_t found;
bool ret = false;
if(NULL == db)
return false;
if(!lm_database_find(db, &found, pkg->name))
goto end;
if(check_version && !eq(found.version, pkg->version))
goto end;
ret = true;
end:
lm_database_free(db);
return ret;
}
bool lm_ctx_database_find(lm_ctx_t *ctx, lm_pkg_t *pkg, char *name){
if(NULL == ctx || NULL == pkg || NULL == name){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
lm_database_t *db = lm_ctx_database_new(ctx);
if(!lm_database_find(db, pkg, name))
return false;
return true;
}
bool lm_ctx_database_foreach(lm_ctx_t *ctx, lm_ctx_database_callback_t callback, void *data){
if(NULL == ctx || NULL == callback){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
lm_database_t *db = lm_ctx_database_new(ctx);
lm_pkg_t pkg;
while(lm_database_next(db, &pkg)){
if(!callback(ctx, &pkg, data))
break;
}
return true;
}

22
src/ctx/find.c Normal file
View File

@ -0,0 +1,22 @@
#include "../../include/error.h"
#include "../../include/pool.h"
#include "../../include/ctx.h"
lm_pkg_t *lm_ctx_find(lm_ctx_t *ctx, char *name, char *version){
if(NULL == ctx || (NULL == name && NULL == version)){
lm_error_set(LM_ERR_ArgNULL);
return NULL;
}
lm_pool_t *cur = ctx->pools;
lm_pkg_t *found = NULL;
while(cur != NULL){
if((found = lm_pool_package_find(cur, name, version)) != NULL)
break;
cur = cur->next;
}
if(NULL == found)
lm_error_set(LM_ERR_PkgNotFound);
return found;
}

88
src/ctx/install.c Normal file
View File

@ -0,0 +1,88 @@
#include "../../include/package.h"
#include "../../include/error.h"
#include "../../include/pool.h"
#include "../../include/util.h"
#include "../../include/ctx.h"
#include <stdlib.h>
#include <string.h>
typedef struct install_list {
lm_pkg_t *packages;
lm_pkg_t *resolving;
size_t count;
} install_list_t;
bool install_resolve(lm_ctx_t *ctx, install_list_t *list, lm_pkg_t *pkg){
if(pkglist_contains(list->packages, pkg))
return true;
if(NULL == pkg->depends)
goto end;
list->resolving = pkglist_add(list->resolving, pkg);
for(int i = 0; pkg->depends[i] != NULL; i++){
lm_pkg_t *depend = lm_ctx_find(ctx, pkg->depends[i], NULL);
if(NULL == depend){
lm_error_set(LM_ERR_DependNotFound, pkg->depends[i], pkg->name);
return false;
}
if(lm_ctx_database_is_installed(ctx, depend, true))
continue;
if(pkglist_contains(list->resolving, depend)){
lm_error_set(LM_ERR_DependNotFound, pkg->depends[i], pkg->name);
return false;
}
if(!install_resolve(ctx, list, pkg))
return false;
}
list->resolving = pkglist_del(list->resolving, pkg);
end:
list->packages = pkglist_add(list->packages, pkg);
list->count++;
return true;
}
bool lm_ctx_install(lm_ctx_t *ctx, char *package){
lm_pkg_t *pkg = lm_ctx_find(ctx, package, NULL);
install_list_t list = {
.packages = NULL,
.resolving = NULL,
.count = 0,
};
bool ret = false;
if(NULL == pkg)
return ret;
if(!install_resolve(ctx, &list, pkg))
goto end;
pkg = list.packages;
while(pkg != NULL){
if(lm_package_downloaded(pkg) && lm_package_verify(pkg))
continue;
if(!lm_pool_package_download(pkg->pool, pkg)){
char *suberror = strdup(lm_strerror());
lm_error_set(LM_ERR_InstallDownloadFail, pkg->name, suberror);
free(suberror);
return false;
}
pkg = pkg->next;
}
// actually install packages
end:
pkglist_free(list.packages);
pkglist_free(list.resolving);
return true;
}

View File

@ -1,62 +1,18 @@
#include "../../include/ctx.h"
#include "../../include/pool.h" #include "../../include/pool.h"
#include "../../include/package.h" #include "../../include/package.h"
#include "../../include/database.h" #include "../../include/database.h"
#include "../../include/util.h" #include "../../include/util.h"
#include "../../include/error.h" #include "../../include/error.h"
#include "../../include/ctx.h"
lm_pkg_t *lm_ctx_package_get(lm_ctx_t *ctx, char *name, char *version) { bool lm_ctx_package_install(lm_ctx_t *ctx, lm_pkg_t *pkg){
lm_pool_t *pool = ctx->pools; return true;
lm_pkg_t *pkg = NULL;
while (NULL != pool) {
if((pkg = lm_pool_package_find(pool, name, version)) != NULL)
break;
pool = pool->next;
} }
if(NULL == pool && NULL == pkg){ bool lm_ctx_package_remove(lm_ctx_t *ctx, lm_pkg_t *pkg){
lm_error_set(LM_ERR_PkgNotFound); return true;
return NULL;
} }
if(!lm_pool_package_get(pool, pkg)) bool lm_ctx_package_verify(lm_ctx_t *ctx, lm_pkg_t *pkg){
return NULL; return true;
return pkg;
}
bool lm_ctx_package_verify(lm_ctx_t *ctx, char *name, char *version) {
lm_pool_t *pool = ctx->pools;
lm_pkg_t *pkg = NULL;
while (NULL != pool) {
if((pkg = lm_pool_package_find(pool, name, version)) != NULL)
break;
pool = pool->next;
}
if(NULL == pool && NULL == pkg){
lm_error_set(LM_ERR_PkgNotFound);
return NULL;
}
return lm_package_verify(pkg);
}
bool lm_ctx_package_is_installed(lm_ctx_t *ctx, char *name, char *version) {
lm_database_t *db = lm_ctx_database_new(ctx);
if(NULL == db)
return false;
bool ret = lm_database_find(db, NULL, name);
lm_database_free(db);
return ret;
}
lm_pkg_t *lm_ctx_package_install(lm_ctx_t *ctx, char *name, char *version){
return NULL;
} }

View File

@ -43,27 +43,13 @@ lm_pool_t *lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url) {
} }
} }
if (NULL == ctx->pools) { // add to the start
pool->next = ctx->pools;
ctx->pools = pool; ctx->pools = pool;
return pool; return pool;
} }
lm_pool_t *cur = ctx->pools;
while (NULL != cur) {
if (NULL == cur->next) {
cur->next = pool;
return pool;
}
cur = cur->next;
}
// if we somehow get here, something very wrong has happend
assert(true);
lm_pool_free(pool);
return NULL;
}
void lm_ctx_pool_clear(lm_ctx_t *ctx) { void lm_ctx_pool_clear(lm_ctx_t *ctx) {
lm_pool_t *cur = ctx->pools, *prev = NULL; lm_pool_t *cur = ctx->pools, *prev = NULL;
while (NULL != cur) { while (NULL != cur) {
@ -134,7 +120,7 @@ void lm_ctx_pool_get_info(lm_ctx_t *ctx, bool allow_update, bool force_update, l
goto success; goto success;
update: update:
if(!lm_pool_info_get(cur)){ if(!lm_pool_info_download(cur)){
pdebug(__func__, "(%s) failed to update info: %s", cur->name, lm_strerror()); pdebug(__func__, "(%s) failed to update info: %s", cur->name, lm_strerror());
goto next; goto next;
} }
@ -174,7 +160,7 @@ void lm_ctx_pool_get_list(lm_ctx_t *ctx, bool allow_update, bool force_update, l
goto success; goto success;
update: update:
if(!lm_pool_list_get(cur)){ if(!lm_pool_list_download(cur)){
pdebug(__func__, "(%s) failed to update list: %s", cur->name, lm_strerror()); pdebug(__func__, "(%s) failed to update list: %s", cur->name, lm_strerror());
goto next; goto next;
} }
@ -244,7 +230,7 @@ bool lm_ctx_pool_serve(lm_ctx_t *ctx, char *addr, uint8_t threads) {
lm_pool_t *pool = lm_ctx_pool_by_url(ctx, hostname, ppath); lm_pool_t *pool = lm_ctx_pool_by_url(ctx, hostname, ppath);
if (NULL == pool) { if (NULL == pool) {
pdebug(__func__, "unknown pool (%s) closing connection", hostname); pdebug(__func__, "unknown pool (%s), closing connection", hostname);
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true); lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(sock, &packet, &saddr); lm_mptp_server_send(sock, &packet, &saddr);
continue; continue;

View File

@ -18,6 +18,7 @@ char *queries[] = {
"INSERT INTO packages VALUES (?, ?, ?, ?, ?)", "INSERT INTO packages VALUES (?, ?, ?, ?, ?)",
"SELECT * FROM packages WHERE name = '?'", "SELECT * FROM packages WHERE name = '?'",
"DELETE from packages WHERE name = '?'", "DELETE from packages WHERE name = '?'",
"SELECT * FROM packages",
}; };
lm_database_t *lm_database_new(char *path){ lm_database_t *lm_database_new(char *path){
@ -50,6 +51,9 @@ lm_database_t *lm_database_new(char *path){
} }
void lm_database_free(lm_database_t *db){ void lm_database_free(lm_database_t *db){
if(NULL != db->st)
sqlite3_finalize(db->st);
sqlite3_close(db->sql); sqlite3_close(db->sql);
free(db->dir); free(db->dir);

View File

@ -15,27 +15,26 @@ bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg){
} }
char depends[lm_package_depend_strlen(pkg)]; char depends[lm_package_depend_strlen(pkg)];
sqlite3_stmt *st = NULL;
bool ret = false; bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_INSERT_PACKAGE], strlen(queries[QUERY_INSERT_PACKAGE]), &st, NULL) != SQLITE_OK){ if(sqlite3_prepare(db->sql, queries[QUERY_INSERT_PACKAGE], strlen(queries[QUERY_INSERT_PACKAGE]), &db->st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for inserting %s: %s", pkg->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to prepare statement for inserting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlPrepareFail); lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end; goto end;
} }
sqlite3_bind_text(st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC); sqlite3_bind_text(db->st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC);
sqlite3_bind_text(st, 2, pkg->desc, strlen(pkg->desc), SQLITE_STATIC); sqlite3_bind_text(db->st, 2, pkg->desc, strlen(pkg->desc), SQLITE_STATIC);
sqlite3_bind_text(st, 3, pkg->version, strlen(pkg->version), SQLITE_STATIC); sqlite3_bind_text(db->st, 3, pkg->version, strlen(pkg->version), SQLITE_STATIC);
sqlite3_bind_int64(st, 4, pkg->size); sqlite3_bind_int64(db->st, 4, pkg->size);
if(!lm_package_depend_tostr(pkg, depends)){ if(!lm_package_depend_tostr(pkg, depends)){
pdebug(__func__, "failed to convert depends to string for inserting %s: %s", pkg->name, lm_strerror()); pdebug(__func__, "failed to convert depends to string for inserting %s: %s", pkg->name, lm_strerror());
goto end; goto end;
} }
sqlite3_bind_text(st, 5, depends, strlen(depends), SQLITE_STATIC); sqlite3_bind_text(db->st, 5, depends, strlen(depends), SQLITE_STATIC);
if(sqlite3_step(st) != SQLITE_DONE){ if(sqlite3_step(db->st) != SQLITE_DONE){
pdebug(__func__, "failed to execute insert statement for inserting %s: %s", pkg->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to execute insert statement for inserting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlInsertFail); lm_error_set(LM_ERR_DbSqlInsertFail);
goto end; goto end;
@ -43,8 +42,10 @@ bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg){
ret = true; ret = true;
end: end:
if(NULL != st) if(NULL != db->st){
sqlite3_finalize(st); sqlite3_finalize(db->st);
db->st = NULL;
}
return ret; return ret;
} }
@ -54,18 +55,17 @@ bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){
return false; return false;
} }
sqlite3_stmt *st;
bool ret = false; bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_SELECT_PACKAGE], strlen(queries[QUERY_SELECT_PACKAGE]), &st, NULL) != SQLITE_OK){ if(sqlite3_prepare(db->sql, queries[QUERY_SELECT_PACKAGE], strlen(queries[QUERY_SELECT_PACKAGE]), &db->st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for finding %s: %s", name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to prepare statement for finding %s: %s", name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlPrepareFail); lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end; goto end;
} }
sqlite3_bind_text(st, 1, name, strlen(name), SQLITE_STATIC); sqlite3_bind_text(db->st, 1, name, strlen(name), SQLITE_STATIC);
if(sqlite3_step(st) != SQLITE_ROW){ if(sqlite3_step(db->st) != SQLITE_ROW){
pdebug(__func__, "got no rows for %s", name); pdebug(__func__, "got no rows for %s", name);
lm_error_set(LM_ERR_DbSqlNotFound); lm_error_set(LM_ERR_DbSqlNotFound);
goto end; goto end;
@ -80,12 +80,12 @@ bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){
// we are initing it just in case the caller didn't // we are initing it just in case the caller didn't
lm_package_init(pkg); lm_package_init(pkg);
pkg->name = strdup((char*)sqlite3_column_text(st, 0)); pkg->name = strdup((char*)sqlite3_column_text(db->st, 0));
pkg->desc = strdup((char*)sqlite3_column_text(st, 1)); pkg->desc = strdup((char*)sqlite3_column_text(db->st, 1));
pkg->version = strdup((char*)sqlite3_column_text(st, 2)); pkg->version = strdup((char*)sqlite3_column_text(db->st, 2));
pkg->size = sqlite3_column_int64(st, 3); pkg->size = sqlite3_column_int64(db->st, 3);
char *depends = (char*)sqlite3_column_text(st, 3); char *depends = (char*)sqlite3_column_text(db->st, 3);
if(!lm_package_depend_fromstr(pkg, depends)){ if(!lm_package_depend_fromstr(pkg, depends)){
pdebug(__func__, "failed to load depends for finding %s: %s", pkg->name, lm_strerror()); pdebug(__func__, "failed to load depends for finding %s: %s", pkg->name, lm_strerror());
// error is set by the function // error is set by the function
@ -94,8 +94,10 @@ bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){
ret = true; ret = true;
end: end:
if(NULL != st) if(NULL != db->st){
sqlite3_finalize(st); sqlite3_finalize(db->st);
db->st = NULL;
}
return ret; return ret;
} }
@ -105,18 +107,17 @@ bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg){
return false; return false;
} }
sqlite3_stmt *st;
bool ret = false; bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_DELETE_PACKAGE], strlen(queries[QUERY_DELETE_PACKAGE]), &st, NULL) != SQLITE_OK){ if(sqlite3_prepare(db->sql, queries[QUERY_DELETE_PACKAGE], strlen(queries[QUERY_DELETE_PACKAGE]), &db->st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to prepare statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlPrepareFail); lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end; goto end;
} }
sqlite3_bind_text(st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC); sqlite3_bind_text(db->st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC);
if(sqlite3_step(st) != SQLITE_DONE){ if(sqlite3_step(db->st) != SQLITE_DONE){
pdebug(__func__, "failed to execute delete statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to execute delete statement for deleting %s: %s", pkg->name, sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlInsertFail); lm_error_set(LM_ERR_DbSqlInsertFail);
goto end; goto end;
@ -124,7 +125,50 @@ bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg){
ret = true; ret = true;
end: end:
if(NULL != st) if(NULL != db->st){
sqlite3_finalize(st); sqlite3_finalize(db->st);
db->st = NULL;
}
return ret; return ret;
} }
bool lm_database_next(lm_database_t *db, lm_pkg_t *pkg){
if(NULL == db || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
if(NULL == db->st){
if(sqlite3_prepare(db->sql, queries[QUERY_ALL_PACKAGE], strlen(queries[QUERY_ALL_PACKAGE]), &db->st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for selecting all: %s", sqlite3_errmsg(db->sql));
lm_error_set(LM_ERR_DbSqlPrepareFail);
return false;
}
}
else
lm_package_free(pkg);
if(sqlite3_step(db->st) != SQLITE_ROW){
sqlite3_finalize(db->st);
db->st = NULL;
return false;
}
lm_package_init(pkg);
pkg->name = strdup((char*)sqlite3_column_text(db->st, 0));
pkg->desc = strdup((char*)sqlite3_column_text(db->st, 1));
pkg->version = strdup((char*)sqlite3_column_text(db->st, 2));
pkg->size = sqlite3_column_int64(db->st, 3);
char *depends = (char*)sqlite3_column_text(db->st, 3);
if(!lm_package_depend_fromstr(pkg, depends)){
pdebug(__func__, "failed to load depends for finding %s: %s", pkg->name, lm_strerror());
sqlite3_finalize(db->st);
return false;
}
return true;
}

View File

@ -1,14 +1,20 @@
#include "../include/error.h" #include "../include/error.h"
#include "../include/util.h" #include "../include/util.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
lm_error_t error = LM_ERR_NoError; lm_error_t error = LM_ERR_NoError;
char *error_str = NULL;
void lm_error_set(lm_error_t code) { void lm_error_clear() {
error = code; free(error_str);
error = LM_ERR_NoError;
error_str = NULL;
} }
char *lm_strerror() { void lm_error_set(lm_error_t code, ...) {
lm_error_desc_t errors[] = { lm_error_desc_t errors[] = {
{.code = LM_ERR_NoError, .desc = _("no error") }, {.code = LM_ERR_NoError, .desc = _("no error") },
{.code = LM_ERR_URLBadChar, .desc = _("URL contains an invalid character") }, {.code = LM_ERR_URLBadChar, .desc = _("URL contains an invalid character") },
@ -100,13 +106,44 @@ char *lm_strerror() {
{.code = LM_ERR_DbKeepsOpenFail, .desc = _("failed to open package keep list in the database") }, {.code = LM_ERR_DbKeepsOpenFail, .desc = _("failed to open package keep list in the database") },
{.code = LM_ERR_DbKeepsDirFail, .desc = _("failed to access package keep list database directory") }, {.code = LM_ERR_DbKeepsDirFail, .desc = _("failed to access package keep list database directory") },
{.code = LM_ERR_DbKeepsUnlinkFail, .desc = _("failed to remove package keep list from the database") }, {.code = LM_ERR_DbKeepsUnlinkFail, .desc = _("failed to remove package keep list from the database") },
{.code = LM_ERR_DependNotFound, .desc = _("failed to find %s (dependency of %s)") },
{.code = LM_ERR_InstallDownloadFail, .desc = _("failed to download %s for installation: %s") },
{.code = LM_ERR_PkgNotDownloaded, .desc = _("package is not downloaded") },
{.code = LM_ERR_PkgRemoveDownloadFail, .desc = _("failed to remove downloaded package") },
}; };
for (int i = 0; i < sizeof(errors) / sizeof(lm_error_desc_t); i++) { char *fmt = NULL;
if (errors[i].code == error) error = code;
return errors[i].desc;
if (NULL != error_str) {
free(error_str);
error_str = NULL;
} }
return NULL;
for (int i = 0; i < sizeof(errors) / sizeof(lm_error_desc_t); i++) {
if (errors[i].code == error) {
fmt = errors[i].desc;
break;
}
}
if (NULL == fmt)
return;
va_list args, argscp;
va_start(args, code);
va_copy(argscp, args);
int size = vsnprintf(NULL, 0, fmt, args);
error_str = malloc(size + 1);
vsnprintf(error_str, size, fmt, args);
va_end(args);
va_end(argscp);
}
char *lm_strerror() {
return error_str;
} }
lm_error_t lm_error() { lm_error_t lm_error() {

View File

@ -2,9 +2,12 @@
#include "../../include/error.h" #include "../../include/error.h"
#include "../../include/types.h" #include "../../include/types.h"
#include "../../include/mptp.h" #include "../../include/mptp.h"
#include "../../include/util.h"
#include <errno.h>
#include <strings.h> #include <strings.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
lm_pkg_t *lm_package_new(){ lm_pkg_t *lm_package_new(){
lm_pkg_t *pkg = malloc(sizeof(lm_pkg_t)); lm_pkg_t *pkg = malloc(sizeof(lm_pkg_t));
@ -16,6 +19,34 @@ void lm_package_init(lm_pkg_t *pkg){
bzero(pkg, sizeof(lm_pkg_t)); bzero(pkg, sizeof(lm_pkg_t));
} }
bool lm_package_downloaded(lm_pkg_t *pkg){
if(lm_package_path_is_empty(pkg)){
lm_error_set(LM_ERR_PkgPathsEmpty);
return false;
}
if(!exists(pkg->paths.archive) || !exists(pkg->paths.signature)){
lm_error_set(LM_ERR_PkgNotDownloaded);
return false;
}
return true;
}
bool lm_package_remove_download(lm_pkg_t *pkg){
if(unlink(pkg->paths.archive) < 0 && errno != ENOENT){
lm_error_set(LM_ERR_PkgRemoveDownloadFail);
return false;
}
if(unlink(pkg->paths.signature) < 0 && errno != ENOENT){
lm_error_set(LM_ERR_PkgRemoveDownloadFail);
return false;
}
return true;
}
void lm_package_free(lm_pkg_t *pkg){ void lm_package_free(lm_pkg_t *pkg){
lm_package_data_free(pkg); lm_package_data_free(pkg);
bzero(pkg, sizeof(lm_pkg_t)); bzero(pkg, sizeof(lm_pkg_t));

View File

@ -11,10 +11,9 @@ bool lm_package_verify(lm_pkg_t *pkg){
return false; return false;
} }
if(lm_package_path_is_empty(pkg)){ // error set by function
lm_error_set(LM_ERR_PkgPathsEmpty); if(!lm_package_downloaded(pkg))
return false; return false;
}
gpgme_data_t sig = NULL, text = NULL; gpgme_data_t sig = NULL, text = NULL;
gpgme_ctx_t ctx = NULL; gpgme_ctx_t ctx = NULL;

View File

@ -60,7 +60,7 @@ bool lm_pool_info_load(lm_pool_t *pool) {
return true; return true;
} }
bool lm_pool_info_get(lm_pool_t *pool) { bool lm_pool_info_download(lm_pool_t *pool) {
if(NULL == pool){ if(NULL == pool){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;

View File

@ -85,7 +85,7 @@ end:
return ret; return ret;
} }
bool lm_pool_list_get(lm_pool_t *pool) { bool lm_pool_list_download(lm_pool_t *pool) {
if(NULL == pool){ if(NULL == pool){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;

View File

@ -35,6 +35,8 @@ bool lm_pool_package_add(lm_pool_t *pool, lm_pkg_t *pkg){
return false; return false;
} }
pkg->pool = pool;
if(!lm_pool_path_is_empty(pool)){ if(!lm_pool_path_is_empty(pool)){
size_t path_size = strlen(pool->paths.dir)+strlen(pkg->name)+strlen(pkg->version); size_t path_size = strlen(pool->paths.dir)+strlen(pkg->name)+strlen(pkg->version);
size_t name_size = path_size - strlen(pool->paths.dir); size_t name_size = path_size - strlen(pool->paths.dir);
@ -52,24 +54,13 @@ bool lm_pool_package_add(lm_pool_t *pool, lm_pkg_t *pkg){
lm_package_path_set_signature(pkg, sig_path); lm_package_path_set_signature(pkg, sig_path);
} }
if(NULL == pool->pkg){ // add to the start
pkg->next = pool->pkg;
pool->pkg = pkg; pool->pkg = pkg;
return true; return true;
} }
lm_pkg_t *cur = pool->pkg; bool lm_pool_package_download(lm_pool_t *pool, lm_pkg_t *pkg){
while(NULL != cur){
if(NULL == cur->next){
cur->next = pkg;
return true;
}
cur = cur->next;
}
return false;
}
bool lm_pool_package_get(lm_pool_t *pool, lm_pkg_t *pkg){
if(NULL == pool || NULL == pkg){ if(NULL == pool || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;

View File

@ -10,7 +10,7 @@ lm_pool_t *lm_pool_new(char *name, char *url) {
lm_pool_t *pool = malloc(sizeof(lm_pool_t)); lm_pool_t *pool = malloc(sizeof(lm_pool_t));
bzero(pool, sizeof(lm_pool_t)); bzero(pool, sizeof(lm_pool_t));
pool->available = true; pool->available = false;
pool->name = name; pool->name = name;
if (NULL != url && !lm_url_init(&pool->url, url)) { if (NULL != url && !lm_url_init(&pool->url, url)) {

View File

@ -325,3 +325,67 @@ char *join_alloc(const char *base, const char *pth) {
join(path, base, pth); join(path, base, pth);
return path; return path;
} }
bool pkglist_contains(lm_pkg_t *list, lm_pkg_t *pkg) {
lm_pkg_t *cur = list;
while (cur) {
if (eq(pkg->name, cur->name))
return true;
cur = cur->next;
}
return false;
}
lm_pkg_t *pkglist_del(lm_pkg_t *list, lm_pkg_t *pkg) {
if (NULL == list)
return list;
lm_pkg_t *cur = list;
lm_pkg_t *target = NULL;
int indx = 0;
while (cur) {
if (eq(cur->name, pkg->name)) {
target = cur;
break;
}
cur = cur->next;
indx++;
}
if (NULL == target)
return list;
cur = list;
for (int i = 0; i < indx; i++) {
if (cur->next != NULL)
cur = cur->next;
}
if (NULL == cur->next)
list = NULL;
else
cur->next = cur->next->next;
free(target);
return list;
}
lm_pkg_t *pkglist_add(lm_pkg_t *list, lm_pkg_t *pkg) {
lm_pkg_t *new = malloc(sizeof(lm_pkg_t));
memcpy(new, pkg, sizeof(lm_pkg_t));
new->next = NULL;
new->next = list;
list = new;
return list;
}
void pkglist_free(lm_pkg_t *list) {
lm_pkg_t *cur = list;
while (cur) {
lm_pkg_t *old = cur;
cur = cur->next;
free(old);
}
}