// (c) COPYRIGHT URI/MIT 1997-1999
// Please read the full copyright statement in the file COPYRIGHT.
//
// Authors:
// jhrg,jimg James Gallagher (jgallagher@gso.uri.edu)
// This is the source to `geturl'; a simple tool to exercise the Connect
// class. It can be used to get naked URLs as well as the DODS DAS and DDS
// objects. jhrg.
#include "config_dap.h"
static char rcsid[] not_used = {"$Id: geturl.cc.html 11906 2005-08-08 19:51:43Z root $"};
#include < stdio.h >
#include < assert.h >
#include < GetOpt.h >
#include < string >
#include "Connect.h"
#ifdef WIN32
#define MAIN_RETURN void
#else
#define MAIN_RETURN int
#endif
using std::cerr;
using std::endl;
const char *version = "$Revision: 11906 $";
extern int keep_temps; // defined in Connect.cc
void
usage(string name)
{
cerr << "Usage: " << name
<< " [dDagVvk] [c ] [t ] [m ] [-T ] [ ...]" << endl
<< "[gVvk] [t ] [T ] [ ...]" << endl
<< endl
<< "In the first form of the command, dereference the URL" << endl
<< "perform the requested operations. This include routing" << endl
<< "the returned information through the DAP processing" << endl
<< "library (parsing the returned objects, et c.). If none" << endl
<< "of a, d, or D are used with a URL, then the DAP library" << endl
<< "routines are NOT used and the URLs contents are dumped" << endl
<< "to standard output." << endl
<< "In the second form of the command, assume the files are" << endl
<< "DODS data objects (stored in files or read from pipes)" << endl
<< "and process them as if -D were given. In this case the" << endl
<< "information *must* contain valid MIME header in order" << endl
<< "to be processed."
<< endl
<< "Options:" << endl
<< " d: For each URL, get the DODS DDS." << endl
<< " a: For each URL, get the DODS DAS." << endl
<< " D: For each URL, get the DODS Data." << endl
<< " g: Show the progress GUI." << endl
<< " v: Verbose." << endl
<< " V: Version." << endl
<< " c: is a contraint expression. Used with -D." << endl
<< " NB: You can use a `?' for the CE also." << endl
<< " k: Keep temporary files created by DODS core" << endl
<< " m: Request the same URL times." << endl
<< " z: Don't ask the server to compress data." << endl
<< " T: List of `Accepted Types'. Translating servers use this." << endl
<< " s: Print Sequences using numbered rows." << endl
<< endl
<< " t: trace output; use -tz for default." << endl
<< " a: show anchor trace." << endl
<< " A: show app trace." << endl
<< " b: show bind trace." << endl
<< " c: show cache trace." << endl
<< " h: show auth trace." << endl
<< " i: show pics trace." << endl
<< " k: show core trace." << endl
<< " l: show sgml trace." << endl
<< " m: show mem trace." << endl
<< " p: show protocol trace." << endl
<< " s: show stream trace." << endl
<< " t: show thread trace." << endl
<< " u: show uri trace." << endl
<< " U: show util trace." << endl
<< " x: show mux trace." << endl
<< " z: show all traces." << endl;
}
bool
read_data(FILE *fp)
{
char c;
if (!fp) {
cerr << "geturl: Whoa!!! Null stream pointer." << endl;
return false;
}
// Changed from a loop that used getc() to one that uses fread(). getc()
// worked fine for transfers of text information, but *not* for binary
// transfers. fread() will handle both.
while (fp && !feof(fp) && fread(&c, 1, 1, fp))
printf("%c", c); // stick with stdio
return true;
}
static void
process_data(Connect & url, DDS *dds, bool verbose = false,
bool print_rows = false)
{
switch (url.type()) {
case dods_error:
throw url.error();
return;
case web_error:
// Web errors (those reported in the return document's MIME header)
// are processed by the WWW library.
return;
case dods_data:
default: {
if (verbose)
cerr << "Server version: " << url.server_version() << endl;
cout << "The data:" << endl;
for (Pix q = dds->first_var(); q; dds->next_var(q)) {
BaseType *v = dds->var(q);
if (print_rows && v->type() == dods_sequence_c)
dynamic_cast(v)->print_val_by_rows(cout);
else
v->print_val(cout);
}
}
cout << endl;
}
}
MAIN_RETURN
main(int argc, char * argv[])
{
GetOpt getopt (argc, argv, "AdaDgVvkc:t:m:zT:s");
int option_char;
bool async = false;
bool get_das = false;
bool get_dds = false;
bool get_data = false;
bool gui = false;
bool cexpr = false;
bool verbose = false;
bool trace = false;
bool multi = false;
bool accept_deflate = true;
string accept_types = "All";
int times = 1;
char *tcode = NULL;
char *expr = ""; // can't use NULL or C++ string conversion will crash
int topts = 0;
bool print_rows = false;
#ifdef WIN32
_setmode(_fileno(stdout), _O_BINARY);
#endif
while ((option_char = getopt()) != EOF)
switch (option_char) {
case 'A': async = true; break;
case 'd': get_dds = true; break;
case 'a': get_das = true; break;
case 'D': get_data = true; break;
case 'V': cerr << "geturl version: " << version << endl; exit(0);
case 'v': verbose = true; break;
case 'g': gui = true; break;
case 'k': keep_temps =1; break; // keep_temp is in Connect.cc
case 'c':
cexpr = true; expr = getopt.optarg; break;
case 't':
trace = true;
topts = strlen(getopt.optarg);
if (topts) {
tcode = new char[topts + 1];
strcpy(tcode, getopt.optarg);
}
break;
case 'm': multi = true; times = atoi(getopt.optarg); break;
case 'z': accept_deflate = false; break;
case 'T': accept_types = getopt.optarg; break;
case 's': print_rows = true; break;
case 'h':
case '?':
default:
usage(argv[0]); exit(1); break;
}
char c, *cc = tcode;
if (trace && topts > 0)
while ((c = *cc++))
switch (c) {
case 'a': WWWTRACE |= SHOW_ANCHOR_TRACE; break;
case 'A': WWWTRACE |= SHOW_APP_TRACE; break;
case 'b': WWWTRACE |= SHOW_BIND_TRACE; break;
case 'c': WWWTRACE |= SHOW_CACHE_TRACE; break;
case 'h': WWWTRACE |= SHOW_AUTH_TRACE; break;
case 'i': WWWTRACE |= SHOW_PICS_TRACE; break;
case 'k': WWWTRACE |= SHOW_CORE_TRACE; break;
case 'l': WWWTRACE |= SHOW_SGML_TRACE; break;
case 'm': WWWTRACE |= SHOW_MEM_TRACE; break;
case 'p': WWWTRACE |= SHOW_PROTOCOL_TRACE; break;
case 's': WWWTRACE |= SHOW_STREAM_TRACE; break;
case 't': WWWTRACE |= SHOW_THREAD_TRACE; break;
case 'u': WWWTRACE |= SHOW_URI_TRACE; break;
case 'U': WWWTRACE |= SHOW_UTIL_TRACE; break;
case 'x': WWWTRACE |= SHOW_MUX_TRACE; break;
case 'z': WWWTRACE = SHOW_ALL_TRACE; break;
default:
cerr << "Unrecognized trace option: `" << c << "'" << endl;
break;
}>
delete[] tcode; tcode = 0;
// If after processing all the command line options there is nothing left
// (no URL or file) assume that we should read from stdin.
for (int i = getopt.optind; i < argc; ++i) {
if (verbose)
cerr << "Fetching: " << argv[i] << endl;
string name = argv[i];
Connect url(name, trace, accept_deflate);
url.set_accept_types(accept_types);
if (url.is_local()) {
if (verbose)
cerr << "Assuming that the argument " << argv[i]
<< " is a file" << endl
<< "that contains a DODS data object; decoding." << endl;
FILE *source;
if (strcmp(argv[i], "-") == 0)
source = stdin;
else
source = fopen(argv[i], "r");
if (!source) {
cerr << "The input source: " << argv[i]
<< " could not be opened." << endl;
break;
}
// NB: local access should never use the popup gui.
try {
DDS *dds = url.read_data(source, false, false);
process_data(url, dds, verbose, print_rows);
}
catch (Error &e) {
e.display_message(url.gui());
break;
if (source != stdin)
fclose(source);
}
else if (get_das) {
for (int j = 0; j < times; ++j) {
try {
if (!url.request_das(gui))
continue;
}
catch (Error &e) {
e.display_message(url.gui());
continue;
}
if (verbose) {
cerr << "Server version: " << url.server_version()
<< endl;
cerr << "DAS:" << endl;
}
url.das().print();
}
}
else if (get_dds) {
for (int j = 0; j < times; ++j) {
try {
if (!url.request_dds(gui))
continue;
}
catch (Error &e) {
e.display_message(url.gui());
continue; // Goto the next URL or exit the loop.
}
if (verbose) {
cerr << "Server version: " << url.server_version()
<< endl;
cerr << "DDS:" << endl;
}
url.dds().print();
}
}
else if (get_data) {
if (!(expr || name.find('?') != name.npos)) {
cerr << "Must supply a constraint expression with -D."
<< endl;
continue;
}
for (int j = 0; j < times; ++j) {
DDS *dds;
try {
dds = url.request_data(expr, gui, async);
if (!dds) {
cerr << "Error: " << url.error().error_message() << endl;
continue;
}
process_data(url, dds, verbose, print_rows);
delete dds; dds = 0;
}
catch (Error &e) {
e.display_message(url.gui());
}
}
}
else { // if (!get_das && !get_dds && !get_data) {
#ifdef GUI
url.gui()->show_gui(gui);
#endif
string url_string = argv[i];
for (int j = 0; j < times; ++j) {
try {
if (!url.fetch_url(url_string))
continue;
if (verbose)
cerr << "Server version: " << url.server_version()
<< endl;
FILE *fp = url.output();
if (!read_data(fp))
continue;
url.close_output();
}
catch (Error &e) {
e.display_message(url.gui());
continue;
}
}
}
}
exit(0); // Running DejaGun/Cygwin based test suites require this.
#ifdef WIN32
return; // Visual C++ asks for this.
#endif
}