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};
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
	char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
	int headerlength;

	if (ei_decode_string_or_binary(buf->buff, &buf->index, SWITCH_UUID_FORMATTED_LENGTH, uuid) ||
		ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "error");
		ei_x_encode_atom(rbuf, "badarg");
	} else {
		switch_core_session_t *session;
		if (!zstr_buf(uuid) && (session = switch_core_session_locate(uuid))) {
			switch_event_t *event;
			if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) {

				char key[1024];
				char value[1024];
				int i = 0;
				switch_bool_t fail = SWITCH_FALSE;
				while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
					i++;
					if (ei_decode_string(buf->buff, &buf->index, key) || ei_decode_string(buf->buff, &buf->index, value)) {
						fail = SWITCH_TRUE;
						break;
					}
					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
				}

				if (headerlength != i || fail) {
					ei_x_encode_tuple_header(rbuf, 2);
					ei_x_encode_atom(rbuf, "error");
					ei_x_encode_atom(rbuf, "badarg");
				} else {
					if (switch_core_session_queue_private_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
						ei_x_encode_atom(rbuf, "ok");
					} else {
						ei_x_encode_tuple_header(rbuf, 2);
						ei_x_encode_atom(rbuf, "error");
						ei_x_encode_atom(rbuf, "badmem");
					}

				}
			}
			/* release the lock returned by session locate */
			switch_core_session_rwunlock(session);

		} else {
			ei_x_encode_tuple_header(rbuf, 2);
			ei_x_encode_atom(rbuf, "error");
			ei_x_encode_atom(rbuf, "nosession");
		}
	}
	return SWITCH_STATUS_SUCCESS;
}
Beispiel #4
0
static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
	char ename[MAXATOMLEN + 1];
	char esname[MAXATOMLEN + 1];
	int headerlength;

	memset(esname, 0, MAXATOMLEN);

	if (ei_decode_atom(buf->buff, &buf->index, ename) ||
		(!strncasecmp(ename, "CUSTOM", MAXATOMLEN) &&
		 ei_decode_atom(buf->buff, &buf->index, esname)) || ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "error");
		ei_x_encode_atom(rbuf, "badarg");
	} else {
		switch_event_types_t etype;
		if (switch_name_event(ename, &etype) == SWITCH_STATUS_SUCCESS) {
			switch_event_t *event;
			if ((strlen(esname) && switch_event_create_subclass(&event, etype, esname) == SWITCH_STATUS_SUCCESS) ||
				switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) {
				char key[1024];
				char value[1024];
				int i = 0;
				switch_bool_t fail = SWITCH_FALSE;

				while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
					i++;
					if (ei_decode_string(buf->buff, &buf->index, key) || ei_decode_string(buf->buff, &buf->index, value)) {
						fail = SWITCH_TRUE;
						break;
					}

					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
				}

				if (headerlength != i || fail) {
					ei_x_encode_tuple_header(rbuf, 2);
					ei_x_encode_atom(rbuf, "error");
					ei_x_encode_atom(rbuf, "badarg");
				} else {
					switch_event_fire(&event);
					ei_x_encode_atom(rbuf, "ok");
				}
			}
		}
	}
	return SWITCH_STATUS_SUCCESS;
}
int ei_decode_string_or_binary(char *buf, int *index, int maxlen, char *dst)
{
	int type, size, res;
	long len;

	ei_get_type(buf, index, &type, &size);

	if (type == ERL_NIL_EXT || size == 0) {
		dst[0] = '\0';
		return 0;
	}

	if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT) {
		return -1;
	} else if (size > maxlen) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of %s with size %d into a buffer of size %d\n",
						  type == ERL_BINARY_EXT ? "binary" : "string", size, maxlen);
		return -1;
	} else if (type == ERL_BINARY_EXT) {
		res = ei_decode_binary(buf, index, dst, &len);
		dst[len] = '\0';		/* binaries aren't null terminated */
	} else {
		res = ei_decode_string(buf, index, dst);
	}

	return res;
}
Beispiel #6
0
/**
 * Decode string/binary into destination buffer.
 *
 */
int ei_decode_strorbin(char *buf, int *index, int maxlen, char *dst)
{
	int type, size, res;
	long len;

	ei_get_type(buf, index, &type, &size);

	if (type == ERL_NIL_EXT || size == 0)
	{
		dst[0] = '\0';
		return 0;
	}

	if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT)
	{
		return -1;
	}
	else if (size > maxlen)
	{
		LM_ERR("buffer size %d too small for %s with size %d\n",
				maxlen, type == ERL_BINARY_EXT ? "binary" : "string", size);
		return -1;
	}
	else if (type == ERL_BINARY_EXT)
	{
		res = ei_decode_binary(buf, index, dst, &len);
		dst[len] = '\0';
	}
	else
	{
		res = ei_decode_string(buf, index, dst);
	}

	return res;
}
Beispiel #7
0
int next_string(GEOSCommand *command, char **data) {
        char *buffer = command->param_bytes;
        int *index = &command->index;
        int type;
        int size;

        if(ei_get_type(buffer, index, &type, &size)) {
                return -1;
        }

        if(type != ERL_STRING_EXT && type != ERL_BINARY_EXT) {
                return 1;
        }
        char* sdata = (char *) malloc(size);

	if(sdata == NULL) {
		return -1;
	}
        if(type == ERL_STRING_EXT) {
                if(ei_decode_string(buffer, index, sdata)) {
                        free(sdata);
                        return -1;
                }
        } else {
		long s;
                if(ei_decode_binary(buffer, index, sdata, &s)) {
                        free(sdata); return -1;
                }
        }
	*data = sdata;
        return 0;
}
int ei_decode_string_or_binary(char *buf, int *index, char **dst) {
    int type, size, res;
    long len;

    ei_get_type(buf, index, &type, &size);

    if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_NIL_EXT) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size);
        return -1;
    }

	*dst = malloc(size + 1);

	if (type == ERL_NIL_EXT) {
		res = 0;
		**dst = '\0';
	} else if (type == ERL_BINARY_EXT) {
        res = ei_decode_binary(buf, index, *dst, &len);
        (*dst)[len] = '\0';
    } else {
        res = ei_decode_string(buf, index, *dst);
    }

    return res;
}
Beispiel #9
0
void do_addstr(state *st) {
  int arity;
  long strlen;
  ei_decode_tuple_header(st->args, &(st->index), &arity);
  ei_decode_long(st->args, &(st->index), &strlen);
  char str[strlen];
  ei_decode_string(st->args, &(st->index), str);
  encode_ok_reply(st, addnstr(str, strlen));
}
Beispiel #10
0
	QByteArray toArray() const
	{
		int idx = _index; QByteArray a(_size, 0);
		if (isAtom())
			ei_decode_atom(_buf, &idx, a.data());
		else
			ei_decode_string(_buf, &idx, a.data());

		return a;
	}
