1 /*
2 	confobj.cc	Configuration Class
3 	Copyright (c) 2000, 2002, 2003, 2004, 2005 Kriang Lerdsuwanakij
4 	email:		lerdsuwa@users.sourceforge.net
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with this program; if not, write to the Free Software
18 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 
21 #include "confobj.h"
22 #include "cstrlib.h"
23 
24 // fnmatch.h that comes with Apache has different function name
25 #define ap_fnmatch fnmatch
26 #include <fnmatch.h>
27 
28 
29 #ifdef	CLIB_HAVE_REGEX
k_regcomp(regex_t * r,const string & s1,int flags)30 int k_regcomp(regex_t *r, const string &s1, int flags)
31 {
32 	string s2;
33 	if (s1.size() && s1[0] == '^')
34 		s2 = s1;
35 	else {
36 		s2 = '^';
37 		s2 += s1;
38 	}
39 	if (s1[s1.size()-1] != '$')
40 		s2 += '$';
41 	return regcomp(r, s2.c_str(), flags);
42 }
43 #endif
44 
45 
KcdConfig()46 KcdConfig::KcdConfig() {
47 	cfgQuietFull = false;		// Equals true for quiet mode (full scan)
48 	cfgQuietSmart = false;		// Equals true for quiet mode (smart scan)
49 	cfgQuietPartial = false;	// Equals true for quiet mode (partial scan)
50 	cfgAutoScan = false;		// Equals true to rescan automatically
51 	cfgSpaceSelect = true;		// Default - space in find mode
52 					// select the highlighted dir
53 	cfgSortTree = true;		// Equals true for sorted dir tree
54 	cfgCaseSensitiveSort = false;	// Equals true for case-sensitive sort
55 	cfgShowListThreshold = 4;	// When match more than the specified
56 					// number, show matched dir as a list
57 	cfgFuzzySize = 10;		// Number of directory kept for
58 					// fuzzy searching
59 	cfgMouseScrollRate = 2;		// Rate of mouse scrolling
60 	cfgGraphicChar = true;		// Enable line-drawing chars, etc.
61 
62 #ifdef KCD_NC_GOOD_SCROLL
63 	cfgScrollBar = true;		// Enable scroll bar
64 #else
65 	cfgScrollBar = false;		// Disable scroll bar
66 #endif
67 
68 	cfgGlobDot = false;
69 	cfgGlobPath = false;
70 
71 	cfgKey = keyBindingDefault;
72 
73 	cfgShowNewDir = showNewDirMulti;
74 
75 	SetAttr(cfgAttrNormal, COLOR_WHITE, DEFAULT_COLOR, A_NORMAL, A_NORMAL);
76 	SetAttr(cfgAttrLink, COLOR_GREEN, DEFAULT_COLOR, A_NORMAL, A_UNDERLINE);
77 	SetAttr(cfgAttrHighlight, COLOR_CYAN, COLOR_BLUE, A_NORMAL, A_REVERSE);
78 	SetAttr(cfgAttrURL, COLOR_BLACK, COLOR_WHITE, A_NORMAL, A_REVERSE);
79 	SetAttr(cfgAttrHeader, COLOR_CYAN, DEFAULT_COLOR, A_NORMAL, A_BOLD);
80 	SetAttr(cfgAttrBold, COLOR_WHITE, DEFAULT_COLOR, A_BOLD, A_BOLD);
81 	SetAttr(cfgAttrItalic, COLOR_YELLOW, DEFAULT_COLOR, A_BOLD, A_BOLD);
82 
83 	SetAttr(cfgAttrScrollArrow, COLOR_YELLOW, COLOR_BLUE, A_BOLD, A_NORMAL);
84 	SetAttr(cfgAttrScrollBlock, COLOR_CYAN, COLOR_BLUE, A_NORMAL, A_REVERSE);
85 	SetAttr(cfgAttrScrollBar, COLOR_BLUE, COLOR_CYAN, A_NORMAL, A_NORMAL);
86 	SetAttr(cfgAttrTitle, COLOR_BLACK, COLOR_CYAN, A_NORMAL, A_REVERSE);
87 	SetAttr(cfgAttrMore, COLOR_RED, DEFAULT_COLOR, A_NORMAL, A_BOLD);
88 
89 	SetAttr(cfgAttrLinkBold, COLOR_WHITE, DEFAULT_COLOR, A_BOLD, A_BOLD | A_UNDERLINE);
90 	SetAttr(cfgAttrLinkItalic, COLOR_YELLOW, DEFAULT_COLOR, A_BOLD, A_BOLD | A_UNDERLINE);
91 	SetAttr(cfgAttrHighlightBold, COLOR_WHITE, COLOR_BLUE, A_BOLD, A_REVERSE);
92 	SetAttr(cfgAttrHighlightItalic, COLOR_YELLOW, COLOR_BLUE, A_BOLD, A_REVERSE);
93 
94 	cfgDefaultBackground = COLOR_BLACK;
95 
96 				// Can throw exception here!
97 	cfgSkipDir = new DirList;
98 	cfgStartDir = new DirList;
99 
100 	cfgDefaultTree = new DirList;
101 
102 	cfgMountDir = new MountDirList;
103 }
104 
KcdConfig(const KcdConfig & c)105 KcdConfig::KcdConfig(const KcdConfig &c)
106 {
107 	cfgSkipDir = 0;
108 	cfgStartDir = 0;
109 	cfgDefaultTree = 0;
110 	cfgMountDir = 0;
111 
112 	*this = c;
113 }
114 
operator =(const KcdConfig & c)115 KcdConfig &KcdConfig::operator=(const KcdConfig &c)
116 {
117 	cfgQuietFull = c.cfgQuietFull;
118 	cfgQuietSmart = c.cfgQuietSmart;
119 	cfgQuietPartial = c.cfgQuietPartial;
120 	cfgAutoScan = c.cfgAutoScan;
121 	cfgSpaceSelect = c.cfgSpaceSelect;
122 	cfgSortTree = c.cfgSortTree;
123 	cfgCaseSensitiveSort = c.cfgCaseSensitiveSort;
124 	cfgShowListThreshold = c.cfgShowListThreshold;
125 	cfgFuzzySize = c.cfgFuzzySize;
126 	cfgMouseScrollRate = c.cfgMouseScrollRate;
127 	cfgGraphicChar = c.cfgGraphicChar;
128 	cfgScrollBar = c.cfgScrollBar;
129 
130 	cfgGlobDot = c.cfgGlobDot;
131 	cfgGlobPath = c.cfgGlobPath;
132 
133 	cfgKey = c.cfgKey;
134 
135 	cfgShowNewDir = c.cfgShowNewDir;
136 
137 	cfgAttrNormal = c.cfgAttrNormal;
138 	cfgAttrLink = c.cfgAttrLink;
139 	cfgAttrHighlight = c.cfgAttrHighlight;
140 	cfgAttrURL = c.cfgAttrURL;
141 	cfgAttrHeader = c.cfgAttrHeader;
142 	cfgAttrBold = c.cfgAttrBold;
143 	cfgAttrItalic = c.cfgAttrItalic;
144 
145 	cfgAttrScrollArrow = c.cfgAttrScrollArrow;
146 	cfgAttrScrollBlock = c.cfgAttrScrollBlock;
147 	cfgAttrScrollBar = c.cfgAttrScrollBar;
148 	cfgAttrTitle = c.cfgAttrTitle;
149 	cfgAttrMore = c.cfgAttrMore;
150 
151 	cfgAttrLinkBold = c.cfgAttrLinkBold;
152 	cfgAttrLinkItalic = c.cfgAttrLinkItalic;
153 	cfgAttrHighlightBold = c.cfgAttrHighlightBold;
154 	cfgAttrHighlightItalic = c.cfgAttrHighlightItalic;
155 
156 	cfgDefaultBackground = c.cfgDefaultBackground;
157 
158 	delete cfgSkipDir;
159 	delete cfgStartDir;
160 	delete cfgDefaultTree;
161 	delete cfgMountDir;
162 
163 				// Can throw exception here!
164 	cfgSkipDir = new DirList;
165 	*cfgSkipDir = *c.cfgSkipDir;
166 	cfgStartDir = new DirList;
167 	*cfgStartDir = *c.cfgStartDir;
168 
169 	cfgDefaultTree = new DirList;
170 	*cfgDefaultTree = *c.cfgDefaultTree;
171 
172 	cfgMountDir = new MountDirList;
173 	*cfgMountDir = *c.cfgMountDir;
174 
175 	return *this;
176 }
177 
~KcdConfig()178 KcdConfig::~KcdConfig()
179 {
180 	delete cfgSkipDir;
181 	cfgSkipDir = 0;
182 	delete cfgStartDir;
183 	cfgStartDir = 0;
184 
185 	delete cfgDefaultTree;
186 	cfgDefaultTree = 0;
187 
188 	delete cfgMountDir;
189 	cfgMountDir = 0;
190 }
191 
ForceQuiet(int forceQuiet)192 void	KcdConfig::ForceQuiet(int forceQuiet)
193 {
194 	kcdConfig.cfgQuietFull = forceQuiet;
195 	kcdConfig.cfgQuietSmart = forceQuiet;
196 	kcdConfig.cfgQuietPartial = forceQuiet;
197 }
198 
199 KcdConfig kcdConfig;
200 KcdConfig defConfig;
201 configMap allConfig;
202 
203 /*************************************************************************
204 	Find string from linked-list helper
205 *************************************************************************/
206 
TemplateFindDirList(const string & str,T * list)207 template <bool regex, class T> bool TemplateFindDirList(const string &str,
208 							T *list)
209 {
210 	for (typename T::iterator iter = list->begin();
211 	     iter != list->end(); ++iter) {
212 
213 		if (regex) {
214 #ifdef	CLIB_HAVE_REGEX
215 			if ((*iter)->regex) {
216 				regmatch_t m;
217 					// regexec returns 0 if strings match
218 				if (! regexec(&((*iter)->regex_buffer), str.c_str(), 1, &m, 0))
219 					return true;
220 			}
221 			else
222 #endif
223 			     {
224 				int flags = 0;
225 				if (! (*iter)->globDot)
226 					flags |= FNM_PERIOD;
227 				if (! (*iter)->globPath)
228 					flags |= FNM_PATHNAME;
229 
230 				if (! k_fnmatch((*iter)->dir, str, flags))
231 					return true;
232 			}
233 		}
234 		else {
235 			if ((*iter)->dir == str)
236 				return true;
237 		}
238 	}
239 	return false;
240 }
241 
242 /*************************************************************************
243 	Find string from linked-list
244 *************************************************************************/
245 
FindSkipDir(const string & str)246 bool	FindSkipDir(const string &str)
247 {
248 	if (str == "/dev" || str == "/proc")
249 		return true;
250 
251 	return TemplateFindDirList<true>(str, kcdConfig.cfgSkipDir);
252 }
253 
FindStartDir(const string & str)254 bool	FindStartDir(const string &str)
255 {
256 	return TemplateFindDirList<false>(str, kcdConfig.cfgStartDir);
257 }
258 
FindMountDir(const string & str)259 bool	FindMountDir(const string &str)
260 {
261 	return TemplateFindDirList<true>(str, kcdConfig.cfgMountDir);
262 }
263 
k_fnmatch(const string & pattern,const string & str)264 int	k_fnmatch(const string &pattern, const string &str)
265 {
266 	int flags = 0;
267 	if (! kcdConfig.cfgGlobDot)
268 		flags |= FNM_PERIOD;
269 	if (! kcdConfig.cfgGlobPath)
270 		flags |= FNM_PATHNAME;
271 
272 	return k_fnmatch(pattern, str, flags);
273 }
274