The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / openssl / openssl / crypto / ui / ui_lib.c @ aa3b4b4d

History | View | Annotate | Download (20.1 KB)

1
/* crypto/ui/ui_lib.c -*- mode:C; c-file-style: "eay" -*- */
2
/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3
 * project 2001.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer. 
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    openssl-core@openssl.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58

    
59
#include <string.h>
60
#include "cryptlib.h"
61
#include <openssl/e_os2.h>
62
#include <openssl/buffer.h>
63
#include <openssl/ui.h>
64
#include <openssl/err.h>
65
#include "ui_locl.h"
66

    
67
IMPLEMENT_STACK_OF(UI_STRING_ST)
68

    
69
static const UI_METHOD *default_UI_meth=NULL;
70

    
71
UI *UI_new(void)
72
        {
73
        return(UI_new_method(NULL));
74
        }
75

    
76
UI *UI_new_method(const UI_METHOD *method)
77
        {
78
        UI *ret;
79

    
80
        ret=(UI *)OPENSSL_malloc(sizeof(UI));
81
        if (ret == NULL)
82
                {
83
                UIerr(UI_F_UI_NEW_METHOD,ERR_R_MALLOC_FAILURE);
84
                return NULL;
85
                }
86
        if (method == NULL)
87
                ret->meth=UI_get_default_method();
88
        else
89
                ret->meth=method;
90

    
91
        ret->strings=NULL;
92
        ret->user_data=NULL;
93
        ret->flags=0;
94
        CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
95
        return ret;
96
        }
97

    
98
static void free_string(UI_STRING *uis)
99
        {
100
        if (uis->flags & OUT_STRING_FREEABLE)
101
                {
102
                OPENSSL_free((char *)uis->out_string);
103
                switch(uis->type)
104
                        {
105
                case UIT_BOOLEAN:
106
                        OPENSSL_free((char *)uis->_.boolean_data.action_desc);
107
                        OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
108
                        OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
109
                        break;
110
                default:
111
                        break;
112
                        }
113
                }
114
        OPENSSL_free(uis);
115
        }
116

    
117
void UI_free(UI *ui)
118
        {
119
        if (ui == NULL)
120
                return;
121
        sk_UI_STRING_pop_free(ui->strings,free_string);
122
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
123
        OPENSSL_free(ui);
124
        }
125

    
126
static int allocate_string_stack(UI *ui)
127
        {
128
        if (ui->strings == NULL)
129
                {
130
                ui->strings=sk_UI_STRING_new_null();
131
                if (ui->strings == NULL)
132
                        {
133
                        return -1;
134
                        }
135
                }
136
        return 0;
137
        }
138

    
139
static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
140
        int prompt_freeable, enum UI_string_types type, int input_flags,
141
        char *result_buf)
142
        {
143
        UI_STRING *ret = NULL;
144

    
145
        if (prompt == NULL)
146
                {
147
                UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,ERR_R_PASSED_NULL_PARAMETER);
148
                }
149
        else if ((type == UIT_PROMPT || type == UIT_VERIFY
150
                         || type == UIT_BOOLEAN) && result_buf == NULL)
151
                {
152
                UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,UI_R_NO_RESULT_BUFFER);
153
                }
154
        else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING))))
155
                {
156
                ret->out_string=prompt;
157
                ret->flags=prompt_freeable ? OUT_STRING_FREEABLE : 0;
158
                ret->input_flags=input_flags;
159
                ret->type=type;
160
                ret->result_buf=result_buf;
161
                }
162
        return ret;
163
        }
164

    
165
static int general_allocate_string(UI *ui, const char *prompt,
166
        int prompt_freeable, enum UI_string_types type, int input_flags,
167
        char *result_buf, int minsize, int maxsize, const char *test_buf)
168
        {
169
        int ret = -1;
170
        UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
171
                type, input_flags, result_buf);
172

    
173
        if (s)
174
                {
175
                if (allocate_string_stack(ui) >= 0)
176
                        {
177
                        s->_.string_data.result_minsize=minsize;
178
                        s->_.string_data.result_maxsize=maxsize;
179
                        s->_.string_data.test_buf=test_buf;
180
                        ret=sk_UI_STRING_push(ui->strings, s);
181
                        /* sk_push() returns 0 on error.  Let's addapt that */
182
                        if (ret <= 0) ret--;
183
                        }
184
                else
185
                        free_string(s);
186
                }
