new: add callback for serve command

This commit is contained in:
ngn 2024-07-17 21:31:25 +03:00
parent 68a0951a9f
commit 7532c0d682
9 changed files with 59 additions and 52 deletions

View File

@ -44,6 +44,11 @@ int main(int argc, char *argv[]) {
goto end;
}
if (!lm_ctx_removeable(&ctx, &pkg)) {
printf("cannot remove package: %s (%d)", lm_strerror(), lm_error());
goto end;
}
printf("removing package: %s (%s)...\n", pkg.name, pkg.version);
if (!lm_ctx_remove(&ctx, &pkg, NULL, NULL)) {

View File

@ -1,5 +1,6 @@
#pragma once
#include "database.h"
#include "mptp.h"
#include "types.h"
#include <stdbool.h>
@ -52,6 +53,7 @@ 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_serve_callback_t)(lm_pool_t *pool, lm_mptp_t *packet, struct sockaddr *addr, void *data);
typedef bool (*lm_ctx_ping_callback_t)(lm_ctx_t *ctx, lm_pool_t *pool, bool status, void *data);
typedef lm_ctx_install_callback_t lm_ctx_remove_callback_t;
typedef lm_ctx_install_callback_t lm_ctx_check_callback_t;
@ -79,17 +81,20 @@ void lm_ctx_update_list_free(lm_ctx_update_list_t *list); // fr
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_removeable(lm_ctx_t *ctx, lm_pkg_t *pkg); // checks if a package is available for removal
bool lm_ctx_remove(
lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_remove_callback_t callback, void *data); // removes a single package
bool lm_ctx_download(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_download_callback_t callback,
void *data); // downloads a single package
bool lm_ctx_install(
lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_install_callback_t callback, void *data); // installs/updates a single package
bool lm_ctx_remove(
lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_remove_callback_t callback, void *data); // removes a single package
bool lm_ctx_check(
lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_check_callback_t callback, void *data); // checks a single package
size_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data); // syncs all the pools
void lm_ctx_ping(lm_ctx_t *ctx, lm_ctx_ping_callback_t callback, void *data); // pings all the pools
bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads); // serves all the pools
bool lm_ctx_serve(
lm_ctx_t *ctx, char *addr, uint8_t threads, lm_ctx_serve_callback_t callback, void *data); // serves all the pools
/* ####################
## pool fucntions ##

View File

@ -9,13 +9,6 @@
#define POOL_INFO_PUBKEY "pubkey"
#define POOL_INFO_MAINTAINER "maintainer"
typedef struct lm_pool_thread_arg {
int sock;
struct sockaddr addr;
lm_mptp_t packet;
lm_pool_t *pool;
} lm_pool_thread_arg_t;
lm_pool_t *lm_pool_new(char *name, char *url);
void lm_pool_test(lm_pool_t *pool);
void lm_pool_free(lm_pool_t *pool);

View File

@ -33,7 +33,6 @@ bool parse_host(char *addr, char *host, uint16_t *port);
bool copy_blocks(struct archive *w, struct archive *r);
bool extract_archive(char *dst, char *src);
bool mkdir_ifnot(char *path);
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);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-16 20:08+0300\n"
"POT-Creation-Date: 2024-07-17 21:20+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"

View File

@ -8,17 +8,12 @@
#include <stdlib.h>
#include <unistd.h>
bool lm_ctx_remove(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_remove_callback_t callback, void *data){
bool lm_ctx_removeable(lm_ctx_t *ctx, lm_pkg_t *pkg){
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_is_installed(ctx, pkg, true)){
lm_error_set(LM_ERR_PkgNotInstalled);
return false;
@ -37,6 +32,24 @@ bool lm_ctx_remove(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_remove_callback_t callba
}
}
lm_database_package_next_free(ctx->db, &cur);
return true;
}
bool lm_ctx_remove(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_remove_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;
char *path = NULL, *hash = NULL, *fpath = NULL;
bool in_keep = false, ret = false;
size_t total = 0, current = 0;
@ -94,7 +107,6 @@ 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;
}

View File

@ -11,29 +11,34 @@
#include <string.h>
#include <stdbool.h>
void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr) {
char ipaddr[INET6_ADDRSTRLEN];
bzero(ipaddr, sizeof(ipaddr));
sockaddr_to_str(addr, ipaddr);
struct lm_ctx_serve_thread_arg {
int sock;
struct sockaddr addr;
lm_mptp_t packet;
lm_pool_t *pool;
lm_ctx_serve_callback_t callback;
void *data;
};
void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr) {
switch (MPTP_FLAGS_CODE(packet)) {
// response PING with PONG
case MPTP_C2S_PING:
pdebug(__func__, "(%s) PING from %s returning PONG", pool->name, ipaddr);
pdebug(__func__, "(%s) PING: returning PONG", pool->name);
lm_mptp_init(packet, false, MPTP_S2C_PONG, true);
lm_mptp_server_send(sock, packet, addr);
break;
// when INFO file is requested, send the file
case MPTP_C2S_INFO:
pdebug(__func__, "(%s) INFO from %s attempting to send info", pool->name, ipaddr);
pdebug(__func__, "(%s) INFO: attempting to send info", pool->name);
lm_mptp_sendfile(sock, addr, pool->paths.info_file, NULL, NULL);
break;
// when LIST file is requested, send the file
case MPTP_C2S_LIST:
pdebug(__func__, "(%s) LIST from %s attempting to send list", pool->name, ipaddr);
pdebug(__func__, "(%s) LIST: attempting to send list", pool->name);
lm_mptp_sendfile(sock, addr, pool->paths.list_file, NULL, NULL);
break;
@ -48,12 +53,12 @@ void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockadd
break;
}
pdebug(__func__, "(%s) PULL from %s attempting to send package archive and signature", pool->name, ipaddr);
pdebug(__func__, "(%s) PULL: attempting to send package archive and signature", pool->name);
char path[packet->header.data_size + 1], *package = path;
if(!lm_mptp_get_data(packet, path)){
// we should never be able to get here, if we do theres definetly a bug
pdebug(__func__, "(%s) skipping PULL from %s, failed to get path: %s", pool->name, ipaddr, lm_strerror());
pdebug(__func__, "(%s) PULL: skipping, failed to get path: %s", pool->name, lm_strerror());
break;
}
@ -90,12 +95,14 @@ void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockadd
}
void __lm_ctx_serve_thread(void *_arg) {
lm_pool_thread_arg_t *arg = _arg;
struct lm_ctx_serve_thread_arg *arg = _arg;
if(NULL != arg->callback && !arg->callback(arg->pool, &arg->packet, &arg->addr, arg->data))
return free(arg);
__lm_ctx_serve(arg->pool, &arg->packet, arg->sock, &arg->addr);
free(arg);
}
bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads){
bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, lm_ctx_serve_callback_t callback, void *data){
if (NULL == addr || threads < 0) {
lm_error_set(LM_ERR_ArgNULL);
return false;
@ -168,10 +175,12 @@ bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads){
continue;
}
lm_pool_thread_arg_t *arg = malloc(sizeof(lm_pool_thread_arg_t));
struct lm_ctx_serve_thread_arg *arg = malloc(sizeof(struct lm_ctx_serve_thread_arg));
memcpy(&arg->addr, &saddr, sizeof(struct sockaddr));
lm_mptp_copy(&arg->packet, &packet);
arg->callback = callback;
arg->data = data;
arg->pool = pool;
arg->sock = sock;

View File

@ -64,6 +64,11 @@ bool lm_database_package_find(lm_database_t *db, lm_pkg_t *pkg, char *name, char
else
query = queries[QUERY_SELECT_PACKAGE_SINGLE_2];
// package pointer should already be free'd
// we are initing it just in case the caller didn't
if(NULL != pkg)
lm_package_init(pkg);
if(sqlite3_prepare(db->packages_db, query, strlen(query), &db->packages_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for finding %s: %s", name, sqlite3_errmsg(db->packages_db));
lm_error_set(LM_ERR_DbSqlPrepareFail);
@ -85,10 +90,6 @@ bool lm_database_package_find(lm_database_t *db, lm_pkg_t *pkg, char *name, char
goto end;
}
// package pointer should already be free'd
// we are initing it just in case the caller didn't
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));

View File

@ -249,23 +249,6 @@ bool mkdir_ifnot(char *path) {
return !(mkdir(path, 0700) < 0 && errno != EEXIST);
}
void sockaddr_to_str(struct sockaddr *addr, char *str) {
struct sockaddr_in *ipv4;
struct sockaddr_in6 *ipv6;
switch (addr->sa_family) {
case AF_INET:
ipv4 = (struct sockaddr_in *)addr;
inet_ntop(AF_INET, &ipv4->sin_addr, str, INET_ADDRSTRLEN);
break;
case AF_INET6:
ipv6 = (struct sockaddr_in6 *)addr;
inet_ntop(AF_INET6, &ipv6->sin6_addr, str, INET6_ADDRSTRLEN);
break;
}
}
bool package_name_valid(char *name) {
for (char *c = name; *c != 0; c++) {
if (!is_digit(*c) && !is_letter(*c) && *c != '-' && *c != '.')