diff gtk/rel2abs.c @ 629:a5deb87b26e4

Add support for using initial directory in dw_file_browse()
author mhessling@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 22 Oct 2008 02:14:34 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gtk/rel2abs.c	Wed Oct 22 02:14:34 2008 +0000
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1997 Shigio Yamaguchi. All rights reserved.
+ * Copyright (c) 1999 Tama Communications Corporation. 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 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.
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+/*
+ * rel2abs: convert an relative path name into absolute.
+ *
+ *	i)	path	relative path
+ *	i)	base	base directory (must be absolute path)
+ *	o)	result	result buffer
+ *	i)	size	size of result buffer
+ *	r)		!= NULL: absolute path
+ *			== NULL: error
+ */
+char *
+rel2abs(path, base, result, size)
+	const char *path;
+	const char *base;
+	char *result;
+	const size_t size;
+{
+	const char *pp, *bp;
+	/*
+	 * endp points the last position which is safe in the result buffer.
+	 */
+	const char *endp = result + size - 1;
+	char *rp;
+	int length;
+
+	if (*path == '/') {
+		if (strlen(path) >= size)
+			goto erange;
+		strcpy(result, path);
+		goto finish;
+	} else if (*base != '/' || !size) {
+		errno = EINVAL;
+		return (NULL);
+	} else if (size == 1)
+		goto erange;
+
+	length = strlen(base);
+
+	if (!strcmp(path, ".") || !strcmp(path, "./")) {
+		if (length >= size)
+			goto erange;
+		strcpy(result, base);
+		/*
+		 * rp points the last char.
+		 */
+		rp = result + length - 1;
+		/*
+		 * remove the last '/'.
+		 */
+		if (*rp == '/') {
+			if (length > 1)
+				*rp = 0;
+		} else
+			rp++;
+		/* rp point NULL char */
+		if (*++path == '/') {
+			/*
+			 * Append '/' to the tail of path name.
+			 */
+			*rp++ = '/';
+			if (rp > endp)
+				goto erange;
+			*rp = 0;
+		}
+		goto finish;
+	}
+	bp = base + length;
+	if (*(bp - 1) == '/')
+		--bp;
+	/*
+	 * up to root.
+	 */
+	for (pp = path; *pp && *pp == '.'; ) {
+		if (!strncmp(pp, "../", 3)) {
+			pp += 3;
+			while (bp > base && *--bp != '/')
+				;
+		} else if (!strncmp(pp, "./", 2)) {
+			pp += 2;
+		} else if (!strncmp(pp, "..\0", 3)) {
+			pp += 2;
+			while (bp > base && *--bp != '/')
+				;
+		} else
+			break;
+	}
+	/*
+	 * down to leaf.
+	 */
+	length = bp - base;
+	if (length >= size)
+		goto erange;
+	strncpy(result, base, length);
+	rp = result + length;
+	if (*pp || *(pp - 1) == '/' || length == 0)
+		*rp++ = '/';
+	if (rp + strlen(pp) > endp)
+		goto erange;
+	strcpy(rp, pp);
+finish:
+	return result;
+erange:
+	errno = ERANGE;
+	return (NULL);
+}