--- vlc/modules/control/rc.c.rc_socket~	2004-07-04 09:40:26.000000000 +0200
+++ vlc/modules/control/rc.c	2004-07-23 07:43:16.000000000 +0200
@@ -46,10 +46,46 @@
 #endif
 #include <sys/types.h>
 
+#ifndef WIN32
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+#if defined(PF_UNIX) || defined(PF_LOCAL)
+#include <sys/un.h>
+#endif
+/* None of the following stupid defines would be required
+ * if M$ wasn't stupid as hell or we didn't care about
+ * compatiblity with broken junk OSes that have no right
+ * to exist in the first place :/
+ */
+#define s_errno errno
+#else
+/* Moron$oft should really stop copying other APIs and
+ * then making them incompatible with the original
+ * and better implementation...
+ * Whoever implemented the Windoze socket API doesn't
+ * have a brain.
+ */
+#include <windows.h>
+#define s_errno WSAGetLastError()
+#endif
+
 #include "vlc_error.h"
+#include "network.h"
 
 #define MAX_LINE_LENGTH 256
 
+typedef struct {
+    /** Address of socket or NULL for stdin */
+    char * psz_addr;
+    /** FD of socket */
+    int    i_fd;
+    /** output FD */
+    int    i_output;
+} rc_data_t;
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -80,22 +116,125 @@
 #define TTY_TEXT N_("Fake TTY")
 #define TTY_LONGTEXT N_("Force the rc module to use stdin as if it was a TTY.")
 
+#define CF_TEXT N_("Command input")
+#define CF_LONGTEXT N_("Accept commands over a socket rather than stdin")
+
 vlc_module_begin();
     set_description( _("Remote control interface") );
     add_bool( "rc-show-pos", 0, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
 #ifdef HAVE_ISATTY
     add_bool( "fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT, VLC_TRUE );
 #endif
+    add_string( "commands-from", 0, NULL, CF_TEXT, CF_LONGTEXT, VLC_TRUE );
     set_capability( "interface", 20 );
     set_callbacks( Activate, NULL );
 vlc_module_end();
 
 /*****************************************************************************
+ * sockprintf: A variant of printf() that prints to a socket
+ *****************************************************************************/
+int sockprintf(int fd, const char *format, ...)
+{
+    va_list arg;
+    char *buf = 0;
+    int size;
+    int ret;
+
+    if(fd < 0)
+        return -1;
+	
+    va_start(arg, format);
+    size = vsnprintf(buf, 0, format, arg);
+    while(size == -1) {
+        /* YUCK, a libc that doesn't conform to ISO C99... */
+        int bufsiz = 1024;
+        buf = (char*)malloc(bufsiz);
+        size = vsnprintf(buf, bufsiz, format, arg);
+        bufsiz += 1024;
+        free(buf);
+    }
+    buf = (char*)malloc(size + 1);
+    vsnprintf(buf, size+1, format, arg);
+    ret = write(fd, buf, size);
+    va_end(arg);
+    free(buf);
+    return ret;
+}
+
+/*****************************************************************************
  * Activate: initialize and create stuff
  *****************************************************************************/
 static int Activate( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t*)p_this;
+    rc_data_t *p_param = (rc_data_t*)p_this->p_private = malloc(sizeof(rc_data_t));
+
+    p_param->psz_addr = config_GetPsz( p_intf, "commands-from" );
+
+    if( p_param->psz_addr && *p_param->psz_addr) {
+	int r;
+	if( p_param->psz_addr[0] == '/' || p_param->psz_addr[0] == '.' ) {
+#if !defined(PF_UNIX) && !defined(PF_LOCAL)
+	    msg_Warn( p_intf, "Your OS doesn't support filesystem sockets" );
+	    return VLC_EGENERIC;
+#else
+#if !defined(PF_UNIX)
+#define PF_UNIX PF_LOCAL
+#endif
+	    struct sockaddr_un addr;
+	    memset( &addr, 0, sizeof(struct sockaddr_un) );
+
+	    msg_Dbg( p_intf, "Trying UNIX socket");
+
+	    p_param->i_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+	    if(p_param->i_fd < 0) {
+		msg_Warn( p_intf, "Can't open socket: %s", strerror(s_errno));
+		return VLC_EGENERIC;
+	    }
+
+	    addr.sun_family = AF_UNIX;
+	    strcpy(addr.sun_path, p_param->psz_addr);
+	    r = bind( p_param->i_fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un) );
+#endif
+	} else {
+	    struct sockaddr_in addr;
+	    vlc_url_t url;
+
+	    memset( &addr, 0, sizeof(struct sockaddr_in) );
+	    memset( &url, 0, sizeof(vlc_url_t) );
+	    
+	    if( strchr( p_param->psz_addr, ':' ) ) /* If it doesn't include a :, it's a port number rather than an URL */
+	    	vlc_UrlParse( &url, p_param->psz_addr, 0);
+	    else
+		url.i_port = atoi(p_param->psz_addr);
+
+            p_param->i_fd = socket(PF_INET, SOCK_STREAM, 0);
+	    if(p_param->i_fd < 0) {
+		msg_Warn( p_intf, "Can't open socket: %s", strerror(s_errno));
+		return VLC_EGENERIC;
+	    }
+	    
+	    addr.sin_family = AF_INET;
+	    addr.sin_port = htons(url.i_port);
+	    /* By default, we listen on localhost only for security reasons.
+	     * If you need to listen on all IP addresses, specify 0.0.0.0
+	     */
+	    addr.sin_addr.s_addr = url.psz_host ? inet_addr(url.psz_host) : inet_addr("127.0.0.1");
+	    r = bind(p_param->i_fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in) );
+	}
+	if (r < 0) {
+	    msg_Warn( p_intf, "Couldn't bind socket to address: %s", strerror(s_errno));
+	    return VLC_EGENERIC;
+	}
+	r = listen( p_param->i_fd, 1 );
+	if (r < 0) {
+            msg_Warn( p_intf, "Can't listen on socket: %s", strerror(s_errno));
+	    return VLC_EGENERIC;
+	}
+    } else {
+        /* Non-buffered stdout */
+        setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
+    }
 
 #if defined(HAVE_ISATTY) && !defined(WIN32)
     /* Check that stdin is a TTY */
