1 /*  $Id: ConfigFile.h 1649 2009-10-19 14:35:01Z terpstra $
2  *
3  *  ConfigFile.h - Knows how to load the config file
4  *
5  *  Copyright (C) 2002 - Wesley W. Terpstra
6  *
7  *  License: GPL
8  *
9  *  Authors: 'Wesley W. Terpstra' <wesley@terpstra.ca>
10  *
11  *    This program is free software; you can redistribute it and/or modify
12  *    it under the terms of the GNU General Public License as published by
13  *    the Free Software Foundation; version 2.1.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24 
25 #ifndef CONFIG_H
26 #define CONFIG_H
27 
28 #include <string>
29 #include <map>
30 #include <set>
31 #include <iostream>
32 #include <vector>
33 
34 #if __GNUC__ == 2
35 #include <strstream>
36 #else
37 #include <sstream>
38 #endif
39 
40 // get VERSION
41 #include "../config.h"
42 
43 using std::string;
44 using std::map;
45 using std::set;
46 using std::ostream;
47 using std::vector;
48 
49 // simplify a path by removing trailing '/'s and duplicate '/'s
50 string simplifyPath(string& path);
51 
52 // localized string
53 class lstring
54 {
55  protected:
56  	map<string, string> s;
57  	static map<string, string>* c; // conversion from one spelling to common
58 
59  	static void prep_c();
60 
61  public:
62  	lstring(const string& fb);
lstring()63  	lstring() { }
64 
65  	// If the locale is funky, returns false
66  	bool translate(const string& locale, const string& translation);
67 
68  	string localize(const string& locale) const;
operator()69  	string operator () (const string& locale) const
70  	{ return localize(locale); }
71 
72  	bool is_set() const;
73 
74  	// normalize the language to a common spelling - false if broken
75  	static bool lang_normalize(string& lang);
76  	static bool locale_normalize(string& locale);
77 };
78 
79 struct List
80 {
81 	// filenames and addresses are not localized, nor are identifiers
82 	string mbox;
83 	string address;
84 	string group;
85 	set<string> languages;
86 
87 	bool offline;
88 	bool allowed; // Set to true if the config file enabled this list
89 
90 	// localize these
91 	lstring title;		// could make sense in some cases
92 	lstring description;	// clearly should be translated
93 	lstring link;		// different language on different pages
94 
95  	struct SerializeMagic
96  	{
97  		const List& m;
98  		string l;
SerializeMagicList::SerializeMagic99  		SerializeMagic(const List& m_, const string& l_)
100  		: m(m_), l(l_) { }
101  	};
operatorList102  	SerializeMagic operator () (const string& locale) const
103  	{ return SerializeMagic(*this, locale); }
104 };
105 
106 struct Frontend
107 {
108  	enum Perm { ALLOW, DENY };
109  	enum What { GROUP, LIST };
110 
111  	struct Entry
112 	{
113 		Perm perm;
114 		What what;
115 		string key;
116  	};
117 
118  	vector<Entry>	entries;
119 
120  	lstring		archive;
121  	lstring		admin_name;
122  	string		admin_address;
123  	bool		hide_email;
124  	bool		raw_email;
125  	bool		web_cache;
126 };
127 
128 class Config
129 {
130  private:
131  	List* list;
132  	Frontend* frontend;
133 
134  	string group;
135 #if __GNUC__ == 2
136 	strstream error;
137 #else
138 	std::stringstream error;
139 #endif
140 
141  public:
142  	typedef map<string, List> Lists;
143  	typedef set<string>       Members;
144 
145  	struct GroupData
146  	{
147  		lstring heading;
148  		Members members;
149  	};
150 
151  	typedef map<string, GroupData> Groups;
152  	typedef map<string, Frontend> Frontends;
153 
154  	Lists lists;
155  	Groups groups;
156  	Frontends frontends;
157 
158         string file;  // the name of this config file
159 
160  	// never localize paths, commands, or addresses
161  	string	dbdir;
162  	int	db_umask;
163  	string	xslt;
164  	string  delete_message;
165  	string	pgpv_mime;
166  	string	pgpv_inline;
167  	string	admin_address;
168 
169  	// some names are spelt differently by locales
170 
171  	lstring	archive;
172  	lstring	admin_name;
173 
174  	bool	web_cache;
175  	bool	hide_email;
176  	bool	raw_email;
177  	time_t	modified; // the timestamp of modification for the config file
178 
179  	// parameters specific for rendering
180  	string	docUrl;
181  	string	cgiUrl;
182  	string	command;
183  	mutable string options;
184 
185  	// get the error string
getError()186  	string getError()
187  	{
188 #if __GNUC__ == 2
189 		string out(error.str(), error.rdbuf()->pcount());
190 		return out;
191 #else
192 		return error.str();
193 #endif
194  	}
195 
196  	Config();
197 
198  	// Open the config from this file.
199  	int load(const string& file, bool toplevel = true);
200  	int process_command(const string& file, int c, const string& key, const string& val, const string& dir);
201 
202  	// Set the allowed flag on lists
203  	void set_permissions(const Frontend& f);
204 
205  	struct SerializeMagic
206  	{
207  		const Config& c;
208  		string l;
SerializeMagicSerializeMagic209  		SerializeMagic(const Config& c_, const string& l_)
210  		: c(c_), l(l_) { }
211  	};
operator()212  	SerializeMagic operator () (const string& locale) const
213  	{ return SerializeMagic(*this, locale); }
214 };
215 
216 ostream& operator << (ostream& o, const List::SerializeMagic& lm);
217 ostream& operator << (ostream& o, const Config::SerializeMagic& cm);
218 
219 #endif
220