NOEXPORT int socket_options_print(void) {
    SOCK_OPT *opt, *ptr;
    SOCKET fd;
    socklen_t optlen;
    OPT_UNION val;
    char *ta, *tl, *tr, *td;

    fd=socket(AF_INET, SOCK_STREAM, 0);
    opt=socket_options_init();

    s_log(LOG_NOTICE, " ");
    s_log(LOG_NOTICE, "Socket option defaults:");
    s_log(LOG_NOTICE,
        "    Option Name         |  Accept  |   Local  |  Remote  |OS default");
    s_log(LOG_NOTICE,
        "    --------------------+----------+----------+----------+----------");
    for(ptr=opt; ptr->opt_str; ++ptr) {
        /* get OS default value */
        optlen=sizeof val;
        if(getsockopt(fd, ptr->opt_level,
                ptr->opt_name, (void *)&val, &optlen)) {
            switch(get_last_socket_error()) {
            case S_ENOPROTOOPT:
            case S_EOPNOTSUPP:
                td=str_dup("write-only");
                break;
            default:
                s_log(LOG_ERR, "Failed to get %s OS default", ptr->opt_str);
                sockerror("getsockopt");
                closesocket(fd);
                return 1; /* FAILED */
            }
        } else
            td=socket_option_text(ptr->opt_type, &val);
        /* get stunnel default values */
        ta=socket_option_text(ptr->opt_type, ptr->opt_val[0]);
        tl=socket_option_text(ptr->opt_type, ptr->opt_val[1]);
        tr=socket_option_text(ptr->opt_type, ptr->opt_val[2]);
        /* print collected data and fee the memory */
        s_log(LOG_NOTICE, "    %-20s|%10s|%10s|%10s|%10s",
            ptr->opt_str, ta, tl, tr, td);
        str_free(ta); str_free(tl); str_free(tr); str_free(td);
    }
    socket_options_free(opt);
    closesocket(fd);
    return 0; /* OK */
}
NOEXPORT int socket_options_print(void) {
    SOCK_OPT *opt, *ptr;
    SOCKET fd;
    socklen_t optlen;
    OPT_UNION val;
    char *ta, *tl, *tr, *td;

    fd=socket(AF_INET, SOCK_STREAM, 0);
    opt=socket_options_init();

    s_log(LOG_NOTICE, " ");
    s_log(LOG_NOTICE, "Socket option defaults:");
    s_log(LOG_NOTICE,
        "    Option Name         |  Accept  |   Local  |  Remote  |OS default");
    s_log(LOG_NOTICE,
        "    --------------------+----------+----------+----------+----------");
    for(ptr=opt; ptr->opt_str; ++ptr) {
         
        optlen=sizeof val;
        if(getsockopt(fd, ptr->opt_level,
                ptr->opt_name, (void *)&val, &optlen)) {
            switch(get_last_socket_error()) {
            case S_ENOPROTOOPT:
            case S_EOPNOTSUPP:
                td=str_dup("write-only");
                break;
            default:
                s_log(LOG_ERR, "Failed to get %s OS default", ptr->opt_str);
                sockerror("getsockopt");
                closesocket(fd);
                return 1;  
            }
        } else
            td=socket_option_text(ptr->opt_type, &val);
         
        ta=socket_option_text(ptr->opt_type, ptr->opt_val[0]);
        tl=socket_option_text(ptr->opt_type, ptr->opt_val[1]);
        tr=socket_option_text(ptr->opt_type, ptr->opt_val[2]);
         
        s_log(LOG_NOTICE, "    %-20s|%10s|%10s|%10s|%10s",
            ptr->opt_str, ta, tl, tr, td);
        str_free(ta); str_free(tl); str_free(tr); str_free(td);
    }
    socket_options_free(opt);
    closesocket(fd);
    return 0;  
}