main.c revision 45744
11573Srgrimes/*
21573Srgrimes * Copyright (c) 1980, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 3. All advertising materials mentioning features or use of this software
141573Srgrimes *    must display the following acknowledgement:
151573Srgrimes *	This product includes software developed by the University of
161573Srgrimes *	California, Berkeley and its contributors.
171573Srgrimes * 4. Neither the name of the University nor the names of its contributors
181573Srgrimes *    may be used to endorse or promote products derived from this software
191573Srgrimes *    without specific prior written permission.
201573Srgrimes *
211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2950476Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31212492Sgjb * SUCH DAMAGE.
3270936Sru */
3370936Sru
3470936Sru#ifndef lint
3570936Srustatic const char copyright[] =
3670936Sru"@(#) Copyright (c) 1980, 1993\n\
3770936Sru	The Regents of the University of California.  All rights reserved.\n";
3884306Sru#endif /* not lint */
39105404Smarkm
40105404Smarkm#ifndef lint
4184306Sru#if 0
4270936Srustatic char sccsid[] = "@(#)main.c	8.1 (Berkeley) 6/6/93";
4370936Sru#endif
4470936Srustatic const char rcsid[] =
45108037Sru	"$Id: main.c,v 1.29 1999/04/11 03:40:10 grog Exp $";
46108037Sru#endif /* not lint */
47108037Sru
481573Srgrimes#include <sys/types.h>
491573Srgrimes#include <sys/stat.h>
501573Srgrimes#include <sys/file.h>
511573Srgrimes#include <sys/mman.h>
521573Srgrimes#include <ctype.h>
531573Srgrimes#include <err.h>
541573Srgrimes#include <stdio.h>
551573Srgrimes#include <sysexits.h>
5670936Sru#include <unistd.h>
5770936Sru#include "y.tab.h"
581573Srgrimes#include "config.h"
5970936Sru
6070936Sru#ifndef TRUE
61108037Sru#define TRUE	(1)
62108037Sru#endif
63108037Sru
6470936Sru#ifndef FALSE
6570936Sru#define FALSE	(0)
661573Srgrimes#endif
671573Srgrimes
68108087Sruchar *	PREFIX;
69108087Srustatic int no_config_clobber = TRUE;
70108087Sruint	old_config_present;
7170936Sruint	debugging;
7270936Sruint	profiling;
731573Srgrimesu_int   loadaddress;
7470936Sru
751573Srgrimesstatic void usage __P((void));
7670936Srustatic void configfile __P((void));
7770936Sru
781573Srgrimes/*
7970936Sru * Config builds a set of files for building a UNIX
8070936Sru * system given a description of the desired system.
81212441Sgjb */
82212441Sgjbint
8370936Srumain(argc, argv)
8470936Sru	int argc;
8570936Sru	char **argv;
8670936Sru{
8770936Sru
8870936Sru	struct stat buf;
891573Srgrimes	int ch;
9070936Sru	char *p;
911573Srgrimes
9270936Sru	while ((ch = getopt(argc, argv, "gprn")) != -1)
931573Srgrimes		switch (ch) {
9470936Sru		case 'g':
9570936Sru			debugging++;
961573Srgrimes			break;
97141846Sru		case 'p':
981573Srgrimes			profiling++;
991573Srgrimes			break;
10070936Sru		case 'n':
1011573Srgrimes			/* no_config_clobber is now true by default, no-op */
1021573Srgrimes			fprintf(stderr,
1031573Srgrimes				"*** Using obsolete config option '-n' ***\n");
10470936Sru			break;
1051573Srgrimes		case 'r':
10670936Sru			no_config_clobber = FALSE;
10770936Sru			break;
10870936Sru		case '?':
10970936Sru		default:
11070936Sru			usage();
11170936Sru		}
11270936Sru	argc -= optind;
1131573Srgrimes	argv += optind;
11470936Sru
11570936Sru	if (argc != 1)
11670936Sru		usage();
11770936Sru
118119893Sru	if (freopen(PREFIX = *argv, "r", stdin) == NULL)
11970936Sru		err(2, "%s", PREFIX);
12070936Sru
12170936Sru	p = path((char *)NULL);
12270936Sru	if (stat(p, &buf)) {
12370936Sru		if (mkdir(p, 0777))
12470936Sru			err(2, "%s", p);
1251573Srgrimes	}
12670936Sru	else if ((buf.st_mode & S_IFMT) != S_IFDIR) {
1271573Srgrimes		errx(2, "%s isn't a directory", p);
1281573Srgrimes	}
1291573Srgrimes	else if (!no_config_clobber) {
13070936Sru		char tmp[strlen(p) + 8];
13170936Sru
13270936Sru		fprintf(stderr, "Removing old directory %s:  ", p);
13370936Sru		fflush(stderr);
1341573Srgrimes		sprintf(tmp, "rm -rf %s", p);
13570936Sru		if (system(tmp)) {
136108037Sru			fprintf(stderr, "Failed!\n");
137108037Sru			err(2, "%s", tmp);
138108037Sru		}
13970936Sru		fprintf(stderr, "Done.\n");
14070936Sru		if (mkdir(p, 0777))
14170936Sru			err(2, "%s", p);
14270936Sru	}
14370936Sru	else
14470936Sru		old_config_present = 1;
14570936Sru
14670936Sru	loadaddress = -1;
147119893Sru	dtab = NULL;
14870936Sru	confp = &conf_list;
1491573Srgrimes	compp = &comp_list;
15070936Sru	if (yyparse())
1511573Srgrimes		exit(3);
15270936Sru	switch (machine) {
153149939Sstefanf
15470936Sru	case MACHINE_I386:
15570936Sru	case MACHINE_PC98:
156149939Sstefanf		i386_ioconf();		/* Print ioconf.c */
15770936Sru		break;
15870936Sru
15970936Sru	case MACHINE_ALPHA:
16070936Sru		alpha_ioconf();
1611573Srgrimes		break;
16270936Sru
16370936Sru	default:
1641573Srgrimes		printf("Specify machine type, e.g. ``machine vax''\n");
1651573Srgrimes		exit(1);
1661573Srgrimes	}
16770936Sru	/*
1681573Srgrimes	 * make symbolic links in compilation directory
16970936Sru	 * for "sys" (to make genassym.c work along with #include <sys/xxx>)
17070936Sru	 * and similarly for "machine".
1711573Srgrimes	 */
17270936Sru	{
1731573Srgrimes	char xxx[80];
1741573Srgrimes
1751573Srgrimes	(void) snprintf(xxx, sizeof(xxx), "../../%s/include", machinename);
1761573Srgrimes	(void) symlink(xxx, path("machine"));
17770936Sru	}
1781573Srgrimes	options();			/* make options .h files */
17970936Sru	makefile();			/* build Makefile */
1801573Srgrimes	headers();			/* make a lot of .h files */
181108087Sru	swapconf();			/* swap config files */
1821573Srgrimes	configfile();			/* put config file into kernel*/
18370936Sru	printf("Kernel build directory is %s\n", p);
1841573Srgrimes	exit(0);
18570936Sru}
1861573Srgrimes
18770936Srustatic void
188108087Sruusage()
18970936Sru{
190108087Sru		fprintf(stderr, "usage: config [-gpr] sysname\n");
1911573Srgrimes		exit(1);
19270936Sru}
19370936Sru
1941573Srgrimes/*
1951573Srgrimes * get_word
19670936Sru *	returns EOF on end of file
19770936Sru *	NULL on end of line
198108087Sru *	pointer to the word otherwise
1991573Srgrimes */
20070936Sruchar *
2011573Srgrimesget_word(fp)
20270936Sru	register FILE *fp;
2031573Srgrimes{
20470936Sru	static char line[80];
2051573Srgrimes	register int ch;
2061573Srgrimes	register char *cp;
2071573Srgrimes	int escaped_nl = 0;
2081573Srgrimes
20970936Srubegin:
2101573Srgrimes	while ((ch = getc(fp)) != EOF)
21170936Sru		if (ch != ' ' && ch != '\t')
2121573Srgrimes			break;
2131573Srgrimes	if (ch == EOF)
21470936Sru		return ((char *)EOF);
2151573Srgrimes	if (ch == '\\'){
21670936Sru		escaped_nl = 1;
2171573Srgrimes		goto begin;
2181573Srgrimes	}
2191573Srgrimes	if (ch == '\n')
2201573Srgrimes		if (escaped_nl){
22170936Sru			escaped_nl = 0;
2221573Srgrimes			goto begin;
22370936Sru		}
2241573Srgrimes		else
22570936Sru			return (NULL);
2261573Srgrimes	cp = line;
2271573Srgrimes	*cp++ = ch;
2281573Srgrimes	while ((ch = getc(fp)) != EOF) {
22970936Sru		if (isspace(ch))
2301573Srgrimes			break;
23170936Sru		*cp++ = ch;
232108087Sru	}
2331573Srgrimes	*cp = 0;
23470936Sru	if (ch == EOF)
2351573Srgrimes		return ((char *)EOF);
23670936Sru	(void) ungetc(ch, fp);
2371573Srgrimes	return (line);
23870936Sru}
2391573Srgrimes
24070936Sru/*
241108087Sru * get_quoted_word
24270936Sru *	like get_word but will accept something in double or single quotes
243108087Sru *	(to allow embedded spaces).
2441573Srgrimes */
24570936Sruchar *
24670936Sruget_quoted_word(fp)
2471573Srgrimes	register FILE *fp;
2481573Srgrimes{
24970936Sru	static char line[256];
2501573Srgrimes	register int ch;
25170936Sru	register char *cp;
2521573Srgrimes	int escaped_nl = 0;
2531573Srgrimes
25470936Srubegin:
2551573Srgrimes	while ((ch = getc(fp)) != EOF)
25670936Sru		if (ch != ' ' && ch != '\t')
25770936Sru			break;
25870936Sru	if (ch == EOF)
25970936Sru		return ((char *)EOF);
2601573Srgrimes	if (ch == '\\'){
26170936Sru		escaped_nl = 1;
2621573Srgrimes		goto begin;
2631573Srgrimes	}
26470936Sru	if (ch == '\n')
2651573Srgrimes		if (escaped_nl){
26670936Sru			escaped_nl = 0;
26770936Sru			goto begin;
26870936Sru		}
26970936Sru		else
2701573Srgrimes			return (NULL);
27170936Sru	cp = line;
2721573Srgrimes	if (ch == '"' || ch == '\'') {
2731573Srgrimes		register int quote = ch;
27470936Sru
27570936Sru		while ((ch = getc(fp)) != EOF) {
27670936Sru			if (ch == quote)
27770936Sru				break;
27870936Sru			if (ch == '\n') {
27970936Sru				*cp = 0;
28070936Sru				printf("config: missing quote reading `%s'\n",
28170936Sru					line);
28270936Sru				exit(2);
28370936Sru			}
28470936Sru			*cp++ = ch;
28570936Sru		}
28670936Sru	} else {
2871573Srgrimes		*cp++ = ch;
2881573Srgrimes		while ((ch = getc(fp)) != EOF) {
28970936Sru			if (isspace(ch))
29070936Sru				break;
29170936Sru			*cp++ = ch;
29270936Sru		}
29370936Sru		if (ch != EOF)
29470936Sru			(void) ungetc(ch, fp);
2951573Srgrimes	}
2961573Srgrimes	*cp = 0;
2971573Srgrimes	if (ch == EOF)
2981573Srgrimes		return ((char *)EOF);
29970936Sru	return (line);
3001573Srgrimes}
30170936Sru
3021573Srgrimes/*
3031573Srgrimes * prepend the path to a filename
30470936Sru */
305108087Sruchar *
3061573Srgrimespath(file)
30770936Sru	char *file;
30870936Sru{
30970936Sru	register char *cp;
31070936Sru
3111573Srgrimes#define	CDIR	"../../compile/"
31270936Sru	cp = malloc((unsigned int)(sizeof(CDIR) + strlen(PREFIX) +
3131573Srgrimes	    (file ? strlen(file) : 0) + 2));
3141573Srgrimes	(void) strcpy(cp, CDIR);
3151573Srgrimes	(void) strcat(cp, PREFIX);
3161573Srgrimes	if (file) {
31770936Sru		(void) strcat(cp, "/");
3181573Srgrimes		(void) strcat(cp, file);
3191573Srgrimes	}
3201573Srgrimes	return (cp);
32170936Sru}
32270936Sru
3231573Srgrimesstatic void
32470936Sruconfigfile()
32570936Sru{
32670936Sru	FILE *fi, *fo;
32770936Sru	char *p;
32870936Sru	int i;
32970936Sru
3301573Srgrimes	fi = fopen(PREFIX,"r");
33170936Sru	if(!fi)
3321573Srgrimes		err(2, "%s", PREFIX);
3331573Srgrimes	fo = fopen(p=path("config.c.new"),"w");
334131504Sru	if(!fo)
3351573Srgrimes		err(2, "%s", p);
33670936Sru	fprintf(fo,"#include \"opt_config.h\"\n");
33770936Sru	fprintf(fo,"#ifdef INCLUDE_CONFIG_FILE \n");
33870936Sru	fprintf(fo,"static const char config[] = \"\\\n");
339108087Sru	fprintf(fo,"START CONFIG FILE %s\\n\\\n___",PREFIX);
34070936Sru	while (EOF != (i=getc(fi))) {
3411573Srgrimes		if(i == '\n') {
34270936Sru			fprintf(fo,"\\n\\\n___");
34370936Sru		} else if(i == '\"') {
3441573Srgrimes			fprintf(fo,"\\\"");
3451573Srgrimes		} else if(i == '\\') {
34670936Sru			fprintf(fo,"\\\\");
3471573Srgrimes		} else {
3481573Srgrimes			putc(i,fo);
34970936Sru		}
35070936Sru	}
35170936Sru	fprintf(fo,"\\n\\\nEND CONFIG FILE %s\\n\\\n",PREFIX);
3521573Srgrimes	fprintf(fo,"\";\n");
3531573Srgrimes	fprintf(fo,"\n#endif /* INCLUDE_CONFIG_FILE */\n");
3541573Srgrimes	fclose(fi);
35570936Sru	fclose(fo);
3561573Srgrimes	moveifchanged(path("config.c.new"), path("config.c"));
3571573Srgrimes}
35870936Sru
3591573Srgrimes/*
3601573Srgrimes * moveifchanged --
36170936Sru *	compare two files; rename if changed.
36270936Sru */
36370936Sruvoid
36470936Srumoveifchanged(const char *from_name, const char *to_name)
36570936Sru{
36670936Sru	char *p, *q;
3671573Srgrimes	int changed;
36870936Sru	size_t tsize;
36970936Sru	struct stat from_sb, to_sb;
37070936Sru	int from_fd, to_fd;
37170936Sru
3721573Srgrimes	changed = 0;
37370936Sru
37470936Sru	if ((from_fd = open(from_name, O_RDONLY)) < 0)
37570936Sru		err(EX_OSERR, "moveifchanged open(%s)", from_name);
37670936Sru
37770936Sru	if ((to_fd = open(to_name, O_RDONLY)) < 0)
37870936Sru		changed++;
37970936Sru
38070936Sru	if (!changed && fstat(from_fd, &from_sb) < 0)
38170936Sru		err(EX_OSERR, "moveifchanged fstat(%s)", from_name);
38270936Sru
38370936Sru	if (!changed && fstat(to_fd, &to_sb) < 0)
38470936Sru		err(EX_OSERR, "moveifchanged fstat(%s)", to_name);
38570936Sru
38670936Sru	if (!changed && from_sb.st_size != to_sb.st_size)
38770936Sru		changed++;
38870936Sru
38970936Sru	tsize = (size_t)from_sb.st_size;
3901573Srgrimes
3911573Srgrimes	if (!changed) {
39270936Sru		p = mmap(NULL, tsize, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
393108087Sru#ifndef MAP_FAILED
3941573Srgrimes#define MAP_FAILED ((caddr_t) -1)
39570936Sru#endif
3961573Srgrimes		if (p == MAP_FAILED)
3971573Srgrimes			err(EX_OSERR, "mmap %s", from_name);
39870936Sru		q = mmap(NULL, tsize, PROT_READ, MAP_SHARED, to_fd, (off_t)0);
39970936Sru		if (q == MAP_FAILED)
40070936Sru			err(EX_OSERR, "mmap %s", to_name);
4011573Srgrimes
4021573Srgrimes		changed = memcmp(p, q, tsize);
40370936Sru		munmap(p, tsize);
4041573Srgrimes		munmap(q, tsize);
40570936Sru	}
4061573Srgrimes	if (changed) {
4071573Srgrimes		if (rename(from_name, to_name) < 0)
40870936Sru			err(EX_OSERR, "rename(%s, %s)", from_name, to_name);
4091573Srgrimes	} else {
41070936Sru		if (unlink(from_name) < 0)
41170936Sru			err(EX_OSERR, "unlink(%s)", from_name);
41270936Sru	}
413108087Sru
41470936Sru#ifdef DIAG
41570936Sru	if (changed)
41670936Sru		printf("CHANGED! rename (%s, %s)\n", from_name, to_name);
41770936Sru	else
41870936Sru		printf("SAME! unlink (%s)\n", from_name);
41970936Sru#endif
42070936Sru
42170936Sru	return;
4221573Srgrimes}
4231573Srgrimes