From 66f5601712ddaa28e75f99e5e3c1ce94b99f28e5 Mon Sep 17 00:00:00 2001 From: simon Date: Sat, 22 Feb 2020 12:40:53 -0500 Subject: [PATCH] Initial commit --- .gitignore | 9 ++++++ CMakeLists.txt | 26 +++++++++++++++ ci/build.sh | 5 +++ main.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100755 ci/build.sh create mode 100644 main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e83dcc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.idea/ +*.iml +cmake_install.cmake +*.cbp +Makefile +CMakeCache.txt +CMakeFiles +cmake-build-debug +cbr2cbz diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..742f41f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.7) +project(cbr2cbz C) + +set(CMAKE_C_STANDARD 11) +option(STATIC_BUILD "Static build" off) + +add_executable(cbr2cbz main.c) + +if (STATIC_BUILD) + target_link_libraries( + cbr2cbz + -static + archive + ) +else () + target_link_libraries( + cbr2cbz + archive + ) +endif () + +target_compile_options( + cbr2cbz + PRIVATE +) + diff --git a/ci/build.sh b/ci/build.sh new file mode 100755 index 0000000..94d21af --- /dev/null +++ b/ci/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +cmake -D STATIC_BUILD=on . +make +strip cbr2cbz \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..dbda90b --- /dev/null +++ b/main.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include + +#define ARC_BUF_SIZE 8192 + +char *abspath(const char *path) { + char *abs = realpath(path, NULL); + if (abs == NULL) { + return NULL; + } + + return abs; +} + +void convert_cbr(char *rar_in_path) { + + if (strstr(rar_in_path, ".cbr") == NULL) { + fprintf(stderr, "Input file does not have .cbr extension"); + return; + } + + char zip_out_path[4096]; + strcpy(zip_out_path, rar_in_path); + memcpy(strstr(zip_out_path, ".cbr"), ".cbz\0", 5); + + struct stat _; + if (stat(zip_out_path, &_) == 0) { + return; + } + + struct archive *rar_in = archive_read_new(); + archive_read_support_filter_none(rar_in); + archive_read_support_format_rar(rar_in); + archive_read_support_format_rar5(rar_in); + + int ret = archive_read_open_filename(rar_in, rar_in_path, ARC_BUF_SIZE); + if (ret != ARCHIVE_OK) { + fprintf(stderr, "%s\n", archive_error_string(rar_in)); + return; + } + + struct archive *zip_out = archive_write_new(); + archive_write_set_format_zip(zip_out); + ret = archive_write_open_filename(zip_out, zip_out_path); + if (ret != ARCHIVE_OK) { + fprintf(stderr, "%s\n", archive_error_string(zip_out)); + return; + } + + + struct archive_entry *entry; + while (archive_read_next_header(rar_in, &entry) == ARCHIVE_OK) { + archive_write_header(zip_out, entry); + + char arc_buf[ARC_BUF_SIZE]; + int len = archive_read_data(rar_in, arc_buf, ARC_BUF_SIZE); + while (len > 0) { + archive_write_data(zip_out, arc_buf, len); + len = archive_read_data(rar_in, arc_buf, ARC_BUF_SIZE); + } + } + + archive_write_close(zip_out); + archive_write_free(zip_out); + + archive_read_close(rar_in); + archive_read_free(rar_in); +} + +int main(int argc, char **argv) { + + if (argc == 1) { + fprintf(stderr, "USAGE: cbr2cbz FILE...\n"); + } + + for (int i = 1; i < argc; i++) { + char *abs = abspath(argv[i]); + + if (abs == NULL) { + fprintf(stderr, "File not found: '%s'\n", argv[i]); + continue; + } + convert_cbr(abs); + free(abs); + } +}