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