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