1 /* 2 * Commandline option parsing functions 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * Copyright (c) 2009 Kevin Wolf <kwolf (at) redhat.com> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 26 #include <stdio.h> 27 #include <string.h> 28 29 #include "qemu-common.h" 30 #include "qemu-option.h" 31 32 /* 33 * Extracts the name of an option from the parameter string (p points at the 34 * first byte of the option name) 35 * 36 * The option name is delimited by delim (usually , or =) or the string end 37 * and is copied into buf. If the option name is longer than buf_size, it is 38 * truncated. buf is always zero terminated. 39 * 40 * The return value is the position of the delimiter/zero byte after the option 41 * name in p. 42 */ 43 const char *get_opt_name(char *buf, int buf_size, const char *p, char delim) 44 { 45 char *q; 46 47 q = buf; 48 while (*p != '\0' && *p != delim) { 49 if (q && (q - buf) < buf_size - 1) 50 *q++ = *p; 51 p++; 52 } 53 if (q) 54 *q = '\0'; 55 56 return p; 57 } 58 59 /* 60 * Extracts the value of an option from the parameter string p (p points at the 61 * first byte of the option value) 62 * 63 * This function is comparable to get_opt_name with the difference that the 64 * delimiter is fixed to be comma which starts a new option. To specify an 65 * option value that contains commas, double each comma. 66 */ 67 const char *get_opt_value(char *buf, int buf_size, const char *p) 68 { 69 char *q; 70 71 q = buf; 72 while (*p != '\0') { 73 if (*p == ',') { 74 if (*(p + 1) != ',') 75 break; 76 p++; 77 } 78 if (q && (q - buf) < buf_size - 1) 79 *q++ = *p; 80 p++; 81 } 82 if (q) 83 *q = '\0'; 84 85 return p; 86 } 87 88 int get_next_param_value(char *buf, int buf_size, 89 const char *tag, const char **pstr) 90 { 91 const char *p; 92 char option[128]; 93 94 p = *pstr; 95 for(;;) { 96 p = get_opt_name(option, sizeof(option), p, '='); 97 if (*p != '=') 98 break; 99 p++; 100 if (!strcmp(tag, option)) { 101 *pstr = get_opt_value(buf, buf_size, p); 102 if (**pstr == ',') { 103 (*pstr)++; 104 } 105 return strlen(buf); 106 } else { 107 p = get_opt_value(NULL, 0, p); 108 } 109 if (*p != ',') 110 break; 111 p++; 112 } 113 return 0; 114 } 115 116 int get_param_value(char *buf, int buf_size, 117 const char *tag, const char *str) 118 { 119 return get_next_param_value(buf, buf_size, tag, &str); 120 } 121 122 int check_params(char *buf, int buf_size, 123 const char * const *params, const char *str) 124 { 125 const char *p; 126 int i; 127 128 p = str; 129 while (*p != '\0') { 130 p = get_opt_name(buf, buf_size, p, '='); 131 if (*p != '=') { 132 return -1; 133 } 134 p++; 135 for (i = 0; params[i] != NULL; i++) { 136 if (!strcmp(params[i], buf)) { 137 break; 138 } 139 } 140 if (params[i] == NULL) { 141 return -1; 142 } 143 p = get_opt_value(NULL, 0, p); 144 if (*p != ',') { 145 break; 146 } 147 p++; 148 } 149 return 0; 150 } 151 152 /* 153 * Searches an option list for an option with the given name 154 */ 155 QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, 156 const char *name) 157 { 158 while (list && list->name) { 159 if (!strcmp(list->name, name)) { 160 return list; 161 } 162 list++; 163 } 164 165 return NULL; 166 } 167 168 static int parse_option_bool(const char *name, const char *value, int *ret) 169 { 170 if (value != NULL) { 171 if (!strcmp(value, "on")) { 172 *ret = 1; 173 } else if (!strcmp(value, "off")) { 174 *ret = 0; 175 } else { 176 fprintf(stderr, "Option '%s': Use 'on' or 'off'\n", name); 177 return -1; 178 } 179 } else { 180 *ret = 1; 181 } 182 return 0; 183 } 184 185 static int parse_option_number(const char *name, const char *value, uint64_t *ret) 186 { 187 char *postfix; 188 uint64_t number; 189 190 if (value != NULL) { 191 number = strtoull(value, &postfix, 0); 192 if (*postfix != '\0') { 193 fprintf(stderr, "Option '%s' needs a number as parameter\n", name); 194 return -1; 195 } 196 *ret = number; 197 } else { 198 fprintf(stderr, "Option '%s' needs a parameter\n", name); 199 return -1; 200 } 201 return 0; 202 } 203 204 static int parse_option_size(const char *name, const char *value, uint64_t *ret) 205 { 206 char *postfix; 207 double sizef; 208 209 if (value != NULL) { 210 sizef = strtod(value, &postfix); 211 switch (*postfix) { 212 case 'T': 213 sizef *= 1024; 214 case 'G': 215 sizef *= 1024; 216 case 'M': 217 sizef *= 1024; 218 case 'K': 219 case 'k': 220 sizef *= 1024; 221 case 'b': 222 case '\0': 223 *ret = (uint64_t) sizef; 224 break; 225 default: 226 fprintf(stderr, "Option '%s' needs size as parameter\n", name); 227 fprintf(stderr, "You may use k, M, G or T suffixes for " 228 "kilobytes, megabytes, gigabytes and terabytes.\n"); 229 return -1; 230 } 231 } else { 232 fprintf(stderr, "Option '%s' needs a parameter\n", name); 233 return -1; 234 } 235 return 0; 236 } 237 238 /* 239 * Sets the value of a parameter in a given option list. The parsing of the 240 * value depends on the type of option: 241 * 242 * OPT_FLAG (uses value.n): 243 * If no value is given, the flag is set to 1. 244 * Otherwise the value must be "on" (set to 1) or "off" (set to 0) 245 * 246 * OPT_STRING (uses value.s): 247 * value is strdup()ed and assigned as option value 248 * 249 * OPT_SIZE (uses value.n): 250 * The value is converted to an integer. Suffixes for kilobytes etc. are 251 * allowed (powers of 1024). 252 * 253 * Returns 0 on succes, -1 in error cases 254 */ 255 int set_option_parameter(QEMUOptionParameter *list, const char *name, 256 const char *value) 257 { 258 int flag; 259 260 // Find a matching parameter 261 list = get_option_parameter(list, name); 262 if (list == NULL) { 263 fprintf(stderr, "Unknown option '%s'\n", name); 264 return -1; 265 } 266 267 // Process parameter 268 switch (list->type) { 269 case OPT_FLAG: 270 if (parse_option_bool(name, value, &flag) == -1) 271 return -1; 272 list->value.n = flag; 273 break; 274 275 case OPT_STRING: 276 if (value != NULL) { 277 list->value.s = qemu_strdup(value); 278 } else { 279 fprintf(stderr, "Option '%s' needs a parameter\n", name); 280 return -1; 281 } 282 break; 283 284 case OPT_SIZE: 285 if (parse_option_size(name, value, &list->value.n) == -1) 286 return -1; 287 break; 288 289 default: 290 fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name); 291 return -1; 292 } 293 294 return 0; 295 } 296 297 /* 298 * Sets the given parameter to an integer instead of a string. 299 * This function cannot be used to set string options. 300 * 301 * Returns 0 on success, -1 in error cases 302 */ 303 int set_option_parameter_int(QEMUOptionParameter *list, const char *name, 304 uint64_t value) 305 { 306 // Find a matching parameter 307 list = get_option_parameter(list, name); 308 if (list == NULL) { 309 fprintf(stderr, "Unknown option '%s'\n", name); 310 return -1; 311 } 312 313 // Process parameter 314 switch (list->type) { 315 case OPT_FLAG: 316 case OPT_NUMBER: 317 case OPT_SIZE: 318 list->value.n = value; 319 break; 320 321 default: 322 return -1; 323 } 324 325 return 0; 326 } 327 328 /* 329 * Frees a option list. If it contains strings, the strings are freed as well. 330 */ 331 void free_option_parameters(QEMUOptionParameter *list) 332 { 333 QEMUOptionParameter *cur = list; 334 335 while (cur && cur->name) { 336 if (cur->type == OPT_STRING) { 337 qemu_free(cur->value.s); 338 } 339 cur++; 340 } 341 342 qemu_free(list); 343 } 344 345 /* 346 * Parses a parameter string (param) into an option list (dest). 347 * 348 * list is the templace is. If dest is NULL, a new copy of list is created for 349 * it. If list is NULL, this function fails. 350 * 351 * A parameter string consists of one or more parameters, separated by commas. 352 * Each parameter consists of its name and possibly of a value. In the latter 353 * case, the value is delimited by an = character. To specify a value which 354 * contains commas, double each comma so it won't be recognized as the end of 355 * the parameter. 356 * 357 * For more details of the parsing see above. 358 * 359 * Returns a pointer to the first element of dest (or the newly allocated copy) 360 * or NULL in error cases 361 */ 362 QEMUOptionParameter *parse_option_parameters(const char *param, 363 QEMUOptionParameter *list, QEMUOptionParameter *dest) 364 { 365 QEMUOptionParameter *cur; 366 QEMUOptionParameter *allocated = NULL; 367 char name[256]; 368 char value[256]; 369 char *param_delim, *value_delim; 370 char next_delim; 371 size_t num_options; 372 373 if (list == NULL) { 374 return NULL; 375 } 376 377 if (dest == NULL) { 378 // Count valid options 379 num_options = 0; 380 cur = list; 381 while (cur->name) { 382 num_options++; 383 cur++; 384 } 385 386 // Create a copy of the option list to fill in values 387 dest = qemu_mallocz((num_options + 1) * sizeof(QEMUOptionParameter)); 388 allocated = dest; 389 memcpy(dest, list, (num_options + 1) * sizeof(QEMUOptionParameter)); 390 } 391 392 while (*param) { 393 394 // Find parameter name and value in the string 395 param_delim = strchr(param, ','); 396 value_delim = strchr(param, '='); 397 398 if (value_delim && (value_delim < param_delim || !param_delim)) { 399 next_delim = '='; 400 } else { 401 next_delim = ','; 402 value_delim = NULL; 403 } 404 405 param = get_opt_name(name, sizeof(name), param, next_delim); 406 if (value_delim) { 407 param = get_opt_value(value, sizeof(value), param + 1); 408 } 409 if (*param != '\0') { 410 param++; 411 } 412 413 // Set the parameter 414 if (set_option_parameter(dest, name, value_delim ? value : NULL)) { 415 goto fail; 416 } 417 } 418 419 return dest; 420 421 fail: 422 // Only free the list if it was newly allocated 423 free_option_parameters(allocated); 424 return NULL; 425 } 426 427 /* 428 * Prints all options of a list that have a value to stdout 429 */ 430 void print_option_parameters(QEMUOptionParameter *list) 431 { 432 while (list && list->name) { 433 switch (list->type) { 434 case OPT_STRING: 435 if (list->value.s != NULL) { 436 printf("%s='%s' ", list->name, list->value.s); 437 } 438 break; 439 case OPT_FLAG: 440 printf("%s=%s ", list->name, list->value.n ? "on" : "off"); 441 break; 442 case OPT_SIZE: 443 case OPT_NUMBER: 444 printf("%s=%" PRId64 " ", list->name, list->value.n); 445 break; 446 default: 447 printf("%s=(unkown type) ", list->name); 448 break; 449 } 450 list++; 451 } 452 } 453 454 /* 455 * Prints an overview of all available options 456 */ 457 void print_option_help(QEMUOptionParameter *list) 458 { 459 printf("Supported options:\n"); 460 while (list && list->name) { 461 printf("%-16s %s\n", list->name, 462 list->help ? list->help : "No description available"); 463 list++; 464 } 465 } 466 467 /* ------------------------------------------------------------------ */ 468 469 struct QemuOpt { 470 const char *name; 471 const char *str; 472 473 const QemuOptDesc *desc; 474 union { 475 int boolean; 476 uint64_t uint; 477 } value; 478 479 QemuOpts *opts; 480 QTAILQ_ENTRY(QemuOpt) next; 481 }; 482 483 struct QemuOpts { 484 char *id; 485 QemuOptsList *list; 486 QTAILQ_HEAD(QemuOptHead, QemuOpt) head; 487 QTAILQ_ENTRY(QemuOpts) next; 488 }; 489 490 static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) 491 { 492 QemuOpt *opt; 493 494 QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) { 495 if (strcmp(opt->name, name) != 0) 496 continue; 497 return opt; 498 } 499 return NULL; 500 } 501 502 const char *qemu_opt_get(QemuOpts *opts, const char *name) 503 { 504 QemuOpt *opt = qemu_opt_find(opts, name); 505 return opt ? opt->str : NULL; 506 } 507 508 int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval) 509 { 510 QemuOpt *opt = qemu_opt_find(opts, name); 511 512 if (opt == NULL) 513 return defval; 514 assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL); 515 return opt->value.boolean; 516 } 517 518 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval) 519 { 520 QemuOpt *opt = qemu_opt_find(opts, name); 521 522 if (opt == NULL) 523 return defval; 524 assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER); 525 return opt->value.uint; 526 } 527 528 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval) 529 { 530 QemuOpt *opt = qemu_opt_find(opts, name); 531 532 if (opt == NULL) 533 return defval; 534 assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE); 535 return opt->value.uint; 536 } 537 538 static int qemu_opt_parse(QemuOpt *opt) 539 { 540 if (opt->desc == NULL) 541 return 0; 542 switch (opt->desc->type) { 543 case QEMU_OPT_STRING: 544 /* nothing */ 545 return 0; 546 case QEMU_OPT_BOOL: 547 return parse_option_bool(opt->name, opt->str, &opt->value.boolean); 548 case QEMU_OPT_NUMBER: 549 return parse_option_number(opt->name, opt->str, &opt->value.uint); 550 case QEMU_OPT_SIZE: 551 return parse_option_size(opt->name, opt->str, &opt->value.uint); 552 default: 553 abort(); 554 } 555 } 556 557 static void qemu_opt_del(QemuOpt *opt) 558 { 559 QTAILQ_REMOVE(&opt->opts->head, opt, next); 560 qemu_free((/* !const */ char*)opt->name); 561 qemu_free((/* !const */ char*)opt->str); 562 qemu_free(opt); 563 } 564 565 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value) 566 { 567 QemuOpt *opt; 568 const QemuOptDesc *desc = opts->list->desc; 569 int i; 570 571 for (i = 0; desc[i].name != NULL; i++) { 572 if (strcmp(desc[i].name, name) == 0) { 573 break; 574 } 575 } 576 if (desc[i].name == NULL) { 577 if (i == 0) { 578 /* empty list -> allow any */; 579 } else { 580 fprintf(stderr, "option \"%s\" is not valid for %s\n", 581 name, opts->list->name); 582 return -1; 583 } 584 } 585 586 opt = qemu_mallocz(sizeof(*opt)); 587 opt->name = qemu_strdup(name); 588 opt->opts = opts; 589 QTAILQ_INSERT_TAIL(&opts->head, opt, next); 590 if (desc[i].name != NULL) { 591 opt->desc = desc+i; 592 } 593 if (value) { 594 opt->str = qemu_strdup(value); 595 } 596 if (qemu_opt_parse(opt) < 0) { 597 fprintf(stderr, "Failed to parse \"%s\" for \"%s.%s\"\n", opt->str, 598 opts->list->name, opt->name); 599 qemu_opt_del(opt); 600 return -1; 601 } 602 return 0; 603 } 604 605 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, 606 int abort_on_failure) 607 { 608 QemuOpt *opt; 609 int rc = 0; 610 611 QTAILQ_FOREACH(opt, &opts->head, next) { 612 rc = func(opt->name, opt->str, opaque); 613 if (abort_on_failure && rc != 0) 614 break; 615 } 616 return rc; 617 } 618 619 QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id) 620 { 621 QemuOpts *opts; 622 623 QTAILQ_FOREACH(opts, &list->head, next) { 624 if (!opts->id) { 625 continue; 626 } 627 if (strcmp(opts->id, id) != 0) { 628 continue; 629 } 630 return opts; 631 } 632 return NULL; 633 } 634 635 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists) 636 { 637 QemuOpts *opts = NULL; 638 639 if (id) { 640 opts = qemu_opts_find(list, id); 641 if (opts != NULL) { 642 if (fail_if_exists) { 643 fprintf(stderr, "tried to create id \"%s\" twice for \"%s\"\n", 644 id, list->name); 645 return NULL; 646 } else { 647 return opts; 648 } 649 } 650 } 651 opts = qemu_mallocz(sizeof(*opts)); 652 if (id) { 653 opts->id = qemu_strdup(id); 654 } 655 opts->list = list; 656 QTAILQ_INIT(&opts->head); 657 QTAILQ_INSERT_TAIL(&list->head, opts, next); 658 return opts; 659 } 660 661 int qemu_opts_set(QemuOptsList *list, const char *id, 662 const char *name, const char *value) 663 { 664 QemuOpts *opts; 665 666 opts = qemu_opts_create(list, id, 1); 667 if (opts == NULL) { 668 return -1; 669 } 670 return qemu_opt_set(opts, name, value); 671 } 672 673 const char *qemu_opts_id(QemuOpts *opts) 674 { 675 return opts->id; 676 } 677 678 void qemu_opts_del(QemuOpts *opts) 679 { 680 QemuOpt *opt; 681 682 for (;;) { 683 opt = QTAILQ_FIRST(&opts->head); 684 if (opt == NULL) 685 break; 686 qemu_opt_del(opt); 687 } 688 QTAILQ_REMOVE(&opts->list->head, opts, next); 689 qemu_free(opts->id); 690 qemu_free(opts); 691 } 692 693 int qemu_opts_print(QemuOpts *opts, void *dummy) 694 { 695 QemuOpt *opt; 696 697 fprintf(stderr, "%s: %s:", opts->list->name, 698 opts->id ? opts->id : "<noid>"); 699 QTAILQ_FOREACH(opt, &opts->head, next) { 700 fprintf(stderr, " %s=\"%s\"", opt->name, opt->str); 701 } 702 fprintf(stderr, "\n"); 703 return 0; 704 } 705 706 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname) 707 { 708 char option[128], value[1024]; 709 const char *p,*pe,*pc; 710 711 for (p = params; *p != '\0'; p++) { 712 pe = strchr(p, '='); 713 pc = strchr(p, ','); 714 if (!pe || (pc && pc < pe)) { 715 /* found "foo,more" */ 716 if (p == params && firstname) { 717 /* implicitly named first option */ 718 pstrcpy(option, sizeof(option), firstname); 719 p = get_opt_value(value, sizeof(value), p); 720 } else { 721 /* option without value, probably a flag */ 722 p = get_opt_name(option, sizeof(option), p, ','); 723 if (strncmp(option, "no", 2) == 0) { 724 memmove(option, option+2, strlen(option+2)+1); 725 pstrcpy(value, sizeof(value), "off"); 726 } else { 727 pstrcpy(value, sizeof(value), "on"); 728 } 729 } 730 } else { 731 /* found "foo=bar,more" */ 732 p = get_opt_name(option, sizeof(option), p, '='); 733 if (*p != '=') { 734 break; 735 } 736 p++; 737 p = get_opt_value(value, sizeof(value), p); 738 } 739 if (strcmp(option, "id") != 0) { 740 /* store and parse */ 741 if (qemu_opt_set(opts, option, value) == -1) { 742 return -1; 743 } 744 } 745 if (*p != ',') { 746 break; 747 } 748 } 749 return 0; 750 } 751 752 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname) 753 { 754 char value[1024], *id = NULL; 755 const char *p; 756 QemuOpts *opts; 757 758 if (strncmp(params, "id=", 3) == 0) { 759 get_opt_value(value, sizeof(value), params+3); 760 id = qemu_strdup(value); 761 } else if ((p = strstr(params, ",id=")) != NULL) { 762 get_opt_value(value, sizeof(value), p+4); 763 id = qemu_strdup(value); 764 } 765 opts = qemu_opts_create(list, id, 1); 766 if (opts == NULL) 767 return NULL; 768 769 if (qemu_opts_do_parse(opts, params, firstname) != 0) { 770 qemu_opts_del(opts); 771 return NULL; 772 } 773 774 return opts; 775 } 776 777 /* Validate parsed opts against descriptions where no 778 * descriptions were provided in the QemuOptsList. 779 */ 780 int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc) 781 { 782 QemuOpt *opt; 783 784 assert(opts->list->desc[0].name == NULL); 785 786 QTAILQ_FOREACH(opt, &opts->head, next) { 787 int i; 788 789 for (i = 0; desc[i].name != NULL; i++) { 790 if (strcmp(desc[i].name, opt->name) == 0) { 791 break; 792 } 793 } 794 if (desc[i].name == NULL) { 795 fprintf(stderr, "option \"%s\" is not valid for %s\n", 796 opt->name, opts->list->name); 797 return -1; 798 } 799 800 opt->desc = &desc[i]; 801 802 if (qemu_opt_parse(opt) < 0) { 803 return -1; 804 } 805 } 806 807 return 0; 808 } 809 810 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, 811 int abort_on_failure) 812 { 813 QemuOpts *opts; 814 int rc = 0; 815 816 QTAILQ_FOREACH(opts, &list->head, next) { 817 rc |= func(opts, opaque); 818 if (abort_on_failure && rc != 0) 819 break; 820 } 821 return rc; 822 } 823