File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpd / options.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 00:32:35 2013 UTC (10 years, 10 months ago) by misho
Branches: miniupnpd, elwix, MAIN
CVS tags: v1_8p0, v1_8, HEAD
1.8

    1: /* $Id: options.c,v 1.1.1.2 2013/07/22 00:32:35 misho Exp $ */
    2: /* MiniUPnP project
    3:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    4:  * author: Ryan Wagoner
    5:  * (c) 2006-2012 Thomas Bernard
    6:  * This software is subject to the conditions detailed
    7:  * in the LICENCE file provided within the distribution */
    8: 
    9: #include <stdio.h>
   10: #include <string.h>
   11: #include <stdlib.h>
   12: #include <ctype.h>
   13: #include <syslog.h>
   14: #include "config.h"
   15: #include "options.h"
   16: #include "upnppermissions.h"
   17: #include "upnpglobalvars.h"
   18: 
   19: #ifndef DISABLE_CONFIG_FILE
   20: struct option * ary_options = NULL;
   21: static char * string_repo = NULL;
   22: unsigned int num_options = 0;
   23: 
   24: static const struct {
   25: 	enum upnpconfigoptions id;
   26: 	const char * name;
   27: } optionids[] = {
   28: 	{ UPNPEXT_IFNAME, "ext_ifname" },
   29: 	{ UPNPEXT_IP,	"ext_ip" },
   30: 	{ UPNPLISTENING_IP, "listening_ip" },
   31: 	{ UPNPPORT, "port" },
   32: 	{ UPNPBITRATE_UP, "bitrate_up" },
   33: 	{ UPNPBITRATE_DOWN, "bitrate_down" },
   34: 	{ UPNPPRESENTATIONURL, "presentation_url" },
   35: 	{ UPNPFRIENDLY_NAME, "friendly_name" },
   36: 	{ UPNPNOTIFY_INTERVAL, "notify_interval" },
   37: 	{ UPNPSYSTEM_UPTIME, "system_uptime" },
   38: 	{ UPNPPACKET_LOG, "packet_log" },
   39: 	{ UPNPUUID, "uuid"},
   40: 	{ UPNPSERIAL, "serial"},
   41: 	{ UPNPMODEL_NUMBER, "model_number"},
   42: 	{ UPNPCLEANTHRESHOLD, "clean_ruleset_threshold"},
   43: 	{ UPNPCLEANINTERVAL, "clean_ruleset_interval"},
   44: #ifdef USE_NETFILTER
   45: 	{ UPNPFORWARDCHAIN, "upnp_forward_chain"},
   46: 	{ UPNPNATCHAIN, "upnp_nat_chain"},
   47: #endif
   48: #ifdef ENABLE_NATPMP
   49: 	{ UPNPENABLENATPMP, "enable_natpmp"},
   50: #endif
   51: 	{ UPNPENABLE, "enable_upnp"},
   52: #ifdef USE_PF
   53: 	{ UPNPANCHOR, "anchor"},
   54: 	{ UPNPQUEUE, "queue"},
   55: 	{ UPNPTAG, "tag"},
   56: #endif
   57: #ifdef PF_ENABLE_FILTER_RULES
   58: 	{ UPNPQUICKRULES, "quickrules" },
   59: #endif
   60: #ifdef ENABLE_LEASEFILE
   61: 	{ UPNPLEASEFILE, "lease_file"},
   62: #endif
   63: 	{ UPNPMINISSDPDSOCKET, "minissdpdsocket"},
   64: 	{ UPNPSECUREMODE, "secure_mode"}
   65: };
   66: 
   67: int
   68: readoptionsfile(const char * fname)
   69: {
   70: 	FILE *hfile = NULL;
   71: 	char buffer[1024];
   72: 	char *equals;
   73: 	char *name;
   74: 	char *value;
   75: 	char *t;
   76: 	int linenum = 0;
   77: 	unsigned int i;
   78: 	enum upnpconfigoptions id;
   79: 	size_t string_repo_len = 0;
   80: 	size_t len;
   81: 	void *tmp;
   82: 
   83: 	if(!fname || (strlen(fname) == 0))
   84: 		return -1;
   85: 
   86: 	memset(buffer, 0, sizeof(buffer));
   87: 
   88: #ifdef DEBUG
   89: 	printf("Reading configuration from file %s\n", fname);
   90: #endif
   91: 
   92: 	if(!(hfile = fopen(fname, "r")))
   93: 		return -1;
   94: 
   95: 	if(ary_options != NULL)
   96: 	{
   97: 		free(ary_options);
   98: 		num_options = 0;
   99: 	}
  100: 
  101: 	while(fgets(buffer, sizeof(buffer), hfile))
  102: 	{
  103: 		linenum++;
  104: 		t = strchr(buffer, '\n');
  105: 		if(t)
  106: 		{
  107: 			*t = '\0';
  108: 			t--;
  109: 			/* remove spaces at the end of the line */
  110: 			while((t >= buffer) && isspace(*t))
  111: 			{
  112: 				*t = '\0';
  113: 				t--;
  114: 			}
  115: 		}
  116: 
  117: 		/* skip leading whitespaces */
  118: 		name = buffer;
  119: 		while(isspace(*name))
  120: 			name++;
  121: 
  122: 		/* check for comments or empty lines */
  123: 		if(name[0] == '#' || name[0] == '\0') continue;
  124: 
  125: 		/* check for UPnP permissions rule */
  126: 		if(0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4))
  127: 		{
  128: 			tmp = realloc(upnppermlist, sizeof(struct upnpperm) * (num_upnpperm+1));
  129: 			if(tmp == NULL)
  130: 			{
  131: 				fprintf(stderr, "memory allocation error. Permission line in file %s line %d\n",
  132: 				        fname, linenum);
  133: 			}
  134: 			else
  135: 			{
  136: 				upnppermlist = tmp;
  137: 				/* parse the rule */
  138: 				if(read_permission_line(upnppermlist + num_upnpperm, name) >= 0)
  139: 				{
  140: 					num_upnpperm++;
  141: 				}
  142: 				else
  143: 				{
  144: 					fprintf(stderr, "parsing error file %s line %d : %s\n",
  145: 					        fname, linenum, name);
  146: 				}
  147: 			}
  148: 			continue;
  149: 		}
  150: 		if(!(equals = strchr(name, '=')))
  151: 		{
  152: 			fprintf(stderr, "parsing error file %s line %d : %s\n",
  153: 			        fname, linenum, name);
  154: 			continue;
  155: 		}
  156: 
  157: 		/* remove ending whitespaces */
  158: 		for(t=equals-1; t>name && isspace(*t); t--)
  159: 			*t = '\0';
  160: 
  161: 		*equals = '\0';
  162: 		value = equals+1;
  163: 
  164: 		/* skip leading whitespaces */
  165: 		while(isspace(*value))
  166: 			value++;
  167: 
  168: 		id = UPNP_INVALID;
  169: 		for(i=0; i<sizeof(optionids)/sizeof(optionids[0]); i++)
  170: 		{
  171: 			/*printf("%2d %2d %s %s\n", i, optionids[i].id, name,
  172: 			       optionids[i].name); */
  173: 
  174: 			if(0 == strcmp(name, optionids[i].name))
  175: 			{
  176: 				id = optionids[i].id;
  177: 				break;
  178: 			}
  179: 		}
  180: 
  181: 		if(id == UPNP_INVALID)
  182: 		{
  183: 			fprintf(stderr, "invalid option in file %s line %d : %s=%s\n",
  184: 			        fname, linenum, name, value);
  185: 		}
  186: 		else
  187: 		{
  188: 			tmp = realloc(ary_options, (num_options + 1) * sizeof(struct option));
  189: 			if(tmp == NULL)
  190: 			{
  191: 				fprintf(stderr, "memory allocation error. Option in file %s line %d.\n",
  192: 				        fname, linenum);
  193: 			}
  194: 			else
  195: 			{
  196: 				ary_options = tmp;
  197: 				len = strlen(value) + 1;	/* +1 for terminating '\0' */
  198: 				tmp = realloc(string_repo, string_repo_len + len);
  199: 				if(tmp == NULL)
  200: 				{
  201: 					fprintf(stderr, "memory allocation error, Option value in file %s line %d : %s=%s\n",
  202: 					        fname, linenum, name, value);
  203: 				}
  204: 				else
  205: 				{
  206: 					string_repo = tmp;
  207: 					memcpy(string_repo + string_repo_len, value, len);
  208: 					ary_options[num_options].id = id;
  209: 					/* save the offset instead of the absolute address because realloc() could
  210: 					 * change it */
  211: 					ary_options[num_options].value = (const char *)string_repo_len;
  212: 					num_options += 1;
  213: 					string_repo_len += len;
  214: 				}
  215: 			}
  216: 		}
  217: 
  218: 	}
  219: 
  220: 	fclose(hfile);
  221: 
  222: 	for(i = 0; i < num_options; i++)
  223: 	{
  224: 		/* add start address of string_repo to get right pointer */
  225: 		ary_options[i].value = string_repo + (size_t)ary_options[i].value;
  226: 	}
  227: 
  228: 	return 0;
  229: }
  230: 
  231: void
  232: freeoptions(void)
  233: {
  234: 	if(ary_options)
  235: 	{
  236: 		free(ary_options);
  237: 		ary_options = NULL;
  238: 		num_options = 0;
  239: 	}
  240: 	if(string_repo)
  241: 	{
  242: 		free(string_repo);
  243: 		string_repo = NULL;
  244: 	}
  245: 	if(upnppermlist)
  246: 	{
  247: 		free(upnppermlist);
  248: 		upnppermlist = NULL;
  249: 		num_upnpperm = 0;
  250: 	}
  251: }
  252: 
  253: #endif /* DISABLE_CONFIG_FILE */
  254: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>