1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-22 07:20:00 +00:00

Added routines to read the canonical UNIX configuration file. This will

later be applied to a number of programs (inetd for instance) to clean
out the bogus code doing the same thing, modulus all the bugs.

If you need to read a '#'-is-a-comment-file, please use these routines.

I realize that the shlib# should be bumped (for the non-US world:
increased by something), but will defer this until something significant
happens.
This commit is contained in:
Poul-Henning Kamp 1994-11-13 20:47:44 +00:00
parent 24ea4a9671
commit 2a7b3781fc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=4441
3 changed files with 267 additions and 4 deletions

View File

@ -1,11 +1,11 @@
# From: @(#)Makefile.inc 8.3 (Berkeley) 4/16/94
# $Id: Makefile.inc,v 1.12 1994/09/25 01:38:27 wollman Exp $
# $Id: Makefile.inc,v 1.13 1994/10/25 14:04:32 bde Exp $
# machine-independent gen sources
.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen
SRCS+= alarm.c assert.c clock.c closedir.c confstr.c crypt.c ctermid.c \
daemon.c devname.c disklabel.c err.c errlst.c \
SRCS+= alarm.c assert.c clock.c closedir.c config.c confstr.c crypt.c \
ctermid.c daemon.c devname.c disklabel.c err.c errlst.c \
exec.c fnmatch.c frexp.c fstab.c fts.c getbootfile.c getbsize.c \
getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \
gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \
@ -36,7 +36,8 @@ errlst.o errlst.po:
rm -f errlst.s
.endif
MAN3+= gen/alarm.3 gen/clock.3 gen/confstr.3 gen/crypt.3 gen/ctermid.3 \
MAN3+= gen/alarm.3 gen/clock.3 gen/confstr.3 gen/config_open.3 \
gen/crypt.3 gen/ctermid.3 \
gen/daemon.3 gen/devname.3 gen/directory.3 gen/err.3 gen/exec.3 \
gen/fnmatch.3 gen/frexp.3 gen/fts.3 gen/getbsize.3 gen/getbootfile.3 \
gen/getcap.3 gen/getcwd.3 gen/getdiskbyname.3 gen/getfsent.3 \
@ -53,6 +54,8 @@ MAN3+= gen/alarm.3 gen/clock.3 gen/confstr.3 gen/crypt.3 gen/ctermid.3 \
gen/times.3 gen/timezone.3 gen/ttyname.3 gen/tzset.3 gen/ualarm.3 \
gen/uname.3 gen/unvis.3 gen/usleep.3 gen/utime.3 gen/valloc.3 gen/vis.3
MLINKS+=config_open.3 config_next.3 config_open.3 config_close.3 \
config_open.3 config_skip.3
MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3
MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \
directory.3 readdir.3 directory.3 rewinddir.3 directory.3 seekdir.3 \

187
lib/libc/gen/config.c Normal file
View File

