ds2.1.1/bin/
ds2.1.1/extra/wolfpaw/
ds2.1.1/lib/cmds/admins/
ds2.1.1/lib/cmds/common/
ds2.1.1/lib/cmds/creators/include/
ds2.1.1/lib/cmds/creators/include/SCCS/
ds2.1.1/lib/daemon/services/
ds2.1.1/lib/doc/
ds2.1.1/lib/doc/efun/all/
ds2.1.1/lib/doc/efun/arrays/
ds2.1.1/lib/doc/efun/buffers/
ds2.1.1/lib/doc/efun/compile/
ds2.1.1/lib/doc/efun/floats/
ds2.1.1/lib/doc/efun/functions/
ds2.1.1/lib/doc/efun/general/
ds2.1.1/lib/doc/efun/mixed/
ds2.1.1/lib/doc/efun/numbers/
ds2.1.1/lib/doc/efun/parsing/
ds2.1.1/lib/doc/faq/
ds2.1.1/lib/doc/hbook/
ds2.1.1/lib/doc/help/classes/
ds2.1.1/lib/doc/lpc/basic/
ds2.1.1/lib/doc/lpc/concepts/
ds2.1.1/lib/doc/lpc/constructs/
ds2.1.1/lib/doc/lpc/etc/
ds2.1.1/lib/doc/lpc/intermediate/
ds2.1.1/lib/doc/lpc/types/
ds2.1.1/lib/doc/misc/
ds2.1.1/lib/doc/old/
ds2.1.1/lib/domains/Ylsrim/
ds2.1.1/lib/domains/Ylsrim/adm/
ds2.1.1/lib/domains/Ylsrim/armor/
ds2.1.1/lib/domains/Ylsrim/broken/
ds2.1.1/lib/domains/Ylsrim/fish/
ds2.1.1/lib/domains/Ylsrim/meal/
ds2.1.1/lib/domains/Ylsrim/npc/
ds2.1.1/lib/domains/Ylsrim/obj/
ds2.1.1/lib/domains/Ylsrim/virtual/
ds2.1.1/lib/domains/Ylsrim/weapon/
ds2.1.1/lib/domains/campus/adm/
ds2.1.1/lib/domains/campus/etc/
ds2.1.1/lib/domains/campus/meals/
ds2.1.1/lib/domains/campus/npc/
ds2.1.1/lib/domains/campus/txt/ai/charles/
ds2.1.1/lib/domains/campus/txt/ai/charles/bak2/
ds2.1.1/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.1.1/lib/domains/campus/txt/ai/charly/
ds2.1.1/lib/domains/campus/txt/ai/charly/bak/
ds2.1.1/lib/domains/campus/txt/jenny/
ds2.1.1/lib/domains/default/creator/
ds2.1.1/lib/domains/default/doors/
ds2.1.1/lib/domains/default/etc/
ds2.1.1/lib/domains/default/weap/
ds2.1.1/lib/domains/town/doors/
ds2.1.1/lib/domains/town/txt/
ds2.1.1/lib/domains/town/txt/shame/
ds2.1.1/lib/domains/town/virtual/
ds2.1.1/lib/lib/comp/
ds2.1.1/lib/lib/lvs/
ds2.1.1/lib/lib/user/
ds2.1.1/lib/lib/virtual/
ds2.1.1/lib/log/
ds2.1.1/lib/obj/book_source/
ds2.1.1/lib/obj/include/
ds2.1.1/lib/realms/template/
ds2.1.1/lib/realms/template/area/armor/
ds2.1.1/lib/realms/template/area/npc/
ds2.1.1/lib/realms/template/area/obj/
ds2.1.1/lib/realms/template/area/room/
ds2.1.1/lib/realms/template/area/weap/
ds2.1.1/lib/realms/template/bak/
ds2.1.1/lib/realms/template/cmds/
ds2.1.1/lib/save/kills/o/
ds2.1.1/lib/secure/cfg/
ds2.1.1/lib/secure/cfg/classes/
ds2.1.1/lib/secure/cfg/races/SCCS/
ds2.1.1/lib/secure/cmds/creators/include/
ds2.1.1/lib/secure/cmds/players/
ds2.1.1/lib/secure/cmds/players/include/
ds2.1.1/lib/secure/daemon/include/
ds2.1.1/lib/secure/lib/
ds2.1.1/lib/secure/lib/include/
ds2.1.1/lib/secure/lib/net/
ds2.1.1/lib/secure/lib/net/include/
ds2.1.1/lib/secure/lib/std/
ds2.1.1/lib/secure/modules/
ds2.1.1/lib/secure/npc/
ds2.1.1/lib/secure/obj/include/
ds2.1.1/lib/secure/room/
ds2.1.1/lib/secure/save/
ds2.1.1/lib/secure/save/boards/
ds2.1.1/lib/secure/verbs/creators/
ds2.1.1/lib/shadows/
ds2.1.1/lib/spells/
ds2.1.1/lib/verbs/admins/include/
ds2.1.1/lib/verbs/common/
ds2.1.1/lib/verbs/common/include/
ds2.1.1/lib/verbs/creators/
ds2.1.1/lib/verbs/creators/include/
ds2.1.1/lib/verbs/players/include/SCCS/
ds2.1.1/lib/verbs/rooms/
ds2.1.1/lib/verbs/rooms/include/
ds2.1.1/lib/www/errors/
ds2.1.1/lib/www/images/
ds2.1.1/v22.2b14/
ds2.1.1/v22.2b14/ChangeLog.old/
ds2.1.1/v22.2b14/Win32/
ds2.1.1/v22.2b14/compat/
ds2.1.1/v22.2b14/compat/simuls/
ds2.1.1/v22.2b14/include/
ds2.1.1/v22.2b14/testsuite/
ds2.1.1/v22.2b14/testsuite/clone/
ds2.1.1/v22.2b14/testsuite/command/
ds2.1.1/v22.2b14/testsuite/data/
ds2.1.1/v22.2b14/testsuite/etc/
ds2.1.1/v22.2b14/testsuite/include/
ds2.1.1/v22.2b14/testsuite/inherit/
ds2.1.1/v22.2b14/testsuite/inherit/master/
ds2.1.1/v22.2b14/testsuite/log/
ds2.1.1/v22.2b14/testsuite/single/
ds2.1.1/v22.2b14/testsuite/single/tests/compiler/
ds2.1.1/v22.2b14/testsuite/single/tests/efuns/
ds2.1.1/v22.2b14/testsuite/single/tests/operators/
ds2.1.1/v22.2b14/testsuite/u/
ds2.1.1/v22.2b14/tmp/
ds2.1.1/win32/
// This file written completely by Tim Johnson (Tim@TimMUD)

static void read_callback(int fd, mixed info){
    // This is called when messages come in from a MUD.
    // Should reject all messages if they have not done a (successful) startup-req,
    // Should check to make sure the fd matches with the mud they are claiming to be, else error.
    // because all packets require an originator_mudname.

    // If target is the name of the router, then call the function in this object.
    // if target is 0, then broadcast to muds.
    // Do an error if target mudname is not known.
    // 

    // According to: http://www.intermud.org/i3/specs/formats.php3
    // Transmissions are LPC arrays with a predefined set of six initial elements:
    // ({ type, ttl, originator mudname, originator username, target mudname, target username, ... }). 
    // info[0]=type
    // info[1]=ttl
    // info[2]=originator mudname
    // info[3]=originator username
    // info[4]=target mudname
    // info[5]=target username

    string mudname;
    int i;
    trr("Received from fd("+fd+"), fd("+socket_address(fd)+")\n"+identify(info),((info[0] == "auth-mud-req" || info[0] == "auth-mud-reply") ? "magenta" : "green"));
    // Base info in a packet is of size 6.
    if(sizeof(info)<6 ||
      !stringp(info[0]) ||
      !intp(info[1]) || !stringp(info[2]) ||
      (!stringp(info[3]) && info[3]!=0) ||
      (!stringp(info[4]) && info[4]!=0) ||
      (!stringp(info[5]) && info[5]!=0) ) {
	write_data(fd,({
	    // okay, their initial data isn't fully there...
	    // careful about array out of bounds...
	    "error",5,router_name,0,
	    (sizeof(info)>=3 ? info[2] : 0), // mud name
	    (sizeof(info)>=4 ? info[3] : 0), // user name
	    "bad-pkt","Invalid initial data",info
	  }));
	return;
    }
    if(info[4]!=0 && !connected_muds[info[4]] && info[4]!=router_name){
	// if target mud is not 0 (broadcasting), not the router name,
	// and not a connected MUD
	write_data(fd,({
	    "error",
	    5,
	    router_name,
	    0,
	    info[2],
	    info[3],
	    "unk-dst", // same as I3
	    "destination unknown", // same as I3
	    info
	  }));
	trr("Error [unk-dst], because target is "+info[4]+" and thus invalid.");
	return;
    }
    if(sscanf(info[0],"startup-req-%d",i)==1){
	// special condition for startup-req...
	trr("calling process_startup_req, i="+i+", fd="+fd+" which is: "+socket_address(fd));
	//call_other(this_object(),"process_startup_req",i,info,fd);
	this_object()->process_startup_req(i,info,fd);
	return;
    }
    if(!connected_muds[info[2]] || (connected_muds[info[2]]!=fd)){
	// MUD hasn't done a startup-req yet
	write_data(fd,({
	    "error",
	    5,
	    router_name,
	    0, // originator username
	    info[2], // mud name
	    info[3], // user name
	    "unk-src", // error code
	    "Your MUD hasn't registered as "+info[2]+" yet", // Error message
	    info
	  }));
	trr("They have not done a startup-req for fd="+fd+", mudname="+info[2]);
	return;
    }
    // at this point, I guess it has a valid origin and stuff
    if(sscanf(info[0],"channel-%*s")==1){ // command has a "channel-" prefix
	// special case for channel stuff
	trr("calling process_channel...");
	process_channel(fd,info);
	return;
    }
    if(info[0]=="chan-filter-reply"){
	if(!stringp(info[6]) || sizeof(info[7])<9 ){
	    // avoid out-of-bounds
	    send_error(info[2],info[3],"bad-pkt",
	      "Invalid chan-filter-reply packet.",info);
	}
	if(channels[info[6]][1]!=info[2]){
	    send_error(info[2],info[3],"not-allowed",
	      "You are not the owner of "+info[6],info);
	    return;
	}
	if(member_array(info[7][6],({ "channel-a", "channel-e", "channel-t"}))==-11){
	    // Not a valid channel packet.
	    send_error(info[2],info[3],"not-allowed","*giggles*",info);
	}
	if(info[6]!=info[7][6]){
	    // They're trying to trick me into broadcasting
	    // fake messages on another channel!
	    // That's pretty funny :P
	    // I'll have to remember to check if the official router falls for it.
	    send_error(info[2],info[3],"not-allowed","Hehe!",info);
	    return;
	}
	if(member_array(info[7][6],({ "channel-a", "channel-e", "channel-t"}))){

	}
	// Broadcast the message...
	foreach(mudname in keys(connected_muds)){
	    if(member_array(mudname, listening[info[6]])!=-1)
		write_data(connected_muds[mudname],info[7]);
	}
	return;
    }

    if(info[4]==0){ // if broadcasting this...
	broadcast_data(connected_muds,info);
	return;
    }
    if(info[4]==router_name) {
	// Something meant for the router but not handled by now!
	send_error(info[2],info[3],"not-imp","Unknown command sent to router: "+info[0],info);
	trr("unhandled packet meant for router: "+info[0],"red");
	log_file("server","UNHANDLED PACKET:\n"+identify(info)+"\n");
	return;
    }
    // at this point, I guess you should forward it to the destination...
    if(info[0]=="locate-reply"){
	// Special case for locate-reply, because protocol 3 has a larger packet...
	if(sizeof(info)==8 && mudinfo[info[4]]["protocol"]>2){
	    // originator mud is sending a protocol 1/2 response,
	    // but target understands 3, so add the extra info
	    write_data(connected_muds[info[4]], ({
		info[0],info[1],info[2],info[3],info[4],info[5],
		info[6],info[7],0,0
	      }));
	    return;
	}
	if(sizeof(info)==10 && mudinfo[info[4]]["protocol"]<=2){
	    // target mud is being sent a protocol 3 response,
	    // but only understands 1 & 2, so strip the extra info
	    write_data(connected_muds[info[4]], ({
		info[0],info[1],info[2],info[3],info[4],info[5],
		info[6],info[7]
	      }));
	    return;
	}
    }
    write_data(connected_muds[info[4]], info);
    return;
}