new: implement more pool stuff, start working on package functions

This commit is contained in:
ngn
2024-06-26 22:33:20 +03:00
parent 92bc029d0a
commit 6ef1bf0b12
22 changed files with 947 additions and 563 deletions

95
src/pool/info.c Normal file
View File

@ -0,0 +1,95 @@
#include "../../include/error.h"
#include "../../include/pool.h"
#include "../../include/mptp.h"
#include "../../include/util.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ini.h>
int lm_pool_info_handler(void *data, const char *_section, const char *_key, const char *_value) {
char *section = (char *)_section, *value = (char *)_value, *key = (char *)_key;
lm_pool_t *pool = data;
if (!eq(pool->name, section))
return 0;
if (eq(key, "size"))
pool->info.size = atol(value);
else if (eq(key, "maintainer"))
pool->info.maintainer = strdup(value);
else if (eq(key, "pubkey"))
pool->info.pubkey = strdup(value);
else
return 0;
return 1;
}
bool lm_pool_info_load(lm_pool_t *pool, char *file) {
lm_pool_info_free(pool);
if (ini_parse(file, lm_pool_info_handler, pool) < 0) {
lm_error_set(LM_ERR_PoolInfoBad);
return false;
}
pool->info.file = strdup(file);
return true;
}
bool lm_pool_info_get(lm_pool_t *pool, char *file) {
if(!pool->available)
return false;
if(NULL == pool->url.host)
return false;
if(NULL == pool->url.path)
return false;
FILE *info = fopen(file, "a");
int sock = lm_mptp_client_connect(pool->url.host, pool->url.port);
lm_mptp_t packet;
bool ret = false;
if(NULL == info)
goto end;
lm_mptp_init(&packet, true, MPTP_C2S_INFO, true);
lm_mptp_set_host(&packet, pool->url.host);
lm_mptp_set_data(&packet, pool->url.path, strlen(pool->url.path));
if(!lm_mptp_client_send(sock, &packet))
goto end;
if(!lm_mptp_client_recv(sock, &packet))
goto end;
while(lm_mptp_client_recv(sock, &packet)){
if(!lm_mptp_client_verify(&packet))
goto end;
if(fwrite(packet.data, 1, packet.header.data_size, info)==0)
goto end;
if(MPTP_IS_LAST(&packet))
break;
}
ret = true;
end:
fclose(info);
if(ret)
ret = lm_pool_info_load(pool, file);
return ret;
}
void lm_pool_info_free(lm_pool_t *pool) {
free(pool->info.file);
free(pool->info.pubkey);
free(pool->info.maintainer);
bzero(&pool->info, sizeof(pool->info));
}

100
src/pool/list.c Normal file
View File

@ -0,0 +1,100 @@
#include "../../include/error.h"
#include "../../include/pool.h"
#include "../../include/mptp.h"
#include "../../include/util.h"
#include "../../include/pkg.h"
#include <dirent.h>
#include <libgen.h>
#include <stdbool.h>
#include <string.h>
bool lm_pool_list_load(lm_pool_t *pool, char *file){
size_t file_len = strlen(file), ent_len = 0;
char filecp[file_len+1], *dir = NULL;
struct dirent *ent = NULL;
DIR *dirfd = NULL;
bool ret = false;
memcpy(filecp, file, file_len+1);
dir = dirname(filecp);
if(!extract_archive(dir, file))
goto end;
if((dirfd = opendir(dir)) == NULL){
lm_error_set(LM_ERR_PoolListDirFail);
goto end;
}
while((ent = readdir(dirfd)) != NULL){
ent_len = strlen(ent->d_name);
char datap[ent_len+file_len+10];
snprintf(datap, sizeof(datap), "%s/%s/DATA", dir, ent->d_name);
lm_pkg_t *pkg = lm_pkg_new();
if(!lm_pkg_data_load(pkg, datap)){
lm_pkg_free(pkg);
continue;
}
if(!lm_pool_add(pool, pkg)){
lm_pkg_free(pkg);
continue;
}
}
end:
if(NULL != dirfd)
closedir(dirfd);
return ret;
}
bool lm_pool_list_get(lm_pool_t *pool, char *file) {
if(!pool->available)
return false;
if(NULL == pool->url.host)
return false;
if(NULL == pool->url.path)
return false;
FILE *info = fopen(file, "a");
int sock = lm_mptp_client_connect(pool->url.host, pool->url.port);
lm_mptp_t packet;
bool ret = false;
if(NULL == info)
goto end;
lm_mptp_init(&packet, true, MPTP_C2S_LIST, true);
lm_mptp_set_host(&packet, pool->url.host);
lm_mptp_set_data(&packet, pool->url.path, strlen(pool->url.path));
if(!lm_mptp_client_send(sock, &packet))
goto end;
if(!lm_mptp_client_recv(sock, &packet))
goto end;
while(lm_mptp_client_recv(sock, &packet)){
if(!lm_mptp_client_verify(&packet))
goto end;
if(fwrite(packet.data, 1, packet.header.data_size, info)==0)
goto end;
if(MPTP_IS_LAST(&packet))
break;
}
ret = true;
end:
fclose(info);
if(ret)
ret = lm_pool_list_load(pool, file);
return ret;
}

