source: mainline/uspace/app/sysinst/futil.c@ b8b64a8

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b8b64a8 was 1433ecda, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix cstyle: make ccheck-fix and commit only files where all the changes are good.

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[3a34852]1/*
2 * Copyright (c) 2014 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 sysinst
30 * @{
31 */
32/** @file File manipulation utility functions for installer
33 */
34
35#include <dirent.h>
36#include <errno.h>
37#include <stdbool.h>
38#include <stdio.h>
39#include <stdlib.h>
[8d2dd7f2]40#include <stddef.h>
[23a0368]41#include <vfs/vfs.h>
[3a34852]42#include <dirent.h>
43
44#include "futil.h"
45
46#define BUF_SIZE 16384
47static char buf[BUF_SIZE];
48
49/** Copy file.
50 *
51 * @param srcp Source path
52 * @param dstp Destination path
53 *
54 * @return EOK on success, EIO on I/O error
55 */
[b7fd2a0]56errno_t futil_copy_file(const char *srcp, const char *destp)
[3a34852]57{
58 int sf, df;
[8e3498b]59 size_t nr, nw;
[b7fd2a0]60 errno_t rc;
[58898d1d]61 aoff64_t posr = 0, posw = 0;
[3a34852]62
63 printf("Copy '%s' to '%s'.\n", srcp, destp);
64
[f77c1c9]65 rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);
66 if (rc != EOK)
[3a34852]67 return EIO;
68
[f77c1c9]69 rc = vfs_lookup_open(destp, WALK_REGULAR | WALK_MAY_CREATE, MODE_WRITE, &df);
70 if (rc != EOK)
[3a34852]71 return EIO;
72
73 do {
[8e3498b]74 rc = vfs_read(sf, &posr, buf, BUF_SIZE, &nr);
75 if (rc != EOK)
76 goto error;
[3a34852]77 if (nr == 0)
78 break;
79
[1433ecda]80 rc = vfs_write(df, &posw, buf, nr, &nw);
[8e3498b]81 if (rc != EOK)
82 goto error;
83
84 } while (nr == BUF_SIZE);
[3a34852]85
[9c4cf0d]86 (void) vfs_put(sf);
[3a34852]87
[9c4cf0d]88 rc = vfs_put(df);
[f77c1c9]89 if (rc != EOK)
[3a34852]90 return EIO;
91
92 return EOK;
[8e3498b]93error:
94 vfs_put(sf);
95 vfs_put(df);
96 return rc;
[3a34852]97}
98
99/** Copy contents of srcdir (recursively) into destdir.
100 *
101 * @param srcdir Source directory
102 * @param destdir Destination directory
103 *
104 * @return EOK on success, ENOMEM if out of memory, EIO on I/O error
105 */
[b7fd2a0]106errno_t futil_rcopy_contents(const char *srcdir, const char *destdir)
[3a34852]107{
108 DIR *dir;
109 struct dirent *de;
[39330200]110 vfs_stat_t s;
[3a34852]111 char *srcp, *destp;
[b7fd2a0]112 errno_t rc;
[3a34852]113
114 dir = opendir(srcdir);
115 if (dir == NULL)
116 return EIO;
117
118 de = readdir(dir);
119 while (de != NULL) {
120 if (asprintf(&srcp, "%s/%s", srcdir, de->d_name) < 0)
121 return ENOMEM;
122 if (asprintf(&destp, "%s/%s", destdir, de->d_name) < 0)
123 return ENOMEM;
124
[23a0368]125 rc = vfs_stat_path(srcp, &s);
[3a34852]126 if (rc != EOK)
127 return EIO;
128
129 if (s.is_file) {
130 rc = futil_copy_file(srcp, destp);
131 if (rc != EOK)
132 return EIO;
133 } else if (s.is_directory) {
134 printf("Create directory '%s'\n", destp);
[a6fc88a]135 rc = vfs_link_path(destp, KIND_DIRECTORY, NULL);
[3a34852]136 if (rc != EOK)
137 return EIO;
138 rc = futil_rcopy_contents(srcp, destp);
139 if (rc != EOK)
140 return EIO;
141 } else {
142 return EIO;
143 }
144
145 de = readdir(dir);
146 }
147
148 return EOK;
149}
150
151/** Return file contents as a heap-allocated block of bytes.
152 *
153 * @param srcp File path
154 * @param rdata Place to store pointer to data
155 * @param rsize Place to store size of data
156 *
157 * @return EOK on success, ENOENT if failed to open file, EIO on other
158 * I/O error, ENOMEM if out of memory
159 */
[b7fd2a0]160errno_t futil_get_file(const char *srcp, void **rdata, size_t *rsize)
[3a34852]161{
162 int sf;
[8e3498b]163 size_t nr;
[b7fd2a0]164 errno_t rc;
[3a34852]165 size_t fsize;
166 char *data;
[39330200]167 vfs_stat_t st;
[3a34852]168
[f77c1c9]169 rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);
170 if (rc != EOK)
[3a34852]171 return ENOENT;
172
[23a0368]173 if (vfs_stat(sf, &st) != EOK) {
[9c4cf0d]174 vfs_put(sf);
[3a34852]175 return EIO;
[8e3498b]176 }
[3a34852]177
[58898d1d]178 fsize = st.size;
[3a34852]179
180 data = calloc(fsize, 1);
[58898d1d]181 if (data == NULL) {
[9c4cf0d]182 vfs_put(sf);
[3a34852]183 return ENOMEM;
[58898d1d]184 }
[3a34852]185
[8e3498b]186 rc = vfs_read(sf, (aoff64_t []) { 0 }, data, fsize, &nr);
187 if (rc != EOK || nr != fsize) {
[9c4cf0d]188 vfs_put(sf);
[58898d1d]189 free(data);
[3a34852]190 return EIO;
[58898d1d]191 }
[3a34852]192
[9c4cf0d]193 (void) vfs_put(sf);
[3a34852]194 *rdata = data;
195 *rsize = fsize;
196
197 return EOK;
198}
199
200/** @}
201 */
Note: See TracBrowser for help on using the repository browser.