posix_errno_t efile_get_cwd(ErlNifEnv *env, ERL_NIF_TERM *result) { ErlNifBinary result_bin; size_t bytes_copied; if(!enif_alloc_binary(256, &result_bin)) { return ENOMEM; } while(getcwd((char*)result_bin.data, result_bin.size) == NULL) { posix_errno_t saved_errno = errno; if(saved_errno != ERANGE) { enif_release_binary(&result_bin); return saved_errno; } else { if(!enif_realloc_binary(&result_bin, result_bin.size * 2)) { enif_release_binary(&result_bin); return ENOMEM; } } } /* getcwd(2) guarantees null-termination. */ bytes_copied = strlen((const char*)result_bin.data); if(!enif_realloc_binary(&result_bin, bytes_copied)) { enif_release_binary(&result_bin); return ENOMEM; } (*result) = enif_make_binary(env, &result_bin); return 0; }
/*-----------------------------------------------------------------------------------------------------------------------*/ static ERL_NIF_TERM msg_to_binary(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[]) { ERL_NIF_TERM parser_res; ERL_NIF_TERM msg_res; ParserRes* parser = NULL; FIXMsg* msg = NULL; ERL_NIF_TERM res = get_parser_msg(env, argv[0], &parser_res, &msg_res, &parser, &msg); if (res != ok_atom) { return res; } int32_t delimiter = 0; if (!enif_get_int(env, argv[1], &delimiter) || delimiter <= 0 || delimiter >= 255) { return make_error(env, FIX_FAILED, "Wrong delimiter."); } uint32_t reqBuffLen = DEF_BINARY_SIZE; ErlNifBinary bin; if (!enif_alloc_binary(reqBuffLen, &bin)) { return make_error(env, FIX_FAILED, "Unable to allocate binary."); } FIXError* error = NULL; pthread_rwlock_rdlock(&parser->lock); if (FIX_FAILED == fix_msg_to_str(msg, (char)delimiter, (char*)bin.data, bin.size, &reqBuffLen, &error)) { if (reqBuffLen > bin.size) // realloc needed { if (!enif_realloc_binary(&bin, reqBuffLen)) { res = make_error(env, FIX_FAILED, "Unable to reallocate binary."); } if (FIX_FAILED == fix_msg_to_str(msg, (char)delimiter, (char*)bin.data, bin.size, &reqBuffLen, &error)) { res = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error)); fix_error_free(error); } } else { res = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error)); fix_error_free(error); } } pthread_rwlock_unlock(&parser->lock); if (res != ok_atom) { enif_release_binary(&bin); return res; } if (bin.size > reqBuffLen) { enif_realloc_binary(&bin, reqBuffLen); } ERL_NIF_TERM bin_term = enif_make_binary(env, &bin); enif_release_binary(&bin); return enif_make_tuple2(env, ok_atom, bin_term); }
/** @brief Reads an entire file into \c result, stopping after \c size bytes or * EOF. It will read until EOF if size is 0. */ static posix_errno_t read_file(efile_data_t *d, size_t size, ErlNifBinary *result) { size_t initial_buffer_size; ssize_t bytes_read; if(size == 0) { initial_buffer_size = 16 << 10; } else { initial_buffer_size = size; } if(!enif_alloc_binary(initial_buffer_size, result)) { return ENOMEM; } bytes_read = 0; for(;;) { ssize_t block_bytes_read; SysIOVec read_vec[1]; read_vec[0].iov_base = result->data + bytes_read; read_vec[0].iov_len = result->size - bytes_read; block_bytes_read = efile_readv(d, read_vec, 1); if(block_bytes_read < 0) { enif_release_binary(result); return d->posix_errno; } bytes_read += block_bytes_read; if(block_bytes_read < (result->size - bytes_read)) { /* EOF */ break; } else if(bytes_read == size) { break; } if(!enif_realloc_binary(result, bytes_read * 2)) { enif_release_binary(result); return ENOMEM; } } /* The file may have shrunk since we queried its size, so we have to do * this even when the size is known. */ if(bytes_read < result->size && !enif_realloc_binary(result, bytes_read)) { ERTS_INTERNAL_ERROR("Failed to shrink read_file result."); } return 0; }
ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */ BIGNUM *other_pub_key = NULL, *dh_p = NULL, *dh_g = NULL; DH *dh_priv = DH_new(); /* Check the arguments and get my private key (dh_priv), the peer's public key (other_pub_key), the parameters p & q */ { BIGNUM *dummy_pub_key = NULL, *priv_key = NULL; ERL_NIF_TERM head, tail; if (!get_bn_from_bin(env, argv[0], &other_pub_key) || !get_bn_from_bin(env, argv[1], &priv_key) || !enif_get_list_cell(env, argv[2], &head, &tail) || !get_bn_from_bin(env, head, &dh_p) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &dh_g) || !enif_is_empty_list(env, tail) /* Note: DH_set0_key() does not allow setting only the * private key, although DH_compute_key() does not use the * public key. Work around this limitation by setting * the public key to a copy of the private key. */ || !(dummy_pub_key = BN_dup(priv_key)) || !DH_set0_key(dh_priv, dummy_pub_key, priv_key) || !DH_set0_pqg(dh_priv, dh_p, NULL, dh_g) ) { if (dh_p) BN_free(dh_p); if (dh_g) BN_free(dh_g); if (other_pub_key) BN_free(other_pub_key); if (dummy_pub_key) BN_free(dummy_pub_key); if (priv_key) BN_free(priv_key); return enif_make_badarg(env); } } { ErlNifBinary ret_bin; int size; enif_alloc_binary(DH_size(dh_priv), &ret_bin); size = DH_compute_key(ret_bin.data, other_pub_key, dh_priv); BN_free(other_pub_key); DH_free(dh_priv); if (size<=0) { enif_release_binary(&ret_bin); return atom_error; } if (size != ret_bin.size) enif_realloc_binary(&ret_bin, size); return enif_make_binary(env, &ret_bin); } }
static ERL_NIF_TERM context_fini(ErlNifEnv* env, Context* ctx, size_t dsize, ChunkHandler handler) { ERL_NIF_TERM result; ctx->bitlen += ctx->count*8; pad(0, 0, ctx); handler(ctx, ctx->bytes); if (ctx->count > ctx->size) { handler(ctx, ctx->bytes + ctx->size); } #ifndef WORDS_BIGENDIAN { int i; if (ctx->size == PADDED_SIZE_2XX_BYTES) { uint32_t* hash = (uint32_t*)ctx->digest.data; for (i = 0; i < ctx->digest.size/sizeof(*hash); ++i) { hash[i] = BYTESWAP32(hash[i]); } } else { uint64_t* hash = (uint64_t*)ctx->digest.data; for (i = 0; i < ctx->digest.size/sizeof(*hash); ++i) { hash[i] = BYTESWAP64(hash[i]); } } } #endif if (ctx->digest.size != dsize) { enif_realloc_binary(&ctx->digest, dsize); } result = enif_make_binary(env, &ctx->digest); ctx->digest.size = 0; return result; }
ERL_NIF_TERM ucrypto_ec_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { unsigned int length; struct ec_key_handle *handle = NULL; ErlNifBinary data; ErlNifBinary signature; if (! enif_get_resource(env, argv[0], ec_key_resource, (void **)&handle)) return enif_make_badarg(env); if (! enif_inspect_iolist_as_binary(env, argv[1], &data)) return enif_make_badarg(env); if (! handle->key) return enif_make_tuple2(env, ATOM_ERROR, ATOM_UNINITIALIZED_KEY); length = ECDSA_size(handle->key); if (! enif_alloc_binary(length, &signature)) return ATOM_ERROR; if (! ECDSA_sign(0, data.data, data.size, signature.data, &length, handle->key)) return ATOM_ERROR; if (! enif_realloc_binary(&signature, length)) return ATOM_ERROR; return enif_make_binary(env, &signature); }
static ERL_NIF_TERM nif_ioctl(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { SRLY_STATE *sp = NULL; unsigned long req = 0; ErlNifBinary arg = {0}; if (!enif_get_resource(env, argv[0], SRLY_STATE_RESOURCE, (void **)&sp)) return enif_make_badarg(env); if (!enif_get_ulong(env, argv[1], &req)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[2], &arg)) return enif_make_badarg(env); /* Make the binary mutable for in/out args */ if (!enif_realloc_binary(&arg, arg.size)) return error_tuple(env, ENOMEM); if (ioctl(sp->fd, req, arg.data) < 0) return error_tuple(env, errno); return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &arg)); }
/** * NIFs */ inline void do_from_utf8( ErlNifBinary in, ErlNifBinary& out, int32_t& ulen, UErrorCode& status) { status = U_ZERO_ERROR; if (!enif_alloc_binary(FROM_ULEN(ulen), &out)) { status = U_MEMORY_ALLOCATION_ERROR; return; } u_strFromUTF8( (UChar*) out.data, /* dest */ ulen, /* capacity */ &ulen, /* len of result */ (char*) in.data, /* src */ (int32_t) in.size, /* len of src */ &status); /* error code */ if (U_FAILURE(status)) { enif_release_binary(&out); return; } if (FROM_ULEN(ulen) != out.size) { /* shrink binary if it was too large */ enif_realloc_binary(&out, FROM_ULEN(ulen)); } }
static ERL_NIF_TERM nif_sendmsg(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int s = -1; ErlNifBinary msg = {0}; int flags = 0; ssize_t n = 0; if (!enif_get_int(env, argv[0], &s)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[1], &msg)) return enif_make_badarg(env); if (!enif_get_int(env, argv[2], &flags)) return enif_make_badarg(env); if (msg.size != sizeof(struct msghdr)) return enif_make_badarg(env); /* Make the binary mutable */ if (!enif_realloc_binary(&msg, msg.size)) return error_tuple(env, ENOMEM); n = sendmsg(s, (const struct msghdr *)msg.data, flags); if (n < 0) return error_tuple(env, errno); return enif_make_tuple3(env, atom_ok, enif_make_ulong(env, n), enif_make_binary(env, &msg)); }
static ERL_NIF_TERM nif_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary dev; SRLY_STATE *sp = NULL; if (!enif_inspect_iolist_as_binary(env, argv[0], (ErlNifBinary *)&dev)) return enif_make_badarg(env); sp = enif_alloc_resource(SRLY_STATE_RESOURCE, sizeof(SRLY_STATE)); if (sp == NULL) return error_tuple(env, ENOMEM); if (!enif_realloc_binary(&dev, dev.size+1)) return enif_make_badarg(env); dev.data[dev.size-1] = '\0'; sp->fd = open((char *)dev.data, O_RDWR|O_NOCTTY|O_NONBLOCK); if (sp->fd < 0 || isatty(sp->fd) != 1) { int err = errno; enif_release_resource(sp); return error_tuple(env, err); } return enif_make_tuple2(env, atom_ok, enif_make_resource(env, sp)); }
inline void do_to_title( ErlNifBinary in, ErlNifBinary& out, int32_t& ulen, UBreakIterator* iter, const char* locale, UErrorCode& status) { status = U_ZERO_ERROR; if (!enif_alloc_binary(FROM_ULEN(ulen), &out)) { status = U_MEMORY_ALLOCATION_ERROR; return; } ulen = u_strToTitle( (UChar*) out.data, /* src */ ulen, /* len of src */ (UChar*) in.data, TO_ULEN(in.size), iter, /* Iterator */ locale, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { /* enlarge buffer if it was too small */ enif_release_binary(&out); return; } if (FROM_ULEN(ulen) != out.size) { /* shrink binary if it was too large */ enif_realloc_binary(&out, FROM_ULEN(ulen)); } }
static ERL_NIF_TERM nif_read(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { SRLY_STATE *sp = NULL; unsigned long len = 0; ErlNifBinary buf = {0}; ssize_t bufsz = 0; if (!enif_get_resource(env, argv[0], SRLY_STATE_RESOURCE, (void **)&sp)) return enif_make_badarg(env); if (!enif_get_ulong(env, argv[1], &len)) return enif_make_badarg(env); if (!enif_alloc_binary(len, &buf)) return error_tuple(env, ENOMEM); if ( (bufsz = read(sp->fd, buf.data, buf.size)) < 0) { int err = errno; enif_release_binary(&buf); return error_tuple(env, err); } if (bufsz < buf.size && !enif_realloc_binary(&buf, bufsz)) { enif_release_binary(&buf); return error_tuple(env, ENOMEM); } return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &buf)); }
inline void do_case( ErlNifBinary in, ErlNifBinary& out, int32_t& ulen, case_fun_ptr fun, const char* locale, UErrorCode& status) { status = U_ZERO_ERROR; if (!enif_alloc_binary(FROM_ULEN(ulen), &out)) { status = U_MEMORY_ALLOCATION_ERROR; return; } ulen = fun( (UChar*) out.data, /* src */ ulen, /* len of src */ (UChar*) in.data, TO_ULEN(in.size), locale, &status); if (U_FAILURE(status)) { enif_release_binary(&out); return; } if (FROM_ULEN(ulen) != out.size) { /* shrink binary if it was too large */ enif_realloc_binary(&out, FROM_ULEN(ulen)); } }
inline void do_to_utf8( ErlNifBinary in, ErlNifBinary& out, int32_t& len, UErrorCode& status) { status = U_ZERO_ERROR; if (!enif_alloc_binary(len, &out)) { status = U_MEMORY_ALLOCATION_ERROR; return; } u_strToUTF8( (char*) out.data, /* dest */ len, &len, (const UChar*) in.data, /* src */ TO_ULEN(in.size), /* len of src */ &status); if (U_FAILURE(status)) { enif_release_binary(&out); return; } if (len != (int32_t) out.size) { /* shrink binary if it was too large */ enif_realloc_binary(&out, len); } }
// int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); static ERL_NIF_TERM nif_getsockname(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int s = -1; ErlNifBinary addr = {0}; socklen_t addrlen = 0; if (!enif_get_int(env, argv[0], &s)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[1], &addr)) return enif_make_badarg(env); /* Make the binary mutable */ if (!enif_realloc_binary(&addr, addr.size)) return error_tuple(env, ENOMEM); addrlen = addr.size; if (getsockname(s, (struct sockaddr *)addr.data, (socklen_t *)&addrlen) < 0) return error_tuple(env, errno); PROCKET_REALLOC(addr, addrlen); return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &addr)); }
static ERL_NIF_TERM spi_data_rw_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int channel, len; ErlNifBinary buf; ERL_NIF_TERM atom_fail, err_code; if (!enif_get_int(env, argv[0], &channel) || !enif_inspect_binary(env, argv[1], &buf) || !enif_get_int(env, argv[2], &len)) { return enif_make_badarg(env); } enif_realloc_binary(&buf, len); int result = wiringPiSPIDataRW(channel, buf.data, len); if (result >= 0) { return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &buf)); } else { atom_fail = enif_make_atom(env, "failed_to_read_write_data"); err_code = enif_make_int(env, result); enif_release_binary(&buf); return enif_make_tuple2(env, atom_error, enif_make_tuple2(env, atom_fail, err_code)); } }
static void do_reserve(size_t sz, State *st){ size_t used = st->cur - st->bin.data; size_t t = st->bin.size * 2; while( t < used + sz ){ t *= 2; } enif_realloc_binary(&st->bin, t); st->cur = st->bin.data + used; }
static int per_realloc_memory(ErlNifBinary *binary, int amount, unsigned char **ptr) { int i = *ptr - binary->data; if (!enif_realloc_binary(binary, amount)) { /*error handling due to memory allocation failure */ return ASN1_ERROR; } else { *ptr = binary->data + i; } return ASN1_OK; }
/* 1: password, 2: dictpath */ static ERL_NIF_TERM nif_check(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { PRIV *priv = NULL; ErlNifBinary passwd; ErlNifBinary path; char *err = NULL; priv = (PRIV *)enif_priv_data(env); if (!enif_inspect_iolist_as_binary(env, argv[0], &passwd)) return enif_make_badarg(env); if (!enif_inspect_iolist_as_binary(env, argv[1], &path)) return enif_make_badarg(env); /* NULL terminate strings */ if (!enif_realloc_binary(&passwd, passwd.size+1)) return atom_enomem; if (!enif_realloc_binary(&path, path.size+1)) return atom_enomem; /* passwd.size is now equal to old passwd.size+1 */ passwd.data[passwd.size-1] = '\0'; path.data[path.size-1] = '\0'; enif_mutex_lock(priv->lock); err = (char *)FascistCheck((char *)passwd.data, (char *)path.data); enif_mutex_unlock(priv->lock); (void)memset(passwd.data, '\0', passwd.size); enif_release_binary(&passwd); enif_release_binary(&path); return ( (err == NULL) ? atom_ok : error_tuple(env, err)); }
int enc_result(Encoder* e, ERL_NIF_TERM* value) { if(e->i != e->curr->size) { if(!enif_realloc_binary(e->curr, e->i)) { return 0; } } *value = enif_make_binary(e->env, e->curr); e->curr = NULL; return 1; }
ErlNifBinary& GetBinary() { size_t allocated = bin.size; if (allocated > used) { if (!enif_realloc_binary(&bin, used)) { enif_release_binary(&bin); THROW_EXC("enif_realloc_binary() failed"); } } return bin; }
posix_errno_t efile_read_link(ErlNifEnv *env, const efile_path_t *path, ERL_NIF_TERM *result) { ErlNifBinary result_bin; if(!enif_alloc_binary(256, &result_bin)) { return ENOMEM; } for(;;) { ssize_t bytes_copied; bytes_copied = readlink((const char*)path->data, (char*)result_bin.data, result_bin.size); if(bytes_copied <= 0) { posix_errno_t saved_errno = errno; enif_release_binary(&result_bin); return saved_errno; } else if(bytes_copied < result_bin.size) { if(!enif_realloc_binary(&result_bin, bytes_copied)) { enif_release_binary(&result_bin); return ENOMEM; } (*result) = enif_make_binary(env, &result_bin); return 0; } /* The result didn't fit into the buffer, so we'll try again with a * larger one. */ if(!enif_realloc_binary(&result_bin, result_bin.size * 2)) { enif_release_binary(&result_bin); return ENOMEM; } } }
/** @brief Converts a native path to the preferred form in "erlang space," * without path-prefixes, forward-slashes, or NUL terminators. */ static int normalize_path_result(ErlNifBinary *path) { WCHAR *path_iterator, *path_start, *path_end; int length; path_start = (WCHAR*)path->data; length = wcslen(path_start); ASSERT(length < path->size / sizeof(WCHAR)); /* Get rid of the long-path prefix, if present. */ if(IS_LONG_UNC_PATH(length, path_start)) { /* The first two characters (\\) are the same for both long and short * UNC paths. */ sys_memmove(&path_start[2], &path_start[LP_UNC_PREFIX_LENGTH], (length - LP_UNC_PREFIX_LENGTH) * sizeof(WCHAR)); length -= LP_UNC_PREFIX_LENGTH - 2; } else if(IS_LONG_PATH(length, path_start)) { length -= LP_PREFIX_LENGTH; sys_memmove(path_start, &path_start[LP_PREFIX_LENGTH], length * sizeof(WCHAR)); } path_end = &path_start[length]; path_iterator = path_start; /* Convert drive letters to lowercase, if present. */ if(length >= 2 && path_start[1] == L':') { WCHAR drive_letter = path_start[0]; if(drive_letter >= L'A' && drive_letter <= L'Z') { path_start[0] = drive_letter - L'A' + L'a'; } } while(path_iterator < path_end) { if(*path_iterator == L'\\') { *path_iterator = L'/'; } path_iterator++; } /* Truncate the result to its actual length; we don't want to include the * NUL terminator. */ return enif_realloc_binary(path, length * sizeof(WCHAR)); }
char* GetAppendBuffer(size_t len, char*) { size_t allocated = bin.size; if ((used + len) > allocated) { size_t sz = len > ALLOC_SIZE ? len + ALLOC_SIZE - (len % ALLOC_SIZE) : ALLOC_SIZE; if (!enif_realloc_binary(&bin, allocated + sz)) { enif_release_binary(&bin); THROW_EXC("enif_realloc_binary() failed"); } } return reinterpret_cast<char*>(bin.data + used); }
static ERL_NIF_TERM patch_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { state_t *state = init_state(); if (!enif_inspect_iolist_as_binary(env, argv[0], &state->bin)) return enif_make_badarg(env); enif_realloc_binary(&state->bin, state->bin.size); state->job = rs_patch_begin((rs_copy_cb *) &read_callback, state); state->type = PATCH; ERL_NIF_TERM result = enif_make_resource(env, state); enif_release_resource(state); return result; }
static inline int enc_ensure(Encoder* e, size_t req) { size_t need = e->curr->size; while(req >= (need - e->i)) need <<= 1; if(need != e->curr->size) { if(!enif_realloc_binary(e->curr, need)) { return 0; } e->p = (char*) e->curr->data; e->u = (unsigned char*) e->curr->data; } return 1; }
//-- static ERL_NIF_TERM nif_compress(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary input; if(!enif_inspect_iolist_as_binary(env, argv[0], &input)) { return(enif_make_badarg(env)); } ErlNifBinary bin; // [rad] Figure out maximum compression buffer size. uint32_t compressed_bytes = wfLZ_GetMaxCompressedSize(input.size); // [rad] Get size of recommended scratchpad. uint32_t scratchpad_bytes = wfLZ_GetWorkMemSize(); if(!enif_alloc_binary(compressed_bytes, &bin)) { return(erlang_produce_error(env, "not_enough_memory")); } // [rad] Allocate scratchpad buffer. uint8_t* scratchpad = malloc(scratchpad_bytes); // [rad] Perform compression. uint32_t data_comp_size = wfLZ_Compress((const uint8_t* const) input.data, input.size, (uint8_t* const) bin.data, (const uint8_t*) scratchpad, 0); // [rad] We no longer need scratchpad. free(scratchpad); if(!data_comp_size) { return(erlang_produce_error(env, "compression_error")); } if(!enif_realloc_binary(&bin, data_comp_size)) { return(erlang_produce_error(env, "not_enough_memory")); } return(enif_make_binary(env, &bin)); }
/** @brief Converts a native path to the preferred form in "erlang space," * without path-prefixes, forward-slashes, or NUL terminators. */ static int normalize_path_result(ErlNifBinary *path) { WCHAR *path_iterator, *path_start, *path_end; int length; path_start = (WCHAR*)path->data; length = wcslen(path_start); ASSERT(length < path->size / sizeof(WCHAR)); /* Get rid of the long-path prefix, if present. */ if(length >= LP_PREFIX_LENGTH) { if(!sys_memcmp(path_start, LP_PREFIX, LP_PREFIX_SIZE)) { length -= LP_PREFIX_LENGTH; sys_memmove(path_start, &path_start[LP_PREFIX_LENGTH], length * sizeof(WCHAR)); } } path_end = &path_start[length]; path_iterator = path_start; /* Convert drive letters to lowercase, if present. */ if(length >= 2 && path_start[1] == L':') { WCHAR drive_letter = path_start[0]; if(drive_letter >= L'A' && drive_letter <= L'Z') { path_start[0] = drive_letter - L'A' + L'a'; } } while(path_iterator < path_end) { if(*path_iterator == L'\\') { *path_iterator = L'/'; } path_iterator++; } /* Truncate the result to its actual length; we don't want to include the * NUL terminator. */ return enif_realloc_binary(path, length * sizeof(WCHAR)); }
static ERL_NIF_TERM nif_pcap_compile(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { EWPCAP_STATE *ep = NULL; ErlNifBinary filter = {0}; int optimize = 0; u_int32_t netmask = 0; struct bpf_program fp = {0}; if (!enif_get_resource(env, argv[0], EWPCAP_RESOURCE, (void **)&ep) || ep->p == NULL) return enif_make_badarg(env); if (!enif_inspect_iolist_as_binary(env, argv[1], &filter)) return enif_make_badarg(env); if (!enif_get_int(env, argv[2], &optimize)) return enif_make_badarg(env); if (!enif_get_uint(env, argv[3], &netmask)) return enif_make_badarg(env); /* NULL terminate the filter */ if (!enif_realloc_binary(&filter, filter.size+1)) return enif_make_tuple2(env, atom_error, atom_enomem); filter.data[filter.size-1] = '\0'; if (pcap_compile(ep->p, &fp, (const char *)filter.data, optimize, netmask) != 0) return enif_make_tuple2(env, atom_error, enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1)); if (pcap_setfilter(ep->p, &fp) < 0) return enif_make_tuple2(env, atom_error, enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1)); return atom_ok; }
static int do_convert(ErlNifEnv* env, char *from, char *to, ErlNifBinary *string, ErlNifBinary *rstring) { char *stmp = (char *) string->data; char *rtmp = (char *) rstring->data; size_t outleft = rstring->size; size_t inleft = string->size; int invalid_utf8_as_latin1 = 0; iconv_t cd; /* Special mode: parse as UTF-8 if possible; otherwise assume it's Latin-1. Makes no difference when encoding. */ if (strcmp(from, "utf-8+latin-1") == 0) { from[5] = '\0'; invalid_utf8_as_latin1 = 1; } if (strcmp(to, "utf-8+latin-1") == 0) { to[5] = '\0'; } cd = iconv_open(to, from); if (cd == (iconv_t) -1) { if (enif_realloc_binary(rstring, string->size)) { memcpy(rstring->data, string->data, string->size); return OK; } else { return ERR_MEMORY_FAIL; } } while (inleft > 0) { if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) { if (invalid_utf8_as_latin1 && (*stmp & 0x80) && outleft >= 2) { /* Encode one byte of (assumed) Latin-1 into two bytes of UTF-8 */ *rtmp++ = 0xc0 | ((*stmp & 0xc0) >> 6); *rtmp++ = 0x80 | (*stmp & 0x3f); outleft -= 2; } stmp++; inleft--; } }