Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Utilities
4 : * Purpose: Command line application to list info about a file.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : * ****************************************************************************
8 : * Copyright (c) 1998, Frank Warmerdam
9 : * Copyright (c) 2007-2015, Even Rouault <even.rouault at spatialys.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 "gdal_version.h"
31 : #include "gdal.h"
32 : #include "cpl_string.h"
33 : #include "cpl_multiproc.h"
34 : #include "commonutils.h"
35 : #include "gdal_utils_priv.h"
36 :
37 : /************************************************************************/
38 : /* GDALExit() */
39 : /* This function exits and cleans up GDAL and OGR resources */
40 : /* Perhaps it should be added to C api and used in all apps? */
41 : /************************************************************************/
42 :
43 14 : static int GDALExit(int nCode)
44 : {
45 14 : const char *pszDebug = CPLGetConfigOption("CPL_DEBUG", nullptr);
46 14 : if (pszDebug && (EQUAL(pszDebug, "ON") || EQUAL(pszDebug, "")))
47 : {
48 0 : GDALDumpOpenDatasets(stderr);
49 0 : CPLDumpSharedList(nullptr);
50 : }
51 :
52 14 : GDALDestroyDriverManager();
53 :
54 14 : OGRCleanupAll();
55 :
56 14 : exit(nCode);
57 : }
58 :
59 : /************************************************************************/
60 : /* Usage() */
61 : /************************************************************************/
62 :
63 0 : static void Usage()
64 :
65 : {
66 0 : fprintf(stderr, "%s\n", GDALInfoAppGetParserUsage().c_str());
67 0 : GDALExit(1);
68 0 : }
69 :
70 : /************************************************************************/
71 : /* main() */
72 : /************************************************************************/
73 :
74 76 : MAIN_START(argc, argv)
75 :
76 : {
77 76 : EarlySetConfigOptions(argc, argv);
78 :
79 : /* -------------------------------------------------------------------- */
80 : /* Register standard GDAL drivers, and process generic GDAL */
81 : /* command options. */
82 : /* -------------------------------------------------------------------- */
83 :
84 76 : GDALAllRegister();
85 76 : argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
86 76 : if (argc < 1)
87 14 : GDALExit(-argc);
88 :
89 : /* -------------------------------------------------------------------- */
90 : /* Parse command line */
91 : /* -------------------------------------------------------------------- */
92 :
93 62 : GDALInfoOptionsForBinary sOptionsForBinary;
94 :
95 : std::unique_ptr<GDALInfoOptions, decltype(&GDALInfoOptionsFree)> psOptions{
96 62 : GDALInfoOptionsNew(argv + 1, &sOptionsForBinary), GDALInfoOptionsFree};
97 59 : CSLDestroy(argv);
98 :
99 59 : if (!psOptions)
100 : {
101 0 : Usage();
102 : }
103 :
104 : /* -------------------------------------------------------------------- */
105 : /* Open dataset. */
106 : /* -------------------------------------------------------------------- */
107 : #ifdef __AFL_HAVE_MANUAL_CONTROL
108 : int iIter = 0;
109 : while (__AFL_LOOP(1000))
110 : {
111 : iIter++;
112 : #endif
113 :
114 59 : GDALDatasetH hDataset = GDALOpenEx(
115 : sOptionsForBinary.osFilename.c_str(),
116 : GDAL_OF_READONLY | GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR,
117 : sOptionsForBinary.aosAllowedInputDrivers,
118 59 : sOptionsForBinary.aosOpenOptions, nullptr);
119 :
120 59 : if (hDataset == nullptr)
121 : {
122 : #ifdef __AFL_HAVE_MANUAL_CONTROL
123 : continue;
124 : #else
125 : VSIStatBuf sStat;
126 5 : CPLString message;
127 : message.Printf("gdalinfo failed - unable to open '%s'.",
128 5 : sOptionsForBinary.osFilename.c_str());
129 5 : if (VSIStat(sOptionsForBinary.osFilename.c_str(), &sStat) == 0)
130 : {
131 : GDALDriverH drv =
132 4 : GDALIdentifyDriverEx(sOptionsForBinary.osFilename.c_str(),
133 : GDAL_OF_VECTOR, nullptr, nullptr);
134 4 : if (drv)
135 : {
136 1 : message += " Did you intend to call ogrinfo?";
137 : }
138 : }
139 5 : fprintf(stderr, "%s\n", message.c_str());
140 :
141 : /* --------------------------------------------------------------------
142 : */
143 : /* If argument is a VSIFILE, then print its contents */
144 : /* --------------------------------------------------------------------
145 : */
146 10 : if (STARTS_WITH(sOptionsForBinary.osFilename.c_str(), "/vsizip/") ||
147 5 : STARTS_WITH(sOptionsForBinary.osFilename.c_str(), "/vsitar/"))
148 : {
149 0 : const char *const apszOptions[] = {"NAME_AND_TYPE_ONLY=YES",
150 : nullptr};
151 0 : VSIDIR *psDir = VSIOpenDir(sOptionsForBinary.osFilename.c_str(), -1,
152 : apszOptions);
153 0 : if (psDir)
154 : {
155 0 : fprintf(stdout,
156 : "Unable to open source `%s' directly.\n"
157 : "The archive contains several files:\n",
158 : sOptionsForBinary.osFilename.c_str());
159 0 : int nCount = 0;
160 0 : while (auto psEntry = VSIGetNextDirEntry(psDir))
161 : {
162 0 : if (VSI_ISDIR(psEntry->nMode) && psEntry->pszName[0] &&
163 0 : psEntry->pszName[strlen(psEntry->pszName) - 1] != '/')
164 : {
165 0 : fprintf(stdout, " %s/%s/\n",
166 : sOptionsForBinary.osFilename.c_str(),
167 0 : psEntry->pszName);
168 : }
169 : else
170 : {
171 0 : fprintf(stdout, " %s/%s\n",
172 : sOptionsForBinary.osFilename.c_str(),
173 0 : psEntry->pszName);
174 : }
175 0 : nCount++;
176 0 : if (nCount == 100)
177 : {
178 0 : fprintf(stdout, "[...trimmed...]\n");
179 0 : break;
180 : }
181 0 : }
182 0 : VSICloseDir(psDir);
183 : }
184 : }
185 :
186 5 : GDALDumpOpenDatasets(stderr);
187 :
188 5 : GDALDestroyDriverManager();
189 :
190 5 : CPLDumpSharedList(nullptr);
191 :
192 5 : exit(1);
193 : #endif
194 : }
195 :
196 : /* --------------------------------------------------------------------
197 : */
198 : /* Read specified subdataset if requested. */
199 : /* --------------------------------------------------------------------
200 : */
201 54 : if (sOptionsForBinary.nSubdataset > 0)
202 : {
203 0 : char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS");
204 0 : int nSubdatasets = CSLCount(papszSubdatasets);
205 :
206 0 : if (nSubdatasets > 0 &&
207 0 : sOptionsForBinary.nSubdataset <= nSubdatasets)
208 : {
209 : char szKeyName[1024];
210 : char *pszSubdatasetName;
211 :
212 0 : snprintf(szKeyName, sizeof(szKeyName), "SUBDATASET_%d_NAME",
213 : sOptionsForBinary.nSubdataset);
214 0 : szKeyName[sizeof(szKeyName) - 1] = '\0';
215 : pszSubdatasetName =
216 0 : CPLStrdup(CSLFetchNameValue(papszSubdatasets, szKeyName));
217 0 : GDALClose(hDataset);
218 0 : hDataset = GDALOpen(pszSubdatasetName, GA_ReadOnly);
219 0 : CPLFree(pszSubdatasetName);
220 : }
221 : else
222 : {
223 0 : fprintf(stderr,
224 : "gdalinfo warning: subdataset %d of %d requested. "
225 : "Reading the main dataset.\n",
226 : sOptionsForBinary.nSubdataset, nSubdatasets);
227 : }
228 : }
229 :
230 54 : char *pszGDALInfoOutput = GDALInfo(hDataset, psOptions.get());
231 :
232 54 : if (pszGDALInfoOutput)
233 54 : printf("%s", pszGDALInfoOutput);
234 :
235 54 : CPLFree(pszGDALInfoOutput);
236 :
237 54 : GDALClose(hDataset);
238 : #ifdef __AFL_HAVE_MANUAL_CONTROL
239 : }
240 : #endif
241 :
242 54 : GDALDumpOpenDatasets(stderr);
243 :
244 54 : GDALDestroyDriverManager();
245 :
246 54 : CPLDumpSharedList(nullptr);
247 :
248 54 : GDALDestroy();
249 :
250 54 : exit(0);
251 : }
252 :
253 0 : MAIN_END
|