diff mbox series

raw_handler: create path for a raw file if path doesn't exists

Message ID 1533717827-30126-1-git-send-email-angelo@amarulasolutions.com
State Changes Requested
Headers show
Series raw_handler: create path for a raw file if path doesn't exists | expand

Commit Message

Angelo Compagnucci Aug. 8, 2018, 8:43 a.m. UTC
Actually, when a path for a file is missing, swupdate will throw an
exception cause it can only write to an existing path.

This patch adds a way to explicitly tell to swupdate to create the path
relative to a file before writing it adding the property
create-destination:

properties = {create-destination = "true";}

Signed-off-by: Angelo Compagnucci <angelo@amarulasolutions.com>
---
 handlers/raw_handler.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Stefano Babic Aug. 8, 2018, 9:01 a.m. UTC | #1
Hi Angelo,

On 08/08/2018 10:43, Angelo Compagnucci wrote:
> Actually, when a path for a file is missing, swupdate will throw an
> exception cause it can only write to an existing path.
> 
> This patch adds a way to explicitly tell to swupdate to create the path
> relative to a file before writing it adding the property
> create-destination:
> 
> properties = {create-destination = "true";}
> 
> Signed-off-by: Angelo Compagnucci <angelo@amarulasolutions.com>
> ---
>  handlers/raw_handler.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
> index e57367e..8349419 100644
> --- a/handlers/raw_handler.c
> +++ b/handlers/raw_handler.c
> @@ -11,6 +11,7 @@
>  #include <fcntl.h>
>  #include <stdlib.h>
>  #include <errno.h>
> +#include <libgen.h>
>  
>  #include "swupdate.h"
>  #include "handler.h"
> @@ -66,6 +67,24 @@ static int install_raw_image(struct img_type *img,
>  	return ret;
>  }
>  
> +static int mkpath(char *dir, mode_t mode)
> +{
> +	if (!dir) {
> +		return -EINVAL;
> +	}
> +
> +	if (strlen(dir) == 1 && dir[0] == '/')
> +		return 0;
> +
> +	mkpath(dirname(strdupa(dir)), mode);
> +
> +	if (mkdir(dir, mode) == -1) {
> +		if (errno != EEXIST)
> +			return 1;
> +	}
> +	return 0;
> +}
> +
>  static int install_raw_file(struct img_type *img,
>  	void __attribute__ ((__unused__)) *data)
>  {
> @@ -75,6 +94,7 @@ static int install_raw_file(struct img_type *img,
>  	int use_mount = (strlen(img->device) && strlen(img->filesystem)) ? 1 : 0;
>  	char* DATADST_DIR = alloca(strlen(get_tmpdir())+strlen(DATADST_DIR_SUFFIX)+1);
>  	sprintf(DATADST_DIR, "%s%s", get_tmpdir(), DATADST_DIR_SUFFIX);
> +	char* make_path;
>  
>  	if (strlen(img->path) == 0) {
>  		ERROR("Missing path attribute");
> @@ -103,6 +123,16 @@ static int install_raw_file(struct img_type *img,
>  
>  	TRACE("Installing file %s on %s\n",
>  		img->fname, path);
> +
> +	make_path = dict_get_value(&img->properties, "create-destination");
> +
> +	if (make_path != NULL && strcmp(make_path, "true") == 0) {
> +		TRACE("Creating path %s\n", path);
> +		fdout = mkpath(dirname(strdupa(path)), 0755);
> +		if (fdout < 0)
> +			ERROR("I cannot create path %s: %s\n", path, strerror(errno));


There is an error, but do we continue ? We should stop in case of error.
This is a general rule in SWUpdate.

> +	}
> +
>  	fdout = openfileoutput(path);
>  	ret = copyimage(&fdout, img, NULL);
>  	if (ret< 0) {
> 


The "properties" should be described in the documentation, not only in
the commit message. I see that I have added the related documentation
for swuforward handler, but I forget to do the same with the recent
added ucfw handler - I will fix this myself. Please add documentation
for the rawfile handler (doc/source/handlers.rst).

Best regards,
Stefano Babic
diff mbox series

Patch

diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
index e57367e..8349419 100644
--- a/handlers/raw_handler.c
+++ b/handlers/raw_handler.c
@@ -11,6 +11,7 @@ 
 #include <fcntl.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <libgen.h>
 
 #include "swupdate.h"
 #include "handler.h"
@@ -66,6 +67,24 @@  static int install_raw_image(struct img_type *img,
 	return ret;
 }
 
+static int mkpath(char *dir, mode_t mode)
+{
+	if (!dir) {
+		return -EINVAL;
+	}
+
+	if (strlen(dir) == 1 && dir[0] == '/')
+		return 0;
+
+	mkpath(dirname(strdupa(dir)), mode);
+
+	if (mkdir(dir, mode) == -1) {
+		if (errno != EEXIST)
+			return 1;
+	}
+	return 0;
+}
+
 static int install_raw_file(struct img_type *img,
 	void __attribute__ ((__unused__)) *data)
 {
@@ -75,6 +94,7 @@  static int install_raw_file(struct img_type *img,
 	int use_mount = (strlen(img->device) && strlen(img->filesystem)) ? 1 : 0;
 	char* DATADST_DIR = alloca(strlen(get_tmpdir())+strlen(DATADST_DIR_SUFFIX)+1);
 	sprintf(DATADST_DIR, "%s%s", get_tmpdir(), DATADST_DIR_SUFFIX);
+	char* make_path;
 
 	if (strlen(img->path) == 0) {
 		ERROR("Missing path attribute");
@@ -103,6 +123,16 @@  static int install_raw_file(struct img_type *img,
 
 	TRACE("Installing file %s on %s\n",
 		img->fname, path);
+
+	make_path = dict_get_value(&img->properties, "create-destination");
+
+	if (make_path != NULL && strcmp(make_path, "true") == 0) {
+		TRACE("Creating path %s\n", path);
+		fdout = mkpath(dirname(strdupa(path)), 0755);
+		if (fdout < 0)
+			ERROR("I cannot create path %s: %s\n", path, strerror(errno));
+	}
+
 	fdout = openfileoutput(path);
 	ret = copyimage(&fdout, img, NULL);
 	if (ret< 0) {