diff --git a/include/parse_subs.h b/include/parse_subs.h new file mode 100644 index 0000000..7c23429 --- /dev/null +++ b/include/parse_subs.h @@ -0,0 +1,28 @@ +/* ----------------------------------------------------------------------- * + * + * parse_subs.c - misc parser subroutines + * automounter map + * + * Copyright 1997 Transmeta Corporation - All Rights Reserved + * Copyright 2000 Jeremy Fitzhardinge + * Copyright 2004-2006 Ian Kent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#ifndef PARSE_SUBS_H +#define PARSE_SUBS_H + +const char *skipspace(const char *); +int check_colon(const char *); +int chunklen(const char *, int); +int strmcmp(const char *, const char *, int); +char *dequote(const char *, int, unsigned int); +char *sanitize_path(const char *, int); + +#endif diff --git a/lib/parse_subs.c b/lib/parse_subs.c new file mode 100644 index 0000000..d5efb8b --- /dev/null +++ b/lib/parse_subs.c @@ -0,0 +1,207 @@ +/* ----------------------------------------------------------------------- * + * + * parse_subs.c - misc parser subroutines + * automounter map + * + * Copyright 1997 Transmeta Corporation - All Rights Reserved + * Copyright 2000 Jeremy Fitzhardinge + * Copyright 2004-2006 Ian Kent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include +#include "log.h" + +/* + * Skip whitespace in a string; if we hit a #, consider the rest of the + * entry a comment. + */ +const char *skipspace(const char *whence) +{ + while (1) { + switch (*whence) { + case ' ': + case '\b': + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + whence++; + break; + case '#': /* comment: skip to end of string */ + while (*whence != '\0') + whence++; + /* FALLTHROUGH */ + + default: + return whence; + } + } +} + +/* + * Check a string to see if a colon appears before the next '/'. + */ +int check_colon(const char *str) +{ + char *ptr = (char *) str; + + while (*ptr && *ptr != ':' && *ptr != '/') { + ptr++; + } + + if (!*ptr || *ptr == '/') + return 0; + + return 1; +} + +/* Get the length of a chunk delimitered by whitespace */ +int chunklen(const char *whence, int expect_colon) +{ + char *str = (char *) whence; + int n = 0; + int quote = 0; + + for (; *str; str++, n++) { + switch (*str) { + case '\\': + if( quote ) { + break; + } else { + quote = 1; + continue; + } + case ':': + if (expect_colon) + expect_colon = 0; + continue; + case ' ': + case '\t': + /* Skip space or tab if we expect a colon */ + if (expect_colon) + continue; + case '\b': + case '\n': + case '\v': + case '\f': + case '\r': + case '\0': + if (!quote) + return n; + /* FALLTHROUGH */ + default: + break; + } + quote = 0; + } + + return n; +} + +/* + * Compare str with pat. Return 0 if compare equal or + * str is an abbreviation of pat of no less than mchr characters. + */ +int strmcmp(const char *str, const char *pat, int mchr) +{ + int nchr = 0; + + while (*str == *pat) { + if (!*str) + return 0; + str++; + pat++; + nchr++; + } + + if (!*str && nchr > mchr) + return 0; + + return *pat - *str; +} + +char *dequote(const char *str, int origlen, unsigned int logopt) +{ + char *ret = malloc(origlen + 1); + char *cp = ret; + const char *scp; + int len = origlen; + int quote = 0, dquote = 0; + + if (ret == NULL) + return NULL; + + for (scp = str; len > 0 && *scp; scp++, len--) { + if (!quote) { + if (*scp == '"') { + if (dquote) + dquote = 0; + else + dquote = 1; + continue; + } + + if (*scp == '\\') { + quote = 1; + continue; + } + } + quote = 0; + *cp++ = *scp; + } + *cp = '\0'; + + if (dquote) { + debug(logopt, "unmatched quote in %.*s", origlen, str); + free(ret); + return NULL; + } + + return ret; +} + +char *sanitize_path(const char *path, int origlen) +{ + char *ret = malloc(origlen + 1); + char *cp = ret; + const char *scp; + int len = origlen; + unsigned int seen_slash = 0, quote = 0; + + if (ret == NULL) + return NULL; + + for (scp = path; len > 0 && *scp; scp++, len--) { + if (!quote) { + if (*scp == '\\') { + quote = 1; + continue; + } + + if (*scp == '/') { + if (seen_slash) + continue; + + seen_slash = 1; + } else + seen_slash = 0; + } + quote = 0; + *cp++ = *scp; + } + *cp = '\0'; + + if (origlen > 1 && *(cp - 1) == '/') + *(cp - 1) = '\0'; + + return ret; +} +