ldmud/mudlib/dns_resolve.c
Zesstra ce457273a0 Replace strlen by sizeof in mudlib.
In preparation of the planned removal of the efun strlen(), which is
replaced by sizeof(), occurences of strlen() were renamed in the mudlib/
directory. (Thanks to Abathur.)
2014-04-24 22:30:58 +02:00

112 lines
3.1 KiB
C

void
dns_resolve (string hostname, closure callback)
// Try to lookup the IP for the fully qualified <hostname> using direct ERQ
// communication. Once the name is resolved, call callback() with the
// resolved name as parameter.
//
// Note: If the ERQ is unavailable, callback() is called with the original
// hostname.
//
// preferably to be installed as "simul efun." latest version available
// in world/net/library.i of psycMUVE (download from http://muve.pages.de)
// this version runs with broken and fixed erq's alike.
//
// Written by Tobias@Heldensaga and Arne@Elridion.
{
closure c;
if (sscanf(hostname,"%~D.%~D.%~D.%~D") == 4) {
// hostname is an IP already. Just call the callback.
funcall(callback, hostname);
return;
}
c = lambda( ({ 'name }), ({
(#'switch), ({ #'sizeof, 'name }),
({ 4 }), // ERQ: name resolved!
({ (#',),
({ (#'=),'name,({ (#'map),'name,#'&,255 }) }),
({ (#'=),'name,
({
(#'sprintf),"%d.%d.%d.%d",
({ #'[, 'name, 0 }),
({ #'[, 'name, 1 }),
({ #'[, 'name, 2 }),
({ #'[, 'name, 3 })
})
}),
({ (#'funcall), callback, 'name })
}),
(#'break),
({ 6 + sizeof(hostname) }), // XERQ
({ (#',),
({ (#'=),'name,({ (#'map),'name,#'&,255 }) }),
({ (#'=),'name,
({
(#'sprintf),"%d.%d.%d.%d",
({ #'[, 'name, 1
}),
({ #'[, 'name, 2
}),
({ #'[, 'name, 3
}),
({ #'[, 'name, 4 })
})
}),
({ (#'funcall), callback, 'name })
}),
(#'break),
({ #'default }),
({
#'debug_message, "FATAL: ERQ could not resolve \""
+ hostname + "\". The callback will not be called.\n"
}),
(#'break)
})
);
#ifdef THEDAYWEARESURENOONERUNSABUGGYERQ
if (!send_erq(ERQ_LOOKUP, hostname, c))
#else
// appending the zero byte fixes a bug in erq. sick!
if (!send_erq(ERQ_LOOKUP, to_array(hostname) + ({ 0 }), c))
#endif
{
// 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(callback, hostname);
}
}
#if 0
/*------------------------------------------------------------------------*/
// typical usage example taken from PSYCmuve world/net/irc/gatebot.c
// this ensures a non-blocking connect to a remote service even by name.
//
connect(host, port) {
unless (host) host = IRCNET_HOST;
unless (port) port = IRCNET_PORT;
D2( D("IRCgate resolving hostname "+ host +"\n"); )
dns_resolve(host, lambda(({ 'result }),
({ #'connect2, 'result, port })));
}
connect2(host, port) {
#if __EFUN_DEFINED__(net_connect)
int res;
D0( D(S("IRCgate attempting connect to %O:%O\n", host, port)); )
res = net_connect(host, port);
if (res) monitor_report("_failure_network_connect_call",
"ircbot: connect to "+host+" returns "+ res);
return res;
#else
D2( D("IRCgate * Oh, driver does not provide net_connect()\n"); )
return -9;
#endif
}
#endif /* EXAMPLE */