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