Exemplo n.º 1
0
int fcgi_listen(const char *path, int backlog)
{
	char     *s;
	int       tcp = 0;
	char      host[MAXPATHLEN];
	short     port = 0;
	int       listen_socket;
	sa_t      sa;
	socklen_t sock_len;
#ifdef SO_REUSEADDR
# ifdef _WIN32
	BOOL reuse = 1;
# else
	int reuse = 1;
# endif
#endif

	if ((s = strchr(path, ':'))) {
		port = atoi(s+1);
		if (port != 0 && (s-path) < MAXPATHLEN) {
			strncpy(host, path, s-path);
			host[s-path] = '\0';
			tcp = 1;
		}
	} else if (is_port_number(path)) {
		port = atoi(path);
		if (port != 0) {
			host[0] = '\0';
			tcp = 1;
		}
	}

	/* Prepare socket address */
	if (tcp) {
		memset(&sa.sa_inet, 0, sizeof(sa.sa_inet));
		sa.sa_inet.sin_family = AF_INET;
		sa.sa_inet.sin_port = htons(port);
		sock_len = sizeof(sa.sa_inet);

		if (!*host || !strncmp(host, "*", sizeof("*")-1)) {
			sa.sa_inet.sin_addr.s_addr = htonl(INADDR_ANY);
		} else {
			sa.sa_inet.sin_addr.s_addr = inet_addr(host);
			if (sa.sa_inet.sin_addr.s_addr == INADDR_NONE) {
				struct hostent *hep;

				hep = gethostbyname(host);
				if (!hep || hep->h_addrtype != AF_INET || !hep->h_addr_list[0]) {
					fprintf(stderr, "Cannot resolve host name '%s'!\n", host);
					return -1;
				} else if (hep->h_addr_list[1]) {
					fprintf(stderr, "Host '%s' has multiple addresses. You must choose one explicitly!\n", host);
					return -1;
				}
				sa.sa_inet.sin_addr.s_addr = ((struct in_addr*)hep->h_addr_list[0])->s_addr;
			}
		}
	} else {
#ifdef _WIN32
		SECURITY_DESCRIPTOR  sd;
		SECURITY_ATTRIBUTES  sa;
		PACL                 acl;
		HANDLE namedPipe;

		memset(&sa, 0, sizeof(sa));
		sa.nLength = sizeof(sa);
		sa.bInheritHandle = FALSE;
		acl = prepare_named_pipe_acl(&sd, &sa);

		namedPipe = CreateNamedPipe(path,
			PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
			PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_READMODE_BYTE,
			PIPE_UNLIMITED_INSTANCES,
			8192, 8192, 0, &sa);
		if (namedPipe == INVALID_HANDLE_VALUE) {
			return -1;
		}		
		listen_socket = _open_osfhandle((long)namedPipe, 0);
		if (!is_initialized) {
			fcgi_init();
		}
		is_fastcgi = 1;
		return listen_socket;

#else
		int path_len = strlen(path);

		if (path_len >= sizeof(sa.sa_unix.sun_path)) {
			fprintf(stderr, "Listening socket's path name is too long.\n");
			return -1;
		}

		memset(&sa.sa_unix, 0, sizeof(sa.sa_unix));
		sa.sa_unix.sun_family = AF_UNIX;
		memcpy(sa.sa_unix.sun_path, path, path_len + 1);
		sock_len = (size_t)(((struct sockaddr_un *)0)->sun_path)	+ path_len;
#ifdef HAVE_SOCKADDR_UN_SUN_LEN
		sa.sa_unix.sun_len = sock_len;
#endif
		unlink(path);
#endif
	}

	/* Create, bind socket and start listen on it */
	if ((listen_socket = socket(sa.sa.sa_family, SOCK_STREAM, 0)) < 0 ||
#ifdef SO_REUSEADDR
	    setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) < 0 ||
#endif
	    bind(listen_socket, (struct sockaddr *) &sa, sock_len) < 0 ||
	    listen(listen_socket, backlog) < 0) {

		fprintf(stderr, "Cannot bind/listen socket - [%d] %s.\n",errno, strerror(errno));
		return -1;
	}

	if (!tcp) {
		chmod(path, 0777);
	} else {
			char *ip = getenv("FCGI_WEB_SERVER_ADDRS");
			char *cur, *end;
			int n;
			
			if (ip) {
				ip = strdup(ip);
				cur = ip;
				n = 0;
				while (*cur) {
					if (*cur == ',') n++;
					cur++;
				}
				allowed_clients = malloc(sizeof(in_addr_t) * (n+2));
				n = 0;
				cur = ip;
				while (cur) {
					end = strchr(cur, ',');
					if (end) {
						*end = 0;
						end++;
					}
					allowed_clients[n] = inet_addr(cur);
					if (allowed_clients[n] == INADDR_NONE) {
					fprintf(stderr, "Wrong IP address '%s' in FCGI_WEB_SERVER_ADDRS\n", cur);
					}
					n++;
					cur = end;
				}
				allowed_clients[n] = INADDR_NONE;
			free(ip);
		}
	}

	if (!is_initialized) {
		fcgi_init();
	}
	is_fastcgi = 1;

