diff options
Diffstat (limited to 'src/spawn-fcgi.c')
-rw-r--r-- | src/spawn-fcgi.c | 178 |
1 files changed, 89 insertions, 89 deletions
diff --git a/src/spawn-fcgi.c b/src/spawn-fcgi.c index 33de85c..c40d8f9 100644 --- a/src/spawn-fcgi.c +++ b/src/spawn-fcgi.c @@ -45,28 +45,28 @@ int fcgi_spawn_connection(char *appPath, char *addr, unsigned short port, const int fcgi_fd; int socket_type, status; struct timeval tv = { 0, 100 * 1000 }; - + struct sockaddr_un fcgi_addr_un; struct sockaddr_in fcgi_addr_in; struct sockaddr *fcgi_addr; - + socklen_t servlen; - + if (child_count < 2) { child_count = 5; } - + if (child_count > 256) { child_count = 256; } - - + + if (unixsocket) { memset(&fcgi_addr, 0, sizeof(fcgi_addr)); - + fcgi_addr_un.sun_family = AF_UNIX; strcpy(fcgi_addr_un.sun_path, unixsocket); - + #ifdef SUN_LEN servlen = SUN_LEN(&fcgi_addr_un); #else @@ -84,50 +84,50 @@ int fcgi_spawn_connection(char *appPath, char *addr, unsigned short port, const } fcgi_addr_in.sin_port = htons(port); servlen = sizeof(fcgi_addr_in); - + socket_type = AF_INET; fcgi_addr = (struct sockaddr *) &fcgi_addr_in; } - + if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { - fprintf(stderr, "%s.%d\n", + fprintf(stderr, "%s.%d\n", __FILE__, __LINE__); return -1; } - + if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) { /* server is not up, spawn in */ pid_t child; int val; - + if (unixsocket) unlink(unixsocket); - + close(fcgi_fd); - + /* reopen socket */ if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { - fprintf(stderr, "%s.%d\n", + fprintf(stderr, "%s.%d\n", __FILE__, __LINE__); return -1; } val = 1; if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { - fprintf(stderr, "%s.%d\n", + fprintf(stderr, "%s.%d\n", __FILE__, __LINE__); return -1; } /* create socket */ if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) { - fprintf(stderr, "%s.%d: bind failed: %s\n", + fprintf(stderr, "%s.%d: bind failed: %s\n", __FILE__, __LINE__, strerror(errno)); return -1; } - + if (-1 == listen(fcgi_fd, 1024)) { - fprintf(stderr, "%s.%d: fd = -1\n", + fprintf(stderr, "%s.%d: fd = -1\n", __FILE__, __LINE__); return -1; } @@ -137,42 +137,42 @@ int fcgi_spawn_connection(char *appPath, char *addr, unsigned short port, const } else { child = 0; } - + switch (child) { case 0: { char cgi_childs[64]; char *b; - + int i = 0; - + /* is save as we limit to 256 childs */ sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count); - + if(fcgi_fd != FCGI_LISTENSOCK_FILENO) { close(FCGI_LISTENSOCK_FILENO); dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO); close(fcgi_fd); } - + /* we don't need the client socket */ for (i = 3; i < 256; i++) { close(i); } - + /* create environment */ - + putenv(cgi_childs); - + /* fork and replace shell */ b = malloc(strlen("exec ") + strlen(appPath) + 1); strcpy(b, "exec "); strcat(b, appPath); - + /* exec the cgi */ execl("/bin/sh", "sh", "-c", b, NULL); - + exit(errno); - + break; } case -1: @@ -180,47 +180,47 @@ int fcgi_spawn_connection(char *appPath, char *addr, unsigned short port, const break; default: /* father */ - + /* wait */ select(0, NULL, NULL, NULL, &tv); - + switch (waitpid(child, &status, WNOHANG)) { case 0: - fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n", + fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n", __FILE__, __LINE__, child); - + /* write pid file */ if (pid_fd != -1) { /* assume a 32bit pid_t */ char pidbuf[12]; - + snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child); - + write(pid_fd, pidbuf, strlen(pidbuf)); close(pid_fd); pid_fd = -1; } - + break; case -1: break; default: if (WIFEXITED(status)) { - fprintf(stderr, "%s.%d: child exited with: %d, %s\n", + fprintf(stderr, "%s.%d: child exited with: %d, %s\n", __FILE__, __LINE__, WEXITSTATUS(status), strerror(WEXITSTATUS(status))); } else if (WIFSIGNALED(status)) { - fprintf(stderr, "%s.%d: child signaled: %d\n", + fprintf(stderr, "%s.%d: child signaled: %d\n", __FILE__, __LINE__, WTERMSIG(status)); } else { - fprintf(stderr, "%s.%d: child died somehow: %d\n", + fprintf(stderr, "%s.%d: child died somehow: %d\n", __FILE__, __LINE__, status); } } - + break; } } else { @@ -228,16 +228,16 @@ int fcgi_spawn_connection(char *appPath, char *addr, unsigned short port, const __FILE__, __LINE__); return -1; } - + close(fcgi_fd); - + return 0; } void show_version () { char *b = "spawn-fcgi" "-" PACKAGE_VERSION \ -" - spawns fastcgi processes\n" +" - spawns fastcgi processes\n" ; write(1, b, strlen(b)); } @@ -265,7 +265,7 @@ void show_help () { int main(int argc, char **argv) { - char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, + char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, *groupname = NULL, *unixsocket = NULL, *pid_file = NULL, *addr = NULL; unsigned short port = 0; @@ -273,9 +273,9 @@ int main(int argc, char **argv) { int i_am_root, o; int pid_fd = -1; int nofork = 0; - + i_am_root = (getuid() == 0); - + while(-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:s:P:"))) { switch(o) { case 'f': fcgi_app = optarg; break; @@ -290,137 +290,137 @@ int main(int argc, char **argv) { case 'P': pid_file = optarg; /* PID file */ break; case 'v': show_version(); return 0; case 'h': show_help(); return 0; - default: + default: show_help(); return -1; } } - + if (fcgi_app == NULL || (port == 0 && unixsocket == NULL)) { show_help(); return -1; } - + if (unixsocket && port) { - fprintf(stderr, "%s.%d: %s\n", + fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "either a unix domain socket or a tcp-port, but not both\n"); - + return -1; } - + if (unixsocket && strlen(unixsocket) > UNIX_PATH_MAX - 1) { - fprintf(stderr, "%s.%d: %s\n", + fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "path of the unix socket is too long\n"); - + return -1; } /* UID handling */ if (!i_am_root && (geteuid() == 0 || getegid() == 0)) { /* we are setuid-root */ - - fprintf(stderr, "%s.%d: %s\n", + + fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "Are you nuts ? Don't apply a SUID bit to this binary\n"); - + return -1; } - - if (pid_file && + + if (pid_file && (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) { struct stat st; if (errno != EEXIST) { - fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", + fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", __FILE__, __LINE__, pid_file, strerror(errno)); - + return -1; } - + /* ok, file exists */ - + if (0 != stat(pid_file, &st)) { - fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n", + fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n", __FILE__, __LINE__, pid_file, strerror(errno)); - + return -1; } - + /* is it a regular file ? */ - + if (!S_ISREG(st.st_mode)) { - fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n", + fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n", __FILE__, __LINE__, pid_file); - + return -1; } - + if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { - fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", + fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", __FILE__, __LINE__, pid_file, strerror(errno)); - + return -1; } } - + if (i_am_root) { struct group *grp = NULL; struct passwd *pwd = NULL; - + /* set user and group */ - + if (username) { if (NULL == (pwd = getpwnam(username))) { - fprintf(stderr, "%s.%d: %s, %s\n", + fprintf(stderr, "%s.%d: %s, %s\n", __FILE__, __LINE__, "can't find username", username); return -1; } - + if (pwd->pw_uid == 0) { - fprintf(stderr, "%s.%d: %s\n", + fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "I will not set uid to 0\n"); return -1; } } - + if (groupname) { if (NULL == (grp = getgrnam(groupname))) { - fprintf(stderr, "%s.%d: %s %s\n", + fprintf(stderr, "%s.%d: %s %s\n", __FILE__, __LINE__, - "can't find groupname", + "can't find groupname", groupname); return -1; } if (grp->gr_gid == 0) { - fprintf(stderr, "%s.%d: %s\n", + fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "I will not set gid to 0\n"); return -1; } } - + if (changeroot) { if (-1 == chroot(changeroot)) { - fprintf(stderr, "%s.%d: %s %s\n", + fprintf(stderr, "%s.%d: %s %s\n", __FILE__, __LINE__, "chroot failed: ", strerror(errno)); return -1; } if (-1 == chdir("/")) { - fprintf(stderr, "%s.%d: %s %s\n", + fprintf(stderr, "%s.%d: %s %s\n", __FILE__, __LINE__, "chdir failed: ", strerror(errno)); return -1; } } - + /* drop root privs */ if (groupname) { setgid(grp->gr_gid); @@ -432,7 +432,7 @@ int main(int argc, char **argv) { setuid(pwd->pw_uid); } } - + return fcgi_spawn_connection(fcgi_app, addr, port, unixsocket, child_count, pid_fd, nofork); } #else |