config(8): use sbuf to manage line buffers

PR:	245476
Reported by:	kevans
Reviewed by:	imp, kevans
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D24373
This commit is contained in:
Jason A. Harmening 2020-04-12 02:42:42 +00:00
parent e3e7c612f3
commit 31de6cad17
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=359815

View File

@ -113,6 +113,8 @@ struct hdr_list {
struct hdr_list *h_next;
} *htab;
static struct sbuf *line_buf = NULL;
/*
* Config builds a set of files for building a UNIX
* system given a description of the desired system.
@ -313,6 +315,29 @@ usage(void)
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
* returns EOF on end of file
@ -322,11 +347,10 @@ usage(void)
char *
get_word(FILE *fp)
{
static char line[160];
int ch;
char *cp;
int escaped_nl = 0;
init_line_buf();
begin:
while ((ch = getc(fp)) != EOF)
if (ch != ' ' && ch != '\t')
@ -345,29 +369,20 @@ get_word(FILE *fp)
else
return (NULL);
}
cp = line;
*cp++ = ch;
sbuf_putc(line_buf, ch);
/* Negation operator is a word by itself. */
if (ch == '!') {
*cp = 0;
return (line);
return get_line_buf();
}
while ((ch = getc(fp)) != EOF && cp < line + sizeof(line)) {
while ((ch = getc(fp)) != EOF) {
if (isspace(ch))
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)
return ((char *)EOF);
(void) ungetc(ch, fp);
return (line);
return (get_line_buf());
}
/*
@ -378,11 +393,10 @@ get_word(FILE *fp)
char *
get_quoted_word(FILE *fp)
{
static char line[512];
int ch;
char *cp;
int escaped_nl = 0;
init_line_buf();
begin:
while ((ch = getc(fp)) != EOF)
if (ch != ' ' && ch != '\t')
@ -401,7 +415,6 @@ get_quoted_word(FILE *fp)
else
return (NULL);
}
cp = line;
if (ch == '"' || ch == '\'') {
int quote = ch;
@ -410,9 +423,8 @@ get_quoted_word(FILE *fp)
if (ch == quote && !escaped_nl)
break;
if (ch == '\n' && !escaped_nl) {
*cp = 0;
printf("config: missing quote reading `%s'\n",
line);
get_line_buf());
exit(2);
}
if (ch == '\\' && !escaped_nl) {
@ -420,38 +432,23 @@ get_quoted_word(FILE *fp)
continue;
}
if (ch != quote && escaped_nl)
*cp++ = '\\';
if (cp >= line + sizeof(line)) {
line[sizeof(line) - 1] = '\0';
printf(
"config: line buffer overflow reading partial line `%s'\n",
line);
exit(2);
}
*cp++ = ch;
sbuf_putc(line_buf, '\\');
sbuf_putc(line_buf, ch);
escaped_nl = 0;
}
} else {
*cp++ = ch;
while ((ch = getc(fp)) != EOF && cp < line + sizeof(line)) {
sbuf_putc(line_buf, ch);
while ((ch = getc(fp)) != EOF) {
if (isspace(ch))
break;
*cp++ = ch;
}
if (cp >= line + sizeof(line)) {
line[sizeof(line) - 1] = '\0';
printf(
"config: line buffer overflow reading partial line `%s'\n",
line);
exit(2);
sbuf_putc(line_buf, ch);
}
if (ch != EOF)
(void) ungetc(ch, fp);
}
*cp = 0;
if (ch == EOF)
return ((char *)EOF);
return (line);
return (get_line_buf());
}
/*