Viewing file:
webmlmdmod.C (6.18 KB) -rw-rw-rw-Select action/file-type:

(
+) |

(
+) |

(
+) |
Code (
+) |
Session (
+) |

(
+) |
SDB (
+) |

(
+) |

(
+) |

(
+) |

(
+) |

(
+) |
/*
**
** Copyright 2007 Double Precision, Inc.
** See COPYING for distribution information.
*/
#include "config.h"
#include "webmlmd.H"
#include "webmlmdhandlers.H"
#include "webmlmdcmlm.H"
#include "cmlm.h"
#include "cmlmsublist.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <cctype>
#include <algorithm>
#include "mydirent.h"
#include "cgi/cgi.h"
#include "rfc2045/rfc2045.h"
#include <stdio.h>
extern "C" {
#include "webmail/msg2html.h"
}
static int cmpmodfilenames(std::string a, std::string b)
{
time_t ta=0;
time_t tb=0;
std::istringstream(a) >> ta;
std::istringstream(b) >> tb;
if (ta < tb)
return -1;
if (ta > tb)
return 1;
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
}
static std::string get_mod_token(std::string n)
{
std::string f= MODQUEUE "/" + n;
std::ifstream i(f.c_str());
if (!i.is_open())
return "";
std::string l;
std::getline(i, l);
if (l.substr(0, 14) != "X-Magic-Token:")
return "";
return std::string(std::find_if(l.begin()+14, l.end(),
std::not1(std::ptr_fun(isspace))),
l.end());
}
std::string webmlmd::get_next_mod_filename(std::string curfilename,
size_t &mod_count)
{
std::string filename;
DIR *dirp=opendir(MODQUEUE);
struct dirent *de;
mod_count=0;
bool checkdigestdir=false;
while (dirp && (de=readdir(dirp)))
{
if (de->d_name[0] == '.')
continue;
++mod_count;
std::string n=de->d_name;
if (curfilename != "" && cmpmodfilenames(n, curfilename) <= 0)
continue;
if (filename == "" || cmpmodfilenames(n, filename) < 0)
{
filename=n;
if (checkdigestdir)
continue;
if (get_mod_token(n) == "")
{
closedir(dirp);
mod_count=0;
return ""; // This is a mailing list digest
}
checkdigestdir=true;
}
}
if (dirp)
closedir(dirp);
return filename;
}
HANDLER("MODURL", emit_modlink)
{
size_t cnt=0;
webmlmd::get_next_mod_filename("", cnt);
if (cnt == 0 || args.empty())
return;
std::string msgtxt=args.front();
size_t p=msgtxt.find('@');
if (p != msgtxt.npos)
{
std::ostringstream o;
o << msgtxt.substr(0, p) << cnt <<
msgtxt.substr(p+1);
msgtxt=o.str();
}
std::cout << " | <a href=\"";
emit_list_url();
std::cout << "/admin/mod\">" << msgtxt << "</a>";
}
static std::string findparam(std::list<std::string> &args, std::string name)
{
std::list<std::string>::iterator b=args.begin(), e=args.end();
while (b != e)
{
if (b->substr(0, name.size()+1) == name + "=")
return b->substr(name.size()+1);
++b;
}
return "";
}
static void unknown_attachment_action(struct rfc2045id *idptr,
const char *content_type,
const char *content_name,
off_t size,
void *arg)
{
std::list<std::string> *argsp=(std::list<std::string> *)arg;
std::string content_type_s(content_type);
std::replace(content_type_s.begin(),
content_type_s.end(), '<', ' ');
printf("<blockquote><p>%s (%s; %ldkb)</p></blockquote>\n",
findparam(*argsp, "ATTACHNOTICE").c_str(),
content_type_s.c_str(),
(long)((size+512)/1024L));
}
static char *get_textlink(const char *url, void *arg)
{
return strdup(url ? url:"");
}
static void inline_image_action(struct rfc2045id *idptr,
const char *content_type,
void *arg)
{
fflush(stdout);
std::cout << "<img src=\"";
webmlmd::emit_list_url();
std::cout << "admin/modmimefetch?msgname="
<< cgi("msgname")
<< std::flush;
msg2html_showmimeid(idptr, NULL);
printf("\" />");
}
static char *get_url_to_mime_part(const char *mimeid,
void *arg)
{
std::ostringstream o;
o << cgirelscriptptr() << "/" << webmlmd::list_name()
<< "/admin/modmimefetch?msgname=" << cgi("msgname")
<< "&mimeid=" << mimeid;
return strdup(o.str().c_str());
}
HANDLER("MODMSG", emit_modmsg)
{
size_t cnt=0;
std::string filename=cgi("msgname");
if (filename.find('/') != filename.npos)
filename="";
if (filename == "")
filename=webmlmd::get_next_mod_filename(filename, cnt);
if (filename == "")
return;
cgi_put("msgname", filename.c_str());
std::cout << "<input type='hidden' name='msgname' value='"
<< filename << "' />";
std::string modfilename=MODQUEUE "/" + filename;
FILE *fp=fopen(modfilename.c_str(), "r");
if (!fp)
return;
struct rfc2045 *rfc=rfc2045_fromfp(fp);
if (!rfc)
{
fclose(fp);
return;
}
fseek(fp, 0L, SEEK_END);
fseek(fp, 0L, SEEK_SET);
struct msg2html_info *msg2htmlp=msg2html_alloc("utf-8");
if (!msg2htmlp)
{
rfc2045_free(rfc);
fclose(fp);
return;
}
std::cout << std::flush;
msg2htmlp->arg=&args;
msg2htmlp->showhtml=1;
msg2htmlp->get_url_to_mime_part=get_url_to_mime_part;
msg2htmlp->unknown_attachment_action=unknown_attachment_action;
msg2htmlp->inline_image_action=inline_image_action;
msg2htmlp->get_textlink=get_textlink;
msg2html(fp, rfc, msg2htmlp);
msg2html_free(msg2htmlp);
rfc2045_free(rfc);
fclose(fp);
}
std::string webmlmd::do_mod_accept(std::string filename)
{
std::string token=get_mod_token(filename);
if (token == "")
return "";
webmlmd::cmlm ctlmsg;
if (ctlmsg.start("moderate", "", "ctlmsg"))
{
FILE *stdinptr=ctlmsg.stdinptr();
ctlmsg.mk_received_header();
fprintf(stdinptr, "Subject: yes\n\n"
"==CUT HERE==\n\n==CUT HERE==\n\n"
"[%s]\n"
"[%s]\n",
filename.c_str(), token.c_str());
if (ctlmsg.wait())
return "";
}
return ctlmsg.format_error_message();
}
std::string webmlmd::do_mod_reject(std::string filename,
bool returntosender,
std::string msg)
{
std::string token=get_mod_token(filename);
if (token == "")
return "";
webmlmd::cmlm ctlmsg;
// Reformat message to prepend a space to each line, to avoid
// clashing with format characters.
std::istringstream i(msg + "\n");
std::ostringstream o;
std::string l;
while (std::getline(i, l).good())
{
o << " " << l << std::endl;
}
if (ctlmsg.start("moderate", "", "ctlmsg"))
{
FILE *stdinptr=ctlmsg.stdinptr();
ctlmsg.mk_received_header();
fprintf(stdinptr, "Subject: %s\n\n"
"==CUT HERE==\n\n%s==CUT HERE==\n\n"
"[%s]\n"
"[%s]\n",
returntosender ? "reject":"no",
o.str().c_str(),
filename.c_str(), token.c_str());
if (ctlmsg.wait())
return "";
}
return ctlmsg.format_error_message();
}