1 /************************************************
2 
3   constants.c -
4 
5   created at: Thu Mar 31 12:21:29 JST 1994
6 
7   Copyright (C) 1993-2007 Yukihiro Matsumoto
8 
9 ************************************************/
10 
11 #include "rubysocket.h"
12 
13 static VALUE rb_mSockConst;
14 
15 #include "constdefs.c"
16 
17 static int
constant_arg(VALUE arg,int (* str_to_int)(const char *,long,int *),const char * errmsg)18 constant_arg(VALUE arg, int (*str_to_int)(const char*, long, int*), const char *errmsg)
19 {
20     VALUE tmp;
21     char *ptr;
22     int ret;
23 
24     if (SYMBOL_P(arg)) {
25         arg = rb_sym2str(arg);
26         goto str;
27     }
28     else if (!NIL_P(tmp = rb_check_string_type(arg))) {
29 	arg = tmp;
30       str:
31 	rb_check_safe_obj(arg);
32         ptr = RSTRING_PTR(arg);
33         if (str_to_int(ptr, RSTRING_LEN(arg), &ret) == -1)
34 	    rb_raise(rb_eSocket, "%s: %s", errmsg, ptr);
35     }
36     else {
37 	ret = NUM2INT(arg);
38     }
39     return ret;
40 }
41 
42 int
rsock_family_arg(VALUE domain)43 rsock_family_arg(VALUE domain)
44 {
45     /* convert AF_INET, etc. */
46     return constant_arg(domain, rsock_family_to_int, "unknown socket domain");
47 }
48 
49 int
rsock_socktype_arg(VALUE type)50 rsock_socktype_arg(VALUE type)
51 {
52     /* convert SOCK_STREAM, etc. */
53     return constant_arg(type, rsock_socktype_to_int, "unknown socket type");
54 }
55 
56 int
rsock_level_arg(int family,VALUE level)57 rsock_level_arg(int family, VALUE level)
58 {
59     /* convert SOL_SOCKET, IPPROTO_TCP, etc. */
60     if (IS_IP_FAMILY(family)) {
61         return constant_arg(level, rsock_ip_level_to_int, "unknown protocol level");
62     }
63     else {
64         return constant_arg(level, rsock_unknown_level_to_int, "unknown protocol level");
65     }
66 }
67 
68 int
rsock_optname_arg(int family,int level,VALUE optname)69 rsock_optname_arg(int family, int level, VALUE optname)
70 {
71     if (IS_IP_FAMILY(family)) {
72         switch (level) {
73           case SOL_SOCKET:
74             return constant_arg(optname, rsock_so_optname_to_int, "unknown socket level option name");
75           case IPPROTO_IP:
76             return constant_arg(optname, rsock_ip_optname_to_int, "unknown IP level option name");
77 #ifdef IPPROTO_IPV6
78           case IPPROTO_IPV6:
79             return constant_arg(optname, rsock_ipv6_optname_to_int, "unknown IPv6 level option name");
80 #endif
81           case IPPROTO_TCP:
82             return constant_arg(optname, rsock_tcp_optname_to_int, "unknown TCP level option name");
83           case IPPROTO_UDP:
84             return constant_arg(optname, rsock_udp_optname_to_int, "unknown UDP level option name");
85           default:
86             return NUM2INT(optname);
87         }
88     }
89     else {
90         switch (level) {
91           case SOL_SOCKET:
92             return constant_arg(optname, rsock_so_optname_to_int, "unknown socket level option name");
93           default:
94             return NUM2INT(optname);
95         }
96     }
97 }
98 
99 int
rsock_cmsg_type_arg(int family,int level,VALUE type)100 rsock_cmsg_type_arg(int family, int level, VALUE type)
101 {
102     if (IS_IP_FAMILY(family)) {
103         switch (level) {
104           case SOL_SOCKET:
105             return constant_arg(type, rsock_scm_optname_to_int, "unknown UNIX control message");
106           case IPPROTO_IP:
107             return constant_arg(type, rsock_ip_optname_to_int, "unknown IP control message");
108 #ifdef IPPROTO_IPV6
109           case IPPROTO_IPV6:
110             return constant_arg(type, rsock_ipv6_optname_to_int, "unknown IPv6 control message");
111 #endif
112           case IPPROTO_TCP:
113             return constant_arg(type, rsock_tcp_optname_to_int, "unknown TCP control message");
114           case IPPROTO_UDP:
115             return constant_arg(type, rsock_udp_optname_to_int, "unknown UDP control message");
116           default:
117             return NUM2INT(type);
118         }
119     }
120     else {
121         switch (level) {
122           case SOL_SOCKET:
123             return constant_arg(type, rsock_scm_optname_to_int, "unknown UNIX control message");
124           default:
125             return NUM2INT(type);
126         }
127     }
128 }
129 
130 int
rsock_shutdown_how_arg(VALUE how)131 rsock_shutdown_how_arg(VALUE how)
132 {
133     /* convert SHUT_RD, SHUT_WR, SHUT_RDWR. */
134     return constant_arg(how, rsock_shutdown_how_to_int, "unknown shutdown argument");
135 }
136 
137 /*
138  * Socket::Constants module
139  */
140 void
rsock_init_socket_constants(void)141 rsock_init_socket_constants(void)
142 {
143     /* constants */
144     init_constants();
145 }
146