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