Add check if file(s) are readable when archiving
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 52s

Also some minor changes like more error logs and refactorings.
This commit is contained in:
Stephen Seo 2024-07-26 16:01:39 +09:00
parent bdbbf7dc16
commit 4479fdce62
2 changed files with 49 additions and 0 deletions

View file

@ -200,6 +200,9 @@ int write_files_fn(void *data, void *ud) {
fopen(temp_filename, "wb"); fopen(temp_filename, "wb");
if (!tmp_fd) { if (!tmp_fd) {
fprintf(stderr, "ERROR: Unable to create temp file for compressing!\n"); fprintf(stderr, "ERROR: Unable to create temp file for compressing!\n");
fprintf(stderr,
"(Use \"--temp-files-dir <dir>\" to change where to write temp "
"files.)\n");
return 1; return 1;
} }
__attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array = __attribute__((cleanup(cleanup_temp_filename_delete))) void **ptrs_array =
@ -543,6 +546,8 @@ int write_files_fn(void *data, void *ud) {
int stat_fd = open(file_info->filename, O_RDONLY); int stat_fd = open(file_info->filename, O_RDONLY);
if (stat_fd == -1) { if (stat_fd == -1) {
// Error. // Error.
fprintf(stderr, "ERROR: Failed to get stat of \"%s\"!\n",
file_info->filename);
return 1; return 1;
} }
int stat_status = fstat(stat_fd, &stat_buf); int stat_status = fstat(stat_fd, &stat_buf);

View file

@ -413,6 +413,7 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames(
SDArchiverFileInfo *file_info = malloc(sizeof(SDArchiverFileInfo)); SDArchiverFileInfo *file_info = malloc(sizeof(SDArchiverFileInfo));
file_info->filename = filename; file_info->filename = filename;
if ((st.st_mode & S_IFMT) == S_IFLNK) { if ((st.st_mode & S_IFMT) == S_IFLNK) {
// Is a symlink.
file_info->link_dest = malloc(MAX_SYMBOLIC_LINK_SIZE); file_info->link_dest = malloc(MAX_SYMBOLIC_LINK_SIZE);
ssize_t count = readlinkat(AT_FDCWD, filename, file_info->link_dest, ssize_t count = readlinkat(AT_FDCWD, filename, file_info->link_dest,
MAX_SYMBOLIC_LINK_SIZE - 1); MAX_SYMBOLIC_LINK_SIZE - 1);
@ -422,13 +423,35 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames(
file_info->link_dest[count] = 0; file_info->link_dest[count] = 0;
} else { } else {
// Failure. // Failure.
fprintf(stderr,
"WARNING: Could not get link info for file \"%s\"!\n",
file_info->filename);
free(file_info->link_dest); free(file_info->link_dest);
free(file_info); free(file_info);
free(filename); free(filename);
continue; continue;
} }
} else { } else {
// Is a regular file.
file_info->link_dest = NULL; file_info->link_dest = NULL;
// Check that the file is readable by opening it. Easier than to
// check permissions because that would also require checking if the
// current USER can open the file.
FILE *readable_file = fopen(file_info->filename, "rb");
if (!readable_file) {
// Cannot open file, so it must be unreadable (at least by the
// current USER).
fprintf(stderr, "WARNING: \"%s\" is not readable, skipping!\n",
file_info->filename);
free(file_info->link_dest);
free(file_info);
free(filename);
continue;
} else {
fclose(readable_file);
// fprintf(stderr, "DEBUG: \"%s\" is readable.\n",
// file_info->filename);
}
} }
simple_archiver_list_add(files_list, file_info, simple_archiver_list_add(files_list, file_info,
simple_archiver_internal_free_file_info_fn); simple_archiver_internal_free_file_info_fn);
@ -486,6 +509,7 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames(
malloc(sizeof(SDArchiverFileInfo)); malloc(sizeof(SDArchiverFileInfo));
file_info->filename = combined_path; file_info->filename = combined_path;
if ((st.st_mode & S_IFMT) == S_IFLNK) { if ((st.st_mode & S_IFMT) == S_IFLNK) {
// Is a symlink.
file_info->link_dest = malloc(MAX_SYMBOLIC_LINK_SIZE); file_info->link_dest = malloc(MAX_SYMBOLIC_LINK_SIZE);
ssize_t count = ssize_t count =
readlinkat(AT_FDCWD, combined_path, file_info->link_dest, readlinkat(AT_FDCWD, combined_path, file_info->link_dest,
@ -502,7 +526,27 @@ SDArchiverLinkedList *simple_archiver_parsed_to_filenames(
continue; continue;
} }
} else { } else {
// Is a regular file.
file_info->link_dest = NULL; file_info->link_dest = NULL;
// Check that the file is readable by opening it. Easier than
// to check permissions because that would also require
// checking if the current USER can open the file.
FILE *readable_file = fopen(file_info->filename, "rb");
if (!readable_file) {
// Cannot open file, so it must be unreadable (at least by
// the current USER).
fprintf(stderr,
"WARNING: \"%s\" is not readable, skipping!\n",
file_info->filename);
free(file_info->link_dest);
free(file_info);
free(combined_path);
continue;
} else {
fclose(readable_file);
// fprintf(stderr, "DEBUG: \"%s\" is readable.\n",
// file_info->filename);
}
} }
simple_archiver_list_add( simple_archiver_list_add(
files_list, file_info, files_list, file_info,