@@ -106,9 +245,6 @@
     }
 #endif
 
-    /* Non-buffered stdout */
-    setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
-
     p_intf->pf_run = Run;
 
     CONSOLE_INTRO_MSG;
@@ -127,6 +263,7 @@
 {
     input_thread_t * p_input;
     playlist_t *     p_playlist;
+    rc_data_t *p_param = (rc_data_t*)p_intf->p_private;
 
     char       p_buffer[ MAX_LINE_LENGTH + 1 ];
     vlc_bool_t b_showpos = config_GetInt( p_intf, "rc-show-pos" );
@@ -136,10 +273,14 @@
     int        i_newpos;
 
 #ifdef WIN32
-    HANDLE hConsoleIn;
+#define FD HANDLE
     INPUT_RECORD input_record;
     DWORD i_dummy2;
+#else
+#define FD int
 #endif
+    FD input;
+    FD output;
 
     p_input = NULL;
     p_playlist = NULL;
@@ -191,20 +332,41 @@
     var_Create( p_intf, "achan", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
     var_AddCallback( p_intf, "achan", AudioConfig, NULL );
 
+    if(!p_param->psz_addr) {
 #ifdef WIN32
-    /* Get the file descriptor of the console input */
-    hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
-    if( hConsoleIn == INVALID_HANDLE_VALUE )
-    {
-        msg_Err( p_intf, "Couldn't open STD_INPUT_HANDLE" );
-        p_intf->b_die = VLC_TRUE;
-    }
+        /* Get the file descriptor of the console input */
+        input = GetStdHandle(STD_INPUT_HANDLE);
+        if( input == INVALID_HANDLE_VALUE )
+        {
+            msg_Err( p_intf, "Couldn't open STD_INPUT_HANDLE" );
+            p_intf->b_die = VLC_TRUE;
+        }
+        output = p_param->i_output = GetStdHandle(STD_OUTPUT_HANDLE);
+        if( output == INVALID_HANDLE_VALUE )
+        {
+            msg_Err( p_intf, "Couldn't open STD_OUTPUT_HANDLE" );
+            p_intf->b_die = VLC_TRUE;
+        }
+#else
+        input = STDIN_FILENO;
+	output = p_param->i_output = STDOUT_FILENO;
 #endif
+    } else
+	input = output = p_param->i_output = -1;
 
     while( !p_intf->b_die )
     {
         vlc_bool_t     b_complete = VLC_FALSE;
 
+	if ( input == -1 ) {
+	    struct sockaddr s;
+	    int size = sizeof(struct sockaddr);
+	    output = p_param->i_output = input = accept(p_param->i_fd, &s, &size);
+	    if ( input < 0 ) {
+		msg_Warn( p_intf, "accept() failed; %s", strerror(s_errno) );
+	    }
+	}
+
 #ifndef WIN32
         fd_set         fds;
         struct timeval tv;
@@ -213,28 +375,34 @@
         tv.tv_sec = 0;
         tv.tv_usec = (long)INTF_IDLE_SLEEP;
         FD_ZERO( &fds );
-        FD_SET( STDIN_FILENO, &fds );
+        FD_SET( input, &fds );
 
-        i_dummy = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
+        i_dummy = select( input + 1, &fds, NULL, NULL, &tv );
 #else
         /* On Win32, select() only works on socket descriptors */
-        i_dummy = ( WaitForSingleObject( hConsoleIn, INTF_IDLE_SLEEP/1000 )
+        i_dummy = ( WaitForSingleObject( input, INTF_IDLE_SLEEP/1000 )
                     == WAIT_OBJECT_0 );
 #endif
         if( i_dummy > 0 )
         {
             int i_size = 0;
+	    int r;
 
             while( !p_intf->b_die
                     && i_size < MAX_LINE_LENGTH
 #ifndef WIN32
-                    && read( STDIN_FILENO, p_buffer + i_size, 1 ) > 0
+                    && (r = read( input, p_buffer + i_size, 1 )) > 0
 #else
-                    && ReadConsoleInput( hConsoleIn, &input_record, 1,
-                                         &i_dummy2 )
+                    && (r = ReadConsoleInput( input, &input_record, 1,
+                                         &i_dummy2 ))
 #endif
                    )
             {
+		if( p_param->psz_addr && r < 0 ) {
+                    // read error -- socket disconnected? Try again...
+		    input = output = p_param->i_output = -1;
+		    break;
+		}
 #ifdef WIN32
                 if( input_record.EventType != KEY_EVENT ||
                     !input_record.Event.KeyEvent.bKeyDown ||
@@ -293,7 +461,10 @@
                 p_buffer[ i_size ] = 0;
                 b_complete = VLC_TRUE;
             }
-        }
+        } else if( i_dummy < 0) {
+	    /* Socket disconnected? */
+            input = p_param->i_output = output = -1;
+	}
 
         /* Manage the input part */
         if( p_input == NULL )
@@ -326,7 +497,7 @@
             if( i_oldpos != i_newpos )
             {
                 i_oldpos = i_newpos;
-                printf( "pos: %d%%\n", i_newpos );
+                sockprintf( output, "pos: %d%%\n", i_newpos );
             }
         }
 
@@ -366,7 +537,7 @@
 
                 val.psz_string = psz_arg;
                 i_ret = var_Set( p_intf, psz_cmd, val );
-                printf( _("%s: returned %i (%s)\n"),
+                sockprintf( output, _("%s: returned %i (%s)\n"),
                         psz_cmd, i_ret, vlc_error( i_ret ) );
             }
             /* Or maybe it's a global command */
@@ -379,7 +550,7 @@
                 /* FIXME: it's a global command, but we should pass the
                  * local object as an argument, not p_intf->p_libvlc. */
                 i_ret = var_Set( p_intf->p_libvlc, psz_cmd, val );
-                printf( _("%s: returned %i (%s)\n"),
+                sockprintf( output, _("%s: returned %i (%s)\n"),
                         psz_cmd, i_ret, vlc_error( i_ret ) );
             }
             else if( !strcmp( psz_cmd, "info" ) )
@@ -393,22 +564,22 @@
                         info_category_t *p_category =
                             p_input->input.p_item->pp_categories[i];
 
-                        printf( "+----[ %s ]\n", p_category->psz_name );
-                        printf( "| \n" );
+                        sockprintf( output, "+----[ %s ]\n", p_category->psz_name );
+                        sockprintf( output, "| \n" );
                         for ( j = 0; j < p_category->i_infos; j++ )
                         {
                             info_t *p_info = p_category->pp_infos[j];
-                            printf( "| %s: %s\n", p_info->psz_name,
+                            sockprintf( output, "| %s: %s\n", p_info->psz_name,
                                     p_info->psz_value );
                         }
-                        printf( "| \n" );
+                        sockprintf( output, "| \n" );
                     }
-                    printf( _("+----[ end of stream info ]\n") );
+                    sockprintf( output, _("+----[ end of stream info ]\n") );
                     vlc_mutex_unlock( &p_input->input.p_item->lock );
                 }
                 else
                 {
-                    printf( _("no input\n") );
+                    sockprintf( output, _("no input\n") );
                 }
             }
             else switch( psz_cmd[0] )
@@ -437,42 +608,42 @@
             case '?':
             case 'h':
             case 'H':
-                printf(_("+----[ Remote control commands ]\n"));
-                printf("| \n");
-                printf(_("| add XYZ  . . . . . . . . . . add XYZ to playlist\n"));
-                printf(_("| playlist . . .  show items currently in playlist\n"));
-                printf(_("| play . . . . . . . . . . . . . . . . play stream\n"));
-                printf(_("| stop . . . . . . . . . . . . . . . . stop stream\n"));
-                printf(_("| next . . . . . . . . . . . .  next playlist item\n"));
-                printf(_("| prev . . . . . . . . . .  previous playlist item\n"));
-                printf(_("| title [X]  . . . . set/get title in current item\n"));
-                printf(_("| title_n  . . . . . .  next title in current item\n"));
-                printf(_("| title_p  . . . .  previous title in current item\n"));
-                printf(_("| chapter [X]  . . set/get chapter in current item\n"));
-                printf(_("| chapter_n  . . . .  next chapter in current item\n"));
-                printf(_("| chapter_p  . .  previous chapter in current item\n"));
-                printf("| \n");
-                printf(_("| seek X . seek in seconds, for instance `seek 12'\n"));
-                printf(_("| pause  . . . . . . . . . . . . . .  toggle pause\n"));
-                printf(_("| f  . . . . . . . . . . . . . . toggle fullscreen\n"));
-                printf(_("| info . . .  information about the current stream\n"));
-                printf("| \n");
-                printf(_("| volume [X] . . . . . . . .  set/get audio volume\n"));
-                printf(_("| volup [X]  . . . . .  raise audio volume X steps\n"));
-                printf(_("| voldown [X]  . . . .  lower audio volume X steps\n"));
-                printf(_("| adev [X] . . . . . . . . .  set/get audio device\n"));
-                printf(_("| achan [X]. . . . . . . .  set/get audio channels\n"));
-                printf("| \n");
-                printf(_("| help . . . . . . . . . . . . . this help message\n"));
-                printf(_("| quit . . . . . . . . . . . . . . . . .  quit vlc\n"));
-                printf("| \n");
-                printf(_("+----[ end of help ]\n"));
+                sockprintf(output, _("+----[ Remote control commands ]\n"));
+                sockprintf(output, "| \n");
+                sockprintf(output, _("| add XYZ  . . . . . . . . . . add XYZ to playlist\n"));
+                sockprintf(output, _("| playlist . . .  show items currently in playlist\n"));
+                sockprintf(output, _("| play . . . . . . . . . . . . . . . . play stream\n"));
+                sockprintf(output, _("| stop . . . . . . . . . . . . . . . . stop stream\n"));
+                sockprintf(output, _("| next . . . . . . . . . . . .  next playlist item\n"));
+                sockprintf(output, _("| prev . . . . . . . . . .  previous playlist item\n"));
+                sockprintf(output, _("| title [X]  . . . . set/get title in current item\n"));
+                sockprintf(output, _("| title_n  . . . . . .  next title in current item\n"));
+                sockprintf(output, _("| title_p  . . . .  previous title in current item\n"));
+                sockprintf(output, _("| chapter [X]  . . set/get chapter in current item\n"));
+                sockprintf(output, _("| chapter_n  . . . .  next chapter in current item\n"));
+                sockprintf(output, _("| chapter_p  . .  previous chapter in current item\n"));
+                sockprintf(output, "| \n");
+                sockprintf(output, _("| seek X . seek in seconds, for instance `seek 12'\n"));
+                sockprintf(output, _("| pause  . . . . . . . . . . . . . .  toggle pause\n"));
+                sockprintf(output, _("| f  . . . . . . . . . . . . . . toggle fullscreen\n"));
+                sockprintf(output, _("| info . . .  information about the current stream\n"));
+                sockprintf(output, "| \n");
+                sockprintf(output, _("| volume [X] . . . . . . . .  set/get audio volume\n"));
+                sockprintf(output, _("| volup [X]  . . . . .  raise audio volume X steps\n"));
+                sockprintf(output, _("| voldown [X]  . . . .  lower audio volume X steps\n"));
+                sockprintf(output, _("| adev [X] . . . . . . . . .  set/get audio device\n"));
+                sockprintf(output, _("| achan [X]. . . . . . . .  set/get audio channels\n"));
+                sockprintf(output, "| \n");
+                sockprintf(output, _("| help . . . . . . . . . . . . . this help message\n"));
+                sockprintf(output, _("| quit . . . . . . . . . . . . . . . . .  quit vlc\n"));
+                sockprintf(output, "| \n");
+                sockprintf(output, _("+----[ end of help ]\n"));
                 break;
             case '\0':
                 /* Ignore empty lines */
                 break;
             default:
-                printf( _("unknown command `%s', type `help' for help\n"), psz_cmd );
+                sockprintf(output, _("unknown command `%s', type `help' for help\n"), psz_cmd );
                 break;
             }
         }
