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 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 447 if (!line[0]) /* blank line */ 448 continue; 449 450 if (line[0] == '#') { 451 if (line[1] != ' ') 452 continue; 453 p = line + 2; 454 if (memcmp(p, CONFIG_, strlen(CONFIG_))) 455 continue; 456 sym_name = p + strlen(CONFIG_); 457 p = strchr(sym_name, ' '); 458 if (!p) 459 continue; 460 *p++ = 0; 461 if (strcmp(p, "is not set")) 462 continue; 463 464 val = "n"; 465 } else { 466 if (memcmp(line, CONFIG_, strlen(CONFIG_))) { 467 conf_warning("unexpected data: %s", line); 468 continue; 469 } 470 471 sym_name = line + strlen(CONFIG_); 472 p = strchr(sym_name, '='); 473 if (!p) { 474 conf_warning("unexpected data: %s", line); 475 continue; 476 } 477 *p = 0; 478 val = p + 1; 479 } 480 481 sym = sym_find(sym_name); 482 if (!sym) { 483 if (def == S_DEF_AUTO) { 484 /* 485 * Reading from include/config/auto.conf. 486 * If CONFIG_FOO previously existed in auto.conf 487 * but it is missing now, include/config/FOO 488 * must be touched. 489 */ 490 conf_touch_dep(sym_name); 491 } else { 492 if (warn_unknown) 493 conf_warning("unknown symbol: %s", sym_name); 494 495 conf_set_changed(true); 496 } 497 continue; 498 } 499 500 if (sym->flags & def_flags) 501 conf_warning("override: reassigning to symbol %s", sym->name); 502 503 if (conf_set_sym_val(sym, def, def_flags, val)) 504 continue; 505 506 if (sym && sym_is_choice_value(sym)) { 507 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 508 switch (sym->def[def].tri) { 509 case no: 510 break; 511 case mod: 512 if (cs->def[def].tri == yes) { 513 conf_warning("%s creates inconsistent choice state", sym->name); 514 cs->flags &= ~def_flags; 515 } 516 break; 517 case yes: 518 if (cs->def[def].tri != no) 519 conf_warning("override: %s changes choice state", sym->name); 520 cs->def[def].val = sym; 521 break; 522 } 523 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); 524 } 525 } 526 free(line); 527 fclose(in); 528 529 if (conf_warnings && werror) 530 exit(1); 531 532 return 0; 533 } 534 535 int conf_read(const char *name) 536 { 537 struct symbol *sym; 538 int conf_unsaved = 0; 539 int i; 540 541 conf_set_changed(false); 542 543 if (conf_read_simple(name, S_DEF_USER)) { 544 sym_calc_value(modules_sym); 545 return 1; 546 } 547 548 sym_calc_value(modules_sym); 549 550 for_all_symbols(i, sym) { 551 sym_calc_value(sym); 552 if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) 553 continue; 554 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 555 /* check that calculated value agrees with saved value */ 556 switch (sym->type) { 557 case S_BOOLEAN: 558 case S_TRISTATE: 559 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) 560 continue; 561 break; 562 default: 563 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 564 continue; 565 break; 566 } 567 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 568 /* no previous value and not saved */ 569 continue; 570 conf_unsaved++; 571 /* maybe print value in verbose mode... */ 572 } 573 574 for_all_symbols(i, sym) { 575 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 576 /* Reset values of generates values, so they'll appear 577 * as new, if they should become visible, but that 578 * doesn't quite work if the Kconfig and the saved 579 * configuration disagree. 580 */ 581 if (sym->visible == no && !conf_unsaved) 582 sym->flags &= ~SYMBOL_DEF_USER; 583 switch (sym->type) { 584 case S_STRING: 585 case S_INT: 586 case S_HEX: 587 /* Reset a string value if it's out of range */ 588 if (sym_string_within_range(sym, sym->def[S_DEF_USER].val)) 589 break; 590 sym->flags &= ~SYMBOL_VALID; 591 conf_unsaved++; 592 break; 593 default: 594 break; 595 } 596 } 597 } 598 599 if (conf_warnings || conf_unsaved) 600 conf_set_changed(true); 601 602 return 0; 603 } 604 605 struct comment_style { 606 const char *decoration; 607 const char *prefix; 608 const char *postfix; 609 }; 610 611 static const struct comment_style comment_style_pound = { 612 .decoration = "#", 613 .prefix = "#", 614 .postfix = "#", 615 }; 616 617 static const struct comment_style comment_style_c = { 618 .decoration = " *", 619 .prefix = "/*", 620 .postfix = " */", 621 }; 622 623 static void conf_write_heading(FILE *fp, const struct comment_style *cs) 624 { 625 if (!cs) 626 return; 627 628 fprintf(fp, "%s\n", cs->prefix); 629 630 fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", 631 cs->decoration); 632 633 fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text); 634 635 fprintf(fp, "%s\n", cs->postfix); 636 } 637 638 /* The returned pointer must be freed on the caller side */ 639 static char *escape_string_value(const char *in) 640 { 641 const char *p; 642 char *out; 643 size_t len; 644 645 len = strlen(in) + strlen("\"\"") + 1; 646 647 p = in; 648 while (1) { 649 p += strcspn(p, "\"\\"); 650 651 if (p[0] == '\0') 652 break; 653 654 len++; 655 p++; 656 } 657 658 out = xmalloc(len); 659 out[0] = '\0'; 660 661 strcat(out, "\""); 662 663 p = in; 664 while (1) { 665 len = strcspn(p, "\"\\"); 666 strncat(out, p, len); 667 p += len; 668 669 if (p[0] == '\0') 670 break; 671 672 strcat(out, "\\"); 673 strncat(out, p++, 1); 674 } 675 676 strcat(out, "\""); 677 678 return out; 679 } 680 681 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; 682 683 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, 684 bool escape_string) 685 { 686 const char *val; 687 char *escaped = NULL; 688 689 if (sym->type == S_UNKNOWN) 690 return; 691 692 val = sym_get_string_value(sym); 693 694 if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) && 695 output_n != OUTPUT_N && *val == 'n') { 696 if (output_n == OUTPUT_N_AS_UNSET) 697 fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name); 698 return; 699 } 700 701 if (sym->type == S_STRING && escape_string) { 702 escaped = escape_string_value(val); 703 val = escaped; 704 } 705 706 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val); 707 708 free(escaped); 709 } 710 711 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym) 712 { 713 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true); 714 } 715 716 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym) 717 { 718 __print_symbol(fp, sym, OUTPUT_N_NONE, false); 719 } 720 721 void print_symbol_for_listconfig(struct symbol *sym) 722 { 723 __print_symbol(stdout, sym, OUTPUT_N, true); 724 } 725 726 static void print_symbol_for_c(FILE *fp, struct symbol *sym) 727 { 728 const char *val; 729 const char *sym_suffix = ""; 730 const char *val_prefix = ""; 731 char *escaped = NULL; 732 733 if (sym->type == S_UNKNOWN) 734 return; 735 736 val = sym_get_string_value(sym); 737 738 switch (sym->type) { 739 case S_BOOLEAN: 740 case S_TRISTATE: 741 switch (*val) { 742 case 'n': 743 return; 744 case 'm': 745 sym_suffix = "_MODULE"; 746 /* fall through */ 747 default: 748 val = "1"; 749 } 750 break; 751 case S_HEX: 752 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 753 val_prefix = "0x"; 754 break; 755 case S_STRING: 756 escaped = escape_string_value(val); 757 val = escaped; 758 default: 759 break; 760 } 761 762 fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, 763 val_prefix, val); 764 765 free(escaped); 766 } 767 768 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) 769 { 770 const char *val; 771 const char *val_prefix = ""; 772 char *val_prefixed = NULL; 773 size_t val_prefixed_len; 774 char *escaped = NULL; 775 776 if (sym->type == S_UNKNOWN) 777 return; 778 779 val = sym_get_string_value(sym); 780 781 switch (sym->type) { 782 case S_BOOLEAN: 783 case S_TRISTATE: 784 /* 785 * We do not care about disabled ones, i.e. no need for 786 * what otherwise are "comments" in other printers. 787 */ 788 if (*val == 'n') 789 return; 790 791 /* 792 * To have similar functionality to the C macro `IS_ENABLED()` 793 * we provide an empty `--cfg CONFIG_X` here in both `y` 794 * and `m` cases. 795 * 796 * Then, the common `fprintf()` below will also give us 797 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can 798 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. 799 */ 800 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); 801 break; 802 case S_HEX: 803 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 804 val_prefix = "0x"; 805 break; 806 default: 807 break; 808 } 809 810 if (strlen(val_prefix) > 0) { 811 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; 812 val_prefixed = xmalloc(val_prefixed_len); 813 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); 814 val = val_prefixed; 815 } 816 817 /* All values get escaped: the `--cfg` option only takes strings */ 818 escaped = escape_string_value(val); 819 val = escaped; 820 821 fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); 822 823 free(escaped); 824 free(val_prefixed); 825 } 826 827 /* 828 * Write out a minimal config. 829 * All values that has default values are skipped as this is redundant. 830 */ 831 int conf_write_defconfig(const char *filename) 832 { 833 struct symbol *sym; 834 struct menu *menu; 835 FILE *out; 836 837 out = fopen(filename, "w"); 838 if (!out) 839 return 1; 840 841 sym_clear_all_valid(); 842 843 /* Traverse all menus to find all relevant symbols */ 844 menu = rootmenu.list; 845 846 while (menu != NULL) 847 { 848 sym = menu->sym; 849 if (sym == NULL) { 850 if (!menu_is_visible(menu)) 851 goto next_menu; 852 } else if (!sym_is_choice(sym)) { 853 sym_calc_value(sym); 854 if (!(sym->flags & SYMBOL_WRITE)) 855 goto next_menu; 856 sym->flags &= ~SYMBOL_WRITE; 857 /* If we cannot change the symbol - skip */ 858 if (!sym_is_changeable(sym)) 859 goto next_menu; 860 /* If symbol equals to default value - skip */ 861 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) 862 goto next_menu; 863 864 /* 865 * If symbol is a choice value and equals to the 866 * default for a choice - skip. 867 * But only if value is bool and equal to "y" and 868 * choice is not "optional". 869 * (If choice is "optional" then all values can be "n") 870 */ 871 if (sym_is_choice_value(sym)) { 872 struct symbol *cs; 873 struct symbol *ds; 874 875 cs = prop_get_symbol(sym_get_choice_prop(sym)); 876 ds = sym_choice_default(cs); 877 if (!sym_is_optional(cs) && sym == ds) { 878 if ((sym->type == S_BOOLEAN) && 879 sym_get_tristate_value(sym) == yes) 880 goto next_menu; 881 } 882 } 883 print_symbol_for_dotconfig(out, sym); 884 } 885 next_menu: 886 if (menu->list != NULL) { 887 menu = menu->list; 888 } 889 else if (menu->next != NULL) { 890 menu = menu->next; 891 } else { 892 while ((menu = menu->parent)) { 893 if (menu->next != NULL) { 894 menu = menu->next; 895 break; 896 } 897 } 898 } 899 } 900 fclose(out); 901 return 0; 902 } 903 904 int conf_write(const char *name) 905 { 906 FILE *out; 907 struct symbol *sym; 908 struct menu *menu; 909 const char *str; 910 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 911 char *env; 912 int i; 913 bool need_newline = false; 914 915 if (!name) 916 name = conf_get_configname(); 917 918 if (!*name) { 919 fprintf(stderr, "config name is empty\n"); 920 return -1; 921 } 922 923 if (is_dir(name)) { 924 fprintf(stderr, "%s: Is a directory\n", name); 925 return -1; 926 } 927 928 if (make_parent_dir(name)) 929 return -1; 930 931 env = getenv("KCONFIG_OVERWRITECONFIG"); 932 if (env && *env) { 933 *tmpname = 0; 934 out = fopen(name, "w"); 935 } else { 936 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 937 name, (int)getpid()); 938 out = fopen(tmpname, "w"); 939 } 940 if (!out) 941 return 1; 942 943 conf_write_heading(out, &comment_style_pound); 944 945 if (!conf_get_changed()) 946 sym_clear_all_valid(); 947 948 menu = rootmenu.list; 949 while (menu) { 950 sym = menu->sym; 951 if (!sym) { 952 if (!menu_is_visible(menu)) 953 goto next; 954 str = menu_get_prompt(menu); 955 fprintf(out, "\n" 956 "#\n" 957 "# %s\n" 958 "#\n", str); 959 need_newline = false; 960 } else if (!(sym->flags & SYMBOL_CHOICE) && 961 !(sym->flags & SYMBOL_WRITTEN)) { 962 sym_calc_value(sym); 963 if (!(sym->flags & SYMBOL_WRITE)) 964 goto next; 965 if (need_newline) { 966 fprintf(out, "\n"); 967 need_newline = false; 968 } 969 sym->flags |= SYMBOL_WRITTEN; 970 print_symbol_for_dotconfig(out, sym); 971 } 972 973 next: 974 if (menu->list) { 975 menu = menu->list; 976 continue; 977 } 978 979 end_check: 980 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && 981 menu->prompt->type == P_MENU) { 982 fprintf(out, "# end of %s\n", menu_get_prompt(menu)); 983 need_newline = true; 984 } 985 986 if (menu->next) { 987 menu = menu->next; 988 } else { 989 menu = menu->parent; 990 if (menu) 991 goto end_check; 992 } 993 } 994 fclose(out); 995 996 for_all_symbols(i, sym) 997 sym->flags &= ~SYMBOL_WRITTEN; 998 999 if (*tmpname) { 1000 if (is_same(name, tmpname)) { 1001 conf_message("No change to %s", name); 1002 unlink(tmpname); 1003 conf_set_changed(false); 1004 return 0; 1005 } 1006 1007 snprintf(oldname, sizeof(oldname), "%s.old", name); 1008 rename(name, oldname); 1009 if (rename(tmpname, name)) 1010 return 1; 1011 } 1012 1013 conf_message("configuration written to %s", name); 1014 1015 conf_set_changed(false); 1016 1017 return 0; 1018 } 1019 1020 /* write a dependency file as used by kbuild to track dependencies */ 1021 static int conf_write_autoconf_cmd(const char *autoconf_name) 1022 { 1023 char name[PATH_MAX], tmp[PATH_MAX]; 1024 struct file *file; 1025 FILE *out; 1026 int ret; 1027 1028 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); 1029 if (ret >= sizeof(name)) /* check truncation */ 1030 return -1; 1031 1032 if (make_parent_dir(name)) 1033 return -1; 1034 1035 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name); 1036 if (ret >= sizeof(tmp)) /* check truncation */ 1037 return -1; 1038 1039 out = fopen(tmp, "w"); 1040 if (!out) { 1041 perror("fopen"); 1042 return -1; 1043 } 1044 1045 fprintf(out, "deps_config := \\\n"); 1046 for (file = file_list; file; file = file->next) 1047 fprintf(out, "\t%s \\\n", file->name); 1048 1049 fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name); 1050 1051 env_write_dep(out, autoconf_name); 1052 1053 fprintf(out, "\n$(deps_config): ;\n"); 1054 1055 fflush(out); 1056 ret = ferror(out); /* error check for all fprintf() calls */ 1057 fclose(out); 1058 if (ret) 1059 return -1; 1060 1061 if (rename(tmp, name)) { 1062 perror("rename"); 1063 return -1; 1064 } 1065 1066 return 0; 1067 } 1068 1069 static int conf_touch_deps(void) 1070 { 1071 const char *name, *tmp; 1072 struct symbol *sym; 1073 int res, i; 1074 1075 name = conf_get_autoconfig_name(); 1076 tmp = strrchr(name, '/'); 1077 depfile_prefix_len = tmp ? tmp - name + 1 : 0; 1078 if (depfile_prefix_len + 1 > sizeof(depfile_path)) 1079 return -1; 1080 1081 strncpy(depfile_path, name, depfile_prefix_len); 1082 depfile_path[depfile_prefix_len] = 0; 1083 1084 conf_read_simple(name, S_DEF_AUTO); 1085 sym_calc_value(modules_sym); 1086 1087 for_all_symbols(i, sym) { 1088 sym_calc_value(sym); 1089 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) 1090 continue; 1091 if (sym->flags & SYMBOL_WRITE) { 1092 if (sym->flags & SYMBOL_DEF_AUTO) { 1093 /* 1094 * symbol has old and new value, 1095 * so compare them... 1096 */ 1097 switch (sym->type) { 1098 case S_BOOLEAN: 1099 case S_TRISTATE: 1100 if (sym_get_tristate_value(sym) == 1101 sym->def[S_DEF_AUTO].tri) 1102 continue; 1103 break; 1104 case S_STRING: 1105 case S_HEX: 1106 case S_INT: 1107 if (!strcmp(sym_get_string_value(sym), 1108 sym->def[S_DEF_AUTO].val)) 1109 continue; 1110 break; 1111 default: 1112 break; 1113 } 1114 } else { 1115 /* 1116 * If there is no old value, only 'no' (unset) 1117 * is allowed as new value. 1118 */ 1119 switch (sym->type) { 1120 case S_BOOLEAN: 1121 case S_TRISTATE: 1122 if (sym_get_tristate_value(sym) == no) 1123 continue; 1124 break; 1125 default: 1126 break; 1127 } 1128 } 1129 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 1130 /* There is neither an old nor a new value. */ 1131 continue; 1132 /* else 1133 * There is an old value, but no new value ('no' (unset) 1134 * isn't saved in auto.conf, so the old value is always 1135 * different from 'no'). 1136 */ 1137 1138 res = conf_touch_dep(sym->name); 1139 if (res) 1140 return res; 1141 } 1142 1143 return 0; 1144 } 1145 1146 static int __conf_write_autoconf(const char *filename, 1147 void (*print_symbol)(FILE *, struct symbol *), 1148 const struct comment_style *comment_style) 1149 { 1150 char tmp[PATH_MAX]; 1151 FILE *file; 1152 struct symbol *sym; 1153 int ret, i; 1154 1155 if (make_parent_dir(filename)) 1156 return -1; 1157 1158 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); 1159 if (ret >= sizeof(tmp)) /* check truncation */ 1160 return -1; 1161 1162 file = fopen(tmp, "w"); 1163 if (!file) { 1164 perror("fopen"); 1165 return -1; 1166 } 1167 1168 conf_write_heading(file, comment_style); 1169 1170 for_all_symbols(i, sym) 1171 if ((sym->flags & SYMBOL_WRITE) && sym->name) 1172 print_symbol(file, sym); 1173 1174 fflush(file); 1175 /* check possible errors in conf_write_heading() and print_symbol() */ 1176 ret = ferror(file); 1177 fclose(file); 1178 if (ret) 1179 return -1; 1180 1181 if (rename(tmp, filename)) { 1182 perror("rename"); 1183 return -1; 1184 } 1185 1186 return 0; 1187 } 1188 1189 int conf_write_autoconf(int overwrite) 1190 { 1191 struct symbol *sym; 1192 const char *autoconf_name = conf_get_autoconfig_name(); 1193 int ret, i; 1194 1195 if (!overwrite && is_present(autoconf_name)) 1196 return 0; 1197 1198 ret = conf_write_autoconf_cmd(autoconf_name); 1199 if (ret) 1200 return -1; 1201 1202 if (conf_touch_deps()) 1203 return 1; 1204 1205 for_all_symbols(i, sym) 1206 sym_calc_value(sym); 1207 1208 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1209 print_symbol_for_c, 1210 &comment_style_c); 1211 if (ret) 1212 return ret; 1213 1214 ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1215 print_symbol_for_rustccfg, 1216 NULL); 1217 if (ret) 1218 return ret; 1219 1220 /* 1221 * Create include/config/auto.conf. This must be the last step because 1222 * Kbuild has a dependency on auto.conf and this marks the successful 1223 * completion of the previous steps. 1224 */ 1225 ret = __conf_write_autoconf(conf_get_autoconfig_name(), 1226 print_symbol_for_autoconf, 1227 &comment_style_pound); 1228 if (ret) 1229 return ret; 1230 1231 return 0; 1232 } 1233 1234 static bool conf_changed; 1235 static void (*conf_changed_callback)(void); 1236 1237 void conf_set_changed(bool val) 1238 { 1239 bool changed = conf_changed != val; 1240 1241 conf_changed = val; 1242 1243 if (conf_changed_callback && changed) 1244 conf_changed_callback(); 1245 } 1246 1247 bool conf_get_changed(void) 1248 { 1249 return conf_changed; 1250 } 1251 1252 void conf_set_changed_callback(void (*fn)(void)) 1253 { 1254 conf_changed_callback = fn; 1255 } 1256 1257 void set_all_choice_values(struct symbol *csym) 1258 { 1259 struct property *prop; 1260 struct symbol *sym; 1261 struct expr *e; 1262 1263 prop = sym_get_choice_prop(csym); 1264 1265 /* 1266 * Set all non-assinged choice values to no 1267 */ 1268 expr_list_for_each_sym(prop->expr, e, sym) { 1269 if (!sym_has_value(sym)) 1270 sym->def[S_DEF_USER].tri = no; 1271 } 1272 csym->flags |= SYMBOL_DEF_USER; 1273 /* clear VALID to get value calculated */ 1274 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); 1275 } 1276