Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/config/main.c
Show First 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | |||||
static void checkversion(void); | static void checkversion(void); | ||||
extern int yyparse(void); | extern int yyparse(void); | ||||
struct hdr_list { | struct hdr_list { | ||||
char *h_name; | char *h_name; | ||||
struct hdr_list *h_next; | struct hdr_list *h_next; | ||||
} *htab; | } *htab; | ||||
static struct sbuf *line_buf = NULL; | |||||
/* | /* | ||||
* Config builds a set of files for building a UNIX | * Config builds a set of files for building a UNIX | ||||
* system given a description of the desired system. | * system given a description of the desired system. | ||||
*/ | */ | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
fprintf(stderr, | fprintf(stderr, | ||||
"usage: config [-CgmpV] [-d destdir] [-s srcdir] sysname\n"); | "usage: config [-CgmpV] [-d destdir] [-s srcdir] sysname\n"); | ||||
fprintf(stderr, " config -x kernel\n"); | fprintf(stderr, " config -x kernel\n"); | ||||
exit(EX_USAGE); | exit(EX_USAGE); | ||||
} | } | ||||
static void | |||||
init_line_buf(void) | |||||
{ | |||||
if (line_buf == NULL) { | |||||
line_buf = sbuf_new(NULL, NULL, 80, SBUF_AUTOEXTEND); | |||||
if (line_buf == NULL) { | |||||
errx(EXIT_FAILURE, "failed to allocate line buffer"); | |||||
} | |||||
} else { | |||||
sbuf_clear(line_buf); | |||||
} | |||||
} | |||||
static char * | |||||
get_line_buf(void) | |||||
{ | |||||
if (sbuf_finish(line_buf) != 0) { | |||||
errx(EXIT_FAILURE, "failed to generate line buffer, " | |||||
"partial line = %s", sbuf_data(line_buf)); | |||||
} | |||||
return sbuf_data(line_buf); | |||||
} | |||||
/* | /* | ||||
* get_word | * get_word | ||||
* returns EOF on end of file | * returns EOF on end of file | ||||
* NULL on end of line | * NULL on end of line | ||||
* pointer to the word otherwise | * pointer to the word otherwise | ||||
*/ | */ | ||||
char * | char * | ||||
get_word(FILE *fp) | get_word(FILE *fp) | ||||
{ | { | ||||
static char line[160]; | |||||
int ch; | int ch; | ||||
char *cp; | |||||
int escaped_nl = 0; | int escaped_nl = 0; | ||||
init_line_buf(); | |||||
begin: | begin: | ||||
while ((ch = getc(fp)) != EOF) | while ((ch = getc(fp)) != EOF) | ||||
if (ch != ' ' && ch != '\t') | if (ch != ' ' && ch != '\t') | ||||
break; | break; | ||||
if (ch == EOF) | if (ch == EOF) | ||||
return ((char *)EOF); | return ((char *)EOF); | ||||
if (ch == '\\'){ | if (ch == '\\'){ | ||||
escaped_nl = 1; | escaped_nl = 1; | ||||
goto begin; | goto begin; | ||||
} | } | ||||
if (ch == '\n') { | if (ch == '\n') { | ||||
if (escaped_nl){ | if (escaped_nl){ | ||||
escaped_nl = 0; | escaped_nl = 0; | ||||
goto begin; | goto begin; | ||||
} | } | ||||
else | else | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
cp = line; | sbuf_putc(line_buf, ch); | ||||
*cp++ = ch; | |||||
/* Negation operator is a word by itself. */ | /* Negation operator is a word by itself. */ | ||||
if (ch == '!') { | if (ch == '!') { | ||||
*cp = 0; | return get_line_buf(); | ||||
return (line); | |||||
} | } | ||||
while ((ch = getc(fp)) != EOF && cp < line + sizeof(line)) { | while ((ch = getc(fp)) != EOF) { | ||||
if (isspace(ch)) | if (isspace(ch)) | ||||
break; | break; | ||||
*cp++ = ch; | sbuf_putc(line_buf, ch); | ||||
} | } | ||||
if (cp >= line + sizeof(line)) { | |||||
line[sizeof(line) - 1] = '\0'; | |||||
fprintf(stderr, "config: attempted overflow, partial line: `%s'", | |||||
line); | |||||
exit(2); | |||||
} | |||||
*cp = 0; | |||||
if (ch == EOF) | if (ch == EOF) | ||||
return ((char *)EOF); | return ((char *)EOF); | ||||
(void) ungetc(ch, fp); | (void) ungetc(ch, fp); | ||||
return (line); | return (get_line_buf()); | ||||
} | } | ||||
/* | /* | ||||
* get_quoted_word | * get_quoted_word | ||||
* like get_word but will accept something in double or single quotes | * like get_word but will accept something in double or single quotes | ||||
* (to allow embedded spaces). | * (to allow embedded spaces). | ||||
*/ | */ | ||||
char * | char * | ||||
get_quoted_word(FILE *fp) | get_quoted_word(FILE *fp) | ||||
{ | { | ||||
static char line[512]; | |||||
int ch; | int ch; | ||||
char *cp; | |||||
int escaped_nl = 0; | int escaped_nl = 0; | ||||
init_line_buf(); | |||||
begin: | begin: | ||||
while ((ch = getc(fp)) != EOF) | while ((ch = getc(fp)) != EOF) | ||||
if (ch != ' ' && ch != '\t') | if (ch != ' ' && ch != '\t') | ||||
break; | break; | ||||
if (ch == EOF) | if (ch == EOF) | ||||
return ((char *)EOF); | return ((char *)EOF); | ||||
if (ch == '\\'){ | if (ch == '\\'){ | ||||
escaped_nl = 1; | escaped_nl = 1; | ||||
goto begin; | goto begin; | ||||
} | } | ||||
if (ch == '\n') { | if (ch == '\n') { | ||||
if (escaped_nl){ | if (escaped_nl){ | ||||
escaped_nl = 0; | escaped_nl = 0; | ||||
goto begin; | goto begin; | ||||
} | } | ||||
else | else | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
cp = line; | |||||
if (ch == '"' || ch == '\'') { | if (ch == '"' || ch == '\'') { | ||||
int quote = ch; | int quote = ch; | ||||
escaped_nl = 0; | escaped_nl = 0; | ||||
while ((ch = getc(fp)) != EOF) { | while ((ch = getc(fp)) != EOF) { | ||||
if (ch == quote && !escaped_nl) | if (ch == quote && !escaped_nl) | ||||
break; | break; | ||||
if (ch == '\n' && !escaped_nl) { | if (ch == '\n' && !escaped_nl) { | ||||
*cp = 0; | |||||
printf("config: missing quote reading `%s'\n", | printf("config: missing quote reading `%s'\n", | ||||
line); | get_line_buf()); | ||||
exit(2); | exit(2); | ||||
} | } | ||||
if (ch == '\\' && !escaped_nl) { | if (ch == '\\' && !escaped_nl) { | ||||
escaped_nl = 1; | escaped_nl = 1; | ||||
continue; | continue; | ||||
} | } | ||||
if (ch != quote && escaped_nl) | if (ch != quote && escaped_nl) | ||||
*cp++ = '\\'; | sbuf_putc(line_buf, '\\'); | ||||
if (cp >= line + sizeof(line)) { | sbuf_putc(line_buf, ch); | ||||
line[sizeof(line) - 1] = '\0'; | |||||
printf( | |||||
"config: line buffer overflow reading partial line `%s'\n", | |||||
line); | |||||
exit(2); | |||||
} | |||||
*cp++ = ch; | |||||
escaped_nl = 0; | escaped_nl = 0; | ||||
} | } | ||||
} else { | } else { | ||||
*cp++ = ch; | sbuf_putc(line_buf, ch); | ||||
while ((ch = getc(fp)) != EOF && cp < line + sizeof(line)) { | while ((ch = getc(fp)) != EOF) { | ||||
if (isspace(ch)) | if (isspace(ch)) | ||||
break; | break; | ||||
*cp++ = ch; | sbuf_putc(line_buf, ch); | ||||
} | } | ||||
if (cp >= line + sizeof(line)) { | |||||
line[sizeof(line) - 1] = '\0'; | |||||
printf( | |||||
"config: line buffer overflow reading partial line `%s'\n", | |||||
line); | |||||
exit(2); | |||||
} | |||||
if (ch != EOF) | if (ch != EOF) | ||||
(void) ungetc(ch, fp); | (void) ungetc(ch, fp); | ||||
} | } | ||||
*cp = 0; | |||||
if (ch == EOF) | if (ch == EOF) | ||||
return ((char *)EOF); | return ((char *)EOF); | ||||
return (line); | return (get_line_buf()); | ||||
} | } | ||||
/* | /* | ||||
* prepend the path to a filename | * prepend the path to a filename | ||||
*/ | */ | ||||
char * | char * | ||||
path(const char *file) | path(const char *file) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 360 Lines • Show Last 20 Lines |