1879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger/*
236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass * Copyright 2011 The Chromium Authors, All Rights Reserved.
3879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
4879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *
5492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass * util_is_printable_string contributed by
6492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass *	Pantelis Antoniou <pantelis.antoniou AT gmail.com>
7492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass *
8879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger * This program is free software; you can redistribute it and/or
9879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger * modify it under the terms of the GNU General Public License as
10879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger * published by the Free Software Foundation; either version 2 of the
11879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger * License, or (at your option) any later version.
12879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *
13879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *  This program is distributed in the hope that it will be useful,
14879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *  General Public License for more details.
17879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *
18879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *  You should have received a copy of the GNU General Public License
19879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *  along with this program; if not, write to the Free Software
20879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
21879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger *                                                                   USA
22879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger */
23879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger
24492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass#include <ctype.h>
258765874963852b2733777e69686251205238ad3dDavid Gibson#include <stdio.h>
268765874963852b2733777e69686251205238ad3dDavid Gibson#include <stdlib.h>
278765874963852b2733777e69686251205238ad3dDavid Gibson#include <stdarg.h>
288765874963852b2733777e69686251205238ad3dDavid Gibson#include <string.h>
29b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf#include <assert.h>
308765874963852b2733777e69686251205238ad3dDavid Gibson
3136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass#include <errno.h>
3236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass#include <fcntl.h>
3336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass#include <unistd.h>
3436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
3536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass#include "libfdt.h"
368765874963852b2733777e69686251205238ad3dDavid Gibson#include "util.h"
37a768648acbcc235ca6d31993cacec8cca68843a4Chris Phoenix#include "version_non_gen.h"
38879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger
39879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeligerchar *xstrdup(const char *s)
40879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger{
41879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger	int len = strlen(s) + 1;
4224cb3d0681d9196d57176a0a94bfc6e610ef7b45Florian Fainelli	char *d = xmalloc(len);
43879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger
4424cb3d0681d9196d57176a0a94bfc6e610ef7b45Florian Fainelli	memcpy(d, s, len);
45879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger
4624cb3d0681d9196d57176a0a94bfc6e610ef7b45Florian Fainelli	return d;
47879e4d2590b50d63f82c3c3652bc3c7900591f1cJon Loeliger}
48d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson
499dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou/* based in part from (3) vsnprintf */
509dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniouint xasprintf(char **strp, const char *fmt, ...)
519dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou{
529dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	int n, size = 128;	/* start with 128 bytes */
539dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	char *p;
549dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	va_list ap;
559dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou
569dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	/* initial pointer is NULL making the fist realloc to be malloc */
579dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	p = NULL;
589dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	while (1) {
599dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		p = xrealloc(p, size);
609dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou
619dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		/* Try to print in the allocated space. */
629dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		va_start(ap, fmt);
639dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		n = vsnprintf(p, size, fmt, ap);
649dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		va_end(ap);
659dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou
669dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		/* If that worked, return the string. */
679dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		if (n > -1 && n < size)
689dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou			break;
699dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		/* Else try again with more space. */
709dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		if (n > -1)	/* glibc 2.1 */
719dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou			size = n + 1; /* precisely what is needed */
729dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou		else		/* glibc 2.0 */
739dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou			size *= 2; /* twice the old size */
749dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	}
759dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	*strp = p;
769dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou	return strlen(p);
779dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou}
789dc404958e9c91f33f75450f69b690a5e676af04Pantelis Antoniou
79d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibsonchar *join_path(const char *path, const char *name)
80d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson{
81d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	int lenp = strlen(path);
82d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	int lenn = strlen(name);
83d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	int len;
84d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	int needslash = 1;
85d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	char *str;
86d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson
87d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	len = lenp + lenn + 2;
88d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	if ((lenp > 0) && (path[lenp-1] == '/')) {
89d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson		needslash = 0;
90d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson		len--;
91d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	}
92d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson
93d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	str = xmalloc(len);
94d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	memcpy(str, path, lenp);
95d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	if (needslash) {
96d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson		str[lenp] = '/';
97d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson		lenp++;
98d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	}
99d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	memcpy(str+lenp, name, lenn+1);
100d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson	return str;
101d68cb36b0bebc7711ada9b750f3c19398c44efb7David Gibson}
102492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass
10317625371eeea2fa7257361163c52d336a1a98ebcDavid Gibsonbool util_is_printable_string(const void *data, int len)
104492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass{
105492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass	const char *s = data;
1061c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou	const char *ss, *se;
107492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass
108492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass	/* zero length is not */
109492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass	if (len == 0)
110492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass		return 0;
111492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass
112492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass	/* must terminate with zero */
113492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass	if (s[len - 1] != '\0')
114492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass		return 0;
115492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass
1161c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou	se = s + len;
117492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass
1181c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou	while (s < se) {
1191c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou		ss = s;
12017119ab0a52df5fb30749d038d796d7e78702e3cSerge Lamikhov-Center		while (s < se && *s && isprint((unsigned char)*s))
1211c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou			s++;
1221c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou
1231c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou		/* not zero, or not done yet */
1241c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou		if (*s != '\0' || s == ss)
1251c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou			return 0;
1261c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou
1271c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou		s++;
1281c1efd69545a101d7181fc8e5df2b9a3545a58e8Pantelis Antoniou	}
129492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass
130492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass	return 1;
131492f9d5de7db74aeb3a905246c4efd7cb29227a8Simon Glass}
132b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
133b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf/*
134b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * Parse a octal encoded character starting at index i in string s.  The
135b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * resulting character will be returned and the index i will be updated to
136b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * point at the character directly after the end of the encoding, this may be
137b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * the '\0' terminator of the string.
138b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf */
139b43335a23854b2620140eda6cca2ffae59e8de23Anton Staafstatic char get_oct_char(const char *s, int *i)
140b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf{
141b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	char x[4];
142b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	char *endx;
143b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	long val;
144b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
145b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	x[3] = '\0';
146b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	strncpy(x, s + *i, 3);
147b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
148b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	val = strtol(x, &endx, 8);
149b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
150b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	assert(endx > x);
151b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
152b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	(*i) += endx - x;
153b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	return val;
154b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf}
155b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
156b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf/*
157b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * Parse a hexadecimal encoded character starting at index i in string s.  The
158b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * resulting character will be returned and the index i will be updated to
159b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * point at the character directly after the end of the encoding, this may be
160b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf * the '\0' terminator of the string.
161b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf */
162b43335a23854b2620140eda6cca2ffae59e8de23Anton Staafstatic char get_hex_char(const char *s, int *i)
163b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf{
164b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	char x[3];
165b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	char *endx;
166b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	long val;
167b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
168b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	x[2] = '\0';
169b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	strncpy(x, s + *i, 2);
170b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
171b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	val = strtol(x, &endx, 16);
172b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	if (!(endx  > x))
173b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		die("\\x used with no following hex digits\n");
174b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
175b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	(*i) += endx - x;
176b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	return val;
177b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf}
178b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
179b43335a23854b2620140eda6cca2ffae59e8de23Anton Staafchar get_escape_char(const char *s, int *i)
180b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf{
181b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	char	c = s[*i];
182b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	int	j = *i + 1;
183b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	char	val;
184b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
185b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	switch (c) {
186b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 'a':
187b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = '\a';
188b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
189b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 'b':
190b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = '\b';
191b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
192b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 't':
193b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = '\t';
194b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
195b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 'n':
196b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = '\n';
197b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
198b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 'v':
199b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = '\v';
200b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
201b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 'f':
202b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = '\f';
203b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
204b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 'r':
205b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = '\r';
206b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
207b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '0':
208b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '1':
209b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '2':
210b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '3':
211b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '4':
212b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '5':
213b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '6':
214b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case '7':
215b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		j--; /* need to re-read the first digit as
216b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		      * part of the octal value */
217b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = get_oct_char(s, &j);
218b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
219b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	case 'x':
220b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = get_hex_char(s, &j);
221b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		break;
222b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	default:
223b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf		val = c;
224b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	}
225b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf
226b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	(*i) = j;
227b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf	return val;
228b43335a23854b2620140eda6cca2ffae59e8de23Anton Staaf}
22936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
230a6d55e039fd22048687fe061b4609e2807efe764Mike Frysingerint utilfdt_read_err_len(const char *filename, char **buffp, off_t *len)
23136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass{
23236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int fd = 0;	/* assume stdin */
23336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	char *buf = NULL;
23436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	off_t bufsize = 1024, offset = 0;
23536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int ret = 0;
23636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
23736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	*buffp = NULL;
23836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (strcmp(filename, "-") != 0) {
23936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		fd = open(filename, O_RDONLY);
24036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		if (fd < 0)
24136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			return errno;
24236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	}
24336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
24436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* Loop until we have read everything */
245f8cb5dd94903a5cfa1609695328b8f1d5557367fMike Frysinger	buf = xmalloc(bufsize);
24636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	do {
24736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		/* Expand the buffer to hold the next chunk */
24836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		if (offset == bufsize) {
24936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			bufsize *= 2;
250f8cb5dd94903a5cfa1609695328b8f1d5557367fMike Frysinger			buf = xrealloc(buf, bufsize);
25136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		}
25236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
25336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		ret = read(fd, &buf[offset], bufsize - offset);
25436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		if (ret < 0) {
25536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			ret = errno;
25636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			break;
25736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		}
25836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		offset += ret;
25936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	} while (ret != 0);
26036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
26136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* Clean up, including closing stdin; return errno on error */
26236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	close(fd);
26336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (ret)
26436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		free(buf);
26536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	else
26636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		*buffp = buf;
267a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger	*len = bufsize;
26836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	return ret;
26936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass}
27036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
271a6d55e039fd22048687fe061b4609e2807efe764Mike Frysingerint utilfdt_read_err(const char *filename, char **buffp)
272a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger{
273a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger	off_t len;
274a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger	return utilfdt_read_err_len(filename, buffp, &len);
275a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger}
276a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger
277a6d55e039fd22048687fe061b4609e2807efe764Mike Frysingerchar *utilfdt_read_len(const char *filename, off_t *len)
27836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass{
27936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	char *buff;
280a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger	int ret = utilfdt_read_err_len(filename, &buff, len);
28136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
28236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (ret) {
28336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
28436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			strerror(ret));
28536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		return NULL;
28636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	}
28736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* Successful read */
28836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	return buff;
28936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass}
29036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
291a6d55e039fd22048687fe061b4609e2807efe764Mike Frysingerchar *utilfdt_read(const char *filename)
292a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger{
293a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger	off_t len;
294a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger	return utilfdt_read_len(filename, &len);
295a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger}
296a6d55e039fd22048687fe061b4609e2807efe764Mike Frysinger
29736204fdf742cabc074617648a5b2cf62409dc40bSimon Glassint utilfdt_write_err(const char *filename, const void *blob)
29836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass{
29936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int fd = 1;	/* assume stdout */
30036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int totalsize;
30136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int offset;
30236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int ret = 0;
30336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	const char *ptr = blob;
30436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
30536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (strcmp(filename, "-") != 0) {
30636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
30736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		if (fd < 0)
30836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			return errno;
30936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	}
31036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
31136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	totalsize = fdt_totalsize(blob);
31236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	offset = 0;
31336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
31436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	while (offset < totalsize) {
31536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		ret = write(fd, ptr + offset, totalsize - offset);
31636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		if (ret < 0) {
31736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			ret = -errno;
31836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			break;
31936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		}
32036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		offset += ret;
32136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	}
32236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* Close the file/stdin; return errno on error */
32336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (fd != 1)
32436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		close(fd);
32536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	return ret < 0 ? -ret : 0;
32636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass}
32736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
32836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
32936204fdf742cabc074617648a5b2cf62409dc40bSimon Glassint utilfdt_write(const char *filename, const void *blob)
33036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass{
33136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int ret = utilfdt_write_err(filename, blob);
33236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
33336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (ret) {
33436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		fprintf(stderr, "Couldn't write blob to '%s': %s\n", filename,
33536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			strerror(ret));
33636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	}
33736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	return ret ? -1 : 0;
33836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass}
33936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
34036204fdf742cabc074617648a5b2cf62409dc40bSimon Glassint utilfdt_decode_type(const char *fmt, int *type, int *size)
34136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass{
34236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	int qualifier = 0;
34336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
344e280442e08fcbe8431dc85d836ff3ecc489932fbDavid Gibson	if (!*fmt)
345e280442e08fcbe8431dc85d836ff3ecc489932fbDavid Gibson		return -1;
346e280442e08fcbe8431dc85d836ff3ecc489932fbDavid Gibson
34736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* get the conversion qualifier */
34836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	*size = -1;
34936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (strchr("hlLb", *fmt)) {
35036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		qualifier = *fmt++;
35136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		if (qualifier == *fmt) {
35236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			switch (*fmt++) {
35336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass/* TODO:		case 'l': qualifier = 'L'; break;*/
35436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			case 'h':
35536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass				qualifier = 'b';
35636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass				break;
35736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass			}
35836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		}
35936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	}
36036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
36136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* we should now have a type */
362e280442e08fcbe8431dc85d836ff3ecc489932fbDavid Gibson	if ((*fmt == '\0') || !strchr("iuxs", *fmt))
36336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		return -1;
36436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
36536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* convert qualifier (bhL) to byte size */
36636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (*fmt != 's')
36736204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		*size = qualifier == 'b' ? 1 :
36836204fdf742cabc074617648a5b2cf62409dc40bSimon Glass				qualifier == 'h' ? 2 :
36936204fdf742cabc074617648a5b2cf62409dc40bSimon Glass				qualifier == 'l' ? 4 : -1;
37036204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	*type = *fmt++;
37136204fdf742cabc074617648a5b2cf62409dc40bSimon Glass
37236204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	/* that should be it! */
37336204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	if (*fmt)
37436204fdf742cabc074617648a5b2cf62409dc40bSimon Glass		return -1;
37536204fdf742cabc074617648a5b2cf62409dc40bSimon Glass	return 0;
37636204fdf742cabc074617648a5b2cf62409dc40bSimon Glass}
377d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass
378d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glassvoid utilfdt_print_data(const char *data, int len)
379d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass{
380d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	int i;
381d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	const char *s;
382d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass
383d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	/* no data, don't print */
384d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	if (len == 0)
385d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		return;
386d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass
387d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	if (util_is_printable_string(data, len)) {
388d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		printf(" = ");
389d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass
390d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		s = data;
391d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		do {
392d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass			printf("\"%s\"", s);
393d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass			s += strlen(s) + 1;
394d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass			if (s < data + len)
395d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass				printf(", ");
396d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		} while (s < data + len);
397d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass
398d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	} else if ((len % 4) == 0) {
399bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibson		const fdt32_t *cell = (const fdt32_t *)data;
400d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass
401d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		printf(" = <");
402c78ca72e1e89714a7a62a85035e5c505c8ba51f0Simon Glass		for (i = 0, len /= 4; i < len; i++)
403c78ca72e1e89714a7a62a85035e5c505c8ba51f0Simon Glass			printf("0x%08x%s", fdt32_to_cpu(cell[i]),
404c78ca72e1e89714a7a62a85035e5c505c8ba51f0Simon Glass			       i < (len - 1) ? " " : "");
405d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		printf(">");
406d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	} else {
407e5e6df7c37f7de13af33a3096e9c66127bb75d15David Gibson		const unsigned char *p = (const unsigned char *)data;
408d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		printf(" = [");
409d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		for (i = 0; i < len; i++)
410d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass			printf("%02x%s", *p++, i < len - 1 ? " " : "");
411d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass		printf("]");
412d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass	}
413d20391d6ff45c8fa7281e945491817c35f42b51bSimon Glass}
41431be4ce7ca550a6fd9c4eb39abdd2f9f5ac8db44Mike Frysinger
415bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibsonvoid NORETURN util_version(void)
41631be4ce7ca550a6fd9c4eb39abdd2f9f5ac8db44Mike Frysinger{
41731be4ce7ca550a6fd9c4eb39abdd2f9f5ac8db44Mike Frysinger	printf("Version: %s\n", DTC_VERSION);
41831be4ce7ca550a6fd9c4eb39abdd2f9f5ac8db44Mike Frysinger	exit(0);
41931be4ce7ca550a6fd9c4eb39abdd2f9f5ac8db44Mike Frysinger}
420be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
421bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibsonvoid NORETURN util_usage(const char *errmsg, const char *synopsis,
422bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibson			 const char *short_opts,
423bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibson			 struct option const long_opts[],
424bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibson			 const char * const opts_help[])
425be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger{
426be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	FILE *fp = errmsg ? stderr : stdout;
427be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	const char a_arg[] = "<arg>";
428be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	size_t a_arg_len = strlen(a_arg) + 1;
429be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	size_t i;
430be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	int optlen;
431be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
432be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	fprintf(fp,
433be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		"Usage: %s\n"
434be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		"\n"
435be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		"Options: -[%s]\n", synopsis, short_opts);
436be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
437be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	/* prescan the --long opt length to auto-align */
438be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	optlen = 0;
439be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	for (i = 0; long_opts[i].name; ++i) {
440be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		/* +1 is for space between --opt and help text */
441be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		int l = strlen(long_opts[i].name) + 1;
442be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		if (long_opts[i].has_arg == a_argument)
443be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger			l += a_arg_len;
444be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		if (optlen < l)
445be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger			optlen = l;
446be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	}
447be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
448be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	for (i = 0; long_opts[i].name; ++i) {
449be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		/* helps when adding new applets or options */
450be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		assert(opts_help[i] != NULL);
451be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
452be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		/* first output the short flag if it has one */
453be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		if (long_opts[i].val > '~')
454be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger			fprintf(fp, "      ");
455be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		else
456be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger			fprintf(fp, "  -%c, ", long_opts[i].val);
457be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
458be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		/* then the long flag */
459be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		if (long_opts[i].has_arg == no_argument)
460be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger			fprintf(fp, "--%-*s", optlen, long_opts[i].name);
461be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		else
462be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger			fprintf(fp, "--%s %s%*s", long_opts[i].name, a_arg,
463be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger				(int)(optlen - strlen(long_opts[i].name) - a_arg_len), "");
464be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
465be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		/* finally the help text */
466be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		fprintf(fp, "%s\n", opts_help[i]);
467be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	}
468be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger
469be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	if (errmsg) {
470be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		fprintf(fp, "\nError: %s\n", errmsg);
471be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		exit(EXIT_FAILURE);
472be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger	} else
473be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger		exit(EXIT_SUCCESS);
474be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53Mike Frysinger}
475