93
src/pool/pool.c Normal file
View File

@ -0,0 +1,93 @@
#include "../../include/error.h"
#include "../../include/util.h"
#include "../../include/pool.h"
#include <stdlib.h>
#include <string.h>
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));
bzero(&pool->info, sizeof(pool->info));
bzero(&pool->url, sizeof(pool->url));
pool->available = true;
pool->name = name;
if (!lm_url_init(&pool->url, url)) {
free(pool);
return NULL;
}
if (!eq(pool->url.protocol, "mptp")) {
lm_error_set(LM_ERR_PoolNoSupport);
lm_pool_free(pool);
return NULL;
}
return pool;
}
void lm_pool_test(lm_pool_t *pool) {
lm_mptp_t packet;
lm_mptp_init(&packet, true, MPTP_C2S_PING, true);
lm_mptp_set_host(&packet, pool->url.host);
lm_mptp_set_data(&packet, pool->url.path, strlen(pool->url.path));
int sock = lm_mptp_client_connect(pool->url.host, pool->url.port);
if (sock == -1) {
pool->available = false;
return;
}
if (!lm_mptp_client_send(sock, &packet)) {
pool->available = false;
goto end;
}
if (!lm_mptp_client_recv(sock, &packet)) {
pool->available = false;
goto end;
}
if (!lm_mptp_client_verify(&packet)) {
pool->available = false;
goto end;
}
pool->available = MPTP_FLAGS_CODE(&packet) == MPTP_S2C_PONG;
end:
lm_mptp_close(sock);
return;
}
bool lm_pool_add(lm_pool_t *pool, lm_pkg_t *pkg){
if(NULL == pool || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
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;
}
void lm_pool_free(lm_pool_t *pool) {
lm_url_free(&pool->url);
lm_pool_info_free(pool);
free(pool);
}

39
src/pool/serve.c Normal file
View File

@ -0,0 +1,39 @@
#include "../../include/error.h"
#include "../../include/util.h"
#include "../../include/pool.h"
#include <stdlib.h>
void lm_pool_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr) {
switch (MPTP_FLAGS_CODE(packet)) {
case MPTP_C2S_PING:
lm_mptp_init(packet, false, MPTP_S2C_PONG, true);
goto end;
case MPTP_C2S_INFO:
if (NULL == pool->info.file) {
lm_mptp_init(packet, false, MPTP_S2C_BRUH, true);
goto end;
}
FILE *info = fopen(pool->info.file, "r");
size_t read = 0;
while ((read = fread(packet->data, 1, MPTP_DATA_MAX, info)) > 0) {
lm_mptp_server_send(sock, packet, addr);
lm_mptp_init(packet, false, MPTP_S2C_COOL, false);
}
fclose(info);
lm_mptp_init(packet, false, MPTP_S2C_COOL, true);
}
end:
lm_mptp_server_send(sock, packet, addr);
}
void lm_pool_serve_thread(void *_arg) {
lm_pool_thread_arg_t *arg = _arg;
lm_pool_serve(arg->pool, &arg->packet, arg->sock, &arg->addr);
free(arg);
}