Example #1
0
int
main(int argc, char * argv[])
{
	/* State variables. */
	int * socks_s;
	int sock_t;
	struct wire_requestqueue * Q_t;
	struct dispatch_state * dstate;

	/* Command-line parameters. */
	intmax_t opt_n = 0;
	char * opt_p = NULL;
	char * opt_t = NULL;
	ADDRLIST opt_s;
	char * opt_s_1 = NULL;

	/* Working variables. */
	size_t opt_s_size;
	struct sock_addr ** sas;
	size_t i;
	const char * ch;

	WARNP_INIT;

	/* We have no addresses to listen on yet. */
	if ((opt_s = addrlist_init(0)) == NULL) {
		warnp("addrlist_init");
		exit(1);
	}

	/* Parse the command line. */
	while ((ch = GETOPT(argc, argv)) != NULL) {
		GETOPT_SWITCH(ch) {
		GETOPT_OPTARG("-n"):
			if (opt_n != 0)
				usage();
			if (PARSENUM(&opt_n, optarg, 0, 65535)) {
				warn0("Invalid option: -n %s", optarg);
				usage();
			}
			break;
		GETOPT_OPTARG("-p"):
			if (opt_p != NULL)
				usage();
			if ((opt_p = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-s"):
			/* Keep a copy of the path for pidfile generation. */
			if ((opt_s_1 == NULL) &&
			    ((opt_s_1 = strdup(optarg)) == NULL))
				OPT_EPARSE(ch, optarg);

			/* Attempt to resolve to a list of addresses. */
			if ((sas = sock_resolve(optarg)) == NULL) {
				warnp("Cannot resolve address: %s", optarg);
				exit(1);
			}
			if (sas[0] == NULL) {
				warn0("No addresses found for %s", optarg);
				exit(1);
			}

			/* Push pointers to addresses onto the list. */
			for (i = 0; sas[i] != NULL; i++) {
				if (addrlist_append(opt_s, &sas[i], 1))
					OPT_EPARSE(ch, optarg);
			}

			/* Free the array (but keep the addresses). */
			free(sas);
			break;
		GETOPT_OPTARG("-t"):
			if (opt_t != NULL)
				usage();
			if ((opt_t = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPT("--version"):
			fprintf(stderr, "kivaloo-mux @VERSION@\n");
			exit(0);
		GETOPT_MISSING_ARG:
			warn0("Missing argument to %s\n", ch);
			usage();
		GETOPT_DEFAULT:
			warn0("illegal option -- %s\n", ch);
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	/* We should have processed all the arguments. */
	if (argc != 0)
		usage();

	/* Sanity-check options. */
	if ((opt_s_size = addrlist_getsize(opt_s)) == 0)
		usage();
	if (opt_t == NULL)
		usage();

	/* Resolve target address. */
	if ((sas = sock_resolve(opt_t)) == NULL) {
		warnp("Error resolving socket address: %s", opt_t);
		exit(1);
	}
	if (sas[0] == NULL) {
		warn0("No addresses found for %s", opt_t);
		exit(1);
	}

	/* Connect to the target. */
	if ((sock_t = sock_connect(sas)) == -1)
		exit(1);

	/* Free the target address(es). */
	sock_addr_freelist(sas);

	/* Create a queue of requests to the target. */
	if ((Q_t = wire_requestqueue_init(sock_t)) == NULL) {
		warnp("Cannot create request queue");
		exit(1);
	}

	/* Allocate array of source sockets. */
	if ((socks_s = malloc(opt_s_size * sizeof(int))) == NULL) {
		warnp("malloc");
		exit(1);
	}

	/* Create listening sockets. */
	for (i = 0; i < opt_s_size; i++) {
		if ((socks_s[i] =
		    sock_listener(*addrlist_get(opt_s, i))) == -1)
			exit(1);
	}

	/* Initialize the dispatcher. */
	if ((dstate = dispatch_init(socks_s, opt_s_size,
	    Q_t, opt_n ? (size_t)opt_n : SIZE_MAX)) == NULL) {
		warnp("Failed to initialize dispatcher");
		exit(1);
	}

	/* Daemonize and write pid. */
	if (opt_p == NULL) {
		if (asprintf(&opt_p, "%s.pid", opt_s_1) == -1) {
			warnp("asprintf");
			exit(1);
		}
	}
	if (daemonize(opt_p)) {
		warnp("Failed to daemonize");
		exit(1);
	}

	/* Loop until the dispatcher is finished. */
	do {
		if (events_run()) {
			warnp("Error running event loop");
			exit(1);
		}
	} while (dispatch_alive(dstate));

	/* Clean up the dispatcher. */
	dispatch_done(dstate);

	/* Shut down the request queue. */
	wire_requestqueue_destroy(Q_t);
	wire_requestqueue_free(Q_t);

	/* Close sockets. */
	for (i = 0; i < opt_s_size; i++)
		close(socks_s[i]);
	free(socks_s);
	close(sock_t);

	/* Free source socket addresses. */
	for (i = 0; i < addrlist_getsize(opt_s); i++)
		sock_addr_free(*addrlist_get(opt_s, i));
	addrlist_free(opt_s);

	/* Shut down the event subsystem. */
	events_shutdown();

	/* Free option strings. */
	free(opt_p);
	free(opt_s_1);
	free(opt_t);

	/* Success! */
	return (0);
}
Example #2
0
/*
 * Free all malloc'ed memory for the specified service
 */
void sc_free( struct service_config *scp )
{
#ifdef HAVE_MDNS
   COND_FREE( SC_MDNS_NAME(scp) );
   xinetd_mdns_svc_free(scp);
#endif
#ifdef LIBWRAP
   COND_FREE( SC_LIBWRAP(scp) );
#endif
   COND_FREE( SC_NAME(scp) ) ;
   COND_FREE( SC_ID(scp) ) ;
   COND_FREE( SC_PROTONAME(scp) ) ;
   COND_FREE( SC_SERVER(scp) ) ;
   COND_FREE( (char *)SC_REDIR_ADDR(scp) ) ;
   COND_FREE( (char *)SC_BIND_ADDR(scp) ) ;
   COND_FREE( (char *)SC_ORIG_BIND_ADDR(scp) ) ;
   COND_FREE( (char *)SC_BANNER(scp) ) ;
   COND_FREE( (char *)SC_BANNER_SUCCESS(scp) ) ;
   COND_FREE( (char *)SC_BANNER_FAIL(scp) ) ;
   if ( SC_SERVER_ARGV(scp) )
   {
      char **pp ;

      /*
       * argv[ 0 ] is a special case because it may not have been allocated yet
       */
      if ( SC_SERVER_ARGV(scp)[ 0 ] != NULL)
         free( SC_SERVER_ARGV(scp)[ 0 ] ) ;
      for ( pp = &SC_SERVER_ARGV(scp)[ 1 ] ; *pp != NULL ; pp++ )
         free( *pp ) ;
      free( (char *) SC_SERVER_ARGV(scp) ) ;
   }
   COND_FREE( LOG_GET_FILELOG( SC_LOG( scp ) )->fl_filename ) ;

   if ( SC_ACCESS_TIMES(scp) != NULL )
   {
      ti_free( SC_ACCESS_TIMES(scp) ) ;
      pset_destroy( SC_ACCESS_TIMES(scp) ) ;
   }

   if ( SC_ONLY_FROM(scp) != NULL )
   {
      addrlist_free( SC_ONLY_FROM(scp) ) ;
      pset_destroy( SC_ONLY_FROM(scp) ) ;
   }

   if ( SC_NO_ACCESS(scp) != NULL )
   {
      addrlist_free( SC_NO_ACCESS(scp) ) ;
      pset_destroy( SC_NO_ACCESS(scp) ) ;
   }

   if ( SC_ENV_VAR_DEFS(scp) != NULL )
      release_string_pset( SC_ENV_VAR_DEFS(scp) ) ;
   if ( SC_PASS_ENV_VARS(scp) != NULL )
      release_string_pset( SC_PASS_ENV_VARS(scp) ) ;
   if ( SC_ENV( scp )->env_type == CUSTOM_ENV && 
                                    SC_ENV( scp )->env_handle != ENV_NULL )
      env_destroy( SC_ENV( scp )->env_handle ) ;
   if (SC_DISABLED(scp) ) 
      release_string_pset( SC_DISABLED(scp) ) ;
   if (SC_ENABLED(scp) ) 
      release_string_pset( SC_ENABLED(scp) ) ;
   
   CLEAR( *scp ) ;
   FREE_SCONF( scp ) ;
}