Beispiel #11
0
void do_mvaddstr(state *st) {
  int arity;
  long strlen, y, x;
  ei_decode_tuple_header(st->args, &(st->index), &arity);
  ei_decode_long(st->args, &(st->index), &y);
  ei_decode_long(st->args, &(st->index), &x);
  ei_decode_long(st->args, &(st->index), &strlen);
  char str[strlen];
  ei_decode_string(st->args, &(st->index), str);
  encode_ok_reply(st, mvaddnstr((int)y, (int)x, str, (int)strlen));
}
Beispiel #12
0
static char*
decode_string(const char *buf, int *index)
{
  int type, length;
  char *str;

  ei_get_type(buf, index, &type, &length);
  str = malloc(sizeof(char) * (length + 1));
  ei_decode_string(buf, index, str);
  return str;
}
Beispiel #13
0
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;
    }
}
Beispiel #14
0
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);
}
Beispiel #15
0
static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
	char api_cmd[MAXATOMLEN];
	char arg[1024];
	if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string(buf->buff, &buf->index, arg)) {
		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "error");
		ei_x_encode_atom(rbuf, "badarg");
		return SWITCH_STATUS_SUCCESS;
	} else {
		struct api_command_struct acs = { 0 };
		acs.listener = listener;
		acs.api_cmd = api_cmd;
		acs.arg = arg;
		acs.bg = 0;
		acs.pid = msg->from;
		api_exec(NULL, (void *) &acs);
		/* don't reply */
		return SWITCH_STATUS_FALSE;
	}
}
Beispiel #16
0
static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
	char api_cmd[MAXATOMLEN];
	char arg[1024];
	if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string(buf->buff, &buf->index, arg)) {
		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "error");
		ei_x_encode_atom(rbuf, "badarg");
	} else {
		struct api_command_struct *acs = NULL;
		switch_memory_pool_t *pool;
		switch_thread_t *thread;
		switch_threadattr_t *thd_attr = NULL;
		switch_uuid_t uuid;

		switch_core_new_memory_pool(&pool);
		acs = switch_core_alloc(pool, sizeof(*acs));
		switch_assert(acs);
		acs->pool = pool;
		acs->listener = listener;
		acs->api_cmd = switch_core_strdup(acs->pool, api_cmd);
		acs->arg = switch_core_strdup(acs->pool, arg);
		acs->bg = 1;
		acs->pid = msg->from;

		switch_threadattr_create(&thd_attr, acs->pool);
		switch_threadattr_detach_set(thd_attr, 1);
		switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);

		switch_uuid_get(&uuid);
		switch_uuid_format(acs->uuid_str, &uuid);
		switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool);

		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "ok");
		_ei_x_encode_string(rbuf, acs->uuid_str);
	}
	return SWITCH_STATUS_SUCCESS;
}
/**
 * @brief Decode a string from Erlang that was either encoded as a list of characters (Erlang)
 *        or as a binary (Elixir). This function also checks the length of the string.
 * @param buf the request
 * @param index the index into the request
 * @param dest where to store the response
 * @param maxlength the length of the destination
 * @return -1 on error; 0 on success
 */
