libmp/src/ctx/sync.c

154 lines
3.6 KiB
C

#include "../../include/error.h"
#include "../../include/pool.h"
#include "../../include/util.h"
#include "../../include/ctx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct __lm_ctx_sync_cb_data {
lm_ctx_t *ctx;
lm_pool_t *pool;
lm_ctx_sync_callback_t callback;
lm_ctx_sync_state_t state;
void *data;
};
bool __lm_ctx_sync_callback(char *path, size_t current, size_t total, void *data){
struct __lm_ctx_sync_cb_data *cbdata = data;
if(NULL == cbdata->callback)
return true;
return cbdata->callback(cbdata->ctx, cbdata->pool, cbdata->state, current, total, data);
}
ssize_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data){
if(NULL == ctx) {
lm_error_set(LM_ERR_ArgNULL);
return -1;
}
if(NULL == ctx->pools){
lm_error_set(LM_ERR_NoPools);
return -1;
}
struct __lm_ctx_sync_cb_data cbdata = {
.ctx = ctx,
.callback = callback,
.data = data,
};
lm_pool_t *cur = ctx->pools;
size_t loaded_count = 0;
char *tempdir = NULL;
bool status = false;
while(NULL != cur){
cbdata.pool = cur;
cbdata.state = SYNC_DOWNLOADING_INFO;
if(lm_pool_path_is_empty(cur)){
pdebug(__func__, "(%s) failed to load info, pool paths are empty", cur->name);
lm_error_set(LM_ERR_PoolPathsEmpty);
goto next_info;
}
if(!do_update && !lm_pool_info_load(cur)){
pdebug(__func__, "(%s) failed to load info: %s", cur->name, lm_strerror());
goto next_info;
}
else if(do_update && !lm_pool_info_download(cur, __lm_ctx_sync_callback, &cbdata)) {
pdebug(__func__, "(%s) failed to update info: %s", cur->name, lm_strerror());
goto next_info;
}
pdebug(__func__, "(%s) loaded pool info", cur->name);
status = true;
next_info:
if(NULL != callback && status){
if(!callback(ctx, cur, SYNC_INFO_SUCCESS, 0, 0, data))
goto fail;
}
else if(NULL != callback && !status){
if(!callback(ctx, cur, SYNC_INFO_FAIL, 0, 0, data))
goto fail;
}
if(status)
cur->loaded = true;
status = false;
cur = cur->next;
}
cur = ctx->pools;
status = false;
while(NULL != cur){
cbdata.pool = cur;
cbdata.state = SYNC_DOWNLOADING_LIST;
if(!cur->loaded){
lm_error_set(LM_ERR_InfoNotLoaded);
goto next_list;
}
if(lm_pool_path_is_empty(cur)){
pdebug(__func__, "(%s) failed to load list, pool paths are empty", cur->name);
goto next_list;
}
lm_ctx_temp_clear(ctx);
if((tempdir = lm_ctx_temp_dir(ctx, "list_extracted")) == NULL){
pdebug(__func__, "(%s) failed to access list extract directory: %s", cur->name, lm_strerror());
goto next_list;
}
if(!do_update && !lm_pool_list_load(cur, tempdir)){
pdebug(__func__, "(%s) failed to load list: %s", cur->name, lm_strerror());
goto next_list;
}
else if(do_update && !lm_pool_list_download(cur, tempdir, __lm_ctx_sync_callback, &cbdata)) {
pdebug(__func__, "(%s) failed to update list: %s", cur->name, lm_strerror());
goto next_list;
}
pdebug(__func__, "(%s) loaded pool list", cur->name);
status = true;
next_list:
free(tempdir);
tempdir = NULL;
if(NULL != callback && status){
if(!callback(ctx, cur, SYNC_LIST_SUCCESS, 0, 0, data))
goto fail;
}
else if(NULL != callback && !status){
if(!callback(ctx, cur, SYNC_LIST_FAIL, 0, 0, data))
goto fail;
}
if(!status)
cur->loaded = false;
else
loaded_count++;
status = false;
cur = cur->next;
}
return loaded_count;
fail:
return -1;
}