1 : /******************************************************************************
2 : * $Id: ogrgeomediadriver.cpp 21545 2011-01-22 14:26:31Z 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 21545 2011-01-22 14:26:31Z rouault $");
35 :
36 : /************************************************************************/
37 : /* ~OGRODBCDriver() */
38 : /************************************************************************/
39 :
40 169 : OGRGeomediaDriver::~OGRGeomediaDriver()
41 :
42 : {
43 169 : }
44 :
45 : /************************************************************************/
46 : /* GetName() */
47 : /************************************************************************/
48 :
49 9992 : const char *OGRGeomediaDriver::GetName()
50 :
51 : {
52 9992 : return "Geomedia";
53 : }
54 :
55 : /************************************************************************/
56 : /* Open() */
57 : /************************************************************************/
58 :
59 62 : OGRDataSource *OGRGeomediaDriver::Open( const char * pszFilename,
60 : int bUpdate )
61 :
62 : {
63 : OGRGeomediaDataSource *poDS;
64 :
65 62 : if( !EQUALN(pszFilename,"GEOMEDIA:",9)
66 : && !EQUAL(CPLGetExtension(pszFilename),"mdb") )
67 61 : return NULL;
68 :
69 1 : if( !EQUALN(pszFilename,"GEOMEDIA:",9) &&
70 : EQUAL(CPLGetExtension(pszFilename),"mdb") )
71 : {
72 1 : VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
73 1 : if (!fp)
74 0 : return NULL;
75 1 : GByte* pabyHeader = (GByte*) CPLMalloc(100000);
76 1 : VSIFReadL(pabyHeader, 100000, 1, fp);
77 1 : VSIFCloseL(fp);
78 :
79 : /* Look for GAliasTable table */
80 1 : const GByte pabyNeedle[] = { 'G', 0, 'A', 0, 'l', 0, 'i', 0, 'a', 0, 's', 0, 'T', 0, 'a', 0, 'b', 0, 'l', 0, 'e'};
81 1 : int bFound = FALSE;
82 99980 : for(int i=0;i<100000 - (int)sizeof(pabyNeedle);i++)
83 : {
84 99979 : if (memcmp(pabyHeader + i, pabyNeedle, sizeof(pabyNeedle)) == 0)
85 : {
86 0 : bFound = TRUE;
87 0 : break;
88 : }
89 : }
90 1 : CPLFree(pabyHeader);
91 1 : if (!bFound)
92 1 : return NULL;
93 : }
94 :
95 : #ifndef WIN32
96 : // Try to register MDB Tools driver
97 : //
98 : // ODBCINST.INI NOTE:
99 : // This operation requires write access to odbcinst.ini file
100 : // located in directory pointed by ODBCINISYS variable.
101 : // Usually, it points to /etc, so non-root users can overwrite this
102 : // setting ODBCINISYS with location they have write access to, e.g.:
103 : // $ export ODBCINISYS=$HOME/etc
104 : // $ touch $ODBCINISYS/odbcinst.ini
105 : //
106 : // See: http://www.unixodbc.org/internals.html
107 : //
108 0 : if ( !InstallMdbDriver() )
109 : {
110 : CPLError( CE_Warning, CPLE_AppDefined,
111 0 : "Unable to install MDB driver for ODBC, MDB access may not supported.\n" );
112 : }
113 : else
114 0 : CPLDebug( "Geomedia", "MDB Tools driver installed successfully!");
115 :
116 : #endif /* ndef WIN32 */
117 :
118 : // Open data source
119 0 : poDS = new OGRGeomediaDataSource();
120 :
121 0 : if( !poDS->Open( pszFilename, bUpdate, TRUE ) )
122 : {
123 0 : delete poDS;
124 0 : return NULL;
125 : }
126 : else
127 0 : return poDS;
128 : }
129 :
130 : /************************************************************************/
131 : /* TestCapability() */
132 : /************************************************************************/
133 :
134 0 : int OGRGeomediaDriver::TestCapability( const char * pszCap )
135 :
136 : {
137 0 : return FALSE;
138 : }
139 :
140 :
141 : /*
142 : * START OF UNIX-only features.
143 : */
144 : #ifndef WIN32
145 :
146 : /************************************************************************/
147 : /* InstallMdbDriver() */
148 : /************************************************************************/
149 :
150 0 : bool OGRGeomediaDriver::InstallMdbDriver()
151 : {
152 0 : if ( !FindDriverLib() )
153 : {
154 0 : return false;
155 : }
156 : else
157 : {
158 0 : CPLAssert( !osDriverFile.empty() );
159 0 : CPLDebug( "Geomedia", "MDB Tools driver: %s", osDriverFile.c_str() );
160 :
161 0 : CPLString driverName("Microsoft Access Driver (*.mdb)");
162 0 : CPLString driver(driverName);
163 0 : driver += '\0';
164 0 : driver += "Driver=";
165 0 : driver += osDriverFile; // Found by FindDriverLib()
166 0 : driver += '\0';
167 0 : driver += "FileUsage=1";
168 0 : driver += '\0';
169 0 : driver += '\0';
170 :
171 : // Create installer and register driver
172 0 : CPLODBCDriverInstaller dri;
173 :
174 0 : if ( !dri.InstallDriver(driver.c_str(), 0, ODBC_INSTALL_COMPLETE) )
175 : {
176 : // Report ODBC error
177 0 : CPLError( CE_Failure, CPLE_AppDefined, "ODBC: %s", dri.GetLastError() );
178 0 : return false;
179 0 : }
180 : }
181 :
182 0 : return true;
183 : }
184 :
185 : /************************************************************************/
186 : /* FindDriverLib() */
187 : /************************************************************************/
188 :
189 0 : bool OGRGeomediaDriver::FindDriverLib()
190 : {
191 : // Default name and path of driver library
192 : const char* aszDefaultLibName[] = {
193 : "libmdbodbc.so",
194 : "libmdbodbc.so.0" /* for Ubuntu 8.04 support */
195 0 : };
196 0 : const int nLibNames = sizeof(aszDefaultLibName) / sizeof(aszDefaultLibName[0]);
197 : const char* libPath[] = {
198 : "/usr/lib",
199 : "/usr/local/lib"
200 0 : };
201 0 : const int nLibPaths = sizeof(libPath) / sizeof(libPath[0]);
202 :
203 0 : CPLString strLibPath("");
204 :
205 0 : const char* pszDrvCfg = CPLGetConfigOption("MDBDRIVER_PATH", NULL);
206 0 : if ( NULL != pszDrvCfg )
207 : {
208 : // Directory or file path
209 0 : strLibPath = pszDrvCfg;
210 :
211 0 : VSIStatBuf sStatBuf = { 0 };
212 0 : if ( VSIStat( pszDrvCfg, &sStatBuf ) == 0
213 : && VSI_ISDIR( sStatBuf.st_mode ) )
214 : {
215 : // Find default library in custom directory
216 0 : const char* pszDriverFile = CPLFormFilename( pszDrvCfg, aszDefaultLibName[0], NULL );
217 0 : CPLAssert( 0 != pszDriverFile );
218 :
219 0 : strLibPath = pszDriverFile;
220 : }
221 :
222 0 : if ( LibraryExists( strLibPath.c_str() ) )
223 : {
224 : // Save custom driver path
225 0 : osDriverFile = strLibPath;
226 0 : return true;
227 : }
228 : }
229 :
230 : // Try to find library in default path
231 0 : for ( int i = 0; i < nLibPaths; i++ )
232 : {
233 0 : for ( int j = 0; j < nLibNames; j++ )
234 : {
235 0 : const char* pszDriverFile = CPLFormFilename( libPath[i], aszDefaultLibName[j], NULL );
236 0 : CPLAssert( 0 != pszDriverFile );
237 :
238 0 : if ( LibraryExists( pszDriverFile ) )
239 : {
240 : // Save default driver path
241 0 : osDriverFile = pszDriverFile;
242 0 : return true;
243 : }
244 : }
245 : }
246 :
247 0 : CPLError(CE_Failure, CPLE_AppDefined, "Geomedia: MDB Tools driver not found!\n");
248 : // Driver not found!
249 0 : return false;
250 : }
251 :
252 : /************************************************************************/
253 : /* LibraryExists() */
254 : /************************************************************************/
255 :
256 0 : bool OGRGeomediaDriver::LibraryExists(const char* pszLibPath)
257 : {
258 0 : CPLAssert( 0 != pszLibPath );
259 :
260 0 : VSIStatBuf stb = { 0 } ;
261 :
262 0 : if ( 0 == VSIStat( pszLibPath, &stb ) )
263 : {
264 0 : if (VSI_ISREG( stb.st_mode ) || VSI_ISLNK(stb.st_mode))
265 : {
266 0 : return true;
267 : }
268 : }
269 :
270 0 : return false;
271 : }
272 :
273 : #endif /* ndef WIN32 */
274 : /*
275 : * END OF UNIX-only features
276 : */
277 :
278 : /************************************************************************/
279 : /* RegisterOGRODBC() */
280 : /************************************************************************/
281 :
282 178 : void RegisterOGRGeomedia()
283 :
284 : {
285 178 : OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( new OGRGeomediaDriver );
286 178 : }
287 :
|