Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Simple client for viewing OGR driver data. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 1999, Frank Warmerdam 9 : * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #include "cpl_port.h" 15 : 16 : #include "gdal_version.h" 17 : #include "gdal_priv.h" 18 : #include "gdal_utils_priv.h" 19 : #include "ogr_p.h" 20 : 21 : #include "commonutils.h" 22 : 23 : /************************************************************************/ 24 : /* Usage() */ 25 : /************************************************************************/ 26 : 27 1 : static void Usage() 28 : { 29 1 : fprintf(stderr, "%s\n", GDALVectorInfoGetParserUsage().c_str()); 30 1 : exit(1); 31 : } 32 : 33 : /************************************************************************/ 34 : /* main() */ 35 : /************************************************************************/ 36 : 37 59 : MAIN_START(argc, argv) 38 : 39 : { 40 : // Check strict compilation and runtime library version as we use C++ API. 41 59 : if (!GDAL_CHECK_VERSION(argv[0])) 42 0 : exit(1); 43 : 44 59 : EarlySetConfigOptions(argc, argv); 45 : 46 59 : OGRRegisterAll(); 47 : 48 59 : argc = OGRGeneralCmdLineProcessor(argc, &argv, 0); 49 59 : if (argc < 1) 50 12 : exit(-argc); 51 : 52 : auto psOptionsForBinary = 53 47 : std::make_unique<GDALVectorInfoOptionsForBinary>(); 54 : 55 : GDALVectorInfoOptions *psOptions = 56 47 : GDALVectorInfoOptionsNew(argv + 1, psOptionsForBinary.get()); 57 44 : if (psOptions == nullptr) 58 1 : Usage(); 59 : 60 : /* -------------------------------------------------------------------- */ 61 : /* Open dataset. */ 62 : /* -------------------------------------------------------------------- */ 63 : #ifdef __AFL_HAVE_MANUAL_CONTROL 64 : int iIter = 0; 65 : while (__AFL_LOOP(1000)) 66 : { 67 : iIter++; 68 : #endif 69 : /* -------------------------------------------------------------------- 70 : */ 71 : /* Open data source. */ 72 : /* -------------------------------------------------------------------- 73 : */ 74 43 : int nFlags = GDAL_OF_VECTOR; 75 43 : bool bMayRetryUpdateMode = false; 76 43 : if (psOptionsForBinary->bUpdate) 77 0 : nFlags |= GDAL_OF_UPDATE | GDAL_OF_VERBOSE_ERROR; 78 43 : else if (psOptionsForBinary->bReadOnly) 79 7 : nFlags |= GDAL_OF_READONLY | GDAL_OF_VERBOSE_ERROR; 80 36 : else if (psOptionsForBinary->osSQLStatement.empty()) 81 : { 82 33 : nFlags |= GDAL_OF_READONLY; 83 : // GDALIdentifyDriverEx() might emit an error message, e.g. 84 : // when opening "/vsizip/foo.zip/" and the zip has more than one 85 : // file. Cf https://github.com/OSGeo/gdal/issues/9459 86 66 : CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler); 87 33 : if (GDALIdentifyDriverEx( 88 33 : psOptionsForBinary->osFilename.c_str(), GDAL_OF_VECTOR, 89 66 : psOptionsForBinary->aosAllowInputDrivers.List(), nullptr)) 90 : { 91 29 : bMayRetryUpdateMode = true; 92 : } 93 : else 94 : { 95 : // And an error Will be emitted 96 4 : nFlags |= GDAL_OF_VERBOSE_ERROR; 97 : } 98 : } 99 : else 100 3 : nFlags |= GDAL_OF_UPDATE | GDAL_OF_VERBOSE_ERROR; 101 43 : GDALDataset *poDS = GDALDataset::Open( 102 43 : psOptionsForBinary->osFilename.c_str(), nFlags, 103 43 : psOptionsForBinary->aosAllowInputDrivers.List(), 104 43 : psOptionsForBinary->aosOpenOptions.List(), nullptr); 105 : 106 48 : if (poDS == nullptr && !psOptionsForBinary->bReadOnly && 107 5 : !psOptionsForBinary->bUpdate) 108 : { 109 5 : if (psOptionsForBinary->osSQLStatement.empty() && 110 : bMayRetryUpdateMode) 111 : { 112 : // In some cases (empty geopackage for example), opening in 113 : // read-only mode fails, so retry in update mode 114 1 : poDS = GDALDataset::Open( 115 1 : psOptionsForBinary->osFilename.c_str(), 116 : GDAL_OF_UPDATE | GDAL_OF_VECTOR, 117 1 : psOptionsForBinary->aosAllowInputDrivers.List(), 118 1 : psOptionsForBinary->aosOpenOptions.List(), nullptr); 119 : } 120 4 : else if (!psOptionsForBinary->osSQLStatement.empty()) 121 : { 122 0 : poDS = GDALDataset::Open( 123 0 : psOptionsForBinary->osFilename.c_str(), 124 : GDAL_OF_READONLY | GDAL_OF_VECTOR, 125 0 : psOptionsForBinary->aosAllowInputDrivers.List(), 126 0 : psOptionsForBinary->aosOpenOptions.List(), nullptr); 127 0 : if (poDS != nullptr && psOptionsForBinary->bVerbose) 128 : { 129 0 : printf("Had to open data source read-only.\n"); 130 : #ifdef __AFL_HAVE_MANUAL_CONTROL 131 : psOptionsForBinary->bReadOnly = true; 132 : #endif 133 : } 134 : } 135 : } 136 : 137 43 : int nRet = 0; 138 43 : if (poDS == nullptr) 139 : { 140 4 : nRet = 1; 141 : 142 : VSIStatBuf sStat; 143 8 : CPLString message; 144 : message.Printf("ogrinfo failed - unable to open '%s'.", 145 4 : psOptionsForBinary->osFilename.c_str()); 146 4 : if (VSIStat(psOptionsForBinary->osFilename.c_str(), &sStat) == 0) 147 : { 148 : GDALDriverH drv = 149 3 : GDALIdentifyDriverEx(psOptionsForBinary->osFilename.c_str(), 150 : GDAL_OF_RASTER, nullptr, nullptr); 151 3 : if (drv) 152 : { 153 2 : message += " Did you intend to call gdalinfo?"; 154 : } 155 : } 156 4 : fprintf(stderr, "%s\n", message.c_str()); 157 : } 158 : else 159 : { 160 : char *pszGDALVectorInfoOutput = 161 39 : GDALVectorInfo(GDALDataset::ToHandle(poDS), psOptions); 162 : 163 39 : if (pszGDALVectorInfoOutput) 164 38 : printf("%s", pszGDALVectorInfoOutput); 165 : else 166 1 : nRet = 1; 167 : 168 39 : CPLFree(pszGDALVectorInfoOutput); 169 : } 170 : 171 43 : delete poDS; 172 : #ifdef __AFL_HAVE_MANUAL_CONTROL 173 : } 174 : #endif 175 : 176 43 : GDALVectorInfoOptionsFree(psOptions); 177 : 178 43 : CSLDestroy(argv); 179 : 180 43 : GDALDumpOpenDatasets(stderr); 181 : 182 43 : GDALDestroyDriverManager(); 183 : 184 43 : CPLDumpSharedList(nullptr); 185 43 : GDALDestroy(); 186 : 187 43 : exit(nRet); 188 : } 189 : 190 0 : MAIN_END