Check if a configuration file exists before feeding it to the XML parser.
[AXE.git] / src / configuration.cpp
1
2 /**************************************************************************
3 **  (c) Copyright 2002, Andromeda Technology & Automation
4 ***************************************************************************
5 ** MODULE INFORMATION *
6 ***********************
7 **      FILE NAME      : configuration.cpp
8 **      SYSTEM NAME    : AXE - Andromeda X-windows Encapsulation
9 **      VERSION NUMBER : $Revision: 1.4 $
10 **
11 **  DESCRIPTION      :  Implementation of configuration class
12 **
13 **  EXPORTED OBJECTS : 
14 **  LOCAL    OBJECTS : 
15 **  MODULES  USED    :
16 ***************************************************************************
17 **  ADMINISTRATIVE INFORMATION *
18 ********************************
19 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
20 **      CREATION DATE   : Jul 23, 2002
21 **      LAST UPDATE     : Nov 22, 2002
22 **      MODIFICATIONS   : 
23 **************************************************************************/
24
25 /*****************************
26    $Log: configuration.cpp,v $
27    Revision 1.4  2002-11-23 12:48:18  arjen
28    Check if a configuration file exists before feeding it to the XML parser.
29
30    Revision 1.3  2002/11/02 14:35:15  arjen
31    Uses the XML2 library
32    BugFix: segfault when finding a parameters that is not in the user-sepcific
33    config tree.
34
35    Revision 1.2  2002/09/28 06:48:46  arjen
36    Bugfix: In configuration::find_parameter(), check if the parameter node exists
37    before retrieving its contents.
38
39    Revision 1.1  2002/07/25 08:01:26  arjen
40    First checkin, AXE release 0.2
41
42 *****************************/
43
44 static const char *RCSID = "$Id: configuration.cpp,v 1.4 2002-11-23 12:48:18 arjen Exp $";
45
46 #include <fcntl.h>
47 #include <unistd.h>
48 #include "configuration.h"
49
50 /*=========================================================================
51 **  NAME           : configuration::read
52 **  SYNOPSIS       :
53 **  PARAMETERS     :
54 **  RETURN VALUE   : true if any config files were found
55 **
56 **  DESCRIPTION    : 
57 **
58 **  VARS USED      :
59 **  VARS CHANGED   :
60 **  FUNCTIONS USED :
61 **  SEE ALSO       :
62 **  LAST MODIFIED  : Nov 22, 2002
63 **=========================================================================
64 */
65
66 bool configuration::read(const String name)
67 {
68    String     filename;
69
70    app_name   = name;
71
72    //   Try to read the config files.
73  
74    filename = "/etc/" + name + ".conf";
75    //  Check if we can read the file.
76
77    int fd = open(filename, O_RDONLY);
78    if (fd < 0)
79    {
80       filename = "/usr/local/etc/" + name + ".conf";
81       fd = open(filename, O_RDONLY);
82    }
83
84    if (fd > 0)
85    {
86       close(fd);
87       system = xmlParseFile(filename);
88    }
89
90    filename = getenv("HOME");
91    filename += "/.";
92    filename += name + ".conf";
93    fd = open(filename, O_RDONLY);
94    if (fd > 0)
95    {
96       close(fd);
97       user = xmlParseFile(filename);
98    }
99
100    //  Check the root element, which must be the application name
101
102    xmlNodePtr   root;
103
104    if (system != NULL)
105    {
106       root = xmlDocGetRootElement(system);
107       if (app_name != (const char *)root->name)
108       {
109          std::cerr << "Wrong config file.\n";
110          xmlFreeDoc(system);
111          system = NULL;
112       }
113    }
114
115    if (user != NULL)
116    {
117       root = xmlDocGetRootElement(user);
118       if (app_name != (const char *)root->name)
119       {
120          std::cerr << "Wrong config file.\n";
121          xmlFreeDoc(user);
122          user = NULL;
123       }
124    }
125
126    return system != NULL || user != NULL;
127 }
128
129 /*=========================================================================
130 **  NAME           : configuration::xmlFindTag
131 **  SYNOPSIS       :
132 **  PARAMETERS     :
133 **  RETURN VALUE   : Pointer to the XML element or NULL
134 **
135 **  DESCRIPTION    : 
136 **
137 **  VARS USED      :
138 **  VARS CHANGED   :
139 **  FUNCTIONS USED :
140 **  SEE ALSO       :
141 **  LAST MODIFIED  : Jul 24, 2002
142 **=========================================================================
143 */
144
145 xmlNodePtr configuration::xmlFindTag(xmlNodePtr node, const String tag)
146 {
147    xmlNodePtr   element = NULL;
148
149    while (element == NULL && node != NULL)
150    {
151       if (node->type == XML_ELEMENT_NODE && tag == (char *)node->name)
152       {
153          element = node;
154       }
155       node = node->next;
156    }
157
158    return element;
159 }
160
161 /*=========================================================================
162 **  NAME           : configuration::find_parameter
163 **  SYNOPSIS       :
164 **  PARAMETERS     :
165 **  RETURN VALUE   : The content of the parameter or an empty string
166 **
167 **  DESCRIPTION    : 
168 **
169 **  VARS USED      :
170 **  VARS CHANGED   :
171 **  FUNCTIONS USED :
172 **  SEE ALSO       :
173 **  LAST MODIFIED  : Nov 02, 2002
174 **=========================================================================
175 */
176
177 String configuration::find_parameter(const String section, const String parameter)
178 {
179    xmlNodePtr     root_node;
180    xmlNodePtr     section_node;
181    xmlNodePtr     param_node;
182
183    String         param_value("");
184
185    //  First, we try to find the parameter in the system-wide config
186
187    if (system)
188    {
189       root_node    = xmlDocGetRootElement(system);
190       section_node = xmlFindTag(root_node->children, section);
191       if (section_node != NULL)
192       {
193          param_node = xmlFindTag(section_node->children, parameter);
194          if (param_node != NULL)
195          {
196             param_node = param_node->children;
197          }
198          if (param_node != NULL)
199          {
200             param_value = (char *)param_node->content;
201          }
202       }
203    }
204
205    //  If the parameter is also defined in the user config, it will override
206    //  the system-wide value.
207
208    if (user)
209    {
210       root_node    = xmlDocGetRootElement(user);
211       section_node = xmlFindTag(root_node->children, section);
212       if (section_node != NULL)
213       {
214          param_node = xmlFindTag(section_node->children, parameter);
215          if (param_node != NULL)
216          {
217             param_node = param_node->children;
218          }
219          if (param_node != NULL)
220          {
221             param_value = (char *)param_node->content;
222          }
223       }
224    }
225
226    return param_value;
227 }