erl_call.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 904 行 · 第 1/2 页

C
904
字号
	  if (ei_rpc(&ec, fd, "file", "write_file", p, i, &reply) < 0) {	      free(p);	      ei_x_free(&reply);	      fprintf(stderr,"erl_call: can't write to source file %s\n",		      fname);	      exit(1);	  }	  free(p);	  ei_x_free(&reply);      }           /* Compile AND load file on other node */      {	  int i = 0;	  char *p;	  ei_x_buff reply;	  ei_encode_list_header(NULL, &i, 2);	  ei_encode_atom(NULL, &i, fname);	  ei_encode_empty_list(NULL, &i);	  ei_encode_empty_list(NULL, &i);	  p = (char *)malloc(i);	  i = 0;		/* Reset */	  	  ei_encode_list_header(p, &i, 2);	  ei_encode_atom(p, &i, fname);	  ei_encode_empty_list(p, &i);	  ei_encode_empty_list(p, &i);	  ei_x_new_with_version(&reply);	  /* erl_format("[~a,[]]", modname) */	  if (ei_rpc(&ec, fd, "c", "c", p, i, &reply) < 0) {	      free(p);	      ei_x_free(&reply);	      fprintf(stderr,"erl_call: can't compile file %s\n", fname);	  }	  free(p);	  /* FIXME complete this code	     FIXME print out error message as term	  if (!erl_match(erl_format("{ok,_}"), reply)) {	      fprintf(stderr,"erl_call: compiler errors\n");	  }	  */	  ei_x_free(&reply);      }         }    /*     * Eval the Erlang functions read from stdin/     */    if (flags.evalp) {      char *evalbuf;      int len;      len = read_stdin(&evalbuf);      {	  int i = 0;	  char *p;	  ei_x_buff reply;	  ei_encode_list_header(NULL, &i, 1);	  ei_encode_binary(NULL, &i, evalbuf, len);	  ei_encode_empty_list(NULL, &i);	  p = (char *)malloc(i);	  i = 0;		/* Reset */	  	  ei_encode_list_header(p, &i, 1);	  ei_encode_binary(p, &i, evalbuf, len);	  ei_encode_empty_list(p, &i);	  ei_x_new_with_version(&reply);	  /* erl_format("[~w]", erl_mk_binary(evalbuf,len))) */	  if (ei_rpc(&ec, fd, "lib", "eval_str", p, i, &reply) < 0) {	      fprintf(stderr,"erl_call: evaluating input failed: %s\n",		      evalbuf);	      free(p);	      free(evalbuf);	/* Allocated in read_stdin() */	      ei_x_free(&reply);	      exit(1);	  }	  i = 0;	  ei_print_term(stdout,reply.buff,&i);	  free(p);	  free(evalbuf);	/* Allocated in read_stdin() */	  ei_x_free(&reply);      }    }    /*     * Any Erlang call to be made ?     */    if (flags.apply != NULL) {      char *mod,*fun,*args;      ei_x_buff e, reply;      split_apply_string(flags.apply, &mod, &fun, &args);      if (flags.verbosep) {	  fprintf(stderr,"erl_call: module = %s, function = %s, args = %s\n",		  mod, fun, args);      }      ei_x_new(&e);		/* No version to ei_rpc() */            if (ei_x_format_wo_ver(&e, args) < 0) {	  /* FIXME no error message and why -1 ? */	  exit(-1);      }      ei_x_new_with_version(&reply);      if (ei_rpc(&ec, fd, mod, fun, e.buff, e.index, &reply) < 0) {	  /* FIXME no error message and why -1 ? */	  ei_x_free(&e);	  ei_x_free(&reply);	  exit(-1);      } else {	  int i = 0;	  ei_print_term(stdout,reply.buff,&i);	  ei_x_free(&e);	  ei_x_free(&reply);      }    }    return(0);}/*************************************************************************** * *  XXXXX * ***************************************************************************//* * Get host entry (by address or name) *//* FIXME: will fail on names like '2fun4you'.  */static struct hostent* get_hostent(char *host){  if (isdigit((int)*host)) {    struct in_addr ip_addr;    int b1, b2, b3, b4;    long addr;          /* FIXME: Use inet_aton() (or inet_pton() and get v6 for free). */    if (sscanf(host, "%d.%d.%d.%d", &b1, &b2, &b3, &b4) != 4) {	return NULL;    }    addr = inet_addr(host);    ip_addr.s_addr = htonl(addr);          return ei_gethostbyaddr((char *)&ip_addr,sizeof(struct in_addr), AF_INET);  }  return ei_gethostbyname(host);} /* get_hostent *//*  * This function does only return on success. */static int do_connect(ei_cnode *ec, char *nodename, struct call_flags *flags){    int fd;    int start_flags;    int r;    start_flags = ERL_START_ENODE |	(flags->use_long_name? ERL_START_LONG : 0) |	(flags->verbosep? ERL_START_VERBOSE : 0) |	(flags->debugp? ERL_START_DEBUG : 0);    if ((fd = ei_connect(ec, nodename)) >= 0) {	/* success */	if (flags->verbosep) {	    fprintf(stderr,"erl_call: now connected to node %s\n", nodename);	}    } else {	char alive[EI_MAXALIVELEN+1];	char *hostname;	struct hostent *h;	char *cookieargs[3];	char **args;	cookieargs[0] = "-setcookie";	cookieargs[1] = flags->cookie;	cookieargs[2] = NULL;	args = (flags->cookie) ? cookieargs : NULL;	if (!(hostname = strrchr(nodename,'@'))) {	    return ERL_BADARG;	}	strncpy(alive,nodename,hostname-nodename);	alive[hostname-nodename] = 0x0;	hostname++;	h = ei_gethostbyname(hostname);	if ((r=erl_start_sys(ec,alive,(Erl_IpAddr)(h->h_addr_list[0]),			     start_flags,flags->script,args)) < 0) {	    fprintf(stderr,"erl_call: unable to start node, error = %d\n", r);	    exit(1);	}	if ((fd=ei_connect(ec, nodename)) >= 0) {	    /* success */	    if (flags->verbosep) {		fprintf(stderr,"erl_call: now connected to node \"%s\"\n",			nodename);	    }	} else {	    /* (failure) */	    switch (fd) {	    case ERL_NO_DAEMON:		fprintf(stderr,"erl_call: no epmd running\n");		exit(1);	    case ERL_CONNECT_FAIL:		fprintf(stderr,"erl_call: connect failed\n");		exit(1);	    case ERL_NO_PORT:		fprintf(stderr,"erl_call: node is not running\n");		exit(1);	    case ERL_TIMEOUT:		fprintf(stderr,"erl_call: connect timed out\n");		exit(1);	    default:		fprintf(stderr,"erl_call: error during connect\n");		exit(1);	    }	}    }    return fd;} /* do_connect */#define SKIP_SPACE(s) while(isspace((int)*(s))) (s)++#define EAT(s) while (!isspace((int)*(s)) && (*(s) != '\0')) (s)++static void split_apply_string(char *str, 			       char **mod, 			       char **fun, 			       char **args){  char *begin=str;  char *start="start";  char *empty_list="[]";  int len;  SKIP_SPACE(str);  if (*str == '\0') {      fprintf(stderr,"erl_call: wrong format of apply string (1)\n");      exit(1);  }  EAT(str);  len = str-begin;  *mod = (char *) calloc(len + 1, sizeof(char));  memcpy(*mod, begin, len);  SKIP_SPACE(str);  if (*str == '\0') {    *fun = (char *) calloc(strlen(start)+1, sizeof(char));    strcpy(*fun, start);    *args = (char *) calloc(strlen(empty_list)+1, sizeof(char));    strcpy(*args, empty_list);    return;  }  begin = str;  EAT(str);  len = str-begin;  *fun = (char *) calloc(len + 1, sizeof(char));  memcpy(*fun, begin, len);  SKIP_SPACE(str);  if (*str == '\0') {    *args = (char *) calloc(strlen(empty_list)+1, sizeof(char));    strcpy(*args, empty_list);    return;  }  *args = (char *) calloc(strlen(str) + 1, sizeof(char));  strcpy(*args, str);    return;} /* split_apply_string *//*  * Read from stdin until EOF is reached. * Allocate the buffer needed. */static int read_stdin(char **buf){    int bsize = BUFSIZ;    int len = 0;    int i;    char *tmp = (char *) malloc(bsize);    while (1) {	if ((i = read(0, &tmp[len], bsize-len)) < 0) {	    fprintf(stderr,"erl_call: can't read stdin, errno = %d", errno);	    exit(1);	} else if (i == 0) {	    break;	} else {	    len += i;	    if ((len+50) > bsize) {		bsize = len * 2;		tmp = (char *) realloc(tmp, bsize);	    } else {		continue;	    }	}    } /* while */    *buf = tmp;    return len;} /* read_stdin *//* * Get the module from stdin. */static int get_module(char **mbuf, char **mname){  char *tmp;  int len,i;  len = read_stdin(mbuf);  /*   * Now, get the module name.   */  if ((tmp = strstr(*mbuf, "-module(")) != NULL) {    char *start;    tmp += strlen("-module(");    while ((*tmp) == ' ') tmp++; /* eat space */    start = tmp;    while (1) {      if (isalnum((int)*tmp) || (*tmp == '_')) {	tmp++;	continue;      } else {	  break;      }    } /* while */    i = tmp - start;    *mname = (char *) calloc(i+1, sizeof(char));    memcpy(*mname, start, i);  }  free(mbuf);			/* Allocated in read_stdin() */  return len;} /* get_module *//*************************************************************************** * *  Different error reporting functions that output usage  * ***************************************************************************/static void usage_noexit(const char *progname) {  fprintf(stderr,"\nUsage: %s [-[demqrsv]] [-c Cookie] [-h HiddenName] \n", progname);  fprintf(stderr,"            [-x ErlScript] [-a [Mod [Fun [Args]]]]\n");  fprintf(stderr,"            (-n Node | -sname Node | -name Node)\n\n");#ifdef __WIN32__  fprintf(stderr,"  where: -a  apply(Mod,Fun,Args) (e.g -a \"erlang length [[a,b,c]]\"\n");#else  fprintf(stderr,"  where: -a  apply(Mod,Fun,Args) (e.g -a 'erlang length [[a,b,c]]'\n");#endif  fprintf(stderr,"         -c  cookie string; by default read from ~/.erlang.cookie\n");  fprintf(stderr,"         -d  direct Erlang output to ~/.erl_call.out.<Nodename>\n");  fprintf(stderr,"         -e  evaluate contents of standard input (e.g echo \"X=1,Y=2,{X,Y}.\"|erl_call -e ...)\n");  fprintf(stderr,"         -h  specify a name for the erl_call client node\n");  fprintf(stderr,"         -m  read and compile Erlang module from stdin\n");  fprintf(stderr,"         -n  name of Erlang node, same as -name\n");  fprintf(stderr,"         -name  name of Erlang node, expanded to a fully qualified\n");  fprintf(stderr,"         -sname name of Erlang node, short form will be used\n");  fprintf(stderr,"         -q  halt the Erlang node (overrides the -s switch)\n");  fprintf(stderr,"         -r  use a random name for the erl_call client node\n");  fprintf(stderr,"         -s  start a new Erlang node if necessary\n");  fprintf(stderr,"         -v  verbose mode, i.e print some information on stderr\n");  fprintf(stderr,"         -x  use specified erl start script, default is erl\n");}static void usage_arg(const char *progname, const char *switchname) {  fprintf(stderr, "Missing argument(s) for \'%s\'.\n", switchname);  usage_noexit(progname);  exit(1);}static void usage_error(const char *progname, const char *switchname) {  fprintf(stderr, "Illegal argument \'%s\'.\n", switchname);  usage_noexit(progname);  exit(1);}static void usage(const char *progname) {  usage_noexit(progname);  exit(0);}/*************************************************************************** * *  OS specific functions * ***************************************************************************/#ifdef __WIN32__/* * FIXME This should not be here.  This is a quick fix to make erl_call * work at all on Windows NT. */static void initWinSock(void){    WORD wVersionRequested;      WSADATA wsaData;     int err;     static int initialized;    wVersionRequested = MAKEWORD(1, 1);     if (!initialized) {	initialized = 1;	err = WSAStartup(wVersionRequested, &wsaData);  	if (err != 0) {	    fprintf(stderr,"erl_call: "		    "Can't initialize windows sockets: %d\n", err);	}  	if ( LOBYTE( wsaData.wVersion ) != 1 || 	    HIBYTE( wsaData.wVersion ) != 1 ) { 	    fprintf(stderr,"erl_call: This version of "		    "windows sockets not supported\n");	    WSACleanup(); 	}    }}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?