#ifdef _WIN32
	if (tcp) {
		listen_socket = _open_osfhandle((long)listen_socket, 0);
	}
#else
	fcgi_setup_signals();
#endif
	return listen_socket;
}
Exemplo n.º 2
0
int fcgi_listen(const char *path, int backlog)
{
#ifdef _WIN32
    /* TODO: Support for manual binding on TCP sockets (php -b <port>) */
    return -1;
#else
    char     *s;
    int       tcp = 0;
    char      host[MAXPATHLEN];
    short     port = 0;
    int       listen_socket;
    sa_t      sa;
    socklen_t sock_len;

    if ((s = strchr(path, ':'))) {
        port = atoi(s+1);
        if (port != 0 && (s-path) < MAXPATHLEN) {
            strncpy(host, path, s-path);
            host[s-path] = '\0';
            tcp = 1;
        }
    }

    /* Prepare socket address */
    if (tcp) {
        memset(&sa.sa_inet, 0, sizeof(sa.sa_inet));
        sa.sa_inet.sin_family = AF_INET;
        sa.sa_inet.sin_port = htons(port);
        sock_len = sizeof(sa.sa_inet);

        if (!*host || !strncmp(host, "*", sizeof("*")-1)) {
            sa.sa_inet.sin_addr.s_addr = htonl(INADDR_ANY);
        } else {
            sa.sa_inet.sin_addr.s_addr = inet_addr(host);
            if (sa.sa_inet.sin_addr.s_addr == INADDR_NONE) {
                struct hostent *hep;

                hep = gethostbyname(host);
                if (!hep || hep->h_addrtype != AF_INET || !hep->h_addr_list[0]) {
                    fprintf(stderr, "Cannot resolve host name '%s'!\n", host);
                    return -1;
                } else if (hep->h_addr_list[1]) {
                    fprintf(stderr, "Host '%s' has multiple addresses. You must choose one explicitly!\n", host);
                    return -1;
                }
                sa.sa_inet.sin_addr.s_addr = ((struct in_addr*)hep->h_addr_list[0])->s_addr;
            }
        }
    } else {
        int path_len = strlen(path);

        if (path_len >= sizeof(sa.sa_unix.sun_path)) {
            fprintf(stderr, "Listening socket's path name is too long.\n");
            return -1;
        }

        memset(&sa.sa_unix, 0, sizeof(sa.sa_unix));
        sa.sa_unix.sun_family = AF_UNIX;
        memcpy(sa.sa_unix.sun_path, path, path_len + 1);
        sock_len = (size_t)(((struct sockaddr_un *)0)->sun_path)	+ path_len;
#ifdef HAVE_SOCKADDR_UN_SUN_LEN
        sa.sa_unix.sun_len = sock_len;
#endif
        unlink(path);
    }

    /* Create, bind socket and start listen on it */
    if ((listen_socket = socket(sa.sa.sa_family, SOCK_STREAM, 0)) < 0 ||
            bind(listen_socket, (struct sockaddr *) &sa, sock_len) < 0 ||
            listen(listen_socket, backlog) < 0) {

        fprintf(stderr, "Cannot bind/listen socket - [%d] %s.\n",errno, strerror(errno));
        return -1;
    }

    if (!tcp) {
        chmod(path, 0777);
    }

    if (!is_initialized) {
        fcgi_init();
    }
    is_fastcgi = 1;
    return listen_socket;
#endif
}