/* * Copyright (C) 2003-2007 the xine-project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA * * gxine Javascript client */ #include "config.h" #include "i18n.h" #include "console_output.h" #include #include #include #include #include #include #include #include #include #include #define BUF_LEN 1024 static volatile int done = 0; static void sigpipe (int sig) { done = 1; signal (SIGPIPE, sigpipe); } int main (int argc, char **argv) { int fd, tfd; union { struct sockaddr_un u; struct sockaddr s; } cli_adr = { .u = {0} }, serv_adr = { .u = {0} }; int length = sizeof(struct sockaddr_un); char filename [FILENAME_MAX]; char *tstr; int ret = 0; signal (SIGPIPE, sigpipe); #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif console_output_init (); /* server filename */ const char *cfgdir = g_get_user_config_dir (); int home_is_not_cfgdir = !!strcmp (g_get_home_dir (), cfgdir); char *path = g_build_filename (cfgdir, ".gxine" + home_is_not_cfgdir, "socket", NULL); snprintf (filename, sizeof (filename), "%s", path); g_free (path); if (strlen (filename) >= sizeof (cli_adr.u.sun_path)) { fputs (_("socket: name too long - cannot connect\n"), stderr); exit (EXIT_FAILURE); } g_print (_("Connecting to %s...\n"), filename); fd = socket (AF_UNIX, SOCK_STREAM, 0); /* initialize the client address structure */ cli_adr.u.sun_family = AF_UNIX; tstr = strdup ("/tmp/gxine_XXXXXX"); tfd = mkstemp (tstr); if (tfd < 0) { perror ("mkstemp"); exit (EXIT_FAILURE); } close (tfd); strncpy (cli_adr.u.sun_path, tstr, sizeof (cli_adr.u.sun_path) - 1); unlink (tstr); /* bind the socket to the client's address */ if (bind (fd, &cli_adr.s, length) < 0) { perror ("bind"); exit (EXIT_FAILURE); } /* initialize the server address structure */ serv_adr.u.sun_family = AF_UNIX; strcpy (serv_adr.u.sun_path, filename); if (connect (fd, &serv_adr.s, sizeof (serv_adr)) < 0) { perror ("connect"); exit (EXIT_FAILURE); } g_print (_("Connected.\n")); if (argc > 1) { /* noninteractive */ g_print (_("Sending command\n")); write (fd, argv[1], strlen(argv[1])); write (fd, "\n", 1); g_print (_("Done.\n")); } else { /* interactive mode */ int n; if (fd > STDIN_FILENO) n = fd + 1; else n = STDIN_FILENO + 1; while (!done) { char buf[10]; fd_set rset; FD_ZERO (&rset); FD_SET (fd, &rset); FD_SET (STDIN_FILENO, &rset); if (select (n, &rset, NULL, NULL, NULL) <= 0) { perror ("client: select: "); ret = 2; break; } if (FD_ISSET (fd, &rset)) { switch (read (fd, buf, 1)) { case EOF: perror ("client: output: "); break; case 0: done = 1; /* gxine exited */ break; case 1: write (STDOUT_FILENO, buf, 1); break; } } if (FD_ISSET (STDIN_FILENO, &rset)) { if (read (STDIN_FILENO, buf, 1) == 1) write (fd, buf, 1); } } } close(fd); unlink (tstr); free (tstr); return ret; }