On 09/28/2009 09:55 AM, Simo Sorce wrote:
> On Mon, 2009-09-28 at 09:38 -0400, Stephen Gallagher wrote:
>> The SSSD needs a config_from_fd() variant of the config_from_file()
>> call
>> so that we can preopen a config file and perform some verification on
>> it
>> before parsing it. The config_from_fd() call is used to avoid race
>> conditions between testing the file and reading it in.
>>
>> Note: the *_from_fd() functions still require the config file name for
>> internal information. This does not imply that it is used to open the
>> file.
> 
> I think it is better not to require a file name, and, internally, just
> use something like "dummy" or a random string like the process pid etc..
> 
> This way there is no risk that someone may accidentally change the code
> later to re-open the file or something like that, if that is done it
> will immediately break when it tries to open "dummy" (hopefully :-)
> 
> Simo.
> 
> _______________________________________________
> sssd-devel mailing list
> sssd-devel@lists.fedorahosted.org
> https://fedorahosted.org/mailman/listinfo/sssd-devel

New version does not require the file name for the _from_fd() functions.
It will create a string "dummy_<fd>" to use for the config file name
internally.



-- 
Stephen Gallagher
RHCE 804006346421761

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
From 97010c97d26556fd752c86fb2f610ac708415bdb Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Mon, 28 Sep 2009 09:36:00 -0400
Subject: [PATCH] Add config_from_fd() to ini_config

---
 common/ini/ini_config.c    |  124 +++++++++++++++++++++++++++++++++++++++++--
 common/ini/ini_config.h    |   17 ++++++
 common/ini/ini_config_ut.c |   71 +++++++++++++++++++++++++
 3 files changed, 206 insertions(+), 6 deletions(-)

diff --git a/common/ini/ini_config.c b/common/ini/ini_config.c
index ffc5960..49a07b2 100644
--- a/common/ini/ini_config.c
+++ b/common/ini/ini_config.c
@@ -27,6 +27,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <locale.h>
+#include <fcntl.h>
 #include "config.h"
 /* For error text */
 #include <libintl.h>
