Compare commits

..

No commits in common. "main" and "24.00" have entirely different histories.
main ... 24.00

40 changed files with 1106 additions and 1580 deletions

View File

@ -1,28 +0,0 @@
name: Build docker image
on:
push:
branches: ["main"]
env:
REGISTRY: git.matterlinux.xyz
IMAGE: ${{gitea.repository}}
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: "https://github.com/actions/checkout@v4"
- name: Login to container repo
uses: "https://github.com/docker/login-action@v1"
with:
registry: ${{env.REGISTRY}}
username: ${{gitea.actor}}
password: ${{secrets.PACKAGES_TOKEN}}
- name: Build image
run: |
docker build --tag ${{env.REGISTRY}}/${{env.IMAGE}}:latest .
docker push ${{env.REGISTRY}}/${{env.IMAGE}}:latest

View File

@ -12,6 +12,7 @@ CFLAGS = -O3 -fstack-protector-strong -fcf-protection=full -fstack-clash-protec
LIBS = -lpthread -lcrypto -larchive -linih -lgpgme -lsqlite3 LIBS = -lpthread -lcrypto -larchive -linih -lgpgme -lsqlite3
DEBUG = 0 DEBUG = 0
VERSION = 24.00
all: dist dist/libmp.so $(PO_OUTS) all: dist dist/libmp.so $(PO_OUTS)

View File

@ -1,7 +1,4 @@
# libmp | MatterLinux package management library # libmp | MatterLinux package management library
![](https://git.matterlinux.xyz/matter/libmp/actions/workflows/docker.yml/badge.svg)
The core library for [`matt`](https://git.matterlinux.xyz/Matter/matt), it has The core library for [`matt`](https://git.matterlinux.xyz/Matter/matt), it has
components for transferring, installing, updating and removing packages. components for transferring, installing, updating and removing packages.

View File

@ -39,7 +39,7 @@ int main(int argc, char *argv[]) {
printf("resolving package: %s (%s)...\n", pkg->data.name, pkg->data.version); printf("resolving package: %s (%s)...\n", pkg->data.name, pkg->data.version);
if ((list = lm_ctx_resolve(&ctx, pkg, true, NULL)) == NULL) { if ((list = lm_ctx_resolve(&ctx, pkg, NULL)) == NULL) {
printf("failed to resolve package: %s (%d)\n", lm_strerror(), lm_error()); printf("failed to resolve package: %s (%d)\n", lm_strerror(), lm_error());
goto end; goto end;
} }

View File

@ -19,19 +19,14 @@ int main(int argc, char *argv[]) {
goto end; goto end;
} }
if (lm_ctx_pool_add(&ctx, "test", "mptp://s.test.local", "./examples/test") == NULL) { if (lm_ctx_pool_add(&ctx, "test", "mptp://127.0.0.1:5858", "./examples/test") == NULL) {
printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error());
goto end;
}
if (lm_ctx_pool_add(&ctx, "test", "mptp://n.test.local", "/tmp/test") == NULL) {
printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error()); printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error());
goto end; goto end;
} }
lm_ctx_sync(&ctx, false, NULL, NULL); lm_ctx_sync(&ctx, false, NULL, NULL);
if (!lm_ctx_serve(&ctx, argv[1], 10, NULL, NULL, NULL)) { if (!lm_ctx_serve(&ctx, argv[1], 10, NULL, NULL)) {
printf("failed to serve the pools: %s (%d)\n", lm_strerror(), lm_error()); printf("failed to serve the pools: %s (%d)\n", lm_strerror(), lm_error());
goto end; goto end;
} }

View File

@ -22,7 +22,7 @@
// clang-format on // clang-format on
#define LM_VERSION "24.09" #define LM_VERSION "24.00"
#include "ctx.h" #include "ctx.h"
#include "error.h" #include "error.h"

View File

@ -3,7 +3,6 @@
#include "mptp.h" #include "mptp.h"
#include "pool.h" #include "pool.h"
#include <signal.h>
#include <stdbool.h> #include <stdbool.h>
typedef struct lm_ctx { typedef struct lm_ctx {
@ -23,9 +22,10 @@ typedef struct lm_ctx_list {
} lm_ctx_list_t; } lm_ctx_list_t;
typedef struct lm_ctx_resolve_list { typedef struct lm_ctx_resolve_list {
lm_pkg_t **packages; lm_pkg_t *resolving;
lm_pkg_t *cur; lm_pkg_t *packages;
ssize_t count, index; lm_pkg_t *cur;
ssize_t count;
} lm_ctx_resolve_list_t; } lm_ctx_resolve_list_t;
typedef struct lm_ctx_update_list { typedef struct lm_ctx_update_list {
@ -73,10 +73,10 @@ lm_ctx_list_t *lm_ctx_list(lm_ctx_t *ctx, lm_ctx_list_t *list); // returns the s
lm_pkg_t *lm_ctx_list_next(lm_ctx_list_t *list); // returns the next package in the list lm_pkg_t *lm_ctx_list_next(lm_ctx_list_t *list); // returns the next package in the list
void lm_ctx_list_free(lm_ctx_list_t *list); // frees the package list state void lm_ctx_list_free(lm_ctx_list_t *list); // frees the package list state
lm_ctx_resolve_list_t *lm_ctx_resolve(lm_ctx_t *ctx, lm_pkg_t *pkg, bool resolve_depends, lm_ctx_resolve_list_t *lm_ctx_resolve(
lm_ctx_resolve_list_t *list); // resolves a package and returns a list of packages lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_resolve_list_t *list); // resolves a package and returns a list of packages
lm_pkg_t *lm_ctx_resolve_next(lm_ctx_resolve_list_t *list); // returns the next package in the list 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 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_list(lm_ctx_t *ctx); // get a list of entries to update lm_ctx_update_list_t *lm_ctx_update_list(lm_ctx_t *ctx); // get a list of entries to update
lm_entry_t *lm_ctx_update_list_next(lm_ctx_update_list_t *list); // get the next entry in the update list lm_entry_t *lm_ctx_update_list_next(lm_ctx_update_list_t *list); // get the next entry in the update list
@ -93,11 +93,11 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
void *data); // installs/updates a single package void *data); // installs/updates a single package
bool lm_ctx_check( bool lm_ctx_check(
lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t callback, void *data); // checks a single package lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t callback, void *data); // checks a single package
ssize_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data); // syncs all the pools 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 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, __sighandler_t handler, lm_ctx_serve_callback_t callback, bool lm_ctx_serve(
void *data); // serves all the pools lm_ctx_t *ctx, char *addr, uint8_t threads, lm_ctx_serve_callback_t callback, void *data); // serves all the pools
//
/* ############################## /* ##############################
## temp directory fucntions ## ## temp directory fucntions ##
############################## */ ############################## */

View File

@ -4,26 +4,39 @@
#include <sqlite3.h> #include <sqlite3.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#define HASH_LEN 32 #define HASH_LEN 32
enum lm_query_index { enum lm_query_index {
QUERY_CREATE_TABLE = 0, QUERY_CREATE_ENTRY_TABLE = 0,
QUERY_INSERT_SINGLE = 1, QUERY_INSERT_ENTRY_SINGLE = 1,
QUERY_SELECT_SINGLE_1 = 2, QUERY_SELECT_ENTRY_SINGLE_1 = 2,
QUERY_SELECT_SINGLE_2 = 3, QUERY_SELECT_ENTRY_SINGLE_2 = 3,
QUERY_DELETE_SINGLE = 4, QUERY_DELETE_ENTRY_SINGLE = 4,
QUERY_SELECT_ALL = 5, QUERY_SELECT_ENTRY_ALL = 5,
QUERY_CREATE_FILE_TABLE = 6,
QUERY_INSERT_FILE_SINGLE = 7,
QUERY_DELETE_FILE_ALL = 8,
QUERY_DELETE_FILE_SINGLE = 9,
QUERY_SELECT_FILE_ALL = 10,
QUERY_SELECT_FILE_SINGLE = 11,
QUERY_UPDATE_FILE_1 = 12,
QUERY_UPDATE_FILE_2 = 13,
}; };
enum lm_columns { enum lm_columns {
COLUMN_NAME = 1, FILES_COLUMN_PATH = 1,
COLUMN_VERSION = 2, FILES_COLUMN_HASH = 2,
COLUMN_DESC = 3, FILES_COLUMN_KEEP = 3,
COLUMN_SIZE = 4, FILES_COLUMN_ENTRY = 4,
COLUMN_DEPENDS = 5,
ENTRIES_COLUMN_NAME = 1,
ENTRIES_COLUMN_VERSION = 2,
ENTRIES_COLUMN_DESC = 3,
ENTRIES_COLUMN_SIZE = 4,
ENTRIES_COLUMN_DEPENDS = 5,
}; };
extern char *queries[]; extern char *queries[];
@ -31,10 +44,13 @@ extern char *queries[];
typedef lm_pkg_data_t lm_entry_t; typedef lm_pkg_data_t lm_entry_t;
typedef struct lm_database { typedef struct lm_database {
sqlite3 *sql; sqlite3 *entries_db;
sqlite3_stmt *st; sqlite3_stmt *entries_st;
FILE *filesp;
char *dir; sqlite3 *files_db;
sqlite3_stmt *files_st;
char *dir;
} lm_database_t; } lm_database_t;
void lm_entry_init(lm_entry_t *entry); void lm_entry_init(lm_entry_t *entry);
@ -63,9 +79,8 @@ bool lm_database_files_next(
lm_database_t *db, lm_entry_t *entry, char **path, char **hash, bool *keep); // gets the next file of the entry lm_database_t *db, lm_entry_t *entry, char **path, char **hash, bool *keep); // gets the next file of the entry
bool lm_database_files_add( bool lm_database_files_add(
lm_database_t *db, lm_entry_t *entry, char *path, char *hash); // adds a file to the files database lm_database_t *db, lm_entry_t *entry, char *path, char *hash); // adds a file to the files database
bool lm_database_files_del( bool lm_database_files_del(lm_database_t *db, lm_entry_t *entry); // dels all files of belonging to a entry
lm_database_t *db, lm_entry_t *entry); // dels files belonging to an entry that is not set as KEEP bool lm_database_files_del_single(lm_database_t *db, char *path);
bool lm_database_files_del_all(lm_database_t *db, lm_entry_t *entry); // dels all files of belonging to an entry
void lm_database_files_next_free(lm_database_t *db, lm_entry_t *entry, char **path, char **hash, void lm_database_files_next_free(lm_database_t *db, lm_entry_t *entry, char **path, char **hash,
bool *keep); // frees resources used for lm_database_files_next bool *keep); // frees resources used for lm_database_files_next

View File

@ -81,7 +81,7 @@ typedef enum lm_error {
LM_ERR_DbFilesOpenFail = 80, LM_ERR_DbFilesOpenFail = 80,
LM_ERR_DbFilesDirFail = 81, LM_ERR_DbFilesDirFail = 81,
LM_ERR_DbFilesUnlinkFail = 82, LM_ERR_DbFilesUnlinkFail = 82,
LM_ERR_DbFilesRenameFail = 83, LM_ERR_DbFilesWriteFail = 83,
LM_ERR_DbKeepsNotFound = 84, LM_ERR_DbKeepsNotFound = 84,
LM_ERR_DbKeepsOpenFail = 85, LM_ERR_DbKeepsOpenFail = 85,
LM_ERR_DbKeepsDirFail = 86, LM_ERR_DbKeepsDirFail = 86,
@ -140,24 +140,11 @@ typedef enum lm_error {
LM_ERR_InstallSaveFail = 138, LM_ERR_InstallSaveFail = 138,
LM_ERR_FailMkdir = 139, LM_ERR_FailMkdir = 139,
LM_ERR_NotDir = 140, LM_ERR_NotDir = 140,
LM_ERR_NoRead = 141, LM_ERR_NoWrite = 141,
LM_ERR_PoolListBadDir = 142, LM_ERR_PoolListBadDir = 142,
LM_ERR_FileNotExist = 143, LM_ERR_FileNotExist = 143,
LM_ERR_FileNotLink = 144, LM_ERR_FileNotLink = 144,
LM_ERR_ArchiveSetFail = 145, LM_ERR_ArchiveSetFail = 145,
LM_ERR_ChdirFail = 146,
LM_ERR_ExtractRootChdirFail = 147,
LM_ERR_ExtractOldChdirFail = 148,
LM_ERR_MPTPAcceptFail = 149,
LM_ERR_MPTPListenFail = 150,
LM_ERR_PoolInfoBadName = 151,
LM_ERR_PoolInfoUnknown = 152,
LM_ERR_MPTPBadPath = 153,
LM_ERR_UnknownThread = 154,
LM_ERR_PkgBadVersion = 155,
LM_ERR_PkgDataMissing = 156,
LM_ERR_PoolListDataFail = 157,
LM_ERR_PoolListAddFail = 158,
} lm_error_t; } lm_error_t;
typedef struct lm_error_desc { typedef struct lm_error_desc {
@ -167,7 +154,6 @@ typedef struct lm_error_desc {
void lm_error_set(lm_error_t code, ...); void lm_error_set(lm_error_t code, ...);
void lm_error_clear(); void lm_error_clear();
void lm_error_init();
lm_error_t lm_error(); lm_error_t lm_error();
char *lm_strerror(); char *lm_strerror();

View File

@ -13,12 +13,9 @@
##################################### #####################################
# FLAGS # # FLAGS #
##################################### #####################################
# HOST SIZE | PATH SIZE # # HOST SIZE | DATA SIZE #
#####################################
# DATA SIZE #
##################################### #####################################
# HOST # # HOST #
# PATH #
# DATA # # DATA #
#...................................# #...................................#
@ -85,8 +82,7 @@
#define MPTP_VERSION_SUPPORTED 0 #define MPTP_VERSION_SUPPORTED 0
#define MPTP_CODE_MAX 3 #define MPTP_CODE_MAX 3
#define MPTP_DATA_MAX 4096 // generally this is the page size on x86_64 linux #define MPTP_DATA_MAX UINT8_MAX
#define MPTP_PATH_MAX UINT8_MAX
#define MPTP_HOST_MAX UINT8_MAX #define MPTP_HOST_MAX UINT8_MAX
#define MPTP_TIMEOUT 10 #define MPTP_TIMEOUT 10
@ -110,45 +106,34 @@ typedef enum lm_mptp_response {
typedef struct lm_mptp_header { typedef struct lm_mptp_header {
uint16_t flags; uint16_t flags;
uint8_t host_size; uint8_t host_size;
uint8_t path_size; uint8_t data_size;
uint16_t data_size; } lm_mptp_header_t;
} __attribute__((packed)) lm_mptp_header_t;
typedef struct lm_mptp { typedef struct lm_mptp {
lm_mptp_header_t header; lm_mptp_header_t header;
char *host, *path, *data; char host[MPTP_DATA_MAX];
char data[MPTP_DATA_MAX];
} lm_mptp_t; } lm_mptp_t;
typedef bool (*lm_mptp_transfer_callback_t)(char *path, size_t current, size_t total, void *data); typedef bool (*lm_mptp_transfer_callback_t)(char *path, size_t current, size_t total, void *data);
#define MPTP_FLAGS_VERSION(m) (((m)->header.flags >> 8) & 0xFF) #define MPTP_FLAGS_VERSION(m) (((m)->header.flags & 0xFF00) >> 8)
#define MPTP_FLAGS_TYPE(m) (((m)->header.flags >> 7) & 0x01) #define MPTP_FLAGS_TYPE(m) (((m)->header.flags & 0x0080) >> 1)
#define MPTP_FLAGS_CODE(m) (((m)->header.flags >> 3) & 0x0F) #define MPTP_FLAGS_CODE(m) (((m)->header.flags & 0x0070) >> 4)
#define MPTP_FLAGS_LAST(m) (((m)->header.flags >> 2) & 0x01) #define MPTP_FLAGS_LAST(m) (((m)->header.flags & 0x0008) >> 3)
#define MPTP_IS_REQUEST(m) (MPTP_FLAGS_TYPE(m) == 0) #define MPTP_IS_REQUEST(m) (MPTP_FLAGS_TYPE(m) == 0)
#define MPTP_IS_LAST(m) (MPTP_FLAGS_LAST(m) == 1) #define MPTP_IS_LAST(m) (MPTP_FLAGS_LAST(m) == 1)
void lm_mptp_init(lm_mptp_t *packet); bool lm_mptp_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last);
bool lm_mptp_new(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last); bool lm_mptp_set_data(lm_mptp_t *packet, char *data, size_t size);
void lm_mptp_free(lm_mptp_t *packet); bool lm_mptp_set_host(lm_mptp_t *packet, char *host);
bool lm_mptp_get_host(lm_mptp_t *packet, char *host);
bool lm_mptp_get_data(lm_mptp_t *packet, char *data);
int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr); int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr);
bool lm_mptp_socket_opts(int sock);
void lm_mptp_copy(lm_mptp_t *dst, lm_mptp_t *src); void lm_mptp_copy(lm_mptp_t *dst, lm_mptp_t *src);
bool lm_mptp_verify(lm_mptp_t *packet); bool lm_mptp_verify(lm_mptp_t *packet);
void lm_mptp_close(int sock); void lm_mptp_close(int sock);
bool lm_mptp_recv(int sock, lm_mptp_t *packet);
void lm_mptp_free(lm_mptp_t *packet);
bool lm_mptp_set_data(lm_mptp_t *packet, char *data, size_t size);
bool lm_mptp_get_data(lm_mptp_t *packet, char *data);
bool lm_mptp_set_host(lm_mptp_t *packet, char *host);
bool lm_mptp_get_host(lm_mptp_t *packet, char *host);
bool lm_mptp_set_path(lm_mptp_t *packet, char *path);
bool lm_mptp_get_path(lm_mptp_t *packet, char *path);
int lm_mptp_client_connect(char *addr, uint16_t port); int lm_mptp_client_connect(char *addr, uint16_t port);
bool lm_mptp_client_verify(lm_mptp_t *packet); bool lm_mptp_client_verify(lm_mptp_t *packet);
@ -156,11 +141,9 @@ bool lm_mptp_client_send(int sock, lm_mptp_t *packet);
bool lm_mptp_client_recv(int sock, lm_mptp_t *packet); bool lm_mptp_client_recv(int sock, lm_mptp_t *packet);
int lm_mptp_server_listen(char *addr, uint16_t port); int lm_mptp_server_listen(char *addr, uint16_t port);
int lm_mptp_server_accept(int sock, struct sockaddr *addr);
void lm_mptp_server_close(int sock);
bool lm_mptp_server_verify(lm_mptp_t *packet); bool lm_mptp_server_verify(lm_mptp_t *packet);
bool lm_mptp_server_recv(int sock, lm_mptp_t *packet); bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr);
bool lm_mptp_server_send(int sock, lm_mptp_t *packet); bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *addr);
bool lm_mptp_sendfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data); bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_transfer_callback_t callback, void *data);
bool lm_mptp_recvfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data); bool lm_mptp_recvfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data);

View File

@ -6,7 +6,7 @@
#define PKG_DATA_DESC "desc" #define PKG_DATA_DESC "desc"
#define PKG_DATA_VERSION "version" #define PKG_DATA_VERSION "version"
#define PKG_DATA_DEPENDS "depends" #define PKG_DATA_DEPENDS "depends"
#define PKG_DATA_KEEPS "keep" #define PKG_DATA_KEEPS "keeps"
#define DATA_FILE "DATA" #define DATA_FILE "DATA"
#define HASHES_FILE "HASHES" #define HASHES_FILE "HASHES"

View File

