cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

conf.c (20344B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
      4 */
      5
      6#include <ctype.h>
      7#include <limits.h>
      8#include <stdio.h>
      9#include <stdlib.h>
     10#include <string.h>
     11#include <time.h>
     12#include <unistd.h>
     13#include <getopt.h>
     14#include <sys/time.h>
     15#include <errno.h>
     16
     17#include "lkc.h"
     18
     19static void conf(struct menu *menu);
     20static void check_conf(struct menu *menu);
     21
     22enum input_mode {
     23	oldaskconfig,
     24	syncconfig,
     25	oldconfig,
     26	allnoconfig,
     27	allyesconfig,
     28	allmodconfig,
     29	alldefconfig,
     30	randconfig,
     31	defconfig,
     32	savedefconfig,
     33	listnewconfig,
     34	helpnewconfig,
     35	olddefconfig,
     36	yes2modconfig,
     37	mod2yesconfig,
     38	mod2noconfig,
     39};
     40static enum input_mode input_mode = oldaskconfig;
     41static int input_mode_opt;
     42static int indent = 1;
     43static int tty_stdio;
     44static int sync_kconfig;
     45static int conf_cnt;
     46static char line[PATH_MAX];
     47static struct menu *rootEntry;
     48
     49static void print_help(struct menu *menu)
     50{
     51	struct gstr help = str_new();
     52
     53	menu_get_ext_help(menu, &help);
     54
     55	printf("\n%s\n", str_get(&help));
     56	str_free(&help);
     57}
     58
     59static void strip(char *str)
     60{
     61	char *p = str;
     62	int l;
     63
     64	while ((isspace(*p)))
     65		p++;
     66	l = strlen(p);
     67	if (p != str)
     68		memmove(str, p, l + 1);
     69	if (!l)
     70		return;
     71	p = str + l - 1;
     72	while ((isspace(*p)))
     73		*p-- = 0;
     74}
     75
     76/* Helper function to facilitate fgets() by Jean Sacren. */
     77static void xfgets(char *str, int size, FILE *in)
     78{
     79	if (!fgets(str, size, in))
     80		fprintf(stderr, "\nError in reading or end of file.\n");
     81
     82	if (!tty_stdio)
     83		printf("%s", str);
     84}
     85
     86static void set_randconfig_seed(void)
     87{
     88	unsigned int seed;
     89	char *env;
     90	bool seed_set = false;
     91
     92	env = getenv("KCONFIG_SEED");
     93	if (env && *env) {
     94		char *endp;
     95
     96		seed = strtol(env, &endp, 0);
     97		if (*endp == '\0')
     98			seed_set = true;
     99	}
    100
    101	if (!seed_set) {
    102		struct timeval now;
    103
    104		/*
    105		 * Use microseconds derived seed, compensate for systems where it may
    106		 * be zero.
    107		 */
    108		gettimeofday(&now, NULL);
    109		seed = (now.tv_sec + 1) * (now.tv_usec + 1);
    110	}
    111
    112	printf("KCONFIG_SEED=0x%X\n", seed);
    113	srand(seed);
    114}
    115
    116static bool randomize_choice_values(struct symbol *csym)
    117{
    118	struct property *prop;
    119	struct symbol *sym;
    120	struct expr *e;
    121	int cnt, def;
    122
    123	/*
    124	 * If choice is mod then we may have more items selected
    125	 * and if no then no-one.
    126	 * In both cases stop.
    127	 */
    128	if (csym->curr.tri != yes)
    129		return false;
    130
    131	prop = sym_get_choice_prop(csym);
    132
    133	/* count entries in choice block */
    134	cnt = 0;
    135	expr_list_for_each_sym(prop->expr, e, sym)
    136		cnt++;
    137
    138	/*
    139	 * find a random value and set it to yes,
    140	 * set the rest to no so we have only one set
    141	 */
    142	def = rand() % cnt;
    143
    144	cnt = 0;
    145	expr_list_for_each_sym(prop->expr, e, sym) {
    146		if (def == cnt++) {
    147			sym->def[S_DEF_USER].tri = yes;
    148			csym->def[S_DEF_USER].val = sym;
    149		} else {
    150			sym->def[S_DEF_USER].tri = no;
    151		}
    152		sym->flags |= SYMBOL_DEF_USER;
    153		/* clear VALID to get value calculated */
    154		sym->flags &= ~SYMBOL_VALID;
    155	}
    156	csym->flags |= SYMBOL_DEF_USER;
    157	/* clear VALID to get value calculated */
    158	csym->flags &= ~SYMBOL_VALID;
    159
    160	return true;
    161}
    162
    163enum conf_def_mode {
    164	def_default,
    165	def_yes,
    166	def_mod,
    167	def_no,
    168	def_random
    169};
    170
    171static bool conf_set_all_new_symbols(enum conf_def_mode mode)
    172{
    173	struct symbol *sym, *csym;
    174	int i, cnt;
    175	/*
    176	 * can't go as the default in switch-case below, otherwise gcc whines
    177	 * about -Wmaybe-uninitialized
    178	 */
    179	int pby = 50; /* probability of bool     = y */
    180	int pty = 33; /* probability of tristate = y */
    181	int ptm = 33; /* probability of tristate = m */
    182	bool has_changed = false;
    183
    184	if (mode == def_random) {
    185		int n, p[3];
    186		char *env = getenv("KCONFIG_PROBABILITY");
    187
    188		n = 0;
    189		while (env && *env) {
    190			char *endp;
    191			int tmp = strtol(env, &endp, 10);
    192
    193			if (tmp >= 0 && tmp <= 100) {
    194				p[n++] = tmp;
    195			} else {
    196				errno = ERANGE;
    197				perror("KCONFIG_PROBABILITY");
    198				exit(1);
    199			}
    200			env = (*endp == ':') ? endp + 1 : endp;
    201			if (n >= 3)
    202				break;
    203		}
    204		switch (n) {
    205		case 1:
    206			pby = p[0];
    207			ptm = pby / 2;
    208			pty = pby - ptm;
    209			break;
    210		case 2:
    211			pty = p[0];
    212			ptm = p[1];
    213			pby = pty + ptm;
    214			break;
    215		case 3:
    216			pby = p[0];
    217			pty = p[1];
    218			ptm = p[2];
    219			break;
    220		}
    221
    222		if (pty + ptm > 100) {
    223			errno = ERANGE;
    224			perror("KCONFIG_PROBABILITY");
    225			exit(1);
    226		}
    227	}
    228
    229	for_all_symbols(i, sym) {
    230		if (sym_has_value(sym) || sym->flags & SYMBOL_VALID)
    231			continue;
    232		switch (sym_get_type(sym)) {
    233		case S_BOOLEAN:
    234		case S_TRISTATE:
    235			has_changed = true;
    236			switch (mode) {
    237			case def_yes:
    238				sym->def[S_DEF_USER].tri = yes;
    239				break;
    240			case def_mod:
    241				sym->def[S_DEF_USER].tri = mod;
    242				break;
    243			case def_no:
    244				sym->def[S_DEF_USER].tri = no;
    245				break;
    246			case def_random:
    247				sym->def[S_DEF_USER].tri = no;
    248				cnt = rand() % 100;
    249				if (sym->type == S_TRISTATE) {
    250					if (cnt < pty)
    251						sym->def[S_DEF_USER].tri = yes;
    252					else if (cnt < pty + ptm)
    253						sym->def[S_DEF_USER].tri = mod;
    254				} else if (cnt < pby)
    255					sym->def[S_DEF_USER].tri = yes;
    256				break;
    257			default:
    258				continue;
    259			}
    260			if (!(sym_is_choice(sym) && mode == def_random))
    261				sym->flags |= SYMBOL_DEF_USER;
    262			break;
    263		default:
    264			break;
    265		}
    266
    267	}
    268
    269	sym_clear_all_valid();
    270
    271	/*
    272	 * We have different type of choice blocks.
    273	 * If curr.tri equals to mod then we can select several
    274	 * choice symbols in one block.
    275	 * In this case we do nothing.
    276	 * If curr.tri equals yes then only one symbol can be
    277	 * selected in a choice block and we set it to yes,
    278	 * and the rest to no.
    279	 */
    280	if (mode != def_random) {
    281		for_all_symbols(i, csym) {
    282			if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
    283			    sym_is_choice_value(csym))
    284				csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
    285		}
    286	}
    287
    288	for_all_symbols(i, csym) {
    289		if (sym_has_value(csym) || !sym_is_choice(csym))
    290			continue;
    291
    292		sym_calc_value(csym);
    293		if (mode == def_random)
    294			has_changed |= randomize_choice_values(csym);
    295		else {
    296			set_all_choice_values(csym);
    297			has_changed = true;
    298		}
    299	}
    300
    301	return has_changed;
    302}
    303
    304static void conf_rewrite_tristates(tristate old_val, tristate new_val)
    305{
    306	struct symbol *sym;
    307	int i;
    308
    309	for_all_symbols(i, sym) {
    310		if (sym_get_type(sym) == S_TRISTATE &&
    311		    sym->def[S_DEF_USER].tri == old_val)
    312			sym->def[S_DEF_USER].tri = new_val;
    313	}
    314	sym_clear_all_valid();
    315}
    316
    317static int conf_askvalue(struct symbol *sym, const char *def)
    318{
    319	if (!sym_has_value(sym))
    320		printf("(NEW) ");
    321
    322	line[0] = '\n';
    323	line[1] = 0;
    324
    325	if (!sym_is_changeable(sym)) {
    326		printf("%s\n", def);
    327		line[0] = '\n';
    328		line[1] = 0;
    329		return 0;
    330	}
    331
    332	switch (input_mode) {
    333	case oldconfig:
    334	case syncconfig:
    335		if (sym_has_value(sym)) {
    336			printf("%s\n", def);
    337			return 0;
    338		}
    339		/* fall through */
    340	default:
    341		fflush(stdout);
    342		xfgets(line, sizeof(line), stdin);
    343		break;
    344	}
    345
    346	return 1;
    347}
    348
    349static int conf_string(struct menu *menu)
    350{
    351	struct symbol *sym = menu->sym;
    352	const char *def;
    353
    354	while (1) {
    355		printf("%*s%s ", indent - 1, "", menu->prompt->text);
    356		printf("(%s) ", sym->name);
    357		def = sym_get_string_value(sym);
    358		if (def)
    359			printf("[%s] ", def);
    360		if (!conf_askvalue(sym, def))
    361			return 0;
    362		switch (line[0]) {
    363		case '\n':
    364			break;
    365		case '?':
    366			/* print help */
    367			if (line[1] == '\n') {
    368				print_help(menu);
    369				def = NULL;
    370				break;
    371			}
    372			/* fall through */
    373		default:
    374			line[strlen(line)-1] = 0;
    375			def = line;
    376		}
    377		if (def && sym_set_string_value(sym, def))
    378			return 0;
    379	}
    380}
    381
    382static int conf_sym(struct menu *menu)
    383{
    384	struct symbol *sym = menu->sym;
    385	tristate oldval, newval;
    386
    387	while (1) {
    388		printf("%*s%s ", indent - 1, "", menu->prompt->text);
    389		if (sym->name)
    390			printf("(%s) ", sym->name);
    391		putchar('[');
    392		oldval = sym_get_tristate_value(sym);
    393		switch (oldval) {
    394		case no:
    395			putchar('N');
    396			break;
    397		case mod:
    398			putchar('M');
    399			break;
    400		case yes:
    401			putchar('Y');
    402			break;
    403		}
    404		if (oldval != no && sym_tristate_within_range(sym, no))
    405			printf("/n");
    406		if (oldval != mod && sym_tristate_within_range(sym, mod))
    407			printf("/m");
    408		if (oldval != yes && sym_tristate_within_range(sym, yes))
    409			printf("/y");
    410		printf("/?] ");
    411		if (!conf_askvalue(sym, sym_get_string_value(sym)))
    412			return 0;
    413		strip(line);
    414
    415		switch (line[0]) {
    416		case 'n':
    417		case 'N':
    418			newval = no;
    419			if (!line[1] || !strcmp(&line[1], "o"))
    420				break;
    421			continue;
    422		case 'm':
    423		case 'M':
    424			newval = mod;
    425			if (!line[1])
    426				break;
    427			continue;
    428		case 'y':
    429		case 'Y':
    430			newval = yes;
    431			if (!line[1] || !strcmp(&line[1], "es"))
    432				break;
    433			continue;
    434		case 0:
    435			newval = oldval;
    436			break;
    437		case '?':
    438			goto help;
    439		default:
    440			continue;
    441		}
    442		if (sym_set_tristate_value(sym, newval))
    443			return 0;
    444help:
    445		print_help(menu);
    446	}
    447}
    448
    449static int conf_choice(struct menu *menu)
    450{
    451	struct symbol *sym, *def_sym;
    452	struct menu *child;
    453	bool is_new;
    454
    455	sym = menu->sym;
    456	is_new = !sym_has_value(sym);
    457	if (sym_is_changeable(sym)) {
    458		conf_sym(menu);
    459		sym_calc_value(sym);
    460		switch (sym_get_tristate_value(sym)) {
    461		case no:
    462			return 1;
    463		case mod:
    464			return 0;
    465		case yes:
    466			break;
    467		}
    468	} else {
    469		switch (sym_get_tristate_value(sym)) {
    470		case no:
    471			return 1;
    472		case mod:
    473			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
    474			return 0;
    475		case yes:
    476			break;
    477		}
    478	}
    479
    480	while (1) {
    481		int cnt, def;
    482
    483		printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
    484		def_sym = sym_get_choice_value(sym);
    485		cnt = def = 0;
    486		line[0] = 0;
    487		for (child = menu->list; child; child = child->next) {
    488			if (!menu_is_visible(child))
    489				continue;
    490			if (!child->sym) {
    491				printf("%*c %s\n", indent, '*', menu_get_prompt(child));
    492				continue;
    493			}
    494			cnt++;
    495			if (child->sym == def_sym) {
    496				def = cnt;
    497				printf("%*c", indent, '>');
    498			} else
    499				printf("%*c", indent, ' ');
    500			printf(" %d. %s", cnt, menu_get_prompt(child));
    501			if (child->sym->name)
    502				printf(" (%s)", child->sym->name);
    503			if (!sym_has_value(child->sym))
    504				printf(" (NEW)");
    505			printf("\n");
    506		}
    507		printf("%*schoice", indent - 1, "");
    508		if (cnt == 1) {
    509			printf("[1]: 1\n");
    510			goto conf_childs;
    511		}
    512		printf("[1-%d?]: ", cnt);
    513		switch (input_mode) {
    514		case oldconfig:
    515		case syncconfig:
    516			if (!is_new) {
    517				cnt = def;
    518				printf("%d\n", cnt);
    519				break;
    520			}
    521			/* fall through */
    522		case oldaskconfig:
    523			fflush(stdout);
    524			xfgets(line, sizeof(line), stdin);
    525			strip(line);
    526			if (line[0] == '?') {
    527				print_help(menu);
    528				continue;
    529			}
    530			if (!line[0])
    531				cnt = def;
    532			else if (isdigit(line[0]))
    533				cnt = atoi(line);
    534			else
    535				continue;
    536			break;
    537		default:
    538			break;
    539		}
    540
    541	conf_childs:
    542		for (child = menu->list; child; child = child->next) {
    543			if (!child->sym || !menu_is_visible(child))
    544				continue;
    545			if (!--cnt)
    546				break;
    547		}
    548		if (!child)
    549			continue;
    550		if (line[0] && line[strlen(line) - 1] == '?') {
    551			print_help(child);
    552			continue;
    553		}
    554		sym_set_choice_value(sym, child->sym);
    555		for (child = child->list; child; child = child->next) {
    556			indent += 2;
    557			conf(child);
    558			indent -= 2;
    559		}
    560		return 1;
    561	}
    562}
    563
    564static void conf(struct menu *menu)
    565{
    566	struct symbol *sym;
    567	struct property *prop;
    568	struct menu *child;
    569
    570	if (!menu_is_visible(menu))
    571		return;
    572
    573	sym = menu->sym;
    574	prop = menu->prompt;
    575	if (prop) {
    576		const char *prompt;
    577
    578		switch (prop->type) {
    579		case P_MENU:
    580			/*
    581			 * Except in oldaskconfig mode, we show only menus that
    582			 * contain new symbols.
    583			 */
    584			if (input_mode != oldaskconfig && rootEntry != menu) {
    585				check_conf(menu);
    586				return;
    587			}
    588			/* fall through */
    589		case P_COMMENT:
    590			prompt = menu_get_prompt(menu);
    591			if (prompt)
    592				printf("%*c\n%*c %s\n%*c\n",
    593					indent, '*',
    594					indent, '*', prompt,
    595					indent, '*');
    596		default:
    597			;
    598		}
    599	}
    600
    601	if (!sym)
    602		goto conf_childs;
    603
    604	if (sym_is_choice(sym)) {
    605		conf_choice(menu);
    606		if (sym->curr.tri != mod)
    607			return;
    608		goto conf_childs;
    609	}
    610
    611	switch (sym->type) {
    612	case S_INT:
    613	case S_HEX:
    614	case S_STRING:
    615		conf_string(menu);
    616		break;
    617	default:
    618		conf_sym(menu);
    619		break;
    620	}
    621
    622conf_childs:
    623	if (sym)
    624		indent += 2;
    625	for (child = menu->list; child; child = child->next)
    626		conf(child);
    627	if (sym)
    628		indent -= 2;
    629}
    630
    631static void check_conf(struct menu *menu)
    632{
    633	struct symbol *sym;
    634	struct menu *child;
    635
    636	if (!menu_is_visible(menu))
    637		return;
    638
    639	sym = menu->sym;
    640	if (sym && !sym_has_value(sym) &&
    641	    (sym_is_changeable(sym) ||
    642	     (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
    643
    644		switch (input_mode) {
    645		case listnewconfig:
    646			if (sym->name)
    647				print_symbol_for_listconfig(sym);
    648			break;
    649		case helpnewconfig:
    650			printf("-----\n");
    651			print_help(menu);
    652			printf("-----\n");
    653			break;
    654		default:
    655			if (!conf_cnt++)
    656				printf("*\n* Restart config...\n*\n");
    657			rootEntry = menu_get_parent_menu(menu);
    658			conf(rootEntry);
    659			break;
    660		}
    661	}
    662
    663	for (child = menu->list; child; child = child->next)
    664		check_conf(child);
    665}
    666
    667static const struct option long_opts[] = {
    668	{"help",          no_argument,       NULL,            'h'},
    669	{"silent",        no_argument,       NULL,            's'},
    670	{"oldaskconfig",  no_argument,       &input_mode_opt, oldaskconfig},
    671	{"oldconfig",     no_argument,       &input_mode_opt, oldconfig},
    672	{"syncconfig",    no_argument,       &input_mode_opt, syncconfig},
    673	{"defconfig",     required_argument, &input_mode_opt, defconfig},
    674	{"savedefconfig", required_argument, &input_mode_opt, savedefconfig},
    675	{"allnoconfig",   no_argument,       &input_mode_opt, allnoconfig},
    676	{"allyesconfig",  no_argument,       &input_mode_opt, allyesconfig},
    677	{"allmodconfig",  no_argument,       &input_mode_opt, allmodconfig},
    678	{"alldefconfig",  no_argument,       &input_mode_opt, alldefconfig},
    679	{"randconfig",    no_argument,       &input_mode_opt, randconfig},
    680	{"listnewconfig", no_argument,       &input_mode_opt, listnewconfig},
    681	{"helpnewconfig", no_argument,       &input_mode_opt, helpnewconfig},
    682	{"olddefconfig",  no_argument,       &input_mode_opt, olddefconfig},
    683	{"yes2modconfig", no_argument,       &input_mode_opt, yes2modconfig},
    684	{"mod2yesconfig", no_argument,       &input_mode_opt, mod2yesconfig},
    685	{"mod2noconfig",  no_argument,       &input_mode_opt, mod2noconfig},
    686	{NULL, 0, NULL, 0}
    687};
    688
    689static void conf_usage(const char *progname)
    690{
    691	printf("Usage: %s [options] <kconfig-file>\n", progname);
    692	printf("\n");
    693	printf("Generic options:\n");
    694	printf("  -h, --help              Print this message and exit.\n");
    695	printf("  -s, --silent            Do not print log.\n");
    696	printf("\n");
    697	printf("Mode options:\n");
    698	printf("  --listnewconfig         List new options\n");
    699	printf("  --helpnewconfig         List new options and help text\n");
    700	printf("  --oldaskconfig          Start a new configuration using a line-oriented program\n");
    701	printf("  --oldconfig             Update a configuration using a provided .config as base\n");
    702	printf("  --syncconfig            Similar to oldconfig but generates configuration in\n"
    703	       "                          include/{generated/,config/}\n");
    704	printf("  --olddefconfig          Same as oldconfig but sets new symbols to their default value\n");
    705	printf("  --defconfig <file>      New config with default defined in <file>\n");
    706	printf("  --savedefconfig <file>  Save the minimal current configuration to <file>\n");
    707	printf("  --allnoconfig           New config where all options are answered with no\n");
    708	printf("  --allyesconfig          New config where all options are answered with yes\n");
    709	printf("  --allmodconfig          New config where all options are answered with mod\n");
    710	printf("  --alldefconfig          New config with all symbols set to default\n");
    711	printf("  --randconfig            New config with random answer to all options\n");
    712	printf("  --yes2modconfig         Change answers from yes to mod if possible\n");
    713	printf("  --mod2yesconfig         Change answers from mod to yes if possible\n");
    714	printf("  --mod2noconfig          Change answers from mod to no if possible\n");
    715	printf("  (If none of the above is given, --oldaskconfig is the default)\n");
    716}
    717
    718int main(int ac, char **av)
    719{
    720	const char *progname = av[0];
    721	int opt;
    722	const char *name, *defconfig_file = NULL /* gcc uninit */;
    723	int no_conf_write = 0;
    724
    725	tty_stdio = isatty(0) && isatty(1);
    726
    727	while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) {
    728		switch (opt) {
    729		case 'h':
    730			conf_usage(progname);
    731			exit(1);
    732			break;
    733		case 's':
    734			conf_set_message_callback(NULL);
    735			break;
    736		case 0:
    737			input_mode = input_mode_opt;
    738			switch (input_mode) {
    739			case syncconfig:
    740				/*
    741				 * syncconfig is invoked during the build stage.
    742				 * Suppress distracting
    743				 *   "configuration written to ..."
    744				 */
    745				conf_set_message_callback(NULL);
    746				sync_kconfig = 1;
    747				break;
    748			case defconfig:
    749			case savedefconfig:
    750				defconfig_file = optarg;
    751				break;
    752			case randconfig:
    753				set_randconfig_seed();
    754				break;
    755			default:
    756				break;
    757			}
    758		default:
    759			break;
    760		}
    761	}
    762	if (ac == optind) {
    763		fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
    764		conf_usage(progname);
    765		exit(1);
    766	}
    767	conf_parse(av[optind]);
    768	//zconfdump(stdout);
    769
    770	switch (input_mode) {
    771	case defconfig:
    772		if (conf_read(defconfig_file)) {
    773			fprintf(stderr,
    774				"***\n"
    775				  "*** Can't find default configuration \"%s\"!\n"
    776				  "***\n",
    777				defconfig_file);
    778			exit(1);
    779		}
    780		break;
    781	case savedefconfig:
    782	case syncconfig:
    783	case oldaskconfig:
    784	case oldconfig:
    785	case listnewconfig:
    786	case helpnewconfig:
    787	case olddefconfig:
    788	case yes2modconfig:
    789	case mod2yesconfig:
    790	case mod2noconfig:
    791		conf_read(NULL);
    792		break;
    793	case allnoconfig:
    794	case allyesconfig:
    795	case allmodconfig:
    796	case alldefconfig:
    797	case randconfig:
    798		name = getenv("KCONFIG_ALLCONFIG");
    799		if (!name)
    800			break;
    801		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
    802			if (conf_read_simple(name, S_DEF_USER)) {
    803				fprintf(stderr,
    804					"*** Can't read seed configuration \"%s\"!\n",
    805					name);
    806				exit(1);
    807			}
    808			break;
    809		}
    810		switch (input_mode) {
    811		case allnoconfig:	name = "allno.config"; break;
    812		case allyesconfig:	name = "allyes.config"; break;
    813		case allmodconfig:	name = "allmod.config"; break;
    814		case alldefconfig:	name = "alldef.config"; break;
    815		case randconfig:	name = "allrandom.config"; break;
    816		default: break;
    817		}
    818		if (conf_read_simple(name, S_DEF_USER) &&
    819		    conf_read_simple("all.config", S_DEF_USER)) {
    820			fprintf(stderr,
    821				"*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
    822				name);
    823			exit(1);
    824		}
    825		break;
    826	default:
    827		break;
    828	}
    829
    830	if (sync_kconfig) {
    831		name = getenv("KCONFIG_NOSILENTUPDATE");
    832		if (name && *name) {
    833			if (conf_get_changed()) {
    834				fprintf(stderr,
    835					"\n*** The configuration requires explicit update.\n\n");
    836				return 1;
    837			}
    838			no_conf_write = 1;
    839		}
    840	}
    841
    842	switch (input_mode) {
    843	case allnoconfig:
    844		conf_set_all_new_symbols(def_no);
    845		break;
    846	case allyesconfig:
    847		conf_set_all_new_symbols(def_yes);
    848		break;
    849	case allmodconfig:
    850		conf_set_all_new_symbols(def_mod);
    851		break;
    852	case alldefconfig:
    853		conf_set_all_new_symbols(def_default);
    854		break;
    855	case randconfig:
    856		/* Really nothing to do in this loop */
    857		while (conf_set_all_new_symbols(def_random)) ;
    858		break;
    859	case defconfig:
    860		conf_set_all_new_symbols(def_default);
    861		break;
    862	case savedefconfig:
    863		break;
    864	case yes2modconfig:
    865		conf_rewrite_tristates(yes, mod);
    866		break;
    867	case mod2yesconfig:
    868		conf_rewrite_tristates(mod, yes);
    869		break;
    870	case mod2noconfig:
    871		conf_rewrite_tristates(mod, no);
    872		break;
    873	case oldaskconfig:
    874		rootEntry = &rootmenu;
    875		conf(&rootmenu);
    876		input_mode = oldconfig;
    877		/* fall through */
    878	case oldconfig:
    879	case listnewconfig:
    880	case helpnewconfig:
    881	case syncconfig:
    882		/* Update until a loop caused no more changes */
    883		do {
    884			conf_cnt = 0;
    885			check_conf(&rootmenu);
    886		} while (conf_cnt);
    887		break;
    888	case olddefconfig:
    889	default:
    890		break;
    891	}
    892
    893	if (input_mode == savedefconfig) {
    894		if (conf_write_defconfig(defconfig_file)) {
    895			fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
    896				defconfig_file);
    897			return 1;
    898		}
    899	} else if (input_mode != listnewconfig && input_mode != helpnewconfig) {
    900		if (!no_conf_write && conf_write(NULL)) {
    901			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
    902			exit(1);
    903		}
    904
    905		/*
    906		 * Create auto.conf if it does not exist.
    907		 * This prevents GNU Make 4.1 or older from emitting
    908		 * "include/config/auto.conf: No such file or directory"
    909		 * in the top-level Makefile
    910		 *
    911		 * syncconfig always creates or updates auto.conf because it is
    912		 * used during the build.
    913		 */
    914		if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
    915			fprintf(stderr,
    916				"\n*** Error during sync of the configuration.\n\n");
    917			return 1;
    918		}
    919	}
    920	return 0;
    921}