cgi_util.cc

Go to the documentation of this file.
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //         Reza Nekovei <rnekovei@intcomm.net>
00010 //
00011 // This library is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU Lesser General Public
00013 // License as published by the Free Software Foundation; either
00014 // version 2.1 of the License, or (at your option) any later version.
00015 //
00016 // This library is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 //
00025 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00026 
00027 // (c) COPYRIGHT URI/MIT 1994-2001
00028 // Please read the full copyright statement in the file COPYRIGHT_URI.
00029 //
00030 // Authors:
00031 //      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>
00032 //      reza            Reza Nekovei <rnekovei@intcomm.net>
00033 
00034 // A few useful routines which are used in CGI programs.
00035 //
00036 // ReZa 9/30/94
00037 
00038 #include "config.h"
00039 
00040 static char rcsid[] not_used =
00041     {"$Id: cgi_util.cc 20518 2009-03-05 23:39:46Z jimg $"
00042     };
00043 
00044 #include <cstring>
00045 #include <cstdio>
00046 #include <ctype.h>
00047 
00048 #ifndef TM_IN_SYS_TIME
00049 #include <time.h>
00050 #else
00051 #include <sys/time.h>
00052 #endif
00053 
00054 #include <sys/types.h>
00055 #include <sys/stat.h>
00056 
00057 #ifndef WIN32
00058 #include <unistd.h>    // for access
00059 #include <sys/wait.h>
00060 #else
00061 #include <io.h>
00062 #include <fcntl.h>
00063 #include <process.h>
00064 // Win32 does not define this. 08/21/02 jhrg
00065 #define F_OK 0
00066 #endif
00067 
00068 #include <iostream>
00069 #include <sstream>
00070 #include <fstream>
00071 #include <string>
00072 
00073 #include "cgi_util.h"
00074 #include "Ancillary.h"
00075 #include "util.h"  // This supplies flush_stream for WIN32.
00076 #include "debug.h"
00077 
00078 
00079 #ifdef WIN32
00080 #define FILE_DELIMITER '\\'
00081 #else  //  default to unix
00082 #define FILE_DELIMITER '/'
00083 #endif
00084 
00085 // ...not using a const string here to avoid global objects. jhrg 12/23/05
00086 #define CRLF "\r\n"             // Change here and in expr-test.cc.
00087 
00088 using namespace std;
00089 
00090 namespace libdap {
00091 
00092 static const int TimLen = 26; // length of string from asctime()
00093 static const int CLUMP_SIZE = 1024; // size of clumps to new in fmakeword()
00094 
00108 bool
00109 do_version(const string &script_ver, const string &dataset_ver)
00110 {
00111     fprintf(stdout, "HTTP/1.0 200 OK%s", CRLF) ;
00112     fprintf(stdout, "XDODS-Server: %s%s", DVR, CRLF) ;
00113     fprintf(stdout, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00114     fprintf(stdout, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00115     fprintf(stdout, "Content-Type: text/plain%s", CRLF) ;
00116     fprintf(stdout, CRLF) ;
00117 
00118     fprintf(stdout, "Core software version: %s%s", DVR, CRLF) ;
00119 
00120     if (script_ver != "")
00121         fprintf(stdout, "Server Script Revision: %s%s", script_ver.c_str(), CRLF) ;
00122 
00123     if (dataset_ver != "")
00124         fprintf(stdout,  "Dataset version: %s%s", dataset_ver.c_str(), CRLF) ;
00125 
00126     fflush(stdout) ;            // Not sure this is needed. jhrg 12/23/05
00127 
00128     return true;
00129 }
00130 
00140 void
00141 ErrMsgT(const string &Msgt)
00142 {
00143     time_t TimBin;
00144     char TimStr[TimLen];
00145 
00146     if (time(&TimBin) == (time_t) - 1)
00147         strncpy(TimStr, "time() error           ", TimLen-1);
00148     else {
00149         strncpy(TimStr, ctime(&TimBin), TimLen-1);
00150         TimStr[TimLen - 2] = '\0'; // overwrite the \n
00151     }
00152 
00153 #if 0
00154         // This was removed because writing these values out 'leaks' system information.
00155         // Since we're not going to write out the script or host, I also removed the
00156         // calls to getenv(). jhrg 8/7/2007
00157     const char *host_or_addr = getenv("REMOTE_HOST") ? getenv("REMOTE_HOST") :
00158                                getenv("REMOTE_ADDR") ? getenv("REMOTE_ADDR") : "local (a non-CGI run)";
00159     const char *script = getenv("SCRIPT_NAME") ? getenv("SCRIPT_NAME") :
00160                          "OPeNDAP server";
00161 
00162     cerr << "[" << TimStr << "] CGI: " << script << " failed for "
00163          << host_or_addr << ": " << Msgt << endl;
00164 #endif
00165     cerr << "[" << TimStr << "] DAP server error: " << Msgt << endl;
00166 }
00167 
00168 // Given a pathname, return just the filename component with any extension
00169 // removed. The new string resides in newly allocated memory; the caller must
00170 // delete it when done using the filename.
00171 // Originally from the netcdf distribution (ver 2.3.2).
00172 //
00173 // *** Change to string class argument and return type. jhrg
00174 // *** Changed so it also removes the#path#of#the#file# from decompressed
00175 //     files.  rph.
00176 // Returns: A filename, with path and extension information removed. If
00177 // memory for the new name cannot be allocated, does not return!
00178 
00189 string
00190 name_path(const string &path)
00191 {
00192     if (path == "")
00193         return string("");
00194 
00195     string::size_type delim = path.find_last_of(FILE_DELIMITER);
00196     string::size_type pound = path.find_last_of("#");
00197     string new_path;
00198 
00199     if (pound != string::npos)
00200         new_path = path.substr(pound + 1);
00201     else
00202         new_path = path.substr(delim + 1);
00203 
00204     return new_path;
00205 }
00206 
00207 // Return a MIME rfc-822 date. The grammar for this is:
00208 //       date-time   =  [ day "," ] date time        ; dd mm yy
00209 //                                                   ;  hh:mm:ss zzz
00210 //
00211 //       day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
00212 //                   /  "Fri"  / "Sat" /  "Sun"
00213 //
00214 //       date        =  1*2DIGIT month 2DIGIT        ; day month year
00215 //                                                   ;  e.g. 20 Jun 82
00216 //                   NB: year is 4 digit; see RFC 1123. 11/30/99 jhrg
00217 //
00218 //       month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
00219 //                   /  "May"  /  "Jun" /  "Jul"  /  "Aug"
00220 //                   /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"
00221 //
00222 //       time        =  hour zone                    ; ANSI and Military
00223 //
00224 //       hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
00225 //                                                   ; 00:00:00 - 23:59:59
00226 //
00227 //       zone        =  "UT"  / "GMT"                ; Universal Time
00228 //                                                   ; North American : UT
00229 //                   /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
00230 //                   /  "CST" / "CDT"                ;  Central:  - 6/ - 5
00231 //                   /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
00232 //                   /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
00233 //                   /  1ALPHA                       ; Military: Z = UT;
00234 //                                                   ;  A:-1; (J not used)
00235 //                                                   ;  M:-12; N:+1; Y:+12
00236 //                   / ( ("+" / "-") 4DIGIT )        ; Local differential
00237 //                                                   ;  hours+min. (HHMM)
00238 
00239 static const char *days[] =
00240     {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00241     };
00242 static const char *months[] =
00243     {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
00244      "Aug", "Sep", "Oct", "Nov", "Dec"
00245     };
00246 
00247 #ifdef _MSC_VER
00248 #define snprintf sprintf_s
00249 #endif
00250 
00258 string
00259 rfc822_date(const time_t t)
00260 {
00261     struct tm *stm = gmtime(&t);
00262     char d[256];
00263 
00264     snprintf(d, 255, "%s, %02d %s %4d %02d:%02d:%02d GMT", days[stm->tm_wday],
00265             stm->tm_mday, months[stm->tm_mon],
00266             1900 + stm->tm_year,
00267             stm->tm_hour, stm->tm_min, stm->tm_sec);
00268     d[255] = '\0';
00269     return string(d);
00270 }
00271 
00277 time_t
00278 last_modified_time(const string &name)
00279 {
00280     struct stat m;
00281 
00282     if (stat(name.c_str(), &m) == 0 && (S_IFREG & m.st_mode))
00283         return m.st_mtime;
00284     else
00285         return time(0);
00286 }
00287 
00288 // Send string to set the transfer (mime) type and server version
00289 // Note that the content description filed is used to indicate whether valid
00290 // information of an error message is contained in the document and the
00291 // content-encoding field is used to indicate whether the data is compressed.
00292 // If the data stream is to be compressed, arrange for a compression output
00293 // filter so that all information sent after the header will be compressed.
00294 //
00295 // Returns: false if the compression output filter was to be used but could
00296 // not be started, true otherwise.
00297 
00298 static const char *descrip[] =
00299     {"unknown", "dods_das", "dods_dds", "dods_data",
00300      "dods_error", "web_error", "dap4_ddx", "dap4_datax", "dap4_errorx"
00301     };
00302 static const char *encoding[] =
00303     {"unknown", "deflate", "x-plain"
00304     };
00305 
00318 void
00319 set_mime_text(FILE *out, ObjectType type, const string &ver,
00320               EncodingType enc, const time_t last_modified)
00321 {
00322     fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
00323     if (ver == "") {
00324         fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00325         fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00326     }
00327     else {
00328         fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
00329         fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
00330     }
00331     fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00332 
00333     const time_t t = time(0);
00334     fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00335 
00336     fprintf(out, "Last-Modified: ") ;
00337     if (last_modified > 0)
00338         fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
00339     else
00340         fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
00341 
00342     if (type == dap4_ddx)
00343         fprintf(out, "Content-Type: text/xml%s", CRLF) ;
00344     else
00345         fprintf(out, "Content-Type: text/plain%s", CRLF) ;
00346 
00347     // Note that Content-Description is from RFC 2045 (MIME, pt 1), not 2616.
00348     // jhrg 12/23/05
00349     fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
00350     if (type == dods_error) // don't cache our error responses.
00351         fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
00352     // Don't write a Content-Encoding header for x-plain since that breaks
00353     // Netscape on NT. jhrg 3/23/97
00354     if (enc != x_plain)
00355         fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
00356     fprintf(out, CRLF) ;
00357 }
00358 
00371 void
00372 set_mime_text(ostream &strm, ObjectType type, const string &ver,
00373               EncodingType enc, const time_t last_modified)
00374 {
00375     strm << "HTTP/1.0 200 OK" << CRLF ;
00376     if (ver == "") {
00377         strm << "XDODS-Server: " << DVR << CRLF ;
00378         strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00379     }
00380     else {
00381         strm << "XDODS-Server: " << ver.c_str() << CRLF ;
00382         strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
00383     }
00384     strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00385 
00386     const time_t t = time(0);
00387     strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00388 
00389     strm << "Last-Modified: " ;
00390     if (last_modified > 0)
00391         strm << rfc822_date(last_modified).c_str() << CRLF ;
00392     else
00393         strm << rfc822_date(t).c_str() << CRLF ;
00394 
00395     if (type == dap4_ddx)
00396         strm << "Content-Type: text/xml" << CRLF ;
00397     else
00398         strm << "Content-Type: text/plain" << CRLF ;
00399 
00400     // Note that Content-Description is from RFC 2045 (MIME, pt 1), not 2616.
00401     // jhrg 12/23/05
00402     strm << "Content-Description: " << descrip[type] << CRLF ;
00403     if (type == dods_error) // don't cache our error responses.
00404         strm << "Cache-Control: no-cache" << CRLF ;
00405     // Don't write a Content-Encoding header for x-plain since that breaks
00406     // Netscape on NT. jhrg 3/23/97
00407     if (enc != x_plain)
00408         strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00409     strm << CRLF ;
00410 }
00411 
00422 void
00423 set_mime_html(FILE *out, ObjectType type, const string &ver,
00424               EncodingType enc, const time_t last_modified)
00425 {
00426     fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
00427     if (ver == "") {
00428         fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00429         fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00430     }
00431     else {
00432         fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
00433         fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
00434     }
00435     fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00436 
00437     const time_t t = time(0);
00438     fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00439 
00440     fprintf(out, "Last-Modified: ") ;
00441     if (last_modified > 0)
00442         fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
00443     else
00444         fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
00445 
00446     fprintf(out, "Content-type: text/html%s", CRLF) ;
00447     // See note above about Content-Description header. jhrg 12/23/05
00448     fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
00449     if (type == dods_error) // don't cache our error responses.
00450         fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
00451     // Don't write a Content-Encoding header for x-plain since that breaks
00452     // Netscape on NT. jhrg 3/23/97
00453     if (enc != x_plain)
00454         fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
00455     fprintf(out, CRLF) ;
00456 }
00457 
00468 void
00469 set_mime_html(ostream &strm, ObjectType type, const string &ver,
00470               EncodingType enc, const time_t last_modified)
00471 {
00472     strm << "HTTP/1.0 200 OK" << CRLF ;
00473     if (ver == "") {
00474         strm << "XDODS-Server: " << DVR << CRLF ;
00475         strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00476     }
00477     else {
00478         strm << "XDODS-Server: " << ver.c_str() << CRLF ;
00479         strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
00480     }
00481     strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00482 
00483     const time_t t = time(0);
00484     strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00485 
00486     strm << "Last-Modified: " ;
00487     if (last_modified > 0)
00488         strm << rfc822_date(last_modified).c_str() << CRLF ;
00489     else
00490         strm << rfc822_date(t).c_str() << CRLF ;
00491 
00492     strm << "Content-type: text/html" << CRLF ;
00493     // See note above about Content-Description header. jhrg 12/23/05
00494     strm << "Content-Description: " << descrip[type] << CRLF ;
00495     if (type == dods_error) // don't cache our error responses.
00496         strm << "Cache-Control: no-cache" << CRLF ;
00497     // Don't write a Content-Encoding header for x-plain since that breaks
00498     // Netscape on NT. jhrg 3/23/97
00499     if (enc != x_plain)
00500         strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00501     strm << CRLF ;
00502 }
00503 
00517 void
00518 set_mime_binary(FILE *out, ObjectType type, const string &ver,
00519                 EncodingType enc, const time_t last_modified)
00520 {
00521     fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
00522     if (ver == "") {
00523         fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00524         fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00525     }
00526     else {
00527         fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
00528         fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
00529     }
00530     fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00531 
00532     const time_t t = time(0);
00533     fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00534 
00535     fprintf(out, "Last-Modified: ") ;
00536     if (last_modified > 0)
00537         fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
00538     else
00539         fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
00540 
00541     fprintf(out, "Content-Type: application/octet-stream%s", CRLF) ;
00542     fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
00543     if (enc != x_plain)
00544         fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
00545 
00546     fprintf(out, CRLF) ;
00547 }
00548 
00562 void
00563 set_mime_binary(ostream &strm, ObjectType type, const string &ver,
00564                 EncodingType enc, const time_t last_modified)
00565 {
00566     strm << "HTTP/1.0 200 OK" << CRLF ;
00567     if (ver == "") {
00568         strm << "XDODS-Server: " << DVR << CRLF ;
00569         strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00570     }
00571     else {
00572         strm << "XDODS-Server: " << ver.c_str() << CRLF ;
00573         strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
00574     }
00575     strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00576 
00577     const time_t t = time(0);
00578     strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00579 
00580     strm << "Last-Modified: " ;
00581     if (last_modified > 0)
00582         strm << rfc822_date(last_modified).c_str() << CRLF ;
00583     else
00584         strm << rfc822_date(t).c_str() << CRLF ;
00585 
00586     strm << "Content-Type: application/octet-stream" << CRLF ;
00587     strm << "Content-Description: " << descrip[type] << CRLF ;
00588     if (enc != x_plain)
00589         strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00590 
00591     strm << CRLF ;
00592 }
00593 
00594 
00601 void
00602 set_mime_error(FILE *out, int code, const string &reason,
00603                const string &version)
00604 {
00605     fprintf(out, "HTTP/1.0 %d %s%s", code, reason.c_str(), CRLF) ;
00606     if (version == "") {
00607         fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00608         fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00609     }
00610     else {
00611         fprintf(out, "XDODS-Server: %s%s", version.c_str(), CRLF) ;
00612         fprintf(out, "XOPeNDAP-Server: %s%s", version.c_str(), CRLF) ;
00613     }
00614     fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00615 
00616     const time_t t = time(0);
00617     fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00618     fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
00619     fprintf(out, CRLF) ;
00620 }
00621 
00628 void
00629 set_mime_error(ostream &strm, int code, const string &reason,
00630                const string &version)
00631 {
00632     strm << "HTTP/1.0 " << code << " " << reason.c_str() << CRLF ;
00633     if (version == "") {
00634         strm << "XDODS-Server: " << DVR << CRLF ;
00635         strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00636     }
00637     else {
00638         strm << "XDODS-Server: " << version.c_str() << CRLF ;
00639         strm << "XOPeNDAP-Server: " << version.c_str() << CRLF ;
00640     }
00641     strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00642 
00643     const time_t t = time(0);
00644     strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00645     strm << "Cache-Control: no-cache" << CRLF ;
00646     strm << CRLF ;
00647 }
00648 
00649 
00656 void
00657 set_mime_not_modified(FILE *out)
00658 {
00659     fprintf(out, "HTTP/1.0 304 NOT MODIFIED%s", CRLF) ;
00660     const time_t t = time(0);
00661     fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00662     fprintf(out, CRLF) ;
00663 }
00664 
00671 void
00672 set_mime_not_modified(ostream &strm)
00673 {
00674     strm << "HTTP/1.0 304 NOT MODIFIED" << CRLF ;
00675     const time_t t = time(0);
00676     strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00677     strm << CRLF ;
00678 }
00679 
00688 bool
00689 found_override(string name, string &doc)
00690 {
00691     ifstream ifs((name + ".ovr").c_str());
00692     if (!ifs)
00693         return false;
00694 
00695     char tmp[256];
00696     doc = "";
00697     while (!ifs.eof()) {
00698         ifs.getline(tmp, 255);
00699         strcat(tmp, "\n");
00700         doc += tmp;
00701     }
00702 
00703         ifs.close();
00704     return true;
00705 }
00706 
00715 bool
00716 remove_mime_header(FILE *in)
00717 {
00718     char tmp[256];
00719     while (!feof(in)) {
00720         char *s = fgets(tmp, 255, in);
00721         if (s && strncmp(s, CRLF, 2) == 0)
00722             return true;
00723     }
00724 
00725     return false;
00726 }
00727 
00728 
00751 string
00752 get_user_supplied_docs(string name, string cgi)
00753 {
00754     char tmp[256];
00755     ostringstream oss;
00756     ifstream ifs((cgi + ".html").c_str());
00757 
00758     if (ifs) {
00759         while (!ifs.eof()) {
00760             ifs.getline(tmp, 255);
00761             oss << tmp << "\n";
00762         }
00763         ifs.close();
00764 
00765         oss << "<hr>";
00766     }
00767 
00768     // Problem: This code is run with the CWD as the CGI-BIN directory but
00769     // the data are in DocumentRoot (and we don't have the pathname of the
00770     // data relative to DocumentRoot). So the only time this will work is
00771     // when the server is in the same directory as the data. See bug 815.
00772     // 10/08/04 jhrg
00773     ifs.open((name + ".html").c_str());
00774 
00775     // If name.html cannot be opened, look for basename.html
00776     if (!ifs) {
00777         string new_name = Ancillary::find_group_ancillary_file(name, ".html");
00778         if (new_name != "")
00779             ifs.open(new_name.c_str());
00780     }
00781 
00782     if (ifs) {
00783         while (!ifs.eof()) {
00784             ifs.getline(tmp, 255);
00785             oss << tmp << "\n";
00786         }
00787         ifs.close();
00788     }
00789 
00790     return oss.str();
00791 }
00792 
00793 } // namespace libdap
00794 

Generated on Mon May 18 10:25:02 2009 for libdap++ by  doxygen 1.4.7