1/*
2 * configfile.c
3 *
4 * Methods for accessing the PPTPD config file and searching for
5 * PPTPD keywords.
6 *
7 * $Id: configfile.c,v 1.2 2004/04/22 10:48:16 quozl Exp $
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include <stdio.h>
15#include <string.h>
16#include <ctype.h>
17
18#include "defaults.h"
19#include "configfile.h"
20#include "our_syslog.h"
21
22/* Local function prototypes */
23static FILE *open_config_file(char *filename);
24static void close_config_file(FILE * file);
25
26/*
27 * read_config_file
28 *
29 * This method opens up the file specified by 'filename' and searches
30 * through the file for 'keyword'. If 'keyword' is found any string
31 * following it is stored in 'value'.
32 *
33 * args: filename (IN) - config filename
34 *       keyword (IN) - word to search for in config file
35 *       value (OUT) - value of keyword
36 *
37 * retn: -1 on error, 0 if keyword not found, 1 on value success
38 */
39int read_config_file(char *filename, char *keyword, char *value)
40{
41	FILE *in;
42	int len = 0, keyword_len = 0;
43	int foundit = 0;
44
45	char *buff_ptr;
46	char buffer[MAX_CONFIG_STRING_SIZE];
47
48	*value = '\0';
49	buff_ptr = buffer;
50	keyword_len = strlen(keyword);
51
52	in = open_config_file(filename);
53	if (in == NULL) {
54		/* Couldn't find config file, or permission denied */
55		return -1;
56	}
57	while ((fgets(buffer, MAX_CONFIG_STRING_SIZE - 1, in)) != NULL) {
58		/* ignore long lines */
59		if (buffer[(len = strlen(buffer)) - 1] != '\n') {
60			syslog(LOG_ERR, "Long config file line ignored.");
61			do
62				if (!fgets(buffer, MAX_CONFIG_STRING_SIZE - 1, in)) break;
63			while (buffer[strlen(buffer) - 1] != '\n');
64			continue;
65		}
66
67		len--;			/* For the NL at the end */
68		while (--len >= 0)
69			if (buffer[len] != ' ' && buffer[len] != '\t')
70				break;
71
72		len++;
73		buffer[len] = '\0';
74
75		buff_ptr = buffer;
76
77		/* Short-circuit blank lines and comments */
78		if (!len || *buff_ptr == '#')
79			continue;
80
81		/* Non-blank lines starting with a space are an error */
82
83		if (*buff_ptr == ' ' || *buff_ptr == '\t') {
84			syslog(LOG_ERR, "Config file line starts with a space: %s", buff_ptr);
85			continue;
86		}
87
88		/* At this point we have a line trimmed for trailing spaces. */
89		/* Now we need to check if the keyword matches, and if so */
90		/* then get the value (if any). */
91
92		/* Check if it's the right keyword */
93
94		do {
95			if (*buff_ptr == ' ' || *buff_ptr == '\t')
96				break;
97		} while (*++buff_ptr);
98
99		len = buff_ptr - buffer;
100		if (len == keyword_len && !strncmp(buffer, keyword, len)) {
101			foundit++;
102			break;
103		}
104	}
105
106	close_config_file(in);
107
108	if (foundit) {
109		/* Right keyword, now get the value (if any) */
110
111		do {
112			if (*buff_ptr != ' ' && *buff_ptr != '\t')
113				break;
114
115		} while (*++buff_ptr);
116
117		strcpy(value, buff_ptr);
118		return 1;
119	} else {
120		/* didn't find it - better luck next time */
121		return 0;
122	}
123}
124
125/*
126 * open_config_file
127 *
128 * Opens up the PPTPD config file for reading.
129 *
130 * args: filename - the config filename (eg. '/etc/pptpd.conf')
131 *
132 * retn: NULL on error, file descriptor on success
133 *
134 */
135static FILE *open_config_file(char *filename)
136{
137	FILE *in;
138	static int first = 1;
139
140	if ((in = fopen(filename, "r")) == NULL) {
141		/* Couldn't open config file */
142		if (first) {
143			perror(filename);
144			first = 0;
145		}
146		return NULL;
147	}
148	return in;
149}
150
151/*
152 * close_config_file
153 *
154 * Closes the PPTPD config file descriptor
155 *
156 */
157static void close_config_file(FILE * in)
158{
159	fclose(in);
160}
161