/** * Serve a single file on stdin, and then exit. **/ static int dcc_inetd_server(void) { int ret, close_ret; struct dcc_sockaddr_storage ss; struct sockaddr *psa = (struct sockaddr *) &ss; socklen_t len = sizeof ss; dcc_log_daemon_started("inetd server"); if ((getpeername(STDIN_FILENO, psa, &len) == -1)) { /* This can fail with ENOTSOCK if e.g. sshd has started us on a pipe, * not on a socket. I think it's harmless. */ rs_log_notice("failed to get peer name: %s", strerror(errno)); psa = NULL; /* make sure we don't refer to uninitialized mem */ len = 0; } ret = dcc_service_job(STDIN_FILENO, STDOUT_FILENO, psa, len); close_ret = dcc_close(STDIN_FILENO); if (ret) return ret; else return close_ret; }
/** * Fork a child to repeatedly accept and handle incoming connections. * * To protect against leaks, we quit after 50 requests and let the parent * recreate us. **/ static int dcc_preforked_child(int listen_fd) { int ireq; const int child_lifetime = 50; for (ireq = 0; ireq < child_lifetime; ireq++) { int acc_fd; struct dcc_sockaddr_storage cli_addr; socklen_t cli_len; cli_len = sizeof cli_addr; do { acc_fd = accept(listen_fd, (struct sockaddr *) &cli_addr, &cli_len); } while (acc_fd == -1 && errno == EINTR); if (acc_fd == -1) { rs_log_error("accept failed: %s", strerror(errno)); dcc_exit(EXIT_CONNECT_FAILED); } dcc_service_job(acc_fd, acc_fd, (struct sockaddr *) &cli_addr, cli_len); dcc_close(acc_fd); } rs_log_info("worn out"); return 0; }
/** * Main loop for no-fork mode. * * Much slower and may leak. Should only be used when you want to run gdb on * distccd. **/ static void dcc_nofork_parent(int listen_fd) { while (1) { int acc_fd; struct dcc_sockaddr_storage cli_addr; socklen_t cli_len; rs_log_info("waiting to accept connection"); cli_len = sizeof cli_addr; acc_fd = accept(listen_fd, (struct sockaddr *) &cli_addr, &cli_len); if (acc_fd == -1 && errno == EINTR) { ; } else if (acc_fd == -1) { rs_log_error("accept failed: %s", strerror(errno)); #ifdef HAVE_GSSAPI if (dcc_auth_enabled) { dcc_gssapi_release_credentials(); if (opt_blacklist_enabled || opt_whitelist_enabled) { dcc_gssapi_free_list(); } } #endif dcc_exit(EXIT_CONNECT_FAILED); } else { dcc_service_job(acc_fd, acc_fd, (struct sockaddr *) &cli_addr, cli_len); dcc_close(acc_fd); } } }