xref: /dragonfly/crypto/libressl/crypto/ui/ui_lib.c (revision 8edacedf)
18edacedfSDaniel Fojt /* $OpenBSD: ui_lib.c,v 1.44 2020/09/25 11:25:31 tb Exp $ */
2f5b1c8a1SJohn Marino /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3f5b1c8a1SJohn Marino  * project 2001.
4f5b1c8a1SJohn Marino  */
5f5b1c8a1SJohn Marino /* ====================================================================
6f5b1c8a1SJohn Marino  * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
7f5b1c8a1SJohn Marino  *
8f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
9f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
10f5b1c8a1SJohn Marino  * are met:
11f5b1c8a1SJohn Marino  *
12f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the above copyright
13f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
14f5b1c8a1SJohn Marino  *
15f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
16f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in
17f5b1c8a1SJohn Marino  *    the documentation and/or other materials provided with the
18f5b1c8a1SJohn Marino  *    distribution.
19f5b1c8a1SJohn Marino  *
20f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this
21f5b1c8a1SJohn Marino  *    software must display the following acknowledgment:
22f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
23f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24f5b1c8a1SJohn Marino  *
25f5b1c8a1SJohn Marino  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26f5b1c8a1SJohn Marino  *    endorse or promote products derived from this software without
27f5b1c8a1SJohn Marino  *    prior written permission. For written permission, please contact
28f5b1c8a1SJohn Marino  *    openssl-core@openssl.org.
29f5b1c8a1SJohn Marino  *
30f5b1c8a1SJohn Marino  * 5. Products derived from this software may not be called "OpenSSL"
31f5b1c8a1SJohn Marino  *    nor may "OpenSSL" appear in their names without prior written
32f5b1c8a1SJohn Marino  *    permission of the OpenSSL Project.
33f5b1c8a1SJohn Marino  *
34f5b1c8a1SJohn Marino  * 6. Redistributions of any form whatsoever must retain the following
35f5b1c8a1SJohn Marino  *    acknowledgment:
36f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
37f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38f5b1c8a1SJohn Marino  *
39f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40f5b1c8a1SJohn Marino  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42f5b1c8a1SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43f5b1c8a1SJohn Marino  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44f5b1c8a1SJohn Marino  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45f5b1c8a1SJohn Marino  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46f5b1c8a1SJohn Marino  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48f5b1c8a1SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49f5b1c8a1SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50f5b1c8a1SJohn Marino  * OF THE POSSIBILITY OF SUCH DAMAGE.
51f5b1c8a1SJohn Marino  * ====================================================================
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * This product includes cryptographic software written by Eric Young
54f5b1c8a1SJohn Marino  * (eay@cryptsoft.com).  This product includes software written by Tim
55f5b1c8a1SJohn Marino  * Hudson (tjh@cryptsoft.com).
56f5b1c8a1SJohn Marino  *
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino 
59f5b1c8a1SJohn Marino #include <string.h>
60f5b1c8a1SJohn Marino 
61f5b1c8a1SJohn Marino #include <openssl/opensslconf.h>
62f5b1c8a1SJohn Marino 
63f5b1c8a1SJohn Marino #include <openssl/buffer.h>
64f5b1c8a1SJohn Marino #include <openssl/err.h>
65f5b1c8a1SJohn Marino #include <openssl/ui.h>
66f5b1c8a1SJohn Marino 
67f5b1c8a1SJohn Marino #include "ui_locl.h"
68f5b1c8a1SJohn Marino 
69f5b1c8a1SJohn Marino static const UI_METHOD *default_UI_meth = NULL;
70f5b1c8a1SJohn Marino 
71f5b1c8a1SJohn Marino UI *
UI_new(void)72f5b1c8a1SJohn Marino UI_new(void)
73f5b1c8a1SJohn Marino {
74f5b1c8a1SJohn Marino 	return (UI_new_method(NULL));
75f5b1c8a1SJohn Marino }
76f5b1c8a1SJohn Marino 
77f5b1c8a1SJohn Marino UI *
UI_new_method(const UI_METHOD * method)78f5b1c8a1SJohn Marino UI_new_method(const UI_METHOD *method)
79f5b1c8a1SJohn Marino {
80f5b1c8a1SJohn Marino 	UI *ret;
81f5b1c8a1SJohn Marino 
828edacedfSDaniel Fojt 	if ((ret = calloc(1, sizeof(UI))) == NULL) {
8372c33676SMaxim Ag 		UIerror(ERR_R_MALLOC_FAILURE);
84f5b1c8a1SJohn Marino 		return NULL;
85f5b1c8a1SJohn Marino 	}
868edacedfSDaniel Fojt 	if ((ret->meth = method) == NULL)
87f5b1c8a1SJohn Marino 		ret->meth = UI_get_default_method();
88f5b1c8a1SJohn Marino 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
898edacedfSDaniel Fojt 
90f5b1c8a1SJohn Marino 	return ret;
91f5b1c8a1SJohn Marino }
92f5b1c8a1SJohn Marino 
93f5b1c8a1SJohn Marino static void
free_string(UI_STRING * uis)94f5b1c8a1SJohn Marino free_string(UI_STRING *uis)
95f5b1c8a1SJohn Marino {
968edacedfSDaniel Fojt 	if (uis == NULL)
978edacedfSDaniel Fojt 		return;
98f5b1c8a1SJohn Marino 	if (uis->flags & OUT_STRING_FREEABLE) {
99f5b1c8a1SJohn Marino 		free((char *) uis->out_string);
100f5b1c8a1SJohn Marino 		switch (uis->type) {
101f5b1c8a1SJohn Marino 		case UIT_BOOLEAN:
102f5b1c8a1SJohn Marino 			free((char *)uis->_.boolean_data.action_desc);
103f5b1c8a1SJohn Marino 			free((char *)uis->_.boolean_data.ok_chars);
104f5b1c8a1SJohn Marino 			free((char *)uis->_.boolean_data.cancel_chars);
105f5b1c8a1SJohn Marino 			break;
106f5b1c8a1SJohn Marino 		default:
107f5b1c8a1SJohn Marino 			break;
108f5b1c8a1SJohn Marino 		}
109f5b1c8a1SJohn Marino 	}
110f5b1c8a1SJohn Marino 	free(uis);
111f5b1c8a1SJohn Marino }
112f5b1c8a1SJohn Marino 
113f5b1c8a1SJohn Marino void
UI_free(UI * ui)114f5b1c8a1SJohn Marino UI_free(UI *ui)
115f5b1c8a1SJohn Marino {
116f5b1c8a1SJohn Marino 	if (ui == NULL)
117f5b1c8a1SJohn Marino 		return;
118f5b1c8a1SJohn Marino 	sk_UI_STRING_pop_free(ui->strings, free_string);
119f5b1c8a1SJohn Marino 	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
120f5b1c8a1SJohn Marino 	free(ui);
121f5b1c8a1SJohn Marino }
122f5b1c8a1SJohn Marino 
123f5b1c8a1SJohn Marino static int
allocate_string_stack(UI * ui)124f5b1c8a1SJohn Marino allocate_string_stack(UI *ui)
125f5b1c8a1SJohn Marino {
126f5b1c8a1SJohn Marino 	if (ui->strings == NULL) {
1278edacedfSDaniel Fojt 		if ((ui->strings = sk_UI_STRING_new_null()) == NULL) {
1288edacedfSDaniel Fojt 			UIerror(ERR_R_MALLOC_FAILURE);
129f5b1c8a1SJohn Marino 			return -1;
130f5b1c8a1SJohn Marino 		}
131f5b1c8a1SJohn Marino 	}
132f5b1c8a1SJohn Marino 	return 0;
133f5b1c8a1SJohn Marino }
134f5b1c8a1SJohn Marino 
135f5b1c8a1SJohn Marino static UI_STRING *
general_allocate_prompt(const char * prompt,int dup_prompt,enum UI_string_types type,int input_flags,char * result_buf)1368edacedfSDaniel Fojt general_allocate_prompt(const char *prompt, int dup_prompt,
137f5b1c8a1SJohn Marino     enum UI_string_types type, int input_flags, char *result_buf)
138f5b1c8a1SJohn Marino {
1398edacedfSDaniel Fojt 	UI_STRING *uis = NULL;
140f5b1c8a1SJohn Marino 
141f5b1c8a1SJohn Marino 	if (prompt == NULL) {
14272c33676SMaxim Ag 		UIerror(ERR_R_PASSED_NULL_PARAMETER);
1438edacedfSDaniel Fojt 		goto err;
144f5b1c8a1SJohn Marino 	}
1458edacedfSDaniel Fojt 	if ((type == UIT_PROMPT || type == UIT_VERIFY || type == UIT_BOOLEAN) &&
1468edacedfSDaniel Fojt 	    result_buf == NULL) {
1478edacedfSDaniel Fojt 		UIerror(UI_R_NO_RESULT_BUFFER);
1488edacedfSDaniel Fojt 		goto err;
1498edacedfSDaniel Fojt 	}
1508edacedfSDaniel Fojt 
1518edacedfSDaniel Fojt 	if ((uis = calloc(1, sizeof(UI_STRING))) == NULL) {
1528edacedfSDaniel Fojt 		UIerror(ERR_R_MALLOC_FAILURE);
1538edacedfSDaniel Fojt 		goto err;
1548edacedfSDaniel Fojt 	}
1558edacedfSDaniel Fojt 	uis->out_string = prompt;
1568edacedfSDaniel Fojt 	if (dup_prompt) {
1578edacedfSDaniel Fojt 		if ((uis->out_string = strdup(prompt)) == NULL) {
1588edacedfSDaniel Fojt 			UIerror(ERR_R_MALLOC_FAILURE);
1598edacedfSDaniel Fojt 			goto err;
1608edacedfSDaniel Fojt 		}
1618edacedfSDaniel Fojt 		uis->flags = OUT_STRING_FREEABLE;
1628edacedfSDaniel Fojt 	}
1638edacedfSDaniel Fojt 	uis->input_flags = input_flags;
1648edacedfSDaniel Fojt 	uis->type = type;
1658edacedfSDaniel Fojt 	uis->result_buf = result_buf;
1668edacedfSDaniel Fojt 
1678edacedfSDaniel Fojt 	return uis;
1688edacedfSDaniel Fojt 
1698edacedfSDaniel Fojt  err:
1708edacedfSDaniel Fojt 	free_string(uis);
1718edacedfSDaniel Fojt 	return NULL;
172f5b1c8a1SJohn Marino }
173f5b1c8a1SJohn Marino 
174f5b1c8a1SJohn Marino static int
general_allocate_string(UI * ui,const char * prompt,int dup_prompt,enum UI_string_types type,int input_flags,char * result_buf,int minsize,int maxsize,const char * test_buf)1758edacedfSDaniel Fojt general_allocate_string(UI *ui, const char *prompt, int dup_prompt,
176f5b1c8a1SJohn Marino     enum UI_string_types type, int input_flags, char *result_buf, int minsize,
177f5b1c8a1SJohn Marino     int maxsize, const char *test_buf)
178f5b1c8a1SJohn Marino {
1798edacedfSDaniel Fojt 	UI_STRING *s;
1808edacedfSDaniel Fojt 	int ret;
181f5b1c8a1SJohn Marino 
1828edacedfSDaniel Fojt 	if ((s = general_allocate_prompt(prompt, dup_prompt, type, input_flags,
1838edacedfSDaniel Fojt 	    result_buf)) == NULL)
1848edacedfSDaniel Fojt 		goto err;
185f5b1c8a1SJohn Marino 	s->_.string_data.result_minsize = minsize;
186f5b1c8a1SJohn Marino 	s->_.string_data.result_maxsize = maxsize;
187f5b1c8a1SJohn Marino 	s->_.string_data.test_buf = test_buf;
1888edacedfSDaniel Fojt 
1898edacedfSDaniel Fojt 	if (allocate_string_stack(ui) < 0)
1908edacedfSDaniel Fojt 		goto err;
1918edacedfSDaniel Fojt 	if ((ret = sk_UI_STRING_push(ui->strings, s)) <= 0)
1928edacedfSDaniel Fojt 		goto err;
1938edacedfSDaniel Fojt 
194f5b1c8a1SJohn Marino 	return ret;
1958edacedfSDaniel Fojt 
1968edacedfSDaniel Fojt  err:
1978edacedfSDaniel Fojt 	free_string(s);
1988edacedfSDaniel Fojt 	return -1;
199f5b1c8a1SJohn Marino }
200f5b1c8a1SJohn Marino 
201f5b1c8a1SJohn Marino static int
general_allocate_boolean(UI * ui,const char * prompt,const char * action_desc,const char * ok_chars,const char * cancel_chars,int dup_strings,enum UI_string_types type,int input_flags,char * result_buf)202f5b1c8a1SJohn Marino general_allocate_boolean(UI *ui, const char *prompt, const char *action_desc,
2038edacedfSDaniel Fojt     const char *ok_chars, const char *cancel_chars, int dup_strings,
204f5b1c8a1SJohn Marino     enum UI_string_types type, int input_flags, char *result_buf)
205f5b1c8a1SJohn Marino {
2068edacedfSDaniel Fojt 	UI_STRING *s = NULL;
2078edacedfSDaniel Fojt 	int ret;
208f5b1c8a1SJohn Marino 
2098edacedfSDaniel Fojt 	if (ok_chars == NULL || cancel_chars == NULL) {
21072c33676SMaxim Ag 		UIerror(ERR_R_PASSED_NULL_PARAMETER);
2118edacedfSDaniel Fojt 		goto err;
2128edacedfSDaniel Fojt 	}
2138edacedfSDaniel Fojt 	if (ok_chars[strcspn(ok_chars, cancel_chars)] != '\0') {
21472c33676SMaxim Ag 		UIerror(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
2158edacedfSDaniel Fojt 		goto err;
216f5b1c8a1SJohn Marino 	}
217f5b1c8a1SJohn Marino 
2188edacedfSDaniel Fojt 	if ((s = general_allocate_prompt(prompt, dup_strings, type, input_flags,
2198edacedfSDaniel Fojt 	    result_buf)) == NULL)
2208edacedfSDaniel Fojt 		goto err;
221f5b1c8a1SJohn Marino 
2228edacedfSDaniel Fojt 	if (dup_strings) {
2238edacedfSDaniel Fojt 		if (action_desc != NULL) {
2248edacedfSDaniel Fojt 			if ((s->_.boolean_data.action_desc =
2258edacedfSDaniel Fojt 			    strdup(action_desc)) == NULL) {
2268edacedfSDaniel Fojt 				UIerror(ERR_R_MALLOC_FAILURE);
2278edacedfSDaniel Fojt 				goto err;
2288edacedfSDaniel Fojt 			}
2298edacedfSDaniel Fojt 		}
2308edacedfSDaniel Fojt 		if ((s->_.boolean_data.ok_chars = strdup(ok_chars)) == NULL) {
2318edacedfSDaniel Fojt 			UIerror(ERR_R_MALLOC_FAILURE);
2328edacedfSDaniel Fojt 			goto err;
2338edacedfSDaniel Fojt 		}
2348edacedfSDaniel Fojt 		if ((s->_.boolean_data.cancel_chars = strdup(cancel_chars)) ==
2358edacedfSDaniel Fojt 		    NULL) {
2368edacedfSDaniel Fojt 			UIerror(ERR_R_MALLOC_FAILURE);
2378edacedfSDaniel Fojt 			goto err;
2388edacedfSDaniel Fojt 		}
2398edacedfSDaniel Fojt 	} else {
240f5b1c8a1SJohn Marino 		s->_.boolean_data.action_desc = action_desc;
241f5b1c8a1SJohn Marino 		s->_.boolean_data.ok_chars = ok_chars;
242f5b1c8a1SJohn Marino 		s->_.boolean_data.cancel_chars = cancel_chars;
243f5b1c8a1SJohn Marino 	}
244f5b1c8a1SJohn Marino 
2458edacedfSDaniel Fojt 	if (allocate_string_stack(ui) < 0)
2468edacedfSDaniel Fojt 		goto err;
2478edacedfSDaniel Fojt 	if ((ret = sk_UI_STRING_push(ui->strings, s)) <= 0)
2488edacedfSDaniel Fojt 		goto err;
2498edacedfSDaniel Fojt 
2508edacedfSDaniel Fojt 	return ret;
2518edacedfSDaniel Fojt 
2528edacedfSDaniel Fojt  err:
2538edacedfSDaniel Fojt 	free_string(s);
2548edacedfSDaniel Fojt 	return -1;
2558edacedfSDaniel Fojt }
2568edacedfSDaniel Fojt 
2578edacedfSDaniel Fojt /*
2588edacedfSDaniel Fojt  * Returns the index to the place in the stack or -1 for error.  Uses a
2598edacedfSDaniel Fojt  * direct reference to the prompt.
2608edacedfSDaniel Fojt  */
261f5b1c8a1SJohn Marino int
UI_add_input_string(UI * ui,const char * prompt,int flags,char * result_buf,int minsize,int maxsize)262f5b1c8a1SJohn Marino UI_add_input_string(UI *ui, const char *prompt, int flags, char *result_buf,
263f5b1c8a1SJohn Marino     int minsize, int maxsize)
264f5b1c8a1SJohn Marino {
265f5b1c8a1SJohn Marino 	return general_allocate_string(ui, prompt, 0, UIT_PROMPT, flags,
266f5b1c8a1SJohn Marino 	    result_buf, minsize, maxsize, NULL);
267f5b1c8a1SJohn Marino }
268f5b1c8a1SJohn Marino 
2698edacedfSDaniel Fojt /* Same as UI_add_input_string(), excepts it takes a copy of the prompt. */
270f5b1c8a1SJohn Marino int
UI_dup_input_string(UI * ui,const char * prompt,int flags,char * result_buf,int minsize,int maxsize)271f5b1c8a1SJohn Marino UI_dup_input_string(UI *ui, const char *prompt, int flags, char *result_buf,
272f5b1c8a1SJohn Marino     int minsize, int maxsize)
273f5b1c8a1SJohn Marino {
2748edacedfSDaniel Fojt 	return general_allocate_string(ui, prompt, 1, UIT_PROMPT, flags,
275f5b1c8a1SJohn Marino 	    result_buf, minsize, maxsize, NULL);
276f5b1c8a1SJohn Marino }
277f5b1c8a1SJohn Marino 
278f5b1c8a1SJohn Marino int
UI_add_verify_string(UI * ui,const char * prompt,int flags,char * result_buf,int minsize,int maxsize,const char * test_buf)279f5b1c8a1SJohn Marino UI_add_verify_string(UI *ui, const char *prompt, int flags, char *result_buf,
280f5b1c8a1SJohn Marino     int minsize, int maxsize, const char *test_buf)
281f5b1c8a1SJohn Marino {
282f5b1c8a1SJohn Marino 	return general_allocate_string(ui, prompt, 0, UIT_VERIFY, flags,
283f5b1c8a1SJohn Marino 	    result_buf, minsize, maxsize, test_buf);
284f5b1c8a1SJohn Marino }
285f5b1c8a1SJohn Marino 
286f5b1c8a1SJohn Marino int
UI_dup_verify_string(UI * ui,const char * prompt,int flags,char * result_buf,int minsize,int maxsize,const char * test_buf)287f5b1c8a1SJohn Marino UI_dup_verify_string(UI *ui, const char *prompt, int flags,
288f5b1c8a1SJohn Marino     char *result_buf, int minsize, int maxsize, const char *test_buf)
289f5b1c8a1SJohn Marino {
2908edacedfSDaniel Fojt 	return general_allocate_string(ui, prompt, 1, UIT_VERIFY, flags,
291f5b1c8a1SJohn Marino 	    result_buf, minsize, maxsize, test_buf);
292f5b1c8a1SJohn Marino }
293f5b1c8a1SJohn Marino 
294f5b1c8a1SJohn Marino int
UI_add_input_boolean(UI * ui,const char * prompt,const char * action_desc,const char * ok_chars,const char * cancel_chars,int flags,char * result_buf)295f5b1c8a1SJohn Marino UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
296f5b1c8a1SJohn Marino     const char *ok_chars, const char *cancel_chars, int flags, char *result_buf)
297f5b1c8a1SJohn Marino {
298f5b1c8a1SJohn Marino 	return general_allocate_boolean(ui, prompt, action_desc, ok_chars,
299f5b1c8a1SJohn Marino 	    cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
300f5b1c8a1SJohn Marino }
301f5b1c8a1SJohn Marino 
302f5b1c8a1SJohn Marino int
UI_dup_input_boolean(UI * ui,const char * prompt,const char * action_desc,const char * ok_chars,const char * cancel_chars,int flags,char * result_buf)303f5b1c8a1SJohn Marino UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
304f5b1c8a1SJohn Marino     const char *ok_chars, const char *cancel_chars, int flags, char *result_buf)
305f5b1c8a1SJohn Marino {
3068edacedfSDaniel Fojt 	return general_allocate_boolean(ui, prompt, action_desc, ok_chars,
3078edacedfSDaniel Fojt 	    cancel_chars, 1, UIT_BOOLEAN, flags, result_buf);
308f5b1c8a1SJohn Marino }
309f5b1c8a1SJohn Marino 
310f5b1c8a1SJohn Marino int
UI_add_info_string(UI * ui,const char * text)311f5b1c8a1SJohn Marino UI_add_info_string(UI *ui, const char *text)
312f5b1c8a1SJohn Marino {
313f5b1c8a1SJohn Marino 	return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
314f5b1c8a1SJohn Marino 	    NULL);
315f5b1c8a1SJohn Marino }
316f5b1c8a1SJohn Marino 
317f5b1c8a1SJohn Marino int
UI_dup_info_string(UI * ui,const char * text)318f5b1c8a1SJohn Marino UI_dup_info_string(UI *ui, const char *text)
319f5b1c8a1SJohn Marino {
3208edacedfSDaniel Fojt 	return general_allocate_string(ui, text, 1, UIT_INFO, 0, NULL, 0, 0,
3218edacedfSDaniel Fojt 	    NULL);
322f5b1c8a1SJohn Marino }
323f5b1c8a1SJohn Marino 
324f5b1c8a1SJohn Marino int
UI_add_error_string(UI * ui,const char * text)325f5b1c8a1SJohn Marino UI_add_error_string(UI *ui, const char *text)
326f5b1c8a1SJohn Marino {
327f5b1c8a1SJohn Marino 	return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
328f5b1c8a1SJohn Marino 	    NULL);
329f5b1c8a1SJohn Marino }
330f5b1c8a1SJohn Marino 
331f5b1c8a1SJohn Marino int
UI_dup_error_string(UI * ui,const char * text)332f5b1c8a1SJohn Marino UI_dup_error_string(UI *ui, const char *text)
333f5b1c8a1SJohn Marino {
3348edacedfSDaniel Fojt 	return general_allocate_string(ui, text, 1, UIT_ERROR, 0, NULL, 0, 0,
3358edacedfSDaniel Fojt 	    NULL);
336f5b1c8a1SJohn Marino }
337f5b1c8a1SJohn Marino 
338f5b1c8a1SJohn Marino char *
UI_construct_prompt(UI * ui,const char * object_desc,const char * object_name)339f5b1c8a1SJohn Marino UI_construct_prompt(UI *ui, const char *object_desc, const char *object_name)
340f5b1c8a1SJohn Marino {
341f5b1c8a1SJohn Marino 	char *prompt;
342f5b1c8a1SJohn Marino 
343f5b1c8a1SJohn Marino 	if (ui->meth->ui_construct_prompt)
344f5b1c8a1SJohn Marino 		return ui->meth->ui_construct_prompt(ui, object_desc,
345f5b1c8a1SJohn Marino 		    object_name);
346f5b1c8a1SJohn Marino 
347f5b1c8a1SJohn Marino 	if (object_desc == NULL)
348f5b1c8a1SJohn Marino 		return NULL;
349f5b1c8a1SJohn Marino 
350f5b1c8a1SJohn Marino 	if (object_name == NULL) {
351f5b1c8a1SJohn Marino 		if (asprintf(&prompt, "Enter %s:", object_desc) == -1)
352f5b1c8a1SJohn Marino 			return (NULL);
353f5b1c8a1SJohn Marino 	} else {
354f5b1c8a1SJohn Marino 		if (asprintf(&prompt, "Enter %s for %s:", object_desc,
355f5b1c8a1SJohn Marino 		    object_name) == -1)
356f5b1c8a1SJohn Marino 			return (NULL);
357f5b1c8a1SJohn Marino 	}
358f5b1c8a1SJohn Marino 
359f5b1c8a1SJohn Marino 	return prompt;
360f5b1c8a1SJohn Marino }
361f5b1c8a1SJohn Marino 
362f5b1c8a1SJohn Marino void *
UI_add_user_data(UI * ui,void * user_data)363f5b1c8a1SJohn Marino UI_add_user_data(UI *ui, void *user_data)
364f5b1c8a1SJohn Marino {
365f5b1c8a1SJohn Marino 	void *old_data = ui->user_data;
366f5b1c8a1SJohn Marino 
367f5b1c8a1SJohn Marino 	ui->user_data = user_data;
368f5b1c8a1SJohn Marino 	return old_data;
369f5b1c8a1SJohn Marino }
370f5b1c8a1SJohn Marino 
371f5b1c8a1SJohn Marino void *
UI_get0_user_data(UI * ui)372f5b1c8a1SJohn Marino UI_get0_user_data(UI *ui)
373f5b1c8a1SJohn Marino {
374f5b1c8a1SJohn Marino 	return ui->user_data;
375f5b1c8a1SJohn Marino }
376f5b1c8a1SJohn Marino 
377f5b1c8a1SJohn Marino const char *
UI_get0_result(UI * ui,int i)378f5b1c8a1SJohn Marino UI_get0_result(UI *ui, int i)
379f5b1c8a1SJohn Marino {
380f5b1c8a1SJohn Marino 	if (i < 0) {
38172c33676SMaxim Ag 		UIerror(UI_R_INDEX_TOO_SMALL);
382f5b1c8a1SJohn Marino 		return NULL;
383f5b1c8a1SJohn Marino 	}
384f5b1c8a1SJohn Marino 	if (i >= sk_UI_STRING_num(ui->strings)) {
38572c33676SMaxim Ag 		UIerror(UI_R_INDEX_TOO_LARGE);
386f5b1c8a1SJohn Marino 		return NULL;
387f5b1c8a1SJohn Marino 	}
388f5b1c8a1SJohn Marino 	return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
389f5b1c8a1SJohn Marino }
390f5b1c8a1SJohn Marino 
391f5b1c8a1SJohn Marino static int
print_error(const char * str,size_t len,void * arg)3928edacedfSDaniel Fojt print_error(const char *str, size_t len, void *arg)
393f5b1c8a1SJohn Marino {
3948edacedfSDaniel Fojt 	UI *ui = arg;
395f5b1c8a1SJohn Marino 	UI_STRING uis;
396f5b1c8a1SJohn Marino 
397f5b1c8a1SJohn Marino 	memset(&uis, 0, sizeof(uis));
398f5b1c8a1SJohn Marino 	uis.type = UIT_ERROR;
399f5b1c8a1SJohn Marino 	uis.out_string = str;
400f5b1c8a1SJohn Marino 
401f5b1c8a1SJohn Marino 	if (ui->meth->ui_write_string &&
402f5b1c8a1SJohn Marino 	    !ui->meth->ui_write_string(ui, &uis))
403f5b1c8a1SJohn Marino 		return -1;
404f5b1c8a1SJohn Marino 	return 0;
405f5b1c8a1SJohn Marino }
406f5b1c8a1SJohn Marino 
407f5b1c8a1SJohn Marino int
UI_process(UI * ui)408f5b1c8a1SJohn Marino UI_process(UI *ui)
409f5b1c8a1SJohn Marino {
410f5b1c8a1SJohn Marino 	int i, ok = 0;
411f5b1c8a1SJohn Marino 
412f5b1c8a1SJohn Marino 	if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
413f5b1c8a1SJohn Marino 		return -1;
414f5b1c8a1SJohn Marino 
415f5b1c8a1SJohn Marino 	if (ui->flags & UI_FLAG_PRINT_ERRORS)
4168edacedfSDaniel Fojt 		ERR_print_errors_cb(print_error, ui);
417f5b1c8a1SJohn Marino 
418f5b1c8a1SJohn Marino 	for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
419f5b1c8a1SJohn Marino 		if (ui->meth->ui_write_string &&
420f5b1c8a1SJohn Marino 		    !ui->meth->ui_write_string(ui,
421f5b1c8a1SJohn Marino 			sk_UI_STRING_value(ui->strings, i))) {
422f5b1c8a1SJohn Marino 			ok = -1;
423f5b1c8a1SJohn Marino 			goto err;
424f5b1c8a1SJohn Marino 		}
425f5b1c8a1SJohn Marino 	}
426f5b1c8a1SJohn Marino 
427f5b1c8a1SJohn Marino 	if (ui->meth->ui_flush)
428f5b1c8a1SJohn Marino 		switch (ui->meth->ui_flush(ui)) {
429f5b1c8a1SJohn Marino 		case -1:	/* Interrupt/Cancel/something... */
430f5b1c8a1SJohn Marino 			ok = -2;
431f5b1c8a1SJohn Marino 			goto err;
432f5b1c8a1SJohn Marino 		case 0:		/* Errors */
433f5b1c8a1SJohn Marino 			ok = -1;
434f5b1c8a1SJohn Marino 			goto err;
435f5b1c8a1SJohn Marino 		default:	/* Success */
436f5b1c8a1SJohn Marino 			ok = 0;
437f5b1c8a1SJohn Marino 			break;
438f5b1c8a1SJohn Marino 		}
439f5b1c8a1SJohn Marino 
440f5b1c8a1SJohn Marino 	for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
441f5b1c8a1SJohn Marino 		if (ui->meth->ui_read_string) {
442f5b1c8a1SJohn Marino 			switch (ui->meth->ui_read_string(ui,
443f5b1c8a1SJohn Marino 			    sk_UI_STRING_value(ui->strings, i))) {
444f5b1c8a1SJohn Marino 			case -1:	/* Interrupt/Cancel/something... */
445f5b1c8a1SJohn Marino 				ui->flags &= ~UI_FLAG_REDOABLE;
446f5b1c8a1SJohn Marino 				ok = -2;
447f5b1c8a1SJohn Marino 				goto err;
448f5b1c8a1SJohn Marino 			case 0:		/* Errors */
449f5b1c8a1SJohn Marino 				ok = -1;
450f5b1c8a1SJohn Marino 				goto err;
451f5b1c8a1SJohn Marino 			default:	/* Success */
452f5b1c8a1SJohn Marino 				ok = 0;
453f5b1c8a1SJohn Marino 				break;
454f5b1c8a1SJohn Marino 			}
455f5b1c8a1SJohn Marino 		}
456f5b1c8a1SJohn Marino 	}
457f5b1c8a1SJohn Marino 
458f5b1c8a1SJohn Marino  err:
459f5b1c8a1SJohn Marino 	if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
460f5b1c8a1SJohn Marino 		return -1;
461f5b1c8a1SJohn Marino 	return ok;
462f5b1c8a1SJohn Marino }
463f5b1c8a1SJohn Marino 
464f5b1c8a1SJohn Marino int
UI_ctrl(UI * ui,int cmd,long i,void * p,void (* f)(void))465f5b1c8a1SJohn Marino UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void))
466f5b1c8a1SJohn Marino {
467f5b1c8a1SJohn Marino 	if (ui == NULL) {
46872c33676SMaxim Ag 		UIerror(ERR_R_PASSED_NULL_PARAMETER);
469f5b1c8a1SJohn Marino 		return -1;
470f5b1c8a1SJohn Marino 	}
471f5b1c8a1SJohn Marino 	switch (cmd) {
472f5b1c8a1SJohn Marino 	case UI_CTRL_PRINT_ERRORS:
473f5b1c8a1SJohn Marino 		{
474f5b1c8a1SJohn Marino 			int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
475f5b1c8a1SJohn Marino 			if (i)
476f5b1c8a1SJohn Marino 				ui->flags |= UI_FLAG_PRINT_ERRORS;
477f5b1c8a1SJohn Marino 			else
478f5b1c8a1SJohn Marino 				ui->flags &= ~UI_FLAG_PRINT_ERRORS;
479f5b1c8a1SJohn Marino 			return save_flag;
480f5b1c8a1SJohn Marino 		}
481f5b1c8a1SJohn Marino 	case UI_CTRL_IS_REDOABLE:
482f5b1c8a1SJohn Marino 		return !!(ui->flags & UI_FLAG_REDOABLE);
483f5b1c8a1SJohn Marino 	default:
484f5b1c8a1SJohn Marino 		break;
485f5b1c8a1SJohn Marino 	}
48672c33676SMaxim Ag 	UIerror(UI_R_UNKNOWN_CONTROL_COMMAND);
487f5b1c8a1SJohn Marino 	return -1;
488f5b1c8a1SJohn Marino }
489f5b1c8a1SJohn Marino 
490f5b1c8a1SJohn Marino int
UI_get_ex_new_index(long argl,void * argp,CRYPTO_EX_new * new_func,CRYPTO_EX_dup * dup_func,CRYPTO_EX_free * free_func)491f5b1c8a1SJohn Marino UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
492f5b1c8a1SJohn Marino     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
493f5b1c8a1SJohn Marino {
494f5b1c8a1SJohn Marino 	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
495f5b1c8a1SJohn Marino 	    new_func, dup_func, free_func);
496f5b1c8a1SJohn Marino }
497f5b1c8a1SJohn Marino 
498f5b1c8a1SJohn Marino int
UI_set_ex_data(UI * r,int idx,void * arg)499f5b1c8a1SJohn Marino UI_set_ex_data(UI *r, int idx, void *arg)
500f5b1c8a1SJohn Marino {
501f5b1c8a1SJohn Marino 	return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
502f5b1c8a1SJohn Marino }
503f5b1c8a1SJohn Marino 
504f5b1c8a1SJohn Marino void *
UI_get_ex_data(UI * r,int idx)505f5b1c8a1SJohn Marino UI_get_ex_data(UI *r, int idx)
506f5b1c8a1SJohn Marino {
507f5b1c8a1SJohn Marino 	return (CRYPTO_get_ex_data(&r->ex_data, idx));
508f5b1c8a1SJohn Marino }
509f5b1c8a1SJohn Marino 
510f5b1c8a1SJohn Marino void
UI_set_default_method(const UI_METHOD * meth)511f5b1c8a1SJohn Marino UI_set_default_method(const UI_METHOD *meth)
512f5b1c8a1SJohn Marino {
513f5b1c8a1SJohn Marino 	default_UI_meth = meth;
514f5b1c8a1SJohn Marino }
515f5b1c8a1SJohn Marino 
516f5b1c8a1SJohn Marino const UI_METHOD *
UI_get_default_method(void)517f5b1c8a1SJohn Marino UI_get_default_method(void)
518f5b1c8a1SJohn Marino {
519f5b1c8a1SJohn Marino 	if (default_UI_meth == NULL) {
520f5b1c8a1SJohn Marino 		default_UI_meth = UI_OpenSSL();
521f5b1c8a1SJohn Marino 	}
522f5b1c8a1SJohn Marino 	return default_UI_meth;
523f5b1c8a1SJohn Marino }
524f5b1c8a1SJohn Marino 
525f5b1c8a1SJohn Marino const UI_METHOD *
UI_get_method(UI * ui)526f5b1c8a1SJohn Marino UI_get_method(UI *ui)
527f5b1c8a1SJohn Marino {
528f5b1c8a1SJohn Marino 	return ui->meth;
529f5b1c8a1SJohn Marino }
530f5b1c8a1SJohn Marino 
531f5b1c8a1SJohn Marino const UI_METHOD *
UI_set_method(UI * ui,const UI_METHOD * meth)532f5b1c8a1SJohn Marino UI_set_method(UI *ui, const UI_METHOD *meth)
533f5b1c8a1SJohn Marino {
534f5b1c8a1SJohn Marino 	ui->meth = meth;
535f5b1c8a1SJohn Marino 	return ui->meth;
536f5b1c8a1SJohn Marino }
537f5b1c8a1SJohn Marino 
538f5b1c8a1SJohn Marino 
539f5b1c8a1SJohn Marino UI_METHOD *
UI_create_method(const char * name)54072c33676SMaxim Ag UI_create_method(const char *name)
541f5b1c8a1SJohn Marino {
542f5b1c8a1SJohn Marino 	UI_METHOD *ui_method = calloc(1, sizeof(UI_METHOD));
543f5b1c8a1SJohn Marino 
544f5b1c8a1SJohn Marino 	if (ui_method && name)
545f5b1c8a1SJohn Marino 		ui_method->name = strdup(name);
546f5b1c8a1SJohn Marino 
547f5b1c8a1SJohn Marino 	return ui_method;
548f5b1c8a1SJohn Marino }
549f5b1c8a1SJohn Marino 
5508edacedfSDaniel Fojt /*
5518edacedfSDaniel Fojt  * BIG FSCKING WARNING!!!!  If you use this on a statically allocated method
5528edacedfSDaniel Fojt  * (that is, it hasn't been allocated using UI_create_method(), you deserve
5538edacedfSDaniel Fojt  * anything Murphy can throw at you and more!  You have been warned.
5548edacedfSDaniel Fojt  */
555f5b1c8a1SJohn Marino void
UI_destroy_method(UI_METHOD * ui_method)556f5b1c8a1SJohn Marino UI_destroy_method(UI_METHOD *ui_method)
557f5b1c8a1SJohn Marino {
558f5b1c8a1SJohn Marino 	free(ui_method->name);
559f5b1c8a1SJohn Marino 	ui_method->name = NULL;
560f5b1c8a1SJohn Marino 	free(ui_method);
561f5b1c8a1SJohn Marino }
562f5b1c8a1SJohn Marino 
563f5b1c8a1SJohn Marino int
UI_method_set_opener(UI_METHOD * method,int (* opener)(UI * ui))564f5b1c8a1SJohn Marino UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui))
565f5b1c8a1SJohn Marino {
566f5b1c8a1SJohn Marino 	if (method) {
567f5b1c8a1SJohn Marino 		method->ui_open_session = opener;
568f5b1c8a1SJohn Marino 		return 0;
5698edacedfSDaniel Fojt 	}
570f5b1c8a1SJohn Marino 	return -1;
571f5b1c8a1SJohn Marino }
572f5b1c8a1SJohn Marino 
573f5b1c8a1SJohn Marino int
UI_method_set_writer(UI_METHOD * method,int (* writer)(UI * ui,UI_STRING * uis))574f5b1c8a1SJohn Marino UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis))
575f5b1c8a1SJohn Marino {
576f5b1c8a1SJohn Marino 	if (method) {
577f5b1c8a1SJohn Marino 		method->ui_write_string = writer;
578f5b1c8a1SJohn Marino 		return 0;
5798edacedfSDaniel Fojt 	}
580f5b1c8a1SJohn Marino 	return -1;
581f5b1c8a1SJohn Marino }
582f5b1c8a1SJohn Marino 
583f5b1c8a1SJohn Marino int
UI_method_set_flusher(UI_METHOD * method,int (* flusher)(UI * ui))584f5b1c8a1SJohn Marino UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui))
585f5b1c8a1SJohn Marino {
586f5b1c8a1SJohn Marino 	if (method) {
587f5b1c8a1SJohn Marino 		method->ui_flush = flusher;
588f5b1c8a1SJohn Marino 		return 0;
5898edacedfSDaniel Fojt 	}
590f5b1c8a1SJohn Marino 	return -1;
591f5b1c8a1SJohn Marino }
592f5b1c8a1SJohn Marino 
593f5b1c8a1SJohn Marino int
UI_method_set_reader(UI_METHOD * method,int (* reader)(UI * ui,UI_STRING * uis))594f5b1c8a1SJohn Marino UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))
595f5b1c8a1SJohn Marino {
596f5b1c8a1SJohn Marino 	if (method) {
597f5b1c8a1SJohn Marino 		method->ui_read_string = reader;
598f5b1c8a1SJohn Marino 		return 0;
5998edacedfSDaniel Fojt 	}
600f5b1c8a1SJohn Marino 	return -1;
601f5b1c8a1SJohn Marino }
602f5b1c8a1SJohn Marino 
603f5b1c8a1SJohn Marino int
UI_method_set_closer(UI_METHOD * method,int (* closer)(UI * ui))604f5b1c8a1SJohn Marino UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
605f5b1c8a1SJohn Marino {
606f5b1c8a1SJohn Marino 	if (method) {
607f5b1c8a1SJohn Marino 		method->ui_close_session = closer;
608f5b1c8a1SJohn Marino 		return 0;
6098edacedfSDaniel Fojt 	}
610f5b1c8a1SJohn Marino 	return -1;
611f5b1c8a1SJohn Marino }
612f5b1c8a1SJohn Marino 
613f5b1c8a1SJohn Marino int
UI_method_set_prompt_constructor(UI_METHOD * method,char * (* prompt_constructor)(UI * ui,const char * object_desc,const char * object_name))614f5b1c8a1SJohn Marino UI_method_set_prompt_constructor(UI_METHOD *method,
615f5b1c8a1SJohn Marino     char *(*prompt_constructor)(UI *ui, const char *object_desc,
616f5b1c8a1SJohn Marino     const char *object_name))
617f5b1c8a1SJohn Marino {
618f5b1c8a1SJohn Marino 	if (method) {
619f5b1c8a1SJohn Marino 		method->ui_construct_prompt = prompt_constructor;
620f5b1c8a1SJohn Marino 		return 0;
6218edacedfSDaniel Fojt 	}
622f5b1c8a1SJohn Marino 	return -1;
623f5b1c8a1SJohn Marino }
624f5b1c8a1SJohn Marino 
625f5b1c8a1SJohn Marino int
UI_method_get_opener(const UI_METHOD * method)62672c33676SMaxim Ag (*UI_method_get_opener(const UI_METHOD * method))(UI *)
627f5b1c8a1SJohn Marino {
628f5b1c8a1SJohn Marino 	if (method)
629f5b1c8a1SJohn Marino 		return method->ui_open_session;
630f5b1c8a1SJohn Marino 	return NULL;
631f5b1c8a1SJohn Marino }
632f5b1c8a1SJohn Marino 
633f5b1c8a1SJohn Marino int
UI_method_get_writer(const UI_METHOD * method)63472c33676SMaxim Ag (*UI_method_get_writer(const UI_METHOD *method))(UI *, UI_STRING *)
635f5b1c8a1SJohn Marino {
636f5b1c8a1SJohn Marino 	if (method)
637f5b1c8a1SJohn Marino 		return method->ui_write_string;
638f5b1c8a1SJohn Marino 	return NULL;
639f5b1c8a1SJohn Marino }
640f5b1c8a1SJohn Marino 
641f5b1c8a1SJohn Marino int
UI_method_get_flusher(const UI_METHOD * method)64272c33676SMaxim Ag (*UI_method_get_flusher(const UI_METHOD *method)) (UI *)
643f5b1c8a1SJohn Marino {
644f5b1c8a1SJohn Marino 	if (method)
645f5b1c8a1SJohn Marino 		return method->ui_flush;
646f5b1c8a1SJohn Marino 	return NULL;
647f5b1c8a1SJohn Marino }
648f5b1c8a1SJohn Marino 
649f5b1c8a1SJohn Marino int
UI_method_get_reader(const UI_METHOD * method)65072c33676SMaxim Ag (*UI_method_get_reader(const UI_METHOD *method))(UI *, UI_STRING *)
651f5b1c8a1SJohn Marino {
652f5b1c8a1SJohn Marino 	if (method)
653f5b1c8a1SJohn Marino 		return method->ui_read_string;
654f5b1c8a1SJohn Marino 	return NULL;
655f5b1c8a1SJohn Marino }
656f5b1c8a1SJohn Marino 
657f5b1c8a1SJohn Marino int
UI_method_get_closer(const UI_METHOD * method)65872c33676SMaxim Ag (*UI_method_get_closer(const UI_METHOD *method))(UI *)
659f5b1c8a1SJohn Marino {
660f5b1c8a1SJohn Marino 	if (method)
661f5b1c8a1SJohn Marino 		return method->ui_close_session;
662f5b1c8a1SJohn Marino 	return NULL;
663f5b1c8a1SJohn Marino }
664f5b1c8a1SJohn Marino 
665f5b1c8a1SJohn Marino char *
UI_method_get_prompt_constructor(const UI_METHOD * method)66672c33676SMaxim Ag (*UI_method_get_prompt_constructor(const UI_METHOD *method))(UI *, const char *,
667f5b1c8a1SJohn Marino     const char *)
668f5b1c8a1SJohn Marino {
669f5b1c8a1SJohn Marino 	if (method)
670f5b1c8a1SJohn Marino 		return method->ui_construct_prompt;
671f5b1c8a1SJohn Marino 	return NULL;
672f5b1c8a1SJohn Marino }
673f5b1c8a1SJohn Marino 
674f5b1c8a1SJohn Marino enum UI_string_types
UI_get_string_type(UI_STRING * uis)675f5b1c8a1SJohn Marino UI_get_string_type(UI_STRING *uis)
676f5b1c8a1SJohn Marino {
677f5b1c8a1SJohn Marino 	if (!uis)
678f5b1c8a1SJohn Marino 		return UIT_NONE;
679f5b1c8a1SJohn Marino 	return uis->type;
680f5b1c8a1SJohn Marino }
681f5b1c8a1SJohn Marino 
682f5b1c8a1SJohn Marino int
UI_get_input_flags(UI_STRING * uis)683f5b1c8a1SJohn Marino UI_get_input_flags(UI_STRING *uis)
684f5b1c8a1SJohn Marino {
685f5b1c8a1SJohn Marino 	if (!uis)
686f5b1c8a1SJohn Marino 		return 0;
687f5b1c8a1SJohn Marino 	return uis->input_flags;
688f5b1c8a1SJohn Marino }
689f5b1c8a1SJohn Marino 
690f5b1c8a1SJohn Marino const char *
UI_get0_output_string(UI_STRING * uis)691f5b1c8a1SJohn Marino UI_get0_output_string(UI_STRING *uis)
692f5b1c8a1SJohn Marino {
693f5b1c8a1SJohn Marino 	if (!uis)
694f5b1c8a1SJohn Marino 		return NULL;
695f5b1c8a1SJohn Marino 	return uis->out_string;
696f5b1c8a1SJohn Marino }
697f5b1c8a1SJohn Marino 
698f5b1c8a1SJohn Marino const char *
UI_get0_action_string(UI_STRING * uis)699f5b1c8a1SJohn Marino UI_get0_action_string(UI_STRING *uis)
700f5b1c8a1SJohn Marino {
701f5b1c8a1SJohn Marino 	if (!uis)
702f5b1c8a1SJohn Marino 		return NULL;
703f5b1c8a1SJohn Marino 	switch (uis->type) {
704f5b1c8a1SJohn Marino 	case UIT_PROMPT:
705f5b1c8a1SJohn Marino 	case UIT_BOOLEAN:
706f5b1c8a1SJohn Marino 		return uis->_.boolean_data.action_desc;
707f5b1c8a1SJohn Marino 	default:
708f5b1c8a1SJohn Marino 		return NULL;
709f5b1c8a1SJohn Marino 	}
710f5b1c8a1SJohn Marino }
711f5b1c8a1SJohn Marino 
712f5b1c8a1SJohn Marino const char *
UI_get0_result_string(UI_STRING * uis)713f5b1c8a1SJohn Marino UI_get0_result_string(UI_STRING *uis)
714f5b1c8a1SJohn Marino {
715f5b1c8a1SJohn Marino 	if (!uis)
716f5b1c8a1SJohn Marino 		return NULL;
717f5b1c8a1SJohn Marino 	switch (uis->type) {
718f5b1c8a1SJohn Marino 	case UIT_PROMPT:
719f5b1c8a1SJohn Marino 	case UIT_VERIFY:
720f5b1c8a1SJohn Marino 		return uis->result_buf;
721f5b1c8a1SJohn Marino 	default:
722f5b1c8a1SJohn Marino 		return NULL;
723f5b1c8a1SJohn Marino 	}
724f5b1c8a1SJohn Marino }
725f5b1c8a1SJohn Marino 
726f5b1c8a1SJohn Marino const char *
UI_get0_test_string(UI_STRING * uis)727f5b1c8a1SJohn Marino UI_get0_test_string(UI_STRING *uis)
728f5b1c8a1SJohn Marino {
729f5b1c8a1SJohn Marino 	if (!uis)
730f5b1c8a1SJohn Marino 		return NULL;
731f5b1c8a1SJohn Marino 	switch (uis->type) {
732f5b1c8a1SJohn Marino 	case UIT_VERIFY:
733f5b1c8a1SJohn Marino 		return uis->_.string_data.test_buf;
734f5b1c8a1SJohn Marino 	default:
735f5b1c8a1SJohn Marino 		return NULL;
736f5b1c8a1SJohn Marino 	}
737f5b1c8a1SJohn Marino }
738f5b1c8a1SJohn Marino 
739f5b1c8a1SJohn Marino int
UI_get_result_minsize(UI_STRING * uis)740f5b1c8a1SJohn Marino UI_get_result_minsize(UI_STRING *uis)
741f5b1c8a1SJohn Marino {
742f5b1c8a1SJohn Marino 	if (!uis)
743f5b1c8a1SJohn Marino 		return -1;
744f5b1c8a1SJohn Marino 	switch (uis->type) {
745f5b1c8a1SJohn Marino 	case UIT_PROMPT:
746f5b1c8a1SJohn Marino 	case UIT_VERIFY:
747f5b1c8a1SJohn Marino 		return uis->_.string_data.result_minsize;
748f5b1c8a1SJohn Marino 	default:
749f5b1c8a1SJohn Marino 		return -1;
750f5b1c8a1SJohn Marino 	}
751f5b1c8a1SJohn Marino }
752f5b1c8a1SJohn Marino 
753f5b1c8a1SJohn Marino int
UI_get_result_maxsize(UI_STRING * uis)754f5b1c8a1SJohn Marino UI_get_result_maxsize(UI_STRING *uis)
755f5b1c8a1SJohn Marino {
756f5b1c8a1SJohn Marino 	if (!uis)
757f5b1c8a1SJohn Marino 		return -1;
758f5b1c8a1SJohn Marino 	switch (uis->type) {
759f5b1c8a1SJohn Marino 	case UIT_PROMPT:
760f5b1c8a1SJohn Marino 	case UIT_VERIFY:
761f5b1c8a1SJohn Marino 		return uis->_.string_data.result_maxsize;
762f5b1c8a1SJohn Marino 	default:
763f5b1c8a1SJohn Marino 		return -1;
764f5b1c8a1SJohn Marino 	}
765f5b1c8a1SJohn Marino }
766f5b1c8a1SJohn Marino 
767f5b1c8a1SJohn Marino int
UI_set_result(UI * ui,UI_STRING * uis,const char * result)768f5b1c8a1SJohn Marino UI_set_result(UI *ui, UI_STRING *uis, const char *result)
769f5b1c8a1SJohn Marino {
7708edacedfSDaniel Fojt 	const char *p;
771f5b1c8a1SJohn Marino 	int l = strlen(result);
772f5b1c8a1SJohn Marino 
773f5b1c8a1SJohn Marino 	ui->flags &= ~UI_FLAG_REDOABLE;
774f5b1c8a1SJohn Marino 
775f5b1c8a1SJohn Marino 	if (!uis)
776f5b1c8a1SJohn Marino 		return -1;
777f5b1c8a1SJohn Marino 	switch (uis->type) {
778f5b1c8a1SJohn Marino 	case UIT_PROMPT:
779f5b1c8a1SJohn Marino 	case UIT_VERIFY:
780f5b1c8a1SJohn Marino 		if (l < uis->_.string_data.result_minsize) {
781f5b1c8a1SJohn Marino 			ui->flags |= UI_FLAG_REDOABLE;
78272c33676SMaxim Ag 			UIerror(UI_R_RESULT_TOO_SMALL);
783f5b1c8a1SJohn Marino 			ERR_asprintf_error_data
784f5b1c8a1SJohn Marino 			    ("You must type in %d to %d characters",
785f5b1c8a1SJohn Marino 				uis->_.string_data.result_minsize,
786f5b1c8a1SJohn Marino 				uis->_.string_data.result_maxsize);
787f5b1c8a1SJohn Marino 			return -1;
788f5b1c8a1SJohn Marino 		}
789f5b1c8a1SJohn Marino 		if (l > uis->_.string_data.result_maxsize) {
790f5b1c8a1SJohn Marino 			ui->flags |= UI_FLAG_REDOABLE;
79172c33676SMaxim Ag 			UIerror(UI_R_RESULT_TOO_LARGE);
792f5b1c8a1SJohn Marino 			ERR_asprintf_error_data
793f5b1c8a1SJohn Marino 			    ("You must type in %d to %d characters",
794f5b1c8a1SJohn Marino 				uis->_.string_data.result_minsize,
795f5b1c8a1SJohn Marino 				uis->_.string_data.result_maxsize);
796f5b1c8a1SJohn Marino 			return -1;
797f5b1c8a1SJohn Marino 		}
798f5b1c8a1SJohn Marino 		if (!uis->result_buf) {
79972c33676SMaxim Ag 			UIerror(UI_R_NO_RESULT_BUFFER);
800f5b1c8a1SJohn Marino 			return -1;
801f5b1c8a1SJohn Marino 		}
802f5b1c8a1SJohn Marino 		strlcpy(uis->result_buf, result,
803f5b1c8a1SJohn Marino 		    uis->_.string_data.result_maxsize + 1);
804f5b1c8a1SJohn Marino 		break;
805f5b1c8a1SJohn Marino 	case UIT_BOOLEAN:
806f5b1c8a1SJohn Marino 		if (!uis->result_buf) {
80772c33676SMaxim Ag 			UIerror(UI_R_NO_RESULT_BUFFER);
808f5b1c8a1SJohn Marino 			return -1;
809f5b1c8a1SJohn Marino 		}
810f5b1c8a1SJohn Marino 		uis->result_buf[0] = '\0';
811f5b1c8a1SJohn Marino 		for (p = result; *p; p++) {
812f5b1c8a1SJohn Marino 			if (strchr(uis->_.boolean_data.ok_chars, *p)) {
813f5b1c8a1SJohn Marino 				uis->result_buf[0] =
814f5b1c8a1SJohn Marino 				    uis->_.boolean_data.ok_chars[0];
815f5b1c8a1SJohn Marino 				break;
816f5b1c8a1SJohn Marino 			}
817f5b1c8a1SJohn Marino 			if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
818f5b1c8a1SJohn Marino 				uis->result_buf[0] =
819f5b1c8a1SJohn Marino 				    uis->_.boolean_data.cancel_chars[0];
820f5b1c8a1SJohn Marino 				break;
821f5b1c8a1SJohn Marino 			}
822f5b1c8a1SJohn Marino 		}
823f5b1c8a1SJohn Marino 	default:
824f5b1c8a1SJohn Marino 		break;
825f5b1c8a1SJohn Marino 	}
826f5b1c8a1SJohn Marino 	return 0;
827f5b1c8a1SJohn Marino }
828