@@ -153,7 +154,8 @@ int read_line(FILE *file,
 /***************************************************************************/
 /* Function to read single ini file and pupulate
  * the provided collection with subcollcetions from the file */
-static int ini_to_collection(const char *filename,
+static int ini_to_collection(int fd,
+                             const char *filename,
                              struct collection_item *ini_config,
                              int error_level,
                              struct collection_item **error_list,
@@ -177,7 +179,7 @@ static int ini_to_collection(const char *filename,
     TRACE_FLOW_STRING("ini_to_collection", "Entry");
 
     /* Open file for reading */
-    file = fopen(filename, "r");
+    file = fdopen(fd, "r");
     if (file == NULL) {
         error = errno;
         TRACE_ERROR_NUMBER("Failed to open file - but this is OK", error);
@@ -423,6 +425,14 @@ void free_ini_config_lines(struct collection_item *lines)
     TRACE_FLOW_STRING("free_ini_config_lines", "Exit");
 }
 
+static int config_with_lines(const char *application,
+                             int fd,
+                             const char *config_file,
+                             struct collection_item **ini_config,
+                             int error_level,
+                             struct collection_item **error_list,
+                             struct collection_item **lines);
+
 /* Read configuration information from a file */
 int config_from_file(const char *application,
                      const char *config_file,
@@ -443,6 +453,26 @@ int config_from_file(const char *application,
     return error;
 }
 
+/* Read configuration information from a file descriptor */
+int config_from_fd(const char *application,
+                   int fd,
+                   struct collection_item **ini_config,
+                   int error_level,
+                   struct collection_item **error_list)
+{
+    int error;
+
+    TRACE_FLOW_STRING("config_from_fd", "Entry");
+    error = config_from_fd_with_lines(application,
+                                      fd,
+                                      ini_config,
+                                      error_level,
+                                      error_list,
+                                      NULL);
+    TRACE_FLOW_NUMBER("config_from_fd. Returns", error);
+    return error;
+}
+
 /* Function to read the ini file and have a collection
  * of which item appers on which line
  */
@@ -453,6 +483,71 @@ int config_from_file_with_lines(const char *application,
                                 struct collection_item **error_list,
                                 struct collection_item **lines)
 {
+    int fd = -1;
+    int error = 0;
+
+    TRACE_FLOW_STRING("config_from_fd", "Entry");
+
+    fd = open(config_file, O_RDONLY);
+    if(fd < 0) {
+        error = errno;
+        TRACE_FLOW_NUMBER("config_from_file_with_lines. Returns", error);
+        return error;
+    }
+    error = config_with_lines(application, fd, config_file,
+                              ini_config, error_level,
+                              error_list, lines);
+    TRACE_FLOW_NUMBER("config_from_file_with_lines. Returns", error);
+    return error;
+}
+
+/* Function to read the ini file and have a collection
+ * of which item appers on which line
+ */
+int config_from_fd_with_lines(const char *application,
+                              int fd,
+                              struct collection_item **ini_config,
+                              int error_level,
+                              struct collection_item **error_list,
+                              struct collection_item **lines)
+{
+    char *filename;
+    int size;
+    int error;
+
+    TRACE_FLOW_STRING("config_from_fd_with_lines", "Entry");
+
+    filename = malloc(sizeof(char) * 13);
+    if(!filename) {
+        TRACE_FLOW_NUMBER("config_from_fd_with_lines. Returns", ENOMEM);
+        return ENOMEM;
+    }
+
+    size = snprintf(filename, 13, "dummy_%d", fd);
+    if ((size < 0) || size >= 13)
+    {
+        free(filename);
+        TRACE_FLOW_NUMBER("config_from_fd_with_lines. Returns", EIO);
+        return EIO;
+    }
+
+    error = config_with_lines(application, fd, filename,
+                              ini_config, error_level,
+                              error_list, lines);
+    TRACE_FLOW_NUMBER("config_from_fd_with_lines. Returns", error);
+
+    free(filename);
+    return error;
+}
+
+static int config_with_lines(const char *application,
+                             int fd,
+                             const char *config_file,
+                             struct collection_item **ini_config,
+                             int error_level,
+                             struct collection_item **error_list,
+                             struct collection_item **lines)
+{
     int error;
     int created = 0;
     int created_lines = 0;
@@ -511,7 +606,7 @@ int config_from_file_with_lines(const char *application,
     }
 
     /* Do the actual work */
-    error = ini_to_collection(config_file, *ini_config,
+    error = ini_to_collection(fd, config_file, *ini_config,
                               error_level, error_list, lines);
     /* In case of error when we created collection - delete it */
     if (error && created) {
@@ -537,6 +632,7 @@ int config_for_app(const char *application,
                    int error_level,
                    struct collection_item **error_set)
 {
+    int fd = -1;
     int error = EOK;
     char *file_name;
     struct collection_item *error_list_common = NULL;
@@ -605,8 +701,18 @@ int config_for_app(const char *application,
     /* Read master file */
     if (config_file != NULL) {
         TRACE_INFO_STRING("Reading master file:", config_file);
-        error = ini_to_collection(config_file, *ini_config,
-                                  error_level, pass_common, NULL);
+        fd = open(config_file, O_RDONLY);
+        if (fd < 0) {
+            error = errno;
+            if(created) {
+                col_destroy_collection(*ini_config);
+                *ini_config = NULL;
+            }
+        }
+        else {
+            error = ini_to_collection(fd, config_file, *ini_config,
+                                      error_level, pass_common, NULL);
+        }
         tried++;
         /* ENOENT and EOK are Ok */
         if (error) {
@@ -665,7 +771,13 @@ int config_for_app(const char *application,
         TRACE_INFO_STRING("Opening file:", file_name);
 
         /* Read master file */
-        error = ini_to_collection(file_name, *ini_config,
+        fd = open(file_name, O_RDONLY);
+        if (fd < 0) {
+            error = errno;
+            TRACE_ERROR_NUMBER("Failed to read specific application file", 
error);
+            return error;
+        }
+        error = ini_to_collection(fd, file_name, *ini_config,
                                   error_level, pass_specific, NULL);
         tried++;
         free(file_name);
diff --git a/common/ini/ini_config.h b/common/ini/ini_config.h
index 1fee48a..7e64214 100644
--- a/common/ini/ini_config.h
+++ b/common/ini/ini_config.h
@@ -103,6 +103,13 @@ int config_from_file(const char *application,              
 /* Name of the appli
                      int error_level,                       /* Error level - 
break for errors, warnings or best effort (don't break) */
                      struct collection_item **error_list);  /* List of errors 
for a file */
 
+/* Read configuration information from a file descriptor */
+int config_from_fd(const char *application,             /* Name of the 
application - will be used as name of the collection */
+                   int fd,                              /* Previously opened 
file descriptor for the config file */
+                   struct collection_item **ini_config, /* If *ini_config is 
NULL a new ini object will be allocated*/
+                   int error_level,                     /* Error level - break 
for errors, warnings or best effort (don't break) */
+                   struct collection_item **error_list); /* List of errors for 
a file */
+
 
 /* Read configuration information from a file with extra collection of line 
numbers */
 int config_from_file_with_lines(
@@ -114,6 +121,16 @@ int config_from_file_with_lines(
                      struct collection_item **error_list,   /* List of errors 
for a file */
                      struct collection_item **lines);       /* Collection of 
pairs where key is the key and value is line number */
 
+/* Read configuration information from a file descriptor with extra collection 
of line numbers */
+int config_from_fd_with_lines(
+                   const char *application,               /* Name of the 
application - will be used as name of the collection */
+                   int fd,                                /* Previously opened 
file descriptor for the config file */
+                   struct collection_item **ini_config,   /* If *ini_config is 
NULL a new ini object will be allocated, */
+                                                          /* otherwise the one 
that is pointed to will be updated. */
+                   int error_level,                       /* Error level - 
break for errors, warnings or best effort (don't break) */
+                   struct collection_item **error_list,   /* List of errors 
for a file */
+                   struct collection_item **lines);       /* Collection of 
pairs where key is the key and value is line number */
+
 
 /* Read default config file and then overwrite it with a specific one from the 
directory */
 int config_for_app(const char *application,               /* Name of the 
application that will be used to get config for */
diff --git a/common/ini/ini_config_ut.c b/common/ini/ini_config_ut.c
index 6fbade6..025ecf1 100644
--- a/common/ini/ini_config_ut.c
+++ b/common/ini/ini_config_ut.c
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
+#include <fcntl.h>
 #define TRACE_HOME
 #include "ini_config.h"
 #include "collection.h"
@@ -133,6 +134,75 @@ int single_file(void)
     return 0;
 }
 
+int single_fd(void)
+{
+    int error;
+    struct collection_item *ini_config = NULL;
+    struct collection_item *error_set = NULL;
+    struct collection_item *lines = NULL;
+
+    int fd = open("./ini.conf", O_RDONLY);
+    if (fd < 0) {
+        error = errno;
+        printf("Attempt to read configuration returned error: %d\n", error);
+        return error;
+    }
+
+    error = config_from_fd("test", fd, &ini_config, INI_STOP_ON_NONE, 
&error_set);
+    if (error) {
+        printf("Attempt to read configuration returned error: %d\n",error);
+        return error;
+    }
+
+    col_debug_collection(ini_config, COL_TRAVERSE_DEFAULT);
+    col_print_collection(ini_config);
+    col_print_collection(error_set);
+
+    printf("\n\n----------------------\n");
+    /* Output parsing errors (if any) */
+    print_file_parsing_errors(stdout, error_set);
+    printf("----------------------\n\n\n");
+
+
+    free_ini_config(ini_config);
+    free_ini_config_errors(error_set);
+    close(fd);
+
+    ini_config = NULL;
+    error_set = NULL;
+
+    printf("TEST WITH LINES\n");
+
+    fd = open("./ini.conf", O_RDONLY);
+    if (fd < 0) {
+        error = errno;
+        printf("Attempt to read configuration returned error: %d\n", error);
+        return error;
+    }
+    error = config_from_fd_with_lines("test", fd, &ini_config,
+                                      INI_STOP_ON_NONE,
+                                      &error_set, &lines);
+    if (error) {
+        printf("Attempt to read configuration returned error: %d\n",error);
+        return error;
+    }
+
+    col_debug_collection(ini_config, COL_TRAVERSE_DEFAULT);
+    col_debug_collection(lines, COL_TRAVERSE_DEFAULT);
+
+    printf("\n\n----------------------\n");
+    /* Output parsing errors (if any) */
+    print_file_parsing_errors(stdout, error_set);
+    printf("----------------------\n\n\n");
+
+
+    free_ini_config(ini_config);
+    free_ini_config_errors(error_set);
+    free_ini_config_lines(lines);
+
+    return 0;
+}
+
 int negative_test(void)
 {
     int error;
@@ -828,6 +898,7 @@ int main(int argc, char *argv[])
 
     if ((error = basic_test()) ||
         (error = single_file()) ||
+        (error = single_fd()) ||
         (error = real_test(NULL)) ||
          /* This should result in merged configuration */
         (error = real_test("./ini.conf")) ||
-- 
1.6.2.5

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to