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

Can copy directory content except links and date attributes

parent 63c2201d
Branches
No related tags found
No related merge requests found
...@@ -26,14 +26,13 @@ int main(int argc, char **argv) { ...@@ -26,14 +26,13 @@ int main(int argc, char **argv) {
source_paths[i][strlen(source_paths[i]) - 1] = '\0'; source_paths[i][strlen(source_paths[i]) - 1] = '\0';
} }
// TODO: Copy files form sources to destination // Copy content
copy_files((const char **)source_paths, destination_path, opt, source_count);
// Free sources // Free sources
for (int i = 0; i < source_count; i++) for (int i = 0; i < source_count; i++)
free(source_paths[i]); free(source_paths[i]);
free(source_paths); free(source_paths);
list_dir("/home/toguy/Documents/source");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
#include "ultra-cp.h" #include "ultra-cp.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
//==================== //====================
// PRIVATE // PRIVATE
//==================== //====================
/**
* @brief Get the entry permissions as int
*
* @param path Entry path
*
* @returns Permissions
*/
int get_int_permissions(const char *path) {
struct stat entry_stat;
if (stat(path, &entry_stat) < 0)
return -1;
return entry_stat.st_mode;
}
/**
* @brief Copy a source entry to a destination location
*
* @param source Source entry
* @param destination Destination location
*/
void copy_entry(struct dirent *entry, const char *source,
const char *destination) {
// 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));
}
// Go deeper if directory
if (entry->d_type == DT_DIR)
mkdir(destination, get_int_permissions(source));
}
/**
* @brief Copy the content of a directory to a destination
*
* @param source Source directory
* @param destination Destination directory
*/
void copy_directory(const char *source, const char *destination) {
DIR *dir;
struct dirent *entry;
// Cannot open dir
if (!(dir = opendir(source)))
return;
// Loop through all entries of the given directory
while ((entry = readdir(dir)) != NULL) {
const char *d_name;
d_name = entry->d_name;
// Skip "." and ".."
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0)
continue;
int dst_path_lenght;
char dst_path[PATH_MAX];
char src_path[PATH_MAX];
// Create the full source and destination paths
snprintf(src_path, PATH_MAX, "%s/%s", source, d_name);
dst_path_lenght =
snprintf(dst_path, PATH_MAX, "%s/%s", destination, d_name);
// Path length exceeded clause
if (dst_path_lenght >= PATH_MAX) {
fprintf(stderr, "Path length has got too long.\n");
exit(EXIT_FAILURE);
}
copy_entry(entry, src_path, dst_path);
if (entry->d_type == DT_DIR)
copy_directory(src_path, dst_path);
}
closedir(dir);
}
//==================== //====================
// PUBLIC // PUBLIC
//==================== //====================
char *get_permissions(const char *name) { char *get_permissions(const char *name) {
struct stat file_stat; int perms = get_int_permissions(name);
// Read stats
if (stat(name, &file_stat) < 0)
return NULL;
char *permissions = calloc(10, sizeof(char)); char *permissions = calloc(10, sizeof(char));
permissions[0] = S_ISDIR(file_stat.st_mode) ? 'd' : S_ISLNK(file_stat.st_mode) ? 'l' : '-'; permissions[0] = S_ISDIR(perms) ? 'd' : S_ISLNK(perms) ? 'l' : '-';
permissions[1] = (file_stat.st_mode & S_IRUSR) ? 'r' : '-'; permissions[1] = (perms & S_IRUSR) ? 'r' : '-';
permissions[2] = (file_stat.st_mode & S_IWUSR) ? 'w' : '-'; permissions[2] = (perms & S_IWUSR) ? 'w' : '-';
permissions[3] = (file_stat.st_mode & S_IXUSR) ? 'x' : '-'; permissions[3] = (perms & S_IXUSR) ? 'x' : '-';
permissions[4] = (file_stat.st_mode & S_IRGRP) ? 'r' : '-'; permissions[4] = (perms & S_IRGRP) ? 'r' : '-';
permissions[5] = (file_stat.st_mode & S_IWGRP) ? 'w' : '-'; permissions[5] = (perms & S_IWGRP) ? 'w' : '-';
permissions[6] = (file_stat.st_mode & S_IXGRP) ? 'x' : '-'; permissions[6] = (perms & S_IXGRP) ? 'x' : '-';
permissions[7] = (file_stat.st_mode & S_IROTH) ? 'r' : '-'; permissions[7] = (perms & S_IROTH) ? 'r' : '-';
permissions[8] = (file_stat.st_mode & S_IWOTH) ? 'w' : '-'; permissions[8] = (perms & S_IWOTH) ? 'w' : '-';
permissions[9] = (file_stat.st_mode & S_IXOTH) ? 'x' : '-'; permissions[9] = (perms & S_IXOTH) ? 'x' : '-';
return permissions; return permissions;
} }
...@@ -104,3 +188,10 @@ void list_dir(const char *name) { ...@@ -104,3 +188,10 @@ void list_dir(const char *name) {
closedir(dir); closedir(dir);
} }
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);
}
}
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#define ULTRA_CP_ #define ULTRA_CP_
#include <dirent.h> #include <dirent.h>
#include <linux/limits.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -44,4 +46,14 @@ char *get_date(const char *name); ...@@ -44,4 +46,14 @@ char *get_date(const char *name);
*/ */
void list_dir(const char *name); void list_dir(const char *name);
/**
* @brief Copy all content from sources to destination
*
* @param sources List of all sources to copy
* @param destination Destination for the content
* @param options Copy options
* @param source_count Source count
*/
void copy_files(const char **sources, const char *destination, uint8_t options,
int source_count);
#endif // !ULTRA_CP_ #endif // !ULTRA_CP_
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment