Beispiel #1
0
int main(int argc, char** argv)
{
	int sock, len;
	socklen_t from_len;
	struct sockaddr_un from, to;
	char name[256];
	static char buffer[BUF_SIZE];
	char *chroot_dir;

	if (argc != 2) {
		printf("Usage: %s <path_to_socket>\n", argv[0]);
		return 1;
	}

	sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
	if (sock == -1) {
		fprintf(stderr, "Error while opening socket: %s\n", strerror(errno));
		return -1;
	}
	
	memset(&from, 0, sizeof(from));
	from.sun_family = PF_LOCAL;

	chroot_dir = getenv("CHROOT_DIR");
	if (chroot_dir == NULL)
		chroot_dir = "";
	sprintf(name, "%s/tmp/Kamailio.%d.XXXXXX", chroot_dir, getpid());
	umask(0); /* set mode to 0666 for when Kamailio is running as non-root user and kamctl is running as root */

	if (mkstemp(name) == -1) {
		fprintf(stderr, "Error in mkstemp with name=%s: %s\n", name, strerror(errno));
		return -2;
	}
	if (unlink(name) == -1) {
		fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno));
		return -2;
	}
	strncpy(from.sun_path, name, strlen(name));

	if (bind(sock, (struct sockaddr*)&from, SUN_LEN(&from)) == -1) {
		fprintf(stderr, "Error in bind: %s\n", strerror(errno));
		goto err;
	}

	memset(&to, 0, sizeof(to));
	to.sun_family = PF_LOCAL;
	strncpy(to.sun_path, argv[1], sizeof(to.sun_path) - 1);
	
	len = fread(buffer, 1, BUF_SIZE, stdin);

	if (len) {
		if (sendto(sock, buffer, len, 0, (struct sockaddr*)&to, SUN_LEN(&to)) == -1) {
			fprintf(stderr, "Error in sendto: %s\n", strerror(errno));
		        goto err;
		}
		from_len = sizeof(from);
		len = recvfrom(sock, buffer, BUF_SIZE, 0, (struct sockaddr*)&from, &from_len);
		if (len == -1) {
			fprintf(stderr, "Error in recvfrom: %s\n", strerror(errno));
			goto err;
		}

		fprintf(stdout, "%.*s", len, buffer);
	} else {
		fprintf(stderr, "Nothing to send\n");
		goto err;
	}

	close(sock);
	if (unlink(name) == -1)
		fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno));
	return 0;

 err:
	close(sock);
	if (unlink(name) == -1)
		fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno));
	return -1;
}
Beispiel #2
0
/* opens data sink */
int ido_sink_open(char *name, int fd, int type, int port, int flags, int *nfd) {
	struct sockaddr_un server_address_u;
	struct sockaddr_in server_address_i;
	struct hostent *hp = NULL;
	mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
	int newfd = 0;
#ifdef HAVE_SSL
	int rc = 0;
#endif

	/* use file */
	if (type == IDO_SINK_FILE) {
		if ((newfd = open(name, flags, mode)) == -1)
			return IDO_ERROR;
	}

	/* use existing file descriptor */
	else if (type == IDO_SINK_FD) {
		if (fd < 0)
			return IDO_ERROR;
		else
			newfd = fd;
	}

	/* we are sending output to a unix domain socket */
	else if (type == IDO_SINK_UNIXSOCKET) {

		if (name == NULL)
			return IDO_ERROR;

		/* create a socket */
		if (!(newfd = socket(PF_UNIX, SOCK_STREAM, 0)))
			return IDO_ERROR;

		/* copy the socket address/path */
		strncpy(server_address_u.sun_path, name, sizeof(server_address_u.sun_path));
		server_address_u.sun_family = AF_UNIX;

		/* connect to the socket */
		if ((connect(newfd, (struct sockaddr *)&server_address_u, SUN_LEN(&server_address_u)))) {
			close(newfd);
			return IDO_ERROR;
		}
	}

	/* we are sending output to a TCP socket */
	else if (type == IDO_SINK_TCPSOCKET) {

		if (name == NULL)
			return IDO_ERROR;

#ifdef HAVE_SSL
		if (use_ssl == IDO_TRUE) {
			SSL_library_init();
			SSLeay_add_ssl_algorithms();
			meth = SSLv23_client_method();
			SSL_load_error_strings();

			if ((ctx = SSL_CTX_new(meth)) == NULL) {
				printf("IDOUtils: Error - could not create SSL context.\n");
				return IDO_ERROR;
			}
			/* ADDED 01/19/2004 */
			/* use only TLSv1 protocol */
			SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
		}
#endif

		/* clear the address */
		bzero((char *)&server_address_i, sizeof(server_address_i));

		/* try to bypass using a DNS lookup if this is just an IP address */
		if (!ido_inet_aton(name, &server_address_i.sin_addr)) {

			/* else do a DNS lookup */
			if ((hp = gethostbyname((const char *)name)) == NULL)
				return IDO_ERROR;

			memcpy(&server_address_i.sin_addr, hp->h_addr, hp->h_length);
		}

		/* create a socket */
		if (!(newfd = socket(PF_INET, SOCK_STREAM, 0)))
			return IDO_ERROR;

		/* copy the host/ip address and port */
		server_address_i.sin_family = AF_INET;
		server_address_i.sin_port = htons(port);

		/* connect to the socket */
		if ((connect(newfd, (struct sockaddr *)&server_address_i, sizeof(server_address_i)))) {
			close(newfd);
			return IDO_ERROR;
		}

#ifdef HAVE_SSL
		if (use_ssl == IDO_TRUE) {
			if ((ssl = SSL_new(ctx)) != NULL) {
				SSL_CTX_set_cipher_list(ctx, "ADH");
				SSL_set_fd(ssl, newfd);
				if ((rc = SSL_connect(ssl)) != 1) {
					printf("Error - Could not complete SSL handshake.\n");
					SSL_CTX_free(ctx);
					close(newfd);
					return IDO_ERROR;
				}
			} else {
				printf("IDOUtils: Error - Could not create SSL connection structure.\n");
				return IDO_ERROR;
			}
		}
#endif
	}

	/* unknown sink type */
	else
		return IDO_ERROR;

	/* save the new file descriptor */
	*nfd = newfd;

	return IDO_OK;
}
Beispiel #3
0
struct imsgbuf *
client_init(char *path, int cmdflags, int flags)
{
	struct sockaddr_un	sa;
	size_t			size;
	int			fd, mode;
#ifdef HAVE_SETPROCTITLE
	char		        rpathbuf[MAXPATHLEN];
#endif

#ifdef HAVE_SETPROCTITLE
	if (realpath(path, rpathbuf) == NULL)
		strlcpy(rpathbuf, path, sizeof rpathbuf);
	setproctitle("client (%s)", rpathbuf);
#endif

	memset(&sa, 0, sizeof sa);
	sa.sun_family = AF_UNIX;
	size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
	if (size >= sizeof sa.sun_path) {
		errno = ENAMETOOLONG;
		goto not_found;
	}

	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		fatal("socket failed");

	if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
		if (!(cmdflags & CMD_STARTSERVER))
			goto not_found;
		switch (errno) {
		case ECONNREFUSED:
			if (unlink(path) != 0)
				goto not_found;
			/* FALLTHROUGH */
		case ENOENT:
			if ((fd = server_start(path)) == -1)
				goto start_failed;
			goto server_started;
		}
		goto not_found;
	}

server_started:
	if ((mode = fcntl(fd, F_GETFL)) == -1)
		fatal("fcntl failed");
	if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
		fatal("fcntl failed");
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
		fatal("fcntl failed");
	imsg_init(&client_ibuf, fd);

	if (cmdflags & CMD_SENDENVIRON)
		client_send_environ();
	if (isatty(STDIN_FILENO))
		client_send_identify(flags);

	return (&client_ibuf);

start_failed:
	log_warnx("server failed to start");
	return (NULL);

not_found:
	log_warn("server not found");
	return (NULL);
}
Beispiel #4
0
int main(int argc, char *argv[]) {
    int sd = -1, rc, bytesReceived;
    char buffer[BUFFER_LENGTH];
    struct sockaddr_un serveraddr;

    /***********************************************************************/
    /* A do/while(FALSE) loop is used to make error cleanup easier.  The   */
    /* close() of the socket descriptor is only done once at the very end  */
    /* of the program.                                                     */
    /***********************************************************************/
    do {
        /***********************************************************************/
        /* The socket() function returns a socket descriptor, which represents */
        /* an endpoint.  The statement also identifies that the UNIX           */
        /* address family with the stream transport (SOCK_STREAM) will be      */
        /* used for this socket.                                               */
        /***********************************************************************/
        sd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sd < 0) {
            //perror("socket() failed");
            break;
        }

        /********************************************************************/
        /* If an argument was passed in, use this as the server, otherwise  */
        /* use the #define that is located at the top of this program.      */
        /********************************************************************/
        memset(&serveraddr, 0, sizeof (serveraddr));
        serveraddr.sun_family = AF_UNIX;
        strcpy(serveraddr.sun_path, SERVER_PATH);

        /********************************************************************/
        /* Use the connect() function to establish a connection to the      */
        /* server.                                                          */
        /********************************************************************/
        rc = connect(sd, (struct sockaddr *) &serveraddr, SUN_LEN(&serveraddr));
        if (rc < 0) {
            //perror("connect() failed");
            break;
        }

        /********************************************************************/
        /* In this example we know that the server is going to respond with */
        /* the same 250 bytes that we just sent.  Since we know that 250    */
        /* bytes are going to be sent back to us, we can use the            */
        /* SO_RCVLOWAT socket option and then issue a single recv() and     */
        /* retrieve all of the data.                                        */
        /*                                                                  */
        /* The use of SO_RCVLOWAT is already illustrated in the server      */
        /* side of this example, so we will do something different here.    */
        /* The 250 bytes of the data may arrive in separate packets,        */
        /* therefore we will issue recv() over and over again until all     */
        /* 250 bytes have arrived.                                          */
        /********************************************************************/
        while (1) {
            bytesReceived = 0;
            memset(&buffer, 0, BUFFER_LENGTH);

            rc = recv(sd, & buffer[bytesReceived], BUFFER_LENGTH - bytesReceived - 1, 0);

            if (rc <= 0) {
                //perror("recv() failed");
                break;
            }

            /*****************************************************************/
            /* Increment the number of bytes that have been received so far  */
            /*****************************************************************/
            bytesReceived += rc;
            printf("%s", buffer);
        }
    } while (FALSE);

    if (sd != -1) close(sd);
    return 0;

}
Beispiel #5
0
int ncat_connect(void)
{
    nsock_pool mypool;
    int rc;

    /* Unless explicitely asked not to do so, ncat uses the
     * fallback nsock engine to maximize compatibility between
     * operating systems and the different use cases.
     */
    if (!o.nsock_engine)
        nsock_set_default_engine("select");

    /* Create an nsock pool */
    if ((mypool = nsp_new(NULL)) == NULL)
        bye("Failed to create nsock_pool.");

    if (o.debug > 1)
        /* A trace level of 1 still gives you an awful lot. */
        nsp_settrace(mypool, stderr, 1, nsock_gettimeofday());

    /* Allow connections to broadcast addresses. */
    nsp_setbroadcast(mypool, 1);

#ifdef HAVE_OPENSSL
    set_ssl_ctx_options((SSL_CTX *) nsp_ssl_init(mypool));
#endif

    if (httpconnect.storage.ss_family == AF_UNSPEC
             && socksconnect.storage.ss_family == AF_UNSPEC) {
        /* A non-proxy connection. Create an iod for a new socket. */
        cs.sock_nsi = nsi_new(mypool, NULL);
        if (cs.sock_nsi == NULL)
            bye("Failed to create nsock_iod.");

        if (nsi_set_hostname(cs.sock_nsi, o.target) == -1)
            bye("Failed to set hostname on iod.");

#if HAVE_SYS_UN_H
        /* For DGRAM UNIX socket we have to use source socket */
        if (o.af == AF_UNIX && o.udp)
        {
            if (srcaddr.storage.ss_family != AF_UNIX) {
                char *tmp_name = NULL;
                /* If no source socket was specified, we have to create temporary one. */
                if ((tmp_name = tempnam(NULL, "ncat.")) == NULL)
                    bye("Failed to create name for temporary DGRAM source Unix domain socket (tempnam).");

                srcaddr.un.sun_family = AF_UNIX;
                strncpy(srcaddr.un.sun_path, tmp_name, sizeof(srcaddr.un.sun_path));
                free (tmp_name);
            }
            nsi_set_localaddr(cs.sock_nsi, &srcaddr.storage, SUN_LEN((struct sockaddr_un *)&srcaddr.storage));

            if (o.verbose)
                loguser("[%s] used as source DGRAM Unix domain socket.\n", srcaddr.un.sun_path);
        }
        else
#endif
        if (srcaddr.storage.ss_family != AF_UNSPEC)
            nsi_set_localaddr(cs.sock_nsi, &srcaddr.storage, sizeof(srcaddr.storage));

        if (o.numsrcrtes) {
            unsigned char *ipopts = NULL;
            size_t ipoptslen = 0;

            if (o.af != AF_INET)
                bye("Sorry, -g can only currently be used with IPv4.");
            ipopts = buildsrcrte(targetss.in.sin_addr, o.srcrtes, o.numsrcrtes, o.srcrteptr, &ipoptslen);

            nsi_set_ipoptions(cs.sock_nsi, ipopts, ipoptslen);
            free(ipopts); /* Nsock has its own copy */
        }

#if HAVE_SYS_UN_H
        if (o.af == AF_UNIX) {
            if (o.udp) {
                nsock_connect_unixsock_datagram(mypool, cs.sock_nsi, connect_handler, NULL,
                                                &targetss.sockaddr,
                                                SUN_LEN((struct sockaddr_un *)&targetss.sockaddr));
            } else {
                nsock_connect_unixsock_stream(mypool, cs.sock_nsi, connect_handler, o.conntimeout,
                                              NULL, &targetss.sockaddr,
                                              SUN_LEN((struct sockaddr_un *)&targetss.sockaddr));
            }
        } else
#endif
        if (o.udp) {
            nsock_connect_udp(mypool, cs.sock_nsi, connect_handler,
                              NULL, &targetss.sockaddr, targetsslen,
                              inet_port(&targetss));
        }
#ifdef HAVE_OPENSSL
        else if (o.sctp && o.ssl) {
            nsock_connect_ssl(mypool, cs.sock_nsi, connect_handler,
                              o.conntimeout, NULL,
                              &targetss.sockaddr, targetsslen,
                              IPPROTO_SCTP, inet_port(&targetss),
                              NULL);
        }
#endif
        else if (o.sctp) {
            nsock_connect_sctp(mypool, cs.sock_nsi, connect_handler,
                              o.conntimeout, NULL,
                              &targetss.sockaddr, targetsslen,
                              inet_port(&targetss));
        }
#ifdef HAVE_OPENSSL
        else if (o.ssl) {
            nsock_connect_ssl(mypool, cs.sock_nsi, connect_handler,
                              o.conntimeout, NULL,
                              &targetss.sockaddr, targetsslen,
                              IPPROTO_TCP, inet_port(&targetss),
                              NULL);
        }
#endif
        else {
            nsock_connect_tcp(mypool, cs.sock_nsi, connect_handler,
                              o.conntimeout, NULL,
                              &targetss.sockaddr, targetsslen,
                              inet_port(&targetss));
        }
    } else {
        /* A proxy connection. */
        static int connect_socket;
        int len;
        char *line;
        size_t n;

        if (httpconnect.storage.ss_family != AF_UNSPEC) {
            connect_socket = do_proxy_http();
            if (connect_socket == -1)
                return 1;
        } else if (socksconnect.storage.ss_family != AF_UNSPEC) {
            struct socket_buffer stateful_buf;
            struct socks4_data socks4msg;
            char socksbuf[8];

            connect_socket = do_connect(SOCK_STREAM);
            if (connect_socket == -1) {
                loguser("Proxy connection failed: %s.\n", socket_strerror(socket_errno()));
                return 1;
            }

            socket_buffer_init(&stateful_buf, connect_socket);

            if (o.verbose) {
                loguser("Connected to proxy %s:%hu\n", inet_socktop(&targetss),
                    inet_port(&targetss));
            }

            /* Fill the socks4_data struct */
            zmem(&socks4msg, sizeof(socks4msg));
            socks4msg.version = SOCKS4_VERSION;
            socks4msg.type = SOCKS_CONNECT;
            socks4msg.port = socksconnect.in.sin_port;
            socks4msg.address = socksconnect.in.sin_addr.s_addr;
            if (o.proxy_auth)
                Strncpy(socks4msg.username, (char *) o.proxy_auth, sizeof(socks4msg.username));

            len = 8 + strlen(socks4msg.username) + 1;

            if (send(connect_socket, (char *) &socks4msg, len, 0) < 0) {
                loguser("Error sending proxy request: %s.\n", socket_strerror(socket_errno()));
                return 1;
            }
            /* The size of the socks4 response is 8 bytes. So read exactly
               8 bytes from the buffer */
            if (socket_buffer_readcount(&stateful_buf, socksbuf, 8) < 0) {
                loguser("Error: short reponse from proxy.\n");
                return 1;
            }
            if (socksbuf[1] != 90) {
                loguser("Proxy connection failed.\n");
                return 1;
            }

            /* Clear out whatever is left in the socket buffer which may be
               already sent by proxy server along with http response headers. */
            line = socket_buffer_remainder(&stateful_buf, &n);
            /* Write the leftover data to stdout. */
            Write(STDOUT_FILENO, line, n);
        }

        /* Once the proxy negotiation is done, Nsock takes control of the
           socket. */
        cs.sock_nsi = nsi_new2(mypool, connect_socket, NULL);

        /* Create IOD for nsp->stdin */
        if ((cs.stdin_nsi = nsi_new2(mypool, 0, NULL)) == NULL)
            bye("Failed to create stdin nsiod.");

        post_connect(mypool, cs.sock_nsi);
    }

    /* connect */
    rc = nsock_loop(mypool, -1);

    if (o.verbose) {
        struct timeval end_time;
        double time;
        gettimeofday(&end_time, NULL);
        time = TIMEVAL_MSEC_SUBTRACT(end_time, start_time) / 1000.0;
        loguser("%lu bytes sent, %lu bytes received in %.2f seconds.\n",
            nsi_get_write_count(cs.sock_nsi),
            nsi_get_read_count(cs.sock_nsi), time);
    }

#if HAVE_SYS_UN_H
    if (o.af == AF_UNIX && o.udp) {
        if (o.verbose)
            loguser("Deleting source DGRAM Unix domain socket. [%s]\n", srcaddr.un.sun_path);
        unlink(srcaddr.un.sun_path);
    }
#endif

    nsp_delete(mypool);

    return rc == NSOCK_LOOP_ERROR ? 1 : 0;
}
Beispiel #6
0
int fcgi_spawn_connection(char *appPath, char **appArgv, char *addr, unsigned short port, const char *unixsocket, int child_count, int pid_fd, int nofork) {
	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;

	pid_t child;
	int val;

	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
		/* stevens says: */
		servlen = strlen(fcgi_addr_un.sun_path) + sizeof(fcgi_addr_un.sun_family);
#endif
		socket_type = AF_UNIX;
		fcgi_addr = (struct sockaddr *) &fcgi_addr_un;

		/* check if some backend is listening on the socket
		 * as if we delete the socket-file and rebind there will be no "socket already in use" error
		 */
		if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
			fprintf(stderr, "%s.%d\n",
				__FILE__, __LINE__);
			return -1;
		}

		if (-1 != connect(fcgi_fd, fcgi_addr, servlen)) {
			fprintf(stderr, "%s.%d: socket is already used, can't spawn\n",
				__FILE__, __LINE__);
			return -1;
		}

		/* cleanup previous socket if it exists */
		unlink(unixsocket);
		close(fcgi_fd);
	} else {
		fcgi_addr_in.sin_family = AF_INET;
                if (addr != NULL) {
                        fcgi_addr_in.sin_addr.s_addr = inet_addr(addr);
                } else {
                        fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
                }
		fcgi_addr_in.sin_port = htons(port);
		servlen = sizeof(fcgi_addr_in);

		socket_type = AF_INET;
		fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
	}

	/* open socket */
	if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
		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",
			__FILE__, __LINE__);
		return -1;
	}

	/* create socket */
	if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
		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",
			__FILE__, __LINE__);
		return -1;
	}

	if (!nofork) {
		child = fork();
	} else {
		child = 0;
	}

	switch (child) {
	case 0: {
		char cgi_childs[64];

		int i = 0;

		/* is safe 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 */
		if (appArgv) {
			execv(appArgv[0], appArgv);

		} else {
			char *b = malloc(strlen("exec ") + strlen(appPath) + 1);
			strcpy(b, "exec ");
			strcat(b, appPath);

			/* exec the cgi */
			execl("/bin/sh", "sh", "-c", b, (char *)NULL);
		}

		exit(errno);

		break;
	}
	case -1:
		/* error */
		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",
				__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",
					__FILE__, __LINE__,
					WEXITSTATUS(status), strerror(WEXITSTATUS(status)));
			} else if (WIFSIGNALED(status)) {
				fprintf(stderr, "%s.%d: child signaled: %d\n",
					__FILE__, __LINE__,
					WTERMSIG(status));
			} else {
				fprintf(stderr, "%s.%d: child died somehow: %d\n",
					__FILE__, __LINE__,
					status);
			}
		}

		break;
	}

	close(fcgi_fd);

	return 0;
}
Beispiel #7
0
/*
 * connect_by_number:  Wheeeee. Yet another monster function i get to fix
 * for the sake of it being inadequate for extension.
 *
 * we now take four arguments:
 *
 *	- hostname - name of the host (pathname) to connect to (if applicable)
 *	- portnum - port number to connect to or listen on (0 if you dont care)
 *	- service -	0 - set up a listening socket
 *			1 - set up a connecting socket
 *	- protocol - 	0 - use the TCP protocol
 *			1 - use the UDP protocol
 *
 *
 * Returns:
 *	Non-negative number -- new file descriptor ready for use
 *	-1 -- could not open a new file descriptor or 
 *		an illegal value for the protocol was specified
 *	-2 -- call to bind() failed
 *	-3 -- call to listen() failed.
 *	-4 -- call to connect() failed
 *	-5 -- call to getsockname() failed
 *	-6 -- the name of the host could not be resolved
 *	-7 -- illegal or unsupported request
 *	-8 -- no socks access
 *
 *
 * Credit: I couldnt have put this together without the help of BSD4.4-lite
 * User SupplimenTary Document #20 (Inter-process Communications tutorial)
 */
int BX_connect_by_number(char *hostn, unsigned short *portnum, int service, int protocol, int nonblocking)
{
	int fd = -1;
	int is_unix = (hostn && *hostn == '/');
	int sock_type, proto_type;

#ifndef __OPENNT
	sock_type = (is_unix) ? AF_UNIX : AF_INET;
#else
	sock_type = AF_INET;
#endif

	proto_type = (protocol == PROTOCOL_TCP) ? SOCK_STREAM : SOCK_DGRAM;

	if ((fd = socket(sock_type, proto_type, 0)) < 0)
		return -1;

	set_socket_options (fd);

	/* Unix domain server */
#ifdef HAVE_SYS_UN_H
	if (is_unix)
	{
		struct sockaddr_un name;

		memset(&name, 0, sizeof(struct sockaddr_un));
		name.sun_family = AF_UNIX;
		strcpy(name.sun_path, hostn);
#ifdef HAVE_SUN_LEN
# ifdef SUN_LEN
		name.sun_len = SUN_LEN(&name);
# else
		name.sun_len = strlen(hostn) + 1;
# endif
#endif

		if (is_unix && (service == SERVICE_SERVER))
		{
			if (bind(fd, (struct sockaddr *)&name, strlen(name.sun_path) + sizeof(name.sun_family)))
				return close(fd), -2;
			if (protocol == PROTOCOL_TCP)
				if (listen(fd, 4) < 0)
					return close(fd), -3;
		}

		/* Unix domain client */
		else if (service == SERVICE_CLIENT)
		{
			alarm(get_int_var(CONNECT_TIMEOUT_VAR));
			if (connect (fd, (struct sockaddr *)&name, strlen(name.sun_path) + 2) < 0)
			{
				alarm(0);
				return close(fd), -4;
			}
			alarm(0);
		}
	}
	else
#endif

	/* Inet domain server */
	if (!is_unix && (service == SERVICE_SERVER))
	{
		int length;
#ifdef IP_PORTRANGE
		int ports;
#endif
		struct sockaddr_foobar name;
#ifdef IPV6
		struct in6_addr any = { IN6ADDR_ANY_INIT };

		memset(&name, 0, sizeof(struct sockaddr_foobar));
		name.sf_family = AF_INET6;
		memcpy(&name.sf_addr6, &any, sizeof(struct in6_addr));
#else
		memset(&name, 0, sizeof(struct sockaddr_foobar));
		name.sf_family = AF_INET;
		name.sf_addr.s_addr = htonl(INADDR_ANY);
#endif

		name.sf_port = htons(*portnum);
#ifdef PARANOID
		name.sf_port += (unsigned short)(rand() & 255);
#endif
		
#ifdef IP_PORTRANGE
		if (getenv("EPIC_USE_HIGHPORTS"))
		{
			ports = IP_PORTRANGE_HIGH;
			setsockopt(fd, IPPROTO_IP, IP_PORTRANGE, 
					(char *)&ports, sizeof(ports));
		}
#endif

		if (bind(fd, (struct sockaddr *)&name, sizeof(name)))
			return close(fd), -2;

		length = sizeof (name);
		if (getsockname(fd, (struct sockaddr *)&name, &length))
			return close(fd), -5;

		*portnum = ntohs(name.sf_port);

		if (protocol == PROTOCOL_TCP)
			if (listen(fd, 4) < 0)
				return close(fd), -3;
#ifdef NON_BLOCKING_CONNECTS
		if (nonblocking && set_non_blocking(fd) < 0)
			return close(fd), -4;
#endif
	}

	/* Inet domain client */
	else if (!is_unix && (service == SERVICE_CLIENT))
	{
		struct sockaddr_foobar server;
		struct hostent *hp;
#ifdef WINNT
		char buf[BIG_BUFFER_SIZE+1];
#endif		
#ifdef IPV6
		struct addrinfo hints, *res;
		struct sockaddr_foobar *sf = NULL;
#else
		struct sockaddr_in localaddr;
		if (LocalHostName)
		{
			memset(&localaddr, 0, sizeof(struct sockaddr_in));
			localaddr.sin_family = AF_INET;
			localaddr.sin_addr = LocalHostAddr.sf_addr;
			localaddr.sin_port = 0;
			if (bind(fd, (struct sockaddr *)&localaddr, sizeof(localaddr)))
				return close(fd), -2;
		}
#endif

		memset(&server, 0, sizeof(struct sockaddr_in));
#ifndef WINNT

#ifdef IPV6
                memset(&hints, 0, sizeof(hints));
                if (!getaddrinfo(hostn, NULL, &hints, &res) && res)
                {
                        sf = (struct sockaddr_foobar*) res->ai_addr;

                        close(fd);

                        proto_type = (protocol == PROTOCOL_TCP) ? SOCK_STREAM : SOCK_DGRAM;
                        if ((fd = socket(sf->sf_family, proto_type, 0)) < 0)
                                return -1;
                        set_socket_options (fd);

                        if ((server.sf_family = sf->sf_family) == AF_INET)
                                memcpy(&server.sf_addr, &sf->sf_addr, sizeof(struct in_addr));
                        else
                                memcpy(&server.sf_addr6, &sf->sf_addr6, sizeof(struct in6_addr));
                        server.sf_port = htons(*portnum);

                        memset(&hints, 0, sizeof(struct addrinfo));
                        hints.ai_family = res->ai_family;
                        freeaddrinfo(res);
 
                        if (LocalHostName && !getaddrinfo(LocalHostName, NULL, &hints, &res) && res)
                        {
                                if (bind(fd, (struct sockaddr *) res->ai_addr, sizeof(struct sockaddr_foobar)))
                                        return close(fd), -2;
                                freeaddrinfo(res);
                        }
                }
                else
                        return close(fd), -6;

#else
		if (isdigit((unsigned char)hostn[strlen(hostn)-1]))
			inet_aton(hostn, (struct in_addr *)&server.sf_addr);
		else
		{
			if (!(hp = gethostbyname(hostn)))
	  			return close(fd), -6;
			memcpy(&server.sf_addr, hp->h_addr, hp->h_length);
		}
		server.sf_family = AF_INET;
		server.sf_port = htons(*portnum);
#endif /* IPV6 */
		
#else
		/* for some odd reason resolv() fails on NT... */
/*		server = (*(struct sockaddr_in *) hostn);*/
		if (!hostn)
		{
			gethostname(buf, sizeof(buf));
			hostn = buf;
		}
		if ((server.sf_addr.s_addr = inet_addr(hostn)) == -1)
		{
			if ((hp = gethostbyname(hostn)) != NULL)
			{
				memset(&server, 0, sizeof(server));
				bcopy(hp->h_addr, (char *) &server.sf_addr,
					hp->h_length);
				server.sf_family = hp->h_addrtype;
			}
			else
				return (-2);
		}
		else
			server.sf_family = AF_INET;
		server.sf_port = (unsigned short) htons(*portnum);
#endif /* WINNT */

#ifdef NON_BLOCKING_CONNECTS
		if (!use_socks && nonblocking && set_non_blocking(fd) < 0)
			return close(fd), -4;
#endif

#if !defined(WTERM_C) && !defined(STERM_C) && !defined(IPV6)

		if (use_socks && get_string_var(SOCKS_HOST_VAR))
		{

			fd = handle_socks(fd, *((struct sockaddr_in*) &server), get_string_var(SOCKS_HOST_VAR), get_int_var(SOCKS_PORT_VAR));
			if (fd == -1)
				return -4;
			else
				return fd;
		}
#endif
		alarm(get_int_var(CONNECT_TIMEOUT_VAR));
		if (connect (fd, (struct sockaddr *)&server, sizeof(server)) < 0)
		{
			alarm(0);
#ifdef NON_BLOCKING_CONNECTS
			if (!nonblocking)
#endif
				return close(fd), -4;
		}
		alarm(0);
	}

	/* error */
	else
		return close(fd), -7;

	return fd;
}
/**---------------------------------------------------------------------------
 * Enqueue an upcall IRQ event for the control-plane on the upcall socket.
 * The API version is added as the header for each upcall message for
 * control-plane sanity check. 
 *
 * @param[in] ev Pointer to the upcall event.
 * @param[out] boolean Returns true if the IRQ event is successfully written 
 * to the socket.
 *---------------------------------------------------------------------------*/ 
