Example #1
0
    static ERL_NIF_TERM
nif_pcap_stats(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    EWPCAP_STATE *ep = NULL;
    struct pcap_stat ps = {0};

    if (!enif_get_resource(env, argv[0], EWPCAP_RESOURCE, (void **)&ep)
            || ep->p == NULL)
        return enif_make_badarg(env);

    if (pcap_stats(ep->p, &ps))
        return enif_make_tuple2(env,
                atom_error,
                enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1));

    return enif_make_tuple2(env,
            atom_ok,
            enif_make_tuple5(env,
                atom_ewpcap_stat,
                enif_make_uint(env, ps.ps_recv),
                enif_make_uint(env, ps.ps_drop),
                enif_make_uint(env, ps.ps_ifdrop),
#ifdef WIN32
                enif_make_uint(env, ps.bs_capt)
#else
                enif_make_uint(env, 0)
#endif
                ));
}
Example #2
0
static ERL_NIF_TERM macros(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    const ERL_NIF_TERM* a;
    ERL_NIF_TERM lists, tuples;
    int arity;
    if (!enif_get_tuple(env, argv[0], &arity, &a) || arity != 9) {
	return enif_make_badarg(env);
    }
    
    lists = enif_make_list(env,9,
			   enif_make_list1(env,a[0]),
			   enif_make_list2(env,a[0],a[1]),
			   enif_make_list3(env,a[0],a[1],a[2]),
			   enif_make_list4(env,a[0],a[1],a[2],a[3]),
			   enif_make_list5(env,a[0],a[1],a[2],a[3],a[4]),
			   enif_make_list6(env,a[0],a[1],a[2],a[3],a[4],a[5]),
			   enif_make_list7(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6]),
			   enif_make_list8(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]),
			   enif_make_list9(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]));
    tuples = enif_make_list(env,9,
			    enif_make_tuple1(env,a[0]),
			    enif_make_tuple2(env,a[0],a[1]),
			    enif_make_tuple3(env,a[0],a[1],a[2]),
			    enif_make_tuple4(env,a[0],a[1],a[2],a[3]),
			    enif_make_tuple5(env,a[0],a[1],a[2],a[3],a[4]),
			    enif_make_tuple6(env,a[0],a[1],a[2],a[3],a[4],a[5]),
			    enif_make_tuple7(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6]),
			    enif_make_tuple8(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]),
			    enif_make_tuple9(env,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]));
    return enif_make_tuple2(env,lists,tuples);
}
Example #3
0
static ERL_NIF_TERM make_strings(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    const char a0string[8] = {'a','0','s','t','r','i','n','g'};
    const char a0string0[9] = {'a','\0','s','t','r','i','n','g',0};
    const char astringwith8bits[37] = {'E','r','l','a','n','g',' ',0xE4 /* 'ä' */,'r',' ','e','t','t',' ','g','e','n','e','r','e','l','l','t',' ','p','r','o','g','r','a','m','s','p','r', 0xE5 /* 'å' */,'k',0};

    return enif_make_tuple5(env,
			    enif_make_string(env, "a0string", ERL_NIF_LATIN1),
			    enif_make_string_len(env, "a0string", 8, ERL_NIF_LATIN1),
			    enif_make_string_len(env, a0string, 8, ERL_NIF_LATIN1),
			    enif_make_string_len(env, a0string0, 9, ERL_NIF_LATIN1),
			    enif_make_string(env, astringwith8bits, ERL_NIF_LATIN1));
}
Example #4
0
// frame_to_tuple/1 :: (frame) -> {ok, {W, H, NChannels, ImageSize, ImageData}}
static ERL_NIF_TERM
frame_to_tuple(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  ERL_NIF_TERM result;
  frame_t* frame;
  if (!enif_get_resource(env, argv[0], frame_res, (void**) &frame)) {
    return enif_make_badarg(env);
  }
  ERL_NIF_TERM* arr = 
    (ERL_NIF_TERM*) malloc(sizeof(ERL_NIF_TERM) * frame->_frame->imageSize);
  int i;
  for (i = 0; i < frame->_frame->imageSize; i++) {
    arr[i] = enif_make_int(env, frame->_frame->imageData[i]);
  }
  ERL_NIF_TERM list = 
    enif_make_list_from_array(env, arr, frame->_frame->imageSize);
  result = enif_make_tuple5(env,
			    enif_make_int(env, frame->_frame->width),
			    enif_make_int(env, frame->_frame->height),
			    enif_make_int(env, frame->_frame->nChannels),
			    enif_make_int(env, frame->_frame->imageSize),
			    list);
  return result;
}
Example #5
0
ERL_NIF_TERM parse_buffer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
	Parser par;
	Parser* parser = &par;

	ErlNifBinary buffer;

	if(!enif_inspect_binary(env, argv[0], &buffer)) return enif_make_badarg(env);
	if(!init_parser(parser, env, argv[0], &buffer, argv[1])) return enif_make_badarg(env);

	ERL_NIF_TERM reply = argv[2];
	ERL_NIF_TERM return_value;

	parser->remaining_length = buffer.size;
	parser->pointer = buffer.data + parser->frame_start;

	while (parser->frame_start < parser->buffer_size) {
		
		parser->frame_size = D3I(parser->pointer);

		parser->pointer += 3;
		unsigned long seg_num = D1(parser->pointer);
		parser->pointer += 1;

		parser->remaining_length -= (parser->frame_size + 4);

		if (parser->remaining_length < 0) {
			return_value = enif_make_tuple3(env, 
				parser->atoms->atom_incomplete,
				reply, 
				enif_make_sub_binary(env, parser->raw, parser->frame_start, parser->buffer_size - parser->frame_start));

			break;
		}

		if (*parser->pointer == MYSQL_RESP_EOF) {
			ERL_NIF_TERM remaining_buffer = enif_make_sub_binary(env, parser->raw, parser->frame_start + parser->frame_size + 4, parser->remaining_length);

			if (parser->frame_size == 5) {
				unsigned long server_status = D2I(parser->pointer + 3);

				return_value = enif_make_tuple5(env, 
					parser->atoms->atom_eof,
					enif_make_uint(env, server_status), 
					enif_make_uint(env, seg_num), 
					reply,
					remaining_buffer);
			} 

			else return_value = enif_make_tuple4(env, 
					parser->atoms->atom_eof,
					enif_make_uint(env, seg_num),
					reply,
					remaining_buffer);

			break;

		}

		parser->frame_start += 4;

		ERL_NIF_TERM row = parse_line(parser);
		reply = enif_make_list_cell(env, row, reply);

		parser->frame_start += parser->frame_size;
		parser->pointer += parser->frame_size;
	}

	if (parser->frame_start >= parser->buffer_size) return_value = enif_make_tuple3(env, 
												parser->atoms->atom_incomplete,
												reply, 
												parser->atoms->atom_empty);

	destroy_parser(parser);
	return return_value;
}
Example #6
0
    static ERL_NIF_TERM