187
        return ret;
188
        }
189

    
190
static int general_allocate_boolean(UI *ui,
191
        const char *prompt, const char *action_desc,
192
        const char *ok_chars, const char *cancel_chars,
193
        int prompt_freeable, enum UI_string_types type, int input_flags,
194
        char *result_buf)
195
        {
196
        int ret = -1;
197
        UI_STRING *s;
198
        const char *p;
199

    
200
        if (ok_chars == NULL)
201
                {
202
                UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
203
                }
204
        else if (cancel_chars == NULL)
205
                {
206
                UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
207
                }
208
        else
209
                {
210
                for(p = ok_chars; *p; p++)
211
                        {
212
                        if (strchr(cancel_chars, *p))
213
                                {
214
                                UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
215
                                        UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
216
                                }
217
                        }
218

    
219
                s = general_allocate_prompt(ui, prompt, prompt_freeable,
220
                        type, input_flags, result_buf);
221

    
222
                if (s)
223
                        {
224
                        if (allocate_string_stack(ui) >= 0)
225
                                {
226
                                s->_.boolean_data.action_desc = action_desc;
227
                                s->_.boolean_data.ok_chars = ok_chars;
228
                                s->_.boolean_data.cancel_chars = cancel_chars;
229
                                ret=sk_UI_STRING_push(ui->strings, s);
230
                                /* sk_push() returns 0 on error.
231
                                   Let's addapt that */
232
                                if (ret <= 0) ret--;
233
                                }
234
                        else
235
                                free_string(s);
236
                        }
237
                }
238
        return ret;
239
        }
240

    
241
/* Returns the index to the place in the stack or -1 for error.  Uses a
242
   direct reference to the prompt.  */
243
int UI_add_input_string(UI *ui, const char *prompt, int flags,
244
        char *result_buf, int minsize, int maxsize)
245
        {
246
        return general_allocate_string(ui, prompt, 0,
247
                UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
248
        }
249

    
250
/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
251
int UI_dup_input_string(UI *ui, const char *prompt, int flags,
252
        char *result_buf, int minsize, int maxsize)
253
        {
254
        char *prompt_copy=NULL;
255

    
256
        if (prompt)
257
                {
258
                prompt_copy=BUF_strdup(prompt);
259
                if (prompt_copy == NULL)
260
                        {
261
                        UIerr(UI_F_UI_DUP_INPUT_STRING,ERR_R_MALLOC_FAILURE);
262
                        return 0;
263
                        }
264
                }
265
        
266
        return general_allocate_string(ui, prompt_copy, 1,
267
                UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
268
        }
269

    
270
int UI_add_verify_string(UI *ui, const char *prompt, int flags,
271
        char *result_buf, int minsize, int maxsize, const char *test_buf)
272
        {
273
        return general_allocate_string(ui, prompt, 0,
274
                UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
275
        }
276

    
277
int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
278
        char *result_buf, int minsize, int maxsize, const char *test_buf)
279
        {
280
        char *prompt_copy=NULL;
281

    
282
        if (prompt)
283
                {
284
                prompt_copy=BUF_strdup(prompt);
285
                if (prompt_copy == NULL)
286
                        {
287
                        UIerr(UI_F_UI_DUP_VERIFY_STRING,ERR_R_MALLOC_FAILURE);
288
                        return -1;
289
                        }
290
                }
291
        
292
        return general_allocate_string(ui, prompt_copy, 1,
293
                UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
294
        }
295

    
296
int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
297
        const char *ok_chars, const char *cancel_chars,
298
        int flags, char *result_buf)
299
        {
300
        return general_allocate_boolean(ui, prompt, action_desc,
301
                ok_chars, cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
302
        }
303

    
304
int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
305
        const char *ok_chars, const char *cancel_chars,
306
        int flags, char *result_buf)
307
        {
308
        char *prompt_copy = NULL;
309
        char *action_desc_copy = NULL;
310
        char *ok_chars_copy = NULL;
311
        char *cancel_chars_copy = NULL;
312

    
313
        if (prompt)
314
                {
315
                prompt_copy=BUF_strdup(prompt);
316
                if (prompt_copy == NULL)
317
                        {
318
                        UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
319
                        goto err;
320
                        }
321
                }
322
        
323
        if (action_desc)
324
                {
325
                action_desc_copy=BUF_strdup(action_desc);
326
                if (action_desc_copy == NULL)
327
                        {
328
                        UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
329
                        goto err;
330
                        }
331
                }
332
        
333
        if (ok_chars)
334
                {
335
                ok_chars_copy=BUF_strdup(ok_chars);
336
                if (ok_chars_copy == NULL)
337
                        {
338
                        UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
339
                        goto err;
340
                        }
341
                }
342
        
343
        if (cancel_chars)
344
                {
345
                cancel_chars_copy=BUF_strdup(cancel_chars);
346
                if (cancel_chars_copy == NULL)
347
                        {
348
                        UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
349
                        goto err;
350
                        }
351
                }
352
        
353
        return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
354
                ok_chars_copy, cancel_chars_copy, 1, UIT_BOOLEAN, flags,
355
                result_buf);
356
 err:
357
        if (prompt_copy) OPENSSL_free(prompt_copy);
358
        if (action_desc_copy) OPENSSL_free(action_desc_copy);
359
        if (ok_chars_copy) OPENSSL_free(ok_chars_copy);
360
        if (cancel_chars_copy) OPENSSL_free(cancel_chars_copy);
361
        return -1;
362
        }
363

    
364
int UI_add_info_string(UI *ui, const char *text)
365
        {
366
        return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
367
                NULL);
368
        }
369

    
370
int UI_dup_info_string(UI *ui, const char *text)
371
        {
372
        char *text_copy=NULL;
373

    
374
        if (text)
375
                {
376
                text_copy=BUF_strdup(text);
377
                if (text_copy == NULL)
378
                        {
379
                        UIerr(UI_F_UI_DUP_INFO_STRING,ERR_R_MALLOC_FAILURE);
380
                        return -1;
381
                        }
382
                }
383

    
384
        return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
385
                0, 0, NULL);
386
        }
387

    
388
int UI_add_error_string(UI *ui, const char *text)
389
        {
390
        return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
391
                NULL);
392
        }
393

    
394
int UI_dup_error_string(UI *ui, const char *text)
395
        {
396
        char *text_copy=NULL;
397

    
398
        if (text)
399
                {
400
                text_copy=BUF_strdup(text);
401
                if (text_copy == NULL)
402
                        {
403
                        UIerr(UI_F_UI_DUP_ERROR_STRING,ERR_R_MALLOC_FAILURE);
404
                        return -1;
405
                        }
406
                }
407
        return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
408
                0, 0, NULL);
409
        }
410

    
411
char *UI_construct_prompt(UI *ui, const char *object_desc,
412
        const char *object_name)
413
        {
414
        char *prompt = NULL;
415

    
416
        if (ui->meth->ui_construct_prompt)
417
                prompt = ui->meth->ui_construct_prompt(ui,
418
                        object_desc, object_name);
419
        else
420
                {
421
                char prompt1[] = "Enter ";
422
                char prompt2[] = " for ";
423
                char prompt3[] = ":";
424
                int len = 0;
425

    
426
                if (object_desc == NULL)
427
                        return NULL;
428
                len = sizeof(prompt1) - 1 + strlen(object_desc);
429
                if (object_name)
430
                        len += sizeof(prompt2) - 1 + strlen(object_name);
431
                len += sizeof(prompt3) - 1;
432

    
433
                prompt = (char *)OPENSSL_malloc(len + 1);
434
                BUF_strlcpy(prompt, prompt1, len + 1);
435
                BUF_strlcat(prompt, object_desc, len + 1);
436
                if (object_name)
437
                        {
438
                        BUF_strlcat(prompt, prompt2, len + 1);
439
                        BUF_strlcat(prompt, object_name, len + 1);
440
                        }
441
                BUF_strlcat(prompt, prompt3, len + 1);
442
                }
443
        return prompt;
444
        }
445

    
446
void *UI_add_user_data(UI *ui, void *user_data)
447
        {
448
        void *old_data = ui->user_data;
449
        ui->user_data = user_data;
450
        return old_data;
451
        }
452

    
453
void *UI_get0_user_data(UI *ui)
454
        {
455
        return ui->user_data;
456
        }
457

    
458
const char *UI_get0_result(UI *ui, int i)
459
        {
460
        if (i < 0)
461
                {
462
                UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_SMALL);
463
                return NULL;
464
                }
465
        if (i >= sk_UI_STRING_num(ui->strings))
466
                {
467
                UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_LARGE);
468
                return NULL;
469
                }
470
        return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
471
        }
472

    
473
static int print_error(const char *str, size_t len, UI *ui)
474
        {
475
        UI_STRING uis;
476

    
477
        memset(&uis, 0, sizeof(uis));
478
        uis.type = UIT_ERROR;
479
        uis.out_string = str;
480

    
481
        if (ui->meth->ui_write_string
482
                && !ui->meth->ui_write_string(ui, &uis))
483
                return -1;
484
        return 0;
485
        }
486

    
487
int UI_process(UI *ui)
488
        {
489
        int i, ok=0;
490

    
491
        if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
492
                return -1;
493

    
494
        if (ui->flags & UI_FLAG_PRINT_ERRORS)
495
                ERR_print_errors_cb(
496
                        (int (*)(const char *, size_t, void *))print_error,
497
                        (void *)ui);
498

    
499
        for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
500
                {
501
                if (ui->meth->ui_write_string
502
                        && !ui->meth->ui_write_string(ui,
503
                                sk_UI_STRING_value(ui->strings, i)))
504
                        {
505
                        ok=-1;
506
                        goto err;
507
                        }
508
                }
509

    
510
        if (ui->meth->ui_flush)
511
                switch(ui->meth->ui_flush(ui))
512
                        {
513
                case -1: /* Interrupt/Cancel/something... */
514
                        ok = -2;
515
                        goto err;
516
                case 0: /* Errors */
517
                        ok = -1;
518
                        goto err;
519
                default: /* Success */
520
                        ok = 0;
521
                        break;
522
                        }
523

    
524
        for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
525
                {
526
                if (ui->meth->ui_read_string)
527
                        {
528
                        switch(ui->meth->ui_read_string(ui,
529
                                sk_UI_STRING_value(ui->strings, i)))
530
                                {
531
                        case -1: /* Interrupt/Cancel/something... */
532
                                ok = -2;
533
                                goto err;
534
                        case 0: /* Errors */
535
                                ok = -1;
536
                                goto err;
537
                        default: /* Success */
538
                                ok = 0;
539
                                break;
540
                                }
541
                        }
542
                }
543
 err:
544
        if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
545
                return -1;
546
        return ok;
547
        }
548

    
549
int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void))
550
        {
551
        if (ui == NULL)
552
                {
553
                UIerr(UI_F_UI_CTRL,ERR_R_PASSED_NULL_PARAMETER);
554
                return -1;
555
                }
556
        switch(cmd)
557
                {
558
        case UI_CTRL_PRINT_ERRORS:
559
                {
560
                int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
561
                if (i)
562
                        ui->flags |= UI_FLAG_PRINT_ERRORS;
563
                else
564
                        ui->flags &= ~UI_FLAG_PRINT_ERRORS;
565
                return save_flag;
566
                }
567
        case UI_CTRL_IS_REDOABLE:
568
                return !!(ui->flags & UI_FLAG_REDOABLE);
569
        default:
570
                break;
571
                }
572
        UIerr(UI_F_UI_CTRL,UI_R_UNKNOWN_CONTROL_COMMAND);
573
        return -1;
574
        }
575

    
576
int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
577
             CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
578
        {
579
        return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
580
                                new_func, dup_func, free_func);
581
        }
582

    
583
int UI_set_ex_data(UI *r, int idx, void *arg)
584
        {
585
        return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
586
        }
587

    
588
void *UI_get_ex_data(UI *r, int idx)
589
        {
590
        return(CRYPTO_get_ex_data(&r->ex_data,idx));
591
        }
592

    
593
void UI_set_default_method(const UI_METHOD *meth)
594
        {
595
        default_UI_meth=meth;
596
        }
597

    
598
const UI_METHOD *UI_get_default_method(void)
599
        {
600
        if (default_UI_meth == NULL)
601
                {
602
                default_UI_meth=UI_OpenSSL();
603
                }
604
        return default_UI_meth;
605
        }
606

    
607
const UI_METHOD *UI_get_method(UI *ui)
608
        {
609
        return ui->meth;
610
        }
611

    
612
const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
613
        {
614
        ui->meth=meth;
615
        return ui->meth;
616
        }
617

    
618

    
619
UI_METHOD *UI_create_method(char *name)
620
        {
621
        UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD));
622

    
623
        if (ui_method)
624
                {
625
                memset(ui_method, 0, sizeof(*ui_method));
626
                ui_method->name = BUF_strdup(name);
627
                }
628
        return ui_method;
629
        }
630

    
631
/* BIG FSCKING WARNING!!!!  If you use this on a statically allocated method
632
   (that is, it hasn't been allocated using UI_create_method(), you deserve
633
   anything Murphy can throw at you and more!  You have been warned. */
634
void UI_destroy_method(UI_METHOD *ui_method)
635
        {
636
        OPENSSL_free(ui_method->name);
637
        ui_method->name = NULL;
638
        OPENSSL_free(ui_method);
639
        }
640

    
641
int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui))
642
        {
643
        if (method)
644
                {
645
                method->ui_open_session = opener;
646
                return 0;
647
                }
648
        else
649
                return -1;
650
        }
651

    
652
int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis))
653
        {
654
        if (method)
655
                {
656
                method->ui_write_string = writer;
657
                return 0;
658
                }
659
        else
660
                return -1;
661
        }
662

    
663
int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui))
664
        {
665
        if (method)
666
                {
667
                method->ui_flush = flusher;
668
                return 0;
669
                }
670
        else
671
                return -1;
672
        }
673

    
674
int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))
675
        {
676
        if (method)
677
                {
678
                method->ui_read_string = reader;
679
                return 0;
680
                }
681
        else
682
                return -1;
683
        }
684

    
685
int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
686
        {
687
        if (method)
688
                {
689
                method->ui_close_session = closer;
690
                return 0;
691
                }
692
        else
693
                return -1;
694
        }
695

    
696
int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name))
697
        {
698
        if (method)
699
                {
700
                method->ui_construct_prompt = prompt_constructor;
701
                return 0;
702
                }
703
        else
704
                return -1;
705
        }
706

    
707
int (*UI_method_get_opener(UI_METHOD *method))(UI*)
708
        {
709
        if (method)
710
                return method->ui_open_session;
711
        else
712
                return NULL;
713
        }
714

    
715
int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*)
716
        {
717
        if (method)
718
                return method->ui_write_string;
719
        else
720
                return NULL;
721
        }
722

    
723
int (*UI_method_get_flusher(UI_METHOD *method))(UI*)
724
        {
725
        if (method)
726
                return method->ui_flush;
727
        else
728
                return NULL;
729
        }
730

    
731
int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*)
732
        {
733
        if (method)
734
                return method->ui_read_string;
735
        else
736
                return NULL;
737
        }
738

    
739
int (*UI_method_get_closer(UI_METHOD *method))(UI*)
740
        {
741
        if (method)
742
                return method->ui_close_session;
743
        else
744
                return NULL;
745
        }
746

    
747
char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*)
748
        {
749
        if (method)
750
                return method->ui_construct_prompt;
751
        else
752
                return NULL;
753
        }
754

    
755
enum UI_string_types UI_get_string_type(UI_STRING *uis)
756
        {
757
        if (!uis)
758
                return UIT_NONE;
759
        return uis->type;
760
        }
761

    
762
int UI_get_input_flags(UI_STRING *uis)
763
        {
764
        if (!uis)
765
                return 0;
766
        return uis->input_flags;
767
        }
768

    
769
const char *UI_get0_output_string(UI_STRING *uis)
770
        {
771
        if (!uis)
772
                return NULL;
773
        return uis->out_string;
774
        }
775

    
776
const char *UI_get0_action_string(UI_STRING *uis)
777
        {
778
        if (!uis)
779
                return NULL;
780
        switch(uis->type)
781
                {
782
        case UIT_PROMPT:
783
        case UIT_BOOLEAN:
784
                return uis->_.boolean_data.action_desc;
785
        default:
786
                return NULL;
787
                }
788
        }
789

    
790
const char *UI_get0_result_string(UI_STRING *uis)
791
        {
792
        if (!uis)
793
                return NULL;
794
        switch(uis->type)
795
                {
796
        case UIT_PROMPT:
797
        case UIT_VERIFY:
798
                return uis->result_buf;
799
        default:
800
                return NULL;
801
                }
802
        }
803

    
804
const char *UI_get0_test_string(UI_STRING *uis)
805
        {
806
        if (!uis)
807
                return NULL;
808
        switch(uis->type)
809
                {
810
        case UIT_VERIFY:
811
                return uis->_.string_data.test_buf;
812
        default:
813
                return NULL;
814
                }
815
        }
816

    
817
int UI_get_result_minsize(UI_STRING *uis)
818
        {
819
        if (!uis)
820
                return -1;
821
        switch(uis->type)
822
                {
823
        case UIT_PROMPT:
824
        case UIT_VERIFY:
825
                return uis->_.string_data.result_minsize;
826
        default:
827
                return -1;
828
                }
829
        }
830

    
831
int UI_get_result_maxsize(UI_STRING *uis)
832
        {
833
        if (!uis)
834
                return -1;
835
        switch(uis->type)
836
                {
837
        case UIT_PROMPT:
838
        case UIT_VERIFY:
839
                return uis->_.string_data.result_maxsize;
840
        default:
841
                return -1;
842
                }
843
        }
844

    
845
int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
846
        {
847
        int l = strlen(result);
848

    
849
        ui->flags &= ~UI_FLAG_REDOABLE;
850

    
851
        if (!uis)
852
                return -1;
853
        switch (uis->type)
854
                {
855
        case UIT_PROMPT:
856
        case UIT_VERIFY:
857
                {
858
                char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize)+1];
859
                char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize)+1];
860

    
861
                BIO_snprintf(number1, sizeof(number1), "%d",
862
                        uis->_.string_data.result_minsize);
863
                BIO_snprintf(number2, sizeof(number2), "%d",
864
                        uis->_.string_data.result_maxsize);
865

    
866
                if (l < uis->_.string_data.result_minsize)
867
                        {
868
                        ui->flags |= UI_FLAG_REDOABLE;
869
                        UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_SMALL);
870
                        ERR_add_error_data(5,"You must type in ",
871
                                number1," to ",number2," characters");
872
                        return -1;
873
                        }
874
                if (l > uis->_.string_data.result_maxsize)
875
                        {
876
                        ui->flags |= UI_FLAG_REDOABLE;
877
                        UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_LARGE);
878
                        ERR_add_error_data(5,"You must type in ",
879
                                number1," to ",number2," characters");
880
                        return -1;
881
                        }
882
                }
883

    
884
                if (!uis->result_buf)
885
                        {
886
                        UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
887
                        return -1;
888
                        }
889

    
890
                BUF_strlcpy(uis->result_buf, result,
891
                            uis->_.string_data.result_maxsize + 1);
892
                break;
893
        case UIT_BOOLEAN:
894
                {
895
                const char *p;
896

    
897
                if (!uis->result_buf)
898
                        {
899
                        UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
900
                        return -1;
901
                        }
902

    
903
                uis->result_buf[0] = '\0';
904
                for(p = result; *p; p++)
905
                        {
906
                        if (strchr(uis->_.boolean_data.ok_chars, *p))
907
                                {
908
                                uis->result_buf[0] =
909
                                        uis->_.boolean_data.ok_chars[0];
910
                                break;
911
                                }
912
                        if (strchr(uis->_.boolean_data.cancel_chars, *p))
913
                                {
914
                                uis->result_buf[0] =
915
                                        uis->_.boolean_data.cancel_chars[0];
916
                                break;
917
                                }
918
                        }
919
                }
920
        default:
921
                break;
922
                }
923
        return 0;
924
        }