1 /* "socket.c" internet socket support for client/server in SCM
2 Copyright (C) 1994 Aubrey Jaffer.
3 Thanks to Hallvard.Tretteberg@si.sintef.no
4 who credits NCSA httpd software by Rob McCool 3/21/93.
5 Rewritten by Gary Houston to be a closer interface to the C
13 #include <sys/types.h>
14 #include <sys/socket.h>
16 #include <netinet/in.h>
18 #include <arpa/inet.h>
23 int close
P ((int fd
));
24 #endif /* STDC_HEADERS */
26 SCM_PROC (s_sys_inet_aton
, "%inet-aton", 1, 0, 0, scm_sys_inet_aton
);
29 scm_sys_inet_aton (SCM address
)
32 scm_sys_inet_aton (address
)
38 SCM_ASSERT (SCM_NIMP (address
) && SCM_ROSTRINGP (address
), address
, SCM_ARG1
, s_sys_inet_aton
);
39 if (SCM_SUBSTRP (address
))
40 address
= scm_makfromstr (SCM_ROCHARS (address
), SCM_ROLENGTH (address
), 0);
41 rv
= inet_aton (SCM_ROCHARS (address
), &soka
);
42 return rv
? scm_ulong2num (ntohl (soka
.s_addr
)) : SCM_BOOL_F
;
46 SCM_PROC (s_inet_ntoa
, "inet-ntoa", 1, 0, 0, scm_inet_ntoa
);
49 scm_inet_ntoa (SCM inetid
)
52 scm_inet_ntoa (inetid
)
59 addr
.s_addr
= htonl (scm_num2ulong (inetid
, (char *) SCM_ARG1
, s_inet_ntoa
));
62 answer
= scm_makfromstr (s
, strlen (s
), 0);
67 SCM_PROC (s_inet_netof
, "inet-netof", 1, 0, 0, scm_inet_netof
);
70 scm_inet_netof (SCM address
)
73 scm_inet_netof (address
)
78 addr
.s_addr
= htonl (scm_num2ulong (address
, (char *) SCM_ARG1
, s_inet_netof
));
79 return scm_ulong2num ((unsigned long) inet_netof (addr
));
82 SCM_PROC (s_lnaof
, "lnaof", 1, 0, 0, scm_lnaof
);
85 scm_lnaof (SCM address
)
93 addr
.s_addr
= htonl (scm_num2ulong (address
, (char *) SCM_ARG1
, s_lnaof
));
94 return scm_ulong2num ((unsigned long) inet_lnaof (addr
));
98 SCM_PROC (s_inet_makeaddr
, "inet-makeaddr", 2, 0, 0, scm_inet_makeaddr
);
101 scm_inet_makeaddr (SCM net
, SCM lna
)
104 scm_inet_makeaddr (net
, lna
)
110 unsigned long netnum
;
111 unsigned long lnanum
;
113 netnum
= scm_num2ulong (net
, (char *) SCM_ARG1
, s_inet_makeaddr
);
114 lnanum
= scm_num2ulong (lna
, (char *) SCM_ARG2
, s_inet_makeaddr
);
115 addr
= inet_makeaddr (netnum
, lnanum
);
116 return scm_ulong2num (ntohl (addr
.s_addr
));
120 /* !!! Doesn't take address format.
121 * Assumes hostent stream isn't reused.
124 SCM_PROC (s_sys_gethost
, "%gethost", 0, 1, 0, scm_sys_gethost
);
127 scm_sys_gethost (SCM name
)
130 scm_sys_gethost (name
)
134 SCM ans
= scm_make_vector (SCM_MAKINUM (5), SCM_UNSPECIFIED
, SCM_BOOL_F
);
135 SCM
*ve
= SCM_VELTS (ans
);
137 struct hostent
*entry
;
141 #ifdef HAVE_GETHOSTENT
142 if (SCM_UNBNDP (name
))
145 entry
= gethostent ();
149 if (SCM_NIMP (name
) && SCM_STRINGP (name
))
152 entry
= gethostbyname (SCM_CHARS (name
));
156 inad
.s_addr
= htonl (scm_num2ulong (name
, (char *) SCM_ARG1
, s_sys_gethost
));
158 entry
= gethostbyaddr ((char *) &inad
, sizeof (inad
), AF_INET
);
163 ve
[0] = scm_makfromstr (entry
->h_name
, (scm_sizet
) strlen (entry
->h_name
), 0);
164 ve
[1] = scm_makfromstrs (-1, entry
->h_aliases
);
165 ve
[2] = SCM_MAKINUM (entry
->h_addrtype
+ 0L);
166 ve
[3] = SCM_MAKINUM (entry
->h_length
+ 0L);
167 if (sizeof (struct in_addr
) != entry
->h_length
)
172 for (argv
= entry
->h_addr_list
; argv
[i
]; i
++);
175 inad
= *(struct in_addr
*) argv
[i
];
176 lst
= scm_cons (scm_ulong2num (ntohl (inad
.s_addr
)), lst
);
183 SCM_PROC (s_sys_getnet
, "%getnet", 0, 1, 0, scm_sys_getnet
);
186 scm_sys_getnet (SCM name
)
189 scm_sys_getnet (name
)
195 struct netent
*entry
;
197 ans
= scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED
, SCM_BOOL_F
);
198 ve
= SCM_VELTS (ans
);
199 if (SCM_UNBNDP (name
))
202 entry
= getnetent ();
204 else if (SCM_NIMP (name
) && SCM_STRINGP (name
))
207 entry
= getnetbyname (SCM_CHARS (name
));
211 unsigned long netnum
;
212 netnum
= scm_num2ulong (name
, (char *) SCM_ARG1
, s_sys_getnet
);
214 entry
= getnetbyaddr (netnum
, AF_INET
);
219 ve
[0] = scm_makfromstr (entry
->n_name
, (scm_sizet
) strlen (entry
->n_name
), 0);
220 ve
[1] = scm_makfromstrs (-1, entry
->n_aliases
);
221 ve
[2] = SCM_MAKINUM (entry
->n_addrtype
+ 0L);
222 ve
[3] = scm_ulong2num (entry
->n_net
+ 0L);
226 SCM_PROC (s_sys_getproto
, "%getproto", 0, 1, 0, scm_sys_getproto
);
229 scm_sys_getproto (SCM name
)
232 scm_sys_getproto (name
)
238 struct protoent
*entry
;
240 ans
= scm_make_vector (SCM_MAKINUM (3), SCM_UNSPECIFIED
, SCM_BOOL_F
);
241 ve
= SCM_VELTS (ans
);
242 if (SCM_UNBNDP (name
))
245 entry
= getprotoent ();
247 else if (SCM_NIMP (name
) && SCM_STRINGP (name
))
250 entry
= getprotobyname (SCM_CHARS (name
));
254 unsigned long protonum
;
255 protonum
= scm_num2ulong (name
, (char *) SCM_ARG1
, s_sys_getproto
);
257 entry
= getprotobynumber (protonum
);
262 ve
[0] = scm_makfromstr (entry
->p_name
, (scm_sizet
) strlen (entry
->p_name
), 0);
263 ve
[1] = scm_makfromstrs (-1, entry
->p_aliases
);
264 ve
[2] = SCM_MAKINUM (entry
->p_proto
+ 0L);
270 scm_return_entry (struct servent
*entry
)
273 scm_return_entry (entry
)
274 struct servent
*entry
;
280 ans
= scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED
, SCM_BOOL_F
);
281 ve
= SCM_VELTS (ans
);
287 ve
[0] = scm_makfromstr (entry
->s_name
, (scm_sizet
) strlen (entry
->s_name
), 0);
288 ve
[1] = scm_makfromstrs (-1, entry
->s_aliases
);
289 ve
[2] = SCM_MAKINUM (ntohs (entry
->s_port
) + 0L);
290 ve
[3] = scm_makfromstr (entry
->s_proto
, (scm_sizet
) strlen (entry
->s_proto
), 0);
295 SCM_PROC (s_sys_getserv
, "%getserv", 0, 2, 0, scm_sys_getserv
);
298 scm_sys_getserv (SCM name
, SCM proto
)
301 scm_sys_getserv (name
, proto
)
306 struct servent
*entry
;
307 if (SCM_UNBNDP (name
))
310 entry
= getservent ();
311 return scm_return_entry (entry
);
313 SCM_ASSERT (SCM_NIMP (proto
) && SCM_STRINGP (proto
), proto
, SCM_ARG2
, s_sys_getserv
);
314 if (SCM_NIMP (name
) && SCM_STRINGP (name
))
317 entry
= getservbyname (SCM_CHARS (name
), SCM_CHARS (proto
));
321 SCM_ASSERT (SCM_INUMP (name
), name
, SCM_ARG1
, s_sys_getserv
);
323 entry
= getservbyport (SCM_INUM (name
), SCM_CHARS (proto
));
325 return scm_return_entry (entry
);
328 SCM_PROC (s_sethost
, "sethost", 0, 1, 0, scm_sethost
);
331 scm_sethost (SCM arg
)
338 if (SCM_UNBNDP (arg
))
341 sethostent (SCM_NFALSEP (arg
));
342 return SCM_UNSPECIFIED
;
345 SCM_PROC (s_setnet
, "setnet", 0, 1, 0, scm_setnet
);
355 if (SCM_UNBNDP (arg
))
358 setnetent (SCM_NFALSEP (arg
));
359 return SCM_UNSPECIFIED
;
362 SCM_PROC (s_setproto
, "setproto", 0, 1, 0, scm_setproto
);
365 scm_setproto (SCM arg
)
372 if (SCM_UNBNDP (arg
))
375 setprotoent (SCM_NFALSEP (arg
));
376 return SCM_UNSPECIFIED
;
379 SCM_PROC (s_setserv
, "setserv", 0, 1, 0, scm_setserv
);
382 scm_setserv (SCM arg
)
389 if (SCM_UNBNDP (arg
))
392 setservent (SCM_NFALSEP (arg
));
393 return SCM_UNSPECIFIED
;
398 scm_init_socket (void)
404 scm_add_feature ("socket");