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 2006-2008 University of Washington
8 * Copyright 2013-2015 Eduardo Chappa
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
)
630 if(servers
&& servers
[0] && servers
[0][0]){
631 for(i
= 0; servers
[i
]; i
++){
632 info
= break_up_ldap_server(servers
[i
]);
633 serv
= (info
&& info
->nick
&& *info
->nick
) ? cpystr(info
->nick
) :
634 (info
&& info
->serv
&& *info
->serv
) ? cpystr(info
->serv
) :
635 cpystr(_("Bad Server Config, Delete this"));
636 subtitle
= (char *)fs_get((((info
&& info
->serv
&& *info
->serv
)
639 strlen(_(dserv
)) + 15) *
641 if(info
&& info
->port
>= 0)
642 snprintf(subtitle
, sizeof(subtitle
), "%s%s:%d",
644 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
647 snprintf(subtitle
, sizeof(subtitle
), "%s%s",
649 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
651 subtitle
[sizeof(subtitle
)-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
){
810 lval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
815 /* catch the special "" case */
817 (cnt
== 1 && lval
[0][0] == '\0')){
818 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
819 new_list
[0] = raw_server
;
823 /* add one for new value */
825 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
827 for(i
= 0; i
< (*cl
)->varmem
; i
++)
828 new_list
[i
] = cpystr(lval
[i
]);
830 new_list
[(*cl
)->varmem
] = raw_server
;
832 for(i
= (*cl
)->varmem
; i
< cnt
; i
++)
833 new_list
[i
+1] = cpystr(lval
[i
]);
837 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
838 free_list_array(&new_list
);
839 set_current_val((*cl
)->var
, TRUE
, FALSE
);
840 subtitle
= (char *)fs_get((((info
&& info
->serv
&& *info
->serv
)
843 strlen(_(dserv
)) + 15) *
845 if(info
&& info
->port
>= 0)
846 snprintf(subtitle
, sizeof(subtitle
), "%s%s:%d",
848 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
851 snprintf(subtitle
, sizeof(subtitle
), "%s%s",
853 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
855 subtitle
[sizeof(subtitle
)-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"));
1084 for(cnt
= 0; lval
&& lval
[cnt
]; cnt
++)
1087 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
1089 for(i
= 0; i
< (*cl
)->varmem
; i
++)
1090 new_list
[i
] = cpystr(lval
[i
]);
1092 new_list
[(*cl
)->varmem
] = raw_server
;
1095 for(i
= (*cl
)->varmem
+ 1; i
< cnt
; i
++)
1096 new_list
[i
] = cpystr(lval
[i
]);
1098 new_list
[cnt
] = NULL
;
1099 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
1100 free_list_array(&new_list
);
1101 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1104 fs_give((void **)&(*cl
)->value
);
1106 (*cl
)->value
= cpystr((info
->nick
&& *info
->nick
) ? info
->nick
1109 if((*cl
)->next
->value
)
1110 fs_give((void **)&(*cl
)->next
->value
);
1112 subtitle
= (char *)fs_get((((info
&& info
->serv
&& *info
->serv
)
1113 ? strlen(info
->serv
)
1115 strlen(_(dserv
)) + 15) *
1117 if(info
&& info
->port
>= 0)
1118 snprintf(subtitle
, sizeof(subtitle
), "%s%s:%d",
1120 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>",
1123 snprintf(subtitle
, sizeof(subtitle
), "%s%s",
1125 (info
&& info
->serv
&& *info
->serv
) ? info
->serv
: "<?>");
1127 subtitle
[sizeof(subtitle
)-1] = '\0';
1129 (*cl
)->next
->value
= subtitle
;
1131 fix_side_effects(ps
, (*cl
)->var
, 0);
1132 write_pinerc(ps
, ew
, WRP_NONE
);
1136 free_ldap_server_info(&info
);
1138 fs_give((void **)&raw_server
);
1142 #define LDAP_F_IMPL 0
1143 #define LDAP_F_RHS 1
1144 #define LDAP_F_REF 2
1145 #define LDAP_F_NOSUB 3
1146 #define LDAP_F_TLS 4
1147 #define LDAP_F_TLSMUST 5
1148 bitmap_t ldap_option_list
;
1149 struct variable
*ldap_srch_rule_ptr
;
1152 * Gives user screen to edit config values for ldap server.
1154 * Args ps -- pine struct
1155 * def -- default values to start with
1156 * title -- part of title at top of screen
1157 * raw_server -- This is the returned item, allocated here and freed by caller.
1159 * Returns: 0 if no change
1160 * 1 if user requested a change
1161 * (change is stored in raw_server and hasn't been acted upon yet)
1162 * 10 user says abort
1165 dir_edit_screen(struct pine
*ps
, LDAP_SERV_S
*def
, char *title
, char **raw_server
)
1167 OPT_SCREEN_S screen
, *saved_screen
;
1168 CONF_S
*ctmp
= NULL
, *ctmpb
, *first_line
= NULL
;
1169 char tmp
[MAXPATH
+1], custom_scope
[MAXPATH
], **apval
;
1170 int rv
, i
, j
, lv
, indent
, rindent
;
1172 struct variable server_var
, base_var
, binddn_var
, port_var
, nick_var
,
1173 srch_type_var
, srch_rule_var
, time_var
,
1174 size_var
, mailattr_var
, cnattr_var
,
1175 snattr_var
, gnattr_var
, cust_var
,
1176 opt_var
, *v
, *varlist
[21];
1177 char *server
= NULL
, *base
= NULL
, *port
= NULL
, *nick
= NULL
,
1178 *srch_type
= NULL
, *srch_rule
= NULL
, *ttime
= NULL
,
1179 *c_s_f
= "custom-search-filter", *binddn
= NULL
,
1180 *ssize
= NULL
, *mailattr
= NULL
, *cnattr
= NULL
,
1181 *snattr
= NULL
, *gnattr
= NULL
, *cust
= NULL
;
1184 * We edit by making a nested call to conf_scroll_screen.
1185 * We use some fake struct variables to get back the results in, and
1186 * so we can use the existing tools from the config screen.
1189 custom_scope
[0] = '\0';
1191 varlist
[j
= 0] = &server_var
;
1192 varlist
[++j
] = &base_var
;
1193 varlist
[++j
] = &port_var
;
1194 varlist
[++j
] = &binddn_var
;
1195 varlist
[++j
] = &nick_var
;
1196 varlist
[++j
] = &srch_type_var
;
1197 varlist
[++j
] = &srch_rule_var
;
1198 varlist
[++j
] = &time_var
;
1199 varlist
[++j
] = &size_var
;
1200 varlist
[++j
] = &mailattr_var
;
1201 varlist
[++j
] = &cnattr_var
;
1202 varlist
[++j
] = &snattr_var
;
1203 varlist
[++j
] = &gnattr_var
;
1204 varlist
[++j
] = &cust_var
;
1205 varlist
[++j
] = &opt_var
;
1206 varlist
[++j
] = NULL
;
1207 for(j
= 0; varlist
[j
]; j
++)
1208 memset(varlist
[j
], 0, sizeof(struct variable
));
1210 server_var
.name
= cpystr("ldap-server");
1211 server_var
.is_used
= 1;
1212 server_var
.is_user
= 1;
1213 apval
= APVAL(&server_var
, ew
);
1214 *apval
= (def
&& def
->serv
&& def
->serv
[0]) ? cpystr(def
->serv
) : NULL
;
1215 set_current_val(&server_var
, FALSE
, FALSE
);
1217 base_var
.name
= cpystr("search-base");
1218 base_var
.is_used
= 1;
1219 base_var
.is_user
= 1;
1220 apval
= APVAL(&base_var
, ew
);
1221 *apval
= (def
&& def
->base
&& def
->base
[0]) ? cpystr(def
->base
) : NULL
;
1222 set_current_val(&base_var
, FALSE
, FALSE
);
1224 port_var
.name
= cpystr("port");
1225 port_var
.is_used
= 1;
1226 port_var
.is_user
= 1;
1227 if(def
&& def
->port
>= 0){
1228 apval
= APVAL(&port_var
, ew
);
1229 *apval
= cpystr(int2string(def
->port
));
1232 port_var
.global_val
.p
= cpystr(int2string(LDAP_PORT
));
1233 set_current_val(&port_var
, FALSE
, FALSE
);
1235 binddn_var
.name
= cpystr("bind-dn");
1236 binddn_var
.is_used
= 1;
1237 binddn_var
.is_user
= 1;
1238 apval
= APVAL(&binddn_var
, ew
);
1239 *apval
= (def
&& def
->binddn
&& def
->binddn
[0]) ? cpystr(def
->binddn
) : NULL
;
1240 set_current_val(&binddn_var
, FALSE
, FALSE
);
1242 nick_var
.name
= cpystr("nickname");
1243 nick_var
.is_used
= 1;
1244 nick_var
.is_user
= 1;
1245 apval
= APVAL(&nick_var
, ew
);
1246 *apval
= (def
&& def
->nick
&& def
->nick
[0]) ? cpystr(def
->nick
) : NULL
;
1247 set_current_val(&nick_var
, FALSE
, FALSE
);
1249 srch_type_var
.name
= cpystr("search-type");
1250 srch_type_var
.is_used
= 1;
1251 srch_type_var
.is_user
= 1;
1252 apval
= APVAL(&srch_type_var
, ew
);
1253 *apval
= (f
=ldap_search_types(def
? def
->type
: -1))
1254 ? cpystr(f
->name
) : NULL
;
1255 srch_type_var
.global_val
.p
=
1256 (f
=ldap_search_types(DEF_LDAP_TYPE
)) ? cpystr(f
->name
) : NULL
;
1257 set_current_val(&srch_type_var
, FALSE
, FALSE
);
1259 ldap_srch_rule_ptr
= &srch_rule_var
; /* so radiobuttons can tell */
1260 srch_rule_var
.name
= cpystr("search-rule");
1261 srch_rule_var
.is_used
= 1;
1262 srch_rule_var
.is_user
= 1;
1263 apval
= APVAL(&srch_rule_var
, ew
);
1264 *apval
= (f
=ldap_search_rules(def
? def
->srch
: -1))
1265 ? cpystr(f
->name
) : NULL
;
1266 srch_rule_var
.global_val
.p
=
1267 (f
=ldap_search_rules(DEF_LDAP_SRCH
)) ? cpystr(f
->name
) : NULL
;
1268 set_current_val(&srch_rule_var
, FALSE
, FALSE
);
1270 time_var
.name
= cpystr("timelimit");
1271 time_var
.is_used
= 1;
1272 time_var
.is_user
= 1;
1273 if(def
&& def
->time
>= 0){
1274 apval
= APVAL(&time_var
, ew
);
1275 *apval
= cpystr(int2string(def
->time
));
1278 time_var
.global_val
.p
= cpystr(int2string(DEF_LDAP_TIME
));
1279 set_current_val(&time_var
, FALSE
, FALSE
);
1281 size_var
.name
= cpystr("sizelimit");
1282 size_var
.is_used
= 1;
1283 size_var
.is_user
= 1;
1284 if(def
&& def
->size
>= 0){
1285 apval
= APVAL(&size_var
, ew
);
1286 *apval
= cpystr(int2string(def
->size
));
1289 size_var
.global_val
.p
= cpystr(int2string(DEF_LDAP_SIZE
));
1290 set_current_val(&size_var
, FALSE
, FALSE
);
1292 mailattr_var
.name
= cpystr("email-attribute");
1293 mailattr_var
.is_used
= 1;
1294 mailattr_var
.is_user
= 1;
1295 apval
= APVAL(&mailattr_var
, ew
);
1296 *apval
= (def
&& def
->mailattr
&& def
->mailattr
[0])
1297 ? cpystr(def
->mailattr
) : NULL
;
1298 mailattr_var
.global_val
.p
= cpystr(DEF_LDAP_MAILATTR
);
1299 set_current_val(&mailattr_var
, FALSE
, FALSE
);
1301 cnattr_var
.name
= cpystr("name-attribute");
1302 cnattr_var
.is_used
= 1;
1303 cnattr_var
.is_user
= 1;
1304 apval
= APVAL(&cnattr_var
, ew
);
1305 *apval
= (def
&& def
->cnattr
&& def
->cnattr
[0])
1306 ? cpystr(def
->cnattr
) : NULL
;
1307 cnattr_var
.global_val
.p
= cpystr(DEF_LDAP_CNATTR
);
1308 set_current_val(&cnattr_var
, FALSE
, FALSE
);
1310 snattr_var
.name
= cpystr("surname-attribute");
1311 snattr_var
.is_used
= 1;
1312 snattr_var
.is_user
= 1;
1313 apval
= APVAL(&snattr_var
, ew
);
1314 *apval
= (def
&& def
->snattr
&& def
->snattr
[0])
1315 ? cpystr(def
->snattr
) : NULL
;
1316 snattr_var
.global_val
.p
= cpystr(DEF_LDAP_SNATTR
);
1317 set_current_val(&snattr_var
, FALSE
, FALSE
);
1319 gnattr_var
.name
= cpystr("givenname-attribute");
1320 gnattr_var
.is_used
= 1;
1321 gnattr_var
.is_user
= 1;
1322 apval
= APVAL(&gnattr_var
, ew
);
1323 *apval
= (def
&& def
->gnattr
&& def
->gnattr
[0])
1324 ? cpystr(def
->gnattr
) : NULL
;
1325 gnattr_var
.global_val
.p
= cpystr(DEF_LDAP_GNATTR
);
1326 set_current_val(&gnattr_var
, FALSE
, FALSE
);
1328 cust_var
.name
= cpystr(c_s_f
);
1329 cust_var
.is_used
= 1;
1330 cust_var
.is_user
= 1;
1331 apval
= APVAL(&cust_var
, ew
);
1332 *apval
= (def
&& def
->cust
&& def
->cust
[0]) ? cpystr(def
->cust
) : NULL
;
1333 set_current_val(&cust_var
, FALSE
, FALSE
);
1335 /* TRANSLATORS: Features is a section title in the LDAP configuration screen. Following
1336 this are a list of features or options that can be turned on or off. */
1337 opt_var
.name
= cpystr(_("Features"));
1338 opt_var
.is_used
= 1;
1339 opt_var
.is_user
= 1;
1340 opt_var
.is_list
= 1;
1341 clrbitmap(ldap_option_list
);
1342 if(def
&& def
->impl
)
1343 setbitn(LDAP_F_IMPL
, ldap_option_list
);
1345 setbitn(LDAP_F_RHS
, ldap_option_list
);
1347 setbitn(LDAP_F_REF
, ldap_option_list
);
1348 if(def
&& def
->nosub
)
1349 setbitn(LDAP_F_NOSUB
, ldap_option_list
);
1351 setbitn(LDAP_F_TLS
, ldap_option_list
);
1352 if(def
&& def
->tlsmust
)
1353 setbitn(LDAP_F_TLSMUST
, 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 for(i
= 0; (f
= ldap_feature_list(i
)); i
++){
1478 new_confline(&ctmp
);
1479 ctmp
->var
= &opt_var
;
1480 ctmp
->help_title
= _("HELP FOR LDAP FEATURES");
1481 ctmp
->varnamep
= ctmpb
;
1482 ctmp
->keymenu
= &config_checkbox_keymenu
;
1485 ctmp
->help
= h_config_ldap_opts_impl
;
1488 ctmp
->help
= h_config_ldap_opts_rhs
;
1491 ctmp
->help
= h_config_ldap_opts_ref
;
1494 ctmp
->help
= h_config_ldap_opts_nosub
;
1497 ctmp
->help
= h_config_ldap_opts_tls
;
1499 case LDAP_F_TLSMUST
:
1500 ctmp
->help
= h_config_ldap_opts_tlsmust
;
1504 ctmp
->tool
= ldap_checkbox_tool
;
1505 ctmp
->valoffset
= rindent
;
1507 utf8_snprintf(tmp
, sizeof(tmp
), "[%c] %-*.*w",
1508 bitnset(f
->value
, ldap_option_list
) ? 'X' : ' ',
1510 tmp
[sizeof(tmp
)-1] = '\0';
1511 ctmp
->value
= cpystr(tmp
);
1515 new_confline(&ctmp
);
1516 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1519 new_confline(&ctmp
);
1520 ctmp
->var
= &srch_type_var
;
1521 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1522 ctmp
->help
= NO_HELP
;
1524 snprintf(tmp
, sizeof(tmp
), "%s =", srch_type_var
.name
);
1525 tmp
[sizeof(tmp
)-1] = '\0';
1526 ctmp
->varname
= cpystr(tmp
);
1527 ctmp
->varnamep
= ctmpb
= ctmp
;
1528 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1530 new_confline(&ctmp
);
1532 ctmp
->valoffset
= rindent
;
1533 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1534 ctmp
->help
= NO_HELP
;
1536 ctmp
->varnamep
= ctmpb
;
1537 ctmp
->flags
|= CF_NOSELECT
;
1538 ctmp
->value
= cpystr("Set Rule Values");
1540 new_confline(&ctmp
);
1542 ctmp
->valoffset
= rindent
;
1543 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1544 ctmp
->help
= NO_HELP
;
1545 ctmp
->tool
= ldap_radiobutton_tool
;
1546 ctmp
->varnamep
= ctmpb
;
1547 ctmp
->flags
|= CF_NOSELECT
;
1548 ctmp
->value
= cpystr(set_choose
);
1550 /* find longest value's name */
1551 for(lv
= 0, i
= 0; (f
= ldap_search_types(i
)); i
++)
1552 if(lv
< (j
= utf8_width(f
->name
)))
1557 for(i
= 0; (f
= ldap_search_types(i
)); i
++){
1558 new_confline(&ctmp
);
1559 ctmp
->help_title
= _("HELP FOR SEARCH TYPE");
1560 ctmp
->var
= &srch_type_var
;
1561 ctmp
->valoffset
= rindent
;
1562 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1563 ctmp
->help
= h_config_ldap_searchtypes
;
1565 ctmp
->tool
= ldap_radiobutton_tool
;
1566 ctmp
->varnamep
= ctmpb
;
1567 utf8_snprintf(tmp
, sizeof(tmp
), "(%c) %-*.*w", (((!def
|| def
->type
== -1) &&
1568 f
->value
== DEF_LDAP_TYPE
) ||
1569 (def
&& f
->value
== def
->type
))
1572 tmp
[sizeof(tmp
)-1] = '\0';
1573 ctmp
->value
= cpystr(tmp
);
1577 new_confline(&ctmp
);
1578 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1579 ctmp
->varname
= cpystr("");
1582 new_confline(&ctmp
);
1583 ctmp
->var
= &srch_rule_var
;
1584 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1585 ctmp
->help
= NO_HELP
;
1587 snprintf(tmp
, sizeof(tmp
), "%s =", srch_rule_var
.name
);
1588 tmp
[sizeof(tmp
)-1] = '\0';
1589 ctmp
->varname
= cpystr(tmp
);
1590 ctmp
->varnamep
= ctmpb
= ctmp
;
1591 ctmp
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
1594 new_confline(&ctmp
);
1596 ctmp
->valoffset
= rindent
;
1597 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1598 ctmp
->help
= NO_HELP
;
1600 ctmp
->varnamep
= ctmpb
;
1601 ctmp
->flags
|= CF_NOSELECT
;
1602 ctmp
->value
= cpystr("Set Rule Values");
1604 new_confline(&ctmp
);
1606 ctmp
->valoffset
= rindent
;
1607 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1608 ctmp
->help
= NO_HELP
;
1609 ctmp
->tool
= ldap_radiobutton_tool
;
1610 ctmp
->varnamep
= ctmpb
;
1611 ctmp
->flags
|= CF_NOSELECT
;
1612 ctmp
->value
= cpystr(set_choose
);
1614 /* find longest value's name */
1615 for(lv
= 0, i
= 0; (f
= ldap_search_rules(i
)); i
++)
1616 if(lv
< (j
= utf8_width(f
->name
)))
1621 for(i
= 0; (f
= ldap_search_rules(i
)); i
++){
1622 new_confline(&ctmp
);
1623 ctmp
->help_title
= _("HELP FOR SEARCH RULE");
1624 ctmp
->var
= &srch_rule_var
;
1625 ctmp
->valoffset
= rindent
;
1626 ctmp
->keymenu
= &config_radiobutton_keymenu
;
1627 ctmp
->help
= h_config_ldap_searchrules
;
1629 ctmp
->tool
= ldap_radiobutton_tool
;
1630 ctmp
->varnamep
= ctmpb
;
1631 utf8_snprintf(tmp
, sizeof(tmp
), "(%c) %-*.*w", (((!def
|| def
->srch
== -1) &&
1632 f
->value
== DEF_LDAP_SRCH
) ||
1633 (def
&& f
->value
== def
->srch
))
1636 tmp
[sizeof(tmp
)-1] = '\0';
1637 ctmp
->value
= cpystr(tmp
);
1641 new_confline(&ctmp
);
1642 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1643 ctmp
->varname
= cpystr("");
1645 /* Email attribute name */
1646 new_confline(&ctmp
);
1647 ctmp
->help_title
= _("HELP FOR EMAIL ATTRIBUTE NAME");
1648 ctmp
->var
= &mailattr_var
;
1649 ctmp
->valoffset
= indent
;
1650 ctmp
->keymenu
= &config_text_keymenu
;
1651 ctmp
->help
= h_config_ldap_email_attr
;
1652 ctmp
->tool
= dir_edit_tool
;
1653 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,mailattr_var
.name
);
1654 tmp
[sizeof(tmp
)-1] = '\0';
1655 ctmp
->varname
= cpystr(tmp
);
1656 ctmp
->varnamep
= ctmp
;
1657 ctmp
->value
= pretty_value(ps
, ctmp
);
1659 /* Name attribute name */
1660 new_confline(&ctmp
);
1661 ctmp
->help_title
= _("HELP FOR NAME ATTRIBUTE NAME");
1662 ctmp
->var
= &cnattr_var
;
1663 ctmp
->valoffset
= indent
;
1664 ctmp
->keymenu
= &config_text_keymenu
;
1665 ctmp
->help
= h_config_ldap_cn_attr
;
1666 ctmp
->tool
= dir_edit_tool
;
1667 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,cnattr_var
.name
);
1668 tmp
[sizeof(tmp
)-1] = '\0';
1669 ctmp
->varname
= cpystr(tmp
);
1670 ctmp
->varnamep
= ctmp
;
1671 ctmp
->value
= pretty_value(ps
, ctmp
);
1673 /* Surname attribute name */
1674 new_confline(&ctmp
);
1675 ctmp
->help_title
= _("HELP FOR SURNAME ATTRIBUTE NAME");
1676 ctmp
->var
= &snattr_var
;
1677 ctmp
->valoffset
= indent
;
1678 ctmp
->keymenu
= &config_text_keymenu
;
1679 ctmp
->help
= h_config_ldap_sn_attr
;
1680 ctmp
->tool
= dir_edit_tool
;
1681 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,snattr_var
.name
);
1682 tmp
[sizeof(tmp
)-1] = '\0';
1683 ctmp
->varname
= cpystr(tmp
);
1684 ctmp
->varnamep
= ctmp
;
1685 ctmp
->value
= pretty_value(ps
, ctmp
);
1687 /* Givenname attribute name */
1688 new_confline(&ctmp
);
1689 ctmp
->help_title
= _("HELP FOR GIVEN NAME ATTRIBUTE NAME");
1690 ctmp
->var
= &gnattr_var
;
1691 ctmp
->valoffset
= indent
;
1692 ctmp
->keymenu
= &config_text_keymenu
;
1693 ctmp
->help
= h_config_ldap_gn_attr
;
1694 ctmp
->tool
= dir_edit_tool
;
1695 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,gnattr_var
.name
);
1696 tmp
[sizeof(tmp
)-1] = '\0';
1697 ctmp
->varname
= cpystr(tmp
);
1698 ctmp
->varnamep
= ctmp
;
1699 ctmp
->value
= pretty_value(ps
, ctmp
);
1702 new_confline(&ctmp
);
1703 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1704 ctmp
->varname
= cpystr("");
1707 new_confline(&ctmp
);
1708 ctmp
->help_title
= _("HELP FOR SERVER TIMELIMIT");
1709 ctmp
->var
= &time_var
;
1710 ctmp
->valoffset
= indent
;
1711 ctmp
->keymenu
= &config_text_keymenu
;
1712 ctmp
->help
= h_config_ldap_time
;
1713 ctmp
->tool
= dir_edit_tool
;
1714 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,time_var
.name
);
1715 tmp
[sizeof(tmp
)-1] = '\0';
1716 ctmp
->varname
= cpystr(tmp
);
1717 ctmp
->varnamep
= ctmp
;
1718 ctmp
->value
= pretty_value(ps
, ctmp
);
1719 ctmp
->flags
|= CF_NUMBER
;
1722 new_confline(&ctmp
);
1723 ctmp
->var
= &size_var
;
1724 ctmp
->help_title
= _("HELP FOR SERVER SIZELIMIT");
1725 ctmp
->valoffset
= indent
;
1726 ctmp
->keymenu
= &config_text_keymenu
;
1727 ctmp
->help
= h_config_ldap_size
;
1728 ctmp
->tool
= dir_edit_tool
;
1729 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,size_var
.name
);
1730 tmp
[sizeof(tmp
)-1] = '\0';
1731 ctmp
->varname
= cpystr(tmp
);
1732 ctmp
->varnamep
= ctmp
;
1733 ctmp
->value
= pretty_value(ps
, ctmp
);
1734 ctmp
->flags
|= CF_NUMBER
;
1737 new_confline(&ctmp
);
1738 ctmp
->flags
|= CF_NOSELECT
| CF_B_LINE
;
1740 /* Custom Search Filter */
1741 new_confline(&ctmp
);
1742 ctmp
->help_title
= _("HELP FOR CUSTOM SEARCH FILTER");
1743 ctmp
->var
= &cust_var
;
1744 ctmp
->valoffset
= indent
;
1745 ctmp
->keymenu
= &config_text_keymenu
;
1746 ctmp
->help
= h_config_ldap_cust
;
1747 ctmp
->tool
= dir_edit_tool
;
1748 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.*w =", indent
-3,indent
-3,cust_var
.name
);
1749 tmp
[sizeof(tmp
)-1] = '\0';
1750 ctmp
->varname
= cpystr(tmp
);
1751 ctmp
->varnamep
= ctmp
;
1752 ctmp
->value
= pretty_value(ps
, ctmp
);
1755 snprintf(tmp
, sizeof(tmp
), "%s DIRECTORY SERVER", title
);
1756 tmp
[sizeof(tmp
)-1] = '\0';
1757 memset(&screen
, 0, sizeof(screen
));
1758 screen
.ro_warning
= saved_screen
? saved_screen
->deferred_ro_warning
: 0;
1759 /* TRANSLATORS: Print something1 using something2.
1760 servers is something1 */
1761 rv
= conf_scroll_screen(ps
, &screen
, first_line
, tmp
, _("servers"), 0, NULL
);
1764 * Now look at the fake variables and extract the information we
1768 if(rv
== 1 && raw_server
){
1769 char dir_tmp
[2200], *p
;
1770 int portval
= -1, timeval
= -1, sizeval
= -1;
1772 apval
= APVAL(&server_var
, ew
);
1776 apval
= APVAL(&base_var
, ew
);
1780 apval
= APVAL(&port_var
, ew
);
1784 apval
= APVAL(&binddn_var
, ew
);
1788 apval
= APVAL(&nick_var
, ew
);
1792 apval
= APVAL(&srch_type_var
, ew
);
1796 apval
= APVAL(&srch_rule_var
, ew
);
1800 apval
= APVAL(&time_var
, ew
);
1804 apval
= APVAL(&size_var
, ew
);
1808 apval
= APVAL(&cust_var
, ew
);
1812 apval
= APVAL(&mailattr_var
, ew
);
1816 apval
= APVAL(&snattr_var
, ew
);
1820 apval
= APVAL(&gnattr_var
, ew
);
1824 apval
= APVAL(&cnattr_var
, ew
);
1829 removing_leading_and_trailing_white_space(server
);
1832 removing_leading_and_trailing_white_space(base
);
1833 (void)removing_double_quotes(base
);
1834 p
= add_backslash_escapes(base
);
1835 fs_give((void **)&base
);
1840 removing_leading_and_trailing_white_space(port
);
1842 portval
= atoi(port
);
1846 removing_leading_and_trailing_white_space(binddn
);
1847 (void)removing_double_quotes(binddn
);
1848 p
= add_backslash_escapes(binddn
);
1849 fs_give((void **)&binddn
);
1854 removing_leading_and_trailing_white_space(nick
);
1855 (void)removing_double_quotes(nick
);
1856 p
= add_backslash_escapes(nick
);
1857 fs_give((void **)&nick
);
1862 removing_leading_and_trailing_white_space(ttime
);
1864 timeval
= atoi(ttime
);
1868 removing_leading_and_trailing_white_space(ssize
);
1870 sizeval
= atoi(ssize
);
1874 removing_leading_and_trailing_white_space(cust
);
1875 p
= add_backslash_escapes(cust
);
1876 fs_give((void **)&cust
);
1881 removing_leading_and_trailing_white_space(mailattr
);
1882 p
= add_backslash_escapes(mailattr
);
1883 fs_give((void **)&mailattr
);
1888 removing_leading_and_trailing_white_space(snattr
);
1889 p
= add_backslash_escapes(snattr
);
1890 fs_give((void **)&snattr
);
1895 removing_leading_and_trailing_white_space(gnattr
);
1896 p
= add_backslash_escapes(gnattr
);
1897 fs_give((void **)&gnattr
);
1902 removing_leading_and_trailing_white_space(cnattr
);
1903 p
= add_backslash_escapes(cnattr
);
1904 fs_give((void **)&cnattr
);
1909 * Don't allow user to edit scope but if one is present then we
1910 * leave it (so they could edit it by hand).
1912 if(def
&& def
->scope
!= -1 && def
->scope
!= DEF_LDAP_SCOPE
){
1915 v
= ldap_search_scope(def
->scope
);
1917 snprintf(custom_scope
, sizeof(custom_scope
), "/scope=%s", v
->name
);
1918 custom_scope
[sizeof(custom_scope
)-1] = '\0';
1922 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/type=%s/srch=%s%s/time=%s/size=%s/cust=%s/nick=%s/matr=%s/catr=%s/satr=%s/gatr=%s\"",
1923 server
? server
: "",
1924 (portval
>= 0 && port
&& *port
) ? ":" : "",
1925 (portval
>= 0 && port
&& *port
) ? port
: "",
1927 binddn
? binddn
: "",
1928 bitnset(LDAP_F_IMPL
, ldap_option_list
) ? 1 : 0,
1929 bitnset(LDAP_F_RHS
, ldap_option_list
) ? 1 : 0,
1930 bitnset(LDAP_F_REF
, ldap_option_list
) ? 1 : 0,
1931 bitnset(LDAP_F_NOSUB
, ldap_option_list
) ? 1 : 0,
1932 bitnset(LDAP_F_TLS
, ldap_option_list
) ? 1 : 0,
1933 bitnset(LDAP_F_TLSMUST
, ldap_option_list
) ? 1 : 0,
1934 srch_type
? srch_type
: "",
1935 srch_rule
? srch_rule
: "",
1937 (timeval
>= 0 && ttime
&& *ttime
) ? ttime
: "",
1938 (sizeval
>= 0 && ssize
&& *ssize
) ? ssize
: "",
1941 mailattr
? mailattr
: "",
1942 cnattr
? cnattr
: "",
1943 snattr
? snattr
: "",
1944 gnattr
? gnattr
: "");
1945 dir_tmp
[sizeof(dir_tmp
)-1] = '\0';
1947 *raw_server
= cpystr(dir_tmp
);
1950 for(j
= 0; varlist
[j
]; j
++){
1952 if(v
->current_val
.p
)
1953 fs_give((void **)&v
->current_val
.p
);
1955 fs_give((void **)&v
->global_val
.p
);
1956 if(v
->main_user_val
.p
)
1957 fs_give((void **)&v
->main_user_val
.p
);
1958 if(v
->post_user_val
.p
)
1959 fs_give((void **)&v
->post_user_val
.p
);
1961 fs_give((void **)&v
->name
);
1965 fs_give((void **)&server
);
1967 fs_give((void **)&base
);
1969 fs_give((void **)&port
);
1971 fs_give((void **)&binddn
);
1973 fs_give((void **)&nick
);
1975 fs_give((void **)&srch_type
);
1977 fs_give((void **)&srch_rule
);
1979 fs_give((void **)&ttime
);
1981 fs_give((void **)&ssize
);
1983 fs_give((void **)&mailattr
);
1985 fs_give((void **)&cnattr
);
1987 fs_give((void **)&snattr
);
1989 fs_give((void **)&gnattr
);
1991 fs_give((void **)&cust
);
1993 opt_screen
= saved_screen
;
1994 ps
->mangled_screen
= 1;
2000 * Just calls text_tool except for intercepting MC_EXIT.
2003 dir_edit_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2006 return(config_exit_cmd(flags
));
2008 return(text_tool(ps
, cmd
, cl
, flags
));
2013 * Delete LDAP directory entry
2016 dir_config_del(struct pine
*ps
, CONF_S
**cl
)
2021 if(fixed_var((*cl
)->var
, NULL
, NULL
)){
2022 if((*cl
)->var
->post_user_val
.l
|| (*cl
)->var
->main_user_val
.l
){
2023 if(want_to(_("Delete (unused) directory servers "),
2024 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y'){
2026 delete_user_vals((*cl
)->var
);
2030 q_status_message(SM_ORDER
, 3, 3,
2031 _("Can't delete sys-admin defined value"));
2034 int cnt
, ans
= 0, no_ex
;
2035 char **new_list
, **lval
, **nelval
;
2037 no_ex
= (ps_global
->ew_for_except_vars
== Main
);
2039 /* This can't happen, intercepted at caller by first_one case */
2040 nelval
= no_ex
? (*cl
)->var
->current_val
.l
: LVAL((*cl
)->var
, ew
);
2041 lval
= LVAL((*cl
)->var
, ew
);
2042 if(lval
&& lval
[0] && lval
[0][0] == '\0')
2045 /* how many servers defined? */
2046 for(cnt
= 0; nelval
[cnt
]; cnt
++)
2050 * If using default and there is more than one in list, ask if user
2051 * wants to ignore them all or delete just this one. If just this
2052 * one, copy rest to user_val. If ignore all, copy "" to user_val
2055 if(!lval
&& cnt
> 1){
2056 static ESCKEY_S opts
[] = {
2057 {'i', 'i', "I", N_("Ignore All")},
2058 {'r', 'r', "R", N_("Remove One")},
2059 {-1, 0, NULL
, NULL
}};
2060 ans
= radio_buttons(
2061 _("Ignore all default directory servers or just remove this one ? "),
2062 -FOOTER_ROWS(ps
), opts
, 'i', 'x',
2063 h_ab_del_dir_ignore
, RB_NORM
);
2067 snprintf(prompt
, sizeof(prompt
), _("Really delete %s \"%s\" from directory servers "),
2068 ((*cl
)->value
&& *(*cl
)->value
)
2071 ((*cl
)->value
&& *(*cl
)->value
)
2073 : int2string((*cl
)->varmem
+ 1));
2074 prompt
[sizeof(prompt
)-1] = '\0';
2078 ps
->mangled_footer
= 1;
2080 rv
= ps
->mangled_body
= 1;
2083 * Ignore all of default by adding an empty string. Make it
2084 * look just like there are no servers defined.
2087 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
2088 new_list
[0] = cpystr("");
2090 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2091 free_list_array(&new_list
);
2092 *cl
= first_confline(*cl
);
2094 opt_screen
->top_line
= NULL
;
2096 add_ldap_fake_first_server(ps
, cl
, &ps
->vars
[V_LDAP_SERVERS
],
2097 &dir_conf_km
, h_direct_config
,
2100 else if(ans
== 'r' ||
2102 want_to(prompt
, 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y')){
2105 int move_top
= 0, this_one
, revert_to_default
,
2106 default_there_to_revert_to
;
2109 * Remove one from current list.
2112 rv
= ps
->mangled_body
= 1;
2114 this_one
= (*cl
)->varmem
;
2116 /* might have to re-adjust screen to see new current */
2117 move_top
= (this_one
> 0) &&
2118 (this_one
== cnt
- 1) &&
2119 (((*cl
) == opt_screen
->top_line
) ||
2120 ((*cl
)->prev
== opt_screen
->top_line
) ||
2121 ((*cl
)->prev
->prev
== opt_screen
->top_line
));
2124 * If this is last one and there is a default available, revert
2127 revert_to_default
= ((cnt
== 1) && lval
);
2129 new_list
= (char **)fs_get((cnt
+ 1) * sizeof(char *));
2130 for(i
= 0; i
< this_one
; i
++)
2131 new_list
[i
] = cpystr(nelval
[i
]);
2133 for(i
= this_one
; i
< cnt
; i
++)
2134 new_list
[i
] = cpystr(nelval
[i
+1]);
2136 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2137 free_list_array(&new_list
);
2139 else if(revert_to_default
){
2142 alval
= ALVAL((*cl
)->var
, ew
);
2144 free_list_array(alval
);
2147 /* cnt is one and we want to hide default */
2148 new_list
= (char **)fs_get((1 + 1) * sizeof(char *));
2149 new_list
[0] = cpystr("");
2151 set_variable_list(V_LDAP_SERVERS
, new_list
, FALSE
, ew
);
2152 free_list_array(&new_list
);
2155 if(cnt
== 1){ /* delete display line for this_one */
2156 if(revert_to_default
){
2157 servers
= (*cl
)->var
->global_val
.l
;
2158 default_there_to_revert_to
= (servers
!= NULL
);
2161 *cl
= first_confline(*cl
);
2163 opt_screen
->top_line
= NULL
;
2164 if(revert_to_default
&& default_there_to_revert_to
){
2165 CONF_S
*first_line
= NULL
;
2167 q_status_message(SM_ORDER
, 0, 3,
2168 _("Reverting to default directory server"));
2169 dir_init_display(ps
, cl
, servers
,
2170 &ps
->vars
[V_LDAP_SERVERS
], &first_line
);
2174 add_ldap_fake_first_server(ps
, cl
,
2175 &ps
->vars
[V_LDAP_SERVERS
],
2176 &dir_conf_km
, h_direct_config
,
2180 else if(this_one
== cnt
- 1){ /* deleted last one */
2181 /* back up and delete it */
2183 free_conflines(&(*cl
)->next
);
2184 /* now back up to first line of this server */
2185 *cl
= (*cl
)->prev
->prev
;
2187 opt_screen
->top_line
= *cl
;
2189 else{ /* deleted one out of the middle */
2190 if(*cl
== opt_screen
->top_line
)
2191 opt_screen
->top_line
= (*cl
)->next
->next
->next
;
2194 *cl
= (*cl
)->next
; /* move to next line, then */
2195 snip_confline(&cp
); /* snip 1st deleted line */
2197 *cl
= (*cl
)->next
; /* move to next line, then */
2198 snip_confline(&cp
); /* snip 2nd deleted line */
2200 *cl
= (*cl
)->next
; /* move to next line, then */
2201 snip_confline(&cp
); /* snip 3rd deleted line */
2202 /* adjust varmems */
2203 for(cp
= *cl
; cp
; cp
= cp
->next
)
2208 q_status_message(SM_ORDER
, 0, 3, _("Server not deleted"));
2212 set_current_val((*cl
)->var
, TRUE
, FALSE
);
2213 fix_side_effects(ps
, (*cl
)->var
, 0);
2214 write_pinerc(ps
, ew
, WRP_NONE
);
2220 * Utility routine to help set up display
2223 add_ldap_fake_first_server(struct pine
*ps
, CONF_S
**ctmp
, struct variable
*var
,
2224 struct key_menu
*km
, HelpType help
,
2225 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned))
2228 (*ctmp
)->help_title
= _("HELP FOR DIRECTORY SERVER CONFIGURATION");
2229 (*ctmp
)->value
= cpystr(ADD_FIRST_LDAP_SERVER
);
2231 (*ctmp
)->varmem
= 0;
2232 (*ctmp
)->keymenu
= km
;
2233 (*ctmp
)->help
= help
;
2234 (*ctmp
)->tool
= tool
;
2235 (*ctmp
)->valoffset
= 2;
2240 * Add an ldap server to the display list.
2242 * Args before -- Insert it before current, else append it after.
2245 add_ldap_server_to_display(struct pine
*ps
, CONF_S
**ctmp
, char *serv
, char *subtitle
,
2246 struct variable
*var
, int member
, struct key_menu
*km
,
2248 int (*tool
)(struct pine
*, int, CONF_S
**, unsigned),
2249 int before
, CONF_S
**first_line
)
2253 *first_line
= *ctmp
;
2257 * New_confline appends ctmp after old current instead of inserting
2258 * it, so we have to adjust. We have
2259 * <- a <-> b <-> p <-> c -> and want <- a <-> p <-> b <-> c ->
2262 CONF_S
*a
, *b
, *c
, *p
;
2267 a
= b
? b
->prev
: NULL
;
2283 (*ctmp
)->help_title
= _("HELP FOR DIRECTORY SERVER CONFIGURATION");
2284 (*ctmp
)->value
= serv
;
2286 (*ctmp
)->varmem
= member
;
2287 (*ctmp
)->keymenu
= km
;
2288 (*ctmp
)->help
= help
;
2289 (*ctmp
)->tool
= tool
;
2290 (*ctmp
)->flags
|= CF_STARTITEM
;
2291 (*ctmp
)->valoffset
= 4;
2294 (*ctmp
)->value
= subtitle
;
2295 (*ctmp
)->keymenu
= km
;
2296 (*ctmp
)->help
= help
;
2297 (*ctmp
)->tool
= tool
;
2298 (*ctmp
)->flags
|= CF_NOSELECT
;
2299 (*ctmp
)->valoffset
= 8;
2302 (*ctmp
)->keymenu
= km
;
2303 (*ctmp
)->help
= help
;
2304 (*ctmp
)->tool
= tool
;
2305 (*ctmp
)->flags
|= CF_NOSELECT
| CF_B_LINE
;
2306 (*ctmp
)->valoffset
= 0;
2311 * ldap option list manipulation tool
2314 * returns: -1 on unrecognized cmd, 0 if no change, 1 if change
2317 ldap_checkbox_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2322 case MC_TOGGLE
: /* mark/unmark option */
2324 toggle_ldap_option_bit(ps
, (*cl
)->varmem
, (*cl
)->var
, (*cl
)->value
);
2327 case MC_EXIT
: /* exit */
2328 rv
= config_exit_cmd(flags
);
2341 toggle_ldap_option_bit(struct pine
*ps
, int index
, struct variable
*var
, char *value
)
2345 f
= ldap_feature_list(index
);
2348 if(bitnset(f
->value
, ldap_option_list
))
2349 clrbitn(f
->value
, ldap_option_list
);
2351 setbitn(f
->value
, ldap_option_list
);
2354 value
[1] = bitnset(f
->value
, ldap_option_list
) ? 'X' : ' ';
2359 ldap_feature_list(int index
)
2361 static NAMEVAL_S ldap_feat_list
[] = {
2362 {"use-implicitly-from-composer", NULL
, LDAP_F_IMPL
},
2363 {"lookup-addrbook-contents", NULL
, LDAP_F_RHS
},
2364 {"save-search-criteria-not-result", NULL
, LDAP_F_REF
},
2365 {"disable-ad-hoc-space-substitution", NULL
, LDAP_F_NOSUB
},
2366 {"attempt-tls-on-connection", NULL
, LDAP_F_TLS
},
2367 {"require-tls-on-connection", NULL
, LDAP_F_TLSMUST
}
2370 return((index
>= 0 &&
2371 index
< (sizeof(ldap_feat_list
)/sizeof(ldap_feat_list
[0])))
2372 ? &ldap_feat_list
[index
] : NULL
);
2377 * simple radio-button style variable handler
2380 ldap_radiobutton_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
2388 case MC_CHOICE
: /* set/unset feature */
2390 /* hunt backwards, turning off old values */
2391 for(ctmp
= *cl
; ctmp
&& !(ctmp
->flags
& CF_NOSELECT
) && !ctmp
->varname
;
2392 ctmp
= prev_confline(ctmp
))
2393 ctmp
->value
[1] = ' ';
2395 /* hunt forwards, turning off old values */
2396 for(ctmp
= *cl
; ctmp
&& !(ctmp
->flags
& CF_NOSELECT
) && !ctmp
->varname
;
2397 ctmp
= next_confline(ctmp
))
2398 ctmp
->value
[1] = ' ';
2400 /* turn on current value */
2401 (*cl
)->value
[1] = R_SELD
;
2403 if((*cl
)->var
== ldap_srch_rule_ptr
)
2404 rule
= ldap_search_rules((*cl
)->varmem
);
2406 rule
= ldap_search_types((*cl
)->varmem
);
2408 apval
= APVAL((*cl
)->var
, ew
);
2410 fs_give((void **)apval
);
2413 *apval
= cpystr(rule
->name
);
2415 ps
->mangled_body
= 1; /* BUG: redraw it all for now? */
2420 case MC_EXIT
: /* exit */
2421 rv
= config_exit_cmd(flags
);
2432 #endif /* ENABLE_LDAP */