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_list(&ctx, true, true, NULL, NULL);
if (lm_ctx_package_get(&ctx, "which", NULL) == NULL) {
printf("failed to get 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());
if(!lm_ctx_install(&ctx, "which")){
printf("failed to install the package: %s (%d)\n", lm_strerror(), lm_error());
goto end;
}

View File

@ -3,7 +3,16 @@
#include "types.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_database_callback_t)(lm_ctx_t *ctx, lm_pkg_t *pkg, void *data);
void lm_ctx_init(lm_ctx_t *ctx);
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);
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);
bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name);
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(
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);
lm_pkg_t *lm_ctx_package_get(lm_ctx_t *ctx, char *name, char *version);
bool lm_ctx_package_verify(lm_ctx_t *ctx, char *name, char *version);
bool lm_ctx_package_install(lm_ctx_t *ctx, lm_pkg_t *pkg);
bool lm_ctx_package_remove(lm_ctx_t *ctx, lm_pkg_t *pkg);
bool lm_ctx_package_verify(lm_ctx_t *ctx, lm_pkg_t *pkg);
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_SELECT_PACKAGE = 2,
QUERY_DELETE_PACKAGE = 3,
QUERY_ALL_PACKAGE = 4,
} lm_query_index_t;
extern char *queries[];
typedef struct lm_database {
char *dir;
lm_pkg_t *pkg;
sqlite3 *sql;
sqlite3_stmt *st;
sqlite3 *sql;
char *dir;
lm_pkg_t *pkg;
} lm_database_t;
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);
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_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_DbKeepsUnlinkFail = 87,
LM_ERR_DbSqlNotFound = 88,
LM_ERR_DependNotFound = 89,
LM_ERR_InstallDownloadFail = 90,
LM_ERR_PkgNotDownloaded = 91,
LM_ERR_PkgRemoveDownloadFail = 92,
} lm_error_t;
typedef struct lm_error_desc {
@ -98,6 +102,7 @@ typedef struct lm_error_desc {
char *desc;
} 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();
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);
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);
size_t lm_package_depend_count(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);
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_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_is_empty(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_get(lm_pool_t *pool);
bool lm_pool_info_download(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_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_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr);

View File

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

View File

@ -1,4 +1,5 @@
#include "../../include/database.h"
#include "../../include/error.h"
#include "../../include/util.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");
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/package.h"
#include "../../include/database.h"
#include "../../include/util.h"
#include "../../include/error.h"
#include "../../include/ctx.h"
lm_pkg_t *lm_ctx_package_get(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;
}
if(!lm_pool_package_get(pool, pkg))
return NULL;
return pkg;
bool lm_ctx_package_install(lm_ctx_t *ctx, lm_pkg_t *pkg){
return true;
}
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_remove(lm_ctx_t *ctx, lm_pkg_t *pkg){
return true;
}
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;
bool lm_ctx_package_verify(lm_ctx_t *ctx, lm_pkg_t *pkg){
return true;
}

View File

@ -43,25 +43,11 @@ lm_pool_t *lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url) {
}
}
if (NULL == ctx->pools) {
ctx->pools = pool;
return pool;
}
// add to the start
pool->next = ctx->pools;
ctx->pools = 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;
return pool;
}
void lm_ctx_pool_clear(lm_ctx_t *ctx) {
@ -134,7 +120,7 @@ void lm_ctx_pool_get_info(lm_ctx_t *ctx, bool allow_update, bool force_update, l
goto success;
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());
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;
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());
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);
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_server_send(sock, &packet, &saddr);
continue;

View File

