1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2002 Roman Zippel <[email protected]> 4 */ 5 6 #include <sys/mman.h> 7 #include <sys/stat.h> 8 #include <sys/types.h> 9 #include <ctype.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <limits.h> 13 #include <stdarg.h> 14 #include <stdbool.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <time.h> 19 #include <unistd.h> 20 21 #include "lkc.h" 22 23 /* return true if 'path' exists, false otherwise */ 24 static bool is_present(const char *path) 25 { 26 struct stat st; 27 28 return !stat(path, &st); 29 } 30 31 /* return true if 'path' exists and it is a directory, false otherwise */ 32 static bool is_dir(const char *path) 33 { 34 struct stat st; 35 36 if (stat(path, &st)) 37 return false; 38 39 return S_ISDIR(st.st_mode); 40 } 41 42 /* return true if the given two files are the same, false otherwise */ 43 static bool is_same(const char *file1, const char *file2) 44 { 45 int fd1, fd2; 46 struct stat st1, st2; 47 void *map1, *map2; 48 bool ret = false; 49 50 fd1 = open(file1, O_RDONLY); 51 if (fd1 < 0) 52 return ret; 53 54 fd2 = open(file2, O_RDONLY); 55 if (fd2 < 0) 56 goto close1; 57 58 ret = fstat(fd1, &st1); 59 if (ret) 60 goto close2; 61 ret = fstat(fd2, &st2); 62 if (ret) 63 goto close2; 64 65 if (st1.st_size != st2.st_size) 66 goto close2; 67 68 map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); 69 if (map1 == MAP_FAILED) 70 goto close2; 71 72 map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); 73 if (map2 == MAP_FAILED) 74 goto close2; 75 76 if (bcmp(map1, map2, st1.st_size)) 77 goto close2; 78 79 ret = true; 80 close2: 81 close(fd2); 82 close1: 83 close(fd1); 84 85 return ret; 86 } 87 88 /* 89 * Create the parent directory of the given path. 90 * 91 * For example, if 'include/config/auto.conf' is given, create 'include/config'. 92 */ 93 static int make_parent_dir(const char *path) 94 { 95 char tmp[PATH_MAX + 1]; 96 char *p; 97 98 strncpy(tmp, path, sizeof(tmp)); 99 tmp[sizeof(tmp) - 1] = 0; 100 101 /* Remove the base name. Just return if nothing is left */ 102 p = strrchr(tmp, '/'); 103 if (!p) 104 return 0; 105 *(p + 1) = 0; 106 107 /* Just in case it is an absolute path */ 108 p = tmp; 109 while (*p == '/') 110 p++; 111 112 while ((p = strchr(p, '/'))) { 113 *p = 0; 114 115 /* skip if the directory exists */ 116 if (!is_dir(tmp) && mkdir(tmp, 0755)) 117 return -1; 118 119 *p = '/'; 120 while (*p == '/') 121 p++; 122 } 123 124 return 0; 125 } 126 127 static char depfile_path[PATH_MAX]; 128 static size_t depfile_prefix_len; 129 130 /* touch depfile for symbol 'name' */ 131 static int conf_touch_dep(const char *name) 132 { 133 int fd; 134 135 /* check overflow: prefix + name + '\0' must fit in buffer. */ 136 if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) 137 return -1; 138 139 strcpy(depfile_path + depfile_prefix_len, name); 140 141 fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 142 if (fd == -1) 143 return -1; 144 close(fd); 145 146 return 0; 147 } 148 149 static void conf_warning(const char *fmt, ...) 150 __attribute__ ((format (printf, 1, 2))); 151 152 static void conf_message(const char *fmt, ...) 153 __attribute__ ((format (printf, 1, 2))); 154 155 static const char *conf_filename; 156 static int conf_lineno, conf_warnings; 157 158 static void conf_warning(const char *fmt, ...) 159 { 160 va_list ap; 161 va_start(ap, fmt); 162 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); 163 vfprintf(stderr, fmt, ap); 164 fprintf(stderr, "\n"); 165 va_end(ap); 166 conf_warnings++; 167 } 168 169 static void conf_default_message_callback(const char *s) 170 { 171 printf("#\n# "); 172 printf("%s", s); 173 printf("\n#\n"); 174 } 175 176 static void (*conf_message_callback)(const char *s) = 177 conf_default_message_callback; 178 void conf_set_message_callback(void (*fn)(const char *s)) 179 { 180 conf_message_callback = fn; 181 } 182 183 static void conf_message(const char *fmt, ...) 184 { 185 va_list ap; 186 char buf[4096]; 187 188 if (!conf_message_callback) 189 return; 190 191 va_start(ap, fmt); 192 193 vsnprintf(buf, sizeof(buf), fmt, ap); 194 conf_message_callback(buf); 195 va_end(ap); 196 } 197 198 const char *conf_get_configname(void) 199 { 200 char *name = getenv("KCONFIG_CONFIG"); 201 202 return name ? name : ".config"; 203 } 204 205 static const char *conf_get_autoconfig_name(void) 206 { 207 char *name = getenv("KCONFIG_AUTOCONFIG"); 208 209 return name ? name : "include/config/auto.conf"; 210 } 211 212 static const char *conf_get_autoheader_name(void) 213 { 214 char *name = getenv("KCONFIG_AUTOHEADER"); 215 216 return name ? name : "include/generated/autoconf.h"; 217 } 218 219 static const char *conf_get_rustccfg_name(void) 220 { 221 char *name = getenv("KCONFIG_RUSTCCFG"); 222 223 return name ? name : "include/generated/rustc_cfg"; 224 } 225 226 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 227 { 228 char *p2; 229 230 switch (sym->type) { 231 case S_TRISTATE: 232 if (p[0] == 'm') { 233 sym->def[def].tri = mod; 234 sym->flags |= def_flags; 235 break; 236 } 237 /* fall through */ 238 case S_BOOLEAN: 239 if (p[0] == 'y') { 240 sym->def[def].tri = yes; 241 sym->flags |= def_flags; 242 break; 243 } 244 if (p[0] == 'n') { 245 sym->def[def].tri = no; 246 sym->flags |= def_flags; 247 break; 248 } 249 if (def != S_DEF_AUTO) 250 conf_warning("symbol value '%s' invalid for %s", 251 p, sym->name); 252 return 1; 253 case S_STRING: 254 /* No escaping for S_DEF_AUTO (include/config/auto.conf) */ 255 if (def != S_DEF_AUTO) { 256 if (*p++ != '"') 257 break; 258 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 259 if (*p2 == '"') { 260 *p2 = 0; 261 break; 262 } 263 memmove(p2, p2 + 1, strlen(p2)); 264 } 265 if (!p2) { 266 conf_warning("invalid string found"); 267 return 1; 268 } 269 } 270 /* fall through */ 271 case S_INT: 272 case S_HEX: 273 if (sym_string_valid(sym, p)) { 274 sym->def[def].val = xstrdup(p); 275 sym->flags |= def_flags; 276 } else { 277 if (def != S_DEF_AUTO) 278 conf_warning("symbol value '%s' invalid for %s", 279 p, sym->name); 280 return 1; 281 } 282 break; 283 default: 284 ; 285 } 286 return 0; 287 } 288 289 #define LINE_GROWTH 16 290 static int add_byte(int c, char **lineptr, size_t slen, size_t *n) 291 { 292 size_t new_size = slen + 1; 293 294 if (new_size > *n) { 295 new_size += LINE_GROWTH - 1; 296 new_size *= 2; 297 *lineptr = xrealloc(*lineptr, new_size); 298 *n = new_size; 299 } 300 301 (*lineptr)[slen] = c; 302 303 return 0; 304 } 305 306 static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream) 307 { 308 char *line = *lineptr; 309 size_t slen = 0; 310 311 for (;;) { 312 int c = getc(stream); 313 314 switch (c) { 315 case '\n': 316 if (add_byte(c, &line, slen, n) < 0) 317 goto e_out; 318 slen++; 319 /* fall through */ 320 case EOF: 321 if (add_byte('\0', &line, slen, n) < 0) 322 goto e_out; 323 *lineptr = line; 324 if (slen == 0) 325 return -1; 326 return slen; 327 default: 328 if (add_byte(c, &line, slen, n) < 0) 329 goto e_out; 330 slen++; 331 } 332 } 333 334 e_out: 335 line[slen-1] = '\0'; 336 *lineptr = line; 337 return -1; 338 } 339 340 /* like getline(), but the newline character is stripped away */ 341 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream) 342 { 343 ssize_t len; 344 345 len = compat_getline(lineptr, n, stream); 346 347 if (len > 0 && (*lineptr)[len - 1] == '\n') { 348 len--; 349 (*lineptr)[len] = '\0'; 350 351 if (len > 0 && (*lineptr)[len - 1] == '\r') { 352 len--; 353 (*lineptr)[len] = '\0'; 354 } 355 } 356 357 return len; 358 } 359 360 int conf_read_simple(const char *name, int def) 361 { 362 FILE *in = NULL; 363 char *line = NULL; 364 size_t line_asize = 0; 365 char *p, *val; 366 struct symbol *sym; 367 int i, def_flags; 368 const char *warn_unknown, *werror, *sym_name; 369 370 warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); 371 werror = getenv("KCONFIG_WERROR"); 372 if (name) { 373 in = zconf_fopen(name); 374 } else { 375 char *env; 376 377 name = conf_get_configname(); 378 in = zconf_fopen(name); 379 if (in) 380 goto load; 381 conf_set_changed(true); 382 383 env = getenv("KCONFIG_DEFCONFIG_LIST"); 384 if (!env) 385 return 1; 386 387 while (1) { 388 bool is_last; 389 390 while (isspace(*env)) 391 env++; 392 393 if (!*env) 394 break; 395 396 p = env; 397 while (*p && !isspace(*p)) 398 p++; 399 400 is_last = (*p == '\0'); 401 402 *p = '\0'; 403 404 in = zconf_fopen(env); 405 if (in) { 406 conf_message("using defaults found in %s", 407 env); 408 goto load; 409 } 410 411 if (is_last) 412 break; 413 414 env = p + 1; 415 } 416 } 417 if (!in) 418 return 1; 419 420 load: 421 conf_filename = name; 422 conf_lineno = 0; 423 conf_warnings = 0; 424 425 def_flags = SYMBOL_DEF << def; 426 for_all_symbols(i, sym) { 427 sym->flags |= SYMBOL_CHANGED; 428 sym->flags &= ~(def_flags|SYMBOL_VALID); 429 if (sym_is_choice(sym)) 430 sym->flags |= def_flags; 431 switch (sym->type) { 432 case S_INT: 433 case S_HEX: 434 case S_STRING: 435 if (sym->def[def].val) 436 free(sym->def[def].val); 437 /* fall through */ 438 default: 439 sym->def[def].val = NULL; 440 sym->def[def].tri = no; 441 } 442 } 443 444 while (getline_stripped(&line, &line_asize, in) != -1) { 445 conf_lineno++; 446 if (line[0] == '#') { 447 if (line[1] != ' ') 448 continue; 449 p = line + 2; 450 if (memcmp(p, CONFIG_, strlen(CONFIG_))) 451 continue; 452 sym_name = p + strlen(CONFIG_); 453 p = strchr(sym_name, ' '); 454 if (!p) 455 continue; 456 *p++ = 0; 457 if (strcmp(p, "is not set")) 458 continue; 459 460 val = "n"; 461 } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) { 462 sym_name = line + strlen(CONFIG_); 463 p = strchr(sym_name, '='); 464 if (!p) 465 continue; 466 *p = 0; 467 val = p + 1; 468 } else { 469 if (line[0] != '\0') 470 conf_warning("unexpected data: %s", line); 471 continue; 472 } 473 474 sym = sym_find(sym_name); 475 if (!sym) { 476 if (def == S_DEF_AUTO) { 477 /* 478 * Reading from include/config/auto.conf. 479 * If CONFIG_FOO previously existed in auto.conf 480 * but it is missing now, include/config/FOO 481 * must be touched. 482 */ 483 conf_touch_dep(sym_name); 484 } else { 485 if (warn_unknown) 486 conf_warning("unknown symbol: %s", sym_name); 487 488 conf_set_changed(true); 489 } 490 continue; 491 } 492 493 if (sym->flags & def_flags) 494 conf_warning("override: reassigning to symbol %s", sym->name); 495 496 if (conf_set_sym_val(sym, def, def_flags, val)) 497 continue; 498 499 if (sym && sym_is_choice_value(sym)) { 500 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 501 switch (sym->def[def].tri) { 502 case no: 503 break; 504 case mod: 505 if (cs->def[def].tri == yes) { 506 conf_warning("%s creates inconsistent choice state", sym->name); 507 cs->flags &= ~def_flags; 508 } 509 break; 510 case yes: 511 if (cs->def[def].tri != no) 512 conf_warning("override: %s changes choice state", sym->name); 513 cs->def[def].val = sym; 514 break; 515 } 516 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); 517 } 518 } 519 free(line); 520 fclose(in); 521 522 if (conf_warnings && werror) 523 exit(1); 524 525 return 0; 526 } 527 528 int conf_read(const char *name) 529 { 530 struct symbol *sym; 531 int conf_unsaved = 0; 532 int i; 533 534 conf_set_changed(false); 535 536 if (conf_read_simple(name, S_DEF_USER)) { 537 sym_calc_value(modules_sym); 538 return 1; 539 } 540 541 sym_calc_value(modules_sym); 542 543 for_all_symbols(i, sym) { 544 sym_calc_value(sym); 545 if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) 546 continue; 547 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 548 /* check that calculated value agrees with saved value */ 549 switch (sym->type) { 550 case S_BOOLEAN: 551 case S_TRISTATE: 552 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) 553 continue; 554 break; 555 default: 556 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 557 continue; 558 break; 559 } 560 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 561 /* no previous value and not saved */ 562 continue; 563 conf_unsaved++; 564 /* maybe print value in verbose mode... */ 565 } 566 567 for_all_symbols(i, sym) { 568 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 569 /* Reset values of generates values, so they'll appear 570 * as new, if they should become visible, but that 571 * doesn't quite work if the Kconfig and the saved 572 * configuration disagree. 573 */ 574 if (sym->visible == no && !conf_unsaved) 575 sym->flags &= ~SYMBOL_DEF_USER; 576 switch (sym->type) { 577 case S_STRING: 578 case S_INT: 579 case S_HEX: 580 /* Reset a string value if it's out of range */ 581 if (sym_string_within_range(sym, sym->def[S_DEF_USER].val)) 582 break; 583 sym->flags &= ~SYMBOL_VALID; 584 conf_unsaved++; 585 break; 586 default: 587 break; 588 } 589 } 590 } 591 592 if (conf_warnings || conf_unsaved) 593 conf_set_changed(true); 594 595 return 0; 596 } 597 598 struct comment_style { 599 const char *decoration; 600 const char *prefix; 601 const char *postfix; 602 }; 603 604 static const struct comment_style comment_style_pound = { 605 .decoration = "#", 606 .prefix = "#", 607 .postfix = "#", 608 }; 609 610 static const struct comment_style comment_style_c = { 611 .decoration = " *", 612 .prefix = "/*", 613 .postfix = " */", 614 }; 615 616 static void conf_write_heading(FILE *fp, const struct comment_style *cs) 617 { 618 if (!cs) 619 return; 620 621 fprintf(fp, "%s\n", cs->prefix); 622 623 fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", 624 cs->decoration); 625 626 fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text); 627 628 fprintf(fp, "%s\n", cs->postfix); 629 } 630 631 /* The returned pointer must be freed on the caller side */ 632 static char *escape_string_value(const char *in) 633 { 634 const char *p; 635 char *out; 636 size_t len; 637 638 len = strlen(in) + strlen("\"\"") + 1; 639 640 p = in; 641 while (1) { 642 p += strcspn(p, "\"\\"); 643 644 if (p[0] == '\0') 645 break; 646 647 len++; 648 p++; 649 } 650 651 out = xmalloc(len); 652 out[0] = '\0'; 653 654 strcat(out, "\""); 655 656 p = in; 657 while (1) { 658 len = strcspn(p, "\"\\"); 659 strncat(out, p, len); 660 p += len; 661 662 if (p[0] == '\0') 663 break; 664 665 strcat(out, "\\"); 666 strncat(out, p++, 1); 667 } 668 669 strcat(out, "\""); 670 671 return out; 672 } 673 674 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; 675 676 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, 677 bool escape_string) 678 { 679 const char *val; 680 char *escaped = NULL; 681 682 if (sym->type == S_UNKNOWN) 683 return; 684 685 val = sym_get_string_value(sym); 686 687 if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) && 688 output_n != OUTPUT_N && *val == 'n') { 689 if (output_n == OUTPUT_N_AS_UNSET) 690 fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name); 691 return; 692 } 693 694 if (sym->type == S_STRING && escape_string) { 695 escaped = escape_string_value(val); 696 val = escaped; 697 } 698 699 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val); 700 701 free(escaped); 702 } 703 704 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym) 705 { 706 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true); 707 } 708 709 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym) 710 { 711 __print_symbol(fp, sym, OUTPUT_N_NONE, false); 712 } 713 714 void print_symbol_for_listconfig(struct symbol *sym) 715 { 716 __print_symbol(stdout, sym, OUTPUT_N, true); 717 } 718 719 static void print_symbol_for_c(FILE *fp, struct symbol *sym) 720 { 721 const char *val; 722 const char *sym_suffix = ""; 723 const char *val_prefix = ""; 724 char *escaped = NULL; 725 726 if (sym->type == S_UNKNOWN) 727 return; 728 729 val = sym_get_string_value(sym); 730 731 switch (sym->type) { 732 case S_BOOLEAN: 733 case S_TRISTATE: 734 switch (*val) { 735 case 'n': 736 return; 737 case 'm': 738 sym_suffix = "_MODULE"; 739 /* fall through */ 740 default: 741 val = "1"; 742 } 743 break; 744 case S_HEX: 745 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 746 val_prefix = "0x"; 747 break; 748 case S_STRING: 749 escaped = escape_string_value(val); 750 val = escaped; 751 default: 752 break; 753 } 754 755 fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, 756 val_prefix, val); 757 758 free(escaped); 759 } 760 761 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) 762 { 763 const char *val; 764 const char *val_prefix = ""; 765 char *val_prefixed = NULL; 766 size_t val_prefixed_len; 767 char *escaped = NULL; 768 769 if (sym->type == S_UNKNOWN) 770 return; 771 772 val = sym_get_string_value(sym); 773 774 switch (sym->type) { 775 case S_BOOLEAN: 776 case S_TRISTATE: 777 /* 778 * We do not care about disabled ones, i.e. no need for 779 * what otherwise are "comments" in other printers. 780 */ 781 if (*val == 'n') 782 return; 783 784 /* 785 * To have similar functionality to the C macro `IS_ENABLED()` 786 * we provide an empty `--cfg CONFIG_X` here in both `y` 787 * and `m` cases. 788 * 789 * Then, the common `fprintf()` below will also give us 790 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can 791 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. 792 */ 793 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); 794 break; 795 case S_HEX: 796 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 797 val_prefix = "0x"; 798 break; 799 default: 800 break; 801 } 802 803 if (strlen(val_prefix) > 0) { 804 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; 805 val_prefixed = xmalloc(val_prefixed_len); 806 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); 807 val = val_prefixed; 808 } 809 810 /* All values get escaped: the `--cfg` option only takes strings */ 811 escaped = escape_string_value(val); 812 val = escaped; 813 814 fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); 815 816 free(escaped); 817 free(val_prefixed); 818 } 819 820 /* 821 * Write out a minimal config. 822 * All values that has default values are skipped as this is redundant. 823 */ 824 int conf_write_defconfig(const char *filename) 825 { 826 struct symbol *sym; 827 struct menu *menu; 828 FILE *out; 829 830 out = fopen(filename, "w"); 831 if (!out) 832 return 1; 833 834 sym_clear_all_valid(); 835 836 /* Traverse all menus to find all relevant symbols */ 837 menu = rootmenu.list; 838 839 while (menu != NULL) 840 { 841 sym = menu->sym; 842 if (sym == NULL) { 843 if (!menu_is_visible(menu)) 844 goto next_menu; 845 } else if (!sym_is_choice(sym)) { 846 sym_calc_value(sym); 847 if (!(sym->flags & SYMBOL_WRITE)) 848 goto next_menu; 849 sym->flags &= ~SYMBOL_WRITE; 850 /* If we cannot change the symbol - skip */ 851 if (!sym_is_changeable(sym)) 852 goto next_menu; 853 /* If symbol equals to default value - skip */ 854 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) 855 goto next_menu; 856 857 /* 858 * If symbol is a choice value and equals to the 859 * default for a choice - skip. 860 * But only if value is bool and equal to "y" and 861 * choice is not "optional". 862 * (If choice is "optional" then all values can be "n") 863 */ 864 if (sym_is_choice_value(sym)) { 865 struct symbol *cs; 866 struct symbol *ds; 867 868 cs = prop_get_symbol(sym_get_choice_prop(sym)); 869 ds = sym_choice_default(cs); 870 if (!sym_is_optional(cs) && sym == ds) { 871 if ((sym->type == S_BOOLEAN) && 872 sym_get_tristate_value(sym) == yes) 873 goto next_menu; 874 } 875 } 876 print_symbol_for_dotconfig(out, sym); 877 } 878 next_menu: 879 if (menu->list != NULL) { 880 menu = menu->list; 881 } 882 else if (menu->next != NULL) { 883 menu = menu->next; 884 } else { 885 while ((menu = menu->parent)) { 886 if (menu->next != NULL) { 887 menu = menu->next; 888 break; 889 } 890 } 891 } 892 } 893 fclose(out); 894 return 0; 895 } 896 897 int conf_write(const char *name) 898 { 899 FILE *out; 900 struct symbol *sym; 901 struct menu *menu; 902 const char *str; 903 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 904 char *env; 905 int i; 906 bool need_newline = false; 907 908 if (!name) 909 name = conf_get_configname(); 910 911 if (!*name) { 912 fprintf(stderr, "config name is empty\n"); 913 return -1; 914 } 915 916 if (is_dir(name)) { 917 fprintf(stderr, "%s: Is a directory\n", name); 918 return -1; 919 } 920 921 if (make_parent_dir(name)) 922 return -1; 923 924 env = getenv("KCONFIG_OVERWRITECONFIG"); 925 if (env && *env) { 926 *tmpname = 0; 927 out = fopen(name, "w"); 928 } else { 929 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 930 name, (int)getpid()); 931 out = fopen(tmpname, "w"); 932 } 933 if (!out) 934 return 1; 935 936 conf_write_heading(out, &comment_style_pound); 937 938 if (!conf_get_changed()) 939 sym_clear_all_valid(); 940 941 menu = rootmenu.list; 942 while (menu) { 943 sym = menu->sym; 944 if (!sym) { 945 if (!menu_is_visible(menu)) 946 goto next; 947 str = menu_get_prompt(menu); 948 fprintf(out, "\n" 949 "#\n" 950 "# %s\n" 951 "#\n", str); 952 need_newline = false; 953 } else if (!(sym->flags & SYMBOL_CHOICE) && 954 !(sym->flags & SYMBOL_WRITTEN)) { 955 sym_calc_value(sym); 956 if (!(sym->flags & SYMBOL_WRITE)) 957 goto next; 958 if (need_newline) { 959 fprintf(out, "\n"); 960 need_newline = false; 961 } 962 sym->flags |= SYMBOL_WRITTEN; 963 print_symbol_for_dotconfig(out, sym); 964 } 965 966 next: 967 if (menu->list) { 968 menu = menu->list; 969 continue; 970 } 971 972 end_check: 973 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && 974 menu->prompt->type == P_MENU) { 975 fprintf(out, "# end of %s\n", menu_get_prompt(menu)); 976 need_newline = true; 977 } 978 979 if (menu->next) { 980 menu = menu->next; 981 } else { 982 menu = menu->parent; 983 if (menu) 984 goto end_check; 985 } 986 } 987 fclose(out); 988 989 for_all_symbols(i, sym) 990 sym->flags &= ~SYMBOL_WRITTEN; 991 992 if (*tmpname) { 993 if (is_same(name, tmpname)) { 994 conf_message("No change to %s", name); 995 unlink(tmpname); 996 conf_set_changed(false); 997 return 0; 998 } 999 1000 snprintf(oldname, sizeof(oldname), "%s.old", name); 1001 rename(name, oldname); 1002 if (rename(tmpname, name)) 1003 return 1; 1004 } 1005 1006 conf_message("configuration written to %s", name); 1007 1008 conf_set_changed(false); 1009 1010 return 0; 1011 } 1012 1013 /* write a dependency file as used by kbuild to track dependencies */ 1014 static int conf_write_autoconf_cmd(const char *autoconf_name) 1015 { 1016 char name[PATH_MAX], tmp[PATH_MAX]; 1017 struct file *file; 1018 FILE *out; 1019 int ret; 1020 1021 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); 1022 if (ret >= sizeof(name)) /* check truncation */ 1023 return -1; 1024 1025 if (make_parent_dir(name)) 1026 return -1; 1027 1028 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name); 1029 if (ret >= sizeof(tmp)) /* check truncation */ 1030 return -1; 1031 1032 out = fopen(tmp, "w"); 1033 if (!out) { 1034 perror("fopen"); 1035 return -1; 1036 } 1037 1038 fprintf(out, "deps_config := \\\n"); 1039 for (file = file_list; file; file = file->next) 1040 fprintf(out, "\t%s \\\n", file->name); 1041 1042 fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name); 1043 1044 env_write_dep(out, autoconf_name); 1045 1046 fprintf(out, "\n$(deps_config): ;\n"); 1047 1048 fflush(out); 1049 ret = ferror(out); /* error check for all fprintf() calls */ 1050 fclose(out); 1051 if (ret) 1052 return -1; 1053 1054 if (rename(tmp, name)) { 1055 perror("rename"); 1056 return -1; 1057 } 1058 1059 return 0; 1060 } 1061 1062 static int conf_touch_deps(void) 1063 { 1064 const char *name, *tmp; 1065 struct symbol *sym; 1066 int res, i; 1067 1068 name = conf_get_autoconfig_name(); 1069 tmp = strrchr(name, '/'); 1070 depfile_prefix_len = tmp ? tmp - name + 1 : 0; 1071 if (depfile_prefix_len + 1 > sizeof(depfile_path)) 1072 return -1; 1073 1074 strncpy(depfile_path, name, depfile_prefix_len); 1075 depfile_path[depfile_prefix_len] = 0; 1076 1077 conf_read_simple(name, S_DEF_AUTO); 1078 sym_calc_value(modules_sym); 1079 1080 for_all_symbols(i, sym) { 1081 sym_calc_value(sym); 1082 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) 1083 continue; 1084 if (sym->flags & SYMBOL_WRITE) { 1085 if (sym->flags & SYMBOL_DEF_AUTO) { 1086 /* 1087 * symbol has old and new value, 1088 * so compare them... 1089 */ 1090 switch (sym->type) { 1091 case S_BOOLEAN: 1092 case S_TRISTATE: 1093 if (sym_get_tristate_value(sym) == 1094 sym->def[S_DEF_AUTO].tri) 1095 continue; 1096 break; 1097 case S_STRING: 1098 case S_HEX: 1099 case S_INT: 1100 if (!strcmp(sym_get_string_value(sym), 1101 sym->def[S_DEF_AUTO].val)) 1102 continue; 1103 break; 1104 default: 1105 break; 1106 } 1107 } else { 1108 /* 1109 * If there is no old value, only 'no' (unset) 1110 * is allowed as new value. 1111 */ 1112 switch (sym->type) { 1113 case S_BOOLEAN: 1114 case S_TRISTATE: 1115 if (sym_get_tristate_value(sym) == no) 1116 continue; 1117 break; 1118 default: 1119 break; 1120 } 1121 } 1122 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 1123 /* There is neither an old nor a new value. */ 1124 continue; 1125 /* else 1126 * There is an old value, but no new value ('no' (unset) 1127 * isn't saved in auto.conf, so the old value is always 1128 * different from 'no'). 1129 */ 1130 1131 res = conf_touch_dep(sym->name); 1132 if (res) 1133 return res; 1134 } 1135 1136 return 0; 1137 } 1138 1139 static int __conf_write_autoconf(const char *filename, 1140 void (*print_symbol)(FILE *, struct symbol *), 1141 const struct comment_style *comment_style) 1142 { 1143 char tmp[PATH_MAX]; 1144 FILE *file; 1145 struct symbol *sym; 1146 int ret, i; 1147 1148 if (make_parent_dir(filename)) 1149 return -1; 1150 1151 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); 1152 if (ret >= sizeof(tmp)) /* check truncation */ 1153 return -1; 1154 1155 file = fopen(tmp, "w"); 1156 if (!file) { 1157 perror("fopen"); 1158 return -1; 1159 } 1160 1161 conf_write_heading(file, comment_style); 1162 1163 for_all_symbols(i, sym) 1164 if ((sym->flags & SYMBOL_WRITE) && sym->name) 1165 print_symbol(file, sym); 1166 1167 fflush(file); 1168 /* check possible errors in conf_write_heading() and print_symbol() */ 1169 ret = ferror(file); 1170 fclose(file); 1171 if (ret) 1172 return -1; 1173 1174 if (rename(tmp, filename)) { 1175 perror("rename"); 1176 return -1; 1177 } 1178 1179 return 0; 1180 } 1181 1182 int conf_write_autoconf(int overwrite) 1183 { 1184 struct symbol *sym; 1185 const char *autoconf_name = conf_get_autoconfig_name(); 1186 int ret, i; 1187 1188 if (!overwrite && is_present(autoconf_name)) 1189 return 0; 1190 1191 ret = conf_write_autoconf_cmd(autoconf_name); 1192 if (ret) 1193 return -1; 1194 1195 if (conf_touch_deps()) 1196 return 1; 1197 1198 for_all_symbols(i, sym) 1199 sym_calc_value(sym); 1200 1201 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1202 print_symbol_for_c, 1203 &comment_style_c); 1204 if (ret) 1205 return ret; 1206 1207 ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1208 print_symbol_for_rustccfg, 1209 NULL); 1210 if (ret) 1211 return ret; 1212 1213 /* 1214 * Create include/config/auto.conf. This must be the last step because 1215 * Kbuild has a dependency on auto.conf and this marks the successful 1216 * completion of the previous steps. 1217 */ 1218 ret = __conf_write_autoconf(conf_get_autoconfig_name(), 1219 print_symbol_for_autoconf, 1220 &comment_style_pound); 1221 if (ret) 1222 return ret; 1223 1224 return 0; 1225 } 1226 1227 static bool conf_changed; 1228 static void (*conf_changed_callback)(void); 1229 1230 void conf_set_changed(bool val) 1231 { 1232 bool changed = conf_changed != val; 1233 1234 conf_changed = val; 1235 1236 if (conf_changed_callback && changed) 1237 conf_changed_callback(); 1238 } 1239 1240 bool conf_get_changed(void) 1241 { 1242 return conf_changed; 1243 } 1244 1245 void conf_set_changed_callback(void (*fn)(void)) 1246 { 1247 conf_changed_callback = fn; 1248 } 1249 1250 void set_all_choice_values(struct symbol *csym) 1251 { 1252 struct property *prop; 1253 struct symbol *sym; 1254 struct expr *e; 1255 1256 prop = sym_get_choice_prop(csym); 1257 1258 /* 1259 * Set all non-assinged choice values to no 1260 */ 1261 expr_list_for_each_sym(prop->expr, e, sym) { 1262 if (!sym_has_value(sym)) 1263 sym->def[S_DEF_USER].tri = no; 1264 } 1265 csym->flags |= SYMBOL_DEF_USER; 1266 /* clear VALID to get value calculated */ 1267 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); 1268 } 1269