static value dgst_sign(value data, value key, value alg){ const mbedtls_md_info_t *md; int r = -1; size_t olen = 0; value out; unsigned char *buf; unsigned char hash[32]; val_check(data, string); val_check_kind(key, k_pkey); val_check(alg, string); md = mbedtls_md_info_from_string(val_string(alg)); if( md == NULL ){ val_throw(alloc_string("Invalid hash algorithm")); return val_null; } if( (r = mbedtls_md( md, (const unsigned char *)val_string(data), val_strlen(data), hash )) != 0 ) return ssl_error(r); out = alloc_empty_string(MBEDTLS_MPI_MAX_SIZE); buf = (unsigned char *)val_string(out); if( (r = mbedtls_pk_sign( val_pkey(key), mbedtls_md_get_type(md), hash, 0, buf, &olen, mbedtls_ctr_drbg_random, &ctr_drbg )) != 0 ) return ssl_error(r); buf[olen] = 0; val_set_size(out, olen); return out; }
static value make_array_result( value a, fd_set *tmp ) { value r; int i, len; int pos = 0; if( tmp == NULL ) return val_null; len = val_array_size(a); r = alloc_array(len); for(i=0;i<len;i++) { value s = val_array_ptr(a)[i]; if( FD_ISSET(val_sock(s),tmp) ) val_array_ptr(r)[pos++] = s; } val_set_size(r,pos); return r; }
static value url_decode( const char *in, int len ) { int pin = 0; int pout = 0; value v = alloc_empty_string(len); char *out = (char*)val_string(v); while( len-- > 0 ) { char c = in[pin++]; if( c == '+' ) c = ' '; else if( c == '%' ) { int p1, p2; if( len < 2 ) break; p1 = in[pin++]; p2 = in[pin++]; len -= 2; if( p1 >= '0' && p1 <= '9' ) p1 -= '0'; else if( p1 >= 'a' && p1 <= 'f' ) p1 -= 'a' - 10; else if( p1 >= 'A' && p1 <= 'F' ) p1 -= 'A' - 10; else continue; if( p2 >= '0' && p2 <= '9' ) p2 -= '0'; else if( p2 >= 'a' && p2 <= 'f' ) p2 -= 'a' - 10; else if( p2 >= 'A' && p2 <= 'F' ) p2 -= 'A' - 10; else continue; c = (char)((unsigned char)((p1 << 4) + p2)); } out[pout++] = c; } out[pout] = 0; val_set_size(v,pout); return v; }
/** socket_epoll_wait : 'epoll -> int -> float -> int array <doc>Wait and return a list of socket fds with events.</doc> **/ static value socket_epoll_wait(value e, value timeout) { epolldata *ep; #ifndef HAS_EPOLL struct timeval t; SOCKET n = 0; bool indefinite; fd_set rx, wx; fd_set *ra, *wa; int i; int pos = 0; val_check_kind(e,k_epoll); ep = val_epoll(e); POSIX_LABEL(select_again); ra = ep->rcount == 0 ? NULL : make_socket_array(ep->read, ep->rcount, &rx, &n); wa = ep->wcount == 0 ? NULL : make_socket_array(ep->write, ep->wcount, &wx, &n); indefinite = val_is_null(timeout); if (!indefinite) { val_check(timeout,number); init_timeval(val_number(timeout),&t); } if( select((int)(n+1),ra,wa,NULL,indefinite ? NULL : &t) == SOCKET_ERROR ) { HANDLE_EINTR(select_again); val_throw(alloc_int(errno)); } if (ra != NULL) { for (i=0; i < ep->rcount && pos < ep->maxevents; i++) { value s = val_array_ptr(ep->read)[i]; if (FD_ISSET(val_sock(s),ra)) val_array_ptr(ep->result)[pos++] = alloc_int(val_sock(s)); } } if (wa != NULL) { for (i=0; i < ep->wcount && pos < ep->maxevents; i++) { value s = val_array_ptr(ep->write)[i]; if (FD_ISSET(val_sock(s),wa)) val_array_ptr(ep->result)[pos++] = alloc_int(val_sock(s)); } } val_set_size(ep->result,pos); return ep->result; #else int t; val_check_kind(e,k_epoll); ep = val_epoll(e); if (val_is_null(timeout)) t = -1; else { val_check(timeout,number); t = (int)(val_number(timeout)) * 1000; } int ret = epoll_wait(ep->epollfd, ep->events, ep->maxevents, t); if (ret == -1) val_throw(alloc_int(errno)); val_set_size(ep->result, ret); int i; for (i = 0; i < ret; i++) { val_array_ptr(ep->result)[i] = alloc_int(ep->events[i].data.fd); } return ep->result; #endif }