diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2014-08-07 06:15:16 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-08-07 06:15:16 +0200 |
commit | 5b7b7ee5d943c6b58d9b7f974167d0105ca1b787 (patch) | |
tree | 5b01a8a5d8fa8f91f56547761df026adce9dabeb /lib | |
parent | f1ee4e8b73a356278056666da8d0c6b5aa53088d (diff) | |
parent | 07f93f54521c212558eb09adc812d97dffda443b (diff) | |
download | barebox-5b7b7ee5d943c6b58d9b7f974167d0105ca1b787.tar.gz barebox-5b7b7ee5d943c6b58d9b7f974167d0105ca1b787.tar.xz |
Merge branch 'for-next/metadata'
Conflicts:
arch/arm/dts/Makefile
common/Makefile
lib/Makefile
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/bootstrap/disk.c | 1 | ||||
-rw-r--r-- | lib/copy_file.c | 86 | ||||
-rw-r--r-- | lib/gui/image_renderer.c | 1 | ||||
-rw-r--r-- | lib/libbb.c | 93 | ||||
-rw-r--r-- | lib/libfile.c | 331 |
6 files changed, 334 insertions, 180 deletions
diff --git a/lib/Makefile b/lib/Makefile index 48c953d679..a75653fb48 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_GLOB) += fnmatch.o obj-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o obj-y += glob.o obj-y += notifier.o -obj-y += copy_file.o obj-y += random.o obj-y += lzo/ obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ @@ -45,3 +44,4 @@ obj-$(CONFIG_XYMODEM) += xymodem.o obj-y += unlink-recursive.o obj-$(CONFIG_STMP_DEVICE) += stmp-device.o obj-y += wchar.o +obj-y += libfile.o diff --git a/lib/bootstrap/disk.c b/lib/bootstrap/disk.c index 527e430897..1e9fbd834b 100644 --- a/lib/bootstrap/disk.c +++ b/lib/bootstrap/disk.c @@ -11,6 +11,7 @@ #include <sizes.h> #include <errno.h> #include <malloc.h> +#include <libfile.h> #include <bootstrap.h> void* bootstrap_read_disk(char *dev, char *fstype) diff --git a/lib/copy_file.c b/lib/copy_file.c deleted file mode 100644 index fdd0cacb40..0000000000 --- a/lib/copy_file.c +++ /dev/null @@ -1,86 +0,0 @@ -#include <common.h> -#include <fs.h> -#include <fcntl.h> -#include <errno.h> -#include <malloc.h> -#include <libbb.h> -#include <progress.h> - -/** - * @param[in] src FIXME - * @param[out] dst FIXME - * @param[in] verbose FIXME - */ -int copy_file(const char *src, const char *dst, int verbose) -{ - char *rw_buf = NULL; - int srcfd = 0, dstfd = 0; - int r, w; - int ret = 1; - void *buf; - int total = 0; - struct stat statbuf; - - rw_buf = xmalloc(RW_BUF_SIZE); - - srcfd = open(src, O_RDONLY); - if (srcfd < 0) { - printf("could not open %s: %s\n", src, errno_str()); - goto out; - } - - dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC); - if (dstfd < 0) { - printf("could not open %s: %s\n", dst, errno_str()); - goto out; - } - - if (verbose) { - if (stat(src, &statbuf) < 0) - statbuf.st_size = 0; - - init_progression_bar(statbuf.st_size); - } - - while(1) { - r = read(srcfd, rw_buf, RW_BUF_SIZE); - if (r < 0) { - perror("read"); - goto out; - } - if (!r) - break; - - buf = rw_buf; - while (r) { - w = write(dstfd, buf, r); - if (w < 0) { - perror("write"); - goto out; - } - buf += w; - r -= w; - total += w; - } - - if (verbose) { - if (statbuf.st_size && statbuf.st_size != FILESIZE_MAX) - show_progress(total); - else - show_progress(total / 16384); - } - } - - ret = 0; -out: - if (verbose) - putchar('\n'); - - free(rw_buf); - if (srcfd > 0) - close(srcfd); - if (dstfd > 0) - close(dstfd); - - return ret; -} diff --git a/lib/gui/image_renderer.c b/lib/gui/image_renderer.c index 8047961e9e..dd29389baa 100644 --- a/lib/gui/image_renderer.c +++ b/lib/gui/image_renderer.c @@ -10,6 +10,7 @@ #include <errno.h> #include <fs.h> #include <malloc.h> +#include <libfile.h> static LIST_HEAD(image_renderers); diff --git a/lib/libbb.c b/lib/libbb.c index dd42e662b4..239611c27b 100644 --- a/lib/libbb.c +++ b/lib/libbb.c @@ -126,96 +126,3 @@ char *simple_itoa(unsigned int i) return p + 1; } EXPORT_SYMBOL(simple_itoa); - -/* - * write_full - write to filedescriptor - * - * Like write, but guarantees to write the full buffer out, else - * it returns with an error. - */ -int write_full(int fd, void *buf, size_t size) -{ - size_t insize = size; - int now; - - while (size) { - now = write(fd, buf, size); - if (now <= 0) - return now; - size -= now; - buf += now; - } - - return insize; -} -EXPORT_SYMBOL(write_full); - -/* - * read_full - read from filedescriptor - * - * Like read, but this function only returns less bytes than - * requested when the end of file is reached. - */ -int read_full(int fd, void *buf, size_t size) -{ - size_t insize = size; - int now; - int total = 0; - - while (size) { - now = read(fd, buf, size); - if (now == 0) - return total; - if (now < 0) - return now; - total += now; - size -= now; - buf += now; - } - - return insize; -} -EXPORT_SYMBOL(read_full); - -/* - * read_file_line - read a line from a file - * - * Used to compose a filename from a printf format and to read a line from this - * file. All leading and trailing whitespaces (including line endings) are - * removed. The returned buffer must be freed with free(). This function is - * supposed for reading variable like content into a buffer, so files > 1024 - * bytes are ignored. - */ -char *read_file_line(const char *fmt, ...) -{ - va_list args; - char *filename; - char *buf, *line = NULL; - size_t size; - int ret; - struct stat s; - - va_start(args, fmt); - filename = vasprintf(fmt, args); - va_end(args); - - ret = stat(filename, &s); - if (ret) - goto out; - - if (s.st_size > 1024) - goto out; - - buf = read_file(filename, &size); - if (!buf) - goto out; - - line = strim(buf); - - line = xstrdup(line); - free(buf); -out: - free(filename); - return line; -} -EXPORT_SYMBOL_GPL(read_file_line); diff --git a/lib/libfile.c b/lib/libfile.c new file mode 100644 index 0000000000..c6fb6d7157 --- /dev/null +++ b/lib/libfile.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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. + * + */ +#include <common.h> +#include <fs.h> +#include <fcntl.h> +#include <malloc.h> +#include <libfile.h> +#include <progress.h> +#include <linux/stat.h> + +/* + * write_full - write to filedescriptor + * + * Like write, but guarantees to write the full buffer out, else + * it returns with an error. + */ +int write_full(int fd, void *buf, size_t size) +{ + size_t insize = size; + int now; + + while (size) { + now = write(fd, buf, size); + if (now <= 0) + return now; + size -= now; + buf += now; + } + + return insize; +} +EXPORT_SYMBOL(write_full); + +/* + * read_full - read from filedescriptor + * + * Like read, but this function only returns less bytes than + * requested when the end of file is reached. + */ +int read_full(int fd, void *buf, size_t size) +{ + size_t insize = size; + int now; + int total = 0; + + while (size) { + now = read(fd, buf, size); + if (now == 0) + return total; + if (now < 0) + return now; + total += now; + size -= now; + buf += now; + } + + return insize; +} +EXPORT_SYMBOL(read_full); + +/* + * read_file_line - read a line from a file + * + * Used to compose a filename from a printf format and to read a line from this + * file. All leading and trailing whitespaces (including line endings) are + * removed. The returned buffer must be freed with free(). This function is + * supposed for reading variable like content into a buffer, so files > 1024 + * bytes are ignored. + */ +char *read_file_line(const char *fmt, ...) +{ + va_list args; + char *filename; + char *buf, *line = NULL; + size_t size; + int ret; + struct stat s; + + va_start(args, fmt); + filename = vasprintf(fmt, args); + va_end(args); + + ret = stat(filename, &s); + if (ret) + goto out; + + if (s.st_size > 1024) + goto out; + + buf = read_file(filename, &size); + if (!buf) + goto out; + + line = strim(buf); + + line = xstrdup(line); + free(buf); +out: + free(filename); + return line; +} +EXPORT_SYMBOL_GPL(read_file_line); + +/** + * read_file_2 - read a file to an allocated buffer + * @filename: The filename to read + * @size: After successful return contains the size of the file + * @outbuf: contains a pointer to the file data after successful return + * @max_size: The maximum size to read. Use FILESIZE_MAX for reading files + * of any size. + * + * This function reads a file to an allocated buffer. At maximum @max_size + * bytes are read. The actual read size is returned in @size. -EFBIG is + * returned if the file is bigger than @max_size, but the buffer is read + * anyway up to @max_size in this case. Free the buffer with free() after + * usage. + * + * Return: 0 for success, or negative error code. -EFBIG is returned + * when the file has been bigger than max_size. + */ +int read_file_2(const char *filename, size_t *size, void **outbuf, + loff_t max_size) +{ + int fd; + struct stat s; + void *buf = NULL; + const char *tmpfile = "/.read_file_tmp"; + int ret; + loff_t read_size; + +again: + ret = stat(filename, &s); + if (ret) + return ret; + + if (max_size == FILESIZE_MAX) + read_size = s.st_size; + else + read_size = max_size; + + if (read_size == FILESIZE_MAX) { + ret = copy_file(filename, tmpfile, 0); + if (ret) + return ret; + filename = tmpfile; + goto again; + } + + buf = xzalloc(read_size + 1); + + fd = open(filename, O_RDONLY); + if (fd < 0) + goto err_out; + + ret = read_full(fd, buf, read_size); + if (ret < 0) + goto err_out1; + + close(fd); + + if (size) + *size = ret; + + if (filename == tmpfile) + unlink(tmpfile); + + *outbuf = buf; + + if (read_size < s.st_size) + return -EFBIG; + else + return 0; + +err_out1: + close(fd); +err_out: + free(buf); + + if (filename == tmpfile) + unlink(tmpfile); + + return ret; +} +EXPORT_SYMBOL(read_file_2); + +/** + * read_file - read a file to an allocated buffer + * @filename: The filename to read + * @size: After successful return contains the size of the file + * + * This function reads a file to an allocated buffer. + * Some TFTP servers do not transfer the size of a file. In this case + * a the file is first read to a temporary file. + * + * Return: The buffer conataining the file or NULL on failure + */ +void *read_file(const char *filename, size_t *size) +{ + int ret; + void *buf; + + ret = read_file_2(filename, size, &buf, FILESIZE_MAX); + if (!ret) + return buf; + + return NULL; +} +EXPORT_SYMBOL(read_file); + +/** + * write_file - write a buffer to a file + * @filename: The filename to write + * @size: The size of the buffer + * + * Return: 0 for success or negative error value + */ +int write_file(const char *filename, void *buf, size_t size) +{ + int fd, ret; + + fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT); + if (fd < 0) + return fd; + + ret = write_full(fd, buf, size); + + close(fd); + + if (ret < 0) + return ret; + + return 0; +} +EXPORT_SYMBOL(write_file); + +/** + * copy_file - Copy a file + * @src: The source filename + * @dst: The destination filename + * @verbose: if true, show a progression bar + * + * Return: 0 for success or negative error code + */ +int copy_file(const char *src, const char *dst, int verbose) +{ + char *rw_buf = NULL; + int srcfd = 0, dstfd = 0; + int r, w; + int ret = 1; + void *buf; + int total = 0; + struct stat statbuf; + + rw_buf = xmalloc(RW_BUF_SIZE); + + srcfd = open(src, O_RDONLY); + if (srcfd < 0) { + printf("could not open %s: %s\n", src, errno_str()); + goto out; + } + + dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC); + if (dstfd < 0) { + printf("could not open %s: %s\n", dst, errno_str()); + goto out; + } + + if (verbose) { + if (stat(src, &statbuf) < 0) + statbuf.st_size = 0; + + init_progression_bar(statbuf.st_size); + } + + while (1) { + r = read(srcfd, rw_buf, RW_BUF_SIZE); + if (r < 0) { + perror("read"); + goto out; + } + if (!r) + break; + + buf = rw_buf; + while (r) { + w = write(dstfd, buf, r); + if (w < 0) { + perror("write"); + goto out; + } + buf += w; + r -= w; + total += w; + } + + if (verbose) { + if (statbuf.st_size && statbuf.st_size != FILESIZE_MAX) + show_progress(total); + else + show_progress(total / 16384); + } + } + + ret = 0; +out: + if (verbose) + putchar('\n'); + + free(rw_buf); + if (srcfd > 0) + close(srcfd); + if (dstfd > 0) + close(dstfd); + + return ret; +} +EXPORT_SYMBOL(copy_file); |