File: header_8c-source.html

package info (click to toggle)
klone 1.1.1.dfsg1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 6,480 kB
  • ctags: 4,238
  • sloc: ansic: 16,288; makefile: 384; sh: 351
file content (309 lines) | stat: -rw-r--r-- 17,356 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>KLone: header.c Source File</title>
<link href="kl.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.9.1 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="globals.html">Globals</a></div>
<div class="nav">
<a class="el" href="dir_000000.html">src</a>&nbsp;/&nbsp;<a class="el" href="dir_000009.html">libpage</a></div>
<h1>header.c</h1><a href="header_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*</span>
00002 <span class="comment"> * Copyright (c) 2005, 2006 by KoanLogic s.r.l. &lt;http://www.koanlogic.com&gt;</span>
00003 <span class="comment"> * All rights reserved.</span>
00004 <span class="comment"> *</span>
00005 <span class="comment"> * This file is part of KLone, and as such it is subject to the license stated</span>
00006 <span class="comment"> * in the LICENSE file which you have received as part of this distribution.</span>
00007 <span class="comment"> *</span>
00008 <span class="comment"> * $Id: header.c,v 1.14 2006/04/06 14:02:22 tat Exp $</span>
00009 <span class="comment"> */</span>
00010 
00011 <span class="preprocessor">#include "klone_conf.h"</span>
00012 <span class="preprocessor">#include &lt;u/libu.h&gt;</span>
00013 <span class="preprocessor">#include &lt;<a class="code" href="klone_8h.html">klone/klone.h</a>&gt;</span>
00014 <span class="preprocessor">#include &lt;<a class="code" href="header_8h.html">klone/header.h</a>&gt;</span>
00015 <span class="preprocessor">#include &lt;<a class="code" href="utils_8h.html">klone/utils.h</a>&gt;</span>
00016 
<a name="l00034"></a><a class="code" href="group__header__t.html#ga0">00034</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga0">header_set_field</a>(<a class="code" href="structheader__t.html">header_t</a> *h, <span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keyword">const</span> <span class="keywordtype">char</span> *value)
00035 {
00036     <a class="code" href="structfield__s.html">field_t</a>* n = NULL, *ex;
00037 
00038     dbg_err_if (h == NULL);
00039     dbg_err_if (name == NULL);
00040     dbg_err_if (value == NULL);
00041 
00042     <span class="comment">/* modify existing field if already set */</span>
00043     <span class="keywordflow">if</span>((ex = <a class="code" href="group__header__t.html#ga4">header_get_field</a>(h, name)) == NULL)
00044     {
00045         dbg_err_if(<a class="code" href="group__field__t.html#ga4">field_create</a>(name, value, &amp;n));
00046         dbg_err_if(<a class="code" href="group__header__t.html#ga7">header_add_field</a>(h, n));
00047     } <span class="keywordflow">else</span>
00048         dbg_err_if(<a class="code" href="group__field__t.html#ga0">field_set</a>(ex, name, value));
00049 
00050     <span class="keywordflow">return</span> 0;
00051 err:
00052     <span class="keywordflow">if</span>(n)
00053         <a class="code" href="group__field__t.html#ga5">field_free</a>(n);
00054     <span class="keywordflow">return</span> ~0;
00055 }
00056 
<a name="l00066"></a><a class="code" href="group__header__t.html#ga1">00066</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga1">header_clear</a>(<a class="code" href="structheader__t.html">header_t</a> *h)
00067 {
00068     <a class="code" href="structfield__s.html">field_t</a> *f;
00069     
00070     dbg_return_if (h == NULL, ~0);
00071     
00072     <span class="comment">/* free all items */</span>
00073     <span class="keywordflow">while</span>((f = TAILQ_FIRST(&amp;h-&gt;<a class="code" href="structheader__t.html#o0">fields</a>)) != NULL)
00074     {
00075         <a class="code" href="group__header__t.html#ga6">header_del_field</a>(h, f);
00076         <a class="code" href="group__field__t.html#ga5">field_free</a>(f);
00077     }
00078 
00079     <span class="keywordflow">return</span> 0;
00080 }
00081 
<a name="l00091"></a><a class="code" href="group__header__t.html#ga2">00091</a> size_t <a class="code" href="group__header__t.html#ga2">header_field_count</a>(<a class="code" href="structheader__t.html">header_t</a> *h)
00092 {
00093     dbg_return_if (h == NULL, 0);
00094 
00095     <span class="keywordflow">return</span> h-&gt;<a class="code" href="structheader__t.html#o1">nfields</a>;
00096 }
00097 
<a name="l00108"></a><a class="code" href="group__header__t.html#ga3">00108</a> <a class="code" href="structfield__s.html">field_t</a> *<a class="code" href="group__header__t.html#ga3">header_get_fieldn</a>(<a class="code" href="structheader__t.html">header_t</a> *h, size_t idx)
00109 {
00110     <a class="code" href="structfield__s.html">field_t</a> *f;
00111     size_t i = 0;
00112 
00113     dbg_goto_if (h == NULL, notfound);
00114     nop_goto_if (idx &gt;= h-&gt;<a class="code" href="structheader__t.html#o1">nfields</a>, notfound);
00115 
00116     TAILQ_FOREACH(f, &amp;h-&gt;<a class="code" href="structheader__t.html#o0">fields</a>, np)
00117     {
00118         <span class="keywordflow">if</span>(i == idx)
00119             <span class="keywordflow">return</span> f;
00120         ++i;
00121     }
00122 
00123 notfound:
00124     <span class="keywordflow">return</span> NULL;
00125 }
00126 
<a name="l00139"></a><a class="code" href="group__header__t.html#ga4">00139</a> <a class="code" href="structfield__s.html">field_t</a> *<a class="code" href="group__header__t.html#ga4">header_get_field</a>(<a class="code" href="structheader__t.html">header_t</a> *h, <span class="keyword">const</span> <span class="keywordtype">char</span> *name)
00140 {
00141     <a class="code" href="structfield__s.html">field_t</a> *f = NULL;
00142 
00143     dbg_goto_if (h == NULL, notfound);
00144     dbg_goto_if (name == NULL, notfound);
00145 
00146     TAILQ_FOREACH(f, &amp;h-&gt;<a class="code" href="structheader__t.html#o0">fields</a>, np)
00147         <span class="keywordflow">if</span>(strcasecmp(f-&gt;<a class="code" href="structfield__s.html#o0">name</a>, name) == 0)
00148             <span class="keywordflow">return</span> f;
00149 
00150 notfound:
00151     <span class="keywordflow">return</span> NULL;
00152 }
00153 
<a name="l00166"></a><a class="code" href="group__header__t.html#ga5">00166</a> <span class="keyword">const</span> <span class="keywordtype">char</span> *<a class="code" href="group__header__t.html#ga5">header_get_field_value</a>(<a class="code" href="structheader__t.html">header_t</a> *h, <span class="keyword">const</span> <span class="keywordtype">char</span> *name)
00167 {
00168     <a class="code" href="structfield__s.html">field_t</a> *f;
00169 
00170     dbg_return_if (h == NULL, NULL);
00171     dbg_return_if (name == NULL, NULL);
00172     
00173     f = <a class="code" href="group__header__t.html#ga4">header_get_field</a>(h, name);
00174 
00175     <span class="keywordflow">return</span> f ? <a class="code" href="group__field__t.html#ga3">field_get_value</a>(f) : NULL;
00176 }
00177 
<a name="l00188"></a><a class="code" href="group__header__t.html#ga6">00188</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga6">header_del_field</a>(<a class="code" href="structheader__t.html">header_t</a> *h, <a class="code" href="structfield__s.html">field_t</a> *f)
00189 {
00190     dbg_return_if (h == NULL, ~0);
00191     dbg_return_if (f == NULL, ~0);
00192 
00193     TAILQ_REMOVE(&amp;h-&gt;<a class="code" href="structheader__t.html#o0">fields</a>, f, np);
00194     h-&gt;<a class="code" href="structheader__t.html#o1">nfields</a>--;
00195 
00196     <span class="keywordflow">return</span> 0;
00197 }
00198 
<a name="l00209"></a><a class="code" href="group__header__t.html#ga7">00209</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga7">header_add_field</a>(<a class="code" href="structheader__t.html">header_t</a> *h, <a class="code" href="structfield__s.html">field_t</a> *f)
00210 {
00211     dbg_return_if (h == NULL, ~0);
00212     dbg_return_if (f == NULL, ~0);
00213 
00214     TAILQ_INSERT_TAIL(&amp;h-&gt;<a class="code" href="structheader__t.html#o0">fields</a>, f, np);
00215     h-&gt;<a class="code" href="structheader__t.html#o1">nfields</a>++;
00216 
00217     <span class="keywordflow">return</span> 0;
00218 }
00219 
00220 <span class="keyword">static</span> <span class="keywordtype">int</span> header_process_line(<a class="code" href="structheader__t.html">header_t</a> *h, u_string_t *line)
00221 {
00222     <a class="code" href="structfield__s.html">field_t</a> *f = NULL;
00223     <span class="keyword">const</span> <span class="keywordtype">char</span> *p;
00224 
00225     dbg_err_if (h == NULL);
00226     dbg_err_if (line == NULL);
00227     
00228     <span class="keywordflow">if</span>(!u_string_len(line))
00229         <span class="keywordflow">return</span> 0;
00230 
00231     <span class="comment">/* look for name/value delimiter */</span>
00232     dbg_err_if((p = strchr(u_string_c(line), <span class="charliteral">':'</span>)) == NULL);
00233 
00234     <span class="comment">/* alloc a new field */</span>
00235     dbg_err_if(<a class="code" href="group__field__t.html#ga4">field_create</a>(NULL, NULL, &amp;f));
00236 
00237     <span class="comment">/* parse and set name, value and params */</span>
00238     dbg_err_if(<a class="code" href="group__field__t.html#ga1">field_set_from_line</a>(f, u_string_c(line)));
00239 
00240     <span class="comment">/* add to this header */</span>
00241     dbg_err_if(<a class="code" href="group__header__t.html#ga7">header_add_field</a>(h, f));
00242 
00243     <span class="keywordflow">return</span> 0;
00244 err:
00245     <span class="keywordflow">if</span>(f)
00246         <a class="code" href="group__field__t.html#ga5">field_free</a>(f);
00247     <span class="keywordflow">return</span> ~0;
00248 }
00249 
00250 <span class="comment">/* load from environment. change each HTTP_name=value to name=value (replacing</span>
00251 <span class="comment">   '_' with '-' */</span>
<a name="l00252"></a><a class="code" href="group__header__t.html#ga9">00252</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga9">header_load_from_cgienv</a>(<a class="code" href="structheader__t.html">header_t</a> *h)
00253 {
00254     <span class="keyword">extern</span> <span class="keywordtype">char</span> **environ;
00255     <span class="keyword">enum</span> { BUFSZ = 256 };
00256     <span class="keywordtype">int</span> i;
00257     size_t blen, t;
00258     <span class="keywordtype">char</span> *e, *eq, buf[BUFSZ];
00259 
00260     <span class="comment">/* add HTTP_* to header field list */</span>
00261     <span class="keywordflow">for</span>(i = 0; environ[i]; ++i)
00262     {
00263         e = environ[i];
00264         <span class="keywordflow">if</span>(strlen(e) &gt; 5 &amp;&amp; strncmp(<span class="stringliteral">"HTTP_"</span>, e, 5) == 0)
00265         {
00266             memset(buf, 0, <span class="keyword">sizeof</span>(buf));
00267 
00268             <span class="comment">/* make a copy of e so we can modify it */</span>
00269             strncpy(buf, e + 5, <a class="code" href="utils_8h.html#a0">MIN</a>(BUFSZ, strlen(e + 5)));
00270             buf[BUFSZ-1] = 0;
00271 
00272             eq = strchr(buf, <span class="charliteral">'='</span>);
00273             <span class="keywordflow">if</span>(eq == NULL)
00274                 <span class="keywordflow">continue</span>; <span class="comment">/* malformed */</span>
00275 
00276             *eq = 0; <span class="comment">/* put a \0 between name and value */</span>
00277 
00278             <span class="comment">/* subst '_' with '-' */</span>
00279             <span class="keywordflow">for</span>(t = 0, blen = strlen(buf); t &lt; blen; ++t)
00280                 <span class="keywordflow">if</span>(buf[t] == <span class="charliteral">'_'</span>)
00281                     buf[t] = <span class="charliteral">'-'</span>;
00282 
00283             dbg_if(<a class="code" href="group__header__t.html#ga0">header_set_field</a>(h, buf, 1 + eq));
00284         }
00285     }
00286 
00287     <span class="keywordflow">return</span> 0;
00288 err:
00289     <span class="keywordflow">return</span> ~0;
00290 }
00291 
<a name="l00292"></a><a class="code" href="group__header__t.html#ga10">00292</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga10">header_load</a>(<a class="code" href="structheader__t.html">header_t</a> *h , <a class="code" href="structio__s.html">io_t</a> *io)
00293 {
00294     <span class="keyword">enum</span> { HEADER_MAX_FIELD_COUNT = 256 }; <span class="comment">/* max num of header fields */</span>
00295     u_string_t *line = NULL, *unfolded = NULL;
00296     <span class="keyword">const</span> <span class="keywordtype">char</span> *ln;
00297     size_t len, c;
00298 
00299     dbg_err_if (h == NULL);
00300     dbg_err_if (io == NULL);
00301 
00302     dbg_err_if(u_string_create(NULL, 0, &amp;line));
00303     dbg_err_if(u_string_create(NULL, 0, &amp;unfolded));
00304 
00305     <span class="keywordflow">for</span>(c = HEADER_MAX_FIELD_COUNT; <a class="code" href="group__u__t.html#ga33">u_getline</a>(io, line) == 0; --c)
00306     {
00307         warn_err_ifm(c == 0, <span class="stringliteral">"too much header fields"</span>);
00308 
00309         ln = u_string_c(line);
00310         len = u_string_len(line);
00311 
00312         <span class="comment">/* remove trailing nl(s) */</span>
00313         <span class="keywordflow">while</span>(len &amp;&amp; u_isnl(ln[len-1]))
00314             u_string_set_length(line, --len);
00315 
00316         <span class="keywordflow">if</span>(u_string_len(line) == 0)
00317             <span class="keywordflow">break</span>; <span class="comment">/* empty line */</span>
00318 
00319         <span class="keywordflow">if</span>(u_isblank(ln[0])) 
00320         {   <span class="comment">/* this is a chunk of a folded line */</span>
00321             dbg_err_if(u_string_append(unfolded, ln, u_string_len(line)));
00322         } <span class="keywordflow">else</span> {
00323             <span class="keywordflow">if</span>(u_string_len(unfolded))
00324             {
00325                 <span class="comment">/* go process this (already unfolded) line */</span>
00326                 header_process_line(h, unfolded);
00327                 u_string_clear(unfolded);
00328             }
00329             <span class="comment">/* this may be the first line of a folded line so wait next lines */</span>
00330             u_string_copy(unfolded, line);
00331         }
00332     }
00333 
00334     <span class="keywordflow">if</span>(u_string_len(unfolded))
00335         header_process_line(h, unfolded);
00336 
00337     u_string_free(unfolded);
00338     u_string_free(line);
00339 
00340     <span class="keywordflow">return</span> 0;
00341 err:
00342     <span class="keywordflow">if</span>(line)
00343         u_string_free(line);
00344     <span class="keywordflow">if</span>(unfolded)
00345         u_string_free(unfolded);
00346     <span class="keywordflow">return</span> ~0;
00347 }
00348 
<a name="l00349"></a><a class="code" href="group__header__t.html#ga11">00349</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga11">header_create</a>(<a class="code" href="structheader__t.html">header_t</a> **ph)
00350 {
00351     <a class="code" href="structheader__t.html">header_t</a> *h = NULL;
00352 
00353     dbg_err_if (ph == NULL);
00354 
00355     h = u_zalloc(<span class="keyword">sizeof</span>(<a class="code" href="structheader__t.html">header_t</a>));
00356     dbg_err_if(h == NULL);
00357 
00358     TAILQ_INIT(&amp;h-&gt;<a class="code" href="structheader__t.html#o0">fields</a>);
00359 
00360     *ph = h;
00361 
00362     <span class="keywordflow">return</span> 0;
00363 err:
00364     <span class="keywordflow">return</span> ~0;
00365 }
00366 
<a name="l00367"></a><a class="code" href="group__header__t.html#ga12">00367</a> <span class="keywordtype">int</span> <a class="code" href="group__header__t.html#ga12">header_free</a>(<a class="code" href="structheader__t.html">header_t</a> *h)
00368 {
00369     <span class="keywordflow">if</span> (h)
00370     {
00371         (void) <a class="code" href="group__header__t.html#ga1">header_clear</a>(h);
00372         U_FREE(h);
00373     }
00374 
00375     <span class="keywordflow">return</span> 0;
00376 }
00377 
</pre></div><hr>
<div> 
  <div style="text-align:left">
    <a href="http://www.koanlogic.com/kl/cont/gb/html/products.html">&larr;Products</a>
  </div>
  <div style="text-align:center;">
    &copy; 2005-2006 - <a href="http://www.koanlogic.com">KoanLogic S.r.l.</a> - All rights reserved
  </div>
</div>

</body>
</html>