]> git.sesse.net Git - vlc/blobdiff - src/stream_output/announce.c
Fix some memleaks
[vlc] / src / stream_output / announce.c
index df67982a4fb1f34d1eef2bcb2067c385e3589fcf..e7950f94d3b0303962e1f0ed3fa3d44683e8d024 100644 (file)
@@ -1,10 +1,10 @@
 /*****************************************************************************
  * announce.c : announce handler
  *****************************************************************************
- * Copyright (C) 2002-2004 VideoLAN
+ * Copyright (C) 2002-2007 the VideoLAN team
  * $Id$
  *
- * Authors: Clément Stenac <zorglub@videolan.org>
+ * Authors: Clément Stenac <zorglub@videolan.org>
  *
  * 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
@@ -18,7 +18,7 @@
  *
  * 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, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
 #include <stdlib.h>                                                /* free() */
 #include <stdio.h>                                              /* sprintf() */
 #include <string.h>                                            /* strerror() */
+#include <assert.h>
 
 #include <vlc/vlc.h>
-#include <vlc/sout.h>
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-#define FREE( p ) if( p ) { free( p ); (p) = NULL; }
+#include <vlc_sout.h>
+#include <vlc_network.h> /* FIXME: fix RegisterSDP() and remove this */
+#include "stream_output.h"
 
+struct announce_method_t
+{
+} sap_method;
 
 /****************************************************************************
  * Sout-side functions
@@ -69,7 +70,7 @@ int sout_AnnounceRegister( sout_instance_t *p_sout,
             return VLC_ENOMEM;
         }
         vlc_object_yield( p_announce );
-        msg_Dbg( p_sout,"Creation done" );
+        msg_Dbg( p_sout, "creation done" );
     }
 
     i_ret = announce_Register( p_announce, p_session, p_method );
@@ -83,11 +84,14 @@ int sout_AnnounceRegister( sout_instance_t *p_sout,
  *
  * \param p_sout a sout instance structure
  * \param psz_sdp the SDP to register
+ * \param psz_uri session address (needed for SAP address auto detection)
  * \param p_method an announce method descriptor
  * \return the new session descriptor structure
  */
-session_descriptor_t *sout_AnnounceRegisterSDP( sout_instance_t *p_sout,
-                          char *psz_sdp, announce_method_t *p_method )
+session_descriptor_t *
+sout_AnnounceRegisterSDP( sout_instance_t *p_sout, const char *cfgpref,
+                          const char *psz_sdp, const char *psz_uri,
+                          announce_method_t *p_method )
 {
     session_descriptor_t *p_session;
     announce_handler_t *p_announce = (announce_handler_t*)
@@ -106,13 +110,19 @@ session_descriptor_t *sout_AnnounceRegisterSDP( sout_instance_t *p_sout,
         vlc_object_yield( p_announce );
     }
 
-    if( p_method->i_type != METHOD_TYPE_SAP )
+    p_session = sout_AnnounceSessionCreate(VLC_OBJECT (p_sout), cfgpref);
+    p_session->psz_sdp = strdup( psz_sdp );
+
+    /* GRUIK. We should not convert back-and-forth from string to numbers */
+    struct addrinfo *res;
+    if (vlc_getaddrinfo (VLC_OBJECT (p_sout), psz_uri, 0, NULL, &res) == 0)
     {
-        msg_Warn( p_sout,"forcing SAP announcement");
+        if (res->ai_addrlen <= sizeof (p_session->addr))
+            memcpy (&p_session->addr, res->ai_addr,
+                    p_session->addrlen = res->ai_addrlen);
+        vlc_freeaddrinfo (res);
     }
 
-    p_session = sout_AnnounceSessionCreate();
-    p_session->psz_sdp = strdup( psz_sdp );
     announce_Register( p_announce, p_session, p_method );
 
     vlc_object_release( p_announce );
@@ -136,7 +146,7 @@ int sout_AnnounceUnRegister( sout_instance_t *p_sout,
                                               FIND_ANYWHERE );
     if( !p_announce )
     {
-        msg_Dbg( p_sout, "Unable to remove announce: no announce handler" );
+        msg_Dbg( p_sout, "unable to remove announce: no announce handler" );
         return VLC_ENOOBJ;
     }
     i_ret  = announce_UnRegister( p_announce, p_session );
@@ -151,22 +161,68 @@ int sout_AnnounceUnRegister( sout_instance_t *p_sout,
  *
  * \return a new session descriptor
  */
-session_descriptor_t * sout_AnnounceSessionCreate()
+session_descriptor_t * sout_AnnounceSessionCreate (vlc_object_t *obj,
+                                                   const char *cfgpref)
 {
-    session_descriptor_t *p_session;
+    size_t cfglen = strlen (cfgpref);
+    if (cfglen > 100)
+        return NULL;
+
+    char varname[cfglen + sizeof ("description")], *subvar = varname + cfglen;
+    strcpy (varname, cfgpref);
+
+    session_descriptor_t *p_session = calloc (1, sizeof (*p_session));
+    if (p_session == NULL)
+        return NULL;
+
+    strcpy (subvar, "name");
+    p_session->psz_name = var_GetNonEmptyString (obj, varname);
+    strcpy (subvar, "group");
+    p_session->psz_group = var_GetNonEmptyString (obj, varname);
+
+    strcpy (subvar, "description");
+    p_session->description = var_GetNonEmptyString (obj, varname);
+    strcpy (subvar, "url");
+    p_session->url = var_GetNonEmptyString (obj, varname);
+    strcpy (subvar, "email");
+    p_session->email = var_GetNonEmptyString (obj, varname);
+    strcpy (subvar, "phone");
+    p_session->phone = var_GetNonEmptyString (obj, varname);
 
-    p_session = (session_descriptor_t *)malloc( sizeof(session_descriptor_t));
+    return p_session;
+}
 
-    if( p_session)
+int sout_SessionSetMedia (vlc_object_t *obj, session_descriptor_t *p_session,
+                          const char *fmt, const char *src, int sport,
+                          const char *dst, int dport)
+{
+    if ((p_session->sdpformat = strdup (fmt)) == NULL)
+        return VLC_ENOMEM;
+
+    /* GRUIK. We should not convert back-and-forth from string to numbers */
+    struct addrinfo *res;
+    if (vlc_getaddrinfo (obj, dst, dport, NULL, &res) == 0)
     {
-        p_session->p_sap = NULL;
-        p_session->psz_sdp = NULL;
-        p_session->psz_name = NULL;
-        p_session->psz_uri = NULL;
-        p_session->i_port = 0;
+        if (res->ai_addrlen > sizeof (p_session->addr))
+            goto oflow;
+
+        memcpy (&p_session->addr, res->ai_addr,
+                p_session->addrlen = res->ai_addrlen);
+        vlc_freeaddrinfo (res);
     }
+    if (vlc_getaddrinfo (obj, src, sport, NULL, &res) == 0)
+    {
+        if (res->ai_addrlen > sizeof (p_session->orig))
+            goto oflow;
+        memcpy (&p_session->orig, res->ai_addr,
+               p_session->origlen = res->ai_addrlen);
+        vlc_freeaddrinfo (res);
+    }
+    return 0;
 
-    return p_session;
+oflow:
+    vlc_freeaddrinfo (res);
+    return VLC_ENOMEM;
 }
 
 /**
@@ -179,37 +235,29 @@ void sout_AnnounceSessionDestroy( session_descriptor_t *p_session )
 {
     if( p_session )
     {
-        FREE( p_session->psz_name );
-        FREE( p_session->psz_uri );
-        FREE( p_session->psz_sdp );
-        FREE( p_session );
+        free (p_session->psz_name);
+        free (p_session->psz_group);
+        free (p_session->psz_sdp);
+        free (p_session->description);
+        free (p_session->sdpformat);
+        free (p_session->url);
+        free (p_session->email);
+        free (p_session->phone);
+        free( p_session );
     }
 }
 
 /**
- * Create and initialize an announcement method structure
- *
- * \param i_type METHOD_TYPE_SAP or METHOD_TYPE_SLP
- * \return a new announce_method structure
+ * \return the SAP announce method
  */
-announce_method_t * sout_AnnounceMethodCreate( int i_type )
+announce_method_t * sout_SAPMethod (void)
 {
-    announce_method_t *p_method;
-
-    p_method = (announce_method_t *)malloc( sizeof(announce_method_t) );
+    return &sap_method;
+}
 
-    if( p_method )
-    {
-        p_method->i_type = i_type;
-        if( i_type == METHOD_TYPE_SAP )
-        {
-            /* Default values */
-            p_method->psz_address = NULL;
-            p_method->i_ip_version = 4 ;
-            p_method->psz_ipv6_scope = strdup("8");
-        }
-    }
-    return p_method;
+void sout_MethodRelease (announce_method_t *m)
+{
+    assert (m == &sap_method);
 }
 
 /************************************************************************
@@ -235,9 +283,7 @@ announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this )
     }
 
     p_announce->p_sap = NULL;
-
-    vlc_object_attach( p_announce, p_this->p_vlc);
-
+    vlc_object_attach( p_announce, p_this->p_libvlc);
 
     return p_announce;
 }
@@ -250,12 +296,11 @@ announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this )
  */
 int announce_HandlerDestroy( announce_handler_t *p_announce )
 {
-
     if( p_announce->p_sap )
     {
-        p_announce->p_sap->b_die = VLC_TRUE;
+        ((vlc_object_t *)p_announce->p_sap)->b_die = VLC_TRUE;
         /* Wait for the SAP thread to exit */
-        vlc_thread_join( p_announce->p_sap );
+        vlc_thread_join( (vlc_object_t *)p_announce->p_sap );
         announce_SAPHandlerDestroy( p_announce->p_sap );
     }
 
@@ -270,9 +315,11 @@ int announce_Register( announce_handler_t *p_announce,
                        session_descriptor_t *p_session,
                        announce_method_t *p_method )
 {
+    if (p_method == NULL)
+        return VLC_EGENERIC;
 
     msg_Dbg( p_announce, "registering announce");
-    if( p_method->i_type == METHOD_TYPE_SAP )
+    if( p_method == &sap_method )
     {
         /* Do we already have a SAP announce handler ? */
         if( !p_announce->p_sap )
@@ -288,19 +335,14 @@ int announce_Register( announce_handler_t *p_announce,
         }
         /* this will set p_session->p_sap for later deletion */
         msg_Dbg( p_announce, "adding SAP session");
-        p_announce->p_sap->pf_add( p_announce->p_sap, p_session, p_method );
-    }
-    else if( p_method->i_type == METHOD_TYPE_SLP )
-    {
-        msg_Dbg( p_announce, "SLP unsupported at the moment" );
-        return VLC_EGENERIC;
+        p_announce->p_sap->pf_add( p_announce->p_sap, p_session );
     }
     else
     {
-        msg_Dbg( p_announce, "Announce type unsupported" );
+        msg_Err( p_announce, "announce type unsupported" );
         return VLC_EGENERIC;
     }
-    return VLC_SUCCESS;;
+    return VLC_SUCCESS;
 }
 
 
@@ -309,14 +351,7 @@ int announce_UnRegister( announce_handler_t *p_announce,
                   session_descriptor_t *p_session )
 {
     msg_Dbg( p_announce, "unregistering announce" );
-    if( p_session->p_sap != NULL ) /* SAP Announce */
-    {
-        if( !p_announce->p_sap )
-        {
-            msg_Err( p_announce, "can't remove announce, no SAP handler");
-            return VLC_ENOOBJ;
-        }
+    if( p_announce->p_sap )
         p_announce->p_sap->pf_del( p_announce->p_sap, p_session );
-    }
     return VLC_SUCCESS;
 }