Skip to content
Snippets Groups Projects
Commit 3d164b94 authored by tanguy.cavagna's avatar tanguy.cavagna :desktop:
Browse files

Added source folder creation in destination and list_dir after copy

parent 570de6d0
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,56 @@ int get_int_permissions(const char *path) { ...@@ -19,6 +19,56 @@ int get_int_permissions(const char *path) {
return entry_stat.st_mode; return entry_stat.st_mode;
} }
/**
* @brief Copy a single file
*
* @param source Source file
* @param destination Destination file
*/
void copy_single_file(const char *source, const char *destination) {
int dst_path_lenght = 0;
char dst_path[PATH_MAX];
// Check if the basename already exists in the destination path
if (strstr(destination, basename((char *)source)) == NULL) {
dst_path_lenght = snprintf(dst_path, PATH_MAX, "%s/%s", destination,
basename((char *)source));
} else {
dst_path_lenght = strlen(destination);
strcpy(dst_path, destination);
}
// Path length exceeded clause
if (dst_path_lenght >= PATH_MAX) {
fprintf(stderr, "Path length has got too long.\n");
exit(EXIT_FAILURE);
}
FILE *src_file, *dst_file;
src_file = fopen(source, "rb");
dst_file = fopen(dst_path, "wb");
size_t n;
char buff[BUFSIZ];
while ((n = fread(buff, 1, BUFSIZ, src_file)) != 0)
fwrite(buff, 1, n, dst_file);
fclose(src_file);
fclose(dst_file);
chmod(destination, get_int_permissions(source));
}
/**
* @brief Copy a directory
*
* @param source Source directory
* @param destination Destination directory
*/
void copy_directory(const char *source, const char *destination) {
mkdir(destination, get_int_permissions(source));
}
/** /**
* @brief Copy a source entry to a destination location * @brief Copy a source entry to a destination location
* *
...@@ -33,25 +83,12 @@ void copy_entry(struct dirent *entry, const char *source, ...@@ -33,25 +83,12 @@ void copy_entry(struct dirent *entry, const char *source,
return; return;
// Entry is a file, copy it // Entry is a file, copy it
if (entry->d_type == DT_REG) { if (entry->d_type == DT_REG)
FILE *src_file, *dst_file; copy_single_file(source, destination);
src_file = fopen(source, "rb");
dst_file = fopen(destination, "wb");
size_t n;
char buff[BUFSIZ];
while ((n = fread(buff, 1, BUFSIZ, src_file)) != 0)
fwrite(buff, 1, n, dst_file);
fclose(src_file);
fclose(dst_file);
chmod(destination, get_int_permissions(source));
}
// Go deeper if directory // Go deeper if directory
if (entry->d_type == DT_DIR) if (entry->d_type == DT_DIR)
mkdir(destination, get_int_permissions(source)); copy_directory(source, destination);
struct utimbuf new_time; struct utimbuf new_time;
new_time.actime = entry_stat.st_atim.tv_sec; new_time.actime = entry_stat.st_atim.tv_sec;
...@@ -66,7 +103,7 @@ void copy_entry(struct dirent *entry, const char *source, ...@@ -66,7 +103,7 @@ void copy_entry(struct dirent *entry, const char *source,
* @param source Source directory * @param source Source directory
* @param destination Destination directory * @param destination Destination directory
*/ */
void copy_directory(const char *source, const char *destination) { void copy_directory_content(const char *source, const char *destination) {
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
...@@ -87,7 +124,7 @@ void copy_directory(const char *source, const char *destination) { ...@@ -87,7 +124,7 @@ void copy_directory(const char *source, const char *destination) {
char dst_path[PATH_MAX]; char dst_path[PATH_MAX];
char src_path[PATH_MAX]; char src_path[PATH_MAX];
// Create the full source and destination paths // Concatenate entry name to source and destination directory
snprintf(src_path, PATH_MAX, "%s/%s", source, d_name); snprintf(src_path, PATH_MAX, "%s/%s", source, d_name);
dst_path_lenght = dst_path_lenght =
snprintf(dst_path, PATH_MAX, "%s/%s", destination, d_name); snprintf(dst_path, PATH_MAX, "%s/%s", destination, d_name);
...@@ -100,8 +137,9 @@ void copy_directory(const char *source, const char *destination) { ...@@ -100,8 +137,9 @@ void copy_directory(const char *source, const char *destination) {
copy_entry(entry, src_path, dst_path); copy_entry(entry, src_path, dst_path);
// Go deeper
if (entry->d_type == DT_DIR) if (entry->d_type == DT_DIR)
copy_directory(src_path, dst_path); copy_directory_content(src_path, dst_path);
} }
closedir(dir); closedir(dir);
...@@ -203,6 +241,32 @@ void list_dir(const char *name) { ...@@ -203,6 +241,32 @@ void list_dir(const char *name) {
void copy_files(const char **sources, const char *destination, uint8_t options, void copy_files(const char **sources, const char *destination, uint8_t options,
int source_count) { int source_count) {
for (int s = 0; s < source_count; s++) { for (int s = 0; s < source_count; s++) {
copy_directory(sources[s], destination); struct stat source_stat;
if (stat(sources[s], &source_stat) < 0)
continue;
if (S_ISDIR(source_stat.st_mode)) {
int dst_path_lenght;
char dst_path[PATH_MAX];
// Create the full source and destination paths
dst_path_lenght =
snprintf(dst_path, PATH_MAX, "%s/%s", destination, basename((char *)sources[s]));
// Path length exceeded clause
if (dst_path_lenght >= PATH_MAX) {
fprintf(stderr, "Path length has got too long.\n");
exit(EXIT_FAILURE);
}
copy_directory(sources[s], dst_path);
copy_directory_content(sources[s], dst_path);
}
if (S_ISREG(source_stat.st_mode))
copy_single_file(sources[s], destination);
} }
list_dir(destination);
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define ULTRA_CP_ #define ULTRA_CP_
#include <dirent.h> #include <dirent.h>
#include <libgen.h>
#include <linux/limits.h> #include <linux/limits.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment