2 suPHP - (c)2002-2008 Sebastian Marsching <sebastian@marsching.com>
4 This file is part of suPHP.
6 suPHP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 suPHP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with suPHP; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "PathMatcher.hpp"
24 using namespace suPHP
;
26 suPHP::PathMatcher::PathMatcher(const UserInfo
& user
, const GroupInfo
& group
) {
31 bool suPHP::PathMatcher::matches(std::string pattern
, std::string path
)
32 throw (KeyNotFoundException
, ParsingException
) {
33 std::string remainingPath
= path
;
34 std::string remainingPattern
= pattern
;
36 while (remainingPath
.length() > 0 && remainingPattern
.length() > 0) {
37 bool escapeNext
= false;
38 for (int i
= 0; i
< remainingPattern
.length(); i
++) {
39 char c
= remainingPattern
.at(i
);
42 if (c
== '\\' || c
== '*' || c
== '$') {
43 // Backslash was used as an escape character
44 if (remainingPath
.at(i
-1) == c
) {
45 remainingPattern
= remainingPattern
.substr(i
+ 1);
46 remainingPath
= remainingPath
.substr(i
);
52 if (remainingPath
.at(i
-1) == '\\') {
53 remainingPattern
= remainingPattern
.substr(i
);
54 remainingPath
= remainingPath
.substr(i
);
63 } else if (c
== '*') {
64 remainingPattern
= remainingPattern
.substr(i
+ 1);
65 remainingPath
= remainingPath
.substr(i
);
66 if (matches(remainingPattern
, remainingPath
)) {
69 std::string testPrefix
;
70 for (int j
= 0; j
< remainingPath
.length(); j
++) {
71 char c2
= remainingPath
.at(j
);
75 if (c2
== '\\' || c2
== '*' || c2
== '$') {
79 if (matches(testPrefix
+ remainingPattern
,
84 } else if (c
== '$') {
85 if (remainingPattern
.length() < i
+ 3) {
86 throw ParsingException("Incorrect use of $ in pattern \"" + pattern
+ "\".", __FILE__
, __LINE__
);
88 if (remainingPattern
.at(i
+ 1) != '{') {
89 throw ParsingException("Incorrect use of $ in pattern \"" + pattern
+ "\".", __FILE__
, __LINE__
);
91 std::string::size_type closingBrace
= remainingPattern
.find('}', i
);
92 if (closingBrace
== std::string::npos
) {
93 throw ParsingException("Incorrect use of $ in pattern \"" + pattern
+ "\".", __FILE__
, __LINE__
);
95 std::string varName
= remainingPattern
.substr(i
+ 2, closingBrace
- i
- 2);
96 remainingPattern
= lookupVariable(varName
) + remainingPattern
.substr(closingBrace
+ 1);
99 if (i
>= remainingPath
.length() || c
!= remainingPath
.at(i
)) {
102 if (i
== remainingPattern
.length() - 1) {
103 if (c
== '/' || (i
+ 1 < remainingPath
.length() && remainingPath
.at(i
+ 1) == '/')) {
104 // Path represents file in subdirectory
106 } else if (remainingPath
.length() == remainingPattern
.length()) {
120 std::string
suPHP::PathMatcher::lookupVariable(std::string str
)
121 throw (KeyNotFoundException
) {
123 if (str
== "USERNAME") {
124 rv
= user
.getUsername();
125 } else if (str
== "UID") {
126 rv
= Util::intToStr(user
.getUid());
127 } else if (str
== "HOME") {
128 rv
= user
.getHomeDirectory();
129 } else if (str
== "GROUPNAME") {
130 rv
= group
.getGroupname();
131 } else if (str
== "GID") {
132 rv
= Util::intToStr(group
.getGid());
134 throw KeyNotFoundException("Key \"" + str
+
135 "\" does not represent a valid variable name", __FILE__
, __LINE__
);
140 std::string
suPHP::PathMatcher::resolveVariables(std::string str
) throw (KeyNotFoundException
, ParsingException
) {
142 bool escapeNext
= false;
143 for (int i
= 0; i
< str
.length(); i
++) {
147 if (c
== '\\' || c
== '$') {
148 // Backslash was used as an escape character
157 } else if (c
== '$') {
158 if (str
.length() < i
+ 3) {
159 throw ParsingException("Incorrect use of $ in string \"" + str
+ "\".", __FILE__
, __LINE__
);
161 if (str
.at(i
+ 1) != '{') {
162 throw ParsingException("Incorrect use of $ in string \"" + str
+ "\".", __FILE__
, __LINE__
);
164 std::string::size_type closingBrace
= str
.find('}', i
);
165 if (closingBrace
== std::string::npos
) {
166 throw ParsingException("Incorrect use of $ in string \"" + str
+ "\".", __FILE__
, __LINE__
);
168 std::string varName
= str
.substr(i
+ 2, closingBrace
- i
- 2);
169 out
+= lookupVariable(varName
);
170 i
= closingBrace
+ 1;