comparison 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
comparison
equal deleted inserted replaced
628:7d93356f250a 629:a5deb87b26e4
1 /*
2 * Copyright (c) 1997 Shigio Yamaguchi. All rights reserved.
3 * Copyright (c) 1999 Tama Communications Corporation. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <string.h>
29 /*
30 * rel2abs: convert an relative path name into absolute.
31 *
32 * i) path relative path
33 * i) base base directory (must be absolute path)
34 * o) result result buffer
35 * i) size size of result buffer
36 * r) != NULL: absolute path
37 * == NULL: error
38 */
39 char *
40 rel2abs(path, base, result, size)
41 const char *path;
42 const char *base;
43 char *result;
44 const size_t size;
45 {
46 const char *pp, *bp;
47 /*
48 * endp points the last position which is safe in the result buffer.
49 */
50 const char *endp = result + size - 1;
51 char *rp;
52 int length;
53
54 if (*path == '/') {
55 if (strlen(path) >= size)
56 goto erange;
57 strcpy(result, path);
58 goto finish;
59 } else if (*base != '/' || !size) {
60 errno = EINVAL;
61 return (NULL);
62 } else if (size == 1)
63 goto erange;
64
65 length = strlen(base);
66
67 if (!strcmp(path, ".") || !strcmp(path, "./")) {
68 if (length >= size)
69 goto erange;
70 strcpy(result, base);
71 /*
72 * rp points the last char.
73 */
74 rp = result + length - 1;
75 /*
76 * remove the last '/'.
77 */
78 if (*rp == '/') {
79 if (length > 1)
80 *rp = 0;
81 } else
82 rp++;
83 /* rp point NULL char */
84 if (*++path == '/') {
85 /*
86 * Append '/' to the tail of path name.
87 */
88 *rp++ = '/';
89 if (rp > endp)
90 goto erange;
91 *rp = 0;
92 }
93 goto finish;
94 }
95 bp = base + length;
96 if (*(bp - 1) == '/')
97 --bp;
98 /*
99 * up to root.
100 */
101 for (pp = path; *pp && *pp == '.'; ) {
102 if (!strncmp(pp, "../", 3)) {
103 pp += 3;
104 while (bp > base && *--bp != '/')
105 ;
106 } else if (!strncmp(pp, "./", 2)) {
107 pp += 2;
108 } else if (!strncmp(pp, "..\0", 3)) {
109 pp += 2;
110 while (bp > base && *--bp != '/')
111 ;
112 } else
113 break;
114 }
115 /*
116 * down to leaf.
117 */
118 length = bp - base;
119 if (length >= size)
120 goto erange;
121 strncpy(result, base, length);
122 rp = result + length;
123 if (*pp || *(pp - 1) == '/' || length == 0)
124 *rp++ = '/';
125 if (rp + strlen(pp) > endp)
126 goto erange;
127 strcpy(rp, pp);
128 finish:
129 return result;
130 erange:
131 errno = ERANGE;
132 return (NULL);
133 }