00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "config.h"
00037
00038 static char rcsid[] not_used =
00039 { "$Id: getdap.cc 18315 2008-03-03 20:14:44Z jimg $"
00040 };
00041
00042 #ifdef WIN32
00043 #include <io.h>
00044 #include <fcntl.h>
00045 #endif
00046
00047 #include <GetOpt.h>
00048 #include <cstring>
00049 #include <string>
00050
00051 #include "AISConnect.h"
00052 #include "Response.h"
00053 #include "StdinResponse.h"
00054
00055 using std::cerr;
00056 using std::endl;
00057
00058 using namespace libdap ;
00059
00060 const char *version = CVER " (" DVR " DAP/" DAP_PROTOCOL_VERSION ")";
00061
00062 extern int libdap::dods_keep_temps;
00063
00064 void usage(string name)
00065 {
00066 cerr << "Usage: " << name << endl;
00067 cerr <<
00068 " [idDaxAVvks] [-B <db>][-c <expr>][-m <num>] <url> [<url> ...]" <<
00069 endl;
00070 cerr << " [Vvks] <file> [<file> ...]" << endl;
00071 cerr << endl;
00072 cerr << "In the first form of the command, dereference the URL and"
00073 << endl;
00074 cerr << "perform the requested operations. This includes routing" <<
00075 endl;
00076 cerr << "the returned information through the DAP processing" << endl;
00077 cerr << "library (parsing the returned objects, et c.). If none" <<
00078 endl;
00079 cerr << "of a, d, or D are used with a URL, then the DAP library" <<
00080 endl;
00081 cerr << "routines are NOT used and the URLs contents are dumped" <<
00082 endl;
00083 cerr << "to standard output." << endl;
00084 cerr << endl;
00085 cerr << "In the second form of the command, assume the files are" <<
00086 endl;
00087 cerr << "DataDDS objects (stored in files or read from pipes)" << endl;
00088 cerr << "and process them as if -D were given. In this case the" <<
00089 endl;
00090 cerr << "information *must* contain valid MIME header in order" <<
00091 endl;
00092 cerr << "to be processed." << endl;
00093 cerr << endl;
00094 cerr << "Options:" << endl;
00095 cerr << " i: For each URL, get the server version." << endl;
00096 cerr << " d: For each URL, get the the DDS." << endl;
00097 cerr << " a: For each URL, get the the DAS." << endl;
00098 cerr << " A: Use the AIS for DAS objects." << endl;
00099 cerr << " D: For each URL, get the the DataDDS." << endl;
00100 cerr <<
00101 " x: For each URL, get the DDX object. Does not get data."
00102 << endl;
00103 cerr << " X: Build a DDX in getdap using the DDS and DAS." << endl;
00104 cerr << " B: <AIS xml dataBase>. Overrides .dodsrc." << endl;
00105 cerr << " v: Verbose." << endl;
00106 cerr << " V: Version." << endl;
00107 cerr << " c: <expr> is a contraint expression. Used with -D." <<
00108 endl;
00109 cerr << " NB: You can use a `?' for the CE also." << endl;
00110 cerr << " k: Keep temporary files created by libdap core\n" <<
00111 endl;
00112 cerr << " m: Request the same URL <num> times." << endl;
00113 cerr << " z: Ask the server to compress data." << endl;
00114 cerr << " s: Print Sequences using numbered rows." << endl;
00115 }
00116
00117 bool read_data(FILE * fp)
00118 {
00119 if (!fp) {
00120 fprintf(stderr, "getdap: Whoa!!! Null stream pointer.\n");
00121 return false;
00122 }
00123
00124
00125
00126 char c;
00127 while (fp && !feof(fp) && fread(&c, 1, 1, fp))
00128 printf("%c", c);
00129
00130 return true;
00131 }
00132
00133 static void print_data(DDS & dds, bool print_rows = false)
00134 {
00135 fprintf(stdout, "The data:\n");
00136
00137 for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++) {
00138 BaseType *v = *i;
00139 if (print_rows && (*i)->type() == dods_sequence_c)
00140 dynamic_cast < Sequence * >(*i)->print_val_by_rows(stdout);
00141 else
00142 v->print_val(stdout);
00143 }
00144
00145 fprintf(stdout, "\n");
00146 fflush(stdout);
00147 }
00148
00149 int main(int argc, char *argv[])
00150 {
00151 GetOpt getopt(argc, argv, "idaDxXAVvkB:c:m:zsh?H");
00152 int option_char;
00153
00154 bool get_das = false;
00155 bool get_dds = false;
00156 bool get_data = false;
00157 bool get_ddx = false;
00158 bool build_ddx = false;
00159 bool get_version = false;
00160 bool cexpr = false;
00161 bool verbose = false;
00162 bool multi = false;
00163 bool accept_deflate = false;
00164 bool print_rows = false;
00165 bool use_ais = false;
00166 int times = 1;
00167 string expr = "";
00168 string ais_db = "";
00169
00170 #ifdef WIN32
00171 _setmode(_fileno(stdout), _O_BINARY);
00172 #endif
00173
00174 while ((option_char = getopt()) != EOF)
00175 switch (option_char) {
00176 case 'd':
00177 get_dds = true;
00178 break;
00179 case 'a':
00180 get_das = true;
00181 break;
00182 case 'D':
00183 get_data = true;
00184 break;
00185 case 'x':
00186 get_ddx = true;
00187 break;
00188 case 'X':
00189 build_ddx = true;
00190 break;
00191 case 'A':
00192 use_ais = true;
00193 break;
00194 case 'V':
00195 fprintf(stderr, "getdap version: %s\n", version);
00196 exit(0);
00197 case 'i':
00198 get_version = true;
00199 break;
00200 case 'v':
00201 verbose = true;
00202 break;
00203 case 'k':
00204 dods_keep_temps = 1;
00205 break;
00206 case 'c':
00207 cexpr = true;
00208 expr = getopt.optarg;
00209 break;
00210 case 'm':
00211 multi = true;
00212 times = atoi(getopt.optarg);
00213 break;
00214 case 'B':
00215 use_ais = true;
00216 ais_db = getopt.optarg;
00217 break;
00218 case 'z':
00219 accept_deflate = true;
00220 break;
00221 case 's':
00222 print_rows = true;
00223 break;
00224 case 'h':
00225 case '?':
00226 default:
00227 usage(argv[0]);
00228 exit(1);
00229 break;
00230 }
00231
00232 try {
00233
00234
00235 for (int i = getopt.optind; i < argc; ++i) {
00236 if (verbose)
00237 fprintf(stderr, "Fetching: %s\n", argv[i]);
00238
00239 string name = argv[i];
00240 Connect *url = 0;
00241 if (use_ais) {
00242 if (!ais_db.empty())
00243 url = new AISConnect(name, ais_db);
00244 else
00245 url = new AISConnect(name);
00246 }
00247 else {
00248 url = new Connect(name);
00249 }
00250
00251
00252 if (accept_deflate)
00253 url->set_accept_deflate(accept_deflate);
00254
00255 if (url->is_local()) {
00256 if (verbose) {
00257 fprintf(stderr,
00258 "Assuming that the argument %s is a file that contains a DAP2 data object; decoding.\n", argv[i]);
00259 }
00260
00261 Response *r = 0;
00262 BaseTypeFactory factory;
00263 DataDDS dds(&factory);
00264
00265 try {
00266 if (strcmp(argv[i], "-") == 0) {
00267 r = new StdinResponse(stdin);
00268
00269 if (!r->get_stream())
00270 throw Error("Could not open standard input.");
00271
00272 url->read_data(dds, r);
00273 }
00274 else {
00275 r = new Response(fopen(argv[i], "r"), 0);
00276
00277 if (!r->get_stream())
00278 throw Error(string("The input source: ")
00279 + string(argv[i])
00280 + string(" could not be opened"));
00281
00282 url->read_data_no_mime(dds, r);
00283 }
00284 }
00285 catch (Error & e) {
00286 cerr << e.get_error_message() << endl;
00287 delete r;
00288 r = 0;
00289 delete url;
00290 url = 0;
00291 break;
00292 }
00293
00294 if (verbose)
00295 fprintf(stderr, "DAP version: %s, Server version: %s\n",
00296 url->get_protocol().c_str(),
00297 url->get_version().c_str());
00298
00299 print_data(dds, print_rows);
00300
00301 }
00302
00303 else if (get_version) {
00304 fprintf(stderr, "DAP version: %s, Server version: %s\n",
00305 url->request_protocol().c_str(),
00306 url->get_version().c_str());
00307 }
00308
00309 else if (get_das) {
00310 for (int j = 0; j < times; ++j) {
00311 DAS das;
00312 try {
00313 url->request_das(das);
00314 }
00315 catch (Error & e) {
00316 cerr << e.get_error_message() << endl;
00317 delete url;
00318 url = 0;
00319 continue;
00320 }
00321
00322 if (verbose) {
00323 fprintf(stderr, "DAP version: %s, Server version: %s\n",
00324 url->get_protocol().c_str(),
00325 url->get_version().c_str());
00326
00327 fprintf(stderr, "DAS:\n");
00328 }
00329
00330 das.print(stdout);
00331 }
00332 }
00333
00334 else if (get_dds) {
00335 for (int j = 0; j < times; ++j) {
00336 BaseTypeFactory factory;
00337 DDS dds(&factory);
00338 try {
00339 url->request_dds(dds, expr);
00340 }
00341 catch (Error & e) {
00342 cerr << e.get_error_message() << endl;
00343 delete url;
00344 url = 0;
00345 continue;
00346 }
00347
00348 if (verbose) {
00349 fprintf(stderr, "DAP version: %s, Server version: %s\n",
00350 url->get_protocol().c_str(),
00351 url->get_version().c_str());
00352
00353 fprintf(stderr, "DDS:\n");
00354 }
00355
00356 dds.print(stdout);
00357 }
00358 }
00359
00360 else if (get_ddx) {
00361 for (int j = 0; j < times; ++j) {
00362 BaseTypeFactory factory;
00363 DDS dds(&factory);
00364 try {
00365 url->request_ddx(dds, expr);
00366 }
00367 catch (Error & e) {
00368 cerr << e.get_error_message() << endl;
00369 continue;
00370 }
00371
00372 if (verbose) {
00373 fprintf(stderr, "DAP version: %s, Server version: %s\n",
00374 url->get_protocol().c_str(),
00375 url->get_version().c_str());
00376
00377 fprintf(stderr, "DDX:\n");
00378 }
00379
00380 dds.print_xml(stdout, false, "getdap; no blob yet");
00381 }
00382 }
00383
00384 else if (build_ddx) {
00385 for (int j = 0; j < times; ++j) {
00386 BaseTypeFactory factory;
00387 DDS dds(&factory);
00388 try {
00389 url->request_dds(dds);
00390 DAS das;
00391 url->request_das(das);
00392 dds.transfer_attributes(&das);
00393 }
00394 catch (Error & e) {
00395 cerr << e.get_error_message() << endl;
00396 continue;
00397 }
00398
00399 if (verbose) {
00400 fprintf(stderr, "DAP version: %s, Server version: %s\n",
00401 url->get_protocol().c_str(),
00402 url->get_version().c_str());
00403
00404 fprintf(stderr, "Client-built DDX:\n");
00405 }
00406
00407 dds.print_xml(stdout, false, "getdap; no blob yet");
00408 }
00409 }
00410
00411 else if (get_data) {
00412 #if 0
00413 if (expr.empty() && name.find('?') == string::npos)
00414 expr = "";
00415 #endif
00416 for (int j = 0; j < times; ++j) {
00417 BaseTypeFactory factory;
00418 DataDDS dds(&factory);
00419 try {
00420 DBG(cerr << "URL: " << url->URL(false) << endl);
00421 DBG(cerr << "CE: " << expr << endl);
00422 url->request_data(dds, expr);
00423
00424 if (verbose)
00425 fprintf(stderr, "DAP version: %s, Server version: %s\n",
00426 url->get_protocol().c_str(),
00427 url->get_version().c_str());
00428
00429 print_data(dds, print_rows);
00430 }
00431 catch (Error & e) {
00432 cerr << e.get_error_message() << endl;
00433 delete url;
00434 url = 0;
00435 continue;
00436 }
00437 }
00438 }
00439
00440 else {
00441
00442
00443
00444
00445
00446 HTTPConnect http(RCReader::instance());
00447
00448
00449 if (accept_deflate)
00450 http.set_accept_deflate(accept_deflate);
00451
00452 string url_string = argv[i];
00453 for (int j = 0; j < times; ++j) {
00454 try {
00455 Response *r = http.fetch_url(url_string);
00456 if (!read_data(r->get_stream())) {
00457 continue;
00458 }
00459 delete r;
00460 r = 0;
00461 }
00462 catch (Error & e) {
00463 cerr << e.get_error_message() << endl;
00464 continue;
00465 }
00466 }
00467 }
00468
00469 delete url;
00470 url = 0;
00471 }
00472 }
00473 catch (Error &e) {
00474 cerr << e.get_error_message() << endl;
00475 return 1;
00476 }
00477 catch (exception &e) {
00478 cerr << "C++ library exception: " << e.what() << endl;
00479 return 1;
00480 }
00481
00482 return 0;
00483 }