-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30 from SegFault42/develop
0.2
- Loading branch information
Showing
13 changed files
with
442 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,5 +31,6 @@ | |
#include "controller.h" | ||
#include "init.h" | ||
#include "cbr.h" | ||
#include "file.h" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#ifndef FILE_H | ||
#define FILE_H | ||
|
||
bool isFileExist(const char *file); | ||
char *get_file_extension(char *str); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,135 +1,244 @@ | ||
#include "common.h" | ||
|
||
static u64 count_files(const char *path) | ||
extern t_cbr *cbr; | ||
|
||
static bool init_cbr(t_cbr *cbr, const char *path) | ||
{ | ||
struct archive *handle = NULL; | ||
u64 count = 0; | ||
int ret = 0; | ||
int ret = 0; | ||
|
||
handle = archive_read_new(); | ||
if (handle == NULL) { | ||
log_warn("%s", archive_error_string(handle)); | ||
return (-1); | ||
cbr->handle = archive_read_new(); | ||
if (cbr->handle == NULL) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
return (false); | ||
} | ||
|
||
cbr->dst = archive_write_disk_new(); | ||
if (cbr->dst == NULL) { | ||
log_warn("%s", archive_error_string(cbr->dst)); | ||
return (false); | ||
} | ||
|
||
ret = archive_read_support_format_all(handle); | ||
ret = archive_read_support_format_all(cbr->handle); | ||
if (ret != ARCHIVE_OK) { | ||
log_warn("%s", archive_error_string(handle)); | ||
return (-1); | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
return (false); | ||
} | ||
|
||
ret = archive_read_open_filename(handle, path, 1024); | ||
ret = archive_read_open_filename(cbr->handle, path, 1024); | ||
if (ret != ARCHIVE_OK) { | ||
printf("%s\n", archive_error_string(handle)); | ||
printf("archive_read_open_filename%d\n", ret); | ||
return 1; | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
return (false); | ||
} | ||
|
||
log_info("init_cbr() [Success]"); | ||
|
||
return (true); | ||
} | ||
|
||
static void deinit_cbr(t_cbr *cbr) | ||
{ | ||
archive_read_free(cbr->handle); | ||
archive_write_free(cbr->dst); | ||
|
||
log_info("deinit_cbr() [Success]"); | ||
} | ||
|
||
static u64 count_files(t_cbr *cbr, const char *path) | ||
{ | ||
int ret = 0; | ||
size_t count = 0; | ||
|
||
if (init_cbr(cbr, path) == false) { | ||
return (-1); | ||
} | ||
|
||
for (;;) { | ||
struct archive_entry *entry = NULL; | ||
|
||
ret = archive_read_next_header(handle, &entry); | ||
ret = archive_read_next_header(cbr->handle, &entry); | ||
if (ret == ARCHIVE_EOF) { | ||
break; | ||
} | ||
|
||
count++; | ||
} | ||
|
||
ret = archive_read_free(handle); | ||
deinit_cbr(cbr); | ||
|
||
log_info("count_files() [Success]"); | ||
return (count); | ||
} | ||
|
||
typedef struct s_cbr | ||
// TODO: review return value | ||
static int write_data(t_cbr *cbr) | ||
{ | ||
struct archive *handle; | ||
struct archive *dst; | ||
u64 max; | ||
} t_cbr; | ||
int ret = 0; | ||
size_t total_length = 0; | ||
|
||
static bool init_cbr(t_cbr *cbr, char *path) | ||
{ | ||
int ret = 0; | ||
for (;;) { | ||
const void *chunk = NULL; | ||
size_t length = 0; | ||
s64 offset = 0; | ||
|
||
cbr->handle = archive_read_new(); | ||
if (cbr->handle == NULL) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
return (false); | ||
ret = archive_read_data_block(cbr->handle, &chunk, &length, &offset); | ||
if (ret == ARCHIVE_EOF) | ||
return ARCHIVE_OK; | ||
|
||
if (ret != ARCHIVE_OK) | ||
return ret; | ||
|
||
ret = archive_write_data_block(cbr->dst, chunk, length, offset); | ||
if (ret != ARCHIVE_OK) | ||
return ret; | ||
} | ||
|
||
cbr->dst = archive_write_disk_new(); | ||
if (cbr->handle == NULL) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
return (false); | ||
log_info("write_data() [Success]"); | ||
return -1; | ||
} | ||
|
||
static int myCompare(const void* a, const void* b) | ||
{ | ||
return (strcmp(*(const char**)a, *(const char**)b)); | ||
} | ||
|
||
char **get_archive_content_file_name(char *path, t_cbr *cbr) | ||
{ | ||
u64 count = 0; | ||
int ret = 0; | ||
char **array = NULL; | ||
|
||
array = (char **)calloc(sizeof(char *), cbr->total_page + 1); | ||
if (array == NULL) { | ||
log_warn("calloc error\n"); | ||
return (NULL); | ||
} | ||
|
||
ret = archive_read_support_format_all(cbr->handle); | ||
if (ret != ARCHIVE_OK) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
return (false); | ||
if (init_cbr(cbr, path) == false) { | ||
return (NULL); | ||
} | ||
|
||
ret = archive_read_open_filename(cbr->handle, path, 1024); | ||
if (ret != ARCHIVE_OK) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
return (false); | ||
for (;;) { | ||
struct archive_entry *entry = NULL; | ||
|
||
ret = archive_read_next_header(cbr->handle, &entry); | ||
if (ret == ARCHIVE_EOF) { | ||
break; | ||
} | ||
|
||
const char *entry_path = archive_entry_pathname(entry); | ||
if (entry_path == NULL) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
break ; | ||
} | ||
array[count] = strdup(entry_path); | ||
|
||
count++; | ||
} | ||
|
||
return (true); | ||
deinit_cbr(cbr); | ||
|
||
// Sort files name | ||
qsort(array, cbr->total_page, sizeof(const char *), myCompare); | ||
|
||
log_info("get_archive_content_file_name() [Success]"); | ||
|
||
return (array); | ||
} | ||
|
||
bool extract_cbr(char *path) | ||
bool extract_cbr(char *path, int page_number) | ||
{ | ||
t_cbr cbr = {0}; | ||
char **array = NULL; | ||
int ret = 0; | ||
u64 count = 0; | ||
|
||
cbr.max = count_files(path); | ||
// create temp directory | ||
if (isFileExist("/tmp") == false) { | ||
if (mkdir("/tmp", 0777) == -1) { | ||
log_warn("%s", strerror(errno)); | ||
return (false); | ||
} | ||
} | ||
|
||
if (init_cbr(&cbr, path) == false) { | ||
// Count files number in archive | ||
cbr->total_page = count_files(cbr, path); | ||
if (page_number > cbr->total_page) { | ||
log_warn("page %d not exist", page_number); | ||
return (false); | ||
} else if (cbr->total_page == -1) { | ||
log_warn("count_files [Failure]"); | ||
return (false); | ||
} | ||
|
||
mkdir("/tmp", 0777); | ||
// Sort and store all filename in char ** | ||
array = get_archive_content_file_name(path, cbr); | ||
if (array == NULL) { | ||
return (false); | ||
} | ||
|
||
if (init_cbr(cbr, path) == false) { | ||
free_2d_array(array); | ||
return (false); | ||
} | ||
|
||
for (;;) { | ||
struct archive_entry *entry = NULL; | ||
ret = archive_read_next_header(handle, &cbr.entry); | ||
struct archive_entry *entry = NULL; | ||
|
||
ret = archive_read_next_header(cbr->handle, &entry); | ||
if (ret == ARCHIVE_EOF) { | ||
break; | ||
} | ||
|
||
if (ret != ARCHIVE_OK) { | ||
Menu_DisplayError("archive_read_next_header failed:", ret); | ||
} else if (ret != ARCHIVE_OK) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
if (ret != ARCHIVE_WARN) { | ||
break; | ||
} | ||
} | ||
|
||
const char *entry_path = archive_entry_pathname(entry); | ||
char new_path[1024]; | ||
|
||
ret = snprintf(new_path, sizeof(new_path), "%s/%s", dest_path, entry_path); | ||
ret = archive_entry_update_pathname_utf8(entry, new_path); | ||
if (!ret) { | ||
Menu_DisplayError("archive_entry_update_pathname_utf8:", ret); | ||
break; | ||
if (entry_path == NULL) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
ret = -1; | ||
break ; | ||
} | ||
|
||
ret = archive_write_disk_set_options(dst, ARCHIVE_EXTRACT_UNLINK); | ||
ret = archive_write_header(dst, entry); | ||
if (ret != ARCHIVE_OK) { | ||
Menu_DisplayError("archive_write_header failed:", ret); | ||
break; | ||
if (!strcmp(array[page_number], entry_path)) { | ||
cbr->path = (char *)calloc(sizeof(char), PATH_MAX + 1); | ||
if (cbr->path == NULL) { | ||
free_2d_array(array); | ||
deinit_cbr(cbr); | ||
return (false); | ||
} | ||
|
||
snprintf(cbr->path, PATH_MAX, "%s/%s", EBOOK_PATH, entry_path); | ||
|
||
if (isFileExist(cbr->path) == false) { | ||
ret = archive_entry_update_pathname_utf8(entry, cbr->path); | ||
if (!ret) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
break; | ||
} | ||
|
||
ret = archive_write_disk_set_options(cbr->dst, ARCHIVE_EXTRACT_UNLINK); | ||
ret = archive_write_header(cbr->dst, entry); | ||
if (ret != ARCHIVE_OK) { | ||
log_warn("%s", archive_error_string(cbr->handle)); | ||
break; | ||
} | ||
|
||
ret = write_data(cbr); | ||
ret = archive_write_finish_entry(cbr->dst); | ||
|
||
ret = write_data(cbr); | ||
} | ||
|
||
break ; | ||
} | ||
|
||
ret = Archive_WriteData(handle, dst); | ||
ret = archive_write_finish_entry(dst); | ||
count++; | ||
} | ||
|
||
ret = archive_write_free(cbr.dst); | ||
ret = archive_read_free(cbr.handle); | ||
free_2d_array(array); | ||
deinit_cbr(cbr); | ||
|
||
log_info("extract_cbr() [Success]"); | ||
return (true); | ||
} |
Oops, something went wrong.