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;