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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a6fc88a was a6fc88a, checked in by Jakub Jermar <jakub@…>, 8 years ago

Let vfs_link() and vfs_link_path() return the linked file handle

Add an output argument to both vfs_link() and vfs_link_path() so that the
client may receive the file handle of the linked file or directory. This
makes it easy to work with the new file or directory as it is ready to be
opened or in case of a directory to use it as a parent for further
operations without the need for additional vfs_lookup().

  • Property mode set to 100644
File size: 4.4 KB
Line 
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>
40#include <vfs/vfs.h>
41#include <sys/types.h>
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 */
56int futil_copy_file(const char *srcp, const char *destp)
57{
58 int sf, df;
59 ssize_t nr, nw;
60 int rc;
61 aoff64_t posr = 0, posw = 0;
62
63 printf("Copy '%s' to '%s'.\n", srcp, destp);
64
65 sf = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ);
66 if (sf < 0)
67 return EIO;
68
69 df = vfs_lookup_open(destp, WALK_REGULAR | WALK_MAY_CREATE, MODE_WRITE);
70 if (df < 0)
71 return EIO;
72
73 do {
74 nr = vfs_read(sf, &posr, buf, BUF_SIZE);
75 if (nr == 0)
76 break;
77 if (nr < 0)
78 return EIO;
79
80 nw = vfs_write(df, &posw, buf, nr);
81 if (nw <= 0)
82 return EIO;
83 } while (true);
84
85 (void) vfs_put(sf);
86
87 rc = vfs_put(df);
88 if (rc < 0)
89 return EIO;
90
91 return EOK;
92}
93
94/** Copy contents of srcdir (recursively) into destdir.
95 *
96 * @param srcdir Source directory
97 * @param destdir Destination directory
98 *
99 * @return EOK on success, ENOMEM if out of memory, EIO on I/O error
100 */
101int futil_rcopy_contents(const char *srcdir, const char *destdir)
102{
103 DIR *dir;
104 struct dirent *de;
105 struct stat s;
106 char *srcp, *destp;
107 int rc;
108
109 dir = opendir(srcdir);
110 if (dir == NULL)
111 return EIO;
112
113 de = readdir(dir);
114 while (de != NULL) {
115 if (asprintf(&srcp, "%s/%s", srcdir, de->d_name) < 0)
116 return ENOMEM;
117 if (asprintf(&destp, "%s/%s", destdir, de->d_name) < 0)
118 return ENOMEM;
119
120 rc = vfs_stat_path(srcp, &s);
121 if (rc != EOK)
122 return EIO;
123
124 if (s.is_file) {
125 rc = futil_copy_file(srcp, destp);
126 if (rc != EOK)
127 return EIO;
128 } else if (s.is_directory) {
129 printf("Create directory '%s'\n", destp);
130 rc = vfs_link_path(destp, KIND_DIRECTORY, NULL);
131 if (rc != EOK)
132 return EIO;
133 rc = futil_rcopy_contents(srcp, destp);
134 if (rc != EOK)
135 return EIO;
136 } else {
137 return EIO;
138 }
139
140 de = readdir(dir);
141 }
142
143 return EOK;
144}
145
146/** Return file contents as a heap-allocated block of bytes.
147 *
148 * @param srcp File path
149 * @param rdata Place to store pointer to data
150 * @param rsize Place to store size of data
151 *
152 * @return EOK on success, ENOENT if failed to open file, EIO on other
153 * I/O error, ENOMEM if out of memory
154 */
155int futil_get_file(const char *srcp, void **rdata, size_t *rsize)
156{
157 int sf;
158 ssize_t nr;
159 size_t fsize;
160 char *data;
161 struct stat st;
162
163 sf = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ);
164 if (sf < 0)
165 return ENOENT;
166
167 if (vfs_stat(sf, &st) != EOK) {
168 vfs_put(sf);
169 return EIO;
170 }
171
172 fsize = st.size;
173
174 data = calloc(fsize, 1);
175 if (data == NULL) {
176 vfs_put(sf);
177 return ENOMEM;
178 }
179
180 nr = vfs_read(sf, (aoff64_t []) { 0 }, data, fsize);
181 if (nr != (ssize_t)fsize) {
182 vfs_put(sf);
183 free(data);
184 return EIO;
185 }
186
187 (void) vfs_put(sf);
188 *rdata = data;
189 *rsize = fsize;
190
191 return EOK;
192}
193
194/** @}
195 */
Note: See TracBrowser for help on using the repository browser.