⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mg.c

📁 一个Megaco实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      usage();      exit(-1);    }  }  /**   * check arguments    */  if (strlen(host) == 0) {    if ((gethostname(host,HOSTNAMESZ))) {      fprintf(stderr,"can't find own hostname\n");      exit(-1);    }  }  if (strlen(fhost) == 0) {    strcpy(fhost,host);  }  if (strlen(mhost) == 0) {    strcpy(mhost,host);  }  /* Check that it was a valid transport (tcp or udp) */  if (!((strcmp(transport,TRANSPORT_TCP) == 0) || 	(strcmp(transport,TRANSPORT_UDP) == 0))) {    fprintf(stderr,"ERROR: invalid transport: '%s'\n", transport);    usage();    exit(-1);  }      /* Check that it was a valid transport (tcp or udp) */  if (!((strcmp(encoding,ENCODING_TEXT) == 0) || 	(strcmp(encoding,ENCODING_BIN) == 0))) {    fprintf(stderr,"ERROR: invalid encoding: '%s'\n", encoding);    usage();    exit(-1);  }      sprintf(fnode, "%s@%s", fname, fhost);  V( ("settings: \n"      "  name:              %s\n"      "  device name:       %s\n"      "  mgc host:          %s\n"      "  transport:         %s\n"      "  encoding:          %s\n"      "  factory host:      %s\n"      "  factory node name: %s\n",       uname, dname, mhost, transport, encoding, fhost, fname) );}static void usage() {  fprintf(stderr, 	  "usage: mg [-cookie <cookie> -mhost <mhost> -t <transport> -e <encoding> -uname <uname> -fname <fname> -fhost <fhost> -h -v]\n\n"	  "  -h               Prints this information\n"	  "  -v               Verbose mode\n"	  "  -stop            Perform proper stop sequence when connection\n"	  "                   has been estabished\n"	  "  -cookie <cookie> Sets the magic cookie of this node to <cookie>\n"	  "                   Default is retrieved from cookie file\n"	  "  -t <transport>   Which transport to use, " TRANSPORT_TCP " or " TRANSPORT_UDP ". \n"	  "                   Default is '" TRANSPORT_DEFAULT "'\n"	  "  -e <encoding>    Which encoding to use, " ENCODING_TEXT " or " ENCODING_BIN ". \n"	  "                   Default is '" ENCODING_DEFAULT "'\n"          "  -dname <name>    Device name (mid) of this mg. Default is '"          DNAME_DEFAULT "'.\n"	  "  -mhost <mhost>   Host of the MGC. \n"	  "                   Default is localhost\n"	  "  -sname <name>    Name of this session user node. Default is '"	  UNAME_DEFAULT "'.\n"	  "                   This will be used to form the MG deviceName\n"	  "                   gateway_<uname>. Defaults to: 'gateway_" UNAME_DEFAULT "'\n"	  "  -name <name>     Fully quallified name of this session user "	  "c-node.\n"	  "                   The structure of this is <name>@<host>. \n"	  "                   Example: " UNAME_DEFAULT "@hobbes.ericsson.se \n"	  "                   The <name> part will be used to form the MG \n"	  "                   deviceName gateway_<name>. \n"	  "  -fname <fname>   Name of the session factory node (as given by -sname). \n"	  "                   Default is '" FNAME_DEFAULT "'\n"	  "  -fhost <fhost>   Host of the session factory node. \n"	  "                   Default is localhost\n\n");}/* Server Loop * This should be utilized in a concurrent manner as three or more threads: * - one thread that only receives Erlang messages and *   copies them into an incoming mailbox queue. If the *   message is a synchronous gen_server call, the sending *   pid and the unique message refreence also needs to be *   copied. * - a pool of worker threads that picks messages from *   the incoming mailbox, handles them and possibly *   puts them into an outbound mailbox. * - one thread that only picks messages from the *   outbound queue and sends Erlang messages. */ static void mg_main(CORBA_Environment *s_env,		    CORBA_Environment *r_env,		    int                sd, 		    int                epmd_fd) {  ___map___* map;  erlang_msg msg;  int status = 1;        /* Initiate the call table */    map = InitSwitch();    while (status >= 0) {      /* write message to buffer */      V( ("await message\n") );      status = ei_receive_encoded(s_env->_fd, 				  &s_env->_inbuf, 				  &s_env->_inbufsz, 				  &msg, 				  &s_env->_iin);             V( ("receive status: %d\n", status) );            switch(status) {      case ERL_SEND:      case ERL_REG_SEND :	/* Switch incoming */	___switch___(r_env, s_env, map);		switch(s_env->_major) {	case CORBA_NO_EXCEPTION: /* Success */	  break;	case CORBA_SYSTEM_EXCEPTION: /* System exception */	  printf("Request failure, reason : %s\n",		 (char *) CORBA_exception_value(s_env));	  CORBA_exception_free(s_env);	  break;	default: /* Should not come here */	  CORBA_exception_free(s_env);	  break;	}		/* send outdata */	if (s_env->_iout > 0) {	  V( ("send data: %d\n", s_env->_iout) );	  ei_send_encoded(s_env->_fd,			  &s_env->_caller,			  s_env->_outbuf,			  s_env->_iout);	}	break;	      case ERL_TICK :	V( ("received tick\n") );	break;      default : /* < 0 */	printf("Connection terminated\n");	break;      }      }} /* Stopping node */extern void mg_exit(CORBA_Environment *s_env,		    CORBA_Environment *r_env) {    /* Close connection */  V( ("exiting -> close erl connection\n") );  erl_close_connection(s_env->_fd);    /* Close file descriptors */  eterminate(&s_env->_fd, &sd, &epmd_fd);  /* Free env & buffers */  V( ("exiting -> free environment and buffers\n") );  CORBA_free(r_env->_inbuf);  CORBA_free(r_env->_outbuf);  CORBA_free(r_env);  CORBA_free(s_env->_inbuf);  CORBA_free(s_env->_outbuf);  CORBA_free(s_env);    exit(1);}static ___map___* InitSwitch() {        ___map___ marray[3] = {       ___Megaco_SessionUser_map___,	___MegacoSessionTcpUser_map___, 	___MegacoSessionUdpUser_map___    };      return ___merge___(marray,3);}static int einit(int *sd, int *portnr, int *epmd_fd) {  struct hostent *h;    /* identify host */  V( ("initiating -> identify host (%s)\n", host) );  if (!(h = erl_gethostbyname(host)))    fprintf(stderr,"can't find own ip address\n");  else {        /* get a listen port. 0 means let system choose port number */    V( ("initiating -> get listen port: ") );    *sd = getlisten(0);          /* what port did we get? */    /* this call not necessary if we specified port in call to getlisten() */    *portnr = getport(*sd);    V( ("%d\n", *portnr) );        /* make our nodename server@host */    sprintf(unode,"%s@%s", uname, host);        /* initiate */    V( ("initiating -> erl initiate\n") );    erl_init(NULL,0);        /* host, alive, alive@host, addr, cookie, creation */    V( ("initiating -> erl connect\n") );    erl_connect_xinit(host, uname,		      unode,(Erl_IpAddr)(h->h_addr_list[0]),cookie,0);        /* let epmd know we are here */    V( ("initiating -> erl publish (let EPMD know we are here)\n") );    *epmd_fd = erl_publish(*portnr);        /* Create and init CORBA_Environments */    V( ("initiating -> create CORBA environment\n") );    send_env    = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); /* env for local side */    receive_env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); /* env for remote side */        /* Connect to other side */    fprintf(stderr, "Connecting to '%s'...", fnode);    send_env->_fd = erl_connect(fnode);        if (send_env->_fd < 0) { /* error */      fprintf(stderr,"\nERROR: Connection failed: %s\n", strerror(errno));      mg_exit(send_env, receive_env);    }         fprintf(stderr, "done\n");    receive_env->_fd = send_env->_fd;        return 0;  }   return -1;}static void eterminate(int *fd, int *sd, int *epmd_fd) {    close(*fd);        /* remove info from epmd */    close(*epmd_fd);        /* return socket */    close(*sd);}/* tells you what port you are using on given socket */static int getport(int sockd) {  struct sockaddr_in addr;  int namelen = sizeof(addr);  int i;  memset(&addr,0,sizeof(addr));    if ((i = getsockname(sockd,(struct sockaddr *)&addr,&namelen))<0)    return i;    return ntohs(addr.sin_port);}/* return a listen socket, bound to given port *//* specify port = 0 to let system assign port */static int getlisten(int port) {  int sockd;  struct sockaddr_in inaddr;  int opt = 1;  int i;  /* get listen socket */  if ((sockd = socket(AF_INET,SOCK_STREAM,0)) < 0) return sockd;    if ((i=setsockopt(sockd,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)))<0)     return i;  /* bind to requested port */  memset(&inaddr,0,sizeof(inaddr));  inaddr.sin_family = AF_INET;                inaddr.sin_addr.s_addr = htonl(INADDR_ANY);   inaddr.sin_port = htons(port);  if ((i = bind(sockd,(struct sockaddr*) &inaddr, sizeof(inaddr))) < 0)    return i;  listen(sockd,5);  return sockd;}

⌨️ 快捷键说明

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