New functions yaz_file_glob2, yaz_xml_include_glob
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 8 Jul 2013 12:09:24 +0000 (14:09 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 8 Jul 2013 12:09:24 +0000 (14:09 +0200)
These functions takes a flags parameter, which, for now only controls
whether to fail inclusion of a non-existing file (without glob
pattern) - flags YAZ_FILE_GLOB_FAIL_NOTEXIST.

include/yaz/file_glob.h
include/yaz/xml_include.h
src/file_glob.c
src/xml_include.c
test/test_xml_include.c

index 0cb87c2..36ea177 100644 (file)
@@ -40,6 +40,7 @@ YAZ_BEGIN_CDECL
 /** \brief file glob handle */
 typedef struct glob_res *yaz_glob_res_t;
 
+#define YAZ_FILE_GLOB_FAIL_NOTEXIST 1
 
 /** \brief perform glob
     \param pattern glob pattern file spec
@@ -50,6 +51,16 @@ typedef struct glob_res *yaz_glob_res_t;
 YAZ_EXPORT
 int yaz_file_glob(const char *pattern, yaz_glob_res_t *res);
 
+/** \brief perform glob (with flags)
+    \param pattern glob pattern file spec
+    \param res returned glob result
+    \param flags YAZ_FILE_GLOB_.. flags
+    \retval 0 OK
+    \retval -1 ERROR
+*/
+YAZ_EXPORT
+int yaz_file_glob2(const char *pattern, yaz_glob_res_t *res, unsigned flags);
+
 /** \brief release glob result
     \param res pointer to glob result
 
index ca4732c..c0f689d 100644 (file)
 
 #include <yaz/yconfig.h>
 #include <yaz/xmltypes.h>
+#include <yaz/file_glob.h>
 
 YAZ_BEGIN_CDECL
 
 #if YAZ_HAVE_XML2
 
 /** \brief substitute include nodes in a tree
-    \param n node where include is peformed
+    \param n node where include is performed
     \param base_path base_path - for relative file specs
     \retval 0 OK
     \retval -1 FAILURE
@@ -53,6 +54,21 @@ YAZ_BEGIN_CDECL
 YAZ_EXPORT
 int yaz_xml_include_simple(xmlNode *n, const char *base_path);
 
+/** \brief substitute include nodes in a tree
+    \param n node where include is performed
+    \param base_path base_path - for relative file specs
+    \param flags for yaz_file_glob2 (YAZ_FILE_GLOB_...)
+    \retval 0 OK
+    \retval -1 FAILURE
+
+    Nodes of the form <include src="glob-pattern"/> are substituted with
+    contents of files matching glob-pattern. Do not use this function
+    on XML from untrusted sources -- from the net for example -- local
+    trusted XML configuration ONLY.
+*/
+YAZ_EXPORT
+int yaz_xml_include_glob(xmlNode *n, const char *base_path, unsigned flags);
+
 #endif
 YAZ_END_CDECL
 
index 3a5def2..8f199ec 100644 (file)
@@ -31,6 +31,7 @@ struct res_entry {
 
 struct glob_res {
     NMEM nmem;
+    unsigned flags;
     size_t number_of_entries;
     struct res_entry **last_entry;
     struct res_entry *entries;
@@ -68,7 +69,8 @@ static void glob_r(yaz_glob_res_t res, const char *pattern, size_t off,
         glob_r(res, pattern, i, prefix);
         prefix[prefix_len] = '\0';
     }
-    else if (!is_pattern && !pattern[i])
+    else if ((res->flags & YAZ_FILE_GLOB_FAIL_NOTEXIST) &&
+             !is_pattern && !pattern[i])
     {
         strcpy(prefix + prefix_len, pattern + off);
         add_entry(res, prefix);
@@ -138,11 +140,17 @@ static void sort_them(yaz_glob_res_t res)
 
 int yaz_file_glob(const char *pattern, yaz_glob_res_t *res)
 {
+    return yaz_file_glob2(pattern, res, 0);
+}
+
+int yaz_file_glob2(const char *pattern, yaz_glob_res_t *res, unsigned flags)
+{
     char prefix[FILENAME_MAX+1];
     NMEM nmem = nmem_create();
 
     *prefix = '\0';
     *res = nmem_malloc(nmem, sizeof(**res));
+    (*res)->flags = flags;
     (*res)->number_of_entries = 0;
     (*res)->nmem = nmem;
     (*res)->entries = 0;
index 00357a8..61a63f9 100644 (file)
@@ -10,8 +10,6 @@
 #include <config.h>
 #endif
 
-#include <yaz/file_glob.h>
-
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdio.h>
@@ -29,6 +27,7 @@
 
 struct yaz_xml_include_s {
     const char *confdir;
+    unsigned glob_flags;
 };
 
 typedef struct yaz_xml_include_s *yaz_xml_include_t;
@@ -101,7 +100,7 @@ static int config_include_src(yaz_xml_include_t config, xmlNode **np,
         int glob_ret;
         yaz_glob_res_t glob_res;
 
-        glob_ret = yaz_file_glob(wrbuf_cstr(w), &glob_res);
+        glob_ret = yaz_file_glob2(wrbuf_cstr(w), &glob_res, config->glob_flags);
         yaz_log(YLOG_LOG, "yaz_file_glob returned w=%s %d", wrbuf_cstr(w),
                 glob_ret);
         if (glob_ret == 0)
@@ -152,14 +151,22 @@ static int process_config_includes(yaz_xml_include_t config, xmlNode *n)
     return 0;
 }
 
-int yaz_xml_include_simple(xmlNode *n, const char *base_path)
+int yaz_xml_include_glob(xmlNode *n, const char *base_path,
+                         unsigned glob_flags)
 {
     struct yaz_xml_include_s s;
 
     s.confdir = base_path;
+    s.glob_flags = glob_flags;
     return process_config_includes(&s, n);
 }
 
+int yaz_xml_include_simple(xmlNode *n, const char *base_path)
+{
+    return yaz_xml_include_glob(n, base_path, 0);
+}
+
+
 /* YAZ_HAVE_XML2 */
 #endif
 
index 7d45f45..30ac2b3 100644 (file)
@@ -82,15 +82,15 @@ static void tst_xml_include2(void)
     YAZ_CHECK(node);
     if (node)
     {
-        const char *expect =
-            "<?xml version=\"1.0\"?>\n"
-            "<x><!-- begin include src=\"test_xml_no.xml\" -->"
-            "<!-- end include src=\"test_xml_no.xml\" --></x>\n";
-
-        xmlChar *xml_out;
-        int len_out;
-        int ret = yaz_xml_include_simple(node, srcdir);
-        YAZ_CHECK(ret == -1);
+        int ret = yaz_xml_include_glob(node, srcdir,
+                                       YAZ_FILE_GLOB_FAIL_NOTEXIST);
+        YAZ_CHECK_EQ(ret, -1);
+    }
+    if (node)
+    {
+        int ret = yaz_xml_include_glob(node, srcdir,
+                                       0);
+        YAZ_CHECK_EQ(ret, 0);
     }
     xmlFreeDoc(doc);
 #endif