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