diff options
| author | Ray Strode <rstrode@redhat.com> | 2007-06-12 12:02:40 -0400 |
|---|---|---|
| committer | Ray Strode <rstrode@redhat.com> | 2007-06-12 12:02:40 -0400 |
| commit | c4f27067d38ca4c0342452ff76a8e76da07ab5d9 (patch) | |
| tree | e7fa60ecdc589566bfded92314e7ddb926e094cc /src | |
| parent | 40db0556635d2bb95a6146feaa072ab5b5b6bbeb (diff) | |
| download | plymouth-c4f27067d38ca4c0342452ff76a8e76da07ab5d9.tar.gz plymouth-c4f27067d38ca4c0342452ff76a8e76da07ab5d9.tar.xz plymouth-c4f27067d38ca4c0342452ff76a8e76da07ab5d9.zip | |
fix up the copy dir function
Diffstat (limited to 'src')
| -rw-r--r-- | src/libply/ply-utils.c | 161 |
1 files changed, 160 insertions, 1 deletions
diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c index 3930fd3..9d8b8f9 100644 --- a/src/libply/ply-utils.c +++ b/src/libply/ply-utils.c @@ -29,11 +29,13 @@ #include <fcntl.h> #include <limits.h> #include <poll.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mount.h> #include <sys/resource.h> #include <sys/socket.h> +#include <sys/stat.h> #include <sys/time.h> #include <sys/types.h> #include <sys/un.h> @@ -661,7 +663,7 @@ ply_create_scratch_directory (const char *directory) { int dir_fd; assert (directory != NULL); - assert (directory[0] != NULL); + assert (directory[0] != '\0'); if (!ply_create_directory (directory)) return false; @@ -691,4 +693,161 @@ ply_create_scratch_directory (const char *directory) return true; } +static bool +ply_copy_subdirectory (const char *subdirectory, + const char *parent, + const char *destination) +{ + char *source, *target; + + source = NULL; + asprintf (&source, "%s/%s", parent, subdirectory); + + target = NULL; + asprintf (&target, "%s/%s", destination, subdirectory); + + if (!ply_copy_directory (source, target)) + { + ply_save_errno (); + free (source); + free (target); + ply_restore_errno (); + return false; + } + free (source); + free (target); + + return true; +} + +bool +ply_copy_file (const char *source, + const char *destination) +{ + char buffer[4096]; + int source_fd, destination_fd; + struct stat file_info; + + source_fd = open (source, O_RDONLY | O_NOFOLLOW); + + if (source_fd < 0) + return false; + + if (fstat (source_fd, &file_info) < 0) + return false; + + destination_fd = open (destination, O_WRONLY | O_NOFOLLOW | O_CREAT, + file_info.st_mode); + + if (destination_fd < 0) + return false; + + while ("we want to copy the file") + { + size_t bytes_read; + bytes_read = read (source_fd, buffer, sizeof (buffer)); + + if (bytes_read < 0) + { + if (errno == EINTR) + continue; + + return false; + } + else if (bytes_read == 0) + break; + + if (!ply_write (destination_fd, buffer, bytes_read)) + return false; + } + + return true; +} + +static bool +ply_copy_file_in_direcetory (const char *filename, + const char *parent, + const char *destination) +{ + char *source, *target; + + source = NULL; + asprintf (&source, "%s/%s", parent, filename); + + target = NULL; + asprintf (&target, "%s/%s", destination, filename); + + if (!ply_copy_file (source, target)) + { + ply_save_errno (); + free (source); + free (target); + ply_restore_errno (); + return false; + } + free (source); + free (target); + + return true; +} + +bool +ply_copy_directory (const char *source, + const char *destination) +{ + DIR *dir; + struct dirent *entry; + char *full_path; + + assert (source != NULL); + assert (source[0] != '\0'); + assert (destination != NULL); + assert (destination[0] != '\0'); + + dir = opendir (source); + + if (dir == NULL) + return false; + + while ((entry = readdir (dir)) != NULL) + { + if (strcmp (entry->d_name, ".") == 0) + continue; + + if (strcmp (entry->d_name, "..") == 0) + continue; + + full_path = NULL; + asprintf (&full_path, "%s/%s", source, entry->d_name); + + if (ply_directory_exists (full_path)) + { + if (!ply_copy_subdirectory (entry->d_name, source, destination)) + { + ply_save_errno (); + free (full_path); + ply_restore_errno (); + return false; + } + } + else if (ply_file_exists (full_path)) + { + if (!ply_copy_file_in_direcetory (entry->d_name, source, destination)) + { + ply_save_errno (); + free (full_path); + ply_restore_errno (); + return false; + } + } + + free (full_path); + } + + assert (entry == NULL); + closedir (dir); + + return true; +} + /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ |
