summaryrefslogtreecommitdiffstats
path: root/crypto/ui/ui_lib.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2001-06-23 16:22:48 +0000
committerRichard Levitte <levitte@openssl.org>2001-06-23 16:22:48 +0000
commit2d2ed9dffd6c2f3bb1c591bdc282f0bb3c19132e (patch)
treea6ea9ca5df9f5b4ba80ad00cb81eaca08d915243 /crypto/ui/ui_lib.c
parent8ada6e7705685be0d97987d31f23e6cf543ef544 (diff)
Implement boolean (yes/no or OK/Cancel, ...) input.
Implement UI controls. Current controls are the possibility to output the OpenSSL error stack on the same channel from within UI_process() and to check if the same user interface can be redone without being rebuilt (this is often more a question of philosophy than technicalities).
Diffstat (limited to 'crypto/ui/ui_lib.c')
-rw-r--r--crypto/ui/ui_lib.c350
1 files changed, 314 insertions, 36 deletions
diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c
index 395f700ffd..2559ea54b6 100644
--- a/crypto/ui/ui_lib.c
+++ b/crypto/ui/ui_lib.c
@@ -98,7 +98,19 @@ UI *UI_new_method(const UI_METHOD *method)
static void free_string(UI_STRING *uis)
{
if (uis->flags & OUT_STRING_FREEABLE)
+ {
OPENSSL_free((char *)uis->out_string);
+ switch(uis->type)
+ {
+ case UIT_BOOLEAN:
+ OPENSSL_free((char *)uis->_.boolean_data.action_desc);
+ OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
+ OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
+ break;
+ default:
+ break;
+ }
+ }
OPENSSL_free(uis);
}
@@ -123,28 +135,98 @@ static int allocate_string_stack(UI *ui)
return 0;
}
+static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
+ int prompt_freeable, enum UI_string_types type, int input_flags,
+ char *result_buf)
+ {
+ UI_STRING *ret = NULL;
+
+ if (prompt == NULL)
+ {
+ UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,ERR_R_PASSED_NULL_PARAMETER);
+ }
+ else if (result_buf == NULL)
+ {
+ UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,UI_R_NO_RESULT_BUFFER);
+ }
+ else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING))))
+ {
+ ret->out_string=prompt;
+ ret->flags=prompt_freeable ? OUT_STRING_FREEABLE : 0;
+ ret->input_flags=input_flags;
+ ret->type=type;
+ ret->result_buf=result_buf;
+ }
+ return ret;
+ }
+
static int general_allocate_string(UI *ui, const char *prompt,
int prompt_freeable, enum UI_string_types type, int input_flags,
char *result_buf, int minsize, int maxsize, const char *test_buf)
{
- int ret=-1;
+ int ret = -1;
+ UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
+ type, input_flags, result_buf);
- if (prompt == NULL)
+ if (s)
+ {
+ if (allocate_string_stack(ui) >= 0)
+ {
+ s->_.string_data.result_minsize=minsize;
+ s->_.string_data.result_maxsize=maxsize;
+ s->_.string_data.test_buf=test_buf;
+ ret=sk_UI_STRING_push(ui->strings, s);
+ }
+ else
+ free_string(s);
+ }
+ return ret;
+ }
+
+static int general_allocate_boolean(UI *ui,
+ const char *prompt, const char *action_desc,
+ const char *ok_chars, const char *cancel_chars,
+ int prompt_freeable, enum UI_string_types type, int input_flags,
+ char *result_buf)
+ {
+ int ret = -1;
+ UI_STRING *s;
+ const char *p;
+
+ if (ok_chars == NULL)
{
- UIerr(UI_F_GENERAL_ALLOCATE_STRING,ERR_R_PASSED_NULL_PARAMETER);
+ UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
}
- else if (allocate_string_stack(ui) >= 0)
+ else if (cancel_chars == NULL)
{
- UI_STRING *s=(UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING));
- s->out_string=prompt;
- s->flags=prompt_freeable ? OUT_STRING_FREEABLE : 0;
- s->input_flags=input_flags;
- s->type=type;
- s->result_buf=result_buf;
- s->result_minsize=minsize;
- s->result_maxsize=maxsize;
- s->test_buf=test_buf;
- ret=sk_UI_STRING_push(ui->strings, s);
+ UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
+ }
+ else
+ {
+ for(p = ok_chars; *p; p++)
+ {
+ if (strchr(cancel_chars, *p))
+ {
+ UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
+ UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
+ }
+ }
+
+ s = general_allocate_prompt(ui, prompt, prompt_freeable,
+ type, input_flags, result_buf);
+
+ if (s)
+ {
+ if (allocate_string_stack(ui) >= 0)
+ {
+ s->_.boolean_data.action_desc = action_desc;
+ s->_.boolean_data.ok_chars = ok_chars;
+ s->_.boolean_data.cancel_chars = cancel_chars;
+ ret=sk_UI_STRING_push(ui->strings, s);
+ }
+ else
+ free_string(s);
+ }
}
return ret;
}
@@ -204,6 +286,74 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
}
+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)
+ {
+ return general_allocate_boolean(ui, prompt, action_desc,
+ ok_chars, cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
+ }
+
+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)
+ {
+ char *prompt_copy = NULL;
+ char *action_desc_copy = NULL;
+ char *ok_chars_copy = NULL;
+ char *cancel_chars_copy = NULL;
+
+ if (prompt)
+ {
+ prompt_copy=BUF_strdup(prompt);
+ if (prompt_copy == NULL)
+ {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (action_desc)
+ {
+ action_desc_copy=BUF_strdup(action_desc);
+ if (action_desc_copy == NULL)
+ {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (ok_chars)
+ {
+ ok_chars_copy=BUF_strdup(ok_chars);
+ if (ok_chars_copy == NULL)
+ {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (cancel_chars)
+ {
+ cancel_chars_copy=BUF_strdup(cancel_chars);
+ if (cancel_chars_copy == NULL)
+ {
+ UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
+ ok_chars_copy, cancel_chars_copy, 1, UIT_BOOLEAN, flags,
+ result_buf);
+ err:
+ if (prompt_copy) OPENSSL_free(prompt_copy);
+ if (action_desc_copy) OPENSSL_free(action_desc_copy);
+ if (ok_chars_copy) OPENSSL_free(ok_chars_copy);
+ if (cancel_chars_copy) OPENSSL_free(cancel_chars_copy);
+ return -1;
+ }
+
int UI_add_info_string(UI *ui, const char *text)
{
return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
@@ -224,8 +374,8 @@ int UI_dup_info_string(UI *ui, const char *text)
}
}
- return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, 0, 0,
- NULL);
+ return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
+ 0, 0, NULL);
}
int UI_add_error_string(UI *ui, const char *text)
@@ -313,6 +463,20 @@ const char *UI_get0_result(UI *ui, int i)
return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
}
+static int print_error(const char *str, size_t len, UI *ui)
+ {
+ UI_STRING uis;
+
+ memset(&uis, 0, sizeof(uis));
+ uis.type = UIT_ERROR;
+ uis.out_string = str;
+
+ if (ui->meth->ui_write_string
+ && !ui->meth->ui_write_string(ui, &uis))
+ return -1;
+ return 0;
+ }
+
int UI_process(UI *ui)
{
int i, ok=0;
@@ -320,6 +484,11 @@ int UI_process(UI *ui)
if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
return -1;
+ if (ui->flags & UI_FLAG_PRINT_ERRORS)
+ ERR_print_errors_cb(
+ (int (*)(const char *, size_t, void *))print_error,
+ (void *)ui);
+
for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
{
if (ui->meth->ui_write_string
@@ -370,6 +539,33 @@ int UI_process(UI *ui)
return ok;
}
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)())
+ {
+ if (ui == NULL)
+ {
+ UIerr(UI_F_UI_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+ switch(cmd)
+ {
+ case UI_CTRL_PRINT_ERRORS:
+ {
+ int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
+ if (i)
+ ui->flags |= UI_FLAG_PRINT_ERRORS;
+ else
+ ui->flags &= ~UI_FLAG_PRINT_ERRORS;
+ return save_flag;
+ }
+ case UI_CTRL_IS_REDOABLE:
+ return !!(ui->flags & UI_FLAG_REDOABLE);
+ default:
+ break;
+ }
+ UIerr(UI_F_UI_CTRL,UI_R_UNKNOWN_CONTROL_COMMAND);
+ return -1;
+ }
+
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)
{
@@ -542,6 +738,20 @@ const char *UI_get0_output_string(UI_STRING *uis)
return uis->out_string;
}
+const char *UI_get0_action_string(UI_STRING *uis)
+ {
+ if (!uis)
+ return NULL;
+ switch(uis->type)
+ {
+ case UIT_PROMPT:
+ case UIT_BOOLEAN:
+ return uis->_.boolean_data.action_desc;
+ default:
+ return NULL;
+ }
+ }
+
const char *UI_get0_result_string(UI_STRING *uis)
{
if (!uis)
@@ -560,51 +770,119 @@ const char *UI_get0_test_string(UI_STRING *uis)
{
if (!uis)
return NULL;
- return uis->test_buf;
+ switch(uis->type)
+ {
+ case UIT_VERIFY:
+ return uis->_.string_data.test_buf;
+ default:
+ return NULL;
+ }
}
int UI_get_result_minsize(UI_STRING *uis)
{
if (!uis)
return -1;
- return uis->result_minsize;
+ switch(uis->type)
+ {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ return uis->_.string_data.result_minsize;
+ default:
+ return -1;
+ }
}
int UI_get_result_maxsize(UI_STRING *uis)
{
if (!uis)
return -1;
- return uis->result_maxsize;
+ switch(uis->type)
+ {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ return uis->_.string_data.result_maxsize;
+ default:
+ return -1;
+ }
}
-int UI_set_result(UI_STRING *uis, const char *result)
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
{
int l = strlen(result);
+ ui->flags &= ~UI_FLAG_REDOABLE;
+
if (!uis)
return -1;
- if (l < uis->result_minsize)
+ switch (uis->type)
{
- UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_SMALL);
- return -1;
- }
- if (l > uis->result_maxsize)
+ case UIT_PROMPT:
+ case UIT_VERIFY:
{
- UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_LARGE);
- return -1;
- }
+ char number1[20];
+ char number2[20];
- if (!uis->result_buf)
- {
- uis->result_buf = OPENSSL_malloc(uis->result_maxsize+1);
+ BIO_snprintf(number1, sizeof(number1), "%d",
+ uis->_.string_data.result_minsize);
+ BIO_snprintf(number2, sizeof(number2), "%d",
+ uis->_.string_data.result_maxsize);
+
+ if (l < uis->_.string_data.result_minsize)
+ {
+ ui->flags |= UI_FLAG_REDOABLE;
+ UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_SMALL);
+ ERR_add_error_data(5,"You must type in ",
+ number1," to ",number2," characters");
+ return -1;
+ }
+ if (l > uis->_.string_data.result_maxsize)
+ {
+ ui->flags |= UI_FLAG_REDOABLE;
+ UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_LARGE);
+ ERR_add_error_data(5,"You must type in ",
+ number1," to ",number2," characters");
+ return -1;
+ }
}
- if (!uis->result_buf)
+ if (!uis->result_buf)
+ {
+ UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
+ return -1;
+ }
+
+ strcpy(uis->result_buf, result);
+ break;
+ case UIT_BOOLEAN:
{
- UIerr(UI_F_UI_NEW_METHOD,ERR_R_MALLOC_FAILURE);
- return -1;
- }
+ const char *p;
- strcpy(uis->result_buf, result);
+ if (!uis->result_buf)
+ {
+ UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
+ return -1;
+ }
+
+ uis->result_buf[0] = '\0';
+ for(p = result; *p; p++)
+ {
+ if (strchr(uis->_.boolean_data.ok_chars, *p))
+ {
+ uis->result_buf[0] =
+ uis->_.boolean_data.ok_chars[0];
+ break;
+ }
+ if (strchr(uis->_.boolean_data.cancel_chars, *p))
+ {
+ uis->result_buf[0] =
+ uis->_.boolean_data.cancel_chars[0];
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ }
return 0;
}