@ -18,6 +18,7 @@ char *queries[] = {
"INSERT INTO packages VALUES (?, ?, ?, ?, ?)",
"SELECT * FROM packages WHERE name = '?'",
"DELETE from packages WHERE name = '?'",
"SELECT * FROM packages",
};
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){
if(NULL != db->st)
sqlite3_finalize(db->st);
sqlite3_close(db->sql);
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)];
sqlite3_stmt *st = NULL;
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));
lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end;
}
sqlite3_bind_text(st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC);
sqlite3_bind_text(st, 2, pkg->desc, strlen(pkg->desc), SQLITE_STATIC);
sqlite3_bind_text(st, 3, pkg->version, strlen(pkg->version), SQLITE_STATIC);
sqlite3_bind_int64(st, 4, pkg->size);
sqlite3_bind_text(db->st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC);
sqlite3_bind_text(db->st, 2, pkg->desc, strlen(pkg->desc), SQLITE_STATIC);
sqlite3_bind_text(db->st, 3, pkg->version, strlen(pkg->version), SQLITE_STATIC);
sqlite3_bind_int64(db->st, 4, pkg->size);
if(!lm_package_depend_tostr(pkg, depends)){
pdebug(__func__, "failed to convert depends to string for inserting %s: %s", pkg->name, lm_strerror());
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));
lm_error_set(LM_ERR_DbSqlInsertFail);
goto end;
@ -43,8 +42,10 @@ bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg){
ret = true;
end:
if(NULL != st)
sqlite3_finalize(st);
if(NULL != db->st){
sqlite3_finalize(db->st);
db->st = NULL;
}
return ret;
}
@ -54,18 +55,17 @@ bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){
return false;
}
sqlite3_stmt *st;
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));
lm_error_set(LM_ERR_DbSqlPrepareFail);
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);
lm_error_set(LM_ERR_DbSqlNotFound);
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
lm_package_init(pkg);
pkg->name = strdup((char*)sqlite3_column_text(st, 0));
pkg->desc = strdup((char*)sqlite3_column_text(st, 1));
pkg->version = strdup((char*)sqlite3_column_text(st, 2));
pkg->size = sqlite3_column_int64(st, 3);
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(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());
// 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;
end:
if(NULL != st)
sqlite3_finalize(st);
if(NULL != db->st){
sqlite3_finalize(db->st);
db->st = NULL;
}
return ret;
}
@ -105,18 +107,17 @@ bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg){
return false;
}
sqlite3_stmt *st;
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));
lm_error_set(LM_ERR_DbSqlPrepareFail);
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));
lm_error_set(LM_ERR_DbSqlInsertFail);
goto end;
@ -124,7 +125,50 @@ bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg){
ret = true;
end:
if(NULL != st)
sqlite3_finalize(st);
if(NULL != db->st){
sqlite3_finalize(db->st);
db->st = NULL;
}
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/util.h"
#include <stdarg.h>
#include <stdio.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) {
error = code;
void lm_error_clear() {
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[] = {
{.code = LM_ERR_NoError, .desc = _("no error") },
{.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_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_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++) {
if (errors[i].code == error)
return errors[i].desc;
char *fmt = NULL;
error = code;
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() {

View File

@ -2,9 +2,12 @@
#include "../../include/error.h"
#include "../../include/types.h"
#include "../../include/mptp.h"
#include "../../include/util.h"
#include <errno.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
lm_pkg_t *lm_package_new(){
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));
}
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){
lm_package_data_free(pkg);
bzero(pkg, sizeof(lm_pkg_t));

View File

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

View File

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

View File

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

View File

@ -35,6 +35,8 @@ bool lm_pool_package_add(lm_pool_t *pool, lm_pkg_t *pkg){
return false;
}
pkg->pool = pool;
if(!lm_pool_path_is_empty(pool)){
size_t path_size = strlen(pool->paths.dir)+strlen(pkg->name)+strlen(pkg->version);
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);
}
if(NULL == pool->pkg){
pool->pkg = pkg;
return true;
}
lm_pkg_t *cur = pool->pkg;
while(NULL != cur){
if(NULL == cur->next){
cur->next = pkg;
return true;
}
cur = cur->next;
}
return false;
// add to the start
pkg->next = pool->pkg;
pool->pkg = pkg;
return true;
}
bool lm_pool_package_get(lm_pool_t *pool, lm_pkg_t *pkg){
bool lm_pool_package_download(lm_pool_t *pool, lm_pkg_t *pkg){
if(NULL == pool || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL);
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));
bzero(pool, sizeof(lm_pool_t));
pool->available = true;
pool->available = false;
pool->name = name;
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);
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);
}
}