"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "bogom-1.9.2/conf.c" of archive bogom-1.9.2.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* $Id: conf.c,v 1.11 2007/10/01 20:50:41 reidrac Exp reidrac $ */
    2 
    3 /*
    4 * conf.c, configuration reader and parser
    5 * Copyright (C) 2004-2007 Juan J. Martinez <jjm*at*usebox*dot*net>
    6 *
    7 * This program is free software; you can redistribute it and/or modify
    8 * it under the terms of the GNU General Public License Version 2 as
    9 * published by the Free Software Foundation.
   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 
   22 #include<stdio.h>
   23 #include<stdlib.h>
   24 #include<string.h>
   25 #include<errno.h>
   26 #include<ctype.h>
   27 
   28 #include "libmilter/mfapi.h"
   29 #include "conf.h"
   30 
   31 #define new_string_list(x) do {\
   32 		x=(struct string_list *) \
   33 			malloc(sizeof(struct string_list));\
   34 		x->n=NULL;\
   35 	} while(0)
   36 
   37 static char * pstrncpy(char *, const char *, size_t);
   38 static int parse_string(char *p);
   39 static int parse_qstring(char *p);
   40 static int parse_bool(char *p);
   41 static char * parse_conf(struct conftoken *conf, char *p);
   42 
   43 static const char rcsid[]="$Id: conf.c,v 1.11 2007/10/01 20:50:41 reidrac Exp reidrac $";
   44 
   45 /*
   46 * strncpy alike function that parses scaped quotes
   47 */
   48 static char *
   49 pstrncpy(char *d, const char *s, size_t l)
   50 {
   51 	size_t i, j;
   52 
   53 	for(i=0, j=0; i<l && s[i]; i++, j++)
   54 	{
   55 		if(s[i]=='\\' && i+1<l)
   56 			if(s[i+1]=='\'' || s[i+1]=='\"')
   57 				i++;
   58 		d[j]=s[i];
   59 	}
   60 
   61 	d[j]=0;
   62 
   63 	return d;
   64 }
   65 
   66 /*
   67 * parses a string and returns its length
   68 */
   69 static int
   70 parse_string(char *p)
   71 {
   72 	char *t;
   73 
   74 	for(t=p; *t && !isspace(*t); t++);
   75 
   76 	return (int)(t-p);
   77 }
   78 
   79 /*
   80 * parses a quoted string and returns its length
   81 * on error:
   82 *	-1	close quote expected
   83 *	0	empty quotes
   84 */
   85 static int
   86 parse_qstring(char *p)
   87 {
   88 	char *t;
   89 	char q=*p;
   90 
   91 	for(t=++p; *t; t++)
   92 	{
   93 		if(*t==q)
   94 			break;
   95 
   96 		if(*t=='\\' && t[1]==q)
   97 			t++;
   98 	}
   99 
  100 	if(*t!=q)
  101 		return -1;
  102 
  103 	if(t==p)
  104 		return 0;
  105 
  106 	return (int)(t-p);
  107 }
  108 
  109 /*
  110 * parses a bool and returns 0/1
  111 * all values ne 0 are true
  112 */
  113 static int
  114 parse_bool(char *p)
  115 {
  116 	if(!p[0] || !isspace(p[1]))
  117 		return -1;
  118 
  119 	if(*p=='0')
  120 		return 0;
  121 	else
  122 		return 1;
  123 }
  124 
  125 /*
  126 * parses one line each call
  127 */
  128 static char *
  129 parse_conf(struct conftoken *conf, char *p)
  130 {
  131 	int i, len;
  132 	struct string_list *t;
  133 
  134 	if(!p)
  135 		return NULL;
  136 
  137 	if(!p[0] || p[0]=='\n' || p[0]=='#')
  138 		return NULL;
  139 
  140 	while(isspace(*p))
  141 		p++;
  142 
  143 	len=parse_string(p);
  144 	if(!len)
  145 		return NULL;
  146 
  147 	for(i=0; conf[i].word; i++)
  148 		if(!strncmp(conf[i].word, p, strlen(conf[i].word)))
  149 		{
  150 			p+=len;
  151 			while(isspace(*p))
  152 				p++;
  153 
  154 			switch(conf[i].required)
  155 			{
  156 				case REQ_NONE:
  157 					/* nothing required */
  158 					break;
  159 
  160 				case REQ_BOOL:
  161 					len=parse_bool(p);
  162 					if(len<0)
  163 					{
  164 						fprintf(stderr,
  165 							"bool expected\n");
  166 						return p;
  167 					}
  168 
  169 					conf[i].bool=len;
  170 					p++;
  171 					break;
  172 
  173 				case REQ_STRING:
  174 					len=parse_string(p);
  175 					if(!len)
  176 					{
  177 						fprintf(stderr,
  178 							"string expected\n");
  179 						return p;
  180 					}
  181 
  182 					if(conf[i].str)
  183 						free(conf[i].str);
  184 					conf[i].str=(char *)malloc(len+1);
  185 					if(!conf[i].str)
  186 					{
  187 						fprintf(stderr, "malloc\n");
  188 						return p;
  189 					}
  190 					strncpy(conf[i].str, p, len);
  191 					p+=len;
  192 					break;
  193 
  194 				case REQ_QSTRING:
  195 					if(*p!='\"' && *p!='\'')
  196 					{
  197 						fprintf(stderr,
  198 							"quoted string"
  199 							" expected\n");
  200 						return p;
  201 					}
  202 
  203 					len=parse_qstring(p);
  204 					p++;
  205 
  206 					if(len==-1)
  207 					{
  208 						fprintf(stderr,
  209 							"end quote expected\n");
  210 						return p;
  211 					}
  212 
  213 					if(!len)
  214 					{
  215 						fprintf(stderr,
  216 							"empty quotes\n");
  217 						return p;
  218 					}
  219 
  220 					if(conf[i].str)
  221 						free(conf[i].str);
  222 					conf[i].str=(char *)malloc(len+1);
  223 					if(!conf[i].str)
  224 					{
  225 						fprintf(stderr, "malloc\n");
  226 						return p;
  227 					}
  228 					pstrncpy(conf[i].str, p, len);
  229 					p+=len+1;
  230 					break;
  231 
  232 				case REQ_LSTQSTRING:
  233 					if(*p!='\"' && *p!='\'')
  234 					{
  235 						fprintf(stderr,
  236 							"quoted string"
  237 							" expected\n");
  238 						return p;
  239 					}
  240 
  241 					len=parse_qstring(p);
  242 					p++;
  243 
  244 					if(len==-1)
  245 					{
  246 						fprintf(stderr,
  247 							"end quote expected\n");
  248 						return p;
  249 					}
  250 
  251 					if(!len)
  252 					{
  253 						fprintf(stderr,
  254 							"empty quotes\n");
  255 						return p;
  256 					}
  257 
  258 					if(!conf[i].sl)
  259 					{
  260 						new_string_list(conf[i].sl);
  261 						if(!conf[i].sl)
  262 						{
  263 							fprintf(stderr,
  264 								"malloc");
  265 							return p;
  266 						}
  267 					}
  268 					else
  269 					{
  270 						new_string_list(t);
  271 						if(!t)
  272 						{
  273 							fprintf(stderr,
  274 								"malloc");
  275 							return p;
  276 						}
  277 						t->n=conf[i].sl;
  278 						conf[i].sl=t;
  279 					}
  280 
  281 					conf[i].sl->s=(char *)malloc(len+1);
  282 					if(!conf[i].sl->s)
  283 					{
  284 						fprintf(stderr, "malloc\n");
  285 						return p;
  286 					}
  287 					pstrncpy(conf[i].sl->s, p, len);
  288 					p+=len+1;
  289 					break;
  290 			}
  291 			break;
  292 		}
  293 
  294 	if(conf[i].word)
  295 	{
  296 		while(isspace(*p))
  297 			p++;
  298 
  299 		if(!p[0])
  300 			return NULL;
  301 
  302 		fprintf(stderr, "parse error\n");
  303 		return p;
  304 	}
  305 
  306 	fprintf(stderr, "unknown token\n");
  307 
  308 	p[len]=0;
  309 	return p;
  310 }
  311 
  312 /*
  313 * reads and parses the configuration file
  314 */
  315 int
  316 read_conf(const char *filename, struct conftoken *conf)
  317 {
  318 	FILE *fd;
  319 	char buffer[1024];
  320 	char *ret;
  321 	int line, i;
  322 
  323 	fd=fopen(filename, "r");
  324 	if(!fd)
  325 		return 0;
  326 
  327 	line=1;
  328 	while(!feof(fd))
  329 	{
  330 		i=0;
  331 		*buffer=0;
  332 		do
  333 		{
  334 			if(i>1023)
  335 			{
  336 				fclose(fd);
  337 				fprintf(stderr, "conf line %i is too long\n",
  338 					 line);
  339 				return 1;
  340 			}
  341 
  342 			fscanf(fd, "%c", &buffer[i]);
  343 
  344 		} while(buffer[i++]!='\n' && !feof(fd));
  345 
  346 		buffer[i]=0;
  347 
  348 		ret=parse_conf(conf, buffer);
  349 		if(ret)
  350 		{
  351 			fclose(fd);
  352 			fprintf(stderr, "conf error at line %i, near: %s\n",
  353 				line, ret);
  354 			return 1;
  355 		}
  356 
  357 		line++;
  358 	}
  359 
  360 	fclose(fd);
  361 
  362 	return 0;
  363 }
  364 
  365 /* EOF */