4ca48ec41b1c56db8c9565f9f529a7d16a2ccdbd
[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         char expbuf[MAX_PATH + 2];
108         DWORD cnt = ExpandEnvironmentStrings(s.c_str(), expbuf, sizeof(expbuf));
109         if (cnt != 0 && cnt <= sizeof(expbuf))
110             s = expbuf;
111     }
112 #endif
113
114     if (!isAbsolute(s.c_str())) {
115         switch (filetype) {
116             case XMLTOOLING_LIB_FILE:
117                 s = m_lib + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
118                 if (!isAbsolute(m_lib.c_str()))
119                     s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
120                 break;
121
122             case XMLTOOLING_LOG_FILE:
123                 s = m_log + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
124                 if (!isAbsolute(m_log.c_str())) {
125                     if (prefix || m_defaultPrefix != "/usr")
126                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
127                     else
128                         s = string("/") + s;
129                 }
130                 break;
131
132             case XMLTOOLING_XML_FILE:
133                 s = m_xml + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
134                 if (!isAbsolute(m_xml.c_str()))
135                     s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
136                 break;
137
138             case XMLTOOLING_RUN_FILE:
139                 s = m_run + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
140                 if (!isAbsolute(m_run.c_str())) {
141                     if (prefix || m_defaultPrefix != "/usr")
142                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
143                     else
144                         s = string("/") + s;
145                 }
146                 break;
147
148             case XMLTOOLING_CFG_FILE:
149                 s = m_cfg + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
150                 if (!isAbsolute(m_cfg.c_str())) {
151                     if (prefix || m_defaultPrefix != "/usr")
152                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
153                     else
154                         s = string("/") + s;
155                 }
156                 break;
157
158             case XMLTOOLING_CACHE_FILE:
159                 s = m_cache + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
160                 if (!isAbsolute(m_cache.c_str())) {
161                     if (prefix || m_defaultPrefix != "/usr")
162                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
163                     else
164                         s = string("/") + s;
165                 }
166                 break;
167
168             default:
169                 throw XMLToolingException("Unknown file type to resolve.");
170         }
171     }
172     return s;
173 }