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
4
world/net/library/Makefile
Normal file
4
world/net/library/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
it: profiles.c
|
||||
|
||||
profiles.c: profiles.pl
|
||||
perl $<
|
162
world/net/library/admin.c
Normal file
162
world/net/library/admin.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
// $Id: admin.c,v 1.26 2007/08/20 12:25:23 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// admin functions and shutdown procedure
|
||||
//
|
||||
#include <net.h>
|
||||
#include <proto.h>
|
||||
#include <sandbox.h>
|
||||
|
||||
// amount of seconds per pass
|
||||
#ifndef TIME_SHUTDOWN
|
||||
# if DEBUG > 0
|
||||
# define TIME_SHUTDOWN 2
|
||||
# else
|
||||
# define TIME_SHUTDOWN 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// this used to be notify_shutdown() in master.c, but we need to do this
|
||||
// before the backend actually terminates, and give it a little time to
|
||||
// shutdown communications sanely. so now the shutdown is a 3 pass process.
|
||||
//
|
||||
// pass 0: shutdown all entities
|
||||
// pass 1: shutdown all network circuits
|
||||
// pass 2: make sure everything is done and terminate
|
||||
//
|
||||
// beware that an external "killall -1 psyced" inevitabely performs only
|
||||
// the last pass, so we need to be able to clean up as best we can, so that
|
||||
// psyced gets half a chance to exit in a psyc-friendly way. it is therefore
|
||||
// not recommended to shutdown a psyc server by signal. please use /ciao or
|
||||
// implement a _request_shutdown you can trigger from say perlpsyc's tell.
|
||||
//
|
||||
varargs int server_shutdown(string reason, int restart, int pass) {
|
||||
object o;
|
||||
int i, errors;
|
||||
|
||||
PROTECT("SERVER_SHUTDOWN")
|
||||
shutdown_in_progress++;
|
||||
if (master) master->notify_shutdown_first(shutdown_in_progress);
|
||||
else debug_message("Warning: Master object destructed?\n");
|
||||
|
||||
if (!reason || reason == "") {
|
||||
#ifdef DEFAULT_SHUTDOWN_REASON
|
||||
reason = DEFAULT_SHUTDOWN_REASON;
|
||||
#else
|
||||
reason = CHATNAME " is performing a quick full twist double "
|
||||
"salto backwards.";
|
||||
#endif
|
||||
}
|
||||
|
||||
unless (pass) { // first pass
|
||||
P0(("Server %s requested by %O. Grace period: "+ TIME_SHUTDOWN * 2
|
||||
+" secs.\n", restart? "RESTART": "SHUTDOWN", previous_object()))
|
||||
// see "psyced" script (was: muvelauncher)
|
||||
unless (restart) rm(DATA_PATH ".autorestart");
|
||||
call_out(#'server_shutdown, TIME_SHUTDOWN, reason, restart, 1);
|
||||
}
|
||||
|
||||
// we first quit all users.. then do the items
|
||||
foreach (o : objects_people()) {
|
||||
if (catch(o->reboot(reason, restart, pass))) errors++;
|
||||
}
|
||||
|
||||
if (pass++) {
|
||||
// this walks thru the complete list of objects of the driver
|
||||
// and gives every stupid little object a chance to store its state.
|
||||
// this may one day change into something more strategic, but since
|
||||
// most PSYC objects do have something to save, this does a good job!
|
||||
#if __EFUN_DEFINED__(debug_info)
|
||||
for(i=0; o = debug_info(2,i); i++) {
|
||||
// we skip the tcp links, as the other objects will need them
|
||||
unless (interactive(o)) {
|
||||
// will output error anyway, but not stop loop from running
|
||||
P2(("%O->reboot(%O, %O, %O)\n", o, reason, restart, pass))
|
||||
if (catch(o->reboot(reason, restart, pass))) errors++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// we use this because remove_player() comes too late to properly
|
||||
// terminate any protocols and send any notifications
|
||||
// TODO: rewrite this with a foreach catch!
|
||||
pass++;
|
||||
P2(("%O->reboot(%O, %O, %O)\n", users(), reason, restart, pass))
|
||||
#ifdef __LPC_ARRAY_CALLS__
|
||||
// this is actually imperfect, as a bug in one user breaks the loop
|
||||
if (catch(users()->reboot(reason, restart, pass))) errors++;
|
||||
#else
|
||||
# if __EFUN_DEFINED__(lambda) && __EFUN_DEFINED__(filter)
|
||||
// same problem here
|
||||
filter(users(), lambda(({'u}),
|
||||
({ #'call_other, 'u, "reboot", reason, restart, pass }) //'
|
||||
));
|
||||
# else
|
||||
# echo Warning: No neat shutdown function.
|
||||
# endif
|
||||
#endif
|
||||
if (pass == 3) {
|
||||
call_out(#'shutdown, TIME_SHUTDOWN);
|
||||
save_object(DATA_PATH "library");
|
||||
} else {
|
||||
P0(("server_shutdown ended at pass %O\n", pass))
|
||||
}
|
||||
}
|
||||
P2(("Errors during shutdown: %O\n", errors))
|
||||
return errors;
|
||||
}
|
||||
|
||||
varargs void shout(mixed who, string what, string text, mapping vars) {
|
||||
PROTECT("SHOUT")
|
||||
unless(mappingp(vars)) vars = ([]);
|
||||
#if 0 //def __LPC_ARRAY_CALLS__
|
||||
// we can't use this cuz we need to copy(vars) for each
|
||||
objects_people() -> msg(who, what, text, vars);
|
||||
#else
|
||||
# if __EFUN_DEFINED__(lambda) && (__EFUN_DEFINED__(filter_array) || __EFUN_DEFINED__(filter))
|
||||
# if __EFUN_DEFINED__(filter)
|
||||
filter(objects_people(), lambda(({'u}), ({#'call_other,
|
||||
'u, "msg", who, to_string(what), to_string(text),
|
||||
({ #'copy, vars }) })
|
||||
));
|
||||
# else
|
||||
filter_array(objects_people(), lambda(({'u}), ({#'call_other,
|
||||
'u, "msg", who, to_string(what), to_string(text),
|
||||
({ #'copy, vars }) })
|
||||
));
|
||||
# endif
|
||||
// # else
|
||||
// # echo shout() admin function disabled on this driver
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef PRO_PATH
|
||||
// boss commands belong into an appropriate commander daemon meguesses
|
||||
// anyway, they get called by bossy user objects - but also by the httpd
|
||||
//
|
||||
int boss_command(string cmd, string args) {
|
||||
object o;
|
||||
|
||||
PROTECT("BOSS_COMMAND")
|
||||
|
||||
switch(cmd) {
|
||||
case "shutdown":
|
||||
// "Server shutting down. Please don't cry."
|
||||
// shout(0, "_notice_broadcast_shutdown",
|
||||
// "Server shutdown: [_reason]", ([ "_reason": args ]));
|
||||
server_shutdown(args, 0);
|
||||
return 1;
|
||||
case "ciao":
|
||||
case "hasta":
|
||||
case "reboot":
|
||||
case "restart":
|
||||
// "Server restarting. Fasten seat belts."
|
||||
// shout(0, "_notice_broadcast_shutdown_restart",
|
||||
// "Server restart: [_reason]", ([ "_reason": args ]));
|
||||
server_shutdown(args, 1);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
102
world/net/library/base64.c
Normal file
102
world/net/library/base64.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
// $Id: base64.c,v 1.7 2005/11/13 19:52:44 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// base64 encoder/decoder
|
||||
// 2004 - Dan@Gueldenland - df@erinye.com
|
||||
//
|
||||
#include <net.h>
|
||||
|
||||
volatile string * char64 = efun::explode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "");
|
||||
|
||||
volatile mapping deco64 = funcall( (:
|
||||
mapping x = ([ ]);
|
||||
int i;
|
||||
for(i=0; i<64; ++i) {
|
||||
x[char64[i][0]] = i+1;
|
||||
}
|
||||
x['='] = 1;
|
||||
return x;
|
||||
:) );
|
||||
|
||||
static int deco(int i) {
|
||||
i = deco64[i];
|
||||
if(!i) raise_error("Oh crap.\n");
|
||||
return i-1;
|
||||
}
|
||||
|
||||
string encode_base64(int * b) {
|
||||
int bbb, i=0, s=sizeof(b);
|
||||
string res = "";
|
||||
|
||||
while(i+3 <= s) {
|
||||
bbb = (b[i++] & 0xff) << 16;
|
||||
bbb |= (b[i++] & 0xff) << 8;
|
||||
bbb |= b[i++] & 0xff;
|
||||
res += char64[(bbb & 0xfc0000) >> 18] + char64[(bbb & 0x3f000) >> 12] + char64[(bbb & 0xfc0) >> 6] + char64[bbb & 0x3f];
|
||||
}
|
||||
if(s - i == 2) {
|
||||
bbb = ((b[i++] & 0xff) << 16) | ((b[i++] & 0xff) << 8);
|
||||
res += char64[(bbb & 0xfc0000) >> 18] + char64[(bbb & 0x3f000) >> 12] + char64[(bbb & 0xfc0) >> 6] + "=";
|
||||
} else if(s - i == 1) {
|
||||
bbb = ((b[i] & 0xff) << 16);
|
||||
res += char64[(bbb & 0xfc0000) >> 18] + char64[(bbb & 0x3f000) >> 12] + "==";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// this doesn't really enforce base64, but if it finds = on positions they
|
||||
// shouldn't be on, this'll get sullen.
|
||||
int * decode_base64(string b) {
|
||||
int * res = ({ });
|
||||
int i=0, s, next;
|
||||
|
||||
b = replace(b, "\n", "");
|
||||
b = replace(b, "\r", "");
|
||||
|
||||
s = strlen(b);
|
||||
|
||||
while(i+4 <= s) {
|
||||
res += ({ (deco(b[i]) << 2) | (deco(b[i+1]) >> 4) });
|
||||
next = ((deco(b[i+1]) << 4) & 0xff) | (deco(b[i+2]) >> 2);
|
||||
unless (!next && b[i+2] == '=') {
|
||||
res += ({ next });
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
next = ((deco(b[i+2]) << 6) & 0xc0) | deco(b[i+3]);
|
||||
unless (!next && b[i+3] == '=') {
|
||||
res += ({ next });
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
i += 4;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#if DEBUG > 1
|
||||
void base64_self_test() {
|
||||
int i, j, cool;
|
||||
string x, y, z;
|
||||
|
||||
for(i=0; i<10; ++i) {
|
||||
x = "";
|
||||
j = random(100) + 5;
|
||||
while(j>0) {
|
||||
x += to_string(({ 32 + random(96) }));
|
||||
--j;
|
||||
}
|
||||
y = encode_base64(to_array(x));
|
||||
z = to_string(decode_base64(y));
|
||||
if(z == x) ++cool;
|
||||
else {
|
||||
P2(("uncool:\n%O !=\n%O\n", x, z));
|
||||
P3(("base: %O\n", y))
|
||||
P3(("strlen: %O, %O, last: %O\n", strlen(x), strlen(z), z[<1]))
|
||||
}
|
||||
}
|
||||
P2(("base64_self_test: %d out of 10 successful.\n", cool));
|
||||
}
|
||||
#endif
|
||||
|
664
world/net/library/dns.c
Normal file
664
world/net/library/dns.c
Normal file
|
@ -0,0 +1,664 @@
|
|||
// vim:syntax=lpc
|
||||
// info: to unfold and view the complete file, hit zR in your vim command mode.
|
||||
//
|
||||
// $Id: dns.c,v 1.112 2008/03/29 20:05:32 lynx Exp $
|
||||
//
|
||||
// {{{ meta-bla about foldmethod=marker
|
||||
// <lynX> hm.. find ich folding jetzt eher nützlich oder lästig? muss ich
|
||||
// noch herausfinden. auf jeden fall sind die farben eher unpraktisch.
|
||||
// steht sicher irgendwo in irgendwelchen files definiert.. juchei
|
||||
// übertreiben sollte man's jedenfalls nicht, oder was soll das
|
||||
// "whatis comment" anderes erreichen als dass der kommentar nicht
|
||||
// gelesen wird obwohl er extra dafür geschrieben wurde?
|
||||
// }}}
|
||||
|
||||
// und dann ist da noch myUNL, myLowerCaseHost.
|
||||
// in der psyclib. letzteres gehört wohl eher hier her.
|
||||
|
||||
// {{{ includes
|
||||
#include "net.h"
|
||||
#include "proto.h"
|
||||
#include "closures.h"
|
||||
#include <dns.h>
|
||||
#include <erq.h>
|
||||
#include <sandbox.h>
|
||||
// }}}
|
||||
|
||||
// {{{ queue-inherit
|
||||
#ifdef NEW_QUEUE
|
||||
inherit NET_PATH "queue2";
|
||||
#else
|
||||
inherit NET_PATH "queue";
|
||||
#endif
|
||||
// }}}
|
||||
|
||||
// {{{ variables
|
||||
//
|
||||
// this mapping has to be *volatile* or it will carry old hostnames
|
||||
// that may no longer be valid, then cause wild illogical behaviour
|
||||
volatile mapping localhosts = ([
|
||||
"localhost": "127.0.0.1",
|
||||
"127.0.0.1": "localhost",
|
||||
// unusual but valid syntax for localhost
|
||||
// then again usually any 127.* leads to localhost so it's
|
||||
// pointless and after all it can even be good for testing
|
||||
// the switch protocol on oneself.. ;)
|
||||
"127.0.1": "localhost",
|
||||
"127.1": "localhost",
|
||||
// "0": ??
|
||||
#ifdef __HOST_IP_NUMBER__
|
||||
# if __HOST_IP_NUMBER__ != "127.0.0.1"
|
||||
__HOST_IP_NUMBER__ : 1,
|
||||
# endif
|
||||
#endif
|
||||
// the hostnames need to be in lowercase... lets do it later
|
||||
// SERVER_HOST : 1,
|
||||
#if defined(JABBER_HOST)
|
||||
# if JABBER_HOST != SERVER_HOST
|
||||
// JABBER_HOST : 1,
|
||||
# endif
|
||||
#endif
|
||||
]);
|
||||
|
||||
volatile mapping host2canonical = ([ ]);
|
||||
volatile object hostsd;
|
||||
// }}}
|
||||
|
||||
// {{{ query_server_ip && myip && register_localhost
|
||||
#ifndef __HOST_IP_NUMBER__
|
||||
volatile string myIP;
|
||||
#else
|
||||
# define myIP __HOST_IP_NUMBER__
|
||||
#endif
|
||||
|
||||
string query_server_ip() { return myIP; }
|
||||
|
||||
// take care to always pass a lowercased (virtual) hostname
|
||||
varargs void register_localhost(string name) { //, string ip) {
|
||||
//unless (ip) ip = myIP;
|
||||
localhosts[name] = 1; //ip;
|
||||
// either we have a static ip, then we already know it, or we
|
||||
// have a public ip hidden by a firewall or nat, then we can
|
||||
// find it out using #'set_my_ip - but what if by dsl relogin
|
||||
// or something like that our public ip address changes? then
|
||||
// we have an old ip number which by very unlikely circumstance
|
||||
// could possibly turn into a security problem. but what's worse:
|
||||
// we might get used having the public ip in here, and then it
|
||||
// suddenly no longer is (because there is an old one instead)
|
||||
// i have the impression we are well off if we only know all of
|
||||
// our virtual host names - we don't need our ip numbers really
|
||||
//localhosts[ip] = name;
|
||||
}
|
||||
// }}}
|
||||
|
||||
#ifndef SANDBOX
|
||||
// {{{ function: del_queue
|
||||
void del_queue(string queue) {
|
||||
qDel(queue);
|
||||
}
|
||||
// }}}
|
||||
#endif
|
||||
|
||||
// {{{ function: legal_host
|
||||
int legal_host(string ip, int port, string scheme, int udpflag) { // proto.h!
|
||||
P3(("legal_host %O %O %O %O\n", ip, port, scheme, udpflag))
|
||||
// do not allow logins during shutdown
|
||||
// if (shutdown_in_progress) return 0;
|
||||
// we sincerely hope our kernel will drop udp packets that
|
||||
// spoof they are coming from localhost.. would be ridiculous if not
|
||||
// if (ip == "127.0.0.1" || ip == "127.1" || ip == "0") return 9;
|
||||
#ifndef DONT_TRUST_LOCALHOST
|
||||
if (localhosts[ip]) return 9;
|
||||
if (ip == myIP || !ip) return 8;
|
||||
#endif
|
||||
unless (hostsd) hostsd = DAEMON_PATH "hosts" -> load();
|
||||
P4(("legal_host asks %O\n", hostsd))
|
||||
return hostsd -> legal_host(ip, port, scheme, udpflag);
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ function: legal_domain
|
||||
int legal_domain(string host, int port, string scheme, int udpflag) {
|
||||
// we sincerely hope our kernel will drop udp packets that
|
||||
// spoof they are coming from localhost.. would be ridiculous if not
|
||||
//
|
||||
// TODO: use is_localhost here?
|
||||
#ifndef DONT_TRUST_LOCALHOST
|
||||
if (host == "localhost" || host == SERVER_HOST) return 9;
|
||||
#endif
|
||||
// if (host == myLowerCaseHost) return 8;
|
||||
// if (lower_case(host) == myLowerCaseHost) return 7;
|
||||
|
||||
// unless (hostsd) hostsd = DAEMON_PATH "hosts" -> load();
|
||||
// return hostsd -> legal_domain(host, port, scheme, udpflag);
|
||||
return 5; // TODOOOOOO
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ function: chost
|
||||
// {{{ whatis comment
|
||||
/** provides us with the "canonical" name of a host as given by DNS PTR,
|
||||
** not to be confused with the aliasing facility "CNAME" - not sure
|
||||
** about this function name but don't know any better right now.
|
||||
** this function does NOT do any DNS resolutions itself, it only consults
|
||||
** a cache which is kept up to date by the dns_*resolve functions.
|
||||
** it is therefore nice and fast.
|
||||
*/
|
||||
// }}}
|
||||
string chost(string host) {
|
||||
return host2canonical[host];
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ function: same_host
|
||||
// {{{ whatis comment
|
||||
/** figures out if two hostnames (aliases or its ip) are the same host.
|
||||
** this is essentially chost(a) == chost(b) with one function call less.
|
||||
*/
|
||||
// }}}
|
||||
|
||||
// {{{ remarks
|
||||
// we should probably lower_case() hosts, as there has been trouble w/
|
||||
// hostnames once lower_cased() (extracted from unl, probably) and
|
||||
// !lower_cased() when we were testing _identification w/ pypsycd.
|
||||
// of course we'd then have to do host = lower_case(host) in register_host(),
|
||||
// too. }}}
|
||||
int same_host(string a, string b) {
|
||||
//mixed c = host2canonical[lower_case(a)];
|
||||
mixed c = host2canonical[a];
|
||||
|
||||
P2(("same_host %O -> %O ==? %O -> %O\n", a, c, b, host2canonical[b]))
|
||||
//return stringp(c) && c == host2canonical[lower_case(b)];
|
||||
return stringp(c) && c == host2canonical[b];
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ function: register_host
|
||||
varargs void register_host(string host, mixed canonical) {
|
||||
PROTECT("REGISTER_HOST")
|
||||
P2(("register_host %O, %O.\n", host, canonical))
|
||||
if (stringp(canonical)) {
|
||||
if (host2canonical[host] != canonical && host2canonical[host]) {
|
||||
// 0 was already mapped to "andrack.tobij.de", now points ...
|
||||
// dunno why that happens, but here we catch it
|
||||
unless (host) return;
|
||||
|
||||
// this probably only happens if the server has been running
|
||||
// for several weeks.. the fx are probably mostly harmless
|
||||
// just some dynamic ip which gets reused by someone else
|
||||
canonical = lower_case(canonical);
|
||||
if (host2canonical[host] != canonical) {
|
||||
// with akamai sites this happens all the time and is harmless
|
||||
#if 0
|
||||
monitor_report("_warning_overridden_register_host",
|
||||
S("%O was already mapped to %O, now points to %O.",
|
||||
host, host2canonical[host], canonical));
|
||||
#else
|
||||
P1(("%O was already mapped to %O, now points to %O.\n",
|
||||
host, host2canonical[host], canonical))
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else canonical = lower_case(canonical);
|
||||
host2canonical[host] = canonical;
|
||||
P3(("%O mapped to %O.\n", host, canonical))
|
||||
return;
|
||||
}
|
||||
else if (intp(canonical) && canonical < 0) {
|
||||
if (stringp(host2canonical[host])) {
|
||||
// we do get to see this message sometimes.. weird thang dns
|
||||
P1(("%O no longer resolves, we keep it mapped to %O.\n",
|
||||
host, host2canonical[host]))
|
||||
// no this doesn't seem to be triggered by timed out dyndns
|
||||
// as dyndns usually carries around the old ip number
|
||||
return;
|
||||
}
|
||||
// host did not resolve, let's store this fact
|
||||
host2canonical[host] = canonical;
|
||||
return;
|
||||
}
|
||||
|
||||
// we won't need the lambda-closure because of my ingenious varargs design
|
||||
// in dns_resolve() and dns_rresolve()
|
||||
#if 0
|
||||
dns_resolve(host, #'dns_rresolve, lambda(({ 'canonical }),
|
||||
({ #'=, ({ CL_INDEX, host2canonical, host }), 'canonical }) ) );
|
||||
#else
|
||||
dns_resolve(host, #'dns_rresolve,
|
||||
(: if (stringp($1)) $2[$3] = $1;
|
||||
return; :), host2canonical, host);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ function: dns_refresh
|
||||
/** wild idea of tobi, needs an admin command to trigger it */
|
||||
void dns_refresh() {
|
||||
string host;
|
||||
|
||||
PROTECT("DNS_REFRESH")
|
||||
|
||||
foreach (host : m_indices(host2canonical)) { register_host(host); }
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ usage: dns_*resolve
|
||||
// we do know that lambda() might be a quite unfamiliar concept to the usual
|
||||
// coder, so we made dns_resolve() and dns_rresolve() a little more handy.
|
||||
// you can use inline-closures at the caller side, even if you need some
|
||||
// "variables" or arguments which cannot be accessed by an unsual inline
|
||||
// closure (with 3-3 style inline closures that works, but we encourage you
|
||||
// not to use them for backward compatibility).
|
||||
//
|
||||
// so here is an usage example:
|
||||
// dns_resolve(hostname, (: sendmsg($2, "_some_mc", $3 + " has been resolved "
|
||||
// "to " + $1); :), source, hostname);
|
||||
// $1 will be the dns_resolve result, $2 will be source and $3 will be
|
||||
// hostname. as you already guessed, $2 and further are just the arguments
|
||||
// you appended to the dns_resolve() call after the closure, and $1 is, as said,
|
||||
// the dns_resolve() result.
|
||||
// this works for any number of extra arguments.
|
||||
//
|
||||
// this is also works for dns_rresolve()
|
||||
// }}}
|
||||
|
||||
// {{{ function: dns_resolve
|
||||
// {{{ whatis comment
|
||||
/** sends a request to the erq to resolve a hostname, on reception of the
|
||||
** reply does the callback where it passes either the ip-number as string
|
||||
** or -1 for failure, followed by any extra arguments you gave it
|
||||
*/ // }}}
|
||||
void dns_resolve(string hostname, closure callback, varargs array(mixed) extra) {
|
||||
closure c, c2; // proto.h
|
||||
string queuename;
|
||||
|
||||
P4(("dns_resolve called with (%O, %O, %O).\n", hostname, callback, extra))
|
||||
unless (stringp(hostname)) {
|
||||
P1(("dns_resolve called with (%O, %O, %O). stopping.\n", hostname, callback, extra))
|
||||
return;
|
||||
}
|
||||
#ifdef __IDNA__
|
||||
if (catch(hostname = idna_to_ascii(TO_UTF8(hostname)); nolog)) {
|
||||
P0(("catch: punycode %O in %O\n", hostname, ME))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sizeof(extra)) {
|
||||
c2 = lambda( ({ 'name }),
|
||||
({ #'funcall, callback, 'name }) + extra );
|
||||
} else {
|
||||
c2 = callback;
|
||||
}
|
||||
|
||||
// if unnecessary this can move into !__ERQ_MAX_SEND__
|
||||
switch(hostname) {
|
||||
// case myLowerCaseHost: // TODO!!
|
||||
#if defined(SERVER_HOST) && SERVER_HOST != "localhost"
|
||||
case SERVER_HOST:
|
||||
# ifdef __HOST_IP_NUMBER__
|
||||
funcall(c2, __HOST_IP_NUMBER__, callback);
|
||||
# else
|
||||
unless (myIP) break;
|
||||
funcall(c2, myIP, callback);
|
||||
# endif
|
||||
P4(("self rresolution used\n"))
|
||||
return;
|
||||
#endif
|
||||
case "localhost":
|
||||
P3(("localhost rresolution used\n"))
|
||||
funcall(c2, "127.0.0.1", callback);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(hostname,"%~D.%~D.%~D.%~D") == 4) {
|
||||
// hostname is an IP already. Just call the callback.
|
||||
funcall(c2, hostname, callback);
|
||||
return;
|
||||
}
|
||||
#ifdef __ERQ_MAX_SEND__
|
||||
queuename = "f" + hostname;
|
||||
if (qExists(queuename)) {
|
||||
enqueue(queuename, c2);
|
||||
return;
|
||||
} else {
|
||||
qInit(queuename, 1000, 10);
|
||||
enqueue(queuename, c2);
|
||||
}
|
||||
|
||||
c = lambda( ({ 'name }), ({
|
||||
(#'switch), ({ #'sizeof, 'name }),
|
||||
({ 4 }), // ERQ: name resolved!
|
||||
({ (#',),
|
||||
({ (#'=),'name,({ (#'map),'name,#'&,255 }) }),
|
||||
({ (#'=),'name,
|
||||
({
|
||||
(#'sprintf),"%d.%d.%d.%d",
|
||||
({ CL_INDEX, 'name, 0 }),
|
||||
({ CL_INDEX, 'name, 1 }),
|
||||
({ CL_INDEX, 'name, 2 }),
|
||||
({ CL_INDEX, 'name, 3 })
|
||||
})
|
||||
}),
|
||||
({ #'while, ({ #'qSize, queuename }), 42,
|
||||
({ #'catch,
|
||||
({ #'funcall, ({ #'shift, queuename }),
|
||||
'name })
|
||||
})
|
||||
}),
|
||||
({ #'qDel, queuename })
|
||||
}),
|
||||
(#'break),
|
||||
# ifdef XERQ
|
||||
({ 6 + strlen(hostname) }), // XERQ
|
||||
({ (#',),
|
||||
({ (#'=),'name,({ (#'map),'name,#'&,255 }) }),
|
||||
({ (#'=),'name,
|
||||
({
|
||||
(#'sprintf),"%d.%d.%d.%d",
|
||||
({ CL_INDEX, 'name, 1 }),
|
||||
({ CL_INDEX, 'name, 2 }),
|
||||
({ CL_INDEX, 'name, 3 }),
|
||||
({ CL_INDEX, 'name, 4 })
|
||||
})
|
||||
}),
|
||||
({ #'while, ({ #'qSize, queuename }), 42,
|
||||
({ #'catch,
|
||||
({ #'funcall, ({ #'shift, queuename }),
|
||||
'name
|
||||
})
|
||||
})
|
||||
}),
|
||||
({ #'qDel, queuename })
|
||||
}),
|
||||
(#'break),
|
||||
# endif
|
||||
({ #'default }),
|
||||
({
|
||||
(#',),
|
||||
# if DEBUG > 0
|
||||
({ #'debug_message, "ERQ could not resolve \""+ hostname +"\".\n" }),
|
||||
# endif
|
||||
// host2canonical[hostname] = 0; <--
|
||||
({ #'funcall, #'register_host, hostname, -1 }),
|
||||
({ #'while, ({ #'qSize, queuename }), 42,
|
||||
/* held sagt: also zuerst sagt er
|
||||
:* ERQ could not resolve
|
||||
:* und dann die while whiles sind die queues
|
||||
:* also angestaute einträge in der queue
|
||||
:* die er dann mit -1 aufruft
|
||||
:* nach den while whiles wird die queue gelöscht
|
||||
:* und der nächste dns_resolve-aufruf geht wieder an den erq
|
||||
:* ziel der queues ist in diesem falle kein caching, sondern
|
||||
:* nur lineares aufrufen der callbacks
|
||||
:* also, fifo
|
||||
:*/
|
||||
// ({ #'debug_message, "while while "+ hostname + "\n"}),
|
||||
({ #'catch, ({ #'funcall, ({ #'shift, queuename }),
|
||||
-1 }) }) }),
|
||||
({ #'qDel, queuename })
|
||||
}),
|
||||
(#'break)
|
||||
}) );
|
||||
// this efun was introduced shortly after erq was fixed.. btw what does it do?
|
||||
# if __EFUN_DEFINED__(reverse)
|
||||
// we are currently doing too many resolutions.. this is nice for
|
||||
// dyndns but silly if we have a valid tcp connection to the host
|
||||
// in question, thus it is proven that the ip hasn't changed.
|
||||
P3(("resolving "+hostname+"\n"))
|
||||
unless (send_erq(ERQ_LOOKUP, hostname, c))
|
||||
# else
|
||||
// appending the zero byte fixes a bug in erq. sick!
|
||||
unless (send_erq(ERQ_LOOKUP, to_array(hostname) + ({ 0 }), c))
|
||||
# endif
|
||||
#else
|
||||
// it's all pretty useless if __ERQ_MAX_SEND__ is defined
|
||||
// even if ldmud was called with -N. what is this, a bug?
|
||||
P1(("no erq: returning unresolved %O\n", hostname))
|
||||
#endif
|
||||
{
|
||||
P1(("%O failed to ERQ_LOOKUP %O!\n", ME, hostname))
|
||||
// if we cannot resolve using erq, we'll send back the hostname,
|
||||
// so the driver can do a blocking resolve itself (needed for
|
||||
// net_connect())
|
||||
funcall(c2, hostname, callback);
|
||||
#ifdef __ERQ_MAX_SEND__
|
||||
qDel(queuename);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ function: dns_rresolve
|
||||
// {{{ whatis comment
|
||||
/** requests a reverse lookup of the given ip address from the erq process,
|
||||
** on reply calls dns_resolve() to ensure the returned host name does indeed
|
||||
** point to the ip address (protection against basic DNS spoofing), then
|
||||
** does the callback, where it passes either the hostname of the ip as given
|
||||
** by IN PTR, -1 for resolution failure, or -2 for a DNS spoofing attempt.
|
||||
** extra arguments follow, if you provided any.
|
||||
*/ // }}}
|
||||
void dns_rresolve(string ip, closure callback, varargs array(mixed) extra) {
|
||||
closure rresolve, resolve; // proto.h
|
||||
int i1, i2, i3, i4;
|
||||
string queuename;
|
||||
|
||||
P4(("dns_rresolve called with (%O, %O, %O).\n", ip, callback, extra))
|
||||
unless (stringp(ip)) {
|
||||
P1(("dns_rresolve called with (%O, %O, %O). stopping.\n", ip, callback, extra))
|
||||
return;
|
||||
}
|
||||
extra = ({ #'funcall, callback, 'host }) + extra;
|
||||
// if unnecessary this can move into !__ERQ_MAX_SEND__
|
||||
switch(ip) {
|
||||
#ifdef __HOST_IP_NUMBER__
|
||||
# if __HOST_IP_NUMBER__ != "127.0.0.1"
|
||||
case __HOST_IP_NUMBER__:
|
||||
# else
|
||||
# ifndef myIP
|
||||
case myIP:
|
||||
# else
|
||||
case 0: // the hostname IS localhost, so this never happens
|
||||
# endif
|
||||
# endif
|
||||
P4(("self resolution used\n"))
|
||||
if (sizeof(extra)) funcall(lambda( ({ 'host }), extra), SERVER_HOST);
|
||||
else funcall(callback, SERVER_HOST);
|
||||
return;
|
||||
#endif
|
||||
case "127.0.0.1":
|
||||
P3(("localhost resolution used\n"))
|
||||
if (sizeof(extra)) funcall(lambda( ({ 'host }), extra), "localhost");
|
||||
else funcall(callback, "localhost");
|
||||
return;
|
||||
}
|
||||
#ifdef __ERQ_MAX_SEND__
|
||||
unless (sscanf(ip, "%D.%D.%D.%D", i1, i2, i3, i4) == 4) {
|
||||
// that is not an ip. what shall we do?
|
||||
// we're just returning for now. suggestions -> changestodo
|
||||
P1(("dns_rresolve called with (%O, %O, %O). stopping.\n", ip, callback, extra))
|
||||
return;
|
||||
}
|
||||
|
||||
queuename = "r" + ip;
|
||||
|
||||
resolve = lambda( ({ 'host, 'ip, 'rip }),
|
||||
({ #'?,
|
||||
({ #'==, 'ip, 'rip }),
|
||||
({ (#',),
|
||||
({ #'while, ({ #'qSize, queuename }),
|
||||
42,
|
||||
({ #'catch,
|
||||
({ #'funcall, ({ #'shift, queuename }), 'host })
|
||||
})
|
||||
}),
|
||||
({ #'qDel, queuename }),
|
||||
}),
|
||||
({ (#',),
|
||||
({ #'=, 'host, -2 }), // useless line
|
||||
({ #'while, ({ #'qSize, queuename }),
|
||||
42,
|
||||
({ #'catch,
|
||||
({ #'funcall, ({ #'shift, queuename }), -2 })
|
||||
}),
|
||||
}),
|
||||
({ #'qDel, queuename })
|
||||
})
|
||||
}) );
|
||||
|
||||
if (qExists(queuename)) {
|
||||
enqueue(queuename, sizeof(extra)
|
||||
? lambda(({ 'host }), extra)
|
||||
: callback);
|
||||
return;
|
||||
} else {
|
||||
qInit(queuename, 1000, 10);
|
||||
enqueue(queuename, sizeof(extra)
|
||||
? lambda(({ 'host }), extra)
|
||||
: callback);
|
||||
}
|
||||
|
||||
rresolve = lambda( ({ 'name }),
|
||||
({ #'funcall, (:
|
||||
$1 = to_string($1[4..<2]); // extract hostname from crazy
|
||||
// erq return format
|
||||
unless ($1 == "") {
|
||||
dns_resolve($1, lambda( ({ 'name }),
|
||||
({ #'funcall, $4, $1, $2, 'name, $3 }) ));
|
||||
} else {
|
||||
funcall($4, -1, 0, 0, $3);
|
||||
}
|
||||
return; :), 'name, ip, callback, resolve }) );
|
||||
|
||||
unless (send_erq(ERQ_RLOOKUP, ({ i1, i2, i3, i4 }), rresolve))
|
||||
#else
|
||||
P1(("no erq: returning unrresolved %O\n", ip))
|
||||
#endif
|
||||
{
|
||||
P1(("%O failed to ERQ_RLOOKUP!\n", ME))
|
||||
if (sizeof(extra)) {
|
||||
funcall(lambda( ({ 'host }),
|
||||
extra), ip);
|
||||
} else {
|
||||
funcall(callback, ip);
|
||||
}
|
||||
#ifdef __ERQ_MAX_SEND__
|
||||
qDel(queuename);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ function: is_localhost
|
||||
#if 1
|
||||
// take care to always pass a lowercased (virtual) hostname
|
||||
int is_localhost(string host) {
|
||||
// async discovery of virtual hosts is not necessary
|
||||
// we should know all of our hostnames in advance for
|
||||
// security anyway
|
||||
return member(localhosts, host);
|
||||
}
|
||||
#else
|
||||
int is_localhost(string host, closure callback, varargs array(mixed) extra) {
|
||||
if (member(localhosts, host)) {
|
||||
funcall(callback, 1, extra);
|
||||
return;
|
||||
}
|
||||
|
||||
// this is maybe not enough... we should resolve myIP,.. too
|
||||
if (sscanf(host, "%~D.%~D.%~D.%~D") == 4) {
|
||||
// what needs to be done?? rresolve both host and __HOST_IP_NUMBER__ ?
|
||||
dns_rresolve(host,
|
||||
lambda(({ 'hostname }),
|
||||
({ #'funcall, callback,
|
||||
({ #'==, 'hostname, SERVER_HOST }) })
|
||||
+ (sizeof(extra) ? extra : ({ }) )
|
||||
));
|
||||
} else {
|
||||
# if !defined(__HOST_IP_NUMBER__) || __HOST_IP_NUMBER__ != "127.0.0.1"
|
||||
dns_resolve(host,
|
||||
lambda(({ 'hostname }),
|
||||
({ #'funcall, callback,
|
||||
# ifdef __HOST_IP_NUMBER__
|
||||
({ #'==, 'hostname, __HOST_IP_NUMBER__ })
|
||||
# else
|
||||
({ #'==, 'hostname, myIP })
|
||||
# endif
|
||||
}) + (sizeof(extra) ? extra : ({ }) )
|
||||
));
|
||||
# else
|
||||
funcall(callback, 0, extra);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
# if 0
|
||||
// call either true or false
|
||||
void if_localhost(string host, closure true, closure false,
|
||||
varargs array(mixed) extra) {
|
||||
is_localhost(host, lambda(({ 'bol }),
|
||||
({ #'funcall,
|
||||
({ #'?, 'bol, true, false }),
|
||||
}) + (sizeof(extra) ? extra : ({ }) ) ));
|
||||
}
|
||||
# endif
|
||||
#endif // if 1
|
||||
// }}}
|
||||
|
||||
#ifndef ERQ_WITHOUT_SRV
|
||||
// {{{ function: dns_srv_resolve
|
||||
void dns_srv_resolve(string hostname, string service, string proto, closure callback, varargs array(mixed) extra)
|
||||
{
|
||||
#ifdef __ERQ_MAX_SEND__
|
||||
string req;
|
||||
int rc;
|
||||
|
||||
// dumme bevormundung. wegen der musste ich jetzt ewig lang suchen:
|
||||
//unless (proto == "tcp" || proto == "udp") return;
|
||||
// da wir mit nem String arbeiten muessen
|
||||
req = sprintf("_%s._%s.%s", service, proto, hostname);
|
||||
rc = send_erq(ERQ_LOOKUP_SRV, req, lambda(({ 'wu }),
|
||||
({ (#',),
|
||||
({ #'?, ({ #'<, ({ #'sizeof, 'wu }), 3 }),
|
||||
({ (#',),
|
||||
# if DEBUG > 1
|
||||
({ #'debug_message, "Could not srv_resolve _" +service+"._"+proto+"."+ hostname + "\n" }),
|
||||
# endif
|
||||
({ #'funcall, callback, -1 }) + extra,
|
||||
({ #'return, 1 }),
|
||||
}),
|
||||
}),
|
||||
({ #'=, 'i, 0 }),
|
||||
({ #'=, 'resarr, quote(({ })) }),
|
||||
({ #'=, 'wu, ({ #'explode, ({ #'to_string, ({ #'[..<], 'wu, 0, 3 }) }), "\n" }) }),
|
||||
// wieso die if in der condition der while ???
|
||||
({ #'while, ({ #'?, ({ #'<, 'i, ({ #'sizeof, 'wu }) }) }), 42,
|
||||
({ (#',),
|
||||
({ #'+=, 'resarr, ({ #'({, ({ #'({, ({ #'[, 'wu, 'i }), ({ #'to_int, ({ #'[, 'wu, ({ #'+, 'i, 1 }) }) }), ({ #'to_int, ({ #'[, 'wu, ({ #'+, 'i, 2 }) }) }), ({ #'to_int, ({ #'[, 'wu, ({ #'+, 'i, 3 }) }) }) }) }) }),
|
||||
({ #'=, 'i, ({ #'+, 'i, 4 }) })
|
||||
})
|
||||
}),
|
||||
// ({ #'funcall, callback, ({ #'sort_array, 'resarr, sortsrv }) }) + extra
|
||||
({ #'funcall, callback, 'resarr }) + extra
|
||||
})
|
||||
));
|
||||
unless (rc) {
|
||||
P0(("%O failed to ERQ_LOOKUP_SRV!\n", ME))
|
||||
funcall(callback, -1, extra);
|
||||
}
|
||||
// Rueckgabe vom erq bei Fehlschlag -> empty message wie bei ERQ_RLOOKUP
|
||||
// callback sollte erwarten:
|
||||
// ein Array von Arrays jeweils mit name, port, pref, weigth
|
||||
// oder ein einzelnes Array und man betrachtet jeweils vier Dinger
|
||||
// waer dufte wenn die lambda das splitten koennte... sonst muss es
|
||||
// halt nen string sein der zurueckgegeben wird
|
||||
return;
|
||||
#else
|
||||
P1(("no erq: aborting SRV check for %O\n", hostname))
|
||||
funcall(callback, -1, extra);
|
||||
#endif
|
||||
}
|
||||
// }}}
|
||||
#endif
|
20
world/net/library/htbasics.c
Normal file
20
world/net/library/htbasics.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
// $Id: htbasics.c,v 1.5 2007/06/28 20:17:50 lynx Exp $ // vim:syntax=lpc
|
||||
#include <net.h>
|
||||
#include <ht/http.h>
|
||||
|
||||
// html-escaping of generic strings -lynx
|
||||
// to make sure they won't trigger
|
||||
// html commands
|
||||
//
|
||||
string htquote(string s) {
|
||||
ASSERT("htquote", stringp(s), s)
|
||||
s = replace(s, "&", "&");
|
||||
// s = replace(s, "\"", """); //"
|
||||
s = replace(s, "<", "<");
|
||||
s = replace(s, ">", ">");
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef HTTP_PATH
|
||||
# include HTTP_PATH "library.i"
|
||||
#endif
|
79
world/net/library/json.c
Normal file
79
world/net/library/json.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include <net.h>
|
||||
#include <proto.h>
|
||||
|
||||
// pike code can be made to run in lpc and the other way round..
|
||||
#include "jsonparser.pike"
|
||||
|
||||
// see http://about.psyc.eu/Serialisation on the merits of JSON
|
||||
//
|
||||
// this function is useful if we decide to use json for complex data
|
||||
// (or rather cannot come up with something better)
|
||||
//
|
||||
string make_json(mixed d) {
|
||||
if (stringp(d)) {
|
||||
#if 1
|
||||
string *x;
|
||||
|
||||
// this code runs on the presumption that the regexplode
|
||||
// will hardly ever encounter anything. should these chars
|
||||
// be commonplace, then the 7 regreplace approach would be
|
||||
// more efficient.
|
||||
x = regexplode(d, "(\"|\\\\|\n|\t|\b|\r|\f)");
|
||||
if (sizeof(x) > 1) {
|
||||
int i;
|
||||
|
||||
for (i=sizeof(x)-2; i >= 0; i-=2) {
|
||||
switch(x[i]) {
|
||||
case "\"": x[i] = "\\\""; break; // common stuff
|
||||
case "\n": x[i] = "\\n"; break;
|
||||
case "\t": x[i] = "\\t"; break;
|
||||
|
||||
case "\b": x[i] = "\\b"; break; // these chars should
|
||||
case "\r": x[i] = "\\r"; break; // not appear in psyc
|
||||
case "\f": x[i] = "\\f"; break; // strings anyway.. !?
|
||||
case "\\": x[i] = "\\\\"; break;
|
||||
default:
|
||||
raise_error(S("encountered %O in %O\n", x[i], d));
|
||||
}
|
||||
P4((" .. encountered %O", x[i]));
|
||||
}
|
||||
P4((" .. result: %O\n", d))
|
||||
}
|
||||
return "\""+ implode(x, "") +"\"";
|
||||
#else
|
||||
// what i don't like about this thing is 7 calls of regreplace
|
||||
// for every damn little string.
|
||||
d = regreplace(d, "\n", "\\n", 1);
|
||||
d = regreplace(d, "\t", "\\t", 1);
|
||||
d = regreplace(d, "\b", "\\b", 1);
|
||||
d = regreplace(d, "\r", "\\r", 1);
|
||||
d = regreplace(d, "\f", "\\f", 1);
|
||||
//d = regreplace(d, "\u", "\\u", 1); // unicode..???
|
||||
d = regreplace(d, "\"", "\\\"", 1);
|
||||
d = regreplace(d, "\\\\", "\\\\\\\\", 1);
|
||||
return "\""+ d +"\"";
|
||||
#endif
|
||||
} else if (intp(d)) {
|
||||
return to_string(d);
|
||||
} else if (pointerp(d)) {
|
||||
return "[ " + implode(map(d, #'make_json), ", ") + " ]";
|
||||
} else if (mappingp(d)) {
|
||||
#if 0
|
||||
return "{ " + implode(map(d,
|
||||
(: return $1 + " : " + make_json($2[0]); :)),
|
||||
", ") + " }";
|
||||
#else
|
||||
// mixed x = map(d,
|
||||
// (: return make_json($1) +" : "+ make_json($2); :));
|
||||
// let's presume a key of type string doesnt contain evil chars
|
||||
mixed x = map(d,
|
||||
(: return (stringp($1) ? ("\""+ $1 +"\"") : make_json($1))
|
||||
+":"+ make_json($2); :));
|
||||
P3(("\nintermediate: %O\n", m_values(x)))
|
||||
return "{"+ implode(m_values(x), ",") +"}";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// see also net/place/storic.c for a JSON generator limited and optimized
|
||||
// to the output of HTML-quoted strings.
|
620
world/net/library/jsonparser.pike
Normal file
620
world/net/library/jsonparser.pike
Normal file
|
@ -0,0 +1,620 @@
|
|||
// vim:syntax=lpc
|
||||
// $Id: jsonparser.pike,v 1.2 2006/10/25 17:50:11 lynx Exp $
|
||||
//
|
||||
// I really hate those comments.
|
||||
//
|
||||
// Copyright History:
|
||||
// 1. Public Domain 2002 JSON.org
|
||||
// 2. Ported to C# by Are Bjolseth, teleplan.no
|
||||
// 3. Ported to pike by Bill Welliver
|
||||
// "Last night, I downloaded the JSON-C# code, and converted it to pike
|
||||
// (with relatively little effort, it was mostly a tedious reformatting
|
||||
// job)."
|
||||
// 4. Adopted by Tobias 'tobij' Josefowitz, now uses Pike datastructures,
|
||||
// and can only be run in LDMud.
|
||||
//
|
||||
// As far as I am concerned, this still is Public Domain.
|
||||
// I will probably once find out whether Are and Bill think the same wwy
|
||||
// about it.
|
||||
|
||||
#ifdef __PIKE__
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// A JSONTokener takes a source string and extracts characters and tokens from
|
||||
/// it. It is used by the JSONObject and JSONArray constructors to parse
|
||||
/// JSON source strings.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Public Domain 2002 JSON.org
|
||||
/// @author JSON.org
|
||||
/// @version 0.1
|
||||
/// </para>
|
||||
/// <para>Ported to C# by Are Bjolseth, teleplan.no</para>
|
||||
/// <para>
|
||||
/// <list type="bullet">
|
||||
/// <item><description>Implement Custom exceptions</description></item>
|
||||
/// <item><description>Add unit testing</description></item>
|
||||
/// <item><description>Add log4net</description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <summary>The index of the next character.</summary>
|
||||
int myIndex;
|
||||
/// <summary>The source string being tokenized.</summary>
|
||||
string mySource;
|
||||
|
||||
# define PROTECTED public
|
||||
|
||||
# define THROW(x) throw(Error.Generic(x))
|
||||
# define SBGET(x) (x)->get()
|
||||
|
||||
# define int2char(x) String.int2char(x)
|
||||
# define trim_whites(x) String.trim_whites(x)
|
||||
|
||||
program objectbuilder, arraybuilder;
|
||||
#else
|
||||
# define PROTECTED protected
|
||||
|
||||
PROTECTED int myIndex;
|
||||
PROTECTED string mySource;
|
||||
|
||||
# define arrayp(x) pointerp(x)
|
||||
# define THROW(x) raise_error(x)
|
||||
# define UNDEFINED 0
|
||||
# define SBGET(x) (x)
|
||||
|
||||
# define int2char(x) _int2char(x)
|
||||
# define trim_whites(x) trim(x)
|
||||
# define search strstr
|
||||
|
||||
PROTECTED mixed nextObject();
|
||||
|
||||
PROTECTED string _int2char(int c) {
|
||||
string s = " ";
|
||||
|
||||
s[0] = c;
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Construct a JSONTokener from a string.
|
||||
/// </summary>
|
||||
/// <param name="s">A source string.</param>
|
||||
#ifdef __PIKE__
|
||||
void create(string s, program|void objectb, program|void arrayb)
|
||||
#else
|
||||
mixed parse_json(string s)
|
||||
#endif
|
||||
{
|
||||
mySource = s;
|
||||
myIndex = 0;
|
||||
#ifdef __PIKE__
|
||||
objectbuilder = objectb;
|
||||
arraybuilder = arrayb;
|
||||
#else
|
||||
return nextObject();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Back up one character. This provides a sort of lookahead capability,
|
||||
/// so that you can test for a digit or letter before attempting to parse
|
||||
/// the next number or identifier.
|
||||
/// </summary>
|
||||
PROTECTED void back() {
|
||||
if (myIndex > 0)
|
||||
myIndex -= 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the hex value of a character (base16).
|
||||
/// </summary>
|
||||
/// <param name="c">
|
||||
/// A character between '0' and '9' or between 'A' and 'F' or
|
||||
/// between 'a' and 'f'.
|
||||
/// </param>
|
||||
/// <returns>An int between 0 and 15, or -1 if c was not a hex digit.</returns>
|
||||
PROTECTED int dehexchar(int c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
return c + 10 - 'A';
|
||||
}
|
||||
if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
return c + 10 - 'a';
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if the source string still contains characters that next() can consume.
|
||||
/// </summary>
|
||||
/// <returns>true if not yet at the end of the source.</returns>
|
||||
PROTECTED int more() {
|
||||
return myIndex < sizeof(mySource);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the next character in the source string.
|
||||
/// </summary>
|
||||
/// <returns>The next character, or 0 if past the end of the source string.</returns>
|
||||
#ifdef __PIKE__
|
||||
PROTECTED int next(int|void x)
|
||||
#else
|
||||
varargs PROTECTED int next(int x)
|
||||
#endif
|
||||
{
|
||||
if(x) {
|
||||
int n = next();
|
||||
|
||||
if (n != x) {
|
||||
THROW("Expected '" + x + "' and instead saw '" + n + "'.\n");
|
||||
}
|
||||
|
||||
return n;
|
||||
} else {
|
||||
int c = more() ? mySource[myIndex] : 0;
|
||||
|
||||
myIndex += 1;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the next n characters.
|
||||
/// </summary>
|
||||
/// <param name="n">The number of characters to take.</param>
|
||||
/// <returns>A string of n characters.</returns>
|
||||
PROTECTED string nextn(int n) {
|
||||
int i = myIndex;
|
||||
int j = i + n;
|
||||
|
||||
if (j >= sizeof(mySource)) {
|
||||
THROW("Substring bounds error\n");
|
||||
}
|
||||
myIndex += n;
|
||||
return mySource[i..j];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the next char in the string, skipping whitespace
|
||||
/// and comments (slashslash and slashstar).
|
||||
/// </summary>
|
||||
/// <returns>A character, or 0 if there are no more characters.</returns>
|
||||
PROTECTED int nextClean() {
|
||||
while (1) {
|
||||
int c = next();
|
||||
if (c == '/') {
|
||||
switch (next()) {
|
||||
case '/':
|
||||
do {
|
||||
c = next();
|
||||
} while (c != '\n' && c != '\r' && c != 0);
|
||||
break;
|
||||
case '*':
|
||||
while (1) {
|
||||
c = next();
|
||||
|
||||
if (c == 0) {
|
||||
THROW("Unclosed comment.\n");
|
||||
}
|
||||
|
||||
if (c == '*') {
|
||||
if (next() == '/') {
|
||||
break;
|
||||
}
|
||||
|
||||
back();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
back();
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
else if (c == 0 || c > ' ') {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __PIKE__
|
||||
return 0; // will never be reached, stupid LDMud!
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the characters up to the next close quote character.
|
||||
/// Backslash processing is done. The formal JSON format does not
|
||||
/// allow strings in single quotes, but an implementation is allowed to
|
||||
/// accept them.
|
||||
/// </summary>
|
||||
/// <param name="quote">The quoting character, either " or '</param>
|
||||
/// <returns>A String.</returns>
|
||||
PROTECTED string nextString(int quote) {
|
||||
int c;
|
||||
#ifdef __PIKE__
|
||||
String.Buffer sb = String.Buffer();
|
||||
#else
|
||||
string sb = "";
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
c = next();
|
||||
if ((c == 0x00) || (c == 0x0A) || (c == 0x0D)) {
|
||||
THROW("Unterminated string.\n");
|
||||
}
|
||||
// CTRL chars
|
||||
if (c == '\\') {
|
||||
c = next();
|
||||
switch (c) {
|
||||
case 'b': //Backspace
|
||||
sb+="\b";
|
||||
break;
|
||||
case 't': //Horizontal tab
|
||||
sb+="\t";
|
||||
break;
|
||||
case 'n': //newline
|
||||
sb+="\n";
|
||||
break;
|
||||
case 'f': //Form feed
|
||||
sb+="\f";
|
||||
break;
|
||||
case 'r': // Carriage return
|
||||
sb+="\r";
|
||||
break;
|
||||
case 'u':
|
||||
#ifdef __PIKE__
|
||||
int iascii;
|
||||
sscanf(nextn(4), "%4x", iascii);
|
||||
sb+=int2char(iascii);
|
||||
#else
|
||||
sb+=int2char(hex2int(nextn(2)));
|
||||
sb+=int2char(hex2int(nextn(2)));
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
sb+=int2char(c);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (c == quote) {
|
||||
#ifdef __PIKE__
|
||||
return SBGET(sb);
|
||||
#else
|
||||
return sb;
|
||||
#endif
|
||||
}
|
||||
sb+=int2char(c);
|
||||
}
|
||||
}//END-while
|
||||
|
||||
#ifndef __PIKE__
|
||||
return ""; // will never be reached. stupid LDMud
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unescape the source text. Convert %hh sequences to single characters,
|
||||
/// and convert plus to space. There are Web transport systems that insist on
|
||||
/// doing unnecessary URL encoding. This provides a way to undo it.
|
||||
/// </summary>
|
||||
|
||||
/// <summary>
|
||||
/// Convert %hh sequences to single characters, and convert plus to space.
|
||||
/// </summary>
|
||||
/// <param name="s">A string that may contain plus and %hh sequences.</param>
|
||||
/// <returns>The unescaped string.</returns>
|
||||
#ifdef __PIKE__
|
||||
PROTECTED string unescape(string|void s)
|
||||
#else
|
||||
PROTECTED varargs string unescape(string s)
|
||||
#endif
|
||||
{
|
||||
if(!s) s = mySource;
|
||||
int len = sizeof(s);
|
||||
#ifdef __PIKE__
|
||||
String.Buffer sb = String.Buffer();
|
||||
#else
|
||||
string sb = "";
|
||||
#endif
|
||||
|
||||
for (int i=0; i < len; i++) {
|
||||
int c = s[i];
|
||||
if (c == '+') {
|
||||
c = ' ';
|
||||
} else if (c == '%' && (i + 2 < len)) {
|
||||
int d = dehexchar(s[i+1]);
|
||||
int e = dehexchar(s[i+2]);
|
||||
if (d >= 0 && e >= 0) {
|
||||
c = (d*16 + e);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
sb+=int2char(c);
|
||||
}
|
||||
return SBGET(sb);
|
||||
}
|
||||
|
||||
#ifdef __PIKE__
|
||||
mapping|object jsonObject()
|
||||
#else
|
||||
mapping jsonObject()
|
||||
#endif
|
||||
{
|
||||
#ifdef __PIKE__
|
||||
mixed addTo = objectbuilder ? objectbuilder() : ([ ]);
|
||||
#else
|
||||
mapping addTo = ([ ]);
|
||||
#endif
|
||||
|
||||
if (next() == '%') {
|
||||
unescape();
|
||||
}
|
||||
|
||||
back();
|
||||
|
||||
if (nextClean() != '{') {
|
||||
THROW("A JSONObject must begin with '{'.\n");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int c;
|
||||
string key;
|
||||
mixed obj;
|
||||
|
||||
c = nextClean();
|
||||
switch (c) {
|
||||
case 0:
|
||||
THROW("A JSONObject must end "
|
||||
"with '}'.\n");
|
||||
case '}':
|
||||
#ifdef __PIKE__
|
||||
return mappingp(addTo)
|
||||
? addTo
|
||||
: ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
case '"':
|
||||
back();
|
||||
// TODO:: error on != " || '
|
||||
key = nextObject();
|
||||
break;
|
||||
default:
|
||||
THROW("Non-String as "
|
||||
"JSONObject-key. That "
|
||||
"is invalid!\n");
|
||||
}
|
||||
|
||||
if (nextClean() != ':') {
|
||||
THROW("Expected a ':' after a key.\n");
|
||||
}
|
||||
|
||||
obj = nextObject();
|
||||
|
||||
#ifdef __PIKE__
|
||||
if (mappingp(addTo)) {
|
||||
([mapping]addTo)[key] = obj;
|
||||
} else {
|
||||
([object]addTo)->add(key, obj);
|
||||
}
|
||||
#else
|
||||
addTo[key] = obj;
|
||||
#endif
|
||||
|
||||
switch (nextClean()) {
|
||||
case ',':
|
||||
if (nextClean() == '}') {
|
||||
#ifdef __PIKE__
|
||||
return mappingp(addTo) ? addTo : ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
}
|
||||
|
||||
back();
|
||||
break;
|
||||
case '}':
|
||||
#ifdef __PIKE__
|
||||
return mappingp(addTo) ? addTo : ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
default:
|
||||
THROW("Expected a ',' or '}'");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __PIKE__
|
||||
return mappingp(addTo) ? addTo : ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __PIKE__
|
||||
array|object jsonArray()
|
||||
#else
|
||||
mixed *jsonArray()
|
||||
#endif
|
||||
{
|
||||
#ifdef __PIKE__
|
||||
mixed addTo = objectbuilder ? objectbuilder() : ({ });
|
||||
#else
|
||||
mixed *addTo = ({ });
|
||||
#endif
|
||||
|
||||
if (nextClean() != '[') {
|
||||
THROW("A JSONArray must start with '['.\n");
|
||||
}
|
||||
|
||||
if (nextClean() == ']') {
|
||||
#ifdef __PIKE__
|
||||
return arrayp(addTo) ? addTo : ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
}
|
||||
|
||||
back();
|
||||
while (1) {
|
||||
if (arrayp(addTo)) {
|
||||
addTo += ({ nextObject() });
|
||||
} else {
|
||||
addTo->add(nextObject());
|
||||
}
|
||||
|
||||
switch (nextClean())
|
||||
{
|
||||
case ',':
|
||||
if (nextClean() == ']') {
|
||||
#ifdef __PIKE__
|
||||
return arrayp(addTo)
|
||||
? addTo
|
||||
: ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
}
|
||||
back();
|
||||
break;
|
||||
case ']':
|
||||
#ifdef __PIKE__
|
||||
return arrayp(addTo)
|
||||
? addTo
|
||||
: ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
default:
|
||||
THROW("Expected a ',' or ']'.\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __PIKE__
|
||||
return arrayp(addTo) ? addTo : ([object]addTo)->finish();
|
||||
#else
|
||||
return addTo;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the next value as object. The value can be a Boolean, Double, Integer,
|
||||
/// JSONArray, JSONObject, or String, or the JSONObject.NULL object.
|
||||
/// </summary>
|
||||
/// <returns>An object.</returns>
|
||||
PROTECTED mixed nextObject() {
|
||||
int c = nextClean();
|
||||
string s;
|
||||
|
||||
if (c == '"' || c == '\'') {
|
||||
return nextString(c);
|
||||
}
|
||||
// Object
|
||||
if (c == '{') {
|
||||
back();
|
||||
return jsonObject();
|
||||
}
|
||||
|
||||
// JSON Array
|
||||
if (c == '[') {
|
||||
back();
|
||||
return jsonArray();
|
||||
}
|
||||
|
||||
#ifdef __PIKE__
|
||||
String.Buffer sb = String.Buffer();
|
||||
#else
|
||||
string sb = "";
|
||||
#endif
|
||||
|
||||
int b = c;
|
||||
while (c >= ' ' && c != ':' && c != ',' && c != ']' && c != '}' && c != '/') {
|
||||
sb+=int2char(c);
|
||||
c = next();
|
||||
}
|
||||
back();
|
||||
|
||||
s = trim_whites(SBGET(sb));
|
||||
if (s == "true")
|
||||
return 1;
|
||||
if (s == "false")
|
||||
return 0;
|
||||
if (s == "null")
|
||||
return UNDEFINED;
|
||||
|
||||
if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
|
||||
int a; float b_; string c_;
|
||||
sscanf(s, "%d%s", a, c_);
|
||||
if(c_ && sizeof(c_)) {
|
||||
#ifdef __PIKE__
|
||||
sscanf(s, "%f", b_);
|
||||
#else
|
||||
b_ = to_float(s);
|
||||
#endif
|
||||
return b_;
|
||||
}
|
||||
else return a;
|
||||
}
|
||||
if (s == "") {
|
||||
THROW("Missing value.\n");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skip characters until the next character is the requested character.
|
||||
/// If the requested character is not found, no characters are skipped.
|
||||
/// </summary>
|
||||
/// <param name="to">A character to skip to.</param>
|
||||
/// <returns>
|
||||
/// The requested character, or zero if the requested character is not found.
|
||||
/// </returns>
|
||||
PROTECTED int skipTo(int to) {
|
||||
int c;
|
||||
int i = myIndex;
|
||||
do {
|
||||
c = next();
|
||||
if (c == 0) {
|
||||
myIndex = i;
|
||||
return c;
|
||||
}
|
||||
}while (c != to);
|
||||
|
||||
back();
|
||||
return c;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skip characters until past the requested string.
|
||||
/// If it is not found, we are left at the end of the source.
|
||||
/// </summary>
|
||||
/// <param name="to">A string to skip past.</param>
|
||||
PROTECTED void skipPast(string to) {
|
||||
myIndex = search(mySource, to, myIndex);
|
||||
if (myIndex < 0) {
|
||||
myIndex = sizeof(mySource);
|
||||
} else {
|
||||
myIndex += sizeof(to);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO implement exception SyntaxError
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Make a printable string of this JSONTokener.
|
||||
/// </summary>
|
||||
/// <returns>" at character [myIndex] of [mySource]"</returns>
|
||||
PROTECTED string ToString() {
|
||||
return " at character " + myIndex + " of " + mySource;
|
||||
}
|
||||
|
88
world/net/library/legal.c
Normal file
88
world/net/library/legal.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
// $Id: legal.c,v 1.16 2008/02/10 14:27:17 lynx Exp $ // vim:syntax=lpc
|
||||
#include <net.h>
|
||||
|
||||
// legal nickname/placename test..
|
||||
string legal_name(string n) {
|
||||
int i;
|
||||
|
||||
//PT(("legal_name(%O) in %O\n", n, ME))
|
||||
if (shutdown_in_progress) {
|
||||
P1(("not legal_name for %O: shutdown in progress\n", n))
|
||||
return 0;
|
||||
}
|
||||
if (!n || n == "") {
|
||||
P1(("not legal_name: %O is empty\n", n))
|
||||
return 0; // "somebody";
|
||||
}
|
||||
#ifdef MAX_NAME_LEN
|
||||
if (strlen(n) > MAX_NAME_LEN) {
|
||||
P1(("not legal_name: %O exceeds MAX_NAME_LEN\n", n))
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
// this saves applet/user from malfunction!
|
||||
if (index("!=-", n[0]) != -1) {
|
||||
P1(("not legal_name: %O has !=- as first char.\n", n))
|
||||
return 0;
|
||||
}
|
||||
for (i=strlen(n)-1; i>=0; i--) {
|
||||
if (index("\
|
||||
abcdefghijklmnopqrstuvwxyz\
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
||||
0123456789_-=+", n[i]) == -1) {
|
||||
P1(("not legal_name: %O has ill char at %d (%O).\n",
|
||||
n, i, n[i]))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
array(string) legal_password(string pw, string nick) {
|
||||
int i;
|
||||
|
||||
if (shutdown_in_progress)
|
||||
return ({ "_failure_server_shutdown",
|
||||
"Sorry, server is being shut down.\n" });
|
||||
|
||||
if (!stringp(pw) || strlen(pw) < 3)
|
||||
return ({ "_error_illegal_password_size",
|
||||
"That password is too short.\n" });
|
||||
|
||||
if (index(pw, '<') != -1 || index(pw, '>') != -1)
|
||||
return ({ "_error_illegal_password_characters",
|
||||
"Password contains illegal characters.\n" });
|
||||
|
||||
if (nick && strstr(lower_case(pw), lower_case(nick), 0) != -1)
|
||||
return ({ "_error_illegal_password_username",
|
||||
"That password contains your nickname.\n" });
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for legal PSYC keyword (var or mc names), see specs */
|
||||
#ifndef legal_keyword // inline variant is better of course
|
||||
int legal_keyword(string n) {
|
||||
# if __EFUN_DEFINED__(regreplace)
|
||||
# include <regexp.h>
|
||||
string t = regmatch(n, "[^_0-9A-Za-z]");
|
||||
P1(("legal_keyword(%O) says %O\n", n, t))
|
||||
return !t;
|
||||
# else
|
||||
int i;
|
||||
|
||||
for (i=strlen(n)-1; i>=0; i--) {
|
||||
if (index("_\
|
||||
abcdefghijklmnopqrstuvwxyz\
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
||||
0123456789", n[i]) == -1) {
|
||||
P1(("not legal_keyword: %O has ill char at %d (%O).\n",
|
||||
n, i, n[i]))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
21
world/net/library/library2.i
Normal file
21
world/net/library/library2.i
Normal file
|
@ -0,0 +1,21 @@
|
|||
// vim:noexpandtab:syntax=lpc
|
||||
// $Id: library2.i,v 1.19 2007/10/08 11:00:31 lynx Exp $
|
||||
|
||||
#include <sandbox.h>
|
||||
|
||||
// one day this could be merged with PSYC_SYNCHRONIZE into
|
||||
// channels of the same context
|
||||
static object monitor;
|
||||
|
||||
void monitor_report(string mc, string text) {
|
||||
#if DEBUG < 2
|
||||
debug_message("MONITOR: "+ text +"\n");
|
||||
#endif
|
||||
log_file("MONITOR", mc +"\t"+ text +"\n");
|
||||
#ifndef __PIKE__ // TPD
|
||||
unless (monitor) monitor = load_object(PLACE_PATH "monitor");
|
||||
if (monitor) monitor->msg(previous_object() || query_server_unl(),
|
||||
mc, text, ([]));
|
||||
#endif
|
||||
}
|
||||
|
121
world/net/library/profiles.c
Normal file
121
world/net/library/profiles.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include <net.h>
|
||||
#include <xml.h>
|
||||
|
||||
#include "profiles.i"
|
||||
|
||||
// convert a setting name from source format to target format, null == psyc
|
||||
varargs string convert_setting(string name, string sf, string tf) {
|
||||
switch (sf) {
|
||||
case "set":
|
||||
name = set2psyc[name];
|
||||
break;
|
||||
case "jCard":
|
||||
name = jCard2psyc[name];
|
||||
break;
|
||||
case "vCard":
|
||||
name = vCard2psyc[name];
|
||||
break;
|
||||
case "LDAP":
|
||||
name = ldap2psyc[name];
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
unless (name) return 0;
|
||||
|
||||
switch (tf) {
|
||||
case "set":
|
||||
name = psyc2set[name];
|
||||
break;
|
||||
case "jProf":
|
||||
name = psyc2jProf[name];
|
||||
break;
|
||||
case "jCard":
|
||||
name = psyc2jCard[name];
|
||||
break;
|
||||
case "vCard":
|
||||
name = psyc2vCard[name];
|
||||
break;
|
||||
case "LDAP":
|
||||
name = psyc2ldap[name];
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// convert a profile from source format to target format, null == psyc
|
||||
varargs mixed convert_profile(mixed p, string sf, string tf) {
|
||||
string k, vc, t, t2;
|
||||
XMLNode n, n2;
|
||||
mixed val;
|
||||
mapping vars = ([ ]);
|
||||
|
||||
// could also create arrays, but not sure if that's useful to anyone
|
||||
#define append(v, nu) if (stringp(nu)) v = stringp(v) ? (v +" "+ nu) : nu;
|
||||
|
||||
// first convert source format to psyc vars
|
||||
switch (sf) {
|
||||
case "jCard":
|
||||
P3(("debug jCard2psyc with p = %O\n", p))
|
||||
foreach( k,vc : jCard2psyc) {
|
||||
if (sscanf(k, "%s/%s", t, t2) && (n = p["/" + t])
|
||||
&& !nodelistp(n) && (n2 = n["/" + t2])) {
|
||||
append(vars[vc], n2[Cdata]);
|
||||
} else if ((n = p["/" + k]) && !nodelistp(n)) {
|
||||
append(vars[vc], n[Cdata]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "set":
|
||||
foreach( k,val : p ) {
|
||||
t = set2psyc[k];
|
||||
if (t) vars[t] = val;
|
||||
else D(k +" can't be set2psyc? never mind.\n");
|
||||
}
|
||||
break;
|
||||
default: // no source format, p contains the vars
|
||||
vars = p;
|
||||
break;
|
||||
}
|
||||
|
||||
// then convert psyc vars to target format
|
||||
switch (tf) {
|
||||
case "jCard":
|
||||
// am i allowed to add newlines?
|
||||
t = "<vCard xmlns='vcard-temp'>";
|
||||
foreach( vc,k : psyc2jCard) {
|
||||
// should be able to render ints too meguess
|
||||
if (stringp(vars[vc])) t += sprintf(k, vars[vc]);
|
||||
}
|
||||
return t + "</vCard>";
|
||||
case "jProf":
|
||||
// see discussion in wiki:
|
||||
// http://about.psyc.eu/Jabber#JEP_0154
|
||||
t = "<field var='FORM_TYPE' type='hidden'>"
|
||||
"<value>http://jabber.org/protocol/profile</value>"
|
||||
"</field>";
|
||||
foreach( vc,k : psyc2jProf) t += "<field var='"+ k +"'><value>"
|
||||
+ vars[vc] +"</value></field>";
|
||||
return t; // no wrapper?
|
||||
case "set":
|
||||
p = ([]);
|
||||
foreach( k,val : vars ) {
|
||||
t = psyc2set[k];
|
||||
if (t) p[t] = val;
|
||||
else D(k +" can't be psyc2set? never mind.\n");
|
||||
}
|
||||
return p;
|
||||
default: // no target format, return the psyc vars
|
||||
return vars;
|
||||
}
|
||||
|
||||
// other cases not supported yet
|
||||
raise_error("cannot convert from "+sf+" to "+tf+" (yet)\n");
|
||||
return 0;
|
||||
}
|
130
world/net/library/profiles.html
Normal file
130
world/net/library/profiles.html
Normal file
|
@ -0,0 +1,130 @@
|
|||
<style> td { background-color: #ccc } </style>
|
||||
<title>PROFILING FIELD NAMES COMPARISON CHART</title>
|
||||
<body bgcolor="#ff9900" text=black link=red vlink=black>
|
||||
<h1>PROFILING FIELD NAMES COMPARISON CHART</h1>
|
||||
<table cellspacing=2>
|
||||
<tr align=left><th>PSYC</th><th>/set</th><th>jProf</th><th>vCard</th><th>jCard</th><th>LDAP</th><th>FOAF</th></tr>
|
||||
<tr><td>_INTERNAL_image_photo</td><td></td><td>photo_data</td><td>PHOTO</td><td>PHOTO/BINVAL</td><td>jpegPhoto</td><td></td></tr>
|
||||
<tr><td>_INTERNAL_type_image_photo</td><td></td><td></td><td></td><td>PHOTO/TYPE</td><td></td><td></td></tr>
|
||||
<tr><td>_action_ask</td><td>askaction</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_action_motto</td><td>mottoaction</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_action_speak</td><td>speakaction</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_address_area</td><td>area</td><td>area</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_address_box_postal</td><td>postalbox</td><td>postalbox</td><td>POBOX</td><td>ADR/POBOX</td><td>postOfficeBox</td><td></td></tr>
|
||||
<tr><td>_address_building</td><td>building</td><td>building</td><td>EXTADD</td><td>ADR/EXTADD</td><td></td><td></td></tr>
|
||||
<tr><td>_address_code_postal</td><td>postalcode</td><td>postalcode</td><td>PCODE</td><td>ADR/PCODE</td><td>postalCode</td><td></td></tr>
|
||||
<tr><td>_address_country</td><td>country</td><td>country</td><td>COUNTRY</td><td>ADR/CTRY</td><td>c</td><td></td></tr>
|
||||
<tr><td>_address_floor</td><td>floor</td><td>floor</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_address_latitude</td><td>latitude</td><td>lat</td><td>LAT</td><td>GEO/LAT</td><td></td><td></td></tr>
|
||||
<tr><td>_address_locality</td><td>locality</td><td>locality</td><td>LOCALITY</td><td>ADR/LOCALITY</td><td>l</td><td></td></tr>
|
||||
<tr><td>_address_longitude</td><td>longitude</td><td>lon</td><td>LON</td><td>GEO/LON</td><td></td><td></td></tr>
|
||||
<tr><td>_address_past</td><td>past</td><td>places_lived</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_address_region</td><td>region</td><td>region</td><td>REGION</td><td>ADR/REGION</td><td>st</td><td></td></tr>
|
||||
<tr><td>_address_room</td><td>room</td><td>room</td><td></td><td></td><td>roomNumber</td><td></td></tr>
|
||||
<tr><td>_address_street</td><td>street</td><td>street</td><td>STREET</td><td>ADR/STREET</td><td>street</td><td></td></tr>
|
||||
<tr><td>_address_zone_time</td><td>timezone</td><td></td><td>TZ</td><td>TZ</td><td></td><td></td></tr>
|
||||
<tr><td>_affiliation</td><td>affiliation</td><td>org_name</td><td>ORGNAME</td><td>ORG/ORGNAME</td><td>o</td><td></td></tr>
|
||||
<tr><td>_character_action</td><td>actioncharacter</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_character_command</td><td>commandcharacter</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_color</td><td>color</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_contact_telephone</td><td>phone</td><td>landline</td><td></td><td>TEL/NUMBER</td><td>telephoneNumber</td><td>phone</td></tr>
|
||||
<tr><td>_contact_telephone_fax</td><td>fax</td><td>fax</td><td>TEL;FAX</td><td></td><td>facsimileTelephoneNumber</td><td></td></tr>
|
||||
<tr><td>_contact_telephone_pager</td><td>pager</td><td>pager</td><td>TEL;PAGER</td><td></td><td>pager</td><td></td></tr>
|
||||
<tr><td>_contact_telephone_voice_home</td><td>homephone</td><td></td><td>TEL;VOICE;HOME</td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_contact_telephone_voice_mobile</td><td>mobilephone</td><td>mobile</td><td>TEL;CELL</td><td></td><td>mobile</td><td>phone</td></tr>
|
||||
<tr><td>_contact_telephone_voice_work</td><td>workphone</td><td></td><td>TEL;VOICE;WORK</td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_date_birth</td><td>birthday</td><td>birth</td><td>BDAY</td><td>BDAY</td><td></td><td></td></tr>
|
||||
<tr><td>_date_name</td><td>nameday</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_date_wedding</td><td>weddingday</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_expertise</td><td>expertisetext</td><td>expertise</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_hobby</td><td>hobbytext</td><td>hobby</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_motto</td><td>mottotext</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_preferences</td><td>likestext</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_preferences_not</td><td>dislikestext</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_presence</td><td>presencetext</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_private</td><td>privatetext</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_description_public</td><td>publictext</td><td>description</td><td></td><td>DESC</td><td>description</td><td></td></tr>
|
||||
<tr><td>_description_quotes</td><td>quotestext</td><td>fav_quotes</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_encoding_characters</td><td>charset</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_animal</td><td>animalfave</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_athletes</td><td>athletesfave</td><td>fav_athletes</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_drinks</td><td>drinksfave</td><td>fav_drinks</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_foods</td><td>foodsfave</td><td>fav_foods</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_games</td><td>gamesfave</td><td>fav_games</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_literature</td><td>literaturefave</td><td>fav_authors</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_movies</td><td>moviesfave</td><td>fav_movies</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_music</td><td>musicfave</td><td>fav_music</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_popstar</td><td>popstarfave</td><td>fav_stars</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_teams</td><td>teamsfave</td><td>fav_teams</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_favorite_television</td><td>televisionfave</td><td>fav_tv</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_action_speak_visible</td><td>visiblespeakaction</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_colors_ignore</td><td>ignorecolors</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_echo</td><td>echo</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_expose_friends</td><td>friendsexpose</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_expose_groups</td><td>groupsexpose</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_filter_strangers</td><td>filter</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_greeting</td><td>greeting</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_places_multiple</td><td>multipleplaces</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_presence_ctcp</td><td>ctcppresence</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_screen_clear</td><td>clearscreen</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_stamp_time</td><td>timestamp</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_uniform_verbatim</td><td>verbatimuniform</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_flag_visibility</td><td>visibility</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_gender</td><td>sex</td><td>gender</td><td></td><td></td><td></td><td>gender</td></tr>
|
||||
<tr><td>_identification</td><td>id</td><td>psyc_id</td><td></td><td>PSYCID</td><td></td><td>psycID</td></tr>
|
||||
<tr><td>_identification_other</td><td>otherid</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_identification_scheme_AIM</td><td>aimid</td><td>aim_id</td><td></td><td></td><td></td><td>aimChatID</td></tr>
|
||||
<tr><td>_identification_scheme_ICQ</td><td>icqid</td><td>icq_id</td><td></td><td></td><td></td><td>icqChatID</td></tr>
|
||||
<tr><td>_identification_scheme_MSN</td><td>msnid</td><td>msn_id</td><td></td><td></td><td></td><td>msnChatID</td></tr>
|
||||
<tr><td>_identification_scheme_SIP</td><td>sipid</td><td>sip_address</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_identification_scheme_Skype</td><td>skypeid</td><td>skype_address</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_identification_scheme_XMPP</td><td>xmppid</td><td>jid</td><td></td><td>JABBERID</td><td></td><td>jabberID</td></tr>
|
||||
<tr><td>_identification_scheme_Yahoo</td><td>yahooid</td><td>yahoo_id</td><td></td><td></td><td></td><td>yahooChatID</td></tr>
|
||||
<tr><td>_identification_scheme_mailto</td><td>email</td><td>email</td><td>EMAIL</td><td>EMAIL/USERID</td><td>mail</td><td></td></tr>
|
||||
<tr><td>_identification_videophone</td><td>videophoneid</td><td>video_phone</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_image_character</td><td>characterimage</td><td>avatar_data</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_language</td><td>language</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_language_alternate</td><td>alternatelanguage</td><td>languages_well</td><td></td><td></td><td>preferredLanguage</td><td></td></tr>
|
||||
<tr><td>_language_optional</td><td>optionallanguage</td><td>languages_lesswell</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_location_work</td><td>worklocation</td><td>workstation</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_login_work</td><td>worklogin</td><td>system_username</td><td></td><td></td><td>userid</td><td></td></tr>
|
||||
<tr><td>_name_family</td><td>familyname</td><td>family_name</td><td>FAMILY</td><td>N/FAMILY</td><td>sn</td><td>surname</td></tr>
|
||||
<tr><td>_name_given</td><td>givenname</td><td>given_name</td><td>GIVEN</td><td>N/GIVEN</td><td>givenName</td><td>givenname</td></tr>
|
||||
<tr><td>_name_middle</td><td>middlename</td><td>middle_name</td><td>MIDDLE</td><td>N/MIDDLE</td><td></td><td></td></tr>
|
||||
<tr><td>_name_patronymic</td><td>patronymicname</td><td>patronymic</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_name_prefix</td><td>prefixname</td><td>name_prefix</td><td>PREFIX</td><td>N/PREFIX</td><td></td><td>title</td></tr>
|
||||
<tr><td>_name_public</td><td>publicname</td><td>display_name</td><td>FN</td><td>FN</td><td>displayName</td><td>name</td></tr>
|
||||
<tr><td>_name_suffix</td><td>suffixname</td><td>name_suffix</td><td>SUFFIX</td><td>N/SUFFIX</td><td></td><td></td></tr>
|
||||
<tr><td>_nick_alternate</td><td>alternatenick</td><td>familiar_name</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_nick_profile</td><td>name</td><td>nickname</td><td>NICKNAME</td><td>NICKNAME</td><td>nickname</td><td>nick</td></tr>
|
||||
<tr><td>_nick_spaced</td><td>longname</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_page_biography</td><td>biographypage</td><td>bio</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_page_diary</td><td>diarypage</td><td>weblog</td><td></td><td></td><td></td><td>weblog</td></tr>
|
||||
<tr><td>_page_links</td><td>linkspage</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_page_photo</td><td>photopage</td><td></td><td></td><td></td><td></td><td>img</td></tr>
|
||||
<tr><td>_page_private</td><td>privatepage</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_page_public</td><td>publicpage</td><td>homepage</td><td>URL</td><td>URL</td><td>labelledURI</td><td>homepage</td></tr>
|
||||
<tr><td>_page_publications</td><td>publicationspage</td><td>publications</td><td></td><td></td><td></td><td>publications</td></tr>
|
||||
<tr><td>_page_resume</td><td>resumepage</td><td>resume</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_page_start</td><td>startpage</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_page_status</td><td>statuspage</td><td>status_url</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_page_work</td><td>workpage</td><td>org_url</td><td></td><td></td><td></td><td>workplaceHomepage</td></tr>
|
||||
<tr><td>_password</td><td>password</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_person_assistant_work</td><td>workassistant</td><td>assistant</td><td></td><td></td><td>secretary</td><td></td></tr>
|
||||
<tr><td>_person_manager_work</td><td>workmanager</td><td>manager</td><td></td><td></td><td>manager</td><td></td></tr>
|
||||
<tr><td>_place_home</td><td>home</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_profession</td><td>profession</td><td>profession</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_role_work</td><td>workrole</td><td>org_role</td><td>ROLE</td><td>ROLE</td><td></td><td></td></tr>
|
||||
<tr><td>_select_filter_presence</td><td>presencefilter</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_title_work</td><td>worktitle</td><td>job_title</td><td>TITLE</td><td>TITLE</td><td>title</td><td>title</td></tr>
|
||||
<tr><td>_uniform_FOAF_private</td><td>privatefoaffile</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_uniform_FOAF_public</td><td>publicfoaffile</td><td>foaf_url</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_uniform_character</td><td>characterfile</td><td>avatar_url</td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_uniform_key_public</td><td>keyfile</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_uniform_photo</td><td>photofile</td><td>photo_url</td><td>PHOTO</td><td></td><td></td><td>depiction</td></tr>
|
||||
<tr><td>_uniform_photo_small</td><td>miniphotofile</td><td></td><td></td><td></td><td></td><td>thumbnail</td></tr>
|
||||
<tr><td>_uniform_style</td><td>stylefile</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
<tr><td>_unit_work</td><td>workunit</td><td>org_unit</td><td>ORGUNIT</td><td>ORG/ORGUNIT</td><td>ou</td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h3>This document was generated by <a href="http://www.psyced.org/dist/world/net/library/profiles.pl">profiles.pl</a> of <a href="http://www.psyced.org/">psyced</a>. See <a href="http://about.psyc.eu/Profile">http://about.psyc.eu/Profile</a> for explanations.</h3>
|
521
world/net/library/profiles.i
Normal file
521
world/net/library/profiles.i
Normal file
|
@ -0,0 +1,521 @@
|
|||
// profiles.i generated out of profiles.gen. do not edit.
|
||||
|
||||
volatile mapping psyc2jProf = ([
|
||||
"_INTERNAL_image_photo" : "photo_data",
|
||||
"_address_area" : "area",
|
||||
"_address_box_postal" : "postalbox",
|
||||
"_address_building" : "building",
|
||||
"_address_code_postal" : "postalcode",
|
||||
"_address_country" : "country",
|
||||
"_address_floor" : "floor",
|
||||
"_address_latitude" : "lat",
|
||||
"_address_locality" : "locality",
|
||||
"_address_longitude" : "lon",
|
||||
"_address_past" : "places_lived",
|
||||
"_address_region" : "region",
|
||||
"_address_room" : "room",
|
||||
"_address_street" : "street",
|
||||
"_affiliation" : "org_name",
|
||||
"_contact_telephone" : "landline",
|
||||
"_contact_telephone_fax" : "fax",
|
||||
"_contact_telephone_pager" : "pager",
|
||||
"_contact_telephone_voice_mobile" : "mobile",
|
||||
"_date_birth" : "birth",
|
||||
"_description_expertise" : "expertise",
|
||||
"_description_hobby" : "hobby",
|
||||
"_description_public" : "description",
|
||||
"_description_quotes" : "fav_quotes",
|
||||
"_favorite_athletes" : "fav_athletes",
|
||||
"_favorite_drinks" : "fav_drinks",
|
||||
"_favorite_foods" : "fav_foods",
|
||||
"_favorite_games" : "fav_games",
|
||||
"_favorite_literature" : "fav_authors",
|
||||
"_favorite_movies" : "fav_movies",
|
||||
"_favorite_music" : "fav_music",
|
||||
"_favorite_popstar" : "fav_stars",
|
||||
"_favorite_teams" : "fav_teams",
|
||||
"_favorite_television" : "fav_tv",
|
||||
"_gender" : "gender",
|
||||
"_identification" : "psyc_id",
|
||||
"_identification_scheme_AIM" : "aim_id",
|
||||
"_identification_scheme_ICQ" : "icq_id",
|
||||
"_identification_scheme_MSN" : "msn_id",
|
||||
"_identification_scheme_SIP" : "sip_address",
|
||||
"_identification_scheme_Skype" : "skype_address",
|
||||
"_identification_scheme_XMPP" : "jid",
|
||||
"_identification_scheme_Yahoo" : "yahoo_id",
|
||||
"_identification_scheme_mailto" : "email",
|
||||
"_identification_videophone" : "video_phone",
|
||||
"_image_character" : "avatar_data",
|
||||
"_language_alternate" : "languages_well",
|
||||
"_language_optional" : "languages_lesswell",
|
||||
"_location_work" : "workstation",
|
||||
"_login_work" : "system_username",
|
||||
"_name_family" : "family_name",
|
||||
"_name_given" : "given_name",
|
||||
"_name_middle" : "middle_name",
|
||||
"_name_patronymic" : "patronymic",
|
||||
"_name_prefix" : "name_prefix",
|
||||
"_name_public" : "display_name",
|
||||
"_name_suffix" : "name_suffix",
|
||||
"_nick_alternate" : "familiar_name",
|
||||
"_nick_profile" : "nickname",
|
||||
"_page_biography" : "bio",
|
||||
"_page_diary" : "weblog",
|
||||
"_page_public" : "homepage",
|
||||
"_page_publications" : "publications",
|
||||
"_page_resume" : "resume",
|
||||
"_page_status" : "status_url",
|
||||
"_page_work" : "org_url",
|
||||
"_person_assistant_work" : "assistant",
|
||||
"_person_manager_work" : "manager",
|
||||
"_profession" : "profession",
|
||||
"_role_work" : "org_role",
|
||||
"_title_work" : "job_title",
|
||||
"_uniform_FOAF_public" : "foaf_url",
|
||||
"_uniform_character" : "avatar_url",
|
||||
"_uniform_photo" : "photo_url",
|
||||
"_unit_work" : "org_unit",
|
||||
]);
|
||||
|
||||
volatile mapping psyc2jCard = ([
|
||||
"_INTERNAL_image_photo" : "<PHOTO><BINVAL>%s</BINVAL></PHOTO>",
|
||||
"_INTERNAL_type_image_photo" : "<PHOTO><TYPE>%s</TYPE></PHOTO>",
|
||||
"_address_box_postal" : "<ADR><POBOX>%s</POBOX></ADR>",
|
||||
"_address_building" : "<ADR><EXTADD>%s</EXTADD></ADR>",
|
||||
"_address_code_postal" : "<ADR><PCODE>%s</PCODE></ADR>",
|
||||
"_address_country" : "<ADR><CTRY>%s</CTRY></ADR>",
|
||||
"_address_latitude" : "<GEO><LAT>%s</LAT></GEO>",
|
||||
"_address_locality" : "<ADR><LOCALITY>%s</LOCALITY></ADR>",
|
||||
"_address_longitude" : "<GEO><LON>%s</LON></GEO>",
|
||||
"_address_region" : "<ADR><REGION>%s</REGION></ADR>",
|
||||
"_address_street" : "<ADR><STREET>%s</STREET></ADR>",
|
||||
"_address_zone_time" : "<TZ>%s</TZ>",
|
||||
"_affiliation" : "<ORG><ORGNAME>%s</ORGNAME></ORG>",
|
||||
"_date_birth" : "<BDAY>%s</BDAY>",
|
||||
"_description_public" : "<DESC>%s</DESC>",
|
||||
"_identification" : "<PSYCID>%s</PSYCID>",
|
||||
"_identification_scheme_XMPP" : "<JABBERID>%s</JABBERID>",
|
||||
"_identification_scheme_mailto" : "<EMAIL><USERID>%s</USERID></EMAIL>",
|
||||
"_name_family" : "<N><FAMILY>%s</FAMILY></N>",
|
||||
"_name_given" : "<N><GIVEN>%s</GIVEN></N>",
|
||||
"_name_middle" : "<N><MIDDLE>%s</MIDDLE></N>",
|
||||
"_name_prefix" : "<N><PREFIX>%s</PREFIX></N>",
|
||||
"_name_public" : "<FN>%s</FN>",
|
||||
"_name_suffix" : "<N><SUFFIX>%s</SUFFIX></N>",
|
||||
"_nick_profile" : "<NICKNAME>%s</NICKNAME>",
|
||||
"_page_public" : "<URL>%s</URL>",
|
||||
"_role_work" : "<ROLE>%s</ROLE>",
|
||||
"_title_work" : "<TITLE>%s</TITLE>",
|
||||
"_unit_work" : "<ORG><ORGUNIT>%s</ORGUNIT></ORG>",
|
||||
"_contact_telephone" : "<TEL><NUMBER>%s</NUMBER></TEL>",
|
||||
"_contact_telephone_fax" : "<TEL><FAX/><NUMBER>%s</NUMBER></TEL>",
|
||||
"_contact_telephone_pager" : "<TEL><PAGER/><NUMBER>%s</NUMBER></TEL>",
|
||||
"_contact_telephone_voice_home" : "<TEL><VOICE/><HOME/><NUMBER>%s</NUMBER></TEL>",
|
||||
"_contact_telephone_voice_mobile" : "<TEL><VOICE/><CELL/><NUMBER>%s</NUMBER></TEL>",
|
||||
"_contact_telephone_voice_work" : "<TEL><VOICE/><WORK/><NUMBER>%s</NUMBER></TEL>",
|
||||
]);
|
||||
|
||||
volatile mapping jCard2psyc = ([
|
||||
"PHOTO/BINVAL" : "_INTERNAL_image_photo",
|
||||
"PHOTO/TYPE" : "_INTERNAL_type_image_photo",
|
||||
"ADR/POBOX" : "_address_box_postal",
|
||||
"ADR/EXTADD" : "_address_building",
|
||||
"ADR/PCODE" : "_address_code_postal",
|
||||
"ADR/CTRY" : "_address_country",
|
||||
"GEO/LAT" : "_address_latitude",
|
||||
"ADR/LOCALITY" : "_address_locality",
|
||||
"GEO/LON" : "_address_longitude",
|
||||
"ADR/REGION" : "_address_region",
|
||||
"ADR/STREET" : "_address_street",
|
||||
"TZ" : "_address_zone_time",
|
||||
"ORG/ORGNAME" : "_affiliation",
|
||||
"TEL/NUMBER" : "_contact_telephone",
|
||||
"BDAY" : "_date_birth",
|
||||
"DESC" : "_description_public",
|
||||
"PSYCID" : "_identification",
|
||||
"JABBERID" : "_identification_scheme_XMPP",
|
||||
"EMAIL/USERID" : "_identification_scheme_mailto",
|
||||
"N/FAMILY" : "_name_family",
|
||||
"N/GIVEN" : "_name_given",
|
||||
"N/MIDDLE" : "_name_middle",
|
||||
"N/PREFIX" : "_name_prefix",
|
||||
"FN" : "_name_public",
|
||||
"N/SUFFIX" : "_name_suffix",
|
||||
"NICKNAME" : "_nick_profile",
|
||||
"URL" : "_page_public",
|
||||
"ROLE" : "_role_work",
|
||||
"TITLE" : "_title_work",
|
||||
"ORG/ORGUNIT" : "_unit_work",
|
||||
]);
|
||||
|
||||
volatile mapping psyc2set = ([
|
||||
"_action_ask" : "askaction",
|
||||
"_action_motto" : "mottoaction",
|
||||
"_action_speak" : "speakaction",
|
||||
"_address_area" : "area",
|
||||
"_address_box_postal" : "postalbox",
|
||||
"_address_building" : "building",
|
||||
"_address_code_postal" : "postalcode",
|
||||
"_address_country" : "country",
|
||||
"_address_floor" : "floor",
|
||||
"_address_latitude" : "latitude",
|
||||
"_address_locality" : "locality",
|
||||
"_address_longitude" : "longitude",
|
||||
"_address_past" : "past",
|
||||
"_address_region" : "region",
|
||||
"_address_room" : "room",
|
||||
"_address_street" : "street",
|
||||
"_address_zone_time" : "timezone",
|
||||
"_affiliation" : "affiliation",
|
||||
"_character_action" : "actioncharacter",
|
||||
"_character_command" : "commandcharacter",
|
||||
"_color" : "color",
|
||||
"_contact_telephone" : "phone",
|
||||
"_contact_telephone_fax" : "fax",
|
||||
"_contact_telephone_pager" : "pager",
|
||||
"_contact_telephone_voice_home" : "homephone",
|
||||
"_contact_telephone_voice_mobile" : "mobilephone",
|
||||
"_contact_telephone_voice_work" : "workphone",
|
||||
"_date_birth" : "birthday",
|
||||
"_date_name" : "nameday",
|
||||
"_date_wedding" : "weddingday",
|
||||
"_description_expertise" : "expertisetext",
|
||||
"_description_hobby" : "hobbytext",
|
||||
"_description_motto" : "mottotext",
|
||||
"_description_preferences" : "likestext",
|
||||
"_description_preferences_not" : "dislikestext",
|
||||
"_description_presence" : "presencetext",
|
||||
"_description_private" : "privatetext",
|
||||
"_description_public" : "publictext",
|
||||
"_description_quotes" : "quotestext",
|
||||
"_encoding_characters" : "charset",
|
||||
"_favorite_animal" : "animalfave",
|
||||
"_favorite_athletes" : "athletesfave",
|
||||
"_favorite_drinks" : "drinksfave",
|
||||
"_favorite_foods" : "foodsfave",
|
||||
"_favorite_games" : "gamesfave",
|
||||
"_favorite_literature" : "literaturefave",
|
||||
"_favorite_movies" : "moviesfave",
|
||||
"_favorite_music" : "musicfave",
|
||||
"_favorite_popstar" : "popstarfave",
|
||||
"_favorite_teams" : "teamsfave",
|
||||
"_favorite_television" : "televisionfave",
|
||||
"_flag_action_speak_visible" : "visiblespeakaction",
|
||||
"_flag_colors_ignore" : "ignorecolors",
|
||||
"_flag_echo" : "echo",
|
||||
"_flag_expose_friends" : "friendsexpose",
|
||||
"_flag_expose_groups" : "groupsexpose",
|
||||
"_flag_filter_strangers" : "filter",
|
||||
"_flag_greeting" : "greeting",
|
||||
"_flag_places_multiple" : "multipleplaces",
|
||||
"_flag_presence_ctcp" : "ctcppresence",
|
||||
"_flag_screen_clear" : "clearscreen",
|
||||
"_flag_stamp_time" : "timestamp",
|
||||
"_flag_uniform_verbatim" : "verbatimuniform",
|
||||
"_flag_visibility" : "visibility",
|
||||
"_gender" : "sex",
|
||||
"_identification" : "id",
|
||||
"_identification_other" : "otherid",
|
||||
"_identification_scheme_AIM" : "aimid",
|
||||
"_identification_scheme_ICQ" : "icqid",
|
||||
"_identification_scheme_MSN" : "msnid",
|
||||
"_identification_scheme_SIP" : "sipid",
|
||||
"_identification_scheme_Skype" : "skypeid",
|
||||
"_identification_scheme_XMPP" : "xmppid",
|
||||
"_identification_scheme_Yahoo" : "yahooid",
|
||||
"_identification_scheme_mailto" : "email",
|
||||
"_identification_videophone" : "videophoneid",
|
||||
"_image_character" : "characterimage",
|
||||
"_language" : "language",
|
||||
"_language_alternate" : "alternatelanguage",
|
||||
"_language_optional" : "optionallanguage",
|
||||
"_location_work" : "worklocation",
|
||||
"_login_work" : "worklogin",
|
||||
"_name_family" : "familyname",
|
||||
"_name_given" : "givenname",
|
||||
"_name_middle" : "middlename",
|
||||
"_name_patronymic" : "patronymicname",
|
||||
"_name_prefix" : "prefixname",
|
||||
"_name_public" : "publicname",
|
||||
"_name_suffix" : "suffixname",
|
||||
"_nick_alternate" : "alternatenick",
|
||||
"_nick_profile" : "name",
|
||||
"_nick_spaced" : "longname",
|
||||
"_page_biography" : "biographypage",
|
||||
"_page_diary" : "diarypage",
|
||||
"_page_links" : "linkspage",
|
||||
"_page_photo" : "photopage",
|
||||
"_page_private" : "privatepage",
|
||||
"_page_public" : "publicpage",
|
||||
"_page_publications" : "publicationspage",
|
||||
"_page_resume" : "resumepage",
|
||||
"_page_start" : "startpage",
|
||||
"_page_status" : "statuspage",
|
||||
"_page_work" : "workpage",
|
||||
"_password" : "password",
|
||||
"_person_assistant_work" : "workassistant",
|
||||
"_person_manager_work" : "workmanager",
|
||||
"_place_home" : "home",
|
||||
"_profession" : "profession",
|
||||
"_role_work" : "workrole",
|
||||
"_select_filter_presence" : "presencefilter",
|
||||
"_title_work" : "worktitle",
|
||||
"_uniform_FOAF_private" : "privatefoaffile",
|
||||
"_uniform_FOAF_public" : "publicfoaffile",
|
||||
"_uniform_character" : "characterfile",
|
||||
"_uniform_key_public" : "keyfile",
|
||||
"_uniform_photo" : "photofile",
|
||||
"_uniform_photo_small" : "miniphotofile",
|
||||
"_uniform_style" : "stylefile",
|
||||
"_unit_work" : "workunit",
|
||||
]);
|
||||
|
||||
volatile mapping set2psyc = ([
|
||||
"askaction" : "_action_ask",
|
||||
"mottoaction" : "_action_motto",
|
||||
"speakaction" : "_action_speak",
|
||||
"area" : "_address_area",
|
||||
"postalbox" : "_address_box_postal",
|
||||
"building" : "_address_building",
|
||||
"postalcode" : "_address_code_postal",
|
||||
"country" : "_address_country",
|
||||
"floor" : "_address_floor",
|
||||
"latitude" : "_address_latitude",
|
||||
"locality" : "_address_locality",
|
||||
"longitude" : "_address_longitude",
|
||||
"past" : "_address_past",
|
||||
"region" : "_address_region",
|
||||
"room" : "_address_room",
|
||||
"street" : "_address_street",
|
||||
"timezone" : "_address_zone_time",
|
||||
"affiliation" : "_affiliation",
|
||||
"actioncharacter" : "_character_action",
|
||||
"commandcharacter" : "_character_command",
|
||||
"color" : "_color",
|
||||
"phone" : "_contact_telephone",
|
||||
"fax" : "_contact_telephone_fax",
|
||||
"pager" : "_contact_telephone_pager",
|
||||
"homephone" : "_contact_telephone_voice_home",
|
||||
"mobilephone" : "_contact_telephone_voice_mobile",
|
||||
"workphone" : "_contact_telephone_voice_work",
|
||||
"birthday" : "_date_birth",
|
||||
"nameday" : "_date_name",
|
||||
"weddingday" : "_date_wedding",
|
||||
"expertisetext" : "_description_expertise",
|
||||
"hobbytext" : "_description_hobby",
|
||||
"mottotext" : "_description_motto",
|
||||
"likestext" : "_description_preferences",
|
||||
"dislikestext" : "_description_preferences_not",
|
||||
"presencetext" : "_description_presence",
|
||||
"privatetext" : "_description_private",
|
||||
"publictext" : "_description_public",
|
||||
"quotestext" : "_description_quotes",
|
||||
"charset" : "_encoding_characters",
|
||||
"animalfave" : "_favorite_animal",
|
||||
"athletesfave" : "_favorite_athletes",
|
||||
"drinksfave" : "_favorite_drinks",
|
||||
"foodsfave" : "_favorite_foods",
|
||||
"gamesfave" : "_favorite_games",
|
||||
"literaturefave" : "_favorite_literature",
|
||||
"moviesfave" : "_favorite_movies",
|
||||
"musicfave" : "_favorite_music",
|
||||
"popstarfave" : "_favorite_popstar",
|
||||
"teamsfave" : "_favorite_teams",
|
||||
"televisionfave" : "_favorite_television",
|
||||
"visiblespeakaction" : "_flag_action_speak_visible",
|
||||
"ignorecolors" : "_flag_colors_ignore",
|
||||
"echo" : "_flag_echo",
|
||||
"friendsexpose" : "_flag_expose_friends",
|
||||
"groupsexpose" : "_flag_expose_groups",
|
||||
"filter" : "_flag_filter_strangers",
|
||||
"greeting" : "_flag_greeting",
|
||||
"multipleplaces" : "_flag_places_multiple",
|
||||
"ctcppresence" : "_flag_presence_ctcp",
|
||||
"clearscreen" : "_flag_screen_clear",
|
||||
"timestamp" : "_flag_stamp_time",
|
||||
"verbatimuniform" : "_flag_uniform_verbatim",
|
||||
"visibility" : "_flag_visibility",
|
||||
"sex" : "_gender",
|
||||
"id" : "_identification",
|
||||
"otherid" : "_identification_other",
|
||||
"aimid" : "_identification_scheme_AIM",
|
||||
"icqid" : "_identification_scheme_ICQ",
|
||||
"msnid" : "_identification_scheme_MSN",
|
||||
"sipid" : "_identification_scheme_SIP",
|
||||
"skypeid" : "_identification_scheme_Skype",
|
||||
"xmppid" : "_identification_scheme_XMPP",
|
||||
"yahooid" : "_identification_scheme_Yahoo",
|
||||
"email" : "_identification_scheme_mailto",
|
||||
"videophoneid" : "_identification_videophone",
|
||||
"characterimage" : "_image_character",
|
||||
"language" : "_language",
|
||||
"alternatelanguage" : "_language_alternate",
|
||||
"optionallanguage" : "_language_optional",
|
||||
"worklocation" : "_location_work",
|
||||
"worklogin" : "_login_work",
|
||||
"familyname" : "_name_family",
|
||||
"givenname" : "_name_given",
|
||||
"middlename" : "_name_middle",
|
||||
"patronymicname" : "_name_patronymic",
|
||||
"prefixname" : "_name_prefix",
|
||||
"publicname" : "_name_public",
|
||||
"suffixname" : "_name_suffix",
|
||||
"alternatenick" : "_nick_alternate",
|
||||
"name" : "_nick_profile",
|
||||
"longname" : "_nick_spaced",
|
||||
"biographypage" : "_page_biography",
|
||||
"diarypage" : "_page_diary",
|
||||
"linkspage" : "_page_links",
|
||||
"photopage" : "_page_photo",
|
||||
"privatepage" : "_page_private",
|
||||
"publicpage" : "_page_public",
|
||||
"publicationspage" : "_page_publications",
|
||||
"resumepage" : "_page_resume",
|
||||
"startpage" : "_page_start",
|
||||
"statuspage" : "_page_status",
|
||||
"workpage" : "_page_work",
|
||||
"password" : "_password",
|
||||
"workassistant" : "_person_assistant_work",
|
||||
"workmanager" : "_person_manager_work",
|
||||
"home" : "_place_home",
|
||||
"profession" : "_profession",
|
||||
"workrole" : "_role_work",
|
||||
"presencefilter" : "_select_filter_presence",
|
||||
"worktitle" : "_title_work",
|
||||
"privatefoaffile" : "_uniform_FOAF_private",
|
||||
"publicfoaffile" : "_uniform_FOAF_public",
|
||||
"characterfile" : "_uniform_character",
|
||||
"keyfile" : "_uniform_key_public",
|
||||
"photofile" : "_uniform_photo",
|
||||
"miniphotofile" : "_uniform_photo_small",
|
||||
"stylefile" : "_uniform_style",
|
||||
"workunit" : "_unit_work",
|
||||
]);
|
||||
|
||||
volatile mapping psyc2ldap = ([
|
||||
"_INTERNAL_image_photo" : "jpegPhoto",
|
||||
"_address_box_postal" : "postOfficeBox",
|
||||
"_address_code_postal" : "postalCode",
|
||||
"_address_country" : "c",
|
||||
"_address_locality" : "l",
|
||||
"_address_region" : "st",
|
||||
"_address_room" : "roomNumber",
|
||||
"_address_street" : "street",
|
||||
"_affiliation" : "o",
|
||||
"_contact_telephone" : "telephoneNumber",
|
||||
"_contact_telephone_fax" : "facsimileTelephoneNumber",
|
||||
"_contact_telephone_pager" : "pager",
|
||||
"_contact_telephone_voice_mobile" : "mobile",
|
||||
"_description_public" : "description",
|
||||
"_identification_scheme_mailto" : "mail",
|
||||
"_language_alternate" : "preferredLanguage",
|
||||
"_login_work" : "userid",
|
||||
"_name_family" : "sn",
|
||||
"_name_given" : "givenName",
|
||||
"_name_public" : "displayName",
|
||||
"_nick_profile" : "nickname",
|
||||
"_page_public" : "labelledURI",
|
||||
"_person_assistant_work" : "secretary",
|
||||
"_person_manager_work" : "manager",
|
||||
"_title_work" : "title",
|
||||
"_unit_work" : "ou",
|
||||
]);
|
||||
|
||||
volatile mapping ldap2psyc = ([
|
||||
"jpegPhoto" : "_INTERNAL_image_photo",
|
||||
"postOfficeBox" : "_address_box_postal",
|
||||
"postalCode" : "_address_code_postal",
|
||||
"c" : "_address_country",
|
||||
"l" : "_address_locality",
|
||||
"st" : "_address_region",
|
||||
"roomNumber" : "_address_room",
|
||||
"street" : "_address_street",
|
||||
"o" : "_affiliation",
|
||||
"telephoneNumber" : "_contact_telephone",
|
||||
"facsimileTelephoneNumber" : "_contact_telephone_fax",
|
||||
"pager" : "_contact_telephone_pager",
|
||||
"mobile" : "_contact_telephone_voice_mobile",
|
||||
"description" : "_description_public",
|
||||
"mail" : "_identification_scheme_mailto",
|
||||
"preferredLanguage" : "_language_alternate",
|
||||
"userid" : "_login_work",
|
||||
"sn" : "_name_family",
|
||||
"givenName" : "_name_given",
|
||||
"displayName" : "_name_public",
|
||||
"nickname" : "_nick_profile",
|
||||
"labelledURI" : "_page_public",
|
||||
"secretary" : "_person_assistant_work",
|
||||
"manager" : "_person_manager_work",
|
||||
"title" : "_title_work",
|
||||
"ou" : "_unit_work",
|
||||
]);
|
||||
|
||||
volatile mapping psyc2vCard = ([
|
||||
"_INTERNAL_image_photo" : "PHOTO",
|
||||
"_address_box_postal" : "POBOX",
|
||||
"_address_building" : "EXTADD",
|
||||
"_address_code_postal" : "PCODE",
|
||||
"_address_country" : "COUNTRY",
|
||||
"_address_latitude" : "LAT",
|
||||
"_address_locality" : "LOCALITY",
|
||||
"_address_longitude" : "LON",
|
||||
"_address_region" : "REGION",
|
||||
"_address_street" : "STREET",
|
||||
"_address_zone_time" : "TZ",
|
||||
"_affiliation" : "ORGNAME",
|
||||
"_contact_telephone_fax" : "TEL;FAX",
|
||||
"_contact_telephone_pager" : "TEL;PAGER",
|
||||
"_contact_telephone_voice_home" : "TEL;VOICE;HOME",
|
||||
"_contact_telephone_voice_mobile" : "TEL;CELL",
|
||||
"_contact_telephone_voice_work" : "TEL;VOICE;WORK",
|
||||
"_date_birth" : "BDAY",
|
||||
"_identification_scheme_mailto" : "EMAIL",
|
||||
"_name_family" : "FAMILY",
|
||||
"_name_given" : "GIVEN",
|
||||
"_name_middle" : "MIDDLE",
|
||||
"_name_prefix" : "PREFIX",
|
||||
"_name_public" : "FN",
|
||||
"_name_suffix" : "SUFFIX",
|
||||
"_nick_profile" : "NICKNAME",
|
||||
"_page_public" : "URL",
|
||||
"_role_work" : "ROLE",
|
||||
"_title_work" : "TITLE",
|
||||
"_uniform_photo" : "PHOTO",
|
||||
"_unit_work" : "ORGUNIT",
|
||||
]);
|
||||
|
||||
volatile mapping vCard2psyc = ([
|
||||
"PHOTO" : "_INTERNAL_image_photo",
|
||||
"POBOX" : "_address_box_postal",
|
||||
"EXTADD" : "_address_building",
|
||||
"PCODE" : "_address_code_postal",
|
||||
"COUNTRY" : "_address_country",
|
||||
"LAT" : "_address_latitude",
|
||||
"LOCALITY" : "_address_locality",
|
||||
"LON" : "_address_longitude",
|
||||
"REGION" : "_address_region",
|
||||
"STREET" : "_address_street",
|
||||
"TZ" : "_address_zone_time",
|
||||
"ORGNAME" : "_affiliation",
|
||||
"TEL;FAX" : "_contact_telephone_fax",
|
||||
"TEL;PAGER" : "_contact_telephone_pager",
|
||||
"TEL;VOICE;HOME" : "_contact_telephone_voice_home",
|
||||
"TEL;CELL" : "_contact_telephone_voice_mobile",
|
||||
"TEL;VOICE;WORK" : "_contact_telephone_voice_work",
|
||||
"BDAY" : "_date_birth",
|
||||
"EMAIL" : "_identification_scheme_mailto",
|
||||
"FAMILY" : "_name_family",
|
||||
"GIVEN" : "_name_given",
|
||||
"MIDDLE" : "_name_middle",
|
||||
"PREFIX" : "_name_prefix",
|
||||
"FN" : "_name_public",
|
||||
"SUFFIX" : "_name_suffix",
|
||||
"NICKNAME" : "_nick_profile",
|
||||
"URL" : "_page_public",
|
||||
"ROLE" : "_role_work",
|
||||
"TITLE" : "_title_work",
|
||||
"PHOTO" : "_uniform_photo",
|
||||
"ORGUNIT" : "_unit_work",
|
||||
]);
|
||||
|
694
world/net/library/profiles.pl
Normal file
694
world/net/library/profiles.pl
Normal file
|
@ -0,0 +1,694 @@
|
|||
#!/usr/bin/perl
|
||||
# $Id: profiles.pl,v 1.54 2008/04/11 10:37:25 lynx Exp $
|
||||
#
|
||||
# generator of mappings between several profile file formats -lynX 2005
|
||||
# part of the psyced project. see documentation for copyrights and licenses.
|
||||
#
|
||||
# see below __DATA__ for the actual mapping data
|
||||
# this is just the perl program to make use of the data
|
||||
|
||||
while (<main::DATA>) {
|
||||
next if /^\s*$/;
|
||||
next if /^#/;
|
||||
if ( /^PSYC\t(\w+)$/ ) {
|
||||
$_ = $psyc = $1;
|
||||
$psyc{$psyc} = 1;
|
||||
next if /^_INTERNAL/;
|
||||
s/_(address|contact|voice|scheme|source|flag|person|select)//g;
|
||||
s/_date/_day/g;
|
||||
s/_description/_text/g;
|
||||
s/_favorite/_fave/g;
|
||||
s/_identification/_ID/g;
|
||||
s/_uniform/_file/g;
|
||||
s/_telephone/_phone/g;
|
||||
$set{$psyc} = lc( join('', reverse split('_', $_)) );
|
||||
next;
|
||||
}
|
||||
if ( /^(\S+)\t(\S+)$/ ) {
|
||||
${$1}{$psyc} = $2;
|
||||
next;
|
||||
}
|
||||
warn "couldn't parse $_";
|
||||
}
|
||||
|
||||
# generate some documentation for your enjoyment
|
||||
open O, ">profiles.html" or die $!;
|
||||
print O <<X;
|
||||
<style> td { background-color: #ccc } </style>
|
||||
<title>PROFILING FIELD NAMES COMPARISON CHART</title>
|
||||
<body bgcolor="#ff9900" text=black link=red vlink=black>
|
||||
<h1>PROFILING FIELD NAMES COMPARISON CHART</h1>
|
||||
<table cellspacing=2>
|
||||
X
|
||||
print O "<tr align=left><th>PSYC</th><th>/set</th><th>jProf</th><th>vCard</th><th>jCard</th><th>LDAP</th><th>FOAF</th></tr>\n";
|
||||
foreach $k ( sort keys %psyc ) {
|
||||
print O "<tr><td>$k</td><td>$set{$k}</td><td>$jProf{$k}</td><td>$vCard{$k}</td><td>$jCard{$k}</td><td>$LDAP{$k}</td><td>$FOAF{$k}</td></tr>\n";
|
||||
}
|
||||
print O <<X;
|
||||
</table>
|
||||
|
||||
<h3>This document was generated by <a href="http://www.psyced.org/dist/world/net/library/profiles.pl">profiles.pl</a> of <a href="http://www.psyced.org/">psyced</a>. See <a href="http://about.psyc.eu/Profile">http://about.psyc.eu/Profile</a> for explanations.</h3>
|
||||
X
|
||||
close O;
|
||||
|
||||
# and now let's get to the real work
|
||||
open O, ">profiles.i" or die $!;
|
||||
print O "// profiles.i generated out of profiles.gen. do not edit.\n\n";
|
||||
print O "volatile mapping psyc2jProf = ([\n";
|
||||
foreach $k ( sort keys %jProf ) {
|
||||
printf O " %37s : \"%s\",\n", "\"$k\"", $jProf{$k};
|
||||
}
|
||||
print O "]);\n\nvolatile mapping psyc2jCard = ([\n";
|
||||
foreach $k ( sort keys %jCard ) {
|
||||
unless ($OjCard{$k}) { $j = $jCard{$k};
|
||||
$j = $j =~ m#^(\w+)/(\w+)$# ? "<$1><$2>%s</$2></$1>" : "<$j>%s</$j>";
|
||||
printf O " %25s : \"%s\",\n", "\"$k\"", $j;
|
||||
}
|
||||
}
|
||||
foreach $k ( sort keys %OjCard ) {
|
||||
printf O " %25s : \"%s\",\n", "\"$k\"", $OjCard{$k};
|
||||
}
|
||||
print O "]);\n\nvolatile mapping jCard2psyc = ([\n";
|
||||
foreach $k ( sort keys %jCard ) {
|
||||
printf O " %15s : \"%s\",\n", "\"$jCard{$k}\"", $k;
|
||||
}
|
||||
print O "]);\n\nvolatile mapping psyc2set = ([\n";
|
||||
foreach $k ( sort keys %set ) {
|
||||
printf O " %37s : \"%s\",\n", "\"$k\"", $set{$k};
|
||||
}
|
||||
print O "]);\n\nvolatile mapping set2psyc = ([\n";
|
||||
foreach $k ( sort keys %set ) {
|
||||
printf O " %20s : \"%s\",\n", "\"$set{$k}\"", $k;
|
||||
}
|
||||
print O "]);\n\nvolatile mapping psyc2ldap = ([\n";
|
||||
foreach $k ( sort keys %LDAP ) {
|
||||
printf O " %37s : \"%s\",\n", "\"$k\"", $LDAP{$k};
|
||||
}
|
||||
print O "]);\n\nvolatile mapping ldap2psyc = ([\n";
|
||||
foreach $k ( sort keys %LDAP ) {
|
||||
printf O " %27s : \"%s\",\n", "\"$LDAP{$k}\"", $k;
|
||||
}
|
||||
print O "]);\n\nvolatile mapping psyc2vCard = ([\n";
|
||||
foreach $k ( sort keys %vCard ) {
|
||||
printf O " %37s : \"%s\",\n", "\"$k\"", $vCard{$k};
|
||||
}
|
||||
print O "]);\n\nvolatile mapping vCard2psyc = ([\n";
|
||||
foreach $k ( sort keys %vCard ) {
|
||||
printf O " %20s : \"%s\",\n", "\"$vCard{$k}\"", $k;
|
||||
}
|
||||
print O "]);\n\n";
|
||||
close O;
|
||||
|
||||
my $skip = <<ENDSKIP;
|
||||
|
||||
# let's generate a file that will make PsycZilla overkill .. then again, no
|
||||
open O, ">profiles.xul" or die $!;
|
||||
print O <<X if 0;
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<prefwindow id="psycProfile"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
type="profwindow"
|
||||
title="PSYC profile" onload="prefWinLoad()"
|
||||
maxwidth='550' windowtype='preferences'>
|
||||
<groupbox>
|
||||
X
|
||||
foreach ( sort keys %psyc ) {
|
||||
next if /^_INTERNAL/ or /^_degree/;
|
||||
# http://developer.mozilla.org/en/docs/XUL:textbox
|
||||
print O <<X;
|
||||
<hbox><label value='$set{$_}'/><textbox id='$_' preference='profile_$set{$_}'/></hbox>
|
||||
X
|
||||
}
|
||||
print O <<X if 0;
|
||||
</groupbox>
|
||||
</prefwindow>
|
||||
X
|
||||
close O;
|
||||
|
||||
ENDSKIP
|
||||
|
||||
# this file was generated from JEP-0154, then edited.. a lot.
|
||||
#
|
||||
# apparently psyc is the only format which keeps hierarchy in the variable
|
||||
# names using families. most newer formats use complex xml paths or even
|
||||
# unusable xml paths.
|
||||
#
|
||||
# there are huge amounts of profile options in here, but please - don't
|
||||
# confront users with endless questionnaires and don't hand this information
|
||||
# out to people who make money out of it. the intention behind such elaborate
|
||||
# profiles is to empower the private trust network of friends to maximize
|
||||
# their use of psyc however they may seem fit, not 3rd parties or the general
|
||||
# public. do not fill in fields until they are actually useful for something.
|
||||
#
|
||||
#PSYC variable name
|
||||
#set user-friendly variable name for /set command
|
||||
#jProf JEP-0154 field var. JEP-0154 is the new profile data representation
|
||||
# for jabber. it is mostly unused everywhere.
|
||||
# http://www.jabber.org/jeps/jep-0154.html
|
||||
#vCard either RFC 2426 or JEP-0054, probably needs to be split into...
|
||||
#jCard JEP-0054 field names should be tagged jCard rather than vCard.
|
||||
# JEP-0054 is a not so brilliant adaption of vCard to jabber,
|
||||
# it is superceded but in use everywhere.
|
||||
# http://www.jabber.org/jeps/jep-0054.html
|
||||
#OjCard OUTGOING format strings for jCard
|
||||
# many cases just cannot be treated the same way as incoming JEP-0054
|
||||
#LDAP actually useful ISO standard. good to have it here for future use.
|
||||
#xNAL http://xml.coverpages.org/xnal.html by OASIS. we don't use it.
|
||||
#FOAF the profiles-without-privacy format. unused, but no need to delete it.
|
||||
|
||||
__DATA__
|
||||
|
||||
PSYC _name_public
|
||||
jProf display_name
|
||||
vCard FN
|
||||
jCard FN
|
||||
LDAP displayName
|
||||
FOAF name
|
||||
|
||||
PSYC _name_family
|
||||
jProf family_name
|
||||
vCard FAMILY
|
||||
jCard N/FAMILY
|
||||
LDAP sn
|
||||
xNAL LastName
|
||||
#FOAF family_name
|
||||
FOAF surname
|
||||
|
||||
PSYC _nick_alternate
|
||||
jProf familiar_name
|
||||
|
||||
PSYC _name_given
|
||||
jProf given_name
|
||||
vCard GIVEN
|
||||
jCard N/GIVEN
|
||||
LDAP givenName
|
||||
xNAL FirstName
|
||||
#FOAF first_name
|
||||
FOAF givenname
|
||||
|
||||
PSYC _name_middle
|
||||
jProf middle_name
|
||||
vCard MIDDLE
|
||||
jCard N/MIDDLE
|
||||
xNAL MiddleName
|
||||
|
||||
PSYC _name_prefix
|
||||
jProf name_prefix
|
||||
vCard PREFIX
|
||||
jCard N/PREFIX
|
||||
xNAL Title
|
||||
FOAF title
|
||||
|
||||
PSYC _name_suffix
|
||||
jProf name_suffix
|
||||
vCard SUFFIX
|
||||
jCard N/SUFFIX
|
||||
xNAL GeneralSuffix
|
||||
|
||||
PSYC _nick_profile
|
||||
set name
|
||||
jProf nickname
|
||||
LDAP nickname
|
||||
vCard NICKNAME
|
||||
jCard NICKNAME
|
||||
xNAL Alias
|
||||
FOAF nick
|
||||
|
||||
PSYC _name_patronymic
|
||||
jProf patronymic
|
||||
|
||||
PSYC _address_country
|
||||
jProf country
|
||||
vCard COUNTRY
|
||||
jCard ADR/CTRY
|
||||
LDAP c
|
||||
xNAL CountryName
|
||||
JEP0112 country
|
||||
|
||||
PSYC _address_region
|
||||
jProf region
|
||||
vCard REGION
|
||||
jCard ADR/REGION
|
||||
LDAP st
|
||||
xNAL AdministrativeAreaName
|
||||
JEP0112 region
|
||||
|
||||
# optionally postfixed by _home _work etc.
|
||||
PSYC _address_locality
|
||||
jProf locality
|
||||
# optionally supplemented with the "HOME" or "WORK" type
|
||||
vCard LOCALITY
|
||||
jCard ADR/LOCALITY
|
||||
LDAP l
|
||||
xNAL LocalityName
|
||||
JEP0112 locality
|
||||
|
||||
PSYC _address_area
|
||||
jProf area
|
||||
xNAL DependentLocalityName
|
||||
JEP0112 area
|
||||
|
||||
PSYC _address_street
|
||||
jProf street
|
||||
vCard STREET
|
||||
jCard ADR/STREET
|
||||
LDAP street
|
||||
xNAL ThoroughfareNumber+ThoroughfareName
|
||||
JEP0112 street
|
||||
|
||||
PSYC _address_building
|
||||
jProf building
|
||||
vCard EXTADD
|
||||
jCard ADR/EXTADD
|
||||
xNAL BuildingName
|
||||
JEP0112 building
|
||||
|
||||
PSYC _address_floor
|
||||
jProf floor
|
||||
xNAL SubPremiseNumber
|
||||
JEP0112 floor
|
||||
|
||||
PSYC _address_room
|
||||
jProf room
|
||||
LDAP roomNumber
|
||||
xNAL SubPremiseNumber
|
||||
JEP0112 room
|
||||
|
||||
PSYC _address_box_postal
|
||||
jProf postalbox
|
||||
vCard POBOX
|
||||
jCard ADR/POBOX
|
||||
LDAP postOfficeBox
|
||||
|
||||
PSYC _address_code_postal
|
||||
jProf postalcode
|
||||
vCard PCODE
|
||||
jCard ADR/PCODE
|
||||
LDAP postalCode
|
||||
xNAL PostalCodeNumber
|
||||
JEP0112 postalcode
|
||||
|
||||
PSYC _address_latitude
|
||||
jProf lat
|
||||
vCard LAT
|
||||
jCard GEO/LAT
|
||||
JEP0080 lat
|
||||
|
||||
PSYC _address_longitude
|
||||
jProf lon
|
||||
vCard LON
|
||||
jCard GEO/LON
|
||||
JEP0080 lon
|
||||
|
||||
PSYC _address_zone_time
|
||||
vCard TZ
|
||||
jCard TZ
|
||||
|
||||
PSYC _contact_telephone
|
||||
jProf landline
|
||||
# both vCard and jCard have no hierarchy for telephone number types
|
||||
# which makes them very cumbersome to use.
|
||||
# so we just ignore it and merge all phone numbers into one _telephone field.
|
||||
jCard TEL/NUMBER
|
||||
OjCard <TEL><NUMBER>%s</NUMBER></TEL>
|
||||
LDAP telephoneNumber
|
||||
FOAF phone
|
||||
|
||||
PSYC _contact_telephone_voice_home
|
||||
vCard TEL;VOICE;HOME
|
||||
OjCard <TEL><VOICE/><HOME/><NUMBER>%s</NUMBER></TEL>
|
||||
|
||||
PSYC _contact_telephone_voice_work
|
||||
vCard TEL;VOICE;WORK
|
||||
OjCard <TEL><VOICE/><WORK/><NUMBER>%s</NUMBER></TEL>
|
||||
|
||||
PSYC _contact_telephone_voice_mobile
|
||||
jProf mobile
|
||||
vCard TEL;CELL
|
||||
OjCard <TEL><VOICE/><CELL/><NUMBER>%s</NUMBER></TEL>
|
||||
LDAP mobile
|
||||
FOAF phone
|
||||
|
||||
PSYC _contact_telephone_pager
|
||||
jProf pager
|
||||
set pager
|
||||
vCard TEL;PAGER
|
||||
OjCard <TEL><PAGER/><NUMBER>%s</NUMBER></TEL>
|
||||
LDAP pager
|
||||
|
||||
PSYC _contact_telephone_fax
|
||||
set fax
|
||||
jProf fax
|
||||
vCard TEL;FAX
|
||||
OjCard <TEL><FAX/><NUMBER>%s</NUMBER></TEL>
|
||||
LDAP facsimileTelephoneNumber
|
||||
|
||||
PSYC _identification_scheme_SIP
|
||||
jProf sip_address
|
||||
|
||||
PSYC _identification_scheme_Skype
|
||||
jProf skype_address
|
||||
|
||||
PSYC _identification_videophone
|
||||
jProf video_phone
|
||||
|
||||
PSYC _identification_scheme_AIM
|
||||
jProf aim_id
|
||||
FOAF aimChatID
|
||||
|
||||
PSYC _identification_scheme_mailto
|
||||
set email
|
||||
jProf email
|
||||
vCard EMAIL
|
||||
jCard EMAIL/USERID
|
||||
LDAP mail
|
||||
|
||||
PSYC _identification_scheme_ICQ
|
||||
jProf icq_id
|
||||
FOAF icqChatID
|
||||
|
||||
PSYC _identification
|
||||
jProf psyc_id
|
||||
jCard PSYCID
|
||||
FOAF psycID
|
||||
|
||||
PSYC _identification_other
|
||||
|
||||
PSYC _identification_scheme_XMPP
|
||||
jProf jid
|
||||
jCard JABBERID
|
||||
FOAF jabberID
|
||||
|
||||
PSYC _identification_scheme_MSN
|
||||
jProf msn_id
|
||||
FOAF msnChatID
|
||||
|
||||
PSYC _identification_scheme_Yahoo
|
||||
jProf yahoo_id
|
||||
FOAF yahooChatID
|
||||
|
||||
PSYC _uniform_character
|
||||
jProf avatar_url
|
||||
|
||||
PSYC _page_biography
|
||||
jProf bio
|
||||
|
||||
PSYC _uniform_FOAF_public
|
||||
jProf foaf_url
|
||||
|
||||
# why i define this? because with profiles.gen we could easily
|
||||
# generate a _real_ foaf file, and with psycish friendsnetting
|
||||
# or at least psyc auth we can make it useful to those we want
|
||||
# to have it. but probably whatever foaf software exists, it is
|
||||
# probably web-based and doesn't have the faintest clue about
|
||||
# privacy.. so better do this all in psyc anyway.
|
||||
PSYC _uniform_FOAF_private
|
||||
|
||||
PSYC _uniform_photo_small
|
||||
set miniphotofile
|
||||
FOAF thumbnail
|
||||
|
||||
PSYC _uniform_photo
|
||||
jProf photo_url
|
||||
vCard PHOTO
|
||||
FOAF depiction
|
||||
|
||||
PSYC _page_photo
|
||||
FOAF img
|
||||
|
||||
# _page_public is a substring of _page_publications
|
||||
# could become a problem for simple inheritance detection
|
||||
PSYC _page_public
|
||||
vCard URL
|
||||
jCard URL
|
||||
jProf homepage
|
||||
LDAP labelledURI
|
||||
FOAF homepage
|
||||
|
||||
PSYC _page_publications
|
||||
jProf publications
|
||||
FOAF publications
|
||||
|
||||
PSYC _page_resume
|
||||
jProf resume
|
||||
|
||||
PSYC _page_status
|
||||
jProf status_url
|
||||
|
||||
PSYC _page_work
|
||||
jProf org_url
|
||||
FOAF workplaceHomepage
|
||||
|
||||
PSYC _page_diary
|
||||
jProf weblog
|
||||
FOAF weblog
|
||||
|
||||
# bookmarks, favorites, del.icio.us stuff or just your friends homepages
|
||||
PSYC _page_links
|
||||
|
||||
PSYC _person_assistant_work
|
||||
jProf assistant
|
||||
LDAP secretary
|
||||
|
||||
PSYC _title_work
|
||||
jProf job_title
|
||||
vCard TITLE
|
||||
jCard TITLE
|
||||
LDAP title
|
||||
FOAF title
|
||||
|
||||
PSYC _person_manager_work
|
||||
jProf manager
|
||||
LDAP manager
|
||||
|
||||
# was: _organisation_work. _affiliation is more generic but since the
|
||||
# other profile things only have the stricter field, we merge them here
|
||||
PSYC _affiliation
|
||||
jProf org_name
|
||||
vCard ORGNAME
|
||||
jCard ORG/ORGNAME
|
||||
LDAP o
|
||||
|
||||
PSYC _role_work
|
||||
jProf org_role
|
||||
vCard ROLE
|
||||
jCard ROLE
|
||||
|
||||
PSYC _unit_work
|
||||
jProf org_unit
|
||||
vCard ORGUNIT
|
||||
jCard ORG/ORGUNIT
|
||||
LDAP ou
|
||||
|
||||
PSYC _login_work
|
||||
jProf system_username
|
||||
LDAP uid
|
||||
LDAP userid
|
||||
|
||||
PSYC _location_work
|
||||
jProf workstation
|
||||
|
||||
PSYC _date_birth
|
||||
jProf birth
|
||||
vCard BDAY
|
||||
jCard BDAY
|
||||
|
||||
## "onomastico" - catholics like to party on the saint's day by the same name
|
||||
## maybe something similar exists in other cultures too?
|
||||
PSYC _date_name
|
||||
|
||||
## hahahaha
|
||||
PSYC _date_wedding
|
||||
|
||||
## only we have a distinction of public and private text.. sigh
|
||||
## not talking of mottos and slogans ;)
|
||||
PSYC _description_public
|
||||
jProf description
|
||||
jCard DESC
|
||||
LDAP description
|
||||
|
||||
#jProf eye_color
|
||||
|
||||
PSYC _gender
|
||||
set sex
|
||||
jProf gender
|
||||
FOAF gender
|
||||
|
||||
#jProf hair_color
|
||||
|
||||
#jProf height
|
||||
|
||||
#jProf weight
|
||||
|
||||
PSYC _description_expertise
|
||||
jProf expertise
|
||||
|
||||
PSYC _image_character
|
||||
jProf avatar_data
|
||||
|
||||
#jProf dietary_preferences
|
||||
|
||||
PSYC _description_hobby
|
||||
jProf hobby
|
||||
|
||||
#jProf interest
|
||||
|
||||
# the current language setting - needs to be iso-conformant etc.
|
||||
PSYC _language
|
||||
set language
|
||||
|
||||
PSYC _language_optional
|
||||
jProf languages_lesswell
|
||||
|
||||
PSYC _language_alternate
|
||||
jProf languages_well
|
||||
LDAP preferredLanguage
|
||||
|
||||
#jProf marital_status
|
||||
|
||||
#jProf mbti
|
||||
#FOAF myersBriggs
|
||||
|
||||
# we don't want to send base64 encoded photos in psyc
|
||||
# but we can handle them internally
|
||||
PSYC _INTERNAL_image_photo
|
||||
jProf photo_data
|
||||
vCard PHOTO
|
||||
jCard PHOTO/BINVAL
|
||||
LDAP jpegPhoto
|
||||
|
||||
PSYC _INTERNAL_type_image_photo
|
||||
jCard PHOTO/TYPE
|
||||
|
||||
PSYC _profession
|
||||
jProf profession
|
||||
|
||||
#jProf religion
|
||||
|
||||
#jProf sexual_orientation
|
||||
|
||||
#jProf smoker
|
||||
|
||||
#jProf wishlist
|
||||
|
||||
#jProf zodiac_chinese
|
||||
|
||||
#jProf zodiac_western
|
||||
|
||||
# for children
|
||||
PSYC _favorite_animal
|
||||
|
||||
PSYC _favorite_literature
|
||||
jProf fav_authors
|
||||
|
||||
PSYC _favorite_athletes
|
||||
jProf fav_athletes
|
||||
|
||||
#jProf fav_charities
|
||||
|
||||
PSYC _favorite_drinks
|
||||
jProf fav_drinks
|
||||
|
||||
PSYC _favorite_foods
|
||||
jProf fav_foods
|
||||
|
||||
PSYC _favorite_games
|
||||
jProf fav_games
|
||||
|
||||
PSYC _favorite_movies
|
||||
jProf fav_movies
|
||||
|
||||
PSYC _favorite_music
|
||||
jProf fav_music
|
||||
|
||||
# for teenagers
|
||||
PSYC _favorite_popstar
|
||||
jProf fav_stars
|
||||
|
||||
PSYC _description_quotes
|
||||
jProf fav_quotes
|
||||
|
||||
PSYC _favorite_teams
|
||||
jProf fav_teams
|
||||
|
||||
PSYC _favorite_television
|
||||
jProf fav_tv
|
||||
|
||||
PSYC _address_past
|
||||
jProf places_lived
|
||||
|
||||
#jProf schools
|
||||
|
||||
# PSYC things that other formats do not propose
|
||||
# listed here to get the set2psyc and psyc2set mappings of it
|
||||
PSYC _place_home
|
||||
set home
|
||||
|
||||
PSYC _flag_filter_strangers
|
||||
set filter
|
||||
|
||||
PSYC _uniform_key_public
|
||||
set keyfile
|
||||
|
||||
# stylesheet for showing psyc profile
|
||||
PSYC _uniform_style
|
||||
set stylefile
|
||||
|
||||
# superceded, but we keep it for those who want to use the code by psyced tuning
|
||||
PSYC _flag_uniform_verbatim
|
||||
set verbatimuniform
|
||||
|
||||
PSYC _description_preferences
|
||||
set likestext
|
||||
|
||||
PSYC _description_preferences_not
|
||||
set dislikestext
|
||||
|
||||
# this one typically requires special care, here it is anyhow..
|
||||
PSYC _password
|
||||
|
||||
# just a version of _nick where spaces are allowed
|
||||
PSYC _nick_spaced
|
||||
set longname
|
||||
|
||||
PSYC _encoding_characters
|
||||
set charset
|
||||
|
||||
PSYC _action_ask
|
||||
PSYC _action_speak
|
||||
|
||||
# nice alternative name for motto: slogan
|
||||
PSYC _action_motto
|
||||
# hmm.. looks like jProf has no place for slogans and mottos
|
||||
|
||||
# not even if we introduce a motto variant which is not /me-like.
|
||||
PSYC _description_motto
|
||||
# this one gets used by the so-called IRCNAME since hardly anyone
|
||||
# really puts his real name in there.
|
||||
|
||||
PSYC _character_action
|
||||
PSYC _character_command
|
||||
PSYC _color
|
||||
# these aren't /set'tings as of now - too volatile
|
||||
#PSYC _degree_availability
|
||||
#PSYC _degree_mood
|
||||
PSYC _description_private
|
||||
PSYC _description_presence
|
||||
PSYC _select_filter_presence
|
||||
PSYC _flag_action_speak_visible
|
||||
PSYC _flag_colors_ignore
|
||||
# does this strictly qualify as a flag, if it has three values, not two?
|
||||
PSYC _flag_echo
|
||||
PSYC _flag_expose_friends
|
||||
PSYC _flag_expose_groups
|
||||
PSYC _flag_greeting
|
||||
PSYC _flag_places_multiple
|
||||
PSYC _flag_presence_ctcp
|
||||
PSYC _flag_screen_clear
|
||||
# does this strictly qualify as a flag, if it has three values, not two?
|
||||
PSYC _flag_stamp_time
|
||||
PSYC _flag_visibility
|
||||
PSYC _page_private
|
||||
PSYC _page_start
|
||||
|
116
world/net/library/profiles.xul
Normal file
116
world/net/library/profiles.xul
Normal file
|
@ -0,0 +1,116 @@
|
|||
<hbox><label value='askaction'/><textbox id='_action_ask' preference='profile_askaction'/></hbox>
|
||||
<hbox><label value='mottoaction'/><textbox id='_action_motto' preference='profile_mottoaction'/></hbox>
|
||||
<hbox><label value='speakaction'/><textbox id='_action_speak' preference='profile_speakaction'/></hbox>
|
||||
<hbox><label value='area'/><textbox id='_address_area' preference='profile_area'/></hbox>
|
||||
<hbox><label value='postalbox'/><textbox id='_address_box_postal' preference='profile_postalbox'/></hbox>
|
||||
<hbox><label value='building'/><textbox id='_address_building' preference='profile_building'/></hbox>
|
||||
<hbox><label value='postalcode'/><textbox id='_address_code_postal' preference='profile_postalcode'/></hbox>
|
||||
<hbox><label value='country'/><textbox id='_address_country' preference='profile_country'/></hbox>
|
||||
<hbox><label value='floor'/><textbox id='_address_floor' preference='profile_floor'/></hbox>
|
||||
<hbox><label value='latitude'/><textbox id='_address_latitude' preference='profile_latitude'/></hbox>
|
||||
<hbox><label value='locality'/><textbox id='_address_locality' preference='profile_locality'/></hbox>
|
||||
<hbox><label value='longitude'/><textbox id='_address_longitude' preference='profile_longitude'/></hbox>
|
||||
<hbox><label value='past'/><textbox id='_address_past' preference='profile_past'/></hbox>
|
||||
<hbox><label value='region'/><textbox id='_address_region' preference='profile_region'/></hbox>
|
||||
<hbox><label value='room'/><textbox id='_address_room' preference='profile_room'/></hbox>
|
||||
<hbox><label value='street'/><textbox id='_address_street' preference='profile_street'/></hbox>
|
||||
<hbox><label value='timezone'/><textbox id='_address_zone_time' preference='profile_timezone'/></hbox>
|
||||
<hbox><label value='affiliation'/><textbox id='_affiliation' preference='profile_affiliation'/></hbox>
|
||||
<hbox><label value='actioncharacter'/><textbox id='_character_action' preference='profile_actioncharacter'/></hbox>
|
||||
<hbox><label value='commandcharacter'/><textbox id='_character_command' preference='profile_commandcharacter'/></hbox>
|
||||
<hbox><label value='color'/><textbox id='_color' preference='profile_color'/></hbox>
|
||||
<hbox><label value='phone'/><textbox id='_contact_telephone' preference='profile_phone'/></hbox>
|
||||
<hbox><label value='fax'/><textbox id='_contact_telephone_fax' preference='profile_fax'/></hbox>
|
||||
<hbox><label value='pager'/><textbox id='_contact_telephone_pager' preference='profile_pager'/></hbox>
|
||||
<hbox><label value='homephone'/><textbox id='_contact_telephone_voice_home' preference='profile_homephone'/></hbox>
|
||||
<hbox><label value='mobilephone'/><textbox id='_contact_telephone_voice_mobile' preference='profile_mobilephone'/></hbox>
|
||||
<hbox><label value='workphone'/><textbox id='_contact_telephone_voice_work' preference='profile_workphone'/></hbox>
|
||||
<hbox><label value='birthday'/><textbox id='_date_birth' preference='profile_birthday'/></hbox>
|
||||
<hbox><label value='nameday'/><textbox id='_date_name' preference='profile_nameday'/></hbox>
|
||||
<hbox><label value='weddingday'/><textbox id='_date_wedding' preference='profile_weddingday'/></hbox>
|
||||
<hbox><label value='expertisetext'/><textbox id='_description_expertise' preference='profile_expertisetext'/></hbox>
|
||||
<hbox><label value='hobbytext'/><textbox id='_description_hobby' preference='profile_hobbytext'/></hbox>
|
||||
<hbox><label value='likestext'/><textbox id='_description_preferences' preference='profile_likestext'/></hbox>
|
||||
<hbox><label value='dislikestext'/><textbox id='_description_preferences_not' preference='profile_dislikestext'/></hbox>
|
||||
<hbox><label value='presencetext'/><textbox id='_description_presence' preference='profile_presencetext'/></hbox>
|
||||
<hbox><label value='privatetext'/><textbox id='_description_private' preference='profile_privatetext'/></hbox>
|
||||
<hbox><label value='publictext'/><textbox id='_description_public' preference='profile_publictext'/></hbox>
|
||||
<hbox><label value='quotestext'/><textbox id='_description_quotes' preference='profile_quotestext'/></hbox>
|
||||
<hbox><label value='charset'/><textbox id='_encoding_characters' preference='profile_charset'/></hbox>
|
||||
<hbox><label value='animalfave'/><textbox id='_favorite_animal' preference='profile_animalfave'/></hbox>
|
||||
<hbox><label value='athletesfave'/><textbox id='_favorite_athletes' preference='profile_athletesfave'/></hbox>
|
||||
<hbox><label value='drinksfave'/><textbox id='_favorite_drinks' preference='profile_drinksfave'/></hbox>
|
||||
<hbox><label value='foodsfave'/><textbox id='_favorite_foods' preference='profile_foodsfave'/></hbox>
|
||||
<hbox><label value='gamesfave'/><textbox id='_favorite_games' preference='profile_gamesfave'/></hbox>
|
||||
<hbox><label value='literaturefave'/><textbox id='_favorite_literature' preference='profile_literaturefave'/></hbox>
|
||||
<hbox><label value='moviesfave'/><textbox id='_favorite_movies' preference='profile_moviesfave'/></hbox>
|
||||
<hbox><label value='musicfave'/><textbox id='_favorite_music' preference='profile_musicfave'/></hbox>
|
||||
<hbox><label value='popstarfave'/><textbox id='_favorite_popstar' preference='profile_popstarfave'/></hbox>
|
||||
<hbox><label value='teamsfave'/><textbox id='_favorite_teams' preference='profile_teamsfave'/></hbox>
|
||||
<hbox><label value='televisionfave'/><textbox id='_favorite_television' preference='profile_televisionfave'/></hbox>
|
||||
<hbox><label value='visiblespeakaction'/><textbox id='_flag_action_speak_visible' preference='profile_visiblespeakaction'/></hbox>
|
||||
<hbox><label value='ignorecolors'/><textbox id='_flag_colors_ignore' preference='profile_ignorecolors'/></hbox>
|
||||
<hbox><label value='echo'/><textbox id='_flag_echo' preference='profile_echo'/></hbox>
|
||||
<hbox><label value='filter'/><textbox id='_flag_filter_strangers' preference='profile_filter'/></hbox>
|
||||
<hbox><label value='exposefriends'/><textbox id='_flag_friends_expose' preference='profile_exposefriends'/></hbox>
|
||||
<hbox><label value='greeting'/><textbox id='_flag_greeting' preference='profile_greeting'/></hbox>
|
||||
<hbox><label value='multipleplaces'/><textbox id='_flag_places_multiple' preference='profile_multipleplaces'/></hbox>
|
||||
<hbox><label value='ctcppresence'/><textbox id='_flag_presence_ctcp' preference='profile_ctcppresence'/></hbox>
|
||||
<hbox><label value='clearscreen'/><textbox id='_flag_screen_clear' preference='profile_clearscreen'/></hbox>
|
||||
<hbox><label value='verbatimuniform'/><textbox id='_flag_uniform_verbatim' preference='profile_verbatimuniform'/></hbox>
|
||||
<hbox><label value='visibility'/><textbox id='_flag_visibility' preference='profile_visibility'/></hbox>
|
||||
<hbox><label value='sex'/><textbox id='_gender' preference='profile_sex'/></hbox>
|
||||
<hbox><label value='id'/><textbox id='_identification' preference='profile_id'/></hbox>
|
||||
<hbox><label value='otherid'/><textbox id='_identification_other' preference='profile_otherid'/></hbox>
|
||||
<hbox><label value='aimid'/><textbox id='_identification_scheme_AIM' preference='profile_aimid'/></hbox>
|
||||
<hbox><label value='icqid'/><textbox id='_identification_scheme_ICQ' preference='profile_icqid'/></hbox>
|
||||
<hbox><label value='msnid'/><textbox id='_identification_scheme_MSN' preference='profile_msnid'/></hbox>
|
||||
<hbox><label value='sipid'/><textbox id='_identification_scheme_SIP' preference='profile_sipid'/></hbox>
|
||||
<hbox><label value='skypeid'/><textbox id='_identification_scheme_Skype' preference='profile_skypeid'/></hbox>
|
||||
<hbox><label value='xmppid'/><textbox id='_identification_scheme_XMPP' preference='profile_xmppid'/></hbox>
|
||||
<hbox><label value='yahooid'/><textbox id='_identification_scheme_Yahoo' preference='profile_yahooid'/></hbox>
|
||||
<hbox><label value='email'/><textbox id='_identification_scheme_mailto' preference='profile_email'/></hbox>
|
||||
<hbox><label value='videophoneid'/><textbox id='_identification_videophone' preference='profile_videophoneid'/></hbox>
|
||||
<hbox><label value='characterimage'/><textbox id='_image_character' preference='profile_characterimage'/></hbox>
|
||||
<hbox><label value='language'/><textbox id='_language' preference='profile_language'/></hbox>
|
||||
<hbox><label value='alternatelanguage'/><textbox id='_language_alternate' preference='profile_alternatelanguage'/></hbox>
|
||||
<hbox><label value='optionallanguage'/><textbox id='_language_optional' preference='profile_optionallanguage'/></hbox>
|
||||
<hbox><label value='worklocation'/><textbox id='_location_work' preference='profile_worklocation'/></hbox>
|
||||
<hbox><label value='worklogin'/><textbox id='_login_work' preference='profile_worklogin'/></hbox>
|
||||
<hbox><label value='familyname'/><textbox id='_name_family' preference='profile_familyname'/></hbox>
|
||||
<hbox><label value='givenname'/><textbox id='_name_given' preference='profile_givenname'/></hbox>
|
||||
<hbox><label value='middlename'/><textbox id='_name_middle' preference='profile_middlename'/></hbox>
|
||||
<hbox><label value='patronymicname'/><textbox id='_name_patronymic' preference='profile_patronymicname'/></hbox>
|
||||
<hbox><label value='prefixname'/><textbox id='_name_prefix' preference='profile_prefixname'/></hbox>
|
||||
<hbox><label value='publicname'/><textbox id='_name_public' preference='profile_publicname'/></hbox>
|
||||
<hbox><label value='suffixname'/><textbox id='_name_suffix' preference='profile_suffixname'/></hbox>
|
||||
<hbox><label value='alternatenick'/><textbox id='_nick_alternate' preference='profile_alternatenick'/></hbox>
|
||||
<hbox><label value='name'/><textbox id='_nick_profile' preference='profile_name'/></hbox>
|
||||
<hbox><label value='longname'/><textbox id='_nick_spaced' preference='profile_longname'/></hbox>
|
||||
<hbox><label value='biographypage'/><textbox id='_page_biography' preference='profile_biographypage'/></hbox>
|
||||
<hbox><label value='diarypage'/><textbox id='_page_diary' preference='profile_diarypage'/></hbox>
|
||||
<hbox><label value='linkspage'/><textbox id='_page_links' preference='profile_linkspage'/></hbox>
|
||||
<hbox><label value='photopage'/><textbox id='_page_photo' preference='profile_photopage'/></hbox>
|
||||
<hbox><label value='privatepage'/><textbox id='_page_private' preference='profile_privatepage'/></hbox>
|
||||
<hbox><label value='publicpage'/><textbox id='_page_public' preference='profile_publicpage'/></hbox>
|
||||
<hbox><label value='publicationspage'/><textbox id='_page_publications' preference='profile_publicationspage'/></hbox>
|
||||
<hbox><label value='resumepage'/><textbox id='_page_resume' preference='profile_resumepage'/></hbox>
|
||||
<hbox><label value='startpage'/><textbox id='_page_start' preference='profile_startpage'/></hbox>
|
||||
<hbox><label value='statuspage'/><textbox id='_page_status' preference='profile_statuspage'/></hbox>
|
||||
<hbox><label value='workpage'/><textbox id='_page_work' preference='profile_workpage'/></hbox>
|
||||
<hbox><label value='password'/><textbox id='_password' preference='profile_password'/></hbox>
|
||||
<hbox><label value='workassistant'/><textbox id='_person_assistant_work' preference='profile_workassistant'/></hbox>
|
||||
<hbox><label value='workmanager'/><textbox id='_person_manager_work' preference='profile_workmanager'/></hbox>
|
||||
<hbox><label value='home'/><textbox id='_place_home' preference='profile_home'/></hbox>
|
||||
<hbox><label value='profession'/><textbox id='_profession' preference='profile_profession'/></hbox>
|
||||
<hbox><label value='workrole'/><textbox id='_role_work' preference='profile_workrole'/></hbox>
|
||||
<hbox><label value='presencefilter'/><textbox id='_select_filter_presence' preference='profile_presencefilter'/></hbox>
|
||||
<hbox><label value='worktitle'/><textbox id='_title_work' preference='profile_worktitle'/></hbox>
|
||||
<hbox><label value='privatefoaffile'/><textbox id='_uniform_FOAF_private' preference='profile_privatefoaffile'/></hbox>
|
||||
<hbox><label value='publicfoaffile'/><textbox id='_uniform_FOAF_public' preference='profile_publicfoaffile'/></hbox>
|
||||
<hbox><label value='characterfile'/><textbox id='_uniform_character' preference='profile_characterfile'/></hbox>
|
||||
<hbox><label value='keyfile'/><textbox id='_uniform_key_public' preference='profile_keyfile'/></hbox>
|
||||
<hbox><label value='photofile'/><textbox id='_uniform_photo' preference='profile_photofile'/></hbox>
|
||||
<hbox><label value='miniphotofile'/><textbox id='_uniform_photo_small' preference='profile_miniphotofile'/></hbox>
|
||||
<hbox><label value='stylefile'/><textbox id='_uniform_style' preference='profile_stylefile'/></hbox>
|
||||
<hbox><label value='workunit'/><textbox id='_unit_work' preference='profile_workunit'/></hbox>
|
330
world/net/library/sandbox.c
Normal file
330
world/net/library/sandbox.c
Normal file
|
@ -0,0 +1,330 @@
|
|||
// vim:foldmethod=marker:syntax=lpc:noexpandtab
|
||||
// $Id: sandbox.c,v 1.16 2008/02/06 12:16:16 lynx Exp $
|
||||
|
||||
#include <net.h>
|
||||
#include <sandbox.h>
|
||||
|
||||
#if __EFUN_DEFINED__(shutdown)
|
||||
MASK(shutdown, "SHUTDOWN")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(add_action)
|
||||
MASK(add_action, "ADD_ACTION")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(break_point)
|
||||
MASK(break_point, "BREAK_POINT")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(call_direct)
|
||||
MASK(call_direct, "CALL_DIRECT")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(call_direct_resolved)
|
||||
MASK(call_direct_resolved, "CALL_DIRECT_RESOLVED")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(call_resolved)
|
||||
MASK(call_resolved, "CALL_RESOLVED")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(swap)
|
||||
MASK(swap, "SWAP")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(debug_info)
|
||||
MASK(debug_info, "DEBUG_INFO")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(command)
|
||||
MASK(command, "COMMAND")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(command_stack)
|
||||
MASK(command_stack, "COMMAND_STACK")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(command_stack_depth)
|
||||
MASK(command_stack_depth, "COMMAND_STACK_DEPTH")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(convert_charset)
|
||||
MASK(convert_charset, "CONVERT_CHARSET")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(debug_message) && DEBUG < 1
|
||||
MASK(debug_message, "DEBUG_MESSAGE")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(disable_commands)
|
||||
MASK(disable_commands, "DISABLE_COMMANDS")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(enable_commands)
|
||||
MASK(enable_commands, "ENABLE_COMMANDS")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(function_exists)
|
||||
MASK(function_exists, "FUNCTION_EXISTS")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(functionlist)
|
||||
MASK(functionlist, "FUNCTIONLIST")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(garbage_collection)
|
||||
MASK(garbage_collection, "GARBAGECOLLECTION")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(get_dir) // caught by valid_read?
|
||||
MASK(get_dir, "GETDIR")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(include_list)
|
||||
MASK(include_list, "INCLUDE_LIST")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(inherit_list)
|
||||
MASK(inherit_list, "INHERIT_LIST")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(input_to_info)
|
||||
MASK(input_to_info, "INPUT_TO_INFO")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(last_instructions)
|
||||
MASK(last_instructions, "LAST_INSTRUCTIONS")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(load_object)
|
||||
MASK(load_object, "LOAD_OBJECT")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(mkdir) // caught by valid_write?
|
||||
MASK(mkdir, "MKDIR")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(move_object)
|
||||
MASK(move_object, "MOVE_OBJECT")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(object_info)
|
||||
MASK(object_info, "OBJECT_INFO")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(process_string)
|
||||
MASK(process_string, "PROCESS_STRING")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(query_ip_name)
|
||||
MASK(query_ip_name, "QUERY_IP_NAME")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(query_ip_number)
|
||||
MASK(query_ip_number, "QUERY_IP_NUMBER")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(query_load_average)
|
||||
MASK(query_load_average, "QUERY_LOAD_AVERAGE")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(query_shadowing)
|
||||
MASK(query_shadowing, "QUERY_SHADOWING")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(remove_action)
|
||||
MASK(remove_action, "REMOVE_ACTION")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(remove_input_to)
|
||||
MASK(remove_input_to, "REMOVE_INPUT_TO")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(remove_interactive)
|
||||
MASK(remove_interactive, "REMOVE_INTERACTIVE")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(rename) // seems to be caught by valid_(read|write), but
|
||||
// i have to check that
|
||||
MASK(rename, "RENAME")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(rm) // caught by valid_write?
|
||||
MASK(rm, "RM")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(rmdir) // caught by valid_write?
|
||||
MASK(rmdir, "RMDIR")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(rusage)
|
||||
MASK(rusage, "RUSAGE")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(say)
|
||||
MASK(say, "SAY")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(set_environment)
|
||||
MASK(set_environment, "SET_ENVIRONMENT")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(set_is_wizard)
|
||||
MASK(set_is_wizard, "SET_IS_WIZARD")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(set_modify_command)
|
||||
MASK(set_modify_command, "SET_MODIFY_COMMAND")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(set_prompt)
|
||||
MASK(set_prompt, "SET_PROMPT")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(swap)
|
||||
MASK(swap, "SWAP")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(tell_object)
|
||||
MASK(tell_object, "TELL_OBJECT")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(tell_room)
|
||||
MASK(tell_room, "TELL_ROOM")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(tls_deinit_connection)
|
||||
MASK(tls_deinit_connection, "TLS_DEINIT_CONNECTION")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(tls_init_connection)
|
||||
MASK(tls_init_connection, "TLS_INIT_CONNECTION")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(tls_query_connection_info)
|
||||
MASK(tls_query_connection_info, "TLS_QUERY_CONNECTION_INFO")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(tls_query_connection_state)
|
||||
MASK(tls_query_connection_state, "TLS_QUERY_CONNECTION_STATE")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(transfer)
|
||||
//MASK(transfer, "TRANSFER")
|
||||
// avoid deprecation warning, and as nobody uses it:
|
||||
nomask void transfer() {}
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(unshadow)
|
||||
MASK(unshadow, "UNSHADOW")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(users)
|
||||
MASK(users, "USERS")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(variable_list)
|
||||
MASK(variable_list, "VARIABLE_LIST")
|
||||
#endif
|
||||
|
||||
#if __EFUN_DEFINED__(wizlist_info)
|
||||
MASK(wizlist_info, "WIZLIST_INFO")
|
||||
#endif
|
||||
|
||||
nomask mixed call_other(mixed obj, string func, varargs mixed * b) {
|
||||
P4(("call_other(%O, %O, %O)\n", obj, func, b));
|
||||
if (extern_call()) {
|
||||
mixed euid = geteuid(previous_object());
|
||||
|
||||
if (stringp(euid) && euid[0] != '/') {
|
||||
string s;
|
||||
object o;
|
||||
|
||||
s = stringp(obj) ? obj : object_name(obj);
|
||||
o = objectp(obj) ? obj : find_object(obj);
|
||||
|
||||
#ifndef __COMPAT_MODE__
|
||||
if (s[0] == '/') s = s[1..];
|
||||
#endif
|
||||
|
||||
if (euid[0] == '@') { // yes, this check is overdone, but only for
|
||||
// now. i think we can use exactly this
|
||||
// structure for allowed call_others into
|
||||
// daemons. says tobij.
|
||||
// <lynX> yes, checking the identity of daemons is much
|
||||
// easier. some of them we already have stored in library
|
||||
// vars, others have static object names, so they can be put
|
||||
// into a switch or mapping. it's only doing so for "any"
|
||||
// user object, which gets too messy. it is architecturally
|
||||
// much cleaner to let sendmsg() decide which msg is legal
|
||||
// (which it has to do anyway) so we don't need yet another
|
||||
// security scheme in here with this wild guessing for user
|
||||
// objects. in fact two redundant security approaches also
|
||||
// unnecessarily raise the chances of being flawed. so let's
|
||||
// allow as few -> operations as possible for sandbox mode.
|
||||
//
|
||||
// great idea. library_object()->sendmsg() _is_
|
||||
// a -> operation, in case you forgot we're doing that (in
|
||||
// entity.c).
|
||||
//
|
||||
// if we rename the library-sendmsg to something reachable
|
||||
// without a call_other, anyways, sendmsg() will be an extra
|
||||
// function call if it just redirects the msg to
|
||||
// target->msg().
|
||||
// in fact, it might be same complexity as calling target->msg
|
||||
// directly, as call_other is overloaded and an lfun doing
|
||||
// ... virtually the same thing for the discussed type of
|
||||
// call.
|
||||
//
|
||||
// the if here isn't even more complex than in sendmsg, it'll
|
||||
// be of equal or less complexity, plus, normal objects
|
||||
// (and, if we want to allow ->qName for everybody anywhere,
|
||||
// normal call_others (well, qName)
|
||||
// don't run deep into this check.
|
||||
//
|
||||
// so, after all, the only argument is "evil! code!
|
||||
// 'duplication'!", which i prefer over (for users who do
|
||||
// their own rooms etc) incomprehensible
|
||||
// #ifndef SADNBOX
|
||||
// target->msg
|
||||
// #else
|
||||
// sendmsg(target, ...)
|
||||
// #endif
|
||||
// mess in files.
|
||||
//
|
||||
// additionally, my sandbox-philosophy is to keep things
|
||||
// maximum equal in usage with and without SANDBOX,
|
||||
// so i'll do it this way.
|
||||
unless (o == previous_object() || o == ME) {
|
||||
int i;
|
||||
|
||||
if ((i = index(s, '#')) == -1) i = strlen(s) - 1;
|
||||
unless (func == "qName"
|
||||
#ifdef FORK
|
||||
|| func == "qOrigin"
|
||||
#endif
|
||||
) switch (s[..i]) {
|
||||
case "net/person#":
|
||||
case "net/user#":
|
||||
//if (func == "qName" || func == "msg") break;
|
||||
if (func == "msg") break;
|
||||
default:
|
||||
if (sscanf(s[..i], "net/%~s/user#")
|
||||
&& func == "msg") break;
|
||||
raise_error(sprintf("INVALID %O "
|
||||
"call_other(%O, %O, %O)\n",
|
||||
euid, obj, func, b));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
raise_error(sprintf("INVALID %O call_other(%O, %O, %O)\n",
|
||||
euid, obj, func, b));
|
||||
}
|
||||
} else unless (euid) {
|
||||
raise_error(sprintf("INVALID euid-0 (%O) call_other(%O, %O, %O)\n",
|
||||
previous_object(), obj, func, b));
|
||||
}
|
||||
set_this_object(previous_object());
|
||||
}
|
||||
return efun::call_other(obj, func, b...);
|
||||
}
|
119
world/net/library/sasl.c
Normal file
119
world/net/library/sasl.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
// $Id: sasl.c,v 1.17 2006/10/18 17:52:15 fippo Exp $ // vim:syntax=lpc
|
||||
|
||||
#include <net.h>
|
||||
|
||||
mapping sasl_parse(string t) {
|
||||
string vname, vvalue;
|
||||
mapping data = ([ ]);
|
||||
|
||||
while (sscanf(t, "%s=%s,%.0t%s", vname, vvalue, t) >= 2) {
|
||||
sscanf(vvalue, "\"%s\"", vvalue);
|
||||
data[vname] = vvalue;
|
||||
}
|
||||
sscanf(t, "%s=%s", vname, vvalue);
|
||||
sscanf(vvalue, "\"%s\"", vvalue);
|
||||
data[vname] = vvalue;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
varargs string sasl_calculate_digestMD5(mapping data, string secret, int calcresponse, string prehash) {
|
||||
/*
|
||||
* calculate the digest-md5 response or rspauth value for data + secret
|
||||
* set calcresponse to 1 if you want to calculate the rspauth,
|
||||
* 0 if you want to calculate the expected response
|
||||
* this function assumes that you have checked the necessary data
|
||||
* and will only complain about missing data with DEBUG > 3
|
||||
*/
|
||||
string HA1, HA2;
|
||||
string t, t2;
|
||||
|
||||
#if DEBUG > 2
|
||||
// data checks
|
||||
unless(mappingp(data) && data["username"] && data["realm"] && data["nonce"]
|
||||
&& data["cnonce"] && data["digest-uri"] && data["nc"]
|
||||
&& data["qop"] && data["qop"] == "auth" // unimplemented otherwise
|
||||
) {
|
||||
raise_error("sasl_calculate_digestMD5 called with invalid data\n"
|
||||
+ sprintf("data is %O\n\n", data));
|
||||
}
|
||||
#endif
|
||||
if (prehash) {
|
||||
/* according to RFC 2831, 3.9 Storing passwords this may also
|
||||
* come directly from a database / storage
|
||||
*/
|
||||
t = prehash;
|
||||
} else {
|
||||
t = md5(data["username"] + ":" + data["realm"] + ":" + secret);
|
||||
}
|
||||
t2 = "";
|
||||
|
||||
// we need octet form
|
||||
// only works with ldmud after 3.3.611
|
||||
for (int i = 0; i < 32; i += 2)
|
||||
t2 += sprintf("%c", to_int("0x" + t[i..i+1]));
|
||||
|
||||
HA1 = md5(t2 + ":" + data["nonce"] + ":" + data["cnonce"]);
|
||||
if (calcresponse)
|
||||
t = ":";
|
||||
else
|
||||
t = "AUTHENTICATE:";
|
||||
t += data["digest-uri"];
|
||||
// TODO: qop == "auth-int"
|
||||
HA2 = md5(t);
|
||||
P2(("sasl: t is %O, t2 is %O\n", t, t2))
|
||||
P2(("sasl: HA1 is %O, HA2 is %O\n", HA1, HA2))
|
||||
|
||||
// watch out, int(nc) should always be one as we dont have
|
||||
// subsequent auth (see rfc 2831)
|
||||
t = sprintf("%s:%s:%s:%s:%s:%s",
|
||||
HA1, data["nonce"], data["nc"],
|
||||
data["cnonce"], data["qop"], HA2);
|
||||
P2(("sasl: response will be md5(%O)\n", t))
|
||||
return md5(t);
|
||||
}
|
||||
|
||||
/* this is testing the behaviour with the example data from RFC 2831
|
||||
* run this whenever you change the code above
|
||||
*/
|
||||
#ifdef TESTSUITE
|
||||
int sasl_test(void) {
|
||||
string t = "realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\","
|
||||
"qop=\"auth\",algorithm=md5-sess,charset=utf-8";
|
||||
string rsp;
|
||||
mapping data;
|
||||
|
||||
// check parsing
|
||||
data = sasl_parse(t);
|
||||
unless (data["realm"] == "elwood.innosoft.com"
|
||||
&& data["algorithm"] == "md5-sess"
|
||||
&& data["charset"] == "utf-8"
|
||||
&& data["nonce"] == "OA6MG9tEQGm2hh"
|
||||
&& data["qop"] == "auth"
|
||||
&& sizeof(data) == 5) {
|
||||
P0(("SASL TEST: parsing failed!! got %O\n", data))
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now add the necessary values from rfc 2831
|
||||
data["username"] = "chris";
|
||||
data["cnonce"] = "OA6MHXh6VqTrRk";
|
||||
data["nc"] = "00000001";
|
||||
data["digest-uri"] = "imap/elwood.innosoft.com";
|
||||
|
||||
// and calculate the response
|
||||
rsp = sasl_calculate_digestMD5(data, "secret", 0);
|
||||
unless (rsp == "d388dad90d4bbd760a152321f2143af7") {
|
||||
P0(("SASL TEST: calc0 failed!! got response %O\n", rsp))
|
||||
return -2;
|
||||
}
|
||||
|
||||
rsp = sasl_calculate_digestMD5(data, "secret", 1);
|
||||
unless (rsp == "ea40f60335c427b5527b84dbabcdfffd") {
|
||||
P0(("SASL TEST: calc1 failed!! got rspauth %O\n", rsp))
|
||||
return -3;
|
||||
}
|
||||
P2(("SASL TEST successful.\n"))
|
||||
return 1;
|
||||
}
|
||||
#endif
|
211
world/net/library/share.c
Normal file
211
world/net/library/share.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
// $Id: share.c,v 1.20 2008/02/10 11:31:10 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// verrry simple way to keep single sets of data for all kinds of purposes.
|
||||
//
|
||||
// the trick is: if you put these mappings here, they only exist once in
|
||||
// the entire system, whereas if defined in your application they will be
|
||||
// recreated for each instance of your app.
|
||||
//
|
||||
// net/d/share was essentially a similar idea, but this works better in library.
|
||||
|
||||
// use something like this to access the mappings:
|
||||
//
|
||||
// volatile mapping mood2jabber;
|
||||
// mood2jabber = shared_memory("mood2jabber");
|
||||
|
||||
#include <net.h>
|
||||
#include <presence.h>
|
||||
#include <peers.h>
|
||||
#include <proto.h>
|
||||
#include <psyc.h>
|
||||
|
||||
// share already contains "preset" data sets
|
||||
volatile mapping share = ([
|
||||
// 'mmp vars' belongs into here aswell.. TODO
|
||||
#ifdef JABBER_PATH
|
||||
"jabber2avail": ([
|
||||
0 : AVAILABILITY_HERE,
|
||||
"chat" : AVAILABILITY_TALKATIVE,
|
||||
"dnd" : AVAILABILITY_BUSY,
|
||||
"away" : AVAILABILITY_DO_NOT_DISTURB,
|
||||
"xa" : AVAILABILITY_AWAY
|
||||
]),
|
||||
// map to http://www.jabber.org/jeps/jep-0107.html although that
|
||||
// is more like good ole mud feelings
|
||||
"mood2jabber": ([
|
||||
0 : "neutral", // unspecified mood
|
||||
// any suggestions on these?
|
||||
1 : "depressed", // not dead
|
||||
2 : "angry",
|
||||
3 : "sad",
|
||||
4 : "moody",
|
||||
5 : "neutral", // not okay
|
||||
6 : "interested", // nothing like 'good'
|
||||
7 : "happy",
|
||||
8 : "excited", // not bright
|
||||
9 : "invincible", // not nirvana
|
||||
]),
|
||||
"disco_identity" : ([
|
||||
"administrator" : "admin",
|
||||
"newbie" : "anonymous",
|
||||
"person" : "registered",
|
||||
"place" : "irc",
|
||||
"news" : "rss",
|
||||
"chatserver" : "im",
|
||||
]),
|
||||
"disco_features" : ([
|
||||
"vCard" : "vcard-temp",
|
||||
"list_feature" : "http://jabber.org/protocol/disco#info",
|
||||
"list_item" : "http://jabber.org/protocol/disco#items",
|
||||
"ignore" : "http://jabber.org/protocol/blocking",
|
||||
"jabber-gc-1.0" : "gc-1.0",
|
||||
"jabber-muc" : "http://jabber.org/protocol/muc",
|
||||
"commands" : "http://jabber.org/protocol/commands",
|
||||
"membersonly" : "muc_membersonly",
|
||||
"nonanonymous" : "muc_nonanonymous",
|
||||
"moderated" : "muc_moderated",
|
||||
"unmoderated" : "muc_unmoderated",
|
||||
"public" : "muc_public",
|
||||
"private" : "muc_hidden",
|
||||
"persistent" : "muc_persistent",
|
||||
"temporary" : "muc_temporary",
|
||||
"registration" : "jabber:iq:register",
|
||||
"offlinestorage" : "msgoffline",
|
||||
"version" : "jabber:iq:version",
|
||||
"lasttime" : "jabber:iq:last",
|
||||
"time" : "jabber:iq:time",
|
||||
]),
|
||||
#endif
|
||||
// even if _degree_availability says it all, we still need
|
||||
// a string to feed to the textdb - even if it were only internal
|
||||
"avail2mc": ([
|
||||
AVAILABILITY_EXPIRED : "_absent", // not true, but..
|
||||
AVAILABILITY_OFFLINE : "_absent",
|
||||
AVAILABILITY_VACATION : "_absent_vacation",
|
||||
AVAILABILITY_AWAY : "_away",
|
||||
AVAILABILITY_DO_NOT_DISTURB : "_here_busy",
|
||||
AVAILABILITY_NEARBY : "_here_busy",
|
||||
AVAILABILITY_BUSY : "_here_busy",
|
||||
AVAILABILITY_HERE : "_here",
|
||||
AVAILABILITY_TALKATIVE : "_here_talkative"
|
||||
]),
|
||||
// these mc mappings are only for the internal textdb
|
||||
"mood2mc": ([
|
||||
0 : "", // unspecified mood
|
||||
// any suggestions on these?
|
||||
1 : "_dead",
|
||||
2 : "_angry",
|
||||
3 : "_sad",
|
||||
4 : "_moody",
|
||||
5 : "_okay",
|
||||
6 : "_good",
|
||||
7 : "_happy",
|
||||
8 : "_bright",
|
||||
9 : "_nirvana",
|
||||
]),
|
||||
// see peers.h for these
|
||||
"ppl2psyc": ([
|
||||
PPL_DISPLAY : "_display",
|
||||
PPL_NOTIFY : "_notification",
|
||||
PPL_EXPOSE : "_expose",
|
||||
PPL_TRUST : "_trust",
|
||||
]),
|
||||
"_display": ([
|
||||
PPL_DISPLAY_NONE : "_none",
|
||||
PPL_DISPLAY_SMALL : "_reduced",
|
||||
PPL_DISPLAY_REGULAR : "_normal",
|
||||
PPL_DISPLAY_BIG : "_highlighted",
|
||||
]),
|
||||
"_notification": ([
|
||||
PPL_NOTIFY_IMMEDIATE : "_immediate",
|
||||
PPL_NOTIFY_DELAYED : "_delayed",
|
||||
PPL_NOTIFY_DELAYED_MORE : "_delayed_more",
|
||||
PPL_NOTIFY_MUTE : "_mute",
|
||||
PPL_NOTIFY_PENDING : "_pending",
|
||||
PPL_NOTIFY_OFFERED : "_offered",
|
||||
PPL_NOTIFY_NONE : "_none",
|
||||
]),
|
||||
// this table defines variable names to go into the routing layer
|
||||
// of PSYC. default is to handle them locally in the routing layer
|
||||
// PSYC_ROUTING_MERGE means to merge them into end-to-end vars at
|
||||
// parsing time. PSYC_ROUTING_RENDER to accept and render them from
|
||||
// application provided vars.
|
||||
"routing": ([
|
||||
"_amount_fragments" : PSYC_ROUTING,
|
||||
"_context" : PSYC_ROUTING + PSYC_ROUTING_MERGE,
|
||||
"_count" : PSYC_ROUTING + PSYC_ROUTING_MERGE,
|
||||
"_fragment" : PSYC_ROUTING,
|
||||
"_length" : PSYC_ROUTING,
|
||||
"_source" : PSYC_ROUTING + PSYC_ROUTING_MERGE,
|
||||
"_source_identification" :
|
||||
PSYC_ROUTING + PSYC_ROUTING_MERGE + PSYC_ROUTING_RENDER,
|
||||
"_source_relay" : PSYC_ROUTING + PSYC_ROUTING_MERGE,
|
||||
// until you have a better idea.. is this really in use?
|
||||
"_source_relay_relay" :
|
||||
PSYC_ROUTING + PSYC_ROUTING_MERGE + PSYC_ROUTING_RENDER,
|
||||
#ifdef NEW_RENDER
|
||||
"_tag" :
|
||||
PSYC_ROUTING + PSYC_ROUTING_MERGE + PSYC_ROUTING_RENDER,
|
||||
"_tag_relay" :
|
||||
PSYC_ROUTING + PSYC_ROUTING_MERGE + PSYC_ROUTING_RENDER,
|
||||
// should be obsolete, but.. TODO
|
||||
"_tag_reply" :
|
||||
PSYC_ROUTING + PSYC_ROUTING_MERGE + PSYC_ROUTING_RENDER,
|
||||
#endif
|
||||
"_target" : PSYC_ROUTING + PSYC_ROUTING_MERGE,
|
||||
"_target_relay" : PSYC_ROUTING + PSYC_ROUTING_MERGE,
|
||||
"_understand_modules" : PSYC_ROUTING,
|
||||
"_using_modules" : PSYC_ROUTING,
|
||||
]),
|
||||
]);
|
||||
|
||||
varargs mixed shared_memory(mixed datensatz, mixed value) {
|
||||
if (value) {
|
||||
share[datensatz] = value;
|
||||
// we don't need a function to delete a data set, do we?
|
||||
// anyway, this could be it:
|
||||
//unless (datensatz) return m_delete(share, value);
|
||||
// usage: shared_memory(0, datensatz);
|
||||
}
|
||||
if (datensatz) return share[datensatz];
|
||||
else return share;
|
||||
}
|
||||
|
||||
#ifdef PSYC_SYNCHRONIZE
|
||||
// one day this could be merged with monitor_report() into
|
||||
// channels of the same context
|
||||
static object sync;
|
||||
|
||||
int synchro_report(string mc, string text, mapping vars) {
|
||||
PT(("SYNCHROCAST %O from %O\n", mc, previous_object()))
|
||||
unless (sync) sync = load_object(PLACE_PATH "sync");
|
||||
if (sync) {
|
||||
sync->msg(previous_object(), mc, text, vars);
|
||||
return 1;
|
||||
}
|
||||
// if you really get here, you will have to parse this
|
||||
// file and resync from there
|
||||
log_file("SYNC_PANIC", "\n\n"+ time() +"\n"+ make_json( ({
|
||||
psyc_name(previous_object()), mc, text, vars
|
||||
}) ));
|
||||
// hey! a new family.. call it _emergency? naah.. long live unix
|
||||
monitor_report("_panic_unavailable_synchronization",
|
||||
"Could not synchronize a "+mc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int synchronize_contact(string mynick, string contact, int pplix, mixed value) {
|
||||
string s = share["ppl2psyc"][pplix];
|
||||
|
||||
unless (s) return 0;
|
||||
if (share[s]) value = share[s][value];
|
||||
else value = PPLDEC(value);
|
||||
synchro_report("_notice_synchronize_contact",
|
||||
"[_nick] has changed [_setting] for \"[_contact]\".", ([
|
||||
"_nick": mynick, "_contact": contact,
|
||||
"_setting": s, "_value": value,
|
||||
]));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
129
world/net/library/signature.c
Normal file
129
world/net/library/signature.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
// $Id: signature.c,v 1.17 2008/03/11 13:42:26 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// generic implementation of http://about.psyc.eu/Signature
|
||||
//
|
||||
// maps an anonymous ordered value list to a named parametric var mapping
|
||||
// according to the signature of a method. probably should
|
||||
// also be able to do it in the other direction.
|
||||
//
|
||||
// needed both for converting slash commands into _request commands
|
||||
// and to implement a protocol level optimization where variable names
|
||||
// can be left out as long as the values are in the proper order.
|
||||
//
|
||||
// currently we only do the first of the two applications (actually the
|
||||
// second being an extension of the first). to achieve that we hold a hash
|
||||
// of command methods which point to their respective signatures.
|
||||
|
||||
#include <net.h>
|
||||
#include <signature.h>
|
||||
|
||||
/* we still don't use structs because they make the driver a lot fatter
|
||||
* we'll get by using arrays and a couple of macros from signature.h
|
||||
*
|
||||
struct Signature {
|
||||
closure handler;
|
||||
mixed extra;
|
||||
array(string) vars;
|
||||
};
|
||||
*
|
||||
* also, we don't use closures as closures stick to the blueprint instead
|
||||
* of operating on the working object. apparently bind_lambda() can rebind
|
||||
* a CLOSURE_LFUN, but i didn't find out how to create that type of closure
|
||||
* and having something like
|
||||
* if (blueprintp(ME)) return
|
||||
* previous_object()->myself(myargs);
|
||||
* in *each* handler is a very ugly enterprise. I finally decided that the
|
||||
* little performance trade off in looking up an object's function in its
|
||||
* function table is well worth the simplicity we get by keeping all
|
||||
* signatures in a central place, being here. first I tried to make a custom
|
||||
* signature hash for each blueprint of a place, but that is just too messy
|
||||
* to go for.
|
||||
*/
|
||||
|
||||
// these could be generated by an external tool
|
||||
private volatile mapping _sigs = ([
|
||||
// "OFFICIAL" METHODS as seen on [[Command]].
|
||||
// ahem... _do? consistency please!
|
||||
"_request_do_show_log": ({ "_request_history", 0, "_parameter" }),
|
||||
// can either be _amount or _match or _parameter
|
||||
"_request_history": ({ "_request_history", 0, "_parameter" }),
|
||||
"_request_kick": ({ "_request_kick", 0, "_person" }),
|
||||
"_request_nickname": ({ "_request_nick_local", 0, "_nick_local", "_INTERNAL_stuss" }),
|
||||
// the real thing, maybe? method inheritance could even lead to here
|
||||
// for all of the _request_set_something methods. good? bad?
|
||||
"_request_set": ({ "_request_set", 0, "_key", "_value" }),
|
||||
// when called by _request_set(), value might be in _value
|
||||
"_request_set_masquerade": ({ "_request_masquerade", 0, "_flag_masquerade" }),
|
||||
"_request_set_owners": ({ "_request_owners", 0, "_list_owners" }), // _tab
|
||||
"_request_set_public": ({ "_request_public", 0, "_flag_public" }),
|
||||
"_request_set_style": ({ "_request_set_style", 0, "_uniform_style" }),
|
||||
// "INTERNAL" METHODS
|
||||
// all of the following "fake" _request methods are just the psyced
|
||||
// way to handle command name variations and shortcuts. never use this
|
||||
// in your clients. always use the official versions listed on
|
||||
// [[Command]]. when sending arbitrary commands, use _request_execute,
|
||||
// don't make up _request_something like psyced does internally.
|
||||
"_request_hist": ({ "_request_history", 0, "_parameter" }),
|
||||
"_request_style": ({ "_request_set_style", 0, "_uniform_style" }),
|
||||
"_request_owners": ({ "_request_owners", 0, "_list_owners" }), // _tab
|
||||
"_request_elrid": ({ "_request_kick", 0, "_person" }),
|
||||
"_request_masquerade": ({ "_request_masquerade", 0, "_flag_masquerade" }),
|
||||
"_request_masq": ({ "_request_masquerade", 0, "_flag_masquerade" }),
|
||||
"_request_nick": ({ "_request_nick_local", 0, "_nick_local", "_INTERNAL_stuss" }),
|
||||
"_request_ni": ({ "_request_nick_local", 0, "_nick_local", "_INTERNAL_stuss" }),
|
||||
"_request_public": ({ "_request_public", 0, "_flag_public" }),
|
||||
"_request_pub": ({ "_request_public", 0, "_flag_public" }),
|
||||
#ifdef EXPERIMENTAL
|
||||
// stuff to play around with
|
||||
"_request_pset": ({ "_request_set", 0, "_key", "_value" }),
|
||||
"_request_cset": ({ "_request_set", 0, "_key_set", "_value" }),
|
||||
"_request_tt": ({ "_request_set", ([ "_key": "_topic" ]), "_value" }),
|
||||
#endif
|
||||
]);
|
||||
|
||||
varargs int call_signature(string source, string mc, mixed data,
|
||||
mapping origvars, varargs array(mixed) more) {
|
||||
Signature s = _sigs[mc];
|
||||
mapping vars;
|
||||
string last;
|
||||
int i, j;
|
||||
|
||||
unless (s) return 0;
|
||||
// ASSERT("call_signature:closurep", closurep(s[SHandler]), s)
|
||||
// vars = ([ "_INTERNAL_method_signature": mc ]);
|
||||
vars = ([]);
|
||||
if (mappingp(origvars) && sizeof(origvars))
|
||||
vars += origvars;
|
||||
if (mappingp(s[SPreset])) vars += s[SPreset];
|
||||
/* else if (s[SPreset])
|
||||
vars["_INTERNAL_preset"] = s[SPreset]; */
|
||||
if (pointerp(data) && sizeof(data)) {
|
||||
vars["_INTERNAL_command"] = data[0];
|
||||
for (i=1, j=SKeys; i<sizeof(data); i++, j++) {
|
||||
if (j < sizeof(s))
|
||||
// check var type here.. TODO
|
||||
vars[ last = s[j] ] = data[i];
|
||||
else
|
||||
vars[ last ] += " "+ data[i];
|
||||
}
|
||||
data = 0;
|
||||
}
|
||||
P2(("call_signature: created %O as vars\n", vars))
|
||||
// this is how i tried to do it with closures..
|
||||
//bind_lambda(s[SHandler]);
|
||||
//return apply(s[SHandler], vars, more);
|
||||
return call_direct(previous_object(), s[SHandler],
|
||||
source, mc, data, vars, more...);
|
||||
}
|
||||
|
||||
#ifdef _flag_extend_backend
|
||||
mapping register_signature(mapping newsigs) {
|
||||
if (newsigs) {
|
||||
_sigs = newsigs;
|
||||
ASSERT("register_signature",
|
||||
mappingp(_sigs) && sizeof(_sigs), _sigs)
|
||||
}
|
||||
return _sigs;
|
||||
}
|
||||
#endif
|
||||
|
97
world/net/library/text.c
Normal file
97
world/net/library/text.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
// $Id: text.c,v 1.17 2008/04/11 10:37:25 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// the marvellous psyctext() function, fundamental of any PSYC implementation.
|
||||
//
|
||||
// this function does PSYC variable replacement for error messages
|
||||
// and informational notices as described in the internet drafts
|
||||
//
|
||||
// this code performs okay, but i would rather have it written in C and
|
||||
// linked to the driver. see also CHANGESTODO for thoughts on how to do a
|
||||
// generic template replacement C function in a way that it does psyctext()
|
||||
// effectively, but can also be used for other syntaxes.
|
||||
//
|
||||
#include <net.h>
|
||||
#include <proto.h>
|
||||
|
||||
varargs string psyctext(string s, mapping m, vastring data,
|
||||
vamixed source, vastring nick) {
|
||||
string r, p, q, v;
|
||||
|
||||
P3(("psyctext(%O)\n", s))
|
||||
unless(s) return "";
|
||||
if (s == "") {
|
||||
if (data) s = data;
|
||||
else return 0;
|
||||
}
|
||||
#if 0
|
||||
ASSERT("psyctext-mapping for "+ to_string(s),
|
||||
mappingp(m) && widthof(m) == 1, m)
|
||||
#else
|
||||
// easy on missing mapping
|
||||
unless (mappingp(m)) return s;
|
||||
#endif
|
||||
r="";
|
||||
while (sscanf(s, "%s[%s]%s", p, v, s) && v) {
|
||||
if (v == "_nick") r += p + (nick || m["_nick"]);
|
||||
else if (v == "_data") r += p + (data || "");
|
||||
else unless (member(m, v)) {
|
||||
if (v == "_source") r += p + to_string(source);
|
||||
else {
|
||||
PT(("psyctext: ignoring [%s]\n", v))
|
||||
r += p + "["+v+"]"; // pretend we havent seen it
|
||||
}
|
||||
}
|
||||
else if (stringp(m[v])) r += p + m[v];
|
||||
else if (pointerp(m[v])) { // used by showMembers
|
||||
r += p + implode(m[v], ", ");
|
||||
}
|
||||
// if (member(m,v) && m[v]) r += p + m[v];
|
||||
else if (intp(m[v])) { // used by /lu and /edit
|
||||
if (v == "_time_idle") r += p + timedelta(m[v]);
|
||||
else if (abbrev("_time", v)) {
|
||||
// verrry similar code in net/user.c
|
||||
if (time() - m[v] > 24*60*60)
|
||||
r += p + isotime( m[v], 0 );
|
||||
else
|
||||
r += p + hhmmss(ctime( m[v] ));
|
||||
// r += p + hhmm(ctime(m[v]));
|
||||
} else
|
||||
r += p + to_string(m[v]);
|
||||
}
|
||||
else if (mappingp(m[v])) { // made by psyc/parse
|
||||
r += p + implode(m_indices(m[v]), ", ");
|
||||
}
|
||||
// used in rare cases where _identification is output
|
||||
else if (objectp(m[v])) r += p + psyc_name(m[v]);
|
||||
else {
|
||||
// in theory at this point we could perform
|
||||
// an inheritance search, but that's overkill.
|
||||
// instead we just bail out. for the psyc standard
|
||||
// on psyctext we will have to decide which option
|
||||
// is right: simplicity vs inheritance power. ouch.
|
||||
D1( if (v[0] == '_')
|
||||
D(S("psyctext warning: invalid %s=%O for %O\n",
|
||||
v, m[v], previous_object() || ME)); )
|
||||
r += p + "["+v+"]"; // pretend we havent seen it
|
||||
}
|
||||
}
|
||||
if (s != "") r += s;
|
||||
return r;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// this doesn't help detect a problem.. this MAKES the problem!
|
||||
// when the library offers a function of the same name as a method
|
||||
// defined in an inheriting class, then the inherited class will
|
||||
// execute the library function instead of finding the method in
|
||||
// the inheriting class. so when you #if 1 this, you will see that
|
||||
// person.c:w() resolves here instead of going into user.c:w().
|
||||
// evil!! -lynX
|
||||
//
|
||||
varargs void w(string mc, string data, mixed vars) {
|
||||
// oh my god seit wann gibt's denn das!?
|
||||
raise_error(sprintf("%O ended up in library/text:w(%s) for %O\n",
|
||||
previous_object(), mc, this_interactive()));
|
||||
}
|
||||
#endif
|
||||
|
55
world/net/library/time.c
Normal file
55
world/net/library/time.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
// $Id: time.c,v 1.3 2007/09/18 08:37:58 lynx Exp $ // vim:syntax=lpc
|
||||
|
||||
#include <net.h>
|
||||
|
||||
volatile mapping cmonth;
|
||||
|
||||
// produces a date/time according to ISO 8601
|
||||
varargs string isotime(mixed ctim, int long) {
|
||||
array(string) t;
|
||||
string res;
|
||||
|
||||
unless (ctim) ctim = ctime();
|
||||
else if (intp(ctim)) ctim = ctime(ctim);
|
||||
if (ctim[8] == ' ') ctim[8] = '0';
|
||||
t = explode(ctim, " ");
|
||||
unless (cmonth) cmonth = ([
|
||||
"Jan" : "01", "Feb" : "02", "Mar" : "03", "Apr" : "04",
|
||||
"May" : "05", "Jun" : "06", "Jul" : "07", "Aug" : "08",
|
||||
"Sep" : "09", "Oct" : "10", "Nov" : "11", "Dec" : "12"
|
||||
]);
|
||||
res = t[4] +"-"+ cmonth[t[1]] +"-"+ t[2];
|
||||
|
||||
// official would be to have "T" instead of " " there,
|
||||
// but all the world prefers readable ISO timestamps.
|
||||
return long ? res+" "+t[3] : res;
|
||||
}
|
||||
|
||||
string timedelta(int secs) {
|
||||
string t = "";
|
||||
int y, d, h, m;
|
||||
|
||||
if (secs < 60) return "--:--";
|
||||
if (y = secs/86400/365) {
|
||||
t += y + "y ";
|
||||
secs = secs % (86400*365);
|
||||
}
|
||||
// if (d = secs/86400/30) {
|
||||
// t += d + "M ";
|
||||
// secs = secs % (86400*30);
|
||||
// }
|
||||
if (d = secs/86400) {
|
||||
if (y) return t + d +"d";
|
||||
t += d + "d ";
|
||||
secs = secs % 86400;
|
||||
}
|
||||
if (h = secs/3600) secs = secs % 3600;
|
||||
if (d) return t+ to_string(h) +"h";
|
||||
// if (m = secs/60) secs = secs % 60;
|
||||
// t += sprintf("%02d:%02d:%02d", h, m, secs);
|
||||
m = secs/60;
|
||||
t += sprintf("%02d:%02d", h, m);
|
||||
// t += hhmm(ctime(secs - 60*60));
|
||||
return t;
|
||||
}
|
||||
|
90
world/net/library/tls.c
Normal file
90
world/net/library/tls.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include <net.h> // vim syntax=lpc
|
||||
mapping tls_certificate(object who, int longnames) {
|
||||
mixed *extra, extensions;
|
||||
mapping cert;
|
||||
int i, j;
|
||||
|
||||
cert = ([ ]);
|
||||
#if __EFUN_DEFINED__(tls_check_certificate)
|
||||
# ifdef WANT_S2S_SASL
|
||||
/*
|
||||
* some platforms (notably cygwin) still have a problem executing the following
|
||||
* #if ... even psyclpc bails out with an "illegal unary operator in #if"
|
||||
* which is nonsense. i simplify this by ifdeffing for psyclpc.
|
||||
*/
|
||||
//# if (__VERSION_MAJOR__ == 3 && __VERSION_MICRO__ > 712) || __VERSION_MAJOR__ > 3
|
||||
# ifdef __psyclpc__
|
||||
# if __EFUN_DEFINED__(enable_binary) // happens to be committed at the same time
|
||||
extra = tls_check_certificate(who, 2);
|
||||
# else
|
||||
extra = tls_check_certificate(who, 1);
|
||||
# endif
|
||||
# else
|
||||
extra = tls_check_certificate(who);
|
||||
# endif
|
||||
unless (extra && sizeof(extra) > 2) return 0;
|
||||
cert[0] = extra[0];
|
||||
if (sizeof(extra) >= 4)
|
||||
cert[1] = extra[3];
|
||||
|
||||
extensions = extra[2];
|
||||
extra = extra[1];
|
||||
|
||||
for (i = 0; i < sizeof(extra); i += 3) {
|
||||
mixed t;
|
||||
|
||||
t = cert[extra[i]];
|
||||
// THIS IS ALWAYS TRUE FOR DRIVER >= 3.3.712
|
||||
// OTHERWISE YOU SHOULD NOT ENABLE S2S SASL. PERIOD.
|
||||
if (sizeof(extra) > i+2) {
|
||||
unless (t) {
|
||||
cert[extra[i]] = extra[i+2];
|
||||
} else if (stringp(t)) {
|
||||
cert[extra[i]] = ({ t, extra[i+2] });
|
||||
} else if (pointerp(t)) {
|
||||
cert[extra[i]] += ({ extra[i+2] });
|
||||
} else {
|
||||
PT(("fippo says this should not happen but you know it always does! %O\n", ME))
|
||||
}
|
||||
} else {
|
||||
PT(("fippo says this should not happen(2) but you know it always does! %O\n", ME))
|
||||
}
|
||||
}
|
||||
if (longnames) {
|
||||
// set up short/long names
|
||||
for (i = 0; i < sizeof(extra); i +=3) {
|
||||
cert[extra[i+1]] = cert[extra[i]];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < sizeof(extensions); i += 3) {
|
||||
string key, mkey;
|
||||
mixed *val;
|
||||
|
||||
unless(extensions[i]) continue;
|
||||
key = extensions[i];
|
||||
val = extensions[i+2];
|
||||
for (j = 0; j < sizeof(val); j += 3) {
|
||||
mixed t;
|
||||
|
||||
mkey = key + ":" + val[j];
|
||||
t = cert[mkey];
|
||||
unless (t) {
|
||||
cert[mkey] = val[j+2];
|
||||
} else if (stringp(t)) {
|
||||
cert[mkey] = ({ t, val[j+2] });
|
||||
} else if (pointerp(t)) {
|
||||
cert[mkey] += ({ val[j+2] });
|
||||
} else {
|
||||
// should not happen
|
||||
}
|
||||
}
|
||||
}
|
||||
# else
|
||||
# echo No WANT_S2S_SASL ? You even have the right driver for it!
|
||||
# endif
|
||||
#else
|
||||
# echo No tls_check_certificate available with this driver.
|
||||
#endif
|
||||
P2(("cert is %O\n", cert))
|
||||
return cert;
|
||||
}
|
138
world/net/library/url.c
Normal file
138
world/net/library/url.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
// $Id: url.c,v 1.43 2008/03/29 20:36:43 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// URLs.. URIs.. UNLs.. UNIs.. maybe even URNs..
|
||||
// the fact they wear a uniform is the only thing these items have in common
|
||||
// after all.. they are not always resources, not always locators,
|
||||
// not always identificators.. but one thing is for sure, they have a
|
||||
// common format.. the uniform :)
|
||||
//
|
||||
// TODO: first move everything called _uniform or url somewhere into here
|
||||
// then rename everything into uniform, also url.c and url.h..
|
||||
|
||||
#include <net.h>
|
||||
#include <url.h>
|
||||
|
||||
string legal_url(string url, string scheme) {
|
||||
if (scheme &&! abbrev(scheme+":", url)) return 0;
|
||||
if (index(url, '"') >= 0) return 0;
|
||||
if (index(url, ' ') >= 0) return 0; // just
|
||||
if (index(url, '\t') >= 0) return 0; // paranoid
|
||||
return url;
|
||||
}
|
||||
|
||||
/** pass it a URL string and it will find out if that string
|
||||
** is a uniform, and if so return an array as defined in url.h
|
||||
**
|
||||
** <fippo> what about using
|
||||
** http://www.gbiv.com/protocols/uri/rfc/rfc3986.html#regexp ?
|
||||
** <lynX> sweet, i really like that. can we do that?
|
||||
** only we have to change that regexp a lot. like we don't
|
||||
** need $1, $6 and $8, we need USlashes instead of $3, but
|
||||
** what's tough is, we need UQuery to support ; or ? and
|
||||
** we need UUser, UPass, UPort, UTransport, and UHostPort.
|
||||
** all of that isn't in that regexp yet...
|
||||
*/
|
||||
varargs array(mixed) parse_uniform(string url, vaint tolerant) {
|
||||
array(string) u = allocate(USize);
|
||||
string t;
|
||||
string s;
|
||||
|
||||
u[UString] = url;
|
||||
if (sscanf(url, "%s:%s", u[UScheme], t) != 2) {
|
||||
if (tolerant) t = url;
|
||||
else return 0;
|
||||
}
|
||||
ASSERT("parse_uniform w/out scheme", u[UScheme] || tolerant, url)
|
||||
P3(("parse_uniform %s of %O (tolerant: %O)\n",
|
||||
url, u[UScheme], tolerant))
|
||||
if (abbrev("//", t)) {
|
||||
t = t[2..];
|
||||
u[USlashes] = "//";
|
||||
} else u[USlashes] = "";
|
||||
switch(u[UScheme]) {
|
||||
case "sip":
|
||||
sscanf(t, "%s;%s", t, u[UQuery]);
|
||||
break;
|
||||
case "telnet":
|
||||
break;
|
||||
case "psyc":
|
||||
sscanf(t, "%s#%s", t, u[UChannel]);
|
||||
break;
|
||||
#if 0 //def MUCSUC
|
||||
case "xmpp":
|
||||
sscanf(t, "%s#%s", t, u[UChannel]);
|
||||
break;
|
||||
#endif
|
||||
//case "mailto":
|
||||
default:
|
||||
sscanf(t, "%s?%s", t, u[UQuery]);
|
||||
}
|
||||
u[UBody] = t;
|
||||
sscanf(t, "%s/%s", t, u[UResource]);
|
||||
#if 0
|
||||
// int n;
|
||||
if (-1 != (n = member(u[UResource], '#'))) {
|
||||
u[UChannel] = u[UResource][n+1..]; // strlen checken??
|
||||
}
|
||||
#endif
|
||||
u[UUserAtHost] = t;
|
||||
if (sscanf(t, "%s@%s", s, t)) {
|
||||
unless (sscanf(s, "%s:%s", u[UUser], u[UPass]))
|
||||
u[UUser] = s;
|
||||
}
|
||||
u[UHostPort] = t;
|
||||
// if (complete) u[UCircuit] = u[UScheme]+":"+u[UHostPort];
|
||||
u[URoot] = u[UScheme]+":"+u[USlashes]+u[UHostPort];
|
||||
if (sscanf(t, "%s:%s", t, s)) {
|
||||
unless (sscanf(s, "%d%s", u[UPort], u[UTransport]))
|
||||
u[UTransport] = s;
|
||||
unless (strlen(u[UTransport])) u[UTransport] = 0;
|
||||
}
|
||||
u[UHost] = t;
|
||||
P4(("parse_uniform %s = %O (tolerant: %O)\n", url, u, tolerant))
|
||||
return u;
|
||||
}
|
||||
|
||||
string render_uniform(array(mixed) u) {
|
||||
string s, t;
|
||||
// wird aufgerufen wenn dieser string nicht mehr gültig ist:
|
||||
// if (u[UString]) return u[UString];
|
||||
unless (s = u[UHost]) return 0;
|
||||
if (u[UUser]) s = u[UPass] ? (u[UUser]+":"+u[UPass]+"@"+s)
|
||||
: (u[UUser]+"@"+s);
|
||||
if (u[UScheme]) s = u[UScheme]+"://"+s;
|
||||
t = u[UPort] ? to_string(u[UPort]) : "";
|
||||
if (u[UTransport]) t += u[UTransport];
|
||||
if (t != "") s += ":"+t+"/";
|
||||
if (u[UResource]) s += u[UResource];
|
||||
if (u[UChannel]) s += "#"+ u[UChannel];
|
||||
if (u[UQuery]) s += "?"+ u[UQuery];
|
||||
D2( if (u[UString] == s) D("render_uniform: das war umsonst..\n"); )
|
||||
P3(("render_uniform %O = %s\n", u, s))
|
||||
return u[UString] = s;
|
||||
}
|
||||
|
||||
// convert GENERIC psyc url stringp()s to objects (if local)
|
||||
#if 0
|
||||
mixed urlobject(string url) {
|
||||
array(mixed) u;
|
||||
object o;
|
||||
|
||||
// we avoid errors! we rule!
|
||||
u = parse_uniform(url);
|
||||
unless (query_udp_port() == (u[UPort] || PSYC_PORT))
|
||||
return url;
|
||||
unless (u[UHost] == __HOST_IP_NUMBER__
|
||||
|| lower_case(u[UHost]) == lower_case(SERVER_HOST))
|
||||
return url;
|
||||
|
||||
if (u[UResource][0] == '~')
|
||||
o = find_person(u[UResource][1..]);
|
||||
else if (u[UUser]) o = find_person(u[UUser]);
|
||||
else o = find_object(u[UResource]);
|
||||
|
||||
unless(objectp(o)) return url;
|
||||
return o;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue