]> source.dussan.org Git - rspamd.git/commitdiff
Sync from libucl.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 31 Jan 2014 13:26:23 +0000 (13:26 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 1 Feb 2014 15:43:09 +0000 (07:43 -0800)
src/ucl/src/ucl_internal.h
src/ucl/src/ucl_parser.c
src/ucl/src/ucl_util.c

index a68403c53a1f3865a1485fee5b39c2de5f6d7c1e..17d5585a20d84af1ea6e44c126099cab38a13f8b 100644 (file)
@@ -159,6 +159,8 @@ size_t ucl_unescape_json_string (char *str, size_t len);
  */
 bool ucl_include_handler (const unsigned char *data, size_t len, void* ud);
 
+bool ucl_try_include_handler (const unsigned char *data, size_t len, void* ud);
+
 /**
  * Handle includes macro
  * @param data include data
index 0441a121c355c3b3ece477d8548a46759e69edc9..895d7be8dcd8a91973c41212a6c918fd2cee9505 100644 (file)
@@ -1724,6 +1724,7 @@ ucl_parser_new (int flags)
        memset (new, 0, sizeof (struct ucl_parser));
 
        ucl_parser_register_macro (new, "include", ucl_include_handler, new);
+       ucl_parser_register_macro (new, "try_include", ucl_try_include_handler, new);
        ucl_parser_register_macro (new, "includes", ucl_includes_handler, new);
 
        new->flags = flags;
index 817d02ac3ba315de3a911a9f6db1bc646fc0afe5..3344fcfc4318eae217db29591adaabd3bfb987c4 100644 (file)
@@ -340,7 +340,8 @@ ucl_curl_write_callback (void* contents, size_t size, size_t nmemb, void* ud)
  * @return
  */
 static bool
-ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen, UT_string **err)
+ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen,
+               UT_string **err, bool must_exist)
 {
 
 #ifdef HAVE_FETCH_H
@@ -355,8 +356,10 @@ ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen, UT
                return false;
        }
        if ((in = fetchXGet (fetch_url, &us, "")) == NULL) {
-               ucl_create_err (err, "cannot fetch URL %s: %s",
+               if (!must_exist) {
+                       ucl_create_err (err, "cannot fetch URL %s: %s",
                                url, strerror (errno));
+               }
                fetchFreeURL (fetch_url);
                return false;
        }
@@ -403,8 +406,10 @@ ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen, UT
        curl_easy_setopt (curl, CURLOPT_WRITEDATA, &cbdata);
 
        if ((r = curl_easy_perform (curl)) != CURLE_OK) {
-               ucl_create_err (err, "error fetching URL %s: %s",
+               if (!must_exist) {
+                       ucl_create_err (err, "error fetching URL %s: %s",
                                url, curl_easy_strerror (r));
+               }
                curl_easy_cleanup (curl);
                if (cbdata.buf) {
                        free (cbdata.buf);
@@ -430,14 +435,17 @@ ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen, UT
  * @return
  */
 static bool
-ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *buflen, UT_string **err)
+ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *buflen,
+               UT_string **err, bool must_exist)
 {
        int fd;
        struct stat st;
 
        if (stat (filename, &st) == -1 || !S_ISREG (st.st_mode)) {
-               ucl_create_err (err, "cannot stat file %s: %s",
-                               filename, strerror (errno));
+               if (must_exist) {
+                       ucl_create_err (err, "cannot stat file %s: %s",
+                                       filename, strerror (errno));
+               }
                return false;
        }
        if (st.st_size == 0) {
@@ -523,7 +531,7 @@ ucl_sig_check (const unsigned char *data, size_t datalen,
  */
 static bool
 ucl_include_url (const unsigned char *data, size_t len,
-               struct ucl_parser *parser, bool check_signature)
+               struct ucl_parser *parser, bool check_signature, bool must_exist)
 {
 
        bool res;
@@ -535,8 +543,8 @@ ucl_include_url (const unsigned char *data, size_t len,
 
        snprintf (urlbuf, sizeof (urlbuf), "%.*s", (int)len, data);
 
-       if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err)) {
-               return false;
+       if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err, must_exist)) {
+               return (!must_exist || false);
        }
 
        if (check_signature) {
@@ -545,7 +553,7 @@ ucl_include_url (const unsigned char *data, size_t len,
                size_t siglen = 0;
                /* We need to check signature first */
                snprintf (urlbuf, sizeof (urlbuf), "%.*s.sig", (int)len, data);
-               if (!ucl_fetch_file (urlbuf, &sigbuf, &siglen, &parser->err)) {
+               if (!ucl_fetch_url (urlbuf, &sigbuf, &siglen, &parser->err, true)) {
                        return false;
                }
                if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) {
@@ -592,7 +600,7 @@ ucl_include_url (const unsigned char *data, size_t len,
  */
 static bool
 ucl_include_file (const unsigned char *data, size_t len,
-               struct ucl_parser *parser, bool check_signature)
+               struct ucl_parser *parser, bool check_signature, bool must_exist)
 {
        bool res;
        struct ucl_chunk *chunk;
@@ -603,14 +611,17 @@ ucl_include_file (const unsigned char *data, size_t len,
 
        snprintf (filebuf, sizeof (filebuf), "%.*s", (int)len, data);
        if (realpath (filebuf, realbuf) == NULL) {
+               if (!must_exist) {
+                       return true;
+               }
                ucl_create_err (&parser->err, "cannot open file %s: %s",
                                                                        filebuf,
                                                                        strerror (errno));
                return false;
        }
 
-       if (!ucl_fetch_file (realbuf, &buf, &buflen, &parser->err)) {
-               return false;
+       if (!ucl_fetch_file (realbuf, &buf, &buflen, &parser->err, must_exist)) {
+               return (!must_exist || false);
        }
 
        if (check_signature) {
@@ -619,7 +630,7 @@ ucl_include_file (const unsigned char *data, size_t len,
                size_t siglen = 0;
                /* We need to check signature first */
                snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf);
-               if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err)) {
+               if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) {
                        return false;
                }
                if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) {
@@ -676,10 +687,10 @@ ucl_include_handler (const unsigned char *data, size_t len, void* ud)
 
        if (*data == '/' || *data == '.') {
                /* Try to load a file */
-               return ucl_include_file (data, len, parser, false);
+               return ucl_include_file (data, len, parser, false, true);
        }
 
-       return ucl_include_url (data, len, parser, false);
+       return ucl_include_url (data, len, parser, false, true);
 }
 
 /**
@@ -697,10 +708,24 @@ ucl_includes_handler (const unsigned char *data, size_t len, void* ud)
 
        if (*data == '/' || *data == '.') {
                /* Try to load a file */
-               return ucl_include_file (data, len, parser, true);
+               return ucl_include_file (data, len, parser, true, true);
+       }
+
+       return ucl_include_url (data, len, parser, true, true);
+}
+
+
+bool
+ucl_try_include_handler (const unsigned char *data, size_t len, void* ud)
+{
+       struct ucl_parser *parser = ud;
+
+       if (*data == '/' || *data == '.') {
+               /* Try to load a file */
+               return ucl_include_file (data, len, parser, false, false);
        }
 
-       return ucl_include_url (data, len, parser, true);
+       return ucl_include_url (data, len, parser, false, false);
 }
 
 bool
@@ -748,7 +773,7 @@ ucl_parser_add_file (struct ucl_parser *parser, const char *filename)
                return false;
        }
 
-       if (!ucl_fetch_file (realbuf, &buf, &len, &parser->err)) {
+       if (!ucl_fetch_file (realbuf, &buf, &len, &parser->err, true)) {
                return false;
        }