@ -8,9 +8,6 @@
#include <stdio.h> #include <stdio.h>
#define _(x) gettext(x) #define _(x) gettext(x)
#define BINARY(b) \
(b & 128 ? '1' : '0'), (b & 64 ? '1' : '0'), (b & 32 ? '1' : '0'), (b & 16 ? '1' : '0'), (b & 8 ? '1' : '0'), \
(b & 4 ? '1' : '0'), (b & 2 ? '1' : '0'), (b & 1 ? '1' : '0')
bool contains(char *str, char s); bool contains(char *str, char s);
bool eq(char *s1, char *s2); bool eq(char *s1, char *s2);
@ -30,21 +27,23 @@ bool exists(char *path, struct stat *st);
bool is_empty(char *p); bool is_empty(char *p);
bool is_dir_empty(char *p); bool is_dir_empty(char *p);
bool rmrf(char *p); bool rmrf(char *p);
int digits(int n);
bool package_parse(char *package, char *name, char *version); bool package_parse(char *package, char *name, char *version);
bool __package_field_valid(char *field); bool package_version_valid(char *name);
#define package_version_valid(x) __package_field_valid(x) bool package_name_valid(char *name);
#define package_name_valid(x) __package_field_valid(x)
void pdebug(const char *func, const char *fmt, ...); void pdebug(const char *func, const char *fmt, ...);
void pdebug_binary(char *data, size_t len);
bool parse_host(char *addr, char *host, uint16_t *port); bool parse_host(char *addr, char *host, uint16_t *port);
bool copy_blocks(struct archive *w, struct archive *r); bool copy_blocks(struct archive *w, struct archive *r);
bool extract_archive(char *dst, char *src); bool extract_archive(char *dst, char *src);
bool mkdir_ifnot(char *path, int mode); bool mkdir_ifnot(char *path);
int join_multiple(char *res, const char *base, const char *pth, const char *pth2); int join_multiple(char *res, const char *base, const char *pth, const char *pth2);
int join(char *res, const char *base, const char *pth); int join(char *res, const char *base, const char *pth);
char *join_alloc(const char *base, const char *pth); char *join_alloc(const char *base, const char *pth);
bool pkglist_contains(lm_pkg_t *list, lm_pkg_t *pkg);
lm_pkg_t *pkglist_del(lm_pkg_t *list, lm_pkg_t *pkg);
lm_pkg_t *pkglist_add_top(lm_pkg_t *list, lm_pkg_t *pkg);
lm_pkg_t *pkglist_add_end(lm_pkg_t *list, lm_pkg_t *pkg);
void pkglist_free(lm_pkg_t *list);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-25 14:07+0300\n" "POT-Creation-Date: 2024-08-06 04:34+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,667 +17,603 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: src/error.c:31 #: src/error.c:19
msgid "no error" msgid "no error"
msgstr "hata yok" msgstr "hata yok"
#: src/error.c:32 #: src/error.c:20
#, fuzzy #, fuzzy
msgid "URL contains an invalid character" msgid "URL contains an invalid character"
msgstr "URL contains an invalid char" msgstr "URL contains an invalid char"
#: src/error.c:33 #: src/error.c:21
msgid "URL does not have a valid protocol field" msgid "URL does not have a valid protocol field"
msgstr "URL does not have a valid protocol field" msgstr "URL does not have a valid protocol field"
#: src/error.c:34 #: src/error.c:22
msgid "URL is too large" msgid "URL is too large"
msgstr "URL is too large" msgstr "URL is too large"
#: src/error.c:35 #: src/error.c:23
msgid "URL hostname is too large" msgid "URL hostname is too large"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:36 #: src/error.c:24
msgid "URL path is too large" msgid "URL path is too large"
msgstr "URL path is too large" msgstr "URL path is too large"
#: src/error.c:37 #: src/error.c:25
msgid "URL does not have a valid hostname" msgid "URL does not have a valid hostname"
msgstr "URL does not have a valid hostname" msgstr "URL does not have a valid hostname"
#: src/error.c:38 #: src/error.c:26
#, fuzzy #, fuzzy
msgid "URL does not have a valid port number" msgid "URL does not have a valid port number"
msgstr "URL does not have a valid hostname" msgstr "URL does not have a valid hostname"
#: src/error.c:39 #: src/error.c:27
msgid "URL does not have a valid path" msgid "URL does not have a valid path"
msgstr "URL does not have a valid path" msgstr "URL does not have a valid path"
#: src/error.c:40 #: src/error.c:28
#, fuzzy #, fuzzy
msgid "hostname does not contain a valid port number" msgid "hostname does not contain a valid port number"
msgstr "URL does not contain a hostname with a valid port number" msgstr "URL does not contain a hostname with a valid port number"
#: src/error.c:41 #: src/error.c:29
#, fuzzy #, fuzzy
msgid "hostname is not valid" msgid "hostname is not valid"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:42 #: src/error.c:30
msgid "URL protocol port number is unknown" msgid "URL protocol port number is unknown"
msgstr "URL protocol port number is unknown" msgstr "URL protocol port number is unknown"
#: src/error.c:43 #: src/error.c:31
msgid "URL is incomplete" msgid "URL is incomplete"
msgstr "URL tamamlanmamış" msgstr "URL tamamlanmamış"
#: src/error.c:44 #: src/error.c:32
msgid "pool does not support the specified protocol" msgid "pool does not support the specified protocol"
msgstr "pool does not support the specified protocol" msgstr "pool does not support the specified protocol"
#: src/error.c:45 #: src/error.c:33
msgid "unsupported MPTP version" msgid "unsupported MPTP version"
msgstr "" msgstr ""
#: src/error.c:46 #: src/error.c:34
msgid "invalid MPTP request/response code" msgid "invalid MPTP request/response code"
msgstr "" msgstr ""
#: src/error.c:47 #: src/error.c:35
msgid "invalid MPTP URL" msgid "invalid MPTP URL"
msgstr "" msgstr ""
#: src/error.c:48 #: src/error.c:36
msgid "failed to resolve hostname for MPTP connection" msgid "failed to resolve hostname for MPTP connection"
msgstr "" msgstr ""
#: src/error.c:49 #: src/error.c:37
msgid "failed to create a MPTP socket" msgid "failed to create a MPTP socket"
msgstr "" msgstr ""
#: src/error.c:50 #: src/error.c:38
msgid "failed to connect to the MPTP host" msgid "failed to connect to the MPTP host"
msgstr "" msgstr ""
#: src/error.c:51 #: src/error.c:39
#, c-format msgid "failed receive MPTP data from host"
msgid "failed receive MPTP data from host: %s"
msgstr "" msgstr ""
#: src/error.c:52 #: src/error.c:40
msgid "failed send MPTP data to host" msgid "failed send MPTP data to host"
msgstr "" msgstr ""
#: src/error.c:53 #: src/error.c:41
#, fuzzy #, fuzzy
msgid "MPTP data size is invalid" msgid "MPTP data size is invalid"
msgstr "URL path is too large" msgstr "URL path is too large"
#: src/error.c:54 #: src/error.c:42
#, fuzzy #, fuzzy
msgid "MPTP host size is invalid" msgid "MPTP host size is invalid"
msgstr "URL path is too large" msgstr "URL path is too large"
#: src/error.c:55 #: src/error.c:43
#, fuzzy
msgid "MPTP path size is invalid"
msgstr "URL path is too large"
#: src/error.c:56
msgid "failed to set MPTP socket options" msgid "failed to set MPTP socket options"
msgstr "" msgstr ""
#: src/error.c:57 #: src/error.c:44
msgid "MPTP connection timed out" msgid "MPTP connection timed out"
msgstr "" msgstr ""
#: src/error.c:58 #: src/error.c:45
#, c-format msgid "failed to bind MPTP socket"
msgid "failed to bind MPTP socket: %s"
msgstr "" msgstr ""
#: src/error.c:59 #: src/error.c:46
msgid "required argument is a NULL pointer or 0" msgid "required argument is a NULL pointer or 0"
msgstr "" msgstr ""
#: src/error.c:60 #: src/error.c:47
msgid "not a MPTP request" msgid "not a MPTP request"
msgstr "" msgstr ""
#: src/error.c:61 #: src/error.c:48
msgid "not a MPTP response" msgid "not a MPTP response"
msgstr "" msgstr ""
#: src/error.c:62 src/error.c:63 #: src/error.c:49 src/error.c:50
msgid "MPTP request last flag is not set" msgid "MPTP request last flag is not set"
msgstr "" msgstr ""
#: src/error.c:64 #: src/error.c:51
msgid "host port not specified" msgid "host port not specified"
msgstr "" msgstr ""
#: src/error.c:65 #: src/error.c:52
msgid "pool info is badly formatted or is not complete" msgid "pool info is badly formatted or is not complete"
msgstr "" msgstr ""
#: src/error.c:66 #: src/error.c:53
msgid "failed to write block from archive" msgid "failed to write block from archive"
msgstr "" msgstr ""
#: src/error.c:67 #: src/error.c:54
msgid "failed to read block from archive" msgid "failed to read block from archive"
msgstr "" msgstr ""
#: src/error.c:68 #: src/error.c:55
msgid "failed to open archive" msgid "failed to open archive"
msgstr "" msgstr ""
#: src/error.c:69 #: src/error.c:56
msgid "failed to write archive header" msgid "failed to write archive header"
msgstr "" msgstr ""
#: src/error.c:70 #: src/error.c:57
msgid "failed to finish writing the archive entry" msgid "failed to finish writing the archive entry"
msgstr "" msgstr ""
#: src/error.c:71 #: src/error.c:58
msgid "failed to create new archive reader/writer" msgid "failed to create new archive reader/writer"
msgstr "" msgstr ""
#: src/error.c:72 #: src/error.c:59
msgid "failed to resolve full path for archive file" msgid "failed to resolve full path for archive file"
msgstr "" msgstr ""
#: src/error.c:73 #: src/error.c:60
msgid "failed to read the next header of the archive" msgid "failed to read the next header of the archive"
msgstr "" msgstr ""
#: src/error.c:74 #: src/error.c:61
msgid "failed to obtain current working directory" msgid "failed to obtain current working directory"
msgstr "" msgstr ""
#: src/error.c:75 #: src/error.c:62
msgid "failed to open extracted pool list directory" msgid "failed to open extracted pool list directory"
msgstr "" msgstr ""
#: src/error.c:76 #: src/error.c:63
#, c-format
msgid "failed to load \"%s\" data: %s"
msgstr ""
#: src/error.c:77
#, c-format
msgid "failed add \"%s\" to the pool list: %s"
msgstr ""
#: src/error.c:78
msgid "failed to read access the pool list file" msgid "failed to read access the pool list file"
msgstr "" msgstr ""
#: src/error.c:79 #: src/error.c:64
msgid "failed to read access the pool info file" msgid "failed to read access the pool info file"
msgstr "" msgstr ""
#: src/error.c:80 #: src/error.c:65
msgid "failed to parse package data" msgid "failed to parse package data"
msgstr "" msgstr ""
#: src/error.c:81 #: src/error.c:66
#, fuzzy #, fuzzy
msgid "package name is invalid" msgid "package name is invalid"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:82 #: src/error.c:67
#, fuzzy
msgid "package version is invalid"
msgstr "URL hostname is too large"
#: src/error.c:83
#, c-format
msgid "package data has missing field: %s"
msgstr ""
#: src/error.c:84
msgid "data path is not set with in the ctx" msgid "data path is not set with in the ctx"
msgstr "" msgstr ""
#: src/error.c:85 #: src/error.c:68
msgid "temp path is not set with in the ctx" msgid "temp path is not set with in the ctx"
msgstr "" msgstr ""
#: src/error.c:86 #: src/error.c:69
msgid "root path is not set with in the ctx" msgid "root path is not set with in the ctx"
msgstr "" msgstr ""
#: src/error.c:87 #: src/error.c:70
#, c-format #, c-format
msgid "failed to set the ctx temp director to %s: %s" msgid "failed to set the ctx temp director to %s: %s"
msgstr "" msgstr ""
#: src/error.c:88 #: src/error.c:71
#, c-format #, c-format
msgid "failed to set the ctx root directory to %s: %s" msgid "failed to set the ctx root directory to %s: %s"
msgstr "" msgstr ""
#: src/error.c:89 #: src/error.c:72
#, c-format #, c-format
msgid "failed to set the ctx data directory to %s: %s" msgid "failed to set the ctx data directory to %s: %s"
msgstr "" msgstr ""
#: src/error.c:90 #: src/error.c:73
msgid "pool did not respond ping with pong" msgid "pool did not respond ping with pong"
msgstr "" msgstr ""
#: src/error.c:91 #: src/error.c:74
msgid "package file and directory paths are empty" msgid "package file and directory paths are empty"
msgstr "" msgstr ""
#: src/error.c:92 #: src/error.c:75
msgid "failed to to open target file for sending" msgid "failed to to open target file for sending"
msgstr "" msgstr ""
#: src/error.c:93 #: src/error.c:76
msgid "failed to to delete target file for receiving" msgid "failed to to delete target file for receiving"
msgstr "" msgstr ""
#: src/error.c:94 #: src/error.c:77
msgid "failed to to open target file for receiving" msgid "failed to to open target file for receiving"
msgstr "" msgstr ""
#: src/error.c:95 #: src/error.c:78
msgid "got a bad response code for receiving the target file" msgid "got a bad response code for receiving the target file"
msgstr "" msgstr ""
#: src/error.c:96 #: src/error.c:79
msgid "failed to write to the target file for receiving" msgid "failed to write to the target file for receiving"
msgstr "" msgstr ""
#: src/error.c:97 #: src/error.c:80
#, fuzzy #, fuzzy
msgid "package not found" msgid "package not found"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:98 #: src/error.c:81
msgid "failed to access to the database file/directory" msgid "failed to access to the database file/directory"
msgstr "" msgstr ""
#: src/error.c:99 #: src/error.c:82
msgid "failed to open SQLite database" msgid "failed to open SQLite database"
msgstr "" msgstr ""
#: src/error.c:100 #: src/error.c:83
msgid "failed to create table in SQLite database" msgid "failed to create table in SQLite database"
msgstr "" msgstr ""
#: src/error.c:101 #: src/error.c:84
msgid "failed to prepare statement for SQLite database" msgid "failed to prepare statement for SQLite database"
msgstr "" msgstr ""
#: src/error.c:102 #: src/error.c:85
msgid "failed to insert to the table in SQLite database" msgid "failed to insert to the table in SQLite database"
msgstr "" msgstr ""
#: src/error.c:103 #: src/error.c:86
msgid "failed to select from the table in SQLite database" msgid "failed to select from the table in SQLite database"
msgstr "" msgstr ""
#: src/error.c:104 #: src/error.c:87
msgid "failed to delete from the table in SQLite database" msgid "failed to delete from the table in SQLite database"
msgstr "" msgstr ""
#: src/error.c:105 #: src/error.c:88
msgid "failed to find entry in SQLite database" msgid "failed to find entry in SQLite database"
msgstr "" msgstr ""
#: src/error.c:106 #: src/error.c:89
msgid "failed to init GPG for package verification" msgid "failed to init GPG for package verification"
msgstr "" msgstr ""
#: src/error.c:107 #: src/error.c:90
msgid "failed to import signature to GPG for package verification" msgid "failed to import signature to GPG for package verification"
msgstr "" msgstr ""
#: src/error.c:108 #: src/error.c:91
msgid "failed to import archive to GPG for package verification" msgid "failed to import archive to GPG for package verification"
msgstr "" msgstr ""
#: src/error.c:109 #: src/error.c:92
msgid "package signature verification failed with zero matches" msgid "package signature verification failed with zero matches"
msgstr "" msgstr ""
#: src/error.c:110 #: src/error.c:93
msgid "package signature verification failed with zero results" msgid "package signature verification failed with zero results"
msgstr "" msgstr ""
#: src/error.c:111 #: src/error.c:94
msgid "pool file and directory paths are empty" msgid "pool file and directory paths are empty"
msgstr "" msgstr ""
#: src/error.c:112 #: src/error.c:95
msgid "pool is not avaliable for connection" msgid "pool is not avaliable for connection"
msgstr "" msgstr ""
#: src/error.c:113 #: src/error.c:96
msgid "pool URL is empty or invalid" msgid "pool URL is empty or invalid"
msgstr "" msgstr ""
#: src/error.c:114 #: src/error.c:97
msgid "pool directory path is not accessible" msgid "pool directory path is not accessible"
msgstr "" msgstr ""
#: src/error.c:115 #: src/error.c:98
msgid "pool directory sub-paths are not accessible" msgid "pool directory sub-paths are not accessible"
msgstr "" msgstr ""
#: src/error.c:116 #: src/error.c:99
msgid "file list not found for the package" msgid "package file list not found in the database"
msgstr "" msgstr ""
#: src/error.c:117 #: src/error.c:100
#, c-format msgid "failed to open package file list in the database"
msgid "failed to rename the file list for the package: %s"
msgstr "" msgstr ""
#: src/error.c:118 #: src/error.c:101
#, c-format msgid "failed to access package file list database directory"
msgid "failed to open the package file list: %s"
msgstr "" msgstr ""
#: src/error.c:119 #: src/error.c:102
#, c-format msgid "failed to remove package file list from the database"
msgid "failed to open the database directory: %s"
msgstr "" msgstr ""
#: src/error.c:120 #: src/error.c:103
#, c-format msgid "failed to write to the file list in the database"
msgid "failed to remove package file list: %s"
msgstr "" msgstr ""
#: src/error.c:121 #: src/error.c:104
msgid "package keep list not found in the database" msgid "package keep list not found in the database"
msgstr "" msgstr ""
#: src/error.c:122 #: src/error.c:105
msgid "failed to open package keep list in the database" msgid "failed to open package keep list in the database"
msgstr "" msgstr ""
#: src/error.c:123 #: src/error.c:106
msgid "failed to access package keep list database directory" msgid "failed to access package keep list database directory"
msgstr "" msgstr ""
#: src/error.c:124 #: src/error.c:107
msgid "failed to remove package keep list from the database" msgid "failed to remove package keep list from the database"
msgstr "" msgstr ""
#: src/error.c:125 #: src/error.c:108
#, c-format #, c-format
msgid "failed to find %s (dependency of %s)" msgid "failed to find %s (dependency of %s)"
msgstr "" msgstr ""
#: src/error.c:126 #: src/error.c:109
#, c-format #, c-format
msgid "failed to download %s for installation: %s" msgid "failed to download %s for installation: %s"
msgstr "" msgstr ""
#: src/error.c:127 #: src/error.c:110
#, fuzzy #, fuzzy
msgid "package is not downloaded" msgid "package is not downloaded"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:128 src/error.c:129 #: src/error.c:111 src/error.c:112
msgid "failed to remove downloaded package" msgid "failed to remove downloaded package"
msgstr "" msgstr ""
#: src/error.c:130 #: src/error.c:113
msgid "failed to open the destination file" msgid "failed to open the destination file"
msgstr "" msgstr ""
#: src/error.c:131 #: src/error.c:114
msgid "failed to open the source file" msgid "failed to open the source file"
msgstr "" msgstr ""
#: src/error.c:132 src/error.c:133 #: src/error.c:115 src/error.c:116
msgid "failed to write to the destination file" msgid "failed to write to the destination file"
msgstr "" msgstr ""
#: src/error.c:134 #: src/error.c:117
msgid "package does not have associated pool" msgid "package does not have associated pool"
msgstr "" msgstr ""
#: src/error.c:135 #: src/error.c:118
msgid "failed to create specified temp directory" msgid "failed to create specified temp directory"
msgstr "" msgstr ""
#: src/error.c:136 #: src/error.c:119
msgid "package archive does not contain required files" msgid "package archive does not contain required files"
msgstr "" msgstr ""
#: src/error.c:137 #: src/error.c:120
msgid "package data does not match with target package" msgid "package data does not match with target package"
msgstr "" msgstr ""
#: src/error.c:138 #: src/error.c:121
#, c-format #, c-format
msgid "failed to update changes file for package: %s" msgid "failed to update changes file for package: %s"
msgstr "" msgstr ""
#: src/error.c:139 #: src/error.c:122
msgid "failed to access package hashes file" msgid "failed to access package hashes file"
msgstr "" msgstr ""
#: src/error.c:140 #: src/error.c:123
msgid "failed to remove package changes file from the database" msgid "failed to remove package changes file from the database"
msgstr "" msgstr ""
#: src/error.c:141 #: src/error.c:124
msgid "failed to stat target file for sending" msgid "failed to stat target file for sending"
msgstr "" msgstr ""
#: src/error.c:142 #: src/error.c:125
msgid "failed to format target file size for sending" msgid "failed to format target file size for sending"
msgstr "" msgstr ""
#: src/error.c:143 #: src/error.c:126
msgid "failed to read target file size for sending" msgid "failed to read target file size for sending"
msgstr "" msgstr ""
#: src/error.c:144 #: src/error.c:127
msgid "failed to parse target file size for receiving" msgid "failed to parse target file size for receiving"
msgstr "" msgstr ""
#: src/error.c:145 #: src/error.c:128
msgid "target file is not fully received" msgid "target file is not fully received"
msgstr "" msgstr ""
#: src/error.c:146 #: src/error.c:129
msgid "failed to stat for target extract archive" msgid "failed to stat for target extract archive"
msgstr "" msgstr ""
#: src/error.c:147 #: src/error.c:130
#, c-format #, c-format
msgid "failed to add package file (%s) to the database: %s" msgid "failed to add package file (%s) to the database: %s"
msgstr "" msgstr ""
#: src/error.c:148 #: src/error.c:131
#, c-format #, c-format
msgid "failed to extract package files: %s" msgid "failed to extract package files: %s"
msgstr "" msgstr ""
#: src/error.c:149 #: src/error.c:132
#, c-format #, c-format
msgid "failed to add package to the database: %s" msgid "failed to add package to the database: %s"
msgstr "" msgstr ""
#: src/error.c:150 #: src/error.c:133
#, fuzzy #, fuzzy
msgid "package is already installed" msgid "package is already installed"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:151 #: src/error.c:134
#, fuzzy #, fuzzy
msgid "package is not installed" msgid "package is not installed"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:152 #: src/error.c:135
#, c-format #, c-format
msgid "failed to remove package file (%s): %s" msgid "failed to remove package file (%s): %s"
msgstr "" msgstr ""
#: src/error.c:153 #: src/error.c:136
#, c-format #, c-format
msgid "failed to remove package from the database: %s" msgid "failed to remove package from the database: %s"
msgstr "" msgstr ""
#: src/error.c:154 #: src/error.c:137
#, c-format #, c-format
msgid "failed to remove package files from the database: %s" msgid "failed to remove package files from the database: %s"
msgstr "" msgstr ""
#: src/error.c:155 #: src/error.c:138
#, c-format #, c-format
msgid "failed to remove changes file for package: %s" msgid "failed to remove changes file for package: %s"
msgstr "" msgstr ""
#: src/error.c:156 #: src/error.c:139
msgid "failed to get current directory for running install" msgid "failed to get current directory for running install"
msgstr "" msgstr ""
#: src/error.c:157 #: src/error.c:140
msgid "failed change directory to root for running install" msgid "failed change directory to root for running install"
msgstr "" msgstr ""
#: src/error.c:158 #: src/error.c:141
msgid "failed run install spawn command" msgid "failed run install spawn command"
msgstr "" msgstr ""
#: src/error.c:160 #: src/error.c:143
msgid "failed to change directory to old directory after running install" msgid "failed to change directory to old directory after running install"
msgstr "" msgstr ""
#: src/error.c:161 #: src/error.c:144
msgid "install script returned a bad status code" msgid "install script returned a bad status code"
msgstr "" msgstr ""
#: src/error.c:162 #: src/error.c:145
#, c-format #, c-format
msgid "failed to run the package install script: %s" msgid "failed to run the package install script: %s"
msgstr "" msgstr ""
#: src/error.c:163 #: src/error.c:146
#, c-format #, c-format
msgid "failed to save the package install script: %s" msgid "failed to save the package install script: %s"
msgstr "" msgstr ""
#: src/error.c:164 #: src/error.c:147
#, c-format #, c-format
msgid "removing package breaks %s" msgid "removing package breaks %s"
msgstr "" msgstr ""
#: src/error.c:165 #: src/error.c:148
#, fuzzy #, fuzzy
msgid "package is already up-to-date" msgid "package is already up-to-date"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:166 #: src/error.c:149
msgid "failed to open file for hashing" msgid "failed to open file for hashing"
msgstr "" msgstr ""
#: src/error.c:167 #: src/error.c:150
msgid "failed create digest for hashing" msgid "failed create digest for hashing"
msgstr "" msgstr ""
#: src/error.c:168 #: src/error.c:151
#, c-format #, c-format
msgid "failed to get hash of %s: %s" msgid "failed to get hash of %s: %s"
msgstr "" msgstr ""
#: src/error.c:169 #: src/error.c:152
#, c-format #, c-format
msgid "file hash does not match for %s" msgid "file hash does not match for %s"
msgstr "" msgstr ""
#: src/error.c:170 #: src/error.c:153
#, fuzzy #, fuzzy
msgid "pool info is not loaded" msgid "pool info is not loaded"
msgstr "URL hostname is too large" msgstr "URL hostname is too large"
#: src/error.c:171 #: src/error.c:154
msgid "pool list is empty" msgid "pool list is empty"
msgstr "" msgstr ""
#: src/error.c:172 #: src/error.c:155
msgid "package changes file not found in the database" msgid "package changes file not found in the database"
msgstr "" msgstr ""
#: src/error.c:173 #: src/error.c:156
msgid "failed to change mod of the changes file" msgid "failed to change mod of the changes file"
msgstr "" msgstr ""
#: src/error.c:174 #: src/error.c:157
msgid "failed to create install script save directory" msgid "failed to create install script save directory"
msgstr "" msgstr ""
#: src/error.c:175 #: src/error.c:158
msgid "directory does not have read permissions" msgid "directory does not have write permissions"
msgstr "" msgstr ""
#: src/error.c:176 #: src/error.c:159
msgid "specified path is not a directory" msgid "specified path is not a directory"
msgstr "" msgstr ""
#: src/error.c:177 #: src/error.c:160
msgid "failed to create the specified directory" msgid "failed to create the specified directory"
msgstr "" msgstr ""
#: src/error.c:178 #: src/error.c:161
msgid "specified list extraction directory is not accessible" msgid "specified list extraction directory is not accessible"
msgstr "" msgstr ""
#: src/error.c:179 #: src/error.c:162
#, c-format #, c-format
msgid "file does not exist: %s" msgid "file does not exist: %s"
msgstr "" msgstr ""
#: src/error.c:180 #: src/error.c:163
#, c-format #, c-format
msgid "file is a symbolic link: %s" msgid "file is a symbolic link: %s"
msgstr "" msgstr ""
#: src/error.c:181 #: src/error.c:164
msgid "failed to set the package archive" msgid "failed to set the package archive"
msgstr "" msgstr ""
#: src/error.c:182
#, c-format
msgid "failed change directory: %s"
msgstr ""
#: src/error.c:183
msgid "failed to change directory to root during extraction"
msgstr ""
#: src/error.c:184
msgid "failed to change directory back from root during extraction"
msgstr ""
#: src/error.c:185
#, c-format
msgid "failed to accept the MPTP connection: %s"
msgstr ""
#: src/error.c:186
#, c-format
msgid "failed to listen the MPTP socket: %s"
msgstr ""
#: src/error.c:187
#, c-format
msgid "pool name (%s) doesn't match with: %s"
msgstr ""
#: src/error.c:188
#, c-format
msgid "unknown key in the configuration: %s"
msgstr ""

View File

