2 * ========================================================================
3 * Copyright 2013-2022 Eduardo Chappa
4 * Copyright 2006-2008 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
20 #include "confscroll.h"
24 #include "../pith/ldap.h"
25 #include "../pith/state.h"
26 #include "../pith/bitmap.h"
27 #include "../pith/mailcmd.h"
28 #include "../pith/list.h"
35 int addr_select_tool(struct pine
*, int, CONF_S
**, unsigned);
36 void dir_init_display(struct pine
*, CONF_S
**, char **, struct variable
*, CONF_S
**);
37 int dir_config_tool(struct pine
*, int, CONF_S
**, unsigned);
38 void dir_config_add(struct pine
*, CONF_S
**);
39 void dir_config_shuffle(struct pine
*, CONF_S
**);
40 void dir_config_edit(struct pine
*, CONF_S
**);
41 int dir_edit_screen(struct pine
*, LDAP_SERV_S
*, char *, char **);
42 int dir_edit_tool(struct pine
*, int, CONF_S
**, unsigned);
43 void dir_config_del(struct pine
*, CONF_S
**);
44 void add_ldap_fake_first_server(struct pine
*, CONF_S
**, struct variable
*,
45 struct key_menu
*, HelpType
,
46 int (*)(struct pine
*, int, CONF_S
**, unsigned));
47 void add_ldap_server_to_display(struct pine
*, CONF_S
**, char *, char *,
48 struct variable
*, int, struct key_menu
*, HelpType
,
49 int (*)(struct pine
*, int, CONF_S
**, unsigned),
51 int ldap_checkbox_tool(struct pine
*, int, CONF_S
**, unsigned);
52 void toggle_ldap_option_bit(struct pine
*, int, struct variable
*, char *);
53 NAMEVAL_S
*ldap_feature_list(int);
56 static char *srch_res_help_title
= N_("HELP FOR SEARCH RESULTS INDEX");
57 static char *set_choose
= "--- ----------------------";
58 #define ADD_FIRST_LDAP_SERVER _("Use Add to add a directory server")
59 #define ADDR_SELECT_EXIT_VAL 5
60 #define ADDR_SELECT_GOBACK_VAL 6
61 #define ADDR_SELECT_FORCED_EXIT_VAL 7
64 static int some_selectable
;
65 static char *dserv
= N_("Directory Server on ");
68 * Let user choose an ldap entry (or return an entry if user doesn't need
72 * -1 if Exit was chosen
73 * -2 if none were selectable
74 * -3 if no entries existed at all
75 * -4 go back to Abook List was chosen
76 * -5 caller shouldn't free ac->res_head
78 * When 0 is returned the winner is pointed to by result.
79 * Result is an allocated LDAP_SEARCH_WINNER_S which has pointers
80 * to the ld and entry that were chosen. Those are pointers into
81 * the initial data, not copies. The two-pointer structure is
82 * allocated here and freed by the caller.
85 ldap_addr_select(struct pine
*ps
, ADDR_CHOOSE_S
*ac
, LDAP_CHOOSE_S
**result
,
86 LDAPLookupStyle style
, WP_ERR_S
*wp_err
, char *srchstr
)
89 LDAP_SERV_RES_S
*res_list
;
90 CONF_S
*ctmpa
= NULL
, *first_line
= NULL
, *alt_first_line
= NULL
;
91 int i
, retval
= 0, got_n_mail
= 0, got_n_entries
= 0;
97 void (*prev_redrawer
) (void);
99 dprint((4, "ldap_addr_select()\n"));
101 need_mail
= (style
== AlwaysDisplay
|| style
== DisplayForURL
) ? 0 : 1;
102 if(style
== AlwaysDisplay
){
103 km
= &addr_s_km_with_view
;
104 help
= h_address_display
;
106 else if(style
== AlwaysDisplayAndMailRequired
){
107 km
= &addr_s_km_with_goback
;
108 help
= h_address_select
;
110 else if(style
== DisplayForURL
){
111 km
= &addr_s_km_for_url
;
112 help
= h_address_display
;
116 help
= h_address_select
;
124 for(res_list
= ac
->res_head
; res_list
; res_list
= res_list
->next
){
125 for(e
= ldap_first_entry(res_list
->ld
, res_list
->res
);
127 e
= ldap_next_entry(res_list
->ld
, e
)){
129 struct berval
**cn
, **org
, **unit
, **title
, **mail
, **sn
;
131 int indent
, have_mail
;
134 cn
= org
= title
= unit
= mail
= sn
= NULL
;
135 for(a
= ldap_first_attribute(res_list
->ld
, e
, &ber
);
137 a
= ldap_next_attribute(res_list
->ld
, e
, ber
)){
139 dprint((9, " %s", a
? a
: "?"));
140 if(strcmp(a
, res_list
->info_used
->cnattr
) == 0){
142 cn
= ldap_get_values_len(res_list
->ld
, e
, a
);
144 if(cn
&& !ALPINE_LDAP_can_use(cn
)){
145 ldap_value_free_len(cn
);
149 else if(strcmp(a
, res_list
->info_used
->mailattr
) == 0){
151 mail
= ldap_get_values_len(res_list
->ld
, e
, a
);
153 else if(strcmp(a
, "o") == 0){
155 org
= ldap_get_values_len(res_list
->ld
, e
, a
);
157 else if(strcmp(a
, "ou") == 0){
159 unit
= ldap_get_values_len(res_list
->ld
, e
, a
);
161 else if(strcmp(a
, "title") == 0){
163 title
= ldap_get_values_len(res_list
->ld
, e
, a
);
172 for(a
= ldap_first_attribute(res_list
->ld
, e
, &ber
);
174 a
= ldap_next_attribute(res_list
->ld
, e
, ber
)){
176 if(strcmp(a
, res_list
->info_used
->snattr
) == 0){
178 sn
= ldap_get_values_len(res_list
->ld
, e
, a
);
180 if(sn
&& !ALPINE_LDAP_can_use(sn
)){
181 ldap_value_free_len(sn
);
190 if(ALPINE_LDAP_can_use(mail
))
195 got_n_mail
+= have_mail
;
200 * First line is either cn, sn, or dn.
203 new_confline(&ctmpa
);
205 alt_first_line
= ctmpa
;
207 ctmpa
->flags
|= CF_STARTITEM
;
208 if(need_mail
&& !have_mail
)
209 ctmpa
->flags
|= CF_PRIVATE
;
211 ctmpa
->value
= cpystr(cn
[0]->bv_val
);
212 ldap_value_free_len(cn
);
213 ctmpa
->valoffset
= indent
;
216 ctmpa
->help_title
= _(srch_res_help_title
);
217 ctmpa
->tool
= addr_select_tool
;
218 ctmpa
->d
.a
.ld
= res_list
->ld
;
219 ctmpa
->d
.a
.entry
= e
;
220 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
221 ctmpa
->d
.a
.serv
= res_list
->serv
;
223 if(!first_line
&& (have_mail
|| !need_mail
))
227 /* only happens if no cn */
229 new_confline(&ctmpa
);
231 alt_first_line
= ctmpa
;
233 ctmpa
->flags
|= CF_STARTITEM
;
234 if(need_mail
&& !have_mail
)
235 ctmpa
->flags
|= CF_PRIVATE
;
237 ctmpa
->value
= cpystr(sn
[0]->bv_val
);
238 ldap_value_free_len(sn
);
239 ctmpa
->valoffset
= indent
;
242 ctmpa
->help_title
= _(srch_res_help_title
);
243 ctmpa
->tool
= addr_select_tool
;
244 ctmpa
->d
.a
.ld
= res_list
->ld
;
245 ctmpa
->d
.a
.entry
= e
;
246 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
247 ctmpa
->d
.a
.serv
= res_list
->serv
;
249 if(!first_line
&& (have_mail
|| !need_mail
))
254 new_confline(&ctmpa
);
256 alt_first_line
= ctmpa
;
258 ctmpa
->flags
|= CF_STARTITEM
;
259 if(need_mail
&& !have_mail
)
260 ctmpa
->flags
|= CF_PRIVATE
;
262 dn
= ldap_get_dn(res_list
->ld
, e
);
265 our_ldap_dn_memfree(dn
);
269 ctmpa
->value
= cpystr(dn
? dn
: "?");
271 our_ldap_dn_memfree(dn
);
273 ctmpa
->valoffset
= indent
;
276 ctmpa
->help_title
= _(srch_res_help_title
);
277 ctmpa
->tool
= addr_select_tool
;
278 ctmpa
->d
.a
.ld
= res_list
->ld
;
279 ctmpa
->d
.a
.entry
= e
;
280 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
281 ctmpa
->d
.a
.serv
= res_list
->serv
;
283 if(!first_line
&& (have_mail
|| !need_mail
))
288 for(i
= 0; ALPINE_LDAP_usable(title
, i
); i
++){
289 new_confline(&ctmpa
);
290 ctmpa
->flags
|= CF_NOSELECT
;
291 ctmpa
->valoffset
= indent
+ 2;
292 ctmpa
->value
= cpystr(title
[i
]->bv_val
);
295 ctmpa
->help_title
= _(srch_res_help_title
);
296 ctmpa
->tool
= addr_select_tool
;
297 ctmpa
->d
.a
.ld
= res_list
->ld
;
298 ctmpa
->d
.a
.entry
= e
;
299 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
300 ctmpa
->d
.a
.serv
= res_list
->serv
;
304 ldap_value_free_len(title
);
308 for(i
= 0; ALPINE_LDAP_usable(unit
, i
); i
++){
309 new_confline(&ctmpa
);
310 ctmpa
->flags
|= CF_NOSELECT
;
311 ctmpa
->valoffset
= indent
+ 2;
312 ctmpa
->value
= cpystr(unit
[i
]->bv_val
);
315 ctmpa
->help_title
= _(srch_res_help_title
);
316 ctmpa
->tool
= addr_select_tool
;
317 ctmpa
->d
.a
.ld
= res_list
->ld
;
318 ctmpa
->d
.a
.entry
= e
;
319 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
320 ctmpa
->d
.a
.serv
= res_list
->serv
;
324 ldap_value_free_len(unit
);
328 for(i
= 0; ALPINE_LDAP_usable(org
, i
); i
++){
329 new_confline(&ctmpa
);
330 ctmpa
->flags
|= CF_NOSELECT
;
331 ctmpa
->valoffset
= indent
+ 2;
332 ctmpa
->value
= cpystr(org
[i
]->bv_val
);
335 ctmpa
->help_title
= _(srch_res_help_title
);
336 ctmpa
->tool
= addr_select_tool
;
337 ctmpa
->d
.a
.ld
= res_list
->ld
;
338 ctmpa
->d
.a
.entry
= e
;
339 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
340 ctmpa
->d
.a
.serv
= res_list
->serv
;
344 ldap_value_free_len(org
);
348 /* Don't show long list of email addresses. */
349 if(!ALPINE_LDAP_can_use_num(mail
, 0) ||
350 !ALPINE_LDAP_can_use_num(mail
, 1) ||
351 !ALPINE_LDAP_can_use_num(mail
, 2) ||
352 !ALPINE_LDAP_can_use_num(mail
, 3)){
353 for(i
= 0; ALPINE_LDAP_usable(mail
, i
); i
++){
354 new_confline(&ctmpa
);
355 ctmpa
->flags
|= CF_NOSELECT
;
356 ctmpa
->valoffset
= indent
+ 2;
357 ctmpa
->value
= cpystr(mail
[i
]->bv_val
);
360 ctmpa
->help_title
= _(srch_res_help_title
);
361 ctmpa
->tool
= addr_select_tool
;
362 ctmpa
->d
.a
.ld
= res_list
->ld
;
363 ctmpa
->d
.a
.entry
= e
;
364 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
365 ctmpa
->d
.a
.serv
= res_list
->serv
;
372 for(i
= 4; ALPINE_LDAP_usable(mail
, i
); i
++)
375 new_confline(&ctmpa
);
376 ctmpa
->flags
|= CF_NOSELECT
;
377 ctmpa
->valoffset
= indent
+ 2;
378 snprintf(tmp
, sizeof(tmp
), _("(%d email addresses)"), i
);
379 tmp
[sizeof(tmp
)-1] = '\0';
380 ctmpa
->value
= cpystr(tmp
);
383 ctmpa
->help_title
= _(srch_res_help_title
);
384 ctmpa
->tool
= addr_select_tool
;
385 ctmpa
->d
.a
.ld
= res_list
->ld
;
386 ctmpa
->d
.a
.entry
= e
;
387 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
388 ctmpa
->d
.a
.serv
= res_list
->serv
;
393 new_confline(&ctmpa
);
394 ctmpa
->flags
|= CF_NOSELECT
;
395 ctmpa
->valoffset
= indent
+ 2;
396 ctmpa
->value
= cpystr(_("<No Email Address Available>"));
399 ctmpa
->help_title
= _(srch_res_help_title
);
400 ctmpa
->tool
= addr_select_tool
;
401 ctmpa
->d
.a
.ld
= res_list
->ld
;
402 ctmpa
->d
.a
.entry
= e
;
403 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
404 ctmpa
->d
.a
.serv
= res_list
->serv
;
409 ldap_value_free_len(mail
);
411 new_confline(&ctmpa
); /* blank line */
414 ctmpa
->help_title
= _(srch_res_help_title
);
415 ctmpa
->tool
= addr_select_tool
;
416 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
422 else if(alt_first_line
)
423 first_line
= alt_first_line
;
425 new_confline(&ctmpa
); /* blank line */
426 ctmpa
->keymenu
= need_mail
? &addr_s_km_exit
: &addr_s_km_goback
;
428 ctmpa
->help_title
= _(srch_res_help_title
);
429 ctmpa
->tool
= addr_select_tool
;
430 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
432 new_confline(&ctmpa
);
434 strncpy(ee
, "[ ", sizeof(ee
));
435 ee
[sizeof(ee
)-1] = '\0';
436 if(wp_err
&& wp_err
->ldap_errno
)
437 /* TRANSLATORS: No matches returned for an LDAP search */
438 snprintf(ee
+2, sizeof(ee
)-2, _("%s, No Matches Returned"),
439 ldap_err2string(wp_err
->ldap_errno
));
441 strncpy(ee
+2, _("No Matches"), sizeof(ee
)-2);
443 ee
[sizeof(ee
)-1] = '\0';
445 /* TRANSLATORS: a request for user to choose Exit after they read text */
446 strncat(ee
, _(" -- Choose Exit ]"), sizeof(ee
)-strlen(ee
)-1);
447 ee
[sizeof(ee
)-1] = '\0';
448 ctmpa
->value
= cpystr(ee
);
449 ctmpa
->valoffset
= 10;
450 ctmpa
->keymenu
= need_mail
? &addr_s_km_exit
: &addr_s_km_goback
;
452 ctmpa
->help_title
= _(srch_res_help_title
);
453 ctmpa
->tool
= addr_select_tool
;
454 ctmpa
->flags
|= CF_NOSELECT
;
457 if(style
== AlwaysDisplay
|| style
== DisplayForURL
||
458 style
== AlwaysDisplayAndMailRequired
||
459 (style
== DisplayIfOne
&& got_n_mail
>= 1) ||
460 (style
== DisplayIfTwo
&& got_n_mail
>= 1 && got_n_entries
>= 2)){
461 if(wp_err
&& wp_err
->mangled
)
462 *wp_err
->mangled
= 1;
464 prev_redrawer
= ps_global
->redrawer
;
465 push_titlebar_state();
467 memset(&screen
, 0, sizeof(screen
));
468 /* TRANSLATORS: Print something1 using something2.
469 "this" is something1 */
470 switch(conf_scroll_screen(ps
,&screen
,first_line
,ac
->title
,_("this"),0, NULL
)){
471 case ADDR_SELECT_EXIT_VAL
:
475 case ADDR_SELECT_GOBACK_VAL
:
479 case ADDR_SELECT_FORCED_EXIT_VAL
:
480 if(alt_first_line
) /* some entries, but none suitable */
493 pop_titlebar_state();
495 if((ps_global
->redrawer
= prev_redrawer
) != NULL
)
496 (*ps_global
->redrawer
)();
498 if(result
&& retval
== 0 && ac
->selected_ld
&& ac
->selected_entry
){
499 (*result
) = (LDAP_CHOOSE_S
*)fs_get(sizeof(LDAP_CHOOSE_S
));
500 (*result
)->ld
= ac
->selected_ld
;
501 (*result
)->selected_entry
= ac
->selected_entry
;
502 (*result
)->info_used
= ac
->info_used
;
503 (*result
)->serv
= ac
->selected_serv
;
506 else if(style
== DisplayIfOne
&& got_n_mail
< 1){
507 if(alt_first_line
) /* some entries, but none suitable */
512 first_line
= first_confline(ctmpa
);
513 free_conflines(&first_line
);
515 else if(style
== DisplayIfTwo
&& (got_n_mail
< 1 || got_n_entries
< 2)){
517 if(alt_first_line
) /* some entries, but none suitable */
525 (*result
) = (LDAP_CHOOSE_S
*)fs_get(sizeof(LDAP_CHOOSE_S
));
526 (*result
)->ld
= first_line
->d
.a
.ld
;
527 (*result
)->selected_entry
= first_line
->d
.a
.entry
;
528 (*result
)->info_used
= first_line
->d
.a
.info_used
;
529 (*result
)->serv
= first_line
->d
.a
.serv
;
533 first_line
= first_confline(ctmpa
);
534 free_conflines(&first_line
);
542 addr_select_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
548 if(flags
& CF_PRIVATE
){
549 q_status_message(SM_ORDER
| SM_DING
, 0, 3,
550 _("No email address available for this entry; choose another or ExitSelect"));
552 else if(some_selectable
){
553 (*cl
)->d
.a
.ac
->selected_ld
= (*cl
)->d
.a
.ld
;
554 (*cl
)->d
.a
.ac
->selected_entry
= (*cl
)->d
.a
.entry
;
555 (*cl
)->d
.a
.ac
->info_used
= (*cl
)->d
.a
.info_used
;
556 (*cl
)->d
.a
.ac
->selected_serv
= (*cl
)->d
.a
.serv
;
557 retval
= simple_exit_cmd(flags
);
560 retval
= ADDR_SELECT_FORCED_EXIT_VAL
;
571 if((*cl
)->d
.a
.ld
&& (*cl
)->d
.a
.entry
){
572 e
= (LDAP_CHOOSE_S
*)fs_get(sizeof(LDAP_CHOOSE_S
));
573 e
->ld
= (*cl
)->d
.a
.ld
;
574 e
->selected_entry
= (*cl
)->d
.a
.entry
;
575 e
->info_used
= (*cl
)->d
.a
.info_used
;
576 e
->serv
= (*cl
)->d
.a
.serv
;
577 if(cmd
== MC_VIEW_TEXT
)
578 view_ldap_entry(ps
, e
);
579 else if(cmd
== MC_SAVE
)
580 save_ldap_entry(ps
, e
, 0);
581 else if(cmd
== MC_COMPOSE
)
582 compose_to_ldap_entry(ps
, e
, 0);
583 else if(cmd
== MC_ROLE
)
584 compose_to_ldap_entry(ps
, e
, 1);
586 forward_ldap_entry(ps
, e
);
588 fs_give((void **)&e
);
595 retval
= ADDR_SELECT_GOBACK_VAL
;
599 retval
= ADDR_SELECT_EXIT_VAL
;
608 ps
->mangled_body
= 1;
615 dir_init_display(struct pine
*ps
, CONF_S
**ctmp
, char **servers
,
616 struct variable
*var
, CONF_S
**first_line
)
627 if(servers
&& servers
[0] && servers
[0][0]){
628 for(i
= 0; servers
[i
]; i
++){
629 info
= break_up_ldap_server(servers
[i
]);
630 serv
= (info
&& info
->nick
&& *info
->nick
) ? cpystr(info
->nick
) :
631 (info
&& info
->serv
&& *info
->serv
) ? cpystr(info
->serv
) :
632 cpystr(_("Bad Server Config, Delete this"));
633 sizeofsub
= (((info
&& info
->serv
&& *info
->serv
)
635 : 3) + strlen(_(dserv
)) + 15) * sizeof(char);
636 subtitle
= (char *)fs_get(sizeofsub
);
637 if(info
&& info
->port
>= 0)
638 snprintf(subtitle
, sizeofsub
, "%s%s:%d",
640 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
643 snprintf(subtitle
, sizeofsub
, "%s%s",
645 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
647 subtitle
[sizeofsub
-1] = '\0';
649 add_ldap_server_to_display(ps
, ctmp
, serv
, subtitle
, var
,
650 i
, &dir_conf_km
, h_direct_config
,
652 (first_line
&& *first_line
== NULL
)
656 free_ldap_server_info(&info
);
660 add_ldap_fake_first_server(ps
, ctmp
, var
,
661 &dir_conf_km
, h_direct_config
,
670 directory_config(struct pine
*ps
, int edit_exceptions
)
672 CONF_S
*ctmp
= NULL
, *first_line
= NULL
;
674 int no_ex
, readonly_warning
= 0;
677 q_status_message(SM_ORDER
, 3, 7,
678 _("Exception Setup not implemented for directory"));
682 ew
= edit_exceptions
? ps_global
->ew_for_except_vars
: Main
;
684 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
687 readonly_warning
= 1;
689 PINERC_S
*prc
= NULL
;
702 readonly_warning
= prc
? prc
->readonly
: 1;
703 if(prc
&& prc
->quit_to_edit
){
704 quit_to_edit_msg(prc
);
709 if(ps
->fix_fixed_warning
)
710 offer_to_fix_pinerc(ps
);
712 dir_init_display(ps
, &ctmp
, no_ex
? ps
->VAR_LDAP_SERVERS
713 : LVAL(&ps
->vars
[V_LDAP_SERVERS
], ew
),
714 &ps
->vars
[V_LDAP_SERVERS
], &first_line
);
716 memset(&screen
, 0, sizeof(screen
));
717 screen
.deferred_ro_warning
= readonly_warning
;
718 /* TRANSLATORS: Print something1 using something2.
719 "servers" is something1 */
720 (void)conf_scroll_screen(ps
, &screen
, first_line
,
721 _("SETUP DIRECTORY SERVERS"), _("servers"), 0, NULL
);
722 ps
->mangled_screen
= 1;
727 dir_config_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
729 int first_one
, rv
= 0;
731 first_one
= (*cl
)->value
&&
732 (strcmp((*cl
)->value
, ADD_FIRST_LDAP_SERVER
) == 0);
736 q_status_message(SM_ORDER
|SM_DING
, 0, 3,
737 _("Nothing to Delete, use Add"));
739 dir_config_del(ps
, cl
);
744 if(!fixed_var((*cl
)->var
, NULL
, "directory list"))
745 dir_config_add(ps
, cl
);
750 if(!fixed_var((*cl
)->var
, NULL
, "directory list")){
752 dir_config_add(ps
, cl
);
754 dir_config_edit(ps
, cl
);
760 if(!fixed_var((*cl
)->var
, NULL
, "directory list")){
762 q_status_message(SM_ORDER
|SM_DING
, 0, 3,
763 _("Nothing to Shuffle, use Add"));
765 dir_config_shuffle(ps
, cl
);
784 * Add LDAP directory entry
787 dir_config_add(struct pine
*ps
, CONF_S
**cl
)
789 char *raw_server
= NULL
;
790 LDAP_SERV_S
*info
= NULL
;
794 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
796 if(dir_edit_screen(ps
, NULL
, "ADD A", &raw_server
) == 1){
798 info
= break_up_ldap_server(raw_server
);
800 if(info
&& info
->serv
&& *info
->serv
){
807 lval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
812 /* catch the special "" case */
814 (cnt
== 1 && lval
[0][0] == '\0')){
815 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
816 new_list
[0] = raw_server
;
820 /* add one for new value */
822 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
824 for(i
= 0; i
< (*cl
)->varmem
; i
++)
825 new_list
[i
] = cpystr(lval
[i
]);
827 new_list
[(*cl
)->varmem
] = raw_server
;
829 for(i
= (*cl
)->varmem
; i
< cnt
; i
++)
830 new_list
[i
+1] = cpystr(lval
[i
]);
834 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
835 free_list_array(&new_list
);
836 set_current_val((*cl
)->var
, TRUE
, FALSE
);
837 sizeofsub
= (((info
&& info
->serv
&& *info
->serv
)
839 : 3) + strlen(_(dserv
)) + 15) * sizeof(char);
840 subtitle
= (char *)fs_get(sizeofsub
);
841 if(info
&& info
->port
>= 0)
842 snprintf(subtitle
, sizeofsub
, "%s%s:%d",
844 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
847 snprintf(subtitle
, sizeofsub
, "%s%s",
849 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
851 subtitle
[sizeofsub
-1] = '\0';
853 if(cnt
< 2){ /* first one */
854 struct variable
*var
;
855 struct key_menu
*keymenu
;
857 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned);
860 keymenu
= (*cl
)->keymenu
;
863 *cl
= first_confline(*cl
);
865 add_ldap_server_to_display(ps
, cl
,
866 (info
&& info
->nick
&& *info
->nick
)
868 : cpystr(info
->serv
),
869 subtitle
, var
, 0, keymenu
, help
,
872 opt_screen
->top_line
= NULL
;
878 add_ldap_server_to_display(ps
, cl
,
879 (info
&& info
->nick
&& *info
->nick
)
881 : cpystr(info
->serv
),
890 /* adjust the rest of the varmems */
891 for(cp
= (*cl
)->next
; cp
; cp
= cp
->next
)
895 /* because add_ldap advanced cl to its third line */
896 (*cl
) = (*cl
)->prev
->prev
;
898 fix_side_effects(ps
, (*cl
)->var
, 0);
899 write_pinerc(ps
, ew
, WRP_NONE
);
902 q_status_message(SM_ORDER
, 0, 3, _("Add cancelled, no server name"));
905 free_ldap_server_info(&info
);
907 fs_give((void **)&raw_server
);
912 * Shuffle order of LDAP directory entries
915 dir_config_shuffle(struct pine
*ps
, CONF_S
**cl
)
917 int cnt
, rv
, current_num
, new_num
= 0, i
, j
, deefault
;
918 char **new_list
, **lval
;
922 CONF_S
*a
= NULL
, *b
= NULL
;
925 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
927 /* how many are in our current list? */
928 lval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
929 for(cnt
= 0; lval
&& lval
[cnt
]; cnt
++)
933 q_status_message(SM_ORDER
, 0, 3,
934 _("Shuffle only makes sense when there is more than one server in list"));
938 current_num
= (*cl
)->varmem
; /* variable number of highlighted directory */
940 /* Move it up or down? */
945 opts
[i
++].label
= _("Up");
950 opts
[i
++].label
= _("Down");
955 if(current_num
== 0){ /* no up */
959 else if(current_num
== cnt
- 1) /* no down */
962 snprintf(tmp
, sizeof(tmp
), "Shuffle \"%s\" %s%s%s ? ",
964 (opts
[0].ch
!= -2) ? _("UP") : "",
965 (opts
[0].ch
!= -2 && opts
[1].ch
!= -2) ? " or " : "",
966 (opts
[1].ch
!= -2) ? _("DOWN") : "");
967 tmp
[sizeof(tmp
)-1] = '\0';
968 help
= (opts
[0].ch
== -2) ? h_dir_shuf_down
969 : (opts
[1].ch
== -2) ? h_dir_shuf_up
972 rv
= radio_buttons(tmp
, -FOOTER_ROWS(ps
), opts
, deefault
, 'x',
977 cmd_cancelled("Shuffle");
981 new_num
= current_num
- 1;
982 a
= (*cl
)->prev
->prev
->prev
;
987 new_num
= current_num
+ 1;
989 b
= (*cl
)->next
->next
->next
;
993 /* allocate space for new list */
994 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
996 /* fill in new_list */
997 for(i
= 0; i
< cnt
; i
++){
1000 else if (i
== new_num
)
1005 /* notice this works even if we were using default */
1006 new_list
[i
] = cpystr(lval
[j
]);
1011 j
= set_variable_list((*cl
)->var
- ps
->vars
, new_list
, TRUE
, ew
);
1012 free_list_array(&new_list
);
1014 q_status_message(SM_ORDER
, 0, 3,
1015 _("Shuffle cancelled: couldn't save configuration file"));
1016 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1020 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1022 if(a
== opt_screen
->top_line
)
1023 opt_screen
->top_line
= b
;
1026 a
->varmem
= b
->varmem
;
1030 * Swap display lines. To start with, a is lower in list, b is higher.
1031 * The fact that there are 3 lines per entry is totally entangled in
1034 a
->next
->next
->next
= b
->next
->next
->next
;
1035 if(b
->next
->next
->next
)
1036 b
->next
->next
->next
->prev
= a
->next
->next
;
1040 b
->next
->next
->next
= a
;
1041 a
->prev
= b
->next
->next
;
1043 ps
->mangled_body
= 1;
1044 write_pinerc(ps
, ew
, WRP_NONE
);
1049 * Edit LDAP directory entry
1052 dir_config_edit(struct pine
*ps
, CONF_S
**cl
)
1054 char *raw_server
= NULL
, **lval
;
1058 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
1060 lval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
1061 info
= break_up_ldap_server((lval
&& lval
[(*cl
)->varmem
])
1062 ? lval
[(*cl
)->varmem
] : NULL
);
1064 if(dir_edit_screen(ps
, info
, "CHANGE THIS", &raw_server
) == 1){
1066 free_ldap_server_info(&info
);
1067 info
= break_up_ldap_server(raw_server
);
1069 if(lval
&& lval
[(*cl
)->varmem
] &&
1070 strcmp(lval
[(*cl
)->varmem
], raw_server
) == 0)
1071 q_status_message(SM_ORDER
, 0, 3, _("No change, cancelled"));
1072 else if(!(info
&& info
->serv
&& *info
->serv
))
1073 q_status_message(SM_ORDER
, 0, 3,
1074 _("Change cancelled, use Delete if you want to remove this server"));
1081 for(cnt
= 0; lval
&& lval
[cnt
]; cnt
++)
1084 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
1086 for(i
= 0; i
< (*cl
)->varmem
; i
++)
1087 new_list
[i
] = cpystr(lval
[i
]);
1089 new_list
[(*cl
)->varmem
] = raw_server
;
1092 for(i
= (*cl
)->varmem
+ 1; i
< cnt
; i
++)
1093 new_list
[i
] = cpystr(lval
[i
]);
1095 new_list
[cnt
] = NULL
;
1096 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
1097 free_list_array(&new_list
);
1098 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1101 fs_give((void **)&(*cl
)->value
);
1103 (*cl
)->value
= cpystr((info
->nick
&& *info
->nick
) ? info
->nick
1106 if((*cl
)->next
->value
)
1107 fs_give((void **)&(*cl
)->next
->value
);
1109 sizeofsub
= (((info
&& info
->serv
&& *info
->serv
)
1110 ? strlen(info
->serv
)
1111 : 3) + strlen(_(dserv
)) + 15) * sizeof(char);
1113 subtitle
= (char *)fs_get(sizeofsub
);
1114 if(info
&& info
->port
>= 0)
1115 snprintf(subtitle
, sizeofsub
, "%s%s:%d",
1117 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
1120 snprintf(subtitle
, sizeofsub
, "%s%s",
1122 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
1124 subtitle
[sizeofsub
] = '\0';
1126 (*cl
)->next
->value
= subtitle
;
1128 fix_side_effects(ps
, (*cl
)->var
, 0);
1129 write_pinerc(ps
, ew
, WRP_NONE
);
1133 free_ldap_server_info(&info
);
1135 fs_give((void **)&raw_server
);
1139 #define LDAP_F_IMPL 0
1140 #define LDAP_F_RHS 1
1141 #define LDAP_F_REF 2
1142 #define LDAP_F_NOSUB 3
1143 #define LDAP_F_TLS 4
1144 #define LDAP_F_TLSMUST 5
1145 #define LDAP_F_LDAPS 6
1146 bitmap_t ldap_option_list
;
1147 struct variable
*ldap_srch_rule_ptr
;
1150 * Gives user screen to edit config values for ldap server.
1152 * Args ps -- pine struct
1153 * def -- default values to start with
1154 * title -- part of title at top of screen
1155 * raw_server -- This is the returned item, allocated here and freed by caller.
1157 * Returns: 0 if no change
1158 * 1 if user requested a change
1159 * (change is stored in raw_server and hasn't been acted upon yet)
1160 * 10 user says abort
1163 dir_edit_screen(struct pine
*ps
, LDAP_SERV_S
*def
, char *title
, char **raw_server
)
1165 OPT_SCREEN_S screen
, *saved_screen
;
1166 CONF_S
*ctmp
= NULL
, *ctmpb
, *first_line
= NULL
;
1167 char tmp
[MAXPATH
+1], custom_scope
[MAXPATH
], **apval
;
1168 int rv
, i
, j
, lv
, indent
, rindent
;
1170 struct variable server_var
, base_var
, binddn_var
, port_var
, nick_var
,
1171 srch_type_var
, srch_rule_var
, time_var
,
1172 size_var
, mailattr_var
, cnattr_var
,
1173 snattr_var
, gnattr_var
, cust_var
,
1174 opt_var
, *v
, *varlist
[21];
1175 char *server
= NULL
, *base
= NULL
, *port
= NULL
, *nick
= NULL
,
1176 *srch_type
= NULL
, *srch_rule
= NULL
, *ttime
= NULL
,
1177 *c_s_f
= "custom-search-filter", *binddn
= NULL
,
1178 *ssize
= NULL
, *mailattr
= NULL
, *cnattr
= NULL
,
1179 *snattr
= NULL
, *gnattr
= NULL
, *cust
= NULL
;
1182 * We edit by making a nested call to conf_scroll_screen.
1183 * We use some fake struct variables to get back the results in, and
1184 * so we can use the existing tools from the config screen.
1187 custom_scope
[0] = '\0';
1189 varlist
[j
= 0] = &server_var
;
1190 varlist
[++j
] = &base_var
;
1191 varlist
[++j
] = &port_var
;
1192 varlist
[++j
] = &binddn_var
;
1193 varlist
[++j
] = &nick_var
;
1194 varlist
[++j
] = &srch_type_var
;
1195 varlist
[++j
] = &srch_rule_var
;
1196 varlist
[++j
] = &time_var
;
1197 varlist
[++j
] = &size_var
;
1198 varlist
[++j
] = &mailattr_var
;
1199 varlist
[++j
] = &cnattr_var
;
1200 varlist
[++j
] = &snattr_var
;
1201 varlist
[++j
] = &gnattr_var
;
1202 varlist
[++j
] = &cust_var
;
1203 varlist
[++j
] = &opt_var
;
1204 varlist
[++j
] = NULL
;
1205 for(j
= 0; varlist
[j
]; j
++)
1206 memset(varlist
[j
], 0, sizeof(struct variable
));
1208 server_var
.name
= cpystr("ldap-server");
1209 server_var
.is_used
= 1;
1210 server_var
.is_user
= 1;
1211 apval
= APVAL(&server_var
, ew
);
1212 *apval
= (def
&& def
->serv
&& def
->serv
[0]) ? cpystr(def
->serv
) : NULL
;
1213 set_current_val(&server_var
, FALSE
, FALSE
);
1215 base_var
.name
= cpystr("search-base");
1216 base_var
.is_used
= 1;
1217 base_var
.is_user
= 1;
1218 apval
= APVAL(&base_var
, ew
);
1219 *apval
= (def
&& def
->base
&& def
->base
[0]) ? cpystr(def
->base
) : NULL
;
1220 set_current_val(&base_var
, FALSE
, FALSE
);
1222 port_var
.name
= cpystr("port");
1223 port_var
.is_used
= 1;
1224 port_var
.is_user
= 1;
1225 if(def
&& def
->port
>= 0){
1226 apval
= APVAL(&port_var
, ew
);
1227 *apval
= cpystr(int2string(def
->port
));
1230 port_var
.global_val
.p
= cpystr(int2string(LDAP_PORT
));
1231 set_current_val(&port_var
, FALSE
, FALSE
);
1233 binddn_var
.name
= cpystr("bind-dn");
1234 binddn_var
.is_used
= 1;
1235 binddn_var
.is_user
= 1;
1236 apval
= APVAL(&binddn_var
, ew
);
1237 *apval
= (def
&& def
->binddn
&& def
->binddn
[0]) ? cpystr(def
->binddn
) : NULL
;
1238 set_current_val(&binddn_var
, FALSE
, FALSE
);
1240 nick_var
.name
= cpystr("nickname");
1241 nick_var
.is_used
= 1;
1242 nick_var
.is_user
= 1;
1243 apval
= APVAL(&nick_var
, ew
);
1244 *apval
= (def
&& def
->nick
&& def
->nick
[0]) ? cpystr(def
->nick
) : NULL
;
1245 set_current_val(&nick_var
, FALSE
, FALSE
);
1247 srch_type_var
.name
= cpystr("search-type");
1248 srch_type_var
.is_used
= 1;
1249 srch_type_var
.is_user
= 1;
1250 apval
= APVAL(&srch_type_var
, ew
);
1251 *apval
= (f
=ldap_search_types(def
? def
->type
: -1))
1252 ? cpystr(f
->name
) : NULL
;
1253 srch_type_var
.global_val
.p
=
1254 (f
=ldap_search_types(DEF_LDAP_TYPE
)) ? cpystr(f
->name
) : NULL
;
1255 set_current_val(&srch_type_var
, FALSE
, FALSE
);
1257 ldap_srch_rule_ptr
= &srch_rule_var
; /* so radiobuttons can tell */
1258 srch_rule_var
.name
= cpystr("search-rule");
1259 srch_rule_var
.is_used
= 1;
1260 srch_rule_var
.is_user
= 1;
1261 apval
= APVAL(&srch_rule_var
, ew
);
1262 *apval
= (f
=ldap_search_rules(def
? def
->srch
: -1))
1263 ? cpystr(f
->name
) : NULL
;
1264 srch_rule_var
.global_val
.p
=
1265 (f
=ldap_search_rules(DEF_LDAP_SRCH
)) ? cpystr(f
->name
) : NULL
;
1266 set_current_val(&srch_rule_var
, FALSE
, FALSE
);
1268 time_var
.name
= cpystr("timelimit");
1269 time_var
.is_used
= 1;
1270 time_var
.is_user
= 1;
1271 if(def
&& def
->time
>= 0){
1272 apval
= APVAL(&time_var
, ew
);
1273 *apval
= cpystr(int2string(def
->time
));
1276 time_var
.global_val
.p
= cpystr(int2string(DEF_LDAP_TIME
));
1277 set_current_val(&time_var
, FALSE
, FALSE
);
1279 size_var
.name
= cpystr("sizelimit");
1280 size_var
.is_used
= 1;
1281 size_var
.is_user
= 1;
1282 if(def
&& def
->size
>= 0){
1283 apval
= APVAL(&size_var
, ew
);
1284 *apval
= cpystr(int2string(def
->size
));
1287 size_var
.global_val
.p
= cpystr(int2string(DEF_LDAP_SIZE
));
1288 set_current_val(&size_var
, FALSE
, FALSE
);
1290 mailattr_var
.name
= cpystr("email-attribute");
1291 mailattr_var
.is_used
= 1;
1292 mailattr_var
.is_user
= 1;
1293 apval
= APVAL(&mailattr_var
, ew
);
1294 *apval
= (def
&& def
->mailattr
&& def
->mailattr
[0])
1295 ? cpystr(def
->mailattr
) : NULL
;
1296 mailattr_var
.global_val
.p
= cpystr(DEF_LDAP_MAILATTR
);
1297 set_current_val(&mailattr_var
, FALSE
, FALSE
);
1299 cnattr_var
.name
= cpystr("name-attribute");
1300 cnattr_var
.is_used
= 1;
1301 cnattr_var
.is_user
= 1;
1302 apval
= APVAL(&cnattr_var
, ew
);
1303 *apval
= (def
&& def
->cnattr
&& def
->cnattr
[0])
1304 ? cpystr(def
->cnattr
) : NULL
;
1305 cnattr_var
.global_val
.p
= cpystr(DEF_LDAP_CNATTR
);
1306 set_current_val(&cnattr_var
, FALSE
, FALSE
);
1308 snattr_var
.name
= cpystr("surname-attribute");
1309 snattr_var
.is_used
= 1;
1310 snattr_var
.is_user
= 1;
1311 apval
= APVAL(&snattr_var
, ew
);
1312 *apval
= (def
&& def
->snattr
&& def
->snattr
[0])
1313 ? cpystr(def
->snattr
) : NULL
;
1314 snattr_var
.global_val
.p
= cpystr(DEF_LDAP_SNATTR
);
1315 set_current_val(&snattr_var
, FALSE
, FALSE
);
1317 gnattr_var
.name
= cpystr("givenname-attribute");
1318 gnattr_var
.is_used
= 1;
1319 gnattr_var
.is_user
= 1;
1320 apval
= APVAL(&gnattr_var
, ew
);
1321 *apval
= (def
&& def
->gnattr
&& def
->gnattr
[0])
1322 ? cpystr(def
->gnattr
) : NULL
;
1323 gnattr_var
.global_val
.p
= cpystr(DEF_LDAP_GNATTR
);
1324 set_current_val(&gnattr_var
, FALSE
, FALSE
);
1326 cust_var
.name
= cpystr(c_s_f
);
1327 cust_var
.is_used
= 1;
1328 cust_var
.is_user
= 1;
1329 apval
= APVAL(&cust_var
, ew
);
1330 *apval
= (def
&& def
->cust
&& def
->cust
[0]) ? cpystr(def
->cust
) : NULL
;
1331 set_current_val(&cust_var
, FALSE
, FALSE
);
1333 /* TRANSLATORS: Features is a section title in the LDAP configuration screen. Following
1334 this are a list of features or options that can be turned on or off. */
1335 opt_var
.name
= cpystr(_("Features"));
1336 opt_var
.is_used
= 1;
1337 opt_var
.is_user
= 1;
1338 opt_var
.is_list
= 1;
1339 clrbitmap(ldap_option_list
);
1340 if(def
&& def
->impl
)
1341 setbitn(LDAP_F_IMPL
, ldap_option_list
);
1343 setbitn(LDAP_F_RHS
, ldap_option_list
);
1345 setbitn(LDAP_F_REF
, ldap_option_list
);
1346 if(def
&& def
->nosub
)
1347 setbitn(LDAP_F_NOSUB
, ldap_option_list
);
1349 setbitn(LDAP_F_TLS
, ldap_option_list
);
1350 if(def
&& def
->tlsmust
)
1351 setbitn(LDAP_F_TLSMUST
, ldap_option_list
);
1352 if(def
&& def
->ldaps
)
1353 setbitn(LDAP_F_LDAPS
, ldap_option_list
);
1355 /* save the old opt_screen before calling scroll screen again */
1356 saved_screen
= opt_screen
;
1358 indent
= utf8_width(c_s_f
) + 3;
1362 new_confline(&ctmp
);
1363 ctmp
->help_title
= _("HELP FOR LDAP SERVER");
1364 ctmp
->var
= &server_var
;
1365 ctmp
->valoffset
= indent
;
1366 ctmp
->keymenu
= &config_text_keymenu
;
1367 ctmp
->help
= h_config_ldap_server
;
1368 ctmp
->tool
= dir_edit_tool
;
1369 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,server_var
.name
);
1370 tmp
[sizeof(tmp
)-1] = '\0';
1371 ctmp
->varname
= cpystr(tmp
);
1372 ctmp
->varnamep
= ctmp
;
1373 ctmp
->value
= pretty_value(ps
, ctmp
);
1378 new_confline(&ctmp
);
1379 ctmp
->help_title
= _("HELP FOR SERVER SEARCH BASE");
1380 ctmp
->var
= &base_var
;
1381 ctmp
->valoffset
= indent
;
1382 ctmp
->keymenu
= &config_text_keymenu
;
1383 ctmp
->help
= h_config_ldap_base
;
1384 ctmp
->tool
= dir_edit_tool
;
1385 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,base_var
.name
);
1386 tmp
[sizeof(tmp
)-1] = '\0';
1387 ctmp
->varname
= cpystr(tmp
);
1388 ctmp
->varnamep
= ctmp
;
1389 ctmp
->value
= pretty_value(ps
, ctmp
);
1392 new_confline(&ctmp
);
1393 ctmp
->help_title
= _("HELP FOR PORT NUMBER");
1394 ctmp
->var
= &port_var
;
1395 ctmp
->valoffset
= indent
;
1396 ctmp
->keymenu
= &config_text_keymenu
;
1397 ctmp
->help
= h_config_ldap_port
;
1398 ctmp
->tool
= dir_edit_tool
;
1399 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,port_var
.name
);
1400 tmp
[sizeof(tmp
)-1] = '\0';
1401 ctmp
->varname
= cpystr(tmp
);
1402 ctmp
->varnamep
= ctmp
;
1403 ctmp
->value
= pretty_value(ps
, ctmp
);
1404 ctmp
->flags
|= CF_NUMBER
;
1406 /* Bind DN (DN to bind to if needed) */
1407 new_confline(&ctmp
);
1408 ctmp
->help_title
= _("HELP FOR SERVER BIND DN");
1409 ctmp
->var
= &binddn_var
;
1410 ctmp
->valoffset
= indent
;
1411 ctmp
->keymenu
= &config_text_keymenu
;
1412 ctmp
->help
= h_config_ldap_binddn
;
1413 ctmp
->tool
= dir_edit_tool
;
1414 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,binddn_var
.name
);
1415 tmp
[sizeof(tmp
)-1] = '\0';
1416 ctmp
->varname
= cpystr(tmp
);
1417 ctmp
->varnamep
= ctmp
;
1418 ctmp
->value
= pretty_value(ps
, ctmp
);
1421 new_confline(&ctmp
);
1422 ctmp
->help_title
= _("HELP FOR SERVER NICKNAME");
1423 ctmp
->var
= &nick_var
;
1424 ctmp
->valoffset
= indent
;
1425 ctmp
->keymenu
= &config_text_keymenu
;
1426 ctmp
->help
= h_config_ldap_nick
;
1427 ctmp
->tool
= dir_edit_tool
;
1428 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,nick_var
.name
);
1429 tmp
[sizeof(tmp
)-1] = '\0';
1430 ctmp
->varname
= cpystr(tmp
);
1431 ctmp
->varnamep
= ctmp
;
1432 ctmp
->value
= pretty_value(ps
, ctmp
);
1435 new_confline(&ctmp
);
1436 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1439 new_confline(&ctmp
);
1440 ctmp
->var
= &opt_var
;
1441 ctmp
->keymenu
= &config_checkbox_keymenu
;
1442 ctmp
->help
= NO_HELP
;
1444 snprintf(tmp
, sizeof(tmp
), "%s =", opt_var
.name
);
1445 tmp
[sizeof(tmp
)-1] = '\0';
1446 ctmp
->varname
= cpystr(tmp
);
1447 ctmp
->varnamep
= ctmpb
= ctmp
;
1448 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1450 new_confline(&ctmp
);
1452 ctmp
->valoffset
= rindent
;
1453 ctmp
->keymenu
= &config_checkbox_keymenu
;
1454 ctmp
->help
= NO_HELP
;
1455 ctmp
->tool
= ldap_checkbox_tool
;
1456 ctmp
->varnamep
= ctmpb
;
1457 ctmp
->flags
|= CF_NOSELECT
;
1458 ctmp
->value
= cpystr("Set Feature Name");
1460 new_confline(&ctmp
);
1462 ctmp
->valoffset
= rindent
;
1463 ctmp
->keymenu
= &config_checkbox_keymenu
;
1464 ctmp
->help
= NO_HELP
;
1465 ctmp
->tool
= ldap_checkbox_tool
;
1466 ctmp
->varnamep
= ctmpb
;
1467 ctmp
->flags
|= CF_NOSELECT
;
1468 ctmp
->value
= cpystr(set_choose
);
1470 /* find longest value's name */
1471 for(lv
= 0, i
= 0; (f
= ldap_feature_list(i
)); i
++)
1472 if(lv
< (j
= utf8_width(f
->name
)))
1477 /* enabling ldaps disables tls */
1478 if((f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
1479 && bitnset(f
->value
, ldap_option_list
)){
1481 if((f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
1482 && bitnset(f
->value
, ldap_option_list
)){
1484 clrbitn(f
->value
, ldap_option_list
);
1486 if((f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
1487 && bitnset(f
->value
, ldap_option_list
)){
1489 clrbitn(f
->value
, ldap_option_list
);
1492 q_status_message(SM_ORDER
, 3, 3,
1493 _("Can not use TLS when connecting using LDAPS"));
1496 /* enabling tls disables ldaps */
1497 if(((f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
1498 && bitnset(f
->value
, ldap_option_list
))
1499 || ((f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
1500 && bitnset(f
->value
, ldap_option_list
))){
1501 if((f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
1502 && bitnset(f
->value
, ldap_option_list
)){
1503 clrbitn(f
->value
, ldap_option_list
);
1504 q_status_message(SM_ORDER
, 3, 3,
1505 _("Can not use LDAPS when connecting using TLS"));
1509 for(i
= 0; (f
= ldap_feature_list(i
)); i
++){
1510 new_confline(&ctmp
);
1511 ctmp
->var
= &opt_var
;
1512 ctmp
->help_title
= _("HELP FOR LDAP FEATURES");
1513 ctmp
->varnamep
= ctmpb
;
1514 ctmp
->keymenu
= &config_checkbox_keymenu
;
1517 ctmp
->help
= h_config_ldap_opts_impl
;
1520 ctmp
->help
= h_config_ldap_opts_rhs
;
1523 ctmp
->help
= h_config_ldap_opts_ref
;
1526 ctmp
->help
= h_config_ldap_opts_nosub
;
1529 ctmp
->help
= h_config_ldap_opts_tls
;
1531 case LDAP_F_TLSMUST
:
1532 ctmp
->help
= h_config_ldap_opts_tlsmust
;
1535 ctmp
->help
= h_config_ldap_opts_ldaps
;
1539 ctmp
->tool
= ldap_checkbox_tool
;
1540 ctmp
->valoffset
= rindent
;
1542 utf8_snprintf(tmp
, sizeof(tmp
), "[%c] %-*.*w",
1543 bitnset(f
->value
, ldap_option_list
) ? 'X' : ' ',
1545 tmp
[sizeof(tmp
)-1] = '\0';
1546 ctmp
->value
= cpystr(tmp
);
1550 new_confline(&ctmp
);
1551 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1554 new_confline(&ctmp
);
1555 ctmp
->var
= &srch_type_var
;
1556 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1557 ctmp
->help
= NO_HELP
;
1559 snprintf(tmp
, sizeof(tmp
), "%s =", srch_type_var
.name
);
1560 tmp
[sizeof(tmp
)-1] = '\0';
1561 ctmp
->varname
= cpystr(tmp
);
1562 ctmp
->varnamep
= ctmpb
= ctmp
;
1563 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1565 new_confline(&ctmp
);
1567 ctmp
->valoffset
= rindent
;
1568 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1569 ctmp
->help
= NO_HELP
;
1571 ctmp
->varnamep
= ctmpb
;
1572 ctmp
->flags
|= CF_NOSELECT
;
1573 ctmp
->value
= cpystr("Set Rule Values");
1575 new_confline(&ctmp
);
1577 ctmp
->valoffset
= rindent
;
1578 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1579 ctmp
->help
= NO_HELP
;
1580 ctmp
->tool
= ldap_radiobutton_tool
;
1581 ctmp
->varnamep
= ctmpb
;
1582 ctmp
->flags
|= CF_NOSELECT
;
1583 ctmp
->value
= cpystr(set_choose
);
1585 /* find longest value's name */
1586 for(lv
= 0, i
= 0; (f
= ldap_search_types(i
)); i
++)
1587 if(lv
< (j
= utf8_width(f
->name
)))
1592 for(i
= 0; (f
= ldap_search_types(i
)); i
++){
1593 new_confline(&ctmp
);
1594 ctmp
->help_title
= _("HELP FOR SEARCH TYPE");
1595 ctmp
->var
= &srch_type_var
;
1596 ctmp
->valoffset
= rindent
;
1597 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1598 ctmp
->help
= h_config_ldap_searchtypes
;
1600 ctmp
->tool
= ldap_radiobutton_tool
;
1601 ctmp
->varnamep
= ctmpb
;
1602 utf8_snprintf(tmp
, sizeof(tmp
), "(%c) %-*.*w", (((!def
|| def
->type
== -1) &&
1603 f
->value
== DEF_LDAP_TYPE
) ||
1604 (def
&& f
->value
== def
->type
))
1607 tmp
[sizeof(tmp
)-1] = '\0';
1608 ctmp
->value
= cpystr(tmp
);
1612 new_confline(&ctmp
);
1613 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1614 ctmp
->varname
= cpystr("");
1617 new_confline(&ctmp
);
1618 ctmp
->var
= &srch_rule_var
;
1619 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1620 ctmp
->help
= NO_HELP
;
1622 snprintf(tmp
, sizeof(tmp
), "%s =", srch_rule_var
.name
);
1623 tmp
[sizeof(tmp
)-1] = '\0';
1624 ctmp
->varname
= cpystr(tmp
);
1625 ctmp
->varnamep
= ctmpb
= ctmp
;
1626 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1629 new_confline(&ctmp
);
1631 ctmp
->valoffset
= rindent
;
1632 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1633 ctmp
->help
= NO_HELP
;
1635 ctmp
->varnamep
= ctmpb
;
1636 ctmp
->flags
|= CF_NOSELECT
;
1637 ctmp
->value
= cpystr("Set Rule Values");
1639 new_confline(&ctmp
);
1641 ctmp
->valoffset
= rindent
;
1642 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1643 ctmp
->help
= NO_HELP
;
1644 ctmp
->tool
= ldap_radiobutton_tool
;
1645 ctmp
->varnamep
= ctmpb
;
1646 ctmp
->flags
|= CF_NOSELECT
;
1647 ctmp
->value
= cpystr(set_choose
);
1649 /* find longest value's name */
1650 for(lv
= 0, i
= 0; (f
= ldap_search_rules(i
)); i
++)
1651 if(lv
< (j
= utf8_width(f
->name
)))
1656 for(i
= 0; (f
= ldap_search_rules(i
)); i
++){
1657 new_confline(&ctmp
);
1658 ctmp
->help_title
= _("HELP FOR SEARCH RULE");
1659 ctmp
->var
= &srch_rule_var
;
1660 ctmp
->valoffset
= rindent
;
1661 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1662 ctmp
->help
= h_config_ldap_searchrules
;
1664 ctmp
->tool
= ldap_radiobutton_tool
;
1665 ctmp
->varnamep
= ctmpb
;
1666 utf8_snprintf(tmp
, sizeof(tmp
), "(%c) %-*.*w", (((!def
|| def
->srch
== -1) &&
1667 f
->value
== DEF_LDAP_SRCH
) ||
1668 (def
&& f
->value
== def
->srch
))
1671 tmp
[sizeof(tmp
)-1] = '\0';
1672 ctmp
->value
= cpystr(tmp
);
1676 new_confline(&ctmp
);
1677 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1678 ctmp
->varname
= cpystr("");
1680 /* Email attribute name */
1681 new_confline(&ctmp
);
1682 ctmp
->help_title
= _("HELP FOR EMAIL ATTRIBUTE NAME");
1683 ctmp
->var
= &mailattr_var
;
1684 ctmp
->valoffset
= indent
;
1685 ctmp
->keymenu
= &config_text_keymenu
;
1686 ctmp
->help
= h_config_ldap_email_attr
;
1687 ctmp
->tool
= dir_edit_tool
;
1688 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,mailattr_var
.name
);
1689 tmp
[sizeof(tmp
)-1] = '\0';
1690 ctmp
->varname
= cpystr(tmp
);
1691 ctmp
->varnamep
= ctmp
;
1692 ctmp
->value
= pretty_value(ps
, ctmp
);
1694 /* Name attribute name */
1695 new_confline(&ctmp
);
1696 ctmp
->help_title
= _("HELP FOR NAME ATTRIBUTE NAME");
1697 ctmp
->var
= &cnattr_var
;
1698 ctmp
->valoffset
= indent
;
1699 ctmp
->keymenu
= &config_text_keymenu
;
1700 ctmp
->help
= h_config_ldap_cn_attr
;
1701 ctmp
->tool
= dir_edit_tool
;
1702 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,cnattr_var
.name
);
1703 tmp
[sizeof(tmp
)-1] = '\0';
1704 ctmp
->varname
= cpystr(tmp
);
1705 ctmp
->varnamep
= ctmp
;
1706 ctmp
->value
= pretty_value(ps
, ctmp
);
1708 /* Surname attribute name */
1709 new_confline(&ctmp
);
1710 ctmp
->help_title
= _("HELP FOR SURNAME ATTRIBUTE NAME");
1711 ctmp
->var
= &snattr_var
;
1712 ctmp
->valoffset
= indent
;
1713 ctmp
->keymenu
= &config_text_keymenu
;
1714 ctmp
->help
= h_config_ldap_sn_attr
;
1715 ctmp
->tool
= dir_edit_tool
;
1716 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,snattr_var
.name
);
1717 tmp
[sizeof(tmp
)-1] = '\0';
1718 ctmp
->varname
= cpystr(tmp
);
1719 ctmp
->varnamep
= ctmp
;
1720 ctmp
->value
= pretty_value(ps
, ctmp
);
1722 /* Givenname attribute name */
1723 new_confline(&ctmp
);
1724 ctmp
->help_title
= _("HELP FOR GIVEN NAME ATTRIBUTE NAME");
1725 ctmp
->var
= &gnattr_var
;
1726 ctmp
->valoffset
= indent
;
1727 ctmp
->keymenu
= &config_text_keymenu
;
1728 ctmp
->help
= h_config_ldap_gn_attr
;
1729 ctmp
->tool
= dir_edit_tool
;
1730 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,gnattr_var
.name
);
1731 tmp
[sizeof(tmp
)-1] = '\0';
1732 ctmp
->varname
= cpystr(tmp
);
1733 ctmp
->varnamep
= ctmp
;
1734 ctmp
->value
= pretty_value(ps
, ctmp
);
1737 new_confline(&ctmp
);
1738 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1739 ctmp
->varname
= cpystr("");
1742 new_confline(&ctmp
);
1743 ctmp
->help_title
= _("HELP FOR SERVER TIMELIMIT");
1744 ctmp
->var
= &time_var
;
1745 ctmp
->valoffset
= indent
;
1746 ctmp
->keymenu
= &config_text_keymenu
;
1747 ctmp
->help
= h_config_ldap_time
;
1748 ctmp
->tool
= dir_edit_tool
;
1749 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,time_var
.name
);
1750 tmp
[sizeof(tmp
)-1] = '\0';
1751 ctmp
->varname
= cpystr(tmp
);
1752 ctmp
->varnamep
= ctmp
;
1753 ctmp
->value
= pretty_value(ps
, ctmp
);
1754 ctmp
->flags
|= CF_NUMBER
;
1757 new_confline(&ctmp
);
1758 ctmp
->var
= &size_var
;
1759 ctmp
->help_title
= _("HELP FOR SERVER SIZELIMIT");
1760 ctmp
->valoffset
= indent
;
1761 ctmp
->keymenu
= &config_text_keymenu
;
1762 ctmp
->help
= h_config_ldap_size
;
1763 ctmp
->tool
= dir_edit_tool
;
1764 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,size_var
.name
);
1765 tmp
[sizeof(tmp
)-1] = '\0';
1766 ctmp
->varname
= cpystr(tmp
);
1767 ctmp
->varnamep
= ctmp
;
1768 ctmp
->value
= pretty_value(ps
, ctmp
);
1769 ctmp
->flags
|= CF_NUMBER
;
1772 new_confline(&ctmp
);
1773 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1775 /* Custom Search Filter */
1776 new_confline(&ctmp
);
1777 ctmp
->help_title
= _("HELP FOR CUSTOM SEARCH FILTER");
1778 ctmp
->var
= &cust_var
;
1779 ctmp
->valoffset
= indent
;
1780 ctmp
->keymenu
= &config_text_keymenu
;
1781 ctmp
->help
= h_config_ldap_cust
;
1782 ctmp
->tool
= dir_edit_tool
;
1783 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,cust_var
.name
);
1784 tmp
[sizeof(tmp
)-1] = '\0';
1785 ctmp
->varname
= cpystr(tmp
);
1786 ctmp
->varnamep
= ctmp
;
1787 ctmp
->value
= pretty_value(ps
, ctmp
);
1790 snprintf(tmp
, sizeof(tmp
), "%s DIRECTORY SERVER", title
);
1791 tmp
[sizeof(tmp
)-1] = '\0';
1792 memset(&screen
, 0, sizeof(screen
));
1793 screen
.ro_warning
= saved_screen
? saved_screen
->deferred_ro_warning
: 0;
1794 /* TRANSLATORS: Print something1 using something2.
1795 servers is something1 */
1796 rv
= conf_scroll_screen(ps
, &screen
, first_line
, tmp
, _("servers"), 0, NULL
);
1799 * Now look at the fake variables and extract the information we
1803 if(rv
== 1 && raw_server
){
1804 char dir_tmp
[2200+MAXPATH
], *p
;
1805 int portval
= -1, timeval
= -1, sizeval
= -1;
1807 apval
= APVAL(&server_var
, ew
);
1811 apval
= APVAL(&base_var
, ew
);
1815 apval
= APVAL(&port_var
, ew
);
1819 apval
= APVAL(&binddn_var
, ew
);
1823 apval
= APVAL(&nick_var
, ew
);
1827 apval
= APVAL(&srch_type_var
, ew
);
1831 apval
= APVAL(&srch_rule_var
, ew
);
1835 apval
= APVAL(&time_var
, ew
);
1839 apval
= APVAL(&size_var
, ew
);
1843 apval
= APVAL(&cust_var
, ew
);
1847 apval
= APVAL(&mailattr_var
, ew
);
1851 apval
= APVAL(&snattr_var
, ew
);
1855 apval
= APVAL(&gnattr_var
, ew
);
1859 apval
= APVAL(&cnattr_var
, ew
);
1864 removing_leading_and_trailing_white_space(server
);
1867 removing_leading_and_trailing_white_space(base
);
1868 (void)removing_double_quotes(base
);
1869 p
= add_backslash_escapes(base
);
1870 fs_give((void **)&base
);
1875 removing_leading_and_trailing_white_space(port
);
1877 portval
= atoi(port
);
1881 removing_leading_and_trailing_white_space(binddn
);
1882 (void)removing_double_quotes(binddn
);
1883 p
= add_backslash_escapes(binddn
);
1884 fs_give((void **)&binddn
);
1889 removing_leading_and_trailing_white_space(nick
);
1890 (void)removing_double_quotes(nick
);
1891 p
= add_backslash_escapes(nick
);
1892 fs_give((void **)&nick
);
1897 removing_leading_and_trailing_white_space(ttime
);
1899 timeval
= atoi(ttime
);
1903 removing_leading_and_trailing_white_space(ssize
);
1905 sizeval
= atoi(ssize
);
1909 removing_leading_and_trailing_white_space(cust
);
1910 p
= add_backslash_escapes(cust
);
1911 fs_give((void **)&cust
);
1916 removing_leading_and_trailing_white_space(mailattr
);
1917 p
= add_backslash_escapes(mailattr
);
1918 fs_give((void **)&mailattr
);
1923 removing_leading_and_trailing_white_space(snattr
);
1924 p
= add_backslash_escapes(snattr
);
1925 fs_give((void **)&snattr
);
1930 removing_leading_and_trailing_white_space(gnattr
);
1931 p
= add_backslash_escapes(gnattr
);
1932 fs_give((void **)&gnattr
);
1937 removing_leading_and_trailing_white_space(cnattr
);
1938 p
= add_backslash_escapes(cnattr
);
1939 fs_give((void **)&cnattr
);
1944 * Don't allow user to edit scope but if one is present then we
1945 * leave it (so they could edit it by hand).
1947 if(def
&& def
->scope
!= -1 && def
->scope
!= DEF_LDAP_SCOPE
){
1950 v
= ldap_search_scope(def
->scope
);
1952 snprintf(custom_scope
, sizeof(custom_scope
), "/scope=%s", v
->name
);
1953 custom_scope
[sizeof(custom_scope
)-1] = '\0';
1957 snprintf(dir_tmp
, sizeof(dir_tmp
), "%s%s%s \"/base=%s/binddn=%s/impl=%d/rhs=%d/ref=%d/nosub=%d/tls=%d/tlsm=%d/ldaps=%d/type=%s/srch=%s%s/time=%s/size=%s/cust=%s/nick=%s/matr=%s/catr=%s/satr=%s/gatr=%s\"",
1958 server
? server
: "",
1959 (portval
>= 0 && port
&& *port
) ? ":" : "",
1960 (portval
>= 0 && port
&& *port
) ? port
: "",
1962 binddn
? binddn
: "",
1963 bitnset(LDAP_F_IMPL
, ldap_option_list
) ? 1 : 0,
1964 bitnset(LDAP_F_RHS
, ldap_option_list
) ? 1 : 0,
1965 bitnset(LDAP_F_REF
, ldap_option_list
) ? 1 : 0,
1966 bitnset(LDAP_F_NOSUB
, ldap_option_list
) ? 1 : 0,
1967 bitnset(LDAP_F_TLS
, ldap_option_list
) ? 1 : 0,
1968 bitnset(LDAP_F_TLSMUST
, ldap_option_list
) ? 1 : 0,
1969 bitnset(LDAP_F_LDAPS
, ldap_option_list
) ? 1 : 0,
1970 srch_type
? srch_type
: "",
1971 srch_rule
? srch_rule
: "",
1973 (timeval
>= 0 && ttime
&& *ttime
) ? ttime
: "",
1974 (sizeval
>= 0 && ssize
&& *ssize
) ? ssize
: "",
1977 mailattr
? mailattr
: "",
1978 cnattr
? cnattr
: "",
1979 snattr
? snattr
: "",
1980 gnattr
? gnattr
: "");
1981 dir_tmp
[sizeof(dir_tmp
)-1] = '\0';
1983 *raw_server
= cpystr(dir_tmp
);
1986 for(j
= 0; varlist
[j
]; j
++){
1988 if(v
->current_val
.p
)
1989 fs_give((void **)&v
->current_val
.p
);
1991 fs_give((void **)&v
->global_val
.p
);
1992 if(v
->main_user_val
.p
)
1993 fs_give((void **)&v
->main_user_val
.p
);
1994 if(v
->post_user_val
.p
)
1995 fs_give((void **)&v
->post_user_val
.p
);
1997 fs_give((void **)&v
->name
);
2001 fs_give((void **)&server
);
2003 fs_give((void **)&base
);
2005 fs_give((void **)&port
);
2007 fs_give((void **)&binddn
);
2009 fs_give((void **)&nick
);
2011 fs_give((void **)&srch_type
);
2013 fs_give((void **)&srch_rule
);
2015 fs_give((void **)&ttime
);
2017 fs_give((void **)&ssize
);
2019 fs_give((void **)&mailattr
);
2021 fs_give((void **)&cnattr
);
2023 fs_give((void **)&snattr
);
2025 fs_give((void **)&gnattr
);
2027 fs_give((void **)&cust
);
2029 opt_screen
= saved_screen
;
2030 ps
->mangled_screen
= 1;
2036 * Just calls text_tool except for intercepting MC_EXIT.
2039 dir_edit_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2042 return(config_exit_cmd(flags
));
2044 return(text_tool(ps
, cmd
, cl
, flags
));
2049 * Delete LDAP directory entry
2052 dir_config_del(struct pine
*ps
, CONF_S
**cl
)
2057 if(fixed_var((*cl
)->var
, NULL
, NULL
)){
2058 if((*cl
)->var
->post_user_val
.l
|| (*cl
)->var
->main_user_val
.l
){
2059 if(want_to(_("Delete (unused) directory servers "),
2060 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y'){
2062 delete_user_vals((*cl
)->var
);
2066 q_status_message(SM_ORDER
, 3, 3,
2067 _("Can't delete sys-admin defined value"));
2070 int cnt
, ans
= 0, no_ex
;
2071 char **new_list
, **lval
, **nelval
;
2073 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
2075 /* This can't happen, intercepted at caller by first_one case */
2076 nelval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
2077 lval
= LVAL((*cl
)->var
, ew
);
2078 if(lval
&& lval
[0] && lval
[0][0] == '\0')
2081 /* how many servers defined? */
2082 for(cnt
= 0; nelval
[cnt
]; cnt
++)
2086 * If using default and there is more than one in list, ask if user
2087 * wants to ignore them all or delete just this one. If just this
2088 * one, copy rest to user_val. If ignore all, copy "" to user_val
2091 if(!lval
&& cnt
> 1){
2092 static ESCKEY_S opts
[] = {
2093 {'i', 'i', "I", N_("Ignore All")},
2094 {'r', 'r', "R", N_("Remove One")},
2095 {-1, 0, NULL
, NULL
}};
2096 ans
= radio_buttons(
2097 _("Ignore all default directory servers or just remove this one ? "),
2098 -FOOTER_ROWS(ps
), opts
, 'i', 'x',
2099 h_ab_del_dir_ignore
, RB_NORM
);
2103 snprintf(prompt
, sizeof(prompt
), _("Really delete %s \"%s\" from directory servers "),
2104 ((*cl
)->value
&& *(*cl
)->value
)
2107 ((*cl
)->value
&& *(*cl
)->value
)
2109 : int2string((*cl
)->varmem
+ 1));
2110 prompt
[sizeof(prompt
)-1] = '\0';
2114 ps
->mangled_footer
= 1;
2116 rv
= ps
->mangled_body
= 1;
2119 * Ignore all of default by adding an empty string. Make it
2120 * look just like there are no servers defined.
2123 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
2124 new_list
[0] = cpystr("");
2126 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2127 free_list_array(&new_list
);
2128 *cl
= first_confline(*cl
);
2130 opt_screen
->top_line
= NULL
;
2132 add_ldap_fake_first_server(ps
, cl
, &ps
->vars
[V_LDAP_SERVERS
],
2133 &dir_conf_km
, h_direct_config
,
2136 else if(ans
== 'r' ||
2138 want_to(prompt
, 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y')){
2141 int move_top
= 0, this_one
, revert_to_default
,
2142 default_there_to_revert_to
= 0;
2145 * Remove one from current list.
2148 rv
= ps
->mangled_body
= 1;
2150 this_one
= (*cl
)->varmem
;
2152 /* might have to re-adjust screen to see new current */
2153 move_top
= (this_one
> 0) &&
2154 (this_one
== cnt
- 1) &&
2155 (((*cl
) == opt_screen
->top_line
) ||
2156 ((*cl
)->prev
== opt_screen
->top_line
) ||
2157 ((*cl
)->prev
->prev
== opt_screen
->top_line
));
2160 * If this is last one and there is a default available, revert
2163 revert_to_default
= ((cnt
== 1) && lval
);
2165 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
2166 for(i
= 0; i
< this_one
; i
++)
2167 new_list
[i
] = cpystr(nelval
[i
]);
2169 for(i
= this_one
; i
< cnt
; i
++)
2170 new_list
[i
] = cpystr(nelval
[i
+1]);
2172 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2173 free_list_array(&new_list
);
2175 else if(revert_to_default
){
2178 alval
= ALVAL((*cl
)->var
, ew
);
2180 free_list_array(alval
);
2183 /* cnt is one and we want to hide default */
2184 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
2185 new_list
[0] = cpystr("");
2187 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2188 free_list_array(&new_list
);
2191 if(cnt
== 1){ /* delete display line for this_one */
2192 if(revert_to_default
){
2193 servers
= (*cl
)->var
->global_val
.l
;
2194 default_there_to_revert_to
= (servers
!= NULL
);
2197 *cl
= first_confline(*cl
);
2199 opt_screen
->top_line
= NULL
;
2200 if(revert_to_default
&& default_there_to_revert_to
){
2201 CONF_S
*first_line
= NULL
;
2203 q_status_message(SM_ORDER
, 0, 3,
2204 _("Reverting to default directory server"));
2205 dir_init_display(ps
, cl
, servers
,
2206 &ps
->vars
[V_LDAP_SERVERS
], &first_line
);
2210 add_ldap_fake_first_server(ps
, cl
,
2211 &ps
->vars
[V_LDAP_SERVERS
],
2212 &dir_conf_km
, h_direct_config
,
2216 else if(this_one
== cnt
- 1){ /* deleted last one */
2217 /* back up and delete it */
2219 free_conflines(&(*cl
)->next
);
2220 /* now back up to first line of this server */
2221 *cl
= (*cl
)->prev
->prev
;
2223 opt_screen
->top_line
= *cl
;
2225 else{ /* deleted one out of the middle */
2226 if(*cl
== opt_screen
->top_line
)
2227 opt_screen
->top_line
= (*cl
)->next
->next
->next
;
2230 *cl
= (*cl
)->next
; /* move to next line, then */
2231 snip_confline(&cp
); /* snip 1st deleted line */
2233 *cl
= (*cl
)->next
; /* move to next line, then */
2234 snip_confline(&cp
); /* snip 2nd deleted line */
2236 *cl
= (*cl
)->next
; /* move to next line, then */
2237 snip_confline(&cp
); /* snip 3rd deleted line */
2238 /* adjust varmems */
2239 for(cp
= *cl
; cp
; cp
= cp
->next
)
2244 q_status_message(SM_ORDER
, 0, 3, _("Server not deleted"));
2248 set_current_val((*cl
)->var
, TRUE
, FALSE
);
2249 fix_side_effects(ps
, (*cl
)->var
, 0);
2250 write_pinerc(ps
, ew
, WRP_NONE
);
2256 * Utility routine to help set up display
2259 add_ldap_fake_first_server(struct pine
*ps
, CONF_S
**ctmp
, struct variable
*var
,
2260 struct key_menu
*km
, HelpType help
,
2261 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned))
2264 (*ctmp
)->help_title
= _("HELP FOR DIRECTORY SERVER CONFIGURATION");
2265 (*ctmp
)->value
= cpystr(ADD_FIRST_LDAP_SERVER
);
2267 (*ctmp
)->varmem
= 0;
2268 (*ctmp
)->keymenu
= km
;
2269 (*ctmp
)->help
= help
;
2270 (*ctmp
)->tool
= tool
;
2271 (*ctmp
)->valoffset
= 2;
2276 * Add an ldap server to the display list.
2278 * Args before -- Insert it before current, else append it after.
2281 add_ldap_server_to_display(struct pine
*ps
, CONF_S
**ctmp
, char *serv
, char *subtitle
,
2282 struct variable
*var
, int member
, struct key_menu
*km
,
2284 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned),
2285 int before
, CONF_S
**first_line
)
2289 *first_line
= *ctmp
;
2293 * New_confline appends ctmp after old current instead of inserting
2294 * it, so we have to adjust. We have
2295 * <- a <-> b <-> p <-> c -> and want <- a <-> p <-> b <-> c ->
2298 CONF_S
*a
, *b
, *c
, *p
;
2303 a
= b
? b
->prev
: NULL
;
2319 (*ctmp
)->help_title
= _("HELP FOR DIRECTORY SERVER CONFIGURATION");
2320 (*ctmp
)->value
= serv
;
2322 (*ctmp
)->varmem
= member
;
2323 (*ctmp
)->keymenu
= km
;
2324 (*ctmp
)->help
= help
;
2325 (*ctmp
)->tool
= tool
;
2326 (*ctmp
)->flags
|= CF_STARTITEM
;
2327 (*ctmp
)->valoffset
= 4;
2330 (*ctmp
)->value
= subtitle
;
2331 (*ctmp
)->keymenu
= km
;
2332 (*ctmp
)->help
= help
;
2333 (*ctmp
)->tool
= tool
;
2334 (*ctmp
)->flags
|= CF_NOSELECT
;
2335 (*ctmp
)->valoffset
= 8;
2338 (*ctmp
)->keymenu
= km
;
2339 (*ctmp
)->help
= help
;
2340 (*ctmp
)->tool
= tool
;
2341 (*ctmp
)->flags
|= CF_NOSELECT
| CF_B_LINE
;
2342 (*ctmp
)->valoffset
= 0;
2347 * ldap option list manipulation tool
2350 * returns: -1 on unrecognized cmd, 0 if no change, 1 if change
2353 ldap_checkbox_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2358 case MC_TOGGLE
: /* mark/unmark option */
2360 toggle_ldap_option_bit(ps
, (*cl
)->varmem
, (*cl
)->var
, (*cl
)->value
);
2363 case MC_EXIT
: /* exit */
2364 rv
= config_exit_cmd(flags
);
2377 toggle_ldap_option_bit(struct pine
*ps
, int index
, struct variable
*var
, char *value
)
2381 int tlsmust_is_on_now
;
2382 int ldaps_is_on_now
;
2383 int tls_is_on_after
;
2384 int tlsmust_is_on_after
;
2385 int ldaps_is_on_after
;
2387 tls_is_on_now
= (f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
2388 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2390 tlsmust_is_on_now
= (f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
2391 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2393 ldaps_is_on_now
= (f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
2394 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2396 f
= ldap_feature_list(index
);
2399 if(bitnset(f
->value
, ldap_option_list
))
2400 clrbitn(f
->value
, ldap_option_list
);
2402 setbitn(f
->value
, ldap_option_list
);
2404 tls_is_on_after
= (f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
2405 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2407 tlsmust_is_on_after
= (f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
2408 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2410 ldaps_is_on_after
= (f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
2411 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2413 f
= ldap_feature_list(index
);
2415 if(!ldaps_is_on_now
&& ldaps_is_on_after
){
2416 if(tlsmust_is_on_after
|| tls_is_on_after
){
2418 if(tlsmust_is_on_after
)
2419 name
= ldap_feature_list(LDAP_F_TLSMUST
)->name
;
2421 name
= ldap_feature_list(LDAP_F_TLS
)->name
;
2422 clrbitn(f
->value
, ldap_option_list
);
2423 q_status_message1(SM_ORDER
, 3, 3,
2424 _("Can not use LDAPS when using TLS. Disable \"%s\" first."), name
);
2427 else if(!tls_is_on_now
&& tls_is_on_after
){
2428 if(ldaps_is_on_after
){
2429 char *name
= ldap_feature_list(LDAP_F_LDAPS
)->name
;
2430 clrbitn(f
->value
, ldap_option_list
);
2431 q_status_message1(SM_ORDER
, 3, 3,
2432 _("Can not use TLS when using LDAPS. Disable \"%s\" first."), name
);
2435 else if(!tlsmust_is_on_now
&& tlsmust_is_on_after
){
2436 if(ldaps_is_on_after
){
2437 char *name
= ldap_feature_list(LDAP_F_LDAPS
)->name
;
2438 clrbitn(f
->value
, ldap_option_list
);
2439 q_status_message1(SM_ORDER
, 3, 3,
2440 _("Can not use TLS when using LDAPS. Disable \"%s\" first."), name
);
2445 value
[1] = bitnset(f
->value
, ldap_option_list
) ? 'X' : ' ';
2450 ldap_feature_list(int index
)
2452 static NAMEVAL_S ldap_feat_list
[] = {
2453 {"use-implicitly-from-composer", NULL
, LDAP_F_IMPL
},
2454 {"lookup-addrbook-contents", NULL
, LDAP_F_RHS
},
2455 {"save-search-criteria-not-result", NULL
, LDAP_F_REF
},
2456 {"disable-ad-hoc-space-substitution", NULL
, LDAP_F_NOSUB
},
2457 {"attempt-tls-on-connection", NULL
, LDAP_F_TLS
},
2458 {"require-tls-on-connection", NULL
, LDAP_F_TLSMUST
},
2459 {"require-ldaps-on-connection", NULL
, LDAP_F_LDAPS
}
2462 return((index
>= 0 &&
2463 index
< (sizeof(ldap_feat_list
)/sizeof(ldap_feat_list
[0])))
2464 ? &ldap_feat_list
[index
] : NULL
);
2469 * simple radio-button style variable handler
2472 ldap_radiobutton_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2480 case MC_CHOICE
: /* set/unset feature */
2482 /* hunt backwards, turning off old values */
2483 for(ctmp
= *cl
; ctmp
&& !(ctmp
->flags
& CF_NOSELECT
) && !ctmp
->varname
;
2484 ctmp
= prev_confline(ctmp
))
2485 ctmp
->value
[1] = ' ';
2487 /* hunt forwards, turning off old values */
2488 for(ctmp
= *cl
; ctmp
&& !(ctmp
->flags
& CF_NOSELECT
) && !ctmp
->varname
;
2489 ctmp
= next_confline(ctmp
))
2490 ctmp
->value
[1] = ' ';
2492 /* turn on current value */
2493 (*cl
)->value
[1] = R_SELD
;
2495 if((*cl
)->var
== ldap_srch_rule_ptr
)
2496 rule
= ldap_search_rules((*cl
)->varmem
);
2498 rule
= ldap_search_types((*cl
)->varmem
);
2500 apval
= APVAL((*cl
)->var
, ew
);
2502 fs_give((void **)apval
);
2505 *apval
= cpystr(rule
->name
);
2507 ps
->mangled_body
= 1; /* BUG: redraw it all for now? */
2512 case MC_EXIT
: /* exit */
2513 rv
= config_exit_cmd(flags
);
2524 #endif /* ENABLE_LDAP */