new: implement check and update functions
This commit is contained in:
parent
f886bc08e4
commit
839bcb47bf
@ -1,6 +1,6 @@
|
||||
CC = gcc
|
||||
|
||||
all: ../dist/client_install ../dist/client_remove ../dist/server
|
||||
all: ../dist/client_install ../dist/client_remove ../dist/client_update ../dist/client_check ../dist/client_list ../dist/server
|
||||
|
||||
../dist/client_install: client/install.c client/*.h ../dist/libmp.so
|
||||
mkdir -pv ../dist
|
||||
@ -10,6 +10,18 @@ all: ../dist/client_install ../dist/client_remove ../dist/server
|
||||
mkdir -pv ../dist
|
||||
$(CC) -L../dist $< -lmp -o $@
|
||||
|
||||
../dist/client_update: client/update.c client/*.h ../dist/libmp.so
|
||||
mkdir -pv ../dist
|
||||
$(CC) -L../dist $< -lmp -o $@
|
||||
|
||||
../dist/client_check: client/check.c client/*.h ../dist/libmp.so
|
||||
mkdir -pv ../dist
|
||||
$(CC) -L../dist $< -lmp -o $@
|
||||
|
||||
../dist/client_list: client/list.c client/*.h ../dist/libmp.so
|
||||
mkdir -pv ../dist
|
||||
$(CC) -L../dist $< -lmp -o $@
|
||||
|
||||
../dist/server: server/*.c ../dist/libmp.so
|
||||
mkdir -pv ../dist
|
||||
$(CC) -L../dist $< -lmp -o $@
|
||||
|
45
examples/client/check.c
Normal file
45
examples/client/check.c
Normal file
@ -0,0 +1,45 @@
|
||||
#include "../../include/all.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int ret = EXIT_FAILURE;
|
||||
lm_pkg_t pkg;
|
||||
lm_ctx_t ctx;
|
||||
|
||||
lm_package_init(&pkg);
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: %s <package name>\n", argv[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
lm_ctx_init(&ctx);
|
||||
|
||||
if (!lm_ctx_set_data(&ctx, DATA_DIR)) {
|
||||
printf("failed to set data dir: %s (%d)\n", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!lm_ctx_database_find(&ctx, &pkg, argv[1], NULL)) {
|
||||
printf("failed to find package: %s (%d)\n", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("checking %s (%s)...\n", pkg.name, pkg.version);
|
||||
|
||||
if (!lm_ctx_check(&ctx, &pkg, NULL, NULL)) {
|
||||
printf("failed to verify the package: %s (%d)\n", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
end:
|
||||
lm_package_free(&pkg);
|
||||
lm_ctx_free(&ctx);
|
||||
return ret;
|
||||
}
|
28
examples/client/list.c
Normal file
28
examples/client/list.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "../../include/all.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
lm_ctx_t ctx;
|
||||
lm_pkg_t pkg;
|
||||
int ret = EXIT_FAILURE;
|
||||
|
||||
lm_ctx_init(&ctx);
|
||||
|
||||
if (!lm_ctx_set_data(&ctx, DATA_DIR)) {
|
||||
printf("failed to set data dir: %s (%d)\n", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("listing installed packages:\n");
|
||||
|
||||
while (lm_ctx_database_next(&ctx, &pkg))
|
||||
printf("%s (%s)\n", pkg.name, pkg.version);
|
||||
|
||||
end:
|
||||
lm_ctx_database_next_free(&ctx, &pkg);
|
||||
return ret;
|
||||
}
|
60
examples/client/update.c
Normal file
60
examples/client/update.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "../../include/all.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
lm_ctx_update_list_t *list = NULL;
|
||||
int ret = EXIT_FAILURE;
|
||||
lm_pkg_t pkg, *cur = NULL;
|
||||
lm_ctx_t ctx;
|
||||
|
||||
if (!mkdir_ifnot(ROOT_DIR)) {
|
||||
printf("failed to create root dir: %s\n", ROOT_DIR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
lm_ctx_init(&ctx);
|
||||
|
||||
if (!lm_ctx_set_data(&ctx, DATA_DIR)) {
|
||||
printf("failed to set data dir: %s (%d)\n", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!lm_ctx_set_temp(&ctx, TEMP_DIR)) {
|
||||
printf("failed to set temp dir: %s (%d)\n", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!lm_ctx_set_root(&ctx, ROOT_DIR)) {
|
||||
printf("failed to set root dir: %s (%d)\n", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((list = lm_ctx_update_list(&ctx)) == NULL) {
|
||||
printf("failed to get update list: %s (%d)", lm_strerror(), lm_error());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (list->count == 0) {
|
||||
printf("all packages are up-to-date\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
while ((cur = lm_ctx_update_list_next(list)) != NULL) {
|
||||
printf("updating %s (%s)...\n", cur->name, cur->version);
|
||||
if (!lm_ctx_update(&ctx, cur, NULL, NULL)) {
|
||||
printf("failed to update package: %s\n", lm_strerror());
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
end:
|
||||
lm_ctx_update_list_free(list);
|
||||
lm_ctx_free(&ctx);
|
||||
return ret;
|
||||
}
|
@ -21,9 +21,9 @@ typedef struct lm_ctx_resolve_list {
|
||||
} lm_ctx_resolve_list_t;
|
||||
|
||||
typedef struct lm_ctx_update_list {
|
||||
lm_pkg_t **packages;
|
||||
size_t count;
|
||||
size_t index;
|
||||
lm_pkg_t *packages;
|
||||
lm_pkg_t *cur;
|
||||
size_t count;
|
||||
} lm_ctx_update_list_t;
|
||||
|
||||
typedef enum lm_ctx_sync_state {
|
||||
@ -35,6 +35,11 @@ typedef enum lm_ctx_sync_state {
|
||||
SYNC_LIST_FAIL = 5,
|
||||
} lm_ctx_sync_state_t;
|
||||
|
||||
typedef enum lm_ctx_update_state {
|
||||
UPDATE_REMOVE = 0,
|
||||
UPDATE_INSTALL = 1,
|
||||
} lm_ctx_update_state_t;
|
||||
|
||||
/* ###################
|
||||
## ctx callbacks ##
|
||||
################### */
|
||||
@ -43,6 +48,8 @@ typedef bool (*lm_ctx_download_callback_t)(
|
||||
lm_ctx_t *ctx, lm_pkg_t *pkg, bool is_archive, size_t current, size_t total, void *data);
|
||||
typedef bool (*lm_ctx_install_callback_t)(
|
||||
lm_ctx_t *ctx, lm_pkg_t *pkg, char *file, size_t current, size_t total, void *data);
|
||||
typedef bool (*lm_ctx_update_callback_t)(
|
||||
lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_update_state_t state, char *file, size_t current, size_t total, void *data);
|
||||
typedef bool (*lm_ctx_sync_callback_t)(
|
||||
lm_ctx_t *ctx, lm_pool_t *pool, lm_ctx_sync_state_t state, size_t current, size_t total, void *data);
|
||||
typedef bool (*lm_ctx_ping_callback_t)(lm_ctx_t *ctx, lm_pool_t *pool, bool status, void *data);
|
||||
@ -66,9 +73,11 @@ lm_ctx_resolve_list_t *lm_ctx_resolve(
|
||||
lm_pkg_t *lm_ctx_resolve_next(lm_ctx_resolve_list_t *list); // returns the next package in the list
|
||||
void lm_ctx_resolve_free(lm_ctx_resolve_list_t *list); // frees the resolved list returned by lm_ctx_resolve
|
||||
|
||||
lm_ctx_update_list_t *lm_ctx_update(lm_ctx_t *ctx); // returns a list of packages to update
|
||||
lm_pkg_t *lm_ctx_update_next(lm_ctx_update_list_t *list); // returns the next package in the list
|
||||
void lm_ctx_update_free(lm_ctx_update_list_t *list); // frees the update list returned by lm_ctx_update
|
||||
lm_ctx_update_list_t *lm_ctx_update_list(lm_ctx_t *ctx); // get a list of packages to update
|
||||
lm_pkg_t *lm_ctx_update_list_next(lm_ctx_update_list_t *list); // get the next package in the update list
|
||||
void lm_ctx_update_list_free(lm_ctx_update_list_t *list); // free the update list
|
||||
bool lm_ctx_update(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_update_callback_t callback,
|
||||
void *data); // returns a list of packages to update
|
||||
|
||||
bool lm_ctx_download(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_download_callback_t callback,
|
||||
void *data); // downloads a single package
|
||||
@ -98,5 +107,5 @@ lm_pool_t *lm_ctx_pool_by_url(lm_ctx_t *ctx, char *host, char *path); // find p
|
||||
bool lm_ctx_database_init(lm_ctx_t *ctx); // init ctx database (if not already present)
|
||||
bool lm_ctx_database_is_installed(lm_ctx_t *ctx, lm_pkg_t *pkg, bool check_version); // check if a package is installed
|
||||
bool lm_ctx_database_find(lm_ctx_t *ctx, lm_pkg_t *pkg, char *name, char *version); // find a package by name
|
||||
bool lm_ctx_database_foreach(
|
||||
lm_ctx_t *ctx, lm_ctx_database_callback_t callback, void *data); // loop for each package in the database
|
||||
bool lm_ctx_database_next(lm_ctx_t *ctx, lm_pkg_t *pkg); // load the next package into pkg pointer
|
||||
bool lm_ctx_database_next_free(lm_ctx_t *ctx, lm_pkg_t *pkg); // free the used next pointers
|
||||
|
@ -133,6 +133,11 @@ typedef enum lm_error {
|
||||
LM_ERR_InstallStatusFail = 125,
|
||||
LM_ERR_InstallScriptFail = 126,
|
||||
LM_ERR_PkgBreaks = 127,
|
||||
LM_ERR_PkgUpToDate = 128,
|
||||
LM_ERR_HashOpenFail = 129,
|
||||
LM_ERR_HashDigestFail = 130,
|
||||
LM_ERR_FileHashFail = 131,
|
||||
LM_ERR_FileHashNoMatch = 132,
|
||||
} lm_error_t;
|
||||
|
||||
typedef struct lm_error_desc {
|
||||
|
@ -12,6 +12,7 @@ lm_pkg_t *lm_package_new();
|
||||
void lm_package_free(lm_pkg_t *pkg);
|
||||
bool lm_package_verify(lm_pkg_t *pkg);
|
||||
void lm_package_init(lm_pkg_t *pkg);
|
||||
bool lm_package_copy(lm_pkg_t *dst, lm_pkg_t *src);
|
||||
|
||||
bool lm_package_data_load(lm_pkg_t *pkg, char *file);
|
||||
void lm_package_data_free(lm_pkg_t *pkg);
|
||||
@ -34,4 +35,5 @@ bool lm_package_path_set_signature(lm_pkg_t *pkg, char *signature_path);
|
||||
bool lm_package_path_set_archive(lm_pkg_t *pkg, char *archive_path);
|
||||
bool lm_package_path_is_empty(lm_pkg_t *pkg);
|
||||
void lm_package_path_free(lm_pkg_t *pkg);
|
||||
bool lm_package_path_copy(lm_pkg_t *dst, lm_pkg_t *src);
|
||||
bool lm_package_is_same(lm_pkg_t *one, lm_pkg_t *two);
|
||||
|
@ -16,12 +16,13 @@ bool is_digit(char c);
|
||||
bool copy_from_buffer(void *dst, void *buffer, size_t size, ssize_t *total, ssize_t *used);
|
||||
bool copy_to_buffer(void *buffer, void *src, size_t size, ssize_t *total, ssize_t *used);
|
||||
|
||||
bool copy_file(char *dst, char *src);
|
||||
bool can_write(char *path);
|
||||
bool can_read(char *path);
|
||||
bool is_file(char *path);
|
||||
bool is_dir(char *path);
|
||||
bool exists(char *path);
|
||||
char *get_md5(char *path);
|
||||
bool copy_file(char *dst, char *src);
|
||||
bool can_write(char *path);
|
||||
bool can_read(char *path);
|
||||
bool is_file(char *path);
|
||||
bool is_dir(char *path);
|
||||
bool exists(char *path);
|
||||
|
||||
bool package_parse(char *package, char *name, char *version);
|
||||
bool package_version_valid(char *name);
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-07-10 16:36+0300\n"
|
||||
"POT-Creation-Date: 2024-07-11 07:30+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"
|
||||
@ -559,3 +559,26 @@ msgstr ""
|
||||
#, c-format
|
||||
msgid "removing package breaks %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/error.c:153
|
||||
#, fuzzy
|
||||
msgid "package is already up-to-date"
|
||||
msgstr "URL hostname is too large"
|
||||
|
||||
#: src/error.c:154
|
||||
msgid "failed to open file for hashing"
|
||||
msgstr ""
|
||||
|
||||
#: src/error.c:155
|
||||
msgid "failed create digest for hashing"
|
||||
msgstr ""
|
||||
|
||||
#: src/error.c:156
|
||||
#, c-format
|
||||
msgid "failed to get hash of %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/error.c:157
|
||||
#, c-format
|
||||
msgid "file hash does not match for %s"
|
||||
msgstr ""
|
||||
|
65
src/ctx/check.c
Normal file
65
src/ctx/check.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include "../../include/error.h"
|
||||
#include "../../include/util.h"
|
||||
#include "../../include/ctx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
bool lm_ctx_check(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_check_callback_t callback, void *data){
|
||||
if(NULL == ctx || NULL == pkg){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(NULL == ctx->root){
|
||||
lm_error_set(LM_ERR_CtxRootNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!lm_ctx_database_init(ctx))
|
||||
return false; // error set by function
|
||||
|
||||
size_t rootlen = strlen(ctx->root), current = 0, total = 0;
|
||||
char *path = NULL, *hash = NULL, *fhash = NULL;
|
||||
bool keep = false, ret = false;
|
||||
|
||||
total = lm_database_files_count(ctx->db, pkg);
|
||||
|
||||
while(lm_database_files_next(ctx->db, pkg, &path, &hash, &keep)){
|
||||
char fp[rootlen+strlen(path)+10];
|
||||
join(fp, ctx->root, path);
|
||||
current++;
|
||||
|
||||
if(NULL != callback)
|
||||
if(!callback(ctx, pkg, fp, current, total, data))
|
||||
goto end;
|
||||
|
||||
if(!exists(fp)){
|
||||
pdebug(__func__, "skipping %s because file does not exists", fp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if((fhash = get_md5(fp)) == NULL){
|
||||
char *suberr = lm_strerror_dup();
|
||||
pdebug(__func__, "failed to get hash of %s: %s", fp, suberr);
|
||||
lm_error_set(LM_ERR_FileHashFail, fp, suberr);
|
||||
free(suberr);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!eq(fhash, hash)){
|
||||
lm_error_set(LM_ERR_FileHashNoMatch, fp);
|
||||
goto end;
|
||||
}
|
||||
|
||||
free(fhash);
|
||||
fhash = NULL;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
end:
|
||||
lm_database_files_next_free(ctx->db, pkg, &path, &hash, &keep);
|
||||
free(fhash);
|
||||
return ret;
|
||||
}
|
@ -39,8 +39,8 @@ bool lm_ctx_database_find(lm_ctx_t *ctx, lm_pkg_t *pkg, char *name, char *versio
|
||||
return lm_database_package_find(ctx->db, pkg, name, version);
|
||||
}
|
||||
|
||||
bool lm_ctx_database_foreach(lm_ctx_t *ctx, lm_ctx_database_callback_t callback, void *data){
|
||||
if(NULL == ctx || NULL == callback){
|
||||
bool lm_ctx_database_next(lm_ctx_t *ctx, lm_pkg_t *pkg){
|
||||
if(NULL == ctx || NULL == pkg){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
@ -48,12 +48,18 @@ bool lm_ctx_database_foreach(lm_ctx_t *ctx, lm_ctx_database_callback_t callback,
|
||||
if(!lm_ctx_database_init(ctx))
|
||||
return false; // error set by function
|
||||
|
||||
lm_pkg_t pkg;
|
||||
return lm_database_package_next(ctx->db, pkg);
|
||||
}
|
||||
|
||||
while(lm_database_package_next(ctx->db, &pkg)){
|
||||
if(!callback(ctx, &pkg, data))
|
||||
break;
|
||||
bool lm_ctx_database_next_free(lm_ctx_t *ctx, lm_pkg_t *pkg){
|
||||
if(NULL == ctx || NULL == pkg){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!lm_ctx_database_init(ctx))
|
||||
return false; // error set by function
|
||||
|
||||
lm_database_package_next_free(ctx->db, pkg);
|
||||
return true;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_install_callback_t call
|
||||
return false;
|
||||
}
|
||||
|
||||
if(lm_ctx_database_is_installed(ctx, pkg, true)){
|
||||
if(lm_ctx_database_is_installed(ctx, pkg, false)){
|
||||
lm_error_set(LM_ERR_PkgAlreadyInstalled);
|
||||
return false;
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ bool lm_ctx_remove(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_remove_callback_t callba
|
||||
|
||||
ret = true;
|
||||
end:
|
||||
lm_database_package_next_free(ctx->db, &cur);
|
||||
lm_database_files_next_free(ctx->db, pkg, &path, &hash, &in_keep);
|
||||
return ret;
|
||||
}
|
||||
|
113
src/ctx/update.c
113
src/ctx/update.c
@ -8,54 +8,117 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
lm_ctx_update_list_t *lm_ctx_update(lm_ctx_t *ctx){
|
||||
lm_ctx_update_list_t *list = malloc(sizeof(lm_ctx_update_list_t));
|
||||
list->packages = NULL;
|
||||
list->index = 0;
|
||||
list->count = 0;
|
||||
struct __lm_ctx_update_cb_data {
|
||||
lm_ctx_update_callback_t callback;
|
||||
lm_ctx_update_state_t state;
|
||||
void *data;
|
||||
};
|
||||
|
||||
if(!lm_ctx_database_init(ctx))
|
||||
bool __lm_ctx_update_callback(lm_ctx_t *ctx, lm_pkg_t *pkg, char *file, size_t current, size_t total, void *data){
|
||||
struct __lm_ctx_update_cb_data *cbdata = data;
|
||||
|
||||
if(NULL == cbdata->callback)
|
||||
return true;
|
||||
|
||||
return cbdata->callback(ctx, pkg, cbdata->state, file, current, total, cbdata->data);
|
||||
}
|
||||
|
||||
lm_ctx_update_list_t *lm_ctx_update_list(lm_ctx_t *ctx){
|
||||
if(NULL == ctx){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return NULL;
|
||||
|
||||
lm_pkg_t *pkg = malloc(sizeof(lm_pkg_t));
|
||||
|
||||
while(lm_database_package_next(ctx->db, pkg)){
|
||||
if(NULL == list->packages)
|
||||
list->packages = malloc(sizeof(lm_pkg_t*));
|
||||
else
|
||||
list->packages = realloc(list->packages, (list->count+1)*sizeof(lm_pkg_t*));
|
||||
|
||||
list->packages[list->count++] = pkg;
|
||||
pkg = malloc(sizeof(lm_pkg_t));
|
||||
}
|
||||
|
||||
lm_ctx_update_list_t *list = malloc(sizeof(lm_ctx_update_list_t));
|
||||
lm_pkg_t cur, *new = NULL;
|
||||
|
||||
bzero(list, sizeof(lm_ctx_update_list_t));
|
||||
lm_package_init(&cur);
|
||||
|
||||
while(lm_ctx_database_next(ctx, &cur)){
|
||||
if((new = lm_ctx_pool_find(ctx, cur.name, NULL)) == NULL)
|
||||
continue;
|
||||
|
||||
if(eq(new->version, cur.version))
|
||||
continue;
|
||||
|
||||
if(NULL == list->packages)
|
||||
list->packages = malloc(sizeof(lm_pkg_t));
|
||||
else
|
||||
list->packages = realloc(list->packages, (list->count+1)*sizeof(lm_pkg_t));
|
||||
lm_package_copy(&list->packages[list->count++], &cur);
|
||||
}
|
||||
|
||||
lm_ctx_database_next_free(ctx, &cur);
|
||||
return list;
|
||||
}
|
||||
|
||||
lm_pkg_t *lm_ctx_update_next(lm_ctx_update_list_t *list){
|
||||
lm_pkg_t *lm_ctx_update_list_next(lm_ctx_update_list_t *list){
|
||||
if(NULL == list){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(list->index >= list->count-1){
|
||||
list->index = 0;
|
||||
if(NULL == list->packages)
|
||||
return NULL;
|
||||
|
||||
if(NULL == list->cur)
|
||||
list->cur = &list->packages[0];
|
||||
|
||||
for(int i = 0; i < list->count-1; i++){
|
||||
if(list->cur != &list->packages[i])
|
||||
continue;
|
||||
list->cur = &list->packages[i+1];
|
||||
return list->cur;
|
||||
}
|
||||
|
||||
return list->packages[list->index++];
|
||||
list->cur = NULL;
|
||||
return list->cur;
|
||||
}
|
||||
|
||||
void lm_ctx_update_free(lm_ctx_update_list_t *list){
|
||||
void lm_ctx_update_list_free(lm_ctx_update_list_t *list){
|
||||
if(NULL == list){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < list->count; i++){
|
||||
lm_package_free(list->packages[i]);
|
||||
free(list->packages[i]);
|
||||
if(NULL != list->packages){
|
||||
for(int i = 0; i < list->count; i++)
|
||||
lm_package_free(&list->packages[i]);
|
||||
free(list->packages);
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
bool lm_ctx_update(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_update_callback_t callback, void *data){
|
||||
if(NULL == ctx || NULL == pkg){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct __lm_ctx_update_cb_data cbdata = {
|
||||
.state = UPDATE_REMOVE,
|
||||
.callback = callback,
|
||||
.data = data,
|
||||
};
|
||||
lm_pkg_t *new = NULL;
|
||||
|
||||
if((new = lm_ctx_pool_find(ctx, pkg->name, NULL)) == NULL){
|
||||
lm_error_set(LM_ERR_PkgNotFound);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(eq(new->version, pkg->version)){
|
||||
lm_error_set(LM_ERR_PkgUpToDate);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!lm_ctx_remove(ctx, pkg, __lm_ctx_update_callback, &cbdata))
|
||||
return false; // error set by function
|
||||
|
||||
if(!lm_ctx_install(ctx, new, __lm_ctx_update_callback, &cbdata))
|
||||
return false; // error set by function
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -227,6 +227,7 @@ bool lm_database_files_next(lm_database_t *db, lm_pkg_t *pkg, char **path, char
|
||||
free(*hash);
|
||||
*path = NULL;
|
||||
*hash = NULL;
|
||||
*keep = false;
|
||||
}
|
||||
|
||||
if(sqlite3_step(db->files_st) != SQLITE_ROW){
|
||||
|
@ -157,14 +157,14 @@ bool lm_database_package_next(lm_database_t *db, lm_pkg_t *pkg){
|
||||
return false;
|
||||
}
|
||||
|
||||
lm_package_init(pkg);
|
||||
|
||||
if(sqlite3_step(db->packages_st) != SQLITE_ROW){
|
||||
sqlite3_finalize(db->packages_st);
|
||||
db->packages_st = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
lm_package_init(pkg);
|
||||
|
||||
pkg->name = strdup((char*)sqlite3_column_text(db->packages_st, PACKAGES_COLUMN_NAME-1));
|
||||
pkg->desc = strdup((char*)sqlite3_column_text(db->packages_st, PACKAGES_COLUMN_DESC-1));
|
||||
pkg->version = strdup((char*)sqlite3_column_text(db->packages_st, PACKAGES_COLUMN_VERSION-1));
|
||||
|
@ -150,6 +150,11 @@ void lm_error_set(lm_error_t code, ...) {
|
||||
{.code = LM_ERR_InstallStatusFail, .desc = _("install script returned a bad status code") },
|
||||
{.code = LM_ERR_InstallScriptFail, .desc = _("failed to run the package install script: %s") },
|
||||
{.code = LM_ERR_PkgBreaks, .desc = _("removing package breaks %s") },
|
||||
{.code = LM_ERR_PkgUpToDate, .desc = _("package is already up-to-date") },
|
||||
{.code = LM_ERR_HashOpenFail, .desc = _("failed to open file for hashing") },
|
||||
{.code = LM_ERR_HashDigestFail, .desc = _("failed create digest for hashing") },
|
||||
{.code = LM_ERR_FileHashFail, .desc = _("failed to get hash of %s: %s") },
|
||||
{.code = LM_ERR_FileHashNoMatch, .desc = _("file hash does not match for %s") },
|
||||
};
|
||||
|
||||
char *fmt = NULL;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "../../include/util.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -48,12 +49,39 @@ bool lm_package_remove_download(lm_pkg_t *pkg){
|
||||
}
|
||||
|
||||
bool lm_package_is_same(lm_pkg_t *one, lm_pkg_t *two){
|
||||
if(NULL == one || NULL == two){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
return eq(one->version, two->version) &&
|
||||
eq(one->name, two->name) &&
|
||||
eq(one->desc, two->desc) &&
|
||||
one->size == two->size;
|
||||
}
|
||||
|
||||
bool lm_package_copy(lm_pkg_t *dst, lm_pkg_t *src){
|
||||
lm_package_init(dst);
|
||||
|
||||
dst->name = strdup(src->name);
|
||||
dst->version = strdup(src->version);
|
||||
dst->desc = strdup(src->desc);
|
||||
dst->size = src->size;
|
||||
dst->pool = src->pool;
|
||||
|
||||
if(NULL != src->keeps){
|
||||
for(int i = 0; src->keeps[i] != NULL; i++)
|
||||
lm_package_keep_add(dst, src->keeps[i]);
|
||||
}
|
||||
|
||||
if(NULL != src->depends){
|
||||
for(int i = 0; src->depends[i] != NULL; i++)
|
||||
lm_package_depend_add(dst, src->depends[i]);
|
||||
}
|
||||
|
||||
return lm_package_path_copy(dst, src);
|
||||
}
|
||||
|
||||
void lm_package_free(lm_pkg_t *pkg){
|
||||
lm_package_data_free(pkg);
|
||||
bzero(pkg, sizeof(lm_pkg_t));
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "../../include/package.h"
|
||||
#include "../../include/error.h"
|
||||
#include "../../include/types.h"
|
||||
#include "../../include/util.h"
|
||||
|
||||
@ -38,6 +39,17 @@ bool lm_package_path_is_empty(lm_pkg_t *pkg){
|
||||
NULL == pkg->paths.archive;
|
||||
}
|
||||
|
||||
bool lm_package_path_copy(lm_pkg_t *dst, lm_pkg_t *src){
|
||||
if(NULL == dst || NULL == src){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
dst->paths.archive = strdup(src->paths.archive);
|
||||
dst->paths.signature = strdup(src->paths.signature);
|
||||
return true;
|
||||
}
|
||||
|
||||
void lm_package_path_free(lm_pkg_t *pkg){
|
||||
free(pkg->paths.signature);
|
||||
free(pkg->paths.archive);
|
||||
|
38
src/util.c
38
src/util.c
@ -6,6 +6,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <linux/limits.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -435,3 +436,40 @@ end:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *get_md5(char *path) {
|
||||
const EVP_MD *alg = NULL;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
FILE *file = NULL;
|
||||
char *sum = NULL, buffer[255];
|
||||
unsigned char digest[16];
|
||||
unsigned int digest_len;
|
||||
size_t read = 0;
|
||||
|
||||
alg = EVP_md5();
|
||||
bzero(buffer, sizeof(buffer));
|
||||
bzero(digest, sizeof(digest));
|
||||
|
||||
if ((file = fopen(path, "r")) == NULL) {
|
||||
lm_error_set(LM_ERR_HashOpenFail);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (EVP_DigestInit_ex(ctx, alg, NULL) <= 0) {
|
||||
lm_error_set(LM_ERR_HashDigestFail);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((read = fread(buffer, sizeof(buffer), 1, file)) > 0)
|
||||
EVP_DigestUpdate(ctx, buffer, read);
|
||||
|
||||
EVP_DigestFinal(ctx, digest, &digest_len);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
sum = malloc((digest_len * 2) + 1);
|
||||
|
||||
for (int i = 0; i < sizeof(digest); i++)
|
||||
sprintf(&sum[i * 2], "%02x", (unsigned int)digest[i]);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user