@ -47,8 +47,7 @@ bool lm_ctx_check(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t call
if(S_ISLNK(st.st_mode)){ if(S_ISLNK(st.st_mode)){
pdebug(__func__, "%s seems to be a link, no hash verification to do", fp); pdebug(__func__, "%s seems to be a link, no hash verification to do", fp);
// hashes for links are just "#" chars if(hash[0] != '\0'){
if(hash[0] != '#'){
lm_error_set(LM_ERR_FileNotLink, fp); lm_error_set(LM_ERR_FileNotLink, fp);
goto end; goto end;
} }

View File

@ -3,16 +3,15 @@
#include "../../include/ctx.h" #include "../../include/ctx.h"
#include <linux/limits.h> #include <linux/limits.h>
#include <strings.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <locale.h> #include <locale.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <strings.h>
bool __lm_ctx_init_checkdir(char *path){ bool __lm_ctx_init_checkdir(char *path){
if(!mkdir_ifnot(path, 0755)){ if(!mkdir_ifnot(path)){
lm_error_set(LM_ERR_FailMkdir); lm_error_set(LM_ERR_FailMkdir);
return false; return false;
} }
@ -22,8 +21,8 @@ bool __lm_ctx_init_checkdir(char *path){
return false; return false;
} }
if(!can_read(path)){ if(!can_write(path)){
lm_error_set(LM_ERR_NoRead); lm_error_set(LM_ERR_NoWrite);
return false; return false;
} }
@ -41,7 +40,7 @@ bool lm_ctx_init(lm_ctx_t *ctx) {
bzero(ctx, sizeof(lm_ctx_t)); bzero(ctx, sizeof(lm_ctx_t));
ctx->version = LM_VERSION; ctx->version = LM_VERSION;
lm_error_init(); lm_error_clear();
return true; return true;
} }
@ -64,12 +63,6 @@ bool lm_ctx_new(lm_ctx_t *ctx, char *root_dir, char *temp_dir, char *data_dir) {
goto end; goto end;
} }
if(root_dir != NULL && !can_write(root_dir)){
pdebug(__func__, "check failed for specified root directory: %s", lm_strerror());
lm_error_set(LM_ERR_CtxRootFail, root_dir, "directory is not writeable");
goto end;
}
if(root_dir != NULL) if(root_dir != NULL)
ctx->root = realpath(root_dir, NULL); ctx->root = realpath(root_dir, NULL);
@ -101,8 +94,6 @@ end:
void lm_ctx_free(lm_ctx_t *ctx) { void lm_ctx_free(lm_ctx_t *ctx) {
lm_ctx_pool_clear(ctx); lm_ctx_pool_clear(ctx);
lm_ctx_temp_clear(ctx);
free(ctx->data); free(ctx->data);
free(ctx->root); free(ctx->root);
free(ctx->temp); free(ctx->temp);

View File

@ -65,9 +65,9 @@ bool lm_ctx_download(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_download_callback_t ca
if((sock = lm_mptp_client_connect(pool->url.host, pool->url.port)) < 0) if((sock = lm_mptp_client_connect(pool->url.host, pool->url.port)) < 0)
return false; return false;
lm_mptp_new(&packet, true, MPTP_C2S_PULL, true); lm_mptp_init(&packet, true, MPTP_C2S_PULL, true);
lm_mptp_set_host(&packet, pool->url.host); lm_mptp_set_host(&packet, pool->url.host);
lm_mptp_set_path(&packet, path); lm_mptp_set_data(&packet, path, strlen(path));
if(!lm_mptp_client_send(sock, &packet)) if(!lm_mptp_client_send(sock, &packet))
goto end; goto end;
@ -83,7 +83,6 @@ bool lm_ctx_download(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_download_callback_t ca
ret = true; ret = true;
end: end:
lm_mptp_free(&packet);
lm_mptp_close(sock); lm_mptp_close(sock);
return ret; return ret;
} }

View File

@ -20,7 +20,8 @@ bool __lm_ctx_save_install(lm_ctx_t *ctx, lm_pkg_t *pkg, char *install_path){
return false; return false;
} }
if(!exists(install_path, NULL) || is_empty(install_path)) // no need to save empty install script :)
if(is_empty(install_path))
return true; return true;
char script_name[strlen(pkg->data.name)+15]; char script_name[strlen(pkg->data.name)+15];
@ -29,7 +30,7 @@ bool __lm_ctx_save_install(lm_ctx_t *ctx, lm_pkg_t *pkg, char *install_path){
sprintf(script_name, "install_%s", pkg->data.name); sprintf(script_name, "install_%s", pkg->data.name);
join(script_dir, ctx->data, "scripts"); join(script_dir, ctx->data, "scripts");
if(!mkdir_ifnot(script_dir, 0755)){ if(!mkdir_ifnot(script_dir)){
lm_error_set(LM_ERR_InstallDirFail); lm_error_set(LM_ERR_InstallDirFail);
return false; return false;
} }
@ -41,7 +42,8 @@ bool __lm_ctx_save_install(lm_ctx_t *ctx, lm_pkg_t *pkg, char *install_path){
} }
bool __lm_ctx_run_install(char *root, char *install_path) { bool __lm_ctx_run_install(char *root, char *install_path) {
if(!exists(install_path, NULL) || is_empty(install_path)) // no need to run empty install script :)
if(is_empty(install_path))
return true; return true;
char *args[] = {"/bin/bash", install_path, NULL}, *oldpwd = NULL; char *args[] = {"/bin/bash", install_path, NULL}, *oldpwd = NULL;
@ -105,10 +107,7 @@ bool __lm_ctx_extract_files(lm_ctx_t *ctx, lm_pkg_t *pkg, char *files, lm_ctx_in
goto end; goto end;
} }
if(chdir(ctx->root) < 0){ chdir(ctx->root);
lm_error_set(LM_ERR_ExtractRootChdirFail);
goto end;
}
flags = ARCHIVE_EXTRACT_PERM; flags = ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_UNLINK; flags |= ARCHIVE_EXTRACT_UNLINK;
@ -137,14 +136,14 @@ bool __lm_ctx_extract_files(lm_ctx_t *ctx, lm_pkg_t *pkg, char *files, lm_ctx_in
current += archive_entry_size(entry); current += archive_entry_size(entry);
type = archive_entry_filetype(entry); type = archive_entry_filetype(entry);
if(exists(entry_path, NULL) && lm_package_data_keep_contains(&pkg->data, entry_path)){ if(exists(entry_path, NULL) && lm_database_files_iskeep(ctx->db, entry_path)){
pdebug(__func__, "not extracting %s, file is set as KEEP", entry_path); pdebug(__func__, "not extracting %s, file is set as KEEP", entry_path);
continue; continue;
} }
switch (type) { switch (type) {
case AE_IFLNK: case AE_IFLNK:
if(!lm_database_files_add(ctx->db, &pkg->data, "################################", entry_path)){ if(!lm_database_files_add(ctx->db, &pkg->data, entry_path, "")){
char *suberr = lm_strerror_dup(); char *suberr = lm_strerror_dup();
pdebug(__func__, "failed to add link to the database for %s: %s", pkg->data.name, suberr); pdebug(__func__, "failed to add link to the database for %s: %s", pkg->data.name, suberr);
lm_error_set(LM_ERR_PkgFilesAddFail, entry_path, suberr); lm_error_set(LM_ERR_PkgFilesAddFail, entry_path, suberr);
@ -203,10 +202,7 @@ end:
} }
if (NULL != oldpwd) { if (NULL != oldpwd) {
if(chdir(oldpwd) < 0){ chdir(oldpwd);
lm_error_set(LM_ERR_ExtractOldChdirFail);
ret = false;
}
free(oldpwd); free(oldpwd);
} }
@ -229,8 +225,10 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
return false; return false;
} }
if(!lm_ctx_temp_clear(ctx)) if(!mkdir_ifnot(ctx->temp)){
return false; // error set by function lm_error_set(LM_ERR_CtxTempFailMkdir);
return false;
}
if(!lm_ctx_database_init(ctx)) if(!lm_ctx_database_init(ctx))
return false; // error set by function return false; // error set by function
@ -268,8 +266,6 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
lm_error_set(LM_ERR_PkgDataNotMatch); lm_error_set(LM_ERR_PkgDataNotMatch);
goto end; goto end;
} }
pdebug(__func__, "updating changes file for %s", pkg->data.name);
if(!lm_database_changes_update(ctx->db, &pkg->data, files->changes_file)){ if(!lm_database_changes_update(ctx->db, &pkg->data, files->changes_file)){
char *suberr = lm_strerror_dup(); char *suberr = lm_strerror_dup();
@ -284,13 +280,6 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
goto end; goto end;
} }
pdebug(__func__, "deleting file list for %s", pkg->data.name);
if(!lm_database_files_del_all(ctx->db, &pkg->data)){
pdebug(__func__, "failed to remove file list for %s: %s", pkg->data.name, lm_error());
goto end;
}
while((line_len = getline(&line, (size_t*)&line_len, hashes)) > 0){ while((line_len = getline(&line, (size_t*)&line_len, hashes)) > 0){
if(NULL == line) if(NULL == line)
goto next; goto next;
@ -313,7 +302,12 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
pdebug(__func__, "(%lu) %s => %s", line_len, file, hash); pdebug(__func__, "(%lu) %s => %s", line_len, file, hash);
if(!lm_database_files_add(ctx->db, &pkg->data, hash, file)){ if(!lm_database_files_del_single(ctx->db, file)){
pdebug(__func__, "failed to remove file from the database for %s: %s", pkg->data.name, lm_error());
goto end;
}
if(!lm_database_files_add(ctx->db, &pkg->data, file, hash)){
char *suberr = lm_strerror_dup(); char *suberr = lm_strerror_dup();
pdebug(__func__, "failed to add file to the database for %s: %s", pkg->data.name, suberr); pdebug(__func__, "failed to add file to the database for %s: %s", pkg->data.name, suberr);
lm_error_set(LM_ERR_PkgFilesAddFail, file, suberr); lm_error_set(LM_ERR_PkgFilesAddFail, file, suberr);
@ -326,8 +320,6 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
line = NULL; line = NULL;
line_len = 0; line_len = 0;
} }
pdebug(__func__, "extracting files for %s", pkg->data.name);
if(!__lm_ctx_extract_files(ctx, pkg, files->files_archive, callback, data)){ if(!__lm_ctx_extract_files(ctx, pkg, files->files_archive, callback, data)){
char *suberr = lm_strerror_dup(); char *suberr = lm_strerror_dup();
@ -336,8 +328,6 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
free(suberr); free(suberr);
goto end; goto end;
} }
pdebug(__func__, "adding an entry for %s", pkg->data.name);
if(!lm_database_entry_add(ctx->db, &pkg->data)){ if(!lm_database_entry_add(ctx->db, &pkg->data)){
char *suberr = lm_strerror_dup(); char *suberr = lm_strerror_dup();
@ -347,11 +337,6 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
goto end; goto end;
} }
if(run_install)
pdebug(__func__, "running the install script for %s", pkg->data.name);
else
pdebug(__func__, "saving the install script for %s", pkg->data.name);
if(run_install && !__lm_ctx_run_install(ctx->root, files->install_file)){ if(run_install && !__lm_ctx_run_install(ctx->root, files->install_file)){
char *suberr = lm_strerror_dup(); char *suberr = lm_strerror_dup();
pdebug(__func__, "failed to run install script: %s", lm_strerror()); pdebug(__func__, "failed to run install script: %s", lm_strerror());
@ -384,10 +369,7 @@ end:
lm_database_files_del(ctx->db, &pkg->data); lm_database_files_del(ctx->db, &pkg->data);
} }
if (pkg->pool != NULL){ unlink(pkg->archive);
unlink(pkg->archive); unlink(pkg->signature);
unlink(pkg->signature);
}
return ret; return ret;
} }

View File

@ -41,14 +41,9 @@ lm_pkg_t *lm_ctx_list_next(lm_ctx_list_t *list){
return list->pkg; return list->pkg;
} }
if((list->pkg = list->pkg->next) == NULL){ if((list->pkg = list->pkg->next) && NULL == list->pkg){
next_pool: if((list->pool = list->pool->next) != NULL)
if((list->pool = list->pool->next) == NULL) list->pkg = list->pool->pkg;
return list->pkg;
if((list->pkg = list->pool->pkg) == NULL)
goto next_pool;
return list->pkg; return list->pkg;
} }

View File

@ -55,16 +55,13 @@ bool lm_ctx_remove(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_remove_callback_t ca
size_t total = 0, current = 0; size_t total = 0, current = 0;
total = lm_database_files_count(ctx->db, entry); total = lm_database_files_count(ctx->db, entry);
pdebug(__func__, "removing %lu files", total);
while(lm_database_files_next(ctx->db, entry, &path, &hash, &in_keep)){ while(lm_database_files_next(ctx->db, entry, &path, &hash, &in_keep)){
if(in_keep){ if(in_keep)
pdebug(__func__, "not removing file because it is set as keep: %s", path);
goto next; goto next;
}
fpath = join_alloc(ctx->root, path); fpath = join_alloc(ctx->root, path);
pdebug(__func__, "removing file %s (%s)", fpath, hash); pdebug(__func__, "removing file %s (%s)", fpath, entry->name);
if(!exists(fpath, NULL)){ if(!exists(fpath, NULL)){
pdebug(__func__, "found file in database, but its not on the file system: %s", fpath); pdebug(__func__, "found file in database, but its not on the file system: %s", fpath);

View File

@ -7,37 +7,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
bool __lm_ctx_resolve_contains(lm_pkg_t *pkg, lm_ctx_resolve_list_t *list){ bool __lm_ctx_resolve(lm_ctx_t *ctx, lm_ctx_resolve_list_t *list, lm_pkg_t *pkg){
if(NULL == list->packages) if(pkglist_contains(list->packages, pkg))
return false;
for(int i = 0; i < list->count; i++){
if(eq(list->packages[i]->data.name, pkg->data.name))
return true;
}
return false;
}
bool __lm_ctx_resolve(lm_ctx_t *ctx, lm_ctx_resolve_list_t *list, lm_pkg_t *pkg, bool resolve_depends){
if(__lm_ctx_resolve_contains(pkg, list)){
pdebug(__func__, "%s is already in the list, skipping", pkg->data.name);
return true; return true;
}
if(NULL == list->packages) if(NULL == pkg->data.depends)
list->packages = malloc(sizeof(lm_pkg_t *)*(++list->count)); goto end;
else
list->packages = realloc(list->packages, sizeof(lm_pkg_t *)*(++list->count));
pdebug(__func__, "adding %s to the list", pkg->data.name); list->resolving = pkglist_add_top(list->resolving, pkg);
list->packages[list->count-1] = pkg;
if(!resolve_depends || NULL == pkg->data.depends){
pdebug(__func__, "skipping depend resolve for %s", pkg->data.name);
return true;
}
lm_pkg_t *depend = NULL; lm_pkg_t *depend = NULL;
for(int i = 0; pkg->data.depends[i] != NULL; i++){ for(int i = 0; pkg->data.depends[i] != NULL; i++){
@ -52,14 +29,23 @@ bool __lm_ctx_resolve(lm_ctx_t *ctx, lm_ctx_resolve_list_t *list, lm_pkg_t *pkg,
return false; return false;
} }
if(!__lm_ctx_resolve(ctx, list, depend, resolve_depends)) if(pkglist_contains(list->resolving, depend)){
lm_error_set(LM_ERR_DependNotFound, pkg->data.depends[i], pkg->data.name);
return false;
}
if(!__lm_ctx_resolve(ctx, list, depend))
return false; return false;
} }
list->resolving = pkglist_del(list->resolving, pkg);
end:
list->packages = pkglist_add_end(list->packages, pkg);
list->count++;
return true; return true;
} }
lm_ctx_resolve_list_t *lm_ctx_resolve(lm_ctx_t *ctx, lm_pkg_t *pkg, bool resolve_depends, lm_ctx_resolve_list_t *list){ lm_ctx_resolve_list_t *lm_ctx_resolve(lm_ctx_t *ctx, lm_pkg_t *pkg, lm_ctx_resolve_list_t *list){
if(NULL == ctx || NULL == pkg){ if(NULL == ctx || NULL == pkg){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return NULL; return NULL;
@ -70,12 +56,16 @@ lm_ctx_resolve_list_t *lm_ctx_resolve(lm_ctx_t *ctx, lm_pkg_t *pkg, bool resolve
bzero(list, sizeof(lm_ctx_resolve_list_t)); bzero(list, sizeof(lm_ctx_resolve_list_t));
} }
if(!__lm_ctx_resolve(ctx, list, pkg, resolve_depends)){ if(!__lm_ctx_resolve(ctx, list, pkg)){
free(list->packages); pkglist_free(list->resolving);
pkglist_free(list->packages);
free(list); free(list);
return NULL; return NULL;
} }
pkglist_free(list->resolving);
list->resolving = NULL;
return list; return list;
} }
@ -86,16 +76,11 @@ lm_pkg_t *lm_ctx_resolve_next(lm_ctx_resolve_list_t *list){
} }
if(NULL == list->cur){ if(NULL == list->cur){
list->index = 0; list->cur = list->packages;
list->cur = list->packages[list->index++];
return list->cur; return list->cur;
} }
if(list->index >= list->count) list->cur = list->cur->next;
list->cur = NULL;
else
list->cur = list->packages[list->index++];
return list->cur; return list->cur;
} }
@ -105,8 +90,7 @@ void lm_ctx_resolve_free(lm_ctx_resolve_list_t *list){
return; return;
} }
free(list->packages); pkglist_free(list->packages);
free(list); free(list);
return; return;
} }

View File

@ -6,170 +6,103 @@
#include <errno.h> #include <errno.h>
#include <libgen.h> #include <libgen.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
int __serve_sock = 0;
lm_thpool_t __serve_tp;
struct lm_ctx_serve_thread_arg { struct lm_ctx_serve_thread_arg {
lm_ctx_serve_callback_t callback;
int sock; int sock;
struct sockaddr addr; struct sockaddr addr;
lm_ctx_t *ctx; lm_mptp_t packet;
lm_pool_t *pool;
lm_ctx_serve_callback_t callback;
void *data; void *data;
}; };
void __lm_ctx_serve_thread(void *_arg) { void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr) {
struct lm_ctx_serve_thread_arg *arg = _arg; switch (MPTP_FLAGS_CODE(packet)) {
bool success = false;
lm_mptp_t packet;
lm_mptp_init(&packet);
if(!lm_mptp_server_recv(arg->sock, &packet)){
pdebug(__func__, "%x: failed to receive packet", arg->addr);
return lm_mptp_close(arg->sock);
}
if (!lm_mptp_server_verify(&packet)) {
pdebug(__func__, "%x: closing connection, failed to verify", arg->addr);
return lm_mptp_close(arg->sock);
}
char hostname[packet.header.host_size + 1]; // +1 for NULL terminator
char path[packet.header.path_size + 1], *ppath = path;
if (!lm_mptp_get_host(&packet, hostname)) {
pdebug(__func__, "%x: closing connection, failed to get hostname", arg->addr);
goto end;
}
if (!lm_mptp_get_path(&packet, path)) {
pdebug(__func__, "%x: closing connection, failed to get path", arg->addr);
goto end;
}
if(MPTP_FLAGS_CODE(&packet) == MPTP_C2S_PULL && (ppath = dirname(path)) == NULL){
pdebug(__func__, "%x: closing connection, failed to get dirname (%s)", strerror(errno));
goto end;
}
lm_pool_t *pool = lm_ctx_pool_by_url(arg->ctx, hostname, ppath);
if (NULL == pool) {
pdebug(__func__, "%x: unknown pool (%s), closing connection", arg->addr, hostname);
lm_mptp_new(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(arg->sock, &packet);
goto end;
}
if(lm_pool_path_is_empty(pool)){
pdebug(__func__, "%x: requested pool (%s) have empty paths, closing connection", arg->addr, pool->name);
lm_mptp_new(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(arg->sock, &packet);
goto end;
}
if(!pool->loaded){
pdebug(__func__, "%x: requested pool (%s) is not loaded, closing connection", arg->addr, pool->name);
lm_mptp_new(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(arg->sock, &packet);
goto end;
}
success = true;
switch (MPTP_FLAGS_CODE(&packet)) {
// response PING with PONG // response PING with PONG
case MPTP_C2S_PING: case MPTP_C2S_PING:
pdebug(__func__, "PING %s: returning PONG", pool->name); pdebug(__func__, "(%s) PING: returning PONG", pool->name);
lm_mptp_new(&packet, false, MPTP_S2C_PONG, true); lm_mptp_init(packet, false, MPTP_S2C_PONG, true);
lm_mptp_server_send(arg->sock, &packet); lm_mptp_server_send(sock, packet, addr);
break; break;
// when INFO file is requested, send the file // when INFO file is requested, send the file
case MPTP_C2S_INFO: case MPTP_C2S_INFO:
pdebug(__func__, "INFO %s: attempting to send info (%s)", pool->name, pool->info_file); pdebug(__func__, "(%s) INFO: attempting to send info", pool->name);
lm_mptp_sendfile(arg->sock, pool->info_file, NULL, NULL); lm_mptp_sendfile(sock, addr, pool->info_file, NULL, NULL);
break; break;
// when LIST file is requested, send the file // when LIST file is requested, send the file
case MPTP_C2S_LIST: case MPTP_C2S_LIST:
pdebug(__func__, "LIST %s: attempting to send list (%s)", pool->name, pool->list_file); pdebug(__func__, "(%s) LIST: attempting to send list", pool->name);
lm_mptp_sendfile(arg->sock, pool->list_file, NULL, NULL); lm_mptp_sendfile(sock, addr, pool->list_file, NULL, NULL);
break; break;
// when the request code is PULL, send the requested package archive and // when the request code is PULL, send the requested package archive and
// requested package signature // requested package signature
case MPTP_C2S_PULL: case MPTP_C2S_PULL:
// PULL request should contain package path, // PULL request should contain package path,
// if path (stored in the data field) is empty it's an invalid request // if path (stored in the data field) is empty it's an invalid request
if(packet.header.path_size <= 0){ if(packet->header.data_size <= 0){
lm_mptp_new(&packet, false, MPTP_S2C_WHAT, true); lm_mptp_init(packet, false, MPTP_S2C_WHAT, true);
lm_mptp_server_send(arg->sock, &packet); lm_mptp_server_send(sock, packet, addr);
break; break;
} }
pdebug(__func__, "(%s) PULL: attempting to send package archive and signature", pool->name);
char path[packet->header.data_size + 1], *package = path;
pdebug(__func__, "PULL %s: attempting to send package archive and signature", pool->name); if(!lm_mptp_get_data(packet, path)){
char path[packet.header.path_size + 1], *package = path;
if(!lm_mptp_get_path(&packet, path)){
// we should never be able to get here, if we do theres definetly a bug // we should never be able to get here, if we do theres definetly a bug
pdebug(__func__, "PULL %s: skipping, failed to get path", pool->name); pdebug(__func__, "(%s) PULL: skipping, failed to get path: %s", pool->name, lm_strerror());
break; break;
} }
// if we can't get the package name, then theres something wrong with the request // if we can't get the package name, then theres something wrong with the request
if((package = basename(path)) == NULL){ if((package = basename(path)) == NULL){
lm_mptp_new(&packet, false, MPTP_S2C_WHAT, true); lm_mptp_init(packet, false, MPTP_S2C_WHAT, true);
lm_mptp_server_send(arg->sock, &packet); lm_mptp_server_send(sock, packet, addr);
break; break;
} }
size_t package_size = strlen(package); size_t package_size = strlen(package);
char name[package_size+1], version[package_size+1]; char name[package_size+1], version[package_size+1];
lm_pkg_t *pkg = NULL; lm_pkg_t *pkg = NULL;
// if we can't parse the package name, request is invalid // if we can't parse the package name, request is invalid
if(!package_parse(package, name, version)){ if(!package_parse(package, name, version)){
lm_mptp_new(&packet, false, MPTP_S2C_WHAT, true); lm_mptp_init(packet, false, MPTP_S2C_WHAT, true);
lm_mptp_server_send(arg->sock, &packet); lm_mptp_server_send(sock, packet, addr);
break; break;
} }
// if the package is not found in the pool, tell the client // if the package is not found in the pool, tell the client
if((pkg = lm_pool_package_find(pool, name, version)) == NULL){ if((pkg = lm_pool_package_find(pool, name, version)) == NULL){
lm_mptp_new(&packet, false, MPTP_S2C_BRUH, true); lm_mptp_init(packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(arg->sock, &packet); lm_mptp_server_send(sock, packet, addr);
break; break;
} }
// send package archive and the signature file // send package archive and the signature file
if(!lm_mptp_sendfile(arg->sock, pkg->archive, NULL, NULL)) lm_mptp_sendfile(sock, addr, pkg->archive, NULL, NULL);
goto end; // if we fail to send the archive no need to send the signature lm_mptp_sendfile(sock, addr, pkg->signature, NULL, NULL);
lm_mptp_sendfile(arg->sock, pkg->signature, NULL, NULL);
break; break;
} }
}
end: void __lm_ctx_serve_thread(void *_arg) {
lm_mptp_close(arg->sock); struct lm_ctx_serve_thread_arg *arg = _arg;
if(success && NULL != arg->callback) if(NULL != arg->callback && !arg->callback(arg->pool, &arg->packet, &arg->addr, arg->data))
arg->callback(pool, &packet, &arg->addr, arg->data); return free(arg);
__lm_ctx_serve(arg->pool, &arg->packet, arg->sock, &arg->addr);
free(arg); free(arg);
} }
void __lm_ctx_serve_signal(int sig){ bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, lm_ctx_serve_callback_t callback, void *data){
pdebug(__func__, "received interrupt, stopping the server");
lm_thpool_stop(&__serve_tp);
lm_mptp_server_close(__serve_sock);
exit(1);
}
bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, __sighandler_t handler, lm_ctx_serve_callback_t callback, void *data){
if (NULL == addr || threads < 0) { if (NULL == addr || threads < 0) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;
@ -177,10 +110,12 @@ bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, __sighandler_t han
char host[strlen(addr)+1]; char host[strlen(addr)+1];
struct sockaddr saddr; struct sockaddr saddr;
lm_mptp_t packet;
uint16_t port; uint16_t port;
int c = -1; int sock;
lm_thpool_t tp;
lm_thpool_init(&__serve_tp, threads); lm_thpool_init(&tp, threads);
if (!parse_host(addr, host, &port)) if (!parse_host(addr, host, &port))
return false; return false;
@ -190,29 +125,69 @@ bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, __sighandler_t han
return false; return false;
} }
if ((__serve_sock = lm_mptp_server_listen(host, port)) < 0) if ((sock = lm_mptp_server_listen(host, port)) < 0)
return false; return false;
if(NULL == handler) while (lm_mptp_server_recv(sock, &packet, &saddr)) {
handler = __lm_ctx_serve_signal; if (!lm_mptp_server_verify(&packet)) {
pdebug(__func__, "skipping packet, failed to verify: %s", lm_strerror());
continue;
}
signal(SIGPIPE, SIG_IGN); char hostname[packet.header.host_size + 1]; // +1 for NULL terminator
signal(SIGINT, handler); char path[packet.header.data_size + 1], *ppath = path;
if (!lm_mptp_get_host(&packet, hostname)) {
pdebug(__func__, "skipping packet, failed to get hostname: %s", lm_strerror());
continue;
}
if (!lm_mptp_get_data(&packet, path)) {
pdebug(__func__, "skipping packet, failed to get path: %s", lm_strerror());
continue;
}
if(MPTP_FLAGS_CODE(&packet) == MPTP_C2S_PULL && (ppath = dirname(path)) == NULL){
pdebug(__func__, "skipping packet, failed to get dirname: %s", strerror(errno));
continue;
}
lm_pool_t *pool = lm_ctx_pool_by_url(ctx, hostname, ppath);
if (NULL == pool) {
pdebug(__func__, "unknown pool (%s), closing connection", hostname);
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(sock, &packet, &saddr);
continue;
}
if(lm_pool_path_is_empty(pool)){
pdebug(__func__, "requested pool (%s) have empty paths, closing connection", pool->name);
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(sock, &packet, &saddr);
continue;
}
if(!pool->loaded){
pdebug(__func__, "requested pool (%s) is not loaded, closing connection", pool->name);
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(sock, &packet, &saddr);
continue;
}
while ((c = lm_mptp_server_accept(__serve_sock, &saddr)) != -1) {
struct lm_ctx_serve_thread_arg *arg = malloc(sizeof(struct lm_ctx_serve_thread_arg)); struct lm_ctx_serve_thread_arg *arg = malloc(sizeof(struct lm_ctx_serve_thread_arg));
memcpy(&arg->addr, &saddr, sizeof(struct sockaddr));
memcpy(&arg->addr, &saddr, sizeof(struct sockaddr));
lm_mptp_copy(&arg->packet, &packet);
arg->callback = callback; arg->callback = callback;
arg->data = data; arg->data = data;
arg->ctx = ctx; arg->pool = pool;
arg->sock = c; arg->sock = sock;
pdebug(__func__, "adding new connection to the pool"); pdebug(__func__, "adding new connection to the pool");
lm_thpool_add(&__serve_tp, __lm_ctx_serve_thread, arg); lm_thpool_add(&tp, __lm_ctx_serve_thread, arg);
} }
lm_thpool_stop(&__serve_tp); lm_thpool_stop(&tp);
// error set by mptp_server_accept return true;
return false;
} }

