mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 3/4] environment: Add function to load envfs from buffer
Date: Thu, 20 Feb 2014 14:49:28 +0100	[thread overview]
Message-ID: <1392904169-786-3-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1392904169-786-1-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/environment.c | 181 +++++++++++++++++++++++++++++++++------------------
 include/envfs.h      |   1 +
 2 files changed, 117 insertions(+), 65 deletions(-)

diff --git a/common/environment.c b/common/environment.c
index 695baf7..19fb027 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -218,78 +218,52 @@ out1:
 }
 EXPORT_SYMBOL(envfs_save);
 
-/**
- * Restore the last environment into the current one
- * @param[in] filename from where to restore
- * @param[in] dir where to store the last content
- * @return 0 on success, anything else in case of failure
- *
- * Note: This function will also be used on the host! See note in the header
- * of this file.
- */
-int envfs_load(const char *filename, const char *dir, unsigned flags)
+static int envfs_check_super(struct envfs_super *super, size_t *size)
 {
-	struct envfs_super super;
-	void *buf = NULL, *buf_free = NULL;
-	int envfd;
-	int fd, ret = 0;
-	char *str, *tmp;
-	int headerlen_full;
-	unsigned long size;
-	/* for envfs < 1.0 */
-	struct envfs_inode_end inode_end_dummy;
-
-	inode_end_dummy.mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO);
-	inode_end_dummy.magic = ENVFS_32(ENVFS_INODE_END_MAGIC);
-
-	envfd = open(filename, O_RDONLY);
-	if (envfd < 0) {
-		printf("Open %s %s\n", filename, errno_str());
-		return -1;
+	if (ENVFS_32(super->magic) != ENVFS_MAGIC) {
+		printf("envfs: wrong magic\n");
+		return -EIO;
 	}
 
-	/* read superblock */
-	ret = read(envfd, &super, sizeof(struct envfs_super));
-	if ( ret < sizeof(struct envfs_super)) {
-		perror("read");
-		ret = -errno;
-		goto out;
+	if (crc32(0, super, sizeof(*super) - 4) != ENVFS_32(super->sb_crc)) {
+		printf("wrong crc on env superblock\n");
+		return -EIO;
 	}
 
-	if ( ENVFS_32(super.magic) != ENVFS_MAGIC) {
-		printf("envfs: wrong magic on %s\n", filename);
-		ret = -EIO;
-		goto out;
-	}
+	if (super->major < ENVFS_MAJOR)
+		printf("envfs version %d.%d loaded into %d.%d\n",
+			super->major, super->minor,
+			ENVFS_MAJOR, ENVFS_MINOR);
 
-	if (crc32(0, (unsigned char *)&super, sizeof(struct envfs_super) - 4)
-		   != ENVFS_32(super.sb_crc)) {
-		printf("wrong crc on env superblock\n");
-		ret = -EIO;
-		goto out;
-	}
+	*size = ENVFS_32(super->size);
 
-	size = ENVFS_32(super.size);
-	buf = xmalloc(size);
-	buf_free = buf;
-	ret = read(envfd, buf, size);
-	if (ret < size) {
-		perror("read");
-		ret = -errno;
-		goto out;
-	}
+	return 0;
+}
 
-	if (crc32(0, (unsigned char *)buf, size)
-		     != ENVFS_32(super.crc)) {
+static int envfs_check_data(struct envfs_super *super, void *buf, size_t size)
+{
+	uint32_t crc;
+
+	crc = crc32(0, buf, size);
+	if (crc != ENVFS_32(super->crc)) {
 		printf("wrong crc on env\n");
-		ret = -EIO;
-		goto out;
+		return -EIO;
 	}
 
-	if (super.major < ENVFS_MAJOR)
-		printf("envfs version %d.%d loaded into %d.%d\n",
-			super.major, super.minor,
-			ENVFS_MAJOR, ENVFS_MINOR);
+	return 0;
+}
+
+static int envfs_load_data(void *buf, size_t size, const char *dir, unsigned flags)
+{
+	struct envfs_super super;
+	int fd, ret = 0;
+	char *str, *tmp;
+	int headerlen_full;
+	/* for envfs < 1.0 */
+	struct envfs_inode_end inode_end_dummy;
+
+	inode_end_dummy.mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO);
+	inode_end_dummy.magic = ENVFS_32(ENVFS_INODE_END_MAGIC);
 
 	while (size) {
 		struct envfs_inode *inode;
@@ -300,7 +274,7 @@ int envfs_load(const char *filename, const char *dir, unsigned flags)
 		buf += sizeof(struct envfs_inode);
 
 		if (ENVFS_32(inode->magic) != ENVFS_INODE_MAGIC) {
-			printf("envfs: wrong magic on %s\n", filename);
+			printf("envfs: wrong magic\n");
 			ret = -EIO;
 			goto out;
 		}
@@ -324,7 +298,7 @@ int envfs_load(const char *filename, const char *dir, unsigned flags)
 		buf += headerlen_full;
 
 		if (ENVFS_32(inode_end->magic) != ENVFS_INODE_END_MAGIC) {
-			printf("envfs: wrong inode_end_magic on %s\n", filename);
+			printf("envfs: wrong inode_end_magic\n");
 			ret = -EIO;
 			goto out;
 		}
@@ -370,9 +344,86 @@ skip:
 
 	ret = 0;
 out:
+	return ret;
+}
+
+int envfs_load_from_buf(void *buf, int len, const char *dir, unsigned flags)
+{
+	int ret;
+	size_t size;
+	struct envfs_super *super = buf;
+
+	buf = super + 1;
+
+	ret = envfs_check_super(super, &size);
+	if (ret)
+		return ret;
+
+	ret = envfs_check_data(super, buf, size);
+	if (ret)
+		return ret;
+
+	ret = envfs_load_data(buf, size, dir, flags);
+
+	return ret;
+}
+
+/**
+ * Restore the last environment into the current one
+ * @param[in] filename from where to restore
+ * @param[in] dir where to store the last content
+ * @return 0 on success, anything else in case of failure
+ *
+ * Note: This function will also be used on the host! See note in the header
+ * of this file.
+ */
+int envfs_load(const char *filename, const char *dir, unsigned flags)
+{
+	struct envfs_super super;
+	void *buf = NULL;
+	int envfd;
+	int ret = 0;
+	size_t size;
+
+	envfd = open(filename, O_RDONLY);
+	if (envfd < 0) {
+		printf("Open %s %s\n", filename, errno_str());
+		return -1;
+	}
+
+	/* read superblock */
+	ret = read(envfd, &super, sizeof(struct envfs_super));
+	if ( ret < sizeof(struct envfs_super)) {
+		perror("read");
+		ret = -errno;
+		goto out;
+	}
+
+	ret = envfs_check_super(&super, &size);
+	if (ret)
+		goto out;
+
+	buf = xmalloc(size);
+	ret = read(envfd, buf, size);
+	if (ret < size) {
+		perror("read");
+		ret = -errno;
+		goto out;
+	}
+
+	ret = envfs_check_data(&super, buf, size);
+	if (ret)
+		goto out;
+
+	ret = envfs_load_data(buf, size, dir, flags);
+	if (ret)
+		goto out;
+
+	ret = 0;
+out:
 	close(envfd);
-	if (buf_free)
-		free(buf_free);
+	free(buf);
+
 	return ret;
 }
 
diff --git a/include/envfs.h b/include/envfs.h
index 94d1353..b63683c 100644
--- a/include/envfs.h
+++ b/include/envfs.h
@@ -92,6 +92,7 @@ struct envfs_super {
 #define ENV_FLAG_NO_OVERWRITE	(1 << 0)
 int envfs_load(const char *filename, const char *dirname, unsigned flags);
 int envfs_save(const char *filename, const char *dirname);
+int envfs_load_from_buf(void *buf, int len, const char *dir, unsigned flags);
 
 /* defaults to /dev/env0 */
 #ifdef CONFIG_ENV_HANDLING
-- 
1.8.5.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2014-02-20 13:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-20 13:49 [PATCH 1/4] filetype: Add detection for barebox environment Sascha Hauer
2014-02-20 13:49 ` [PATCH 2/4] environment: constify arguments Sascha Hauer
2014-02-20 13:49 ` Sascha Hauer [this message]
2014-02-20 15:16   ` [PATCH 3/4] environment: Add function to load envfs from buffer Alexander Aring
2014-02-22 18:28     ` Sascha Hauer
2014-02-22 19:40       ` Alexander Aring
2014-02-20 13:49 ` [PATCH 4/4] defaultenv: Align defaultenv array Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1392904169-786-3-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox