Revision bb5fc20f

b/block.c
430 430
        }
431 431
    }
432 432

  
433
    /* call the change callback */
434
    bs->media_changed = 1;
435
    if (bs->change_cb)
436
        bs->change_cb(bs->change_opaque);
437

  
433
    if (!bdrv_key_required(bs)) {
434
        /* call the change callback */
435
        bs->media_changed = 1;
436
        if (bs->change_cb)
437
            bs->change_cb(bs->change_opaque);
438
    }
438 439
    return 0;
439 440
}
440 441

  
......
989 990
    if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
990 991
        return -1;
991 992
    ret = bs->drv->bdrv_set_key(bs, key);
992
    bs->valid_key = (ret == 0);
993
    if (ret < 0) {
994
        bs->valid_key = 0;
995
    } else if (!bs->valid_key) {
996
        bs->valid_key = 1;
997
        /* call the change callback now, we skipped it on open */
998
        bs->media_changed = 1;
999
        if (bs->change_cb)
1000
            bs->change_cb(bs->change_opaque);
1001
    }
993 1002
    return ret;
994 1003
}
995 1004

  
b/console.h
304 304
void term_print_help(void);
305 305
void monitor_suspend(void);
306 306
void monitor_resume(void);
307
int monitor_read_bdrv_key(BlockDriverState *bs);
307

  
308
#include "block.h"
309
void monitor_read_bdrv_key_start(BlockDriverState *bs,
310
                                 BlockDriverCompletionFunc *completion_cb,
311
                                 void *opaque);
308 312

  
309 313
/* readline.c */
310 314
typedef void ReadLineFunc(void *opaque, const char *str);
b/hw/usb-msd.c
514 514
    qemu_free(s);
515 515
}
516 516

  
517
USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs)
517
USBDevice *usb_msd_init(const char *filename)
518 518
{
519 519
    MSDState *s;
520 520
    BlockDriverState *bdrv;
......
554 554
    if (bdrv_open2(bdrv, filename, 0, drv) < 0)
555 555
        goto fail;
556 556
    s->bs = bdrv;
557
    *pbs = bdrv;
558 557

  
559 558
    s->dev.speed = USB_SPEED_FULL;
560 559
    s->dev.handle_packet = usb_generic_handle_packet;
......
574 573
    qemu_free(s);
575 574
    return NULL;
576 575
}
576

  
577
BlockDriverState *usb_msd_get_bdrv(USBDevice *dev)
578
{
579
    MSDState *s = (MSDState *)dev;
580

  
581
    return s->bs;
582
}
b/hw/usb.h
253 253
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
254 254

  
255 255
/* usb-msd.c */
256
USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs);
256
USBDevice *usb_msd_init(const char *filename);
257
BlockDriverState *usb_msd_get_bdrv(USBDevice *dev);
257 258

  
258 259
/* usb-net.c */
259 260
USBDevice *usb_net_init(NICInfo *nd);
b/monitor.c
74 74

  
75 75
static uint8_t term_outbuf[1024];
76 76
static int term_outbuf_index;
77
static BlockDriverCompletionFunc *password_completion_cb;
78
static void *password_opaque;
77 79

  
78 80
static void monitor_start_input(void);
79
static void monitor_readline(const char *prompt, int is_password,
80
                             char *buf, int buf_size);
81 81

  
82 82
static CPUState *mon_cpu = NULL;
83 83

  
84
static void monitor_read_password(ReadLineFunc *readline_func, void *opaque)
85
{
86
    readline_start("Password: ", 1, readline_func, opaque);
87
}
88

  
84 89
void term_flush(void)
85 90
{
86 91
    int i;
......
435 440
    if (eject_device(bs, 0) < 0)
436 441
        return;
437 442
    bdrv_open2(bs, filename, 0, drv);
438
    monitor_read_bdrv_key(bs);
443
    monitor_read_bdrv_key_start(bs, NULL, NULL);
444
}
445

  
446
static void change_vnc_password_cb(void *opaque, const char *password)
447
{
448
    if (vnc_display_password(NULL, password) < 0)
449
        term_printf("could not set VNC server password\n");
450

  
451
    monitor_start_input();
439 452
}
440 453

  
441 454
static void do_change_vnc(const char *target, const char *arg)
442 455
{
443 456
    if (strcmp(target, "passwd") == 0 ||
444 457
	strcmp(target, "password") == 0) {
445
	char password[9];
446 458
	if (arg) {
459
            char password[9];
447 460
	    strncpy(password, arg, sizeof(password));
448 461
	    password[sizeof(password) - 1] = '\0';
449
	} else
450
	    monitor_readline("Password: ", 1, password, sizeof(password));
451
	if (vnc_display_password(NULL, password) < 0)
452
	    term_printf("could not set VNC server password\n");
462
            change_vnc_password_cb(NULL, password);
463
        } else {
464
            monitor_read_password(change_vnc_password_cb, NULL);
465
        }
453 466
    } else {
454 467
	if (vnc_display_open(NULL, target) < 0)
455 468
	    term_printf("could not start VNC server on %s\n", target);
......
496 509
    vm_stop(EXCP_INTERRUPT);
497 510
}
498 511

  
499
static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
500
{
501
    int *err = opaque;
502

  
503
    if (bdrv_key_required(bs))
504
        *err = monitor_read_bdrv_key(bs);
505
    else
506
        *err = 0;
507
}
512
static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs);
508 513

  
509 514
static void do_cont(void)
510 515
{
......
516 521
        vm_start();
517 522
}
518 523

  
524
static void bdrv_key_cb(void *opaque, int err)
525
{
526
    /* another key was set successfully, retry to continue */
527
    if (!err)
528
        do_cont();
529
}
530

  
531
static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
532
{
533
    int *err = opaque;
534

  
535
    if (!*err && bdrv_key_required(bs)) {
536
        *err = -EBUSY;
537
        monitor_read_bdrv_key_start(bs, bdrv_key_cb, NULL);
538
    }
539
}
540

  
519 541
#ifdef CONFIG_GDBSTUB
520 542
static void do_gdbserver(const char *port)
521 543
{
......
2835 2857
{
2836 2858
    monitor_handle_command(cmdline);
2837 2859
    if (!monitor_suspended)
2838
        monitor_start_input();
2860
        readline_show_prompt();
2839 2861
    else
2840 2862
        monitor_suspended = 2;
2841 2863
}
......
2898 2920
    readline_start("", 0, monitor_handle_command1, NULL);
2899 2921
}
2900 2922

  
2901
/* XXX: use threads ? */
2902
/* modal monitor readline */
2903
static int monitor_readline_started;
2904
static char *monitor_readline_buf;
2905
static int monitor_readline_buf_size;
2906

  
2907
static void monitor_readline_cb(void *opaque, const char *input)
2923
static void bdrv_password_cb(void *opaque, const char *password)
2908 2924
{
2909
    pstrcpy(monitor_readline_buf, monitor_readline_buf_size, input);
2910
    monitor_readline_started = 0;
2911
}
2925
    BlockDriverState *bs = opaque;
2926
    int ret = 0;
2912 2927

  
2913
static void monitor_readline(const char *prompt, int is_password,
2914
                             char *buf, int buf_size)
2915
{
2916
    readline_start(prompt, is_password, monitor_readline_cb, NULL);
2917
    readline_show_prompt();
2918
    monitor_readline_buf = buf;
2919
    monitor_readline_buf_size = buf_size;
2920
    monitor_readline_started = 1;
2921
    while (monitor_readline_started) {
2922
        main_loop_wait(10);
2928
    if (bdrv_set_key(bs, password) != 0) {
2929
        term_printf("invalid password\n");
2930
        ret = -EPERM;
2923 2931
    }
2932
    if (password_completion_cb)
2933
        password_completion_cb(password_opaque, ret);
2934

  
2935
    monitor_start_input();
2924 2936
}
2925 2937

  
2926
int monitor_read_bdrv_key(BlockDriverState *bs)
2938
void monitor_read_bdrv_key_start(BlockDriverState *bs,
2939
                                 BlockDriverCompletionFunc *completion_cb,
2940
                                 void *opaque)
2927 2941
{
2928
    char password[256];
2929
    int i;
2930

  
2931
    if (!bdrv_is_encrypted(bs))
2932
        return 0;
2942
    if (!bdrv_key_required(bs)) {
2943
        if (completion_cb)
2944
            completion_cb(opaque, 0);
2945
        return;
2946
    }
2933 2947

  
2934 2948
    term_printf("%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
2935 2949
                bdrv_get_encrypted_filename(bs));
2936
    for(i = 0; i < 3; i++) {
2937
        monitor_readline("Password: ", 1, password, sizeof(password));
2938
        if (bdrv_set_key(bs, password) == 0)
2939
            return 0;
2940
        term_printf("invalid password\n");
2941
    }
2942
    return -EPERM;
2950

  
2951
    password_completion_cb = completion_cb;
2952
    password_opaque = opaque;
2953

  
2954
    monitor_read_password(bdrv_password_cb, bs);
2943 2955
}
b/vl.c
2661 2661
    return 0;
2662 2662
}
2663 2663

  
2664
static void usb_msd_password_cb(void *opaque, int err)
2665
{
2666
    USBDevice *dev = opaque;
2667

  
2668
    if (!err)
2669
        usb_device_add_dev(dev);
2670
    else
2671
        dev->handle_destroy(dev);
2672
}
2673

  
2664 2674
static int usb_device_add(const char *devname, int is_hotplug)
2665 2675
{
2666 2676
    const char *p;
......
2680 2690
    } else if (strstart(devname, "disk:", &p)) {
2681 2691
        BlockDriverState *bs;
2682 2692

  
2683
        dev = usb_msd_init(p, &bs);
2693
        dev = usb_msd_init(p);
2684 2694
        if (!dev)
2685 2695
            return -1;
2696
        bs = usb_msd_get_bdrv(dev);
2686 2697
        if (bdrv_key_required(bs)) {
2687 2698
            autostart = 0;
2688
            if (is_hotplug && monitor_read_bdrv_key(bs) < 0) {
2689
                dev->handle_destroy(dev);
2690
                return -1;
2699
            if (is_hotplug) {
2700
                monitor_read_bdrv_key_start(bs, usb_msd_password_cb, dev);
2701
                return 0;
2691 2702
            }
2692 2703
        }
2693 2704
    } else if (!strcmp(devname, "wacom-tablet")) {

Also available in: Unified diff