1 /* 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 3 * Released under the terms of the GNU GPL v2.0. 4 */ 5 6 #include <sys/stat.h> 7 #include <ctype.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <time.h> 12 #include <unistd.h> 13 14 #define LKC_DIRECT_LINK 15 #include "lkc.h" 16 17 static void conf_warning(const char *fmt, ...) 18 __attribute__ ((format (printf, 1, 2))); 19 20 static const char *conf_filename; 21 static int conf_lineno, conf_warnings, conf_unsaved; 22 23 const char conf_def_filename[] = ".config"; 24 25 const char conf_defname[] = "arch/$ARCH/defconfig"; 26 27 const char *conf_confnames[] = { 28 ".config", 29 "/lib/modules/$UNAME_RELEASE/.config", 30 "/etc/kernel-config", 31 "/boot/config-$UNAME_RELEASE", 32 conf_defname, 33 NULL, 34 }; 35 36 static void conf_warning(const char *fmt, ...) 37 { 38 va_list ap; 39 va_start(ap, fmt); 40 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); 41 vfprintf(stderr, fmt, ap); 42 fprintf(stderr, "\n"); 43 va_end(ap); 44 conf_warnings++; 45 } 46 47 static char *conf_expand_value(const char *in) 48 { 49 struct symbol *sym; 50 const char *src; 51 static char res_value[SYMBOL_MAXLENGTH]; 52 char *dst, name[SYMBOL_MAXLENGTH]; 53 54 res_value[0] = 0; 55 dst = name; 56 while ((src = strchr(in, '$'))) { 57 strncat(res_value, in, src - in); 58 src++; 59 dst = name; 60 while (isalnum(*src) || *src == '_') 61 *dst++ = *src++; 62 *dst = 0; 63 sym = sym_lookup(name, 0); 64 sym_calc_value(sym); 65 strcat(res_value, sym_get_string_value(sym)); 66 in = src; 67 } 68 strcat(res_value, in); 69 70 return res_value; 71 } 72 73 char *conf_get_default_confname(void) 74 { 75 struct stat buf; 76 static char fullname[PATH_MAX+1]; 77 char *env, *name; 78 79 name = conf_expand_value(conf_defname); 80 env = getenv(SRCTREE); 81 if (env) { 82 sprintf(fullname, "%s/%s", env, name); 83 if (!stat(fullname, &buf)) 84 return fullname; 85 } 86 return name; 87 } 88 89 int conf_read_simple(const char *name) 90 { 91 FILE *in = NULL; 92 char line[1024]; 93 char *p, *p2; 94 struct symbol *sym; 95 int i; 96 97 if (name) { 98 in = zconf_fopen(name); 99 } else { 100 const char **names = conf_confnames; 101 name = *names++; 102 if (!name) 103 return 1; 104 in = zconf_fopen(name); 105 if (in) 106 goto load; 107 sym_change_count++; 108 while ((name = *names++)) { 109 name = conf_expand_value(name); 110 in = zconf_fopen(name); 111 if (in) { 112 printf(_("#\n" 113 "# using defaults found in %s\n" 114 "#\n"), name); 115 goto load; 116 } 117 } 118 } 119 if (!in) 120 return 1; 121 122 load: 123 conf_filename = name; 124 conf_lineno = 0; 125 conf_warnings = 0; 126 conf_unsaved = 0; 127 128 for_all_symbols(i, sym) { 129 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; 130 if (sym_is_choice(sym)) 131 sym->flags &= ~SYMBOL_NEW; 132 sym->flags &= ~SYMBOL_VALID; 133 switch (sym->type) { 134 case S_INT: 135 case S_HEX: 136 case S_STRING: 137 if (sym->user.val) 138 free(sym->user.val); 139 default: 140 sym->user.val = NULL; 141 sym->user.tri = no; 142 } 143 } 144 145 while (fgets(line, sizeof(line), in)) { 146 conf_lineno++; 147 sym = NULL; 148 switch (line[0]) { 149 case '#': 150 if (memcmp(line + 2, "CONFIG_", 7)) 151 continue; 152 p = strchr(line + 9, ' '); 153 if (!p) 154 continue; 155 *p++ = 0; 156 if (strncmp(p, "is not set", 10)) 157 continue; 158 sym = sym_find(line + 9); 159 if (!sym) { 160 conf_warning("trying to assign nonexistent symbol %s", line + 9); 161 break; 162 } else if (!(sym->flags & SYMBOL_NEW)) { 163 conf_warning("trying to reassign symbol %s", sym->name); 164 break; 165 } 166 switch (sym->type) { 167 case S_BOOLEAN: 168 case S_TRISTATE: 169 sym->user.tri = no; 170 sym->flags &= ~SYMBOL_NEW; 171 break; 172 default: 173 ; 174 } 175 break; 176 case 'C': 177 if (memcmp(line, "CONFIG_", 7)) { 178 conf_warning("unexpected data"); 179 continue; 180 } 181 p = strchr(line + 7, '='); 182 if (!p) 183 continue; 184 *p++ = 0; 185 p2 = strchr(p, '\n'); 186 if (p2) 187 *p2 = 0; 188 sym = sym_find(line + 7); 189 if (!sym) { 190 conf_warning("trying to assign nonexistent symbol %s", line + 7); 191 break; 192 } else if (!(sym->flags & SYMBOL_NEW)) { 193 conf_warning("trying to reassign symbol %s", sym->name); 194 break; 195 } 196 switch (sym->type) { 197 case S_TRISTATE: 198 if (p[0] == 'm') { 199 sym->user.tri = mod; 200 sym->flags &= ~SYMBOL_NEW; 201 break; 202 } 203 case S_BOOLEAN: 204 if (p[0] == 'y') { 205 sym->user.tri = yes; 206 sym->flags &= ~SYMBOL_NEW; 207 break; 208 } 209 if (p[0] == 'n') { 210 sym->user.tri = no; 211 sym->flags &= ~SYMBOL_NEW; 212 break; 213 } 214 conf_warning("symbol value '%s' invalid for %s", p, sym->name); 215 break; 216 case S_STRING: 217 if (*p++ != '"') 218 break; 219 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 220 if (*p2 == '"') { 221 *p2 = 0; 222 break; 223 } 224 memmove(p2, p2 + 1, strlen(p2)); 225 } 226 if (!p2) { 227 conf_warning("invalid string found"); 228 continue; 229 } 230 case S_INT: 231 case S_HEX: 232 if (sym_string_valid(sym, p)) { 233 sym->user.val = strdup(p); 234 sym->flags &= ~SYMBOL_NEW; 235 } else { 236 conf_warning("symbol value '%s' invalid for %s", p, sym->name); 237 continue; 238 } 239 break; 240 default: 241 ; 242 } 243 break; 244 case '\n': 245 break; 246 default: 247 conf_warning("unexpected data"); 248 continue; 249 } 250 if (sym && sym_is_choice_value(sym)) { 251 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 252 switch (sym->user.tri) { 253 case no: 254 break; 255 case mod: 256 if (cs->user.tri == yes) { 257 conf_warning("%s creates inconsistent choice state", sym->name); 258 cs->flags |= SYMBOL_NEW; 259 } 260 break; 261 case yes: 262 if (cs->user.tri != no) { 263 conf_warning("%s creates inconsistent choice state", sym->name); 264 cs->flags |= SYMBOL_NEW; 265 } else 266 cs->user.val = sym; 267 break; 268 } 269 cs->user.tri = E_OR(cs->user.tri, sym->user.tri); 270 } 271 } 272 fclose(in); 273 274 if (modules_sym) 275 sym_calc_value(modules_sym); 276 return 0; 277 } 278 279 int conf_read(const char *name) 280 { 281 struct symbol *sym; 282 struct property *prop; 283 struct expr *e; 284 int i; 285 286 sym_change_count = 0; 287 288 if (conf_read_simple(name)) 289 return 1; 290 291 for_all_symbols(i, sym) { 292 sym_calc_value(sym); 293 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) 294 goto sym_ok; 295 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 296 /* check that calculated value agrees with saved value */ 297 switch (sym->type) { 298 case S_BOOLEAN: 299 case S_TRISTATE: 300 if (sym->user.tri != sym_get_tristate_value(sym)) 301 break; 302 if (!sym_is_choice(sym)) 303 goto sym_ok; 304 default: 305 if (!strcmp(sym->curr.val, sym->user.val)) 306 goto sym_ok; 307 break; 308 } 309 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 310 /* no previous value and not saved */ 311 goto sym_ok; 312 conf_unsaved++; 313 /* maybe print value in verbose mode... */ 314 sym_ok: 315 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 316 if (sym->visible == no) 317 sym->flags |= SYMBOL_NEW; 318 switch (sym->type) { 319 case S_STRING: 320 case S_INT: 321 case S_HEX: 322 if (!sym_string_within_range(sym, sym->user.val)) { 323 sym->flags |= SYMBOL_NEW; 324 sym->flags &= ~SYMBOL_VALID; 325 } 326 default: 327 break; 328 } 329 } 330 if (!sym_is_choice(sym)) 331 continue; 332 prop = sym_get_choice_prop(sym); 333 for (e = prop->expr; e; e = e->left.expr) 334 if (e->right.sym->visible != no) 335 sym->flags |= e->right.sym->flags & SYMBOL_NEW; 336 } 337 338 sym_change_count += conf_warnings || conf_unsaved; 339 340 return 0; 341 } 342 343 int conf_write(const char *name) 344 { 345 FILE *out; 346 struct symbol *sym; 347 struct menu *menu; 348 const char *basename; 349 char dirname[128], tmpname[128], newname[128]; 350 int type, l; 351 const char *str; 352 time_t now; 353 int use_timestamp = 1; 354 char *env; 355 356 dirname[0] = 0; 357 if (name && name[0]) { 358 struct stat st; 359 char *slash; 360 361 if (!stat(name, &st) && S_ISDIR(st.st_mode)) { 362 strcpy(dirname, name); 363 strcat(dirname, "/"); 364 basename = conf_def_filename; 365 } else if ((slash = strrchr(name, '/'))) { 366 int size = slash - name + 1; 367 memcpy(dirname, name, size); 368 dirname[size] = 0; 369 if (slash[1]) 370 basename = slash + 1; 371 else 372 basename = conf_def_filename; 373 } else 374 basename = name; 375 } else 376 basename = conf_def_filename; 377 378 sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); 379 out = fopen(newname, "w"); 380 if (!out) 381 return 1; 382 sym = sym_lookup("KERNELVERSION", 0); 383 sym_calc_value(sym); 384 time(&now); 385 env = getenv("KCONFIG_NOTIMESTAMP"); 386 if (env && *env) 387 use_timestamp = 0; 388 389 fprintf(out, _("#\n" 390 "# Automatically generated make config: don't edit\n" 391 "# Linux kernel version: %s\n" 392 "%s%s" 393 "#\n"), 394 sym_get_string_value(sym), 395 use_timestamp ? "# " : "", 396 use_timestamp ? ctime(&now) : ""); 397 398 if (!sym_change_count) 399 sym_clear_all_valid(); 400 401 menu = rootmenu.list; 402 while (menu) { 403 sym = menu->sym; 404 if (!sym) { 405 if (!menu_is_visible(menu)) 406 goto next; 407 str = menu_get_prompt(menu); 408 fprintf(out, "\n" 409 "#\n" 410 "# %s\n" 411 "#\n", str); 412 } else if (!(sym->flags & SYMBOL_CHOICE)) { 413 sym_calc_value(sym); 414 if (!(sym->flags & SYMBOL_WRITE)) 415 goto next; 416 sym->flags &= ~SYMBOL_WRITE; 417 type = sym->type; 418 if (type == S_TRISTATE) { 419 sym_calc_value(modules_sym); 420 if (modules_sym->curr.tri == no) 421 type = S_BOOLEAN; 422 } 423 switch (type) { 424 case S_BOOLEAN: 425 case S_TRISTATE: 426 switch (sym_get_tristate_value(sym)) { 427 case no: 428 fprintf(out, "# CONFIG_%s is not set\n", sym->name); 429 break; 430 case mod: 431 fprintf(out, "CONFIG_%s=m\n", sym->name); 432 break; 433 case yes: 434 fprintf(out, "CONFIG_%s=y\n", sym->name); 435 break; 436 } 437 break; 438 case S_STRING: 439 str = sym_get_string_value(sym); 440 fprintf(out, "CONFIG_%s=\"", sym->name); 441 while (1) { 442 l = strcspn(str, "\"\\"); 443 if (l) { 444 fwrite(str, l, 1, out); 445 str += l; 446 } 447 if (!*str) 448 break; 449 fprintf(out, "\\%c", *str++); 450 } 451 fputs("\"\n", out); 452 break; 453 case S_HEX: 454 str = sym_get_string_value(sym); 455 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 456 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 457 break; 458 } 459 case S_INT: 460 str = sym_get_string_value(sym); 461 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 462 break; 463 } 464 } 465 466 next: 467 if (menu->list) { 468 menu = menu->list; 469 continue; 470 } 471 if (menu->next) 472 menu = menu->next; 473 else while ((menu = menu->parent)) { 474 if (menu->next) { 475 menu = menu->next; 476 break; 477 } 478 } 479 } 480 fclose(out); 481 if (!name || basename != conf_def_filename) { 482 if (!name) 483 name = conf_def_filename; 484 sprintf(tmpname, "%s.old", name); 485 rename(name, tmpname); 486 } 487 sprintf(tmpname, "%s%s", dirname, basename); 488 if (rename(newname, tmpname)) 489 return 1; 490 491 printf(_("#\n" 492 "# configuration written to %s\n" 493 "#\n"), tmpname); 494 495 sym_change_count = 0; 496 497 return 0; 498 } 499 500 int conf_write_autoconf(void) 501 { 502 struct symbol *sym; 503 const char *str; 504 char *name; 505 FILE *out, *out_h; 506 time_t now; 507 int i, l; 508 509 file_write_dep("include/config/auto.conf.cmd"); 510 511 out = fopen(".tmpconfig", "w"); 512 if (!out) 513 return 1; 514 515 out_h = fopen(".tmpconfig.h", "w"); 516 if (!out_h) { 517 fclose(out); 518 return 1; 519 } 520 521 sym = sym_lookup("KERNELVERSION", 0); 522 sym_calc_value(sym); 523 time(&now); 524 fprintf(out, "#\n" 525 "# Automatically generated make config: don't edit\n" 526 "# Linux kernel version: %s\n" 527 "# %s" 528 "#\n", 529 sym_get_string_value(sym), ctime(&now)); 530 fprintf(out_h, "/*\n" 531 " * Automatically generated C config: don't edit\n" 532 " * Linux kernel version: %s\n" 533 " * %s" 534 " */\n" 535 "#define AUTOCONF_INCLUDED\n", 536 sym_get_string_value(sym), ctime(&now)); 537 538 sym_clear_all_valid(); 539 540 for_all_symbols(i, sym) { 541 sym_calc_value(sym); 542 if (!(sym->flags & SYMBOL_WRITE) || !sym->name) 543 continue; 544 switch (sym->type) { 545 case S_BOOLEAN: 546 case S_TRISTATE: 547 switch (sym_get_tristate_value(sym)) { 548 case no: 549 break; 550 case mod: 551 fprintf(out, "CONFIG_%s=m\n", sym->name); 552 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 553 break; 554 case yes: 555 fprintf(out, "CONFIG_%s=y\n", sym->name); 556 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); 557 break; 558 } 559 break; 560 case S_STRING: 561 str = sym_get_string_value(sym); 562 fprintf(out, "CONFIG_%s=\"", sym->name); 563 fprintf(out_h, "#define CONFIG_%s \"", sym->name); 564 while (1) { 565 l = strcspn(str, "\"\\"); 566 if (l) { 567 fwrite(str, l, 1, out); 568 fwrite(str, l, 1, out_h); 569 str += l; 570 } 571 if (!*str) 572 break; 573 fprintf(out, "\\%c", *str); 574 fprintf(out_h, "\\%c", *str); 575 str++; 576 } 577 fputs("\"\n", out); 578 fputs("\"\n", out_h); 579 break; 580 case S_HEX: 581 str = sym_get_string_value(sym); 582 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 583 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 584 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 585 break; 586 } 587 case S_INT: 588 str = sym_get_string_value(sym); 589 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 590 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 591 break; 592 default: 593 break; 594 } 595 } 596 fclose(out); 597 fclose(out_h); 598 599 name = getenv("KCONFIG_AUTOHEADER"); 600 if (!name) 601 name = "include/linux/autoconf.h"; 602 if (rename(".tmpconfig.h", name)) 603 return 1; 604 name = getenv("KCONFIG_AUTOCONFIG"); 605 if (!name) 606 name = "include/config/auto.conf"; 607 /* 608 * This must be the last step, kbuild has a dependency on auto.conf 609 * and this marks the successful completion of the previous steps. 610 */ 611 if (rename(".tmpconfig", name)) 612 return 1; 613 614 return 0; 615 } 616