static SCM scm_resize_client(SCM client_smob, SCM width, SCM height) { client_t *client = (client_t *)SCM_SMOB_DATA(client_smob); client->rect.width = scm_to_uint16(width); client->rect.height = scm_to_uint16(height); update_client_geometry(client); return SCM_UNSPECIFIED; }
static SCM scm_bind_key(SCM mod_mask, SCM key, SCM proc) { xcb_keysym_t keysym; if (scm_is_true(scm_number_p(key))) keysym = scm_to_uint32(key); else if (scm_is_true(scm_string_p(key))) { scm_dynwind_begin(0); char *c_key = scm_to_locale_string(key); scm_dynwind_free(c_key); keysym = get_keysym(c_key); scm_dynwind_end(); } else return SCM_UNSPECIFIED; bind_key(scm_to_uint16(mod_mask), keysym, proc); return SCM_UNSPECIFIED; }
//get scm symbols: scm_from_utf8_symbol(name) SCM scm_connect_tls(SCM host, SCM port){ char hostbuf[256], portbuf[16]; //Assume the current locale is utf8, as the only function that lets //use use our own buffers implicitly uses the current locale if(!scm_is_string(host)){ scm_raise_error("wrong-type-arg", "expected string in position 1"); } else { size_t len = scm_to_locale_stringbuf(host, hostbuf, 256); if(len >= 256){ scm_raise_error("too-long", "hostname too long"); } else { hostbuf[len] = '\0'; } } if(scm_is_string(port)){ //make sure port looks like a number if(scm_is_false(scm_string_to_number(port, scm_from_int(10)))){ scm_raise_error("wrong-type-arg", "expected number or number as string in position 2"); } size_t len = scm_to_locale_stringbuf(port, portbuf, 32); if(len >= 16){ scm_raise_error("out-of-range", "Maximum port number is 65535"); } else { portbuf[len] = '\0'; } } else if(scm_is_integer(port)){ uint16_t portno = scm_to_uint16(port); snprintf(portbuf, 16, "%d", portno); } else { scm_raise_error("wrong-type-arg", "expected number or number as string in position 2"); } BIO *bio = connect_tls(hostbuf, portbuf); if(!bio){ scm_raise_error("system-error", "Failed to make tls connection"); } return scm_new_smob(tls_tag, (scm_t_bits)bio); }
static SCM guile_sock_local_address (SCM sock, SCM address) { svz_socket_t *xsock; uint16_t port; SCM pair; scm_assert_smob_type (guile_svz_socket_tag, sock); xsock = (svz_socket_t *) SCM_SMOB_DATA (sock); pair = scm_cons (scm_from_ulong (xsock->local_addr), scm_from_int ((int) xsock->local_port)); if (!SCM_UNBNDP (address)) { SCM_ASSERT (scm_is_pair (address) && scm_is_integer (SCM_CAR (address)) && scm_is_integer (SCM_CDR (address)), address, SCM_ARG2, FUNC_NAME); port = scm_to_uint16 (SCM_CDR (address)); xsock->local_addr = scm_to_ulong (SCM_CAR (address)); xsock->local_port = (unsigned short) port; } return pair; }
SCM guile_sock_connect (SCM host, SCM proto, SCM port) { svz_socket_t *sock; uint32_t xhost; uint16_t xport = 0; uint16_t p; int xproto; char *str; struct sockaddr_in addr; SCM ret = SCM_BOOL_F; SCM_ASSERT (scm_is_integer (host) || scm_is_string (host), host, SCM_ARG1, FUNC_NAME); SCM_ASSERT (scm_is_integer (proto), proto, SCM_ARG2, FUNC_NAME); /* Extract host to connect to. */ if (scm_is_integer (host)) xhost = htonl (scm_to_uint32 (host)); else { str = guile_to_string (host); if (svz_inet_aton (str, &addr) == -1) { if (guile_resolve (str, &xhost) == -1) { guile_error ("%s: IP in dotted decimals or hostname expected", FUNC_NAME); free (str); return ret; } } else xhost = addr.sin_addr.s_addr; free (str); } /* Extract protocol to use. */ xproto = scm_to_int (proto); /* Find out about given port. */ if (!SCM_UNBNDP (port)) { SCM_ASSERT (scm_is_integer (port), port, SCM_ARG3, FUNC_NAME); p = scm_to_uint16 (port); xport = htons (p); } /* Depending on the requested protocol; create different kinds of socket structures. */ switch (xproto) { case PROTO_TCP: sock = svz_tcp_connect (xhost, xport); break; case PROTO_UDP: sock = svz_udp_connect (xhost, xport); break; case PROTO_ICMP: sock = svz_icmp_connect (xhost, xport, ICMP_SERVEEZ); break; default: scm_out_of_range (FUNC_NAME, proto); } if (sock == NULL) return ret; sock->disconnected_socket = guile_func_disconnected_socket; SCM_RETURN_NEWSMOB (guile_svz_socket_tag, sock); }