nif_recvmsg(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    int s = -1;
    ErlNifBinary buf = {0};
    ErlNifBinary src_addr = {0};
    char *ctrldata = NULL;
    ERL_NIF_TERM ctrldatalist;
    int flags = 0;
    unsigned long bufsize = 0;
    unsigned long ctrlsize = 0;
    unsigned long sasize = 0;

    struct iovec iov[1];
    struct msghdr message;
    struct cmsghdr *cmsg;

    ssize_t n = 0;

    if (!enif_get_int(env, argv[0], &s))
        return enif_make_badarg(env);

    if (!enif_get_ulong(env, argv[1], &bufsize))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[2], &flags))
        return enif_make_badarg(env);

    if (!enif_get_ulong(env, argv[3], &ctrlsize))
        return enif_make_badarg(env);

    if (!enif_get_ulong(env, argv[4], &sasize))
        return enif_make_badarg(env);

    if (!enif_alloc_binary(bufsize, &buf))
        return error_tuple(env, ENOMEM);

    if (ctrlsize > 0 && !(ctrldata = malloc(ctrlsize))) {
        enif_release_binary(&buf);
        return error_tuple(env, ENOMEM);
    }

    if (!enif_alloc_binary(sasize, &src_addr)) {
        enif_release_binary(&buf);
        free(ctrldata);
        return error_tuple(env, ENOMEM);
    }

    iov[0].iov_base = (buf.size == 0 ? NULL : buf.data);
    iov[0].iov_len=buf.size;

    message.msg_name = (src_addr.size == 0 ? NULL : src_addr.data);
    message.msg_namelen=src_addr.size;
    message.msg_iov=iov;
    message.msg_iovlen=1;
    message.msg_control=ctrldata;
    message.msg_controllen=ctrlsize;

    n = recvmsg(s, &message, flags);

    if (n < 0) {
        int err = errno;
        enif_release_binary(&buf);
        enif_release_binary(&src_addr);
        free(ctrldata);
        return error_tuple(env, err);
    }

    /* resize the binary to the actual size of the received packet
     *
     * XXX On error, the macro will return ENOMEM here, leaking buf,
     * XXX src_addr and ctrldata. Since the VM has OOM'ed, it will probably
     * XXX crash anyway.
     */
    PROCKET_REALLOC(buf, n);
    PROCKET_REALLOC(src_addr, message.msg_namelen);

    ctrldatalist = enif_make_list(env, 0);

    for (cmsg = CMSG_FIRSTHDR(&message); cmsg != NULL;
            cmsg = CMSG_NXTHDR(&message, cmsg)) {
        size_t len = cmsg->cmsg_len - CMSG_LEN(0);
        ErlNifBinary cdata = {0};

        if (!enif_alloc_binary(len, &cdata)) {
            enif_release_binary(&buf);
            enif_release_binary(&src_addr);
            free(ctrldata);
            return error_tuple(env, ENOMEM);
        }

        memcpy(cdata.data, CMSG_DATA(cmsg), len);

        ctrldatalist = enif_make_list_cell(env,
                enif_make_tuple3(env,
                    enif_make_int(env, cmsg->cmsg_level),
                    enif_make_int(env, cmsg->cmsg_type),
                    enif_make_binary(env, &cdata)), ctrldatalist);
    }

    free(ctrldata);

    return enif_make_tuple5(env,
            atom_ok,
            enif_make_binary(env, &buf), /* Data packet */
            enif_make_int(env, message.msg_flags), /* the message flags, eg. MSG_EOR, MSG_OOB, etc. */
            ctrldatalist, /* array of 3-tuples of {cmsg->cmsg_level, cmsg->cmsg_type, cmsg->cmsg_data} */
            enif_make_binary(env, &src_addr) /* source address, as a sockaddr_storage */
            );
}
Example #7
0
ERL_NIF_TERM
decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    Decoder* d;
    jiffy_st* st = (jiffy_st*) enif_priv_data(env);

    ErlNifBinary bin;

    ERL_NIF_TERM objs;
    ERL_NIF_TERM curr;
    ERL_NIF_TERM val = argv[2];
    ERL_NIF_TERM trailer;
    ERL_NIF_TERM ret;
    size_t bytes_read = 0;

    if(argc != 5) {
        return enif_make_badarg(env);
    } else if(!enif_inspect_binary(env, argv[0], &bin)) {
        return enif_make_badarg(env);
    } else if(!enif_get_resource(env, argv[1], st->res_dec, (void**) &d)) {
        return enif_make_badarg(env);
    } else if(!enif_is_list(env, argv[3])) {
        return enif_make_badarg(env);
    } else if(!enif_is_list(env, argv[4])) {
        return enif_make_badarg(env);
    }

    dec_init(d, env, argv[0], &bin);
    objs = argv[3];
    curr = argv[4];

    while(d->i < bin.size) {
        if(should_yield(env, &bytes_read, d->bytes_per_red)) {
            return enif_make_tuple5(
                    env,
                    st->atom_iter,
                    argv[1],
                    val,
                    objs,
                    curr
                );
        }

        bytes_read += 1;

        switch(dec_curr(d)) {
            case st_value:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case 'n':
                        if(d->i + 3 >= d->len) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        if(memcmp(&(d->p[d->i]), "null", 4) != 0) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        val = d->null_term;
                        dec_pop(d, st_value);
                        d->i += 4;
                        break;
                    case 't':
                        if(d->i + 3 >= d->len) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        if(memcmp(&(d->p[d->i]), "true", 4) != 0) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        val = d->atoms->atom_true;
                        dec_pop(d, st_value);
                        d->i += 4;
                        break;
                    case 'f':
                        if(d->i + 4 >= bin.size) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        if(memcmp(&(d->p[d->i]), "false", 5) != 0) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        val = d->atoms->atom_false;
                        dec_pop(d, st_value);
                        d->i += 5;
                        break;
                    case '\"':
                        if(!dec_string(d, &val)) {
                            ret = dec_error(d, "invalid_string");
                            goto done;
                        }
                        dec_pop(d, st_value);
                        break;
                    case '-':
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        if(!dec_number(d, &val)) {
                            ret = dec_error(d, "invalid_number");
                            goto done;
                        }
                        dec_pop(d, st_value);
                        break;
                    case '{':
                        dec_push(d, st_object);
                        dec_push(d, st_key);
                        objs = enif_make_list_cell(env, curr, objs);
                        curr = enif_make_list(env, 0);
                        d->i++;
                        break;
                    case '[':
                        dec_push(d, st_array);
                        dec_push(d, st_value);
                        objs = enif_make_list_cell(env, curr, objs);
                        curr = enif_make_list(env, 0);
                        d->i++;
                        break;
                    case ']':
                        if(!enif_is_empty_list(env, curr)) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_value);
                        if(dec_curr(d) != st_array) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_array);
                        dec_pop(d, st_value);
                        val = curr; // curr is []
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                if(dec_top(d) == 0) {
                    dec_push(d, st_done);
                } else if(dec_curr(d) != st_value && dec_curr(d) != st_key) {
                    dec_push(d, st_comma);
                    curr = enif_make_list_cell(env, val, curr);
                }
                break;

            case st_key:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case '\"':
                        if(!dec_string(d, &val)) {
                            ret = dec_error(d, "invalid_string");
                            goto done;
                        }
                        dec_pop(d, st_key);
                        dec_push(d, st_colon);
                        curr = enif_make_list_cell(env, val, curr);
                        break;
                    case '}':
                        if(!enif_is_empty_list(env, curr)) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_key);
                        dec_pop(d, st_object);
                        dec_pop(d, st_value);
                        val = make_empty_object(env, d->return_maps);
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        if(dec_top(d) == 0) {
                            dec_push(d, st_done);
                        } else {
                            dec_push(d, st_comma);
                            curr = enif_make_list_cell(env, val, curr);
                        }
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                break;

            case st_colon:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case ':':
                        dec_pop(d, st_colon);
                        dec_push(d, st_value);
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                break;

            case st_comma:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case ',':
                        dec_pop(d, st_comma);
                        switch(dec_curr(d)) {
                            case st_object:
                                dec_push(d, st_key);
                                break;
                            case st_array:
                                dec_push(d, st_value);
                                break;
                            default:
                                ret = dec_error(d, "internal_error");
                                goto done;
                        }
                        d->i++;
                        break;
                    case '}':
                        dec_pop(d, st_comma);
                        if(dec_curr(d) != st_object) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_object);
                        dec_pop(d, st_value);
                        if(!make_object(env, curr, &val,
                                d->return_maps, d->dedupe_keys)) {
                            ret = dec_error(d, "internal_object_error");
                            goto done;
                        }
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        if(dec_top(d) > 0) {
                            dec_push(d, st_comma);
                            curr = enif_make_list_cell(env, val, curr);
                        } else {
                            dec_push(d, st_done);
                        }
                        d->i++;
                        break;
                    case ']':
                        dec_pop(d, st_comma);
                        if(dec_curr(d) != st_array) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_array);
                        dec_pop(d, st_value);
                        val = make_array(env, curr);
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        if(dec_top(d) > 0) {
                            dec_push(d, st_comma);
                            curr = enif_make_list_cell(env, val, curr);
                        } else {
                            dec_push(d, st_done);
                        }
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                break;

            case st_done:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    default:
                        goto decode_done;
                }
                break;

            default:
                ret = dec_error(d, "invalid_internal_state");
                goto done;
        }
    }

decode_done:

    if(d->i < bin.size && d->return_trailer) {
        trailer = enif_make_sub_binary(env, argv[0], d->i, bin.size - d->i);
        val = enif_make_tuple3(env, d->atoms->atom_has_trailer, val, trailer);
    } else if(d->i < bin.size) {
        ret = dec_error(d, "invalid_trailing_data");
        goto done;
    }

    if(dec_curr(d) != st_done) {
        ret = dec_error(d, "truncated_json");
    } else if(d->is_partial) {
        ret = enif_make_tuple2(env, d->atoms->atom_partial, val);
    } else {
        ret = val;
    }

done:
    return ret;
}