/* ** Copyright (C) 2002-2004 Daniel Caujolle-Bert ** ** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** */ /* required for getsubopt() */ #ifndef __sun #define _XOPEN_SOURCE 500 #endif #define _BSD_SOURCE 1 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #ifdef HAVE_GETOPT_LONG # include #else # include "getopt.h" #endif #include #include #include "common.h" #include "utils.h" #include "commands.h" #include "playlist.h" extern int errno; static toxine_t *tox; /* options args */ static const char *short_options = "?hs:e:o::vV:A:iI"; static struct option long_options[] = { { "help" , no_argument , 0, 'h' }, { "script" , required_argument, 0, 's' }, { "execute" , required_argument, 0, 'e' }, { "output" , optional_argument, 0, 'o' }, { "video" , required_argument, 0, 'V' }, { "audio" , required_argument, 0, 'A' }, { "interactive" , required_argument, 0, 'i' }, { "autoinit" , no_argument, 0, 'I' }, { "version" , no_argument , 0, 'v' }, { 0 , no_argument , 0, 0 } }; /* * Display version/copyright banner. */ static void toxine_show_version(void) { int major, minor, sub; printf("This is toxine - xine shell v%s\n" "(c) 2002-2003 by Daniel Caujolle-Bert .\n", VERSION); printf("Built with xine library %d.%d.%d (%s)\n", XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION, XINE_VERSION); xine_get_version (&major, &minor, &sub); printf("Found xine library version: %d.%d.%d (%s).\n", major, minor, sub, xine_get_version_string()); } /* * Display full help. */ static void toxine_print_usage(void) { printf("Usage: toxine [options]\n"); printf(" -s, --script Use as toxine script file.\n"); printf(" -e, --execute Execute specified commands (like in prompt mode).\n"); printf(" -o, --output [filename] Save all messages in a file(*).\n"); printf(" *('toxine.out' if filename isn't specified).\n"); printf(" -V, --video Use video driver .\n"); printf(" -A, --audio Use audio driver .\n"); printf(" -i, --interactive Disable interactive mode (no confirm).\n"); printf(" -I, --autoinit Init xine engine on start(*).\n"); printf(" *(video/audio driver names should be sets).\n"); printf(" -v, --version Display version.\n"); printf(" -h, --help Display this help text.\n"); printf("\n"); } /* * Freeing allocated memory. */ static void toxine_release(toxine_t *tox) { if(tox) { int i; if(tox->msg_fd >= 0) close(tox->msg_fd); if(tox->playlist.num) { for(; tox->playlist.num > 0;) playlist_free_entry(tox, (tox->playlist.num - 1)); toxine_free(tox->playlist.mmk); } toxine_free(tox->configfile); toxine_free(tox->video.name); toxine_free(tox->audio.name); toxine_free(tox->command.line); toxine_free(tox->command.remain); toxine_free(tox->command.command); // toxine_free(tox->last_result); for(i = 0; i < 256; i++) toxine_free(tox->command.args[i]); toxine_free(tox->script.filename); toxine_free(tox); } } /* * ... */ int main(int argc, char **argv) { int c = '?'; int option_index = 0; int interactive = 1; int i; /* Check xine library version */ if(!xine_check_version(1, 0, 0)) { int major, minor, sub; xine_get_version(&major, &minor, &sub); fprintf(stderr, "Require xine library version 1.0.0, found %d.%d.%d.\n", major, minor, sub); exit(1); } tox = (toxine_t *) xine_xmalloc(sizeof(toxine_t)); tox->command.remain = NULL; tox->command.line = NULL; tox->command.command = NULL; tox->command.execute = 0; tox->xine_state = 0; tox->msg_fd = -1; tox->playlist.cur = -1; tox->playlist.loop = 0; /* * parse command line */ opterr = 0; while((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != EOF) { switch(c) { case 's': /* use a script file */ if(optarg != NULL) { if(tox->script.filename == NULL) { tox->script.filename = strdup(optarg); tox->script.in_use = 1; } else fprintf(stderr, "script filename already set: '%s'\n", tox->script.filename); } else { fprintf(stderr, "script filename is required to -S/--script option\n"); exit(1); } break; case 'e': /* execute commands */ if(optarg != NULL) { tox->command.execute = 1; tox->command.line = strdup(toxine_atoa(optarg)); } break; case 'o': { char *ofile = (optarg) ? optarg : "toxine.out"; if((tox->msg_fd = open(ofile, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644)) < 0) { fprintf(stderr, "Cannot open %s: %s\n", ofile, strerror(errno)); exit(1); } } break; case 'V': /* video driver name */ if(optarg != NULL) tox->video.name = strdup(optarg); break; case 'A': /* audio driver name */ if(optarg != NULL) tox->audio.name = strdup(optarg); break; case 'i': /* interactive mode */ interactive = 0; break; case 'I': /* auto init */ tox->autoinit = 1; break; case 'v': /* Display version and exit*/ toxine_show_version(); exit(1); break; case 'h': /* Display usage */ case '?': toxine_print_usage(); exit(1); break; default: toxine_print_usage(); fprintf(stderr, "invalid argument %d => exit\n",c); exit(1); } } if(tox->msg_fd >= 0) { if((!tox->script.in_use) && (!tox->command.execute)) { fprintf(stderr, "You can't use message redirection in prompt mode.\n"); toxine_release(tox); exit(1); } if(dup2(tox->msg_fd, STDOUT_FILENO) < 0) fprintf(stderr, "Cannot dup2 stdout: %s\n", strerror(errno)); if(dup2(tox->msg_fd, STDERR_FILENO) < 0) fprintf(stderr, "Cannot dup2 stderr: %s\n", strerror(errno)); } toxine_show_version(); /* * generate and init a config "object" */ { char *cfgfile = ".xine/toxine_config"; if (!(tox->configfile = getenv ("XINERC"))) { tox->configfile = (char *) xine_xmalloc((strlen((xine_get_homedir())) + strlen(cfgfile))+2); sprintf(tox->configfile, "%s/%s", (xine_get_homedir()), cfgfile); } } tox->running = 1; tox->playlist.mmk = NULL; tox->playlist.thread_num = 0;; tox->loop_mode = PLAYLIST_LOOP; tox->last_result = NULL; for(i = 0; i < 256; i++) tox->command.args[i] = (char *) xine_xmalloc(sizeof(char *) * 2048); if(interactive) tox->interactive = 1; else tox->interactive = 0; toxine_run(tox, argc - optind, &argv[optind]); toxine_release(tox); return 1; }