/* * A true RPC. It return a NULL pointer * in case of failure, otherwise a valid * (ETERM *) pointer containing the reply */ int ei_rpc(ei_cnode* ec, int fd, char *mod, char *fun, const char* inbuf, int inbuflen, ei_x_buff* x) { int i, index; ei_term t; erlang_msg msg; char rex[MAXATOMLEN]; if (ei_rpc_to(ec, fd, mod, fun, inbuf, inbuflen) < 0) { return -1; } /* FIXME are we not to reply to the tick? */ while ((i = ei_rpc_from(ec, fd, ERL_NO_TIMEOUT, &msg, x)) == ERL_TICK) ; if (i == ERL_ERROR) return -1; /*ep = 'erl'_element(2,emsg.msg);*/ /* {RPC_Tag, RPC_Reply} */ index = 0; if (ei_decode_version(x->buff, &index, &i) < 0 || ei_decode_ei_term(x->buff, &index, &t) < 0) return -1; /* FIXME ei_decode_version don't set erl_errno as before */ /* FIXME this is strange, we don't check correct "rex" atom and we let it pass if not ERL_SMALL_TUPLE_EXT and arity == 2 */ if (t.ei_type == ERL_SMALL_TUPLE_EXT && t.arity == 2) if (ei_decode_atom(x->buff, &index, rex) < 0) return -1; /* remove header */ x->index -= index; memmove(x->buff, &x->buff[index], x->index); return 0; }
static void outputv(ErlDrvData handle, ErlIOVec *ev) { ErlDrvPort port = (ErlDrvPort) handle; SysIOVec *bin; int i, n, index = 0; unsigned long hash; unsigned long seed; //first piece of the iovec is the seed // printf("ev->size %d\n", ev->size); // printf("ev-vsize %d\n", ev->vsize); //apparently we start counting at 1 round here? bin = &ev->iov[1]; // printf("bin->orig_size %d\n", bin->iov_len); // printf("bin->iov_base %s\n", bin->iov_base); ei_decode_version(bin->iov_base, &index, NULL); ei_decode_ulong(bin->iov_base, &index, &seed); hash = (unsigned int) seed; if (index < bin->iov_len) { hash = MurmurHash2(&bin->iov_base[index], bin->iov_len - index, hash); } // printf("hash %d\n", hash); for (i=2; i<ev->vsize; i++) { bin = &ev->iov[i]; // printf("bin->orig_size %d\n", bin->iov_len); hash = MurmurHash2(bin->iov_base, bin->iov_len, hash); // printf("hashed %d\n", i); } send_hash(port, hash); }
static void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT) { driver_data_t *data = (driver_data_t *)drv_data; int result = 0; int index = 0, version, arity; ei_decode_version(buf, &index, &version); ei_decode_tuple_header(buf, &index, &arity); if (2 == arity) { result = ergen_driver_do_txn(data->driver, buf, &index); if(result) { ergen_drv_output_bool(data->port, result); } else { ergen_drv_output_error1(data->port, "badmatch", "cmd"); } return; } ergen_drv_output_error0(data->port, "badarg"); }
/* * Reads an Erlang term. * * Only accepts 't' (term) or 'e' (end of test), * exits program on error * returns 1 on 'e', 0 on 't' */ int get_bin_term(ei_x_buff* x, ei_term* term) { int len, version; ei_x_free(x); x->buff = read_packet(&len); x->buffsz = len; x->index = 0; switch (x->buff[x->index++]) { case 'e': return 1; case 't': if (ei_decode_version(x->buff, &x->index, &version) < 0 || ei_decode_ei_term(x->buff, &x->index, term) < 0) { fail("Failed to decode term"); exit(0); } return 0; default: fprintf(stderr, "Garbage received: "); dump(x->buff, len, 16); putc('\n', stderr); fail("C program received garbage"); exit(1); } }
static int prepared_clear_bindings(sqlite3_drv_t *drv, char *buffer, int buffer_size) { unsigned int prepared_index; long long_prepared_index; int index = 0; sqlite3_stmt *statement; ei_decode_version(buffer, &index, NULL); ei_decode_long(buffer, &index, &long_prepared_index); prepared_index = (unsigned int) long_prepared_index; if (prepared_index >= drv->prepared_count) { #ifdef DEBUG fprintf(drv->log, "Tried to clear bindings of prepared statement #%d, but maximum possible is #%d\n", prepared_index, drv->prepared_count - 1); fflush(drv->log); #endif return output_error(drv, SQLITE_MISUSE, "Trying to clear bindings of non-existent prepared statement"); } #ifdef DEBUG fprintf(drv->log, "Clearing bindings of prepared statement #%d\n", prepared_index); fflush(drv->log); #endif statement = drv->prepared_stmts[prepared_index]; sqlite3_clear_bindings(statement); return output_ok(drv); }
static int prepared_finalize(sqlite3_drv_t *drv, char *buffer, int buffer_size) { unsigned int prepared_index; long long_prepared_index; int index = 0; ei_decode_version(buffer, &index, NULL); ei_decode_long(buffer, &index, &long_prepared_index); prepared_index = (unsigned int) long_prepared_index; if (prepared_index >= drv->prepared_count) { #ifdef DEBUG fprintf(drv->log, "Tried to finalize prepared statement #%d, but maximum possible is #%d\n", prepared_index, drv->prepared_count - 1); fflush(drv->log); #endif return output_error(drv, SQLITE_MISUSE, "Trying to finalize non-existent prepared statement"); } #ifdef DEBUG fprintf(drv->log, "Finalizing prepared statement #%d\n", prepared_index); fflush(drv->log); #endif // finalize the statement and make sure it isn't accidentally executed again sqlite3_finalize(drv->prepared_stmts[prepared_index]); drv->prepared_stmts[prepared_index] = NULL; // if the statement is at the end of the array, space can be reused; // otherwise don't bother if (prepared_index == drv->prepared_count - 1) { drv->prepared_count--; } return output_ok(drv); }
/** * @brief Decode and forward requests from Elixir to the appropriate handlers * @param req the undecoded request * @param cookie */ static void handle_elixir_request(const char *req, void *cookie) { (void) cookie; // Commands are of the form {Command, Arguments}: // { atom(), term() } int req_index = sizeof(uint16_t); if (ei_decode_version(req, &req_index, NULL) < 0) errx(EXIT_FAILURE, "Message version issue?"); int arity; if (ei_decode_tuple_header(req, &req_index, &arity) < 0 || arity != 2) errx(EXIT_FAILURE, "expecting {cmd, args} tuple"); char cmd[MAXATOMLEN]; if (ei_decode_atom(req, &req_index, cmd) < 0) errx(EXIT_FAILURE, "expecting command atom"); for (struct request_handler *rh = request_handlers; rh->name != NULL; rh++) { if (strcmp(cmd, rh->name) == 0) { rh->handler(req, &req_index); return; } } errx(EXIT_FAILURE, "unknown command: %s", cmd); }
static int prepared_reset(sqlite3_drv_t *drv, char *buffer, int buffer_size) { unsigned int prepared_index; long long_prepared_index; int index = 0; sqlite3_stmt *statement; ei_decode_version(buffer, &index, NULL); ei_decode_long(buffer, &index, &long_prepared_index); prepared_index = (unsigned int) long_prepared_index; if (prepared_index >= drv->prepared_count) { #ifdef DEBUG fprintf(drv->log, "Tried to reset prepared statement #%d, but maximum possible is #%d\n", prepared_index, drv->prepared_count - 1); fflush(drv->log); #endif return output_error(drv, SQLITE_MISUSE, "Trying to reset non-existent prepared statement"); } #ifdef DEBUG fprintf(drv->log, "Resetting prepared statement #%d\n", prepared_index); fflush(drv->log); #endif // don't bother about error code, any errors should already be shown by step statement = drv->prepared_stmts[prepared_index]; sqlite3_reset(statement); return output_ok(drv); }
static int prepared_bind(sqlite3_drv_t *drv, char *buffer, int buffer_size) { int result; unsigned int prepared_index; long long_prepared_index; int index = 0, type, size; sqlite3_stmt *statement; #ifdef DEBUG fprintf(drv->log, "Finalizing prepared statement: %.*s\n", buffer_size, buffer); fflush(drv->log); #endif ei_decode_version(buffer, &index, NULL); ei_decode_tuple_header(buffer, &index, &size); // assert(size == 2); ei_decode_long(buffer, &index, &long_prepared_index); prepared_index = (unsigned int) long_prepared_index; if (prepared_index >= drv->prepared_count) { return output_error(drv, SQLITE_MISUSE, "Trying to bind non-existent prepared statement"); } statement = drv->prepared_stmts[prepared_index]; result = bind_parameters(drv, buffer, buffer_size, &index, statement, &type, &size); if (result == SQLITE_OK) { return output_ok(drv); } else { return result; // error has already been output } }
decode_result process_data(ErlDrvData handle,unsigned char* buf, ErlDrvSizeT* sz,char*& html_content,char*& url_address){ int index = 0,size=0,type=0,ver=0; if (ei_decode_version((char*)buf, &index,&ver)){ //data encoding version mismatch return decode_result{false,std::pair<std::string,std::string>("",""), "data encoding version mismatch"}; } else if (ei_get_type((char*)buf,&index,&type,&size)){ //must be a binary return decode_result{false,std::pair<std::string,std::string>("",""), "must be a binary"}; } else{ int tuple_arity; ei_decode_tuple_header((char*)buf,&index,&tuple_arity); ei_get_type((char*)buf,&index,&type,&size); url_address = (char*)driver_alloc((size+2)*sizeof(char)); ei_decode_string((char*)buf,&index,url_address); ei_get_type((char*)buf,&index,&type,&size); //cout << "Html Content Size " << size << endl; html_content = (char*)driver_alloc((size+2)*sizeof(char)); ei_decode_string((char*)buf,&index,html_content); *sz = size; std::string url_address_str(url_address); std::string html_content_str(html_content); return decode_result{true,std::pair<std::string,std::string>(url_address_str,html_content_str),NULL}; } }
static void crop(Cmd *cmd) { char *buff = cmd->data; int len = cmd->size; Gd *gd = cmd->gd; int index = 0; long width, height; int srcW, srcH, srcX, srcY, destX, destY, playX, playY; gdImagePtr destination = NULL; ei_decode_version(buff, &index, NULL); ei_decode_tuple_header(buff, &index, NULL); ei_decode_long(buff, &index, &width); ei_decode_long(buff, &index, &height); if (NULL == gd->image) { driver_failure_atom(gd->port, "null_image"); return; } srcW = gdImageSX(gd->image); srcH = gdImageSY(gd->image); destination = gdImageCreateTrueColor(width, height); if (NULL == destination) { driver_failure_posix(gd->port, ENOMEM); return; } gdImageFilledRectangle(destination, 0, 0, width, height, gdImageColorAllocate(destination, 255, 255, 255)); destX = (width - srcW) / 2; destY = (height - srcH) / 2; gdImageCopy(destination, gd->image, destX, destY, 0, 0, srcW, srcH); gdImageDestroy(gd->image); gd->image = destination; send_atom(gd->port, "ok"); }
static void reply(erlang_msg *msg, ei_x_buff *recv_x_buf) { int index = 0; int version; ei_decode_version(recv_x_buf->buff, &index, &version); send_replies(recv_x_buf->buff, &index); }
static void resize(Cmd *cmd) { char *buff = cmd->data; int len = cmd->size; Gd *gd = cmd->gd; int index = 0; unsigned long width, height, srcW, srcH; gdImagePtr destination = NULL; ei_decode_version(buff, &index, NULL); ei_decode_tuple_header(buff, &index, NULL); ei_decode_ulong(buff, &index, &width); ei_decode_ulong(buff, &index, &height); if (NULL == gd->image) { driver_failure_atom(gd->port, "null_image"); return; } srcW = gdImageSX(gd->image); srcH = gdImageSY(gd->image); destination = gdImageCreateTrueColor(width, height); if (NULL == destination) { driver_failure_posix(gd->port, ENOMEM); return; } gdImageCopyResampled(destination, gd->image, 0, 0, 0, 0, width, height, srcW, srcH); gdImageDestroy(gd->image); gd->image = destination; send_atom(gd->port, "ok"); }
static int iconv_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen) { int i; int size; int index = 0; int avail; size_t inleft, outleft; ErlDrvBinary *b; char *from, *to, *string, *stmp, *rstring, *rtmp; iconv_t cd; ei_decode_version(buf, &index, &i); ei_decode_tuple_header(buf, &index, &i); ei_get_type(buf, &index, &i, &size); from = malloc(size + 1); ei_decode_string(buf, &index, from); ei_get_type(buf, &index, &i, &size); to = malloc(size + 1); ei_decode_string(buf, &index, to); ei_get_type(buf, &index, &i, &size); stmp = string = malloc(size + 1); ei_decode_string(buf, &index, string); cd = iconv_open(to, from); if(cd == (iconv_t) -1) { cd = iconv_open("ascii", "ascii"); if(cd == (iconv_t) -1) { cd = iconv_open("ascii", "ascii"); } } outleft = avail = 4*size; inleft = size; rtmp = rstring = malloc(avail); iconv(cd, &stmp, &inleft, &rtmp, &outleft); size = rtmp - rstring; //printf("size=%d, res=%s\r\n", size, rstring); *rbuf = (char*)(b = driver_alloc_binary(size)); memcpy(b->orig_bytes, rstring, size); free(from); free(to); free(string); free(rstring); iconv_close(cd); return size; }
ETERM *erl_global_whereis(int fd, const char *name, char *node) { char buf[EISMALLBUF]; char *bufp=buf; char tmpbuf[64]; int index = 0; erlang_pid *self = erl_self(); erlang_pid epid; ETERM *opid; erlang_msg msg; int i; int version,arity,msglen; self->num = fd; /* FIXME looks strange to change something?! */ ei_encode_version(buf,&index); ei_encode_tuple_header(buf,&index,2); ei_encode_pid(buf,&index,self); /* PidFrom */ ei_encode_tuple_header(buf,&index,5); ei_encode_atom(buf,&index,"call"); /* call */ ei_encode_atom(buf,&index,"global"); /* Mod */ ei_encode_atom(buf,&index,"whereis_name"); /* Fun */ ei_encode_list_header(buf,&index,1); /* Args: [ name ] */ ei_encode_atom(buf,&index,name); ei_encode_empty_list(buf,&index); ei_encode_atom(buf,&index,"user"); /* user */ /* make the rpc call */ if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return NULL; while (1) { index = EISMALLBUF; if (!(i = ei_recv_internal(fd,&bufp,&index,&msg,&msglen,1,0))) continue; else break; } if (i != ERL_SEND) return NULL; /* expecting { rex, pid } */ index = 0; if (ei_decode_version(buf,&index,&version) || ei_decode_tuple_header(buf,&index,&arity) || (arity != 2) || ei_decode_atom(buf,&index,tmpbuf) || strcmp(tmpbuf,"rex") || ei_decode_pid(buf,&index,&epid)) return NULL; /* bad response from other side */ /* put the pid into a format for the caller */ index = 0; ei_encode_pid(buf,&index,&epid); opid = erl_decode((unsigned char*)buf); /* extract the nodename for the caller */ if (node) strcpy(node,epid.node); return opid; }
/*----------------------------------------------------------------- * MAIN *----------------------------------------------------------------*/ int main(int argc, char *argv[]) { byte* buf; int size = BUF_SIZE; if (argc > 1) { test(argc, argv); return 0; } fprintf(stderr, "gssapi started\r\n"); if ((buf = malloc(size)) == NULL) return -1; while ( (buf = read_cmd(buf, &size)) ) { int res = 0; int index = 0; int version, arity; char command[MAXATOMLEN]; ei_x_buff result; port_func func; /* Ensure that we are receiving the binary term by reading and * stripping the version byte */ EI(ei_decode_version(buf, &index, &version)); /* Our marshalling spec is that we are expecting a tuple {Command, Arg1} */ EI(ei_decode_tuple_header(buf, &index, &arity)); EI(arity != 2); EI(ei_decode_atom(buf, &index, command)); /* Prepare the output buffer that will hold {ok, Result} or {error, Reason} */ EI(ei_x_new_with_version(&result) || ei_x_encode_tuple_header(&result, 2)); /* fprintf(stderr, "command: %s\r\n", command); */ func = lookup_func(command); if (func) { res = func(buf, index, &result); } else { EI(ei_x_encode_atom(&result, "error") || ei_x_encode_atom(&result, "unsupported_command")); } write_cmd(&result); ei_x_free(&result); } /* error: */ fprintf(stderr, "No more command, exiting\r\n"); return 0; }
eqmlTerm(const char * buf, int index = 0) : _buf(buf), _index(index) { if (index == 0) ei_decode_version(_buf, &_index, NULL); ei_get_type(_buf, &_index, &_type, &_size); if (isTuple()) ei_decode_tuple_header(_buf, &_index, &_arity); }
int xbuff2xavp(sr_xavp_t **xavp, ei_x_buff *xbuff) { int i=0, version=0; if (ei_decode_version(xbuff->buff,&i,&version)) { LM_DBG("no version byte encoded in reply\n"); } return xavp_decode(xbuff,&i,xavp,0); }
// ============================================================================= // Utility functions // ============================================================================= void init_state(state *st, char *args, int argslen) { st->index = 0; st->version = 0; st->args = args; st->argslen = argslen; ei_decode_version(st->args, &(st->index), &(st->version)); assert(st->version != 0); assert(st->index != 0); ei_x_new_with_version(&(st->eixb)); }
static ErlDrvSSizeT test_drv_call(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen, unsigned int *flags) { int index = 0, vsn; char arg, res; ei_decode_version(buf, &index, &vsn); ei_decode_char(buf, &index, &arg); res = (char) do_f((char) command, arg); index = 0; ei_encode_version(*rbuf, &index); ei_encode_char(*rbuf, &index, res); return index+1; }
int exmpp_skip_version(const char *buf) { int index, version; index = 0; if (ei_decode_version(buf, &index, &version) != 0) return (-1); return (index); }
static void reply(erlang_msg *msg, ei_x_buff *recv_x_buf) { int i = 0; int version; ei_x_buff xbuf; ei_decode_version(recv_x_buf->buff, &i, &version); ei_x_new_with_version(&xbuf); make_reply_list(&xbuf, recv_x_buf->buff, &i); gn_send(&xbuf); ei_x_free(&xbuf); }
static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { syslogdrv_t* d = (syslogdrv_t*)handle; if (d->open) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } int index = 0, version, arity, type, size; if (command != SYSLOGDRV_OPEN) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_decode_version(buf, &index, &version)) { return encode_error(*rbuf, "badver"); } if (ei_decode_tuple_header(buf, &index, &arity) || arity != 3) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_get_type(buf, &index, &type, &size)) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (type == ERL_STRING_EXT) { long logopt, facility; if (d->ident) { driver_free(d->ident); } d->ident = driver_alloc(size+1); if (d->ident == NULL) { return encode_error(*rbuf, "enomem"); } if (ei_decode_string(buf, &index, d->ident)) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_decode_long(buf, &index, &logopt) || ei_decode_long(buf, &index, &facility)) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } d->logopt = (int)logopt; d->facility = (int)facility; d->open = 1; return 0; } else { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } }
static int sql_bind_and_exec(sqlite3_drv_t *drv, char *buffer, int buffer_size) { int result; int index = 0; int type, size; const char *rest; sqlite3_stmt *statement; long bin_size; char *command; #ifdef DEBUG fprintf(drv->log, "Preexec: %.*s\n", buffer_size, buffer); fflush(drv->log); #endif ei_decode_version(buffer, &index, NULL); result = ei_decode_tuple_header(buffer, &index, &size); if (result || (size != 2)) { return output_error(drv, SQLITE_MISUSE, "Expected a tuple of SQL command and params"); } // decode SQL statement ei_get_type(buffer, &index, &type, &size); // TODO support any iolists if (type != ERL_BINARY_EXT) { return output_error(drv, SQLITE_MISUSE, "SQL should be sent as an Erlang binary"); } command = driver_alloc(size * sizeof(char)); ei_decode_binary(buffer, &index, command, &bin_size); // assert(bin_size == size) result = sqlite3_prepare_v2(drv->db, command, size, &statement, &rest); driver_free(command); if (result != SQLITE_OK) { return output_db_error(drv); } else if (statement == NULL) { return output_error(drv, SQLITE_MISUSE, "empty statement"); } result = bind_parameters(drv, buffer, buffer_size, &index, statement, &type, &size); if (result == SQLITE_OK) { return sql_exec_statement(drv, statement); } else { return result; // error has already been output } }
/* tests de tipos simples */ int test_performance_atom(char *atom, int times) { ei_x_buff output; ei_x_buff input; erlang_msg msg; int version; int ei_res; int index; char decoded_atom[MAXATOMLEN]; // Inicializa buffers ei_x_new_with_version(&output); ei_x_new(&input); // Codifica ei_x_encode_tuple_header(&output, 2); ei_x_encode_pid(&output, &local_pid); ei_x_encode_atom(&output, atom); for (int i = 0; i<times; i++) { if (ei_reg_send(&ec, connection_fd, REMOTE_SERVER_NAME, output.buff, output.index) < 0) { return 1; } do { ei_res = ei_xreceive_msg(connection_fd, &msg, &input); } while(ei_res == ERL_TICK); if (ei_res == ERL_ERROR) { return -1; } index = 0; if (ei_decode_version(input.buff, &index, &version) < 0) { std::cout << "failed decoding version \n"; return 1; } if (ei_decode_atom(input.buff, &index, decoded_atom) < 0) { std::cout << "failed decoding atom \n"; return 1; } } return 0; }
static int prepared_columns(sqlite3_drv_t *drv, char *buffer, int buffer_size) { unsigned int prepared_index; long long_prepared_index; int index = 0, term_count = 0, term_allocated = 0, column_count; sqlite3_stmt *statement; ErlDrvTermData *dataset = NULL; ei_decode_version(buffer, &index, NULL); ei_decode_long(buffer, &index, &long_prepared_index); prepared_index = (unsigned int) long_prepared_index; if (prepared_index >= drv->prepared_count) { #ifdef DEBUG fprintf(drv->log, "Tried to get columns for prepared statement #%d, but maximum possible is #%d\n", prepared_index, drv->prepared_count - 1); fflush(drv->log); #endif return output_error(drv, SQLITE_MISUSE, "Trying to reset non-existent prepared statement"); } #ifdef DEBUG fprintf(drv->log, "Getting the columns for prepared statement #%d\n", prepared_index); fflush(drv->log); #endif statement = drv->prepared_stmts[prepared_index]; term_count += 4; if (term_count > term_allocated) { term_allocated = max(term_count, term_allocated*2); dataset = driver_realloc(dataset, sizeof(ErlDrvTermData) * term_allocated); } dataset[term_count - 4] = ERL_DRV_PORT; dataset[term_count - 3] = driver_mk_port(drv->port); column_count = sqlite3_column_count(statement); get_columns( drv, statement, column_count, 2, &term_count, &term_allocated, &dataset); dataset[term_count - 2] = ERL_DRV_TUPLE; dataset[term_count - 1] = 2; return driver_output_term(drv->port, dataset, term_count); }
static void setup(bloom_drv_t *driver, char *buf, int len) { long n; double e; char *filename; int size; int type; int index = 0; ei_decode_version(buf, &index, NULL); ei_decode_tuple_header(buf, &index, NULL); ei_get_type(buf, &index, &type, &size); filename = driver_alloc(size+1); ei_decode_string(buf, &index, filename); ei_decode_long(buf, &index, &n); ei_decode_double(buf, &index, &e); driver->bloom = bloom_open(filename, n, e); driver_free(filename); }
static void get_blob(Cmd *cmd) { char *buff = cmd->data; int len = cmd->size; Gd *gd = cmd->gd; int index = 0; void *imgData = NULL; int size = 0; ErlDrvBinary * bin; long quality; ei_decode_version(buff, &index, NULL); ei_decode_long(buff, &index, &quality); if (NULL == gd->image) { driver_failure_atom(gd->port, "null_image"); return; } imgData = gd->blob(gd->image, &size, quality); if (NULL == imgData) { driver_failure_posix(gd->port, ENOMEM); return; } bin = driver_alloc_binary(size); if (NULL == bin) { driver_failure_posix(gd->port, ENOMEM); return; } memcpy(bin->orig_bytes, imgData, size); gdFree(imgData); ErlDrvTermData spec[] = { ERL_DRV_PORT, driver_mk_port(gd->port), ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_BINARY, bin, size, 0, ERL_DRV_TUPLE, 3}; driver_output_term(gd->port, spec, sizeof(spec) / sizeof(ERL_DRV_PORT)); driver_free_binary(bin); }
static int mn_send_commit(int fd, erlang_pid *mnesia, erlang_pid *self) { char buf[EISMALLBUF]; char *bufp=buf; char string[256]; int index = 0; int version,arity; int msglen; erlang_msg msg; int i; /* set up commit message { commit, self() } */ ei_encode_version(buf,&index); ei_encode_tuple_header(buf,&index,2); ei_encode_atom(buf,&index,EI_MNESIA_COMMIT); ei_encode_pid(buf,&index,self); /* send it */ if (ei_send_encoded(fd,mnesia,buf,index)) return -1; /* get reply */ while (1) { index = EISMALLBUF; if (!(i=ei_recv_internal(fd,&bufp,&index,&msg,&msglen,1,0))) continue; else if (i < 0) return -1; else break; } if (i == ERL_SEND) { index = 0; if (ei_decode_version(buf,&index,&version) || ei_decode_tuple_header(buf,&index,&arity) || ei_decode_atom(buf,&index,string)) return -1; if (!strcmp(string,"ok")) return 0; } /* wrong message type */ return -1; }
int _impl_reply(const ei_x_buff *msg) { int i=0,version; if (ei_decode_version(msg->buff,&i,&version)) { LM_ERR("msg must be encoded with version\n"); return -1; } /* must be in call back / event route */ if (csockfd) { LM_ERR("not in callback\n"); return -1; } else if (!enode) { LM_ERR("not connected\n"); return -1; } if (rex_call_in_progress) { LM_ERR("RPC in progress detected\n"); return -1; } /* copy into reply */ if (enode->response.buffsz < msg->buffsz) { /* realocate */ enode->response.buff=realloc(enode->response.buff,msg->buffsz); if (!enode->response.buff) { LM_ERR("realloc failed: not enough memory\n"); return -1; } enode->response.buffsz = msg->buffsz; } memcpy((void*)enode->response.buff,(void*)msg->buff,msg->buffsz); enode->response.index = msg->index; return 0; }