Merge with http://elinks.cz/elinks.git
[elinks.git] / src / cookies / dialogs.c
blobba88d2f8aa1ea321672496e77c2d7b78725023e7
1 /* Cookie-related dialogs */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <errno.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "elinks.h"
13 #include "bfu/dialog.h"
14 #include "cookies/cookies.h"
15 #include "cookies/dialogs.h"
16 #include "dialogs/edit.h"
17 #include "intl/gettext/libintl.h"
18 #include "main/object.h"
19 #include "session/session.h"
20 #include "terminal/draw.h"
21 #include "terminal/terminal.h"
22 #include "util/conv.h"
23 #include "util/lists.h"
24 #include "util/memory.h"
25 #include "util/string.h"
28 INIT_LIST_HEAD(cookie_queries);
30 static void
31 add_cookie_info_to_string(struct string *string, struct cookie *cookie,
32 struct terminal *term)
34 add_format_to_string(string, "\n%s: %s", _("Name", term), cookie->name);
35 add_format_to_string(string, "\n%s: %s", _("Value", term), cookie->value);
36 add_format_to_string(string, "\n%s: %s", _("Domain", term), cookie->domain);
37 add_format_to_string(string, "\n%s: %s", _("Path", term), cookie->path);
39 if (!cookie->expires) {
40 add_format_to_string(string, "\n%s: ", _("Expires", term));
41 add_to_string(string, _("at quit time", term));
42 #ifdef HAVE_STRFTIME
43 } else {
44 add_format_to_string(string, "\n%s: ", _("Expires", term));
45 add_date_to_string(string, get_opt_str("ui.date_format"), &cookie->expires);
46 #endif
49 add_format_to_string(string, "\n%s: %s", _("Secure", term),
50 _(cookie->secure ? N_("yes") : N_("no"), term));
53 /* TODO: Store cookie in data arg. --jonas*/
54 void
55 accept_cookie_dialog(struct session *ses, void *data)
57 /* [gettext_accelerator_context(accept_cookie_dialog)] */
58 struct cookie *cookie = cookie_queries.next;
59 struct string string;
61 assert(ses);
63 if (list_empty(cookie_queries)
64 || !init_string(&string))
65 return;
67 del_from_list(cookie);
69 add_format_to_string(&string,
70 _("Do you want to accept a cookie from %s?", ses->tab->term),
71 cookie->server->host);
73 add_to_string(&string, "\n\n");
75 add_cookie_info_to_string(&string, cookie, ses->tab->term);
77 msg_box(ses->tab->term, NULL, MSGBOX_FREE_TEXT,
78 N_("Accept cookie?"), ALIGN_LEFT,
79 string.source,
80 cookie, 2,
81 N_("~Accept"), accept_cookie, B_ENTER,
82 N_("~Reject"), done_cookie, B_ESC);
86 static void
87 lock_cookie(struct listbox_item *item)
89 if (item->type == BI_LEAF)
90 object_lock((struct cookie *) item->udata);
91 else
92 object_lock((struct cookie_server *) item->udata);
95 static void
96 unlock_cookie(struct listbox_item *item)
98 if (item->type == BI_LEAF)
99 object_unlock((struct cookie *) item->udata);
100 else
101 object_unlock((struct cookie_server *) item->udata);
104 static int
105 is_cookie_used(struct listbox_item *item)
107 if (item->type == BI_FOLDER) {
108 struct listbox_item *root = item;
110 foreach (item, root->child)
111 if (is_object_used((struct cookie *) item->udata))
112 return 1;
114 return 0;
117 return is_object_used((struct cookie *) item->udata);
120 static unsigned char *
121 get_cookie_text(struct listbox_item *item, struct terminal *term)
123 /* Are we dealing with a folder? */
124 if (item->type == BI_FOLDER) {
125 struct cookie_server *server = item->udata;
127 return stracpy(server->host);
129 } else {
130 struct cookie *cookie = item->udata;
132 return stracpy(cookie->name);
136 static unsigned char *
137 get_cookie_info(struct listbox_item *item, struct terminal *term)
139 struct cookie *cookie = item->udata;
140 struct cookie_server *server;
141 struct string string;
143 if (item->type == BI_FOLDER) return NULL;
145 if (!init_string(&string)) return NULL;
147 server = cookie->server;
149 add_format_to_string(&string, "%s: %s", _("Server", term), server->host);
151 add_cookie_info_to_string(&string, cookie, term);
153 return string.source;
156 static struct listbox_item *
157 get_cookie_root(struct listbox_item *item)
159 /* Are we dealing with a folder? */
160 if (item->type == BI_FOLDER) {
161 return NULL;
162 } else {
163 struct cookie *cookie = item->udata;
165 return cookie->server->box_item;
169 static int
170 can_delete_cookie(struct listbox_item *item)
172 return 1;
175 static void
176 delete_cookie_item(struct listbox_item *item, int last)
178 struct cookie *cookie = item->udata;
180 if (item->type == BI_FOLDER) {
181 struct listbox_item *next, *root = item;
183 /* Releasing refcounts on the cookie_server will automagically
184 * delete it. */
185 foreachsafe (item, next, root->child)
186 delete_cookie_item(item, 0);
187 } else {
188 assert(!is_object_used(cookie));
190 delete_cookie(cookie);
193 if (last
194 && get_opt_bool("cookies.save")
195 && get_opt_bool("cookies.resave"))
196 save_cookies();
199 static struct listbox_ops_messages cookies_messages = {
200 /* cant_delete_item */
201 N_("Sorry, but cookie \"%s\" cannot be deleted."),
202 /* cant_delete_used_item */
203 N_("Sorry, but cookie \"%s\" is being used by something else."),
204 /* cant_delete_folder */
205 N_("Sorry, but cookie domain \"%s\" cannot be deleted."),
206 /* cant_delete_used_folder */
207 N_("Sorry, but cookie domain \"%s\" is being used by something else."),
208 /* delete_marked_items_title */
209 N_("Delete marked cookies"),
210 /* delete_marked_items */
211 N_("Delete marked cookies?"),
212 /* delete_folder_title */
213 N_("Delete domain's cookies"),
214 /* delete_folder */
215 N_("Delete all cookies from domain \"%s\"?"),
216 /* delete_item_title */
217 N_("Delete cookie"),
218 /* delete_item */
219 N_("Delete this cookie?"),
220 /* clear_all_items_title */
221 N_("Clear all cookies"),
222 /* clear_all_items_title */
223 N_("Do you really want to remove all cookies?"),
226 static struct listbox_ops cookies_listbox_ops = {
227 lock_cookie,
228 unlock_cookie,
229 is_cookie_used,
230 get_cookie_text,
231 get_cookie_info,
232 NULL,
233 get_cookie_root,
234 NULL,
235 can_delete_cookie,
236 delete_cookie_item,
237 NULL,
238 &cookies_messages,
241 static widget_handler_status_T
242 set_cookie_name(struct dialog_data *dlg_data, struct widget_data *widget_data)
244 struct cookie *cookie = dlg_data->dlg->udata;
245 unsigned char *value = widget_data->cdata;
247 if (!value || !cookie) return EVENT_NOT_PROCESSED;
248 mem_free_set(&cookie->name, stracpy(value));
249 return EVENT_PROCESSED;
252 static widget_handler_status_T
253 set_cookie_value(struct dialog_data *dlg_data, struct widget_data *widget_data)
255 struct cookie *cookie = dlg_data->dlg->udata;
256 unsigned char *value = widget_data->cdata;
258 if (!value || !cookie) return EVENT_NOT_PROCESSED;
259 mem_free_set(&cookie->value, stracpy(value));
260 return EVENT_PROCESSED;
263 static widget_handler_status_T
264 set_cookie_domain(struct dialog_data *dlg_data, struct widget_data *widget_data)
266 struct cookie *cookie = dlg_data->dlg->udata;
267 unsigned char *value = widget_data->cdata;
269 if (!value || !cookie) return EVENT_NOT_PROCESSED;
270 mem_free_set(&cookie->domain, stracpy(value));
271 return EVENT_PROCESSED;
274 static widget_handler_status_T
275 set_cookie_expires(struct dialog_data *dlg_data, struct widget_data *widget_data)
277 struct cookie *cookie = dlg_data->dlg->udata;
278 unsigned char *value = widget_data->cdata;
279 unsigned char *end;
280 long number;
282 if (!value || !cookie) return EVENT_NOT_PROCESSED;
284 errno = 0;
285 number = strtol(value, (char **) &end, 10);
286 if (errno || *end || number < 0) return EVENT_NOT_PROCESSED;
288 cookie->expires = (time_t) number;
289 return EVENT_PROCESSED;
292 static widget_handler_status_T
293 set_cookie_secure(struct dialog_data *dlg_data, struct widget_data *widget_data)
295 struct cookie *cookie = dlg_data->dlg->udata;
296 unsigned char *value = widget_data->cdata;
297 unsigned char *end;
298 long number;
300 if (!value || !cookie) return EVENT_NOT_PROCESSED;
302 errno = 0;
303 number = strtol(value, (char **) &end, 10);
304 if (errno || *end) return EVENT_NOT_PROCESSED;
306 cookie->secure = (number != 0);
307 return EVENT_PROCESSED;
310 static void
311 build_edit_dialog(struct terminal *term, struct cookie *cookie)
313 #define EDIT_WIDGETS_COUNT 8
314 /* [gettext_accelerator_context(.build_edit_dialog)] */
315 struct dialog *dlg;
316 unsigned char *name, *value, *domain, *expires, *secure;
317 unsigned char *dlg_server;
318 int length = 0;
320 dlg = calloc_dialog(EDIT_WIDGETS_COUNT, MAX_STR_LEN * 5);
321 if (!dlg) return;
323 dlg->title = _("Edit", term);
324 dlg->layouter = generic_dialog_layouter;
325 dlg->udata = cookie;
326 dlg->udata2 = NULL;
328 name = get_dialog_offset(dlg, EDIT_WIDGETS_COUNT);
329 value = name + MAX_STR_LEN;
330 domain = value + MAX_STR_LEN;
331 expires = domain + MAX_STR_LEN;
332 secure = expires + MAX_STR_LEN;
334 safe_strncpy(name, cookie->name, MAX_STR_LEN);
335 safe_strncpy(value, cookie->value, MAX_STR_LEN);
336 safe_strncpy(domain, cookie->domain, MAX_STR_LEN);
337 ulongcat(expires, &length, cookie->expires, MAX_STR_LEN, 0);
338 length = 0;
339 ulongcat(secure, &length, cookie->secure, MAX_STR_LEN, 0);
341 dlg_server = cookie->server->host;
342 dlg_server = straconcat(_("Server", term), ": ", dlg_server, "\n", NULL);
344 if (!dlg_server) {
345 mem_free(dlg);
346 return;
349 add_dlg_text(dlg, dlg_server, ALIGN_LEFT, 0);
350 add_dlg_field_float(dlg, _("Name", term), 0, 0, set_cookie_name, MAX_STR_LEN, name, NULL);
351 add_dlg_field_float(dlg, _("Value", term), 0, 0, set_cookie_value, MAX_STR_LEN, value, NULL);
352 add_dlg_field_float(dlg, _("Domain", term), 0, 0, set_cookie_domain, MAX_STR_LEN, domain, NULL);
353 add_dlg_field_float(dlg, _("Expires", term), 0, 0, set_cookie_expires, MAX_STR_LEN, expires, NULL);
354 add_dlg_field_float(dlg, _("Secure", term), 0, 0, set_cookie_secure, MAX_STR_LEN, secure, NULL);
356 add_dlg_button(dlg, _("~OK", term), B_ENTER, ok_dialog, NULL);
357 add_dlg_button(dlg, _("~Cancel", term), B_ESC, cancel_dialog, NULL);
359 add_dlg_end(dlg, EDIT_WIDGETS_COUNT);
361 do_dialog(term, dlg, getml(dlg, dlg_server, NULL));
362 #undef EDIT_WIDGETS_COUNT
365 static widget_handler_status_T
366 push_edit_button(struct dialog_data *dlg_data, struct widget_data *button)
368 struct listbox_data *box = get_dlg_listbox_data(dlg_data);
369 struct terminal *term = dlg_data->win->term;
370 struct cookie *cookie;
372 if (!box->sel) return EVENT_PROCESSED;
373 if (box->sel->type == BI_FOLDER) return EVENT_PROCESSED;
374 cookie = box->sel->udata;
375 if (!cookie) return EVENT_PROCESSED;
376 build_edit_dialog(term, cookie);
377 return EVENT_PROCESSED;
380 static widget_handler_status_T
381 push_add_button(struct dialog_data *dlg_data, struct widget_data *button)
383 struct listbox_data *box = get_dlg_listbox_data(dlg_data);
384 struct terminal *term = dlg_data->win->term;
385 struct cookie *new_cookie;
386 struct cookie_server *server;
388 if (!box->sel || !box->sel->udata) return EVENT_PROCESSED;
390 new_cookie = mem_calloc(1, sizeof(*new_cookie));
391 if (!new_cookie) return EVENT_PROCESSED;
393 if (box->sel->type == BI_FOLDER) {
394 assert(box->sel->depth == 0);
395 server = box->sel->udata;
396 } else {
397 struct cookie *cookie = box->sel->udata;
399 server = cookie->server;
402 object_lock(server);
403 new_cookie->server = server;
405 new_cookie->name = stracpy("");
406 new_cookie->value = stracpy("");
407 new_cookie->domain = stracpy("");
408 accept_cookie(new_cookie);
409 build_edit_dialog(term, new_cookie);
410 return EVENT_PROCESSED;
413 static widget_handler_status_T
414 push_save_button(struct dialog_data *dlg_data, struct widget_data *button)
416 save_cookies();
417 return EVENT_PROCESSED;
420 static struct hierbox_browser_button cookie_buttons[] = {
421 /* [gettext_accelerator_context(.cookie_buttons)] */
422 { N_("~Info"), push_hierbox_info_button, 1 },
423 { N_("~Add"), push_add_button, 1 },
424 { N_("~Edit"), push_edit_button, 1 },
425 { N_("~Delete"), push_hierbox_delete_button, 1 },
426 { N_("C~lear"), push_hierbox_clear_button, 1 },
427 { N_("Sa~ve"), push_save_button, 0 },
430 struct_hierbox_browser(
431 cookie_browser,
432 N_("Cookie manager"),
433 cookie_buttons,
434 &cookies_listbox_ops
437 void
438 cookie_manager(struct session *ses)
440 hierbox_browser(&cookie_browser, ses);