View File

@ -25,7 +25,7 @@ bool __lm_ctx_sync_callback(char *path, size_t current, size_t total, void *data
return cbdata->callback(cbdata->ctx, cbdata->pool, cbdata->state, current, total, data); 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){ size_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callback, void *data){
if(NULL == ctx) { if(NULL == ctx) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return -1; return -1;

View File

@ -19,7 +19,7 @@ char *lm_ctx_temp_dir(lm_ctx_t *ctx, char *dir){
char td[strlen(ctx->temp)+strlen(dir)+10]; char td[strlen(ctx->temp)+strlen(dir)+10];
join(td, ctx->temp, dir); join(td, ctx->temp, dir);
if(!mkdir_ifnot(td, 0755)){ if(!mkdir_ifnot(td)){
lm_error_set(LM_ERR_CtxTempFailMkdir); lm_error_set(LM_ERR_CtxTempFailMkdir);
return NULL; return NULL;
} }
@ -35,10 +35,11 @@ bool lm_ctx_temp_clear(lm_ctx_t *ctx) {
rmrf(ctx->temp); rmrf(ctx->temp);
if(!mkdir_ifnot(ctx->temp, 0755)){ if(!mkdir_ifnot(ctx->temp)){
lm_error_set(LM_ERR_CtxTempFailMkdir); lm_error_set(LM_ERR_CtxTempFailMkdir);
return false; return false;
} }
return true; return true;
} }

View File

@ -32,15 +32,9 @@ lm_ctx_update_list_t *lm_ctx_update_list(lm_ctx_t *ctx){
list->entries = malloc(sizeof(lm_entry_t*)*(++list->count)); list->entries = malloc(sizeof(lm_entry_t*)*(++list->count));
else else
list->entries = realloc(list->entries, sizeof(lm_entry_t*)*(++list->count)); list->entries = realloc(list->entries, sizeof(lm_entry_t*)*(++list->count));
list->entries[list->count-1] = cur; list->entries[list->count-1] = cur;
cur = malloc(sizeof(lm_entry_t));
lm_entry_init(cur);
} }
lm_entry_free(cur);
free(cur);
lm_ctx_database_next_free(ctx, NULL); lm_ctx_database_next_free(ctx, NULL);
return list; return list;
} }
@ -69,10 +63,8 @@ void lm_ctx_update_list_free(lm_ctx_update_list_t *list){
} }
if(NULL != list->entries){ if(NULL != list->entries){
for(int i = 0; i < list->count; i++){ for(int i = 0; i < list->count; i++)
lm_entry_free(list->entries[i]); lm_entry_free(list->entries[i]);
free(list->entries[i]);
}
free(list->entries); free(list->entries);
} }

View File

