#include "../include/util.h" #include "../include/error.h" #include "../include/types.h" #include #include #include #include #include #include #include #include void pdebug(lm_ctx_t *ctx, const char *func, const char *fmt, ...) { if (!ctx->debug) return; va_list args; va_start(args, fmt); printf("[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; 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; }