mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-24 11:29:10 +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:
parent
24ea4a9671
commit
2a7b3781fc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=4441
@ -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
187
lib/libc/gen/config.c
Normal 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;
|
||||
}
|
73
lib/libc/gen/config_open.3
Normal file
73
lib/libc/gen/config_open.3
Normal 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>
|
Loading…
Reference in New Issue
Block a user