Index: stable/4/lib/libutil/libutil.h =================================================================== --- stable/4/lib/libutil/libutil.h (revision 69019) +++ stable/4/lib/libutil/libutil.h (revision 69020) @@ -1,98 +1,101 @@ /* * Copyright (c) 1996 Peter Wemm . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * $FreeBSD$ */ #ifndef _LIBUTIL_H_ #define _LIBUTIL_H_ #include +#define PROPERTY_MAX_NAME 64 +#define PROPERTY_MAX_VALUE 512 + /* for properties.c */ typedef struct _property { struct _property *next; char *name; char *value; } *properties; /* Avoid pulling in all the include files for no need */ struct termios; struct winsize; struct utmp; struct in_addr; __BEGIN_DECLS void login __P((struct utmp *_ut)); int login_tty __P((int _fd)); int logout __P((const char *_line)); void logwtmp __P((const char *_line, const char *_name, const char *_host)); void trimdomain __P((char *_fullhost, int _hostsize)); int openpty __P((int *_amaster, int *_aslave, char *_name, struct termios *_termp, struct winsize *_winp)); int forkpty __P((int *_amaster, char *_name, struct termios *_termp, struct winsize *_winp)); const char *uu_lockerr __P((int _uu_lockresult)); int uu_lock __P((const char *_ttyname)); int uu_unlock __P((const char *_ttyname)); int uu_lock_txfr __P((const char *_ttyname, pid_t _pid)); int _secure_path __P((const char *_path, uid_t _uid, gid_t _gid)); properties properties_read __P((int fd)); void properties_free __P((properties list)); char *property_find __P((properties list, const char *name)); char *auth_getval __P((const char *name)); int realhostname __P((char *host, size_t hsize, const struct in_addr *ip)); struct sockaddr; int realhostname_sa __P((char *host, size_t hsize, struct sockaddr *addr, int addrlen)); #ifdef _STDIO_H_ /* avoid adding new includes */ char *fparseln __P((FILE *, size_t *, size_t *, const char[3], int)); #endif __END_DECLS #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) /* return values from realhostname() */ #define HOSTNAME_FOUND (0) #define HOSTNAME_INCORRECTNAME (1) #define HOSTNAME_INVALIDADDR (2) #define HOSTNAME_INVALIDNAME (3) /* fparseln(3) */ #define FPARSELN_UNESCESC 0x01 #define FPARSELN_UNESCCONT 0x02 #define FPARSELN_UNESCCOMM 0x04 #define FPARSELN_UNESCREST 0x08 #define FPARSELN_UNESCALL 0x0f #endif /* !_LIBUTIL_H_ */ Index: stable/4/lib/libutil/property.3 =================================================================== --- stable/4/lib/libutil/property.3 (revision 69019) +++ stable/4/lib/libutil/property.3 (revision 69020) @@ -1,93 +1,95 @@ .\" .\" Copyright (c) 1998 Jordan Hubbard .\" .\" 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. .\" .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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. .\" .\" $FreeBSD$ .\" " .Dd October 7, 1998 .Os .Dt PROPERTIES 3 .Sh NAME .Nm properties_read , .Nm propery_find , .Nm properties_free .Nd "functions to allow creating simple property lists from ASCII file data" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .Fd #include .Fd #include .Ft properties .Fn properties_read "int fd" .Ft char * .Fn property_find "properties list" "const char *name" .Ft void .Fn properties_free "properties list" .Sh DESCRIPTION .nf typedef struct _properties { struct _properties *next; char *name; char *value; } *properties; .fi The function .Fn properties_read reads .Fa name = value pairs from the file descriptor passed in .Fa fd and returns the head of a new property list, assuming that the file's contents have been parsed properly, or NULL in case of error. .Pp .Fn property_find Returns the associated value string for the property named .Fa name -if found, otherwise NULL. +if found, otherwise NULL. The value returned may be up to +.Dv PROPERTY_MAX_VALUE +bytes in length. .Pp .Fn properties_free is used to free the structure returned by .Fn properties_read when it is no longer needed. .Pp .Sh FILE FORMAT Each property in the file is assumed to have the format of .Fa name = value where .Fa name is an alphanumeric string (and any punctuation not including the `=' character) and .Fa value is an arbitary string of text terminated by a newline character. If newlines are desired, the entire value should be enclosed in { } (curly-bracket) characters. Any line beginning with a # or ; character is assumed to be a comment and will be ignored. .Sh SEE ALSO .Xr auth_getval 3 .Sh BUGS Simplistic. .Sh AUTHORS .An Jordan Hubbard Index: stable/4/lib/libutil/property.c =================================================================== --- stable/4/lib/libutil/property.c (revision 69019) +++ stable/4/lib/libutil/property.c (revision 69020) @@ -1,224 +1,228 @@ /* * * Simple property list handling code. * * Copyright (c) 1998 * Jordan Hubbard. 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, * verbatim and that no modifications are made prior to this * point in the file. * 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. * * 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 OR HIS PETS 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, LIFE 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. * + * $FreeBSD$ + * */ #include #include #include #include #include #include #include #include -#define MAX_NAME 64 -#define MAX_VALUE 512 - static properties property_alloc(char *name, char *value) { properties n; n = (properties)malloc(sizeof(struct _property)); n->next = NULL; n->name = name ? strdup(name) : NULL; n->value = value ? strdup(value) : NULL; return n; } properties properties_read(int fd) { properties head, ptr; - char hold_n[MAX_NAME + 1]; - char hold_v[MAX_VALUE + 1]; + char hold_n[PROPERTY_MAX_NAME + 1]; + char hold_v[PROPERTY_MAX_VALUE + 1]; char buf[BUFSIZ * 4]; int bp, n, v, max; enum { LOOK, COMMENT, NAME, VALUE, MVALUE, COMMIT, FILL, STOP } state; int ch = 0, blevel = 0; n = v = bp = max = 0; head = ptr = NULL; state = LOOK; while (state != STOP) { if (state != COMMIT) { if (bp == max) state = FILL; else ch = buf[bp++]; } switch(state) { case FILL: if ((max = read(fd, buf, sizeof buf)) <= 0) { state = STOP; break; } else { state = LOOK; ch = buf[0]; bp = 1; } /* Fall through deliberately since we already have a character and state == LOOK */ case LOOK: if (isspace(ch)) continue; /* Allow shell or lisp style comments */ else if (ch == '#' || ch == ';') { state = COMMENT; continue; } else if (isalnum(ch) || ch == '_') { - if (n >= MAX_NAME) { + if (n >= PROPERTY_MAX_NAME) { n = 0; state = COMMENT; } else { hold_n[n++] = ch; state = NAME; } } else state = COMMENT; /* Ignore the rest of the line */ break; case COMMENT: if (ch == '\n') state = LOOK; break; case NAME: if (ch == '\n' || !ch) { hold_n[n] = '\0'; hold_v[0] = '\0'; v = n = 0; state = COMMIT; } else if (isspace(ch)) continue; else if (ch == '=') { hold_n[n] = '\0'; v = n = 0; state = VALUE; } else hold_n[n++] = ch; break; case VALUE: - if (v == 0 && isspace(ch)) + if (v == 0 && ch == '\n') { + hold_v[v] = '\0'; + v = n = 0; + state = COMMIT; + } + else if (v == 0 && isspace(ch)) continue; else if (ch == '{') { state = MVALUE; ++blevel; } else if (ch == '\n' || !ch) { hold_v[v] = '\0'; v = n = 0; state = COMMIT; } else { - if (v >= MAX_VALUE) { + if (v >= PROPERTY_MAX_VALUE) { state = COMMENT; v = n = 0; break; } else hold_v[v++] = ch; } break; case MVALUE: /* multiline value */ - if (v >= MAX_VALUE) { + if (v >= PROPERTY_MAX_VALUE) { warn("properties_read: value exceeds max length"); state = COMMENT; n = v = 0; } else if (ch == '}' && !--blevel) { hold_v[v] = '\0'; v = n = 0; state = COMMIT; } else { hold_v[v++] = ch; if (ch == '{') ++blevel; } break; case COMMIT: if (!head) head = ptr = property_alloc(hold_n, hold_v); else { ptr->next = property_alloc(hold_n, hold_v); ptr = ptr->next; } state = LOOK; v = n = 0; break; case STOP: /* we don't handle this here, but this prevents warnings */ break; } } return head; } char * property_find(properties list, const char *name) { if (!list || !name || !name[0]) return NULL; while (list) { if (!strcmp(list->name, name)) return list->value; list = list->next; } return NULL; } void properties_free(properties list) { properties tmp; while (list) { tmp = list->next; if (list->name) free(list->name); if (list->value) free(list->value); free(list); list = tmp; } }