Forgot to change length of variable
[shibboleth/cpp-xmltooling.git] / xmltooling / util / PathResolver.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * PathResolver.cpp
23  *
24  * Resolves local filenames into absolute pathnames.
25  */
26
27 #include "internal.h"
28 #include "exceptions.h"
29 #include "util/PathResolver.h"
30
31 using namespace xmltooling;
32 using namespace std;
33
34 PathResolver::PathResolver() : m_defaultPackage(PACKAGE_NAME), m_defaultPrefix("/usr")
35 {
36     setLibDir("/usr/lib");
37     setLogDir("/var/log");
38     setXMLDir("/usr/share/xml");
39     setRunDir("/var/run");
40     setCfgDir("/etc");
41     setCacheDir("/var/cache");
42 }
43
44 PathResolver::~PathResolver()
45 {
46 }
47
48 void PathResolver::setDefaultPackageName(const char* pkgname)
49 {
50     m_defaultPackage = pkgname;
51 }
52
53 void PathResolver::setDefaultPrefix(const char* prefix)
54 {
55     m_defaultPrefix = prefix;
56 }
57
58 void PathResolver::setLibDir(const char* dir)
59 {
60     m_lib = dir;
61 }
62
63 void PathResolver::setLogDir(const char* dir)
64 {
65     m_log = dir;
66 }
67
68 void PathResolver::setXMLDir(const char* dir)
69 {
70     m_xml = dir;
71 }
72
73 void PathResolver::setRunDir(const char* dir)
74 {
75     m_run = dir;
76 }
77
78 void PathResolver::setCfgDir(const char* dir)
79 {
80     m_cfg = dir;
81 }
82
83 void PathResolver::setCacheDir(const char* dir)
84 {
85     m_cache = dir;
86 }
87
88 bool PathResolver::isAbsolute(const char* s) const
89 {
90     switch (*s) {
91         case 0:
92             return false;
93         case '/':
94         case '\\':
95             return true;
96         case '.':
97             return (*(s+1) == '.' || *(s+1) == '/' || *(s+1) == '\\');
98     }
99     return *(s+1) == ':';
100 }
101
102 const string& PathResolver::resolve(string& s, file_type_t filetype, const char* pkgname, const char* prefix) const
103 {
104 #ifdef WIN32
105     // Check for possible environment variable(s).
106     if (s.find('%') != string::npos) {
107         // This is an ugly workaround for Windows XP/2003, which don't support the PROGRAMDATA variable.
108         if (!getenv("PROGRAMDATA") && s.find("%PROGRAMDATA%") != string::npos) {
109             s.replace(s.find("%PROGRAMDATA%"), 13, "%ALLUSERSPROFILE%/Application Data");
110         }
111         char expbuf[MAX_PATH + 2];
112         DWORD cnt = ExpandEnvironmentStrings(s.c_str(), expbuf, sizeof(expbuf));
113         if (cnt != 0 && cnt <= sizeof(expbuf))
114             s = expbuf;
115     }
116 #endif
117
118     if (!isAbsolute(s.c_str())) {
119         switch (filetype) {
120             case XMLTOOLING_LIB_FILE:
121                 s = m_lib + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
122                 if (!isAbsolute(m_lib.c_str()))
123                     s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
124                 break;
125
126             case XMLTOOLING_LOG_FILE:
127                 s = m_log + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
128                 if (!isAbsolute(m_log.c_str())) {
129                     if (prefix || m_defaultPrefix != "/usr")
130                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
131                     else
132                         s = string("/") + s;
133                 }
134                 break;
135
136             case XMLTOOLING_XML_FILE:
137                 s = m_xml + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
138                 if (!isAbsolute(m_xml.c_str()))
139                     s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
140                 break;
141
142             case XMLTOOLING_RUN_FILE:
143                 s = m_run + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
144                 if (!isAbsolute(m_run.c_str())) {
145                     if (prefix || m_defaultPrefix != "/usr")
146                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
147                     else
148                         s = string("/") + s;
149                 }
150                 break;
151
152             case XMLTOOLING_CFG_FILE:
153                 s = m_cfg + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
154                 if (!isAbsolute(m_cfg.c_str())) {
155                     if (prefix || m_defaultPrefix != "/usr")
156                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
157                     else
158                         s = string("/") + s;
159                 }
160                 break;
161
162             case XMLTOOLING_CACHE_FILE:
163                 s = m_cache + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
164                 if (!isAbsolute(m_cache.c_str())) {
165                     if (prefix || m_defaultPrefix != "/usr")
166                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
167                     else
168                         s = string("/") + s;
169                 }
170                 break;
171
172             default:
173                 throw XMLToolingException("Unknown file type to resolve.");
174         }
175     }
176     return s;
177 }