Пример #1
0
int create_server_socket(int port) {

    int sid;
    int one = 1;
    struct sockaddr_in sin;

    const char* hostname = TRAX_LOCALHOST;

    initialize_sockets();

    if((sid = (int) socket(AF_INET,SOCK_STREAM,0)) == -1) {
        return -1;
    }
    
    memset(&sin,0,sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr(hostname);

    sin.sin_port = htons(port);

    if(bind(sid,(struct sockaddr *)&sin,sizeof(sin)) == -1) {
        perror("bind");
        closesocket(sid);
        return -1;
    }

    if(listen(sid, 1)== -1) {
        perror("listen");
        closesocket(sid);
        return -1;
    }

    return sid;

}
Пример #2
0
static SOCKET
tcp_connect( const char *host, int port )
{
	struct addrinfo* result = 0;
	int success;
	SOCKET fd;
	struct addrinfo hint;
	union {
		struct sockaddr_in6 v6;
		struct sockaddr_in v4;
		struct sockaddr_storage storage;
	} sa;

	if(!initialize_sockets())
		return INVALID_SOCKET;

	// Ubuntu 10 and 12 don't implement AI_ADDRCONFIG the same way
	// everyone else does, so we have to turn it off explicitly.
	memset( & hint, 0, sizeof(hint) );
	hint.ai_family = AF_UNSPEC;
	hint.ai_flags = AI_CANONNAME;
	success = getaddrinfo(host, NULL, &hint, &result);

	if (success != 0)
		return INVALID_SOCKET;

	if (result == NULL)
		return INVALID_SOCKET;

	memcpy(&sa.storage, result->ai_addr, result->ai_addrlen );
	switch(result->ai_family) {
		case AF_INET: sa.v4.sin_port = htons(port); break;
		case AF_INET6: sa.v6.sin6_port = htons(port); break;
		default:
			freeaddrinfo( result );
			return INVALID_SOCKET;
	}

#if defined(WIN32)
	// Create the socket with no overlapped I/0 so we can later associate the socket
	// with a valid file descripter using _open_osfhandle.
	fd = WSASocket(result->ai_family, SOCK_STREAM, 0, NULL, 0, 0);
#else
	fd = socket( result->ai_family, SOCK_STREAM, 0 );
#endif
	if(fd == INVALID_SOCKET) {
		freeaddrinfo(result);
		return INVALID_SOCKET;
	}

	success = connect( fd, (struct sockaddr*)&sa.storage, result->ai_addrlen );
	freeaddrinfo(result);
	if(success == SOCKET_ERROR) {
		closesocket(fd);
		return INVALID_SOCKET;
	}

	return fd;
}
Пример #3
0
int main(int argc, char *argv[])
{
    print_init();
    if(argc < 4)
    {
        printf("Usage: server [first addr] [first port] [last port]\n");
    }

    first_name = argv[1];
    port_first = atoi(argv[2]);
    port_last = atoi(argv[3]);
    sensor_timeout = DEF_SENSOR_TIMEOUT;
    sensor_period = DEF_SENSOR_PERIOD;

    if(initialize_sockets() < 0)
    {
        return -1;
    }

    initilize_sockaddr();
    if(bind(sock_last, (struct sockaddr*) &last_addr, sizeof(last_addr)) < 0)
    {
        print_error("Failed to bind socket");
        return -1;
    }

    print_success("Server launched");
    if(initialize_thread() < 0)
    {
        print_error("Failed to init thread");
        return -1;
    }

    if(pthread_create(&reconf_thread, NULL, reconf_fun, NULL) != 0)
    {
        return -1;
    }
    last_loop();
    pthread_join(first_thread, NULL);
    return 0;
}
Пример #4
0
/** @par Detailed Design: */
int Trick::MonteCarlo::master_init() {

    /** <ul><li> Construct the run directory. */
    if (construct_run_directory() == -1) return -1 ;

    /** <ul><li> Create the runs and header files and open them for writing. */
    std::string file_name = run_directory+"/monte_header" ;
    if (open_file(file_name, &run_header_file)==-1) return -1 ;

    file_name = run_directory+"/monte_runs" ;
    if (open_file(file_name, &run_data_file)==-1) return -1 ;

    write_to_run_files(file_name) ;

    /** <li> If this is a dry run return else initialize sockets: */
    if (dry_run) {
       return 0 ;
    }

    return initialize_sockets() ;
}
Пример #5
0
static SOCKET _connect_to_host(int plain, const char *address) {
  SOCKET fd;
  struct sockaddr_in inaddr;
#ifndef WIN32
  struct sockaddr_un unaddr;
#endif
  char name[512];
  int unixsockets;
  unsigned short port;
  struct hostent *hent = NULL;
  struct protoent *prstruc = NULL;

  if ( ! sockets_initialized ) initialize_sockets(NULL,NULL,NULL,NULL);

#ifdef WIN32
  unixsockets = parse_address(address,name,&port,NULL,0);
  if ( unixsockets ) {
    warn("Unix sockets not supported on Windows");
    return INVALID_SOCKET;
  }
#else
  unixsockets = parse_address(address,name,&port,unaddr.sun_path,sizeof(unaddr.sun_path));
#endif /* WIN32 */

  if ( !unixsockets ) {
    hent = gethostbyname(name);
    
    if ( ! hent ) {
      perror("connect_to_host: gethostbyname failed");
      return INVALID_SOCKET;
    }
    
    prstruc = getprotobyname("tcp");
    if ( prstruc == NULL ) {
      perror("connect_to_host: getprotobyname failed");
      return INVALID_SOCKET;
    }
  }

  fd = socket(unixsockets ? AF_UNIX : AF_INET,
	      SOCK_STREAM,
	      unixsockets ? 0 : prstruc->p_proto);
  if ( fd == INVALID_SOCKET ) {
    perror("connect_to_host: socket failed");
    return INVALID_SOCKET;
  }

#ifndef WIN32
  if ( unixsockets ) {
    unaddr.sun_family = AF_UNIX;
    if ( connect(fd,(struct sockaddr *)&unaddr,sizeof(struct sockaddr_un)) < 0 ) {
      perror("connect_to_host: connect failed");
      return INVALID_SOCKET;
    }
  } else {
#else
  if ( 1 ) {
#endif /* WIN32 */
    inaddr.sin_family = AF_INET;
    inaddr.sin_port = htons(port);
    inaddr.sin_addr = *((struct in_addr *)hent->h_addr);
    if ( connect(fd,(struct sockaddr *)&inaddr,sizeof(struct sockaddr_in)) < 0 ) {
      perror("connect_to_host: connect failed");
      return INVALID_SOCKET;
    }
  }
  
#ifndef WIN32
  /* mark close on exec */
  fcntl(fd,F_SETFD,1);
#endif /* WIN32 */

  /* Set a five-minute keepalive in order to dissuade natting routers
     from dropping the connection */
  { int data = 1;
    int n;
    n = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&data, sizeof(int));
    if ( n < 0 ) {
      perror("connect_to_host: setsockopt keepalive failed");
    } else {
#ifdef TCP_KEEPIDLE
      /* this call exists on modern Linuxes, but not everywhere */
      data = 300;
      n = setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &data, sizeof(int));
      if ( n < 0 ) {
	/* of course, this is not supported for unix sockets. We could
	   have checked the address family, but it's probably simpler
	   just to ignore errors */
	if ( errno != ENOTSUP ) {
	  perror("connect_to_host: setsockopt keepidle failed");
	}
      }
#endif
    }
  }

  if ( !plain && skt_open_transform ) {
    return (SOCKET) skt_open_transform(fd);
  } else {
    return fd;
  }
}

SOCKET connect_to_host(const char *address) {
  return _connect_to_host(0,address);
}

SOCKET plain_connect_to_host(const char *address) {
  return _connect_to_host(1,address);
}


/* close a network connection */
static int _close_socket(int plain, SOCKET s) {
  if ( !plain && skt_closer ) {
    return skt_closer((void *)s);
  } else {
    return closesocket(s);
  }
}

int close_socket(SOCKET s) {
  return _close_socket(0,s);
}

int plain_close_socket(SOCKET s) {
  return _close_socket(1,s);
}

/* read a line, up to lf/crlf terminator, from the socket,
   and return it.
   Internal backslashes are removed, unless doubled.
   If the line ends with an unescaped backslash, replace by newline,
   and append the next line.
   If there is an error or end of file before seeing a terminator,
   NULL is returned. At present, error includes reading a partial line.
   The returned string is valid until the next call of get_line.
   This is the internal function implementing the next two;
   the second arg says whether the first is int or SOCKET.
*/
static char *_get_line(SOCKET fd,int is_socket) {
  int length,i,j;
  int offset=0;
  static char *buffer = NULL;
  static size_t buffer_size = 0;

  while ( 1 ) {
    while ( 1 ) {
      while (offset+1 >= (int)buffer_size) { /* +1 to keep some space for '\0' */
	buffer_size = (buffer_size == 0) ? 1024 : (2 * buffer_size);
	buffer = realloc(buffer, buffer_size);
	if (!buffer) {
	  perror("get_line");
	  exit(-1);
	}
      }
      length = (is_socket ?
	(skt_reader ? skt_reader((void *)fd,buffer+offset,1)
		  : 
#ifdef WIN32
		  recv(fd,buffer+offset,1,0)
#else
		  read(fd,buffer+offset,1)
#endif
	 ) : read(fd,buffer+offset,1));
      if ((length <= 0) || (buffer[offset] == '\n'))
	break;
      offset += length;
    }
    if ( offset == 0 ) return NULL;
    if ( length <= 0 ) {
      fprintf(stderr,"get_line read partial line");
      return NULL;
    }
    offset += length;
    buffer[offset] = '\0';
    /* now check for newline */
    if ( buffer[offset-1] == '\n' ) {
      if ( buffer[offset-2] == '\r' && buffer[offset-3] == '\\' ) {
        /* zap the CR */
	buffer[offset-2] = '\n';
	buffer[offset-1] = '\0';
	offset -= 1;
        /* and go onto next clause */
      }
      if ( buffer[offset-2] == '\\' ) {
	/* we have to decide whether this is an escaped backslash */
	int j = 1,k=offset-3;
	while ( k >= 0 && buffer[k--] == '\\' ) j++;
	if ( j & 1 ) {
	  /* odd number, not escaped */
	  buffer[offset-2] = '\n' ;
	  buffer[--offset] = '\0' ;
	  /* read another line */
	} else break; /* return this line */
      } else break; /* return this line */
    } /* no newline, keep going */
  }
  /* now remove internal backslashes */
  for ( i = j = 0; 1; i++, j++ ) {
    if ( buffer[j] == '\\' ) {
      j++;
    }
    buffer[i] = buffer[j];
    if ( !buffer[i] ) break;
  }
  return buffer;
}
Пример #6
0
/* set_up_listening_socket:
   Set up a socket listening on the given address.
   Return its fd.
*/
SOCKET set_up_listening_socket(const char *address) {
  SOCKET sfd;
  struct protoent *prstruc = NULL;
  struct sockaddr_in inaddr;
#ifndef WIN32
  struct sockaddr_un unaddr;
#endif
  int unixsockets;
  unsigned short port;
  char name[256];
  int sockopt;

  if ( ! sockets_initialized ) initialize_sockets(NULL,NULL,NULL,NULL);

  unixsockets = 
#ifdef WIN32
    parse_address(address,name,&port,NULL,0);
#else
    parse_address(address,name,&port,unaddr.sun_path,sizeof(unaddr.sun_path));
#endif /* WIN32 */

#ifdef WIN32
  if ( unixsockets ) {
    warn("unix sockets not available on Windows");
    return INVALID_SOCKET;
  }
#endif /* WINDOWS */

  if ( !unixsockets ) {
    prstruc = getprotobyname("tcp");
    if ( prstruc == NULL ) {
      perror("getprotobyname failed");
      return INVALID_SOCKET;
    }
  }
  sfd = socket(unixsockets ? AF_UNIX : AF_INET,
	       SOCK_STREAM,
	       unixsockets ? 0 : prstruc->p_proto);
  if ( sfd == INVALID_SOCKET ) {
    perror("socket failed");
    return INVALID_SOCKET;
  }

  sockopt=1;
  setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&sockopt,sizeof(int));