boolean
vqec_dp_ipcserver_tx_upcall_irq (vqec_dp_upcall_irq_event_t *ev)
{
#define VQEC_IRQ_IOV_CNT 2
    vqec_dp_upcall_info_t *upc_info;
    int32_t len, err, iov_cnt = 0;
    boolean ret = FALSE;
    struct msghdr msg;
    struct iovec iov[VQEC_IRQ_IOV_CNT];
    vqec_dp_api_version_t ver = VQEC_DP_API_VERSION;
    vqec_dp_tlm_t *tlm = vqec_dp_tlm_get(); 
    mm_segment_t old_fs;

    if (!ev || 
        !tlm) {
        return (ret);
    }

    upc_info = &s_irq_upcall_info;

    if (upc_info->sock) {

        memset(&msg, 0, sizeof(msg));
        iov[iov_cnt].iov_base = &ver;  /* version sub-block */
        iov[iov_cnt].iov_len = sizeof(ver);
        iov_cnt++;
        
        iov[iov_cnt].iov_base = ev;  /* event sub-block */
        iov[iov_cnt].iov_len = sizeof(*ev);
        iov_cnt++;
        
        msg.msg_iov = iov;
        msg.msg_iovlen = iov_cnt;
        
        msg.msg_name = (void *)&upc_info->sock_addr;
        msg.msg_namelen = SUN_LEN(&upc_info->sock_addr);
        msg.msg_flags = MSG_DONTWAIT;
        
        len = sizeof(ver) + sizeof(*ev);
        old_fs = get_fs();
        set_fs(KERNEL_DS);
        err = sock_sendmsg(upc_info->sock, 
                           &msg,
                           len);
        set_fs(old_fs);
        if ((err < 0) || (err != len)) {
            /* failed to enQ IRQ to the control-plane. */
            VQEC_DP_TLM_CNT(irqs_dropped, tlm); 
            VQEC_DP_SYSLOG_PRINT(LOST_UPCALL, 
                                 "socket enQ for upcall IRQ event failed"); 
        } else {
            /* successfully enQd IRQ to the control-plane. */
            upc_info->upcall_count++;
            VQEC_DP_TLM_CNT(irqs_sent, tlm);
            ret = TRUE;
        }
    } else {
        /* don't have a socket setup. */
        VQEC_DP_TLM_CNT(irqs_dropped, tlm);           
        VQEC_DP_SYSLOG_PRINT(LOST_UPCALL, 
                             "no socket decriptor to send IRQ upcall");
    }

    return (ret);
}
Beispiel #9
0
int main (int argc, char *const *argv, char *const *envp, const char **apple)
{
#if defined (DEBUG_LLDB_LAUNCHER)
    const char *program_name = strrchr(apple[0], '/');
    
    if (program_name)
        program_name++; // Skip the last slash..
    else
        program_name = apple[0];
    
    printf("%s called with:\n", program_name);
    for (int i=0; i<argc; ++i)
        printf("argv[%u] = '%s'\n", i, argv[i]);
#endif

    cpu_type_t cpu_type = 0;
    bool show_usage = false;
    int ch;
    int disable_aslr = 0; // By default we disable ASLR
    bool pass_env = true;
    std::string unix_socket_name;
    std::string working_dir;
    
#if __GLIBC__
    optind = 0;
#else
    optreset = 1;
    optind = 1;
#endif

	while ((ch = getopt_long_only(argc, argv, "a:deE:hsu:?", g_long_options, NULL)) != -1)
	{
		switch (ch) 
		{
        case 0:
            break;

		case 'a':	// "-a i386" or "--arch=i386"
			if (optarg)
			{
				if (streq (optarg, "i386"))
                    cpu_type = CPU_TYPE_I386;
				else if (streq (optarg, "x86_64"))
                    cpu_type = CPU_TYPE_X86_64;
                else if (streq (optarg, "x86_64h"))
                    cpu_type = 0; // Don't set CPU type when we have x86_64h
                else if (strstr (optarg, "arm") == optarg)
                    cpu_type = CPU_TYPE_ARM;
                else
                {
                    ::fprintf (stderr, "error: unsupported cpu type '%s'\n", optarg);
                    ::exit (1);
                }
			} 
			break;

        case 'd':
            disable_aslr = 1;
            break;            

        case 'e':
            pass_env = false;
            break;
            
        case 'E':
            {
                // Since we will exec this program into our new program, we can just set environment
                // variables in this process and they will make it into the child process.
                std::string name;
                std::string value;
                const char *equal_pos = strchr (optarg, '=');
                if (equal_pos)
                {
                    name.assign (optarg, equal_pos - optarg);
                    value.assign (equal_pos + 1);
                }
                else
                {
                    name = optarg;
                }
                ::setenv (name.c_str(), value.c_str(), 1);
            }
            break;
            
        case 's':
            // Create a new session to avoid having control-C presses kill our current
            // terminal session when this program is launched from a .command file
            ::setsid();
            break;

        case 'u':
            unix_socket_name.assign (optarg);
            break;

        case 'w':
            {
                struct stat working_dir_stat;
                if (stat (optarg, &working_dir_stat) == 0)
                    working_dir.assign (optarg);
                else
                    ::fprintf(stderr, "warning: working directory doesn't exist: '%s'\n", optarg);
            }
            break;

		case 'h':
		case '?':
		default:
			show_usage = true;
			break;
		}
	}
	argc -= optind;
	argv += optind;

    if (show_usage || argc <= 0 || unix_socket_name.empty())
        usage();

#if defined (DEBUG_LLDB_LAUNCHER)
    printf ("\n%s post options:\n", program_name);
    for (int i=0; i<argc; ++i)
        printf ("argv[%u] = '%s'\n", i, argv[i]);
#endif

    // Open the socket that was passed in as an option
    struct sockaddr_un saddr_un;
    int s = ::socket (AF_UNIX, SOCK_STREAM, 0);
    if (s < 0)
    {
        perror("error: socket (AF_UNIX, SOCK_STREAM, 0)");
        exit(1);
    }

    saddr_un.sun_family = AF_UNIX;
    ::strncpy(saddr_un.sun_path, unix_socket_name.c_str(), sizeof(saddr_un.sun_path) - 1);
    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
    saddr_un.sun_len = SUN_LEN (&saddr_un);

    if (::connect (s, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 
    {
        perror("error: connect (socket, &saddr_un, saddr_un_len)");
        exit(1);
    }
    
    // We were able to connect to the socket, now write our PID so whomever
    // launched us will know this process's ID
    char pid_str[64];
    const int pid_str_len = ::snprintf (pid_str, sizeof(pid_str), "%i", ::getpid());
    const int bytes_sent = ::send (s, pid_str, pid_str_len, 0);
    
    if (pid_str_len != bytes_sent)
    {
        perror("error: send (s, pid_str, pid_str_len, 0)");
        exit (1);
    }

    // We are done with the socket
    close (s);

    system("clear");
    printf ("Launching: '%s'\n", argv[0]);
    if (working_dir.empty())
    {
        char cwd[PATH_MAX];
        const char *cwd_ptr = getcwd(cwd, sizeof(cwd));
        printf ("Working directory: '%s'\n", cwd_ptr);
    }
    else
    {
        printf ("Working directory: '%s'\n", working_dir.c_str());
    }
    printf ("%i arguments:\n", argc);

    for (int i=0; i<argc; ++i)
        printf ("argv[%u] = '%s'\n", i, argv[i]);

    // Now we posix spawn to exec this process into the inferior that we want
    // to debug.
    posix_spawn_for_debug (argv,
                           pass_env ? *_NSGetEnviron() : NULL, // Pass current environment as we may have modified it if "--env" options was used, do NOT pass "envp" here
                           working_dir.empty() ? NULL : working_dir.c_str(),
                           cpu_type, 
                           disable_aslr);
    
	return 0;
}
Beispiel #10
0
int create_socket()
{
    int sockfd;
    ksocklen_t addrlen;
    struct stat s;

    QCString display(getenv("DISPLAY"));
    if (display.isEmpty())
    {
        kdWarning(1205) << "$DISPLAY is not set\n";
        return -1;
    }

    // strip the screen number from the display
    display.replace(QRegExp("\\.[0-9]+$"), "");

    sock = QFile::encodeName(locateLocal("socket", QString("kdesud_%1").arg(display)));
    int stat_err=lstat(sock, &s);
    if(!stat_err && S_ISLNK(s.st_mode)) {
        kdWarning(1205) << "Someone is running a symlink attack on you\n";
        if(unlink(sock)) {
            kdWarning(1205) << "Could not delete symlink\n";
            return -1;
        }
    }

    if (!access(sock, R_OK|W_OK))
    {
        KDEsuClient client;
        if (client.ping() == -1)
        {
            kdWarning(1205) << "stale socket exists\n";
            if (unlink(sock))
            {
                kdWarning(1205) << "Could not delete stale socket\n";
                return -1;
            }
        } else
        {
            kdWarning(1205) << "kdesud is already running\n";
            return -1;
        }

    }

    sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        kdError(1205) << "socket(): " << ERR << "\n";
        return -1;
    }

    struct sockaddr_un addr;
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, sock, sizeof(addr.sun_path)-1);
    addr.sun_path[sizeof(addr.sun_path)-1] = '\000';
    addrlen = SUN_LEN(&addr);
    if (bind(sockfd, (struct sockaddr *)&addr, addrlen) < 0)
    {
        kdError(1205) << "bind(): " << ERR << "\n";
        return -1;
    }

    struct linger lin;
    lin.l_onoff = lin.l_linger = 0;
    if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *) &lin,
                   sizeof(linger)) < 0)
    {
        kdError(1205) << "setsockopt(SO_LINGER): " << ERR << "\n";
        return -1;
    }

    int opt = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt,
                   sizeof(opt)) < 0)
    {
        kdError(1205) << "setsockopt(SO_REUSEADDR): " << ERR << "\n";
        return -1;
    }
    opt = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
                   sizeof(opt)) < 0)
    {
        kdError(1205) << "setsockopt(SO_KEEPALIVE): " << ERR << "\n";
        return -1;
    }
    chmod(sock, 0600);
    return sockfd;
}
boolean
vqec_dp_ipcserver_eject_pak (vqec_dp_pak_hdr_t *hdr, vqec_pak_t *pak)
{
#define VQEC_EJECT_IOV_CNT 3
    vqec_dp_upcall_info_t *pak_upc_info;
    int32_t len, err, iov_cnt = 0;
    boolean ret = FALSE;
    struct msghdr msg;
    struct iovec iov[VQEC_EJECT_IOV_CNT];
    vqec_dp_api_version_t ver = VQEC_DP_API_VERSION;
    vqec_dp_tlm_t *tlm = vqec_dp_tlm_get(); 
    mm_segment_t old_fs;
    uint32_t buf_len;

    if (!hdr || 
        !pak || 
        !pak->skb ||
        !tlm) {
        return (ret);
    }

    pak_upc_info = &s_pak_upcall_info;
    if (!pak_upc_info->sock) { 
        /* don't have a socket setup. */
        VQEC_DP_TLM_CNT(ejects_dropped, tlm);
        VQEC_DP_SYSLOG_PRINT(LOST_UPCALL, 
                             "no socket decriptor to send ejected packet");
        return (ret);
    }	
	
    buf_len = ((struct sk_buff *)(pak->skb))->len - sizeof(struct udphdr);
    if (!buf_len || buf_len > VQEC_DP_IPC_MAX_PAKSIZE) {
        VQEC_DP_TLM_CNT(ejects_dropped, tlm);	
        VQEC_DP_SYSLOG_PRINT(LOST_UPCALL, 	
                             "exceeds maximum packet size");
        return (ret);	
    }	

    err = skb_copy_bits(pak->skb, 
                        sizeof(struct udphdr),
                        s_nat_rspbuf, 
                        buf_len);
    if (err < 0) {
        /* failed to enQ. */
        VQEC_DP_TLM_CNT(ejects_dropped, tlm); 
        VQEC_DP_SYSLOG_PRINT(LOST_UPCALL, 
                             "copy of socket buffer failed");
        return (ret);
    }

        
    memset(&msg, 0, sizeof(msg));
    iov[iov_cnt].iov_base = &ver;  /* version sub-block */
    iov[iov_cnt].iov_len = sizeof(ver);
    iov_cnt++;

    iov[iov_cnt].iov_base = hdr;  /* packet header sub-block */
    iov[iov_cnt].iov_len = sizeof(*hdr);
    iov_cnt++;
    
    iov[iov_cnt].iov_base = s_nat_rspbuf;  /* packet buffer sub-block */
    iov[iov_cnt].iov_len = buf_len;
    iov_cnt++;
    
    msg.msg_iov = iov;
    msg.msg_iovlen = iov_cnt;
    
    msg.msg_name = (void *)&pak_upc_info->sock_addr;
    msg.msg_namelen = SUN_LEN(&pak_upc_info->sock_addr);
    msg.msg_flags = MSG_DONTWAIT;
    
    len = sizeof(ver) + sizeof(*hdr) + buf_len;
    old_fs = get_fs();
    set_fs(KERNEL_DS);
    err = sock_sendmsg(pak_upc_info->sock,
                       &msg,
                       len);
    set_fs(old_fs);
    if ((err < 0) || 
        (err != len)) {
        /* failed to enQ. */
        VQEC_DP_TLM_CNT(ejects_dropped, tlm); 
        VQEC_DP_SYSLOG_PRINT(LOST_UPCALL, 
                             "Socket enQ for ejected packet failed");
        
    } else {
        /* successfully enQd IRQ to the control-plane. */
        pak_upc_info->upcall_count++;
        VQEC_DP_TLM_CNT(ejects_sent, tlm);
        ret = TRUE;        
    }

    
    return (ret);
}
Beispiel #12
0
void socket_read(char *programName)
{
		int audispdSocketDescriptor = -1, charactersRead, bytesReceived;
		char buffer[BUFFER_LENGTH];
		struct sockaddr_un serverAddress;

		do {
				audispdSocketDescriptor = socket(AF_UNIX, SOCK_STREAM, 0);
				if (audispdSocketDescriptor < 0) {
						fprintf(stderr, "%s: Unable to construct a socket. Error: %s\n", programName, strerror(errno));
						break;
				}

				memset(&serverAddress, 0, sizeof (serverAddress));
				serverAddress.sun_family = AF_UNIX;
				strcpy(serverAddress.sun_path, socketPath);

				charactersRead = connect(audispdSocketDescriptor, (struct sockaddr *) &serverAddress, SUN_LEN(&serverAddress));
				if (charactersRead < 0) {
						fprintf(stderr, "%s: Unable to connect to the socket: %s. Error: %s\n", programName, socketPath, strerror(errno));
						break;
				}

				fprintf(stderr, "#CONTROL_MSG#pid=%d\n", getpid());

				while (TRUE) {
						memset(&buffer, 0, BUFFER_LENGTH);
						charactersRead = recv(audispdSocketDescriptor, & buffer[0], BUFFER_LENGTH - 1, 0);
						if (charactersRead < 0) {
								fprintf(stderr, "%s: Error while reading from the socket. Error: %s\n", programName, strerror(errno));
								break;
						} else if (charactersRead == 0) {
								fprintf(stderr, "%s: Server closed the connection. Errror: %s\n", programName, strerror(errno));
								break;
						}
						UBSI_buffer(buffer);
				}
		} while (FALSE);

		if (audispdSocketDescriptor != -1) close(audispdSocketDescriptor);
}
Beispiel #13
0
void QWSServerSocket::init(const QString &file)
{
#ifndef QT_NO_SXE
    QByteArray fn = file.toLocal8Bit();
    bool result = QUnixSocketServer::listen( fn );
    if ( !result )
    {
        QUnixSocketServer::ServerError err = serverError();
        switch ( err )
        {
            case InvalidPath:
                qWarning("QWSServerSocket:: invalid path %s", qPrintable(file));
                break;
            case ResourceError:
            case BindError:
            case ListenError:
                qWarning("QWSServerSocket:: could not listen on path %s", qPrintable(file));
                break;
            default:
                break;
        }
    }
#else
    int backlog = 16; //#####

// create socket
    int s = ::socket(PF_LOCAL, SOCK_STREAM, 0);
    if (s == -1) {
        perror("QWSServerSocket::init");
        qWarning("QWSServerSocket: unable to create socket.");
        return;
    }

    QByteArray fn = file.toLocal8Bit();
    unlink(fn.constData()); // doesn't have to succeed

    // bind socket
    struct sockaddr_un a;
    memset(&a, 0, sizeof(a));
    a.sun_family = PF_LOCAL;
    strncpy(a.sun_path, fn.constData(), sizeof(a.sun_path) - 1);
    int r = ::bind(s, (struct sockaddr*)&a, SUN_LEN(&a));
    if (r < 0) {
        perror("QWSServerSocket::init");
        qWarning("QWSServerSocket: could not bind to file %s", fn.constData());
        ::close(s);
        return;
    }

    if (chmod(fn.constData(), 0600) < 0) {
        perror("QWSServerSocket::init");
        qWarning("Could not set permissions of %s", fn.constData());
        ::close(s);
        return;
    }

    // listen
    if (::listen(s, backlog) == 0) {
        if (!setSocketDescriptor(s))
            qWarning( "QWSServerSocket could not set descriptor %d : %s", s, errorString().toLatin1().constData());
    } else {
        perror("QWSServerSocket::init");
        qWarning("QWSServerSocket: could not listen to file %s", fn.constData());
        ::close(s);
    }
#endif
}
Beispiel #14
0
static gpgrt_ssize_t
fun_writer (void *cookie_arg, const void *buffer, size_t size)
{
  struct fun_cookie_s *cookie = cookie_arg;

  /* FIXME: Use only estream with a callback for socket writing.  This
     avoids the ugly mix of fd and estream code.  */

  /* Note that we always try to reconnect to the socket but print
     error messages only the first time an error occurred.  If
     RUNNING_DETACHED is set we don't fall back to stderr and even do
     not print any error messages.  This is needed because detached
     processes often close stderr and by writing to file descriptor 2
     we might send the log message to a file not intended for logging
     (e.g. a pipe or network connection). */
  if (cookie->want_socket && cookie->fd == -1)
    {
#ifdef WITH_IPV6
      struct sockaddr_in6 srvr_addr_in6;
#endif
      struct sockaddr_in srvr_addr_in;
#ifndef HAVE_W32_SYSTEM
      struct sockaddr_un srvr_addr_un;
#endif
      size_t addrlen;
      struct sockaddr *srvr_addr = NULL;
      unsigned short port = 0;
      int af = AF_LOCAL;
      int pf = PF_LOCAL;
      const char *name = cookie->name;

      /* Not yet open or meanwhile closed due to an error. */
      cookie->is_socket = 0;

      /* Check whether this is a TCP socket or a local socket.  */
      if (!strncmp (name, "tcp://", 6) && name[6])
        {
          name += 6;
          af = AF_INET;
          pf = PF_INET;
        }
#ifndef HAVE_W32_SYSTEM
      else if (!strncmp (name, "socket://", 9) && name[9])
        name += 9;
#endif

      if (af == AF_LOCAL)
        {
#ifdef HAVE_W32_SYSTEM
          addrlen = 0;
#else
          memset (&srvr_addr, 0, sizeof srvr_addr);
          srvr_addr_un.sun_family = af;
          strncpy (srvr_addr_un.sun_path,
                   name, sizeof (srvr_addr_un.sun_path)-1);
          srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0;
          srvr_addr = (struct sockaddr *)&srvr_addr_un;
          addrlen = SUN_LEN (&srvr_addr_un);
#endif
        }
      else
        {
          char *addrstr, *p;
#ifdef HAVE_INET_PTON
          void *addrbuf = NULL;
#endif /*HAVE_INET_PTON*/

          addrstr = xtrymalloc (strlen (name) + 1);
          if (!addrstr)
            addrlen = 0; /* This indicates an error.  */
          else if (*name == '[')
            {
              /* Check for IPv6 literal address.  */
              strcpy (addrstr, name+1);
              p = strchr (addrstr, ']');
              if (!p || p[1] != ':' || !parse_portno (p+2, &port))
                {
                  gpg_err_set_errno (EINVAL);
                  addrlen = 0;
                }
              else
                {
                  *p = 0;
#ifdef WITH_IPV6
                  af = AF_INET6;
                  pf = PF_INET6;
                  memset (&srvr_addr_in6, 0, sizeof srvr_addr_in6);
                  srvr_addr_in6.sin6_family = af;
                  srvr_addr_in6.sin6_port = htons (port);
#ifdef HAVE_INET_PTON
                  addrbuf = &srvr_addr_in6.sin6_addr;
#endif /*HAVE_INET_PTON*/
                  srvr_addr = (struct sockaddr *)&srvr_addr_in6;
                  addrlen = sizeof srvr_addr_in6;
#else
                  gpg_err_set_errno (EAFNOSUPPORT);
                  addrlen = 0;
#endif
                }
            }
          else
            {
              /* Check for IPv4 literal address.  */
              strcpy (addrstr, name);
              p = strchr (addrstr, ':');
              if (!p || !parse_portno (p+1, &port))
                {
                  gpg_err_set_errno (EINVAL);
                  addrlen = 0;
                }
              else
                {
                  *p = 0;
                  memset (&srvr_addr_in, 0, sizeof srvr_addr_in);
                  srvr_addr_in.sin_family = af;
                  srvr_addr_in.sin_port = htons (port);
#ifdef HAVE_INET_PTON
                  addrbuf = &srvr_addr_in.sin_addr;
#endif /*HAVE_INET_PTON*/
                  srvr_addr = (struct sockaddr *)&srvr_addr_in;
                  addrlen = sizeof srvr_addr_in;
                }
            }

          if (addrlen)
            {
#ifdef HAVE_INET_PTON
              if (inet_pton (af, addrstr, addrbuf) != 1)
                addrlen = 0;
#else /*!HAVE_INET_PTON*/
              /* We need to use the old function.  If we are here v6
                 support isn't enabled anyway and thus we can do fine
                 without.  Note that Windows has a compatible inet_pton
                 function named inetPton, but only since Vista.  */
              srvr_addr_in.sin_addr.s_addr = inet_addr (addrstr);
              if (srvr_addr_in.sin_addr.s_addr == INADDR_NONE)
                addrlen = 0;
#endif /*!HAVE_INET_PTON*/
            }

          xfree (addrstr);
        }

      cookie->fd = addrlen? socket (pf, SOCK_STREAM, 0) : -1;
      if (cookie->fd == -1)
        {
          if (!cookie->quiet && !running_detached
              && isatty (es_fileno (es_stderr)))
            es_fprintf (es_stderr, "failed to create socket for logging: %s\n",
                        strerror(errno));
        }
      else
        {
          if (connect (cookie->fd, srvr_addr, addrlen) == -1)
            {
              if (!cookie->quiet && !running_detached
                  && isatty (es_fileno (es_stderr)))
                es_fprintf (es_stderr, "can't connect to '%s': %s\n",
                            cookie->name, strerror(errno));
              sock_close (cookie->fd);
              cookie->fd = -1;
            }
        }

      if (cookie->fd == -1)
        {
          if (!running_detached)
            {
              /* Due to all the problems with apps not running
                 detached but being called with stderr closed or used
                 for a different purposes, it does not make sense to
                 switch to stderr.  We therefore disable it. */
              if (!cookie->quiet)
                {
                  /* fputs ("switching logging to stderr\n", stderr);*/
                  cookie->quiet = 1;
                }
              cookie->fd = -1; /*fileno (stderr);*/
            }
        }
      else /* Connection has been established. */
        {
          cookie->quiet = 0;
          cookie->is_socket = 1;
        }
    }

  log_socket = cookie->fd;
  if (cookie->fd != -1)
    {
#ifdef HAVE_W32CE_SYSTEM
      if (cookie->use_writefile)
        {
          DWORD nwritten;

          WriteFile ((HANDLE)cookie->fd, buffer, size, &nwritten, NULL);
          return (gpgrt_ssize_t)size; /* Okay.  */
        }
#endif
      if (!writen (cookie->fd, buffer, size, cookie->is_socket))
        return (gpgrt_ssize_t)size; /* Okay. */
    }

  if (!running_detached && cookie->fd != -1
      && isatty (es_fileno (es_stderr)))
    {
      if (*cookie->name)
        es_fprintf (es_stderr, "error writing to '%s': %s\n",
                    cookie->name, strerror(errno));
      else
        es_fprintf (es_stderr, "error writing to file descriptor %d: %s\n",
                    cookie->fd, strerror(errno));
    }
  if (cookie->is_socket && cookie->fd != -1)
    {
      sock_close (cookie->fd);
      cookie->fd = -1;
      log_socket = -1;
    }

  return (gpgrt_ssize_t)size;
}
Beispiel #15
0
void StartDebuggingAndDetach(char *udid, char *app_path)
{
	SDMMD_AMDeviceRef device = FindDeviceFromUDID(udid);
	if (device) {

		CFStringRef bundleId = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)app_path, strlen(app_path), kCFStringEncodingUTF8, false);
		CFURLRef relative_url = CFURLCreateWithFileSystemPath(NULL, bundleId, kCFURLPOSIXPathStyle, false);
		CFURLRef disk_app_url = CFURLCopyAbsoluteURL(relative_url);
		CFStringRef bundle_identifier = copy_disk_app_identifier(disk_app_url);

		SDMMD_AMDebugConnectionRef debug = SDMMD_AMDebugConnectionCreateForDevice(device);
		SDMMD_AMDebugConnectionStart(debug);

		uintptr_t socket = SDMMD_AMDServiceConnectionGetSocket(debug->connection);
		CFSocketContext context = {0, (void *)socket, NULL, NULL, NULL};
		CFSocketRef fdvendor = CFSocketCreate(NULL, AF_UNIX, 0, 0, kCFSocketAcceptCallBack, &socket_callback, &context);

		int yes = 1;
		setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

		struct sockaddr_un address;
		memset(&address, 0, sizeof(address));
		address.sun_family = AF_UNIX;
		strcpy(address.sun_path, SDM_LLDB_SOCKET);
		address.sun_len = SUN_LEN(&address);
		CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&address, sizeof(address));

		unlink(SDM_LLDB_SOCKET);

		CFSocketSetAddress(fdvendor, address_data);
		CFRelease(address_data);
		CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, fdvendor, 0), kCFRunLoopCommonModes);

		SDMMD_AMDeviceRef device = SDMMD_AMDServiceConnectionGetDevice(debug->connection);
		CFMutableStringRef cmds = CFStringCreateMutableCopy(NULL, 0, LLDB_PREP_CMDS);
		CFRange range = {0, CFStringGetLength(cmds)};

		CFURLRef device_app_url = copy_device_app_url(device, bundle_identifier);
		CFStringRef device_app_path = CFURLCopyFileSystemPath(device_app_url, kCFURLPOSIXPathStyle);
		CFStringFindAndReplace(cmds, CFSTR("{DEVICE_PATH}"), device_app_path, range, 0);
		range.length = CFStringGetLength(cmds);

		CFStringRef disk_app_path = CFURLCopyFileSystemPath(disk_app_url, kCFURLPOSIXPathStyle);
		CFStringFindAndReplace(cmds, CFSTR("{APP_PATH}"), disk_app_path, range, 0);
		range.length = CFStringGetLength(cmds);

		CFURLRef device_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, device_app_url);
		CFStringRef device_container_path = CFURLCopyFileSystemPath(device_container_url, kCFURLPOSIXPathStyle);
		CFMutableStringRef dcp_noprivate = CFStringCreateMutableCopy(NULL, 0, device_container_path);
		range.length = CFStringGetLength(dcp_noprivate);
		CFStringFindAndReplace(dcp_noprivate, CFSTR("/private/var/"), CFSTR("/var/"), range, 0);
		range.length = CFStringGetLength(cmds);
		CFStringFindAndReplace(cmds, CFSTR("{device_container}"), dcp_noprivate, range, 0);
		range.length = CFStringGetLength(cmds);

		CFURLRef disk_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, disk_app_url);
		CFStringRef disk_container_path = CFURLCopyFileSystemPath(disk_container_url, kCFURLPOSIXPathStyle);
		CFStringFindAndReplace(cmds, CFSTR("{disk_container}"), disk_container_path, range, 0);

		CFDataRef cmds_data = CFStringCreateExternalRepresentation(NULL, cmds, kCFStringEncodingASCII, 0);
		FILE *out = fopen(PREP_CMDS_PATH, "w");
		fwrite(CFDataGetBytePtr(cmds_data), CFDataGetLength(cmds_data), 1, out);
		fclose(out);

		CFSafeRelease(cmds);
		CFSafeRelease(bundle_identifier);
		CFSafeRelease(device_app_url);
		CFSafeRelease(device_app_path);
		CFSafeRelease(disk_app_path);
		CFSafeRelease(device_container_url);
		CFSafeRelease(device_container_path);
		CFSafeRelease(dcp_noprivate);
		CFSafeRelease(disk_container_url);
		CFSafeRelease(disk_container_path);
		CFSafeRelease(cmds_data);

		signal(SIGHUP, exit);

		pid_t parent = getpid();
		int pid = fork();
		if (pid == 0) {
			system("xcrun -sdk iphoneos lldb /tmp/sdmmd-lldb-prep");
			kill(parent, SIGHUP);
			_exit(0);
		}
		CFRunLoopRun();
	}
}
Beispiel #16
0
static int vzevt_send_evt(vzevt_handle_t *h, vzevt_t *evt)
{
	DIR *dh;
	struct stat st;
	struct dirent *dp;
	struct sockaddr_un addr;
	int sock;

	if (!evt || (evt->size > EVT_MAX_MESSAGE_SIZE))
		return vzevt_err(VZEVT_ERR_INVAL,
				"evt_send: incorrect event size: %d",
				evt->size);
	// no listeners
	if (stat(g_evt_dir, &st) != 0)
		return 0;
	/* get registered unix sockets list from g_evt_dir directory... */
	dh = opendir(g_evt_dir);
	if (!dh)
		return vzevt_err(VZEVT_ERR_FATAL,
			"can't open directory %s", g_evt_dir);

	// Create socket
	if (h == NULL) {
		sock = socket(PF_UNIX, SOCK_DGRAM, 0);
		if (sock == -1)
			return vzevt_err(VZEVT_ERR_FATAL,
				"Can't create/open socket for send event: %s",
				strerror(errno));
	} else {
		sock = h->sock;
	}

	addr.sun_family = PF_UNIX;

	while ((dp = readdir(dh))) {
		if (strcmp(dp->d_name, "..") == 0 ||
		    strcmp(dp->d_name, ".") == 0)
				continue;
		if (h != NULL && strcmp(dp->d_name, h->sock_name) == 0)
			continue;

		snprintf(addr.sun_path,UNIX_PATH_MAX, "%s/%s",
			 g_evt_dir, dp->d_name);
		if (stat(addr.sun_path, &st) != -1 &&
			S_ISSOCK(st.st_mode))
		{
			if (sendto(sock, evt, sizeof(vzevt_t) + evt->size, 0,
				(struct sockaddr *)&addr, SUN_LEN(&addr)) == -1)
			{
				if (errno == ECONNREFUSED)
					// listener is dead
					unlink(addr.sun_path);
				else
					 vzevt_err(VZEVT_ERR_FATAL, "Can not send the event to '%s': %s",
						dp->d_name, strerror(errno));
			}
		}
	}

	if (h == NULL)
		close(sock);

	closedir(dh);
	return VZEVT_ERR_OK;
}
Beispiel #17
0
int  mi_init_datagram_server(sockaddr_dtgram *addr, unsigned int socket_domain, rx_tx_sockets * socks, int mode, int uid, int gid )
{
	char * socket_name;

	/* create sockets rx and tx ... */
	/***********************************/
	mi_socket_domain = socket_domain;
	/**********************************/

	socks->rx_sock = socket(socket_domain, SOCK_DGRAM, 0);
	if (socks->rx_sock == -1) {
		LM_ERR("cannot create RX socket: %s\n", strerror(errno));
		return -1;
	}

	switch(socket_domain)
	{
	case AF_LOCAL:
			LM_DBG("we have a unix socket: %s\n", addr->unix_addr.sun_path);
			socket_name = addr->unix_addr.sun_path;
			if(bind(socks->rx_sock,(struct sockaddr*)&addr->unix_addr, SUN_LEN(&addr->unix_addr))< 0) {
				LM_ERR("bind: %s\n", strerror(errno));
				goto err_rx;
			}
			if(mi_sock_check(socks->rx_sock, socket_name)!=0)
				goto err_rx;
			/* change permissions */
			if (mode){
				if (chmod(socket_name, mode)<0){
					LM_ERR("failed to change the permissions for %s to %04o:"
						"%s[%d]\n",socket_name, mode, strerror(errno), errno);
					goto err_rx;
				}
			}
			/* change ownership */
			if ((uid!=-1) || (gid!=-1)){
				if (chown(socket_name, uid, gid)<0){
					LM_ERR("failed to change the owner/group for %s  to %d.%d;"
					"%s[%d]\n",socket_name, uid, gid, strerror(errno), errno);
					goto err_rx;
				}
			}
			break;

	case AF_INET:
			if (bind(socks->rx_sock, &addr->udp_addr.s,
			sockaddru_len(addr->udp_addr))< 0) {
				LM_ERR("bind: %s\n", strerror(errno));
				goto err_rx;
			}
			break;
#ifdef USE_IPV6
	case AF_INET6: 
			if(bind(socks->rx_sock, (struct sockaddr*)&addr->udp_addr.sin6, sizeof(addr->udp_addr)) < 0) {
				LM_ERR("bind: %s\n", strerror(errno));
				goto err_rx;
			}
			break;
#endif
	default:
			LM_ERR("domain not supported\n");
			goto err_both;

	}
	mi_create_dtgram_replysocket(socks->tx_sock,socket_domain, err_both);

	return 0;
err_both:
	close(socks->tx_sock);
err_rx:
	close(socks->rx_sock);
	return -1;
}
Beispiel #18
0
static int open_sock(const char *sname)
{
	struct sockaddr_un addr;
	int s, res;

	if ((strlen(sname) + strlen(g_evt_dir) + 1) >= UNIX_PATH_MAX)
		return vzevt_err(VZEVT_ERR_FATAL, "Invalid sun_path: %s/%s",
				g_evt_dir, sname);

	res = create_evt_dir();
	if (res)
		return vzevt_err(VZEVT_ERR_FATAL,
				"Can't create directory %s: %s", g_evt_dir,
				strerror(errno));

	s = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (s == -1)
		return vzevt_err(VZEVT_ERR_FATAL,
				"can't create socket: %s",
				strerror(errno));

	addr.sun_family = PF_UNIX;
	snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", g_evt_dir, sname);
	res = bind(s, (struct sockaddr*)&addr, SUN_LEN(&addr));
	if (res == -1) {
		if (errno == EADDRINUSE) {
			unlink(sname);
			res = bind(s, (struct sockaddr *)&addr, SUN_LEN(&addr));
		}
	}
	if (res == -1) {
		vzevt_err(VZEVT_ERR_FATAL,
				"Failed to bind to socket %s: %s",
				sname, strerror(errno));
		goto err;
	}

	res = fcntl(s, F_GETFL);
	if (res >= 0)
		res = fcntl(s, F_SETFL, res | O_NONBLOCK);
	if (res == -1) {
		vzevt_err(VZEVT_ERR_FATAL,
				"Can't set socket to non-blocked mode: %s",
				strerror(errno));
		goto err;
	}

	res = fcntl(s, F_GETFD);
	if (res >= 0)
		res = fcntl(s, F_SETFD, res | FD_CLOEXEC);

	if (res == -1) {
		vzevt_err(VZEVT_ERR_FATAL,
				"Can't set FD_CLOEXEC: %s",
				strerror(errno));
		goto err;
	}

	return s;

err:
	close(s);
	return -1;
}
Beispiel #19
0
ret_t
cherokee_socket_connect (cherokee_socket_t *sock)
{
	int r;
	int err;

	TRACE (ENTRIES",connect", "connect type=%s\n",
	       SOCKET_AF(sock) == AF_INET  ? "AF_INET"  :
	       SOCKET_AF(sock) == AF_INET6 ? "AF_INET6" :
	       SOCKET_AF(sock) == AF_UNIX  ? "AF_UNIX"  : "Unknown");

	do {
		switch (SOCKET_AF(sock)) {
		case AF_INET:
			r = connect (SOCKET_FD(sock),
			             (struct sockaddr *) &SOCKET_ADDR(sock),
			             sizeof(struct sockaddr_in));
			break;
#ifdef HAVE_IPV6
		case AF_INET6:
			r = connect (SOCKET_FD(sock),
			             (struct sockaddr *) &SOCKET_ADDR(sock),
			             sizeof(struct sockaddr_in6));
			break;
#endif
#ifdef HAVE_SOCKADDR_UN
		case AF_UNIX:
			if (SOCKET_SUN_PATH (socket)[0] != 0) {
				r = connect (SOCKET_FD(sock),
				             (struct sockaddr *) &SOCKET_ADDR(sock),
				             SUN_LEN (SOCKET_ADDR_UNIX(sock)));
			}
			else {
				r = connect (SOCKET_FD(sock),
				             (struct sockaddr *) &SOCKET_ADDR(sock),
				             SUN_ABSTRACT_LEN (SOCKET_ADDR_UNIX(sock)));
			}
			break;
#endif
		default:
			SHOULDNT_HAPPEN;
			return ret_no_sys;
		}
	} while ((r == -1) && (errno == EINTR));

	if (r < 0) {
		err = SOCK_ERRNO();
		TRACE (ENTRIES",connect", "connect error=%d '%s'\n", err, strerror(err));

		switch (err) {
		case EISCONN:
			break;
		case EINVAL:
		case ENOENT:
		case ECONNRESET:
		case ECONNREFUSED:
		case EADDRNOTAVAIL:
			return ret_deny;
		case ETIMEDOUT:
			return ret_error;
		case EAGAIN:
		case EALREADY:
		case EINPROGRESS:
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
		case EWOULDBLOCK:
#endif
			return ret_eagain;
		default:
			LOG_ERRNO_S (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_CONNECT);
			return ret_error;
		}
	}

	TRACE (ENTRIES",connect", "succeed. fd=%d\n", SOCKET_FD(sock));

	sock->status = socket_reading;
	return ret_ok;
}
Beispiel #20
0
int main (int argc, char **argv)
#endif
{
  int test_fd, listen_fd, cli_fd;
  socklen_t  cliaddr_len;
  struct sockaddr_un test_addr, listen_addr, cli_addr;
  const int on = 1;
  int nbytes;
  struct ucred cli_cred;
  int ucred_len = sizeof(cli_cred);
  struct be_msg smsg, rmsg;
  struct stat listen_stat;

  openlog("pvc2684d",LOG_PERROR, LOG_DAEMON);

  bzero(group_head.name,MAX_GROUPNAME_LEN);
  group_head.head = NULL;
  group_head.next = NULL;

  bzero(&test_addr, sizeof(test_addr));
  test_addr.sun_family = AF_LOCAL;
  strncpy(test_addr.sun_path, BRPVC_SOCKPATH, sizeof(test_addr.sun_path) -1);
  memcpy(&listen_addr, &test_addr, sizeof(test_addr));

  if( (test_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) 
    do_error(LOG_ERR,"Couldn't create initial socket: %s",strerror(errno));

  /* Check for already running daemon  */

  if(connect(test_fd, (struct sockaddr *) &test_addr, sizeof(test_addr))) {
    if(errno == ECONNREFUSED)
      unlink(BRPVC_SOCKPATH);
  }
  close(test_fd);

  if( (listen_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
    do_error(LOG_ERR,"Couldn't create server socket: %s",strerror(errno));

  if( bind(listen_fd, (struct sockaddr *) &listen_addr, SUN_LEN(&listen_addr)) ) {
    do_error(LOG_WARNING,"Another b2684d is running");
    exit(-1);
  }
  
  
  if(stat(BRPVC_SOCKPATH, &listen_stat))
    do_error(LOG_ERR,"Can't fstat listen socket: %s",strerror(errno));

  if(chmod(BRPVC_SOCKPATH, listen_stat.st_mode | S_IWOTH))
    do_error(LOG_ERR,"Can't fchmod listen socket: %s",strerror(errno));

  if( listen(listen_fd, 5) )
    do_error(LOG_ERR,"listen() on server socket failed: %s",strerror(errno));
  
  while(1) {
    cliaddr_len = sizeof(cli_addr);
    if((cli_fd = accept(listen_fd, (struct sockaddr *) &cli_addr, &cliaddr_len)) < 0) {
      if(errno == EINTR)
	continue;
      else
	do_error(LOG_ERR,"accept() on server socket failed: %s",strerror(errno));
    }
    if( setsockopt(cli_fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0 )
      do_error(LOG_ERR,"setsockopt() on client socket failed: %s",strerror(errno));
    
    while((nbytes = recv(cli_fd, &rmsg, sizeof(rmsg), 0)) > 0) {
      switch (rmsg.msgtype) {
	
      case HELLO:
	
	if ( getsockopt(cli_fd, SOL_SOCKET, SO_PEERCRED, &cli_cred, &ucred_len) < 0 )
	  do_error(LOG_ERR,"getsockopt() for credentials failed: %s",strerror(errno));
	
	smsg.msgtype = OK;
	if( send(cli_fd, &smsg, sizeof(smsg), 0) < 0 )
	  do_error(LOG_ERR,"Couldn't send OK message to new client: %s",strerror(errno)); 

	break;
      
      case ADD:

	do_add(cli_fd,&rmsg,&cli_cred);
	break;
      
      case DELETE:

	do_delete(cli_fd,&rmsg,&cli_cred);
	break;
      
      case DELETE_GROUP:

	do_delete_group(cli_fd,rmsg.name,&cli_cred);
	break;
      
      case LIST_GROUP:
	 
	do_list_group(cli_fd,&rmsg);
	break;
      
      case LIST_ALL:

	do_list_all(cli_fd,&rmsg);
	break;

      case MEM_STATS:
	
	if( send(cli_fd, &memstat, sizeof(memstat), 0) < 0 )
	  do_error(LOG_ERR,"Couldn't send MEM_STAT message: %s",strerror(errno)); 
	break;
      
      default:
	smsg.msgtype = UNKNOWN_CMD;
	if( send(cli_fd, &smsg, sizeof(smsg), 0) < 0 )
	  do_error(LOG_ERR,"Couldn't send UNKNOWN_COMMAND message: %s",strerror(errno)); 
      }
    }
    close(cli_fd);
  }
}
Beispiel #21
0
static int fr_domain_socket(char const *path)
{
	int sockfd = -1;
#ifdef HAVE_SYS_UN_H
	size_t len;
	socklen_t socklen;
	struct sockaddr_un saremote;

	len = strlen(path);
	if (len >= sizeof(saremote.sun_path)) {
		fprintf(stderr, "%s: Path too long in filename\n", progname);
		return -1;
	}

	if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
		fprintf(stderr, "%s: Failed creating socket: %s\n",
			progname, strerror(errno));
		return -1;
	}

	saremote.sun_family = AF_UNIX;
	memcpy(saremote.sun_path, path, len + 1); /* SUN_LEN does strlen */
	
	socklen = SUN_LEN(&saremote);

	if (connect(sockfd, (struct sockaddr *)&saremote, socklen) < 0) {
		struct stat buf;

		close(sockfd);
		fprintf(stderr, "%s: Failed connecting to %s: %s\n",
			progname, path, strerror(errno));

		/*
		 *	The file doesn't exist.  Tell the user how to
		 *	fix it.
		 */
		if ((stat(path, &buf) < 0) &&
		    (errno == ENOENT)) {
			fprintf(stderr, "  Perhaps you need to run the commands:\n\tcd /etc/raddb\n\tln -s sites-available/control-socket sites-enabled/control-socket\n  and then re-start the server?\n");
		}

		return -1;
	}

#ifdef O_NONBLOCK
	{
		int flags;
		
		if ((flags = fcntl(sockfd, F_GETFL, NULL)) < 0)  {
			fprintf(stderr, "%s: Failure getting socket flags: %s",
				progname, strerror(errno));
			close(sockfd);
			return -1;
		}
		
		flags |= O_NONBLOCK;
		if( fcntl(sockfd, F_SETFL, flags) < 0) {
			fprintf(stderr, "%s: Failure setting socket flags: %s",
				progname, strerror(errno));
			close(sockfd);
			return -1;
		}
	}
#endif
#endif
	return sockfd;
}
Beispiel #22
0
isc_result_t isc_entropy_createfilesource (isc_entropy_t * ent, const char *fname)
{
    int fd;

    struct stat _stat;

    isc_boolean_t is_usocket = ISC_FALSE;

    isc_boolean_t is_connected = ISC_FALSE;

    isc_result_t ret;

    isc_entropysource_t *source;

    REQUIRE (VALID_ENTROPY (ent));
    REQUIRE (fname != NULL);

    LOCK (&ent->lock);

    if (stat (fname, &_stat) < 0)
    {
        ret = isc__errno2result (errno);
        goto errout;
    }
    /*
     * Solaris 2.5.1 does not have support for sockets (S_IFSOCK),
     * but it does return type S_IFIFO (the OS believes that
     * the socket is a fifo).  This may be an issue if we tell
     * the program to look at an actual FIFO as its source of
     * entropy.
     */
#if defined(S_ISSOCK)
    if (S_ISSOCK (_stat.st_mode))
        is_usocket = ISC_TRUE;
#endif
#if defined(S_ISFIFO) && defined(sun)
    if (S_ISFIFO (_stat.st_mode))
        is_usocket = ISC_TRUE;
#endif
    if (is_usocket)
        fd = socket (PF_UNIX, SOCK_STREAM, 0);
    else
        fd = open (fname, O_RDONLY | PORT_NONBLOCK, 0);

    if (fd < 0)
    {
        ret = isc__errno2result (errno);
        goto errout;
    }

    ret = make_nonblock (fd);
    if (ret != ISC_R_SUCCESS)
        goto closefd;

    if (is_usocket)
    {
        struct sockaddr_un sname;

        memset (&sname, 0, sizeof (sname));
        sname.sun_family = AF_UNIX;
        strncpy (sname.sun_path, fname, sizeof (sname.sun_path));
        sname.sun_path[sizeof (sname.sun_path) - 1] = '0';
#ifdef ISC_PLATFORM_HAVESALEN
#if !defined(SUN_LEN)
#define SUN_LEN(su) \
    (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif
        sname.sun_len = SUN_LEN (&sname);
#endif

        if (connect (fd, (struct sockaddr *) &sname, sizeof (struct sockaddr_un)) < 0)
        {
            if (errno != EINPROGRESS)
            {
                ret = isc__errno2result (errno);
                goto closefd;
            }
        }
        else
            is_connected = ISC_TRUE;
    }

    source = isc_mem_get (ent->mctx, sizeof (isc_entropysource_t));
    if (source == NULL)
    {
        ret = ISC_R_NOMEMORY;
        goto closefd;
    }

    /*
     * From here down, no failures can occur.
     */
    source->magic = SOURCE_MAGIC;
    source->ent = ent;
    source->total = 0;
    source->bad = ISC_FALSE;
    memset (source->name, 0, sizeof (source->name));
    ISC_LINK_INIT (source, link);
    if (is_usocket)
    {
        source->sources.usocket.handle = fd;
        if (is_connected)
            source->sources.usocket.status = isc_usocketsource_connected;
        else
            source->sources.usocket.status = isc_usocketsource_connecting;
        source->sources.usocket.sz_to_recv = 0;
        source->type = ENTROPY_SOURCETYPE_USOCKET;
    }
    else
    {
        source->sources.file.handle = fd;
        source->type = ENTROPY_SOURCETYPE_FILE;
    }

    /*
     * Hook it into the entropy system.
     */
    ISC_LIST_APPEND (ent->sources, source, link);
    ent->nsources++;

    UNLOCK (&ent->lock);
    return (ISC_R_SUCCESS);

  closefd:
    (void) close (fd);

  errout:
    UNLOCK (&ent->lock);

    return (ret);
}
Beispiel #23
0
BOOL DLLCALL xpms_add(struct xpms_set *xpms_set, int domain, int type,
	int protocol, const char *addr, uint16_t port, const char *prot, 
	void (*sock_init)(SOCKET, void *), int(*bind_init)(BOOL), void *cbdata)
{
	struct xpms_sockdef	*new_socks;
    struct addrinfo		hints;
    struct addrinfo		*res=NULL;
    struct addrinfo		*cur;
    unsigned int		added = 0;
    int					ret;
    char				port_str[6];

#ifndef _WIN32
	struct addrinfo		dummy;
	struct sockaddr_un	un_addr;

	if(domain == AF_UNIX) {
		memset(&dummy, 0, sizeof(dummy));
		dummy.ai_family = AF_UNIX;
		dummy.ai_socktype = type;
		dummy.ai_addr = (struct sockaddr *)&un_addr;
		un_addr.sun_family=AF_UNIX;

		if(strlen(addr) >= sizeof(un_addr.sun_path)) {
			if(xpms_set->lprintf)
				xpms_set->lprintf(LOG_ERR, "!ERROR %s is too long for a portable AF_UNIX socket", addr);
			return FALSE;
		}
		strcpy(un_addr.sun_path,addr);
		if(fexist(addr))
			unlink(addr);
		dummy.ai_addrlen = sizeof(un_addr);
		un_addr.sun_len=SUN_LEN(&un_addr);
		res = &dummy;
	}
#endif
	if(res == NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_flags=AI_PASSIVE;
		hints.ai_family=domain;
		hints.ai_socktype=type;
		hints.ai_protocol=protocol;
		hints.ai_flags|=AI_NUMERICSERV;
#ifdef AI_ADDRCONFIG
		hints.ai_flags|=AI_ADDRCONFIG;
#endif
		sprintf(port_str, "%hu", port);
		if((ret=getaddrinfo(addr, port_str, &hints, &res))!=0) {
			if(xpms_set->lprintf)
				xpms_set->lprintf(LOG_CRIT, "!ERROR %d calling getaddrinfo() on %s", ret, addr);
			return FALSE;
		}
	}

	for(cur=res; cur; cur=cur->ai_next) {
		new_socks=(struct xpms_sockdef *)realloc(xpms_set->socks, sizeof(struct xpms_sockdef)*(xpms_set->sock_count+1));
		if(new_socks==NULL) {
			/* This may be a partial failure */
			if(xpms_set->lprintf)
				xpms_set->lprintf(LOG_CRIT, "!ERROR out of memory adding to multisocket");
			break;
		}
		xpms_set->socks=new_socks;
		xpms_set->socks[xpms_set->sock_count].address = strdup(addr);
		xpms_set->socks[xpms_set->sock_count].cb_data = cbdata;
		xpms_set->socks[xpms_set->sock_count].domain = cur->ai_family;	/* Address/Protocol Family */
		xpms_set->socks[xpms_set->sock_count].type = cur->ai_socktype;
		xpms_set->socks[xpms_set->sock_count].protocol = protocol;
		xpms_set->socks[xpms_set->sock_count].port = port;
		xpms_set->socks[xpms_set->sock_count].prot = strdup(prot);
		xpms_set->socks[xpms_set->sock_count].sock = socket(cur->ai_family, cur->ai_socktype, protocol);
		if(xpms_set->socks[xpms_set->sock_count].sock == INVALID_SOCKET) {
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
			continue;
		}
		if(sock_init)
			sock_init(xpms_set->socks[xpms_set->sock_count].sock, cbdata);

		if(bind_init) {
			if(port < IPPORT_RESERVED && port > 0)
				bind_init(FALSE);
		}
		if(retry_bind(xpms_set->socks[xpms_set->sock_count].sock, cur->ai_addr, cur->ai_addrlen, xpms_set->retries, xpms_set->wait_secs, prot, xpms_set->lprintf)==-1) {
			closesocket(xpms_set->socks[xpms_set->sock_count].sock);
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
			if(bind_init) {
				if(port < IPPORT_RESERVED)
					bind_init(TRUE);
			}
			continue;
		}
		if(bind_init) {
			if(port < IPPORT_RESERVED && port > 0)
				bind_init(TRUE);
		}

		if(type != SOCK_DGRAM) {
			if(listen(xpms_set->socks[xpms_set->sock_count].sock, SOMAXCONN)==-1) {
				if(xpms_set->lprintf)
					xpms_set->lprintf(LOG_WARNING, "%04d !ERROR %d listen()ing on port %d"
							, xpms_set->socks[xpms_set->sock_count].sock, ERROR_VALUE, port);
				closesocket(xpms_set->socks[xpms_set->sock_count].sock);
				FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
				FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
				continue;
			}
		}

		added++;
		xpms_set->sock_count++;
	}

#ifndef _WIN32
	if(res != &dummy)
#endif
		freeaddrinfo(res);
	if(added)
		return TRUE;
	return FALSE;
}
Beispiel #24
0
NB_Blackadder::NB_Blackadder(bool user_space) {
    int ret;
    (void) signal(SIGINT, signal_handler);
    if (user_space) {
        cout << "NB_Blackadder Library: Initializing blackadder client for user space" << endl;
#if HAVE_USE_NETLINK
        sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
#else
        sock_fd = socket(PF_LOCAL, SOCK_DGRAM, 0);
#endif
    } else {
        cout << "NB_Blackadder Library: Initializing blackadder client for kernel space" << endl;
#if HAVE_USE_NETLINK
        sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_BADDER);
#else	
        sock_fd = -1;
        errno = EPFNOSUPPORT; /* XXX */
#endif
    }
    if (sock_fd < 0) {
        perror("NB_Blackadder Library: socket");
    } else {
        cout << "NB_Blackadder Library: Created and opened netlink socket" << endl;
    }
    int x;
    x = fcntl(sock_fd, F_GETFL, 0);
    fcntl(sock_fd, F_SETFL, x | O_NONBLOCK);
    /* source address */
    memset(&s_nladdr, 0, sizeof (s_nladdr));
#if HAVE_USE_NETLINK
    s_nladdr.nl_family = AF_NETLINK;
    s_nladdr.nl_pad = 0;
    s_nladdr.nl_pid = getpid();
    ret = bind(sock_fd, (struct sockaddr *) &s_nladdr, sizeof (s_nladdr));
#else
    s_nladdr.sun_len = sizeof (s_nladdr);
    s_nladdr.sun_family = PF_LOCAL;
    /* XXX: Probably shouldn't use getpid() here. */
    ba_id2path(s_nladdr.sun_path, getpid());
    if (unlink(s_nladdr.sun_path) != 0 && errno != ENOENT)
        perror("unlink");
    ret = bind(sock_fd, (struct sockaddr *) &s_nladdr, SUN_LEN(&s_nladdr));
#endif
    if (ret < 0) {
        perror("NB_Blackadder Library: bind");
    }
    /* destination address */
    memset(&d_nladdr, 0, sizeof (d_nladdr));
#if HAVE_USE_NETLINK
    d_nladdr.nl_family = AF_NETLINK;
    d_nladdr.nl_pad = 0;
    if (user_space) {
        d_nladdr.nl_pid = 9999; /* destined to user space blackadder */
    } else {
        d_nladdr.nl_pid = 0; /* destined to kernel */
    }
#else
    d_nladdr.sun_len = sizeof (d_nladdr);
    d_nladdr.sun_family = PF_LOCAL;
    ba_id2path(d_nladdr.sun_path, (user_space) ? 9999 : 0); /* XXX */
#endif
    /*initialize pipes*/
    if (pipe(pipe_fds) != 0) {
        perror("pipe");
        /* XXX: Should we raise an exception or something? */
    }
    FD_ZERO(&read_set);
    FD_SET(sock_fd, &read_set);
    FD_SET(pipe_fds[0], &read_set);
    /*register default callback method*/
    cf = &defaultCallback;
    pthread_mutex_init(&selector_mutex, NULL);
    pthread_mutex_init(&worker_mutex, NULL);
    pthread_cond_init(&queue_overflow_cond, NULL);
    pthread_cond_init(&worker_cond, NULL);
    pthread_create(&selector_thread, NULL, selector, NULL);
    pthread_create(&worker_thread, NULL, worker, NULL);
}
Beispiel #25
0
static int unix_bind(COMSTACK h, void *address, int mode)
{
    unix_state *sp = (unix_state *)h->cprivate;
    struct sockaddr *addr = (struct sockaddr *)address;
    const char * path = ((struct sockaddr_un *)addr)->sun_path;
    struct stat stat_buf;

    TRC (fprintf (stderr, "unix_bind\n"));

    if(stat(path, &stat_buf) != -1) {
        struct sockaddr_un socket_unix;
        int socket_out = -1;

        if((stat_buf.st_mode&S_IFMT) != S_IFSOCK) { /* used to be S_ISSOCK */
            h->cerrno = CSYSERR;
            yaz_set_errno(EEXIST); /* Not a socket (File exists) */
            return -1;
        }
        if((socket_out = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
            h->cerrno = CSYSERR;
            return -1;
        }
        socket_unix.sun_family = AF_UNIX;
        strncpy(socket_unix.sun_path, path, sizeof(socket_unix.sun_path)-1);
        socket_unix.sun_path[sizeof(socket_unix.sun_path)-1] = 0;
        if(connect(socket_out, (struct sockaddr *) &socket_unix, SUN_LEN(&socket_unix)) < 0) {
            if(yaz_errno() == ECONNREFUSED) {
                TRC (fprintf (stderr, "Socket exists but nobody is listening\n"));
            } else {
                h->cerrno = CSYSERR;
                return -1;
            }
        } else {
            close(socket_out);
            h->cerrno = CSYSERR;
            yaz_set_errno(EADDRINUSE);
            return -1;
        }
        unlink(path);
    }

    if (bind(h->iofile, (struct sockaddr *) addr, SUN_LEN((struct sockaddr_un *)addr)))
    {
        h->cerrno = CSYSERR;
        return -1;
    }
    if (chown(path, sp->uid, sp->gid))
    {
        h->cerrno = CSYSERR;
        return -1;
    }
    if (chmod(path, sp->umask != -1 ? sp->umask : 0666))
    {
        h->cerrno = CSYSERR;
        return -1;
    }
    if (mode == CS_SERVER && listen(h->iofile, 100) < 0)
    {
        h->cerrno = CSYSERR;
        return -1;
    }
    h->state = CS_ST_IDLE;
    h->event = CS_LISTEN;
    return 0;
}
Beispiel #26
0
int main( int i_argc, char **ppsz_argv )
{
    char *client_socket_tmpl = "dvblastctl.clientsock.XXXXXX";
    char *psz_srv_socket = NULL;
    int i;
    char *p_cmd, *p_arg1 = NULL, *p_arg2 = NULL;
    ssize_t i_size;
    struct sockaddr_un sun_client, sun_server;
    uint8_t p_buffer[COMM_BUFFER_SIZE];
    uint8_t *p_data = p_buffer + COMM_HEADER_SIZE;
    uint16_t i_pid = 0;
    struct dvblastctl_option opt = { 0, 0, 0 };

    for ( ; ; )
    {
        int c;

        static const struct option long_options[] =
        {
            {"remote-socket", required_argument, NULL, 'r'},
            {"print", required_argument, NULL, 'x'},
            {"help", no_argument, NULL, 'h'},
            {0, 0, 0, 0}
        };

        if ( (c = getopt_long(i_argc, ppsz_argv, "r:x:h", long_options, NULL)) == -1 )
            break;

        switch ( c )
        {
        case 'r':
            psz_srv_socket = optarg;
            break;

        case 'x':
            if ( !strcmp(optarg, "text") )
                i_print_type = PRINT_TEXT;
            else if ( !strcmp(optarg, "xml") )
                i_print_type = PRINT_XML;
            else
                msg_Warn( NULL, "unrecognized print type %s", optarg );
            /* Make stdout line-buffered */
            setvbuf(stdout, NULL, _IOLBF, 0);
            break;

        case 'h':
        default:
            usage();
        }
    }

    /* Validate commands */
#define usage_error(msg, ...) \
        do { \
            msg_Err( NULL, msg, ##__VA_ARGS__ ); \
            usage(); \
        } while(0)
    p_cmd  = ppsz_argv[optind];
    p_arg1 = ppsz_argv[optind + 1];
    p_arg2 = ppsz_argv[optind + 2];

    if ( !psz_srv_socket )
        usage_error( "Remote socket is not set.\n" );

    if ( !p_cmd )
       usage_error( "Command is not set.\n" );

    i = 0;
    do {
        if ( streq(ppsz_argv[optind], options[i].opt) )
        {
            opt = options[i];
            break;
        }
    } while ( options[++i].opt );

    if ( !opt.opt )
        usage_error( "Unknown command: %s\n", p_cmd );

    if ( opt.nparams == 1 && !p_arg1 )
        usage_error( "%s option needs parameter.\n", opt.opt );

    if ( opt.nparams == 2 && (!p_arg1 || !p_arg2) )
        usage_error( "%s option needs two parameters.\n", opt.opt );
#undef usage_error

    /* Create client socket name */
    char *tmpdir = getenv("TMPDIR");
    snprintf( psz_client_socket, PATH_MAX - 1, "%s/%s",
       tmpdir ? tmpdir : "/tmp", client_socket_tmpl );
    psz_client_socket[PATH_MAX - 1] = '\0';

    int tmp_fd = mkstemp(psz_client_socket);
    if ( tmp_fd > -1 ) {
        close(tmp_fd);
        unlink(psz_client_socket);
    } else {
        return_error( "Cannot build UNIX socket %s (%s)", psz_client_socket, strerror(errno) );
    }

    if ( (i_fd = socket( AF_UNIX, SOCK_DGRAM, 0 )) < 0 )
        return_error( "Cannot create UNIX socket (%s)", strerror(errno) );

    i = COMM_MAX_MSG_CHUNK;
    setsockopt( i_fd, SOL_SOCKET, SO_RCVBUF, &i, sizeof(i) );

    memset( &sun_client, 0, sizeof(sun_client) );
    sun_client.sun_family = AF_UNIX;
    strncpy( sun_client.sun_path, psz_client_socket,
             sizeof(sun_client.sun_path) );
    sun_client.sun_path[sizeof(sun_client.sun_path) - 1] = '\0';

    if ( bind( i_fd, (struct sockaddr *)&sun_client,
               SUN_LEN(&sun_client) ) < 0 )
        return_error( "Cannot bind (%s)", strerror(errno) );

    memset( &sun_server, 0, sizeof(sun_server) );
    sun_server.sun_family = AF_UNIX;
    strncpy( sun_server.sun_path, psz_srv_socket, sizeof(sun_server.sun_path) );
    sun_server.sun_path[sizeof(sun_server.sun_path) - 1] = '\0';

    p_buffer[0] = COMM_HEADER_MAGIC;
    p_buffer[1] = opt.cmd;
    memset( p_buffer + 2, 0, COMM_HEADER_SIZE - 2 );
    i_size = COMM_HEADER_SIZE;

    /* Handle commands that send parameters */
    switch ( opt.cmd )
    {
    case CMD_INVALID:
    case CMD_RELOAD:
    case CMD_SHUTDOWN:
    case CMD_FRONTEND_STATUS:
    case CMD_MMI_STATUS:
    case CMD_GET_PAT:
    case CMD_GET_CAT:
    case CMD_GET_NIT:
    case CMD_GET_SDT:
    case CMD_GET_PIDS:
        /* These commands need no special handling because they have no parameters */
        break;
    case CMD_GET_PMT:
    {
        uint16_t i_sid = atoi(p_arg1);
        i_size = COMM_HEADER_SIZE + 2;
        p_data[0] = (uint8_t)((i_sid >> 8) & 0xff);
        p_data[1] = (uint8_t)(i_sid & 0xff);
        break;
    }
    case CMD_GET_PID:
    {
        i_pid = (uint16_t)atoi(p_arg1);
        i_size = COMM_HEADER_SIZE + 2;
        p_data[0] = (uint8_t)((i_pid >> 8) & 0xff);
        p_data[1] = (uint8_t)(i_pid & 0xff);
        break;
    }
    case CMD_MMI_SEND_TEXT:
    {
        struct cmd_mmi_send *p_cmd = (struct cmd_mmi_send *)p_data;
        p_cmd->i_slot = atoi(p_arg1);

        en50221_mmi_object_t object;
        object.i_object_type = EN50221_MMI_ANSW;
        if ( !p_arg2 || p_arg2[0] == '\0' )
        {
             object.u.answ.b_ok = 0;
             object.u.answ.psz_answ = "";
        }
        else
        {
             object.u.answ.b_ok = 1;
             object.u.answ.psz_answ = p_arg2;
        }
        i_size = COMM_BUFFER_SIZE - COMM_HEADER_SIZE
                  - ((void *)&p_cmd->object - (void *)p_cmd);
        if ( en50221_SerializeMMIObject( (uint8_t *)&p_cmd->object,
                                         &i_size, &object ) == -1 )
            return_error( "Comm buffer is too small" );

        i_size += COMM_HEADER_SIZE
                   + ((void *)&p_cmd->object - (void *)p_cmd);
        break;
    }
    case CMD_MMI_SEND_CHOICE:
    {
        struct cmd_mmi_send *p_cmd = (struct cmd_mmi_send *)p_data;
        p_cmd->i_slot = atoi(p_arg1);

        i_size = COMM_HEADER_SIZE + sizeof(struct cmd_mmi_send);
        p_cmd->object.i_object_type = EN50221_MMI_MENU_ANSW;
        p_cmd->object.u.menu_answ.i_choice = atoi(p_arg2);
        break;
    }
    case CMD_MMI_SLOT_STATUS:
    case CMD_MMI_OPEN:
    case CMD_MMI_CLOSE:
    case CMD_MMI_RECV:
    {
        p_data[0] = atoi(p_arg1);
        i_size = COMM_HEADER_SIZE + 1;
        break;
    }
    default:
        /* This should not happen */
        return_error( "Unhandled option (%d)", opt.cmd );
    }

    /* Send command and receive answer */
    if ( sendto( i_fd, p_buffer, i_size, 0, (struct sockaddr *)&sun_server,
                 SUN_LEN(&sun_server) ) < 0 )
        return_error( "Cannot send comm socket (%s)", strerror(errno) );

    uint32_t i_packet_size = 0, i_received = 0;
    do {
        i_size = recv( i_fd, p_buffer + i_received, COMM_MAX_MSG_CHUNK, 0 );
        if ( i_size == -1 )
            break;
        if ( !i_packet_size ) {
            i_packet_size = *((uint32_t *)&p_buffer[4]);
            if ( i_packet_size > COMM_BUFFER_SIZE ) {
                i_size = -1;
                break;
            }
        }
        i_received += i_size;
    } while ( i_received < i_packet_size );

    clean_client_socket();
    if ( i_size < COMM_HEADER_SIZE )
        return_error( "Cannot recv from comm socket, size:%zd (%s)", i_size, strerror(errno) );

    /* Process answer */
    if ( p_buffer[0] != COMM_HEADER_MAGIC )
        return_error( "Wrong protocol version 0x%x", p_buffer[0] );

    now = mdate();

    ctl_cmd_answer_t c_answer = p_buffer[1];
    switch ( c_answer )
    {
    case RET_OK:
        break;

    case RET_MMI_WAIT:
        exit(252);
        break;

    case RET_ERR:
        return_error( "Request failed" );
        break;

    case RET_HUH:
        return_error( "Internal error" );
        break;

    case RET_NODATA:
        return_error( "No data" );
        break;

    case RET_PAT:
    case RET_CAT:
    case RET_NIT:
    case RET_SDT:
    {
        uint8_t *p_flat_data = p_buffer + COMM_HEADER_SIZE;
        unsigned int i_flat_data_size = i_size - COMM_HEADER_SIZE;
        uint8_t **pp_sections = psi_unpack_sections( p_flat_data, i_flat_data_size );

        switch( c_answer )
        {
            case RET_PAT: pat_table_print( pp_sections, psi_print, NULL, i_print_type ); break;
            case RET_CAT: cat_table_print( pp_sections, psi_print, NULL, i_print_type ); break;
            case RET_NIT: nit_table_print( pp_sections, psi_print, NULL, psi_iconv, NULL, i_print_type ); break;
            case RET_SDT: sdt_table_print( pp_sections, psi_print, NULL, psi_iconv, NULL, i_print_type ); break;
            default: break; /* Can't happen */
        }

        psi_table_free( pp_sections );
        free( pp_sections );
        break;
    }

    case RET_PMT:
    {
        pmt_print( p_data, psi_print, NULL, psi_iconv, NULL, i_print_type );
        break;
    }

    case RET_PID:
    {
        print_pids_header();
        print_pid( i_pid, (ts_pid_info_t *)p_data );
        print_pids_footer();
        break;
    }

    case RET_PIDS:
    {
        print_pids( p_data );
        break;
    }

    case RET_FRONTEND_STATUS:
    {
        int ret = 1;
        struct ret_frontend_status *p_ret =
            (struct ret_frontend_status *)&p_buffer[COMM_HEADER_SIZE];
        if ( i_size != COMM_HEADER_SIZE + sizeof(struct ret_frontend_status) )
            return_error( "Bad frontend status" );

        if ( i_print_type == PRINT_XML )
            printf("<FRONTEND>\n");

#define PRINT_TYPE( x ) \
    do { \
        if ( i_print_type == PRINT_XML ) \
            printf( " <TYPE type=\"%s\"/>\n", STRINGIFY(x) ); \
        else \
            printf( "type: %s\n", STRINGIFY(x) ); \
    } while(0)
        switch ( p_ret->info.type )
        {
        case FE_QPSK: PRINT_TYPE(QPSK); break;
        case FE_QAM : PRINT_TYPE(QAM); break;
        case FE_OFDM: PRINT_TYPE(OFDM); break;
        case FE_ATSC: PRINT_TYPE(ATSC); break;
        default     : PRINT_TYPE(UNKNOWN); break;
        }
#undef PRINT_TYPE

#define PRINT_INFO( x ) \
    do { \
        if ( i_print_type == PRINT_XML ) \
            printf( " <SETTING %s=\"%u\"/>\n", STRINGIFY(x), p_ret->info.x ); \
        else \
            printf( "%s: %u\n", STRINGIFY(x), p_ret->info.x ); \
    } while(0)
        PRINT_INFO( frequency_min );
        PRINT_INFO( frequency_max );
        PRINT_INFO( frequency_stepsize );
        PRINT_INFO( frequency_tolerance );
        PRINT_INFO( symbol_rate_min );
        PRINT_INFO( symbol_rate_max );
        PRINT_INFO( symbol_rate_tolerance );
        PRINT_INFO( notifier_delay );
#undef PRINT_INFO

        if ( i_print_type == PRINT_TEXT )
            printf("\ncapability list:\n");

#define PRINT_CAPS( x ) \
    do { \
        if ( p_ret->info.caps & (FE_##x) ) { \
            if ( i_print_type == PRINT_XML ) { \
                printf( " <CAPABILITY %s=\"1\"/>\n", STRINGIFY(x) ); \
            } else { \
                printf( "%s\n", STRINGIFY(x) ); \
            } \
        } \
    } while(0)
        PRINT_CAPS( IS_STUPID );
        PRINT_CAPS( CAN_INVERSION_AUTO );
        PRINT_CAPS( CAN_FEC_1_2 );
        PRINT_CAPS( CAN_FEC_2_3 );
        PRINT_CAPS( CAN_FEC_3_4 );
        PRINT_CAPS( CAN_FEC_4_5 );
        PRINT_CAPS( CAN_FEC_5_6 );
        PRINT_CAPS( CAN_FEC_6_7 );
        PRINT_CAPS( CAN_FEC_7_8 );
        PRINT_CAPS( CAN_FEC_8_9 );
        PRINT_CAPS( CAN_FEC_AUTO );
        PRINT_CAPS( CAN_QPSK );
        PRINT_CAPS( CAN_QAM_16 );
        PRINT_CAPS( CAN_QAM_32 );
        PRINT_CAPS( CAN_QAM_64 );
        PRINT_CAPS( CAN_QAM_128 );
        PRINT_CAPS( CAN_QAM_256 );
        PRINT_CAPS( CAN_QAM_AUTO );
        PRINT_CAPS( CAN_TRANSMISSION_MODE_AUTO );
        PRINT_CAPS( CAN_BANDWIDTH_AUTO );
        PRINT_CAPS( CAN_GUARD_INTERVAL_AUTO );
        PRINT_CAPS( CAN_HIERARCHY_AUTO );
        PRINT_CAPS( CAN_MUTE_TS );

#define DVBAPI_VERSION ((DVB_API_VERSION)*100+(DVB_API_VERSION_MINOR))

#if DVBAPI_VERSION >= 301
        PRINT_CAPS( CAN_8VSB );
        PRINT_CAPS( CAN_16VSB );
        PRINT_CAPS( NEEDS_BENDING );
        PRINT_CAPS( CAN_RECOVER );
#endif
#if DVBAPI_VERSION >= 500
        PRINT_CAPS( HAS_EXTENDED_CAPS );
#endif
#if DVBAPI_VERSION >= 501
        PRINT_CAPS( CAN_2G_MODULATION );
#endif
#undef PRINT_CAPS

        if ( i_print_type == PRINT_TEXT )
            printf("\nstatus:\n");

#define PRINT_STATUS( x ) \
    do { \
        if ( p_ret->i_status & (FE_##x) ) { \
            if ( i_print_type == PRINT_XML ) { \
                printf( " <STATUS status=\"%s\"/>\n", STRINGIFY(x) ); \
            } else { \
                printf( "%s\n", STRINGIFY(x) ); \
            } \
        } \
    } while(0)
        PRINT_STATUS( HAS_SIGNAL );
        PRINT_STATUS( HAS_CARRIER );
        PRINT_STATUS( HAS_VITERBI );
        PRINT_STATUS( HAS_SYNC );
        PRINT_STATUS( HAS_LOCK );
        PRINT_STATUS( REINIT );
#undef PRINT_STATUS

        if ( p_ret->i_status & FE_HAS_LOCK )
        {
            if ( i_print_type == PRINT_XML )
            {
                printf(" <VALUE bit_error_rate=\"%d\"/>\n", p_ret->i_ber);
                printf(" <VALUE signal_strength=\"%d\"/>\n", p_ret->i_strength);
                printf(" <VALUE SNR=\"%d\"/>\n", p_ret->i_snr);
            } else {
                printf("\nBit error rate: %d\n", p_ret->i_ber);
                printf("Signal strength: %d\n", p_ret->i_strength);
                printf("SNR: %d\n", p_ret->i_snr);
            }
            ret = 0;
        }

        if ( i_print_type == PRINT_XML )
            printf("</FRONTEND>\n" );

        exit(ret);
        break;
    }

    case RET_MMI_STATUS:
    {
        struct ret_mmi_status *p_ret =
            (struct ret_mmi_status *)&p_buffer[COMM_HEADER_SIZE];
        if ( i_size != COMM_HEADER_SIZE + sizeof(struct ret_mmi_status) )
            return_error( "Bad MMI status" );

        printf("CA interface with %d %s, type:\n", p_ret->caps.slot_num,
               p_ret->caps.slot_num == 1 ? "slot" : "slots");
#define PRINT_CAPS( x, s )                                              \
        if ( p_ret->caps.slot_type & (CA_##x) )                         \
            printf(s "\n");
        PRINT_CAPS( CI, "CI high level interface" );
        PRINT_CAPS( CI_LINK, "CI link layer level interface" );
        PRINT_CAPS( CI_PHYS, "CI physical layer level interface (not supported)" );
        PRINT_CAPS( DESCR, "built-in descrambler" );
        PRINT_CAPS( SC, "simple smartcard interface" );
#undef PRINT_CAPS

        printf("\n%d available %s\n", p_ret->caps.descr_num,
            p_ret->caps.descr_num == 1 ? "descrambler (key)" :
                                         "descramblers (keys)");
#define PRINT_DESC( x )                                                 \
        if ( p_ret->caps.descr_type & (CA_##x) )                        \
            printf( STRINGIFY(x) "\n" );
        PRINT_DESC( ECD );
        PRINT_DESC( NDS );
        PRINT_DESC( DSS );
#undef PRINT_DESC

        exit( p_ret->caps.slot_num );
        break;
    }

    case RET_MMI_SLOT_STATUS:
    {
        struct ret_mmi_slot_status *p_ret =
            (struct ret_mmi_slot_status *)&p_buffer[COMM_HEADER_SIZE];
        if ( i_size < COMM_HEADER_SIZE + sizeof(struct ret_mmi_slot_status) )
            return_error( "Bad MMI slot status" );

        printf("CA slot #%u: ", p_ret->sinfo.num);

#define PRINT_TYPE( x, s )                                                  \
        if ( p_ret->sinfo.type & (CA_##x) )                                 \
            printf(s);

        PRINT_TYPE( CI, "high level, " );
        PRINT_TYPE( CI_LINK, "link layer level, " );
        PRINT_TYPE( CI_PHYS, "physical layer level, " );
#undef PRINT_TYPE

        if ( p_ret->sinfo.flags & CA_CI_MODULE_READY )
        {
            printf("module present and ready\n");
            exit(0);
        }

        if ( p_ret->sinfo.flags & CA_CI_MODULE_PRESENT )
            printf("module present, not ready\n");
        else
            printf("module not present\n");

        exit(1);
        break;
    }

    case RET_MMI_RECV:
    {
        struct ret_mmi_recv *p_ret =
            (struct ret_mmi_recv *)&p_buffer[COMM_HEADER_SIZE];
        if ( i_size < COMM_HEADER_SIZE + sizeof(struct ret_mmi_recv) )
            return_error( "Bad MMI recv" );

        en50221_UnserializeMMIObject( &p_ret->object, i_size
          - COMM_HEADER_SIZE - ((void *)&p_ret->object - (void *)p_ret) );

        switch ( p_ret->object.i_object_type )
        {
        case EN50221_MMI_ENQ:
            printf("%s\n", p_ret->object.u.enq.psz_text);
            printf("(empty to cancel)\n");
            exit(p_ret->object.u.enq.b_blind ? 253 : 254);
            break;

        case EN50221_MMI_MENU:
            printf("%s\n", p_ret->object.u.menu.psz_title);
            printf("%s\n", p_ret->object.u.menu.psz_subtitle);
            printf("0 - Cancel\n");
            for ( i = 0; i < p_ret->object.u.menu.i_choices; i++ )
                printf("%d - %s\n", i + 1,
                       p_ret->object.u.menu.ppsz_choices[i]);
            printf("%s\n", p_ret->object.u.menu.psz_bottom);
            exit(p_ret->object.u.menu.i_choices);
            break;

        case EN50221_MMI_LIST:
            printf("%s\n", p_ret->object.u.menu.psz_title);
            printf("%s\n", p_ret->object.u.menu.psz_subtitle);
            for ( i = 0; i < p_ret->object.u.menu.i_choices; i++ )
                printf("%s\n", p_ret->object.u.menu.ppsz_choices[i]);
            printf("%s\n", p_ret->object.u.menu.psz_bottom);
            printf("(0 to cancel)\n");
            exit(0);
            break;

        default:
            return_error( "Unknown MMI object" );
            break;
        }

        exit(255);
        break;
    }

    default:
        return_error( "Unknown command answer: %u", c_answer );
    }

    return 0;
}
Beispiel #27
0
int
client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
{
	struct sockaddr_un		sa;
	struct stat			sb;
	struct msg_identify_data	data;
	struct winsize			ws;
	size_t				size;
	int				mode;
	struct buffer		       *b;
	char			       *name;
#ifdef HAVE_SETPROCTITLE
	char		 		rpathbuf[MAXPATHLEN];
#endif

#ifdef HAVE_SETPROCTITLE
	if (realpath(path, rpathbuf) == NULL)
		strlcpy(rpathbuf, path, sizeof rpathbuf);
	setproctitle("client (%s)", rpathbuf);
#endif

	if (lstat(path, &sb) != 0) {
		if (start_server && errno == ENOENT) {
			if ((cctx->srv_fd = server_start(path)) == -1)
				goto start_failed;
			goto server_started;
		}
		goto not_found;
	}
	if (!S_ISSOCK(sb.st_mode)) {
		errno = ENOTSOCK;
		goto not_found;
	}

	memset(&sa, 0, sizeof sa);
	sa.sun_family = AF_UNIX;
	size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
	if (size >= sizeof sa.sun_path) {
		errno = ENAMETOOLONG;
		goto not_found;
	}

	if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		fatal("socket");

	if (connect(
	    cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
		if (errno == ECONNREFUSED) {
			if (unlink(path) != 0 || !start_server)
				goto not_found;
			if ((cctx->srv_fd = server_start(path)) == -1)
				goto start_failed;
			goto server_started;
		}
		goto not_found;
	}

server_started:
	if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
		fatal("fcntl failed");
	if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
		fatal("fcntl failed");
	cctx->srv_in = buffer_create(BUFSIZ);
	cctx->srv_out = buffer_create(BUFSIZ);

	if (isatty(STDIN_FILENO)) {
		if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
			fatal("ioctl(TIOCGWINSZ)");
		data.version = PROTOCOL_VERSION;
		data.flags = flags;
		data.sx = ws.ws_col;
		data.sy = ws.ws_row;
		*data.tty = '\0';
		if (getcwd(data.cwd, sizeof data.cwd) == NULL)
			*data.cwd = '\0';

		if ((name = ttyname(STDIN_FILENO)) == NULL)
			fatal("ttyname failed");
		if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty)
			fatalx("ttyname failed");

		b = buffer_create(BUFSIZ);
		cmd_send_string(b, getenv("TERM"));
		client_write_server2(cctx, MSG_IDENTIFY,
		    &data, sizeof data, BUFFER_OUT(b), BUFFER_USED(b));
		buffer_destroy(b);
	}

	return (0);

start_failed:
	log_warnx("server failed to start");
	return (1);

not_found:
	log_warn("server not found");
	return (1);
}
Beispiel #28
0
Datei: itchy.c Projekt: Rubusch/c
int main(int argc, char** argv)
{
  int sd_listen = -1;
  int sd_client = -1;
  struct sockaddr_un adr_server;
  char buf[BUF_SIZE];
  memset(buf, '\0', BUF_SIZE);

  do{
    // set up client socket
    fprintf(stderr, "%s set up \"listen socket\"\n", ME);
    if(0 > (sd_listen = socket(AF_UNIX, SOCK_STREAM, 0))){
      perror("socket failed");
      break;
    }

    // init server address
    fprintf(stderr, "%s init server address\n", ME);
    memset(&adr_server, 0, sizeof(adr_server));
    adr_server.sun_family = AF_UNIX;
    strncpy(adr_server.sun_path, SERVER_PATH, 1+strlen(SERVER_PATH));

    // bind socket to address
    fprintf(stderr, "%s bind \"listen socket\" to the server address\n", ME);
    if(0 > bind(sd_listen, (struct sockaddr*) &adr_server, SUN_LEN(&adr_server))){
      perror("bind failed");
      break;
    }

    // listen on socket with queue of max 3 candidantes
    fprintf(stderr, "%s listening\n", ME);
    if(0 > listen(sd_listen, 3)){
      perror("listen failed");
      break;
    }

    // accept - accept() is blocking by default, thus the server waits until it can connect
    fprintf(stderr, "%s waiting for accept..\n", ME);
    if(0 > (sd_client = accept(sd_listen, NULL, NULL))){
      perror("accept failed");
      break;
    }

    /*
    // set sockoption - in this case (SO_RCVLOWAT) the socket won't wake up the 
    // recv() until the buffer is full
    const int size = BUF_SIZE;
    if(0 > setsockopt(sd_client, SOL_SOCKET, SO_RCVLOWAT, (char*) &size, sizeof(size))){
      perror("setsockopt failed");
      break;
    }
    //*/

    // receive
    register ssize_t bytes=0;
    if(0 > (bytes = recv(sd_client, buf, BUF_SIZE, 0))){
      fprintf(stderr, "%s recv failed\n", ME);
      // nothing

    }else if(bytes == 0){
      fprintf(stderr, "%s nothing received\n", ME);
      break;

    }else{
      buf[bytes] = '\0'; // add string termination!
      fprintf(stderr, "%s received \"%s\"\n", ME, buf);
    }
    
    // send
    fprintf(stderr, "%s send \"%s\"..\n", ME, MESSAGE);
    memset(buf, '\0', BUF_SIZE);
    strncpy(buf, MESSAGE, strlen(MESSAGE));
    if(0 > send(sd_client, buf, sizeof(buf), 0)){
      perror("send failed");
      break;
    }

  }while(0);


  // in case something crashed - clean up
  if(-1 != sd_listen) close(sd_listen);
  if(-1 != sd_client) close(sd_client);
  unlink(SERVER_PATH);

  fprintf(stderr, "%s done!\n", ME);
  exit(EXIT_SUCCESS);
}
Beispiel #29
0
int main(void) 
{

    //printf("SHARE %d\n", *KMotionLocal.sharePtr);
    /* SJH - modified to listen to a TCP socket in addition to the unix domain (local) socket.
       Listens at port KMOTION_PORT (defined in KMotionDLL.h).
       FIXME: need to make this an argc/argv parameter.
    */
#ifdef _DEAMON
	//daemonize2();
	daemonize();
#endif
    //http://robertoacevedo.net/blog/2012/12/03/socket-server/
    pthread_attr_t attr; // Thread attribute
    pthread_attr_init(&attr); // Creating thread attributes
    pthread_attr_setschedpolicy(&attr, SCHED_FIFO); // FIFO scheduling for threads
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // Don't want threads (particualrly main)
                                                                   // waiting on each other

	openlog("KMotionServer", LOG_PID|LOG_CONS, LOG_USER);
	syslog(LOG_ERR, "KMotionServer started ");


    int tcp_socket;
    int main_socket;
    int client_socket;
    unsigned int t;
    struct sockaddr_un local, remote;
    struct sockaddr_in tlocal, tremote;
    fd_set rfds;
    int retval;
    socklen_t len;
    bool select_timedout;


    if ((main_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    	perrorExit("socket");
    }
    if ((tcp_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    	perrorExit("tcp socket");
    }

    if (strlen(SOCK_PATH) >= sizeof(local.sun_path)) {
    	perrorExit("path too long!");
    }

    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, SOCK_PATH);

    int unlink_err;
    if((unlink_err = unlink(local.sun_path))){
    	logError("unlink");
    }

    //http://idletechnology.blogspot.se/2011/12/unix-domain-sockets-on-osx.html
#ifdef __APPLE__
    local.sun_len = sizeof(local);
    if (bind(main_socket, (struct sockaddr *)&local, SUN_LEN(&local)) == -1) {
#else
    len = strlen(local.sun_path) + sizeof(local.sun_family);
    if (bind(main_socket, (struct sockaddr *)&local, len) == -1) {
#endif
    	perrorExit("bind");
    }
    
    
    tlocal.sin_family = AF_INET;
    tlocal.sin_port = htons(KMOTION_PORT);
    tlocal.sin_addr.s_addr = INADDR_ANY;
    len = sizeof(tlocal);
    if (bind(tcp_socket, (struct sockaddr *)&tlocal, len) == -1) {
    	perrorExit("tcp bind");
    }
    

    if (listen(main_socket, 5) == -1) {
    	perrorExit("listen");
    }
    if (listen(tcp_socket, 5) == -1) {
    	perrorExit("tcp listen");
    }

   for (int i=0; i<MAX_BOARDS; i++) ConsolePipeHandle[i]=0;
 
// The main loop creates an instance of the named pipe and 
// then waits for a client to connect to it. When the client 
// connects, a thread is created to handle communications 
// with that client, and the loop is repeated. 
	//pthread_t ct = pthread_self();
	//printf("Thread %.8x %.8x: Current thread\n", ct);
   select_timedout = false;
   for (;;) 
   { 
       
       FD_ZERO(&rfds);
       FD_SET(main_socket, &rfds);
       FD_SET(tcp_socket, &rfds);

       if(!select_timedout){
         syslog(LOG_ERR,"Main Thread. Waiting for a connection...\n");
       }

       struct timeval timeout;
       // Initialize the timeout data structure.
       timeout.tv_sec = 1;
       timeout.tv_usec = 0;

       retval = select(tcp_socket+1, &rfds, NULL, NULL, &timeout);
       select_timedout = retval == 0;
       if (retval < 0){
          perrorExit("select");
       } else if(select_timedout){
         //If exit() is executed in the processs that started the server we never get here
         //Hence the reference counting from KMotionDLl.nInstances must be made.
         if (nClients <= 0) break;                // nobody left - terminate server
         if (KMotionDLL.nInstances() < 2) break;  // nobody left - terminate server
         continue; //timeout
       } else if (FD_ISSET(main_socket, &rfds)) {
            t = sizeof(remote);
            client_socket = accept(main_socket, (struct sockaddr *)&remote, &t);
       }
       else if (FD_ISSET(tcp_socket, &rfds)) {
            t = sizeof(tremote);
            client_socket = accept(tcp_socket, (struct sockaddr *)&tremote, &t);
            if (client_socket >= 0) {
                int flag = 1;
                setsockopt(client_socket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
            }
       }
       else {
            // select() man page indicates possibility that there is nothing really there
            continue;
       }

       if (client_socket < 0) {
         perrorExit("Main Thread. accept");
       } else {
         //struct timeval tv;
         //tv.tv_sec = 5;  /* 30 Secs Timeout */
         //setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));

         syslog(LOG_ERR,"Main Thread. Connected descriptor %d %s\n",
             client_socket, FD_ISSET(tcp_socket, &rfds) ? "(tcp)" : "(local)");
         nClients++;

         syslog(LOG_ERR,"Main Thread. Spawning worker\n");
         pthread_t thr;
         // initialize data to pass to thread
         thdata data;
         data.file_desc = client_socket;

         if(pthread_create(&thr, &attr, &InstanceThread, (void *) &data))
         {
            MyErrExit("Main Thread. pthread_create");
         }
       }

   }
   closelog();
   syslog(LOG_ERR,"Main Thread. Closing server\n");
   exit(EXIT_SUCCESS);
} 
//http://www.amparo.net/ce155/thread-ex.html
void * InstanceThread(void *ptr){
	thdata *data = (thdata*) ptr;
	int thread_socket = data->file_desc;
	//pthread_t ct = pthread_self();
	//printf("Thread %.8x %.8x: Current thread\n", ct);
	syslog(LOG_ERR,"The ID of this of this thread is: %ld\n", syscall(SYS_gettid/*224*/));

	syslog(LOG_ERR,"Worker Thread. Nr of Clients when entered %d", nClients);
	//vsyslog(LOG_INFO, "Inside Thread %d\n", thread_socket);
	syslog(LOG_ERR, "Worker Thread. Inside Thread %d\n", thread_socket);

	char chRequest[BUFSIZE];
	char chReply[BUFSIZE];
	unsigned short cbReplyBytes;
	int cbBytesRead, cbWritten;
	
	// SJH - messages to/from client must now be prefixed with 2-byte length word (except for ACK 0xAA from client
	// in response to console or error messages).  This allows working over
	// network with SOCK_STREAM sockets where message boundaries are likely to be broken.  Even with Unix 
	// domain sockets, this is safer.
	unsigned short   msglen;
	unsigned short   len;
	enum {
	    RD_LEN,
	    RD_MSG
	} state;

    state = RD_LEN;
    len = 0;
    msglen = sizeof(msglen);
    bool cont = true;

	while(cont) {

		cbBytesRead = recv(thread_socket, chRequest + len, msglen - len, 0);
		if (cbBytesRead <= 0) {
			if (cbBytesRead < 0){
				logError("Worker Thread. recv");
			} else {
				syslog(LOG_ERR,"Worker Thread. received 0 bytes");
			}
			break;
		}
		len += cbBytesRead;
		switch (state) 
		{
		case RD_LEN:
		    if (len == msglen) {
		        memcpy(&msglen, chRequest, sizeof(msglen));
		        state = RD_MSG;
		        len = 0;
		        if (msglen > sizeof(chRequest)) {  
		            // Too long to possibly fit in buffer.  This should not happen unless client bad.
				    syslog(LOG_ERR,"Worker Thread. Message prefix %hu too long", msglen);
				    cont = false;
				    continue;
		        }
		    }
		    continue;
		case RD_MSG:
		    if (len == msglen) {
		        cbBytesRead = len;
		        msglen = sizeof(msglen);
		        state = RD_LEN;
		        len = 0;
		        break;  // from switch and process this msg
		    }
		    continue;
		}

		GetAnswerToRequest(chRequest, cbBytesRead, chReply+sizeof(msglen), &cbReplyBytes, thread_socket);
		memcpy(chReply, &cbReplyBytes, sizeof(msglen));
		cbReplyBytes += sizeof(msglen);
		cbWritten = send(thread_socket, chReply, cbReplyBytes, 0);

		if (cbWritten < 0 || cbReplyBytes != cbWritten) {
			if (cbWritten < 0){
				logError("Worker Thread. send");
			} else {
				syslog(LOG_ERR,"Worker Thread. %d bytes written != %d bytes sent\n",cbWritten,cbReplyBytes);
			}
			break;
		}
		
	}
	syslog(LOG_ERR,"Worker Thread. Exiting thread %d", thread_socket);

	// Flush the pipe to allow the client to read the pipe's contents
	// before disconnecting. Then disconnect the pipe, and close the
	// handle to this pipe instance.

	//	   FlushFileBuffers(thread_socket);
	//	   DisconnectNamedPipe(thread_socket);
	//	   CloseHandle(thread_socket);
	if(shutdown(thread_socket,SHUT_RDWR)< 0){
		logError("thread socket shutdown");
	}

	close(thread_socket);
	syslog(LOG_ERR,"Worker Thread. Nr of clients left %d", --nClients);
	pthread_exit(0);
	return 0;
}
Beispiel #30
0
Variant HHVM_FUNCTION(socket_sendto,
                      const Resource& socket,
                      const String& buf,
                      int len,
                      int flags,
                      const String& addr,
                      int port /* = -1 */) {
  Socket *sock = socket.getTyped<Socket>();
  if (len > buf.size()) {
    len = buf.size();
  }
  int retval;
  switch (sock->getType()) {
  case AF_UNIX:
    {
      struct sockaddr_un  s_un;
      memset(&s_un, 0, sizeof(s_un));
      s_un.sun_family = AF_UNIX;
      snprintf(s_un.sun_path, 108, "%s", addr.data());

      retval = sendto(sock->fd(), buf.data(), len, flags,
                      (struct sockaddr *)&s_un, SUN_LEN(&s_un));
    }
    break;
  case AF_INET:
    {
      if (port == -1) {
        throw_missing_arguments_nr("socket_sendto", 6, 5);
        return false;
      }

      struct sockaddr_in  sin;
      memset(&sin, 0, sizeof(sin));
      sin.sin_family = AF_INET;
      sin.sin_port = htons((unsigned short) port);
      if (!php_set_inet_addr(&sin, addr.c_str(), sock)) {
        return false;
      }

      retval = sendto(sock->fd(), buf.data(), len, flags,
                      (struct sockaddr *)&sin, sizeof(sin));
    }
    break;
  case AF_INET6:
    {
      if (port == -1) {
        throw_missing_arguments_nr("socket_sendto", 6, 5);
        return false;
      }

      struct sockaddr_in6  sin6;
      memset(&sin6, 0, sizeof(sin6));
      sin6.sin6_family = AF_INET6;
      sin6.sin6_port = htons((unsigned short) port);

      if (!php_set_inet6_addr(&sin6, addr.c_str(), sock)) {
        return false;
      }

      retval = sendto(sock->fd(), buf.data(), len, flags,
                      (struct sockaddr *)&sin6, sizeof(sin6));
    }
    break;
  default:
    raise_warning("Unsupported socket type %d", sock->getType());
    return false;
  }

  if (retval == -1) {
    SOCKET_ERROR(sock, "unable to write to socket", errno);
    return false;
  }

  return retval;
}