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
|
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
|
-
+
-
-
-
-
+
-
+
-
+
+
+
+
+
+
-
+
-
+
-
+
-
-
+
+
|
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code used to manage a cookie that stores user-specific
** display preferences for the web interface.
**
** cookie_parse(zNameOfCookie);
** cookie_parse(void);
**
** Identify a cookie that will be used to remember display choices
** made by the user, so that those same choices are selected automatically
** the next time the page is presented. This routine must be invoked
** first, to initialize this module.
** Read and parse the display preferences cookie.
**
** cookie_read_parameter(zQP, zPName);
**
** If query parameter zQP does not exist but zPName does exist in
** the parsed cookie, then initialize zQP to hold the same value
** as the zPName element in the parsed cookie.
**
** cookie_write_parameter(zQP, zPName);
** cookie_write_parameter(zQP, zPName, zDefault);
**
** If query parameter zQP exists and if it has a different value from
** the zPName parameter in the parsed cookie, then replace the value of
** zPName with the value of zQP. If zQP exists but zPName does not
** exist, then zPName is created. If zQP does not exist or if it has
** the same value as zPName, then this routine is a no-op.
**
** cookie_link_parameter(zQP, zPName);
** cookie_link_parameter(zQP, zPName, zDefault);
**
** This does both cookie_read_parameter() and cookie_write_parameter()
** all at once.
**
** cookie_render();
**
** If any prior calls to cookie_write_parameter() have changed the
** value of the user preferences cookie, this routine will cause the
** new cookie value to be included in the HTTP header for the current
** web page. This routine is a destructor for this module and should
** be called once.
**
** char *cookie_value(zPName, zDefault);
**
** Look up the value of a cookie parameter zPName. Return zDefault if
** there is no display preferences cookie or if zPName does not exist.
*/
#include "cookies.h"
#include <assert.h>
#include <string.h>
#if INTERFACE
/* the standard name of the display settings cookie for fossil */
# define DISPLAY_SETTINGS_COOKIE "fossil_display_settings"
#endif
/*
** State information private to this module
*/
#define COOKIE_NPARAM 10
static struct {
const char *zCookieName; /* name of the user preferences cookie */
char *zCookieValue; /* Value of the user preferences cookie */
int bChanged; /* True if any value has changed */
int bIsInit; /* True after initialization */
int nParam; /* Number of parameters in the cookie */
struct {
const char *zPName; /* Name of a parameter */
char *zPValue; /* Value of that parameter */
} aParam[COOKIE_NPARAM];
} cookies;
/* Initialize this module by parsing the content of the cookie named
** by zCookieName
*/
void cookie_parse(const char *zCookieName){
void cookie_parse(void){
char *z;
assert( cookies.zCookieName==0 );
if( cookies.bIsInit ) return;
cookies.zCookieName = zCookieName;
z = (char*)P(zCookieName);
z = (char*)P(DISPLAY_SETTINGS_COOKIE);
if( z==0 ) z = "";
cookies.zCookieValue = z = mprintf("%s", z);
cookies.bIsInit = 1;
while( cookies.nParam<COOKIE_NPARAM ){
while( fossil_isspace(z[0]) ) z++;
if( z[0]==0 ) break;
cookies.aParam[cookies.nParam].zPName = z;
while( *z && *z!='=' && *z!=',' ){ z++; }
if( *z=='=' ){
*z = 0;
|
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
-
+
|
const char *zQP, /* Name of the query parameter */
const char *zPName, /* Name of the cooking setting */
const char *zDflt, /* Default value for the query parameter */
int flags /* READ or WRITE or both */
){
const char *zQVal = P(zQP);
int i;
assert( cookies.zCookieName!=0 );
cookie_parse();
for(i=0; i<cookies.nParam && strcmp(zPName,cookies.aParam[i].zPName); i++){}
if( zQVal==0 && (flags & COOKIE_READ)!=0 && i<cookies.nParam ){
cgi_set_parameter_nocopy(zQP, cookies.aParam[i].zPValue, 1);
return;
}
if( zQVal==0 ) zQVal = zDflt;
if( (flags & COOKIE_WRITE)!=0
|
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
|
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
|
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
|
cookie_readwrite(zQP, zPName, zDflt, COOKIE_READ|COOKIE_WRITE);
}
/* Update the user preferences cookie, if necessary, and shut down this
** module
*/
void cookie_render(void){
assert( cookies.zCookieName!=0 );
if( cookies.bChanged ){
Blob new;
int i;
blob_init(&new, 0, 0);
for(i=0;i<cookies.nParam;i++){
if( i>0 ) blob_append(&new, ",", 1);
blob_appendf(&new, "%s=%T",
cookies.aParam[i].zPName, cookies.aParam[i].zPValue);
}
cgi_set_cookie(cookies.zCookieName, blob_str(&new), 0, 31536000);
cgi_set_cookie(DISPLAY_SETTINGS_COOKIE, blob_str(&new), 0, 31536000);
}
cookies.zCookieName = 0;
cookies.bIsInit = 0;
}
/* Return the value of a preference cookie.
*/
const char *cookie_value(const char *zPName, const char *zDefault){
int i;
assert( zPName!=0 );
cookie_parse();
for(i=0; i<cookies.nParam && strcmp(zPName,cookies.aParam[i].zPName); i++){}
return i<cookies.nParam ? cookies.aParam[i].zPValue : zDefault;
}
/*
** WEBPAGE: cookies
**
** Show the current display settings contained in the
** "fossil_display_settings" cookie.
*/
void cookie_page(void){
int i;
if( PB("clear") ){
cgi_set_cookie(DISPLAY_SETTINGS_COOKIE, "", 0, 1);
cgi_replace_parameter(DISPLAY_SETTINGS_COOKIE, "");
}
cookie_parse(DISPLAY_SETTINGS_COOKIE);
cookie_parse();
style_header("User Preference Cookie Values");
if( cookies.nParam ){
style_submenu_element("Clear", "%R/cookies?clear");
}
@ <p>The following are user preference settings held in the
@ "fossil_display_settings" cookie.
@ <ul>
|