blob: c9f978de59cd74c0f5cab389a30abbca99bdc6d1 [file] [log] [blame]
Guido van Rossumd8eb2111998-08-04 17:57:28 +00001/*
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*/
10
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
18
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>
27
28#include "copy_attrs.h"
29
30static const char *rcs_version_id = "$Id$";
31
32/* ----------------------------------------------------------------------
33** Copy file attributes from src_file to dst_file.
34*/
35
36status_t copy_attrs( const char *dst_file, const char *src_file )
37{
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;
45
46 ASSERT( dst_file != NULL );
47 ASSERT( src_file != NULL );
48
49 /* Attempt to open the files.
50 */
51 src_fd = open( src_file, O_RDONLY );
52 if( src_fd < 0 ) {
53 return B_FILE_NOT_FOUND;
54 }
55
56 dst_fd = open( dst_file, O_WRONLY );
57 if( dst_fd < 0 ) {
58 close( src_fd );
59 return B_FILE_NOT_FOUND;
60 }
61
62 /* Read the attributes, and write them to the destination file.
63 */
64 fa_dir = fs_fopen_attr_dir( src_fd );
65 if( fa_dir == NULL ) {
66 retval = B_IO_ERROR;
67 goto close_return;
68 }
69
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?
75 */
76 goto read_next_attr;
77 }
78
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...
82 */
83 goto read_next_attr;
84 }
85
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?
90 */
91 goto read_next_attr;
92 }
93
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?
98 */
99 goto free_attr_buff;
100 }
101
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?
106 */
107 ;
108 }
109
110 free_attr_buff:
111 free( buff );
112
113 retval = B_OK;
114 }
115
116 /* Read the next entry.
117 */
118 read_next_attr:
119 fa_ent = fs_read_attr_dir( fa_dir );
120 }
121
122close_return:
123 close( dst_fd );
124 close( src_fd );
125
126 return retval;
127}
128