int erlcmd_decode_string(const char *buf, int *index, char *dest, int maxlength)
{
    int type;
    int size;
    if (ei_get_type(buf, index, &type, &size) < 0)
        return -1;

    if (type == ERL_STRING_EXT) {
        if (size + 1 > maxlength)
            return -1;

        return ei_decode_string(buf, index, dest);
    } else if (type == ERL_BINARY_EXT) {
        if (size + 1 > maxlength)
            return -1;

        dest[size] = '\0';
        long unused;
        return ei_decode_binary(buf, index, dest, &unused);
    } else
        return -1;
}
Beispiel #18
0
bool decodeBinary(char* erlBuf, int* pIndex, char* outBuf, int bufLen, long* outLen)
{
    int type, size;
    long long integerValue = 0;
    double doubleValue = 0;

    ei_get_type(erlBuf, pIndex, &type, &size);

    if (bufLen >= size && ei_decode_binary(erlBuf, pIndex, outBuf, outLen) == 0) {
    } else if (bufLen > size && ei_decode_string(erlBuf, pIndex, outBuf) == 0) {
        *outLen = strlen(outBuf);
    } else if (ei_decode_longlong(erlBuf, pIndex, &integerValue) == 0) {
        snprintf(outBuf, bufLen, "%lld", integerValue);
        *outLen = strlen(outBuf);
    } else if (ei_decode_double(erlBuf, pIndex, &doubleValue) == 0) {
        snprintf(outBuf, bufLen, "%lf", doubleValue);
        *outLen = strlen(outBuf);
    } else {
        return false;
    }

    return true;
}
Beispiel #19
0
bool decodeDouble(char* erlBuf, int* pIndex, double* outValue)
{
    long len = 0;
    int type, size;
    long long integerValue = 0;
    char strValue[64];

    if(ei_decode_double(erlBuf, pIndex, outValue) == 0) {
    } else if (ei_decode_longlong(erlBuf, pIndex, &integerValue) == 0) {
        *outValue = (double)integerValue;
    } else if (ei_get_type(erlBuf, pIndex, &type, &size) == 0 && size < 64){
        if (ei_decode_string(erlBuf, pIndex, strValue) == 0) {
        } else if (ei_decode_binary(erlBuf, pIndex, strValue, &len) == 0) {
            strValue[len] = '\0';
        }
        if (sscanf(strValue, "%lf", outValue) < 1) {
            return false;
        }
    } else {
        return false;
    }

    return true;
}
Beispiel #20
0
static ErlDrvSSizeT iconv_erl_control(ErlDrvData drv_data,
			     unsigned int command,
			     char *buf, ErlDrvSizeT len,
			     char **rbuf, ErlDrvSizeT 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;
   int invalid_utf8_as_latin1 = 0;

   ei_decode_version(buf, &index, &i);
   ei_decode_tuple_header(buf, &index, &i);
   ei_get_type(buf, &index, &i, &size);
   from = driver_alloc(size + 1); 
   ei_decode_string(buf, &index, from);

   ei_get_type(buf, &index, &i, &size);
   to = driver_alloc(size + 1); 
   ei_decode_string(buf, &index, to);
  
   ei_get_type(buf, &index, &i, &size);
   stmp = string = driver_alloc(size + 1); 
   ei_decode_string(buf, &index, string);

   /* 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) {
      cd = iconv_open("ascii", "ascii");
      if (cd == (iconv_t) -1) {
	 *rbuf = (char*)(b = driver_alloc_binary(size));
	 memcpy(b->orig_bytes, string, size);

	 driver_free(from);
	 driver_free(to);
	 driver_free(string);

	 return size;
      }
   }
   
   outleft = avail = 4*size;
   inleft = size;
   rtmp = rstring = driver_alloc(avail);
   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--;
      }
   }
Beispiel #21
0
int main(void)
#endif
{
  ErlConnect conp;
  Erl_IpAddr thisipaddr = (Erl_IpAddr)0;
  FILE *fp = (FILE *)0;
  char* charp = "foo";
  double *doublep = NULL;
  double doublex = 0.0;
  ei_cnode xec;
  ei_reg *ei_regp = NULL;
  ei_term eterm;
  ei_x_buff eix;
  erlang_big *bigp = NULL;
  erlang_fun efun;
  erlang_msg *msgp = NULL;
  erlang_msg emsg;
  erlang_pid *pidp = NULL;
  erlang_pid epid;
  erlang_port eport;
  erlang_ref eref;
  erlang_trace etrace;
  int *intp = NULL;
  int intx = 0;
  long *longp = NULL;
  long longx = 0;
  short creation = 0;
  struct ei_reg_stat *ei_reg_statp = NULL;
  struct ei_reg_tabstat *ei_reg_tabstatp = NULL;
  struct hostent *hostp = NULL;
  unsigned char * ucharp = (unsigned char *)"foo";
  unsigned long *ulongp = NULL;
  unsigned long ulongx = 0;
  void *voidp = NULL;
#ifndef VXWORKS
  EI_LONGLONG *longlongp = (EI_LONGLONG*)NULL;
  EI_LONGLONG longlongx = 0;
  EI_ULONGLONG *ulonglongp = (EI_ULONGLONG*)NULL;
  EI_ULONGLONG ulonglongx = 0;
#endif
  enum erlang_char_encoding enc;

  intx = erl_errno;

  ei_connect_init(&xec, charp, charp, creation);
  ei_connect_xinit (&xec, charp, charp, charp, thisipaddr, charp, creation);

  ei_connect(&xec, charp);
  ei_xconnect (&xec, thisipaddr, charp);

  ei_receive(intx, ucharp, intx);
  ei_receive_msg(intx, &emsg, &eix);
  ei_xreceive_msg(intx, &emsg, &eix);

  ei_send(intx, &epid, charp, intx);
  ei_reg_send(&xec, intx, charp, charp, intx);

  ei_rpc(&xec, intx, charp, charp, charp, intx, &eix);
  ei_rpc_to(&xec, intx, charp, charp, charp, intx);
  ei_rpc_from(&xec, intx, intx, &emsg, &eix);

  ei_publish(&xec, intx);
  ei_accept(&xec, intx, &conp);
  ei_unpublish(&xec);

  ei_thisnodename(&xec);
  ei_thishostname(&xec);
  ei_thisalivename(&xec);

  ei_self(&xec);

  ei_gethostbyname(charp);
  ei_gethostbyaddr(charp, intx, intx);
  ei_gethostbyname_r(charp, hostp, charp, intx, intp);
  ei_gethostbyaddr_r(charp, intx, intx, hostp, charp, intx, intp);

  ei_encode_version(charp, intp);
  ei_x_encode_version(&eix);
  ei_encode_long(charp, intp, longx);
  ei_x_encode_long(&eix, longx);
  ei_encode_ulong(charp, intp, ulongx);
  ei_x_encode_ulong(&eix, ulongx);
  ei_encode_double(charp, intp, doublex);
  ei_x_encode_double(&eix, doublex);
  ei_encode_boolean(charp, intp, intx);
  ei_x_encode_boolean(&eix, intx);
  ei_encode_char(charp, intp, 'a');
  ei_x_encode_char(&eix, 'a');
  ei_encode_string(charp, intp, charp);
  ei_encode_string_len(charp, intp, charp, intx);
  ei_x_encode_string(&eix, charp);
  ei_x_encode_string_len(&eix, charp, intx);
  ei_encode_atom(charp, intp, charp);
  ei_encode_atom_as(charp, intp, charp, ERLANG_LATIN1, ERLANG_UTF8);
  ei_encode_atom_len(charp, intp, charp, intx);
  ei_encode_atom_len_as(charp, intp, charp, intx, ERLANG_ASCII, ERLANG_LATIN1);
  ei_x_encode_atom(&eix, charp);
  ei_x_encode_atom_as(&eix, charp, ERLANG_LATIN1, ERLANG_UTF8);
  ei_x_encode_atom_len(&eix, charp, intx);
  ei_x_encode_atom_len_as(&eix, charp, intx, ERLANG_LATIN1, ERLANG_UTF8);
  ei_encode_binary(charp, intp, (void *)0, longx);
  ei_x_encode_binary(&eix, (void*)0, intx);
  ei_encode_pid(charp, intp, &epid);
  ei_x_encode_pid(&eix, &epid);
  ei_encode_fun(charp, intp, &efun);
  ei_x_encode_fun(&eix, &efun);
  ei_encode_port(charp, intp, &eport);
  ei_x_encode_port(&eix, &eport);
  ei_encode_ref(charp, intp, &eref);
  ei_x_encode_ref(&eix, &eref);
  ei_encode_trace(charp, intp, &etrace);
  ei_x_encode_trace(&eix, &etrace);
  ei_encode_tuple_header(charp, intp, intx);
  ei_x_encode_tuple_header(&eix, longx);
  ei_encode_list_header(charp, intp, intx);
  ei_x_encode_list_header(&eix, longx);
/* #define ei_encode_empty_list(buf,i) ei_encode_list_header(buf,i,0) */
  ei_x_encode_empty_list(&eix);

  ei_get_type(charp, intp, intp, intp);
  ei_get_type_internal(charp, intp, intp, intp);

  ei_decode_version(charp, intp, intp);
  ei_decode_long(charp, intp, longp);
  ei_decode_ulong(charp, intp, ulongp);
  ei_decode_double(charp, intp, doublep);
  ei_decode_boolean(charp, intp, intp);
  ei_decode_char(charp, intp, charp);
  ei_decode_string(charp, intp, charp);
  ei_decode_atom(charp, intp, charp);
  ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_WHATEVER, &enc, &enc);
  ei_decode_binary(charp, intp, (void *)0, longp);
  ei_decode_fun(charp, intp, &efun);
  free_fun(&efun);
  ei_decode_pid(charp, intp, &epid);
  ei_decode_port(charp, intp, &eport);
  ei_decode_ref(charp, intp, &eref);
  ei_decode_trace(charp, intp, &etrace);
  ei_decode_tuple_header(charp, intp, intp);
  ei_decode_list_header(charp, intp, intp);

  ei_decode_ei_term(charp, intp, &eterm);

  ei_print_term(fp, charp, intp);
  ei_s_print_term(&charp, charp, intp);

  ei_x_format(&eix, charp);
  ei_x_format_wo_ver(&eix, charp);

  ei_x_new(&eix);
  ei_x_new_with_version(&eix);
  ei_x_free(&eix);
  ei_x_append(&eix, &eix);
  ei_x_append_buf(&eix, charp, intx);
  ei_skip_term(charp, intp);

  ei_reg_open(intx);
  ei_reg_resize(ei_regp, intx);
  ei_reg_close(ei_regp);

  ei_reg_setival(ei_regp, charp, longx);
  ei_reg_setfval(ei_regp, charp, doublex);
  ei_reg_setsval(ei_regp, charp, charp);
  ei_reg_setpval(ei_regp, charp, voidp, intx);

  ei_reg_setval(ei_regp, charp, intx);

  ei_reg_getival(ei_regp, charp);
  ei_reg_getfval(ei_regp, charp);
  ei_reg_getsval(ei_regp, charp);
  ei_reg_getpval(ei_regp, charp, intp);

  ei_reg_getval(ei_regp, charp, intx);

  ei_reg_markdirty(ei_regp, charp);

  ei_reg_delete(ei_regp, charp);

  ei_reg_stat(ei_regp, charp, ei_reg_statp);

  ei_reg_tabstat(ei_regp, ei_reg_tabstatp);

  ei_reg_dump(intx, ei_regp, charp, intx);
  ei_reg_restore(intx, ei_regp, charp);
  ei_reg_purge(ei_regp);

