1 /* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lib.h"
4 #include "fs-api-private.h"
5 #include "ostream.h"
6 
7 struct wrapper_fs_iter {
8 	struct fs_iter iter;
9 	struct fs_iter *parent;
10 };
11 
fs_wrapper_get_properties(struct fs * fs)12 enum fs_properties fs_wrapper_get_properties(struct fs *fs)
13 {
14 	return fs_get_properties(fs->parent);
15 }
16 
fs_wrapper_file_close(struct fs_file * file)17 void fs_wrapper_file_close(struct fs_file *file)
18 {
19 	fs_file_close(file->parent);
20 }
21 
fs_wrapper_file_get_path(struct fs_file * file)22 const char *fs_wrapper_file_get_path(struct fs_file *file)
23 {
24 	return fs_file_path(file->parent);
25 }
26 
fs_wrapper_set_async_callback(struct fs_file * file,fs_file_async_callback_t * callback,void * context)27 void fs_wrapper_set_async_callback(struct fs_file *file,
28 				   fs_file_async_callback_t *callback,
29 				   void *context)
30 {
31 	fs_file_set_async_callback(file->parent, *callback, context);
32 }
33 
fs_wrapper_wait_async(struct fs * fs)34 void fs_wrapper_wait_async(struct fs *fs)
35 {
36 	fs_wait_async(fs->parent);
37 }
38 
fs_wrapper_set_metadata(struct fs_file * file,const char * key,const char * value)39 void fs_wrapper_set_metadata(struct fs_file *file, const char *key,
40 			     const char *value)
41 {
42 	fs_set_metadata(file->parent, key, value);
43 }
44 
fs_wrapper_get_metadata(struct fs_file * file,enum fs_get_metadata_flags flags,const ARRAY_TYPE (fs_metadata)** metadata_r)45 int fs_wrapper_get_metadata(struct fs_file *file,
46 			    enum fs_get_metadata_flags flags,
47 			    const ARRAY_TYPE(fs_metadata) **metadata_r)
48 {
49 	return fs_get_metadata_full(file->parent, flags, metadata_r);
50 }
51 
fs_wrapper_prefetch(struct fs_file * file,uoff_t length)52 bool fs_wrapper_prefetch(struct fs_file *file, uoff_t length)
53 {
54 	return fs_prefetch(file->parent, length);
55 }
56 
fs_wrapper_read(struct fs_file * file,void * buf,size_t size)57 ssize_t fs_wrapper_read(struct fs_file *file, void *buf, size_t size)
58 {
59 	return fs_read(file->parent, buf, size);
60 }
61 
62 struct istream *
fs_wrapper_read_stream(struct fs_file * file,size_t max_buffer_size)63 fs_wrapper_read_stream(struct fs_file *file, size_t max_buffer_size)
64 {
65 	return fs_read_stream(file->parent, max_buffer_size);
66 }
67 
fs_wrapper_write(struct fs_file * file,const void * data,size_t size)68 int fs_wrapper_write(struct fs_file *file, const void *data, size_t size)
69 {
70 	return fs_write(file->parent, data, size);
71 }
72 
fs_wrapper_write_stream(struct fs_file * file)73 void fs_wrapper_write_stream(struct fs_file *file)
74 {
75 	i_assert(file->output == NULL);
76 
77 	file->output = fs_write_stream(file->parent);
78 }
79 
fs_wrapper_write_stream_finish(struct fs_file * file,bool success)80 int fs_wrapper_write_stream_finish(struct fs_file *file, bool success)
81 {
82 	if (file->output == NULL)
83 		return fs_write_stream_finish_async(file->parent);
84 
85 	if (!success) {
86 		fs_write_stream_abort_parent(file, &file->output);
87 		return -1;
88 	}
89 	return fs_write_stream_finish(file->parent, &file->output);
90 }
91 
fs_wrapper_lock(struct fs_file * file,unsigned int secs,struct fs_lock ** lock_r)92 int fs_wrapper_lock(struct fs_file *file, unsigned int secs,
93 		    struct fs_lock **lock_r)
94 {
95 	return fs_lock(file->parent, secs, lock_r);
96 }
97 
fs_wrapper_unlock(struct fs_lock * _lock ATTR_UNUSED)98 void fs_wrapper_unlock(struct fs_lock *_lock ATTR_UNUSED)
99 {
100 	i_unreached();
101 }
102 
fs_wrapper_exists(struct fs_file * file)103 int fs_wrapper_exists(struct fs_file *file)
104 {
105 	return fs_exists(file->parent);
106 }
107 
fs_wrapper_stat(struct fs_file * file,struct stat * st_r)108 int fs_wrapper_stat(struct fs_file *file, struct stat *st_r)
109 {
110 	return fs_stat(file->parent, st_r);
111 }
112 
fs_wrapper_get_nlinks(struct fs_file * file,nlink_t * nlinks_r)113 int fs_wrapper_get_nlinks(struct fs_file *file, nlink_t *nlinks_r)
114 {
115 	return fs_get_nlinks(file->parent, nlinks_r);
116 }
117 
fs_wrapper_copy(struct fs_file * src,struct fs_file * dest)118 int fs_wrapper_copy(struct fs_file *src, struct fs_file *dest)
119 {
120 	if (src != NULL)
121 		return fs_copy(src->parent, dest->parent);
122 	else
123 		return fs_copy_finish_async(dest->parent);
124 }
125 
fs_wrapper_rename(struct fs_file * src,struct fs_file * dest)126 int fs_wrapper_rename(struct fs_file *src, struct fs_file *dest)
127 {
128 	return fs_rename(src->parent, dest->parent);
129 }
130 
fs_wrapper_delete(struct fs_file * file)131 int fs_wrapper_delete(struct fs_file *file)
132 {
133 	return fs_delete(file->parent);
134 }
135 
fs_wrapper_iter_alloc(void)136 struct fs_iter *fs_wrapper_iter_alloc(void)
137 {
138 	struct wrapper_fs_iter *iter = i_new(struct wrapper_fs_iter, 1);
139 	return &iter->iter;
140 }
141 
fs_wrapper_iter_init(struct fs_iter * _iter,const char * path,enum fs_iter_flags flags)142 void fs_wrapper_iter_init(struct fs_iter *_iter, const char *path,
143 			  enum fs_iter_flags flags)
144 {
145 	struct wrapper_fs_iter *iter = (struct wrapper_fs_iter *)_iter;
146 
147 	iter->parent = fs_iter_init_parent(_iter, path, flags);
148 }
149 
fs_wrapper_iter_next(struct fs_iter * _iter)150 const char *fs_wrapper_iter_next(struct fs_iter *_iter)
151 {
152 	struct wrapper_fs_iter *iter = (struct wrapper_fs_iter *)_iter;
153 	const char *fname;
154 
155 	iter->parent->async_callback = _iter->async_callback;
156 	iter->parent->async_context = _iter->async_context;
157 
158 	fname = fs_iter_next(iter->parent);
159 	_iter->async_have_more = iter->parent->async_have_more;
160 	return fname;
161 }
162 
fs_wrapper_iter_deinit(struct fs_iter * _iter)163 int fs_wrapper_iter_deinit(struct fs_iter *_iter)
164 {
165 	struct wrapper_fs_iter *iter = (struct wrapper_fs_iter *)_iter;
166 	const char *error;
167 	int ret;
168 
169 	if ((ret = fs_iter_deinit(&iter->parent, &error)) < 0)
170 		fs_set_error_errno(_iter->event, "%s", error);
171 	return ret;
172 }
173