From 3d164b948951514ee277a17fdf32f74dc409bf44 Mon Sep 17 00:00:00 2001 From: "tanguy.cavagna" <tanguy.cavagna@etu.hesge.ch> Date: Mon, 27 Jun 2022 19:21:31 +0200 Subject: [PATCH] Added source folder creation in destination and list_dir after copy --- ultra-cp/ultra-cp.c | 104 +++++++++++++++++++++++++++++++++++--------- ultra-cp/ultra-cp.h | 1 + 2 files changed, 85 insertions(+), 20 deletions(-) diff --git a/ultra-cp/ultra-cp.c b/ultra-cp/ultra-cp.c index 48e8603..cb618ec 100644 --- a/ultra-cp/ultra-cp.c +++ b/ultra-cp/ultra-cp.c @@ -19,6 +19,56 @@ int get_int_permissions(const char *path) { 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 * @@ -33,25 +83,12 @@ void copy_entry(struct dirent *entry, const char *source, return; // Entry is a file, copy it - if (entry->d_type == DT_REG) { - FILE *src_file, *dst_file; - 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)); - } + if (entry->d_type == DT_REG) + copy_single_file(source, destination); // Go deeper if directory if (entry->d_type == DT_DIR) - mkdir(destination, get_int_permissions(source)); + copy_directory(source, destination); struct utimbuf new_time; new_time.actime = entry_stat.st_atim.tv_sec; @@ -66,7 +103,7 @@ void copy_entry(struct dirent *entry, const char *source, * @param source Source 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; struct dirent *entry; @@ -87,7 +124,7 @@ void copy_directory(const char *source, const char *destination) { char dst_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); dst_path_lenght = snprintf(dst_path, PATH_MAX, "%s/%s", destination, d_name); @@ -100,8 +137,9 @@ void copy_directory(const char *source, const char *destination) { copy_entry(entry, src_path, dst_path); + // Go deeper if (entry->d_type == DT_DIR) - copy_directory(src_path, dst_path); + copy_directory_content(src_path, dst_path); } closedir(dir); @@ -203,6 +241,32 @@ void list_dir(const char *name) { void copy_files(const char **sources, const char *destination, uint8_t options, int source_count) { 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); } diff --git a/ultra-cp/ultra-cp.h b/ultra-cp/ultra-cp.h index 28e2c44..8f9ea90 100644 --- a/ultra-cp/ultra-cp.h +++ b/ultra-cp/ultra-cp.h @@ -2,6 +2,7 @@ #define ULTRA_CP_ #include <dirent.h> +#include <libgen.h> #include <linux/limits.h> #include <stdint.h> #include <stdio.h> -- GitLab