blob: add uci<->blob conversion library code
[project/uci.git] / util.c
diff --git a/util.c b/util.c
index 1db3366..812a3a3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -9,7 +9,7 @@
  * 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.
+ * GNU Lesser General Public License for more details.
  */
 
 /*
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <libgen.h>
 
 #include "uci.h"
 #include "uci_internal.h"
 
-__plugin void *uci_malloc(struct uci_context *ctx, size_t size)
+__private void *uci_malloc(struct uci_context *ctx, size_t size)
 {
        void *ptr;
 
@@ -43,7 +44,7 @@ __plugin void *uci_malloc(struct uci_context *ctx, size_t size)
        return ptr;
 }
 
-__plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
+__private void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
 {
        ptr = realloc(ptr, size);
        if (!ptr)
@@ -52,7 +53,7 @@ __plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
        return ptr;
 }
 
-__plugin char *uci_strdup(struct uci_context *ctx, const char *str)
+__private char *uci_strdup(struct uci_context *ctx, const char *str)
 {
        char *ptr;
 
@@ -68,7 +69,7 @@ __plugin char *uci_strdup(struct uci_context *ctx, const char *str)
  * for names, only alphanum and _ is allowed (shell compatibility)
  * for types, we allow more characters
  */
-__plugin bool uci_validate_str(const char *str, bool name)
+__private bool uci_validate_str(const char *str, bool name)
 {
        if (!*str)
                return false;
@@ -182,17 +183,30 @@ __private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, i
        struct stat statbuf;
        FILE *file = NULL;
        int fd, ret;
-       int mode = (write ? O_RDWR : O_RDONLY);
-
-       if (create)
-               mode |= O_CREAT;
+       int flags = (write ? O_RDWR : O_RDONLY);
+       mode_t mode = UCI_FILEMODE;
+       char *name = NULL;
+       char *filename2 = NULL;
+
+       if (create) {
+               flags |= O_CREAT;
+               name = basename((char *) filename);
+               if ((asprintf(&filename2, "%s/%s", ctx->confdir, name) < 0) || !filename2) {
+                       UCI_THROW(ctx, UCI_ERR_MEM);
+               } else {
+                       if (stat(filename2,&statbuf) == 0)
+                               mode = statbuf.st_mode;
+
+                       free(filename2);
+               }
+       }
 
        if (!write && ((stat(filename, &statbuf) < 0) ||
                ((statbuf.st_mode &  S_IFMT) != S_IFREG))) {
                UCI_THROW(ctx, UCI_ERR_NOTFOUND);
        }
 
-       fd = open(filename, mode, UCI_FILEMODE);
+       fd = open(filename, flags, mode);
        if (fd < 0)
                goto error;