Clarify portability and main program.
[python/dscho.git] / BeOS / ar-1.1 / copy_attrs.c
blobc9f978de59cd74c0f5cab389a30abbca99bdc6d1
1 /*
2 ** copy_attrs.h - copy BeFS attributes from one file to another
3 **
4 ** Jan. 11, 1998 Chris Herborth (chrish@qnx.com)
5 **
6 ** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify,
7 ** redistribute, steal, or otherwise manipulate this code. No restrictions
8 ** at all. If you laugh at this code, you can't use it.
9 */
11 #include <support/Errors.h>
12 #ifndef NO_DEBUG
13 #include <assert.h>
14 #define ASSERT(cond) assert(cond)
15 #else
16 #define ASSERT(cond) ((void)0)
17 #endif
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <limits.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <kernel/fs_attr.h>
26 #include <fcntl.h>
28 #include "copy_attrs.h"
30 static const char *rcs_version_id = "$Id$";
32 /* ----------------------------------------------------------------------
33 ** Copy file attributes from src_file to dst_file.
36 status_t copy_attrs( const char *dst_file, const char *src_file )
38 int dst_fd, src_fd;
39 status_t retval = B_OK;
40 DIR *fa_dir = NULL;
41 struct dirent *fa_ent = NULL;
42 char *buff = NULL;
43 struct attr_info fa_info;
44 off_t read_bytes, wrote_bytes;
46 ASSERT( dst_file != NULL );
47 ASSERT( src_file != NULL );
49 /* Attempt to open the files.
51 src_fd = open( src_file, O_RDONLY );
52 if( src_fd < 0 ) {
53 return B_FILE_NOT_FOUND;
56 dst_fd = open( dst_file, O_WRONLY );
57 if( dst_fd < 0 ) {
58 close( src_fd );
59 return B_FILE_NOT_FOUND;
62 /* Read the attributes, and write them to the destination file.
64 fa_dir = fs_fopen_attr_dir( src_fd );
65 if( fa_dir == NULL ) {
66 retval = B_IO_ERROR;
67 goto close_return;
70 fa_ent = fs_read_attr_dir( fa_dir );
71 while( fa_ent != NULL ) {
72 retval = fs_stat_attr( src_fd, fa_ent->d_name, &fa_info );
73 if( retval != B_OK ) {
74 /* TODO: Print warning message?
76 goto read_next_attr;
79 if( fa_info.size > (off_t)UINT_MAX ) {
80 /* TODO: That's too big. Print a warning message? You could
81 ** copy it in chunks...
83 goto read_next_attr;
86 if( fa_info.size > (off_t)0 ) {
87 buff = malloc( (size_t)fa_info.size );
88 if( buff == NULL ) {
89 /* TODO: Can't allocate memory for this attribute. Warning?
91 goto read_next_attr;
94 read_bytes = fs_read_attr( src_fd, fa_ent->d_name, fa_info.type,
95 0, buff, fa_info.size );
96 if( read_bytes != fa_info.size ) {
97 /* TODO: Couldn't read entire attribute. Warning?
99 goto free_attr_buff;
102 wrote_bytes = fs_write_attr( dst_fd, fa_ent->d_name, fa_info.type,
103 0, buff, fa_info.size );
104 if( wrote_bytes != fa_info.size ) {
105 /* TODO: Couldn't write entire attribute. Warning?
110 free_attr_buff:
111 free( buff );
113 retval = B_OK;
116 /* Read the next entry.
118 read_next_attr:
119 fa_ent = fs_read_attr_dir( fa_dir );
122 close_return:
123 close( dst_fd );
124 close( src_fd );
126 return retval;