1 : /******************************************************************************
2 : * $Id: ogrpgeodriver.cpp 18168 2009-12-03 23:56:59Z warmerdam $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements Personal Geodatabase driver.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogr_pgeo.h"
31 : #include "cpl_conv.h"
32 :
33 : CPL_CVSID("$Id: ogrpgeodriver.cpp 18168 2009-12-03 23:56:59Z warmerdam $");
34 :
35 : /************************************************************************/
36 : /* ~OGRODBCDriver() */
37 : /************************************************************************/
38 :
39 72 : OGRPGeoDriver::~OGRPGeoDriver()
40 :
41 : {
42 72 : }
43 :
44 : /************************************************************************/
45 : /* GetName() */
46 : /************************************************************************/
47 :
48 3238 : const char *OGRPGeoDriver::GetName()
49 :
50 : {
51 3238 : return "PGeo";
52 : }
53 :
54 : /************************************************************************/
55 : /* Open() */
56 : /************************************************************************/
57 :
58 : OGRDataSource *OGRPGeoDriver::Open( const char * pszFilename,
59 113 : int bUpdate )
60 :
61 : {
62 : OGRPGeoDataSource *poDS;
63 :
64 113 : if( !EQUALN(pszFilename,"PGEO:",5)
65 : && !EQUAL(CPLGetExtension(pszFilename),"mdb") )
66 113 : return NULL;
67 :
68 : #ifndef WIN32
69 : // Try to register MDB Tools driver
70 : //
71 : // ODBCINST.INI NOTE:
72 : // This operation requires write access to odbcinst.ini file
73 : // located in directory pointed by ODBCINISYS variable.
74 : // Usually, it points to /etc, so non-root users can overwrite this
75 : // setting ODBCINISYS with location they have write access to, e.g.:
76 : // $ export ODBCINISYS=$HOME/etc
77 : // $ touch $ODBCINISYS/odbcinst.ini
78 : //
79 : // See: http://www.unixodbc.org/internals.html
80 : //
81 0 : if ( !InstallMdbDriver() )
82 : {
83 : CPLError( CE_Warning, CPLE_AppDefined,
84 0 : "Unable to install MDB driver for ODBC, MDB access may not supported.\n" );
85 : }
86 : else
87 0 : CPLDebug( "PGeo", "MDB Tools driver installed successfully!");
88 :
89 : #endif /* ndef WIN32 */
90 :
91 : // Open data source
92 0 : poDS = new OGRPGeoDataSource();
93 :
94 0 : if( !poDS->Open( pszFilename, bUpdate, TRUE ) )
95 : {
96 0 : delete poDS;
97 0 : return NULL;
98 : }
99 : else
100 0 : return poDS;
101 : }
102 :
103 : /************************************************************************/
104 : /* TestCapability() */
105 : /************************************************************************/
106 :
107 0 : int OGRPGeoDriver::TestCapability( const char * pszCap )
108 :
109 : {
110 0 : return FALSE;
111 : }
112 :
113 :
114 : /*
115 : * START OF UNIX-only features.
116 : */
117 : #ifndef WIN32
118 :
119 : /************************************************************************/
120 : /* InstallMdbDriver() */
121 : /************************************************************************/
122 :
123 0 : bool OGRPGeoDriver::InstallMdbDriver()
124 : {
125 0 : if ( !FindDriverLib() )
126 : {
127 0 : return false;
128 : }
129 : else
130 : {
131 0 : CPLAssert( !osDriverFile.empty() );
132 0 : CPLDebug( "PGeo", "MDB Tools driver: %s", osDriverFile.c_str() );
133 :
134 0 : CPLString driverName("Microsoft Access Driver (*.mdb)");
135 0 : CPLString driver(driverName);
136 0 : driver += '\0';
137 0 : driver += "Driver=";
138 0 : driver += osDriverFile; // Found by FindDriverLib()
139 0 : driver += '\0';
140 0 : driver += "FileUsage=1";
141 0 : driver += '\0';
142 0 : driver += '\0';
143 :
144 : // Create installer and register driver
145 0 : CPLODBCDriverInstaller dri;
146 :
147 0 : if ( !dri.InstallDriver(driver.c_str(), 0, ODBC_INSTALL_COMPLETE) )
148 : {
149 : // Report ODBC error
150 0 : CPLError( CE_Failure, CPLE_AppDefined, "ODBC: %s", dri.GetLastError() );
151 0 : return false;
152 0 : }
153 : }
154 :
155 0 : return true;
156 : }
157 :
158 : /************************************************************************/
159 : /* FindDriverLib() */
160 : /************************************************************************/
161 :
162 0 : bool OGRPGeoDriver::FindDriverLib()
163 : {
164 : // Default name and path of driver library
165 : const char* aszDefaultLibName[] = {
166 : "libmdbodbc.so",
167 : "libmdbodbc.so.0" /* for Ubuntu 8.04 support */
168 0 : };
169 0 : const int nLibNames = sizeof(aszDefaultLibName) / sizeof(aszDefaultLibName[0]);
170 : const char* libPath[] = {
171 : "/usr/lib",
172 : "/usr/local/lib"
173 0 : };
174 0 : const int nLibPaths = sizeof(libPath) / sizeof(libPath[0]);
175 :
176 0 : CPLString strLibPath("");
177 :
178 0 : const char* pszDrvCfg = CPLGetConfigOption("MDBDRIVER_PATH", NULL);
179 0 : if ( NULL != pszDrvCfg )
180 : {
181 : // Directory or file path
182 0 : strLibPath = pszDrvCfg;
183 :
184 0 : VSIStatBuf sStatBuf = { 0 };
185 0 : if ( VSIStat( pszDrvCfg, &sStatBuf ) == 0
186 : && VSI_ISDIR( sStatBuf.st_mode ) )
187 : {
188 : // Find default library in custom directory
189 0 : const char* pszDriverFile = CPLFormFilename( pszDrvCfg, aszDefaultLibName[0], NULL );
190 0 : CPLAssert( 0 != pszDriverFile );
191 :
192 0 : strLibPath = pszDriverFile;
193 : }
194 :
195 0 : if ( LibraryExists( strLibPath.c_str() ) )
196 : {
197 : // Save custom driver path
198 0 : osDriverFile = strLibPath;
199 0 : return true;
200 : }
201 : }
202 :
203 : // Try to find library in default path
204 0 : for ( int i = 0; i < nLibPaths; i++ )
205 : {
206 0 : for ( int j = 0; j < nLibNames; j++ )
207 : {
208 0 : const char* pszDriverFile = CPLFormFilename( libPath[i], aszDefaultLibName[j], NULL );
209 0 : CPLAssert( 0 != pszDriverFile );
210 :
211 0 : if ( LibraryExists( pszDriverFile ) )
212 : {
213 : // Save default driver path
214 0 : osDriverFile = pszDriverFile;
215 0 : return true;
216 : }
217 : }
218 : }
219 :
220 0 : CPLError(CE_Failure, CPLE_AppDefined, "PGeo: MDB Tools driver not found!\n");
221 : // Driver not found!
222 0 : return false;
223 : }
224 :
225 : /************************************************************************/
226 : /* LibraryExists() */
227 : /************************************************************************/
228 :
229 0 : bool OGRPGeoDriver::LibraryExists(const char* pszLibPath)
230 : {
231 0 : CPLAssert( 0 != pszLibPath );
232 :
233 0 : VSIStatBuf stb = { 0 } ;
234 :
235 0 : if ( 0 == VSIStat( pszLibPath, &stb ) )
236 : {
237 0 : if (VSI_ISREG( stb.st_mode ) || VSI_ISLNK(stb.st_mode))
238 : {
239 0 : return true;
240 : }
241 : }
242 :
243 0 : return false;
244 : }
245 :
246 : #endif /* ndef WIN32 */
247 : /*
248 : * END OF UNIX-only features
249 : */
250 :
251 : /************************************************************************/
252 : /* RegisterOGRODBC() */
253 : /************************************************************************/
254 :
255 80 : void RegisterOGRPGeo()
256 :
257 : {
258 80 : OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( new OGRPGeoDriver );
259 80 : }
260 :
|