Get rid of sys/time.h
[helenos.git] / uspace / app / sysinst / futil.c
blob45fbe01dbe4dddabbdd66f051a6154ca02710cb4
1 /*
2 * Copyright (c) 2014 Jiri Svoboda
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
29 /** @addtogroup sysinst
30 * @{
32 /** @file File manipulation utility functions for installer
35 #include <dirent.h>
36 #include <errno.h>
37 #include <stdbool.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <stddef.h>
41 #include <vfs/vfs.h>
42 #include <dirent.h>
44 #include "futil.h"
46 #define BUF_SIZE 16384
47 static char buf[BUF_SIZE];
49 /** Copy file.
51 * @param srcp Source path
52 * @param dstp Destination path
54 * @return EOK on success, EIO on I/O error
56 errno_t futil_copy_file(const char *srcp, const char *destp)
58 int sf, df;
59 size_t nr, nw;
60 errno_t rc;
61 aoff64_t posr = 0, posw = 0;
63 printf("Copy '%s' to '%s'.\n", srcp, destp);
65 rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);
66 if (rc != EOK)
67 return EIO;
69 rc = vfs_lookup_open(destp, WALK_REGULAR | WALK_MAY_CREATE, MODE_WRITE, &df);
70 if (rc != EOK)
71 return EIO;
73 do {
74 rc = vfs_read(sf, &posr, buf, BUF_SIZE, &nr);
75 if (rc != EOK)
76 goto error;
77 if (nr == 0)
78 break;
80 rc = vfs_write(df, &posw, buf, nr, &nw);
81 if (rc != EOK)
82 goto error;
84 } while (nr == BUF_SIZE);
86 (void) vfs_put(sf);
88 rc = vfs_put(df);
89 if (rc != EOK)
90 return EIO;
92 return EOK;
93 error:
94 vfs_put(sf);
95 vfs_put(df);
96 return rc;
99 /** Copy contents of srcdir (recursively) into destdir.
101 * @param srcdir Source directory
102 * @param destdir Destination directory
104 * @return EOK on success, ENOMEM if out of memory, EIO on I/O error
106 errno_t futil_rcopy_contents(const char *srcdir, const char *destdir)
108 DIR *dir;
109 struct dirent *de;
110 vfs_stat_t s;
111 char *srcp, *destp;
112 errno_t rc;
114 dir = opendir(srcdir);
115 if (dir == NULL)
116 return EIO;
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;
125 rc = vfs_stat_path(srcp, &s);
126 if (rc != EOK)
127 return EIO;
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);
135 rc = vfs_link_path(destp, KIND_DIRECTORY, NULL);
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;
145 de = readdir(dir);
148 return EOK;
151 /** Return file contents as a heap-allocated block of bytes.
153 * @param srcp File path
154 * @param rdata Place to store pointer to data
155 * @param rsize Place to store size of data
157 * @return EOK on success, ENOENT if failed to open file, EIO on other
158 * I/O error, ENOMEM if out of memory
160 errno_t futil_get_file(const char *srcp, void **rdata, size_t *rsize)
162 int sf;
163 size_t nr;
164 errno_t rc;
165 size_t fsize;
166 char *data;
167 vfs_stat_t st;
169 rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);
170 if (rc != EOK)
171 return ENOENT;
173 if (vfs_stat(sf, &st) != EOK) {
174 vfs_put(sf);
175 return EIO;
178 fsize = st.size;
180 data = calloc(fsize, 1);
181 if (data == NULL) {
182 vfs_put(sf);
183 return ENOMEM;
186 rc = vfs_read(sf, (aoff64_t []) { 0 }, data, fsize, &nr);
187 if (rc != EOK || nr != fsize) {
188 vfs_put(sf);
189 free(data);
190 return EIO;
193 (void) vfs_put(sf);
194 *rdata = data;
195 *rsize = fsize;
197 return EOK;
200 /** @}