#if defined(HAVE_GMP_H) && defined(HAVE_LIBGMP)
  {
      mpz_t obj;
      ei_decode_bignum(charp, intp, obj);
      ei_encode_bignum(charp, intp, obj);
      ei_x_encode_bignum(&eix, obj);
  }
#endif /* HAVE_GMP_H && HAVE_LIBGMP */

#ifndef VXWORKS

  ei_decode_longlong(charp, intp, longlongp);
  ei_decode_ulonglong(charp, intp, ulonglongp);
  ei_encode_longlong(charp, intp, longlongx);
  ei_encode_ulonglong(charp, intp, ulonglongx);
  ei_x_encode_longlong(&eix, longlongx);
  ei_x_encode_ulonglong(&eix, ulonglongx);

#endif

#ifdef USE_EI_UNDOCUMENTED

  ei_decode_intlist(charp, intp, longp, intp);

  ei_receive_encoded(intx, &charp, intp, msgp, intp);
  ei_send_encoded(intx, pidp, charp, intx);
  ei_send_reg_encoded(intx, pidp, charp, charp, intx);

  ei_decode_big(charp, intp, bigp);
  ei_big_comp(bigp, bigp);
  ei_big_to_double(bigp, doublep);
  ei_small_to_big(intx, bigp);
  ei_alloc_big(intx);
  ei_free_big(bigp);

