1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: ldapconf.c 1012 2008-03-26 00:44:22Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2013-2018 Eduardo Chappa
8 * Copyright 2006-2008 University of Washington
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
24 #include "confscroll.h"
28 #include "../pith/ldap.h"
29 #include "../pith/state.h"
30 #include "../pith/bitmap.h"
31 #include "../pith/mailcmd.h"
32 #include "../pith/list.h"
39 int addr_select_tool(struct pine
*, int, CONF_S
**, unsigned);
40 void dir_init_display(struct pine
*, CONF_S
**, char **, struct variable
*, CONF_S
**);
41 int dir_config_tool(struct pine
*, int, CONF_S
**, unsigned);
42 void dir_config_add(struct pine
*, CONF_S
**);
43 void dir_config_shuffle(struct pine
*, CONF_S
**);
44 void dir_config_edit(struct pine
*, CONF_S
**);
45 int dir_edit_screen(struct pine
*, LDAP_SERV_S
*, char *, char **);
46 int dir_edit_tool(struct pine
*, int, CONF_S
**, unsigned);
47 void dir_config_del(struct pine
*, CONF_S
**);
48 void add_ldap_fake_first_server(struct pine
*, CONF_S
**, struct variable
*,
49 struct key_menu
*, HelpType
,
50 int (*)(struct pine
*, int, CONF_S
**, unsigned));
51 void add_ldap_server_to_display(struct pine
*, CONF_S
**, char *, char *,
52 struct variable
*, int, struct key_menu
*, HelpType
,
53 int (*)(struct pine
*, int, CONF_S
**, unsigned),
55 int ldap_checkbox_tool(struct pine
*, int, CONF_S
**, unsigned);
56 void toggle_ldap_option_bit(struct pine
*, int, struct variable
*, char *);
57 NAMEVAL_S
*ldap_feature_list(int);
60 static char *srch_res_help_title
= N_("HELP FOR SEARCH RESULTS INDEX");
61 static char *set_choose
= "--- ----------------------";
62 #define ADD_FIRST_LDAP_SERVER _("Use Add to add a directory server")
63 #define ADDR_SELECT_EXIT_VAL 5
64 #define ADDR_SELECT_GOBACK_VAL 6
65 #define ADDR_SELECT_FORCED_EXIT_VAL 7
68 static int some_selectable
;
69 static char *dserv
= N_("Directory Server on ");
72 * Let user choose an ldap entry (or return an entry if user doesn't need
76 * -1 if Exit was chosen
77 * -2 if none were selectable
78 * -3 if no entries existed at all
79 * -4 go back to Abook List was chosen
80 * -5 caller shouldn't free ac->res_head
82 * When 0 is returned the winner is pointed to by result.
83 * Result is an allocated LDAP_SEARCH_WINNER_S which has pointers
84 * to the ld and entry that were chosen. Those are pointers into
85 * the initial data, not copies. The two-pointer structure is
86 * allocated here and freed by the caller.
89 ldap_addr_select(struct pine
*ps
, ADDR_CHOOSE_S
*ac
, LDAP_CHOOSE_S
**result
,
90 LDAPLookupStyle style
, WP_ERR_S
*wp_err
, char *srchstr
)
93 LDAP_SERV_RES_S
*res_list
;
94 CONF_S
*ctmpa
= NULL
, *first_line
= NULL
, *alt_first_line
= NULL
;
95 int i
, retval
= 0, got_n_mail
= 0, got_n_entries
= 0;
101 void (*prev_redrawer
) (void);
103 dprint((4, "ldap_addr_select()\n"));
105 need_mail
= (style
== AlwaysDisplay
|| style
== DisplayForURL
) ? 0 : 1;
106 if(style
== AlwaysDisplay
){
107 km
= &addr_s_km_with_view
;
108 help
= h_address_display
;
110 else if(style
== AlwaysDisplayAndMailRequired
){
111 km
= &addr_s_km_with_goback
;
112 help
= h_address_select
;
114 else if(style
== DisplayForURL
){
115 km
= &addr_s_km_for_url
;
116 help
= h_address_display
;
120 help
= h_address_select
;
128 for(res_list
= ac
->res_head
; res_list
; res_list
= res_list
->next
){
129 for(e
= ldap_first_entry(res_list
->ld
, res_list
->res
);
131 e
= ldap_next_entry(res_list
->ld
, e
)){
133 struct berval
**cn
, **org
, **unit
, **title
, **mail
, **sn
;
135 int indent
, have_mail
;
138 cn
= org
= title
= unit
= mail
= sn
= NULL
;
139 for(a
= ldap_first_attribute(res_list
->ld
, e
, &ber
);
141 a
= ldap_next_attribute(res_list
->ld
, e
, ber
)){
143 dprint((9, " %s", a
? a
: "?"));
144 if(strcmp(a
, res_list
->info_used
->cnattr
) == 0){
146 cn
= ldap_get_values_len(res_list
->ld
, e
, a
);
148 if(cn
&& !ALPINE_LDAP_can_use(cn
)){
149 ldap_value_free_len(cn
);
153 else if(strcmp(a
, res_list
->info_used
->mailattr
) == 0){
155 mail
= ldap_get_values_len(res_list
->ld
, e
, a
);
157 else if(strcmp(a
, "o") == 0){
159 org
= ldap_get_values_len(res_list
->ld
, e
, a
);
161 else if(strcmp(a
, "ou") == 0){
163 unit
= ldap_get_values_len(res_list
->ld
, e
, a
);
165 else if(strcmp(a
, "title") == 0){
167 title
= ldap_get_values_len(res_list
->ld
, e
, a
);
176 for(a
= ldap_first_attribute(res_list
->ld
, e
, &ber
);
178 a
= ldap_next_attribute(res_list
->ld
, e
, ber
)){
180 if(strcmp(a
, res_list
->info_used
->snattr
) == 0){
182 sn
= ldap_get_values_len(res_list
->ld
, e
, a
);
184 if(sn
&& !ALPINE_LDAP_can_use(sn
)){
185 ldap_value_free_len(sn
);
194 if(ALPINE_LDAP_can_use(mail
))
199 got_n_mail
+= have_mail
;
204 * First line is either cn, sn, or dn.
207 new_confline(&ctmpa
);
209 alt_first_line
= ctmpa
;
211 ctmpa
->flags
|= CF_STARTITEM
;
212 if(need_mail
&& !have_mail
)
213 ctmpa
->flags
|= CF_PRIVATE
;
215 ctmpa
->value
= cpystr(cn
[0]->bv_val
);
216 ldap_value_free_len(cn
);
217 ctmpa
->valoffset
= indent
;
220 ctmpa
->help_title
= _(srch_res_help_title
);
221 ctmpa
->tool
= addr_select_tool
;
222 ctmpa
->d
.a
.ld
= res_list
->ld
;
223 ctmpa
->d
.a
.entry
= e
;
224 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
225 ctmpa
->d
.a
.serv
= res_list
->serv
;
227 if(!first_line
&& (have_mail
|| !need_mail
))
231 /* only happens if no cn */
233 new_confline(&ctmpa
);
235 alt_first_line
= ctmpa
;
237 ctmpa
->flags
|= CF_STARTITEM
;
238 if(need_mail
&& !have_mail
)
239 ctmpa
->flags
|= CF_PRIVATE
;
241 ctmpa
->value
= cpystr(sn
[0]->bv_val
);
242 ldap_value_free_len(sn
);
243 ctmpa
->valoffset
= indent
;
246 ctmpa
->help_title
= _(srch_res_help_title
);
247 ctmpa
->tool
= addr_select_tool
;
248 ctmpa
->d
.a
.ld
= res_list
->ld
;
249 ctmpa
->d
.a
.entry
= e
;
250 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
251 ctmpa
->d
.a
.serv
= res_list
->serv
;
253 if(!first_line
&& (have_mail
|| !need_mail
))
258 new_confline(&ctmpa
);
260 alt_first_line
= ctmpa
;
262 ctmpa
->flags
|= CF_STARTITEM
;
263 if(need_mail
&& !have_mail
)
264 ctmpa
->flags
|= CF_PRIVATE
;
266 dn
= ldap_get_dn(res_list
->ld
, e
);
269 our_ldap_dn_memfree(dn
);
273 ctmpa
->value
= cpystr(dn
? dn
: "?");
275 our_ldap_dn_memfree(dn
);
277 ctmpa
->valoffset
= indent
;
280 ctmpa
->help_title
= _(srch_res_help_title
);
281 ctmpa
->tool
= addr_select_tool
;
282 ctmpa
->d
.a
.ld
= res_list
->ld
;
283 ctmpa
->d
.a
.entry
= e
;
284 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
285 ctmpa
->d
.a
.serv
= res_list
->serv
;
287 if(!first_line
&& (have_mail
|| !need_mail
))
292 for(i
= 0; ALPINE_LDAP_usable(title
, i
); i
++){
293 new_confline(&ctmpa
);
294 ctmpa
->flags
|= CF_NOSELECT
;
295 ctmpa
->valoffset
= indent
+ 2;
296 ctmpa
->value
= cpystr(title
[i
]->bv_val
);
299 ctmpa
->help_title
= _(srch_res_help_title
);
300 ctmpa
->tool
= addr_select_tool
;
301 ctmpa
->d
.a
.ld
= res_list
->ld
;
302 ctmpa
->d
.a
.entry
= e
;
303 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
304 ctmpa
->d
.a
.serv
= res_list
->serv
;
308 ldap_value_free_len(title
);
312 for(i
= 0; ALPINE_LDAP_usable(unit
, i
); i
++){
313 new_confline(&ctmpa
);
314 ctmpa
->flags
|= CF_NOSELECT
;
315 ctmpa
->valoffset
= indent
+ 2;
316 ctmpa
->value
= cpystr(unit
[i
]->bv_val
);
319 ctmpa
->help_title
= _(srch_res_help_title
);
320 ctmpa
->tool
= addr_select_tool
;
321 ctmpa
->d
.a
.ld
= res_list
->ld
;
322 ctmpa
->d
.a
.entry
= e
;
323 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
324 ctmpa
->d
.a
.serv
= res_list
->serv
;
328 ldap_value_free_len(unit
);
332 for(i
= 0; ALPINE_LDAP_usable(org
, i
); i
++){
333 new_confline(&ctmpa
);
334 ctmpa
->flags
|= CF_NOSELECT
;
335 ctmpa
->valoffset
= indent
+ 2;
336 ctmpa
->value
= cpystr(org
[i
]->bv_val
);
339 ctmpa
->help_title
= _(srch_res_help_title
);
340 ctmpa
->tool
= addr_select_tool
;
341 ctmpa
->d
.a
.ld
= res_list
->ld
;
342 ctmpa
->d
.a
.entry
= e
;
343 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
344 ctmpa
->d
.a
.serv
= res_list
->serv
;
348 ldap_value_free_len(org
);
352 /* Don't show long list of email addresses. */
353 if(!ALPINE_LDAP_can_use_num(mail
, 0) ||
354 !ALPINE_LDAP_can_use_num(mail
, 1) ||
355 !ALPINE_LDAP_can_use_num(mail
, 2) ||
356 !ALPINE_LDAP_can_use_num(mail
, 3)){
357 for(i
= 0; ALPINE_LDAP_usable(mail
, i
); i
++){
358 new_confline(&ctmpa
);
359 ctmpa
->flags
|= CF_NOSELECT
;
360 ctmpa
->valoffset
= indent
+ 2;
361 ctmpa
->value
= cpystr(mail
[i
]->bv_val
);
364 ctmpa
->help_title
= _(srch_res_help_title
);
365 ctmpa
->tool
= addr_select_tool
;
366 ctmpa
->d
.a
.ld
= res_list
->ld
;
367 ctmpa
->d
.a
.entry
= e
;
368 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
369 ctmpa
->d
.a
.serv
= res_list
->serv
;
376 for(i
= 4; ALPINE_LDAP_usable(mail
, i
); i
++)
379 new_confline(&ctmpa
);
380 ctmpa
->flags
|= CF_NOSELECT
;
381 ctmpa
->valoffset
= indent
+ 2;
382 snprintf(tmp
, sizeof(tmp
), _("(%d email addresses)"), i
);
383 tmp
[sizeof(tmp
)-1] = '\0';
384 ctmpa
->value
= cpystr(tmp
);
387 ctmpa
->help_title
= _(srch_res_help_title
);
388 ctmpa
->tool
= addr_select_tool
;
389 ctmpa
->d
.a
.ld
= res_list
->ld
;
390 ctmpa
->d
.a
.entry
= e
;
391 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
392 ctmpa
->d
.a
.serv
= res_list
->serv
;
397 new_confline(&ctmpa
);
398 ctmpa
->flags
|= CF_NOSELECT
;
399 ctmpa
->valoffset
= indent
+ 2;
400 ctmpa
->value
= cpystr(_("<No Email Address Available>"));
403 ctmpa
->help_title
= _(srch_res_help_title
);
404 ctmpa
->tool
= addr_select_tool
;
405 ctmpa
->d
.a
.ld
= res_list
->ld
;
406 ctmpa
->d
.a
.entry
= e
;
407 ctmpa
->d
.a
.info_used
= res_list
->info_used
;
408 ctmpa
->d
.a
.serv
= res_list
->serv
;
413 ldap_value_free_len(mail
);
415 new_confline(&ctmpa
); /* blank line */
418 ctmpa
->help_title
= _(srch_res_help_title
);
419 ctmpa
->tool
= addr_select_tool
;
420 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
426 else if(alt_first_line
)
427 first_line
= alt_first_line
;
429 new_confline(&ctmpa
); /* blank line */
430 ctmpa
->keymenu
= need_mail
? &addr_s_km_exit
: &addr_s_km_goback
;
432 ctmpa
->help_title
= _(srch_res_help_title
);
433 ctmpa
->tool
= addr_select_tool
;
434 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
436 new_confline(&ctmpa
);
438 strncpy(ee
, "[ ", sizeof(ee
));
439 ee
[sizeof(ee
)-1] = '\0';
440 if(wp_err
&& wp_err
->ldap_errno
)
441 /* TRANSLATORS: No matches returned for an LDAP search */
442 snprintf(ee
+2, sizeof(ee
)-2, _("%s, No Matches Returned"),
443 ldap_err2string(wp_err
->ldap_errno
));
445 strncpy(ee
+2, _("No Matches"), sizeof(ee
)-2);
447 ee
[sizeof(ee
)-1] = '\0';
449 /* TRANSLATORS: a request for user to choose Exit after they read text */
450 strncat(ee
, _(" -- Choose Exit ]"), sizeof(ee
)-strlen(ee
)-1);
451 ee
[sizeof(ee
)-1] = '\0';
452 ctmpa
->value
= cpystr(ee
);
453 ctmpa
->valoffset
= 10;
454 ctmpa
->keymenu
= need_mail
? &addr_s_km_exit
: &addr_s_km_goback
;
456 ctmpa
->help_title
= _(srch_res_help_title
);
457 ctmpa
->tool
= addr_select_tool
;
458 ctmpa
->flags
|= CF_NOSELECT
;
461 if(style
== AlwaysDisplay
|| style
== DisplayForURL
||
462 style
== AlwaysDisplayAndMailRequired
||
463 (style
== DisplayIfOne
&& got_n_mail
>= 1) ||
464 (style
== DisplayIfTwo
&& got_n_mail
>= 1 && got_n_entries
>= 2)){
465 if(wp_err
&& wp_err
->mangled
)
466 *wp_err
->mangled
= 1;
468 prev_redrawer
= ps_global
->redrawer
;
469 push_titlebar_state();
471 memset(&screen
, 0, sizeof(screen
));
472 /* TRANSLATORS: Print something1 using something2.
473 "this" is something1 */
474 switch(conf_scroll_screen(ps
,&screen
,first_line
,ac
->title
,_("this"),0, NULL
)){
475 case ADDR_SELECT_EXIT_VAL
:
479 case ADDR_SELECT_GOBACK_VAL
:
483 case ADDR_SELECT_FORCED_EXIT_VAL
:
484 if(alt_first_line
) /* some entries, but none suitable */
497 pop_titlebar_state();
499 if((ps_global
->redrawer
= prev_redrawer
) != NULL
)
500 (*ps_global
->redrawer
)();
502 if(result
&& retval
== 0 && ac
->selected_ld
&& ac
->selected_entry
){
503 (*result
) = (LDAP_CHOOSE_S
*)fs_get(sizeof(LDAP_CHOOSE_S
));
504 (*result
)->ld
= ac
->selected_ld
;
505 (*result
)->selected_entry
= ac
->selected_entry
;
506 (*result
)->info_used
= ac
->info_used
;
507 (*result
)->serv
= ac
->selected_serv
;
510 else if(style
== DisplayIfOne
&& got_n_mail
< 1){
511 if(alt_first_line
) /* some entries, but none suitable */
516 first_line
= first_confline(ctmpa
);
517 free_conflines(&first_line
);
519 else if(style
== DisplayIfTwo
&& (got_n_mail
< 1 || got_n_entries
< 2)){
521 if(alt_first_line
) /* some entries, but none suitable */
529 (*result
) = (LDAP_CHOOSE_S
*)fs_get(sizeof(LDAP_CHOOSE_S
));
530 (*result
)->ld
= first_line
->d
.a
.ld
;
531 (*result
)->selected_entry
= first_line
->d
.a
.entry
;
532 (*result
)->info_used
= first_line
->d
.a
.info_used
;
533 (*result
)->serv
= first_line
->d
.a
.serv
;
537 first_line
= first_confline(ctmpa
);
538 free_conflines(&first_line
);
546 addr_select_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
552 if(flags
& CF_PRIVATE
){
553 q_status_message(SM_ORDER
| SM_DING
, 0, 3,
554 _("No email address available for this entry; choose another or ExitSelect"));
556 else if(some_selectable
){
557 (*cl
)->d
.a
.ac
->selected_ld
= (*cl
)->d
.a
.ld
;
558 (*cl
)->d
.a
.ac
->selected_entry
= (*cl
)->d
.a
.entry
;
559 (*cl
)->d
.a
.ac
->info_used
= (*cl
)->d
.a
.info_used
;
560 (*cl
)->d
.a
.ac
->selected_serv
= (*cl
)->d
.a
.serv
;
561 retval
= simple_exit_cmd(flags
);
564 retval
= ADDR_SELECT_FORCED_EXIT_VAL
;
575 if((*cl
)->d
.a
.ld
&& (*cl
)->d
.a
.entry
){
576 e
= (LDAP_CHOOSE_S
*)fs_get(sizeof(LDAP_CHOOSE_S
));
577 e
->ld
= (*cl
)->d
.a
.ld
;
578 e
->selected_entry
= (*cl
)->d
.a
.entry
;
579 e
->info_used
= (*cl
)->d
.a
.info_used
;
580 e
->serv
= (*cl
)->d
.a
.serv
;
581 if(cmd
== MC_VIEW_TEXT
)
582 view_ldap_entry(ps
, e
);
583 else if(cmd
== MC_SAVE
)
584 save_ldap_entry(ps
, e
, 0);
585 else if(cmd
== MC_COMPOSE
)
586 compose_to_ldap_entry(ps
, e
, 0);
587 else if(cmd
== MC_ROLE
)
588 compose_to_ldap_entry(ps
, e
, 1);
590 forward_ldap_entry(ps
, e
);
592 fs_give((void **)&e
);
599 retval
= ADDR_SELECT_GOBACK_VAL
;
603 retval
= ADDR_SELECT_EXIT_VAL
;
612 ps
->mangled_body
= 1;
619 dir_init_display(struct pine
*ps
, CONF_S
**ctmp
, char **servers
,
620 struct variable
*var
, CONF_S
**first_line
)
631 if(servers
&& servers
[0] && servers
[0][0]){
632 for(i
= 0; servers
[i
]; i
++){
633 info
= break_up_ldap_server(servers
[i
]);
634 serv
= (info
&& info
->nick
&& *info
->nick
) ? cpystr(info
->nick
) :
635 (info
&& info
->serv
&& *info
->serv
) ? cpystr(info
->serv
) :
636 cpystr(_("Bad Server Config, Delete this"));
637 sizeofsub
= (((info
&& info
->serv
&& *info
->serv
)
639 : 3) + strlen(_(dserv
)) + 15) * sizeof(char);
640 subtitle
= (char *)fs_get(sizeofsub
);
641 if(info
&& info
->port
>= 0)
642 snprintf(subtitle
, sizeofsub
, "%s%s:%d",
644 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
647 snprintf(subtitle
, sizeofsub
, "%s%s",
649 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
651 subtitle
[sizeofsub
-1] = '\0';
653 add_ldap_server_to_display(ps
, ctmp
, serv
, subtitle
, var
,
654 i
, &dir_conf_km
, h_direct_config
,
656 (first_line
&& *first_line
== NULL
)
660 free_ldap_server_info(&info
);
664 add_ldap_fake_first_server(ps
, ctmp
, var
,
665 &dir_conf_km
, h_direct_config
,
674 directory_config(struct pine
*ps
, int edit_exceptions
)
676 CONF_S
*ctmp
= NULL
, *first_line
= NULL
;
678 int no_ex
, readonly_warning
= 0;
681 q_status_message(SM_ORDER
, 3, 7,
682 _("Exception Setup not implemented for directory"));
686 ew
= edit_exceptions
? ps_global
->ew_for_except_vars
: Main
;
688 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
691 readonly_warning
= 1;
693 PINERC_S
*prc
= NULL
;
706 readonly_warning
= prc
? prc
->readonly
: 1;
707 if(prc
&& prc
->quit_to_edit
){
708 quit_to_edit_msg(prc
);
713 if(ps
->fix_fixed_warning
)
714 offer_to_fix_pinerc(ps
);
716 dir_init_display(ps
, &ctmp
, no_ex
? ps
->VAR_LDAP_SERVERS
717 : LVAL(&ps
->vars
[V_LDAP_SERVERS
], ew
),
718 &ps
->vars
[V_LDAP_SERVERS
], &first_line
);
720 memset(&screen
, 0, sizeof(screen
));
721 screen
.deferred_ro_warning
= readonly_warning
;
722 /* TRANSLATORS: Print something1 using something2.
723 "servers" is something1 */
724 (void)conf_scroll_screen(ps
, &screen
, first_line
,
725 _("SETUP DIRECTORY SERVERS"), _("servers"), 0, NULL
);
726 ps
->mangled_screen
= 1;
731 dir_config_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
733 int first_one
, rv
= 0;
735 first_one
= (*cl
)->value
&&
736 (strcmp((*cl
)->value
, ADD_FIRST_LDAP_SERVER
) == 0);
740 q_status_message(SM_ORDER
|SM_DING
, 0, 3,
741 _("Nothing to Delete, use Add"));
743 dir_config_del(ps
, cl
);
748 if(!fixed_var((*cl
)->var
, NULL
, "directory list"))
749 dir_config_add(ps
, cl
);
754 if(!fixed_var((*cl
)->var
, NULL
, "directory list")){
756 dir_config_add(ps
, cl
);
758 dir_config_edit(ps
, cl
);
764 if(!fixed_var((*cl
)->var
, NULL
, "directory list")){
766 q_status_message(SM_ORDER
|SM_DING
, 0, 3,
767 _("Nothing to Shuffle, use Add"));
769 dir_config_shuffle(ps
, cl
);
788 * Add LDAP directory entry
791 dir_config_add(struct pine
*ps
, CONF_S
**cl
)
793 char *raw_server
= NULL
;
794 LDAP_SERV_S
*info
= NULL
;
798 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
800 if(dir_edit_screen(ps
, NULL
, "ADD A", &raw_server
) == 1){
802 info
= break_up_ldap_server(raw_server
);
804 if(info
&& info
->serv
&& *info
->serv
){
811 lval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
816 /* catch the special "" case */
818 (cnt
== 1 && lval
[0][0] == '\0')){
819 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
820 new_list
[0] = raw_server
;
824 /* add one for new value */
826 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
828 for(i
= 0; i
< (*cl
)->varmem
; i
++)
829 new_list
[i
] = cpystr(lval
[i
]);
831 new_list
[(*cl
)->varmem
] = raw_server
;
833 for(i
= (*cl
)->varmem
; i
< cnt
; i
++)
834 new_list
[i
+1] = cpystr(lval
[i
]);
838 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
839 free_list_array(&new_list
);
840 set_current_val((*cl
)->var
, TRUE
, FALSE
);
841 sizeofsub
= (((info
&& info
->serv
&& *info
->serv
)
843 : 3) + strlen(_(dserv
)) + 15) * sizeof(char);
844 subtitle
= (char *)fs_get(sizeofsub
);
845 if(info
&& info
->port
>= 0)
846 snprintf(subtitle
, sizeofsub
, "%s%s:%d",
848 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
851 snprintf(subtitle
, sizeofsub
, "%s%s",
853 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
855 subtitle
[sizeofsub
-1] = '\0';
857 if(cnt
< 2){ /* first one */
858 struct variable
*var
;
859 struct key_menu
*keymenu
;
861 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned);
864 keymenu
= (*cl
)->keymenu
;
867 *cl
= first_confline(*cl
);
869 add_ldap_server_to_display(ps
, cl
,
870 (info
&& info
->nick
&& *info
->nick
)
872 : cpystr(info
->serv
),
873 subtitle
, var
, 0, keymenu
, help
,
876 opt_screen
->top_line
= NULL
;
882 add_ldap_server_to_display(ps
, cl
,
883 (info
&& info
->nick
&& *info
->nick
)
885 : cpystr(info
->serv
),
894 /* adjust the rest of the varmems */
895 for(cp
= (*cl
)->next
; cp
; cp
= cp
->next
)
899 /* because add_ldap advanced cl to its third line */
900 (*cl
) = (*cl
)->prev
->prev
;
902 fix_side_effects(ps
, (*cl
)->var
, 0);
903 write_pinerc(ps
, ew
, WRP_NONE
);
906 q_status_message(SM_ORDER
, 0, 3, _("Add cancelled, no server name"));
909 free_ldap_server_info(&info
);
911 fs_give((void **)&raw_server
);
916 * Shuffle order of LDAP directory entries
919 dir_config_shuffle(struct pine
*ps
, CONF_S
**cl
)
921 int cnt
, rv
, current_num
, new_num
, i
, j
, deefault
;
922 char **new_list
, **lval
;
929 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
931 /* how many are in our current list? */
932 lval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
933 for(cnt
= 0; lval
&& lval
[cnt
]; cnt
++)
937 q_status_message(SM_ORDER
, 0, 3,
938 _("Shuffle only makes sense when there is more than one server in list"));
942 current_num
= (*cl
)->varmem
; /* variable number of highlighted directory */
944 /* Move it up or down? */
949 opts
[i
++].label
= _("Up");
954 opts
[i
++].label
= _("Down");
959 if(current_num
== 0){ /* no up */
963 else if(current_num
== cnt
- 1) /* no down */
966 snprintf(tmp
, sizeof(tmp
), "Shuffle \"%s\" %s%s%s ? ",
968 (opts
[0].ch
!= -2) ? _("UP") : "",
969 (opts
[0].ch
!= -2 && opts
[1].ch
!= -2) ? " or " : "",
970 (opts
[1].ch
!= -2) ? _("DOWN") : "");
971 tmp
[sizeof(tmp
)-1] = '\0';
972 help
= (opts
[0].ch
== -2) ? h_dir_shuf_down
973 : (opts
[1].ch
== -2) ? h_dir_shuf_up
976 rv
= radio_buttons(tmp
, -FOOTER_ROWS(ps
), opts
, deefault
, 'x',
981 cmd_cancelled("Shuffle");
985 new_num
= current_num
- 1;
986 a
= (*cl
)->prev
->prev
->prev
;
991 new_num
= current_num
+ 1;
993 b
= (*cl
)->next
->next
->next
;
997 /* allocate space for new list */
998 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
1000 /* fill in new_list */
1001 for(i
= 0; i
< cnt
; i
++){
1002 if(i
== current_num
)
1004 else if (i
== new_num
)
1009 /* notice this works even if we were using default */
1010 new_list
[i
] = cpystr(lval
[j
]);
1015 j
= set_variable_list((*cl
)->var
- ps
->vars
, new_list
, TRUE
, ew
);
1016 free_list_array(&new_list
);
1018 q_status_message(SM_ORDER
, 0, 3,
1019 _("Shuffle cancelled: couldn't save configuration file"));
1020 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1024 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1026 if(a
== opt_screen
->top_line
)
1027 opt_screen
->top_line
= b
;
1030 a
->varmem
= b
->varmem
;
1034 * Swap display lines. To start with, a is lower in list, b is higher.
1035 * The fact that there are 3 lines per entry is totally entangled in
1038 a
->next
->next
->next
= b
->next
->next
->next
;
1039 if(b
->next
->next
->next
)
1040 b
->next
->next
->next
->prev
= a
->next
->next
;
1044 b
->next
->next
->next
= a
;
1045 a
->prev
= b
->next
->next
;
1047 ps
->mangled_body
= 1;
1048 write_pinerc(ps
, ew
, WRP_NONE
);
1053 * Edit LDAP directory entry
1056 dir_config_edit(struct pine
*ps
, CONF_S
**cl
)
1058 char *raw_server
= NULL
, **lval
;
1062 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
1064 lval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
1065 info
= break_up_ldap_server((lval
&& lval
[(*cl
)->varmem
])
1066 ? lval
[(*cl
)->varmem
] : NULL
);
1068 if(dir_edit_screen(ps
, info
, "CHANGE THIS", &raw_server
) == 1){
1070 free_ldap_server_info(&info
);
1071 info
= break_up_ldap_server(raw_server
);
1073 if(lval
&& lval
[(*cl
)->varmem
] &&
1074 strcmp(lval
[(*cl
)->varmem
], raw_server
) == 0)
1075 q_status_message(SM_ORDER
, 0, 3, _("No change, cancelled"));
1076 else if(!(info
&& info
->serv
&& *info
->serv
))
1077 q_status_message(SM_ORDER
, 0, 3,
1078 _("Change cancelled, use Delete if you want to remove this server"));
1085 for(cnt
= 0; lval
&& lval
[cnt
]; cnt
++)
1088 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
1090 for(i
= 0; i
< (*cl
)->varmem
; i
++)
1091 new_list
[i
] = cpystr(lval
[i
]);
1093 new_list
[(*cl
)->varmem
] = raw_server
;
1096 for(i
= (*cl
)->varmem
+ 1; i
< cnt
; i
++)
1097 new_list
[i
] = cpystr(lval
[i
]);
1099 new_list
[cnt
] = NULL
;
1100 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
1101 free_list_array(&new_list
);
1102 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1105 fs_give((void **)&(*cl
)->value
);
1107 (*cl
)->value
= cpystr((info
->nick
&& *info
->nick
) ? info
->nick
1110 if((*cl
)->next
->value
)
1111 fs_give((void **)&(*cl
)->next
->value
);
1113 sizeofsub
= (((info
&& info
->serv
&& *info
->serv
)
1114 ? strlen(info
->serv
)
1115 : 3) + strlen(_(dserv
)) + 15) * sizeof(char);
1117 subtitle
= (char *)fs_get(sizeofsub
);
1118 if(info
&& info
->port
>= 0)
1119 snprintf(subtitle
, sizeofsub
, "%s%s:%d",
1121 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
1124 snprintf(subtitle
, sizeofsub
, "%s%s",
1126 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
1128 subtitle
[sizeofsub
] = '\0';
1130 (*cl
)->next
->value
= subtitle
;
1132 fix_side_effects(ps
, (*cl
)->var
, 0);
1133 write_pinerc(ps
, ew
, WRP_NONE
);
1137 free_ldap_server_info(&info
);
1139 fs_give((void **)&raw_server
);
1143 #define LDAP_F_IMPL 0
1144 #define LDAP_F_RHS 1
1145 #define LDAP_F_REF 2
1146 #define LDAP_F_NOSUB 3
1147 #define LDAP_F_TLS 4
1148 #define LDAP_F_TLSMUST 5
1149 #define LDAP_F_LDAPS 6
1150 bitmap_t ldap_option_list
;
1151 struct variable
*ldap_srch_rule_ptr
;
1154 * Gives user screen to edit config values for ldap server.
1156 * Args ps -- pine struct
1157 * def -- default values to start with
1158 * title -- part of title at top of screen
1159 * raw_server -- This is the returned item, allocated here and freed by caller.
1161 * Returns: 0 if no change
1162 * 1 if user requested a change
1163 * (change is stored in raw_server and hasn't been acted upon yet)
1164 * 10 user says abort
1167 dir_edit_screen(struct pine
*ps
, LDAP_SERV_S
*def
, char *title
, char **raw_server
)
1169 OPT_SCREEN_S screen
, *saved_screen
;
1170 CONF_S
*ctmp
= NULL
, *ctmpb
, *first_line
= NULL
;
1171 char tmp
[MAXPATH
+1], custom_scope
[MAXPATH
], **apval
;
1172 int rv
, i
, j
, lv
, indent
, rindent
;
1174 struct variable server_var
, base_var
, binddn_var
, port_var
, nick_var
,
1175 srch_type_var
, srch_rule_var
, time_var
,
1176 size_var
, mailattr_var
, cnattr_var
,
1177 snattr_var
, gnattr_var
, cust_var
,
1178 opt_var
, *v
, *varlist
[21];
1179 char *server
= NULL
, *base
= NULL
, *port
= NULL
, *nick
= NULL
,
1180 *srch_type
= NULL
, *srch_rule
= NULL
, *ttime
= NULL
,
1181 *c_s_f
= "custom-search-filter", *binddn
= NULL
,
1182 *ssize
= NULL
, *mailattr
= NULL
, *cnattr
= NULL
,
1183 *snattr
= NULL
, *gnattr
= NULL
, *cust
= NULL
;
1186 * We edit by making a nested call to conf_scroll_screen.
1187 * We use some fake struct variables to get back the results in, and
1188 * so we can use the existing tools from the config screen.
1191 custom_scope
[0] = '\0';
1193 varlist
[j
= 0] = &server_var
;
1194 varlist
[++j
] = &base_var
;
1195 varlist
[++j
] = &port_var
;
1196 varlist
[++j
] = &binddn_var
;
1197 varlist
[++j
] = &nick_var
;
1198 varlist
[++j
] = &srch_type_var
;
1199 varlist
[++j
] = &srch_rule_var
;
1200 varlist
[++j
] = &time_var
;
1201 varlist
[++j
] = &size_var
;
1202 varlist
[++j
] = &mailattr_var
;
1203 varlist
[++j
] = &cnattr_var
;
1204 varlist
[++j
] = &snattr_var
;
1205 varlist
[++j
] = &gnattr_var
;
1206 varlist
[++j
] = &cust_var
;
1207 varlist
[++j
] = &opt_var
;
1208 varlist
[++j
] = NULL
;
1209 for(j
= 0; varlist
[j
]; j
++)
1210 memset(varlist
[j
], 0, sizeof(struct variable
));
1212 server_var
.name
= cpystr("ldap-server");
1213 server_var
.is_used
= 1;
1214 server_var
.is_user
= 1;
1215 apval
= APVAL(&server_var
, ew
);
1216 *apval
= (def
&& def
->serv
&& def
->serv
[0]) ? cpystr(def
->serv
) : NULL
;
1217 set_current_val(&server_var
, FALSE
, FALSE
);
1219 base_var
.name
= cpystr("search-base");
1220 base_var
.is_used
= 1;
1221 base_var
.is_user
= 1;
1222 apval
= APVAL(&base_var
, ew
);
1223 *apval
= (def
&& def
->base
&& def
->base
[0]) ? cpystr(def
->base
) : NULL
;
1224 set_current_val(&base_var
, FALSE
, FALSE
);
1226 port_var
.name
= cpystr("port");
1227 port_var
.is_used
= 1;
1228 port_var
.is_user
= 1;
1229 if(def
&& def
->port
>= 0){
1230 apval
= APVAL(&port_var
, ew
);
1231 *apval
= cpystr(int2string(def
->port
));
1234 port_var
.global_val
.p
= cpystr(int2string(LDAP_PORT
));
1235 set_current_val(&port_var
, FALSE
, FALSE
);
1237 binddn_var
.name
= cpystr("bind-dn");
1238 binddn_var
.is_used
= 1;
1239 binddn_var
.is_user
= 1;
1240 apval
= APVAL(&binddn_var
, ew
);
1241 *apval
= (def
&& def
->binddn
&& def
->binddn
[0]) ? cpystr(def
->binddn
) : NULL
;
1242 set_current_val(&binddn_var
, FALSE
, FALSE
);
1244 nick_var
.name
= cpystr("nickname");
1245 nick_var
.is_used
= 1;
1246 nick_var
.is_user
= 1;
1247 apval
= APVAL(&nick_var
, ew
);
1248 *apval
= (def
&& def
->nick
&& def
->nick
[0]) ? cpystr(def
->nick
) : NULL
;
1249 set_current_val(&nick_var
, FALSE
, FALSE
);
1251 srch_type_var
.name
= cpystr("search-type");
1252 srch_type_var
.is_used
= 1;
1253 srch_type_var
.is_user
= 1;
1254 apval
= APVAL(&srch_type_var
, ew
);
1255 *apval
= (f
=ldap_search_types(def
? def
->type
: -1))
1256 ? cpystr(f
->name
) : NULL
;
1257 srch_type_var
.global_val
.p
=
1258 (f
=ldap_search_types(DEF_LDAP_TYPE
)) ? cpystr(f
->name
) : NULL
;
1259 set_current_val(&srch_type_var
, FALSE
, FALSE
);
1261 ldap_srch_rule_ptr
= &srch_rule_var
; /* so radiobuttons can tell */
1262 srch_rule_var
.name
= cpystr("search-rule");
1263 srch_rule_var
.is_used
= 1;
1264 srch_rule_var
.is_user
= 1;
1265 apval
= APVAL(&srch_rule_var
, ew
);
1266 *apval
= (f
=ldap_search_rules(def
? def
->srch
: -1))
1267 ? cpystr(f
->name
) : NULL
;
1268 srch_rule_var
.global_val
.p
=
1269 (f
=ldap_search_rules(DEF_LDAP_SRCH
)) ? cpystr(f
->name
) : NULL
;
1270 set_current_val(&srch_rule_var
, FALSE
, FALSE
);
1272 time_var
.name
= cpystr("timelimit");
1273 time_var
.is_used
= 1;
1274 time_var
.is_user
= 1;
1275 if(def
&& def
->time
>= 0){
1276 apval
= APVAL(&time_var
, ew
);
1277 *apval
= cpystr(int2string(def
->time
));
1280 time_var
.global_val
.p
= cpystr(int2string(DEF_LDAP_TIME
));
1281 set_current_val(&time_var
, FALSE
, FALSE
);
1283 size_var
.name
= cpystr("sizelimit");
1284 size_var
.is_used
= 1;
1285 size_var
.is_user
= 1;
1286 if(def
&& def
->size
>= 0){
1287 apval
= APVAL(&size_var
, ew
);
1288 *apval
= cpystr(int2string(def
->size
));
1291 size_var
.global_val
.p
= cpystr(int2string(DEF_LDAP_SIZE
));
1292 set_current_val(&size_var
, FALSE
, FALSE
);
1294 mailattr_var
.name
= cpystr("email-attribute");
1295 mailattr_var
.is_used
= 1;
1296 mailattr_var
.is_user
= 1;
1297 apval
= APVAL(&mailattr_var
, ew
);
1298 *apval
= (def
&& def
->mailattr
&& def
->mailattr
[0])
1299 ? cpystr(def
->mailattr
) : NULL
;
1300 mailattr_var
.global_val
.p
= cpystr(DEF_LDAP_MAILATTR
);
1301 set_current_val(&mailattr_var
, FALSE
, FALSE
);
1303 cnattr_var
.name
= cpystr("name-attribute");
1304 cnattr_var
.is_used
= 1;
1305 cnattr_var
.is_user
= 1;
1306 apval
= APVAL(&cnattr_var
, ew
);
1307 *apval
= (def
&& def
->cnattr
&& def
->cnattr
[0])
1308 ? cpystr(def
->cnattr
) : NULL
;
1309 cnattr_var
.global_val
.p
= cpystr(DEF_LDAP_CNATTR
);
1310 set_current_val(&cnattr_var
, FALSE
, FALSE
);
1312 snattr_var
.name
= cpystr("surname-attribute");
1313 snattr_var
.is_used
= 1;
1314 snattr_var
.is_user
= 1;
1315 apval
= APVAL(&snattr_var
, ew
);
1316 *apval
= (def
&& def
->snattr
&& def
->snattr
[0])
1317 ? cpystr(def
->snattr
) : NULL
;
1318 snattr_var
.global_val
.p
= cpystr(DEF_LDAP_SNATTR
);
1319 set_current_val(&snattr_var
, FALSE
, FALSE
);
1321 gnattr_var
.name
= cpystr("givenname-attribute");
1322 gnattr_var
.is_used
= 1;
1323 gnattr_var
.is_user
= 1;
1324 apval
= APVAL(&gnattr_var
, ew
);
1325 *apval
= (def
&& def
->gnattr
&& def
->gnattr
[0])
1326 ? cpystr(def
->gnattr
) : NULL
;
1327 gnattr_var
.global_val
.p
= cpystr(DEF_LDAP_GNATTR
);
1328 set_current_val(&gnattr_var
, FALSE
, FALSE
);
1330 cust_var
.name
= cpystr(c_s_f
);
1331 cust_var
.is_used
= 1;
1332 cust_var
.is_user
= 1;
1333 apval
= APVAL(&cust_var
, ew
);
1334 *apval
= (def
&& def
->cust
&& def
->cust
[0]) ? cpystr(def
->cust
) : NULL
;
1335 set_current_val(&cust_var
, FALSE
, FALSE
);
1337 /* TRANSLATORS: Features is a section title in the LDAP configuration screen. Following
1338 this are a list of features or options that can be turned on or off. */
1339 opt_var
.name
= cpystr(_("Features"));
1340 opt_var
.is_used
= 1;
1341 opt_var
.is_user
= 1;
1342 opt_var
.is_list
= 1;
1343 clrbitmap(ldap_option_list
);
1344 if(def
&& def
->impl
)
1345 setbitn(LDAP_F_IMPL
, ldap_option_list
);
1347 setbitn(LDAP_F_RHS
, ldap_option_list
);
1349 setbitn(LDAP_F_REF
, ldap_option_list
);
1350 if(def
&& def
->nosub
)
1351 setbitn(LDAP_F_NOSUB
, ldap_option_list
);
1353 setbitn(LDAP_F_TLS
, ldap_option_list
);
1354 if(def
&& def
->tlsmust
)
1355 setbitn(LDAP_F_TLSMUST
, ldap_option_list
);
1356 if(def
&& def
->ldaps
)
1357 setbitn(LDAP_F_LDAPS
, ldap_option_list
);
1359 /* save the old opt_screen before calling scroll screen again */
1360 saved_screen
= opt_screen
;
1362 indent
= utf8_width(c_s_f
) + 3;
1366 new_confline(&ctmp
);
1367 ctmp
->help_title
= _("HELP FOR LDAP SERVER");
1368 ctmp
->var
= &server_var
;
1369 ctmp
->valoffset
= indent
;
1370 ctmp
->keymenu
= &config_text_keymenu
;
1371 ctmp
->help
= h_config_ldap_server
;
1372 ctmp
->tool
= dir_edit_tool
;
1373 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,server_var
.name
);
1374 tmp
[sizeof(tmp
)-1] = '\0';
1375 ctmp
->varname
= cpystr(tmp
);
1376 ctmp
->varnamep
= ctmp
;
1377 ctmp
->value
= pretty_value(ps
, ctmp
);
1382 new_confline(&ctmp
);
1383 ctmp
->help_title
= _("HELP FOR SERVER SEARCH BASE");
1384 ctmp
->var
= &base_var
;
1385 ctmp
->valoffset
= indent
;
1386 ctmp
->keymenu
= &config_text_keymenu
;
1387 ctmp
->help
= h_config_ldap_base
;
1388 ctmp
->tool
= dir_edit_tool
;
1389 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,base_var
.name
);
1390 tmp
[sizeof(tmp
)-1] = '\0';
1391 ctmp
->varname
= cpystr(tmp
);
1392 ctmp
->varnamep
= ctmp
;
1393 ctmp
->value
= pretty_value(ps
, ctmp
);
1396 new_confline(&ctmp
);
1397 ctmp
->help_title
= _("HELP FOR PORT NUMBER");
1398 ctmp
->var
= &port_var
;
1399 ctmp
->valoffset
= indent
;
1400 ctmp
->keymenu
= &config_text_keymenu
;
1401 ctmp
->help
= h_config_ldap_port
;
1402 ctmp
->tool
= dir_edit_tool
;
1403 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,port_var
.name
);
1404 tmp
[sizeof(tmp
)-1] = '\0';
1405 ctmp
->varname
= cpystr(tmp
);
1406 ctmp
->varnamep
= ctmp
;
1407 ctmp
->value
= pretty_value(ps
, ctmp
);
1408 ctmp
->flags
|= CF_NUMBER
;
1410 /* Bind DN (DN to bind to if needed) */
1411 new_confline(&ctmp
);
1412 ctmp
->help_title
= _("HELP FOR SERVER BIND DN");
1413 ctmp
->var
= &binddn_var
;
1414 ctmp
->valoffset
= indent
;
1415 ctmp
->keymenu
= &config_text_keymenu
;
1416 ctmp
->help
= h_config_ldap_binddn
;
1417 ctmp
->tool
= dir_edit_tool
;
1418 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,binddn_var
.name
);
1419 tmp
[sizeof(tmp
)-1] = '\0';
1420 ctmp
->varname
= cpystr(tmp
);
1421 ctmp
->varnamep
= ctmp
;
1422 ctmp
->value
= pretty_value(ps
, ctmp
);
1425 new_confline(&ctmp
);
1426 ctmp
->help_title
= _("HELP FOR SERVER NICKNAME");
1427 ctmp
->var
= &nick_var
;
1428 ctmp
->valoffset
= indent
;
1429 ctmp
->keymenu
= &config_text_keymenu
;
1430 ctmp
->help
= h_config_ldap_nick
;
1431 ctmp
->tool
= dir_edit_tool
;
1432 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,nick_var
.name
);
1433 tmp
[sizeof(tmp
)-1] = '\0';
1434 ctmp
->varname
= cpystr(tmp
);
1435 ctmp
->varnamep
= ctmp
;
1436 ctmp
->value
= pretty_value(ps
, ctmp
);
1439 new_confline(&ctmp
);
1440 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1443 new_confline(&ctmp
);
1444 ctmp
->var
= &opt_var
;
1445 ctmp
->keymenu
= &config_checkbox_keymenu
;
1446 ctmp
->help
= NO_HELP
;
1448 snprintf(tmp
, sizeof(tmp
), "%s =", opt_var
.name
);
1449 tmp
[sizeof(tmp
)-1] = '\0';
1450 ctmp
->varname
= cpystr(tmp
);
1451 ctmp
->varnamep
= ctmpb
= ctmp
;
1452 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1454 new_confline(&ctmp
);
1456 ctmp
->valoffset
= rindent
;
1457 ctmp
->keymenu
= &config_checkbox_keymenu
;
1458 ctmp
->help
= NO_HELP
;
1459 ctmp
->tool
= ldap_checkbox_tool
;
1460 ctmp
->varnamep
= ctmpb
;
1461 ctmp
->flags
|= CF_NOSELECT
;
1462 ctmp
->value
= cpystr("Set Feature Name");
1464 new_confline(&ctmp
);
1466 ctmp
->valoffset
= rindent
;
1467 ctmp
->keymenu
= &config_checkbox_keymenu
;
1468 ctmp
->help
= NO_HELP
;
1469 ctmp
->tool
= ldap_checkbox_tool
;
1470 ctmp
->varnamep
= ctmpb
;
1471 ctmp
->flags
|= CF_NOSELECT
;
1472 ctmp
->value
= cpystr(set_choose
);
1474 /* find longest value's name */
1475 for(lv
= 0, i
= 0; (f
= ldap_feature_list(i
)); i
++)
1476 if(lv
< (j
= utf8_width(f
->name
)))
1481 /* enabling ldaps disables tls */
1482 if((f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
1483 && bitnset(f
->value
, ldap_option_list
)){
1485 if((f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
1486 && bitnset(f
->value
, ldap_option_list
)){
1488 clrbitn(f
->value
, ldap_option_list
);
1490 if((f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
1491 && bitnset(f
->value
, ldap_option_list
)){
1493 clrbitn(f
->value
, ldap_option_list
);
1496 q_status_message(SM_ORDER
, 3, 3,
1497 _("Can not use TLS when connecting using LDAPS"));
1500 /* enabling tls disables ldaps */
1501 if(((f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
1502 && bitnset(f
->value
, ldap_option_list
))
1503 || ((f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
1504 && bitnset(f
->value
, ldap_option_list
))){
1505 if((f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
1506 && bitnset(f
->value
, ldap_option_list
)){
1507 clrbitn(f
->value
, ldap_option_list
);
1508 q_status_message(SM_ORDER
, 3, 3,
1509 _("Can not use LDAPS when connecting using TLS"));
1513 for(i
= 0; (f
= ldap_feature_list(i
)); i
++){
1514 new_confline(&ctmp
);
1515 ctmp
->var
= &opt_var
;
1516 ctmp
->help_title
= _("HELP FOR LDAP FEATURES");
1517 ctmp
->varnamep
= ctmpb
;
1518 ctmp
->keymenu
= &config_checkbox_keymenu
;
1521 ctmp
->help
= h_config_ldap_opts_impl
;
1524 ctmp
->help
= h_config_ldap_opts_rhs
;
1527 ctmp
->help
= h_config_ldap_opts_ref
;
1530 ctmp
->help
= h_config_ldap_opts_nosub
;
1533 ctmp
->help
= h_config_ldap_opts_tls
;
1535 case LDAP_F_TLSMUST
:
1536 ctmp
->help
= h_config_ldap_opts_tlsmust
;
1539 ctmp
->help
= h_config_ldap_opts_ldaps
;
1543 ctmp
->tool
= ldap_checkbox_tool
;
1544 ctmp
->valoffset
= rindent
;
1546 utf8_snprintf(tmp
, sizeof(tmp
), "[%c] %-*.*w",
1547 bitnset(f
->value
, ldap_option_list
) ? 'X' : ' ',
1549 tmp
[sizeof(tmp
)-1] = '\0';
1550 ctmp
->value
= cpystr(tmp
);
1554 new_confline(&ctmp
);
1555 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1558 new_confline(&ctmp
);
1559 ctmp
->var
= &srch_type_var
;
1560 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1561 ctmp
->help
= NO_HELP
;
1563 snprintf(tmp
, sizeof(tmp
), "%s =", srch_type_var
.name
);
1564 tmp
[sizeof(tmp
)-1] = '\0';
1565 ctmp
->varname
= cpystr(tmp
);
1566 ctmp
->varnamep
= ctmpb
= ctmp
;
1567 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1569 new_confline(&ctmp
);
1571 ctmp
->valoffset
= rindent
;
1572 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1573 ctmp
->help
= NO_HELP
;
1575 ctmp
->varnamep
= ctmpb
;
1576 ctmp
->flags
|= CF_NOSELECT
;
1577 ctmp
->value
= cpystr("Set Rule Values");
1579 new_confline(&ctmp
);
1581 ctmp
->valoffset
= rindent
;
1582 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1583 ctmp
->help
= NO_HELP
;
1584 ctmp
->tool
= ldap_radiobutton_tool
;
1585 ctmp
->varnamep
= ctmpb
;
1586 ctmp
->flags
|= CF_NOSELECT
;
1587 ctmp
->value
= cpystr(set_choose
);
1589 /* find longest value's name */
1590 for(lv
= 0, i
= 0; (f
= ldap_search_types(i
)); i
++)
1591 if(lv
< (j
= utf8_width(f
->name
)))
1596 for(i
= 0; (f
= ldap_search_types(i
)); i
++){
1597 new_confline(&ctmp
);
1598 ctmp
->help_title
= _("HELP FOR SEARCH TYPE");
1599 ctmp
->var
= &srch_type_var
;
1600 ctmp
->valoffset
= rindent
;
1601 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1602 ctmp
->help
= h_config_ldap_searchtypes
;
1604 ctmp
->tool
= ldap_radiobutton_tool
;
1605 ctmp
->varnamep
= ctmpb
;
1606 utf8_snprintf(tmp
, sizeof(tmp
), "(%c) %-*.*w", (((!def
|| def
->type
== -1) &&
1607 f
->value
== DEF_LDAP_TYPE
) ||
1608 (def
&& f
->value
== def
->type
))
1611 tmp
[sizeof(tmp
)-1] = '\0';
1612 ctmp
->value
= cpystr(tmp
);
1616 new_confline(&ctmp
);
1617 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1618 ctmp
->varname
= cpystr("");
1621 new_confline(&ctmp
);
1622 ctmp
->var
= &srch_rule_var
;
1623 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1624 ctmp
->help
= NO_HELP
;
1626 snprintf(tmp
, sizeof(tmp
), "%s =", srch_rule_var
.name
);
1627 tmp
[sizeof(tmp
)-1] = '\0';
1628 ctmp
->varname
= cpystr(tmp
);
1629 ctmp
->varnamep
= ctmpb
= ctmp
;
1630 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1633 new_confline(&ctmp
);
1635 ctmp
->valoffset
= rindent
;
1636 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1637 ctmp
->help
= NO_HELP
;
1639 ctmp
->varnamep
= ctmpb
;
1640 ctmp
->flags
|= CF_NOSELECT
;
1641 ctmp
->value
= cpystr("Set Rule Values");
1643 new_confline(&ctmp
);
1645 ctmp
->valoffset
= rindent
;
1646 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1647 ctmp
->help
= NO_HELP
;
1648 ctmp
->tool
= ldap_radiobutton_tool
;
1649 ctmp
->varnamep
= ctmpb
;
1650 ctmp
->flags
|= CF_NOSELECT
;
1651 ctmp
->value
= cpystr(set_choose
);
1653 /* find longest value's name */
1654 for(lv
= 0, i
= 0; (f
= ldap_search_rules(i
)); i
++)
1655 if(lv
< (j
= utf8_width(f
->name
)))
1660 for(i
= 0; (f
= ldap_search_rules(i
)); i
++){
1661 new_confline(&ctmp
);
1662 ctmp
->help_title
= _("HELP FOR SEARCH RULE");
1663 ctmp
->var
= &srch_rule_var
;
1664 ctmp
->valoffset
= rindent
;
1665 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1666 ctmp
->help
= h_config_ldap_searchrules
;
1668 ctmp
->tool
= ldap_radiobutton_tool
;
1669 ctmp
->varnamep
= ctmpb
;
1670 utf8_snprintf(tmp
, sizeof(tmp
), "(%c) %-*.*w", (((!def
|| def
->srch
== -1) &&
1671 f
->value
== DEF_LDAP_SRCH
) ||
1672 (def
&& f
->value
== def
->srch
))
1675 tmp
[sizeof(tmp
)-1] = '\0';
1676 ctmp
->value
= cpystr(tmp
);
1680 new_confline(&ctmp
);
1681 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1682 ctmp
->varname
= cpystr("");
1684 /* Email attribute name */
1685 new_confline(&ctmp
);
1686 ctmp
->help_title
= _("HELP FOR EMAIL ATTRIBUTE NAME");
1687 ctmp
->var
= &mailattr_var
;
1688 ctmp
->valoffset
= indent
;
1689 ctmp
->keymenu
= &config_text_keymenu
;
1690 ctmp
->help
= h_config_ldap_email_attr
;
1691 ctmp
->tool
= dir_edit_tool
;
1692 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,mailattr_var
.name
);
1693 tmp
[sizeof(tmp
)-1] = '\0';
1694 ctmp
->varname
= cpystr(tmp
);
1695 ctmp
->varnamep
= ctmp
;
1696 ctmp
->value
= pretty_value(ps
, ctmp
);
1698 /* Name attribute name */
1699 new_confline(&ctmp
);
1700 ctmp
->help_title
= _("HELP FOR NAME ATTRIBUTE NAME");
1701 ctmp
->var
= &cnattr_var
;
1702 ctmp
->valoffset
= indent
;
1703 ctmp
->keymenu
= &config_text_keymenu
;
1704 ctmp
->help
= h_config_ldap_cn_attr
;
1705 ctmp
->tool
= dir_edit_tool
;
1706 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,cnattr_var
.name
);
1707 tmp
[sizeof(tmp
)-1] = '\0';
1708 ctmp
->varname
= cpystr(tmp
);
1709 ctmp
->varnamep
= ctmp
;
1710 ctmp
->value
= pretty_value(ps
, ctmp
);
1712 /* Surname attribute name */
1713 new_confline(&ctmp
);
1714 ctmp
->help_title
= _("HELP FOR SURNAME ATTRIBUTE NAME");
1715 ctmp
->var
= &snattr_var
;
1716 ctmp
->valoffset
= indent
;
1717 ctmp
->keymenu
= &config_text_keymenu
;
1718 ctmp
->help
= h_config_ldap_sn_attr
;
1719 ctmp
->tool
= dir_edit_tool
;
1720 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,snattr_var
.name
);
1721 tmp
[sizeof(tmp
)-1] = '\0';
1722 ctmp
->varname
= cpystr(tmp
);
1723 ctmp
->varnamep
= ctmp
;
1724 ctmp
->value
= pretty_value(ps
, ctmp
);
1726 /* Givenname attribute name */
1727 new_confline(&ctmp
);
1728 ctmp
->help_title
= _("HELP FOR GIVEN NAME ATTRIBUTE NAME");
1729 ctmp
->var
= &gnattr_var
;
1730 ctmp
->valoffset
= indent
;
1731 ctmp
->keymenu
= &config_text_keymenu
;
1732 ctmp
->help
= h_config_ldap_gn_attr
;
1733 ctmp
->tool
= dir_edit_tool
;
1734 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,gnattr_var
.name
);
1735 tmp
[sizeof(tmp
)-1] = '\0';
1736 ctmp
->varname
= cpystr(tmp
);
1737 ctmp
->varnamep
= ctmp
;
1738 ctmp
->value
= pretty_value(ps
, ctmp
);
1741 new_confline(&ctmp
);
1742 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1743 ctmp
->varname
= cpystr("");
1746 new_confline(&ctmp
);
1747 ctmp
->help_title
= _("HELP FOR SERVER TIMELIMIT");
1748 ctmp
->var
= &time_var
;
1749 ctmp
->valoffset
= indent
;
1750 ctmp
->keymenu
= &config_text_keymenu
;
1751 ctmp
->help
= h_config_ldap_time
;
1752 ctmp
->tool
= dir_edit_tool
;
1753 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,time_var
.name
);
1754 tmp
[sizeof(tmp
)-1] = '\0';
1755 ctmp
->varname
= cpystr(tmp
);
1756 ctmp
->varnamep
= ctmp
;
1757 ctmp
->value
= pretty_value(ps
, ctmp
);
1758 ctmp
->flags
|= CF_NUMBER
;
1761 new_confline(&ctmp
);
1762 ctmp
->var
= &size_var
;
1763 ctmp
->help_title
= _("HELP FOR SERVER SIZELIMIT");
1764 ctmp
->valoffset
= indent
;
1765 ctmp
->keymenu
= &config_text_keymenu
;
1766 ctmp
->help
= h_config_ldap_size
;
1767 ctmp
->tool
= dir_edit_tool
;
1768 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,size_var
.name
);
1769 tmp
[sizeof(tmp
)-1] = '\0';
1770 ctmp
->varname
= cpystr(tmp
);
1771 ctmp
->varnamep
= ctmp
;
1772 ctmp
->value
= pretty_value(ps
, ctmp
);
1773 ctmp
->flags
|= CF_NUMBER
;
1776 new_confline(&ctmp
);
1777 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1779 /* Custom Search Filter */
1780 new_confline(&ctmp
);
1781 ctmp
->help_title
= _("HELP FOR CUSTOM SEARCH FILTER");
1782 ctmp
->var
= &cust_var
;
1783 ctmp
->valoffset
= indent
;
1784 ctmp
->keymenu
= &config_text_keymenu
;
1785 ctmp
->help
= h_config_ldap_cust
;
1786 ctmp
->tool
= dir_edit_tool
;
1787 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,cust_var
.name
);
1788 tmp
[sizeof(tmp
)-1] = '\0';
1789 ctmp
->varname
= cpystr(tmp
);
1790 ctmp
->varnamep
= ctmp
;
1791 ctmp
->value
= pretty_value(ps
, ctmp
);
1794 snprintf(tmp
, sizeof(tmp
), "%s DIRECTORY SERVER", title
);
1795 tmp
[sizeof(tmp
)-1] = '\0';
1796 memset(&screen
, 0, sizeof(screen
));
1797 screen
.ro_warning
= saved_screen
? saved_screen
->deferred_ro_warning
: 0;
1798 /* TRANSLATORS: Print something1 using something2.
1799 servers is something1 */
1800 rv
= conf_scroll_screen(ps
, &screen
, first_line
, tmp
, _("servers"), 0, NULL
);
1803 * Now look at the fake variables and extract the information we
1807 if(rv
== 1 && raw_server
){
1808 char dir_tmp
[2200], *p
;
1809 int portval
= -1, timeval
= -1, sizeval
= -1;
1811 apval
= APVAL(&server_var
, ew
);
1815 apval
= APVAL(&base_var
, ew
);
1819 apval
= APVAL(&port_var
, ew
);
1823 apval
= APVAL(&binddn_var
, ew
);
1827 apval
= APVAL(&nick_var
, ew
);
1831 apval
= APVAL(&srch_type_var
, ew
);
1835 apval
= APVAL(&srch_rule_var
, ew
);
1839 apval
= APVAL(&time_var
, ew
);
1843 apval
= APVAL(&size_var
, ew
);
1847 apval
= APVAL(&cust_var
, ew
);
1851 apval
= APVAL(&mailattr_var
, ew
);
1855 apval
= APVAL(&snattr_var
, ew
);
1859 apval
= APVAL(&gnattr_var
, ew
);
1863 apval
= APVAL(&cnattr_var
, ew
);
1868 removing_leading_and_trailing_white_space(server
);
1871 removing_leading_and_trailing_white_space(base
);
1872 (void)removing_double_quotes(base
);
1873 p
= add_backslash_escapes(base
);
1874 fs_give((void **)&base
);
1879 removing_leading_and_trailing_white_space(port
);
1881 portval
= atoi(port
);
1885 removing_leading_and_trailing_white_space(binddn
);
1886 (void)removing_double_quotes(binddn
);
1887 p
= add_backslash_escapes(binddn
);
1888 fs_give((void **)&binddn
);
1893 removing_leading_and_trailing_white_space(nick
);
1894 (void)removing_double_quotes(nick
);
1895 p
= add_backslash_escapes(nick
);
1896 fs_give((void **)&nick
);
1901 removing_leading_and_trailing_white_space(ttime
);
1903 timeval
= atoi(ttime
);
1907 removing_leading_and_trailing_white_space(ssize
);
1909 sizeval
= atoi(ssize
);
1913 removing_leading_and_trailing_white_space(cust
);
1914 p
= add_backslash_escapes(cust
);
1915 fs_give((void **)&cust
);
1920 removing_leading_and_trailing_white_space(mailattr
);
1921 p
= add_backslash_escapes(mailattr
);
1922 fs_give((void **)&mailattr
);
1927 removing_leading_and_trailing_white_space(snattr
);
1928 p
= add_backslash_escapes(snattr
);
1929 fs_give((void **)&snattr
);
1934 removing_leading_and_trailing_white_space(gnattr
);
1935 p
= add_backslash_escapes(gnattr
);
1936 fs_give((void **)&gnattr
);
1941 removing_leading_and_trailing_white_space(cnattr
);
1942 p
= add_backslash_escapes(cnattr
);
1943 fs_give((void **)&cnattr
);
1948 * Don't allow user to edit scope but if one is present then we
1949 * leave it (so they could edit it by hand).
1951 if(def
&& def
->scope
!= -1 && def
->scope
!= DEF_LDAP_SCOPE
){
1954 v
= ldap_search_scope(def
->scope
);
1956 snprintf(custom_scope
, sizeof(custom_scope
), "/scope=%s", v
->name
);
1957 custom_scope
[sizeof(custom_scope
)-1] = '\0';
1961 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\"",
1962 server
? server
: "",
1963 (portval
>= 0 && port
&& *port
) ? ":" : "",
1964 (portval
>= 0 && port
&& *port
) ? port
: "",
1966 binddn
? binddn
: "",
1967 bitnset(LDAP_F_IMPL
, ldap_option_list
) ? 1 : 0,
1968 bitnset(LDAP_F_RHS
, ldap_option_list
) ? 1 : 0,
1969 bitnset(LDAP_F_REF
, ldap_option_list
) ? 1 : 0,
1970 bitnset(LDAP_F_NOSUB
, ldap_option_list
) ? 1 : 0,
1971 bitnset(LDAP_F_TLS
, ldap_option_list
) ? 1 : 0,
1972 bitnset(LDAP_F_TLSMUST
, ldap_option_list
) ? 1 : 0,
1973 bitnset(LDAP_F_LDAPS
, ldap_option_list
) ? 1 : 0,
1974 srch_type
? srch_type
: "",
1975 srch_rule
? srch_rule
: "",
1977 (timeval
>= 0 && ttime
&& *ttime
) ? ttime
: "",
1978 (sizeval
>= 0 && ssize
&& *ssize
) ? ssize
: "",
1981 mailattr
? mailattr
: "",
1982 cnattr
? cnattr
: "",
1983 snattr
? snattr
: "",
1984 gnattr
? gnattr
: "");
1985 dir_tmp
[sizeof(dir_tmp
)-1] = '\0';
1987 *raw_server
= cpystr(dir_tmp
);
1990 for(j
= 0; varlist
[j
]; j
++){
1992 if(v
->current_val
.p
)
1993 fs_give((void **)&v
->current_val
.p
);
1995 fs_give((void **)&v
->global_val
.p
);
1996 if(v
->main_user_val
.p
)
1997 fs_give((void **)&v
->main_user_val
.p
);
1998 if(v
->post_user_val
.p
)
1999 fs_give((void **)&v
->post_user_val
.p
);
2001 fs_give((void **)&v
->name
);
2005 fs_give((void **)&server
);
2007 fs_give((void **)&base
);
2009 fs_give((void **)&port
);
2011 fs_give((void **)&binddn
);
2013 fs_give((void **)&nick
);
2015 fs_give((void **)&srch_type
);
2017 fs_give((void **)&srch_rule
);
2019 fs_give((void **)&ttime
);
2021 fs_give((void **)&ssize
);
2023 fs_give((void **)&mailattr
);
2025 fs_give((void **)&cnattr
);
2027 fs_give((void **)&snattr
);
2029 fs_give((void **)&gnattr
);
2031 fs_give((void **)&cust
);
2033 opt_screen
= saved_screen
;
2034 ps
->mangled_screen
= 1;
2040 * Just calls text_tool except for intercepting MC_EXIT.
2043 dir_edit_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2046 return(config_exit_cmd(flags
));
2048 return(text_tool(ps
, cmd
, cl
, flags
));
2053 * Delete LDAP directory entry
2056 dir_config_del(struct pine
*ps
, CONF_S
**cl
)
2061 if(fixed_var((*cl
)->var
, NULL
, NULL
)){
2062 if((*cl
)->var
->post_user_val
.l
|| (*cl
)->var
->main_user_val
.l
){
2063 if(want_to(_("Delete (unused) directory servers "),
2064 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y'){
2066 delete_user_vals((*cl
)->var
);
2070 q_status_message(SM_ORDER
, 3, 3,
2071 _("Can't delete sys-admin defined value"));
2074 int cnt
, ans
= 0, no_ex
;
2075 char **new_list
, **lval
, **nelval
;
2077 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
2079 /* This can't happen, intercepted at caller by first_one case */
2080 nelval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
2081 lval
= LVAL((*cl
)->var
, ew
);
2082 if(lval
&& lval
[0] && lval
[0][0] == '\0')
2085 /* how many servers defined? */
2086 for(cnt
= 0; nelval
[cnt
]; cnt
++)
2090 * If using default and there is more than one in list, ask if user
2091 * wants to ignore them all or delete just this one. If just this
2092 * one, copy rest to user_val. If ignore all, copy "" to user_val
2095 if(!lval
&& cnt
> 1){
2096 static ESCKEY_S opts
[] = {
2097 {'i', 'i', "I", N_("Ignore All")},
2098 {'r', 'r', "R", N_("Remove One")},
2099 {-1, 0, NULL
, NULL
}};
2100 ans
= radio_buttons(
2101 _("Ignore all default directory servers or just remove this one ? "),
2102 -FOOTER_ROWS(ps
), opts
, 'i', 'x',
2103 h_ab_del_dir_ignore
, RB_NORM
);
2107 snprintf(prompt
, sizeof(prompt
), _("Really delete %s \"%s\" from directory servers "),
2108 ((*cl
)->value
&& *(*cl
)->value
)
2111 ((*cl
)->value
&& *(*cl
)->value
)
2113 : int2string((*cl
)->varmem
+ 1));
2114 prompt
[sizeof(prompt
)-1] = '\0';
2118 ps
->mangled_footer
= 1;
2120 rv
= ps
->mangled_body
= 1;
2123 * Ignore all of default by adding an empty string. Make it
2124 * look just like there are no servers defined.
2127 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
2128 new_list
[0] = cpystr("");
2130 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2131 free_list_array(&new_list
);
2132 *cl
= first_confline(*cl
);
2134 opt_screen
->top_line
= NULL
;
2136 add_ldap_fake_first_server(ps
, cl
, &ps
->vars
[V_LDAP_SERVERS
],
2137 &dir_conf_km
, h_direct_config
,
2140 else if(ans
== 'r' ||
2142 want_to(prompt
, 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y')){
2145 int move_top
= 0, this_one
, revert_to_default
,
2146 default_there_to_revert_to
;
2149 * Remove one from current list.
2152 rv
= ps
->mangled_body
= 1;
2154 this_one
= (*cl
)->varmem
;
2156 /* might have to re-adjust screen to see new current */
2157 move_top
= (this_one
> 0) &&
2158 (this_one
== cnt
- 1) &&
2159 (((*cl
) == opt_screen
->top_line
) ||
2160 ((*cl
)->prev
== opt_screen
->top_line
) ||
2161 ((*cl
)->prev
->prev
== opt_screen
->top_line
));
2164 * If this is last one and there is a default available, revert
2167 revert_to_default
= ((cnt
== 1) && lval
);
2169 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
2170 for(i
= 0; i
< this_one
; i
++)
2171 new_list
[i
] = cpystr(nelval
[i
]);
2173 for(i
= this_one
; i
< cnt
; i
++)
2174 new_list
[i
] = cpystr(nelval
[i
+1]);
2176 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2177 free_list_array(&new_list
);
2179 else if(revert_to_default
){
2182 alval
= ALVAL((*cl
)->var
, ew
);
2184 free_list_array(alval
);
2187 /* cnt is one and we want to hide default */
2188 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
2189 new_list
[0] = cpystr("");
2191 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2192 free_list_array(&new_list
);
2195 if(cnt
== 1){ /* delete display line for this_one */
2196 if(revert_to_default
){
2197 servers
= (*cl
)->var
->global_val
.l
;
2198 default_there_to_revert_to
= (servers
!= NULL
);
2201 *cl
= first_confline(*cl
);
2203 opt_screen
->top_line
= NULL
;
2204 if(revert_to_default
&& default_there_to_revert_to
){
2205 CONF_S
*first_line
= NULL
;
2207 q_status_message(SM_ORDER
, 0, 3,
2208 _("Reverting to default directory server"));
2209 dir_init_display(ps
, cl
, servers
,
2210 &ps
->vars
[V_LDAP_SERVERS
], &first_line
);
2214 add_ldap_fake_first_server(ps
, cl
,
2215 &ps
->vars
[V_LDAP_SERVERS
],
2216 &dir_conf_km
, h_direct_config
,
2220 else if(this_one
== cnt
- 1){ /* deleted last one */
2221 /* back up and delete it */
2223 free_conflines(&(*cl
)->next
);
2224 /* now back up to first line of this server */
2225 *cl
= (*cl
)->prev
->prev
;
2227 opt_screen
->top_line
= *cl
;
2229 else{ /* deleted one out of the middle */
2230 if(*cl
== opt_screen
->top_line
)
2231 opt_screen
->top_line
= (*cl
)->next
->next
->next
;
2234 *cl
= (*cl
)->next
; /* move to next line, then */
2235 snip_confline(&cp
); /* snip 1st deleted line */
2237 *cl
= (*cl
)->next
; /* move to next line, then */
2238 snip_confline(&cp
); /* snip 2nd deleted line */
2240 *cl
= (*cl
)->next
; /* move to next line, then */
2241 snip_confline(&cp
); /* snip 3rd deleted line */
2242 /* adjust varmems */
2243 for(cp
= *cl
; cp
; cp
= cp
->next
)
2248 q_status_message(SM_ORDER
, 0, 3, _("Server not deleted"));
2252 set_current_val((*cl
)->var
, TRUE
, FALSE
);
2253 fix_side_effects(ps
, (*cl
)->var
, 0);
2254 write_pinerc(ps
, ew
, WRP_NONE
);
2260 * Utility routine to help set up display
2263 add_ldap_fake_first_server(struct pine
*ps
, CONF_S
**ctmp
, struct variable
*var
,
2264 struct key_menu
*km
, HelpType help
,
2265 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned))
2268 (*ctmp
)->help_title
= _("HELP FOR DIRECTORY SERVER CONFIGURATION");
2269 (*ctmp
)->value
= cpystr(ADD_FIRST_LDAP_SERVER
);
2271 (*ctmp
)->varmem
= 0;
2272 (*ctmp
)->keymenu
= km
;
2273 (*ctmp
)->help
= help
;
2274 (*ctmp
)->tool
= tool
;
2275 (*ctmp
)->valoffset
= 2;
2280 * Add an ldap server to the display list.
2282 * Args before -- Insert it before current, else append it after.
2285 add_ldap_server_to_display(struct pine
*ps
, CONF_S
**ctmp
, char *serv
, char *subtitle
,
2286 struct variable
*var
, int member
, struct key_menu
*km
,
2288 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned),
2289 int before
, CONF_S
**first_line
)
2293 *first_line
= *ctmp
;
2297 * New_confline appends ctmp after old current instead of inserting
2298 * it, so we have to adjust. We have
2299 * <- a <-> b <-> p <-> c -> and want <- a <-> p <-> b <-> c ->
2302 CONF_S
*a
, *b
, *c
, *p
;
2307 a
= b
? b
->prev
: NULL
;
2323 (*ctmp
)->help_title
= _("HELP FOR DIRECTORY SERVER CONFIGURATION");
2324 (*ctmp
)->value
= serv
;
2326 (*ctmp
)->varmem
= member
;
2327 (*ctmp
)->keymenu
= km
;
2328 (*ctmp
)->help
= help
;
2329 (*ctmp
)->tool
= tool
;
2330 (*ctmp
)->flags
|= CF_STARTITEM
;
2331 (*ctmp
)->valoffset
= 4;
2334 (*ctmp
)->value
= subtitle
;
2335 (*ctmp
)->keymenu
= km
;
2336 (*ctmp
)->help
= help
;
2337 (*ctmp
)->tool
= tool
;
2338 (*ctmp
)->flags
|= CF_NOSELECT
;
2339 (*ctmp
)->valoffset
= 8;
2342 (*ctmp
)->keymenu
= km
;
2343 (*ctmp
)->help
= help
;
2344 (*ctmp
)->tool
= tool
;
2345 (*ctmp
)->flags
|= CF_NOSELECT
| CF_B_LINE
;
2346 (*ctmp
)->valoffset
= 0;
2351 * ldap option list manipulation tool
2354 * returns: -1 on unrecognized cmd, 0 if no change, 1 if change
2357 ldap_checkbox_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2362 case MC_TOGGLE
: /* mark/unmark option */
2364 toggle_ldap_option_bit(ps
, (*cl
)->varmem
, (*cl
)->var
, (*cl
)->value
);
2367 case MC_EXIT
: /* exit */
2368 rv
= config_exit_cmd(flags
);
2381 toggle_ldap_option_bit(struct pine
*ps
, int index
, struct variable
*var
, char *value
)
2385 int tlsmust_is_on_now
;
2386 int ldaps_is_on_now
;
2387 int tls_is_on_after
;
2388 int tlsmust_is_on_after
;
2389 int ldaps_is_on_after
;
2391 tls_is_on_now
= (f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
2392 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2394 tlsmust_is_on_now
= (f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
2395 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2397 ldaps_is_on_now
= (f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
2398 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2400 f
= ldap_feature_list(index
);
2403 if(bitnset(f
->value
, ldap_option_list
))
2404 clrbitn(f
->value
, ldap_option_list
);
2406 setbitn(f
->value
, ldap_option_list
);
2408 tls_is_on_after
= (f
= ldap_feature_list(LDAP_F_TLS
)) != NULL
2409 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2411 tlsmust_is_on_after
= (f
= ldap_feature_list(LDAP_F_TLSMUST
)) != NULL
2412 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2414 ldaps_is_on_after
= (f
= ldap_feature_list(LDAP_F_LDAPS
)) != NULL
2415 && bitnset(f
->value
, ldap_option_list
) ? 1 : 0;
2417 f
= ldap_feature_list(index
);
2419 if(!ldaps_is_on_now
&& ldaps_is_on_after
){
2420 if(tlsmust_is_on_after
|| tls_is_on_after
){
2422 if(tlsmust_is_on_after
)
2423 name
= ldap_feature_list(LDAP_F_TLSMUST
)->name
;
2425 name
= ldap_feature_list(LDAP_F_TLS
)->name
;
2426 clrbitn(f
->value
, ldap_option_list
);
2427 q_status_message1(SM_ORDER
, 3, 3,
2428 _("Can not use LDAPS when using TLS. Disable \"%s\" first."), name
);
2431 else if(!tls_is_on_now
&& tls_is_on_after
){
2432 if(ldaps_is_on_after
){
2433 char *name
= ldap_feature_list(LDAP_F_LDAPS
)->name
;
2434 clrbitn(f
->value
, ldap_option_list
);
2435 q_status_message1(SM_ORDER
, 3, 3,
2436 _("Can not use TLS when using LDAPS. Disable \"%s\" first."), name
);
2439 else if(!tlsmust_is_on_now
&& tlsmust_is_on_after
){
2440 if(ldaps_is_on_after
){
2441 char *name
= ldap_feature_list(LDAP_F_LDAPS
)->name
;
2442 clrbitn(f
->value
, ldap_option_list
);
2443 q_status_message1(SM_ORDER
, 3, 3,
2444 _("Can not use TLS when using LDAPS. Disable \"%s\" first."), name
);
2449 value
[1] = bitnset(f
->value
, ldap_option_list
) ? 'X' : ' ';
2454 ldap_feature_list(int index
)
2456 static NAMEVAL_S ldap_feat_list
[] = {
2457 {"use-implicitly-from-composer", NULL
, LDAP_F_IMPL
},
2458 {"lookup-addrbook-contents", NULL
, LDAP_F_RHS
},
2459 {"save-search-criteria-not-result", NULL
, LDAP_F_REF
},
2460 {"disable-ad-hoc-space-substitution", NULL
, LDAP_F_NOSUB
},
2461 {"attempt-tls-on-connection", NULL
, LDAP_F_TLS
},
2462 {"require-tls-on-connection", NULL
, LDAP_F_TLSMUST
},
2463 {"require-ldaps-on-connection", NULL
, LDAP_F_LDAPS
}
2466 return((index
>= 0 &&
2467 index
< (sizeof(ldap_feat_list
)/sizeof(ldap_feat_list
[0])))
2468 ? &ldap_feat_list
[index
] : NULL
);
2473 * simple radio-button style variable handler
2476 ldap_radiobutton_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2484 case MC_CHOICE
: /* set/unset feature */
2486 /* hunt backwards, turning off old values */
2487 for(ctmp
= *cl
; ctmp
&& !(ctmp
->flags
& CF_NOSELECT
) && !ctmp
->varname
;
2488 ctmp
= prev_confline(ctmp
))
2489 ctmp
->value
[1] = ' ';
2491 /* hunt forwards, turning off old values */
2492 for(ctmp
= *cl
; ctmp
&& !(ctmp
->flags
& CF_NOSELECT
) && !ctmp
->varname
;
2493 ctmp
= next_confline(ctmp
))
2494 ctmp
->value
[1] = ' ';
2496 /* turn on current value */
2497 (*cl
)->value
[1] = R_SELD
;
2499 if((*cl
)->var
== ldap_srch_rule_ptr
)
2500 rule
= ldap_search_rules((*cl
)->varmem
);
2502 rule
= ldap_search_types((*cl
)->varmem
);
2504 apval
= APVAL((*cl
)->var
, ew
);
2506 fs_give((void **)apval
);
2509 *apval
= cpystr(rule
->name
);
2511 ps
->mangled_body
= 1; /* BUG: redraw it all for now? */
2516 case MC_EXIT
: /* exit */
2517 rv
= config_exit_cmd(flags
);
2528 #endif /* ENABLE_LDAP */