dns_mastergold.c

来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· C语言 代码 · 共 887 行 · 第 1/2 页

C
887
字号
			"tell"     :  SVC_UDP,			"rwho_q"   :  SVC_UDP,			"gwizmsg"  :  SVC_UDP,		]);		break;	default: // TCP_NONE		mud_svc[name] = ([			"mail"     :  SVC_NO_TCP,			"finger"   :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,			"tell"     :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,			"rwho_q"   :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,			"gwizmsg"  :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,		]);		break;	} // switch (tcp)	// handle service information	if (tcp != TCP_ONLY)		query_services(name, junk["HOSTADDRESS"], junk["PORTUDP"], tcp);}// deletes an entry for a mudvoid zap_mud_info(string name, mapping junk){	// check permissions	if( !previous_object()	||	!ACCESS_CHECK(previous_object())	||	file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH)		return;	// delete the entry	map_delete(muds, name);	// wipe the service information	map_delete(mud_svc, name);}// This is called when we get a service response from the other endvoid support_q_callback(mapping info){	string cmd;	string mud;	// check permission	if (!ACCESS_CHECK(previous_object())) return;	// check the reply is valid - note that if info is 0 it is possible	// this is the result of a tiemout, but as muds are only queried	// once, and the default is unknown, we dont have a problem.	if (!info || !info["CMD"] || !info["NAME"] || !strlen(info["CMD"])	||	!strlen(info["NAME"]))		return;	mud = htonn( info["NAME"] );	if (undefinedp(muds[mud])) return;	if (undefinedp(mud_svc[mud])) mud_svc[mud] = ([]);	if(!info["SUPPORTED"] && !info["NOTSUPPORTED"]) return; // mesed up packet	if (info["CMD"] == "tcp") {		cmd = info["PARAM"];      // if udp is known then we know the whole status      if (mud_svc[mud][cmd] & (SVC_UDP | SVC_NO_UDP))	mud_svc[mud][cmd] |= SVC_KNOWN;      if (info["SUPPORTED"])	{	  mud_svc[mud][cmd] |= SVC_TCP;	  mud_svc[mud][cmd] &= ~SVC_NO_TCP;	}      else	{	  mud_svc[mud][cmd] |= SVC_NO_TCP;	  mud_svc[mud][cmd] &= ~SVC_TCP;	  // if they don't support something tcp, we check udp	  if(!(mud_svc[mud][cmd] & SVC_KNOWN))	    SUPPORT_Q->send_support_q(muds[mud]["HOSTADDRESS"],				      muds[mud]["PORTUDP"], info["PARAM"]);	}    } // if (info["CMD"] == "tcp")  else    {      cmd = info["CMD"];      // if tcp is known then we know the whole status      if (mud_svc[mud][cmd] & (SVC_TCP | SVC_NO_TCP))	mud_svc[mud][cmd] |= SVC_KNOWN;      if (info["SUPPORTED"])	{	  mud_svc[mud][cmd] |= SVC_UDP;	  mud_svc[mud][cmd] &= ~SVC_NO_UDP;	}      else	{	  mud_svc[mud][cmd] |= SVC_NO_UDP;	  mud_svc[mud][cmd] &= ~SVC_UDP;	  // if they don't support something udp, we check tcp	  if(!(mud_svc[mud][cmd] & SVC_KNOWN))	    SUPPORT_Q->send_support_q(muds[mud]["HOSTADDRESS"],				      muds[mud]["PORTUDP"], "tcp", info["CMD"]);	}    } // if (info["CMD"] == "tcp")  return;}// This queries a mud just added to the database for its supported services// What is queries for is dependant on config.hprivate voidquery_services(string mud, string address, string port, string tcp){#ifdef PREF_MAIL  if (!(mud_svc[mud]["mail"] & SVC_KNOWN))    {#if PREF_MAIL & SVC_TCP      if (tcp == TCP_SOME && !(mud_svc[mud]["mail"] & (SVC_TCP | SVC_NO_TCP)))	SUPPORT_Q->send_support_q(address, port, "tcp", "mail");#elif PREF_MAIL & SVC_UDP      if (!(mud_svc[mud]["mail"] & (SVC_UDP | SVC_NO_UDP)))	SUPPORT_Q->send_support_q(address, port, "mail");#endif    }#endif // PREF_MAIL#ifdef PREF_FINGER  if (!(mud_svc[mud]["finger"] & SVC_KNOWN))    {#if PREF_FINGER & SVC_TCP      if (tcp == TCP_SOME && !(mud_svc[mud]["finger"] & (SVC_TCP | SVC_NO_TCP)))	SUPPORT_Q->send_support_q(address, port, "tcp", "finger");#endif    }#endif // PREF_FINGER#ifdef PREF_TELL  if (!(mud_svc[mud]["tell"] & SVC_KNOWN))    {#if PREF_TELL & SVC_TCP      if (tcp == TCP_SOME && !(mud_svc[mud]["tell"] & (SVC_TCP | SVC_NO_TCP)))	SUPPORT_Q->send_support_q(address, port, "tcp", "tell");#endif    }#endif // PREF_TELL  return;}/*---------------------------------------------------------------------------- * Name server functions */// this is used by the internet communication front ends.  It return// flags representing whether a service is supported or not.int query_service_method(string mud, string service){  mud = htonn(mud);  // do we know about the mud  if (undefinedp(muds[mud]))    return SVC_UNKNOWN;  // if we have an entry, but no service entry, it is a static mud  if (undefinedp(mud_svc[mud]))    return SVC_TCP | SVC_NO_UDP | SVC_KNOWN;  // if we have an entry for the mud, do we know what the service is ?  if (undefinedp(mud_svc[mud][service]))    {      // if it is a standard service we try to find out      if(member_array(service, STD_SERVICE) != -1)	query_services(mud, muds[mud]["HOSTADDRESS"], muds[mud]["PORTUDP"],		       muds[mud]["TCP"]);      return SVC_UNKNOWN;    }  return mud_svc[mud][service];}mapping query_svc_entry(string mud){//	if (ACCESS_CHECK(previous_object()))	return mud_svc[mud];}string get_host_name(string name){  name = htonn(name);  if (name == mud_nname())    return this_host["HOSTADDRESS"];  if (undefinedp(muds[name]))    return 0;  return muds[name]["HOSTADDRESS"];}mapping query_mud_info(string name){	name = htonn(name);	if(name == mud_nname())		return this_host + ([ "TIME" : ctime(time()) ]);	return muds[name];}// this returns '1' if the mud is in the dns, or if it is usint dns_mudp(string name){	name = htonn( name );	return undefinedp(mud_svc[name]) ? (name == mud_nname() ? 1 : 0) : 1;}// returns all the muds in the databasesmapping query_muds(){//	if (ACCESS_CHECK(previous_object()))	return muds + ([ mud_nname():this_host + ([ "TIME":ctime(time()) ]) +		(["USERS":sprintf("%d",sizeof(users())) ])	]);}// returns the services mappingmapping query_svc(){//	if (ACCESS_CHECK(previous_object()))	return mud_svc;}// ----------------------------------------------------------------------------// service sequencing functions//// this is a potential security nightmare, be careful what euid the object// has when it calls the function// ----------------------------------------------------------------------------// register a function in the sequencervarargs int idx_request(function f){	if (file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH)		return 0;	seq_ctr++;	seq_entries[seq_ctr] = ({ geteuid(previous_object()), f, time() });	return seq_ctr;}// call a function in the sequencervoid idx_callback(int idx, mixed param){	mixed *entry;	if (!ACCESS_CHECK(previous_object())) return;  if (undefinedp(seq_entries[idx]))      return;  entry = seq_entries[idx];  map_delete(seq_entries, idx);  seteuid(entry[0]);  (*entry[1]) (param);  restore_euid();}// remove timed out entriesvoid sequence_clean_up(){  int i, now;  int *indexes;  if(find_call_out("sequence_clean_up") != -1)    return;  indexes = keys(seq_entries);  now = time();  i = sizeof(indexes);  while (i--)  if( now - seq_entries[indexes[i]][2] > SERVICE_TIMEOUT )      {	seteuid(seq_entries[indexes[i]][0]);	(*seq_entries[indexes[i]][1]) (0);	restore_euid();   map_delete( seq_entries, indexes[i] );      }  call_out("sequence_clean_up", SEQ_CLEAN_INTERVAL);}/*---------------------------------------------------------------------------- * general debugging stuff */#ifdef DEBUGmixed *query_bootsrv(){	return bootsrv;}void dump_sequencer(){	printf("counter: %d\n\n%O\n", seq_ctr, seq_entries);}void dump_svc(){	printf("%O\n", mud_svc);}void dump_mud_keys(){	printf("%O\n", keys(muds));}void dump_svc_keys(){	printf("%O\n", keys(mud_svc));}void set_monitor(object ob){	string euid;/*	euid = geteuid(previous_object());	if (!euid || !member_group(euid, "admin") && !member_group(euid, "socket"))		return;*/	monitor = ob;}objectquery_monitor(){  return monitor;}#endif // DEBUG/*---------------------------------------------------------------------------- * some misc functions */// Not really used yetprivate void restore_euid(){	seteuid(ROOT_UID);}// Logging functions// This one is for log entries from the auxiliariesvoidaux_log(string file, string entry){  if(!ACCESS_CHECK(previous_object()))    return;  restore_euid();  log_file(file, sprintf("%s: %s\n", ctime(time()), entry));}// This one is for warnings from the auxiliariesvoidaux_warning(string warning){  if(!ACCESS_CHECK(previous_object()))    return;  log("dns_warning: "+warning);}// This is for internal useprivate voidlog(string entry){  log_file(MY_LOG_FILE, sprintf("%s: %s\n", ctime(time()), entry));}// Used to find the ip number of the host we are onvoid resolve_callback(string address, string my_ip, int key){/*  if(previous_object()) return;*/	this_host["HOSTADDRESS"] = my_ip;}// ----------------------------------------------------------------------------// This starts us all off// ----------------------------------------------------------------------------void create(){	restore_euid();	set("channel_id", "网路精灵");	// find out which port we are on	my_port = SRVC_PORT_UDP(mud_port());	// initialise global mud info variables	muds = allocate_mapping(MUDS_ALLOC);	mud_svc = allocate_mapping(MUDS_ALLOC);	// initialise the sequencing variables	seq_ctr = 0;	seq_entries = ([]);	// set the bootserver default	bootsrv = MUDLIST_DNS;	bootsrv_retry = 0;	// tell the mudlist_a daemon that we have cleared the database	MUDLIST_A->clear_db_flag();	// set up our own info	this_host = ([		"MUDNAME"	: CHINESE_MUD_NAME,	// add by ken@XAJH 1997-10-18		"NAME"		: Mud_name(),		"ALIAS"		: Mud_name(),		"DRIVER"	: __VERSION__,		// add by ken@XAJH 1998-05-28		"MUDLIB"	: MUDLIB_NAME,		"VERSION"	: MUDLIB_VERSION,		"HOST"		: query_host_name(),		"HOSTADDRESS"	: 0,			// set in resolve_callback()		"PORT"		: "" + mud_port(),		"PORTUDP"	: "" + my_port,		"ADMIN"		: MUD_ADMIN,		"HTTP"		: MUD_WEB,		"ENCODING"	: MUDLIB_ENCODING,	// add by ken@XAJH 1998-05-28		"TIME"		: ctime(time()),		"TCP"		: TCP_SERVICE_LEVEL,		"USERS"		: sprintf("%d",sizeof(users())),	]);	resolve(query_host_name(), "resolve_callback");	// initialise the udp socket, if successful start the database system	if (startup_udp()) init_database();	CHANNEL_D->do_channel(this_object(), "sys", "MUD 互联核心 DNS_MASTER 已经启动。 \n");}void remove(){	send_shutdown();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?