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 + -
显示快捷键?