From f15aa3a552022743398a652165d76bf912c715e5 Mon Sep 17 00:00:00 2001 From: Guillaume Cottenceau Date: Mon, 14 May 2001 13:47:49 +0000 Subject: Initial revision --- mdk-stage1/dietlibc/libcruft/entlib.c | 153 ++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 mdk-stage1/dietlibc/libcruft/entlib.c (limited to 'mdk-stage1/dietlibc/libcruft/entlib.c') diff --git a/mdk-stage1/dietlibc/libcruft/entlib.c b/mdk-stage1/dietlibc/libcruft/entlib.c new file mode 100644 index 000000000..f88b3f057 --- /dev/null +++ b/mdk-stage1/dietlibc/libcruft/entlib.c @@ -0,0 +1,153 @@ +/* + * dietlibc/lib/entlib.c - Generic delimited-line parsing library + * + * Copyright 2001 Jeff Garzik + * + * This is a brand new implementation, based on the interface + * described in man-pages-1.34-1mdk man pages package. + */ + + +#include "entlib.h" /* this is our only include */ + + +/* + * __ent_start + * + * Allocates and zeroes the module's state structure, + * and open a handle to /etc/passwd. + * + * Returns -1 on failure and sets errno, or zero for success. + */ + +int __ent_start(const char *pathname, struct __ent_state **st_ref) +{ + struct __ent_state *st; + + if (*st_ref) + return 0; + + st = calloc(1, sizeof(*st)); + if (!st) { + errno = ENOMEM; + return -1; + } + + st->fd = open(pathname, O_RDONLY); + if (st->fd == -1) { + /* errno should have been set by open(2) */ + free(st); + st = NULL; + return -1; + } + + *st_ref = st; + return 0; +} + + +/* + * __ent_get_line + * + * Eliminates a previous line from the buffer, if any. + * Then reads in a new line from /etc/passwd, if necessary. + * + * Returns -1 on failure, or zero for success. + */ + +int __ent_get_line(struct __ent_state *st) +{ + int rc; + + /* overwrite previous line, by shifting the rest + * of the rest to the front of the buffer + */ + if (st->bufptr) { + unsigned int slop = st->buflen - st->bufptr; + memmove(st->ent_buf, &st->ent_buf[st->bufptr], slop); + st->bufptr = 0; + st->buflen = slop; + st->ent_buf[st->buflen] = 0; /* null terminate */ + } + + if (st->buflen == __ENT_BUFSIZ || strchr(st->ent_buf, '\n')) + return 0; + + rc = read(st->fd, &st->ent_buf[st->buflen], __ENT_BUFSIZ - st->buflen); + if (rc < 0) + return -1; + + st->buflen += rc; + if (st->buflen == 0) + return -1; + + return 0; +} + + +/* + * __ent_split + * + * Splits a string into parts based on a delimiter. + * Stops processing when \n is reached also. + * + * Returns -1 on failure, or zero on success. + */ + +int __ent_split(struct __ent_state *st, char **parts, + int n_parts, int delimiter, int require_exact) +{ + char *s = &st->ent_buf[st->bufptr]; + int idx = 0; + + /* empty list */ + if (!*s) { + if (!require_exact) + return 0; + return -1; + } + + /* scan through string, sticking string pointers + * into parts[] as delimiters are found + */ + parts[idx++] = s; + while (*s) { + st->bufptr++; + if (*s == '\n') { + *s = 0; /* null terminate */ + break; + } + if (*s == delimiter) { + *s = 0; /* null terminate */ + /* boundary error: too many delimiters */ + if (idx == n_parts) + return -1; + s++; + parts[idx++] = s; + } else { + s++; + } + } + + if (!require_exact) + return 0; + return (n_parts == idx) ? 0 : -1; +} + + +void __ent_set(struct __ent_state *st) +{ + if (!st) + return; + st->buflen = st->bufptr = 0; + lseek(st->fd, 0, SEEK_SET); +} + + +void __ent_end(struct __ent_state *st) +{ + if (!st) + return; + close(st->fd); + free(st); +} -- cgit v1.2.1