static void gen_q_drv_output(ErlDrvData handle, char *buff, ErlDrvSizeT bufflen) { GenQData *d = (GenQData*)handle; QWork* work = genq_alloc_work(buff, bufflen); if(work->op == FUNC_OPTS) { LOG("received opts %ld\n", work->op); copy_qopts((QOpts*)work->data, &d->opts); genq_free_work(work); LOG("responding %s\n", "ok"); ei_x_buff ok; ei_x_new(&ok); ei_x_encode_ok(&ok); driver_output(d->port, ok.buff, ok.index); ei_x_free(&ok); return; } else if(work->data == NULL) { genq_free_work(work); ei_x_buff error; ei_x_new(&error); ei_x_encode_error_tuple_atom(&error, "badarg"); driver_output(d->port, error.buff, error.index); ei_x_free(&error); return; } work->opts = &d->opts; driver_async(d->port, work->dispatch_key, genq_work, work, genq_free_work); }
/* buf is the name of the intented user */ static ErlDrvData setuid_start(ErlDrvPort port, char *buf) { char *t; char xbuf[BUFSIZ]; struct passwd *pe; if ((t = strchr(buf, ' ')) == NULL) return (ErlDrvData) -1; t++; switch (*t++) { case 's': /* setuid */ while ((pe = getpwent())) { if (strcmp(pe->pw_name , t) == 0) { if ((setuid(pe->pw_uid) != 0) || (setreuid(pe->pw_uid, pe->pw_uid) != 0)) { return (ErlDrvData) -1; } sprintf(xbuf, "ok %d", pe->pw_uid); endpwent(); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; } } endpwent(); return (ErlDrvData) -1; case 'g': /* getuid */ sprintf(xbuf, "ok %d", getuid()); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; case 'u': while ((pe = getpwent())) { if (strcmp(pe->pw_name , t) == 0) { sprintf(xbuf, "ok %d", pe->pw_uid); endpwent(); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; } } endpwent(); return (ErlDrvData) -1; case 'h': while ((pe = getpwent())) { if (strcmp(pe->pw_name , t) == 0) { sprintf(xbuf, "ok %s", pe->pw_dir); endpwent(); driver_output(port,xbuf, strlen(xbuf)); return (ErlDrvData) port; } } endpwent(); return (ErlDrvData) -1; } }
// function ehecatl_driver_output, hanldes the ouput to erlang, when receives a // request from it (erlang request) static void ehecatl_driver_output(ErlDrvData handle, char *buff, int bufflen) { erl_port* to_erl_port = (erl_port*)handle; char fun = buff[0], arg = buff[1], res; if (fun == 1) { char* ehecatl_api = (char*)ehecatl_api_sc(arg); driver_output(to_erl_port->port, ehecatl_api, strlen(ehecatl_api)); } else { char* ehecatl_api = (char*)ehecatl_api_sc(arg); driver_output(to_erl_port->port, ehecatl_api, strlen(ehecatl_api)); } }
bool CCESUT::TradeOrder(PTradeOrderTxnInput pTxnInput, INT32 iTradeType, bool bExecutorIsAccountOwner) { ei_x_buff x; ei_x_new_with_version(&x); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, "ok"); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, APP ".BH.TO"); ei_x_encode_tuple_header(&x, 3); { m_Encoder.encode(&x, "trade_type", iTradeType); m_Encoder.encode(&x, "executor_is_account_owner", bExecutorIsAccountOwner); m_Encoder.encode(&x, *pTxnInput); } } } int result = driver_output(m_ErlDrvPort, x.buff, x.index); #ifdef _TRACE cout << "[TO] ! " << *pTxnInput << ", result=" << result << '\r' << endl; #endif ei_x_free(&x); return result; }
static int control_control(ErlDrvData port, unsigned command, char* buf, int count, char** res, int res_size) { switch (command) { case 'e': if (count > res_size) { *res = (char *) driver_alloc(count); } memcpy(*res, buf, count); return count; case 'b': set_busy_port(erlang_port, buf[0]); return 0; case 'i': driver_output(erlang_port, buf, count); return 0; default: if (command < 256) { return -1; } else { char* p = *res; int i; for (i = 3; i >= 0; i--) { p[i] = command; command >>= 8; } return 4; } } }
static int state_reply(RegPort* rp, /* Pointer to port structure. */ HKEY root, /* Handle to root key for this key. */ LPSTR name, /* Pointer to name. */ DWORD nameSize) /* Length of name. */ { char sbuf[512]; char* s = sbuf; int needed = 1+4+nameSize; int i; if (sizeof sbuf < needed) { s = driver_alloc(needed); } s[0] = 's'; i = 1; put_int32((DWORD) root, s+i); i += 4; memcpy(s+i, name, nameSize); ASSERT(i+nameSize == needed); driver_output(rp->port, s, needed); if (s != sbuf) { driver_free(s); } return 1; }
bool CCESUT::MarketWatch(PMarketWatchTxnInput pTxnInput) { ei_x_buff x; ei_x_new_with_version(&x); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, "ok"); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, APP ".BH.MW"); m_Encoder.encode(&x, *pTxnInput); } } int result = driver_output(m_ErlDrvPort, x.buff, x.index); #ifdef _TRACE cout << "[MW] ! " << *pTxnInput << ", result=" << result << '\r' << endl; #endif ei_x_free(&x); return result; }
bool CDMSUT::TradeCleanup(PTradeCleanupTxnInput pTxnInput) { ei_x_buff x; ei_x_new_with_version(&x); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, "ok"); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, APP ".BH.TC"); m_Encoder.encode(&x, *pTxnInput); } } int result = driver_output(m_ErlDrvPort, x.buff, x.index); #ifdef _TRACE cout << "[TC] ! " << *pTxnInput << ", result=" << result << '\r' << endl; #endif ei_x_free(&x); return result; }
static void drv_output(ErlDrvData handle, char *buf,ErlDrvSizeT sz){ ei_x_buff packed_data; char* html_content = NULL; char* url_address = NULL; //first - url, second - html content decode_result process_data_result = process_data(handle,(unsigned char*)buf,&sz,html_content,url_address); if (!process_data_result.decode_success){ packed_data = make_error(process_data_result.error_msg); } else{ //first - links, second - wholeText parse_result process_html_result = process_html_source(process_data_result.html_content.second,process_data_result.html_content.first); packed_data = pack_parse_data(process_html_result); if (html_content != NULL && url_address != NULL){ driver_free(html_content); driver_free(url_address); } } drv_data_t* drv_t = (drv_data_t*)handle; driver_output(drv_t->port, packed_data.buff, packed_data.buffsz); ei_x_free(&packed_data); }
static int value_reply(RegPort* rp, /* Pointer to port structure. */ DWORD type, /* Type of value */ LPSTR name, /* Pointer to name. */ DWORD nameSize, /* Length of name. */ LPSTR value, /* Pointer to value. */ DWORD valueSize) /* Size of value. */ { char sbuf[512]; char* s = sbuf; int needed = 1+4+nameSize+1+valueSize; int i; if (sizeof sbuf < needed) { s = driver_alloc(needed); } s[0] = 'v'; i = 1; put_int32(type, s+i); i += 4; memcpy(s+i, name, nameSize); i += nameSize; s[i++] = '\0'; memcpy(s+i, value, valueSize); ASSERT(i+valueSize == needed); driver_output(rp->port, s, needed); if (s != sbuf) { driver_free(s); } return 1; }
static void send_atom(ErlDrvPort port, const char *str) { ei_x_buff x; ei_x_new_with_version(&x); ei_x_encode_atom(&x, str); driver_output(port, x.buff, x.index); ei_x_free(&x); }
static void sendfile_drv_output(ErlDrvData handle, char* buf, ErlDrvSizeT buflen) { int fd, socket_fd; Desc* d = (Desc*)handle; Buffer b; b.buffer = buf; socket_fd = get_int32(&(b.args->out_fd)); fd = open(b.args->filename, O_RDONLY | O_NONBLOCK); if (fd < 0) { ErlDrvSizeT out_buflen = set_error_buffer(&b, socket_fd, errno); driver_output(d->port, buf, out_buflen); } else { Transfer* xfer; SocketFd sfd; sfd.socket_fd = socket_fd; xfer = (Transfer*)hashtable_search(d->xfer_table, sfd.hashkey); if (xfer == NULL) { /* Transfer objects are intentionally not freed until the driver stops, or if an insertion error occurs below. */ xfer = (Transfer*)malloc(sizeof(Transfer)); if (xfer == NULL) { ErlDrvSizeT out_buflen = set_error_buffer(&b, socket_fd, ENOMEM); driver_output(d->port, buf, out_buflen); return; } if (!hashtable_insert(d->xfer_table, sfd.hashkey, xfer)) { ErlDrvSizeT out_buflen = set_error_buffer(&b, socket_fd, ENOMEM); driver_output(d->port, buf, out_buflen); free(xfer); return; } } xfer->file_fd = fd; xfer->offset = get_int64(&(b.args->offset.offset)); xfer->count = get_int64(&(b.args->count.size)); xfer->total = 0; #if defined(ERL_DRV_USE) && defined(ERL_DRV_WRITE) driver_select(d->port, sfd.ev_data, ERL_DRV_USE|ERL_DRV_WRITE, 1); #else driver_select(d->port, sfd.ev_data, DO_WRITE, 1); #endif } }
static void timer(ErlDrvData port) { char reply[1]; /* fprintf(stderr, "[timer_drv] timer timed out\n"); */ reply[0] = TIMER; driver_output((ErlDrvPort)port, reply, 1); }
static void startc_drv_output(ErlDrvData handle, char *buff, int bufflen) { startc_data* d = (startc_data*)handle; CString strNodeName; strNodeName = startc(atoi(buff)); driver_output(d->port, (char*)(LPCTSTR)strNodeName, strNodeName.GetLength()); }
static void send_hash(ErlDrvPort port, unsigned long hash) { ei_x_buff x; ei_x_new_with_version(&x); ei_x_encode_ulong(&x, hash); driver_output(port, x.buff, x.index); // printf("sent hash %d\n", hash); ei_x_free(&x); }
void handle_winch(int sig){ ei_x_buff eixb; ei_x_new_with_version(&eixb); tuple(&eixb, 2); atom(&eixb, "sigwinch", 8); atom(&eixb, "sigwinch", 8); driver_output(stpt->drv_port, eixb.buff, eixb.index); }
static int ret_int(int port, int ret) { char buf[5]; buf[0] = 1; put_int32(ret, buf+1); driver_output(port, buf, 5); return ret; }
doio(ErlDrvData port, ErlDrvEvent ino) { /* First go get the io, unless we already did that */ /* In the sighandler */ /* Then send it to erlang */ driver_output(this_port, "y", 1); }
static int ret_int_int(int port, int i, int j) { char buf[9]; buf[0] = 1; put_int32(i, buf+1); put_int32(j, buf+5); driver_output(port, buf, 9); return i; }
static void do_getch(ErlDrvData drvstate, ErlDrvEvent event) { state *st = (state *)drvstate; ei_x_buff eixb; int keycode; ei_x_new_with_version(&eixb); keycode = getch(); integer(&eixb, keycode); driver_output(st->drv_port, eixb.buff, eixb.index); }
static void tiger_drv_output(ErlDrvData handle, char *buff, int bufflen) { tiger_data* d = (tiger_data*)handle; uint64_t tiger_res[3]; tiger((uint64_t*) buff, bufflen, (uint64_t*) tiger_res); driver_output(d->port, tiger_res, 24); }
static void key_size(bloom_drv_t *driver) { long result; ei_x_buff x; result = bloom_key_size(driver->bloom); ei_x_new_with_version(&x); ei_x_encode_long(&x, result); driver_output(driver->port, x.buff, x.index); ei_x_free(&x); }
static void has(bloom_drv_t *driver, char *buf, int len) { int result; ei_x_buff x; result = bloom_has(driver->bloom, buf, len); ei_x_new_with_version(&x); ei_x_encode_boolean(&x, result); driver_output(driver->port, x.buff, x.index); ei_x_free(&x); }
static void example_drv_output(ErlDrvData handle, char *buff, int bufflen) { example_data* d = (example_data*)handle; char fn = buff[0], arg = buff[1], res; if (fn == 1) { res = twice(arg); } else if (fn == 2) { res = sum(buff[1], buff[2]); } driver_output(d->port, &res, 1); }
static void example_drv_output(ErlDrvData handle, char *buff, ErlDrvSizeT bufflen) { example_data* d = (example_data*)handle; char fn = buff[0], arg = buff[1], res; if (fn == 1) { res = foo(arg); } else if (fn == 2) { res = bar(arg); } driver_output(d->port, &res, 1); }
static void reply(RegPort* rp, LONG result) { char sbuf[256]; if (result == ERROR_SUCCESS) { sbuf[0] = 'o'; driver_output(rp->port, sbuf, 1); } else { char* s; char* t; int err; sbuf[0] = 'e'; err = maperror(result); for (s = erl_errno_id(err), t = sbuf+1; *s; s++, t++) { *t = tolower(*s); } driver_output(rp->port, sbuf, t-sbuf); } /* return 1; */ }
static void ready_async(ErlDrvData handle, ErlDrvThreadData w) { GenQData* d = (GenQData*)handle; QWork* work = (QWork*)w; ei_x_buff result; ei_x_new(&result); genq_work_result(work, &result); genq_free_work(work); driver_output(d->port, result.buff, result.index); ei_x_free(&result); }
static void sendfile_drv_ready_output(ErlDrvData handle, ErlDrvEvent ev) { Desc* d = (Desc*)handle; ssize_t result; off_t cur_offset; Transfer* xfer; SocketFd* sfd = (SocketFd*)&ev; xfer = (Transfer*)hashtable_search(d->xfer_table, sfd->hashkey); if (xfer == NULL) { /* fatal error, something is very wrong */ driver_failure_atom(d->port, "socket_fd_not_found"); return; } cur_offset = xfer->offset; result = sendfile_call(sfd->socket_fd, xfer->file_fd, &xfer->offset, xfer->count); if (result < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS || errno == EALREADY)) { if (xfer->offset != cur_offset) { off_t written = xfer->offset - cur_offset; xfer->count -= written; xfer->total += written; } } else { int save_errno = errno; ErlDrvSizeT out_buflen; char buf[36]; Buffer b; b.buffer = buf; memset(buf, 0, sizeof buf); #ifdef ERL_DRV_WRITE driver_select(d->port, ev, ERL_DRV_WRITE, 0); #else driver_select(d->port, ev, DO_WRITE, 0); #endif close(xfer->file_fd); if (result < 0) { out_buflen = set_error_buffer(&b, sfd->socket_fd, save_errno); } else { uint64_t total = xfer->total + result; put_int64(total, &(b.result->count.count)); put_int32(sfd->socket_fd, &(b.result->out_fd)); b.result->success = 1; b.result->errno_string[0] = '\0'; out_buflen = sizeof(*b.result); } xfer->file_fd = -1; xfer->offset = xfer->count = xfer->total = 0; driver_output(d->port, buf, out_buflen); } }
static void tun_input(ErlDrvData data, ErlDrvEvent nil) { struct tun_state *state = (struct tun_state *)data; int len; len = read(state->fd, state->buf, TUNNEL_BUF_SIZE); if (len > 0) { driver_output(state->port, state->buf, len); } if (state->active == ACTIVE_ONCE) { state->active = ACTIVE_FALSE; set_input(state, 0); } }
static void do_getch(ErlDrvData drvstate, ErlDrvEvent event) { state *st = (state *)drvstate; ei_x_buff eixb; int keycode; ei_x_new_with_version(&eixb); keycode = getch(); if(keycode == KEY_RESIZE) { encode_ok_reply(st, OK); } else { tuple(&eixb, 2); atom(&eixb, "getch", 5); integer(&eixb, keycode); driver_output(st->drv_port, eixb.buff, eixb.index); } }