diff options
Diffstat (limited to 'BeOS/ar-1.1/copy_attrs.c')
-rw-r--r-- | BeOS/ar-1.1/copy_attrs.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/BeOS/ar-1.1/copy_attrs.c b/BeOS/ar-1.1/copy_attrs.c new file mode 100644 index 0000000..c9f978d --- /dev/null +++ b/BeOS/ar-1.1/copy_attrs.c @@ -0,0 +1,128 @@ +/* +** copy_attrs.h - copy BeFS attributes from one file to another +** +** Jan. 11, 1998 Chris Herborth (chrish@qnx.com) +** +** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify, +** redistribute, steal, or otherwise manipulate this code. No restrictions +** at all. If you laugh at this code, you can't use it. +*/ + +#include <support/Errors.h> +#ifndef NO_DEBUG +#include <assert.h> +#define ASSERT(cond) assert(cond) +#else +#define ASSERT(cond) ((void)0) +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> +#include <string.h> +#include <errno.h> +#include <kernel/fs_attr.h> +#include <fcntl.h> + +#include "copy_attrs.h" + +static const char *rcs_version_id = "$Id$"; + +/* ---------------------------------------------------------------------- +** Copy file attributes from src_file to dst_file. +*/ + +status_t copy_attrs( const char *dst_file, const char *src_file ) +{ + int dst_fd, src_fd; + status_t retval = B_OK; + DIR *fa_dir = NULL; + struct dirent *fa_ent = NULL; + char *buff = NULL; + struct attr_info fa_info; + off_t read_bytes, wrote_bytes; + + ASSERT( dst_file != NULL ); + ASSERT( src_file != NULL ); + + /* Attempt to open the files. + */ + src_fd = open( src_file, O_RDONLY ); + if( src_fd < 0 ) { + return B_FILE_NOT_FOUND; + } + + dst_fd = open( dst_file, O_WRONLY ); + if( dst_fd < 0 ) { + close( src_fd ); + return B_FILE_NOT_FOUND; + } + + /* Read the attributes, and write them to the destination file. + */ + fa_dir = fs_fopen_attr_dir( src_fd ); + if( fa_dir == NULL ) { + retval = B_IO_ERROR; + goto close_return; + } + + fa_ent = fs_read_attr_dir( fa_dir ); + while( fa_ent != NULL ) { + retval = fs_stat_attr( src_fd, fa_ent->d_name, &fa_info ); + if( retval != B_OK ) { + /* TODO: Print warning message? + */ + goto read_next_attr; + } + + if( fa_info.size > (off_t)UINT_MAX ) { + /* TODO: That's too big. Print a warning message? You could + ** copy it in chunks... + */ + goto read_next_attr; + } + + if( fa_info.size > (off_t)0 ) { + buff = malloc( (size_t)fa_info.size ); + if( buff == NULL ) { + /* TODO: Can't allocate memory for this attribute. Warning? + */ + goto read_next_attr; + } + + read_bytes = fs_read_attr( src_fd, fa_ent->d_name, fa_info.type, + 0, buff, fa_info.size ); + if( read_bytes != fa_info.size ) { + /* TODO: Couldn't read entire attribute. Warning? + */ + goto free_attr_buff; + } + + wrote_bytes = fs_write_attr( dst_fd, fa_ent->d_name, fa_info.type, + 0, buff, fa_info.size ); + if( wrote_bytes != fa_info.size ) { + /* TODO: Couldn't write entire attribute. Warning? + */ + ; + } + + free_attr_buff: + free( buff ); + + retval = B_OK; + } + + /* Read the next entry. + */ + read_next_attr: + fa_ent = fs_read_attr_dir( fa_dir ); + } + +close_return: + close( dst_fd ); + close( src_fd ); + + return retval; +} + |