summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Schlyter <jakob@cvs.openbsd.org>1999-07-20 16:38:58 +0000
committerJakob Schlyter <jakob@cvs.openbsd.org>1999-07-20 16:38:58 +0000
commit31da66718389de8efc626064406ffc36b093517d (patch)
treed5e03fa03dee95c6c52eda77641403d9007b4f6c
parent85273159e99f5a6dde00812182cd445ede601017 (diff)
Added fparseln from NetBSD.
ok deraadt@
-rw-r--r--lib/libutil/Makefile7
-rw-r--r--lib/libutil/fparseln.3143
-rw-r--r--lib/libutil/fparseln.c225
-rw-r--r--lib/libutil/shlib_version2
-rw-r--r--lib/libutil/util.h13
5 files changed, 385 insertions, 5 deletions
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index cb39be8829f..2c6cf13d1b9 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.16 1998/06/08 20:28:23 brian Exp $
+# $OpenBSD: Makefile,v 1.17 1999/07/20 16:38:56 jakob Exp $
# $NetBSD: Makefile,v 1.8 1996/05/16 07:03:28 thorpej Exp $
LIB= util
@@ -7,11 +7,12 @@ CFLAGS+=-DLIBC_SCCS
HDRS= util.h scsi.h
SRCS= getmaxpartitions.c getrawpartition.c login.c login_tty.c logout.c \
logwtmp.c opendev.c passwd.c pty.c readlabel.c scsi.c login_fbtab.c \
- uucplock.c
+ uucplock.c fparseln.c
# XXX need login_fbtab.3
MAN= getmaxpartitions.3 getrawpartition.3 login.3 opendev.3 openpty.3 \
- pw_init.3 pw_lock.3 readlabelfs.3 scsi.3 pw_getconf.3 uucplock.3
+ pw_init.3 pw_lock.3 readlabelfs.3 scsi.3 pw_getconf.3 uucplock.3 \
+ fparseln.3
MLINKS+=login.3 logout.3
MLINKS+=login.3 logwtmp.3
diff --git a/lib/libutil/fparseln.3 b/lib/libutil/fparseln.3
new file mode 100644
index 00000000000..a8853341747
--- /dev/null
+++ b/lib/libutil/fparseln.3
@@ -0,0 +1,143 @@
+.\" $OpenBSD: fparseln.3,v 1.1 1999/07/20 16:38:56 jakob Exp $
+.\" $NetBSD: fparseln.3,v 1.7 1999/07/02 15:49:12 simonb Exp $
+.\"
+.\" Copyright (c) 1997 Christos Zoulas. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Christos Zoulas.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd December 1, 1997
+.Dt FPARSELN 3
+.Os
+.Sh NAME
+.Nm fparseln
+.Nd return the next logical line from a stream
+.Sh SYNOPSIS
+.Fd #include <util.h>
+.Ft "char *"
+.Fo "fparseln"
+.Fa "FILE *stream" "size_t *len" "size_t *lineno"
+.Fa "const char delim[3]" "int flags"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn fparseln
+function
+returns a pointer to the next logical line from the stream referenced by
+.Fa stream .
+This string is null terminated and it is dynamicaly allocated on each
+invocation. It is the responsibility of the caller to free the pointer.
+.Pp
+By default, if a character is escaped, both it and the preceeding escape
+character will be present in the returned string.
+Various
+.Fa flags
+alter this behaviour.
+.Pp
+The meaning of the arguments is as follows:
+.Bl -tag -width "lineno"
+.It Fa stream
+The stream to read from.
+.It Fa len
+If not
+.Dv NULL ,
+the length of the string is stored in the memory location to which it
+points.
+.It Fa lineno
+If not
+.Dv NULL ,
+the value of the memory location to which is pointed to, is incremented
+by the number of lines actually read from the file.
+.It Fa delim
+Contains the escape, continuation, and comment characters.
+If a character is
+.Dv NUL
+then processing for that character is disabled.
+If
+.Dv NULL ,
+all characters default to values specified below.
+The contents of
+.Fa delim
+is as follows:
+.Bl -tag -width "delim[0]"
+.It Fa delim[0]
+The escape character, which defaults to
+.Ql \e ,
+is used to remove any special meaning from the next character.
+.It Fa delim[1]
+The continuation character, which defaults to
+.Ql \e ,
+is used to indicate that the next line should be concatenated with the
+current one if this character is the last character on the current line
+and is not escaped.
+.It Fa delim[2]
+The comment character, which defaults to
+.Ql # ,
+if not escaped indicates the beginning of a comment that extends until the
+end of the current line.
+.El
+.It Fa flags
+If non-zero, alter the operation of
+.Fn fparseln .
+The various flags, which may be
+.Tn OR Ns 'ed
+together, are:
+.Bl -tag -width "FPARSELN_UNESCCOMM"
+.It Dv FPARSELN_UNESCCOMM
+Remove escape preceeding an escaped comment.
+.It Dv FPARSELN_UNESCCONT
+Remove escape preceeding an escaped continuation.
+.It Dv FPARSELN_UNESCESC
+Remove escape preceeding an escaped escape.
+.It Dv FPARSELN_UNESCREST
+Remove escape preceeding any other character.
+.It Dv FPARSELN_UNESCALL
+All of the above.
+.El
+.Sh RETURN VALUES
+Upon successful completion a pointer to the parsed line is returned;
+otherwise,
+.Dv NULL
+is returned.
+.Pp
+The
+.Fn fparseln
+function uses internally
+.Xr fgetln 3 ,
+so all error conditions that apply to
+.Xr fgetln 3 ,
+apply to
+.Fn fparseln .
+In addition
+.Fn fparseln
+may set
+.Va errno
+to
+.Er ENOMEM
+and return
+.Dv NULL
+if it runs out of memory.
+.Sh SEE ALSO
+.Xr fgetln 3
diff --git a/lib/libutil/fparseln.c b/lib/libutil/fparseln.c
new file mode 100644
index 00000000000..e09ce8fb9a6
--- /dev/null
+++ b/lib/libutil/fparseln.c
@@ -0,0 +1,225 @@
+/* $OpenBSD: fparseln.c,v 1.1 1999/07/20 16:38:56 jakob Exp $
+/* $NetBSD: fparseln.c,v 1.7 1999/07/02 15:49:12 simonb Exp $ */
+
+/*
+ * Copyright (c) 1997 Christos Zoulas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: fparseln.c,v 1.1 1999/07/20 16:38:56 jakob Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/cdefs.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <util.h>
+
+static int isescaped __P((const char *, const char *, int));
+
+/* isescaped():
+ * Return true if the character in *p that belongs to a string
+ * that starts in *sp, is escaped by the escape character esc.
+ */
+static int
+isescaped(sp, p, esc)
+ const char *sp, *p;
+ int esc;
+{
+ const char *cp;
+ size_t ne;
+
+ /* No escape character */
+ if (esc == '\0')
+ return 1;
+
+ /* Count the number of escape characters that precede ours */
+ for (ne = 0, cp = p; --cp >= sp && *cp == esc; ne++)
+ continue;
+
+ /* Return true if odd number of escape characters */
+ return (ne & 1) != 0;
+}
+
+
+/* fparseln():
+ * Read a line from a file parsing continuations ending in \
+ * and eliminating trailing newlines, or comments starting with
+ * the comment char.
+ */
+char *
+fparseln(fp, size, lineno, str, flags)
+ FILE *fp;
+ size_t *size;
+ size_t *lineno;
+ const char str[3];
+ int flags;
+{
+ static const char dstr[3] = { '\\', '\\', '#' };
+
+ size_t s, len;
+ char *buf;
+ char *ptr, *cp;
+ int cnt;
+ char esc, con, nl, com;
+
+ len = 0;
+ buf = NULL;
+ cnt = 1;
+
+ if (str == NULL)
+ str = dstr;
+
+ esc = str[0];
+ con = str[1];
+ com = str[2];
+ /*
+ * XXX: it would be cool to be able to specify the newline character,
+ * but unfortunately, fgetln does not let us
+ */
+ nl = '\n';
+
+ while (cnt) {
+ cnt = 0;
+
+ if (lineno)
+ (*lineno)++;
+
+ if ((ptr = fgetln(fp, &s)) == NULL)
+ break;
+
+ if (s && com) { /* Check and eliminate comments */
+ for (cp = ptr; cp < ptr + s; cp++)
+ if (*cp == com && !isescaped(ptr, cp, esc)) {
+ s = cp - ptr;
+ cnt = s == 0 && buf == NULL;
+ break;
+ }
+ }
+
+ if (s && nl) { /* Check and eliminate newlines */
+ cp = &ptr[s - 1];
+
+ if (*cp == nl)
+ s--; /* forget newline */
+ }
+
+ if (s && con) { /* Check and eliminate continuations */
+ cp = &ptr[s - 1];
+
+ if (*cp == con && !isescaped(ptr, cp, esc)) {
+ s--; /* forget escape */
+ cnt = 1;
+ }
+ }
+
+ if (s == 0 && buf != NULL)
+ continue;
+
+ if ((cp = realloc(buf, len + s + 1)) == NULL) {
+ free(buf);
+ return NULL;
+ }
+ buf = cp;
+
+ (void) memcpy(buf + len, ptr, s);
+ len += s;
+ buf[len] = '\0';
+ }
+
+ if ((flags & FPARSELN_UNESCALL) != 0 && esc && buf != NULL &&
+ strchr(buf, esc) != NULL) {
+ ptr = cp = buf;
+ while (cp[0] != '\0') {
+ int skipesc;
+
+ while (cp[0] != '\0' && cp[0] != esc)
+ *ptr++ = *cp++;
+ if (cp[0] == '\0' || cp[1] == '\0')
+ break;
+
+ skipesc = 0;
+ if (cp[1] == com)
+ skipesc += (flags & FPARSELN_UNESCCOMM);
+ if (cp[1] == con)
+ skipesc += (flags & FPARSELN_UNESCCONT);
+ if (cp[1] == esc)
+ skipesc += (flags & FPARSELN_UNESCESC);
+ if (cp[1] != com && cp[1] != con && cp[1] != esc)
+ skipesc = (flags & FPARSELN_UNESCREST);
+
+ if (skipesc)
+ cp++;
+ else
+ *ptr++ = *cp++;
+ *ptr++ = *cp++;
+ }
+ *ptr = '\0';
+ len = strlen(buf);
+ }
+
+ if (size)
+ *size = len;
+ return buf;
+}
+
+#ifdef TEST
+
+int main __P((int, char **));
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *ptr;
+ size_t size, line;
+
+ line = 0;
+ while ((ptr = fparseln(stdin, &size, &line, NULL,
+ FPARSELN_UNESCALL)) != NULL)
+ printf("line %d (%d) |%s|\n", line, size, ptr);
+ return 0;
+}
+
+/*
+
+# This is a test
+line 1
+line 2 \
+line 3 # Comment
+line 4 \# Not comment \\\\
+
+# And a comment \
+line 5 \\\
+line 6
+
+*/
+
+#endif /* TEST */
diff --git a/lib/libutil/shlib_version b/lib/libutil/shlib_version
index f89dbabf714..cd1b568c0bb 100644
--- a/lib/libutil/shlib_version
+++ b/lib/libutil/shlib_version
@@ -1,2 +1,2 @@
major=4
-minor=2
+minor=3
diff --git a/lib/libutil/util.h b/lib/libutil/util.h
index 3f40ce91d0f..dba5e6f0509 100644
--- a/lib/libutil/util.h
+++ b/lib/libutil/util.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.h,v 1.8 1998/06/08 20:28:28 brian Exp $ */
+/* $OpenBSD: util.h,v 1.9 1999/07/20 16:38:57 jakob Exp $ */
/* $NetBSD: util.h,v 1.2 1996/05/16 07:00:22 thorpej Exp $ */
/*-
@@ -38,6 +38,7 @@
#ifndef _UTIL_H_
#define _UTIL_H_
+#include <stdio.h>
#include <pwd.h>
#include <utmp.h>
#include <termios.h>
@@ -46,12 +47,22 @@
#include <sys/cdefs.h>
/*
+ * fparseln() specific operation flags.
+ */
+#define FPARSELN_UNESCESC 0x01
+#define FPARSELN_UNESCCONT 0x02
+#define FPARSELN_UNESCCOMM 0x04
+#define FPARSELN_UNESCREST 0x08
+#define FPARSELN_UNESCALL 0x0f
+
+/*
* opendev() specific operation flags.
*/
#define OPENDEV_PART 0x01 /* Try to open the raw partition. */
#define OPENDEV_DRCT 0x02 /* Try to open the device directly. */
__BEGIN_DECLS
+char *fparseln __P((FILE *, size_t *, size_t *, const char[3], int));
void login __P((struct utmp *));
int login_tty __P((int));
int logout __P((const char *));