@@ -496,6 +667,7 @@
 {
     input_thread_t * p_input;
     vlc_value_t     val;
+    rc_data_t *p_param = (rc_data_t*)p_this->p_private;
 
     p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
 
@@ -548,7 +720,7 @@
                 /* Get. */
                 var_Get( p_input, "chapter", &val );
                 var_Change( p_input, "chapter", VLC_VAR_GETCHOICES, &val_list, NULL );
-                printf( _("Currently playing chapter %d/%d\n"), val.i_int, val_list.p_list->i_count );
+                sockprintf( p_param->i_output, _("Currently playing chapter %d/%d\n"), val.i_int, val_list.p_list->i_count );
                 var_Change( p_this, "chapter", VLC_VAR_FREELIST, &val_list, NULL );
             }
         }
@@ -585,7 +757,7 @@
                 /* Get. */
                 var_Get( p_input, "title", &val );
                 var_Change( p_input, "title", VLC_VAR_GETCHOICES, &val_list, NULL );
-                printf( _("Currently playing title %d/%d\n"), val.i_int, val_list.p_list->i_count );
+                sockprintf( p_param->i_output, _("Currently playing title %d/%d\n"), val.i_int, val_list.p_list->i_count );
                 var_Change( p_this, "title", VLC_VAR_FREELIST, &val_list, NULL );
             }
         }
