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