tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
/*
    InterMud 3 client
        by Drizzt@Tmi-2
// Leto july 6th 95 - Tried to add some security :)
*/
                     
#include <net/i3.h>
 
#define I3_DEBUG_OUT 0x01
#define I3_DEBUG_IN  0x02
#define I3_DEBUG_LST 0x04
 
static object router_socket, oob_socket, debugger;
static mapping services;
static int debug_level;
int router_password, mudlist_id, chanlist_id;
mapping mudlist, chanlist;
 
// Prototypes :)
void create();
void check_router();

void set_debugging(int level, object person){

// Prevent people from snooping private stuff
   if(!adminp(person)) return;

    debugger = person;
    debug_level = level;
}
 
mixed *query_debugging(){
    return ({ debugger, debug_level });
}
 
static private void debug_stuff(mixed message){

  if(debugger)
    message("I3",sprintf("%c[1;32m[I3]: %O%c[0m\n", 27, message, 27), debugger);    
}
 
string query_network_name(string mud){
    string *names;
    int found,i;
    
    if(mud == "global") return 0;
    if(mud && mudlist){
        mud = replace_string(mud,"."," ");
        /* Match in the Mudlist for a correct name */
        mud = lower_case(mud);
        names = keys(mudlist);
        found = 0;
        for(i=0;i<sizeof(names);i++){
            if(lower_case(names[i]) == mud) {
                mud = names[i];
                found = 1;
                break;
            }
        }
        if(!found) return 0;
    }        
    return mud;
}    
 
int read_callback(object socket, mixed info){
    string func, fname;
 
// Leto: We should add an origin() and/or prev_obj==SOCKET_OBJ
// check for security.
    if(!sizeof(info)) return 0;
    if(debug_level & I3_DEBUG_IN) debug_stuff(info);
    func = "process_"+info[0];
    func = replace_string(func,"-","_");
    if(function_exists(func, this_object())) {
        /* Internal function (Mudlists, etc) */
        call_other(this_object(), func, info);
        return 0;
    }    
    /* External Module */
    if(!sscanf(info[0], "%s-%*s",fname)) fname = info[0];
    call_other(I3_MODULES+fname, func, info);
    return 1;
}
 
int close_callback(object socket){

// Leto: add a check here too, same reason.

    socket->remove();
    create();
    return 1;
}
  
int send_packet(string type, string user, string mud, string target, mixed *data){
    mixed *send, *names;
    int i,found;
 
// Leto: Add origin()==LOCAL_ORGIN || base_name(prev_obj)[0..x]
// == "/adm/daemons/network/I3/" check here.

    if(!query_network_name(mud) && mud != "global" && mud != 0) return 0;
    mud = query_network_name(mud);
    send = ({ type, I3_TTL, MUD_NAME, user, mud, target }) + data;
    if(debug_level & I3_DEBUG_OUT) debug_stuff(send);
    router_socket->send(send);
    return 1;
}    
 
static private int send_chanlist_req(){
    send_packet(PRT_CHANLIST_REQ, 0, ROUTER_NAME, 0, ({ chanlist_id }) );
}    
 
// Leto: I can't find anything calling this function.
void process_chanlist_reply(mixed *info){
    int i;
    string *kys;
 
    if(sizeof(info) != SIZ_CHANLIST_REPLY) return;
    chanlist_id = info[6];
    if(!chanlist) chanlist = ([]);
    chanlist += info[7];
    kys = keys(chanlist);
    /* Clean up deleted channels */
    for(i=0;i<sizeof(kys);i++){
        if(!chanlist[kys[i]]) map_delete(chanlist, kys[i]);
    }
    save_object(I3_SAVE_FILE);
}    
    
static private int send_startup_req_1() {
    mixed *packet;
 
    packet = ({ router_password, 
                mudlist_id,
                chanlist_id,
                __PORT__,
                OOB_TCP,
                OOB_UDP,
                I3_MUDLIB,
                I3_BASE_LIB,
                __VERSION__,
                "LPmud",
                MUD_STAGE,
                services });
    send_packet(PRT_STARTUP_REQ_1,0,ROUTER_NAME,0,packet);
}    
 
// Leto: This function isn't called either
void process_startup_reply(mixed *info){
    if(sizeof(info) != SIZ_STARTUP_REPLY) return;
    router_password = info[7];
    save_object(I3_SAVE_FILE);
}
 
 
/*
    Internal Mudlist Routines:
        We handle all of them in here because this way we can deal with
        only 1 object to save, instead of saving a module, and this object
*/
 
void process_mudlist(mixed *info){
    string *kys;
    int i;
 
    if(sizeof(info) != SIZ_MUDLIST) return;
    mudlist_id = info[6];
    if(!mudlist) mudlist = ([]);
    mudlist += info[7];
    kys = keys(mudlist);
    /* Clean up deleted channels */
    for(i=0;i<sizeof(kys);i++){
        if(!mudlist[kys[i]]) {
            map_delete(mudlist, kys[i]);
            if(debug_level & I3_DEBUG_LST) debug_stuff("Removing Mud \""+kys[i]+"\"\n");
            continue;
        }
    }
    save_object(I3_SAVE_FILE);
}
 
mixed query_mud(string arg){
    return mudlist[arg];
}
mapping query_mudlist(){
    return mudlist;
}
/* End of Mudlist Routines */
 
void send_error(string mud, string user, string error_code, string message, mixed *packet){
    send_packet(PRT_ERROR, 0, mud, user, ({ error_code, message, packet }));
}
 
void process_error(mixed *info){
    object ob;
 
    ob = find_living(info[5]);
if (!ob && debugger) ob = debugger;
if (!ob) log_file("I3","I3 Error from "+info[2]+": "+info[7]+"\n");
    else message("I3","I3 Error from "+info[2]+": "+info[7]+"\n", ob);
}    
 
void setup_services(){
    mixed dir;
    string name;
    int i;
 
    services = ([]);
#ifdef I3_SERVICE_DETECT
    dir = get_dir(I3_MODULES);
    for(i=0;i<sizeof(dir);i++){
        sscanf(dir[i],"%s.c", name);
        services += ([ name : 1 ]);
    }
#endif
    services += I3_SERVICES;
    return;
}
 
 
void create(){ 
    if(sizeof(get_dir(I3_SAVE_FILE))) restore_object(I3_SAVE_FILE);
    setup_services();
    router_socket = clone_object(SOCKET, SKT_STYLE_CONNECT_M, 
                                 I3_ROUTER, (: read_callback :), 
                                 (: close_callback :) );
    oob_socket = clone_object(SOCKET, SKT_STYLE_LISTEN_M, OOB_TCP,
		 		(: read_callback :), (: close_callback :) );
    send_startup_req_1();
// [Deathblade] commented this damn thing out :-).  There is
// no such packet.
//    send_chanlist_req();

call_out( (: check_router :) , 900 );
}
 
void remove(){  
    if(oob_socket) oob_socket->remove();
    if(router_socket) router_socket->remove();
    destruct(this_object());
}
 

void check_router() {

if(!router_socket || !oob_socket) 
 {
  log_file("I3","Lost I3 router, reconnecting at "+ctime(time())+".\n");
  create();
  return;
 }
 call_out( (: check_router :) , 900 );
}