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: util.cc 16731 2007-06-22 18:56:39Z jimg $"
00040 };
00041
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <assert.h>
00045 #include <ctype.h>
00046 #ifndef TM_IN_SYS_TIME
00047 #include <time.h>
00048 #else
00049 #include <sys/time.h>
00050 #endif
00051
00052 #ifndef WIN32
00053 #include <unistd.h>
00054 #else
00055 #include <io.h>
00056 #include <fcntl.h>
00057 #include <process.h>
00058 #endif
00059
00060 #include <sys/types.h>
00061 #include <sys/stat.h>
00062
00063 #include <string>
00064 #include <sstream>
00065 #include <vector>
00066 #include <algorithm>
00067 #include <stdexcept>
00068
00069 #include "BaseType.h"
00070 #include "Str.h"
00071 #include "Url.h"
00072 #include "Sequence.h"
00073 #include "Error.h"
00074 #include "parser.h"
00075 #include "util.h"
00076 #include "debug.h"
00077
00078
00079 using namespace std;
00080
00081
00082
00083
00092 string
00093 prune_spaces(const string &name)
00094 {
00095
00096 if (name.find_first_of(' ') == name.npos)
00097 return name;
00098 else {
00099
00100 unsigned int i = name.find_first_not_of(' ');
00101 string tmp_name = name.substr(i);
00102
00103
00104 unsigned int j = tmp_name.find('?') + 1;
00105 i = tmp_name.find_first_not_of(' ', j);
00106 tmp_name.erase(j, i - j);
00107
00108 return tmp_name;
00109 }
00110 }
00111
00112
00113
00114
00115 bool
00116 unique_names(vector<BaseType *> l, const string &var_name,
00117 const string &type_name, string &msg)
00118 {
00119
00120 vector<string> names(l.size());
00121
00122 int nelem = 0;
00123 typedef std::vector<BaseType *>::const_iterator citer ;
00124 for (citer i = l.begin(); i != l.end(); i++) {
00125 assert(*i);
00126 names[nelem++] = (*i)->name();
00127 DBG(cerr << "NAMES[" << nelem - 1 << "]=" << names[nelem-1] << endl);
00128 }
00129
00130
00131 sort(names.begin(), names.end());
00132
00133 #ifdef DODS_DEBUG2
00134 cout << "unique:" << endl;
00135 for (int ii = 0; ii < nelem; ++ii)
00136 cout << "NAMES[" << ii << "]=" << names[ii] << endl;
00137 #endif
00138
00139
00140 sort(names.begin(), names.end());
00141
00142 #ifdef DODS_DEBUG2
00143 cout << "unique:" << endl;
00144 for (int ii = 0; ii < nelem; ++ii)
00145 cout << "NAMES[" << ii << "]=" << names[ii] << endl;
00146 #endif
00147
00148
00149 for (int j = 1; j < nelem; ++j) {
00150 if (names[j-1] == names[j]) {
00151 ostringstream oss;
00152 oss << "The variable `" << names[j]
00153 << "' is used more than once in " << type_name << " `"
00154 << var_name << "'";
00155 msg = oss.str();
00156
00157 return false;
00158 }
00159 }
00160
00161 return true;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171 #ifndef __POWERPC__
00172 XDR *
00173 new_xdrstdio(FILE *stream, enum xdr_op xop)
00174 {
00175 XDR *xdr = new XDR;
00176
00177 xdrstdio_create(xdr, stream, xop);
00178
00179 return xdr;
00180 }
00181
00182 XDR *
00183 set_xdrstdio(XDR *xdr, FILE *stream, enum xdr_op xop)
00184 {
00185 xdrstdio_create(xdr, stream, xop);
00186
00187 return xdr;
00188 }
00189
00190
00191
00192
00193 void
00194 delete_xdrstdio(XDR *xdr)
00195 {
00196 xdr_destroy(xdr);
00197
00198 delete xdr; xdr = 0;
00199 }
00200 #endif
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 extern "C" bool_t
00218 xdr_str(XDR *xdrs, string &buf)
00219 {
00220 DBG(cerr << "In xdr_str, xdrs: " << xdrs << endl);
00221
00222 switch (xdrs->x_op) {
00223 case XDR_ENCODE: {
00224 const char *out_tmp = buf.c_str();
00225
00226 return xdr_string(xdrs, (char **)&out_tmp, max_str_len);
00227 }
00228
00229 case XDR_DECODE: {
00230 char *in_tmp = NULL;
00231
00232 bool_t stat = xdr_string(xdrs, &in_tmp, max_str_len);
00233 if (!stat)
00234 return stat;
00235
00236 buf = in_tmp;
00237
00238 free(in_tmp);
00239
00240 return stat;
00241 }
00242
00243 default:
00244 assert(false);
00245 return 0;
00246 }
00247 }
00248
00249 const char *
00250 libdap_root()
00251 {
00252 char *libdap_root = 0;
00253 return ((libdap_root = getenv("LIBDAP_ROOT")) ? libdap_root : LIBDAP_ROOT);
00254 }
00255
00256 extern "C"
00257 const char *
00258 libdap_version()
00259 {
00260 return PACKAGE_VERSION;
00261 }
00262
00263 extern "C"
00264 const char *
00265 libdap_name()
00266 {
00267 return PACKAGE_NAME;
00268 }
00269
00270
00271
00272
00273
00274 #if COMPRESSION_FOR_SERVER3
00275
00276
00277
00278
00279
00280
00281
00282
00283 bool
00284 deflate_exists()
00285 {
00286 DBG(cerr << "Entering deflate_exists...");
00287
00288 int status = false;
00289 struct stat buf;
00290
00291 #ifdef WIN32
00292 string deflate = (string)libdap_root() + "\\bin\\deflate";
00293 #else
00294 string deflate = (string)libdap_root() + "/sbin/deflate";
00295 #endif
00296
00297
00298
00299
00300
00301
00302 status = (stat(deflate.c_str(), &buf) == 0)
00303 #ifdef WIN32
00304 || (stat(".\\deflate", &buf) == 0);
00305 #else
00306 || (stat("./deflate", &buf) == 0);
00307 #endif
00308
00309
00310 #ifdef WIN32
00311 status &= (buf.st_mode & _S_IEXEC);
00312 #else
00313 status &= buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH);
00314 #endif
00315 DBG(cerr << " returning " << (status ? "true." : "false.") << endl);
00316 return (status != 0);
00317 }
00318
00319 FILE *
00320 compressor(FILE *output, int &childpid)
00321 {
00322 #ifdef WIN32
00323
00324
00325
00326 int pid, data[2];
00327 int hStdIn, hStdOut;
00328
00329 if (_pipe(data, 512, O_BINARY | O_NOINHERIT) < 0) {
00330 cerr << "Could not create IPC channel for compressor process"
00331 << endl;
00332 return NULL;
00333 }
00334
00335
00336
00337
00338
00339
00340 hStdIn = _dup(_fileno(stdin));
00341 hStdOut = _dup(_fileno(stdout));
00342
00343
00344 if (_dup2(data[0], _fileno(stdin)) != 0) {
00345 cerr << "dup of child stdin failed" << endl;
00346 return NULL;
00347 }
00348
00349 if (_dup2(_fileno(output), _fileno(stdout)) != 0) {
00350 cerr << "dup of child stdout failed" << endl;
00351 return NULL;
00352 }
00353
00354
00355 string deflate = "deflate.exe";
00356 if ((pid = _spawnlp(_P_NOWAIT, deflate.c_str(), deflate.c_str(),
00357 "-c", "5", "-s", NULL)) < 0) {
00358 cerr << "Could not spawn to create compressor process" << endl;
00359 return NULL;
00360 }
00361
00362
00363 if (_dup2(hStdIn, _fileno(stdin)) != 0) {
00364 cerr << "dup of stdin failed" << endl;
00365 return NULL;
00366 }
00367 if (_dup2(hStdOut, _fileno(stdout)) != 0) {
00368 cerr << "dup of stdout failed" << endl;
00369 return NULL;
00370 }
00371 close(hStdIn);
00372 close(hStdOut);
00373
00374
00375
00376 close(data[0]);
00377 FILE *input = fdopen(data[1], "w");
00378 setbuf(input, 0);
00379 childpid = pid;
00380 return input;
00381
00382 #else
00383 FILE *ret_file = NULL ;
00384
00385 int pid, data[2];
00386
00387 if (pipe(data) < 0) {
00388 cerr << "Could not create IPC channel for compressor process"
00389 << endl;
00390 return NULL;
00391 }
00392
00393 if ((pid = fork()) < 0) {
00394 cerr << "Could not fork to create compressor process" << endl;
00395 return NULL;
00396 }
00397
00398
00399
00400
00401
00402 if (pid > 0) {
00403 close(data[0]);
00404 ret_file = fdopen(data[1], "w");
00405 setbuf(ret_file, 0);
00406 childpid = pid;
00407 }
00408 else {
00409 close(data[1]);
00410 dup2(data[0], 0);
00411 dup2(fileno(output), 1);
00412
00413 DBG(cerr << "Opening compression stream." << endl);
00414
00415
00416
00417
00418 string deflate = (string)libdap_root() + "/sbin/deflate";
00419 (void) execl(deflate.c_str(), "deflate", "-c", "5", "-s", NULL);
00420 (void) execl("./deflate", "deflate", "-c", "5", "-s", NULL);
00421 cerr << "Warning: Could not start compressor!" << endl;
00422 cerr << "defalte should be in DODS_ROOT/etc or in the CWD!"
00423 << endl;
00424 _exit(127);
00425 }
00426
00427 return ret_file ;
00428 #endif
00429 }
00430
00431 #endif // COMPRESSION_FOR_SERVER3
00432
00433
00434
00435
00436 string
00437 systime()
00438 {
00439 time_t TimBin;
00440
00441 if (time(&TimBin) == (time_t) - 1)
00442 return string("time() error");
00443 else {
00444 string TimStr = ctime(&TimBin);
00445 return TimStr.substr(0, TimStr.size() - 2);
00446 }
00447 }
00448
00449 void
00450 downcase(string &s)
00451 {
00452 for (unsigned int i = 0; i < s.length(); i++)
00453 s[i] = tolower(s[i]);
00454 }
00455
00456 #ifdef WIN32
00457
00458
00459
00460
00461
00462 void flush_stream(iostream ios, FILE *out)
00463 {
00464 int nbytes;
00465 char buffer[512];
00466
00467 ios.get(buffer, 512, NULL);
00468 while ((nbytes = ios.gcount()) > 0) {
00469 fwrite(buffer, 1, nbytes, out);
00470 ios.get(buffer, 512, NULL);
00471 }
00472
00473 return;
00474 }
00475 #endif
00476
00477
00478 void
00479 append_long_to_string(long val, int base, string &str_val)
00480 {
00481
00482
00483
00484 char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00485
00486 ldiv_t r;
00487
00488 if (base > 36 || base < 2) {
00489
00490 std::invalid_argument ex("The parameter base has an invalid value.");
00491 throw ex;
00492 }
00493 if (val < 0)
00494 str_val += '-';
00495 r = ldiv(labs(val), base);
00496
00497
00498 if (r.quot > 0)
00499 append_long_to_string(r.quot, base, str_val);
00500
00501
00502
00503 str_val += digits[(int)r.rem];
00504 }
00505
00506
00507 string
00508 long_to_string(long val, int base)
00509 {
00510 string s;
00511 append_long_to_string(val, base, s);
00512 return s;
00513 }
00514
00515
00516 void append_double_to_string(const double &num, string &str)
00517 {
00518
00519
00520 ostringstream oss;
00521 oss.precision(9);
00522 oss << num;
00523 str += oss.str();
00524 }
00525
00526 string
00527 double_to_string(const double &num)
00528 {
00529 string s;
00530 append_double_to_string(num, s);
00531 return s;
00532 }
00533
00534
00535
00536
00537 string
00538 dap_version()
00539 {
00540 return (string)"OPeNDAP DAP/" + libdap_version() + ": compiled on " + __DATE__ + ":" + __TIME__ ;
00541 }
00542
00543
00544
00545
00546
00547
00548
00549 #ifdef WIN32
00550 static const char path_sep[] =
00551 {"\\"
00552 };
00553 #else
00554 static const char path_sep[] =
00555 {"/"
00556 };
00557 #endif
00558
00559 string
00560 path_to_filename(string path)
00561 {
00562 string::size_type pos = path.rfind(path_sep);
00563
00564 return (pos == string::npos) ? path : path.substr(++pos);
00565 }
00566
00567
00568
00569
00570
00571
00572
00573
00574 char *
00575 get_tempfile_template(char *file_template)
00576 {
00577 char *c;
00578 #ifdef WIN32
00579 if (getenv("TEMP") && (access(getenv("TEMP"), 6) == 0))
00580 c = getenv("TEMP");
00581 else if (getenv("TMP"))
00582 c = getenv("TMP");
00583 #else
00584 if (getenv("TMPDIR") && (access(getenv("TMPDIR"), W_OK | R_OK) == 0))
00585 c = getenv("TMPDIR");
00586 #ifdef P_tmpdir
00587 else if (access(P_tmpdir, W_OK | R_OK) == 0)
00588 c = P_tmpdir;
00589 #endif
00590 #endif
00591 else
00592 c = ".";
00593
00594 char *temp = new char[strlen(c) + strlen(file_template) + 2];
00595 strcpy(temp, c);
00596 strcat(temp, "/");
00597
00598 strcat(temp, file_template);
00599
00600 return temp;
00601 }
00602
00608 #ifndef WIN32
00609 FILE *
00610 get_temp_file(char *temp)
00611 {
00612 int fd = mkstemp(temp);
00613 if (fd < 0)
00614 return 0;
00615 FILE *tmp = fdopen(fd, "a+");
00616 return tmp;
00617 }
00618 #endif
00619
00624 string
00625 file_to_string(FILE *fp)
00626 {
00627 rewind(fp);
00628 ostringstream oss;
00629 char c;
00630 while (fread(&c, 1, 1, fp))
00631 oss << c;
00632 return oss.str();
00633 }