main.c revision 29451
11553Srgrimes/* 21553Srgrimes * Copyright (c) 1980, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 3. All advertising materials mentioning features or use of this software 141553Srgrimes * must display the following acknowledgement: 151553Srgrimes * This product includes software developed by the University of 161553Srgrimes * California, Berkeley and its contributors. 171553Srgrimes * 4. Neither the name of the University nor the names of its contributors 181553Srgrimes * may be used to endorse or promote products derived from this software 191553Srgrimes * without specific prior written permission. 201553Srgrimes * 211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311553Srgrimes * SUCH DAMAGE. 321553Srgrimes */ 331553Srgrimes 341553Srgrimes#ifndef lint 3529451Scharnierstatic const char copyright[] = 361553Srgrimes"@(#) Copyright (c) 1980, 1993\n\ 371553Srgrimes The Regents of the University of California. All rights reserved.\n"; 381553Srgrimes#endif /* not lint */ 391553Srgrimes 401553Srgrimes#ifndef lint 4129451Scharnier#if 0 421553Srgrimesstatic char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; 4329451Scharnier#endif 4429451Scharnierstatic const char rcsid[] = 4529451Scharnier "$Id$"; 461553Srgrimes#endif /* not lint */ 471553Srgrimes 481553Srgrimes#include <sys/types.h> 491553Srgrimes#include <sys/stat.h> 501553Srgrimes#include <sys/file.h> 5113400Speter#include <sys/mman.h> 521553Srgrimes#include <ctype.h> 5313400Speter#include <err.h> 5429451Scharnier#include <stdio.h> 5513400Speter#include <sysexits.h> 5629451Scharnier#include <unistd.h> 5716073Sphk#include "y.tab.h" 581553Srgrimes#include "config.h" 591553Srgrimes 606631Sjkh#ifndef TRUE 616631Sjkh#define TRUE (1) 626631Sjkh#endif 636631Sjkh 646631Sjkh#ifndef FALSE 656631Sjkh#define FALSE (0) 666631Sjkh#endif 676631Sjkh 681553Srgrimesstatic char *PREFIX; 696631Sjkhstatic int no_config_clobber = FALSE; 7012772Speterint old_config_present; 711553Srgrimes 7229451Scharnierstatic void usage __P((void)); 7329451Scharniervoid configfile __P((void)); 7429451Scharnier 751553Srgrimes/* 761553Srgrimes * Config builds a set of files for building a UNIX 771553Srgrimes * system given a description of the desired system. 781553Srgrimes */ 7929451Scharnierint 801553Srgrimesmain(argc, argv) 811553Srgrimes int argc; 821553Srgrimes char **argv; 831553Srgrimes{ 841553Srgrimes 851553Srgrimes struct stat buf; 861553Srgrimes int ch; 871553Srgrimes char *p; 881553Srgrimes 8924428Simp while ((ch = getopt(argc, argv, "gpn")) != -1) 901553Srgrimes switch (ch) { 911553Srgrimes case 'g': 921553Srgrimes debugging++; 931553Srgrimes break; 941553Srgrimes case 'p': 951553Srgrimes profiling++; 961553Srgrimes break; 976631Sjkh case 'n': 986631Sjkh no_config_clobber = TRUE; 996631Sjkh break; 1001553Srgrimes case '?': 1011553Srgrimes default: 10229451Scharnier usage(); 1031553Srgrimes } 1041553Srgrimes argc -= optind; 1051553Srgrimes argv += optind; 1061553Srgrimes 10729451Scharnier if (argc != 1) 10829451Scharnier usage(); 1091553Srgrimes 11029451Scharnier if (freopen(PREFIX = *argv, "r", stdin) == NULL) 11129451Scharnier err(2, "%s", PREFIX); 1126631Sjkh if (getenv("NO_CONFIG_CLOBBER")) 1136631Sjkh no_config_clobber = TRUE; 1146631Sjkh 1152483Sjkh p = path((char *)NULL); 1162483Sjkh if (stat(p, &buf)) { 11729451Scharnier if (mkdir(p, 0777)) 11829451Scharnier err(2, "%s", p); 1191553Srgrimes } 1201553Srgrimes else if ((buf.st_mode & S_IFMT) != S_IFDIR) { 12129451Scharnier errx(2, "%s isn't a directory", p); 1221553Srgrimes } 12312508Swollman#ifndef NO_CLOBBER_EVER 1246631Sjkh else if (!no_config_clobber) { 1252483Sjkh char tmp[strlen(p) + 8]; 1261553Srgrimes 1272483Sjkh fprintf(stderr, "Removing old directory %s: ", p); 1282483Sjkh fflush(stderr); 1292483Sjkh sprintf(tmp, "rm -rf %s", p); 1302483Sjkh if (system(tmp)) { 1312483Sjkh fprintf(stderr, "Failed!\n"); 13229451Scharnier err(2, "%s", tmp); 1332483Sjkh } 1342483Sjkh fprintf(stderr, "Done.\n"); 13529451Scharnier if (mkdir(p, 0777)) 13629451Scharnier err(2, "%s", p); 1372483Sjkh } 13812508Swollman#endif 13912772Speter else 14012772Speter old_config_present++; 14112772Speter 1421566Srgrimes loadaddress = -1; 1431553Srgrimes dtab = NULL; 1441553Srgrimes confp = &conf_list; 1451553Srgrimes compp = &comp_list; 1461553Srgrimes if (yyparse()) 1471553Srgrimes exit(3); 1481553Srgrimes switch (machine) { 1491553Srgrimes 1501553Srgrimes case MACHINE_VAX: 1511553Srgrimes vax_ioconf(); /* Print ioconf.c */ 1521553Srgrimes ubglue(); /* Create ubglue.s */ 1531553Srgrimes break; 1541553Srgrimes 1551553Srgrimes case MACHINE_TAHOE: 1561553Srgrimes tahoe_ioconf(); 1571553Srgrimes vbglue(); 1581553Srgrimes break; 1591553Srgrimes 1601553Srgrimes case MACHINE_HP300: 1611553Srgrimes case MACHINE_LUNA68K: 1621553Srgrimes hp300_ioconf(); 1631553Srgrimes hpglue(); 1641553Srgrimes break; 1651553Srgrimes 1661553Srgrimes case MACHINE_I386: 1671553Srgrimes i386_ioconf(); /* Print ioconf.c */ 1681553Srgrimes vector(); /* Create vector.s */ 1691553Srgrimes break; 1701553Srgrimes 1711553Srgrimes case MACHINE_MIPS: 1721553Srgrimes case MACHINE_PMAX: 1731553Srgrimes pmax_ioconf(); 1741553Srgrimes break; 1751553Srgrimes 1761553Srgrimes case MACHINE_NEWS3400: 1771553Srgrimes news_ioconf(); 1781553Srgrimes break; 1791553Srgrimes 1801553Srgrimes default: 1811553Srgrimes printf("Specify machine type, e.g. ``machine vax''\n"); 1821553Srgrimes exit(1); 1831553Srgrimes } 1841553Srgrimes /* 1851553Srgrimes * make symbolic links in compilation directory 1861553Srgrimes * for "sys" (to make genassym.c work along with #include <sys/xxx>) 1871553Srgrimes * and similarly for "machine". 1881553Srgrimes */ 1891553Srgrimes { 1901553Srgrimes char xxx[80]; 1911553Srgrimes 1921553Srgrimes (void) sprintf(xxx, "../../%s/include", machinename); 1931553Srgrimes (void) symlink(xxx, path("machine")); 1941553Srgrimes } 19512772Speter options(); /* make options .h files */ 1961553Srgrimes makefile(); /* build Makefile */ 1971553Srgrimes headers(); /* make a lot of .h files */ 1981553Srgrimes swapconf(); /* swap config files */ 19916239Sjkh configfile(); /* put config file into kernel*/ 2008248Sjkh printf("Kernel build directory is %s\n", p); 2011553Srgrimes exit(0); 2021553Srgrimes} 2031553Srgrimes 20429451Scharnierstatic void 20529451Scharnierusage() 20629451Scharnier{ 20729451Scharnier fprintf(stderr, "usage: config [-gpn] sysname\n"); 20829451Scharnier exit(1); 20929451Scharnier} 21029451Scharnier 2111553Srgrimes/* 2121553Srgrimes * get_word 2131553Srgrimes * returns EOF on end of file 2141553Srgrimes * NULL on end of line 2151553Srgrimes * pointer to the word otherwise 2161553Srgrimes */ 2171553Srgrimeschar * 2181553Srgrimesget_word(fp) 2191553Srgrimes register FILE *fp; 2201553Srgrimes{ 2211553Srgrimes static char line[80]; 2221553Srgrimes register int ch; 2231553Srgrimes register char *cp; 2244571Sgibbs int escaped_nl = 0; 2251553Srgrimes 2264571Sgibbsbegin: 2271553Srgrimes while ((ch = getc(fp)) != EOF) 2281553Srgrimes if (ch != ' ' && ch != '\t') 2291553Srgrimes break; 2301553Srgrimes if (ch == EOF) 2311553Srgrimes return ((char *)EOF); 2324571Sgibbs if (ch == '\\'){ 2334571Sgibbs escaped_nl = 1; 2344571Sgibbs goto begin; 2354571Sgibbs } 2361553Srgrimes if (ch == '\n') 2374571Sgibbs if (escaped_nl){ 2384571Sgibbs escaped_nl = 0; 2394571Sgibbs goto begin; 2404571Sgibbs } 2414571Sgibbs else 2424571Sgibbs return (NULL); 2431553Srgrimes cp = line; 2441553Srgrimes *cp++ = ch; 2451553Srgrimes while ((ch = getc(fp)) != EOF) { 2461553Srgrimes if (isspace(ch)) 2471553Srgrimes break; 2481553Srgrimes *cp++ = ch; 2491553Srgrimes } 2501553Srgrimes *cp = 0; 2511553Srgrimes if (ch == EOF) 2521553Srgrimes return ((char *)EOF); 2531553Srgrimes (void) ungetc(ch, fp); 2541553Srgrimes return (line); 2551553Srgrimes} 2561553Srgrimes 2571553Srgrimes/* 2581553Srgrimes * get_quoted_word 2591553Srgrimes * like get_word but will accept something in double or single quotes 2601553Srgrimes * (to allow embedded spaces). 2611553Srgrimes */ 2621553Srgrimeschar * 2631553Srgrimesget_quoted_word(fp) 2641553Srgrimes register FILE *fp; 2651553Srgrimes{ 2661553Srgrimes static char line[256]; 2671553Srgrimes register int ch; 2681553Srgrimes register char *cp; 2694571Sgibbs int escaped_nl = 0; 2701553Srgrimes 2714571Sgibbsbegin: 2721553Srgrimes while ((ch = getc(fp)) != EOF) 2731553Srgrimes if (ch != ' ' && ch != '\t') 2741553Srgrimes break; 2751553Srgrimes if (ch == EOF) 2761553Srgrimes return ((char *)EOF); 2774571Sgibbs if (ch == '\\'){ 2784571Sgibbs escaped_nl = 1; 2794571Sgibbs goto begin; 2804571Sgibbs } 2811553Srgrimes if (ch == '\n') 2824571Sgibbs if (escaped_nl){ 2834571Sgibbs escaped_nl = 0; 2844571Sgibbs goto begin; 2854571Sgibbs } 2864571Sgibbs else 2874571Sgibbs return (NULL); 2881553Srgrimes cp = line; 2891553Srgrimes if (ch == '"' || ch == '\'') { 2901553Srgrimes register int quote = ch; 2911553Srgrimes 2921553Srgrimes while ((ch = getc(fp)) != EOF) { 2931553Srgrimes if (ch == quote) 2941553Srgrimes break; 2951553Srgrimes if (ch == '\n') { 2961553Srgrimes *cp = 0; 2971553Srgrimes printf("config: missing quote reading `%s'\n", 2981553Srgrimes line); 2991553Srgrimes exit(2); 3001553Srgrimes } 3011553Srgrimes *cp++ = ch; 3021553Srgrimes } 3031553Srgrimes } else { 3041553Srgrimes *cp++ = ch; 3051553Srgrimes while ((ch = getc(fp)) != EOF) { 3061553Srgrimes if (isspace(ch)) 3071553Srgrimes break; 3081553Srgrimes *cp++ = ch; 3091553Srgrimes } 3101553Srgrimes if (ch != EOF) 3111553Srgrimes (void) ungetc(ch, fp); 3121553Srgrimes } 3131553Srgrimes *cp = 0; 3141553Srgrimes if (ch == EOF) 3151553Srgrimes return ((char *)EOF); 3161553Srgrimes return (line); 3171553Srgrimes} 3181553Srgrimes 3191553Srgrimes/* 3201553Srgrimes * prepend the path to a filename 3211553Srgrimes */ 3221553Srgrimeschar * 3231553Srgrimespath(file) 3241553Srgrimes char *file; 3251553Srgrimes{ 3261553Srgrimes register char *cp; 3271553Srgrimes 3281553Srgrimes#define CDIR "../../compile/" 3291553Srgrimes cp = malloc((unsigned int)(sizeof(CDIR) + strlen(PREFIX) + 3301553Srgrimes (file ? strlen(file) : 0) + 2)); 3311553Srgrimes (void) strcpy(cp, CDIR); 3321553Srgrimes (void) strcat(cp, PREFIX); 3331553Srgrimes if (file) { 3341553Srgrimes (void) strcat(cp, "/"); 3351553Srgrimes (void) strcat(cp, file); 3361553Srgrimes } 3371553Srgrimes return (cp); 3381553Srgrimes} 33913400Speter 34029451Scharniervoid 34116239Sjkhconfigfile() 34216239Sjkh{ 34316239Sjkh FILE *fi, *fo; 34416239Sjkh char *p; 34516239Sjkh int i; 34616239Sjkh 34716239Sjkh fi = fopen(PREFIX,"r"); 34829451Scharnier if(!fi) 34929451Scharnier err(2, "%s", PREFIX); 35020940Speter fo = fopen(p=path("config.c.new"),"w"); 35129451Scharnier if(!fo) 35229451Scharnier err(2, "%s", p); 35320940Speter fprintf(fo,"#include \"opt_config.h\"\n"); 35416239Sjkh fprintf(fo,"#ifdef INCLUDE_CONFIG_FILE \n"); 35516239Sjkh fprintf(fo,"static char *config = \"\n"); 35616239Sjkh fprintf(fo,"START CONFIG FILE %s\n___",PREFIX); 35716239Sjkh while (EOF != (i=getc(fi))) { 35816239Sjkh if(i == '\n') { 35916239Sjkh fprintf(fo,"\n___"); 36016239Sjkh } else if(i == '\"') { 36116239Sjkh fprintf(fo,"\\\""); 36216239Sjkh } else if(i == '\\') { 36316239Sjkh fprintf(fo,"\\\\"); 36416239Sjkh } else { 36516239Sjkh putc(i,fo); 36616239Sjkh } 36716239Sjkh } 36816239Sjkh fprintf(fo,"\nEND CONFIG FILE %s\n",PREFIX); 36916239Sjkh fprintf(fo,"\";\n"); 37020940Speter fprintf(fo,"\n#endif /* INCLUDE_CONFIG_FILE */\n"); 37116239Sjkh fclose(fi); 37216239Sjkh fclose(fo); 37320940Speter moveifchanged(path("config.c.new"), path("config.c")); 37416239Sjkh} 37516239Sjkh 37613400Speter/* 37713400Speter * moveifchanged -- 37813400Speter * compare two files; rename if changed. 37913400Speter */ 38013400Spetervoid 38113400Spetermoveifchanged(const char *from_name, const char *to_name) 38213400Speter{ 38313400Speter char *p, *q; 38413400Speter int changed; 38513400Speter size_t tsize; 38613400Speter struct stat from_sb, to_sb; 38713400Speter int from_fd, to_fd; 38813400Speter 38913400Speter changed = 0; 39013400Speter 39113400Speter if ((from_fd = open(from_name, O_RDONLY)) < 0) 39213400Speter err(EX_OSERR, "moveifchanged open(%s)", from_name); 39313400Speter 39413400Speter if ((to_fd = open(to_name, O_RDONLY)) < 0) 39513400Speter changed++; 39613400Speter 39713400Speter if (!changed && fstat(from_fd, &from_sb) < 0) 39813400Speter err(EX_OSERR, "moveifchanged fstat(%s)", from_name); 39913400Speter 40013400Speter if (!changed && fstat(to_fd, &to_sb) < 0) 40113400Speter err(EX_OSERR, "moveifchanged fstat(%s)", to_name); 40213400Speter 40313400Speter if (!changed && from_sb.st_size != to_sb.st_size) 40413400Speter changed++; 40513400Speter 40613400Speter tsize = (size_t)from_sb.st_size; 40713400Speter 40813400Speter if (!changed) { 40921786Salex p = mmap(NULL, tsize, PROT_READ, MAP_SHARED, from_fd, (off_t)0); 41021786Salex if (p == MAP_FAILED) 41113400Speter err(EX_OSERR, "mmap %s", from_name); 41221786Salex q = mmap(NULL, tsize, PROT_READ, MAP_SHARED, to_fd, (off_t)0); 41321786Salex if (q == MAP_FAILED) 41413400Speter err(EX_OSERR, "mmap %s", to_name); 41513400Speter 41613400Speter changed = memcmp(p, q, tsize); 41713400Speter munmap(p, tsize); 41813400Speter munmap(q, tsize); 41913400Speter } 42013400Speter if (changed) { 42113400Speter if (rename(from_name, to_name) < 0) 42213400Speter err(EX_OSERR, "rename(%s, %s)", from_name, to_name); 42313400Speter } else { 42413400Speter if (unlink(from_name) < 0) 42513400Speter err(EX_OSERR, "unlink(%s, %s)", from_name); 42613400Speter } 42713400Speter 42813400Speter#ifdef DIAG 42913400Speter if (changed) 43013400Speter printf("CHANGED! rename (%s, %s)\n", from_name, to_name); 43113400Speter else 43213400Speter printf("SAME! unlink (%s)\n", from_name); 43313400Speter#endif 43413400Speter 43513400Speter return; 43613400Speter} 437