#include "../../include/error.h" #include "../../include/pool.h" #include "../../include/util.h" #include "../../include/ctx.h" #include #include #include #include struct __lm_ctx_download_cb_data { lm_ctx_t *ctx; lm_pkg_t *pkg; lm_ctx_download_callback_t callback; void *data; }; bool __lm_ctx_download_callback(char *path, size_t current, size_t total, void *data){ struct __lm_ctx_download_cb_data *cbdata = data; if(NULL == cbdata->callback) return true; if(eq(cbdata->pkg->paths.archive, path)) return cbdata->callback(cbdata->ctx, cbdata->pkg, true, current, total, cbdata->data); else return cbdata->callback(cbdata->ctx, cbdata->pkg, false, current, total, cbdata->data); } bool lm_ctx_download(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_download_callback_t callback, void *data){ if(NULL == ctx || NULL == pkg){ lm_error_set(LM_ERR_ArgNULL); return false; } if(NULL == pkg->pool){ lm_error_set(LM_ERR_PkgNoPool); return false; } lm_pool_t *pool = pkg->pool; if(!pool->available){ lm_error_set(LM_ERR_PoolNotAvailable); return false; } char path[strlen(pool->url.path)+strlen(pkg->name)+strlen(pkg->version)+20]; char name[strlen(pkg->name)+strlen(pkg->version)+10]; struct __lm_ctx_download_cb_data cbdata = { .ctx = ctx, .pkg = pkg, .data = data, .callback = callback }; lm_mptp_t packet; bool ret = false; int sock = -1; snprintf(name, sizeof(name), "%s_%s", pkg->name, pkg->version); join(path, pool->url.path, name); if((sock = lm_mptp_client_connect(pool->url.host, pool->url.port)) < 0) return false; lm_mptp_init(&packet, true, MPTP_C2S_PULL, true); lm_mptp_set_host(&packet, pool->url.host); lm_mptp_set_data(&packet, path, strlen(path)); if(!lm_mptp_client_send(sock, &packet)) goto end; if(!lm_mptp_recvfile(sock, pkg->paths.archive, __lm_ctx_download_callback, &cbdata)) goto end; if(!lm_mptp_recvfile(sock, pkg->paths.signature, __lm_ctx_download_callback, &cbdata)) goto end; ret = true; end: lm_mptp_close(sock); return ret; }