1
/* $Id: Cache.cpp,v 1.12 2004/08/20 02:42:45 terpstra Exp $
3
* Cache.h - Helper which transforms xml -> html and caches files
5
* Copyright (C) 2002 - Wesley W. Terpstra
9
* Authors: 'Wesley W. Terpstra' <wesley@terpstra.ca>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; version 2.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#define _XOPEN_SOURCE 500
26
#define _FILE_OFFSET_BITS 64
37
class streambug : public std::streambuf
42
void set_target(FILE* t) { target = t; }
50
char buf[128]; //8192];
53
streambug::streambug()
56
setp(&buf[0], &buf[sizeof(buf)-1]);
57
setg(0,0,0); // output only
60
int streambug::overflow(int c)
64
// Make sure there is a put area
65
if (!pptr()) setp(&buf[0], &buf[sizeof(buf)-1]);
67
// Determine how many characters have been
68
// inserted but not consumed.
69
std::streamsize w = pptr() - pbase();
71
// If c is not EOF it is a character that must
75
// We always leave space
80
// consume characters.
81
if ((std::streamsize)fwrite(pbase(), 1, w, target) == w)
82
{ // Set up put area. Be sure that there
83
// is space at end for one extra character.
85
setp(&buf[0], &buf[sizeof(buf)-1]);
87
if (c == EOF) return 0;
99
if (pptr() && pptr() > pbase())
100
{ // Flush waiting output
101
return overflow(EOF);
107
Cache::Cache(const Config& cfg, const string& command, const string& parameter, const string& ext)
108
: bug(new streambug), o(bug)
110
if (chdir(command.c_str()) != 0)
112
cout << "Status: 200 OK\r\n";
113
cout << "Content-Type: text/html\r\n\r\n";
114
cout << error(_("Entering command dir"), command + ":" + strerror(errno),
115
_("Perhaps the directory does not exist to which "
116
"the cache file is being written."));
122
cache = fopen(parameter.c_str(), "w+");
125
cout << "Status: 200 OK\r\n";
126
cout << "Content-Type: text/html\r\n\r\n";
127
cout << error(_("Creating cache file"), parameter + ":" + strerror(errno),
128
_("Perhaps the user which runs lurker.cgi does not have write "
129
"permissions to this directory."));
138
cout << "Status: 200 OK\r\n";
142
if (cache != stdout) sprintf(buf, " >&%d", fileno(cache));
143
string command = cfg.xslt + buf;
145
output = popen(command.c_str(), "w");
148
cout << "Content-Type: text/html\r\n\r\n";
149
cout << error(_("Opening xslt pipeline"), strerror(errno),
150
_("The specified xslt pipeline in your config "
151
"file, entry xslt, could not be opened. "
152
"Please ensure that the command correctly "
153
"streams xml into html for you."));
157
cout << "Content-Type: text/html; charset=UTF-8\r\n\r\n";
159
else if (ext == "txt")
161
cout << "Content-Type: text/plain\r\n\r\n";
164
else if (ext == "rfc822")
166
cout << "Content-Type: message/rfc822\r\n\r\n";
169
else if (ext == "xml")
171
cout << "Content-Type: text/xml; charset=UTF-8\r\n\r\n";
176
cout << "Content-Type: text/html\r\n\r\n";
177
cout << error(_("Unknown file type"), ext,
178
_("The requested extension is not supported by lurker. "
179
"Please reformulate your request."));
183
cout.flush(); // in case of stdout writing next (ick)
184
bug->set_target(output);
196
// reset to the start of the cache file
198
fseek(cache, 0, SEEK_SET);
201
// Begin streaming to cout
205
while ((got = fread(buf, 1, sizeof(buf), cache)) != 0)
206
cout.write(buf, got);