Update to the new FSF address
[infodrom/cgilib] / cookies.c
1 /*
2     cookies.c - Cookie support for CGI library
3     Copyright (C) 1999,2007,8 by Martin Schulze <joey@infodrom.org>
4      
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9     
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14     
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software Foundation
17     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <cgi.h>
24 #include "aux.h"
25
26 s_cookie **cgiReadCookies()
27 {
28     char *http_cookie;
29     char *curpos, *n0, *n1, *v0, *v1, *cp;
30     s_cookie **res, *pivot = NULL;
31     int count;
32     int len;
33
34     if ((curpos = http_cookie = getenv ("HTTP_COOKIE")) == NULL)
35         return NULL;
36     count = 0;
37     if ((res = (s_cookie **)malloc (sizeof (s_cookie *))) == NULL)
38         return NULL;
39     res[0] = NULL;
40
41     while (*curpos) {
42         for (n0=curpos; *n0 && *n0==' '; n0++);
43         for (n1=n0; *n1 && *n1!=' ' && *n1!='=' && *n1!=';' && *n1!=',';n1++);
44         for (v0=n1; *v0 && (*v0==' ' || *v0=='=' || *v0==' ');v0++);
45         if (*v0 == '"') {
46             v1=++v0;
47             for (;*v1 && *v1!='"';v1++);
48         } else {
49             v1=v0;
50             for (;*v1 && *v1!=',' && *v1!=';';v1++);
51         }
52
53         if (n0 != n1) {
54             if (*n0 == '$') {
55                 if (strncasecmp (n0, "$version", 8) && strncasecmp (n0, "$path", 5)
56                     && strncasecmp (n0, "$domain", 7)) {
57                     curpos = v1+1;
58                     continue;
59                 }
60             } else
61                 if (pivot && pivot->name) {
62                     count++;
63                     if ((res = (s_cookie **)realloc (res, sizeof (s_cookie *) * (count+1))) == NULL)
64                         return NULL;
65                     res[count-1] = pivot;
66                     res[count] = pivot = NULL;
67                 }
68
69             if (!pivot) {
70                 if ((pivot = (s_cookie *)malloc (sizeof (s_cookie))) == NULL)
71                     return res;
72                 memset (pivot, 0, sizeof (s_cookie));
73                 if (res && res[0] && res[0]->version)
74                     pivot->version = res[0]->version;   /* Warning: *Never* free() res[n!=0]->version */
75             }
76             if (*n0 == '$') {
77                 n0++;
78                 len = sizeof (char) * (v1-v0);
79                 if ((cp = (char *)malloc (len)) == NULL)
80                     return res;
81                 memset (cp, 0, len);
82                 strncpy (cp, v0, v1-v0);
83
84                 if (!strncasecmp (n0, "version", 7))
85                     pivot->version = cp;
86                 else if (!strncasecmp (n0, "path", 4))
87                     pivot->path = cp;
88                 else if (!strncasecmp (n0, "domain", 6))
89                     pivot->domain = cp;
90                 else
91                     free (cp);
92             } else {
93                 len = sizeof (char) * (n1-n0+1);
94                 if ((pivot->name = (char *)malloc (len)) == NULL)
95                     return res;
96                 memset (pivot->name, 0, len);
97                 strncpy (pivot->name, n0, n1-n0);
98
99                 if (*v0 == '"')
100                     v0++;
101                 len = sizeof (char) * (v1-v0+1);
102                 if ((pivot->value = (char *)malloc (len)) == NULL)
103                     return res;
104                 memset (pivot->value, 0, len);
105                 strncpy (pivot->value, v0, v1-v0);
106             }
107         } else {
108             curpos = n0+1;
109         }
110         curpos = v1;
111         if (*curpos) curpos++;
112     }
113
114     count++;
115     if ((res = (s_cookie **)realloc (res, sizeof (s_cookie *) * (count+1))) == NULL)
116         return NULL;
117     res[count-1] = pivot;
118     res[count] = NULL;
119
120     return res;
121 }
122
123 s_cookie *cgiGetCookie (s_cgi *parms, const char *name)
124 {
125     int i;
126
127     if (!parms || !parms->cookies)
128         return NULL;
129     for (i=0;parms->cookies[i]; i++)
130         if (parms->cookies[i]->name && parms->cookies[i]->value && !strcmp(name,parms->cookies[i]->name)) {
131             cgiDebugOutput (1, "%s found as %s\n", name, parms->cookies[i]->value);
132             return parms->cookies[i];
133         }
134     cgiDebugOutput (1, "%s not found\n", name);
135     return NULL;
136 }
137
138 char **cgiGetCookies (s_cgi *parms)
139 {
140     int i, k;
141     char **res = NULL;
142     int len;
143
144     if (!parms || !parms->cookies)
145         return NULL;
146     for (i=k=0;parms->cookies[i];i++)
147         if (parms->cookies[i]->name && parms->cookies[i]->value)
148             k++;
149     len = sizeof (char *) * ++k;
150     if ((res = (char **)malloc (len)) == NULL)
151         return NULL;
152     memset (res, 0, len);
153     for (i=k=0;parms->cookies[i]; i++) {
154         if (parms->cookies[i]->name && parms->cookies[i]->value) {
155             len = strlen (parms->cookies[i]->name) +1;
156             if ((res[i] = (char *)malloc (len)) == NULL)
157                 return NULL;
158             memset (res[i], 0, len);
159             strcpy (res[i], parms->cookies[i]->name);
160         }
161     }
162     return res;
163 }
164
165 /*
166  * Local variables:
167  *  c-indent-level: 4
168  *  c-basic-offset: 4
169  *  tab-width: 8
170  * End:
171  */