#include "../include/util.h" #include "../include/error.h" #include "../include/types.h" #include #include #include #include #include #include #include #include void pdebug(const char *func, const char *fmt, ...) { if (LM_DEBUG != 1) return; va_list args; va_start(args, fmt); printf("[libmp debug] %s: ", func); 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; } bool parse_host(char *addr, char *host, uint16_t *port) { char *save = NULL, *portc = NULL; int portint = 0; if ((host = strtok_r(addr, ":", &save)) == NULL) { lm_error_set(LM_ERR_BadHost); return false; } if ((portc = strtok_r(NULL, ":", &save)) == NULL) { *port = 0; return true; } portint = atoi(portc); if (portint <= 0 || portint > UINT16_MAX) { 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; char srcfull[PATH_MAX + 1]; if (NULL == realpath(src, srcfull)) { lm_error_set(LM_ERR_ArcRealpathFail); goto end; } 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_disk_new(); if (NULL == reader || NULL == writer) { lm_error_set(LM_ERR_ArcNewFail); goto end; } 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, srcfull, 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; } } if (rc != ARCHIVE_EOF) { lm_error_set(LM_ERR_ArcNextHeaderFail); goto end; } ret = true; end: if (NULL != reader) { archive_read_close(reader); archive_read_free(reader); } if (NULL != writer) { archive_write_close(writer); archive_write_free(writer); } 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; } }