#ifndef WIN32
  if ( unixsockets ) {
    unaddr.sun_family = AF_UNIX;
    unlink(unaddr.sun_path); /* need to check success FIXME */
    if ( bind(sfd,(struct sockaddr *)&unaddr,sizeof(struct sockaddr_un)) < 0 ) {
      perror("bind failed");
      return INVALID_SOCKET;
    }
  } else {
#else
  if ( 1 ) {
#endif /* WIN32 */
    inaddr.sin_family = AF_INET;
    inaddr.sin_port = htons(port);
    inaddr.sin_addr.s_addr = INADDR_ANY;
    if ( bind(sfd,(struct sockaddr *)&inaddr,sizeof(struct sockaddr_in)) < 0 ) {
      perror("bind failed");
      return INVALID_SOCKET;
    }
  }

  if ( listen(sfd,5) < 0 ) {
    perror("listen failed");
    return INVALID_SOCKET;
  }
  
  if ( skt_open_transform ) {
    return (SOCKET) skt_open_transform(sfd);
  } else {
    return sfd;
  }
}
  
  

/* accept_new_connection:
   A connection has arrived on the socket fd.
   Accept the connection, and return the new fd,
   or INVALID_SOCKET on error.
*/

SOCKET accept_new_connection(SOCKET fd) {
  SOCKET newfd;
  struct sockaddr saddr;
  struct linger l = { 1, 1000 } ; /* linger on close for 10 seconds */
  socklen_t saddrlen = sizeof(saddr);

  if ( ! sockets_initialized ) initialize_sockets(NULL,NULL,NULL,NULL);

  newfd = accept(fd,&saddr,&saddrlen);
  if ( newfd == INVALID_SOCKET ) { perror("accept failed"); }
  /* we should make sure that data is sent when this socket is closed */
  if ( setsockopt(newfd,SOL_SOCKET,SO_LINGER,(void *)&l,sizeof(l)) < 0 ) {
    warn("setsockopt failed");
  }
  if ( skt_open_transform ) {
    return (SOCKET) skt_open_transform(newfd);
  } else {
    return newfd;
  }
}
Пример #7
0
int main(int argc, char *argv[])
{
  memcached_st *memc;
  memcached_return_t rc;
  memcached_server_st *servers;

  int return_code= 0;

  options_parse(argc, argv);
  initialize_sockets();

  memc= memcached_create(NULL);
  process_hash_option(memc, opt_hash);

  if (!opt_servers)
  {
    char *temp;

    if ((temp= getenv("MEMCACHED_SERVERS")))
    {
      opt_servers= strdup(temp);
    }
    else
    {
      fprintf(stderr, "No Servers provided\n");
      exit(1);
    }
  }

  if (opt_servers)
    servers= memcached_servers_parse(opt_servers);
  else
    servers= memcached_servers_parse(argv[--argc]);

  memcached_server_push(memc, servers);
  memcached_server_list_free(servers);
  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
                         (uint64_t)opt_binary);
  if (!initialize_sasl(memc, opt_username, opt_passwd))
  {
    memcached_free(memc);
    return 1;
  }

  while (optind < argc)
  {
    struct stat sbuf;
    int fd;
    char *ptr;
    ssize_t read_length;
    char *file_buffer_ptr;

    fd= open(argv[optind], O_RDONLY);
    if (fd < 0)
    {
      fprintf(stderr, "memcp: %s: %s\n", argv[optind], strerror(errno));
      optind++;
      continue;
    }

    (void)fstat(fd, &sbuf);

    ptr= rindex(argv[optind], '/');
    if (ptr)
      ptr++;
    else
      ptr= argv[optind];

    if (opt_verbose)
    {
      static const char *opstr[] = { "set", "add", "replace" };
      printf("op: %s\nsource file: %s\nlength: %zu\n"
	     "key: %s\nflags: %x\nexpires: %llu\n",
	     opstr[opt_method - OPT_SET], argv[optind], (size_t)sbuf.st_size,
	     ptr, opt_flags, (unsigned long long)opt_expires);
    }

    if ((file_buffer_ptr= (char *)malloc(sizeof(char) * (size_t)sbuf.st_size)) == NULL)
    {
      fprintf(stderr, "malloc: %s\n", strerror(errno));
      exit(1);
    }

    if ((read_length= read(fd, file_buffer_ptr, (size_t)sbuf.st_size)) == -1)
    {
      fprintf(stderr, "read: %s\n", strerror(errno));
      exit(1);
    }

    if (read_length != sbuf.st_size)
    {
      fprintf(stderr, "Failure reading from file\n");
      exit(1);
    }

    if (opt_method == OPT_ADD)
      rc= memcached_add(memc, ptr, strlen(ptr),
                        file_buffer_ptr, (size_t)sbuf.st_size,
			opt_expires, opt_flags);
    else if (opt_method == OPT_REPLACE)
      rc= memcached_replace(memc, ptr, strlen(ptr),
			    file_buffer_ptr, (size_t)sbuf.st_size,
			    opt_expires, opt_flags);
    else
      rc= memcached_set(memc, ptr, strlen(ptr),
                        file_buffer_ptr, (size_t)sbuf.st_size,
                        opt_expires, opt_flags);

    if (rc != MEMCACHED_SUCCESS)
    {
      fprintf(stderr, "memcp: %s: memcache error %s",
	      ptr, memcached_strerror(memc, rc));
      if (memc->cached_errno)
	fprintf(stderr, " system error %s", strerror(memc->cached_errno));
      fprintf(stderr, "\n");

      return_code= -1;
    }

    free(file_buffer_ptr);
    close(fd);
    optind++;
  }

  memcached_free(memc);

  if (opt_servers)
    free(opt_servers);
  if (opt_hash)
    free(opt_hash);
  shutdown_sasl();

  return return_code;
}
Пример #8
0
void mexFunction(int nlhs, mxArray *plhs[],
								int nrhs, const mxArray *prhs[])
{
	int *sock;
	struct hostent *hp;
	struct sockaddr_in pin;
	char *hostname;
	int port;
	int one = 1;

#if defined(WIN32)
  if(!initialized) initialize_sockets();
#endif

	/* Go ahead and create the output socket */
	plhs[0] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL);
	sock = (int *)mxGetPr(plhs[0]);
	sock[0] = -1;

	/* Verify the input */
	if(nrhs < 2) {
		mexPrintf("Must input a hostname and a port\n");
		return;
	}
	if(!mxIsNumeric(prhs[1])) {
		mexPrintf("Port must be numeric.\n");
		return;
	}
	if(!mxIsChar(prhs[0])) {
		mexPrintf("Hostname must be a string.\n");
		return;
	}
	
	/* Get the input */
	port = (int) mxGetScalar(prhs[1]);
	hostname = mxArrayToString(prhs[0]);

	memset(&pin,0,sizeof(pin));
	pin.sin_family = AF_INET;
	pin.sin_port = htons(port);
	if((hp = gethostbyname(hostname))!=0) 
		pin.sin_addr.s_addr = 
			((struct in_addr *)hp->h_addr)->s_addr;
	else 
		pin.sin_addr.s_addr = inet_addr(hostname);
	
	if((sock[0] = (int)socket(AF_INET,SOCK_STREAM,0)) == -1) { // SOCK_DGRAM,
		perror("socket");
		return;
	}

    // Added by Shay:
    
    setsockopt(sock[0],IPPROTO_TCP,TCP_NODELAY,(const char *)&one,sizeof(int));
	
	if(connect(sock[0],(const struct sockaddr *)&pin,sizeof(pin))) {
		perror("connect");
#if !defined(WIN32)
		close(sock[0]);
#else
		closesocket(sock[0]);
#endif
		sock[0] = -1;
		return;
	}
	return;
} /* end of mexFunction */
Пример #9
0
/**
 * Program entry point. Connect to a memcached server and use the binary
 * protocol to retrieve a given set of stats.
 *
 * @param argc argument count
 * @param argv argument vector
 * @return 0 if success, error code otherwise
 */
int main(int argc, char **argv)
{
    int cmd;
    const char * const default_ports[] = { "memcache", "11211", NULL };
    const char *port = NULL;
    const char *host = NULL;
    const char *user = NULL;
    const char *pass = NULL;
    char *ptr;

    /* Initialize the socket subsystem */
    initialize_sockets();

    while ((cmd = getopt(argc, argv, "h:p:u:P:")) != EOF) {
        switch (cmd) {
        case 'h' :
            host = optarg;
            ptr = strchr(optarg, ':');
            if (ptr != NULL) {
                *ptr = '\0';
                port = ptr + 1;
            }
            break;
        case 'p':
            port = optarg;
            break;
        case 'u' :
            user = optarg;
            break;
        case 'P':
            pass = optarg;
            break;
        default:
            fprintf(stderr,
                    "Usage mcstat [-h host[:port]] [-p port] [-u user] [-p pass] [statkey]*\n");
            return 1;
        }
    }

    if (host == NULL) {
        host = "localhost";
    }

    int sock = -1;
    if (port == NULL) {
        int ii = 0;
        do {
            port = default_ports[ii++];
            sock = connect_server(host, port, user, pass);
        } while (sock == -1 && default_ports[ii] != NULL);
    } else {
        sock = connect_server(host, port, user, pass);
    }

    if (sock == -1) {
        return 1;
    }

    if (optind == argc) {
        request_stat(sock, NULL);
    } else {
        for (int ii = optind; ii < argc; ++ii) {
            request_stat(sock, argv[ii]);
        }
    }

    close(sock);

    return 0;
}
Пример #10
0
int main(int argc, char *argv[])
{
  memcached_st *memc;
  char *string;
  size_t string_length;
  uint32_t flags;
  memcached_return_t rc;
  memcached_server_st *servers;

  int return_code= 0;

  options_parse(argc, argv);
  initialize_sockets();

  if (!opt_servers)
  {
    char *temp;

    if ((temp= getenv("MEMCACHED_SERVERS")))
      opt_servers= strdup(temp);
    else
    {
      fprintf(stderr, "No Servers provided\n");
      exit(1);
    }
  }

  memc= memcached_create(NULL);
  process_hash_option(memc, opt_hash);

  servers= memcached_servers_parse(opt_servers);

  memcached_server_push(memc, servers);
  memcached_server_list_free(servers);
  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
                         (uint64_t)opt_binary);

  if (!initialize_sasl(memc, opt_username, opt_passwd))
  {
    memcached_free(memc);
    return EXIT_FAILURE;
  }

  while (optind < argc)
  {
    string= memcached_get(memc, argv[optind], strlen(argv[optind]),
                          &string_length, &flags, &rc);
    if (rc == MEMCACHED_SUCCESS)
    {
      if (opt_displayflag)
      {
        if (opt_verbose)
          printf("key: %s\nflags: ", argv[optind]);
        printf("%x\n", flags);
      }
      else
      {
        if (opt_verbose)
        {
          printf("key: %s\nflags: %x\nlength: %zu\nvalue: ",
                 argv[optind], flags, string_length);
        }

        if (opt_file)
        {
          FILE *fp;
          size_t written;

          fp= fopen(opt_file, "w");
          if (!fp)
          {
            perror("fopen");
            return_code= -1;
            break;
          }

          written= fwrite(string, 1, string_length, fp);
          if (written != string_length) 
          {
            fprintf(stderr, "error writing file (written %zu, should be %zu)\n", written, string_length);
            return_code= -1;
            break;
          }

          if (fclose(fp))
          {
            fprintf(stderr, "error closing file\n");
            return_code= -1;
            break;
          }
        }
        else
        {
            printf("%.*s\n", (int)string_length, string);
        }
        free(string);
      }
    }
    else if (rc != MEMCACHED_NOTFOUND)
    {
      fprintf(stderr, "memcat: %s: memcache error %s",
              argv[optind], memcached_strerror(memc, rc));
      if (memcached_last_error_errno(memc))
      {
	fprintf(stderr, " system error %s", strerror(memcached_last_error_errno(memc)));
      }
      fprintf(stderr, "\n");

      return_code= -1;
      break;
    }
    else // Unknown Issue
    {
      fprintf(stderr, "memcat: %s not found\n", argv[optind]);
      return_code= -1;
    }
    optind++;
  }

  memcached_free(memc);

  if (opt_servers)
    free(opt_servers);
  if (opt_hash)
    free(opt_hash);

  shutdown_sasl();

  return return_code;
}