#endif /* USE_EI_UNDOCUMENTED */

  return
      BUFSIZ +
      EAGAIN +
      EHOSTUNREACH +
      EIO +
      EI_BIN +
      EI_DELET +
      EI_DIRTY +
      EI_FLT +
      EI_FORCE +
      EI_INT +
      EI_NOPURGE +
      EI_STR +
      EMSGSIZE +
      ENOMEM +
      ERL_ERROR +
      ERL_EXIT +
      ERL_LINK +
      ERL_MSG +
      ERL_NO_TIMEOUT +
      ERL_REG_SEND +
      ERL_SEND +
      ERL_TICK +
      ERL_TIMEOUT +
      ERL_UNLINK +
      ETIMEDOUT +
      MAXATOMLEN;
}
Beispiel #22
0
int ei_skip_term(const char* buf, int* index)
{
    int i, n, ty;

    /* ASSERT(ep != NULL); */

    ei_get_type_internal(buf, index, &ty, &n);
    switch (ty) {
    case ERL_ATOM_EXT:
	/* FIXME: what if some weird locale is in use? */
	if (ei_decode_atom_as(buf, index, NULL, MAXATOMLEN_UTF8, (ERLANG_LATIN1|ERLANG_UTF8),
			      NULL, NULL) < 0) return -1;
	break;
    case ERL_PID_EXT:
    case ERL_NEW_PID_EXT:
	if (ei_decode_pid(buf, index, NULL) < 0) return -1;
	break;
    case ERL_PORT_EXT:
    case ERL_NEW_PORT_EXT:
	if (ei_decode_port(buf, index, NULL) < 0) return -1;
	break;
    case ERL_NEW_REFERENCE_EXT:
    case ERL_NEWER_REFERENCE_EXT:
    case ERL_REFERENCE_EXT:
	if (ei_decode_ref(buf, index, NULL) < 0) return -1;
	break;
    case ERL_NIL_EXT:
	if (ei_decode_list_header(buf, index, &n) < 0) return -1;
	break;
    case ERL_LIST_EXT:
	if (ei_decode_list_header(buf, index, &n) < 0) return -1;
	for (i = 0; i < n; ++i)
	    ei_skip_term(buf, index);
	if (ei_get_type_internal(buf, index, &ty, &n) < 0) return -1;
	if (ty != ERL_NIL_EXT)
	    ei_skip_term(buf, index);
	else
	    if (ei_decode_list_header(buf, index, &n) < 0) return -1;
	break;
    case ERL_STRING_EXT:
	if (ei_decode_string(buf, index, NULL) < 0) return -1;
	break;
    case ERL_SMALL_TUPLE_EXT:
    case ERL_LARGE_TUPLE_EXT:
	if (ei_decode_tuple_header(buf, index, &n) < 0) return -1;
	for (i = 0; i < n; ++i)
	    ei_skip_term(buf, index);
	break;
    case ERL_MAP_EXT:
	if (ei_decode_map_header(buf, index, &n) < 0) return -1;
	n *= 2;
	for (i = 0; i < n; ++i)
	    ei_skip_term(buf, index);
	break;
    case ERL_BINARY_EXT:
	if (ei_decode_binary(buf, index, NULL, NULL) < 0)
	    return -1;
	break;
    case ERL_SMALL_INTEGER_EXT:
    case ERL_INTEGER_EXT:
	if (ei_decode_long(buf, index, NULL) < 0) return -1;
	break;
    case ERL_SMALL_BIG_EXT:
    case ERL_LARGE_BIG_EXT:
	if (ei_decode_big(buf, index, NULL) < 0) return -1;
	break;
    case ERL_FLOAT_EXT:
    case NEW_FLOAT_EXT:
	if (ei_decode_double(buf, index, NULL) < 0) return -1;
	break;
    case ERL_FUN_EXT:
    case ERL_NEW_FUN_EXT:
	if (ei_decode_fun(buf, index, NULL) < 0) return -1;
	break;
    default:
	return -1;
    }
    return 0;
}
Beispiel #23
0
static void show_term(const char *termbuf, int *index, FILE *stream)
{
    int type;
    char smallbuf[EISHOWBUF];
    int version;
    long num;
    double fnum;
    erlang_pid pid;
    erlang_port port;
    erlang_ref ref;
    int i, len;
    char *s;

    ei_get_type_internal(termbuf,index,&type,&len);

    switch (type) {
    case ERL_VERSION_MAGIC:
        /* just skip past this */
        ei_decode_version(termbuf,index,&version);
        show_term(termbuf,index,stream);
        break;

    case ERL_ATOM_EXT:
        ei_decode_atom(termbuf,index,smallbuf);
        fprintf(stream,"%s",smallbuf);
        break;

    case ERL_STRING_EXT:
        /* strings can be much longer than EISHOWBUF */
        if (len < EISHOWBUF) s = smallbuf;
        else if (!(s = malloc(len+1))) break; /* FIXME just break if can't? */

        ei_decode_string(termbuf,index,s);

        if (printable_list_p((uint8 *)s,len)) {
            /* just show it as it is */
            fprintf(stream,"\"%s\"",s);
        } else {
            /* show it as a list instead */
            fprintf(stream,"[");
            for (i=0; i<len; i++) {
                if (i > 0) fprintf(stream,", ");
                fprintf(stream,"%d",s[i]);
            }
            fprintf(stream,"]");
        }

        /* did we allocate anything? */
        if (s && (s != smallbuf)) free(s);

        break;

    /* FIXME add case using ei_decode_longlong */
    case ERL_SMALL_BIG_EXT:
    case ERL_SMALL_INTEGER_EXT:
    case ERL_INTEGER_EXT:
        if (ei_decode_long(termbuf,index,&num) == 0) {
            fprintf(stream,"%ld",num);
        } else {
            ei_decode_skip_bignum(termbuf,index,NULL);
            fprintf(stream,"#Bignum");
        }
        break;

    case ERL_FLOAT_EXT:
    case NEW_FLOAT_EXT:
        ei_decode_double(termbuf,index,&fnum);
        fprintf(stream,"%f",fnum);
        break;

    case ERL_PID_EXT:
        ei_decode_pid(termbuf,index,&pid);
        show_pid(stream,&pid);
        break;

    case ERL_SMALL_TUPLE_EXT:
    case ERL_LARGE_TUPLE_EXT:
        ei_decode_tuple_header(termbuf,index,&len);
        fprintf(stream,"{");
        for (i=0; i<len; i++) {
            if (i > 0) fprintf(stream,", ");
            show_term(termbuf,index,stream);
        }
        fprintf(stream,"}");
        break;

    case ERL_LIST_EXT:
        ei_decode_list_header(termbuf,index,&len);
        fprintf(stream,"[");
        for (i=0; i<len; i++) {
            if (i > 0) fprintf(stream,", ");
            show_term(termbuf,index,stream);
        }
        /* get the empty list at the end */
        ei_decode_list_header(termbuf,index,&len);
        fprintf(stream,"]");
        break;

    case ERL_NIL_EXT:
        ei_decode_list_header(termbuf,index,&len);
        fprintf(stream,"[]");
        break;

    case ERL_REFERENCE_EXT:
    case ERL_NEW_REFERENCE_EXT:
        ei_decode_ref(termbuf,index,&ref);
        fprintf(stream,"#Ref<%s",ref.node);
        for (i = 0; i < ref.len; i++) {
            fprintf(stream,".%u",ref.n[i]);
        }
        fprintf(stream,".%u>",ref.creation);
        break;

    case ERL_PORT_EXT:
        ei_decode_port(termbuf,index,&port);
        fprintf(stream,"#Port<%s.%u.%u>",port.node,port.id,port.creation);
        break;

    case ERL_BINARY_EXT:
        ei_decode_binary(termbuf,index,NULL,&num);
        fprintf(stream,"#Bin<%ld>",num);
        break;

    case ERL_LARGE_BIG_EXT:
        /* doesn't actually decode - just skip over it */
        /* FIXME if GMP, what to do here?? */
        ei_decode_skip_bignum(termbuf,index,NULL);
        fprintf(stream,"#Bignum");
        break;

    case ERL_FUN_EXT: {
        char atom[MAXATOMLEN];
        long idx;
        long uniq;
        const char* s = termbuf + *index, * s0 = s;
        int n_free;

        ++s;
        n_free = get32be(s);
        *index += s - s0;
        ei_decode_pid(termbuf, index, NULL); /* skip pid */
        ei_decode_atom(termbuf, index, atom); /* get module, index, uniq */
        ei_decode_long(termbuf, index, &idx);
        ei_decode_long(termbuf, index, &uniq);
        fprintf(stream,"#Fun<%s.%ld.%ld>", atom, idx, uniq);
        for (i = 0; i < n_free; ++i) {
            /* FIXME how to report error ?! */
            if (ei_skip_term(termbuf, index) != 0)
                fprintf(stderr,"<ERROR> show_msg: unknown type of term !");
        }
        break;
    }
    default:
        fprintf(stream,"#Unknown<%d.%d>",type,len);
        /* unfortunately we don't know how to skip over this type in
         * the buffer if we don't even know what it is, so we return.
         */
        return;
        break;
    }
}
Beispiel #24
0
static ErlDrvSSizeT control(ErlDrvData drv_data, unsigned int command,
                            char *buf, ErlDrvSizeT, char **rbuf, ErlDrvSizeT) {

  driver_data_t *data = (driver_data_t *)drv_data;

  ei_x_buff x;

  ei_x_new_with_version(&x);

  switch ((TPCE::eCommand)command) {
  case TPCE::CMD_ALL_INIT:
    {
      int index = 0, version, arity;
      char atom[MAXATOMLEN+1];
      bool found = true;

      ei_decode_version(buf, &index, &version);
      ei_decode_list_header(buf, &index, &arity);

      for (int size = arity, i = 0; found && i < size; i++) {

        ei_decode_tuple_header(buf, &index, &arity);

        if (2 == arity) {

          ei_term term;

          ei_decode_atom(buf, &index, atom);
          ei_decode_ei_term(buf, &index, &term);

          if (0 == strcmp(atom, "id")) {
            data->id = term.value.i_val;
          } else if (0 == strcmp(atom, "path") && ERL_STRING_EXT == term.ei_type) {
            char v[term.size+1];
            ei_decode_string(buf, &index, v);
            strncpy(data->path, v, sizeof(data->path));
          } else if (0 == strcmp(atom, "path") && ERL_BINARY_EXT == term.ei_type) {
            char v[term.size+1];
            long l = term.size;
            ei_decode_binary(buf, &index, v, &l); v[l] = '\0';
            strncpy(data->path, v, sizeof(data->path));
          } else if (0 == strcmp(atom, "configured_customer_count")) {
            data->configured_customer_count = term.value.i_val;
          } else if (0 == strcmp(atom, "active_customer_count")) {
            data->active_customer_count = term.value.i_val;
          } else if (0 == strcmp(atom, "scale_factor")) {
            data->scale_factor = term.value.i_val;
          } else if (0 == strcmp(atom, "days_of_initial_trades")) {
            data->days_of_initial_trades = term.value.i_val;
          } else {
            found = false;
          }
        }
      }

      if (found) {
        ei_x_encode_atom(&x, "ok");
      } else {
        ergen_drv_encode_error1(&x, "badmatch", atom);
      }
    }
    break;
  case TPCE::CMD_ALL_CONFIG:
    {
      ei_x_encode_atom(&x, "ok");
    }
    break;
  case TPCE::CMD_ALL_ALLOC:
    {
      void *ptr = ergen_driver_new(data);

      if (NULL != ptr) {

        data->driver = ptr;

        ei_x_encode_atom(&x, "ok");

      } else {
        ergen_drv_encode_error0(&x, "nomem");
      }
    }
    break;
  case TPCE::CMD_ALL_FREE:
    {
      void *ptr = data->driver;

      if (NULL != ptr) {
        ergen_driver_delete(ptr);
        data->driver = NULL;
      }

      ei_x_encode_atom(&x, "ok");
    }
    break;
  default:
    {
      ergen_drv_encode_error0(&x, "badarg");
    }
    break;
  }

  ErlDrvSizeT result = x.index;
  *rbuf = (char *)ergen_drv_bindup(x.buff, result);

  ei_x_free(&x);

  return result;
}
Beispiel #25
0
static int print_term(FILE* fp, ei_x_buff* x,
			       const char* buf, int* index)
{
    int i, doquote, n, m, ty, r;
    char a[MAXATOMLEN], *p;
    int ch_written = 0;		/* counter of written chars */
    erlang_pid pid;
    erlang_port port;
    erlang_ref ref;
    double d;
    long l;

    int tindex = *index;

    /* use temporary index for multiple (and failable) decodes */

    if (fp == NULL && x == NULL) return -1;

    doquote = 0;
    ei_get_type_internal(buf, index, &ty, &n);
    switch (ty) {
    case ERL_ATOM_EXT:   
    case ERL_ATOM_UTF8_EXT:
    case ERL_SMALL_ATOM_EXT:
    case ERL_SMALL_ATOM_UTF8_EXT:
	if (ei_decode_atom(buf, index, a) < 0)
	   goto err;
	doquote = !islower((int)a[0]);
	for (p = a; !doquote && *p != '\0'; ++p)
	    doquote = !(isalnum((int)*p) || *p == '_' || *p == '@');
	if (doquote) {
	    xputc('\'', fp, x); ++ch_written; 
	}
	xputs(a, fp, x); ch_written += strlen(a);
	if (doquote) {
	    xputc('\'', fp, x); ++ch_written;
	}
	break;
    case ERL_PID_EXT:
    case ERL_NEW_PID_EXT:
	if (ei_decode_pid(buf, index, &pid) < 0) goto err;
	ch_written += xprintf(fp, x, "<%s.%d.%d>", pid.node,
			      pid.num, pid.serial);
	break;
    case ERL_PORT_EXT:
    case ERL_NEW_PORT_EXT:
	if (ei_decode_port(buf, index, &port) < 0) goto err;
	ch_written += xprintf(fp, x, "#Port<%d.%d>", port.id, port.creation);
	break;
    case ERL_NEW_REFERENCE_EXT:
    case ERL_NEWER_REFERENCE_EXT:
    case ERL_REFERENCE_EXT:
	if (ei_decode_ref(buf, index, &ref) < 0) goto err;
	ch_written += xprintf(fp, x, "#Ref<");
	for (i = 0; i < ref.len; ++i) {
	    ch_written += xprintf(fp, x, "%d", ref.n[i]);
	    if (i < ref.len - 1) {
		xputc('.', fp, x); ++ch_written;
	    }
	}
	xputc('>', fp, x); ++ch_written;
	break;
    case ERL_NIL_EXT:
	if (ei_decode_list_header(buf, index, &n) < 0) goto err;
	ch_written += xprintf(fp, x, "[]");
	break;
    case ERL_LIST_EXT:
	if (ei_decode_list_header(buf, &tindex, &n) < 0) goto err;
	xputc('[', fp, x); ch_written++;
	for (i = 0; i < n; ++i) {
	    r = print_term(fp, x, buf, &tindex);
	    if (r < 0) goto err;
	    ch_written += r;
	    if (i < n - 1) {
		xputs(", ", fp, x); ch_written += 2;
	    }
	}
	if (ei_get_type_internal(buf, &tindex, &ty, &n) < 0) goto err;
	if (ty != ERL_NIL_EXT) {
	    xputs(" | ", fp, x); ch_written += 3;
	    r = print_term(fp, x, buf, &tindex);
	    if (r < 0) goto err;
	    ch_written += r;
	} else {
	    if (ei_decode_list_header(buf, &tindex, &n) < 0) goto err;
	}
	xputc(']', fp, x); ch_written++;
	*index = tindex;
	break;
    case ERL_STRING_EXT:
	p = ei_malloc(n+1);
	if (p == NULL) goto err;
	if (ei_decode_string(buf, index, p) < 0) {
	    ei_free(p);
	    goto err;
	}
	ch_written += print_string(fp, x, p, n);
	ei_free(p);
	break;
    case ERL_SMALL_TUPLE_EXT:
    case ERL_LARGE_TUPLE_EXT:
	if (ei_decode_tuple_header(buf, &tindex, &n) < 0) goto err;
	xputc('{', fp, x); ch_written++;

	for (i = 0; i < n; ++i) {
	    r = print_term(fp, x, buf, &tindex);
	    if (r < 0) goto err;
	    ch_written += r;
	    if (i < n-1) {
		xputs(", ", fp, x); ch_written += 2;
	    }
	}
	*index = tindex;
	xputc('}', fp, x); ch_written++;
	break;
    case ERL_BINARY_EXT:
	p = ei_malloc(n);
	if (p == NULL) goto err;
	if (ei_decode_binary(buf, index, p, &l) < 0) {
	    ei_free(p);
	    goto err;
	}
	ch_written += xprintf(fp, x, "#Bin<");
	if (l > BINPRINTSIZE)
	    m = BINPRINTSIZE;
	else
	    m = l;
	--m;
	for (i = 0; i < m; ++i) {
	    ch_written += xprintf(fp, x, "%d,", p[i]);
	}
	ch_written += xprintf(fp, x, "%d", p[i]);
	if (l > BINPRINTSIZE)
	    ch_written += xprintf(fp, x, ",...");
	xputc('>', fp, x); ++ch_written;
	ei_free(p);
	break;
    case ERL_SMALL_INTEGER_EXT:
    case ERL_INTEGER_EXT:
	if (ei_decode_long(buf, index, &l) < 0) goto err;
	ch_written += xprintf(fp, x, "%ld", l);
	break;
    case ERL_SMALL_BIG_EXT:
    case ERL_LARGE_BIG_EXT:
        {
            erlang_big *b;
            char *ds;

            if ( (b = ei_alloc_big(n)) == NULL) goto err;

            if (ei_decode_big(buf, index, b) < 0) {
                ei_free_big(b);
                goto err;
            }
            
            if ( (ds = ei_big_to_str(b)) == NULL ) {
                ei_free_big(b);
                goto err;
            }
            
            ch_written += xprintf(fp, x, ds);
            free(ds);
            ei_free_big(b);
            
        }
        break;

    case ERL_FLOAT_EXT:
    case NEW_FLOAT_EXT:
	if (ei_decode_double(buf, index, &d) < 0) goto err;
	ch_written += xprintf(fp, x, "%f", d);
	break;
    default:
	goto err;
    }
    return ch_written;
 err:
    return -1;
}
Beispiel #26
0
void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {

	int etype, esize;
	int arity;

	char *gen_call;
	char *module;
	char *call;
	char buffer[0xffff];

	char *argv[256] ;
	uint16_t argvs[256] ;
	int argc = 0;
	uint16_t ret;
	ei_x_buff xr;

	erlang_ref eref;

	ei_get_type(x->buff, &x->index, &etype, &esize);

#ifdef UWSGI_DEBUG
	uwsgi_log("%d %c %c %c\n", etype, etype, ERL_SMALL_TUPLE_EXT, ERL_LARGE_TUPLE_EXT);
#endif
	if (etype != ERL_SMALL_TUPLE_EXT && etype != ERL_LARGE_TUPLE_EXT) return;

	ei_decode_tuple_header(x->buff, &x->index, &arity);

#ifdef UWSGI_DEBUG
	uwsgi_log("rpc arity %d\n", arity);
#endif
	if (arity != 3) return ;

	ei_get_type(x->buff, &x->index, &etype, &esize);

	if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ;

	gen_call = uwsgi_malloc(esize);

	if (etype == ERL_ATOM_EXT) {
                ei_decode_atom(x->buff, &x->index, gen_call);
        }
        else {
                ei_decode_string(x->buff, &x->index, gen_call);
        }

#ifdef UWSGI_DEBUG
	uwsgi_log("gen call = %s\n", gen_call);
#endif

	ei_get_type(x->buff, &x->index, &etype, &esize);
	
	if (etype != ERL_SMALL_TUPLE_EXT) return ;

	ei_decode_tuple_header(x->buff, &x->index, &arity);
	if (arity != 2) return ;

	ei_get_type(x->buff, &x->index, &etype, &esize);
	ei_skip_term(x->buff, &x->index);
	ei_get_type(x->buff, &x->index, &etype, &esize);
	ei_decode_ref(x->buff, &x->index, &eref);

	ei_get_type(x->buff, &x->index, &etype, &esize);

	module = uwsgi_malloc(esize);

	if (etype == ERL_ATOM_EXT) {
		ei_decode_atom(x->buff, &x->index, module);
	}
	else {
		ei_decode_string(x->buff, &x->index, module);
	}

	ei_get_type(x->buff, &x->index, &etype, &esize);

	if (etype != ERL_SMALL_TUPLE_EXT) return ;

	ei_decode_tuple_header(x->buff, &x->index, &arity);

#ifdef UWSGI_DEBUG
	uwsgi_log("arity: %d\n", arity);
#endif
	if (arity != 5) return ;

	ei_get_type(x->buff, &x->index, &etype, &esize);

        char *method = uwsgi_malloc(esize);

        if (etype == ERL_ATOM_EXT) {
                ei_decode_atom(x->buff, &x->index, method);
        }
        else {
                ei_decode_string(x->buff, &x->index, method);
        }

        if (strcmp(method, "call")) return;

        ei_get_type(x->buff, &x->index, &etype, &esize);

	if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ;

	module = uwsgi_malloc(esize);

	if (etype == ERL_ATOM_EXT) {
		ei_decode_atom(x->buff, &x->index, module);
	}
	else {
		ei_decode_string(x->buff, &x->index, module);
	}

	ei_get_type(x->buff, &x->index, &etype, &esize);

	if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ;

	call = uwsgi_malloc(esize);

	if (etype == ERL_ATOM_EXT) {
		ei_decode_atom(x->buff, &x->index, call);
	}
	else {
		ei_decode_string(x->buff, &x->index, call);
	}

#ifdef UWSGI_DEBUG
	uwsgi_log("RPC %s %s\n", module, call);
#endif

	ei_get_type(x->buff, &x->index, &etype, &esize);

	if (etype == ERL_ATOM_EXT) {
		argc = 1;
		argv[0] = uwsgi_malloc(esize+1);
		ei_decode_atom(x->buff, &x->index, argv[0]);	
		argvs[1] = esize;
	}
	else if (etype == ERL_STRING_EXT) {
		argc = 1;
		argv[0] = uwsgi_malloc(esize+1);
		ei_decode_string(x->buff, &x->index, argv[0]);	
		argvs[1] = esize;
	}

	ret = uwsgi_rpc(call, argc, argv, argvs, buffer);

#ifdef UWSGI_DEBUG
	uwsgi_log("buffer: %.*s\n", ret, buffer);
#endif

	ei_x_new_with_version(&xr);

	ei_x_encode_tuple_header(&xr, 2);
	//ei_x_encode_atom(&xr, "rex");
	ei_x_encode_ref(&xr, &eref);
	ei_x_encode_string_len(&xr, buffer, ret);

	uwsgi_log("ei_send to %d %s %d %d %d: %d %d\n", fd, from->node, from->num , from->serial, from->creation, xr.index, ei_send(fd, from, xr.buff, xr.index));
	//uwsgi_log("ei_send to %d %s %d %d %d: %d %d\n", fd, from->node, from->num , from->serial, from->creation, xr.index, ei_reg_send(&uerl.cnode, fd, "rex", xr.buff, xr.index));
	
	
}
Beispiel #27
0
int ei_decode_term(const char *buf, int *index, void *t)
{
    const char *s = buf + *index;
    const char *s0 = s;

    if (t) {
        ETERM *tmp;

        /* this decodes and advances s */
        if (!(tmp = erl_decode_buf((unsigned char **)&s))) return -1;

        *(ETERM **)t = tmp;
        *index += s - s0;

        return 0;
    }
    else {
        int tmpindex = *index;
        long ttype;
        int arity;
        int i;

        /* these are all the external types */
        switch ((ttype = get8(s))) {
        case ERL_SMALL_INTEGER_EXT:
        case ERL_INTEGER_EXT:
        case ERL_SMALL_BIG_EXT:
            return ei_decode_long(buf,index,NULL);

        case ERL_FLOAT_EXT:
        case NEW_FLOAT_EXT:
            return ei_decode_double(buf,index,NULL);

        case ERL_ATOM_EXT:
            return ei_decode_atom(buf,index,NULL);

        case ERL_REFERENCE_EXT:
        case ERL_NEW_REFERENCE_EXT:
            return ei_decode_ref(buf,index,NULL);

        case ERL_PORT_EXT:
            return ei_decode_port(buf,index,NULL);

        case ERL_PID_EXT:
            return ei_decode_pid(buf,index,NULL);

        case ERL_SMALL_TUPLE_EXT:
        case ERL_LARGE_TUPLE_EXT:
            if (ei_decode_tuple_header(buf,index,&arity) < 0)
                return -1;

            for (i=0; i<arity; i++) {
                if (ei_decode_term(buf,index,NULL)) {
                    /* restore possibly changed index before returning */
                    *index = tmpindex;
                    return -1;
                }
            }
            return 0;

        case ERL_STRING_EXT:
            return ei_decode_string(buf,index,NULL);

        case ERL_LIST_EXT:
        case ERL_NIL_EXT:
            if (ei_decode_list_header(buf,index,&arity) < 0)
                return -1;

            if (arity) {
                for (i=0; i<arity; i++) {
                    if (ei_decode_term(buf,index,NULL) < 0) {
                        /* restore possibly changed index before returning */
                        *index = tmpindex;
                        return -1;
                    }
                }
                if (ei_decode_list_header(buf,index,&arity) < 0) {
                    *index = tmpindex;
                    return -1;
                }
            }
            return 0;

        case ERL_BINARY_EXT:
            return ei_decode_binary(buf,index,NULL,NULL);

        case ERL_LARGE_BIG_EXT:
        default:
            break;
        }
    }

    return -1;
}
Beispiel #28
0
/* decode an object and insert it into the table */
static int mn_decode_insert(ei_reg *reg, const char *msgbuf, int *index, char *key)
{
  long keylen;
  long objlen;
  long objtype;
  void *objbuf = NULL;
  long i;
  double f;

  if (ei_decode_long(msgbuf,index,&keylen) 
      || ei_decode_long(msgbuf,index,&objlen) 
      || ei_decode_long(msgbuf,index,&objtype)) 
    return -1;


  /* decode key */
  if (ei_decode_string(msgbuf,index,key)) {
    if (objbuf) free(objbuf);
    return -1;
  }

  /* finally! decode object and insert in table */
  /* don't forget to fix attributes (dirty bit for example) */

  /* FIXME: added cast but 64 bit trouble I think */
  switch ((int)objtype & EI_REG_TYPEMASK) {
  case EI_INT:
    if (ei_decode_long(msgbuf,index,&i)) return -1;
    ei_reg_setival(reg,key,i);
    break;

  case EI_FLT:
    if (ei_decode_double(msgbuf,index,&f)) return -1;
    ei_reg_setfval(reg,key,f);
    break;

  case EI_STR:
    objbuf = NULL;
    if (objlen > 0) {
      if (!(objbuf = malloc(objlen))) return -1;
      if (ei_decode_string(msgbuf,index,objbuf)) {
	free(objbuf);
	return -1;
      }
      ei_reg_setsval(reg,key,objbuf);
    }
    else {
      /* just a pointer to nothing */
      if (ei_decode_long(msgbuf,index,&i)) return -1;
      ei_reg_setsval(reg,key,NULL);
    }
    break;

  case EI_BIN:
    objbuf = NULL;
    if (objlen > 0) {
      if (!(objbuf = malloc(objlen))) return -1;
      if (ei_decode_binary(msgbuf,index,objbuf,&i)) {
	free(objbuf);
	return -1;
      }
      /* assert(i == objlen) */
      ei_reg_setpval(reg,key,objbuf,objlen);
    }
    else {
      /* just a pointer to nothing */
      if (ei_decode_long(msgbuf,index,&i)) return -1;
      ei_reg_setpval(reg,key,(void *)i,0);
    }
    break;

  default:
    /* unknown type */
    if (objbuf) free(objbuf);
    return -1;
  } /* switch */

  return 0;
}
Beispiel #29
0
/* Return values:
 * - -1 error
 * - 0 nothing
 * - 1 detach */
