Example #1
0
File: ic.c Project: 0x00evil/otp
/* Prepare reply decoding (gen_server client) */
int oe_prepare_reply_decoding(CORBA_Environment *env)
{
    int error = 0;
    int version = 0;
    erlang_ref unique;

    env->_iin = 0;
    env->_received = 0;

    if ((error = ei_decode_version(env->_inbuf, 
				   &env->_iin, 
				   &version)) < 0)
        return error;
    if ((error = ei_decode_tuple_header(env->_inbuf, 
					&env->_iin, 
					&env->_received)) < 0)
        return error;
    if ((error = ei_decode_ref(env->_inbuf,
			       &env->_iin, 
			       &unique)) < 0)
        return error;
    return ic_compare_refs(&env->_unique, &unique);
}   
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
File: ic.c Project: 0x00evil/otp
/* Prepare request decoding (gen_server server) */
int oe_prepare_request_decoding(CORBA_Environment *env)
{
    char gencall_atom[10];
    int error = 0;
    int version = 0;

    env->_iin = 0;
    env->_received = 0;
    memset(gencall_atom, 0, 10);
    ei_decode_version(env->_inbuf, &env->_iin, &version);
    ei_decode_tuple_header(env->_inbuf, &env->_iin, &env->_received);
    ei_decode_atom(env->_inbuf, &env->_iin, gencall_atom);

    if (strcmp(gencall_atom, "$gen_cast") == 0) {
	if ((error = ei_decode_atom(env->_inbuf, &env->_iin, 
				    env->_operation)) < 0) {
	    ei_decode_tuple_header(env->_inbuf, &env->_iin, &env->_received);
	    if ((error = ei_decode_atom(env->_inbuf, &env->_iin, 
					env->_operation)) < 0) { 
		CORBA_exc_set(env, CORBA_SYSTEM_EXCEPTION, BAD_OPERATION, 
			      "Bad Message, cannot extract operation");
		return error;
	    }
	    env->_received -= 1;
	} else
	    env->_received -= 2;
	return 0;
    }
    if (strcmp(gencall_atom, "$gen_call") == 0) {
	ei_decode_tuple_header(env->_inbuf, &env->_iin, &env->_received);
	if ((error = ei_decode_pid(env->_inbuf, &env->_iin, 
				   &env->_caller)) < 0) {
	    CORBA_exc_set(env, CORBA_SYSTEM_EXCEPTION, MARSHAL, 
			  "Bad Message, bad caller identity");
	    return error;
	}
	if ((error = ei_decode_ref(env->_inbuf, &env->_iin, 
				   &env->_unique)) < 0) {
	    CORBA_exc_set(env, CORBA_SYSTEM_EXCEPTION, MARSHAL, 
			  "Bad Message, bad message reference");
	    return error;
	}
	if ((error = ei_decode_atom(env->_inbuf, &env->_iin, 
				    env->_operation)) < 0) {
	    
	    ei_decode_tuple_header(env->_inbuf, &env->_iin, &env->_received);
	    
	    if ((error = ei_decode_atom(env->_inbuf, &env->_iin, 
					env->_operation)) < 0) { 
		CORBA_exc_set(env, CORBA_SYSTEM_EXCEPTION, BAD_OPERATION, 
			      "Bad Message, cannot extract operation");
		return error;
	    }
	    env->_received -= 1;
	    return 0;	  
	}
	else {
	    env->_received -= 2;
	    return 0;
	}
    }
    
    CORBA_exc_set(env, CORBA_SYSTEM_EXCEPTION, MARSHAL, 
		  "Bad message, neither cast nor call");
    return -1;
}
Example #6
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;
    }
}
Example #7
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;
}
Example #8
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));
	
	
}
Example #9
0
/* {'$gen_call', {<[email protected]>, #Ref<254770.4.0>}, {is_auth, cpx@freecpx} */
static switch_status_t handle_net_kernel_msg(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
	int version, size, type, arity;
	char atom[MAXATOMLEN];
	erlang_ref ref;
	erlang_pid pid;

	buf->index = 0;
	ei_decode_version(buf->buff, &buf->index, &version);
	ei_get_type(buf->buff, &buf->index, &type, &size);

	if (type != ERL_SMALL_TUPLE_EXT && type != ERL_SMALL_TUPLE_EXT) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not a tuple\n");
		return SWITCH_STATUS_FALSE;
	}

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

	if (arity != 3) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "wrong arity\n");
		return SWITCH_STATUS_FALSE;
	}

	if (ei_decode_atom(buf->buff, &buf->index, atom) || strncmp(atom, "$gen_call", MAXATOMLEN)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not gen_call\n");
		return SWITCH_STATUS_FALSE;
	}

	ei_get_type(buf->buff, &buf->index, &type, &size);

	if (type != ERL_SMALL_TUPLE_EXT && type != ERL_SMALL_TUPLE_EXT) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not a tuple\n");
		return SWITCH_STATUS_FALSE;
	}

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

	if (arity != 2) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "wrong arity\n");
		return SWITCH_STATUS_FALSE;
	}

	if (ei_decode_pid(buf->buff, &buf->index, &pid) || ei_decode_ref(buf->buff, &buf->index, &ref)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "decoding pid and ref error\n");
		return SWITCH_STATUS_FALSE;
	}

	ei_get_type(buf->buff, &buf->index, &type, &size);

	if (type != ERL_SMALL_TUPLE_EXT && type != ERL_SMALL_TUPLE_EXT) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not a tuple\n");
		return SWITCH_STATUS_FALSE;
	}

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

	if (arity != 2) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "bad arity\n");
		return SWITCH_STATUS_FALSE;
	}

	if (ei_decode_atom(buf->buff, &buf->index, atom) || strncmp(atom, "is_auth", MAXATOMLEN)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not is_auth\n");
		return SWITCH_STATUS_FALSE;
	}

	/* To ! {Tag, Reply} */
	ei_x_encode_tuple_header(rbuf, 2);
	ei_x_encode_ref(rbuf, &ref);
	ei_x_encode_atom(rbuf, "yes");

	switch_mutex_lock(listener->sock_mutex);
	ei_send(listener->sockfd, &pid, rbuf->buff, rbuf->index);
	switch_mutex_unlock(listener->sock_mutex);
