more
This commit is contained in:
parent
3c4ad2fe50
commit
fde7ed3d3b
1
contrib/backends/nntpchan-daemon/.gitignore
vendored
1
contrib/backends/nntpchan-daemon/.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
*.o
|
||||
nntpd
|
||||
nntpchan-tool
|
||||
test
|
||||
.gdb_history
|
@ -27,8 +27,14 @@ $(EXE): $(OBJECTS)
|
||||
$(TOOL): $(OBJECTS)
|
||||
$(CXX) -o $(TOOL) $(LD_FLAGS) $(OBJECTS) $(CXXFLAGS) tool.cpp
|
||||
|
||||
build-test: $(OBJECTS)
|
||||
$(CXX) -o test $(LD_FLAGS) $(OBJECTS) $(CXXFLAGS) test.cpp
|
||||
|
||||
test: build-test
|
||||
./test
|
||||
|
||||
%.o: src/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(EXE) $(TOOL)
|
||||
rm -f $(OBJECTS) $(EXE) $(TOOL) test
|
||||
|
2
contrib/backends/nntpchan-daemon/contrib/nntpchan.sh
Executable file
2
contrib/backends/nntpchan-daemon/contrib/nntpchan.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exit 0
|
@ -60,18 +60,18 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
if ( level.sections.find("frontend") != level.sections.end()) {
|
||||
// frontend enabled
|
||||
auto & frontconf = level.sections["frontend"];
|
||||
auto & frontconf = level.sections["frontend"].values;
|
||||
if (frontconf.find("type") == frontconf.end()) {
|
||||
std::cerr << "frontend section provided but 'type' value not provided" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
auto & ftype = frontconf.find("type");
|
||||
auto ftype = frontconf["type"];
|
||||
if (ftype == "exec") {
|
||||
if (frontconf.find("exec") == frontconf.end()) {
|
||||
std::cerr << "exec frontend specified but no 'exec' value provided" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
nntp.SetFrontend(new nntpchan::ExecFrontend(loop, frontconf["exec"]));
|
||||
nntp.SetFrontend(new nntpchan::ExecFrontend(frontconf["exec"]));
|
||||
} else {
|
||||
std::cerr << "unknown frontend type '" << ftype << "'" << std::endl;
|
||||
}
|
||||
|
57
contrib/backends/nntpchan-daemon/src/exec_frontend.cpp
Normal file
57
contrib/backends/nntpchan-daemon/src/exec_frontend.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include "exec_frontend.hpp"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
ExecFrontend::ExecFrontend(const std::string & fname) :
|
||||
m_exec(fname)
|
||||
{
|
||||
}
|
||||
|
||||
ExecFrontend::~ExecFrontend() {}
|
||||
|
||||
void ExecFrontend::ProcessNewMessage(const std::string & fpath)
|
||||
{
|
||||
Exec({"post", fpath});
|
||||
}
|
||||
|
||||
bool ExecFrontend::AcceptsNewsgroup(const std::string & newsgroup)
|
||||
{
|
||||
return Exec({"newsgroup", newsgroup}) == 0;
|
||||
}
|
||||
|
||||
bool ExecFrontend::AcceptsMessage(const std::string & msgid)
|
||||
{
|
||||
return Exec({"msgid", msgid}) == 0;
|
||||
}
|
||||
|
||||
int ExecFrontend::Exec(std::deque<std::string> args)
|
||||
{
|
||||
// set up arguments
|
||||
const char ** cargs = new char const *[args.size() +2];
|
||||
std::size_t l = 0;
|
||||
cargs[l++] = m_exec.c_str();
|
||||
while (args.size()) {
|
||||
cargs[l++] = args.front().c_str();
|
||||
args.pop_front();
|
||||
}
|
||||
cargs[l] = 0;
|
||||
int retcode = 0;
|
||||
pid_t child = fork();
|
||||
if(child) {
|
||||
waitpid(child, &retcode, 0);
|
||||
} else {
|
||||
int r = execvpe(m_exec.c_str(),(char * const *) cargs, environ);
|
||||
if ( r == -1 ) {
|
||||
std::cout << strerror(errno) << std::endl;
|
||||
exit( errno );
|
||||
} else
|
||||
exit(r);
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
}
|
@ -1,9 +1,30 @@
|
||||
#ifndef NNTPCHAN_EXEC_FRONTEND_HPP
|
||||
#define NNTPCHAN_EXEC_FRONTEND_HPP
|
||||
#include "frontend.hpp"
|
||||
#include <deque>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
class ExecFrontend : public Frontend
|
||||
{
|
||||
public:
|
||||
|
||||
ExecFrontend(const std::string & exe);
|
||||
|
||||
~ExecFrontend();
|
||||
|
||||
void ProcessNewMessage(const std::string & fpath);
|
||||
bool AcceptsNewsgroup(const std::string & newsgroup);
|
||||
bool AcceptsMessage(const std::string & msgid);
|
||||
|
||||
private:
|
||||
|
||||
int Exec(std::deque<std::string> args);
|
||||
|
||||
private:
|
||||
std::string m_exec;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
#ifndef NNTPCHAN_FRONTEND_HPP
|
||||
#define NNTPCHAN_FRONTEND_HPP
|
||||
#include <string>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
@ -10,14 +11,13 @@ namespace nntpchan
|
||||
virtual ~Frontend() {}
|
||||
|
||||
/** @brief process an inbound message stored at fpath that we have accepted. */
|
||||
void ProcessNewMessage(const std::string & fpath) = 0;
|
||||
virtual void ProcessNewMessage(const std::string & fpath) = 0;
|
||||
|
||||
/** @brief return true if we take posts in a newsgroup */
|
||||
bool AcceptsNewsgroup(const std::string & newsgroup) = 0;
|
||||
virtual bool AcceptsNewsgroup(const std::string & newsgroup) = 0;
|
||||
|
||||
/** @brief return true if we will accept a message given its message-id */
|
||||
bool AcceptsMessage(const std::string & msgid) = 0;
|
||||
|
||||
virtual bool AcceptsMessage(const std::string & msgid) = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -12,11 +12,21 @@ namespace nntpchan
|
||||
{
|
||||
uv_tcp_init(loop, &m_server);
|
||||
m_loop = loop;
|
||||
m_server.data = this;
|
||||
}
|
||||
|
||||
NNTPServer::~NNTPServer()
|
||||
{
|
||||
uv_close((uv_handle_t*)&m_server, [](uv_handle_t *) {});
|
||||
if (m_frontend) delete m_frontend;
|
||||
}
|
||||
|
||||
void NNTPServer::Close()
|
||||
{
|
||||
uv_close((uv_handle_t*)&m_server, [](uv_handle_t * s) {
|
||||
NNTPServer * self = (NNTPServer*)s->data;
|
||||
if (self) delete self;
|
||||
s->data = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
void NNTPServer::Bind(const std::string & addr)
|
||||
@ -24,7 +34,6 @@ namespace nntpchan
|
||||
auto saddr = ParseAddr(addr);
|
||||
assert(uv_tcp_bind(*this, saddr, 0) == 0);
|
||||
std::cerr << "nntp server bound to " << saddr.to_string() << std::endl;
|
||||
m_server.data = this;
|
||||
auto cb = [] (uv_stream_t * s, int status) {
|
||||
NNTPServer * self = (NNTPServer *) s->data;
|
||||
self->OnAccept(s, status);
|
||||
@ -61,6 +70,12 @@ namespace nntpchan
|
||||
m_storagePath = path;
|
||||
}
|
||||
|
||||
void NNTPServer::SetFrontend(Frontend * f)
|
||||
{
|
||||
if(m_frontend) delete m_frontend;
|
||||
m_frontend = f;
|
||||
}
|
||||
|
||||
NNTPServerConn::NNTPServerConn(uv_loop_t * l, uv_stream_t * s, const std::string & storage, NNTPCredentialDB * creds) :
|
||||
m_handler(storage)
|
||||
{
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include "storage.hpp"
|
||||
#include "frontend.hpp"
|
||||
#include "nntp_auth.hpp"
|
||||
#include "nntp_handler.hpp"
|
||||
|
||||
@ -26,6 +27,10 @@ namespace nntpchan
|
||||
|
||||
void SetLoginDB(const std::string path);
|
||||
|
||||
void SetFrontend(Frontend * f);
|
||||
|
||||
void Close();
|
||||
|
||||
private:
|
||||
|
||||
operator uv_handle_t * () { return (uv_handle_t*) &m_server; }
|
||||
@ -40,6 +45,8 @@ namespace nntpchan
|
||||
std::string m_logindbpath;
|
||||
std::string m_storagePath;
|
||||
|
||||
Frontend * m_frontend;
|
||||
|
||||
};
|
||||
|
||||
class NNTPServerConn
|
||||
|
13
contrib/backends/nntpchan-daemon/test.cpp
Normal file
13
contrib/backends/nntpchan-daemon/test.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "exec_frontend.hpp"
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
int main(int , char * [])
|
||||
{
|
||||
nntpchan::Frontend * f = new nntpchan::ExecFrontend("./contrib/nntpchan.sh");
|
||||
assert(f->AcceptsMessage("<test@server>"));
|
||||
assert(f->AcceptsNewsgroup("overchan.test"));
|
||||
std::cout << "all good" << std::endl;
|
||||
}
|
0
contrib/frontends/py/frontend.py
Normal file → Executable file
0
contrib/frontends/py/frontend.py
Normal file → Executable file
@ -1,42 +1 @@
|
||||
|
||||
from nntpchan import store
|
||||
from nntpchan import message
|
||||
from nntpchan import preprocess
|
||||
|
||||
|
||||
def addArticle(msgid, group):
|
||||
"""
|
||||
add article to system
|
||||
:return True if we need to regenerate otherwise False:
|
||||
"""
|
||||
msg = None
|
||||
# open message
|
||||
with store.openArticle(msgid) as f:
|
||||
# read article header
|
||||
hdr = message.readHeader(f)
|
||||
|
||||
mclass = message.MultipartMessage
|
||||
if hdr.isTextOnly:
|
||||
# treat as text message instead of multipart
|
||||
mclass = message.TextMessage
|
||||
elif hdr.isSigned:
|
||||
# treat as signed message
|
||||
mclass = message.TripcodeMessage
|
||||
# create messgae
|
||||
msg = mclass(hdr, f)
|
||||
|
||||
if msg is not None:
|
||||
# we got a message that is valid
|
||||
store.storeMessage(msg)
|
||||
else:
|
||||
# invalid message
|
||||
print("invalid message: {}".format(msgid))
|
||||
return msg is not None
|
||||
|
||||
|
||||
def regenerate(msgid, group):
|
||||
"""
|
||||
regenerate markup
|
||||
"""
|
||||
pass
|
||||
|
||||
|
Reference in New Issue
Block a user