source: mainline/uspace/lib/fmgt/src/copy.c

Last change on this file was 857fba8, checked in by Jiri Svoboda <jiri@…>, 20 hours ago

Move file system wrapper functions to a separate module.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2026 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fmgt
30 * @{
31 */
32/** @file Copy files and directories.
33 */
34
35#include <errno.h>
36#include <stdbool.h>
37#include <stdlib.h>
38#include <vfs/vfs.h>
39
40#include "fmgt.h"
41#include "fmgt/walk.h"
42#include "../private/fmgt.h"
43#include "../private/fsops.h"
44
45static errno_t fmgt_copy_dir_enter(void *, const char *, const char *);
46static errno_t fmgt_copy_file(void *, const char *, const char *);
47
48static fmgt_walk_cb_t fmgt_copy_cb = {
49 .dir_enter = fmgt_copy_dir_enter,
50 .file = fmgt_copy_file
51};
52
53/** Copy operation - enter directory.
54 *
55 * @param arg Argument (fmgt_t *)
56 * @param fname Source directory name
57 * @param dest Destination directory name
58 * @return EOK on success or an error code
59 */
60static errno_t fmgt_copy_dir_enter(void *arg, const char *src, const char *dest)
61{
62 fmgt_t *fmgt = (fmgt_t *)arg;
63
64 (void)dest;
65 return fmgt_create_dir(fmgt, dest);
66}
67
68/** Copy single file.
69 *
70 * @param arg Argument (fmgt_t *)
71 * @param fname Source file name
72 * @param dest Destination file name
73 * @return EOK on success or an error code
74 */
75static errno_t fmgt_copy_file(void *arg, const char *src, const char *dest)
76{
77 fmgt_t *fmgt = (fmgt_t *)arg;
78 int rfd;
79 int wfd;
80 size_t nr;
81 aoff64_t rpos = 0;
82 aoff64_t wpos = 0;
83 char *buffer;
84 bool skip;
85 errno_t rc;
86
87 buffer = calloc(BUFFER_SIZE, 1);
88 if (buffer == NULL)
89 return ENOMEM;
90
91 rc = fmgt_open(fmgt, src, &rfd);
92 if (rc != EOK) {
93 free(buffer);
94 return rc;
95 }
96
97 rc = fmgt_create_file(fmgt, dest, &wfd, &skip);
98 if (rc != EOK) {
99 free(buffer);
100 vfs_put(rfd);
101
102 /* User decided to skip and continue. */
103 if (rc == EEXIST && skip)
104 return EOK;
105 return rc;
106 }
107
108 fmgt_progress_init_file(fmgt, src);
109
110 do {
111 rc = fmgt_read(fmgt, rfd, src, &rpos, buffer, BUFFER_SIZE,
112 &nr);
113 if (rc != EOK)
114 goto error;
115
116 rc = fmgt_write(fmgt, wfd, dest, &wpos, buffer, nr);
117 if (rc != EOK)
118 goto error;
119
120 fmgt_progress_incr_bytes(fmgt, nr);
121
122 /* User requested abort? */
123 if (fmgt_abort_query(fmgt)) {
124 rc = EINTR;
125 goto error;
126 }
127 } while (nr > 0);
128
129 free(buffer);
130 vfs_put(rfd);
131 vfs_put(wfd);
132 fmgt_progress_incr_files(fmgt);
133 return EOK;
134error:
135 free(buffer);
136 vfs_put(rfd);
137 vfs_put(wfd);
138 fmgt_final_progress_update(fmgt);
139 return rc;
140}
141
142/** Copy files.
143 *
144 * @param fmgt File management object
145 * @param flist File list
146 * @param dest Destination path
147 * @return EOK on success or an error code
148 */
149errno_t fmgt_copy(fmgt_t *fmgt, fmgt_flist_t *flist, const char *dest)
150{
151 fmgt_walk_params_t params;
152 errno_t rc;
153
154 fmgt_walk_params_init(&params);
155
156 params.flist = flist;
157 params.dest = dest;
158 params.cb = &fmgt_copy_cb;
159 params.arg = (void *)fmgt;
160 if (fmgt_is_dir(dest))
161 params.into_dest = true;
162
163 fmgt_progress_init(fmgt);
164
165 fmgt_timer_start(fmgt);
166 fmgt_initial_progress_update(fmgt);
167 rc = fmgt_walk(&params);
168 fmgt_final_progress_update(fmgt);
169 return rc;
170}
171
172/** @}
173 */
Note: See TracBrowser for help on using the repository browser.