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