aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>1994-11-13 20:47:44 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>1994-11-13 20:47:44 +0000
commit2a7b3781fcc3f3db0c437533ba1a1f5b558e24fb (patch)
treebd9820d8413cdad8edf72373c8bb3288b32d8953 /lib
parent24ea4a96716695ed8828f91e40e0ac920c736fe3 (diff)
downloadsrc-2a7b3781fcc3f3db0c437533ba1a1f5b558e24fb.tar.gz
src-2a7b3781fcc3f3db0c437533ba1a1f5b558e24fb.zip
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.
Notes
Notes: svn path=/head/; revision=4441
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/Makefile.inc11
-rw-r--r--lib/libc/gen/config.c187
-rw-r--r--lib/libc/gen/config_open.373
3 files changed, 267 insertions, 4 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index e307157bad42..c9cf4e7656a8 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -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 \
diff --git a/lib/libc/gen/config.c b/lib/libc/gen/config.c
new file mode 100644
index 000000000000..6ea292b78b13
--- /dev/null
+++ b/lib/libc/gen/config.c
@@ -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;
+}
diff --git a/lib/libc/gen/config_open.3 b/lib/libc/gen/config_open.3
new file mode 100644
index 000000000000..f51bc6cd01f8
--- /dev/null
+++ b/lib/libc/gen/config_open.3
@@ -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>