/* copy-file.c: * **************************************************************** * Copyright (C) 2003 Tom Lord * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */ #include "hackerlab/fs/file-names.h" #include "hackerlab/vu/safe.h" #include "libfsutils/link-target.h" #include "libfsutils/ensure-dir.h" #include "libfsutils/copy-file.h" void copy_fd (int in_fd, int out_fd) { static t_uchar buf[8192]; long amt; while (1) { amt = safe_read_retry (in_fd, buf, sizeof (buf)); if (!amt) break; safe_write_retry (out_fd, buf, amt); } } void copy_file (char * from, char * to) { int in_fd; int out_fd; in_fd = safe_open (from, O_RDONLY, 0); out_fd = safe_open (to, O_WRONLY | O_EXCL | O_CREAT, 0666); copy_fd (in_fd, out_fd); safe_close (in_fd); safe_close (out_fd); } void copy_symlink (char const * const from, char const * const to) { t_uchar * target; target = link_target (from); safe_symlink (target, to); lim_free (0, target); } void copy_file_or_symlink (char * from, char * to) { struct stat stat_buf; safe_lstat (from, &stat_buf); if (S_ISLNK (stat_buf.st_mode)) copy_symlink (from, to); else copy_file (from, to); } void copy_permissions (char * from, char * to) { struct stat from_stat_buf; struct stat to_stat_buf; mode_t mode; safe_lstat (from, &from_stat_buf); safe_lstat (to, &to_stat_buf); mode = from_stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); if (!S_ISLNK (from_stat_buf.st_mode) && !S_ISLNK (to_stat_buf.st_mode)) safe_chmod (to, mode); } void copy_file_list (t_uchar const * const dest_dir, t_uchar const * const src_dir, rel_table index) { int x; for (x = 0; x < rel_n_records (index); ++x) { t_uchar * src_path = 0; t_uchar * dest_path = 0; t_uchar * dest_path_dir = 0; struct stat stat_buf; mode_t src_mode; src_path = file_name_in_vicinity (0, src_dir, index[x][0]); dest_path = file_name_in_vicinity (0, dest_dir, index[x][0]); dest_path_dir = file_name_directory_file (0, dest_path); ensure_directory_exists (dest_path_dir); safe_lstat (src_path, &stat_buf); src_mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); if (S_ISLNK (stat_buf.st_mode)) { copy_symlink (src_path, dest_path); } else if (S_ISDIR (stat_buf.st_mode)) { ensure_directory_exists (dest_path); safe_chmod (dest_path, src_mode); } else { int in_fd; int out_fd; in_fd = safe_open (src_path, O_RDONLY, 0); out_fd = safe_open (dest_path, O_WRONLY | O_EXCL | O_CREAT, src_mode); safe_fchmod (out_fd, src_mode); copy_fd (in_fd, out_fd); safe_close (in_fd); safe_close (out_fd); } lim_free (0, src_path); lim_free (0, dest_path); lim_free (0, dest_path_dir); } } /* tag: Tom Lord Wed May 14 18:34:05 2003 (copy-file.c) */