@ -8,31 +8,18 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
size_t __lm_database_changes_get(lm_database_t *db, lm_entry_t *entry, char *path){
size_t changes_size = strlen(entry->name)+15;
size_t full_size = changes_size + strlen(db->dir);
if(NULL != path){
char changes_file[changes_size];
snprintf(changes_file, changes_size, "%s_changes", entry->name);
join(path, db->dir, changes_file);
}
return full_size;
}
#define __lm_changes_size() __lm_database_changes_get(db, entry, NULL)
#define __lm_changes_path(p) __lm_database_changes_get(db, entry, p)
bool lm_database_changes_update(lm_database_t *db, lm_entry_t *entry, char *file){ bool lm_database_changes_update(lm_database_t *db, lm_entry_t *entry, char *file){
if(NULL == db || NULL == entry || NULL == file){ if(NULL == db || NULL == entry || NULL == file){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;
} }
char changes_path[__lm_changes_size()]; char changes_file[strlen(entry->name)+20];
__lm_changes_path(changes_path); sprintf(changes_file, "%s_changes", entry->name);
char changes_path[strlen(db->dir)+sizeof(changes_file)];
join(changes_path, db->dir, changes_file);
if(!copy_file(changes_path, file)) if(!copy_file(changes_path, file))
return false; return false;
@ -50,8 +37,11 @@ bool lm_database_changes_del(lm_database_t *db, lm_entry_t *entry){
return false; return false;
} }
char changes_path[__lm_changes_size()]; char changes_file[strlen(entry->name)+20];
__lm_changes_path(changes_path); sprintf(changes_file, "%s_changes", entry->name);
char changes_path[strlen(db->dir)+sizeof(changes_file)];
join(changes_path, db->dir, changes_file);
if(unlink(changes_path) < 0 && errno != ENOENT){ if(unlink(changes_path) < 0 && errno != ENOENT){
lm_error_set(LM_ERR_DbChangesUnlinkFail); lm_error_set(LM_ERR_DbChangesUnlinkFail);
@ -62,16 +52,15 @@ bool lm_database_changes_del(lm_database_t *db, lm_entry_t *entry){
} }
char *lm_database_changes_get(lm_database_t *db, lm_entry_t *entry){ char *lm_database_changes_get(lm_database_t *db, lm_entry_t *entry){
if(NULL == db || NULL == entry){ char changes_file[strlen(entry->name)+20];
lm_error_set(LM_ERR_ArgNULL); sprintf(changes_file, "%s_changes", entry->name);
return false;
}
char* changes_path = malloc(__lm_changes_size()); char *changes_path = malloc(strlen(db->dir)+sizeof(changes_file));
__lm_changes_path(changes_path); join(changes_path, db->dir, changes_file);
if(!exists(changes_path, NULL)){ if(!exists(changes_path, NULL)){
lm_error_set(LM_ERR_DbChangesNotExists); lm_error_set(LM_ERR_DbChangesNotExists);
free(changes_path);
return NULL; return NULL;
} }

View File

@ -31,6 +31,34 @@ char *queries[] = {
// QUERY_SELECT_PACKAGE_ALL // QUERY_SELECT_PACKAGE_ALL
"SELECT * FROM packages", "SELECT * FROM packages",
// QUERY_CREATE_FILE_TABLE
"CREATE TABLE IF NOT EXISTS files (" \
" path TEXT PRIMARY KEY NOT NULL," \
" hash TEXT NOT NULL," \
" keep INT NOT NULL," \
" package TEXT NOT NULL);",
// QUERY_INSERT_FILE_SINGLE
"INSERT INTO files VALUES (?, ?, ?, ?)",
// QUERY_DELETE_FILE_ALL
"DELETE FROM files WHERE package = ? AND keep = 0",
// QUERY_DELETE_FILE_SINGLE
"DELETE FROM files WHERE path = ?",
// QUERY_SELECT_FILE_ALL
"SELECT * FROM files WHERE package = ?",
// QUERY_SELECT_FILE_SINGLE
"SELECT * FROM files WHERE path = ?",
// QUERY_UPDATE_FILE_1
"UPDATE files SET keep = 1 WHERE path = ?",
// QUERY_UPDATE_FILE_2
"UPDATE files SET keep = 0 WHERE path = ?",
}; };
lm_database_t *lm_database_new(char *path){ lm_database_t *lm_database_new(char *path){
@ -38,31 +66,46 @@ lm_database_t *lm_database_new(char *path){
char *err = NULL; char *err = NULL;
bzero(db, sizeof(lm_database_t)); bzero(db, sizeof(lm_database_t));
if(exists(path, NULL) && (is_file(path) || !can_read(path))){ if(exists(path, NULL) && (is_file(path) || !can_read(path) || !can_write(path))){
lm_error_set(LM_ERR_DbCantAccess); lm_error_set(LM_ERR_DbCantAccess);
return NULL; return NULL;
} }
if(!exists(path, NULL) && !mkdir_ifnot(path, 0755)){ if(!exists(path, NULL) && !mkdir_ifnot(path)){
lm_error_set(LM_ERR_DbCantAccess); lm_error_set(LM_ERR_DbCantAccess);
return NULL; return NULL;
} }
size_t pathlen = strlen(path); size_t pathlen = strlen(path);
char packagesdb[pathlen+15]; char packagesdb[pathlen+20], filesdb[pathlen+20];
join(packagesdb, path, "packages.db"); join(packagesdb, path, "packages.db");
join(filesdb, path, "files.db");
if(sqlite3_open(packagesdb, &db->sql)){ if(sqlite3_open(packagesdb, &db->entries_db)){
pdebug(__func__, "(%s) failed to open databse: %s", packagesdb, sqlite3_errmsg(db->sql)); pdebug(__func__, "(%s) failed to open databse: %s", packagesdb, sqlite3_errmsg(db->entries_db));
lm_error_set(LM_ERR_DbSqlOpenFail); lm_error_set(LM_ERR_DbSqlOpenFail);
return NULL; return NULL;
} }
if(can_write(path) && sqlite3_exec(db->sql, queries[QUERY_CREATE_TABLE], NULL, 0, &err) != SQLITE_OK){ if(sqlite3_open(filesdb, &db->files_db)){
pdebug(__func__, "(%s) failed to open databse: %s", filesdb, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlOpenFail);
return NULL;
}
if(sqlite3_exec(db->entries_db, queries[QUERY_CREATE_ENTRY_TABLE], NULL, 0, &err) != SQLITE_OK){
pdebug(__func__, "(%s) failed to create packages table: %s", packagesdb, err); pdebug(__func__, "(%s) failed to create packages table: %s", packagesdb, err);
lm_error_set(LM_ERR_DbSqlCreateFail); lm_error_set(LM_ERR_DbSqlCreateFail);
sqlite3_free(err); sqlite3_free(err);
db->sql = NULL; db->entries_db = NULL;
}
if(sqlite3_exec(db->files_db, queries[QUERY_CREATE_FILE_TABLE], NULL, 0, &err) != SQLITE_OK){
pdebug(__func__, "(%s) failed to create files table: %s", filesdb, err);
lm_error_set(LM_ERR_DbSqlCreateFail);
sqlite3_free(err);
db->files_db = NULL;
} }
db->dir = strdup(path); db->dir = strdup(path);
@ -70,13 +113,15 @@ lm_database_t *lm_database_new(char *path){
} }
void lm_database_free(lm_database_t *db){ void lm_database_free(lm_database_t *db){
if(NULL != db->st) if(NULL != db->entries_st)
sqlite3_finalize(db->st); sqlite3_finalize(db->entries_st);
if(NULL != db->filesp) if(NULL != db->files_st)
fclose(db->filesp); sqlite3_finalize(db->files_st);
sqlite3_close(db->entries_db);
sqlite3_close(db->files_db);
sqlite3_close(db->sql);
free(db->dir); free(db->dir);
free(db); free(db);
} }

View File

@ -28,35 +28,35 @@ bool lm_database_entry_add(lm_database_t *db, lm_entry_t *entry){
char depends[lm_package_data_depend_strlen(entry)]; char depends[lm_package_data_depend_strlen(entry)];
bool ret = false; bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_INSERT_SINGLE], strlen(queries[QUERY_INSERT_SINGLE]), &db->st, NULL) != SQLITE_OK){ if(sqlite3_prepare(db->entries_db, queries[QUERY_INSERT_ENTRY_SINGLE], strlen(queries[QUERY_INSERT_ENTRY_SINGLE]), &db->entries_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for inserting %s: %s", entry->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to prepare statement for inserting %s: %s", entry->name, sqlite3_errmsg(db->entries_db));
lm_error_set(LM_ERR_DbSqlPrepareFail); lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end; goto end;
} }
sqlite3_bind_text(db->st, COLUMN_NAME, entry->name, strlen(entry->name), SQLITE_STATIC); sqlite3_bind_text(db->entries_st, ENTRIES_COLUMN_NAME, entry->name, strlen(entry->name), SQLITE_STATIC);
sqlite3_bind_text(db->st, COLUMN_DESC, entry->desc, strlen(entry->desc), SQLITE_STATIC); sqlite3_bind_text(db->entries_st, ENTRIES_COLUMN_DESC, entry->desc, strlen(entry->desc), SQLITE_STATIC);
sqlite3_bind_text(db->st, COLUMN_VERSION, entry->version, strlen(entry->version), SQLITE_STATIC); sqlite3_bind_text(db->entries_st, ENTRIES_COLUMN_VERSION, entry->version, strlen(entry->version), SQLITE_STATIC);
sqlite3_bind_int64(db->st, COLUMN_SIZE, entry->size); sqlite3_bind_int64(db->entries_st, ENTRIES_COLUMN_SIZE, entry->size);
if(!lm_package_data_depend_tostr(entry, depends)){ if(!lm_package_data_depend_tostr(entry, depends)){
pdebug(__func__, "failed to convert depends to string for inserting %s: %s", entry->name, lm_strerror()); pdebug(__func__, "failed to convert depends to string for inserting %s: %s", entry->name, lm_strerror());
goto end; goto end;
} }
pdebug(__func__, "depend list for %s: %s", entry->name, depends); pdebug(__func__, "depend list for %s: %s", entry->name, depends);
sqlite3_bind_text(db->st, COLUMN_DEPENDS, depends, strlen(depends), SQLITE_STATIC); sqlite3_bind_text(db->entries_st, ENTRIES_COLUMN_DEPENDS, depends, strlen(depends), SQLITE_STATIC);
if(!lm_database_step_all(db->st)){ if(!lm_database_step_all(db->entries_st)){
pdebug(__func__, "failed to execute insert statement for inserting %s: %s", entry->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to execute insert statement for inserting %s: %s", entry->name, sqlite3_errmsg(db->entries_db));
lm_error_set(LM_ERR_DbSqlInsertFail); lm_error_set(LM_ERR_DbSqlInsertFail);
goto end; goto end;
} }
ret = true; ret = true;
end: end:
if(NULL != db->st){ if(NULL != db->entries_st){
sqlite3_finalize(db->st); sqlite3_finalize(db->entries_st);
db->st = NULL; db->entries_st = NULL;
} }
return ret; return ret;
} }
@ -71,26 +71,26 @@ bool lm_database_entry_find(lm_database_t *db, lm_entry_t *entry, char *name, ch
char *query = NULL; char *query = NULL;
if(NULL == version) if(NULL == version)
query = queries[QUERY_SELECT_SINGLE_1]; query = queries[QUERY_SELECT_ENTRY_SINGLE_1];
else else
query = queries[QUERY_SELECT_SINGLE_2]; query = queries[QUERY_SELECT_ENTRY_SINGLE_2];
// package pointer should already be free'd // package pointer should already be free'd
// we are initing it just in case the caller didn't // we are initing it just in case the caller didn't
if(NULL != entry) if(NULL != entry)
lm_entry_init(entry); lm_entry_init(entry);
if(sqlite3_prepare(db->sql, query, strlen(query), &db->st, NULL) != SQLITE_OK){ if(sqlite3_prepare(db->entries_db, query, strlen(query), &db->entries_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for finding %s: %s", name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to prepare statement for finding %s: %s", name, sqlite3_errmsg(db->entries_db));
lm_error_set(LM_ERR_DbSqlPrepareFail); lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end; goto end;
} }
sqlite3_bind_text(db->st, COLUMN_NAME, name, strlen(name), SQLITE_STATIC); sqlite3_bind_text(db->entries_st, ENTRIES_COLUMN_NAME, name, strlen(name), SQLITE_STATIC);
if(NULL != version) if(NULL != version)
sqlite3_bind_text(db->st, COLUMN_VERSION, version, strlen(version), SQLITE_STATIC); sqlite3_bind_text(db->entries_st, ENTRIES_COLUMN_VERSION, version, strlen(version), SQLITE_STATIC);
if(sqlite3_step(db->st) != SQLITE_ROW){ if(sqlite3_step(db->entries_st) != SQLITE_ROW){
pdebug(__func__, "got no rows for %s", name); pdebug(__func__, "got no rows for %s", name);
lm_error_set(LM_ERR_DbSqlNotFound); lm_error_set(LM_ERR_DbSqlNotFound);
goto end; goto end;
@ -101,12 +101,12 @@ bool lm_database_entry_find(lm_database_t *db, lm_entry_t *entry, char *name, ch
goto end; goto end;
} }
entry->name = strdup((char*)sqlite3_column_text(db->st, COLUMN_NAME-1)); entry->name = strdup((char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_NAME-1));
entry->desc = strdup((char*)sqlite3_column_text(db->st, COLUMN_DESC-1)); entry->desc = strdup((char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_DESC-1));
entry->version = strdup((char*)sqlite3_column_text(db->st, COLUMN_VERSION-1)); entry->version = strdup((char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_VERSION-1));
entry->size = sqlite3_column_int64(db->st, COLUMN_SIZE-1); entry->size = sqlite3_column_int64(db->entries_st, ENTRIES_COLUMN_SIZE-1);
char *depends = (char*)sqlite3_column_text(db->st, COLUMN_DEPENDS-1); char *depends = (char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_DEPENDS-1);
if(!lm_package_data_depend_fromstr(entry, depends)){ if(!lm_package_data_depend_fromstr(entry, depends)){
pdebug(__func__, "failed to load depends for finding %s: %s", entry->name, lm_strerror()); pdebug(__func__, "failed to load depends for finding %s: %s", entry->name, lm_strerror());
// error is set by the function // error is set by the function
@ -115,9 +115,9 @@ bool lm_database_entry_find(lm_database_t *db, lm_entry_t *entry, char *name, ch
ret = true; ret = true;
end: end:
if(NULL != db->st){ if(NULL != db->entries_st){
sqlite3_finalize(db->st); sqlite3_finalize(db->entries_st);
db->st = NULL; db->entries_st = NULL;
} }
return ret; return ret;
} }
@ -130,25 +130,25 @@ bool lm_database_entry_del(lm_database_t *db, lm_entry_t *entry){
bool ret = false; bool ret = false;
if(sqlite3_prepare(db->sql, queries[QUERY_DELETE_SINGLE], strlen(queries[QUERY_DELETE_SINGLE]), &db->st, NULL) != SQLITE_OK){ if(sqlite3_prepare(db->entries_db, queries[QUERY_DELETE_ENTRY_SINGLE], strlen(queries[QUERY_DELETE_ENTRY_SINGLE]), &db->entries_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for deleting %s: %s", entry->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to prepare statement for deleting %s: %s", entry->name, sqlite3_errmsg(db->entries_db));
lm_error_set(LM_ERR_DbSqlPrepareFail); lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end; goto end;
} }
sqlite3_bind_text(db->st, COLUMN_NAME, entry->name, strlen(entry->name), SQLITE_STATIC); sqlite3_bind_text(db->entries_st, ENTRIES_COLUMN_NAME, entry->name, strlen(entry->name), SQLITE_STATIC);
if(sqlite3_step(db->st) != SQLITE_DONE){ if(sqlite3_step(db->entries_st) != SQLITE_DONE){
pdebug(__func__, "failed to execute delete statement for deleting %s: %s", entry->name, sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to execute delete statement for deleting %s: %s", entry->name, sqlite3_errmsg(db->entries_db));
lm_error_set(LM_ERR_DbSqlDeleteFail); lm_error_set(LM_ERR_DbSqlDeleteFail);
goto end; goto end;
} }
ret = true; ret = true;
end: end:
if(NULL != db->st){ if(NULL != db->entries_st){
sqlite3_finalize(db->st); sqlite3_finalize(db->entries_st);
db->st = NULL; db->entries_st = NULL;
} }
return ret; return ret;
} }
@ -159,33 +159,33 @@ bool lm_database_entry_next(lm_database_t *db, lm_entry_t *entry){
return false; return false;
} }
if(NULL != db->st) if(NULL != db->entries_st)
lm_entry_free(entry); lm_entry_free(entry);
else if(NULL == db->st && else if(NULL == db->entries_st &&
sqlite3_prepare(db->sql, queries[QUERY_SELECT_ALL], strlen(queries[QUERY_SELECT_ALL]), &db->st, NULL) != SQLITE_OK){ sqlite3_prepare(db->entries_db, queries[QUERY_SELECT_ENTRY_ALL], strlen(queries[QUERY_SELECT_ENTRY_ALL]), &db->entries_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for selecting all: %s", sqlite3_errmsg(db->sql)); pdebug(__func__, "failed to prepare statement for selecting all: %s", sqlite3_errmsg(db->entries_db));
lm_error_set(LM_ERR_DbSqlPrepareFail); lm_error_set(LM_ERR_DbSqlPrepareFail);
return false; return false;
} }
lm_entry_init(entry); lm_entry_init(entry);
if(sqlite3_step(db->st) != SQLITE_ROW){ if(sqlite3_step(db->entries_st) != SQLITE_ROW){
sqlite3_finalize(db->st); sqlite3_finalize(db->entries_st);
db->st = NULL; db->entries_st = NULL;
return false; return false;
} }
entry->name = strdup((char*)sqlite3_column_text(db->st, COLUMN_NAME-1)); entry->name = strdup((char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_NAME-1));
entry->desc = strdup((char*)sqlite3_column_text(db->st, COLUMN_DESC-1)); entry->desc = strdup((char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_DESC-1));
entry->version = strdup((char*)sqlite3_column_text(db->st, COLUMN_VERSION-1)); entry->version = strdup((char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_VERSION-1));
entry->size = sqlite3_column_int64(db->st, COLUMN_SIZE-1); entry->size = sqlite3_column_int64(db->entries_st, ENTRIES_COLUMN_SIZE-1);
char *depends = (char*)sqlite3_column_text(db->st, COLUMN_DEPENDS-1); char *depends = (char*)sqlite3_column_text(db->entries_st, ENTRIES_COLUMN_DEPENDS-1);
if(!lm_package_data_depend_fromstr(entry, depends)){ if(!lm_package_data_depend_fromstr(entry, depends)){
pdebug(__func__, "failed to load depends for finding %s: %s", entry->name, lm_strerror()); pdebug(__func__, "failed to load depends for finding %s: %s", entry->name, lm_strerror());
sqlite3_finalize(db->st); sqlite3_finalize(db->entries_st);
return false; return false;
} }
@ -198,9 +198,9 @@ void lm_database_entry_next_free(lm_database_t *db, lm_entry_t *entry){
return; return;
} }
if(NULL != db->st){ if(NULL != db->entries_st){
sqlite3_finalize(db->st); sqlite3_finalize(db->entries_st);
db->st = NULL; db->entries_st = NULL;
} }
if(NULL != entry) if(NULL != entry)

View File

@ -4,234 +4,176 @@
#include "../../include/util.h" #include "../../include/util.h"
#include <sqlite3.h> #include <sqlite3.h>
#include <stdio.h>
#include <errno.h>
#include <strings.h> #include <strings.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#define LINE_MIN 36 // keep (1) + colon (1) + MD5 hash (32) + colon (1) + path (min 1) ssize_t lm_database_files_count(lm_database_t *db, lm_entry_t *entry){
#define KEEP_INDEX 0 ssize_t count = 0;
#define HASH_INDEX 2
#define PATH_INDEX 35
size_t __lm_database_files_get(lm_database_t *db, lm_entry_t *entry, char *path){
size_t name_size = strlen(entry->name)+20;
size_t full_size = name_size + strlen(db->dir);
if(NULL != path){
char files_name[name_size];
snprintf(files_name, name_size, "%s_files", entry->name);
join(path, db->dir, files_name);
}
return full_size;
}
#define __lm_files_size() __lm_database_files_get(db, entry, NULL)
#define __lm_files_path(p) __lm_database_files_get(db, entry, p)
FILE *__lm_database_files_open(lm_database_t *db, lm_entry_t *entry, char *perms){
if(NULL == db || NULL == entry){ if(NULL == db || NULL == entry){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false;
}
char files_path[__lm_files_size()];
FILE *filesp = NULL;
__lm_files_path(files_path);
if(!exists(files_path, NULL)){
lm_error_set(LM_ERR_DbFilesNotFound);
return NULL;
}
if(NULL == (filesp = fopen(files_path, perms))){
lm_error_set(LM_ERR_DbFilesOpenFail, files_path);
return NULL;
}
return filesp;
}
char *__lm_database_files_line_single(FILE *filesp, char *path) {
ssize_t line_len = 0;
char *line = NULL;
while ((line_len = getline(&line, (size_t*)&line_len, filesp)) >= LINE_MIN) {
// keep : hash : path
// 1 : 32 : ?
// ignore empty line
if(line[0] == 0)
goto next;
// remove newline
else if (line[line_len-1] == '\n')
line[line_len-1] = 0;
if(eq((line + PATH_INDEX), path))
return line;
next:
free(line);
line = NULL;
line_len = 0;
}
return line;
}
char *__lm_database_files_line_all(lm_database_t *db, char *path) {
size_t dirlen = strlen(db->dir);
struct dirent *ent = NULL;
FILE* filesp = NULL;
DIR *ddir = NULL;
char *ret = NULL;
if(NULL == (ddir = opendir(db->dir))){
lm_error_set(LM_ERR_DbFilesDirFail, db->dir);
goto end; goto end;
} }
while(NULL != (ent = readdir(ddir))){ if(sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_ALL], strlen(queries[QUERY_SELECT_FILE_ALL]), &db->files_st, NULL) != SQLITE_OK){
size_t entlen = strlen(ent->d_name); pdebug(__func__, "failed to prepare statement for selecting all: %s", sqlite3_errmsg(db->files_db));
char entpath[entlen+dirlen+10]; lm_error_set(LM_ERR_DbSqlPrepareFail);
return false;
join(entpath, db->dir, ent->d_name);
if(NULL == (filesp = fopen(entpath, "r"))){
lm_error_set(LM_ERR_DbFilesOpenFail, entpath);
goto end;
}
if(NULL == (ret = __lm_database_files_line_single(filesp, path)))
goto end;
} }
sqlite3_bind_text(db->files_st, 1, entry->name, strlen(entry->name), SQLITE_STATIC);
while(sqlite3_step(db->files_st) == SQLITE_ROW)
count++;
end: end:
if(NULL != ddir) if(NULL != db->files_st){
closedir(ddir); sqlite3_finalize(db->files_st);
db->files_st = NULL;
if(NULL != filesp)
fclose(filesp);
return ret;
}
ssize_t lm_database_files_count(lm_database_t *db, lm_entry_t *entry){
if(NULL == db || NULL == entry){
lm_error_set(LM_ERR_ArgNULL);
return 0;
} }
FILE *filesp = NULL;
ssize_t count = 0;
char c = 0;
if((filesp = __lm_database_files_open(db, entry, "r")) == NULL)
return 0; // error set by function
while((c = fgetc(filesp)) != EOF)
if(c == '\n')
count ++;
fclose(filesp);
return count; return count;
} }
bool lm_database_files_contains(lm_database_t *db, lm_entry_t *entry, char *path){ bool lm_database_files_contains(lm_database_t *db, lm_entry_t *entry, char *path){
if(NULL == db || NULL == entry || NULL == path){ char *package = NULL;
lm_error_set(LM_ERR_ArgNULL);
return false;
}
FILE *filesp = NULL;
char *line = NULL;
bool ret = false; bool ret = false;
if((filesp = __lm_database_files_open(db, entry, "r")) == NULL) if(NULL == db || NULL == path){
return false; // error set by function lm_error_set(LM_ERR_ArgNULL);
goto end;
}
if((line = __lm_database_files_line_single(filesp, path)) != NULL) if(sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_SINGLE], strlen(queries[QUERY_SELECT_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
ret = true; pdebug(__func__, "failed to prepare statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlPrepareFail);
free(line); goto end;
}
if(NULL != filesp)
fclose(filesp); sqlite3_bind_text(db->files_st, FILES_COLUMN_PATH, path, strlen(path), SQLITE_STATIC);
if(sqlite3_step(db->files_st) != SQLITE_ROW){
pdebug(__func__, "failed to execute select statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlSelectFail);
goto end;
}
package = (char*)sqlite3_column_text(db->files_st, FILES_COLUMN_ENTRY-1);
ret = eq(package, entry->name);
end:
if(NULL != db->files_st){
sqlite3_finalize(db->files_st);
db->files_st = NULL;
}
return ret; return ret;
} }
bool lm_database_files_matches(lm_database_t *db, char *path, char *hash){ bool lm_database_files_matches(lm_database_t *db, char *path, char *hash){
if(NULL == db || NULL == path || NULL == hash){ char *hashdb = NULL;
lm_error_set(LM_ERR_ArgNULL);
return false;
}
char *line = NULL, *line_hash = NULL;
bool ret = false; bool ret = false;
if(NULL == (line = __lm_database_files_line_all(db, path))) if(NULL == db || NULL == path || NULL == hash){
return false; lm_error_set(LM_ERR_ArgNULL);
goto end;
}
line_hash = line+2; if(sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_SINGLE], strlen(queries[QUERY_SELECT_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
line[35] = 0; pdebug(__func__, "failed to prepare statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end;
}
sqlite3_bind_text(db->files_st, 1, path, strlen(path), SQLITE_STATIC);
if(eq(line_hash, hash)) if(sqlite3_step(db->files_st) != SQLITE_ROW){
ret = true; pdebug(__func__, "failed to execute select statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlSelectFail);
goto end;
}
free(line); hashdb = (char*)sqlite3_column_text(db->files_st, FILES_COLUMN_HASH-1);
ret = eq(hashdb, hash);
end:
if(NULL != db->files_st){
sqlite3_finalize(db->files_st);
db->files_st = NULL;
}
return ret; return ret;
} }
bool lm_database_files_iskeep(lm_database_t *db, char *path){ bool lm_database_files_iskeep(lm_database_t *db, char *path){
bool ret = false;
int iskeep = 0;
if(NULL == db || NULL == path){ if(NULL == db || NULL == path){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; goto end;
} }
char *line = NULL; if(sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_SINGLE], strlen(queries[QUERY_SELECT_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
bool ret = false; pdebug(__func__, "failed to prepare statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end;
}
sqlite3_bind_text(db->files_st, 1, path, strlen(path), SQLITE_STATIC);
if(NULL == (line = __lm_database_files_line_all(db, path))) if(!lm_database_step_all(db->files_st)){
return false; pdebug(__func__, "failed to execute select statement for selecting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlSelectFail);
goto end;
}
if(line[0] == '1') iskeep = sqlite3_column_int64(db->files_st, FILES_COLUMN_KEEP-1);
ret = true; ret = iskeep == 1;
free(line); end:
if(NULL != db->files_st){
sqlite3_finalize(db->files_st);
db->files_st = NULL;
}
return ret; return ret;
} }
bool lm_database_files_add(lm_database_t *db, lm_entry_t *entry, char *hash, char *path){ bool lm_database_files_add(lm_database_t *db, lm_entry_t *entry, char *path, char *hash){
if(NULL == db || NULL == entry || NULL == hash || NULL == path){ bool ret = false;
if(NULL == db || NULL == entry || NULL == path || NULL == hash){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; goto end;
} }
char files_path[__lm_files_size()];
FILE *filesp = NULL;
__lm_files_path(files_path); if(sqlite3_prepare(db->files_db, queries[QUERY_INSERT_FILE_SINGLE], strlen(queries[QUERY_INSERT_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for inserting %s: %s", path, sqlite3_errmsg(db->files_db));
if(NULL == (filesp = fopen(files_path, "a"))){ lm_error_set(LM_ERR_DbSqlPrepareFail);
lm_error_set(LM_ERR_DbFilesOpenFail, files_path); goto end;
return false;
} }
fwrite(lm_package_data_keep_contains(entry, path) ? "1:" : "0:", 1, 2, filesp);
fwrite(hash, 1, strlen(hash), filesp);
fwrite(":", 1, 1, filesp);
fwrite(path, 1, strlen(path), filesp);
fwrite("\n", 1, 1, filesp);
fclose(filesp); sqlite3_bind_text(db->files_st, FILES_COLUMN_PATH, path, strlen(path), SQLITE_STATIC);
return true; sqlite3_bind_text(db->files_st, FILES_COLUMN_HASH, hash, strlen(hash), SQLITE_STATIC);
if(lm_package_data_keep_contains(entry, path))
sqlite3_bind_int(db->files_st, FILES_COLUMN_KEEP, 1);
else
sqlite3_bind_int(db->files_st, FILES_COLUMN_KEEP, 0);
sqlite3_bind_text(db->files_st, FILES_COLUMN_ENTRY, entry->name, strlen(entry->name), SQLITE_STATIC);
if(!lm_database_step_all(db->files_st)){
pdebug(__func__, "failed to execute insert statement for inserting %s: %s", entry->name, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlInsertFail);
goto end;
}
ret = true;
end:
if(NULL != db->files_st){
sqlite3_finalize(db->files_st);
db->files_st = NULL;
}
return ret;
} }
bool lm_database_files_del(lm_database_t *db, lm_entry_t *entry){ bool lm_database_files_del(lm_database_t *db, lm_entry_t *entry){
@ -240,80 +182,60 @@ bool lm_database_files_del(lm_database_t *db, lm_entry_t *entry){
return false; return false;
} }
FILE *original = NULL, *temp = NULL; bool ret = false;
char temp_name[strlen(entry->name)+15];
char temp_path[__lm_files_size()+10];
char real_path[__lm_files_size()], *line = NULL;
bool ret = false, empty = true;
ssize_t line_len = 0;
__lm_files_path(real_path); if(sqlite3_prepare(db->files_db, queries[QUERY_DELETE_FILE_ALL], strlen(queries[QUERY_DELETE_FILE_ALL]), &db->files_st, NULL) != SQLITE_OK){
sprintf(temp_name, "%s_files.temp", entry->name); pdebug(__func__, "failed to prepare statement for deleting %s: %s", entry->name, sqlite3_errmsg(db->files_db));
join(temp_path, db->dir, temp_name); lm_error_set(LM_ERR_DbSqlPrepareFail);
if(NULL == (original = fopen(real_path, "r"))){
lm_error_set(LM_ERR_DbFilesOpenFail, real_path);
goto end;
}
if(NULL == (temp = fopen(temp_path, "a"))){
lm_error_set(LM_ERR_DbFilesOpenFail, temp_path);
goto end; goto end;
} }
while ((line_len = getline(&line, (size_t*)&line_len, original)) >= LINE_MIN){ sqlite3_bind_text(db->files_st, 1, entry->name, strlen(entry->name), SQLITE_STATIC);
if(line[0] == '1'){
fwrite(line, 1, line_len, temp);
empty = false;
}
free(line); if(!lm_database_step_all(db->files_st)){
line = NULL; pdebug(__func__, "failed to execute delete statement for deleting %s: %s", entry->name, sqlite3_errmsg(db->files_db));
line_len = 0; lm_error_set(LM_ERR_DbSqlDeleteFail);
goto end;
} }
ret = true; ret = true;
end: end:
if(NULL != original) if(NULL != db->files_st){
fclose(original); sqlite3_finalize(db->files_st);
db->files_st = NULL;
if(NULL != temp)
fclose(temp);
free(line);
if(ret && unlink(real_path) != 0){
lm_error_set(LM_ERR_DbFilesUnlinkFail, real_path);
ret = false;
} }
if(empty || !ret){
unlink(temp_path);
}
else if(ret && rename(temp_path, real_path) != 0){
lm_error_set(LM_ERR_DbFilesRenameFail, real_path);
ret = false;
}
return ret; return ret;
} }
bool lm_database_files_del_all(lm_database_t *db, lm_entry_t *entry){ bool lm_database_files_del_single(lm_database_t *db, char *path){
if(NULL == db || NULL == entry){ if(NULL == db || NULL == path){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;
} }
char files_path[__lm_files_size()];
__lm_files_path(files_path);
if(exists(files_path, NULL) && unlink(files_path) != 0){ bool ret = false;
lm_error_set(LM_ERR_DbFilesUnlinkFail, files_path);
return false; if(sqlite3_prepare(db->files_db, queries[QUERY_DELETE_FILE_SINGLE], strlen(queries[QUERY_DELETE_FILE_SINGLE]), &db->files_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for deleting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlPrepareFail);
goto end;
} }
return true; sqlite3_bind_text(db->files_st, 1, path, strlen(path), SQLITE_STATIC);
if(!lm_database_step_all(db->files_st)){
pdebug(__func__, "failed to execute delete statement for deleting %s: %s", path, sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlDeleteFail);
goto end;
}
ret = true;
end:
if(NULL != db->files_st){
sqlite3_finalize(db->files_st);
db->files_st = NULL;
}
return ret;
} }
bool lm_database_files_next(lm_database_t *db, lm_entry_t *entry, char **path, char **hash, bool *keep){ bool lm_database_files_next(lm_database_t *db, lm_entry_t *entry, char **path, char **hash, bool *keep){
@ -322,38 +244,33 @@ bool lm_database_files_next(lm_database_t *db, lm_entry_t *entry, char **path, c
return false; return false;
} }
if(NULL == db->filesp && NULL == (db->filesp = __lm_database_files_open(db, entry, "r"))) if(NULL == db->files_st){
return false; // error set by function if(sqlite3_prepare(db->files_db, queries[QUERY_SELECT_FILE_ALL], strlen(queries[QUERY_SELECT_FILE_ALL]), &db->files_st, NULL) != SQLITE_OK){
pdebug(__func__, "failed to prepare statement for selecting all: %s", sqlite3_errmsg(db->files_db));
lm_error_set(LM_ERR_DbSqlPrepareFail);
return false;
}
sqlite3_bind_text(db->files_st, 1, entry->name, strlen(entry->name), SQLITE_STATIC);
}
ssize_t line_len = 0; else if(NULL != db->files_st){
char *line = NULL; free(*path);
free(*hash);
*path = NULL;
*hash = NULL;
*keep = false;
}
if(NULL != *hash) if(sqlite3_step(db->files_st) != SQLITE_ROW){
free(*hash-HASH_INDEX); sqlite3_finalize(db->files_st);
db->files_st = NULL;
if((line_len = getline(&line, (size_t*)&line_len, db->filesp)) <= LINE_MIN) return false;
goto eof; }
if(line[line_len-1] == '\n')
line[line_len-1] = 0; // replace newline with null terminator
line[PATH_INDEX-1] = 0; // replace colon with null terminator
*keep = line[0] == '1';
*hash = line + HASH_INDEX;
*path = line + PATH_INDEX;
*path = strdup((char*)sqlite3_column_text(db->files_st, FILES_COLUMN_PATH-1));
*hash = strdup((char*)sqlite3_column_text(db->files_st, FILES_COLUMN_HASH-1));
*keep = sqlite3_column_int(db->files_st, FILES_COLUMN_KEEP-1) == 1;
return true; return true;
eof:
fclose(db->filesp);
free(line);
db->filesp = NULL;
*keep = false;
*path = NULL;
*hash = NULL;
return false;
} }
void lm_database_files_next_free(lm_database_t *db, lm_entry_t *entry, char **path, char **hash, bool *keep){ void lm_database_files_next_free(lm_database_t *db, lm_entry_t *entry, char **path, char **hash, bool *keep){
@ -362,14 +279,16 @@ void lm_database_files_next_free(lm_database_t *db, lm_entry_t *entry, char **pa
return; return;
} }
if(NULL != db->filesp) if(NULL != db->files_st){
fclose(db->filesp); sqlite3_finalize(db->files_st);
db->files_st = NULL;
}
if(NULL != path)
free(*path);
if(NULL != *hash) if(NULL != hash)
free(*hash-HASH_INDEX); free(*hash);
db->filesp = NULL;
*keep = false; *keep = false;
*path = NULL;
*hash = NULL;
} }

View File

@ -1,14 +1,12 @@
#include "../include/error.h" #include "../include/error.h"
#include "../include/util.h" #include "../include/util.h"
#include <pthread.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
lm_error_t lm_error_code = LM_ERR_NoError; // error code lm_error_t lm_error_code = LM_ERR_NoError;
char *lm_error_str = NULL; // error string char *lm_error_str = NULL;
pthread_t lm_error_thread = 0; // thread that is using the error system
void lm_error_clear() { void lm_error_clear() {
free(lm_error_str); free(lm_error_str);
@ -16,176 +14,154 @@ void lm_error_clear() {
lm_error_str = NULL; lm_error_str = NULL;
} }
void lm_error_init() {
lm_error_clear();
lm_error_code = LM_ERR_NoError;
lm_error_str = NULL;
lm_error_thread = pthread_self();
}
void lm_error_set(lm_error_t code, ...) { void lm_error_set(lm_error_t code, ...) {
if (!pthread_equal(pthread_self(), lm_error_thread)) // ignore error_set outside the main thread
return;
lm_error_desc_t errors[] = { lm_error_desc_t errors[] = {
{.code = LM_ERR_NoError, .desc = _("no error") }, {.code = LM_ERR_NoError, .desc = _("no error") },
{.code = LM_ERR_URLBadChar, .desc = _("URL contains an invalid character") }, {.code = LM_ERR_URLBadChar, .desc = _("URL contains an invalid character") },
{.code = LM_ERR_URLBadProtocol, .desc = _("URL does not have a valid protocol field") }, {.code = LM_ERR_URLBadProtocol, .desc = _("URL does not have a valid protocol field") },
{.code = LM_ERR_URLTooLarge, .desc = _("URL is too large") }, {.code = LM_ERR_URLTooLarge, .desc = _("URL is too large") },
{.code = LM_ERR_URLHostLarge, .desc = _("URL hostname is too large") }, {.code = LM_ERR_URLHostLarge, .desc = _("URL hostname is too large") },
{.code = LM_ERR_URLPathLarge, .desc = _("URL path is too large") }, {.code = LM_ERR_URLPathLarge, .desc = _("URL path is too large") },
{.code = LM_ERR_URLBadHost, .desc = _("URL does not have a valid hostname") }, {.code = LM_ERR_URLBadHost, .desc = _("URL does not have a valid hostname") },
{.code = LM_ERR_URLBadPort, .desc = _("URL does not have a valid port number") }, {.code = LM_ERR_URLBadPort, .desc = _("URL does not have a valid port number") },
{.code = LM_ERR_URLBadPath, .desc = _("URL does not have a valid path") }, {.code = LM_ERR_URLBadPath, .desc = _("URL does not have a valid path") },
{.code = LM_ERR_BadPort, .desc = _("hostname does not contain a valid port number") }, {.code = LM_ERR_BadPort, .desc = _("hostname does not contain a valid port number") },
{.code = LM_ERR_BadHost, .desc = _("hostname is not valid") }, {.code = LM_ERR_BadHost, .desc = _("hostname is not valid") },
{.code = LM_ERR_URLPortUnknown, .desc = _("URL protocol port number is unknown") }, {.code = LM_ERR_URLPortUnknown, .desc = _("URL protocol port number is unknown") },
{.code = LM_ERR_URLEnd, .desc = _("URL is incomplete") }, {.code = LM_ERR_URLEnd, .desc = _("URL is incomplete") },
{.code = LM_ERR_PoolNoSupport, .desc = _("pool does not support the specified protocol") }, {.code = LM_ERR_PoolNoSupport, .desc = _("pool does not support the specified protocol") },
{.code = LM_ERR_MPTPBadVersion, .desc = _("unsupported MPTP version") }, {.code = LM_ERR_MPTPBadVersion, .desc = _("unsupported MPTP version") },
{.code = LM_ERR_MPTPBadCode, .desc = _("invalid MPTP request/response code") }, {.code = LM_ERR_MPTPBadCode, .desc = _("invalid MPTP request/response code") },
{.code = LM_ERR_MPTPBadUrl, .desc = _("invalid MPTP URL") }, {.code = LM_ERR_MPTPBadUrl, .desc = _("invalid MPTP URL") },
{.code = LM_ERR_MPTPHostFail, .desc = _("failed to resolve hostname for MPTP connection") }, {.code = LM_ERR_MPTPHostFail, .desc = _("failed to resolve hostname for MPTP connection") },
{.code = LM_ERR_MPTPSocketFail, .desc = _("failed to create a MPTP socket") }, {.code = LM_ERR_MPTPSocketFail, .desc = _("failed to create a MPTP socket") },
{.code = LM_ERR_MPTPConnectFail, .desc = _("failed to connect to the MPTP host") }, {.code = LM_ERR_MPTPConnectFail, .desc = _("failed to connect to the MPTP host") },
{.code = LM_ERR_MPTPRecvFail, .desc = _("failed receive MPTP data from host: %s") }, {.code = LM_ERR_MPTPRecvFail, .desc = _("failed receive MPTP data from host") },
{.code = LM_ERR_MPTPSendFail, .desc = _("failed send MPTP data to host") }, {.code = LM_ERR_MPTPSendFail, .desc = _("failed send MPTP data to host") },
{.code = LM_ERR_MPTPBadData, .desc = _("MPTP data size is invalid") }, {.code = LM_ERR_MPTPBadData, .desc = _("MPTP data size is invalid") },
{.code = LM_ERR_MPTPBadHost, .desc = _("MPTP host size is invalid") }, {.code = LM_ERR_MPTPBadHost, .desc = _("MPTP host size is invalid") },
{.code = LM_ERR_MPTPBadPath, .desc = _("MPTP path size is invalid") }, {.code = LM_ERR_MPTPSetsockopt, .desc = _("failed to set MPTP socket options") },
{.code = LM_ERR_MPTPSetsockopt, .desc = _("failed to set MPTP socket options") }, {.code = LM_ERR_MPTPTimeout, .desc = _("MPTP connection timed out") },
{.code = LM_ERR_MPTPTimeout, .desc = _("MPTP connection timed out") }, {.code = LM_ERR_MPTPBindFail, .desc = _("failed to bind MPTP socket") },
{.code = LM_ERR_MPTPBindFail, .desc = _("failed to bind MPTP socket: %s") }, {.code = LM_ERR_ArgNULL, .desc = _("required argument is a NULL pointer or 0") },
{.code = LM_ERR_ArgNULL, .desc = _("required argument is a NULL pointer or 0") }, {.code = LM_ERR_MPTPNotRequest, .desc = _("not a MPTP request") },
{.code = LM_ERR_MPTPNotRequest, .desc = _("not a MPTP request") }, {.code = LM_ERR_MPTPNotResponse, .desc = _("not a MPTP response") },
{.code = LM_ERR_MPTPNotResponse, .desc = _("not a MPTP response") }, {.code = LM_ERR_MPTPNotLast, .desc = _("MPTP request last flag is not set") },
{.code = LM_ERR_MPTPNotLast, .desc = _("MPTP request last flag is not set") }, {.code = LM_ERR_MPTPNotLast, .desc = _("MPTP request last flag is not set") },
{.code = LM_ERR_MPTPNotLast, .desc = _("MPTP request last flag is not set") }, {.code = LM_ERR_NoPort, .desc = _("host port not specified") },
{.code = LM_ERR_NoPort, .desc = _("host port not specified") }, {.code = LM_ERR_PoolInfoBad, .desc = _("pool info is badly formatted or is not complete") },
{.code = LM_ERR_PoolInfoBad, .desc = _("pool info is badly formatted or is not complete") }, {.code = LM_ERR_ArcWBlockFail, .desc = _("failed to write block from archive") },
{.code = LM_ERR_ArcWBlockFail, .desc = _("failed to write block from archive") }, {.code = LM_ERR_ArcRBlockFail, .desc = _("failed to read block from archive") },
{.code = LM_ERR_ArcRBlockFail, .desc = _("failed to read block from archive") }, {.code = LM_ERR_ArcOpenFail, .desc = _("failed to open archive") },
{.code = LM_ERR_ArcOpenFail, .desc = _("failed to open archive") }, {.code = LM_ERR_ArcWHeaderFail, .desc = _("failed to write archive header") },
{.code = LM_ERR_ArcWHeaderFail, .desc = _("failed to write archive header") }, {.code = LM_ERR_ArcWEntryFail, .desc = _("failed to finish writing the archive entry") },
{.code = LM_ERR_ArcWEntryFail, .desc = _("failed to finish writing the archive entry") }, {.code = LM_ERR_ArcNewFail, .desc = _("failed to create new archive reader/writer") },
{.code = LM_ERR_ArcNewFail, .desc = _("failed to create new archive reader/writer") }, {.code = LM_ERR_ArcRealpathFail, .desc = _("failed to resolve full path for archive file") },
{.code = LM_ERR_ArcRealpathFail, .desc = _("failed to resolve full path for archive file") }, {.code = LM_ERR_ArcNextHeaderFail, .desc = _("failed to read the next header of the archive") },
{.code = LM_ERR_ArcNextHeaderFail, .desc = _("failed to read the next header of the archive") }, {.code = LM_ERR_GetCwdFail, .desc = _("failed to obtain current working directory") },
{.code = LM_ERR_GetCwdFail, .desc = _("failed to obtain current working directory") }, {.code = LM_ERR_PoolListDirFail, .desc = _("failed to open extracted pool list directory") },
{.code = LM_ERR_PoolListDirFail, .desc = _("failed to open extracted pool list directory") }, {.code = LM_ERR_PoolListCantRead, .desc = _("failed to read access the pool list file") },
{.code = LM_ERR_PoolListDataFail, .desc = _("failed to load \"%s\" data: %s") }, {.code = LM_ERR_PoolInfoCantRead, .desc = _("failed to read access the pool info file") },
{.code = LM_ERR_PoolListAddFail, .desc = _("failed add \"%s\" to the pool list: %s") }, {.code = LM_ERR_PkgDataBad, .desc = _("failed to parse package data") },
{.code = LM_ERR_PoolListCantRead, .desc = _("failed to read access the pool list file") }, {.code = LM_ERR_PkgBadName, .desc = _("package name is invalid") },
{.code = LM_ERR_PoolInfoCantRead, .desc = _("failed to read access the pool info file") }, {.code = LM_ERR_CtxDataNULL, .desc = _("data path is not set with in the ctx") },
{.code = LM_ERR_PkgDataBad, .desc = _("failed to parse package data") }, {.code = LM_ERR_CtxTempNULL, .desc = _("temp path is not set with in the ctx") },
{.code = LM_ERR_PkgBadName, .desc = _("package name is invalid") }, {.code = LM_ERR_CtxRootNULL, .desc = _("root path is not set with in the ctx") },
{.code = LM_ERR_PkgBadVersion, .desc = _("package version is invalid") }, {.code = LM_ERR_CtxTempFail, .desc = _("failed to set the ctx temp director to %s: %s") },
{.code = LM_ERR_PkgDataMissing, .desc = _("package data has missing field: %s") }, {.code = LM_ERR_CtxRootFail, .desc = _("failed to set the ctx root directory to %s: %s") },
{.code = LM_ERR_CtxDataNULL, .desc = _("data path is not set with in the ctx") }, {.code = LM_ERR_CtxDataFail, .desc = _("failed to set the ctx data directory to %s: %s") },
{.code = LM_ERR_CtxTempNULL, .desc = _("temp path is not set with in the ctx") }, {.code = LM_ERR_PoolTestNotPong, .desc = _("pool did not respond ping with pong") },
{.code = LM_ERR_CtxRootNULL, .desc = _("root path is not set with in the ctx") }, {.code = LM_ERR_PkgPathsEmpty, .desc = _("package file and directory paths are empty") },
{.code = LM_ERR_CtxTempFail, .desc = _("failed to set the ctx temp director to %s: %s") }, {.code = LM_ERR_SendOpenFail, .desc = _("failed to to open target file for sending") },
{.code = LM_ERR_CtxRootFail, .desc = _("failed to set the ctx root directory to %s: %s") }, {.code = LM_ERR_RecvDelFail, .desc = _("failed to to delete target file for receiving") },
{.code = LM_ERR_CtxDataFail, .desc = _("failed to set the ctx data directory to %s: %s") }, {.code = LM_ERR_RecvOpenFail, .desc = _("failed to to open target file for receiving") },
{.code = LM_ERR_PoolTestNotPong, .desc = _("pool did not respond ping with pong") }, {.code = LM_ERR_RecvBadCode, .desc = _("got a bad response code for receiving the target file") },
{.code = LM_ERR_PkgPathsEmpty, .desc = _("package file and directory paths are empty") }, {.code = LM_ERR_RecvWriteFail, .desc = _("failed to write to the target file for receiving") },
{.code = LM_ERR_SendOpenFail, .desc = _("failed to to open target file for sending") }, {.code = LM_ERR_PkgNotFound, .desc = _("package not found") },
{.code = LM_ERR_RecvDelFail, .desc = _("failed to to delete target file for receiving") }, {.code = LM_ERR_DbCantAccess, .desc = _("failed to access to the database file/directory") },
{.code = LM_ERR_RecvOpenFail, .desc = _("failed to to open target file for receiving") }, {.code = LM_ERR_DbSqlOpenFail, .desc = _("failed to open SQLite database") },
{.code = LM_ERR_RecvBadCode, .desc = _("got a bad response code for receiving the target file") }, {.code = LM_ERR_DbSqlCreateFail, .desc = _("failed to create table in SQLite database") },
{.code = LM_ERR_RecvWriteFail, .desc = _("failed to write to the target file for receiving") }, {.code = LM_ERR_DbSqlPrepareFail, .desc = _("failed to prepare statement for SQLite database") },
{.code = LM_ERR_PkgNotFound, .desc = _("package not found") }, {.code = LM_ERR_DbSqlInsertFail, .desc = _("failed to insert to the table in SQLite database") },
{.code = LM_ERR_DbCantAccess, .desc = _("failed to access to the database file/directory") }, {.code = LM_ERR_DbSqlSelectFail, .desc = _("failed to select from the table in SQLite database") },
{.code = LM_ERR_DbSqlOpenFail, .desc = _("failed to open SQLite database") }, {.code = LM_ERR_DbSqlDeleteFail, .desc = _("failed to delete from the table in SQLite database") },
{.code = LM_ERR_DbSqlCreateFail, .desc = _("failed to create table in SQLite database") }, {.code = LM_ERR_DbSqlNotFound, .desc = _("failed to find entry in SQLite database") },
{.code = LM_ERR_DbSqlPrepareFail, .desc = _("failed to prepare statement for SQLite database") }, {.code = LM_ERR_PkgGPGFail, .desc = _("failed to init GPG for package verification") },
{.code = LM_ERR_DbSqlInsertFail, .desc = _("failed to insert to the table in SQLite database") }, {.code = LM_ERR_PkgGPGSigFail, .desc = _("failed to import signature to GPG for package verification")},
{.code = LM_ERR_DbSqlSelectFail, .desc = _("failed to select from the table in SQLite database") }, {.code = LM_ERR_PkgGPGArchiveFail, .desc = _("failed to import archive to GPG for package verification") },
{.code = LM_ERR_DbSqlDeleteFail, .desc = _("failed to delete from the table in SQLite database") }, {.code = LM_ERR_PkgSigNoMatch, .desc = _("package signature verification failed with zero matches") },
{.code = LM_ERR_DbSqlNotFound, .desc = _("failed to find entry in SQLite database") }, {.code = LM_ERR_PkgSigNoResult, .desc = _("package signature verification failed with zero results") },
{.code = LM_ERR_PkgGPGFail, .desc = _("failed to init GPG for package verification") }, {.code = LM_ERR_PoolPathsEmpty, .desc = _("pool file and directory paths are empty") },
{.code = LM_ERR_PkgGPGSigFail, .desc = _("failed to import signature to GPG for package verification") }, {.code = LM_ERR_PoolNotAvailable, .desc = _("pool is not avaliable for connection") },
{.code = LM_ERR_PkgGPGArchiveFail, .desc = _("failed to import archive to GPG for package verification") }, {.code = LM_ERR_PoolUrlEmpty, .desc = _("pool URL is empty or invalid") },
{.code = LM_ERR_PkgSigNoMatch, .desc = _("package signature verification failed with zero matches") }, {.code = LM_ERR_PoolBadDir, .desc = _("pool directory path is not accessible") },
{.code = LM_ERR_PkgSigNoResult, .desc = _("package signature verification failed with zero results") }, {.code = LM_ERR_PoolBadPaths, .desc = _("pool directory sub-paths are not accessible") },
{.code = LM_ERR_PoolPathsEmpty, .desc = _("pool file and directory paths are empty") }, {.code = LM_ERR_DbFilesNotFound, .desc = _("package file list not found in the database") },
{.code = LM_ERR_PoolNotAvailable, .desc = _("pool is not avaliable for connection") }, {.code = LM_ERR_DbFilesOpenFail, .desc = _("failed to open package file list in the database") },
{.code = LM_ERR_PoolUrlEmpty, .desc = _("pool URL is empty or invalid") }, {.code = LM_ERR_DbFilesDirFail, .desc = _("failed to access package file list database directory") },
{.code = LM_ERR_PoolBadDir, .desc = _("pool directory path is not accessible") }, {.code = LM_ERR_DbFilesUnlinkFail, .desc = _("failed to remove package file list from the database") },
{.code = LM_ERR_PoolBadPaths, .desc = _("pool directory sub-paths are not accessible") }, {.code = LM_ERR_DbFilesWriteFail, .desc = _("failed to write to the file list in the database") },
{.code = LM_ERR_DbFilesNotFound, .desc = _("file list not found for the package") }, {.code = LM_ERR_DbKeepsNotFound, .desc = _("package keep list not found in the database") },
{.code = LM_ERR_DbFilesRenameFail, .desc = _("failed to rename the file list for the package: %s") }, {.code = LM_ERR_DbKeepsOpenFail, .desc = _("failed to open package keep list in the database") },
{.code = LM_ERR_DbFilesOpenFail, .desc = _("failed to open the package file list: %s") }, {.code = LM_ERR_DbKeepsDirFail, .desc = _("failed to access package keep list database directory") },
{.code = LM_ERR_DbFilesDirFail, .desc = _("failed to open the database directory: %s") }, {.code = LM_ERR_DbKeepsUnlinkFail, .desc = _("failed to remove package keep list from the database") },
{.code = LM_ERR_DbFilesUnlinkFail, .desc = _("failed to remove package file list: %s") }, {.code = LM_ERR_DependNotFound, .desc = _("failed to find %s (dependency of %s)") },
{.code = LM_ERR_DbKeepsNotFound, .desc = _("package keep list not found in the database") }, {.code = LM_ERR_InstallDownloadFail, .desc = _("failed to download %s for installation: %s") },
{.code = LM_ERR_DbKeepsOpenFail, .desc = _("failed to open package keep list in the database") }, {.code = LM_ERR_PkgNotDownloaded, .desc = _("package is not downloaded") },
{.code = LM_ERR_DbKeepsDirFail, .desc = _("failed to access package keep list database directory") }, {.code = LM_ERR_PkgRemoveDownloadFail, .desc = _("failed to remove downloaded package") },
{.code = LM_ERR_DbKeepsUnlinkFail, .desc = _("failed to remove package keep list from the database") }, {.code = LM_ERR_PkgRemoveDownloadFail, .desc = _("failed to remove downloaded package") },
{.code = LM_ERR_DependNotFound, .desc = _("failed to find %s (dependency of %s)") }, {.code = LM_ERR_DstOpenFail, .desc = _("failed to open the destination file") },
{.code = LM_ERR_InstallDownloadFail, .desc = _("failed to download %s for installation: %s") }, {.code = LM_ERR_SrcOpenFail, .desc = _("failed to open the source file") },
{.code = LM_ERR_PkgNotDownloaded, .desc = _("package is not downloaded") }, {.code = LM_ERR_DstWriteFail, .desc = _("failed to write to the destination file") },
{.code = LM_ERR_PkgRemoveDownloadFail, .desc = _("failed to remove downloaded package") }, {.code = LM_ERR_DstWriteFail, .desc = _("failed to write to the destination file") },
{.code = LM_ERR_PkgRemoveDownloadFail, .desc = _("failed to remove downloaded package") }, {.code = LM_ERR_PkgNoPool, .desc = _("package does not have associated pool") },
{.code = LM_ERR_DstOpenFail, .desc = _("failed to open the destination file") }, {.code = LM_ERR_CtxTempFailMkdir, .desc = _("failed to create specified temp directory") },
{.code = LM_ERR_SrcOpenFail, .desc = _("failed to open the source file") }, {.code = LM_ERR_PkgBadArchive, .desc = _("package archive does not contain required files") },
{.code = LM_ERR_DstWriteFail, .desc = _("failed to write to the destination file") }, {.code = LM_ERR_PkgDataNotMatch, .desc = _("package data does not match with target package") },
{.code = LM_ERR_DstWriteFail, .desc = _("failed to write to the destination file") }, {.code = LM_ERR_PkgChangesUpdateFail, .desc = _("failed to update changes file for package: %s") },
{.code = LM_ERR_PkgNoPool, .desc = _("package does not have associated pool") }, {.code = LM_ERR_PkgHashesOpenFail, .desc = _("failed to access package hashes file") },
{.code = LM_ERR_CtxTempFailMkdir, .desc = _("failed to create specified temp directory") }, {.code = LM_ERR_DbChangesUnlinkFail, .desc = _("failed to remove package changes file from the database") },
{.code = LM_ERR_PkgBadArchive, .desc = _("package archive does not contain required files") }, {.code = LM_ERR_SendStatFail, .desc = _("failed to stat target file for sending") },
{.code = LM_ERR_PkgDataNotMatch, .desc = _("package data does not match with target package") }, {.code = LM_ERR_SendSnprintfFail, .desc = _("failed to format target file size for sending") },
{.code = LM_ERR_PkgChangesUpdateFail, .desc = _("failed to update changes file for package: %s") }, {.code = LM_ERR_SendReadFail, .desc = _("failed to read target file size for sending") },
{.code = LM_ERR_PkgHashesOpenFail, .desc = _("failed to access package hashes file") }, {.code = LM_ERR_RecvBadSize, .desc = _("failed to parse target file size for receiving") },
{.code = LM_ERR_DbChangesUnlinkFail, .desc = _("failed to remove package changes file from the database") }, {.code = LM_ERR_RecvNotCompleted, .desc = _("target file is not fully received") },
{.code = LM_ERR_SendStatFail, .desc = _("failed to stat target file for sending") }, {.code = LM_ERR_ExtractStatFail, .desc = _("failed to stat for target extract archive") },
{.code = LM_ERR_SendSnprintfFail, .desc = _("failed to format target file size for sending") }, {.code = LM_ERR_PkgFilesAddFail, .desc = _("failed to add package file (%s) to the database: %s") },
{.code = LM_ERR_SendReadFail, .desc = _("failed to read target file size for sending") }, {.code = LM_ERR_PkgExtractFilesFail, .desc = _("failed to extract package files: %s") },
{.code = LM_ERR_RecvBadSize, .desc = _("failed to parse target file size for receiving") }, {.code = LM_ERR_PkgDatabaseAddFail, .desc = _("failed to add package to the database: %s") },
{.code = LM_ERR_RecvNotCompleted, .desc = _("target file is not fully received") }, {.code = LM_ERR_PkgAlreadyInstalled, .desc = _("package is already installed") },
{.code = LM_ERR_ExtractStatFail, .desc = _("failed to stat for target extract archive") }, {.code = LM_ERR_PkgNotInstalled, .desc = _("package is not installed") },
{.code = LM_ERR_PkgFilesAddFail, .desc = _("failed to add package file (%s) to the database: %s") }, {.code = LM_ERR_PkgFileUnlinkFail, .desc = _("failed to remove package file (%s): %s") },
{.code = LM_ERR_PkgExtractFilesFail, .desc = _("failed to extract package files: %s") }, {.code = LM_ERR_PkgDatabaseDelFail, .desc = _("failed to remove package from the database: %s") },
{.code = LM_ERR_PkgDatabaseAddFail, .desc = _("failed to add package to the database: %s") }, {.code = LM_ERR_PkgFilesDelFail, .desc = _("failed to remove package files from the database: %s") },
{.code = LM_ERR_PkgAlreadyInstalled, .desc = _("package is already installed") }, {.code = LM_ERR_PkgChangesDelFail, .desc = _("failed to remove changes file for package: %s") },
{.code = LM_ERR_PkgNotInstalled, .desc = _("package is not installed") }, {.code = LM_ERR_InstallCwdFail, .desc = _("failed to get current directory for running install") },
{.code = LM_ERR_PkgFileUnlinkFail, .desc = _("failed to remove package file (%s): %s") }, {.code = LM_ERR_InstallRootChdirFail, .desc = _("failed change directory to root for running install") },
{.code = LM_ERR_PkgDatabaseDelFail, .desc = _("failed to remove package from the database: %s") }, {.code = LM_ERR_InstallSpawnFail, .desc = _("failed run install spawn command") },
{.code = LM_ERR_PkgFilesDelFail, .desc = _("failed to remove package files from the database: %s") },
{.code = LM_ERR_PkgChangesDelFail, .desc = _("failed to remove changes file for package: %s") },
{.code = LM_ERR_InstallCwdFail, .desc = _("failed to get current directory for running install") },
{.code = LM_ERR_InstallRootChdirFail, .desc = _("failed change directory to root for running install") },
{.code = LM_ERR_InstallSpawnFail, .desc = _("failed run install spawn command") },
{.code = LM_ERR_InstallBackChdirFail, {.code = LM_ERR_InstallBackChdirFail,
.desc = _("failed to change directory to old directory after running install") }, .desc = _("failed to change directory to old directory after running install") },
{.code = LM_ERR_InstallStatusFail, .desc = _("install script returned a bad status code") }, {.code = LM_ERR_InstallStatusFail, .desc = _("install script returned a bad status code") },
{.code = LM_ERR_InstallRunFail, .desc = _("failed to run the package install script: %s") }, {.code = LM_ERR_InstallRunFail, .desc = _("failed to run the package install script: %s") },
{.code = LM_ERR_InstallSaveFail, .desc = _("failed to save the package install script: %s") }, {.code = LM_ERR_InstallSaveFail, .desc = _("failed to save the package install script: %s") },
{.code = LM_ERR_PkgBreaks, .desc = _("removing package breaks %s") }, {.code = LM_ERR_PkgBreaks, .desc = _("removing package breaks %s") },
{.code = LM_ERR_PkgUpToDate, .desc = _("package is already up-to-date") }, {.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_HashOpenFail, .desc = _("failed to open file for hashing") },
{.code = LM_ERR_HashDigestFail, .desc = _("failed create digest 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_FileHashFail, .desc = _("failed to get hash of %s: %s") },
{.code = LM_ERR_FileHashNoMatch, .desc = _("file hash does not match for %s") }, {.code = LM_ERR_FileHashNoMatch, .desc = _("file hash does not match for %s") },
{.code = LM_ERR_InfoNotLoaded, .desc = _("pool info is not loaded") }, {.code = LM_ERR_InfoNotLoaded, .desc = _("pool info is not loaded") },
{.code = LM_ERR_NoPools, .desc = _("pool list is empty") }, {.code = LM_ERR_NoPools, .desc = _("pool list is empty") },
{.code = LM_ERR_DbChangesNotExists, .desc = _("package changes file not found in the database") }, {.code = LM_ERR_DbChangesNotExists, .desc = _("package changes file not found in the database") },
{.code = LM_ERR_DbChangesChmodFail, .desc = _("failed to change mod of the changes file") }, {.code = LM_ERR_DbChangesChmodFail, .desc = _("failed to change mod of the changes file") },
{.code = LM_ERR_InstallDirFail, .desc = _("failed to create install script save directory") }, {.code = LM_ERR_InstallDirFail, .desc = _("failed to create install script save directory") },
{.code = LM_ERR_NoRead, .desc = _("directory does not have read permissions") }, {.code = LM_ERR_NoWrite, .desc = _("directory does not have write permissions") },
{.code = LM_ERR_NotDir, .desc = _("specified path is not a directory") }, {.code = LM_ERR_NotDir, .desc = _("specified path is not a directory") },
{.code = LM_ERR_FailMkdir, .desc = _("failed to create the specified directory") }, {.code = LM_ERR_FailMkdir, .desc = _("failed to create the specified directory") },
{.code = LM_ERR_PoolListBadDir, .desc = _("specified list extraction directory is not accessible") }, {.code = LM_ERR_PoolListBadDir, .desc = _("specified list extraction directory is not accessible") },
{.code = LM_ERR_FileNotExist, .desc = _("file does not exist: %s") }, {.code = LM_ERR_FileNotExist, .desc = _("file does not exist: %s") },
{.code = LM_ERR_FileNotLink, .desc = _("file is a symbolic link: %s") }, {.code = LM_ERR_FileNotLink, .desc = _("file is a symbolic link: %s") },
{.code = LM_ERR_ArchiveSetFail, .desc = _("failed to set the package archive") }, {.code = LM_ERR_ArchiveSetFail, .desc = _("failed to set the package archive") },
{.code = LM_ERR_ChdirFail, .desc = _("failed change directory: %s") },
{.code = LM_ERR_ExtractRootChdirFail, .desc = _("failed to change directory to root during extraction") },
{.code = LM_ERR_ExtractOldChdirFail, .desc = _("failed to change directory back from root during extraction")},
{.code = LM_ERR_MPTPAcceptFail, .desc = _("failed to accept the MPTP connection: %s") },
{.code = LM_ERR_MPTPListenFail, .desc = _("failed to listen the MPTP socket: %s") },
{.code = LM_ERR_PoolInfoBadName, .desc = _("pool name (%s) doesn't match with: %s") },
{.code = LM_ERR_PoolInfoUnknown, .desc = _("unknown key in the configuration: %s") },
}; };
char *fmt = NULL; char *fmt = NULL;
@ -219,13 +195,9 @@ void lm_error_set(lm_error_t code, ...) {
} }
char *lm_strerror() { char *lm_strerror() {
if (!pthread_equal(pthread_self(), lm_error_thread))
return NULL;
return lm_error_str; return lm_error_str;
} }
lm_error_t lm_error() { lm_error_t lm_error() {
if (!pthread_equal(pthread_self(), lm_error_thread))
return LM_ERR_UnknownThread;
return lm_error_code; return lm_error_code;
} }

View File

@ -15,8 +15,17 @@ int lm_mptp_client_connect(char *addr, uint16_t port) {
if ((sock = lm_mptp_socket(addr, port, &saddr)) < 0) if ((sock = lm_mptp_socket(addr, port, &saddr)) < 0)
return -1; return -1;
if(!lm_mptp_socket_opts(sock)) struct timeval timeout;
bzero(&timeout, sizeof(timeout));
timeout.tv_sec = MPTP_TIMEOUT;
timeout.tv_usec = 0;
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
lm_error_set(LM_ERR_MPTPSetsockopt);
lm_mptp_close(sock);
return -1; return -1;
}
if (connect(sock, &saddr, sizeof(saddr)) < 0) { if (connect(sock, &saddr, sizeof(saddr)) < 0) {
lm_mptp_close(sock); lm_mptp_close(sock);
@ -28,19 +37,15 @@ int lm_mptp_client_connect(char *addr, uint16_t port) {
} }
bool lm_mptp_client_verify(lm_mptp_t *packet) { bool lm_mptp_client_verify(lm_mptp_t *packet) {
if (!lm_mptp_verify(packet)){ if (!lm_mptp_verify(packet))
pdebug(__func__, "failed to verify the packet: %s", lm_strerror());
return false; return false;
}
if (MPTP_IS_REQUEST(packet)) { if (MPTP_IS_REQUEST(packet)) {
pdebug(__func__, "MPTP packet is a request");
lm_error_set(LM_ERR_MPTPNotResponse); lm_error_set(LM_ERR_MPTPNotResponse);
return false; return false;
} }
if (packet->header.host_size != 0) { if (packet->header.host_size != 0) {
pdebug(__func__, "MPTP response has host section");
lm_error_set(LM_ERR_MPTPBadHost); lm_error_set(LM_ERR_MPTPBadHost);
return false; return false;
} }
@ -51,59 +56,39 @@ bool lm_mptp_client_verify(lm_mptp_t *packet) {
bool lm_mptp_client_send(int sock, lm_mptp_t *packet) { bool lm_mptp_client_send(int sock, lm_mptp_t *packet) {
if (NULL == packet) { if (NULL == packet) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
lm_mptp_free(packet);
return false; return false;
} }
if (MPTP_FLAGS_VERSION(packet) != MPTP_VERSION_SUPPORTED) { if (MPTP_FLAGS_VERSION(packet) != MPTP_VERSION_SUPPORTED) {
lm_error_set(LM_ERR_MPTPBadVersion); lm_error_set(LM_ERR_MPTPBadVersion);
lm_mptp_free(packet);
return false; return false;
} }
if (packet->header.data_size > MPTP_DATA_MAX) { if (packet->header.data_size > MPTP_DATA_MAX) {
lm_error_set(LM_ERR_MPTPBadData); lm_error_set(LM_ERR_MPTPBadData);
lm_mptp_free(packet);
return false; return false;
} }
if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size <= 0) { if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size <= 0) {
lm_error_set(LM_ERR_MPTPBadHost); lm_error_set(LM_ERR_MPTPBadHost);
lm_mptp_free(packet);
return false; return false;
} }
char buffer[ char buffer[sizeof(packet->header) + packet->header.host_size + packet->header.data_size];
sizeof(packet->header) + ssize_t total = sizeof(buffer), used = 0;
packet->header.host_size +
packet->header.path_size + packet->header.flags = htons(packet->header.flags);
packet->header.data_size
];
ssize_t total = sizeof(buffer), used = 0, buflen = total;
bool ret = false;
copy_to_buffer(buffer, &packet->header, sizeof(packet->header), &total, &used); copy_to_buffer(buffer, &packet->header, sizeof(packet->header), &total, &used);
copy_to_buffer(buffer, packet->host, packet->header.host_size, &total, &used); copy_to_buffer(buffer, packet->host, packet->header.host_size, &total, &used);
copy_to_buffer(buffer, packet->path, packet->header.path_size, &total, &used);
copy_to_buffer(buffer, packet->data, packet->header.data_size, &total, &used); copy_to_buffer(buffer, packet->data, packet->header.data_size, &total, &used);
packet->header.flags = htons(packet->header.flags); if (send(sock, buffer, sizeof(buffer), 0) < 0) {
//packet->header.host_size = htons(packet->header.host_size);
//packet->header.path_size = htons(packet->header.path_size);
packet->header.data_size = htons(packet->header.data_size);
if (send(sock, buffer, sizeof(buffer), MSG_MORE) < 0) {
lm_error_set(LM_ERR_MPTPSendFail); lm_error_set(LM_ERR_MPTPSendFail);
goto end; return false;
} }
pdebug(__func__, "printing the packet dump (%lu bytes)", buflen); return true;
pdebug_binary(buffer, buflen);
ret = true;
end:
lm_mptp_free(packet);
return ret;
} }
bool lm_mptp_client_recv(int sock, lm_mptp_t *packet) { bool lm_mptp_client_recv(int sock, lm_mptp_t *packet) {
@ -112,15 +97,31 @@ bool lm_mptp_client_recv(int sock, lm_mptp_t *packet) {
return false; return false;
} }
lm_mptp_free(packet); char buffer[sizeof(packet->header) + MPTP_HOST_MAX + MPTP_DATA_MAX];
ssize_t total = sizeof(buffer), used = 0;
if(!lm_mptp_recv(sock, packet)){ bzero(buffer, sizeof(buffer));
pdebug(__func__, "failed to receive the packet: %s", lm_strerror()); bzero(packet, sizeof(lm_mptp_t));
return false; // error set by function
if (recv(sock, buffer, sizeof(buffer), 0) < 0) {
if (ETIMEDOUT == errno || EAGAIN == errno) {
lm_error_set(LM_ERR_MPTPTimeout);
return false;
}
lm_error_set(LM_ERR_MPTPRecvFail);
return false;
} }
pdebug(__func__, "printing the header dump"); copy_from_buffer(&packet->header, buffer, sizeof(packet->header), &total, &used);
pdebug_binary((char*)&packet->header, sizeof(packet->header)); packet->header.flags = ntohs(packet->header.flags);
// packet->header.host_size = ntohs(packet->header.host_size);
// packet->header.data_size = ntohs(packet->header.data_size);
if (packet->header.host_size <= MPTP_HOST_MAX)
copy_from_buffer(&packet->host, buffer, packet->header.host_size, &total, &used);
if (packet->header.data_size <= MPTP_DATA_MAX)
copy_from_buffer(&packet->data, buffer, packet->header.data_size, &total, &used);
return true; return true;
} }

View File

@ -2,20 +2,17 @@
#include "../../include/mptp.h" #include "../../include/mptp.h"
#include "../../include/url.h" #include "../../include/url.h"
#include <errno.h>
#include <netinet/tcp.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
void lm_mptp_init(lm_mptp_t *packet){ bool lm_mptp_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last) {
bzero(packet, sizeof(lm_mptp_t)); packet->header.flags = 0;
} packet->header.data_size = 0;
packet->header.host_size = 0;
bool lm_mptp_new(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last) { bzero(packet->data, MPTP_DATA_MAX);
lm_mptp_init(packet); bzero(packet->host, MPTP_HOST_MAX);
if (code > MPTP_CODE_MAX) { if (code > MPTP_CODE_MAX) {
lm_error_set(LM_ERR_MPTPBadCode); lm_error_set(LM_ERR_MPTPBadCode);
@ -29,27 +26,16 @@ bool lm_mptp_new(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last)
else else
packet->header.flags |= (MPTP_RESPONSE << 7); packet->header.flags |= (MPTP_RESPONSE << 7);
packet->header.flags |= (code << 3); packet->header.flags |= (code << 4);
if (is_last || is_request) if (is_last || is_request)
packet->header.flags |= (1 << 2); packet->header.flags |= (1 << 3);
else else
packet->header.flags |= (0 << 2); packet->header.flags |= (0 << 3);
return true; return true;
} }
void lm_mptp_free(lm_mptp_t *packet) {
if(NULL == packet)
return;
free(packet->host);
free(packet->path);
free(packet->data);
lm_mptp_init(packet);
}
bool lm_mptp_verify(lm_mptp_t *packet) { bool lm_mptp_verify(lm_mptp_t *packet) {
if (NULL == packet) { if (NULL == packet) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
@ -61,16 +47,6 @@ bool lm_mptp_verify(lm_mptp_t *packet) {
return false; return false;
} }
if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size < 0) {
lm_error_set(LM_ERR_MPTPBadHost);
return false;
}
if (packet->header.path_size > MPTP_PATH_MAX || packet->header.path_size < 0) {
lm_error_set(LM_ERR_MPTPBadPath);
return false;
}
if (packet->header.data_size > MPTP_DATA_MAX || packet->header.data_size < 0) { if (packet->header.data_size > MPTP_DATA_MAX || packet->header.data_size < 0) {
lm_error_set(LM_ERR_MPTPBadData); lm_error_set(LM_ERR_MPTPBadData);
return false; return false;
@ -84,41 +60,6 @@ bool lm_mptp_verify(lm_mptp_t *packet) {
return true; return true;
} }
bool lm_mptp_socket_opts(int sock){
struct timeval timeout;
int flags = 1;
bzero(&timeout, sizeof(timeout));
timeout.tv_sec = MPTP_TIMEOUT;
timeout.tv_usec = 0;
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
lm_error_set(LM_ERR_MPTPSetsockopt);
lm_mptp_close(sock);
return false;
}
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
lm_error_set(LM_ERR_MPTPSetsockopt);
lm_mptp_close(sock);
return false;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(int)) < 0) {
lm_error_set(LM_ERR_MPTPSetsockopt);
lm_mptp_close(sock);
return false;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &flags, sizeof(int)) < 0) {
lm_error_set(LM_ERR_MPTPSetsockopt);
lm_mptp_close(sock);
return false;
}
return true;
}
int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr) { int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr) {
if (NULL == addr || NULL == saddr) { if (NULL == addr || NULL == saddr) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
@ -130,7 +71,7 @@ int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr) {
bzero(&hints, sizeof(hints)); bzero(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = AF_INET; hints.ai_socktype = SOCK_DGRAM;
if ((status = getaddrinfo(addr, NULL, &hints, &res)) < 0) { if ((status = getaddrinfo(addr, NULL, &hints, &res)) < 0) {
lm_error_set(LM_ERR_MPTPHostFail); lm_error_set(LM_ERR_MPTPHostFail);
@ -167,7 +108,7 @@ int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr) {
return -1; return -1;
} }
if ((sock = socket(family, SOCK_STREAM, 0)) < 0) { if ((sock = socket(family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
lm_error_set(LM_ERR_MPTPSocketFail); lm_error_set(LM_ERR_MPTPSocketFail);
return -1; return -1;
} }
@ -186,13 +127,9 @@ bool lm_mptp_set_host(lm_mptp_t *packet, char *host) {
return false; return false;
} }
free(packet->host);
packet->host = malloc(size);
// do NOT copy the NULL terminator // do NOT copy the NULL terminator
packet->header.host_size = size; packet->header.host_size = size;
memcpy(packet->host, host, size); memcpy(packet->host, host, size);
return true; return true;
} }
@ -208,49 +145,14 @@ bool lm_mptp_get_host(lm_mptp_t *packet, char *host) {
return true; return true;
} }
bool lm_mptp_set_path(lm_mptp_t *packet, char *path) {
size_t size = strlen(path);
if (size > MPTP_PATH_MAX || size < 0) {
lm_error_set(LM_ERR_MPTPBadHost);
return false;
}
free(packet->path);
packet->path = malloc(size);
// do NOT copy the NULL terminator
packet->header.path_size = size;
memcpy(packet->path, path, size);
return true;
}
bool lm_mptp_get_path(lm_mptp_t *packet, char *path) {
if (packet->header.path_size > MPTP_PATH_MAX || packet->header.path_size < 0) {
path = NULL;
lm_error_set(LM_ERR_BadHost);
return false;
}
memcpy(path, packet->path, packet->header.path_size);
path[packet->header.path_size] = 0;
return true;
}
bool lm_mptp_set_data(lm_mptp_t *packet, char *data, size_t size) { bool lm_mptp_set_data(lm_mptp_t *packet, char *data, size_t size) {
if (size > MPTP_DATA_MAX || size < 0) { if (size > MPTP_DATA_MAX || size < 0) {
lm_error_set(LM_ERR_MPTPBadData); lm_error_set(LM_ERR_MPTPBadData);
return false; return false;
} }
free(packet->data); packet->header.data_size = size;
packet->data = malloc(size); mempcpy(packet->data, data, size);
if(NULL != data){
packet->header.data_size = size;
mempcpy(packet->data, data, size);
}
return true; return true;
} }
@ -266,56 +168,8 @@ bool lm_mptp_get_data(lm_mptp_t *packet, char *data) {
return true; return true;
} }
bool lm_mptp_recv(int sock, lm_mptp_t *packet) { void lm_mptp_copy(lm_mptp_t *dst, lm_mptp_t *src) {
if (recv(sock, &packet->header, sizeof(packet->header), MSG_WAITALL) <= 0) { memcpy(&dst->header, &src->header, sizeof(dst->header));
if (ETIMEDOUT == errno || EAGAIN == errno) { memcpy(&dst->host, &src->data, sizeof(src->host));
lm_error_set(LM_ERR_MPTPTimeout); memcpy(&dst->data, &src->data, sizeof(src->data));
return false;
}
lm_error_set(LM_ERR_MPTPRecvFail, strerror(errno));
return false;
}
/*packet->header.flags = ntohs(packet->header.flags);
packet->header.host_size = ntohs(packet->header.host_size);
packet->header.path_size = ntohs(packet->header.path_size);
packet->header.data_size = ntohs(packet->header.data_size);*/
if (packet->header.host_size <= MPTP_HOST_MAX && packet->header.host_size != 0){
packet->host = malloc(packet->header.host_size);
if(recv(sock, packet->host, packet->header.host_size, MSG_WAITALL) <= 0){
if (ETIMEDOUT == errno || EAGAIN == errno) {
lm_error_set(LM_ERR_MPTPTimeout);
return false;
}
lm_error_set(LM_ERR_MPTPRecvFail, strerror(errno));
return false;
}
}
if (packet->header.path_size <= MPTP_PATH_MAX && packet->header.path_size != 0){
packet->path = malloc(packet->header.path_size);
if(recv(sock, packet->path, packet->header.path_size, MSG_WAITALL) <= 0){
if (ETIMEDOUT == errno || EAGAIN == errno) {
lm_error_set(LM_ERR_MPTPTimeout);
return false;
}
lm_error_set(LM_ERR_MPTPRecvFail, strerror(errno));
return false;
}
}
if (packet->header.data_size <= MPTP_DATA_MAX && packet->header.data_size != 0){
packet->data = malloc(packet->header.data_size);
if(recv(sock, packet->data, packet->header.data_size, MSG_WAITALL) <= 0){
if (ETIMEDOUT == errno || EAGAIN == errno) {
lm_error_set(LM_ERR_MPTPTimeout);
return false;
}
lm_error_set(LM_ERR_MPTPRecvFail, strerror(errno));
return false;
}
}
return true;
} }

View File

@ -2,10 +2,8 @@
#include "../../include/mptp.h" #include "../../include/mptp.h"
#include "../../include/util.h" #include "../../include/util.h"
#include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <sys/socket.h>
int lm_mptp_server_listen(char *addr, uint16_t port) { int lm_mptp_server_listen(char *addr, uint16_t port) {
struct sockaddr saddr; struct sockaddr saddr;
@ -18,54 +16,28 @@ int lm_mptp_server_listen(char *addr, uint16_t port) {
if (bind(sock, &saddr, sizeof(struct sockaddr)) < 0) { if (bind(sock, &saddr, sizeof(struct sockaddr)) < 0) {
lm_mptp_close(sock); lm_mptp_close(sock);
lm_error_set(LM_ERR_MPTPBindFail, strerror(errno)); lm_error_set(LM_ERR_MPTPBindFail);
return -1;
}
if(listen(sock, SOMAXCONN) < 0){
lm_mptp_close(sock);
lm_error_set(LM_ERR_MPTPListenFail, strerror(errno));
return -1; return -1;
} }
return sock; return sock;
} }
int lm_mptp_server_accept(int sock, struct sockaddr *addr){
socklen_t sl = sizeof(struct sockaddr);
int s = -1;
if((s = accept(sock, addr, &sl)) < 0){
lm_error_set(LM_ERR_MPTPAcceptFail, strerror(errno));
s = -1;
}
if(!lm_mptp_socket_opts(s)){
close(s);
s = -1;
}
return s;
}
void lm_mptp_server_close(int sock){
close(sock); // you didn't see that comming, did you?
}
bool lm_mptp_server_verify(lm_mptp_t *packet) { bool lm_mptp_server_verify(lm_mptp_t *packet) {
if (!lm_mptp_verify(packet)){ if (!lm_mptp_verify(packet))
pdebug(__func__, "failed to verify the packet: %s", lm_strerror());
return false; return false;
}
if (!MPTP_IS_REQUEST(packet)) { if (!MPTP_IS_REQUEST(packet)) {
pdebug(__func__, "MPTP packet is not request");
lm_error_set(LM_ERR_MPTPNotRequest); lm_error_set(LM_ERR_MPTPNotRequest);
return false; return false;
} }
if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size <= 0) {
lm_error_set(LM_ERR_MPTPBadHost);
return false;
}
if (!MPTP_IS_LAST(packet)) { if (!MPTP_IS_LAST(packet)) {
pdebug(__func__, "MPTP packet is not the last");
lm_error_set(LM_ERR_MPTPNotLast); lm_error_set(LM_ERR_MPTPNotLast);
return false; return false;
} }
@ -73,76 +45,73 @@ bool lm_mptp_server_verify(lm_mptp_t *packet) {
return true; return true;
} }
bool lm_mptp_server_recv(int sock, lm_mptp_t *packet) { bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
if (NULL == packet) { if (NULL == packet || NULL == addr) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;
} }
lm_mptp_free(packet); char buffer[sizeof(packet->header) + MPTP_HOST_MAX + MPTP_DATA_MAX];
socklen_t socklen = sizeof(struct sockaddr);
ssize_t total = sizeof(buffer), used = 0;
if(!lm_mptp_recv(sock, packet)){ bzero(buffer, sizeof(buffer));
pdebug(__func__, "failed to receive the packet: %s", lm_strerror()); bzero(packet, sizeof(lm_mptp_t));
return false; // error set by function
if (recvfrom(sock, buffer, sizeof(buffer), 0, addr, &socklen) <= 0) {
lm_error_set(LM_ERR_MPTPRecvFail);
return false;
} }
copy_from_buffer(&packet->header, buffer, sizeof(packet->header), &total, &used);
packet->header.flags = ntohs(packet->header.flags);
// packet->header.host_size = ntohs(packet->header.host_size);
// packet->header.data_size = ntohs(packet->header.data_size);
if (packet->header.host_size <= MPTP_HOST_MAX)
copy_from_buffer(&packet->host, buffer, packet->header.host_size, &total, &used);
if (packet->header.data_size <= MPTP_DATA_MAX)
copy_from_buffer(&packet->data, buffer, packet->header.data_size, &total, &used);
return true; return true;
} }
bool lm_mptp_server_send(int sock, lm_mptp_t *packet) { bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
if (NULL == packet) { if (NULL == packet) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
lm_mptp_free(packet);
return false; return false;
} }
if (MPTP_FLAGS_VERSION(packet) != MPTP_VERSION_SUPPORTED) { if (MPTP_FLAGS_VERSION(packet) != MPTP_VERSION_SUPPORTED) {
lm_error_set(LM_ERR_MPTPBadVersion); lm_error_set(LM_ERR_MPTPBadVersion);
lm_mptp_free(packet);
return false; return false;
} }
if (packet->header.data_size > MPTP_DATA_MAX) { if (packet->header.data_size > MPTP_DATA_MAX) {
lm_error_set(LM_ERR_MPTPBadData); lm_error_set(LM_ERR_MPTPBadData);
lm_mptp_free(packet);
return false; return false;
} }
if (packet->header.host_size != 0) { if (packet->header.host_size != 0) {
lm_error_set(LM_ERR_MPTPBadHost); lm_error_set(LM_ERR_MPTPBadHost);
lm_mptp_free(packet);
return false; return false;
} }
char buffer[ socklen_t addrlen = sizeof(struct sockaddr);
sizeof(packet->header) + char buffer[sizeof(packet->header) + packet->header.host_size + packet->header.data_size];
packet->header.host_size + ssize_t total = sizeof(buffer), used = 0;
packet->header.path_size +
packet->header.data_size packet->header.flags = htons(packet->header.flags);
];
ssize_t total = sizeof(buffer), used = 0, buflen = total;
bool ret = false;
copy_to_buffer(buffer, &packet->header, sizeof(packet->header), &total, &used); copy_to_buffer(buffer, &packet->header, sizeof(packet->header), &total, &used);
copy_to_buffer(buffer, packet->host, packet->header.host_size, &total, &used); copy_to_buffer(buffer, packet->host, packet->header.host_size, &total, &used);
copy_to_buffer(buffer, packet->path, packet->header.path_size, &total, &used);
copy_to_buffer(buffer, packet->data, packet->header.data_size, &total, &used); copy_to_buffer(buffer, packet->data, packet->header.data_size, &total, &used);
packet->header.flags = htons(packet->header.flags);
//packet->header.host_size = htons(packet->header.host_size);
//packet->header.path_size = htons(packet->header.path_size);
packet->header.data_size = htons(packet->header.data_size);
if (send(sock, buffer, buflen, MSG_MORE) < 0) { if (sendto(sock, buffer, sizeof(buffer), 0, addr, addrlen) < 0) {
lm_error_set(LM_ERR_MPTPSendFail); lm_error_set(LM_ERR_MPTPSendFail);
goto end; return false;
} }
pdebug(__func__, "printing the packet dump (%lu bytes)", buflen); return true;
pdebug_binary(buffer, buflen);
ret = true;
end:
lm_mptp_free(packet);
return ret;
} }

View File

@ -3,15 +3,14 @@
#include "../../include/util.h" #include "../../include/util.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h> #include <errno.h>
#include <error.h> #include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
bool lm_mptp_sendfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data){ bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_transfer_callback_t callback, void *data){
if (NULL == path){ if (NULL == path || NULL == addr){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;
} }
@ -24,82 +23,69 @@ bool lm_mptp_sendfile(int sock, char *path, lm_mptp_transfer_callback_t callback
size_t read = 0; size_t read = 0;
struct stat st; struct stat st;
int size = -1; int size = -1;
lm_mptp_init(&packet);
if(NULL == file){ if(NULL == file){
pdebug(__func__, "failed to open file: %s", path); pdebug(__func__, "failed to open file: %s", path);
lm_error_set(LM_ERR_SendOpenFail); lm_error_set(LM_ERR_SendOpenFail);
goto end_1; lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
} }
if(fstat(fileno(file), &st)<0){ if(fstat(fileno(file), &st)<0){
pdebug(__func__, "failed to stat file: %s", path); pdebug(__func__, "failed to stat file: %s", path);
lm_error_set(LM_ERR_SendStatFail); lm_error_set(LM_ERR_SendStatFail);
goto end_1; lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
} }
total = st.st_size; total = st.st_size;
lm_mptp_new(&packet, false, MPTP_S2C_COOL, false); lm_mptp_init(&packet, false, MPTP_S2C_COOL, false);
lm_mptp_set_data(&packet, NULL, digits(total)); if((size = snprintf(packet.data, MPTP_DATA_MAX, "%lu", st.st_size)) <= 0){
if((size = snprintf(packet.data, MPTP_DATA_MAX, "%lu", total)) <= 0){
pdebug(__func__, "snprintf for stat size failed: %s", path); pdebug(__func__, "snprintf for stat size failed: %s", path);
lm_error_set(LM_ERR_SendSnprintfFail); lm_error_set(LM_ERR_SendSnprintfFail);
goto end_1; lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
} }
packet.header.data_size = size; packet.header.data_size = size;
lm_mptp_server_send(sock, &packet); lm_mptp_server_send(sock, &packet, addr);
if(NULL != callback && !callback(path, current, total, data)) if(NULL != callback)
goto end_1; if(!callback(path, current, total, data))
goto end;
// clear the packet // clear the packet
lm_mptp_new(&packet, false, MPTP_S2C_COOL, false); lm_mptp_init(&packet, false, MPTP_S2C_COOL, false);
lm_mptp_set_data(&packet, NULL, MPTP_DATA_MAX);
while ((read = fread(packet.data, 1, MPTP_DATA_MAX, file)) > 0) { while ((read = fread(packet.data, 1, MPTP_DATA_MAX, file)) > 0) {
packet.header.data_size = read; packet.header.data_size = read;
pdebug(__func__, "sending the %lu/%lu of %s", current+read, total, path); if(!lm_mptp_server_send(sock, &packet, addr))
goto end;
if(!lm_mptp_server_send(sock, &packet)){
pdebug(__func__, "failed to send packet for %s (left at %lu/%lu): %s", path, current, total, lm_strerror());
goto end_2;
}
current += read; current += read;
if(NULL != callback && !callback(path, current, st.st_size, data)) if(NULL != callback)
goto end_1; if(!callback(path, current, st.st_size, data))
goto end;
lm_mptp_free(&packet);
lm_mptp_init(&packet, false, MPTP_S2C_COOL, false);
lm_mptp_new(&packet, false, MPTP_S2C_COOL, false);
lm_mptp_set_data(&packet, NULL, MPTP_DATA_MAX);
} }
if(current != total){ if(current != total){
pdebug(__func__, "failed read the entire file (left at %lu/%lu): %s", current, total, path); pdebug(__func__, "failed read the entire file (left at %lu/%lu): %s", current, total, path);
lm_error_set(LM_ERR_SendReadFail); lm_error_set(LM_ERR_SendReadFail);
goto end_1; lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
} }
pdebug(__func__, "completed sending %s, sending last packet", path); lm_mptp_init(&packet, false, MPTP_S2C_COOL, true);
lm_mptp_new(&packet, false, MPTP_S2C_COOL, true);
lm_mptp_server_send(sock, &packet);
ret = true; ret = true;
goto end_2;
end_1: end:
lm_mptp_free(&packet);
lm_mptp_new(&packet, false, MPTP_S2C_BRUH, true);
lm_mptp_server_send(sock, &packet);
lm_mptp_free(&packet);
end_2:
if(NULL != file) if(NULL != file)
fclose(file); fclose(file);
lm_mptp_server_send(sock, &packet, addr);
return ret; return ret;
} }
@ -119,8 +105,6 @@ bool lm_mptp_recvfile(int sock, char *path, lm_mptp_transfer_callback_t callback
bool ret = false; bool ret = false;
lm_mptp_t packet; lm_mptp_t packet;
lm_mptp_init(&packet);
if(NULL == file){ if(NULL == file){
pdebug(__func__, "failed to open file: %s", path); pdebug(__func__, "failed to open file: %s", path);
lm_error_set(LM_ERR_RecvOpenFail); lm_error_set(LM_ERR_RecvOpenFail);
@ -143,30 +127,24 @@ bool lm_mptp_recvfile(int sock, char *path, lm_mptp_transfer_callback_t callback
lm_error_set(LM_ERR_RecvBadSize); lm_error_set(LM_ERR_RecvBadSize);
goto end; goto end;
} }
if(NULL != callback) if(NULL != callback)
if(!callback(path, current, total, data)) if(!callback(path, current, total, data))
goto end; goto end;
while(lm_mptp_client_recv(sock, &packet)){ while(lm_mptp_client_recv(sock, &packet)){
if(!lm_mptp_client_verify(&packet)){ if(!lm_mptp_client_verify(&packet))
pdebug(__func__, "failed to verify the packet for %s (%lu/%lu)", path, current, total);
goto end; goto end;
}
if(MPTP_FLAGS_CODE(&packet) != MPTP_S2C_COOL){ if(MPTP_FLAGS_CODE(&packet) != MPTP_S2C_COOL){
pdebug(__func__, "server responded with bad status code for %s (%lu/%lu)", path, current, total);
lm_error_set(LM_ERR_RecvBadCode); lm_error_set(LM_ERR_RecvBadCode);
goto end; goto end;
} }
if(MPTP_IS_LAST(&packet)){ if(MPTP_IS_LAST(&packet))
pdebug(__func__, "received the last packet for %s (%lu/%lu)", path, current, total);
break; break;
}
if(fwrite(packet.data, 1, packet.header.data_size, file)==0){ if(fwrite(packet.data, 1, packet.header.data_size, file)==0){
pdebug(__func__, "failed to write received data for %s (%lu/%lu)", path, current, total);
lm_error_set(LM_ERR_RecvWriteFail); lm_error_set(LM_ERR_RecvWriteFail);
goto end; goto end;
} }
@ -179,17 +157,13 @@ bool lm_mptp_recvfile(int sock, char *path, lm_mptp_transfer_callback_t callback
} }
if(current != total){ if(current != total){
if(MPTP_IS_LAST(&packet)) pdebug(__func__, "failed to receive the entire file (left at %lu/%lu): %s (%s)", current, total, path, lm_strerror());
pdebug(__func__, "failed to receive the entire file (left at %lu/%lu), got the last packet: %s", current, total, path);
else
pdebug(__func__, "failed to receive the entire file (left at %lu/%lu): %s (%s)", current, total, path, lm_strerror());
lm_error_set(LM_ERR_RecvNotCompleted); lm_error_set(LM_ERR_RecvNotCompleted);
goto end; goto end;
} }
ret = true; ret = true;
end: end:
lm_mptp_free(&packet);
if(NULL != file) if(NULL != file)
fclose(file); fclose(file);
return ret; return ret;

View File

@ -12,10 +12,8 @@ int lm_package_data_handler(void *_data, const char *_section, const char *_key,
lm_pkg_data_t *data = _data; lm_pkg_data_t *data = _data;
if(NULL == data->name){ if(NULL == data->name){
if(!package_name_valid(section)){ if(!package_name_valid(section))
lm_error_set(LM_ERR_PkgBadName);
return 0; return 0;
}
data->name = strdup(section); data->name = strdup(section);
} }
@ -26,10 +24,8 @@ int lm_package_data_handler(void *_data, const char *_section, const char *_key,
data->desc = strdup(value); data->desc = strdup(value);
else if(eq(key, PKG_DATA_VERSION)){ else if(eq(key, PKG_DATA_VERSION)){
if(!package_version_valid(value)){ if(!package_version_valid(value))
lm_error_set(LM_ERR_PkgBadVersion);
return 0; return 0;
}
data->version = strdup(value); data->version = strdup(value);
} }
@ -51,26 +47,13 @@ int lm_package_data_handler(void *_data, const char *_section, const char *_key,
bool lm_package_data_load(lm_pkg_data_t *data, char *file){ bool lm_package_data_load(lm_pkg_data_t *data, char *file){
lm_package_data_free(data); lm_package_data_free(data);
lm_error_clear();
if (ini_parse(file, lm_package_data_handler, data) < 0) { if (ini_parse(file, lm_package_data_handler, data) < 0) {
lm_error_set(LM_ERR_PkgDataBad); lm_error_set(LM_ERR_PkgDataBad);
return false; return false;
} }
if(LM_ERR_NoError != lm_error()) return true;
return false;
if(NULL == data->name)
lm_error_set(LM_ERR_PkgDataMissing, "name");
else if(NULL == data->desc)
lm_error_set(LM_ERR_PkgDataMissing, "desc");
else if(NULL == data->version)
lm_error_set(LM_ERR_PkgDataMissing, "version");
else if(0 == data->size)
lm_error_set(LM_ERR_PkgDataMissing, "size");
return LM_ERR_NoError == lm_error();
} }
void lm_package_data_free(lm_pkg_data_t *data){ void lm_package_data_free(lm_pkg_data_t *data){
@ -79,5 +62,5 @@ void lm_package_data_free(lm_pkg_data_t *data){
free(data->version); free(data->version);
lm_package_data_depend_free(data); lm_package_data_depend_free(data);
lm_package_data_keep_free(data); lm_package_data_keep_free(data);
bzero(data, sizeof(lm_pkg_data_t)); bzero(&data, sizeof(lm_pkg_data_t));
} }

View File

@ -42,6 +42,7 @@ lm_pkg_files_t *lm_package_extract(lm_pkg_t *pkg, char *target){
if(!__lm_package_extract_check(files->data_file) || if(!__lm_package_extract_check(files->data_file) ||
!__lm_package_extract_check(files->hashes_file) || !__lm_package_extract_check(files->hashes_file) ||
!__lm_package_extract_check(files->changes_file) || !__lm_package_extract_check(files->changes_file) ||
!__lm_package_extract_check(files->install_file) ||
!__lm_package_extract_check(files->files_archive)){ !__lm_package_extract_check(files->files_archive)){
goto end; goto end;
} }

View File

@ -12,26 +12,17 @@ int lm_pool_info_handler(void *data, const char *_section, const char *_key, con
char *section = (char *)_section, *value = (char *)_value, *key = (char *)_key; char *section = (char *)_section, *value = (char *)_value, *key = (char *)_key;
lm_pool_t *pool = data; lm_pool_t *pool = data;
if (!eq(pool->name, section)){ if (!eq(pool->name, section))
pdebug(__func__, "pool name (%s) doesn't match: %s", pool->name, section);
lm_error_set(LM_ERR_PoolInfoBadName, pool->name, section);
return 0; return 0;
}
if (eq(key, POOL_INFO_SIZE)) if (eq(key, POOL_INFO_SIZE))
pool->info.size = atol(value); pool->info.size = atol(value);
else if (eq(key, POOL_INFO_MAINTAINER)) else if (eq(key, POOL_INFO_MAINTAINER))
pool->info.maintainer = strdup(value); pool->info.maintainer = strdup(value);
else if (eq(key, POOL_INFO_PUBKEY)) else if (eq(key, POOL_INFO_PUBKEY))
pool->info.pubkey = strdup(value); pool->info.pubkey = strdup(value);
else
else{
pdebug(__func__, "pool info contains unknown key: %s", key);
lm_error_set(LM_ERR_PoolInfoUnknown, key);
return 0; return 0;
}
return 1; return 1;
} }
@ -54,19 +45,15 @@ bool lm_pool_info_load(lm_pool_t *pool) {
return false; return false;
} }
lm_error_clear();
if (ini_parse(pool->info_file, lm_pool_info_handler, pool) < 0) { if (ini_parse(pool->info_file, lm_pool_info_handler, pool) < 0) {
if(lm_error() == LM_ERR_NoError) lm_error_set(LM_ERR_PoolInfoBad);
lm_error_set(LM_ERR_PoolInfoBad);
return false; return false;
} }
if(pool->info.size <= 0 || if(pool->info.size <= 0 ||
pool->info.pubkey == NULL || pool->info.pubkey == NULL ||
pool->info.maintainer == NULL){ pool->info.maintainer == NULL){
if(lm_error() == LM_ERR_NoError) lm_error_set(LM_ERR_PoolInfoBad);
lm_error_set(LM_ERR_PoolInfoBad);
return false; return false;
} }
@ -89,7 +76,7 @@ bool lm_pool_info_download(lm_pool_t *pool, lm_mptp_transfer_callback_t callback
return false; return false;
} }
if(!mkdir_ifnot(pool->dir, 0755)){ if(!mkdir_ifnot(pool->dir)){
lm_error_set(LM_ERR_PoolBadDir); lm_error_set(LM_ERR_PoolBadDir);
return false; return false;
} }
@ -106,23 +93,18 @@ bool lm_pool_info_download(lm_pool_t *pool, lm_mptp_transfer_callback_t callback
if((sock = lm_mptp_client_connect(pool->url.host, pool->url.port)) < 0) if((sock = lm_mptp_client_connect(pool->url.host, pool->url.port)) < 0)
return false; return false;
lm_mptp_new(&packet, true, MPTP_C2S_INFO, true); lm_mptp_init(&packet, true, MPTP_C2S_INFO, true);
lm_mptp_set_host(&packet, pool->url.host); lm_mptp_set_host(&packet, pool->url.host);
lm_mptp_set_path(&packet, pool->url.path); lm_mptp_set_data(&packet, pool->url.path, strlen(pool->url.path));
if(!lm_mptp_client_send(sock, &packet)){ if(!lm_mptp_client_send(sock, &packet))
pdebug(__func__, "info file request failed for %s: %s", pool->name, lm_strerror());
goto end; goto end;
}
if(!lm_mptp_recvfile(sock, pool->info_file, callback, data)){ if(!lm_mptp_recvfile(sock, pool->info_file, callback, data))
pdebug(__func__, "recvfile failed for %s: %s", pool->name, lm_strerror());
goto end; goto end;
}
ret = true; ret = true;
end: end:
lm_mptp_free(&packet);
lm_mptp_close(sock); lm_mptp_close(sock);
if(ret) if(ret)
ret = lm_pool_info_load(pool); ret = lm_pool_info_load(pool);

View File

@ -15,7 +15,7 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
return false; return false;
} }
lm_pool_list_free(pool); lm_pool_list_free(pool);
if(lm_pool_path_is_empty(pool)){ if(lm_pool_path_is_empty(pool)){
@ -30,12 +30,12 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){
pdebug(__func__, "(%s) extracting pool to %s", pool->name, dir); pdebug(__func__, "(%s) extracting pool to %s", pool->name, dir);
if(!mkdir_ifnot(pool->dir, 0755)){ if(!mkdir_ifnot(pool->dir)){
lm_error_set(LM_ERR_PoolBadDir); lm_error_set(LM_ERR_PoolBadDir);
return false; return false;
} }
if(!mkdir_ifnot(dir, 0755)){ if(!mkdir_ifnot(dir)){
lm_error_set(LM_ERR_PoolListBadDir); lm_error_set(LM_ERR_PoolListBadDir);
return false; return false;
} }
@ -52,7 +52,7 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){
lm_error_set(LM_ERR_PoolListDirFail); lm_error_set(LM_ERR_PoolListDirFail);
goto end; goto end;
} }
while((ent = readdir(dirfd)) != NULL){ while((ent = readdir(dirfd)) != NULL){
if(eq(ent->d_name, "..") || eq(ent->d_name, ".")) if(eq(ent->d_name, "..") || eq(ent->d_name, "."))
continue; continue;
@ -60,29 +60,21 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){
ent_len = strlen(ent->d_name); ent_len = strlen(ent->d_name);
char datap[ent_len+list_dir_len+10]; char datap[ent_len+list_dir_len+10];
join_multiple(datap, dir, ent->d_name, "DATA"); join_multiple(datap, dir, ent->d_name, "DATA");
lm_pkg_t *pkg = lm_package_new(); lm_pkg_t *pkg = lm_package_new();
if(!lm_package_data_load(&pkg->data, datap)){ if(!lm_package_data_load(&pkg->data, datap)){
pdebug(__func__, "(%s) failed to load new package from %s: %s", pool->name, datap, lm_strerror()); pdebug(__func__, "(%s) failed to load new package from %s", pool->name, datap);
if(NULL != pkg->data.name){
char *suberr = lm_strerror_dup();
lm_error_set(LM_ERR_PoolListDataFail, pkg->data.name, suberr);
free(suberr);
}
lm_package_free(pkg); lm_package_free(pkg);
goto end; continue;
} }
if(!lm_pool_package_add(pool, pkg)){ if(!lm_pool_package_add(pool, pkg)){
pdebug(__func__, "(%s) failed to add package %s: %s", pool->name, pkg->data.name, lm_strerror()); pdebug(__func__, "(%s) failed to add new package: %s", pool->name, pkg->data.name);
char *suberr = lm_strerror_dup();
lm_error_set(LM_ERR_PoolListAddFail, pkg->data.name, suberr);
free(suberr);
lm_package_free(pkg); lm_package_free(pkg);
goto end; continue;
} }
pdebug(__func__, "(%s) added new package: %s", pool->name, pkg->data.name); pdebug(__func__, "(%s) added new package: %s", pool->name, pkg->data.name);
} }
@ -110,7 +102,7 @@ bool lm_pool_list_download(lm_pool_t *pool, char *dir, lm_mptp_transfer_callback
return false; return false;
} }
if(!mkdir_ifnot(pool->dir, 0755)){ if(!mkdir_ifnot(pool->dir)){
lm_error_set(LM_ERR_PoolBadDir); lm_error_set(LM_ERR_PoolBadDir);
return false; return false;
} }
@ -127,23 +119,18 @@ bool lm_pool_list_download(lm_pool_t *pool, char *dir, lm_mptp_transfer_callback
if((sock = lm_mptp_client_connect(pool->url.host, pool->url.port)) < 0) if((sock = lm_mptp_client_connect(pool->url.host, pool->url.port)) < 0)
return false; return false;
lm_mptp_new(&packet, true, MPTP_C2S_LIST, true); lm_mptp_init(&packet, true, MPTP_C2S_LIST, true);
lm_mptp_set_host(&packet, pool->url.host); lm_mptp_set_host(&packet, pool->url.host);
lm_mptp_set_path(&packet, pool->url.path); lm_mptp_set_data(&packet, pool->url.path, strlen(pool->url.path));
if(!lm_mptp_client_send(sock, &packet)){ if(!lm_mptp_client_send(sock, &packet))
pdebug(__func__, "list file request failed for %s: %s", pool->name, lm_strerror());
goto end; goto end;
}
if(!lm_mptp_recvfile(sock, pool->list_file, callback, data))
if(!lm_mptp_recvfile(sock, pool->list_file, callback, data)){
pdebug(__func__, "recvfile failed for %s: %s", pool->name, lm_strerror());
goto end; goto end;
}
ret = true; ret = true;
end: end:
lm_mptp_free(&packet);
lm_mptp_close(sock); lm_mptp_close(sock);
if(ret) if(ret)
ret = lm_pool_list_load(pool, dir); ret = lm_pool_list_load(pool, dir);

View File

@ -17,7 +17,7 @@ bool lm_pool_path_set_dir(lm_pool_t *pool, char *dir){
if(NULL == dir) if(NULL == dir)
return true; return true;
if(exists(dir, NULL) && (is_file(dir) || !can_read(dir))){ if(exists(dir, NULL) && (is_file(dir) || !can_read(dir) || !can_write(dir))){
lm_error_set(LM_ERR_PoolBadDir); lm_error_set(LM_ERR_PoolBadDir);
return false; return false;
} }
@ -26,12 +26,12 @@ bool lm_pool_path_set_dir(lm_pool_t *pool, char *dir){
pool->info_file = join_alloc(dir, "INFO"); pool->info_file = join_alloc(dir, "INFO");
pool->list_file = join_alloc(dir, "LIST"); pool->list_file = join_alloc(dir, "LIST");
if(exists(pool->info_file, NULL) && (!is_file(pool->info_file) || !can_read(pool->info_file))){ if(exists(pool->info_file, NULL) && (!is_file(pool->info_file) || !can_read(pool->info_file) || !can_write(pool->info_file))){
lm_error_set(LM_ERR_PoolBadPaths); lm_error_set(LM_ERR_PoolBadPaths);
return false; return false;
} }
if(exists(pool->list_file, NULL) && (!is_file(pool->list_file) || !can_read(pool->list_file))){ if(exists(pool->list_file, NULL) && (!is_file(pool->list_file) || !can_read(pool->list_file) || !can_write(pool->list_file))){
lm_error_set(LM_ERR_PoolBadPaths); lm_error_set(LM_ERR_PoolBadPaths);
return false; return false;
} }

View File

@ -30,10 +30,10 @@ lm_pool_t *lm_pool_new(char *name, char *url) {
void lm_pool_test(lm_pool_t *pool) { void lm_pool_test(lm_pool_t *pool) {
lm_mptp_t packet; lm_mptp_t packet;
lm_mptp_new(&packet, true, MPTP_C2S_PING, true); lm_mptp_init(&packet, true, MPTP_C2S_PING, true);
lm_mptp_set_host(&packet, pool->url.host); lm_mptp_set_host(&packet, pool->url.host);
lm_mptp_set_path(&packet, pool->url.path); lm_mptp_set_data(&packet, pool->url.path, strlen(pool->url.path));
int sock = lm_mptp_client_connect(pool->url.host, pool->url.port); int sock = lm_mptp_client_connect(pool->url.host, pool->url.port);
if (sock == -1) { if (sock == -1) {
@ -60,7 +60,6 @@ void lm_pool_test(lm_pool_t *pool) {
if(!pool->available) if(!pool->available)
lm_error_set(LM_ERR_PoolTestNotPong); lm_error_set(LM_ERR_PoolTestNotPong);
end: end:
lm_mptp_free(&packet);
lm_mptp_close(sock); lm_mptp_close(sock);
return; return;
} }

View File

@ -29,19 +29,6 @@ void pdebug(const char *func, const char *fmt, ...) {
va_end(args); va_end(args);
} }
void pdebug_binary(char *data, size_t len) {
if (LM_DEBUG != 1)
return;
for (size_t i = 0; i < len; i++) {
if (i != 0 && i % 4 == 0)
printf("\n");
printf("%c%c%c%c%c%c%c%c ", BINARY(data[i]));
}
printf("\n");
}
bool eq(char *s1, char *s2) { bool eq(char *s1, char *s2) {
if (NULL == s1 || NULL == s2) if (NULL == s1 || NULL == s2)
return false; return false;
@ -108,9 +95,7 @@ bool copy_to_buffer(void *buffer, void *src, size_t size, ssize_t *total, ssize_
if (*used == 0) if (*used == 0)
bzero(buffer, *total); bzero(buffer, *total);
if (NULL != buffer && NULL != src && size > 0) memcpy(buffer + *used, src, size);
memcpy(buffer + *used, src, size);
*used += size; *used += size;
return true; return true;
} }
@ -122,9 +107,7 @@ bool copy_from_buffer(void *dst, void *buffer, size_t size, ssize_t *total, ssiz
if (*used == 0) if (*used == 0)
bzero(dst, size); bzero(dst, size);
if (NULL != buffer && NULL != dst && size > 0) memcpy(dst, buffer + *used, size);
memcpy(dst, buffer + *used, size);
*used += size; *used += size;
return true; return true;
} }
@ -171,10 +154,7 @@ bool extract_archive(char *dst, char *src) {
goto end; goto end;
} }
if (chdir(dst) < 0) { chdir(dst);
lm_error_set(LM_ERR_ChdirFail, dst);
goto end;
}
flags = ARCHIVE_EXTRACT_PERM; flags = ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_UNLINK; flags |= ARCHIVE_EXTRACT_UNLINK;
@ -234,10 +214,7 @@ end:
} }
if (NULL != oldpwd) { if (NULL != oldpwd) {
if (chdir(oldpwd) < 0) { chdir(oldpwd);
lm_error_set(LM_ERR_ChdirFail, oldpwd);
ret = false;
}
free(oldpwd); free(oldpwd);
} }
@ -278,12 +255,20 @@ bool can_write(char *path) {
return access(path, W_OK) == 0; return access(path, W_OK) == 0;
} }
bool mkdir_ifnot(char *path, int mode) { bool mkdir_ifnot(char *path) {
return !(mkdir(path, mode) < 0 && errno != EEXIST); return !(mkdir(path, 0700) < 0 && errno != EEXIST);
} }
bool __package_field_valid(char *field) { bool package_name_valid(char *name) {
for (char *c = field; *c != 0; c++) { for (char *c = name; *c != 0; c++) {
if (!is_digit(*c) && !is_letter(*c) && *c != '-' && *c != '.')
return false;
}
return true;
}
bool package_version_valid(char *version) {
for (char *c = version; *c != 0; c++) {
if (!is_digit(*c) && !is_letter(*c) && *c != '-' && *c != '+' && *c != '.') if (!is_digit(*c) && !is_letter(*c) && *c != '-' && *c != '+' && *c != '.')
return false; return false;
} }
@ -346,6 +331,81 @@ char *join_alloc(const char *base, const char *pth) {
return path; return path;
} }
bool pkglist_contains(lm_pkg_t *list, lm_pkg_t *pkg) {
lm_pkg_t *cur = list;
while (cur) {
if (eq(pkg->data.name, cur->data.name))
return true;
cur = cur->next;
}
return false;
}
lm_pkg_t *pkglist_del(lm_pkg_t *list, lm_pkg_t *pkg) {
if (NULL == pkg) {
lm_error_set(LM_ERR_ArgNULL);
return list;
}
if (NULL == list)
return list;
if (eq(list->data.name, pkg->data.name)) {
list = NULL;
return list;
}
lm_pkg_t *cur = list;
lm_pkg_t *found = NULL;
while (NULL != cur->next) {
if (eq(cur->next->data.name, pkg->data.name)) {
found = cur->next;
cur->next = cur->next->next;
break;
}
cur = cur->next;
}
free(found);
return list;
}
lm_pkg_t *pkglist_add_top(lm_pkg_t *list, lm_pkg_t *pkg) {
lm_pkg_t *new = malloc(sizeof(lm_pkg_t));
memcpy(new, pkg, sizeof(lm_pkg_t));
new->next = list;
list = new;
return list;
}
lm_pkg_t *pkglist_add_end(lm_pkg_t *list, lm_pkg_t *pkg) {
lm_pkg_t *new = malloc(sizeof(lm_pkg_t)), *cur = list;
memcpy(new, pkg, sizeof(lm_pkg_t));
new->next = NULL;
if (NULL == cur) {
list = new;
return list;
}
while (cur->next != NULL)
cur = cur->next;
cur->next = new;
return list;
}
void pkglist_free(lm_pkg_t *list) {
lm_pkg_t *cur = list, *old = NULL;
while (cur != NULL) {
old = cur;
cur = cur->next;
free(old);
}
}
bool copy_file(char *dst, char *src) { bool copy_file(char *dst, char *src) {
FILE *dstp = NULL, *srcp = NULL; FILE *dstp = NULL, *srcp = NULL;
bool ret = false; bool ret = false;
@ -503,11 +563,3 @@ bool is_dir_empty(char *p) {
closedir(fd); closedir(fd);
return empty; return empty;
} }
int digits(int n) {
if (n < 0)
return digits((n == INT_MIN) ? INT_MAX : -n);
if (n < 10)
return 1;
return 1 + digits(n / 10);
}