| Viewing file:  util.c (6.24 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
/** Copyright 2011 The Chromium Authors, All Rights Reserved.
 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
 *
 * util_is_printable_string contributed by
 *    Pantelis Antoniou <pantelis.antoniou AT gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 *                                                                   USA
 */
 
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
 #include <assert.h>
 
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 
 #include "libfdt.h"
 #include "util.h"
 
 char *xstrdup(const char *s)
 {
 int len = strlen(s) + 1;
 char *dup = xmalloc(len);
 
 memcpy(dup, s, len);
 
 return dup;
 }
 
 char *join_path(const char *path, const char *name)
 {
 int lenp = strlen(path);
 int lenn = strlen(name);
 int len;
 int needslash = 1;
 char *str;
 
 len = lenp + lenn + 2;
 if ((lenp > 0) && (path[lenp-1] == '/')) {
 needslash = 0;
 len--;
 }
 
 str = xmalloc(len);
 memcpy(str, path, lenp);
 if (needslash) {
 str[lenp] = '/';
 lenp++;
 }
 memcpy(str+lenp, name, lenn+1);
 return str;
 }
 
 int util_is_printable_string(const void *data, int len)
 {
 const char *s = data;
 const char *ss;
 
 /* zero length is not */
 if (len == 0)
 return 0;
 
 /* must terminate with zero */
 if (s[len - 1] != '\0')
 return 0;
 
 ss = s;
 while (*s && isprint(*s))
 s++;
 
 /* not zero, or not done yet */
 if (*s != '\0' || (s + 1 - ss) < len)
 return 0;
 
 return 1;
 }
 
 /*
 * Parse a octal encoded character starting at index i in string s.  The
 * resulting character will be returned and the index i will be updated to
 * point at the character directly after the end of the encoding, this may be
 * the '\0' terminator of the string.
 */
 static char get_oct_char(const char *s, int *i)
 {
 char x[4];
 char *endx;
 long val;
 
 x[3] = '\0';
 strncpy(x, s + *i, 3);
 
 val = strtol(x, &endx, 8);
 
 assert(endx > x);
 
 (*i) += endx - x;
 return val;
 }
 
 /*
 * Parse a hexadecimal encoded character starting at index i in string s.  The
 * resulting character will be returned and the index i will be updated to
 * point at the character directly after the end of the encoding, this may be
 * the '\0' terminator of the string.
 */
 static char get_hex_char(const char *s, int *i)
 {
 char x[3];
 char *endx;
 long val;
 
 x[2] = '\0';
 strncpy(x, s + *i, 2);
 
 val = strtol(x, &endx, 16);
 if (!(endx  > x))
 die("\\x used with no following hex digits\n");
 
 (*i) += endx - x;
 return val;
 }
 
 char get_escape_char(const char *s, int *i)
 {
 char    c = s[*i];
 int    j = *i + 1;
 char    val;
 
 assert(c);
 switch (c) {
 case 'a':
 val = '\a';
 break;
 case 'b':
 val = '\b';
 break;
 case 't':
 val = '\t';
 break;
 case 'n':
 val = '\n';
 break;
 case 'v':
 val = '\v';
 break;
 case 'f':
 val = '\f';
 break;
 case 'r':
 val = '\r';
 break;
 case '0':
 case '1':
 case '2':
 case '3':
 case '4':
 case '5':
 case '6':
 case '7':
 j--; /* need to re-read the first digit as
 * part of the octal value */
 val = get_oct_char(s, &j);
 break;
 case 'x':
 val = get_hex_char(s, &j);
 break;
 default:
 val = c;
 }
 
 (*i) = j;
 return val;
 }
 
 int utilfdt_read_err(const char *filename, char **buffp)
 {
 int fd = 0;    /* assume stdin */
 char *buf = NULL;
 off_t bufsize = 1024, offset = 0;
 int ret = 0;
 
 *buffp = NULL;
 if (strcmp(filename, "-") != 0) {
 fd = open(filename, O_RDONLY);
 if (fd < 0)
 return errno;
 }
 
 /* Loop until we have read everything */
 buf = malloc(bufsize);
 do {
 /* Expand the buffer to hold the next chunk */
 if (offset == bufsize) {
 bufsize *= 2;
 buf = realloc(buf, bufsize);
 if (!buf) {
 ret = ENOMEM;
 break;
 }
 }
 
 ret = read(fd, &buf[offset], bufsize - offset);
 if (ret < 0) {
 ret = errno;
 break;
 }
 offset += ret;
 } while (ret != 0);
 
 /* Clean up, including closing stdin; return errno on error */
 close(fd);
 if (ret)
 free(buf);
 else
 *buffp = buf;
 return ret;
 }
 
 char *utilfdt_read(const char *filename)
 {
 char *buff;
 int ret = utilfdt_read_err(filename, &buff);
 
 if (ret) {
 fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
 strerror(ret));
 return NULL;
 }
 /* Successful read */
 return buff;
 }
 
 int utilfdt_write_err(const char *filename, const void *blob)
 {
 int fd = 1;    /* assume stdout */
 int totalsize;
 int offset;
 int ret = 0;
 const char *ptr = blob;
 
 if (strcmp(filename, "-") != 0) {
 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 if (fd < 0)
 return errno;
 }
 
 totalsize = fdt_totalsize(blob);
 offset = 0;
 
 while (offset < totalsize) {
 ret = write(fd, ptr + offset, totalsize - offset);
 if (ret < 0) {
 ret = -errno;
 break;
 }
 offset += ret;
 }
 /* Close the file/stdin; return errno on error */
 if (fd != 1)
 close(fd);
 return ret < 0 ? -ret : 0;
 }
 
 
 int utilfdt_write(const char *filename, const void *blob)
 {
 int ret = utilfdt_write_err(filename, blob);
 
 if (ret) {
 fprintf(stderr, "Couldn't write blob to '%s': %s\n", filename,
 strerror(ret));
 }
 return ret ? -1 : 0;
 }
 
 int utilfdt_decode_type(const char *fmt, int *type, int *size)
 {
 int qualifier = 0;
 
 if (!*fmt)
 return -1;
 
 /* get the conversion qualifier */
 *size = -1;
 if (strchr("hlLb", *fmt)) {
 qualifier = *fmt++;
 if (qualifier == *fmt) {
 switch (*fmt++) {
 /* TODO:        case 'l': qualifier = 'L'; break;*/
 case 'h':
 qualifier = 'b';
 break;
 }
 }
 }
 
 /* we should now have a type */
 if ((*fmt == '\0') || !strchr("iuxs", *fmt))
 return -1;
 
 /* convert qualifier (bhL) to byte size */
 if (*fmt != 's')
 *size = qualifier == 'b' ? 1 :
 qualifier == 'h' ? 2 :
 qualifier == 'l' ? 4 : -1;
 *type = *fmt++;
 
 /* that should be it! */
 if (*fmt)
 return -1;
 return 0;
 }
 
 |