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