libmp/src/util.c

256 lines
5.1 KiB
C
Raw Normal View History

2024-06-20 00:34:32 +00:00
#include "../include/util.h"
2024-06-22 04:03:17 +00:00
#include "../include/error.h"
#include "../include/types.h"
#include <archive.h>
#include <arpa/inet.h>
#include <errno.h>
2024-06-22 04:03:17 +00:00
#include <error.h>
#include <linux/limits.h>
#include <netinet/in.h>
2024-06-20 00:34:32 +00:00
#include <stdarg.h>
2024-06-20 22:36:56 +00:00
#include <stdio.h>
2024-06-20 00:34:32 +00:00
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
2024-06-20 00:34:32 +00:00
void pdebug(const char *func, const char *fmt, ...) {
if (LM_DEBUG != 1)
2024-06-20 00:34:32 +00:00
return;
va_list args;
va_start(args, fmt);
printf("[libmp debug] %s: ", func);
2024-06-20 00:34:32 +00:00
vprintf(fmt, args);
printf("\n");
va_end(args);
}
bool eq(char *s1, char *s2) {
if (NULL == s1 || NULL == s2)
return false;
if (strlen(s1) != strlen(s2))
return false;
return strcmp(s1, s2) == 0;
}
bool is_letter(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
bool is_digit(char c) {
return c >= '0' && c <= '9';
}
bool contains(char *str, char s) {
for (char *c = str; *c != 0; c++)
if (*c == s)
return true;
return false;
}
2024-06-22 04:03:17 +00:00
bool parse_host(char *addr, char *host, uint16_t *port) {
2024-06-22 04:03:17 +00:00
char *save = NULL, *portc = NULL;
int portint = 0;
2024-06-22 04:03:17 +00:00
if ((host = strtok_r(addr, ":", &save)) == NULL) {
2024-06-22 04:03:17 +00:00
lm_error_set(LM_ERR_BadHost);
return false;
}
if ((portc = strtok_r(NULL, ":", &save)) == NULL) {
2024-06-22 04:03:17 +00:00
*port = 0;
return true;
}
portint = atoi(portc);
if (portint <= 0 || portint > UINT16_MAX) {
2024-06-22 04:03:17 +00:00
lm_error_set(LM_ERR_BadPort);
return false;
}
*port = portint;
return true;
}
bool copy_to_buffer(void *buffer, void *src, size_t size, ssize_t *total, ssize_t *used) {
if (*used + size > *total)
return false;
if (*used == 0)
bzero(buffer, *total);
memcpy(buffer + *used, src, size);
*used += size;
return true;
}
bool copy_from_buffer(void *dst, void *buffer, size_t size, ssize_t *total, ssize_t *used) {
if (*used + size > *total)
return false;
if (*used == 0)
bzero(dst, size);
memcpy(dst, buffer + *used, size);
*used += size;
return true;
}
bool copy_blocks(struct archive *w, struct archive *r) {
int64_t offset = 0;
const void *buffer;
size_t size = 0;
int rc = 0;
while ((rc = archive_read_data_block(r, &buffer, &size, &offset)) == ARCHIVE_OK) {
rc = archive_write_data_block(w, buffer, size, offset);
if (rc != ARCHIVE_OK) {
lm_error_set(LM_ERR_ArcWBlockFail);
return false;
}
}
if (rc != ARCHIVE_EOF) {
lm_error_set(LM_ERR_ArcRBlockFail);
return false;
}
return true;
}
bool extract_archive(char *dst, char *src) {
struct archive *reader = NULL, *writer = NULL;
struct archive_entry *entry = NULL;
int flags = 0, rc = 0;
char *oldpwd = NULL;
bool ret = false;
oldpwd = getcwd(NULL, 0);
if (NULL == oldpwd) {
lm_error_set(LM_ERR_GetCwdFail);
goto end;
}
chdir(dst);
flags = ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_UNLINK;
reader = archive_read_new();
writer = archive_write_new();
archive_write_disk_set_options(writer, flags);
archive_write_disk_set_standard_lookup(writer);
archive_read_support_format_tar(reader);
archive_read_support_filter_gzip(reader);
if (archive_read_open_filename(reader, src, 1024 * 10) != ARCHIVE_OK) {
lm_error_set(LM_ERR_ArcOpenFail);
goto end;
}
while ((rc = archive_read_next_header(reader, &entry)) == ARCHIVE_OK) {
rc = archive_write_header(writer, entry);
if (rc != ARCHIVE_OK) {
lm_error_set(LM_ERR_ArcWHeaderFail);
goto end;
}
if (!copy_blocks(writer, reader))
goto end;
rc = archive_write_finish_entry(writer);
if (rc != ARCHIVE_OK) {
lm_error_set(LM_ERR_ArcWEntryFail);
goto end;
}
}
ret = true;
end:
if (NULL != reader) {
archive_read_close(reader);
archive_read_free(reader);
}
if (NULL != writer) {
archive_write_close(reader);
archive_write_free(reader);
}
if (NULL != oldpwd) {
chdir(oldpwd);
free(oldpwd);
}
return ret;
}
bool is_pkg_name_valid(char *name) {
for (char *c = name; *c != 0; c++) {
if (*c == '_')
return false;
if (*c == ' ')
return false;
}
return true;
}
bool exists(char *path) {
struct stat st;
return stat(path, &st) == 0;
}
bool is_file(char *path) {
struct stat st;
if (stat(path, &st) < 0)
return false;
return S_ISREG(st.st_mode);
}
bool is_dir(char *path) {
struct stat st;
if (stat(path, &st) < 0)
return false;
return S_ISDIR(st.st_mode);
}
bool can_read(char *path) {
return access(path, R_OK) == 0;
}
bool can_write(char *path) {
return access(path, W_OK) == 0;
}
bool mkdir_ifnot(char *path) {
return !(mkdir(path, 0700) < 0 && errno != EEXIST);
}
void sockaddr_to_str(struct sockaddr *addr, char *str) {
struct sockaddr_in *ipv4;
struct sockaddr_in6 *ipv6;
switch (addr->sa_family) {
case AF_INET:
ipv4 = (struct sockaddr_in *)addr;
inet_ntop(AF_INET, &ipv4->sin_addr, str, INET_ADDRSTRLEN);
break;
case AF_INET6:
ipv6 = (struct sockaddr_in6 *)addr;
inet_ntop(AF_INET6, &ipv6->sin6_addr, str, INET6_ADDRSTRLEN);
break;
}
}