static int tls_scache_decode(TLS_SCACHE *cp, const char *cache_id, const char *hex_data, ssize_t hex_data_len, ACL_VSTRING *out_session) { const char *myname = "tls+scache_decode"; TLS_SCACHE_ENTRY *entry; ACL_VSTRING *bin_data; /* * Sanity check. */ if (hex_data_len < (ssize_t) (2 * (offsetof(TLS_SCACHE_ENTRY, session)))) { acl_msg_warn("%s: %s TLS cache: truncated entry for %s: %.100s", myname, cp->cache_label, cache_id, hex_data); return (0); } /* * Disassemble the TLS session cache entry. * * No early returns or we have a memory leak. */ #define FREE_AND_RETURN(ptr, x) { acl_vstring_free(ptr); return (x); } bin_data = acl_vstring_alloc(hex_data_len / 2 + 1); if (acl_hex_decode(bin_data, hex_data, hex_data_len) == 0) { acl_msg_warn("%s: %s TLS cache: malformed entry for %s: %.100s", myname, cp->cache_label, cache_id, hex_data); FREE_AND_RETURN(bin_data, 0); } entry = (TLS_SCACHE_ENTRY *) STR(bin_data); /* * Logging. */ if (cp->verbose) acl_msg_info("read %s TLS cache entry %s: time=%ld [data %ld bytes]", cp->cache_label, cache_id, (long) entry->timestamp, (long) (LEN(bin_data) - offsetof(TLS_SCACHE_ENTRY, session))); /* * Other mandatory restrictions. */ if (entry->timestamp + cp->timeout < time((time_t *) 0)) FREE_AND_RETURN(bin_data, 0); /* * Optional output. */ if (out_session != 0) acl_vstring_memcpy(out_session, entry->session, LEN(bin_data) - offsetof(TLS_SCACHE_ENTRY, session)); /* * Clean up. */ FREE_AND_RETURN(bin_data, 1); }
int main(int argc, char *argv[]) { int result = 0; ref_t val, answer, assoc, name; FILE *input_fl = stdin, *output_fl = stdout; clock_t start_time, end_time; #define FREE_AND_RETURN(x) {result = x; goto free_and_return;} if (parse_command_line(argc, argv, cmd_opt_decls) == -1) { printf("%s\n\n", get_error()); print_usage(); FREE_AND_RETURN(1); } if (help_flag) { print_usage(); FREE_AND_RETURN(0); } if (input_fname) { input_fl = fopen(input_fname, "r"); if (input_fl == 0) { printf("Could not open input file %s\n", input_fname); FREE_AND_RETURN(1); } } if (output_fname) { output_fl = fopen(output_fname, "w"); if (output_fl == 0) { printf("Could not open output file %s\n", output_fname); FREE_AND_RETURN(1); } } if (trace_file_fname) { trace_fl = fopen(trace_file_fname, "w"); if (trace_fl == 0) { printf("Could not open trace file %s\n", trace_file_fname); FREE_AND_RETURN(1); } } assoc = make_stack(nil()); register_gc_root(assoc); stack_enter(assoc); name = make_symbol("t", 0); stack_let(assoc, name, name); release_ref(&name); register_core_lib(assoc); REG_FN(exit, assoc); REG_FN(trace, assoc); REG_FN(profile, assoc); REG_NAMED_FN("no-trace", slfe_no_trace, assoc); REG_NAMED_FN("dump-stack", slfe_dump_stack, assoc); if (trace_fl) set_trace_file(trace_fl); start_time = clock(); finished = 0; while (! finished) { if (input_fl == stdin) printf("> "); val = read(input_fl); answer = eval(val, assoc); release_ref(&val); if (!quiet_flag) { println(answer, output_fl); fflush(output_fl); } release_ref(&answer); collect_garbage(); } stack_enter(nil()); unregister_gc_root(assoc); release_ref(&assoc); collect_garbage(); end_time = clock(); if (trace_fl) fprintf(trace_fl, "Total time taken: %f seconds\n", (float)(end_time - start_time) / (float)CLOCKS_PER_SEC); #undef FREE_AND_RETURN free_and_return: if (trace_fl && stats_flag) fprintf(trace_fl, "Total symbol evals: %d; total stack switches: %d\n", symbol_eval_count, stack_switch_count); if (input_fl != stdin) fclose(input_fl); if (output_fl != stdout) fclose(output_fl); if (trace_fl) fclose(trace_fl); if (input_fname) X_FREE(input_fname); if (output_fname) X_FREE(output_fname); if (trace_file_fname) X_FREE(trace_file_fname); return result; }