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

confdata.c (23778B)


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