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