<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">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 &lt;jeremy@goop.org&gt;
+ *   Copyright 2004-2006 Ian Kent &lt;raven@themaw.net&gt;
+ *
+ *   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 &lt;jeremy@goop.org&gt;
+ *   Copyright 2004-2006 Ian Kent &lt;raven@themaw.net&gt;
+ *
+ *   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 &lt;stdlib.h&gt;
+#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 &amp;&amp; *ptr != ':' &amp;&amp; *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 &amp;&amp; nchr &gt; 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 &gt; 0 &amp;&amp; *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 &gt; 0 &amp;&amp; *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 &gt; 1 &amp;&amp; *(cp - 1) == '/')
+		*(cp - 1) = '\0';
+
+	return ret;
+}
+
</pre></body></html>