1 | /* |
2 | * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. Oracle designates this |
8 | * particular file as subject to the "Classpath" exception as provided |
9 | * by Oracle in the LICENSE file that accompanied this code. |
10 | * |
11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * version 2 for more details (a copy is included in the LICENSE file that |
15 | * accompanied this code). |
16 | * |
17 | * You should have received a copy of the GNU General Public License version |
18 | * 2 along with this work; if not, write to the Free Software Foundation, |
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | * |
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 | * or visit www.oracle.com if you need additional information or have any |
23 | * questions. |
24 | */ |
25 | |
26 | #include <stdio.h> |
27 | #include <stdlib.h> |
28 | #include <string.h> |
29 | |
30 | #include "FileSystemSupport_md.h" |
31 | |
32 | /* |
33 | * Solaris/Linux implementation of the file system support functions. |
34 | */ |
35 | |
36 | #define slash '/' |
37 | |
38 | char pathSeparator() { |
39 | return ':'; |
40 | } |
41 | |
42 | /* Filenames are case senstitive */ |
43 | int filenameStrcmp(const char* s1, const char* s2) { |
44 | return strcmp(s1, s2); |
45 | } |
46 | |
47 | char* basePath(const char* path) { |
48 | char* last = strrchr(path, slash); |
49 | if (last == NULL) { |
50 | return (char*)path; |
51 | } else { |
52 | int len = last - path; |
53 | char* str = (char*)malloc(len+1); |
54 | if (str == NULL) { |
55 | fprintf(stderr, "OOM error in native tmp buffer allocation" ); |
56 | return NULL; |
57 | } |
58 | if (len > 0) { |
59 | memcpy(str, path, len); |
60 | } |
61 | str[len] = '\0'; |
62 | return str; |
63 | } |
64 | } |
65 | |
66 | int isAbsolute(const char* path) { |
67 | return (path[0] == slash) ? 1 : 0; |
68 | } |
69 | |
70 | /* Ported from src/solaris/classes/java/io/UnixFileSystem.java */ |
71 | |
72 | /* A normal Unix pathname contains no duplicate slashes and does not end |
73 | with a slash. It may be the empty string. */ |
74 | |
75 | /* Normalize the given pathname, whose length is len, starting at the given |
76 | offset; everything before this offset is already normal. */ |
77 | static char* normalizePath(const char* pathname, int len, int off) { |
78 | char* sb; |
79 | int sbLen, i, n; |
80 | char prevChar; |
81 | |
82 | if (len == 0) return (char*)pathname; |
83 | n = len; |
84 | while ((n > 0) && (pathname[n - 1] == slash)) n--; |
85 | if (n == 0) return strdup("/" ); |
86 | |
87 | sb = (char*)malloc(strlen(pathname)+1); |
88 | if (sb == NULL) { |
89 | fprintf(stderr, "OOM error in native tmp buffer allocation" ); |
90 | return NULL; |
91 | } |
92 | sbLen = 0; |
93 | |
94 | if (off > 0) { |
95 | memcpy(sb, pathname, off); |
96 | sbLen = off; |
97 | } |
98 | |
99 | prevChar = 0; |
100 | for (i = off; i < n; i++) { |
101 | char c = pathname[i]; |
102 | if ((prevChar == slash) && (c == slash)) continue; |
103 | sb[sbLen++] = c; |
104 | prevChar = c; |
105 | } |
106 | return sb; |
107 | } |
108 | |
109 | /* Check that the given pathname is normal. If not, invoke the real |
110 | normalizer on the part of the pathname that requires normalization. |
111 | This way we iterate through the whole pathname string only once. */ |
112 | char* normalize(const char* pathname) { |
113 | int i; |
114 | int n = strlen(pathname); |
115 | char prevChar = 0; |
116 | for (i = 0; i < n; i++) { |
117 | char c = pathname[i]; |
118 | if ((prevChar == slash) && (c == slash)) |
119 | return normalizePath(pathname, n, i - 1); |
120 | prevChar = c; |
121 | } |
122 | if (prevChar == slash) return normalizePath(pathname, n, n - 1); |
123 | return (char*)pathname; |
124 | } |
125 | |
126 | char* resolve(const char* parent, const char* child) { |
127 | int len; |
128 | char* theChars; |
129 | int pn = strlen(parent); |
130 | int cn = strlen(child); |
131 | int childStart = 0; |
132 | int parentEnd = pn; |
133 | |
134 | if (pn > 0 && parent[pn-1] == slash) { |
135 | parentEnd--; |
136 | } |
137 | len = parentEnd + cn - childStart; |
138 | if (child[0] == slash) { |
139 | theChars = (char*)malloc(len+1); |
140 | if (theChars == NULL) { |
141 | fprintf(stderr, "OOM error in native tmp buffer allocation" ); |
142 | return NULL; |
143 | } |
144 | if (parentEnd > 0) |
145 | memcpy(theChars, parent, parentEnd); |
146 | if (cn > 0) |
147 | memcpy(theChars+parentEnd, child, cn); |
148 | theChars[len] = '\0'; |
149 | } else { |
150 | theChars = (char*)malloc(len+2); |
151 | if (theChars == NULL) { |
152 | fprintf(stderr, "OOM error in native tmp buffer allocation" ); |
153 | return NULL; |
154 | } |
155 | if (parentEnd > 0) |
156 | memcpy(theChars, parent, parentEnd); |
157 | theChars[parentEnd] = slash; |
158 | if (cn > 0) |
159 | memcpy(theChars+parentEnd+1, child, cn); |
160 | theChars[len+1] = '\0'; |
161 | } |
162 | return theChars; |
163 | } |
164 | |
165 | char* fromURIPath(const char* path) { |
166 | int len = strlen(path); |
167 | if (len > 1 && path[len-1] == slash) { |
168 | // "/foo/" --> "/foo", but "/" --> "/" |
169 | char* str = (char*)malloc(len); |
170 | if (str == NULL) |
171 | { |
172 | fprintf(stderr, "OOM error in native tmp buffer allocation" ); |
173 | return NULL; |
174 | } |
175 | memcpy(str, path, len-1); |
176 | str[len-1] = '\0'; |
177 | return str; |
178 | } else { |
179 | return (char*)path; |
180 | } |
181 | } |
182 | |