Merge branch '1.x' of ssh://authdev.it.ohio-state.edu/~scantor/git/cpp-xmltooling...
[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 }
42
43 PathResolver::~PathResolver()
44 {
45 }
46
47 void PathResolver::setDefaultPackageName(const char* pkgname)
48 {
49     m_defaultPackage = pkgname;
50 }
51
52 void PathResolver::setDefaultPrefix(const char* prefix)
53 {
54     m_defaultPrefix = prefix;
55 }
56
57 void PathResolver::setLibDir(const char* dir)
58 {
59     m_lib = dir;
60 }
61
62 void PathResolver::setLogDir(const char* dir)
63 {
64     m_log = dir;
65 }
66
67 void PathResolver::setXMLDir(const char* dir)
68 {
69     m_xml = dir;
70 }
71
72 void PathResolver::setRunDir(const char* dir)
73 {
74     m_run = dir;
75 }
76
77 void PathResolver::setCfgDir(const char* dir)
78 {
79     m_cfg = dir;
80 }
81
82 bool PathResolver::isAbsolute(const char* s) const
83 {
84     switch (*s) {
85         case 0:
86             return false;
87         case '/':
88         case '\\':
89             return true;
90         case '.':
91             return (*(s+1) == '.' || *(s+1) == '/' || *(s+1) == '\\');
92     }
93     return *(s+1) == ':';
94 }
95
96 const string& PathResolver::resolve(string& s, file_type_t filetype, const char* pkgname, const char* prefix) const
97 {
98     if (!isAbsolute(s.c_str())) {
99         switch (filetype) {
100             case XMLTOOLING_LIB_FILE:
101                 s = m_lib + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
102                 if (!isAbsolute(m_lib.c_str()))
103                     s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
104                 break;
105
106             case XMLTOOLING_LOG_FILE:
107                 s = m_log + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
108                 if (!isAbsolute(m_log.c_str())) {
109                     if (prefix || m_defaultPrefix != "/usr")
110                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
111                     else
112                         s = string("/") + s;
113                 }
114                 break;
115
116             case XMLTOOLING_XML_FILE:
117                 s = m_xml + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
118                 if (!isAbsolute(m_xml.c_str()))
119                     s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
120                 break;
121
122             case XMLTOOLING_RUN_FILE:
123                 s = m_run + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
124                 if (!isAbsolute(m_run.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_CFG_FILE:
133                 s = m_cfg + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
134                 if (!isAbsolute(m_cfg.c_str())) {
135                     if (prefix || m_defaultPrefix != "/usr")
136                         s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
137                     else
138                         s = string("/") + s;
139                 }
140                 break;
141
142             default:
143                 throw XMLToolingException("Unknown file type to resolve.");
144         }
145     }
146     return s;
147 }