#ifdef EI_DEBUG
	ei_x_print_msg(rbuf, &pid, 1);
#endif

	return SWITCH_STATUS_FALSE;
}
Example #10
0
static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
	erlang_ref ref;
	erlang_pid *pid;
	char hash[100];
	int arity;
	const void *key;
	void *val;
	session_elem_t *se;
	switch_hash_index_t *iter;

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

	if (ei_decode_ref(buf->buff, &buf->index, &ref)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid reference\n");
		return SWITCH_STATUS_FALSE;
	}

	if (!(pid = malloc(sizeof(erlang_pid)))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "error");
		ei_x_encode_atom(rbuf, "badmem");
		return SWITCH_STATUS_SUCCESS;
	}

	if (ei_decode_pid(buf->buff, &buf->index, pid)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid pid in a reference/pid tuple\n");
		return SWITCH_STATUS_FALSE;
	}

	ei_hash_ref(&ref, hash);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hashed ref to %s\n", hash);

	switch_thread_rwlock_rdlock(listener->session_rwlock);
	for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
		switch_hash_this(iter, &key, NULL, &val);
		se = (session_elem_t*)val;
		if (se->spawn_reply && !strncmp(se->spawn_reply->hash, hash, 100)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found matching session for %s : %s\n", hash, se->uuid_str);
			switch_mutex_lock(se->spawn_reply->mutex);
			if (se->spawn_reply->state == reply_not_ready) {
				switch_thread_cond_wait(se->spawn_reply->ready_or_found, se->spawn_reply->mutex);
			}

			if (se->spawn_reply->state == reply_waiting) {
				se->spawn_reply->pid = pid;
				switch_thread_cond_broadcast(se->spawn_reply->ready_or_found);
				ei_x_encode_atom(rbuf, "ok");
				switch_thread_rwlock_unlock(listener->session_rwlock);
				switch_mutex_unlock(se->spawn_reply->mutex);
				return SWITCH_STATUS_SUCCESS;
			}
			switch_mutex_unlock(se->spawn_reply->mutex);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "get_pid came in too late for %s; %s\n", hash, se->uuid_str);
			break;
		}
	}
	switch_thread_rwlock_unlock(listener->session_rwlock);

	ei_x_encode_tuple_header(rbuf, 2);
	ei_x_encode_atom(rbuf, "error");
	ei_x_encode_atom(rbuf, "notfound");

	switch_safe_free(pid);		/* don't need it */

	return SWITCH_STATUS_SUCCESS;
}
Example #11
0
int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
{
    const char* s = buf + *index, * s0 = s;
    int n, sign;
    char c;

    if (term == NULL) return -1;
    c = term->ei_type = get8(s);
    switch (c) {
    case ERL_SMALL_INTEGER_EXT:
	term->value.i_val = get8(s);
	break;
    case ERL_INTEGER_EXT:
	term->value.i_val = get32be(s);
	break;
    case ERL_FLOAT_EXT:
    case NEW_FLOAT_EXT:
        return (ei_decode_double(buf, index, &term->value.d_val) < 0
                ? -1 : 1);
    case ERL_ATOM_EXT:
    case ERL_ATOM_UTF8_EXT:
    case ERL_SMALL_ATOM_EXT:
    case ERL_SMALL_ATOM_UTF8_EXT:
	return (ei_decode_atom(buf, index, term->value.atom_name) < 0
                ? -1 : 1);
    case ERL_REFERENCE_EXT:
    case ERL_NEW_REFERENCE_EXT:
    case ERL_NEWER_REFERENCE_EXT:
        return (ei_decode_ref(buf, index, &term->value.ref) < 0
                ? -1 : 1);
    case ERL_PORT_EXT:
    case ERL_NEW_PORT_EXT:
        return (ei_decode_port(buf, index, &term->value.port) < 0
                ? -1 : 1);
    case ERL_PID_EXT:
    case ERL_NEW_PID_EXT:
        return (ei_decode_pid(buf, index, &term->value.pid) < 0
                ? -1 : 1);
    case ERL_SMALL_TUPLE_EXT:
	term->arity = get8(s);
	break;
    case ERL_LARGE_TUPLE_EXT:
	term->arity = get32be(s);
	break;
    case ERL_NIL_EXT:
	term->arity = 0;
	break;
    case ERL_STRING_EXT:
	term->size = get16be(s);
	return 0;
    case ERL_LIST_EXT:
    case ERL_MAP_EXT:
	term->arity = get32be(s);
	break;
    case ERL_BINARY_EXT:
	term->size = get32be(s);
	return 0;
    case ERL_SMALL_BIG_EXT:
	if ((term->arity = get8(s)) != 4) return -1;
	sign = get8(s);
	/* Little Endian, and n always positive, except for LONG_MIN */
	n = get32le(s);
	if (sign) {
	    /* check for overflow */
	    if ((n - 1) < 0) return -1;
	    n = -n;
	} else {
	    /* check for overflow */
	    if (n < 0) return -1;
	}
	break;
    case ERL_LARGE_BIG_EXT:
	return 0;
    case ERL_PASS_THROUGH:
	return 0;
    case ERL_NEW_CACHE:
	return -1;
    case ERL_CACHED_ATOM:
	return -1;
    default:
	return -1;
    }
    *index += s-s0;
    return 1;
}
Example #12
0
static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
	erlang_ref ref;
	erlang_pid pid;
	char hash[100];
	int arity;
	const void *key;
	void *val;
	session_elem_t *se;
	switch_hash_index_t *iter;
	int found = 0;

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

	if (ei_decode_ref(buf->buff, &buf->index, &ref)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid reference\n");
		return SWITCH_STATUS_FALSE;
	}

	if (ei_decode_pid(buf->buff, &buf->index, &pid)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid pid in a reference/pid tuple\n");
		return SWITCH_STATUS_FALSE;
	}

	ei_hash_ref(&ref, hash);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hashed ref to %s\n", hash);

	switch_thread_rwlock_rdlock(listener->session_rwlock);
	for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
		switch_hash_this(iter, &key, NULL, &val);
		se = (session_elem_t*)val;
		if (se->spawn_reply && !strncmp(se->spawn_reply->hash, hash, 100)) {
			
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found matching session for %s : %s\n", hash, se->uuid_str);

			switch_mutex_lock(se->spawn_reply->mutex);

			se->spawn_reply->pid = switch_core_alloc(se->pool, sizeof(erlang_pid));
			switch_assert(se->spawn_reply->pid != NULL);
			memcpy(se->spawn_reply->pid, &pid, sizeof(erlang_pid));

			switch_thread_cond_signal(se->spawn_reply->ready_or_found);

			switch_mutex_unlock(se->spawn_reply->mutex);

			found++;

			break;
		}
	}
	switch_thread_rwlock_unlock(listener->session_rwlock);

	if (found) {
		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, "notfound");
	}

	return SWITCH_STATUS_SUCCESS;
}