1
0
Fork 0
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:
PSYC 2009-01-26 20:21:29 +01:00
commit 4e601cf1c7
509 changed files with 77963 additions and 0 deletions

149
world/net/nntp/common.c Normal file
View 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
View 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
}