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