mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
some missing files
This commit is contained in:
parent
61e6cf4f60
commit
699fe68c44
20 changed files with 4284 additions and 0 deletions
440
world/drivers/ldmud/master/accept.c
Normal file
440
world/drivers/ldmud/master/accept.c
Normal file
|
@ -0,0 +1,440 @@
|
|||
// $Id: accept.c,v 1.119 2008/08/03 14:21:59 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
//
|
||||
// this file contains the glue between LDMUD and psyced to
|
||||
// connect the socket ports to appropriately named objects.
|
||||
//
|
||||
#include "/local/config.h"
|
||||
|
||||
#ifdef Dmaster
|
||||
# undef DEBUG
|
||||
# define DEBUG Dmaster
|
||||
#endif
|
||||
|
||||
#include NET_PATH "include/net.h"
|
||||
#include NET_PATH "include/services.h"
|
||||
#include DRIVER_PATH "include/driver.h"
|
||||
#include CONFIG_PATH "config.h"
|
||||
|
||||
#include DRIVER_PATH "sys/tls.h"
|
||||
|
||||
#ifndef ERR_TLS_NOT_DETECTED
|
||||
# define ERR_TLS_NOT_DETECTED -31337
|
||||
# ifdef SPYC_PATH
|
||||
# echo Warning: TLS autodetect is not enabled in driver.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
volatile int shutdown_in_progress = 0;
|
||||
|
||||
// not part of the master/driver API.. this is called from the library
|
||||
void notify_shutdown_first(int progress) {
|
||||
P3(("%O notify_shutdown_first(%O)\n", ME, progress))
|
||||
shutdown_in_progress = progress;
|
||||
}
|
||||
|
||||
#ifndef UID2NICK
|
||||
# ifdef _userid_nick_mapping
|
||||
# define UID2NICK(uid) ([ _userid_nick_mapping ])[uid]
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function is called every time a TCP connection is established.
|
||||
* It dispatches the ports to the protocol implementations.
|
||||
* input_to() can't be called from here.
|
||||
*
|
||||
* uid is only passed if USE_AUTHLOCAL is built into the driver.
|
||||
*/
|
||||
object connect(int uid, int port, string service) {
|
||||
int peerport;
|
||||
mixed arg, t;
|
||||
|
||||
// now that's a bit of preprocessor magic you don't need to understand.. ;)
|
||||
D2( if (uid) D("master:connected on port "+ query_mud_port() +" by uid "
|
||||
+ uid +"\n");
|
||||
else) {
|
||||
D3(D("master:connected on port "+query_mud_port()
|
||||
+" by "+query_ip_name()+"\n");)
|
||||
}
|
||||
#ifndef H_DEFAULT_PROMPT
|
||||
set_prompt("");
|
||||
#endif
|
||||
|
||||
if (shutdown_in_progress) {
|
||||
PT(("shutdown_in_progress(%O): putting connection from %O on hold\n",
|
||||
shutdown_in_progress, query_ip_name(ME)))
|
||||
// put the connection on hold to avoid further reconnects
|
||||
return clone_object(NET_PATH "utility/onhold");
|
||||
}
|
||||
|
||||
// we dont want the telnet machine most of the time
|
||||
// but disabling and re-enabling it for telnet doesn't work
|
||||
switch(port || query_mud_port()) {
|
||||
|
||||
#if HAS_PORT(PSYCS_PORT, PSYC_PATH)
|
||||
case PSYCS_PORT: // inofficial & temporary
|
||||
# if __EFUN_DEFINED__(tls_want_peer_certificate)
|
||||
tls_want_peer_certificate(ME);
|
||||
# endif
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
#endif // fall thru
|
||||
#if HAS_PORT(PSYC_PORT, PSYC_PATH)
|
||||
case PSYC_PORT:
|
||||
#endif
|
||||
#if HAS_PORT(PSYC_PORT, PSYC_PATH) || HAS_PORT(PSYCS_PORT, PSYC_PATH)
|
||||
# ifdef DRIVER_HAS_CALL_BY_REFERENCE
|
||||
arg = ME;
|
||||
query_ip_number(&arg);
|
||||
// this assumes network byte order provided by driver
|
||||
peerport = pointerp(arg) ? (arg[2]*256 + arg[3]) : 0;
|
||||
if (peerport < 0) peerport = 65536 + peerport;
|
||||
// no support for non-AF_INET nets yet
|
||||
if (peerport == PSYC_SERVICE) peerport = 0;
|
||||
# else
|
||||
// as long as the object names don't collide, this is okay too
|
||||
peerport = 65536 + random(9999999);
|
||||
# endif
|
||||
# ifdef DRIVER_HAS_RENAMED_CLONES
|
||||
unless (service) service = "psyc";
|
||||
t = "S:"+ service + ":"+ query_ip_number();
|
||||
// tcp peerports cannot be connected to, so we use minus
|
||||
if (peerport) t += ":-"+peerport;
|
||||
# else
|
||||
t = clone_object(PSYC_PATH "server");
|
||||
# endif
|
||||
// the psyc backend distinguishes listen ports from peers using minus
|
||||
D3(D(S("%O -> load(%O, %O)\n", t, query_ip_number(), -peerport));)
|
||||
return t -> load(query_ip_number(), -peerport);
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(SPYCS_PORT, SPYC_PATH)
|
||||
case SPYCS_PORT: // inofficial & temporary
|
||||
# if __EFUN_DEFINED__(tls_want_peer_certificate)
|
||||
tls_want_peer_certificate(ME);
|
||||
# endif
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
#endif // fall thru
|
||||
#if HAS_PORT(SPYC_PORT, SPYC_PATH)
|
||||
case SPYC_PORT:
|
||||
#endif
|
||||
#if HAS_PORT(SPYC_PORT, SPYC_PATH) || HAS_PORT(SPYCS_PORT, SPYC_PATH)
|
||||
# ifdef DRIVER_HAS_CALL_BY_REFERENCE
|
||||
arg = ME;
|
||||
query_ip_number(&arg);
|
||||
// this assumes network byte order provided by driver
|
||||
peerport = pointerp(arg) ? (arg[2]*256 + arg[3]) : 0;
|
||||
if (peerport < 0) peerport = 65536 + peerport;
|
||||
// no support for non-AF_INET nets yet
|
||||
if (peerport == SPYC_SERVICE) peerport = 0;
|
||||
# else
|
||||
// as long as the object names don't collide, this is okay too
|
||||
peerport = 65536 + random(9999999);
|
||||
# endif
|
||||
# ifdef DRIVER_HAS_RENAMED_CLONES
|
||||
t = "S:spyc:"+query_ip_number();
|
||||
// tcp peerports cannot be connected to, so we use minus
|
||||
if (peerport) t += ":-"+peerport;
|
||||
# else
|
||||
t = clone_object(SPYC_PATH "server");
|
||||
# endif
|
||||
// the psyc backend distinguishes listen ports from peers using minus
|
||||
D3(D(S("%O -> load(%O, %O)\n", t, query_ip_number(), -peerport));)
|
||||
return t -> load(query_ip_number(), -peerport);
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(POP3S_PORT, POP3_PATH)
|
||||
case POP3S_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
return clone_object(POP3_PATH "server");
|
||||
#endif
|
||||
#if HAS_PORT(POP3_PORT, POP3_PATH)
|
||||
case POP3_PORT:
|
||||
return clone_object(POP3_PATH "server");
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(SMTPS_PORT, NNTP_PATH)
|
||||
case SMTPS_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
return clone_object(SMTP_PATH "server");
|
||||
#endif
|
||||
#if HAS_PORT(SMTP_PORT, SMTP_PATH)
|
||||
case SMTP_PORT:
|
||||
return clone_object(SMTP_PATH "server");
|
||||
#endif
|
||||
|
||||
// heldensagas little http app
|
||||
#if HAS_PORT(SHT_PORT, SHT_PATH)
|
||||
case SHT_PORT:
|
||||
return clone_object(SHT_PATH "server");
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(NNTPS_PORT, NNTP_PATH)
|
||||
case NNTPS_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
return clone_object(NNTP_PATH "server");
|
||||
#endif
|
||||
#if HAS_PORT(NNTP_PORT, NNTP_PATH)
|
||||
case NNTP_PORT:
|
||||
return clone_object(NNTP_PATH "server");
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(JABBERS_PORT, JABBER_PATH)
|
||||
case JABBERS_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
return clone_object(JABBER_PATH "server");
|
||||
#endif
|
||||
#if HAS_PORT(JABBER_PORT, JABBER_PATH)
|
||||
case JABBER_PORT:
|
||||
# if __EFUN_DEFINED__(enable_telnet)
|
||||
enable_telnet(0); // are you sure!???
|
||||
# endif
|
||||
return clone_object(JABBER_PATH "server");
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(JABBER_S2S_PORT, JABBER_PATH)
|
||||
case JABBER_S2S_PORT:
|
||||
# ifdef DRIVER_HAS_CALL_BY_REFERENCE
|
||||
arg = ME;
|
||||
query_ip_number(&arg);
|
||||
// this assumes network byte order provided by driver
|
||||
peerport = pointerp(arg) ? (arg[2]*256 + arg[3]) : 0;
|
||||
if (peerport < 0) peerport = 65536 + peerport;
|
||||
if (peerport == JABBER_S2S_SERVICE) peerport = 0;
|
||||
# else
|
||||
// as long as the object names don't collide, this is okay too
|
||||
peerport = 65536 + random(9999999);
|
||||
# endif
|
||||
# if __EFUN_DEFINED__(enable_telnet)
|
||||
enable_telnet(0);
|
||||
# endif
|
||||
t = "S:xmpp:"+query_ip_number();
|
||||
// it's just an object name, but let's be consequent minus peerport
|
||||
if (peerport) t += ":-"+peerport;
|
||||
# ifdef _flag_log_sockets_XMPP
|
||||
SIMUL_EFUN_FILE -> log_file("RAW_XMPP", "\n\n%O: %O -> load(%O, %O)",
|
||||
ME, t,
|
||||
# ifdef _flag_log_hosts
|
||||
query_ip_number(),
|
||||
# else
|
||||
"?",
|
||||
# endif
|
||||
-peerport);
|
||||
# endif
|
||||
P3(("%O -> load(%O, %O)\n", t, query_ip_number(), -peerport))
|
||||
return t -> load(query_ip_number(), -peerport);
|
||||
#endif
|
||||
#if 0 //__EFUN_DEFINED__(enable_binary)
|
||||
// work in progress
|
||||
case 8888:
|
||||
enable_binary();
|
||||
enable_telnet(0);
|
||||
return clone_object(NET_PATH "socks/protocol");
|
||||
case 1935:
|
||||
enable_binary();
|
||||
enable_telnet(0);
|
||||
return clone_object(NET_PATH "rtmp/protocol");
|
||||
#endif
|
||||
#if HAS_PORT(IRCS_PORT, IRC_PATH)
|
||||
case IRCS_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
return clone_object(IRC_PATH "server");
|
||||
#endif
|
||||
#if HAS_PORT(IRC_PORT, IRC_PATH)
|
||||
case IRC_PORT:
|
||||
# if 0 // __EFUN_DEFINED__(enable_telnet)
|
||||
enable_telnet(0); // shouldn't harm.. but it does!!!
|
||||
# endif
|
||||
return clone_object(IRC_PATH "server");
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(APPLET_PORT, APPLET_PATH)
|
||||
case APPLET_PORT:
|
||||
# if __EFUN_DEFINED__(enable_telnet)
|
||||
// enable_telnet(0);
|
||||
# endif
|
||||
return clone_object(APPLET_PATH "server");
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(TELNETS_PORT, TELNET_PATH)
|
||||
case TELNETS_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
// we could do the UID2NICK thing here, too, but why should we?
|
||||
// what do you need tls for on a localhost tcp link?
|
||||
return clone_object(TELNET_PATH "server");
|
||||
#endif
|
||||
#if HAS_PORT(TELNET_PORT, TELNET_PATH)
|
||||
case TELNET_PORT:
|
||||
// set_prompt("> ");
|
||||
// we can't do the usual autodetect here, as telnet users
|
||||
// don't send first and rather expect the server to prompt
|
||||
// the correct way to do this: implement telnet nego for tls. bah!
|
||||
t = clone_object(TELNET_PATH "server");
|
||||
# ifdef UID2NICK
|
||||
if (uid && (arg = UID2NICK(uid))) { t -> sName(arg); }
|
||||
# endif
|
||||
return t;
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(HTTPS_PORT, HTTP_PATH)
|
||||
case HTTPS_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0) {
|
||||
D1( if (t != ERR_TLS_NOT_DETECTED) PP(( "TLS(%O) on %O: %O\n",
|
||||
t, query_mud_port(), tls_error(t) )); )
|
||||
#if !HAS_PORT(HTTP_PORT, HTTP_PATH)
|
||||
// if we have no http port, it may be intentional
|
||||
return (object)0;
|
||||
#endif
|
||||
}
|
||||
D2( else if (t > 0) PP(( "Setting up TLS connection in the background.\n" )); )
|
||||
D2( else PP(( "Oh yeah, I'm initializing an https session!\n" )); )
|
||||
return clone_object(HTTP_PATH "server");
|
||||
#endif
|
||||
/* don't fall thru. allow for https: to be available without http: */
|
||||
#if HAS_PORT(HTTP_PORT, HTTP_PATH)
|
||||
case HTTP_PORT:
|
||||
return clone_object(HTTP_PATH "server");
|
||||
#endif
|
||||
|
||||
#if HAS_PORT(MUDS_PORT, MUD_PATH)
|
||||
case MUDS_PORT:
|
||||
t = tls_init_connection(this_object());
|
||||
if (t < 0 && t != ERR_TLS_NOT_DETECTED) PP(( "TLS on %O: %O\n",
|
||||
query_mud_port(), tls_error(t) ));
|
||||
return clone_object(MUD_PATH "login");
|
||||
#endif
|
||||
#if HAS_PORT(MUD_PORT, MUD_PATH)
|
||||
default:
|
||||
// if you want to multiplex psyced with an LPMUD game
|
||||
// set_prompt("> ");
|
||||
return clone_object(MUD_PATH "login");
|
||||
#endif
|
||||
}
|
||||
|
||||
PP(("Received connection on port %O which isn't configured.\n",
|
||||
query_mud_port()));
|
||||
return (object)0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DRIVER_HAS_RENAMED_CLONES
|
||||
// named clones -lynx
|
||||
object compile_object(string file) {
|
||||
string path, name;
|
||||
object rob;
|
||||
|
||||
# ifdef PSYC_PATH
|
||||
if (abbrev("S:psyc:", file)) {
|
||||
rob = clone_object(PSYC_PATH "server");
|
||||
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
||||
return rob;
|
||||
}
|
||||
if (abbrev("psyc:", file)) {
|
||||
rob = clone_object(PSYC_PATH "active");
|
||||
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
||||
return rob;
|
||||
}
|
||||
# endif
|
||||
# ifdef SPYC_PATH
|
||||
if (abbrev("S:spyc:", file)) {
|
||||
rob = clone_object(SPYC_PATH "server");
|
||||
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
||||
return rob;
|
||||
}
|
||||
if (abbrev("spyc:", file)) {
|
||||
rob = clone_object(SPYC_PATH "active");
|
||||
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
||||
return rob;
|
||||
}
|
||||
# endif
|
||||
# ifdef HTTP_PATH
|
||||
// match both http:/ and https:/ objects ;D
|
||||
if (abbrev("http", file)) {
|
||||
rob = clone_object(HTTP_PATH "fetch");
|
||||
if (rob) rob->fetch(file[..<3]);
|
||||
return rob;
|
||||
}
|
||||
if (abbrev("xmlrpc:", file)) {
|
||||
rob = clone_object(HTTP_PATH "xmlrpc");
|
||||
if (rob) rob->fetch("http://" + file[7..<3]);
|
||||
return rob;
|
||||
}
|
||||
# endif
|
||||
if (sscanf(file, "%s#%s.c", path, name) && name != "") {
|
||||
unless (name = SIMUL_EFUN_FILE->legal_name(name))
|
||||
return (object)0;
|
||||
rob = clone_object(path);
|
||||
rob -> sName(name);
|
||||
D2(if (rob) PP(("NAMED CLONE: %O becomes %s of %s\n",
|
||||
rob, name, path));)
|
||||
return rob;
|
||||
}
|
||||
if (sscanf(file, "place/%s.c", name) && name != "") {
|
||||
#ifdef SANDBOX
|
||||
string t;
|
||||
#endif
|
||||
unless (name = SIMUL_EFUN_FILE->legal_name(name))
|
||||
return (object)0;
|
||||
|
||||
#ifdef SANDBOX
|
||||
if (file_size(t = USER_PATH + name + ".c") != -1) {
|
||||
rob = t -> sName(name);
|
||||
D2(if (rob) PP(("USER PLACE loaded: %O becomes %O\n", rob, file));)
|
||||
} else {
|
||||
#endif
|
||||
#ifdef _flag_disable_places_arbitrary
|
||||
P2(("WARN: cloned places disabled by #define %O\n", file))
|
||||
return (object)0;
|
||||
#else
|
||||
#ifdef _path_archetype_place_default
|
||||
rob = clone_object(_path_archetype_place_default);
|
||||
#else
|
||||
rob = clone_object(NET_PATH "place/default");
|
||||
#endif
|
||||
rob -> sName(name);
|
||||
D2(if (rob) PP(("PLACE CLONED: %O becomes %O\n", rob, file));)
|
||||
#endif
|
||||
#ifdef SANDBOX
|
||||
}
|
||||
#endif
|
||||
return rob;
|
||||
}
|
||||
if (sscanf(file, "%s/text.c", path) && path != "") {
|
||||
rob = clone_object(NET_PATH "text");
|
||||
rob -> sPath(path);
|
||||
D2(if (rob) PP(("DB CLONED: %O becomes %s/text\n", rob, path));)
|
||||
return rob;
|
||||
}
|
||||
# ifdef JABBER_PATH
|
||||
if (abbrev("S:xmpp:", file)) {
|
||||
rob = clone_object(JABBER_PATH "gateway");
|
||||
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
||||
return rob;
|
||||
}
|
||||
if (abbrev("C:xmpp:", file)) {
|
||||
rob = clone_object(JABBER_PATH "active");
|
||||
D2(if (rob) PP(("NAMED CLONE: %O => %s\n", rob, file));)
|
||||
return rob;
|
||||
}
|
||||
# endif
|
||||
P3(("WARN: could not create %O\n", file))
|
||||
return (object)0;
|
||||
}
|
||||
#endif
|
||||
|
32
world/net/include/trust.h
Normal file
32
world/net/include/trust.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
// $Id: trust.h,v 1.2 2008/07/26 13:18:06 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
//
|
||||
#ifndef _INCLUDE_TRUST_H
|
||||
#define _INCLUDE_TRUST_H
|
||||
|
||||
// all of these need new names to fit the tuning masterplan
|
||||
#ifndef MAX_EXPOSE_GROUPS
|
||||
# define MAX_EXPOSE_GROUPS 4 // just the top four ;)
|
||||
#endif
|
||||
#ifndef DEFAULT_EXPOSE_GROUPS // change this value in your local.h
|
||||
# define DEFAULT_EXPOSE_GROUPS 4 // if you want groups to be exposed by
|
||||
#endif // default like on irc
|
||||
#ifndef MAX_EXPOSE_FRIENDS
|
||||
# define MAX_EXPOSE_FRIENDS 8 // just the top eight ;)
|
||||
#endif
|
||||
#ifndef DEFAULT_EXPOSE_FRIENDS
|
||||
# define DEFAULT_EXPOSE_FRIENDS 4 // do not expose yet, until we have
|
||||
// profiles worth exposing for
|
||||
#endif
|
||||
#define TRUST_OVER_NOTIFY 3 // how much /trust counts more
|
||||
// than notify. the normal value for
|
||||
// a notify friendship is 8. if a
|
||||
// medium trust is equivalent to
|
||||
// that, 3 needs to be added to
|
||||
// trust 5 to reach notify 8.
|
||||
#define TRUST_MYSELF (9 + TRUST_OVER_NOTIFY)
|
||||
// maximum trust
|
||||
#ifndef EXPOSE_THRESHOLD
|
||||
# define EXPOSE_THRESHOLD TRUST_MYSELF // at least show it to myself
|
||||
#endif
|
||||
|
||||
#endif
|
239
world/net/spyc/dispatch.i
Normal file
239
world/net/spyc/dispatch.i
Normal file
|
@ -0,0 +1,239 @@
|
|||
// included by TCP circuit *and* UDP daemon // vim:syntax=lpc
|
||||
|
||||
void dispatch(mixed header_vars, mixed varops, mixed method, mixed body) {
|
||||
string vname;
|
||||
mixed vop; // value operation
|
||||
string t;
|
||||
mapping vars;
|
||||
string family;
|
||||
int glyph;
|
||||
|
||||
// check that method is a valid keyword
|
||||
if (method && !legal_keyword(method)) {
|
||||
DISPATCHERROR("non legal method");
|
||||
}
|
||||
#ifdef PSYC_TCP
|
||||
// copy() + occasional double modifier ops should be more
|
||||
// efficient than merge at every packet --lynX
|
||||
// no one cares about "efficiency" here. please proof your
|
||||
// bold statements with benchmarks anyway
|
||||
vars = header_vars + instate;
|
||||
#else
|
||||
vars = header_vars;
|
||||
#endif
|
||||
|
||||
// FIXME: this can happen earlier, e.g. in parse.c after
|
||||
// process_header
|
||||
// check _source/_context
|
||||
// this check can be skipped if _source and _context are empty
|
||||
if ((t = vars["_context"] || vars["_source"])) {
|
||||
array(mixed) u;
|
||||
unless (u = parse_uniform(t)) {
|
||||
DISPATCHERROR("logical source is not an uniform\n")
|
||||
}
|
||||
#ifdef PSYC_TCP
|
||||
unless (qAuthenticated(NAMEPREP(u[UHost]))) {
|
||||
DISPATCHERROR("non-authenticated host\n")
|
||||
}
|
||||
#else
|
||||
// TODO?
|
||||
#endif
|
||||
}
|
||||
// check that _target is hosted by us
|
||||
// this check can be skipped if _target is not set
|
||||
if ((t = vars["_target"])) {
|
||||
array(mixed) u;
|
||||
unless (u = parse_uniform(t)) {
|
||||
DISPATCHERROR("target is not an uniform\n")
|
||||
}
|
||||
// FIXME relaying support here?
|
||||
if (!is_localhost(u[UHost])) {
|
||||
DISPATCHERROR("target is not configured on this server\n")
|
||||
}
|
||||
}
|
||||
// FIXME: i dont like this block... maybe we decode each variable
|
||||
// when setting it?
|
||||
// that would also fit with 0 as varname deletion
|
||||
// below
|
||||
foreach(vop : varops) {
|
||||
vname = vop[0];
|
||||
|
||||
// psyc type conversion implementation ( http://about.psyc.eu/Type )
|
||||
// this does not support register_type() yet, but it is feasible
|
||||
PSYC_TRY(vname) {
|
||||
case "_uniform":
|
||||
case "_page":
|
||||
case "_entity":
|
||||
// TODO: check legal uniform
|
||||
break;
|
||||
case "_nick":
|
||||
// TODO: check legal nick
|
||||
break;
|
||||
case "_degree":
|
||||
// only honour the first digit
|
||||
if (strlen(vop[2]) && vop[2][0] >= '0' && vop[2][0] <= '9')
|
||||
vop[2] = vop[2][0] - '0';
|
||||
else {
|
||||
PT(("type parser _degree: could not handle value %O\n",
|
||||
vop[2]))
|
||||
vop[2] = 0;
|
||||
}
|
||||
break;
|
||||
case "_time":
|
||||
case "_amount":
|
||||
vop[2] = to_int(vop[2]);
|
||||
break;
|
||||
case "_list":
|
||||
mixed plist = list_parse(vop[2]);
|
||||
if (plist == -1) {
|
||||
DISPATCHERROR("could not parse list");
|
||||
}
|
||||
vop[2] = plist;
|
||||
break;
|
||||
PSYC_SLICE_AND_REPEAT
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME deliver packet
|
||||
// this should be a separate function
|
||||
PT(("SPYC vars is %O\n", vars))
|
||||
PT(("SPYC method %O\nbody %O\n", method, body))
|
||||
// delivery rules as usual, but
|
||||
if (vars["_context"]) {
|
||||
mixed context;
|
||||
mixed context_state;
|
||||
mixed source, target;
|
||||
|
||||
if (vars["_source"]) {
|
||||
P0(("invalid _context %O with _source %O\n",
|
||||
context, vars["_source"]))
|
||||
DISPATCHERROR("invalid usage of context with _source");
|
||||
}
|
||||
|
||||
context = find_context(vars["_context"]);
|
||||
if (!objectp(context)) {
|
||||
P0(("context %O not found?!\n", vars["_context"]))
|
||||
return;
|
||||
}
|
||||
context_state = context->get_state();
|
||||
|
||||
// apply varops to context state
|
||||
foreach(vop : varops) {
|
||||
vname = vop[0];
|
||||
if (!legal_keyword(vname) || abbrev("_INTERNAL", vname)) {
|
||||
DISPATCHERROR("illegal varname in psyc")
|
||||
}
|
||||
|
||||
switch(vop[1]) { // the glyph
|
||||
case C_GLYPH_MODIFIER_SET:
|
||||
vars[vname] = vop[2];
|
||||
break;
|
||||
case C_GLYPH_MODIFIER_ASSIGN:
|
||||
vars[vname] = context_state[vname] = vop[2];
|
||||
break;
|
||||
case C_GLYPH_MODIFIER_AUGMENT:
|
||||
if (!abbrev("_list", vname)) {
|
||||
DISPATCHERROR("psyc modifier + with non-list arg")
|
||||
}
|
||||
// FIXME: duplicates?
|
||||
context_state[vname] += vop[2];
|
||||
PT(("current state is %O, augment %O\n", context_state[vname], vop[2]))
|
||||
break;
|
||||
case C_GLYPH_MODIFIER_DIMINISH:
|
||||
if (!abbrev("_list", vname)) {
|
||||
DISPATCHERROR("psyc modifier + with non-list arg")
|
||||
}
|
||||
PT(("current state is %O, diminish %O\n", context_state[vname], vop[2]))
|
||||
foreach(mixed item : vop[2])
|
||||
context_state[vname] -= ({ item });
|
||||
PT(("after dim: %O\n", context_state[vname]))
|
||||
break;
|
||||
case C_GLYPH_MODIFIER_QUERY:
|
||||
DISPATCHERROR("psyc modifier ? not implemented")
|
||||
break;
|
||||
}
|
||||
}
|
||||
vars = vars + context_state;
|
||||
// FIXME: is it legal to do this if this has _target?
|
||||
// there should be no mods then anyway
|
||||
context->commit_state(context_state);
|
||||
|
||||
if (vars["_target"]) {
|
||||
// FIXME: delivery copycat from below
|
||||
// beware: source is set to 0 here as it may not be present
|
||||
target = find_psyc_object(parse_uniform(vars["_target"]));
|
||||
PT(("target is %O\n", target))
|
||||
// FIXME: net/entity can not yet deal with 0 method
|
||||
//
|
||||
if (objectp(context)) {
|
||||
context->msg(0, method || "", body, vars, 0, target);
|
||||
} else {
|
||||
// FIXME: proper croak back to sender here
|
||||
P0(("context %O for unicast to %O not found???\n", target))
|
||||
}
|
||||
} else {
|
||||
if (vars["_source_relay"]) {
|
||||
mixed localrelay;
|
||||
if ((localrelay = psyc_object(vars["_source_relay"]))) {
|
||||
P0(("local relay %O\n", localrelay))
|
||||
vars["_source_relay"] = localrelay;
|
||||
} else { // NORMALIZE UNIFORM
|
||||
vars["_source_relay"] = lower_case(vars["_source_relay"]);
|
||||
}
|
||||
}
|
||||
if (objectp(context)) {
|
||||
// do we need more local object detection here?
|
||||
context -> castmsg(source, method || "", body, vars);
|
||||
} else {
|
||||
// empty contexts are not bad currently
|
||||
// in the current implementation it only means that no one
|
||||
// interested in that context is online right now
|
||||
// FIXME: lines above are about the old stuff where we did
|
||||
// not have context state
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!vars["_target"] && !vars["_source"]) {
|
||||
#ifdef PSYC_TCP
|
||||
circuit_msg(method, vars, body);
|
||||
#else
|
||||
P1(("Ignoring a rootMsg from UDP: %O,%O,%O\n", method, vars, body))
|
||||
#endif
|
||||
} else {
|
||||
string source;
|
||||
mixed target;
|
||||
if (!vars["_source"]) {
|
||||
// FIXME: where to set netloc in active
|
||||
if (!netloc) { // set in sender after _request_features
|
||||
// FIXME: this is wrong
|
||||
DISPATCHERROR("Did you forget to request circuit features?");
|
||||
}
|
||||
source = netloc;
|
||||
} else {
|
||||
// FIXME: a macro NORMALIZE_UNIFORM that may do lower_case please
|
||||
// not a simple lower_case
|
||||
source = lower_case(vars["_source"]);
|
||||
}
|
||||
// source was checked either via x509 or dns before
|
||||
// so it is 'safe' to do this
|
||||
register_target(source);
|
||||
|
||||
// deliver FIXME same code above
|
||||
if (!vars["_target"]) {
|
||||
target = find_object(NET_PATH "root");
|
||||
} else {
|
||||
target = find_psyc_object(parse_uniform(vars["_target"]));
|
||||
}
|
||||
PT(("target is %O\n", target))
|
||||
// FIXME: net/entity can not yet deal with 0 method
|
||||
if (objectp(target))
|
||||
target->msg(source, method || "", body, vars);
|
||||
else {
|
||||
// FIXME: proper croak back to sender here
|
||||
P0(("target %O not found???\n", target))
|
||||
}
|
||||
}
|
||||
}
|
||||
::dispatch(header_vars, varops, method, body);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue