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