int cnode_read(int fd, char **ret_str) {
	ei_x_buff x;
	erlang_msg msg;
	int result, index, o_index, arity, type, size, ver, rv = CNODE_IGNORE;
	const char *str;
	char *s;
	char atom[MAXATOMLEN];

	ei_x_new(&x);
	/* We don't use xreceive because we're not expecting any big
	   messages and we don't want a huge term to cause our memory
	   usage to blow out and crash us. */
	/* Use a timeout of 1 millisecond even though we know we'll
	   be able to read at least some bytes, just to be sure we
	   do not get blocked (for long). Really we want to specify
	   "no timeout but don't block" to ei_receive_msg but it
	   doesn't provide that functionality. */
	result = ei_receive_msg_tmo(fd, &msg, &x, 1);

	if (result < 0) {
		LOG_V("ei_receive_msg_tmo failed (%d): %s", erl_errno, strerror(erl_errno));
		switch (erl_errno) {
			case ETIMEDOUT:
				DEBUG("ei_receive_msg_tmo: timed out.");
				break;
			case EAGAIN:
				DEBUG("ei_receive_msg_tmo: try again");
				break;
			case EMSGSIZE:
				DEBUG("ei_receive_msg_tmo: message too big");
				rv = CNODE_ERROR;
				break;
			case EIO:
				LOG_V("ei_receive_msg_tmo: IO error (%d: %s)", errno, strerror(errno));
				if (errno != EAGAIN)
					rv = CNODE_ERROR;
				break;
		}
	}
	else {
		if (result == ERL_TICK) { /* nothing to do */
			DEBUG("node tick message");
		}
		else {
			switch (msg.msgtype) {
				case ERL_SEND: str = "SEND"; break;
				case ERL_REG_SEND: str = "REG_SEND"; break;
				case ERL_LINK: str = "LINK"; break;
				case ERL_UNLINK: str = "UNLINK"; break;
				default: str = "unknown";
			}
			if (msg.msgtype == ERL_REG_SEND) {
				index = 0;

				if (ei_decode_version(x.buff, &index, &ver) == 0) {
					// DEBUG_V("data ver %d", ver);
				}

				o_index = index;

				if (ei_decode_atom(x.buff, &index, atom) == 0) {
					// DEBUG_V("atom %s", atom);
					if (!strcmp(atom, "detach")) {
						DEBUG("got detach message");
						rv = CNODE_DETACH;
					}
					else if (!strcmp(atom, "thump")) {
						rv = CNODE_THUMP;
					}
					else {
						DEBUG("message is unknown");
					}
				}
				else if (ei_decode_tuple_header(x.buff, &index, &arity) == 0) {
					if ((arity == 2)
					&& !ei_decode_atom(x.buff, &index, atom) && !strcmp(atom, "stdout")
					&& !ei_get_type(x.buff, &index, &type, &size)
					&& (type == ERL_STRING_EXT)) {
						*ret_str = (char *)malloc(size + 1);
						if (ei_decode_string(x.buff, &index, *ret_str)) {
							LOG("Failed to decode string for stdout message.");
							free(*ret_str);
							rv = CNODE_ERROR;
						}
						else
							rv = CNODE_STR;
					}
					else {
						index = o_index; // Re-set index to beginning of term.
						s = 0;
						ei_s_print_term(&s, x.buff, &index);
						LOG_V("Unknown tuple (arity %d): %s", arity, s);
						free(s);
					}
				}
				else {
					s = 0;
					ei_s_print_term(&s, x.buff, &index);
					LOG_V("Unknown message: %s", s);
					free(s);
				}
			}
			else {
				DEBUG_V("received %s message", str);
			}
		}
	}
	ei_x_free(&x);
	return rv;
}
Beispiel #30
0
/* Scratch function */
int oe_ei_decode_wstring(const char *buf, int *index, CORBA_wchar *p) {

  int length,error_code,type,tmp=0;
  char * tmp_space = NULL;


  if ((error_code = ei_get_type(buf, index, &type, &length)) < 0)
    return error_code;
  
  switch(type) {
    
  case ERL_LIST_EXT: /* A list */
  case ERL_NIL_EXT: /* An empty list */
    
    if (p) { /* Decoding part */

      if ((error_code = ei_decode_list_header(buf, index, &length)) < 0) 
	return error_code;
      
      if (length != 0) {
	for(tmp = 0; tmp < length; tmp++) 
	  if ((error_code = oe_ei_decode_wchar(buf, index, &(p[tmp]))) < 0)
	    return error_code;

	/* Read list tail also */
	if ((error_code = ei_decode_list_header(buf, index, &length)) < 0) 
	  return error_code;
      }
      
      p[tmp] = 0;   /* Wide NULL */
	
    } else { /* Allocation counting part */

      if ((error_code = ei_decode_list_header(buf, index, &length)) < 0) 
	return error_code;
      
      if (length != 0) {
	for(tmp = 0; tmp < length; tmp++) 
	  if ((error_code = oe_ei_decode_wchar(buf, index, 0)) < 0)
	    return error_code;

	/* Read list tail also */
	if ((error_code = ei_decode_list_header(buf, index, &length)) < 0) 
	  return error_code;
      }
    }
    
    break;

  case ERL_STRING_EXT: /* A string */

    if (p) { /* Decoding part */
      
      /* Allocate temporary string */
      tmp_space = (char*) malloc(length*(__OE_WCHARSZ__+1));

      if ((error_code = ei_decode_string(buf, index, tmp_space)) < 0)
	return error_code;
      
      /* Assign characters to wide characters */
      for(tmp = 0; tmp < length; tmp++)
	p[tmp] = tmp_space[tmp];
      
      p[tmp] = 0; /* Wide NULL */
      
      /* Free temporary string */
      CORBA_free(tmp_space);

    } else { /* Allocation counting part */
      
      if ((error_code = ei_decode_string(buf, index, 0)) < 0)
	return error_code;

    }
    break;

  default: /* Bad header */
    return -1; 
  }

  return 0;
}