1 /* Cookie-related dialogs */
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_OF(struct cookie
, cookie_queries
);
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
));
44 add_format_to_string(string
, "\n%s: ", _("Expires", term
));
45 add_date_to_string(string
, get_opt_str("ui.date_format", NULL
), &cookie
->expires
);
49 add_format_to_string(string
, "\n%s: %s", _("Secure", term
),
50 _(cookie
->secure
? N_("yes") : N_("no"), term
));
54 accept_cookie_in_msg_box(void *cookie_
)
56 accept_cookie((struct cookie
*) cookie_
);
60 reject_cookie_in_msg_box(void *cookie_
)
62 done_cookie((struct cookie
*) cookie_
);
65 /* TODO: Store cookie in data arg. --jonas*/
67 accept_cookie_dialog(struct session
*ses
, void *data
)
69 /* [gettext_accelerator_context(accept_cookie_dialog)] */
70 struct cookie
*cookie
= cookie_queries
.next
;
75 if (list_empty(cookie_queries
)
76 || !init_string(&string
))
79 del_from_list(cookie
);
81 add_format_to_string(&string
,
82 _("Do you want to accept a cookie from %s?", ses
->tab
->term
),
83 cookie
->server
->host
);
85 add_to_string(&string
, "\n\n");
87 add_cookie_info_to_string(&string
, cookie
, ses
->tab
->term
);
89 msg_box(ses
->tab
->term
, NULL
, MSGBOX_FREE_TEXT
,
90 N_("Accept cookie?"), ALIGN_LEFT
,
93 MSG_BOX_BUTTON(N_("~Accept"), accept_cookie_in_msg_box
, B_ENTER
),
94 MSG_BOX_BUTTON(N_("~Reject"), reject_cookie_in_msg_box
, B_ESC
));
99 lock_cookie(struct listbox_item
*item
)
101 if (item
->type
== BI_LEAF
)
102 object_lock((struct cookie
*) item
->udata
);
104 object_lock((struct cookie_server
*) item
->udata
);
108 unlock_cookie(struct listbox_item
*item
)
110 if (item
->type
== BI_LEAF
)
111 object_unlock((struct cookie
*) item
->udata
);
113 object_unlock((struct cookie_server
*) item
->udata
);
117 is_cookie_used(struct listbox_item
*item
)
119 if (item
->type
== BI_FOLDER
) {
120 struct listbox_item
*root
= item
;
122 foreach (item
, root
->child
)
123 if (is_object_used((struct cookie
*) item
->udata
))
129 return is_object_used((struct cookie
*) item
->udata
);
132 static unsigned char *
133 get_cookie_text(struct listbox_item
*item
, struct terminal
*term
)
135 /* Are we dealing with a folder? */
136 if (item
->type
== BI_FOLDER
) {
137 struct cookie_server
*server
= item
->udata
;
139 return stracpy(server
->host
);
142 struct cookie
*cookie
= item
->udata
;
144 return stracpy(cookie
->name
);
148 static unsigned char *
149 get_cookie_info(struct listbox_item
*item
, struct terminal
*term
)
151 struct cookie
*cookie
= item
->udata
;
152 struct cookie_server
*server
;
153 struct string string
;
155 if (item
->type
== BI_FOLDER
) return NULL
;
157 if (!init_string(&string
)) return NULL
;
159 server
= cookie
->server
;
161 add_format_to_string(&string
, "%s: %s", _("Server", term
), server
->host
);
163 add_cookie_info_to_string(&string
, cookie
, term
);
165 return string
.source
;
168 static struct listbox_item
*
169 get_cookie_root(struct listbox_item
*item
)
171 /* Are we dealing with a folder? */
172 if (item
->type
== BI_FOLDER
) {
175 struct cookie
*cookie
= item
->udata
;
177 return cookie
->server
->box_item
;
182 can_delete_cookie(struct listbox_item
*item
)
188 delete_cookie_item(struct listbox_item
*item
, int last
)
190 struct cookie
*cookie
= item
->udata
;
192 if (item
->type
== BI_FOLDER
) {
193 struct listbox_item
*next
, *root
= item
;
195 /* Releasing refcounts on the cookie_server will automagically
197 foreachsafe (item
, next
, root
->child
)
198 delete_cookie_item(item
, 0);
200 assert(!is_object_used(cookie
));
202 delete_cookie(cookie
);
207 static struct listbox_ops_messages cookies_messages
= {
208 /* cant_delete_item */
209 N_("Sorry, but cookie \"%s\" cannot be deleted."),
210 /* cant_delete_used_item */
211 N_("Sorry, but cookie \"%s\" is being used by something else."),
212 /* cant_delete_folder */
213 N_("Sorry, but cookie domain \"%s\" cannot be deleted."),
214 /* cant_delete_used_folder */
215 N_("Sorry, but cookie domain \"%s\" is being used by something else."),
216 /* delete_marked_items_title */
217 N_("Delete marked cookies"),
218 /* delete_marked_items */
219 N_("Delete marked cookies?"),
220 /* delete_folder_title */
221 N_("Delete domain's cookies"),
223 N_("Delete all cookies from domain \"%s\"?"),
224 /* delete_item_title */
226 /* delete_item; xgettext:c-format */
227 N_("Delete this cookie?"),
228 /* clear_all_items_title */
229 N_("Clear all cookies"),
230 /* clear_all_items_title */
231 N_("Do you really want to remove all cookies?"),
234 static const struct listbox_ops cookies_listbox_ops
= {
249 static widget_handler_status_T
250 set_cookie_name(struct dialog_data
*dlg_data
, struct widget_data
*widget_data
)
252 struct cookie
*cookie
= dlg_data
->dlg
->udata
;
253 unsigned char *value
= widget_data
->cdata
;
255 if (!value
|| !cookie
) return EVENT_NOT_PROCESSED
;
256 mem_free_set(&cookie
->name
, stracpy(value
));
258 return EVENT_PROCESSED
;
261 static widget_handler_status_T
262 set_cookie_value(struct dialog_data
*dlg_data
, struct widget_data
*widget_data
)
264 struct cookie
*cookie
= dlg_data
->dlg
->udata
;
265 unsigned char *value
= widget_data
->cdata
;
267 if (!value
|| !cookie
) return EVENT_NOT_PROCESSED
;
268 mem_free_set(&cookie
->value
, stracpy(value
));
270 return EVENT_PROCESSED
;
273 static widget_handler_status_T
274 set_cookie_domain(struct dialog_data
*dlg_data
, struct widget_data
*widget_data
)
276 struct cookie
*cookie
= dlg_data
->dlg
->udata
;
277 unsigned char *value
= widget_data
->cdata
;
279 if (!value
|| !cookie
) return EVENT_NOT_PROCESSED
;
280 mem_free_set(&cookie
->domain
, stracpy(value
));
282 return EVENT_PROCESSED
;
285 static widget_handler_status_T
286 set_cookie_expires(struct dialog_data
*dlg_data
, struct widget_data
*widget_data
)
288 struct cookie
*cookie
= dlg_data
->dlg
->udata
;
289 unsigned char *value
= widget_data
->cdata
;
293 if (!value
|| !cookie
) return EVENT_NOT_PROCESSED
;
295 /* Bug 923: Assumes time_t values fit in long. */
297 number
= strtol(value
, (char **) &end
, 10);
298 if (errno
|| *end
|| number
< 0) return EVENT_NOT_PROCESSED
;
300 cookie
->expires
= (time_t) number
;
302 return EVENT_PROCESSED
;
305 static widget_handler_status_T
306 set_cookie_secure(struct dialog_data
*dlg_data
, struct widget_data
*widget_data
)
308 struct cookie
*cookie
= dlg_data
->dlg
->udata
;
309 unsigned char *value
= widget_data
->cdata
;
313 if (!value
|| !cookie
) return EVENT_NOT_PROCESSED
;
316 number
= strtol(value
, (char **) &end
, 10);
317 if (errno
|| *end
) return EVENT_NOT_PROCESSED
;
319 cookie
->secure
= (number
!= 0);
321 return EVENT_PROCESSED
;
325 build_edit_dialog(struct terminal
*term
, struct cookie
*cookie
)
327 #define EDIT_WIDGETS_COUNT 8
328 /* [gettext_accelerator_context(.build_edit_dialog)] */
330 unsigned char *name
, *value
, *domain
, *expires
, *secure
;
331 unsigned char *dlg_server
;
334 dlg
= calloc_dialog(EDIT_WIDGETS_COUNT
, MAX_STR_LEN
* 5);
337 dlg
->title
= _("Edit", term
);
338 dlg
->layouter
= generic_dialog_layouter
;
342 name
= get_dialog_offset(dlg
, EDIT_WIDGETS_COUNT
);
343 value
= name
+ MAX_STR_LEN
;
344 domain
= value
+ MAX_STR_LEN
;
345 expires
= domain
+ MAX_STR_LEN
;
346 secure
= expires
+ MAX_STR_LEN
;
348 safe_strncpy(name
, cookie
->name
, MAX_STR_LEN
);
349 safe_strncpy(value
, cookie
->value
, MAX_STR_LEN
);
350 safe_strncpy(domain
, cookie
->domain
, MAX_STR_LEN
);
351 /* Bug 923: Assumes time_t values fit in unsigned long. */
352 ulongcat(expires
, &length
, cookie
->expires
, MAX_STR_LEN
, 0);
354 ulongcat(secure
, &length
, cookie
->secure
, MAX_STR_LEN
, 0);
356 dlg_server
= cookie
->server
->host
;
357 dlg_server
= straconcat(_("Server", term
), ": ", dlg_server
, "\n",
358 (unsigned char *) NULL
);
365 add_dlg_text(dlg
, dlg_server
, ALIGN_LEFT
, 0);
366 add_dlg_field_float(dlg
, _("Name", term
), 0, 0, set_cookie_name
, MAX_STR_LEN
, name
, NULL
);
367 add_dlg_field_float(dlg
, _("Value", term
), 0, 0, set_cookie_value
, MAX_STR_LEN
, value
, NULL
);
368 add_dlg_field_float(dlg
, _("Domain", term
), 0, 0, set_cookie_domain
, MAX_STR_LEN
, domain
, NULL
);
369 add_dlg_field_float(dlg
, _("Expires", term
), 0, 0, set_cookie_expires
, MAX_STR_LEN
, expires
, NULL
);
370 add_dlg_field_float(dlg
, _("Secure", term
), 0, 0, set_cookie_secure
, MAX_STR_LEN
, secure
, NULL
);
372 add_dlg_button(dlg
, _("~OK", term
), B_ENTER
, ok_dialog
, NULL
);
373 add_dlg_button(dlg
, _("~Cancel", term
), B_ESC
, cancel_dialog
, NULL
);
375 add_dlg_end(dlg
, EDIT_WIDGETS_COUNT
);
377 do_dialog(term
, dlg
, getml(dlg
, (void *) dlg_server
, (void *) NULL
));
378 #undef EDIT_WIDGETS_COUNT
381 static widget_handler_status_T
382 push_edit_button(struct dialog_data
*dlg_data
, struct widget_data
*button
)
384 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
385 struct terminal
*term
= dlg_data
->win
->term
;
386 struct cookie
*cookie
;
388 if (!box
->sel
) return EVENT_PROCESSED
;
389 if (box
->sel
->type
== BI_FOLDER
) return EVENT_PROCESSED
;
390 cookie
= box
->sel
->udata
;
391 if (!cookie
) return EVENT_PROCESSED
;
392 build_edit_dialog(term
, cookie
);
393 return EVENT_PROCESSED
;
396 static widget_handler_status_T
397 push_add_button(struct dialog_data
*dlg_data
, struct widget_data
*button
)
399 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
400 struct terminal
*term
= dlg_data
->win
->term
;
401 struct cookie
*new_cookie
;
402 struct cookie_server
*server
;
404 if (!box
->sel
|| !box
->sel
->udata
) return EVENT_PROCESSED
;
406 if (box
->sel
->type
== BI_FOLDER
) {
407 assert(box
->sel
->depth
== 0);
408 server
= box
->sel
->udata
;
410 struct cookie
*cookie
= box
->sel
->udata
;
412 server
= cookie
->server
;
415 object_lock(server
); /* ref consumed by init_cookie */
417 new_cookie
= init_cookie(stracpy("") /* name */,
418 stracpy("") /* value */,
419 stracpy("/") /* path */,
420 stracpy(server
->host
) /* domain */,
422 if (!new_cookie
) return EVENT_PROCESSED
;
424 accept_cookie(new_cookie
);
425 build_edit_dialog(term
, new_cookie
);
426 return EVENT_PROCESSED
;
429 /* Called by ok_dialog for the "OK" button in the "Add Server" dialog.
430 * The data parameter points to the buffer used by the server name
433 add_server_do(void *data
)
435 unsigned char *value
= data
;
436 struct cookie
*dummy_cookie
;
440 dummy_cookie
= init_cookie(stracpy("empty") /* name */,
441 stracpy("1") /* value */,
442 stracpy("/") /* path */,
443 stracpy(value
) /* domain */,
444 get_cookie_server(value
, strlen(value
)));
445 if (!dummy_cookie
) return;
447 accept_cookie(dummy_cookie
);
450 static widget_handler_status_T
451 push_add_server_button(struct dialog_data
*dlg_data
, struct widget_data
*button
)
453 /* [gettext_accelerator_context(.push_add_server_button)] */
454 #define SERVER_WIDGETS_COUNT 3
455 struct terminal
*term
= dlg_data
->win
->term
;
460 dlg
= calloc_dialog(SERVER_WIDGETS_COUNT
, MAX_STR_LEN
);
461 if (!dlg
) return EVENT_NOT_PROCESSED
;
463 name
= get_dialog_offset(dlg
, SERVER_WIDGETS_COUNT
);
464 dlg
->title
= _("Add server", term
);
465 dlg
->layouter
= generic_dialog_layouter
;
468 text
= _("Server name", term
);
469 add_dlg_field_float(dlg
, text
, 0, 0, check_nonempty
, MAX_STR_LEN
, name
, NULL
);
470 add_dlg_ok_button(dlg
, _("~OK", term
), B_ENTER
, add_server_do
, name
);
471 add_dlg_button(dlg
, _("~Cancel", term
), B_ESC
, cancel_dialog
, NULL
);
472 add_dlg_end(dlg
, SERVER_WIDGETS_COUNT
);
473 do_dialog(term
, dlg
, getml(dlg
, (void *) NULL
));
475 return EVENT_PROCESSED
;
476 #undef SERVER_WIDGETS_COUNT
480 static widget_handler_status_T
481 push_save_button(struct dialog_data
*dlg_data
, struct widget_data
*button
)
483 save_cookies(dlg_data
->win
->term
);
484 return EVENT_PROCESSED
;
487 static const struct hierbox_browser_button cookie_buttons
[] = {
488 /* [gettext_accelerator_context(.cookie_buttons)] */
489 { N_("~Info"), push_hierbox_info_button
, 1 },
490 { N_("~Add"), push_add_button
, 1 },
491 { N_("Add ~server"), push_add_server_button
, 1 },
492 { N_("~Edit"), push_edit_button
, 1 },
493 { N_("~Delete"), push_hierbox_delete_button
, 1 },
494 { N_("C~lear"), push_hierbox_clear_button
, 1 },
495 { N_("Sa~ve"), push_save_button
, 0 },
498 struct_hierbox_browser(
500 N_("Cookie manager"),
506 cookie_manager(struct session
*ses
)
508 hierbox_browser(&cookie_browser
, ses
);