diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/compat.c | 275 | ||||
| -rw-r--r-- | common/compat.h | 88 | ||||
| -rw-r--r-- | common/config-parser.c | 366 | ||||
| -rw-r--r-- | common/config-parser.h | 53 | ||||
| -rw-r--r-- | common/usuals.h | 79 | 
5 files changed, 861 insertions, 0 deletions
| diff --git a/common/compat.c b/common/compat.c new file mode 100644 index 0000000..c6138d0 --- /dev/null +++ b/common/compat.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2004, Nate Nielsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + *     * Redistributions of source code must retain the above + *       copyright notice, this list of conditions and the + *       following disclaimer. + *     * 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. + *     * The names of contributors to this software may not be + *       used to endorse or promote products derived from this + *       software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + * + * CONTRIBUTORS + *  Nate Nielsen <nielsen@memberwebs.com> + * + */ + +#include <sys/types.h> + +#include <ctype.h> +#include <syslog.h> +#include <stdlib.h> +#include <stdio.h> +#include <err.h> +#include <strings.h> + +#include "usuals.h" +#include "compat.h" + +#ifndef HAVE_STRCLN + +void +strcln(char* data, char ch) +{ +    char* p; +    for(p = data; *data; data++, p++) +    { +        while(*data == ch) +            data++; +        *p = *data; +    } + +    /* Renull terminate */ +    *p = 0; +} + +#endif /* HAVE_STRCLN */ + +#ifndef HAVE_STRBTRIM + +char* +strbtrim(const char* data) +{ +    while(*data && isspace(*data)) +        ++data; +    return (char*)data; +} + +#endif /* HAVE_STRBTRIM */ + +#ifndef HAVE_STRETRIM + +void +stretrim(char* data) +{ +    char* t = data + strlen(data); +    while(t > data && isspace(*(t - 1))) +    { +        t--; +        *t = 0; +    } +} + +#endif /* HAVE_STRETRIM */ + +#ifndef HAVE_STRTRIM + +char* +strtrim(char* data) +{ +    data = (char*)strbtrim(data); +    stretrim(data); +    return data; +} + +#endif /* HAVE_STRTRIM */ + +#ifndef HAVE_STRTOB + +int +strtob(const char* str) +{ +    if(strcasecmp(str, "0") == 0 || +       strcasecmp(str, "no") == 0 || +       strcasecmp(str, "false") == 0 || +       strcasecmp(str, "f") == 0 || +       strcasecmp(str, "off") == 0) +        return 0; + +    if(strcasecmp(str, "1") == 0 || +       strcasecmp(str, "yes") == 0 || +       strcasecmp(str, "true") == 0 || +       strcasecmp(str, "t") == 0 || +       strcasecmp(str, "on") == 0) +        return 1; + +    return -1; +} + +#endif /* HAVE_STRTOB */ + + +#ifndef HAVE_STRLCPY + +size_t +strlcpy(char *dst, const char *src, size_t len) +{ +        size_t ret = strlen(dst); + +        while (len > 1) { +                *dst++ = *src++; +                len--; +        } +        if (len > 0) +                *dst = '\0'; +        return (ret); +} + +#endif /* HAVE_STRLCPY */ + +#ifndef HAVE_STRLCAT + +size_t +strlcat(char* dst, const char* src, size_t siz) +{ +    char* d = dst; +    const char* s = src; +    size_t n = siz; +    size_t dlen; + +    while(n-- != 0 && *d != '\0') +        d++; +    dlen = d - dst; +    n = siz - dlen; +    if(n == 0) +        return dlen + strlen(s); +    while(*s != '\0') +    { +        if(n != 1) +        { +            *d++ = *s; +            n--; +        } + +        s++; +    } +    *d = '\0'; +    return dlen + (s - src);       /* count does not include NUL */ +} + +#endif /* HAVE_STRLCAT */ + +#ifndef HAVE_ATEXITV + +typedef void (*voidfunc)(void*); +typedef struct _exit_stack +{ +    voidfunc func; +    void* data; + +    /* We have a list of these beauties */ +    struct _exit_stack* next; +} +exit_stack; + +/* Our exit stack */ +static exit_stack* atexits = NULL; +static int atexit_registered = 0; + +static void +atexit_do_stack(void) +{ +    exit_stack* next; +    for(; atexits; atexits = next) +    { +        next = atexits->next; +        (atexits->func)(atexits->data); +        free(atexits); +    } +} + +void +atexitv(voidfunc func, void* data) +{ +    exit_stack* ae; + +    ASSERT(func); + +    ae = (exit_stack*)calloc(1, sizeof(exit_stack)); +    if(ae) +    { +        ae->func = func; +        ae->data = data; +        ae->next = atexits; +        atexits = ae; + +        if(!atexit_registered) +            atexit(atexit_do_stack); +    } +} + +#endif /* HAVE_ATEXITV */ + + +#ifndef HAVE_XCALLOC + +void* +xcalloc(size_t size) +{ +    register void* value = calloc(1, size); +    if(value == NULL) +        errx(1, "out of memory"); +    return value; +} + +#endif /* HAVE_XCALLOC */ + + +#ifndef HAVE_STRLWR + +void strlwr(char* data) +{ +    while(*data) +    { +        *data = tolower(*data); +        data++; +    } +} + +#endif /* HAVE_STRLWR */ + + +#ifndef HAVE_STRUPR + +void strupr(char* data) +{ +    while(*data) +    { +        *data = toupper(*data); +        data++; +    } +} + +#endif /* HAVE_STRUPR */ diff --git a/common/compat.h b/common/compat.h new file mode 100644 index 0000000..8aaef66 --- /dev/null +++ b/common/compat.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004, Nate Nielsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + *     * Redistributions of source code must retain the above + *       copyright notice, this list of conditions and the + *       following disclaimer. + *     * 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. + *     * The names of contributors to this software may not be + *       used to endorse or promote products derived from this + *       software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + * + * CONTRIBUTORS + *  Nate Nielsen <nielsen@memberwebs.com> + * + */ + +#ifndef __COMPAT_H__ +#define __COMPAT_H__ + +#include "config.h" + +#ifndef HAVE_STRLCPY +size_t strlcpy(char *dst, const char *src, size_t len); +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char* dst, const char* src, size_t siz); +#endif + +#ifndef HAVE_STRCLN +void strcln(char* data, char ch); +#endif + +#ifndef HAVE_STRBTRIM +char* strbtrim(const char* data); +#endif + +#ifndef HAVE_STRETRIM +void stretrim(char* data); +#endif + +#ifndef HAVE_STRTRIM +char* strtrim(char* data); +#endif + +#ifndef HAVE_STRTOB +int strtob(const char* str); +#endif + +#ifndef HAVE_ATEXITV +void atexitv(void (*func)(void*), void* data); +#endif + +#ifndef HAVE_XCALLOC +void* xcalloc(size_t size); +#endif + +#ifndef HAVE_STRLWR +void strlwr(char* data); +#endif + +#ifndef HAVE_STRUPR +void strupr(char* data); +#endif + +#endif /* __COMPAT_H__ */ diff --git a/common/config-parser.c b/common/config-parser.c new file mode 100644 index 0000000..36c8ba9 --- /dev/null +++ b/common/config-parser.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2005, Nate Nielsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + *     * Redistributions of source code must retain the above + *       copyright notice, this list of conditions and the + *       following disclaimer. + *     * 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. + *     * The names of contributors to this software may not be + *       used to endorse or promote products derived from this + *       software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + * + * CONTRIBUTORS + *  Nate Nielsen <nielsen@memberwebs.com> + */ + +#include "usuals.h" +#include <errno.h> +#include <unistd.h> +#include <syslog.h> +#include <stdarg.h> +#include <dirent.h> + +#include "config-parser.h" + +static void +errmsg(const char* filename, void* data, const char* msg, ...) +{ +    #define MAX_MSGLEN  1024 +    char buf[MAX_MSGLEN]; +    va_list ap; + +    va_start(ap, msg); +    vsnprintf(buf, MAX_MSGLEN, msg, ap); +    buf[MAX_MSGLEN - 1] = 0; +    cfg_error(filename, buf, data); +    va_end(ap); +} + +/* ----------------------------------------------------------------------------- + * CONFIG PARSER + */ + +static char* +read_config_file(const char** configfile, void* data) +{ +    char* config = NULL; +	char* newfilename; +    FILE* f = NULL; +    long len; +	int flen; + +    ASSERT(configfile); + +    f = fopen(*configfile, "r"); +    if(f == NULL) +    { +        errmsg(*configfile, data, "couldn't open config file: %s", *configfile); +        return NULL; +    } + +    /* Figure out size */ +    if(fseek(f, 0, SEEK_END) == -1 || (len = ftell(f)) == -1 || fseek(f, 0, SEEK_SET) == -1) +    { +        errmsg(*configfile, data, "couldn't seek config file: %s", *configfile); +        return NULL; +    } + +	flen = strlen(*configfile); +    if((config = (char*)malloc(len + 4 + flen)) == NULL) +    { +        errmsg(*configfile, data, "out of memory"); +        return NULL; +    } + +    /* And read in one block */ +    if(fread(config, 1, len, f) != len) +    { +        errmsg(*configfile, data, "couldn't read config file: %s", *configfile); +        return NULL; +    } + +    fclose(f); + +    /* Null terminate the data */ +    config[len] = '\n'; +    config[len + 1] = 0; + +    /* Remove nasty dos line endings */ +    strcln(config, '\r'); + +	/* Persistent allocation for filename */ +	newfilename = config + len + 2; +	strcpy(newfilename, *configfile); +    *configfile = newfilename; + +    return config; +} + +int +cfg_parse_file(const char* filename, void* data, char** memory) +{ +    char* name = NULL; +    char* value = NULL; +    char* config; +    char* next; +    char* header; +    int ret = -1; +    char* p; +    char* t; + +    ASSERT(filename); + +    config = read_config_file(&filename, data); +    if(!config) +        goto finally; + +    next = config; + +    /* Go through lines and process them */ +    while((t = strchr(next, '\n')) != NULL) +    { +        *t = 0; +        p = next; /* Do this before cleaning below */ +        next = t + 1; + +        t = strbtrim(p); + +        /* Continuation line (had spaces at start) */ +        if(p < t && *t) +        { +            if(!value) +            { +                errmsg(filename, data, "%s: invalid continuation in config: %s", +                       filename, p); +                goto finally; +            } + +            /* Calculate the end of the current value */ +            t = value + strlen(value); +            ASSERT(t < p); + +            /* Continuations are separated by spaces */ +            *t = ' '; +            t++; + +            continue; +        } + +        /* No continuation hand off value if necessary */ +        if(name && value) +        { +            if(cfg_value(filename, header, name, value, data) == -1) +                goto finally; +        } + +        name = NULL; +        value = NULL; + +        /* Empty lines / comments at start / comments without continuation */ +        if(!*t || *p == '#') +            continue; + +        /* A header */ +        if(*p == '[') +        { +            t = p + strcspn(p, "]"); +            if(!*t || t == p + 1) +            { +                errmsg(filename, data, "%s: invalid config header: %s", +                       filename, p); +                goto finally; +            } + +            *t = 0; +            header = strtrim(p + 1); +            continue; +        } + +        /* Look for the break between name = value on the same line */ +        t = p + strcspn(p, ":="); +        if(!*t) +        { +            errmsg(filename, data, "%s: invalid config line: %s", +                   filename, p); +            goto finally; +        } + +        /* Null terminate and split value part */ +        *t = 0; +        t++; + +        name = strtrim(p); +        value = strtrim(t); +    } + +    if(name && value) +    { +        if(cfg_value(filename, header, name, value, data) == -1) +            goto finally; +    } + +    ret = 0; + + +finally: + +    if(!memory || ret != 0) +        free(config); +    else if(memory) +        *memory = config; + +    return ret; +} + +static int +parse_dir_internal(const char* subdir, void* data) +{ +    char path[MAXPATHLEN]; +    struct dirent* dire; +    char* memory; +    DIR* dir; +    int r; + +    /* Open specified or current directory */ +    dir = opendir(subdir ? subdir : "."); +    if(!dir) +    { +        errmsg(NULL, data, "couldn't list config directory: %s", +               subdir ? subdir : "."); +        return -1; +    } + +    while((dire = readdir(dir)) != NULL) +    { +        /* Build a file path to this entry */ +        if(subdir) +        { +            strlcpy(path, subdir, MAXPATHLEN); +            strlcat(path, "/", MAXPATHLEN); +            strlcat(path, dire->d_name, MAXPATHLEN); +        } +        else +            strlcpy(path, dire->d_name, MAXPATHLEN); + +        /* Descend into each sub directory */ +        if(dire->d_type == DT_DIR) +        { +            /* No hidden or dot directories */ +            if(dire->d_name[0] == '.') +                continue; + +            r = parse_dir_internal(path, data); +            if(r < 0) +                return r; + +            continue; +        } + +        if(dire->d_type != DT_REG && dire->d_type != DT_LNK) +            continue; + +        /* Build a happy path name */ +        cfg_parse_file(path, data, &memory); + +        /* We call it with blanks after files */ +        if(cfg_value(path, NULL, NULL, NULL, data) == -1) +            break; + +        /* Keep the memory around */ +        if(memory) +            atexitv(free, memory); +    } + +    closedir(dir); + +    return 0; +} + +int +cfg_parse_dir(const char* dirname, void* data) +{ +    char olddir[MAXPATHLEN]; +    int ret; + +    ASSERT(dirname != NULL); + +    if(!getcwd(olddir, MAXPATHLEN)) +        olddir[0] = 0; + +    if(chdir(dirname) == -1) +    { +        errmsg(NULL, data, "couldn't list config directory: %s", dirname); +        return -1; +    } + +    ret = parse_dir_internal(NULL, data); + +    if(olddir[0]) +        chdir(olddir); + +    return ret; +} + +const char* +cfg_parse_uri (char *uri, char** scheme, char** host, char** user, char** path) +{ +    char* t; + +    *scheme = NULL; +    *host = NULL; +    *user = NULL; +    *path = NULL; + +    *scheme = strsep(&uri, ":"); +    if(uri == NULL || (uri[0] != '/' && uri[1] != '/')) +        return "invalid uri"; + +    uri += 2; +    *host = strsep(&uri, "/"); +    if(*host[0]) +    { +        /* Parse the community out from the host */ +        t = strchr(*host, '@'); +        if(t) +        { +            *t = 0; +            *user = *host; +            *host = t + 1; +        } +    } + +    if(!*host[0]) +        return "invalid uri: no host name found"; + +    if(!uri || !uri[0] || !uri[1]) +        return "invalid uri: no path found"; + +    *path = uri; + +    while((*path)[0] == '/') +        (*path)++; + +    return NULL; +} diff --git a/common/config-parser.h b/common/config-parser.h new file mode 100644 index 0000000..11949a2 --- /dev/null +++ b/common/config-parser.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005, Nate Nielsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + *     * Redistributions of source code must retain the above + *       copyright notice, this list of conditions and the + *       following disclaimer. + *     * 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. + *     * The names of contributors to this software may not be + *       used to endorse or promote products derived from this + *       software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + * + * CONTRIBUTORS + *  Nate Nielsen <nielsen@memberwebs.com> + */ + +#ifndef __CONFIG_PARSER_H__ +#define __CONFIG_PARSER_H__ + +/* Callbacks must be defined by the caller */ +extern int cfg_value(const char* filename, const char* header, const char* name, +                     char* value, void* data); +extern int cfg_error(const char* filename, const char* errmsg, void* data); + +/* Calling these will call the callbacks above */ +int cfg_parse_dir(const char* dirname, void* data); +int cfg_parse_file(const char* filename, void* data, char** memory); + +/* A helper for parsing URIs */ +const char* cfg_parse_uri (char *uri, char** scheme, char** host, char** user, char** path); + +#endif /* __CONFIG_PARSER_H__ */ diff --git a/common/usuals.h b/common/usuals.h new file mode 100644 index 0000000..5fece3f --- /dev/null +++ b/common/usuals.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2005, Nate Nielsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + *     * Redistributions of source code must retain the above + *       copyright notice, this list of conditions and the + *       following disclaimer. + *     * 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. + *     * The names of contributors to this software may not be + *       used to endorse or promote products derived from this + *       software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + * + * CONTRIBUTORS + *  Nate Nielsen <nielsen@memberwebs.com> + * + */ + +#ifndef __USUALS_H__ +#define __USUALS_H__ + +#include <sys/types.h> + +#include "config.h" + +#include <sys/types.h> +#include <sys/param.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + +#include "compat.h" + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef max +#define max(a,b)  (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b)  (((a) < (b)) ? (a) : (b)) +#endif + +#define countof(x) (sizeof(x) / sizeof(x[0])) + +#ifdef _DEBUG +  #include "assert.h" +  #define ASSERT(x) assert(x) +#else +  #define ASSERT(x) +#endif + +#define KL(s)               ((sizeof(s) - 1) / sizeof(char)) +#define RETURN(x)           { ret = (x); goto finally; } + +#endif /* __USUALS_H__ */ | 
