]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ConfigParser.cc
Merged from parent (large-rock r12530 including trunk r12732; v3.3.3+).
[thirdparty/squid.git] / src / ConfigParser.cc
1
2 /*
3 *
4 * SQUID Web Proxy Cache http://www.squid-cache.org/
5 * ----------------------------------------------------------
6 *
7 * Squid is the result of efforts by numerous individuals from
8 * the Internet community; see the CONTRIBUTORS file for full
9 * details. Many organizations have provided support for Squid's
10 * development; see the SPONSORS file for full details. Squid is
11 * Copyrighted (C) 2001 by the Regents of the University of
12 * California; see the COPYRIGHT file for full details. Squid
13 * incorporates software developed and/or copyrighted by other
14 * sources; see the CREDITS file for full details.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
29 *
30 *
31 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
32 */
33
34 #include "squid.h"
35 #include "cache_cf.h"
36 #include "ConfigParser.h"
37 #include "Debug.h"
38 #include "fatal.h"
39 #include "globals.h"
40
41 char *ConfigParser::lastToken = NULL;
42 std::queue<std::string> ConfigParser::undo;
43
44 void
45 ConfigParser::destruct()
46 {
47 shutting_down = 1;
48 fatalf("Bungled %s line %d: %s",
49 cfg_filename, config_lineno, config_input_line);
50 }
51
52 void
53 ConfigParser::strtokFileUndo()
54 {
55 assert(lastToken);
56 undo.push(lastToken);
57 }
58
59 void
60 ConfigParser::strtokFilePutBack(const char *tok)
61 {
62 assert(tok);
63 undo.push(tok);
64 }
65
66 char *
67 ConfigParser::strtokFile(void)
68 {
69 static int fromFile = 0;
70 static FILE *wordFile = NULL;
71 LOCAL_ARRAY(char, undoToken, CONFIG_LINE_LIMIT);
72
73 char *t, *fn;
74 LOCAL_ARRAY(char, buf, CONFIG_LINE_LIMIT);
75
76 if (!undo.empty()) {
77 strncpy(undoToken, undo.front().c_str(), sizeof(undoToken));
78 undoToken[sizeof(undoToken) - 1] = '\0';
79 undo.pop();
80 return undoToken;
81 }
82
83 lastToken = NULL;
84 do {
85
86 if (!fromFile) {
87 t = (strtok(NULL, w_space));
88
89 if (!t || *t == '#') {
90 return NULL;
91 } else if (*t == '\"' || *t == '\'') {
92 /* quote found, start reading from file */
93 fn = ++t;
94
95 while (*t && *t != '\"' && *t != '\'')
96 ++t;
97
98 *t = '\0';
99
100 if ((wordFile = fopen(fn, "r")) == NULL) {
101 debugs(28, DBG_CRITICAL, "strtokFile: " << fn << " not found");
102 return (NULL);
103 }
104
105 #if _SQUID_WINDOWS_
106 setmode(fileno(wordFile), O_TEXT);
107 #endif
108
109 fromFile = 1;
110 } else {
111 return lastToken = t;
112 }
113 }
114
115 /* fromFile */
116 if (fgets(buf, CONFIG_LINE_LIMIT, wordFile) == NULL) {
117 /* stop reading from file */
118 fclose(wordFile);
119 wordFile = NULL;
120 fromFile = 0;
121 return NULL;
122 } else {
123 char *t2, *t3;
124 t = buf;
125 /* skip leading and trailing white space */
126 t += strspn(buf, w_space);
127 t2 = t + strcspn(t, w_space);
128 t3 = t2 + strspn(t2, w_space);
129
130 while (*t3 && *t3 != '#') {
131 t2 = t3 + strcspn(t3, w_space);
132 t3 = t2 + strspn(t2, w_space);
133 }
134
135 *t2 = '\0';
136 }
137
138 /* skip comments */
139 /* skip blank lines */
140 } while ( *t == '#' || !*t );
141
142 return lastToken = t;
143 }
144
145 void
146 ConfigParser::ParseQuotedString(char **var, bool *wasQuoted)
147 {
148 String sVar;
149 ParseQuotedString(&sVar, wasQuoted);
150 *var = xstrdup(sVar.termedBuf());
151 }
152
153 void
154 ConfigParser::ParseQuotedString(String *var, bool *wasQuoted)
155 {
156 // Get all of the remaining string
157 char *token = strtok(NULL, "");
158 if (token == NULL)
159 self_destruct();
160
161 if (*token != '"') {
162 token = strtok(token, w_space);
163 var->reset(token);
164 if (wasQuoted)
165 *wasQuoted = false;
166 return;
167 } else if (wasQuoted)
168 *wasQuoted = true;
169
170 char *s = token + 1;
171 /* scan until the end of the quoted string, unescaping " and \ */
172 while (*s && *s != '"') {
173 if (*s == '\\') {
174 const char * next = s+1; // may point to 0
175 memmove(s, next, strlen(next) + 1);
176 }
177 ++s;
178 }
179
180 if (*s != '"') {
181 debugs(3, DBG_CRITICAL, "ParseQuotedString: missing '\"' at the end of quoted string" );
182 self_destruct();
183 }
184 strtok(s-1, "\""); /*Reset the strtok to point after the " */
185 *s = '\0';
186
187 var->reset(token+1);
188 }
189
190 const char *
191 ConfigParser::QuoteString(String &var)
192 {
193 static String quotedStr;
194 const char *s = var.termedBuf();
195 bool needQuote = false;
196
197 for (const char *l = s; !needQuote && *l != '\0'; ++l )
198 needQuote = !isalnum(*l);
199
200 if (!needQuote)
201 return s;
202
203 quotedStr.clean();
204 quotedStr.append('"');
205 for (; *s != '\0'; ++s) {
206 if (*s == '"' || *s == '\\')
207 quotedStr.append('\\');
208 quotedStr.append(*s);
209 }
210 quotedStr.append('"');
211 return quotedStr.termedBuf();
212 }