+ utf8_fprintf( pidfile, "%d", (int)i_pid );
+ fclose( pidfile );
+ }
+ else
+ {
+ msg_Err( p_libvlc, "cannot open pid file for writing: %s (%m)",
+ psz_pidfile );
+ }
+ }
+ free( psz_pidfile );
+
+#else
+ pid_t i_pid;
+
+ if( ( i_pid = fork() ) < 0 )
+ {
+ msg_Err( p_libvlc, "unable to fork vlc to daemon mode" );
+ b_exit = true;
+ }
+ else if( i_pid )
+ {
+ /* This is the parent, exit right now */
+ msg_Dbg( p_libvlc, "closing parent process" );
+ b_exit = true;
+ i_ret = VLC_EEXITSUCCESS;
+ }
+ else
+ {
+ /* We are the child */
+ msg_Dbg( p_libvlc, "daemon spawned" );
+ close( STDIN_FILENO );
+ close( STDOUT_FILENO );
+ close( STDERR_FILENO );
+
+ b_daemon = true;
+ }
+#endif
+ }
+#endif
+
+ if( b_exit )
+ {
+ module_EndBank( p_libvlc );
+ return i_ret;
+ }
+
+ /* Check for translation config option */
+#if defined( ENABLE_NLS ) \
+ && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
+# if defined (WIN32) || defined (__APPLE__)
+ /* This ain't really nice to have to reload the config here but it seems
+ * the only way to do it. */
+
+ if( !config_GetInt( p_libvlc, "ignore-config" ) )
+ config_LoadConfigFile( p_libvlc, "main" );
+ config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
+
+ /* Check if the user specified a custom language */
+ psz_language = config_GetPsz( p_libvlc, "language" );
+ if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
+ {
+ bool b_cache_delete = p_libvlc_global->p_module_bank->b_cache_delete;
+
+ /* Reset the default domain */
+ SetLanguage( psz_language );
+
+ /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
+ msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
+
+ module_EndBank( p_libvlc );
+ module_InitBank( p_libvlc );
+ if( !config_GetInt( p_libvlc, "ignore-config" ) )
+ config_LoadConfigFile( p_libvlc, "main" );
+ config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
+ p_libvlc_global->p_module_bank->b_cache_delete = b_cache_delete;
+ }
+ free( psz_language );
+# endif
+#endif
+
+ /*
+ * Load the builtins and plugins into the module_bank.
+ * We have to do it before config_Load*() because this also gets the
+ * list of configuration options exported by each module and loads their
+ * default values.
+ */
+ module_LoadBuiltins( p_libvlc );
+ module_LoadPlugins( p_libvlc );
+ if( p_libvlc->b_die )
+ {
+ b_exit = true;
+ }
+
+ msg_Dbg( p_libvlc, "module bank initialized, found %i modules",
+ vlc_internals( p_libvlc_global->p_module_bank )->i_children );
+
+ /* Check for help on modules */
+ if( (p_tmp = config_GetPsz( p_libvlc, "module" )) )
+ {
+ Help( p_libvlc, p_tmp );
+ free( p_tmp );
+ b_exit = true;
+ i_ret = VLC_EEXITSUCCESS;
+ }
+ /* Check for long help option */
+ else if( config_GetInt( p_libvlc, "longhelp" ) > 0 )
+ {
+ Help( p_libvlc, "longhelp" );
+ b_exit = true;
+ i_ret = VLC_EEXITSUCCESS;
+ }
+ /* Check for module list option */
+ else if( config_GetInt( p_libvlc, "list" ) > 0 )
+ {
+ ListModules( p_libvlc, false );
+ b_exit = true;
+ i_ret = VLC_EEXITSUCCESS;
+ }
+ else if( config_GetInt( p_libvlc, "list-verbose" ) > 0 )
+ {
+ ListModules( p_libvlc, true );
+ b_exit = true;
+ i_ret = VLC_EEXITSUCCESS;
+ }
+
+ /* Check for config file options */
+ if( !config_GetInt( p_libvlc, "ignore-config" ) )
+ {
+ if( config_GetInt( p_libvlc, "reset-config" ) > 0 )
+ {
+ config_ResetAll( p_libvlc );
+ config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
+ config_SaveConfigFile( p_libvlc, NULL );
+ }
+ if( config_GetInt( p_libvlc, "save-config" ) > 0 )
+ {
+ config_LoadConfigFile( p_libvlc, NULL );
+ config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
+ config_SaveConfigFile( p_libvlc, NULL );
+ }
+ }
+
+ if( b_exit )
+ {
+ module_EndBank( p_libvlc );
+ return i_ret;
+ }
+
+ /*
+ * Init device values
+ */
+ InitDeviceValues( p_libvlc );
+
+ /*
+ * Override default configuration with config file settings
+ */
+ if( !config_GetInt( p_libvlc, "ignore-config" ) )
+ config_LoadConfigFile( p_libvlc, NULL );
+
+ /*
+ * Override configuration with command line settings
+ */
+ if( config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, false ) )
+ {
+#ifdef WIN32
+ ShowConsole( false );
+ /* Pause the console because it's destroyed when we exit */
+ fprintf( stderr, "The command line options couldn't be loaded, check "
+ "that they are valid.\n" );
+ PauseConsole();
+#endif
+ module_EndBank( p_libvlc );
+ return VLC_EGENERIC;
+ }
+
+ /*
+ * System specific configuration
+ */
+ system_Configure( p_libvlc, &i_argc, ppsz_argv );
+
+/* FIXME: could be replaced by using Unix sockets */
+#ifdef HAVE_DBUS
+ dbus_threads_init_default();
+
+ if( config_GetInt( p_libvlc, "one-instance" ) > 0 )
+ {
+ /* Initialise D-Bus interface, check for other instances */
+ DBusConnection *p_conn = NULL;
+ DBusError dbus_error;
+
+ dbus_error_init( &dbus_error );
+
+ /* connect to the session bus */
+ p_conn = dbus_bus_get( DBUS_BUS_SESSION, &dbus_error );
+ if( !p_conn )
+ {
+ msg_Err( p_libvlc, "Failed to connect to D-Bus session daemon: %s",
+ dbus_error.message );
+ dbus_error_free( &dbus_error );
+ }
+ else
+ {
+ /* check if VLC is available on the bus
+ * if not: D-Bus control is not enabled on the other
+ * instance and we can't pass MRLs to it */
+ DBusMessage *p_test_msg = NULL;
+ DBusMessage *p_test_reply = NULL;
+ p_test_msg = dbus_message_new_method_call(
+ "org.mpris.vlc", "/",
+ "org.freedesktop.MediaPlayer", "Identity" );
+ /* block until a reply arrives */
+ p_test_reply = dbus_connection_send_with_reply_and_block(
+ p_conn, p_test_msg, -1, &dbus_error );
+ dbus_message_unref( p_test_msg );
+ if( p_test_reply == NULL )
+ {
+ dbus_error_free( &dbus_error );
+ msg_Dbg( p_libvlc, "No Media Player is running. "
+ "Continuing normally." );
+ }
+ else
+ {
+ int i_input;
+ DBusMessage* p_dbus_msg = NULL;
+ DBusMessageIter dbus_args;
+ DBusPendingCall* p_dbus_pending = NULL;
+ dbus_bool_t b_play;
+
+ dbus_message_unref( p_test_reply );
+ msg_Warn( p_libvlc, "Another Media Player is running. Exiting");
+
+ for( i_input = optind;i_input < i_argc;i_input++ )
+ {
+ msg_Dbg( p_libvlc, "Adds %s to the running Media Player",
+ ppsz_argv[i_input] );
+
+ p_dbus_msg = dbus_message_new_method_call(
+ "org.mpris.vlc", "/TrackList",
+ "org.freedesktop.MediaPlayer", "AddTrack" );
+
+ if ( NULL == p_dbus_msg )
+ {
+ msg_Err( p_libvlc, "D-Bus problem" );
+ system_End( p_libvlc );
+ exit( VLC_ETIMEOUT );
+ }
+
+ /* append MRLs */
+ dbus_message_iter_init_append( p_dbus_msg, &dbus_args );
+ if ( !dbus_message_iter_append_basic( &dbus_args,
+ DBUS_TYPE_STRING, &ppsz_argv[i_input] ) )
+ {
+ dbus_message_unref( p_dbus_msg );
+ system_End( p_libvlc );
+ exit( VLC_ENOMEM );
+ }
+ b_play = TRUE;
+ if( config_GetInt( p_libvlc, "playlist-enqueue" ) > 0 )
+ b_play = FALSE;
+ if ( !dbus_message_iter_append_basic( &dbus_args,
+ DBUS_TYPE_BOOLEAN, &b_play ) )
+ {
+ dbus_message_unref( p_dbus_msg );
+ system_End( p_libvlc );
+ exit( VLC_ENOMEM );
+ }
+
+ /* send message and get a handle for a reply */
+ if ( !dbus_connection_send_with_reply ( p_conn,
+ p_dbus_msg, &p_dbus_pending, -1 ) )
+ {
+ msg_Err( p_libvlc, "D-Bus problem" );
+ dbus_message_unref( p_dbus_msg );
+ system_End( p_libvlc );
+ exit( VLC_ETIMEOUT );
+ }
+
+ if ( NULL == p_dbus_pending )
+ {
+ msg_Err( p_libvlc, "D-Bus problem" );
+ dbus_message_unref( p_dbus_msg );
+ system_End( p_libvlc );
+ exit( VLC_ETIMEOUT );
+ }
+ dbus_connection_flush( p_conn );
+ dbus_message_unref( p_dbus_msg );
+ /* block until we receive a reply */
+ dbus_pending_call_block( p_dbus_pending );
+ dbus_pending_call_unref( p_dbus_pending );
+ } /* processes all command line MRLs */
+
+ /* bye bye */
+ system_End( p_libvlc );
+ exit( VLC_SUCCESS );
+ }
+ }
+ /* we unreference the connection when we've finished with it */
+ if( p_conn ) dbus_connection_unref( p_conn );
+ }
+#endif
+
+ /*
+ * Message queue options
+ */
+ char * psz_verbose_objects = config_GetPsz( p_libvlc, "verbose-objects" );
+ if( psz_verbose_objects )
+ {
+ char * psz_object, * iter = psz_verbose_objects;
+ while( (psz_object = strsep( &iter, "," )) )
+ {
+ switch( psz_object[0] )
+ {
+ printf("%s\n", psz_object+1);
+ case '+': msg_EnableObjectPrinting(p_libvlc, psz_object+1); break;
+ case '-': msg_DisableObjectPrinting(p_libvlc, psz_object+1); break;