Line data Source code
1 : /*
2 : * Copyright (c) 2005 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include <config.h>
35 :
36 : #include "roken.h"
37 :
38 : /*
39 : * Write datablob to a filename, don't care about errors.
40 : */
41 :
42 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
43 0 : rk_dumpdata (const char *filename, const void *buf, size_t size)
44 : {
45 0 : int fd;
46 :
47 0 : fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0640);
48 0 : if (fd < 0)
49 0 : return;
50 0 : net_write(fd, buf, size);
51 0 : close(fd);
52 : }
53 :
54 : /* For not-regular files */
55 : static int
56 0 : undump_not_file(int fd, char **out, size_t *size, int nul_terminate)
57 : {
58 0 : size_t lim = 10 * 1024 * 1024;
59 0 : size_t bufsz = 0;
60 0 : size_t sz = 0;
61 0 : char *buf = NULL;
62 0 : char *tmp;
63 :
64 0 : *out = NULL;
65 0 : if (size && *size != 0 && *size < lim)
66 0 : lim = *size;
67 0 : if (size)
68 0 : *size = 0;
69 :
70 : /*
71 : * We can't use net_read() if we're on WIN32 because that really wants a
72 : * socket FD, which is in a distinct FD namespace from those returned by
73 : * open() on Windows.
74 : */
75 0 : do {
76 0 : ssize_t bytes;
77 :
78 0 : if (sz == bufsz) {
79 0 : if (bufsz == 0)
80 0 : bufsz = 1024;
81 : else
82 0 : bufsz += bufsz >> 1;
83 :
84 0 : tmp = realloc(buf, bufsz);
85 0 : if (tmp == NULL) {
86 0 : free(buf);
87 0 : return ENOMEM;
88 : }
89 0 : buf = tmp;
90 : }
91 :
92 0 : bytes = read(fd, buf + sz, bufsz - sz);
93 0 : if (bytes == 0)
94 0 : break;
95 0 : if (bytes < 0 &&
96 0 : (errno == EAGAIN || errno == EWOULDBLOCK))
97 0 : continue;
98 0 : if (bytes < 0) {
99 0 : free(buf);
100 0 : return errno;
101 : }
102 0 : sz += bytes;
103 0 : } while (sz < lim);
104 :
105 0 : *out = buf;
106 0 : if (size)
107 0 : *size = sz;
108 :
109 0 : if (!nul_terminate)
110 0 : return 0;
111 :
112 0 : if (bufsz > sz) {
113 0 : buf[sz] = '\0';
114 0 : return 0;
115 : }
116 :
117 0 : *out = tmp = realloc(buf, bufsz + 1);
118 0 : if (tmp == NULL) {
119 0 : free(buf);
120 0 : return ENOMEM;
121 : }
122 0 : buf = tmp;
123 0 : buf[sz] = '\0';
124 0 : return 0;
125 : }
126 :
127 : /*
128 : * Read all data from a file, care about errors.
129 : *
130 : * If `*size' is not zero and the file is not a regular file, then up to that
131 : * many bytes will be read.
132 : *
133 : * Returns zero on success or a system error code on failure.
134 : */
135 :
136 : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
137 0 : rk_undumpdata(const char *filename, void **buf, size_t *size)
138 : {
139 0 : struct stat sb;
140 0 : int fd, ret;
141 0 : ssize_t sret;
142 :
143 0 : *buf = NULL;
144 :
145 0 : fd = open(filename, O_RDONLY, 0);
146 0 : if (fd < 0)
147 0 : return errno;
148 0 : if (fstat(fd, &sb) != 0){
149 0 : ret = errno;
150 0 : goto out;
151 : }
152 0 : if (!S_ISREG(sb.st_mode)) {
153 0 : char *char_buf;
154 :
155 0 : ret = undump_not_file(fd, &char_buf, size, 0);
156 0 : (void) close(fd);
157 0 : *buf = char_buf;
158 0 : return ret;
159 : }
160 :
161 0 : if (sb.st_size < 0)
162 0 : sb.st_size = 0;
163 0 : *buf = malloc(sb.st_size);
164 0 : if (*buf == NULL) {
165 0 : ret = ENOMEM;
166 0 : goto out;
167 : }
168 0 : *size = sb.st_size;
169 :
170 0 : sret = read(fd, *buf, *size);
171 0 : if (sret < 0)
172 0 : ret = errno;
173 0 : else if (sret != (ssize_t)*size)
174 0 : ret = EINVAL;
175 : else
176 0 : ret = 0;
177 :
178 0 : out:
179 0 : if (ret) {
180 0 : free(*buf);
181 0 : *buf = NULL;
182 : }
183 0 : close(fd);
184 0 : return ret;
185 : }
186 :
187 : /*
188 : * Read all text from a file.
189 : *
190 : * Outputs a C string. It is up to the caller to check for embedded NULs.
191 : * The number of bytes read will be stored in `*size' if `size' is not NULL.
192 : *
193 : * If `size' is not NULL and `*size' is not zero and the file is not a regular
194 : * file, then up to that many bytes will be read.
195 : *
196 : * Returns zero on success or a system error code on failure.
197 : */
198 :
199 : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
200 0 : rk_undumptext(const char *filename, char **out, size_t *size)
201 : {
202 0 : struct stat sb;
203 0 : int fd, ret;
204 0 : ssize_t sret;
205 0 : char *buf;
206 :
207 0 : *out = NULL;
208 :
209 0 : fd = open(filename, O_RDONLY, 0);
210 0 : if (fd < 0)
211 0 : return errno;
212 0 : if (fstat(fd, &sb) != 0) {
213 0 : (void) close(fd);
214 0 : return errno;
215 : }
216 0 : if (!S_ISREG(sb.st_mode)) {
217 0 : ret = undump_not_file(fd, out, size, 1);
218 0 : (void) close(fd);
219 0 : return ret;
220 : }
221 :
222 0 : if (sb.st_size < 0)
223 0 : sb.st_size = 0;
224 0 : buf = malloc(sb.st_size + 1);
225 0 : if (buf == NULL) {
226 0 : ret = ENOMEM;
227 0 : goto out;
228 : }
229 0 : if (size)
230 0 : *size = sb.st_size;
231 :
232 0 : sret = read(fd, buf, sb.st_size);
233 0 : if (sret < 0)
234 0 : ret = errno;
235 0 : else if (sret != (ssize_t)sb.st_size)
236 0 : ret = EINVAL;
237 : else
238 0 : ret = 0;
239 :
240 0 : out:
241 0 : if (ret) {
242 0 : free(buf);
243 : } else {
244 0 : buf[sb.st_size] = '\0';
245 0 : *out = buf;
246 : }
247 0 : close(fd);
248 0 : return ret;
249 : }
|