@@ -612,6 +784,7 @@
                      vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
     playlist_t *     p_playlist;
+    rc_data_t *p_param = (rc_data_t*)p_this->p_private;
 
     p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
                                            FIND_ANYWHERE );
@@ -639,7 +812,7 @@
     }
     else if( !strcmp( psz_cmd, "add" ) )
     {
-        printf( _("trying to add %s to playlist\n"), newval.psz_string );
+        sockprintf( p_param->i_output, _("trying to add %s to playlist\n"), newval.psz_string );
         playlist_Add( p_playlist, newval.psz_string, newval.psz_string,
                       PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
     }
@@ -648,13 +821,14 @@
         int i;
         for ( i = 0; i < p_playlist->i_size; i++ )
         {
-            printf( "|%s%s   %s|\n", i == p_playlist->i_index?"*":" ",
-                    p_playlist->pp_items[i]->input.psz_name,
-                    p_playlist->pp_items[i]->input.psz_uri );
+            sockprintf( p_param->i_output,
+                        "|%s%s   %s|\n", i == p_playlist->i_index?"*":" ",
+                        p_playlist->pp_items[i]->input.psz_name,
+                        p_playlist->pp_items[i]->input.psz_uri );
         }
         if ( i == 0 )
         {
-            printf( _("| no entries\n") );
+            sockprintf( p_param->i_output, _("| no entries\n") );
         }
     }
     /*
@@ -662,7 +836,7 @@
      */
     else
     {
-        printf( _("unknown command!\n") );
+        sockprintf( p_param->i_output, _("unknown command!\n") );
     }
 
     vlc_object_release( p_playlist );
