mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
let the past begone in cvs land. welcome to igit igit!
This commit is contained in:
commit
4e601cf1c7
509 changed files with 77963 additions and 0 deletions
149
world/net/nntp/common.c
Normal file
149
world/net/nntp/common.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include <net.h>
|
||||
#include <services.h>
|
||||
inherit NET_PATH "connect";
|
||||
inherit NET_PATH "queue2";
|
||||
|
||||
/*
|
||||
* this connects to a nntp server as client and does some fancy things.
|
||||
* the ultimate goal is to peer a nntp server and get notifications
|
||||
* or even the whole articles fed into PSYC
|
||||
*/
|
||||
#define NEWSSERVER "news.btx.dtag.de"
|
||||
#define NEWSGROUP "de.comm.chatsystems"
|
||||
|
||||
int busy;
|
||||
|
||||
request(cmd, cb) {
|
||||
if (busy)
|
||||
return enqueue(ME, ({ cmd, cb }));
|
||||
// should be an input_to to idle()
|
||||
remove_input_to(ME);
|
||||
binary_message(cmd + "\n");
|
||||
next_input_to(cb);
|
||||
}
|
||||
|
||||
// call this whenever you're idle
|
||||
do_request() {
|
||||
mixed *a;
|
||||
a = shift(ME);
|
||||
|
||||
request(a...);
|
||||
}
|
||||
|
||||
idle(a) {
|
||||
int numeric;
|
||||
|
||||
PT(("server said %O\n", a))
|
||||
sscanf(a, "%d %s\n", numeric, a);
|
||||
switch(numeric) {
|
||||
case 200:
|
||||
// HACK
|
||||
// fetchXHeader("Subject", 0, 0, "<dj4ve0$t40$1@online.de>");
|
||||
// HACK 2
|
||||
// fetchGroup(NEWSGROUP);
|
||||
// this is what should be really done
|
||||
busy = 0;
|
||||
do_request();
|
||||
default:
|
||||
next_input_to(#'idle);
|
||||
}
|
||||
}
|
||||
|
||||
string *buffer;
|
||||
doBuffer(a, whendone) {
|
||||
PT(("dobuffer %O\n", a))
|
||||
if (a == ".") {
|
||||
apply(whendone, buffer, 0); // dont flatten
|
||||
buffer = ({ });
|
||||
next_input_to(#'idle);
|
||||
return;
|
||||
}
|
||||
buffer += ({ a });
|
||||
|
||||
input_to(#'doBuffer, INPUT_IGNORE_BANG, whendone);
|
||||
}
|
||||
|
||||
// NNTP library below
|
||||
|
||||
_gotGroup(a) {
|
||||
int numeric;
|
||||
|
||||
sscanf(a, "%d%t%s", numeric, a);
|
||||
switch(numeric) {
|
||||
case 211:
|
||||
{
|
||||
int num, low, high;
|
||||
if (sscanf(a, "%d %d %d %s", num, low, high, a) == 4) {
|
||||
gotGroup(a, num, low, high);
|
||||
} else {
|
||||
P0(("%O broken 211 command?\n"))
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PT(("_gotGroup status code %d - %O\n", numeric, a))
|
||||
break;
|
||||
}
|
||||
// 211 -> ok
|
||||
// 411 -> No such group %s
|
||||
}
|
||||
|
||||
gotGroup(group, num, low, high) {
|
||||
PT(("got group %O with %d articles from %d to %d\n", group, num, low, high))
|
||||
// HACK 3
|
||||
fetchXHeader("Subject", high - 5, high);
|
||||
}
|
||||
|
||||
fetchGroup(group) {
|
||||
request(sprintf("GROUP %s", group), #'_gotGroup);
|
||||
}
|
||||
|
||||
_gotXHdr2(buffer) {
|
||||
PT(("_gotXHdr2 %O\n", buffer))
|
||||
}
|
||||
|
||||
_gotXHdr(a) {
|
||||
int numeric;
|
||||
PT(("_gotXHdr(%O)\n", a))
|
||||
sscanf(a, "%d %s", numeric, a);
|
||||
switch(numeric) {
|
||||
case 430: // no such article
|
||||
case 221:
|
||||
buffer = ({ });
|
||||
input_to(#'doBuffer, INPUT_IGNORE_BANG, #'_gotXHdr2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fetchXHeader(what, low, high, id) {
|
||||
string q;
|
||||
q = "XHDR " + what + " ";
|
||||
if (id)
|
||||
q += id;
|
||||
else if (low == 0 && high == 0)
|
||||
; // NOOP
|
||||
else if (high == 0)
|
||||
q += low + "-";
|
||||
else if (low == 0)
|
||||
q += "-" + high;
|
||||
else
|
||||
q += low + "-" + high;
|
||||
|
||||
request(q, #'_gotXHdr);
|
||||
}
|
||||
|
||||
logon(result) {
|
||||
int ret;
|
||||
ret = ::logon(result);
|
||||
busy = 1;
|
||||
next_input_to(#'idle);
|
||||
fetchGroup(NEWSGROUP);
|
||||
return ret;
|
||||
}
|
||||
|
||||
create() {
|
||||
qCreate();
|
||||
qInit(ME, 30);
|
||||
connect(NEWSSERVER, NNTP_SERVICE);
|
||||
return 1;
|
||||
}
|
229
world/net/nntp/server.c
Normal file
229
world/net/nntp/server.c
Normal file
|
@ -0,0 +1,229 @@
|
|||
// $Id: server.c,v 1.15 2006/08/24 11:43:36 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// NTTP server. currently only works with net/place/threads.
|
||||
/*
|
||||
* This may become a working nntp server one day,
|
||||
* even morphing into a user (AUTHINFO)
|
||||
*/
|
||||
#include <net.h>
|
||||
#include <server.h>
|
||||
#include <person.h>
|
||||
|
||||
qScheme() { return "nntp"; }
|
||||
|
||||
//protected object user;
|
||||
//string nick
|
||||
string password;
|
||||
int authenticated;
|
||||
object currentgroup;
|
||||
|
||||
mapping post_headers;
|
||||
string post_text;
|
||||
|
||||
parse(a) {
|
||||
/*
|
||||
* this should probably be moved to cmd and to a user.c
|
||||
* but currently it is too small
|
||||
*/
|
||||
string cmd, fullargs;
|
||||
string *args;
|
||||
|
||||
unless (sscanf(a, "%s%t%s", cmd, fullargs)) cmd = a;
|
||||
if (fullargs) args = explode(fullargs, " ");
|
||||
if (authenticated) nntp_cmd(cmd, args, a);
|
||||
else authenticate(cmd, args);
|
||||
next_input_to(#'parse);
|
||||
}
|
||||
|
||||
post_body(a) {
|
||||
object group;
|
||||
string dummy1, dummy2;
|
||||
int replyid;
|
||||
|
||||
if (a == ".") {
|
||||
post_headers["from"] = user -> qName();
|
||||
group = find_object("place/" + post_headers["newsgroups"]);
|
||||
P2(("group: %O\n", group))
|
||||
if (post_headers["in-reply-to"]) {
|
||||
sscanf(post_headers["in-reply-to"], "<%s$%d@%s>",
|
||||
dummy1, replyid, dummy2);
|
||||
P2(("its a reply to %d!\n", replyid - 1))
|
||||
group -> addComment(post_text, post_headers["from"],
|
||||
replyid - 1);
|
||||
} else {
|
||||
group -> addEntry(post_text, post_headers["from"],
|
||||
post_headers["subject"]);
|
||||
}
|
||||
write("240 Article posted successfully.\n");
|
||||
// P2(("headers: %O\n", post_headers))
|
||||
return next_input_to(#'parse);
|
||||
}
|
||||
unless (post_text) post_text = "";
|
||||
post_text += a + "\n";
|
||||
next_input_to(#'post_body);
|
||||
}
|
||||
|
||||
post(a) {
|
||||
string key, value;
|
||||
if (a == "") {
|
||||
return next_input_to(#'post_body);
|
||||
}
|
||||
sscanf(a, "%s:%t%s", key, value);
|
||||
unless (post_headers) post_headers = ([ ]);
|
||||
post_headers[lower_case(key)] = value;
|
||||
P2(("%s => %s\n", key, value))
|
||||
next_input_to(#'post);
|
||||
}
|
||||
|
||||
authenticate(cmd, args) {
|
||||
mixed authCb;
|
||||
P2(("authenticate %s, %O\n", cmd, args))
|
||||
switch(upper_case(cmd)) {
|
||||
case "AUTHINFO":
|
||||
unless (args) return -1;
|
||||
if (args[0] == "user") {
|
||||
nick = args[1];
|
||||
unless (user = find_person(nick)) {
|
||||
write("502 No permission\n");
|
||||
return quit();
|
||||
}
|
||||
} else if (args[0] == "pass") {
|
||||
password = args[1];
|
||||
}
|
||||
#ifdef ASYNC_AUTH
|
||||
authCb = CLOSURE((int result), (authenticated, password),
|
||||
(int authenticated, string password),
|
||||
{
|
||||
if(result) {
|
||||
write("281 Authorization accepted.\n");
|
||||
authenticated = 1;
|
||||
password = "";
|
||||
} else {
|
||||
write("381 PASS required.\n");
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
user -> checkPassword(password, "plain", 0, 0, authCb);
|
||||
#else
|
||||
write("500 ASYNC_AUTH required.\n");
|
||||
return quit();
|
||||
#endif
|
||||
break;
|
||||
case "MODE":
|
||||
// mode reader
|
||||
write("200 Ok\n");
|
||||
break;
|
||||
case "QUIT":
|
||||
return quit();
|
||||
default:
|
||||
write("480 User and password still required, authinfo command\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nntp_cmd(cmd, args, all) {
|
||||
object o;
|
||||
string group;
|
||||
P2(("nntp_cmd %s %O\n", cmd, args))
|
||||
unless (authenticated) return -1;
|
||||
switch(upper_case(cmd)) {
|
||||
case "GROUP":
|
||||
unless (args[0]) return;
|
||||
group = "place/" + args[0];
|
||||
o = group -> load();
|
||||
// watch out, saga suspects this might not work in some
|
||||
// cases
|
||||
if (objectp(o) || o = find_object(group) ) {
|
||||
// place exists and provides nntp support
|
||||
currentgroup = o;
|
||||
currentgroup -> nntpget("GROUP");
|
||||
// some kind of vSet("place")...
|
||||
} else {
|
||||
// place does not exist or does not provide nntp
|
||||
write("411 No such news capable place\n");
|
||||
}
|
||||
break;
|
||||
// mysterious article pointer stuff somewhere here
|
||||
case "XOVER":
|
||||
unless (currentgroup) {
|
||||
// write error!
|
||||
break;
|
||||
}
|
||||
write("224 data follows\n");
|
||||
// data here
|
||||
currentgroup -> nntpget("XOVER");
|
||||
write(".\n");
|
||||
break;
|
||||
#if 0
|
||||
case "NEWNEWS":
|
||||
group = "place/" + args[0];
|
||||
o = group -> load()
|
||||
if (objectp(o) || o = find_object(group)) {
|
||||
write("230 New news by message id follows\n");
|
||||
o -> nntpget
|
||||
write(".\n");
|
||||
} else write("411 No such news capable place\n");
|
||||
break;
|
||||
#endif
|
||||
case "HEAD":
|
||||
write("221 1 <foo@host> Article retrieved; head follows.\n");
|
||||
// header here
|
||||
write(".\n");
|
||||
break;
|
||||
case "BODY":
|
||||
write("222 1 <foo@host> Article retrieved; body follows.\n");
|
||||
// body here
|
||||
write(".\n");
|
||||
break;
|
||||
case "ARTICLE":
|
||||
unless(currentgroup) {
|
||||
// error!
|
||||
break;
|
||||
}
|
||||
currentgroup -> nntpget("ARTICLE", args[0]);
|
||||
break;
|
||||
case "HELP":
|
||||
write("100 This server provides no commands\n");
|
||||
break;
|
||||
case "MODE":
|
||||
write("200 Ok\n");
|
||||
break;
|
||||
case "NEWGROUPS": // besser als garnix?
|
||||
case "LIST":
|
||||
write("215 Newsgroups in form 'group high low flags'.\n");
|
||||
// kind of: list of places that are public and provide
|
||||
// nntp export
|
||||
// this is an example that does not even work proper
|
||||
// maybe this should be implemented in user object
|
||||
// and show the subscribed places
|
||||
foreach(group : user -> vQuery("subscriptions")) {
|
||||
o = find_object(PLACE_PATH + group);
|
||||
if (objectp(o)) o -> nntpget("LIST");
|
||||
}
|
||||
write(".\n");
|
||||
break;
|
||||
case "POST":
|
||||
write("340 Ok\n");
|
||||
post_headers = ([ ]);
|
||||
post_text = "";
|
||||
next_input_to(#'post);
|
||||
break;
|
||||
case "QUIT":
|
||||
return quit();
|
||||
default:
|
||||
if (all && strlen(all)) write("500 command not recognized\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
logon() {
|
||||
// write("201 Hello PSYC-NNTP world, posting is not implemented yet\r\n");
|
||||
write("480 User and password still required, authinfo command\n");
|
||||
next_input_to(#'parse);
|
||||
}
|
||||
|
||||
quit() {
|
||||
write("205 You just lost that magic feeling.\n");
|
||||
QUIT
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue