예제 #1
0
ERROR_CODE run_service_s(char *program_name, struct hash_map_t *arguments) {
    /* allocates space for the error value that will be used
    to check for an error in the call */
    ERROR_CODE return_value;

    /* initializes the service creating the structures and starting
    the values for the configuration of it */
    return_value = init_service(program_name, arguments);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }

    /* run the service, blocking the call until the service is
    finished, the retrives the return value from it */
    return_value = run_service();
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }

    /* destroys the service eliminating any structures that have
    been created in the service life-time */
    return_value = destroy_service();
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }

    /* raises no error as the execution of the service went normally
    and no problems have been issued */
    RAISE_NO_ERROR;
}
예제 #2
0
static void daemonize(void)
{
  close_random_fds();

  // the double-fork-and-setsid trick establishes a
  // child process that runs in its own process group
  // with its own session and that won't get killed
  // off when your shell exits (for example).
  if (fork()) {
    // The parent of the first fork is the client
    // process that is being run by the user, and
    // we want to allow that to continue.
    return;
  }
  setsid();
  if (fork()) {
    // The parent of the second fork has served its
    // purpose, so we simply exit here, otherwise
    // we'll duplicate the effort of either the
    // client or the server depending on if we
    // return or not.
    _exit(0);
  }

  // we are the child, let's set things up
  run_service();
}
예제 #3
0
static void get_info_refs(char *arg)
{
	const char *service_name = get_parameter("service");
	struct strbuf buf = STRBUF_INIT;

	hdr_nocache();

	if (service_name) {
		const char *argv[] = {NULL /* service name */,
			"--stateless-rpc", "--advertise-refs",
			".", NULL};
		struct rpc_service *svc = select_service(service_name);

		strbuf_addf(&buf, "application/x-git-%s-advertisement",
			svc->name);
		hdr_str(content_type, buf.buf);
		end_headers();

		packet_write(1, "# service=git-%s\n", svc->name);
		packet_flush(1);

		argv[0] = svc->name;
		run_service(argv);

	} else {
		select_getanyfile();
		for_each_namespaced_ref(show_text_ref, &buf);
		send_strbuf("text/plain", &buf);
	}
	strbuf_release(&buf);
}
void ConcurrentMarkThread::run() {
    initialize_in_thread();
    wait_for_universe_init();

    run_service();

    terminate();
}
예제 #5
0
파일: daemon.c 프로젝트: 136357477/git
static int execute(void)
{
	char *line = packet_buffer;
	int pktlen, len, i;
	char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");
	struct hostinfo hi;

	hostinfo_init(&hi);

	if (addr)
		loginfo("Connection from %s:%s", addr, port);

	set_keep_alive(0);
	alarm(init_timeout ? init_timeout : timeout);
	pktlen = packet_read(0, NULL, NULL, packet_buffer, sizeof(packet_buffer), 0);
	alarm(0);

	len = strlen(line);
	if (pktlen != len)
		loginfo("Extended attributes (%d bytes) exist <%.*s>",
			(int) pktlen - len,
			(int) pktlen - len, line + len + 1);
	if (len && line[len-1] == '\n') {
		line[--len] = 0;
		pktlen--;
	}

	if (len != pktlen)
		parse_host_arg(&hi, line + len + 1, pktlen - len - 1);

	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
		struct daemon_service *s = &(daemon_service[i]);
		const char *arg;

		if (skip_prefix(line, "git-", &arg) &&
		    skip_prefix(arg, s->name, &arg) &&
		    *arg++ == ' ') {
			/*
			 * Note: The directory here is probably context sensitive,
			 * and might depend on the actual service being performed.
			 */
			int rc = run_service(arg, s, &hi);
			hostinfo_clear(&hi);
			return rc;
		}
	}

	hostinfo_clear(&hi);
	logerror("Protocol error: '%s'", line);
	return -1;
}
예제 #6
0
static PyObject *_wrap_start(PyObject *self, PyObject *args) {
    PyObject *resultobj;
    int arg1 ;
    char *arg2 ;
    int result;
    
    if(!PyArg_ParseTuple(args,(char *)"is:start",&arg1,&arg2)) goto fail;
    result = (int)run_service(arg1,arg2);
    
    resultobj = PyInt_FromLong((long)result);
    return resultobj;
    fail:
    return NULL;
}
예제 #7
0
int _tmain(int argc, _TCHAR* argv[])
{
	char host[20] = "127.1.1.1";
	unsigned short port = 10080;

	if( argc > 1 ) {
		::wcstombs( host, argv[1], sizeof(host) );
	}
	if( argc > 2 ) {
		try {
			port = lexical_cast<unsigned short>( wstring(argv[2]) );
		} catch( const bad_lexical_cast & ) {
			cout << "input port illegal. expected unsigned short value, but ";
			wcout << argv[2] << endl;
		}
	}


	try	{
		io_service::work work(ios_);
		run_service( ios_ );

		shared_ptr<fastnetwork::io_connector> connector( new udp::udp_connector( ios_ ) );
		connector->set_handler( session_created );

//		connector->connect( ip::udp::endpoint( ip::address_v4::from_string(host), port ) );
		// while using ip::address_v4::from_string(host), async_receive_from won't work
		// I don't know why.
		connector->connect( ip::udp::endpoint( ip::address_v4::from_string("127.0.0.1"), port ) );

		while ( true ) {
			if ( ! client )	{
				::Sleep(1000);
			} else {
				read_send( client );
				// break;
			}
		}
	} catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
	}

	ios_.stop();

	while( true ) {
		::Sleep( 10000 );
	}
	
	return 0;
}
예제 #8
0
void
tcpmux (int s, struct servtab *sep)
{
  char service[MAX_SERV_LEN + 1];
  int len;

  /* Get requested service name */
  if ((len = fd_getline (s, service, MAX_SERV_LEN)) < 0)
    {
      strwrite (s, "-Error reading service name\r\n");
      _exit (1);
    }
  service[len] = '\0';

  if (debug)
    fprintf (stderr, "tcpmux: someone wants %s\n", service);

  /*
   * Help is a required command, and lists available services,
   * one per line.
   */
  if (!strcasecmp (service, "help"))
    {
      for (sep = servtab; sep; sep = sep->se_next)
	{
	  if (!ISMUX (sep))
	    continue;
	  write (s, sep->se_service, strlen (sep->se_service));
	  strwrite (s, "\r\n");
	}
      _exit (1);
    }

  /* Try matching a service in inetd.conf with the request */
  for (sep = servtab; sep; sep = sep->se_next)
    {
      if (ISMUX (sep) && !strcasecmp (service, sep->se_service))
	{
	  if (ISMUXPLUS (sep))
	    {
	      strwrite (s, "+Go\r\n");
	    }
	  run_service (s, sep);
	  return;
	}
    }
  strwrite (s, "-Service not available\r\n");
  exit (1);
}
예제 #9
0
파일: daemon.c 프로젝트: 00027jang27/git
static int execute(void)
{
	char *line = packet_buffer;
	int pktlen, len, i;
	char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");

	if (addr)
		loginfo("Connection from %s:%s", addr, port);

	alarm(init_timeout ? init_timeout : timeout);
	pktlen = packet_read(0, NULL, NULL, packet_buffer, sizeof(packet_buffer), 0);
	alarm(0);

	len = strlen(line);
	if (pktlen != len)
		loginfo("Extended attributes (%d bytes) exist <%.*s>",
			(int) pktlen - len,
			(int) pktlen - len, line + len + 1);
	if (len && line[len-1] == '\n') {
		line[--len] = 0;
		pktlen--;
	}

	free(hostname);
	free(canon_hostname);
	free(ip_address);
	free(tcp_port);
	hostname = canon_hostname = ip_address = tcp_port = NULL;

	if (len != pktlen)
		parse_host_arg(line + len + 1, pktlen - len - 1);

	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
		struct daemon_service *s = &(daemon_service[i]);
		int namelen = strlen(s->name);
		if (!prefixcmp(line, "git-") &&
		    !strncmp(s->name, line + 4, namelen) &&
		    line[namelen + 4] == ' ') {
			/*
			 * Note: The directory here is probably context sensitive,
			 * and might depend on the actual service being performed.
			 */
			return run_service(line + namelen + 5, s);
		}
	}

	logerror("Protocol error: '%s'", line);
	return -1;
}
예제 #10
0
파일: main.c 프로젝트: Kingside/watchman
int main(int argc, char **argv)
{
  bool ran;
  json_t *cmd;

  parse_cmdline(&argc, &argv);

  if (foreground) {
    run_service();
    return 0;
  }

  cmd = build_command(argc, argv);
  preprocess_command(cmd, output_pdu);

  ran = try_command(cmd, 0);
  if (!ran && should_start(errno)) {
    if (no_spawn) {
      if (!no_local) {
        ran = try_client_mode_command(cmd, !no_pretty);
      }
    } else {
#ifdef USE_GIMLI
      spawn_via_gimli();
#elif defined(__APPLE__)
      spawn_via_launchd();
#else
      daemonize();
#endif
      ran = try_command(cmd, 10);
    }
  }

  json_decref(cmd);

  if (ran) {
    return 0;
  }

  if (!no_spawn) {
    w_log(W_LOG_ERR, "unable to talk to your watchman!\n");
  }
  return 1;
}
예제 #11
0
int service_chor(int argc,char *argv[]){
    chor_method_data list_methods[12];
    int list_methods_len = 0;
    char mailbox[50];
    strcpy(mailbox,argv[1]);
    XBT_INFO("created service %s",mailbox);
    int count_arg = 2;
    while(count_arg < argc){
	//add method
	if(strcmp(argv[count_arg],"method") == 0){
	    count_arg++;
	    make_chor_method(&list_methods[list_methods_len],argv[count_arg],argv[count_arg+1],argv[count_arg+2]);

	    XBT_INFO("method: %s",argv[count_arg]);
	    count_arg = count_arg+3;
	    //add instructions
	    int number_of_instruction = 0;
	    while(strcmp(argv[count_arg],"method") != 0){
		if(strcmp(argv[count_arg],"invoke") == 0){
		    make_instruction(&list_methods[list_methods_len].instructions[number_of_instruction],INVOKE,argv[count_arg+1],argv[count_arg+2],atof(argv[count_arg+3]));
		    count_arg = count_arg+4;
		
		}else if(strcmp(argv[count_arg],"exec") == 0){
			list_methods[list_methods_len].instructions[number_of_instruction].type = EXEC;
			count_arg++;
		}else if(strcmp(argv[count_arg],"wait") == 0){
			list_methods[list_methods_len].instructions[number_of_instruction].type = WAIT;
			count_arg++;
		    }else{	
			XBT_WARN("parser arguments error");
			return 1;}
		number_of_instruction++;
		if(count_arg >= argc){
		    break;
		}
	    }
	    list_methods[list_methods_len].instructions_len = number_of_instruction;
	    list_methods_len++;
	}
    }
    
    run_service(list_methods_len,list_methods,mailbox);
}
예제 #12
0
파일: main.c 프로젝트: nanomsg/topologist
int main(int argc, char **argv) {
    int rc;
    struct cfg_main cfg;

    rc = cfg_load(&cfg, argc, argv);
    if(rc == 0) {
        run_service(&cfg);
    }
    cfg_free(&cfg);

    if(rc > 0) {
        /*  rc > 0 means we had some configuration error  */
        return rc;
    } else {
        /*  rc == 0 means we have run successfully  */
        /*  rc < 0 means we've done some config action successfully  */
        return 0;
    }
}
예제 #13
0
파일: main.c 프로젝트: no2key/watchman
int main(int argc, char **argv)
{
  bool ran;
  json_t *cmd;

  parse_cmdline(&argc, &argv);

  if (foreground) {
    unlink(sock_name);
    run_service();
    return 0;
  }

  cmd = build_command(argc, argv);

  ran = try_command(cmd, 0);
  if (!ran && should_start(errno)) {
    if (no_spawn) {
      ran = try_client_mode_command(cmd, !no_pretty);
    } else {
      unlink(sock_name);
#ifdef USE_GIMLI
      spawn_via_gimli();
#else
      daemonize();
#endif
      ran = try_command(cmd, 10);
    }
  }

  json_decref(cmd);

  if (ran) {
    return 0;
  }

  if (!no_spawn) {
    w_log(W_LOG_ERR, "unable to talk to your watchman!\n");
  }
  return 1;
}
예제 #14
0
static void service_rpc(char *service_name)
{
	const char *argv[] = {NULL, "--stateless-rpc", ".", NULL};
	struct rpc_service *svc = select_service(service_name);
	struct strbuf buf = STRBUF_INIT;

	strbuf_reset(&buf);
	strbuf_addf(&buf, "application/x-git-%s-request", svc->name);
	check_content_type(buf.buf);

	hdr_nocache();

	strbuf_reset(&buf);
	strbuf_addf(&buf, "application/x-git-%s-result", svc->name);
	hdr_str(content_type, buf.buf);

	end_headers();

	argv[0] = svc->name;
	run_service(argv);
	strbuf_release(&buf);
}
예제 #15
0
파일: ImR_Activator.cpp 프로젝트: CCJY/ATCD
int
ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
  Activator_Options opts;

  int result = opts.init (argc, argv);
  if (result < 0)
    return 1;  // Error
  else if (result > 0)
    return 0;  // No error, but we should exit anyway.

  result = run_service_command (opts);
  if (result < 0)
    return 1;  // Error
  else if (result > 0)
    return 0;  // No error, but we should exit anyway.

  if (opts.service ())
    return run_service ();

  return run_standalone (opts);
}
예제 #16
0
int Service_Win32::main(int argc, char **argv)
{
	std::vector<std::string> args;
	for (int i=0; i<argc; i++)
		args.push_back(StringHelp::local8_to_text(argv[i]));

	if (argc == 2 && args[1] == "-debug")
	{
		return run_debug(args);
	}
	else if (argc == 2 && args[1] == "-install")
	{
		return run_install();
	}
	else if (argc == 2 && args[1] == "-uninstall")
	{
		return run_uninstall();
	}
	else
	{
		print_help();
		return run_service();
	}
}
예제 #17
0
int _tmain( int argc, TCHAR *argv[] ) {
    // LPCTSTR service_name = _T("hindsight");
    TCHAR *service_name = _T("hindsight");

    if ( argc == 1 ) return run_service( service_name );

    if ( lstrcmpi(argv[1], TEXT("install")) == 0 ) {
        return install_service( service_name );
    }

    if ( lstrcmpi(argv[1], TEXT("start")) == 0 ) {
        return start_service( service_name );
    }

    if ( lstrcmpi(argv[1], TEXT("stop")) == 0 ) {
        return stop_service( service_name );
    }

    if ( lstrcmpi(argv[1], TEXT("uninstall")) == 0 ) {
        return uninstall_service( service_name );
    }

    return -1;
}
예제 #18
0
static void run_service(struct omap_sdma_thc_service_binding_t *sv)
{
    omap_sdma_service_msg_t msg;
    bool loop = true;

    // this is the bitmap of messages we are interested in receiving
    struct omap_sdma_service_selector selector = {
        .mem_copy = 1, .mem_copy_2d = 1,
        .mem_fill = 1, .mem_fill_2d = 1,
    };

    while (loop) {
        // receive any message
        sv->recv_any(sv, &msg, selector);

        errval_t reterr = SYS_ERR_OK;

        // dispatch it
        switch(msg.msg) {
        case omap_sdma_mem_copy:
            reterr = mem_copy(
                msg.args.mem_copy.in.dst,
                msg.args.mem_copy.in.src);
            sv->send.mem_copy(sv, reterr);
            break;
        case omap_sdma_mem_fill:
            reterr = mem_fill(
                msg.args.mem_fill.in.dst,
                msg.args.mem_fill.in.color);
            sv->send.mem_fill(sv, reterr);
            break;
        case omap_sdma_mem_copy_2d:
            reterr = mem_copy_2d(
                msg.args.mem_copy_2d.in.dst,
                msg.args.mem_copy_2d.in.src,
                msg.args.mem_copy_2d.in.count,
                msg.args.mem_copy_2d.in.transparent,
                msg.args.mem_copy_2d.in.color);
            sv->send.mem_copy_2d(sv, reterr);
            break;
        case omap_sdma_mem_fill_2d:
            reterr = mem_fill_2d(
                msg.args.mem_fill_2d.in.dst,
                msg.args.mem_fill_2d.in.count,
                msg.args.mem_fill_2d.in.color);
            sv->send.mem_fill_2d(sv, reterr);
            break;
        default:
            debug_printf("unexpected message: %d\n", msg.msg);
            loop = false;
            break;
        }
    }

    free(sv);
}