@@ -700,6 +874,7 @@
                    vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
     int i_error;
+    rc_data_t *p_param = (rc_data_t*)p_this->p_private;
 
     if ( *newval.psz_string )
     {
@@ -707,7 +882,7 @@
         audio_volume_t i_volume = atoi( newval.psz_string );
         if ( i_volume > AOUT_VOLUME_MAX )
         {
-            printf( _("Volume must be in the range %d-%d\n"), AOUT_VOLUME_MIN,
+            sockprintf( p_param->i_output, _("Volume must be in the range %d-%d\n"), AOUT_VOLUME_MIN,
                     AOUT_VOLUME_MAX );
             i_error = VLC_EBADVAR;
         }
@@ -723,7 +898,7 @@
         }
         else
         {
-            printf( _("Volume is %d\n"), i_volume );
+            sockprintf( p_param->i_output, _("Volume is %d\n"), i_volume );
             i_error = VLC_SUCCESS;
         }
     }
@@ -737,6 +912,7 @@
     audio_volume_t i_volume;
     int i_nb_steps = atoi(newval.psz_string);
     int i_error = VLC_SUCCESS;
+    rc_data_t *p_param = (rc_data_t*)p_this->p_private;
 
     if ( i_nb_steps <= 0 || i_nb_steps > (AOUT_VOLUME_MAX/AOUT_VOLUME_STEP) )
     {
@@ -754,7 +930,7 @@
             i_error = VLC_EGENERIC;
     }
 
