Exemple #1
0
/* End playing and cleanup. */
static void server_shutdown ()
{
	logit ("Server exiting...");
	audio_exit ();
	tags_cache_free (tags_cache);
	tags_cache = NULL;
	unlink (socket_name());
	unlink (create_file_name(PID_FILE));
	close (wake_up_pipe[0]);
	close (wake_up_pipe[1]);
	logit ("Server exited");
	log_close ();
}
Exemple #2
0
/* End playing and cleanup. */
static void server_shutdown ()
{
	logit ("Server exiting...");
	audio_exit ();
	tags_cache_save (&tags_cache, create_file_name("tags_cache"));
	tags_cache_destroy (&tags_cache);
	unlink (socket_name());
	unlink (create_file_name(PID_FILE));
	close (wake_up_pipe[0]);
	close (wake_up_pipe[1]);
	logit ("Server exited");
	log_close ();
}
Exemple #3
0
/* Connect to the server, return fd of the socket or -1 on error. */
static int server_connect ()
{
	struct sockaddr_un sock_name;
	int sock;

	/* Create a socket */
	if ((sock = socket (PF_LOCAL, SOCK_STREAM, 0)) == -1)
		 return -1;

	sock_name.sun_family = AF_LOCAL;
	strcpy (sock_name.sun_path, socket_name());

	if (connect(sock, (struct sockaddr *)&sock_name,
				SUN_LEN(&sock_name)) == -1) {
		close (sock);
		return -1;
	}

	return sock;
}
Exemple #4
0
/* Connect to the server, return fd of the socket or -1 on error. */
static int server_connect ()
{
	struct sockaddr_un sock_name;
	int sock;

	/* Create a socket.
	 * For reasons why AF_UNIX is the correct constant to use in both
	 * cases, see the commentary the SVN log for commit r2833. */
	if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) == -1)
		 return -1;

	sock_name.sun_family = AF_UNIX;
	strcpy (sock_name.sun_path, socket_name());

	if (connect(sock, (struct sockaddr *)&sock_name,
				SUN_LEN(&sock_name)) == -1) {
		close (sock);
		return -1;
	}

	return sock;
}
Exemple #5
0
/* Initialize the server - return fd of the listening socket or -1 on error */
void server_init (int debugging, int foreground)
{
	struct sockaddr_un sock_name;
	pid_t pid;

	logit ("Starting MOC Server");

	assert (server_sock == -1);

	pid = check_pid_file ();
	if (pid && valid_pid(pid)) {
		fprintf (stderr, "\nIt seems that the server is already running"
				" with pid %d.\n", pid);
		fprintf (stderr, "If it is not true, remove the pid file (%s)"
				" and try again.\n",
				create_file_name(PID_FILE));
		fatal ("Exiting!");
	}

	if (foreground)
		log_init_stream (stdout, "stdout");
	else {
		FILE *logfp;

		logfp = NULL;
		if (debugging) {
			logfp = fopen (SERVER_LOG, "a");
			if (!logfp)
				fatal ("Can't open server log file: %s", xstrerror (errno));
		}
		log_init_stream (logfp, SERVER_LOG);
	}

	if (pipe(wake_up_pipe) < 0)
		fatal ("pipe() failed: %s", xstrerror (errno));

	unlink (socket_name());

	/* Create a socket.
	 * For reasons why AF_UNIX is the correct constant to use in both
	 * cases, see the commentary the SVN log for commit r9999. */
	server_sock = socket (AF_UNIX, SOCK_STREAM, 0);
	if (server_sock == -1)
		fatal ("Can't create socket: %s", xstrerror (errno));
	sock_name.sun_family = AF_UNIX;
	strcpy (sock_name.sun_path, socket_name());

	/* Bind to socket */
	if (bind(server_sock, (struct sockaddr *)&sock_name, SUN_LEN(&sock_name)) == -1)
		fatal ("Can't bind() to the socket: %s", xstrerror (errno));

	if (listen(server_sock, 1) == -1)
		fatal ("listen() failed: %s", xstrerror (errno));

	/* Log stack sizes so stack overflows can be debugged. */
	log_process_stack_size ();
	log_pthread_stack_size ();

	clients_init ();
	audio_initialize ();
	tags_cache = tags_cache_new (options_get_int("TagsCacheSize"));
	tags_cache_load (tags_cache, create_file_name("cache"));

	server_tid = pthread_self ();
	xsignal (SIGTERM, sig_exit);
	xsignal (SIGINT, foreground ? sig_exit : SIG_IGN);
	xsignal (SIGHUP, SIG_IGN);
	xsignal (SIGQUIT, sig_exit);
	xsignal (SIGPIPE, SIG_IGN);
	xsignal (SIGCHLD, sig_chld);

	write_pid_file ();

	if (!foreground) {
		setsid ();
		redirect_output (stdin);
		redirect_output (stdout);
		redirect_output (stderr);
	}

	return;
}
Exemple #6
0
/* Initialize the server - return fd of the listening socket or -1 on error */
int server_init (int debugging, int foreground)
{
	struct sockaddr_un sock_name;
	int server_sock;
	int pid;

	logit ("Starting MOC Server");

	pid = check_pid_file ();
	if (pid && valid_pid(pid)) {
		fprintf (stderr, "\nIt seems that the server is already running"
				" with pid %d.\n", pid);
		fprintf (stderr, "If it is not true, remove the pid file (%s)"
				" and try again.\n",
				create_file_name(PID_FILE));
		fatal ("Exiting!");
	}

	if (foreground)
		log_init_stream (stdout, "stdout");
	else {
		FILE *logfp;

		logfp = NULL;
		if (debugging) {
			logfp = fopen (SERVER_LOG, "a");
			if (!logfp)
				fatal ("Can't open server log file: %s", strerror (errno));
		}
		log_init_stream (logfp, SERVER_LOG);
	}

	if (pipe(wake_up_pipe) < 0)
		fatal ("pipe() failed: %s", strerror(errno));

	unlink (socket_name());

	/* Create a socket */
	if ((server_sock = socket (PF_LOCAL, SOCK_STREAM, 0)) == -1)
		fatal ("Can't create socket: %s", strerror(errno));
	sock_name.sun_family = AF_LOCAL;
	strcpy (sock_name.sun_path, socket_name());

	/* Bind to socket */
	if (bind(server_sock, (struct sockaddr *)&sock_name, SUN_LEN(&sock_name)) == -1)
		fatal ("Can't bind() to the socket: %s", strerror(errno));

	if (listen(server_sock, 1) == -1)
		fatal ("listen() failed: %s", strerror(errno));

	audio_initialize ();
	tags_cache_init (&tags_cache, options_get_int("TagsCacheSize"));
	tags_cache_load (&tags_cache, create_file_name("cache"));
	clients_init ();

	server_tid = pthread_self ();
	thread_signal (SIGTERM, sig_exit);
	thread_signal (SIGINT, foreground ? sig_exit : SIG_IGN);
	thread_signal (SIGHUP, SIG_IGN);
	thread_signal (SIGQUIT, sig_exit);
	thread_signal (SIGPIPE, SIG_IGN);

	write_pid_file ();

	if (!foreground) {
		setsid ();
		redirect_output (stdin);
		redirect_output (stdout);
		redirect_output (stderr);
	}

	return server_sock;
}
Exemple #7
0
int socket_create(const char *dest_ip, int dest_port, const char *src_ip, int src_port, int flags)
{
        char *passive[] = {"::", "0.0.0.0"};
        int sock = -1, pfamily, try_ok;
        sockname_t dest_name, src_name;

        /* If no source ip address is given, try :: and 0.0.0.0 (passive). */
        for (try_ok = 0; try_ok < 2; try_ok++) {
                /* Resolve the ip addresses. */
                socket_name(&dest_name, dest_ip ? dest_ip : passive[try_ok], dest_port);
                socket_name(&src_name, src_ip ? src_ip : passive[try_ok], src_port);

                if (src_ip || src_port) flags |= SOCKET_BIND;

                if (flags & SOCKET_CLIENT) pfamily = dest_name.family;
                else if (flags & SOCKET_SERVER) pfamily = src_name.family;
                else {
                        errno = EADDRNOTAVAIL;
                        return(-1);
                }

                /* Create the socket. */
                if (flags & SOCKET_UDP) sock = socket(pfamily, SOCK_DGRAM, 0);
                else sock = socket(pfamily, SOCK_STREAM, 0);

                if (sock >= 0) break;
        }

        if (sock < 0) return(-2);

        allocsock(sock, 0);

        if (flags & SOCKET_NONBLOCK) socket_set_nonblock(sock, 1);

        /* Do the bind if necessary. */
        if (flags & (SOCKET_SERVER|SOCKET_BIND)) {
                int yes = 1;

                setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
                if (bind(sock, &src_name.u.addr, src_name.len) != 0) {
			killsock(sock);
			return(-3);
		}
                if (flags & SOCKET_SERVER) listen(sock, 50);
        }


        if (flags & SOCKET_CLIENT) {
			int i = -1;
			if ((i = findanysnum(sock)) != -1) {
				socklist[i].flags = (socklist[i].flags & ~SOCK_VIRTUAL) | SOCK_CONNECT | SOCK_PASS;
				socklist[i].host = strdup(dest_ip);
				socklist[i].port = dest_port;
			}

          if (connect(sock, &dest_name.u.addr, dest_name.len) != 0) {
		if (errno != EINPROGRESS) {
			killsock(sock);
			return(-4);
		}
          }
        }

        errno = 0;

        /* Yay, we're done. */
        return(sock);
}