/*
 * Document-method: getservbyname
 * call-seq: Socket.getservbyname(name, proto="tcp") => port
 *
 * +name+ is a service name ("ftp", "telnet", ...) and proto is a protocol name
 * ("udp", "tcp", ...). '/etc/services' (or your system's equivalent) is
 * searched for a service for +name+ and +proto+, and the port number is
 * returned.
 *
 * Note that unlike Socket.getaddrinfo, +proto+ may not be specified using the
 * Socket::SOCK_* constants, a string must must be used.
 */
static VALUE
sock_s_getservbyaname(argc, argv)
    int argc;
    VALUE *argv;
{
    VALUE service, proto;
    struct servent *sp;
    int port;

    rb_scan_args(argc, argv, "11", &service, &proto);
    if (NIL_P(proto)) proto = rb_str_new2("tcp");
    StringValue(service);
    StringValue(proto);

    sp = getservbyname(StringValueCStr(service),  StringValueCStr(proto));
    if (sp) {
        port = ntohs(sp->s_port);
    }
    else {
        char *s = RSTRING(service)->ptr;
        char *end;

        port = strtoul(s, &end, 0);
        if (*end != '\0') {
            rb_raise(rb_eSocket, "no such service %s/%s", s, RSTRING(proto)->ptr);
        }
    }
    return INT2FIX(port);
}