-    if ( !i_error ) printf( _("Volume is %d\n"), i_volume );
+    if ( !i_error ) sockprintf( p_param->i_output, _("Volume is %d\n"), i_volume );
     return i_error;
 }
 
@@ -765,6 +941,7 @@
     const char * psz_variable;
     vlc_value_t val_name;
     int i_error;
+    rc_data_t *p_param = (rc_data_t*)p_this->p_private;
 
     p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
     if ( p_aout == NULL ) return VLC_ENOOBJ;
@@ -803,19 +980,19 @@
             return VLC_EGENERIC;
         }
 
-        printf( "+----[ %s ]\n", val_name.psz_string );
+        sockprintf( p_param->i_output, "+----[ %s ]\n", val_name.psz_string );
         for ( i = 0; i < val.p_list->i_count; i++ )
         {
             if ( i_value == val.p_list->p_values[i].i_int )
-                printf( "| %i - %s *\n", val.p_list->p_values[i].i_int,
+                sockprintf( p_param->i_output, "| %i - %s *\n", val.p_list->p_values[i].i_int,
                         text.p_list->p_values[i].psz_string );
             else
-                printf( "| %i - %s\n", val.p_list->p_values[i].i_int,
+                sockprintf( p_param->i_output, "| %i - %s\n", val.p_list->p_values[i].i_int,
                         text.p_list->p_values[i].psz_string );
         }
         var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_FREELIST,
                     &val, &text );
-        printf( _("+----[ end of %s ]\n"), val_name.psz_string );
+        sockprintf( p_param->i_output, _("+----[ end of %s ]\n"), val_name.psz_string );
 
         if( val_name.psz_string ) free( val_name.psz_string );
         i_error = VLC_SUCCESS;