@ -0,0 +1,187 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $Id$
*
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] = "$Id: config.c,v 1.1 1994/01/14 12:24:39 jkh Exp $";
#endif /* LIBC_SCCS and not lint */
/*
* This file contains four procedures used to read config-files.
*
* char * config_open(const char *filename,int contlines)
* Will open the named file, read it into a private malloc'ed area,
* and close the file again.
* All lines where the first !isspace() char is '#' are deleted.
* If contlines are non-zero lines where the first char is isspace()
* will be joined to the preceeding line.
* In case of trouble the name of the offending system call will be
* returned. On success NULL is returned.
*
* void config_close()
* This will free the internal malloc'ed area.
*
* char * config_next()
* This will return a pointer to the next entry in the area. NULL is
* returned at "end of file". The return value is '\0' terminated, and
* can be modified, but the contents must be copied somewhere else for
* permanent use.
*
* char * config_skip(char **p)
* This will pick out the next word from the string. The return-value
* points to the word found, and *p is advanced past the word. NULL is
* returned at "end of string".
*
* Many programs have a n*100 bytes config-file and N*1000 bytes of source
* to read it. Doing pointer-aerobics on files that small is a waste of
* time, and bashing around with getchar/ungetc isn't much better. These
* routines implement a simple algorithm and syntax.
*
* config_skip consider a contiguous string of !isspace() chars a word.
*
* 13nov1994 Poul-Henning Kamp phk@login.dknet.dk
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
static char *file_buf;
static char *ptr;
char *
config_open(const char *filename, int contlines)
{
int fd;
struct stat st;
char *p, *q;
if ((fd = open(filename, O_RDONLY)) < 0)
return "open";
if (fstat(fd, &st) < 0) {
close(fd);
return "fstat";
}
if (file_buf)
free(file_buf);
file_buf = malloc(st.st_size + 2);
if (!file_buf) {
close(fd);
return "malloc";
}
if (st.st_size != read(fd, file_buf, st.st_size)) {
free(file_buf);
file_buf = (char *) 0;
close(fd);
return "read";
}
close(fd);
file_buf[st.st_size] = '\n';
file_buf[st.st_size + 1] = '\0';
/*
* /^[ \t]*#[^\n]*$/d
*
* Delete all lines where the first !isspace() char is '#'
*/
ptr = file_buf;
for (p = ptr; *p;) {
for (q = p; *q != '\n' && isspace(*q); q++)
continue;
if (*q == '#') {
p = strchr(p, '\n');
if (p)
p++;
} else {
q = strchr(p, '\n');
q++;
memcpy(ptr, p, q - p);
ptr += q - p;
p = q;
}
}
*ptr = '\0';
ptr = file_buf;
if (!contlines)
return 0;
/* Join all lines starting with a isspace() char to the preceeding
* line */
for (p = ptr; *p;) {
q = strchr(p, '\n');
if (isspace(*(q + 1)))
*q = ' ';
p = q + 1;
}
return 0;
}
void
config_close(void)
{
if (file_buf)
free(file_buf);
ptr = file_buf = 0;
}
/*
* Get next entry. config_open did all the weird stuff, so just return
* the next line.
*/
char *
config_next(void)
{
char *p;
/* We might be done already ! */
if (!ptr || !*ptr)
return 0;
while (isspace(*ptr))
ptr++;
p = ptr;
ptr = strchr(p, '\n');
if (ptr) {
*ptr = '\0';
ptr++;
}
return p;
}
/*
* Return next word
*/
char *
config_skip(char **p)
{
char *q, *r;
if (!*p || !**p)
return 0;
for (q = *p; isspace(*q); q++);
if (!*q)
return 0;
for (r = q; *r && !isspace(*r); r++);
if (*r)
*r++ = '\0';
*p = r;
return q;
}

View File

@ -0,0 +1,73 @@
.\" ----------------------------------------------------------------------------
.\" "THE BEER-WARE LICENSE" (Revision 42):
.\" <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
.\" can do whatever you want with this stuff. If we meet some day, and you think
.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
.\" ----------------------------------------------------------------------------
.\"
.\" $Id$
.\"
.Dd November 13, 1994
.Dt config_open 3
.Os FreeBSD
.Sh NAME
.Nm config_open ,
.Nm config_close ,
.Nm config_next ,
.Nm config_skip
.Nd read config files
.Sh SYNOPSIS
.Ft char *
.Fn config_open "const char *filename" "int contlines"
.Ft void
.Fn config_close
.Ft char *
.Fn config_next
.Ft char *
.Fn config_skip "char **string"
.Sh DESCRIPTION
These functions are used to read config files with the following syntax:
.Bl -bullet -compact
.It
All lines where the first
.Sq !isspace()
is '#' are comments which are discarded.
.It
If continuation-lines are enabled, any line starting with a
.Sq isspace()
character is joined to the preceeding line and blank lines are discarded.
.It
An entry starts at the first
.Sq !isspace()
character and ends at the first
.Sq Li \en
.Li .
.El
.Pp
.Fn config_open
will open the specified
.Fa filename
and read it into a private malloced area, and close the file again. If
.Fa contlines
is non-zero, continuation lines will be allowed.
In case of trouble, the name of the system-call causing the trouble will
be returned. If successful,
.Fn config_open
returns NULL.
.Pp
.Fn config_close
will free the malloced area.
.Pp
.Fn config_next
returns the next entry in the area. NULL is returned to indicate End-of-file.
The returned string is null-terminated.
.Pp
.Fn config_skip
returns the next word from the string
.Fa *string
.Li .
.Fa *string
will be advanced to point to the next word.
NULL is returned to indicate the end of the string.
.Sh AUTHOR
Poul-Henning Kamp <phk@login.dknet.dk>