1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <ctype.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <stdarg.h>
28#include <string.h>
29#include <assert.h>
30
31#include <errno.h>
32#include <fcntl.h>
33#include <unistd.h>
34
35#include "libfdt.h"
36#include "util.h"
37
38char *xstrdup(const char *s)
39{
40 int len = strlen(s) + 1;
41 char *dup = xmalloc(len);
42
43 memcpy(dup, s, len);
44
45 return dup;
46}
47
48char *join_path(const char *path, const char *name)
49{
50 int lenp = strlen(path);
51 int lenn = strlen(name);
52 int len;
53 int needslash = 1;
54 char *str;
55
56 len = lenp + lenn + 2;
57 if ((lenp > 0) && (path[lenp-1] == '/')) {
58 needslash = 0;
59 len--;
60 }
61
62 str = xmalloc(len);
63 memcpy(str, path, lenp);
64 if (needslash) {
65 str[lenp] = '/';
66 lenp++;
67 }
68 memcpy(str+lenp, name, lenn+1);
69 return str;
70}
71
72int util_is_printable_string(const void *data, int len)
73{
74 const char *s = data;
75 const char *ss;
76
77
78 if (len == 0)
79 return 0;
80
81
82 if (s[len - 1] != '\0')
83 return 0;
84
85 ss = s;
86 while (*s && isprint(*s))
87 s++;
88
89
90 if (*s != '\0' || (s + 1 - ss) < len)
91 return 0;
92
93 return 1;
94}
95
96
97
98
99
100
101
102static char get_oct_char(const char *s, int *i)
103{
104 char x[4];
105 char *endx;
106 long val;
107
108 x[3] = '\0';
109 strncpy(x, s + *i, 3);
110
111 val = strtol(x, &endx, 8);
112
113 assert(endx > x);
114
115 (*i) += endx - x;
116 return val;
117}
118
119
120
121
122
123
124
125static char get_hex_char(const char *s, int *i)
126{
127 char x[3];
128 char *endx;
129 long val;
130
131 x[2] = '\0';
132 strncpy(x, s + *i, 2);
133
134 val = strtol(x, &endx, 16);
135 if (!(endx > x))
136 die("\\x used with no following hex digits\n");
137
138 (*i) += endx - x;
139 return val;
140}
141
142char get_escape_char(const char *s, int *i)
143{
144 char c = s[*i];
145 int j = *i + 1;
146 char val;
147
148 assert(c);
149 switch (c) {
150 case 'a':
151 val = '\a';
152 break;
153 case 'b':
154 val = '\b';
155 break;
156 case 't':
157 val = '\t';
158 break;
159 case 'n':
160 val = '\n';
161 break;
162 case 'v':
163 val = '\v';
164 break;
165 case 'f':
166 val = '\f';
167 break;
168 case 'r':
169 val = '\r';
170 break;
171 case '0':
172 case '1':
173 case '2':
174 case '3':
175 case '4':
176 case '5':
177 case '6':
178 case '7':
179 j--;
180
181 val = get_oct_char(s, &j);
182 break;
183 case 'x':
184 val = get_hex_char(s, &j);
185 break;
186 default:
187 val = c;
188 }
189
190 (*i) = j;
191 return val;
192}
193
194int utilfdt_read_err(const char *filename, char **buffp)
195{
196 int fd = 0;
197 char *buf = NULL;
198 off_t bufsize = 1024, offset = 0;
199 int ret = 0;
200
201 *buffp = NULL;
202 if (strcmp(filename, "-") != 0) {
203 fd = open(filename, O_RDONLY);
204 if (fd < 0)
205 return errno;
206 }
207
208
209 buf = malloc(bufsize);
210 do {
211
212 if (offset == bufsize) {
213 bufsize *= 2;
214 buf = realloc(buf, bufsize);
215 if (!buf) {
216 ret = ENOMEM;
217 break;
218 }
219 }
220
221 ret = read(fd, &buf[offset], bufsize - offset);
222 if (ret < 0) {
223 ret = errno;
224 break;
225 }
226 offset += ret;
227 } while (ret != 0);
228
229
230 close(fd);
231 if (ret)
232 free(buf);
233 else
234 *buffp = buf;
235 return ret;
236}
237
238char *utilfdt_read(const char *filename)
239{
240 char *buff;
241 int ret = utilfdt_read_err(filename, &buff);
242
243 if (ret) {
244 fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
245 strerror(ret));
246 return NULL;
247 }
248
249 return buff;
250}
251
252int utilfdt_write_err(const char *filename, const void *blob)
253{
254 int fd = 1;
255 int totalsize;
256 int offset;
257 int ret = 0;
258 const char *ptr = blob;
259
260 if (strcmp(filename, "-") != 0) {
261 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
262 if (fd < 0)
263 return errno;
264 }
265
266 totalsize = fdt_totalsize(blob);
267 offset = 0;
268
269 while (offset < totalsize) {
270 ret = write(fd, ptr + offset, totalsize - offset);
271 if (ret < 0) {
272 ret = -errno;
273 break;
274 }
275 offset += ret;
276 }
277
278 if (fd != 1)
279 close(fd);
280 return ret < 0 ? -ret : 0;
281}
282
283
284int utilfdt_write(const char *filename, const void *blob)
285{
286 int ret = utilfdt_write_err(filename, blob);
287
288 if (ret) {
289 fprintf(stderr, "Couldn't write blob to '%s': %s\n", filename,
290 strerror(ret));
291 }
292 return ret ? -1 : 0;
293}
294
295int utilfdt_decode_type(const char *fmt, int *type, int *size)
296{
297 int qualifier = 0;
298
299 if (!*fmt)
300 return -1;
301
302
303 *size = -1;
304 if (strchr("hlLb", *fmt)) {
305 qualifier = *fmt++;
306 if (qualifier == *fmt) {
307 switch (*fmt++) {
308
309 case 'h':
310 qualifier = 'b';
311 break;
312 }
313 }
314 }
315
316
317 if ((*fmt == '\0') || !strchr("iuxs", *fmt))
318 return -1;
319
320
321 if (*fmt != 's')
322 *size = qualifier == 'b' ? 1 :
323 qualifier == 'h' ? 2 :
324 qualifier == 'l' ? 4 : -1;
325 *type = *fmt++;
326
327
328 if (*fmt)
329 return -1;
330 return 0;
331}
332