Preserve original permissions when rewriting config files on commit
authorJo-Philipp Wich <jow@openwrt.org>
Fri, 11 Apr 2014 16:02:51 +0000 (18:02 +0200)
committerJo-Philipp Wich <jow@openwrt.org>
Fri, 11 Apr 2014 16:10:27 +0000 (18:10 +0200)
Patch provided by Patrick Grimm <patrick@lunatiki.de>

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
delta.c
file.c
uci_internal.h
util.c

diff --git a/delta.c b/delta.c
index 73c2728893009fd49cbdffb0be00eecf6f0f76ee..32628dcb719c11a4934f780e72fbfffb15c981e2 100644 (file)
--- a/delta.c
+++ b/delta.c
@@ -240,7 +240,7 @@ static int uci_load_delta_file(struct uci_context *ctx, struct uci_package *p, c
        int changes = 0;
 
        UCI_TRAP_SAVE(ctx, done);
-       stream = uci_open_stream(ctx, filename, SEEK_SET, flush, false);
+       stream = uci_open_stream(ctx, filename, NULL, SEEK_SET, flush, false);
        if (p)
                changes = uci_parse_delta(ctx, stream, p);
        UCI_TRAP_RESTORE(ctx);
@@ -305,7 +305,7 @@ static void uci_filter_delta(struct uci_context *ctx, const char *name, const ch
                UCI_THROW(ctx, UCI_ERR_MEM);
 
        UCI_TRAP_SAVE(ctx, done);
-       f = uci_open_stream(ctx, filename, SEEK_SET, true, false);
+       f = uci_open_stream(ctx, filename, NULL, SEEK_SET, true, false);
        pctx->file = f;
        while (!feof(f)) {
                struct uci_element *e;
@@ -435,7 +435,7 @@ int uci_save(struct uci_context *ctx, struct uci_package *p)
 
        ctx->err = 0;
        UCI_TRAP_SAVE(ctx, done);
-       f = uci_open_stream(ctx, filename, SEEK_END, true, true);
+       f = uci_open_stream(ctx, filename, NULL, SEEK_END, true, true);
        UCI_TRAP_RESTORE(ctx);
 
        uci_foreach_element_safe(&p->delta, tmp, e) {
diff --git a/file.c b/file.c
index 04973f395655361bf9a3adede6e82d254a2a7a4c..a5e242f4908409bd9dfe9c9bbec67deb56bb9ce3 100644 (file)
--- a/file.c
+++ b/file.c
@@ -714,7 +714,7 @@ static void uci_file_commit(struct uci_context *ctx, struct uci_package **packag
                UCI_THROW(ctx, UCI_ERR_IO);
 
        /* open the config file for writing now, so that it is locked */
-       f1 = uci_open_stream(ctx, p->path, SEEK_SET, true, true);
+       f1 = uci_open_stream(ctx, p->path, NULL, SEEK_SET, true, true);
 
        /* flush unsaved changes and reload from delta file */
        UCI_TRAP_SAVE(ctx, done);
@@ -747,7 +747,7 @@ static void uci_file_commit(struct uci_context *ctx, struct uci_package **packag
                        goto done;
        }
 
-       f2 = uci_open_stream(ctx, filename, SEEK_SET, true, true);
+       f2 = uci_open_stream(ctx, filename, p->path, SEEK_SET, true, true);
        uci_export(ctx, f2, p, false);
 
        fflush(f2);
@@ -864,7 +864,7 @@ static struct uci_package *uci_file_load(struct uci_context *ctx, const char *na
        }
 
        UCI_TRAP_SAVE(ctx, done);
-       file = uci_open_stream(ctx, filename, SEEK_SET, false, false);
+       file = uci_open_stream(ctx, filename, NULL, SEEK_SET, false, false);
        ctx->err = 0;
        UCI_INTERNAL(uci_import, ctx, file, name, &package, true);
        UCI_TRAP_RESTORE(ctx);
index 30d79a64fbb7a9a40742f1b7c025826f46b6c1f1..b4e62ffb973714588cfcbbd00c40353873fcf299 100644 (file)
@@ -46,7 +46,7 @@ __private void uci_add_delta(struct uci_context *ctx, struct uci_list *list, int
 __private void uci_free_delta(struct uci_delta *h);
 __private struct uci_package *uci_alloc_package(struct uci_context *ctx, const char *name);
 
-__private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, int pos, bool write, bool create);
+__private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, const char *origfilename, int pos, bool write, bool create);
 __private void uci_close_stream(FILE *stream);
 __private void uci_getln(struct uci_context *ctx, int offset);
 
diff --git a/util.c b/util.c
index 15f311b9f1ea0733707e4d2ec7cb1ca38632f5c2..ce7d849855fe39b5b3b1caf3a683fac4b05e3a7f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -178,7 +178,7 @@ __private void uci_parse_error(struct uci_context *ctx, char *pos, char *reason)
  * note: when opening for write and seeking to the beginning of
  * the stream, truncate the file
  */
-__private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, int pos, bool write, bool create)
+__private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, const char *origfilename, int pos, bool write, bool create)
 {
        struct stat statbuf;
        FILE *file = NULL;
@@ -190,7 +190,11 @@ __private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, i
 
        if (create) {
                flags |= O_CREAT;
-               name = basename((char *) filename);
+               if (origfilename) {
+                       name = basename((char *) origfilename);
+               } else {
+                       name = basename((char *) filename);
+               }
                if ((asprintf(&filename2, "%s/%s", ctx->confdir, name) < 0) || !filename2) {
                        UCI_THROW(ctx, UCI_ERR_MEM);
                } else {