static int process_hashpw(ETERM *pid, ETERM *data) { int retval = 0; ETERM *pattern, *pwd, *slt; char *password, *salt; char *ret = NULL; pattern = erl_format("{Pass, Salt}"); if (erl_match(pattern, data)) { pwd = erl_var_content(pattern, "Pass"); password = erl_iolist_to_string(pwd); slt = erl_var_content(pattern, "Salt"); salt = erl_iolist_to_string(slt); if (NULL == (ret = bcrypt(password, salt)) || 0 == strcmp(ret, ":")) { retval = process_reply(pid, CMD_HASHPW, "Invalid salt"); } else { retval = process_reply(pid, CMD_HASHPW, ret); } erl_free_term(pwd); erl_free_term(slt); erl_free(password); erl_free(salt); }; erl_free_term(pattern); return retval; }
static int process_auth(ETERM *pid, ETERM *data) { int retval = 0; ETERM *pattern, *srv, *user, *pass; char *service, *username, *password; pattern = erl_format("{Srv, User, Pass}"); if (erl_match(pattern, data)) { srv = erl_var_content(pattern, "Srv"); service = erl_iolist_to_string(srv); user = erl_var_content(pattern, "User"); username = erl_iolist_to_string(user); pass = erl_var_content(pattern, "Pass"); password = erl_iolist_to_string(pass); retval = process_reply(pid, CMD_AUTH, auth(service, username, password)); erl_free_term(srv); erl_free_term(user); erl_free_term(pass); erl_free(service); erl_free(username); erl_free(password); }; erl_free_term(pattern); return retval; }
int bind_string(MYSQL_BIND *bind, const ETERM *erl_value, unsigned long len) { char *val; unsigned long slen; val = erl_iolist_to_string(erl_value); if (!val) { logmsg("ERROR: bind_string val is NULL"); return -1; } slen = strlen(val); bind->buffer_type = MYSQL_TYPE_BLOB; bind->buffer_length = len; bind->length = safe_malloc(sizeof(unsigned long)); memcpy(bind->length, &slen, sizeof(unsigned long)); bind->buffer = safe_malloc((slen + 1) * sizeof(char)); memcpy(bind->buffer, val, slen); free(val); return 0; }
void handle_connect(ETERM *msg) { ETERM *resp, *tmp; char *host, *db_name, *user, *passwd; int port; tmp = erl_element(2, msg); host = erl_iolist_to_string(tmp); erl_free_term(tmp); tmp = erl_element(3, msg); port = ERL_INT_VALUE(tmp); erl_free_term(tmp); tmp = erl_element(4, msg); db_name = erl_iolist_to_string(tmp); erl_free_term(tmp); tmp = erl_element(5, msg); user = erl_iolist_to_string(tmp); erl_free_term(tmp); tmp = erl_element(6, msg); passwd = erl_iolist_to_string(tmp); erl_free_term(tmp); /* TODO: handle options, passed in next. */ logmsg("INFO: Connecting to %s on %s:%d as %s", db_name, host, port, user); if (mysql_real_connect(&dbh, host, user, passwd, db_name, port, NULL, 0) == NULL) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_errno(&dbh), mysql_error(&dbh)); write_msg(resp); erl_free_term(resp); exit(2); } resp = erl_format("ok"); write_msg(resp); erl_free_term(resp); }
static int process_acct(ETERM *pid, ETERM *data) { int retval = 0; ETERM *pattern, *srv, *user; char *service, *username; pattern = erl_format("{Srv, User}"); if (erl_match(pattern, data)) { srv = erl_var_content(pattern, "Srv"); service = erl_iolist_to_string(srv); user = erl_var_content(pattern, "User"); username = erl_iolist_to_string(user); retval = process_reply(pid, CMD_ACCT, acct_mgmt(service, username)); erl_free_term(srv); erl_free_term(user); erl_free(service); erl_free(username); } erl_free_term(pattern); return retval; }
void handle_query(ETERM *cmd) { ETERM *query, *resp; MYSQL_STMT *handle; char *q; query = erl_element(2, cmd); q = erl_iolist_to_string(query); erl_free_term(query); logmsg("INFO: got query: %s", q); handle = mysql_stmt_init(&dbh); if (mysql_stmt_prepare(handle, q, strlen(q))) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } else if (mysql_stmt_execute(handle)) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } else { set_mysql_results(handle); if (results) { resp = handle_mysql_result(); } else { if (mysql_stmt_field_count(handle) == 0) { resp = erl_format("{updated, ~i}", numrows); } else { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } } } erl_free(q); mysql_stmt_close(handle); write_msg(resp); erl_free_term(resp); }
void handle_select_count(ETERM *msg) { ETERM *query, *resp; MYSQL_STMT *handle; char *q; query = erl_element(2, msg); q = erl_iolist_to_string(query); erl_free_term(query); logmsg("INFO: Got select count for: %s", q); handle = mysql_stmt_init(&dbh); if (mysql_stmt_prepare(handle, q, strlen(q))) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } else if (mysql_stmt_execute(handle)) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } else { set_mysql_results(handle); if (results) { resp = erl_format("{ok, ~i}", mysql_stmt_affected_rows(handle)); } else if (mysql_stmt_field_count(handle) == 0) { resp = erl_format("{ok, ~i}", mysql_stmt_affected_rows(handle)); } else { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } } erl_free(q); write_msg(resp); erl_free_term(resp); }
int main(int argc, char **argv) { ETERM *tuplep; ETERM *fnp, *argp; byte buf[1024]; sqlite3 *db; char *zErrMsg = 0; int rc; log = fopen("/tmp/sqlite_port.log", "a+"); fprintf(log, "******start log (%s)******\n", argv[1]); fflush(log); rc = sqlite3_open(argv[1], &db); if (rc) { sqlite3_close(db); exit(1); } erl_init(NULL, 0); while (read_cmd(buf) > 0) { tuplep = erl_decode(buf); fnp = erl_element(1, tuplep); argp = erl_element(2, tuplep); if (strncmp((const char *)ERL_ATOM_PTR(fnp), "close", 5) == 0) { fprintf(log, "closing sqlite3_close\n"); fflush(log); sqlite3_close(db); break; } else if (strncmp((const char *)ERL_ATOM_PTR(fnp), "list_tables", 11) == 0) { fprintf(log, "calling list_tables\n"); result = 0; rc = sqlite3_exec(db, MASTER_QUERY, list_tables, 0, &zErrMsg); if (rc != SQLITE_OK) { send_error(zErrMsg); sqlite3_free(zErrMsg); } else if (result != 0) { send_result(); } else { // not an error and no results. still need to return something send_ok(); } fflush(log); } else if (strncmp((const char *)ERL_ATOM_PTR(fnp), "sql_exec", 8) == 0) { fprintf(log, "calling sqlite3_exec %s\n", erl_iolist_to_string(argp)); result = 0; rc = sqlite3_exec(db, erl_iolist_to_string(argp), callback, 0, &zErrMsg); if (rc != SQLITE_OK) { send_error(zErrMsg); sqlite3_free(zErrMsg); } else if (result != 0) { send_result(); } else { // not an error and no results. still need to return something send_ok(); } fflush(log); } erl_free_compound(tuplep); erl_free_term(fnp); erl_free_term(argp); } fprintf(log, "******end log******\n"); fclose(log); return 0; }
int main(void) #endif { ei_x_buff eix; int index = 0; ETERM **etermpp = NULL, *etermp = NULL; char *charp = NULL; unsigned char uchar, **ucharpp = NULL, *ucharp = NULL; void *voidp = NULL; Erl_Heap *erl_heapp = NULL; int intx = 0; int *intp = NULL; unsigned int uintx, *uintp; unsigned long *ulongp = NULL; long longx = 0; double doublex = 0.0; short shortx = 42; FILE *filep = NULL; Erl_IpAddr erl_ipaddr = NULL; ErlMessage *erlmessagep = NULL; ErlConnect *erlconnectp = NULL; struct hostent *hostp = NULL; struct in_addr *inaddrp = NULL; /* Converion to erl_interface format is in liberl_interface */ intx = erl_errno; ei_encode_term(charp, &index, voidp); ei_x_encode_term(&eix, voidp); ei_decode_term(charp, &index, voidp); erl_init(voidp, longx); erl_connect_init(intx, charp,shortx); erl_connect_xinit(charp,charp,charp,erl_ipaddr,charp,shortx); erl_connect(charp); erl_xconnect(erl_ipaddr,charp); erl_close_connection(intx); erl_receive(intx, ucharp, intx); erl_receive_msg(intx, ucharp, intx, erlmessagep); erl_xreceive_msg(intx, ucharpp, intp, erlmessagep); erl_send(intx, etermp, etermp); erl_reg_send(intx, charp, etermp); erl_rpc(intx,charp,charp,etermp); erl_rpc_to(intx,charp,charp,etermp); erl_rpc_from(intx,intx,erlmessagep); erl_publish(intx); erl_accept(intx,erlconnectp); erl_thiscookie(); erl_thisnodename(); erl_thishostname(); erl_thisalivename(); erl_thiscreation(); erl_unpublish(charp); erl_err_msg(charp); erl_err_quit(charp); erl_err_ret(charp); erl_err_sys(charp); erl_cons(etermp,etermp); erl_copy_term(etermp); erl_element(intx,etermp); erl_hd(etermp); erl_iolist_to_binary(etermp); erl_iolist_to_string(etermp); erl_iolist_length(etermp); erl_length(etermp); erl_mk_atom(charp); erl_mk_binary(charp,intx); erl_mk_empty_list(); erl_mk_estring(charp, intx); erl_mk_float(doublex); erl_mk_int(intx); erl_mk_list(etermpp,intx); erl_mk_pid(charp,uintx,uintx,uchar); erl_mk_port(charp,uintx,uchar); erl_mk_ref(charp,uintx,uchar); erl_mk_long_ref(charp,uintx,uintx,uintx,uchar); erl_mk_string(charp); erl_mk_tuple(etermpp,intx); erl_mk_uint(uintx); erl_mk_var(charp); erl_print_term(filep,etermp); /* erl_sprint_term(charp,etermp); */ erl_size(etermp); erl_tl(etermp); erl_var_content(etermp, charp); erl_format(charp); erl_match(etermp, etermp); erl_global_names(intx, intp); erl_global_register(intx, charp, etermp); erl_global_unregister(intx, charp); erl_global_whereis(intx, charp, charp); erl_init_malloc(erl_heapp,longx); erl_alloc_eterm(uchar); erl_eterm_release(); erl_eterm_statistics(ulongp,ulongp); erl_free_array(etermpp,intx); erl_free_term(etermp); erl_free_compound(etermp); erl_malloc(longx); erl_free(voidp); erl_compare_ext(ucharp, ucharp); erl_decode(ucharp); erl_decode_buf(ucharpp); erl_encode(etermp,ucharp); erl_encode_buf(etermp,ucharpp); erl_ext_size(ucharp); erl_ext_type(ucharp); erl_peek_ext(ucharp,intx); erl_term_len(etermp); erl_gethostbyname(charp); erl_gethostbyaddr(charp, intx, intx); erl_gethostbyname_r(charp, hostp, charp, intx, intp); erl_gethostbyaddr_r(charp, intx, intx, hostp, charp, intx, intp); erl_init_resolve(); erl_distversion(intx); erl_epmd_connect(inaddrp); erl_epmd_port(inaddrp, charp, intp); charp = ERL_ATOM_PTR(etermp); intx = ERL_ATOM_SIZE(etermp); ucharp = ERL_BIN_PTR(etermp); intx = ERL_BIN_SIZE(etermp); etermp = ERL_CONS_HEAD(etermp); etermp = ERL_CONS_TAIL(etermp); intx = ERL_COUNT(etermp); doublex= ERL_FLOAT_VALUE(etermp); uintx = ERL_INT_UVALUE(etermp); intx = ERL_INT_VALUE(etermp); intx = ERL_IS_ATOM(etermp); intx = ERL_IS_BINARY(etermp); intx = ERL_IS_CONS(etermp); intx = ERL_IS_EMPTY_LIST(etermp); intx = ERL_IS_FLOAT(etermp); intx = ERL_IS_INTEGER(etermp); intx = ERL_IS_LIST(etermp); intx = ERL_IS_PID(etermp); intx = ERL_IS_PORT(etermp); intx = ERL_IS_REF(etermp); intx = ERL_IS_TUPLE(etermp); intx = ERL_IS_UNSIGNED_INTEGER(etermp); uchar = ERL_PID_CREATION(etermp); charp = ERL_PID_NODE(etermp); uintx = ERL_PID_NUMBER(etermp); uintx = ERL_PID_SERIAL(etermp); uchar = ERL_PORT_CREATION(etermp); charp = ERL_PORT_NODE(etermp); uintx = ERL_PORT_NUMBER(etermp); uchar = ERL_REF_CREATION(etermp); intx = ERL_REF_LEN(etermp); charp = ERL_REF_NODE(etermp); uintx = ERL_REF_NUMBER(etermp); uintp = ERL_REF_NUMBERS(etermp); etermp = ERL_TUPLE_ELEMENT(etermp,intx); intx = ERL_TUPLE_SIZE(etermp); return BUFSIZ + EAGAIN + EHOSTUNREACH + EINVAL + EIO + EMSGSIZE + ENOMEM + ERL_ATOM + ERL_BINARY + ERL_ERROR + ERL_EXIT + ERL_FLOAT + ERL_INTEGER + ERL_LINK + ERL_LIST + ERL_MSG + ERL_NO_TIMEOUT + ERL_PID + ERL_PORT + ERL_REF + ERL_REG_SEND + ERL_SEND + ERL_SMALL_BIG + ERL_TICK + ERL_TIMEOUT + ERL_TUPLE + ERL_UNLINK + ERL_U_INTEGER + ERL_U_SMALL_BIG + ERL_VARIABLE + ETIMEDOUT + MAXNODELEN + MAXREGLEN; }
/** ** rockse <path_to_tbl> <path_to_log> **/ int main(int argc, char **argv) { rockse * ptr; ETERM *from_erl; ETERM *cmd; ETERM *key; ETERM *value; char *ret; ETERM *to_send; byte buf[1024]; int length; log = fopen(argv[2], "a+"); erl_init(NULL, 0); fprintf(log, "*** rockse opening table %s\n", argv[1]); ptr = open(argv[1]); while (read_cmd(buf) > 0) { from_erl = erl_decode(buf); fprintf(log, " rockse command type %d\n", ERL_TYPE(from_erl)); if (match_close(from_erl)) { send_bok(); fprintf(log, " rockse command +close+ sent\n"); break; } if (ERL_IS_TUPLE(from_erl) && ERL_TUPLE_SIZE(from_erl) == 3) { /* can only be a {put, key, val} */ cmd = ERL_TUPLE_ELEMENT(from_erl, 0); if (match_put(cmd)) { key = ERL_TUPLE_ELEMENT(from_erl, 1); value = ERL_TUPLE_ELEMENT(from_erl, 2); fprintf(log, " rockse command +put+ %s %s sent\n", erl_iolist_to_string(key), erl_iolist_to_string(value)); put(ptr, erl_iolist_to_string(key), erl_iolist_to_string(value)); send_put_ok(); } erl_free_term(from_erl); erl_free_term(cmd); erl_free_term(key); erl_free_term(value); } if (ERL_IS_TUPLE(from_erl) && ERL_TUPLE_SIZE(from_erl) == 2) { /* can only be a {get, key} or {delete, key} */ cmd = ERL_TUPLE_ELEMENT(from_erl, 0); if (match_get(cmd)) { key = ERL_TUPLE_ELEMENT(from_erl, 1); fprintf(log, " rockse command +get+ %s sent\n", erl_iolist_to_string(key)); ret = get(ptr, erl_iolist_to_string(key)); if (ret == NULL) { send_nok(); } else { length = strlen(ret); fprintf(log, " rockse command +get+ found %s of size %d\n", ret, length); to_send = erl_format("{ok, get, ~s}", ret); send_get_result(to_send); free(ret); } } else if (match_delete(cmd)) { key = ERL_TUPLE_ELEMENT(from_erl, 1); fprintf(log, " rockse command +delete+ %s sent\n", erl_iolist_to_string(key)); delete(ptr, erl_iolist_to_string(key)); send_delete_ok(); } erl_free_term(from_erl); erl_free_term(cmd); erl_free_term(key); } fflush(log); } close_and_destroy(ptr); fprintf(log, "*** rockse closing table %s\n", argv[1]); erl_free_term(from_erl); fclose(log); return 0; }
void process_init_cmd(ETERM* init_cmd_pattern, int erl_fd, ETERM* msg_frompid) { fprintf(stderr, "process_init_cmd got PID "); erl_print_term(stderr, msg_frompid); fprintf(stderr, "\n"); ETERM* response; ETERM* msg_arg = erl_var_content(init_cmd_pattern, "Arg"); if (!ERL_IS_LIST(msg_arg)) { erl_err_msg("invalid argument to init command"); response = erl_format("{ecap_node, {error, {badarg, {init, ~w} } } }", msg_arg); erl_send(erl_fd, msg_frompid, response); goto invarg_cleanup; } char* fn_str = erl_iolist_to_string(msg_arg); if (fn_str == NULL) { erl_err_msg("could not unpack string"); response = erl_format("{ecap_node, {error, {badarg, {init, ~w}}}}", msg_arg); erl_send(erl_fd, msg_frompid, response); goto nostr_cleanup; } TRACE(("init command got argstring: %s", fn_str)); pthread_t* thread = (pthread_t*)malloc(sizeof(pthread_t)); info_t* threadinfo = (info_t*)malloc(sizeof(info_t)); // We copy all of this data because the transient pointers will be free()d // just before each function returns, destroying in the thread context. threadinfo->topid = msg_frompid; threadinfo->self = thread; threadinfo->fname = (char*)malloc(strlen(fn_str)+1); strncpy(threadinfo->fname, fn_str, strlen(fn_str)+1); threadinfo->erlvm_fd = erl_fd; int ret; if ((ret = pthread_create(thread, NULL, watcher, threadinfo)) != 0) { TRACE(("failed to create thread, with return code %d", ret)); erl_err_ret("failed to create watcher thread"); response = erl_format("{ecap_node, {error, {threadfail}}}"); erl_send(erl_fd, msg_frompid, response); TRACE(("freeing thread stuff")); free(thread); free(threadinfo->fname); free(threadinfo); goto nothread_cleanup; } response = erl_format("{ecap_node, ok}"); erl_send(erl_fd, msg_frompid, response); TRACE(("normal cleanup from init command call")); nothread_cleanup: nostr_cleanup: TRACE(("freeing fn_str")); erl_free(fn_str); invarg_cleanup: TRACE(("freeing terms")); erl_free_term(response); erl_free_term(msg_arg); TRACE(("done with init command processing")); }
/* * http://dev.mysql.com/doc/refman/5.1/en/mysql-stmt-execute.html * * 6 > odbc:param_query(Ref, * "INSERT INTO EMPLOYEE (NR, FIRSTNAME, " * "LASTNAME, GENDER) VALUES(?, ?, ?, ?)", * [{sql_integer,[2,3,4,5,6,7,8]}, * {{sql_varchar, 20}, * ["John", "Monica", "Ross", "Rachel", * "Piper", "Prue", "Louise"]}, * {{sql_varchar, 20}, * ["Doe","Geller","Geller", "Green", * "Halliwell", "Halliwell", "Lane"]}, * {{sql_char, 1}, ["M","F","M","F","T","F","F"]}]). * {updated, 7} */ void handle_param_query(ETERM *msg) { ETERM *query, *params, *p, *tmp, *resp; MYSQL_STMT *handle; MYSQL_BIND *bind; char *q; int param_count, i; query = erl_element(2, msg); q = erl_iolist_to_string(query); erl_free_term(query); logmsg("INFO: got param query: %s", q); params = erl_element(3, msg); erl_free_term(params); handle = mysql_stmt_init(&dbh); if (mysql_stmt_prepare(handle, q, strlen(q))) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } else { param_count = mysql_stmt_param_count(handle); if (param_count != erl_length(params)) { resp = erl_format("{error, {mysql_error, -1, [expected_params, %d, got_params, %d]}}", param_count, erl_length(params)); } else { bind = safe_malloc(param_count * sizeof(MYSQL_BIND)); memset(bind, 0, param_count * sizeof(MYSQL_BIND)); for (i = 0, tmp = params; i < param_count && (p = erl_hd(tmp)) != NULL; i++, tmp = erl_tl(tmp)) { ETERM *type, *value; type = erl_element(1, p); value = erl_element(2, p); if (ERL_IS_TUPLE(type)) { // Parameter Type + Size: {Type, Size} ETERM *t_type, *t_size; char *t; unsigned long size; t_size = erl_element(2, type); size = ERL_INT_VALUE(t_size); bind[i].buffer_length = size; erl_free_term(t_size); t_type = erl_element(1, type); t = (char *)ERL_ATOM_PTR(t_type); bind[i].length = safe_malloc(sizeof(unsigned long)); if (strncmp(t, NUMERIC_SQL, strlen(NUMERIC_SQL)) == 0) { int val; bind[i].buffer_type = MYSQL_TYPE_LONG; *bind[i].length = sizeof(int); bind[i].buffer = safe_malloc(*bind[i].length); memset(bind[i].buffer, 0, *bind[i].length); val = ERL_INT_VALUE(value); memcpy(bind[i].buffer, &val, *bind[i].length); } else if (strncmp(t, DECIMAL_SQL, strlen(DECIMAL_SQL)) == 0) { char *val; bind[i].buffer_type = MYSQL_TYPE_STRING; *bind[i].length = bind[i].buffer_length * sizeof(char); bind[i].buffer = safe_malloc(*bind[i].length); memset(bind[i].buffer, 0, *bind[i].length); val = erl_iolist_to_string(value); if (val) { memcpy(bind[i].buffer, val, *bind[i].length); free(val); } } else if (strncmp(t, FLOAT_SQL, strlen(FLOAT_SQL)) == 0) { float val; bind[i].buffer_type = MYSQL_TYPE_FLOAT; *bind[i].length = sizeof(float); bind[i].buffer = safe_malloc(*bind[i].length); memset(bind[i].buffer, 0, *bind[i].length); val = ERL_FLOAT_VALUE(value); memcpy(bind[i].buffer, &val, *bind[i].length); } else if (strncmp(t, CHAR_SQL, strlen(CHAR_SQL)) == 0) { char *val; bind[i].buffer_type = MYSQL_TYPE_STRING; *bind[i].length = bind[i].buffer_length * sizeof(char); bind[i].buffer = safe_malloc(*bind[i].length); memset(bind[i].buffer, 0, *bind[i].length); val = erl_iolist_to_string(value); if (val) { memcpy(bind[i].buffer, val, *bind[i].length); free(val); } } else if (strncmp(t, VARCHAR_SQL, strlen(VARCHAR_SQL)) == 0) { (void)bind_string(&bind[i], value, size); } else { ETERM *resp; resp = erl_format("{error, {unknown_sized_type, ~s, ~i}}", t, bind[i].buffer_length); write_msg(resp); erl_free_term(resp); } erl_free_term(t_type); } else { char *t; t = (char *)ERL_ATOM_PTR(type); if (strncmp(t, TIMESTAMP_SQL, strlen(TIMESTAMP_SQL)) == 0) { bind[i].buffer_type = MYSQL_TYPE_TIMESTAMP; *bind[i].length = sizeof(MYSQL_TIME); bind[i].buffer = safe_malloc(*bind[i].length); memset(bind[i].buffer, 0, *bind[i].length); memcpy(bind[i].buffer, value, *bind[i].length); } else if (strncmp(t, INTEGER_SQL, strlen(INTEGER_SQL)) == 0) { int val; bind[i].buffer_type = MYSQL_TYPE_LONG; *bind[i].length = sizeof(int); bind[i].buffer = safe_malloc(*bind[i].length); memset(bind[i].buffer, 0, *bind[i].length); val = ERL_INT_VALUE(value); memcpy(bind[i].buffer, &val, *bind[i].length); } else { ETERM *resp; resp = erl_format("{error, {unknown_type, ~s}}", t); write_msg(resp); erl_free_term(resp); } } if (ERL_IS_ATOM(value) && strncmp((char *)ERL_ATOM_PTR(value), NULL_SQL, strlen(NULL_SQL)) == 0) bind[i].is_null = &TRUTHY; else bind[i].is_null = &FALSY; erl_free_term(value); erl_free_term(type); } erl_free_term(params); if (mysql_stmt_bind_param(handle, bind)) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } else { if (mysql_stmt_execute(handle)) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } else { set_mysql_results(handle); if (results) { resp = handle_mysql_result(); } else { if (mysql_stmt_field_count(handle) == 0) resp = erl_format("{updated, ~i}", numrows); else resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_stmt_errno(handle), mysql_stmt_error(handle)); } } } for (i = 0; i < param_count; i++) { free(bind[i].length); free(bind[i].buffer); } free(bind); } } erl_free(q); mysql_stmt_close(handle); write_msg(resp); erl_free_term(resp); }