made "hide files" and "veto files" into per-service parameter sections,
[Samba.git] / source / param / params.c
blob0fdde0348ffe64dd4257186beb3e7f7766f4baf5
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Parameter loading utlities
5 Copyright (C) Karl Auer 1993,1994,1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 /**************************************************************************
23 PARAMS.C
25 Copyright (C) 1990, 1991, 1992, 1993, 1994 Karl Auer
27 This module provides for streamlines retrieval of information from a
28 Windows-like parameter files. There is a function which will search for
29 all sections in the file and call a specified function with each. There is
30 a similar function which will call a specified function for all parameters
31 in a section. The idea is that you pass the addresses of suitable functions
32 to a single function in this module which will then enumerate all sections,
33 and within each section all parameters, to your program.
35 Parameter files contain text lines (newline delimited) which consist of
36 either a section name in square brackets or a parameter name, delimited
37 from the parameter value by an equals sign. Blank lines or lines where the
38 first non-whitespace character is a colon are ignored. All whitespace in
39 section names and parameter names is compressed to single spaces. Leading
40 and trailing whitespace on parameter names and parameter values is stripped.
42 Only the first equals sign in a parameter line is significant - parameter
43 values may contain equals signs, square brackets and semicolons. Internal
44 whitespace is retained in parameter values. Parameter names may not start
45 with a square bracket, an equals sign or a semicolon, for obvious reasons.
47 A sample parameter file might look like this:
49 [things]
50 this=1
51 that=2
52 [other things]
53 the other = 3
55 **************************************************************************/
57 #include "includes.h"
59 #include "smb.h"
61 /* local variable pointing to passed filename */
62 static char *pszParmFile = NULL;
63 extern int DEBUGLEVEL;
66 /**************************************************************************
67 Strip all leading whitespace from a string.
68 **************************************************************************/
69 static void trimleft(char *psz)
71 char *pszDest;
73 pszDest = psz;
74 if (psz != NULL)
76 while (*psz != '\0' && isspace(*psz))
77 psz++;
78 while (*psz != '\0')
79 *pszDest++ = *psz++;
80 *pszDest = '\0';
84 /**************************************************************************
85 Strip all trailing whitespace from a string.
86 **************************************************************************/
87 static void trimright(char *psz)
89 char *pszTemp;
91 if (psz != NULL && psz[0] != '\0')
93 pszTemp = psz + strlen(psz) - 1;
94 while (isspace(*pszTemp))
95 *pszTemp-- = '\0';
99 /***********************************************************************
100 Collapse each whitespace area in a string to a single space.
101 ***********************************************************************/
102 static void collapse_spaces(char *psz)
104 while (*psz)
105 if (isspace(*psz))
107 *psz++ = ' ';
108 trimleft(psz);
110 else
111 psz++;
114 /**************************************************************************
115 Return the value of the first non-white character in the specified string.
116 The terminating NUL counts as non-white for the purposes of this function.
117 Note - no check for a NULL string! What would we return?
118 **************************************************************************/
119 static int firstnonwhite(char *psz)
121 while (isspace(*psz) && (*psz != '\0'))
122 psz++;
123 return (*psz);
127 /**************************************************************************
128 Identifies all parameters in the current section, calls the parameter
129 function for each. Ignores comment lines, stops and backs up in file when
130 a section is encountered. Returns True on success, False on error.
131 **************************************************************************/
132 static BOOL enumerate_parameters(FILE *fileIn, BOOL (*pfunc)(char *,char *))
134 pstring szBuf;
135 char *pszTemp;
136 BOOL bRetval;
137 long lFileOffset;
138 int cTemp;
139 BOOL bParmFound;
141 bRetval = False;
142 bParmFound = False;
143 while (True)
145 /* first remember where we are */
146 if ((lFileOffset = ftell(fileIn)) >= 0L)
148 /* then get and check a line */
149 if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL)
151 /* stop - return OK unless file error */
152 bRetval = !ferror(fileIn);
153 if (!bRetval)
154 DEBUG(0,( "Read error on configuration file (enumerating parameters)!\n"));
155 break;
157 else
158 /* if first non-white is a '[', stop (new section) */
159 if ((cTemp = firstnonwhite(szBuf)) == '[')
161 /* restore position to start of new section */
162 if (fseek(fileIn, lFileOffset, SEEK_SET) < 0L)
164 DEBUG(0,( "Seek error on configuration file!\n"));
165 break;
168 /* return success */
169 bRetval = True;
170 break;
172 else
173 /* if it's a semicolon or line is blank, ignore the line */
174 if (!cTemp || strchr(";#",cTemp))
176 continue;
178 else
179 /* if no equals sign and line contains non-whitespace */
180 /* then line is badly formed */
181 if ((pszTemp = strchr(szBuf, '=')) == NULL)
183 DEBUG(0,( "Ignoring badly formed line: %s", szBuf));
185 else
187 /* Note that we have found a parameter */
188 bParmFound = True;
189 /* cut line at the equals sign */
190 *pszTemp++ = '\0';
191 /* trim leading and trailing space from both halves */
192 trimright(szBuf);
193 trimleft(szBuf);
194 trimright(pszTemp);
195 trimleft(pszTemp);
196 /* process the parameter iff passed pointer not NULL */
197 if (pfunc != NULL)
198 if (!pfunc(szBuf, pszTemp))
199 break;
203 return (bRetval);
207 /***********************************************************************
208 Close up s by n chars, at offset start.
209 ***********************************************************************/
210 static void closestr(char *s, int start, int n)
212 char *src;
213 char *dest;
214 int len;
216 if (n > 0)
217 if ((src = dest = s) != NULL)
219 len = strlen(s);
220 if (start >= 0 && start < len - n)
222 src += start + n;
223 dest += start;
225 while (*src)
226 *dest++ = *src++;
227 *dest = '\0';
232 /**************************************************************************
233 Identifies all sections in the parameter file, calls passed section_func()
234 for each, passing the section name, then calls enumerate_parameters().
235 Returns True on success, False on failure. Note that the section and
236 parameter names will have all internal whitespace areas collapsed to a
237 single space for processing.
238 **************************************************************************/
239 static BOOL enumerate_sections(FILE *fileIn,
240 BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *))
242 pstring szBuf;
243 BOOL bRetval;
244 BOOL bSectionFound;
246 /* this makes sure we get include lines right */
247 enumerate_parameters(fileIn, pfunc);
249 bRetval = False;
250 bSectionFound = False;
251 while (True)
253 if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL)
255 /* stop - return OK unless file error */
256 bRetval = !ferror(fileIn);
257 if (!bRetval)
258 DEBUG(0,( "Read error on configuration file (enumerating sections)!\n"));
259 break;
261 else
263 trimleft(szBuf);
264 trimright(szBuf);
265 if (szBuf[0] == '[')
267 closestr(szBuf, 0, 1);
268 if (strlen(szBuf) > 1)
269 if (szBuf[strlen(szBuf) - 1] == ']')
271 /* found a section - note the fact */
272 bSectionFound = True;
273 /* remove trailing metabracket */
274 szBuf[strlen(szBuf) - 1] = '\0';
275 /* remove leading and trailing whitespace from name */
276 trimleft(szBuf);
277 trimright(szBuf);
278 /* reduce all internal whitespace to one space */
279 collapse_spaces(szBuf);
280 /* process it - stop if the processing fails */
281 if (sfunc != NULL)
282 if (!sfunc(szBuf))
283 break;
284 if (!enumerate_parameters(fileIn, pfunc))
285 break;
291 return (bRetval);
294 /**************************************************************************
295 Process the passed parameter file.
297 Returns True if successful, else False.
298 **************************************************************************/
299 BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *))
301 FILE *fileIn;
302 BOOL bRetval;
304 bRetval = False;
306 /* record the filename for use in error messages one day... */
307 pszParmFile = pszFileName;
309 if (pszParmFile == NULL || strlen(pszParmFile) < 1)
310 DEBUG(0,( "No configuration filename specified!\n"));
311 else
312 if ((fileIn = fopen(pszParmFile, "r")) == NULL)
313 DEBUG(0,( "Unable to open configuration file \"%s\"!\n", pszParmFile));
314 else
316 DEBUG(3,("Processing configuration file \"%s\"\n", pszParmFile));
317 bRetval = enumerate_sections(fileIn, sfunc, pfunc);
318 fclose(fileIn);
321 if (!bRetval)
322 DEBUG(0,("pm_process retuned false\n"));
323 return (bRetval);