mg

port of mg editor (openbsd to linux)
Log | Files | Refs | README

commit f3988747cbdeade6f68bc447828c35167b3331ff
parent 92f6c3b8848b8fdabf150ee2bcddb22aa0379b20
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Sat, 22 Nov 2014 00:34:20 +0100

add libutil

Diffstat:
libutil/fparseln.c | 208+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
libutil/util.h | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 331 insertions(+), 0 deletions(-)

diff --git a/libutil/fparseln.c b/libutil/fparseln.c @@ -0,0 +1,208 @@ +/* $OpenBSD: fparseln.c,v 1.7 2012/12/05 23:20:06 deraadt 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. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "util.h" + +static int isescaped(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(const char *sp, const char *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(FILE *fp, size_t *size, size_t *lineno, const char str[3], + int flags) +{ + static const char dstr[3] = { '\\', '\\', '#' }; + char *buf = NULL, *ptr, *cp, esc, con, nl, com; + size_t s, len = 0; + int 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(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/libutil/util.h b/libutil/util.h @@ -0,0 +1,123 @@ +/* $OpenBSD: util.h,v 1.34 2013/06/03 21:07:02 tedu Exp $ */ +/* $NetBSD: util.h,v 1.2 1996/05/16 07:00:22 thorpej Exp $ */ + +/*- + * Copyright (c) 1995 + * The Regents of the University of California. All rights reserved. + * Portions Copyright (c) 1996, Jason Downs. 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. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#include <sys/types.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_BLCK 0x04 /* Open block, not character device. */ + +/* + * uucplock(3) specific flags. + */ +#define UU_LOCK_INUSE (1) +#define UU_LOCK_OK (0) +#define UU_LOCK_OPEN_ERR (-1) +#define UU_LOCK_READ_ERR (-2) +#define UU_LOCK_CREAT_ERR (-3) +#define UU_LOCK_WRITE_ERR (-4) +#define UU_LOCK_LINK_ERR (-5) +#define UU_LOCK_TRY_ERR (-6) +#define UU_LOCK_OWNER_ERR (-7) + +/* + * fmt_scaled(3) specific flags. + */ +#define FMT_SCALED_STRSIZE 7 /* minus sign, 4 digits, suffix, null byte */ + +/* + * stub struct definitions. + */ +struct __sFILE; +struct login_cap; +struct passwd; +struct termios; +struct utmp; +struct winsize; + +__BEGIN_DECLS +char *fparseln(struct __sFILE *, size_t *, size_t *, const char[3], int); +void login(struct utmp *); +int login_tty(int); +int logout(const char *); +void logwtmp(const char *, const char *, const char *); +int opendev(const char *, int, int, char **); +int pidfile(const char *); +void pw_setdir(const char *); +char *pw_file(const char *); +int pw_lock(int); +int pw_mkdb(char *, int); +int pw_abort(void); +void pw_init(void); +void pw_edit(int, const char *); +void pw_prompt(void); +void pw_copy(int, int, const struct passwd *, const struct passwd *); +int pw_scan(char *, struct passwd *, int *); +void pw_error(const char *, int, int); +int openpty(int *, int *, char *, struct termios *, struct winsize *); +int opendisk(const char *, int, char *, size_t, int); +pid_t forkpty(int *, char *, struct termios *, struct winsize *); +int getmaxpartitions(void); +int getrawpartition(void); +void login_fbtab(const char *, uid_t, gid_t); +int login_check_expire(struct __sFILE *, struct passwd *, char *, int); +char *readlabelfs(char *, int); +const char *uu_lockerr(int); +int uu_lock(const char *); +int uu_lock_txfr(const char *, pid_t); +int uu_unlock(const char *); +int fmt_scaled(long long, char *); +int scan_scaled(char *, long long *); +int isduid(const char *, int); +int pkcs5_pbkdf2(const char *, size_t, const uint8_t *, size_t, + uint8_t *, size_t, unsigned int); +int bcrypt_pbkdf(const char *, size_t, const uint8_t *, size_t, + uint8_t *, size_t, unsigned int); + +__END_DECLS + +#endif /* !_UTIL_H_ */