void start_service(void)
{
    errval_t err;

    struct omap_sdma_thc_export_info e_info;
    struct omap_sdma_thc_service_binding_t *sv;
    struct omap_sdma_binding *b;
    iref_t iref;

    err = omap_sdma_thc_export(&e_info, "sdma",
                             get_default_waitset(),
                             IDC_EXPORT_FLAGS_DEFAULT,
                             &iref);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "thc export failed");
    }

    DO_FINISH({
        while(true) {
            err = omap_sdma_thc_accept(&e_info, &b);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "thc accept failed");
            }

            sv = malloc(sizeof(struct omap_sdma_thc_service_binding_t));
            assert(sv != NULL);

            err = omap_sdma_thc_init_service(sv, b, b);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "thc init failed");
            }

            ASYNC({run_service(sv);});
        }
    });
예제 #19
0
파일: daemon.c 프로젝트: Pistos/git
static int execute(struct sockaddr *addr)
{
	static char line[1000];
	int pktlen, len, i;

	if (addr) {
		char addrbuf[256] = "";
		int port = -1;

		if (addr->sa_family == AF_INET) {
			struct sockaddr_in *sin_addr = (void *) addr;
			inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
			port = ntohs(sin_addr->sin_port);
#ifndef NO_IPV6
		} else if (addr && addr->sa_family == AF_INET6) {
			struct sockaddr_in6 *sin6_addr = (void *) addr;

			char *buf = addrbuf;
			*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
			inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
			strcat(buf, "]");

			port = ntohs(sin6_addr->sin6_port);
#endif
		}
		loginfo("Connection from %s:%d", addrbuf, port);
	}

	alarm(init_timeout ? init_timeout : timeout);
	pktlen = packet_read_line(0, line, sizeof(line));
	alarm(0);

	len = strlen(line);
	if (pktlen != len)
		loginfo("Extended attributes (%d bytes) exist <%.*s>",
			(int) pktlen - len,
			(int) pktlen - len, line + len + 1);
	if (len && line[len-1] == '\n') {
		line[--len] = 0;
		pktlen--;
	}

	/*
	 * Initialize the path interpolation table for this connection.
	 */
	interp_clear_table(interp_table, ARRAY_SIZE(interp_table));
	interp_set_entry(interp_table, INTERP_SLOT_PERCENT, "%");

	if (len != pktlen) {
	    parse_extra_args(interp_table, line + len + 1, pktlen - len - 1);
	    fill_in_extra_table_entries(interp_table);
	}

	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
		struct daemon_service *s = &(daemon_service[i]);
		int namelen = strlen(s->name);
		if (!prefixcmp(line, "git-") &&
		    !strncmp(s->name, line + 4, namelen) &&
		    line[namelen + 4] == ' ') {
			/*
			 * Note: The directory here is probably context sensitive,
			 * and might depend on the actual service being performed.
			 */
			interp_set_entry(interp_table,
					 INTERP_SLOT_DIR, line + namelen + 5);
			return run_service(interp_table, s);
		}
	}

	logerror("Protocol error: '%s'", line);
	return -1;
}
예제 #20
0
int main(int argc, char **argv)
{
  bool ran;
  json_t *cmd;

  w_client_lock_init();
  parse_cmdline(&argc, &argv);

  if (foreground) {
    run_service();
    return 0;
  }

  w_set_thread_name("cli");
  cmd = build_command(argc, argv);
  preprocess_command(cmd, output_pdu);

  ran = try_command(cmd, 0);
  if (!ran && should_start(errno)) {
    if (no_spawn) {
      if (!no_local) {
        ran = try_client_mode_command(cmd, !no_pretty);
      }
    } else {
      spawn_watchman();
      ran = try_command(cmd, 10);
    }
  }

  json_decref(cmd);

  if (ran) {
    return 0;
  }

  if (!no_spawn) {
    w_log(W_LOG_ERR, "unable to talk to your watchman on %s! (%s)\n",
        sock_name, strerror(errno));
#ifdef __APPLE__
    if (getenv("TMUX")) {
      w_log(W_LOG_ERR, "\n"
"You may be hitting a tmux related session issue.\n"
"An immediate workaround is to run:\n"
"\n"
"    watchman version\n"
"\n"
"just once, from *outside* your tmux session, to allow the launchd\n"
"registration to be setup.  Once done, you can continue to access\n"
"watchman from inside your tmux sessions as usual.\n"
"\n"
"Longer term, you may wish to install this tool:\n"
"\n"
"    https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard\n"
"\n"
"and configure tmux to use `reattach-to-user-namespace`\n"
"when it launches your shell.\n");
    }
#endif
  }
  return 1;
}
예제 #21
0
static int execute(struct sockaddr *addr)
{
	static char line[1000];
	int pktlen, len, i;

	if (addr) {
		char addrbuf[256] = "";
		int port = -1;

		if (addr->sa_family == AF_INET) {
			struct sockaddr_in *sin_addr = (void *) addr;
			inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
			port = ntohs(sin_addr->sin_port);
#ifndef NO_IPV6
		} else if (addr && addr->sa_family == AF_INET6) {
			struct sockaddr_in6 *sin6_addr = (void *) addr;

			char *buf = addrbuf;
			*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
			inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
			strcat(buf, "]");

			port = ntohs(sin6_addr->sin6_port);
#endif
		}
		loginfo("Connection from %s:%d", addrbuf, port);
		setenv("REMOTE_ADDR", addrbuf, 1);
	}
	else {
		unsetenv("REMOTE_ADDR");
	}

	alarm(init_timeout ? init_timeout : timeout);
	pktlen = packet_read_line(0, line, sizeof(line));
	alarm(0);

	len = strlen(line);
	if (pktlen != len)
		loginfo("Extended attributes (%d bytes) exist <%.*s>",
			(int) pktlen - len,
			(int) pktlen - len, line + len + 1);
	if (len && line[len-1] == '\n') {
		line[--len] = 0;
		pktlen--;
	}

	free(hostname);
	free(canon_hostname);
	free(ip_address);
	free(tcp_port);
	hostname = canon_hostname = ip_address = tcp_port = NULL;

	if (len != pktlen)
		parse_host_arg(line + len + 1, pktlen - len - 1);

	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
		struct daemon_service *s = &(daemon_service[i]);
		int namelen = strlen(s->name);
		if (!prefixcmp(line, "git-") &&
		    !strncmp(s->name, line + 4, namelen) &&
		    line[namelen + 4] == ' ') {
			/*
			 * Note: The directory here is probably context sensitive,
			 * and might depend on the actual service being performed.
			 */
			return run_service(line + namelen + 5, s);
		}
	}

	logerror("Protocol error: '%s'", line);
	return -1;
}
예제 #22
0
int
main (int argc, char *argv[], char *envp[])
{
  int index;
  struct servtab *sep;
  int dofork;
  pid_t pid;

  set_program_name (argv[0]);

  Argv = argv;
  if (envp == 0 || *envp == 0)
    envp = argv;
  while (*envp)
    envp++;
  LastArg = envp[-1] + strlen (envp[-1]);

  /* Parse command line */
  iu_argp_init ("inetd", program_authors);
  argp_parse (&argp, argc, argv, 0, &index, NULL);

  if (resolve_option)
    env_option = true;

  if (index < argc)
    {
      int i;
      config_files = calloc (argc - index + 1, sizeof (*config_files));
      for (i = 0; index < argc; index++, i++)
	{
	  config_files[i] = strdup (argv[index]);
	}
    }
  else
    {
      config_files = calloc (3, sizeof (*config_files));
      config_files[0] = newstr (PATH_INETDCONF);
      config_files[1] = newstr (PATH_INETDDIR);
    }

  if (!debug)
    {
      daemon (0, 0);
    }

  openlog ("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);

  {
    FILE *fp = fopen (PATH_INETDPID, "w");
    if (fp != NULL)
      {
	fprintf (fp, "%d\n", getpid ());
	fclose (fp);
      }
    else
      syslog (LOG_CRIT, "can't open %s: %s\n", PATH_INETDPID,
	      strerror (errno));
  }

  signal_set_handler (SIGALRM, retry);
  config (0);
  signal_set_handler (SIGHUP, config);
  signal_set_handler (SIGCHLD, reapchild);
  signal_set_handler (SIGPIPE, SIG_IGN);

  {
    /* space for daemons to overwrite environment for ps */
#define DUMMYSIZE	100
    char dummy[DUMMYSIZE];

    memset (dummy, 'x', DUMMYSIZE - 1);
    dummy[DUMMYSIZE - 1] = '\0';
    setenv ("inetd_dummy", dummy, 1);
  }

  for (;;)
    {
      int n, ctrl;
      fd_set readable;

      if (nsock == 0)
	{
	  SIGSTATUS stat;
	  sigstatus_empty (stat);

	  signal_block (NULL);
	  while (nsock == 0)
	    inetd_pause (stat);
	  signal_unblock (NULL);
	}
      readable = allsock;
      if ((n = select (maxsock + 1, &readable, NULL, NULL, NULL)) <= 0)
	{
	  if (n < 0 && errno != EINTR)
	    syslog (LOG_WARNING, "select: %m");
	  sleep (1);
	  continue;
	}
      for (sep = servtab; n && sep; sep = sep->se_next)
	if (sep->se_fd != -1 && FD_ISSET (sep->se_fd, &readable))
	  {
	    n--;
	    if (debug)
	      fprintf (stderr, "someone wants %s\n", sep->se_service);
	    if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
	      {
		struct sockaddr_in sa_client;
		socklen_t len = sizeof (sa_client);

		ctrl = accept (sep->se_fd, (struct sockaddr *) &sa_client,
			       &len);
		if (debug)
		  fprintf (stderr, "accept, ctrl %d\n", ctrl);
		if (ctrl < 0)
		  {
		    if (errno != EINTR)
		      syslog (LOG_WARNING, "accept (for %s): %m",
			      sep->se_service);
		    continue;
		  }
		if (env_option)
		  prepenv (ctrl, sa_client);
	      }
	    else
	      ctrl = sep->se_fd;

	    signal_block (NULL);
	    pid = 0;
	    dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
	    if (dofork)
	      {
		if (sep->se_count++ == 0)
		  gettimeofday (&sep->se_time, NULL);
		else if ((sep->se_max && sep->se_count > sep->se_max)
			 || sep->se_count >= toomany)
		  {
		    struct timeval now;

		    gettimeofday (&now, NULL);
		    if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL)
		      {
			sep->se_time = now;
			sep->se_count = 1;
		      }
		    else
		      {
			syslog (LOG_ERR,
				"%s/%s server failing (looping), service terminated",
				sep->se_service, sep->se_proto);
			close_sep (sep);
			if (! sep->se_wait && sep->se_socktype == SOCK_STREAM)
			  close (ctrl);
			signal_unblock (NULL);
			if (!timingout)
			  {
			    timingout = 1;
			    alarm (RETRYTIME);
			  }
			continue;
		      }
		  }
		pid = fork ();
	      }
	    if (pid < 0)
	      {
		syslog (LOG_ERR, "fork: %m");
		if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
		  close (ctrl);
		signal_unblock (NULL);
		sleep (1);
		continue;
	      }
	    if (pid && sep->se_wait)
	      {
		sep->se_wait = pid;
		if (sep->se_fd >= 0)
		  {
		    FD_CLR (sep->se_fd, &allsock);
		    nsock--;
		  }
	      }
	    signal_unblock (NULL);
	    if (pid == 0)
	      {
		if (debug && dofork)
		  setsid ();
		if (dofork)
		  {
		    int sock;
		    if (debug)
		      fprintf (stderr, "+ Closing from %d\n", maxsock);
		    for (sock = maxsock; sock > 2; sock--)
		      if (sock != ctrl)
			close (sock);
		  }
		run_service (ctrl, sep);
	      }
	    if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
	      close (ctrl);
	  }
    }
}
예제 #23
0
파일: skeleton.hpp 프로젝트: 1901/libmoost
 /**
  * \brief Run the service
  *
  * Override this if you want to do anything else than just running the service
  * depending on the commandline options. To actually run the service, call
  * run_service() from within your override.
  */
 virtual void run()
 {
    run_service();
 }